omp-fabric 1.1.0 → 1.2.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 +20 -0
- package/README.md +1 -0
- package/dist/agents/handoff.d.ts +1 -1
- package/dist/agents/handoff.d.ts.map +1 -1
- package/dist/agents/types.d.ts +1 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/chunks/{chunk-TLSJXU4F.js → chunk-5YGOVBOZ.js} +179 -10
- package/dist/chunks/chunk-5YGOVBOZ.js.map +7 -0
- package/dist/chunks/{chunk-CVLO4GNW.js → chunk-EQNNENN6.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-WXZP5VWP.js → chunk-TQL7FKMG.js} +3 -3
- package/dist/chunks/{chunk-Z6HEQPXX.js → chunk-WGFHMECI.js} +47 -1
- package/dist/chunks/{chunk-Z6HEQPXX.js.map → chunk-WGFHMECI.js.map} +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-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/fabric-runtime-state.d.ts.map +1 -1
- package/dist/fabric-runtime-state.js +1605 -344
- package/dist/fabric-runtime-state.js.map +4 -4
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -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/codemap-provider.d.ts +14 -0
- package/dist/providers/codemap-provider.d.ts.map +1 -0
- package/dist/residency/host.js +5 -5
- package/dist/residency/omp-entry.js +5 -5
- 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/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 +89 -0
- package/docs/configuration.md +1 -1
- package/package.json +4 -1
- package/dist/chunks/chunk-EZPERYEG.js.map +0 -7
- package/dist/chunks/chunk-L2FNMIOW.js.map +0 -7
- package/dist/chunks/chunk-TLSJXU4F.js.map +0 -7
- package/dist/chunks/chunk-YPYVUGON.js.map +0 -7
- /package/dist/chunks/{chunk-CVLO4GNW.js.map → chunk-EQNNENN6.js.map} +0 -0
- /package/dist/chunks/{chunk-WXZP5VWP.js.map → chunk-TQL7FKMG.js.map} +0 -0
- /package/dist/chunks/{chunk-KIREBD2V.js.map → chunk-ZP3S74LW.js.map} +0 -0
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
repairFabricGuestCode,
|
|
34
34
|
resolveFabricIdentity,
|
|
35
35
|
runFabricHandoffAtBoundary
|
|
36
|
-
} from "./chunks/chunk-
|
|
36
|
+
} from "./chunks/chunk-5YGOVBOZ.js";
|
|
37
37
|
import "./chunks/chunk-7VIQNUPS.js";
|
|
38
38
|
import {
|
|
39
39
|
AgentTranscriptReader,
|
|
@@ -94,7 +94,7 @@ import {
|
|
|
94
94
|
resolveAgentCwd,
|
|
95
95
|
resolveOmpBinary,
|
|
96
96
|
validateAgentCwdRequest
|
|
97
|
-
} from "./chunks/chunk-
|
|
97
|
+
} from "./chunks/chunk-TQL7FKMG.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,7 +114,7 @@ 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,
|
|
@@ -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 path18 from "node:path";
|
|
175
176
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
176
177
|
|
|
177
178
|
// src/actors/global-registry.ts
|
|
@@ -425,36 +426,36 @@ var GlobalActorRegistry = class {
|
|
|
425
426
|
if (!Array.isArray(records)) return;
|
|
426
427
|
for (const value of records) {
|
|
427
428
|
if (typeof value !== "object" || value === null || Array.isArray(value)) continue;
|
|
428
|
-
const
|
|
429
|
-
if (typeof
|
|
429
|
+
const record2 = value;
|
|
430
|
+
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
431
|
continue;
|
|
431
432
|
}
|
|
432
|
-
const events = Array.isArray(
|
|
433
|
-
const topics = Array.isArray(
|
|
433
|
+
const events = Array.isArray(record2.events) ? record2.events.filter((event) => HOST_EVENTS.has(event)) : [];
|
|
434
|
+
const topics = Array.isArray(record2.topics) ? record2.topics.filter(
|
|
434
435
|
(topic) => typeof topic === "string" && TOPIC_PATTERN.test(topic)
|
|
435
436
|
) : [];
|
|
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 timeoutMs = typeof
|
|
446
|
-
const extensions = typeof
|
|
437
|
+
const delivery = record2.delivery === "steer" || record2.delivery === "followUp" || record2.delivery === "nextTurn" ? record2.delivery : "mailbox";
|
|
438
|
+
const responseMode = record2.responseMode === "directive" ? "directive" : "text";
|
|
439
|
+
const triggerTurn = (delivery === "steer" || delivery === "followUp") && record2.triggerTurn === true;
|
|
440
|
+
const coalesce = record2.coalesce !== false;
|
|
441
|
+
const residency = record2.residency === "durable" ? "durable" : "session";
|
|
442
|
+
const runner = record2.runner === "claude" ? "claude" : "omp";
|
|
443
|
+
const thinking = isFabricThinking(record2.thinking) ? record2.thinking : void 0;
|
|
444
|
+
const tools = Array.isArray(record2.tools) ? record2.tools.filter((tool) => typeof tool === "string") : void 0;
|
|
445
|
+
const transport = record2.transport !== void 0 && TRANSPORTS.has(record2.transport) ? record2.transport : void 0;
|
|
446
|
+
const timeoutMs = typeof record2.timeoutMs === "number" ? record2.timeoutMs : void 0;
|
|
447
|
+
const extensions = typeof record2.extensions === "boolean" ? record2.extensions : void 0;
|
|
447
448
|
let requires;
|
|
448
449
|
try {
|
|
449
|
-
requires = normalizeRequirements(
|
|
450
|
+
requires = normalizeRequirements(record2.requires);
|
|
450
451
|
} catch {
|
|
451
452
|
continue;
|
|
452
453
|
}
|
|
453
|
-
const validWhile =
|
|
454
|
+
const validWhile = record2.validWhile?.version === 1 && typeof record2.validWhile.source === "string" && record2.validWhile.source.length <= 16e3 ? clone(record2.validWhile) : void 0;
|
|
454
455
|
const def = {
|
|
455
|
-
id:
|
|
456
|
-
name:
|
|
457
|
-
instructions:
|
|
456
|
+
id: record2.id,
|
|
457
|
+
name: record2.name,
|
|
458
|
+
instructions: record2.instructions,
|
|
458
459
|
events,
|
|
459
460
|
topics,
|
|
460
461
|
delivery,
|
|
@@ -463,9 +464,9 @@ var GlobalActorRegistry = class {
|
|
|
463
464
|
coalesce,
|
|
464
465
|
residency,
|
|
465
466
|
runner,
|
|
466
|
-
createdAt:
|
|
467
|
-
updatedAt: typeof
|
|
468
|
-
...typeof
|
|
467
|
+
createdAt: record2.createdAt,
|
|
468
|
+
updatedAt: typeof record2.updatedAt === "number" ? record2.updatedAt : record2.createdAt,
|
|
469
|
+
...typeof record2.model === "string" && record2.model ? { model: record2.model } : {},
|
|
469
470
|
...thinking ? { thinking } : {},
|
|
470
471
|
...tools ? { tools } : {},
|
|
471
472
|
...transport ? { transport } : {},
|
|
@@ -793,10 +794,10 @@ var normalizeRegistration = (registration, fallbackLabel) => {
|
|
|
793
794
|
}
|
|
794
795
|
};
|
|
795
796
|
};
|
|
796
|
-
var beginCleanup = (
|
|
797
|
-
if (
|
|
798
|
-
|
|
799
|
-
|
|
797
|
+
var beginCleanup = (record2) => {
|
|
798
|
+
if (record2.cleanupStarted) return;
|
|
799
|
+
record2.cleanupStarted = true;
|
|
800
|
+
record2.beforeCleanup?.();
|
|
800
801
|
};
|
|
801
802
|
var closeIterator = async (iterator, disposers) => {
|
|
802
803
|
if (!iterator.return) return;
|
|
@@ -809,20 +810,20 @@ var closeIterator = async (iterator, disposers) => {
|
|
|
809
810
|
var checkTarget = async (guard) => {
|
|
810
811
|
if (guard && !await guard()) throw new FabricEffectDivertedError();
|
|
811
812
|
};
|
|
812
|
-
var driveIterator = async (iterator,
|
|
813
|
+
var driveIterator = async (iterator, record2, guard) => {
|
|
813
814
|
try {
|
|
814
815
|
for (; ; ) {
|
|
815
|
-
if (!
|
|
816
|
-
beginCleanup(
|
|
817
|
-
await closeIterator(iterator,
|
|
816
|
+
if (!record2.armed) {
|
|
817
|
+
beginCleanup(record2);
|
|
818
|
+
await closeIterator(iterator, record2.disposers);
|
|
818
819
|
return;
|
|
819
820
|
}
|
|
820
821
|
await checkTarget(guard);
|
|
821
822
|
const step = await iterator.next();
|
|
822
|
-
if (!step.done) collectDisposer(step.value,
|
|
823
|
-
if (!
|
|
824
|
-
beginCleanup(
|
|
825
|
-
await closeIterator(iterator,
|
|
823
|
+
if (!step.done) collectDisposer(step.value, record2.disposers);
|
|
824
|
+
if (!record2.armed) {
|
|
825
|
+
beginCleanup(record2);
|
|
826
|
+
await closeIterator(iterator, record2.disposers);
|
|
826
827
|
return;
|
|
827
828
|
}
|
|
828
829
|
if (step.done) {
|
|
@@ -833,8 +834,8 @@ var driveIterator = async (iterator, record, guard) => {
|
|
|
833
834
|
} catch (error) {
|
|
834
835
|
if (error instanceof FabricEffectDivertedError) {
|
|
835
836
|
try {
|
|
836
|
-
beginCleanup(
|
|
837
|
-
await closeIterator(iterator,
|
|
837
|
+
beginCleanup(record2);
|
|
838
|
+
await closeIterator(iterator, record2.disposers);
|
|
838
839
|
} catch (closeError) {
|
|
839
840
|
throw new FabricEffectDivertedError(
|
|
840
841
|
"Fabric effect target changed and iterator close failed",
|
|
@@ -845,19 +846,19 @@ var driveIterator = async (iterator, record, guard) => {
|
|
|
845
846
|
throw error;
|
|
846
847
|
}
|
|
847
848
|
};
|
|
848
|
-
var collectEffect = async (effect,
|
|
849
|
+
var collectEffect = async (effect, record2, guard) => {
|
|
849
850
|
const resolved = isPromiseLike(effect) ? await effect : effect;
|
|
850
851
|
if (resolved === void 0 || resolved === null || typeof resolved === "function") {
|
|
851
|
-
collectDisposer(resolved,
|
|
852
|
-
if (
|
|
852
|
+
collectDisposer(resolved, record2.disposers);
|
|
853
|
+
if (record2.armed) await checkTarget(guard);
|
|
853
854
|
return;
|
|
854
855
|
}
|
|
855
856
|
if (isAsyncIterable(resolved)) {
|
|
856
|
-
await driveIterator(resolved[Symbol.asyncIterator](),
|
|
857
|
+
await driveIterator(resolved[Symbol.asyncIterator](), record2, guard);
|
|
857
858
|
return;
|
|
858
859
|
}
|
|
859
860
|
if (isIterable(resolved)) {
|
|
860
|
-
await driveIterator(resolved[Symbol.iterator](),
|
|
861
|
+
await driveIterator(resolved[Symbol.iterator](), record2, guard);
|
|
861
862
|
return;
|
|
862
863
|
}
|
|
863
864
|
throw new TypeError("Fabric effect returned an unsupported value");
|
|
@@ -876,10 +877,10 @@ var FabricEffectScope = class {
|
|
|
876
877
|
}
|
|
877
878
|
footprint(limit = Number.POSITIVE_INFINITY) {
|
|
878
879
|
const effects = [];
|
|
879
|
-
for (const
|
|
880
|
+
for (const record2 of this.#records) {
|
|
880
881
|
if (effects.length >= limit) break;
|
|
881
|
-
if (!
|
|
882
|
-
effects.push({ ...
|
|
882
|
+
if (!record2.disposed && record2.effect) {
|
|
883
|
+
effects.push({ ...record2.effect, resources: [...record2.effect.resources] });
|
|
883
884
|
}
|
|
884
885
|
}
|
|
885
886
|
return effects;
|
|
@@ -889,7 +890,7 @@ var FabricEffectScope = class {
|
|
|
889
890
|
throw new Error("Cannot create an effect on a disposing Fabric scope");
|
|
890
891
|
}
|
|
891
892
|
const normalized = normalizeRegistration(registration, "anonymous");
|
|
892
|
-
const
|
|
893
|
+
const record2 = {
|
|
893
894
|
label: normalized.label,
|
|
894
895
|
...normalized.effect ? { effect: normalized.effect } : {},
|
|
895
896
|
disposers: [],
|
|
@@ -902,9 +903,9 @@ var FabricEffectScope = class {
|
|
|
902
903
|
...hooks.beforeCleanup ? { beforeCleanup: hooks.beforeCleanup } : {}
|
|
903
904
|
};
|
|
904
905
|
const cleanupDisposers = async () => {
|
|
905
|
-
beginCleanup(
|
|
906
|
+
beginCleanup(record2);
|
|
906
907
|
const failures = [];
|
|
907
|
-
for (const disposer of
|
|
908
|
+
for (const disposer of record2.disposers.splice(0).reverse()) {
|
|
908
909
|
try {
|
|
909
910
|
await disposer();
|
|
910
911
|
} catch (error) {
|
|
@@ -912,64 +913,64 @@ var FabricEffectScope = class {
|
|
|
912
913
|
}
|
|
913
914
|
}
|
|
914
915
|
if (failures.length > 0) {
|
|
915
|
-
throw new AggregateError(failures, `Fabric effect cleanup failed: ${
|
|
916
|
+
throw new AggregateError(failures, `Fabric effect cleanup failed: ${record2.label}`);
|
|
916
917
|
}
|
|
917
918
|
};
|
|
918
919
|
let disposal;
|
|
919
|
-
|
|
920
|
-
if (
|
|
921
|
-
|
|
922
|
-
|
|
920
|
+
record2.dispose = async () => {
|
|
921
|
+
if (record2.disposed) return disposal;
|
|
922
|
+
record2.disposed = true;
|
|
923
|
+
record2.armed = false;
|
|
923
924
|
disposal = (async () => {
|
|
924
|
-
await
|
|
925
|
+
await record2.setup.catch(() => void 0);
|
|
925
926
|
await cleanupDisposers();
|
|
926
927
|
})();
|
|
927
928
|
return disposal;
|
|
928
929
|
};
|
|
929
|
-
this.#records.push(
|
|
930
|
-
|
|
930
|
+
this.#records.push(record2);
|
|
931
|
+
record2.setup = (async () => {
|
|
931
932
|
try {
|
|
932
933
|
if (this.#guard) await checkTarget(this.#guard);
|
|
933
|
-
if (!
|
|
934
|
-
await collectEffect(setup(),
|
|
934
|
+
if (!record2.armed) return;
|
|
935
|
+
await collectEffect(setup(), record2, this.#guard);
|
|
935
936
|
} catch (error) {
|
|
936
937
|
try {
|
|
937
938
|
await cleanupDisposers();
|
|
938
939
|
} catch (cleanupError) {
|
|
939
940
|
const failures = cleanupError instanceof AggregateError ? cleanupError.errors : [cleanupError];
|
|
940
941
|
for (const failure of failures) {
|
|
941
|
-
this.#setupCleanupFailures.push({ label:
|
|
942
|
+
this.#setupCleanupFailures.push({ label: record2.label, error: errorMessage(failure) });
|
|
942
943
|
}
|
|
943
944
|
throw new AggregateError(
|
|
944
945
|
[error, cleanupError],
|
|
945
|
-
`Fabric effect setup and rollback failed: ${
|
|
946
|
+
`Fabric effect setup and rollback failed: ${record2.label}`
|
|
946
947
|
);
|
|
947
948
|
}
|
|
948
949
|
throw error;
|
|
949
950
|
}
|
|
950
951
|
})();
|
|
951
952
|
try {
|
|
952
|
-
await
|
|
953
|
+
await record2.setup;
|
|
953
954
|
if (this.#state === "open") {
|
|
954
|
-
const index = this.#records.indexOf(
|
|
955
|
+
const index = this.#records.indexOf(record2);
|
|
955
956
|
if (index >= 0 && index !== this.#records.length - 1) {
|
|
956
957
|
this.#records.splice(index, 1);
|
|
957
|
-
this.#records.push(
|
|
958
|
+
this.#records.push(record2);
|
|
958
959
|
}
|
|
959
960
|
}
|
|
960
961
|
} catch (error) {
|
|
961
|
-
const index = this.#records.indexOf(
|
|
962
|
+
const index = this.#records.indexOf(record2);
|
|
962
963
|
if (index >= 0) this.#records.splice(index, 1);
|
|
963
964
|
throw error;
|
|
964
965
|
}
|
|
965
|
-
return
|
|
966
|
+
return record2.dispose;
|
|
966
967
|
}
|
|
967
968
|
defer(disposer, registration = "deferred") {
|
|
968
969
|
if (this.#state !== "open") {
|
|
969
970
|
throw new Error("Cannot defer cleanup on a disposing Fabric scope");
|
|
970
971
|
}
|
|
971
972
|
const normalized = normalizeRegistration(registration, "deferred");
|
|
972
|
-
const
|
|
973
|
+
const record2 = {
|
|
973
974
|
label: normalized.label,
|
|
974
975
|
...normalized.effect ? { effect: normalized.effect } : {},
|
|
975
976
|
disposers: [disposer],
|
|
@@ -981,13 +982,13 @@ var FabricEffectScope = class {
|
|
|
981
982
|
cleanupStarted: false
|
|
982
983
|
};
|
|
983
984
|
let disposal;
|
|
984
|
-
|
|
985
|
-
if (
|
|
986
|
-
|
|
987
|
-
|
|
985
|
+
record2.dispose = async () => {
|
|
986
|
+
if (record2.disposed) return disposal;
|
|
987
|
+
record2.disposed = true;
|
|
988
|
+
record2.armed = false;
|
|
988
989
|
disposal = (async () => {
|
|
989
990
|
const failures = [];
|
|
990
|
-
for (const cleanup of
|
|
991
|
+
for (const cleanup of record2.disposers.splice(0).reverse()) {
|
|
991
992
|
try {
|
|
992
993
|
await cleanup();
|
|
993
994
|
} catch (error) {
|
|
@@ -995,29 +996,29 @@ var FabricEffectScope = class {
|
|
|
995
996
|
}
|
|
996
997
|
}
|
|
997
998
|
if (failures.length > 0) {
|
|
998
|
-
throw new AggregateError(failures, `Fabric effect cleanup failed: ${
|
|
999
|
+
throw new AggregateError(failures, `Fabric effect cleanup failed: ${record2.label}`);
|
|
999
1000
|
}
|
|
1000
1001
|
})();
|
|
1001
1002
|
return disposal;
|
|
1002
1003
|
};
|
|
1003
|
-
this.#records.push(
|
|
1004
|
-
return
|
|
1004
|
+
this.#records.push(record2);
|
|
1005
|
+
return record2.dispose;
|
|
1005
1006
|
}
|
|
1006
1007
|
dispose() {
|
|
1007
1008
|
if (this.#cleanup) return this.#cleanup;
|
|
1008
1009
|
this.#state = "disposing";
|
|
1009
1010
|
this.#cleanup = (async () => {
|
|
1010
1011
|
const failures = this.#setupCleanupFailures.splice(0);
|
|
1011
|
-
for (const
|
|
1012
|
+
for (const record2 of this.#records.splice(0).reverse()) {
|
|
1012
1013
|
try {
|
|
1013
|
-
await
|
|
1014
|
+
await record2.dispose();
|
|
1014
1015
|
} catch (error) {
|
|
1015
1016
|
if (error instanceof AggregateError) {
|
|
1016
1017
|
for (const nested of error.errors) {
|
|
1017
|
-
failures.push({ label:
|
|
1018
|
+
failures.push({ label: record2.label, error: errorMessage(nested) });
|
|
1018
1019
|
}
|
|
1019
1020
|
} else {
|
|
1020
|
-
failures.push({ label:
|
|
1021
|
+
failures.push({ label: record2.label, error: errorMessage(error) });
|
|
1021
1022
|
}
|
|
1022
1023
|
}
|
|
1023
1024
|
}
|
|
@@ -2218,10 +2219,10 @@ var FabricComponentSupervisor = class {
|
|
|
2218
2219
|
adjacent.set(edge.from, targets);
|
|
2219
2220
|
}
|
|
2220
2221
|
const cycles = /* @__PURE__ */ new Map();
|
|
2221
|
-
const visit = (node,
|
|
2222
|
+
const visit = (node, path19, positions) => {
|
|
2222
2223
|
const position = positions.get(node);
|
|
2223
2224
|
if (position !== void 0) {
|
|
2224
|
-
const cycle =
|
|
2225
|
+
const cycle = path19.slice(position);
|
|
2225
2226
|
const rotations = cycle.map((_, index) => [
|
|
2226
2227
|
...cycle.slice(index),
|
|
2227
2228
|
...cycle.slice(0, index)
|
|
@@ -2231,10 +2232,10 @@ var FabricComponentSupervisor = class {
|
|
|
2231
2232
|
cycles.set(canonical.join("\0"), canonical);
|
|
2232
2233
|
return;
|
|
2233
2234
|
}
|
|
2234
|
-
if (
|
|
2235
|
-
const nextPositions = new Map(positions).set(node,
|
|
2235
|
+
if (path19.length > this.#components.size) return;
|
|
2236
|
+
const nextPositions = new Map(positions).set(node, path19.length);
|
|
2236
2237
|
for (const target of adjacent.get(node) ?? []) {
|
|
2237
|
-
visit(target, [...
|
|
2238
|
+
visit(target, [...path19, node], nextPositions);
|
|
2238
2239
|
}
|
|
2239
2240
|
};
|
|
2240
2241
|
for (const id of this.#components.keys()) visit(id, [], /* @__PURE__ */ new Map());
|
|
@@ -2736,18 +2737,18 @@ var finiteNumber = (value) => typeof value === "number" && Number.isFinite(value
|
|
|
2736
2737
|
var nonEmptyString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2737
2738
|
var decodeOutcome = (raw) => {
|
|
2738
2739
|
if (typeof raw !== "object" || raw === null) return void 0;
|
|
2739
|
-
const
|
|
2740
|
-
const at = finiteNumber(
|
|
2741
|
-
const requestedBy = nonEmptyString(
|
|
2742
|
-
const status =
|
|
2740
|
+
const record2 = raw;
|
|
2741
|
+
const at = finiteNumber(record2.at);
|
|
2742
|
+
const requestedBy = nonEmptyString(record2.requestedBy);
|
|
2743
|
+
const status = record2.status;
|
|
2743
2744
|
if (at === void 0 || requestedBy === void 0) return void 0;
|
|
2744
2745
|
if (status !== "committed" && status !== "cancelled" && status !== "failed" && status !== "skipped") {
|
|
2745
2746
|
return void 0;
|
|
2746
2747
|
}
|
|
2747
|
-
const summary = nonEmptyString(
|
|
2748
|
-
const error = nonEmptyString(
|
|
2749
|
-
const tokensBefore = finiteNumber(
|
|
2750
|
-
const estimatedTokensAfter = finiteNumber(
|
|
2748
|
+
const summary = nonEmptyString(record2.summary);
|
|
2749
|
+
const error = nonEmptyString(record2.error);
|
|
2750
|
+
const tokensBefore = finiteNumber(record2.tokensBefore);
|
|
2751
|
+
const estimatedTokensAfter = finiteNumber(record2.estimatedTokensAfter);
|
|
2751
2752
|
return {
|
|
2752
2753
|
at,
|
|
2753
2754
|
requestedBy,
|
|
@@ -2964,7 +2965,7 @@ var FabricExecutionService = class {
|
|
|
2964
2965
|
})) ?? []
|
|
2965
2966
|
) : void 0;
|
|
2966
2967
|
const code = repairFabricGuestCode(options.code);
|
|
2967
|
-
const
|
|
2968
|
+
const checked2 = dependencies.typeCheckFabricCode(
|
|
2968
2969
|
code,
|
|
2969
2970
|
dependencies.guestTypeDeclarations(effectiveFullCodeMode, {
|
|
2970
2971
|
excludeGlobals: [...unavailable.keys()],
|
|
@@ -2972,8 +2973,8 @@ var FabricExecutionService = class {
|
|
|
2972
2973
|
...coreOverrideDeclarations ? { coreOverrides: coreOverrideDeclarations } : {}
|
|
2973
2974
|
})
|
|
2974
2975
|
);
|
|
2975
|
-
if (
|
|
2976
|
-
for (const error of
|
|
2976
|
+
if (checked2.errors.length > 0) {
|
|
2977
|
+
for (const error of checked2.errors) {
|
|
2977
2978
|
const missing = /^Cannot find name '([^']+)'/.exec(error.message);
|
|
2978
2979
|
const reason = missing?.[1] ? unavailable.get(missing[1]) : void 0;
|
|
2979
2980
|
if (missing && reason) {
|
|
@@ -2990,10 +2991,10 @@ var FabricExecutionService = class {
|
|
|
2990
2991
|
trace: traceRecorder.seal(
|
|
2991
2992
|
"failed",
|
|
2992
2993
|
[],
|
|
2993
|
-
`Type checking failed (${
|
|
2994
|
+
`Type checking failed (${checked2.errors.length} ${checked2.errors.length === 1 ? "error" : "errors"})`
|
|
2994
2995
|
),
|
|
2995
2996
|
elapsedMs: performance.now() - startedAt,
|
|
2996
|
-
typeErrors:
|
|
2997
|
+
typeErrors: checked2.errors
|
|
2997
2998
|
};
|
|
2998
2999
|
}
|
|
2999
3000
|
const classifierUsages = [];
|
|
@@ -3424,8 +3425,8 @@ var FabricExecutionService = class {
|
|
|
3424
3425
|
memoryLimitBytes: this.config.executor.memoryLimitBytes,
|
|
3425
3426
|
maxLogChars: this.config.executor.maxOutputChars,
|
|
3426
3427
|
minimumTimeoutMsForHostCall,
|
|
3427
|
-
...
|
|
3428
|
-
...
|
|
3428
|
+
...checked2.javascript ? { transpiledCode: checked2.javascript } : {},
|
|
3429
|
+
...checked2.sourceMap ? { transpiledSourceMap: checked2.sourceMap } : {},
|
|
3429
3430
|
...options.payloads ? { payloads: options.payloads } : {},
|
|
3430
3431
|
...Object.keys(proxyNames).length > 0 ? { proxyNames } : {},
|
|
3431
3432
|
...options.tokenBudget !== void 0 ? { tokenBudget: options.tokenBudget } : {},
|
|
@@ -5032,10 +5033,10 @@ var ResidencyClient = class {
|
|
|
5032
5033
|
statusAgent(id) {
|
|
5033
5034
|
const metadata = this.#metadata(id);
|
|
5034
5035
|
if (!metadata) throw new Error(`Unknown durable Fabric agent: ${id}`);
|
|
5035
|
-
const
|
|
5036
|
-
if (!
|
|
5036
|
+
const record2 = readJson(path5.join(metadata.runDirectory, "status.json"));
|
|
5037
|
+
if (!record2 || record2.id !== metadata.id) return structuredClone(metadata.handle);
|
|
5037
5038
|
return {
|
|
5038
|
-
...
|
|
5039
|
+
...record2,
|
|
5039
5040
|
cwd: metadata.handle.cwd,
|
|
5040
5041
|
residency: "durable",
|
|
5041
5042
|
logFile: path5.join(metadata.runDirectory, "events.jsonl"),
|
|
@@ -5398,20 +5399,20 @@ var actorRequest = (args, context, manager, inheritModel = true) => {
|
|
|
5398
5399
|
var collectAgentToolPreviewNodes = (records, options, depth = 0, budget = { remaining: options.maxNodes ?? AGENT_PREVIEW_TREE_MAX_NODES }) => {
|
|
5399
5400
|
const maxDepth = options.maxDepth ?? AGENT_PREVIEW_TREE_MAX_DEPTH;
|
|
5400
5401
|
const nodes = [];
|
|
5401
|
-
for (const
|
|
5402
|
+
for (const record2 of records) {
|
|
5402
5403
|
if (budget.remaining <= 0) break;
|
|
5403
5404
|
budget.remaining -= 1;
|
|
5404
|
-
const descendants = Array.isArray(
|
|
5405
|
+
const descendants = Array.isArray(record2.nestedAgents) ? record2.nestedAgents : [];
|
|
5405
5406
|
const agents = depth + 1 < maxDepth && descendants.length > 0 && budget.remaining > 0 ? collectAgentToolPreviewNodes(descendants, options, depth + 1, budget) : [];
|
|
5406
5407
|
nodes.push({
|
|
5407
|
-
id:
|
|
5408
|
-
name:
|
|
5409
|
-
status:
|
|
5410
|
-
...
|
|
5411
|
-
owner:
|
|
5412
|
-
...
|
|
5413
|
-
...
|
|
5414
|
-
tools: options.tools(
|
|
5408
|
+
id: record2.id,
|
|
5409
|
+
name: record2.actorName ?? record2.name,
|
|
5410
|
+
status: record2.status,
|
|
5411
|
+
...record2.runner === "omp" || record2.runner === "claude" || record2.runner === "veda" ? { runner: record2.runner } : {},
|
|
5412
|
+
owner: record2.actorId ? "actor" : "agent",
|
|
5413
|
+
...record2.currentTool ? { currentTool: record2.currentTool } : {},
|
|
5414
|
+
...record2.text ? { text: tailCodePoints(record2.text, AGENT_PREVIEW_TEXT_CODE_POINTS) } : {},
|
|
5415
|
+
tools: options.tools(record2),
|
|
5415
5416
|
...agents.length > 0 ? { agents } : {},
|
|
5416
5417
|
...descendants.length > agents.length ? { agentsTruncated: true } : {}
|
|
5417
5418
|
});
|
|
@@ -6457,18 +6458,18 @@ var AgentsProvider = class {
|
|
|
6457
6458
|
const scope = this.#participantScope(scopeValue, "local");
|
|
6458
6459
|
if (scope === "local") return this.manager.list();
|
|
6459
6460
|
const local = /* @__PURE__ */ new Map();
|
|
6460
|
-
const append = (
|
|
6461
|
-
local.set(
|
|
6462
|
-
if ("nestedAgents" in
|
|
6463
|
-
for (const nested of
|
|
6461
|
+
const append = (record2) => {
|
|
6462
|
+
local.set(record2.id, record2);
|
|
6463
|
+
if ("nestedAgents" in record2) {
|
|
6464
|
+
for (const nested of record2.nestedAgents ?? []) append(nested);
|
|
6464
6465
|
}
|
|
6465
6466
|
};
|
|
6466
|
-
for (const
|
|
6467
|
-
for (const
|
|
6467
|
+
for (const record2 of this.manager.list()) append(record2);
|
|
6468
|
+
for (const record2 of this.residency?.listAgents() ?? []) append(record2);
|
|
6468
6469
|
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(
|
|
6470
|
+
const seen = new Set(listed.map((record2) => record2.id));
|
|
6471
|
+
for (const record2 of this.residency?.listAgents() ?? []) {
|
|
6472
|
+
if (!seen.has(record2.id)) listed.push(record2);
|
|
6472
6473
|
}
|
|
6473
6474
|
return listed;
|
|
6474
6475
|
}
|
|
@@ -6624,9 +6625,9 @@ var CapturedToolsProvider = class {
|
|
|
6624
6625
|
#allowedTools = readChildToolAllowlist();
|
|
6625
6626
|
async list(request, _context) {
|
|
6626
6627
|
const query = request.query?.trim().toLowerCase();
|
|
6627
|
-
const
|
|
6628
|
-
if (!query) return
|
|
6629
|
-
return
|
|
6628
|
+
const descriptors7 = this.catalog.list().filter((entry) => !this.#allowedTools || this.#allowedTools.has(entry.name)).map(descriptorFrom);
|
|
6629
|
+
if (!query) return descriptors7;
|
|
6630
|
+
return descriptors7.filter(
|
|
6630
6631
|
(descriptor) => `${descriptor.name} ${descriptor.description} ${descriptor.namespace ?? ""}`.toLowerCase().includes(query)
|
|
6631
6632
|
);
|
|
6632
6633
|
}
|
|
@@ -6762,32 +6763,1274 @@ var CapturedToolsProvider = class {
|
|
|
6762
6763
|
}
|
|
6763
6764
|
};
|
|
6764
6765
|
|
|
6765
|
-
// src/providers/
|
|
6766
|
+
// src/providers/codemap-provider.ts
|
|
6766
6767
|
import { Type } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
6767
6768
|
import { validateJsonSchemaValue } from "@oh-my-pi/pi-ai/utils/schema";
|
|
6768
|
-
|
|
6769
|
-
|
|
6769
|
+
|
|
6770
|
+
// src/codemap/budget.ts
|
|
6771
|
+
var KIND_LETTERS = {
|
|
6772
|
+
fn: "f",
|
|
6773
|
+
class: "c",
|
|
6774
|
+
iface: "i",
|
|
6775
|
+
type: "t",
|
|
6776
|
+
const: "v",
|
|
6777
|
+
enum: "e",
|
|
6778
|
+
method: "m"
|
|
6779
|
+
};
|
|
6780
|
+
var LEGEND = "# f=fn c=class i=iface t=type v=const e=enum m=method";
|
|
6781
|
+
var MIN_FILE_ENTRY = 8;
|
|
6782
|
+
var FOCUS_WEIGHT = 1;
|
|
6783
|
+
var CASCADE_WEIGHT = 0.6;
|
|
6784
|
+
var NAME_EXACT_SCORE = 6;
|
|
6785
|
+
var NAME_WORD_SCORE = 3;
|
|
6786
|
+
var PATH_WORD_SCORE = 4;
|
|
6787
|
+
var SUBSTRING_SCORE = 1;
|
|
6788
|
+
var MIN_SUBSTRING_LENGTH = 3;
|
|
6789
|
+
var EXPORT_PASSES = [true, false];
|
|
6790
|
+
var isUpper = (code) => code >= 65 && code <= 90;
|
|
6791
|
+
var isLower = (code) => code >= 97 && code <= 122;
|
|
6792
|
+
var isDigit = (code) => code >= 48 && code <= 57;
|
|
6793
|
+
var isWordChar = (code) => isUpper(code) || isLower(code) || isDigit(code);
|
|
6794
|
+
var compareText = (left, right) => left < right ? -1 : left > right ? 1 : 0;
|
|
6795
|
+
var collectWords = (value, sink) => {
|
|
6796
|
+
let start = -1;
|
|
6797
|
+
for (let index = 0; index < value.length; index++) {
|
|
6798
|
+
const code = value.charCodeAt(index);
|
|
6799
|
+
if (!isWordChar(code)) {
|
|
6800
|
+
if (start >= 0) sink.add(value.slice(start, index).toLowerCase());
|
|
6801
|
+
start = -1;
|
|
6802
|
+
continue;
|
|
6803
|
+
}
|
|
6804
|
+
if (start < 0) {
|
|
6805
|
+
start = index;
|
|
6806
|
+
continue;
|
|
6807
|
+
}
|
|
6808
|
+
const previous = value.charCodeAt(index - 1);
|
|
6809
|
+
const next = index + 1 < value.length ? value.charCodeAt(index + 1) : 0;
|
|
6810
|
+
if (isUpper(code) && (!isUpper(previous) || isLower(next))) {
|
|
6811
|
+
sink.add(value.slice(start, index).toLowerCase());
|
|
6812
|
+
start = index;
|
|
6813
|
+
}
|
|
6814
|
+
}
|
|
6815
|
+
if (start >= 0) sink.add(value.slice(start).toLowerCase());
|
|
6816
|
+
};
|
|
6817
|
+
var focusTerms = (focus) => {
|
|
6818
|
+
if (focus === void 0 || focus.length === 0) return [];
|
|
6819
|
+
const words = /* @__PURE__ */ new Set();
|
|
6820
|
+
collectWords(focus, words);
|
|
6821
|
+
return [...words];
|
|
6822
|
+
};
|
|
6823
|
+
var lexiconFor = (group) => {
|
|
6824
|
+
const pathWords = /* @__PURE__ */ new Set();
|
|
6825
|
+
collectWords(group.file, pathWords);
|
|
6826
|
+
const names = /* @__PURE__ */ new Set();
|
|
6827
|
+
const nameWords = /* @__PURE__ */ new Set();
|
|
6828
|
+
const distinct = [];
|
|
6829
|
+
for (const symbol of group.symbols) {
|
|
6830
|
+
const lowered = symbol.name.toLowerCase();
|
|
6831
|
+
if (names.has(lowered)) continue;
|
|
6832
|
+
names.add(lowered);
|
|
6833
|
+
distinct.push(lowered);
|
|
6834
|
+
collectWords(symbol.name, nameWords);
|
|
6835
|
+
}
|
|
6836
|
+
return {
|
|
6837
|
+
pathWords,
|
|
6838
|
+
pathLower: group.file.toLowerCase(),
|
|
6839
|
+
names,
|
|
6840
|
+
nameWords,
|
|
6841
|
+
namesBlob: distinct.join("\n")
|
|
6842
|
+
};
|
|
6843
|
+
};
|
|
6844
|
+
var termScore = (term, lexicon) => {
|
|
6845
|
+
const wideEnough = term.length >= MIN_SUBSTRING_LENGTH;
|
|
6846
|
+
let score = 0;
|
|
6847
|
+
if (lexicon.names.has(term)) score += NAME_EXACT_SCORE;
|
|
6848
|
+
else if (lexicon.nameWords.has(term)) score += NAME_WORD_SCORE;
|
|
6849
|
+
else if (wideEnough && lexicon.namesBlob.includes(term)) score += SUBSTRING_SCORE;
|
|
6850
|
+
if (lexicon.pathWords.has(term)) score += PATH_WORD_SCORE;
|
|
6851
|
+
else if (wideEnough && lexicon.pathLower.includes(term)) score += SUBSTRING_SCORE;
|
|
6852
|
+
return score;
|
|
6853
|
+
};
|
|
6854
|
+
var groupByFile = (symbols) => {
|
|
6855
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
6856
|
+
for (const symbol of symbols) {
|
|
6857
|
+
let group = byFile.get(symbol.file);
|
|
6858
|
+
if (group === void 0) {
|
|
6859
|
+
group = { file: symbol.file, symbols: [], score: 0 };
|
|
6860
|
+
byFile.set(symbol.file, group);
|
|
6861
|
+
}
|
|
6862
|
+
group.symbols.push(symbol);
|
|
6863
|
+
}
|
|
6864
|
+
for (const group of byFile.values()) {
|
|
6865
|
+
group.symbols.sort((left, right) => left.line - right.line || compareText(left.name, right.name) || compareText(left.kind, right.kind));
|
|
6866
|
+
}
|
|
6867
|
+
return [...byFile.values()];
|
|
6868
|
+
};
|
|
6869
|
+
var applyFocus = (groups, focus) => {
|
|
6870
|
+
const terms = focusTerms(focus);
|
|
6871
|
+
if (terms.length === 0) return;
|
|
6872
|
+
let peak = 0;
|
|
6873
|
+
for (const group of groups) {
|
|
6874
|
+
const lexicon = lexiconFor(group);
|
|
6875
|
+
let raw = 0;
|
|
6876
|
+
for (const term of terms) raw += termScore(term, lexicon);
|
|
6877
|
+
group.score = raw;
|
|
6878
|
+
if (raw > peak) peak = raw;
|
|
6879
|
+
}
|
|
6880
|
+
for (const group of groups) group.score = peak > 0 ? group.score / peak * FOCUS_WEIGHT : 0;
|
|
6881
|
+
};
|
|
6882
|
+
var applyCascade = (groups, request) => {
|
|
6883
|
+
const edges = request.cascade?.edges;
|
|
6884
|
+
if (edges === void 0 || edges.length === 0) return;
|
|
6885
|
+
const best = /* @__PURE__ */ new Map();
|
|
6886
|
+
let peak = 0;
|
|
6887
|
+
for (const edge of edges) {
|
|
6888
|
+
if (edge.score > peak) peak = edge.score;
|
|
6889
|
+
const previous = best.get(edge.file);
|
|
6890
|
+
if (previous === void 0 || edge.score > previous) best.set(edge.file, edge.score);
|
|
6891
|
+
}
|
|
6892
|
+
if (peak <= 0) return;
|
|
6893
|
+
for (const group of groups) {
|
|
6894
|
+
const edgeScore = best.get(group.file);
|
|
6895
|
+
if (edgeScore !== void 0 && edgeScore > 0) {
|
|
6896
|
+
group.score += edgeScore / peak * CASCADE_WEIGHT;
|
|
6897
|
+
}
|
|
6898
|
+
}
|
|
6899
|
+
};
|
|
6900
|
+
var rankGroups = (groups, request) => {
|
|
6901
|
+
applyFocus(groups, request.focus);
|
|
6902
|
+
applyCascade(groups, request);
|
|
6903
|
+
groups.sort((left, right) => right.score - left.score || right.symbols.length - left.symbols.length || compareText(left.file, right.file));
|
|
6904
|
+
};
|
|
6905
|
+
var spend = (groups, charBudget, reserved) => {
|
|
6906
|
+
const lines = [];
|
|
6907
|
+
let used = reserved;
|
|
6908
|
+
let filesShown = 0;
|
|
6909
|
+
let symbolsShown = 0;
|
|
6910
|
+
let omittedFiles = 0;
|
|
6911
|
+
let omittedSymbols = 0;
|
|
6912
|
+
for (const group of groups) {
|
|
6913
|
+
const headerCost = group.file.length + 1;
|
|
6914
|
+
if (used + headerCost >= charBudget) {
|
|
6915
|
+
omittedFiles++;
|
|
6916
|
+
omittedSymbols += group.symbols.length;
|
|
6917
|
+
continue;
|
|
6918
|
+
}
|
|
6919
|
+
const rendered = new Array(group.symbols.length);
|
|
6920
|
+
const picked = [];
|
|
6921
|
+
let cost = headerCost;
|
|
6922
|
+
for (const exported of EXPORT_PASSES) {
|
|
6923
|
+
for (let index = 0; index < group.symbols.length; index++) {
|
|
6924
|
+
const symbol = group.symbols[index];
|
|
6925
|
+
if (symbol.exported !== exported) continue;
|
|
6926
|
+
let line = rendered[index];
|
|
6927
|
+
if (line === void 0) {
|
|
6928
|
+
line = `${symbol.line} ${KIND_LETTERS[symbol.kind]} ${symbol.name}`;
|
|
6929
|
+
rendered[index] = line;
|
|
6930
|
+
}
|
|
6931
|
+
const lineCost = line.length + 1;
|
|
6932
|
+
if (used + cost + lineCost > charBudget) continue;
|
|
6933
|
+
cost += lineCost;
|
|
6934
|
+
picked.push(index);
|
|
6935
|
+
}
|
|
6936
|
+
}
|
|
6937
|
+
if (picked.length === 0) {
|
|
6938
|
+
omittedFiles++;
|
|
6939
|
+
omittedSymbols += group.symbols.length;
|
|
6940
|
+
continue;
|
|
6941
|
+
}
|
|
6942
|
+
picked.sort((left, right) => left - right);
|
|
6943
|
+
lines.push(group.file);
|
|
6944
|
+
for (const index of picked) lines.push(rendered[index]);
|
|
6945
|
+
used += cost;
|
|
6946
|
+
filesShown++;
|
|
6947
|
+
symbolsShown += picked.length;
|
|
6948
|
+
omittedSymbols += group.symbols.length - picked.length;
|
|
6949
|
+
}
|
|
6950
|
+
return { lines, filesShown, symbolsShown, omittedFiles, omittedSymbols };
|
|
6951
|
+
};
|
|
6952
|
+
function assembleMap(request) {
|
|
6953
|
+
const groups = groupByFile(request.index.symbols);
|
|
6954
|
+
rankGroups(groups, request);
|
|
6955
|
+
const charBudget = request.maxTokens > 0 ? Math.floor(request.maxTokens) * 4 : 0;
|
|
6956
|
+
const legendCost = LEGEND.length + 1;
|
|
6957
|
+
const reserved = charBudget >= legendCost + MIN_FILE_ENTRY ? legendCost : 0;
|
|
6958
|
+
let plan = spend(groups, charBudget, reserved);
|
|
6959
|
+
let legendShown = reserved > 0;
|
|
6960
|
+
if (plan.filesShown === 0 && reserved > 0) {
|
|
6961
|
+
plan = spend(groups, charBudget, 0);
|
|
6962
|
+
legendShown = false;
|
|
6963
|
+
}
|
|
6964
|
+
const body = plan.lines.join("\n");
|
|
6965
|
+
const text = plan.lines.length === 0 ? "" : legendShown ? `${LEGEND}
|
|
6966
|
+
${body}
|
|
6967
|
+
` : `${body}
|
|
6968
|
+
`;
|
|
6969
|
+
return {
|
|
6970
|
+
text,
|
|
6971
|
+
tokensEstimated: estimateTokens({ role: "user", content: text }),
|
|
6972
|
+
filesShown: plan.filesShown,
|
|
6973
|
+
symbolsShown: plan.symbolsShown,
|
|
6974
|
+
omittedFiles: plan.omittedFiles,
|
|
6975
|
+
omittedSymbols: plan.omittedSymbols,
|
|
6976
|
+
truncated: plan.omittedFiles > 0 || plan.omittedSymbols > 0
|
|
6977
|
+
};
|
|
6978
|
+
}
|
|
6979
|
+
|
|
6980
|
+
// src/codemap/cascade.ts
|
|
6981
|
+
import { execFile } from "node:child_process";
|
|
6982
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
6983
|
+
import path7 from "node:path";
|
|
6984
|
+
import { promisify } from "node:util";
|
|
6985
|
+
var execFileAsync = promisify(execFile);
|
|
6986
|
+
var BULK_COMMIT_FILE_CEILING = 100;
|
|
6987
|
+
var GIT_TIMEOUT_MS = 2e4;
|
|
6988
|
+
var GIT_MAX_BUFFER = 64 << 20;
|
|
6989
|
+
var COMMIT_MARKER_CODE = 1;
|
|
6990
|
+
var QUOTE_CODE = 34;
|
|
6991
|
+
var ESCAPE_BYTES = /* @__PURE__ */ new Map([
|
|
6992
|
+
["a", 7],
|
|
6993
|
+
["b", 8],
|
|
6994
|
+
["t", 9],
|
|
6995
|
+
["n", 10],
|
|
6996
|
+
["v", 11],
|
|
6997
|
+
["f", 12],
|
|
6998
|
+
["r", 13],
|
|
6999
|
+
['"', 34],
|
|
7000
|
+
["\\", 92]
|
|
7001
|
+
]);
|
|
7002
|
+
var toPosix = (value) => path7.sep === "/" ? value : value.replaceAll(path7.sep, "/");
|
|
7003
|
+
var unquoteGitPath = (raw) => {
|
|
7004
|
+
if (raw.length < 2 || raw.charCodeAt(raw.length - 1) !== QUOTE_CODE) return raw;
|
|
7005
|
+
const bytes = [];
|
|
7006
|
+
for (let index = 1; index < raw.length - 1; index += 1) {
|
|
7007
|
+
const char = raw[index];
|
|
7008
|
+
if (char !== "\\") {
|
|
7009
|
+
const code = char.charCodeAt(0);
|
|
7010
|
+
if (code < 128) bytes.push(code);
|
|
7011
|
+
else for (const byte of Buffer.from(char, "utf8")) bytes.push(byte);
|
|
7012
|
+
continue;
|
|
7013
|
+
}
|
|
7014
|
+
const next = raw[index + 1];
|
|
7015
|
+
if (next === void 0) break;
|
|
7016
|
+
const mapped = ESCAPE_BYTES.get(next);
|
|
7017
|
+
if (mapped !== void 0) {
|
|
7018
|
+
bytes.push(mapped);
|
|
7019
|
+
index += 1;
|
|
7020
|
+
continue;
|
|
7021
|
+
}
|
|
7022
|
+
if (next >= "0" && next <= "7") {
|
|
7023
|
+
let value = 0;
|
|
7024
|
+
let digits = 0;
|
|
7025
|
+
while (digits < 3) {
|
|
7026
|
+
const digit = raw[index + 1 + digits];
|
|
7027
|
+
if (digit === void 0 || digit < "0" || digit > "7") break;
|
|
7028
|
+
value = value * 8 + (digit.charCodeAt(0) - 48);
|
|
7029
|
+
digits += 1;
|
|
7030
|
+
}
|
|
7031
|
+
bytes.push(value & 255);
|
|
7032
|
+
index += digits;
|
|
7033
|
+
continue;
|
|
7034
|
+
}
|
|
7035
|
+
bytes.push(next.charCodeAt(0));
|
|
7036
|
+
index += 1;
|
|
7037
|
+
}
|
|
7038
|
+
return Buffer.from(bytes).toString("utf8");
|
|
7039
|
+
};
|
|
7040
|
+
var realPath = (value) => {
|
|
7041
|
+
try {
|
|
7042
|
+
return realpathSync.native(value);
|
|
7043
|
+
} catch {
|
|
7044
|
+
return value;
|
|
7045
|
+
}
|
|
7046
|
+
};
|
|
7047
|
+
var relativeSeed = (root, top, seed) => {
|
|
7048
|
+
const absolute = path7.isAbsolute(seed) ? seed : path7.resolve(root, seed);
|
|
7049
|
+
for (const base of /* @__PURE__ */ new Set([top, realPath(top)])) {
|
|
7050
|
+
for (const candidate of /* @__PURE__ */ new Set([absolute, realPath(absolute), path7.resolve(realPath(root), seed)])) {
|
|
7051
|
+
const relative = path7.relative(base, candidate);
|
|
7052
|
+
if (!relative || relative === ".." || relative.startsWith(`..${path7.sep}`) || path7.isAbsolute(relative)) {
|
|
7053
|
+
continue;
|
|
7054
|
+
}
|
|
7055
|
+
return toPosix(relative);
|
|
7056
|
+
}
|
|
7057
|
+
}
|
|
7058
|
+
return void 0;
|
|
7059
|
+
};
|
|
7060
|
+
var emptyGraph = (seeds, unavailable) => ({
|
|
7061
|
+
seeds,
|
|
7062
|
+
edges: [],
|
|
7063
|
+
commitsScanned: 0,
|
|
7064
|
+
truncated: false,
|
|
7065
|
+
unavailable
|
|
7066
|
+
});
|
|
7067
|
+
async function coChange(request) {
|
|
7068
|
+
const requestedSeeds = request.seeds.filter((seed) => seed.length > 0);
|
|
7069
|
+
if (requestedSeeds.length === 0) return emptyGraph([], "no seed files were provided");
|
|
7070
|
+
if (!existsSync(request.root)) return emptyGraph(requestedSeeds, "root directory does not exist");
|
|
7071
|
+
const maxCommits = Math.max(1, Math.floor(request.maxCommits) || 1);
|
|
7072
|
+
const limit = Math.max(1, Math.floor(request.limit) || 1);
|
|
7073
|
+
let top;
|
|
7074
|
+
try {
|
|
7075
|
+
const revParse = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
|
|
7076
|
+
cwd: request.root,
|
|
7077
|
+
timeout: GIT_TIMEOUT_MS,
|
|
7078
|
+
encoding: "utf8"
|
|
7079
|
+
});
|
|
7080
|
+
top = revParse.stdout.trim();
|
|
7081
|
+
} catch (error) {
|
|
7082
|
+
const code = error.code;
|
|
7083
|
+
if (code === "ENOENT") return emptyGraph(requestedSeeds, "git is not available");
|
|
7084
|
+
return emptyGraph(requestedSeeds, "not a git repository");
|
|
7085
|
+
}
|
|
7086
|
+
if (!top) return emptyGraph(requestedSeeds, "not a git repository");
|
|
7087
|
+
const seedSet = /* @__PURE__ */ new Set();
|
|
7088
|
+
for (const seed of requestedSeeds) {
|
|
7089
|
+
const normalized = relativeSeed(request.root, top, seed);
|
|
7090
|
+
if (normalized) seedSet.add(normalized);
|
|
7091
|
+
}
|
|
7092
|
+
const seeds = [...seedSet];
|
|
7093
|
+
if (seeds.length === 0) return emptyGraph(requestedSeeds, "seed files are outside the repository");
|
|
7094
|
+
let stdout;
|
|
7095
|
+
try {
|
|
7096
|
+
const log = await execFileAsync(
|
|
7097
|
+
"git",
|
|
7098
|
+
[
|
|
7099
|
+
"log",
|
|
7100
|
+
`--max-count=${maxCommits}`,
|
|
7101
|
+
"--no-merges",
|
|
7102
|
+
"--name-only",
|
|
7103
|
+
`--pretty=format:%H`
|
|
7104
|
+
],
|
|
7105
|
+
{
|
|
7106
|
+
cwd: top,
|
|
7107
|
+
timeout: GIT_TIMEOUT_MS,
|
|
7108
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
7109
|
+
encoding: "utf8"
|
|
7110
|
+
}
|
|
7111
|
+
);
|
|
7112
|
+
stdout = log.stdout;
|
|
7113
|
+
} catch (error) {
|
|
7114
|
+
const code = error.code;
|
|
7115
|
+
if (code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") {
|
|
7116
|
+
return emptyGraph(seeds, "commit history exceeded the read budget");
|
|
7117
|
+
}
|
|
7118
|
+
return emptyGraph(seeds, "no commit history");
|
|
7119
|
+
}
|
|
7120
|
+
const fileCommits = /* @__PURE__ */ new Map();
|
|
7121
|
+
const sharedCommits = /* @__PURE__ */ new Map();
|
|
7122
|
+
const current = [];
|
|
7123
|
+
let commitsScanned = 0;
|
|
7124
|
+
let seedCommits = 0;
|
|
7125
|
+
let inCommit = false;
|
|
7126
|
+
let bulk = false;
|
|
7127
|
+
const settle = () => {
|
|
7128
|
+
if (!inCommit) return;
|
|
7129
|
+
inCommit = false;
|
|
7130
|
+
if (bulk) {
|
|
7131
|
+
bulk = false;
|
|
7132
|
+
current.length = 0;
|
|
7133
|
+
return;
|
|
7134
|
+
}
|
|
7135
|
+
commitsScanned += 1;
|
|
7136
|
+
let touchesSeed = false;
|
|
7137
|
+
for (const file of current) {
|
|
7138
|
+
if (seedSet.has(file)) {
|
|
7139
|
+
touchesSeed = true;
|
|
7140
|
+
break;
|
|
7141
|
+
}
|
|
7142
|
+
}
|
|
7143
|
+
if (touchesSeed) seedCommits += 1;
|
|
7144
|
+
for (const file of current) {
|
|
7145
|
+
fileCommits.set(file, (fileCommits.get(file) ?? 0) + 1);
|
|
7146
|
+
if (touchesSeed && !seedSet.has(file)) {
|
|
7147
|
+
sharedCommits.set(file, (sharedCommits.get(file) ?? 0) + 1);
|
|
7148
|
+
}
|
|
7149
|
+
}
|
|
7150
|
+
current.length = 0;
|
|
7151
|
+
};
|
|
7152
|
+
let cursor = 0;
|
|
7153
|
+
while (cursor <= stdout.length) {
|
|
7154
|
+
let end = stdout.indexOf("\n", cursor);
|
|
7155
|
+
if (end < 0) end = stdout.length;
|
|
7156
|
+
const line = stdout.slice(cursor, end);
|
|
7157
|
+
cursor = end + 1;
|
|
7158
|
+
if (line.length === 0) continue;
|
|
7159
|
+
if (line.charCodeAt(0) === COMMIT_MARKER_CODE) {
|
|
7160
|
+
settle();
|
|
7161
|
+
inCommit = true;
|
|
7162
|
+
continue;
|
|
7163
|
+
}
|
|
7164
|
+
if (!inCommit || bulk) continue;
|
|
7165
|
+
if (current.length >= BULK_COMMIT_FILE_CEILING) {
|
|
7166
|
+
bulk = true;
|
|
7167
|
+
current.length = 0;
|
|
7168
|
+
continue;
|
|
7169
|
+
}
|
|
7170
|
+
current.push(line.charCodeAt(0) === QUOTE_CODE ? unquoteGitPath(line) : line);
|
|
7171
|
+
}
|
|
7172
|
+
settle();
|
|
7173
|
+
if (commitsScanned === 0) return emptyGraph(seeds, "no commit history");
|
|
7174
|
+
const edges = [];
|
|
7175
|
+
if (seedCommits > 0) {
|
|
7176
|
+
const seedRoot = Math.sqrt(seedCommits);
|
|
7177
|
+
for (const [file, shared] of sharedCommits) {
|
|
7178
|
+
const total = fileCommits.get(file) ?? shared;
|
|
7179
|
+
edges.push({ file, score: shared / (seedRoot * Math.sqrt(total)), commits: shared });
|
|
7180
|
+
}
|
|
7181
|
+
}
|
|
7182
|
+
edges.sort((left, right) => {
|
|
7183
|
+
if (right.score !== left.score) return right.score - left.score;
|
|
7184
|
+
if (right.commits !== left.commits) return right.commits - left.commits;
|
|
7185
|
+
return left.file < right.file ? -1 : left.file > right.file ? 1 : 0;
|
|
7186
|
+
});
|
|
7187
|
+
const truncated = edges.length > limit;
|
|
7188
|
+
if (truncated) edges.length = limit;
|
|
7189
|
+
if (seedCommits === 0) {
|
|
7190
|
+
return { seeds, edges, commitsScanned, truncated, unavailable: "seed files do not appear in the scanned history" };
|
|
7191
|
+
}
|
|
7192
|
+
return { seeds, edges, commitsScanned, truncated };
|
|
7193
|
+
}
|
|
7194
|
+
|
|
7195
|
+
// src/codemap/symbols.ts
|
|
7196
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
7197
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
7198
|
+
import { createRequire } from "node:module";
|
|
7199
|
+
import path8 from "node:path";
|
|
7200
|
+
import { promisify as promisify2 } from "node:util";
|
|
7201
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
7202
|
+
var commonDirectory = (files) => {
|
|
7203
|
+
let prefix;
|
|
7204
|
+
for (const file of files) {
|
|
7205
|
+
const parts = file.split("/");
|
|
7206
|
+
parts.pop();
|
|
7207
|
+
if (prefix === void 0) {
|
|
7208
|
+
prefix = parts;
|
|
7209
|
+
continue;
|
|
7210
|
+
}
|
|
7211
|
+
let shared = 0;
|
|
7212
|
+
while (shared < prefix.length && shared < parts.length && prefix[shared] === parts[shared]) shared++;
|
|
7213
|
+
prefix.length = shared;
|
|
7214
|
+
if (shared === 0) return "";
|
|
7215
|
+
}
|
|
7216
|
+
return prefix === void 0 ? "" : prefix.join("/");
|
|
7217
|
+
};
|
|
7218
|
+
var importBundledNatives = async () => {
|
|
7219
|
+
try {
|
|
7220
|
+
const bundled = await import("@oh-my-pi/pi-natives");
|
|
7221
|
+
return typeof bundled.astGrep === "function" ? bundled : void 0;
|
|
7222
|
+
} catch {
|
|
7223
|
+
return void 0;
|
|
7224
|
+
}
|
|
7225
|
+
};
|
|
7226
|
+
var importPlatformNatives = () => {
|
|
7227
|
+
const load = createRequire(import.meta.url);
|
|
7228
|
+
return load(`@oh-my-pi/pi-natives-${process.platform}-${process.arch}`);
|
|
7229
|
+
};
|
|
7230
|
+
var nativesOnce;
|
|
7231
|
+
var codeNatives = () => {
|
|
7232
|
+
nativesOnce ??= importBundledNatives().then((bundled) => bundled ?? importPlatformNatives());
|
|
7233
|
+
return nativesOnce;
|
|
7234
|
+
};
|
|
7235
|
+
var SCRIPT_DECLARATION = /^(?:export\s+)?(?:default\s+)?(?:declare\s+)?(?:abstract\s+)?(?:async\s+)?(function|class|interface|type|enum|const|let|var)\b/;
|
|
7236
|
+
var ARROW_VALUE = /^(?:async\s*)?[(<]/;
|
|
7237
|
+
var classifyScript = (text, meta) => {
|
|
7238
|
+
const exported = text.startsWith("export");
|
|
7239
|
+
const declaration = SCRIPT_DECLARATION.exec(text);
|
|
7240
|
+
switch (declaration?.[1]) {
|
|
7241
|
+
case "function":
|
|
7242
|
+
return { kind: "fn", exported };
|
|
7243
|
+
case "class":
|
|
7244
|
+
return { kind: "class", exported };
|
|
7245
|
+
case "interface":
|
|
7246
|
+
return { kind: "iface", exported };
|
|
7247
|
+
case "type":
|
|
7248
|
+
return { kind: "type", exported };
|
|
7249
|
+
case "enum":
|
|
7250
|
+
return { kind: "enum", exported };
|
|
7251
|
+
default: {
|
|
7252
|
+
const value = meta?.V;
|
|
7253
|
+
if (value === void 0) return { kind: "fn", exported };
|
|
7254
|
+
const arrow = ARROW_VALUE.test(value) && value.includes("=>");
|
|
7255
|
+
return { kind: arrow ? "fn" : "const", exported };
|
|
7256
|
+
}
|
|
7257
|
+
}
|
|
7258
|
+
};
|
|
7259
|
+
var SCRIPT_VALUE_PATTERNS = [
|
|
7260
|
+
"function $NAME($$$A) { $$$B }",
|
|
7261
|
+
"export function $NAME($$$A) { $$$B }",
|
|
7262
|
+
"export default function $NAME($$$A) { $$$B }",
|
|
7263
|
+
"class $NAME { $$$B }",
|
|
7264
|
+
"export class $NAME { $$$B }",
|
|
7265
|
+
"export default class $NAME { $$$B }",
|
|
7266
|
+
"const $NAME = ($$$A) => $B",
|
|
7267
|
+
"const $NAME = $V",
|
|
7268
|
+
"export const $NAME = $V"
|
|
7269
|
+
];
|
|
7270
|
+
var TYPED_SCRIPT_PATTERNS = [
|
|
7271
|
+
...SCRIPT_VALUE_PATTERNS,
|
|
7272
|
+
"interface $NAME { $$$B }",
|
|
7273
|
+
"export interface $NAME { $$$B }",
|
|
7274
|
+
"type $NAME = $V",
|
|
7275
|
+
"export type $NAME = $V",
|
|
7276
|
+
"enum $NAME { $$$B }",
|
|
7277
|
+
"export enum $NAME { $$$B }"
|
|
7278
|
+
];
|
|
7279
|
+
var PYTHON_DEFINITION = /^(?:async\s+)?def\b/;
|
|
7280
|
+
var PYTHON_CLASS = /^class\b/;
|
|
7281
|
+
var classifyPython = (text) => {
|
|
7282
|
+
if (PYTHON_DEFINITION.test(text)) return { kind: "fn", exported: true };
|
|
7283
|
+
if (PYTHON_CLASS.test(text)) return { kind: "class", exported: true };
|
|
7284
|
+
return { kind: "const", exported: true };
|
|
7285
|
+
};
|
|
7286
|
+
var GO_METHOD = /^func\s*\(/;
|
|
7287
|
+
var GO_FUNCTION = /^func\b/;
|
|
7288
|
+
var GO_STRUCT = /^type\s+\w+\s+struct\b/;
|
|
7289
|
+
var GO_INTERFACE = /^type\s+\w+\s+interface\b/;
|
|
7290
|
+
var GO_TYPE = /^type\b/;
|
|
7291
|
+
var classifyGo = (text) => {
|
|
7292
|
+
if (GO_METHOD.test(text)) return { kind: "method", exported: true };
|
|
7293
|
+
if (GO_FUNCTION.test(text)) return { kind: "fn", exported: true };
|
|
7294
|
+
if (GO_STRUCT.test(text)) return { kind: "class", exported: true };
|
|
7295
|
+
if (GO_INTERFACE.test(text)) return { kind: "iface", exported: true };
|
|
7296
|
+
if (GO_TYPE.test(text)) return { kind: "type", exported: true };
|
|
7297
|
+
return { kind: "const", exported: true };
|
|
7298
|
+
};
|
|
7299
|
+
var RUST_KEYWORD = /^(?:pub(?:\([^)]*\))?\s+)?(fn|struct|enum|trait|type|const|static)\b/;
|
|
7300
|
+
var classifyRust = (text) => {
|
|
7301
|
+
const exported = text.startsWith("pub");
|
|
7302
|
+
switch (RUST_KEYWORD.exec(text)?.[1]) {
|
|
7303
|
+
case "fn":
|
|
7304
|
+
return { kind: "fn", exported };
|
|
7305
|
+
case "struct":
|
|
7306
|
+
return { kind: "class", exported };
|
|
7307
|
+
case "enum":
|
|
7308
|
+
return { kind: "enum", exported };
|
|
7309
|
+
case "trait":
|
|
7310
|
+
return { kind: "iface", exported };
|
|
7311
|
+
case "type":
|
|
7312
|
+
return { kind: "type", exported };
|
|
7313
|
+
default:
|
|
7314
|
+
return { kind: "const", exported };
|
|
7315
|
+
}
|
|
7316
|
+
};
|
|
7317
|
+
var JAVA_KEYWORD = /^(?:(?:public|private|protected|static|final|abstract|synchronized|native|strictfp)\s+)*(class|interface|enum|record)\b/;
|
|
7318
|
+
var classifyJava = (text) => {
|
|
7319
|
+
const exported = text.startsWith("public");
|
|
7320
|
+
switch (JAVA_KEYWORD.exec(text)?.[1]) {
|
|
7321
|
+
case "class":
|
|
7322
|
+
case "record":
|
|
7323
|
+
return { kind: "class", exported };
|
|
7324
|
+
case "interface":
|
|
7325
|
+
return { kind: "iface", exported };
|
|
7326
|
+
case "enum":
|
|
7327
|
+
return { kind: "enum", exported };
|
|
7328
|
+
default:
|
|
7329
|
+
return { kind: "method", exported };
|
|
7330
|
+
}
|
|
7331
|
+
};
|
|
7332
|
+
var globFor = (extensions) => extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(",")}}`;
|
|
7333
|
+
var defineSpec = (id, lang, extensions, patterns, classify) => ({ id, lang, extensions, glob: globFor(extensions), patterns, classify });
|
|
7334
|
+
var LANGUAGE_SPECS = [
|
|
7335
|
+
defineSpec("ts", "ts", ["ts", "mts", "cts"], TYPED_SCRIPT_PATTERNS, classifyScript),
|
|
7336
|
+
defineSpec("tsx", "tsx", ["tsx"], TYPED_SCRIPT_PATTERNS, classifyScript),
|
|
7337
|
+
defineSpec("js", "js", ["js", "mjs", "cjs", "jsx"], SCRIPT_VALUE_PATTERNS, classifyScript),
|
|
7338
|
+
defineSpec(
|
|
7339
|
+
"python",
|
|
7340
|
+
"python",
|
|
7341
|
+
["py", "pyi"],
|
|
7342
|
+
[
|
|
7343
|
+
"def $NAME($$$A): $$$B",
|
|
7344
|
+
"class $NAME($$$A): $$$B",
|
|
7345
|
+
"class $NAME: $$$B",
|
|
7346
|
+
"$NAME = $V"
|
|
7347
|
+
],
|
|
7348
|
+
classifyPython
|
|
7349
|
+
),
|
|
7350
|
+
defineSpec(
|
|
7351
|
+
"go",
|
|
7352
|
+
"go",
|
|
7353
|
+
["go"],
|
|
7354
|
+
[
|
|
7355
|
+
"func $NAME($$$A) $$$R { $$$B }",
|
|
7356
|
+
"func ($$$RECV) $NAME($$$A) $$$R { $$$B }",
|
|
7357
|
+
"type $NAME struct { $$$B }",
|
|
7358
|
+
"type $NAME interface { $$$B }",
|
|
7359
|
+
"type $NAME = $V",
|
|
7360
|
+
"const $NAME = $V",
|
|
7361
|
+
"var $NAME = $V"
|
|
7362
|
+
],
|
|
7363
|
+
classifyGo
|
|
7364
|
+
),
|
|
7365
|
+
defineSpec(
|
|
7366
|
+
"rust",
|
|
7367
|
+
"rust",
|
|
7368
|
+
["rs"],
|
|
7369
|
+
[
|
|
7370
|
+
"fn $NAME($$$A) { $$$B }",
|
|
7371
|
+
"fn $NAME($$$A) -> $R { $$$B }",
|
|
7372
|
+
"pub fn $NAME($$$A) { $$$B }",
|
|
7373
|
+
"pub fn $NAME($$$A) -> $R { $$$B }",
|
|
7374
|
+
"struct $NAME { $$$B }",
|
|
7375
|
+
"pub struct $NAME { $$$B }",
|
|
7376
|
+
"enum $NAME { $$$B }",
|
|
7377
|
+
"pub enum $NAME { $$$B }",
|
|
7378
|
+
"trait $NAME { $$$B }",
|
|
7379
|
+
"pub trait $NAME { $$$B }",
|
|
7380
|
+
"type $NAME = $V;",
|
|
7381
|
+
"pub type $NAME = $V;",
|
|
7382
|
+
"const $NAME: $T = $V;",
|
|
7383
|
+
"pub const $NAME: $T = $V;",
|
|
7384
|
+
"static $NAME: $T = $V;",
|
|
7385
|
+
"pub static $NAME: $T = $V;"
|
|
7386
|
+
],
|
|
7387
|
+
classifyRust
|
|
7388
|
+
),
|
|
7389
|
+
defineSpec(
|
|
7390
|
+
"java",
|
|
7391
|
+
"java",
|
|
7392
|
+
["java"],
|
|
7393
|
+
[
|
|
7394
|
+
"class $NAME { $$$B }",
|
|
7395
|
+
"public class $NAME { $$$B }",
|
|
7396
|
+
"interface $NAME { $$$B }",
|
|
7397
|
+
"public interface $NAME { $$$B }",
|
|
7398
|
+
"enum $NAME { $$$B }",
|
|
7399
|
+
"public enum $NAME { $$$B }",
|
|
7400
|
+
"$RET $NAME($$$A) { $$$B }",
|
|
7401
|
+
"public $RET $NAME($$$A) { $$$B }",
|
|
7402
|
+
"private $RET $NAME($$$A) { $$$B }",
|
|
7403
|
+
"protected $RET $NAME($$$A) { $$$B }",
|
|
7404
|
+
"public static $RET $NAME($$$A) { $$$B }",
|
|
7405
|
+
"static $RET $NAME($$$A) { $$$B }"
|
|
7406
|
+
],
|
|
7407
|
+
classifyJava
|
|
7408
|
+
)
|
|
7409
|
+
];
|
|
7410
|
+
var EXTENSION_SPECS = /* @__PURE__ */ new Map();
|
|
7411
|
+
for (const spec of LANGUAGE_SPECS) {
|
|
7412
|
+
for (const extension of spec.extensions) EXTENSION_SPECS.set(extension, spec);
|
|
7413
|
+
}
|
|
7414
|
+
var FALLBACK_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
7415
|
+
"c",
|
|
7416
|
+
"cc",
|
|
7417
|
+
"cpp",
|
|
7418
|
+
"cs",
|
|
7419
|
+
"cxx",
|
|
7420
|
+
"dart",
|
|
7421
|
+
"elm",
|
|
7422
|
+
"erl",
|
|
7423
|
+
"ex",
|
|
7424
|
+
"exs",
|
|
7425
|
+
"groovy",
|
|
7426
|
+
"h",
|
|
7427
|
+
"hh",
|
|
7428
|
+
"hpp",
|
|
7429
|
+
"hs",
|
|
7430
|
+
"jl",
|
|
7431
|
+
"kt",
|
|
7432
|
+
"kts",
|
|
7433
|
+
"lua",
|
|
7434
|
+
"nim",
|
|
7435
|
+
"php",
|
|
7436
|
+
"pl",
|
|
7437
|
+
"pm",
|
|
7438
|
+
"proto",
|
|
7439
|
+
"rb",
|
|
7440
|
+
"scala",
|
|
7441
|
+
"sh",
|
|
7442
|
+
"sql",
|
|
7443
|
+
"svelte",
|
|
7444
|
+
"swift",
|
|
7445
|
+
"vue",
|
|
7446
|
+
"zig"
|
|
7447
|
+
]);
|
|
7448
|
+
var SKIP_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist"]);
|
|
7449
|
+
var IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
7450
|
+
var KIND_RANK = {
|
|
7451
|
+
method: 5,
|
|
7452
|
+
fn: 4,
|
|
7453
|
+
class: 3,
|
|
7454
|
+
iface: 3,
|
|
7455
|
+
enum: 3,
|
|
7456
|
+
type: 2,
|
|
7457
|
+
const: 1
|
|
7458
|
+
};
|
|
7459
|
+
var MATCH_TIMEOUT_MS = 12e4;
|
|
7460
|
+
var MAX_FALLBACK_BYTES = 2e6;
|
|
7461
|
+
var extensionOf = (file) => {
|
|
7462
|
+
const slash = file.lastIndexOf("/");
|
|
7463
|
+
const dot = file.lastIndexOf(".");
|
|
7464
|
+
if (dot <= slash + 1) return void 0;
|
|
7465
|
+
return file.slice(dot + 1).toLowerCase();
|
|
7466
|
+
};
|
|
7467
|
+
var indexableExtension = (file) => {
|
|
7468
|
+
const extension = extensionOf(file);
|
|
7469
|
+
if (extension === void 0) return void 0;
|
|
7470
|
+
if (EXTENSION_SPECS.has(extension) || FALLBACK_EXTENSIONS.has(extension)) return extension;
|
|
7471
|
+
return void 0;
|
|
7472
|
+
};
|
|
7473
|
+
var GLOB_ESCAPE = /[.+^$()|[\]\\]/g;
|
|
7474
|
+
var globToRegExp = (pattern) => {
|
|
7475
|
+
let source = "";
|
|
7476
|
+
let braces = 0;
|
|
7477
|
+
for (let i = 0; i < pattern.length; i += 1) {
|
|
7478
|
+
const character = pattern[i];
|
|
7479
|
+
if (character === "*") {
|
|
7480
|
+
if (pattern[i + 1] === "*") {
|
|
7481
|
+
i += 1;
|
|
7482
|
+
if (pattern[i + 1] === "/") {
|
|
7483
|
+
i += 1;
|
|
7484
|
+
source += "(?:[^/]*/)*";
|
|
7485
|
+
} else {
|
|
7486
|
+
source += ".*";
|
|
7487
|
+
}
|
|
7488
|
+
continue;
|
|
7489
|
+
}
|
|
7490
|
+
source += "[^/]*";
|
|
7491
|
+
continue;
|
|
7492
|
+
}
|
|
7493
|
+
if (character === "?") {
|
|
7494
|
+
source += "[^/]";
|
|
7495
|
+
continue;
|
|
7496
|
+
}
|
|
7497
|
+
if (character === "{") {
|
|
7498
|
+
braces += 1;
|
|
7499
|
+
source += "(?:";
|
|
7500
|
+
continue;
|
|
7501
|
+
}
|
|
7502
|
+
if (character === "}" && braces > 0) {
|
|
7503
|
+
braces -= 1;
|
|
7504
|
+
source += ")";
|
|
7505
|
+
continue;
|
|
7506
|
+
}
|
|
7507
|
+
if (character === "," && braces > 0) {
|
|
7508
|
+
source += "|";
|
|
7509
|
+
continue;
|
|
7510
|
+
}
|
|
7511
|
+
source += character?.replace(GLOB_ESCAPE, "\\$&") ?? "";
|
|
7512
|
+
}
|
|
7513
|
+
return new RegExp(`^${source}$`);
|
|
7514
|
+
};
|
|
7515
|
+
var GIT_LIST_TIMEOUT_MS = 2e4;
|
|
7516
|
+
var GIT_LIST_MAX_BUFFER = 64 * 1024 * 1024;
|
|
7517
|
+
var gitTrackedFiles = async (root, matcher, signal) => {
|
|
7518
|
+
let stdout;
|
|
7519
|
+
try {
|
|
7520
|
+
const result = await execFileAsync2(
|
|
7521
|
+
"git",
|
|
7522
|
+
["-C", root, "ls-files", "--cached", "--others", "--exclude-standard", "-z"],
|
|
7523
|
+
{
|
|
7524
|
+
maxBuffer: GIT_LIST_MAX_BUFFER,
|
|
7525
|
+
timeout: GIT_LIST_TIMEOUT_MS,
|
|
7526
|
+
...signal ? { signal } : {}
|
|
7527
|
+
}
|
|
7528
|
+
);
|
|
7529
|
+
stdout = result.stdout;
|
|
7530
|
+
} catch {
|
|
7531
|
+
return void 0;
|
|
7532
|
+
}
|
|
7533
|
+
const found = [];
|
|
7534
|
+
let cursor = 0;
|
|
7535
|
+
while (cursor < stdout.length) {
|
|
7536
|
+
let end = stdout.indexOf("\0", cursor);
|
|
7537
|
+
if (end === -1) end = stdout.length;
|
|
7538
|
+
const relative = stdout.slice(cursor, end);
|
|
7539
|
+
cursor = end + 1;
|
|
7540
|
+
if (relative.length === 0) continue;
|
|
7541
|
+
if (relative.charCodeAt(0) === 46) continue;
|
|
7542
|
+
if (indexableExtension(relative) === void 0) continue;
|
|
7543
|
+
if (matcher !== void 0 && !matcher.test(relative)) continue;
|
|
7544
|
+
let skipped2 = false;
|
|
7545
|
+
let segmentStart = 0;
|
|
7546
|
+
while (segmentStart < relative.length) {
|
|
7547
|
+
let segmentEnd = relative.indexOf("/", segmentStart);
|
|
7548
|
+
if (segmentEnd === -1) break;
|
|
7549
|
+
const segment = relative.slice(segmentStart, segmentEnd);
|
|
7550
|
+
if (segment.charCodeAt(0) === 46 || SKIP_DIRECTORIES.has(segment)) {
|
|
7551
|
+
skipped2 = true;
|
|
7552
|
+
break;
|
|
7553
|
+
}
|
|
7554
|
+
segmentStart = segmentEnd + 1;
|
|
7555
|
+
}
|
|
7556
|
+
if (!skipped2) found.push(relative);
|
|
7557
|
+
}
|
|
7558
|
+
return found;
|
|
7559
|
+
};
|
|
7560
|
+
var walkFiles = async (root, matcher, signal) => {
|
|
7561
|
+
const found = [];
|
|
7562
|
+
const pending = [""];
|
|
7563
|
+
while (pending.length > 0) {
|
|
7564
|
+
const directory = pending.pop() ?? "";
|
|
7565
|
+
throwIfAborted(signal);
|
|
7566
|
+
let entries;
|
|
7567
|
+
try {
|
|
7568
|
+
entries = await readdir(directory === "" ? root : path8.join(root, directory), {
|
|
7569
|
+
withFileTypes: true
|
|
7570
|
+
});
|
|
7571
|
+
} catch {
|
|
7572
|
+
continue;
|
|
7573
|
+
}
|
|
7574
|
+
for (const entry of entries) {
|
|
7575
|
+
const name = entry.name;
|
|
7576
|
+
if (name.charCodeAt(0) === 46) continue;
|
|
7577
|
+
const relative = directory === "" ? name : `${directory}/${name}`;
|
|
7578
|
+
if (entry.isDirectory()) {
|
|
7579
|
+
if (!SKIP_DIRECTORIES.has(name)) pending.push(relative);
|
|
7580
|
+
continue;
|
|
7581
|
+
}
|
|
7582
|
+
if (!entry.isFile()) continue;
|
|
7583
|
+
if (indexableExtension(relative) === void 0) continue;
|
|
7584
|
+
if (matcher !== void 0 && !matcher.test(relative)) continue;
|
|
7585
|
+
found.push(relative);
|
|
7586
|
+
}
|
|
7587
|
+
}
|
|
7588
|
+
return found;
|
|
7589
|
+
};
|
|
7590
|
+
var discoverFiles = async (root, matcher, signal) => await gitTrackedFiles(root, matcher, signal) ?? await walkFiles(root, matcher, signal);
|
|
7591
|
+
var COMMENT_HEAD = /^(?:\/\/|\/\*|\*|#|--|<!--|;|%)/;
|
|
7592
|
+
var IMPORT_HEAD = /^(?:import|from|require|include|use|using|package|open|load|source)\b/;
|
|
7593
|
+
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/;
|
|
7594
|
+
var ASSIGNMENT_HEAD = /^[A-Za-z_$][\w$]*\s*(?::[^=]*)?=[^=]/;
|
|
7595
|
+
var EXPORTED_HEAD = /^(?:export|pub|public)\b/;
|
|
7596
|
+
var IDENTIFIERS = /[A-Za-z_$][\w$]*/g;
|
|
7597
|
+
var FALLBACK_KINDS = /* @__PURE__ */ new Map([
|
|
7598
|
+
["class", "class"],
|
|
7599
|
+
["module", "class"],
|
|
7600
|
+
["namespace", "class"],
|
|
7601
|
+
["record", "class"],
|
|
7602
|
+
["object", "class"],
|
|
7603
|
+
["struct", "class"],
|
|
7604
|
+
["impl", "class"],
|
|
7605
|
+
["actor", "class"],
|
|
7606
|
+
["defmodule", "class"],
|
|
7607
|
+
["defstruct", "class"],
|
|
7608
|
+
["interface", "iface"],
|
|
7609
|
+
["trait", "iface"],
|
|
7610
|
+
["protocol", "iface"],
|
|
7611
|
+
["enum", "enum"],
|
|
7612
|
+
["union", "enum"],
|
|
7613
|
+
["def", "fn"],
|
|
7614
|
+
["defp", "fn"],
|
|
7615
|
+
["defmacro", "fn"],
|
|
7616
|
+
["fn", "fn"],
|
|
7617
|
+
["func", "fn"],
|
|
7618
|
+
["function", "fn"],
|
|
7619
|
+
["sub", "fn"],
|
|
7620
|
+
["procedure", "fn"],
|
|
7621
|
+
["method", "method"],
|
|
7622
|
+
["constructor", "method"],
|
|
7623
|
+
["init", "method"],
|
|
7624
|
+
["type", "type"],
|
|
7625
|
+
["typedef", "type"],
|
|
7626
|
+
["typealias", "type"]
|
|
7627
|
+
]);
|
|
7628
|
+
var FALLBACK_SKIP = /* @__PURE__ */ new Set([
|
|
7629
|
+
...FALLBACK_KINDS.keys(),
|
|
7630
|
+
"export",
|
|
7631
|
+
"pub",
|
|
7632
|
+
"public",
|
|
7633
|
+
"private",
|
|
7634
|
+
"protected",
|
|
7635
|
+
"internal",
|
|
7636
|
+
"static",
|
|
7637
|
+
"final",
|
|
7638
|
+
"abstract",
|
|
7639
|
+
"override",
|
|
7640
|
+
"virtual",
|
|
7641
|
+
"inline",
|
|
7642
|
+
"async",
|
|
7643
|
+
"unsafe",
|
|
7644
|
+
"extern",
|
|
7645
|
+
"shared",
|
|
7646
|
+
"readonly",
|
|
7647
|
+
"declare",
|
|
7648
|
+
"local",
|
|
7649
|
+
"extension",
|
|
7650
|
+
"template",
|
|
7651
|
+
"operator",
|
|
7652
|
+
"property",
|
|
7653
|
+
"event",
|
|
7654
|
+
"signal",
|
|
7655
|
+
"macro",
|
|
7656
|
+
"task",
|
|
7657
|
+
"const",
|
|
7658
|
+
"let",
|
|
7659
|
+
"var",
|
|
7660
|
+
"val",
|
|
7661
|
+
"auto",
|
|
7662
|
+
"new",
|
|
7663
|
+
"return",
|
|
7664
|
+
"self",
|
|
7665
|
+
"this",
|
|
7666
|
+
"void",
|
|
7667
|
+
"int",
|
|
7668
|
+
"long",
|
|
7669
|
+
"short",
|
|
7670
|
+
"byte",
|
|
7671
|
+
"char",
|
|
7672
|
+
"bool",
|
|
7673
|
+
"boolean",
|
|
7674
|
+
"float",
|
|
7675
|
+
"double",
|
|
7676
|
+
"string",
|
|
7677
|
+
"str",
|
|
7678
|
+
"unsigned",
|
|
7679
|
+
"signed",
|
|
7680
|
+
"size_t",
|
|
7681
|
+
"mut",
|
|
7682
|
+
"end",
|
|
7683
|
+
"do",
|
|
7684
|
+
"then",
|
|
7685
|
+
"begin",
|
|
7686
|
+
"where",
|
|
7687
|
+
"with",
|
|
7688
|
+
"as",
|
|
7689
|
+
"in",
|
|
7690
|
+
"of",
|
|
7691
|
+
"is",
|
|
7692
|
+
"not",
|
|
7693
|
+
"and",
|
|
7694
|
+
"or",
|
|
7695
|
+
"if",
|
|
7696
|
+
"else",
|
|
7697
|
+
"for",
|
|
7698
|
+
"while",
|
|
7699
|
+
"switch",
|
|
7700
|
+
"match",
|
|
7701
|
+
"try",
|
|
7702
|
+
"catch",
|
|
7703
|
+
"throw",
|
|
7704
|
+
"throws",
|
|
7705
|
+
"extends",
|
|
7706
|
+
"implements"
|
|
7707
|
+
]);
|
|
7708
|
+
var fallbackSymbol = (file, line, lineNumber) => {
|
|
7709
|
+
const trimmed = line.trim();
|
|
7710
|
+
if (trimmed.length === 0) return void 0;
|
|
7711
|
+
if (COMMENT_HEAD.test(trimmed) || IMPORT_HEAD.test(trimmed)) return void 0;
|
|
7712
|
+
if (!DECLARATION_HEAD.test(trimmed) && !ASSIGNMENT_HEAD.test(trimmed)) return void 0;
|
|
7713
|
+
IDENTIFIERS.lastIndex = 0;
|
|
7714
|
+
let kind = "const";
|
|
7715
|
+
let name;
|
|
7716
|
+
for (let token = IDENTIFIERS.exec(trimmed); token !== null; token = IDENTIFIERS.exec(trimmed)) {
|
|
7717
|
+
const word = token[0];
|
|
7718
|
+
if (!FALLBACK_SKIP.has(word)) {
|
|
7719
|
+
name = word;
|
|
7720
|
+
break;
|
|
7721
|
+
}
|
|
7722
|
+
const mapped = FALLBACK_KINDS.get(word);
|
|
7723
|
+
if (mapped !== void 0 && kind === "const") kind = mapped;
|
|
7724
|
+
}
|
|
7725
|
+
if (name === void 0 || !IDENTIFIER.test(name)) return void 0;
|
|
7726
|
+
const exported = EXPORTED_HEAD.test(trimmed) || name.charCodeAt(0) !== 95;
|
|
7727
|
+
return { file, line: lineNumber, kind, name, exported };
|
|
7728
|
+
};
|
|
7729
|
+
var countLines = (code) => {
|
|
7730
|
+
let lines = 1;
|
|
7731
|
+
for (let at = code.indexOf("\n"); at >= 0; at = code.indexOf("\n", at + 1)) lines += 1;
|
|
7732
|
+
return lines;
|
|
7733
|
+
};
|
|
7734
|
+
var record = (into, symbol) => {
|
|
7735
|
+
const key = `${symbol.file}\0${symbol.line}\0${symbol.name}`;
|
|
7736
|
+
const existing = into.get(key);
|
|
7737
|
+
if (existing === void 0) {
|
|
7738
|
+
into.set(key, symbol);
|
|
7739
|
+
return;
|
|
7740
|
+
}
|
|
7741
|
+
if (symbol.exported) existing.exported = true;
|
|
7742
|
+
if (KIND_RANK[symbol.kind] > KIND_RANK[existing.kind]) existing.kind = symbol.kind;
|
|
7743
|
+
};
|
|
7744
|
+
var toPosix2 = (value) => path8.sep === "/" ? value : value.split(path8.sep).join("/");
|
|
7745
|
+
var compareSymbols = (left, right) => {
|
|
7746
|
+
if (left.file !== right.file) return left.file < right.file ? -1 : 1;
|
|
7747
|
+
if (left.line !== right.line) return left.line - right.line;
|
|
7748
|
+
return left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
|
|
7749
|
+
};
|
|
7750
|
+
async function buildSymbolIndex(request) {
|
|
7751
|
+
const startedAt = Date.now();
|
|
7752
|
+
const signal = request.signal;
|
|
7753
|
+
throwIfAborted(signal);
|
|
7754
|
+
const root = path8.resolve(request.root);
|
|
7755
|
+
const matcher = request.glob === void 0 ? void 0 : globToRegExp(request.glob);
|
|
7756
|
+
const discovered = await discoverFiles(root, matcher, signal);
|
|
7757
|
+
discovered.sort();
|
|
7758
|
+
let truncated = false;
|
|
7759
|
+
let files = discovered;
|
|
7760
|
+
if (files.length > request.maxFiles) {
|
|
7761
|
+
files = discovered.slice(0, request.maxFiles);
|
|
7762
|
+
truncated = true;
|
|
7763
|
+
}
|
|
7764
|
+
const languages = {};
|
|
7765
|
+
const assigned = /* @__PURE__ */ new Map();
|
|
7766
|
+
const activeSpecs = /* @__PURE__ */ new Set();
|
|
7767
|
+
const fallbackFiles = [];
|
|
7768
|
+
for (const file of files) {
|
|
7769
|
+
const extension = indexableExtension(file);
|
|
7770
|
+
if (extension === void 0) continue;
|
|
7771
|
+
const spec = EXTENSION_SPECS.get(extension);
|
|
7772
|
+
const label = spec?.id ?? extension;
|
|
7773
|
+
languages[label] = (languages[label] ?? 0) + 1;
|
|
7774
|
+
if (spec === void 0) {
|
|
7775
|
+
fallbackFiles.push(file);
|
|
7776
|
+
continue;
|
|
7777
|
+
}
|
|
7778
|
+
assigned.set(file, spec.id);
|
|
7779
|
+
activeSpecs.add(spec.id);
|
|
7780
|
+
}
|
|
7781
|
+
const natives = await codeNatives();
|
|
7782
|
+
const collected = /* @__PURE__ */ new Map();
|
|
7783
|
+
const matchLimit = Math.max(4096, request.maxSymbols * 2);
|
|
7784
|
+
for (const spec of LANGUAGE_SPECS) {
|
|
7785
|
+
if (!activeSpecs.has(spec.id)) continue;
|
|
7786
|
+
throwIfAborted(signal);
|
|
7787
|
+
const scoped = [];
|
|
7788
|
+
for (const [file, id] of assigned) if (id === spec.id) scoped.push(file);
|
|
7789
|
+
const prefix = commonDirectory(scoped);
|
|
7790
|
+
const result = await natives.astGrep({
|
|
7791
|
+
patterns: spec.patterns,
|
|
7792
|
+
lang: spec.lang,
|
|
7793
|
+
path: prefix === "" ? root : path8.join(root, prefix),
|
|
7794
|
+
glob: spec.glob,
|
|
7795
|
+
includeMeta: true,
|
|
7796
|
+
limit: matchLimit,
|
|
7797
|
+
timeoutMs: MATCH_TIMEOUT_MS,
|
|
7798
|
+
...signal ? { signal } : {}
|
|
7799
|
+
});
|
|
7800
|
+
if (result.limitReached) truncated = true;
|
|
7801
|
+
for (const match of result.matches) {
|
|
7802
|
+
const relative = toPosix2(match.path);
|
|
7803
|
+
const file = prefix === "" ? relative : `${prefix}/${relative}`;
|
|
7804
|
+
if (assigned.get(file) !== spec.id) continue;
|
|
7805
|
+
const name = match.metaVariables?.NAME;
|
|
7806
|
+
if (name === void 0 || !IDENTIFIER.test(name)) continue;
|
|
7807
|
+
const classification = spec.classify(match.text, match.metaVariables);
|
|
7808
|
+
record(collected, {
|
|
7809
|
+
file,
|
|
7810
|
+
line: match.startLine,
|
|
7811
|
+
kind: classification.kind,
|
|
7812
|
+
name,
|
|
7813
|
+
exported: classification.exported
|
|
7814
|
+
});
|
|
7815
|
+
}
|
|
7816
|
+
}
|
|
7817
|
+
for (const file of fallbackFiles) {
|
|
7818
|
+
throwIfAborted(signal);
|
|
7819
|
+
let code;
|
|
7820
|
+
try {
|
|
7821
|
+
code = await readFile(path8.join(root, file), "utf8");
|
|
7822
|
+
} catch {
|
|
7823
|
+
continue;
|
|
7824
|
+
}
|
|
7825
|
+
if (code.length === 0 || code.length > MAX_FALLBACK_BYTES) continue;
|
|
7826
|
+
let summary;
|
|
7827
|
+
try {
|
|
7828
|
+
summary = natives.summarizeCode({
|
|
7829
|
+
code,
|
|
7830
|
+
path: file,
|
|
7831
|
+
unfoldUntilLines: Math.max(64, countLines(code) >> 2)
|
|
7832
|
+
});
|
|
7833
|
+
} catch {
|
|
7834
|
+
continue;
|
|
7835
|
+
}
|
|
7836
|
+
for (const segment of summary.segments) {
|
|
7837
|
+
if (segment.kind !== "kept" || segment.text === void 0) continue;
|
|
7838
|
+
const lines = segment.text.split("\n");
|
|
7839
|
+
for (let offset = 0; offset < lines.length; offset += 1) {
|
|
7840
|
+
const symbol = fallbackSymbol(file, lines[offset] ?? "", segment.startLine + offset);
|
|
7841
|
+
if (symbol !== void 0) record(collected, symbol);
|
|
7842
|
+
}
|
|
7843
|
+
}
|
|
7844
|
+
}
|
|
7845
|
+
const symbols = [...collected.values()];
|
|
7846
|
+
symbols.sort(compareSymbols);
|
|
7847
|
+
if (symbols.length > request.maxSymbols) {
|
|
7848
|
+
symbols.length = request.maxSymbols;
|
|
7849
|
+
truncated = true;
|
|
7850
|
+
}
|
|
7851
|
+
return {
|
|
7852
|
+
root,
|
|
7853
|
+
symbols,
|
|
7854
|
+
files,
|
|
7855
|
+
languages,
|
|
7856
|
+
fallbackFiles,
|
|
7857
|
+
truncated,
|
|
7858
|
+
elapsedMs: Date.now() - startedAt
|
|
7859
|
+
};
|
|
7860
|
+
}
|
|
7861
|
+
|
|
7862
|
+
// src/providers/codemap-provider.ts
|
|
7863
|
+
var INDEX_TTL_MS = 3e4;
|
|
7864
|
+
var mapSchema = Type.Object({
|
|
7865
|
+
maxTokens: Type.Optional(Type.Number({
|
|
7866
|
+
minimum: 200,
|
|
7867
|
+
maximum: 2e5,
|
|
7868
|
+
description: "Token ceiling for the rendered map"
|
|
7869
|
+
})),
|
|
7870
|
+
glob: Type.Optional(Type.String({
|
|
7871
|
+
maxLength: 512,
|
|
7872
|
+
description: "Glob filter relative to the workspace root"
|
|
7873
|
+
})),
|
|
7874
|
+
focus: Type.Optional(Type.String({
|
|
7875
|
+
maxLength: 512,
|
|
7876
|
+
description: "Task description or symbol name the map should centre on"
|
|
7877
|
+
})),
|
|
7878
|
+
seeds: Type.Optional(Type.Array(Type.String({ maxLength: 1024 }), {
|
|
7879
|
+
maxItems: 32,
|
|
7880
|
+
description: "Files whose git co-change history should raise related files in the ranking"
|
|
7881
|
+
})),
|
|
7882
|
+
refresh: Type.Optional(Type.Boolean({
|
|
7883
|
+
description: "Rebuild the symbol index instead of reusing the cached one"
|
|
7884
|
+
}))
|
|
7885
|
+
}, { additionalProperties: false });
|
|
7886
|
+
var cascadeSchema = Type.Object({
|
|
7887
|
+
seeds: Type.Array(Type.String({ maxLength: 1024 }), {
|
|
7888
|
+
minItems: 1,
|
|
7889
|
+
maxItems: 32,
|
|
7890
|
+
description: "Files to rank co-change against"
|
|
7891
|
+
}),
|
|
7892
|
+
limit: Type.Optional(Type.Number({ minimum: 1, maximum: 200 })),
|
|
7893
|
+
maxCommits: Type.Optional(Type.Number({ minimum: 10, maximum: 2e4 }))
|
|
7894
|
+
}, { additionalProperties: false });
|
|
7895
|
+
var checked = (action, schema, args) => {
|
|
7896
|
+
const validation = validateJsonSchemaValue(schema.toJsonSchema(), args);
|
|
7897
|
+
if (!validation.success) {
|
|
7898
|
+
const message2 = validation.issues.slice(0, 5).map((issue) => issue.message).join("; ");
|
|
7899
|
+
throw new Error(`Invalid codemap.${action} arguments: ${message2}`);
|
|
7900
|
+
}
|
|
7901
|
+
return args;
|
|
7902
|
+
};
|
|
7903
|
+
var descriptors = [
|
|
7904
|
+
{
|
|
7905
|
+
name: "map",
|
|
7906
|
+
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.",
|
|
7907
|
+
inputSchema: mapSchema.toJsonSchema(),
|
|
7908
|
+
risk: "read"
|
|
7909
|
+
},
|
|
7910
|
+
{
|
|
7911
|
+
name: "cascade",
|
|
7912
|
+
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.",
|
|
7913
|
+
inputSchema: cascadeSchema.toJsonSchema(),
|
|
7914
|
+
risk: "read"
|
|
7915
|
+
}
|
|
7916
|
+
];
|
|
7917
|
+
var normalizeCodemapArgs = actionArgNormalizer(() => descriptors);
|
|
7918
|
+
var CodemapProvider = class {
|
|
7919
|
+
constructor(config) {
|
|
7920
|
+
this.config = config;
|
|
7921
|
+
}
|
|
7922
|
+
name = "codemap";
|
|
7923
|
+
description = "Structural repo map: budgeted symbol disclosure and git co-change ranking";
|
|
7924
|
+
#cache = /* @__PURE__ */ new Map();
|
|
7925
|
+
async list(request, _context) {
|
|
7926
|
+
const query = request.query?.toLowerCase();
|
|
7927
|
+
return query ? descriptors.filter(
|
|
7928
|
+
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
7929
|
+
) : descriptors;
|
|
7930
|
+
}
|
|
7931
|
+
async describe(actionName, _context) {
|
|
7932
|
+
return descriptors.find((descriptor) => descriptor.name === actionName);
|
|
7933
|
+
}
|
|
7934
|
+
prepareArguments(actionName, args) {
|
|
7935
|
+
return normalizeCodemapArgs(actionName, args);
|
|
7936
|
+
}
|
|
7937
|
+
async #index(root, glob, refresh, signal) {
|
|
7938
|
+
const key = `${root}\0${glob ?? ""}`;
|
|
7939
|
+
const cached = this.#cache.get(key);
|
|
7940
|
+
if (!refresh && cached && Date.now() - cached.at < INDEX_TTL_MS) return cached.index;
|
|
7941
|
+
const index = await buildSymbolIndex({
|
|
7942
|
+
root,
|
|
7943
|
+
...glob !== void 0 ? { glob } : {},
|
|
7944
|
+
maxFiles: this.config.maxFiles,
|
|
7945
|
+
maxSymbols: this.config.maxSymbols,
|
|
7946
|
+
...signal !== void 0 ? { signal } : {}
|
|
7947
|
+
});
|
|
7948
|
+
this.#cache.set(key, { index, at: Date.now() });
|
|
7949
|
+
return index;
|
|
7950
|
+
}
|
|
7951
|
+
async invoke(actionName, args, context) {
|
|
7952
|
+
switch (actionName) {
|
|
7953
|
+
case "map": {
|
|
7954
|
+
const input = checked("map", mapSchema, args);
|
|
7955
|
+
const index = await this.#index(context.cwd, input.glob, input.refresh === true, context.signal);
|
|
7956
|
+
let cascade;
|
|
7957
|
+
if (input.seeds && input.seeds.length > 0) {
|
|
7958
|
+
cascade = await coChange({
|
|
7959
|
+
root: context.cwd,
|
|
7960
|
+
seeds: input.seeds,
|
|
7961
|
+
maxCommits: this.config.cascadeCommits,
|
|
7962
|
+
limit: this.config.cascadeLimit
|
|
7963
|
+
});
|
|
7964
|
+
}
|
|
7965
|
+
const budgeted = assembleMap({
|
|
7966
|
+
index,
|
|
7967
|
+
maxTokens: input.maxTokens ?? this.config.defaultMaxTokens,
|
|
7968
|
+
...input.focus !== void 0 ? { focus: input.focus } : {},
|
|
7969
|
+
...cascade !== void 0 ? { cascade } : {}
|
|
7970
|
+
});
|
|
7971
|
+
context.activity?.({
|
|
7972
|
+
type: "progress",
|
|
7973
|
+
message: `Code map: ${budgeted.symbolsShown} symbols across ${budgeted.filesShown} files${budgeted.truncated ? ` (${budgeted.omittedSymbols} omitted)` : ""}`
|
|
7974
|
+
});
|
|
7975
|
+
return {
|
|
7976
|
+
...budgeted,
|
|
7977
|
+
indexed: {
|
|
7978
|
+
files: index.files.length,
|
|
7979
|
+
symbols: index.symbols.length,
|
|
7980
|
+
languages: index.languages,
|
|
7981
|
+
fallbackFiles: index.fallbackFiles.length,
|
|
7982
|
+
truncated: index.truncated,
|
|
7983
|
+
elapsedMs: index.elapsedMs
|
|
7984
|
+
},
|
|
7985
|
+
...cascade !== void 0 ? { cascade } : {}
|
|
7986
|
+
};
|
|
7987
|
+
}
|
|
7988
|
+
case "cascade": {
|
|
7989
|
+
const input = checked("cascade", cascadeSchema, args);
|
|
7990
|
+
const graph = await coChange({
|
|
7991
|
+
root: context.cwd,
|
|
7992
|
+
seeds: input.seeds,
|
|
7993
|
+
maxCommits: input.maxCommits ?? this.config.cascadeCommits,
|
|
7994
|
+
limit: input.limit ?? this.config.cascadeLimit
|
|
7995
|
+
});
|
|
7996
|
+
context.activity?.({
|
|
7997
|
+
type: "progress",
|
|
7998
|
+
message: graph.unavailable ? `Co-change unavailable: ${graph.unavailable}` : `Co-change: ${graph.edges.length} related files from ${graph.commitsScanned} commits`
|
|
7999
|
+
});
|
|
8000
|
+
return graph;
|
|
8001
|
+
}
|
|
8002
|
+
default:
|
|
8003
|
+
throw new Error(`Unknown codemap action: ${actionName}`);
|
|
8004
|
+
}
|
|
8005
|
+
}
|
|
8006
|
+
};
|
|
8007
|
+
|
|
8008
|
+
// src/providers/compact-provider.ts
|
|
8009
|
+
import { Type as Type2 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8010
|
+
import { validateJsonSchemaValue as validateJsonSchemaValue2 } from "@oh-my-pi/pi-ai/utils/schema";
|
|
8011
|
+
var requestSchema = Type2.Object({
|
|
8012
|
+
reason: Type2.Optional(Type2.String({
|
|
6770
8013
|
maxLength: 1024,
|
|
6771
8014
|
description: "Short human-readable reason for the compaction"
|
|
6772
8015
|
})),
|
|
6773
|
-
instructions:
|
|
8016
|
+
instructions: Type2.Optional(Type2.String({
|
|
6774
8017
|
maxLength: MAX_COMPACTION_INSTRUCTIONS_CHARS,
|
|
6775
8018
|
description: "Custom compaction instructions forwarded to OMP core"
|
|
6776
8019
|
})),
|
|
6777
|
-
preserve:
|
|
6778
|
-
|
|
8020
|
+
preserve: Type2.Optional(Type2.Array(
|
|
8021
|
+
Type2.String({ maxLength: MAX_PRESERVE_ITEM_CHARS }),
|
|
6779
8022
|
{
|
|
6780
8023
|
maxItems: MAX_PRESERVE_ITEMS,
|
|
6781
8024
|
description: "Explicit bounded facts to preserve, encoded as a typed Fabric compaction request"
|
|
6782
8025
|
}
|
|
6783
8026
|
)),
|
|
6784
|
-
requestedBy:
|
|
8027
|
+
requestedBy: Type2.Optional(Type2.String({
|
|
6785
8028
|
maxLength: 256,
|
|
6786
8029
|
description: "Who requested the compaction (default: model)"
|
|
6787
8030
|
}))
|
|
6788
8031
|
}, { additionalProperties: false });
|
|
6789
8032
|
var checkedRequestArguments = (args) => {
|
|
6790
|
-
const validation =
|
|
8033
|
+
const validation = validateJsonSchemaValue2(requestSchema.toJsonSchema(), args);
|
|
6791
8034
|
if (!validation.success) {
|
|
6792
8035
|
const message2 = validation.issues.slice(0, 5).map((error) => error.message).join("; ");
|
|
6793
8036
|
throw new Error(`Invalid compact.request arguments: ${message2}`);
|
|
@@ -6811,7 +8054,7 @@ var emptySchema = {
|
|
|
6811
8054
|
properties: {},
|
|
6812
8055
|
additionalProperties: false
|
|
6813
8056
|
};
|
|
6814
|
-
var
|
|
8057
|
+
var descriptors2 = [
|
|
6815
8058
|
{
|
|
6816
8059
|
name: "request",
|
|
6817
8060
|
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 +8077,7 @@ var descriptors = [
|
|
|
6834
8077
|
risk: "write"
|
|
6835
8078
|
}
|
|
6836
8079
|
];
|
|
6837
|
-
var normalizeCompactArgs = actionArgNormalizer(() =>
|
|
8080
|
+
var normalizeCompactArgs = actionArgNormalizer(() => descriptors2);
|
|
6838
8081
|
var CompactProvider = class {
|
|
6839
8082
|
constructor(controller) {
|
|
6840
8083
|
this.controller = controller;
|
|
@@ -6843,12 +8086,12 @@ var CompactProvider = class {
|
|
|
6843
8086
|
description = "Programmatic, advisory-then-committed context compaction for the host OMP session";
|
|
6844
8087
|
async list(request, _context) {
|
|
6845
8088
|
const query = request.query?.toLowerCase();
|
|
6846
|
-
return query ?
|
|
8089
|
+
return query ? descriptors2.filter(
|
|
6847
8090
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
6848
|
-
) :
|
|
8091
|
+
) : descriptors2;
|
|
6849
8092
|
}
|
|
6850
8093
|
async describe(actionName, _context) {
|
|
6851
|
-
return
|
|
8094
|
+
return descriptors2.find((descriptor) => descriptor.name === actionName);
|
|
6852
8095
|
}
|
|
6853
8096
|
prepareArguments(actionName, args) {
|
|
6854
8097
|
return normalizeCompactArgs(actionName, args);
|
|
@@ -6888,7 +8131,7 @@ var CompactProvider = class {
|
|
|
6888
8131
|
};
|
|
6889
8132
|
|
|
6890
8133
|
// src/providers/components-provider.ts
|
|
6891
|
-
var
|
|
8134
|
+
var descriptors3 = [
|
|
6892
8135
|
{
|
|
6893
8136
|
name: "list",
|
|
6894
8137
|
description: "List registered component definitions and configured component instances.",
|
|
@@ -6935,13 +8178,13 @@ var ComponentsProvider = class {
|
|
|
6935
8178
|
description = "Supervised component lifecycle, exact capability dependencies, effect cleanup, and reload diagnostics.";
|
|
6936
8179
|
async list(request, _context) {
|
|
6937
8180
|
const query = request.query?.normalize("NFKC").trim().toLowerCase();
|
|
6938
|
-
const filtered = query ?
|
|
8181
|
+
const filtered = query ? descriptors3.filter(
|
|
6939
8182
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
6940
|
-
) :
|
|
8183
|
+
) : descriptors3;
|
|
6941
8184
|
return filtered.slice(0, Math.max(1, Math.min(request.limit ?? 100, 100)));
|
|
6942
8185
|
}
|
|
6943
8186
|
async describe(actionName, _context) {
|
|
6944
|
-
return
|
|
8187
|
+
return descriptors3.find((descriptor) => descriptor.name === actionName);
|
|
6945
8188
|
}
|
|
6946
8189
|
async invoke(actionName, args, _context) {
|
|
6947
8190
|
switch (actionName) {
|
|
@@ -6976,7 +8219,7 @@ var ComponentsProvider = class {
|
|
|
6976
8219
|
import fs5 from "node:fs/promises";
|
|
6977
8220
|
import fsSync from "node:fs";
|
|
6978
8221
|
import os from "node:os";
|
|
6979
|
-
import
|
|
8222
|
+
import path9 from "node:path";
|
|
6980
8223
|
var MCP_DESCRIPTOR_CACHE_VERSION = 1;
|
|
6981
8224
|
var homeDir = () => {
|
|
6982
8225
|
const home = process.env.HOME;
|
|
@@ -6987,25 +8230,25 @@ var expandHome = (input) => {
|
|
|
6987
8230
|
const home = homeDir();
|
|
6988
8231
|
if (input === "~") return home;
|
|
6989
8232
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
6990
|
-
return
|
|
8233
|
+
return path9.join(home, input.slice(2));
|
|
6991
8234
|
}
|
|
6992
8235
|
return input;
|
|
6993
8236
|
};
|
|
6994
|
-
var legacyMcporterDir = () =>
|
|
8237
|
+
var legacyMcporterDir = () => path9.join(homeDir(), ".mcporter");
|
|
6995
8238
|
var mcporterConfigDir = () => {
|
|
6996
8239
|
const raw = process.env.XDG_CONFIG_HOME;
|
|
6997
8240
|
if (raw && raw.trim().length > 0) {
|
|
6998
8241
|
const resolved = expandHome(raw.trim());
|
|
6999
|
-
if (
|
|
8242
|
+
if (path9.isAbsolute(resolved)) return path9.join(resolved, "mcporter");
|
|
7000
8243
|
}
|
|
7001
8244
|
return legacyMcporterDir();
|
|
7002
8245
|
};
|
|
7003
8246
|
var mcporterConfigCandidates = () => {
|
|
7004
8247
|
const base = mcporterConfigDir();
|
|
7005
|
-
const candidates = [
|
|
8248
|
+
const candidates = [path9.join(base, "mcporter.json"), path9.join(base, "mcporter.jsonc")];
|
|
7006
8249
|
const legacy = legacyMcporterDir();
|
|
7007
8250
|
if (base !== legacy) {
|
|
7008
|
-
candidates.push(
|
|
8251
|
+
candidates.push(path9.join(legacy, "mcporter.json"), path9.join(legacy, "mcporter.jsonc"));
|
|
7009
8252
|
}
|
|
7010
8253
|
return candidates;
|
|
7011
8254
|
};
|
|
@@ -7020,12 +8263,12 @@ var pathExists = (filePath) => {
|
|
|
7020
8263
|
var mcpConfigLayerPaths = (rootDir, configPath) => {
|
|
7021
8264
|
const explicitRaw = configPath ?? process.env.MCPORTER_CONFIG;
|
|
7022
8265
|
if (explicitRaw && explicitRaw.trim().length > 0) {
|
|
7023
|
-
return [
|
|
8266
|
+
return [path9.resolve(expandHome(explicitRaw.trim()))];
|
|
7024
8267
|
}
|
|
7025
8268
|
const paths = [];
|
|
7026
8269
|
const home = mcporterConfigCandidates().find(pathExists);
|
|
7027
8270
|
if (home) paths.push(home);
|
|
7028
|
-
const projectPath =
|
|
8271
|
+
const projectPath = path9.resolve(rootDir, "config", "mcporter.json");
|
|
7029
8272
|
if (pathExists(projectPath)) paths.push(projectPath);
|
|
7030
8273
|
return paths;
|
|
7031
8274
|
};
|
|
@@ -7076,8 +8319,8 @@ var parseCacheFile = (value) => {
|
|
|
7076
8319
|
servers: value.servers
|
|
7077
8320
|
};
|
|
7078
8321
|
};
|
|
7079
|
-
var projectMcpCachePath = (projectRoot) =>
|
|
7080
|
-
var globalMcpCachePath = (agentDir) =>
|
|
8322
|
+
var projectMcpCachePath = (projectRoot) => path9.join(projectRoot, ".omp", "fabric", "mcp-cache.json");
|
|
8323
|
+
var globalMcpCachePath = (agentDir) => path9.join(agentDir, "fabric", "mcp-descriptors.json");
|
|
7081
8324
|
var tempCounter = 0;
|
|
7082
8325
|
var McpDescriptorCacheStore = class {
|
|
7083
8326
|
constructor(filePath) {
|
|
@@ -7094,9 +8337,9 @@ var McpDescriptorCacheStore = class {
|
|
|
7094
8337
|
// Atomic-ish write: temp file then rename, so a concurrent reader either
|
|
7095
8338
|
// sees the previous cache or the next one, never a torn document.
|
|
7096
8339
|
async save(file) {
|
|
7097
|
-
const directory =
|
|
8340
|
+
const directory = path9.dirname(this.filePath);
|
|
7098
8341
|
await fs5.mkdir(directory, { recursive: true });
|
|
7099
|
-
const tempPath =
|
|
8342
|
+
const tempPath = path9.join(
|
|
7100
8343
|
directory,
|
|
7101
8344
|
`.mcp-cache-${process.pid}-${Date.now()}-${tempCounter++}.tmp`
|
|
7102
8345
|
);
|
|
@@ -7111,7 +8354,7 @@ var McpDescriptorCacheStore = class {
|
|
|
7111
8354
|
};
|
|
7112
8355
|
|
|
7113
8356
|
// src/providers/mcp-provider.ts
|
|
7114
|
-
import
|
|
8357
|
+
import path10 from "node:path";
|
|
7115
8358
|
var TOOL_METADATA_TTL_MS = 6e4;
|
|
7116
8359
|
var REVALIDATE_CONCURRENCY = 3;
|
|
7117
8360
|
var REVALIDATE_SERVER_TIMEOUT_MS = 2e4;
|
|
@@ -7181,16 +8424,16 @@ var managementDescriptors = [
|
|
|
7181
8424
|
var normalizeSchema = (schema) => typeof schema === "object" && schema !== null && !Array.isArray(schema) ? schema : emptyObjectSchema;
|
|
7182
8425
|
var normalizeMcpResult = (result) => {
|
|
7183
8426
|
if (typeof result !== "object" || result === null || Array.isArray(result)) return result;
|
|
7184
|
-
const
|
|
7185
|
-
if (!Array.isArray(
|
|
7186
|
-
const text =
|
|
8427
|
+
const record2 = result;
|
|
8428
|
+
if (!Array.isArray(record2.content)) return result;
|
|
8429
|
+
const text = record2.content.filter(
|
|
7187
8430
|
(part) => typeof part === "object" && part !== null && part.type === "text" && typeof part.text === "string"
|
|
7188
8431
|
).map((part) => part.text).join("\n");
|
|
7189
|
-
if (
|
|
8432
|
+
if (record2.isError === true) throw new Error(text || "MCP tool returned an error");
|
|
7190
8433
|
return {
|
|
7191
8434
|
text,
|
|
7192
|
-
content:
|
|
7193
|
-
structuredContent:
|
|
8435
|
+
content: record2.content,
|
|
8436
|
+
structuredContent: record2.structuredContent ?? null
|
|
7194
8437
|
};
|
|
7195
8438
|
};
|
|
7196
8439
|
var delay2 = (ms, signal) => new Promise((resolve2) => {
|
|
@@ -7265,9 +8508,9 @@ var McpProvider = class {
|
|
|
7265
8508
|
this.#kickRevalidation();
|
|
7266
8509
|
if (!request.namespace) await this.#awaitColdEnumeration(context.signal);
|
|
7267
8510
|
const query = request.query?.toLowerCase();
|
|
7268
|
-
const filterQuery = (
|
|
8511
|
+
const filterQuery = (descriptors7) => query ? descriptors7.filter(
|
|
7269
8512
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
7270
|
-
) :
|
|
8513
|
+
) : descriptors7;
|
|
7271
8514
|
if (request.namespace) {
|
|
7272
8515
|
const server = await this.#resolveKnownServer(request.namespace);
|
|
7273
8516
|
if (!server) return [];
|
|
@@ -7416,11 +8659,11 @@ var McpProvider = class {
|
|
|
7416
8659
|
// Provider-fidelity descriptors for everything currently known, cached or
|
|
7417
8660
|
// ephemeral.
|
|
7418
8661
|
sliceDescriptors() {
|
|
7419
|
-
const
|
|
8662
|
+
const descriptors7 = [];
|
|
7420
8663
|
for (const [server, entry] of this.#servers) {
|
|
7421
|
-
for (const tool of entry.tools)
|
|
8664
|
+
for (const tool of entry.tools) descriptors7.push(this.#toolDescriptor(server, tool));
|
|
7422
8665
|
}
|
|
7423
|
-
return
|
|
8666
|
+
return descriptors7;
|
|
7424
8667
|
}
|
|
7425
8668
|
// Test/ops hook: await hydration and any in-flight background revalidation,
|
|
7426
8669
|
// then flush pending persistence and notifications.
|
|
@@ -7822,7 +9065,7 @@ var McpProvider = class {
|
|
|
7822
9065
|
kind: "stdio",
|
|
7823
9066
|
command: args.command,
|
|
7824
9067
|
args: commandArgs,
|
|
7825
|
-
cwd:
|
|
9068
|
+
cwd: path10.resolve(this.cwd, typeof args.cwd === "string" ? args.cwd : ".")
|
|
7826
9069
|
},
|
|
7827
9070
|
...env ? { env } : {}
|
|
7828
9071
|
};
|
|
@@ -7887,13 +9130,13 @@ var McpProvider = class {
|
|
|
7887
9130
|
return tools.map((tool) => this.#toolDescriptor(server, tool));
|
|
7888
9131
|
})
|
|
7889
9132
|
);
|
|
7890
|
-
const
|
|
9133
|
+
const descriptors7 = settled.flatMap(
|
|
7891
9134
|
(entry) => entry.status === "fulfilled" ? entry.value : []
|
|
7892
9135
|
);
|
|
7893
9136
|
const query = request.query?.toLowerCase();
|
|
7894
|
-
const filtered = query ?
|
|
9137
|
+
const filtered = query ? descriptors7.filter(
|
|
7895
9138
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
7896
|
-
) :
|
|
9139
|
+
) : descriptors7;
|
|
7897
9140
|
return request.namespace ? filtered : [...managementDescriptors, ...filtered];
|
|
7898
9141
|
}
|
|
7899
9142
|
async #describeLegacy(actionName, _context) {
|
|
@@ -7965,7 +9208,7 @@ var assertReadableStateKey = (key) => {
|
|
|
7965
9208
|
throw new Error(`Fabric mesh key is private host state: ${key}`);
|
|
7966
9209
|
}
|
|
7967
9210
|
};
|
|
7968
|
-
var
|
|
9211
|
+
var descriptors4 = [
|
|
7969
9212
|
{
|
|
7970
9213
|
name: "self",
|
|
7971
9214
|
description: "Return this Fabric participant's mesh identity",
|
|
@@ -8084,7 +9327,7 @@ var descriptors3 = [
|
|
|
8084
9327
|
namespace: "coordination"
|
|
8085
9328
|
}
|
|
8086
9329
|
];
|
|
8087
|
-
var normalizeMeshArgs = actionArgNormalizer(() =>
|
|
9330
|
+
var normalizeMeshArgs = actionArgNormalizer(() => descriptors4);
|
|
8088
9331
|
var MeshProvider = class {
|
|
8089
9332
|
constructor(store, identity, participants) {
|
|
8090
9333
|
this.store = store;
|
|
@@ -8095,12 +9338,12 @@ var MeshProvider = class {
|
|
|
8095
9338
|
description = "Durable topics and compare-and-swap shared state for emergent agent coordination";
|
|
8096
9339
|
async list(request, _context) {
|
|
8097
9340
|
const query = request.query?.toLowerCase();
|
|
8098
|
-
return query ?
|
|
9341
|
+
return query ? descriptors4.filter(
|
|
8099
9342
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
8100
|
-
) :
|
|
9343
|
+
) : descriptors4;
|
|
8101
9344
|
}
|
|
8102
9345
|
async describe(actionName, _context) {
|
|
8103
|
-
return
|
|
9346
|
+
return descriptors4.find((descriptor) => descriptor.name === actionName);
|
|
8104
9347
|
}
|
|
8105
9348
|
prepareArguments(actionName, args) {
|
|
8106
9349
|
return normalizeMeshArgs(actionName, args);
|
|
@@ -8191,7 +9434,7 @@ var MeshProvider = class {
|
|
|
8191
9434
|
import { mkdirSync as mkdirSync2, mkdtempSync, readFileSync as readFileSync2, statSync as statSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
8192
9435
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8193
9436
|
import os2 from "node:os";
|
|
8194
|
-
import
|
|
9437
|
+
import path13 from "node:path";
|
|
8195
9438
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
8196
9439
|
import { BashTool } from "@oh-my-pi/pi-coding-agent/tools/bash";
|
|
8197
9440
|
import { EditTool } from "@oh-my-pi/pi-coding-agent/edit";
|
|
@@ -8207,7 +9450,7 @@ import {
|
|
|
8207
9450
|
|
|
8208
9451
|
// src/agents/bash-worktree-add.ts
|
|
8209
9452
|
import fs6 from "node:fs";
|
|
8210
|
-
import
|
|
9453
|
+
import path11 from "node:path";
|
|
8211
9454
|
var BARE_SAFE = /^[A-Za-z0-9_./:@%+=,-]+$/;
|
|
8212
9455
|
var parseGitWorktreeAdd = (command) => {
|
|
8213
9456
|
const trimmed = command.trim();
|
|
@@ -8270,8 +9513,8 @@ var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
|
8270
9513
|
if (typeof command !== "string") return void 0;
|
|
8271
9514
|
const parsed = parseGitWorktreeAdd(command);
|
|
8272
9515
|
if (!parsed) return void 0;
|
|
8273
|
-
const gitCwd = parsed.gitCwd ?
|
|
8274
|
-
const dest =
|
|
9516
|
+
const gitCwd = parsed.gitCwd ? path11.resolve(sessionCwd, parsed.gitCwd) : typeof args.cwd === "string" ? args.cwd : sessionCwd;
|
|
9517
|
+
const dest = path11.resolve(gitCwd, parsed.dest);
|
|
8275
9518
|
let gitRoot;
|
|
8276
9519
|
try {
|
|
8277
9520
|
const root = await executeFile("git", ["rev-parse", "--show-toplevel"], {
|
|
@@ -8300,9 +9543,9 @@ var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
|
8300
9543
|
|
|
8301
9544
|
// src/providers/omp-bash-cwd.ts
|
|
8302
9545
|
import { accessSync, constants, statSync as statSync2 } from "node:fs";
|
|
8303
|
-
import
|
|
9546
|
+
import path12 from "node:path";
|
|
8304
9547
|
import { createBashToolDefinition } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-pi-coding-agent-shim";
|
|
8305
|
-
import { Type as
|
|
9548
|
+
import { Type as Type3 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8306
9549
|
var OMP_BASH_CWD_KEY = "cwd";
|
|
8307
9550
|
var resolveOmpShellCwd = (toolName, sessionCwd, requested) => {
|
|
8308
9551
|
if (typeof requested !== "string" || requested.trim().length === 0) {
|
|
@@ -8310,7 +9553,7 @@ var resolveOmpShellCwd = (toolName, sessionCwd, requested) => {
|
|
|
8310
9553
|
`Invalid omp.${toolName} cwd ${JSON.stringify(requested)}: path must be a non-empty string`
|
|
8311
9554
|
);
|
|
8312
9555
|
}
|
|
8313
|
-
const resolved =
|
|
9556
|
+
const resolved = path12.isAbsolute(requested) ? path12.resolve(requested) : path12.resolve(sessionCwd, requested);
|
|
8314
9557
|
try {
|
|
8315
9558
|
if (!statSync2(resolved).isDirectory()) throw new Error("path is not a directory");
|
|
8316
9559
|
accessSync(resolved, constants.R_OK | constants.X_OK);
|
|
@@ -8330,8 +9573,8 @@ var resolveShellCwdArgument = (toolName, sessionCwd, args) => Object.hasOwn(args
|
|
|
8330
9573
|
args[OMP_BASH_CWD_KEY]
|
|
8331
9574
|
)
|
|
8332
9575
|
} : args;
|
|
8333
|
-
var CWD_PROPERTY =
|
|
8334
|
-
|
|
9576
|
+
var CWD_PROPERTY = Type3.Optional(
|
|
9577
|
+
Type3.String({
|
|
8335
9578
|
description: "Execution directory for this command; relative paths resolve from the session cwd."
|
|
8336
9579
|
})
|
|
8337
9580
|
);
|
|
@@ -8350,7 +9593,7 @@ var withShellCwdSchema = (schema) => {
|
|
|
8350
9593
|
if (Object.hasOwn(document.properties, OMP_BASH_CWD_KEY)) return schema;
|
|
8351
9594
|
const cwdSchema = schemaDocument2(CWD_PROPERTY);
|
|
8352
9595
|
if (!cwdSchema) return schema;
|
|
8353
|
-
return
|
|
9596
|
+
return Type3.Unsafe({
|
|
8354
9597
|
...document,
|
|
8355
9598
|
properties: { ...document.properties, [OMP_BASH_CWD_KEY]: cwdSchema }
|
|
8356
9599
|
});
|
|
@@ -8386,22 +9629,22 @@ var BashCwdDefinitions = class extends ShellCwdDefinitions {
|
|
|
8386
9629
|
// src/providers/write-preview.ts
|
|
8387
9630
|
import { homedir } from "node:os";
|
|
8388
9631
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
8389
|
-
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
8390
|
-
import { Type as
|
|
9632
|
+
import { mkdir, readFile as readFile2, stat, writeFile } from "node:fs/promises";
|
|
9633
|
+
import { Type as Type4 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
|
|
8391
9634
|
var mutationQueues = /* @__PURE__ */ new Map();
|
|
8392
|
-
var withFileMutationQueue = async (
|
|
8393
|
-
const previous = mutationQueues.get(
|
|
9635
|
+
var withFileMutationQueue = async (path19, operation) => {
|
|
9636
|
+
const previous = mutationQueues.get(path19) ?? Promise.resolve();
|
|
8394
9637
|
let release;
|
|
8395
9638
|
const current = new Promise((resolve2) => {
|
|
8396
9639
|
release = resolve2;
|
|
8397
9640
|
});
|
|
8398
|
-
mutationQueues.set(
|
|
9641
|
+
mutationQueues.set(path19, current);
|
|
8399
9642
|
await previous;
|
|
8400
9643
|
try {
|
|
8401
9644
|
return await operation();
|
|
8402
9645
|
} finally {
|
|
8403
9646
|
release();
|
|
8404
|
-
if (mutationQueues.get(
|
|
9647
|
+
if (mutationQueues.get(path19) === current) mutationQueues.delete(path19);
|
|
8405
9648
|
}
|
|
8406
9649
|
};
|
|
8407
9650
|
var resolvePreviewPath = (filePath, cwd) => {
|
|
@@ -8436,7 +9679,7 @@ var readExistingFileForPreview = async (filePath, cwd, nextContent) => {
|
|
|
8436
9679
|
return skipped("previous file too large", fileStat.size, true);
|
|
8437
9680
|
}
|
|
8438
9681
|
try {
|
|
8439
|
-
const content = await
|
|
9682
|
+
const content = await readFile2(absolutePath, "utf8");
|
|
8440
9683
|
const bytes = Buffer.byteLength(content, "utf8");
|
|
8441
9684
|
return bytes > MAX_WRITE_DIFF_BYTES ? skipped("previous file too large", bytes, true) : { kind: "content", content };
|
|
8442
9685
|
} catch {
|
|
@@ -8448,20 +9691,20 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
8448
9691
|
name: "write",
|
|
8449
9692
|
label: "Write",
|
|
8450
9693
|
description: "Write a file",
|
|
8451
|
-
parameters:
|
|
9694
|
+
parameters: Type4.Object({ path: Type4.String(), content: Type4.String() }),
|
|
8452
9695
|
execute: async () => ({ content: [{ type: "text", text: "" }] })
|
|
8453
9696
|
};
|
|
8454
9697
|
return {
|
|
8455
9698
|
...original,
|
|
8456
9699
|
async execute(_toolCallId, params, signal) {
|
|
8457
|
-
const { path:
|
|
8458
|
-
const absolutePath = resolvePreviewPath(
|
|
9700
|
+
const { path: path19, content } = params;
|
|
9701
|
+
const absolutePath = resolvePreviewPath(path19, cwd);
|
|
8459
9702
|
return withFileMutationQueue(absolutePath, async () => {
|
|
8460
9703
|
const throwIfAborted2 = () => {
|
|
8461
9704
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
8462
9705
|
};
|
|
8463
9706
|
throwIfAborted2();
|
|
8464
|
-
const before = await readExistingFileForPreview(
|
|
9707
|
+
const before = await readExistingFileForPreview(path19, cwd, content);
|
|
8465
9708
|
throwIfAborted2();
|
|
8466
9709
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
8467
9710
|
throwIfAborted2();
|
|
@@ -8471,7 +9714,7 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
8471
9714
|
content: [
|
|
8472
9715
|
{
|
|
8473
9716
|
type: "text",
|
|
8474
|
-
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${
|
|
9717
|
+
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${path19}`
|
|
8475
9718
|
}
|
|
8476
9719
|
],
|
|
8477
9720
|
details: { codePreviewBeforeWrite: before }
|
|
@@ -8486,7 +9729,7 @@ var MAX_RENDERER_ARGUMENT_CHARS = 2e5;
|
|
|
8486
9729
|
var GUEST_READ_LINE_LIMIT = 1e5;
|
|
8487
9730
|
var MAX_REPLACE_ALL_FILE_CHARS = 2e6;
|
|
8488
9731
|
var createNativeSession = (cwd, artifactPaths) => {
|
|
8489
|
-
const artifactRoot = artifactPaths ? mkdtempSync(
|
|
9732
|
+
const artifactRoot = artifactPaths ? mkdtempSync(path13.join(os2.tmpdir(), "omp-fabric-bash-")) : void 0;
|
|
8490
9733
|
return {
|
|
8491
9734
|
cwd,
|
|
8492
9735
|
hasUI: false,
|
|
@@ -8503,7 +9746,7 @@ var createNativeSession = (cwd, artifactPaths) => {
|
|
|
8503
9746
|
try {
|
|
8504
9747
|
mkdirSync2(artifactRoot, { recursive: true, mode: 448 });
|
|
8505
9748
|
const id = randomUUID3();
|
|
8506
|
-
const artifactPath =
|
|
9749
|
+
const artifactPath = path13.join(artifactRoot, `${toolType}-${id}.log`);
|
|
8507
9750
|
writeFileSync2(artifactPath, "", { mode: 384 });
|
|
8508
9751
|
artifactPaths.set(id, artifactPath);
|
|
8509
9752
|
artifactAllocations.getStore()?.push(artifactPath);
|
|
@@ -8566,19 +9809,19 @@ var createGrepDefinitionWithSkip = (cwd) => {
|
|
|
8566
9809
|
...legacy,
|
|
8567
9810
|
parameters: withGrepSkipSchema(legacy.parameters),
|
|
8568
9811
|
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
|
|
9812
|
+
const record2 = asRecord(params) ?? {};
|
|
9813
|
+
const rawPattern = typeof record2.pattern === "string" ? record2.pattern : "";
|
|
9814
|
+
const searchPath = typeof record2.path === "string" ? record2.path : ".";
|
|
9815
|
+
const glob = typeof record2.glob === "string" ? record2.glob : void 0;
|
|
9816
|
+
const contextLines = typeof record2.context === "number" ? record2.context : void 0;
|
|
9817
|
+
const skip = typeof record2.skip === "number" ? record2.skip : void 0;
|
|
8575
9818
|
const tool = contextLines === void 0 ? defaultTool : new GrepTool(grepSession(cwd, contextLines));
|
|
8576
9819
|
return tool.execute(
|
|
8577
9820
|
toolCallId,
|
|
8578
9821
|
{
|
|
8579
|
-
pattern:
|
|
9822
|
+
pattern: record2.literal === true ? piEscapeRegexLiteral(rawPattern) : rawPattern,
|
|
8580
9823
|
path: glob ? piJoinPath(searchPath, glob) : searchPath,
|
|
8581
|
-
case:
|
|
9824
|
+
case: record2.ignoreCase === true ? false : void 0,
|
|
8582
9825
|
...skip === void 0 ? {} : { skip }
|
|
8583
9826
|
},
|
|
8584
9827
|
signal,
|
|
@@ -8598,19 +9841,19 @@ var normalizeEditArguments = (args, replaceAll, cwd) => {
|
|
|
8598
9841
|
if (typeof edit !== "object" || edit === null || Array.isArray(edit)) {
|
|
8599
9842
|
throw new Error(`omp.edit edits[${index}] must be an object`);
|
|
8600
9843
|
}
|
|
8601
|
-
const
|
|
8602
|
-
const oldString =
|
|
8603
|
-
const newString =
|
|
9844
|
+
const record2 = edit;
|
|
9845
|
+
const oldString = record2.old_string ?? record2.oldText ?? record2.old;
|
|
9846
|
+
const newString = record2.new_string ?? record2.newText ?? record2.new ?? record2.replacement;
|
|
8604
9847
|
if (typeof oldString !== "string" || typeof newString !== "string") {
|
|
8605
9848
|
throw new Error(`omp.edit edits[${index}] requires old and new text strings`);
|
|
8606
9849
|
}
|
|
8607
9850
|
return {
|
|
8608
9851
|
old_string: oldString,
|
|
8609
9852
|
new_string: newString,
|
|
8610
|
-
...replaceAll ||
|
|
9853
|
+
...replaceAll || record2.all === true || record2.replace_all === true ? { replace_all: true } : {}
|
|
8611
9854
|
};
|
|
8612
9855
|
});
|
|
8613
|
-
const resolvedPath =
|
|
9856
|
+
const resolvedPath = path13.resolve(cwd, filePath.startsWith("@") ? filePath.slice(1) : filePath);
|
|
8614
9857
|
const current = readFileSync2(resolvedPath, "utf8");
|
|
8615
9858
|
if (current.length > MAX_REPLACE_ALL_FILE_CHARS) {
|
|
8616
9859
|
throw new Error(`omp.edit refuses files over ${MAX_REPLACE_ALL_FILE_CHARS} characters`);
|
|
@@ -8722,7 +9965,7 @@ var keepLeadingLines = (text, count) => {
|
|
|
8722
9965
|
}
|
|
8723
9966
|
return text.slice(0, index - 1);
|
|
8724
9967
|
};
|
|
8725
|
-
var
|
|
9968
|
+
var countLines2 = (text) => {
|
|
8726
9969
|
if (text.length === 0) return 0;
|
|
8727
9970
|
let lines = 1;
|
|
8728
9971
|
for (let index = text.indexOf("\n"); index !== -1; index = text.indexOf("\n", index + 1)) lines++;
|
|
@@ -8791,11 +10034,11 @@ var withoutColumnLimit = (detailRecord, metaRecord) => {
|
|
|
8791
10034
|
return remainingDetails;
|
|
8792
10035
|
};
|
|
8793
10036
|
var grepTruncationSignal = (details) => {
|
|
8794
|
-
const
|
|
8795
|
-
if (!
|
|
8796
|
-
const perFile = finiteNumber2(
|
|
8797
|
-
const maxColumn = finiteNumber2(asRecord(asRecord(asRecord(
|
|
8798
|
-
const fileCount = finiteNumber2(
|
|
10037
|
+
const record2 = asRecord(details);
|
|
10038
|
+
if (!record2 || record2.truncated !== true) return void 0;
|
|
10039
|
+
const perFile = finiteNumber2(record2.perFileLimitReached);
|
|
10040
|
+
const maxColumn = finiteNumber2(asRecord(asRecord(asRecord(record2.meta)?.limits)?.columnTruncated)?.maxColumn);
|
|
10041
|
+
const fileCount = finiteNumber2(record2.fileCount);
|
|
8799
10042
|
const reasons = [];
|
|
8800
10043
|
const notes = [];
|
|
8801
10044
|
let continuation = null;
|
|
@@ -8822,7 +10065,7 @@ var grepTruncationSignal = (details) => {
|
|
|
8822
10065
|
tool: "grep",
|
|
8823
10066
|
partial: true,
|
|
8824
10067
|
reasons,
|
|
8825
|
-
...finiteNumber2(
|
|
10068
|
+
...finiteNumber2(record2.matchCount) === void 0 ? {} : { matchCount: record2.matchCount },
|
|
8826
10069
|
...fileCount === void 0 ? {} : { fileCount },
|
|
8827
10070
|
...perFile === void 0 ? {} : { perFileMatchLimit: perFile },
|
|
8828
10071
|
...maxColumn === void 0 ? {} : { maxColumn },
|
|
@@ -8859,9 +10102,9 @@ var lineBudgetSignal = (meta, target, progress) => {
|
|
|
8859
10102
|
};
|
|
8860
10103
|
};
|
|
8861
10104
|
var findTruncationSignal = (details) => {
|
|
8862
|
-
const
|
|
8863
|
-
if (!
|
|
8864
|
-
const reached = finiteNumber2(
|
|
10105
|
+
const record2 = asRecord(details);
|
|
10106
|
+
if (!record2 || record2.truncated !== true) return void 0;
|
|
10107
|
+
const reached = finiteNumber2(record2.resultLimitReached) ?? finiteNumber2(record2.fileCount);
|
|
8865
10108
|
return {
|
|
8866
10109
|
tool: "find",
|
|
8867
10110
|
partial: true,
|
|
@@ -9014,10 +10257,10 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9014
10257
|
}
|
|
9015
10258
|
async list(request, _context) {
|
|
9016
10259
|
const query = request.query?.toLowerCase();
|
|
9017
|
-
const
|
|
10260
|
+
const descriptors7 = await Promise.all(
|
|
9018
10261
|
OMP_CORE_TOOL_NAMES.map((name) => this.describe(name, _context))
|
|
9019
10262
|
);
|
|
9020
|
-
return
|
|
10263
|
+
return descriptors7.filter((descriptor) => descriptor !== void 0).filter(
|
|
9021
10264
|
(descriptor) => query ? `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query) : true
|
|
9022
10265
|
);
|
|
9023
10266
|
}
|
|
@@ -9041,13 +10284,13 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9041
10284
|
if (typeof prepared !== "object" || prepared === null || Array.isArray(prepared)) {
|
|
9042
10285
|
throw new Error(`OMP tool ${actionName} prepared non-object arguments`);
|
|
9043
10286
|
}
|
|
9044
|
-
const
|
|
10287
|
+
const record2 = prepared;
|
|
9045
10288
|
if (isOmpShellToolName(actionName)) {
|
|
9046
|
-
const shellArgs = Object.hasOwn(args, OMP_BASH_CWD_KEY) ? { ...
|
|
10289
|
+
const shellArgs = Object.hasOwn(args, OMP_BASH_CWD_KEY) ? { ...record2, [OMP_BASH_CWD_KEY]: args[OMP_BASH_CWD_KEY] } : record2;
|
|
9047
10290
|
return resolveShellCwdArgument(actionName, this.#cwd, shellArgs);
|
|
9048
10291
|
}
|
|
9049
|
-
if (actionName === "read") return normalizeReadArguments(
|
|
9050
|
-
return actionName === "edit" ? normalizeEditArguments(
|
|
10292
|
+
if (actionName === "read") return normalizeReadArguments(record2);
|
|
10293
|
+
return actionName === "edit" ? normalizeEditArguments(record2, args.all === true, this.#cwd) : record2;
|
|
9051
10294
|
}
|
|
9052
10295
|
#assertAllowed(name) {
|
|
9053
10296
|
if (this.#allowedTools && !this.#allowedTools.has(name)) {
|
|
@@ -9257,7 +10500,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9257
10500
|
}
|
|
9258
10501
|
const budget = resultCharBound(context) - READ_MARKER_RESERVE_CHARS;
|
|
9259
10502
|
let text = stripRepeatReadHint(textContent(result.content));
|
|
9260
|
-
let covered = meta.shownEnd ??
|
|
10503
|
+
let covered = meta.shownEnd ?? countLines2(text);
|
|
9261
10504
|
let nextOffset = meta.nextOffset;
|
|
9262
10505
|
let stopped;
|
|
9263
10506
|
while (nextOffset !== void 0 && covered < target.endLimit) {
|
|
@@ -9281,7 +10524,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9281
10524
|
const pageText = stripRepeatReadHint(textContent(page.content));
|
|
9282
10525
|
const start = pageMeta?.shownStart ?? nextOffset;
|
|
9283
10526
|
const body = dropLeadingLines(pageText, Math.max(0, covered - start + 1));
|
|
9284
|
-
const pageEnd = pageMeta?.shownEnd ?? start +
|
|
10527
|
+
const pageEnd = pageMeta?.shownEnd ?? start + countLines2(pageText) - 1;
|
|
9285
10528
|
if (body.length === 0 || pageEnd <= covered) {
|
|
9286
10529
|
nextOffset = void 0;
|
|
9287
10530
|
break;
|
|
@@ -9411,7 +10654,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
|
|
|
9411
10654
|
import { spawn } from "node:child_process";
|
|
9412
10655
|
import { createHash as createHash3, randomBytes, randomUUID as randomUUID4 } from "node:crypto";
|
|
9413
10656
|
import fs8 from "node:fs";
|
|
9414
|
-
import
|
|
10657
|
+
import path15 from "node:path";
|
|
9415
10658
|
|
|
9416
10659
|
// src/schema/types.ts
|
|
9417
10660
|
var stateBinding = (head) => head ? { transitionId: head.transitionId, version: head.version, to: head.to } : null;
|
|
@@ -9420,7 +10663,7 @@ var stateBinding = (head) => head ? { transitionId: head.transitionId, version:
|
|
|
9420
10663
|
import { execFileSync } from "node:child_process";
|
|
9421
10664
|
import { createHash as createHash2 } from "node:crypto";
|
|
9422
10665
|
import fs7 from "node:fs";
|
|
9423
|
-
import
|
|
10666
|
+
import path14 from "node:path";
|
|
9424
10667
|
var SNAPSHOT_MAX_FILES = 2e4;
|
|
9425
10668
|
var SNAPSHOT_MAX_BYTES = 512 * 1024 * 1024;
|
|
9426
10669
|
var FALLBACK_SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
@@ -9438,10 +10681,10 @@ var git = (cwd, args) => execFileSync("git", ["-C", cwd, ...args], {
|
|
|
9438
10681
|
stdio: ["ignore", "pipe", "ignore"]
|
|
9439
10682
|
});
|
|
9440
10683
|
var nulPaths = (buffer) => buffer.toString("utf8").split("\0").filter((item) => item.length > 0);
|
|
9441
|
-
var normalizeRelative = (value) => value.split(
|
|
10684
|
+
var normalizeRelative = (value) => value.split(path14.sep).join("/");
|
|
9442
10685
|
var isInside = (root, candidate) => {
|
|
9443
|
-
const relative =
|
|
9444
|
-
return relative === "" || !
|
|
10686
|
+
const relative = path14.relative(root, candidate);
|
|
10687
|
+
return relative === "" || !path14.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path14.sep}`);
|
|
9445
10688
|
};
|
|
9446
10689
|
var excluded = (absolute, exclusions) => exclusions.some((root) => isInside(root, absolute));
|
|
9447
10690
|
var entryDigest = (absolute) => {
|
|
@@ -9467,12 +10710,12 @@ var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
|
9467
10710
|
let bytes = 0;
|
|
9468
10711
|
const unique = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
9469
10712
|
for (const relativeInput of unique) {
|
|
9470
|
-
const absolute =
|
|
10713
|
+
const absolute = path14.resolve(cwd, relativeInput);
|
|
9471
10714
|
if (!isInside(cwd, absolute) || excluded(absolute, exclusions)) continue;
|
|
9472
10715
|
if (Object.keys(entries).length >= SNAPSHOT_MAX_FILES) {
|
|
9473
10716
|
throw new Error(`Schema workspace snapshot exceeds ${SNAPSHOT_MAX_FILES} files`);
|
|
9474
10717
|
}
|
|
9475
|
-
const relative = normalizeRelative(
|
|
10718
|
+
const relative = normalizeRelative(path14.relative(cwd, absolute));
|
|
9476
10719
|
const entry = entryDigest(absolute);
|
|
9477
10720
|
bytes += entry.bytes;
|
|
9478
10721
|
if (bytes > SNAPSHOT_MAX_BYTES) {
|
|
@@ -9501,9 +10744,9 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
9501
10744
|
const entries = fs7.readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
9502
10745
|
for (const entry of entries) {
|
|
9503
10746
|
if (FALLBACK_SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
9504
|
-
const absolute =
|
|
10747
|
+
const absolute = path14.join(directory, entry.name);
|
|
9505
10748
|
if (excluded(absolute, exclusions)) continue;
|
|
9506
|
-
const relative = normalizeRelative(
|
|
10749
|
+
const relative = normalizeRelative(path14.relative(cwd, absolute));
|
|
9507
10750
|
if (entry.isDirectory()) visit(absolute);
|
|
9508
10751
|
else paths.push(relative);
|
|
9509
10752
|
if (paths.length > SNAPSHOT_MAX_FILES) {
|
|
@@ -9517,7 +10760,7 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
9517
10760
|
var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
9518
10761
|
const cwd = fs7.realpathSync(cwdInput);
|
|
9519
10762
|
const exclusions = excludedRoots.map((root) => {
|
|
9520
|
-
const absolute =
|
|
10763
|
+
const absolute = path14.resolve(root);
|
|
9521
10764
|
try {
|
|
9522
10765
|
return fs7.realpathSync(absolute);
|
|
9523
10766
|
} catch {
|
|
@@ -9555,18 +10798,18 @@ var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
|
9555
10798
|
);
|
|
9556
10799
|
};
|
|
9557
10800
|
var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
9558
|
-
if (!requestedPath.trim() ||
|
|
10801
|
+
if (!requestedPath.trim() || path14.isAbsolute(requestedPath)) {
|
|
9559
10802
|
throw new Error(`Schema paths must be non-empty project-relative paths: ${requestedPath}`);
|
|
9560
10803
|
}
|
|
9561
10804
|
const cwd = fs7.realpathSync(cwdInput);
|
|
9562
|
-
const absolute =
|
|
10805
|
+
const absolute = path14.resolve(cwd, requestedPath);
|
|
9563
10806
|
if (!isInside(cwd, absolute) || absolute === cwd) {
|
|
9564
10807
|
throw new Error(`Schema path escapes the project workspace: ${requestedPath}`);
|
|
9565
10808
|
}
|
|
9566
|
-
const relativeParts =
|
|
10809
|
+
const relativeParts = path14.relative(cwd, absolute).split(path14.sep);
|
|
9567
10810
|
let cursor = cwd;
|
|
9568
10811
|
for (let index = 0; index < relativeParts.length; index++) {
|
|
9569
|
-
cursor =
|
|
10812
|
+
cursor = path14.join(cursor, relativeParts[index]);
|
|
9570
10813
|
let stat2;
|
|
9571
10814
|
try {
|
|
9572
10815
|
stat2 = fs7.lstatSync(cursor);
|
|
@@ -9575,9 +10818,9 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9575
10818
|
if (index !== relativeParts.length - 1 || !options.allowAbsent) {
|
|
9576
10819
|
throw new Error(`Schema path does not exist: ${requestedPath}`);
|
|
9577
10820
|
}
|
|
9578
|
-
const parentReal = fs7.realpathSync(
|
|
10821
|
+
const parentReal = fs7.realpathSync(path14.dirname(cursor));
|
|
9579
10822
|
if (!isInside(cwd, parentReal)) throw new Error(`Schema path parent escapes the workspace: ${requestedPath}`);
|
|
9580
|
-
return { absolute, relative: normalizeRelative(
|
|
10823
|
+
return { absolute, relative: normalizeRelative(path14.relative(cwd, absolute)), exists: false };
|
|
9581
10824
|
}
|
|
9582
10825
|
throw error;
|
|
9583
10826
|
}
|
|
@@ -9589,7 +10832,7 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
9589
10832
|
throw new Error(`Schema transaction paths must name regular files: ${requestedPath}`);
|
|
9590
10833
|
}
|
|
9591
10834
|
}
|
|
9592
|
-
return { absolute, relative: normalizeRelative(
|
|
10835
|
+
return { absolute, relative: normalizeRelative(path14.relative(cwd, absolute)), exists: true };
|
|
9593
10836
|
};
|
|
9594
10837
|
var sha256File = (absolute) => `sha256:${digest(fs7.readFileSync(absolute))}`;
|
|
9595
10838
|
|
|
@@ -9640,8 +10883,8 @@ var SchemaController = class {
|
|
|
9640
10883
|
this.identity = identity;
|
|
9641
10884
|
this.state = state;
|
|
9642
10885
|
this.cwd = fs8.realpathSync(cwd);
|
|
9643
|
-
this.#journalRoot =
|
|
9644
|
-
this.#lockPath =
|
|
10886
|
+
this.#journalRoot = path15.join(mesh.root, "schema-transactions");
|
|
10887
|
+
this.#lockPath = path15.join(this.#journalRoot, ".commit.lock");
|
|
9645
10888
|
this.#recoverJournals();
|
|
9646
10889
|
}
|
|
9647
10890
|
#activeHypotheses = /* @__PURE__ */ new Map();
|
|
@@ -9666,12 +10909,12 @@ var SchemaController = class {
|
|
|
9666
10909
|
}
|
|
9667
10910
|
status(parentToolCallId) {
|
|
9668
10911
|
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:
|
|
10912
|
+
const hypotheses = this.mesh.list(HYPOTHESIS_PREFIX, this.mesh.maxReadEvents).map((entry) => entry.value).filter((record2) => !parentToolCallId || record2.parentToolCallId === parentToolCallId).map((record2) => ({
|
|
10913
|
+
id: record2.id,
|
|
10914
|
+
label: record2.label,
|
|
10915
|
+
status: record2.status,
|
|
10916
|
+
generation: record2.generation,
|
|
10917
|
+
updatedAt: record2.updatedAt
|
|
9675
10918
|
}));
|
|
9676
10919
|
return {
|
|
9677
10920
|
mode: this.config.mode,
|
|
@@ -9696,7 +10939,7 @@ var SchemaController = class {
|
|
|
9696
10939
|
const snapshot = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
9697
10940
|
const generation = this.#generation();
|
|
9698
10941
|
const now = Date.now();
|
|
9699
|
-
const
|
|
10942
|
+
const record2 = {
|
|
9700
10943
|
id: randomUUID4(),
|
|
9701
10944
|
label: input.label,
|
|
9702
10945
|
summary: input.summary,
|
|
@@ -9710,66 +10953,66 @@ var SchemaController = class {
|
|
|
9710
10953
|
createdAt: now,
|
|
9711
10954
|
updatedAt: now
|
|
9712
10955
|
};
|
|
9713
|
-
await this.#publish("hypothesized",
|
|
10956
|
+
await this.#publish("hypothesized", record2);
|
|
9714
10957
|
await this.mesh.put({
|
|
9715
|
-
key: `${HYPOTHESIS_PREFIX}${
|
|
9716
|
-
value:
|
|
10958
|
+
key: `${HYPOTHESIS_PREFIX}${record2.id}`,
|
|
10959
|
+
value: record2,
|
|
9717
10960
|
ifVersion: 0,
|
|
9718
10961
|
identity: this.identity
|
|
9719
10962
|
});
|
|
9720
|
-
this.#activeHypotheses.set(
|
|
9721
|
-
context.update(`Schema hypothesis recorded: ${
|
|
10963
|
+
this.#activeHypotheses.set(record2.id, context.parentToolCallId);
|
|
10964
|
+
context.update(`Schema hypothesis recorded: ${record2.label}`);
|
|
9722
10965
|
return {
|
|
9723
|
-
hypothesisId:
|
|
9724
|
-
status:
|
|
9725
|
-
state:
|
|
9726
|
-
fingerprint:
|
|
10966
|
+
hypothesisId: record2.id,
|
|
10967
|
+
status: record2.status,
|
|
10968
|
+
state: record2.state,
|
|
10969
|
+
fingerprint: record2.fingerprint,
|
|
9727
10970
|
generation
|
|
9728
10971
|
};
|
|
9729
10972
|
}
|
|
9730
10973
|
async verify(hypothesisId, context) {
|
|
9731
10974
|
const entry = this.#requireHypothesis(hypothesisId);
|
|
9732
|
-
const
|
|
9733
|
-
this.#assertInvocation(
|
|
9734
|
-
if (
|
|
9735
|
-
if (
|
|
10975
|
+
const record2 = entry.value;
|
|
10976
|
+
this.#assertInvocation(record2.parentToolCallId, context.parentToolCallId);
|
|
10977
|
+
if (record2.status !== "active") throw new Error(`Schema hypothesis is not active: ${record2.status}`);
|
|
10978
|
+
if (record2.evidence.length === 0) return this.#failedVerification(record2, [], "missing evidence");
|
|
9736
10979
|
let before;
|
|
9737
10980
|
try {
|
|
9738
10981
|
before = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
9739
10982
|
} catch (error) {
|
|
9740
|
-
return this.#failedVerification(
|
|
10983
|
+
return this.#failedVerification(record2, [], `workspace snapshot failed: ${errorMessage4(error)}`);
|
|
9741
10984
|
}
|
|
9742
10985
|
const currentState = stateBinding(this.state?.getHead() ?? null);
|
|
9743
|
-
if (!sameBinding(
|
|
9744
|
-
return this.#failedVerification(
|
|
10986
|
+
if (!sameBinding(record2.state, currentState)) {
|
|
10987
|
+
return this.#failedVerification(record2, [], "state head changed since hypothesis");
|
|
9745
10988
|
}
|
|
9746
|
-
if (
|
|
9747
|
-
return this.#failedVerification(
|
|
10989
|
+
if (record2.generation !== this.#generation()) {
|
|
10990
|
+
return this.#failedVerification(record2, [], "workspace generation changed since hypothesis");
|
|
9748
10991
|
}
|
|
9749
|
-
if (
|
|
9750
|
-
return this.#failedVerification(
|
|
10992
|
+
if (record2.fingerprint !== before.fingerprint) {
|
|
10993
|
+
return this.#failedVerification(record2, [], "workspace fingerprint changed since hypothesis");
|
|
9751
10994
|
}
|
|
9752
|
-
const results = await this.#verifyEvidence(
|
|
10995
|
+
const results = await this.#verifyEvidence(record2.evidence, context);
|
|
9753
10996
|
let after;
|
|
9754
10997
|
try {
|
|
9755
10998
|
after = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
9756
10999
|
} catch (error) {
|
|
9757
|
-
return this.#failedVerification(
|
|
11000
|
+
return this.#failedVerification(record2, results, `post-evidence snapshot failed: ${errorMessage4(error)}`);
|
|
9758
11001
|
}
|
|
9759
11002
|
const allConfirmed = results.length > 0 && results.every((result) => result.status === "confirmed");
|
|
9760
11003
|
if (!allConfirmed || before.fingerprint !== after.fingerprint) {
|
|
9761
11004
|
const reason = before.fingerprint !== after.fingerprint ? "workspace fingerprint changed while evidence ran" : "one or more evidence items were not confirmed";
|
|
9762
|
-
return this.#failedVerification(
|
|
11005
|
+
return this.#failedVerification(record2, results, reason);
|
|
9763
11006
|
}
|
|
9764
11007
|
const certificate = randomBytes(32).toString("hex");
|
|
9765
11008
|
const issuedAt = Date.now();
|
|
9766
11009
|
const certificateRecord = {
|
|
9767
11010
|
tokenHash: hashToken(certificate),
|
|
9768
|
-
hypothesisId:
|
|
11011
|
+
hypothesisId: record2.id,
|
|
9769
11012
|
parentToolCallId: context.parentToolCallId,
|
|
9770
|
-
state:
|
|
9771
|
-
fingerprint:
|
|
9772
|
-
generation:
|
|
11013
|
+
state: record2.state,
|
|
11014
|
+
fingerprint: record2.fingerprint,
|
|
11015
|
+
generation: record2.generation,
|
|
9773
11016
|
issuedAt,
|
|
9774
11017
|
expiresAt: issuedAt + this.config.certificateTtlMs,
|
|
9775
11018
|
status: "active"
|
|
@@ -9784,7 +11027,7 @@ var SchemaController = class {
|
|
|
9784
11027
|
try {
|
|
9785
11028
|
await this.mesh.put({
|
|
9786
11029
|
key: entry.key,
|
|
9787
|
-
value: { ...
|
|
11030
|
+
value: { ...record2, status: "verified", updatedAt: Date.now() },
|
|
9788
11031
|
ifVersion: entry.version,
|
|
9789
11032
|
identity: this.identity
|
|
9790
11033
|
});
|
|
@@ -9803,16 +11046,16 @@ var SchemaController = class {
|
|
|
9803
11046
|
this.#activeCertificates.set(certificateRecord.tokenHash, context.parentToolCallId);
|
|
9804
11047
|
try {
|
|
9805
11048
|
await this.#publish("verified", {
|
|
9806
|
-
hypothesisId:
|
|
11049
|
+
hypothesisId: record2.id,
|
|
9807
11050
|
tokenHash: certificateRecord.tokenHash,
|
|
9808
11051
|
results: results.map((result) => ({
|
|
9809
11052
|
kind: result.evidence.kind,
|
|
9810
11053
|
status: result.status,
|
|
9811
11054
|
detail: result.detail
|
|
9812
11055
|
})),
|
|
9813
|
-
state:
|
|
9814
|
-
fingerprint:
|
|
9815
|
-
generation:
|
|
11056
|
+
state: record2.state,
|
|
11057
|
+
fingerprint: record2.fingerprint,
|
|
11058
|
+
generation: record2.generation,
|
|
9816
11059
|
issuedAt,
|
|
9817
11060
|
expiresAt: certificateRecord.expiresAt
|
|
9818
11061
|
});
|
|
@@ -9821,7 +11064,7 @@ var SchemaController = class {
|
|
|
9821
11064
|
context.update(`Schema evidence confirmed; certificate expires in ${this.config.certificateTtlMs}ms`);
|
|
9822
11065
|
return {
|
|
9823
11066
|
verified: true,
|
|
9824
|
-
hypothesisId:
|
|
11067
|
+
hypothesisId: record2.id,
|
|
9825
11068
|
certificate,
|
|
9826
11069
|
issuedAt,
|
|
9827
11070
|
expiresAt: certificateRecord.expiresAt,
|
|
@@ -9840,7 +11083,7 @@ var SchemaController = class {
|
|
|
9840
11083
|
this.#assertPayloadBound(input);
|
|
9841
11084
|
const release = this.#acquireCommitLock();
|
|
9842
11085
|
const transactionId = randomUUID4();
|
|
9843
|
-
const journalPath =
|
|
11086
|
+
const journalPath = path15.join(this.#journalRoot, `${transactionId}.json`);
|
|
9844
11087
|
let journal;
|
|
9845
11088
|
let consumed = false;
|
|
9846
11089
|
let committed = false;
|
|
@@ -10050,12 +11293,12 @@ var SchemaController = class {
|
|
|
10050
11293
|
if (invocation !== parentToolCallId) continue;
|
|
10051
11294
|
const entry = this.mesh.get(`${CERTIFICATE_PREFIX}${tokenHash}`);
|
|
10052
11295
|
if (entry) {
|
|
10053
|
-
const
|
|
10054
|
-
if (
|
|
11296
|
+
const record2 = entry.value;
|
|
11297
|
+
if (record2.status === "active") {
|
|
10055
11298
|
try {
|
|
10056
11299
|
await this.mesh.put({
|
|
10057
11300
|
key: entry.key,
|
|
10058
|
-
value: { ...
|
|
11301
|
+
value: { ...record2, status: "abandoned" },
|
|
10059
11302
|
ifVersion: entry.version,
|
|
10060
11303
|
identity: this.identity
|
|
10061
11304
|
});
|
|
@@ -10069,12 +11312,12 @@ var SchemaController = class {
|
|
|
10069
11312
|
if (invocation !== parentToolCallId) continue;
|
|
10070
11313
|
const entry = this.mesh.get(`${HYPOTHESIS_PREFIX}${hypothesisId}`);
|
|
10071
11314
|
if (entry) {
|
|
10072
|
-
const
|
|
10073
|
-
if (
|
|
11315
|
+
const record2 = entry.value;
|
|
11316
|
+
if (record2.status === "active" || record2.status === "verified") {
|
|
10074
11317
|
try {
|
|
10075
11318
|
await this.mesh.put({
|
|
10076
11319
|
key: entry.key,
|
|
10077
|
-
value: { ...
|
|
11320
|
+
value: { ...record2, status: "abandoned", updatedAt: Date.now() },
|
|
10078
11321
|
ifVersion: entry.version,
|
|
10079
11322
|
identity: this.identity
|
|
10080
11323
|
});
|
|
@@ -10085,16 +11328,16 @@ var SchemaController = class {
|
|
|
10085
11328
|
this.#activeHypotheses.delete(hypothesisId);
|
|
10086
11329
|
}
|
|
10087
11330
|
}
|
|
10088
|
-
async #failedVerification(
|
|
11331
|
+
async #failedVerification(record2, results, reason) {
|
|
10089
11332
|
try {
|
|
10090
11333
|
await this.#publish("verification_failed", {
|
|
10091
|
-
hypothesisId:
|
|
11334
|
+
hypothesisId: record2.id,
|
|
10092
11335
|
reason,
|
|
10093
11336
|
results: results.map((result) => ({ kind: result.evidence.kind, status: result.status, detail: result.detail }))
|
|
10094
11337
|
});
|
|
10095
11338
|
} catch {
|
|
10096
11339
|
}
|
|
10097
|
-
return { verified: false, hypothesisId:
|
|
11340
|
+
return { verified: false, hypothesisId: record2.id, reason, results };
|
|
10098
11341
|
}
|
|
10099
11342
|
async #verifyEvidence(evidence, context) {
|
|
10100
11343
|
if (evidence.length === 0) return [];
|
|
@@ -10321,7 +11564,7 @@ ${Date.now()}
|
|
|
10321
11564
|
}
|
|
10322
11565
|
for (const name of fs8.readdirSync(this.#journalRoot)) {
|
|
10323
11566
|
if (!name.endsWith(".json")) continue;
|
|
10324
|
-
const filePath =
|
|
11567
|
+
const filePath = path15.join(this.#journalRoot, name);
|
|
10325
11568
|
try {
|
|
10326
11569
|
const journal = JSON.parse(fs8.readFileSync(filePath, "utf8"));
|
|
10327
11570
|
if (journal.format !== 1 || journal.status !== "applying" || !Array.isArray(journal.before)) continue;
|
|
@@ -10441,7 +11684,7 @@ var operationSchema = {
|
|
|
10441
11684
|
}
|
|
10442
11685
|
]
|
|
10443
11686
|
};
|
|
10444
|
-
var
|
|
11687
|
+
var descriptors5 = [
|
|
10445
11688
|
{
|
|
10446
11689
|
name: "status",
|
|
10447
11690
|
description: "Read the fixed session Schema mode, transaction bounds, generation, and invocation hypotheses",
|
|
@@ -10511,7 +11754,7 @@ var descriptors4 = [
|
|
|
10511
11754
|
namespace: "schema"
|
|
10512
11755
|
}
|
|
10513
11756
|
];
|
|
10514
|
-
var normalizeSchemaArgs = actionArgNormalizer(() =>
|
|
11757
|
+
var normalizeSchemaArgs = actionArgNormalizer(() => descriptors5);
|
|
10515
11758
|
var SchemaProvider = class {
|
|
10516
11759
|
constructor(controller) {
|
|
10517
11760
|
this.controller = controller;
|
|
@@ -10520,12 +11763,12 @@ var SchemaProvider = class {
|
|
|
10520
11763
|
description = "Host-owned, opt-in Schema verification and bounded local-file transaction control plane";
|
|
10521
11764
|
async list(request, _context) {
|
|
10522
11765
|
const query = request.query?.toLowerCase();
|
|
10523
|
-
return query ?
|
|
11766
|
+
return query ? descriptors5.filter(
|
|
10524
11767
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
10525
|
-
) :
|
|
11768
|
+
) : descriptors5;
|
|
10526
11769
|
}
|
|
10527
11770
|
async describe(actionName, _context) {
|
|
10528
|
-
return
|
|
11771
|
+
return descriptors5.find((descriptor) => descriptor.name === actionName);
|
|
10529
11772
|
}
|
|
10530
11773
|
prepareArguments(actionName, args) {
|
|
10531
11774
|
return normalizeSchemaArgs(actionName, args);
|
|
@@ -10575,11 +11818,11 @@ var SchemaProvider = class {
|
|
|
10575
11818
|
|
|
10576
11819
|
// src/state/store.ts
|
|
10577
11820
|
import { createHash as createHash5 } from "node:crypto";
|
|
10578
|
-
import
|
|
11821
|
+
import path17 from "node:path";
|
|
10579
11822
|
|
|
10580
11823
|
// src/state/complexity.ts
|
|
10581
11824
|
import fs9 from "node:fs";
|
|
10582
|
-
import
|
|
11825
|
+
import path16 from "node:path";
|
|
10583
11826
|
var isWordStart = (character) => character !== void 0 && (character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character === "_" || character === "$");
|
|
10584
11827
|
var isWordPart = (character) => isWordStart(character) || character !== void 0 && character >= "0" && character <= "9";
|
|
10585
11828
|
var regularExpressionPrefixWords = /* @__PURE__ */ new Set([
|
|
@@ -10811,7 +12054,7 @@ var languageComplexities = [
|
|
|
10811
12054
|
typeScriptJavaScriptComplexity
|
|
10812
12055
|
];
|
|
10813
12056
|
var complexityForFile = (file, languages = languageComplexities) => {
|
|
10814
|
-
const extension =
|
|
12057
|
+
const extension = path16.extname(file).toLowerCase();
|
|
10815
12058
|
return languages.find((language) => language.extensions.includes(extension));
|
|
10816
12059
|
};
|
|
10817
12060
|
var countFileComplexity = (file) => {
|
|
@@ -11630,10 +12873,10 @@ var StateStore = class {
|
|
|
11630
12873
|
const currentHead = this.getHead();
|
|
11631
12874
|
const records = [];
|
|
11632
12875
|
for (const event of events) {
|
|
11633
|
-
const
|
|
11634
|
-
if (
|
|
12876
|
+
const record2 = toRecord(event, committedIds);
|
|
12877
|
+
if (record2) records.push(record2);
|
|
11635
12878
|
}
|
|
11636
|
-
if (currentHead && !records.some((
|
|
12879
|
+
if (currentHead && !records.some((record2) => record2.transitionId === currentHead.transitionId)) {
|
|
11637
12880
|
const currentRecord = toHeadRecord(currentHead);
|
|
11638
12881
|
if (currentRecord) records.push(currentRecord);
|
|
11639
12882
|
}
|
|
@@ -11646,7 +12889,7 @@ var StateStore = class {
|
|
|
11646
12889
|
}
|
|
11647
12890
|
}
|
|
11648
12891
|
const visibleRecords = input.includeArchived || lastRepresentation < 0 ? records : records.slice(lastRepresentation);
|
|
11649
|
-
const visibleIds = new Set(visibleRecords.map((
|
|
12892
|
+
const visibleIds = new Set(visibleRecords.map((record2) => record2.transitionId));
|
|
11650
12893
|
const latestOutcomes = latestTransitionOutcomes(events);
|
|
11651
12894
|
const eventCertifications = events.map((event) => toCertificate(event, currentHead, latestOutcomes)).filter((certificate) => certificate !== void 0).filter(
|
|
11652
12895
|
(certificate) => certificate.targets.every((target) => visibleIds.has(target.transitionId))
|
|
@@ -11662,32 +12905,32 @@ var StateStore = class {
|
|
|
11662
12905
|
certifications.map((certificate) => [certificate.sequence, certificate])
|
|
11663
12906
|
);
|
|
11664
12907
|
const latestCertificate = /* @__PURE__ */ new Map();
|
|
11665
|
-
for (const
|
|
11666
|
-
const outcome = latestOutcomes.get(
|
|
12908
|
+
for (const record2 of visibleRecords) {
|
|
12909
|
+
const outcome = latestOutcomes.get(record2.transitionId);
|
|
11667
12910
|
if (outcome?.phase !== "certified") continue;
|
|
11668
12911
|
const certificate = certificatesBySequence.get(outcome.event.sequence);
|
|
11669
|
-
if (certificate) latestCertificate.set(
|
|
12912
|
+
if (certificate) latestCertificate.set(record2.transitionId, certificate);
|
|
11670
12913
|
}
|
|
11671
12914
|
if (durableCertificate) {
|
|
11672
12915
|
latestCertificate.set(currentHead.transitionId, durableCertificate);
|
|
11673
12916
|
}
|
|
11674
12917
|
const archiveBoundaryId = input.includeArchived !== true && lastRepresentation > 0 ? records[lastRepresentation]?.transitionId : void 0;
|
|
11675
12918
|
const filtered = (input.label ? visibleRecords.filter(
|
|
11676
|
-
(
|
|
11677
|
-
) : visibleRecords).map((
|
|
11678
|
-
const certificate = latestCertificate.get(
|
|
11679
|
-
return certificate ? { ...
|
|
12919
|
+
(record2) => record2.label === input.label || record2.to === input.label || record2.from === input.label && record2.transitionId !== archiveBoundaryId
|
|
12920
|
+
) : visibleRecords).map((record2) => {
|
|
12921
|
+
const certificate = latestCertificate.get(record2.transitionId);
|
|
12922
|
+
return certificate ? { ...record2, certificationStatus: "certified", certificate } : record2;
|
|
11680
12923
|
});
|
|
11681
12924
|
const limited = input.limit !== void 0 && input.limit > 0 ? filtered.slice(0, input.limit) : filtered;
|
|
11682
12925
|
const labelSet = /* @__PURE__ */ new Set();
|
|
11683
12926
|
const limitedIds = /* @__PURE__ */ new Set();
|
|
11684
|
-
for (const
|
|
11685
|
-
limitedIds.add(
|
|
11686
|
-
if (
|
|
11687
|
-
labelSet.add(
|
|
12927
|
+
for (const record2 of limited) {
|
|
12928
|
+
limitedIds.add(record2.transitionId);
|
|
12929
|
+
if (record2.from && record2.transitionId !== archiveBoundaryId) {
|
|
12930
|
+
labelSet.add(record2.from);
|
|
11688
12931
|
}
|
|
11689
|
-
labelSet.add(
|
|
11690
|
-
labelSet.add(
|
|
12932
|
+
labelSet.add(record2.to);
|
|
12933
|
+
labelSet.add(record2.label);
|
|
11691
12934
|
}
|
|
11692
12935
|
return {
|
|
11693
12936
|
transitions: limited,
|
|
@@ -11702,7 +12945,7 @@ var StateStore = class {
|
|
|
11702
12945
|
const files = [];
|
|
11703
12946
|
let netDelta = 0;
|
|
11704
12947
|
for (const file of this.normalizeComplexityFiles(requestedFiles, input.cwd)) {
|
|
11705
|
-
const measured = countFileComplexity(
|
|
12948
|
+
const measured = countFileComplexity(path17.resolve(input.cwd, file));
|
|
11706
12949
|
if (!measured) {
|
|
11707
12950
|
files.push({ file, supported: false });
|
|
11708
12951
|
continue;
|
|
@@ -11729,7 +12972,7 @@ var StateStore = class {
|
|
|
11729
12972
|
const updates = [];
|
|
11730
12973
|
let netDelta = 0;
|
|
11731
12974
|
for (const file of this.normalizeComplexityFiles(files, cwd)) {
|
|
11732
|
-
const measured = countFileComplexity(
|
|
12975
|
+
const measured = countFileComplexity(path17.resolve(cwd, file));
|
|
11733
12976
|
if (!measured) {
|
|
11734
12977
|
deltas.push({ file, supported: false });
|
|
11735
12978
|
continue;
|
|
@@ -11779,11 +13022,11 @@ var StateStore = class {
|
|
|
11779
13022
|
const normalized = /* @__PURE__ */ new Set();
|
|
11780
13023
|
for (const file of files) {
|
|
11781
13024
|
if (!file.trim()) continue;
|
|
11782
|
-
const relative =
|
|
11783
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
13025
|
+
const relative = path17.relative(cwd, path17.resolve(cwd, file));
|
|
13026
|
+
if (relative === ".." || relative.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative)) {
|
|
11784
13027
|
throw new Error(`State complexity file must be inside the project cwd: ${file}`);
|
|
11785
13028
|
}
|
|
11786
|
-
normalized.add(relative.split(
|
|
13029
|
+
normalized.add(relative.split(path17.sep).join("/"));
|
|
11787
13030
|
}
|
|
11788
13031
|
return [...normalized];
|
|
11789
13032
|
}
|
|
@@ -11917,7 +13160,7 @@ var StateStore = class {
|
|
|
11917
13160
|
includeArchived: input.includeArchived === true
|
|
11918
13161
|
});
|
|
11919
13162
|
const match = transitions.find(
|
|
11920
|
-
(
|
|
13163
|
+
(record2) => record2.transitionId === verificationHead.transitionId
|
|
11921
13164
|
);
|
|
11922
13165
|
targets = match ? [match] : [];
|
|
11923
13166
|
} else {
|
|
@@ -12225,7 +13468,7 @@ var checkGoalSchema = {
|
|
|
12225
13468
|
additionalProperties: false
|
|
12226
13469
|
};
|
|
12227
13470
|
var emptySchema3 = { type: "object", properties: {}, additionalProperties: false };
|
|
12228
|
-
var
|
|
13471
|
+
var descriptors6 = [
|
|
12229
13472
|
{
|
|
12230
13473
|
name: "transition",
|
|
12231
13474
|
description: "Append a labeled, validated state transition and compare-and-swap advance the head",
|
|
@@ -12276,7 +13519,7 @@ var descriptors5 = [
|
|
|
12276
13519
|
namespace: "state"
|
|
12277
13520
|
}
|
|
12278
13521
|
];
|
|
12279
|
-
var normalizeStateArgs = actionArgNormalizer(() =>
|
|
13522
|
+
var normalizeStateArgs = actionArgNormalizer(() => descriptors6);
|
|
12280
13523
|
var StateProvider = class {
|
|
12281
13524
|
name = "state";
|
|
12282
13525
|
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 +13534,12 @@ var StateProvider = class {
|
|
|
12291
13534
|
}
|
|
12292
13535
|
async list(request, _context) {
|
|
12293
13536
|
const query = request.query?.toLowerCase();
|
|
12294
|
-
return query ?
|
|
13537
|
+
return query ? descriptors6.filter(
|
|
12295
13538
|
(descriptor) => `${descriptor.name} ${descriptor.description}`.toLowerCase().includes(query)
|
|
12296
|
-
) :
|
|
13539
|
+
) : descriptors6;
|
|
12297
13540
|
}
|
|
12298
13541
|
async describe(actionName, _context) {
|
|
12299
|
-
return
|
|
13542
|
+
return descriptors6.find((descriptor) => descriptor.name === actionName);
|
|
12300
13543
|
}
|
|
12301
13544
|
prepareArguments(actionName, args) {
|
|
12302
13545
|
return normalizeStateArgs(actionName, args);
|
|
@@ -12777,7 +14020,7 @@ var FabricRuntimeState = class {
|
|
|
12777
14020
|
this.#mainAgent = mainAgent;
|
|
12778
14021
|
const projectRoot = process.env.OMP_FABRIC_PROJECT_ROOT ?? context.cwd;
|
|
12779
14022
|
const configuredMeshRoot = this.#config.mesh.root;
|
|
12780
|
-
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ?
|
|
14023
|
+
const meshRoot = process.env.OMP_FABRIC_MESH_ROOT ?? (configuredMeshRoot ? path18.resolve(projectRoot, configuredMeshRoot) : path18.join(projectRoot, ".omp", "fabric", "mesh"));
|
|
12781
14024
|
this.#mesh = new MeshStore(
|
|
12782
14025
|
meshRoot,
|
|
12783
14026
|
this.#config.mesh.maxEventBytes,
|
|
@@ -12842,6 +14085,19 @@ var FabricRuntimeState = class {
|
|
|
12842
14085
|
description: "Host context compaction controller",
|
|
12843
14086
|
create: () => new CompactProvider(this.#compact)
|
|
12844
14087
|
}));
|
|
14088
|
+
if (this.#config.codemap.enabled) {
|
|
14089
|
+
const codemapConfig = this.#config.codemap;
|
|
14090
|
+
await installBuiltin(createProviderComponent({
|
|
14091
|
+
provider: "codemap",
|
|
14092
|
+
description: "Structural repo map and git co-change ranking",
|
|
14093
|
+
create: () => new CodemapProvider(codemapConfig)
|
|
14094
|
+
}));
|
|
14095
|
+
} else {
|
|
14096
|
+
this.#registry.markUnavailable(
|
|
14097
|
+
"codemap",
|
|
14098
|
+
'disabled by configuration (codemap.enabled=false); set "codemap": { "enabled": true } in .omp/fabric.json or the agent fabric.json to enable codemap.* actions'
|
|
14099
|
+
);
|
|
14100
|
+
}
|
|
12845
14101
|
const agentConfig = enforceSchema ? { ...this.#config.agents, enabled: false } : this.#config.agents;
|
|
12846
14102
|
const modelsConfig = this.#config.models;
|
|
12847
14103
|
const visibleOmpModels = () => {
|
|
@@ -12938,8 +14194,8 @@ var FabricRuntimeState = class {
|
|
|
12938
14194
|
};
|
|
12939
14195
|
const lineageAlive = (rootId) => this.#participants?.get(rootId) !== void 0;
|
|
12940
14196
|
const actorRoots = {
|
|
12941
|
-
project:
|
|
12942
|
-
session:
|
|
14197
|
+
project: path18.join(meshRoot, "actors"),
|
|
14198
|
+
session: path18.join(meshRoot, "actors", fabricSessionId)
|
|
12943
14199
|
};
|
|
12944
14200
|
const acquireActorCapabilityView = (requirements, signal) => this.#registry.acquireCapabilityView(requirements, {
|
|
12945
14201
|
cwd: context.cwd,
|
|
@@ -13139,6 +14395,7 @@ ${escapeXmlText(text)}
|
|
|
13139
14395
|
...this.#config.mesh.enabled ? ["mesh", "state"] : [],
|
|
13140
14396
|
"schema",
|
|
13141
14397
|
"compact",
|
|
14398
|
+
...this.#config.codemap.enabled ? ["codemap"] : [],
|
|
13142
14399
|
"agents",
|
|
13143
14400
|
...this.#config.memory.enabled ? ["memory"] : []
|
|
13144
14401
|
]);
|
|
@@ -13279,7 +14536,11 @@ ${escapeXmlText(text)}
|
|
|
13279
14536
|
pending,
|
|
13280
14537
|
outerToolResult,
|
|
13281
14538
|
context,
|
|
13282
|
-
(update) => this.activity.updateCall(runId, callId, update)
|
|
14539
|
+
(update) => this.activity.updateCall(runId, callId, update),
|
|
14540
|
+
{
|
|
14541
|
+
handoffRetirement: this.#config?.prewalk.handoffRetirement ?? DEFAULT_FABRIC_CONFIG.prewalk.handoffRetirement,
|
|
14542
|
+
handoffRetirementKeep: this.#config?.prewalk.handoffRetirementKeep ?? DEFAULT_FABRIC_CONFIG.prewalk.handoffRetirementKeep
|
|
14543
|
+
}
|
|
13283
14544
|
);
|
|
13284
14545
|
const succeeded = result.completed === true || result.continued === true;
|
|
13285
14546
|
const error = typeof result.error === "string" ? result.error : void 0;
|