@cortexkit/opencode-magic-context 0.34.2 → 0.35.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/README.md +3 -1
- package/dist/agents/hidden-agent-registrations.d.ts +10 -2
- package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
- package/dist/agents/magic-context-prompt.d.ts +2 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/agents/permissions.d.ts +4 -3
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +3 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/agent-overrides.d.ts +1 -1
- package/dist/config/schema/magic-context.d.ts +51 -10
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-fvpfvt0w.js → conflict-warning-hook-p2pmhvn7.js} +2 -1
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +15 -0
- package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/mural/compress-cues.d.ts +6 -2
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/mural/storage-mural-cues.d.ts +4 -4
- package/dist/hooks/magic-context/compartment-prompt.d.ts +6 -6
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -14
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +16 -2
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +10 -3
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +2 -1
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +5 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +2 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +6 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +19 -5
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +3 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index-0c9dmw9m.js +116 -0
- package/dist/{index-dtas91s5.js → index-8aaadh98.js} +7 -119
- package/dist/index-dpdnjawy.js +2892 -0
- package/dist/{index-z70pxrq1.js → index-fkyamz2w.js} +732 -613
- package/dist/{index-cn960ffd.js → index-h5zjfesc.js} +1 -1
- package/dist/{index-fcyvznch.js → index-w0nygb4p.js} +45 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +843 -818
- package/dist/plugin/hooks/create-session-hooks.d.ts +12 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +1 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts +4 -0
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-6cd3nrt7.js → recomp-orchestrator-29f4rqax.js} +5 -4
- package/dist/{send-session-notification-6njqewzk.js → send-session-notification-sr5g06hz.js} +2 -2
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.d.ts.map +1 -1
- package/dist/shared/prompt-surface-a1-golden.d.ts +28 -0
- package/dist/shared/prompt-surface-a1-golden.d.ts.map +1 -0
- package/dist/shared/prompt-surface-runtime.d.ts +43 -0
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -0
- package/dist/shared/prompt-surface.d.ts +49 -0
- package/dist/shared/prompt-surface.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +13 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/{storage-meta-session-xt41zbw4.js → storage-meta-session-ev8b55a9.js} +2 -2
- package/dist/tools/ctx-expand/tools.d.ts +1 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts +1 -0
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts +1 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +1 -0
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts +1 -0
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/light-descriptions.d.ts +6 -0
- package/dist/tools/light-descriptions.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/agents/hidden-agent-registrations.ts +49 -1
- package/src/agents/magic-context-prompt.test.ts +144 -0
- package/src/agents/magic-context-prompt.ts +53 -2
- package/src/agents/permissions.ts +4 -3
- package/src/config/index.test.ts +53 -0
- package/src/config/index.ts +4 -0
- package/src/config/project-security.test.ts +20 -0
- package/src/config/project-security.ts +23 -0
- package/src/config/schema/magic-context.test.ts +58 -0
- package/src/config/schema/magic-context.ts +61 -1
- package/src/shared/index.ts +2 -0
- package/src/shared/prompt-surface-a1-golden.md +458 -0
- package/src/shared/prompt-surface-a1-golden.ts +41 -0
- package/src/shared/prompt-surface-runtime.test.ts +141 -0
- package/src/shared/prompt-surface-runtime.ts +250 -0
- package/src/shared/prompt-surface.test.ts +109 -0
- package/src/shared/prompt-surface.ts +138 -0
- package/src/shared/sqlite.test.ts +32 -0
- package/src/shared/sqlite.ts +85 -9
- package/dist/index-b563sga5.js +0 -134784
package/dist/index.js
CHANGED
|
@@ -85,11 +85,15 @@ import {
|
|
|
85
85
|
computeNormalizedHash,
|
|
86
86
|
computeWorkspaceEpochFingerprint,
|
|
87
87
|
contentSha256,
|
|
88
|
+
cortexKitProjectConfigBasePath,
|
|
89
|
+
cortexKitUserConfigBasePath,
|
|
88
90
|
cosineSimilarity,
|
|
89
91
|
countEmbeddedCommits,
|
|
90
92
|
countPrimerCandidatesForProject,
|
|
91
93
|
createChildSessionWithFence,
|
|
92
94
|
createPrimer,
|
|
95
|
+
createPromptSurfaceGuidanceEpochCache,
|
|
96
|
+
createPromptSurfaceRuntime,
|
|
93
97
|
deleteTagsByMessageId,
|
|
94
98
|
deleteUserMemoryCandidates,
|
|
95
99
|
deriveTagLoadFloor,
|
|
@@ -111,7 +115,6 @@ import {
|
|
|
111
115
|
ensureContextStoreUuid,
|
|
112
116
|
ensureMemoryEmbeddings,
|
|
113
117
|
escalationBands,
|
|
114
|
-
estimateTrueRawMessageTokens,
|
|
115
118
|
expandWorkspaceIdentitySetWithAliases,
|
|
116
119
|
exports_external,
|
|
117
120
|
extractLatestAssistantText,
|
|
@@ -220,7 +223,6 @@ import {
|
|
|
220
223
|
insertUserMemoryCandidates,
|
|
221
224
|
invalidateMemory,
|
|
222
225
|
invalidateProject,
|
|
223
|
-
invalidateTrueRawTokenCache,
|
|
224
226
|
isConsumerReconnectTransient,
|
|
225
227
|
isDatabasePersisted,
|
|
226
228
|
isEmbeddingEnabled,
|
|
@@ -241,6 +243,7 @@ import {
|
|
|
241
243
|
markProjectLoadUntrusted,
|
|
242
244
|
memoryNeedsCue,
|
|
243
245
|
mergeMemoryStats,
|
|
246
|
+
migrateMagicContextConfigLocations,
|
|
244
247
|
mustMaterialize,
|
|
245
248
|
nextDueAtMs,
|
|
246
249
|
nextOccurrence,
|
|
@@ -262,6 +265,7 @@ import {
|
|
|
262
265
|
prepareCompartmentInjection,
|
|
263
266
|
primerOccurrenceKey,
|
|
264
267
|
primerOccurrenceUtcDay,
|
|
268
|
+
promptSurfaceHashMaterial,
|
|
265
269
|
promptSyncWithValidatedOutputRetry,
|
|
266
270
|
pruneAutoSearchHintDecisions,
|
|
267
271
|
pruneExpiredUserMemoryCandidates,
|
|
@@ -309,10 +313,14 @@ import {
|
|
|
309
313
|
resetProtectedTailNoEligibleHead,
|
|
310
314
|
resolveCompactionModeRecord,
|
|
311
315
|
resolveGitTopLevel,
|
|
316
|
+
resolveLegacyConfigSources,
|
|
317
|
+
resolveLegacyConfigSourcesForHarness,
|
|
318
|
+
resolveModelConfigOrDefault,
|
|
312
319
|
resolveOpenCodeProtectedTailBoundary,
|
|
313
320
|
resolveProjectIdentity,
|
|
314
321
|
resolveProjectIdentityForSession,
|
|
315
322
|
resolveProjectIdentityStrict,
|
|
323
|
+
resolvePromptSurface,
|
|
316
324
|
resolveStoredPathWorkspaceIdentity,
|
|
317
325
|
resolveWorkspaceIdentitySet,
|
|
318
326
|
resolveWorkspaceShareCategories,
|
|
@@ -374,7 +382,7 @@ import {
|
|
|
374
382
|
upsertCommits,
|
|
375
383
|
verificationFileExists,
|
|
376
384
|
withContentLanguageDirective
|
|
377
|
-
} from "./index-
|
|
385
|
+
} from "./index-fkyamz2w.js";
|
|
378
386
|
import {
|
|
379
387
|
deriveHistorianChunkTokens,
|
|
380
388
|
deriveTriggerBudget,
|
|
@@ -398,7 +406,7 @@ import {
|
|
|
398
406
|
getErrorMessage,
|
|
399
407
|
sendIgnoredMessage,
|
|
400
408
|
sendUserPrompt
|
|
401
|
-
} from "./index-
|
|
409
|
+
} from "./index-h5zjfesc.js";
|
|
402
410
|
import {
|
|
403
411
|
ToolMutationBatch,
|
|
404
412
|
advanceToolReclaimWatermark,
|
|
@@ -411,6 +419,7 @@ import {
|
|
|
411
419
|
createToolDropTarget,
|
|
412
420
|
deleteIndexedMessage,
|
|
413
421
|
estimateTokens,
|
|
422
|
+
estimateTrueRawMessageTokens,
|
|
414
423
|
extractInMemoryMessageViews,
|
|
415
424
|
extractTexts,
|
|
416
425
|
extractToolCallObservation,
|
|
@@ -424,6 +433,7 @@ import {
|
|
|
424
433
|
hasMeaningfulUserText,
|
|
425
434
|
indexMessagesAfterOrdinal,
|
|
426
435
|
indexSingleMessage,
|
|
436
|
+
invalidateTrueRawTokenCache,
|
|
427
437
|
isEditTool,
|
|
428
438
|
isFilePart,
|
|
429
439
|
isMessageIndexReconciledThrough,
|
|
@@ -453,7 +463,7 @@ import {
|
|
|
453
463
|
textMentionsRecentCommit,
|
|
454
464
|
updateSessionMeta,
|
|
455
465
|
withRawSessionMessageCache
|
|
456
|
-
} from "./index-
|
|
466
|
+
} from "./index-dpdnjawy.js";
|
|
457
467
|
import {
|
|
458
468
|
Database,
|
|
459
469
|
closeQuietly,
|
|
@@ -462,15 +472,17 @@ import {
|
|
|
462
472
|
isMidTurn,
|
|
463
473
|
openCodeDbExists,
|
|
464
474
|
withReadOnlySessionDb
|
|
465
|
-
} from "./index-
|
|
475
|
+
} from "./index-w0nygb4p.js";
|
|
466
476
|
import {
|
|
467
477
|
cleanupConflictWarnings,
|
|
468
|
-
detectConfigFile,
|
|
469
478
|
detectConflicts,
|
|
479
|
+
sendConflictWarning
|
|
480
|
+
} from "./index-8aaadh98.js";
|
|
481
|
+
import {
|
|
482
|
+
detectConfigFile,
|
|
470
483
|
parseJsonc,
|
|
471
|
-
sendConflictWarning,
|
|
472
484
|
stripJsonComments
|
|
473
|
-
} from "./index-
|
|
485
|
+
} from "./index-0c9dmw9m.js";
|
|
474
486
|
import {
|
|
475
487
|
ANNOUNCEMENT_FEATURES,
|
|
476
488
|
ANNOUNCEMENT_FOOTER,
|
|
@@ -8190,10 +8202,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8190
8202
|
replacer = null;
|
|
8191
8203
|
indent = EMPTY;
|
|
8192
8204
|
};
|
|
8193
|
-
var
|
|
8205
|
+
var join = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
|
|
8194
8206
|
var join_content = (inside, value, gap) => {
|
|
8195
8207
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
8196
|
-
return
|
|
8208
|
+
return join(comment, inside, gap);
|
|
8197
8209
|
};
|
|
8198
8210
|
var stringify_string = (holder, key, value) => {
|
|
8199
8211
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -8215,13 +8227,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8215
8227
|
if (i !== 0) {
|
|
8216
8228
|
inside += COMMA;
|
|
8217
8229
|
}
|
|
8218
|
-
const before =
|
|
8230
|
+
const before = join(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
8219
8231
|
inside += before || LF + deeper_gap;
|
|
8220
8232
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
8221
8233
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
8222
8234
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
8223
8235
|
}
|
|
8224
|
-
inside +=
|
|
8236
|
+
inside += join(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
8225
8237
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
8226
8238
|
};
|
|
8227
8239
|
var object_stringify = (value, gap) => {
|
|
@@ -8242,13 +8254,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
8242
8254
|
inside += COMMA;
|
|
8243
8255
|
}
|
|
8244
8256
|
first = false;
|
|
8245
|
-
const before =
|
|
8257
|
+
const before = join(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
8246
8258
|
inside += before || LF + deeper_gap;
|
|
8247
8259
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
8248
8260
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
8249
8261
|
};
|
|
8250
8262
|
keys.forEach(iteratee);
|
|
8251
|
-
inside +=
|
|
8263
|
+
inside += join(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
8252
8264
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
8253
8265
|
};
|
|
8254
8266
|
function stringify(key, holder, gap) {
|
|
@@ -8368,11 +8380,15 @@ function applyDisallowedTools(defaults, disallowed) {
|
|
|
8368
8380
|
function clampHiddenAgentStepLimit(value, cap) {
|
|
8369
8381
|
return typeof value === "number" && Number.isFinite(value) ? Math.min(value, cap) : cap;
|
|
8370
8382
|
}
|
|
8383
|
+
var HIDDEN_AGENT_DESCRIPTION = "Internal Magic Context maintenance agent. Not for general tasks — do not select for user work.";
|
|
8371
8384
|
function buildHiddenAgentRegistrations(args) {
|
|
8372
8385
|
const historianAllowedTools = applyDisallowedTools(["read", "aft_outline", "aft_zoom", "aft_search"], args.historianDisallowed);
|
|
8373
8386
|
return [
|
|
8374
8387
|
{
|
|
8375
8388
|
id: "dreamer",
|
|
8389
|
+
mode: "primary",
|
|
8390
|
+
hidden: true,
|
|
8391
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8376
8392
|
prompt: args.dreamerPrompt,
|
|
8377
8393
|
allowedTools: ["ctx_memory"],
|
|
8378
8394
|
maxSteps: 150,
|
|
@@ -8381,6 +8397,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8381
8397
|
},
|
|
8382
8398
|
{
|
|
8383
8399
|
id: "dreamer-docs",
|
|
8400
|
+
mode: "primary",
|
|
8401
|
+
hidden: true,
|
|
8402
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8384
8403
|
prompt: args.dreamerPrompt,
|
|
8385
8404
|
allowedTools: [
|
|
8386
8405
|
"read",
|
|
@@ -8399,6 +8418,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8399
8418
|
},
|
|
8400
8419
|
{
|
|
8401
8420
|
id: "dreamer-reviewer",
|
|
8421
|
+
mode: "primary",
|
|
8422
|
+
hidden: true,
|
|
8423
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8402
8424
|
prompt: args.dreamerPrompt,
|
|
8403
8425
|
allowedTools: [],
|
|
8404
8426
|
maxSteps: 4,
|
|
@@ -8407,6 +8429,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8407
8429
|
},
|
|
8408
8430
|
{
|
|
8409
8431
|
id: "dreamer-retrospective",
|
|
8432
|
+
mode: "primary",
|
|
8433
|
+
hidden: true,
|
|
8434
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8410
8435
|
prompt: args.dreamerPrompt,
|
|
8411
8436
|
allowedTools: ["ctx_search"],
|
|
8412
8437
|
maxSteps: 40,
|
|
@@ -8415,6 +8440,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8415
8440
|
},
|
|
8416
8441
|
{
|
|
8417
8442
|
id: "dreamer-primer-investigator",
|
|
8443
|
+
mode: "primary",
|
|
8444
|
+
hidden: true,
|
|
8445
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8418
8446
|
prompt: args.dreamerPrompt,
|
|
8419
8447
|
allowedTools: [
|
|
8420
8448
|
"read",
|
|
@@ -8431,6 +8459,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8431
8459
|
},
|
|
8432
8460
|
{
|
|
8433
8461
|
id: "dreamer-memory-mapper",
|
|
8462
|
+
mode: "primary",
|
|
8463
|
+
hidden: true,
|
|
8464
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8434
8465
|
prompt: args.dreamerPrompt,
|
|
8435
8466
|
allowedTools: ["read", "grep", "glob", "aft_outline", "aft_zoom", "aft_search"],
|
|
8436
8467
|
maxSteps: 60,
|
|
@@ -8439,6 +8470,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8439
8470
|
},
|
|
8440
8471
|
{
|
|
8441
8472
|
id: "dreamer-classifier",
|
|
8473
|
+
mode: "primary",
|
|
8474
|
+
hidden: true,
|
|
8475
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8442
8476
|
prompt: args.dreamerPrompt,
|
|
8443
8477
|
allowedTools: [],
|
|
8444
8478
|
maxSteps: 4,
|
|
@@ -8447,6 +8481,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8447
8481
|
},
|
|
8448
8482
|
{
|
|
8449
8483
|
id: "smart-note-compiler",
|
|
8484
|
+
mode: "primary",
|
|
8485
|
+
hidden: true,
|
|
8486
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8450
8487
|
prompt: args.smartNoteCompilerPrompt,
|
|
8451
8488
|
allowedTools: [],
|
|
8452
8489
|
maxSteps: 8,
|
|
@@ -8455,6 +8492,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8455
8492
|
},
|
|
8456
8493
|
{
|
|
8457
8494
|
id: "historian",
|
|
8495
|
+
mode: "primary",
|
|
8496
|
+
hidden: true,
|
|
8497
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8458
8498
|
prompt: args.historianPrompt,
|
|
8459
8499
|
allowedTools: historianAllowedTools,
|
|
8460
8500
|
maxSteps: 40,
|
|
@@ -8462,6 +8502,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8462
8502
|
},
|
|
8463
8503
|
{
|
|
8464
8504
|
id: "historian-recomp",
|
|
8505
|
+
mode: "primary",
|
|
8506
|
+
hidden: true,
|
|
8507
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8465
8508
|
prompt: args.historianRecompPrompt ?? args.historianPrompt,
|
|
8466
8509
|
allowedTools: historianAllowedTools,
|
|
8467
8510
|
maxSteps: 40,
|
|
@@ -8469,6 +8512,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8469
8512
|
},
|
|
8470
8513
|
{
|
|
8471
8514
|
id: "historian-editor",
|
|
8515
|
+
mode: "primary",
|
|
8516
|
+
hidden: true,
|
|
8517
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8472
8518
|
prompt: args.historianEditorPrompt,
|
|
8473
8519
|
allowedTools: historianAllowedTools,
|
|
8474
8520
|
maxSteps: 40,
|
|
@@ -8476,6 +8522,9 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8476
8522
|
},
|
|
8477
8523
|
{
|
|
8478
8524
|
id: "sidekick",
|
|
8525
|
+
mode: "primary",
|
|
8526
|
+
hidden: true,
|
|
8527
|
+
description: HIDDEN_AGENT_DESCRIPTION,
|
|
8479
8528
|
prompt: args.sidekickPrompt,
|
|
8480
8529
|
allowedTools: ["ctx_search", "aft_outline", "aft_zoom"],
|
|
8481
8530
|
maxSteps: 40,
|
|
@@ -8483,7 +8532,7 @@ function buildHiddenAgentRegistrations(args) {
|
|
|
8483
8532
|
}
|
|
8484
8533
|
];
|
|
8485
8534
|
}
|
|
8486
|
-
function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agentLabel, lockPermissions = false) {
|
|
8535
|
+
function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agentLabel, lockPermissions = false, description) {
|
|
8487
8536
|
const {
|
|
8488
8537
|
permission: overridePermission,
|
|
8489
8538
|
tools: overrideTools,
|
|
@@ -8510,13 +8559,14 @@ function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agent
|
|
|
8510
8559
|
...basePermission,
|
|
8511
8560
|
...lockPermissions ? {} : overridePermission ?? {}
|
|
8512
8561
|
},
|
|
8513
|
-
mode: "
|
|
8514
|
-
hidden: true
|
|
8562
|
+
mode: "primary",
|
|
8563
|
+
hidden: true,
|
|
8564
|
+
...description !== undefined ? { description } : {}
|
|
8515
8565
|
};
|
|
8516
8566
|
}
|
|
8517
8567
|
|
|
8518
8568
|
// src/config/index.ts
|
|
8519
|
-
import { existsSync as
|
|
8569
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
8520
8570
|
|
|
8521
8571
|
// src/config/agent-disable.ts
|
|
8522
8572
|
var COMPACTION_ENABLED_PATH = `compaction${"."}enabled`;
|
|
@@ -8578,384 +8628,6 @@ function migrateLegacyAgentEnabledInMemory(rawConfig, warnings) {
|
|
|
8578
8628
|
return patched;
|
|
8579
8629
|
}
|
|
8580
8630
|
|
|
8581
|
-
// src/config/migrate-config-location.ts
|
|
8582
|
-
import {
|
|
8583
|
-
closeSync,
|
|
8584
|
-
existsSync,
|
|
8585
|
-
mkdirSync,
|
|
8586
|
-
openSync,
|
|
8587
|
-
readFileSync,
|
|
8588
|
-
renameSync,
|
|
8589
|
-
rmSync,
|
|
8590
|
-
statSync,
|
|
8591
|
-
unlinkSync,
|
|
8592
|
-
writeFileSync
|
|
8593
|
-
} from "node:fs";
|
|
8594
|
-
import { homedir } from "node:os";
|
|
8595
|
-
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
8596
|
-
var CONFIG_FILE_BASENAME = "magic-context";
|
|
8597
|
-
var MOVED_MARKER_SUFFIX = ".MOVED_READPLEASE";
|
|
8598
|
-
function homeDir() {
|
|
8599
|
-
if (process.platform === "win32") {
|
|
8600
|
-
return process.env.USERPROFILE || process.env.HOME || homedir();
|
|
8601
|
-
}
|
|
8602
|
-
return process.env.HOME || homedir();
|
|
8603
|
-
}
|
|
8604
|
-
function configHome() {
|
|
8605
|
-
const xdg = process.env.XDG_CONFIG_HOME;
|
|
8606
|
-
if (xdg && isAbsolute(xdg))
|
|
8607
|
-
return xdg;
|
|
8608
|
-
return join(homeDir(), ".config");
|
|
8609
|
-
}
|
|
8610
|
-
function cortexKitUserConfigBasePath() {
|
|
8611
|
-
return join(configHome(), "cortexkit", CONFIG_FILE_BASENAME);
|
|
8612
|
-
}
|
|
8613
|
-
function cortexKitProjectConfigBasePath(directory) {
|
|
8614
|
-
return join(directory, ".cortexkit", CONFIG_FILE_BASENAME);
|
|
8615
|
-
}
|
|
8616
|
-
function resolveCortexKitUserConfigPath() {
|
|
8617
|
-
return `${cortexKitUserConfigBasePath()}.jsonc`;
|
|
8618
|
-
}
|
|
8619
|
-
function resolveCortexKitProjectConfigPath(directory) {
|
|
8620
|
-
return `${cortexKitProjectConfigBasePath(directory)}.jsonc`;
|
|
8621
|
-
}
|
|
8622
|
-
function legacySourcesForBase(basePath, label) {
|
|
8623
|
-
return [
|
|
8624
|
-
{ path: `${basePath}.jsonc`, label: `${label} magic-context.jsonc` },
|
|
8625
|
-
{ path: `${basePath}.json`, label: `${label} magic-context.json` }
|
|
8626
|
-
];
|
|
8627
|
-
}
|
|
8628
|
-
function userScopeConfigPaths() {
|
|
8629
|
-
return new Set([
|
|
8630
|
-
`${cortexKitUserConfigBasePath()}.jsonc`,
|
|
8631
|
-
`${cortexKitUserConfigBasePath()}.json`,
|
|
8632
|
-
join(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.jsonc`),
|
|
8633
|
-
join(configHome(), "opencode", `${CONFIG_FILE_BASENAME}.json`),
|
|
8634
|
-
join(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.jsonc`),
|
|
8635
|
-
join(homeDir(), ".pi", "agent", `${CONFIG_FILE_BASENAME}.json`)
|
|
8636
|
-
]);
|
|
8637
|
-
}
|
|
8638
|
-
function resolveLegacyConfigSources(directory) {
|
|
8639
|
-
const userPaths = userScopeConfigPaths();
|
|
8640
|
-
return {
|
|
8641
|
-
user: [
|
|
8642
|
-
...legacySourcesForBase(join(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
|
|
8643
|
-
...legacySourcesForBase(join(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user")
|
|
8644
|
-
],
|
|
8645
|
-
project: [
|
|
8646
|
-
...legacySourcesForBase(join(directory, CONFIG_FILE_BASENAME), "project root"),
|
|
8647
|
-
...legacySourcesForBase(join(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project"),
|
|
8648
|
-
...legacySourcesForBase(join(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
|
|
8649
|
-
].filter((source) => !userPaths.has(source.path))
|
|
8650
|
-
};
|
|
8651
|
-
}
|
|
8652
|
-
function resolveLegacyConfigSourcesForHarness(directory, harness) {
|
|
8653
|
-
if (harness === "pi") {
|
|
8654
|
-
return {
|
|
8655
|
-
user: legacySourcesForBase(join(homeDir(), ".pi", "agent", CONFIG_FILE_BASENAME), "Pi user"),
|
|
8656
|
-
project: legacySourcesForBase(join(directory, ".pi", CONFIG_FILE_BASENAME), "Pi project")
|
|
8657
|
-
};
|
|
8658
|
-
}
|
|
8659
|
-
return {
|
|
8660
|
-
user: legacySourcesForBase(join(configHome(), "opencode", CONFIG_FILE_BASENAME), "OpenCode user"),
|
|
8661
|
-
project: [
|
|
8662
|
-
...legacySourcesForBase(join(directory, CONFIG_FILE_BASENAME), "project root"),
|
|
8663
|
-
...legacySourcesForBase(join(directory, ".opencode", CONFIG_FILE_BASENAME), "OpenCode project")
|
|
8664
|
-
]
|
|
8665
|
-
};
|
|
8666
|
-
}
|
|
8667
|
-
function stripJsoncForParse(input) {
|
|
8668
|
-
let out = "";
|
|
8669
|
-
let inString = false;
|
|
8670
|
-
let escaped = false;
|
|
8671
|
-
for (let i = 0;i < input.length; i++) {
|
|
8672
|
-
const ch = input[i];
|
|
8673
|
-
const next = input[i + 1];
|
|
8674
|
-
if (inString) {
|
|
8675
|
-
out += ch;
|
|
8676
|
-
if (escaped)
|
|
8677
|
-
escaped = false;
|
|
8678
|
-
else if (ch === "\\")
|
|
8679
|
-
escaped = true;
|
|
8680
|
-
else if (ch === '"')
|
|
8681
|
-
inString = false;
|
|
8682
|
-
continue;
|
|
8683
|
-
}
|
|
8684
|
-
if (ch === '"') {
|
|
8685
|
-
inString = true;
|
|
8686
|
-
out += ch;
|
|
8687
|
-
continue;
|
|
8688
|
-
}
|
|
8689
|
-
if (ch === "/" && next === "/") {
|
|
8690
|
-
while (i < input.length && input[i] !== `
|
|
8691
|
-
`)
|
|
8692
|
-
i++;
|
|
8693
|
-
out += `
|
|
8694
|
-
`;
|
|
8695
|
-
continue;
|
|
8696
|
-
}
|
|
8697
|
-
if (ch === "/" && next === "*") {
|
|
8698
|
-
i += 2;
|
|
8699
|
-
while (i < input.length && !(input[i] === "*" && input[i + 1] === "/"))
|
|
8700
|
-
i++;
|
|
8701
|
-
i++;
|
|
8702
|
-
out += " ";
|
|
8703
|
-
continue;
|
|
8704
|
-
}
|
|
8705
|
-
out += ch;
|
|
8706
|
-
}
|
|
8707
|
-
let withoutTrailingCommas = "";
|
|
8708
|
-
inString = false;
|
|
8709
|
-
escaped = false;
|
|
8710
|
-
for (let i = 0;i < out.length; i++) {
|
|
8711
|
-
const ch = out[i];
|
|
8712
|
-
if (inString) {
|
|
8713
|
-
withoutTrailingCommas += ch;
|
|
8714
|
-
if (escaped)
|
|
8715
|
-
escaped = false;
|
|
8716
|
-
else if (ch === "\\")
|
|
8717
|
-
escaped = true;
|
|
8718
|
-
else if (ch === '"')
|
|
8719
|
-
inString = false;
|
|
8720
|
-
continue;
|
|
8721
|
-
}
|
|
8722
|
-
if (ch === '"') {
|
|
8723
|
-
inString = true;
|
|
8724
|
-
withoutTrailingCommas += ch;
|
|
8725
|
-
continue;
|
|
8726
|
-
}
|
|
8727
|
-
if (ch === ",") {
|
|
8728
|
-
let j = i + 1;
|
|
8729
|
-
while (j < out.length && /\s/.test(out[j]))
|
|
8730
|
-
j++;
|
|
8731
|
-
if (out[j] === "}" || out[j] === "]")
|
|
8732
|
-
continue;
|
|
8733
|
-
}
|
|
8734
|
-
withoutTrailingCommas += ch;
|
|
8735
|
-
}
|
|
8736
|
-
return withoutTrailingCommas;
|
|
8737
|
-
}
|
|
8738
|
-
function sortJson(value) {
|
|
8739
|
-
if (Array.isArray(value))
|
|
8740
|
-
return value.map(sortJson);
|
|
8741
|
-
if (value && typeof value === "object") {
|
|
8742
|
-
const sorted = {};
|
|
8743
|
-
for (const key of Object.keys(value).sort()) {
|
|
8744
|
-
sorted[key] = sortJson(value[key]);
|
|
8745
|
-
}
|
|
8746
|
-
return sorted;
|
|
8747
|
-
}
|
|
8748
|
-
return value;
|
|
8749
|
-
}
|
|
8750
|
-
function normalizedJsoncSemantics(content) {
|
|
8751
|
-
return JSON.stringify(sortJson(JSON.parse(stripJsoncForParse(content))));
|
|
8752
|
-
}
|
|
8753
|
-
function fileSemanticsMatch(a, b) {
|
|
8754
|
-
try {
|
|
8755
|
-
return normalizedJsoncSemantics(a) === normalizedJsoncSemantics(b);
|
|
8756
|
-
} catch {
|
|
8757
|
-
return a === b;
|
|
8758
|
-
}
|
|
8759
|
-
}
|
|
8760
|
-
var CONFIG_LOCK_STALE_MS = 4000;
|
|
8761
|
-
function acquireConfigMigrationLock(lockDir) {
|
|
8762
|
-
for (let attempt = 0;attempt < 2; attempt++) {
|
|
8763
|
-
try {
|
|
8764
|
-
mkdirSync(lockDir, { recursive: false });
|
|
8765
|
-
return () => {
|
|
8766
|
-
try {
|
|
8767
|
-
rmSync(lockDir, { recursive: true, force: true });
|
|
8768
|
-
} catch {}
|
|
8769
|
-
};
|
|
8770
|
-
} catch (err) {
|
|
8771
|
-
const code = err?.code;
|
|
8772
|
-
if (code !== "EEXIST")
|
|
8773
|
-
throw err;
|
|
8774
|
-
try {
|
|
8775
|
-
const ageMs = Date.now() - statSync(lockDir).mtimeMs;
|
|
8776
|
-
if (ageMs > CONFIG_LOCK_STALE_MS) {
|
|
8777
|
-
rmSync(lockDir, { recursive: true, force: true });
|
|
8778
|
-
continue;
|
|
8779
|
-
}
|
|
8780
|
-
} catch {
|
|
8781
|
-
continue;
|
|
8782
|
-
}
|
|
8783
|
-
return null;
|
|
8784
|
-
}
|
|
8785
|
-
}
|
|
8786
|
-
return null;
|
|
8787
|
-
}
|
|
8788
|
-
function atomicCopyConfigFile(sourcePath, targetPath) {
|
|
8789
|
-
mkdirSync(dirname(targetPath), { recursive: true });
|
|
8790
|
-
const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
8791
|
-
let fd = null;
|
|
8792
|
-
try {
|
|
8793
|
-
fd = openSync(tmpPath, "wx", 384);
|
|
8794
|
-
writeFileSync(fd, readFileSync(sourcePath));
|
|
8795
|
-
closeSync(fd);
|
|
8796
|
-
fd = null;
|
|
8797
|
-
renameSync(tmpPath, targetPath);
|
|
8798
|
-
} catch (err) {
|
|
8799
|
-
if (fd !== null) {
|
|
8800
|
-
try {
|
|
8801
|
-
closeSync(fd);
|
|
8802
|
-
} catch {}
|
|
8803
|
-
}
|
|
8804
|
-
try {
|
|
8805
|
-
unlinkSync(tmpPath);
|
|
8806
|
-
} catch {}
|
|
8807
|
-
throw err;
|
|
8808
|
-
}
|
|
8809
|
-
}
|
|
8810
|
-
function atomicWriteConfigFile(targetPath, content) {
|
|
8811
|
-
mkdirSync(dirname(targetPath), { recursive: true });
|
|
8812
|
-
const tmpPath = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
|
|
8813
|
-
let fd = null;
|
|
8814
|
-
try {
|
|
8815
|
-
fd = openSync(tmpPath, "wx", 384);
|
|
8816
|
-
writeFileSync(fd, content);
|
|
8817
|
-
closeSync(fd);
|
|
8818
|
-
fd = null;
|
|
8819
|
-
renameSync(tmpPath, targetPath);
|
|
8820
|
-
} catch (err) {
|
|
8821
|
-
if (fd !== null) {
|
|
8822
|
-
try {
|
|
8823
|
-
closeSync(fd);
|
|
8824
|
-
} catch {}
|
|
8825
|
-
}
|
|
8826
|
-
try {
|
|
8827
|
-
unlinkSync(tmpPath);
|
|
8828
|
-
} catch {}
|
|
8829
|
-
throw err;
|
|
8830
|
-
}
|
|
8831
|
-
}
|
|
8832
|
-
function movedMarkerContent(targetPath, originalName, originalContent) {
|
|
8833
|
-
const header = [
|
|
8834
|
-
"// Magic Context configuration moved.",
|
|
8835
|
-
"//",
|
|
8836
|
-
"// Magic Context now reads its configuration from one shared CortexKit",
|
|
8837
|
-
"// location instead of a per-agent path. The settings that were in this",
|
|
8838
|
-
"// file have been moved to:",
|
|
8839
|
-
"//",
|
|
8840
|
-
`// ${targetPath}`,
|
|
8841
|
-
"//",
|
|
8842
|
-
"// Edit that file to change Magic Context settings. This location is no",
|
|
8843
|
-
"// longer read by Magic Context.",
|
|
8844
|
-
"//",
|
|
8845
|
-
`// To undo, rename this file back to "${originalName}" (and remove the`,
|
|
8846
|
-
"// CortexKit copy above if you want this location to take precedence).",
|
|
8847
|
-
"//",
|
|
8848
|
-
"// Your original settings are preserved below for reference.",
|
|
8849
|
-
"",
|
|
8850
|
-
""
|
|
8851
|
-
].join(`
|
|
8852
|
-
`);
|
|
8853
|
-
return `${header}${originalContent}`;
|
|
8854
|
-
}
|
|
8855
|
-
function markLegacySourcesMovedAside(sources, targetPath, logger) {
|
|
8856
|
-
const warnings = [];
|
|
8857
|
-
const info = logger?.info ?? logger?.log;
|
|
8858
|
-
for (const source of sources) {
|
|
8859
|
-
const markerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
|
|
8860
|
-
try {
|
|
8861
|
-
const original = readFileSync(source.path, "utf-8");
|
|
8862
|
-
atomicWriteConfigFile(markerPath, movedMarkerContent(targetPath, basename(source.path), original));
|
|
8863
|
-
unlinkSync(source.path);
|
|
8864
|
-
info?.(`Moved legacy Magic Context config ${source.path} aside to ${markerPath}; now reading ${targetPath}`);
|
|
8865
|
-
} catch (err) {
|
|
8866
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
8867
|
-
warnings.push(`Magic Context could not move legacy config ${source.path} aside (${msg}); it is now stale and ignored. Delete it manually — config is read from ${targetPath}.`);
|
|
8868
|
-
logger?.warn?.(`Could not move legacy Magic Context config ${source.path} aside (${msg}); reading ${targetPath}`);
|
|
8869
|
-
}
|
|
8870
|
-
}
|
|
8871
|
-
return warnings;
|
|
8872
|
-
}
|
|
8873
|
-
function visibleConfigMigrationWarning(scope, targetPath, paths, reason) {
|
|
8874
|
-
const uniquePaths = [...new Set([targetPath, ...paths])];
|
|
8875
|
-
return `Magic Context ${scope} config migration refused: ${reason}. ` + `Legacy and CortexKit config paths collapse to one file, but Magic Context will not overwrite or merge them automatically. ` + `Please consolidate manually into ${targetPath}. Paths: ${uniquePaths.join(" ; ")}`;
|
|
8876
|
-
}
|
|
8877
|
-
function migrateConfigFile(opts) {
|
|
8878
|
-
const warnings = [];
|
|
8879
|
-
const existingSources = opts.legacySources.filter((source) => existsSync(source.path));
|
|
8880
|
-
const info = opts.logger?.info ?? opts.logger?.log;
|
|
8881
|
-
if (existingSources.length === 0) {
|
|
8882
|
-
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
8883
|
-
}
|
|
8884
|
-
mkdirSync(dirname(opts.targetPath), { recursive: true });
|
|
8885
|
-
const release = acquireConfigMigrationLock(`${opts.targetPath}.lock`);
|
|
8886
|
-
if (!release) {
|
|
8887
|
-
warnings.push(`Config migration for ${opts.scope} skipped this run (another instance is migrating); will retry on next start.`);
|
|
8888
|
-
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
8889
|
-
}
|
|
8890
|
-
try {
|
|
8891
|
-
const sources = existingSources.map((source) => ({
|
|
8892
|
-
...source,
|
|
8893
|
-
content: readFileSync(source.path, "utf-8")
|
|
8894
|
-
}));
|
|
8895
|
-
if (existsSync(opts.targetPath)) {
|
|
8896
|
-
const targetContent = readFileSync(opts.targetPath, "utf-8");
|
|
8897
|
-
const differing2 = sources.filter((source) => !fileSemanticsMatch(source.content, targetContent));
|
|
8898
|
-
if (differing2.length > 0) {
|
|
8899
|
-
const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, differing2.map((source) => source.path), "the CortexKit target already exists with different settings");
|
|
8900
|
-
warnings.push(message);
|
|
8901
|
-
opts.logger?.warn?.(message);
|
|
8902
|
-
return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
|
|
8903
|
-
}
|
|
8904
|
-
info?.(`Magic Context ${opts.scope} config already present at ${opts.targetPath}; legacy copies match`);
|
|
8905
|
-
warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
|
|
8906
|
-
return { migrated: false, conflict: false, targetPath: opts.targetPath, warnings };
|
|
8907
|
-
}
|
|
8908
|
-
const first = sources[0];
|
|
8909
|
-
const differing = sources.filter((source) => !fileSemanticsMatch(source.content, first.content));
|
|
8910
|
-
if (differing.length > 0) {
|
|
8911
|
-
const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, sources.map((source) => source.path), "multiple legacy sources have different settings");
|
|
8912
|
-
warnings.push(message);
|
|
8913
|
-
opts.logger?.warn?.(message);
|
|
8914
|
-
return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
|
|
8915
|
-
}
|
|
8916
|
-
atomicCopyConfigFile(first.path, opts.targetPath);
|
|
8917
|
-
info?.(`Migrated Magic Context ${opts.scope} config from ${first.path} to ${opts.targetPath}`);
|
|
8918
|
-
warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
|
|
8919
|
-
return {
|
|
8920
|
-
migrated: true,
|
|
8921
|
-
conflict: false,
|
|
8922
|
-
sourcePath: first.path,
|
|
8923
|
-
targetPath: opts.targetPath,
|
|
8924
|
-
warnings
|
|
8925
|
-
};
|
|
8926
|
-
} catch (err) {
|
|
8927
|
-
const message = visibleConfigMigrationWarning(opts.scope, opts.targetPath, existingSources.map((source) => source.path), `migration failed (${err instanceof Error ? err.message : String(err)})`);
|
|
8928
|
-
warnings.push(message);
|
|
8929
|
-
opts.logger?.warn?.(message);
|
|
8930
|
-
return { migrated: false, conflict: true, targetPath: opts.targetPath, warnings };
|
|
8931
|
-
} finally {
|
|
8932
|
-
release();
|
|
8933
|
-
}
|
|
8934
|
-
}
|
|
8935
|
-
function migrateMagicContextConfigLocations(directory, logger) {
|
|
8936
|
-
const warnings = [];
|
|
8937
|
-
const legacy = resolveLegacyConfigSources(directory);
|
|
8938
|
-
try {
|
|
8939
|
-
warnings.push(...migrateConfigFile({
|
|
8940
|
-
scope: "user",
|
|
8941
|
-
targetPath: resolveCortexKitUserConfigPath(),
|
|
8942
|
-
legacySources: legacy.user,
|
|
8943
|
-
logger
|
|
8944
|
-
}).warnings);
|
|
8945
|
-
warnings.push(...migrateConfigFile({
|
|
8946
|
-
scope: "project",
|
|
8947
|
-
targetPath: resolveCortexKitProjectConfigPath(directory),
|
|
8948
|
-
legacySources: legacy.project,
|
|
8949
|
-
logger
|
|
8950
|
-
}).warnings);
|
|
8951
|
-
} catch (err) {
|
|
8952
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
8953
|
-
logger?.warn?.(`Magic Context config-location migration error (continuing): ${msg}`);
|
|
8954
|
-
warnings.push(`Magic Context config-location migration error: ${msg}`);
|
|
8955
|
-
}
|
|
8956
|
-
return warnings;
|
|
8957
|
-
}
|
|
8958
|
-
|
|
8959
8631
|
// src/config/migrate-dreamer-v2.ts
|
|
8960
8632
|
var OLD_VERIFY_TASK = "verify";
|
|
8961
8633
|
var OLD_CURATE_TASKS = ["consolidate", "archive-stale", "improve"];
|
|
@@ -9267,6 +8939,7 @@ function migrateLegacyExperimental(rawConfig, warnings) {
|
|
|
9267
8939
|
// src/config/project-security.ts
|
|
9268
8940
|
var HIDDEN_AGENT_KEYS = ["historian", "dreamer", "sidekick"];
|
|
9269
8941
|
var HISTORIAN_USER_ONLY_FIELDS = ["model", "fallback_models"];
|
|
8942
|
+
var PROMPT_SURFACE_USER_ONLY_FIELDS = ["guidance_override_path", "tool_descriptions"];
|
|
9270
8943
|
var AGENT_ESCALATION_FIELDS = ["prompt", "permission", "tools", "system_prompt"];
|
|
9271
8944
|
var EMBEDDING_DESTINATION_FIELDS = ["endpoint", "provider", "fallback_provider"];
|
|
9272
8945
|
var PERCENTAGE_THRESHOLD_REASON = "security: a repository may only raise compaction thresholds above the user's effective value; it cannot force earlier historian work or cloned-repo cost escalation.";
|
|
@@ -9402,6 +9075,19 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
9402
9075
|
delete storage.enforce_private_permissions;
|
|
9403
9076
|
warnings.push("Ignoring storage.enforce_private_permissions from project config (security: only user-level config may opt into externally managed shared storage permissions).");
|
|
9404
9077
|
}
|
|
9078
|
+
const promptSurface = projectRaw.prompt_surface;
|
|
9079
|
+
if (isPlainObject(promptSurface)) {
|
|
9080
|
+
const removed = [];
|
|
9081
|
+
for (const field of PROMPT_SURFACE_USER_ONLY_FIELDS) {
|
|
9082
|
+
if (field in promptSurface) {
|
|
9083
|
+
delete promptSurface[field];
|
|
9084
|
+
removed.push(field);
|
|
9085
|
+
}
|
|
9086
|
+
}
|
|
9087
|
+
if (removed.length > 0) {
|
|
9088
|
+
warnings.push(`Ignoring prompt_surface.${removed.join("/")} from project config (security: repositories may select prompt presets but only user config may provide guidance or tool-description text).`);
|
|
9089
|
+
}
|
|
9090
|
+
}
|
|
9405
9091
|
const pi = projectRaw.pi;
|
|
9406
9092
|
if (isPlainObject(pi) && "subagent_extensions" in pi) {
|
|
9407
9093
|
delete pi.subagent_extensions;
|
|
@@ -9649,13 +9335,13 @@ function resolveTransformMode(args) {
|
|
|
9649
9335
|
}
|
|
9650
9336
|
|
|
9651
9337
|
// src/config/variable.ts
|
|
9652
|
-
import { existsSync
|
|
9653
|
-
import { homedir
|
|
9654
|
-
import { dirname
|
|
9338
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
9339
|
+
import { homedir } from "node:os";
|
|
9340
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
9655
9341
|
var ENV_PATTERN = /\{env:([^}]+)\}/g;
|
|
9656
9342
|
var FILE_PATTERN = /\{file:([^}]+)\}/g;
|
|
9657
9343
|
function sensitiveFilePathReason(resolvedPath) {
|
|
9658
|
-
const home =
|
|
9344
|
+
const home = homedir();
|
|
9659
9345
|
const sensitiveDirs = [
|
|
9660
9346
|
{ dir: resolve(home, ".ssh"), label: "SSH keys" },
|
|
9661
9347
|
{ dir: resolve(home, ".aws"), label: "AWS credentials" },
|
|
@@ -9700,7 +9386,7 @@ function substituteConfigVariables(input) {
|
|
|
9700
9386
|
if (fileMatches.length === 0) {
|
|
9701
9387
|
return { text, warnings };
|
|
9702
9388
|
}
|
|
9703
|
-
const configDir = input.configPath ?
|
|
9389
|
+
const configDir = input.configPath ? dirname(input.configPath) : process.cwd();
|
|
9704
9390
|
let output = "";
|
|
9705
9391
|
let cursor = 0;
|
|
9706
9392
|
for (const match of fileMatches) {
|
|
@@ -9718,21 +9404,21 @@ function substituteConfigVariables(input) {
|
|
|
9718
9404
|
}
|
|
9719
9405
|
let filePath = rawPath.trim();
|
|
9720
9406
|
if (filePath.startsWith("~/")) {
|
|
9721
|
-
filePath = resolve(
|
|
9722
|
-
} else if (!
|
|
9407
|
+
filePath = resolve(homedir(), filePath.slice(2));
|
|
9408
|
+
} else if (!isAbsolute(filePath)) {
|
|
9723
9409
|
filePath = resolve(configDir, filePath);
|
|
9724
9410
|
}
|
|
9725
9411
|
const sensitiveReason = sensitiveFilePathReason(filePath);
|
|
9726
9412
|
if (sensitiveReason) {
|
|
9727
9413
|
warnings.push(`${token} resolves to a sensitive path (${sensitiveReason}: ${filePath}); ` + "inlining its contents into config — make sure this is intentional.");
|
|
9728
9414
|
}
|
|
9729
|
-
if (!
|
|
9415
|
+
if (!existsSync(filePath)) {
|
|
9730
9416
|
warnings.push(`File not found for ${token} (resolved to ${filePath}); using empty string`);
|
|
9731
9417
|
continue;
|
|
9732
9418
|
}
|
|
9733
9419
|
let contents;
|
|
9734
9420
|
try {
|
|
9735
|
-
contents =
|
|
9421
|
+
contents = readFileSync(filePath, "utf-8").trim();
|
|
9736
9422
|
} catch (error) {
|
|
9737
9423
|
const message = error instanceof Error ? error.message : String(error);
|
|
9738
9424
|
warnings.push(`Failed to read file for ${token} (${filePath}): ${message}; using empty string`);
|
|
@@ -9752,15 +9438,15 @@ function getProjectConfigBasePath(directory) {
|
|
|
9752
9438
|
return cortexKitProjectConfigBasePath(directory);
|
|
9753
9439
|
}
|
|
9754
9440
|
function resolveLegacyReadFallback(sources) {
|
|
9755
|
-
return { source: sources.find((s) =>
|
|
9441
|
+
return { source: sources.find((s) => existsSync2(s.path)) ?? null };
|
|
9756
9442
|
}
|
|
9757
9443
|
function loadConfigFileDetailed(configPath, source) {
|
|
9758
|
-
if (!
|
|
9444
|
+
if (!existsSync2(configPath)) {
|
|
9759
9445
|
return null;
|
|
9760
9446
|
}
|
|
9761
9447
|
let rawText;
|
|
9762
9448
|
try {
|
|
9763
|
-
rawText =
|
|
9449
|
+
rawText = readFileSync2(configPath, "utf-8");
|
|
9764
9450
|
} catch (error) {
|
|
9765
9451
|
return {
|
|
9766
9452
|
config: {},
|
|
@@ -9919,9 +9605,6 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
9919
9605
|
configWarnings: [...preMigrationWarnings, ...warnings]
|
|
9920
9606
|
};
|
|
9921
9607
|
}
|
|
9922
|
-
function loadPluginConfig(directory) {
|
|
9923
|
-
return loadPluginConfigDetailed(directory).config;
|
|
9924
|
-
}
|
|
9925
9608
|
function hasUserTierSubcConfig(config) {
|
|
9926
9609
|
const subc = config?.subc;
|
|
9927
9610
|
if (typeof subc !== "object" || subc === null || Array.isArray(subc))
|
|
@@ -9977,8 +9660,8 @@ function loadPluginConfigDetailed(directory) {
|
|
|
9977
9660
|
const harnessLegacy = resolveLegacyConfigSourcesForHarness(directory, "opencode");
|
|
9978
9661
|
const userLegacyFallback = userDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.user) : { source: null };
|
|
9979
9662
|
const projectLegacyFallback = projectDetected.format === "none" ? resolveLegacyReadFallback(harnessLegacy.project) : { source: null };
|
|
9980
|
-
const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) =>
|
|
9981
|
-
const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) =>
|
|
9663
|
+
const legacyUserUnmigrated = userDetected.format === "none" && !userLegacyFallback.source && legacySources.user.some((source) => existsSync2(source.path));
|
|
9664
|
+
const legacyProjectUnmigrated = projectDetected.format === "none" && !projectLegacyFallback.source && legacySources.project.some((source) => existsSync2(source.path));
|
|
9982
9665
|
const userLoaded = userDetected.format !== "none" ? loadConfigFileDetailed(userDetected.path, "user") : userLegacyFallback.source ? loadConfigFileDetailed(userLegacyFallback.source.path, "user") : null;
|
|
9983
9666
|
const projectLoaded = projectDetected.format !== "none" ? loadConfigFileDetailed(projectDetected.path, "project") : projectLegacyFallback.source ? loadConfigFileDetailed(projectLegacyFallback.source.path, "project") : null;
|
|
9984
9667
|
const allWarnings = [];
|
|
@@ -10050,6 +9733,7 @@ function loadPluginConfigDetailed(directory) {
|
|
|
10050
9733
|
};
|
|
10051
9734
|
return {
|
|
10052
9735
|
config,
|
|
9736
|
+
registrationPromptSurface: trustedBaseConfig.prompt_surface,
|
|
10053
9737
|
loadOutcome: combinedOutcome({ sources, substitutionFailures, recoveredTopLevelKeys }),
|
|
10054
9738
|
sources,
|
|
10055
9739
|
substitutionFailures,
|
|
@@ -10098,10 +9782,10 @@ function getMagicContextBuiltinCommands(compactionEnabled = true) {
|
|
|
10098
9782
|
}
|
|
10099
9783
|
|
|
10100
9784
|
// src/features/magic-context/dreamer/open-opencode-db.ts
|
|
10101
|
-
import { existsSync as
|
|
9785
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
10102
9786
|
function openOpenCodeDb() {
|
|
10103
9787
|
const dbPath = getOpenCodeDbPath();
|
|
10104
|
-
if (!
|
|
9788
|
+
if (!existsSync3(dbPath)) {
|
|
10105
9789
|
log(`[dreamer] OpenCode DB not found at ${dbPath} — skipping OpenCode history scan`);
|
|
10106
9790
|
return null;
|
|
10107
9791
|
}
|
|
@@ -10588,7 +10272,7 @@ function getLastHookInitFailure() {
|
|
|
10588
10272
|
|
|
10589
10273
|
// src/features/magic-context/session-project-backfill.ts
|
|
10590
10274
|
import { randomUUID } from "node:crypto";
|
|
10591
|
-
import { existsSync as
|
|
10275
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
10592
10276
|
var LEASE_TTL_MS = 10 * 60 * 1000;
|
|
10593
10277
|
var SESSION_PAGE_SIZE = 100;
|
|
10594
10278
|
var SESSION_QUERY_CHUNK_SIZE = 250;
|
|
@@ -10784,7 +10468,7 @@ async function runSessionProjectBackfill(db, source, options = {}) {
|
|
|
10784
10468
|
if (!session.directory) {
|
|
10785
10469
|
result.skippedEmptyDirectories += 1;
|
|
10786
10470
|
} else {
|
|
10787
|
-
const stillExists = existenceCache.get(session.directory) ??
|
|
10471
|
+
const stillExists = existenceCache.get(session.directory) ?? existsSync4(session.directory);
|
|
10788
10472
|
existenceCache.set(session.directory, stillExists);
|
|
10789
10473
|
if (!stillExists) {
|
|
10790
10474
|
result.skippedDeadDirectories += 1;
|
|
@@ -11209,45 +10893,45 @@ async function runDeferredV22Backfill(db, options = {}) {
|
|
|
11209
10893
|
}
|
|
11210
10894
|
|
|
11211
10895
|
// src/hooks/auto-update-checker/index.ts
|
|
11212
|
-
import { existsSync as
|
|
11213
|
-
import { dirname as
|
|
10896
|
+
import { existsSync as existsSync6, mkdirSync, readFileSync as readFileSync4, renameSync as renameSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
10897
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
11214
10898
|
|
|
11215
10899
|
// src/hooks/auto-update-checker/checker.ts
|
|
11216
10900
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
11217
10901
|
import { spawn } from "node:child_process";
|
|
11218
10902
|
import {
|
|
11219
10903
|
accessSync,
|
|
11220
|
-
existsSync as
|
|
10904
|
+
existsSync as existsSync5,
|
|
11221
10905
|
constants as fsConstants,
|
|
11222
|
-
readFileSync as
|
|
11223
|
-
renameSync
|
|
11224
|
-
statSync
|
|
11225
|
-
writeFileSync
|
|
10906
|
+
readFileSync as readFileSync3,
|
|
10907
|
+
renameSync,
|
|
10908
|
+
statSync,
|
|
10909
|
+
writeFileSync
|
|
11226
10910
|
} from "node:fs";
|
|
11227
|
-
import { dirname as
|
|
10911
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, resolve as resolve2 } from "node:path";
|
|
11228
10912
|
import { fileURLToPath } from "node:url";
|
|
11229
10913
|
|
|
11230
10914
|
// src/hooks/auto-update-checker/constants.ts
|
|
11231
|
-
import { homedir as
|
|
11232
|
-
import { join
|
|
10915
|
+
import { homedir as homedir2, platform } from "node:os";
|
|
10916
|
+
import { join } from "node:path";
|
|
11233
10917
|
var PACKAGE_NAME = "@cortexkit/opencode-magic-context";
|
|
11234
10918
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
11235
10919
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
11236
10920
|
function getOpenCodeCacheRoot() {
|
|
11237
10921
|
if (platform() === "win32") {
|
|
11238
|
-
return
|
|
10922
|
+
return join(process.env.LOCALAPPDATA ?? homedir2(), "opencode");
|
|
11239
10923
|
}
|
|
11240
|
-
return
|
|
10924
|
+
return join(homedir2(), ".cache", "opencode");
|
|
11241
10925
|
}
|
|
11242
10926
|
function getOpenCodeConfigRoot() {
|
|
11243
10927
|
if (platform() === "win32") {
|
|
11244
|
-
return
|
|
10928
|
+
return join(process.env.APPDATA ?? join(homedir2(), "AppData", "Roaming"), "opencode");
|
|
11245
10929
|
}
|
|
11246
|
-
return
|
|
10930
|
+
return join(process.env.XDG_CONFIG_HOME ?? join(homedir2(), ".config"), "opencode");
|
|
11247
10931
|
}
|
|
11248
|
-
var CACHE_DIR =
|
|
11249
|
-
var USER_OPENCODE_CONFIG =
|
|
11250
|
-
var USER_OPENCODE_CONFIG_JSONC =
|
|
10932
|
+
var CACHE_DIR = join(getOpenCodeCacheRoot(), "packages");
|
|
10933
|
+
var USER_OPENCODE_CONFIG = join(getOpenCodeConfigRoot(), "opencode.json");
|
|
10934
|
+
var USER_OPENCODE_CONFIG_JSONC = join(getOpenCodeConfigRoot(), "opencode.jsonc");
|
|
11251
10935
|
|
|
11252
10936
|
// src/hooks/auto-update-checker/types.ts
|
|
11253
10937
|
var NpmPackageEnvelopeSchema = exports_external.object({
|
|
@@ -11308,17 +10992,17 @@ function extractChannel(version) {
|
|
|
11308
10992
|
}
|
|
11309
10993
|
function getSurfaceConfigPaths(directory, surface) {
|
|
11310
10994
|
const name = surface === "server" ? "opencode" : "tui";
|
|
11311
|
-
const globalDir =
|
|
10995
|
+
const globalDir = dirname2(USER_OPENCODE_CONFIG);
|
|
11312
10996
|
const dirs = [
|
|
11313
10997
|
globalDir,
|
|
11314
10998
|
directory,
|
|
11315
|
-
|
|
10999
|
+
join2(directory, ".opencode"),
|
|
11316
11000
|
process.env.OPENCODE_CONFIG_DIR
|
|
11317
11001
|
].filter((value) => Boolean(value));
|
|
11318
11002
|
const paths = [];
|
|
11319
11003
|
for (const dir of dirs) {
|
|
11320
11004
|
for (const extension of ["json", "jsonc"]) {
|
|
11321
|
-
const path2 =
|
|
11005
|
+
const path2 = join2(dir, `${name}.${extension}`);
|
|
11322
11006
|
if (!paths.includes(path2))
|
|
11323
11007
|
paths.push(path2);
|
|
11324
11008
|
}
|
|
@@ -11329,9 +11013,9 @@ function getWinningConfig(directory, surface) {
|
|
|
11329
11013
|
let winner = null;
|
|
11330
11014
|
for (const path2 of getSurfaceConfigPaths(directory, surface)) {
|
|
11331
11015
|
try {
|
|
11332
|
-
if (!
|
|
11016
|
+
if (!existsSync5(path2))
|
|
11333
11017
|
continue;
|
|
11334
|
-
const parsed = parseJsonConfig(
|
|
11018
|
+
const parsed = parseJsonConfig(readFileSync3(path2, "utf-8"));
|
|
11335
11019
|
const entries = getPluginEntries(parsed);
|
|
11336
11020
|
if (entries.some((entry) => entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))) {
|
|
11337
11021
|
if (winner) {
|
|
@@ -11354,24 +11038,24 @@ function resolvePathPluginSpec(spec, configPath) {
|
|
|
11354
11038
|
return spec.replace(/^file:\/\//, "");
|
|
11355
11039
|
}
|
|
11356
11040
|
}
|
|
11357
|
-
if (
|
|
11041
|
+
if (isAbsolute2(spec) || /^[A-Za-z]:[\\/]/.test(spec))
|
|
11358
11042
|
return spec;
|
|
11359
|
-
return resolve2(
|
|
11043
|
+
return resolve2(dirname2(configPath), spec);
|
|
11360
11044
|
}
|
|
11361
11045
|
function findPackageJsonUp(startPath) {
|
|
11362
11046
|
try {
|
|
11363
|
-
const stat =
|
|
11364
|
-
let dir = stat.isDirectory() ? startPath :
|
|
11047
|
+
const stat = statSync(startPath);
|
|
11048
|
+
let dir = stat.isDirectory() ? startPath : dirname2(startPath);
|
|
11365
11049
|
for (let i = 0;i < 10; i++) {
|
|
11366
|
-
const pkgPath =
|
|
11367
|
-
if (
|
|
11050
|
+
const pkgPath = join2(dir, "package.json");
|
|
11051
|
+
if (existsSync5(pkgPath)) {
|
|
11368
11052
|
try {
|
|
11369
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
11053
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
|
|
11370
11054
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
11371
11055
|
return pkgPath;
|
|
11372
11056
|
} catch {}
|
|
11373
11057
|
}
|
|
11374
|
-
const parent =
|
|
11058
|
+
const parent = dirname2(dir);
|
|
11375
11059
|
if (parent === dir)
|
|
11376
11060
|
break;
|
|
11377
11061
|
dir = parent;
|
|
@@ -11382,19 +11066,19 @@ function findPackageJsonUp(startPath) {
|
|
|
11382
11066
|
function getLocalDevPath(directory) {
|
|
11383
11067
|
for (const configPath of getConfigPaths(directory)) {
|
|
11384
11068
|
try {
|
|
11385
|
-
if (!
|
|
11069
|
+
if (!existsSync5(configPath))
|
|
11386
11070
|
continue;
|
|
11387
|
-
const rawConfig = parseJsonConfig(
|
|
11071
|
+
const rawConfig = parseJsonConfig(readFileSync3(configPath, "utf-8"));
|
|
11388
11072
|
const plugins = getPluginEntries(rawConfig);
|
|
11389
11073
|
for (const entry of plugins) {
|
|
11390
11074
|
if (entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))
|
|
11391
11075
|
continue;
|
|
11392
|
-
if (entry.startsWith("file://") || entry.startsWith(".") ||
|
|
11076
|
+
if (entry.startsWith("file://") || entry.startsWith(".") || isAbsolute2(entry)) {
|
|
11393
11077
|
const localPath = resolvePathPluginSpec(entry, configPath);
|
|
11394
11078
|
const pkgPath = findPackageJsonUp(localPath);
|
|
11395
11079
|
if (!pkgPath)
|
|
11396
11080
|
continue;
|
|
11397
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
11081
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
|
|
11398
11082
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
11399
11083
|
return localPath;
|
|
11400
11084
|
}
|
|
@@ -11411,7 +11095,7 @@ function getLocalDevVersion(directory) {
|
|
|
11411
11095
|
const pkgPath = findPackageJsonUp(localPath);
|
|
11412
11096
|
if (!pkgPath)
|
|
11413
11097
|
return null;
|
|
11414
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
11098
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(pkgPath, "utf-8")));
|
|
11415
11099
|
return pkg.success ? pkg.data.version ?? null : null;
|
|
11416
11100
|
} catch {
|
|
11417
11101
|
return null;
|
|
@@ -11419,7 +11103,7 @@ function getLocalDevVersion(directory) {
|
|
|
11419
11103
|
}
|
|
11420
11104
|
function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
11421
11105
|
try {
|
|
11422
|
-
return findPackageJsonUp(
|
|
11106
|
+
return findPackageJsonUp(dirname2(fileURLToPath(currentModuleUrl)));
|
|
11423
11107
|
} catch (err) {
|
|
11424
11108
|
warn(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
|
|
11425
11109
|
return null;
|
|
@@ -11460,7 +11144,7 @@ function preflightConfigUpdates(paths, version) {
|
|
|
11460
11144
|
for (const path2 of paths) {
|
|
11461
11145
|
try {
|
|
11462
11146
|
accessSync(path2, fsConstants.W_OK);
|
|
11463
|
-
const original =
|
|
11147
|
+
const original = readFileSync3(path2, "utf-8");
|
|
11464
11148
|
const updated = configUpdateContent(original, version);
|
|
11465
11149
|
if (!updated)
|
|
11466
11150
|
return null;
|
|
@@ -11474,8 +11158,8 @@ function preflightConfigUpdates(paths, version) {
|
|
|
11474
11158
|
}
|
|
11475
11159
|
function writeConfig(path2, content) {
|
|
11476
11160
|
const tmp = `${path2}.mc-tmp-${process.pid}`;
|
|
11477
|
-
|
|
11478
|
-
|
|
11161
|
+
writeFileSync(tmp, content, "utf-8");
|
|
11162
|
+
renameSync(tmp, path2);
|
|
11479
11163
|
}
|
|
11480
11164
|
function restoreConfigs(snapshots) {
|
|
11481
11165
|
for (const snapshot of snapshots) {
|
|
@@ -11489,7 +11173,7 @@ function restoreConfigs(snapshots) {
|
|
|
11489
11173
|
function configsHaveSpec(paths, spec) {
|
|
11490
11174
|
return paths.every((path2) => {
|
|
11491
11175
|
try {
|
|
11492
|
-
const parsed = parseJsonConfig(
|
|
11176
|
+
const parsed = parseJsonConfig(readFileSync3(path2, "utf-8"));
|
|
11493
11177
|
return getPluginEntries(parsed).includes(spec);
|
|
11494
11178
|
} catch {
|
|
11495
11179
|
return false;
|
|
@@ -11545,8 +11229,8 @@ async function preparePluginUpdate(directory, _pluginInfo, version, options = {}
|
|
|
11545
11229
|
return null;
|
|
11546
11230
|
const spec = `${PACKAGE_NAME}@${version}`;
|
|
11547
11231
|
const globalServerPaths = [USER_OPENCODE_CONFIG, USER_OPENCODE_CONFIG_JSONC];
|
|
11548
|
-
const globalTuiPaths = globalServerPaths.map((path2) =>
|
|
11549
|
-
globalTuiPaths.push(...globalServerPaths.map((path2) =>
|
|
11232
|
+
const globalTuiPaths = globalServerPaths.map((path2) => join2(dirname2(path2), "tui.json"));
|
|
11233
|
+
globalTuiPaths.push(...globalServerPaths.map((path2) => join2(dirname2(path2), "tui.jsonc")));
|
|
11550
11234
|
const isGlobal = globalServerPaths.includes(paths[0]) && globalTuiPaths.includes(paths[1]);
|
|
11551
11235
|
if (isGlobal) {
|
|
11552
11236
|
const hostResult = await runHostPluginInstall(spec, options.signal, options.timeoutMs);
|
|
@@ -11579,9 +11263,9 @@ function getCachedVersion(_spec) {
|
|
|
11579
11263
|
const candidates = [getCurrentRuntimePackageJsonPath()].filter(isString);
|
|
11580
11264
|
for (const packageJsonPath of candidates) {
|
|
11581
11265
|
try {
|
|
11582
|
-
if (!
|
|
11266
|
+
if (!existsSync5(packageJsonPath))
|
|
11583
11267
|
continue;
|
|
11584
|
-
const pkg = PackageJsonSchema.safeParse(JSON.parse(
|
|
11268
|
+
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync3(packageJsonPath, "utf-8")));
|
|
11585
11269
|
if (pkg.success && pkg.data.version) {
|
|
11586
11270
|
if (!_spec)
|
|
11587
11271
|
cachedPackageVersion = pkg.data.version;
|
|
@@ -11679,20 +11363,20 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
11679
11363
|
if (!storageDir)
|
|
11680
11364
|
return true;
|
|
11681
11365
|
try {
|
|
11682
|
-
const file =
|
|
11683
|
-
if (
|
|
11366
|
+
const file = join3(storageDir, TIMESTAMP_FILENAME);
|
|
11367
|
+
if (existsSync6(file)) {
|
|
11684
11368
|
try {
|
|
11685
|
-
const raw = JSON.parse(
|
|
11369
|
+
const raw = JSON.parse(readFileSync4(file, "utf-8"));
|
|
11686
11370
|
const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
|
|
11687
11371
|
if (Number.isFinite(last) && Date.now() - last < intervalMs) {
|
|
11688
11372
|
return false;
|
|
11689
11373
|
}
|
|
11690
11374
|
} catch {}
|
|
11691
11375
|
}
|
|
11692
|
-
|
|
11376
|
+
mkdirSync(dirname3(file), { recursive: true });
|
|
11693
11377
|
const tmp = `${file}.tmp.${process.pid}`;
|
|
11694
|
-
|
|
11695
|
-
|
|
11378
|
+
writeFileSync2(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
|
|
11379
|
+
renameSync2(tmp, file);
|
|
11696
11380
|
return true;
|
|
11697
11381
|
} catch (err) {
|
|
11698
11382
|
warn2(`[auto-update-checker] Could not coordinate via timestamp file: ${String(err)}`);
|
|
@@ -11700,39 +11384,39 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
11700
11384
|
}
|
|
11701
11385
|
}
|
|
11702
11386
|
function pendingMarkerPath(storageDir) {
|
|
11703
|
-
return
|
|
11387
|
+
return join3(storageDir ?? getOpenCodeStorageDir(), PENDING_UPDATE_FILENAME);
|
|
11704
11388
|
}
|
|
11705
11389
|
function writePendingUpdateMarker(storageDir, update, version) {
|
|
11706
11390
|
try {
|
|
11707
|
-
const dir = storageDir ??
|
|
11708
|
-
|
|
11391
|
+
const dir = storageDir ?? dirname3(pendingMarkerPath(storageDir));
|
|
11392
|
+
mkdirSync(dir, { recursive: true });
|
|
11709
11393
|
const path2 = pendingMarkerPath(storageDir);
|
|
11710
11394
|
const temp = `${path2}.tmp.${process.pid}`;
|
|
11711
|
-
|
|
11395
|
+
writeFileSync2(temp, `${JSON.stringify({ spec: update.spec, version, configPaths: update.configPaths, writtenAt: Date.now() }, null, 2)}
|
|
11712
11396
|
`, "utf-8");
|
|
11713
|
-
|
|
11397
|
+
renameSync2(temp, path2);
|
|
11714
11398
|
} catch (err) {
|
|
11715
11399
|
warn2(`[auto-update-checker] Could not write pending update marker: ${String(err)}`);
|
|
11716
11400
|
}
|
|
11717
11401
|
}
|
|
11718
11402
|
function consumePendingUpdateMarker(storageDir, loadedVersion) {
|
|
11719
11403
|
const path2 = pendingMarkerPath(storageDir);
|
|
11720
|
-
if (!
|
|
11404
|
+
if (!existsSync6(path2))
|
|
11721
11405
|
return;
|
|
11722
11406
|
try {
|
|
11723
|
-
const marker = JSON.parse(
|
|
11407
|
+
const marker = JSON.parse(readFileSync4(path2, "utf-8"));
|
|
11724
11408
|
const age = Date.now() - (marker.writtenAt ?? 0);
|
|
11725
11409
|
const olderThanLoaded = typeof marker.version === "string" && typeof loadedVersion === "string" && (compareSemverCore(marker.version, loadedVersion) ?? 0) < 0;
|
|
11726
11410
|
if (marker.version === loadedVersion && marker.spec === `${PACKAGE_NAME}@${loadedVersion}` && Array.isArray(marker.configPaths) && marker.configPaths.length === 2) {
|
|
11727
|
-
|
|
11411
|
+
rmSync(path2, { force: true });
|
|
11728
11412
|
log(`[auto-update-checker] Pending update applied: ${marker.spec}`);
|
|
11729
11413
|
} else if (age > PENDING_UPDATE_MAX_AGE_MS || olderThanLoaded) {
|
|
11730
|
-
|
|
11414
|
+
rmSync(path2, { force: true });
|
|
11731
11415
|
warn2("[auto-update-checker] Discarded stale or mismatched pending update marker");
|
|
11732
11416
|
}
|
|
11733
11417
|
} catch (err) {
|
|
11734
11418
|
try {
|
|
11735
|
-
|
|
11419
|
+
rmSync(path2, { force: true });
|
|
11736
11420
|
} catch {}
|
|
11737
11421
|
warn2(`[auto-update-checker] Discarded corrupt pending update marker: ${String(err)}`);
|
|
11738
11422
|
}
|
|
@@ -11833,7 +11517,7 @@ function createLiveSessionState() {
|
|
|
11833
11517
|
|
|
11834
11518
|
// src/hooks/magic-context/module-transport.ts
|
|
11835
11519
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
11836
|
-
import { join as
|
|
11520
|
+
import { join as join4 } from "node:path";
|
|
11837
11521
|
var DEFAULT_MODULE_ID = "magic-context";
|
|
11838
11522
|
var CONNECT_BACKOFF_INITIAL_MS = 1000;
|
|
11839
11523
|
var CONNECT_BACKOFF_MAX_MS = 30000;
|
|
@@ -11843,7 +11527,7 @@ var SERIAL_LANE_MAX_WAITERS = 16;
|
|
|
11843
11527
|
var SERIAL_LANE_MIN_REMAINING_MS = 25;
|
|
11844
11528
|
var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
|
|
11845
11529
|
function getDefaultConnectionFile() {
|
|
11846
|
-
return
|
|
11530
|
+
return join4(getDataDir(), "cortexkit", "run", "subc-connection.json");
|
|
11847
11531
|
}
|
|
11848
11532
|
function errorChainSome(error, predicate) {
|
|
11849
11533
|
let current = error;
|
|
@@ -12111,6 +11795,14 @@ class SubcModuleTransport {
|
|
|
12111
11795
|
throw new Error("mirror.pull omitted page");
|
|
12112
11796
|
return { page: response.page };
|
|
12113
11797
|
}
|
|
11798
|
+
async deleteSession(sessionId, projectRoot) {
|
|
11799
|
+
await this.call({
|
|
11800
|
+
sessionId,
|
|
11801
|
+
projectRoot,
|
|
11802
|
+
method: "session.delete",
|
|
11803
|
+
body: { method: "session.delete", v: 1, session_id: sessionId }
|
|
11804
|
+
});
|
|
11805
|
+
}
|
|
12114
11806
|
closeSession(sessionId) {
|
|
12115
11807
|
const client = this.client;
|
|
12116
11808
|
const prefix = `${sessionId}\x00`;
|
|
@@ -12230,7 +11922,7 @@ class SubcModuleTransport {
|
|
|
12230
11922
|
}
|
|
12231
11923
|
|
|
12232
11924
|
// src/plugin/dream-timer.ts
|
|
12233
|
-
import { statSync as
|
|
11925
|
+
import { statSync as statSync3 } from "node:fs";
|
|
12234
11926
|
|
|
12235
11927
|
// src/features/magic-context/dreamer/storage-dream-state.ts
|
|
12236
11928
|
var getDreamStateStatements = new WeakMap;
|
|
@@ -12882,8 +12574,8 @@ function recordRetrospectiveWindowProcessed(db, projectPath, windowKey) {
|
|
|
12882
12574
|
}
|
|
12883
12575
|
|
|
12884
12576
|
// src/features/magic-context/dreamer/task-executor.ts
|
|
12885
|
-
import { createHash as
|
|
12886
|
-
import { existsSync as
|
|
12577
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
12578
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
12887
12579
|
|
|
12888
12580
|
// src/agents/dreamer.ts
|
|
12889
12581
|
var DREAMER_AGENT = "dreamer";
|
|
@@ -12894,6 +12586,9 @@ var DREAMER_CLASSIFIER_AGENT = "dreamer-classifier";
|
|
|
12894
12586
|
var DREAMER_DOCS_AGENT = "dreamer-docs";
|
|
12895
12587
|
var DREAMER_REVIEWER_AGENT = "dreamer-reviewer";
|
|
12896
12588
|
|
|
12589
|
+
// src/features/magic-context/mural/compress-cues.ts
|
|
12590
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
12591
|
+
|
|
12897
12592
|
// src/features/magic-context/dreamer/manifest-parser.ts
|
|
12898
12593
|
function extractCompleteManifestBody(text, rootName) {
|
|
12899
12594
|
const escapedRoot = rootName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -12927,6 +12622,64 @@ function assertManifestCoversExactly(ids, expectedIds, rootName) {
|
|
|
12927
12622
|
}
|
|
12928
12623
|
}
|
|
12929
12624
|
|
|
12625
|
+
// src/features/magic-context/dreamer/module-apply.ts
|
|
12626
|
+
class DreamerModuleFailureError extends Error {
|
|
12627
|
+
transient = true;
|
|
12628
|
+
constructor(operation, cause) {
|
|
12629
|
+
super(`Rust dreamer ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
12630
|
+
this.name = "DreamerModuleFailureError";
|
|
12631
|
+
this.cause = cause;
|
|
12632
|
+
}
|
|
12633
|
+
}
|
|
12634
|
+
async function resolveDreamerModuleRoute(args) {
|
|
12635
|
+
const transport = args.transformMode === "ts" ? undefined : args.moduleClient;
|
|
12636
|
+
if (!transport?.authorityStatus)
|
|
12637
|
+
return;
|
|
12638
|
+
const contextStoreUuid = getContextStoreUuid(args.db);
|
|
12639
|
+
if (!contextStoreUuid)
|
|
12640
|
+
throw new Error("Rust dreamer requires a context store identity");
|
|
12641
|
+
const result = await transport.authorityStatus({
|
|
12642
|
+
context_store_uuid: contextStoreUuid,
|
|
12643
|
+
project: args.projectIdentity,
|
|
12644
|
+
projectRoot: args.projectRoot,
|
|
12645
|
+
domain: "memories"
|
|
12646
|
+
});
|
|
12647
|
+
if (result.authority?.state !== "MODULE")
|
|
12648
|
+
return;
|
|
12649
|
+
const generation = result.authority.generation;
|
|
12650
|
+
if (typeof generation !== "number")
|
|
12651
|
+
throw new Error("Rust authority status omitted generation");
|
|
12652
|
+
return {
|
|
12653
|
+
moduleClient: transport,
|
|
12654
|
+
moduleSessionId: args.projectIdentity,
|
|
12655
|
+
moduleProjectRoot: args.projectRoot,
|
|
12656
|
+
moduleContextStoreUuid: contextStoreUuid,
|
|
12657
|
+
moduleAuthorityGeneration: generation,
|
|
12658
|
+
moduleCommandId: args.commandId
|
|
12659
|
+
};
|
|
12660
|
+
}
|
|
12661
|
+
function getModuleMemoryIdentities(db, projectIdentity, contextIds) {
|
|
12662
|
+
if (contextIds.length === 0)
|
|
12663
|
+
return new Map;
|
|
12664
|
+
const placeholders = contextIds.map(() => "?").join(", ");
|
|
12665
|
+
const rows = db.prepare(`SELECT identity.context_row_id, identity.module_row_id, live.normalized_hash
|
|
12666
|
+
FROM mirror_identity identity
|
|
12667
|
+
LEFT JOIN mirror_live_memory_rows live
|
|
12668
|
+
ON live.module_project = identity.module_project
|
|
12669
|
+
AND live.module_row_id = identity.module_row_id
|
|
12670
|
+
WHERE identity.domain = 'memories' AND identity.module_project = ?
|
|
12671
|
+
AND identity.context_row_id IN (${placeholders})`).all(projectIdentity, ...contextIds);
|
|
12672
|
+
return new Map(rows.flatMap((row) => Number.isInteger(row.context_row_id) && Number.isInteger(row.module_row_id) && typeof row.normalized_hash === "string" ? [
|
|
12673
|
+
[
|
|
12674
|
+
row.context_row_id,
|
|
12675
|
+
{
|
|
12676
|
+
moduleId: row.module_row_id,
|
|
12677
|
+
normalizedHash: row.normalized_hash
|
|
12678
|
+
}
|
|
12679
|
+
]
|
|
12680
|
+
] : []));
|
|
12681
|
+
}
|
|
12682
|
+
|
|
12930
12683
|
// src/features/magic-context/mural/compress-cues-prompt.ts
|
|
12931
12684
|
var CUE_BUDGET_HIGH = 90;
|
|
12932
12685
|
var CUE_BUDGET_LOW = 50;
|
|
@@ -13198,7 +12951,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
13198
12951
|
return text;
|
|
13199
12952
|
}
|
|
13200
12953
|
});
|
|
13201
|
-
return applyCues(args, chunk, run.validated);
|
|
12954
|
+
return args.moduleRoute ? await applyCuesThroughModule(args, chunk, run.validated, signal) : applyCues(args, chunk, run.validated);
|
|
13202
12955
|
} catch (error) {
|
|
13203
12956
|
const desc = describeError(error);
|
|
13204
12957
|
log(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
@@ -13256,6 +13009,111 @@ function applyCues(args, chunk, manifestText) {
|
|
|
13256
13009
|
});
|
|
13257
13010
|
return { compressed, skipped };
|
|
13258
13011
|
}
|
|
13012
|
+
async function applyCuesThroughModule(args, chunk, manifestText, signal) {
|
|
13013
|
+
const route = args.moduleRoute;
|
|
13014
|
+
if (!route)
|
|
13015
|
+
throw new Error("module cue apply called without a module route");
|
|
13016
|
+
const byId = new Map(chunk.map((candidate) => [candidate.memory.id, candidate]));
|
|
13017
|
+
const parsed = parseCuesManifest(manifestText);
|
|
13018
|
+
assertManifestCoversExactly(parsed.map((entry) => entry.id), new Set(byId.keys()), "cues");
|
|
13019
|
+
const state = getMuralCueState(args.db, chunk.map((candidate) => candidate.memory.id));
|
|
13020
|
+
const identities = getModuleMemoryIdentities(args.db, args.projectIdentity, chunk.map((candidate) => candidate.memory.id));
|
|
13021
|
+
const updates = [];
|
|
13022
|
+
for (const entry of parsed) {
|
|
13023
|
+
const candidate = byId.get(entry.id);
|
|
13024
|
+
if (!candidate)
|
|
13025
|
+
throw new Error(`cues manifest contains unknown id ${entry.id}`);
|
|
13026
|
+
const identity = identities.get(candidate.memory.id);
|
|
13027
|
+
if (!identity) {
|
|
13028
|
+
throw new Error(`module mirror identity missing for memory ${candidate.memory.id}`);
|
|
13029
|
+
}
|
|
13030
|
+
const failure = validateCue(entry.cue, candidate.memory.importance ?? 50, candidate.memory.id);
|
|
13031
|
+
if (!failure) {
|
|
13032
|
+
updates.push({
|
|
13033
|
+
contextId: candidate.memory.id,
|
|
13034
|
+
moduleId: identity.moduleId,
|
|
13035
|
+
contentHash: candidate.contentHash,
|
|
13036
|
+
cue: entry.cue.trim(),
|
|
13037
|
+
rejectionCount: 0,
|
|
13038
|
+
kind: "compressed"
|
|
13039
|
+
});
|
|
13040
|
+
continue;
|
|
13041
|
+
}
|
|
13042
|
+
const previous = state.get(candidate.memory.id);
|
|
13043
|
+
const rejectionCount = previous?.hash === candidate.contentHash ? (previous.rejectionCount ?? 0) + 1 : 1;
|
|
13044
|
+
if (rejectionCount >= CUE_REJECTION_LATCH_THRESHOLD) {
|
|
13045
|
+
updates.push({
|
|
13046
|
+
contextId: candidate.memory.id,
|
|
13047
|
+
moduleId: identity.moduleId,
|
|
13048
|
+
contentHash: candidate.contentHash,
|
|
13049
|
+
cue: deterministicFallbackCue(candidate, entry.cue),
|
|
13050
|
+
rejectionCount: 0,
|
|
13051
|
+
kind: "compressed"
|
|
13052
|
+
});
|
|
13053
|
+
log(`[dreamer] compress-cues: fallback cue for memory ${entry.id} (${failure.reason}; ${rejectionCount} rejections; fallback)`);
|
|
13054
|
+
} else {
|
|
13055
|
+
updates.push({
|
|
13056
|
+
contextId: candidate.memory.id,
|
|
13057
|
+
moduleId: identity.moduleId,
|
|
13058
|
+
contentHash: candidate.contentHash,
|
|
13059
|
+
cue: null,
|
|
13060
|
+
rejectionCount,
|
|
13061
|
+
kind: "skipped"
|
|
13062
|
+
});
|
|
13063
|
+
log(`[dreamer] compress-cues: skipped cue for memory ${entry.id} (${failure.reason}; rejection ${rejectionCount}/${CUE_REJECTION_LATCH_THRESHOLD})`);
|
|
13064
|
+
}
|
|
13065
|
+
}
|
|
13066
|
+
const commandId = `mural-cues:${route.moduleCommandId}:${createHash2("sha256").update(chunk.map((candidate) => candidate.memory.id).join(",")).digest("hex").slice(0, 24)}`;
|
|
13067
|
+
let response;
|
|
13068
|
+
try {
|
|
13069
|
+
response = await route.moduleClient.call({
|
|
13070
|
+
sessionId: route.moduleSessionId,
|
|
13071
|
+
projectRoot: route.moduleProjectRoot,
|
|
13072
|
+
method: "memory.set_mural_cue",
|
|
13073
|
+
body: {
|
|
13074
|
+
name: "memory.set_mural_cue",
|
|
13075
|
+
arguments: {
|
|
13076
|
+
memory_project: args.projectIdentity,
|
|
13077
|
+
context_store_uuid: route.moduleContextStoreUuid,
|
|
13078
|
+
authority_generation: route.moduleAuthorityGeneration,
|
|
13079
|
+
command_id: commandId,
|
|
13080
|
+
rows: updates.map((update) => ({
|
|
13081
|
+
memory_id: update.moduleId,
|
|
13082
|
+
content_hash_at_prompt: update.contentHash,
|
|
13083
|
+
cue: update.cue,
|
|
13084
|
+
rejection_count: update.rejectionCount
|
|
13085
|
+
}))
|
|
13086
|
+
}
|
|
13087
|
+
},
|
|
13088
|
+
signal
|
|
13089
|
+
});
|
|
13090
|
+
} catch (error) {
|
|
13091
|
+
throw new DreamerModuleFailureError("mural cue apply", error);
|
|
13092
|
+
}
|
|
13093
|
+
const result = response?.result ?? response;
|
|
13094
|
+
if (!result || typeof result !== "object") {
|
|
13095
|
+
throw new Error("module returned invalid mural cue apply result");
|
|
13096
|
+
}
|
|
13097
|
+
const accepted = result.accepted;
|
|
13098
|
+
if (!Array.isArray(accepted) || !accepted.every((id) => Number.isInteger(id))) {
|
|
13099
|
+
throw new Error("module returned no mural cue acceptance list");
|
|
13100
|
+
}
|
|
13101
|
+
const acceptedIds = new Set(accepted);
|
|
13102
|
+
const rejected = result.rejected;
|
|
13103
|
+
const rejectedReasons = new Map;
|
|
13104
|
+
for (const row of Array.isArray(rejected) ? rejected : []) {
|
|
13105
|
+
const reason = row && typeof row === "object" && typeof row.reason === "string" ? row.reason : "unknown";
|
|
13106
|
+
rejectedReasons.set(reason, (rejectedReasons.get(reason) ?? 0) + 1);
|
|
13107
|
+
}
|
|
13108
|
+
if ([...rejectedReasons].some(([reason]) => reason !== "stale")) {
|
|
13109
|
+
throw new Error(`module rejected mural cues (${[...rejectedReasons].map(([reason, count]) => `${reason}=${count}`).join(", ")})`);
|
|
13110
|
+
}
|
|
13111
|
+
return updates.reduce((counts, update) => {
|
|
13112
|
+
if (acceptedIds.has(update.moduleId))
|
|
13113
|
+
counts[update.kind] += 1;
|
|
13114
|
+
return counts;
|
|
13115
|
+
}, { compressed: 0, skipped: 0 });
|
|
13116
|
+
}
|
|
13259
13117
|
|
|
13260
13118
|
// src/features/magic-context/user-memory/review-user-memories.ts
|
|
13261
13119
|
async function reviewUserMemories(args) {
|
|
@@ -13465,7 +13323,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
13465
13323
|
}
|
|
13466
13324
|
|
|
13467
13325
|
// src/features/magic-context/dreamer/classify.ts
|
|
13468
|
-
import { createHash as
|
|
13326
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
13469
13327
|
|
|
13470
13328
|
// src/plugin/rust-tool-backends.ts
|
|
13471
13329
|
function toolCallIdFromContext(context) {
|
|
@@ -13500,7 +13358,7 @@ function isRustAuthorityDrainingError(error) {
|
|
|
13500
13358
|
}
|
|
13501
13359
|
|
|
13502
13360
|
// src/shared/redaction.ts
|
|
13503
|
-
import { homedir as
|
|
13361
|
+
import { homedir as homedir3, userInfo } from "node:os";
|
|
13504
13362
|
function escapeRegex(value) {
|
|
13505
13363
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
13506
13364
|
}
|
|
@@ -13549,7 +13407,7 @@ var SECRET_QUALIFIERS = new Set([
|
|
|
13549
13407
|
"azure"
|
|
13550
13408
|
]);
|
|
13551
13409
|
function sanitizePathString(value) {
|
|
13552
|
-
const home =
|
|
13410
|
+
const home = homedir3();
|
|
13553
13411
|
const username = userInfo().username;
|
|
13554
13412
|
let sanitized = value;
|
|
13555
13413
|
if (home) {
|
|
@@ -13751,64 +13609,6 @@ function parseClassifyManifest(text) {
|
|
|
13751
13609
|
return out;
|
|
13752
13610
|
}
|
|
13753
13611
|
|
|
13754
|
-
// src/features/magic-context/dreamer/module-apply.ts
|
|
13755
|
-
class DreamerModuleFailureError extends Error {
|
|
13756
|
-
transient = true;
|
|
13757
|
-
constructor(operation, cause) {
|
|
13758
|
-
super(`Rust dreamer ${operation} failed: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
13759
|
-
this.name = "DreamerModuleFailureError";
|
|
13760
|
-
this.cause = cause;
|
|
13761
|
-
}
|
|
13762
|
-
}
|
|
13763
|
-
async function resolveDreamerModuleRoute(args) {
|
|
13764
|
-
const transport = args.transformMode === "ts" ? undefined : args.moduleClient;
|
|
13765
|
-
if (!transport?.authorityStatus)
|
|
13766
|
-
return;
|
|
13767
|
-
const contextStoreUuid = getContextStoreUuid(args.db);
|
|
13768
|
-
if (!contextStoreUuid)
|
|
13769
|
-
throw new Error("Rust dreamer requires a context store identity");
|
|
13770
|
-
const result = await transport.authorityStatus({
|
|
13771
|
-
context_store_uuid: contextStoreUuid,
|
|
13772
|
-
project: args.projectIdentity,
|
|
13773
|
-
projectRoot: args.projectRoot,
|
|
13774
|
-
domain: "memories"
|
|
13775
|
-
});
|
|
13776
|
-
if (result.authority?.state !== "MODULE")
|
|
13777
|
-
return;
|
|
13778
|
-
const generation = result.authority.generation;
|
|
13779
|
-
if (typeof generation !== "number")
|
|
13780
|
-
throw new Error("Rust authority status omitted generation");
|
|
13781
|
-
return {
|
|
13782
|
-
moduleClient: transport,
|
|
13783
|
-
moduleSessionId: args.projectIdentity,
|
|
13784
|
-
moduleProjectRoot: args.projectRoot,
|
|
13785
|
-
moduleContextStoreUuid: contextStoreUuid,
|
|
13786
|
-
moduleAuthorityGeneration: generation,
|
|
13787
|
-
moduleCommandId: args.commandId
|
|
13788
|
-
};
|
|
13789
|
-
}
|
|
13790
|
-
function getModuleMemoryIdentities(db, projectIdentity, contextIds) {
|
|
13791
|
-
if (contextIds.length === 0)
|
|
13792
|
-
return new Map;
|
|
13793
|
-
const placeholders = contextIds.map(() => "?").join(", ");
|
|
13794
|
-
const rows = db.prepare(`SELECT identity.context_row_id, identity.module_row_id, live.normalized_hash
|
|
13795
|
-
FROM mirror_identity identity
|
|
13796
|
-
LEFT JOIN mirror_live_memory_rows live
|
|
13797
|
-
ON live.module_project = identity.module_project
|
|
13798
|
-
AND live.module_row_id = identity.module_row_id
|
|
13799
|
-
WHERE identity.domain = 'memories' AND identity.module_project = ?
|
|
13800
|
-
AND identity.context_row_id IN (${placeholders})`).all(projectIdentity, ...contextIds);
|
|
13801
|
-
return new Map(rows.flatMap((row) => Number.isInteger(row.context_row_id) && Number.isInteger(row.module_row_id) && typeof row.normalized_hash === "string" ? [
|
|
13802
|
-
[
|
|
13803
|
-
row.context_row_id,
|
|
13804
|
-
{
|
|
13805
|
-
moduleId: row.module_row_id,
|
|
13806
|
-
normalizedHash: row.normalized_hash
|
|
13807
|
-
}
|
|
13808
|
-
]
|
|
13809
|
-
] : []));
|
|
13810
|
-
}
|
|
13811
|
-
|
|
13812
13612
|
// src/features/magic-context/dreamer/classify.ts
|
|
13813
13613
|
var MIN_POOL_TO_CLASSIFY = 10;
|
|
13814
13614
|
var FULL_POOL_CEILING = 100;
|
|
@@ -14045,7 +13845,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal) {
|
|
|
14045
13845
|
v: 1,
|
|
14046
13846
|
session_id: args.moduleSessionId,
|
|
14047
13847
|
task: "classify",
|
|
14048
|
-
command_id: `classify:${args.moduleCommandId ?? Date.now()}:${
|
|
13848
|
+
command_id: `classify:${args.moduleCommandId ?? Date.now()}:${createHash3("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`,
|
|
14049
13849
|
authority_generation: args.moduleAuthorityGeneration,
|
|
14050
13850
|
payload: {
|
|
14051
13851
|
prompt_body: prompt,
|
|
@@ -14577,21 +14377,21 @@ function isSecretDeniedPath(repoRelativePath) {
|
|
|
14577
14377
|
const segments = normalized.split("/");
|
|
14578
14378
|
if (segments.includes(".git") || segments.includes("secrets"))
|
|
14579
14379
|
return true;
|
|
14580
|
-
const
|
|
14581
|
-
if (
|
|
14380
|
+
const basename = segments.at(-1) ?? "";
|
|
14381
|
+
if (basename === ".npmrc" || basename.startsWith(".env"))
|
|
14582
14382
|
return true;
|
|
14583
|
-
if (
|
|
14383
|
+
if (basename === ".pgpass" || basename === ".netrc")
|
|
14584
14384
|
return true;
|
|
14585
|
-
if (SECRET_KEY_EXTENSIONS.some((extension) =>
|
|
14385
|
+
if (SECRET_KEY_EXTENSIONS.some((extension) => basename.endsWith(extension)))
|
|
14586
14386
|
return true;
|
|
14587
|
-
if (
|
|
14387
|
+
if (basename === "id_rsa" || basename === "id_dsa" || basename === "id_ecdsa" || basename === "id_ed25519" || basename.startsWith("id_")) {
|
|
14588
14388
|
return true;
|
|
14589
14389
|
}
|
|
14590
|
-
if (segments.includes(".aws") &&
|
|
14390
|
+
if (segments.includes(".aws") && basename === "credentials")
|
|
14591
14391
|
return true;
|
|
14592
|
-
if (
|
|
14593
|
-
const serviceAccountJson =
|
|
14594
|
-
const gcloudCredentialJson = segments.includes("gcloud") && (
|
|
14392
|
+
if (basename.endsWith(".json")) {
|
|
14393
|
+
const serviceAccountJson = basename.includes("service-account") || basename.includes("service_account");
|
|
14394
|
+
const gcloudCredentialJson = segments.includes("gcloud") && (basename === "application_default_credentials.json" || basename.includes("credential") || segments.includes("legacy_credentials"));
|
|
14595
14395
|
if (serviceAccountJson || gcloudCredentialJson)
|
|
14596
14396
|
return true;
|
|
14597
14397
|
}
|
|
@@ -14741,7 +14541,7 @@ function throwIfAborted2(signal) {
|
|
|
14741
14541
|
}
|
|
14742
14542
|
|
|
14743
14543
|
// src/features/magic-context/smart-notes/compiler.ts
|
|
14744
|
-
import { createHash as
|
|
14544
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
14745
14545
|
|
|
14746
14546
|
// src/features/magic-context/smart-notes/sandbox-runner.ts
|
|
14747
14547
|
var asyncModulePromise = null;
|
|
@@ -15135,7 +14935,7 @@ function manifestAdvisoryWarnings(code, manifest) {
|
|
|
15135
14935
|
return warnings;
|
|
15136
14936
|
}
|
|
15137
14937
|
function hashCheck(surfaceCondition, compiledCheck, manifest, checkCron) {
|
|
15138
|
-
return
|
|
14938
|
+
return createHash4("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
|
|
15139
14939
|
}
|
|
15140
14940
|
function extractJsonObject(output) {
|
|
15141
14941
|
const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
@@ -15833,8 +15633,8 @@ Output exactly JSON: {"met": false}`;
|
|
|
15833
15633
|
}
|
|
15834
15634
|
|
|
15835
15635
|
// src/features/magic-context/dreamer/maintain-docs-protected-enforcement.ts
|
|
15836
|
-
import { existsSync as
|
|
15837
|
-
import { join as
|
|
15636
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
15637
|
+
import { join as join5 } from "node:path";
|
|
15838
15638
|
|
|
15839
15639
|
// src/features/magic-context/dreamer/protected-regions.ts
|
|
15840
15640
|
var PROTECTED_START_TOKEN = "mc:protected START";
|
|
@@ -15935,10 +15735,10 @@ var MAINTAIN_DOCS_SNAPSHOT_FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
|
15935
15735
|
function snapshotMaintainDocsFiles(docsDir) {
|
|
15936
15736
|
const snapshot = new Map;
|
|
15937
15737
|
for (const name of MAINTAIN_DOCS_SNAPSHOT_FILES) {
|
|
15938
|
-
const path3 =
|
|
15738
|
+
const path3 = join5(docsDir, name);
|
|
15939
15739
|
try {
|
|
15940
|
-
if (
|
|
15941
|
-
snapshot.set(name,
|
|
15740
|
+
if (existsSync7(path3)) {
|
|
15741
|
+
snapshot.set(name, readFileSync5(path3, "utf8"));
|
|
15942
15742
|
}
|
|
15943
15743
|
} catch {}
|
|
15944
15744
|
}
|
|
@@ -15946,14 +15746,14 @@ function snapshotMaintainDocsFiles(docsDir) {
|
|
|
15946
15746
|
}
|
|
15947
15747
|
function enforceMaintainDocsProtectedRegions(args) {
|
|
15948
15748
|
for (const [fileName, original] of args.snapshot) {
|
|
15949
|
-
const path3 =
|
|
15749
|
+
const path3 = join5(args.docsDir, fileName);
|
|
15950
15750
|
try {
|
|
15951
|
-
const current =
|
|
15751
|
+
const current = readFileSync5(path3, "utf8");
|
|
15952
15752
|
const { text, violated } = enforceProtectedRegions(original, current);
|
|
15953
15753
|
if (!violated) {
|
|
15954
15754
|
continue;
|
|
15955
15755
|
}
|
|
15956
|
-
|
|
15756
|
+
writeFileSync3(path3, text, "utf8");
|
|
15957
15757
|
log(`[dreamer] maintain-docs altered a protected region in ${fileName} — restored from pre-task snapshot`);
|
|
15958
15758
|
} catch (error) {
|
|
15959
15759
|
log(`[dreamer] maintain-docs protected-region enforcement failed for ${fileName}: ${error}`);
|
|
@@ -15962,10 +15762,10 @@ function enforceMaintainDocsProtectedRegions(args) {
|
|
|
15962
15762
|
}
|
|
15963
15763
|
|
|
15964
15764
|
// src/features/magic-context/dreamer/map-memories.ts
|
|
15965
|
-
import { createHash as
|
|
15765
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
15966
15766
|
|
|
15967
15767
|
// src/features/magic-context/dreamer/map-memories-prompt.ts
|
|
15968
|
-
import { existsSync as
|
|
15768
|
+
import { existsSync as existsSync8, statSync as statSync2 } from "node:fs";
|
|
15969
15769
|
import path3 from "node:path";
|
|
15970
15770
|
var MAP_MEMORIES_SYSTEM_PROMPT = `You are a memory mapper for the magic-context system. You map project memories to the repository files that back them.
|
|
15971
15771
|
|
|
@@ -16003,7 +15803,7 @@ function extractMemoryCandidatePaths(content, repoDir) {
|
|
|
16003
15803
|
if (!abs.startsWith(`${root}/`))
|
|
16004
15804
|
continue;
|
|
16005
15805
|
try {
|
|
16006
|
-
if (
|
|
15806
|
+
if (existsSync8(abs) && statSync2(abs).isFile())
|
|
16007
15807
|
found.add(rel);
|
|
16008
15808
|
} catch {}
|
|
16009
15809
|
if (found.size >= MAX_SEED_PATHS_PER_MEMORY)
|
|
@@ -16223,7 +16023,7 @@ async function applyBatchMappings(args, batch, manifestText) {
|
|
|
16223
16023
|
memory_project: args.projectIdentity,
|
|
16224
16024
|
context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
|
|
16225
16025
|
authority_generation: args.moduleRoute.moduleAuthorityGeneration,
|
|
16226
|
-
command_id: `${args.moduleRoute.moduleCommandId}:${
|
|
16026
|
+
command_id: `${args.moduleRoute.moduleCommandId}:${createHash5("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
|
|
16227
16027
|
rows
|
|
16228
16028
|
}
|
|
16229
16029
|
}
|
|
@@ -17165,7 +16965,69 @@ function evaluateTaskGate(task, ctx) {
|
|
|
17165
16965
|
}
|
|
17166
16966
|
|
|
17167
16967
|
// src/features/magic-context/dreamer/verify.ts
|
|
17168
|
-
import { createHash as
|
|
16968
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
16969
|
+
|
|
16970
|
+
// src/features/magic-context/dreamer/provider-output-failure.ts
|
|
16971
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
16972
|
+
var MAX_NEAR_ZERO_OUTPUT_TOKENS = 32;
|
|
16973
|
+
|
|
16974
|
+
class DreamerProviderOutputFailureError extends Error {
|
|
16975
|
+
fingerprint;
|
|
16976
|
+
outputTokens;
|
|
16977
|
+
reasoningTokens;
|
|
16978
|
+
transient = true;
|
|
16979
|
+
constructor(fingerprint, outputTokens, reasoningTokens, responseText) {
|
|
16980
|
+
const preview = responseText.trim().replace(/\s+/g, " ").slice(0, 160);
|
|
16981
|
+
super(`verify provider-outage completion (output_tokens=${outputTokens}, reasoning_tokens=${reasoningTokens}): ${JSON.stringify(preview)}`);
|
|
16982
|
+
this.fingerprint = fingerprint;
|
|
16983
|
+
this.outputTokens = outputTokens;
|
|
16984
|
+
this.reasoningTokens = reasoningTokens;
|
|
16985
|
+
this.name = "DreamerProviderOutputFailureError";
|
|
16986
|
+
}
|
|
16987
|
+
}
|
|
16988
|
+
function finiteTokenCount(value) {
|
|
16989
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
16990
|
+
}
|
|
16991
|
+
function completionShape(value) {
|
|
16992
|
+
if (!isRecord(value))
|
|
16993
|
+
return null;
|
|
16994
|
+
const info = isRecord(value.info) ? value.info : value;
|
|
16995
|
+
if (info.role !== "assistant")
|
|
16996
|
+
return null;
|
|
16997
|
+
const time = isRecord(info.time) ? info.time : null;
|
|
16998
|
+
const tokens = isRecord(info.tokens) ? info.tokens : null;
|
|
16999
|
+
return {
|
|
17000
|
+
createdAt: typeof time?.created === "number" ? time.created : 0,
|
|
17001
|
+
finish: typeof info.finish === "string" ? info.finish : typeof info.finish_reason === "string" ? info.finish_reason : typeof info.finishReason === "string" ? info.finishReason : null,
|
|
17002
|
+
error: info.error,
|
|
17003
|
+
outputTokens: finiteTokenCount(tokens?.output),
|
|
17004
|
+
reasoningTokens: finiteTokenCount(tokens?.reasoning)
|
|
17005
|
+
};
|
|
17006
|
+
}
|
|
17007
|
+
function latestAssistantCompletion(messages) {
|
|
17008
|
+
if (!Array.isArray(messages))
|
|
17009
|
+
return null;
|
|
17010
|
+
let latest = null;
|
|
17011
|
+
for (const message of messages) {
|
|
17012
|
+
const completion = completionShape(message);
|
|
17013
|
+
if (completion && (!latest || completion.createdAt >= latest.createdAt))
|
|
17014
|
+
latest = completion;
|
|
17015
|
+
}
|
|
17016
|
+
return latest;
|
|
17017
|
+
}
|
|
17018
|
+
function providerOutputFailureFromInvalidManifest(messages, responseText) {
|
|
17019
|
+
const completion = latestAssistantCompletion(messages);
|
|
17020
|
+
if (completion?.finish?.toLowerCase() !== "stop")
|
|
17021
|
+
return null;
|
|
17022
|
+
if (completion.error != null || completion.outputTokens === null || completion.outputTokens > MAX_NEAR_ZERO_OUTPUT_TOKENS || completion.reasoningTokens !== 0) {
|
|
17023
|
+
return null;
|
|
17024
|
+
}
|
|
17025
|
+
const normalized = responseText.trim().replace(/\s+/g, " ").toLowerCase();
|
|
17026
|
+
if (!normalized)
|
|
17027
|
+
return null;
|
|
17028
|
+
const fingerprint = createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
17029
|
+
return new DreamerProviderOutputFailureError(fingerprint, completion.outputTokens, completion.reasoningTokens, responseText);
|
|
17030
|
+
}
|
|
17169
17031
|
|
|
17170
17032
|
// src/features/magic-context/dreamer/verify-gate.ts
|
|
17171
17033
|
import path4 from "node:path";
|
|
@@ -17358,6 +17220,7 @@ function parseVerifyManifest(text) {
|
|
|
17358
17220
|
|
|
17359
17221
|
// src/features/magic-context/dreamer/verify.ts
|
|
17360
17222
|
var VERIFY_BATCH_SIZE = 50;
|
|
17223
|
+
var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
|
|
17361
17224
|
function closeBroadCycle(args, cycleStartAt) {
|
|
17362
17225
|
if (!args.forceBroad || cycleStartAt === undefined)
|
|
17363
17226
|
return;
|
|
@@ -17411,6 +17274,9 @@ async function runVerify(args) {
|
|
|
17411
17274
|
}
|
|
17412
17275
|
const abortController = new AbortController;
|
|
17413
17276
|
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, () => abortController.abort());
|
|
17277
|
+
let consecutiveProviderFailures = 0;
|
|
17278
|
+
let priorProviderFailureFingerprint = null;
|
|
17279
|
+
let lastProviderFailure = null;
|
|
17414
17280
|
try {
|
|
17415
17281
|
for (let i = 0;i < batches.length; i += 1) {
|
|
17416
17282
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
@@ -17425,7 +17291,25 @@ async function runVerify(args) {
|
|
|
17425
17291
|
result.remaining -= counts.verified + counts.updated + counts.archived;
|
|
17426
17292
|
result.batches += 1;
|
|
17427
17293
|
args.onProgress?.(result.verified + result.updated + result.archived);
|
|
17294
|
+
if (counts.providerFailure) {
|
|
17295
|
+
lastProviderFailure = counts.providerFailure;
|
|
17296
|
+
if (counts.providerFailure.fingerprint === priorProviderFailureFingerprint) {
|
|
17297
|
+
consecutiveProviderFailures += 1;
|
|
17298
|
+
} else {
|
|
17299
|
+
priorProviderFailureFingerprint = counts.providerFailure.fingerprint;
|
|
17300
|
+
consecutiveProviderFailures = 1;
|
|
17301
|
+
}
|
|
17302
|
+
if (consecutiveProviderFailures >= IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT) {
|
|
17303
|
+
log(`[dreamer] verify run aborting after ${consecutiveProviderFailures} identical provider-failure batches`);
|
|
17304
|
+
throw counts.providerFailure;
|
|
17305
|
+
}
|
|
17306
|
+
} else {
|
|
17307
|
+
priorProviderFailureFingerprint = null;
|
|
17308
|
+
consecutiveProviderFailures = 0;
|
|
17309
|
+
}
|
|
17428
17310
|
}
|
|
17311
|
+
if (lastProviderFailure)
|
|
17312
|
+
throw lastProviderFailure;
|
|
17429
17313
|
result.complete = result.remaining === 0;
|
|
17430
17314
|
if (result.complete)
|
|
17431
17315
|
closeBroadCycle(args, gate.broadCycleStartAt);
|
|
@@ -17483,7 +17367,14 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
17483
17367
|
const text = extractLatestAssistantText(messages);
|
|
17484
17368
|
if (!text)
|
|
17485
17369
|
throw new Error("verify returned no output");
|
|
17486
|
-
|
|
17370
|
+
try {
|
|
17371
|
+
parseVerifyManifest(text);
|
|
17372
|
+
} catch (error) {
|
|
17373
|
+
const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
|
|
17374
|
+
if (providerFailure)
|
|
17375
|
+
throw providerFailure;
|
|
17376
|
+
throw error;
|
|
17377
|
+
}
|
|
17487
17378
|
return text;
|
|
17488
17379
|
}
|
|
17489
17380
|
});
|
|
@@ -17491,11 +17382,12 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
17491
17382
|
return await applyVerifyManifest(args, batch, run.validated);
|
|
17492
17383
|
} catch (error) {
|
|
17493
17384
|
const desc = describeError(error);
|
|
17494
|
-
|
|
17385
|
+
const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
|
|
17386
|
+
log(`[dreamer] verify batch ${providerFailure ? "provider failure" : "failed"}: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
17495
17387
|
recordInvocation4(args, startedAt, { status: "failed", error });
|
|
17496
17388
|
if (error instanceof DreamerModuleFailureError || signal.aborted)
|
|
17497
17389
|
throw error;
|
|
17498
|
-
return { verified: 0, updated: 0, archived: 0 };
|
|
17390
|
+
return { verified: 0, updated: 0, archived: 0, providerFailure };
|
|
17499
17391
|
} finally {
|
|
17500
17392
|
if (agentSessionId && !shouldKeepSubagents()) {
|
|
17501
17393
|
await args.client.session.delete({
|
|
@@ -17567,7 +17459,7 @@ async function applyVerifyManifest(args, batch, manifestText) {
|
|
|
17567
17459
|
memory_project: args.projectIdentity,
|
|
17568
17460
|
context_store_uuid: args.moduleRoute.moduleContextStoreUuid,
|
|
17569
17461
|
authority_generation: args.moduleRoute.moduleAuthorityGeneration,
|
|
17570
|
-
command_id: `${args.moduleRoute.moduleCommandId}:${
|
|
17462
|
+
command_id: `${args.moduleRoute.moduleCommandId}:${createHash7("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
|
|
17571
17463
|
rows
|
|
17572
17464
|
}
|
|
17573
17465
|
}
|
|
@@ -17811,12 +17703,6 @@ function createDreamTaskExecutor(deps) {
|
|
|
17811
17703
|
recordRun("completed", null);
|
|
17812
17704
|
return { status: "completed" };
|
|
17813
17705
|
}
|
|
17814
|
-
if (moduleRoute) {
|
|
17815
|
-
const reason = "compress-cues parked: MODULE memory authority has no cue write facade";
|
|
17816
|
-
log(`[dreamer] compress-cues: skipped (${reason})`);
|
|
17817
|
-
recordRun("failed", reason);
|
|
17818
|
-
return { status: "failed", transient: true, error: reason };
|
|
17819
|
-
}
|
|
17820
17706
|
const result = await runCompressCues({
|
|
17821
17707
|
db,
|
|
17822
17708
|
client: deps.client,
|
|
@@ -17828,6 +17714,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
17828
17714
|
deadline,
|
|
17829
17715
|
model: config.model ?? deps.mural.model ?? deps.dreamerModel,
|
|
17830
17716
|
fallbackModels: config.fallbackModels,
|
|
17717
|
+
moduleRoute,
|
|
17831
17718
|
onProgress: (processed) => reportProgress(processed)
|
|
17832
17719
|
});
|
|
17833
17720
|
log(`[dreamer] compress-cues: compressed=${result.compressed} skipped=${result.skipped} chunks=${result.chunks} remaining=${result.remaining}`);
|
|
@@ -18109,7 +17996,7 @@ function parseFrictionGateVerdict(verdict) {
|
|
|
18109
17996
|
}
|
|
18110
17997
|
function computeRetrospectiveWindowKey(flagged) {
|
|
18111
17998
|
const anchors = flagged.map((message) => `${message.sessionId}:${message.ts}`).sort().join("|");
|
|
18112
|
-
return
|
|
17999
|
+
return createHash8("sha256").update(anchors).digest("hex").slice(0, 32);
|
|
18113
18000
|
}
|
|
18114
18001
|
function renderFrictionWindow(messages, flaggedOrdinals, radius = 2) {
|
|
18115
18002
|
const flagged = new Set(flaggedOrdinals);
|
|
@@ -18342,8 +18229,8 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
18342
18229
|
const lastRunAt = getTaskScheduleState(db, projectIdentity, config.task)?.lastRunAt ?? null;
|
|
18343
18230
|
const maintainDocsSnapshot = task === "maintain-docs" ? snapshotMaintainDocsFiles(docsDir) : undefined;
|
|
18344
18231
|
const existingDocs = task === "maintain-docs" ? {
|
|
18345
|
-
architecture:
|
|
18346
|
-
structure:
|
|
18232
|
+
architecture: existsSync9(`${docsDir}/ARCHITECTURE.md`),
|
|
18233
|
+
structure: existsSync9(`${docsDir}/STRUCTURE.md`)
|
|
18347
18234
|
} : undefined;
|
|
18348
18235
|
const userMemories = task === "curate" ? getActiveUserMemories(db).map((um) => ({ id: um.id, content: um.content })) : undefined;
|
|
18349
18236
|
let curateMemories;
|
|
@@ -19056,7 +18943,7 @@ var startupJitters = new Map;
|
|
|
19056
18943
|
var nextStartupJitterSlot = 0;
|
|
19057
18944
|
function directoryStillExists(directory) {
|
|
19058
18945
|
try {
|
|
19059
|
-
return
|
|
18946
|
+
return statSync3(directory).isDirectory();
|
|
19060
18947
|
} catch {
|
|
19061
18948
|
return false;
|
|
19062
18949
|
}
|
|
@@ -19379,7 +19266,7 @@ function createDreamTimerModuleClient(moduleClient) {
|
|
|
19379
19266
|
}
|
|
19380
19267
|
|
|
19381
19268
|
// src/plugin/embedding-bootstrap-helpers.ts
|
|
19382
|
-
import { createHash as
|
|
19269
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
19383
19270
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
19384
19271
|
"embedding.api_key",
|
|
19385
19272
|
"embedding.endpoint",
|
|
@@ -19425,7 +19312,7 @@ var EMBEDDING_WARNING_TERMS = [
|
|
|
19425
19312
|
];
|
|
19426
19313
|
var loggedFailureSignatures = new Map;
|
|
19427
19314
|
function sha256Prefix(value, length = 16) {
|
|
19428
|
-
return
|
|
19315
|
+
return createHash9("sha256").update(value).digest("hex").slice(0, length);
|
|
19429
19316
|
}
|
|
19430
19317
|
function warningLooksEmbeddingRelated(message) {
|
|
19431
19318
|
const lower = message.toLowerCase();
|
|
@@ -19729,16 +19616,7 @@ function resolveCacheTtl(cacheTtl, modelKey) {
|
|
|
19729
19616
|
if (typeof cacheTtl === "string") {
|
|
19730
19617
|
return cacheTtl;
|
|
19731
19618
|
}
|
|
19732
|
-
|
|
19733
|
-
return cacheTtl[modelKey];
|
|
19734
|
-
}
|
|
19735
|
-
if (modelKey) {
|
|
19736
|
-
const bareModelId = modelKey.split("/").slice(1).join("/");
|
|
19737
|
-
if (bareModelId && typeof cacheTtl[bareModelId] === "string") {
|
|
19738
|
-
return cacheTtl[bareModelId];
|
|
19739
|
-
}
|
|
19740
|
-
}
|
|
19741
|
-
return cacheTtl.default ?? "5m";
|
|
19619
|
+
return resolveModelConfigOrDefault(cacheTtl, modelKey, cacheTtl.default ?? "5m");
|
|
19742
19620
|
}
|
|
19743
19621
|
var clampWarnSeen = new Set;
|
|
19744
19622
|
function isFinitePositive(v) {
|
|
@@ -22765,7 +22643,7 @@ function replayCavemanCompression(sessionId, db, targets, tags) {
|
|
|
22765
22643
|
}
|
|
22766
22644
|
|
|
22767
22645
|
// src/hooks/magic-context/compaction-off-transition.ts
|
|
22768
|
-
import { existsSync as
|
|
22646
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
22769
22647
|
var loggedUnverifiedMarkerCleanupRetry = false;
|
|
22770
22648
|
var COMPACTION_OFF_FLIP_NOTICE = [
|
|
22771
22649
|
"## Magic Context — compaction-off mode is now active",
|
|
@@ -22800,7 +22678,7 @@ function clearCachedM0Baseline(db, sessionId) {
|
|
|
22800
22678
|
return (result.changes ?? 0) > 0;
|
|
22801
22679
|
}
|
|
22802
22680
|
function cleanupOffMarkers(sessionId) {
|
|
22803
|
-
if (!
|
|
22681
|
+
if (!existsSync10(getOpenCodeDbPath())) {
|
|
22804
22682
|
return { verified: true, removedLineages: 0, removedRows: 0, retainedLineages: 0 };
|
|
22805
22683
|
}
|
|
22806
22684
|
return removeMcOwnedCompactionMarkers(sessionId, MARKER_SUMMARY_TEXT);
|
|
@@ -23894,7 +23772,7 @@ function createPassOutcome() {
|
|
|
23894
23772
|
}
|
|
23895
23773
|
|
|
23896
23774
|
// src/hooks/magic-context/rust-mode-transform.ts
|
|
23897
|
-
import { createHash as
|
|
23775
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
23898
23776
|
|
|
23899
23777
|
// src/hooks/magic-context/module-state-sync.ts
|
|
23900
23778
|
import { createHmac, randomUUID as randomUUID5 } from "node:crypto";
|
|
@@ -25232,6 +25110,121 @@ async function syncModuleState(args) {
|
|
|
25232
25110
|
}
|
|
25233
25111
|
}
|
|
25234
25112
|
|
|
25113
|
+
// src/hooks/magic-context/todo-view.ts
|
|
25114
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
25115
|
+
var TODO_STATUS_PENDING = "pending";
|
|
25116
|
+
var TODO_STATUS_IN_PROGRESS = "in_progress";
|
|
25117
|
+
var TODO_STATUS_COMPLETED = "completed";
|
|
25118
|
+
var TODO_STATUS_CANCELLED = "cancelled";
|
|
25119
|
+
var TODO_PRIORITY_HIGH = "high";
|
|
25120
|
+
var TODO_PRIORITY_MEDIUM = "medium";
|
|
25121
|
+
var TODO_PRIORITY_LOW = "low";
|
|
25122
|
+
var TODO_STATUSES = [
|
|
25123
|
+
TODO_STATUS_PENDING,
|
|
25124
|
+
TODO_STATUS_IN_PROGRESS,
|
|
25125
|
+
TODO_STATUS_COMPLETED,
|
|
25126
|
+
TODO_STATUS_CANCELLED
|
|
25127
|
+
];
|
|
25128
|
+
var TODO_PRIORITIES = [
|
|
25129
|
+
TODO_PRIORITY_HIGH,
|
|
25130
|
+
TODO_PRIORITY_MEDIUM,
|
|
25131
|
+
TODO_PRIORITY_LOW
|
|
25132
|
+
];
|
|
25133
|
+
var TODO_STATUS_SET = new Set(TODO_STATUSES);
|
|
25134
|
+
var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
|
|
25135
|
+
var TERMINAL_STATUSES = new Set([
|
|
25136
|
+
TODO_STATUS_COMPLETED,
|
|
25137
|
+
TODO_STATUS_CANCELLED
|
|
25138
|
+
]);
|
|
25139
|
+
var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
|
|
25140
|
+
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
25141
|
+
function normalizeTodoStateJson(todos) {
|
|
25142
|
+
if (!Array.isArray(todos))
|
|
25143
|
+
return null;
|
|
25144
|
+
const normalized = [];
|
|
25145
|
+
for (const todo of todos) {
|
|
25146
|
+
if (!isTodoItem(todo))
|
|
25147
|
+
return null;
|
|
25148
|
+
normalized.push({
|
|
25149
|
+
content: todo.content,
|
|
25150
|
+
status: todo.status,
|
|
25151
|
+
priority: todo.priority ?? TODO_PRIORITY_MEDIUM
|
|
25152
|
+
});
|
|
25153
|
+
}
|
|
25154
|
+
return JSON.stringify(normalized);
|
|
25155
|
+
}
|
|
25156
|
+
function buildSyntheticTodoPart(stateJson) {
|
|
25157
|
+
const todos = parseTodoState(stateJson);
|
|
25158
|
+
if (todos === null || todos.length === 0)
|
|
25159
|
+
return null;
|
|
25160
|
+
if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
|
|
25161
|
+
return null;
|
|
25162
|
+
const callID = computeSyntheticCallId(stateJson);
|
|
25163
|
+
const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
|
|
25164
|
+
const output = JSON.stringify(todos, null, 2);
|
|
25165
|
+
const ts = 0;
|
|
25166
|
+
return {
|
|
25167
|
+
type: "tool",
|
|
25168
|
+
callID,
|
|
25169
|
+
tool: "todowrite",
|
|
25170
|
+
state: {
|
|
25171
|
+
status: "completed",
|
|
25172
|
+
input: { todos },
|
|
25173
|
+
output,
|
|
25174
|
+
title: `${activeCount} todos`,
|
|
25175
|
+
metadata: { todos, truncated: false },
|
|
25176
|
+
time: { start: ts, end: ts }
|
|
25177
|
+
},
|
|
25178
|
+
syntheticTodoMarker: true
|
|
25179
|
+
};
|
|
25180
|
+
}
|
|
25181
|
+
function computeSyntheticCallId(stateJson) {
|
|
25182
|
+
const hash = createHash11("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
25183
|
+
return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
|
|
25184
|
+
}
|
|
25185
|
+
function isSyntheticTodoPart(part) {
|
|
25186
|
+
if (part === null || typeof part !== "object")
|
|
25187
|
+
return false;
|
|
25188
|
+
const p = part;
|
|
25189
|
+
if (p.syntheticTodoMarker === true)
|
|
25190
|
+
return true;
|
|
25191
|
+
return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
|
|
25192
|
+
}
|
|
25193
|
+
function parseTodoState(stateJson) {
|
|
25194
|
+
if (stateJson.length === 0)
|
|
25195
|
+
return null;
|
|
25196
|
+
try {
|
|
25197
|
+
const parsed = JSON.parse(stateJson);
|
|
25198
|
+
if (!Array.isArray(parsed))
|
|
25199
|
+
return null;
|
|
25200
|
+
const result = [];
|
|
25201
|
+
for (const item of parsed) {
|
|
25202
|
+
if (!isTodoItem(item))
|
|
25203
|
+
return null;
|
|
25204
|
+
result.push({
|
|
25205
|
+
content: item.content,
|
|
25206
|
+
status: item.status,
|
|
25207
|
+
priority: item.priority ?? TODO_PRIORITY_MEDIUM
|
|
25208
|
+
});
|
|
25209
|
+
}
|
|
25210
|
+
return result;
|
|
25211
|
+
} catch {
|
|
25212
|
+
return null;
|
|
25213
|
+
}
|
|
25214
|
+
}
|
|
25215
|
+
function isTodoStatus(value) {
|
|
25216
|
+
return typeof value === "string" && TODO_STATUS_SET.has(value);
|
|
25217
|
+
}
|
|
25218
|
+
function isTodoPriority(value) {
|
|
25219
|
+
return typeof value === "string" && TODO_PRIORITY_SET.has(value);
|
|
25220
|
+
}
|
|
25221
|
+
function isTodoItem(value) {
|
|
25222
|
+
if (value === null || typeof value !== "object")
|
|
25223
|
+
return false;
|
|
25224
|
+
const todo = value;
|
|
25225
|
+
return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
|
|
25226
|
+
}
|
|
25227
|
+
|
|
25235
25228
|
// src/hooks/magic-context/transform-context-state.ts
|
|
25236
25229
|
function loadPersistedUsageWatermark(db, sessionId) {
|
|
25237
25230
|
const result = db.prepare("SELECT last_response_time FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
@@ -25335,7 +25328,7 @@ function containsProbeVerbatim(text, probes) {
|
|
|
25335
25328
|
}
|
|
25336
25329
|
|
|
25337
25330
|
// src/features/magic-context/search-measurement.ts
|
|
25338
|
-
import { createHash as
|
|
25331
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
25339
25332
|
function resultId(result) {
|
|
25340
25333
|
switch (result.source) {
|
|
25341
25334
|
case "memory":
|
|
@@ -25422,7 +25415,7 @@ async function recordShadowMeasurement(args) {
|
|
|
25422
25415
|
}
|
|
25423
25416
|
}
|
|
25424
25417
|
function sha256(value) {
|
|
25425
|
-
return
|
|
25418
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
25426
25419
|
}
|
|
25427
25420
|
|
|
25428
25421
|
// src/features/magic-context/search.ts
|
|
@@ -27783,121 +27776,6 @@ function readFilePath(target) {
|
|
|
27783
27776
|
return null;
|
|
27784
27777
|
}
|
|
27785
27778
|
|
|
27786
|
-
// src/hooks/magic-context/todo-view.ts
|
|
27787
|
-
import { createHash as createHash10 } from "node:crypto";
|
|
27788
|
-
var TODO_STATUS_PENDING = "pending";
|
|
27789
|
-
var TODO_STATUS_IN_PROGRESS = "in_progress";
|
|
27790
|
-
var TODO_STATUS_COMPLETED = "completed";
|
|
27791
|
-
var TODO_STATUS_CANCELLED = "cancelled";
|
|
27792
|
-
var TODO_PRIORITY_HIGH = "high";
|
|
27793
|
-
var TODO_PRIORITY_MEDIUM = "medium";
|
|
27794
|
-
var TODO_PRIORITY_LOW = "low";
|
|
27795
|
-
var TODO_STATUSES = [
|
|
27796
|
-
TODO_STATUS_PENDING,
|
|
27797
|
-
TODO_STATUS_IN_PROGRESS,
|
|
27798
|
-
TODO_STATUS_COMPLETED,
|
|
27799
|
-
TODO_STATUS_CANCELLED
|
|
27800
|
-
];
|
|
27801
|
-
var TODO_PRIORITIES = [
|
|
27802
|
-
TODO_PRIORITY_HIGH,
|
|
27803
|
-
TODO_PRIORITY_MEDIUM,
|
|
27804
|
-
TODO_PRIORITY_LOW
|
|
27805
|
-
];
|
|
27806
|
-
var TODO_STATUS_SET = new Set(TODO_STATUSES);
|
|
27807
|
-
var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
|
|
27808
|
-
var TERMINAL_STATUSES = new Set([
|
|
27809
|
-
TODO_STATUS_COMPLETED,
|
|
27810
|
-
TODO_STATUS_CANCELLED
|
|
27811
|
-
]);
|
|
27812
|
-
var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
|
|
27813
|
-
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
27814
|
-
function normalizeTodoStateJson(todos) {
|
|
27815
|
-
if (!Array.isArray(todos))
|
|
27816
|
-
return null;
|
|
27817
|
-
const normalized = [];
|
|
27818
|
-
for (const todo of todos) {
|
|
27819
|
-
if (!isTodoItem(todo))
|
|
27820
|
-
return null;
|
|
27821
|
-
normalized.push({
|
|
27822
|
-
content: todo.content,
|
|
27823
|
-
status: todo.status,
|
|
27824
|
-
priority: todo.priority ?? TODO_PRIORITY_MEDIUM
|
|
27825
|
-
});
|
|
27826
|
-
}
|
|
27827
|
-
return JSON.stringify(normalized);
|
|
27828
|
-
}
|
|
27829
|
-
function buildSyntheticTodoPart(stateJson) {
|
|
27830
|
-
const todos = parseTodoState(stateJson);
|
|
27831
|
-
if (todos === null || todos.length === 0)
|
|
27832
|
-
return null;
|
|
27833
|
-
if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
|
|
27834
|
-
return null;
|
|
27835
|
-
const callID = computeSyntheticCallId(stateJson);
|
|
27836
|
-
const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
|
|
27837
|
-
const output = JSON.stringify(todos, null, 2);
|
|
27838
|
-
const ts = 0;
|
|
27839
|
-
return {
|
|
27840
|
-
type: "tool",
|
|
27841
|
-
callID,
|
|
27842
|
-
tool: "todowrite",
|
|
27843
|
-
state: {
|
|
27844
|
-
status: "completed",
|
|
27845
|
-
input: { todos },
|
|
27846
|
-
output,
|
|
27847
|
-
title: `${activeCount} todos`,
|
|
27848
|
-
metadata: { todos, truncated: false },
|
|
27849
|
-
time: { start: ts, end: ts }
|
|
27850
|
-
},
|
|
27851
|
-
syntheticTodoMarker: true
|
|
27852
|
-
};
|
|
27853
|
-
}
|
|
27854
|
-
function computeSyntheticCallId(stateJson) {
|
|
27855
|
-
const hash = createHash10("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
27856
|
-
return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
|
|
27857
|
-
}
|
|
27858
|
-
function isSyntheticTodoPart(part) {
|
|
27859
|
-
if (part === null || typeof part !== "object")
|
|
27860
|
-
return false;
|
|
27861
|
-
const p = part;
|
|
27862
|
-
if (p.syntheticTodoMarker === true)
|
|
27863
|
-
return true;
|
|
27864
|
-
return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
|
|
27865
|
-
}
|
|
27866
|
-
function parseTodoState(stateJson) {
|
|
27867
|
-
if (stateJson.length === 0)
|
|
27868
|
-
return null;
|
|
27869
|
-
try {
|
|
27870
|
-
const parsed = JSON.parse(stateJson);
|
|
27871
|
-
if (!Array.isArray(parsed))
|
|
27872
|
-
return null;
|
|
27873
|
-
const result = [];
|
|
27874
|
-
for (const item of parsed) {
|
|
27875
|
-
if (!isTodoItem(item))
|
|
27876
|
-
return null;
|
|
27877
|
-
result.push({
|
|
27878
|
-
content: item.content,
|
|
27879
|
-
status: item.status,
|
|
27880
|
-
priority: item.priority ?? TODO_PRIORITY_MEDIUM
|
|
27881
|
-
});
|
|
27882
|
-
}
|
|
27883
|
-
return result;
|
|
27884
|
-
} catch {
|
|
27885
|
-
return null;
|
|
27886
|
-
}
|
|
27887
|
-
}
|
|
27888
|
-
function isTodoStatus(value) {
|
|
27889
|
-
return typeof value === "string" && TODO_STATUS_SET.has(value);
|
|
27890
|
-
}
|
|
27891
|
-
function isTodoPriority(value) {
|
|
27892
|
-
return typeof value === "string" && TODO_PRIORITY_SET.has(value);
|
|
27893
|
-
}
|
|
27894
|
-
function isTodoItem(value) {
|
|
27895
|
-
if (value === null || typeof value !== "object")
|
|
27896
|
-
return false;
|
|
27897
|
-
const todo = value;
|
|
27898
|
-
return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
|
|
27899
|
-
}
|
|
27900
|
-
|
|
27901
27779
|
// src/hooks/magic-context/tool-reclaim.ts
|
|
27902
27780
|
function buildSyntheticToolReclaimOps(input) {
|
|
27903
27781
|
const watermark = Math.max(0, input.watermark);
|
|
@@ -29411,7 +29289,9 @@ class MemoryAuthorityUnavailableError extends Error {
|
|
|
29411
29289
|
}
|
|
29412
29290
|
}
|
|
29413
29291
|
var RUST_FAILURE_PARK_THRESHOLD = 3;
|
|
29414
|
-
var
|
|
29292
|
+
var RUST_PARK_RETRY_INTERVAL = 5;
|
|
29293
|
+
var RUST_EMERGENCY_WALL_PCT = 95;
|
|
29294
|
+
var RUST_PARK_PROBE_PRESSURE_BYPASS_PCT = 90;
|
|
29415
29295
|
var RUST_SEND_TIMEOUT_MS = 15000;
|
|
29416
29296
|
function isRecord3(value) {
|
|
29417
29297
|
return value !== null && typeof value === "object";
|
|
@@ -29572,10 +29452,10 @@ function messageCacheSignature(message) {
|
|
|
29572
29452
|
const parts = Array.isArray(message.parts) ? message.parts : [];
|
|
29573
29453
|
const serializedParts = JSON.stringify(parts) ?? "null";
|
|
29574
29454
|
const serializedMessage = JSON.stringify(message) ?? "null";
|
|
29575
|
-
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${
|
|
29455
|
+
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash13("sha256").update(serializedMessage).digest("hex")}`;
|
|
29576
29456
|
}
|
|
29577
29457
|
function advanceWireFingerprint(previous, encoded) {
|
|
29578
|
-
return
|
|
29458
|
+
return createHash13("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
|
|
29579
29459
|
}
|
|
29580
29460
|
function buildWireFingerprint(encoded) {
|
|
29581
29461
|
let fingerprint = "rust-wire-v1";
|
|
@@ -29613,7 +29493,8 @@ function formatRustPassLog(args) {
|
|
|
29613
29493
|
const timings = args.timings ?? emptyRustPassTimings();
|
|
29614
29494
|
const measured = timings.prefixGuard + timings.ordinalResolve + timings.stateSync + timings.clone + timings.wireBuild + timings.transport + timings.apply + timings.lkgSnapshot;
|
|
29615
29495
|
const unattributed = Math.max(0, args.elapsedMs - measured);
|
|
29616
|
-
|
|
29496
|
+
const rowVersion = Number.isSafeInteger(args.rowVersion) ? args.rowVersion : 0;
|
|
29497
|
+
return `rust pass: decision=${args.decision} reason=${args.reason} served_from=${args.servedFrom} in=${args.inputCount} out=${args.outputCount} applied=${args.applied} row_version=${rowVersion} elapsed=${args.elapsedMs.toFixed(1)} ms module=${args.moduleElapsedMs.toFixed(1)} ms stages=prefix_guard:${timings.prefixGuard.toFixed(1)} ordinal_resolve:${timings.ordinalResolve.toFixed(1)} state_sync:${timings.stateSync.toFixed(1)} clone:${timings.clone.toFixed(1)} wire_build:${timings.wireBuild.toFixed(1)} wire_messages:${timings.wireMessages} transport:${timings.transport.toFixed(1)} transport_pages:${timings.transportPages} transport_bytes:${timings.transportBytes} apply:${timings.apply.toFixed(1)} lkg_snapshot:${timings.lkgSnapshot.toFixed(1)} other:${unattributed.toFixed(1)}`;
|
|
29617
29498
|
}
|
|
29618
29499
|
function isSyntheticUserMessage(message) {
|
|
29619
29500
|
if (!message || messageInfo2(message).role !== "user" || !Array.isArray(message.parts)) {
|
|
@@ -29774,7 +29655,7 @@ function canonicalizeForChecksum(value) {
|
|
|
29774
29655
|
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalizeForChecksum(value[key])]));
|
|
29775
29656
|
}
|
|
29776
29657
|
function checksumSeedRows(rows) {
|
|
29777
|
-
return
|
|
29658
|
+
return createHash13("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
|
|
29778
29659
|
}
|
|
29779
29660
|
function authoritySeedRows(db, projectPath, domain) {
|
|
29780
29661
|
const snapshots = domain === "memories" ? db.prepare("SELECT * FROM memories WHERE project_path = ? ORDER BY id ASC").all(projectPath) : db.prepare(`SELECT n.*
|
|
@@ -29915,6 +29796,35 @@ async function prepareRustMemoryAuthority(args) {
|
|
|
29915
29796
|
state.memoryAuthorityReady = true;
|
|
29916
29797
|
args.onProjectPrepared?.(projectPath);
|
|
29917
29798
|
}
|
|
29799
|
+
var TODO_HEAD_ANCHOR_ID2 = "__magic_context_todo_head__";
|
|
29800
|
+
function syntheticTodoAnchorFromNative(messages) {
|
|
29801
|
+
for (let index = 0;index < messages.length; index += 1) {
|
|
29802
|
+
const message = messages[index];
|
|
29803
|
+
if (!isRecord3(message) || !Array.isArray(message.parts))
|
|
29804
|
+
continue;
|
|
29805
|
+
const part = message.parts.find((candidate) => isRecord3(candidate) && candidate.syntheticTodoMarker === true);
|
|
29806
|
+
if (!isRecord3(part) || typeof part.callID !== "string")
|
|
29807
|
+
continue;
|
|
29808
|
+
const state = isRecord3(part.state) ? part.state : undefined;
|
|
29809
|
+
const input = state && isRecord3(state.input) ? state.input : undefined;
|
|
29810
|
+
const stateJson = normalizeTodoStateJson(input?.todos);
|
|
29811
|
+
if (stateJson === null || computeSyntheticCallId(stateJson) !== part.callID)
|
|
29812
|
+
continue;
|
|
29813
|
+
const previous = messages[index - 1];
|
|
29814
|
+
const previousInfo = isRecord3(previous) && isRecord3(previous.info) ? previous.info : undefined;
|
|
29815
|
+
const messageId2 = previousInfo && typeof previousInfo.id === "string" && previousInfo.id.length > 0 ? previousInfo.id : TODO_HEAD_ANCHOR_ID2;
|
|
29816
|
+
return { callId: part.callID, messageId: messageId2, stateJson };
|
|
29817
|
+
}
|
|
29818
|
+
return null;
|
|
29819
|
+
}
|
|
29820
|
+
function mirrorRustSyntheticTodoAnchor(args) {
|
|
29821
|
+
const anchor = syntheticTodoAnchorFromNative(args.messages);
|
|
29822
|
+
if (anchor) {
|
|
29823
|
+
setPersistedTodoSyntheticAnchor(args.db, args.sessionId, anchor.callId, anchor.messageId, anchor.stateJson);
|
|
29824
|
+
} else if (args.cacheBustingPass) {
|
|
29825
|
+
clearPersistedTodoSyntheticAnchor(args.db, args.sessionId);
|
|
29826
|
+
}
|
|
29827
|
+
}
|
|
29918
29828
|
function applyNativeMessagesVerbatim(output, response) {
|
|
29919
29829
|
const nativeMessages = response.native_messages;
|
|
29920
29830
|
if (typeof nativeMessages === "string") {
|
|
@@ -29968,6 +29878,9 @@ function buildTransformBody(args) {
|
|
|
29968
29878
|
model_key: args.modelKey,
|
|
29969
29879
|
provider_id: args.providerId,
|
|
29970
29880
|
tool_present: args.passInputs.tool_present === true,
|
|
29881
|
+
prompt_surface_preset: args.passInputs.prompt_surface_preset ?? "full",
|
|
29882
|
+
prompt_surface_model_key: args.passInputs.prompt_surface_model_key,
|
|
29883
|
+
prompt_surface_tool_descriptions: args.passInputs.prompt_surface_tool_descriptions ?? {},
|
|
29971
29884
|
effective_execute_threshold: args.passInputs.effective_execute_threshold,
|
|
29972
29885
|
history_budget_tokens: args.passInputs.history_budget_tokens,
|
|
29973
29886
|
clear_reasoning_age: args.passInputs.clear_reasoning_age,
|
|
@@ -30014,7 +29927,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30014
29927
|
state.passesSincePark = 0;
|
|
30015
29928
|
state.warningSent = true;
|
|
30016
29929
|
const warning = "Rust Magic Context is unavailable for this session; retry after the module recovers.";
|
|
30017
|
-
sessionLog(sessionId,
|
|
29930
|
+
sessionLog(sessionId, `mc_rust_park_transition failure_passes=${state.consecutiveFailures} pass_count=${state.passCount} park_count=${state.parkCount}`);
|
|
30018
29931
|
options.notifyParked?.(sessionId, warning);
|
|
30019
29932
|
};
|
|
30020
29933
|
const resetOrdinalMemo = (state) => {
|
|
@@ -30147,6 +30060,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30147
30060
|
let materializeReason = "none";
|
|
30148
30061
|
let servedFrom = "none";
|
|
30149
30062
|
let moduleElapsedMs = 0;
|
|
30063
|
+
let rowVersion = 0;
|
|
30150
30064
|
let appliedAt;
|
|
30151
30065
|
let emergencyFailClosed = false;
|
|
30152
30066
|
const passUsageSnapshot = loadContextUsage(deps.contextUsageMap, deps.db, sessionId);
|
|
@@ -30178,7 +30092,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30178
30092
|
} catch (error) {
|
|
30179
30093
|
preflightError ??= error;
|
|
30180
30094
|
}
|
|
30181
|
-
emergencyFailClosed = passUsageSnapshot.percentage >=
|
|
30095
|
+
emergencyFailClosed = passUsageSnapshot.percentage >= RUST_EMERGENCY_WALL_PCT && resolvedContextLimit !== undefined && resolvedContextLimit > 0;
|
|
30182
30096
|
if (overflowState) {
|
|
30183
30097
|
const detectedLimitMatchesModel = overflowState.detectedContextLimitModelKey === null || overflowState.detectedContextLimitModelKey === modelKey;
|
|
30184
30098
|
const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
|
|
@@ -30196,6 +30110,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30196
30110
|
applied,
|
|
30197
30111
|
elapsedMs,
|
|
30198
30112
|
moduleElapsedMs,
|
|
30113
|
+
rowVersion,
|
|
30199
30114
|
timings
|
|
30200
30115
|
}));
|
|
30201
30116
|
if (served) {
|
|
@@ -30215,6 +30130,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30215
30130
|
const timings2 = isRecord3(response.timings) ? response.timings : undefined;
|
|
30216
30131
|
const total = timings2?.total;
|
|
30217
30132
|
moduleElapsedMs = typeof total === "number" && Number.isFinite(total) ? total : 0;
|
|
30133
|
+
rowVersion = typeof response.row_version === "number" && Number.isSafeInteger(response.row_version) ? response.row_version : 0;
|
|
30218
30134
|
if (timings2 && moduleElapsedMs >= 1000) {
|
|
30219
30135
|
const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
|
|
30220
30136
|
if (detail)
|
|
@@ -30223,7 +30139,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30223
30139
|
};
|
|
30224
30140
|
if (state.parked) {
|
|
30225
30141
|
state.passesSincePark += 1;
|
|
30226
|
-
if (!emergencyFailClosed && passUsageSnapshot.percentage <
|
|
30142
|
+
if (!emergencyFailClosed && passUsageSnapshot.percentage < RUST_PARK_PROBE_PRESSURE_BYPASS_PCT && state.passCount % RUST_PARK_RETRY_INTERVAL !== 0) {
|
|
30227
30143
|
decision = "parked";
|
|
30228
30144
|
const replayed = replayLastGood(sessionId, messages, output, sessionMeta.systemPromptTokens);
|
|
30229
30145
|
if (replayed) {
|
|
@@ -30255,6 +30171,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30255
30171
|
const midTurn = isMidTurn(deps, sessionId);
|
|
30256
30172
|
const requestObservedAtMs = Date.now();
|
|
30257
30173
|
const recoveryNoHeadEscape = overflowState.needsEmergencyRecovery && loadProtectedTailMeta(deps.db, sessionId).recoveryNoEligibleHeadCount >= RECOVERY_NO_HEAD_LIMIT;
|
|
30174
|
+
const promptSurface = resolvePromptSurface(deps.promptSurface, modelKey ?? undefined);
|
|
30258
30175
|
const passInputs = {
|
|
30259
30176
|
now_ms: requestObservedAtMs,
|
|
30260
30177
|
model_key: modelKey,
|
|
@@ -30271,6 +30188,9 @@ function createRustModeTransform(deps, options) {
|
|
|
30271
30188
|
system_prompt_hash: sessionMeta.systemPromptHash ?? "",
|
|
30272
30189
|
upgrade_state: readUpgradeState(deps.db, sessionId),
|
|
30273
30190
|
tool_present: toolPresent,
|
|
30191
|
+
prompt_surface_preset: promptSurface.preset,
|
|
30192
|
+
prompt_surface_model_key: modelKey,
|
|
30193
|
+
prompt_surface_tool_descriptions: deps.promptSurface?.tool_descriptions ?? {},
|
|
30274
30194
|
protected_tags: deps.protectedTags ?? DEFAULT_PROTECTED_TAGS,
|
|
30275
30195
|
temporal_awareness: deps.experimentalTemporalAwareness === true,
|
|
30276
30196
|
channel2_nudge_state: getChannel2NudgeState(deps.db, sessionId),
|
|
@@ -30630,6 +30550,9 @@ function createRustModeTransform(deps, options) {
|
|
|
30630
30550
|
});
|
|
30631
30551
|
}
|
|
30632
30552
|
};
|
|
30553
|
+
const explicitDecision = typeof response.decision === "string" || typeof response.action === "string" || typeof response.cache_bust === "boolean";
|
|
30554
|
+
const decisionUpper = decision.toUpperCase();
|
|
30555
|
+
const cacheBustingPass = response.cache_bust === true || decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT" || !explicitDecision;
|
|
30633
30556
|
let appliedMessages;
|
|
30634
30557
|
const applyStartedAt = performance.now();
|
|
30635
30558
|
try {
|
|
@@ -30645,6 +30568,14 @@ function createRustModeTransform(deps, options) {
|
|
|
30645
30568
|
if (typeof boundaryId === "string" && boundaryId.length > 0) {
|
|
30646
30569
|
assertNativeBoundary(appliedMessages, sessionId, boundaryId);
|
|
30647
30570
|
}
|
|
30571
|
+
if (!sessionMeta.isSubagent) {
|
|
30572
|
+
mirrorRustSyntheticTodoAnchor({
|
|
30573
|
+
db: deps.db,
|
|
30574
|
+
sessionId,
|
|
30575
|
+
messages: appliedMessages,
|
|
30576
|
+
cacheBustingPass
|
|
30577
|
+
});
|
|
30578
|
+
}
|
|
30648
30579
|
if (passInputs.emergency_recovery_armed === true) {
|
|
30649
30580
|
servedFinalWireEstimate = estimateFinalWireInputTokens({
|
|
30650
30581
|
messages: appliedMessages,
|
|
@@ -30656,9 +30587,6 @@ function createRustModeTransform(deps, options) {
|
|
|
30656
30587
|
}
|
|
30657
30588
|
logStage(sessionId, "apply", applyStartedAt, timings);
|
|
30658
30589
|
const lkgSnapshotStartedAt = performance.now();
|
|
30659
|
-
const explicitDecision = typeof response.decision === "string" || typeof response.action === "string" || typeof response.cache_bust === "boolean";
|
|
30660
|
-
const decisionUpper = decision.toUpperCase();
|
|
30661
|
-
const cacheBustingPass = response.cache_bust === true || decisionUpper === "HARD" || decisionUpper === "MIGRATE_HARD" || decisionUpper === "EXECUTE" || decisionUpper === "SOFT" || !explicitDecision;
|
|
30662
30590
|
if (cacheBustingPass || !getSlot(sessionId)) {
|
|
30663
30591
|
const captured = captureRustResponse(sessionId, messages, response);
|
|
30664
30592
|
if (cacheBustingPass && !captured) {
|
|
@@ -30766,6 +30694,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30766
30694
|
sessionLog(sessionId, "rust transform wire invariant failed; LKG replay required", error);
|
|
30767
30695
|
}
|
|
30768
30696
|
if (emergencyFailClosed) {
|
|
30697
|
+
sessionLog(sessionId, "mc_rust_emergency_refusal before_lkg");
|
|
30769
30698
|
markFailure(sessionId, state, error);
|
|
30770
30699
|
finishPass(false, false);
|
|
30771
30700
|
throw new EmergencyFailClosedError("Rust Magic Context was unavailable at a provider-proven context limit", { cause: error });
|
|
@@ -30785,10 +30714,17 @@ function createRustModeTransform(deps, options) {
|
|
|
30785
30714
|
return {
|
|
30786
30715
|
run,
|
|
30787
30716
|
clearSession(sessionId) {
|
|
30717
|
+
const projectRoot = states.get(sessionId)?.memoryAuthorityRoot ?? options.projectRoot ?? null;
|
|
30788
30718
|
dropSlot(sessionId, "session-deleted");
|
|
30789
30719
|
states.delete(sessionId);
|
|
30790
30720
|
wireCaches.delete(sessionId);
|
|
30791
|
-
options.moduleClient.
|
|
30721
|
+
if (projectRoot && options.moduleClient.deleteSession) {
|
|
30722
|
+
options.moduleClient.deleteSession(sessionId, projectRoot).catch((error) => {
|
|
30723
|
+
sessionLog(sessionId, "rust module session deletion failed:", error);
|
|
30724
|
+
}).finally(() => options.moduleClient.closeSession?.(sessionId));
|
|
30725
|
+
} else {
|
|
30726
|
+
options.moduleClient.closeSession?.(sessionId);
|
|
30727
|
+
}
|
|
30792
30728
|
},
|
|
30793
30729
|
invalidateWireState,
|
|
30794
30730
|
getState(sessionId) {
|
|
@@ -33123,7 +33059,7 @@ function createToolExecuteAfterHook(args) {
|
|
|
33123
33059
|
}
|
|
33124
33060
|
|
|
33125
33061
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
33126
|
-
import { createHash as
|
|
33062
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
33127
33063
|
|
|
33128
33064
|
// src/agents/magic-context-prompt.ts
|
|
33129
33065
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
@@ -33139,6 +33075,10 @@ var PARTNER_FRAME_CLOSER_REDUCE = `
|
|
|
33139
33075
|
Reduction prompts are routine housekeeping to keep the session fast and cheap — act on them as light maintenance, never as scarcity warnings. Keep individual operations efficient, but never let context size change *what* work you take on or *how thoroughly* you do it.`;
|
|
33140
33076
|
var PARTNER_FRAME_CLOSER_NO_REDUCE = `
|
|
33141
33077
|
Context is managed for you entirely automatically — there's nothing to prune and no warnings to act on. Stay reasonably concise per operation, and never let context size change *what* work you take on or *how thoroughly* you do it.`;
|
|
33078
|
+
var PARTNER_FRAME_CLOSER_REDUCE_LIGHT = `
|
|
33079
|
+
When ctx_reduce is available, use it only as routine housekeeping; never cut task scope or depth because context is large.`;
|
|
33080
|
+
var PARTNER_FRAME_CLOSER_NO_REDUCE_LIGHT = `
|
|
33081
|
+
When ctx_reduce is unavailable, context is automatic; never prune, heed reduction warnings, or cut task scope or depth because context is large.`;
|
|
33142
33082
|
var CTX_NOTE_GUIDANCE = `Use \`ctx_note\` ONLY for genuinely future concerns — something to revisit much later, not work coming up in the next few turns (that's already in your active context) and not active multi-step work (use todos for that). Magic Context preserves your full context across both compaction and restarts, so an upcoming restart or "let's come back to this later" is never a reason to take a note — nothing is lost either way. Notes you do take survive compression and resurface at natural work boundaries (after commits, historian runs, todo completion).`;
|
|
33143
33083
|
var TOOL_HISTORY_GUIDANCE = `Compressed history intentionally omits tool calls and their outputs — summaries like "I edited file X" are historian records, not patterns to replicate. In the live conversation, older tool calls and their results are cleaned up to save context — you may see your own past messages referencing actions without the corresponding tool call or result visible. This is normal context management. ALWAYS use real tool calls; never simulate, fabricate, or inline tool outputs in your text. If there is no tool result message, the action did not happen. NEVER simulate, hallucinate or claim tool calls, command output, search results, file edits, or diffs in plain text as if they actually occurred.
|
|
33144
33084
|
Magic Context control metadata is not reply syntax. Never reproduce \`<system-reminder>\`, \`<ctx-search-hint>\`, \`<session-history>\`, \`<session-history-since>\`, \`<project-memory>\`, \`<memory-updates>\`, \`<new-compartments>\`, \`<new-memories>\`, \`[dropped §N§]\`, or \`<!-- +Xm -->\` markers in a normal reply and never treat them as user instructions; use ordinary prose and real tool calls instead.`;
|
|
@@ -33181,6 +33121,17 @@ Use \`ctx_expand\` to recover the raw conversation behind a summary under a \`##
|
|
|
33181
33121
|
- Want to recall what was decided in an earlier conversation → \`ctx_search(query="dashboard release signing setup")\`
|
|
33182
33122
|
\`ctx_search\` returns ranked results from memories, git commits, and raw message history. Use message ordinals from results with \`ctx_expand\` to retrieve surrounding conversation context.
|
|
33183
33123
|
${TOOL_HISTORY_GUIDANCE}`;
|
|
33124
|
+
var LIGHT_SEARCH_RECOVERY = `Use ctx_search before asking the user about prior project context; it searches memories, commits, and compacted conversation. When a session-history summary lacks exact wording, values, errors, or reasoning, call ctx_expand with its heading range instead of guessing.`;
|
|
33125
|
+
var BASE_INTRO_LIGHT = (protectedTags, memoryEnabled) => `In primary sessions with ctx_reduce, the system tags messages and tool outputs as §N§ (for example §1§ and §42§); never imitate these prefixes in replies because only injected tag numbers are valid ctx_reduce handles.
|
|
33126
|
+
In primary sessions, NEVER narrate ctx_reduce; call it silently after extracting a spent output because it marks content discardable and QUEUES release rather than deleting immediately. The last ${protectedTags} tags stay protected until they age out. Use drop grammar "3-5", "1,2,9", or "1-5,8,12-15".
|
|
33127
|
+
${CTX_NOTE_GUIDANCE}
|
|
33128
|
+
${memoryGuidanceBlock(memoryEnabled)}${LIGHT_SEARCH_RECOVERY}
|
|
33129
|
+
${TOOL_HISTORY_GUIDANCE}
|
|
33130
|
+
For primary ctx_reduce choices, NEVER blanket-drop a large range because mixed-value evidence may be lost: inspect every tag first. Drop only analyzed reads, searches, diagnostics, or build/test outputs after use. NEVER drop user directives or assistant prose unless exceptionally large; keep requirements, constraints, unresolved errors or decisions, exact wording, raw evidence, and active files or work. Only extracted pasted user payloads may go.
|
|
33131
|
+
Consider small targeted drops after acted-on reads or searches, completed logical steps, before context switches, and before the turn ends; this keeps the working set tidy without changing task scope.`;
|
|
33132
|
+
var BASE_INTRO_NO_REDUCE_LIGHT = (memoryEnabled) => `${CTX_NOTE_GUIDANCE}
|
|
33133
|
+
${memoryGuidanceBlock(memoryEnabled)}${LIGHT_SEARCH_RECOVERY}
|
|
33134
|
+
${TOOL_HISTORY_GUIDANCE}`;
|
|
33184
33135
|
var GENERIC_SECTION = `
|
|
33185
33136
|
### Reduction Triggers
|
|
33186
33137
|
- After reading files or search results you already acted on — drop raw outputs.
|
|
@@ -33197,21 +33148,27 @@ var GENERIC_SECTION = `
|
|
|
33197
33148
|
- Your current task requirements and constraints.
|
|
33198
33149
|
- Recent errors and unresolved decisions.
|
|
33199
33150
|
- Active work context and files being edited.`;
|
|
33151
|
+
var SMART_NOTE_GUIDANCE_LIGHT = `
|
|
33152
|
+
surface_condition creates a smart note checked nightly against external signals on ctx_note write.`;
|
|
33200
33153
|
var TEMPORAL_AWARENESS_GUIDANCE = `
|
|
33201
33154
|
**Temporal awareness**: User messages may be preceded by HTML comments like \`<!-- +12m -->\`, \`<!-- +2h 15m -->\`, or \`<!-- +3d 4h -->\` indicating time elapsed since the previous message's completion. Compartments in \`<session-history>\` carry \`start-date\` and \`end-date\` attributes (YYYY-MM-DD) showing real-time boundaries. Use these when reasoning about workflow pacing, log durations, build times, or how long ago something happened.`;
|
|
33202
33155
|
var SUBAGENT_REDUCE_INTRO = (protectedTags) => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
|
|
33203
33156
|
Use \`ctx_reduce\` to drop tool outputs you have already finished with, keeping your working context lean. Syntax: "3-5", "1,2,9", or "1-5,8,12-15". The last ${protectedTags} tags are protected.
|
|
33204
33157
|
Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-50"); review each tag first. Do not drop user or assistant text messages — only large tool outputs are worth dropping.
|
|
33205
33158
|
Older tool calls may show \`[dropped §N§]\` sentinels; that is normal context management, not a pattern to copy. ALWAYS make fresh real tool calls when you need data again; never fabricate or inline tool output.`;
|
|
33159
|
+
var SUBAGENT_REDUCE_INTRO_LIGHT = (protectedTags) => `In bounded subagent sessions, the system tags messages and tool outputs as §N§; use only those IDs in ctx_reduce drop ranges such as "3-5", "1,2,9", or "1-5,8,12-15". The last ${protectedTags} tags stay protected.
|
|
33160
|
+
When dropping, do it silently and NEVER choose a large range before reviewing every tag; drop only finished large tool outputs, never user or assistant messages.
|
|
33161
|
+
If older calls show [dropped §N§], never copy that system sentinel because it is not reply syntax; make a fresh real tool call and never fabricate or inline output.`;
|
|
33206
33162
|
var CAVEMAN_COMPRESSION_WARNING = `
|
|
33207
33163
|
**BEWARE**: History compression is on; older user AND assistant text — including your own earlier responses — has been deterministically rewritten in a terse caveman style (dropped articles, missing auxiliaries, \`//\` instead of connectives like \`because\`). This is automatic context compression that runs after the fact, not your actual prior wording or the user's. **DO NOT mimic this style in new turns.** Write fresh responses in normal prose. If you notice your output drifting into caveman cadence, that drift is in-context-learning bleeding from the compressed history — consciously revert to full sentences.`;
|
|
33208
|
-
function buildMagicContextSection(_agent, protectedTags, ctxReduceCallable = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language, memoryEnabled = true) {
|
|
33164
|
+
function buildMagicContextSection(_agent, protectedTags, ctxReduceCallable = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language, memoryEnabled = true, preset = "full", primaryOverride) {
|
|
33209
33165
|
if (subagentMode) {
|
|
33166
|
+
const intro = preset === "light" ? SUBAGENT_REDUCE_INTRO_LIGHT(protectedTags) : SUBAGENT_REDUCE_INTRO(protectedTags);
|
|
33210
33167
|
return `## Magic Context
|
|
33211
33168
|
|
|
33212
|
-
${
|
|
33169
|
+
${intro}`;
|
|
33213
33170
|
}
|
|
33214
|
-
const smartNoteGuidance = dreamerEnabled ? `
|
|
33171
|
+
const smartNoteGuidance = dreamerEnabled ? preset === "light" ? SMART_NOTE_GUIDANCE_LIGHT : `
|
|
33215
33172
|
When \`surface_condition\` is provided with \`write\`, the note becomes a project-scoped smart note.
|
|
33216
33173
|
The dreamer evaluates smart note conditions during nightly runs and surfaces them when conditions are met.
|
|
33217
33174
|
Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
|
|
@@ -33221,13 +33178,32 @@ Example: \`ctx_note(action="write", content="Implement X because Y", surface_con
|
|
|
33221
33178
|
const languageGuidance = languageDirective ? `
|
|
33222
33179
|
|
|
33223
33180
|
${languageDirective}` : "";
|
|
33181
|
+
if (primaryOverride !== undefined) {
|
|
33182
|
+
return `${primaryOverride}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
33183
|
+
}
|
|
33224
33184
|
if (!ctxReduceCallable) {
|
|
33185
|
+
if (preset === "light") {
|
|
33186
|
+
return `## Magic Context
|
|
33187
|
+
|
|
33188
|
+
${LONG_TERM_PARTNER_FRAME}
|
|
33189
|
+
${PARTNER_FRAME_CLOSER_NO_REDUCE_LIGHT}
|
|
33190
|
+
|
|
33191
|
+
${BASE_INTRO_NO_REDUCE_LIGHT(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
33192
|
+
}
|
|
33225
33193
|
return `## Magic Context
|
|
33226
33194
|
|
|
33227
33195
|
${LONG_TERM_PARTNER_FRAME}
|
|
33228
33196
|
${PARTNER_FRAME_CLOSER_NO_REDUCE}
|
|
33229
33197
|
|
|
33230
33198
|
${BASE_INTRO_NO_REDUCE(memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
33199
|
+
}
|
|
33200
|
+
if (preset === "light") {
|
|
33201
|
+
return `## Magic Context
|
|
33202
|
+
|
|
33203
|
+
${LONG_TERM_PARTNER_FRAME}
|
|
33204
|
+
${PARTNER_FRAME_CLOSER_REDUCE_LIGHT}
|
|
33205
|
+
|
|
33206
|
+
${BASE_INTRO_LIGHT(protectedTags, memoryEnabled)}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
33231
33207
|
}
|
|
33232
33208
|
return `## Magic Context
|
|
33233
33209
|
|
|
@@ -33253,6 +33229,11 @@ function isMagicContextInternalAgent(systemPromptContent) {
|
|
|
33253
33229
|
return systemPromptContent.includes("You are Historian — the hippocampus of a long-running coding agent.") || systemPromptContent.includes("for the magic-context system") || systemPromptContent.includes("You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.");
|
|
33254
33230
|
}
|
|
33255
33231
|
function createSystemPromptHashHandler(deps) {
|
|
33232
|
+
const promptSurfaceRuntime = deps.promptSurfaceRuntime ?? createPromptSurfaceRuntime({
|
|
33233
|
+
userConfigDirectory: process.cwd(),
|
|
33234
|
+
warn: (message) => console.warn(`[magic-context] config warning: ${message}`)
|
|
33235
|
+
});
|
|
33236
|
+
const guidanceEpochs = createPromptSurfaceGuidanceEpochCache(promptSurfaceRuntime);
|
|
33256
33237
|
const stickyDateBySession = new Map;
|
|
33257
33238
|
const handler = async (input, output) => {
|
|
33258
33239
|
const sessionId = input.sessionID;
|
|
@@ -33290,10 +33271,14 @@ function createSystemPromptHashHandler(deps) {
|
|
|
33290
33271
|
const subagentReduceMode = isSubagentSession2 && ctxReduceCallable;
|
|
33291
33272
|
const effectiveCtxReduceEnabled = isSubagentSession2 ? false : ctxReduceCallable;
|
|
33292
33273
|
const skipGuidanceForDisabledSubagent = isSubagentSession2 && !ctxReduceCallable;
|
|
33274
|
+
const inputModel = input.model;
|
|
33275
|
+
const liveModel = inputModel?.providerID && inputModel.modelID ? { providerID: inputModel.providerID, modelID: inputModel.modelID } : deps.resolveModel?.(sessionId);
|
|
33276
|
+
const modelKey = liveModel?.providerID && liveModel.modelID ? `${liveModel.providerID}/${liveModel.modelID}` : undefined;
|
|
33277
|
+
const promptSurface = guidanceEpochs.resolve(sessionId, deps.promptSurface, modelKey);
|
|
33293
33278
|
const fullPrompt = output.system.join(`
|
|
33294
33279
|
`);
|
|
33295
33280
|
if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER) && !skipGuidanceForDisabledSubagent) {
|
|
33296
|
-
const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode, deps.language, deps.memoryEnabled !== false);
|
|
33281
|
+
const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode, deps.language, deps.memoryEnabled !== false, promptSurface.preset, promptSurface.primaryOverride);
|
|
33297
33282
|
output.system.push(guidance);
|
|
33298
33283
|
sessionLog(sessionId, `injected generic guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession2}, subagentReduceMode=${subagentReduceMode})`);
|
|
33299
33284
|
}
|
|
@@ -33324,7 +33309,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
33324
33309
|
return;
|
|
33325
33310
|
if (!availability.frozen)
|
|
33326
33311
|
return;
|
|
33327
|
-
const currentHash =
|
|
33312
|
+
const currentHash = createHash14("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
|
|
33328
33313
|
if (!sessionMetaEarly) {
|
|
33329
33314
|
return;
|
|
33330
33315
|
}
|
|
@@ -33362,6 +33347,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
33362
33347
|
return {
|
|
33363
33348
|
handler,
|
|
33364
33349
|
clearSession: (sessionId) => {
|
|
33350
|
+
guidanceEpochs.clear(sessionId);
|
|
33365
33351
|
clearSystemPromptHashSession(sessionId, {
|
|
33366
33352
|
stickyDateBySession,
|
|
33367
33353
|
cachedDocsBySession: new Map
|
|
@@ -33814,6 +33800,7 @@ function createMagicContextHook(deps) {
|
|
|
33814
33800
|
const client = {
|
|
33815
33801
|
call: (args) => transport.call(args),
|
|
33816
33802
|
stateSyncCapabilities: (args) => transport.stateSyncCapabilities(args),
|
|
33803
|
+
deleteSession: (sessionId, projectRoot) => transport.deleteSession(sessionId, projectRoot),
|
|
33817
33804
|
closeSession: (sessionId) => transport.closeSession(sessionId),
|
|
33818
33805
|
authorityStatus: (args) => transport.authorityStatus(args),
|
|
33819
33806
|
authorityPrepare: (args) => transport.authorityPrepare(args),
|
|
@@ -33842,6 +33829,23 @@ function createMagicContextHook(deps) {
|
|
|
33842
33829
|
return client;
|
|
33843
33830
|
})();
|
|
33844
33831
|
const rustModeModuleClient = deps.config.transform_mode === "rust" ? authorityRecoveryModuleClient : undefined;
|
|
33832
|
+
const syncModuleDomain = async (domain) => {
|
|
33833
|
+
if (!rustModeModuleClient?.mirrorPull)
|
|
33834
|
+
return;
|
|
33835
|
+
for (;; ) {
|
|
33836
|
+
const cursor = getMirrorCursor(db, domain);
|
|
33837
|
+
const response = await rustModeModuleClient.mirrorPull({
|
|
33838
|
+
domain,
|
|
33839
|
+
cursor,
|
|
33840
|
+
limit: 1000
|
|
33841
|
+
});
|
|
33842
|
+
const next = applyMirrorPage({ db, page: response.page });
|
|
33843
|
+
if (!response.page.has_more || next === cursor)
|
|
33844
|
+
break;
|
|
33845
|
+
}
|
|
33846
|
+
};
|
|
33847
|
+
const syncModuleNotes = () => syncModuleDomain("notes");
|
|
33848
|
+
const syncModuleMemories = () => syncModuleDomain("memories");
|
|
33845
33849
|
const rustToolBackends = deps.config.transform_mode === "rust" && rustModeModuleClient ? {
|
|
33846
33850
|
authorityState: async ({ projectPath: projectPath2, projectRoot, domain }) => {
|
|
33847
33851
|
if (!rustModeModuleClient.authorityStatus)
|
|
@@ -33866,7 +33870,7 @@ function createMagicContextHook(deps) {
|
|
|
33866
33870
|
command_id: commandId
|
|
33867
33871
|
}
|
|
33868
33872
|
}),
|
|
33869
|
-
note: ({
|
|
33873
|
+
note: async ({
|
|
33870
33874
|
commandId,
|
|
33871
33875
|
sessionId,
|
|
33872
33876
|
projectRoot,
|
|
@@ -33878,26 +33882,30 @@ function createMagicContextHook(deps) {
|
|
|
33878
33882
|
limit,
|
|
33879
33883
|
offset,
|
|
33880
33884
|
noteId
|
|
33881
|
-
}) =>
|
|
33882
|
-
|
|
33883
|
-
|
|
33884
|
-
|
|
33885
|
-
|
|
33886
|
-
|
|
33887
|
-
|
|
33888
|
-
|
|
33889
|
-
|
|
33890
|
-
|
|
33891
|
-
|
|
33892
|
-
|
|
33893
|
-
|
|
33894
|
-
|
|
33895
|
-
|
|
33896
|
-
|
|
33885
|
+
}) => {
|
|
33886
|
+
const response = await rustModeModuleClient.call({
|
|
33887
|
+
sessionId,
|
|
33888
|
+
projectRoot,
|
|
33889
|
+
method: "ctx_note",
|
|
33890
|
+
body: {
|
|
33891
|
+
name: "ctx_note",
|
|
33892
|
+
arguments: {
|
|
33893
|
+
...commandId ? { command_id: commandId } : {},
|
|
33894
|
+
action,
|
|
33895
|
+
content,
|
|
33896
|
+
memory_project: memoryProject,
|
|
33897
|
+
surface_condition: surfaceCondition,
|
|
33898
|
+
filter,
|
|
33899
|
+
limit,
|
|
33900
|
+
offset,
|
|
33901
|
+
note_id: noteId
|
|
33902
|
+
}
|
|
33897
33903
|
}
|
|
33898
|
-
}
|
|
33899
|
-
|
|
33900
|
-
|
|
33904
|
+
});
|
|
33905
|
+
await syncModuleNotes();
|
|
33906
|
+
return response;
|
|
33907
|
+
},
|
|
33908
|
+
memory: async ({
|
|
33901
33909
|
commandId,
|
|
33902
33910
|
sessionId,
|
|
33903
33911
|
projectRoot,
|
|
@@ -33907,23 +33915,27 @@ function createMagicContextHook(deps) {
|
|
|
33907
33915
|
category,
|
|
33908
33916
|
ids,
|
|
33909
33917
|
reason
|
|
33910
|
-
}) =>
|
|
33911
|
-
|
|
33912
|
-
|
|
33913
|
-
|
|
33914
|
-
|
|
33915
|
-
|
|
33916
|
-
|
|
33917
|
-
|
|
33918
|
-
|
|
33919
|
-
|
|
33920
|
-
|
|
33921
|
-
|
|
33922
|
-
|
|
33923
|
-
|
|
33918
|
+
}) => {
|
|
33919
|
+
const response = await rustModeModuleClient.call({
|
|
33920
|
+
sessionId,
|
|
33921
|
+
projectRoot,
|
|
33922
|
+
method: "ctx_memory",
|
|
33923
|
+
body: {
|
|
33924
|
+
name: "ctx_memory",
|
|
33925
|
+
arguments: {
|
|
33926
|
+
...commandId ? { command_id: commandId } : {},
|
|
33927
|
+
action,
|
|
33928
|
+
content,
|
|
33929
|
+
category,
|
|
33930
|
+
ids,
|
|
33931
|
+
reason,
|
|
33932
|
+
memory_project: memoryProject
|
|
33933
|
+
}
|
|
33924
33934
|
}
|
|
33925
|
-
}
|
|
33926
|
-
|
|
33935
|
+
});
|
|
33936
|
+
await syncModuleMemories();
|
|
33937
|
+
return response;
|
|
33938
|
+
},
|
|
33927
33939
|
noteEvaluationAvailable: (evaluationProjectPath) => getModuleNoteEvaluationBridge(evaluationProjectPath) !== undefined,
|
|
33928
33940
|
memorySync: (sessionId) => {
|
|
33929
33941
|
rustMemorySyncRequestedSessions.add(sessionId);
|
|
@@ -33934,21 +33946,6 @@ function createMagicContextHook(deps) {
|
|
|
33934
33946
|
return;
|
|
33935
33947
|
if (getModuleNoteEvaluationBridge(bridgeProjectPath))
|
|
33936
33948
|
return;
|
|
33937
|
-
const syncModuleNotes = async () => {
|
|
33938
|
-
for (;; ) {
|
|
33939
|
-
const cursor = getMirrorCursor(db, "notes");
|
|
33940
|
-
const response = await rustModeModuleClient.mirrorPull?.({
|
|
33941
|
-
domain: "notes",
|
|
33942
|
-
cursor,
|
|
33943
|
-
limit: 1000
|
|
33944
|
-
});
|
|
33945
|
-
if (!response)
|
|
33946
|
-
throw new Error("mirror.pull is unavailable for notes");
|
|
33947
|
-
const next = applyMirrorPage({ db, page: response.page });
|
|
33948
|
-
if (!response.page.has_more || next === cursor)
|
|
33949
|
-
break;
|
|
33950
|
-
}
|
|
33951
|
-
};
|
|
33952
33949
|
registerModuleNoteEvaluationBridge(bridgeProjectPath, {
|
|
33953
33950
|
sync: syncModuleNotes,
|
|
33954
33951
|
async evaluate({ contextNoteId, sessionId, verdict }) {
|
|
@@ -34056,6 +34053,7 @@ function createMagicContextHook(deps) {
|
|
|
34056
34053
|
} : undefined,
|
|
34057
34054
|
maybeAutoEmbedSession,
|
|
34058
34055
|
transformMode: deps.config.transform_mode,
|
|
34056
|
+
promptSurface: deps.config.prompt_surface,
|
|
34059
34057
|
rustModeModuleClient,
|
|
34060
34058
|
tsAuthorityRecoveryModuleClient: authorityRecoveryModuleClient,
|
|
34061
34059
|
rustMemorySyncRequestedSessions,
|
|
@@ -34237,6 +34235,9 @@ function createMagicContextHook(deps) {
|
|
|
34237
34235
|
dreamerEnabled: dreamerRunnable,
|
|
34238
34236
|
memoryEnabled: deps.config.memory?.enabled !== false,
|
|
34239
34237
|
language: deps.config.language,
|
|
34238
|
+
promptSurface: deps.config.prompt_surface,
|
|
34239
|
+
promptSurfaceRuntime: deps.promptSurfaceRuntime,
|
|
34240
|
+
resolveModel: resolveLiveModel,
|
|
34240
34241
|
historyRefreshSessions,
|
|
34241
34242
|
systemPromptRefreshSessions,
|
|
34242
34243
|
pendingMaterializationSessions,
|
|
@@ -34377,6 +34378,7 @@ async function createSessionHooksAsync(args) {
|
|
|
34377
34378
|
compactionHandler,
|
|
34378
34379
|
liveSessionState,
|
|
34379
34380
|
rustModeModuleClient: args.rustModeModuleClient,
|
|
34381
|
+
promptSurfaceRuntime: args.promptSurfaceRuntime,
|
|
34380
34382
|
config: buildMagicContextHookConfig(pluginConfig)
|
|
34381
34383
|
});
|
|
34382
34384
|
return {
|
|
@@ -35207,8 +35209,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
35207
35209
|
const db = getDb();
|
|
35208
35210
|
if (!db)
|
|
35209
35211
|
return { ok: false, error: "db unavailable" };
|
|
35210
|
-
const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-
|
|
35211
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
35212
|
+
const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-29f4rqax.js");
|
|
35213
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-sr5g06hz.js");
|
|
35212
35214
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
35213
35215
|
const ctx = await buildManagedCtx(db);
|
|
35214
35216
|
runManagedRecomp2(ctx, sessionId).then((message) => {
|
|
@@ -35223,8 +35225,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
35223
35225
|
const db = getDb();
|
|
35224
35226
|
if (!db)
|
|
35225
35227
|
return { ok: false, error: "db unavailable" };
|
|
35226
|
-
const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-
|
|
35227
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
35228
|
+
const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-29f4rqax.js");
|
|
35229
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-sr5g06hz.js");
|
|
35228
35230
|
log(`[rpc] session-upgrade requested for session ${sessionId}`);
|
|
35229
35231
|
const ctx = await buildManagedCtx(db);
|
|
35230
35232
|
runManagedUpgrade2(ctx, sessionId).then((message) => {
|
|
@@ -35240,7 +35242,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
35240
35242
|
if (!db)
|
|
35241
35243
|
return { ok: false, error: "db unavailable" };
|
|
35242
35244
|
try {
|
|
35243
|
-
const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-
|
|
35245
|
+
const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-ev8b55a9.js");
|
|
35244
35246
|
updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
|
|
35245
35247
|
return { ok: true };
|
|
35246
35248
|
} catch (error) {
|
|
@@ -36526,7 +36528,7 @@ Mark discardable once processed: large outputs you've summarized, repeated or re
|
|
|
36526
36528
|
Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
|
|
36527
36529
|
Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
|
|
36528
36530
|
// src/tools/ctx-reduce/tools.ts
|
|
36529
|
-
import { createHash as
|
|
36531
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
36530
36532
|
import { tool as tool4 } from "@opencode-ai/plugin";
|
|
36531
36533
|
|
|
36532
36534
|
// src/features/magic-context/range-parser.ts
|
|
@@ -36596,11 +36598,11 @@ function createCtxReduceTool(deps) {
|
|
|
36596
36598
|
const stableId = `oc-${sessionId}-${callId}`;
|
|
36597
36599
|
if (Buffer.byteLength(stableId) <= 128)
|
|
36598
36600
|
return stableId;
|
|
36599
|
-
return `oc-${
|
|
36601
|
+
return `oc-${createHash15("sha256").update(stableId).digest("hex")}`;
|
|
36600
36602
|
}
|
|
36601
36603
|
fallbackCommandSequence += 1;
|
|
36602
36604
|
const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
|
|
36603
|
-
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${
|
|
36605
|
+
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash15("sha256").update(monotonicId).digest("hex")}`;
|
|
36604
36606
|
};
|
|
36605
36607
|
return tool4({
|
|
36606
36608
|
description: CTX_REDUCE_DESCRIPTION,
|
|
@@ -36996,10 +36998,23 @@ function createToolRegistry(args) {
|
|
|
36996
36998
|
rustToolBackends
|
|
36997
36999
|
}) : {}
|
|
36998
37000
|
};
|
|
36999
|
-
|
|
37001
|
+
const promptSurfaceRuntime = args.promptSurfaceRuntime ?? createPromptSurfaceRuntime({
|
|
37002
|
+
harness: "opencode",
|
|
37003
|
+
directory: ctx.directory,
|
|
37004
|
+
warn: (message) => console.warn(`[magic-context] config warning: ${message}`)
|
|
37005
|
+
});
|
|
37006
|
+
const registration = promptSurfaceRuntime.resolveRegistration(args.registrationPromptSurface ?? pluginConfig.prompt_surface);
|
|
37007
|
+
const surfacedTools = Object.fromEntries(Object.entries(allTools).map(([toolId, definition]) => [
|
|
37008
|
+
toolId,
|
|
37009
|
+
{
|
|
37010
|
+
...definition,
|
|
37011
|
+
description: registration.descriptionFor(toolId, definition.description ?? "")
|
|
37012
|
+
}
|
|
37013
|
+
]));
|
|
37014
|
+
for (const toolDefinition of Object.values(surfacedTools)) {
|
|
37000
37015
|
normalizeToolArgSchemas(toolDefinition);
|
|
37001
37016
|
}
|
|
37002
|
-
return
|
|
37017
|
+
return surfacedTools;
|
|
37003
37018
|
}
|
|
37004
37019
|
|
|
37005
37020
|
// src/shared/exit-abort-registry.ts
|
|
@@ -37027,15 +37042,15 @@ function unregisterExitAbort(controller) {
|
|
|
37027
37042
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
37028
37043
|
import {
|
|
37029
37044
|
chmodSync,
|
|
37030
|
-
mkdirSync as
|
|
37045
|
+
mkdirSync as mkdirSync2,
|
|
37031
37046
|
readdirSync,
|
|
37032
|
-
readFileSync as
|
|
37033
|
-
renameSync as
|
|
37034
|
-
rmSync as
|
|
37035
|
-
unlinkSync
|
|
37036
|
-
writeFileSync as
|
|
37047
|
+
readFileSync as readFileSync6,
|
|
37048
|
+
renameSync as renameSync3,
|
|
37049
|
+
rmSync as rmSync2,
|
|
37050
|
+
unlinkSync,
|
|
37051
|
+
writeFileSync as writeFileSync4
|
|
37037
37052
|
} from "node:fs";
|
|
37038
|
-
import { dirname as
|
|
37053
|
+
import { dirname as dirname4 } from "node:path";
|
|
37039
37054
|
var MAX_BODY_BYTES = 1048576;
|
|
37040
37055
|
var WS_AUTH_TIMEOUT_MS = 5000;
|
|
37041
37056
|
var WS_CLOSE_UNAUTHORIZED = 4401;
|
|
@@ -37109,28 +37124,28 @@ class MagicContextRpcServer {
|
|
|
37109
37124
|
this.port = server.port ?? 0;
|
|
37110
37125
|
try {
|
|
37111
37126
|
this.warnIfOtherLiveInstance();
|
|
37112
|
-
const dir =
|
|
37127
|
+
const dir = dirname4(this.portFilePath);
|
|
37113
37128
|
const enforcePrivatePermissions = shouldEnforcePrivateStoragePermissions();
|
|
37114
37129
|
if (enforcePrivatePermissions) {
|
|
37115
|
-
|
|
37130
|
+
mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
37116
37131
|
try {
|
|
37117
37132
|
chmodSync(dir, 448);
|
|
37118
37133
|
} catch {}
|
|
37119
37134
|
} else {
|
|
37120
|
-
|
|
37135
|
+
mkdirSync2(dir, { recursive: true });
|
|
37121
37136
|
}
|
|
37122
37137
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
37123
37138
|
try {
|
|
37124
|
-
|
|
37139
|
+
rmSync2(tmpPath, { force: true });
|
|
37125
37140
|
} catch {}
|
|
37126
|
-
|
|
37141
|
+
writeFileSync4(tmpPath, JSON.stringify({
|
|
37127
37142
|
port: this.port,
|
|
37128
37143
|
pid: process.pid,
|
|
37129
37144
|
started_at: this.startedAt,
|
|
37130
37145
|
token: this.token,
|
|
37131
37146
|
instance_id: this.instanceId
|
|
37132
37147
|
}), enforcePrivatePermissions ? { encoding: "utf-8", mode: 384 } : { encoding: "utf-8" });
|
|
37133
|
-
|
|
37148
|
+
renameSync3(tmpPath, this.portFilePath);
|
|
37134
37149
|
if (enforcePrivatePermissions) {
|
|
37135
37150
|
try {
|
|
37136
37151
|
chmodSync(this.portFilePath, 384);
|
|
@@ -37157,7 +37172,7 @@ class MagicContextRpcServer {
|
|
|
37157
37172
|
this.server = null;
|
|
37158
37173
|
}
|
|
37159
37174
|
try {
|
|
37160
|
-
|
|
37175
|
+
unlinkSync(this.portFilePath);
|
|
37161
37176
|
} catch {}
|
|
37162
37177
|
}
|
|
37163
37178
|
warnIfOtherLiveInstance() {
|
|
@@ -37165,7 +37180,7 @@ class MagicContextRpcServer {
|
|
|
37165
37180
|
for (const entry of readdirSync(this.portDir)) {
|
|
37166
37181
|
if (!entry.startsWith("port-") || !entry.endsWith(".json"))
|
|
37167
37182
|
continue;
|
|
37168
|
-
const record = parseRpcPortFile(
|
|
37183
|
+
const record = parseRpcPortFile(readFileSync6(`${this.portDir}/${entry}`, "utf-8"));
|
|
37169
37184
|
if (!record || record.pid === process.pid || !isPidAlive(record.pid))
|
|
37170
37185
|
continue;
|
|
37171
37186
|
log(`[rpc] another Magic Context RPC server is active for this project (pid ${record.pid}, port ${record.port}); starting separate instance on a new port`);
|
|
@@ -37305,7 +37320,13 @@ var server = async (ctx) => {
|
|
|
37305
37320
|
warn: (m) => log(`[magic-context] ${m}`),
|
|
37306
37321
|
info: (m) => log(`[magic-context] ${m}`)
|
|
37307
37322
|
});
|
|
37308
|
-
const
|
|
37323
|
+
const loadedPluginConfig = loadPluginConfigDetailed(ctx.directory);
|
|
37324
|
+
const pluginConfig = loadedPluginConfig.config;
|
|
37325
|
+
const promptSurfaceRuntime = createPromptSurfaceRuntime({
|
|
37326
|
+
harness: "opencode",
|
|
37327
|
+
directory: ctx.directory,
|
|
37328
|
+
warn: (message) => log(`[magic-context] config warning: ${message}`)
|
|
37329
|
+
});
|
|
37309
37330
|
if (configMigrationWarnings.length > 0) {
|
|
37310
37331
|
pluginConfig.configWarnings = [
|
|
37311
37332
|
...configMigrationWarnings,
|
|
@@ -37336,7 +37357,7 @@ var server = async (ctx) => {
|
|
|
37336
37357
|
`);
|
|
37337
37358
|
setTimeout(async () => {
|
|
37338
37359
|
try {
|
|
37339
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
37360
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-sr5g06hz.js");
|
|
37340
37361
|
const clientWithSessions = ctx.client;
|
|
37341
37362
|
const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
|
|
37342
37363
|
const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
|
|
@@ -37365,7 +37386,8 @@ var server = async (ctx) => {
|
|
|
37365
37386
|
ctx,
|
|
37366
37387
|
pluginConfig,
|
|
37367
37388
|
liveSessionState,
|
|
37368
|
-
rustModeModuleClient
|
|
37389
|
+
rustModeModuleClient,
|
|
37390
|
+
promptSurfaceRuntime
|
|
37369
37391
|
});
|
|
37370
37392
|
const magicContextRuntime = {
|
|
37371
37393
|
magicContext: hooks.magicContext,
|
|
@@ -37390,7 +37412,8 @@ var server = async (ctx) => {
|
|
|
37390
37412
|
ctx,
|
|
37391
37413
|
pluginConfig,
|
|
37392
37414
|
liveSessionState,
|
|
37393
|
-
rustModeModuleClient
|
|
37415
|
+
rustModeModuleClient,
|
|
37416
|
+
promptSurfaceRuntime
|
|
37394
37417
|
});
|
|
37395
37418
|
if (!reopened.magicContext)
|
|
37396
37419
|
return false;
|
|
@@ -37407,7 +37430,9 @@ var server = async (ctx) => {
|
|
|
37407
37430
|
const tools5 = createToolRegistry({
|
|
37408
37431
|
ctx,
|
|
37409
37432
|
pluginConfig,
|
|
37410
|
-
rustToolBackends: magicContextRuntime.rustToolBackends
|
|
37433
|
+
rustToolBackends: magicContextRuntime.rustToolBackends,
|
|
37434
|
+
promptSurfaceRuntime,
|
|
37435
|
+
registrationPromptSurface: loadedPluginConfig.registrationPromptSurface
|
|
37411
37436
|
});
|
|
37412
37437
|
if (pluginConfig.enabled && magicContextRuntime.magicContext) {
|
|
37413
37438
|
try {
|
|
@@ -37513,7 +37538,7 @@ var server = async (ctx) => {
|
|
|
37513
37538
|
{
|
|
37514
37539
|
const fence = getSchemaFenceRejection();
|
|
37515
37540
|
if (fence) {
|
|
37516
|
-
import("./conflict-warning-hook-
|
|
37541
|
+
import("./conflict-warning-hook-p2pmhvn7.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
|
|
37517
37542
|
}
|
|
37518
37543
|
}
|
|
37519
37544
|
if (conflictResult?.hasConflict) {
|
|
@@ -37534,7 +37559,7 @@ var server = async (ctx) => {
|
|
|
37534
37559
|
} = await import("./announcement-gms2nhya.js");
|
|
37535
37560
|
if (shouldShowAnnouncement2()) {
|
|
37536
37561
|
setTimeout(() => {
|
|
37537
|
-
import("./conflict-warning-hook-
|
|
37562
|
+
import("./conflict-warning-hook-p2pmhvn7.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
|
|
37538
37563
|
}, 8000);
|
|
37539
37564
|
}
|
|
37540
37565
|
} catch {}
|
|
@@ -37666,7 +37691,7 @@ var server = async (ctx) => {
|
|
|
37666
37691
|
log(`[magic-context] skipping hidden agent '${reg.id}' — prompt unavailable at config time (dir=${ctx.directory}); will re-register on a later complete pass`);
|
|
37667
37692
|
continue;
|
|
37668
37693
|
}
|
|
37669
|
-
agentConfig[reg.id] = buildHiddenAgentConfig(reg.prompt, reg.allowedTools, reg.maxSteps, reg.overrides, reg.id, reg.lockPermissions === true);
|
|
37694
|
+
agentConfig[reg.id] = buildHiddenAgentConfig(reg.prompt, reg.allowedTools, reg.maxSteps, reg.overrides, reg.id, reg.lockPermissions === true, reg.description);
|
|
37670
37695
|
}
|
|
37671
37696
|
config.agent = agentConfig;
|
|
37672
37697
|
} catch (error) {
|