@cortexkit/opencode-magic-context 0.35.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/dist/agents/permissions.d.ts +17 -0
- package/dist/agents/permissions.d.ts.map +1 -1
- package/dist/{announcement-gms2nhya.js → announcement-6c1g4es4.js} +2 -2
- package/dist/config/schema/magic-context.d.ts +10 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-p2pmhvn7.js → conflict-warning-hook-dw9fs934.js} +4 -4
- package/dist/{derive-budgets-9crp0cvd.js → derive-budgets-88mxk2w1.js} +3 -3
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +2 -0
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +1 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/condition-compiler.d.ts +37 -0
- package/dist/features/magic-context/smart-notes/condition-compiler.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/storage.d.ts +3 -3
- package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +13 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +3 -0
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +15 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +6 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +9 -0
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts +10 -0
- package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +7 -2
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/{index-8aaadh98.js → index-37rt2bka.js} +2 -2
- package/dist/{index-fkyamz2w.js → index-3nfgbsp4.js} +99 -56
- package/dist/{index-w0nygb4p.js → index-3tnkymva.js} +2 -2
- package/dist/{index-k1esqfwk.js → index-f1tnb3vm.js} +1 -1
- package/dist/{index-kvrcg31b.js → index-mmrhhk9a.js} +8 -1
- package/dist/{index-h5zjfesc.js → index-nsx2n9eg.js} +3 -3
- package/dist/{index-dmr999a2.js → index-qf20mv7e.js} +1 -1
- package/dist/{index-73xz0247.js → index-tsgs7td8.js} +1 -1
- package/dist/{index-ry8rh8cv.js → index-wgvxkqpx.js} +5 -4
- package/dist/{index-dpdnjawy.js → index-z8v31d85.js} +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +781 -116
- package/dist/plugin/dream-timer.d.ts +1 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts +5 -5
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-29f4rqax.js → recomp-orchestrator-7wbbvf87.js} +7 -7
- package/dist/{safe-notification-target-q9jk5n44.js → safe-notification-target-c11fdda2.js} +3 -3
- package/dist/{send-session-notification-sr5g06hz.js → send-session-notification-bgtf4853.js} +4 -4
- package/dist/shared/data-path.d.ts +27 -0
- package/dist/shared/data-path.d.ts.map +1 -1
- package/dist/shared/harness-provider-map.d.ts +23 -20
- package/dist/shared/harness-provider-map.d.ts.map +1 -1
- package/dist/shared/prompt-surface-runtime.d.ts +15 -2
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/{storage-meta-session-ev8b55a9.js → storage-meta-session-kh5egr11.js} +4 -4
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agents/permissions.ts +87 -0
- package/src/config/compaction-accessor-guard.test.ts +9 -4
- package/src/config/schema/magic-context.test.ts +2 -0
- package/src/config/schema/magic-context.ts +15 -0
- package/src/shared/data-path.test.ts +65 -9
- package/src/shared/data-path.ts +66 -1
- package/src/shared/harness-provider-map.test.ts +42 -1
- package/src/shared/harness-provider-map.ts +48 -26
- package/src/shared/prompt-surface-runtime.ts +13 -5
package/dist/index.js
CHANGED
|
@@ -25,6 +25,14 @@ import {
|
|
|
25
25
|
GLOBAL_USER_PROFILE_PROJECT_PATH,
|
|
26
26
|
HISTORIAN_EDITOR_SYSTEM_PROMPT,
|
|
27
27
|
LATEST_SUPPORTED_VERSION,
|
|
28
|
+
LKG_SNAPSHOT_ARRAY,
|
|
29
|
+
LKG_SNAPSHOT_BOOLEAN,
|
|
30
|
+
LKG_SNAPSHOT_KEY,
|
|
31
|
+
LKG_SNAPSHOT_NULL,
|
|
32
|
+
LKG_SNAPSHOT_NUMBER,
|
|
33
|
+
LKG_SNAPSHOT_OBJECT,
|
|
34
|
+
LKG_SNAPSHOT_STRING,
|
|
35
|
+
LKG_SNAPSHOT_UNDEFINED,
|
|
28
36
|
MARKER_SUMMARY_TEXT,
|
|
29
37
|
MAX_EXECUTE_THRESHOLD,
|
|
30
38
|
MagicContextConfigSchema,
|
|
@@ -230,6 +238,7 @@ import {
|
|
|
230
238
|
isPidAlive,
|
|
231
239
|
isProviderOverflowReconfirmed,
|
|
232
240
|
lkgContentDigest,
|
|
241
|
+
lkgContentDigestFromFields,
|
|
233
242
|
loadCompartmentChunkEmbeddingsForSearch,
|
|
234
243
|
loadPersistedUsage,
|
|
235
244
|
loadProjectCommitEmbeddings,
|
|
@@ -382,7 +391,7 @@ import {
|
|
|
382
391
|
upsertCommits,
|
|
383
392
|
verificationFileExists,
|
|
384
393
|
withContentLanguageDirective
|
|
385
|
-
} from "./index-
|
|
394
|
+
} from "./index-3nfgbsp4.js";
|
|
386
395
|
import {
|
|
387
396
|
deriveHistorianChunkTokens,
|
|
388
397
|
deriveTriggerBudget,
|
|
@@ -394,7 +403,7 @@ import {
|
|
|
394
403
|
setOutputReserveConfig,
|
|
395
404
|
setStoragePrivatePermissionEnforcement,
|
|
396
405
|
shouldEnforcePrivateStoragePermissions
|
|
397
|
-
} from "./index-
|
|
406
|
+
} from "./index-wgvxkqpx.js";
|
|
398
407
|
import {
|
|
399
408
|
modelBodyField,
|
|
400
409
|
resolveFallbackChain
|
|
@@ -406,7 +415,7 @@ import {
|
|
|
406
415
|
getErrorMessage,
|
|
407
416
|
sendIgnoredMessage,
|
|
408
417
|
sendUserPrompt
|
|
409
|
-
} from "./index-
|
|
418
|
+
} from "./index-nsx2n9eg.js";
|
|
410
419
|
import {
|
|
411
420
|
ToolMutationBatch,
|
|
412
421
|
advanceToolReclaimWatermark,
|
|
@@ -463,7 +472,7 @@ import {
|
|
|
463
472
|
textMentionsRecentCommit,
|
|
464
473
|
updateSessionMeta,
|
|
465
474
|
withRawSessionMessageCache
|
|
466
|
-
} from "./index-
|
|
475
|
+
} from "./index-z8v31d85.js";
|
|
467
476
|
import {
|
|
468
477
|
Database,
|
|
469
478
|
closeQuietly,
|
|
@@ -472,12 +481,12 @@ import {
|
|
|
472
481
|
isMidTurn,
|
|
473
482
|
openCodeDbExists,
|
|
474
483
|
withReadOnlySessionDb
|
|
475
|
-
} from "./index-
|
|
484
|
+
} from "./index-3tnkymva.js";
|
|
476
485
|
import {
|
|
477
486
|
cleanupConflictWarnings,
|
|
478
487
|
detectConflicts,
|
|
479
488
|
sendConflictWarning
|
|
480
|
-
} from "./index-
|
|
489
|
+
} from "./index-37rt2bka.js";
|
|
481
490
|
import {
|
|
482
491
|
detectConfigFile,
|
|
483
492
|
parseJsonc,
|
|
@@ -491,7 +500,7 @@ import {
|
|
|
491
500
|
isValidSemver,
|
|
492
501
|
markAnnouncementSeen,
|
|
493
502
|
shouldShowAnnouncement
|
|
494
|
-
} from "./index-
|
|
503
|
+
} from "./index-qf20mv7e.js";
|
|
495
504
|
import {
|
|
496
505
|
acknowledgeNotifications,
|
|
497
506
|
drainNotifications,
|
|
@@ -499,17 +508,17 @@ import {
|
|
|
499
508
|
pushNotification,
|
|
500
509
|
registerNotificationSink
|
|
501
510
|
} from "./index-d62ypazr.js";
|
|
502
|
-
import"./index-
|
|
511
|
+
import"./index-tsgs7td8.js";
|
|
503
512
|
import {
|
|
504
513
|
log,
|
|
505
514
|
sessionLog
|
|
506
|
-
} from "./index-
|
|
515
|
+
} from "./index-f1tnb3vm.js";
|
|
507
516
|
import {
|
|
508
517
|
getDataDir,
|
|
509
518
|
getHarness,
|
|
510
519
|
getMagicContextStorageDir,
|
|
511
520
|
getOpenCodeStorageDir
|
|
512
|
-
} from "./index-
|
|
521
|
+
} from "./index-mmrhhk9a.js";
|
|
513
522
|
import {
|
|
514
523
|
resolvePromptContext
|
|
515
524
|
} from "./index-szf8w1p5.js";
|
|
@@ -8370,6 +8379,49 @@ function buildAllowOnlyPermission(allowedTools, agentLabel) {
|
|
|
8370
8379
|
}
|
|
8371
8380
|
return permission;
|
|
8372
8381
|
}
|
|
8382
|
+
function isPermissionAction(value) {
|
|
8383
|
+
return value === "ask" || value === "allow" || value === "deny";
|
|
8384
|
+
}
|
|
8385
|
+
function isPermissionMap(value) {
|
|
8386
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8387
|
+
}
|
|
8388
|
+
function denyTaskRoutingToAgents(permission, internalAgentIds) {
|
|
8389
|
+
const configured = isPermissionAction(permission) ? { "*": permission } : isPermissionMap(permission) ? permission : {};
|
|
8390
|
+
const { task, ...otherPermissions } = configured;
|
|
8391
|
+
const configuredTask = isPermissionAction(task) ? { "*": task } : isPermissionMap(task) ? task : {};
|
|
8392
|
+
const internalAgentIdSet = new Set(internalAgentIds);
|
|
8393
|
+
const retainedTask = Object.fromEntries(Object.entries(configuredTask).filter(([agentId]) => !internalAgentIdSet.has(agentId)));
|
|
8394
|
+
return {
|
|
8395
|
+
...otherPermissions,
|
|
8396
|
+
task: {
|
|
8397
|
+
...retainedTask,
|
|
8398
|
+
...Object.fromEntries(internalAgentIds.map((agentId) => [agentId, "deny"]))
|
|
8399
|
+
}
|
|
8400
|
+
};
|
|
8401
|
+
}
|
|
8402
|
+
var BUILTIN_TASK_CALLER_IDS = ["build", "plan"];
|
|
8403
|
+
function isTaskRoutingCaller(agentId, config) {
|
|
8404
|
+
const mode = config.mode;
|
|
8405
|
+
if (mode === "primary")
|
|
8406
|
+
return true;
|
|
8407
|
+
if (mode === "subagent" || mode === "all")
|
|
8408
|
+
return false;
|
|
8409
|
+
return agentId === "build" || agentId === "plan";
|
|
8410
|
+
}
|
|
8411
|
+
function denyTaskRoutingToCallerAgents(agentConfigs, internalAgentIds) {
|
|
8412
|
+
const result = { ...agentConfigs };
|
|
8413
|
+
const candidateIds = new Set([...BUILTIN_TASK_CALLER_IDS, ...Object.keys(agentConfigs)]);
|
|
8414
|
+
for (const agentId of candidateIds) {
|
|
8415
|
+
const agentConfig = agentConfigs[agentId] ?? {};
|
|
8416
|
+
if (!isTaskRoutingCaller(agentId, agentConfig))
|
|
8417
|
+
continue;
|
|
8418
|
+
result[agentId] = {
|
|
8419
|
+
...agentConfig,
|
|
8420
|
+
permission: denyTaskRoutingToAgents(agentConfig.permission, internalAgentIds)
|
|
8421
|
+
};
|
|
8422
|
+
}
|
|
8423
|
+
return result;
|
|
8424
|
+
}
|
|
8373
8425
|
function applyDisallowedTools(defaults, disallowed) {
|
|
8374
8426
|
if (disallowed.includes("*"))
|
|
8375
8427
|
return [];
|
|
@@ -11523,6 +11575,7 @@ var CONNECT_BACKOFF_INITIAL_MS = 1000;
|
|
|
11523
11575
|
var CONNECT_BACKOFF_MAX_MS = 30000;
|
|
11524
11576
|
var HANDSHAKE_TIMEOUT_MS = 2000;
|
|
11525
11577
|
var MODULE_SEND_TIMEOUT_MS = 15000;
|
|
11578
|
+
var TRANSFORM_SEND_TIMEOUT_MS = 5000;
|
|
11526
11579
|
var SERIAL_LANE_MAX_WAITERS = 16;
|
|
11527
11580
|
var SERIAL_LANE_MIN_REMAINING_MS = 25;
|
|
11528
11581
|
var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
|
|
@@ -11558,15 +11611,21 @@ function isConnectionFailure(error) {
|
|
|
11558
11611
|
if (error instanceof SocketClosedError || error instanceof SocketTimeoutError || error instanceof StaleRouteHandleError || isConsumerReconnectTransient(error) || isStaleOrDeadRouteFailure(error)) {
|
|
11559
11612
|
return true;
|
|
11560
11613
|
}
|
|
11561
|
-
return errorChainSome(error, (current) =>
|
|
11562
|
-
"
|
|
11563
|
-
"
|
|
11564
|
-
|
|
11565
|
-
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
11614
|
+
return errorChainSome(error, (current) => {
|
|
11615
|
+
const code = typeof current.code === "string" ? current.code : "";
|
|
11616
|
+
const message = typeof current.message === "string" ? current.message : "";
|
|
11617
|
+
return [
|
|
11618
|
+
"ENOENT",
|
|
11619
|
+
"ECONNREFUSED",
|
|
11620
|
+
"ECONNRESET",
|
|
11621
|
+
"EPIPE",
|
|
11622
|
+
"ETIMEDOUT",
|
|
11623
|
+
"request_deadline",
|
|
11624
|
+
"deadline_exceeded_no_drop_observed",
|
|
11625
|
+
"connection_dropped",
|
|
11626
|
+
"SUBC_CONNECTION_BACKOFF"
|
|
11627
|
+
].includes(code) || /\bclient closed\b|\bconnection closed\b|\bclosed the connection\b/i.test(message);
|
|
11628
|
+
});
|
|
11570
11629
|
}
|
|
11571
11630
|
|
|
11572
11631
|
class SubcModuleTransport {
|
|
@@ -11584,7 +11643,20 @@ class SubcModuleTransport {
|
|
|
11584
11643
|
authorityBindRoot = "";
|
|
11585
11644
|
backoffMs = CONNECT_BACKOFF_INITIAL_MS;
|
|
11586
11645
|
connectionGeneration = 0;
|
|
11646
|
+
stateSyncCapabilityCache = null;
|
|
11647
|
+
getCachedStateSyncCapabilities() {
|
|
11648
|
+
const cached = this.stateSyncCapabilityCache;
|
|
11649
|
+
if (!cached || cached.generation !== this.connectionGeneration)
|
|
11650
|
+
return;
|
|
11651
|
+
return cached.capabilities;
|
|
11652
|
+
}
|
|
11653
|
+
invalidateStateSyncCapabilities() {
|
|
11654
|
+
this.stateSyncCapabilityCache = null;
|
|
11655
|
+
}
|
|
11587
11656
|
async stateSyncCapabilities(args) {
|
|
11657
|
+
const cached = this.getCachedStateSyncCapabilities();
|
|
11658
|
+
if (cached)
|
|
11659
|
+
return cached;
|
|
11588
11660
|
const response = await this.call({
|
|
11589
11661
|
sessionId: args.sessionId,
|
|
11590
11662
|
projectRoot: args.projectRoot,
|
|
@@ -11594,7 +11666,9 @@ class SubcModuleTransport {
|
|
|
11594
11666
|
const raw = isRecord(response) ? response : {};
|
|
11595
11667
|
const value = isRecord(raw.result) ? raw.result : raw;
|
|
11596
11668
|
const epochs = isRecord(value.epochs) ? value.epochs : {};
|
|
11597
|
-
|
|
11669
|
+
const capabilities = { state_sync_deltas: epochs.state_sync_deltas === true };
|
|
11670
|
+
this.stateSyncCapabilityCache = { generation: this.connectionGeneration, capabilities };
|
|
11671
|
+
return capabilities;
|
|
11598
11672
|
}
|
|
11599
11673
|
constructor(connectionFile, moduleId = DEFAULT_MODULE_ID, requestTimeoutMs = MODULE_SEND_TIMEOUT_MS, routeSessionPrefix = "") {
|
|
11600
11674
|
this.connectionFile = connectionFile ?? getDefaultConnectionFile();
|
|
@@ -11602,11 +11676,31 @@ class SubcModuleTransport {
|
|
|
11602
11676
|
this.requestTimeoutMs = requestTimeoutMs;
|
|
11603
11677
|
this.routeSessionPrefix = routeSessionPrefix;
|
|
11604
11678
|
}
|
|
11605
|
-
|
|
11606
|
-
const error = new Error(
|
|
11679
|
+
deadlineError(detail) {
|
|
11680
|
+
const error = new Error(`module transport deadline expired ${detail}`);
|
|
11607
11681
|
error.code = "ETIMEDOUT";
|
|
11608
11682
|
return error;
|
|
11609
11683
|
}
|
|
11684
|
+
laneTimeoutError() {
|
|
11685
|
+
return this.deadlineError("while queued");
|
|
11686
|
+
}
|
|
11687
|
+
async beforeDeadline(operation, deadlineMs, detail) {
|
|
11688
|
+
const remainingMs = deadlineMs - Date.now();
|
|
11689
|
+
if (remainingMs <= 0)
|
|
11690
|
+
throw this.deadlineError(detail);
|
|
11691
|
+
let timer;
|
|
11692
|
+
try {
|
|
11693
|
+
return await Promise.race([
|
|
11694
|
+
operation,
|
|
11695
|
+
new Promise((_resolve, reject) => {
|
|
11696
|
+
timer = setTimeout(() => reject(this.deadlineError(detail)), remainingMs);
|
|
11697
|
+
})
|
|
11698
|
+
]);
|
|
11699
|
+
} finally {
|
|
11700
|
+
if (timer)
|
|
11701
|
+
clearTimeout(timer);
|
|
11702
|
+
}
|
|
11703
|
+
}
|
|
11610
11704
|
laneRelease() {
|
|
11611
11705
|
let released = false;
|
|
11612
11706
|
return () => {
|
|
@@ -11684,8 +11778,9 @@ class SubcModuleTransport {
|
|
|
11684
11778
|
});
|
|
11685
11779
|
}
|
|
11686
11780
|
async call(args) {
|
|
11687
|
-
const
|
|
11688
|
-
const
|
|
11781
|
+
const attemptTimeoutMs = args.timeoutMs ?? (args.method === "transform" ? Math.min(this.requestTimeoutMs, TRANSFORM_SEND_TIMEOUT_MS) : this.requestTimeoutMs);
|
|
11782
|
+
const laneDeadlineMs = Date.now() + attemptTimeoutMs;
|
|
11783
|
+
const releaseLane = await this.acquireCorrectnessLane(args.sessionId, args.signal, laneDeadlineMs);
|
|
11689
11784
|
const onAbort = () => this.invalidateConnection();
|
|
11690
11785
|
args.signal?.addEventListener("abort", onAbort, { once: true });
|
|
11691
11786
|
try {
|
|
@@ -11695,21 +11790,18 @@ class SubcModuleTransport {
|
|
|
11695
11790
|
if (args.signal?.aborted) {
|
|
11696
11791
|
throw args.signal.reason ?? new Error("module transport call aborted");
|
|
11697
11792
|
}
|
|
11698
|
-
const
|
|
11699
|
-
|
|
11700
|
-
throw this.laneTimeoutError();
|
|
11701
|
-
ensuredRoute = await this.ensureRoute(args.sessionId, args.projectRoot);
|
|
11793
|
+
const attemptDeadlineMs = Date.now() + attemptTimeoutMs;
|
|
11794
|
+
ensuredRoute = await this.ensureRoute(args.sessionId, args.projectRoot, attemptDeadlineMs);
|
|
11702
11795
|
if (args.signal?.aborted) {
|
|
11703
11796
|
throw args.signal.reason ?? new Error("module transport call aborted");
|
|
11704
11797
|
}
|
|
11705
|
-
return await ensuredRoute.client.request(ensuredRoute.route, args.body, {
|
|
11798
|
+
return await this.beforeDeadline(ensuredRoute.client.request(ensuredRoute.route, args.body, {
|
|
11706
11799
|
priority: Priority.Background,
|
|
11707
11800
|
admissionClass: AdmissionClass.Normal,
|
|
11708
|
-
timeoutMs: Math.max(1,
|
|
11709
|
-
});
|
|
11801
|
+
timeoutMs: Math.max(1, attemptDeadlineMs - Date.now())
|
|
11802
|
+
}), attemptDeadlineMs, "waiting for the module response");
|
|
11710
11803
|
} catch (error) {
|
|
11711
|
-
|
|
11712
|
-
if (staleOrDeadRoute) {
|
|
11804
|
+
if (isConnectionFailure(error)) {
|
|
11713
11805
|
if (ensuredRoute) {
|
|
11714
11806
|
this.dropRoute(ensuredRoute.routeKey, ensuredRoute.route);
|
|
11715
11807
|
this.invalidateConnection(ensuredRoute.client);
|
|
@@ -11718,8 +11810,6 @@ class SubcModuleTransport {
|
|
|
11718
11810
|
}
|
|
11719
11811
|
if (attempt === 0 && !args.signal?.aborted)
|
|
11720
11812
|
continue;
|
|
11721
|
-
} else if (isConnectionFailure(error)) {
|
|
11722
|
-
this.invalidateConnection(ensuredRoute?.client);
|
|
11723
11813
|
}
|
|
11724
11814
|
throw error;
|
|
11725
11815
|
}
|
|
@@ -11821,7 +11911,7 @@ class SubcModuleTransport {
|
|
|
11821
11911
|
this.invalidateConnection(client);
|
|
11822
11912
|
}
|
|
11823
11913
|
}
|
|
11824
|
-
async ensureRoute(sessionId, rawProjectRoot) {
|
|
11914
|
+
async ensureRoute(sessionId, rawProjectRoot, deadlineMs = Date.now() + this.requestTimeoutMs) {
|
|
11825
11915
|
const projectRoot = this.canonicalRoot(rawProjectRoot);
|
|
11826
11916
|
const routeKey = `${sessionId}\x00${projectRoot}`;
|
|
11827
11917
|
const client = await this.ensureConnected();
|
|
@@ -11838,7 +11928,7 @@ class SubcModuleTransport {
|
|
|
11838
11928
|
harness: getHarness(),
|
|
11839
11929
|
session: `${this.routeSessionPrefix}${sessionId}`
|
|
11840
11930
|
};
|
|
11841
|
-
const route = await client.routeOpen(target, identity);
|
|
11931
|
+
const route = await this.beforeDeadline(client.routeOpen(target, identity), deadlineMs, "opening the module route");
|
|
11842
11932
|
if (this.client !== client || generation !== this.connectionGeneration) {
|
|
11843
11933
|
await client.closeRoute(route).catch(() => {
|
|
11844
11934
|
return;
|
|
@@ -11915,6 +12005,7 @@ class SubcModuleTransport {
|
|
|
11915
12005
|
if (client && this.client && client !== this.client)
|
|
11916
12006
|
return;
|
|
11917
12007
|
this.connectionGeneration += 1;
|
|
12008
|
+
this.invalidateStateSyncCapabilities();
|
|
11918
12009
|
this.client = null;
|
|
11919
12010
|
this.routes.clear();
|
|
11920
12011
|
client?.close();
|
|
@@ -15068,16 +15159,16 @@ function claimExpectedState(db, expected) {
|
|
|
15068
15159
|
WHERE id = ? AND type = 'smart' AND status = 'pending'
|
|
15069
15160
|
AND content = ? AND surface_condition IS ? AND updated_at = ?${statusClause}`).run(...params).changes > 0;
|
|
15070
15161
|
}
|
|
15071
|
-
function getDueCompiledSmartNoteChecks(db, projectPath, now, limit) {
|
|
15072
|
-
return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && (note.checkQuarantinedUntil === null || note.checkQuarantinedUntil <= now) && (note.checkNextDueAt === null || note.checkNextDueAt <= now)).sort((a, b) => (a.checkNextDueAt ?? 0) - (b.checkNextDueAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
15162
|
+
function getDueCompiledSmartNoteChecks(db, projectPath, now, limit, retinaHandoff = false) {
|
|
15163
|
+
return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && (note.checkQuarantinedUntil === null || note.checkQuarantinedUntil <= now) && (note.checkNextDueAt === null || note.checkNextDueAt <= now)).sort((a, b) => (a.checkNextDueAt ?? 0) - (b.checkNextDueAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
15073
15164
|
}
|
|
15074
|
-
function getSmartNotesNeedingCompilation(db, projectPath, now, limit) {
|
|
15075
|
-
return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => (note.checkNextDueAt === null || note.checkNextDueAt <= now) && (note.checkStatus === "uncompiled" || note.checkStatus === "failing" || note.compiledCheck === null || note.policyVersion !== SMART_NOTE_CHECK_POLICY_VERSION)).sort((a, b) => a.createdAt - b.createdAt || a.id - b.id).slice(0, Math.max(1, limit));
|
|
15165
|
+
function getSmartNotesNeedingCompilation(db, projectPath, now, limit, retinaHandoff = false) {
|
|
15166
|
+
return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => (note.checkNextDueAt === null || note.checkNextDueAt <= now) && (note.checkStatus === "uncompiled" || note.checkStatus === "failing" || note.compiledCheck === null || note.policyVersion !== SMART_NOTE_CHECK_POLICY_VERSION)).sort((a, b) => a.createdAt - b.createdAt || a.id - b.id).slice(0, Math.max(1, limit));
|
|
15076
15167
|
}
|
|
15077
|
-
function getStaleCompiledSmartNotes(db, projectPath, now, limit) {
|
|
15168
|
+
function getStaleCompiledSmartNotes(db, projectPath, now, limit, retinaHandoff = false) {
|
|
15078
15169
|
const staleBefore = now - SMART_NOTE_CHECK_MAX_STALENESS_MS;
|
|
15079
15170
|
const livenessBefore = now - SMART_NOTE_CHECK_LIVENESS_RECHECK_MS;
|
|
15080
|
-
return getPendingSmartNotes(db, projectPath).map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && note.checkFalseSinceAt !== null && note.checkFalseSinceAt <= staleBefore && (note.checkLastLivenessAt === null || note.checkLastLivenessAt <= livenessBefore)).sort((a, b) => (a.checkFalseSinceAt ?? 0) - (b.checkFalseSinceAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
15171
|
+
return getPendingSmartNotes(db, projectPath).filter((note) => !retinaHandoff || note.compileStatus !== "compiled").map(toSmartNote).filter((note) => note.checkStatus === "compiled" && note.compiledCheck !== null && note.policyVersion === SMART_NOTE_CHECK_POLICY_VERSION && note.checkFalseSinceAt !== null && note.checkFalseSinceAt <= staleBefore && (note.checkLastLivenessAt === null || note.checkLastLivenessAt <= livenessBefore)).sort((a, b) => (a.checkFalseSinceAt ?? 0) - (b.checkFalseSinceAt ?? 0) || a.id - b.id).slice(0, Math.max(1, limit));
|
|
15081
15172
|
}
|
|
15082
15173
|
function storeCompiledSmartNoteCheck(db, args) {
|
|
15083
15174
|
db.prepare(`UPDATE notes
|
|
@@ -15173,7 +15264,7 @@ var MAX_FAILURES_BEFORE_REAUTHOR = 3;
|
|
|
15173
15264
|
async function runDueCompiledSmartNoteChecks(args) {
|
|
15174
15265
|
const startedAt = Date.now();
|
|
15175
15266
|
const now = args.now ?? startedAt;
|
|
15176
|
-
const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS);
|
|
15267
|
+
const due = getDueCompiledSmartNoteChecks(args.db, args.projectIdentity, now, args.maxChecks ?? DEFAULT_MAX_CHECKS, args.retinaHandoff);
|
|
15177
15268
|
let ran = 0;
|
|
15178
15269
|
let surfaced = 0;
|
|
15179
15270
|
let failed = 0;
|
|
@@ -15303,7 +15394,8 @@ async function evaluateSmartNotes(args) {
|
|
|
15303
15394
|
const projectRoot = args.sessionDirectory ?? args.projectIdentity;
|
|
15304
15395
|
const moduleBridge = getModuleNoteEvaluationBridge(args.projectIdentity);
|
|
15305
15396
|
await moduleBridge?.sync();
|
|
15306
|
-
const
|
|
15397
|
+
const pendingNotes = () => getPendingSmartNotes(args.db, args.projectIdentity).filter((note) => !args.retinaHandoff || note.compileStatus !== "compiled");
|
|
15398
|
+
const pendingAtStart = pendingNotes().length;
|
|
15307
15399
|
if (pendingAtStart === 0) {
|
|
15308
15400
|
log("[dreamer] smart notes: no pending notes");
|
|
15309
15401
|
return { surfaced: 0, pending: 0, ran: false };
|
|
@@ -15327,7 +15419,7 @@ async function evaluateSmartNotes(args) {
|
|
|
15327
15419
|
let didWork = false;
|
|
15328
15420
|
try {
|
|
15329
15421
|
if (moduleBridge) {
|
|
15330
|
-
const candidates2 =
|
|
15422
|
+
const candidates2 = pendingNotes().slice(0, MAX_COMPILE_PER_RUN);
|
|
15331
15423
|
for (const note of candidates2) {
|
|
15332
15424
|
if (Date.now() >= args.deadline)
|
|
15333
15425
|
break;
|
|
@@ -15348,7 +15440,7 @@ async function evaluateSmartNotes(args) {
|
|
|
15348
15440
|
surfaced += 1;
|
|
15349
15441
|
}
|
|
15350
15442
|
await moduleBridge.sync();
|
|
15351
|
-
const pending2 =
|
|
15443
|
+
const pending2 = pendingNotes().length;
|
|
15352
15444
|
return { surfaced, pending: pending2, ran: didWork };
|
|
15353
15445
|
}
|
|
15354
15446
|
const dueRun = await runDueCompiledSmartNoteChecks({
|
|
@@ -15358,11 +15450,12 @@ async function evaluateSmartNotes(args) {
|
|
|
15358
15450
|
maxChecks: 10,
|
|
15359
15451
|
sweepBudgetMs: 1e4,
|
|
15360
15452
|
leaseHeld,
|
|
15361
|
-
signal: leaseAbortController.signal
|
|
15453
|
+
signal: leaseAbortController.signal,
|
|
15454
|
+
retinaHandoff: args.retinaHandoff
|
|
15362
15455
|
});
|
|
15363
15456
|
surfaced += dueRun.surfaced;
|
|
15364
15457
|
didWork ||= dueRun.ran > 0;
|
|
15365
|
-
const candidates = getSmartNotesNeedingCompilation(args.db, args.projectIdentity, Date.now(), MAX_COMPILE_PER_RUN);
|
|
15458
|
+
const candidates = getSmartNotesNeedingCompilation(args.db, args.projectIdentity, Date.now(), MAX_COMPILE_PER_RUN, args.retinaHandoff);
|
|
15366
15459
|
for (const note of candidates) {
|
|
15367
15460
|
if (Date.now() >= args.deadline)
|
|
15368
15461
|
break;
|
|
@@ -15372,7 +15465,7 @@ async function evaluateSmartNotes(args) {
|
|
|
15372
15465
|
if (compiled)
|
|
15373
15466
|
surfaced += 1;
|
|
15374
15467
|
}
|
|
15375
|
-
const stale = getStaleCompiledSmartNotes(args.db, args.projectIdentity, Date.now(), MAX_FALLBACK_PER_RUN);
|
|
15468
|
+
const stale = getStaleCompiledSmartNotes(args.db, args.projectIdentity, Date.now(), MAX_FALLBACK_PER_RUN, args.retinaHandoff);
|
|
15376
15469
|
for (const note of stale) {
|
|
15377
15470
|
if (Date.now() >= args.deadline)
|
|
15378
15471
|
break;
|
|
@@ -15382,7 +15475,7 @@ async function evaluateSmartNotes(args) {
|
|
|
15382
15475
|
if (met)
|
|
15383
15476
|
surfaced += 1;
|
|
15384
15477
|
}
|
|
15385
|
-
const fallbackNotes =
|
|
15478
|
+
const fallbackNotes = pendingNotes().filter((note) => note.checkStatus === "fallback").slice(0, MAX_FALLBACK_PER_RUN);
|
|
15386
15479
|
for (const note of fallbackNotes) {
|
|
15387
15480
|
if (Date.now() >= args.deadline)
|
|
15388
15481
|
break;
|
|
@@ -17917,7 +18010,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
17917
18010
|
leaseKey,
|
|
17918
18011
|
deadline,
|
|
17919
18012
|
model: config.model,
|
|
17920
|
-
fallbackModels: config.fallbackModels
|
|
18013
|
+
fallbackModels: config.fallbackModels,
|
|
18014
|
+
retinaHandoff: deps.retinaHandoff
|
|
17921
18015
|
});
|
|
17922
18016
|
recordRun("completed", null, {
|
|
17923
18017
|
smartNotesSurfaced: result.surfaced,
|
|
@@ -19133,6 +19227,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
19133
19227
|
dreamerModel: dreamerConfig.model,
|
|
19134
19228
|
mural: reg.mural,
|
|
19135
19229
|
memoryInjectionBudgetTokens: reg.memoryInjectionBudgetTokens,
|
|
19230
|
+
retinaHandoff: reg.retinaHandoff,
|
|
19136
19231
|
transformMode: reg.transformMode,
|
|
19137
19232
|
moduleClient: reg.moduleClient,
|
|
19138
19233
|
onProgress: (progress, completedTask) => reg.onDreamerProgress?.(progress, completedTask)
|
|
@@ -19176,7 +19271,8 @@ async function runCompiledSmartNoteSweep(reg, db) {
|
|
|
19176
19271
|
const result = await runDueCompiledSmartNoteChecks({
|
|
19177
19272
|
db,
|
|
19178
19273
|
projectIdentity: reg.projectIdentity,
|
|
19179
|
-
projectRoot: reg.directory
|
|
19274
|
+
projectRoot: reg.directory,
|
|
19275
|
+
retinaHandoff: reg.retinaHandoff
|
|
19180
19276
|
});
|
|
19181
19277
|
if (result.ran > 0) {
|
|
19182
19278
|
log(`[dreamer] compiled smart-note sweep ${reg.projectIdentity}: ran=${result.ran} surfaced=${result.surfaced} logic_failed=${result.failed} network_failed=${result.networkFailed}`);
|
|
@@ -25051,7 +25147,7 @@ function readAuthoritySeqMismatch(error) {
|
|
|
25051
25147
|
async function syncModuleState(args) {
|
|
25052
25148
|
let force = args.force;
|
|
25053
25149
|
const adoption = args.options?.authoritySeqAdoption ?? { used: false };
|
|
25054
|
-
let stateSyncDeltas = args.options?.stateSyncDeltas;
|
|
25150
|
+
let stateSyncDeltas = args.options?.stateSyncDeltas ?? args.client.getCachedStateSyncCapabilities?.()?.state_sync_deltas;
|
|
25055
25151
|
if (stateSyncDeltas === undefined && args.client.stateSyncCapabilities) {
|
|
25056
25152
|
try {
|
|
25057
25153
|
stateSyncDeltas = (await args.client.stateSyncCapabilities({
|
|
@@ -25110,6 +25206,20 @@ async function syncModuleState(args) {
|
|
|
25110
25206
|
}
|
|
25111
25207
|
}
|
|
25112
25208
|
|
|
25209
|
+
// src/hooks/magic-context/raw-fallback-context-limit.ts
|
|
25210
|
+
class RawFallbackContextLimitError extends Error {
|
|
25211
|
+
estimatedTokens;
|
|
25212
|
+
contextLimitTokens;
|
|
25213
|
+
code = "RAW_FALLBACK_CONTEXT_LIMIT";
|
|
25214
|
+
recoverable = true;
|
|
25215
|
+
constructor(estimatedTokens, contextLimitTokens, options) {
|
|
25216
|
+
super(`Magic Context could not safely serve the raw prompt: the best local estimate is ${estimatedTokens.toLocaleString()} tokens, above the known ${contextLimitTokens.toLocaleString()}-token context limit. Retry the turn so the module can reconnect.`, options);
|
|
25217
|
+
this.estimatedTokens = estimatedTokens;
|
|
25218
|
+
this.contextLimitTokens = contextLimitTokens;
|
|
25219
|
+
this.name = "RawFallbackContextLimitError";
|
|
25220
|
+
}
|
|
25221
|
+
}
|
|
25222
|
+
|
|
25113
25223
|
// src/hooks/magic-context/todo-view.ts
|
|
25114
25224
|
import { createHash as createHash11 } from "node:crypto";
|
|
25115
25225
|
var TODO_STATUS_PENDING = "pending";
|
|
@@ -29321,34 +29431,26 @@ function updateFnv1a32(hash, value) {
|
|
|
29321
29431
|
}
|
|
29322
29432
|
return next;
|
|
29323
29433
|
}
|
|
29324
|
-
var SNAPSHOT_ARRAY = Symbol("array");
|
|
29325
|
-
var SNAPSHOT_OBJECT = Symbol("object");
|
|
29326
|
-
var SNAPSHOT_KEY = Symbol("key");
|
|
29327
|
-
var SNAPSHOT_STRING = Symbol("string");
|
|
29328
|
-
var SNAPSHOT_NUMBER = Symbol("number");
|
|
29329
|
-
var SNAPSHOT_BOOLEAN = Symbol("boolean");
|
|
29330
|
-
var SNAPSHOT_NULL = Symbol("null");
|
|
29331
|
-
var SNAPSHOT_UNDEFINED = Symbol("undefined");
|
|
29332
29434
|
function isSnapshotObjectChild(value) {
|
|
29333
29435
|
return value !== undefined && typeof value !== "function" && typeof value !== "symbol";
|
|
29334
29436
|
}
|
|
29335
29437
|
function visitMessageContentFields(value, visitor) {
|
|
29336
29438
|
if (value === null)
|
|
29337
|
-
return visitor.field(
|
|
29439
|
+
return visitor.field(LKG_SNAPSHOT_NULL);
|
|
29338
29440
|
if (typeof value === "string") {
|
|
29339
|
-
return visitor.field(
|
|
29441
|
+
return visitor.field(LKG_SNAPSHOT_STRING) && visitor.field(value);
|
|
29340
29442
|
}
|
|
29341
29443
|
if (typeof value === "number") {
|
|
29342
|
-
return visitor.field(
|
|
29444
|
+
return visitor.field(LKG_SNAPSHOT_NUMBER) && visitor.field(value);
|
|
29343
29445
|
}
|
|
29344
29446
|
if (typeof value === "boolean") {
|
|
29345
|
-
return visitor.field(
|
|
29447
|
+
return visitor.field(LKG_SNAPSHOT_BOOLEAN) && visitor.field(value);
|
|
29346
29448
|
}
|
|
29347
29449
|
if (value === undefined || typeof value === "function" || typeof value === "symbol") {
|
|
29348
|
-
return visitor.field(
|
|
29450
|
+
return visitor.field(LKG_SNAPSHOT_UNDEFINED);
|
|
29349
29451
|
}
|
|
29350
29452
|
if (Array.isArray(value)) {
|
|
29351
|
-
if (!visitor.field(
|
|
29453
|
+
if (!visitor.field(LKG_SNAPSHOT_ARRAY) || !visitor.field(value.length))
|
|
29352
29454
|
return false;
|
|
29353
29455
|
for (const item of value) {
|
|
29354
29456
|
if (!visitMessageContentFields(item, visitor))
|
|
@@ -29357,7 +29459,7 @@ function visitMessageContentFields(value, visitor) {
|
|
|
29357
29459
|
return true;
|
|
29358
29460
|
}
|
|
29359
29461
|
if (typeof value === "object") {
|
|
29360
|
-
if (!visitor.field(
|
|
29462
|
+
if (!visitor.field(LKG_SNAPSHOT_OBJECT))
|
|
29361
29463
|
return false;
|
|
29362
29464
|
const objectToken = visitor.beginObject();
|
|
29363
29465
|
if (objectToken === undefined)
|
|
@@ -29370,13 +29472,13 @@ function visitMessageContentFields(value, visitor) {
|
|
|
29370
29472
|
if (!isSnapshotObjectChild(child))
|
|
29371
29473
|
continue;
|
|
29372
29474
|
entryCount += 1;
|
|
29373
|
-
if (!visitor.field(
|
|
29475
|
+
if (!visitor.field(LKG_SNAPSHOT_KEY) || !visitor.field(key) || !visitMessageContentFields(child, visitor)) {
|
|
29374
29476
|
return false;
|
|
29375
29477
|
}
|
|
29376
29478
|
}
|
|
29377
29479
|
return visitor.endObject(objectToken, entryCount);
|
|
29378
29480
|
}
|
|
29379
|
-
return visitor.field(
|
|
29481
|
+
return visitor.field(LKG_SNAPSHOT_UNDEFINED);
|
|
29380
29482
|
}
|
|
29381
29483
|
function messageContentFields(message) {
|
|
29382
29484
|
const fields = [];
|
|
@@ -29587,7 +29689,10 @@ function ensureState(states, sessionId) {
|
|
|
29587
29689
|
memoryAuthorityProject: null,
|
|
29588
29690
|
memoryAuthorityRoot: null,
|
|
29589
29691
|
memoryAuthorityReady: false,
|
|
29590
|
-
authorityMemorySyncSkipLogged: false
|
|
29692
|
+
authorityMemorySyncSkipLogged: false,
|
|
29693
|
+
lkgCaptureSequence: 0,
|
|
29694
|
+
lkgLastCapturedRowVersion: 0,
|
|
29695
|
+
lkgSyncCaptureRequired: false
|
|
29591
29696
|
};
|
|
29592
29697
|
states.set(sessionId, state);
|
|
29593
29698
|
}
|
|
@@ -29901,6 +30006,7 @@ function buildTransformBody(args) {
|
|
|
29901
30006
|
function createRustModeTransform(deps, options) {
|
|
29902
30007
|
const states = new Map;
|
|
29903
30008
|
const wireCaches = new Map;
|
|
30009
|
+
const scheduleLkgCapture = options.scheduleLkgCapture ?? ((capture) => setImmediate(capture));
|
|
29904
30010
|
const timeoutMs = Math.max(1, options.moduleTimeoutMs ?? RUST_SEND_TIMEOUT_MS);
|
|
29905
30011
|
const logStage = (sessionId, stage, startedAt, timings, extra) => {
|
|
29906
30012
|
const elapsed = Math.max(0, performance.now() - startedAt);
|
|
@@ -30019,28 +30125,50 @@ function createRustModeTransform(deps, options) {
|
|
|
30019
30125
|
sessionLog(sessionId, "lkg_replay_served");
|
|
30020
30126
|
return true;
|
|
30021
30127
|
};
|
|
30022
|
-
const
|
|
30023
|
-
|
|
30024
|
-
|
|
30025
|
-
|
|
30128
|
+
const prepareRustCapture = (state, sessionId, input, inputSnapshots, response, responseRowVersion) => {
|
|
30129
|
+
state.lkgCaptureSequence += 1;
|
|
30130
|
+
const inputIds = input.map((message) => message.info.id);
|
|
30131
|
+
if (inputIds.some((id) => typeof id !== "string") || new Set(inputIds).size !== inputIds.length || inputIds.length === 0 || inputSnapshots.length !== inputIds.length) {
|
|
30132
|
+
return null;
|
|
30026
30133
|
}
|
|
30027
|
-
const inputContentDigests = input.map((message) => lkgContentDigest(message));
|
|
30028
|
-
if (inputContentDigests.some((digest) => digest === null))
|
|
30029
|
-
return false;
|
|
30030
30134
|
const native = response.native_messages;
|
|
30031
30135
|
const jsonPrefix = typeof native === "string" ? native : JSON.stringify(native);
|
|
30032
30136
|
if (typeof jsonPrefix !== "string")
|
|
30033
|
-
return
|
|
30137
|
+
return null;
|
|
30034
30138
|
const keys = resolveLkgModelKeys(input);
|
|
30035
|
-
return
|
|
30139
|
+
return {
|
|
30140
|
+
sessionId,
|
|
30141
|
+
inputIds,
|
|
30142
|
+
inputSnapshots,
|
|
30036
30143
|
jsonPrefix,
|
|
30037
|
-
inputIdSeq: ids,
|
|
30038
|
-
inputContentDigests,
|
|
30039
|
-
lastInputMessageId: ids[ids.length - 1],
|
|
30040
30144
|
modelKey: keys.modelKey,
|
|
30041
30145
|
providerKey: keys.providerKey,
|
|
30042
|
-
capturedAt: Date.now()
|
|
30146
|
+
capturedAt: Date.now(),
|
|
30147
|
+
rowVersion: responseRowVersion,
|
|
30148
|
+
captureSequence: state.lkgCaptureSequence
|
|
30149
|
+
};
|
|
30150
|
+
};
|
|
30151
|
+
const commitRustCapture = (state, plan) => {
|
|
30152
|
+
if (states.get(plan.sessionId) !== state || plan.captureSequence !== state.lkgCaptureSequence || plan.rowVersion < state.lkgLastCapturedRowVersion) {
|
|
30153
|
+
return "superseded";
|
|
30154
|
+
}
|
|
30155
|
+
const inputContentDigests = plan.inputSnapshots.map((snapshot) => lkgContentDigestFromFields(snapshot.fields));
|
|
30156
|
+
const captured = captureSlot(plan.sessionId, {
|
|
30157
|
+
jsonPrefix: plan.jsonPrefix,
|
|
30158
|
+
inputIdSeq: plan.inputIds,
|
|
30159
|
+
inputContentDigests,
|
|
30160
|
+
lastInputMessageId: plan.inputIds[plan.inputIds.length - 1],
|
|
30161
|
+
modelKey: plan.modelKey,
|
|
30162
|
+
providerKey: plan.providerKey,
|
|
30163
|
+
capturedAt: plan.capturedAt,
|
|
30164
|
+
rowVersion: plan.rowVersion,
|
|
30165
|
+
captureSequence: plan.captureSequence
|
|
30043
30166
|
});
|
|
30167
|
+
if (!captured)
|
|
30168
|
+
throw new Error("LKG slot rejected the prepared snapshot");
|
|
30169
|
+
state.lkgLastCapturedRowVersion = plan.rowVersion;
|
|
30170
|
+
state.lkgSyncCaptureRequired = false;
|
|
30171
|
+
return "captured";
|
|
30044
30172
|
};
|
|
30045
30173
|
const run = async (sessionId, messages, output, sessionMeta) => {
|
|
30046
30174
|
const passStartedAt = performance.now();
|
|
@@ -30098,6 +30226,30 @@ function createRustModeTransform(deps, options) {
|
|
|
30098
30226
|
const hasProviderProof = overflowState.detectedContextLimit > 0 && detectedLimitMatchesModel || isProviderOverflowReconfirmed(sessionId);
|
|
30099
30227
|
emergencyFailClosed ||= overflowState.needsEmergencyRecovery && overflowState.emergencyRecoveryOrigin === "provider_overflow" && hasProviderProof;
|
|
30100
30228
|
}
|
|
30229
|
+
const serveRawFallback = (cause) => {
|
|
30230
|
+
const contextLimit = resolvedContextLimit ?? (overflowState && overflowState.detectedContextLimit > 0 ? overflowState.detectedContextLimit : undefined);
|
|
30231
|
+
if (contextLimit !== undefined) {
|
|
30232
|
+
try {
|
|
30233
|
+
const estimate = estimateFinalWireInputTokens({
|
|
30234
|
+
messages,
|
|
30235
|
+
systemPromptTokens: sessionMeta.systemPromptTokens,
|
|
30236
|
+
providerID: model?.providerID,
|
|
30237
|
+
modelID: model?.modelID,
|
|
30238
|
+
agentName: deps.getNotificationParams?.(sessionId)?.agent
|
|
30239
|
+
});
|
|
30240
|
+
if (estimate.tokens > contextLimit) {
|
|
30241
|
+
sessionLog(sessionId, `raw_fallback_over_context_limit estimated=${estimate.tokens} limit=${contextLimit}`);
|
|
30242
|
+
throw new RawFallbackContextLimitError(estimate.tokens, contextLimit, {
|
|
30243
|
+
cause
|
|
30244
|
+
});
|
|
30245
|
+
}
|
|
30246
|
+
} catch (error) {
|
|
30247
|
+
if (error instanceof RawFallbackContextLimitError)
|
|
30248
|
+
throw error;
|
|
30249
|
+
}
|
|
30250
|
+
}
|
|
30251
|
+
replaceMessagesInPlace(output, messages);
|
|
30252
|
+
};
|
|
30101
30253
|
const finishPass = (applied, served = true) => {
|
|
30102
30254
|
const elapsedAt = applied && appliedAt !== undefined ? appliedAt : performance.now();
|
|
30103
30255
|
const elapsedMs = Math.max(0, elapsedAt - passStartedAt);
|
|
@@ -30128,11 +30280,19 @@ function createRustModeTransform(deps, options) {
|
|
|
30128
30280
|
servedFrom = typeof response.served_from === "string" ? response.served_from : "unknown";
|
|
30129
30281
|
materializeReason = typeof response.materialize_reason === "string" && response.materialize_reason.length > 0 ? response.materialize_reason : "none";
|
|
30130
30282
|
const timings2 = isRecord3(response.timings) ? response.timings : undefined;
|
|
30131
|
-
const
|
|
30132
|
-
|
|
30283
|
+
const applyOnceTotal = timings2?.total;
|
|
30284
|
+
const handlerTotal = timings2?.handler_total;
|
|
30285
|
+
moduleElapsedMs = typeof handlerTotal === "number" && Number.isFinite(handlerTotal) ? handlerTotal : typeof applyOnceTotal === "number" && Number.isFinite(applyOnceTotal) ? applyOnceTotal : 0;
|
|
30133
30286
|
rowVersion = typeof response.row_version === "number" && Number.isSafeInteger(response.row_version) ? response.row_version : 0;
|
|
30287
|
+
if (timings2 && (typeof timings2.handler_total === "number" || typeof timings2.native_cache_reused_messages === "number" || typeof timings2.native_cache_encoded_messages === "number")) {
|
|
30288
|
+
const stage = (name) => {
|
|
30289
|
+
const value = timings2[name];
|
|
30290
|
+
return typeof value === "number" && Number.isFinite(value) ? value.toFixed(1) : "n/a";
|
|
30291
|
+
};
|
|
30292
|
+
sessionLog(sessionId, `rust module stages: handler=${stage("handler_total")} apply_once=${stage("total")} ` + `request_to_handler=${stage("request_observed_to_handler")} ` + `projection=${stage("projection")} selection=${stage("selection")} ` + `build_output=${stage("build_output")} store_commit=${stage("store_commit")} ` + `post_attach=${stage("post_attach")} response_encode=${stage("response_encode")} ` + `native_cache_reused=${stage("native_cache_reused_messages")} ` + `native_cache_encoded=${stage("native_cache_encoded_messages")}`);
|
|
30293
|
+
}
|
|
30134
30294
|
if (timings2 && moduleElapsedMs >= 1000) {
|
|
30135
|
-
const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
|
|
30295
|
+
const detail = Object.entries(timings2).filter(([key, value]) => key !== "total" && key !== "handler_total" && typeof value === "number").map(([key, value]) => `${key}:${value.toFixed(1)}`).join(" ");
|
|
30136
30296
|
if (detail)
|
|
30137
30297
|
sessionLog(sessionId, `rust module stages (slow pass): ${detail}`);
|
|
30138
30298
|
}
|
|
@@ -30146,7 +30306,12 @@ function createRustModeTransform(deps, options) {
|
|
|
30146
30306
|
servedFrom = "lkg";
|
|
30147
30307
|
} else {
|
|
30148
30308
|
servedFrom = "raw";
|
|
30149
|
-
|
|
30309
|
+
try {
|
|
30310
|
+
serveRawFallback();
|
|
30311
|
+
} catch (error) {
|
|
30312
|
+
finishPass(false, false);
|
|
30313
|
+
throw error;
|
|
30314
|
+
}
|
|
30150
30315
|
}
|
|
30151
30316
|
finishPass(false);
|
|
30152
30317
|
return;
|
|
@@ -30306,10 +30471,12 @@ function createRustModeTransform(deps, options) {
|
|
|
30306
30471
|
};
|
|
30307
30472
|
}
|
|
30308
30473
|
}
|
|
30474
|
+
const getCachedStateSyncCapabilities = options.moduleClient.getCachedStateSyncCapabilities;
|
|
30309
30475
|
const stateSyncCapabilities = options.moduleClient.stateSyncCapabilities;
|
|
30310
30476
|
const stateSyncResult = await syncModuleState({
|
|
30311
30477
|
client: {
|
|
30312
30478
|
call: callModule,
|
|
30479
|
+
getCachedStateSyncCapabilities: getCachedStateSyncCapabilities ? () => getCachedStateSyncCapabilities.call(options.moduleClient) : undefined,
|
|
30313
30480
|
stateSyncCapabilities: stateSyncCapabilities ? (capabilityArgs) => stateSyncCapabilities.call(options.moduleClient, capabilityArgs) : undefined
|
|
30314
30481
|
},
|
|
30315
30482
|
state,
|
|
@@ -30434,6 +30601,7 @@ function createRustModeTransform(deps, options) {
|
|
|
30434
30601
|
throw new Error("rust module returned no transform response");
|
|
30435
30602
|
captureResponseTelemetry(response);
|
|
30436
30603
|
if (isNeedFullSync(response)) {
|
|
30604
|
+
options.moduleClient.invalidateStateSyncCapabilities?.();
|
|
30437
30605
|
state.forceFullWire = true;
|
|
30438
30606
|
if (wireDelta) {
|
|
30439
30607
|
const retryOrdinalStartedAt = performance.now();
|
|
@@ -30587,13 +30755,43 @@ function createRustModeTransform(deps, options) {
|
|
|
30587
30755
|
}
|
|
30588
30756
|
logStage(sessionId, "apply", applyStartedAt, timings);
|
|
30589
30757
|
const lkgSnapshotStartedAt = performance.now();
|
|
30590
|
-
|
|
30591
|
-
|
|
30592
|
-
|
|
30593
|
-
|
|
30758
|
+
const capturePlan = prepareRustCapture(state, sessionId, messages, pendingWireCache.rawContentSnapshots, response, rowVersion);
|
|
30759
|
+
let captureMode = "async";
|
|
30760
|
+
const captureFailed = (mode, error) => {
|
|
30761
|
+
if (states.get(sessionId) !== state || capturePlan && capturePlan.captureSequence !== state.lkgCaptureSequence) {
|
|
30762
|
+
return;
|
|
30763
|
+
}
|
|
30764
|
+
dropSlot(sessionId, `lkg_${mode}_capture_failed`);
|
|
30765
|
+
state.lkgSyncCaptureRequired = true;
|
|
30766
|
+
sessionLog(sessionId, `LKG ${mode.toUpperCase()} CAPTURE FAILED; forcing synchronous capture on the next applied pass:`, error);
|
|
30767
|
+
};
|
|
30768
|
+
if (!capturePlan) {
|
|
30769
|
+
captureMode = "declined";
|
|
30770
|
+
captureFailed("async", new Error("LKG snapshot preparation was rejected"));
|
|
30771
|
+
} else if (state.lkgSyncCaptureRequired) {
|
|
30772
|
+
captureMode = "sync_recovery";
|
|
30773
|
+
try {
|
|
30774
|
+
commitRustCapture(state, capturePlan);
|
|
30775
|
+
} catch (error) {
|
|
30776
|
+
captureFailed("sync", error);
|
|
30777
|
+
}
|
|
30778
|
+
} else {
|
|
30779
|
+
try {
|
|
30780
|
+
scheduleLkgCapture(() => {
|
|
30781
|
+
const asyncStartedAt = performance.now();
|
|
30782
|
+
try {
|
|
30783
|
+
const result = commitRustCapture(state, capturePlan);
|
|
30784
|
+
logTransformTiming(sessionId, "rust.lkg_snapshot_async", asyncStartedAt, `result=${result} row_version=${capturePlan.rowVersion}`);
|
|
30785
|
+
} catch (error) {
|
|
30786
|
+
captureFailed("async", error);
|
|
30787
|
+
}
|
|
30788
|
+
});
|
|
30789
|
+
} catch (error) {
|
|
30790
|
+
captureMode = "schedule_failed";
|
|
30791
|
+
captureFailed("async", error);
|
|
30594
30792
|
}
|
|
30595
30793
|
}
|
|
30596
|
-
logStage(sessionId, "lkgSnapshot", lkgSnapshotStartedAt, timings,
|
|
30794
|
+
logStage(sessionId, "lkgSnapshot", lkgSnapshotStartedAt, timings, `mode=${captureMode} row_version=${rowVersion}`);
|
|
30597
30795
|
const applyReplaceStartedAt = performance.now();
|
|
30598
30796
|
replaceMessagesInPlace(output, appliedMessages);
|
|
30599
30797
|
logStage(sessionId, "apply", applyReplaceStartedAt, timings);
|
|
@@ -30700,13 +30898,19 @@ function createRustModeTransform(deps, options) {
|
|
|
30700
30898
|
throw new EmergencyFailClosedError("Rust Magic Context was unavailable at a provider-proven context limit", { cause: error });
|
|
30701
30899
|
}
|
|
30702
30900
|
const replayed = replayLastGood(sessionId, messages, output, sessionMeta.systemPromptTokens);
|
|
30703
|
-
if (!replayed)
|
|
30704
|
-
replaceMessagesInPlace(output, messages);
|
|
30705
30901
|
servedFrom = replayed ? "lkg" : "raw";
|
|
30706
30902
|
if (decision.toLowerCase() !== "need_full_sync")
|
|
30707
30903
|
decision = "error";
|
|
30708
30904
|
materializeReason = "none";
|
|
30709
30905
|
markFailure(sessionId, state, error);
|
|
30906
|
+
if (!replayed) {
|
|
30907
|
+
try {
|
|
30908
|
+
serveRawFallback(error);
|
|
30909
|
+
} catch (rawFallbackError) {
|
|
30910
|
+
finishPass(false, false);
|
|
30911
|
+
throw rawFallbackError;
|
|
30912
|
+
}
|
|
30913
|
+
}
|
|
30710
30914
|
finishPass(false);
|
|
30711
30915
|
return;
|
|
30712
30916
|
}
|
|
@@ -34130,6 +34334,7 @@ function createMagicContextHook(deps) {
|
|
|
34130
34334
|
}),
|
|
34131
34335
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreaming),
|
|
34132
34336
|
language: deps.config.language,
|
|
34337
|
+
retinaHandoff: deps.config.smart_notes?.retina_handoff === true,
|
|
34133
34338
|
transformMode: deps.config.transform_mode,
|
|
34134
34339
|
moduleClient: rustModeModuleClient,
|
|
34135
34340
|
onProgress: (progress, completedTask) => {
|
|
@@ -34215,6 +34420,7 @@ function createMagicContextHook(deps) {
|
|
|
34215
34420
|
language: deps.config.language,
|
|
34216
34421
|
mural: deps.config.mural,
|
|
34217
34422
|
memoryInjectionBudgetTokens: deps.config.memory?.injection_budget_tokens,
|
|
34423
|
+
retinaHandoff: deps.config.smart_notes?.retina_handoff === true,
|
|
34218
34424
|
transformMode: deps.config.transform_mode,
|
|
34219
34425
|
moduleClient: rustModeModuleClient,
|
|
34220
34426
|
onProgress: (progress, completedTask) => {
|
|
@@ -34443,6 +34649,8 @@ function createMessagesTransformHandler(args) {
|
|
|
34443
34649
|
await magicContext?.["experimental.chat.messages.transform"]?.(input, output);
|
|
34444
34650
|
return output.messages;
|
|
34445
34651
|
} catch (error) {
|
|
34652
|
+
if (error instanceof RawFallbackContextLimitError)
|
|
34653
|
+
throw error;
|
|
34446
34654
|
if (error instanceof EmergencyFailClosedError || isFailClosedBlockingError(error)) {
|
|
34447
34655
|
if (!args.compactionOff)
|
|
34448
34656
|
throw error;
|
|
@@ -35182,7 +35390,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
35182
35390
|
}
|
|
35183
35391
|
});
|
|
35184
35392
|
const buildManagedCtx = async (db) => {
|
|
35185
|
-
const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-
|
|
35393
|
+
const { deriveHistorianChunkTokens: deriveHistorianChunkTokens2, resolveHistorianContextLimit: resolveHistorianContextLimit2 } = await import("./derive-budgets-88mxk2w1.js");
|
|
35186
35394
|
const { resolveFallbackChain: resolveFallbackChain2 } = await import("./resolve-fallbacks-5n5tvge1.js");
|
|
35187
35395
|
const { userMemoryCollectionEnabled: userMemoryCollectionEnabled2 } = await import("./task-config-gbp7r23g.js");
|
|
35188
35396
|
const DEFAULT_HISTORIAN_TIMEOUT_MS2 = 600000;
|
|
@@ -35209,8 +35417,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
35209
35417
|
const db = getDb();
|
|
35210
35418
|
if (!db)
|
|
35211
35419
|
return { ok: false, error: "db unavailable" };
|
|
35212
|
-
const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-
|
|
35213
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
35420
|
+
const { runManagedRecomp: runManagedRecomp2 } = await import("./recomp-orchestrator-7wbbvf87.js");
|
|
35421
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
|
|
35214
35422
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
35215
35423
|
const ctx = await buildManagedCtx(db);
|
|
35216
35424
|
runManagedRecomp2(ctx, sessionId).then((message) => {
|
|
@@ -35225,8 +35433,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
35225
35433
|
const db = getDb();
|
|
35226
35434
|
if (!db)
|
|
35227
35435
|
return { ok: false, error: "db unavailable" };
|
|
35228
|
-
const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-
|
|
35229
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
35436
|
+
const { runManagedUpgrade: runManagedUpgrade2 } = await import("./recomp-orchestrator-7wbbvf87.js");
|
|
35437
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
|
|
35230
35438
|
log(`[rpc] session-upgrade requested for session ${sessionId}`);
|
|
35231
35439
|
const ctx = await buildManagedCtx(db);
|
|
35232
35440
|
runManagedUpgrade2(ctx, sessionId).then((message) => {
|
|
@@ -35242,7 +35450,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
35242
35450
|
if (!db)
|
|
35243
35451
|
return { ok: false, error: "db unavailable" };
|
|
35244
35452
|
try {
|
|
35245
|
-
const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-
|
|
35453
|
+
const { updateSessionMeta: updateSessionMeta2 } = await import("./storage-meta-session-kh5egr11.js");
|
|
35246
35454
|
updateSessionMeta2(db, sessionId, { upgradeRemindedAt: Date.now() });
|
|
35247
35455
|
return { ok: true };
|
|
35248
35456
|
} catch (error) {
|
|
@@ -36198,6 +36406,447 @@ Smart notes: pass surface_condition and the note stays hidden until a background
|
|
|
36198
36406
|
Example: ctx_note(action="write", content="Re-run the perf benchmark once the boundary rework ships", surface_condition="When the latest release tag is >= v0.23.0")`;
|
|
36199
36407
|
// src/tools/ctx-note/tools.ts
|
|
36200
36408
|
import { tool as tool3 } from "@opencode-ai/plugin";
|
|
36409
|
+
|
|
36410
|
+
// src/features/magic-context/smart-notes/condition-compiler.ts
|
|
36411
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
36412
|
+
import { isAbsolute as isAbsolute4 } from "node:path";
|
|
36413
|
+
|
|
36414
|
+
// ../retina-local-fs/src/path-fence.ts
|
|
36415
|
+
import { lstat as lstat2, readlink, realpath as realpath2 } from "node:fs/promises";
|
|
36416
|
+
import { homedir as homedir4 } from "node:os";
|
|
36417
|
+
import { basename, dirname as dirname4, isAbsolute as isAbsolute3, join as join6, relative, resolve as resolve3, sep } from "node:path";
|
|
36418
|
+
|
|
36419
|
+
// ../retina-local-fs/src/errors.ts
|
|
36420
|
+
class ProviderError extends Error {
|
|
36421
|
+
code;
|
|
36422
|
+
constructor(code, message) {
|
|
36423
|
+
super(message);
|
|
36424
|
+
this.code = code;
|
|
36425
|
+
this.name = "ProviderError";
|
|
36426
|
+
}
|
|
36427
|
+
}
|
|
36428
|
+
|
|
36429
|
+
// ../retina-local-fs/src/path-fence.ts
|
|
36430
|
+
async function resolveAndFenceProviderPath(configuredPath, options) {
|
|
36431
|
+
const configuredHomePath = resolve3(options.homeDirectory ?? process.env.HOME ?? homedir4());
|
|
36432
|
+
let home;
|
|
36433
|
+
try {
|
|
36434
|
+
home = await realpath2(configuredHomePath);
|
|
36435
|
+
} catch (error) {
|
|
36436
|
+
throw fsError(configuredHomePath, error);
|
|
36437
|
+
}
|
|
36438
|
+
const expanded = configuredPath.startsWith("~/") ? join6(home, configuredPath.slice(2)) : configuredPath === "~" ? home : configuredPath;
|
|
36439
|
+
const absolute = isAbsolute3(expanded) ? resolve3(expanded) : resolve3(options.cwd ?? process.cwd(), expanded);
|
|
36440
|
+
const canonical = await canonicalPath(absolute, options.allowMissing);
|
|
36441
|
+
if (isFencedPath(canonical, home)) {
|
|
36442
|
+
throw new ProviderError("fenced_path", `Refusing fenced path: ${canonical}`);
|
|
36443
|
+
}
|
|
36444
|
+
return canonical;
|
|
36445
|
+
}
|
|
36446
|
+
async function canonicalPath(path6, allowMissing) {
|
|
36447
|
+
try {
|
|
36448
|
+
return await realpath2(path6);
|
|
36449
|
+
} catch (error) {
|
|
36450
|
+
if (!allowMissing || !isMissingError(error)) {
|
|
36451
|
+
throw fsError(path6, error);
|
|
36452
|
+
}
|
|
36453
|
+
const suffix = [];
|
|
36454
|
+
let candidate = path6;
|
|
36455
|
+
while (true) {
|
|
36456
|
+
try {
|
|
36457
|
+
const metadata = await lstat2(candidate);
|
|
36458
|
+
if (metadata.isSymbolicLink()) {
|
|
36459
|
+
const target = await readlink(candidate);
|
|
36460
|
+
const resolvedTarget = resolve3(dirname4(candidate), target);
|
|
36461
|
+
return canonicalPath(join6(resolvedTarget, ...suffix), true);
|
|
36462
|
+
}
|
|
36463
|
+
} catch (candidateError) {
|
|
36464
|
+
if (!isMissingError(candidateError)) {
|
|
36465
|
+
throw fsError(path6, candidateError);
|
|
36466
|
+
}
|
|
36467
|
+
}
|
|
36468
|
+
const parent = dirname4(candidate);
|
|
36469
|
+
if (parent === candidate) {
|
|
36470
|
+
throw fsError(path6, error);
|
|
36471
|
+
}
|
|
36472
|
+
suffix.unshift(basename(candidate));
|
|
36473
|
+
candidate = parent;
|
|
36474
|
+
try {
|
|
36475
|
+
return join6(await realpath2(candidate), ...suffix);
|
|
36476
|
+
} catch (parentError) {
|
|
36477
|
+
if (!isMissingError(parentError)) {
|
|
36478
|
+
throw fsError(path6, parentError);
|
|
36479
|
+
}
|
|
36480
|
+
}
|
|
36481
|
+
}
|
|
36482
|
+
}
|
|
36483
|
+
}
|
|
36484
|
+
function isFencedPath(canonicalPath2, homeDirectory) {
|
|
36485
|
+
const home = resolve3(homeDirectory);
|
|
36486
|
+
const cortexkitRoot = join6(home, ".local", "share", "cortexkit");
|
|
36487
|
+
const relativeToCortexkit = relative(cortexkitRoot, canonicalPath2);
|
|
36488
|
+
const insideCortexkit = relativeToCortexkit !== "" && relativeToCortexkit !== ".." && !relativeToCortexkit.startsWith(`..${sep}`) && !isAbsolute3(relativeToCortexkit);
|
|
36489
|
+
const parts = insideCortexkit ? relativeToCortexkit.split(sep) : [];
|
|
36490
|
+
const pathParts = canonicalPath2.split(sep).filter(Boolean);
|
|
36491
|
+
const name = basename(canonicalPath2);
|
|
36492
|
+
const catalogDirectoryCarveIn = pathParts.includes("catalog");
|
|
36493
|
+
const moduleBinCarveIn = parts.length >= 2 && parts[1] === "bin";
|
|
36494
|
+
const catalogJsonCarveIn = name.endsWith(".json") && name.includes("catalog");
|
|
36495
|
+
if (catalogDirectoryCarveIn || moduleBinCarveIn || catalogJsonCarveIn) {
|
|
36496
|
+
return false;
|
|
36497
|
+
}
|
|
36498
|
+
const inFencedRoot = insideCortexkit && ["plexus", "claustrum", "staging"].includes(parts[0] ?? "");
|
|
36499
|
+
const fencedBasename = name.includes("binding-key") || name.endsWith(".handle");
|
|
36500
|
+
const plexusStore = insideCortexkit && parts[0] === "plexus" && name.startsWith("store.db");
|
|
36501
|
+
return inFencedRoot || fencedBasename || plexusStore;
|
|
36502
|
+
}
|
|
36503
|
+
function fsError(path6, error) {
|
|
36504
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36505
|
+
return new ProviderError("unreadable_path", `Could not read ${path6}: ${message}`);
|
|
36506
|
+
}
|
|
36507
|
+
function isMissingError(error) {
|
|
36508
|
+
return error !== null && typeof error === "object" && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
36509
|
+
}
|
|
36510
|
+
|
|
36511
|
+
// ../retina-local-fs/src/provider.ts
|
|
36512
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
36513
|
+
import { promisify as promisify3 } from "node:util";
|
|
36514
|
+
var execFileAsync3 = promisify3(execFile3);
|
|
36515
|
+
function parseSemver(value) {
|
|
36516
|
+
const match = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(value);
|
|
36517
|
+
if (!match) {
|
|
36518
|
+
throw new ProviderError("invalid_config", `Invalid semantic version: ${value}`);
|
|
36519
|
+
}
|
|
36520
|
+
return {
|
|
36521
|
+
major: Number(match[1]),
|
|
36522
|
+
minor: Number(match[2]),
|
|
36523
|
+
patch: Number(match[3]),
|
|
36524
|
+
prerelease: match[4] ? match[4].split(".").map((part) => /^\d+$/.test(part) ? Number(part) : part) : []
|
|
36525
|
+
};
|
|
36526
|
+
}
|
|
36527
|
+
function validateProviderConfig(input) {
|
|
36528
|
+
try {
|
|
36529
|
+
return { success: true, config: parseConfig(input) };
|
|
36530
|
+
} catch (error) {
|
|
36531
|
+
return {
|
|
36532
|
+
success: false,
|
|
36533
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
36534
|
+
};
|
|
36535
|
+
}
|
|
36536
|
+
}
|
|
36537
|
+
function parseConfig(value) {
|
|
36538
|
+
const config = requireObject(value, "config");
|
|
36539
|
+
if ("any" in config) {
|
|
36540
|
+
requireOnlyKeys(config, ["any"], "compound config");
|
|
36541
|
+
if (!Array.isArray(config.any) || config.any.length < 1 || config.any.length > 4) {
|
|
36542
|
+
invalid("config.any must contain between 1 and 4 predicates");
|
|
36543
|
+
}
|
|
36544
|
+
return { any: config.any.map(parseAtomicPredicate) };
|
|
36545
|
+
}
|
|
36546
|
+
return parseAtomicPredicate(config);
|
|
36547
|
+
}
|
|
36548
|
+
function parseAtomicPredicate(value) {
|
|
36549
|
+
const predicate = requireObject(value, "predicate");
|
|
36550
|
+
if (typeof predicate.kind !== "string") {
|
|
36551
|
+
invalid("predicate.kind must be a string");
|
|
36552
|
+
}
|
|
36553
|
+
switch (predicate.kind) {
|
|
36554
|
+
case "file_contains":
|
|
36555
|
+
requireOnlyKeys(predicate, ["kind", "path", "needle", "absent", "resolved_path_exists"], predicate.kind);
|
|
36556
|
+
return {
|
|
36557
|
+
kind: predicate.kind,
|
|
36558
|
+
path: requireString(predicate.path, "path"),
|
|
36559
|
+
needle: requireString(predicate.needle, "needle", true),
|
|
36560
|
+
...optionalBoolean(predicate.absent, "absent") === undefined ? {} : { absent: predicate.absent },
|
|
36561
|
+
...predicateAudit(predicate)
|
|
36562
|
+
};
|
|
36563
|
+
case "path_exists":
|
|
36564
|
+
requireOnlyKeys(predicate, ["kind", "path", "gone", "resolved_path_exists"], predicate.kind);
|
|
36565
|
+
return {
|
|
36566
|
+
kind: predicate.kind,
|
|
36567
|
+
path: requireString(predicate.path, "path"),
|
|
36568
|
+
...optionalBoolean(predicate.gone, "gone") === undefined ? {} : { gone: predicate.gone },
|
|
36569
|
+
...predicateAudit(predicate)
|
|
36570
|
+
};
|
|
36571
|
+
case "mtime_after":
|
|
36572
|
+
requireOnlyKeys(predicate, ["kind", "path", "since_ms", "resolved_path_exists"], predicate.kind);
|
|
36573
|
+
return {
|
|
36574
|
+
kind: predicate.kind,
|
|
36575
|
+
path: requireString(predicate.path, "path"),
|
|
36576
|
+
since_ms: requireFiniteNumber(predicate.since_ms, "since_ms"),
|
|
36577
|
+
...predicateAudit(predicate)
|
|
36578
|
+
};
|
|
36579
|
+
case "git_commit_after":
|
|
36580
|
+
requireOnlyKeys(predicate, ["kind", "repo_path", "ref", "sha", "resolved_path_exists"], predicate.kind);
|
|
36581
|
+
return {
|
|
36582
|
+
kind: predicate.kind,
|
|
36583
|
+
repo_path: requireString(predicate.repo_path, "repo_path"),
|
|
36584
|
+
sha: requireString(predicate.sha, "sha"),
|
|
36585
|
+
...predicate.ref === undefined ? {} : { ref: requireString(predicate.ref, "ref") },
|
|
36586
|
+
...predicateAudit(predicate)
|
|
36587
|
+
};
|
|
36588
|
+
case "git_tag_matching": {
|
|
36589
|
+
requireOnlyKeys(predicate, ["kind", "repo_path", "pattern", "above", "resolved_path_exists"], predicate.kind);
|
|
36590
|
+
const above = predicate.above === undefined ? undefined : requireString(predicate.above, "above");
|
|
36591
|
+
if (above !== undefined) {
|
|
36592
|
+
parseSemver(above);
|
|
36593
|
+
}
|
|
36594
|
+
return {
|
|
36595
|
+
kind: predicate.kind,
|
|
36596
|
+
repo_path: requireString(predicate.repo_path, "repo_path"),
|
|
36597
|
+
pattern: requireString(predicate.pattern, "pattern"),
|
|
36598
|
+
...above === undefined ? {} : { above },
|
|
36599
|
+
...predicateAudit(predicate)
|
|
36600
|
+
};
|
|
36601
|
+
}
|
|
36602
|
+
default:
|
|
36603
|
+
invalid(`Unsupported predicate kind: ${predicate.kind}`);
|
|
36604
|
+
}
|
|
36605
|
+
}
|
|
36606
|
+
function requireObject(value, field) {
|
|
36607
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
36608
|
+
invalid(`${field} must be an object`);
|
|
36609
|
+
}
|
|
36610
|
+
return value;
|
|
36611
|
+
}
|
|
36612
|
+
function requireOnlyKeys(value, allowed, field) {
|
|
36613
|
+
const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
|
|
36614
|
+
if (unknown.length > 0) {
|
|
36615
|
+
invalid(`${field} contains unknown field(s): ${unknown.join(", ")}`);
|
|
36616
|
+
}
|
|
36617
|
+
}
|
|
36618
|
+
function requireString(value, field, allowEmpty = false) {
|
|
36619
|
+
if (typeof value !== "string" || !allowEmpty && value.length === 0) {
|
|
36620
|
+
invalid(`${field} must be ${allowEmpty ? "a string" : "a non-empty string"}`);
|
|
36621
|
+
}
|
|
36622
|
+
return value;
|
|
36623
|
+
}
|
|
36624
|
+
function predicateAudit(predicate) {
|
|
36625
|
+
const exists = optionalBoolean(predicate.resolved_path_exists, "resolved_path_exists");
|
|
36626
|
+
return exists === undefined ? {} : { resolved_path_exists: exists };
|
|
36627
|
+
}
|
|
36628
|
+
function optionalBoolean(value, field) {
|
|
36629
|
+
if (value !== undefined && typeof value !== "boolean") {
|
|
36630
|
+
invalid(`${field} must be a boolean`);
|
|
36631
|
+
}
|
|
36632
|
+
return value;
|
|
36633
|
+
}
|
|
36634
|
+
function requireFiniteNumber(value, field) {
|
|
36635
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
36636
|
+
invalid(`${field} must be a finite number`);
|
|
36637
|
+
}
|
|
36638
|
+
return value;
|
|
36639
|
+
}
|
|
36640
|
+
function invalid(message) {
|
|
36641
|
+
throw new ProviderError("invalid_config", message);
|
|
36642
|
+
}
|
|
36643
|
+
|
|
36644
|
+
// src/features/magic-context/smart-notes/condition-compiler.ts
|
|
36645
|
+
var RETINA_LOCAL_FS_PROVIDER = "local-fs";
|
|
36646
|
+
var VALUE = String.raw`(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\S+)`;
|
|
36647
|
+
async function compileSurfaceCondition(surfaceCondition, options) {
|
|
36648
|
+
const parsed = parseCondition(surfaceCondition, options.projectPath);
|
|
36649
|
+
if (parsed === null)
|
|
36650
|
+
return { status: "plain" };
|
|
36651
|
+
const now = (options.now ?? Date.now)();
|
|
36652
|
+
const resolvePath = options.resolvePath ?? (async (path6) => {
|
|
36653
|
+
const resolved = await resolveAndFenceProviderPath(path6, {
|
|
36654
|
+
allowMissing: true,
|
|
36655
|
+
homeDirectory: options.homeDirectory,
|
|
36656
|
+
cwd: options.projectPath
|
|
36657
|
+
});
|
|
36658
|
+
return { path: resolved, exists: existsSync11(resolved) };
|
|
36659
|
+
});
|
|
36660
|
+
let predicates;
|
|
36661
|
+
try {
|
|
36662
|
+
predicates = [];
|
|
36663
|
+
for (const predicate of parsed) {
|
|
36664
|
+
predicates.push(await resolvePredicate(predicate, resolvePath, now));
|
|
36665
|
+
}
|
|
36666
|
+
} catch (error) {
|
|
36667
|
+
const code = error !== null && typeof error === "object" && "code" in error ? error.code : undefined;
|
|
36668
|
+
return {
|
|
36669
|
+
status: "refused",
|
|
36670
|
+
reason: code === "fenced_path" ? "fenced path" : "path resolution failed"
|
|
36671
|
+
};
|
|
36672
|
+
}
|
|
36673
|
+
const candidate = predicates.length === 1 ? predicates[0] : { any: predicates };
|
|
36674
|
+
const validation = validateProviderConfig(candidate);
|
|
36675
|
+
if (!validation.success) {
|
|
36676
|
+
return {
|
|
36677
|
+
status: "refused",
|
|
36678
|
+
reason: `provider schema: ${singleLine(validation.reason)}`.slice(0, 180)
|
|
36679
|
+
};
|
|
36680
|
+
}
|
|
36681
|
+
return {
|
|
36682
|
+
status: "compiled",
|
|
36683
|
+
provider: RETINA_LOCAL_FS_PROVIDER,
|
|
36684
|
+
config: validation.config,
|
|
36685
|
+
compiledAt: now
|
|
36686
|
+
};
|
|
36687
|
+
}
|
|
36688
|
+
function conditionCompileStorageFields(result) {
|
|
36689
|
+
if (result.status === "compiled") {
|
|
36690
|
+
return {
|
|
36691
|
+
compiledProvider: result.provider,
|
|
36692
|
+
compiledConfig: JSON.stringify(result.config),
|
|
36693
|
+
compiledAt: result.compiledAt,
|
|
36694
|
+
compileStatus: result.status
|
|
36695
|
+
};
|
|
36696
|
+
}
|
|
36697
|
+
return {
|
|
36698
|
+
compiledProvider: null,
|
|
36699
|
+
compiledConfig: null,
|
|
36700
|
+
compiledAt: null,
|
|
36701
|
+
compileStatus: result.status
|
|
36702
|
+
};
|
|
36703
|
+
}
|
|
36704
|
+
function conditionCompileReplySuffix(result) {
|
|
36705
|
+
if (result.status === "compiled") {
|
|
36706
|
+
return `
|
|
36707
|
+
- Retina provider: ${result.provider}`;
|
|
36708
|
+
}
|
|
36709
|
+
if (result.status === "refused") {
|
|
36710
|
+
return `
|
|
36711
|
+
- Retina compile refused: ${result.reason}`;
|
|
36712
|
+
}
|
|
36713
|
+
return "";
|
|
36714
|
+
}
|
|
36715
|
+
function parseCondition(surfaceCondition, projectPath) {
|
|
36716
|
+
const trimmed = surfaceCondition.trim();
|
|
36717
|
+
const either = trimmed.match(/^either\s+(.+)$/i);
|
|
36718
|
+
if (!either) {
|
|
36719
|
+
const predicate = parseAtomicCondition(trimmed, projectPath);
|
|
36720
|
+
return predicate ? [predicate] : null;
|
|
36721
|
+
}
|
|
36722
|
+
const clauses = splitOrClauses(either[1]);
|
|
36723
|
+
if (clauses.length < 2)
|
|
36724
|
+
return null;
|
|
36725
|
+
const predicates = clauses.map((clause) => parseAtomicCondition(clause, projectPath));
|
|
36726
|
+
return predicates.every((predicate) => predicate !== null) ? predicates : null;
|
|
36727
|
+
}
|
|
36728
|
+
function parseAtomicCondition(text, projectPath) {
|
|
36729
|
+
const fileContains = text.match(new RegExp(`^(?:when\\s+)?file\\s+(${VALUE})\\s+(no longer contains|contains)\\s+(.+)$`, "i"));
|
|
36730
|
+
if (fileContains) {
|
|
36731
|
+
const needle = unquote(fileContains[3].trim());
|
|
36732
|
+
if (needle === null)
|
|
36733
|
+
return null;
|
|
36734
|
+
return {
|
|
36735
|
+
kind: "file_contains",
|
|
36736
|
+
path: unquote(fileContains[1]) ?? fileContains[1],
|
|
36737
|
+
needle,
|
|
36738
|
+
...fileContains[2].toLowerCase() === "no longer contains" ? { absent: true } : {}
|
|
36739
|
+
};
|
|
36740
|
+
}
|
|
36741
|
+
const commit = text.match(new RegExp(`^(?:when\\s+)?(?:repo(?:sitory)?\\s+)?(${VALUE})\\s+has\\s+a\\s+commit\\s+(?:after|newer than)\\s+([0-9a-f]{7,64})$`, "i"));
|
|
36742
|
+
if (commit) {
|
|
36743
|
+
return {
|
|
36744
|
+
kind: "git_commit_after",
|
|
36745
|
+
repo_path: unquote(commit[1]) ?? commit[1],
|
|
36746
|
+
sha: commit[2]
|
|
36747
|
+
};
|
|
36748
|
+
}
|
|
36749
|
+
const tag = text.match(new RegExp(`^(?:when\\s+)?a\\s+tag\\s+(?:(?:matching\\s+(${VALUE})(?:\\s+above\\s+semver\\s+(${VALUE}))?)|(?:above\\s+semver\\s+(${VALUE})))\\s+appears(?:\\s+in\\s+(?:repo(?:sitory)?\\s+)?(${VALUE}))?$`, "i"));
|
|
36750
|
+
if (tag) {
|
|
36751
|
+
const pattern = tag[1] ? unquote(tag[1]) : "*";
|
|
36752
|
+
const above = unquote(tag[2] ?? tag[3] ?? "");
|
|
36753
|
+
const repoPath = tag[4] ? unquote(tag[4]) : projectPath;
|
|
36754
|
+
if (pattern === null || above === null || repoPath === null)
|
|
36755
|
+
return null;
|
|
36756
|
+
return {
|
|
36757
|
+
kind: "git_tag_matching",
|
|
36758
|
+
repo_path: repoPath,
|
|
36759
|
+
pattern,
|
|
36760
|
+
...above.length > 0 ? { above } : {}
|
|
36761
|
+
};
|
|
36762
|
+
}
|
|
36763
|
+
const mtime = text.match(new RegExp(`^(?:when\\s+)?(?:file\\s+)?(${VALUE})\\s+(changes|is rebuilt|mtime moves)$`, "i"));
|
|
36764
|
+
if (mtime) {
|
|
36765
|
+
return {
|
|
36766
|
+
kind: "mtime_after",
|
|
36767
|
+
path: unquote(mtime[1]) ?? mtime[1]
|
|
36768
|
+
};
|
|
36769
|
+
}
|
|
36770
|
+
const pathExists = text.match(new RegExp(`^(?:when\\s+)?(?:path\\s+)?(${VALUE})\\s+(exists|is gone)$`, "i"));
|
|
36771
|
+
if (pathExists) {
|
|
36772
|
+
return {
|
|
36773
|
+
kind: "path_exists",
|
|
36774
|
+
path: unquote(pathExists[1]) ?? pathExists[1],
|
|
36775
|
+
...pathExists[2].toLowerCase() === "is gone" ? { gone: true } : {}
|
|
36776
|
+
};
|
|
36777
|
+
}
|
|
36778
|
+
return null;
|
|
36779
|
+
}
|
|
36780
|
+
async function resolvePredicate(predicate, resolvePath, now) {
|
|
36781
|
+
const configuredPath = "repo_path" in predicate ? predicate.repo_path : predicate.path;
|
|
36782
|
+
const resolved = await resolvePath(configuredPath);
|
|
36783
|
+
const sourceIsResolvable = isAbsolute4(configuredPath) || configuredPath === "~" || configuredPath.startsWith("~/");
|
|
36784
|
+
const audit = sourceIsResolvable && resolved.exists ? {} : { resolved_path_exists: false };
|
|
36785
|
+
switch (predicate.kind) {
|
|
36786
|
+
case "file_contains":
|
|
36787
|
+
return { ...predicate, path: resolved.path, ...audit };
|
|
36788
|
+
case "path_exists":
|
|
36789
|
+
return { ...predicate, path: resolved.path, ...audit };
|
|
36790
|
+
case "mtime_after":
|
|
36791
|
+
return { kind: predicate.kind, path: resolved.path, since_ms: now, ...audit };
|
|
36792
|
+
case "git_commit_after":
|
|
36793
|
+
return { ...predicate, repo_path: resolved.path, ...audit };
|
|
36794
|
+
case "git_tag_matching":
|
|
36795
|
+
return { ...predicate, repo_path: resolved.path, ...audit };
|
|
36796
|
+
}
|
|
36797
|
+
}
|
|
36798
|
+
function splitOrClauses(text) {
|
|
36799
|
+
const clauses = [];
|
|
36800
|
+
let start = 0;
|
|
36801
|
+
let quote = null;
|
|
36802
|
+
let escaped = false;
|
|
36803
|
+
for (let index = 0;index < text.length; index += 1) {
|
|
36804
|
+
const character = text[index];
|
|
36805
|
+
if (escaped) {
|
|
36806
|
+
escaped = false;
|
|
36807
|
+
continue;
|
|
36808
|
+
}
|
|
36809
|
+
if (quote && character === "\\") {
|
|
36810
|
+
escaped = true;
|
|
36811
|
+
continue;
|
|
36812
|
+
}
|
|
36813
|
+
if (character === '"' || character === "'") {
|
|
36814
|
+
quote = quote === character ? null : quote === null ? character : quote;
|
|
36815
|
+
continue;
|
|
36816
|
+
}
|
|
36817
|
+
if (quote !== null)
|
|
36818
|
+
continue;
|
|
36819
|
+
const separator = text.slice(index).match(/^\s+or\s+/i);
|
|
36820
|
+
if (!separator)
|
|
36821
|
+
continue;
|
|
36822
|
+
clauses.push(text.slice(start, index).trim());
|
|
36823
|
+
index += separator[0].length - 1;
|
|
36824
|
+
start = index + 1;
|
|
36825
|
+
}
|
|
36826
|
+
clauses.push(text.slice(start).trim());
|
|
36827
|
+
return clauses.filter(Boolean);
|
|
36828
|
+
}
|
|
36829
|
+
function unquote(value) {
|
|
36830
|
+
if (value.length < 2)
|
|
36831
|
+
return value;
|
|
36832
|
+
const quote = value[0];
|
|
36833
|
+
if (quote !== '"' && quote !== "'" || value.at(-1) !== quote)
|
|
36834
|
+
return value;
|
|
36835
|
+
if (quote === '"') {
|
|
36836
|
+
try {
|
|
36837
|
+
const parsed = JSON.parse(value);
|
|
36838
|
+
return typeof parsed === "string" ? parsed : null;
|
|
36839
|
+
} catch {
|
|
36840
|
+
return null;
|
|
36841
|
+
}
|
|
36842
|
+
}
|
|
36843
|
+
return value.slice(1, -1).replace(/\\'/g, "'").replace(/\\\\/g, "\\");
|
|
36844
|
+
}
|
|
36845
|
+
function singleLine(value) {
|
|
36846
|
+
return value.replace(/\s+/g, " ").trim();
|
|
36847
|
+
}
|
|
36848
|
+
|
|
36849
|
+
// src/tools/ctx-note/tools.ts
|
|
36201
36850
|
function captureAnchorOrdinal(db, sessionId) {
|
|
36202
36851
|
try {
|
|
36203
36852
|
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
@@ -36423,16 +37072,21 @@ function createCtxNoteTool(deps) {
|
|
|
36423
37072
|
if (!projectIdentity) {
|
|
36424
37073
|
return "Error: Could not resolve project identity for smart note.";
|
|
36425
37074
|
}
|
|
37075
|
+
const surfaceCondition = args.surface_condition.trim();
|
|
37076
|
+
const compilation = await compileSurfaceCondition(surfaceCondition, {
|
|
37077
|
+
projectPath: toolContext.directory
|
|
37078
|
+
});
|
|
36426
37079
|
const note2 = addNote(deps.db, "smart", {
|
|
36427
37080
|
content,
|
|
36428
37081
|
projectPath: projectIdentity,
|
|
36429
37082
|
sessionId,
|
|
36430
|
-
surfaceCondition
|
|
36431
|
-
anchorOrdinal
|
|
37083
|
+
surfaceCondition,
|
|
37084
|
+
anchorOrdinal,
|
|
37085
|
+
...conditionCompileStorageFields(compilation)
|
|
36432
37086
|
});
|
|
36433
37087
|
return `Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
36434
37088
|
- Content: ${content}
|
|
36435
|
-
- Condition: ${
|
|
37089
|
+
- Condition: ${surfaceCondition}${conditionCompileReplySuffix(compilation)}`;
|
|
36436
37090
|
}
|
|
36437
37091
|
const note = addNote(deps.db, "session", { sessionId, content, anchorOrdinal });
|
|
36438
37092
|
return `Saved session note #${note.id}.`;
|
|
@@ -36459,8 +37113,15 @@ function createCtxNoteTool(deps) {
|
|
|
36459
37113
|
const updates = {};
|
|
36460
37114
|
if (args.content?.trim())
|
|
36461
37115
|
updates.content = args.content.trim();
|
|
36462
|
-
|
|
36463
|
-
|
|
37116
|
+
let compilation;
|
|
37117
|
+
if (args.surface_condition?.trim()) {
|
|
37118
|
+
const surfaceCondition = args.surface_condition.trim();
|
|
37119
|
+
updates.surfaceCondition = surfaceCondition;
|
|
37120
|
+
compilation = await compileSurfaceCondition(surfaceCondition, {
|
|
37121
|
+
projectPath: toolContext.directory
|
|
37122
|
+
});
|
|
37123
|
+
Object.assign(updates, conditionCompileStorageFields(compilation));
|
|
37124
|
+
}
|
|
36464
37125
|
if (!updates.content && !updates.surfaceCondition) {
|
|
36465
37126
|
return "Error: Provide 'content' and/or 'surface_condition' to update.";
|
|
36466
37127
|
}
|
|
@@ -36481,7 +37142,7 @@ function createCtxNoteTool(deps) {
|
|
|
36481
37142
|
parts.push(`Condition: ${updates.surfaceCondition}`);
|
|
36482
37143
|
return `Updated note #${noteId}:
|
|
36483
37144
|
${parts.join(`
|
|
36484
|
-
`)}`;
|
|
37145
|
+
`)}${compilation ? conditionCompileReplySuffix(compilation) : ""}`;
|
|
36485
37146
|
}
|
|
36486
37147
|
const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : DEFAULT_READ_LIMIT;
|
|
36487
37148
|
const offset = typeof args.offset === "number" && args.offset > 0 ? Math.floor(args.offset) : 0;
|
|
@@ -37050,7 +37711,7 @@ import {
|
|
|
37050
37711
|
unlinkSync,
|
|
37051
37712
|
writeFileSync as writeFileSync4
|
|
37052
37713
|
} from "node:fs";
|
|
37053
|
-
import { dirname as
|
|
37714
|
+
import { dirname as dirname5 } from "node:path";
|
|
37054
37715
|
var MAX_BODY_BYTES = 1048576;
|
|
37055
37716
|
var WS_AUTH_TIMEOUT_MS = 5000;
|
|
37056
37717
|
var WS_CLOSE_UNAUTHORIZED = 4401;
|
|
@@ -37124,7 +37785,7 @@ class MagicContextRpcServer {
|
|
|
37124
37785
|
this.port = server.port ?? 0;
|
|
37125
37786
|
try {
|
|
37126
37787
|
this.warnIfOtherLiveInstance();
|
|
37127
|
-
const dir =
|
|
37788
|
+
const dir = dirname5(this.portFilePath);
|
|
37128
37789
|
const enforcePrivatePermissions = shouldEnforcePrivateStoragePermissions();
|
|
37129
37790
|
if (enforcePrivatePermissions) {
|
|
37130
37791
|
mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
@@ -37357,7 +38018,7 @@ var server = async (ctx) => {
|
|
|
37357
38018
|
`);
|
|
37358
38019
|
setTimeout(async () => {
|
|
37359
38020
|
try {
|
|
37360
|
-
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-
|
|
38021
|
+
const { sendIgnoredMessage: sendIgnoredMessage2 } = await import("./send-session-notification-bgtf4853.js");
|
|
37361
38022
|
const clientWithSessions = ctx.client;
|
|
37362
38023
|
const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
|
|
37363
38024
|
const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
|
|
@@ -37501,6 +38162,7 @@ var server = async (ctx) => {
|
|
|
37501
38162
|
memoryEnabled: pluginConfig.memory?.enabled === true,
|
|
37502
38163
|
memoryInjectionBudgetTokens: pluginConfig.memory?.injection_budget_tokens,
|
|
37503
38164
|
mural: pluginConfig.mural,
|
|
38165
|
+
retinaHandoff: pluginConfig.smart_notes.retina_handoff,
|
|
37504
38166
|
gitCommitIndexing: pluginConfig.memory.git_commit_indexing?.enabled ? {
|
|
37505
38167
|
enabled: true,
|
|
37506
38168
|
since_days: pluginConfig.memory.git_commit_indexing.since_days,
|
|
@@ -37538,7 +38200,7 @@ var server = async (ctx) => {
|
|
|
37538
38200
|
{
|
|
37539
38201
|
const fence = getSchemaFenceRejection();
|
|
37540
38202
|
if (fence) {
|
|
37541
|
-
import("./conflict-warning-hook-
|
|
38203
|
+
import("./conflict-warning-hook-dw9fs934.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
|
|
37542
38204
|
}
|
|
37543
38205
|
}
|
|
37544
38206
|
if (conflictResult?.hasConflict) {
|
|
@@ -37556,10 +38218,10 @@ var server = async (ctx) => {
|
|
|
37556
38218
|
ANNOUNCEMENT_FEATURES: ANNOUNCEMENT_FEATURES2,
|
|
37557
38219
|
ANNOUNCEMENT_FOOTER: ANNOUNCEMENT_FOOTER2,
|
|
37558
38220
|
markAnnouncementSeen: markAnnouncementSeen2
|
|
37559
|
-
} = await import("./announcement-
|
|
38221
|
+
} = await import("./announcement-6c1g4es4.js");
|
|
37560
38222
|
if (shouldShowAnnouncement2()) {
|
|
37561
38223
|
setTimeout(() => {
|
|
37562
|
-
import("./conflict-warning-hook-
|
|
38224
|
+
import("./conflict-warning-hook-dw9fs934.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION2, ANNOUNCEMENT_FEATURES2, ANNOUNCEMENT_FOOTER2, markAnnouncementSeen2)).catch(() => {});
|
|
37563
38225
|
}, 8000);
|
|
37564
38226
|
}
|
|
37565
38227
|
} catch {}
|
|
@@ -37686,14 +38348,17 @@ var server = async (ctx) => {
|
|
|
37686
38348
|
historianDisallowed: pluginConfig.historian?.disallowed_tools ?? []
|
|
37687
38349
|
});
|
|
37688
38350
|
const agentConfig = { ...config.agent ?? {} };
|
|
38351
|
+
const agentConfigRecord = agentConfig;
|
|
38352
|
+
const internalAgentIds = registrations.map((registration) => registration.id);
|
|
37689
38353
|
for (const reg of registrations) {
|
|
37690
38354
|
if (typeof reg.prompt !== "string" || reg.prompt.length === 0) {
|
|
37691
38355
|
log(`[magic-context] skipping hidden agent '${reg.id}' — prompt unavailable at config time (dir=${ctx.directory}); will re-register on a later complete pass`);
|
|
37692
38356
|
continue;
|
|
37693
38357
|
}
|
|
37694
|
-
|
|
38358
|
+
agentConfigRecord[reg.id] = buildHiddenAgentConfig(reg.prompt, reg.allowedTools, reg.maxSteps, reg.overrides, reg.id, reg.lockPermissions === true, reg.description);
|
|
37695
38359
|
}
|
|
37696
|
-
|
|
38360
|
+
const callerAgentConfig = denyTaskRoutingToCallerAgents(agentConfigRecord, internalAgentIds);
|
|
38361
|
+
config.agent = callerAgentConfig;
|
|
37697
38362
|
} catch (error) {
|
|
37698
38363
|
const e = error;
|
|
37699
38364
|
log(`[magic-context] config hook failed (commands/agents NOT registered; transform still active): ${e?.message ?? error}`, e?.stack ? { stackHead: e.stack.split(`
|