omp-fabric 1.1.0 → 1.3.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/CHANGELOG.md +50 -0
- package/README.md +1 -0
- package/dist/actors/global-registry.d.ts.map +1 -1
- package/dist/actors/manager.d.ts.map +1 -1
- package/dist/actors/types.d.ts +1 -0
- package/dist/actors/types.d.ts.map +1 -1
- package/dist/agents/handoff.d.ts +1 -1
- package/dist/agents/handoff.d.ts.map +1 -1
- package/dist/agents/manager.d.ts.map +1 -1
- package/dist/agents/types.d.ts +2 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/chunks/{chunk-3TWC6XOS.js → chunk-2WDZT27Q.js} +36 -13
- package/dist/chunks/chunk-2WDZT27Q.js.map +7 -0
- package/dist/chunks/{chunk-UOSJZXJV.js → chunk-3LI7YO4M.js} +1 -1
- package/dist/chunks/chunk-3LI7YO4M.js.map +7 -0
- package/dist/chunks/{chunk-WXZP5VWP.js → chunk-7MFYALJI.js} +16 -16
- package/dist/chunks/chunk-7MFYALJI.js.map +7 -0
- package/dist/chunks/{chunk-B2SQR2JY.js → chunk-BMIE4PIL.js} +2 -2
- package/dist/chunks/{chunk-NX4SNIMR.js → chunk-FX3XLQYI.js} +36 -7
- package/dist/chunks/chunk-FX3XLQYI.js.map +7 -0
- package/dist/chunks/{chunk-CVLO4GNW.js → chunk-GDZDWKJS.js} +3 -3
- package/dist/chunks/{chunk-YPYVUGON.js → chunk-JOWMM3EX.js} +6 -6
- package/dist/chunks/chunk-JOWMM3EX.js.map +7 -0
- package/dist/chunks/{chunk-L2FNMIOW.js → chunk-QNRGTJGE.js} +2 -1
- package/dist/chunks/chunk-QNRGTJGE.js.map +7 -0
- package/dist/chunks/{chunk-2GQC324T.js → chunk-TSU4AEPZ.js} +2 -2
- package/dist/chunks/{chunk-TLSJXU4F.js → chunk-VSSC4IDU.js} +180 -11
- package/dist/chunks/chunk-VSSC4IDU.js.map +7 -0
- package/dist/chunks/{chunk-HDJBUXDX.js → chunk-WQUMHDOS.js} +2 -2
- package/dist/chunks/{chunk-EZPERYEG.js → chunk-XRJYPNTI.js} +56 -2
- package/dist/chunks/chunk-XRJYPNTI.js.map +7 -0
- package/dist/chunks/{chunk-Z6HEQPXX.js → chunk-Z5AP4M6K.js} +70 -6
- package/dist/chunks/chunk-Z5AP4M6K.js.map +7 -0
- package/dist/chunks/{chunk-KIREBD2V.js → chunk-ZP3S74LW.js} +2 -1
- package/dist/codemap/budget.d.ts +3 -0
- package/dist/codemap/budget.d.ts.map +1 -0
- package/dist/codemap/cascade.d.ts +3 -0
- package/dist/codemap/cascade.d.ts.map +1 -0
- package/dist/codemap/symbols.d.ts +3 -0
- package/dist/codemap/symbols.d.ts.map +1 -0
- package/dist/codemap/types.d.ts +58 -0
- package/dist/codemap/types.d.ts.map +1 -0
- package/dist/compaction/hook.js +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/core/system-guidance.d.ts.map +1 -1
- package/dist/entropy/index.js +2 -2
- package/dist/fabric-runtime-state.d.ts.map +1 -1
- package/dist/fabric-runtime-state.js +1806 -378
- package/dist/fabric-runtime-state.js.map +4 -4
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/memory/discovery.d.ts +10 -0
- package/dist/memory/discovery.d.ts.map +1 -1
- package/dist/memory/discovery.js +3 -1
- package/dist/prewalk/handoff.d.ts +2 -1
- package/dist/prewalk/handoff.d.ts.map +1 -1
- package/dist/prewalk/retirement.d.ts +35 -0
- package/dist/prewalk/retirement.d.ts.map +1 -0
- package/dist/providers/agents-actions.d.ts.map +1 -1
- package/dist/providers/agents-provider.d.ts.map +1 -1
- package/dist/providers/codemap-provider.d.ts +14 -0
- package/dist/providers/codemap-provider.d.ts.map +1 -0
- package/dist/providers/mcp-provider.d.ts.map +1 -1
- package/dist/providers/memory-provider.d.ts.map +1 -1
- package/dist/providers/memory-provider.js +2 -2
- package/dist/providers/mesh-provider.d.ts.map +1 -1
- package/dist/providers/omp-tools-provider.d.ts.map +1 -1
- package/dist/providers/write-preview.d.ts.map +1 -1
- package/dist/residency/host.js +6 -6
- package/dist/residency/omp-entry.js +6 -6
- package/dist/runtime/core-override-guest-types.js +1 -1
- package/dist/runtime/guest-types.d.ts +1 -1
- package/dist/runtime/guest-types.d.ts.map +1 -1
- package/dist/runtime/guest-types.js +1 -1
- package/dist/runtime/node-process-runtime.js +1 -1
- package/dist/runtime/quickjs-runtime.d.ts +1 -1
- package/dist/runtime/quickjs-runtime.d.ts.map +1 -1
- package/dist/runtime/quickjs-runtime.js +1 -1
- package/dist/ui/dashboard.js +3 -3
- package/dist/ui/settings.d.ts.map +1 -1
- package/dist/ui/settings.js +90 -1
- package/dist/ui/settings.js.map +2 -2
- package/docs/architecture.md +1 -1
- package/docs/codemap.md +95 -0
- package/docs/configuration.md +1 -1
- package/package.json +4 -1
- package/dist/chunks/chunk-3TWC6XOS.js.map +0 -7
- package/dist/chunks/chunk-EZPERYEG.js.map +0 -7
- package/dist/chunks/chunk-L2FNMIOW.js.map +0 -7
- package/dist/chunks/chunk-NX4SNIMR.js.map +0 -7
- package/dist/chunks/chunk-TLSJXU4F.js.map +0 -7
- package/dist/chunks/chunk-UOSJZXJV.js.map +0 -7
- package/dist/chunks/chunk-WXZP5VWP.js.map +0 -7
- package/dist/chunks/chunk-YPYVUGON.js.map +0 -7
- package/dist/chunks/chunk-Z6HEQPXX.js.map +0 -7
- /package/dist/chunks/{chunk-B2SQR2JY.js.map → chunk-BMIE4PIL.js.map} +0 -0
- /package/dist/chunks/{chunk-CVLO4GNW.js.map → chunk-GDZDWKJS.js.map} +0 -0
- /package/dist/chunks/{chunk-2GQC324T.js.map → chunk-TSU4AEPZ.js.map} +0 -0
- /package/dist/chunks/{chunk-HDJBUXDX.js.map → chunk-WQUMHDOS.js.map} +0 -0
- /package/dist/chunks/{chunk-KIREBD2V.js.map → chunk-ZP3S74LW.js.map} +0 -0
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
MemoryProvider,
|
|
12
12
|
actionArgNormalizer,
|
|
13
13
|
uniqueDeclaredKeyForSpelling
|
|
14
|
-
} from "./chunks/chunk-
|
|
14
|
+
} from "./chunks/chunk-2WDZT27Q.js";
|
|
15
15
|
import "./chunks/chunk-2KEWFW56.js";
|
|
16
16
|
import "./chunks/chunk-U5FYOMG5.js";
|
|
17
17
|
import {
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
repairFabricGuestCode,
|
|
34
34
|
resolveFabricIdentity,
|
|
35
35
|
runFabricHandoffAtBoundary
|
|
36
|
-
} from "./chunks/chunk-
|
|
36
|
+
} from "./chunks/chunk-VSSC4IDU.js";
|
|
37
37
|
import "./chunks/chunk-7VIQNUPS.js";
|
|
38
38
|
import {
|
|
39
39
|
AgentTranscriptReader,
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
countContentLines,
|
|
42
42
|
recentTranscriptTools,
|
|
43
43
|
writeContentForPreview
|
|
44
|
-
} from "./chunks/chunk-
|
|
44
|
+
} from "./chunks/chunk-WQUMHDOS.js";
|
|
45
45
|
import "./chunks/chunk-DLXPTBPL.js";
|
|
46
46
|
import {
|
|
47
47
|
ActionRegistry,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
withExclusiveFileLockAsync
|
|
64
64
|
} from "./chunks/chunk-YWEXP724.js";
|
|
65
65
|
import "./chunks/chunk-4A4MVZQW.js";
|
|
66
|
-
import "./chunks/chunk-
|
|
66
|
+
import "./chunks/chunk-FX3XLQYI.js";
|
|
67
67
|
import "./chunks/chunk-6QBPSZJ5.js";
|
|
68
68
|
import {
|
|
69
69
|
FABRIC_COMPONENT_DISCOVER_EVENT,
|
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
resolveAgentCwd,
|
|
95
95
|
resolveOmpBinary,
|
|
96
96
|
validateAgentCwdRequest
|
|
97
|
-
} from "./chunks/chunk-
|
|
97
|
+
} from "./chunks/chunk-7MFYALJI.js";
|
|
98
98
|
import "./chunks/chunk-VPPIJRNZ.js";
|
|
99
99
|
import {
|
|
100
100
|
executeFile,
|
|
@@ -104,7 +104,7 @@ import {
|
|
|
104
104
|
import "./chunks/chunk-CT2AJ2UI.js";
|
|
105
105
|
import {
|
|
106
106
|
checkedHandoffCompaction
|
|
107
|
-
} from "./chunks/chunk-
|
|
107
|
+
} from "./chunks/chunk-JOWMM3EX.js";
|
|
108
108
|
import {
|
|
109
109
|
DEFAULT_FABRIC_CONFIG,
|
|
110
110
|
FUZZY_RESOLUTION_MARKERS,
|
|
@@ -114,12 +114,12 @@ import {
|
|
|
114
114
|
resolveAgentDir,
|
|
115
115
|
resolveAvailableOmpModel,
|
|
116
116
|
resolveFabricModel
|
|
117
|
-
} from "./chunks/chunk-
|
|
117
|
+
} from "./chunks/chunk-XRJYPNTI.js";
|
|
118
118
|
import {
|
|
119
119
|
FABRIC_ACTOR_HOST_EVENTS,
|
|
120
120
|
isFabricActorHostEvent,
|
|
121
121
|
readJsonlPage
|
|
122
|
-
} from "./chunks/chunk-
|
|
122
|
+
} from "./chunks/chunk-3LI7YO4M.js";
|
|
123
123
|
import {
|
|
124
124
|
isFabricThinking
|
|
125
125
|
} from "./chunks/chunk-JSBTB3P6.js";
|
|
@@ -155,8 +155,9 @@ import {
|
|
|
155
155
|
MAX_PRESERVE_ITEM_CHARS,
|
|
156
156
|
compactionRequestBoundsError,
|
|
157
157
|
encodeCompactionRequest,
|
|
158
|
+
estimateTokens,
|
|
158
159
|
fabricExecTitleHintCached
|
|
159
|
-
} from "./chunks/chunk-
|
|
160
|
+
} from "./chunks/chunk-ZP3S74LW.js";
|
|
160
161
|
import "./chunks/chunk-3J7BKUNG.js";
|
|
161
162
|
import "./chunks/chunk-4HQDSTHN.js";
|
|
162
163
|
import {
|
|
@@ -171,7 +172,7 @@ import {
|
|
|
171
172
|
} from "./chunks/chunk-6N4XGAZY.js";
|
|
172
173
|
|
|
173
174
|
// src/fabric-runtime-state.ts
|
|
174
|
-
import
|
|
175
|
+
import path19 from "node:path";
|
|
175
176
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
176
177
|
|
|
177
178
|
// src/actors/global-registry.ts
|
|
@@ -293,6 +294,7 @@ var GlobalActorRegistry = class {
|
|
|
293
294
|
...patch.thinking !== void 0 ? { thinking: patch.thinking } : existing.thinking ? { thinking: existing.thinking } : {},
|
|
294
295
|
...patch.tools !== void 0 ? { tools: patch.tools } : existing.tools ? { tools: existing.tools } : {},
|
|
295
296
|
...patch.transport !== void 0 ? { transport: patch.transport } : existing.transport ? { transport: existing.transport } : {},
|
|
297
|
+
...patch.cwd !== void 0 ? { cwd: patch.cwd } : existing.cwd ? { cwd: existing.cwd } : {},
|
|
296
298
|
...patch.timeoutMs !== void 0 ? { timeoutMs: patch.timeoutMs } : existing.timeoutMs ? { timeoutMs: existing.timeoutMs } : {},
|
|
297
299
|
...patch.extensions !== void 0 ? { extensions: patch.extensions } : typeof existing.extensions === "boolean" ? { extensions: existing.extensions } : {},
|
|
298
300
|
...patch.validWhile !== void 0 ? { validWhile: patch.validWhile } : existing.validWhile ? { validWhile: existing.validWhile } : {}
|
|
@@ -346,6 +348,7 @@ var GlobalActorRegistry = class {
|
|
|
346
348
|
...def.thinking ? { thinking: def.thinking } : {},
|
|
347
349
|
...def.tools ? { tools: [...def.tools] } : {},
|
|
348
350
|
...def.transport ? { transport: def.transport } : {},
|
|
351
|
+
...def.cwd ? { cwd: def.cwd } : {},
|
|
349
352
|
...def.timeoutMs ? { timeoutMs: def.timeoutMs } : {},
|
|
350
353
|
...typeof def.extensions === "boolean" ? { extensions: def.extensions } : {},
|
|
351
354
|
...def.validWhile ? { validWhile: clone(def.validWhile) } : {}
|
|
@@ -386,6 +389,7 @@ var GlobalActorRegistry = class {
|
|
|
386
389
|
const thinking = def.thinking !== void 0 && isFabricThinking(def.thinking) ? def.thinking : void 0;
|
|
387
390
|
const tools = Array.isArray(def.tools) ? [...new Set(def.tools.filter((tool) => typeof tool === "string"))] : void 0;
|
|
388
391
|
const transport = def.transport !== void 0 && TRANSPORTS.has(def.transport) ? def.transport : void 0;
|
|
392
|
+
const cwd = typeof def.cwd === "string" && def.cwd.trim().length > 0 ? def.cwd : void 0;
|
|
389
393
|
const timeoutMs = typeof def.timeoutMs === "number" ? def.timeoutMs : void 0;
|
|
390
394
|
const extensions = typeof def.extensions === "boolean" ? def.extensions : void 0;
|
|
391
395
|
const requires = normalizeRequirements(def.requires);
|
|
@@ -406,6 +410,7 @@ var GlobalActorRegistry = class {
|
|
|
406
410
|
...thinking ? { thinking } : {},
|
|
407
411
|
...tools ? { tools } : {},
|
|
408
412
|
...transport ? { transport } : {},
|
|
413
|
+
...cwd ? { cwd } : {},
|
|
409
414
|
...timeoutMs ? { timeoutMs } : {},
|
|
410
415
|
...extensions !== void 0 ? { extensions } : {},
|
|
411
416
|
...requires && requires.length > 0 ? { requires } : {},
|
|
@@ -425,36 +430,37 @@ var GlobalActorRegistry = class {
|
|
|
425
430
|
if (!Array.isArray(records)) return;
|
|
426
431
|
for (const value of records) {
|
|
427
432
|
if (typeof value !== "object" || value === null || Array.isArray(value)) continue;
|
|
428
|
-
const
|
|
429
|
-
if (typeof
|
|
433
|
+
const record2 = value;
|
|
434
|
+
if (typeof record2.id !== "string" || !/^[a-f0-9]{32}$/.test(record2.id) || typeof record2.name !== "string" || !ACTOR_NAME_PATTERN.test(record2.name) || typeof record2.instructions !== "string" || Buffer.byteLength(record2.instructions, "utf8") > this.#maxBytes || typeof record2.createdAt !== "number") {
|
|
430
435
|
continue;
|
|
431
436
|
}
|
|
432
|
-
const events = Array.isArray(
|
|
433
|
-
const topics = Array.isArray(
|
|
437
|
+
const events = Array.isArray(record2.events) ? record2.events.filter((event) => HOST_EVENTS.has(event)) : [];
|
|
438
|
+
const topics = Array.isArray(record2.topics) ? record2.topics.filter(
|
|
434
439
|
(topic) => typeof topic === "string" && TOPIC_PATTERN.test(topic)
|
|
435
440
|
) : [];
|
|
436
|
-
const delivery =
|
|
437
|
-
const responseMode =
|
|
438
|
-
const triggerTurn = (delivery === "steer" || delivery === "followUp") &&
|
|
439
|
-
const coalesce =
|
|
440
|
-
const residency =
|
|
441
|
-
const runner =
|
|
442
|
-
const thinking = isFabricThinking(
|
|
443
|
-
const tools = Array.isArray(
|
|
444
|
-
const transport =
|
|
445
|
-
const
|
|
446
|
-
const
|
|
441
|
+
const delivery = record2.delivery === "steer" || record2.delivery === "followUp" || record2.delivery === "nextTurn" ? record2.delivery : "mailbox";
|
|
442
|
+
const responseMode = record2.responseMode === "directive" ? "directive" : "text";
|
|
443
|
+
const triggerTurn = (delivery === "steer" || delivery === "followUp") && record2.triggerTurn === true;
|
|
444
|
+
const coalesce = record2.coalesce !== false;
|
|
445
|
+
const residency = record2.residency === "durable" ? "durable" : "session";
|
|
446
|
+
const runner = record2.runner === "claude" ? "claude" : "omp";
|
|
447
|
+
const thinking = isFabricThinking(record2.thinking) ? record2.thinking : void 0;
|
|
448
|
+
const tools = Array.isArray(record2.tools) ? record2.tools.filter((tool) => typeof tool === "string") : void 0;
|
|
449
|
+
const transport = record2.transport !== void 0 && TRANSPORTS.has(record2.transport) ? record2.transport : void 0;
|
|
450
|
+
const cwd = typeof record2.cwd === "string" && record2.cwd.trim().length > 0 ? record2.cwd : void 0;
|
|
451
|
+
const timeoutMs = typeof record2.timeoutMs === "number" ? record2.timeoutMs : void 0;
|
|
452
|
+
const extensions = typeof record2.extensions === "boolean" ? record2.extensions : void 0;
|
|
447
453
|
let requires;
|
|
448
454
|
try {
|
|
449
|
-
requires = normalizeRequirements(
|
|
455
|
+
requires = normalizeRequirements(record2.requires);
|
|
450
456
|
} catch {
|
|
451
457
|
continue;
|
|
452
458
|
}
|
|
453
|
-
const validWhile =
|
|
459
|
+
const validWhile = record2.validWhile?.version === 1 && typeof record2.validWhile.source === "string" && record2.validWhile.source.length <= 16e3 ? clone(record2.validWhile) : void 0;
|
|
454
460
|
const def = {
|
|
455
|
-
id:
|
|
456
|
-
name:
|
|
457
|
-
instructions:
|
|
461
|
+
id: record2.id,
|
|
462
|
+
name: record2.name,
|
|
463
|
+
instructions: record2.instructions,
|
|
458
464
|
events,
|
|
459
465
|
topics,
|
|
460
466
|
delivery,
|
|
@@ -463,12 +469,13 @@ var GlobalActorRegistry = class {
|
|
|
463
469
|
coalesce,
|
|
464
470
|
residency,
|
|
465
471
|
runner,
|
|
466
|
-
createdAt:
|
|
467
|
-
updatedAt: typeof
|
|
468
|
-
...typeof
|
|
472
|
+
createdAt: record2.createdAt,
|
|
473
|
+
updatedAt: typeof record2.updatedAt === "number" ? record2.updatedAt : record2.createdAt,
|
|
474
|
+
...typeof record2.model === "string" && record2.model ? { model: record2.model } : {},
|
|
469
475
|
...thinking ? { thinking } : {},
|
|
470
476
|
...tools ? { tools } : {},
|
|
471
477
|
...transport ? { transport } : {},
|
|
478
|
+
...cwd ? { cwd } : {},
|
|
472
479
|
...timeoutMs ? { timeoutMs } : {},
|
|
473
480
|
...extensions !== void 0 ? { extensions } : {},
|
|
474
481
|
...requires && requires.length > 0 ? { requires } : {},
|
|
@@ -793,10 +800,10 @@ var normalizeRegistration = (registration, fallbackLabel) => {
|
|
|
793
800
|
}
|
|
794
801
|
};
|
|
795
802
|
};
|
|
796
|
-
var beginCleanup = (
|
|
797
|
-
if (
|
|
798
|
-
|
|
799
|
-
|
|
803
|
+
var beginCleanup = (record2) => {
|
|
804
|
+
if (record2.cleanupStarted) return;
|
|
805
|
+
record2.cleanupStarted = true;
|
|
806
|
+
record2.beforeCleanup?.();
|
|
800
807
|
};
|
|
801
808
|
var closeIterator = async (iterator, disposers) => {
|
|
802
809
|
if (!iterator.return) return;
|
|
@@ -809,20 +816,20 @@ var closeIterator = async (iterator, disposers) => {
|
|
|
809
816
|
var checkTarget = async (guard) => {
|
|
810
817
|
if (guard && !await guard()) throw new FabricEffectDivertedError();
|
|
811
818
|
};
|
|
812
|
-
var driveIterator = async (iterator,
|
|
819
|
+
var driveIterator = async (iterator, record2, guard) => {
|
|
813
820
|
try {
|
|
814
821
|
for (; ; ) {
|
|
815
|
-
if (!
|
|
816
|
-
beginCleanup(
|
|
817
|
-
await closeIterator(iterator,
|
|
822
|
+
if (!record2.armed) {
|
|
823
|
+
beginCleanup(record2);
|
|
824
|
+
await closeIterator(iterator, record2.disposers);
|
|
818
825
|
return;
|
|
819
826
|
}
|
|
820
827
|
await checkTarget(guard);
|
|
821
828
|
const step = await iterator.next();
|
|
822
|
-
if (!step.done) collectDisposer(step.value,
|
|
823
|
-
if (!
|
|
824
|
-
beginCleanup(
|
|
825
|
-
await closeIterator(iterator,
|
|
829
|
+
if (!step.done) collectDisposer(step.value, record2.disposers);
|
|
830
|
+
if (!record2.armed) {
|
|
831
|
+
beginCleanup(record2);
|
|
832
|
+
await closeIterator(iterator, record2.disposers);
|
|
826
833
|
return;
|
|
827
834
|
}
|
|
828
835
|
if (step.done) {
|
|
@@ -833,8 +840,8 @@ var driveIterator = async (iterator, record, guard) => {
|
|
|
833
840
|
} catch (error) {
|
|
834
841
|
if (error instanceof FabricEffectDivertedError) {
|
|
835
842
|
try {
|
|
836
|
-
beginCleanup(
|
|
837
|
-
await closeIterator(iterator,
|
|
843
|
+
beginCleanup(record2);
|
|
844
|
+
await closeIterator(iterator, record2.disposers);
|
|
838
845
|
} catch (closeError) {
|
|
839
846
|
throw new FabricEffectDivertedError(
|
|
840
847
|
"Fabric effect target changed and iterator close failed",
|
|
@@ -845,19 +852,19 @@ var driveIterator = async (iterator, record, guard) => {
|
|
|
845
852
|
throw error;
|
|
846
853
|
}
|
|
847
854
|
};
|
|
848
|
-
var collectEffect = async (effect,
|
|
855
|
+
var collectEffect = async (effect, record2, guard) => {
|
|
849
856
|
const resolved = isPromiseLike(effect) ? await effect : effect;
|
|
850
857
|
if (resolved === void 0 || resolved === null || typeof resolved === "function") {
|
|
851
|
-
collectDisposer(resolved,
|
|
852
|
-
if (
|
|
858
|
+
collectDisposer(resolved, record2.disposers);
|
|
859
|
+
if (record2.armed) await checkTarget(guard);
|
|
853
860
|
return;
|
|
854
861
|
}
|
|
855
862
|
if (isAsyncIterable(resolved)) {
|
|
856
|
-
await driveIterator(resolved[Symbol.asyncIterator](),
|
|
863
|
+
await driveIterator(resolved[Symbol.asyncIterator](), record2, guard);
|
|
857
864
|
return;
|
|
858
865
|
}
|
|
859
866
|
if (isIterable(resolved)) {
|
|
860
|
-
await driveIterator(resolved[Symbol.iterator](),
|
|
867
|
+
await driveIterator(resolved[Symbol.iterator](), record2, guard);
|
|
861
868
|
return;
|
|
862
869
|
}
|
|
863
870
|
throw new TypeError("Fabric effect returned an unsupported value");
|
|
@@ -876,10 +883,10 @@ var FabricEffectScope = class {
|
|
|
876
883
|
}
|
|
877
884
|
footprint(limit = Number.POSITIVE_INFINITY) {
|
|
878
885
|
const effects = [];
|
|
879
|
-
for (const
|
|
886
|
+
for (const record2 of this.#records) {
|
|
880
887
|
if (effects.length >= limit) break;
|
|
881
|
-
if (!
|
|
882
|
-
effects.push({ ...
|
|
888
|
+
if (!record2.disposed && record2.effect) {
|
|
889
|
+
effects.push({ ...record2.effect, resources: [...record2.effect.resources] });
|
|
883
890
|
}
|
|
884
891
|
}
|
|
885
892
|
return effects;
|
|
@@ -889,7 +896,7 @@ var FabricEffectScope = class {
|
|
|
889
896
|
throw new Error("Cannot create an effect on a disposing Fabric scope");
|
|
890
897
|
}
|
|
891
898
|
const normalized = normalizeRegistration(registration, "anonymous");
|
|
892
|
-
const
|
|
899
|
+
const record2 = {
|
|
893
900
|
label: normalized.label,
|
|
894
901
|
...normalized.effect ? { effect: normalized.effect } : {},
|
|
895
902
|
disposers: [],
|
|
@@ -902,9 +909,9 @@ var FabricEffectScope = class {
|
|
|
902
909
|
...hooks.beforeCleanup ? { beforeCleanup: hooks.beforeCleanup } : {}
|
|
903
910
|
};
|
|
904
911
|
const cleanupDisposers = async () => {
|
|
905
|
-
beginCleanup(
|
|
912
|
+
beginCleanup(record2);
|
|
906
913
|
const failures = [];
|
|
907
|
-
for (const disposer of
|
|
914
|
+
for (const disposer of record2.disposers.splice(0).reverse()) {
|
|
908
915
|
try {
|
|
909
916
|
await disposer();
|
|
910
917
|
} catch (error) {
|
|
@@ -912,64 +919,64 @@ var FabricEffectScope = class {
|
|
|
912
919
|
}
|
|
913
920
|
}
|
|
914
921
|
if (failures.length > 0) {
|
|
915
|
-
throw new AggregateError(failures, `Fabric effect cleanup failed: ${
|
|
922
|
+
throw new AggregateError(failures, `Fabric effect cleanup failed: ${record2.label}`);
|
|
916
923
|
}
|
|
917
924
|
};
|
|
918
925
|
let disposal;
|
|
919
|
-
|
|
920
|
-
if (
|
|
921
|
-
|
|
922
|
-
|
|
926
|
+
record2.dispose = async () => {
|
|
927
|
+
if (record2.disposed) return disposal;
|
|
928
|
+
record2.disposed = true;
|
|
929
|
+
record2.armed = false;
|
|
923
930
|
disposal = (async () => {
|
|
924
|
-
await
|
|
931
|
+
await record2.setup.catch(() => void 0);
|
|
925
932
|
await cleanupDisposers();
|
|
926
933
|
})();
|
|
927
934
|
return disposal;
|
|
928
935
|
};
|
|
929
|
-
this.#records.push(
|
|
930
|
-
|
|
936
|
+
this.#records.push(record2);
|
|
937
|
+
record2.setup = (async () => {
|
|
931
938
|
try {
|
|
932
939
|
if (this.#guard) await checkTarget(this.#guard);
|
|
933
|
-
if (!
|
|
934
|
-
await collectEffect(setup(),
|
|
940
|
+
if (!record2.armed) return;
|
|
941
|
+
await collectEffect(setup(), record2, this.#guard);
|
|
935
942
|
} catch (error) {
|
|
936
943
|
try {
|
|
937
944
|
await cleanupDisposers();
|
|
938
945
|
} catch (cleanupError) {
|
|
939
946
|
const failures = cleanupError instanceof AggregateError ? cleanupError.errors : [cleanupError];
|
|
940
947
|
for (const failure of failures) {
|
|
941
|
-
this.#setupCleanupFailures.push({ label:
|
|
948
|
+
this.#setupCleanupFailures.push({ label: record2.label, error: errorMessage(failure) });
|
|
942
949
|
}
|
|
943
950
|
throw new AggregateError(
|
|
944
951
|
[error, cleanupError],
|
|
945
|
-
`Fabric effect setup and rollback failed: ${
|
|
952
|
+
`Fabric effect setup and rollback failed: ${record2.label}`
|
|
946
953
|
);
|
|
947
954
|
}
|
|
948
955
|
throw error;
|
|
949
956
|
}
|
|
950
957
|
})();
|
|
951
958
|
try {
|
|
952
|
-
await
|
|
959
|
+
await record2.setup;
|
|
953
960
|
if (this.#state === "open") {
|
|
954
|
-
const index = this.#records.indexOf(
|
|
961
|
+
const index = this.#records.indexOf(record2);
|
|
955
962
|
if (index >= 0 && index !== this.#records.length - 1) {
|
|
956
963
|
this.#records.splice(index, 1);
|
|
957
|
-
this.#records.push(
|
|
964
|
+
this.#records.push(record2);
|
|
958
965
|
}
|
|
959
966
|
}
|
|
960
967
|
} catch (error) {
|
|
961
|
-
const index = this.#records.indexOf(
|
|
968
|
+
const index = this.#records.indexOf(record2);
|
|
962
969
|
if (index >= 0) this.#records.splice(index, 1);
|
|
963
970
|
throw error;
|
|
964
971
|
}
|
|
965
|
-
return
|
|
972
|
+
return record2.dispose;
|
|
966
973
|
}
|
|
967
974
|
defer(disposer, registration = "deferred") {
|
|
968
975
|
if (this.#state !== "open") {
|
|
969
976
|
throw new Error("Cannot defer cleanup on a disposing Fabric scope");
|
|
970
977
|
}
|
|
971
978
|
const normalized = normalizeRegistration(registration, "deferred");
|
|
972
|
-
const
|
|
979
|
+
const record2 = {
|
|
973
980
|
label: normalized.label,
|
|
974
981
|
...normalized.effect ? { effect: normalized.effect } : {},
|
|
975
982
|
disposers: [disposer],
|
|
@@ -981,13 +988,13 @@ var FabricEffectScope = class {
|
|
|
981
988
|
cleanupStarted: false
|
|
982
989
|
};
|
|
983
990
|
let disposal;
|
|
984
|
-
|
|
985
|
-
if (
|
|
986
|
-
|
|
987
|
-
|
|
991
|
+
record2.dispose = async () => {
|
|
992
|
+
if (record2.disposed) return disposal;
|
|
993
|
+
record2.disposed = true;
|
|
994
|
+
record2.armed = false;
|
|
988
995
|
disposal = (async () => {
|
|
989
996
|
const failures = [];
|
|
990
|
-
for (const cleanup of
|
|
997
|
+
for (const cleanup of record2.disposers.splice(0).reverse()) {
|
|
991
998
|
try {
|
|
992
999
|
await cleanup();
|
|
993
1000
|
} catch (error) {
|
|
@@ -995,29 +1002,29 @@ var FabricEffectScope = class {
|
|
|
995
1002
|
}
|
|
996
1003
|
}
|
|
997
1004
|
if (failures.length > 0) {
|
|
998
|
-
throw new AggregateError(failures, `Fabric effect cleanup failed: ${
|
|
1005
|
+
throw new AggregateError(failures, `Fabric effect cleanup failed: ${record2.label}`);
|
|
999
1006
|
}
|
|
1000
1007
|
})();
|
|
1001
1008
|
return disposal;
|
|
1002
1009
|
};
|
|
1003
|
-
this.#records.push(
|
|
1004
|
-
return
|
|
1010
|
+
this.#records.push(record2);
|
|
1011
|
+
return record2.dispose;
|
|
1005
1012
|
}
|
|
1006
1013
|
dispose() {
|
|
1007
1014
|
if (this.#cleanup) return this.#cleanup;
|
|
1008
1015
|
this.#state = "disposing";
|
|
1009
1016
|
this.#cleanup = (async () => {
|
|
1010
1017
|
const failures = this.#setupCleanupFailures.splice(0);
|
|
1011
|
-
for (const
|
|
1018
|
+
for (const record2 of this.#records.splice(0).reverse()) {
|
|
1012
1019
|
try {
|
|
1013
|
-
await
|
|
1020
|
+
await record2.dispose();
|
|
1014
1021
|
} catch (error) {
|
|
1015
1022
|
if (error instanceof AggregateError) {
|
|
1016
1023
|
for (const nested of error.errors) {
|
|
1017
|
-
failures.push({ label:
|
|
1024
|
+
failures.push({ label: record2.label, error: errorMessage(nested) });
|
|
1018
1025
|
}
|
|
1019
1026
|
} else {
|
|
1020
|
-
failures.push({ label:
|
|
1027
|
+
failures.push({ label: record2.label, error: errorMessage(error) });
|
|
1021
1028
|
}
|
|
1022
1029
|
}
|
|
1023
1030
|
}
|
|
@@ -2218,10 +2225,10 @@ var FabricComponentSupervisor = class {
|
|
|
2218
2225
|
adjacent.set(edge.from, targets);
|
|
2219
2226
|
}
|
|
2220
2227
|
const cycles = /* @__PURE__ */ new Map();
|
|
2221
|
-
const visit = (node,
|
|
2228
|
+
const visit = (node, path20, positions) => {
|
|
2222
2229
|
const position = positions.get(node);
|
|
2223
2230
|
if (position !== void 0) {
|
|
2224
|
-
const cycle =
|
|
2231
|
+
const cycle = path20.slice(position);
|
|
2225
2232
|
const rotations = cycle.map((_, index) => [
|
|
2226
2233
|
...cycle.slice(index),
|
|
2227
2234
|
...cycle.slice(0, index)
|
|
@@ -2231,10 +2238,10 @@ var FabricComponentSupervisor = class {
|
|
|
2231
2238
|
cycles.set(canonical.join("\0"), canonical);
|
|
2232
2239
|
return;
|
|
2233
2240
|
}
|
|
2234
|
-
if (
|
|
2235
|
-
const nextPositions = new Map(positions).set(node,
|
|
2241
|
+
if (path20.length > this.#components.size) return;
|
|
2242
|
+
const nextPositions = new Map(positions).set(node, path20.length);
|
|
2236
2243
|
for (const target of adjacent.get(node) ?? []) {
|
|
2237
|
-
visit(target, [...
|
|
2244
|
+
visit(target, [...path20, node], nextPositions);
|
|
2238
2245
|
}
|
|
2239
2246
|
};
|
|
2240
2247
|
for (const id of this.#components.keys()) visit(id, [], /* @__PURE__ */ new Map());
|
|
@@ -2736,18 +2743,18 @@ var finiteNumber = (value) => typeof value === "number" && Number.isFinite(value
|
|
|
2736
2743
|
var nonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2737
2744
|
var decodeOutcome = (raw) => {
|
|
2738
2745
|
if (typeof raw !== "object" || raw === null) return void 0;
|
|
2739
|
-
const
|
|
2740
|
-
const at = finiteNumber(
|
|
2741
|
-
const requestedBy = nonEmptyString(
|
|
2742
|
-
const status =
|
|
2746
|
+
const record2 = raw;
|
|
2747
|
+
const at = finiteNumber(record2.at);
|
|
2748
|
+
const requestedBy = nonEmptyString(record2.requestedBy);
|
|
2749
|
+
const status = record2.status;
|
|
2743
2750
|
if (at === void 0 || requestedBy === void 0) return void 0;
|
|
2744
2751
|
if (status !== "committed" && status !== "cancelled" && status !== "failed" && status !== "skipped") {
|
|
2745
2752
|
return void 0;
|
|
2746
2753
|
}
|
|
2747
|
-
const summary = nonEmptyString(
|
|
2748
|
-
const error = nonEmptyString(
|
|
2749
|
-
const tokensBefore = finiteNumber(
|
|
2750
|
-
const estimatedTokensAfter = finiteNumber(
|
|
2754
|
+
const summary = nonEmptyString(record2.summary);
|
|
2755
|
+
const error = nonEmptyString(record2.error);
|
|
2756
|
+
const tokensBefore = finiteNumber(record2.tokensBefore);
|
|
2757
|
+
const estimatedTokensAfter = finiteNumber(record2.estimatedTokensAfter);
|
|
2751
2758
|
return {
|
|
2752
2759
|
at,
|
|
2753
2760
|
requestedBy,
|
|
@@ -2964,7 +2971,7 @@ var FabricExecutionService = class {
|
|
|
2964
2971
|
})) ?? []
|
|
2965
2972
|
) : void 0;
|
|
2966
2973
|
const code = repairFabricGuestCode(options.code);
|
|
2967
|
-
const
|
|
2974
|
+
const checked2 = dependencies.typeCheckFabricCode(
|
|
2968
2975
|
code,
|
|
2969
2976
|
dependencies.guestTypeDeclarations(effectiveFullCodeMode, {
|
|
2970
2977
|
excludeGlobals: [...unavailable.keys()],
|
|
@@ -2972,8 +2979,8 @@ var FabricExecutionService = class {
|
|
|
2972
2979
|
...coreOverrideDeclarations ? { coreOverrides: coreOverrideDeclarations } : {}
|
|
2973
2980
|
})
|
|
2974
2981
|
);
|
|
2975
|
-
if (
|
|
2976
|
-
for (const error of
|
|
2982
|
+
if (checked2.errors.length > 0) {
|
|
2983
|
+
for (const error of checked2.errors) {
|
|
2977
2984
|
const missing = /^Cannot find name '([^']+)'/.exec(error.message);
|
|
2978
2985
|
const reason = missing?.[1] ? unavailable.get(missing[1]) : void 0;
|
|
2979
2986
|
if (missing && reason) {
|
|
@@ -2990,10 +2997,10 @@ var FabricExecutionService = class {
|
|
|
2990
2997
|
trace: traceRecorder.seal(
|
|
2991
2998
|
"failed",
|
|
2992
2999
|
[],
|
|
2993
|
-
`Type checking failed (${
|
|
3000
|
+
`Type checking failed (${checked2.errors.length} ${checked2.errors.length === 1 ? "error" : "errors"})`
|
|
2994
3001
|
),
|
|
2995
3002
|
elapsedMs: performance.now() - startedAt,
|
|
2996
|
-
typeErrors:
|
|
3003
|
+
typeErrors: checked2.errors
|
|
2997
3004
|
};
|
|
2998
3005
|
}
|
|
2999
3006
|
const classifierUsages = [];
|
|
@@ -3424,8 +3431,8 @@ var FabricExecutionService = class {
|
|
|
3424
3431
|
memoryLimitBytes: this.config.executor.memoryLimitBytes,
|
|
3425
3432
|
maxLogChars: this.config.executor.maxOutputChars,
|
|
3426
3433
|
minimumTimeoutMsForHostCall,
|
|
3427
|
-
...
|
|
3428
|
-
...
|
|
3434
|
+
...checked2.javascript ? { transpiledCode: checked2.javascript } : {},
|
|
3435
|
+
...checked2.sourceMap ? { transpiledSourceMap: checked2.sourceMap } : {},
|
|
3429
3436
|
...options.payloads ? { payloads: options.payloads } : {},
|
|
3430
3437
|
...Object.keys(proxyNames).length > 0 ? { proxyNames } : {},
|
|
3431
3438
|
...options.tokenBudget !== void 0 ? { tokenBudget: options.tokenBudget } : {},
|
|
@@ -4197,9 +4204,28 @@ var runProperties = {
|
|
|
4197
4204
|
enum: ["off", "minimal", "low", "medium", "high", "xhigh", "max"]
|
|
4198
4205
|
},
|
|
4199
4206
|
tools: { type: "array", items: { type: "string" } },
|
|
4207
|
+
addTools: {
|
|
4208
|
+
type: "array",
|
|
4209
|
+
items: { type: "string" },
|
|
4210
|
+
description: "Extra tools merged onto the resolved tool list instead of replacing it; use with or without tools."
|
|
4211
|
+
},
|
|
4212
|
+
images: {
|
|
4213
|
+
type: "array",
|
|
4214
|
+
description: "Image blocks delivered with the task on the child agent's first turn.",
|
|
4215
|
+
items: {
|
|
4216
|
+
type: "object",
|
|
4217
|
+
properties: {
|
|
4218
|
+
type: { const: "image" },
|
|
4219
|
+
data: { type: "string", description: "Base64-encoded image bytes." },
|
|
4220
|
+
mimeType: { type: "string" }
|
|
4221
|
+
},
|
|
4222
|
+
required: ["type", "data", "mimeType"],
|
|
4223
|
+
additionalProperties: false
|
|
4224
|
+
}
|
|
4225
|
+
},
|
|
4200
4226
|
timeoutMs: {
|
|
4201
4227
|
type: "number",
|
|
4202
|
-
description: "Optional
|
|
4228
|
+
description: "Optional wall-clock limit in milliseconds, raising or lowering agents.timeoutMs (60 minutes by default). Clamped to the supported range of 1 second to 24 hours."
|
|
4203
4229
|
},
|
|
4204
4230
|
extensions: { type: "boolean" },
|
|
4205
4231
|
recursive: { type: "boolean" },
|
|
@@ -4492,6 +4518,10 @@ var AGENTS_ACTION_DESCRIPTORS = [
|
|
|
4492
4518
|
thinking: runProperties.thinking,
|
|
4493
4519
|
tools: runProperties.tools,
|
|
4494
4520
|
transport: runProperties.transport,
|
|
4521
|
+
cwd: {
|
|
4522
|
+
...runProperties.cwd,
|
|
4523
|
+
description: "Filesystem execution directory for every activation; relative paths resolve from the host cwd. An OMP actor must also pass extensions: false, because recursive Fabric activations do not support cwd."
|
|
4524
|
+
},
|
|
4495
4525
|
timeoutMs: runProperties.timeoutMs,
|
|
4496
4526
|
extensions: runProperties.extensions,
|
|
4497
4527
|
requires: {
|
|
@@ -5032,10 +5062,10 @@ var ResidencyClient = class {
|
|
|
5032
5062
|
statusAgent(id) {
|
|
5033
5063
|
const metadata = this.#metadata(id);
|
|
5034
5064
|
if (!metadata) throw new Error(`Unknown durable Fabric agent: ${id}`);
|
|
5035
|
-
const
|
|
5036
|
-
if (!
|
|
5065
|
+
const record2 = readJson(path5.join(metadata.runDirectory, "status.json"));
|
|
5066
|
+
if (!record2 || record2.id !== metadata.id) return structuredClone(metadata.handle);
|
|
5037
5067
|
return {
|
|
5038
|
-
...
|
|
5068
|
+
...record2,
|
|
5039
5069
|
cwd: metadata.handle.cwd,
|
|
5040
5070
|
residency: "durable",
|
|
5041
5071
|
logFile: path5.join(metadata.runDirectory, "events.jsonl"),
|
|
@@ -5286,27 +5316,37 @@ var actorRunBinding = (args) => ({
|
|
|
5286
5316
|
...typeof args.model === "string" && args.model.trim() ? { model: args.model.trim() } : {},
|
|
5287
5317
|
...isFabricThinking(args.thinking) ? { thinking: args.thinking } : {}
|
|
5288
5318
|
});
|
|
5289
|
-
var
|
|
5319
|
+
var imageContents = (value) => {
|
|
5320
|
+
if (!Array.isArray(value)) return void 0;
|
|
5321
|
+
const images = value.filter(
|
|
5322
|
+
(entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry) && entry.type === "image" && typeof entry.data === "string" && typeof entry.mimeType === "string"
|
|
5323
|
+
);
|
|
5324
|
+
return images.length > 0 ? images : void 0;
|
|
5325
|
+
};
|
|
5326
|
+
var boundedTimeoutOverride = (value, manager) => {
|
|
5290
5327
|
if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
|
|
5291
|
-
|
|
5292
|
-
return effective > manager.config.timeoutMs ? effective : void 0;
|
|
5328
|
+
return effectiveAgentTimeoutMs(manager.config.timeoutMs, value);
|
|
5293
5329
|
};
|
|
5294
5330
|
var runRequest = (args, context, manager, options = {}) => {
|
|
5295
5331
|
const transport = args.transport === "auto" || args.transport === "process" || args.transport === "tmux" || args.transport === "screen" || args.transport === "localterm" || args.transport === "herdr" ? args.transport : void 0;
|
|
5296
5332
|
const thinking = isFabricThinking(args.thinking) ? args.thinking : void 0;
|
|
5297
5333
|
const tools = stringArray(args.tools);
|
|
5298
|
-
const
|
|
5334
|
+
const addTools = stringArray(args.addTools);
|
|
5335
|
+
const images = imageContents(args.images);
|
|
5336
|
+
const timeoutMs = boundedTimeoutOverride(args.timeoutMs, manager);
|
|
5299
5337
|
const runner = args.runner === "omp" || args.runner === "claude" || args.runner === "veda" ? args.runner : manager.config.runner;
|
|
5300
5338
|
const inheritedModel = runner === "omp" && !manager.config.model && context.extensionContext.model ? `${context.extensionContext.model.provider}/${context.extensionContext.model.id}` : void 0;
|
|
5301
5339
|
return {
|
|
5302
5340
|
task: String(args.task),
|
|
5303
5341
|
runner,
|
|
5342
|
+
...images ? { images } : {},
|
|
5304
5343
|
...typeof args.name === "string" ? { name: args.name } : {},
|
|
5305
5344
|
...transport ? { transport } : {},
|
|
5306
5345
|
...typeof args.model === "string" ? { model: args.model } : inheritedModel ? { model: inheritedModel } : {},
|
|
5307
5346
|
...typeof args.persona === "string" && args.persona.trim() ? { persona: args.persona.trim() } : {},
|
|
5308
5347
|
...thinking ? { thinking } : {},
|
|
5309
5348
|
...tools ? { tools } : {},
|
|
5349
|
+
...addTools ? { addTools } : {},
|
|
5310
5350
|
...timeoutMs !== void 0 ? { timeoutMs } : {},
|
|
5311
5351
|
...typeof args.extensions === "boolean" ? { extensions: args.extensions } : {},
|
|
5312
5352
|
...typeof args.recursive === "boolean" ? { recursive: args.recursive } : {},
|
|
@@ -5364,7 +5404,7 @@ var actorRequest = (args, context, manager, inheritModel = true) => {
|
|
|
5364
5404
|
},
|
|
5365
5405
|
[]
|
|
5366
5406
|
) : void 0;
|
|
5367
|
-
const timeoutMs =
|
|
5407
|
+
const timeoutMs = boundedTimeoutOverride(args.timeoutMs, manager);
|
|
5368
5408
|
const validWhile = typeof args.validWhile === "object" && args.validWhile !== null && !Array.isArray(args.validWhile) && args.validWhile.version === 1 && typeof args.validWhile.source === "string" ? { version: 1, source: args.validWhile.source } : void 0;
|
|
5369
5409
|
const runner = args.runner === "omp" || args.runner === "claude" || args.runner === "veda" ? args.runner : manager.config.runner;
|
|
5370
5410
|
if (runner === "veda") {
|
|
@@ -5372,6 +5412,12 @@ var actorRequest = (args, context, manager, inheritModel = true) => {
|
|
|
5372
5412
|
'The Veda runner does not support persistent actors: Veda executes one headless prompt per invocation. Use an OMP or Claude actor, or agents.run({ runner: "veda" }).'
|
|
5373
5413
|
);
|
|
5374
5414
|
}
|
|
5415
|
+
const requestedCwd = typeof args.cwd === "string" ? args.cwd : void 0;
|
|
5416
|
+
validateAgentCwdRequest({
|
|
5417
|
+
...requestedCwd === void 0 ? {} : { cwd: requestedCwd },
|
|
5418
|
+
recursive: (typeof args.extensions === "boolean" ? args.extensions : true) && runner === "omp"
|
|
5419
|
+
});
|
|
5420
|
+
const cwd = requestedCwd === void 0 ? void 0 : manager.resolveCwd(requestedCwd);
|
|
5375
5421
|
const inheritedModel = inheritModel && runner === "omp" && !manager.config.model && context.extensionContext.model ? `${context.extensionContext.model.provider}/${context.extensionContext.model.id}` : void 0;
|
|
5376
5422
|
return {
|
|
5377
5423
|
...args.scope === "session" || args.scope === "project" ? { scope: args.scope } : {},
|
|
@@ -5389,6 +5435,7 @@ var actorRequest = (args, context, manager, inheritModel = true) => {
|
|
|
5389
5435
|
...isFabricThinking(args.thinking) ? { thinking: args.thinking } : {},
|
|
5390
5436
|
...tools ? { tools } : {},
|
|
5391
5437
|
...args.transport === "auto" || args.transport === "process" || args.transport === "tmux" || args.transport === "screen" || args.transport === "localterm" || args.transport === "herdr" ? { transport: args.transport } : {},
|
|
5438
|
+
...cwd ? { cwd } : {},
|
|
5392
5439
|
...timeoutMs !== void 0 ? { timeoutMs } : {},
|
|
5393
5440
|
...typeof args.extensions === "boolean" ? { extensions: args.extensions } : {},
|
|
5394
5441
|
...requires ? { requires } : {},
|
|
@@ -5398,20 +5445,20 @@ var actorRequest = (args, context, manager, inheritModel = true) => {
|
|
|
5398
5445
|
var collectAgentToolPreviewNodes = (records, options, depth = 0, budget = { remaining: options.maxNodes ?? AGENT_PREVIEW_TREE_MAX_NODES }) => {
|
|
5399
5446
|
const maxDepth = options.maxDepth ?? AGENT_PREVIEW_TREE_MAX_DEPTH;
|
|
5400
5447
|
const nodes = [];
|
|
5401
|
-
for (const
|
|
5448
|
+
for (const record2 of records) {
|
|
5402
5449
|
if (budget.remaining <= 0) break;
|
|
5403
5450
|
budget.remaining -= 1;
|
|
5404
|
-
const descendants = Array.isArray(
|
|
5451
|
+
const descendants = Array.isArray(record2.nestedAgents) ? record2.nestedAgents : [];
|
|
5405
5452
|
const agents = depth + 1 < maxDepth && descendants.length > 0 && budget.remaining > 0 ? collectAgentToolPreviewNodes(descendants, options, depth + 1, budget) : [];
|
|
5406
5453
|
nodes.push({
|
|
5407
|
-
id:
|
|
5408
|
-
name:
|
|
5409
|
-
status:
|
|
5410
|
-
...
|
|
5411
|
-
owner:
|
|
5412
|
-
...
|
|
5413
|
-
...
|
|
5414
|
-
tools: options.tools(
|
|
5454
|
+
id: record2.id,
|
|
5455
|
+
name: record2.actorName ?? record2.name,
|
|
5456
|
+
status: record2.status,
|
|
5457
|
+
...record2.runner === "omp" || record2.runner === "claude" || record2.runner === "veda" ? { runner: record2.runner } : {},
|
|
5458
|
+
owner: record2.actorId ? "actor" : "agent",
|
|
5459
|
+
...record2.currentTool ? { currentTool: record2.currentTool } : {},
|
|
5460
|
+
...record2.text ? { text: tailCodePoints(record2.text, AGENT_PREVIEW_TEXT_CODE_POINTS) } : {},
|
|
5461
|
+
tools: options.tools(record2),
|
|
5415
5462
|
...agents.length > 0 ? { agents } : {},
|
|
5416
5463
|
...descendants.length > agents.length ? { agentsTruncated: true } : {}
|
|
5417
5464
|
});
|
|
@@ -6457,18 +6504,18 @@ var AgentsProvider = class {
|
|
|
6457
6504
|
const scope = this.#participantScope(scopeValue, "local");
|
|
6458
6505
|
if (scope === "local") return this.manager.list();
|
|
6459
6506
|
const local = /* @__PURE__ */ new Map();
|
|
6460
|
-
const append = (
|
|
6461
|
-
local.set(
|
|
6462
|
-
if ("nestedAgents" in
|
|
6463
|
-
for (const nested of
|
|
6507
|
+
const append = (record2) => {
|
|
6508
|
+
local.set(record2.id, record2);
|
|
6509
|
+
if ("nestedAgents" in record2) {
|
|
6510
|
+
for (const nested of record2.nestedAgents ?? []) append(nested);
|
|
6464
6511
|
}
|
|
6465
6512
|
};
|
|
6466
|
-
for (const
|
|
6467
|
-
for (const
|
|
6513
|
+
for (const record2 of this.manager.list()) append(record2);
|
|
6514
|
+
for (const record2 of this.residency?.listAgents() ?? []) append(record2);
|
|
6468
6515
|
const listed = this.participants.list({ scope, kinds: ["agent"] }).map((participant) => local.get(participant.id) ?? participant);
|
|
6469
|
-
const seen = new Set(listed.map((
|
|
6470
|
-
for (const
|
|
6471
|
-
if (!seen.has(
|
|
6516
|
+
const seen = new Set(listed.map((record2) => record2.id));
|
|
6517
|
+
for (const record2 of this.residency?.listAgents() ?? []) {
|
|
6518
|
+
if (!seen.has(record2.id)) listed.push(record2);
|
|
6472
6519
|
}
|
|
6473
6520
|
return listed;
|
|
6474
6521
|
}
|
|
@@ -6624,9 +6671,9 @@ var CapturedToolsProvider = class {
|
|
|
6624
6671
|
#allowedTools = readChildToolAllowlist();
|
|
6625
6672
|
async list(request, _context) {
|
|
6626
6673
|
const query = request.query?.trim().toLowerCase();
|
|
6627
|
-
const
|
|
6628
|
-
if (!query) return
|
|
6629
|
-
return
|
|
6674
|
+
const descriptors7 = this.catalog.list().filter((entry) => !this.#allowedTools || this.#allowedTools.has(entry.name)).map(descriptorFrom);
|
|
6675
|
+
if (!query) return descriptors7;
|
|
6676
|
+
return descriptors7.filter(
|
|
6630
6677
|
(descriptor) => `${descriptor.name} ${descriptor.description} ${descriptor.namespace ?? ""}`.toLowerCase().includes(query)
|
|
6631
6678
|
);
|
|
6632
6679
|
}
|
|
@@ -6762,32 +6809,1302 @@ var CapturedToolsProvider = class {
|
|
|
6762
6809
|
}
|
|
6763
6810
|
};
|
|
6764
6811
|
|
|
6765
|
-
// src/providers/
|
|
6812
|
+
// src/providers/codemap-provider.ts
|
|
6813
|
+
import { statSync as statSync2 } from "node:fs";
|
|
6814
|
+
import path9 from "node:path";
|
|
6766
6815
|
import { Type } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
6767
6816
|
import { validateJsonSchemaValue } from "@oh-my-pi/pi-ai/utils/schema";
|
|
6768
|
-
|
|
6769
|
-
|
|
6817
|
+
|
|
6818
|
+
// src/codemap/budget.ts
|
|
6819
|
+
var KIND_LETTERS = {
|
|
6820
|
+
fn: "f",
|
|
6821
|
+
class: "c",
|
|
6822
|
+
iface: "i",
|
|
6823
|
+
type: "t",
|
|
6824
|
+
const: "v",
|
|
6825
|
+
enum: "e",
|
|
6826
|
+
method: "m"
|
|
6827
|
+
};
|
|
6828
|
+
var LEGEND = "# f=fn c=class i=iface t=type v=const e=enum m=method";
|
|
6829
|
+
var MIN_FILE_ENTRY = 8;
|
|
6830
|
+
var FOCUS_WEIGHT = 1;
|
|
6831
|
+
var CASCADE_WEIGHT = 0.6;
|
|
6832
|
+
var NAME_EXACT_SCORE = 6;
|
|
6833
|
+
var NAME_WORD_SCORE = 3;
|
|
6834
|
+
var PATH_WORD_SCORE = 4;
|
|
6835
|
+
var SUBSTRING_SCORE = 1;
|
|
6836
|
+
var MIN_SUBSTRING_LENGTH = 3;
|
|
6837
|
+
var EXPORT_PASSES = [true, false];
|
|
6838
|
+
var isUpper = (code) => code >= 65 && code <= 90;
|
|
6839
|
+
var isLower = (code) => code >= 97 && code <= 122;
|
|
6840
|
+
var isDigit = (code) => code >= 48 && code <= 57;
|
|
6841
|
+
var isWordChar = (code) => isUpper(code) || isLower(code) || isDigit(code);
|
|
6842
|
+
var compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
6843
|
+
var collectWords = (value, sink) => {
|
|
6844
|
+
let start = -1;
|
|
6845
|
+
for (let index = 0; index < value.length; index++) {
|
|
6846
|
+
const code = value.charCodeAt(index);
|
|
6847
|
+
if (!isWordChar(code)) {
|
|
6848
|
+
if (start >= 0) sink.add(value.slice(start, index).toLowerCase());
|
|
6849
|
+
start = -1;
|
|
6850
|
+
continue;
|
|
6851
|
+
}
|
|
6852
|
+
if (start < 0) {
|
|
6853
|
+
start = index;
|
|
6854
|
+
continue;
|
|
6855
|
+
}
|
|
6856
|
+
const previous = value.charCodeAt(index - 1);
|
|
6857
|
+
const next = index + 1 < value.length ? value.charCodeAt(index + 1) : 0;
|
|
6858
|
+
if (isUpper(code) && (!isUpper(previous) || isLower(next))) {
|
|
6859
|
+
sink.add(value.slice(start, index).toLowerCase());
|
|
6860
|
+
start = index;
|
|
6861
|
+
}
|
|
6862
|
+
}
|
|
6863
|
+
if (start >= 0) sink.add(value.slice(start).toLowerCase());
|
|
6864
|
+
};
|
|
6865
|
+
var focusTerms = (focus) => {
|
|
6866
|
+
if (focus === void 0 || focus.length === 0) return [];
|
|
6867
|
+
const words = /* @__PURE__ */ new Set();
|
|
6868
|
+
collectWords(focus, words);
|
|
6869
|
+
return [...words];
|
|
6870
|
+
};
|
|
6871
|
+
var lexiconFor = (group) => {
|
|
6872
|
+
const pathWords = /* @__PURE__ */ new Set();
|
|
6873
|
+
collectWords(group.file, pathWords);
|
|
6874
|
+
const names = /* @__PURE__ */ new Set();
|
|
6875
|
+
const nameWords = /* @__PURE__ */ new Set();
|
|
6876
|
+
const distinct = [];
|
|
6877
|
+
for (const symbol of group.symbols) {
|
|
6878
|
+
const lowered = symbol.name.toLowerCase();
|
|
6879
|
+
if (names.has(lowered)) continue;
|
|
6880
|
+
names.add(lowered);
|
|
6881
|
+
distinct.push(lowered);
|
|
6882
|
+
collectWords(symbol.name, nameWords);
|
|
6883
|
+
}
|
|
6884
|
+
return {
|
|
6885
|
+
pathWords,
|
|
6886
|
+
pathLower: group.file.toLowerCase(),
|
|
6887
|
+
names,
|
|
6888
|
+
nameWords,
|
|
6889
|
+
namesBlob: distinct.join("\n")
|
|
6890
|
+
};
|
|
6891
|
+
};
|
|
6892
|
+
var termScore = (term, lexicon) => {
|
|
6893
|
+
const wideEnough = term.length >= MIN_SUBSTRING_LENGTH;
|
|
6894
|
+
let score = 0;
|
|
6895
|
+
if (lexicon.names.has(term)) score += NAME_EXACT_SCORE;
|
|
6896
|
+
else if (lexicon.nameWords.has(term)) score += NAME_WORD_SCORE;
|
|
6897
|
+
else if (wideEnough && lexicon.namesBlob.includes(term)) score += SUBSTRING_SCORE;
|
|
6898
|
+
if (lexicon.pathWords.has(term)) score += PATH_WORD_SCORE;
|
|
6899
|
+
else if (wideEnough && lexicon.pathLower.includes(term)) score += SUBSTRING_SCORE;
|
|
6900
|
+
return score;
|
|
6901
|
+
};
|
|
6902
|
+
var groupByFile = (symbols) => {
|
|
6903
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
6904
|
+
for (const symbol of symbols) {
|
|
6905
|
+
let group = byFile.get(symbol.file);
|
|
6906
|
+
if (group === void 0) {
|
|
6907
|
+
group = { file: symbol.file, symbols: [], score: 0 };
|
|
6908
|
+
byFile.set(symbol.file, group);
|
|
6909
|
+
}
|
|
6910
|
+
group.symbols.push(symbol);
|
|
6911
|
+
}
|
|
6912
|
+
for (const group of byFile.values()) {
|
|
6913
|
+
group.symbols.sort((left, right) => left.line - right.line || compareText(left.name, right.name) || compareText(left.kind, right.kind));
|
|
6914
|
+
}
|
|
6915
|
+
return [...byFile.values()];
|
|
6916
|
+
};
|
|
6917
|
+
var applyFocus = (groups, focus) => {
|
|
6918
|
+
const terms = focusTerms(focus);
|
|
6919
|
+
if (terms.length === 0) return;
|
|
6920
|
+
let peak = 0;
|
|
6921
|
+
for (const group of groups) {
|
|
6922
|
+
const lexicon = lexiconFor(group);
|
|
6923
|
+
let raw = 0;
|
|
6924
|
+
for (const term of terms) raw += termScore(term, lexicon);
|
|
6925
|
+
group.score = raw;
|
|
6926
|
+
if (raw > peak) peak = raw;
|
|
6927
|
+
}
|
|
6928
|
+
for (const group of groups) group.score = peak > 0 ? group.score / peak * FOCUS_WEIGHT : 0;
|
|
6929
|
+
};
|
|
6930
|
+
var applyCascade = (groups, request) => {
|
|
6931
|
+
const edges = request.cascade?.edges;
|
|
6932
|
+
if (edges === void 0 || edges.length === 0) return;
|
|
6933
|
+
const best = /* @__PURE__ */ new Map();
|
|
6934
|
+
let peak = 0;
|
|
6935
|
+
for (const edge of edges) {
|
|
6936
|
+
if (edge.score > peak) peak = edge.score;
|
|
6937
|
+
const previous = best.get(edge.file);
|
|
6938
|
+
if (previous === void 0 || edge.score > previous) best.set(edge.file, edge.score);
|
|
6939
|
+
}
|
|
6940
|
+
if (peak <= 0) return;
|
|
6941
|
+
for (const group of groups) {
|
|
6942
|
+
const edgeScore = best.get(group.file);
|
|
6943
|
+
if (edgeScore !== void 0 && edgeScore > 0) {
|
|
6944
|
+
group.score += edgeScore / peak * CASCADE_WEIGHT;
|
|
6945
|
+
}
|
|
6946
|
+
}
|
|
6947
|
+
};
|
|
6948
|
+
var rankGroups = (groups, request) => {
|
|
6949
|
+
applyFocus(groups, request.focus);
|
|
6950
|
+
applyCascade(groups, request);
|
|
6951
|
+
groups.sort((left, right) => right.score - left.score || right.symbols.length - left.symbols.length || compareText(left.file, right.file));
|
|
6952
|
+
};
|
|
6953
|
+
var spend = (groups, charBudget, reserved) => {
|
|
6954
|
+
const lines = [];
|
|
6955
|
+
let used = reserved;
|
|
6956
|
+
let filesShown = 0;
|
|
6957
|
+
let symbolsShown = 0;
|
|
6958
|
+
let omittedFiles = 0;
|
|
6959
|
+
let omittedSymbols = 0;
|
|
6960
|
+
for (const group of groups) {
|
|
6961
|
+
const headerCost = group.file.length + 1;
|
|
6962
|
+
if (used + headerCost >= charBudget) {
|
|
6963
|
+
omittedFiles++;
|
|
6964
|
+
omittedSymbols += group.symbols.length;
|
|
6965
|
+
continue;
|
|
6966
|
+
}
|
|
6967
|
+
const rendered = new Array(group.symbols.length);
|
|
6968
|
+
const picked = [];
|
|
6969
|
+
let cost = headerCost;
|
|
6970
|
+
for (const exported of EXPORT_PASSES) {
|
|
6971
|
+
for (let index = 0; index < group.symbols.length; index++) {
|
|
6972
|
+
const symbol = group.symbols[index];
|
|
6973
|
+
if (symbol.exported !== exported) continue;
|
|
6974
|
+
let line = rendered[index];
|
|
6975
|
+
if (line === void 0) {
|
|
6976
|
+
line = `${symbol.line} ${KIND_LETTERS[symbol.kind]} ${symbol.name}`;
|
|
6977
|
+
rendered[index] = line;
|
|
6978
|
+
}
|
|
6979
|
+
const lineCost = line.length + 1;
|
|
6980
|
+
if (used + cost + lineCost > charBudget) continue;
|
|
6981
|
+
cost += lineCost;
|
|
6982
|
+
picked.push(index);
|
|
6983
|
+
}
|
|
6984
|
+
}
|
|
6985
|
+
if (picked.length === 0) {
|
|
6986
|
+
omittedFiles++;
|
|
6987
|
+
omittedSymbols += group.symbols.length;
|
|
6988
|
+
continue;
|
|
6989
|
+
}
|
|
6990
|
+
picked.sort((left, right) => left - right);
|
|
6991
|
+
lines.push(group.file);
|
|
6992
|
+
for (const index of picked) lines.push(rendered[index]);
|
|
6993
|
+
used += cost;
|
|
6994
|
+
filesShown++;
|
|
6995
|
+
symbolsShown += picked.length;
|
|
6996
|
+
omittedSymbols += group.symbols.length - picked.length;
|
|
6997
|
+
}
|
|
6998
|
+
return { lines, filesShown, symbolsShown, omittedFiles, omittedSymbols };
|
|
6999
|
+
};
|
|
7000
|
+
function assembleMap(request) {
|
|
7001
|
+
const groups = groupByFile(request.index.symbols);
|
|
7002
|
+
rankGroups(groups, request);
|
|
7003
|
+
const charBudget = request.maxTokens > 0 ? Math.floor(request.maxTokens) * 4 : 0;
|
|
7004
|
+
const legendCost = LEGEND.length + 1;
|
|
7005
|
+
const reserved = charBudget >= legendCost + MIN_FILE_ENTRY ? legendCost : 0;
|
|
7006
|
+
let plan = spend(groups, charBudget, reserved);
|
|
7007
|
+
let legendShown = reserved > 0;
|
|
7008
|
+
if (plan.filesShown === 0 && reserved > 0) {
|
|
7009
|
+
plan = spend(groups, charBudget, 0);
|
|
7010
|
+
legendShown = false;
|
|
7011
|
+
}
|
|
7012
|
+
const body = plan.lines.join("\n");
|
|
7013
|
+
const text = plan.lines.length === 0 ? "" : legendShown ? `${LEGEND}
|
|
7014
|
+
${body}
|
|
7015
|
+
` : `${body}
|
|
7016
|
+
`;
|
|
7017
|
+
return {
|
|
7018
|
+
text,
|
|
7019
|
+
tokensEstimated: estimateTokens({ role: "user", content: text }),
|
|
7020
|
+
filesShown: plan.filesShown,
|
|
7021
|
+
symbolsShown: plan.symbolsShown,
|
|
7022
|
+
omittedFiles: plan.omittedFiles,
|
|
7023
|
+
omittedSymbols: plan.omittedSymbols,
|
|
7024
|
+
truncated: plan.omittedFiles > 0 || plan.omittedSymbols > 0
|
|
7025
|
+
};
|
|
7026
|
+
}
|
|
7027
|
+
|
|
7028
|
+
// src/codemap/cascade.ts
|
|
7029
|
+
import { execFile } from "node:child_process";
|
|
7030
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
7031
|
+
import path7 from "node:path";
|
|
7032
|
+
import { promisify } from "node:util";
|
|
7033
|
+
var execFileAsync = promisify(execFile);
|
|
7034
|
+
var BULK_COMMIT_FILE_CEILING = 100;
|
|
7035
|
+
var GIT_TIMEOUT_MS = 2e4;
|
|
7036
|
+
var GIT_MAX_BUFFER = 64 << 20;
|
|
7037
|
+
var COMMIT_MARKER_CODE = 1;
|
|
7038
|
+
var QUOTE_CODE = 34;
|
|
7039
|
+
var ESCAPE_BYTES = /* @__PURE__ */ new Map([
|
|
7040
|
+
["a", 7],
|
|
7041
|
+
["b", 8],
|
|
7042
|
+
["t", 9],
|
|
7043
|
+
["n", 10],
|
|
7044
|
+
["v", 11],
|
|
7045
|
+
["f", 12],
|
|
7046
|
+
["r", 13],
|
|
7047
|
+
['"', 34],
|
|
7048
|
+
["\\", 92]
|
|
7049
|
+
]);
|
|
7050
|
+
var toPosix = (value) => path7.sep === "/" ? value : value.replaceAll(path7.sep, "/");
|
|
7051
|
+
var unquoteGitPath = (raw) => {
|
|
7052
|
+
if (raw.length < 2 || raw.charCodeAt(raw.length - 1) !== QUOTE_CODE) return raw;
|
|
7053
|
+
const bytes = [];
|
|
7054
|
+
for (let index = 1; index < raw.length - 1; index += 1) {
|
|
7055
|
+
const char = raw[index];
|
|
7056
|
+
if (char !== "\\") {
|
|
7057
|
+
const code = char.charCodeAt(0);
|
|
7058
|
+
if (code < 128) bytes.push(code);
|
|
7059
|
+
else for (const byte of Buffer.from(char, "utf8")) bytes.push(byte);
|
|
7060
|
+
continue;
|
|
7061
|
+
}
|
|
7062
|
+
const next = raw[index + 1];
|
|
7063
|
+
if (next === void 0) break;
|
|
7064
|
+
const mapped = ESCAPE_BYTES.get(next);
|
|
7065
|
+
if (mapped !== void 0) {
|
|
7066
|
+
bytes.push(mapped);
|
|
7067
|
+
index += 1;
|
|
7068
|
+
continue;
|
|
7069
|
+
}
|
|
7070
|
+
if (next >= "0" && next <= "7") {
|
|
7071
|
+
let value = 0;
|
|
7072
|
+
let digits = 0;
|
|
7073
|
+
while (digits < 3) {
|
|
7074
|
+
const digit = raw[index + 1 + digits];
|
|
7075
|
+
if (digit === void 0 || digit < "0" || digit > "7") break;
|
|
7076
|
+
value = value * 8 + (digit.charCodeAt(0) - 48);
|
|
7077
|
+
digits += 1;
|
|
7078
|
+
}
|
|
7079
|
+
bytes.push(value & 255);
|
|
7080
|
+
index += digits;
|
|
7081
|
+
continue;
|
|
7082
|
+
}
|
|
7083
|
+
bytes.push(next.charCodeAt(0));
|
|
7084
|
+
index += 1;
|
|
7085
|
+
}
|
|
7086
|
+
return Buffer.from(bytes).toString("utf8");
|
|
7087
|
+
};
|
|
7088
|
+
var realPath = (value) => {
|
|
7089
|
+
try {
|
|
7090
|
+
return realpathSync.native(value);
|
|
7091
|
+
} catch {
|
|
7092
|
+
return value;
|
|
7093
|
+
}
|
|
7094
|
+
};
|
|
7095
|
+
var relativeSeed = (root, top, seed) => {
|
|
7096
|
+
const absolute = path7.isAbsolute(seed) ? seed : path7.resolve(root, seed);
|
|
7097
|
+
for (const base of /* @__PURE__ */ new Set([top, realPath(top)])) {
|
|
7098
|
+
for (const candidate of /* @__PURE__ */ new Set([absolute, realPath(absolute), path7.resolve(realPath(root), seed)])) {
|
|
7099
|
+
const relative = path7.relative(base, candidate);
|
|
7100
|
+
if (!relative || relative === ".." || relative.startsWith(`..${path7.sep}`) || path7.isAbsolute(relative)) {
|
|
7101
|
+
continue;
|
|
7102
|
+
}
|
|
7103
|
+
return toPosix(relative);
|
|
7104
|
+
}
|
|
7105
|
+
}
|
|
7106
|
+
return void 0;
|
|
7107
|
+
};
|
|
7108
|
+
var emptyGraph = (seeds, unavailable) => ({
|
|
7109
|
+
seeds,
|
|
7110
|
+
edges: [],
|
|
7111
|
+
commitsScanned: 0,
|
|
7112
|
+
truncated: false,
|
|
7113
|
+
unavailable
|
|
7114
|
+
});
|
|
7115
|
+
async function coChange(request) {
|
|
7116
|
+
const requestedSeeds = request.seeds.filter((seed) => seed.length > 0);
|
|
7117
|
+
if (requestedSeeds.length === 0) return emptyGraph([], "no seed files were provided");
|
|
7118
|
+
if (!existsSync(request.root)) return emptyGraph(requestedSeeds, "root directory does not exist");
|
|
7119
|
+
const maxCommits = Math.max(1, Math.floor(request.maxCommits) || 1);
|
|
7120
|
+
const limit = Math.max(1, Math.floor(request.limit) || 1);
|
|
7121
|
+
let top;
|
|
7122
|
+
try {
|
|
7123
|
+
const revParse = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
|
|
7124
|
+
cwd: request.root,
|
|
7125
|
+
timeout: GIT_TIMEOUT_MS,
|
|
7126
|
+
encoding: "utf8"
|
|
7127
|
+
});
|
|
7128
|
+
top = revParse.stdout.trim();
|
|
7129
|
+
} catch (error) {
|
|
7130
|
+
const code = error.code;
|
|
7131
|
+
if (code === "ENOENT") return emptyGraph(requestedSeeds, "git is not available");
|
|
7132
|
+
return emptyGraph(requestedSeeds, "not a git repository");
|
|
7133
|
+
}
|
|
7134
|
+
if (!top) return emptyGraph(requestedSeeds, "not a git repository");
|
|
7135
|
+
const seedSet = /* @__PURE__ */ new Set();
|
|
7136
|
+
for (const seed of requestedSeeds) {
|
|
7137
|
+
const normalized = relativeSeed(request.root, top, seed);
|
|
7138
|
+
if (normalized) seedSet.add(normalized);
|
|
7139
|
+
}
|
|
7140
|
+
const seeds = [...seedSet];
|
|
7141
|
+
if (seeds.length === 0) return emptyGraph(requestedSeeds, "seed files are outside the repository");
|
|
7142
|
+
let stdout;
|
|
7143
|
+
try {
|
|
7144
|
+
const log = await execFileAsync(
|
|
7145
|
+
"git",
|
|
7146
|
+
[
|
|
7147
|
+
"log",
|
|
7148
|
+
`--max-count=${maxCommits}`,
|
|
7149
|
+
"--no-merges",
|
|
7150
|
+
"--name-only",
|
|
7151
|
+
`--pretty=format:%H`
|
|
7152
|
+
],
|
|
7153
|
+
{
|
|
7154
|
+
cwd: top,
|
|
7155
|
+
timeout: GIT_TIMEOUT_MS,
|
|
7156
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
7157
|
+
encoding: "utf8"
|
|
7158
|
+
}
|
|
7159
|
+
);
|
|
7160
|
+
stdout = log.stdout;
|
|
7161
|
+
} catch (error) {
|
|
7162
|
+
const code = error.code;
|
|
7163
|
+
if (code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") {
|
|
7164
|
+
return emptyGraph(seeds, "commit history exceeded the read budget");
|
|
7165
|
+
}
|
|
7166
|
+
return emptyGraph(seeds, "no commit history");
|
|
7167
|
+
}
|
|
7168
|
+
const fileCommits = /* @__PURE__ */ new Map();
|
|
7169
|
+
const sharedCommits = /* @__PURE__ */ new Map();
|
|
7170
|
+
const current = [];
|
|
7171
|
+
let commitsScanned = 0;
|
|
7172
|
+
let seedCommits = 0;
|
|
7173
|
+
let inCommit = false;
|
|
7174
|
+
let bulk = false;
|
|
7175
|
+
const settle = () => {
|
|
7176
|
+
if (!inCommit) return;
|
|
7177
|
+
inCommit = false;
|
|
7178
|
+
if (bulk) {
|
|
7179
|
+
bulk = false;
|
|
7180
|
+
current.length = 0;
|
|
7181
|
+
return;
|
|
7182
|
+
}
|
|
7183
|
+
commitsScanned += 1;
|
|
7184
|
+
let touchesSeed = false;
|
|
7185
|
+
for (const file of current) {
|
|
7186
|
+
if (seedSet.has(file)) {
|
|
7187
|
+
touchesSeed = true;
|
|
7188
|
+
break;
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
if (touchesSeed) seedCommits += 1;
|
|
7192
|
+
for (const file of current) {
|
|
7193
|
+
fileCommits.set(file, (fileCommits.get(file) ?? 0) + 1);
|
|
7194
|
+
if (touchesSeed && !seedSet.has(file)) {
|
|
7195
|
+
sharedCommits.set(file, (sharedCommits.get(file) ?? 0) + 1);
|
|
7196
|
+
}
|
|
7197
|
+
}
|
|
7198
|
+
current.length = 0;
|
|
7199
|
+
};
|
|
7200
|
+
let cursor = 0;
|
|
7201
|
+
while (cursor <= stdout.length) {
|
|
7202
|
+
let end = stdout.indexOf("\n", cursor);
|
|
7203
|
+
if (end < 0) end = stdout.length;
|
|
7204
|
+
const line = stdout.slice(cursor, end);
|
|
7205
|
+
cursor = end + 1;
|
|
7206
|
+
if (line.length === 0) continue;
|
|
7207
|
+
if (line.charCodeAt(0) === COMMIT_MARKER_CODE) {
|
|
7208
|
+
settle();
|
|
7209
|
+
inCommit = true;
|
|
7210
|
+
continue;
|
|
7211
|
+
}
|
|
7212
|
+
if (!inCommit || bulk) continue;
|
|
7213
|
+
if (current.length >= BULK_COMMIT_FILE_CEILING) {
|
|
7214
|
+
bulk = true;
|
|
7215
|
+
current.length = 0;
|
|
7216
|
+
continue;
|
|
7217
|
+
}
|
|
7218
|
+
current.push(line.charCodeAt(0) === QUOTE_CODE ? unquoteGitPath(line) : line);
|
|
7219
|
+
}
|
|
7220
|
+
settle();
|
|
7221
|
+
if (commitsScanned === 0) return emptyGraph(seeds, "no commit history");
|
|
7222
|
+
const edges = [];
|
|
7223
|
+
if (seedCommits > 0) {
|
|
7224
|
+
const seedRoot = Math.sqrt(seedCommits);
|
|
7225
|
+
for (const [file, shared] of sharedCommits) {
|
|
7226
|
+
const total = fileCommits.get(file) ?? shared;
|
|
7227
|
+
edges.push({ file, score: shared / (seedRoot * Math.sqrt(total)), commits: shared });
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
edges.sort((left, right) => {
|
|
7231
|
+
if (right.score !== left.score) return right.score - left.score;
|
|
7232
|
+
if (right.commits !== left.commits) return right.commits - left.commits;
|
|
7233
|
+
return left.file < right.file ? -1 : left.file > right.file ? 1 : 0;
|
|
7234
|
+
});
|
|
7235
|
+
const truncated = edges.length > limit;
|
|
7236
|
+
if (truncated) edges.length = limit;
|
|
7237
|
+
if (seedCommits === 0) {
|
|
7238
|
+
return { seeds, edges, commitsScanned, truncated, unavailable: "seed files do not appear in the scanned history" };
|
|
7239
|
+
}
|
|
7240
|
+
return { seeds, edges, commitsScanned, truncated };
|
|
7241
|
+
}
|
|
7242
|
+
|
|
7243
|
+
// src/codemap/symbols.ts
|
|
7244
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
7245
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
7246
|
+
import { createRequire } from "node:module";
|
|
7247
|
+
import path8 from "node:path";
|
|
7248
|
+
import { promisify as promisify2 } from "node:util";
|
|
7249
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
7250
|
+
var commonDirectory = (files) => {
|
|
7251
|
+
let prefix;
|
|
7252
|
+
for (const file of files) {
|
|
7253
|
+
const parts = file.split("/");
|
|
7254
|
+
parts.pop();
|
|
7255
|
+
if (prefix === void 0) {
|
|
7256
|
+
prefix = parts;
|
|
7257
|
+
continue;
|
|
7258
|
+
}
|
|
7259
|
+
let shared = 0;
|
|
7260
|
+
while (shared < prefix.length && shared < parts.length && prefix[shared] === parts[shared]) shared++;
|
|
7261
|
+
prefix.length = shared;
|
|
7262
|
+
if (shared === 0) return "";
|
|
7263
|
+
}
|
|
7264
|
+
return prefix === void 0 ? "" : prefix.join("/");
|
|
7265
|
+
};
|
|
7266
|
+
var importBundledNatives = async () => {
|
|
7267
|
+
try {
|
|
7268
|
+
const bundled = await import("@oh-my-pi/pi-natives");
|
|
7269
|
+
return typeof bundled.astGrep === "function" ? bundled : void 0;
|
|
7270
|
+
} catch {
|
|
7271
|
+
return void 0;
|
|
7272
|
+
}
|
|
7273
|
+
};
|
|
7274
|
+
var importPlatformNatives = () => {
|
|
7275
|
+
const load = createRequire(import.meta.url);
|
|
7276
|
+
return load(`@oh-my-pi/pi-natives-${process.platform}-${process.arch}`);
|
|
7277
|
+
};
|
|
7278
|
+
var nativesOnce;
|
|
7279
|
+
var codeNatives = () => {
|
|
7280
|
+
nativesOnce ??= importBundledNatives().then((bundled) => bundled ?? importPlatformNatives());
|
|
7281
|
+
return nativesOnce;
|
|
7282
|
+
};
|
|
7283
|
+
var SCRIPT_DECLARATION = /^(?:export\s+)?(?:default\s+)?(?:declare\s+)?(?:abstract\s+)?(?:async\s+)?(function|class|interface|type|enum|const|let|var)\b/;
|
|
7284
|
+
var ARROW_VALUE = /^(?:async\s*)?[(<]/;
|
|
7285
|
+
var classifyScript = (text, meta) => {
|
|
7286
|
+
const exported = text.startsWith("export");
|
|
7287
|
+
const declaration = SCRIPT_DECLARATION.exec(text);
|
|
7288
|
+
switch (declaration?.[1]) {
|
|
7289
|
+
case "function":
|
|
7290
|
+
return { kind: "fn", exported };
|
|
7291
|
+
case "class":
|
|
7292
|
+
return { kind: "class", exported };
|
|
7293
|
+
case "interface":
|
|
7294
|
+
return { kind: "iface", exported };
|
|
7295
|
+
case "type":
|
|
7296
|
+
return { kind: "type", exported };
|
|
7297
|
+
case "enum":
|
|
7298
|
+
return { kind: "enum", exported };
|
|
7299
|
+
default: {
|
|
7300
|
+
const value = meta?.V;
|
|
7301
|
+
if (value === void 0) return { kind: "fn", exported };
|
|
7302
|
+
const arrow = ARROW_VALUE.test(value) && value.includes("=>");
|
|
7303
|
+
return { kind: arrow ? "fn" : "const", exported };
|
|
7304
|
+
}
|
|
7305
|
+
}
|
|
7306
|
+
};
|
|
7307
|
+
var SCRIPT_VALUE_PATTERNS = [
|
|
7308
|
+
"function $NAME($$$A) { $$$B }",
|
|
7309
|
+
"export function $NAME($$$A) { $$$B }",
|
|
7310
|
+
"export default function $NAME($$$A) { $$$B }",
|
|
7311
|
+
"class $NAME { $$$B }",
|
|
7312
|
+
"export class $NAME { $$$B }",
|
|
7313
|
+
"export default class $NAME { $$$B }",
|
|
7314
|
+
"const $NAME = ($$$A) => $B",
|
|
7315
|
+
"const $NAME = $V",
|
|
7316
|
+
"export const $NAME = $V"
|
|
7317
|
+
];
|
|
7318
|
+
var TYPED_SCRIPT_PATTERNS = [
|
|
7319
|
+
...SCRIPT_VALUE_PATTERNS,
|
|
7320
|
+
"interface $NAME { $$$B }",
|
|
7321
|
+
"export interface $NAME { $$$B }",
|
|
7322
|
+
"type $NAME = $V",
|
|
7323
|
+
"export type $NAME = $V",
|
|
7324
|
+
"enum $NAME { $$$B }",
|
|
7325
|
+
"export enum $NAME { $$$B }"
|
|
7326
|
+
];
|
|
7327
|
+
var PYTHON_DEFINITION = /^(?:async\s+)?def\b/;
|
|
7328
|
+
var PYTHON_CLASS = /^class\b/;
|
|
7329
|
+
var classifyPython = (text) => {
|
|
7330
|
+
if (PYTHON_DEFINITION.test(text)) return { kind: "fn", exported: true };
|
|
7331
|
+
if (PYTHON_CLASS.test(text)) return { kind: "class", exported: true };
|
|
7332
|
+
return { kind: "const", exported: true };
|
|
7333
|
+
};
|
|
7334
|
+
var GO_METHOD = /^func\s*\(/;
|
|
7335
|
+
var GO_FUNCTION = /^func\b/;
|
|
7336
|
+
var GO_STRUCT = /^type\s+\w+\s+struct\b/;
|
|
7337
|
+
var GO_INTERFACE = /^type\s+\w+\s+interface\b/;
|
|
7338
|
+
var GO_TYPE = /^type\b/;
|
|
7339
|
+
var classifyGo = (text) => {
|
|
7340
|
+
if (GO_METHOD.test(text)) return { kind: "method", exported: true };
|
|
7341
|
+
if (GO_FUNCTION.test(text)) return { kind: "fn", exported: true };
|
|
7342
|
+
if (GO_STRUCT.test(text)) return { kind: "class", exported: true };
|
|
7343
|
+
if (GO_INTERFACE.test(text)) return { kind: "iface", exported: true };
|
|
7344
|
+
if (GO_TYPE.test(text)) return { kind: "type", exported: true };
|
|
7345
|
+
return { kind: "const", exported: true };
|
|
7346
|
+
};
|
|
7347
|
+
var RUST_KEYWORD = /^(?:pub(?:\([^)]*\))?\s+)?(fn|struct|enum|trait|type|const|static)\b/;
|
|
7348
|
+
var classifyRust = (text) => {
|
|
7349
|
+
const exported = text.startsWith("pub");
|
|
7350
|
+
switch (RUST_KEYWORD.exec(text)?.[1]) {
|
|
7351
|
+
case "fn":
|
|
7352
|
+
return { kind: "fn", exported };
|
|
7353
|
+
case "struct":
|
|
7354
|
+
return { kind: "class", exported };
|
|
7355
|
+
case "enum":
|
|
7356
|
+
return { kind: "enum", exported };
|
|
7357
|
+
case "trait":
|
|
7358
|
+
return { kind: "iface", exported };
|
|
7359
|
+
case "type":
|
|
7360
|
+
return { kind: "type", exported };
|
|
7361
|
+
default:
|
|
7362
|
+
return { kind: "const", exported };
|
|
7363
|
+
}
|
|
7364
|
+
};
|
|
7365
|
+
var JAVA_KEYWORD = /^(?:(?:public|private|protected|static|final|abstract|synchronized|native|strictfp)\s+)*(class|interface|enum|record)\b/;
|
|
7366
|
+
var classifyJava = (text) => {
|
|
7367
|
+
const exported = text.startsWith("public");
|
|
7368
|
+
switch (JAVA_KEYWORD.exec(text)?.[1]) {
|
|
7369
|
+
case "class":
|
|
7370
|
+
case "record":
|
|
7371
|
+
return { kind: "class", exported };
|
|
7372
|
+
case "interface":
|
|
7373
|
+
return { kind: "iface", exported };
|
|
7374
|
+
case "enum":
|
|
7375
|
+
return { kind: "enum", exported };
|
|
7376
|
+
default:
|
|
7377
|
+
return { kind: "method", exported };
|
|
7378
|
+
}
|
|
7379
|
+
};
|
|
7380
|
+
var globFor = (extensions) => extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(",")}}`;
|
|
7381
|
+
var defineSpec = (id, lang, extensions, patterns, classify) => ({ id, lang, extensions, glob: globFor(extensions), patterns, classify });
|
|
7382
|
+
var LANGUAGE_SPECS = [
|
|
7383
|
+
defineSpec("ts", "ts", ["ts", "mts", "cts"], TYPED_SCRIPT_PATTERNS, classifyScript),
|
|
7384
|
+
defineSpec("tsx", "tsx", ["tsx"], TYPED_SCRIPT_PATTERNS, classifyScript),
|
|
7385
|
+
defineSpec("js", "js", ["js", "mjs", "cjs", "jsx"], SCRIPT_VALUE_PATTERNS, classifyScript),
|
|
7386
|
+
defineSpec(
|
|
7387
|
+
"python",
|
|
7388
|
+
"python",
|
|
7389
|
+
["py", "pyi"],
|
|
7390
|
+
[
|
|
7391
|
+
"def $NAME($$$A): $$$B",
|
|
7392
|
+
"class $NAME($$$A): $$$B",
|
|
7393
|
+
"class $NAME: $$$B",
|
|
7394
|
+
"$NAME = $V"
|
|
7395
|
+
],
|
|
7396
|
+
classifyPython
|
|
7397
|
+
),
|
|
7398
|
+
defineSpec(
|
|
7399
|
+
"go",
|
|
7400
|
+
"go",
|
|
7401
|
+
["go"],
|
|
7402
|
+
[
|
|
7403
|
+
"func $NAME($$$A) $$$R { $$$B }",
|
|
7404
|
+
"func ($$$RECV) $NAME($$$A) $$$R { $$$B }",
|
|
7405
|
+
"type $NAME struct { $$$B }",
|
|
7406
|
+
"type $NAME interface { $$$B }",
|
|
7407
|
+
"type $NAME = $V",
|
|
7408
|
+
"const $NAME = $V",
|
|
7409
|
+
"var $NAME = $V"
|
|
7410
|
+
],
|
|
7411
|
+
classifyGo
|
|
7412
|
+
),
|
|
7413
|
+
defineSpec(
|
|
7414
|
+
"rust",
|
|
7415
|
+
"rust",
|
|
7416
|
+
["rs"],
|
|
7417
|
+
[
|
|
7418
|
+
"fn $NAME($$$A) { $$$B }",
|
|
7419
|
+
"fn $NAME($$$A) -> $R { $$$B }",
|
|
7420
|
+
"pub fn $NAME($$$A) { $$$B }",
|
|
7421
|
+
"pub fn $NAME($$$A) -> $R { $$$B }",
|
|
7422
|
+
"struct $NAME { $$$B }",
|
|
7423
|
+
"pub struct $NAME { $$$B }",
|
|
7424
|
+
"enum $NAME { $$$B }",
|
|
7425
|
+
"pub enum $NAME { $$$B }",
|
|
7426
|
+
"trait $NAME { $$$B }",
|
|
7427
|
+
"pub trait $NAME { $$$B }",
|
|
7428
|
+
"type $NAME = $V;",
|
|
7429
|
+
"pub type $NAME = $V;",
|
|
7430
|
+
"const $NAME: $T = $V;",
|
|
7431
|
+
"pub const $NAME: $T = $V;",
|
|
7432
|
+
"static $NAME: $T = $V;",
|
|
7433
|
+
"pub static $NAME: $T = $V;"
|
|
7434
|
+
],
|
|
7435
|
+
classifyRust
|
|
7436
|
+
),
|
|
7437
|
+
defineSpec(
|
|
7438
|
+
"java",
|
|
7439
|
+
"java",
|
|
7440
|
+
["java"],
|
|
7441
|
+
[
|
|
7442
|
+
"class $NAME { $$$B }",
|
|
7443
|
+
"public class $NAME { $$$B }",
|
|
7444
|
+
"interface $NAME { $$$B }",
|
|
7445
|
+
"public interface $NAME { $$$B }",
|
|
7446
|
+
"enum $NAME { $$$B }",
|
|
7447
|
+
"public enum $NAME { $$$B }",
|
|
7448
|
+
"$RET $NAME($$$A) { $$$B }",
|
|
7449
|
+
"public $RET $NAME($$$A) { $$$B }",
|
|
7450
|
+
"private $RET $NAME($$$A) { $$$B }",
|
|
7451
|
+
"protected $RET $NAME($$$A) { $$$B }",
|
|
7452
|
+
"public static $RET $NAME($$$A) { $$$B }",
|
|
7453
|
+
"static $RET $NAME($$$A) { $$$B }"
|
|
7454
|
+
],
|
|
7455
|
+
classifyJava
|
|
7456
|
+
)
|
|
7457
|
+
];
|
|
7458
|
+
var EXTENSION_SPECS = /* @__PURE__ */ new Map();
|
|
7459
|
+
for (const spec of LANGUAGE_SPECS) {
|
|
7460
|
+
for (const extension of spec.extensions) EXTENSION_SPECS.set(extension, spec);
|
|
7461
|
+
}
|
|
7462
|
+
var FALLBACK_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
7463
|
+
"c",
|
|
7464
|
+
"cc",
|
|
7465
|
+
"cpp",
|
|
7466
|
+
"cs",
|
|
7467
|
+
"cxx",
|
|
7468
|
+
"dart",
|
|
7469
|
+
"elm",
|
|
7470
|
+
"erl",
|
|
7471
|
+
"ex",
|
|
7472
|
+
"exs",
|
|
7473
|
+
"groovy",
|
|
7474
|
+
"h",
|
|
7475
|
+
"hh",
|
|
7476
|
+
"hpp",
|
|
7477
|
+
"hs",
|
|
7478
|
+
"jl",
|
|
7479
|
+
"kt",
|
|
7480
|
+
"kts",
|
|
7481
|
+
"lua",
|
|
7482
|
+
"nim",
|
|
7483
|
+
"php",
|
|
7484
|
+
"pl",
|
|
7485
|
+
"pm",
|
|
7486
|
+
"proto",
|
|
7487
|
+
"rb",
|
|
7488
|
+
"scala",
|
|
7489
|
+
"sh",
|
|
7490
|
+
"sql",
|
|
7491
|
+
"svelte",
|
|
7492
|
+
"swift",
|
|
7493
|
+
"vue",
|
|
7494
|
+
"zig"
|
|
7495
|
+
]);
|
|
7496
|
+
var SKIP_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist"]);
|
|
7497
|
+
var IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
7498
|
+
var KIND_RANK = {
|
|
7499
|
+
method: 5,
|
|
7500
|
+
fn: 4,
|
|
7501
|
+
class: 3,
|
|
7502
|
+
iface: 3,
|
|
7503
|
+
enum: 3,
|
|
7504
|
+
type: 2,
|
|
7505
|
+
const: 1
|
|
7506
|
+
};
|
|
7507
|
+
var MATCH_TIMEOUT_MS = 12e4;
|
|
7508
|
+
var MAX_FALLBACK_BYTES = 2e6;
|
|
7509
|
+
var extensionOf = (file) => {
|
|
7510
|
+
const slash = file.lastIndexOf("/");
|
|
7511
|
+
const dot = file.lastIndexOf(".");
|
|
7512
|
+
if (dot <= slash + 1) return void 0;
|
|
7513
|
+
return file.slice(dot + 1).toLowerCase();
|
|
7514
|
+
};
|
|
7515
|
+
var indexableExtension = (file) => {
|
|
7516
|
+
const extension = extensionOf(file);
|
|
7517
|
+
if (extension === void 0) return void 0;
|
|
7518
|
+
if (EXTENSION_SPECS.has(extension) || FALLBACK_EXTENSIONS.has(extension)) return extension;
|
|
7519
|
+
return void 0;
|
|
7520
|
+
};
|
|
7521
|
+
var GLOB_ESCAPE = /[.+^$()|[\]\\]/g;
|
|
7522
|
+
var globToRegExp = (pattern) => {
|
|
7523
|
+
let source = "";
|
|
7524
|
+
let braces = 0;
|
|
7525
|
+
for (let i = 0; i < pattern.length; i += 1) {
|
|
7526
|
+
const character = pattern[i];
|
|
7527
|
+
if (character === "*") {
|
|
7528
|
+
if (pattern[i + 1] === "*") {
|
|
7529
|
+
i += 1;
|
|
7530
|
+
if (pattern[i + 1] === "/") {
|
|
7531
|
+
i += 1;
|
|
7532
|
+
source += "(?:[^/]*/)*";
|
|
7533
|
+
} else {
|
|
7534
|
+
source += ".*";
|
|
7535
|
+
}
|
|
7536
|
+
continue;
|
|
7537
|
+
}
|
|
7538
|
+
source += "[^/]*";
|
|
7539
|
+
continue;
|
|
7540
|
+
}
|
|
7541
|
+
if (character === "?") {
|
|
7542
|
+
source += "[^/]";
|
|
7543
|
+
continue;
|
|
7544
|
+
}
|
|
7545
|
+
if (character === "{") {
|
|
7546
|
+
braces += 1;
|
|
7547
|
+
source += "(?:";
|
|
7548
|
+
continue;
|
|
7549
|
+
}
|
|
7550
|
+
if (character === "}" && braces > 0) {
|
|
7551
|
+
braces -= 1;
|
|
7552
|
+
source += ")";
|
|
7553
|
+
continue;
|
|
7554
|
+
}
|
|
7555
|
+
if (character === "," && braces > 0) {
|
|
7556
|
+
source += "|";
|
|
7557
|
+
continue;
|
|
7558
|
+
}
|
|
7559
|
+
source += character?.replace(GLOB_ESCAPE, "\\$&") ?? "";
|
|
7560
|
+
}
|
|
7561
|
+
return new RegExp(`^${source}$`);
|
|
7562
|
+
};
|
|
7563
|
+
var GIT_LIST_TIMEOUT_MS = 2e4;
|
|
7564
|
+
var GIT_LIST_MAX_BUFFER = 64 * 1024 * 1024;
|
|
7565
|
+
var gitTrackedFiles = async (root, matcher, signal) => {
|
|
7566
|
+
let stdout;
|
|
7567
|
+
try {
|
|
7568
|
+
const result = await execFileAsync2(
|
|
7569
|
+
"git",
|
|
7570
|
+
["-C", root, "ls-files", "--cached", "--others", "--exclude-standard", "-z"],
|
|
7571
|
+
{
|
|
7572
|
+
maxBuffer: GIT_LIST_MAX_BUFFER,
|
|
7573
|
+
timeout: GIT_LIST_TIMEOUT_MS,
|
|
7574
|
+
...signal ? { signal } : {}
|
|
7575
|
+
}
|
|
7576
|
+
);
|
|
7577
|
+
stdout = result.stdout;
|
|
7578
|
+
} catch {
|
|
7579
|
+
return void 0;
|
|
7580
|
+
}
|
|
7581
|
+
const found = [];
|
|
7582
|
+
let cursor = 0;
|
|
7583
|
+
while (cursor < stdout.length) {
|
|
7584
|
+
let end = stdout.indexOf("\0", cursor);
|
|
7585
|
+
if (end === -1) end = stdout.length;
|
|
7586
|
+
const relative = stdout.slice(cursor, end);
|
|
7587
|
+
cursor = end + 1;
|
|
7588
|
+
if (relative.length === 0) continue;
|
|
7589
|
+
if (relative.charCodeAt(0) === 46) continue;
|
|
7590
|
+
if (indexableExtension(relative) === void 0) continue;
|
|
7591
|
+
if (matcher !== void 0 && !matcher.test(relative)) continue;
|
|
7592
|
+
let skipped2 = false;
|
|
7593
|
+
let segmentStart = 0;
|
|
7594
|
+
while (segmentStart < relative.length) {
|
|
7595
|
+
let segmentEnd = relative.indexOf("/", segmentStart);
|
|
7596
|
+
if (segmentEnd === -1) break;
|
|
7597
|
+
const segment = relative.slice(segmentStart, segmentEnd);
|
|
7598
|
+
if (segment.charCodeAt(0) === 46 || SKIP_DIRECTORIES.has(segment)) {
|
|
7599
|
+
skipped2 = true;
|
|
7600
|
+
break;
|
|
7601
|
+
}
|
|
7602
|
+
segmentStart = segmentEnd + 1;
|
|
7603
|
+
}
|
|
7604
|
+
if (!skipped2) found.push(relative);
|
|
7605
|
+
}
|
|
7606
|
+
return found;
|
|
7607
|
+
};
|
|
7608
|
+
var walkFiles = async (root, matcher, signal) => {
|
|
7609
|
+
const found = [];
|
|
7610
|
+
const pending = [""];
|
|
7611
|
+
while (pending.length > 0) {
|
|
7612
|
+
const directory = pending.pop() ?? "";
|
|
7613
|
+
throwIfAborted(signal);
|
|
7614
|
+
let entries;
|
|
7615
|
+
try {
|
|
7616
|
+
entries = await readdir(directory === "" ? root : path8.join(root, directory), {
|
|
7617
|
+
withFileTypes: true
|
|
7618
|
+
});
|
|
7619
|
+
} catch {
|
|
7620
|
+
continue;
|
|
7621
|
+
}
|
|
7622
|
+
for (const entry of entries) {
|
|
7623
|
+
const name = entry.name;
|
|
7624
|
+
if (name.charCodeAt(0) === 46) continue;
|
|
7625
|
+
const relative = directory === "" ? name : `${directory}/${name}`;
|
|
7626
|
+
if (entry.isDirectory()) {
|
|
7627
|
+
if (!SKIP_DIRECTORIES.has(name)) pending.push(relative);
|
|
7628
|
+
continue;
|
|
7629
|
+
}
|
|
7630
|
+
if (!entry.isFile()) continue;
|
|
7631
|
+
if (indexableExtension(relative) === void 0) continue;
|
|
7632
|
+
if (matcher !== void 0 && !matcher.test(relative)) continue;
|
|
7633
|
+
found.push(relative);
|
|
7634
|
+
}
|
|
7635
|
+
}
|
|
7636
|
+
return found;
|
|
7637
|
+
};
|
|
7638
|
+
var discoverFiles = async (root, matcher, signal) => await gitTrackedFiles(root, matcher, signal) ?? await walkFiles(root, matcher, signal);
|
|
7639
|
+
var COMMENT_HEAD = /^(?:\/\/|\/\*|\*|#|--|<!--|;|%)/;
|
|
7640
|
+
var IMPORT_HEAD = /^(?:import|from|require|include|use|using|package|open|load|source)\b/;
|
|
7641
|
+
var DECLARATION_HEAD = /^(?:export|pub|public|private|protected|internal|static|final|abstract|override|virtual|inline|async|unsafe|extern|shared|readonly|declare|local|def|defp|defmodule|defstruct|defmacro|class|module|namespace|record|object|data|struct|enum|union|interface|trait|protocol|actor|impl|extension|fn|func|function|sub|procedure|method|const|let|var|val|type|typedef|typealias|template|operator|constructor|init|property|event|signal|macro|task)\b/;
|
|
7642
|
+
var ASSIGNMENT_HEAD = /^[A-Za-z_$][\w$]*\s*(?::[^=]*)?=[^=]/;
|
|
7643
|
+
var EXPORTED_HEAD = /^(?:export|pub|public)\b/;
|
|
7644
|
+
var IDENTIFIERS = /[A-Za-z_$][\w$]*/g;
|
|
7645
|
+
var FALLBACK_KINDS = /* @__PURE__ */ new Map([
|
|
7646
|
+
["class", "class"],
|
|
7647
|
+
["module", "class"],
|
|
7648
|
+
["namespace", "class"],
|
|
7649
|
+
["record", "class"],
|
|
7650
|
+
["object", "class"],
|
|
7651
|
+
["struct", "class"],
|
|
7652
|
+
["impl", "class"],
|
|
7653
|
+
["actor", "class"],
|
|
7654
|
+
["defmodule", "class"],
|
|
7655
|
+
["defstruct", "class"],
|
|
7656
|
+
["interface", "iface"],
|
|
7657
|
+
["trait", "iface"],
|
|
7658
|
+
["protocol", "iface"],
|
|
7659
|
+
["enum", "enum"],
|
|
7660
|
+
["union", "enum"],
|
|
7661
|
+
["def", "fn"],
|
|
7662
|
+
["defp", "fn"],
|
|
7663
|
+
["defmacro", "fn"],
|
|
7664
|
+
["fn", "fn"],
|
|
7665
|
+
["func", "fn"],
|
|
7666
|
+
["function", "fn"],
|
|
7667
|
+
["sub", "fn"],
|
|
7668
|
+
["procedure", "fn"],
|
|
7669
|
+
["method", "method"],
|
|
7670
|
+
["constructor", "method"],
|
|
7671
|
+
["init", "method"],
|
|
7672
|
+
["type", "type"],
|
|
7673
|
+
["typedef", "type"],
|
|
7674
|
+
["typealias", "type"]
|
|
7675
|
+
]);
|
|
7676
|
+
var FALLBACK_SKIP = /* @__PURE__ */ new Set([
|
|
7677
|
+
...FALLBACK_KINDS.keys(),
|
|
7678
|
+
"export",
|
|
7679
|
+
"pub",
|
|
7680
|
+
"public",
|
|
7681
|
+
"private",
|
|
7682
|
+
"protected",
|
|
7683
|
+
"internal",
|
|
7684
|
+
"static",
|
|
7685
|
+
"final",
|
|
7686
|
+
"abstract",
|
|
7687
|
+
"override",
|
|
7688
|
+
"virtual",
|
|
7689
|
+
"inline",
|
|
7690
|
+
"async",
|
|
7691
|
+
"unsafe",
|
|
7692
|
+
"extern",
|
|
7693
|
+
"shared",
|
|
7694
|
+
"readonly",
|
|
7695
|
+
"declare",
|
|
7696
|
+
"local",
|
|
7697
|
+
"extension",
|
|
7698
|
+
"template",
|
|
7699
|
+
"operator",
|
|
7700
|
+
"property",
|
|
7701
|
+
"event",
|
|
7702
|
+
"signal",
|
|
7703
|
+
"macro",
|
|
7704
|
+
"task",
|
|
7705
|
+
"const",
|
|
7706
|
+
"let",
|
|
7707
|
+
"var",
|
|
7708
|
+
"val",
|
|
7709
|
+
"auto",
|
|
7710
|
+
"new",
|
|
7711
|
+
"return",
|
|
7712
|
+
"self",
|
|
7713
|
+
"this",
|
|
7714
|
+
"void",
|
|
7715
|
+
"int",
|
|
7716
|
+
"long",
|
|
7717
|
+
"short",
|
|
7718
|
+
"byte",
|
|
7719
|
+
"char",
|
|
7720
|
+
"bool",
|
|
7721
|
+
"boolean",
|
|
7722
|
+
"float",
|
|
7723
|
+
"double",
|
|
7724
|
+
"string",
|
|
7725
|
+
"str",
|
|
7726
|
+
"unsigned",
|
|
7727
|
+
"signed",
|
|
7728
|
+
"size_t",
|
|
7729
|
+
"mut",
|
|
7730
|
+
"end",
|
|
7731
|
+
"do",
|
|
7732
|
+
"then",
|
|
7733
|
+
"begin",
|
|
7734
|
+
"where",
|
|
7735
|
+
"with",
|
|
7736
|
+
"as",
|
|
7737
|
+
"in",
|
|
7738
|
+
"of",
|
|
7739
|
+
"is",
|
|
7740
|
+
"not",
|
|
7741
|
+
"and",
|
|
7742
|
+
"or",
|
|
7743
|
+
"if",
|
|
7744
|
+
"else",
|
|
7745
|
+
"for",
|
|
7746
|
+
"while",
|
|
7747
|
+
"switch",
|
|
7748
|
+
"match",
|
|
7749
|
+
"try",
|
|
7750
|
+
"catch",
|
|
7751
|
+
"throw",
|
|
7752
|
+
"throws",
|
|
7753
|
+
"extends",
|
|
7754
|
+
"implements"
|
|
7755
|
+
]);
|
|
7756
|
+
var fallbackSymbol = (file, line, lineNumber) => {
|
|
7757
|
+
const trimmed = line.trim();
|
|
7758
|
+
if (trimmed.length === 0) return void 0;
|
|
7759
|
+
if (COMMENT_HEAD.test(trimmed) || IMPORT_HEAD.test(trimmed)) return void 0;
|
|
7760
|
+
if (!DECLARATION_HEAD.test(trimmed) && !ASSIGNMENT_HEAD.test(trimmed)) return void 0;
|
|
7761
|
+
IDENTIFIERS.lastIndex = 0;
|
|
7762
|
+
let kind = "const";
|
|
7763
|
+
let name;
|
|
7764
|
+
for (let token = IDENTIFIERS.exec(trimmed); token !== null; token = IDENTIFIERS.exec(trimmed)) {
|
|
7765
|
+
const word = token[0];
|
|
7766
|
+
if (!FALLBACK_SKIP.has(word)) {
|
|
7767
|
+
name = word;
|
|
7768
|
+
break;
|
|
7769
|
+
}
|
|
7770
|
+
const mapped = FALLBACK_KINDS.get(word);
|
|
7771
|
+
if (mapped !== void 0 && kind === "const") kind = mapped;
|
|
7772
|
+
}
|
|
7773
|
+
if (name === void 0 || !IDENTIFIER.test(name)) return void 0;
|
|
7774
|
+
const exported = EXPORTED_HEAD.test(trimmed) || name.charCodeAt(0) !== 95;
|
|
7775
|
+
return { file, line: lineNumber, kind, name, exported };
|
|
7776
|
+
};
|
|
7777
|
+
var countLines = (code) => {
|
|
7778
|
+
let lines = 1;
|
|
7779
|
+
for (let at = code.indexOf("\n"); at >= 0; at = code.indexOf("\n", at + 1)) lines += 1;
|
|
7780
|
+
return lines;
|
|
7781
|
+
};
|
|
7782
|
+
var record = (into, symbol) => {
|
|
7783
|
+
const key = `${symbol.file}\0${symbol.line}\0${symbol.name}`;
|
|
7784
|
+
const existing = into.get(key);
|
|
7785
|
+
if (existing === void 0) {
|
|
7786
|
+
into.set(key, symbol);
|
|
7787
|
+
return;
|
|
7788
|
+
}
|
|
7789
|
+
if (symbol.exported) existing.exported = true;
|
|
7790
|
+
if (KIND_RANK[symbol.kind] > KIND_RANK[existing.kind]) existing.kind = symbol.kind;
|
|
7791
|
+
};
|
|
7792
|
+
var toPosix2 = (value) => path8.sep === "/" ? value : value.split(path8.sep).join("/");
|
|
7793
|
+
var compareSymbols = (left, right) => {
|
|
7794
|
+
if (left.file !== right.file) return left.file < right.file ? -1 : 1;
|
|
7795
|
+
if (left.line !== right.line) return left.line - right.line;
|
|
7796
|
+
return left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
|
|
7797
|
+
};
|
|
7798
|
+
async function buildSymbolIndex(request) {
|
|
7799
|
+
const startedAt = Date.now();
|
|
7800
|
+
const signal = request.signal;
|
|
7801
|
+
throwIfAborted(signal);
|
|
7802
|
+
const root = path8.resolve(request.root);
|
|
7803
|
+
const matcher = request.glob === void 0 ? void 0 : globToRegExp(request.glob);
|
|
7804
|
+
const discovered = await discoverFiles(root, matcher, signal);
|
|
7805
|
+
discovered.sort();
|
|
7806
|
+
let truncated = false;
|
|
7807
|
+
let files = discovered;
|
|
7808
|
+
if (files.length > request.maxFiles) {
|
|
7809
|
+
files = discovered.slice(0, request.maxFiles);
|
|
7810
|
+
truncated = true;
|
|
7811
|
+
}
|
|
7812
|
+
const languages = {};
|
|
7813
|
+
const assigned = /* @__PURE__ */ new Map();
|
|
7814
|
+
const activeSpecs = /* @__PURE__ */ new Set();
|
|
7815
|
+
const fallbackFiles = [];
|
|
7816
|
+
for (const file of files) {
|
|
7817
|
+
const extension = indexableExtension(file);
|
|
7818
|
+
if (extension === void 0) continue;
|
|
7819
|
+
const spec = EXTENSION_SPECS.get(extension);
|
|
7820
|
+
const label = spec?.id ?? extension;
|
|
7821
|
+
languages[label] = (languages[label] ?? 0) + 1;
|
|
7822
|
+
if (spec === void 0) {
|
|
7823
|
+
fallbackFiles.push(file);
|
|
7824
|
+
continue;
|
|
7825
|
+
}
|
|
7826
|
+
assigned.set(file, spec.id);
|
|
7827
|
+
activeSpecs.add(spec.id);
|
|
7828
|
+
}
|
|
7829
|
+
const natives = await codeNatives();
|
|
7830
|
+
const collected = /* @__PURE__ */ new Map();
|
|
7831
|
+
const matchLimit = Math.max(4096, request.maxSymbols * 2);
|
|
7832
|
+
for (const spec of LANGUAGE_SPECS) {
|
|
7833
|
+
if (!activeSpecs.has(spec.id)) continue;
|
|
7834
|
+
throwIfAborted(signal);
|
|
7835
|
+
const scoped = [];
|
|
7836
|
+
for (const [file, id] of assigned) if (id === spec.id) scoped.push(file);
|
|
7837
|
+
const prefix = commonDirectory(scoped);
|
|
7838
|
+
const result = await natives.astGrep({
|
|
7839
|
+
patterns: spec.patterns,
|
|
7840
|
+
lang: spec.lang,
|
|
7841
|
+
path: prefix === "" ? root : path8.join(root, prefix),
|
|
7842
|
+
glob: spec.glob,
|
|
7843
|
+
includeMeta: true,
|
|
7844
|
+
limit: matchLimit,
|
|
7845
|
+
timeoutMs: MATCH_TIMEOUT_MS,
|
|
7846
|
+
...signal ? { signal } : {}
|
|
7847
|
+
});
|
|
7848
|
+
if (result.limitReached) truncated = true;
|
|
7849
|
+
for (const match of result.matches) {
|
|
7850
|
+
const relative = toPosix2(match.path);
|
|
7851
|
+
const file = prefix === "" ? relative : `${prefix}/${relative}`;
|
|
7852
|
+
if (assigned.get(file) !== spec.id) continue;
|
|
7853
|
+
const name = match.metaVariables?.NAME;
|
|
7854
|
+
if (name === void 0 || !IDENTIFIER.test(name)) continue;
|
|
7855
|
+
const classification = spec.classify(match.text, match.metaVariables);
|
|
7856
|
+
record(collected, {
|
|
7857
|
+
file,
|
|
7858
|
+
line: match.startLine,
|
|
7859
|
+
kind: classification.kind,
|
|
7860
|
+
name,
|
|
7861
|
+
exported: classification.exported
|
|
7862
|
+
});
|
|
7863
|
+
}
|
|
7864
|
+
}
|
|
7865
|
+
for (const file of fallbackFiles) {
|
|
7866
|
+
throwIfAborted(signal);
|
|
7867
|
+
let code;
|
|
7868
|
+
try {
|
|
7869
|
+
code = await readFile(path8.join(root, file), "utf8");
|
|
7870
|
+
} catch {
|
|
7871
|
+
continue;
|
|
7872
|
+
}
|
|
7873
|
+
if (code.length === 0 || code.length > MAX_FALLBACK_BYTES) continue;
|
|
7874
|
+
let summary;
|
|
7875
|
+
try {
|
|
7876
|
+
summary = natives.summarizeCode({
|
|
7877
|
+
code,
|
|
7878
|
+
path: file,
|
|
7879
|
+
unfoldUntilLines: Math.max(64, countLines(code) >> 2)
|
|
7880
|
+
});
|
|
7881
|
+
} catch {
|
|
7882
|
+
continue;
|
|
7883
|
+
}
|
|
7884
|
+
for (const segment of summary.segments) {
|
|
7885
|
+
if (segment.kind !== "kept" || segment.text === void 0) continue;
|
|
7886
|
+
const lines = segment.text.split("\n");
|
|
7887
|
+
for (let offset = 0; offset < lines.length; offset += 1) {
|
|
7888
|
+
const symbol = fallbackSymbol(file, lines[offset] ?? "", segment.startLine + offset);
|
|
7889
|
+
if (symbol !== void 0) record(collected, symbol);
|
|
7890
|
+
}
|
|
7891
|
+
}
|
|
7892
|
+
}
|
|
7893
|
+
const symbols = [...collected.values()];
|
|
7894
|
+
symbols.sort(compareSymbols);
|
|
7895
|
+
if (symbols.length > request.maxSymbols) {
|
|
7896
|
+
symbols.length = request.maxSymbols;
|
|
7897
|
+
truncated = true;
|
|
7898
|
+
}
|
|
7899
|
+
return {
|
|
7900
|
+
root,
|
|
7901
|
+
symbols,
|
|
7902
|
+
files,
|
|
7903
|
+
languages,
|
|
7904
|
+
fallbackFiles,
|
|
7905
|
+
truncated,
|
|
7906
|
+
elapsedMs: Date.now() - startedAt
|
|
7907
|
+
};
|
|
7908
|
+
}
|
|
7909
|
+
|
|
7910
|
+
// src/providers/codemap-provider.ts
|
|
7911
|
+
var INDEX_TTL_MS = 3e4;
|
|
7912
|
+
var pathField = Type.Optional(Type.String({
|
|
7913
|
+
maxLength: 4096,
|
|
7914
|
+
description: "Directory to index. Relative paths resolve against the session directory; defaults to it. Point this at a project root when the session runs elsewhere."
|
|
7915
|
+
}));
|
|
7916
|
+
var mapSchema = Type.Object({
|
|
7917
|
+
path: pathField,
|
|
7918
|
+
maxTokens: Type.Optional(Type.Number({
|
|
7919
|
+
minimum: 200,
|
|
7920
|
+
maximum: 2e5,
|
|
7921
|
+
description: "Token ceiling for the rendered map"
|
|
7922
|
+
})),
|
|
7923
|
+
glob: Type.Optional(Type.String({
|
|
7924
|
+
maxLength: 512,
|
|
7925
|
+
description: "Glob filter relative to the workspace root"
|
|
7926
|
+
})),
|
|
7927
|
+
focus: Type.Optional(Type.String({
|
|
7928
|
+
maxLength: 512,
|
|
7929
|
+
description: "Task description or symbol name the map should centre on"
|
|
7930
|
+
})),
|
|
7931
|
+
seeds: Type.Optional(Type.Array(Type.String({ maxLength: 1024 }), {
|
|
7932
|
+
maxItems: 32,
|
|
7933
|
+
description: "Files whose git co-change history should raise related files in the ranking"
|
|
7934
|
+
})),
|
|
7935
|
+
refresh: Type.Optional(Type.Boolean({
|
|
7936
|
+
description: "Rebuild the symbol index instead of reusing the cached one"
|
|
7937
|
+
}))
|
|
7938
|
+
}, { additionalProperties: false });
|
|
7939
|
+
var cascadeSchema = Type.Object({
|
|
7940
|
+
path: pathField,
|
|
7941
|
+
seeds: Type.Array(Type.String({ maxLength: 1024 }), {
|
|
7942
|
+
minItems: 1,
|
|
7943
|
+
maxItems: 32,
|
|
7944
|
+
description: "Files to rank co-change against"
|
|
7945
|
+
}),
|
|
7946
|
+
limit: Type.Optional(Type.Number({ minimum: 1, maximum: 200 })),
|
|
7947
|
+
maxCommits: Type.Optional(Type.Number({ minimum: 10, maximum: 2e4 }))
|
|
7948
|
+
}, { additionalProperties: false });
|
|
7949
|
+
var checked = (action, schema, args) => {
|
|
7950
|
+
const validation = validateJsonSchemaValue(schema.toJsonSchema(), args);
|
|
7951
|
+
if (!validation.success) {
|
|
7952
|
+
const message2 = validation.issues.slice(0, 5).map((issue) => issue.message).join("; ");
|
|
7953
|
+
throw new Error(`Invalid codemap.${action} arguments: ${message2}`);
|
|
7954
|
+
}
|
|
7955
|
+
return args;
|
|
7956
|
+
};
|
|
7957
|
+
var resolveRoot = (requested, cwd) => {
|
|
7958
|
+
if (requested === void 0) return cwd;
|
|
7959
|
+
const trimmed = requested.trim();
|
|
7960
|
+
if (trimmed.length === 0) {
|
|
7961
|
+
throw new Error("Invalid codemap path: expected a non-empty directory");
|
|
7962
|
+
}
|
|
7963
|
+
const resolved = path9.isAbsolute(trimmed) ? trimmed : path9.resolve(cwd, trimmed);
|
|
7964
|
+
let stats;
|
|
7965
|
+
try {
|
|
7966
|
+
stats = statSync2(resolved);
|
|
7967
|
+
} catch {
|
|
7968
|
+
throw new Error(`Invalid codemap path: ${resolved} does not exist`);
|
|
7969
|
+
}
|
|
7970
|
+
if (!stats.isDirectory()) {
|
|
7971
|
+
throw new Error(`Invalid codemap path: ${resolved} is not a directory`);
|
|
7972
|
+
}
|
|
7973
|
+
return resolved;
|
|
7974
|
+
};
|
|
7975
|
+
var descriptors = [
|
|
7976
|
+
{
|
|
7977
|
+
name: "map",
|
|
7978
|
+
description: "Repo-wide symbol map under an explicit token budget. Returns one line per symbol (line, kind, name) grouped by file, ranked by focus relevance and optional git co-change, with omission counts when the budget bites. Answers which files and symbols a task touches; use omp.grep for text and omp.read for source.",
|
|
7979
|
+
inputSchema: mapSchema.toJsonSchema(),
|
|
7980
|
+
risk: "read"
|
|
7981
|
+
},
|
|
7982
|
+
{
|
|
7983
|
+
name: "cascade",
|
|
7984
|
+
description: "Rank files by how often they historically changed in the same commits as the seed files, normalised so ubiquitous files (lockfiles, changelogs) do not dominate. Answers which files a change will drag along, which text search cannot.",
|
|
7985
|
+
inputSchema: cascadeSchema.toJsonSchema(),
|
|
7986
|
+
risk: "read"
|
|
7987
|
+
}
|
|
7988
|
+
];
|
|
7989
|
+
var normalizeCodemapArgs = actionArgNormalizer(() => descriptors);
|
|
7990
|
+
var CodemapProvider = class {
|
|
7991
|
+
constructor(config) {
|
|
7992
|
+
this.config = config;
|
|
7993
|
+
}
|
|
7994
|
+
name = "codemap";
|
|
7995
|
+
description = "Structural repo map: budgeted symbol disclosure and git co-change ranking";
|
|
7996
|
+
#cache = /* @__PURE__ */ new Map();
|
|
7997
|
+
async list(request, _context) {
|
|
7998
|
+
const query = request.query?.toLowerCase();
|
|
7999
|
+
return query ? descriptors.filter(
|
|
8000
|
+
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
8001
|
+
) : descriptors;
|
|
8002
|
+
}
|
|
8003
|
+
async describe(actionName, _context) {
|
|
8004
|
+
return descriptors.find((descriptor) => descriptor.name === actionName);
|
|
8005
|
+
}
|
|
8006
|
+
prepareArguments(actionName, args) {
|
|
8007
|
+
return normalizeCodemapArgs(actionName, args);
|
|
8008
|
+
}
|
|
8009
|
+
async #index(root, glob, refresh, signal) {
|
|
8010
|
+
const key = `${root}\0${glob ?? ""}`;
|
|
8011
|
+
const cached = this.#cache.get(key);
|
|
8012
|
+
if (!refresh && cached && Date.now() - cached.at < INDEX_TTL_MS) return cached.index;
|
|
8013
|
+
const index = await buildSymbolIndex({
|
|
8014
|
+
root,
|
|
8015
|
+
...glob !== void 0 ? { glob } : {},
|
|
8016
|
+
maxFiles: this.config.maxFiles,
|
|
8017
|
+
maxSymbols: this.config.maxSymbols,
|
|
8018
|
+
...signal !== void 0 ? { signal } : {}
|
|
8019
|
+
});
|
|
8020
|
+
this.#cache.set(key, { index, at: Date.now() });
|
|
8021
|
+
return index;
|
|
8022
|
+
}
|
|
8023
|
+
async invoke(actionName, args, context) {
|
|
8024
|
+
switch (actionName) {
|
|
8025
|
+
case "map": {
|
|
8026
|
+
const input = checked("map", mapSchema, args);
|
|
8027
|
+
const target = resolveRoot(input.path, context.cwd);
|
|
8028
|
+
const index = await this.#index(target, input.glob, input.refresh === true, context.signal);
|
|
8029
|
+
let cascade;
|
|
8030
|
+
if (input.seeds && input.seeds.length > 0) {
|
|
8031
|
+
cascade = await coChange({
|
|
8032
|
+
root: target,
|
|
8033
|
+
seeds: input.seeds,
|
|
8034
|
+
maxCommits: this.config.cascadeCommits,
|
|
8035
|
+
limit: this.config.cascadeLimit
|
|
8036
|
+
});
|
|
8037
|
+
}
|
|
8038
|
+
const budgeted = assembleMap({
|
|
8039
|
+
index,
|
|
8040
|
+
maxTokens: input.maxTokens ?? this.config.defaultMaxTokens,
|
|
8041
|
+
...input.focus !== void 0 ? { focus: input.focus } : {},
|
|
8042
|
+
...cascade !== void 0 ? { cascade } : {}
|
|
8043
|
+
});
|
|
8044
|
+
context.activity?.({
|
|
8045
|
+
type: "progress",
|
|
8046
|
+
message: `Code map: ${budgeted.symbolsShown} symbols across ${budgeted.filesShown} files${budgeted.truncated ? ` (${budgeted.omittedSymbols} omitted)` : ""}`
|
|
8047
|
+
});
|
|
8048
|
+
return {
|
|
8049
|
+
...budgeted,
|
|
8050
|
+
root: index.root,
|
|
8051
|
+
indexed: {
|
|
8052
|
+
files: index.files.length,
|
|
8053
|
+
symbols: index.symbols.length,
|
|
8054
|
+
languages: index.languages,
|
|
8055
|
+
fallbackFiles: index.fallbackFiles.length,
|
|
8056
|
+
truncated: index.truncated,
|
|
8057
|
+
elapsedMs: index.elapsedMs
|
|
8058
|
+
},
|
|
8059
|
+
...cascade !== void 0 ? { cascade } : {}
|
|
8060
|
+
};
|
|
8061
|
+
}
|
|
8062
|
+
case "cascade": {
|
|
8063
|
+
const input = checked("cascade", cascadeSchema, args);
|
|
8064
|
+
const graph = await coChange({
|
|
8065
|
+
root: resolveRoot(input.path, context.cwd),
|
|
8066
|
+
seeds: input.seeds,
|
|
8067
|
+
maxCommits: input.maxCommits ?? this.config.cascadeCommits,
|
|
8068
|
+
limit: input.limit ?? this.config.cascadeLimit
|
|
8069
|
+
});
|
|
8070
|
+
context.activity?.({
|
|
8071
|
+
type: "progress",
|
|
8072
|
+
message: graph.unavailable ? `Co-change unavailable: ${graph.unavailable}` : `Co-change: ${graph.edges.length} related files from ${graph.commitsScanned} commits`
|
|
8073
|
+
});
|
|
8074
|
+
return graph;
|
|
8075
|
+
}
|
|
8076
|
+
default:
|
|
8077
|
+
throw new Error(`Unknown codemap action: ${actionName}`);
|
|
8078
|
+
}
|
|
8079
|
+
}
|
|
8080
|
+
};
|
|
8081
|
+
|
|
8082
|
+
// src/providers/compact-provider.ts
|
|
8083
|
+
import { Type as Type2 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8084
|
+
import { validateJsonSchemaValue as validateJsonSchemaValue2 } from "@oh-my-pi/pi-ai/utils/schema";
|
|
8085
|
+
var requestSchema = Type2.Object({
|
|
8086
|
+
reason: Type2.Optional(Type2.String({
|
|
6770
8087
|
maxLength: 1024,
|
|
6771
8088
|
description: "Short human-readable reason for the compaction"
|
|
6772
8089
|
})),
|
|
6773
|
-
instructions:
|
|
8090
|
+
instructions: Type2.Optional(Type2.String({
|
|
6774
8091
|
maxLength: MAX_COMPACTION_INSTRUCTIONS_CHARS,
|
|
6775
8092
|
description: "Custom compaction instructions forwarded to OMP core"
|
|
6776
8093
|
})),
|
|
6777
|
-
preserve:
|
|
6778
|
-
|
|
8094
|
+
preserve: Type2.Optional(Type2.Array(
|
|
8095
|
+
Type2.String({ maxLength: MAX_PRESERVE_ITEM_CHARS }),
|
|
6779
8096
|
{
|
|
6780
8097
|
maxItems: MAX_PRESERVE_ITEMS,
|
|
6781
8098
|
description: "Explicit bounded facts to preserve, encoded as a typed Fabric compaction request"
|
|
6782
8099
|
}
|
|
6783
8100
|
)),
|
|
6784
|
-
requestedBy:
|
|
8101
|
+
requestedBy: Type2.Optional(Type2.String({
|
|
6785
8102
|
maxLength: 256,
|
|
6786
8103
|
description: "Who requested the compaction (default: model)"
|
|
6787
8104
|
}))
|
|
6788
8105
|
}, { additionalProperties: false });
|
|
6789
8106
|
var checkedRequestArguments = (args) => {
|
|
6790
|
-
const validation =
|
|
8107
|
+
const validation = validateJsonSchemaValue2(requestSchema.toJsonSchema(), args);
|
|
6791
8108
|
if (!validation.success) {
|
|
6792
8109
|
const message2 = validation.issues.slice(0, 5).map((error) => error.message).join("; ");
|
|
6793
8110
|
throw new Error(`Invalid compact.request arguments: ${message2}`);
|
|
@@ -6811,7 +8128,7 @@ var emptySchema = {
|
|
|
6811
8128
|
properties: {},
|
|
6812
8129
|
additionalProperties: false
|
|
6813
8130
|
};
|
|
6814
|
-
var
|
|
8131
|
+
var descriptors2 = [
|
|
6815
8132
|
{
|
|
6816
8133
|
name: "request",
|
|
6817
8134
|
description: "Request an advisory compaction of the host session's context at the next safe boundary (agent_end). The host commits it only between turns, never mid-turn. A new request replaces any pending one.",
|
|
@@ -6834,7 +8151,7 @@ var descriptors = [
|
|
|
6834
8151
|
risk: "write"
|
|
6835
8152
|
}
|
|
6836
8153
|
];
|
|
6837
|
-
var normalizeCompactArgs = actionArgNormalizer(() =>
|
|
8154
|
+
var normalizeCompactArgs = actionArgNormalizer(() => descriptors2);
|
|
6838
8155
|
var CompactProvider = class {
|
|
6839
8156
|
constructor(controller) {
|
|
6840
8157
|
this.controller = controller;
|
|
@@ -6843,12 +8160,12 @@ var CompactProvider = class {
|
|
|
6843
8160
|
description = "Programmatic, advisory-then-committed context compaction for the host OMP session";
|
|
6844
8161
|
async list(request, _context) {
|
|
6845
8162
|
const query = request.query?.toLowerCase();
|
|
6846
|
-
return query ?
|
|
8163
|
+
return query ? descriptors2.filter(
|
|
6847
8164
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
6848
|
-
) :
|
|
8165
|
+
) : descriptors2;
|
|
6849
8166
|
}
|
|
6850
8167
|
async describe(actionName, _context) {
|
|
6851
|
-
return
|
|
8168
|
+
return descriptors2.find((descriptor) => descriptor.name === actionName);
|
|
6852
8169
|
}
|
|
6853
8170
|
prepareArguments(actionName, args) {
|
|
6854
8171
|
return normalizeCompactArgs(actionName, args);
|
|
@@ -6888,7 +8205,7 @@ var CompactProvider = class {
|
|
|
6888
8205
|
};
|
|
6889
8206
|
|
|
6890
8207
|
// src/providers/components-provider.ts
|
|
6891
|
-
var
|
|
8208
|
+
var descriptors3 = [
|
|
6892
8209
|
{
|
|
6893
8210
|
name: "list",
|
|
6894
8211
|
description: "List registered component definitions and configured component instances.",
|
|
@@ -6935,13 +8252,13 @@ var ComponentsProvider = class {
|
|
|
6935
8252
|
description = "Supervised component lifecycle, exact capability dependencies, effect cleanup, and reload diagnostics.";
|
|
6936
8253
|
async list(request, _context) {
|
|
6937
8254
|
const query = request.query?.normalize("NFKC").trim().toLowerCase();
|
|
6938
|
-
const filtered = query ?
|
|
8255
|
+
const filtered = query ? descriptors3.filter(
|
|
6939
8256
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
6940
|
-
) :
|
|
8257
|
+
) : descriptors3;
|
|
6941
8258
|
return filtered.slice(0, Math.max(1, Math.min(request.limit ?? 100, 100)));
|
|
6942
8259
|
}
|
|
6943
8260
|
async describe(actionName, _context) {
|
|
6944
|
-
return
|
|
8261
|
+
return descriptors3.find((descriptor) => descriptor.name === actionName);
|
|
6945
8262
|
}
|
|
6946
8263
|
async invoke(actionName, args, _context) {
|
|
6947
8264
|
switch (actionName) {
|
|
@@ -6976,7 +8293,7 @@ var ComponentsProvider = class {
|
|
|
6976
8293
|
import fs5 from "node:fs/promises";
|
|
6977
8294
|
import fsSync from "node:fs";
|
|
6978
8295
|
import os from "node:os";
|
|
6979
|
-
import
|
|
8296
|
+
import path10 from "node:path";
|
|
6980
8297
|
var MCP_DESCRIPTOR_CACHE_VERSION = 1;
|
|
6981
8298
|
var homeDir = () => {
|
|
6982
8299
|
const home = process.env.HOME;
|
|
@@ -6987,25 +8304,25 @@ var expandHome = (input) => {
|
|
|
6987
8304
|
const home = homeDir();
|
|
6988
8305
|
if (input === "~") return home;
|
|
6989
8306
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
6990
|
-
return
|
|
8307
|
+
return path10.join(home, input.slice(2));
|
|
6991
8308
|
}
|
|
6992
8309
|
return input;
|
|
6993
8310
|
};
|
|
6994
|
-
var legacyMcporterDir = () =>
|
|
8311
|
+
var legacyMcporterDir = () => path10.join(homeDir(), ".mcporter");
|
|
6995
8312
|
var mcporterConfigDir = () => {
|
|
6996
8313
|
const raw = process.env.XDG_CONFIG_HOME;
|
|
6997
8314
|
if (raw && raw.trim().length > 0) {
|
|
6998
8315
|
const resolved = expandHome(raw.trim());
|
|
6999
|
-
if (
|
|
8316
|
+
if (path10.isAbsolute(resolved)) return path10.join(resolved, "mcporter");
|
|
7000
8317
|
}
|
|
7001
8318
|
return legacyMcporterDir();
|
|
7002
8319
|
};
|
|
7003
8320
|
var mcporterConfigCandidates = () => {
|
|
7004
8321
|
const base = mcporterConfigDir();
|
|
7005
|
-
const candidates = [
|
|
8322
|
+
const candidates = [path10.join(base, "mcporter.json"), path10.join(base, "mcporter.jsonc")];
|
|
7006
8323
|
const legacy = legacyMcporterDir();
|
|
7007
8324
|
if (base !== legacy) {
|
|
7008
|
-
candidates.push(
|
|
8325
|
+
candidates.push(path10.join(legacy, "mcporter.json"), path10.join(legacy, "mcporter.jsonc"));
|
|
7009
8326
|
}
|
|
7010
8327
|
return candidates;
|
|
7011
8328
|
};
|
|
@@ -7020,12 +8337,12 @@ var pathExists = (filePath) => {
|
|
|
7020
8337
|
var mcpConfigLayerPaths = (rootDir, configPath) => {
|
|
7021
8338
|
const explicitRaw = configPath ?? process.env.MCPORTER_CONFIG;
|
|
7022
8339
|
if (explicitRaw && explicitRaw.trim().length > 0) {
|
|
7023
|
-
return [
|
|
8340
|
+
return [path10.resolve(expandHome(explicitRaw.trim()))];
|
|
7024
8341
|
}
|
|
7025
8342
|
const paths = [];
|
|
7026
8343
|
const home = mcporterConfigCandidates().find(pathExists);
|
|
7027
8344
|
if (home) paths.push(home);
|
|
7028
|
-
const projectPath =
|
|
8345
|
+
const projectPath = path10.resolve(rootDir, "config", "mcporter.json");
|
|
7029
8346
|
if (pathExists(projectPath)) paths.push(projectPath);
|
|
7030
8347
|
return paths;
|
|
7031
8348
|
};
|
|
@@ -7076,8 +8393,8 @@ var parseCacheFile = (value) => {
|
|
|
7076
8393
|
servers: value.servers
|
|
7077
8394
|
};
|
|
7078
8395
|
};
|
|
7079
|
-
var projectMcpCachePath = (projectRoot) =>
|
|
7080
|
-
var globalMcpCachePath = (agentDir) =>
|
|
8396
|
+
var projectMcpCachePath = (projectRoot) => path10.join(projectRoot, ".omp", "fabric", "mcp-cache.json");
|
|
8397
|
+
var globalMcpCachePath = (agentDir) => path10.join(agentDir, "fabric", "mcp-descriptors.json");
|
|
7081
8398
|
var tempCounter = 0;
|
|
7082
8399
|
var McpDescriptorCacheStore = class {
|
|
7083
8400
|
constructor(filePath) {
|
|
@@ -7094,9 +8411,9 @@ var McpDescriptorCacheStore = class {
|
|
|
7094
8411
|
// Atomic-ish write: temp file then rename, so a concurrent reader either
|
|
7095
8412
|
// sees the previous cache or the next one, never a torn document.
|
|
7096
8413
|
async save(file) {
|
|
7097
|
-
const directory =
|
|
8414
|
+
const directory = path10.dirname(this.filePath);
|
|
7098
8415
|
await fs5.mkdir(directory, { recursive: true });
|
|
7099
|
-
const tempPath =
|
|
8416
|
+
const tempPath = path10.join(
|
|
7100
8417
|
directory,
|
|
7101
8418
|
`.mcp-cache-${process.pid}-${Date.now()}-${tempCounter++}.tmp`
|
|
7102
8419
|
);
|
|
@@ -7111,7 +8428,7 @@ var McpDescriptorCacheStore = class {
|
|
|
7111
8428
|
};
|
|
7112
8429
|
|
|
7113
8430
|
// src/providers/mcp-provider.ts
|
|
7114
|
-
import
|
|
8431
|
+
import path11 from "node:path";
|
|
7115
8432
|
var TOOL_METADATA_TTL_MS = 6e4;
|
|
7116
8433
|
var REVALIDATE_CONCURRENCY = 3;
|
|
7117
8434
|
var REVALIDATE_SERVER_TIMEOUT_MS = 2e4;
|
|
@@ -7119,6 +8436,7 @@ var MIN_REVALIDATE_SERVER_TIMEOUT_MS = 5e3;
|
|
|
7119
8436
|
var NOTIFY_DEBOUNCE_MS = 100;
|
|
7120
8437
|
var PERSIST_DEBOUNCE_MS = 150;
|
|
7121
8438
|
var COLD_LIST_WAIT_MS = 2500;
|
|
8439
|
+
var MAX_CALL_TIMEOUT_MS = 9e5;
|
|
7122
8440
|
var emptyObjectSchema = {
|
|
7123
8441
|
type: "object",
|
|
7124
8442
|
properties: {},
|
|
@@ -7169,7 +8487,12 @@ var managementDescriptors = [
|
|
|
7169
8487
|
properties: {
|
|
7170
8488
|
server: { type: "string" },
|
|
7171
8489
|
tool: { type: "string" },
|
|
7172
|
-
args: { type: "object", additionalProperties: true }
|
|
8490
|
+
args: { type: "object", additionalProperties: true },
|
|
8491
|
+
timeoutMs: {
|
|
8492
|
+
type: "number",
|
|
8493
|
+
minimum: 1,
|
|
8494
|
+
description: `Per-call timeout overriding mcp.callTimeoutMs, clamped to ${MAX_CALL_TIMEOUT_MS}ms.`
|
|
8495
|
+
}
|
|
7173
8496
|
},
|
|
7174
8497
|
required: ["server", "tool"],
|
|
7175
8498
|
additionalProperties: false
|
|
@@ -7178,19 +8501,20 @@ var managementDescriptors = [
|
|
|
7178
8501
|
namespace: "management"
|
|
7179
8502
|
}
|
|
7180
8503
|
];
|
|
8504
|
+
var resolveMcpCallTimeoutMs = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.min(Math.floor(value), MAX_CALL_TIMEOUT_MS) : fallback;
|
|
7181
8505
|
var normalizeSchema = (schema) => typeof schema === "object" && schema !== null && !Array.isArray(schema) ? schema : emptyObjectSchema;
|
|
7182
8506
|
var normalizeMcpResult = (result) => {
|
|
7183
8507
|
if (typeof result !== "object" || result === null || Array.isArray(result)) return result;
|
|
7184
|
-
const
|
|
7185
|
-
if (!Array.isArray(
|
|
7186
|
-
const text =
|
|
8508
|
+
const record2 = result;
|
|
8509
|
+
if (!Array.isArray(record2.content)) return result;
|
|
8510
|
+
const text = record2.content.filter(
|
|
7187
8511
|
(part) => typeof part === "object" && part !== null && part.type === "text" && typeof part.text === "string"
|
|
7188
8512
|
).map((part) => part.text).join("\n");
|
|
7189
|
-
if (
|
|
8513
|
+
if (record2.isError === true) throw new Error(text || "MCP tool returned an error");
|
|
7190
8514
|
return {
|
|
7191
8515
|
text,
|
|
7192
|
-
content:
|
|
7193
|
-
structuredContent:
|
|
8516
|
+
content: record2.content,
|
|
8517
|
+
structuredContent: record2.structuredContent ?? null
|
|
7194
8518
|
};
|
|
7195
8519
|
};
|
|
7196
8520
|
var delay2 = (ms, signal) => new Promise((resolve2) => {
|
|
@@ -7265,9 +8589,9 @@ var McpProvider = class {
|
|
|
7265
8589
|
this.#kickRevalidation();
|
|
7266
8590
|
if (!request.namespace) await this.#awaitColdEnumeration(context.signal);
|
|
7267
8591
|
const query = request.query?.toLowerCase();
|
|
7268
|
-
const filterQuery = (
|
|
8592
|
+
const filterQuery = (descriptors7) => query ? descriptors7.filter(
|
|
7269
8593
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
7270
|
-
) :
|
|
8594
|
+
) : descriptors7;
|
|
7271
8595
|
if (request.namespace) {
|
|
7272
8596
|
const server = await this.#resolveKnownServer(request.namespace);
|
|
7273
8597
|
if (!server) return [];
|
|
@@ -7365,7 +8689,13 @@ var McpProvider = class {
|
|
|
7365
8689
|
const server = String(args.server);
|
|
7366
8690
|
const tool = String(args.tool);
|
|
7367
8691
|
const toolArgs = typeof args.args === "object" && args.args !== null && !Array.isArray(args.args) ? args.args : {};
|
|
7368
|
-
return this.#call(
|
|
8692
|
+
return this.#call(
|
|
8693
|
+
server,
|
|
8694
|
+
tool,
|
|
8695
|
+
toolArgs,
|
|
8696
|
+
context.signal,
|
|
8697
|
+
resolveMcpCallTimeoutMs(args.timeoutMs, this.config.callTimeoutMs)
|
|
8698
|
+
);
|
|
7369
8699
|
}
|
|
7370
8700
|
const parsed = this.#parseToolName(actionName);
|
|
7371
8701
|
if (!parsed) throw new Error(`Invalid MCP action: ${actionName}`);
|
|
@@ -7416,11 +8746,11 @@ var McpProvider = class {
|
|
|
7416
8746
|
// Provider-fidelity descriptors for everything currently known, cached or
|
|
7417
8747
|
// ephemeral.
|
|
7418
8748
|
sliceDescriptors() {
|
|
7419
|
-
const
|
|
8749
|
+
const descriptors7 = [];
|
|
7420
8750
|
for (const [server, entry] of this.#servers) {
|
|
7421
|
-
for (const tool of entry.tools)
|
|
8751
|
+
for (const tool of entry.tools) descriptors7.push(this.#toolDescriptor(server, tool));
|
|
7422
8752
|
}
|
|
7423
|
-
return
|
|
8753
|
+
return descriptors7;
|
|
7424
8754
|
}
|
|
7425
8755
|
// Test/ops hook: await hydration and any in-flight background revalidation,
|
|
7426
8756
|
// then flush pending persistence and notifications.
|
|
@@ -7438,8 +8768,8 @@ var McpProvider = class {
|
|
|
7438
8768
|
}
|
|
7439
8769
|
if (this.#dirtyPersist) await this.#persistNow().catch(() => void 0);
|
|
7440
8770
|
}
|
|
7441
|
-
async #call(serverName, toolName, args, signal) {
|
|
7442
|
-
if (!this.#cacheOn) return this.#callLegacy(serverName, toolName, args, signal);
|
|
8771
|
+
async #call(serverName, toolName, args, signal, timeoutMs) {
|
|
8772
|
+
if (!this.#cacheOn) return this.#callLegacy(serverName, toolName, args, signal, timeoutMs);
|
|
7443
8773
|
if (signal?.aborted) throw new Error("MCP call cancelled");
|
|
7444
8774
|
await this.#hydrate();
|
|
7445
8775
|
const server = await this.#resolveKnownServer(serverName);
|
|
@@ -7457,7 +8787,7 @@ var McpProvider = class {
|
|
|
7457
8787
|
if (firstContact) this.#recontacted.add(server);
|
|
7458
8788
|
const operation = runtime.callTool(server, tool.name, {
|
|
7459
8789
|
args,
|
|
7460
|
-
timeoutMs: this.config.callTimeoutMs,
|
|
8790
|
+
timeoutMs: timeoutMs ?? this.config.callTimeoutMs,
|
|
7461
8791
|
disableOAuth: this.config.disableOAuth
|
|
7462
8792
|
});
|
|
7463
8793
|
try {
|
|
@@ -7822,7 +9152,7 @@ var McpProvider = class {
|
|
|
7822
9152
|
kind: "stdio",
|
|
7823
9153
|
command: args.command,
|
|
7824
9154
|
args: commandArgs,
|
|
7825
|
-
cwd:
|
|
9155
|
+
cwd: path11.resolve(this.cwd, typeof args.cwd === "string" ? args.cwd : ".")
|
|
7826
9156
|
},
|
|
7827
9157
|
...env ? { env } : {}
|
|
7828
9158
|
};
|
|
@@ -7887,13 +9217,13 @@ var McpProvider = class {
|
|
|
7887
9217
|
return tools.map((tool) => this.#toolDescriptor(server, tool));
|
|
7888
9218
|
})
|
|
7889
9219
|
);
|
|
7890
|
-
const
|
|
9220
|
+
const descriptors7 = settled.flatMap(
|
|
7891
9221
|
(entry) => entry.status === "fulfilled" ? entry.value : []
|
|
7892
9222
|
);
|
|
7893
9223
|
const query = request.query?.toLowerCase();
|
|
7894
|
-
const filtered = query ?
|
|
9224
|
+
const filtered = query ? descriptors7.filter(
|
|
7895
9225
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
7896
|
-
) :
|
|
9226
|
+
) : descriptors7;
|
|
7897
9227
|
return request.namespace ? filtered : [...managementDescriptors, ...filtered];
|
|
7898
9228
|
}
|
|
7899
9229
|
async #describeLegacy(actionName, _context) {
|
|
@@ -7905,7 +9235,7 @@ var McpProvider = class {
|
|
|
7905
9235
|
const tool = await this.#findToolLegacy(runtime, server, parsed.tool);
|
|
7906
9236
|
return tool ? this.#toolDescriptor(server, tool) : void 0;
|
|
7907
9237
|
}
|
|
7908
|
-
async #callLegacy(serverName, toolName, args, signal) {
|
|
9238
|
+
async #callLegacy(serverName, toolName, args, signal, timeoutMs) {
|
|
7909
9239
|
if (signal?.aborted) throw new Error("MCP call cancelled");
|
|
7910
9240
|
const runtime = await this.#getRuntime();
|
|
7911
9241
|
const server = this.#resolveServerName(runtime, serverName);
|
|
@@ -7915,7 +9245,7 @@ var McpProvider = class {
|
|
|
7915
9245
|
if (!tool) throw new Error(`Unknown MCP tool: ${serverName}.${toolName}`);
|
|
7916
9246
|
const operation = runtime.callTool(server, tool.name, {
|
|
7917
9247
|
args,
|
|
7918
|
-
timeoutMs: this.config.callTimeoutMs,
|
|
9248
|
+
timeoutMs: timeoutMs ?? this.config.callTimeoutMs,
|
|
7919
9249
|
disableOAuth: this.config.disableOAuth
|
|
7920
9250
|
});
|
|
7921
9251
|
try {
|
|
@@ -7965,7 +9295,7 @@ var assertReadableStateKey = (key) => {
|
|
|
7965
9295
|
throw new Error(`Fabric mesh key is private host state: ${key}`);
|
|
7966
9296
|
}
|
|
7967
9297
|
};
|
|
7968
|
-
var
|
|
9298
|
+
var descriptors4 = [
|
|
7969
9299
|
{
|
|
7970
9300
|
name: "self",
|
|
7971
9301
|
description: "Return this Fabric participant's mesh identity",
|
|
@@ -8019,7 +9349,11 @@ var descriptors3 = [
|
|
|
8019
9349
|
items: { type: "string", enum: ["root", "agent", "actor"] }
|
|
8020
9350
|
},
|
|
8021
9351
|
includeStale: { type: "boolean" },
|
|
8022
|
-
limit: { type: "number", minimum: 1 }
|
|
9352
|
+
limit: { type: "number", minimum: 1 },
|
|
9353
|
+
withTotal: {
|
|
9354
|
+
type: "boolean",
|
|
9355
|
+
description: "Return { members, total, truncated } instead of a bare array, so a clipped page is distinguishable from a complete one."
|
|
9356
|
+
}
|
|
8023
9357
|
},
|
|
8024
9358
|
additionalProperties: false
|
|
8025
9359
|
},
|
|
@@ -8045,7 +9379,11 @@ var descriptors3 = [
|
|
|
8045
9379
|
type: "object",
|
|
8046
9380
|
properties: {
|
|
8047
9381
|
prefix: { type: "string" },
|
|
8048
|
-
limit: { type: "number", minimum: 1 }
|
|
9382
|
+
limit: { type: "number", minimum: 1 },
|
|
9383
|
+
withTotal: {
|
|
9384
|
+
type: "boolean",
|
|
9385
|
+
description: "Return { entries, total, truncated } instead of a bare array, so a clipped page is distinguishable from a complete one."
|
|
9386
|
+
}
|
|
8049
9387
|
},
|
|
8050
9388
|
additionalProperties: false
|
|
8051
9389
|
},
|
|
@@ -8084,7 +9422,7 @@ var descriptors3 = [
|
|
|
8084
9422
|
namespace: "coordination"
|
|
8085
9423
|
}
|
|
8086
9424
|
];
|
|
8087
|
-
var normalizeMeshArgs = actionArgNormalizer(() =>
|
|
9425
|
+
var normalizeMeshArgs = actionArgNormalizer(() => descriptors4);
|
|
8088
9426
|
var MeshProvider = class {
|
|
8089
9427
|
constructor(store, identity, participants) {
|
|
8090
9428
|
this.store = store;
|
|
@@ -8095,12 +9433,12 @@ var MeshProvider = class {
|
|
|
8095
9433
|
description = "Durable topics and compare-and-swap shared state for emergent agent coordination";
|
|
8096
9434
|
async list(request, _context) {
|
|
8097
9435
|
const query = request.query?.toLowerCase();
|
|
8098
|
-
return query ?
|
|
9436
|
+
return query ? descriptors4.filter(
|
|
8099
9437
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
8100
|
-
) :
|
|
9438
|
+
) : descriptors4;
|
|
8101
9439
|
}
|
|
8102
9440
|
async describe(actionName, _context) {
|
|
8103
|
-
return
|
|
9441
|
+
return descriptors4.find((descriptor) => descriptor.name === actionName);
|
|
8104
9442
|
}
|
|
8105
9443
|
prepareArguments(actionName, args) {
|
|
8106
9444
|
return normalizeMeshArgs(actionName, args);
|
|
@@ -8136,11 +9474,13 @@ var MeshProvider = class {
|
|
|
8136
9474
|
) : void 0;
|
|
8137
9475
|
const scope = args.scope === "local" || args.scope === "lineage" || args.scope === "project" ? args.scope : "project";
|
|
8138
9476
|
const limit = Math.max(1, Math.floor(typeof args.limit === "number" ? args.limit : 100));
|
|
8139
|
-
|
|
9477
|
+
const matched = this.participants.list({
|
|
8140
9478
|
scope,
|
|
8141
9479
|
...kinds ? { kinds } : {},
|
|
8142
9480
|
...args.includeStale === true ? { includeStale: true } : {}
|
|
8143
|
-
})
|
|
9481
|
+
});
|
|
9482
|
+
const members = matched.slice(0, limit);
|
|
9483
|
+
return args.withTotal === true ? { members, total: matched.length, truncated: matched.length > members.length } : members;
|
|
8144
9484
|
}
|
|
8145
9485
|
case "get": {
|
|
8146
9486
|
const key = String(args.key);
|
|
@@ -8157,11 +9497,13 @@ var MeshProvider = class {
|
|
|
8157
9497
|
this.store.maxReadEvents
|
|
8158
9498
|
)
|
|
8159
9499
|
);
|
|
8160
|
-
|
|
9500
|
+
const matched = this.store.listAll(prefix).filter(
|
|
8161
9501
|
(entry) => !PRIVATE_STATE_PREFIXES.some(
|
|
8162
9502
|
(privatePrefix) => entry.key.startsWith(privatePrefix)
|
|
8163
9503
|
)
|
|
8164
|
-
)
|
|
9504
|
+
);
|
|
9505
|
+
const entries = matched.slice(0, limit);
|
|
9506
|
+
return args.withTotal === true ? { entries, total: matched.length, truncated: matched.length > entries.length } : entries;
|
|
8165
9507
|
}
|
|
8166
9508
|
case "put": {
|
|
8167
9509
|
const key = String(args.key);
|
|
@@ -8188,13 +9530,14 @@ var MeshProvider = class {
|
|
|
8188
9530
|
};
|
|
8189
9531
|
|
|
8190
9532
|
// src/providers/omp-tools-provider.ts
|
|
8191
|
-
import { mkdirSync as mkdirSync2, mkdtempSync, readFileSync as readFileSync2, statSync as
|
|
9533
|
+
import { mkdirSync as mkdirSync2, mkdtempSync, readFileSync as readFileSync2, statSync as statSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
8192
9534
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8193
9535
|
import os2 from "node:os";
|
|
8194
|
-
import
|
|
9536
|
+
import path14 from "node:path";
|
|
8195
9537
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
8196
9538
|
import { BashTool } from "@oh-my-pi/pi-coding-agent/tools/bash";
|
|
8197
9539
|
import { EditTool } from "@oh-my-pi/pi-coding-agent/edit";
|
|
9540
|
+
import { GlobTool } from "@oh-my-pi/pi-coding-agent/tools/glob";
|
|
8198
9541
|
import { GrepTool, MULTI_FILE_PER_FILE_MATCHES, SINGLE_FILE_MATCHES } from "@oh-my-pi/pi-coding-agent/tools/grep";
|
|
8199
9542
|
import { ReadTool } from "@oh-my-pi/pi-coding-agent/tools/read";
|
|
8200
9543
|
import { piEscapeRegexLiteral, piJoinPath } from "@oh-my-pi/pi-ai/providers/cursor-pi-args";
|
|
@@ -8207,7 +9550,7 @@ import {
|
|
|
8207
9550
|
|
|
8208
9551
|
// src/agents/bash-worktree-add.ts
|
|
8209
9552
|
import fs6 from "node:fs";
|
|
8210
|
-
import
|
|
9553
|
+
import path12 from "node:path";
|
|
8211
9554
|
var BARE_SAFE = /^[A-Za-z0-9_./:@%+=,-]+$/;
|
|
8212
9555
|
var parseGitWorktreeAdd = (command) => {
|
|
8213
9556
|
const trimmed = command.trim();
|
|
@@ -8270,8 +9613,8 @@ var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
|
8270
9613
|
if (typeof command !== "string") return void 0;
|
|
8271
9614
|
const parsed = parseGitWorktreeAdd(command);
|
|
8272
9615
|
if (!parsed) return void 0;
|
|
8273
|
-
const gitCwd = parsed.gitCwd ?
|
|
8274
|
-
const dest =
|
|
9616
|
+
const gitCwd = parsed.gitCwd ? path12.resolve(sessionCwd, parsed.gitCwd) : typeof args.cwd === "string" ? args.cwd : sessionCwd;
|
|
9617
|
+
const dest = path12.resolve(gitCwd, parsed.dest);
|
|
8275
9618
|
let gitRoot;
|
|
8276
9619
|
try {
|
|
8277
9620
|
const root = await executeFile("git", ["rev-parse", "--show-toplevel"], {
|
|
@@ -8299,10 +9642,10 @@ var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
|
8299
9642
|
};
|
|
8300
9643
|
|
|
8301
9644
|
// src/providers/omp-bash-cwd.ts
|
|
8302
|
-
import { accessSync, constants, statSync as
|
|
8303
|
-
import
|
|
9645
|
+
import { accessSync, constants, statSync as statSync3 } from "node:fs";
|
|
9646
|
+
import path13 from "node:path";
|
|
8304
9647
|
import { createBashToolDefinition } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-pi-coding-agent-shim";
|
|
8305
|
-
import { Type as
|
|
9648
|
+
import { Type as Type3 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8306
9649
|
var OMP_BASH_CWD_KEY = "cwd";
|
|
8307
9650
|
var resolveOmpShellCwd = (toolName, sessionCwd, requested) => {
|
|
8308
9651
|
if (typeof requested !== "string" || requested.trim().length === 0) {
|
|
@@ -8310,9 +9653,9 @@ var resolveOmpShellCwd = (toolName, sessionCwd, requested) => {
|
|
|
8310
9653
|
`Invalid omp.${toolName} cwd ${JSON.stringify(requested)}: path must be a non-empty string`
|
|
8311
9654
|
);
|
|
8312
9655
|
}
|
|
8313
|
-
const resolved =
|
|
9656
|
+
const resolved = path13.isAbsolute(requested) ? path13.resolve(requested) : path13.resolve(sessionCwd, requested);
|
|
8314
9657
|
try {
|
|
8315
|
-
if (!
|
|
9658
|
+
if (!statSync3(resolved).isDirectory()) throw new Error("path is not a directory");
|
|
8316
9659
|
accessSync(resolved, constants.R_OK | constants.X_OK);
|
|
8317
9660
|
} catch (error) {
|
|
8318
9661
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -8330,8 +9673,8 @@ var resolveShellCwdArgument = (toolName, sessionCwd, args) => Object.hasOwn(args
|
|
|
8330
9673
|
args[OMP_BASH_CWD_KEY]
|
|
8331
9674
|
)
|
|
8332
9675
|
} : args;
|
|
8333
|
-
var CWD_PROPERTY =
|
|
8334
|
-
|
|
9676
|
+
var CWD_PROPERTY = Type3.Optional(
|
|
9677
|
+
Type3.String({
|
|
8335
9678
|
description: "Execution directory for this command; relative paths resolve from the session cwd."
|
|
8336
9679
|
})
|
|
8337
9680
|
);
|
|
@@ -8350,7 +9693,7 @@ var withShellCwdSchema = (schema) => {
|
|
|
8350
9693
|
if (Object.hasOwn(document.properties, OMP_BASH_CWD_KEY)) return schema;
|
|
8351
9694
|
const cwdSchema = schemaDocument2(CWD_PROPERTY);
|
|
8352
9695
|
if (!cwdSchema) return schema;
|
|
8353
|
-
return
|
|
9696
|
+
return Type3.Unsafe({
|
|
8354
9697
|
...document,
|
|
8355
9698
|
properties: { ...document.properties, [OMP_BASH_CWD_KEY]: cwdSchema }
|
|
8356
9699
|
});
|
|
@@ -8385,28 +9728,49 @@ var BashCwdDefinitions = class extends ShellCwdDefinitions {
|
|
|
8385
9728
|
|
|
8386
9729
|
// src/providers/write-preview.ts
|
|
8387
9730
|
import { homedir } from "node:os";
|
|
8388
|
-
import { dirname, isAbsolute, resolve } from "node:path";
|
|
8389
|
-
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
8390
|
-
import { Type as
|
|
9731
|
+
import { dirname, isAbsolute, resolve, win32 } from "node:path";
|
|
9732
|
+
import { mkdir, readFile as readFile2, stat, writeFile } from "node:fs/promises";
|
|
9733
|
+
import { Type as Type4 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8391
9734
|
var mutationQueues = /* @__PURE__ */ new Map();
|
|
8392
|
-
var withFileMutationQueue = async (
|
|
8393
|
-
const previous = mutationQueues.get(
|
|
9735
|
+
var withFileMutationQueue = async (path20, operation) => {
|
|
9736
|
+
const previous = mutationQueues.get(path20) ?? Promise.resolve();
|
|
8394
9737
|
let release;
|
|
8395
9738
|
const current = new Promise((resolve2) => {
|
|
8396
9739
|
release = resolve2;
|
|
8397
9740
|
});
|
|
8398
|
-
mutationQueues.set(
|
|
9741
|
+
mutationQueues.set(path20, current);
|
|
8399
9742
|
await previous;
|
|
8400
9743
|
try {
|
|
8401
9744
|
return await operation();
|
|
8402
9745
|
} finally {
|
|
8403
9746
|
release();
|
|
8404
|
-
if (mutationQueues.get(
|
|
9747
|
+
if (mutationQueues.get(path20) === current) mutationQueues.delete(path20);
|
|
8405
9748
|
}
|
|
8406
9749
|
};
|
|
9750
|
+
var URI_LIKE_WRITE_TARGET_RE = /^([a-z][a-z0-9+.-]*):\/{1,2}/i;
|
|
9751
|
+
var OmpWriteUriTargetError = class extends Error {
|
|
9752
|
+
path;
|
|
9753
|
+
constructor(message2, path20) {
|
|
9754
|
+
super(message2);
|
|
9755
|
+
this.name = "OmpWriteUriTargetError";
|
|
9756
|
+
this.path = path20;
|
|
9757
|
+
}
|
|
9758
|
+
};
|
|
9759
|
+
var assertFilesystemWriteTarget = (candidate, reported) => {
|
|
9760
|
+
const trimmed = candidate.trim();
|
|
9761
|
+
if (win32.isAbsolute(trimmed)) return;
|
|
9762
|
+
const scheme = URI_LIKE_WRITE_TARGET_RE.exec(trimmed)?.[1]?.toLowerCase();
|
|
9763
|
+
if (scheme === void 0) return;
|
|
9764
|
+
const guidance = scheme === "xd" ? "Tool devices are dispatched by the top-level `write` tool, which carries the xd:// transport; omp.write writes files." : "omp.write resolves filesystem paths only.";
|
|
9765
|
+
throw new OmpWriteUriTargetError(
|
|
9766
|
+
`Refusing to write '${reported}': '${scheme}://' is a URI scheme, not a directory. ${guidance} Prefix the path with './' to create a literal file by that name.`,
|
|
9767
|
+
reported
|
|
9768
|
+
);
|
|
9769
|
+
};
|
|
8407
9770
|
var resolvePreviewPath = (filePath, cwd) => {
|
|
8408
9771
|
let expanded = filePath.startsWith("@") ? filePath.slice(1) : filePath;
|
|
8409
9772
|
expanded = expanded.replace(/[\u00a0\u2000-\u200a\u202f\u205f\u3000]/g, " ");
|
|
9773
|
+
assertFilesystemWriteTarget(expanded, filePath);
|
|
8410
9774
|
if (expanded === "~") expanded = homedir();
|
|
8411
9775
|
else if (expanded.startsWith("~/")) expanded = homedir() + expanded.slice(1);
|
|
8412
9776
|
return isAbsolute(expanded) ? expanded : resolve(cwd, expanded);
|
|
@@ -8436,7 +9800,7 @@ var readExistingFileForPreview = async (filePath, cwd, nextContent) => {
|
|
|
8436
9800
|
return skipped("previous file too large", fileStat.size, true);
|
|
8437
9801
|
}
|
|
8438
9802
|
try {
|
|
8439
|
-
const content = await
|
|
9803
|
+
const content = await readFile2(absolutePath, "utf8");
|
|
8440
9804
|
const bytes = Buffer.byteLength(content, "utf8");
|
|
8441
9805
|
return bytes > MAX_WRITE_DIFF_BYTES ? skipped("previous file too large", bytes, true) : { kind: "content", content };
|
|
8442
9806
|
} catch {
|
|
@@ -8448,20 +9812,20 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
8448
9812
|
name: "write",
|
|
8449
9813
|
label: "Write",
|
|
8450
9814
|
description: "Write a file",
|
|
8451
|
-
parameters:
|
|
9815
|
+
parameters: Type4.Object({ path: Type4.String(), content: Type4.String() }),
|
|
8452
9816
|
execute: async () => ({ content: [{ type: "text", text: "" }] })
|
|
8453
9817
|
};
|
|
8454
9818
|
return {
|
|
8455
9819
|
...original,
|
|
8456
9820
|
async execute(_toolCallId, params, signal) {
|
|
8457
|
-
const { path:
|
|
8458
|
-
const absolutePath = resolvePreviewPath(
|
|
9821
|
+
const { path: path20, content } = params;
|
|
9822
|
+
const absolutePath = resolvePreviewPath(path20, cwd);
|
|
8459
9823
|
return withFileMutationQueue(absolutePath, async () => {
|
|
8460
9824
|
const throwIfAborted2 = () => {
|
|
8461
9825
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
8462
9826
|
};
|
|
8463
9827
|
throwIfAborted2();
|
|
8464
|
-
const before = await readExistingFileForPreview(
|
|
9828
|
+
const before = await readExistingFileForPreview(path20, cwd, content);
|
|
8465
9829
|
throwIfAborted2();
|
|
8466
9830
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
8467
9831
|
throwIfAborted2();
|
|
@@ -8471,7 +9835,7 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
8471
9835
|
content: [
|
|
8472
9836
|
{
|
|
8473
9837
|
type: "text",
|
|
8474
|
-
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${
|
|
9838
|
+
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${path20}`
|
|
8475
9839
|
}
|
|
8476
9840
|
],
|
|
8477
9841
|
details: { codePreviewBeforeWrite: before }
|
|
@@ -8486,7 +9850,7 @@ var MAX_RENDERER_ARGUMENT_CHARS = 2e5;
|
|
|
8486
9850
|
var GUEST_READ_LINE_LIMIT = 1e5;
|
|
8487
9851
|
var MAX_REPLACE_ALL_FILE_CHARS = 2e6;
|
|
8488
9852
|
var createNativeSession = (cwd, artifactPaths) => {
|
|
8489
|
-
const artifactRoot = artifactPaths ? mkdtempSync(
|
|
9853
|
+
const artifactRoot = artifactPaths ? mkdtempSync(path14.join(os2.tmpdir(), "omp-fabric-bash-")) : void 0;
|
|
8490
9854
|
return {
|
|
8491
9855
|
cwd,
|
|
8492
9856
|
hasUI: false,
|
|
@@ -8503,7 +9867,7 @@ var createNativeSession = (cwd, artifactPaths) => {
|
|
|
8503
9867
|
try {
|
|
8504
9868
|
mkdirSync2(artifactRoot, { recursive: true, mode: 448 });
|
|
8505
9869
|
const id = randomUUID3();
|
|
8506
|
-
const artifactPath =
|
|
9870
|
+
const artifactPath = path14.join(artifactRoot, `${toolType}-${id}.log`);
|
|
8507
9871
|
writeFileSync2(artifactPath, "", { mode: 384 });
|
|
8508
9872
|
artifactPaths.set(id, artifactPath);
|
|
8509
9873
|
artifactAllocations.getStore()?.push(artifactPath);
|
|
@@ -8544,12 +9908,28 @@ var GREP_SKIP_PROPERTY = {
|
|
|
8544
9908
|
type: "number",
|
|
8545
9909
|
description: "Files to skip before collecting results \u2014 paginate when a search hit the file limit"
|
|
8546
9910
|
};
|
|
8547
|
-
var
|
|
8548
|
-
|
|
9911
|
+
var GITIGNORE_PROPERTY = {
|
|
9912
|
+
type: "boolean",
|
|
9913
|
+
description: "Respect gitignore rules; pass false to search ignored files such as build output or .env"
|
|
9914
|
+
};
|
|
9915
|
+
var HIDDEN_PROPERTY = {
|
|
9916
|
+
type: "boolean",
|
|
9917
|
+
description: "Include dotfiles and hidden directories"
|
|
9918
|
+
};
|
|
9919
|
+
var withExtraProperties = (document, extras) => {
|
|
9920
|
+
const source = typeof document === "function" && "toJsonSchema" in document ? document.toJsonSchema() : document;
|
|
9921
|
+
const schema = asRecord(source);
|
|
8549
9922
|
const properties = asRecord(schema?.properties);
|
|
8550
|
-
if (!schema || !properties
|
|
8551
|
-
|
|
9923
|
+
if (!schema || !properties) return document;
|
|
9924
|
+
const additions = {};
|
|
9925
|
+
for (const [name, property] of Object.entries(extras)) {
|
|
9926
|
+
if (!Object.hasOwn(properties, name)) additions[name] = property;
|
|
9927
|
+
}
|
|
9928
|
+
if (Object.keys(additions).length === 0) return document;
|
|
9929
|
+
return { ...schema, properties: { ...properties, ...additions } };
|
|
8552
9930
|
};
|
|
9931
|
+
var withGrepSkipSchema = (document) => withExtraProperties(document, { skip: GREP_SKIP_PROPERTY, gitignore: GITIGNORE_PROPERTY });
|
|
9932
|
+
var withFindFilterSchema = (document) => withExtraProperties(document, { gitignore: GITIGNORE_PROPERTY, hidden: HIDDEN_PROPERTY });
|
|
8553
9933
|
var grepSession = (cwd, context) => ({
|
|
8554
9934
|
cwd,
|
|
8555
9935
|
hasUI: false,
|
|
@@ -8566,20 +9946,50 @@ var createGrepDefinitionWithSkip = (cwd) => {
|
|
|
8566
9946
|
...legacy,
|
|
8567
9947
|
parameters: withGrepSkipSchema(legacy.parameters),
|
|
8568
9948
|
execute: (toolCallId, params, signal, onUpdate, context) => {
|
|
8569
|
-
const
|
|
8570
|
-
const rawPattern = typeof
|
|
8571
|
-
const searchPath = typeof
|
|
8572
|
-
const glob = typeof
|
|
8573
|
-
const contextLines = typeof
|
|
8574
|
-
const skip = typeof
|
|
9949
|
+
const record2 = asRecord(params) ?? {};
|
|
9950
|
+
const rawPattern = typeof record2.pattern === "string" ? record2.pattern : "";
|
|
9951
|
+
const searchPath = typeof record2.path === "string" ? record2.path : ".";
|
|
9952
|
+
const glob = typeof record2.glob === "string" ? record2.glob : void 0;
|
|
9953
|
+
const contextLines = typeof record2.context === "number" ? record2.context : void 0;
|
|
9954
|
+
const skip = typeof record2.skip === "number" ? record2.skip : void 0;
|
|
8575
9955
|
const tool = contextLines === void 0 ? defaultTool : new GrepTool(grepSession(cwd, contextLines));
|
|
8576
9956
|
return tool.execute(
|
|
8577
9957
|
toolCallId,
|
|
8578
9958
|
{
|
|
8579
|
-
pattern:
|
|
9959
|
+
pattern: record2.literal === true ? piEscapeRegexLiteral(rawPattern) : rawPattern,
|
|
8580
9960
|
path: glob ? piJoinPath(searchPath, glob) : searchPath,
|
|
8581
|
-
case:
|
|
8582
|
-
...skip === void 0 ? {} : { skip }
|
|
9961
|
+
case: record2.ignoreCase === true ? false : void 0,
|
|
9962
|
+
...skip === void 0 ? {} : { skip },
|
|
9963
|
+
...typeof record2.gitignore === "boolean" ? { gitignore: record2.gitignore } : {}
|
|
9964
|
+
},
|
|
9965
|
+
signal,
|
|
9966
|
+
onUpdate,
|
|
9967
|
+
context
|
|
9968
|
+
);
|
|
9969
|
+
}
|
|
9970
|
+
};
|
|
9971
|
+
};
|
|
9972
|
+
var createFindDefinitionWithFilters = (cwd) => {
|
|
9973
|
+
const legacy = createFindToolDefinition(cwd);
|
|
9974
|
+
const tool = new GlobTool(grepSession(cwd));
|
|
9975
|
+
return {
|
|
9976
|
+
...legacy,
|
|
9977
|
+
parameters: withFindFilterSchema(legacy.parameters),
|
|
9978
|
+
execute: (toolCallId, params, signal, onUpdate, context) => {
|
|
9979
|
+
const record2 = asRecord(params) ?? {};
|
|
9980
|
+
if (typeof record2.gitignore !== "boolean" && typeof record2.hidden !== "boolean") {
|
|
9981
|
+
return legacy.execute(toolCallId, params, signal, onUpdate, context);
|
|
9982
|
+
}
|
|
9983
|
+
const pattern = typeof record2.pattern === "string" ? record2.pattern : void 0;
|
|
9984
|
+
const searchPath = typeof record2.path === "string" ? record2.path : void 0;
|
|
9985
|
+
const limit = typeof record2.limit === "number" ? record2.limit : void 0;
|
|
9986
|
+
return tool.execute(
|
|
9987
|
+
toolCallId,
|
|
9988
|
+
{
|
|
9989
|
+
path: piJoinPath(searchPath ?? ".", pattern ?? "*"),
|
|
9990
|
+
...limit === void 0 ? {} : { limit },
|
|
9991
|
+
...typeof record2.gitignore === "boolean" ? { gitignore: record2.gitignore } : {},
|
|
9992
|
+
...typeof record2.hidden === "boolean" ? { hidden: record2.hidden } : {}
|
|
8583
9993
|
},
|
|
8584
9994
|
signal,
|
|
8585
9995
|
onUpdate,
|
|
@@ -8598,19 +10008,19 @@ var normalizeEditArguments = (args, replaceAll, cwd) => {
|
|
|
8598
10008
|
if (typeof edit !== "object" || edit === null || Array.isArray(edit)) {
|
|
8599
10009
|
throw new Error(`omp.edit edits[${index}] must be an object`);
|
|
8600
10010
|
}
|
|
8601
|
-
const
|
|
8602
|
-
const oldString =
|
|
8603
|
-
const newString =
|
|
10011
|
+
const record2 = edit;
|
|
10012
|
+
const oldString = record2.old_string ?? record2.oldText ?? record2.old;
|
|
10013
|
+
const newString = record2.new_string ?? record2.newText ?? record2.new ?? record2.replacement;
|
|
8604
10014
|
if (typeof oldString !== "string" || typeof newString !== "string") {
|
|
8605
10015
|
throw new Error(`omp.edit edits[${index}] requires old and new text strings`);
|
|
8606
10016
|
}
|
|
8607
10017
|
return {
|
|
8608
10018
|
old_string: oldString,
|
|
8609
10019
|
new_string: newString,
|
|
8610
|
-
...replaceAll ||
|
|
10020
|
+
...replaceAll || record2.all === true || record2.replace_all === true ? { replace_all: true } : {}
|
|
8611
10021
|
};
|
|
8612
10022
|
});
|
|
8613
|
-
const resolvedPath =
|
|
10023
|
+
const resolvedPath = path14.resolve(cwd, filePath.startsWith("@") ? filePath.slice(1) : filePath);
|
|
8614
10024
|
const current = readFileSync2(resolvedPath, "utf8");
|
|
8615
10025
|
if (current.length > MAX_REPLACE_ALL_FILE_CHARS) {
|
|
8616
10026
|
throw new Error(`omp.edit refuses files over ${MAX_REPLACE_ALL_FILE_CHARS} characters`);
|
|
@@ -8722,7 +10132,7 @@ var keepLeadingLines = (text, count) => {
|
|
|
8722
10132
|
}
|
|
8723
10133
|
return text.slice(0, index - 1);
|
|
8724
10134
|
};
|
|
8725
|
-
var
|
|
10135
|
+
var countLines2 = (text) => {
|
|
8726
10136
|
if (text.length === 0) return 0;
|
|
8727
10137
|
let lines = 1;
|
|
8728
10138
|
for (let index = text.indexOf("\n"); index !== -1; index = text.indexOf("\n", index + 1)) lines++;
|
|
@@ -8764,7 +10174,7 @@ var restoreBashOutput = (artifactPath, maxChars, delivered) => {
|
|
|
8764
10174
|
if (!artifactPath || maxChars <= 0) return void 0;
|
|
8765
10175
|
let size;
|
|
8766
10176
|
try {
|
|
8767
|
-
size =
|
|
10177
|
+
size = statSync4(artifactPath).size;
|
|
8768
10178
|
} catch {
|
|
8769
10179
|
return void 0;
|
|
8770
10180
|
}
|
|
@@ -8791,11 +10201,11 @@ var withoutColumnLimit = (detailRecord, metaRecord) => {
|
|
|
8791
10201
|
return remainingDetails;
|
|
8792
10202
|
};
|
|
8793
10203
|
var grepTruncationSignal = (details) => {
|
|
8794
|
-
const
|
|
8795
|
-
if (!
|
|
8796
|
-
const perFile = finiteNumber2(
|
|
8797
|
-
const maxColumn = finiteNumber2(asRecord(asRecord(asRecord(
|
|
8798
|
-
const fileCount = finiteNumber2(
|
|
10204
|
+
const record2 = asRecord(details);
|
|
10205
|
+
if (!record2 || record2.truncated !== true) return void 0;
|
|
10206
|
+
const perFile = finiteNumber2(record2.perFileLimitReached);
|
|
10207
|
+
const maxColumn = finiteNumber2(asRecord(asRecord(asRecord(record2.meta)?.limits)?.columnTruncated)?.maxColumn);
|
|
10208
|
+
const fileCount = finiteNumber2(record2.fileCount);
|
|
8799
10209
|
const reasons = [];
|
|
8800
10210
|
const notes = [];
|
|
8801
10211
|
let continuation = null;
|
|
@@ -8822,7 +10232,7 @@ var grepTruncationSignal = (details) => {
|
|
|
8822
10232
|
tool: "grep",
|
|
8823
10233
|
partial: true,
|
|
8824
10234
|
reasons,
|
|
8825
|
-
...finiteNumber2(
|
|
10235
|
+
...finiteNumber2(record2.matchCount) === void 0 ? {} : { matchCount: record2.matchCount },
|
|
8826
10236
|
...fileCount === void 0 ? {} : { fileCount },
|
|
8827
10237
|
...perFile === void 0 ? {} : { perFileMatchLimit: perFile },
|
|
8828
10238
|
...maxColumn === void 0 ? {} : { maxColumn },
|
|
@@ -8859,9 +10269,9 @@ var lineBudgetSignal = (meta, target, progress) => {
|
|
|
8859
10269
|
};
|
|
8860
10270
|
};
|
|
8861
10271
|
var findTruncationSignal = (details) => {
|
|
8862
|
-
const
|
|
8863
|
-
if (!
|
|
8864
|
-
const reached = finiteNumber2(
|
|
10272
|
+
const record2 = asRecord(details);
|
|
10273
|
+
if (!record2 || record2.truncated !== true) return void 0;
|
|
10274
|
+
const reached = finiteNumber2(record2.resultLimitReached) ?? finiteNumber2(record2.fileCount);
|
|
8865
10275
|
return {
|
|
8866
10276
|
tool: "find",
|
|
8867
10277
|
partial: true,
|
|
@@ -9006,7 +10416,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9006
10416
|
edit: createNativeReplaceEditToolDefinition(cwd),
|
|
9007
10417
|
write: createPreviewWriteToolDefinition(cwd),
|
|
9008
10418
|
grep: createGrepDefinitionWithSkip(cwd),
|
|
9009
|
-
find:
|
|
10419
|
+
find: createFindDefinitionWithFilters(cwd),
|
|
9010
10420
|
ls: createLsToolDefinition(cwd)
|
|
9011
10421
|
};
|
|
9012
10422
|
this.#catalog = catalog;
|
|
@@ -9014,10 +10424,10 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9014
10424
|
}
|
|
9015
10425
|
async list(request, _context) {
|
|
9016
10426
|
const query = request.query?.toLowerCase();
|
|
9017
|
-
const
|
|
10427
|
+
const descriptors7 = await Promise.all(
|
|
9018
10428
|
OMP_CORE_TOOL_NAMES.map((name) => this.describe(name, _context))
|
|
9019
10429
|
);
|
|
9020
|
-
return
|
|
10430
|
+
return descriptors7.filter((descriptor) => descriptor !== void 0).filter(
|
|
9021
10431
|
(descriptor) => query ? `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query) : true
|
|
9022
10432
|
);
|
|
9023
10433
|
}
|
|
@@ -9041,13 +10451,13 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9041
10451
|
if (typeof prepared !== "object" || prepared === null || Array.isArray(prepared)) {
|
|
9042
10452
|
throw new Error(`OMP tool ${actionName} prepared non-object arguments`);
|
|
9043
10453
|
}
|
|
9044
|
-
const
|
|
10454
|
+
const record2 = prepared;
|
|
9045
10455
|
if (isOmpShellToolName(actionName)) {
|
|
9046
|
-
const shellArgs = Object.hasOwn(args, OMP_BASH_CWD_KEY) ? { ...
|
|
10456
|
+
const shellArgs = Object.hasOwn(args, OMP_BASH_CWD_KEY) ? { ...record2, [OMP_BASH_CWD_KEY]: args[OMP_BASH_CWD_KEY] } : record2;
|
|
9047
10457
|
return resolveShellCwdArgument(actionName, this.#cwd, shellArgs);
|
|
9048
10458
|
}
|
|
9049
|
-
if (actionName === "read") return normalizeReadArguments(
|
|
9050
|
-
return actionName === "edit" ? normalizeEditArguments(
|
|
10459
|
+
if (actionName === "read") return normalizeReadArguments(record2);
|
|
10460
|
+
return actionName === "edit" ? normalizeEditArguments(record2, args.all === true, this.#cwd) : record2;
|
|
9051
10461
|
}
|
|
9052
10462
|
#assertAllowed(name) {
|
|
9053
10463
|
if (this.#allowedTools && !this.#allowedTools.has(name)) {
|
|
@@ -9257,7 +10667,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9257
10667
|
}
|
|
9258
10668
|
const budget = resultCharBound(context) - READ_MARKER_RESERVE_CHARS;
|
|
9259
10669
|
let text = stripRepeatReadHint(textContent(result.content));
|
|
9260
|
-
let covered = meta.shownEnd ??
|
|
10670
|
+
let covered = meta.shownEnd ?? countLines2(text);
|
|
9261
10671
|
let nextOffset = meta.nextOffset;
|
|
9262
10672
|
let stopped;
|
|
9263
10673
|
while (nextOffset !== void 0 && covered < target.endLimit) {
|
|
@@ -9281,7 +10691,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9281
10691
|
const pageText = stripRepeatReadHint(textContent(page.content));
|
|
9282
10692
|
const start = pageMeta?.shownStart ?? nextOffset;
|
|
9283
10693
|
const body = dropLeadingLines(pageText, Math.max(0, covered - start + 1));
|
|
9284
|
-
const pageEnd = pageMeta?.shownEnd ?? start +
|
|
10694
|
+
const pageEnd = pageMeta?.shownEnd ?? start + countLines2(pageText) - 1;
|
|
9285
10695
|
if (body.length === 0 || pageEnd <= covered) {
|
|
9286
10696
|
nextOffset = void 0;
|
|
9287
10697
|
break;
|
|
@@ -9411,7 +10821,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9411
10821
|
import { spawn } from "node:child_process";
|
|
9412
10822
|
import { createHash as createHash3, randomBytes, randomUUID as randomUUID4 } from "node:crypto";
|
|
9413
10823
|
import fs8 from "node:fs";
|
|
9414
|
-
import
|
|
10824
|
+
import path16 from "node:path";
|
|
9415
10825
|
|
|
9416
10826
|
// src/schema/types.ts
|
|
9417
10827
|
var stateBinding = (head) => head ? { transitionId: head.transitionId, version: head.version, to: head.to } : null;
|
|
@@ -9420,7 +10830,7 @@ var stateBinding = (head) => head ? { transitionId: head.transitionId, version:
|
|
|
9420
10830
|
import { execFileSync } from "node:child_process";
|
|
9421
10831
|
import { createHash as createHash2 } from "node:crypto";
|
|
9422
10832
|
import fs7 from "node:fs";
|
|
9423
|
-
import
|
|
10833
|
+
import path15 from "node:path";
|
|
9424
10834
|
var SNAPSHOT_MAX_FILES = 2e4;
|
|
9425
10835
|
var SNAPSHOT_MAX_BYTES = 512 * 1024 * 1024;
|
|
9426
10836
|
var FALLBACK_SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
@@ -9438,10 +10848,10 @@ var git = (cwd, args) => execFileSync("git", ["-C", cwd, ...args], {
|
|
|
9438
10848
|
stdio: ["ignore", "pipe", "ignore"]
|
|
9439
10849
|
});
|
|
9440
10850
|
var nulPaths = (buffer) => buffer.toString("utf8").split("\0").filter((item) => item.length > 0);
|
|
9441
|
-
var normalizeRelative = (value) => value.split(
|
|
10851
|
+
var normalizeRelative = (value) => value.split(path15.sep).join("/");
|
|
9442
10852
|
var isInside = (root, candidate) => {
|
|
9443
|
-
const relative =
|
|
9444
|
-
return relative === "" || !
|
|
10853
|
+
const relative = path15.relative(root, candidate);
|
|
10854
|
+
return relative === "" || !path15.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path15.sep}`);
|
|
9445
10855
|
};
|
|
9446
10856
|
var excluded = (absolute, exclusions) => exclusions.some((root) => isInside(root, absolute));
|
|
9447
10857
|
var entryDigest = (absolute) => {
|
|
@@ -9467,12 +10877,12 @@ var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
|
9467
10877
|
let bytes = 0;
|
|
9468
10878
|
const unique = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
9469
10879
|
for (const relativeInput of unique) {
|
|
9470
|
-
const absolute =
|
|
10880
|
+
const absolute = path15.resolve(cwd, relativeInput);
|
|
9471
10881
|
if (!isInside(cwd, absolute) || excluded(absolute, exclusions)) continue;
|
|
9472
10882
|
if (Object.keys(entries).length >= SNAPSHOT_MAX_FILES) {
|
|
9473
10883
|
throw new Error(`Schema workspace snapshot exceeds ${SNAPSHOT_MAX_FILES} files`);
|
|
9474
10884
|
}
|
|
9475
|
-
const relative = normalizeRelative(
|
|
10885
|
+
const relative = normalizeRelative(path15.relative(cwd, absolute));
|
|
9476
10886
|
const entry = entryDigest(absolute);
|
|
9477
10887
|
bytes += entry.bytes;
|
|
9478
10888
|
if (bytes > SNAPSHOT_MAX_BYTES) {
|
|
@@ -9501,9 +10911,9 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
9501
10911
|
const entries = fs7.readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
9502
10912
|
for (const entry of entries) {
|
|
9503
10913
|
if (FALLBACK_SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
9504
|
-
const absolute =
|
|
10914
|
+
const absolute = path15.join(directory, entry.name);
|
|
9505
10915
|
if (excluded(absolute, exclusions)) continue;
|
|
9506
|
-
const relative = normalizeRelative(
|
|
10916
|
+
const relative = normalizeRelative(path15.relative(cwd, absolute));
|
|
9507
10917
|
if (entry.isDirectory()) visit(absolute);
|
|
9508
10918
|
else paths.push(relative);
|
|
9509
10919
|
if (paths.length > SNAPSHOT_MAX_FILES) {
|
|
@@ -9517,7 +10927,7 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
9517
10927
|
var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
9518
10928
|
const cwd = fs7.realpathSync(cwdInput);
|
|
9519
10929
|
const exclusions = excludedRoots.map((root) => {
|
|
9520
|
-
const absolute =
|
|
10930
|
+
const absolute = path15.resolve(root);
|
|
9521
10931
|
try {
|
|
9522
10932
|
return fs7.realpathSync(absolute);
|
|
9523
10933
|
} catch {
|
|
@@ -9555,18 +10965,18 @@ var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
|
9555
10965
|
);
|
|
9556
10966
|
};
|
|
9557
10967
|
var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
9558
|
-
if (!requestedPath.trim() ||
|
|
10968
|
+
if (!requestedPath.trim() || path15.isAbsolute(requestedPath)) {
|
|
9559
10969
|
throw new Error(`Schema paths must be non-empty project-relative paths: ${requestedPath}`);
|
|
9560
10970
|
}
|
|
9561
10971
|
const cwd = fs7.realpathSync(cwdInput);
|
|
9562
|
-
const absolute =
|
|
10972
|
+
const absolute = path15.resolve(cwd, requestedPath);
|
|
9563
10973
|
if (!isInside(cwd, absolute) || absolute === cwd) {
|
|
9564
10974
|
throw new Error(`Schema path escapes the project workspace: ${requestedPath}`);
|
|
9565
10975
|
}
|
|
9566
|
-
const relativeParts =
|
|
10976
|
+
const relativeParts = path15.relative(cwd, absolute).split(path15.sep);
|
|
9567
10977
|
let cursor = cwd;
|
|
9568
10978
|
for (let index = 0; index < relativeParts.length; index++) {
|
|
9569
|
-
cursor =
|
|
10979
|
+
cursor = path15.join(cursor, relativeParts[index]);
|
|
9570
10980
|
let stat2;
|
|
9571
10981
|
try {
|
|
9572
10982
|
stat2 = fs7.lstatSync(cursor);
|
|
@@ -9575,9 +10985,9 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9575
10985
|
if (index !== relativeParts.length - 1 || !options.allowAbsent) {
|
|
9576
10986
|
throw new Error(`Schema path does not exist: ${requestedPath}`);
|
|
9577
10987
|
}
|
|
9578
|
-
const parentReal = fs7.realpathSync(
|
|
10988
|
+
const parentReal = fs7.realpathSync(path15.dirname(cursor));
|
|
9579
10989
|
if (!isInside(cwd, parentReal)) throw new Error(`Schema path parent escapes the workspace: ${requestedPath}`);
|
|
9580
|
-
return { absolute, relative: normalizeRelative(
|
|
10990
|
+
return { absolute, relative: normalizeRelative(path15.relative(cwd, absolute)), exists: false };
|
|
9581
10991
|
}
|
|
9582
10992
|
throw error;
|
|
9583
10993
|
}
|
|
@@ -9589,7 +10999,7 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9589
10999
|
throw new Error(`Schema transaction paths must name regular files: ${requestedPath}`);
|
|
9590
11000
|
}
|
|
9591
11001
|
}
|
|
9592
|
-
return { absolute, relative: normalizeRelative(
|
|
11002
|
+
return { absolute, relative: normalizeRelative(path15.relative(cwd, absolute)), exists: true };
|
|
9593
11003
|
};
|
|
9594
11004
|
var sha256File = (absolute) => `sha256:${digest(fs7.readFileSync(absolute))}`;
|
|
9595
11005
|
|
|
@@ -9640,8 +11050,8 @@ var SchemaController = class {
|
|
|
9640
11050
|
this.identity = identity;
|
|
9641
11051
|
this.state = state;
|
|
9642
11052
|
this.cwd = fs8.realpathSync(cwd);
|
|
9643
|
-
this.#journalRoot =
|
|
9644
|
-
this.#lockPath =
|
|
11053
|
+
this.#journalRoot = path16.join(mesh.root, "schema-transactions");
|
|
11054
|
+
this.#lockPath = path16.join(this.#journalRoot, ".commit.lock");
|
|
9645
11055
|
this.#recoverJournals();
|
|
9646
11056
|
}
|
|
9647
11057
|
#activeHypotheses = /* @__PURE__ */ new Map();
|
|
@@ -9666,12 +11076,12 @@ var SchemaController = class {
|
|
|
9666
11076
|
}
|
|
9667
11077
|
status(parentToolCallId) {
|
|
9668
11078
|
const workspace = this.#workspaceEntry();
|
|
9669
|
-
const hypotheses = this.mesh.list(HYPOTHESIS_PREFIX, this.mesh.maxReadEvents).map((entry) => entry.value).filter((
|
|
9670
|
-
id:
|
|
9671
|
-
label:
|
|
9672
|
-
status:
|
|
9673
|
-
generation:
|
|
9674
|
-
updatedAt:
|
|
11079
|
+
const hypotheses = this.mesh.list(HYPOTHESIS_PREFIX, this.mesh.maxReadEvents).map((entry) => entry.value).filter((record2) => !parentToolCallId || record2.parentToolCallId === parentToolCallId).map((record2) => ({
|
|
11080
|
+
id: record2.id,
|
|
11081
|
+
label: record2.label,
|
|
11082
|
+
status: record2.status,
|
|
11083
|
+
generation: record2.generation,
|
|
11084
|
+
updatedAt: record2.updatedAt
|
|
9675
11085
|
}));
|
|
9676
11086
|
return {
|
|
9677
11087
|
mode: this.config.mode,
|
|
@@ -9696,7 +11106,7 @@ var SchemaController = class {
|
|
|
9696
11106
|
const snapshot = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
9697
11107
|
const generation = this.#generation();
|
|
9698
11108
|
const now = Date.now();
|
|
9699
|
-
const
|
|
11109
|
+
const record2 = {
|
|
9700
11110
|
id: randomUUID4(),
|
|
9701
11111
|
label: input.label,
|
|
9702
11112
|
summary: input.summary,
|
|
@@ -9710,66 +11120,66 @@ var SchemaController = class {
|
|
|
9710
11120
|
createdAt: now,
|
|
9711
11121
|
updatedAt: now
|
|
9712
11122
|
};
|
|
9713
|
-
await this.#publish("hypothesized",
|
|
11123
|
+
await this.#publish("hypothesized", record2);
|
|
9714
11124
|
await this.mesh.put({
|
|
9715
|
-
key: `${HYPOTHESIS_PREFIX}${
|
|
9716
|
-
value:
|
|
11125
|
+
key: `${HYPOTHESIS_PREFIX}${record2.id}`,
|
|
11126
|
+
value: record2,
|
|
9717
11127
|
ifVersion: 0,
|
|
9718
11128
|
identity: this.identity
|
|
9719
11129
|
});
|
|
9720
|
-
this.#activeHypotheses.set(
|
|
9721
|
-
context.update(`Schema hypothesis recorded: ${
|
|
11130
|
+
this.#activeHypotheses.set(record2.id, context.parentToolCallId);
|
|
11131
|
+
context.update(`Schema hypothesis recorded: ${record2.label}`);
|
|
9722
11132
|
return {
|
|
9723
|
-
hypothesisId:
|
|
9724
|
-
status:
|
|
9725
|
-
state:
|
|
9726
|
-
fingerprint:
|
|
11133
|
+
hypothesisId: record2.id,
|
|
11134
|
+
status: record2.status,
|
|
11135
|
+
state: record2.state,
|
|
11136
|
+
fingerprint: record2.fingerprint,
|
|
9727
11137
|
generation
|
|
9728
11138
|
};
|
|
9729
11139
|
}
|
|
9730
11140
|
async verify(hypothesisId, context) {
|
|
9731
11141
|
const entry = this.#requireHypothesis(hypothesisId);
|
|
9732
|
-
const
|
|
9733
|
-
this.#assertInvocation(
|
|
9734
|
-
if (
|
|
9735
|
-
if (
|
|
11142
|
+
const record2 = entry.value;
|
|
11143
|
+
this.#assertInvocation(record2.parentToolCallId, context.parentToolCallId);
|
|
11144
|
+
if (record2.status !== "active") throw new Error(`Schema hypothesis is not active: ${record2.status}`);
|
|
11145
|
+
if (record2.evidence.length === 0) return this.#failedVerification(record2, [], "missing evidence");
|
|
9736
11146
|
let before;
|
|
9737
11147
|
try {
|
|
9738
11148
|
before = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
9739
11149
|
} catch (error) {
|
|
9740
|
-
return this.#failedVerification(
|
|
11150
|
+
return this.#failedVerification(record2, [], `workspace snapshot failed: ${errorMessage4(error)}`);
|
|
9741
11151
|
}
|
|
9742
11152
|
const currentState = stateBinding(this.state?.getHead() ?? null);
|
|
9743
|
-
if (!sameBinding(
|
|
9744
|
-
return this.#failedVerification(
|
|
11153
|
+
if (!sameBinding(record2.state, currentState)) {
|
|
11154
|
+
return this.#failedVerification(record2, [], "state head changed since hypothesis");
|
|
9745
11155
|
}
|
|
9746
|
-
if (
|
|
9747
|
-
return this.#failedVerification(
|
|
11156
|
+
if (record2.generation !== this.#generation()) {
|
|
11157
|
+
return this.#failedVerification(record2, [], "workspace generation changed since hypothesis");
|
|
9748
11158
|
}
|
|
9749
|
-
if (
|
|
9750
|
-
return this.#failedVerification(
|
|
11159
|
+
if (record2.fingerprint !== before.fingerprint) {
|
|
11160
|
+
return this.#failedVerification(record2, [], "workspace fingerprint changed since hypothesis");
|
|
9751
11161
|
}
|
|
9752
|
-
const results = await this.#verifyEvidence(
|
|
11162
|
+
const results = await this.#verifyEvidence(record2.evidence, context);
|
|
9753
11163
|
let after;
|
|
9754
11164
|
try {
|
|
9755
11165
|
after = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
9756
11166
|
} catch (error) {
|
|
9757
|
-
return this.#failedVerification(
|
|
11167
|
+
return this.#failedVerification(record2, results, `post-evidence snapshot failed: ${errorMessage4(error)}`);
|
|
9758
11168
|
}
|
|
9759
11169
|
const allConfirmed = results.length > 0 && results.every((result) => result.status === "confirmed");
|
|
9760
11170
|
if (!allConfirmed || before.fingerprint !== after.fingerprint) {
|
|
9761
11171
|
const reason = before.fingerprint !== after.fingerprint ? "workspace fingerprint changed while evidence ran" : "one or more evidence items were not confirmed";
|
|
9762
|
-
return this.#failedVerification(
|
|
11172
|
+
return this.#failedVerification(record2, results, reason);
|
|
9763
11173
|
}
|
|
9764
11174
|
const certificate = randomBytes(32).toString("hex");
|
|
9765
11175
|
const issuedAt = Date.now();
|
|
9766
11176
|
const certificateRecord = {
|
|
9767
11177
|
tokenHash: hashToken(certificate),
|
|
9768
|
-
hypothesisId:
|
|
11178
|
+
hypothesisId: record2.id,
|
|
9769
11179
|
parentToolCallId: context.parentToolCallId,
|
|
9770
|
-
state:
|
|
9771
|
-
fingerprint:
|
|
9772
|
-
generation:
|
|
11180
|
+
state: record2.state,
|
|
11181
|
+
fingerprint: record2.fingerprint,
|
|
11182
|
+
generation: record2.generation,
|
|
9773
11183
|
issuedAt,
|
|
9774
11184
|
expiresAt: issuedAt + this.config.certificateTtlMs,
|
|
9775
11185
|
status: "active"
|
|
@@ -9784,7 +11194,7 @@ var SchemaController = class {
|
|
|
9784
11194
|
try {
|
|
9785
11195
|
await this.mesh.put({
|
|
9786
11196
|
key: entry.key,
|
|
9787
|
-
value: { ...
|
|
11197
|
+
value: { ...record2, status: "verified", updatedAt: Date.now() },
|
|
9788
11198
|
ifVersion: entry.version,
|
|
9789
11199
|
identity: this.identity
|
|
9790
11200
|
});
|
|
@@ -9803,16 +11213,16 @@ var SchemaController = class {
|
|
|
9803
11213
|
this.#activeCertificates.set(certificateRecord.tokenHash, context.parentToolCallId);
|
|
9804
11214
|
try {
|
|
9805
11215
|
await this.#publish("verified", {
|
|
9806
|
-
hypothesisId:
|
|
11216
|
+
hypothesisId: record2.id,
|
|
9807
11217
|
tokenHash: certificateRecord.tokenHash,
|
|
9808
11218
|
results: results.map((result) => ({
|
|
9809
11219
|
kind: result.evidence.kind,
|
|
9810
11220
|
status: result.status,
|
|
9811
11221
|
detail: result.detail
|
|
9812
11222
|
})),
|
|
9813
|
-
state:
|
|
9814
|
-
fingerprint:
|
|
9815
|
-
generation:
|
|
11223
|
+
state: record2.state,
|
|
11224
|
+
fingerprint: record2.fingerprint,
|
|
11225
|
+
generation: record2.generation,
|
|
9816
11226
|
issuedAt,
|
|
9817
11227
|
expiresAt: certificateRecord.expiresAt
|
|
9818
11228
|
});
|
|
@@ -9821,7 +11231,7 @@ var SchemaController = class {
|
|
|
9821
11231
|
context.update(`Schema evidence confirmed; certificate expires in ${this.config.certificateTtlMs}ms`);
|
|
9822
11232
|
return {
|
|
9823
11233
|
verified: true,
|
|
9824
|
-
hypothesisId:
|
|
11234
|
+
hypothesisId: record2.id,
|
|
9825
11235
|
certificate,
|
|
9826
11236
|
issuedAt,
|
|
9827
11237
|
expiresAt: certificateRecord.expiresAt,
|
|
@@ -9840,7 +11250,7 @@ var SchemaController = class {
|
|
|
9840
11250
|
this.#assertPayloadBound(input);
|
|
9841
11251
|
const release = this.#acquireCommitLock();
|
|
9842
11252
|
const transactionId = randomUUID4();
|
|
9843
|
-
const journalPath =
|
|
11253
|
+
const journalPath = path16.join(this.#journalRoot, `${transactionId}.json`);
|
|
9844
11254
|
let journal;
|
|
9845
11255
|
let consumed = false;
|
|
9846
11256
|
let committed = false;
|
|
@@ -10050,12 +11460,12 @@ var SchemaController = class {
|
|
|
10050
11460
|
if (invocation !== parentToolCallId) continue;
|
|
10051
11461
|
const entry = this.mesh.get(`${CERTIFICATE_PREFIX}${tokenHash}`);
|
|
10052
11462
|
if (entry) {
|
|
10053
|
-
const
|
|
10054
|
-
if (
|
|
11463
|
+
const record2 = entry.value;
|
|
11464
|
+
if (record2.status === "active") {
|
|
10055
11465
|
try {
|
|
10056
11466
|
await this.mesh.put({
|
|
10057
11467
|
key: entry.key,
|
|
10058
|
-
value: { ...
|
|
11468
|
+
value: { ...record2, status: "abandoned" },
|
|
10059
11469
|
ifVersion: entry.version,
|
|
10060
11470
|
identity: this.identity
|
|
10061
11471
|
});
|
|
@@ -10069,12 +11479,12 @@ var SchemaController = class {
|
|
|
10069
11479
|
if (invocation !== parentToolCallId) continue;
|
|
10070
11480
|
const entry = this.mesh.get(`${HYPOTHESIS_PREFIX}${hypothesisId}`);
|
|
10071
11481
|
if (entry) {
|
|
10072
|
-
const
|
|
10073
|
-
if (
|
|
11482
|
+
const record2 = entry.value;
|
|
11483
|
+
if (record2.status === "active" || record2.status === "verified") {
|
|
10074
11484
|
try {
|
|
10075
11485
|
await this.mesh.put({
|
|
10076
11486
|
key: entry.key,
|
|
10077
|
-
value: { ...
|
|
11487
|
+
value: { ...record2, status: "abandoned", updatedAt: Date.now() },
|
|
10078
11488
|
ifVersion: entry.version,
|
|
10079
11489
|
identity: this.identity
|
|
10080
11490
|
});
|
|
@@ -10085,16 +11495,16 @@ var SchemaController = class {
|
|
|
10085
11495
|
this.#activeHypotheses.delete(hypothesisId);
|
|
10086
11496
|
}
|
|
10087
11497
|
}
|
|
10088
|
-
async #failedVerification(
|
|
11498
|
+
async #failedVerification(record2, results, reason) {
|
|
10089
11499
|
try {
|
|
10090
11500
|
await this.#publish("verification_failed", {
|
|
10091
|
-
hypothesisId:
|
|
11501
|
+
hypothesisId: record2.id,
|
|
10092
11502
|
reason,
|
|
10093
11503
|
results: results.map((result) => ({ kind: result.evidence.kind, status: result.status, detail: result.detail }))
|
|
10094
11504
|
});
|
|
10095
11505
|
} catch {
|
|
10096
11506
|
}
|
|
10097
|
-
return { verified: false, hypothesisId:
|
|
11507
|
+
return { verified: false, hypothesisId: record2.id, reason, results };
|
|
10098
11508
|
}
|
|
10099
11509
|
async #verifyEvidence(evidence, context) {
|
|
10100
11510
|
if (evidence.length === 0) return [];
|
|
@@ -10321,7 +11731,7 @@ ${Date.now()}
|
|
|
10321
11731
|
}
|
|
10322
11732
|
for (const name of fs8.readdirSync(this.#journalRoot)) {
|
|
10323
11733
|
if (!name.endsWith(".json")) continue;
|
|
10324
|
-
const filePath =
|
|
11734
|
+
const filePath = path16.join(this.#journalRoot, name);
|
|
10325
11735
|
try {
|
|
10326
11736
|
const journal = JSON.parse(fs8.readFileSync(filePath, "utf8"));
|
|
10327
11737
|
if (journal.format !== 1 || journal.status !== "applying" || !Array.isArray(journal.before)) continue;
|
|
@@ -10441,7 +11851,7 @@ var operationSchema = {
|
|
|
10441
11851
|
}
|
|
10442
11852
|
]
|
|
10443
11853
|
};
|
|
10444
|
-
var
|
|
11854
|
+
var descriptors5 = [
|
|
10445
11855
|
{
|
|
10446
11856
|
name: "status",
|
|
10447
11857
|
description: "Read the fixed session Schema mode, transaction bounds, generation, and invocation hypotheses",
|
|
@@ -10511,7 +11921,7 @@ var descriptors4 = [
|
|
|
10511
11921
|
namespace: "schema"
|
|
10512
11922
|
}
|
|
10513
11923
|
];
|
|
10514
|
-
var normalizeSchemaArgs = actionArgNormalizer(() =>
|
|
11924
|
+
var normalizeSchemaArgs = actionArgNormalizer(() => descriptors5);
|
|
10515
11925
|
var SchemaProvider = class {
|
|
10516
11926
|
constructor(controller) {
|
|
10517
11927
|
this.controller = controller;
|
|
@@ -10520,12 +11930,12 @@ var SchemaProvider = class {
|
|
|
10520
11930
|
description = "Host-owned, opt-in Schema verification and bounded local-file transaction control plane";
|
|
10521
11931
|
async list(request, _context) {
|
|
10522
11932
|
const query = request.query?.toLowerCase();
|
|
10523
|
-
return query ?
|
|
11933
|
+
return query ? descriptors5.filter(
|
|
10524
11934
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
10525
|
-
) :
|
|
11935
|
+
) : descriptors5;
|
|
10526
11936
|
}
|
|
10527
11937
|
async describe(actionName, _context) {
|
|
10528
|
-
return
|
|
11938
|
+
return descriptors5.find((descriptor) => descriptor.name === actionName);
|
|
10529
11939
|
}
|
|
10530
11940
|
prepareArguments(actionName, args) {
|
|
10531
11941
|
return normalizeSchemaArgs(actionName, args);
|
|
@@ -10575,11 +11985,11 @@ var SchemaProvider = class {
|
|
|
10575
11985
|
|
|
10576
11986
|
// src/state/store.ts
|
|
10577
11987
|
import { createHash as createHash5 } from "node:crypto";
|
|
10578
|
-
import
|
|
11988
|
+
import path18 from "node:path";
|
|
10579
11989
|
|
|
10580
11990
|
// src/state/complexity.ts
|
|
10581
11991
|
import fs9 from "node:fs";
|
|
10582
|
-
import
|
|
11992
|
+
import path17 from "node:path";
|
|
10583
11993
|
var isWordStart = (character) => character !== void 0 && (character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character === "_" || character === "$");
|
|
10584
11994
|
var isWordPart = (character) => isWordStart(character) || character !== void 0 && character >= "0" && character <= "9";
|
|
10585
11995
|
var regularExpressionPrefixWords = /* @__PURE__ */ new Set([
|
|
@@ -10811,7 +12221,7 @@ var languageComplexities = [
|
|
|
10811
12221
|
typeScriptJavaScriptComplexity
|
|
10812
12222
|
];
|
|
10813
12223
|
var complexityForFile = (file, languages = languageComplexities) => {
|
|
10814
|
-
const extension =
|
|
12224
|
+
const extension = path17.extname(file).toLowerCase();
|
|
10815
12225
|
return languages.find((language) => language.extensions.includes(extension));
|
|
10816
12226
|
};
|
|
10817
12227
|
var countFileComplexity = (file) => {
|
|
@@ -11630,10 +13040,10 @@ var StateStore = class {
|
|
|
11630
13040
|
const currentHead = this.getHead();
|
|
11631
13041
|
const records = [];
|
|
11632
13042
|
for (const event of events) {
|
|
11633
|
-
const
|
|
11634
|
-
if (
|
|
13043
|
+
const record2 = toRecord(event, committedIds);
|
|
13044
|
+
if (record2) records.push(record2);
|
|
11635
13045
|
}
|
|
11636
|
-
if (currentHead && !records.some((
|
|
13046
|
+
if (currentHead && !records.some((record2) => record2.transitionId === currentHead.transitionId)) {
|
|
11637
13047
|
const currentRecord = toHeadRecord(currentHead);
|
|
11638
13048
|
if (currentRecord) records.push(currentRecord);
|
|
11639
13049
|
}
|
|
@@ -11646,7 +13056,7 @@ var StateStore = class {
|
|
|
11646
13056
|
}
|
|
11647
13057
|
}
|
|
11648
13058
|
const visibleRecords = input.includeArchived || lastRepresentation < 0 ? records : records.slice(lastRepresentation);
|
|
11649
|
-
const visibleIds = new Set(visibleRecords.map((
|
|
13059
|
+
const visibleIds = new Set(visibleRecords.map((record2) => record2.transitionId));
|
|
11650
13060
|
const latestOutcomes = latestTransitionOutcomes(events);
|
|
11651
13061
|
const eventCertifications = events.map((event) => toCertificate(event, currentHead, latestOutcomes)).filter((certificate) => certificate !== void 0).filter(
|
|
11652
13062
|
(certificate) => certificate.targets.every((target) => visibleIds.has(target.transitionId))
|
|
@@ -11662,32 +13072,32 @@ var StateStore = class {
|
|
|
11662
13072
|
certifications.map((certificate) => [certificate.sequence, certificate])
|
|
11663
13073
|
);
|
|
11664
13074
|
const latestCertificate = /* @__PURE__ */ new Map();
|
|
11665
|
-
for (const
|
|
11666
|
-
const outcome = latestOutcomes.get(
|
|
13075
|
+
for (const record2 of visibleRecords) {
|
|
13076
|
+
const outcome = latestOutcomes.get(record2.transitionId);
|
|
11667
13077
|
if (outcome?.phase !== "certified") continue;
|
|
11668
13078
|
const certificate = certificatesBySequence.get(outcome.event.sequence);
|
|
11669
|
-
if (certificate) latestCertificate.set(
|
|
13079
|
+
if (certificate) latestCertificate.set(record2.transitionId, certificate);
|
|
11670
13080
|
}
|
|
11671
13081
|
if (durableCertificate) {
|
|
11672
13082
|
latestCertificate.set(currentHead.transitionId, durableCertificate);
|
|
11673
13083
|
}
|
|
11674
13084
|
const archiveBoundaryId = input.includeArchived !== true && lastRepresentation > 0 ? records[lastRepresentation]?.transitionId : void 0;
|
|
11675
13085
|
const filtered = (input.label ? visibleRecords.filter(
|
|
11676
|
-
(
|
|
11677
|
-
) : visibleRecords).map((
|
|
11678
|
-
const certificate = latestCertificate.get(
|
|
11679
|
-
return certificate ? { ...
|
|
13086
|
+
(record2) => record2.label === input.label || record2.to === input.label || record2.from === input.label && record2.transitionId !== archiveBoundaryId
|
|
13087
|
+
) : visibleRecords).map((record2) => {
|
|
13088
|
+
const certificate = latestCertificate.get(record2.transitionId);
|
|
13089
|
+
return certificate ? { ...record2, certificationStatus: "certified", certificate } : record2;
|
|
11680
13090
|
});
|
|
11681
13091
|
const limited = input.limit !== void 0 && input.limit > 0 ? filtered.slice(0, input.limit) : filtered;
|
|
11682
13092
|
const labelSet = /* @__PURE__ */ new Set();
|
|
11683
13093
|
const limitedIds = /* @__PURE__ */ new Set();
|
|
11684
|
-
for (const
|
|
11685
|
-
limitedIds.add(
|
|
11686
|
-
if (
|
|
11687
|
-
labelSet.add(
|
|
13094
|
+
for (const record2 of limited) {
|
|
13095
|
+
limitedIds.add(record2.transitionId);
|
|
13096
|
+
if (record2.from && record2.transitionId !== archiveBoundaryId) {
|
|
13097
|
+
labelSet.add(record2.from);
|
|
11688
13098
|
}
|
|
11689
|
-
labelSet.add(
|
|
11690
|
-
labelSet.add(
|
|
13099
|
+
labelSet.add(record2.to);
|
|
13100
|
+
labelSet.add(record2.label);
|
|
11691
13101
|
}
|
|
11692
13102
|
return {
|
|
11693
13103
|
transitions: limited,
|
|
@@ -11702,7 +13112,7 @@ var StateStore = class {
|
|
|
11702
13112
|
const files = [];
|
|
11703
13113
|
let netDelta = 0;
|
|
11704
13114
|
for (const file of this.normalizeComplexityFiles(requestedFiles, input.cwd)) {
|
|
11705
|
-
const measured = countFileComplexity(
|
|
13115
|
+
const measured = countFileComplexity(path18.resolve(input.cwd, file));
|
|
11706
13116
|
if (!measured) {
|
|
11707
13117
|
files.push({ file, supported: false });
|
|
11708
13118
|
continue;
|
|
@@ -11729,7 +13139,7 @@ var StateStore = class {
|
|
|
11729
13139
|
const updates = [];
|
|
11730
13140
|
let netDelta = 0;
|
|
11731
13141
|
for (const file of this.normalizeComplexityFiles(files, cwd)) {
|
|
11732
|
-
const measured = countFileComplexity(
|
|
13142
|
+
const measured = countFileComplexity(path18.resolve(cwd, file));
|
|
11733
13143
|
if (!measured) {
|
|
11734
13144
|
deltas.push({ file, supported: false });
|
|
11735
13145
|
continue;
|
|
@@ -11779,11 +13189,11 @@ var StateStore = class {
|
|
|
11779
13189
|
const normalized = /* @__PURE__ */ new Set();
|
|
11780
13190
|
for (const file of files) {
|
|
11781
13191
|
if (!file.trim()) continue;
|
|
11782
|
-
const relative =
|
|
11783
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
13192
|
+
const relative = path18.relative(cwd, path18.resolve(cwd, file));
|
|
13193
|
+
if (relative === ".." || relative.startsWith(`..${path18.sep}`) || path18.isAbsolute(relative)) {
|
|
11784
13194
|
throw new Error(`State complexity file must be inside the project cwd: ${file}`);
|
|
11785
13195
|
}
|
|
11786
|
-
normalized.add(relative.split(
|
|
13196
|
+
normalized.add(relative.split(path18.sep).join("/"));
|
|
11787
13197
|
}
|
|
11788
13198
|
return [...normalized];
|
|
11789
13199
|
}
|
|
@@ -11917,7 +13327,7 @@ var StateStore = class {
|
|
|
11917
13327
|
includeArchived: input.includeArchived === true
|
|
11918
13328
|
});
|
|
11919
13329
|
const match = transitions.find(
|
|
11920
|
-
(
|
|
13330
|
+
(record2) => record2.transitionId === verificationHead.transitionId
|
|
11921
13331
|
);
|
|
11922
13332
|
targets = match ? [match] : [];
|
|
11923
13333
|
} else {
|
|
@@ -12225,7 +13635,7 @@ var checkGoalSchema = {
|
|
|
12225
13635
|
additionalProperties: false
|
|
12226
13636
|
};
|
|
12227
13637
|
var emptySchema3 = { type: "object", properties: {}, additionalProperties: false };
|
|
12228
|
-
var
|
|
13638
|
+
var descriptors6 = [
|
|
12229
13639
|
{
|
|
12230
13640
|
name: "transition",
|
|
12231
13641
|
description: "Append a labeled, validated state transition and compare-and-swap advance the head",
|
|
@@ -12276,7 +13686,7 @@ var descriptors5 = [
|
|
|
12276
13686
|
namespace: "state"
|
|
12277
13687
|
}
|
|
12278
13688
|
];
|
|
12279
|
-
var normalizeStateArgs = actionArgNormalizer(() =>
|
|
13689
|
+
var normalizeStateArgs = actionArgNormalizer(() => descriptors6);
|
|
12280
13690
|
var StateProvider = class {
|
|
12281
13691
|
name = "state";
|
|
12282
13692
|
description = "Schema-style labeled transition layer: an append-only timeline of validated transitions with a compare-and-swap head and evidence-based certification over mesh storage";
|
|
@@ -12291,12 +13701,12 @@ var StateProvider = class {
|
|
|
12291
13701
|
}
|
|
12292
13702
|
async list(request, _context) {
|
|
12293
13703
|
const query = request.query?.toLowerCase();
|
|
12294
|
-
return query ?
|
|
13704
|
+
return query ? descriptors6.filter(
|
|
12295
13705
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
12296
|
-
) :
|
|
13706
|
+
) : descriptors6;
|
|
12297
13707
|
}
|
|
12298
13708
|
async describe(actionName, _context) {
|
|
12299
|
-
return
|
|
13709
|
+
return descriptors6.find((descriptor) => descriptor.name === actionName);
|
|
12300
13710
|
}
|
|
12301
13711
|
prepareArguments(actionName, args) {
|
|
12302
13712
|
return normalizeStateArgs(actionName, args);
|
|
@@ -12777,7 +14187,7 @@ var FabricRuntimeState = class {
|
|
|
12777
14187
|
this.#mainAgent = mainAgent;
|
|
12778
14188
|
const projectRoot = process.env.OMP_FABRIC_PROJECT_ROOT ?? context.cwd;
|
|
12779
14189
|
const configuredMeshRoot = this.#config.mesh.root;
|
|
12780
|
-
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ?
|
|
14190
|
+
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ? path19.resolve(projectRoot, configuredMeshRoot) : path19.join(projectRoot, ".omp", "fabric", "mesh"));
|
|
12781
14191
|
this.#mesh = new MeshStore(
|
|
12782
14192
|
meshRoot,
|
|
12783
14193
|
this.#config.mesh.maxEventBytes,
|
|
@@ -12842,6 +14252,19 @@ var FabricRuntimeState = class {
|
|
|
12842
14252
|
description: "Host context compaction controller",
|
|
12843
14253
|
create: () => new CompactProvider(this.#compact)
|
|
12844
14254
|
}));
|
|
14255
|
+
if (this.#config.codemap.enabled) {
|
|
14256
|
+
const codemapConfig = this.#config.codemap;
|
|
14257
|
+
await installBuiltin(createProviderComponent({
|
|
14258
|
+
provider: "codemap",
|
|
14259
|
+
description: "Structural repo map and git co-change ranking",
|
|
14260
|
+
create: () => new CodemapProvider(codemapConfig)
|
|
14261
|
+
}));
|
|
14262
|
+
} else {
|
|
14263
|
+
this.#registry.markUnavailable(
|
|
14264
|
+
"codemap",
|
|
14265
|
+
'disabled by configuration (codemap.enabled=false); set "codemap": { "enabled": true } in .omp/fabric.json or the agent fabric.json to enable codemap.* actions'
|
|
14266
|
+
);
|
|
14267
|
+
}
|
|
12845
14268
|
const agentConfig = enforceSchema ? { ...this.#config.agents, enabled: false } : this.#config.agents;
|
|
12846
14269
|
const modelsConfig = this.#config.models;
|
|
12847
14270
|
const visibleOmpModels = () => {
|
|
@@ -12938,8 +14361,8 @@ var FabricRuntimeState = class {
|
|
|
12938
14361
|
};
|
|
12939
14362
|
const lineageAlive = (rootId) => this.#participants?.get(rootId) !== void 0;
|
|
12940
14363
|
const actorRoots = {
|
|
12941
|
-
project:
|
|
12942
|
-
session:
|
|
14364
|
+
project: path19.join(meshRoot, "actors"),
|
|
14365
|
+
session: path19.join(meshRoot, "actors", fabricSessionId)
|
|
12943
14366
|
};
|
|
12944
14367
|
const acquireActorCapabilityView = (requirements, signal) => this.#registry.acquireCapabilityView(requirements, {
|
|
12945
14368
|
cwd: context.cwd,
|
|
@@ -13139,6 +14562,7 @@ ${escapeXmlText(text)}
|
|
|
13139
14562
|
...this.#config.mesh.enabled ? ["mesh", "state"] : [],
|
|
13140
14563
|
"schema",
|
|
13141
14564
|
"compact",
|
|
14565
|
+
...this.#config.codemap.enabled ? ["codemap"] : [],
|
|
13142
14566
|
"agents",
|
|
13143
14567
|
...this.#config.memory.enabled ? ["memory"] : []
|
|
13144
14568
|
]);
|
|
@@ -13279,7 +14703,11 @@ ${escapeXmlText(text)}
|
|
|
13279
14703
|
pending,
|
|
13280
14704
|
outerToolResult,
|
|
13281
14705
|
context,
|
|
13282
|
-
(update) => this.activity.updateCall(runId, callId, update)
|
|
14706
|
+
(update) => this.activity.updateCall(runId, callId, update),
|
|
14707
|
+
{
|
|
14708
|
+
handoffRetirement: this.#config?.prewalk.handoffRetirement ?? DEFAULT_FABRIC_CONFIG.prewalk.handoffRetirement,
|
|
14709
|
+
handoffRetirementKeep: this.#config?.prewalk.handoffRetirementKeep ?? DEFAULT_FABRIC_CONFIG.prewalk.handoffRetirementKeep
|
|
14710
|
+
}
|
|
13283
14711
|
);
|
|
13284
14712
|
const succeeded = result.completed === true || result.continued === true;
|
|
13285
14713
|
const error = typeof result.error === "string" ? result.error : void 0;
|