@exaudeus/workrail 3.79.3 → 3.81.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/dist/cli/commands/worktrain-diagnose.d.ts +114 -0
- package/dist/cli/commands/worktrain-diagnose.js +628 -0
- package/dist/cli-worktrain.js +85 -7
- package/dist/console-ui/assets/{index-pA7_pNwu.js → index-BgMh_c_3.js} +1 -1
- package/dist/console-ui/index.html +1 -1
- package/dist/daemon/active-sessions.d.ts +8 -5
- package/dist/daemon/active-sessions.js +11 -2
- package/dist/daemon/core/session-result.d.ts +2 -2
- package/dist/daemon/daemon-events.d.ts +17 -13
- package/dist/daemon/daemon-events.js +4 -0
- package/dist/daemon/runner/agent-loop-runner.d.ts +4 -4
- package/dist/daemon/runner/pre-agent-session.d.ts +2 -2
- package/dist/daemon/runner/pre-agent-session.js +2 -1
- package/dist/daemon/runner/runner-types.d.ts +4 -4
- package/dist/daemon/session-scope.d.ts +2 -2
- package/dist/daemon/startup-recovery.js +2 -1
- package/dist/daemon/tools/bash.d.ts +2 -2
- package/dist/daemon/tools/continue-workflow.d.ts +3 -3
- package/dist/daemon/tools/file-tools.d.ts +4 -4
- package/dist/daemon/tools/glob-grep.d.ts +3 -3
- package/dist/daemon/tools/report-issue.d.ts +2 -2
- package/dist/daemon/tools/signal-coordinator.d.ts +2 -2
- package/dist/daemon/tools/spawn-agent.d.ts +2 -2
- package/dist/daemon/types.d.ts +4 -2
- package/dist/daemon/workflow-runner.js +2 -1
- package/dist/manifest.json +55 -47
- package/docs/ideas/backlog.md +55 -491
- package/package.json +1 -1
package/dist/cli-worktrain.js
CHANGED
|
@@ -52,6 +52,7 @@ const index_js_1 = require("./context-assembly/index.js");
|
|
|
52
52
|
const infra_js_1 = require("./context-assembly/infra.js");
|
|
53
53
|
const index_js_2 = require("./cli/commands/index.js");
|
|
54
54
|
const stats_summary_js_1 = require("./daemon/stats-summary.js");
|
|
55
|
+
const worktrain_diagnose_js_1 = require("./cli/commands/worktrain-diagnose.js");
|
|
55
56
|
const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
|
|
56
57
|
const program = new commander_1.Command();
|
|
57
58
|
program
|
|
@@ -362,11 +363,11 @@ program
|
|
|
362
363
|
const shutdown = async () => {
|
|
363
364
|
console.log('\nShutting down daemon...');
|
|
364
365
|
clearInterval(heartbeatInterval);
|
|
365
|
-
for (const
|
|
366
|
+
for (const sh of handle.activeSessionSet.handles()) {
|
|
366
367
|
emitter.emit({
|
|
367
368
|
kind: 'session_aborted',
|
|
368
|
-
sessionId:
|
|
369
|
-
workrailSessionId,
|
|
369
|
+
sessionId: sh.sessionId,
|
|
370
|
+
...(sh.workrailSessionId !== null ? { workrailSessionId: sh.workrailSessionId } : {}),
|
|
370
371
|
reason: 'daemon_shutdown',
|
|
371
372
|
ts: Date.now(),
|
|
372
373
|
});
|
|
@@ -744,6 +745,31 @@ program
|
|
|
744
745
|
}
|
|
745
746
|
}
|
|
746
747
|
});
|
|
748
|
+
program
|
|
749
|
+
.command('diagnose <sessionId>')
|
|
750
|
+
.description('Print a failure card for a daemon session. Searches the last 7 days of daemon event logs. ' +
|
|
751
|
+
'Works without the daemon running. Accepts sessionId (UUID prefix) or workrailSessionId (sess_xxx).')
|
|
752
|
+
.option('--json', 'Output machine-readable JSON (full untruncated fields)')
|
|
753
|
+
.option('--ascii', 'Use ASCII-only output (no Unicode glyphs)')
|
|
754
|
+
.action((sessionId, options) => {
|
|
755
|
+
const eventsDir = path_1.default.join(os_1.default.homedir(), '.workrail', 'events', 'daemon');
|
|
756
|
+
const readFile = (filePath) => {
|
|
757
|
+
try {
|
|
758
|
+
return fs_1.default.readFileSync(filePath, 'utf8');
|
|
759
|
+
}
|
|
760
|
+
catch {
|
|
761
|
+
return null;
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
const result = (0, worktrain_diagnose_js_1.parseDaemonEvents)(sessionId, eventsDir, 7, readFile);
|
|
765
|
+
if (options.json) {
|
|
766
|
+
process.stdout.write((0, worktrain_diagnose_js_1.formatDiagnosticJson)(result) + '\n');
|
|
767
|
+
}
|
|
768
|
+
else {
|
|
769
|
+
const card = (0, worktrain_diagnose_js_1.formatDiagnosticCard)(result, { ascii: options.ascii ?? false });
|
|
770
|
+
process.stdout.write(card + '\n');
|
|
771
|
+
}
|
|
772
|
+
});
|
|
747
773
|
program
|
|
748
774
|
.command('health <sessionId>')
|
|
749
775
|
.description('Print a health summary for a daemon session. Accepts sessionId (UUID prefix) or workrailSessionId (sess_xxx).')
|
|
@@ -760,7 +786,34 @@ program
|
|
|
760
786
|
raw = fs_1.default.readFileSync(filePath, 'utf8');
|
|
761
787
|
}
|
|
762
788
|
catch {
|
|
763
|
-
|
|
789
|
+
raw = '';
|
|
790
|
+
}
|
|
791
|
+
const sessionInTodayLog = raw.split('\n').some((line) => {
|
|
792
|
+
if (!line.trim())
|
|
793
|
+
return false;
|
|
794
|
+
try {
|
|
795
|
+
const obj = JSON.parse(line);
|
|
796
|
+
const sid = typeof obj['sessionId'] === 'string' ? obj['sessionId'] : '';
|
|
797
|
+
const wrid = typeof obj['workrailSessionId'] === 'string' ? obj['workrailSessionId'] : '';
|
|
798
|
+
return sid.startsWith(sessionId) || sid === sessionId ||
|
|
799
|
+
wrid.startsWith(sessionId) || wrid === sessionId;
|
|
800
|
+
}
|
|
801
|
+
catch {
|
|
802
|
+
return false;
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
if (!sessionInTodayLog) {
|
|
806
|
+
const readFile = (fp) => {
|
|
807
|
+
try {
|
|
808
|
+
return fs_1.default.readFileSync(fp, 'utf8');
|
|
809
|
+
}
|
|
810
|
+
catch {
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
const result = (0, worktrain_diagnose_js_1.parseDaemonEvents)(sessionId, eventsDir, 7, readFile);
|
|
815
|
+
const card = (0, worktrain_diagnose_js_1.formatDiagnosticCard)(result);
|
|
816
|
+
process.stdout.write(card + '\n');
|
|
764
817
|
return;
|
|
765
818
|
}
|
|
766
819
|
runHealthSummary(sessionId, raw);
|
|
@@ -782,15 +835,40 @@ program
|
|
|
782
835
|
const eventsDir = path_1.default.join(os_1.default.homedir(), '.workrail', 'events', 'daemon');
|
|
783
836
|
const date = new Date().toISOString().slice(0, 10);
|
|
784
837
|
const filePath = path_1.default.join(eventsDir, `${date}.jsonl`);
|
|
785
|
-
let raw;
|
|
838
|
+
let raw = '';
|
|
786
839
|
try {
|
|
787
840
|
raw = fs_1.default.readFileSync(filePath, 'utf8');
|
|
788
841
|
}
|
|
789
842
|
catch {
|
|
790
|
-
process.stdout.write(`No events today. Is the daemon running? (Expected: ${filePath})\n`);
|
|
791
|
-
return;
|
|
792
843
|
}
|
|
793
844
|
process.stderr.write(`\nNote: This is the old \`worktrain status <id>\` output. Use \`worktrain health <id>\` instead.\n\n`);
|
|
845
|
+
const sessionInTodayLog = raw.split('\n').some((line) => {
|
|
846
|
+
if (!line.trim())
|
|
847
|
+
return false;
|
|
848
|
+
try {
|
|
849
|
+
const obj = JSON.parse(line);
|
|
850
|
+
const sid = typeof obj['sessionId'] === 'string' ? obj['sessionId'] : '';
|
|
851
|
+
const wrid = typeof obj['workrailSessionId'] === 'string' ? obj['workrailSessionId'] : '';
|
|
852
|
+
return sid.startsWith(sessionId) || sid === sessionId ||
|
|
853
|
+
wrid.startsWith(sessionId) || wrid === sessionId;
|
|
854
|
+
}
|
|
855
|
+
catch {
|
|
856
|
+
return false;
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
if (!sessionInTodayLog) {
|
|
860
|
+
const readFile = (fp) => {
|
|
861
|
+
try {
|
|
862
|
+
return fs_1.default.readFileSync(fp, 'utf8');
|
|
863
|
+
}
|
|
864
|
+
catch {
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
const result = (0, worktrain_diagnose_js_1.parseDaemonEvents)(sessionId, eventsDir, 7, readFile);
|
|
869
|
+
process.stdout.write((0, worktrain_diagnose_js_1.formatDiagnosticCard)(result) + '\n');
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
794
872
|
runHealthSummary(sessionId, raw);
|
|
795
873
|
return;
|
|
796
874
|
}
|