taskforce-loop-engineering 0.15.0 → 0.15.1
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.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.15.1 - 2026-08-20
|
|
6
|
+
|
|
7
|
+
- Keep generated OpenClaw and Hermes scheduler services healthy when asynchronous human or terminal notification delivery fails, while preserving notification logging and retries.
|
|
8
|
+
|
|
5
9
|
## 0.15.0 - 2026-08-20
|
|
6
10
|
|
|
7
11
|
- Reconcile project-scoped human gates against the authoritative project contract and acceptance ledger, superseding stale or optional deferred gates without replay.
|
package/package.json
CHANGED
|
@@ -33,6 +33,7 @@ const install = await run(process.execPath, [installer, ...base, '--confirm-inst
|
|
|
33
33
|
const queue = JSON.parse(await readFile(path.join(root, 'configs/loops/queues/hermes-tasks.json'), 'utf8')); if (queue.dispatcher !== 'node scripts/loops/hermes-loop-dispatch.mjs' || queue.scheduler?.required !== true) throw new Error('Hermes queue wiring missing');
|
|
34
34
|
const instructions = await readFile(path.join(root, 'AGENTS.md'), 'utf8'); if (!instructions.includes('Use Loop Engineering to fix this issue') || !instructions.includes('Queue this only; do not run it yet') || /走 loop|只入队|只排队/.test(instructions)) throw new Error('Hermes English conversation instructions are missing or contain Chinese routing examples');
|
|
35
35
|
const wrapper = await readFile(path.join(root, 'scripts/loops/hermes-loop.mjs'), 'utf8'); if (!wrapper.includes('queue') || !wrapper.includes('continue') || /只入队|只排队|继续当前/.test(wrapper)) throw new Error('Hermes English wrapper routing was not fully localized');
|
|
36
|
+
if (!wrapper.includes('process.exitCode = tickCode;') || wrapper.includes('process.exitCode = tickCode || humanCode || terminalCode;')) throw new Error('Hermes scheduler health still depends on notification delivery');
|
|
36
37
|
const dispatcher = await readFile(path.join(root, 'scripts/loops/hermes-loop-dispatch.mjs'), 'utf8'); if (!dispatcher.includes("'-z', prompt")) throw new Error('Hermes one-shot dispatcher missing');
|
|
37
38
|
const notifier = path.join(root, 'scripts/loops/hermes-loop-notify.mjs'); const notify = await run(process.execPath, [notifier, 'hello from loop'], { env: { ...process.env, HERMES_SEND_CAPTURE: sendCapture, LOOP_NOTIFICATION_SOURCE: JSON.stringify({ channel: 'telegram', target: 'telegram:12345' }) } }); if (notify.code !== 0) throw new Error(`Hermes notifier failed: ${notify.stderr}`);
|
|
38
39
|
const sent = JSON.parse(await readFile(sendCapture, 'utf8')); if (!sent.includes('telegram:12345') || !sent.includes('hello from loop')) throw new Error('Hermes notifier did not preserve delivery target/message');
|
|
@@ -116,7 +116,7 @@ if (command === 'route') {
|
|
|
116
116
|
const tickCode = await run(['queue-scheduler-tick', '--config', ${JSON.stringify(`configs/loops/queues/${queue}.json`)}, '--progress-notify-command', 'node scripts/loops/hermes-loop-notify.mjs', ...rest]);
|
|
117
117
|
const humanCode = await run(['queue-human-input-notify', '--queue', ${JSON.stringify(queue)}, '--notify-command', 'node scripts/loops/hermes-loop-notify.mjs']);
|
|
118
118
|
const terminalCode = await run(['queue-terminal-notify', '--queue', ${JSON.stringify(queue)}, '--notify-command', 'node scripts/loops/hermes-loop-notify.mjs']);
|
|
119
|
-
process.exitCode = tickCode
|
|
119
|
+
process.exitCode = tickCode;
|
|
120
120
|
} else { console.error(${JSON.stringify(text(language, 'Usage: node scripts/loops/hermes-loop.mjs route|run-once|scheduler-tick', '用法:node scripts/loops/hermes-loop.mjs route|run-once|scheduler-tick'))}); process.exitCode = 1; }
|
|
121
121
|
`;
|
|
122
122
|
}
|
|
@@ -70,6 +70,7 @@ const instructions = await readFile(path.join(root, 'AGENTS.md'), 'utf8');
|
|
|
70
70
|
if (!instructions.includes('Use Loop Engineering to fix this issue') || !instructions.includes('Queue this only; do not run it yet') || /走 loop|只入队|只排队/.test(instructions)) throw new Error('English conversation instructions are missing or contain Chinese routing examples');
|
|
71
71
|
const wrapper = await readFile(path.join(root, 'scripts/loops/openclaw-loop.mjs'), 'utf8');
|
|
72
72
|
if (!wrapper.includes('--supersede-active') || !wrapper.includes('--amend-active') || !wrapper.includes('--progress-notify-command') || !wrapper.includes('runWhenUnlocked') || wrapper.includes("run-queue-drain', '--config'") || wrapper.includes("spawn('loop-engineering'") || !wrapper.includes('queue-human-input-notify') || !wrapper.includes('queue-terminal-notify') || !wrapper.includes('queue-scheduler-tick') || !wrapper.includes('queue') || !wrapper.includes('continue') || /只入队|只排队|继续当前/.test(wrapper) || !wrapper.includes('requiredSource') || !wrapper.includes('--source-message-id')) throw new Error('supersede/amend routing, source fail-closed policy, localization, absolute CLI, scheduler, live progress, async notification, or queue-only routing missing');
|
|
73
|
+
if (!wrapper.includes('process.exitCode = tickCode;') || wrapper.includes('process.exitCode = tickCode || humanNotifyCode || terminalNotifyCode;')) throw new Error('scheduler health still depends on notification delivery');
|
|
73
74
|
const missingSourceRoute = await new Promise((resolve) => {
|
|
74
75
|
const child = spawn(process.execPath, [path.join(root, 'scripts/loops/openclaw-loop.mjs'), 'route', '--message', '用 loop engineering 对齐系统'], { cwd: root, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
75
76
|
let stderr = ''; child.stderr.on('data', (chunk) => { stderr += chunk; });
|
|
@@ -218,7 +218,7 @@ if (command === 'route') {
|
|
|
218
218
|
const tickCode = await run(['queue-scheduler-tick', '--config', ${JSON.stringify(`configs/loops/queues/${queue}.json`)}, '--progress-notify-command', 'node scripts/loops/openclaw-loop-notify.mjs', ...rest]);
|
|
219
219
|
const humanNotifyCode = await run(['queue-human-input-notify', '--queue', ${JSON.stringify(queue)}, '--notify-command', 'node scripts/loops/openclaw-loop-notify.mjs']);
|
|
220
220
|
const terminalNotifyCode = await run(['queue-terminal-notify', '--queue', ${JSON.stringify(queue)}, '--notify-command', 'node scripts/loops/openclaw-loop-notify.mjs']);
|
|
221
|
-
process.exitCode = tickCode
|
|
221
|
+
process.exitCode = tickCode;
|
|
222
222
|
} else {
|
|
223
223
|
console.error(${JSON.stringify(usage)});
|
|
224
224
|
process.exitCode = 1;
|