@mnemom/mnemom 0.17.33 → 0.17.34-next.2
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/base-url-proxy.mjs +18 -4
- package/dist/commands/agent-config.js +5 -1
- package/dist/commands/agent-doctor.d.ts +9 -0
- package/dist/commands/agent-doctor.js +4 -0
- package/dist/commands/agent-session.d.ts +1 -2
- package/dist/commands/agent-session.js +1 -2
- package/dist/commands/agent-setup.d.ts +6 -0
- package/dist/commands/agent-setup.js +12 -1
- package/dist/commands/agent-share-render.d.ts +1 -1
- package/dist/commands/agent-share-render.js +1 -1
- package/dist/commands/agent.d.ts +26 -0
- package/dist/commands/agent.js +228 -53
- package/dist/commands/durable-doctor.d.ts +50 -0
- package/dist/commands/durable-doctor.js +186 -0
- package/dist/commands/durable-lock.d.ts +254 -0
- package/dist/commands/durable-lock.js +595 -0
- package/dist/commands/durable-sessions.d.ts +87 -0
- package/dist/commands/durable-sessions.js +303 -0
- package/dist/commands/durable-verbs.d.ts +116 -0
- package/dist/commands/durable-verbs.js +393 -0
- package/dist/commands/protection.js +1 -1
- package/dist/commands/scan.d.ts +97 -0
- package/dist/commands/scan.js +238 -0
- package/dist/durable/flock.d.ts +26 -0
- package/dist/durable/flock.js +80 -0
- package/dist/durable/launch-spec.d.ts +7 -1
- package/dist/durable/launch-spec.js +10 -3
- package/dist/durable/seat-proxy-entry.d.ts +11 -0
- package/dist/durable/seat-proxy-entry.js +25 -0
- package/dist/durable/seat-proxy.d.ts +107 -0
- package/dist/durable/seat-proxy.js +599 -0
- package/dist/durable/seat-socket.d.ts +46 -0
- package/dist/durable/seat-socket.js +179 -0
- package/dist/durable/seat-spec-validator.d.ts +28 -0
- package/dist/durable/seat-spec-validator.js +59 -0
- package/dist/durable/test-mode.mjs +81 -0
- package/dist/durable/turn-chain.d.ts +55 -0
- package/dist/durable/turn-chain.js +178 -0
- package/dist/host/auto-continue.d.ts +67 -0
- package/dist/host/auto-continue.js +118 -0
- package/dist/host/bootid.d.ts +13 -0
- package/dist/host/bootid.js +41 -0
- package/dist/host/client.d.ts +123 -0
- package/dist/host/client.js +171 -0
- package/dist/host/commands.d.ts +2 -0
- package/dist/host/commands.js +122 -0
- package/dist/host/control.d.ts +33 -0
- package/dist/host/control.js +144 -0
- package/dist/host/daemon.d.ts +217 -0
- package/dist/host/daemon.js +606 -0
- package/dist/host/gate.d.ts +46 -0
- package/dist/host/gate.js +82 -0
- package/dist/host/grant.d.ts +24 -0
- package/dist/host/grant.js +24 -0
- package/dist/host/instance.d.ts +35 -0
- package/dist/host/instance.js +62 -0
- package/dist/host/integrity.d.ts +35 -0
- package/dist/host/integrity.js +115 -0
- package/dist/host/launchd.d.ts +16 -0
- package/dist/host/launchd.js +45 -0
- package/dist/host/lock.d.ts +20 -0
- package/dist/host/lock.js +63 -0
- package/dist/host/owner.d.ts +55 -0
- package/dist/host/owner.js +121 -0
- package/dist/host/plist.d.ts +16 -0
- package/dist/host/plist.js +85 -0
- package/dist/host/procs.d.ts +27 -0
- package/dist/host/procs.js +105 -0
- package/dist/host/run.d.ts +66 -0
- package/dist/host/run.js +314 -0
- package/dist/host/runtime.d.ts +8 -0
- package/dist/host/runtime.js +22 -0
- package/dist/host/s1-names.d.ts +22 -0
- package/dist/host/s1-names.js +21 -0
- package/dist/host/seat-credential.d.ts +27 -0
- package/dist/host/seat-credential.js +41 -0
- package/dist/host/seat-launch-main.d.ts +1 -0
- package/dist/host/seat-launch-main.js +59 -0
- package/dist/host/seat-launch.d.ts +116 -0
- package/dist/host/seat-launch.js +302 -0
- package/dist/host/seat.d.ts +48 -0
- package/dist/host/seat.js +149 -0
- package/dist/host/state.d.ts +33 -0
- package/dist/host/state.js +117 -0
- package/dist/host/status.d.ts +101 -0
- package/dist/host/status.js +307 -0
- package/dist/host/tmux.d.ts +56 -0
- package/dist/host/tmux.js +182 -0
- package/dist/host/transcript.d.ts +30 -0
- package/dist/host/transcript.js +130 -0
- package/dist/host/verbs.d.ts +50 -0
- package/dist/host/verbs.js +271 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.js +232 -35
- package/dist/lib/agent.d.ts +8 -26
- package/dist/lib/agent.js +11 -26
- package/dist/lib/api.d.ts +13 -0
- package/dist/lib/api.js +8 -0
- package/dist/lib/claude-plugin.d.ts +11 -2
- package/dist/lib/claude-plugin.js +10 -1
- package/dist/lib/durable/api.d.ts +136 -0
- package/dist/lib/durable/api.js +220 -0
- package/dist/lib/durable/codes.d.ts +8 -0
- package/dist/lib/durable/codes.js +2 -0
- package/dist/lib/durable/first-turn.d.ts +50 -0
- package/dist/lib/durable/first-turn.js +102 -0
- package/dist/lib/durable/gate.d.ts +48 -0
- package/dist/lib/durable/gate.js +122 -0
- package/dist/lib/durable/handover.d.ts +101 -0
- package/dist/lib/durable/handover.js +175 -0
- package/dist/lib/durable/launch.d.ts +182 -0
- package/dist/lib/durable/launch.js +443 -0
- package/dist/lib/durable/launching.d.ts +15 -0
- package/dist/lib/durable/launching.js +70 -0
- package/dist/lib/durable/live.d.ts +194 -0
- package/dist/lib/durable/live.js +635 -0
- package/dist/lib/durable/refusal.d.ts +57 -0
- package/dist/lib/durable/refusal.js +78 -0
- package/dist/lib/durable/view.d.ts +83 -0
- package/dist/lib/durable/view.js +244 -0
- package/dist/lib/experimental.d.ts +0 -9
- package/dist/lib/experimental.js +18 -17
- package/dist/lib/launcher-config.d.ts +7 -0
- package/dist/lib/launcher-config.js +21 -0
- package/dist/lib/scan/caps.d.ts +35 -0
- package/dist/lib/scan/caps.js +67 -0
- package/dist/lib/scan/credential.d.ts +37 -0
- package/dist/lib/scan/credential.js +104 -0
- package/dist/lib/scan/failure.d.ts +10 -0
- package/dist/lib/scan/failure.js +43 -0
- package/dist/lib/scan/pr-source.d.ts +57 -0
- package/dist/lib/scan/pr-source.js +130 -0
- package/dist/lib/scan/record.d.ts +49 -0
- package/dist/lib/scan/record.js +85 -0
- package/dist/lib/scan/report-email.d.ts +92 -0
- package/dist/lib/scan/report-email.js +144 -0
- package/dist/lib/scan/report.d.ts +13 -0
- package/dist/lib/scan/report.js +30 -0
- package/dist/lib/scan/scan.d.ts +64 -0
- package/dist/lib/scan/scan.js +182 -0
- package/dist/lib/scan/share.d.ts +38 -0
- package/dist/lib/scan/share.js +47 -0
- package/dist/lib/scan/spend/ai-tool-detect.d.ts +6 -0
- package/dist/lib/scan/spend/ai-tool-detect.js +18 -0
- package/dist/lib/scan/spend/anthropic-usage.d.ts +57 -0
- package/dist/lib/scan/spend/anthropic-usage.js +244 -0
- package/dist/lib/scan/spend/cost-corpus.v1.d.ts +56 -0
- package/dist/lib/scan/spend/cost-corpus.v1.js +64 -0
- package/dist/lib/scan/spend/prices.d.ts +33 -0
- package/dist/lib/scan/spend/prices.js +57 -0
- package/dist/lib/scan/spend/spend-estimate.d.ts +30 -0
- package/dist/lib/scan/spend/spend-estimate.js +70 -0
- package/dist/lib/scan/spend/spend-tiers.d.ts +25 -0
- package/dist/lib/scan/spend/spend-tiers.js +42 -0
- package/dist/lib/scan/spend/token-rate.d.ts +30 -0
- package/dist/lib/scan/spend/token-rate.js +54 -0
- package/dist/lib/session-key.d.ts +41 -0
- package/dist/lib/session-key.js +124 -0
- package/dist/lib/subscription-login.d.ts +15 -0
- package/dist/lib/subscription-login.js +28 -1
- package/dist/rc-key-401.mjs +75 -0
- package/dist/rc-proxy.mjs +221 -25
- package/dist/vendor/durable-contract/index.js +240 -18
- package/dist/vendor/shared/durable-contract/admission.d.ts +240 -0
- package/dist/vendor/shared/durable-contract/admission.js +533 -0
- package/dist/vendor/shared/durable-contract/arm.d.ts +51 -0
- package/dist/vendor/shared/durable-contract/arm.js +133 -0
- package/dist/vendor/shared/durable-contract/canonical.d.ts +29 -0
- package/dist/vendor/shared/durable-contract/canonical.js +98 -0
- package/dist/vendor/shared/durable-contract/cell-id.d.ts +22 -0
- package/dist/vendor/shared/durable-contract/cell-id.js +38 -0
- package/dist/vendor/shared/durable-contract/cli-output.d.ts +342 -0
- package/dist/vendor/shared/durable-contract/cli-output.js +201 -0
- package/dist/vendor/shared/durable-contract/cli-surface.d.ts +119 -0
- package/dist/vendor/shared/durable-contract/cli-surface.js +270 -0
- package/dist/vendor/shared/durable-contract/codes.d.ts +537 -0
- package/dist/vendor/shared/durable-contract/codes.js +475 -0
- package/dist/vendor/shared/durable-contract/constants.d.ts +153 -0
- package/dist/vendor/shared/durable-contract/constants.js +179 -0
- package/dist/vendor/shared/durable-contract/doors.d.ts +119 -0
- package/dist/vendor/shared/durable-contract/doors.js +249 -0
- package/dist/vendor/shared/durable-contract/envelope.d.ts +103 -0
- package/dist/vendor/shared/durable-contract/envelope.js +317 -0
- package/dist/vendor/shared/durable-contract/events.d.ts +147 -0
- package/dist/vendor/shared/durable-contract/events.js +630 -0
- package/dist/vendor/shared/durable-contract/executor-state.d.ts +41 -0
- package/dist/vendor/shared/durable-contract/executor-state.js +32 -0
- package/dist/vendor/shared/durable-contract/fixlines.d.ts +318 -0
- package/dist/vendor/shared/durable-contract/fixlines.js +483 -0
- package/dist/vendor/shared/durable-contract/freeze-record.d.ts +787 -0
- package/dist/vendor/shared/durable-contract/freeze-record.js +361 -0
- package/dist/vendor/shared/durable-contract/index.d.ts +36 -0
- package/dist/vendor/shared/durable-contract/index.js +37 -0
- package/dist/vendor/shared/durable-contract/journal-approvals.d.ts +29 -0
- package/dist/vendor/shared/durable-contract/journal-approvals.js +60 -0
- package/dist/vendor/shared/durable-contract/keys.d.ts +24 -0
- package/dist/vendor/shared/durable-contract/keys.js +66 -0
- package/dist/vendor/shared/durable-contract/lock.d.ts +128 -0
- package/dist/vendor/shared/durable-contract/lock.js +151 -0
- package/dist/vendor/shared/durable-contract/names.d.ts +25 -0
- package/dist/vendor/shared/durable-contract/names.js +78 -0
- package/dist/vendor/shared/durable-contract/owner-verbs.d.ts +175 -0
- package/dist/vendor/shared/durable-contract/owner-verbs.js +403 -0
- package/dist/vendor/shared/durable-contract/paths.d.ts +23 -0
- package/dist/vendor/shared/durable-contract/paths.js +35 -0
- package/dist/vendor/shared/durable-contract/pure-fn.d.ts +48 -0
- package/dist/vendor/shared/durable-contract/pure-fn.js +89 -0
- package/dist/vendor/shared/durable-contract/routes.d.ts +205 -0
- package/dist/vendor/shared/durable-contract/routes.js +315 -0
- package/dist/vendor/shared/durable-contract/schema.d.ts +126 -0
- package/dist/vendor/shared/durable-contract/schema.js +441 -0
- package/dist/vendor/shared/durable-contract/seal.d.ts +54 -0
- package/dist/vendor/shared/durable-contract/seal.js +99 -0
- package/dist/vendor/shared/durable-contract/secret-scope.d.ts +28 -0
- package/dist/vendor/shared/durable-contract/secret-scope.js +76 -0
- package/dist/vendor/shared/durable-contract/session-id.d.ts +21 -0
- package/dist/vendor/shared/durable-contract/session-id.js +58 -0
- package/dist/vendor/shared/durable-contract/spec.d.ts +162 -0
- package/dist/vendor/shared/durable-contract/spec.js +286 -0
- package/dist/vendor/shared/durable-contract/states.d.ts +96 -0
- package/dist/vendor/shared/durable-contract/states.js +218 -0
- package/dist/vendor/shared/durable-contract/telemetry.d.ts +94 -0
- package/dist/vendor/shared/durable-contract/telemetry.js +180 -0
- package/dist/vendor/shared/durable-contract/test-mode.d.ts +62 -0
- package/dist/vendor/shared/durable-contract/test-mode.js +140 -0
- package/dist/vendor/shared/durable-contract/turn.d.ts +57 -0
- package/dist/vendor/shared/durable-contract/turn.js +81 -0
- package/dist/vendor/shared/durable-contract/vectors.d.ts +191 -0
- package/dist/vendor/shared/durable-contract/vectors.js +208 -0
- package/package.json +4 -3
- package/plugins/integrity-manifest.json +35 -0
- package/plugins/mnemom/hooks/hooks.json +15 -1
- package/plugins/mnemom/hooks/register.tsx +60 -2
- package/plugins/mnemom/hooks/seat-hello.mjs +116 -0
- package/dist/commands/agent-implicit-notice.d.ts +0 -31
- package/dist/commands/agent-implicit-notice.js +0 -73
package/dist/index.js
CHANGED
|
@@ -37,22 +37,32 @@ import { agentDoctorCommand } from "./commands/agent-doctor.js";
|
|
|
37
37
|
import { agentSetupCommand, parseGovernanceFlag } from "./commands/agent-setup.js";
|
|
38
38
|
import { agentInviteCommand, runAgentInvocation } from "./commands/agent-invite.js";
|
|
39
39
|
import { agentFirstRunCommand, offerFirstRunOnLaunch } from "./commands/agent-first-run.js";
|
|
40
|
-
import { showImplicitDefaultNoticeOnce } from "./commands/agent-implicit-notice.js";
|
|
41
|
-
import { isPrerelease } from "./lib/update/semver.js";
|
|
42
40
|
import { applyConfigToEnv, launcherEntries, loadLauncherConfig, withoutDisabledExperimental, } from "./lib/launcher-config.js";
|
|
43
|
-
import { loadExperimentalState } from "./lib/cli-config.js";
|
|
44
|
-
import {
|
|
41
|
+
import { loadCliConfig, loadExperimentalState } from "./lib/cli-config.js";
|
|
42
|
+
import { isSeatProxyArgv, runSeatProxyEntry } from "./durable/seat-proxy-entry.js";
|
|
43
|
+
import { assertEnabled, EXPERIMENTAL_CONTRACT, gateCheck, ignoredSettingLines, reportCliError, } from "./lib/experimental.js";
|
|
45
44
|
import { durableVerbOffLines } from "./durable/gate.js";
|
|
46
45
|
import { experimentalDisableCommand, experimentalEnableCommand, experimentalListCommand, runExperimentalMigration, } from "./commands/experimental.js";
|
|
47
|
-
import { parseCompactAt, parseContextProfile,
|
|
46
|
+
import { parseCompactAt, parseContextProfile, resolveImplicit, selectLaunchAgent, splitSessionArg, } from "./lib/agent.js";
|
|
48
47
|
import { wrapCommand } from "./commands/wrap.js";
|
|
49
48
|
import { onboardCommand } from "./commands/onboard.js";
|
|
50
49
|
import { skillsListCommand, skillsDescribeCommand } from "./commands/skills.js";
|
|
51
50
|
import { usageCommand, parseNumericFlag, parseDaysFlag } from "./commands/usage.js";
|
|
51
|
+
import { scanCommand, parseRepoFlags } from "./commands/scan.js";
|
|
52
52
|
import { updateCommand } from "./commands/update.js";
|
|
53
53
|
import { runAction } from "./lib/update/action.js";
|
|
54
54
|
import { configListCommand, configGetCommand, configSetCommand, configUnsetCommand, } from "./commands/config.js";
|
|
55
55
|
import { defaultStartupDeps, maybeRunUpdateHook } from "./lib/update/startup.js";
|
|
56
|
+
import { durableActionGate, durableGate, durableOn, optionShapesOf, } from "./lib/durable/gate.js";
|
|
57
|
+
import { durableSessionsCommand, durableShowCommand } from "./commands/durable-sessions.js";
|
|
58
|
+
import { durablePreflight } from "./lib/durable/launch.js";
|
|
59
|
+
import { durableRefusalExit } from "./lib/durable/refusal.js";
|
|
60
|
+
import { liveDoctorDurableLines, liveLockVerbDeps, liveSessionsReadDeps, liveVerbDeps, } from "./lib/durable/live.js";
|
|
61
|
+
import { amendCommand, containmentCommand, ownerVerbCommand, unlockCommand, } from "./commands/durable-verbs.js";
|
|
62
|
+
import { lockCommand } from "./commands/durable-lock.js";
|
|
63
|
+
import { registerHostCommands } from "./host/commands.js";
|
|
64
|
+
import { hostArgvGate } from "./host/gate.js";
|
|
65
|
+
import { homedir } from "node:os";
|
|
56
66
|
program
|
|
57
67
|
.name("mnemom")
|
|
58
68
|
.description("Transparent AI agent tracing")
|
|
@@ -121,14 +131,11 @@ program
|
|
|
121
131
|
// ── experimental features (lib/experimental.ts) ── While a feature is off its flags and
|
|
122
132
|
// commands are hidden from --help (decided once, at load) and using one fails with a
|
|
123
133
|
// pointer to `mnemom experimental enable <id>` (decided per invocation, in the action).
|
|
124
|
-
|
|
125
|
-
const PRERELEASE_BUILD = isPrerelease(CLI_VERSION);
|
|
126
|
-
const loadAvailableFeatures = () => availableFeatures(loadExperimentalState().enabled, PRERELEASE_BUILD);
|
|
127
|
-
const experimentalAtLoad = loadAvailableFeatures();
|
|
134
|
+
const experimentalAtLoad = loadExperimentalState().enabled;
|
|
128
135
|
const hiddenUnless = (id) => !experimentalAtLoad.includes(id);
|
|
129
136
|
/** preAction guard for a gated command: print the guidance and exit 2 while `id` is off. */
|
|
130
137
|
function requireExperimental(what, id) {
|
|
131
|
-
const message = gateCheck(what, id,
|
|
138
|
+
const message = gateCheck(what, id, loadExperimentalState().enabled);
|
|
132
139
|
if (message) {
|
|
133
140
|
console.error(message);
|
|
134
141
|
process.exit(2);
|
|
@@ -152,6 +159,8 @@ function printAgentHelp(verb) {
|
|
|
152
159
|
: undefined;
|
|
153
160
|
(sub ?? agentCmd).outputHelp();
|
|
154
161
|
}
|
|
162
|
+
// `agent --new` is a durable option: held here so DURABLE_GATED_OPTIONS can name it.
|
|
163
|
+
const agentNewOption = new Option("--new", "EXPERIMENTAL (`mnemom experimental enable durable`): start a fresh session under this name; never continue one").hideHelp(hiddenUnless("durable"));
|
|
155
164
|
const agentCmd = program
|
|
156
165
|
.command("agent [session] [passthrough...]")
|
|
157
166
|
.description("Launch your governed agent (Claude Code in v1) through the Mnemom gateway — governed identity + optional sealed goal contract. Plain `mnemom agent` asks for a session name. " +
|
|
@@ -171,7 +180,7 @@ const agentCmd = program
|
|
|
171
180
|
"platform cards (strictest wins). See `mnemom protection` for that mode.")
|
|
172
181
|
.option("--lead-directed", "Seal the standard lead-directed requirement: own-branch push and draft/ready PR creation, " +
|
|
173
182
|
"from a git worktree, on the lead's direction — not merging. Requires --goal; idempotent.")
|
|
174
|
-
.addOption(new Option("--implicit", "EXPERIMENTAL (`mnemom experimental enable implicit`): implicit goal alignment — the gateway infers the goal from your messages and revises it as you steer (the default while the feature is on
|
|
183
|
+
.addOption(new Option("--implicit", "EXPERIMENTAL (`mnemom experimental enable implicit`): implicit goal alignment — the gateway infers the goal from your messages and revises it as you steer (the default while the feature is on; not combinable with --goal/--requirement/--allow/--forbid/--goal-id/--mode/--lead-directed; the guardrail ceilings still apply)").hideHelp(hiddenUnless("implicit")))
|
|
175
184
|
.option("--no-implicit", "Turn implicit goal alignment OFF for this launch (overrides launcher.toml goal_mode = implicit)")
|
|
176
185
|
.option("--conversation-id <id>", "x-mnemom-conversation-id (default: auto-generated)")
|
|
177
186
|
.option("--cli <name|path>", "Coding-agent CLI to launch: a name or full path (default: claude)")
|
|
@@ -233,6 +242,7 @@ const agentCmd = program
|
|
|
233
242
|
}
|
|
234
243
|
return v;
|
|
235
244
|
}))
|
|
245
|
+
.addOption(agentNewOption)
|
|
236
246
|
.addOption(new Option("--context-handoff", "EXPERIMENTAL (`mnemom experimental enable context-handoff`): register the `handoff(note)` MCP tool and tell the gateway to turn on the context-handoff capability for this session").hideHelp(hiddenUnless("context-handoff")))
|
|
237
247
|
.option("--no-context-handoff", "Keep context handoff off for this launch even when launcher.toml (context_handoff = true) or MNEMOM_AGENT_CONTEXT_HANDOFF turns it on")
|
|
238
248
|
.option("--compaction-intercept", "Turn the compaction intercept on for this launch even when launcher.toml (compaction_intercept = false) or MNEMOM_AGENT_COMPACTION_INTERCEPT=0 turns it off. On by default: the gateway reports the real context size (so Claude Code compacts at its own threshold) and answers the compaction at once from its fold")
|
|
@@ -263,14 +273,18 @@ const agentCmd = program
|
|
|
263
273
|
});
|
|
264
274
|
}
|
|
265
275
|
catch (error) {
|
|
276
|
+
const durableExit = durableRefusalExit(error, {
|
|
277
|
+
out: (l) => process.stdout.write(`${l}\n`),
|
|
278
|
+
err: (l) => console.error(l),
|
|
279
|
+
});
|
|
280
|
+
if (durableExit !== null)
|
|
281
|
+
process.exit(durableExit);
|
|
266
282
|
const report = reportCliError(error);
|
|
267
283
|
console.error(...report.args);
|
|
268
284
|
process.exit(report.code);
|
|
269
285
|
}
|
|
270
286
|
async function launchAgent(scenario) {
|
|
271
287
|
const experimental = loadExperimentalState().enabled;
|
|
272
|
-
// What a flag, key or command may use: the enabled features, plus implicit on `next`.
|
|
273
|
-
const available = availableFeatures(experimental, PRERELEASE_BUILD);
|
|
274
288
|
// The one place the flag's raw string becomes `number | null` (see the argParser's
|
|
275
289
|
// comment for why commander can't carry `null` through parseArg directly). Already
|
|
276
290
|
// validated by the argParser, so this never throws.
|
|
@@ -278,7 +292,7 @@ const agentCmd = program
|
|
|
278
292
|
// Sub-verb: `mnemom agent config …` manages persistent settings and never
|
|
279
293
|
// launches. (A scenario literally named "config" is reserved for this.)
|
|
280
294
|
if (scenario === "config") {
|
|
281
|
-
await agentConfigCommand(passthrough, { enabled:
|
|
295
|
+
await agentConfigCommand(passthrough, { enabled: experimental });
|
|
282
296
|
return;
|
|
283
297
|
}
|
|
284
298
|
// Sub-verb: `mnemom agent slack …` posts/receives Slack messages as this
|
|
@@ -298,7 +312,8 @@ const agentCmd = program
|
|
|
298
312
|
used: opts.contextHandoff === true,
|
|
299
313
|
},
|
|
300
314
|
{ what: "--implicit", id: "implicit", used: opts.implicit === true },
|
|
301
|
-
|
|
315
|
+
{ what: "--new", id: "durable", used: opts.new === true },
|
|
316
|
+
], experimental);
|
|
302
317
|
if (opts.gateway)
|
|
303
318
|
process.env.MNEMOM_AGENT_GATEWAY = opts.gateway;
|
|
304
319
|
// Persistent settings (~/.mnemom/launcher.toml) sit UNDER env and flags:
|
|
@@ -311,11 +326,11 @@ const agentCmd = program
|
|
|
311
326
|
for (const line of ignoredSettingLines({
|
|
312
327
|
entries: launcherEntries(rawCfg),
|
|
313
328
|
env: process.env,
|
|
314
|
-
enabled:
|
|
329
|
+
enabled: experimental,
|
|
315
330
|
})) {
|
|
316
331
|
console.error(line);
|
|
317
332
|
}
|
|
318
|
-
const cfg = withoutDisabledExperimental(rawCfg,
|
|
333
|
+
const cfg = withoutDisabledExperimental(rawCfg, experimental);
|
|
319
334
|
applyConfigToEnv(cfg, process.env);
|
|
320
335
|
// Sub-verb: `mnemom agent doctor` runs a read-only preflight and never
|
|
321
336
|
// launches. Placed after config load so it reports the effective settings.
|
|
@@ -325,7 +340,11 @@ const agentCmd = program
|
|
|
325
340
|
return;
|
|
326
341
|
}
|
|
327
342
|
if (scenario === "doctor") {
|
|
328
|
-
await agentDoctorCommand({
|
|
343
|
+
await agentDoctorCommand({
|
|
344
|
+
cli: opts.cli,
|
|
345
|
+
agent: program.opts().agent ?? cfg.agent,
|
|
346
|
+
...(experimental.includes("durable") ? { durable: liveDoctorDurableLines } : {}),
|
|
347
|
+
});
|
|
329
348
|
return;
|
|
330
349
|
}
|
|
331
350
|
// Validated up front so a typo fails before any sign-in or provisioning.
|
|
@@ -348,22 +367,14 @@ const agentCmd = program
|
|
|
348
367
|
const numToStr = (n) => n === undefined ? undefined : String(n);
|
|
349
368
|
// Implicit mode: --implicit / --no-implicit win; a --goal statement seals
|
|
350
369
|
// (the standing config default never overrides it); else launcher.toml
|
|
351
|
-
// `goal_mode`; else implicit while the `implicit` feature is on
|
|
352
|
-
//
|
|
353
|
-
|
|
354
|
-
const goalMode = resolveImplicitSource({
|
|
370
|
+
// `goal_mode`; else implicit while the `implicit` feature is on, off while it is
|
|
371
|
+
// off. Pure + unit-tested in lib/agent.ts.
|
|
372
|
+
const implicit = resolveImplicit({
|
|
355
373
|
goal: opts.goal,
|
|
356
374
|
implicit: opts.implicit,
|
|
357
375
|
configGoalMode: cfg.goalMode,
|
|
358
376
|
experimentalOn: experimental.includes("implicit"),
|
|
359
|
-
prerelease: PRERELEASE_BUILD,
|
|
360
|
-
print: passthroughIsPrint(passthrough),
|
|
361
377
|
});
|
|
362
|
-
const implicit = goalMode.implicit;
|
|
363
|
-
// The T16 default tells the user once, the first time it applies.
|
|
364
|
-
if (implicit && goalMode.source === "prerelease") {
|
|
365
|
-
showImplicitDefaultNoticeOnce({ dryRun: opts.dryRun });
|
|
366
|
-
}
|
|
367
378
|
// Config guardrails apply only when goal alignment is actually intended (a
|
|
368
379
|
// --goal is present, or implicit mode — where they ride on the mode header),
|
|
369
380
|
// so a saved ceiling never forces an unrequested contract (which would
|
|
@@ -373,6 +384,20 @@ const agentCmd = program
|
|
|
373
384
|
// shadows a subcommand `--agent` under commander@12 — the MNE-238 class),
|
|
374
385
|
// exactly as status/logs/onboard read it.
|
|
375
386
|
const parentOpts = program.opts();
|
|
387
|
+
// Durable (gate on only, BACKBONE C1): refusals decided before any registry call or spawn
|
|
388
|
+
// (nested launch, --server, the S1 name grammar); the registry plan runs in agentCommand.
|
|
389
|
+
const durableOn = experimental.includes("durable");
|
|
390
|
+
const durableKey = cfg.durable ?? "off";
|
|
391
|
+
if (durableOn) {
|
|
392
|
+
const refusal = durablePreflight({
|
|
393
|
+
name: scenario,
|
|
394
|
+
env: process.env,
|
|
395
|
+
server: opts.server === true,
|
|
396
|
+
launcherKey: durableKey,
|
|
397
|
+
});
|
|
398
|
+
if (refusal !== null)
|
|
399
|
+
throw refusal;
|
|
400
|
+
}
|
|
376
401
|
// First interactive launch only: offer (opt-in) the local look at what Mnemom
|
|
377
402
|
// would have saved. Tracked in ~/.mnemom/first-run.json; never blocks the launch.
|
|
378
403
|
await offerFirstRunOnLaunch({ dryRun: opts.dryRun });
|
|
@@ -422,6 +447,9 @@ const agentCmd = program
|
|
|
422
447
|
keySource: cfg.keySource,
|
|
423
448
|
passthrough,
|
|
424
449
|
dryRun: opts.dryRun,
|
|
450
|
+
...(durableOn
|
|
451
|
+
? { durable: { launcherKey: durableKey, newSession: opts.new === true } }
|
|
452
|
+
: {}),
|
|
425
453
|
});
|
|
426
454
|
}
|
|
427
455
|
});
|
|
@@ -847,6 +875,7 @@ policyCmd
|
|
|
847
875
|
// ============================================================================
|
|
848
876
|
// Agent management — sub-verbs of `mnemom agent` (the launcher above): list / claim / move.
|
|
849
877
|
// ============================================================================
|
|
878
|
+
const agentHostCmd = registerHostCommands(agentCmd, hiddenUnless("durable"));
|
|
850
879
|
agentCmd
|
|
851
880
|
.command("list")
|
|
852
881
|
.description("List the agents in your active org (set with `mnemom org use`), or every org you belong to if none is set (ADR-062 org-scoped)")
|
|
@@ -940,13 +969,25 @@ const agentSessionsCmd = agentCmd
|
|
|
940
969
|
.option("--json", "Output the rows as JSON instead of a table")
|
|
941
970
|
.action(async (opts) => {
|
|
942
971
|
try {
|
|
943
|
-
|
|
972
|
+
const ledger = async () => {
|
|
973
|
+
await agentSessionsCommand({ all: opts.all, json: opts.json }, liveSessionDeps);
|
|
974
|
+
return 0;
|
|
975
|
+
};
|
|
976
|
+
// Durable on: the server registry (C01-R12); off: the ledger, exactly as before.
|
|
977
|
+
if (durableOn(loadExperimentalState().enabled))
|
|
978
|
+
process.exitCode = await durableSessionsCommand(opts, liveSessionsReadDeps(), ledger);
|
|
979
|
+
else
|
|
980
|
+
await ledger();
|
|
944
981
|
}
|
|
945
982
|
catch (error) {
|
|
946
983
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
947
984
|
process.exit(1);
|
|
948
985
|
}
|
|
949
986
|
});
|
|
987
|
+
// `sessions` has no subcommands before M1: its usage line is captured here, before any durable
|
|
988
|
+
// sub-verb (C4 `adopt`, C1 `unlock`) is added, and restored once they are all registered while
|
|
989
|
+
// durable is off (commander counts hidden subcommands in `[command]`; C17-R09).
|
|
990
|
+
const agentSessionsPreM1Usage = agentSessionsCmd.usage();
|
|
950
991
|
/** preAction (and --help) guard for a durable verb: while durable is off it does not exist (C14-R22). */
|
|
951
992
|
function requireDurableVerb(word, what) {
|
|
952
993
|
const lines = durableVerbOffLines(word, what, loadExperimentalState().enabled);
|
|
@@ -986,11 +1027,14 @@ const agentSessionsAdoptCmd = agentSessionsCmd
|
|
|
986
1027
|
}
|
|
987
1028
|
});
|
|
988
1029
|
/**
|
|
989
|
-
* The durable-gated commands (BACKBONE Flags/CLI: off lists no durable verb). The
|
|
990
|
-
* command-tree.json leaves them out whatever the generating machine's experimental
|
|
991
|
-
* (scripts/gen-command-tree.mjs);
|
|
1030
|
+
* The durable-gated commands and options (BACKBONE Flags/CLI: off lists no durable verb). The
|
|
1031
|
+
* committed command-tree.json leaves them out whatever the generating machine's experimental
|
|
1032
|
+
* state (scripts/gen-command-tree.mjs); --help shows them only once durable is enabled. A piece
|
|
1033
|
+
* that registers another durable verb or option adds it here.
|
|
992
1034
|
*/
|
|
993
|
-
|
|
1035
|
+
const durableGatedCommands = new Set([agentHostCmd, agentSessionsAdoptCmd]);
|
|
1036
|
+
export const DURABLE_GATED_COMMANDS = durableGatedCommands;
|
|
1037
|
+
export const DURABLE_GATED_OPTIONS = new Set([agentNewOption]);
|
|
994
1038
|
// commander answers --help before preAction: gate the help too, so the verb does not exist while off.
|
|
995
1039
|
const adoptOutputHelp = agentSessionsAdoptCmd.outputHelp.bind(agentSessionsAdoptCmd);
|
|
996
1040
|
agentSessionsAdoptCmd.outputHelp = ((...args) => {
|
|
@@ -1016,13 +1060,92 @@ agentCmd
|
|
|
1016
1060
|
}
|
|
1017
1061
|
followIntervalMs = seconds * 1000;
|
|
1018
1062
|
}
|
|
1019
|
-
|
|
1063
|
+
const ledger = async () => {
|
|
1064
|
+
await agentShowCommand(ref, { json: opts.json, follow: opts.follow, followIntervalMs }, liveSessionDeps);
|
|
1065
|
+
return 0;
|
|
1066
|
+
};
|
|
1067
|
+
// Durable on: resolve the name through the registry (C01-R12, R24); --follow and a ref
|
|
1068
|
+
// the registry does not know stay on the ledger view.
|
|
1069
|
+
if (durableOn(loadExperimentalState().enabled) && !opts.follow)
|
|
1070
|
+
process.exitCode = await durableShowCommand(ref, { json: opts.json }, liveSessionsReadDeps(), ledger);
|
|
1071
|
+
else
|
|
1072
|
+
await ledger();
|
|
1020
1073
|
}
|
|
1021
1074
|
catch (error) {
|
|
1022
1075
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
1023
1076
|
process.exit(1);
|
|
1024
1077
|
}
|
|
1025
1078
|
});
|
|
1079
|
+
/**
|
|
1080
|
+
* Read an option value the user typed on this parse from `cmd`, then clear it: commander keeps
|
|
1081
|
+
* option values on the command object across parses, so a value left behind would carry into the
|
|
1082
|
+
* next parse of the same program (another amend, or a launch that reads the guardrail).
|
|
1083
|
+
*/
|
|
1084
|
+
function takeParentOption(cmd, key) {
|
|
1085
|
+
if (cmd.getOptionValueSource(key) !== "cli")
|
|
1086
|
+
return undefined;
|
|
1087
|
+
const v = cmd.getOptionValue(key);
|
|
1088
|
+
cmd.setOptionValueWithSource(key, undefined, "default");
|
|
1089
|
+
return v;
|
|
1090
|
+
}
|
|
1091
|
+
// ── durable verbs (BACKBONE C1; EXPERIMENTAL `durable`) ── hidden while durable is off, and
|
|
1092
|
+
// unreachable then: runEntrypoint's durable gate exits 2 on these words before commander parses.
|
|
1093
|
+
// Each handler returns its exit status (refusals rendered by lib/durable/refusal.ts).
|
|
1094
|
+
{
|
|
1095
|
+
const hidden = hiddenUnless("durable");
|
|
1096
|
+
// The action-level gate (C17): while durable is off the action exits 2 with the pointer before it
|
|
1097
|
+
// builds any client, for any argv shape that got past runEntrypoint's scan.
|
|
1098
|
+
const exitWith = async (what, run) => {
|
|
1099
|
+
const gated = durableActionGate(what, loadExperimentalState().enabled);
|
|
1100
|
+
if (gated !== null) {
|
|
1101
|
+
console.error(gated);
|
|
1102
|
+
process.exitCode = 2;
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
process.exitCode = await run();
|
|
1106
|
+
};
|
|
1107
|
+
const gate = (cmd) => {
|
|
1108
|
+
durableGatedCommands.add(cmd);
|
|
1109
|
+
return cmd;
|
|
1110
|
+
};
|
|
1111
|
+
gate(agentCmd.command("lock <name>", { hidden }))
|
|
1112
|
+
.description("EXPERIMENTAL (durable): lock a session so the host daemon keeps it running")
|
|
1113
|
+
.option("--own-agent", "Lock even though other sessions share the agent (they are locked too)")
|
|
1114
|
+
.option("--json", "Output the answer as JSON")
|
|
1115
|
+
.action((name, o) => exitWith("`mnemom agent lock`", () => lockCommand(name, o, liveLockVerbDeps())));
|
|
1116
|
+
for (const verb of ["pause", "resume", "done", "kill"]) {
|
|
1117
|
+
gate(agentCmd.command(`${verb} <name>`, { hidden }))
|
|
1118
|
+
.description(`EXPERIMENTAL (durable): ${verb} a session`)
|
|
1119
|
+
.option("--json", "Output the answer as JSON")
|
|
1120
|
+
.action((name, o) => exitWith(`\`mnemom agent ${verb}\``, () => ownerVerbCommand(verb, name, o, liveVerbDeps())));
|
|
1121
|
+
}
|
|
1122
|
+
gate(agentCmd.command("amend <name>", { hidden }))
|
|
1123
|
+
.description("EXPERIMENTAL (durable): lower a session's limits, or raise its budget (approved by device step)")
|
|
1124
|
+
.option("--budget <usd>", "New budget in USD")
|
|
1125
|
+
.option("--turns <n>", "New turn ceiling (lowering only)")
|
|
1126
|
+
.option("--json", "Output the answer as JSON")
|
|
1127
|
+
.action((name, o) => {
|
|
1128
|
+
// `agent` has its own --budget (the launch guardrail), and commander hands an option the
|
|
1129
|
+
// parent knows to the parent wherever it sits in argv: amend's --budget lands there.
|
|
1130
|
+
const budget = takeParentOption(agentCmd, "budget");
|
|
1131
|
+
return exitWith("`mnemom agent amend`", () => amendCommand(name, { ...o, budget }, liveVerbDeps()));
|
|
1132
|
+
});
|
|
1133
|
+
const containmentCmd = gate(agentCmd.command("containment", { hidden })).description("EXPERIMENTAL (durable): org admin containment of an agent (pause | resume)");
|
|
1134
|
+
for (const verb of ["pause", "resume"]) {
|
|
1135
|
+
containmentCmd
|
|
1136
|
+
.command(`${verb} <agent>`)
|
|
1137
|
+
.description(`${verb} every session of an agent (org admin, signed in)`)
|
|
1138
|
+
.action((agent) => exitWith(`\`mnemom agent containment ${verb}\``, () => containmentCommand(verb, agent, liveVerbDeps())));
|
|
1139
|
+
}
|
|
1140
|
+
// `sessions` has no subcommands before M1: keep its usage line byte-identical (commander
|
|
1141
|
+
// counts hidden subcommands in `[command]`). Captured before C4's `adopt` was added too.
|
|
1142
|
+
const sessionsUsage = agentSessionsPreM1Usage;
|
|
1143
|
+
gate(agentSessionsCmd.command("unlock <name>", { hidden }))
|
|
1144
|
+
.description("EXPERIMENTAL (durable): unlock a locked session back to tracked (device step)")
|
|
1145
|
+
.action((name) => exitWith("`mnemom agent sessions unlock`", () => unlockCommand(name, liveVerbDeps())));
|
|
1146
|
+
if (hidden)
|
|
1147
|
+
agentSessionsCmd.usage(sessionsUsage);
|
|
1148
|
+
}
|
|
1026
1149
|
// `mnemom agent run --watch|--once` — the thin runner (ruling 34.12; Doors W-L13): claim served-phase
|
|
1027
1150
|
// jobs from the org's ready pool and run their signed phases. Exit 0 done/no_job, 1 failed,
|
|
1028
1151
|
// 2 usage, 3 refused.
|
|
@@ -2196,6 +2319,40 @@ program
|
|
|
2196
2319
|
process.exit(1);
|
|
2197
2320
|
}
|
|
2198
2321
|
});
|
|
2322
|
+
program
|
|
2323
|
+
.command("scan")
|
|
2324
|
+
.description("Read-only local scan of GitHub PR metadata; the report is emailed to you every time (counts only, no repo names) and Mnemom keeps nothing at share level none")
|
|
2325
|
+
.option("--repo <owner/name...>", "Repo to scan (repeatable or comma-separated)")
|
|
2326
|
+
.option("--start <YYYY-MM-DD>", "Period start (default: today)")
|
|
2327
|
+
.option("--end <YYYY-MM-DD>", "Period end (default: today)")
|
|
2328
|
+
.option("--share <level>", "summary | full | none (default: ask)")
|
|
2329
|
+
.option("--cto-email <email>", "CTO who receives the report (required unless you are the CTO; asked when omitted)")
|
|
2330
|
+
.option("--monthly-spend <usd>", "Your own approximate monthly AI spend (self-reported; never sent or saved; needs MNEMOM_ORG_SCAN_MODE=true)")
|
|
2331
|
+
.option("--anthropic-admin-key", "Ask (masked) for your Anthropic admin key and read measured usage with it, locally; or set ANTHROPIC_ADMIN_KEY. Never stored, logged or sent anywhere but api.anthropic.com (needs MNEMOM_ORG_SCAN_MODE=true)")
|
|
2332
|
+
.option("--no-anthropic-usage", "Decline Anthropic usage and be asked for a monthly figure (needs MNEMOM_ORG_SCAN_MODE=true)")
|
|
2333
|
+
.option("--org <org_id>", "Your org id; the report is emailed to you for this org (default: your only organization, else the scan stops and asks). Also selects the Record totals preview (needs MNEMOM_ORG_SCAN_MODE=true)")
|
|
2334
|
+
.action(async (options) => {
|
|
2335
|
+
try {
|
|
2336
|
+
const repos = parseRepoFlags(options.repo);
|
|
2337
|
+
if (!repos)
|
|
2338
|
+
throw new Error("--repo owner/name is required (repeatable)");
|
|
2339
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
2340
|
+
await scanCommand({
|
|
2341
|
+
repos,
|
|
2342
|
+
period: { start: options.start ?? options.end ?? today, end: options.end ?? today },
|
|
2343
|
+
share: options.share,
|
|
2344
|
+
ctoEmail: options.ctoEmail,
|
|
2345
|
+
monthlySpend: options.monthlySpend,
|
|
2346
|
+
noAnthropicUsage: options.anthropicUsage === false,
|
|
2347
|
+
anthropicAdminKey: options.anthropicAdminKey === true,
|
|
2348
|
+
org: options.org,
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
catch (error) {
|
|
2352
|
+
console.error("Error:", error instanceof Error ? error.message : "scan failed");
|
|
2353
|
+
process.exit(1);
|
|
2354
|
+
}
|
|
2355
|
+
});
|
|
2199
2356
|
// ============================================================================
|
|
2200
2357
|
// update + config — CLI auto-update (channel latest|next, mode auto|notify|off)
|
|
2201
2358
|
//
|
|
@@ -2256,6 +2413,13 @@ export { program };
|
|
|
2256
2413
|
// Parse argv only when invoked as the CLI entrypoint — not when imported.
|
|
2257
2414
|
// The symlink-safe guard lives in ./lib/entrypoint so it can be unit-tested
|
|
2258
2415
|
// without executing this module's top-level parse().
|
|
2416
|
+
/**
|
|
2417
|
+
* The value-taking options of the program, `agent` and `agent sessions`: the durable gate steps over
|
|
2418
|
+
* them (and their values) to find the verb word, as commander does before it dispatches.
|
|
2419
|
+
*/
|
|
2420
|
+
export function agentOptionShapes() {
|
|
2421
|
+
return optionShapesOf([program, agentCmd, agentSessionsCmd]);
|
|
2422
|
+
}
|
|
2259
2423
|
/**
|
|
2260
2424
|
* The entrypoint dispatch. `mnemom agent slack …` owns its own flags (--thread,
|
|
2261
2425
|
* --channel, …), which the `agent` launcher options would otherwise reject as
|
|
@@ -2263,8 +2427,41 @@ export { program };
|
|
|
2263
2427
|
* verbatim. Exported (not auto-run) so the bypass is unit-testable.
|
|
2264
2428
|
*/
|
|
2265
2429
|
export function runEntrypoint(argv = process.argv.slice(2), migrate = runExperimentalMigration) {
|
|
2430
|
+
// The durable seat proxy (C3) is spawned by the host daemon; its stdout carries only READY, so it
|
|
2431
|
+
// runs before the migration and the update hook (durable/seat-proxy-entry.ts holds the gate).
|
|
2432
|
+
if (isSeatProxyArgv(argv)) {
|
|
2433
|
+
runSeatProxyEntry(argv, {
|
|
2434
|
+
stored: () => loadCliConfig().experimental,
|
|
2435
|
+
stderr: (line) => void process.stderr.write(line),
|
|
2436
|
+
exit: (code) => process.exit(code),
|
|
2437
|
+
run: async (rest) => (await import("./durable/seat-proxy.js")).seatProxyMain(rest),
|
|
2438
|
+
});
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2266
2441
|
// First run after the upgrade that introduced experimental features: keep on whatever
|
|
2267
2442
|
// launcher.toml already uses (commands/experimental.ts; never throws).
|
|
2443
|
+
// `mnemom agent host …` with durable off: gated before commander's help/usage paths and before
|
|
2444
|
+
// the one-time migration below can write config.json (C17-R10: no HOME write). C2 owns the
|
|
2445
|
+
// `host` word (config.json-only gate for `host run`, C12-R25/R39), so the C1 verb-word gate
|
|
2446
|
+
// below steps aside for it (integration r1: the C1 gate documents "until C2 registers its handler").
|
|
2447
|
+
const hostGate = hostArgvGate(argv, { env: process.env, home: homedir() });
|
|
2448
|
+
if (hostGate) {
|
|
2449
|
+
console.error(hostGate.message);
|
|
2450
|
+
process.exit(hostGate.code);
|
|
2451
|
+
return;
|
|
2452
|
+
}
|
|
2453
|
+
// Durable verb words while `durable` is off: exit 2 with the pointer before commander can
|
|
2454
|
+
// answer --help, and before the one-time migration below can write config.json (BACKBONE
|
|
2455
|
+
// Flags/CLI: no HTTP, no HOME write, no process).
|
|
2456
|
+
const hostArgv = argv[0] === "agent" && argv[1] === "host";
|
|
2457
|
+
const durableGateMessage = hostArgv
|
|
2458
|
+
? null
|
|
2459
|
+
: durableGate(argv, loadExperimentalState().enabled, agentOptionShapes());
|
|
2460
|
+
if (durableGateMessage !== null) {
|
|
2461
|
+
console.error(durableGateMessage);
|
|
2462
|
+
process.exit(2);
|
|
2463
|
+
return;
|
|
2464
|
+
}
|
|
2268
2465
|
migrate();
|
|
2269
2466
|
if (argv[0] === "agent" && argv[1] === "slack") {
|
|
2270
2467
|
requireExperimental("`mnemom agent slack`", "slack");
|
package/dist/lib/agent.d.ts
CHANGED
|
@@ -925,47 +925,29 @@ export declare function buildHandoffMcpConfigJson(p: HandoffMcpParams): string;
|
|
|
925
925
|
* per-session statement, so it is always a per-launch `--goal`.
|
|
926
926
|
*/
|
|
927
927
|
export type GoalModeDefault = "implicit" | "off";
|
|
928
|
-
/**
|
|
929
|
-
* Where a launch's goal mode came from (`resolveImplicitSource`). `prerelease` is door
|
|
930
|
-
* one's T16 default (decisions 12 and 22): implicit by default on a `-next.N` build with
|
|
931
|
-
* nothing configured. It is the only source that shows the one-time notice.
|
|
932
|
-
*/
|
|
933
|
-
export type ImplicitSource = "flag" | "goal" | "config" | "experimental" | "prerelease" | "default";
|
|
934
|
-
/** Does a Claude Code passthrough run headless (`-p` / `--print`)? */
|
|
935
|
-
export declare function passthroughIsPrint(passthrough: readonly string[]): boolean;
|
|
936
928
|
/**
|
|
937
929
|
* Is this launch implicit-mode? Precedence, highest wins:
|
|
938
930
|
* 1. an explicit flag — `--implicit` (true) or `--no-implicit` (false);
|
|
939
931
|
* 2. a `--goal` statement — a sealed contract is a per-launch choice that the
|
|
940
|
-
* standing config default must never silently override
|
|
941
|
-
* runs both modes;
|
|
932
|
+
* standing config default must never silently override;
|
|
942
933
|
* 3. the config default `goal_mode` — `"off"` turns alignment off, `"implicit"`
|
|
943
934
|
* keeps it implicit;
|
|
944
|
-
* 4. with the `implicit` experimental feature ON, IMPLICIT
|
|
945
|
-
*
|
|
946
|
-
*
|
|
947
|
-
*
|
|
935
|
+
* 4. with the `implicit` experimental feature ON, IMPLICIT: the gateway infers
|
|
936
|
+
* the goal from the user's own messages (turn it off for a launch with
|
|
937
|
+
* `--no-implicit`, or standing with `goal_mode = "off"`); with it OFF (the
|
|
938
|
+
* default), OFF.
|
|
948
939
|
* Pure so every arm is unit-tested; the caller passes the resolved value on to
|
|
949
940
|
* `assembleContract` / `buildGoalModeHeader` (which still refuse `--implicit`
|
|
950
941
|
* combined with a contract flag — that conflict is EXPLICIT and is reported).
|
|
951
942
|
*/
|
|
952
|
-
export declare function
|
|
943
|
+
export declare function resolveImplicit(opts: {
|
|
953
944
|
goal?: string;
|
|
954
945
|
implicit?: boolean;
|
|
955
946
|
configGoalMode?: GoalModeDefault;
|
|
956
947
|
/**
|
|
957
948
|
* Is the `implicit` experimental feature on? Off ⇒ the default is OFF and
|
|
958
949
|
* `goal_mode = implicit` is ignored (`--implicit` is refused upstream, before
|
|
959
|
-
* this runs)
|
|
950
|
+
* this runs). Omitted ⇒ on.
|
|
960
951
|
*/
|
|
961
952
|
experimentalOn?: boolean;
|
|
962
|
-
|
|
963
|
-
prerelease?: boolean;
|
|
964
|
-
/** Does the launch run Claude Code headless (`-p`)? `passthroughIsPrint`. */
|
|
965
|
-
print?: boolean;
|
|
966
|
-
}): {
|
|
967
|
-
implicit: boolean;
|
|
968
|
-
source: ImplicitSource;
|
|
969
|
-
};
|
|
970
|
-
/** `resolveImplicitSource(opts).implicit`. */
|
|
971
|
-
export declare function resolveImplicit(opts: Parameters<typeof resolveImplicitSource>[0]): boolean;
|
|
953
|
+
}): boolean;
|
package/dist/lib/agent.js
CHANGED
|
@@ -1353,42 +1353,27 @@ export function buildHandoffMcpConfig(p) {
|
|
|
1353
1353
|
export function buildHandoffMcpConfigJson(p) {
|
|
1354
1354
|
return JSON.stringify(buildHandoffMcpConfig(p));
|
|
1355
1355
|
}
|
|
1356
|
-
/** Does a Claude Code passthrough run headless (`-p` / `--print`)? */
|
|
1357
|
-
export function passthroughIsPrint(passthrough) {
|
|
1358
|
-
return passthrough.some((a) => a === "-p" || a === "--print" || a.startsWith("--print="));
|
|
1359
|
-
}
|
|
1360
1356
|
/**
|
|
1361
1357
|
* Is this launch implicit-mode? Precedence, highest wins:
|
|
1362
1358
|
* 1. an explicit flag — `--implicit` (true) or `--no-implicit` (false);
|
|
1363
1359
|
* 2. a `--goal` statement — a sealed contract is a per-launch choice that the
|
|
1364
|
-
* standing config default must never silently override
|
|
1365
|
-
* runs both modes;
|
|
1360
|
+
* standing config default must never silently override;
|
|
1366
1361
|
* 3. the config default `goal_mode` — `"off"` turns alignment off, `"implicit"`
|
|
1367
1362
|
* keeps it implicit;
|
|
1368
|
-
* 4. with the `implicit` experimental feature ON, IMPLICIT
|
|
1369
|
-
*
|
|
1370
|
-
*
|
|
1371
|
-
*
|
|
1363
|
+
* 4. with the `implicit` experimental feature ON, IMPLICIT: the gateway infers
|
|
1364
|
+
* the goal from the user's own messages (turn it off for a launch with
|
|
1365
|
+
* `--no-implicit`, or standing with `goal_mode = "off"`); with it OFF (the
|
|
1366
|
+
* default), OFF.
|
|
1372
1367
|
* Pure so every arm is unit-tested; the caller passes the resolved value on to
|
|
1373
1368
|
* `assembleContract` / `buildGoalModeHeader` (which still refuse `--implicit`
|
|
1374
1369
|
* combined with a contract flag — that conflict is EXPLICIT and is reported).
|
|
1375
1370
|
*/
|
|
1376
|
-
export function
|
|
1371
|
+
export function resolveImplicit(opts) {
|
|
1377
1372
|
if (opts.implicit !== undefined)
|
|
1378
|
-
return
|
|
1373
|
+
return opts.implicit;
|
|
1379
1374
|
if (hasText(opts.goal))
|
|
1380
|
-
return
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
if (opts.configGoalMode !== undefined) {
|
|
1385
|
-
return { implicit: opts.configGoalMode === "implicit", source: "config" };
|
|
1386
|
-
}
|
|
1387
|
-
if (experimentalOn)
|
|
1388
|
-
return { implicit: true, source: "experimental" };
|
|
1389
|
-
return { implicit: !opts.print, source: opts.print ? "default" : "prerelease" };
|
|
1390
|
-
}
|
|
1391
|
-
/** `resolveImplicitSource(opts).implicit`. */
|
|
1392
|
-
export function resolveImplicit(opts) {
|
|
1393
|
-
return resolveImplicitSource(opts).implicit;
|
|
1375
|
+
return false;
|
|
1376
|
+
if (opts.experimentalOn === false)
|
|
1377
|
+
return false;
|
|
1378
|
+
return opts.configGoalMode !== "off";
|
|
1394
1379
|
}
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -450,6 +450,19 @@ export interface RecordTotals {
|
|
|
450
450
|
row_count: number;
|
|
451
451
|
}
|
|
452
452
|
export declare function getRecordTotals(orgId: string, lineageKey: string, signal?: AbortSignal): Promise<RecordTotals>;
|
|
453
|
+
/** The window form of the totals read (contract i2-totals-window v1.2), the fields the scan preview uses. */
|
|
454
|
+
export interface RecordWindowTotals {
|
|
455
|
+
model_cost_mmu: string;
|
|
456
|
+
mu_charged_mmu: string | null;
|
|
457
|
+
row_count: number;
|
|
458
|
+
as_of: string | null;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* GET /v1/orgs/{org_id}/record/totals?from=&to= — the org's total over a window (at most 30 days,
|
|
462
|
+
* `to` not in the future). Returns the raw body: the caller shape-checks it. A 404 means the org is
|
|
463
|
+
* not in the Record cohort.
|
|
464
|
+
*/
|
|
465
|
+
export declare function getRecordWindowTotals(orgId: string, from: string, to: string, signal?: AbortSignal): Promise<unknown>;
|
|
453
466
|
/**
|
|
454
467
|
* Report one commit to Record's commit index (Doors W1.8, lib/commit-report.ts):
|
|
455
468
|
* `POST /v1/orgs/{org}/record/commits`, body RecordCommit/v1. Returns the HTTP
|
package/dist/lib/api.js
CHANGED
|
@@ -427,6 +427,14 @@ export async function getMe() {
|
|
|
427
427
|
export async function getRecordTotals(orgId, lineageKey, signal) {
|
|
428
428
|
return gFetch(`/v1/orgs/${encodeURIComponent(orgId)}/record/totals?lineage_key=${encodeURIComponent(lineageKey)}`, signal ? { signal } : {}, { notFoundLabel: "Record totals", fallback: "Could not read record totals" });
|
|
429
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* GET /v1/orgs/{org_id}/record/totals?from=&to= — the org's total over a window (at most 30 days,
|
|
432
|
+
* `to` not in the future). Returns the raw body: the caller shape-checks it. A 404 means the org is
|
|
433
|
+
* not in the Record cohort.
|
|
434
|
+
*/
|
|
435
|
+
export async function getRecordWindowTotals(orgId, from, to, signal) {
|
|
436
|
+
return gFetch(`/v1/orgs/${encodeURIComponent(orgId)}/record/totals?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`, signal ? { signal } : {}, { notFoundLabel: "Record totals", fallback: "Could not read record totals" });
|
|
437
|
+
}
|
|
430
438
|
/**
|
|
431
439
|
* Report one commit to Record's commit index (Doors W1.8, lib/commit-report.ts):
|
|
432
440
|
* `POST /v1/orgs/{org}/record/commits`, body RecordCommit/v1. Returns the HTTP
|
|
@@ -65,11 +65,16 @@ export declare const PLUGIN_ENV: {
|
|
|
65
65
|
readonly launcherVersion: "MNEMOM_CC_LAUNCHER_VERSION";
|
|
66
66
|
};
|
|
67
67
|
export type PluginEnvName = (typeof PLUGIN_ENV)[keyof typeof PLUGIN_ENV];
|
|
68
|
+
/**
|
|
69
|
+
* Set to "1" only on a launch with the `durable` experimental gate on (BACKBONE C1): the mod then
|
|
70
|
+
* offers `/mnemom lock`. Absent otherwise, so a launch with durable off has the same env as before.
|
|
71
|
+
*/
|
|
72
|
+
export declare const PLUGIN_DURABLE_ENV = "MNEMOM_CC_DURABLE";
|
|
68
73
|
/**
|
|
69
74
|
* Whether this launch loads the plugin: `--plugin` / `--no-plugin` (an explicit boolean) wins,
|
|
70
75
|
* then MNEMOM_AGENT_PLUGIN (1/true/yes/on ⇒ on), else OFF: the plugin lands dark.
|
|
71
76
|
*/
|
|
72
|
-
export declare function pluginEnabled(optionPlugin: boolean | undefined, env: NodeJS.ProcessEnv): boolean;
|
|
77
|
+
export declare function pluginEnabled(optionPlugin: boolean | undefined, env: NodeJS.ProcessEnv, durable?: boolean): boolean;
|
|
73
78
|
/**
|
|
74
79
|
* The bundled plugin's folder (the one holding `.claude-plugin/plugin.json`), or null when it is
|
|
75
80
|
* missing. Lives at `<package>/plugins/mnemom`, next to `dist/` and `src/`, so it is
|
|
@@ -97,12 +102,16 @@ export interface PluginLaunch {
|
|
|
97
102
|
launcherExec?: readonly string[];
|
|
98
103
|
scenario: string;
|
|
99
104
|
launcherVersion: string;
|
|
105
|
+
/** The `durable` gate is on for this launch (adds PLUGIN_DURABLE_ENV=1). */
|
|
106
|
+
durable?: boolean;
|
|
100
107
|
}
|
|
101
108
|
/**
|
|
102
109
|
* The `MNEMOM_CC_*` block for the child env. Pure: no key, no header, nothing the gateway
|
|
103
110
|
* authenticates with — just what the launch log already prints to stderr.
|
|
104
111
|
*/
|
|
105
|
-
export declare function buildPluginEnv(launch: PluginLaunch): Record<PluginEnvName, string
|
|
112
|
+
export declare function buildPluginEnv(launch: PluginLaunch): Record<PluginEnvName, string> & {
|
|
113
|
+
[PLUGIN_DURABLE_ENV]?: "1";
|
|
114
|
+
};
|
|
106
115
|
/** Writes the block onto a child env in place (the launch shapes all build their env first). */
|
|
107
116
|
export declare function applyPluginEnv(childEnv: NodeJS.ProcessEnv, launch: PluginLaunch): void;
|
|
108
117
|
/**
|