trellis 3.1.35 → 3.2.2
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 +23 -5
- package/README.md +63 -156
- package/bin/trellis.mjs +2 -75
- package/dist/{better-sqlite-backend-ahx5p0br.js → better-sqlite-backend-2P4F6AOJ.js} +91 -29
- package/dist/boot-middleware-MHLHFCUC.js +9 -0
- package/dist/browser/index.d.ts +18 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +95 -0
- package/dist/{index-53f3b8p8.js → chunk-2W3MHTMG.js} +552 -213
- package/dist/chunk-44FFQKQX.js +142 -0
- package/dist/chunk-4HYPLFJD.js +150 -0
- package/dist/chunk-4XIVMVHC.js +361 -0
- package/dist/{index-yp88he8n.js → chunk-6CTA6MCE.js} +88 -64
- package/dist/chunk-6GEZ6DN5.js +394 -0
- package/dist/chunk-7ZFRVCUE.js +211 -0
- package/dist/chunk-CAG4FULI.js +121 -0
- package/dist/chunk-FF36CQHZ.js +61 -0
- package/dist/{index-h32txmxe.js → chunk-FKQO5A3H.js} +6 -13
- package/dist/{index-nq520y6k.js → chunk-FWRS4CSC.js} +46 -32
- package/dist/chunk-GFZCJ4EH.js +108 -0
- package/dist/chunk-GLM4HGN4.js +55 -0
- package/dist/{index-4cdr7x2x.js → chunk-GU374KWZ.js} +182 -111
- package/dist/chunk-H6JB3PZ3.js +45 -0
- package/dist/chunk-IZX2PLIB.js +1240 -0
- package/dist/chunk-J2TXUFCZ.js +289 -0
- package/dist/chunk-J3WYZO3Q.js +211 -0
- package/dist/{index-xzym9w0m.js → chunk-JA7AIHRK.js} +12 -7
- package/dist/chunk-JHHEXEDM.js +162 -0
- package/dist/chunk-JUEMDWLU.js +233 -0
- package/dist/chunk-KFQGP6VL.js +33 -0
- package/dist/chunk-KIJITUZB.js +419 -0
- package/dist/{index-4wxa8xz4.js → chunk-KQ4A2D2P.js} +162 -23
- package/dist/chunk-KSU2GW22.js +958 -0
- package/dist/{index-rv1p47gp.js → chunk-L5N5PR2S.js} +3015 -2480
- package/dist/{index-h9e2efx4.js → chunk-LNUIGRDZ.js} +71 -55
- package/dist/{index-skhn0agf.js → chunk-MLC5BUYO.js} +19 -20
- package/dist/chunk-MPXUVGT3.js +104 -0
- package/dist/chunk-N6MYZT4O.js +68 -0
- package/dist/chunk-O2AV5WMN.js +48 -0
- package/dist/chunk-PZ4XYZ4J.js +143 -0
- package/dist/chunk-QB5ISE47.js +419 -0
- package/dist/chunk-RSWUFTO2.js +857 -0
- package/dist/chunk-S3XLFZ27.js +1095 -0
- package/dist/{index-w5wccer3.js → chunk-S6GBJ2ZB.js} +28 -12
- package/dist/{index-7pjz3tsy.js → chunk-SGMDTWJJ.js} +57 -15
- package/dist/chunk-SPSPV5BC.js +390 -0
- package/dist/chunk-TCKXSOBP.js +123 -0
- package/dist/chunk-UBGUDMUV.js +59 -0
- package/dist/{index-wt8rz4gn.js → chunk-UQISRW6T.js} +97 -26
- package/dist/chunk-USEINYUL.js +12 -0
- package/dist/{index-bmyt7k8n.js → chunk-UZRUP7QW.js} +12 -4
- package/dist/{index-xhcp6xrn.js → chunk-VBYUTRXX.js} +695 -514
- package/dist/{index-vkpkfwhq.js → chunk-VDAKEOML.js} +234 -194
- package/dist/chunk-WXSWA3MV.js +0 -0
- package/dist/{index-n9f2qyh5.js → chunk-X5FLTRUB.js} +55 -33
- package/dist/{index-h7zxhhhh.js → chunk-XMQ7G77X.js} +46 -38
- package/dist/{index-w7ng765c.js → chunk-YCM7ZYEZ.js} +102 -49
- package/dist/cli/deploy-cli.d.ts +18 -0
- package/dist/cli/deploy-cli.d.ts.map +1 -0
- package/dist/cli/errors.d.ts +6 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/examples.d.ts +23 -0
- package/dist/cli/examples.d.ts.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2426 -6225
- package/dist/client/index.browser.d.ts +29 -0
- package/dist/client/index.browser.d.ts.map +1 -0
- package/dist/client/index.browser.js +64 -0
- package/dist/client/index.d.ts +6 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +41 -21
- package/dist/client/live.d.ts +67 -0
- package/dist/client/live.d.ts.map +1 -0
- package/dist/client/reactive.d.ts +31 -0
- package/dist/client/reactive.d.ts.map +1 -0
- package/dist/client/sdk.browser.d.ts +104 -0
- package/dist/client/sdk.browser.d.ts.map +1 -0
- package/dist/client/sdk.browser.js +9 -0
- package/dist/client/sdk.d.ts +26 -2
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +9 -0
- package/dist/client/vcs-client.d.ts +129 -0
- package/dist/client/vcs-client.d.ts.map +1 -0
- package/dist/cms/index.js +171 -163
- package/dist/{config-8hczw0rs.js → config-PFTP67TR.js} +8 -9
- package/dist/core/computation/index.d.ts +5 -0
- package/dist/core/computation/index.d.ts.map +1 -0
- package/dist/core/computation/rollup.d.ts +18 -0
- package/dist/core/computation/rollup.d.ts.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +171 -104
- package/dist/core/kernel/boot-middleware.d.ts +10 -0
- package/dist/core/kernel/boot-middleware.d.ts.map +1 -0
- package/dist/core/kernel/logic-middleware.d.ts +7 -1
- package/dist/core/kernel/logic-middleware.d.ts.map +1 -1
- package/dist/core/kernel/trellis-kernel.d.ts.map +1 -1
- package/dist/core/ontology/types.d.ts +5 -0
- package/dist/core/ontology/types.d.ts.map +1 -1
- package/dist/core/persist/better-sqlite-backend.d.ts +9 -2
- package/dist/core/persist/better-sqlite-backend.d.ts.map +1 -1
- package/dist/core/persist/factory.d.ts +6 -7
- package/dist/core/persist/factory.d.ts.map +1 -1
- package/dist/core/persist/factory.js +2 -3
- package/dist/core/persist/sqljs-backend.js +2 -3
- package/dist/db/index.d.ts +4 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +67 -54
- package/dist/db/inspector.js +11 -19
- package/dist/db/trellis.css +1 -1
- package/dist/decisions/index.js +9 -10
- package/dist/deploy-LQ7GUGJ5.js +9 -0
- package/dist/deploy-YNVG5E4E.js +9 -0
- package/dist/deploy-cli-24BCHAXY.js +67 -0
- package/dist/deploy-cli-C35HTITO.js +67 -0
- package/dist/embeddings/auto-embed.d.ts +2 -2
- package/dist/embeddings/auto-embed.d.ts.map +1 -1
- package/dist/embeddings/index.js +20 -22
- package/dist/embeddings/search.d.ts +2 -1
- package/dist/embeddings/search.d.ts.map +1 -1
- package/dist/embeddings/store.d.ts +25 -4
- package/dist/embeddings/store.d.ts.map +1 -1
- package/dist/engine.d.ts +59 -19
- package/dist/engine.d.ts.map +1 -1
- package/dist/import-UZEKXU3B.js +10 -0
- package/dist/index.js +102 -93
- package/dist/launch-explorer-HZ4ZJA4X.js +95 -0
- package/dist/links/index.js +24 -26
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/plugins/agent-memory/index.js +316 -0
- package/dist/plugins/idea-garden/index.js +165 -0
- package/dist/plugins/plan-approval/index.js +579 -0
- package/dist/plugins/proactive-watcher/index.js +194 -0
- package/dist/{index-2r4jxwnb.js → query-XYLTJYSA.js} +14 -15
- package/dist/react/index.js +39 -70
- package/dist/react/realtime.js +11 -0
- package/dist/react/schema-hooks.js +87 -0
- package/dist/realtime/broadcast-channel-transport.d.ts +43 -0
- package/dist/realtime/broadcast-channel-transport.d.ts.map +1 -0
- package/dist/realtime/durable-object-relay-transport.d.ts +96 -0
- package/dist/realtime/durable-object-relay-transport.d.ts.map +1 -0
- package/dist/realtime/index.d.ts +44 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +40 -0
- package/dist/realtime/memory-hub.d.ts +32 -0
- package/dist/realtime/memory-hub.d.ts.map +1 -0
- package/dist/realtime/persistent-channel.d.ts +105 -0
- package/dist/realtime/persistent-channel.d.ts.map +1 -0
- package/dist/realtime/presence.d.ts +73 -0
- package/dist/realtime/presence.d.ts.map +1 -0
- package/dist/realtime/relay-persistence.d.ts +37 -0
- package/dist/realtime/relay-persistence.d.ts.map +1 -0
- package/dist/realtime/relay-persistence.js +107 -0
- package/dist/realtime/relay-server.d.ts +103 -0
- package/dist/realtime/relay-server.d.ts.map +1 -0
- package/dist/realtime/room.d.ts +98 -0
- package/dist/realtime/room.d.ts.map +1 -0
- package/dist/realtime/text.d.ts +73 -0
- package/dist/realtime/text.d.ts.map +1 -0
- package/dist/realtime/types.d.ts +89 -0
- package/dist/realtime/types.d.ts.map +1 -0
- package/dist/realtime/websocket-relay-transport.d.ts +28 -0
- package/dist/realtime/websocket-relay-transport.d.ts.map +1 -0
- package/dist/realtime.bundle.js +1100 -0
- package/dist/{remote-manager-xvbg4230.js → remote-manager-ODE3T2KR.js} +25 -15
- package/dist/scaffold/seed.d.ts.map +1 -1
- package/dist/scaffold/write.d.ts +1 -1
- package/dist/scaffold/write.d.ts.map +1 -1
- package/dist/schema/define.d.ts +137 -0
- package/dist/schema/define.d.ts.map +1 -0
- package/dist/schema/entity-projection.d.ts +34 -0
- package/dist/schema/entity-projection.d.ts.map +1 -0
- package/dist/schema/eql.d.ts +46 -0
- package/dist/schema/eql.d.ts.map +1 -0
- package/dist/schema/index.d.ts +21 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +46 -0
- package/dist/schema/kernel-resolve.d.ts +21 -0
- package/dist/schema/kernel-resolve.d.ts.map +1 -0
- package/dist/schema/mutations.d.ts +20 -0
- package/dist/schema/mutations.d.ts.map +1 -0
- package/dist/schema/resolve.d.ts +21 -0
- package/dist/schema/resolve.d.ts.map +1 -0
- package/dist/server/deploy-meta.d.ts +25 -0
- package/dist/server/deploy-meta.d.ts.map +1 -0
- package/dist/server/deploy.d.ts +7 -2
- package/dist/server/deploy.d.ts.map +1 -1
- package/dist/server/index.d.ts +7 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +100 -58
- package/dist/server/node-adapter.js +5 -104
- package/dist/server/realtime.d.ts +14 -3
- package/dist/server/realtime.d.ts.map +1 -1
- package/dist/server/server.d.ts +8 -16
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/sprites.d.ts +18 -1
- package/dist/server/sprites.d.ts.map +1 -1
- package/dist/server/tenancy.d.ts +4 -0
- package/dist/server/tenancy.d.ts.map +1 -1
- package/dist/server/usage-meter.d.ts +53 -0
- package/dist/server/usage-meter.d.ts.map +1 -0
- package/dist/server-MB3OPSPI.js +18 -0
- package/dist/server-ZVWGLLRF.js +18 -0
- package/dist/sprites-KQGTGM6W.js +27 -0
- package/dist/{sprites-vc4qbrp1.js → sprites-RU3E4XQN.js} +6 -7
- package/dist/svelte/index.d.ts +17 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +51 -0
- package/dist/svelte/schema-hooks.d.ts +45 -0
- package/dist/svelte/schema-hooks.d.ts.map +1 -0
- package/dist/svelte/schema-hooks.js +71 -0
- package/dist/svelte/stores.d.ts +78 -0
- package/dist/svelte/stores.d.ts.map +1 -0
- package/dist/sync/http-transport.d.ts +3 -3
- package/dist/sync/http-transport.d.ts.map +1 -1
- package/dist/sync/index.d.ts +15 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +617 -0
- package/dist/sync/memory-room.d.ts +37 -0
- package/dist/sync/memory-room.d.ts.map +1 -0
- package/dist/sync/memory-transport.d.ts +3 -3
- package/dist/sync/memory-transport.d.ts.map +1 -1
- package/dist/sync/partykit-room.d.ts +40 -0
- package/dist/sync/partykit-room.d.ts.map +1 -0
- package/dist/sync/partykit-transport.d.ts +84 -0
- package/dist/sync/partykit-transport.d.ts.map +1 -0
- package/dist/sync/room-core.d.ts +53 -0
- package/dist/sync/room-core.d.ts.map +1 -0
- package/dist/sync/sync-engine.d.ts +40 -2
- package/dist/sync/sync-engine.d.ts.map +1 -1
- package/dist/sync/sync-room-server.d.ts +39 -0
- package/dist/sync/sync-room-server.d.ts.map +1 -0
- package/dist/sync/types.d.ts +70 -3
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/sync/vcs-sync-peer.d.ts +63 -0
- package/dist/sync/vcs-sync-peer.d.ts.map +1 -0
- package/dist/sync/ws-transport.d.ts +2 -2
- package/dist/sync/ws-transport.d.ts.map +1 -1
- package/dist/tenancy-NBLLGCNJ.js +14 -0
- package/dist/tenancy-POMWQP6M.js +16 -0
- package/dist/ui/client.html +355 -67
- package/dist/ui/launch-explorer.d.ts +22 -0
- package/dist/ui/launch-explorer.d.ts.map +1 -0
- package/dist/ui/server.d.ts +1 -1
- package/dist/ui/server.d.ts.map +1 -1
- package/dist/vcs/blob-store.d.ts.map +1 -1
- package/dist/vcs/idb-op-log.d.ts +67 -0
- package/dist/vcs/idb-op-log.d.ts.map +1 -0
- package/dist/vcs/index.d.ts +1 -0
- package/dist/vcs/index.d.ts.map +1 -1
- package/dist/vcs/index.js +81 -72
- package/dist/vcs/issue.d.ts +22 -5
- package/dist/vcs/issue.d.ts.map +1 -1
- package/dist/vcs/lane-materialize.d.ts +5 -0
- package/dist/vcs/lane-materialize.d.ts.map +1 -1
- package/dist/vcs/op-log.d.ts +28 -2
- package/dist/vcs/op-log.d.ts.map +1 -1
- package/dist/vcs/ops.d.ts +10 -0
- package/dist/vcs/ops.d.ts.map +1 -1
- package/dist/vcs/types.d.ts +2 -0
- package/dist/vcs/types.d.ts.map +1 -1
- package/dist/{vm-config-6xhsj6b3.js → vm-config-JI4OXKDQ.js} +9 -10
- package/dist/vue/hooks.d.ts +64 -0
- package/dist/vue/hooks.d.ts.map +1 -0
- package/dist/vue/index.d.ts +19 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +59 -0
- package/dist/vue/schema-hooks.d.ts +41 -0
- package/dist/vue/schema-hooks.d.ts.map +1 -0
- package/dist/vue/schema-hooks.js +64 -0
- package/package.json +130 -17
- package/dist/deploy-999q207z.js +0 -10
- package/dist/engine-y0724kjq.js +0 -8
- package/dist/import-s2b8e0ft.js +0 -11
- package/dist/index-a76rekgs.js +0 -67
- package/dist/index-c9h37r6h.js +0 -1
- package/dist/index-hr9qvv77.js +0 -860
- package/dist/index-k5b0xskw.js +0 -1
- package/dist/index-nzb3am4f.js +0 -80
- package/dist/index-wncptktd.js +0 -292
- package/dist/index-y6a4kj0p.js +0 -43
- package/dist/index-yhwjgfvj.js +0 -342
- package/dist/sdk-bepky0xs.js +0 -16
- package/dist/server-szdjx0nt.js +0 -13
- package/dist/sqlite-backend-0vsmc6qj.js +0 -8
- package/dist/tenancy-pjm32b4v.js +0 -14
|
@@ -1,33 +1,32 @@
|
|
|
1
|
-
// @bun
|
|
2
1
|
import {
|
|
3
|
-
createVcsOp,
|
|
4
2
|
criterionEntityId,
|
|
5
3
|
decisionEntityId,
|
|
6
4
|
dirEntityId,
|
|
7
5
|
fileEntityId,
|
|
8
|
-
init_ops,
|
|
9
6
|
init_types,
|
|
10
7
|
issueEntityId,
|
|
11
8
|
laneEntityId
|
|
12
|
-
} from "./
|
|
9
|
+
} from "./chunk-N6MYZT4O.js";
|
|
10
|
+
import {
|
|
11
|
+
createVcsOp,
|
|
12
|
+
init_ops
|
|
13
|
+
} from "./chunk-GLM4HGN4.js";
|
|
13
14
|
import {
|
|
14
15
|
__esm,
|
|
15
16
|
__require
|
|
16
|
-
} from "./
|
|
17
|
+
} from "./chunk-KFQGP6VL.js";
|
|
17
18
|
|
|
18
19
|
// src/vcs/decompose.ts
|
|
19
20
|
import { dirname } from "path";
|
|
20
21
|
function pickFacts(input) {
|
|
21
|
-
if (!Array.isArray(input))
|
|
22
|
-
return [];
|
|
22
|
+
if (!Array.isArray(input)) return [];
|
|
23
23
|
return input.filter((item) => {
|
|
24
24
|
const fact = item;
|
|
25
25
|
return typeof fact.e === "string" && typeof fact.a === "string" && (typeof fact.v === "string" || typeof fact.v === "number" || typeof fact.v === "boolean");
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
function pickLinks(input) {
|
|
29
|
-
if (!Array.isArray(input))
|
|
30
|
-
return [];
|
|
29
|
+
if (!Array.isArray(input)) return [];
|
|
31
30
|
return input.filter((item) => {
|
|
32
31
|
const link = item;
|
|
33
32
|
return typeof link.e1 === "string" && typeof link.a === "string" && typeof link.e2 === "string";
|
|
@@ -41,8 +40,7 @@ function decompose(op) {
|
|
|
41
40
|
deleteLinks: []
|
|
42
41
|
};
|
|
43
42
|
const vcs = op.vcs;
|
|
44
|
-
if (!vcs)
|
|
45
|
-
return result;
|
|
43
|
+
if (!vcs) return result;
|
|
46
44
|
if (vcs.issueId && vcs.oldIssueStatus) {
|
|
47
45
|
result.deleteFacts.push({
|
|
48
46
|
e: issueEntityId(vcs.issueId),
|
|
@@ -52,29 +50,33 @@ function decompose(op) {
|
|
|
52
50
|
}
|
|
53
51
|
switch (op.kind) {
|
|
54
52
|
case "vcs:fileAdd": {
|
|
55
|
-
if (!vcs.filePath)
|
|
56
|
-
break;
|
|
53
|
+
if (!vcs.filePath) break;
|
|
57
54
|
const eid = fileEntityId(vcs.filePath);
|
|
58
55
|
const dir = dirname(vcs.filePath);
|
|
59
56
|
const did = dirEntityId(dir === "." ? "" : dir);
|
|
60
|
-
result.addFacts.push(
|
|
57
|
+
result.addFacts.push(
|
|
58
|
+
{ e: eid, a: "type", v: "FileNode" },
|
|
59
|
+
{ e: eid, a: "path", v: vcs.filePath }
|
|
60
|
+
);
|
|
61
61
|
if (vcs.contentHash) {
|
|
62
62
|
result.addFacts.push({ e: eid, a: "contentHash", v: vcs.contentHash });
|
|
63
63
|
}
|
|
64
|
-
if (vcs.size !==
|
|
64
|
+
if (vcs.size !== void 0) {
|
|
65
65
|
result.addFacts.push({ e: eid, a: "size", v: vcs.size });
|
|
66
66
|
}
|
|
67
67
|
if (vcs.language) {
|
|
68
68
|
result.addFacts.push({ e: eid, a: "language", v: vcs.language });
|
|
69
69
|
}
|
|
70
70
|
result.addFacts.push({ e: eid, a: "lastModified", v: op.timestamp });
|
|
71
|
-
result.addFacts.push(
|
|
71
|
+
result.addFacts.push(
|
|
72
|
+
{ e: did, a: "type", v: "DirectoryNode" },
|
|
73
|
+
{ e: did, a: "path", v: dir === "." ? "" : dir }
|
|
74
|
+
);
|
|
72
75
|
result.addLinks.push({ e1: did, a: "contains", e2: eid });
|
|
73
76
|
break;
|
|
74
77
|
}
|
|
75
78
|
case "vcs:fileModify": {
|
|
76
|
-
if (!vcs.filePath)
|
|
77
|
-
break;
|
|
79
|
+
if (!vcs.filePath) break;
|
|
78
80
|
const eid = fileEntityId(vcs.filePath);
|
|
79
81
|
if (vcs.oldContentHash) {
|
|
80
82
|
result.deleteFacts.push({
|
|
@@ -86,19 +88,21 @@ function decompose(op) {
|
|
|
86
88
|
if (vcs.contentHash) {
|
|
87
89
|
result.addFacts.push({ e: eid, a: "contentHash", v: vcs.contentHash });
|
|
88
90
|
}
|
|
89
|
-
if (vcs.size !==
|
|
91
|
+
if (vcs.size !== void 0) {
|
|
90
92
|
result.addFacts.push({ e: eid, a: "size", v: vcs.size });
|
|
91
93
|
}
|
|
92
94
|
result.addFacts.push({ e: eid, a: "lastModified", v: op.timestamp });
|
|
93
95
|
break;
|
|
94
96
|
}
|
|
95
97
|
case "vcs:fileDelete": {
|
|
96
|
-
if (!vcs.filePath)
|
|
97
|
-
break;
|
|
98
|
+
if (!vcs.filePath) break;
|
|
98
99
|
const eid = fileEntityId(vcs.filePath);
|
|
99
100
|
const dir = dirname(vcs.filePath);
|
|
100
101
|
const did = dirEntityId(dir === "." ? "" : dir);
|
|
101
|
-
result.deleteFacts.push(
|
|
102
|
+
result.deleteFacts.push(
|
|
103
|
+
{ e: eid, a: "type", v: "FileNode" },
|
|
104
|
+
{ e: eid, a: "path", v: vcs.filePath }
|
|
105
|
+
);
|
|
102
106
|
if (vcs.contentHash) {
|
|
103
107
|
result.deleteFacts.push({
|
|
104
108
|
e: eid,
|
|
@@ -110,8 +114,7 @@ function decompose(op) {
|
|
|
110
114
|
break;
|
|
111
115
|
}
|
|
112
116
|
case "vcs:fileRename": {
|
|
113
|
-
if (!vcs.filePath || !vcs.oldFilePath)
|
|
114
|
-
break;
|
|
117
|
+
if (!vcs.filePath || !vcs.oldFilePath) break;
|
|
115
118
|
const eid = fileEntityId(vcs.oldFilePath);
|
|
116
119
|
const oldDir = dirname(vcs.oldFilePath);
|
|
117
120
|
const newDir = dirname(vcs.filePath);
|
|
@@ -121,15 +124,22 @@ function decompose(op) {
|
|
|
121
124
|
result.addFacts.push({ e: eid, a: "path", v: vcs.filePath });
|
|
122
125
|
result.addFacts.push({ e: eid, a: "lastModified", v: op.timestamp });
|
|
123
126
|
result.deleteLinks.push({ e1: oldDid, a: "contains", e2: eid });
|
|
124
|
-
result.addFacts.push(
|
|
127
|
+
result.addFacts.push(
|
|
128
|
+
{ e: newDid, a: "type", v: "DirectoryNode" },
|
|
129
|
+
{ e: newDid, a: "path", v: newDir === "." ? "" : newDir }
|
|
130
|
+
);
|
|
125
131
|
result.addLinks.push({ e1: newDid, a: "contains", e2: eid });
|
|
126
132
|
break;
|
|
127
133
|
}
|
|
128
134
|
case "vcs:branchCreate": {
|
|
129
|
-
if (!vcs.branchName)
|
|
130
|
-
break;
|
|
135
|
+
if (!vcs.branchName) break;
|
|
131
136
|
const bid = `branch:${vcs.branchName}`;
|
|
132
|
-
result.addFacts.push(
|
|
137
|
+
result.addFacts.push(
|
|
138
|
+
{ e: bid, a: "type", v: "Branch" },
|
|
139
|
+
{ e: bid, a: "name", v: vcs.branchName },
|
|
140
|
+
{ e: bid, a: "createdAt", v: op.timestamp },
|
|
141
|
+
{ e: bid, a: "createdBy", v: op.agentId }
|
|
142
|
+
);
|
|
133
143
|
if (vcs.targetOpHash) {
|
|
134
144
|
result.addFacts.push({ e: bid, a: "headOpHash", v: vcs.targetOpHash });
|
|
135
145
|
}
|
|
@@ -143,24 +153,28 @@ function decompose(op) {
|
|
|
143
153
|
break;
|
|
144
154
|
}
|
|
145
155
|
case "vcs:branchDelete": {
|
|
146
|
-
if (!vcs.branchName)
|
|
147
|
-
break;
|
|
156
|
+
if (!vcs.branchName) break;
|
|
148
157
|
const bid = `branch:${vcs.branchName}`;
|
|
149
|
-
result.deleteFacts.push(
|
|
158
|
+
result.deleteFacts.push(
|
|
159
|
+
{ e: bid, a: "type", v: "Branch" },
|
|
160
|
+
{ e: bid, a: "name", v: vcs.branchName }
|
|
161
|
+
);
|
|
150
162
|
break;
|
|
151
163
|
}
|
|
152
164
|
case "vcs:branchAdvance": {
|
|
153
|
-
if (!vcs.branchName || !vcs.targetOpHash)
|
|
154
|
-
break;
|
|
165
|
+
if (!vcs.branchName || !vcs.targetOpHash) break;
|
|
155
166
|
const bid = `branch:${vcs.branchName}`;
|
|
156
167
|
result.addFacts.push({ e: bid, a: "headOpHash", v: vcs.targetOpHash });
|
|
157
168
|
break;
|
|
158
169
|
}
|
|
159
170
|
case "vcs:milestoneCreate": {
|
|
160
|
-
if (!vcs.milestoneId)
|
|
161
|
-
break;
|
|
171
|
+
if (!vcs.milestoneId) break;
|
|
162
172
|
const mid = vcs.milestoneId;
|
|
163
|
-
result.addFacts.push(
|
|
173
|
+
result.addFacts.push(
|
|
174
|
+
{ e: mid, a: "type", v: "Milestone" },
|
|
175
|
+
{ e: mid, a: "createdAt", v: op.timestamp },
|
|
176
|
+
{ e: mid, a: "createdBy", v: op.agentId }
|
|
177
|
+
);
|
|
164
178
|
if (vcs.message) {
|
|
165
179
|
result.addFacts.push({ e: mid, a: "message", v: vcs.message });
|
|
166
180
|
}
|
|
@@ -174,17 +188,26 @@ function decompose(op) {
|
|
|
174
188
|
}
|
|
175
189
|
case "vcs:checkpointCreate": {
|
|
176
190
|
const cid = `checkpoint:${op.hash}`;
|
|
177
|
-
result.addFacts.push(
|
|
191
|
+
result.addFacts.push(
|
|
192
|
+
{ e: cid, a: "type", v: "Checkpoint" },
|
|
193
|
+
{ e: cid, a: "createdAt", v: op.timestamp },
|
|
194
|
+
{ e: cid, a: "atOpHash", v: op.hash }
|
|
195
|
+
);
|
|
178
196
|
if (vcs.trigger) {
|
|
179
197
|
result.addFacts.push({ e: cid, a: "trigger", v: vcs.trigger });
|
|
180
198
|
}
|
|
181
199
|
break;
|
|
182
200
|
}
|
|
201
|
+
// ----- Issue tracking -----
|
|
183
202
|
case "vcs:issueCreate": {
|
|
184
|
-
if (!vcs.issueId)
|
|
185
|
-
break;
|
|
203
|
+
if (!vcs.issueId) break;
|
|
186
204
|
const eid = issueEntityId(vcs.issueId);
|
|
187
|
-
result.addFacts.push(
|
|
205
|
+
result.addFacts.push(
|
|
206
|
+
{ e: eid, a: "type", v: "Issue" },
|
|
207
|
+
{ e: eid, a: "status", v: vcs.issueStatus ?? "backlog" },
|
|
208
|
+
{ e: eid, a: "createdAt", v: op.timestamp },
|
|
209
|
+
{ e: eid, a: "createdBy", v: op.agentId }
|
|
210
|
+
);
|
|
188
211
|
if (vcs.issueTitle) {
|
|
189
212
|
result.addFacts.push({ e: eid, a: "title", v: vcs.issueTitle });
|
|
190
213
|
}
|
|
@@ -218,8 +241,7 @@ function decompose(op) {
|
|
|
218
241
|
break;
|
|
219
242
|
}
|
|
220
243
|
case "vcs:issueUpdate": {
|
|
221
|
-
if (!vcs.issueId)
|
|
222
|
-
break;
|
|
244
|
+
if (!vcs.issueId) break;
|
|
223
245
|
const eid = issueEntityId(vcs.issueId);
|
|
224
246
|
if (vcs.issueStatus) {
|
|
225
247
|
result.addFacts.push({ e: eid, a: "status", v: vcs.issueStatus });
|
|
@@ -240,7 +262,7 @@ function decompose(op) {
|
|
|
240
262
|
if (vcs.issueAssignee) {
|
|
241
263
|
result.addFacts.push({ e: eid, a: "assignee", v: vcs.issueAssignee });
|
|
242
264
|
}
|
|
243
|
-
if (vcs.issueDescription !==
|
|
265
|
+
if (vcs.issueDescription !== void 0) {
|
|
244
266
|
result.addFacts.push({
|
|
245
267
|
e: eid,
|
|
246
268
|
a: "description",
|
|
@@ -264,10 +286,12 @@ function decompose(op) {
|
|
|
264
286
|
break;
|
|
265
287
|
}
|
|
266
288
|
case "vcs:issueStart": {
|
|
267
|
-
if (!vcs.issueId)
|
|
268
|
-
break;
|
|
289
|
+
if (!vcs.issueId) break;
|
|
269
290
|
const eid = issueEntityId(vcs.issueId);
|
|
270
|
-
result.addFacts.push(
|
|
291
|
+
result.addFacts.push(
|
|
292
|
+
{ e: eid, a: "status", v: "in_progress" },
|
|
293
|
+
{ e: eid, a: "startedAt", v: op.timestamp }
|
|
294
|
+
);
|
|
271
295
|
if (vcs.issueAssignee) {
|
|
272
296
|
result.addFacts.push({ e: eid, a: "assignee", v: vcs.issueAssignee });
|
|
273
297
|
}
|
|
@@ -281,41 +305,50 @@ function decompose(op) {
|
|
|
281
305
|
break;
|
|
282
306
|
}
|
|
283
307
|
case "vcs:issuePause": {
|
|
284
|
-
if (!vcs.issueId)
|
|
285
|
-
break;
|
|
308
|
+
if (!vcs.issueId) break;
|
|
286
309
|
const eid = issueEntityId(vcs.issueId);
|
|
287
|
-
result.addFacts.push(
|
|
310
|
+
result.addFacts.push(
|
|
311
|
+
{ e: eid, a: "status", v: "paused" },
|
|
312
|
+
{ e: eid, a: "pausedAt", v: op.timestamp }
|
|
313
|
+
);
|
|
288
314
|
if (vcs.pauseNote) {
|
|
289
315
|
result.addFacts.push({ e: eid, a: "pauseNote", v: vcs.pauseNote });
|
|
290
316
|
}
|
|
291
317
|
break;
|
|
292
318
|
}
|
|
293
319
|
case "vcs:issueResume": {
|
|
294
|
-
if (!vcs.issueId)
|
|
295
|
-
break;
|
|
320
|
+
if (!vcs.issueId) break;
|
|
296
321
|
const eid = issueEntityId(vcs.issueId);
|
|
297
|
-
result.addFacts.push(
|
|
322
|
+
result.addFacts.push(
|
|
323
|
+
{ e: eid, a: "status", v: "in_progress" },
|
|
324
|
+
{ e: eid, a: "resumedAt", v: op.timestamp },
|
|
325
|
+
{ e: eid, a: "pauseNote", v: "" }
|
|
326
|
+
);
|
|
298
327
|
break;
|
|
299
328
|
}
|
|
300
329
|
case "vcs:issueClose": {
|
|
301
|
-
if (!vcs.issueId)
|
|
302
|
-
break;
|
|
330
|
+
if (!vcs.issueId) break;
|
|
303
331
|
const eid = issueEntityId(vcs.issueId);
|
|
304
|
-
result.addFacts.push(
|
|
332
|
+
result.addFacts.push(
|
|
333
|
+
{ e: eid, a: "status", v: "closed" },
|
|
334
|
+
{ e: eid, a: "closedAt", v: op.timestamp }
|
|
335
|
+
);
|
|
305
336
|
break;
|
|
306
337
|
}
|
|
307
338
|
case "vcs:issueReopen": {
|
|
308
|
-
if (!vcs.issueId)
|
|
309
|
-
break;
|
|
339
|
+
if (!vcs.issueId) break;
|
|
310
340
|
const eid = issueEntityId(vcs.issueId);
|
|
311
341
|
result.addFacts.push({ e: eid, a: "status", v: "queue" });
|
|
312
342
|
break;
|
|
313
343
|
}
|
|
314
344
|
case "vcs:criterionAdd": {
|
|
315
|
-
if (!vcs.criterionId || !vcs.issueId)
|
|
316
|
-
break;
|
|
345
|
+
if (!vcs.criterionId || !vcs.issueId) break;
|
|
317
346
|
const ceid = vcs.criterionId;
|
|
318
|
-
result.addFacts.push(
|
|
347
|
+
result.addFacts.push(
|
|
348
|
+
{ e: ceid, a: "type", v: "Criterion" },
|
|
349
|
+
{ e: ceid, a: "status", v: "pending" },
|
|
350
|
+
{ e: ceid, a: "createdAt", v: op.timestamp }
|
|
351
|
+
);
|
|
319
352
|
if (vcs.criterionDescription) {
|
|
320
353
|
result.addFacts.push({
|
|
321
354
|
e: ceid,
|
|
@@ -338,8 +371,7 @@ function decompose(op) {
|
|
|
338
371
|
break;
|
|
339
372
|
}
|
|
340
373
|
case "vcs:criterionUpdate": {
|
|
341
|
-
if (!vcs.criterionId)
|
|
342
|
-
break;
|
|
374
|
+
if (!vcs.criterionId) break;
|
|
343
375
|
const ceid = vcs.criterionId;
|
|
344
376
|
if (vcs.criterionStatus) {
|
|
345
377
|
result.addFacts.push({ e: ceid, a: "status", v: vcs.criterionStatus });
|
|
@@ -354,27 +386,30 @@ function decompose(op) {
|
|
|
354
386
|
result.addFacts.push({ e: ceid, a: "lastRunAt", v: op.timestamp });
|
|
355
387
|
break;
|
|
356
388
|
}
|
|
389
|
+
// ----- Issue blocking -----
|
|
357
390
|
case "vcs:issueBlock": {
|
|
358
|
-
if (!vcs.issueId || !vcs.blockedByIssueId)
|
|
359
|
-
break;
|
|
391
|
+
if (!vcs.issueId || !vcs.blockedByIssueId) break;
|
|
360
392
|
const eid = issueEntityId(vcs.issueId);
|
|
361
393
|
const blockerEid = issueEntityId(vcs.blockedByIssueId);
|
|
362
394
|
result.addLinks.push({ e1: eid, a: "blockedBy", e2: blockerEid });
|
|
363
395
|
break;
|
|
364
396
|
}
|
|
365
397
|
case "vcs:issueUnblock": {
|
|
366
|
-
if (!vcs.issueId || !vcs.blockedByIssueId)
|
|
367
|
-
break;
|
|
398
|
+
if (!vcs.issueId || !vcs.blockedByIssueId) break;
|
|
368
399
|
const eid = issueEntityId(vcs.issueId);
|
|
369
400
|
const blockerEid = issueEntityId(vcs.blockedByIssueId);
|
|
370
401
|
result.deleteLinks.push({ e1: eid, a: "blockedBy", e2: blockerEid });
|
|
371
402
|
break;
|
|
372
403
|
}
|
|
404
|
+
// ----- Decision traces -----
|
|
373
405
|
case "vcs:decisionRecord": {
|
|
374
|
-
if (!vcs.decisionId)
|
|
375
|
-
break;
|
|
406
|
+
if (!vcs.decisionId) break;
|
|
376
407
|
const did = decisionEntityId(vcs.decisionId);
|
|
377
|
-
result.addFacts.push(
|
|
408
|
+
result.addFacts.push(
|
|
409
|
+
{ e: did, a: "type", v: "Decision" },
|
|
410
|
+
{ e: did, a: "createdAt", v: op.timestamp },
|
|
411
|
+
{ e: did, a: "createdBy", v: op.agentId }
|
|
412
|
+
);
|
|
378
413
|
if (vcs.decisionToolName) {
|
|
379
414
|
result.addFacts.push({
|
|
380
415
|
e: did,
|
|
@@ -416,10 +451,14 @@ function decompose(op) {
|
|
|
416
451
|
break;
|
|
417
452
|
}
|
|
418
453
|
case "vcs:laneCreate": {
|
|
419
|
-
if (!vcs.laneId)
|
|
420
|
-
break;
|
|
454
|
+
if (!vcs.laneId) break;
|
|
421
455
|
const lid = laneEntityId(vcs.laneId);
|
|
422
|
-
result.addFacts.push(
|
|
456
|
+
result.addFacts.push(
|
|
457
|
+
{ e: lid, a: "type", v: "AgentLane" },
|
|
458
|
+
{ e: lid, a: "status", v: "active" },
|
|
459
|
+
{ e: lid, a: "createdAt", v: op.timestamp },
|
|
460
|
+
{ e: lid, a: "createdBy", v: op.agentId }
|
|
461
|
+
);
|
|
423
462
|
if (vcs.baseBranch) {
|
|
424
463
|
result.addFacts.push({ e: lid, a: "baseBranch", v: vcs.baseBranch });
|
|
425
464
|
}
|
|
@@ -459,8 +498,7 @@ function decompose(op) {
|
|
|
459
498
|
break;
|
|
460
499
|
}
|
|
461
500
|
case "vcs:laneDrop": {
|
|
462
|
-
if (!vcs.laneId)
|
|
463
|
-
break;
|
|
501
|
+
if (!vcs.laneId) break;
|
|
464
502
|
const lid = laneEntityId(vcs.laneId);
|
|
465
503
|
if (vcs.laneStatus) {
|
|
466
504
|
result.deleteFacts.push({ e: lid, a: "status", v: "active" });
|
|
@@ -469,16 +507,14 @@ function decompose(op) {
|
|
|
469
507
|
break;
|
|
470
508
|
}
|
|
471
509
|
case "vcs:lanePromoteStart": {
|
|
472
|
-
if (!vcs.laneId)
|
|
473
|
-
break;
|
|
510
|
+
if (!vcs.laneId) break;
|
|
474
511
|
const lid = laneEntityId(vcs.laneId);
|
|
475
512
|
result.deleteFacts.push({ e: lid, a: "status", v: "active" });
|
|
476
513
|
result.addFacts.push({ e: lid, a: "status", v: "promoting" });
|
|
477
514
|
break;
|
|
478
515
|
}
|
|
479
516
|
case "vcs:lanePromoteComplete": {
|
|
480
|
-
if (!vcs.laneId)
|
|
481
|
-
break;
|
|
517
|
+
if (!vcs.laneId) break;
|
|
482
518
|
const lid = laneEntityId(vcs.laneId);
|
|
483
519
|
result.deleteFacts.push({ e: lid, a: "status", v: "promoting" });
|
|
484
520
|
result.addFacts.push({ e: lid, a: "status", v: "promoted" });
|
|
@@ -488,13 +524,13 @@ function decompose(op) {
|
|
|
488
524
|
break;
|
|
489
525
|
}
|
|
490
526
|
case "vcs:lanePromoteAbort": {
|
|
491
|
-
if (!vcs.laneId)
|
|
492
|
-
break;
|
|
527
|
+
if (!vcs.laneId) break;
|
|
493
528
|
const lid = laneEntityId(vcs.laneId);
|
|
494
529
|
result.deleteFacts.push({ e: lid, a: "status", v: "promoting" });
|
|
495
530
|
result.addFacts.push({ e: lid, a: "status", v: "active" });
|
|
496
531
|
break;
|
|
497
532
|
}
|
|
533
|
+
// ----- EAV store (CMS / knowledge graph) -----
|
|
498
534
|
case "vcs:storeAssert": {
|
|
499
535
|
result.addFacts.push(...pickFacts(vcs.facts));
|
|
500
536
|
break;
|
|
@@ -514,89 +550,120 @@ function decompose(op) {
|
|
|
514
550
|
}
|
|
515
551
|
return result;
|
|
516
552
|
}
|
|
517
|
-
var init_decompose = __esm(
|
|
518
|
-
|
|
553
|
+
var init_decompose = __esm({
|
|
554
|
+
"src/vcs/decompose.ts"() {
|
|
555
|
+
"use strict";
|
|
556
|
+
init_types();
|
|
557
|
+
}
|
|
519
558
|
});
|
|
520
559
|
|
|
521
560
|
// src/vcs/blob-store.ts
|
|
522
561
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
523
562
|
import { join } from "path";
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
563
|
+
var BlobStore;
|
|
564
|
+
var init_blob_store = __esm({
|
|
565
|
+
"src/vcs/blob-store.ts"() {
|
|
566
|
+
"use strict";
|
|
567
|
+
BlobStore = class {
|
|
568
|
+
blobDir;
|
|
569
|
+
constructor(trellisDir) {
|
|
570
|
+
this.blobDir = join(trellisDir, "blobs");
|
|
571
|
+
if (!existsSync(this.blobDir)) {
|
|
572
|
+
mkdirSync(this.blobDir, { recursive: true });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Store content and return its SHA-256 hash.
|
|
577
|
+
* Idempotent — storing the same content twice is a no-op.
|
|
578
|
+
*/
|
|
579
|
+
async put(content) {
|
|
580
|
+
const hash = await this.hash(content);
|
|
581
|
+
const blobPath = join(this.blobDir, hash);
|
|
582
|
+
if (!existsSync(blobPath)) {
|
|
583
|
+
writeFileSync(blobPath, content);
|
|
584
|
+
}
|
|
585
|
+
return hash;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Synchronous put — uses Bun's sync crypto if available.
|
|
589
|
+
*/
|
|
590
|
+
putSync(content) {
|
|
591
|
+
const hash = this.hashSync(content);
|
|
592
|
+
const blobPath = join(this.blobDir, hash);
|
|
593
|
+
if (!existsSync(blobPath)) {
|
|
594
|
+
writeFileSync(blobPath, content);
|
|
595
|
+
}
|
|
596
|
+
return hash;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Retrieve content by hash. Returns null if not found.
|
|
600
|
+
*/
|
|
601
|
+
get(hash) {
|
|
602
|
+
const blobPath = join(this.blobDir, hash);
|
|
603
|
+
if (!existsSync(blobPath)) {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
return readFileSync(blobPath);
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Check if a blob exists.
|
|
610
|
+
*/
|
|
611
|
+
has(hash) {
|
|
612
|
+
return existsSync(join(this.blobDir, hash));
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Compute SHA-256 hash of content (async).
|
|
616
|
+
*/
|
|
617
|
+
async hash(content) {
|
|
618
|
+
const hashBuffer = await crypto.subtle.digest(
|
|
619
|
+
"SHA-256",
|
|
620
|
+
content
|
|
621
|
+
);
|
|
622
|
+
return this.hexFromBuffer(hashBuffer);
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Compute SHA-256 hash of content (sync).
|
|
626
|
+
* Uses Bun.CryptoHasher when running under Bun, else node:crypto.
|
|
627
|
+
*/
|
|
628
|
+
hashSync(content) {
|
|
629
|
+
const { createHash } = __require("crypto");
|
|
630
|
+
return createHash("sha256").update(content).digest("hex");
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Returns the number of blobs stored.
|
|
634
|
+
*/
|
|
635
|
+
count() {
|
|
585
636
|
try {
|
|
586
|
-
|
|
637
|
+
const { readdirSync: readdirSync2 } = __require("fs");
|
|
638
|
+
return readdirSync2(this.blobDir).length;
|
|
587
639
|
} catch {
|
|
588
|
-
return
|
|
640
|
+
return 0;
|
|
589
641
|
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Returns the total size of all blobs in bytes.
|
|
645
|
+
*/
|
|
646
|
+
totalSize() {
|
|
647
|
+
try {
|
|
648
|
+
const { readdirSync: readdirSync2, statSync } = __require("fs");
|
|
649
|
+
const files = readdirSync2(this.blobDir);
|
|
650
|
+
return files.reduce((sum, f) => {
|
|
651
|
+
try {
|
|
652
|
+
return sum + statSync(join(this.blobDir, f)).size;
|
|
653
|
+
} catch {
|
|
654
|
+
return sum;
|
|
655
|
+
}
|
|
656
|
+
}, 0);
|
|
657
|
+
} catch {
|
|
658
|
+
return 0;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
hexFromBuffer(buffer) {
|
|
662
|
+
return Array.from(new Uint8Array(buffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
663
|
+
}
|
|
664
|
+
};
|
|
597
665
|
}
|
|
598
|
-
}
|
|
599
|
-
var init_blob_store = () => {};
|
|
666
|
+
});
|
|
600
667
|
|
|
601
668
|
// src/vcs/branch.ts
|
|
602
669
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -676,19 +743,23 @@ function loadBranchState(rootPath) {
|
|
|
676
743
|
activeLaneId: state.activeLaneId
|
|
677
744
|
};
|
|
678
745
|
}
|
|
679
|
-
} catch {
|
|
746
|
+
} catch {
|
|
747
|
+
}
|
|
680
748
|
}
|
|
681
749
|
return { currentBranch: "main" };
|
|
682
750
|
}
|
|
683
751
|
var BRANCH_ADVANCE_SKIP_KINDS;
|
|
684
|
-
var init_branch = __esm(
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
752
|
+
var init_branch = __esm({
|
|
753
|
+
"src/vcs/branch.ts"() {
|
|
754
|
+
"use strict";
|
|
755
|
+
init_ops();
|
|
756
|
+
BRANCH_ADVANCE_SKIP_KINDS = /* @__PURE__ */ new Set([
|
|
757
|
+
"vcs:branchAdvance",
|
|
758
|
+
"vcs:branchCreate",
|
|
759
|
+
"vcs:branchDelete",
|
|
760
|
+
"vcs:checkpointCreate"
|
|
761
|
+
]);
|
|
762
|
+
}
|
|
692
763
|
});
|
|
693
764
|
|
|
694
765
|
// src/vcs/milestone.ts
|
|
@@ -715,7 +786,9 @@ async function createMilestone(ctx, message, opts) {
|
|
|
715
786
|
const toIdx = ops.findIndex((o) => o.hash === toOpHash);
|
|
716
787
|
const rangeOps = fromIdx >= 0 && toIdx >= 0 ? ops.slice(fromIdx, toIdx + 1) : ops;
|
|
717
788
|
const affectedFiles = [
|
|
718
|
-
...new Set(
|
|
789
|
+
...new Set(
|
|
790
|
+
rangeOps.filter((o) => o.vcs?.filePath).map((o) => o.vcs.filePath)
|
|
791
|
+
)
|
|
719
792
|
];
|
|
720
793
|
const op = await createVcsOp("vcs:milestoneCreate", {
|
|
721
794
|
agentId: ctx.agentId,
|
|
@@ -750,8 +823,11 @@ function listMilestones(ctx) {
|
|
|
750
823
|
};
|
|
751
824
|
});
|
|
752
825
|
}
|
|
753
|
-
var init_milestone = __esm(
|
|
754
|
-
|
|
826
|
+
var init_milestone = __esm({
|
|
827
|
+
"src/vcs/milestone.ts"() {
|
|
828
|
+
"use strict";
|
|
829
|
+
init_ops();
|
|
830
|
+
}
|
|
755
831
|
});
|
|
756
832
|
|
|
757
833
|
// src/vcs/checkpoint.ts
|
|
@@ -777,16 +853,18 @@ function listCheckpoints(ctx) {
|
|
|
777
853
|
};
|
|
778
854
|
});
|
|
779
855
|
}
|
|
780
|
-
var init_checkpoint = __esm(
|
|
781
|
-
|
|
856
|
+
var init_checkpoint = __esm({
|
|
857
|
+
"src/vcs/checkpoint.ts"() {
|
|
858
|
+
"use strict";
|
|
859
|
+
init_ops();
|
|
860
|
+
}
|
|
782
861
|
});
|
|
783
862
|
|
|
784
863
|
// src/vcs/diff.ts
|
|
785
864
|
function diffFileStates(stateA, stateB, blobStore) {
|
|
786
865
|
const diffs = [];
|
|
787
866
|
for (const [path, bState] of stateB) {
|
|
788
|
-
if (bState.deleted)
|
|
789
|
-
continue;
|
|
867
|
+
if (bState.deleted) continue;
|
|
790
868
|
const aState = stateA.get(path);
|
|
791
869
|
if (!aState || aState.deleted) {
|
|
792
870
|
diffs.push({
|
|
@@ -805,15 +883,18 @@ function diffFileStates(stateA, stateB, blobStore) {
|
|
|
805
883
|
const oldContent = blobStore.get(aState.contentHash);
|
|
806
884
|
const newContent = blobStore.get(bState.contentHash);
|
|
807
885
|
if (oldContent && newContent) {
|
|
808
|
-
diff.unifiedDiff = generateUnifiedDiff(
|
|
886
|
+
diff.unifiedDiff = generateUnifiedDiff(
|
|
887
|
+
path,
|
|
888
|
+
oldContent.toString("utf-8"),
|
|
889
|
+
newContent.toString("utf-8")
|
|
890
|
+
);
|
|
809
891
|
}
|
|
810
892
|
}
|
|
811
893
|
diffs.push(diff);
|
|
812
894
|
}
|
|
813
895
|
}
|
|
814
896
|
for (const [path, aState] of stateA) {
|
|
815
|
-
if (aState.deleted)
|
|
816
|
-
continue;
|
|
897
|
+
if (aState.deleted) continue;
|
|
817
898
|
const bState = stateB.get(path);
|
|
818
899
|
if (!bState || bState.deleted) {
|
|
819
900
|
diffs.push({
|
|
@@ -836,7 +917,7 @@ function diffFileStates(stateA, stateB, blobStore) {
|
|
|
836
917
|
};
|
|
837
918
|
}
|
|
838
919
|
function buildFileStateAtOp(ops, atOpHash) {
|
|
839
|
-
const state = new Map;
|
|
920
|
+
const state = /* @__PURE__ */ new Map();
|
|
840
921
|
for (const op of ops) {
|
|
841
922
|
if (op.vcs?.filePath) {
|
|
842
923
|
switch (op.kind) {
|
|
@@ -855,8 +936,7 @@ function buildFileStateAtOp(ops, atOpHash) {
|
|
|
855
936
|
break;
|
|
856
937
|
}
|
|
857
938
|
}
|
|
858
|
-
if (atOpHash && op.hash === atOpHash)
|
|
859
|
-
break;
|
|
939
|
+
if (atOpHash && op.hash === atOpHash) break;
|
|
860
940
|
}
|
|
861
941
|
return state;
|
|
862
942
|
}
|
|
@@ -866,17 +946,16 @@ function diffOpRange(ops, fromHash, toHash, blobStore) {
|
|
|
866
946
|
return diffFileStates(stateA, stateB, blobStore);
|
|
867
947
|
}
|
|
868
948
|
function generateUnifiedDiff(filePath, oldText, newText, contextLines = 3) {
|
|
869
|
-
const oldLines = oldText.split(
|
|
870
|
-
|
|
871
|
-
const newLines = newText.split(`
|
|
872
|
-
`);
|
|
949
|
+
const oldLines = oldText.split("\n");
|
|
950
|
+
const newLines = newText.split("\n");
|
|
873
951
|
const edits = myersDiff(oldLines, newLines);
|
|
874
952
|
const hunks = buildHunks(edits, contextLines);
|
|
875
|
-
if (hunks.length === 0)
|
|
876
|
-
return "";
|
|
953
|
+
if (hunks.length === 0) return "";
|
|
877
954
|
const lines = [`--- a/${filePath}`, `+++ b/${filePath}`];
|
|
878
955
|
for (const hunk of hunks) {
|
|
879
|
-
lines.push(
|
|
956
|
+
lines.push(
|
|
957
|
+
`@@ -${hunk.oldStart},${hunk.oldCount} +${hunk.newStart},${hunk.newCount} @@`
|
|
958
|
+
);
|
|
880
959
|
for (const edit of hunk.edits) {
|
|
881
960
|
switch (edit.kind) {
|
|
882
961
|
case "equal":
|
|
@@ -891,14 +970,12 @@ function generateUnifiedDiff(filePath, oldText, newText, contextLines = 3) {
|
|
|
891
970
|
}
|
|
892
971
|
}
|
|
893
972
|
}
|
|
894
|
-
return lines.join(
|
|
895
|
-
`);
|
|
973
|
+
return lines.join("\n");
|
|
896
974
|
}
|
|
897
975
|
function myersDiff(oldLines, newLines) {
|
|
898
976
|
const n = oldLines.length;
|
|
899
977
|
const m = newLines.length;
|
|
900
|
-
if (n === 0 && m === 0)
|
|
901
|
-
return [];
|
|
978
|
+
if (n === 0 && m === 0) return [];
|
|
902
979
|
if (n === 0)
|
|
903
980
|
return newLines.map((line) => ({ kind: "insert", line }));
|
|
904
981
|
if (m === 0)
|
|
@@ -908,30 +985,28 @@ function myersDiff(oldLines, newLines) {
|
|
|
908
985
|
const v = new Int32Array(size);
|
|
909
986
|
const trace = [];
|
|
910
987
|
const off = max;
|
|
911
|
-
outer:
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
x2 = v[k - 1 + off] + 1;
|
|
920
|
-
}
|
|
921
|
-
let y2 = x2 - k;
|
|
922
|
-
while (x2 < n && y2 < m && oldLines[x2] === newLines[y2]) {
|
|
923
|
-
x2++;
|
|
924
|
-
y2++;
|
|
925
|
-
}
|
|
926
|
-
v[k + off] = x2;
|
|
927
|
-
if (x2 >= n && y2 >= m)
|
|
928
|
-
break outer;
|
|
988
|
+
outer: for (let d = 0; d <= max; d++) {
|
|
989
|
+
trace.push(v.slice());
|
|
990
|
+
for (let k = -d; k <= d; k += 2) {
|
|
991
|
+
let x2;
|
|
992
|
+
if (k === -d || k !== d && v[k - 1 + off] < v[k + 1 + off]) {
|
|
993
|
+
x2 = v[k + 1 + off];
|
|
994
|
+
} else {
|
|
995
|
+
x2 = v[k - 1 + off] + 1;
|
|
929
996
|
}
|
|
997
|
+
let y2 = x2 - k;
|
|
998
|
+
while (x2 < n && y2 < m && oldLines[x2] === newLines[y2]) {
|
|
999
|
+
x2++;
|
|
1000
|
+
y2++;
|
|
1001
|
+
}
|
|
1002
|
+
v[k + off] = x2;
|
|
1003
|
+
if (x2 >= n && y2 >= m) break outer;
|
|
930
1004
|
}
|
|
1005
|
+
}
|
|
931
1006
|
let x = n;
|
|
932
1007
|
let y = m;
|
|
933
1008
|
const edits = [];
|
|
934
|
-
for (let d = trace.length - 1;d >= 0; d--) {
|
|
1009
|
+
for (let d = trace.length - 1; d >= 0; d--) {
|
|
935
1010
|
const tv = trace[d];
|
|
936
1011
|
const k = x - y;
|
|
937
1012
|
let prevK;
|
|
@@ -967,22 +1042,23 @@ function myersDiff(oldLines, newLines) {
|
|
|
967
1042
|
return edits;
|
|
968
1043
|
}
|
|
969
1044
|
function buildHunks(edits, contextLines) {
|
|
970
|
-
if (edits.length === 0)
|
|
971
|
-
return [];
|
|
1045
|
+
if (edits.length === 0) return [];
|
|
972
1046
|
const changeIndices = [];
|
|
973
|
-
for (let i = 0;i < edits.length; i++) {
|
|
1047
|
+
for (let i = 0; i < edits.length; i++) {
|
|
974
1048
|
if (edits[i].kind !== "equal") {
|
|
975
1049
|
changeIndices.push(i);
|
|
976
1050
|
}
|
|
977
1051
|
}
|
|
978
|
-
if (changeIndices.length === 0)
|
|
979
|
-
return [];
|
|
1052
|
+
if (changeIndices.length === 0) return [];
|
|
980
1053
|
const hunks = [];
|
|
981
1054
|
let hunkStart = Math.max(0, changeIndices[0] - contextLines);
|
|
982
1055
|
let hunkEnd = Math.min(edits.length - 1, changeIndices[0] + contextLines);
|
|
983
|
-
for (let i = 1;i < changeIndices.length; i++) {
|
|
1056
|
+
for (let i = 1; i < changeIndices.length; i++) {
|
|
984
1057
|
const changeStart = changeIndices[i] - contextLines;
|
|
985
|
-
const changeEnd = Math.min(
|
|
1058
|
+
const changeEnd = Math.min(
|
|
1059
|
+
edits.length - 1,
|
|
1060
|
+
changeIndices[i] + contextLines
|
|
1061
|
+
);
|
|
986
1062
|
if (changeStart <= hunkEnd + 1) {
|
|
987
1063
|
hunkEnd = changeEnd;
|
|
988
1064
|
} else {
|
|
@@ -998,19 +1074,15 @@ function createHunk(edits, start, end) {
|
|
|
998
1074
|
const hunkEdits = edits.slice(start, end + 1);
|
|
999
1075
|
let oldLine = 1;
|
|
1000
1076
|
let newLine = 1;
|
|
1001
|
-
for (let i = 0;i < start; i++) {
|
|
1002
|
-
if (edits[i].kind === "equal" || edits[i].kind === "delete")
|
|
1003
|
-
|
|
1004
|
-
if (edits[i].kind === "equal" || edits[i].kind === "insert")
|
|
1005
|
-
newLine++;
|
|
1077
|
+
for (let i = 0; i < start; i++) {
|
|
1078
|
+
if (edits[i].kind === "equal" || edits[i].kind === "delete") oldLine++;
|
|
1079
|
+
if (edits[i].kind === "equal" || edits[i].kind === "insert") newLine++;
|
|
1006
1080
|
}
|
|
1007
1081
|
let oldCount = 0;
|
|
1008
1082
|
let newCount = 0;
|
|
1009
1083
|
for (const edit of hunkEdits) {
|
|
1010
|
-
if (edit.kind === "equal" || edit.kind === "delete")
|
|
1011
|
-
|
|
1012
|
-
if (edit.kind === "equal" || edit.kind === "insert")
|
|
1013
|
-
newCount++;
|
|
1084
|
+
if (edit.kind === "equal" || edit.kind === "delete") oldCount++;
|
|
1085
|
+
if (edit.kind === "equal" || edit.kind === "insert") newCount++;
|
|
1014
1086
|
}
|
|
1015
1087
|
return {
|
|
1016
1088
|
oldStart: oldLine,
|
|
@@ -1020,28 +1092,22 @@ function createHunk(edits, start, end) {
|
|
|
1020
1092
|
edits: hunkEdits
|
|
1021
1093
|
};
|
|
1022
1094
|
}
|
|
1023
|
-
var init_diff = (
|
|
1095
|
+
var init_diff = __esm({
|
|
1096
|
+
"src/vcs/diff.ts"() {
|
|
1097
|
+
"use strict";
|
|
1098
|
+
}
|
|
1099
|
+
});
|
|
1024
1100
|
|
|
1025
1101
|
// src/vcs/merge.ts
|
|
1026
1102
|
function threeWayMerge(base, ours, theirs, blobStore) {
|
|
1027
|
-
const mergedFiles = new Map;
|
|
1103
|
+
const mergedFiles = /* @__PURE__ */ new Map();
|
|
1028
1104
|
const conflicts = [];
|
|
1029
|
-
const allPaths = new Set;
|
|
1030
|
-
for (const [p, s] of base)
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
for (const [p, s] of ours)
|
|
1034
|
-
|
|
1035
|
-
allPaths.add(p);
|
|
1036
|
-
for (const [p, s] of theirs)
|
|
1037
|
-
if (!s.deleted)
|
|
1038
|
-
allPaths.add(p);
|
|
1039
|
-
for (const [p, s] of ours)
|
|
1040
|
-
if (s.deleted)
|
|
1041
|
-
allPaths.add(p);
|
|
1042
|
-
for (const [p, s] of theirs)
|
|
1043
|
-
if (s.deleted)
|
|
1044
|
-
allPaths.add(p);
|
|
1105
|
+
const allPaths = /* @__PURE__ */ new Set();
|
|
1106
|
+
for (const [p, s] of base) if (!s.deleted) allPaths.add(p);
|
|
1107
|
+
for (const [p, s] of ours) if (!s.deleted) allPaths.add(p);
|
|
1108
|
+
for (const [p, s] of theirs) if (!s.deleted) allPaths.add(p);
|
|
1109
|
+
for (const [p, s] of ours) if (s.deleted) allPaths.add(p);
|
|
1110
|
+
for (const [p, s] of theirs) if (s.deleted) allPaths.add(p);
|
|
1045
1111
|
for (const path of allPaths) {
|
|
1046
1112
|
const b = base.get(path);
|
|
1047
1113
|
const o = ours.get(path);
|
|
@@ -1049,9 +1115,9 @@ function threeWayMerge(base, ours, theirs, blobStore) {
|
|
|
1049
1115
|
const baseExists = b && !b.deleted;
|
|
1050
1116
|
const oursExists = o && !o.deleted;
|
|
1051
1117
|
const theirsExists = t && !t.deleted;
|
|
1052
|
-
const baseHash = baseExists ? b.contentHash :
|
|
1053
|
-
const oursHash = oursExists ? o.contentHash :
|
|
1054
|
-
const theirsHash = theirsExists ? t.contentHash :
|
|
1118
|
+
const baseHash = baseExists ? b.contentHash : void 0;
|
|
1119
|
+
const oursHash = oursExists ? o.contentHash : void 0;
|
|
1120
|
+
const theirsHash = theirsExists ? t.contentHash : void 0;
|
|
1055
1121
|
if (oursHash === theirsHash) {
|
|
1056
1122
|
continue;
|
|
1057
1123
|
}
|
|
@@ -1076,9 +1142,9 @@ function threeWayMerge(base, ours, theirs, blobStore) {
|
|
|
1076
1142
|
if (oursHash === theirsHash) {
|
|
1077
1143
|
continue;
|
|
1078
1144
|
}
|
|
1079
|
-
const oursContent = oursHash && blobStore ? blobStore.get(oursHash)?.toString("utf-8") :
|
|
1080
|
-
const theirsContent = theirsHash && blobStore ? blobStore.get(theirsHash)?.toString("utf-8") :
|
|
1081
|
-
if (oursContent !==
|
|
1145
|
+
const oursContent = oursHash && blobStore ? blobStore.get(oursHash)?.toString("utf-8") : void 0;
|
|
1146
|
+
const theirsContent = theirsHash && blobStore ? blobStore.get(theirsHash)?.toString("utf-8") : void 0;
|
|
1147
|
+
if (oursContent !== void 0 && theirsContent !== void 0) {
|
|
1082
1148
|
const textResult = threeWayTextMerge("", oursContent, theirsContent);
|
|
1083
1149
|
if (textResult.clean) {
|
|
1084
1150
|
mergedFiles.set(path, textResult.merged);
|
|
@@ -1100,7 +1166,7 @@ function threeWayMerge(base, ours, theirs, blobStore) {
|
|
|
1100
1166
|
conflicts.push({
|
|
1101
1167
|
path,
|
|
1102
1168
|
kind: "modify-delete",
|
|
1103
|
-
ours: oursHash && blobStore ? blobStore.get(oursHash)?.toString("utf-8") :
|
|
1169
|
+
ours: oursHash && blobStore ? blobStore.get(oursHash)?.toString("utf-8") : void 0
|
|
1104
1170
|
});
|
|
1105
1171
|
continue;
|
|
1106
1172
|
}
|
|
@@ -1108,15 +1174,15 @@ function threeWayMerge(base, ours, theirs, blobStore) {
|
|
|
1108
1174
|
conflicts.push({
|
|
1109
1175
|
path,
|
|
1110
1176
|
kind: "modify-delete",
|
|
1111
|
-
theirs: theirsHash && blobStore ? blobStore.get(theirsHash)?.toString("utf-8") :
|
|
1177
|
+
theirs: theirsHash && blobStore ? blobStore.get(theirsHash)?.toString("utf-8") : void 0
|
|
1112
1178
|
});
|
|
1113
1179
|
continue;
|
|
1114
1180
|
}
|
|
1115
1181
|
if (oursExists && theirsExists && oursHash !== theirsHash) {
|
|
1116
|
-
const baseContent = baseHash && blobStore ? blobStore.get(baseHash)?.toString("utf-8") :
|
|
1117
|
-
const oursContent = oursHash && blobStore ? blobStore.get(oursHash)?.toString("utf-8") :
|
|
1118
|
-
const theirsContent = theirsHash && blobStore ? blobStore.get(theirsHash)?.toString("utf-8") :
|
|
1119
|
-
if (baseContent !==
|
|
1182
|
+
const baseContent = baseHash && blobStore ? blobStore.get(baseHash)?.toString("utf-8") : void 0;
|
|
1183
|
+
const oursContent = oursHash && blobStore ? blobStore.get(oursHash)?.toString("utf-8") : void 0;
|
|
1184
|
+
const theirsContent = theirsHash && blobStore ? blobStore.get(theirsHash)?.toString("utf-8") : void 0;
|
|
1185
|
+
if (baseContent !== void 0 && oursContent !== void 0 && theirsContent !== void 0) {
|
|
1120
1186
|
const textResult = threeWayTextMerge(baseContent, oursContent, theirsContent);
|
|
1121
1187
|
if (textResult.clean) {
|
|
1122
1188
|
mergedFiles.set(path, textResult.merged);
|
|
@@ -1151,18 +1217,16 @@ function threeWayMerge(base, ours, theirs, blobStore) {
|
|
|
1151
1217
|
stats: {
|
|
1152
1218
|
added,
|
|
1153
1219
|
modified: added,
|
|
1220
|
+
// in a merge context, additions from theirs are "modified"
|
|
1154
1221
|
deleted,
|
|
1155
1222
|
conflicted: conflicts.length
|
|
1156
1223
|
}
|
|
1157
1224
|
};
|
|
1158
1225
|
}
|
|
1159
1226
|
function threeWayTextMerge(baseText, oursText, theirsText) {
|
|
1160
|
-
const baseLines = baseText.split(
|
|
1161
|
-
|
|
1162
|
-
const
|
|
1163
|
-
`);
|
|
1164
|
-
const theirsLines = theirsText.split(`
|
|
1165
|
-
`);
|
|
1227
|
+
const baseLines = baseText.split("\n");
|
|
1228
|
+
const oursLines = oursText.split("\n");
|
|
1229
|
+
const theirsLines = theirsText.split("\n");
|
|
1166
1230
|
const oursChanges = computeLineChanges(baseLines, oursLines);
|
|
1167
1231
|
const theirsChanges = computeLineChanges(baseLines, theirsLines);
|
|
1168
1232
|
const result = [];
|
|
@@ -1198,9 +1262,7 @@ function threeWayTextMerge(baseText, oursText, theirsText) {
|
|
|
1198
1262
|
oursIdx += theirsChange.baseCount;
|
|
1199
1263
|
theirsIdx += theirsChange.newCount;
|
|
1200
1264
|
} else if (oursChange && theirsChange) {
|
|
1201
|
-
if (oursChange.baseCount === theirsChange.baseCount && oursChange.newLines.join(
|
|
1202
|
-
`) === theirsChange.newLines.join(`
|
|
1203
|
-
`)) {
|
|
1265
|
+
if (oursChange.baseCount === theirsChange.baseCount && oursChange.newLines.join("\n") === theirsChange.newLines.join("\n")) {
|
|
1204
1266
|
applyChange(oursChange, result);
|
|
1205
1267
|
baseIdx += oursChange.baseCount;
|
|
1206
1268
|
oursIdx += oursChange.newCount;
|
|
@@ -1208,11 +1270,9 @@ function threeWayTextMerge(baseText, oursText, theirsText) {
|
|
|
1208
1270
|
} else {
|
|
1209
1271
|
clean = false;
|
|
1210
1272
|
result.push("<<<<<<< ours");
|
|
1211
|
-
for (const line of oursChange.newLines)
|
|
1212
|
-
result.push(line);
|
|
1273
|
+
for (const line of oursChange.newLines) result.push(line);
|
|
1213
1274
|
result.push("=======");
|
|
1214
|
-
for (const line of theirsChange.newLines)
|
|
1215
|
-
result.push(line);
|
|
1275
|
+
for (const line of theirsChange.newLines) result.push(line);
|
|
1216
1276
|
result.push(">>>>>>> theirs");
|
|
1217
1277
|
baseIdx += Math.max(oursChange.baseCount, theirsChange.baseCount);
|
|
1218
1278
|
oursIdx += oursChange.newCount;
|
|
@@ -1220,8 +1280,7 @@ function threeWayTextMerge(baseText, oursText, theirsText) {
|
|
|
1220
1280
|
}
|
|
1221
1281
|
}
|
|
1222
1282
|
}
|
|
1223
|
-
return { clean, merged: result.join(
|
|
1224
|
-
`) };
|
|
1283
|
+
return { clean, merged: result.join("\n") };
|
|
1225
1284
|
}
|
|
1226
1285
|
function applyChange(change, result) {
|
|
1227
1286
|
for (const line of change.newLines) {
|
|
@@ -1229,7 +1288,7 @@ function applyChange(change, result) {
|
|
|
1229
1288
|
}
|
|
1230
1289
|
}
|
|
1231
1290
|
function computeLineChanges(baseLines, newLines) {
|
|
1232
|
-
const changes = new Map;
|
|
1291
|
+
const changes = /* @__PURE__ */ new Map();
|
|
1233
1292
|
const matches = lcsMatch(baseLines, newLines);
|
|
1234
1293
|
let baseIdx = 0;
|
|
1235
1294
|
let newIdx = 0;
|
|
@@ -1266,11 +1325,13 @@ function computeLineChanges(baseLines, newLines) {
|
|
|
1266
1325
|
function lcsMatch(a, b) {
|
|
1267
1326
|
const n = a.length;
|
|
1268
1327
|
const m = b.length;
|
|
1269
|
-
if (n === 0 || m === 0)
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1328
|
+
if (n === 0 || m === 0) return [];
|
|
1329
|
+
const dp = Array.from(
|
|
1330
|
+
{ length: n + 1 },
|
|
1331
|
+
() => new Array(m + 1).fill(0)
|
|
1332
|
+
);
|
|
1333
|
+
for (let i2 = 1; i2 <= n; i2++) {
|
|
1334
|
+
for (let j2 = 1; j2 <= m; j2++) {
|
|
1274
1335
|
if (a[i2 - 1] === b[j2 - 1]) {
|
|
1275
1336
|
dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
|
|
1276
1337
|
} else {
|
|
@@ -1294,7 +1355,11 @@ function lcsMatch(a, b) {
|
|
|
1294
1355
|
}
|
|
1295
1356
|
return matches;
|
|
1296
1357
|
}
|
|
1297
|
-
var init_merge = (
|
|
1358
|
+
var init_merge = __esm({
|
|
1359
|
+
"src/vcs/merge.ts"() {
|
|
1360
|
+
"use strict";
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1298
1363
|
|
|
1299
1364
|
// src/vcs/issue.ts
|
|
1300
1365
|
import { exec } from "child_process";
|
|
@@ -1312,13 +1377,22 @@ import { join as join3, dirname as dirname2 } from "path";
|
|
|
1312
1377
|
function getIssueCounterPath(rootPath) {
|
|
1313
1378
|
return join3(rootPath, ".trellis", "issue-counter.json");
|
|
1314
1379
|
}
|
|
1315
|
-
function
|
|
1380
|
+
function getLaneIssueCounterPath(rootPath, laneId) {
|
|
1381
|
+
return join3(
|
|
1382
|
+
rootPath,
|
|
1383
|
+
".trellis",
|
|
1384
|
+
"issue-counters",
|
|
1385
|
+
`${encodeURIComponent(laneId)}.json`
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
function nextIssueId(rootPath, laneId) {
|
|
1389
|
+
const laneScope = laneId?.trim();
|
|
1316
1390
|
const counterPath = getIssueCounterPath(rootPath);
|
|
1317
|
-
const
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
const lockPath = `${
|
|
1321
|
-
const deadline = Date.now() +
|
|
1391
|
+
const scopedCounterPath = laneScope ? getLaneIssueCounterPath(rootPath, laneScope) : counterPath;
|
|
1392
|
+
const dir = dirname2(scopedCounterPath);
|
|
1393
|
+
if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
|
|
1394
|
+
const lockPath = `${scopedCounterPath}.lock`;
|
|
1395
|
+
const deadline = Date.now() + 5e3;
|
|
1322
1396
|
let lockFd;
|
|
1323
1397
|
while (Date.now() < deadline) {
|
|
1324
1398
|
try {
|
|
@@ -1330,35 +1404,44 @@ function nextIssueId(rootPath) {
|
|
|
1330
1404
|
}
|
|
1331
1405
|
}
|
|
1332
1406
|
}
|
|
1333
|
-
if (lockFd ===
|
|
1334
|
-
throw new Error(
|
|
1407
|
+
if (lockFd === void 0) {
|
|
1408
|
+
throw new Error(
|
|
1409
|
+
`Timed out waiting for issue counter lock: ${lockPath}. Another Trellis process may be stalled.`
|
|
1410
|
+
);
|
|
1335
1411
|
}
|
|
1336
1412
|
try {
|
|
1337
1413
|
let counter = 0;
|
|
1338
|
-
if (existsSync3(
|
|
1414
|
+
if (existsSync3(scopedCounterPath)) {
|
|
1339
1415
|
try {
|
|
1340
|
-
counter = JSON.parse(readFileSync3(
|
|
1341
|
-
} catch {
|
|
1416
|
+
counter = JSON.parse(readFileSync3(scopedCounterPath, "utf-8")).counter ?? 0;
|
|
1417
|
+
} catch {
|
|
1418
|
+
}
|
|
1342
1419
|
}
|
|
1343
1420
|
counter++;
|
|
1344
|
-
writeFileSync3(
|
|
1421
|
+
writeFileSync3(scopedCounterPath, JSON.stringify({ counter }, null, 2));
|
|
1422
|
+
if (laneScope) return `issue:${laneScope}:${counter}`;
|
|
1345
1423
|
return `TRL-${counter}`;
|
|
1346
1424
|
} finally {
|
|
1347
1425
|
closeSync(lockFd);
|
|
1348
1426
|
try {
|
|
1349
1427
|
unlinkSync(lockPath);
|
|
1350
|
-
} catch {
|
|
1428
|
+
} catch {
|
|
1429
|
+
}
|
|
1351
1430
|
}
|
|
1352
1431
|
}
|
|
1353
1432
|
function getIssueFact(ctx, entityId, attr) {
|
|
1354
1433
|
const facts = ctx.store.getFactsByEntity(entityId);
|
|
1355
1434
|
const matches = facts.filter((f) => f.a === attr);
|
|
1356
|
-
return matches.length > 0 ? matches[matches.length - 1].v :
|
|
1435
|
+
return matches.length > 0 ? matches[matches.length - 1].v : void 0;
|
|
1357
1436
|
}
|
|
1358
1437
|
function getIssueLinks(ctx, entityId, attr) {
|
|
1359
1438
|
const links = ctx.store.getLinksByEntity(entityId);
|
|
1360
1439
|
return links.filter((l) => l.a === attr && l.e1 === entityId).map((l) => l.e2);
|
|
1361
1440
|
}
|
|
1441
|
+
function issueInfoIdFromEntityId(entityId) {
|
|
1442
|
+
const bare = entityId.replace(/^issue:/, "");
|
|
1443
|
+
return bare.includes(":") ? entityId : bare;
|
|
1444
|
+
}
|
|
1362
1445
|
function getCriteriaForIssue(ctx, issueId) {
|
|
1363
1446
|
const eid = issueEntityId(issueId);
|
|
1364
1447
|
const criterionLinks = ctx.store.getLinksByAttribute("criterionOf").filter((l) => l.e2 === eid);
|
|
@@ -1367,7 +1450,7 @@ function getCriteriaForIssue(ctx, issueId) {
|
|
|
1367
1450
|
const facts = ctx.store.getFactsByEntity(ceid);
|
|
1368
1451
|
const getLast = (a) => {
|
|
1369
1452
|
const matches = facts.filter((f) => f.a === a);
|
|
1370
|
-
return matches.length > 0 ? matches[matches.length - 1].v :
|
|
1453
|
+
return matches.length > 0 ? matches[matches.length - 1].v : void 0;
|
|
1371
1454
|
};
|
|
1372
1455
|
return {
|
|
1373
1456
|
id: ceid,
|
|
@@ -1383,25 +1466,26 @@ function buildIssueInfo(ctx, entityId) {
|
|
|
1383
1466
|
const facts = ctx.store.getFactsByEntity(entityId);
|
|
1384
1467
|
const get = (a) => {
|
|
1385
1468
|
const matches = facts.filter((f) => f.a === a);
|
|
1386
|
-
return matches.length > 0 ? matches[matches.length - 1].v :
|
|
1469
|
+
return matches.length > 0 ? matches[matches.length - 1].v : void 0;
|
|
1387
1470
|
};
|
|
1388
1471
|
const labelsStr = get("labels");
|
|
1389
1472
|
const labels = labelsStr ? labelsStr.split(",").filter(Boolean) : [];
|
|
1390
1473
|
const trackedOnLinks = getIssueLinks(ctx, entityId, "trackedOn");
|
|
1391
|
-
const branchName = trackedOnLinks.length > 0 ? trackedOnLinks[0].replace(/^branch:/, "") :
|
|
1474
|
+
const branchName = trackedOnLinks.length > 0 ? trackedOnLinks[0].replace(/^branch:/, "") : void 0;
|
|
1392
1475
|
const childOfLinks = getIssueLinks(ctx, entityId, "childOf");
|
|
1393
|
-
const parentId = childOfLinks.length > 0 ? childOfLinks[0]
|
|
1394
|
-
const
|
|
1476
|
+
const parentId = childOfLinks.length > 0 ? issueInfoIdFromEntityId(childOfLinks[0]) : void 0;
|
|
1477
|
+
const issueId = issueInfoIdFromEntityId(entityId);
|
|
1395
1478
|
const blockedByLinks = getIssueLinks(ctx, entityId, "blockedBy");
|
|
1396
|
-
const blockedBy = blockedByLinks.map(
|
|
1479
|
+
const blockedBy = blockedByLinks.map(issueInfoIdFromEntityId);
|
|
1397
1480
|
const allBlockedByLinks = ctx.store.getLinksByAttribute("blockedBy");
|
|
1398
|
-
const blocking = allBlockedByLinks.filter((l) => l.e2 === entityId).map((l) => l.e1
|
|
1481
|
+
const blocking = allBlockedByLinks.filter((l) => l.e2 === entityId).map((l) => issueInfoIdFromEntityId(l.e1));
|
|
1399
1482
|
const isBlocked = blockedByLinks.some((blockerEid) => {
|
|
1400
1483
|
const blockerStatus = getIssueFact(ctx, blockerEid, "status");
|
|
1401
1484
|
return blockerStatus !== "closed";
|
|
1402
1485
|
});
|
|
1403
1486
|
return {
|
|
1404
|
-
id:
|
|
1487
|
+
id: issueId,
|
|
1488
|
+
displayId: defaultDisplayId(issueId),
|
|
1405
1489
|
title: get("title"),
|
|
1406
1490
|
description: get("description"),
|
|
1407
1491
|
status: get("status"),
|
|
@@ -1412,18 +1496,27 @@ function buildIssueInfo(ctx, entityId) {
|
|
|
1412
1496
|
createdBy: get("createdBy"),
|
|
1413
1497
|
startedAt: get("startedAt"),
|
|
1414
1498
|
pausedAt: get("pausedAt"),
|
|
1415
|
-
pauseNote: get("pauseNote") ||
|
|
1499
|
+
pauseNote: get("pauseNote") || void 0,
|
|
1416
1500
|
closedAt: get("closedAt"),
|
|
1417
1501
|
parentId,
|
|
1418
1502
|
branchName,
|
|
1419
1503
|
blockedBy,
|
|
1420
1504
|
blocking,
|
|
1421
1505
|
isBlocked,
|
|
1422
|
-
criteria: getCriteriaForIssue(ctx,
|
|
1506
|
+
criteria: getCriteriaForIssue(ctx, issueId)
|
|
1423
1507
|
};
|
|
1424
1508
|
}
|
|
1509
|
+
function defaultDisplayId(id) {
|
|
1510
|
+
return /^TRL-\d+$/.test(id) ? id : void 0;
|
|
1511
|
+
}
|
|
1425
1512
|
async function createIssue(ctx, rootPath, title, opts) {
|
|
1426
|
-
|
|
1513
|
+
if (opts?.parentId) {
|
|
1514
|
+
const parent = getIssue(ctx, opts.parentId);
|
|
1515
|
+
if (!parent) {
|
|
1516
|
+
throw new Error(`Parent issue ${opts.parentId} not found.`);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
const id = nextIssueId(rootPath, opts?.laneId);
|
|
1427
1520
|
const op = await createVcsOp("vcs:issueCreate", {
|
|
1428
1521
|
agentId: ctx.agentId,
|
|
1429
1522
|
previousHash: ctx.getLastOp()?.hash,
|
|
@@ -1440,8 +1533,13 @@ async function createIssue(ctx, rootPath, title, opts) {
|
|
|
1440
1533
|
});
|
|
1441
1534
|
await ctx.applyOp(op);
|
|
1442
1535
|
if (opts?.criteria) {
|
|
1443
|
-
for (let i = 0;i < opts.criteria.length; i++) {
|
|
1444
|
-
await addCriterion(
|
|
1536
|
+
for (let i = 0; i < opts.criteria.length; i++) {
|
|
1537
|
+
await addCriterion(
|
|
1538
|
+
ctx,
|
|
1539
|
+
id,
|
|
1540
|
+
opts.criteria[i].description,
|
|
1541
|
+
opts.criteria[i].command
|
|
1542
|
+
);
|
|
1445
1543
|
}
|
|
1446
1544
|
}
|
|
1447
1545
|
return op;
|
|
@@ -1452,21 +1550,16 @@ async function updateIssue(ctx, id, updates) {
|
|
|
1452
1550
|
throw new Error(`Issue ${id} not found.`);
|
|
1453
1551
|
}
|
|
1454
1552
|
const vcs = { issueId: id };
|
|
1455
|
-
if (updates.title !==
|
|
1456
|
-
|
|
1457
|
-
if (updates.
|
|
1458
|
-
vcs.issueDescription = updates.description;
|
|
1459
|
-
if (updates.status !== undefined) {
|
|
1553
|
+
if (updates.title !== void 0) vcs.issueTitle = updates.title;
|
|
1554
|
+
if (updates.description !== void 0) vcs.issueDescription = updates.description;
|
|
1555
|
+
if (updates.status !== void 0) {
|
|
1460
1556
|
vcs.oldIssueStatus = getIssueFact(ctx, issueEntityId(id), "status");
|
|
1461
1557
|
vcs.issueStatus = updates.status;
|
|
1462
1558
|
}
|
|
1463
|
-
if (updates.priority !==
|
|
1464
|
-
|
|
1465
|
-
if (updates.
|
|
1466
|
-
|
|
1467
|
-
if (updates.assignee !== undefined)
|
|
1468
|
-
vcs.issueAssignee = updates.assignee;
|
|
1469
|
-
if (updates.parentId !== undefined) {
|
|
1559
|
+
if (updates.priority !== void 0) vcs.issuePriority = updates.priority;
|
|
1560
|
+
if (updates.labels !== void 0) vcs.issueLabels = updates.labels;
|
|
1561
|
+
if (updates.assignee !== void 0) vcs.issueAssignee = updates.assignee;
|
|
1562
|
+
if (updates.parentId !== void 0) {
|
|
1470
1563
|
const newParent = updates.parentId;
|
|
1471
1564
|
if (newParent === id) {
|
|
1472
1565
|
throw new Error(`Issue ${id} cannot be its own parent.`);
|
|
@@ -1479,10 +1572,8 @@ async function updateIssue(ctx, id, updates) {
|
|
|
1479
1572
|
}
|
|
1480
1573
|
const currentParent = issue.parentId;
|
|
1481
1574
|
if (newParent !== currentParent) {
|
|
1482
|
-
if (currentParent)
|
|
1483
|
-
|
|
1484
|
-
if (newParent)
|
|
1485
|
-
vcs.parentIssueId = newParent;
|
|
1575
|
+
if (currentParent) vcs.oldParentIssueId = currentParent;
|
|
1576
|
+
if (newParent) vcs.parentIssueId = newParent;
|
|
1486
1577
|
}
|
|
1487
1578
|
}
|
|
1488
1579
|
const op = await createVcsOp("vcs:issueUpdate", {
|
|
@@ -1517,12 +1608,16 @@ async function startIssue(ctx, id, branchName) {
|
|
|
1517
1608
|
}
|
|
1518
1609
|
async function pauseIssue(ctx, id, note) {
|
|
1519
1610
|
if (!note || !note.trim()) {
|
|
1520
|
-
throw new Error(
|
|
1611
|
+
throw new Error(
|
|
1612
|
+
`A pause note is required. Explain why the issue is paused and what must happen before resuming.`
|
|
1613
|
+
);
|
|
1521
1614
|
}
|
|
1522
1615
|
const eid = issueEntityId(id);
|
|
1523
1616
|
const status = getIssueFact(ctx, eid, "status");
|
|
1524
1617
|
if (status !== "in_progress") {
|
|
1525
|
-
throw new Error(
|
|
1618
|
+
throw new Error(
|
|
1619
|
+
`Cannot pause issue ${id} \u2014 status is '${status}', expected 'in_progress'.`
|
|
1620
|
+
);
|
|
1526
1621
|
}
|
|
1527
1622
|
const op = await createVcsOp("vcs:issuePause", {
|
|
1528
1623
|
agentId: ctx.agentId,
|
|
@@ -1540,7 +1635,9 @@ async function resumeIssue(ctx, id) {
|
|
|
1540
1635
|
const eid = issueEntityId(id);
|
|
1541
1636
|
const status = getIssueFact(ctx, eid, "status");
|
|
1542
1637
|
if (status !== "paused") {
|
|
1543
|
-
throw new Error(
|
|
1638
|
+
throw new Error(
|
|
1639
|
+
`Cannot resume issue ${id} \u2014 status is '${status}', expected 'paused'.`
|
|
1640
|
+
);
|
|
1544
1641
|
}
|
|
1545
1642
|
const op = await createVcsOp("vcs:issueResume", {
|
|
1546
1643
|
agentId: ctx.agentId,
|
|
@@ -1566,9 +1663,10 @@ async function closeIssue(ctx, id, opts) {
|
|
|
1566
1663
|
const allPassed = results.length === 0 || results.every((r) => r.status === "passed");
|
|
1567
1664
|
if (!allPassed) {
|
|
1568
1665
|
const failing = results.filter((r) => r.status !== "passed");
|
|
1569
|
-
throw new Error(
|
|
1570
|
-
`
|
|
1571
|
-
`))
|
|
1666
|
+
throw new Error(
|
|
1667
|
+
`Cannot close issue ${id}: ${failing.length} criteria not passing:
|
|
1668
|
+
` + failing.map((f) => ` - ${f.description ?? f.id} (${f.status})`).join("\n")
|
|
1669
|
+
);
|
|
1572
1670
|
}
|
|
1573
1671
|
if (!opts?.confirm) {
|
|
1574
1672
|
return { criteriaResults: results };
|
|
@@ -1590,7 +1688,9 @@ async function triageIssue(ctx, id) {
|
|
|
1590
1688
|
const eid = issueEntityId(id);
|
|
1591
1689
|
const status = getIssueFact(ctx, eid, "status");
|
|
1592
1690
|
if (status !== "backlog") {
|
|
1593
|
-
throw new Error(
|
|
1691
|
+
throw new Error(
|
|
1692
|
+
`Cannot triage issue ${id} \u2014 status is '${status}', expected 'backlog'.`
|
|
1693
|
+
);
|
|
1594
1694
|
}
|
|
1595
1695
|
const op = await createVcsOp("vcs:issueUpdate", {
|
|
1596
1696
|
agentId: ctx.agentId,
|
|
@@ -1608,7 +1708,9 @@ async function reopenIssue(ctx, id) {
|
|
|
1608
1708
|
const eid = issueEntityId(id);
|
|
1609
1709
|
const status = getIssueFact(ctx, eid, "status");
|
|
1610
1710
|
if (status !== "closed") {
|
|
1611
|
-
throw new Error(
|
|
1711
|
+
throw new Error(
|
|
1712
|
+
`Cannot reopen issue ${id} \u2014 status is '${status}', expected 'closed'.`
|
|
1713
|
+
);
|
|
1612
1714
|
}
|
|
1613
1715
|
const op = await createVcsOp("vcs:issueReopen", {
|
|
1614
1716
|
agentId: ctx.agentId,
|
|
@@ -1670,7 +1772,9 @@ async function addCriterion(ctx, issueId, description, command) {
|
|
|
1670
1772
|
async function setCriterionStatus(ctx, issueId, criterionIndex, status) {
|
|
1671
1773
|
const criteria = getCriteriaForIssue(ctx, issueId);
|
|
1672
1774
|
if (criterionIndex < 1 || criterionIndex > criteria.length) {
|
|
1673
|
-
throw new Error(
|
|
1775
|
+
throw new Error(
|
|
1776
|
+
`Criterion index ${criterionIndex} out of range (1\u2013${criteria.length})`
|
|
1777
|
+
);
|
|
1674
1778
|
}
|
|
1675
1779
|
const c = criteria[criterionIndex - 1];
|
|
1676
1780
|
const op = await createVcsOp("vcs:criterionUpdate", {
|
|
@@ -1703,15 +1807,13 @@ async function runCriteria(ctx, issueId, rootPath) {
|
|
|
1703
1807
|
try {
|
|
1704
1808
|
const result = await execAsync(c.command, {
|
|
1705
1809
|
cwd: rootPath,
|
|
1706
|
-
timeout:
|
|
1810
|
+
timeout: 12e4
|
|
1707
1811
|
});
|
|
1708
|
-
output = (result.stdout +
|
|
1709
|
-
` + result.stderr).trim();
|
|
1812
|
+
output = (result.stdout + "\n" + result.stderr).trim();
|
|
1710
1813
|
exitCode = 0;
|
|
1711
1814
|
status = "passed";
|
|
1712
1815
|
} catch (err) {
|
|
1713
|
-
output = (err.stdout ?? "") +
|
|
1714
|
-
` + (err.stderr ?? err.message ?? "");
|
|
1816
|
+
output = (err.stdout ?? "") + "\n" + (err.stderr ?? err.message ?? "");
|
|
1715
1817
|
output = output.trim();
|
|
1716
1818
|
exitCode = err.code ?? 1;
|
|
1717
1819
|
status = "failed";
|
|
@@ -1752,7 +1854,7 @@ function listIssues(ctx, filters) {
|
|
|
1752
1854
|
if (filters?.parentId) {
|
|
1753
1855
|
issues = issues.filter((i) => i.parentId === filters.parentId);
|
|
1754
1856
|
}
|
|
1755
|
-
if (filters?.blocked !==
|
|
1857
|
+
if (filters?.blocked !== void 0) {
|
|
1756
1858
|
issues = issues.filter((i) => i.isBlocked === filters.blocked);
|
|
1757
1859
|
}
|
|
1758
1860
|
return issues;
|
|
@@ -1760,8 +1862,7 @@ function listIssues(ctx, filters) {
|
|
|
1760
1862
|
function getIssue(ctx, id) {
|
|
1761
1863
|
const eid = issueEntityId(id);
|
|
1762
1864
|
const typeFact = ctx.store.getFactsByEntity(eid).find((f) => f.a === "type" && f.v === "Issue");
|
|
1763
|
-
if (!typeFact)
|
|
1764
|
-
return null;
|
|
1865
|
+
if (!typeFact) return null;
|
|
1765
1866
|
return buildIssueInfo(ctx, eid);
|
|
1766
1867
|
}
|
|
1767
1868
|
function getActiveIssues(ctx) {
|
|
@@ -1779,23 +1880,31 @@ function checkCompletionReadiness(ctx) {
|
|
|
1779
1880
|
} else {
|
|
1780
1881
|
parts.push("\u2717 Not ready for completion:");
|
|
1781
1882
|
if (queue.length > 0) {
|
|
1782
|
-
parts.push(
|
|
1883
|
+
parts.push(
|
|
1884
|
+
` Queue (${queue.length}): ${queue.map((i) => i.id).join(", ")}`
|
|
1885
|
+
);
|
|
1783
1886
|
}
|
|
1784
1887
|
if (inProgress.length > 0) {
|
|
1785
|
-
parts.push(
|
|
1888
|
+
parts.push(
|
|
1889
|
+
` In progress (${inProgress.length}): ${inProgress.map((i) => i.id).join(", ")}`
|
|
1890
|
+
);
|
|
1786
1891
|
}
|
|
1787
1892
|
if (paused.length > 0) {
|
|
1788
|
-
parts.push(
|
|
1893
|
+
parts.push(
|
|
1894
|
+
` Paused (${paused.length}): ${paused.map((i) => `${i.id}${i.pauseNote ? ` \u2014 ${i.pauseNote}` : ""}`).join(", ")}`
|
|
1895
|
+
);
|
|
1789
1896
|
}
|
|
1790
1897
|
}
|
|
1791
|
-
return { ready, queue, paused, inProgress, summary: parts.join(
|
|
1792
|
-
`) };
|
|
1898
|
+
return { ready, queue, paused, inProgress, summary: parts.join("\n") };
|
|
1793
1899
|
}
|
|
1794
1900
|
var execAsync;
|
|
1795
|
-
var init_issue = __esm(
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1901
|
+
var init_issue = __esm({
|
|
1902
|
+
"src/vcs/issue.ts"() {
|
|
1903
|
+
"use strict";
|
|
1904
|
+
init_ops();
|
|
1905
|
+
init_types();
|
|
1906
|
+
execAsync = promisify(exec);
|
|
1907
|
+
}
|
|
1799
1908
|
});
|
|
1800
1909
|
|
|
1801
1910
|
// src/vcs/op-log.ts
|
|
@@ -1813,172 +1922,179 @@ import {
|
|
|
1813
1922
|
import { dirname as dirname3 } from "path";
|
|
1814
1923
|
function lockTimeoutMs() {
|
|
1815
1924
|
const raw = process.env.TRELLIS_OPLOG_LOCK_MS;
|
|
1816
|
-
if (!raw)
|
|
1817
|
-
return 5000;
|
|
1925
|
+
if (!raw) return 5e3;
|
|
1818
1926
|
const parsed = Number(raw);
|
|
1819
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed :
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
this.
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1927
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 5e3;
|
|
1928
|
+
}
|
|
1929
|
+
var JsonOpLog, LaneOpLog;
|
|
1930
|
+
var init_op_log = __esm({
|
|
1931
|
+
"src/vcs/op-log.ts"() {
|
|
1932
|
+
"use strict";
|
|
1933
|
+
JsonOpLog = class {
|
|
1934
|
+
ops = [];
|
|
1935
|
+
filePath;
|
|
1936
|
+
lockPath;
|
|
1937
|
+
constructor(filePath) {
|
|
1938
|
+
this.filePath = filePath;
|
|
1939
|
+
this.lockPath = `${filePath}.lock`;
|
|
1940
|
+
}
|
|
1941
|
+
get path() {
|
|
1942
|
+
return this.filePath;
|
|
1943
|
+
}
|
|
1944
|
+
load() {
|
|
1945
|
+
if (existsSync4(this.filePath)) {
|
|
1946
|
+
const raw = readFileSync4(this.filePath, "utf-8");
|
|
1947
|
+
try {
|
|
1948
|
+
this.ops = JSON.parse(raw);
|
|
1949
|
+
} catch {
|
|
1950
|
+
const backupPath = this.filePath + ".bak";
|
|
1951
|
+
if (existsSync4(backupPath)) {
|
|
1952
|
+
const backupRaw = readFileSync4(backupPath, "utf-8");
|
|
1953
|
+
this.ops = JSON.parse(backupRaw);
|
|
1954
|
+
writeFileSync4(this.filePath, backupRaw);
|
|
1955
|
+
} else {
|
|
1956
|
+
throw new Error(
|
|
1957
|
+
`Corrupted ops log at ${this.filePath} and no backup found. Run \`trellis repair\` to attempt recovery.`
|
|
1958
|
+
);
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1846
1961
|
}
|
|
1847
1962
|
}
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1963
|
+
append(op) {
|
|
1964
|
+
this.withLock(() => {
|
|
1965
|
+
const diskOps = this.readOpsFromDisk();
|
|
1966
|
+
this.ops = diskOps;
|
|
1967
|
+
if (this.ops.some((existing) => existing.hash === op.hash)) {
|
|
1968
|
+
return;
|
|
1969
|
+
}
|
|
1970
|
+
this.ops.push(op);
|
|
1971
|
+
this.writeOpsToDisk();
|
|
1972
|
+
});
|
|
1856
1973
|
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
const backupPath = this.filePath + ".bak";
|
|
1876
|
-
try {
|
|
1877
|
-
copyFileSync(this.filePath, backupPath);
|
|
1878
|
-
} catch {}
|
|
1879
|
-
}
|
|
1880
|
-
const tempPath = `${this.filePath}.tmp`;
|
|
1881
|
-
writeFileSync4(tempPath, JSON.stringify(this.ops, null, 2));
|
|
1882
|
-
renameSync(tempPath, this.filePath);
|
|
1883
|
-
}
|
|
1884
|
-
readOpsFromDisk() {
|
|
1885
|
-
if (!existsSync4(this.filePath)) {
|
|
1886
|
-
return [];
|
|
1887
|
-
}
|
|
1888
|
-
const raw = readFileSync4(this.filePath, "utf-8");
|
|
1889
|
-
try {
|
|
1890
|
-
const parsed = JSON.parse(raw);
|
|
1891
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
1892
|
-
} catch {
|
|
1893
|
-
const backupPath = this.filePath + ".bak";
|
|
1894
|
-
if (existsSync4(backupPath)) {
|
|
1895
|
-
const backupRaw = readFileSync4(backupPath, "utf-8");
|
|
1896
|
-
const parsedBackup = JSON.parse(backupRaw);
|
|
1897
|
-
writeFileSync4(this.filePath, backupRaw);
|
|
1898
|
-
return Array.isArray(parsedBackup) ? parsedBackup : [];
|
|
1899
|
-
}
|
|
1900
|
-
throw new Error(`Corrupted ops log at ${this.filePath} and no backup found. Run \`trellis repair\` to attempt recovery.`);
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
withLock(fn) {
|
|
1904
|
-
const dir = dirname3(this.filePath);
|
|
1905
|
-
if (!existsSync4(dir))
|
|
1906
|
-
mkdirSync3(dir, { recursive: true });
|
|
1907
|
-
const deadline = Date.now() + lockTimeoutMs();
|
|
1908
|
-
let lockFd;
|
|
1909
|
-
while (Date.now() < deadline) {
|
|
1910
|
-
try {
|
|
1911
|
-
lockFd = openSync2(this.lockPath, "wx");
|
|
1912
|
-
break;
|
|
1913
|
-
} catch (err) {
|
|
1914
|
-
if (err?.code !== "EEXIST") {
|
|
1915
|
-
throw err;
|
|
1974
|
+
readAll() {
|
|
1975
|
+
return [...this.ops];
|
|
1976
|
+
}
|
|
1977
|
+
getLastOp() {
|
|
1978
|
+
return this.ops.length > 0 ? this.ops[this.ops.length - 1] : void 0;
|
|
1979
|
+
}
|
|
1980
|
+
count() {
|
|
1981
|
+
return this.ops.length;
|
|
1982
|
+
}
|
|
1983
|
+
writeOpsToDisk() {
|
|
1984
|
+
const dir = dirname3(this.filePath);
|
|
1985
|
+
if (!existsSync4(dir)) mkdirSync3(dir, { recursive: true });
|
|
1986
|
+
if (existsSync4(this.filePath)) {
|
|
1987
|
+
const backupPath = this.filePath + ".bak";
|
|
1988
|
+
try {
|
|
1989
|
+
copyFileSync(this.filePath, backupPath);
|
|
1990
|
+
} catch {
|
|
1991
|
+
}
|
|
1916
1992
|
}
|
|
1993
|
+
const tempPath = `${this.filePath}.tmp`;
|
|
1994
|
+
writeFileSync4(tempPath, JSON.stringify(this.ops, null, 2));
|
|
1995
|
+
renameSync(tempPath, this.filePath);
|
|
1917
1996
|
}
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
fn();
|
|
1924
|
-
} finally {
|
|
1925
|
-
closeSync2(lockFd);
|
|
1926
|
-
try {
|
|
1927
|
-
unlinkSync2(this.lockPath);
|
|
1928
|
-
} catch {}
|
|
1929
|
-
}
|
|
1930
|
-
}
|
|
1931
|
-
static repair(filePath) {
|
|
1932
|
-
if (!existsSync4(filePath)) {
|
|
1933
|
-
return { recovered: 0, lost: 0 };
|
|
1934
|
-
}
|
|
1935
|
-
const raw = readFileSync4(filePath, "utf-8");
|
|
1936
|
-
try {
|
|
1937
|
-
const ops = JSON.parse(raw);
|
|
1938
|
-
return { recovered: ops.length, lost: 0 };
|
|
1939
|
-
} catch {}
|
|
1940
|
-
const lastHash = raw.lastIndexOf('"hash": "trellis:op:');
|
|
1941
|
-
if (lastHash === -1) {
|
|
1942
|
-
const bakPath = filePath + ".bak";
|
|
1943
|
-
if (existsSync4(bakPath)) {
|
|
1944
|
-
const bakRaw = readFileSync4(bakPath, "utf-8");
|
|
1997
|
+
readOpsFromDisk() {
|
|
1998
|
+
if (!existsSync4(this.filePath)) {
|
|
1999
|
+
return [];
|
|
2000
|
+
}
|
|
2001
|
+
const raw = readFileSync4(this.filePath, "utf-8");
|
|
1945
2002
|
try {
|
|
1946
|
-
const
|
|
1947
|
-
|
|
2003
|
+
const parsed = JSON.parse(raw);
|
|
2004
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
2005
|
+
} catch {
|
|
2006
|
+
const backupPath = this.filePath + ".bak";
|
|
2007
|
+
if (existsSync4(backupPath)) {
|
|
2008
|
+
const backupRaw = readFileSync4(backupPath, "utf-8");
|
|
2009
|
+
const parsedBackup = JSON.parse(backupRaw);
|
|
2010
|
+
writeFileSync4(this.filePath, backupRaw);
|
|
2011
|
+
return Array.isArray(parsedBackup) ? parsedBackup : [];
|
|
2012
|
+
}
|
|
2013
|
+
throw new Error(
|
|
2014
|
+
`Corrupted ops log at ${this.filePath} and no backup found. Run \`trellis repair\` to attempt recovery.`
|
|
2015
|
+
);
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
withLock(fn) {
|
|
2019
|
+
const dir = dirname3(this.filePath);
|
|
2020
|
+
if (!existsSync4(dir)) mkdirSync3(dir, { recursive: true });
|
|
2021
|
+
const deadline = Date.now() + lockTimeoutMs();
|
|
2022
|
+
let lockFd;
|
|
2023
|
+
while (Date.now() < deadline) {
|
|
2024
|
+
try {
|
|
2025
|
+
lockFd = openSync2(this.lockPath, "wx");
|
|
2026
|
+
break;
|
|
2027
|
+
} catch (err) {
|
|
2028
|
+
if (err?.code !== "EEXIST") {
|
|
2029
|
+
throw err;
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
if (lockFd === void 0) {
|
|
2034
|
+
throw new Error(
|
|
2035
|
+
`Timed out waiting for ops log lock: ${this.lockPath}. Another Trellis process may be stalled.`
|
|
2036
|
+
);
|
|
2037
|
+
}
|
|
2038
|
+
try {
|
|
2039
|
+
fn();
|
|
2040
|
+
} finally {
|
|
2041
|
+
closeSync2(lockFd);
|
|
2042
|
+
try {
|
|
2043
|
+
unlinkSync2(this.lockPath);
|
|
2044
|
+
} catch {
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
static repair(filePath) {
|
|
2049
|
+
if (!existsSync4(filePath)) {
|
|
2050
|
+
return { recovered: 0, lost: 0 };
|
|
2051
|
+
}
|
|
2052
|
+
const raw = readFileSync4(filePath, "utf-8");
|
|
2053
|
+
try {
|
|
2054
|
+
const ops = JSON.parse(raw);
|
|
2055
|
+
return { recovered: ops.length, lost: 0 };
|
|
2056
|
+
} catch {
|
|
2057
|
+
}
|
|
2058
|
+
const lastHash = raw.lastIndexOf('"hash": "trellis:op:');
|
|
2059
|
+
if (lastHash === -1) {
|
|
2060
|
+
const bakPath = filePath + ".bak";
|
|
2061
|
+
if (existsSync4(bakPath)) {
|
|
2062
|
+
const bakRaw = readFileSync4(bakPath, "utf-8");
|
|
2063
|
+
try {
|
|
2064
|
+
const ops = JSON.parse(bakRaw);
|
|
2065
|
+
writeFileSync4(filePath, bakRaw);
|
|
2066
|
+
return { recovered: ops.length, lost: 0 };
|
|
2067
|
+
} catch {
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
writeFileSync4(filePath, "[]");
|
|
2071
|
+
return { recovered: 0, lost: -1 };
|
|
2072
|
+
}
|
|
2073
|
+
const endOfLine = raw.indexOf("\n", lastHash);
|
|
2074
|
+
const closingBrace = raw.indexOf(" }", endOfLine);
|
|
2075
|
+
if (closingBrace === -1) {
|
|
2076
|
+
writeFileSync4(filePath, "[]");
|
|
2077
|
+
return { recovered: 0, lost: -1 };
|
|
2078
|
+
}
|
|
2079
|
+
const fixed = raw.slice(0, closingBrace + 3) + "\n]";
|
|
2080
|
+
try {
|
|
2081
|
+
const ops = JSON.parse(fixed);
|
|
2082
|
+
writeFileSync4(filePath + ".corrupted", raw);
|
|
2083
|
+
writeFileSync4(filePath, fixed);
|
|
1948
2084
|
return { recovered: ops.length, lost: 0 };
|
|
1949
|
-
} catch {
|
|
2085
|
+
} catch {
|
|
2086
|
+
writeFileSync4(filePath + ".corrupted", raw);
|
|
2087
|
+
writeFileSync4(filePath, "[]");
|
|
2088
|
+
return { recovered: 0, lost: -1 };
|
|
2089
|
+
}
|
|
1950
2090
|
}
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
if (closingBrace === -1) {
|
|
1958
|
-
writeFileSync4(filePath, "[]");
|
|
1959
|
-
return { recovered: 0, lost: -1 };
|
|
1960
|
-
}
|
|
1961
|
-
const fixed = raw.slice(0, closingBrace + 3) + `
|
|
1962
|
-
]`;
|
|
1963
|
-
try {
|
|
1964
|
-
const ops = JSON.parse(fixed);
|
|
1965
|
-
writeFileSync4(filePath + ".corrupted", raw);
|
|
1966
|
-
writeFileSync4(filePath, fixed);
|
|
1967
|
-
return { recovered: ops.length, lost: 0 };
|
|
1968
|
-
} catch {
|
|
1969
|
-
writeFileSync4(filePath + ".corrupted", raw);
|
|
1970
|
-
writeFileSync4(filePath, "[]");
|
|
1971
|
-
return { recovered: 0, lost: -1 };
|
|
1972
|
-
}
|
|
2091
|
+
};
|
|
2092
|
+
LaneOpLog = class extends JsonOpLog {
|
|
2093
|
+
constructor(laneDir2) {
|
|
2094
|
+
super(`${laneDir2}/ops.json`);
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
1973
2097
|
}
|
|
1974
|
-
}
|
|
1975
|
-
var LaneOpLog;
|
|
1976
|
-
var init_op_log = __esm(() => {
|
|
1977
|
-
LaneOpLog = class LaneOpLog extends JsonOpLog {
|
|
1978
|
-
constructor(laneDir) {
|
|
1979
|
-
super(`${laneDir}/ops.json`);
|
|
1980
|
-
}
|
|
1981
|
-
};
|
|
1982
2098
|
});
|
|
1983
2099
|
|
|
1984
2100
|
// src/vcs/lane.ts
|
|
@@ -1999,28 +2115,27 @@ function newLaneId() {
|
|
|
1999
2115
|
}
|
|
2000
2116
|
function loadLaneMeta(trellisDir, laneId) {
|
|
2001
2117
|
const path = laneMetaPath(trellisDir, laneId);
|
|
2002
|
-
if (!existsSync5(path))
|
|
2003
|
-
return;
|
|
2118
|
+
if (!existsSync5(path)) return void 0;
|
|
2004
2119
|
return JSON.parse(readFileSync5(path, "utf-8"));
|
|
2005
2120
|
}
|
|
2006
2121
|
function saveLaneMeta(trellisDir, meta) {
|
|
2007
2122
|
const dir = laneDir(trellisDir, meta.id);
|
|
2008
|
-
if (!existsSync5(dir))
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2123
|
+
if (!existsSync5(dir)) mkdirSync4(dir, { recursive: true });
|
|
2124
|
+
writeFileSync5(
|
|
2125
|
+
laneMetaPath(trellisDir, meta.id),
|
|
2126
|
+
JSON.stringify(meta, null, 2) + "\n"
|
|
2127
|
+
);
|
|
2012
2128
|
}
|
|
2013
2129
|
function listLaneIds(trellisDir) {
|
|
2014
2130
|
const root = lanesRoot(trellisDir);
|
|
2015
|
-
if (!existsSync5(root))
|
|
2016
|
-
return [];
|
|
2131
|
+
if (!existsSync5(root)) return [];
|
|
2017
2132
|
return readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.startsWith("lane-")).map((d) => d.name);
|
|
2018
2133
|
}
|
|
2019
2134
|
function resolveLaneHeadFromJournal(meta, laneOps) {
|
|
2020
2135
|
return laneOps.at(-1)?.hash ?? meta.headOpHash ?? meta.baseOpHash;
|
|
2021
2136
|
}
|
|
2022
2137
|
function createLaneMeta(trellisDir, params) {
|
|
2023
|
-
const now = new Date().toISOString();
|
|
2138
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2024
2139
|
const meta = {
|
|
2025
2140
|
id: newLaneId(),
|
|
2026
2141
|
status: "active",
|
|
@@ -2045,15 +2160,81 @@ function createLaneMeta(trellisDir, params) {
|
|
|
2045
2160
|
}
|
|
2046
2161
|
function updateLaneHead(trellisDir, laneId, headOpHash) {
|
|
2047
2162
|
const meta = loadLaneMeta(trellisDir, laneId);
|
|
2048
|
-
if (!meta)
|
|
2049
|
-
return;
|
|
2163
|
+
if (!meta) return;
|
|
2050
2164
|
meta.headOpHash = headOpHash;
|
|
2051
|
-
meta.updatedAt = new Date().toISOString();
|
|
2165
|
+
meta.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2052
2166
|
saveLaneMeta(trellisDir, meta);
|
|
2053
2167
|
}
|
|
2054
2168
|
function listLaneMetas(trellisDir) {
|
|
2055
|
-
return listLaneIds(trellisDir).map((id) => loadLaneMeta(trellisDir, id)).filter((m) => m !==
|
|
2169
|
+
return listLaneIds(trellisDir).map((id) => loadLaneMeta(trellisDir, id)).filter((m) => m !== void 0);
|
|
2056
2170
|
}
|
|
2057
|
-
var init_lane = (
|
|
2171
|
+
var init_lane = __esm({
|
|
2172
|
+
"src/vcs/lane.ts"() {
|
|
2173
|
+
"use strict";
|
|
2174
|
+
}
|
|
2175
|
+
});
|
|
2058
2176
|
|
|
2059
|
-
export {
|
|
2177
|
+
export {
|
|
2178
|
+
decompose,
|
|
2179
|
+
init_decompose,
|
|
2180
|
+
BlobStore,
|
|
2181
|
+
init_blob_store,
|
|
2182
|
+
shouldAdvanceBranchHead,
|
|
2183
|
+
getBranchHeadOpHash,
|
|
2184
|
+
createBranch,
|
|
2185
|
+
switchBranch,
|
|
2186
|
+
listBranches,
|
|
2187
|
+
deleteBranch,
|
|
2188
|
+
saveBranchState,
|
|
2189
|
+
loadBranchState,
|
|
2190
|
+
init_branch,
|
|
2191
|
+
createMilestone,
|
|
2192
|
+
listMilestones,
|
|
2193
|
+
init_milestone,
|
|
2194
|
+
createCheckpoint,
|
|
2195
|
+
listCheckpoints,
|
|
2196
|
+
init_checkpoint,
|
|
2197
|
+
diffFileStates,
|
|
2198
|
+
buildFileStateAtOp,
|
|
2199
|
+
diffOpRange,
|
|
2200
|
+
generateUnifiedDiff,
|
|
2201
|
+
myersDiff,
|
|
2202
|
+
init_diff,
|
|
2203
|
+
threeWayMerge,
|
|
2204
|
+
threeWayTextMerge,
|
|
2205
|
+
init_merge,
|
|
2206
|
+
createIssue,
|
|
2207
|
+
updateIssue,
|
|
2208
|
+
startIssue,
|
|
2209
|
+
pauseIssue,
|
|
2210
|
+
resumeIssue,
|
|
2211
|
+
closeIssue,
|
|
2212
|
+
triageIssue,
|
|
2213
|
+
reopenIssue,
|
|
2214
|
+
assignIssue,
|
|
2215
|
+
blockIssue,
|
|
2216
|
+
unblockIssue,
|
|
2217
|
+
addCriterion,
|
|
2218
|
+
setCriterionStatus,
|
|
2219
|
+
runCriteria,
|
|
2220
|
+
listIssues,
|
|
2221
|
+
getIssue,
|
|
2222
|
+
getActiveIssues,
|
|
2223
|
+
checkCompletionReadiness,
|
|
2224
|
+
init_issue,
|
|
2225
|
+
JsonOpLog,
|
|
2226
|
+
LaneOpLog,
|
|
2227
|
+
init_op_log,
|
|
2228
|
+
lanesRoot,
|
|
2229
|
+
laneDir,
|
|
2230
|
+
laneMetaPath,
|
|
2231
|
+
newLaneId,
|
|
2232
|
+
loadLaneMeta,
|
|
2233
|
+
saveLaneMeta,
|
|
2234
|
+
listLaneIds,
|
|
2235
|
+
resolveLaneHeadFromJournal,
|
|
2236
|
+
createLaneMeta,
|
|
2237
|
+
updateLaneHead,
|
|
2238
|
+
listLaneMetas,
|
|
2239
|
+
init_lane
|
|
2240
|
+
};
|