@tocca-systems/twp-cli 0.53.0 → 0.55.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 +14 -0
- package/README.md +49 -2
- package/dist/{agent-LHNDQMT5.js → agent-QFI6UOVQ.js} +1 -1
- package/dist/{agent-loop-D35USHWR.js → agent-loop-KBQJP5E7.js} +1 -1
- package/dist/{analysis-RFO4E4ZS.js → analysis-MWPZKAUA.js} +1 -1
- package/dist/{announcement-HQ7CQYFI.js → announcement-4PDYMC6K.js} +1 -1
- package/dist/{api-command-NZ4GJ7BW.js → api-command-YCIZ37HT.js} +2 -2
- package/dist/{app-67TGWKPM.js → app-EEHQ46DG.js} +3 -3
- package/dist/{attendance-correct-CRRR4EKL.js → attendance-correct-CSAET72A.js} +1 -1
- package/dist/{attendance-lists-XPCU25OJ.js → attendance-lists-E6WHZPIH.js} +1 -1
- package/dist/{backlog-NU5HHXN2.js → backlog-YQKUID7L.js} +1 -1
- package/dist/{budget-YQHHSX7Q.js → budget-WKPD5GPG.js} +1 -1
- package/dist/{chunk-FEJDU42E.js → chunk-3LWQO2ZK.js} +1 -1
- package/dist/{chunk-NGY4K5VW.js → chunk-3UYVUEV4.js} +1 -1
- package/dist/{chunk-B6WIFZF2.js → chunk-5M7QCXPY.js} +1 -1
- package/dist/{chunk-AKLQMTMW.js → chunk-A56FFATZ.js} +1 -1
- package/dist/{chunk-52HYPBSW.js → chunk-A576CQJW.js} +6 -5
- package/dist/{chunk-6JB4MSDX.js → chunk-ASHN4KFF.js} +1 -1
- package/dist/{chunk-NQJV2X2R.js → chunk-B7GUZW6Z.js} +1 -1
- package/dist/{chunk-F53TSCRD.js → chunk-DDCERTPP.js} +1 -1
- package/dist/{chunk-7GJFKKOJ.js → chunk-DZWIABLW.js} +3 -3
- package/dist/chunk-FNKRVPMV.js +10 -0
- package/dist/{chunk-LXGYOKDY.js → chunk-GIUINGC7.js} +1 -1
- package/dist/chunk-H6DUSCEZ.js +3 -0
- package/dist/{chunk-74WGU5BM.js → chunk-HG7UEH3L.js} +1 -1
- package/dist/{chunk-XZU53BUV.js → chunk-HIJQJXRB.js} +2 -2
- package/dist/{chunk-E7TZU54Y.js → chunk-N33PUUKC.js} +1 -1
- package/dist/chunk-NXHJYRAM.js +50 -0
- package/dist/{chunk-2NP3BLPI.js → chunk-P7LUVC3J.js} +1 -1
- package/dist/{chunk-22OIKHMN.js → chunk-Q76QFEF3.js} +1 -1
- package/dist/{chunk-FACNRXN7.js → chunk-QGX7L6HN.js} +2 -2
- package/dist/{chunk-MKQDUQQ2.js → chunk-QL2YKREQ.js} +1 -1
- package/dist/{chunk-AUAZP2G7.js → chunk-UFGJSWKU.js} +5 -5
- package/dist/{chunk-S36LGDG2.js → chunk-X2P7N7WO.js} +59 -6
- package/dist/{chunk-DBCF4H3V.js → chunk-X6KRLHSG.js} +1 -1
- package/dist/cli.js +19 -8
- package/dist/{commands-5VM6LUB5.js → commands-L6ADDE5N.js} +2 -2
- package/dist/{commands-CVSXWYGR.js → commands-RYRSKDXJ.js} +106 -104
- package/dist/{company-BKULUHIU.js → company-RRWGDHKO.js} +2 -2
- package/dist/{contract-376FE7VC.js → contract-6CR57KCS.js} +2 -2
- package/dist/{department-YKBPBPU6.js → department-JF7KTFQX.js} +1 -1
- package/dist/{deposit-CY5K3ZTM.js → deposit-KXGMK66O.js} +1 -1
- package/dist/{estimate-GPNG6YOJ.js → estimate-ONS2KBM7.js} +3 -3
- package/dist/{evaluation-VRLMQV32.js → evaluation-GKSJ5ZHU.js} +1 -1
- package/dist/{expense-3MT6WHTG.js → expense-32QOHO6C.js} +1 -1
- package/dist/{inquiry-YV433Q7V.js → inquiry-PAPJCGKO.js} +1 -1
- package/dist/{invoice-OSAO4PIO.js → invoice-RJ7M2FY2.js} +2 -2
- package/dist/{job-title-FITZHBR4.js → job-title-B7VMIZ2H.js} +1 -1
- package/dist/{knowledge-YEEAKLQJ.js → knowledge-YPXOGA2U.js} +1 -1
- package/dist/{leave-MWYAL66X.js → leave-4AFSQ2IP.js} +1 -1
- package/dist/{logout-guard-ZQV2OPIO.js → logout-guard-7DAWGOM3.js} +1 -1
- package/dist/{media-ZIAI4GEB.js → media-HMYE2TR7.js} +2 -2
- package/dist/{notification-EAEKDN54.js → notification-CMWQ6JZQ.js} +1 -1
- package/dist/{oneshot-62DOJWOH.js → oneshot-P75VON6Q.js} +1 -1
- package/dist/{position-ZKYGVAAK.js → position-IKF3SR3O.js} +1 -1
- package/dist/project-WHVEIPH5.js +4 -0
- package/dist/{prospect-ASQA5QVD.js → prospect-STAA2UPR.js} +2 -2
- package/dist/{purchase-WLJJSMM6.js → purchase-VCAMBAW7.js} +3 -3
- package/dist/{receivable-FBPROHOV.js → receivable-6A2OVBZN.js} +1 -1
- package/dist/{registry-4QVXMTGW.js → registry-DZH6EYRY.js} +1 -1
- package/dist/{render-R5QZ46GF.js → render-HTS5OJGG.js} +1 -1
- package/dist/{report-HK2NZXHC.js → report-5WTMGPDN.js} +1 -1
- package/dist/{run-KXZBNXJF.js → run-NR7KO6GU.js} +1 -1
- package/dist/{sales-ai-review-IEISLBIH.js → sales-ai-review-7U2EBEYX.js} +1 -1
- package/dist/{sales-master-S3YTUE7J.js → sales-master-E2LDMJIC.js} +2 -2
- package/dist/{sales-numbering-M4KUZAM7.js → sales-numbering-E53EMSMI.js} +1 -1
- package/dist/{schedule-command-QCGEMBVR.js → schedule-command-ONHLWUW6.js} +2 -3
- package/dist/{server-settings-WYHQZV2N.js → server-settings-6NHVHMPS.js} +1 -1
- package/dist/{setup-G24BYLQV.js → setup-SIL2ELR4.js} +1 -1
- package/dist/{skill-45FBIGC5.js → skill-76QF44O3.js} +1 -1
- package/dist/{supplier-payment-MS6YMIT4.js → supplier-payment-HQQVWIQW.js} +2 -2
- package/dist/{support-VSDMFUTY.js → support-I2QTNQTP.js} +1 -1
- package/dist/{task-BTYFJRSC.js → task-RZBH4I6U.js} +51 -12
- package/dist/{user-VFJGLZDR.js → user-XTQNSWP4.js} +2 -2
- package/dist/{worker-agent-YX2KPVQG.js → worker-agent-PDAQVQKO.js} +1 -1
- package/dist/{workflow-OPZYCSDL.js → workflow-TRHRVMUK.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-EZGN7PTO.js +0 -48
- package/dist/chunk-JY4VWR5O.js +0 -10
- package/dist/chunk-MXKAEPXA.js +0 -3
- package/dist/project-5MHCPDVC.js +0 -4
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRequire as __twpCreateRequire } from 'node:module';
|
|
2
2
|
const require = __twpCreateRequire(import.meta.url);
|
|
3
|
-
import{
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import{
|
|
3
|
+
import{ScheduleApi,collectDue,gateStatus,nowInZone,parseCounts,promptSection}from"./chunk-NXHJYRAM.js";import{InstanceLock,buildLockOwner,defaultIsLoopProcess,writeLockOwner}from"./chunk-3WHC4FSG.js";import{LoopSettingsApplier,renderStepBudget}from"./chunk-N33PUUKC.js";import{EngineNotConfiguredError,NoopEngine,UnknownEngineError,aiUnavailableLabel,assertKnownEngine,failureHint,isAiUnavailable,needsHumanToRestoreAi}from"./chunk-ZOOEH7ZE.js";import{ServerSkillCatalog,formatSkillOrigins}from"./chunk-TVODNAPX.js";
|
|
4
|
+
import"./chunk-YJZT3UD3.js";import"./chunk-A4LFG7MW.js";import"./chunk-VRBI2NPI.js";import{claudeConfigDir,resolveDetectDeps}from"./chunk-T4QZO6RQ.js";import{duplicateTaskKeyDropReason,excludedKeyInArgs,extractPlanJson,parseOpsCount,parsePlanExcludeKeys,placeholderTaskKey,releaseDeployDropReason,stepToItem,zeroTargetDropReasons}from"./chunk-LUQ2KE6Y.js";import{CapacityReporter,buildLoopConfig,describeOperations,evaluateOwnership,formatHookIds,formatHookWiring,localDate,
|
|
5
|
+
loopStateDir,runHook,runPrefetch,runPreflight}from"./chunk-A576CQJW.js";import{exclusiveInflightEntries,formatExclusiveEntry,normalizeSkillName,skillOfItem,spawnSyncResolved}from"./chunk-AEJHDFXB.js";import{killProcessTree}from"./chunk-N2UVRM3Z.js";import{AgentLoopApi,describeError,filterByStatus,isPermanent,pick,pickString}from"./chunk-JTJWDV5U.js";import{PRIVATE_PROJECT_REF,isPrivateProjectId,isPrivateProjectRef,privateProjectId,projectFileKey}from"./chunk-GY7KI5E5.js";
|
|
6
|
+
import{resolveProjectRef,uuidProjectIdPolicy}from"./chunk-GMBJTG6A.js";import{isTaskKey}from"./chunk-II5RVJQN.js";import"./chunk-VFPY2A23.js";import{joinFor}from"./chunk-PMOUHEJQ.js";import{AuthSession}from"./chunk-XNLIEUAW.js";import{httpFetch}from"./chunk-J7QYPKVK.js";import{compareVersionCores,parseVersionCore}from"./chunk-DXXFUNYN.js";import"./chunk-5WGOHFAS.js";import{effectiveApiUrl,resolveProfile}from"./chunk-4VZKNEVN.js";import{twpHomeDir}from"./chunk-RZVI6PMW.js";
|
|
7
|
+
import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import"./chunk-VSJBJXZO.js";import fs10 from"fs";import path8 from"path";import fs from"fs";import path from"path";var LoopLogger=class{constructor(runnerId,logFile,out=process.stdout,now=()=>new Date){this.runnerId=runnerId;this.out=out;this.now=now;if(logFile){fs.mkdirSync(path.dirname(logFile),{recursive:true});this.stream=fs.createWriteStream(logFile,{flags:"a"})}}runnerId;out;now;stream=null;log(message){const d=this.now();const ts=`${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;const line=`[${ts}] [${this.runnerId}] ${stripTerminalControls(
|
|
8
8
|
message)}
|
|
9
9
|
`;this.out.write(line);this.stream?.write(line)}separator(){this.log("=".repeat(60))}close(){this.stream?.end();this.stream=null}};function pad(n){return String(n).padStart(2,"0")}function rotateLogs(dir,retentionDays,now=Date.now()){if(retentionDays<=0)return;const cutoff=now-retentionDays*864e5;let entries;try{entries=fs.readdirSync(dir)}catch{return}for(const name of entries){if(!/^(agent-loop|task-loop|step|plan|schedule-enqueued)-.*\.(log|txt)$/.test(name))continue;const file=path.join(dir,
|
|
10
10
|
name);try{if(fs.statSync(file).mtimeMs<cutoff)fs.rmSync(file,{force:true})}catch{}}}import fs7 from"fs";import path5 from"path";import{spawnSync}from"child_process";import fs2 from"fs";import path2 from"path";var GIT_IDENTITY_ENV_KEYS=["GIT_AUTHOR_NAME","GIT_AUTHOR_EMAIL","GIT_COMMITTER_NAME","GIT_COMMITTER_EMAIL"];function resolveDeps(deps){return{run:deps.run??spawnSync,readdirSync:deps.readdirSync??(dir=>fs2.readdirSync(dir,{withFileTypes:true})),existsSync:deps.existsSync??fs2.existsSync,env:deps.env??process.env}}function expectedIdentity(configured,env=process.env){const pick2=(envKey,fromConfig)=>{const fromEnv=(env[envKey]??"").trim();if(fromEnv!=="")return fromEnv;return(fromConfig??"").trim()};
|
|
@@ -139,12 +139,14 @@ get(advance.taskKey);if(current===void 0){return{suppress:true,reason:""}}if(cur
|
|
|
139
139
|
status}\uFF09\u3002\u500B\u4EBA\u30AD\u30E5\u30FC\u3092\u56DE\u3059\u306B\u306F \`twp login\` \u304C\u5FC5\u8981\u3067\u3059\u3002\u63A5\u7D9A\u5148\u3068\u30ED\u30B0\u30A4\u30F3\u72B6\u614B\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}const userId=res.json?.user?.id;if(typeof userId!=="string"||!USER_ID_RE.test(userId)){throw new Error(`\u30B5\u30FC\u30D0\u304C\u8FD4\u3057\u305F\u30E6\u30FC\u30B6\u30FCID\u3092\u500B\u4EBA\u30AD\u30E5\u30FC\u306EID\u306B\u4F7F\u3048\u307E\u305B\u3093\uFF08${String(
|
|
140
140
|
userId).slice(0,60)}\uFF09\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}return{id:privateProjectId(userId),code:PRIVATE_PROJECT_REF,name:"\u500B\u4EBA\u30BF\u30B9\u30AF"}}async countByStatus(projectId,statusId){const res=await this.get(`/api/v2/projects/${projectId}/tasks?status_id=${encodeURIComponent(statusId)}&limit=1`);if(!res.ok){return{total:null,error:res.status===null?res.error??"\u901A\u4FE1\u5931\u6557":`HTTP ${res.status}`}}const total=res.json?.
|
|
141
141
|
pagination?.total;if(typeof total!=="number"){return{total:null,error:"\u5FDC\u7B54\u304B\u3089 pagination.total \u3092\u8AAD\u3081\u306A\u3044"}}return{total,error:null}}async get(path9){let token;try{token=await this.session.getAccessToken()}catch(err){return{ok:false,status:null,json:null,error:err.message}}try{const res=await this.fetchImpl(`${this.apiUrl}${path9}`,{headers:{Authorization:`Bearer ${token}`,"Content-Type":"application/json",Accept:"application/json"}});const raw=await res.text();
|
|
142
|
-
let json=null;try{json=raw.trim()===""?null:JSON.parse(raw)}catch{json=null}return{ok:res.ok,status:res.status,json,error:null}}catch(err){return{ok:false,status:null,json:null,error:err.message}}}};import fs5 from"fs";var ScheduleBridge=class{constructor(deps){this.deps=deps}deps;tzWarned=false;zoneWarned=false;now(){if(this.deps.now)return this.deps.now();return nowInZone(this.deps.config.scheduleTimezone,m=>{if(this.zoneWarned)return;this.zoneWarned=true;this.deps.log.log(` ${m}`)})}warn(message){this.deps.log.log(` \u26A0\uFE0F \u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB: ${message}`)}async loadConfig(){const res=await this.deps.api.definitions();if(res.
|
|
143
|
-
config.schedules.length===0){const warn=(res.config.warnings??[]).map(w=>w&&typeof w==="object"?String(w["message"]??""):"").filter(m=>m!=="").join("; ");this.deps.log.log(" \u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u306F\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u5B9A\u7FA9\u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u5B9A\u671F\u30BF\u30B9\u30AF\u306F\u6295\u5165\u3055\u308C\u307E\u305B\u3093\uFF09"+(warn?` / ${warn}`:""))}
|
|
144
|
-
|
|
142
|
+
let json=null;try{json=raw.trim()===""?null:JSON.parse(raw)}catch{json=null}return{ok:res.ok,status:res.status,json,error:null}}catch(err){return{ok:false,status:null,json:null,error:err.message}}}};import fs5 from"fs";var ScheduleBridge=class{constructor(deps){this.deps=deps}deps;tzWarned=false;zoneWarned=false;lastStatusesSummary="";unmappedWarned=new Set;now(){if(this.deps.now)return this.deps.now();return nowInZone(this.deps.config.scheduleTimezone,m=>{if(this.zoneWarned)return;this.zoneWarned=true;this.deps.log.log(` ${m}`)})}warn(message){this.deps.log.log(` \u26A0\uFE0F \u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB: ${message}`)}async loadConfig(){const res=await this.deps.api.definitions();if(res.
|
|
143
|
+
kind==="error")return{error:res.message};if(res.config.schedules.length===0){const warn=(res.config.warnings??[]).map(w=>w&&typeof w==="object"?String(w["message"]??""):"").filter(m=>m!=="").join("; ");this.deps.log.log(" \u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u306F\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u5B9A\u7FA9\u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u5B9A\u671F\u30BF\u30B9\u30AF\u306F\u6295\u5165\u3055\u308C\u307E\u305B\u3093\uFF09"+(warn?` / ${warn}`:""))}this.
|
|
144
|
+
describeStatuses(res.config);return{config:res.config}}describeStatuses(config){const keys=Object.keys(config.require_zero_statuses??{}).sort();const used=[...new Set((config.schedules??[]).flatMap(s=>{const raw=s.require_zero??[];const list=Array.isArray(raw)?raw:typeof raw==="string"?[raw]:[];return list.filter(k=>typeof k==="string")}))].sort();const missing=used.filter(k=>!keys.includes(k));const summary=`\u4EF6\u6570\u30B2\u30FC\u30C8\u306E\u5BFE\u5FDC\uFF08\u30B5\u30FC\u30D0\u8A2D\u5B9A require_zero_statuses\uFF09: ${keys.
|
|
145
|
+
length>0?keys.join(","):"\u306A\u3057"}`+(missing.length>0?` \uFF0F \u26A0\uFE0F \u5BFE\u5FDC\u306A\u3057: ${missing.join(",")}\uFF08\u3053\u308C\u3092 require_zero \u306B\u6301\u3064\u67A0\u306F\u767A\u706B\u3057\u307E\u305B\u3093\uFF09`:"");if(summary!==this.lastStatusesSummary){this.deps.log.log(` ${summary}`);this.unmappedWarned.clear()}this.lastStatusesSummary=summary}async loadHistory(){const res=await this.deps.api.history();if(res.kind==="error")return{error:res.message};const serverTz=res.
|
|
146
|
+
history.timezone;if(serverTz&&serverTz!==this.deps.config.scheduleTimezone&&!this.tzWarned){this.tzWarned=true;this.warn(`\u5C65\u6B74\u306E\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3\uFF08\u30B5\u30FC\u30D0: ${serverTz}\uFF09\u3068\u5224\u5B9A\u306B\u4F7F\u3046\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3\uFF08${this.deps.config.scheduleTimezone}\uFF09\u304C\u9055\u3044\u307E\u3059\u3002\u65E5\u6B21\u67A0\u306E\u5F53\u65E5\u5224\u5B9A\u3068 interval \u306E\u8DB3\u5207\u308A\u304C\u540C\u6642\u306B\u305A\u308C\u307E\u3059\u3002AGENT_LOOP_SCHEDULE_TZ \u3092\u5408\u308F\u305B\u3066\u304F\u3060\u3055\u3044`)}
|
|
145
147
|
return{rows:res.history.rows,windowCounts:res.history.windowCounts}}async due(counts){const cfg=await this.loadConfig();if("error"in cfg)return{kind:"error",message:cfg.error};const hist=await this.loadHistory();if("error"in hist)return{kind:"error",message:hist.error};const rows=await collectDue({config:cfg.config,now:this.now(),history:hist.rows,windowCounts:hist.windowCounts,safeMode:this.deps.config.safeMode,exclusiveSkills:this.deps.config.operations.exclusiveSkills,statusEndpoint:this.deps.
|
|
146
|
-
config.operations.statusEndpoint,counts:parseCounts(counts),...this.deps.fetchCount?{fetchCount:this.deps.fetchCount}:{},warn:m=>this.warn(m),verbose:m=>this.deps.log.log(m)});return{kind:"ok",rows}}async gateAllows(skill){if(!skill)return{allowed:true,reason:""};const res=await this.deps.api.definitions();if(res.kind==="error"){this.warn(`\u5B9A\u7FA9\u304C\u53D6\u308C\u306A\u3044\u305F\u3081\u30B2\u30FC\u30C8\u306F\u8A31\u53EF\u6271\u3044\u306B\u3057\u307E\u3059\uFF08${res.
|
|
147
|
-
allowed:true,reason:""}}return gateStatus(skill,this.now(),res.config.gates)}claimWindow(row){return this.deps.api.claim(row.scheduleId,{windowKey:row.windowKey,runnerId:this.deps.config.runnerId,runId:this.deps.config.runId,args:row.args})}async record(scheduleId,windowKey,status,opts={}){const res=await this.deps.api.record(scheduleId,{status,windowKey,...opts.itemId?{itemId:opts.itemId}:{},runnerId:this.deps.config.runnerId});if(!res.ok){this.warn(`\u67A0\u306E\u8A18\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${scheduleId}\
|
|
148
|
+
config.operations.statusEndpoint,counts:parseCounts(counts),...this.deps.fetchCount?{fetchCount:this.deps.fetchCount}:{},warn:m=>{if(m.includes("require_zero_statuses")){if(this.unmappedWarned.has(m))return;this.unmappedWarned.add(m)}this.warn(m)},verbose:m=>this.deps.log.log(m)});return{kind:"ok",rows}}async gateAllows(skill){if(!skill)return{allowed:true,reason:""};const res=await this.deps.api.definitions();if(res.kind==="error"){this.warn(`\u5B9A\u7FA9\u304C\u53D6\u308C\u306A\u3044\u305F\u3081\u30B2\u30FC\u30C8\u306F\u8A31\u53EF\u6271\u3044\u306B\u3057\u307E\u3059\uFF08${res.
|
|
149
|
+
message}\uFF09`);return{allowed:true,reason:""}}return gateStatus(skill,this.now(),res.config.gates)}claimWindow(row){return this.deps.api.claim(row.scheduleId,{windowKey:row.windowKey,runnerId:this.deps.config.runnerId,runId:this.deps.config.runId,args:row.args})}async record(scheduleId,windowKey,status,opts={}){const res=await this.deps.api.record(scheduleId,{status,windowKey,...opts.itemId?{itemId:opts.itemId}:{},runnerId:this.deps.config.runnerId});if(!res.ok){this.warn(`\u67A0\u306E\u8A18\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${scheduleId}\
|
|
148
150
|
${windowKey} \u2192 ${status}\uFF09: ${res.detail}`)}return res.ok}async recordByItem(itemId,status){if(!itemId)return;const res=await this.deps.api.recordByItem(itemId,status,this.deps.config.runnerId);if(res.kind==="error"){this.deps.log.log(` \u26A0\uFE0F \u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u5C65\u6B74\u3092\u66F4\u65B0\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08item=${itemId} \u2192 ${status}\uFF09: ${res.message}`);return}if(res.kind==="not_scheduled")return;this.deps.
|
|
149
151
|
log.log(` \u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u5C65\u6B74\u3092\u66F4\u65B0: ${res.scheduleId} \u2192 ${status}`)}async releaseWindow(scheduleId,windowKey,why){if(await this.record(scheduleId,windowKey,"failed")){this.deps.log.log(` \u3053\u306E\u67A0\u306F failed \u3068\u3057\u3066\u8FD4\u3057\u307E\u3057\u305F\uFF08\u7406\u7531: ${why}\u30FB\u6B21\u30B5\u30A4\u30AF\u30EB\u3067\u518D\u8A66\u884C\u3055\u308C\u307E\u3059\uFF09`)}else{this.deps.log.log(` \u26A0\uFE0F \u67A0\u3092 failed \u3068\u3057\u3066\u8FD4\u305B\u307E\u305B\
|
|
150
152
|
\u3093\u3067\u3057\u305F\uFF08\u7406\u7531: ${why}\uFF09\u3002\u30EA\u30FC\u30B9\u671F\u9650\u307E\u3067\u518D\u8A66\u884C\u3067\u304D\u307E\u305B\u3093`)}}async promptSection(enqueuedFile){const cfg=await this.loadConfig();if("error"in cfg){this.deps.log.log(` \u26A0\uFE0F \u8A08\u753B\u30D7\u30ED\u30F3\u30D7\u30C8\u7528\u306E\u5B9A\u671F\u30BB\u30AF\u30B7\u30E7\u30F3\u3092\u751F\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: ${cfg.error}`);this.deps.log.log(" \u8A08\u753BAI\u306B\u300C\u6295\u5165\u6E08\u307F\u306E\u5B9A\u671F\u30BF\u30B9\u30AF\u300D\u3092\u4F1D\u3048\
|
|
@@ -167,103 +169,103 @@ continue}try{const ageDays=(now-fs6.statSync(file).mtimeMs)/864e5;if(ageDays>thi
|
|
|
167
169
|
continue}const{run_id:runId,...rest}=payload;const res=await this.api.update(itemId,rest,runId||this.config.runId);if(res.ok){fs6.rmSync(file,{force:true});this.log.log(` \u2705 \u5B9F\u884C\u7D50\u679C\u3092\u518D\u9001\u3057\u307E\u3057\u305F: item=${itemId}\uFF08status=${payload.status}\uFF09`);if(payload.status==="completed")recorded.push(itemId)}else if(res.status===409){fs6.rmSync(file,{force:true});this.log.log(` \u26A0\uFE0F \u518D\u9001\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08409\u30FB\u65E2\u306B\u5225\u306E\u30E9\u30F3\u30CA\u30FC/\u5225\u306E run \u304C\u4FDD\u6301\uFF09: item=${itemId}\
|
|
168
170
|
\u2192 \u7D50\u679C\u306F\u7834\u68C4\u3057\u307E\u3059`)}else if(res.status!==null&&res.status>=400&&res.status<500&&res.status!==408&&res.status!==429){fs6.rmSync(file,{force:true});this.log.log(` \u26D4 \u30B5\u30FC\u30D0\u306B\u6052\u4E45\u7684\u306B\u62D2\u5426\u3055\u308C\u305F\u305F\u3081\u7834\u68C4\u3057\u307E\u3059\uFF08http=${res.status}\uFF09: item=${itemId}`)}else{this.log.log(` \u26A0\uFE0F \u518D\u9001\u306B\u5931\u6557\uFF08${describeError(res)}\uFF09: item=${itemId}\u3002\u6B21\u30B5\u30A4\u30AF\u30EB\u3067\u518D\u8A66\
|
|
169
171
|
\u884C\u3057\u307E\u3059`)}}return recorded}};function exitReasonFor(outcome){if(outcome==="ok")return"ok";if(outcome==="timeout")return"timeout";if(outcome==="rate-limited")return"rate_limited";if(outcome==="aborted")return"interrupted";if(outcome==="max-turns")return"max_turns";return"error"}function withFailureHint(base,output){const hint=failureHint(output);return hint===""?base:`${base} | ${hint}`}var STOP_WAIT_MAX_SEC=3600;var AI_RECOVERY_HINT="\u78BA\u8A8D: claude-auto-switch status \uFF0F \u5404AI CLI\u306E\u30ED\u30B0\u30A4\u30F3\u72B6\u614B\uFF08twp task-loop setup \u3067\u691C\u51FA\u7D50\u679C\u304C\u51FA\u307E\u3059\uFF09";
|
|
170
|
-
var ABORT_DRAIN_TIMEOUT_MS=15e3;var TaskLoop=class{constructor(deps){this.deps=deps;this.writeback=new Writeback(deps.api,deps.config,deps.log);this.schedule=new ScheduleBridge({config:deps.config,log:deps.log,api:new ScheduleApi(deps.api),fetchCount:async
|
|
171
|
-
key,total,deps.config.operations.countHooks,deps.config.workspace);if(refined.note)deps.log.log(` ${refined.note}`);return refined.total}});this.engine=deps.engine;this.releaseLog=new ReleaseOutcomeLog(deps.config.releaseOutcomeLogPath,deps.log);this.postDeps={api:deps.api,config:deps.config,log:deps.log,releaseLog:this.releaseLog};this.planLock=new PlanLock({api:deps.
|
|
172
|
-
reregister:async()=>{deps.runner.registered=false;await deps.runner.registerOrThrow()},...deps.sleepFn?{sleepFn:deps.sleepFn}:{}});this.trustGate=deps.trustGate??new TrustGate({enabled:()=>deps.config.ai.usesAi("claude"),check:()=>checkWorkspaceTrust(deps.config.workspace,{launcherBin:deps.config.claudeLauncher.bin})});this.timestamp=new Date().toISOString().
|
|
173
|
-
log(m)});this.skills=deps.skills??new ServerSkillCatalog({api:deps.api,config:deps.config,log:m=>deps.log.log(m)})}deps;writeback;schedule;planLock;engine;releaseLog;postDeps;timestamp;deferredIds=new Set;midcycleEnqueued=0;aborting=false;draining=false;nothingClaimableBacklog=false;drainExitCode=0;drainWaiters=new Set;itemInFlight=null;ownershipLostItemId=null;abortDrained=null;cyclePreflightSection="";trustGate;settings;skills;sleep(ms){
|
|
174
|
-
if(this.draining)return Promise.resolve();return new Promise(resolve=>{let timer=null;let settled=false;const wake=()=>{if(settled)return;settled=true;if(timer!==null)clearTimeout(timer);this.drainWaiters.delete(wake);resolve()};this.drainWaiters.add(wake);const injected=this.deps.sleepFn;if(injected)void injected(ms).then(wake);else timer=setTimeout(wake,ms)})}requestDrain(reason,exitCode=0){if(this.draining)return;this.draining=true;
|
|
175
|
-
trim()===""?"\u7406\u7531\u4E0D\u660E":reason;this.deps.log.log(running===null?`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\uFF08${why}\uFF09\u3002\u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u65B0\u3057\u3044\u30A2\u30A4\u30C6\u30E0\u3092\u53D6\u3089\u305A\u306B\u7D42\u4E86\u3057\u307E\u3059\u3002`:`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\uFF08${why}\
|
|
176
|
-
\uFF09\u3092\u5B8C\u8D70\u3055\u305B\u3066\u304B\u3089\u7D42\u4E86\u3057\u307E\u3059\u3002`);const waiters=[...this.drainWaiters];this.drainWaiters.clear();for(const w of waiters)w()}cooldownNote(outcome){if(outcome!=="rate-limited")return"";const remaining=this.deps.config.ai.minCooldownRemainingSec();return remaining===null?"":`\uFF08\u6700\u77ED\u306E\u89E3\u9664\u307E\u3067\u7D04${remaining}\u79D2\uFF09`}startOwnershipWatch(itemId){
|
|
177
|
-
if(intervalSec<=0)return{stop:()=>{}};let stopped=false;let checking=false;let unknownLogged=false;const timer=setInterval(()=>{if(stopped||checking)return;checking=true;void(async()=>{try{const res=await api.getItem(itemId);const check=evaluateOwnership(res.json?.item??null,config.runnerId,config.runId);if(stopped)return;if(check.verdict==="unknown"){if(!unknownLogged){unknownLogged=true;log.log(` \u26A0\uFE0F \u6240\u6709\u6A29\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\
|
|
178
|
-
reason}\uFF09\u3002\u76E3\u8996\u306F\u7D9A\u3051\u307E\u3059\u304C\u5B9F\u884C\u306F\u6B62\u3081\u307E\u305B\u3093`)}return}if(check.verdict!=="lost")return;stopped=true;clearInterval(timer);this.ownershipLostItemId=itemId;log.log(` \u26D4 \u5B9F\u884C\u4E2D\u306B\u3053\u306E\u30A2\u30A4\u30C6\u30E0\u306E\u6240\u6709\u6A29\u3092\u5931\u3044\u307E\u3057\u305F: ${check.reason}`);log.log(" **AI \u3092\u3053\u3053\u3067\u505C\u6B62\u3057\u307E\u3059**\uFF08\u7D9A\u3051\u3066\u3082\u7D50\u679C\u306F\u66F8\u304D\u623B\u305B\u305A\u3001PR\u30FB\u30B3\u30E1\u30F3\u30C8\u3060\u3051\u304C\u91CD\u8907\u3057\u307E\u3059\uFF09");
|
|
172
|
+
var ABORT_DRAIN_TIMEOUT_MS=15e3;var TaskLoop=class{constructor(deps){this.deps=deps;this.writeback=new Writeback(deps.api,deps.config,deps.log);this.schedule=new ScheduleBridge({config:deps.config,log:deps.log,api:new ScheduleApi(deps.api),fetchCount:async(key,statusId)=>{const{total,error}=await deps.projectApi.countByStatus(deps.config.projectId,statusId);if(error){deps.log.log(` \u26A0\uFE0F require_zero\u300C${key}\u300D\u306E\u4EF6\u6570\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${error}\
|
|
173
|
+
\uFF09\u3002\u3053\u306E\u67A0\u306F\u767A\u706B\u3057\u307E\u305B\u3093\uFF08fail-closed\uFF09`)}const refined=await refineCount(key,total,deps.config.operations.countHooks,deps.config.workspace);if(refined.note)deps.log.log(` ${refined.note}`);return refined.total}});this.engine=deps.engine;this.releaseLog=new ReleaseOutcomeLog(deps.config.releaseOutcomeLogPath,deps.log);this.postDeps={api:deps.api,config:deps.config,log:deps.log,releaseLog:this.releaseLog};this.planLock=new PlanLock({api:deps.
|
|
174
|
+
api,config:deps.config,log:deps.log,runner:deps.runner,hasPendingItems:async()=>await this.hasPendingItems()&&!this.nothingClaimableBacklog,reregister:async()=>{deps.runner.registered=false;await deps.runner.registerOrThrow()},...deps.sleepFn?{sleepFn:deps.sleepFn}:{}});this.trustGate=deps.trustGate??new TrustGate({enabled:()=>deps.config.ai.usesAi("claude"),check:()=>checkWorkspaceTrust(deps.config.workspace,{launcherBin:deps.config.claudeLauncher.bin})});this.timestamp=new Date().toISOString().
|
|
175
|
+
replace(/[-:]/g,"").replace(/\..*$/,"");this.settings=deps.settings??new LoopSettingsApplier({api:deps.api,config:deps.config,log:m=>deps.log.log(m)});this.skills=deps.skills??new ServerSkillCatalog({api:deps.api,config:deps.config,log:m=>deps.log.log(m)})}deps;writeback;schedule;planLock;engine;releaseLog;postDeps;timestamp;deferredIds=new Set;midcycleEnqueued=0;aborting=false;draining=false;nothingClaimableBacklog=false;drainExitCode=0;drainWaiters=new Set;itemInFlight=null;ownershipLostItemId=null;abortDrained=null;cyclePreflightSection="";trustGate;settings;skills;sleep(ms){
|
|
176
|
+
return(this.deps.sleepFn??sleep)(ms)}sleepUnlessDraining(ms){if(this.draining)return Promise.resolve();return new Promise(resolve=>{let timer=null;let settled=false;const wake=()=>{if(settled)return;settled=true;if(timer!==null)clearTimeout(timer);this.drainWaiters.delete(wake);resolve()};this.drainWaiters.add(wake);const injected=this.deps.sleepFn;if(injected)void injected(ms).then(wake);else timer=setTimeout(wake,ms)})}requestDrain(reason,exitCode=0){if(this.draining)return;this.draining=true;
|
|
177
|
+
this.drainExitCode=exitCode;const running=this.itemInFlight;const why=reason.trim()===""?"\u7406\u7531\u4E0D\u660E":reason;this.deps.log.log(running===null?`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\uFF08${why}\uFF09\u3002\u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u65B0\u3057\u3044\u30A2\u30A4\u30C6\u30E0\u3092\u53D6\u3089\u305A\u306B\u7D42\u4E86\u3057\u307E\u3059\u3002`:`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\uFF08${why}\
|
|
178
|
+
\uFF09\u3002\u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\uFF08${running}\uFF09\u3092\u5B8C\u8D70\u3055\u305B\u3066\u304B\u3089\u7D42\u4E86\u3057\u307E\u3059\u3002`);const waiters=[...this.drainWaiters];this.drainWaiters.clear();for(const w of waiters)w()}cooldownNote(outcome){if(outcome!=="rate-limited")return"";const remaining=this.deps.config.ai.minCooldownRemainingSec();return remaining===null?"":`\uFF08\u6700\u77ED\u306E\u89E3\u9664\u307E\u3067\u7D04${remaining}\u79D2\uFF09`}startOwnershipWatch(itemId){
|
|
179
|
+
const{config,log,api}=this.deps;const intervalSec=config.ownershipCheckIntervalSec;if(intervalSec<=0)return{stop:()=>{}};let stopped=false;let checking=false;let unknownLogged=false;const timer=setInterval(()=>{if(stopped||checking)return;checking=true;void(async()=>{try{const res=await api.getItem(itemId);const check=evaluateOwnership(res.json?.item??null,config.runnerId,config.runId);if(stopped)return;if(check.verdict==="unknown"){if(!unknownLogged){unknownLogged=true;log.log(` \u26A0\uFE0F \u6240\u6709\u6A29\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\
|
|
180
|
+
\u3093\u3067\u3057\u305F\uFF08${check.reason}\uFF09\u3002\u76E3\u8996\u306F\u7D9A\u3051\u307E\u3059\u304C\u5B9F\u884C\u306F\u6B62\u3081\u307E\u305B\u3093`)}return}if(check.verdict!=="lost")return;stopped=true;clearInterval(timer);this.ownershipLostItemId=itemId;log.log(` \u26D4 \u5B9F\u884C\u4E2D\u306B\u3053\u306E\u30A2\u30A4\u30C6\u30E0\u306E\u6240\u6709\u6A29\u3092\u5931\u3044\u307E\u3057\u305F: ${check.reason}`);log.log(" **AI \u3092\u3053\u3053\u3067\u505C\u6B62\u3057\u307E\u3059**\uFF08\u7D9A\u3051\u3066\u3082\u7D50\u679C\u306F\u66F8\u304D\u623B\u305B\u305A\u3001PR\u30FB\u30B3\u30E1\u30F3\u30C8\u3060\u3051\u304C\u91CD\u8907\u3057\u307E\u3059\uFF09");
|
|
179
181
|
await this.engine.abort?.()}catch(err){log.log(` \u26A0\uFE0F \u6240\u6709\u6A29\u306E\u78BA\u8A8D\u4E2D\u306B\u4F8B\u5916\u304C\u767A\u751F\u3057\u307E\u3057\u305F\uFF08${err.message}\uFF09\u3002\u5B9F\u884C\u306F\u7D9A\u3051\u307E\u3059`)}finally{checking=false}})()},intervalSec*1e3);timer.unref?.();return{stop:()=>{stopped=true;clearInterval(timer)}}}async abortRunningAi(){this.aborting=true;const inFlight=this.itemInFlight!==null;const drained=new Promise(resolve=>{this.abortDrained=resolve});
|
|
180
182
|
await this.engine.abort?.();if(!inFlight){this.abortDrained=null;return}this.deps.log.log(` \u5B9F\u884C\u4E2D\u30A2\u30A4\u30C6\u30E0\u3092\u30AD\u30E5\u30FC\u3078\u8FD4\u3059\u307E\u3067\u5F85\u6A5F\u3057\u307E\u3059\uFF08\u6700\u5927${ABORT_DRAIN_TIMEOUT_MS/1e3}\u79D2\uFF09...`);let timer=null;await Promise.race([drained,new Promise(resolve=>{timer=setTimeout(()=>{this.deps.log.log(` \u26A0\uFE0F ${ABORT_DRAIN_TIMEOUT_MS/1e3}\u79D2\u4EE5\u5185\u306B\u30AD\u30E5\u30FC\u3078\u8FD4\u305B\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30B5\u30FC\u30D0\u306E\u56DE\u53CE\uFF08heartbeat \u3057\u304D\u3044\u5024\uFF09\u3067 pending \u3078\u623B\u308A\u307E\u3059`);
|
|
181
|
-
resolve()},ABORT_DRAIN_TIMEOUT_MS);timer.unref?.()})]);if(timer!==null)clearTimeout(timer);this.abortDrained=null}async shutdown(){await this.planLock.release("failed")}async run(){const{config,log,runner}=this.deps;log.log(describeOperations(config.operations));if(
|
|
182
|
-
let cycle=0;let noProgressStreak=0;let unavailableStreak=0;let undeterminedStreak=0;let exitCode=0;while(cycle<config.maxCycles){if(this.aborting){log.log("\u4E2D\u65AD\u30B7\u30B0\u30CA\u30EB\u3092\u53D7\u3051\u3066\u3044\u308B\
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
resolve()},ABORT_DRAIN_TIMEOUT_MS);timer.unref?.()})]);if(timer!==null)clearTimeout(timer);this.abortDrained=null}async shutdown(){await this.planLock.release("failed")}async run(){const{config,log,runner}=this.deps;log.log(describeOperations(config.operations));if(config.planEnabled&&config.operations.planSkill===null){log.log("\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u306F\u7121\u52B9\u3067\u3059\uFF08operations.plan_skill \u672A\u8A2D\u5B9A\uFF09\u3002\u30AD\u30E5\u30FC\u304C\u7A7A\u3067\u3082\u8A08\u753BAI\u3092\u8D77\u52D5\u305B\u305A\u3001\u7A4D\u307E\u308C\u305F\u4ED5\u4E8B\u306E\u5B9F\u884C\u3060\u3051\u3092\u884C\u3044\u307E\u3059\u3002")}
|
|
184
|
+
if(!config.planEnabled){log.log("\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u306F\u7121\u52B9\u3067\u3059\uFF08plan_enabled=false\uFF09\u3002\u30AD\u30E5\u30FC\u304C\u7A7A\u3067\u3082\u8A08\u753BAI\u3092\u8D77\u52D5\u305B\u305A\u3001\u7A4D\u307E\u308C\u305F\u4ED5\u4E8B\u306E\u5B9F\u884C\u3060\u3051\u3092\u884C\u3044\u307E\u3059\u3002")}let cycle=0;let noProgressStreak=0;let unavailableStreak=0;let undeterminedStreak=0;let exitCode=0;while(cycle<config.maxCycles){if(this.aborting){log.log("\u4E2D\u65AD\u30B7\u30B0\u30CA\u30EB\u3092\u53D7\u3051\u3066\u3044\u308B\
|
|
185
|
+
\u305F\u3081\u3001\u65B0\u3057\u3044\u30B5\u30A4\u30AF\u30EB\u3092\u958B\u59CB\u3057\u307E\u305B\u3093\u3002");break}if(this.draining){log.log(`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u3066\u3044\u308B\u305F\u3081\u3001\u65B0\u3057\u3044\u30B5\u30A4\u30AF\u30EB\u3092\u958B\u59CB\u3057\u307E\u305B\u3093\uFF08\u7D42\u4E86\u30B3\u30FC\u30C9 ${this.drainExitCode}\uFF09\u3002`);exitCode=this.drainExitCode;break}cycle+=1;const cycleStart=Date.now();log.separator();log.log(`========== Cy\
|
|
186
|
+
cle ${cycle}${config.daemon?"":`/${config.maxCycles}`} \u958B\u59CB ==========`);log.separator();await runner.beat("idle");log.log(formatHookWiring(config.prefetch,config.preflight));if(config.preflight.length>0){log.log(`\u74B0\u5883\u306E\u524D\u63D0\u6761\u4EF6\u3092\u78BA\u8A8D\u4E2D\uFF08\u30D5\u30C3\u30AF ${config.preflight.length}\u4EF6\uFF09...`)}this.cyclePreflightSection=await runPreflight(config.preflight,config.workspace,m=>log.log(m));await this.settings.apply();await this.skills.refresh();
|
|
187
|
+
try{await this.engine.healthCheck?.({cwd:config.workspace,logFilePrefix:path5.join(config.logDir,`health-${this.timestamp}-${cycle}`)})}catch(err){log.log(` \u26A0\uFE0F AI\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${err.message}\uFF09\u3002\u9396\u306F\u305D\u306E\u307E\u307E\u4F7F\u3044\u307E\u3059`)}for(const line of normalizeGitIdentity(config.workspace,config.gitIdentity).logs)log.log(line);let planSkippedNoLock=false;const resent=await this.
|
|
188
|
+
writeback.retryPending();for(const itemId of resent)await this.schedule.recordByItem(itemId,"completed");const reclaimRes=await this.deps.api.reclaim();if(!reclaimRes.ok){log.log(` \u26A0\uFE0F \u6B7B\u3093\u3060\u30E9\u30F3\u30CA\u30FC\u306E\u30A2\u30A4\u30C6\u30E0\u56DE\u53CEAPI\u304C\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${describeError(reclaimRes)}\uFF09\u3002\u53D6\u308A\u6B8B\u3057\u304C\u6B8B\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059`)}await this.reclaimStaleProcessing();
|
|
189
|
+
const trust=this.trustGate.evaluate();for(const line of trust.logs)log.log(line);if(trust.note!==null){this.cyclePreflightSection=this.cyclePreflightSection===""?trust.note:`${this.cyclePreflightSection}
|
|
187
190
|
|
|
188
191
|
${trust.note}`}if(trust.wait){await runner.beat("waiting");if(cycle<config.maxCycles)await this.sleepUnlessDraining(config.intervalSec*1e3);continue}const pendingListed=await this.hasPendingItems();const hadPending=pendingListed&&!this.nothingClaimableBacklog;if(pendingListed&&!hadPending){log.log("pending \u306F\u3053\u306E\u6A5F\u4F53\u304C\u53D6\u308C\u306A\u3044\u3082\u306E\uFF08\u524D\u63D0\u672A\u5145\u8DB3\u30FB\u5225\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u5C02\u7528\uFF09\u3060\u3051\u3067\u3059\uFF08\u524D\u56DE\u306E claim \u306E\u5224\u5B9A\uFF09\u3002\u30AD\u30E5\u30FC\u304C\u7A7A\u306E\u3068\u304D\u3068\u540C\u3058\u304F\u8A08\u753B\u3057\u307E\u3059\u3002")}
|
|
189
|
-
this.midcycleEnqueued=0;this.deferredIds=new Set;await this.enqueueDueScheduled(false);const planSkippedDisabled=!hadPending
|
|
190
|
-
log.log("\u30AD\u30E5\u30FC\u304C\u7A7A\u3067\u3059\u3002\u8A08\u753B\u3092\u7ACB\u6848\u3057\u3066\u30A8\u30F3\u30AD\u30E5\u30FC\u3057\u307E\u3059\u3002")}if(planSkippedDisabled){}else if(!hadPending&&this.draining){log.log("\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u3066\u3044\u308B\u305F\u3081\u3001\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u3092\u5B9F\u884C\u3057\u307E\u305B\u3093\u3002")}else if(!hadPending){
|
|
191
|
-
true;log.log("\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u30AD\u30E5\u30FC\u306E\u5B9F\u884C\u3078\u9032\u307F\u307E\u3059\u3002")}else{await runner.beat("plan");this.planLock.startRenewWorker();let planResult="failed";try{planResult=await this.runPlanAndEnqueue(cycle)}finally{await this.planLock.release(planResult==="ok"?"completed":"failed");this.planLock.reportIfLost()}
|
|
192
|
-
break}if(planResult!=="ok"&&isAiUnavailable(planResult)){undeterminedStreak=0;if(needsHumanToRestoreAi(planResult)){noProgressStreak+=1;unavailableStreak+=1;log.log(`\u26D4 ${aiUnavailableLabel(planResult)}\u305F\u3081\u8A08\u753B\u3067\u304D\u307E\u305B\u3093 (\u9023\u7D9A: ${unavailableStreak}
|
|
193
|
-
log.log("
|
|
194
|
-
if(cycle<config.maxCycles){await runner.beat("waiting");await this.sleepUnlessDraining(config.intervalSec*1e3)}continue}if(planResult!=="ok"){log.log("\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u304C\u5931\u6557\u3057\u307E\u3057\u305F");
|
|
195
|
-
runDequeueLoop(cycle);if(outcome.stop){log.log(this.aborting?"\u4E2D\u65AD\u30B7\u30B0\u30CA\u30EB\u306B\u3088\u308A\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002":this.draining?`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u306B\u3088\u308A\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\uFF08\u5B9F\u884C\u4E2D\u306E\u30A2\
|
|
196
|
-
if(this.draining)exitCode=this.drainExitCode;break}unavailableStreak=outcome.unexecuted>0&&outcome.needsHuman?unavailableStreak+1:0;if(outcome.progress){noProgressStreak=0;undeterminedStreak=0;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u9032\u6357\u3042\u308A`)}else if(outcome.
|
|
197
|
-
\u4EF6\u3092\u30AD\u30E5\u30FC\u3078\u8FD4\u5374\u30FB\u9023\u7D9A: ${noProgressStreak}\uFF09`);log.log(` ${AI_RECOVERY_HINT}`)}else if(outcome.unexecuted>0){undeterminedStreak=0;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: AI \u5074\u306E\u90FD\u5408\u3067 ${outcome.unexecuted}\
|
|
198
|
-
|
|
199
|
-
emptyQueue&&
|
|
200
|
-
)`)}else{log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u8A08\u753B\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3001\u30AD\u30E5\u30FC\u3082\u7A7A\u3067\u3057\u305F\uFF08\u9023\u7D9A\u30AB\u30A6\u30F3\u30C8\u306F\u52A0\u7B97\u3057\u306A\u3044\u30FB\u6B21\u30B5\u30A4\u30AF\u30EB\u3067\u518D\u5224\u5B9A\uFF09`)}}else if(outcome.
|
|
201
|
-
\u30B5\u30A4\u30AF\u30EB\u9023\u7D9A\u30FB\u9032\u6357\u306A\u3057\u306B\u306F\u6570\u3048\u306A\u3044\uFF09`);if(undeterminedStreak>=config.queueUndeterminedMax){log.log(`\u26D4 claim API\u306E\u969C\u5BB3\u304C ${undeterminedStreak} \u30B5\u30A4\u30AF\u30EB\u7D9A\u3044\u3066\u3044\u307E\u3059\u3002\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\uFF08\u7D42\u4E86\u30B3\u30FC\u30C91\uFF09`);
|
|
202
|
-
exitCode=1;break}}else{undeterminedStreak=0;noProgressStreak+=1;log.log(outcome.emptyQueue?`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u30AD\u30E5\u30FC\u304C\u7A7A\u3067\u3057\u305F (\u9023\u7D9A: ${noProgressStreak})`:`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u9032\u6357\u306A\u3057 (\u9023\u7D9A: ${noProgressStreak}
|
|
203
|
-
|
|
204
|
-
\u3082\u540C\u3058\u7D50\u679C\u306B\u306A\u308A\u307E\u3059**")
|
|
205
|
-
|
|
192
|
+
this.midcycleEnqueued=0;this.deferredIds=new Set;await this.enqueueDueScheduled(false);const planSkippedDisabled=!hadPending&&(!config.planEnabled||config.operations.planSkill===null);if(hadPending){log.log("\u30AD\u30E5\u30FC\u306Bpending\u30A2\u30A4\u30C6\u30E0\u304C\u3042\u308A\u307E\u3059\u3002\u8A08\u753B\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u5B9F\u884C\u306B\u9032\u307F\u307E\u3059\u3002")}else if(planSkippedDisabled){log.log(`\u30AD\u30E5\u30FC\u306F\u7A7A\u3067\u3059\u304C\u3001\u3053\u306E\u6A5F\u4F53\u306F\u8A08\u753B\u3092\u7ACB\u3066\u306A\u3044\u8A2D\u5B9A\u3067\u3059\uFF08${config.
|
|
193
|
+
planEnabled?"operations.plan_skill \u672A\u8A2D\u5B9A":"plan_enabled=false"}\uFF09\u3002AI \u3092\u8D77\u52D5\u305B\u305A\u30AD\u30E5\u30FC\u306E\u5B9F\u884C\u3078\u9032\u307F\u307E\u3059\u3002`)}else{log.log("\u30AD\u30E5\u30FC\u304C\u7A7A\u3067\u3059\u3002\u8A08\u753B\u3092\u7ACB\u6848\u3057\u3066\u30A8\u30F3\u30AD\u30E5\u30FC\u3057\u307E\u3059\u3002")}if(planSkippedDisabled){}else if(!hadPending&&this.draining){log.log("\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u3066\u3044\u308B\u305F\u3081\u3001\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u3092\u5B9F\u884C\u3057\u307E\u305B\u3093\u3002")}else if(!hadPending){
|
|
194
|
+
const acquired=await this.planLock.acquire();if(acquired!=="acquired"){planSkippedNoLock=true;log.log("\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3066\u30AD\u30E5\u30FC\u306E\u5B9F\u884C\u3078\u9032\u307F\u307E\u3059\u3002")}else{await runner.beat("plan");this.planLock.startRenewWorker();let planResult="failed";try{planResult=await this.runPlanAndEnqueue(cycle)}finally{await this.planLock.release(planResult==="ok"?"completed":"failed");this.planLock.reportIfLost()}
|
|
195
|
+
if(planResult==="aborted"){log.log("\u4E2D\u65AD\u30B7\u30B0\u30CA\u30EB\u306B\u3088\u308A\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u3092\u6253\u3061\u5207\u308A\u307E\u3057\u305F\u3002\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002");break}if(planResult!=="ok"&&isAiUnavailable(planResult)){undeterminedStreak=0;if(needsHumanToRestoreAi(planResult)){noProgressStreak+=1;unavailableStreak+=1;log.log(`\u26D4 ${aiUnavailableLabel(planResult)}\u305F\u3081\u8A08\u753B\u3067\u304D\u307E\u305B\u3093 (\u9023\u7D9A: ${unavailableStreak}\
|
|
196
|
+
)`);log.log(` ${AI_RECOVERY_HINT}`);if(unavailableStreak>=3){exitCode=1;log.log("\u26D4 AI \u30921\u3064\u3082\u8D77\u52D5\u3067\u304D\u306A\u3044\u72B6\u614B\u304C\u7D9A\u3044\u3066\u3044\u307E\u3059\u3002\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\uFF08\u7D42\u4E86\u30B3\u30FC\u30C91\uFF09");log.log(" **\u518D\u30ED\u30B0\u30A4\u30F3\uFF0F\u30C8\u30FC\u30AF\u30F3\u6295\u5165\u307E\u3067\u518D\u8D77\u52D5\u3057\u3066\u3082\u540C\u3058\u7D50\u679C\u306B\u306A\u308A\u307E\u3059**");
|
|
197
|
+
break}}else{unavailableStreak=0;log.log(`\u26A0\uFE0F ${aiUnavailableLabel(planResult)}\u3067\u8A08\u753B\u3067\u304D\u307E\u305B\u3093${this.cooldownNote(planResult)}\uFF08\u9023\u7D9A\u30AB\u30A6\u30F3\u30C8\u306F\u52A0\u7B97\u3057\u306A\u3044\u30FB\u6B21\u30B5\u30A4\u30AF\u30EB\u3067\u518D\u5224\u5B9A\uFF09`)}if(cycle<config.maxCycles){await runner.beat("waiting");await this.sleepUnlessDraining(config.intervalSec*1e3)}continue}if(planResult!=="ok"){log.log("\u8A08\u753B\u30D5\u30A7\u30FC\u30BA\u304C\u5931\u6557\u3057\u307E\u3057\u305F");
|
|
198
|
+
if(config.daemon){log.log(`\u30C7\u30FC\u30E2\u30F3\u30E2\u30FC\u30C9\u306E\u305F\u3081 ${config.intervalSec}\u79D2\u5F8C\u306B\u30EA\u30C8\u30E9\u30A4...`);await runner.beat("waiting");await this.sleepUnlessDraining(config.intervalSec*1e3);continue}break}}}const outcome=await this.runDequeueLoop(cycle);if(outcome.stop){log.log(this.aborting?"\u4E2D\u65AD\u30B7\u30B0\u30CA\u30EB\u306B\u3088\u308A\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002":this.draining?`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u306B\u3088\u308A\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\uFF08\u5B9F\u884C\u4E2D\u306E\u30A2\
|
|
199
|
+
\u30A4\u30C6\u30E0\u306F\u5B8C\u8D70\u6E08\u307F\u30FB\u7D42\u4E86\u30B3\u30FC\u30C9 ${this.drainExitCode}\uFF09\u3002`:"/stop \u30B3\u30DE\u30F3\u30C9\u306B\u3088\u308A\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002");if(this.draining)exitCode=this.drainExitCode;break}unavailableStreak=outcome.unexecuted>0&&outcome.needsHuman?unavailableStreak+1:0;if(outcome.progress){noProgressStreak=0;undeterminedStreak=0;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u9032\u6357\u3042\u308A`)}else if(outcome.
|
|
200
|
+
unexecuted>0&&outcome.needsHuman){undeterminedStreak=0;noProgressStreak+=1;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: AI \u30921\u3064\u3082\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${outcome.unexecuted}\u4EF6\u3092\u30AD\u30E5\u30FC\u3078\u8FD4\u5374\u30FB\u9023\u7D9A: ${noProgressStreak}\uFF09`);log.log(` ${AI_RECOVERY_HINT}`)}else if(outcome.unexecuted>0){undeterminedStreak=0;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: AI \u5074\u306E\u90FD\u5408\u3067 ${outcome.unexecuted}\
|
|
201
|
+
\u4EF6\u3092\u5B9F\u884C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F${this.cooldownNote("rate-limited")}\uFF08\u30AD\u30E5\u30FC\u3078\u8FD4\u5374\u30FB\u9023\u7D9A\u30AB\u30A6\u30F3\u30C8\u306F\u52A0\u7B97\u3057\u306A\u3044\uFF09`)}else if(outcome.deferred>0){log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u6642\u9593\u5E2F\u30B2\u30FC\u30C8\u3067\u5F85\u6A5F\u4E2D\uFF08${outcome.deferred}\u4EF6\u3092\u5F8C\u56DE\u3057\u30FB\u9023\u7D9A\u30AB\u30A6\u30F3\u30C8\u306F\u52A0\u7B97\u3057\u306A\u3044\uFF09`)}else if(outcome.
|
|
202
|
+
emptyQueue&&planSkippedDisabled){undeterminedStreak=0;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u8A08\u753B\u3092\u7ACB\u3066\u306A\u3044\u8A2D\u5B9A\u3067\u30AD\u30E5\u30FC\u3082\u7A7A\u3067\u3057\u305F\uFF08\u5F85\u6A5F\u30FB\u9023\u7D9A\u30AB\u30A6\u30F3\u30C8\u306F\u52A0\u7B97\u3057\u306A\u3044\uFF09`)}else if(outcome.emptyQueue&&planSkippedNoLock){undeterminedStreak=0;if(this.planLock.permanentFail&&this.planLock.failStreak>=config.planLockPermanentMax){noProgressStreak+=1;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}\
|
|
203
|
+
: \u8A08\u753B\u30ED\u30C3\u30AF\u306E\u53D6\u5F97\u304C\u6052\u4E45\u30A8\u30E9\u30FC\uFF084xx\uFF09\u3067 ${this.planLock.failStreak}\u30B5\u30A4\u30AF\u30EB\u9023\u7D9A\u3057\u3066\u3044\u307E\u3059`);log.log(` **\u518D\u8A66\u884C\u3067\u306F\u89E3\u6D88\u3057\u306A\u3044\u305F\u3081\u3001\u9032\u6357\u306A\u3057\u3068\u3057\u3066\u6570\u3048\u307E\u3059** (\u9023\u7D9A: ${noProgressStreak})`)}else{log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u8A08\u753B\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u3001\u30AD\u30E5\u30FC\u3082\u7A7A\u3067\u3057\u305F\uFF08\u9023\u7D9A\u30AB\u30A6\u30F3\u30C8\u306F\u52A0\u7B97\u3057\u306A\u3044\u30FB\u6B21\u30B5\u30A4\u30AF\u30EB\u3067\u518D\u5224\u5B9A\uFF09`)}}else if(outcome.
|
|
204
|
+
undetermined){undeterminedStreak+=1;log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u30AD\u30E5\u30FC\u306E\u72B6\u614B\u3092\u5224\u5B9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${undeterminedStreak}\u30B5\u30A4\u30AF\u30EB\u9023\u7D9A\u30FB\u9032\u6357\u306A\u3057\u306B\u306F\u6570\u3048\u306A\u3044\uFF09`);if(undeterminedStreak>=config.queueUndeterminedMax){log.log(`\u26D4 claim API\u306E\u969C\u5BB3\u304C ${undeterminedStreak} \u30B5\u30A4\u30AF\u30EB\u7D9A\u3044\u3066\u3044\u307E\u3059\u3002\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\uFF08\u7D42\u4E86\u30B3\u30FC\u30C91\uFF09`);
|
|
205
|
+
log.log(" \u78BA\u8A8D: API\u306E\u758E\u901A\uFF0F\u30ED\u30B0\u30A4\u30F3\u72B6\u614B\uFF0F--project \u306E\u6307\u5B9A\u3002\u5FA9\u65E7\u5F8C\u306B\u518D\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044");exitCode=1;break}}else{undeterminedStreak=0;noProgressStreak+=1;log.log(outcome.emptyQueue?`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u30AD\u30E5\u30FC\u304C\u7A7A\u3067\u3057\u305F (\u9023\u7D9A: ${noProgressStreak})`:`\u30B5\u30A4\u30AF\u30EB ${cycle}: \u9032\u6357\u306A\u3057 (\u9023\u7D9A: ${noProgressStreak}\
|
|
206
|
+
)`)}log.log(`\u30B5\u30A4\u30AF\u30EB ${cycle} \u5B8C\u4E86 (duration: ${Math.trunc((Date.now()-cycleStart)/1e3)}s)`);if(noProgressStreak>=3){log.log("3\u30B5\u30A4\u30AF\u30EB\u9023\u7D9A\u3067\u9032\u6357\u306A\u3057\u3002\u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002");if(unavailableStreak>=3){exitCode=1;log.log("\u26D4 \u539F\u56E0\u306F\u300CAI \u30921\u3064\u3082\u8D77\u52D5\u3067\u304D\u306A\u3044\u300D\u3053\u3068\u3067\u3059\uFF08\u672A\u30ED\u30B0\u30A4\u30F3\u7B49\uFF09\u3002");
|
|
207
|
+
log.log(` ${AI_RECOVERY_HINT}`);log.log(" **\u8CC7\u683C\u60C5\u5831\u3092\u76F4\u3059\u307E\u3067\u518D\u8D77\u52D5\u3057\u3066\u3082\u540C\u3058\u7D50\u679C\u306B\u306A\u308A\u307E\u3059**")}if(this.planLock.permanentFail){log.log("\u26D4 \u539F\u56E0\u306F\u8A08\u753B\u30ED\u30C3\u30AFAPI\u306E\u6052\u4E45\u30A8\u30E9\u30FC\uFF084xx\uFF09\u3067\u3059\u3002**\u8A2D\u5B9A\u3092\u76F4\u3059\u307E\u3067\u518D\u8D77\u52D5\u3057\u3066\u3082\u540C\u3058\u7D50\u679C\u306B\u306A\u308A\u307E\u3059**");
|
|
208
|
+
exitCode=1}break}if(cycle<config.maxCycles){log.log(`\u6B21\u30B5\u30A4\u30AF\u30EB\u307E\u3067 ${config.intervalSec}\u79D2 \u5F85\u6A5F...`);await runner.beat("waiting");await this.sleepUnlessDraining(config.intervalSec*1e3)}}log.separator();this.abortDrained?.();log.log("twp task-loop \u7D42\u4E86");log.log(` \u7DCF\u30B5\u30A4\u30AF\u30EB\u6570: ${cycle}`);log.log(` \u30ED\u30B0: ${config.logDir}`);log.separator();return exitCode}async hasPendingItems(){const res=await this.deps.api.list({status:"\
|
|
209
|
+
pending",limit:1});if(!res.ok){this.deps.log.log(` \u26A0\uFE0F pending\u4EF6\u6570\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${describeError(res)}\uFF09\u3002\u5B89\u5168\u5074\u306B\u5012\u3057\u3066\u8A08\u753B\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u307E\u3059\u3002`);return true}const items=pick(res.json,"items");if(!Array.isArray(items)){this.deps.log.log(` \u26A0\uFE0F pending\u4EF6\u6570\u3092\u89E3\u91C8\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u5FDC\u7B54\u306E\u5148\u982D: ${res.
|
|
206
210
|
raw.slice(0,120)}\uFF09\u3002\u5B89\u5168\u5074\u306B\u5012\u3057\u3066\u8A08\u753B\u3092\u30B9\u30AD\u30C3\u30D7\u3057\u307E\u3059\u3002`);return true}return filterByStatus(items,"pending").length>0}async reclaimStaleProcessing(){const{config,log,api}=this.deps;if(config.staleReclaimHours<=0)return;const floorH=staleFloorHours(config.aiTimeoutSec);let hours=config.staleReclaimHours;if(hours<floorH){log.log(` \u2139\uFE0F STALE_RECLAIM_HOURS=${hours}h \u306F\u6700\u9577\u5B9F\u884C\u6642\u9593(AI_TIMEOUT\xD72=${floorH}\
|
|
207
211
|
h)\u3092\u4E0B\u56DE\u308B\u305F\u3081 ${floorH}h \u3092\u4F7F\u3044\u307E\u3059`);hours=floorH}const thresholdMs=hours*36e5;const now=Date.now();const stale=[];let cursor;for(let page=0;page<50;page++){const res=await api.list({status:"processing",limit:200,cursor});if(!res.ok){log.log(` \u26A0\uFE0F stale processing \u306E\u8D70\u67FB\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${describeError(res)}\uFF09\u3002`);log.log(" \u53D6\u308A\u6B8B\u3057\u306E\u56DE\u53CE\u306F\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u884C\u308F\u308C\u3066\u3044\u307E\u305B\u3093");
|
|
208
212
|
return}const items=pick(res.json,"items");if(!Array.isArray(items)){log.log(` \u26A0\uFE0F stale processing \u306E\u4E00\u89A7\u3092\u89E3\u91C8\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u5FDC\u7B54\u306E\u5148\u982D: ${res.raw.slice(0,120)}\uFF09\u3002`);log.log(" \u53D6\u308A\u6B8B\u3057\u306E\u56DE\u53CE\u306F\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u884C\u308F\u308C\u3066\u3044\u307E\u305B\u3093");return}for(const it of filterByStatus(items,"processing")){if(it.runner_id)continue;
|
|
209
213
|
const ts=it.updated_at??it.dequeued_at??it.created_at??"";const at=Date.parse(ts);if(Number.isFinite(at)&&now-at>thresholdMs&&it.item_id)stale.push(it.item_id)}const body=res.json;const pg=body?.["pagination"];const hasMore=(pg?.["has_more"]??body?.["has_more"])===true;const next=pg?.["next_cursor"]??body?.["next_cursor"];if(!hasMore||!next)break;cursor=next}if(stale.length===0)return;let ok=0;for(const itemId of stale){const res=await api.updateUnowned(itemId,{status:"failed",error_message:`sta\
|
|
210
|
-
le processing auto-reclaimed (>${hours}h with no completion update, interrupted cycle)`});if(res.ok)ok+=1}log.log(` stale processing \u56DE\u53CE: ${ok}\u4EF6\u3092 failed \u306B\u5909\u66F4\uFF08${hours}h\u4EE5\u4E0A\u66F4\u65B0\u306A\u3057\uFF09`)}async enqueueDueScheduled(midcycle){const{config,log
|
|
211
|
-
\
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
log.log(` \
|
|
216
|
-
|
|
217
|
-
log.log(` \u26A0\uFE0F
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
scheduleId}] ${row.windowKey}\
|
|
221
|
-
|
|
222
|
-
if(
|
|
223
|
-
\
|
|
224
|
-
join(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
for(const
|
|
233
|
-
log.log("
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
null
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
if(
|
|
243
|
-
|
|
244
|
-
skill} \u2014 ${
|
|
245
|
-
|
|
246
|
-
\
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
log(` \u30A8\u30F3\u30AD\u30E5\u30FC\
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
\
|
|
256
|
-
|
|
257
|
-
{
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
409){log.log(` \u26A0\uFE0F \u65E2\u306B\u5225\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08409\uFF09
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
exec(label)?.[1];this.itemInFlight=itemId;const resolvedSkills=await this.skills.resolve(prompt);const skillOrigins=formatSkillOrigins(resolvedSkills.origins);if(skillOrigins!=="")log.log(` \u30B9\u30AD\u30EB: ${skillOrigins}`);const ownershipWatch=this.startOwnershipWatch(itemId);let result;try{result=await this.engine.run({serverSkills:resolvedSkills.bodies,prompt:buildStepPrompt(config,prompt),promptPrefix:this.cyclePreflightSection,logFile:stepLog,aiType:item.ai_type??void 0,aiModel:item.ai_model??
|
|
266
|
-
void 0,aiEffort:item.ai_effort??void 0,timeoutSec:config.aiTimeoutSec,cwd:config.workspace,skill:skillName,...skillName===""&&taggedCategory!==void 0?{category:taggedCategory}:{}})}finally{ownershipWatch.stop();this.itemInFlight=null}writeLogFile(stepLog,skillOrigins===""?result.output:`[skill] ${skillOrigins}
|
|
214
|
+
le processing auto-reclaimed (>${hours}h with no completion update, interrupted cycle)`});if(res.ok)ok+=1}log.log(` stale processing \u56DE\u53CE: ${ok}\u4EF6\u3092 failed \u306B\u5909\u66F4\uFF08${hours}h\u4EE5\u4E0A\u66F4\u65B0\u306A\u3057\uFF09`)}async enqueueDueScheduled(midcycle){const{config,log}=this.deps;const counts="";const due=await this.schedule.due(counts);if(due.kind==="error"){log.log(` \u26D4 ${due.message}`);log.log(" \u5B9A\u671F\u30BF\u30B9\u30AF\u306F1\u4EF6\u3082\u6295\u5165\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
|
|
215
|
+
return}const queued=await this.deps.api.queuedSnapshot();if(queued===null&&!midcycle){log.log(" \u26A0\uFE0F \u30AD\u30E5\u30FC\u306E prompt \u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u4E8C\u91CD\u6295\u5165\u306E\u4FDD\u967A\uFF08prompt \u4E00\u81F4\uFF09\u306F\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u7121\u52B9\u3067\u3059")}const queuedPrompts=new Set((queued??[]).map(it=>(it.prompt??"").trim()));let exclusiveQueuedSkills=null;let exclusiveFetched=false;
|
|
216
|
+
const exclusiveInflight=async()=>{if(exclusiveFetched)return exclusiveQueuedSkills;exclusiveFetched=true;const[pending,processing]=await Promise.all([this.deps.api.pendingSnapshot(),this.deps.api.processingSnapshot()]);if(pending===null&&processing===null)return null;if(pending===null||processing===null){log.log(` \u26A0\uFE0F ${pending===null?"pending":"processing"} \u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u305D\u306E\u3076\u3093\u5916\u90E8\u6295\u7A3F\u30B9\u30AD\u30EB\u306E\u540C\u6642\u5B9F\u884C\u30AC\u30FC\u30C9\u306F\u7DE9\u307F\u307E\u3059`)}
|
|
217
|
+
const entries=exclusiveInflightEntries([{status:"processing",items:processing??[]},{status:"pending",items:pending??[]}],{staleHours:inflightStaleHours(config.aiTimeoutSec)});const exclusive=entries.filter(e=>config.ai.isExclusiveSkill(e.skill));for(const entry of exclusive)log.log(` \u65E2\u306B\u30AD\u30E5\u30FC/\u5B9F\u884C\u4E2D\u306E\u6392\u4ED6\u30B9\u30AD\u30EB: ${formatExclusiveEntry(entry)}`);exclusiveQueuedSkills=new Set(exclusive.map(e=>e.skill));return exclusiveQueuedSkills};const exclusiveEnqueued=new Set;
|
|
218
|
+
const enqueuedLines=[];const ai=config.ai;let count=0;for(const row of due.rows){const prompt=`/twp-${row.skill}${row.args?` ${row.args}`:""}`;if(queued!==null&&queuedPrompts.has(prompt)){log.log(` \u5B9A\u671F\u30B9\u30AD\u30C3\u30D7: \u540C\u4E00\u30A2\u30A4\u30C6\u30E0\u304C\u30AD\u30E5\u30FC\u306B\u5B58\u5728 | ${prompt}`);continue}const exclusiveSkill=config.ai.isExclusiveSkill(row.skill)?normalizeSkillName(row.skill):null;if(exclusiveSkill!==null){if(exclusiveEnqueued.has(exclusiveSkill)){
|
|
219
|
+
log.log(` \u5B9A\u671F\u30B9\u30AD\u30C3\u30D7: ${row.skill} \u306F\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u3067\u65E2\u306B\u6295\u5165\u3057\u307E\u3057\u305F\uFF08\u5916\u90E8\u6295\u7A3F\u30B9\u30AD\u30EB\u306F\u540C\u66421\u672C\uFF09 | ${prompt}`);continue}const queuedSkills=await exclusiveInflight();if(queuedSkills===null){log.log(` \u26A0\uFE0F ${row.skill} \u306E\u540C\u6642\u5B9F\u884C\u30AC\u30FC\u30C9\u3092\u8A55\u4FA1\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08\u30AD\u30E5\u30FC\u4E00\u89A7\u306E\u53D6\u5F97\u5931\u6557\uFF09\u2192 \u6295\u5165\u306F\u6B62\u3081\u307E\u305B\u3093`)}else if(queuedSkills.
|
|
220
|
+
has(exclusiveSkill)){log.log(` \u5B9A\u671F\u30B9\u30AD\u30C3\u30D7: ${row.skill} \u306F\u65E2\u306B\u30AD\u30E5\u30FC/\u5B9F\u884C\u4E2D\u3067\u3059\uFF08\u5916\u90E8\u6295\u7A3F\u30B9\u30AD\u30EB\u306F\u540C\u66421\u672C\uFF09 | ${prompt}`);continue}}const claim=await this.schedule.claimWindow(row);if(claim==="taken"){log.log(` \u5B9A\u671F\u30B9\u30AD\u30C3\u30D7: \u4ED6\u6A5F\u304C\u3053\u306E\u67A0\u3092\u6D88\u5316\u6E08\u307F\u3067\u3059 | [${row.scheduleId}] ${row.windowKey}`);continue}
|
|
221
|
+
if(claim==="error"){log.log(` \u26A0\uFE0F \u5B9A\u671F\u67A0\u306E\u7372\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002\u3053\u306E\u67A0\u306F\u672A\u6D88\u5316\u3068\u3057\u3066\u6B21\u30B5\u30A4\u30AF\u30EB\u3078\u9001\u308A\u307E\u3059 | [${row.scheduleId}] ${row.windowKey}`);continue}const category=ai.categoryForSkill(row.skill);const label=`[\u5B9A\u671F][${row.priority}] ${row.label} #ai:${category}`.slice(0,200);const primary=ai.selectPrimary(category,row.skill,row.priority,label);
|
|
222
|
+
const{itemId,detail}=await createItem(this.deps.api,{label,prompt,...primary===""?{}:{ai_type:primary},...row.requiredPlatforms.length>0?{required_platforms:row.requiredPlatforms}:{}});if(!itemId){log.log(` \u26D4 \u5B9A\u671F\u30BF\u30B9\u30AF\u306E\u30A8\u30F3\u30AD\u30E5\u30FC\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08[${row.scheduleId}] ${row.windowKey}\uFF09: ${detail}`);if(detail.startsWith("item_id \u3092\u8AAD\u3081\u307E\u305B\u3093")){log.log(" \u30A2\u30A4\u30C6\u30E0\u306F\u4F5C\u6210\u3055\u308C\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002**\u3053\u306E\u67A0\u306F fai\
|
|
223
|
+
led \u3068\u3057\u3066\u8FD4\u3057\u307E\u305B\u3093**")}else{await this.schedule.releaseWindow(row.scheduleId,row.windowKey,"\u30A8\u30F3\u30AD\u30E5\u30FCAPI\u304C\u5FDC\u7B54\u3057\u306A\u3044")}continue}let recorded=false;for(let attempt=1;attempt<=3&&!recorded;attempt++){recorded=await this.schedule.record(row.scheduleId,row.windowKey,"enqueued",{itemId});if(!recorded&&attempt<3)await this.sleep(3e3)}if(!recorded){log.log(` \u26D4 \u5B9A\u671F\u67A0\u3078\u306E item_id \u8A18\u9332\u306B3\u56DE\u5931\u6557\u3057\u307E\u3057\u305F\uFF08[${row.
|
|
224
|
+
scheduleId}] ${row.windowKey} \u2192 ${itemId}\uFF09`);log.log(" **\u30EA\u30FC\u30B9\u671F\u9650\u5F8C\u306B\u540C\u3058\u67A0\u304C\u518D\u6295\u5165\u3055\u308C\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059**\u3002\u5B9A\u671F\u67A0\u304C\u672C\u756A\u30EA\u30EA\u30FC\u30B9\u306A\u3089\u4E8C\u91CD\u5B9F\u884C\u306B\u306A\u308A\u307E\u3059")}if(exclusiveSkill!==null)exclusiveEnqueued.add(exclusiveSkill);enqueuedLines.push(`- [${row.priority}] ${row.label} \u2192 ${prompt}`);log.log(
|
|
225
|
+
` \u5B9A\u671F\u30A8\u30F3\u30AD\u30E5\u30FC: [${row.priority}] ${row.label} \u2192 ${prompt}`);count+=1}if(count>0){log.log(midcycle?`\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\uFF08\u4E2D\u9593\u5224\u5B9A\uFF09: ${count}\u4EF6\u3092\u30AD\u30E5\u30FC\u306B\u6295\u5165\u3057\u307E\u3057\u305F`:`\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB: ${count}\u4EF6\u3092\u30AD\u30E5\u30FC\u306B\u6295\u5165\u3057\u307E\u3057\u305F`);this.midcycleEnqueued+=count}else if(!midcycle){log.log("\u5B9A\u671F\u30B9\u30B1\u30B8\
|
|
226
|
+
\u30E5\u30FC\u30EB: \u4ECA\u30B5\u30A4\u30AF\u30EB\u3067\u767A\u706B\u3057\u305F\u5B9A\u671F\u30BF\u30B9\u30AF\u306F\u3042\u308A\u307E\u305B\u3093")}if(!midcycle){const file=path5.join(this.deps.config.logDir,`schedule-enqueued-${this.timestamp}.txt`);try{fs7.mkdirSync(path5.dirname(file),{recursive:true});fs7.writeFileSync(file,enqueuedLines.join("\n"))}catch{}}}async maybeEnqueueDueMidcycle(){const res=await this.deps.api.reclaim();if(!res.ok){this.deps.log.log(` \u26A0\uFE0F \u6B7B\u3093\u3060\u30E9\u30F3\u30CA\u30FC\u306E\u30A2\u30A4\u30C6\u30E0\u56DE\u53CEAPI\u304C\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${describeError(
|
|
227
|
+
res)}\uFF09`)}if(this.midcycleEnqueued>=this.deps.config.scheduleMidcycleMax)return;await this.enqueueDueScheduled(true)}async runPlanAndEnqueue(cycle){const{config,log}=this.deps;const planSkill=config.operations.planSkill;if(planSkill===null)return"failed";log.separator();log.log("Phase 1: \u8A08\u753B\u3092\u7ACB\u6848\u3057\u3066\u30AD\u30E5\u30FC\u306B\u683C\u7D0D...");log.separator();const planLogFile=path5.join(config.logDir,`plan-${this.timestamp}-${cycle}.log`);const enqueuedFile=path5.
|
|
228
|
+
join(config.logDir,`schedule-enqueued-${this.timestamp}.txt`);const scheduleSection=await this.schedule.promptSection(enqueuedFile);if(config.prefetch.length>0)log.log(`\u8A08\u753B\u7528\u30C7\u30FC\u30BF\u3092\u4E8B\u524D\u53D6\u5F97\u4E2D\uFF08\u30D5\u30C3\u30AF ${config.prefetch.length}\u4EF6\uFF09...`);const prefetchSection=await runPrefetch(config.prefetch,config.workspace,m=>log.log(m));const excludeKeys=parsePlanExcludeKeys(prefetchSection);if(excludeKeys.size>0){log.log(` \u8A08\u753B\u5019\u88DC\u304B\u3089\u5916\u3059\u30BF\u30B9\u30AF\uFF08\u672A\
|
|
229
|
+
\u56DE\u7B54\u306E\u8CEA\u554F\u3042\u308A\uFF09: ${[...excludeKeys].sort().join(", ")}`)}const taskStatusSnapshot=parseTaskStatusSnapshot(prefetchSection);if(taskStatusSnapshot===null){log.log(" \u26A0\uFE0F prefetch \u306B OPS_TASK_STATUS \u30DE\u30FC\u30AB\u30FC\u304C\u3042\u308A\u307E\u305B\u3093");log.log(" \u300C\u524D\u56DE\u304C\u72B6\u614B\u3092\u9032\u3081\u305F\u5834\u5408\u306E\u518D\u6295\u5165\u6291\u6B62\u300D\u306F**\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u7121\u52B9**\u3067\u3059\uFF08\u6295\u5165\u306F\u6B62\u3081\u307E\u305B\u3093\uFF09")}else if(!taskStatusSnapshot.
|
|
230
|
+
complete){log.log(" \u26A0\uFE0F \u30BF\u30B9\u30AF\u306E\u30B9\u30C6\u30FC\u30BF\u30B9\u3092\u4E00\u90E8\u53D6\u5F97\u3067\u304D\u3066\u3044\u307E\u305B\u3093\uFF08complete=0\uFF09\u2192 \u518D\u6295\u5165\u6291\u6B62\u306F\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u7121\u52B9\u3067\u3059")}const result=await this.engine.run({prompt:buildPlanPrompt(config,planSkill,scheduleSection,prefetchSection),promptPrefix:this.cyclePreflightSection,logFile:planLogFile,timeoutSec:config.planTimeoutSec,cwd:config.
|
|
231
|
+
workspace,skill:normalizeSkillName(planSkill.replace(/^\//,"")),validate:output=>extractPlanJson(output)!==null});writeLogFile(planLogFile,result.output);if(result.outcome==="aborted"){log.log(" \u23F9 \u4E2D\u65AD\u30B7\u30B0\u30CA\u30EB\u306B\u3088\u308A\u8A08\u753B\u3092\u6253\u3061\u5207\u308A\u307E\u3057\u305F");return"aborted"}if(result.outcome!=="ok"){if(isAiUnavailable(result.outcome)){log.log(` \u23ED AI \u3092\u8D77\u52D5\u3067\u304D\u306A\u3044\u305F\u3081\u8A08\u753B\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08outcome=${result.
|
|
232
|
+
outcome}\uFF09`);return result.outcome}log.log(` \u26D4 \u8A08\u753B\u306E\u5B9F\u884C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08outcome=${result.outcome}\uFF09`);return"failed"}if(this.planLock.isLost()){log.log(` \u26D4 \u8A08\u753B\u4E2D\u306B\u8A08\u753B\u30ED\u30C3\u30AF\u3092\u5931\u3044\u307E\u3057\u305F\uFF08reason=${this.planLock.lostReasonText()}\uFF09`);log.log(" **\u30A8\u30F3\u30AD\u30E5\u30FC\u3092\u4E2D\u6B62\u3057\u307E\u3059**\u3002\u8A08\u753B\u7D50\u679C\u306F\u7834\u68C4\u3057\u3001\u6B21\u30B5\u30A4\u30AF\u30EB\u3067\u53D6\u308A\u76F4\u3057\u307E\u3059");
|
|
233
|
+
return"ok"}const plan=extractPlanJson(result.output);if(!plan||plan.steps.length===0){log.log("\u8A08\u753B\u306Bsteps\u304C\u3042\u308A\u307E\u305B\u3093");return"ok"}const verifyBacklog=parseOpsCount(prefetchSection,"verify");const devVerifyPlanned=plan.steps.filter(s=>(s.skill??"").trim()==="dev-verify").length;const releaseDeployDrop=releaseDeployDropReason(verifyBacklog,devVerifyPlanned);if(releaseDeployDrop!==null&&plan.steps.some(s=>normalizeSkillName(s.skill??"")==="release-deploy")){log.
|
|
234
|
+
log(` release-deploy \u306F\u8A08\u753B\u304B\u3089\u9664\u5916\u3057\u307E\u3059\uFF08\u7A7A\u632F\u308A\u9632\u6B62\u30AC\u30FC\u30C9\uFF09: ${releaseDeployDrop}`)}const zeroTargetDrops=zeroTargetDropReasons(prefetchSection,config.operations.zeroTargetGates);for(const[skill,reason]of zeroTargetDrops){if(plan.steps.some(s=>normalizeSkillName(s.skill??"")===skill)){log.log(` ${skill} \u306F\u8A08\u753B\u304B\u3089\u9664\u5916\u3057\u307E\u3059\uFF08\u5BFE\u8C61\u8AAD\u307F\u66FF\u3048\u9632\u6B62\u30AC\u30FC\u30C9\uFF09: ${reason}`)}}
|
|
235
|
+
const processing=await this.deps.api.processingSnapshot();const inflightKeys=new Set;if(processing===null){log.log(" \u26A0\uFE0F \u51E6\u7406\u4E2D\u30A2\u30A4\u30C6\u30E0\u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F");log.log(" \u540C\u4E00\u30BF\u30B9\u30AF\u306E\u4E8C\u91CD\u7740\u624B\u30AC\u30FC\u30C9\u306F**\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u7121\u52B9**\u3067\u3059\uFF08\u6295\u5165\u306F\u6B62\u3081\u307E\u305B\u3093\uFF09")}else{const entries=inflightEntries(
|
|
236
|
+
processing,new Date,inflightStaleHours(config.aiTimeoutSec));for(const entry of entries)inflightKeys.add(entry.key);if(entries.length>0){log.log(" \u4ED6\u30E9\u30F3\u30CA\u30FC\u304C\u51E6\u7406\u4E2D\u306E task_key\uFF08\u3053\u306E\u8A08\u753B\u304B\u3089\u306F\u9664\u5916\u3057\u307E\u3059\uFF09:");for(const entry of entries)log.log(` - ${formatInflightEntry(entry)}`)}}let pendingCache=null;let pendingFetched=false;const pendingOnce=async()=>{if(!pendingFetched){pendingFetched=true;pendingCache=
|
|
237
|
+
await this.deps.api.pendingSnapshot()}return pendingCache};let pendingKeys=null;let pendingKeysResolved=false;const queuedPendingKeys=async()=>{if(pendingKeysResolved)return pendingKeys;pendingKeysResolved=true;const pending=await pendingOnce();if(pending===null){log.log(" \u26A0\uFE0F pending \u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F");log.log(" \u30AD\u30E5\u30FC\u5F85\u3061\u30AD\u30FC\u306E\u7A4D\u307F\u76F4\u3057\u6291\u6B62\u306F**\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u7121\u52B9**\u3067\u3059\uFF08\u6295\u5165\u306F\u6B62\u3081\u307E\u305B\u3093\uFF09");
|
|
238
|
+
return null}pendingKeys=new Set(pending.map(p=>(p.task_key??"").trim()).filter(k=>k!==""));return pendingKeys};let exclusiveQueued=null;let exclusiveFetched=false;const exclusiveInflight=async()=>{if(exclusiveFetched)return exclusiveQueued;exclusiveFetched=true;const pending=await pendingOnce();if(pending===null&&processing===null){log.log(" \u26A0\uFE0F \u30AD\u30E5\u30FC/\u5B9F\u884C\u4E2D\u30A2\u30A4\u30C6\u30E0\u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F");
|
|
239
|
+
log.log(" \u5916\u90E8\u6295\u7A3F\u30B9\u30AD\u30EB\u306E\u540C\u6642\u5B9F\u884C\u30AC\u30FC\u30C9\u306F**\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u7121\u52B9**\u3067\u3059\uFF08\u6295\u5165\u306F\u6B62\u3081\u307E\u305B\u3093\uFF09");return null}if(pending===null||processing===null){log.log(` \u26A0\uFE0F ${pending===null?"pending":"processing"} \u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u305D\u306E\u3076\u3093\u5916\u90E8\u6295\u7A3F\u30B9\u30AD\u30EB\u306E\u540C\u6642\u5B9F\u884C\u30AC\u30FC\u30C9\u306F\u7DE9\u307F\u307E\u3059`)}
|
|
240
|
+
const entries=exclusiveInflightEntries([{status:"processing",items:processing??[]},{status:"pending",items:pending??[]}],{staleHours:inflightStaleHours(config.aiTimeoutSec)});const exclusive=entries.filter(e=>config.ai.isExclusiveSkill(e.skill));if(exclusive.length>0){log.log(" \u65E2\u306B\u30AD\u30E5\u30FC/\u5B9F\u884C\u4E2D\u306E\u6392\u4ED6\u30B9\u30AD\u30EB\uFF08\u3053\u306E\u8A08\u753B\u304B\u3089\u306F\u9664\u5916\u3057\u307E\u3059\uFF09:");for(const entry of exclusive)log.log(` - ${formatExclusiveEntry(
|
|
241
|
+
entry)}`)}exclusiveQueued=new Set(exclusive.map(e=>e.skill));return exclusiveQueued};let recentCandidates=null;let recentFetched=false;let resultFetchBudget=5;const recentAdvanceFor=async(taskKey,skill)=>{if(!recentFetched){recentFetched=true;const items=await this.deps.api.completedSince(windowStartMicros(new Date));if(items===null){log.log(" \u26A0\uFE0F \u76F4\u8FD1\u306E\u5B9F\u884C\u53F0\u5E33\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F");log.log(" \u300C\u524D\u56DE\u304C\u72B6\u614B\u3092\u9032\u3081\u305F\u5834\u5408\u306E\u518D\
|
|
242
|
+
\u6295\u5165\u6291\u6B62\u300D\u306F**\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u7121\u52B9**\u3067\u3059\uFF08\u6295\u5165\u306F\u6B62\u3081\u307E\u305B\u3093\uFF09")}else{recentCandidates=buildRecentCandidateIndex(items);log.log(` \u76F4\u8FD1${RECENT_ADVANCE_WINDOW_HOURS}\u6642\u9593\u306B\u540C\u4E00\u30BF\u30B9\u30AF\u3092\u6271\u3063\u305F\u5B9F\u884C: ${recentCandidates.size}\u4EF6`)}}if(recentCandidates===null)return null;const candidate=findRecentCandidate(recentCandidates,taskKey,skill);if(candidate===
|
|
243
|
+
null)return null;return resolveRecentAdvance(candidate,async itemId=>{if(resultFetchBudget<=0)return null;resultFetchBudget-=1;const res=await this.deps.api.getItem(itemId);if(!res.ok){log.log(` \u26A0\uFE0F \u76F4\u8FD1\u30A2\u30A4\u30C6\u30E0\u306E\u7D50\u679C\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${describeError(res)}\uFF09\u3002${taskKey} \u306E\u518D\u6295\u5165\u306F\u6291\u6B62\u3057\u307E\u305B\u3093`);return null}return res.json?.item?.result??null})};
|
|
244
|
+
const exclusiveEnqueued=new Set;const enqueuedTaskKeys=new Set;let enqueued=0;for(const step of plan.steps){const item=stepToItem(step,config.ai);if(!item)continue;if(!/^[a-z][a-z0-9-]*$/.test(step.skill)){log.log(` \u26A0\uFE0F \u30B9\u30AD\u30EB\u540D\u304C\u60F3\u5B9A\u306E\u6587\u5B57\u7A2E\u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08skill='${step.skill}'\uFF09\u3002\u6642\u9593\u5E2F\u30B2\u30FC\u30C8\u3068\u30AB\u30C6\u30B4\u30EA\u5224\u5B9A\u304C\u52B9\u304D\u307E\u305B\u3093`)}const placeholder=placeholderTaskKey(
|
|
245
|
+
step.args??"");if(placeholder!==null){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u30BF\u30B9\u30AF\u30AD\u30FC\u304C\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\uFF09: ${step.skill} \u2014 args \u306B '${placeholder}' \u304C\u6B8B\u3063\u3066\u3044\u307E\u3059 | ${item.label}`);continue}const stepSkill=normalizeSkillName(step.skill??"");if(stepSkill==="release-deploy"&&releaseDeployDrop!==null){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08release-deploy \u306E\u7A7A\u632F\u308A\u9632\u6B62\uFF09: ${releaseDeployDrop}\
|
|
246
|
+
| ${item.label}`);continue}const zeroTargetReason=zeroTargetDrops.get(stepSkill);if(zeroTargetReason!==void 0){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u5BFE\u8C610\u4EF6\uFF09: ${step.skill} \u2014 ${zeroTargetReason} | ${item.label}`);continue}if(item.task_key&&inflightKeys.has(item.task_key)){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u4ED6\u30E9\u30F3\u30CA\u30FC\u304C\u51E6\u7406\u4E2D\uFF09: ${step.skill} \u2014 ${item.task_key} \u306F\u4ED6\u30E9\u30F3\u30CA\u30FC\u304C\u51E6\u7406\u4E2D | ${item.
|
|
247
|
+
label}`);continue}if(item.task_key&&(await queuedPendingKeys())?.has(item.task_key)){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u65E2\u306B\u30AD\u30E5\u30FC\u5F85\u3061\uFF09: ${step.skill} \u2014 ${item.task_key} \u306F pending \u306B\u5C45\u307E\u3059 | ${item.label}`);continue}const duplicateKey=duplicateTaskKeyDropReason(enqueuedTaskKeys,item.task_key);if(duplicateKey!==null){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u540C\u4E00\u8A08\u753B\u5185\u306E\u91CD\u8907\u30AD\u30FC\uFF09: ${step.
|
|
248
|
+
skill} \u2014 ${duplicateKey} | ${item.label}`);continue}const excludedKey=excludedKeyInArgs(step.args??"",excludeKeys);if(excludedKey!==null){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u4EBA\u306B\u30DC\u30FC\u30EB\u304C\u3042\u308B\uFF09: ${step.skill} \u2014 ${excludedKey} \u306F\u672A\u56DE\u7B54\u306E\u8CEA\u554F\u3092\u6301\u3064\u4EBA\u9593\u5F85\u3061\u30BF\u30B9\u30AF | ${item.label}`);continue}if(item.task_key){const advance=await recentAdvanceFor(item.task_key,step.skill);
|
|
249
|
+
if(advance!==null){const gate2=shouldSuppressForStatus(advance,taskStatusSnapshot);if(gate2.suppress){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u524D\u56DE\u304C\u72B6\u614B\u3092\u9032\u3081\u305F\uFF09: ${step.skill} \u2014 ${item.task_key} \u306F ${formatRecentAdvance(advance)} | ${item.label}`);continue}log.log(` \u6291\u6B62\u3092\u898B\u9001\u308A: ${step.skill} \u2014 ${item.task_key} \u306F ${formatRecentAdvance(advance)} \u3060\u304C ${gate2.reason} | ${item.label}`)}}
|
|
250
|
+
const gate=await this.schedule.gateAllows(step.skill);if(!gate.allowed){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u6642\u9593\u5E2F\u30B2\u30FC\u30C8\uFF09: ${step.skill} \u2014 ${gate.reason} | ${item.label}`);continue}if(this.planLock.isLost()){log.log(` \u26D4 \u30A8\u30F3\u30AD\u30E5\u30FC\u4E2D\u306B\u8A08\u753B\u30ED\u30C3\u30AF\u3092\u5931\u3044\u307E\u3057\u305F\uFF08reason=${this.planLock.lostReasonText()}\uFF09\u2192 \u3053\u3053\u3067\u4E2D\u6B62\u3057\u307E\u3059\uFF08\u6295\u5165\u6E08\u307F: ${enqueued}\
|
|
251
|
+
\u4EF6\uFF09`);break}const exclusiveSkill=config.ai.isExclusiveSkill(step.skill)?normalizeSkillName(step.skill):null;if(exclusiveSkill!==null){if(exclusiveEnqueued.has(exclusiveSkill)){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u5916\u90E8\u6295\u7A3F\u30B9\u30AD\u30EB\u306E\u540C\u6642\u5B9F\u884C\uFF09: ${step.skill} \u2014 \u540C\u3058\u8A08\u753B\u306B\u65E2\u306B1\u4EF6\u3042\u308A\u307E\u3059 | ${item.label}`);continue}const queuedSkills=await exclusiveInflight();if(queuedSkills?.
|
|
252
|
+
has(exclusiveSkill)){log.log(` \u30A8\u30F3\u30AD\u30E5\u30FC\u6291\u6B62\uFF08\u5916\u90E8\u6295\u7A3F\u30B9\u30AD\u30EB\u306E\u540C\u6642\u5B9F\u884C\uFF09: ${step.skill} \u2014 \u65E2\u306B\u30AD\u30E5\u30FC/\u5B9F\u884C\u4E2D\u306E\u305F\u3081\u7A4D\u307F\u307E\u305B\u3093 | ${item.label}`);continue}}const{itemId,detail}=await createItem(this.deps.api,item);if(itemId){enqueued+=1;if(exclusiveSkill!==null)exclusiveEnqueued.add(exclusiveSkill);if(item.task_key)enqueuedTaskKeys.add(item.task_key)}else{
|
|
253
|
+
log.log(` \u8B66\u544A: \u30A8\u30F3\u30AD\u30E5\u30FC\u5931\u6557: ${item.label} \u2014 ${detail}`)}}log.log(`\u8A08\u753B\u5B8C\u4E86: ${enqueued} \u30A2\u30A4\u30C6\u30E0\u3092\u30AD\u30E5\u30FC\u306B\u8FFD\u52A0\u3057\u307E\u3057\u305F`);return"ok"}async runDequeueLoop(cycle){const{config,log,api,runner}=this.deps;log.separator();log.log("Phase 2: \u30AD\u30E5\u30FC\u304B\u3089\u30C7\u30AD\u30E5\u30FC\u3057\u3066\u9806\u6B21\u5B9F\u884C...");log.separator();let completed=0;let failed=0;let unexecuted=0;
|
|
254
|
+
let unexecutedNeedsHuman=false;let stepNum=0;let contendedRetry=0;let undetermined=false;let stop=false;this.nothingClaimableBacklog=false;dequeue:for(;;){if(this.draining){log.log("\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u3066\u3044\u308B\u305F\u3081\u3001\u65B0\u3057\u3044\u30A2\u30A4\u30C6\u30E0\u306F\u53D6\u5F97\u3057\u307E\u305B\u3093\u3002Phase 2 \u3092\u7D42\u4E86\u3057\u307E\u3059\u3002");stop=true;break}const claimed=await this.claimOne();if(claimed.kind==="undetermined"){
|
|
255
|
+
undetermined=true;break}if(claimed.kind==="contended"){contendedRetry+=1;if(contendedRetry>=config.contendedMax){log.log(` \u26A0\uFE0F contended \u304C ${contendedRetry} \u56DE\u7D9A\u304D\u307E\u3057\u305F\u3002\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u3067\u306E\u53D6\u5F97\u3092\u8AE6\u3081\u307E\u3059\uFF08\u4ED6\u6A5F\u304C\u51E6\u7406\u3092\u7D9A\u3051\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u9AD8\u3044\uFF09`);undetermined=true;break}log.log(` \u2139\uFE0F \u4ED6\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u5148\u306B\u53D6\u5F97\u3057\u307E\u3057\u305F\uFF08contended\u30FB${contendedRetry}\
|
|
256
|
+
\u56DE\u76EE\uFF09\u30023\u79D2\u5F8C\u306B\u518D\u8A66\u884C\u3057\u307E\u3059`);await this.sleep(3e3);continue}contendedRetry=0;this.nothingClaimableBacklog=claimed.kind==="filtered"&&claimed.by.length>0&&claimed.by.every(b=>b==="prerequisite"||b==="platform");if(claimed.kind==="empty"){log.log("\u30AD\u30E5\u30FC\u306Bpending\u30A2\u30A4\u30C6\u30E0\u304C\u3042\u308A\u307E\u305B\u3093\u3002Phase 2 \u5B8C\u4E86\u3002");break}if(claimed.kind==="filtered"){const reasons=claimed.by.includes("plat\
|
|
257
|
+
form")?claimed.by.includes("prerequisite")?"\u524D\u63D0\u672A\u5145\u8DB3\u30FB\u5225\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u5C02\u7528\u306E\u307F":"\u5225\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u5C02\u7528\u306E\u307F":"\u524D\u63D0\u672A\u5145\u8DB3\u306E\u307F";log.log(this.nothingClaimableBacklog?`\u3053\u306E\u6A5F\u4F53\u304C\u53D6\u308C\u308B pending \u30A2\u30A4\u30C6\u30E0\u304C\u3042\u308A\u307E\u305B\u3093\uFF08${reasons}\uFF09\u3002Phase 2 \u5B8C\u4E86\u3002\u6B21\u30B5\u30A4\u30AF\u30EB\u306F\u8A08\u753B\u3057\u307E\u3059\u3002`:
|
|
258
|
+
"\u3053\u306E\u6A5F\u4F53\u304C\u53D6\u308C\u308B pending \u30A2\u30A4\u30C6\u30E0\u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u7406\u7531\u3092\u5224\u5B9A\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u6B21\u30B5\u30A4\u30AF\u30EB\u3082\u8A08\u753B\u3057\u307E\u305B\u3093\uFF09\u3002Phase 2 \u5B8C\u4E86\u3002");break}const item=claimed.item;const itemId=item.item_id??"";const prompt=(item.prompt??"").trim();const label=item.label??"";if(!itemId||!prompt){log.log(`\u30C7\u30AD\u30E5\u30FC\u7D50\u679C\u306E\u30D1\u30FC\u30B9\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${JSON.
|
|
259
|
+
stringify(item).slice(0,200)}`);break}stepNum+=1;log.separator();log.log(`[${stepNum}] ${label}`);log.log(` item_id: ${itemId}`);await runner.beat("dequeue",itemId);log.log(` prompt: ${prompt}`);log.separator();const stopMatch=/^\/stop(?:\s+(\d+))?$/.exec(prompt);if(stopMatch){const res=await api.update(itemId,{status:"completed"},config.runId);if(res.status===409){log.log(" \u26A0\uFE0F /stop \u30A2\u30A4\u30C6\u30E0\u306F\u65E2\u306B\u5225\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08409\uFF09\u3002\u3053\u3061\u3089\u3067\u306F\u8A18\u9332\u3057\u307E\u305B\u3093")}else if(!res.
|
|
260
|
+
ok){log.log(` \u26D4 /stop \u30A2\u30A4\u30C6\u30E0\u3092 completed \u306B\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${describeError(res)}\uFF09`);log.log(" \u3053\u306E\u30A2\u30A4\u30C6\u30E0\u306F\u56DE\u53CE\u5F8C\u306B pending \u3078\u623B\u308B\u305F\u3081\u3001**\u6B21\u56DE\u8D77\u52D5\u6642\u3082\u5373\u505C\u6B62\u3057\u307E\u3059**");log.log(` \u5FA9\u65E7: UI \u304BAPI\u3067 item=${itemId} \u3092 completed / failed \u306B\u3057\u3066\u304F\u3060\u3055\u3044`)}completed+=
|
|
261
|
+
1;const waitSec=stopMatch[1];if(waitSec){const requested=Number.parseInt(waitSec,10);const capped=Math.min(requested,STOP_WAIT_MAX_SEC);if(capped!==requested){log.log(` \u26A0\uFE0F /stop \u306E\u5F85\u6A5F ${requested}\u79D2 \u306F\u4E0A\u9650 ${STOP_WAIT_MAX_SEC}\u79D2 \u306B\u4E38\u3081\u307E\u3059`)}log.log(`[${stepNum}] /stop ${capped} \u2192 ${capped}\u79D2\u9593\u5F85\u6A5F\u3057\u307E\u3059...`);await this.sleepUnlessDraining(capped*1e3);log.log(`[${stepNum}] \u5F85\u6A5F\u5B8C\u4E86\u3002\u6B21\u306E\u30A2\u30A4\u30C6\u30E0\u306B\u9032\u307F\u307E\u3059\u3002`);
|
|
262
|
+
continue}log.log(`[${stepNum}] /stop \u2192 \u30EB\u30FC\u30D7\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002`);stop=true;break}const skillName=/\/twp-([a-z][a-z0-9-]*)/.exec(prompt)?.[1]??"";const promptPlaceholder=placeholderTaskKey(prompt.replace(/^\/twp-[a-z0-9-]*\s*/,""));if(promptPlaceholder!==null){const reason=`\u30BF\u30B9\u30AF\u30AD\u30FC\u304C\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u306E\u307E\u307E\u3067\u3059\uFF08'${promptPlaceholder}'\uFF09\u3002\u8A08\u753B\u6642\u306E\u96DB\u5F62\u304C\u7F6E\u63DB\u3055\u308C\u3066\u3044\u307E\u305B\u3093`;
|
|
263
|
+
log.log(` \u26D4 \u5B9F\u884C\u3057\u307E\u305B\u3093: ${reason}`);const res=await api.update(itemId,{status:"failed",error_message:reason},config.runId);if(res.status===409){log.log(` \u26A0\uFE0F \u65E2\u306B\u5225\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08409\uFF09\u3002\u3053\u3061\u3089\u3067\u306F\u8A18\u9332\u3057\u307E\u305B\u3093: item=${itemId}`)}else if(!res.ok){log.log(` \u26A0\uFE0F failed \u306B\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${describeError(
|
|
264
|
+
res)}\uFF09: item=${itemId}`)}else{log.log(`[${stepNum}] ${label} \u2192 \u5931\u6557 [ai=-] (0s)`);await this.schedule.recordByItem(itemId,"failed")}failed+=1;continue}if(skillName){const gate=await this.schedule.gateAllows(skillName);if(!gate.allowed){stepNum-=1;if(this.deferredIds.has(itemId)){log.log(" \u6642\u9593\u5E2F\u30B2\u30FC\u30C8\u3067\u5F85\u6A5F\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u304C\u518D\u3073\u30C7\u30AD\u30E5\u30FC\u3055\u308C\u307E\u3057\u305F\u3002\u3053\u306E\u30B5\u30A4\u30AF\u30EB\u306EPhase 2\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002");
|
|
265
|
+
break}const res=await api.update(itemId,{status:"pending"},config.runId);if(res.status===409){log.log(` \u26A0\uFE0F \u5F8C\u56DE\u3057\u306B\u3057\u3088\u3046\u3068\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u306F\u65E2\u306B\u5225\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08409\uFF09: item=${itemId}`);log.log(" \u81EA\u5206\u306E claim \u306F\u5931\u52B9\u3057\u3066\u3044\u307E\u3059\u3002**\u3053\u306E\u30A2\u30A4\u30C6\u30E0\u306F\u5B9F\u884C\u305B\u305A\u653E\u68C4\u3057\u307E\u3059**");
|
|
266
|
+
continue}if(res.ok){this.deferredIds.add(itemId);log.log(` \u23F8 \u6642\u9593\u5E2F\u30B2\u30FC\u30C8\u306B\u3088\u308A\u5F8C\u56DE\u3057: ${skillName} \u2014 ${gate.reason}`);continue}log.log(" \u26A0\uFE0F pending\u3078\u623B\u305B\u306A\u304B\u3063\u305F\u305F\u3081\u3001\u6642\u9593\u5E2F\u30B2\u30FC\u30C8\u3092\u7121\u8996\u3057\u3066\u3053\u306E\u307E\u307E\u5B9F\u884C\u3057\u307E\u3059");stepNum+=1}}const stepLog=path5.join(config.logDir,`step-${this.timestamp}-${cycle}-${stepNum}.lo\
|
|
267
|
+
g`);const startedAt=Date.now();const taggedCategory=/#ai:([a-z]+)/.exec(label)?.[1];this.itemInFlight=itemId;const resolvedSkills=await this.skills.resolve(prompt);const skillOrigins=formatSkillOrigins(resolvedSkills.origins);if(skillOrigins!=="")log.log(` \u30B9\u30AD\u30EB: ${skillOrigins}`);const ownershipWatch=this.startOwnershipWatch(itemId);let result;try{result=await this.engine.run({serverSkills:resolvedSkills.bodies,prompt:buildStepPrompt(config,prompt),promptPrefix:this.cyclePreflightSection,
|
|
268
|
+
logFile:stepLog,aiType:item.ai_type??void 0,aiModel:item.ai_model??void 0,aiEffort:item.ai_effort??void 0,timeoutSec:config.aiTimeoutSec,cwd:config.workspace,skill:skillName,...skillName===""&&taggedCategory!==void 0?{category:taggedCategory}:{}})}finally{ownershipWatch.stop();this.itemInFlight=null}writeLogFile(stepLog,skillOrigins===""?result.output:`[skill] ${skillOrigins}
|
|
267
269
|
${result.output}`);const durationSec=Math.trunc((Date.now()-startedAt)/1e3);if(this.ownershipLostItemId===itemId){this.ownershipLostItemId=null;log.log(`[${stepNum}] ${label} \u2192 \u26A0\uFE0F \u6240\u6709\u6A29\u3092\u5931\u3063\u3066\u3044\u305F\u305F\u3081\u7D50\u679C\u3092\u7834\u68C4\u3057\u307E\u3057\u305F [ai=${result.usedAi||"-"}] (${durationSec}s)`);log.log(" \u3053\u306E\u30A2\u30A4\u30C6\u30E0\u306E\u5F8C\u51E6\u7406\uFF08\u5B9A\u671F\u67A0\u306E\u8A18\u9332\u30FB\u30EA\u30EA\u30FC\u30B9\u7D50\u679C\u306E\u8A18\u9332\u30FB\u5F8C\u7D9A\u6295\u5165\uFF09\u306F\u884C\u3044\u307E\u305B\u3093");
|
|
268
270
|
this.abortDrained?.();this.abortDrained=null;continue dequeue}if(result.outcome==="aborted"){log.log(`[${stepNum}] ${label} \u2192 \u4E2D\u65AD [ai=${result.usedAi||"-"}] (${durationSec}s)`);const res=await api.update(itemId,{status:"pending",result:truncateResult(result.output),error_message:"aborted: \u4E2D\u65AD\u30B7\u30B0\u30CA\u30EB\u306B\u3088\u308A AI \u3092\u505C\u6B62\u3057\u307E\u3057\u305F\uFF08\u4F5C\u696D\u306F\u9014\u4E2D\u306E\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\uFF09"},
|
|
269
271
|
config.runId);if(res.status===409){log.log(` \u26A0\uFE0F \u30AD\u30E5\u30FC\u3078\u8FD4\u305D\u3046\u3068\u3057\u305F\u30A2\u30A4\u30C6\u30E0\u306F\u65E2\u306B\u5225\u306E\u30E9\u30F3\u30CA\u30FC\u304C\u4FDD\u6301\u3057\u3066\u3044\u307E\u3059\uFF08409\uFF09: item=${itemId}`)}else if(res.ok){log.log(" \u2192 \u30A2\u30A4\u30C6\u30E0\u3092 pending \u306B\u623B\u3057\u307E\u3057\u305F\uFF08\u6B21\u306E\u8D77\u52D5\u3067\u62FE\u3044\u76F4\u3057\u307E\u3059\uFF09")}else{log.log(` \u26A0\uFE0F pending \u3078\u623B\
|
|
@@ -288,8 +290,8 @@ this.postDeps,contract);return}const followUpOnCut=this.deps.config.operations.p
|
|
|
288
290
|
"object")return{kind:"claimed",item};log.log(` \u26A0\uFE0F claim \u304C claimed \u3092\u8FD4\u3057\u307E\u3057\u305F\u304C item \u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u5FDC\u7B54\u306E\u5148\u982D: ${res.raw.slice(0,120)}\uFF09`);return{kind:"undetermined"}}if(reason==="empty")return{kind:"empty"};if(reason==="filtered"){const by=res.json?.filtered_by;return{kind:"filtered",by:Array.isArray(by)?by.filter(b=>typeof b==="string"):[]}}if(reason!=="runner_not_registered"){log.log(` \u26A0\uFE0F claim\
|
|
289
291
|
\u306E\u5FDC\u7B54\u3092\u89E3\u91C8\u3067\u304D\u307E\u305B\u3093\uFF08reason='${reason}'\uFF09\u3002`);log.log(` **\u30AD\u30E5\u30FC\u304C\u7A7A\u304B\u3069\u3046\u304B\u306F\u5224\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002** \u5FDC\u7B54\u306E\u5148\u982D: ${res.raw.slice(0,120)}`);return{kind:"undetermined"}}}attempt+=1;if(res.status===409||pickString(res.json,"reason")==="runner_not_registered"){log.log(" \u26A0\uFE0F claim \u304C 409\uFF08\u30E9\u30F3\u30CA\u30FC\u672A\u767B\u9332\u6271\u3044\uFF09\u3002register \u304B\u3089\u3084\u308A\u76F4\u3057\u307E\u3059");
|
|
290
292
|
runner.registered=false;try{await runner.registerOrThrow()}catch{return{kind:"undetermined"}}if(attempt>=3)return{kind:"undetermined"};continue}if(attempt>=3){log.log(` \u26A0\uFE0F claim API\u304C3\u56DE\u9023\u7D9A\u3067\u5931\u6557\uFF08${describeError(res)}\uFF09\u3002`);log.log(" **\u30AD\u30E5\u30FC\u304C\u7A7A\u304B\u3069\u3046\u304B\u306F\u5224\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002** \u672A\u51E6\u7406\u306E\u30A2\u30A4\u30C6\u30E0\u304C\u6B8B\u3063\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002");
|
|
291
|
-
return{kind:"undetermined"}}log.log(` \u26A0\uFE0F claim API\u304C\u5FDC\u7B54\u3057\u307E\u305B\u3093\uFF08${describeError(res)}\uFF09\u3002${attempt}\u56DE\u76EE\u30FB5\u79D2\u5F8C\u306B\u518D\u8A66\u884C`);await this.sleep(5e3)}}};function writeLogFile(file,text){try{fs7.mkdirSync(path5.dirname(file),{recursive:true});fs7.writeFileSync(file,text)}catch{}}function buildPlanPrompt(config,scheduleSection,prefetchSection){return[promptText(config,"plan_preamble",""),config.safeMode?promptText(
|
|
292
|
-
"safe_mode_note",SAFE_MODE_NOTE):"",promptText(config,"non_interactive_note",NON_INTERACTIVE_NOTE),scheduleSection,prefetchSection,
|
|
293
|
+
return{kind:"undetermined"}}log.log(` \u26A0\uFE0F claim API\u304C\u5FDC\u7B54\u3057\u307E\u305B\u3093\uFF08${describeError(res)}\uFF09\u3002${attempt}\u56DE\u76EE\u30FB5\u79D2\u5F8C\u306B\u518D\u8A66\u884C`);await this.sleep(5e3)}}};function writeLogFile(file,text){try{fs7.mkdirSync(path5.dirname(file),{recursive:true});fs7.writeFileSync(file,text)}catch{}}function buildPlanPrompt(config,planSkill,scheduleSection,prefetchSection){return[promptText(config,"plan_preamble",""),config.safeMode?promptText(
|
|
294
|
+
config,"safe_mode_note",SAFE_MODE_NOTE):"",promptText(config,"non_interactive_note",NON_INTERACTIVE_NOTE),scheduleSection,prefetchSection,planSkill].filter(s=>s!=="").join("\n\n")}function promptText(config,key,builtin){return config.serverPrompts?.[key]??builtin}function buildStepPrompt(config,body){const timeoutMin=Math.trunc(config.aiTimeoutSec/60);const softMin=Math.trunc(config.aiTimeoutSec*config.aiSoftDeadlineRatio/100/60);const wrapUpMin=Math.max(0,timeoutMin-softMin);return[renderStepBudget(
|
|
293
295
|
promptText(config,"step_budget",STEP_BUDGET),{timeoutMin,softMin,wrapUpMin}),config.safeMode?promptText(config,"safe_mode_note",SAFE_MODE_NOTE):"",promptText(config,"non_interactive_note",NON_INTERACTIVE_NOTE),body].filter(s=>s!=="").join("\n\n")}var STEP_BUDGET=["\u3010\u5B9F\u884C\u6642\u9593\u306E\u4E88\u7B97\u3011\u3053\u306E\u5B9F\u884C\u306F {timeout_min}\u5206 \u3067\u30D7\u30ED\u30BB\u30B9\u304C\u5F37\u5236\u7D42\u4E86\u3055\u308C\u307E\u3059\u3002\u4E88\u544A\u3084\u7336\u4E88\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
|
|
294
296
|
["- \u958B\u59CB\u304B\u3089 **{soft_min}\u5206** \u3092\u904E\u304E\u305F\u3089\u3001\u4F5C\u696D\u3092\u6253\u3061\u5207\u3063\u3066\u7DE0\u3081\u51E6\u7406\u306B\u5165\u3063\u3066\u304F\u3060\u3055\u3044\uFF08\u30B3\u30DF\u30C3\u30C8 \u2192 push \u2192 PR\u4F5C\u6210 \u2192 \u30BF\u30B9\u30AF\u306E\u30B9\u30C6\u30FC\u30BF\u30B9\u30FB\u62C5\u5F53\u306E\u66F4\u65B0 \u2192 \u5F15\u304D\u7D99\u304E\u30B3\u30E1\u30F3\u30C8\uFF09","- \u7DE0\u3081\u51E6\u7406\u306B\u306F10\u5206\u7A0B\u5EA6\u3092\u898B\u8FBC\u3093\u3067\u304F\u3060\u3055\u3044\uFF08{soft_min}\u5206\u6642\u70B9\u3067\u306E\u6B8B\u308A\u306F {wrap_up_min}\u5206\uFF09",
|
|
295
297
|
"- **\u7D4C\u904E\u6642\u9593\u306F `date` \u3067\u5B9F\u6E2C\u3057\u3066\u304F\u3060\u3055\u3044\u3002** \u4F53\u611F\u3067\u300C\u4E88\u7B97\u304C\u5C3D\u304D\u304B\u3051\u3066\u3044\u308B\u300D\u3068\u5224\u65AD\u3057\u306A\u3044\u3053\u3068\u2014\u2014\u5B9F\u6E2C\u305B\u305A\u306B\u65E9\u671F\u96E2\u8131\u3059\u308B\u3068\u3001\u6B8B\u308A\u6642\u9593\u304C\u3042\u308B\u306E\u306B\u5DE5\u7A0B\u304C\u9014\u4E2D\u3067\u6B62\u307E\u308A\u307E\u3059\uFF08\u5B9F\u6E2C\u305B\u305A\u306B\u8FF0\u3079\u305F\u6B8B\u308A\u6642\u9593\u306F\u61B2\u7AE0A3\u9055\u53CD\uFF09",
|
|
@@ -321,13 +323,13 @@ operations.preflightHosts;return new DispatchEngine(config.ai,log,{workspace:con
|
|
|
321
323
|
claudeLauncher.bin,...extraHosts.length>0?{preflightHosts:[...DEFAULT_PREFLIGHT_HOSTS,...extraHosts]}:{}})}function lockDir(config){return path8.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-SIL2ELR4.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}:{}})}if(opts.action==="charter"){if(opts.charterOp===void 0){process.stderr.
|
|
326
328
|
write("charter \u306B\u306F push \u304B pull \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\n");return 2}if(isPrivateProjectId(projectId)){process.stderr.write("\u500B\u4EBA\u30BF\u30B9\u30AF\u306E\u30AD\u30E5\u30FC\uFF08--project __private__\uFF09\u306B\u306F\u61B2\u7AE0\u306E\u8A2D\u5B9A\u304C\u3042\u308A\u307E\u305B\u3093\n");return 2}const{runCharterCommand}=await import("./charter-command-LIX2JXRJ.js");return runCharterCommand({api:new AgentLoopApi({apiUrl,projectId,session})},{op:opts.
|
|
327
329
|
charterOp,file:opts.charterInput,out:opts.charterOutput,revision:opts.charterRevision,yes:opts.yes===true,projectRef,profile:opts.profile})}if(opts.action==="skill"){if(opts.skillOp===void 0){process.stderr.write("skill \u306B\u306F push \u304B pull \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\n");return 2}if(isPrivateProjectId(projectId)){process.stderr.write("\u500B\u4EBA\u30BF\u30B9\u30AF\u306E\u30AD\u30E5\u30FC\uFF08--project __private__\uFF09\u306B\u306F\u30B9\u30AD\u30EB\u5B9A\u7FA9\u306E\u8A2D\u5B9A\u304C\u3042\u308A\u307E\u305B\u3093\n");
|
|
328
330
|
return 2}const{runSkillCommand}=await import("./skill-command-NXHTJXYY.js");return runSkillCommand({api:new AgentLoopApi({apiUrl,projectId,session})},{op:opts.skillOp,name:opts.skillName,all:opts.skillAll===true,dir:opts.skillDir,revision:opts.charterRevision,yes:opts.yes===true,projectRef,profile:opts.profile})}const config=buildLoopConfig({projectId,projectRef,apiUrl,safeMode:opts.safe,daemon:opts.daemon,...opts.maxCycles!==void 0?{maxCycles:opts.maxCycles}:{},...opts.interval!==void 0?{intervalSec:opts.
|
|
329
331
|
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}
|
|
330
|
-
`)}if(opts.action==="status")return showStatus(api,config);if(opts.action==="schedule"){const{runScheduleCommand}=await import("./schedule-command-
|
|
332
|
+
`)}if(opts.action==="status")return showStatus(api,config);if(opts.action==="schedule"){const{runScheduleCommand}=await import("./schedule-command-ONHLWUW6.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}
|
|
331
333
|
`);return 2}try{assertKnownEngine(config.engine)}catch(err){if(err instanceof UnknownEngineError){process.stderr.write(`${err.message}
|
|
332
334
|
`);return 2}throw err}fs10.mkdirSync(config.logDir,{recursive:true,mode:448});rotateLogs(config.logDir,config.logRetentionDays);const logFile=path8.join(config.logDir,`agent-loop-${compactTimestamp()}.log`);const log=new LoopLogger(config.runnerId,logFile);for(const warning of config.warnings)log.log(`\u26A0\uFE0F ${warning}`);const lock=new InstanceLock(lockDir(config));const acquired=lock.acquire();if(!acquired.acquired){log.log(`\u274C ${acquired.reason}`);log.log(" \u610F\u56F3\u7684\u306B2\u30D7\u30ED\u30BB\u30B9\u52D5\u304B\u3059\u691C\u8A3C\u3067\u306F TWP_OP\
|
|
333
335
|
S_STATE_DIR \u3068 RUNNER_ID \u3092\u5206\u3051\u3066\u304F\u3060\u3055\u3044");log.close();return 1}if(acquired.note)log.log(` \u2139\uFE0F ${acquired.note}`);const ownerError=writeLockOwner(lockDir(config),buildLockOwner({pid:process.pid,profile:profile.name,twpHome:twpHomeDir(),projectRef:config.projectRef,projectId:config.projectId}));if(ownerError!==null){log.log(` \u26A0\uFE0F \u30ED\u30C3\u30AF\u306B\u6240\u6709\u8005\u306E\u8A18\u9332\u3092\u66F8\u3051\u307E\u305B\u3093\u3067\u3057\u305F\uFF08${ownerError}\
|
|
@@ -342,7 +344,7 @@ let driftWatcher=null;const pendingDrain={value:null};const shutdown=async()=>{i
|
|
|
342
344
|
then(()=>process.exit(130))};process.once("SIGINT",onSignal);process.once("SIGTERM",onSignal);process.once("SIGHUP",onSignal);stopWatcher=watchMarker(lockDir(config),"stop",process.pid,req=>{log.log(`\u505C\u6B62\u8981\u6C42\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\uFF08${req.at||"\u6642\u523B\u4E0D\u660E"}\uFF09\u3002\u7D42\u4E86\u3057\u307E\u3059...`);stopWatcher?.();drainWatcher?.();driftWatcher?.();void shutdown().catch(()=>void 0).then(()=>process.exit(130))});drainWatcher=watchMarker(
|
|
343
345
|
lockDir(config),"drain",process.pid,req=>{drainWatcher?.();if(loop===null){pendingDrain.value={reason:`stop --drain\u30FB${req.at||"\u6642\u523B\u4E0D\u660E"}`,exitCode:0};log.log(`\u30C9\u30EC\u30A4\u30F3\u8981\u6C42\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\uFF08${req.at||"\u6642\u523B\u4E0D\u660E"}\uFF09\u3002\u8D77\u52D5\u51E6\u7406\u306E\u5B8C\u4E86\u5F8C\u306B\u53CD\u6620\u3057\u307E\u3059\u3002`);return}loop.requestDrain(`stop --drain\u30FB${req.at||"\u6642\u523B\u4E0D\u660E"}`)});if(installed!==
|
|
344
346
|
null){const watch=watchVersionDrift({runningVersion:opts.version,stateDir:config.stateDir,projectKey:projectFileKey(config.projectId),supervised:autoRestart.supervised,disabled:autoRestart.disabled},{onWarn:reason=>log.log(`\u26A0\uFE0F ${reason}`),onRestart:({from,to})=>{driftWatcher?.();log.log(`\u7248\u30C9\u30EA\u30D5\u30C8\u3092\u691C\u51FA\u3057\u307E\u3057\u305F\uFF08${from} \u2192 ${to}\uFF09\u3002`);log.log(` \u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u3092\u5B8C\u8D70\u3055\u305B\u3066\u304B\u3089\u7D42\u4E86\u3057\u307E\u3059\uFF08\u7D42\u4E86\u30B3\u30FC\u30C9 ${EXIT_VERSION_DRIFT}\
|
|
345
|
-
\uFF09\u3002\u518D\u8D77\u52D5\u306F systemd\uFF08Restart=always\uFF09\u304C\u884C\u3044\u307E\u3059`);const reason=`\u7248\u30C9\u30EA\u30D5\u30C8 ${from} \u2192 ${to} \u306B\u3088\u308B\u81EA\u52D5\u518D\u8D77\u52D5`;if(loop===null)pendingDrain.value={reason,exitCode:EXIT_VERSION_DRIFT};else loop.requestDrain(reason,EXIT_VERSION_DRIFT)}});driftWatcher=watch.stop}try{const{LoopSettingsApplier:LoopSettingsApplier2}=await import("./server-settings-
|
|
347
|
+
\uFF09\u3002\u518D\u8D77\u52D5\u306F systemd\uFF08Restart=always\uFF09\u304C\u884C\u3044\u307E\u3059`);const reason=`\u7248\u30C9\u30EA\u30D5\u30C8 ${from} \u2192 ${to} \u306B\u3088\u308B\u81EA\u52D5\u518D\u8D77\u52D5`;if(loop===null)pendingDrain.value={reason,exitCode:EXIT_VERSION_DRIFT};else loop.requestDrain(reason,EXIT_VERSION_DRIFT)}});driftWatcher=watch.stop}try{const{LoopSettingsApplier:LoopSettingsApplier2}=await import("./server-settings-6NHVHMPS.js");const settings=new LoopSettingsApplier2(
|
|
346
348
|
{api,config,log:m=>log.log(m)});await settings.apply();const{ServerSkillCatalog:ServerSkillCatalog2}=await import("./server-skills-IXIOOOC2.js");const skills=new ServerSkillCatalog2({api,config,log:m=>log.log(m)});await skills.refresh();await runner.checkHeartbeatInterval();await runner.registerOrThrow();runner.startHeartbeatWorker();log.log(` heartbeat: ${config.heartbeatIntervalSec}\u79D2\u3054\u3068\u306B\u9001\u4FE1${runner.heartbeatTimeoutServer?`\uFF08\u30B5\u30FC\u30D0\u306E\u6B7B\u6D3B\u3057\u304D\u3044\u5024 ${runner.
|
|
347
349
|
heartbeatTimeoutServer}\u79D2\uFF09`:""}`);loop=new TaskLoop({api,projectApi,config,log,runner,engine:await buildEngine(config,m=>log.log(m)),settings,skills});if(pendingDrain.value!==null){loop.requestDrain(pendingDrain.value.reason,pendingDrain.value.exitCode)}exitCode=await loop.run()}catch(err){if(err instanceof RunnerRegistrationError){exitCode=1}else{log.log(`\u26D4 \u4E88\u671F\u3057\u306A\u3044\u30A8\u30E9\u30FC\u3067\u7D42\u4E86\u3057\u307E\u3059: ${err.message}`);exitCode=1}}finally{await shutdown()}
|
|
348
350
|
return exitCode}async function showStatus(api,config){const out={write:text=>process.stdout.write(stripTerminalControls(text))};out.write(`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8: ${config.projectRef}\uFF08${config.projectId}\uFF09
|