Back to skills
SKILL.md
Delaylocal
ASecurity當使用者要「把一段 prompt 排程到 5 小時 quota 重置之後自動在本機執行」時觸發。觸發詞:「/goal2:delaylocal」、「delaylocal」、「排程到 quota 之後」、「quota 重置後跑」、「延後到額度恢復再執行」、「等 5h 額度回來再跑」。要「現在就做、不等 quota」→ 用同 plugin 的 goal skill(/goal2:goal),不是本 skill。
- 2 stars
- 0 votes
- 0 copies
- 1 view
- Added September 3, 2026
Works with
Security analysis
100/100Pro scans all 4 files and shows the line behind each finding
npx -y skills add abs1294/fulin-claude-plugins --skill delaylocal --agent claude-codeAre you the author of Delaylocal?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/abs1294-delaylocal)---
name: delaylocal
description: 當使用者要「把一段 prompt 排程到 5 小時 quota 重置之後自動在本機執行」時觸發。觸發詞:「/goal2:delaylocal」、「delaylocal」、「排程到 quota 之後」、「quota 重置後跑」、「延後到額度恢復再執行」、「等 5h 額度回來再跑」。要「現在就做、不等 quota」→ 用同 plugin 的 goal skill(/goal2:goal),不是本 skill。
---
# delaylocal — 排程 prompt 到 5h quota 重置後(工具化;goal2 plugin 的 delaylocal skill)
## 架構(薄 skill + 確定性工具)
確定性邏輯全在工具裡,skill 只負責「呼叫工具 → 拿結果 → CronCreate」,不靠 AI 即興。
- `delaylocal.js`:鎖定**當前 session**(讀 `CLAUDE_CODE_SESSION_ID`)的 5h quota 重置時間。goal 模式(預設):排程時就把引擎 prompt(只有 `/goal <條件>;已發 LINE` 加一句指向錨定區,≤3900 字)落到 `~/.claude/goal2/runs/<id>/prompt.txt`,任務全文、工作清單、報告格式、notify 指令全進同目錄 `anchor.md`(走系統提示,不受 /goal 的 4000 字元限制),cron 的 final_prompt 只做「session 守衛 → 叫 Claude 背景執行 `delaylocal.js --run <run_dir>`」;到點後 `--run` 起子程序 `claude -p "/goal …"` 跑官方引擎到達成。plain 模式:final_prompt 內建「session 守衛 + 無人值守文字紀律 + 任務 + LINE 通知」,不起子程序。
- **為什麼 goal 模式要繞子程序**:2.1.196 起 cron fire 的 prompt 不再解析 slash command,開頭 `/goal` 只是純文字(官方 scheduled-tasks 文件、GitHub #75837);`claude -p "/goal …"` 是唯一入口(見 `../../lib/engine.js` 檔頭與 goal skill 的 SKILL.md)。
- `notify-line.js`:LINE push 通知工具(node https,處理中文 / emoji)。
> 本 skill 的 js(`delaylocal.js` / `notify-line.js`)與這份 `SKILL.md` **同目錄**。
> 執行時用「本 SKILL.md 所在目錄」組出 js 絕對路徑即可——user-level skill、symlink、plugin 安裝
> 三種情境都成立(不依賴 `CLAUDE_PLUGIN_ROOT` 是否存在)。
> `delaylocal.js` 另依賴 plugin 根層的 `../../lib/`(`goal-head.js`:/goal 第一行 4000 字元門檻;`cron-time.js`:cron 轉換與跨月警告;`config.js`:設定檔讀取;`engine.js`:子程序引擎),
> 與同 plugin 的 goal skill 共用。**須整個 plugin 一起安裝**,只複製 `skills/delaylocal/` 資料夾會找不到 lib(工具會明確報錯)。
## 前置設定(一次性,每台機器)
**需要 Node.js**(`delaylocal.js` 與 `notify-line.js` 皆為 node 腳本):
- Windows:`winget install OpenJS.NodeJS` 或官網安裝包
- macOS:`brew install node`
- Linux:發行版套件管理器,或 nvm / nodenv
**skill 安裝(user-level symlink,三平台皆可)**:把 plugin 內的 skill 目錄連到 `~/.claude/skills/`:
- macOS / Linux:`ln -s <repo>/plugins/goal2/skills/delaylocal ~/.claude/skills/delaylocal`
- Windows(系統管理員 PowerShell):`New-Item -ItemType SymbolicLink -Path $HOME\.claude\skills\delaylocal -Target <repo>\plugins\goal2\skills\delaylocal`
- 或三平台都可改用 `/plugin install goal2@fulin-plugins`(免手動 symlink,**建議**;觸發名為 `/goal2:delaylocal`)
(`delaylocal.js` / `notify-line.js` 以 `__dirname` 解析同目錄與 `../../lib`,Node 對 symlink 取真身路徑,所以 symlink、plugin 安裝、user-level 三情境都成立,不依賴執行平台。)
**設定檔(選用)**:`~/.claude/goal2/config.json`(家目錄,重裝 plugin 不會被清掉;範本在 plugin 根層 `config.example.json`)。本 skill 用的欄位:`delaylocal.confirmTimeoutMinutes`(propose 後等使用者確認的逾時,**預設 10 分鐘**)、`delaylocal.bufferSeconds`(quota 重置後再等幾秒才 fire,**預設 900**,CLI 裸數字可臨時覆蓋)、`engine.permissionMode`(子程序權限模式,**預設 bypassPermissions**)、`engine.stopHookBlockCap`(引擎連續擋停上限,**預設 0=做到達成為止**)、`engine.model`、`engine.autocompact`(子程序壓縮視窗,預設 auto;長任務可調大)、`engine.maxBudgetUsd`(子程序 `--max-budget-usd`,花到自停 `status: budget`,**預設 300**)、`engine.maxMinutes`(runner 時限,超過殺樹標 timeout,**預設 480**)。沒檔就用預設;檔案壞掉或欄位錯會直接報錯不靜默退回。`node "<skill_dir>/delaylocal.js" --show-config` 可看生效值與當下的 `confirm_timer_cron`。
LINE 通知為**選用**:**有設憑證就發、沒設就自動略過、完全不影響任務執行**。
要啟用通知再設定其一(憑證**不進 git**):
- **環境變數(建議)**:設 `LINE_TOKEN`、`LINE_USER_ID`。plugin 安裝模式下 skill 目錄在 cache,重裝會被清掉,所以憑證放環境變數最穩。
- **或設定檔**:複製本 skill 目錄下的 `notify-line.config.example.json`
成 `notify-line.config.json`(同目錄),填入你的 LINE Channel Access Token 與 userId。
沒設好的話,排程照常建立、任務照常無人值守執行;結束時 `notify-line.js` 只會印一行
`LINE SKIP …` 並以 exit 0 結束(不算失敗、不卡 goal)。
## 執行步驟
### 🧭 先看這張決策表(三選一,弱模型務必先分流再往下)
| 使用者的意圖 | 走哪條 | 關鍵動作 |
|--------------|--------|----------|
| 「直接排、別問」(趕 quota 視窗、明說不要問) | **fast-path**(下方⚡) | `--plain`,立刻排,唯一可停:args 為空 |
| 一般排程、要「做到完成」(預設) | **goal 模式** | 先 propose 完成條件 → 使用者確認 → `--goal` 排程 |
| 明確說「不要目標、就照文字跑」 | **plain 模式** | `--plain`,不要完成條件 |
| 要「現在就做、不等 quota」 | **不是本 skill** | 改用同 plugin 的 `goal` skill(`/goal2:goal`) |
> **兩層時間別混淆**(弱模型最常錯的點;完整表見 `../../references/goal-propose-flow.md` 第 5 節):
> - **第 1 層=任務何時 fire**:quota 重置後(`delaylocal.js` 算出的 cron)。這是「任務本體」的排程。⚠️ CronCreate 的 `durable` 在目前版本**無效**(工具 schema 明寫「Has no effect — all jobs are session-only」,六月與現在皆如此):job 只活在本 process,Claude Code 關掉就沒了。
> - **第 2 層=goal 模式的 propose 確認 timer**(預設 10 分鐘,設定檔 `delaylocal.confirmTimeoutMinutes` 可調):只在 goal 模式、且你 propose 完成條件後才有,是「等使用者確認」的短 timer(`durable:false`),與第 1 層是**不同的 job**。
> - fast-path 與 plain 模式**沒有**第 2 層。只有 goal 模式才需要處理 propose timer。
### ⚡ 無條件直接排程(fast-path,最高優先)
當使用者意圖是「直接排、別問」時(觸發詞:「直接排程」、「無條件放進排程」、「quota 快滿了先排」、「不要 propose」、「不要問直接排」,或單純就是要你立刻把 args 排進去),**立刻用 `--plain` 模式排程**,並**嚴禁**:
- ❌ 用 AskUserQuestion 反問「要不要排 / 怎麼排 / 是不是真任務」
- ❌ 走 goal propose → 確認 → 確認 timer 流程
- ❌ 要求使用者補完成條件
直接執行:
1. Write 把 args 原文寫進唯一名暫存檔(命名規則同下方步驟 2)。
2. `node "<skill_dir>/delaylocal.js" --prompt-file <檔> --plain`(讓工具讀**真實** `CLAUDE_CODE_SESSION_ID`,勿自設假值)。
3. 用輸出的 cron + final_prompt 直接 `CronCreate({ recurring:false, durable:false })`。
4. 依步驟 5 格式回報。
> **唯一可停下的情況**:args 完全為空 → 請使用者補。其餘一律直接排,不問。
> ⚠️ 排程是時間敏感操作(quota 視窗),任何反問都在浪費使用者的視窗——這就是本 fast-path 存在的理由。
---
**(一般情況)預設為 goal 模式。** 先做下方「goal 模式排程流程」的 propose → 確認,拿到使用者確認的**完成條件**,
再走下列步驟(步驟 3 會以 `--goal-file <條件檔>` 帶入完成條件)。只有在這個任務實在無法定義可測量條件時,
才改用 `--plain` 文字模式(可跳過 propose、不需完成條件)。
> 若使用者要求「無條件直接排」,**上方 fast-path 優先**,跳過本 goal propose 流程。
### 1. 取得使用者要排的 prompt 原文
`/delaylocal <prompt>` 的 args。空 → 請使用者補,停止。
### 2. 把 prompt 寫進「唯一名稱」的暫存檔(避免 shell escape + 並發覆寫)
用 Write 把 prompt 原文寫到暫存檔。**檔名必須每次唯一**,禁止用固定檔名(多 session 並發、或同 session 多次排程會互相覆寫)。
檔名規則:`delaylocal-input-<14位時間戳>-<4位隨機>.txt`,放在**系統暫存目錄**(不要寫死使用者名,一律用該機器展開後的絕對路徑):
- **Windows**:`%TEMP%`,通常 `C:\Users\<你的帳號>\AppData\Local\Temp\`
- **macOS**:`$TMPDIR`(通常 `/var/folders/.../T/`)或 `/tmp`
- **Linux**:`$TMPDIR` 或 `/tmp`
例如 Windows `%TEMP%\delaylocal-input-20260520213045-7f3a.txt`;macOS `$TMPDIR/delaylocal-input-20260520213045-7f3a.txt`
> 步驟 3、收尾的 `node "<skill_dir>/..."` 與 `cat "<path>" | node ...` 指令在 macOS / Linux 原生 shell(bash / zsh)即可執行;Windows 則在 git-bash 下執行(語法相同)。
> 此中繼檔在**排程準備成功後**才由 `delaylocal.js` 刪除;驗證失敗(缺 --goal、cwd 不存在、超長)會保留,補參數重跑即可。
### 3. 跑主工具拿 JSON
```bash
# <skill_dir> = 本 SKILL.md 所在目錄
# 預設 goal 模式:帶 --goal-file <條件檔>(使用者已確認的完成條件)
node "<skill_dir>/delaylocal.js" [bufferSeconds] --prompt-file <步驟2的唯一檔名> --goal-file <條件檔> --cwd "<專案根目錄>"
# 條件先用 Write 寫進 delaylocal-cond-<時間戳>-<隨機>.txt 再以 --goal-file 傳(含引號/$/反引號/路徑時 --goal "<條件>" 會被 shell 改寫);一句話純文字的條件才用 --goal "<條件>"
# 文字模式(少數無法定義可測量條件時):改帶 --plain、省略 --goal
```
- **`--cwd` 必帶**(goal 模式),且要是 CLAUDE.md/自動記憶所在的專案根(不是子目錄):輸出的 `cwd_inspection`/`warnings` 會告訴你子程序載得到哪些 CLAUDE.md、記憶、project-scope plugin;有警告就改傳祖先目錄。任務書同樣要有 `## 脈絡與約束` 節(對話裡已決定的事;沒有只警告)。不帶 `--cwd` 會退回 Bash 工具當下的 cwd,那會漂移。同一棵工作樹已有活著的 run 不會擋,JSON 的 `active_runs_in_tree` 會列出來,排程回報時一併提醒。**並行時路徑不重疊不代表沒干擾**(共用 DB/測試結果/dev server port/git 工作樹),任務書要寫明本 run 的範圍切分與「別的 run 可能同時在動什麼」。`--stop` 殺不到引擎內用 `&`/nohup 起、已脫離父子鏈的背景服務,停完提醒使用者查 port。
- `bufferSeconds` 預設 900(15 分),可在設定檔 `~/.claude/goal2/config.json` 的 `delaylocal.bufferSeconds` 改預設;要臨時不同緩衝就帶數字(例 `1800`=30 分,CLI 優先於設定檔)。輸出的 `buffer_source` 說明用了哪個(cli / config / default)。
- 準備成功後工具才刪 `--prompt-file`/`--goal-file`;失敗保留。未知旗標(例 `--cwdd`)直接報錯,不會靜默吃掉。
- 工具輸出 JSON:`{ ok, plugin_version, plugin_root, sessionId, snapshotKey, resets_at_local, target_local, cron, cron_warning, fire_in_minutes, buffer_seconds, buffer_source, confirm_timeout_minutes, confirm_timer_cron, confirm_timer_target_local, config_path, config_loaded, mode, run_dir, run_command, stop_command, engine, engine_prompt, final_prompt }`。goal 模式時 `run_dir` 已建好、`engine_prompt`(`/goal` 開頭)已落在裡面;plain 模式這三個為 null。
- `ok:false` → 把 error 告訴使用者,停止。
### 4. 用工具輸出的 cron + final_prompt 排程
```
CronCreate({
cron: <JSON.cron>,
prompt: <JSON.final_prompt>, // goal 模式:session 守衛 + 「背景執行 run_command」指令;plain 模式:守衛 + 紀律 + 任務 + LINE
recurring: false,
durable: false // durable 在目前版本無效,填 true 也是 session-only;誠實寫 false
})
```
**禁止**自己把 `/goal` 放進 cron 的 prompt——到點時它只是純文字,不會啟動引擎。
### 5. 回報使用者(只回報以下欄位,格式固定)
- Cron Job ID
- 觸發時間:`JSON.target_local`(約 `JSON.fire_in_minutes` 分鐘後)
- **若 `JSON.cron_warning` 非 null → 必須把它原文一併回報給使用者**(跨月/跨年時 cron 可能 fire 到非預期年份的警告;請使用者核對觸發時間是否為預期那天)。為 null 則略過此行。
- quota 重置時間:`JSON.resets_at_local`、緩衝秒數
- 綁定 session:`JSON.sessionId`;goal 模式另報 `JSON.run_dir`
- 提醒(純陳述事實,不加 offer):
- cron 只活在本 Claude Code process,且 REPL idle 才 fire(`durable` 無效,關掉程式排程就沒了)
- final prompt 內建 **session 守衛**:只有 `JSON.sessionId` 那個 session 會真正執行,其他 session fire 到會自動跳過
- goal 模式到點後會另起子程序跑官方 /goal 引擎做到達成;完成 / 中止會嘗試發 LINE 總結(未設 LINE 憑證則自動略過、不影響任務)
- 取消:`CronDelete <id>`
### 6. cron 到點後(goal 模式,final_prompt 會指示你做這些)
1. Session 守衛通過 → 用 Bash、`run_in_background: true` 原樣執行 `run_command`(`node "<delaylocal.js>" --run "<run_dir>"`)。它阻塞到引擎結束,最後印 summary JSON。
2. 收到背景結束通知後讀 JSON:**`status` 與 `goal_verdict`**(`done`=檢查器確認達成;`unverified`=正常結束但沒有達成判定,**不可當作達成**,要明講;`impossible`/`failed`/`timeout`/`budget`/`unknown` 各照 goal skill 步驟 5 的說法講)、`continuations`、`compactions`/`anchor_injections`(壓縮次數與壓縮後錨定注回次數)、`num_turns`、`total_cost_usd`、`result_text`(引擎最後一則回覆=報告全文,**原文保留**)、`run_dir`(`stream.jsonl` 可追查、`progress.md` 是進度帳本、`child_transcript` 是檢查器紀錄)。固定格式回報,不加提問或 offer。
3. `runs/` 目錄全機共用,**禁止整批 rm**;清理只能 `goal.js --prune`(見 goal skill;等 cron 的 delaylocal prepared run 以 meta 的 `scheduledFor` 起算,到點前不會被清)。進行中要終止:`node "<skill_dir>/delaylocal.js" --stop <run_dir>`(先核對 pid 身分再殺整棵子程序樹、標 stopped;多個活著的 run 時先問停哪一個;`--stop`/`--status` 不需要 `CLAUDE_CODE_SESSION_ID`,使用者在自己的終端也能用);要看進度:`--status <run_dir>`,回報時第一句直接用它的 `summary_zh`(狀態+回合+擋停次數+壓縮次數+最後動作+最後一句,已是人話),再貼 `progress_md` 的已完成/剩餘;欄位對照見 goal skill 的 SKILL.md 4b。不要只 TaskStop 背景指令:殺 runner 引擎會跟著死,但 meta 停在 running、沒有 result.json,之後只能 `--stop` 收狀態。
**嚴禁**在回報結尾追加任何「建議 / 下一步 / 要不要我改用別的方式」之類的提問或 offer。
回報到「取消方式」就結束。
### goal 模式排程流程(propose →(確認 / 逾時自動採納)→ 排程)⚠️ 必守
goal 是**預設模式**。通用骨架(為什麼要 propose、可測量條件怎麼寫、timer 怎麼收斂、/goal 引擎契約)在 `../../references/goal-propose-flow.md`,**先讀第 2、3 節**。`delaylocal.js` 在「非 --plain 又沒給 --goal」時會直接報錯,提醒先 propose——**禁止未經 propose 就排任務**。
本 skill 的具體差異(對照 references 第 3 節的表):
0. **事實層+grill**(同 goal skill 步驟 2a/2b):任務原文含對話指涉(「你掌握的」「這 N 個」「你的建議」)就先把項目逐條展開成任務書的 `## 項目清單`(`delaylocal.js` 對不自足的任務會拒絕);再依 `goal.grill`(預設 true)grill 到 frontier 空:每輪問完當下能問的全部分岔、附建議答案,沒有默默假設的決策才 propose。fast-path 與 plain 模式跳過這一步。
1. **propose 時**一併給:完成條件(照 references 第 2 節,**極端**:等式與全稱,`= 0`/每一項,不用 `<`、`≤`、「大部分」;條件內含例外條款「例外清單內的項目不計」,例外限真 blocker+證據+原因,回報時逐項列出)、任務拆解、**緩衝秒數 / 預計 fire 時間**。
2. **確認 timer 的 cron 由工具算,不要心算**:先跑 `node "<skill_dir>/delaylocal.js" --show-config`,拿 `confirm_timer_cron`(= 現在 + 設定檔 `delaylocal.confirmTimeoutMinutes`,預設 10 分鐘,向上取整到整分)與 `confirm_timeout_minutes`。timer 的 prompt 是**文字指令**(不是任務本體):`CronCreate({ cron: <confirm_timer_cron>, recurring:false, durable:false, prompt: "[delaylocal 逾時自動採納] 若使用者自此 propose 後尚未回覆,視為自動採納,直接完成排程。完成條件:<condition 全文>;任務:<task>;buffer:<秒>。請把條件寫進條件檔後跑 delaylocal.js --goal-file … --cwd …,再 CronCreate。" })`。**記下 timer 的 job id。**回報時把 `confirm_timeout_minutes` 講給使用者(「N 分鐘內沒回覆將自動採納」)。
3. **收斂**:使用者回覆 → 先 `CronDelete <timer id>` 再處理(同意 → 第 4 步;改 → 重 propose 並重排 timer);逾時 → timer fire 自動採納,進第 4 步。
4. **排程任務**:把採納的完成條件寫進條件檔,跑 `delaylocal.js … --goal-file <條件檔> --cwd <專案根>`(此時引擎 prompt 已落 `run_dir`)取得 final_prompt,再 `CronCreate`(到 quota 重置後 fire;fire 進來的 prompt 會叫你背景執行 `run_command` 起引擎)。timer 與任務是**兩個不同的 job**。
## 運作原理(why,不是執行步驟)
- **算哪個 session 的 quota**:工具讀 `CLAUDE_CODE_SESSION_ID`(去 dash 取前 24 字元 = snapshot key)→ 精準鎖定當前 session。
- **排到哪個 session 執行**:cron 是 session-only(`durable` 無效),fire 時仍以 final prompt 第一步的 session 守衛保險 → 只有目標 session 執行。
- **無人值守(unattended)**:plain 模式的 final prompt 內建紀律——假設使用者不在線、不停下來問、持續執行直到無可執行項目、每次收尾前強制自問清單全「否」才可結束、只有真 blocker 才停。goal 模式則交給官方引擎的檢查器。
- **goal 引擎在子程序**:/goal 引擎契約(第一行必須是 `/goal`、4000 字元上限、達成後自動清除、本質是 Stop hook)見 `../../references/goal-propose-flow.md` 第 4 節。2.1.195 時 cron 送 `/goal` 曾能啟動引擎;**2.1.196 起不再解析**(GitHub #75837),所以現在分兩層:
- **cron 的 final_prompt**(fire 進本 session):session 守衛 → 叫 Claude 背景執行 `delaylocal.js --run <run_dir>`。
- **引擎 prompt**(排程時落在 `run_dir/prompt.txt`,由 `--run` 交給 `claude -p`):**第一行** = `/goal <完成條件>;並且已執行 notify-line.js 完成收尾通知(…)`——把「已收尾通知」**納入完成條件**:goal 達成後會自動清除、不接後續指示,唯有把這步寫進條件,引擎才會強迫做完才停(未設憑證時 notify-line.js 回 exit 0,同樣算達成、不卡)。⚠️ -p 路徑下 4000 字元上限算的是**整段 prompt**(2026-09-12 實測),所以任務、工作清單、報告格式一律在 anchor.md;條件本身超長時 `lib/goal-head.js` 把第一行換成指針句、全文放 anchor「完成條件全文」並要求引擎第一則回覆先貼出。工作清單(在 anchor)= ①開工先拆里程碑進帳本 ②執行任務 ③補帳本+寫報告+發 LINE。子程序沒有 session 守衛的問題(它就是為這個任務起的)。
- **長任務防漂移**:`anchor.md`(條件+任務+帳本規則)進子程序系統提示、`progress.md` 帳本邊做邊更新、SessionStart(compact) hook 壓縮後注回——與 goal skill 同一套,細節見 goal skill 的 SKILL.md「運作原理」與 references 第 4 節。
- **為什麼 goal 要先 propose**:見 references 第 1 節。無法定義可測量條件的少數任務,才加 `--plain` 退回文字版紀律(不需條件、跳過 propose)。
- **LINE 通知(選用)**:final prompt 結尾呼叫 `notify-line.js` 嘗試發總結;未設憑證則自動略過、不影響完成。
## 注意
- `rate-limit-snapshots.json` 的 `resets_at` 只在送訊息時更新;skill 由使用者送 prompt 觸發 → 即時可信。
- 只用 CronCreate 排程,不可用 SQL 偽造。
- LINE 憑證放本機 `notify-line.config.json` 或環境變數,**不進 git**(已被 .gitignore 排除)。
Files in this skill
- SKILL.md
- delaylocal.js
- notify-line.config.example.json
- notify-line.js
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.