@mnemom/mnemom 0.17.31 → 0.17.32-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-url-proxy.mjs +30 -0
- package/dist/commands/agent-fuel.d.ts +75 -0
- package/dist/commands/agent-fuel.js +298 -0
- package/dist/commands/agent-implicit-notice.d.ts +31 -0
- package/dist/commands/agent-implicit-notice.js +73 -0
- package/dist/commands/agent-session.d.ts +2 -1
- package/dist/commands/agent-session.js +2 -1
- package/dist/commands/agent-share-fixture.d.ts +20 -0
- package/dist/commands/agent-share-fixture.js +134 -0
- package/dist/commands/agent-share.d.ts +87 -0
- package/dist/commands/agent-share.js +251 -0
- package/dist/commands/agent.d.ts +75 -2
- package/dist/commands/agent.js +165 -28
- package/dist/commands/status.js +1 -1
- package/dist/commands/update.js +3 -1
- package/dist/commands/validate.d.ts +1 -1
- package/dist/commands/validate.js +1 -1
- package/dist/index.js +68 -12
- package/dist/lib/agent.d.ts +34 -19
- package/dist/lib/agent.js +41 -32
- package/dist/lib/api.d.ts +66 -0
- package/dist/lib/api.js +50 -10
- package/dist/lib/canonical-json.d.ts +12 -0
- package/dist/lib/canonical-json.js +22 -0
- package/dist/lib/commit-report.d.ts +109 -0
- package/dist/lib/commit-report.js +205 -0
- package/dist/lib/conduct-receipt.d.ts +81 -0
- package/dist/lib/conduct-receipt.js +177 -0
- package/dist/lib/contract-hash.d.ts +61 -0
- package/dist/lib/contract-hash.js +126 -0
- package/dist/lib/experimental.d.ts +10 -1
- package/dist/lib/experimental.js +35 -1
- package/dist/lib/oauth.d.ts +2 -1
- package/dist/lib/oauth.js +2 -1
- package/dist/lib/statusline-bin.d.ts +2 -2
- package/dist/lib/statusline-bin.js +4 -7
- package/dist/lib/statusline-feed.d.ts +33 -0
- package/dist/lib/statusline-feed.js +68 -0
- package/dist/lib/statusline.d.ts +39 -88
- package/dist/lib/statusline.js +58 -250
- package/dist/lib/update/decide.d.ts +22 -3
- package/dist/lib/update/decide.js +35 -12
- package/dist/lib/update/doctor.js +5 -1
- package/dist/lib/update/run.d.ts +2 -0
- package/dist/lib/update/run.js +22 -8
- package/package.json +1 -1
package/dist/commands/agent.js
CHANGED
|
@@ -31,7 +31,10 @@ import { randomUUID } from "node:crypto";
|
|
|
31
31
|
import { tmpdir, homedir, hostname } from "node:os";
|
|
32
32
|
import { basename, join, dirname } from "node:path";
|
|
33
33
|
import { fileURLToPath } from "node:url";
|
|
34
|
-
import {
|
|
34
|
+
import { FEED_ENV, statuslineLaunch } from "../lib/statusline.js";
|
|
35
|
+
import { startFeed } from "../lib/statusline-feed.js";
|
|
36
|
+
import { isPrerelease } from "../lib/update/semver.js";
|
|
37
|
+
import { attributionSettings, COMMIT_REPORT_ENV, commitReportEnabled, realGit, startCommitReporter, } from "../lib/commit-report.js";
|
|
35
38
|
import { ALLOW_AUTOCOMPACT_OFF_ENV, dropAutocompactOffEnv, hasOwnSettingsFlag, mergedSettingsArgs, planAutocompactGuard, } from "../lib/autocompact-guard.js";
|
|
36
39
|
import { getApiUrl, getGatewayUrl, MNEMOM_DIR } from "../lib/config.js";
|
|
37
40
|
import { createApiKey } from "../lib/api.js";
|
|
@@ -41,6 +44,7 @@ import { isLoggedIn } from "../lib/auth.js";
|
|
|
41
44
|
import { loadCliConfig } from "../lib/cli-config.js";
|
|
42
45
|
import { configKeySpec, loadLauncherConfig, writeLauncherConfig } from "../lib/launcher-config.js";
|
|
43
46
|
import { experimentalNotice } from "../lib/experimental.js";
|
|
47
|
+
import { conductReceiptFor } from "../lib/conduct-receipt.js";
|
|
44
48
|
import { fmt } from "../lib/format.js";
|
|
45
49
|
import { askInput, askSelect, askYesNo, isInteractive } from "../lib/prompt.js";
|
|
46
50
|
import { authConfigured, chooseAuth, detectClaudeLogin, readClaudeLoginState, } from "../lib/login-detect.js";
|
|
@@ -169,7 +173,8 @@ export async function agentCommand(scenarioArg, options = {}) {
|
|
|
169
173
|
liftPassthroughName(options.passthrough ?? []);
|
|
170
174
|
// ── session name + goal ── (a bare `mnemom agent` in a terminal asks for the name;
|
|
171
175
|
// goal alignment is resolved upstream: --goal seals a contract, implicit alignment
|
|
172
|
-
// is on by default
|
|
176
|
+
// is on by default while the `implicit` experimental feature is on, and on a `next`
|
|
177
|
+
// build for every launch but `-p` (T16).
|
|
173
178
|
const session = await resolveSessionSetup({
|
|
174
179
|
scenario: scenarioArg,
|
|
175
180
|
goal: options.goal,
|
|
@@ -729,6 +734,13 @@ export async function agentCommand(scenarioArg, options = {}) {
|
|
|
729
734
|
}),
|
|
730
735
|
knownCcSessionId: cc.id ?? continuedCcSessionId,
|
|
731
736
|
plugin,
|
|
737
|
+
receipt: experimental.includes("record")
|
|
738
|
+
? { orgId: account.orgId, agentId: servedAgentId }
|
|
739
|
+
: undefined,
|
|
740
|
+
orgId: account.orgId,
|
|
741
|
+
commitReport: cli.name === "claude" &&
|
|
742
|
+
Boolean(account.orgId) &&
|
|
743
|
+
commitReportEnabled(process.env[COMMIT_REPORT_ENV], CLI_VERSION),
|
|
732
744
|
});
|
|
733
745
|
return; // launchTerminal exits the process
|
|
734
746
|
}
|
|
@@ -1237,6 +1249,7 @@ function launchTerminal(ctx) {
|
|
|
1237
1249
|
// A subscription launch (no Anthropic key) sets NO auth token: Claude Code then sends its
|
|
1238
1250
|
// own claude.ai login to the gateway (lib/subscription-login.ts).
|
|
1239
1251
|
let childEnv;
|
|
1252
|
+
let feed = null;
|
|
1240
1253
|
if (ctx.anthropicKey) {
|
|
1241
1254
|
childEnv = { ...process.env };
|
|
1242
1255
|
delete childEnv.ANTHROPIC_API_KEY;
|
|
@@ -1262,10 +1275,8 @@ function launchTerminal(ctx) {
|
|
|
1262
1275
|
applyGatewayHintHeaders(childEnv);
|
|
1263
1276
|
if (ctx.options.slack)
|
|
1264
1277
|
args.push(...slackChannelArgs(sessionName));
|
|
1265
|
-
// The status-bar
|
|
1266
|
-
//
|
|
1267
|
-
// decision alone: a value inherited from an outer `mnemom agent` session never rides along.
|
|
1268
|
-
Reflect.deleteProperty(childEnv, MEASURED_ENV);
|
|
1278
|
+
// The status-bar segment (lib/statusline.ts). Claude Code only; the user's own
|
|
1279
|
+
// statusLine keeps running in front of it.
|
|
1269
1280
|
if (ctx.cli.name === "claude") {
|
|
1270
1281
|
const passthrough = ctx.options.passthrough ?? [];
|
|
1271
1282
|
const sl = statuslineLaunch({
|
|
@@ -1274,21 +1285,48 @@ function launchTerminal(ctx) {
|
|
|
1274
1285
|
cwd: process.cwd(),
|
|
1275
1286
|
node: process.execPath,
|
|
1276
1287
|
bin: join(dirname(fileURLToPath(import.meta.url)), "..", "lib", "statusline-bin.js"),
|
|
1277
|
-
measured: ctx.usageSavings,
|
|
1278
1288
|
});
|
|
1279
1289
|
if (sl)
|
|
1280
1290
|
Object.assign(childEnv, sl.env);
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1291
|
+
feed = prepareStatuslineFeed({
|
|
1292
|
+
statusline: sl !== null,
|
|
1293
|
+
orgId: ctx.orgId,
|
|
1294
|
+
version: CLI_VERSION,
|
|
1295
|
+
goalMode: Boolean(ctx.goalMode),
|
|
1296
|
+
env: process.env,
|
|
1297
|
+
childEnv,
|
|
1298
|
+
});
|
|
1299
|
+
// Autocompact guard (lib/autocompact-guard.ts): one --settings carries every layer. The
|
|
1300
|
+
// commit trailer (W1.8) rides in it unless the user passed their own --settings.
|
|
1301
|
+
const ownSettings = hasOwnSettingsFlag(passthrough);
|
|
1302
|
+
const guard = applyAutocompactGuard(childEnv, ctx.options, !ownSettings);
|
|
1303
|
+
const extra = launchSettingsExtra({
|
|
1304
|
+
statusline: sl?.settings ?? null,
|
|
1305
|
+
commitReport: Boolean(ctx.commitReport),
|
|
1306
|
+
ownSettings,
|
|
1307
|
+
conversationId: ctx.conversationId,
|
|
1308
|
+
settings: ctx.commitReport && !ownSettings ? ccSettings() : [],
|
|
1309
|
+
});
|
|
1310
|
+
args.push(...mergedSettingsArgs(guard, extra));
|
|
1284
1311
|
}
|
|
1285
1312
|
if (ctx.contextHint) {
|
|
1286
1313
|
seedContextHintFlag(childEnv);
|
|
1287
1314
|
childEnv.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
|
|
1288
1315
|
childEnv.CLAUDE_CODE_GB_DISK_CACHE_WHEN_TELEMETRY_OFF = "1";
|
|
1289
1316
|
}
|
|
1317
|
+
let recordStatePath;
|
|
1290
1318
|
const run = () => {
|
|
1319
|
+
const launchedSec = Math.floor(Date.now() / 1000);
|
|
1291
1320
|
const child = spawn(ctx.cli.bin, args, { stdio: "inherit", env: childEnv });
|
|
1321
|
+
// W1.8: report the session's commits while it runs; no record state (no proxy) → no reports.
|
|
1322
|
+
const commits = ctx.commitReport && ctx.orgId && recordStatePath
|
|
1323
|
+
? startCommitReporter({
|
|
1324
|
+
orgId: ctx.orgId,
|
|
1325
|
+
recordStateFile: recordStatePath,
|
|
1326
|
+
sinceSec: launchedSec,
|
|
1327
|
+
git: realGit(process.cwd()),
|
|
1328
|
+
})
|
|
1329
|
+
: null;
|
|
1292
1330
|
child.on("error", (err) => {
|
|
1293
1331
|
say(`mnemom agent: failed to launch ${ctx.cli.name}: ${err.message}`);
|
|
1294
1332
|
process.exit(1);
|
|
@@ -1296,34 +1334,114 @@ function launchTerminal(ctx) {
|
|
|
1296
1334
|
child.on("exit", (code, signal) => {
|
|
1297
1335
|
if (signal)
|
|
1298
1336
|
process.kill(process.pid, signal);
|
|
1299
|
-
else
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
const
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1337
|
+
else
|
|
1338
|
+
void (async () => {
|
|
1339
|
+
// The conduct receipt and the last commit sweep run side by side, each under its own
|
|
1340
|
+
// hard deadline inside W1.3's exit budget; neither changes the exit code.
|
|
1341
|
+
const swept = commits?.finish().catch(() => undefined);
|
|
1342
|
+
if (ctx.receipt)
|
|
1343
|
+
await sayConductReceipt({ ...ctx.receipt, statePath: recordStatePath });
|
|
1344
|
+
await swept;
|
|
1345
|
+
// Claude Code's own last line is "Resume this session with: claude --resume <id>",
|
|
1346
|
+
// which reopens it OUTSIDE Mnemom (ungoverned, unbilled). Ours goes after it, last.
|
|
1347
|
+
if (code === 0 && ctx.resumeHint && wantsResumeHint(ctx.cli, args)) {
|
|
1348
|
+
const id = ctx.knownCcSessionId ?? newestCcSessionIn(process.cwd(), process.env);
|
|
1349
|
+
say(ctx.resumeHint(id));
|
|
1350
|
+
}
|
|
1351
|
+
process.exit(code ?? 0);
|
|
1352
|
+
})();
|
|
1308
1353
|
});
|
|
1309
1354
|
};
|
|
1310
1355
|
// Implicit goal mode: put the local base-URL proxy in front of the door so each main request
|
|
1311
1356
|
// carries x-mnemom-turn (where each recent user turn came from, read from Claude Code's own
|
|
1312
1357
|
// transcript — base-url-proxy.mjs / turn-origin.mjs). The prompt id it joins on comes from the
|
|
1313
|
-
// gateway hint headers set above.
|
|
1314
|
-
|
|
1358
|
+
// gateway hint headers set above. Experimental `record` runs it too (turn header off unless
|
|
1359
|
+
// implicit), to capture the lineage key the conduct receipt reads. Fail-open: no proxy → the
|
|
1360
|
+
// door directly, as before, and a receipt that links instead of giving figures.
|
|
1361
|
+
const turnHeader = Boolean(ctx.goalMode) && turnProxyWanted(process.env);
|
|
1362
|
+
if (!proxyWanted({
|
|
1363
|
+
turnHeader,
|
|
1364
|
+
receipt: Boolean(ctx.receipt),
|
|
1365
|
+
commitReport: Boolean(ctx.commitReport),
|
|
1366
|
+
})) {
|
|
1315
1367
|
run();
|
|
1316
1368
|
return;
|
|
1317
1369
|
}
|
|
1318
|
-
startBaseUrlProxy(ctx.door, (baseUrl) => {
|
|
1319
|
-
if (baseUrl)
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
exemptLoopbackFromProxy(childEnv);
|
|
1323
|
-
}
|
|
1370
|
+
startBaseUrlProxy(ctx.door, (baseUrl, statePath) => {
|
|
1371
|
+
if (baseUrl)
|
|
1372
|
+
recordStatePath = statePath;
|
|
1373
|
+
onBaseUrlProxyReady(baseUrl, statePath, childEnv, feed && ctx.orgId ? { ...feed, orgId: ctx.orgId } : null);
|
|
1324
1374
|
run();
|
|
1375
|
+
}, {
|
|
1376
|
+
turnHeader,
|
|
1377
|
+
recordState: wantsRecordState(Boolean(ctx.receipt || ctx.commitReport), feed !== null),
|
|
1325
1378
|
});
|
|
1326
1379
|
}
|
|
1380
|
+
/**
|
|
1381
|
+
* The extra `--settings` the launch merges (beside the autocompact guard): the status line's,
|
|
1382
|
+
* and with commit reporting on (W1.8) the `Mnemom-Conversation` commit trailer, which keeps the
|
|
1383
|
+
* user's own commit attribution in front of it. Never when the user passed their own --settings.
|
|
1384
|
+
*/
|
|
1385
|
+
export function launchSettingsExtra(o) {
|
|
1386
|
+
const trailer = o.commitReport && !o.ownSettings
|
|
1387
|
+
? attributionSettings(o.conversationId, o.settings.find((v) => v.commitAttribution !== undefined)?.commitAttribution)
|
|
1388
|
+
: null;
|
|
1389
|
+
if (!o.statusline && !trailer)
|
|
1390
|
+
return null;
|
|
1391
|
+
return { ...(o.statusline ?? {}), ...(trailer ?? {}) };
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Whether the local base-URL proxy runs: implicit goals (turn header), the conduct receipt and
|
|
1395
|
+
* commit reporting (W1.8) all need it; commit reporting reads the lineage key it records.
|
|
1396
|
+
*/
|
|
1397
|
+
export function proxyWanted(o) {
|
|
1398
|
+
return o.turnHeader || o.receipt || o.commitReport;
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Whether the proxy captures the gateway's record state: the conduct receipt reads it at exit,
|
|
1402
|
+
* and the fed status line reads its lineage key while the session runs.
|
|
1403
|
+
*/
|
|
1404
|
+
export function wantsRecordState(receipt, fed) {
|
|
1405
|
+
return receipt || fed;
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Point Claude Code at a ready proxy and, on a fed launch, start the status-line feed on the
|
|
1409
|
+
* proxy's record state (no state file, no feed: the line stays "mnemom").
|
|
1410
|
+
*/
|
|
1411
|
+
export function onBaseUrlProxyReady(baseUrl, recordStateFile, childEnv, feed, start = startFeed) {
|
|
1412
|
+
if (!baseUrl)
|
|
1413
|
+
return;
|
|
1414
|
+
childEnv.ANTHROPIC_BASE_URL = baseUrl;
|
|
1415
|
+
// An inherited HTTPS_PROXY must not carry the loopback hop.
|
|
1416
|
+
exemptLoopbackFromProxy(childEnv);
|
|
1417
|
+
if (feed && recordStateFile)
|
|
1418
|
+
start({ ...feed, recordStateFile });
|
|
1419
|
+
}
|
|
1420
|
+
/**
|
|
1421
|
+
* The status-line feed file for a fed launch (and FEED_ENV set on the child), or null: the
|
|
1422
|
+
* segment off, no billing org, or {@link fedStatuslineWanted} false.
|
|
1423
|
+
*/
|
|
1424
|
+
export function prepareStatuslineFeed(o) {
|
|
1425
|
+
if (!o.statusline || !o.orgId || !fedStatuslineWanted(o.version, o.goalMode, o.env))
|
|
1426
|
+
return null;
|
|
1427
|
+
const feed = (o.files ?? fedStatuslineFiles)();
|
|
1428
|
+
o.childEnv[FEED_ENV] = feed.feedFile;
|
|
1429
|
+
return feed;
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Whether this launch feeds the status line measured model cost and μ (W1.4): prerelease
|
|
1433
|
+
* builds only (stable stays "mnemom", decision 14), and only when the turn proxy runs, since
|
|
1434
|
+
* the proxy is what learns the gateway's lineage key for the session.
|
|
1435
|
+
*/
|
|
1436
|
+
export function fedStatuslineWanted(version, goalMode, env) {
|
|
1437
|
+
return isPrerelease(version) && goalMode && turnProxyWanted(env);
|
|
1438
|
+
}
|
|
1439
|
+
/** A private per-session dir holding the feed (launcher → bin). */
|
|
1440
|
+
function fedStatuslineFiles() {
|
|
1441
|
+
const dir = mkdtempSync(join(tmpdir(), "mnemom-statusline."));
|
|
1442
|
+
process.on("exit", () => rmSync(dir, { recursive: true, force: true }));
|
|
1443
|
+
return { feedFile: join(dir, "feed.json") };
|
|
1444
|
+
}
|
|
1327
1445
|
/**
|
|
1328
1446
|
* Add 127.0.0.1 and localhost to BOTH NO_PROXY and no_proxy (proxy clients disagree on which one
|
|
1329
1447
|
* wins, and some read only the lowercase one), keeping whatever each already listed.
|
|
@@ -1334,6 +1452,20 @@ export function exemptLoopbackFromProxy(env) {
|
|
|
1334
1452
|
env.NO_PROXY = [upper, "127.0.0.1,localhost"].filter(Boolean).join(",");
|
|
1335
1453
|
env.no_proxy = [lower, "127.0.0.1,localhost"].filter(Boolean).join(",");
|
|
1336
1454
|
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Print the conduct receipt (experimental `record`) — the exit call site here, and the one a
|
|
1457
|
+
* durable park calls. Never throws: a failure is one warning line, and the caller's exit code
|
|
1458
|
+
* is untouched.
|
|
1459
|
+
*/
|
|
1460
|
+
export async function sayConductReceipt(launch, trigger = "exit", receipt = conductReceiptFor) {
|
|
1461
|
+
try {
|
|
1462
|
+
for (const line of await receipt(launch, trigger))
|
|
1463
|
+
say(line);
|
|
1464
|
+
}
|
|
1465
|
+
catch (err) {
|
|
1466
|
+
say(fmt.warn(`mnemom agent: no conduct receipt (${err instanceof Error ? err.message : String(err)})`));
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1337
1469
|
/** Whether a terminal implicit launch runs the turn-origin proxy (MNEMOM_AGENT_TURN_HEADER=0 opts out). */
|
|
1338
1470
|
export function turnProxyWanted(env) {
|
|
1339
1471
|
const raw = (env.MNEMOM_AGENT_TURN_HEADER ?? "").trim().toLowerCase();
|
|
@@ -1350,6 +1482,9 @@ export function startBaseUrlProxy(door, done, opts = {}) {
|
|
|
1350
1482
|
const script = opts.script ?? join(dirname(fileURLToPath(import.meta.url)), "..", "base-url-proxy.mjs");
|
|
1351
1483
|
// The log carries method / path / status / latency / turn note only (never a header value or body).
|
|
1352
1484
|
const logDir = mkdtempSync(join(tmpdir(), "mnemom-turn-proxy."));
|
|
1485
|
+
// The receipt's record state (lineage key, record URL: non-secret) lives beside the log and is
|
|
1486
|
+
// removed with it on exit, after the receipt has read it.
|
|
1487
|
+
const recordStatePath = opts.recordState ? join(logDir, "record.json") : undefined;
|
|
1353
1488
|
const proxy = spawn(opts.node ?? process.execPath, [script], {
|
|
1354
1489
|
env: {
|
|
1355
1490
|
...process.env,
|
|
@@ -1357,6 +1492,8 @@ export function startBaseUrlProxy(door, done, opts = {}) {
|
|
|
1357
1492
|
MNEMOM_AGENT_BU_CWD: process.cwd(),
|
|
1358
1493
|
MNEMOM_AGENT_BU_LOG: process.env.MNEMOM_AGENT_TURN_PROXY_LOG || join(logDir, "proxy.log"),
|
|
1359
1494
|
MNEMOM_AGENT_BU_PARENT_PID: String(process.pid),
|
|
1495
|
+
...(opts.turnHeader === false ? { MNEMOM_AGENT_TURN_HEADER: "0" } : {}),
|
|
1496
|
+
...(recordStatePath ? { MNEMOM_AGENT_BU_RECORD_STATE: recordStatePath } : {}),
|
|
1360
1497
|
},
|
|
1361
1498
|
stdio: ["ignore", "pipe", "ignore"],
|
|
1362
1499
|
});
|
|
@@ -1375,7 +1512,7 @@ export function startBaseUrlProxy(door, done, opts = {}) {
|
|
|
1375
1512
|
if (!url) {
|
|
1376
1513
|
say(fmt.warn(`mnemom agent: turn-origin proxy unavailable (${why}) — launching straight to the gateway; the gateway reads turn origins from the wire only.`));
|
|
1377
1514
|
}
|
|
1378
|
-
done(url);
|
|
1515
|
+
done(url, url ? recordStatePath : undefined);
|
|
1379
1516
|
};
|
|
1380
1517
|
const timeoutMs = opts.readyTimeoutMs ?? 5000;
|
|
1381
1518
|
const timer = setTimeout(() => finish(null, `no READY within ${timeoutMs}ms`), timeoutMs);
|
package/dist/commands/status.js
CHANGED
|
@@ -138,7 +138,7 @@ async function checkApiConnectivity(agentId) {
|
|
|
138
138
|
catch (error) {
|
|
139
139
|
// 404 = agent not registered yet. Branch on effectiveStatus (enforce hook may
|
|
140
140
|
// rewrite an undocumented 404 → synthetic 500 + spec_deviation.original_status;
|
|
141
|
-
// effectiveStatus === status when documented). getAgent →
|
|
141
|
+
// effectiveStatus === status when documented). getAgent → readApiError → MnemomApiError.
|
|
142
142
|
if (error instanceof MnemomApiError && error.effectiveStatus === 404) {
|
|
143
143
|
return {
|
|
144
144
|
name: "API",
|
package/dist/commands/update.js
CHANGED
|
@@ -43,7 +43,9 @@ export function formatUpdateResult(result, current) {
|
|
|
43
43
|
lines.push(` Try manually: ${manual(action.version)}`);
|
|
44
44
|
}
|
|
45
45
|
else if (action.kind === "notify") {
|
|
46
|
-
lines.push(
|
|
46
|
+
lines.push(result.movedBack
|
|
47
|
+
? `mnemom ${current} was withdrawn; ${result.channel} is back on ${action.version}.`
|
|
48
|
+
: `mnemom ${action.version} is available on ${result.channel} (you have ${current}).`);
|
|
47
49
|
lines.push(` Run: ${canSelfUpdate(result.method ?? "unknown") ? "mnemom update" : manual(action.version)}`);
|
|
48
50
|
}
|
|
49
51
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `mnemom validate ...` commands — Safe House Hardening T1-4 (CI gate
|
|
3
|
-
* integration). Surface for engineers to check whether
|
|
3
|
+
* integration). Surface for engineers to check whether the test cell is safe
|
|
4
4
|
* to promote to production based on the most recent harness run state.
|
|
5
5
|
*
|
|
6
6
|
* mnemom validate safe-house [--against=test] [--max-age=24h]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `mnemom validate ...` commands — Safe House Hardening T1-4 (CI gate
|
|
3
|
-
* integration). Surface for engineers to check whether
|
|
3
|
+
* integration). Surface for engineers to check whether the test cell is safe
|
|
4
4
|
* to promote to production based on the most recent harness run state.
|
|
5
5
|
*
|
|
6
6
|
* mnemom validate safe-house [--against=test] [--max-age=24h]
|
package/dist/index.js
CHANGED
|
@@ -14,8 +14,11 @@ import { policyInitCommand, policyValidateCommand, policyPublishCommand, policyL
|
|
|
14
14
|
import { protectionShowCommand, protectionPublishCommand, protectionValidateCommand, protectionEditCommand, protectionDriftCommand, } from "./commands/protection.js";
|
|
15
15
|
import { agentsListCommand, agentsClaimCommand, agentsMoveCommand } from "./commands/agents.js";
|
|
16
16
|
import { agentExportCommand, liveExportDeps } from "./commands/agent-export.js";
|
|
17
|
+
import { agentShareCommand, liveAgentShareDeps } from "./commands/agent-share.js";
|
|
18
|
+
import { agentShareFixtureEnabled, fixtureAgentShareParts, } from "./commands/agent-share-fixture.js";
|
|
17
19
|
import { agentSessionsCommand, agentShowCommand, liveSessionDeps, } from "./commands/agent-sessions.js";
|
|
18
20
|
import { agentGoalPinCommand, agentGoalResetCommand, agentGoalShowCommand, liveGoalDeps, } from "./commands/agent-goal.js";
|
|
21
|
+
import { agentFuelCommand, liveFuelDeps } from "./commands/agent-fuel.js";
|
|
19
22
|
import { orgListCommand, orgShowCommand, orgUseCommand } from "./commands/org.js";
|
|
20
23
|
import { teamListCommand, teamShowCommand, teamTemplateCommand, teamPreviewComposeCommand, teamAdminGrantCommand, teamAdminRevokeCommand, teamAdminListCommand, teamCoverageCommand, } from "./commands/team.js";
|
|
21
24
|
import { advisoriesListCommand, advisoriesShowCommand } from "./commands/advisories.js";
|
|
@@ -33,11 +36,13 @@ import { agentDoctorCommand } from "./commands/agent-doctor.js";
|
|
|
33
36
|
import { agentSetupCommand, parseGovernanceFlag } from "./commands/agent-setup.js";
|
|
34
37
|
import { agentInviteCommand, runAgentInvocation } from "./commands/agent-invite.js";
|
|
35
38
|
import { agentFirstRunCommand, offerFirstRunOnLaunch } from "./commands/agent-first-run.js";
|
|
39
|
+
import { showImplicitDefaultNoticeOnce } from "./commands/agent-implicit-notice.js";
|
|
40
|
+
import { isPrerelease } from "./lib/update/semver.js";
|
|
36
41
|
import { applyConfigToEnv, launcherEntries, loadLauncherConfig, withoutDisabledExperimental, } from "./lib/launcher-config.js";
|
|
37
42
|
import { loadExperimentalState } from "./lib/cli-config.js";
|
|
38
|
-
import { assertEnabled, EXPERIMENTAL_CONTRACT, gateCheck, ignoredSettingLines, reportCliError, } from "./lib/experimental.js";
|
|
43
|
+
import { assertEnabled, availableFeatures, EXPERIMENTAL_CONTRACT, gateCheck, ignoredSettingLines, reportCliError, } from "./lib/experimental.js";
|
|
39
44
|
import { experimentalDisableCommand, experimentalEnableCommand, experimentalListCommand, runExperimentalMigration, } from "./commands/experimental.js";
|
|
40
|
-
import { parseCompactAt, parseContextProfile,
|
|
45
|
+
import { parseCompactAt, parseContextProfile, passthroughIsPrint, resolveImplicitSource, selectLaunchAgent, splitSessionArg, } from "./lib/agent.js";
|
|
41
46
|
import { wrapCommand } from "./commands/wrap.js";
|
|
42
47
|
import { onboardCommand } from "./commands/onboard.js";
|
|
43
48
|
import { skillsListCommand, skillsDescribeCommand } from "./commands/skills.js";
|
|
@@ -114,11 +119,14 @@ program
|
|
|
114
119
|
// ── experimental features (lib/experimental.ts) ── While a feature is off its flags and
|
|
115
120
|
// commands are hidden from --help (decided once, at load) and using one fails with a
|
|
116
121
|
// pointer to `mnemom experimental enable <id>` (decided per invocation, in the action).
|
|
117
|
-
|
|
122
|
+
// A prerelease (`next`) build also makes PRERELEASE_AVAILABLE usable (door one's T16).
|
|
123
|
+
const PRERELEASE_BUILD = isPrerelease(CLI_VERSION);
|
|
124
|
+
const loadAvailableFeatures = () => availableFeatures(loadExperimentalState().enabled, PRERELEASE_BUILD);
|
|
125
|
+
const experimentalAtLoad = loadAvailableFeatures();
|
|
118
126
|
const hiddenUnless = (id) => !experimentalAtLoad.includes(id);
|
|
119
127
|
/** preAction guard for a gated command: print the guidance and exit 2 while `id` is off. */
|
|
120
128
|
function requireExperimental(what, id) {
|
|
121
|
-
const message = gateCheck(what, id,
|
|
129
|
+
const message = gateCheck(what, id, loadAvailableFeatures());
|
|
122
130
|
if (message) {
|
|
123
131
|
console.error(message);
|
|
124
132
|
process.exit(2);
|
|
@@ -161,7 +169,7 @@ const agentCmd = program
|
|
|
161
169
|
"platform cards (strictest wins). See `mnemom protection` for that mode.")
|
|
162
170
|
.option("--lead-directed", "Seal the standard lead-directed requirement: own-branch push and draft/ready PR creation, " +
|
|
163
171
|
"from a git worktree, on the lead's direction — not merging. Requires --goal; idempotent.")
|
|
164
|
-
.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
|
|
172
|
+
.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, and on a `next` build for every launch but `-p`; not combinable with --goal/--requirement/--allow/--forbid/--goal-id/--mode/--lead-directed; the guardrail ceilings still apply)").hideHelp(hiddenUnless("implicit")))
|
|
165
173
|
.option("--no-implicit", "Turn implicit goal alignment OFF for this launch (overrides launcher.toml goal_mode = implicit)")
|
|
166
174
|
.option("--conversation-id <id>", "x-mnemom-conversation-id (default: auto-generated)")
|
|
167
175
|
.option("--cli <name|path>", "Coding-agent CLI to launch: a name or full path (default: claude)")
|
|
@@ -259,6 +267,8 @@ const agentCmd = program
|
|
|
259
267
|
}
|
|
260
268
|
async function launchAgent(scenario) {
|
|
261
269
|
const experimental = loadExperimentalState().enabled;
|
|
270
|
+
// What a flag, key or command may use: the enabled features, plus implicit on `next`.
|
|
271
|
+
const available = availableFeatures(experimental, PRERELEASE_BUILD);
|
|
262
272
|
// The one place the flag's raw string becomes `number | null` (see the argParser's
|
|
263
273
|
// comment for why commander can't carry `null` through parseArg directly). Already
|
|
264
274
|
// validated by the argParser, so this never throws.
|
|
@@ -266,7 +276,7 @@ const agentCmd = program
|
|
|
266
276
|
// Sub-verb: `mnemom agent config …` manages persistent settings and never
|
|
267
277
|
// launches. (A scenario literally named "config" is reserved for this.)
|
|
268
278
|
if (scenario === "config") {
|
|
269
|
-
await agentConfigCommand(passthrough, { enabled:
|
|
279
|
+
await agentConfigCommand(passthrough, { enabled: available });
|
|
270
280
|
return;
|
|
271
281
|
}
|
|
272
282
|
// Sub-verb: `mnemom agent slack …` posts/receives Slack messages as this
|
|
@@ -286,7 +296,7 @@ const agentCmd = program
|
|
|
286
296
|
used: opts.contextHandoff === true,
|
|
287
297
|
},
|
|
288
298
|
{ what: "--implicit", id: "implicit", used: opts.implicit === true },
|
|
289
|
-
],
|
|
299
|
+
], available);
|
|
290
300
|
if (opts.gateway)
|
|
291
301
|
process.env.MNEMOM_AGENT_GATEWAY = opts.gateway;
|
|
292
302
|
// Persistent settings (~/.mnemom/launcher.toml) sit UNDER env and flags:
|
|
@@ -299,11 +309,11 @@ const agentCmd = program
|
|
|
299
309
|
for (const line of ignoredSettingLines({
|
|
300
310
|
entries: launcherEntries(rawCfg),
|
|
301
311
|
env: process.env,
|
|
302
|
-
enabled:
|
|
312
|
+
enabled: available,
|
|
303
313
|
})) {
|
|
304
314
|
console.error(line);
|
|
305
315
|
}
|
|
306
|
-
const cfg = withoutDisabledExperimental(rawCfg,
|
|
316
|
+
const cfg = withoutDisabledExperimental(rawCfg, available);
|
|
307
317
|
applyConfigToEnv(cfg, process.env);
|
|
308
318
|
// Sub-verb: `mnemom agent doctor` runs a read-only preflight and never
|
|
309
319
|
// launches. Placed after config load so it reports the effective settings.
|
|
@@ -334,14 +344,22 @@ const agentCmd = program
|
|
|
334
344
|
const numToStr = (n) => n === undefined ? undefined : String(n);
|
|
335
345
|
// Implicit mode: --implicit / --no-implicit win; a --goal statement seals
|
|
336
346
|
// (the standing config default never overrides it); else launcher.toml
|
|
337
|
-
// `goal_mode`; else implicit while the `implicit` feature is on,
|
|
338
|
-
//
|
|
339
|
-
|
|
347
|
+
// `goal_mode`; else implicit while the `implicit` feature is on; else, on a
|
|
348
|
+
// `next` build, implicit unless the launch is headless `-p` (T16); else off.
|
|
349
|
+
// Pure + unit-tested in lib/agent.ts.
|
|
350
|
+
const goalMode = resolveImplicitSource({
|
|
340
351
|
goal: opts.goal,
|
|
341
352
|
implicit: opts.implicit,
|
|
342
353
|
configGoalMode: cfg.goalMode,
|
|
343
354
|
experimentalOn: experimental.includes("implicit"),
|
|
355
|
+
prerelease: PRERELEASE_BUILD,
|
|
356
|
+
print: passthroughIsPrint(passthrough),
|
|
344
357
|
});
|
|
358
|
+
const implicit = goalMode.implicit;
|
|
359
|
+
// The T16 default tells the user once, the first time it applies.
|
|
360
|
+
if (implicit && goalMode.source === "prerelease") {
|
|
361
|
+
showImplicitDefaultNoticeOnce({ dryRun: opts.dryRun });
|
|
362
|
+
}
|
|
345
363
|
// Config guardrails apply only when goal alignment is actually intended (a
|
|
346
364
|
// --goal is present, or implicit mode — where they ride on the mode header),
|
|
347
365
|
// so a saved ceiling never forces an unrequested contract (which would
|
|
@@ -895,6 +913,21 @@ agentCmd
|
|
|
895
913
|
.action(async (idOrName, opts) => {
|
|
896
914
|
process.exitCode = await agentExportCommand(idOrName, opts, liveExportDeps);
|
|
897
915
|
});
|
|
916
|
+
// Hidden until MNEMOM_AGENT_SHARE=1 (MNE-9037): with the flag off the command behaves as unknown.
|
|
917
|
+
agentCmd
|
|
918
|
+
.command("share", { hidden: true })
|
|
919
|
+
.description("Build a shareable card from lines of your signed statements and print the share-page link (card in the URL fragment; nothing is posted). Needs MNEMOM_AGENT_SHARE=1")
|
|
920
|
+
.option("--lines <ids>", "Comma-separated line ids to include (skips the picker)")
|
|
921
|
+
.option("--list", "List the lines available to share and exit")
|
|
922
|
+
.option("--json", "Print JSON instead of text")
|
|
923
|
+
.action(async (opts) => {
|
|
924
|
+
// MNEMOM_AGENT_SHARE_FIXTURE=1 (with MNEMOM_AGENT_SHARE=1) swaps in the test-only fixture
|
|
925
|
+
// source/issuer; otherwise the not-yet-connected live deps are used, unchanged.
|
|
926
|
+
const deps = agentShareFixtureEnabled()
|
|
927
|
+
? { ...liveAgentShareDeps, ...fixtureAgentShareParts }
|
|
928
|
+
: liveAgentShareDeps;
|
|
929
|
+
process.exitCode = await agentShareCommand(opts, deps);
|
|
930
|
+
});
|
|
898
931
|
agentCmd
|
|
899
932
|
.command("sessions")
|
|
900
933
|
.description("List your Mnemom Agent sessions from the local ledger (~/.mnemom/sessions.jsonl), newest first — the last 20 unless --all")
|
|
@@ -935,6 +968,29 @@ agentCmd
|
|
|
935
968
|
process.exit(1);
|
|
936
969
|
}
|
|
937
970
|
});
|
|
971
|
+
// `mnemom agent fuel <file>` — the fuel step (Doors W3.2): one confirmation seals a batch of job
|
|
972
|
+
// contracts through the batch-seal endpoint and commits them to the repo.
|
|
973
|
+
agentCmd
|
|
974
|
+
.command("fuel <file>", { hidden: hiddenUnless("fuel") })
|
|
975
|
+
.description("EXPERIMENTAL (`mnemom experimental enable fuel`): seal a batch of job contracts with one confirmation. " +
|
|
976
|
+
'`file` is a JSON array of contracts (or `{ "contracts": [...] }`; `-` reads stdin); each is sealed, ' +
|
|
977
|
+
"then written to .mnemom/contracts/<sha256>.json and committed")
|
|
978
|
+
.option("--repo <owner/name>", "The repo the jobs run against (default: the GitHub origin remote)")
|
|
979
|
+
.option("--org <org_id>", "The org to seal under (default: your only organization)")
|
|
980
|
+
.option("--yes", "Seal without the confirmation prompt")
|
|
981
|
+
.option("--no-commit", "Seal only; do not write or commit the contract files")
|
|
982
|
+
.option("--json", "Output the batch-seal response, the files and the commit as JSON")
|
|
983
|
+
.option("--key <idempotency-key>", "Replay a batch already sealed with this key (printed when committing its files failed)")
|
|
984
|
+
.hook("preAction", () => requireExperimental("`mnemom agent fuel`", "fuel"))
|
|
985
|
+
.action(async (file, opts) => {
|
|
986
|
+
try {
|
|
987
|
+
await agentFuelCommand(file, opts, liveFuelDeps);
|
|
988
|
+
}
|
|
989
|
+
catch (error) {
|
|
990
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
991
|
+
process.exitCode = 1;
|
|
992
|
+
}
|
|
993
|
+
});
|
|
938
994
|
// `mnemom agent goal show|pin|reset` — the implicit goal the gateway inferred for a session
|
|
939
995
|
// (implicit-goal CLI). The handlers set process.exitCode themselves (1 / 2); the catch is for
|
|
940
996
|
// the unexpected.
|
package/dist/lib/agent.d.ts
CHANGED
|
@@ -269,6 +269,8 @@ export declare function supportsOneM(model: string): boolean;
|
|
|
269
269
|
export interface CcSettingsView {
|
|
270
270
|
model?: string;
|
|
271
271
|
env?: Record<string, string | undefined>;
|
|
272
|
+
/** `attribution.commit`, or false when `attribution` is false (all attribution hidden). */
|
|
273
|
+
commitAttribution?: string | false;
|
|
272
274
|
}
|
|
273
275
|
/**
|
|
274
276
|
* Claude Code's settings files, highest precedence first: `<cwd>/.claude/settings.local.json`,
|
|
@@ -359,13 +361,7 @@ export declare function resolveConversationId(raw: string | undefined): string;
|
|
|
359
361
|
export declare function isPositiveInt(value: unknown): boolean;
|
|
360
362
|
/** A strictly-positive finite number (rejects 0, negatives, NaN, Infinity, non-numeric). */
|
|
361
363
|
export declare function isPositiveNumber(value: unknown): boolean;
|
|
362
|
-
|
|
363
|
-
* Canonical JSON — object keys sorted recursively, arrays in order, no
|
|
364
|
-
* whitespace, `undefined` keys dropped. Byte-identical to the gateway's
|
|
365
|
-
* `canonicalJson` (gateway/src/goal-contract.ts), so the base64 we send and the
|
|
366
|
-
* sha we print match what the gateway seals.
|
|
367
|
-
*/
|
|
368
|
-
export declare function canonicalJson(value: unknown): string;
|
|
364
|
+
export { canonicalJson } from "./canonical-json.js";
|
|
369
365
|
/** sha256 hex (first 16 chars) of a string — the operator-eyeball contract hash. */
|
|
370
366
|
export declare function sha256Hex16(text: string): string;
|
|
371
367
|
/**
|
|
@@ -447,7 +443,8 @@ export declare const COMPACTION_INTERCEPT_KEY = "GATEWAY_COMPACTION_INTERCEPT";
|
|
|
447
443
|
/**
|
|
448
444
|
* The gateway env key that has it measure each request's saving for a single session and put
|
|
449
445
|
* it in the client-facing usage (`mnemom_savings` in the read `usage.iterations` entry), where
|
|
450
|
-
*
|
|
446
|
+
* it lands in Claude Code's transcript. The status bar never shows it (decision 14: never
|
|
447
|
+
* "saved"). Default OFF on the gateway; sent `"on"`
|
|
451
448
|
* only while the `measured-savings` experimental feature is on and the launched CLI is Claude
|
|
452
449
|
* Code (`resolveUsageSavings`). Independent of folding, so every profile sends it — `off` too,
|
|
453
450
|
* where the measured saving is honestly $0.00.
|
|
@@ -834,9 +831,9 @@ export declare function resolveCompactionIntercept(opts: {
|
|
|
834
831
|
env?: NodeJS.ProcessEnv;
|
|
835
832
|
}): boolean;
|
|
836
833
|
/**
|
|
837
|
-
* Does the gateway measure this launch's saving (`GATEWAY_USAGE_SAVINGS` in the header
|
|
838
|
-
*
|
|
839
|
-
*
|
|
834
|
+
* Does the gateway measure this launch's saving (`GATEWAY_USAGE_SAVINGS` in the header)? Only
|
|
835
|
+
* with the `measured-savings` experimental feature on, and only for Claude Code, whose
|
|
836
|
+
* transcript keeps the measurement. No flag or
|
|
840
837
|
* launcher.toml key: `mnemom experimental enable measured-savings` is the switch.
|
|
841
838
|
*/
|
|
842
839
|
export declare function resolveUsageSavings(opts: {
|
|
@@ -921,29 +918,47 @@ export declare function buildHandoffMcpConfigJson(p: HandoffMcpParams): string;
|
|
|
921
918
|
* per-session statement, so it is always a per-launch `--goal`.
|
|
922
919
|
*/
|
|
923
920
|
export type GoalModeDefault = "implicit" | "off";
|
|
921
|
+
/**
|
|
922
|
+
* Where a launch's goal mode came from (`resolveImplicitSource`). `prerelease` is door
|
|
923
|
+
* one's T16 default (decisions 12 and 22): implicit by default on a `-next.N` build with
|
|
924
|
+
* nothing configured. It is the only source that shows the one-time notice.
|
|
925
|
+
*/
|
|
926
|
+
export type ImplicitSource = "flag" | "goal" | "config" | "experimental" | "prerelease" | "default";
|
|
927
|
+
/** Does a Claude Code passthrough run headless (`-p` / `--print`)? */
|
|
928
|
+
export declare function passthroughIsPrint(passthrough: readonly string[]): boolean;
|
|
924
929
|
/**
|
|
925
930
|
* Is this launch implicit-mode? Precedence, highest wins:
|
|
926
931
|
* 1. an explicit flag — `--implicit` (true) or `--no-implicit` (false);
|
|
927
932
|
* 2. a `--goal` statement — a sealed contract is a per-launch choice that the
|
|
928
|
-
* standing config default must never silently override
|
|
933
|
+
* standing config default must never silently override, so a launch never
|
|
934
|
+
* runs both modes;
|
|
929
935
|
* 3. the config default `goal_mode` — `"off"` turns alignment off, `"implicit"`
|
|
930
936
|
* keeps it implicit;
|
|
931
|
-
* 4. with the `implicit` experimental feature ON, IMPLICIT
|
|
932
|
-
*
|
|
933
|
-
*
|
|
934
|
-
*
|
|
937
|
+
* 4. with the `implicit` experimental feature ON, IMPLICIT (as before T16);
|
|
938
|
+
* 5. on a prerelease (`next`) build, IMPLICIT for an interactive or Remote Control
|
|
939
|
+
* launch and OFF for a headless `-p` one (OD-13: T16 never covers `-p`);
|
|
940
|
+
* 6. otherwise OFF — stable without the experimental feature behaves as today.
|
|
935
941
|
* Pure so every arm is unit-tested; the caller passes the resolved value on to
|
|
936
942
|
* `assembleContract` / `buildGoalModeHeader` (which still refuse `--implicit`
|
|
937
943
|
* combined with a contract flag — that conflict is EXPLICIT and is reported).
|
|
938
944
|
*/
|
|
939
|
-
export declare function
|
|
945
|
+
export declare function resolveImplicitSource(opts: {
|
|
940
946
|
goal?: string;
|
|
941
947
|
implicit?: boolean;
|
|
942
948
|
configGoalMode?: GoalModeDefault;
|
|
943
949
|
/**
|
|
944
950
|
* Is the `implicit` experimental feature on? Off ⇒ the default is OFF and
|
|
945
951
|
* `goal_mode = implicit` is ignored (`--implicit` is refused upstream, before
|
|
946
|
-
* this runs). Omitted ⇒ on.
|
|
952
|
+
* this runs), unless this is a prerelease build. Omitted ⇒ on.
|
|
947
953
|
*/
|
|
948
954
|
experimentalOn?: boolean;
|
|
949
|
-
|
|
955
|
+
/** Is this a prerelease (`-next.N`) CLI build? `isPrerelease(CLI_VERSION)`. Omitted ⇒ no. */
|
|
956
|
+
prerelease?: boolean;
|
|
957
|
+
/** Does the launch run Claude Code headless (`-p`)? `passthroughIsPrint`. */
|
|
958
|
+
print?: boolean;
|
|
959
|
+
}): {
|
|
960
|
+
implicit: boolean;
|
|
961
|
+
source: ImplicitSource;
|
|
962
|
+
};
|
|
963
|
+
/** `resolveImplicitSource(opts).implicit`. */
|
|
964
|
+
export declare function resolveImplicit(opts: Parameters<typeof resolveImplicitSource>[0]): boolean;
|