@zhixuan92/multi-model-agent 5.0.2 → 5.0.3
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/README.md +8 -18
- package/dist/cli/index.d.ts +62 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +345 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/info.d.ts +22 -0
- package/dist/cli/info.d.ts.map +1 -0
- package/dist/cli/info.js +100 -0
- package/dist/cli/info.js.map +1 -0
- package/dist/cli/logs.d.ts +15 -0
- package/dist/cli/logs.d.ts.map +1 -0
- package/dist/cli/logs.js +102 -0
- package/dist/cli/logs.js.map +1 -0
- package/dist/cli/print-token.d.ts +18 -0
- package/dist/cli/print-token.d.ts.map +1 -0
- package/dist/cli/print-token.js +60 -0
- package/dist/cli/print-token.js.map +1 -0
- package/dist/cli/serve.d.ts +28 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +405 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/status.d.ts +49 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +155 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/sync-skills.d.ts +58 -0
- package/dist/cli/sync-skills.d.ts.map +1 -0
- package/dist/cli/sync-skills.js +266 -0
- package/dist/cli/sync-skills.js.map +1 -0
- package/dist/cli/telemetry.d.ts +10 -0
- package/dist/cli/telemetry.d.ts.map +1 -0
- package/dist/cli/telemetry.js +161 -0
- package/dist/cli/telemetry.js.map +1 -0
- package/dist/cli/toggle.d.ts +26 -0
- package/dist/cli/toggle.d.ts.map +1 -0
- package/dist/cli/toggle.js +185 -0
- package/dist/cli/toggle.js.map +1 -0
- package/dist/http/async-dispatch.d.ts +44 -0
- package/dist/http/async-dispatch.d.ts.map +1 -0
- package/dist/http/async-dispatch.js +175 -0
- package/dist/http/async-dispatch.js.map +1 -0
- package/dist/http/auth.d.ts +20 -0
- package/dist/http/auth.d.ts.map +1 -0
- package/dist/http/auth.js +56 -0
- package/dist/http/auth.js.map +1 -0
- package/dist/http/canonicalize-file-paths.d.ts +8 -0
- package/dist/http/canonicalize-file-paths.d.ts.map +1 -0
- package/dist/http/canonicalize-file-paths.js +43 -0
- package/dist/http/canonicalize-file-paths.js.map +1 -0
- package/dist/http/cwd-validator.d.ts +11 -0
- package/dist/http/cwd-validator.d.ts.map +1 -0
- package/dist/http/cwd-validator.js +130 -0
- package/dist/http/cwd-validator.js.map +1 -0
- package/dist/http/errors.d.ts +4 -0
- package/dist/http/errors.d.ts.map +1 -0
- package/dist/http/errors.js +9 -0
- package/dist/http/errors.js.map +1 -0
- package/dist/http/execution-context.d.ts +18 -0
- package/dist/http/execution-context.d.ts.map +1 -0
- package/dist/http/execution-context.js +61 -0
- package/dist/http/execution-context.js.map +1 -0
- package/dist/http/handler-deps.d.ts +19 -0
- package/dist/http/handler-deps.d.ts.map +1 -0
- package/dist/http/handler-deps.js +2 -0
- package/dist/http/handler-deps.js.map +1 -0
- package/dist/http/handlers/control/batch-slice.d.ts +4 -0
- package/dist/http/handlers/control/batch-slice.d.ts.map +1 -0
- package/dist/http/handlers/control/batch-slice.js +40 -0
- package/dist/http/handlers/control/batch-slice.js.map +1 -0
- package/dist/http/handlers/control/batch.d.ts +23 -0
- package/dist/http/handlers/control/batch.d.ts.map +1 -0
- package/dist/http/handlers/control/batch.js +332 -0
- package/dist/http/handlers/control/batch.js.map +1 -0
- package/dist/http/handlers/control/context-blocks.d.ts +22 -0
- package/dist/http/handlers/control/context-blocks.d.ts.map +1 -0
- package/dist/http/handlers/control/context-blocks.js +111 -0
- package/dist/http/handlers/control/context-blocks.js.map +1 -0
- package/dist/http/handlers/introspection/health.d.ts +20 -0
- package/dist/http/handlers/introspection/health.d.ts.map +1 -0
- package/dist/http/handlers/introspection/health.js +18 -0
- package/dist/http/handlers/introspection/health.js.map +1 -0
- package/dist/http/handlers/introspection/status.d.ts +26 -0
- package/dist/http/handlers/introspection/status.d.ts.map +1 -0
- package/dist/http/handlers/introspection/status.js +136 -0
- package/dist/http/handlers/introspection/status.js.map +1 -0
- package/dist/http/handlers/tools/audit.d.ts +4 -0
- package/dist/http/handlers/tools/audit.d.ts.map +1 -0
- package/dist/http/handlers/tools/audit.js +43 -0
- package/dist/http/handlers/tools/audit.js.map +1 -0
- package/dist/http/handlers/tools/debug.d.ts +4 -0
- package/dist/http/handlers/tools/debug.d.ts.map +1 -0
- package/dist/http/handlers/tools/debug.js +43 -0
- package/dist/http/handlers/tools/debug.js.map +1 -0
- package/dist/http/handlers/tools/delegate.d.ts +4 -0
- package/dist/http/handlers/tools/delegate.d.ts.map +1 -0
- package/dist/http/handlers/tools/delegate.js +43 -0
- package/dist/http/handlers/tools/delegate.js.map +1 -0
- package/dist/http/handlers/tools/execute-plan.d.ts +4 -0
- package/dist/http/handlers/tools/execute-plan.d.ts.map +1 -0
- package/dist/http/handlers/tools/execute-plan.js +45 -0
- package/dist/http/handlers/tools/execute-plan.js.map +1 -0
- package/dist/http/handlers/tools/investigate.d.ts +4 -0
- package/dist/http/handlers/tools/investigate.d.ts.map +1 -0
- package/dist/http/handlers/tools/investigate.js +64 -0
- package/dist/http/handlers/tools/investigate.js.map +1 -0
- package/dist/http/handlers/tools/journal-recall.d.ts +4 -0
- package/dist/http/handlers/tools/journal-recall.d.ts.map +1 -0
- package/dist/http/handlers/tools/journal-recall.js +40 -0
- package/dist/http/handlers/tools/journal-recall.js.map +1 -0
- package/dist/http/handlers/tools/journal-record.d.ts +8 -0
- package/dist/http/handlers/tools/journal-record.d.ts.map +1 -0
- package/dist/http/handlers/tools/journal-record.js +40 -0
- package/dist/http/handlers/tools/journal-record.js.map +1 -0
- package/dist/http/handlers/tools/research.d.ts +4 -0
- package/dist/http/handlers/tools/research.d.ts.map +1 -0
- package/dist/http/handlers/tools/research.js +64 -0
- package/dist/http/handlers/tools/research.js.map +1 -0
- package/dist/http/handlers/tools/retry.d.ts +4 -0
- package/dist/http/handlers/tools/retry.d.ts.map +1 -0
- package/dist/http/handlers/tools/retry.js +73 -0
- package/dist/http/handlers/tools/retry.js.map +1 -0
- package/dist/http/handlers/tools/review.d.ts +4 -0
- package/dist/http/handlers/tools/review.d.ts.map +1 -0
- package/dist/http/handlers/tools/review.js +43 -0
- package/dist/http/handlers/tools/review.js.map +1 -0
- package/dist/http/journal-lock.d.ts +4 -0
- package/dist/http/journal-lock.d.ts.map +1 -0
- package/dist/http/journal-lock.js +34 -0
- package/dist/http/journal-lock.js.map +1 -0
- package/dist/http/middleware/body-reader.d.ts +16 -0
- package/dist/http/middleware/body-reader.d.ts.map +1 -0
- package/dist/http/middleware/body-reader.js +44 -0
- package/dist/http/middleware/body-reader.js.map +1 -0
- package/dist/http/middleware/caller-identity.d.ts +16 -0
- package/dist/http/middleware/caller-identity.d.ts.map +1 -0
- package/dist/http/middleware/caller-identity.js +16 -0
- package/dist/http/middleware/caller-identity.js.map +1 -0
- package/dist/http/middleware/decompress.d.ts +14 -0
- package/dist/http/middleware/decompress.d.ts.map +1 -0
- package/dist/http/middleware/decompress.js +51 -0
- package/dist/http/middleware/decompress.js.map +1 -0
- package/dist/http/project-registry.d.ts +54 -0
- package/dist/http/project-registry.d.ts.map +1 -0
- package/dist/http/project-registry.js +130 -0
- package/dist/http/project-registry.js.map +1 -0
- package/dist/http/request-observability.d.ts +8 -0
- package/dist/http/request-observability.d.ts.map +1 -0
- package/dist/http/request-observability.js +20 -0
- package/dist/http/request-observability.js.map +1 -0
- package/dist/http/request-pipeline.d.ts +16 -0
- package/dist/http/request-pipeline.d.ts.map +1 -0
- package/dist/http/request-pipeline.js +144 -0
- package/dist/http/request-pipeline.js.map +1 -0
- package/dist/http/server.d.ts +17 -0
- package/dist/http/server.d.ts.map +1 -0
- package/dist/http/server.js +300 -0
- package/dist/http/server.js.map +1 -0
- package/dist/http/types.d.ts +20 -0
- package/dist/http/types.d.ts.map +1 -0
- package/dist/http/types.js +2 -0
- package/dist/http/types.js.map +1 -0
- package/dist/skill-install/disabled-state.d.ts +35 -0
- package/dist/skill-install/disabled-state.d.ts.map +1 -0
- package/dist/skill-install/disabled-state.js +96 -0
- package/dist/skill-install/disabled-state.js.map +1 -0
- package/dist/skill-install/discover.d.ts +29 -0
- package/dist/skill-install/discover.d.ts.map +1 -0
- package/dist/skill-install/discover.js +104 -0
- package/dist/skill-install/discover.js.map +1 -0
- package/dist/skill-install/include-utils.d.ts +27 -0
- package/dist/skill-install/include-utils.d.ts.map +1 -0
- package/dist/skill-install/include-utils.js +90 -0
- package/dist/skill-install/include-utils.js.map +1 -0
- package/dist/skill-install/manifest.d.ts +82 -0
- package/dist/skill-install/manifest.d.ts.map +1 -0
- package/dist/skill-install/manifest.js +215 -0
- package/dist/skill-install/manifest.js.map +1 -0
- package/dist/skill-install/skill-installer-common.d.ts +26 -0
- package/dist/skill-install/skill-installer-common.d.ts.map +1 -0
- package/dist/skill-install/skill-installer-common.js +139 -0
- package/dist/skill-install/skill-installer-common.js.map +1 -0
- package/dist/skill-install/skill-installers/claude-code.d.ts +43 -0
- package/dist/skill-install/skill-installers/claude-code.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/claude-code.js +65 -0
- package/dist/skill-install/skill-installers/claude-code.js.map +1 -0
- package/dist/skill-install/skill-installers/codex-cli.d.ts +27 -0
- package/dist/skill-install/skill-installers/codex-cli.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/codex-cli.js +84 -0
- package/dist/skill-install/skill-installers/codex-cli.js.map +1 -0
- package/dist/skill-install/skill-installers/cursor.d.ts +72 -0
- package/dist/skill-install/skill-installers/cursor.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/cursor.js +81 -0
- package/dist/skill-install/skill-installers/cursor.js.map +1 -0
- package/dist/skill-install/skill-installers/gemini-cli.d.ts +50 -0
- package/dist/skill-install/skill-installers/gemini-cli.d.ts.map +1 -0
- package/dist/skill-install/skill-installers/gemini-cli.js +72 -0
- package/dist/skill-install/skill-installers/gemini-cli.js.map +1 -0
- package/dist/skill-install/skill-manifest-sync.d.ts +11 -0
- package/dist/skill-install/skill-manifest-sync.d.ts.map +1 -0
- package/dist/skill-install/skill-manifest-sync.js +65 -0
- package/dist/skill-install/skill-manifest-sync.js.map +1 -0
- package/dist/skills/_shared/auth.md +41 -0
- package/dist/skills/_shared/error-handling.md +31 -0
- package/dist/skills/_shared/polling.md +88 -0
- package/dist/skills/_shared/response-shape.md +55 -0
- package/dist/skills/_shared/review-policy.md +15 -0
- package/dist/skills/mma-audit/SKILL.md +270 -0
- package/dist/skills/mma-context-blocks/SKILL.md +148 -0
- package/dist/skills/mma-debug/SKILL.md +208 -0
- package/dist/skills/mma-delegate/SKILL.md +216 -0
- package/dist/skills/mma-execute-plan/SKILL.md +214 -0
- package/dist/skills/mma-explore/SKILL.md +190 -0
- package/dist/skills/mma-investigate/SKILL.md +258 -0
- package/dist/skills/mma-journal-recall/SKILL.md +242 -0
- package/dist/skills/mma-journal-record/SKILL.md +202 -0
- package/dist/skills/mma-research/SKILL.md +223 -0
- package/dist/skills/mma-retry/SKILL.md +221 -0
- package/dist/skills/mma-review/SKILL.md +209 -0
- package/dist/skills/multi-model-agent/SKILL.md +206 -0
- package/dist/telemetry/consent.d.ts +4 -0
- package/dist/telemetry/consent.d.ts.map +1 -0
- package/dist/telemetry/consent.js +40 -0
- package/dist/telemetry/consent.js.map +1 -0
- package/dist/telemetry/flusher.d.ts +19 -0
- package/dist/telemetry/flusher.d.ts.map +1 -0
- package/dist/telemetry/flusher.js +277 -0
- package/dist/telemetry/flusher.js.map +1 -0
- package/dist/telemetry/generation.d.ts +9 -0
- package/dist/telemetry/generation.d.ts.map +1 -0
- package/dist/telemetry/generation.js +33 -0
- package/dist/telemetry/generation.js.map +1 -0
- package/dist/telemetry/identity.d.ts +9 -0
- package/dist/telemetry/identity.d.ts.map +1 -0
- package/dist/telemetry/identity.js +35 -0
- package/dist/telemetry/identity.js.map +1 -0
- package/dist/telemetry/install-id.d.ts +13 -0
- package/dist/telemetry/install-id.d.ts.map +1 -0
- package/dist/telemetry/install-id.js +49 -0
- package/dist/telemetry/install-id.js.map +1 -0
- package/dist/telemetry/install-meta.d.ts +10 -0
- package/dist/telemetry/install-meta.d.ts.map +1 -0
- package/dist/telemetry/install-meta.js +15 -0
- package/dist/telemetry/install-meta.js.map +1 -0
- package/dist/telemetry/queue.d.ts +35 -0
- package/dist/telemetry/queue.d.ts.map +1 -0
- package/dist/telemetry/queue.js +287 -0
- package/dist/telemetry/queue.js.map +1 -0
- package/dist/telemetry/recorder.d.ts +39 -0
- package/dist/telemetry/recorder.d.ts.map +1 -0
- package/dist/telemetry/recorder.js +173 -0
- package/dist/telemetry/recorder.js.map +1 -0
- package/package.json +43 -24
- package/scripts/postinstall.js +36 -0
- package/bin/mmagent.mjs +0 -47
- package/postinstall.mjs +0 -8
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* telemetry.ts — `mmagent telemetry` subcommands.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* mmagent telemetry status
|
|
6
|
+
* mmagent telemetry enable
|
|
7
|
+
* mmagent telemetry disable
|
|
8
|
+
* mmagent telemetry reset-id
|
|
9
|
+
* mmagent telemetry dump-queue
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';
|
|
12
|
+
import { join, dirname } from 'node:path';
|
|
13
|
+
import { decide } from '../telemetry/consent.js';
|
|
14
|
+
import { deleteInstallId } from '../telemetry/install-id.js';
|
|
15
|
+
import { bumpGeneration } from '../telemetry/generation.js';
|
|
16
|
+
import { Queue } from '../telemetry/queue.js';
|
|
17
|
+
/**
|
|
18
|
+
* Read the raw MMAGENT_TELEMETRY env value (not the parsed decision).
|
|
19
|
+
*/
|
|
20
|
+
function readRawEnv() {
|
|
21
|
+
return process.env.MMAGENT_TELEMETRY;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Read the existing config.json as a parsed object, or null if it doesn't exist.
|
|
25
|
+
*/
|
|
26
|
+
function readConfigObj(homeDir) {
|
|
27
|
+
const cfgPath = join(homeDir, 'config.json');
|
|
28
|
+
if (!existsSync(cfgPath))
|
|
29
|
+
return null;
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse(readFileSync(cfgPath, 'utf8'));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Write config.json, ensuring parent directory exists.
|
|
39
|
+
*/
|
|
40
|
+
function writeConfigObj(homeDir, obj) {
|
|
41
|
+
const cfgPath = join(homeDir, 'config.json');
|
|
42
|
+
const parent = dirname(cfgPath);
|
|
43
|
+
if (!existsSync(parent))
|
|
44
|
+
mkdirSync(parent, { recursive: true });
|
|
45
|
+
writeFileSync(cfgPath, JSON.stringify(obj, null, 2) + '\n', { mode: 0o600 });
|
|
46
|
+
}
|
|
47
|
+
async function revokeIdentity(homeDir) {
|
|
48
|
+
await bumpGeneration(homeDir);
|
|
49
|
+
const queuePath = join(homeDir, 'telemetry-queue.ndjson');
|
|
50
|
+
if (existsSync(queuePath))
|
|
51
|
+
unlinkSync(queuePath);
|
|
52
|
+
}
|
|
53
|
+
// ─── status ──────────────────────────────────────────────────────────────────
|
|
54
|
+
async function runStatus(deps) {
|
|
55
|
+
const stdout = deps.stdout ?? process.stdout.write.bind(process.stdout);
|
|
56
|
+
const d = decide(deps.homeDir);
|
|
57
|
+
const envRaw = readRawEnv();
|
|
58
|
+
const lines = [];
|
|
59
|
+
lines.push(`Telemetry: ${d.enabled ? 'enabled' : 'disabled'}`);
|
|
60
|
+
lines.push(`Source: ${d.source}`);
|
|
61
|
+
if (d.source === 'env_invalid') {
|
|
62
|
+
lines.push(`Warning: MMAGENT_TELEMETRY="${envRaw ?? ''}" is not a recognized value (use 1/true/on/yes or 0/false/off/no)`);
|
|
63
|
+
}
|
|
64
|
+
// Surface set-but-empty env distinction
|
|
65
|
+
if (envRaw !== undefined && envRaw.trim().length === 0) {
|
|
66
|
+
lines.push(`Note: MMAGENT_TELEMETRY is set to '' (no effect — falls through to ${d.source})`);
|
|
67
|
+
}
|
|
68
|
+
stdout(lines.join('\n') + '\n');
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
// ─── enable ──────────────────────────────────────────────────────────────────
|
|
72
|
+
async function runEnable(deps) {
|
|
73
|
+
const stdout = deps.stdout ?? process.stdout.write.bind(process.stdout);
|
|
74
|
+
const stderr = deps.stderr ?? process.stderr.write.bind(process.stderr);
|
|
75
|
+
let cfg = readConfigObj(deps.homeDir) ?? {};
|
|
76
|
+
// Remove bare top-level `enabled` if present — canonical shape is `telemetry.enabled`
|
|
77
|
+
if (typeof cfg.enabled === 'boolean') {
|
|
78
|
+
delete cfg.enabled;
|
|
79
|
+
}
|
|
80
|
+
const telemetry = (cfg.telemetry ?? {});
|
|
81
|
+
telemetry.enabled = true;
|
|
82
|
+
delete telemetry.consentSchemaVersion;
|
|
83
|
+
cfg.telemetry = telemetry;
|
|
84
|
+
try {
|
|
85
|
+
writeConfigObj(deps.homeDir, cfg);
|
|
86
|
+
stdout('Telemetry enabled (config.telemetry.enabled = true)\n');
|
|
87
|
+
return 0;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
stderr(`mmagent telemetry enable: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ─── disable ──────────────────────────────────────────────────────────────────
|
|
95
|
+
async function runDisable(deps) {
|
|
96
|
+
const stdout = deps.stdout ?? process.stdout.write.bind(process.stdout);
|
|
97
|
+
const stderr = deps.stderr ?? process.stderr.write.bind(process.stderr);
|
|
98
|
+
let cfg = readConfigObj(deps.homeDir) ?? {};
|
|
99
|
+
if (typeof cfg.enabled === 'boolean') {
|
|
100
|
+
delete cfg.enabled;
|
|
101
|
+
}
|
|
102
|
+
const telemetry = (cfg.telemetry ?? {});
|
|
103
|
+
telemetry.enabled = false;
|
|
104
|
+
cfg.telemetry = telemetry;
|
|
105
|
+
try {
|
|
106
|
+
writeConfigObj(deps.homeDir, cfg);
|
|
107
|
+
await revokeIdentity(deps.homeDir);
|
|
108
|
+
stdout('Telemetry disabled (config.telemetry.enabled = false, identity revoked)\n');
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
stderr(`mmagent telemetry disable: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ─── reset-id ─────────────────────────────────────────────────────────────────
|
|
117
|
+
async function runResetId(deps) {
|
|
118
|
+
const stdout = deps.stdout ?? process.stdout.write.bind(process.stdout);
|
|
119
|
+
const stderr = deps.stderr ?? process.stderr.write.bind(process.stderr);
|
|
120
|
+
try {
|
|
121
|
+
await revokeIdentity(deps.homeDir);
|
|
122
|
+
deleteInstallId(deps.homeDir);
|
|
123
|
+
stdout('Identity reset (generation bumped, queue deleted, install-id deleted)\n');
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
stderr(`mmagent telemetry reset-id: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
128
|
+
return 1;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// ─── dump-queue ───────────────────────────────────────────────────────────────
|
|
132
|
+
async function runDumpQueue(deps) {
|
|
133
|
+
const stdout = deps.stdout ?? process.stdout.write.bind(process.stdout);
|
|
134
|
+
const stderr = deps.stderr ?? process.stderr.write.bind(process.stderr);
|
|
135
|
+
try {
|
|
136
|
+
const queue = new Queue(deps.homeDir);
|
|
137
|
+
const batch = await queue.readBatch();
|
|
138
|
+
stdout(JSON.stringify(batch.records, null, 2) + '\n');
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
stderr(`mmagent telemetry dump-queue: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// ─── dispatch ─────────────────────────────────────────────────────────────────
|
|
147
|
+
export async function runTelemetry(deps) {
|
|
148
|
+
switch (deps.subcommand) {
|
|
149
|
+
case 'status': return runStatus(deps);
|
|
150
|
+
case 'enable': return runEnable(deps);
|
|
151
|
+
case 'disable': return runDisable(deps);
|
|
152
|
+
case 'reset-id': return runResetId(deps);
|
|
153
|
+
case 'dump-queue': return runDumpQueue(deps);
|
|
154
|
+
default: {
|
|
155
|
+
const stderr = deps.stderr ?? process.stderr.write.bind(process.stderr);
|
|
156
|
+
stderr(`mmagent telemetry: unknown subcommand '${deps.subcommand}'\n`);
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/cli/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare const ToggleExitCode: Readonly<{
|
|
2
|
+
SUCCESS: 0;
|
|
3
|
+
ERR_PARTIAL: 1;
|
|
4
|
+
ERR_UNKNOWN_TARGET: 3;
|
|
5
|
+
}>;
|
|
6
|
+
export interface ToggleDeps {
|
|
7
|
+
argv?: string[];
|
|
8
|
+
homeDir?: string;
|
|
9
|
+
/** Override skills root — threaded into runSyncSkills for `enable` in tests. */
|
|
10
|
+
skillsRoot?: string;
|
|
11
|
+
/** Recorded in the sentinel for diagnostics; defaults to 'unknown'. */
|
|
12
|
+
cliVersion?: string;
|
|
13
|
+
stdout?: (s: string) => boolean;
|
|
14
|
+
stderr?: (s: string) => boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* `mmagent disable` — remove all MMA skills from the resolved clients and
|
|
18
|
+
* record the sticky sentinel.
|
|
19
|
+
*/
|
|
20
|
+
export declare function runDisable(deps?: ToggleDeps): Promise<number>;
|
|
21
|
+
/**
|
|
22
|
+
* `mmagent enable` — clear the sentinel for the resolved clients, then
|
|
23
|
+
* delegate to sync-skills' idempotent upsert to reinstall the skills.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runEnable(deps?: ToggleDeps): Promise<number>;
|
|
26
|
+
//# sourceMappingURL=toggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../src/cli/toggle.ts"],"names":[],"mappings":"AAqCA,eAAO,MAAM,cAAc;;;;EAIzB,CAAC;AAEH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;CACjC;AA4BD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAyEvE;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDtE"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* toggle.ts — `mmagent disable` / `mmagent enable` subcommands.
|
|
3
|
+
*
|
|
4
|
+
* disable: remove every shipped skill from the resolved clients, drop their
|
|
5
|
+
* manifest entries, and record a sticky sentinel so a later `npm install`
|
|
6
|
+
* postinstall (which shells out to `sync-skills`) does not silently
|
|
7
|
+
* reinstall them. This is the only "off switch" that survives an upgrade.
|
|
8
|
+
* enable: clear the sentinel for the resolved clients, then run the normal
|
|
9
|
+
* sync-skills upsert to reinstall the skills.
|
|
10
|
+
*
|
|
11
|
+
* Both reuse sync-skills' target resolution so `--target` / `--all-targets`
|
|
12
|
+
* behave identically across all three commands.
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* mmagent disable [--target=<client>] [--all-targets] [--dry-run] [--json]
|
|
16
|
+
* mmagent enable [--target=<client>] [--all-targets] [--dry-run] [--json]
|
|
17
|
+
*
|
|
18
|
+
* Exit codes:
|
|
19
|
+
* 0 — success (or no clients detected)
|
|
20
|
+
* 1 — one or more skills failed to remove
|
|
21
|
+
* 3 — explicit --target was not a known client
|
|
22
|
+
*/
|
|
23
|
+
import * as os from 'node:os';
|
|
24
|
+
import minimist from 'minimist';
|
|
25
|
+
import { removeEntry, ALL_CLIENTS } from '../skill-install/manifest.js';
|
|
26
|
+
import { SUPPORTED_SKILLS } from '../skill-install/discover.js';
|
|
27
|
+
import { removeSkillFromClient, UnknownTargetError, } from '../skill-install/skill-installer-common.js';
|
|
28
|
+
import { addDisabledTargets, clearDisabledTargets, disabledTargets, } from '../skill-install/disabled-state.js';
|
|
29
|
+
import { resolveTargets, runSyncSkills } from './sync-skills.js';
|
|
30
|
+
export const ToggleExitCode = Object.freeze({
|
|
31
|
+
SUCCESS: 0,
|
|
32
|
+
ERR_PARTIAL: 1,
|
|
33
|
+
ERR_UNKNOWN_TARGET: 3,
|
|
34
|
+
});
|
|
35
|
+
function parseToggleArgs(argv) {
|
|
36
|
+
const args = minimist(argv, {
|
|
37
|
+
string: ['target'],
|
|
38
|
+
boolean: ['dry-run', 'json', 'all-targets'],
|
|
39
|
+
alias: { t: 'target', j: 'json' },
|
|
40
|
+
});
|
|
41
|
+
let targets = null;
|
|
42
|
+
if (args.target) {
|
|
43
|
+
const t = Array.isArray(args.target) ? args.target : [args.target];
|
|
44
|
+
targets = t.map((s) => s);
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
targets,
|
|
48
|
+
allTargets: args['all-targets'] === true,
|
|
49
|
+
dryRun: args['dry-run'] === true,
|
|
50
|
+
json: args['json'] === true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* `mmagent disable` — remove all MMA skills from the resolved clients and
|
|
55
|
+
* record the sticky sentinel.
|
|
56
|
+
*/
|
|
57
|
+
export async function runDisable(deps = {}) {
|
|
58
|
+
const argv = deps.argv ?? process.argv.slice(2);
|
|
59
|
+
const homeDir = deps.homeDir ?? os.homedir();
|
|
60
|
+
const stdout = deps.stdout ?? process.stdout.write.bind(process.stdout);
|
|
61
|
+
const stderr = deps.stderr ?? process.stderr.write.bind(process.stderr);
|
|
62
|
+
const cliVersion = deps.cliVersion ?? 'unknown';
|
|
63
|
+
const parsed = parseToggleArgs(argv);
|
|
64
|
+
let targets;
|
|
65
|
+
try {
|
|
66
|
+
targets = resolveTargets(parsed.targets, parsed.allTargets, homeDir);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (err instanceof UnknownTargetError) {
|
|
70
|
+
stderr(`mmagent disable: ${err.message}\n`);
|
|
71
|
+
return ToggleExitCode.ERR_UNKNOWN_TARGET;
|
|
72
|
+
}
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
if (targets.length === 0) {
|
|
76
|
+
if (parsed.json) {
|
|
77
|
+
stdout(JSON.stringify({ action: 'disable', targets: [], outcome: 'no-clients-detected' }) + '\n');
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
stdout('No clients detected. Use --target=<client> or --all-targets.\n');
|
|
81
|
+
}
|
|
82
|
+
return ToggleExitCode.SUCCESS;
|
|
83
|
+
}
|
|
84
|
+
const removed = [];
|
|
85
|
+
const errors = [];
|
|
86
|
+
if (parsed.dryRun) {
|
|
87
|
+
for (const target of targets) {
|
|
88
|
+
for (const skill of SUPPORTED_SKILLS)
|
|
89
|
+
removed.push({ skill, target });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
for (const target of targets) {
|
|
94
|
+
for (const skill of SUPPORTED_SKILLS) {
|
|
95
|
+
try {
|
|
96
|
+
removeSkillFromClient(skill, target, homeDir);
|
|
97
|
+
removed.push({ skill, target });
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
errors.push({
|
|
101
|
+
skill,
|
|
102
|
+
target,
|
|
103
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
for (const skill of SUPPORTED_SKILLS)
|
|
109
|
+
removeEntry(skill, targets, homeDir);
|
|
110
|
+
addDisabledTargets(homeDir, targets, cliVersion);
|
|
111
|
+
}
|
|
112
|
+
if (parsed.json) {
|
|
113
|
+
stdout(JSON.stringify({
|
|
114
|
+
action: 'disable',
|
|
115
|
+
dryRun: parsed.dryRun,
|
|
116
|
+
targets,
|
|
117
|
+
removed: removed.length,
|
|
118
|
+
errors,
|
|
119
|
+
}) + '\n');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
const verb = parsed.dryRun ? 'Would disable' : 'Disabled';
|
|
123
|
+
const errClause = errors.length > 0 ? `, ${errors.length} errors` : '';
|
|
124
|
+
stdout(`${verb} MMA skills → ${targets.join(', ')} (${removed.length} removed${errClause}).\n`);
|
|
125
|
+
if (!parsed.dryRun)
|
|
126
|
+
stdout('Run `mmagent enable` to restore.\n');
|
|
127
|
+
for (const e of errors)
|
|
128
|
+
stderr(`error: ${e.skill} → ${e.target}: ${e.reason}\n`);
|
|
129
|
+
}
|
|
130
|
+
return errors.length > 0 ? ToggleExitCode.ERR_PARTIAL : ToggleExitCode.SUCCESS;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* `mmagent enable` — clear the sentinel for the resolved clients, then
|
|
134
|
+
* delegate to sync-skills' idempotent upsert to reinstall the skills.
|
|
135
|
+
*/
|
|
136
|
+
export async function runEnable(deps = {}) {
|
|
137
|
+
const argv = deps.argv ?? process.argv.slice(2);
|
|
138
|
+
const homeDir = deps.homeDir ?? os.homedir();
|
|
139
|
+
const stdout = deps.stdout ?? process.stdout.write.bind(process.stdout);
|
|
140
|
+
const stderr = deps.stderr ?? process.stderr.write.bind(process.stderr);
|
|
141
|
+
const parsed = parseToggleArgs(argv);
|
|
142
|
+
let targets;
|
|
143
|
+
try {
|
|
144
|
+
targets = resolveTargets(parsed.targets, parsed.allTargets, homeDir);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
if (err instanceof UnknownTargetError) {
|
|
148
|
+
stderr(`mmagent enable: ${err.message}\n`);
|
|
149
|
+
return ToggleExitCode.ERR_UNKNOWN_TARGET;
|
|
150
|
+
}
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
const wasDisabled = disabledTargets(homeDir);
|
|
154
|
+
const bare = parsed.targets === null && !parsed.allTargets;
|
|
155
|
+
// Clear the sentinel BEFORE syncing — otherwise sync-skills would see the
|
|
156
|
+
// targets as still-disabled and skip them. On --dry-run, leave it intact.
|
|
157
|
+
if (!parsed.dryRun) {
|
|
158
|
+
// No explicit --target means "re-enable everything", so clear the whole set.
|
|
159
|
+
const toClear = bare ? [...ALL_CLIENTS] : targets;
|
|
160
|
+
clearDisabledTargets(homeDir, toClear);
|
|
161
|
+
}
|
|
162
|
+
if (wasDisabled.length === 0) {
|
|
163
|
+
stdout('MMA skills were not disabled; syncing to ensure they are installed.\n');
|
|
164
|
+
}
|
|
165
|
+
// Reinstall via the canonical upsert. For a bare `enable`, sync-skills would
|
|
166
|
+
// otherwise touch only auto-detected clients (claude-code / codex) and skip
|
|
167
|
+
// a previously `disable --target=cursor` — un-pinning it without restoring
|
|
168
|
+
// it. So when no explicit target is given, sync the union of detected
|
|
169
|
+
// clients and whatever was pinned off, making `enable` actually restore what
|
|
170
|
+
// `disable` removed. Explicit --target / --all-targets pass straight through.
|
|
171
|
+
let syncArgv = argv;
|
|
172
|
+
if (bare && wasDisabled.length > 0) {
|
|
173
|
+
const detected = resolveTargets(null, false, homeDir);
|
|
174
|
+
const union = ALL_CLIENTS.filter((c) => detected.includes(c) || wasDisabled.includes(c));
|
|
175
|
+
syncArgv = [...argv, ...union.map((c) => `--target=${c}`)];
|
|
176
|
+
}
|
|
177
|
+
return runSyncSkills({
|
|
178
|
+
argv: syncArgv,
|
|
179
|
+
homeDir,
|
|
180
|
+
skillsRoot: deps.skillsRoot,
|
|
181
|
+
stdout: deps.stdout,
|
|
182
|
+
stderr: deps.stderr,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=toggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggle.js","sourceRoot":"","sources":["../../src/cli/toggle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { BatchRegistry, ProjectContext } from '@zhixuan92/multi-model-agent-core';
|
|
2
|
+
import type { ExecutionContext } from '@zhixuan92/multi-model-agent-core';
|
|
3
|
+
import type { HandlerDeps } from './handler-deps.js';
|
|
4
|
+
export interface AsyncDispatchOptions<TResult> {
|
|
5
|
+
tool: string;
|
|
6
|
+
projectCwd: string;
|
|
7
|
+
blockIds: string[];
|
|
8
|
+
batchRegistry: BatchRegistry;
|
|
9
|
+
projectContext: ProjectContext;
|
|
10
|
+
deps: HandlerDeps;
|
|
11
|
+
/**
|
|
12
|
+
* Caller identity from the x-mma-client request header. Threaded into
|
|
13
|
+
* ExecutionContext so the cloud `task.completed` event carries the client.
|
|
14
|
+
* Without this the wire event has an empty string and the backend rejects
|
|
15
|
+
* the upload (STRICT_ID_REGEX). triggeringSkill was dropped because it's
|
|
16
|
+
* implied by `route` for the 99% case (mma-<route> → /<route>).
|
|
17
|
+
*/
|
|
18
|
+
caller?: {
|
|
19
|
+
client: string;
|
|
20
|
+
mainModel?: string | null;
|
|
21
|
+
};
|
|
22
|
+
reviewPolicy?: 'full' | 'quality_only' | 'diff_only' | 'none';
|
|
23
|
+
/**
|
|
24
|
+
* The async function that does the real work. Receives the ExecutionContext
|
|
25
|
+
* and the pre-allocated batchId.
|
|
26
|
+
*/
|
|
27
|
+
executor: (ctx: ExecutionContext, batchId: string) => Promise<TResult>;
|
|
28
|
+
}
|
|
29
|
+
export interface AsyncDispatchResult {
|
|
30
|
+
batchId: string;
|
|
31
|
+
statusUrl: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Registers a new batch as 'pending', schedules the executor via setImmediate,
|
|
35
|
+
* and returns immediately with { batchId, statusUrl }.
|
|
36
|
+
*
|
|
37
|
+
* On success: calls batchRegistry.complete(batchId, result).
|
|
38
|
+
* On failure: calls batchRegistry.fail(batchId, { code, message, stack }).
|
|
39
|
+
*
|
|
40
|
+
* IMPORTANT: Does NOT maintain a manual activeBatches counter.
|
|
41
|
+
* Use BatchRegistry.countActiveForProject(cwd) as the truth source.
|
|
42
|
+
*/
|
|
43
|
+
export declare function asyncDispatch<TResult>(opts: AsyncDispatchOptions<TResult>): AsyncDispatchResult;
|
|
44
|
+
//# sourceMappingURL=async-dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-dispatch.d.ts","sourceRoot":"","sources":["../../src/http/async-dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAG1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,MAAM,WAAW,oBAAoB,CAAC,OAAO;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACvD,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,WAAW,GAAG,MAAM,CAAC;IAC9D;;;OAGG;IACH,QAAQ,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxE;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EACnC,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAClC,mBAAmB,CA8HrB"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// packages/server/src/http/async-dispatch.ts
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { TaskEnvelopeStore } from '@zhixuan92/multi-model-agent-core/events/task-envelope';
|
|
4
|
+
import { buildExecutionContext } from './execution-context.js';
|
|
5
|
+
/**
|
|
6
|
+
* Registers a new batch as 'pending', schedules the executor via setImmediate,
|
|
7
|
+
* and returns immediately with { batchId, statusUrl }.
|
|
8
|
+
*
|
|
9
|
+
* On success: calls batchRegistry.complete(batchId, result).
|
|
10
|
+
* On failure: calls batchRegistry.fail(batchId, { code, message, stack }).
|
|
11
|
+
*
|
|
12
|
+
* IMPORTANT: Does NOT maintain a manual activeBatches counter.
|
|
13
|
+
* Use BatchRegistry.countActiveForProject(cwd) as the truth source.
|
|
14
|
+
*/
|
|
15
|
+
export function asyncDispatch(opts) {
|
|
16
|
+
const batchId = randomUUID();
|
|
17
|
+
const { batchRegistry, projectContext, deps, tool, projectCwd, blockIds } = opts;
|
|
18
|
+
// Register entry as 'pending' before scheduling executor
|
|
19
|
+
batchRegistry.register({
|
|
20
|
+
batchId,
|
|
21
|
+
projectCwd,
|
|
22
|
+
tool,
|
|
23
|
+
state: 'pending',
|
|
24
|
+
startedAt: Date.now(),
|
|
25
|
+
stateChangedAt: Date.now(),
|
|
26
|
+
blockIds,
|
|
27
|
+
blocksReleased: false,
|
|
28
|
+
});
|
|
29
|
+
// Create and attach envelope to registry
|
|
30
|
+
const envelope = TaskEnvelopeStore.create({
|
|
31
|
+
taskId: batchId + ':' + 0,
|
|
32
|
+
batchId: batchId, taskIndex: 0,
|
|
33
|
+
route: tool, agentType: 'standard',
|
|
34
|
+
client: opts.caller?.client ?? '', mainModel: opts.caller?.mainModel ?? '', cwd: projectCwd,
|
|
35
|
+
reviewPolicy: opts.reviewPolicy ?? 'full',
|
|
36
|
+
}, deps.bus);
|
|
37
|
+
batchRegistry.attachEnvelope(batchId, 0, envelope);
|
|
38
|
+
// Build execution context for this batch
|
|
39
|
+
const ctx = buildExecutionContext(deps, projectContext, batchId, envelope, tool, opts.caller);
|
|
40
|
+
// Schedule executor asynchronously — do not await here
|
|
41
|
+
const startedAtMs = Date.now();
|
|
42
|
+
setImmediate(() => {
|
|
43
|
+
void (async () => {
|
|
44
|
+
try {
|
|
45
|
+
// Mark the batch as running so /batch/:id polling reports
|
|
46
|
+
// "1/1 running, Xs elapsed" the instant the executor begins.
|
|
47
|
+
// Without bumping the headline snapshot here, the polling endpoint
|
|
48
|
+
// returns the initial "0/N queued" fallback until the runner's first
|
|
49
|
+
// heartbeat arrives — which can be many seconds (or minutes) later
|
|
50
|
+
// because heartbeats fire from inside provider.run. That gap is what
|
|
51
|
+
// made 4.0.1 audits look like the daemon was deadlocked when the
|
|
52
|
+
// only thing actually slow was the LLM call.
|
|
53
|
+
const entry = batchRegistry.get(batchId);
|
|
54
|
+
if (entry) {
|
|
55
|
+
entry.tasksTotal = 1;
|
|
56
|
+
entry.tasksStarted = 1;
|
|
57
|
+
entry.tasksCompleted = 0;
|
|
58
|
+
// Use the route's stage-order denominator (3 for audit, 7 for
|
|
59
|
+
// delegate, etc.) so polling shows "Implementing (1/3)" the
|
|
60
|
+
// instant the executor starts — instead of an opaque
|
|
61
|
+
// "1/1 running" that doesn't tell the main agent how far along
|
|
62
|
+
// the lifecycle has progressed.
|
|
63
|
+
// Headline seeding moved to envelope creation in T7-T11 migration —
|
|
64
|
+
// each TaskEnvelope's headline is derived on every mutation, and
|
|
65
|
+
// BatchRegistry no longer caches snapshot objects.
|
|
66
|
+
}
|
|
67
|
+
// 4.6.0+: always-on verbose breadcrumb so operators tailing the daemon
|
|
68
|
+
// see the executor lifecycle past request_received without grepping the
|
|
69
|
+
// JSONL log.
|
|
70
|
+
process.stderr.write(`[mmagent] event=executor_started ts=${new Date().toISOString()} batch=${batchId} route=${tool}\n`);
|
|
71
|
+
const result = await opts.executor(ctx, batchId);
|
|
72
|
+
const resultObj = result;
|
|
73
|
+
const entryAfter = batchRegistry.get(batchId);
|
|
74
|
+
if (entryAfter) {
|
|
75
|
+
// For multi-task batches the executor bumped tasksTotal from the
|
|
76
|
+
// placeholder of 1 to the real fan-out width. Mark every task as
|
|
77
|
+
// completed so the live/terminal headline reports n/n complete.
|
|
78
|
+
entryAfter.tasksCompleted = Math.max(entryAfter.tasksTotal ?? 1, 1);
|
|
79
|
+
}
|
|
80
|
+
const taskCount = Array.isArray(resultObj?.results) ? resultObj.results.length : 0;
|
|
81
|
+
const durationMs = Date.now() - startedAtMs;
|
|
82
|
+
// Gap 5 fix (4.0.3+): inspect the envelope for structured failure
|
|
83
|
+
// signals. The executor may catch errors and package them into a
|
|
84
|
+
// result envelope (with structuredError or status='error') instead
|
|
85
|
+
// of throwing — without this check, batch_completed fires
|
|
86
|
+
// misleadingly while the verbose log gives operators no signal
|
|
87
|
+
// that anything went wrong. Detection uses STRUCTURED FIELDS ONLY,
|
|
88
|
+
// never string comparisons.
|
|
89
|
+
//
|
|
90
|
+
// Order matters: detect failure FIRST, then call complete() or
|
|
91
|
+
// fail() exactly once. Pre-fix, complete() ran unconditionally
|
|
92
|
+
// before fail() — the fail() then no-op'd because the registry
|
|
93
|
+
// entry was already terminal, leaving the wire error field stuck
|
|
94
|
+
// at "not_applicable" even when detectFailure returned a real
|
|
95
|
+
// failure. Probe I (multi-task /delegate) hit this every time.
|
|
96
|
+
const failure = detectFailure(resultObj);
|
|
97
|
+
if (failure) {
|
|
98
|
+
batchRegistry.fail(batchId, failure);
|
|
99
|
+
deps.bus.emitPlainEntry({ ts: new Date().toISOString(), kind: 'batch_failed', fields: { batch_id: batchId, tool, duration_ms: durationMs, error_code: failure.code, error_message: failure.message } });
|
|
100
|
+
process.stderr.write(`[mmagent] event=batch_failed ts=${new Date().toISOString()} batch=${batchId} route=${tool} duration_ms=${durationMs} error_code=${failure.code} error="${failure.message.replace(/"/g, '\\"')}"\n`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
batchRegistry.complete(batchId);
|
|
104
|
+
const dispatchMode = resultObj?.dispatchMode;
|
|
105
|
+
deps.bus.emitPlainEntry({ ts: new Date().toISOString(), kind: 'batch_completed', fields: { batch_id: batchId, tool, duration_ms: durationMs, task_count: taskCount, ...(dispatchMode !== undefined ? { dispatch_mode: dispatchMode } : {}) } });
|
|
106
|
+
process.stderr.write(`[mmagent] event=batch_completed ts=${new Date().toISOString()} batch=${batchId} route=${tool} duration_ms=${durationMs}\n`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
111
|
+
const stack = err instanceof Error ? err.stack : undefined;
|
|
112
|
+
const errObj = {
|
|
113
|
+
code: 'runner_crash',
|
|
114
|
+
message,
|
|
115
|
+
...(stack !== undefined && { stack }),
|
|
116
|
+
};
|
|
117
|
+
batchRegistry.fail(batchId, errObj);
|
|
118
|
+
const durationMs = Date.now() - startedAtMs;
|
|
119
|
+
deps.bus.emitPlainEntry({ ts: new Date().toISOString(), kind: 'batch_failed', fields: { batch_id: batchId, tool, duration_ms: durationMs, error_code: errObj.code, error_message: errObj.message } });
|
|
120
|
+
process.stderr.write(`[mmagent] event=batch_failed ts=${new Date().toISOString()} batch=${batchId} route=${tool} duration_ms=${durationMs} error="${message.replace(/"/g, '\\"')}"\n`);
|
|
121
|
+
}
|
|
122
|
+
})();
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
batchId,
|
|
126
|
+
statusUrl: `/batch/${batchId}`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Inspect an executor return envelope for structured failure signals.
|
|
131
|
+
* Returns { code, message } when the envelope indicates failure, null
|
|
132
|
+
* otherwise.
|
|
133
|
+
*
|
|
134
|
+
* Per the Gap 5 fix design (wire-telemetry-gaps plan): NO string
|
|
135
|
+
* comparison to "batch succeeded". Use only:
|
|
136
|
+
* 1. Any task result with `structuredError` (most authoritative)
|
|
137
|
+
* 2. Any task result with `status` other than 'ok'
|
|
138
|
+
* 3. Envelope-level `error` object whose `kind` is not 'not_applicable'
|
|
139
|
+
* (notApplicable() is the structured "no error" sentinel)
|
|
140
|
+
*/
|
|
141
|
+
function detectFailure(envelope) {
|
|
142
|
+
if (!envelope)
|
|
143
|
+
return null;
|
|
144
|
+
const results = Array.isArray(envelope.results) ? envelope.results : [];
|
|
145
|
+
// Source 1: explicit structuredError on any task result
|
|
146
|
+
for (const r of results) {
|
|
147
|
+
const se = r.structuredError;
|
|
148
|
+
if (se && typeof se.code === 'string') {
|
|
149
|
+
return { code: se.code, message: typeof se.message === 'string' ? se.message : se.code };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Source 2: any task result with status === 'error'.
|
|
153
|
+
// 'incomplete' is intentionally NOT treated as failure — review-rework
|
|
154
|
+
// paths can transit through 'incomplete' on intermediate rounds while
|
|
155
|
+
// the eventual envelope still represents a valid (if imperfect) batch.
|
|
156
|
+
// Only 'error' and 'failed' are categorical batch-level failures.
|
|
157
|
+
for (const r of results) {
|
|
158
|
+
const status = r.status;
|
|
159
|
+
if (typeof status === 'string' && (status === 'error' || status === 'failed')) {
|
|
160
|
+
const code = (typeof r.errorCode === 'string' && r.errorCode.length > 0) ? r.errorCode : status;
|
|
161
|
+
const msg = (typeof r.error === 'string' && r.error.length > 0) ? r.error : status;
|
|
162
|
+
return { code, message: msg };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Source 3: envelope-level error object with kind != 'not_applicable'
|
|
166
|
+
const env = envelope.error;
|
|
167
|
+
if (env && typeof env.kind === 'string' && env.kind !== 'not_applicable') {
|
|
168
|
+
return {
|
|
169
|
+
code: typeof env.code === 'string' ? env.code : 'envelope_error',
|
|
170
|
+
message: typeof env.message === 'string' ? env.message : 'envelope error',
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=async-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async-dispatch.js","sourceRoot":"","sources":["../../src/http/async-dispatch.ts"],"names":[],"mappings":"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"}
|