@tocca-systems/twp-cli 0.15.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.public.md
CHANGED
|
@@ -11,6 +11,27 @@
|
|
|
11
11
|
`CHANGELOG.md` に残してあります。顧客向けの履歴は public 公開以降を対象とします。
|
|
12
12
|
-->
|
|
13
13
|
|
|
14
|
+
## 0.16.0
|
|
15
|
+
|
|
16
|
+
`twp task-loop` が、使っている AI アカウントの枠(利用率・上限・再ログイン期限)をエージェントループ画面へ報告できるようになりました。**設定しなければ何も変わりません**(プローブの実行も送信も起きません)。
|
|
17
|
+
|
|
18
|
+
`~/.twp/loops/<プロジェクトUUID>.json` に次のキーを足すと有効になります。
|
|
19
|
+
|
|
20
|
+
```jsonc
|
|
21
|
+
"capacity_probe": {
|
|
22
|
+
"command": ["claude-auto-switch", "status", "--json"],
|
|
23
|
+
"format": "claude_auto_switch/v1", // 既定は "twp.capacity/v1"(正準スキーマ直出し)
|
|
24
|
+
"interval": 900, // 送信間隔(秒)
|
|
25
|
+
"timeout": 15, // プローブのタイムアウト(秒)
|
|
26
|
+
"identity": "masked" // "masked"(既定) | "none" | "full"
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- `command` は任意のコマンドで、**標準出力の JSON を読むだけ**です。`format` が `twp.capacity/v1`(既定)なら正準スキーマをそのまま受け取り、`claude_auto_switch/v1` なら `claude-auto-switch status --json` の出力を変換します。他のツールを使う場合は、正準スキーマを標準出力に書くラッパを用意すれば `format` は既定のまま使えます。
|
|
31
|
+
- メールアドレスは送信前に伏字化されます(`agent@example.com` → `a**nt@ex*******om`)。`"identity": "none"` にすると識別子を一切送りません。
|
|
32
|
+
- プローブが失敗しても**ループは止まりません**。警告を1行出し、「取得に失敗した」という事実のほうを送ります。
|
|
33
|
+
- `command` を指定していない・書式が不正な場合は、警告を出したうえで枠の観測を行いません(勝手に既定のコマンドを実行することはありません)。
|
|
34
|
+
|
|
14
35
|
## 0.15.0
|
|
15
36
|
|
|
16
37
|
モードを自分で調整できるようになりました。`.twp/modes/dev.md`(プロジェクト)や `~/.twp/modes/dev.md`(個人)に markdown を置くと、そのモードのラベル・色・使えるツール・権限・モデルへの指示を上書きできます。書き間違えても起動は止まらず、警告を出して既定の設定で続きます。
|
|
@@ -6,17 +6,16 @@ join(", ")}] \u3092\u4F7F\u3044\u307E\u3059\uFF09`);return fallback}}if(value.le
|
|
|
6
6
|
warnings.push(`claude_launcher.probe_match \u306F\u6B63\u898F\u8868\u73FE\u3068\u3057\u3066\u89E3\u91C8\u3067\u304D\u307E\u305B\u3093\uFF08${err.message}\uFF09\u3002\u65E2\u5B9A '${DEFAULT_CLAUDE_LAUNCHER.probeMatch}' \u3092\u4F7F\u3044\u307E\u3059`);return DEFAULT_CLAUDE_LAUNCHER.probeMatch}return raw}var NOT_YET_APPLIED=[{key:"probe",get:c=>c.probe},{key:"probe_match",get:c=>c.probeMatch},{key:"exec_args",get:c=>c.execArgs},{key:"active_args",get:c=>c.activeArgs}];function sameAsDefault(key,parsed){
|
|
7
7
|
const entry=NOT_YET_APPLIED.find(e=>e.key===key);if(entry===void 0)return true;const a=entry.get(parsed);const b=entry.get(DEFAULT_CLAUDE_LAUNCHER);return typeof a==="string"||typeof b==="string"?a===b:a.length===b.length&&a.every((v,i)=>v===b[i])}function parseClaudeLauncher(value){const warnings=[];if(value===void 0||value===null){return{launcher:DEFAULT_CLAUDE_LAUNCHER,warnings}}if(typeof value!=="object"||Array.isArray(value)){warnings.push("claude_launcher \u306F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u65E2\u5B9A\u306E\u8D77\u52D5\u65B9\u6CD5\u3092\u4F7F\u3044\u307E\u3059\uFF09");
|
|
8
8
|
return{launcher:DEFAULT_CLAUDE_LAUNCHER,warnings}}const v=value;const launcher={bin:stringField(v["bin"],"bin",DEFAULT_CLAUDE_LAUNCHER.bin,warnings),probe:argvField(v["probe"],"probe",DEFAULT_CLAUDE_LAUNCHER.probe,warnings,true),probeMatch:probeMatchField(v["probe_match"],warnings),execArgs:argvField(v["exec_args"],"exec_args",DEFAULT_CLAUDE_LAUNCHER.execArgs,warnings,false),activeArgs:argvField(v["active_args"],"active_args",DEFAULT_CLAUDE_LAUNCHER.activeArgs,warnings,false)};for(const{key}of NOT_YET_APPLIED){
|
|
9
|
-
if(!sameAsDefault(key,launcher)){warnings.push(`claude_launcher.${key} \u306F\u307E\u3060\u9069\u7528\u3055\u308C\u307E\u305B\u3093\uFF08\u3053\u306E\u7248\u3067\u52B9\u304F\u306E\u306F bin \u3060\u3051\u3067\u3059\uFF09`)}}return{launcher,warnings}}import{randomBytes}from"crypto";import fs from"fs";import os from"os";import path from"path";function
|
|
10
|
-
lost",reason:`status=${status}\uFF08processing \u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09`}}const itemRunner=(item.runner_id??"").trim();const itemRun=(item.run_id??"").trim();if(itemRunner===""||itemRun===""){return{verdict:"unknown",reason:"\u5FDC\u7B54\u306B runner_id / run_id \u304C\u3042\u308A\u307E\u305B\u3093"}}if(itemRunner!==runnerId){return{verdict:"lost",reason:`\u5225\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08runner=${itemRunner}\uFF09`}}
|
|
11
|
-
if(itemRun!==runId){return{verdict:"lost",reason:`\u540C\u3058\u6A5F\u4F53\u306E\u5225\u306E\u8D77\u52D5\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08run_id \u304C\u4E00\u81F4\u3057\u307E\u305B\u3093\uFF09`}}return{verdict:"held",reason:"processing \u304B\u3064 runner_id / run_id \u304C\u4E00\u81F4"}}var OWNERSHIP_CHECK_INTERVAL_SEC=60;import{spawn}from"child_process";function resolveHookCommand(file,env){if(process.platform!=="win32")return file;if(isWindowsDriveAbsolute(file))return file;return findExecutable(file,{env,platform:"win32"})}var DEFAULT_TIMEOUT_SEC=120;var MAX_OUTPUT_BYTES=512*1024;var HOOK_ID_RE=/^[A-Za-z0-9._:-]{1,64}$/;function validateHooks(raw,configKey="prefetch"){const warnings=[];if(raw===void 0||raw===null)return{hooks:[],warnings};if(!Array.isArray(raw)){return{hooks:[],warnings:[`${configKey} \u306F\u914D\u5217\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u30D5\u30C3\u30AF\u306F1\u3064\u3082\u5B9F\u884C\u3057\u307E\u305B\u3093`]}}
|
|
9
|
+
if(!sameAsDefault(key,launcher)){warnings.push(`claude_launcher.${key} \u306F\u307E\u3060\u9069\u7528\u3055\u308C\u307E\u305B\u3093\uFF08\u3053\u306E\u7248\u3067\u52B9\u304F\u306E\u306F bin \u3060\u3051\u3067\u3059\uFF09`)}}return{launcher,warnings}}import{randomBytes}from"crypto";import fs from"fs";import os from"os";import path from"path";import{createHash}from"crypto";import{spawn}from"child_process";function resolveHookCommand(file,env){if(process.platform!=="win32")return file;if(isWindowsDriveAbsolute(file))return file;return findExecutable(file,{env,platform:"win32"})}var DEFAULT_TIMEOUT_SEC=120;var MAX_OUTPUT_BYTES=512*1024;var HOOK_ID_RE=/^[A-Za-z0-9._:-]{1,64}$/;function validateHooks(raw,configKey="prefetch"){const warnings=[];if(raw===void 0||raw===null)return{hooks:[],warnings};if(!Array.isArray(raw)){return{hooks:[],warnings:[`${configKey} \u306F\u914D\u5217\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\u30D5\u30C3\u30AF\u306F1\u3064\u3082\u5B9F\u884C\u3057\u307E\u305B\u3093`]}}
|
|
12
10
|
const hooks=[];const seen=new Set;for(const[i,entry]of raw.entries()){if(entry===null||typeof entry!=="object"||Array.isArray(entry)){warnings.push(`${configKey}[${i}] \u304C\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u3053\u306E\u30D5\u30C3\u30AF\u306F\u5B9F\u884C\u3057\u307E\u305B\u3093`);continue}const e=entry;const id=typeof e["id"]==="string"?e["id"].trim():"";const command=e["command"];if(id===""){warnings.push(`${configKey}[${i}] \u306B id \u304C\u3042\u308A\u307E\u305B\u3093\u3002\u3053\u306E\u30D5\u30C3\u30AF\u306F\
|
|
13
11
|
\u5B9F\u884C\u3057\u307E\u305B\u3093`);continue}if(!HOOK_ID_RE.test(id)){warnings.push(`${configKey}[${i}] \u306E id '${id}' \u306F64\u6587\u5B57\u4EE5\u4E0B\u306E\u82F1\u6570\u5B57\u3068 . _ : - \u3060\u3051\u3092\u4F7F\u3048\u307E\u3059\u3002\u3053\u306E\u30D5\u30C3\u30AF\u306F\u5B9F\u884C\u3057\u307E\u305B\u3093`);continue}if(seen.has(id)){warnings.push(`${configKey}[${i}] \u306E id '${id}' \u304C\u91CD\u8907\u3057\u3066\u3044\u307E\u3059\u3002\u3053\u306E\u30D5\u30C3\u30AF\u306F\u5B9F\u884C\u3057\u307E\u305B\u3093`);
|
|
14
12
|
continue}if(!Array.isArray(command)||command.length===0||!command.every(c=>typeof c==="string")){warnings.push(`${configKey}[${i}]\uFF08${id}\uFF09\u306E command \u304C\u6587\u5B57\u5217\u306E\u914D\u5217\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u3053\u306E\u30D5\u30C3\u30AF\u306F\u5B9F\u884C\u3057\u307E\u305B\u3093`);continue}const timeout=typeof e["timeout"]==="number"&&Number.isFinite(e["timeout"])&&e["timeout"]>0?Math.trunc(e["timeout"]):DEFAULT_TIMEOUT_SEC;seen.add(id);hooks.push({id,
|
|
15
13
|
command,timeout})}return{hooks,warnings}}async function runHook(hook,cwd,env=process.env,allowEmpty=false){const started=Date.now();const[file,...args]=hook.command;if(file===void 0){return{id:hook.id,ok:false,stdout:"",reason:"command \u304C\u7A7A\u3067\u3059",durationMs:0}}return new Promise(resolve=>{const resolved=resolveHookCommand(file,env);if(resolved===null){resolve({id:hook.id,ok:false,stdout:"",reason:`\u5B9F\u884C\u30D5\u30A1\u30A4\u30EB ${file} \u3092 PATH \u4E0A\u3067\u89E3\u6C7A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08Windows \u3067\u306F bare nam\
|
|
16
|
-
e \u3067\u8D77\u52D5\u3057\u307E\u305B\u3093\uFF09`,durationMs:0});return}let child;try{child=spawn(resolved,args,{cwd,env,detached:process.platform!=="win32",stdio:["ignore","pipe","pipe"]})}catch(e){const code=e.code??"spawn \u5931\u6557";resolve({id:hook.id,ok:false,stdout:"",reason:`\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093: ${file} (${code})`,durationMs:Date.now()-started});return}let stdout="";let stderr="";let truncated=false;let timedOut=false;const timer=setTimeout(
|
|
17
|
-
child,"SIGKILL")},(hook.timeout??DEFAULT_TIMEOUT_SEC)*1e3);child.stdout.on("data",c=>{if(stdout.length>=MAX_OUTPUT_BYTES){truncated=true;return}stdout+=c.toString("utf8");if(stdout.length>MAX_OUTPUT_BYTES){stdout=stdout.slice(0,MAX_OUTPUT_BYTES);truncated=true}});child.stderr.on("data",c=>{if(stderr.length<8192)stderr+=c.toString("utf8")});const done=(ok,reason)=>{clearTimeout(timer);resolve({id:hook.id,ok,stdout:truncated?`${stdout}
|
|
18
|
-
\u2026\uFF08\u51FA\u529B\u304C\u4E0A\u9650\u3092\u8D85\u3048\u305F\u305F\u3081\u5207\u308A\u8A70\u3081\u307E\u3057\u305F\uFF09`:stdout,reason,durationMs:Date.now()-started})};child.on("error",e=>done(false,`\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093: ${e.message}
|
|
19
|
-
""?"":`: ${firstLine(stderr)}`}
|
|
14
|
+
e \u3067\u8D77\u52D5\u3057\u307E\u305B\u3093\uFF09`,failure:"spawn",durationMs:0});return}let child;try{child=spawn(resolved,args,{cwd,env,detached:process.platform!=="win32",stdio:["ignore","pipe","pipe"]})}catch(e){const code=e.code??"spawn \u5931\u6557";resolve({id:hook.id,ok:false,stdout:"",reason:`\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093: ${file} (${code})`,failure:"spawn",durationMs:Date.now()-started});return}let stdout="";let stderr="";let truncated=false;let timedOut=false;const timer=setTimeout(
|
|
15
|
+
()=>{timedOut=true;killProcessTree(child,"SIGKILL")},(hook.timeout??DEFAULT_TIMEOUT_SEC)*1e3);child.stdout.on("data",c=>{if(stdout.length>=MAX_OUTPUT_BYTES){truncated=true;return}stdout+=c.toString("utf8");if(stdout.length>MAX_OUTPUT_BYTES){stdout=stdout.slice(0,MAX_OUTPUT_BYTES);truncated=true}});child.stderr.on("data",c=>{if(stderr.length<8192)stderr+=c.toString("utf8")});const done=(ok,reason,failure)=>{clearTimeout(timer);resolve({id:hook.id,ok,stdout:truncated?`${stdout}
|
|
16
|
+
\u2026\uFF08\u51FA\u529B\u304C\u4E0A\u9650\u3092\u8D85\u3048\u305F\u305F\u3081\u5207\u308A\u8A70\u3081\u307E\u3057\u305F\uFF09`:stdout,reason,...failure===void 0?{}:{failure},durationMs:Date.now()-started})};child.on("error",e=>done(false,`\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093: ${e.message}`,"spawn"));child.on("close",code=>{if(timedOut)return done(false,`\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\uFF08${hook.timeout??DEFAULT_TIMEOUT_SEC}\u79D2\uFF09`,"timeout");if(code!==0)return done(false,`\u7D42\u4E86\u30B3\
|
|
17
|
+
\u30FC\u30C9 ${code}${stderr.trim()===""?"":`: ${firstLine(stderr)}`}`,"exit");if(!allowEmpty&&stdout.trim()==="")return done(false,"\u51FA\u529B\u304C\u7A7A\u3067\u3057\u305F","empty");done(true,null)})})}async function runPrefetch(hooks,cwd,log,env=process.env){if(hooks.length===0)return"";const sections=[];for(const hook of hooks){const r=await runHook(hook,cwd,env);if(r.ok){log(` prefetch: ${r.id} \u53D6\u5F97\u5B8C\u4E86\uFF08${Math.round(r.durationMs/1e3)}s\uFF09`);sections.push(`--- pref\
|
|
18
|
+
etch: ${r.id} ---
|
|
20
19
|
${r.stdout.trim()}`)}else{log(` \u26A0\uFE0F prefetch: ${r.id} \u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${r.reason}\uFF09`);sections.push(`--- prefetch: ${r.id} ---
|
|
21
20
|
\uFF08\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${r.reason}\u3002\u3053\u306E\u60C5\u5831\u306F\u6B20\u3051\u3066\u3044\u307E\u3059\uFF09`)}}return["\u3010\u4E8B\u524D\u53D6\u5F97\u6E08\u307F\u30C7\u30FC\u30BF\u3011","\u4EE5\u4E0B\u306F\u30EB\u30FC\u30D7\u304C\u4E8B\u524D\u306B\u53D6\u5F97\u3057\u305F\u8A08\u753B\u7528\u30C7\u30FC\u30BF\u3067\u3059\u3002\u540C\u3058\u60C5\u5831\u3092\u96C6\u3081\u76F4\u3059\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u3002","\u300C\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u300D\u3068\u66F8\u304B\u308C\u305F\u7BC0\u3060\u3051\
|
|
22
21
|
\u306F\u6B20\u3051\u3066\u3044\u308B\u306E\u3067\u3001\u5FC5\u8981\u306A\u3089\u305D\u306E\u5206\u3092\u81EA\u5206\u3067\u53D6\u5F97\u3057\u3066\u304F\u3060\u3055\u3044\u3002","",sections.join("\n\n")].join("\n")}async function runPreflight(hooks,cwd,log,env=process.env){if(hooks.length===0)return"";const sections=[];for(const hook of hooks){const r=await runHook(hook,cwd,env,true);if(r.ok){log(` preflight: ${r.id} \u78BA\u8A8D\u5B8C\u4E86\uFF08${Math.round(r.durationMs/1e3)}s\uFF09`);if(r.stdout.
|
|
@@ -24,7 +23,28 @@ trim()!=="")sections.push(`--- preflight: ${r.id} ---
|
|
|
24
23
|
${r.stdout.trim()}`)}else{log(` \u26A0\uFE0F preflight: ${r.id} \u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${r.reason}\uFF09`);sections.push(`--- preflight: ${r.id} ---
|
|
25
24
|
\uFF08\u78BA\u8A8D\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${r.reason}\u3002\u3053\u306E\u524D\u63D0\u6761\u4EF6\u306F\u4E0D\u660E\u3067\u3059\uFF09`)}}if(sections.length===0)return"";return["\u3010\u74B0\u5883\u306E\u524D\u63D0\u6761\u4EF6\uFF08preflight\uFF09\u3011","\u4EE5\u4E0B\u306F\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u306E\u5192\u982D\u3067\u78BA\u8A8D\u3057\u305F\u74B0\u5883\u60C5\u5831\u3067\u3059\u3002\u8A08\u753B\u3068\u5404\u30A2\u30A4\u30C6\u30E0\u306E\u5B9F\u884C\u3067\u8003\u616E\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
26
25
|
"\u5931\u6557\u3057\u305F\u30D5\u30C3\u30AF\u304C\u3042\u3063\u3066\u3082\u30B5\u30A4\u30AF\u30EB\u306F\u7D99\u7D9A\u3057\u307E\u3059\u3002\u5FC5\u8981\u306A\u62C5\u4FDD\u304C\u53D6\u308C\u306A\u3044\u5834\u5408\u306F\u3001\u305D\u306E\u4E8B\u5B9F\u3092\u660E\u8A18\u3057\u3066\u304F\u3060\u3055\u3044\u3002","",sections.join("\n\n")].join("\n")}function firstLine(s){return(s.trim().split("\n")[0]??"").slice(0,200)}function formatHookWiring(prefetch,preflight){return`LOOP_HOOKS ${formatHookIds(prefetch,
|
|
27
|
-
preflight)}`}function formatHookIds(prefetch,preflight){const ids=hooks=>hooks.map(h=>h.id).join(",");return`prefetch=[${ids(prefetch)}] preflight=[${ids(preflight)}]`}var
|
|
26
|
+
preflight)}`}function formatHookIds(prefetch,preflight){const ids=hooks=>hooks.map(h=>h.id).join(",");return`prefetch=[${ids(prefetch)}] preflight=[${ids(preflight)}]`}var CAPACITY_SCHEMA="twp.capacity/v1";var CAPACITY_MAX_BYTES=8192;var CAPACITY_FORMATS=[CAPACITY_SCHEMA,"claude_auto_switch/v1"];var IDENTITY_MODES=["masked","none","full"];var DEFAULT_CAPACITY_PROBE={format:CAPACITY_SCHEMA,interval:900,timeout:15,identity:"masked"};var LOCAL_HEAD=1;var LOCAL_TAIL=2;var DOMAIN_HEAD=2;var DOMAIN_TAIL=2;var COLLAPSED="***";function maskPart(value,head,tail){if(value.length<head+tail+1)return null;return`${value.slice(0,head)}${"*".repeat(value.length-head-tail)}${value.
|
|
27
|
+
slice(value.length-tail)}`}function maskEmail(raw){const value=raw.trim();const at=value.lastIndexOf("@");if(at<0)return maskPart(value,LOCAL_HEAD,LOCAL_TAIL)??COLLAPSED;const local=value.slice(0,at);const domain=value.slice(at+1);const maskedLocal=maskPart(local,LOCAL_HEAD,LOCAL_TAIL);const maskedDomain=maskPart(domain,DOMAIN_HEAD,DOMAIN_TAIL);if(maskedLocal===null||maskedDomain===null)return`${COLLAPSED}@${COLLAPSED}`;return`${maskedLocal}@${maskedDomain}`}function identityHash(raw){return`sha\
|
|
28
|
+
256:${createHash("sha256").update(raw.trim()).digest("hex").slice(0,12)}`}function applyIdentity(slot,raw,mode){if(mode==="none")return;if(typeof raw!=="string"||raw.trim()==="")return;slot.identity_masked=mode==="full"?raw.trim():maskEmail(raw);slot.identity_hash=identityHash(raw)}var CAS_METRIC_LABELS={five_hour:"5\u6642\u9593\u67A0",seven_day:"\u9031\u9593",weekly_fable:"\u9031\u9593(Fable)"};function isRecord(v){return typeof v==="object"&&v!==null&&!Array.isArray(v)}function num(v){return typeof v===
|
|
29
|
+
"number"&&Number.isFinite(v)?v:void 0}function str(v){return typeof v==="string"&&v.trim()!==""?v.trim():void 0}function epochToIso(v){const n=num(v);if(n===void 0||n<=0)return void 0;return new Date(n*1e3).toISOString()}function toSlotState(raw,eligible){const s=str(raw);if(s==="needs_login")return"needs_login";if(eligible===false)return"excluded";if(s==="over_ceiling")return"excluded";if(s===void 0)return"unknown";return"usable"}function adaptClaudeAutoSwitch(raw,identity){if(!isRecord(raw)||!Array.
|
|
30
|
+
isArray(raw["accounts"]))return null;const slots=[];for(const entry of raw["accounts"]){if(!isRecord(entry))continue;const name=str(entry["name"]);if(name===void 0)continue;const metrics=[];if(isRecord(entry["metrics"])){for(const[key,m]of Object.entries(entry["metrics"])){if(!isRecord(m))continue;const metric={key};const label=CAS_METRIC_LABELS[key];if(label!==void 0)metric.label=label;const utilization=num(m["utilization"]);if(utilization!==void 0)metric.utilization=utilization;const threshold=num(
|
|
31
|
+
m["threshold"]);if(threshold!==void 0)metric.threshold=threshold;const ceiling=num(m["ceiling"]);if(ceiling!==void 0)metric.ceiling=ceiling;const resets=epochToIso(m["resets_at"]);if(resets!==void 0)metric.resets_at=resets;metrics.push(metric)}}const slot={name,state:toSlotState(entry["state"],entry["eligible"]),metrics};const stateLabel=str(entry["state_label"]);if(stateLabel!==void 0)slot.state_label=stateLabel;if(typeof entry["eligible"]==="boolean")slot.eligible=entry["eligible"];if(isRecord(
|
|
32
|
+
entry["relogin"])){const deadline=str(entry["relogin"]["deadline_iso"])??epochToIso(entry["relogin"]["deadline"]);if(deadline!==void 0)slot.relogin_deadline=deadline}applyIdentity(slot,entry["email"],identity);slots.push(slot)}const report={schema:CAPACITY_SCHEMA,provider:"claude",slots};const generatedAt=epochToIso(raw["generated_at"]);if(generatedAt!==void 0)report.generated_at=generatedAt;const active=str(raw["active"]);if(active!==void 0)report.active_slot=active;return report}function adaptCanonical(raw,identity){
|
|
33
|
+
if(!isRecord(raw))return null;if(str(raw["schema"])!==CAPACITY_SCHEMA)return null;const report={...raw};if(identity==="none"&&Array.isArray(report.slots)){report.slots=report.slots.map(slot=>{const stripped={...slot};delete stripped.identity_masked;delete stripped.identity_hash;return stripped})}return report}function summarize(slots){const s={total:slots.length,usable:0,excluded:0,needs_login:0,unknown:0};for(const slot of slots){const state=isRecord(slot)?slot.state:void 0;if(state==="usable"||
|
|
34
|
+
state==="excluded"||state==="needs_login")s[state]+=1;else s.unknown+=1}return s}function capacityError(reason){return JSON.stringify({schema:CAPACITY_SCHEMA,error:"probe_failed",reason})}function encodeCapacity(report){const withSummary={...report};if(Array.isArray(withSummary.slots)&&withSummary.summary===void 0){withSummary.summary=summarize(withSummary.slots)}const full=JSON.stringify(withSummary);if(Buffer.byteLength(full,"utf8")<=CAPACITY_MAX_BYTES)return full;const compact={...withSummary,
|
|
35
|
+
slots_omitted:true};delete compact.slots;const trimmed=JSON.stringify(compact);if(Buffer.byteLength(trimmed,"utf8")<=CAPACITY_MAX_BYTES)return trimmed;return capacityError("payload_too_large")}function parseCapacityProbe(value){const warnings=[];if(value===void 0||value===null)return{probe:null,warnings};if(!isRecord(value)){return{probe:null,warnings:["capacity_probe \u306F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u67A0\u306E\u89B3\u6E2C\u306F\u884C\u3044\u307E\u305B\u3093"]}}
|
|
36
|
+
const rawCommand=value["command"];if(!Array.isArray(rawCommand)||rawCommand.length===0){return{probe:null,warnings:["capacity_probe.command \u306F1\u3064\u4EE5\u4E0A\u306E\u6587\u5B57\u5217\u306E\u914D\u5217\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u67A0\u306E\u89B3\u6E2C\u306F\u884C\u3044\u307E\u305B\u3093"]}}for(const v of rawCommand){if(typeof v!=="string"||v.trim()===""){return{probe:null,warnings:["capacity_probe.command \u306E\u8981\u7D20\u306F\u7A7A\u3067\u306A\u3044\u6587\u5B57\u5217\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u67A0\u306E\u89B3\u6E2C\u306F\u884C\u3044\u307E\u305B\u3093"]}}}
|
|
37
|
+
let format=DEFAULT_CAPACITY_PROBE.format;const rawFormat=value["format"];if(rawFormat!==void 0&&rawFormat!==null){if(typeof rawFormat==="string"&&CAPACITY_FORMATS.includes(rawFormat.trim())){format=rawFormat.trim()}else{warnings.push(`capacity_probe.format \u306F ${CAPACITY_FORMATS.join(" / ")} \u306E\u3044\u305A\u308C\u304B\u3067\u3059\uFF08\u65E2\u5B9A '${DEFAULT_CAPACITY_PROBE.format}' \u3092\u4F7F\u3044\u307E\u3059\uFF09`)}}let identity=DEFAULT_CAPACITY_PROBE.identity;const rawIdentity=value["\
|
|
38
|
+
identity"];if(rawIdentity!==void 0&&rawIdentity!==null){if(typeof rawIdentity==="string"&&IDENTITY_MODES.includes(rawIdentity.trim())){identity=rawIdentity.trim()}else{warnings.push(`capacity_probe.identity \u306F ${IDENTITY_MODES.join(" / ")} \u306E\u3044\u305A\u308C\u304B\u3067\u3059\uFF08\u65E2\u5B9A '${DEFAULT_CAPACITY_PROBE.identity}' \u3092\u4F7F\u3044\u307E\u3059\uFF09`)}}const interval=intField(value["interval"],"interval",DEFAULT_CAPACITY_PROBE.interval,warnings);const timeout=intField(
|
|
39
|
+
value["timeout"],"timeout",DEFAULT_CAPACITY_PROBE.timeout,warnings,TIMEOUT_MAX_SEC);return{probe:{command:rawCommand.map(v=>v.trim()),format,interval,timeout,identity},warnings}}var TIMEOUT_MAX_SEC=60;function intField(value,key,fallback,warnings,max){if(value===void 0||value===null||value==="")return fallback;const n=typeof value==="number"?value:Number.parseInt(String(value),10);if(Number.isInteger(n)&&n>=1){if(max!==void 0&&n>max){warnings.push(`capacity_probe.${key} \u306F ${max} \u4EE5\u4E0B\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\
|
|
40
|
+
\uFF08${max} \u306B\u4E38\u3081\u307E\u3059\u3002heartbeat \u306E\u9001\u4FE1\u3092\u5F85\u305F\u305B\u308B\u6642\u9593\u3067\u3059\uFF09`);return max}return n}warnings.push(`capacity_probe.${key} \u306F1\u4EE5\u4E0A\u306E\u6574\u6570\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u65E2\u5B9A ${fallback} \u3092\u4F7F\u3044\u307E\u3059\uFF09`);return fallback}function classify(outcome){switch(outcome.failure){case"timeout":return"timeout";case"spawn":return"spawn_failed";case"empty":
|
|
41
|
+
return"empty_output";default:return"exit_status"}}async function probeCapacity(probe,cwd,log,env=process.env){const outcome=await runHook({id:"capacity_probe",command:probe.command,timeout:probe.timeout},cwd,env);if(!outcome.ok){const reason=classify(outcome);log(` \u26A0\uFE0F capacity_probe \u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${reason}: ${(outcome.reason??"\u7406\u7531\u4E0D\u660E").slice(0,200)}\uFF09\u3002\u67A0\u60C5\u5831\u306A\u3057\u3067\u7D9A\u884C\u3057\u307E\u3059`);return capacityError(
|
|
42
|
+
reason)}let parsed;try{parsed=JSON.parse(outcome.stdout)}catch{log(" \u26A0\uFE0F capacity_probe \u306E\u51FA\u529B\u3092 JSON \u3068\u3057\u3066\u89E3\u91C8\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u67A0\u60C5\u5831\u306A\u3057\u3067\u7D9A\u884C\u3057\u307E\u3059");return capacityError("invalid_json")}try{const report=probe.format==="claude_auto_switch/v1"?adaptClaudeAutoSwitch(parsed,probe.identity):adaptCanonical(parsed,probe.identity);if(report===null){log(` \u26A0\uFE0F capacity_prob\
|
|
43
|
+
e \u306E\u51FA\u529B\u304C ${probe.format} \u306E\u60F3\u5B9A\u3068\u9055\u3044\u307E\u3059\u3002\u67A0\u60C5\u5831\u306A\u3057\u3067\u7D9A\u884C\u3057\u307E\u3059`);return capacityError("unexpected_shape")}return encodeCapacity(report)}catch{log(` \u26A0\uFE0F capacity_probe \u306E\u51FA\u529B\u3092 ${probe.format} \u3068\u3057\u3066\u5909\u63DB\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u67A0\u60C5\u5831\u306A\u3057\u3067\u7D9A\u884C\u3057\u307E\u3059`);return capacityError("unexp\
|
|
44
|
+
ected_shape")}}var CapacityReporter=class{constructor(probe,cwd,log,env=process.env,now=()=>Date.now()){this.probe=probe;this.cwd=cwd;this.log=log;this.env=env;this.now=now}probe;cwd;log;env;now;cached=null;lastProbedAt=0;pending=false;running=false;async refreshIfDue(){const at=this.now();if(this.cached!==null&&at-this.lastProbedAt<this.probe.interval*1e3)return;await this.refresh()}async refresh(){if(this.running)return;this.running=true;try{this.cached=await probeCapacity(this.probe,this.cwd,
|
|
45
|
+
this.log,this.env);this.lastProbedAt=this.now();this.pending=true}finally{this.running=false}}take(){if(!this.pending||this.cached===null)return null;this.pending=false;return this.cached}rearm(){if(this.cached!==null)this.pending=true}};function evaluateOwnership(item,runnerId,runId){if(!item){return{verdict:"unknown",reason:"\u30A2\u30A4\u30C6\u30E0\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"}}if(runnerId===""||runId===""){return{verdict:"unknown",reason:"\u81EA\u5206\u306E runner_id / run_id \u304C\u7A7A\u3067\u3059"}}const status=(item.status??"").trim();if(status===""){return{verdict:"unknown",reason:"\u5FDC\u7B54\u306B status \u304C\u3042\u308A\u307E\u305B\u3093"}}if(status!=="processing"){return{verdict:"\
|
|
46
|
+
lost",reason:`status=${status}\uFF08processing \u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF09`}}const itemRunner=(item.runner_id??"").trim();const itemRun=(item.run_id??"").trim();if(itemRunner===""||itemRun===""){return{verdict:"unknown",reason:"\u5FDC\u7B54\u306B runner_id / run_id \u304C\u3042\u308A\u307E\u305B\u3093"}}if(itemRunner!==runnerId){return{verdict:"lost",reason:`\u5225\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08runner=${itemRunner}\uFF09`}}
|
|
47
|
+
if(itemRun!==runId){return{verdict:"lost",reason:`\u540C\u3058\u6A5F\u4F53\u306E\u5225\u306E\u8D77\u52D5\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08run_id \u304C\u4E00\u81F4\u3057\u307E\u305B\u3093\uFF09`}}return{verdict:"held",reason:"processing \u304B\u3064 runner_id / run_id \u304C\u4E00\u81F4"}}var OWNERSHIP_CHECK_INTERVAL_SEC=60;var NO_OPERATIONS={exclusiveSkills:new Set,statusEndpoint:null,highRiskSkills:new Set,preflightHosts:[],releaseRecoverySkill:null,postSuccessEnqueue:new Map,contractSkills:new Set,zeroTargetGates:{}};var DEFAULT_STATUS_PATH="/api/release/list";var DEFAULT_STATUS_HEADER="X-API-Key";function stringArray(value,label,warnings){if(value===void 0||value===null)return[];if(!Array.isArray(value)){warnings.push(`operations.${label} \u306F\u914D\u5217\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u7121\u8996\u3057\u307E\u3059\uFF09`);
|
|
28
48
|
return[]}const out=[];for(const v of value){if(typeof v!=="string"||v.trim()===""){warnings.push(`operations.${label} \u306E\u8981\u7D20\u306F\u7A7A\u3067\u306A\u3044\u6587\u5B57\u5217\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u3053\u306E\u8981\u7D20\u306F\u7121\u8996\u3057\u307E\u3059\uFF09`);continue}out.push(v.trim())}return out}function stringMap(value,label,warnings){const out=new Map;if(value===void 0||value===null)return out;if(typeof value!=="object"||Array.isArray(value)){
|
|
29
49
|
warnings.push(`operations.${label} \u306F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u7121\u8996\u3057\u307E\u3059\uFF09`);return out}for(const[k,v]of Object.entries(value)){if(typeof v!=="string"||v.trim()===""){warnings.push(`operations.${label}.${k} \u306F\u7A7A\u3067\u306A\u3044\u6587\u5B57\u5217\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u3053\u306E\u9805\u76EE\u306F\u7121\u8996\u3057\u307E\u3059\uFF09`);continue}out.set(
|
|
30
50
|
k,v.trim())}return out}function parseZeroTargetGates(value,warnings){const out={};if(value===void 0||value===null)return out;if(typeof value!=="object"||Array.isArray(value)){warnings.push("operations.zero_target_gates \u306F\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u7121\u8996\u3057\u307E\u3059\uFF09");return out}for(const[skill,v]of Object.entries(value)){if(typeof v!=="object"||v===null||Array.isArray(v)){warnings.push(`operations.zero_ta\
|
|
@@ -44,14 +64,14 @@ env){const file=localConfigPath(projectId,env);try{const parsed=JSON.parse(fs.re
|
|
|
44
64
|
${err.message}`,{cause:err})}}function resolveRunnerId(stateDir,env=process.env){const file=env.RUNNER_ID_FILE&&env.RUNNER_ID_FILE.trim()!==""?env.RUNNER_ID_FILE:path.join(stateDir,"runner-id");let candidate=env.RUNNER_ID?.trim()??"";if(!candidate){try{candidate=fs.readFileSync(file,"utf8").split("\n")[0]?.trim()??""}catch{candidate=""}}let warning=null;if(candidate&&!/^[A-Za-z0-9._-]+$/.test(candidate)){warning=`runner_id '${candidate}' \u306B\u4F7F\u3048\u306A\u3044\u6587\u5B57\u304C\u542B\u307E\u308C\u308B\u305F\u3081\u63A1\u756A\u3057\u76F4\u3057\u307E\u3057\u305F\uFF08[A-Za-z0-9._-] \u306E\u307F\uFF09`;
|
|
45
65
|
candidate=""}if(!candidate){const host=(os.hostname()||"host").split(".")[0]??"host";const hostPart=host.replace(/[^A-Za-z0-9._-]/g,"-").slice(0,32)||"host";candidate=`${hostPart}-${randomBytes(4).toString("hex")}`;try{fs.mkdirSync(path.dirname(file),{recursive:true,mode:448});fs.writeFileSync(file,`${candidate}
|
|
46
66
|
`,{mode:384})}catch{warning=`runner_id \u3092 ${file} \u3078\u4FDD\u5B58\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u8D77\u52D5\u306E\u305F\u3073\u306B\u5225\u30E9\u30F3\u30CA\u30FC\u3068\u3057\u3066\u767B\u9332\u3055\u308C\u3001\u53F0\u6570\u4E0A\u9650\u306B\u9054\u3057\u307E\u3059`}}return{runnerId:candidate,warning}}function buildRunId(runnerId,now=new Date){const stamp=now.toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z");return`${runnerId}#${stamp}#${process.pid}`}function buildLoopConfig(input){
|
|
47
|
-
const env=input.env??process.env;const warnings=[];const
|
|
67
|
+
const env=input.env??process.env;const warnings=[];const num2=(raw,fallback,min=1,label="")=>{const r=sanitizeInt(raw,fallback,min);if(r.warning)warnings.push(`${label}${r.warning}`);return r.value};if(input.daemon&&input.maxCycles!==void 0){warnings.push("--daemon \u3068 --max-cycles \u306F\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\uFF08--daemon \u3092\u512A\u5148\u3057\u3001--max-cycles \u306F\u7121\u8996\u3057\u307E\u3059\uFF09")}const local=loadLocalConfig(input.projectId,env);
|
|
48
68
|
if(local.schedule_command&&local.schedule_command.length>0){warnings.push("\u30ED\u30FC\u30AB\u30EB\u8A2D\u5B9A\u306E schedule_command \u306F\u4F7F\u308F\u308C\u307E\u305B\u3093\uFF08\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306E\u5224\u5B9A\u306F twp-cli \u5185\u3067\u884C\u3044\u307E\u3059\uFF09\u3002\u8A2D\u5B9A\u304B\u3089\u524A\u9664\u3057\u3066\u304F\u3060\u3055\u3044")}if(nonEmpty(env.TWP_TASK_LOOP_SCHEDULE_CMD)){warnings.push("TWP_TASK_LOOP_SCHEDULE_CMD \u306F\u4F7F\u308F\u308C\u307E\u305B\u3093\uFF08\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306E\u5224\u5B9A\u306F twp-c\
|
|
49
|
-
li \u5185\u3067\u884C\u3044\u307E\u3059\uFF09")}const stateDir=loopStateDir(env);const{runnerId,warning:runnerWarning}=resolveRunnerId(stateDir,env);if(runnerWarning)warnings.push(runnerWarning);const aiTimeoutSec=
|
|
50
|
-
local.workspace)??process.cwd();const ai=loadAiConfig(local.ai,local.ai_config_file,workspace);warnings.push(...ai.warnings);const operations=parseOperations(local.operations);warnings.push(...operations.warnings);const claudeLauncher=parseClaudeLauncher(local.claude_launcher);warnings.push(...claudeLauncher.warnings);const
|
|
51
|
-
projectId:input.projectId,projectRef:input.projectRef,apiUrl:input.apiUrl,runnerId,runId:buildRunId(runnerId,input.now??new Date),stateDir,logDir:nonEmpty(env.LOG_DIR)??local.log_dir??path.join(os.homedir(),".twp-agent-loop","logs"),logRetentionDays:
|
|
52
|
-
300,forceRunner:input.forceRunner,engine:nonEmpty(input.engine)??nonEmpty(local.engine)??"",aiTimeoutSec,aiSoftDeadlineRatio,planTimeoutSec:
|
|
53
|
-
|
|
54
|
-
env.PLAN_LOCK_STEAL_ATTEMPTS,3,0,"PLAN_LOCK_STEAL_ATTEMPTS="),planLockPermanentMax:
|
|
55
|
-
env.AGENT_LOOP_WRITEBACK_MAX_AGE_DAYS,7,1,"AGENT_LOOP_WRITEBACK_MAX_AGE_DAYS="),scheduleTimezone:nonEmpty(env.AGENT_LOOP_SCHEDULE_TZ)??"Asia/Tokyo",counterTimezone:nonEmpty(env.AGENT_LOOP_COUNTER_TZ)??"Asia/Tokyo",compileCommand:local.compile_command!==void 0&&local.compile_command.length>0?local.compile_command:null,charterFile:nonEmpty(env.CHARTER_FILE)??nonEmpty(local.
|
|
56
|
-
m)),charterPrefix:charterWrapper(env.CHARTER_PREFIX,local.charter_prefix,"charter_prefix",m=>warnings.push(m)),charterSuffix:charterWrapper(env.CHARTER_SUFFIX,local.charter_suffix,"charter_suffix",m=>warnings.push(m)),planEnabled:resolveBoolSetting(env.PLAN_ENABLED,local.plan_enabled,"plan_enabled",true,"\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u3092\u5B9F\u884C\u3057\u307E\u3059",
|
|
57
|
-
hooks,preflight:preflight.hooks,configHash:ai.config.hash(),version:input.version,warnings,releaseOutcomeLogPath:releaseOutcomeLogPath(env)}}function localDate(timezone,now=new Date){const fmt=new Intl.DateTimeFormat("en-CA",{timeZone:timezone,year:"numeric",month:"2-digit",day:"2-digit"});return fmt.format(now)}export{
|
|
69
|
+
li \u5185\u3067\u884C\u3044\u307E\u3059\uFF09")}const stateDir=loopStateDir(env);const{runnerId,warning:runnerWarning}=resolveRunnerId(stateDir,env);if(runnerWarning)warnings.push(runnerWarning);const aiTimeoutSec=num2(env.AI_TIMEOUT??local.ai_timeout,4500,60,"AI_TIMEOUT=");const aiSoftDeadlineRatio=Math.min(num2(env.AI_SOFT_DEADLINE_RATIO??local.ai_soft_deadline_ratio,80,1,"AI_SOFT_DEADLINE_RATIO="),100);const planLockTtlSec=num2(env.PLAN_LOCK_TTL,1800,60,"PLAN_LOCK_TTL=");const workspace=nonEmpty(
|
|
70
|
+
local.workspace)??process.cwd();const ai=loadAiConfig(local.ai,local.ai_config_file,workspace);warnings.push(...ai.warnings);const operations=parseOperations(local.operations);warnings.push(...operations.warnings);const claudeLauncher=parseClaudeLauncher(local.claude_launcher);warnings.push(...claudeLauncher.warnings);const capacityProbe=parseCapacityProbe(local.capacity_probe);warnings.push(...capacityProbe.warnings);const prefetch=validateHooks(local.prefetch);warnings.push(...prefetch.warnings);
|
|
71
|
+
const preflight=validateHooks(local.preflight,"preflight");warnings.push(...preflight.warnings);return{projectId:input.projectId,projectRef:input.projectRef,apiUrl:input.apiUrl,runnerId,runId:buildRunId(runnerId,input.now??new Date),stateDir,logDir:nonEmpty(env.LOG_DIR)??local.log_dir??path.join(os.homedir(),".twp-agent-loop","logs"),logRetentionDays:num2(env.LOG_RETENTION_DAYS??local.log_retention_days,7,0,"LOG_RETENTION_DAYS="),workspace,gitIdentity:local.git_identity,safeMode:input.safeMode,daemon:input.
|
|
72
|
+
daemon,maxCycles:input.daemon?Number.MAX_SAFE_INTEGER:input.maxCycles??1,intervalSec:input.intervalSec??300,forceRunner:input.forceRunner,engine:nonEmpty(input.engine)??nonEmpty(local.engine)??"",aiTimeoutSec,aiSoftDeadlineRatio,planTimeoutSec:num2(env.PLAN_TIMEOUT??local.plan_timeout,900,60,"PLAN_TIMEOUT="),heartbeatIntervalSec:num2(env.AGENT_LOOP_HEARTBEAT_INTERVAL,120,1,"AGENT_LOOP_HEARTBEAT_INTERVAL="),ownershipCheckIntervalSec:num2(env.AGENT_LOOP_OWNERSHIP_CHECK_INTERVAL,OWNERSHIP_CHECK_INTERVAL_SEC,
|
|
73
|
+
0,"AGENT_LOOP_OWNERSHIP_CHECK_INTERVAL="),contendedMax:num2(env.AGENT_LOOP_CONTENDED_MAX,10,1,"AGENT_LOOP_CONTENDED_MAX="),queueUndeterminedMax:num2(env.QUEUE_UNDETERMINED_MAX,5,1,"QUEUE_UNDETERMINED_MAX="),staleReclaimHours:num2(env.STALE_RECLAIM_HOURS,3,0,"STALE_RECLAIM_HOURS="),planLockTtlSec,planLockWaitMaxSec:num2(env.PLAN_LOCK_WAIT_MAX,planLockTtlSec,0,"PLAN_LOCK_WAIT_MAX="),planLockPollIntervalSec:num2(env.PLAN_LOCK_POLL_INTERVAL,60,1,"PLAN_LOCK_POLL_INTERVAL="),planLockRenewIntervalSec:num2(
|
|
74
|
+
env.PLAN_LOCK_RENEW_INTERVAL,Math.trunc(planLockTtlSec/3),1,"PLAN_LOCK_RENEW_INTERVAL="),planLockStealAttempts:num2(env.PLAN_LOCK_STEAL_ATTEMPTS,3,0,"PLAN_LOCK_STEAL_ATTEMPTS="),planLockPermanentMax:num2(env.PLAN_LOCK_PERMANENT_MAX,3,1,"PLAN_LOCK_PERMANENT_MAX="),scheduleMidcycleMax:num2(env.SCHEDULE_MIDCYCLE_MAX,6,1,"SCHEDULE_MIDCYCLE_MAX="),blockerRecoveryMaxPerDay:num2(env.BLOCKER_RECOVERY_MAX_PER_DAY,2,1,"BLOCKER_RECOVERY_MAX_PER_DAY="),releaseRerunAutoEnqueue:env.RELEASE_RERUN_AUTOENQUEUE_ENABLED!==
|
|
75
|
+
"false",releaseRerunMaxPerCause:num2(env.RELEASE_RERUN_MAX_PER_CAUSE,2,1,"RELEASE_RERUN_MAX_PER_CAUSE="),writebackMaxAgeDays:num2(env.AGENT_LOOP_WRITEBACK_MAX_AGE_DAYS,7,1,"AGENT_LOOP_WRITEBACK_MAX_AGE_DAYS="),scheduleTimezone:nonEmpty(env.AGENT_LOOP_SCHEDULE_TZ)??"Asia/Tokyo",counterTimezone:nonEmpty(env.AGENT_LOOP_COUNTER_TZ)??"Asia/Tokyo",compileCommand:local.compile_command!==void 0&&local.compile_command.length>0?local.compile_command:null,charterFile:nonEmpty(env.CHARTER_FILE)??nonEmpty(local.
|
|
76
|
+
charter_file)??"CONSTITUTION.md",charterEnabled:resolveCharterEnabled(env.CHARTER_ENABLED,local.charter_enabled,m=>warnings.push(m)),charterPrefix:charterWrapper(env.CHARTER_PREFIX,local.charter_prefix,"charter_prefix",m=>warnings.push(m)),charterSuffix:charterWrapper(env.CHARTER_SUFFIX,local.charter_suffix,"charter_suffix",m=>warnings.push(m)),planEnabled:resolveBoolSetting(env.PLAN_ENABLED,local.plan_enabled,"plan_enabled",true,"\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u3092\u5B9F\u884C\u3057\u307E\u3059",
|
|
77
|
+
m=>warnings.push(m)),ai:ai.config,operations:operations.operations,claudeLauncher:claudeLauncher.launcher,capacityProbe:capacityProbe.probe,prefetch:prefetch.hooks,preflight:preflight.hooks,configHash:ai.config.hash(),version:input.version,warnings,releaseOutcomeLogPath:releaseOutcomeLogPath(env)}}function localDate(timezone,now=new Date){const fmt=new Intl.DateTimeFormat("en-CA",{timeZone:timezone,year:"numeric",month:"2-digit",day:"2-digit"});return fmt.format(now)}export{runPrefetch,runPreflight,formatHookWiring,formatHookIds,CapacityReporter,parseClaudeLauncher,evaluateOwnership,describeOperations,loopStateDir,localConfigPath,buildLoopConfig,localDate};
|
package/dist/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ if(out.output!==void 0)out.unknown.push("--output");if(out.query!==void 0)out.un
|
|
|
24
24
|
void 0)out.unknown.push("--counts");if(out.scheduleGate!==void 0)out.unknown.push("--gate")}if(out.command==="task-loop"&&out.taskLoopAction!=="stop"&&out.stopForce){out.unknown.push("--force")}if(out.command==="task-loop"&&out.taskLoopAction!=="stop"&&out.stopDrain){out.unknown.push("--drain")}if(out.command==="task-loop"&&out.taskLoopAction==="stop"&&out.stopForce&&out.stopDrain){out.unknown.push("--force \u3068 --drain \u306F\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093");out.stopForce=
|
|
25
25
|
false;out.stopDrain=false}if(out.command==="task-loop"&&out.taskLoopAction!=="setup"){if(out.yes)out.unknown.push("--yes");if(out.ais!==void 0)out.unknown.push("--ai");if(out.workspace!==void 0)out.unknown.push("--workspace");if(out.aiConfigFile!==void 0)out.unknown.push("--ai-config-file");if(out.noAiConfigFile)out.unknown.push("--no-ai-config-file")}if(out.command==="task-loop"&&(out.taskLoopAction==="stop"||out.taskLoopAction==="status")){if(out.safe)out.unknown.push("--safe");if(out.daemon)out.
|
|
26
26
|
unknown.push("--daemon");if(out.forceRunner)out.unknown.push("--force-runner");if(out.engine!==void 0)out.unknown.push("--engine");if(out.interval!==void 0)out.unknown.push("--interval");if(out.maxCycles!==void 0)out.unknown.push("--max-cycles")}if(out.command==="task-loop"&&out.taskLoopAction==="setup"){if(out.engine!==void 0)out.unknown.push("--engine");if(out.safe)out.unknown.push("--safe");if(out.daemon)out.unknown.push("--daemon");if(out.forceRunner)out.unknown.push("--force-runner");if(out.
|
|
27
|
-
interval!==void 0)out.unknown.push("--interval");if(out.maxCycles!==void 0)out.unknown.push("--max-cycles")}return out}var VERSION=true?"0.
|
|
27
|
+
interval!==void 0)out.unknown.push("--interval");if(out.maxCycles!==void 0)out.unknown.push("--max-cycles")}return out}var VERSION=true?"0.16.0":"0.0.0-dev";var HELP=`twp ${VERSION} \u2014 TWP CLI
|
|
28
28
|
|
|
29
29
|
\u4F7F\u3044\u65B9:
|
|
30
30
|
twp \u5BFE\u8A71 TUI \u3092\u8D77\u52D5
|
|
@@ -152,6 +152,6 @@ TUI \u5185:
|
|
|
152
152
|
${HELP}`);process.exitCode=2;return}if(args.command==="domain"&&args.domain!==void 0){const{runDomain}=await import("./run-BJQLIPWN.js");process.exitCode=await runDomain({domain:args.domain,...args.operation!==void 0?{operation:args.operation}:{},argv:args.domainArgv,help:args.domainHelp,globals:{...args.profile!==void 0?{profile:args.profile}:{},...args.output!==void 0?{output:args.output}:{},...args.query!==void 0?{query:args.query}:{},dryRun:args.dryRun,debug:args.debug,yes:args.yes,refresh:args.
|
|
153
153
|
refresh},version:VERSION});return}if(args.command==="api"){const{runApiCommand}=await import("./api-command-HGTPIEAP.js");process.exitCode=await runApiCommand({argv:args.domainArgv,help:args.domainHelp,globals:{...args.profile!==void 0?{profile:args.profile}:{},...args.output!==void 0?{output:args.output}:{},...args.query!==void 0?{query:args.query}:{},dryRun:args.dryRun,debug:args.debug,yes:args.yes},version:VERSION});return}if(args.command==="update"){const{runUpdate}=await import("./update-WDWUECN7.js");
|
|
154
154
|
process.exitCode=await runUpdate({...args.profile!==void 0?{profile:args.profile}:{},version:VERSION});return}if(args.command==="login"||args.command==="logout"||args.command==="whoami"){const{runLogin,runLogout,runWhoami}=await import("./commands-VUWI4ERO.js");const options={profile:args.profile,method:args.loginMethod,tenant:args.tenant,noBrowser:args.loginNoBrowser,cliVersion:VERSION};const runner=args.command==="login"?runLogin:args.command==="logout"?runLogout:runWhoami;process.exitCode=
|
|
155
|
-
await runner(options);return}if(args.command==="task-loop"){const{runTaskLoop}=await import("./commands-
|
|
155
|
+
await runner(options);return}if(args.command==="task-loop"){const{runTaskLoop}=await import("./commands-UGGBVOYU.js");process.exitCode=await runTaskLoop({action:args.taskLoopAction??"run",project:args.project,profile:args.profile,safe:args.safe,daemon:args.daemon,interval:args.interval,maxCycles:args.maxCycles,forceRunner:args.forceRunner,force:args.stopForce,drain:args.stopDrain,engine:args.engine,version:VERSION,verbose:args.verbose,scheduleNow:args.scheduleNow,scheduleCounts:args.scheduleCounts,
|
|
156
156
|
scheduleGate:args.scheduleGate,yes:args.yes,ais:args.ais,workspace:args.workspace,aiConfigFile:args.aiConfigFile,noAiConfigFile:args.noAiConfigFile});return}if(args.command==="print"){const{runOneShot}=await import("./oneshot-HQJEXZHJ.js");process.exitCode=await runOneShot({prompt:args.prompt??"",fromStdin:args.promptFromStdin,mode:args.mode??"dev",...args.permissionMode!==void 0?{permissionMode:args.permissionMode}:{},...args.model!==void 0?{model:args.model}:{},...args.profile!==void 0?{profile:args.
|
|
157
157
|
profile}:{},version:VERSION});return}const{startTui}=await import("./app-LLSZV6SM.js");await startTui({mode:args.mode,permissionMode:args.permissionMode,model:args.model,profile:args.profile,noTui:args.noTui||!process.stdout.isTTY,doctor:args.doctor,version:VERSION})}await main();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{EngineNotConfiguredError,NoopEngine,UnknownEngineError,aiUnavailableLabel,assertKnownEngine,failureHint,isAiUnavailable,needsHumanToRestoreAi}from"./chunk-ZOOEH7ZE.js";import{buildLoopConfig,describeOperations,evaluateOwnership,formatHookIds,formatHookWiring,localDate,loopStateDir,runPrefetch,runPreflight}from"./chunk-
|
|
3
|
+
import{EngineNotConfiguredError,NoopEngine,UnknownEngineError,aiUnavailableLabel,assertKnownEngine,failureHint,isAiUnavailable,needsHumanToRestoreAi}from"./chunk-ZOOEH7ZE.js";import{CapacityReporter,buildLoopConfig,describeOperations,evaluateOwnership,formatHookIds,formatHookWiring,localDate,loopStateDir,runPrefetch,runPreflight}from"./chunk-EZCMF4I3.js";import{claudeConfigDir,exclusiveInflightEntries,formatExclusiveEntry,normalizeSkillName,resolveDetectDeps,skillOfItem,spawnSyncResolved}from"./chunk-3WJHTPOZ.js";
|
|
4
4
|
import{AgentLoopApi,REQUIRE_ZERO_STATUS,ScheduleApi,collectDue,describeError,filterByStatus,gateStatus,isPermanent,nowInZone,parseCounts,pick,pickString,promptSection}from"./chunk-N56AWWTM.js";import{compareVersionCores,parseVersionCore}from"./chunk-DXXFUNYN.js";import{killProcessTree,system32}from"./chunk-N2UVRM3Z.js";import{joinFor}from"./chunk-PMOUHEJQ.js";import{PRIVATE_PROJECT_REF,isPrivateProjectRef,privateProjectId,projectFileKey}from"./chunk-GY7KI5E5.js";import{
|
|
5
5
|
AuthSession}from"./chunk-63LDNYGW.js";import{extractLeadingTaskKey}from"./chunk-II5RVJQN.js";import{effectiveApiUrl,resolveProfile}from"./chunk-NERYSBA4.js";import"./chunk-RZVI6PMW.js";import{httpFetch}from"./chunk-J7QYPKVK.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import{resolveProjectRef,uuidProjectIdPolicy}from"./chunk-5QCAIKFE.js";import"./chunk-VSJBJXZO.js";import fs11 from"fs";import path9 from"path";import{execFileSync}from"child_process";import fs from"fs";import path from"path";var DEFAULT_GRACE_MS=6e4;var InstanceLock=class{constructor(lockDir2,opts={}){this.lockDir=lockDir2;this.opts=opts}lockDir;opts;owned=null;acquire(){const mine=this.tryMkdir();if(mine)return{acquired:true,reason:"",note:null};const oldPid=this.readPid();if(oldPid!==null){if(this.isLoop(oldPid)){return{acquired:false,reason:`\u540C\u3058\u30DE\u30B7\u30F3\u3067\u5225\u306E task-loop \u304C\u7A3C\u50CD\u4E2D\u3067\u3059\uFF08pid=${oldPid} / \u30ED\u30C3\u30AF: ${this.lockDir}\uFF09`,note:null}}const note=`\
|
|
6
6
|
\u30ED\u30C3\u30AF\u306EPID ${oldPid} \u306F\u5225\u306E\u30D7\u30ED\u30BB\u30B9\u306B\u518D\u5229\u7528\u3055\u308C\u3066\u3044\u307E\u3059\uFF08\u30EB\u30FC\u30D7\u3067\u306F\u306A\u3044\uFF09\u2192 \u6B8B\u9AB8\u3068\u3057\u3066\u5F15\u304D\u53D6\u308A\u307E\u3059`;return this.takeOver(note)}const age=this.lockAgeMs();const grace=this.opts.graceMs??DEFAULT_GRACE_MS;if(age===null||age<grace){return{acquired:false,reason:`\u30ED\u30C3\u30AF\u304C\u4F5C\u6210\u76F4\u5F8C\u306E\u305F\u3081\u5F85\u6A5F\u5074\u306B\u5012\u3057\u307E\u3059\uFF08\u30ED\u30C3\u30AF: ${this.
|
|
@@ -28,25 +28,27 @@ since===null?null:this.now()-this.since;this.since=null;this.expired=false;retur
|
|
|
28
28
|
note:null}}if(this.expired)return{wait:false,logs:[this.expiredLog()],note:expiredNote()};const now=this.now();if(this.since===null){this.since=now;return{wait:true,logs:[` \u23F8 ${r.detail}`,` \u30C8\u30E9\u30B9\u30C8\u304C\u5C0E\u51FA\u3055\u308C\u308B\u307E\u3067\u30A2\u30A4\u30C6\u30E0\u3092\u53D6\u308A\u307E\u305B\u3093\uFF08\u6700\u5927${Math.round(this.timeoutMs/6e4)}\u5206\uFF09\u3002\u672A\u30C8\u30E9\u30B9\u30C8\u306E\u307E\u307E\u5B9F\u884C\u3059\u308B\u3068 permissions.allow \u304C\u7121\u8996\u3055\u308C\u3001\u6210\u679C\u3092\u51FA\u3057\u3066\u3082 untrusted \u3067\u8A18\u9332\u3055\u308C\u307E\u3059`],
|
|
29
29
|
note:null}}const waited=now-this.since;if(waited>=this.timeoutMs){this.expired=true;return{wait:false,logs:[this.expiredLog()],note:expiredNote()}}return{wait:true,logs:[` \u23F8 ${r.detail}\uFF08\u5F85\u6A5F ${Math.round(waited/1e3)}\u79D2\uFF09`],note:null}}expiredLog(){return` \u26D4 ${Math.round(this.timeoutMs/6e4)}\u5206\u5F85\u3063\u3066\u3082\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E\u30C8\u30E9\u30B9\u30C8\u304C\u5C0E\u51FA\u3055\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u7121\u8A00\u306E\u7121\u7A3C\u50CD\u3092\u907F\u3051\u308B\u305F\u3081\u901A\u5E38\u52D5\u4F5C\u3078\u843D\u3068\u3057\u307E\u3059\uFF08untrusted \u3067\u5931\u6557\u8A18\u9332\u304C\u6B8B\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\uFF09\u3002\u78BA\u8A8D: runner-state status \uFF0F \u67A0\u306E .claude.json \u306E projects[<workspace>].hasTrustDialogAccepted`}};
|
|
30
30
|
function expiredNote(){return["\u3010\u8B66\u544A: \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u304C\u672A\u30C8\u30E9\u30B9\u30C8\u3067\u3059\u3011","\u3053\u306E\u30DE\u30B7\u30F3\u306E claude \u306F\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092\u672A\u30C8\u30E9\u30B9\u30C8\u306E\u72B6\u614B\u3067\u8D77\u52D5\u3057\u3066\u3044\u307E\u3059\u3002","permissions.allow \u304C\u7121\u8996\u3055\u308C\u3001\u6210\u679C\u3092\u51FA\u3057\u5207\u3063\u3066\u3082\u5B9F\u884C\u7D50\u679C\u304C untrusted \u3068\u3057\u3066\u8A18\u9332\u3055\u308C\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002",
|
|
31
|
-
"\u30C8\u30E9\u30B9\u30C8\u306E\u5C0E\u51FA\uFF08runner-state \u306E2\u5206\u3054\u3068\u306E\u6CBB\u7652\uFF09\u304C30\u5206\u4EE5\u4E0A\u6210\u7ACB\u3057\u3066\u3044\u306A\u3044\u305F\u3081\u3001\u3053\u306E\u72B6\u614B\u306E\u307E\u307E\u5B9F\u884C\u3057\u3066\u3044\u307E\u3059\u3002"].join("\n")}import os from"os";var RunnerRegistrationError=class extends Error{};var RunnerSession=class{constructor(api,config,log,now=()=>Date.now()){this.api=api;this.config=config;this.log=log;this.now=now;this.forcePending=config.forceRunner}api;config;log;now;registered=false;heartbeatTimeoutServer=null;forcePending;hooksPayloadWarningLogged=false;timer=null;phase="idle";currentItemId="";lastTickAt=0;lastOkAt=0;failures=0;sending=false;silenceWarned=false;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.log.log(
|
|
40
|
-
this.log.log(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
\
|
|
44
|
-
this.
|
|
45
|
-
config.heartbeatIntervalSec
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
31
|
+
"\u30C8\u30E9\u30B9\u30C8\u306E\u5C0E\u51FA\uFF08runner-state \u306E2\u5206\u3054\u3068\u306E\u6CBB\u7652\uFF09\u304C30\u5206\u4EE5\u4E0A\u6210\u7ACB\u3057\u3066\u3044\u306A\u3044\u305F\u3081\u3001\u3053\u306E\u72B6\u614B\u306E\u307E\u307E\u5B9F\u884C\u3057\u3066\u3044\u307E\u3059\u3002"].join("\n")}import os from"os";var RunnerRegistrationError=class extends Error{};var RunnerSession=class{constructor(api,config,log,now=()=>Date.now()){this.api=api;this.config=config;this.log=log;this.now=now;this.forcePending=config.forceRunner;this.capacity=config.capacityProbe===null?null:new CapacityReporter(config.capacityProbe,config.workspace,m=>this.log.log(m),process.env,this.now)}api;config;log;now;registered=false;heartbeatTimeoutServer=null;forcePending;hooksPayloadWarningLogged=false;timer=null;phase="idle";currentItemId="";lastTickAt=0;lastOkAt=0;failures=0;sending=false;silenceWarned=false;capacity;capacityRefresh(force){
|
|
32
|
+
const reporter=this.capacity;if(reporter===null)return null;return(force?reporter.refresh():reporter.refreshIfDue()).catch(err=>{this.log.log(` \u26A0\uFE0F capacity_probe \u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF08${err.message}\uFF09\u3002\u67A0\u60C5\u5831\u306A\u3057\u3067\u7D9A\u884C\u3057\u307E\u3059`)})}payload(phase,itemId="",force=false){const p={runner_id:this.config.runnerId,run_id:this.config.runId,phase,pid:process.pid,safe_mode:this.config.safeMode};const host=os.
|
|
33
|
+
hostname();if(host)p.hostname=host;if(this.config.configHash)p.config_hash=this.config.configHash;const hooks=formatHookIds(this.config.prefetch,this.config.preflight);if(hooks.length<=512){p.hooks=hooks}else if(!this.hooksPayloadWarningLogged){this.log.log(` \u26A0\uFE0F \u30D5\u30C3\u30AF\u914D\u7DDA\u306E\u5831\u544A\u5024\u304C512\u6587\u5B57\u3092\u8D85\u3048\u305F\u305F\u3081\u53F0\u5E33\u3078\u306E\u5831\u544A\u3060\u3051\u3092\u7701\u7565\u3057\u307E\u3059\uFF08prefetch=${this.config.prefetch.
|
|
34
|
+
length}\u4EF6 / preflight=${this.config.preflight.length}\u4EF6\uFF09`);this.hooksPayloadWarningLogged=true}const capacity=this.capacity?.take()??null;if(capacity!==null)p.capacity=capacity;if(this.config.version)p.version=this.config.version;if(itemId)p.current_item_id=itemId;if(force)p.force=true;return p}async checkHeartbeatInterval(){const res=await this.api.runners();if(!res.ok)return;const timeout=pick(res.json,"heartbeat_timeout");if(typeof timeout!=="number")return;this.heartbeatTimeoutServer=
|
|
35
|
+
timeout;if(this.config.heartbeatIntervalSec>=timeout){this.log.log(` \u26A0\uFE0F AGENT_LOOP_HEARTBEAT_INTERVAL=${this.config.heartbeatIntervalSec}\u79D2 \u304C\u30B5\u30FC\u30D0\u306E\u6B7B\u6D3B\u3057\u304D\u3044\u5024 ${timeout}\u79D2 \u4EE5\u4E0A\u3067\u3059`);this.log.log(" \u3053\u306E\u307E\u307E\u3067\u306F\u81EA\u5206\u304C\u300C\u5FDC\u7B54\u306A\u3057\u300D\u3068\u5224\u5B9A\u3055\u308C\u3001\u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u3092\u4ED6\u6A5F\u306B\u56DE\u53CE\u3055\u308C\u3001\u8A08\u753B\u30ED\u30C3\u30AF\u306E\u5EF6\u9577\u3082 409 \u3067\u901A\u3089\u306A\u304F\u306A\u308A\u307E\u3059\uFF08\u3057\u304D\u3044\u5024\u306E 1/3 \u4EE5\u4E0B\u3092\u63A8\u5968\uFF09")}}async registerOrThrow(){
|
|
36
|
+
let lastStatus;let lastBody;let lastDetail;const registering=this.capacityRefresh(true);if(registering!==null)await registering;for(let attempt=1;;attempt++){const res=await this.api.registerRunner(this.payload("idle","",this.forcePending));this.forcePending=false;lastStatus=res.status;lastBody=res.json;lastDetail=describeError(res);if(res.ok){this.registered=true;this.log.log(` \u30E9\u30F3\u30CA\u30FC\u767B\u9332: ${this.config.runnerId}\uFF08run_id: ${this.config.runId}\uFF09`);return}const permanent=res.
|
|
37
|
+
status!==null&&res.status>=400&&res.status<500;if(!permanent&&attempt<3){this.log.log(` \u26A0\uFE0F \u30E9\u30F3\u30CA\u30FC\u767B\u9332\u306B\u5931\u6557\uFF08${lastDetail}\uFF09\u3002${attempt}\u56DE\u76EE\u30FB5\u79D2\u5F8C\u306B\u518D\u8A66\u884C\u3057\u307E\u3059`);this.capacity?.rearm();await sleep(5e3);continue}break}if(lastStatus===409){this.log.log("\u274C \u3053\u306E\u30E9\u30F3\u30CA\u30FCID\u306F\u5225\u30D7\u30ED\u30BB\u30B9\u304C\u7A3C\u50CD\u4E2D\u3068\u3057\u3066\u767B\u9332\u3055\u308C\u3066\u3044\u307E\u3059\uFF08HTTP 409\uFF09");
|
|
38
|
+
this.log.log(" \u524D\u306E\u30D7\u30ED\u30BB\u30B9\u304C\u7570\u5E38\u7D42\u4E86\u3057\u3066\u3044\u308B\u5834\u5408\u306F\u767B\u9332\u3092\u596A\u3063\u3066\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044:");this.log.log(` twp task-loop run --project ${this.config.projectRef} --force-runner`);this.log.log(" \u26A0\uFE0F \u305F\u3060\u3057**\u524D\u306E\u30D7\u30ED\u30BB\u30B9\u304C\u751F\u304D\u3066\u3044\u308B\u5834\u5408\u306F\u4F7F\u308F\u306A\u3044\u3053\u3068**\uFF08\u5B9F\u884C\u4E2D\u30A2\u30A4\u30C6\u30E0\u304C\u4E8C\u91CD\u306B\u8D70\u308A\u307E\u3059\uFF09");
|
|
39
|
+
this.log.log(` \uFF08\u30B5\u30FC\u30D0\u306E\u767B\u9332\u306F\u6B7B\u6D3B\u3057\u304D\u3044\u5024 ${this.heartbeatTimeoutServer??600}\u79D2 \u307E\u3067 live \u6271\u3044\u306E\u305F\u3081\u3001\u5F85\u3063\u3066\u3082\u6570\u5206\u304B\u304B\u308A\u307E\u3059\uFF09`)}else if(lastStatus===403){if(pickString(lastBody,"reason")==="max_runners_exceeded"){this.log.log("\u274C \u7A3C\u50CD\u30E9\u30F3\u30CA\u30FC\u304C\u4E0A\u9650\u306B\u9054\u3057\u3066\u3044\u307E\u3059\uFF08HTTP 403\u30FBmax_runners_exceeded\uFF09");
|
|
40
|
+
this.log.log(" \u53F0\u6570\u8A2D\u5B9A\uFF08\u30B5\u30FC\u30D0\u5074 AGENT_LOOP_MAX_RUNNERS\uFF09\u3092\u898B\u76F4\u3059\u304B\u3001\u4E0D\u8981\u306A\u30E9\u30F3\u30CA\u30FC\u3092\u505C\u6B62\u3057\u3066\u304F\u3060\u3055\u3044");this.log.log(" **--force-runner \u3067\u306F\u901A\u308A\u307E\u305B\u3093**\uFF08\u8A2D\u5B9A\u3092\u76F4\u3059\u307E\u3067\u540C\u3058\u7D50\u679C\u306B\u306A\u308A\u307E\u3059\uFF09")}else{this.log.log(`\u274C \u30E9\u30F3\u30CA\u30FC\u767B\u9332\u304C 403 \u3067\u62D2\u5426\u3055\u308C\u307E\u3057\u305F: ${lastDetail}`);
|
|
41
|
+
this.log.log(" \u53F0\u6570\u4E0A\u9650\u3068\u306F\u5225\u306E\u7406\u7531\u3067\u3059\u3002\u78BA\u8A8D: \u30ED\u30B0\u30A4\u30F3\u4E2D\u30E6\u30FC\u30B6\u30FC\u306E\u6A29\u9650\uFF0F\u30C6\u30CA\u30F3\u30C8\u306E\u30AF\u30EC\u30B8\u30C3\u30C8\u72B6\u614B")}}else{this.log.log(`\u274C \u30E9\u30F3\u30CA\u30FC\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${lastDetail}\uFF09\u3002\u767B\u9332\u3067\u304D\u306A\u3044\u72B6\u614B\u3067\u306F claim \u304C\u901A\u3089\u306A\u3044\u305F\u3081\u7D42\u4E86\u3057\u307E\u3059`)}
|
|
42
|
+
throw new RunnerRegistrationError(`\u30E9\u30F3\u30CA\u30FC\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08http=${lastStatus??"\u306A\u3057"}\uFF09`)}async beat(phase,itemId=""){this.phase=phase;this.currentItemId=itemId;if(!this.registered)return;const refreshing=this.capacityRefresh(false);if(refreshing!==null)await refreshing;const res=await this.api.heartbeatRunner(this.payload(phase,itemId));if(res.ok){this.markSent();return}if(res.status===409){this.log.log(" \u26A0\uFE0F heartbeat \u304C 4\
|
|
43
|
+
09\uFF08\u767B\u9332\u304C\u5225\u30D7\u30ED\u30BB\u30B9\u306B\u596A\u308F\u308C\u305F\u53EF\u80FD\u6027\uFF09\u3002\u6B21\u306E\u30A2\u30A4\u30C6\u30E0\u53D6\u5F97\u6642\u306B\u767B\u9332\u3057\u76F4\u3057\u307E\u3059");this.registered=false;this.failures+=1;return}this.failures+=1;this.log.log(` \u26A0\uFE0F heartbeat \u306E\u9001\u4FE1\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${describeError(res)}\u30FBphase=${phase}\uFF09\u3002\u7D9A\u304F\u3068\u4ED6\u6A5F\u304B\u3089\u5FDC\u7B54\u306A\u3057\u3068\u898B\u306A\u3055\u308C\u307E\u3059`)}markSent(){
|
|
44
|
+
if(this.failures>0){const silentSec=this.lastOkAt===0?0:Math.round((this.now()-this.lastOkAt)/1e3);this.log.log(` \u2705 heartbeat \u306E\u9001\u4FE1\u304C\u5FA9\u5E30\u3057\u307E\u3057\u305F\uFF08\u9023\u7D9A\u5931\u6557 ${this.failures}\u56DE\u30FB\u6C88\u9ED9 ${silentSec}\u79D2\uFF09`)}this.failures=0;this.silenceWarned=false;this.lastOkAt=this.now()}startHeartbeatWorker(){if(!this.registered){this.log.log(" \u26A0\uFE0F \u30E9\u30F3\u30CA\u30FC\u672A\u767B\u9332\u306E\u305F\u3081 heartbeat \u306E\u5468\u671F\u9001\u4FE1\u3092\u958B\u59CB\u3057\u307E\u305B\u3093\uFF08\u5B9F\u884C\u4E2D\u306B dead \u5224\u5B9A\u3055\u308C\u307E\u3059\uFF09");
|
|
45
|
+
return}if(this.timer)return;this.lastTickAt=this.now();if(this.lastOkAt===0)this.lastOkAt=this.now();this.timer=setInterval(()=>{void this.heartbeatTick()},this.config.heartbeatIntervalSec*1e3);this.timer.unref?.()}async heartbeatTick(){const intervalMs=this.config.heartbeatIntervalSec*1e3;const at=this.now();const sinceTick=this.lastTickAt===0?0:at-this.lastTickAt;this.lastTickAt=at;if(sinceTick>intervalMs*2){this.log.log(` \u26A0\uFE0F heartbeat \u306E\u5468\u671F\u9001\u4FE1\u304C ${Math.round(
|
|
46
|
+
sinceTick/1e3)}\u79D2\u3076\u308A\u306B\u767A\u706B\u3057\u307E\u3057\u305F\uFF08\u9593\u9694\u306F ${this.config.heartbeatIntervalSec}\u79D2\uFF09\u3002\u30D7\u30ED\u30BB\u30B9\u304C\u6B62\u307E\u3063\u3066\u3044\u305F\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059`)}if(this.sending){this.log.log(" \u26A0\uFE0F \u524D\u56DE\u306E heartbeat \u304C\u672A\u5B8C\u4E86\u306E\u305F\u3081\u4ECA\u56DE\u306E\u9001\u4FE1\u3092\u98DB\u3070\u3057\u307E\u3057\u305F\uFF08\u5FDC\u7B54\u304C\u9045\u5EF6\u3057\u3066\u3044\u307E\u3059\uFF09");
|
|
47
|
+
return}this.sending=true;try{const refreshing=this.capacityRefresh(false);if(refreshing!==null)await refreshing;const res=await this.api.heartbeatRunner(this.payload(this.phase,this.currentItemId));if(res.ok){this.markSent();return}this.failures+=1;if(res.status===409){this.registered=false;if(this.failures<=3||this.failures%5===0){this.log.log(` \u26A0\uFE0F heartbeat\uFF08\u5468\u671F\u9001\u4FE1\uFF09\u304C 409\u3002\u767B\u9332\u304C\u5225\u30D7\u30ED\u30BB\u30B9\u306B\u596A\u308F\u308C\u305F\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\uFF08${this.
|
|
48
|
+
failures}\u56DE\u9023\u7D9A\u30FB\u6B21\u306E\u30A2\u30A4\u30C6\u30E0\u53D6\u5F97\u6642\u306B\u767B\u9332\u3057\u76F4\u3057\u307E\u3059\uFF09`)}}else if(this.failures<=3||this.failures%5===0){this.log.log(` \u26A0\uFE0F heartbeat \u306E\u5468\u671F\u9001\u4FE1\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${describeError(res)}\u30FB${this.failures}\u56DE\u9023\u7D9A\u30FBphase=${this.phase}\uFF09`)}}catch(err){this.failures+=1;if(this.failures<=3||this.failures%5===0){this.log.log(` \u26A0\uFE0F hear\
|
|
49
|
+
tbeat \u306E\u5468\u671F\u9001\u4FE1\u3067\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF08${err.message}\u30FB${this.failures}\u56DE\u9023\u7D9A\uFF09`)}}finally{this.sending=false;this.warnIfSilent()}}warnIfSilent(){if(this.silenceWarned||this.lastOkAt===0)return;const timeout=this.heartbeatTimeoutServer??600;const silentSec=Math.round((this.now()-this.lastOkAt)/1e3);if(silentSec<timeout)return;this.silenceWarned=true;this.log.log(` \u26D4 heartbeat \u3092 ${silentSec}\u79D2 \u9001\u308C\u3066\u3044\u307E\u305B\u3093\uFF08\u30B5\u30FC\u30D0\
|
|
50
|
+
\u306E\u6B7B\u6D3B\u3057\u304D\u3044\u5024 ${timeout}\u79D2\uFF09\u3002\u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u304C\u4ED6\u6A5F\u306B\u56DE\u53CE\u3055\u308C\u3046\u308B\u72B6\u614B\u3067\u3059`)}stopHeartbeatWorker(){if(!this.timer)return;clearInterval(this.timer);this.timer=null}async deregister(){this.stopHeartbeatWorker();if(!this.registered)return;this.registered=false;await this.api.deregisterRunner(this.payload("idle"))}};function sleep(ms){return new Promise(resolve=>setTimeout(
|
|
51
|
+
resolve,ms))}var PlanLock=class{constructor(deps){this.deps=deps;this.renewIntervalSec=deps.config.planLockRenewIntervalSec}deps;held=false;startedAt="";failStreak=0;permanentFail=false;ownLastFinish="";lostReason=null;renewTimer=null;renewStopped=true;renewIntervalSec;renewInFlight=null;now(){return this.deps.now?.()??Date.now()}sleep(ms){return(this.deps.sleepFn??sleep)(ms)}async acquire(){const{api,config,log,runner}=this.deps;if(await this.alreadyPlannedByOther())return"not-needed";const deadline=this.now()+
|
|
50
52
|
config.planLockWaitMaxSec*1e3;let waited=false;let firstFinished="";let retriedRegister=false;let stealAttempts=0;for(;;){const res=await api.planStart(config.runnerId,config.runId);if(!res.ok&&res.status===409&&!retriedRegister){log.log(" \u26A0\uFE0F plan/start \u304C 409\uFF08\u30E9\u30F3\u30CA\u30FC\u672A\u767B\u9332\u6271\u3044\uFF09\u3002register \u304B\u3089\u3084\u308A\u76F4\u3057\u307E\u3059");retriedRegister=true;await this.deps.reregister();continue}if(!res.ok){this.failStreak+=1;if(isPermanent(
|
|
51
53
|
res)){log.log(` \u26D4 \u8A08\u753B\u30ED\u30C3\u30AF\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\uFF08HTTP ${res.status}\u30FB${this.failStreak}\u30B5\u30A4\u30AF\u30EB\u9023\u7D9A\uFF09\u3002**\u518D\u8A66\u884C\u3067\u306F\u89E3\u6D88\u3057\u307E\u305B\u3093**`);log.log(` \u30B5\u30FC\u30D0\u304C\u8FD4\u3057\u305F\u7406\u7531: ${describeError(res)}`);log.log(" \u78BA\u8A8D: \u30ED\u30B0\u30A4\u30F3\u4E2D\u30E6\u30FC\u30B6\u30FC\u306E\u6A29\u9650\uFF0F--project \u306E\u6307\u5B9A\uFF0FAPI \u306E\u63A5\u7D9A\u5148");
|
|
52
54
|
this.permanentFail=true}else{log.log(` \u26D4 \u8A08\u753B\u30ED\u30C3\u30AF\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${describeError(res)}\u30FB${this.failStreak}\u30B5\u30A4\u30AF\u30EB\u9023\u7D9A\uFF09\u3002\u6B21\u30B5\u30A4\u30AF\u30EB\u3067\u518D\u8A66\u884C\u3057\u307E\u3059`);this.permanentFail=false}log.log(" **\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u306E\u8A08\u753B\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u307E\u3059**\uFF08\u6392\u4ED6\u304C\u53D6\u308C\u306A\u3044\u72B6\u614B\u3067\u8A08\u753B\u3059\u308B\u3068\u3001\u8907\u6570\u53F0\u304C\u540C\u3058\u8A08\u753B\u3092\u7A4D\u307F\u307E\u3059\uFF09");
|
|
@@ -321,7 +323,7 @@ operations.preflightHosts;return new DispatchEngine(config.ai,log,{workspace:con
|
|
|
321
323
|
return path9.join(config.stateDir,`task-loop-${projectFileKey(config.projectId)}.lock.d`)}async function runTaskLoop(opts){if(opts.action==="stop")return await stopLoop(opts);const profile=resolveProfile(opts.profile);let creds;try{creds=new AuthSession(profile.name,profile.apiUrl).loadOrThrow()}catch(err){process.stderr.write(`${err.message}
|
|
322
324
|
`);return 1}const apiUrl=effectiveApiUrl(profile,creds.api_url);const session=new AuthSession(profile.name,apiUrl);const projectRef=opts.project??process.env.TWP_PROJECT??"";if(projectRef===""){process.stderr.write("--project <\u30AD\u30FC|UUID> \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08TWP_PROJECT \u3067\u3082\u53EF\uFF09\n");return 2}const projectApi=new ProjectApi(apiUrl,session);let project;try{project=await projectApi.resolve(projectRef)}catch(err){process.stderr.write(`${err.
|
|
323
325
|
message}
|
|
324
|
-
`);return 1}const projectId=project.id;if(opts.action==="setup"){const{runSetup,parseAiList}=await import("./setup-
|
|
326
|
+
`);return 1}const projectId=project.id;if(opts.action==="setup"){const{runSetup,parseAiList}=await import("./setup-I4PA2TQW.js");let ais;if(opts.ais!==void 0&&opts.ais.length>0){const parsed=parseAiList(opts.ais.join(","));if(parsed.unknown.length>0){process.stderr.write(`--ai \u306B\u672A\u77E5\u306E\u5024\u304C\u3042\u308A\u307E\u3059: ${parsed.unknown.join(" / ")}
|
|
325
327
|
`);return 2}ais=parsed.ais}return runSetup({projectId,projectRef,projectName:project.name===project.id?projectRef:`${project.code} / ${project.name}`,apiUrl,yes:opts.yes===true,...ais!==void 0?{ais}:{},...opts.workspace!==void 0?{workspace:opts.workspace}:{},...opts.aiConfigFile!==void 0?{aiConfigFile:opts.aiConfigFile}:{},...opts.noAiConfigFile===true?{noAiConfigFile:true}:{},...opts.profile!==void 0?{profile:opts.profile}:{}})}const config=buildLoopConfig({projectId,projectRef,apiUrl,safeMode:opts.
|
|
326
328
|
safe,daemon:opts.daemon,...opts.maxCycles!==void 0?{maxCycles:opts.maxCycles}:{},...opts.interval!==void 0?{intervalSec:opts.interval}:{},forceRunner:opts.forceRunner,...opts.engine!==void 0?{engine:opts.engine}:{},version:opts.version});const api=new AgentLoopApi({apiUrl,projectId,session});if(opts.action==="status"||opts.action==="schedule"){for(const warning of config.warnings)process.stderr.write(`\u26A0\uFE0F ${warning}
|
|
327
329
|
`)}if(opts.action==="status")return showStatus(api,config);if(opts.action==="schedule"){const{runScheduleCommand}=await import("./schedule-command-YPKIO3FK.js");return runScheduleCommand({api,projectApi,config},{now:opts.scheduleNow,counts:opts.scheduleCounts,gate:opts.scheduleGate,verbose:opts.verbose===true})}if(config.engine===""){process.stderr.write(`${new EngineNotConfiguredError().message}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{PromptAbortedError,promptText}from"./chunk-L37NS5L2.js";import{localConfigPath,parseClaudeLauncher}from"./chunk-
|
|
3
|
+
import{PromptAbortedError,promptText}from"./chunk-L37NS5L2.js";import{localConfigPath,parseClaudeLauncher}from"./chunk-EZCMF4I3.js";import{AiConfig,detectAiClis,formatDetection,isDetectableAi,isSelectable}from"./chunk-3WJHTPOZ.js";import"./chunk-N2UVRM3Z.js";import"./chunk-PMOUHEJQ.js";import"./chunk-GY7KI5E5.js";import"./chunk-RZVI6PMW.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import"./chunk-VSJBJXZO.js";import fs from"fs";import path from"path";var RECOMMENDED_ROTATION={complex:["claude"],verify:["claude"],security:["claude"],support:["claude"],triage:["claude"],search:["claude"],simple:["claude"]};var RECOMMENDED_CHAINS={complex:["claude","codex"],verify:["claude","codex","copilot"],security:["claude","codex","copilot"],support:["claude","codex","copilot"],triage:["codex","gemini","copilot","claude"],search:["codex","gemini","copilot","claude"],simple:["codex","gemini","copilot","claude"]};var PREFERENCE=["claude","codex","gemini","co\
|
|
4
4
|
pilot"];function buildAiAssignment(selected){if(selected.length===0)throw new Error("\u9078\u629E\u3055\u308C\u305FAI\u304C\u7A7A\u3067\u3059");const fallbackOrder=PREFERENCE.filter(ai=>selected.includes(ai));for(const ai of selected)if(!fallbackOrder.includes(ai))fallbackOrder.push(ai);const chains={};const rotation={};for(const category of Object.keys(RECOMMENDED_CHAINS)){const filtered=(RECOMMENDED_CHAINS[category]??[]).filter(ai=>selected.includes(ai));const chain=filtered.length>0?filtered:
|
|
5
5
|
[...fallbackOrder];chains[category]=chain;const rot=(RECOMMENDED_ROTATION[category]??[]).filter(ai=>selected.includes(ai));const head=chain[0];rotation[category]=rot.length>0?rot:head===void 0?[...fallbackOrder]:[head]}return{primary_rotation:rotation,fallback_chains:chains}}var SETUP_EXIT_NO_CLI=3;var SETUP_EXIT_ABORTED=130;async function runSetup(opts){const env=opts.env??process.env;const rawOut=opts.out??(t=>void process.stdout.write(t));const rawErr=opts.err??(t=>void process.stderr.write(t));
|
|
6
6
|
const out=t=>rawOut(stripTerminalControls(t));const err=t=>rawErr(stripTerminalControls(t));const rawAsk=opts.ask??promptText;const ask=q=>rawAsk(stripTerminalControls(q));const detect=opts.detect??detectAiClis;try{return await setupFlow(opts,{env,out,err,ask,detect})}catch(e){if(e instanceof PromptAbortedError){err("\n\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u306F\u4F5C\u6210\u3057\u3066\u3044\u307E\u305B\u3093\u3002\n \u5BFE\u8A71\u305B\u305A\u306B\u5B9F\u884C\u3059\u308B\u306B\u306F --yes \u3092\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\u3002\n");
|