@rryando/arcs 4.2.1 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/cli/arcs-flash.d.ts +1 -1
- package/dist/cli/arcs-flash.d.ts.map +1 -1
- package/dist/cli/arcs-flash.js +8 -4
- package/dist/cli/arcs-flash.js.map +1 -1
- package/dist/cli/arcs-orchestrate.d.ts +1 -1
- package/dist/cli/arcs-orchestrate.d.ts.map +1 -1
- package/dist/cli/arcs-orchestrate.js +6 -2
- package/dist/cli/arcs-orchestrate.js.map +1 -1
- package/dist/cli/arg-parser.d.ts +1 -0
- package/dist/cli/arg-parser.d.ts.map +1 -1
- package/dist/cli/arg-parser.js +12 -2
- package/dist/cli/arg-parser.js.map +1 -1
- package/dist/cli/command-registry.d.ts +2 -0
- package/dist/cli/command-registry.d.ts.map +1 -1
- package/dist/cli/command-registry.js.map +1 -1
- package/dist/cli/commands/index.d.ts +2 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +2 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/proposal-doc.js +3 -2
- package/dist/cli/commands/proposal-doc.js.map +1 -1
- package/dist/cli/commands/remember.js +1 -0
- package/dist/cli/commands/remember.js.map +1 -1
- package/dist/cli/commands/worktree.d.ts +2 -0
- package/dist/cli/commands/worktree.d.ts.map +1 -0
- package/dist/cli/commands/worktree.js +608 -0
- package/dist/cli/commands/worktree.js.map +1 -0
- package/dist/cli/dag-commands.d.ts +9 -0
- package/dist/cli/dag-commands.d.ts.map +1 -1
- package/dist/cli/dag-commands.js +37 -26
- package/dist/cli/dag-commands.js.map +1 -1
- package/dist/cli/help-generator.d.ts.map +1 -1
- package/dist/cli/help-generator.js +3 -0
- package/dist/cli/help-generator.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +14 -24
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/orchestrator-shared-blocks.d.ts +7 -5
- package/dist/cli/orchestrator-shared-blocks.d.ts.map +1 -1
- package/dist/cli/orchestrator-shared-blocks.js +45 -21
- package/dist/cli/orchestrator-shared-blocks.js.map +1 -1
- package/dist/cli/write-gate.d.ts +20 -0
- package/dist/cli/write-gate.d.ts.map +1 -0
- package/dist/cli/write-gate.js +39 -0
- package/dist/cli/write-gate.js.map +1 -0
- package/dist/utils/worktree-store.d.ts +54 -0
- package/dist/utils/worktree-store.d.ts.map +1 -0
- package/dist/utils/worktree-store.js +150 -0
- package/dist/utils/worktree-store.js.map +1 -0
- package/dist/utils/worktree.d.ts +71 -0
- package/dist/utils/worktree.d.ts.map +1 -0
- package/dist/utils/worktree.js +197 -0
- package/dist/utils/worktree.js.map +1 -0
- package/dist/web-client/assets/{GraphCanvas-Dw6EcoDb.js → GraphCanvas-BYZE4sO9.js} +1 -1
- package/dist/web-client/assets/{MarkdownEditor-Cz5_44Ej.js → MarkdownEditor-BKx6M1cw.js} +1 -1
- package/dist/web-client/assets/{abnfDiagram-VRR7QNED-CFJzLuew.js → abnfDiagram-VRR7QNED-D4kt0l2y.js} +1 -1
- package/dist/web-client/assets/architecture-TIHT7OUA-CIdGE6VO.js +1 -0
- package/dist/web-client/assets/{architectureDiagram-ZJ3FMSHR-FRlSgnnW.js → architectureDiagram-ZJ3FMSHR-bu29SJFS.js} +1 -1
- package/dist/web-client/assets/{blockDiagram-677ZJIJ3-WUkkunPZ.js → blockDiagram-677ZJIJ3-hsu7mXKw.js} +1 -1
- package/dist/web-client/assets/{c4Diagram-LMCZKHZV-BKeAsL6F.js → c4Diagram-LMCZKHZV-DMllRlT_.js} +1 -1
- package/dist/web-client/assets/channel-CBg-s-ZD.js +1 -0
- package/dist/web-client/assets/{chunk-32BRIVSS-B0b9kUcF.js → chunk-32BRIVSS-BSzwj5eM.js} +1 -1
- package/dist/web-client/assets/{chunk-52WLFC77-i6Y-vfL3.js → chunk-52WLFC77-RDdZn6yY.js} +1 -1
- package/dist/web-client/assets/{chunk-C7G6YPKG-atYWm6iP.js → chunk-C7G6YPKG-DQr--txT.js} +1 -1
- package/dist/web-client/assets/{chunk-EX3LRPZG-CZD6y0UU.js → chunk-EX3LRPZG-Bb8nc4z4.js} +1 -1
- package/dist/web-client/assets/{chunk-FWX5IMBZ-CVErR-UZ.js → chunk-FWX5IMBZ-QvBpOcOg.js} +2 -2
- package/dist/web-client/assets/{chunk-HOUHSVGY-BlHO2iQ3.js → chunk-HOUHSVGY-B0mX_yjc.js} +1 -1
- package/dist/web-client/assets/{chunk-ICXQ74PX-Ar8kfXfa.js → chunk-ICXQ74PX-BmJSQqOH.js} +1 -1
- package/dist/web-client/assets/{chunk-MOJQB5TN-DKrK867P.js → chunk-MOJQB5TN-BrEI4GGn.js} +1 -1
- package/dist/web-client/assets/{chunk-OGEWGWER-BmGykUeg.js → chunk-OGEWGWER-CrqDPOWP.js} +1 -1
- package/dist/web-client/assets/{chunk-PUDLZKDR-Bq23pnso.js → chunk-PUDLZKDR-DfPKldpG.js} +1 -1
- package/dist/web-client/assets/{chunk-Q4XR5HBZ-g15qvFAN.js → chunk-Q4XR5HBZ-ekATI9aV.js} +1 -1
- package/dist/web-client/assets/{chunk-V7JOEXUC-uyXA7S9r.js → chunk-V7JOEXUC-C5APsP1t.js} +1 -1
- package/dist/web-client/assets/{chunk-VAUOI2AC-WofZ-2M0.js → chunk-VAUOI2AC-BhfSWJZI.js} +1 -1
- package/dist/web-client/assets/{chunk-VR4S4FIN-DtTkK86v.js → chunk-VR4S4FIN-BGa-44J7.js} +1 -1
- package/dist/web-client/assets/{chunk-WYO6CB5R-zVyUwJq3.js → chunk-WYO6CB5R-By1K0guW.js} +1 -1
- package/dist/web-client/assets/{chunk-ZGVPDNZ5-CA1Oe3TK.js → chunk-ZGVPDNZ5-Vnzpc76F.js} +1 -1
- package/dist/web-client/assets/classDiagram-OUVF2IWQ-ciwDjhUR.js +1 -0
- package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-ciwDjhUR.js +1 -0
- package/dist/web-client/assets/{cynefin-VYW2F7L2-ivJY1h_9.js → cynefin-VYW2F7L2-C6MOMOOz.js} +1 -1
- package/dist/web-client/assets/{cynefinDiagram-TSTJHNR4-D2DstShq.js → cynefinDiagram-TSTJHNR4-Cseyu79b.js} +1 -1
- package/dist/web-client/assets/{dagre-VKFMJZFB-CwnMRy0K.js → dagre-VKFMJZFB-CQJlIuNh.js} +1 -1
- package/dist/web-client/assets/{diagram-FQU43EPY-BKJv6Cvw.js → diagram-FQU43EPY-DpqDxhq4.js} +1 -1
- package/dist/web-client/assets/{diagram-G47NLZAW-CwCXcgU5.js → diagram-G47NLZAW-C11fYYaF.js} +1 -1
- package/dist/web-client/assets/{diagram-NH7WQ7WH-CkghU1-6.js → diagram-NH7WQ7WH-BiG-uRAF.js} +1 -1
- package/dist/web-client/assets/{diagram-OA4YK3LP-D3siQIGu.js → diagram-OA4YK3LP-CIXWWjq-.js} +1 -1
- package/dist/web-client/assets/{diagram-WEI45ONY-CSs9xTBn.js → diagram-WEI45ONY-C3OgIWu9.js} +1 -1
- package/dist/web-client/assets/{ebnfDiagram-CCIWWBDH--i52vMiv.js → ebnfDiagram-CCIWWBDH-BHF_NA3_.js} +1 -1
- package/dist/web-client/assets/{erDiagram-Q63AITRT-q2hgOBY1.js → erDiagram-Q63AITRT-CUOJCrLy.js} +1 -1
- package/dist/web-client/assets/eventmodeling-45OFAUF4-DxfboL1J.js +1 -0
- package/dist/web-client/assets/flowDiagram-23GEKE2U-C3NzpTtI.js +1 -0
- package/dist/web-client/assets/{ganttDiagram-NO4QXBWP-BZ2rBbTe.js → ganttDiagram-NO4QXBWP-D_4BMJ-g.js} +1 -1
- package/dist/web-client/assets/{gitGraph-TEB2WS4Q-OnJ8tHgt.js → gitGraph-TEB2WS4Q-CBuaZBId.js} +1 -1
- package/dist/web-client/assets/{gitGraphDiagram-IHSO6WYX-CPNExFAr.js → gitGraphDiagram-IHSO6WYX-BbztsGuO.js} +1 -1
- package/dist/web-client/assets/index-B1KVIr80.css +2 -0
- package/dist/web-client/assets/{index-DCBn-YrR.js → index-BWd2fBNL.js} +38 -38
- package/dist/web-client/assets/{info-DKCQHKI2-DGuJbmdY.js → info-DKCQHKI2-Bzi0Xjro.js} +1 -1
- package/dist/web-client/assets/{infoDiagram-FWYZ7A6U-ADIAn-P5.js → infoDiagram-FWYZ7A6U-BkeEKcr0.js} +1 -1
- package/dist/web-client/assets/{ishikawaDiagram-FXEZZL3T-CUx-RGfg.js → ishikawaDiagram-FXEZZL3T-CVusWu0p.js} +1 -1
- package/dist/web-client/assets/{journeyDiagram-5HDEW3XC-BH7-tBBy.js → journeyDiagram-5HDEW3XC-BUxu71zw.js} +1 -1
- package/dist/web-client/assets/{kanban-definition-HUTT4EX6-BGEXBnI2.js → kanban-definition-HUTT4EX6-BE8Hv4Kd.js} +1 -1
- package/dist/web-client/assets/{line-CC-5ezU8.js → line-CiAoINJS.js} +1 -1
- package/dist/web-client/assets/{mermaid-parser.core-Dw18Fjbq.js → mermaid-parser.core-BW47khiS.js} +3 -3
- package/dist/web-client/assets/{mermaid.core-CMQBgE43.js → mermaid.core-DP--Jl9R.js} +3 -3
- package/dist/web-client/assets/{mindmap-definition-LN4V7U3C-CGtjw8tB.js → mindmap-definition-LN4V7U3C-CvWJUqdq.js} +1 -1
- package/dist/web-client/assets/{packet-7NZHBO7P-w71Y4Hzd.js → packet-7NZHBO7P-XtzX9SaQ.js} +1 -1
- package/dist/web-client/assets/{pegDiagram-2B236MQR-DWtfEm4T.js → pegDiagram-2B236MQR-XNo0K1ct.js} +1 -1
- package/dist/web-client/assets/{pie-RZYD4A2V-S9ztgnWs.js → pie-RZYD4A2V-B1eUd9yt.js} +1 -1
- package/dist/web-client/assets/{pieDiagram-ENE6RG2P-BWZQPN4m.js → pieDiagram-ENE6RG2P-CRSb5z-4.js} +1 -1
- package/dist/web-client/assets/{quadrantDiagram-ABIIQ3AL-DINDwblH.js → quadrantDiagram-ABIIQ3AL-DziMaQxE.js} +1 -1
- package/dist/web-client/assets/{radar-I7S5WNFK-BOGl9krB.js → radar-I7S5WNFK-BpRqZH2g.js} +1 -1
- package/dist/web-client/assets/{railroad-3IZDKUUU-CR9kuYSZ.js → railroad-3IZDKUUU-FDIHW04k.js} +1 -1
- package/dist/web-client/assets/railroad-abnf-AHOZXSZD-BKj6JAhH.js +1 -0
- package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-ChDM1OBv.js +1 -0
- package/dist/web-client/assets/railroad-peg-LSFZ7HO6-DvwA2e0i.js +1 -0
- package/dist/web-client/assets/{railroadDiagram-RFXS5EU6-byLCs9hp.js → railroadDiagram-RFXS5EU6-Cs7EVBaz.js} +1 -1
- package/dist/web-client/assets/{requirementDiagram-TGXJPOKE-Dn_FtbqW.js → requirementDiagram-TGXJPOKE-B9_Lj1ga.js} +1 -1
- package/dist/web-client/assets/{sankeyDiagram-HTMAVEWB-DUjRrCeC.js → sankeyDiagram-HTMAVEWB-DuTJTiy0.js} +1 -1
- package/dist/web-client/assets/{sequenceDiagram-DBY2YBRQ-BmBz8Wpq.js → sequenceDiagram-DBY2YBRQ-vOCU5UoE.js} +1 -1
- package/dist/web-client/assets/{stateDiagram-2N3HPSRC-BAYHjmqB.js → stateDiagram-2N3HPSRC-rxAnfzWn.js} +1 -1
- package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-B3EvQPEe.js +1 -0
- package/dist/web-client/assets/{swimlanes-5IMT3BWC-Bm942AR-.js → swimlanes-5IMT3BWC-gdVZUnPe.js} +1 -1
- package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-WcOXuCPg.js +8 -0
- package/dist/web-client/assets/{timeline-definition-FHXFAJF6-CHAZHhQk.js → timeline-definition-FHXFAJF6-Do68JyGy.js} +1 -1
- package/dist/web-client/assets/{treeView-QDETBFTQ-DHHkLsSy.js → treeView-QDETBFTQ-CdZkmg80.js} +1 -1
- package/dist/web-client/assets/{treemap-6X3UGDF4-BUxZ8fhY.js → treemap-6X3UGDF4-ub54fmpW.js} +1 -1
- package/dist/web-client/assets/{vennDiagram-L72KCM5P-BL9TRcUU.js → vennDiagram-L72KCM5P-D-r8NBEp.js} +1 -1
- package/dist/web-client/assets/{wardley-OPB4EBWU-CfJ5mO-y.js → wardley-OPB4EBWU-CTleH1-J.js} +1 -1
- package/dist/web-client/assets/{wardleyDiagram-EHGQE667-BlH1TSjy.js → wardleyDiagram-EHGQE667-BU8Kw39F.js} +1 -1
- package/dist/web-client/assets/{xychartDiagram-FW5EYKEG-BJN6wtrV.js → xychartDiagram-FW5EYKEG-CfNnag6i.js} +1 -1
- package/dist/web-client/index.html +2 -2
- package/dist/web-server/routes/sessions.js +43 -2
- package/dist/web-server/routes/sessions.js.map +1 -1
- package/opencode/arcs/.opencode/plugins/arcs.js +5 -1
- package/opencode/arcs/bundle-runtime.json +3 -0
- package/opencode/arcs/prompts/arcs-docs.txt +1 -1
- package/opencode/arcs/prompts/arcs-flash.txt +46 -20
- package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +47 -21
- package/opencode/arcs/prompts/arcs-orchestrate.txt +47 -21
- package/opencode/arcs/prompts/software-engineer.txt +6 -0
- package/opencode/arcs/skills/writing-proposals/SKILL.md +90 -0
- package/package.json +2 -2
- package/scripts/build-opencode-bundle.mjs +7 -8
- package/dist/cli/commands/hooks.d.ts +0 -76
- package/dist/cli/commands/hooks.d.ts.map +0 -1
- package/dist/cli/commands/hooks.js +0 -436
- package/dist/cli/commands/hooks.js.map +0 -1
- package/dist/utils/claude-code-hook-install.d.ts +0 -80
- package/dist/utils/claude-code-hook-install.d.ts.map +0 -1
- package/dist/utils/claude-code-hook-install.js +0 -212
- package/dist/utils/claude-code-hook-install.js.map +0 -1
- package/dist/utils/graphify-knowledge.d.ts +0 -22
- package/dist/utils/graphify-knowledge.d.ts.map +0 -1
- package/dist/utils/graphify-knowledge.js +0 -47
- package/dist/utils/graphify-knowledge.js.map +0 -1
- package/dist/utils/graphify.d.ts +0 -104
- package/dist/utils/graphify.d.ts.map +0 -1
- package/dist/utils/graphify.js +0 -439
- package/dist/utils/graphify.js.map +0 -1
- package/dist/utils/hook-contract.d.ts +0 -36
- package/dist/utils/hook-contract.d.ts.map +0 -1
- package/dist/utils/hook-contract.js +0 -35
- package/dist/utils/hook-contract.js.map +0 -1
- package/dist/utils/hook-token-store.d.ts +0 -63
- package/dist/utils/hook-token-store.d.ts.map +0 -1
- package/dist/utils/hook-token-store.js +0 -88
- package/dist/utils/hook-token-store.js.map +0 -1
- package/dist/web-client/assets/architecture-TIHT7OUA-CoHvhex9.js +0 -1
- package/dist/web-client/assets/channel-D8xMXC5_.js +0 -1
- package/dist/web-client/assets/classDiagram-OUVF2IWQ-Doj1_hvZ.js +0 -1
- package/dist/web-client/assets/classDiagram-v2-EOCWNBFH-Doj1_hvZ.js +0 -1
- package/dist/web-client/assets/eventmodeling-45OFAUF4-ESVuFkJJ.js +0 -1
- package/dist/web-client/assets/flowDiagram-23GEKE2U-DN9SdR9f.js +0 -1
- package/dist/web-client/assets/index-wSzUPvml.css +0 -2
- package/dist/web-client/assets/railroad-abnf-AHOZXSZD-BvbCHrlR.js +0 -1
- package/dist/web-client/assets/railroad-ebnf-EBAXGLYW-D869lbCL.js +0 -1
- package/dist/web-client/assets/railroad-peg-LSFZ7HO6-r4TXaJPI.js +0 -1
- package/dist/web-client/assets/stateDiagram-v2-6OUMAXLB-Bl-1K1zV.js +0 -1
- package/dist/web-client/assets/swimlanesDiagram-G3AALYLV-DHU7bsfA.js +0 -8
- package/dist/web-server/hook-auth.d.ts +0 -12
- package/dist/web-server/hook-auth.d.ts.map +0 -1
- package/dist/web-server/hook-auth.js +0 -36
- package/dist/web-server/hook-auth.js.map +0 -1
- package/dist/web-server/opencode-client.d.ts +0 -123
- package/dist/web-server/opencode-client.d.ts.map +0 -1
- package/dist/web-server/opencode-client.js +0 -514
- package/dist/web-server/opencode-client.js.map +0 -1
- package/dist/web-server/routes/hook-events.d.ts +0 -43
- package/dist/web-server/routes/hook-events.d.ts.map +0 -1
- package/dist/web-server/routes/hook-events.js +0 -316
- package/dist/web-server/routes/hook-events.js.map +0 -1
package/dist/utils/graphify.js
DELETED
|
@@ -1,439 +0,0 @@
|
|
|
1
|
-
import { execSync, spawnSync } from "node:child_process";
|
|
2
|
-
import { appendFileSync, existsSync, readFileSync } from "node:fs";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
4
|
-
export function detectGraphify() {
|
|
5
|
-
try {
|
|
6
|
-
const version = execSync("graphify --version", {
|
|
7
|
-
encoding: "utf-8",
|
|
8
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
9
|
-
timeout: 5000,
|
|
10
|
-
}).trim();
|
|
11
|
-
const resolvedPath = execSync("which graphify", {
|
|
12
|
-
encoding: "utf-8",
|
|
13
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
14
|
-
timeout: 5000,
|
|
15
|
-
}).trim();
|
|
16
|
-
// Extract semver from output (e.g. "graphify 0.8.18" or just "0.8.18")
|
|
17
|
-
const match = version.match(/(\d+\.\d+\.\d+)/);
|
|
18
|
-
return {
|
|
19
|
-
available: true,
|
|
20
|
-
version: match ? match[1] : version,
|
|
21
|
-
path: resolvedPath || undefined,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return { available: false };
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function parseGraphJson(graphPath) {
|
|
29
|
-
try {
|
|
30
|
-
const raw = readFileSync(graphPath, "utf-8");
|
|
31
|
-
const data = JSON.parse(raw);
|
|
32
|
-
if (!Array.isArray(data?.nodes) || data.nodes.length === 0)
|
|
33
|
-
return null;
|
|
34
|
-
// Normalize links (graphify uses "links" key; older format used "edges")
|
|
35
|
-
const links = data.links || data.edges || [];
|
|
36
|
-
// Compute degree (total) plus directional in/out per node
|
|
37
|
-
const degreeMap = new Map();
|
|
38
|
-
const inMap = new Map();
|
|
39
|
-
const outMap = new Map();
|
|
40
|
-
for (const link of links) {
|
|
41
|
-
degreeMap.set(link.source, (degreeMap.get(link.source) || 0) + 1);
|
|
42
|
-
degreeMap.set(link.target, (degreeMap.get(link.target) || 0) + 1);
|
|
43
|
-
outMap.set(link.source, (outMap.get(link.source) || 0) + 1);
|
|
44
|
-
inMap.set(link.target, (inMap.get(link.target) || 0) + 1);
|
|
45
|
-
}
|
|
46
|
-
// Normalize nodes
|
|
47
|
-
const nodes = data.nodes.map((n) => ({
|
|
48
|
-
id: n.id,
|
|
49
|
-
label: n.label,
|
|
50
|
-
type: n.type || n.file_type || "unknown",
|
|
51
|
-
fileType: n.file_type || n.type || "unknown",
|
|
52
|
-
file: n.file || n.source_file || "",
|
|
53
|
-
community: n.community ?? -1,
|
|
54
|
-
degree: n.degree ?? degreeMap.get(n.id) ?? 0,
|
|
55
|
-
inDegree: inMap.get(n.id) ?? 0,
|
|
56
|
-
outDegree: outMap.get(n.id) ?? 0,
|
|
57
|
-
}));
|
|
58
|
-
// Use communities if available; otherwise synthesize from source_file grouping
|
|
59
|
-
const communities = data.communities || [];
|
|
60
|
-
if (communities.length === 0) {
|
|
61
|
-
// Group nodes by directory prefix as pseudo-communities
|
|
62
|
-
const dirGroups = new Map();
|
|
63
|
-
for (const node of nodes) {
|
|
64
|
-
if (!node.file)
|
|
65
|
-
continue;
|
|
66
|
-
const dir = node.file.split("/").slice(0, -1).join("/") || ".";
|
|
67
|
-
const list = dirGroups.get(dir) || [];
|
|
68
|
-
list.push(node.id);
|
|
69
|
-
dirGroups.set(dir, list);
|
|
70
|
-
}
|
|
71
|
-
let communityId = 0;
|
|
72
|
-
for (const [dir, nodeIds] of dirGroups) {
|
|
73
|
-
if (nodeIds.length >= 3) {
|
|
74
|
-
communities.push({
|
|
75
|
-
id: communityId++,
|
|
76
|
-
label: dir,
|
|
77
|
-
nodes: nodeIds,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return { nodes, communities, links };
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
function percentile(values, p) {
|
|
89
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
90
|
-
const idx = (p / 100) * (sorted.length - 1);
|
|
91
|
-
const lower = Math.floor(idx);
|
|
92
|
-
const frac = idx - lower;
|
|
93
|
-
if (lower + 1 >= sorted.length)
|
|
94
|
-
return sorted[lower];
|
|
95
|
-
return sorted[lower] + frac * (sorted[lower + 1] - sorted[lower]);
|
|
96
|
-
}
|
|
97
|
-
export function ingestGraph(graphJsonPath, _slug) {
|
|
98
|
-
const empty = {
|
|
99
|
-
proposals: [],
|
|
100
|
-
stats: { godNodes: 0, communities: 0, crossModuleCouplings: 0, totalProposals: 0 },
|
|
101
|
-
};
|
|
102
|
-
const graph = parseGraphJson(graphJsonPath);
|
|
103
|
-
if (!graph || graph.nodes.length === 0)
|
|
104
|
-
return empty;
|
|
105
|
-
const proposals = [];
|
|
106
|
-
const nodeMap = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
107
|
-
// God nodes (degree > 95th percentile — top 5% most connected)
|
|
108
|
-
// Exclude test files — they naturally import many modules but aren't architectural hubs
|
|
109
|
-
const isTestFile = (file) => /\.(test|spec)\.[jt]sx?$/.test(file) ||
|
|
110
|
-
file.startsWith("test/") ||
|
|
111
|
-
file.startsWith("tests/") ||
|
|
112
|
-
file.includes("/__tests__/");
|
|
113
|
-
const degrees = graph.nodes.map((n) => n.degree).filter((d) => d > 0);
|
|
114
|
-
const threshold = percentile(degrees, 95);
|
|
115
|
-
const godNodes = graph.nodes
|
|
116
|
-
.filter((n) => n.degree > threshold && n.file && !isTestFile(n.file))
|
|
117
|
-
.sort((a, b) => b.degree - a.degree)
|
|
118
|
-
.slice(0, 8); // cap god nodes at 8 to leave room for other kinds
|
|
119
|
-
for (const node of godNodes) {
|
|
120
|
-
// Top callers: nodes with edge → this node, ranked by their own degree.
|
|
121
|
-
const callerDegreeById = new Map();
|
|
122
|
-
const calleeDegreeById = new Map();
|
|
123
|
-
for (const link of graph.links) {
|
|
124
|
-
if (link.target === node.id && link.source !== node.id) {
|
|
125
|
-
const src = nodeMap.get(link.source);
|
|
126
|
-
if (src)
|
|
127
|
-
callerDegreeById.set(src.id, src.degree);
|
|
128
|
-
}
|
|
129
|
-
if (link.source === node.id && link.target !== node.id) {
|
|
130
|
-
const tgt = nodeMap.get(link.target);
|
|
131
|
-
if (tgt)
|
|
132
|
-
calleeDegreeById.set(tgt.id, tgt.degree);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
const topCallers = [...callerDegreeById.entries()]
|
|
136
|
-
.sort((a, b) => b[1] - a[1])
|
|
137
|
-
.slice(0, 5)
|
|
138
|
-
.map(([id]) => {
|
|
139
|
-
const n = nodeMap.get(id);
|
|
140
|
-
return n ? { label: n.label, file: n.file } : null;
|
|
141
|
-
})
|
|
142
|
-
.filter((x) => x !== null);
|
|
143
|
-
const topCallees = [...calleeDegreeById.entries()]
|
|
144
|
-
.sort((a, b) => b[1] - a[1])
|
|
145
|
-
.slice(0, 5)
|
|
146
|
-
.map(([id]) => {
|
|
147
|
-
const n = nodeMap.get(id);
|
|
148
|
-
return n ? { label: n.label, file: n.file } : null;
|
|
149
|
-
})
|
|
150
|
-
.filter((x) => x !== null);
|
|
151
|
-
proposals.push({
|
|
152
|
-
id: makeProposalId("graphify-god", `${node.label}-${node.file}`),
|
|
153
|
-
kind: "module",
|
|
154
|
-
label: node.label,
|
|
155
|
-
structuralFacts: {
|
|
156
|
-
nodeFile: node.file,
|
|
157
|
-
nodeIn: node.inDegree,
|
|
158
|
-
nodeOut: node.outDegree,
|
|
159
|
-
topCallers,
|
|
160
|
-
topCallees,
|
|
161
|
-
},
|
|
162
|
-
sourceFiles: [{ path: node.file }],
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
// Community clusters (sorted by size desc, top 8). Drop document-only clusters.
|
|
166
|
-
const allCommunities = [...(graph.communities || [])].sort((a, b) => b.nodes.length - a.nodes.length);
|
|
167
|
-
// Build community-membership map for cross-cluster degree calculations.
|
|
168
|
-
const communityIdByNode = new Map();
|
|
169
|
-
for (const c of allCommunities) {
|
|
170
|
-
for (const nodeId of c.nodes)
|
|
171
|
-
communityIdByNode.set(nodeId, c.id);
|
|
172
|
-
}
|
|
173
|
-
const survivingCommunities = [];
|
|
174
|
-
for (const community of allCommunities) {
|
|
175
|
-
const members = community.nodes.map((id) => nodeMap.get(id)).filter((n) => !!n);
|
|
176
|
-
if (members.length === 0)
|
|
177
|
-
continue;
|
|
178
|
-
// Filtering rule: drop the cluster if EVERY member has file_type === "document".
|
|
179
|
-
const hasNonDocument = members.some((m) => m.fileType !== "document");
|
|
180
|
-
if (!hasNonDocument)
|
|
181
|
-
continue;
|
|
182
|
-
survivingCommunities.push(community);
|
|
183
|
-
if (survivingCommunities.length >= 8)
|
|
184
|
-
break;
|
|
185
|
-
}
|
|
186
|
-
for (const community of survivingCommunities) {
|
|
187
|
-
const members = community.nodes.map((id) => nodeMap.get(id)).filter((n) => !!n);
|
|
188
|
-
// memberCount, fileCount, fileTypeBreakdown
|
|
189
|
-
const memberCount = members.length;
|
|
190
|
-
const fileSet = new Set();
|
|
191
|
-
const fileTypeBreakdown = {};
|
|
192
|
-
const fileEntityCount = new Map();
|
|
193
|
-
for (const m of members) {
|
|
194
|
-
if (m.file)
|
|
195
|
-
fileSet.add(m.file);
|
|
196
|
-
const ft = m.fileType || "unknown";
|
|
197
|
-
fileTypeBreakdown[ft] = (fileTypeBreakdown[ft] || 0) + 1;
|
|
198
|
-
if (m.file) {
|
|
199
|
-
fileEntityCount.set(m.file, (fileEntityCount.get(m.file) || 0) + 1);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// topHubs: top 3 by in+out
|
|
203
|
-
const topHubs = [...members]
|
|
204
|
-
.sort((a, b) => b.inDegree + b.outDegree - (a.inDegree + a.outDegree))
|
|
205
|
-
.slice(0, 3)
|
|
206
|
-
.filter((m) => m.inDegree + m.outDegree > 0)
|
|
207
|
-
.map((m) => ({ label: m.label, file: m.file, in: m.inDegree, out: m.outDegree }));
|
|
208
|
-
// topFilesByEntityCount: top 3
|
|
209
|
-
const topFilesByEntityCount = [...fileEntityCount.entries()]
|
|
210
|
-
.sort((a, b) => b[1] - a[1])
|
|
211
|
-
.slice(0, 3)
|
|
212
|
-
.map(([file, count]) => ({ file, count }));
|
|
213
|
-
// Cross-cluster degree: count links where one endpoint is in this community
|
|
214
|
-
// and the other endpoint is in a DIFFERENT community.
|
|
215
|
-
const memberIds = new Set(community.nodes);
|
|
216
|
-
let incoming = 0;
|
|
217
|
-
let outgoing = 0;
|
|
218
|
-
for (const link of graph.links) {
|
|
219
|
-
const srcInCluster = memberIds.has(link.source);
|
|
220
|
-
const tgtInCluster = memberIds.has(link.target);
|
|
221
|
-
if (srcInCluster === tgtInCluster)
|
|
222
|
-
continue; // same-side or both-out → ignore
|
|
223
|
-
// Only count edges where the OTHER endpoint belongs to some community
|
|
224
|
-
// (otherwise it's not "another cluster", just stray nodes).
|
|
225
|
-
const otherId = srcInCluster ? link.target : link.source;
|
|
226
|
-
const otherCommunity = communityIdByNode.get(otherId);
|
|
227
|
-
if (otherCommunity === undefined || otherCommunity === community.id)
|
|
228
|
-
continue;
|
|
229
|
-
if (srcInCluster)
|
|
230
|
-
outgoing++;
|
|
231
|
-
else
|
|
232
|
-
incoming++;
|
|
233
|
-
}
|
|
234
|
-
const uniqueFiles = [...fileSet];
|
|
235
|
-
proposals.push({
|
|
236
|
-
id: makeProposalId("graphify-cluster", community.label),
|
|
237
|
-
kind: "architecture",
|
|
238
|
-
label: community.label,
|
|
239
|
-
structuralFacts: {
|
|
240
|
-
memberCount,
|
|
241
|
-
fileCount: uniqueFiles.length,
|
|
242
|
-
fileTypeBreakdown,
|
|
243
|
-
topHubs,
|
|
244
|
-
topFilesByEntityCount,
|
|
245
|
-
incomingFromOtherClusters: incoming,
|
|
246
|
-
outgoingToOtherClusters: outgoing,
|
|
247
|
-
},
|
|
248
|
-
sourceFiles: uniqueFiles.map((p) => ({ path: p })),
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
const couplingByKey = new Map();
|
|
252
|
-
for (const link of graph.links) {
|
|
253
|
-
const nodeA = nodeMap.get(link.source);
|
|
254
|
-
const nodeB = nodeMap.get(link.target);
|
|
255
|
-
if (!nodeA || !nodeB || !nodeA.file || !nodeB.file)
|
|
256
|
-
continue;
|
|
257
|
-
if (isTestFile(nodeA.file) || isTestFile(nodeB.file))
|
|
258
|
-
continue;
|
|
259
|
-
const dirA = nodeA.file.split("/").slice(0, 2).join("/");
|
|
260
|
-
const dirB = nodeB.file.split("/").slice(0, 2).join("/");
|
|
261
|
-
if (!dirA || !dirB || dirA === dirB)
|
|
262
|
-
continue;
|
|
263
|
-
if (nodeA.degree <= threshold && nodeB.degree <= threshold)
|
|
264
|
-
continue;
|
|
265
|
-
const [first, second] = nodeA.id < nodeB.id ? [nodeA, nodeB] : [nodeB, nodeA];
|
|
266
|
-
const key = `${first.id}|${second.id}`;
|
|
267
|
-
const existing = couplingByKey.get(key);
|
|
268
|
-
if (existing) {
|
|
269
|
-
if (link.relation)
|
|
270
|
-
existing.relations.add(link.relation);
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
273
|
-
couplingByKey.set(key, {
|
|
274
|
-
a: first,
|
|
275
|
-
b: second,
|
|
276
|
-
relations: new Set(link.relation ? [link.relation] : []),
|
|
277
|
-
combinedDegree: first.degree + second.degree,
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
const couplings = [...couplingByKey.values()]
|
|
282
|
-
.sort((x, y) => y.combinedDegree - x.combinedDegree)
|
|
283
|
-
.slice(0, 5);
|
|
284
|
-
for (const { a, b, relations } of couplings) {
|
|
285
|
-
proposals.push({
|
|
286
|
-
id: makeProposalId("graphify-coupling", `${a.label}-${b.label}`),
|
|
287
|
-
kind: "gotcha",
|
|
288
|
-
label: `${a.label} ↔ ${b.label}`,
|
|
289
|
-
structuralFacts: {
|
|
290
|
-
couplingA: { label: a.label, file: a.file, degree: a.degree },
|
|
291
|
-
couplingB: { label: b.label, file: b.file, degree: b.degree },
|
|
292
|
-
relations: [...relations],
|
|
293
|
-
},
|
|
294
|
-
sourceFiles: [{ path: a.file }, { path: b.file }],
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
// Cap at 20
|
|
298
|
-
const capped = proposals.slice(0, 20);
|
|
299
|
-
return {
|
|
300
|
-
proposals: capped,
|
|
301
|
-
stats: {
|
|
302
|
-
godNodes: godNodes.length,
|
|
303
|
-
communities: survivingCommunities.length,
|
|
304
|
-
crossModuleCouplings: capped.filter((p) => p.kind === "gotcha").length,
|
|
305
|
-
totalProposals: capped.length,
|
|
306
|
-
},
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Slugify a label suffix and prefix it. Stable, lowercase, dash-separated.
|
|
311
|
-
* E.g. makeProposalId("graphify-cluster", "src/utils") → "graphify-cluster-src-utils".
|
|
312
|
-
*/
|
|
313
|
-
function makeProposalId(prefix, suffix) {
|
|
314
|
-
const slug = suffix
|
|
315
|
-
.toLowerCase()
|
|
316
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
317
|
-
.replace(/^-+|-+$/g, "")
|
|
318
|
-
.slice(0, 80);
|
|
319
|
-
return slug ? `${prefix}-${slug}` : prefix;
|
|
320
|
-
}
|
|
321
|
-
export function queryGraph(question, workspacePath) {
|
|
322
|
-
const info = detectGraphify();
|
|
323
|
-
if (!info.available) {
|
|
324
|
-
return { success: false, error: "graphify binary not found" };
|
|
325
|
-
}
|
|
326
|
-
const graphPath = join(resolve(workspacePath), "graphify-out", "graph.json");
|
|
327
|
-
if (!existsSync(graphPath)) {
|
|
328
|
-
return { success: false, error: "graph.json not found" };
|
|
329
|
-
}
|
|
330
|
-
const result = spawnSync("graphify", ["query", question, "--graph", graphPath], {
|
|
331
|
-
encoding: "utf-8",
|
|
332
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
333
|
-
timeout: 30_000,
|
|
334
|
-
});
|
|
335
|
-
if (result.error) {
|
|
336
|
-
return { success: false, error: result.error.message };
|
|
337
|
-
}
|
|
338
|
-
if (result.status !== 0) {
|
|
339
|
-
return { success: false, error: result.stderr?.trim() || "Query failed" };
|
|
340
|
-
}
|
|
341
|
-
return { success: true, answer: result.stdout.trim() };
|
|
342
|
-
}
|
|
343
|
-
export function pathBetween(entityA, entityB, workspacePath) {
|
|
344
|
-
const info = detectGraphify();
|
|
345
|
-
if (!info.available) {
|
|
346
|
-
return { success: false, error: "graphify binary not found" };
|
|
347
|
-
}
|
|
348
|
-
const graphPath = join(resolve(workspacePath), "graphify-out", "graph.json");
|
|
349
|
-
if (!existsSync(graphPath)) {
|
|
350
|
-
return { success: false, error: "graph.json not found" };
|
|
351
|
-
}
|
|
352
|
-
const result = spawnSync("graphify", ["path", entityA, entityB, "--graph", graphPath], {
|
|
353
|
-
encoding: "utf-8",
|
|
354
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
355
|
-
timeout: 30_000,
|
|
356
|
-
});
|
|
357
|
-
if (result.error) {
|
|
358
|
-
return { success: false, error: result.error.message };
|
|
359
|
-
}
|
|
360
|
-
if (result.status !== 0) {
|
|
361
|
-
return { success: false, error: result.stderr?.trim() || "Path query failed" };
|
|
362
|
-
}
|
|
363
|
-
return { success: true, answer: result.stdout.trim() };
|
|
364
|
-
}
|
|
365
|
-
export function runExtraction(workspacePath) {
|
|
366
|
-
const info = detectGraphify();
|
|
367
|
-
if (!info.available) {
|
|
368
|
-
return {
|
|
369
|
-
success: false,
|
|
370
|
-
error: "graphify binary not found",
|
|
371
|
-
code: "ENOENT",
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
const absolutePath = resolve(workspacePath);
|
|
375
|
-
// Use `update --force --no-cluster` for AST-only extraction (no LLM API key needed)
|
|
376
|
-
const result = spawnSync("graphify", ["update", absolutePath, "--force", "--no-cluster"], {
|
|
377
|
-
encoding: "utf-8",
|
|
378
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
379
|
-
timeout: 120_000,
|
|
380
|
-
cwd: absolutePath,
|
|
381
|
-
});
|
|
382
|
-
if (result.error) {
|
|
383
|
-
const errCode = result.error.code;
|
|
384
|
-
return {
|
|
385
|
-
success: false,
|
|
386
|
-
error: result.error.message,
|
|
387
|
-
code: errCode === "ETIMEDOUT" ? "ETIMEDOUT" : errCode,
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
if (result.status !== 0) {
|
|
391
|
-
const stderr = result.stderr?.trim() || "Process exited with non-zero status";
|
|
392
|
-
return {
|
|
393
|
-
success: false,
|
|
394
|
-
error: stderr,
|
|
395
|
-
code: `EXIT_${result.status}`,
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
const graphJsonPath = join(absolutePath, "graphify-out", "graph.json");
|
|
399
|
-
if (!existsSync(graphJsonPath)) {
|
|
400
|
-
return {
|
|
401
|
-
success: false,
|
|
402
|
-
error: "Extraction completed but graph.json not found",
|
|
403
|
-
code: "ENOENT",
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
// Ensure graphify-out/ is in .gitignore so extraction output doesn't pollute the repo
|
|
407
|
-
ensureGitignoreEntry(absolutePath, "graphify-out/");
|
|
408
|
-
return {
|
|
409
|
-
success: true,
|
|
410
|
-
graphJsonPath,
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
/**
|
|
414
|
-
* Append an entry to .gitignore if it's not already present.
|
|
415
|
-
* Creates the file if it doesn't exist.
|
|
416
|
-
*/
|
|
417
|
-
function ensureGitignoreEntry(workspacePath, entry) {
|
|
418
|
-
const gitignorePath = join(workspacePath, ".gitignore");
|
|
419
|
-
try {
|
|
420
|
-
if (existsSync(gitignorePath)) {
|
|
421
|
-
const content = readFileSync(gitignorePath, "utf-8");
|
|
422
|
-
// Check if entry already present (exact line match)
|
|
423
|
-
const lines = content.split("\n").map((l) => l.trim());
|
|
424
|
-
if (lines.includes(entry))
|
|
425
|
-
return;
|
|
426
|
-
// Append with newline separator if file doesn't end with one
|
|
427
|
-
const separator = content.endsWith("\n") ? "" : "\n";
|
|
428
|
-
appendFileSync(gitignorePath, `${separator}${entry}\n`, "utf-8");
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
// Create .gitignore with the entry
|
|
432
|
-
appendFileSync(gitignorePath, `${entry}\n`, "utf-8");
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
catch {
|
|
436
|
-
// Non-fatal — don't fail extraction over .gitignore issues
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
//# sourceMappingURL=graphify.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"graphify.js","sourceRoot":"","sources":["../../src/utils/graphify.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The wire contract shared by everything on the Claude Code session bridge:
|
|
3
|
-
* the event names the hook is registered under, and the address it posts to.
|
|
4
|
-
*
|
|
5
|
-
* These values are duplicated across process boundaries by necessity — the
|
|
6
|
-
* server validates them, the installer writes them into settings.json, and
|
|
7
|
-
* `scripts/claude-code-session-hook.mjs` runs standalone under Claude Code with
|
|
8
|
-
* no ARCS import available. Every duplicate that CAN import derives from here;
|
|
9
|
-
* the one that cannot (the `.mjs`, which must stay dependency-free so a broken
|
|
10
|
-
* bridge is inert rather than fatal) keeps its own literals and is pinned to
|
|
11
|
-
* this module by `test/hook-contract-parity.test.ts`, which fails on any
|
|
12
|
-
* divergence in either direction.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* The four Claude Code events the bridge registers for. One script is installed
|
|
16
|
-
* under all of them; it dispatches internally on `hook_event_name`.
|
|
17
|
-
*
|
|
18
|
-
* A readonly tuple so `z.enum()` consumes it directly — the route's validation
|
|
19
|
-
* and the installer's registration can never drift apart. Adding a fifth event
|
|
20
|
-
* here without adding it to the hook script breaks the parity test.
|
|
21
|
-
*/
|
|
22
|
-
export declare const HOOK_EVENTS: readonly ["SessionStart", "UserPromptSubmit", "SessionEnd", "Stop"];
|
|
23
|
-
export type HookEventName = (typeof HOOK_EVENTS)[number];
|
|
24
|
-
/** Loopback only: `arcs web` refuses to bind anything else. */
|
|
25
|
-
export declare const DEFAULT_WEB_HOST = "127.0.0.1";
|
|
26
|
-
/** Default `arcs web` port, and therefore the port every hook is installed with. */
|
|
27
|
-
export declare const DEFAULT_WEB_PORT = 4173;
|
|
28
|
-
/**
|
|
29
|
-
* Where an installed hook posts when `--url` was not given.
|
|
30
|
-
*
|
|
31
|
-
* Baked into the settings.json command string at install time, so changing it
|
|
32
|
-
* only affects hooks installed afterwards — an already-installed hook keeps
|
|
33
|
-
* posting to the URL it was written with.
|
|
34
|
-
*/
|
|
35
|
-
export declare const DEFAULT_SERVER_URL = "http://127.0.0.1:4173";
|
|
36
|
-
//# sourceMappingURL=hook-contract.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hook-contract.d.ts","sourceRoot":"","sources":["../../src/utils/hook-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,qEAAsE,CAAC;AAE/F,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C,oFAAoF;AACpF,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,0BAAmD,CAAC"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The wire contract shared by everything on the Claude Code session bridge:
|
|
3
|
-
* the event names the hook is registered under, and the address it posts to.
|
|
4
|
-
*
|
|
5
|
-
* These values are duplicated across process boundaries by necessity — the
|
|
6
|
-
* server validates them, the installer writes them into settings.json, and
|
|
7
|
-
* `scripts/claude-code-session-hook.mjs` runs standalone under Claude Code with
|
|
8
|
-
* no ARCS import available. Every duplicate that CAN import derives from here;
|
|
9
|
-
* the one that cannot (the `.mjs`, which must stay dependency-free so a broken
|
|
10
|
-
* bridge is inert rather than fatal) keeps its own literals and is pinned to
|
|
11
|
-
* this module by `test/hook-contract-parity.test.ts`, which fails on any
|
|
12
|
-
* divergence in either direction.
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* The four Claude Code events the bridge registers for. One script is installed
|
|
16
|
-
* under all of them; it dispatches internally on `hook_event_name`.
|
|
17
|
-
*
|
|
18
|
-
* A readonly tuple so `z.enum()` consumes it directly — the route's validation
|
|
19
|
-
* and the installer's registration can never drift apart. Adding a fifth event
|
|
20
|
-
* here without adding it to the hook script breaks the parity test.
|
|
21
|
-
*/
|
|
22
|
-
export const HOOK_EVENTS = ["SessionStart", "UserPromptSubmit", "SessionEnd", "Stop"];
|
|
23
|
-
/** Loopback only: `arcs web` refuses to bind anything else. */
|
|
24
|
-
export const DEFAULT_WEB_HOST = "127.0.0.1";
|
|
25
|
-
/** Default `arcs web` port, and therefore the port every hook is installed with. */
|
|
26
|
-
export const DEFAULT_WEB_PORT = 4173;
|
|
27
|
-
/**
|
|
28
|
-
* Where an installed hook posts when `--url` was not given.
|
|
29
|
-
*
|
|
30
|
-
* Baked into the settings.json command string at install time, so changing it
|
|
31
|
-
* only affects hooks installed afterwards — an already-installed hook keeps
|
|
32
|
-
* posting to the URL it was written with.
|
|
33
|
-
*/
|
|
34
|
-
export const DEFAULT_SERVER_URL = `http://${DEFAULT_WEB_HOST}:${DEFAULT_WEB_PORT}`;
|
|
35
|
-
//# sourceMappingURL=hook-contract.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hook-contract.js","sourceRoot":"","sources":["../../src/utils/hook-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,CAAU,CAAC;AAI/F,+DAA+D;AAC/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAE5C,oFAAoF;AACpF,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,gBAAgB,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-project auth token for the Claude Code session-bridge hook endpoint.
|
|
3
|
-
*
|
|
4
|
-
* Loopback-only is not enough on its own: every process on the machine shares
|
|
5
|
-
* localhost, so any local program could otherwise register sessions, write
|
|
6
|
-
* checkpoints, and hit the SessionStart path — whose answer is injected into a
|
|
7
|
-
* live agent session as `additionalContext`. The token proves the caller is
|
|
8
|
-
* the hook script that `arcs hooks install-claude-code` provisioned for this
|
|
9
|
-
* project.
|
|
10
|
-
*
|
|
11
|
-
* Intentionally not a CRUD store — one token per project, rotated by rerunning
|
|
12
|
-
* the install command. No index, no markdown mirror, no lock (a rotation races
|
|
13
|
-
* only with itself, and the loser simply has to rerun install).
|
|
14
|
-
*/
|
|
15
|
-
export declare function hookTokenPath(projectDir: string): string;
|
|
16
|
-
export declare function readHookToken(projectDir: string): Promise<string | undefined>;
|
|
17
|
-
/**
|
|
18
|
-
* Rotates the on-disk token, owner-only.
|
|
19
|
-
*
|
|
20
|
-
* Unlike the web token there is no in-memory copy to verify against — the hook
|
|
21
|
-
* subprocess re-reads this file at every checkpoint, so the FILE is the
|
|
22
|
-
* credential and its mode is the whole control. `writeJson` stages a temp file
|
|
23
|
-
* and renames it into place with no mode argument, so the token lands 0644
|
|
24
|
-
* (world-readable) on a default umask — and it lands that way on EVERY write,
|
|
25
|
-
* not just the first: the rename swaps in the freshly created temp inode, whose
|
|
26
|
-
* mode came from the umask, and the previous file's mode is discarded with the
|
|
27
|
-
* inode it belonged to. (A mode passed at open() would in fact have covered this
|
|
28
|
-
* writer, precisely because every write creates the destination inode; the
|
|
29
|
-
* "applies only at create" caveat bites a direct non-atomic open(path,"w",mode)
|
|
30
|
-
* over an existing file, which is not this path.) The chmod is nonetheless
|
|
31
|
-
* unconditional rather than conditional on the mode read back, so the 0600
|
|
32
|
-
* guarantee survives a future switch away from the atomic writer.
|
|
33
|
-
*
|
|
34
|
-
* The directory is narrowed too: the staged temp file is a fresh inode born
|
|
35
|
-
* under the umask, so it is briefly world-readable between write and rename.
|
|
36
|
-
* 0o700 on the enclosing directory — which holds nothing but this token —
|
|
37
|
-
* denies another account the traversal needed to reach that window at all.
|
|
38
|
-
*
|
|
39
|
-
* What this buys, stated honestly: 0o600 is a cross-user control. It keeps
|
|
40
|
-
* other UNIX accounts out; it is NOT a defense against a process running as
|
|
41
|
-
* THIS user, which can read the file at any mode. Nor is this the token's only
|
|
42
|
-
* copy — `arcs hooks install-claude-code --write` embeds the same value in the
|
|
43
|
-
* workspace's .claude/settings.local.json, which is now created 0o600 and
|
|
44
|
-
* chmodded 0o600 unconditionally too (claude-code-hook-install.ts), though that
|
|
45
|
-
* copy is inlined into the hook command string and so still leaks to `ps` on
|
|
46
|
-
* every hook fire. So this is a floor on ARCS's own copy, not a guarantee about
|
|
47
|
-
* the secret.
|
|
48
|
-
*
|
|
49
|
-
* A chmod failure propagates and fails the install command. That is
|
|
50
|
-
* deliberate — the caller (`arcs hooks install-claude-code`) has not printed
|
|
51
|
-
* the snippet yet, so the run fails closed and the user reruns to rotate,
|
|
52
|
-
* rather than silently installing a token this process could not protect. The
|
|
53
|
-
* hook's own read path (readHookToken/verifyHookToken) is untouched by this and
|
|
54
|
-
* still never throws.
|
|
55
|
-
*/
|
|
56
|
-
export declare function writeHookToken(projectDir: string, token: string): Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
* Constant-time token comparison. Returns false when the project has no token
|
|
59
|
-
* provisioned yet, so an uninstalled project cannot be driven by an empty
|
|
60
|
-
* `Authorization` header.
|
|
61
|
-
*/
|
|
62
|
-
export declare function verifyHookToken(projectDir: string, candidate: string): Promise<boolean>;
|
|
63
|
-
//# sourceMappingURL=hook-token-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hook-token-store.d.ts","sourceRoot":"","sources":["../../src/utils/hook-token-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAaH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAGnF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrF;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ7F"}
|