axgram 0.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 +126 -0
- package/dist/bin/axgram-hook.js +77 -0
- package/dist/bin/axgram-hook.js.map +1 -0
- package/dist/bin/axgram.js +386 -0
- package/dist/bin/axgram.js.map +1 -0
- package/dist/commands/hook-session-start.js +85 -0
- package/dist/commands/hook-session-start.js.map +1 -0
- package/dist/commands/hook-stop.js +73 -0
- package/dist/commands/hook-stop.js.map +1 -0
- package/dist/commands/import.js +56 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/invitations.js +153 -0
- package/dist/commands/invitations.js.map +1 -0
- package/dist/commands/login.js +125 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +11 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/members.js +231 -0
- package/dist/commands/members.js.map +1 -0
- package/dist/commands/mine.js +78 -0
- package/dist/commands/mine.js.map +1 -0
- package/dist/commands/orgs.js +153 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/projects.js +285 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/teams.js +153 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/whoami.js +27 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/lib/auth.js +128 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/chunkers/exchange-pair.js +51 -0
- package/dist/lib/chunkers/exchange-pair.js.map +1 -0
- package/dist/lib/chunkers/index.js +74 -0
- package/dist/lib/chunkers/index.js.map +1 -0
- package/dist/lib/chunkers/line-group.js +20 -0
- package/dist/lib/chunkers/line-group.js.map +1 -0
- package/dist/lib/chunkers/paragraph.js +29 -0
- package/dist/lib/chunkers/paragraph.js.map +1 -0
- package/dist/lib/chunkers/types.js +3 -0
- package/dist/lib/chunkers/types.js.map +1 -0
- package/dist/lib/config-dir.js +30 -0
- package/dist/lib/config-dir.js.map +1 -0
- package/dist/lib/destructive-confirm.js +71 -0
- package/dist/lib/destructive-confirm.js.map +1 -0
- package/dist/lib/entity-extractor.js +182 -0
- package/dist/lib/entity-extractor.js.map +1 -0
- package/dist/lib/global-config.js +42 -0
- package/dist/lib/global-config.js.map +1 -0
- package/dist/lib/hook-settings.js +87 -0
- package/dist/lib/hook-settings.js.map +1 -0
- package/dist/lib/hook-state.js +38 -0
- package/dist/lib/hook-state.js.map +1 -0
- package/dist/lib/importers/chatgpt.js +89 -0
- package/dist/lib/importers/chatgpt.js.map +1 -0
- package/dist/lib/importers/claude.js +47 -0
- package/dist/lib/importers/claude.js.map +1 -0
- package/dist/lib/importers/gemini.js +38 -0
- package/dist/lib/importers/gemini.js.map +1 -0
- package/dist/lib/importers/markdown.js +47 -0
- package/dist/lib/importers/markdown.js.map +1 -0
- package/dist/lib/importers/obsidian.js +62 -0
- package/dist/lib/importers/obsidian.js.map +1 -0
- package/dist/lib/importers/run.js +51 -0
- package/dist/lib/importers/run.js.map +1 -0
- package/dist/lib/ingest.js +101 -0
- package/dist/lib/ingest.js.map +1 -0
- package/dist/lib/mcp-client.js +56 -0
- package/dist/lib/mcp-client.js.map +1 -0
- package/dist/lib/project-resolver.js +42 -0
- package/dist/lib/project-resolver.js.map +1 -0
- package/dist/lib/remote-url.js +23 -0
- package/dist/lib/remote-url.js.map +1 -0
- package/dist/lib/repo-bindings.js +52 -0
- package/dist/lib/repo-bindings.js.map +1 -0
- package/dist/lib/repo.js +72 -0
- package/dist/lib/repo.js.map +1 -0
- package/dist/lib/room-detector.js +99 -0
- package/dist/lib/room-detector.js.map +1 -0
- package/dist/lib/slugify.js +17 -0
- package/dist/lib/slugify.js.map +1 -0
- package/dist/lib/supabase-client.js +35 -0
- package/dist/lib/supabase-client.js.map +1 -0
- package/dist/lib/tool-vocab.js +114 -0
- package/dist/lib/tool-vocab.js.map +1 -0
- package/dist/lib/transcript.js +68 -0
- package/dist/lib/transcript.js.map +1 -0
- package/dist/lib/walker.js +81 -0
- package/dist/lib/walker.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exchangePairChunker = exchangePairChunker;
|
|
4
|
+
const SPEAKER_RE = /^(?:User|Human|Assistant|AI|System):\s*/i;
|
|
5
|
+
const USER_RE = /^(?:User|Human):\s*/i;
|
|
6
|
+
const ASSISTANT_RE = /^(?:Assistant|AI):\s*/i;
|
|
7
|
+
function exchangePairChunker(input) {
|
|
8
|
+
const turns = parseTurns(input);
|
|
9
|
+
const chunks = [];
|
|
10
|
+
for (let i = 0; i < turns.length - 1; i++) {
|
|
11
|
+
const cur = turns[i];
|
|
12
|
+
const next = turns[i + 1];
|
|
13
|
+
if (cur.role === "user" && next.role === "assistant") {
|
|
14
|
+
const content = `User: ${cur.content.trim()}\n\nAssistant: ${next.content.trim()}`;
|
|
15
|
+
if (content.trim().length > 0) {
|
|
16
|
+
chunks.push({ content, location: `exchange ${chunks.length + 1}` });
|
|
17
|
+
}
|
|
18
|
+
i++; // skip the assistant we just consumed
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return chunks;
|
|
22
|
+
}
|
|
23
|
+
function parseTurns(input) {
|
|
24
|
+
const lines = input.split(/\r?\n/);
|
|
25
|
+
const turns = [];
|
|
26
|
+
let current = null;
|
|
27
|
+
for (const line of lines) {
|
|
28
|
+
if (SPEAKER_RE.test(line)) {
|
|
29
|
+
if (current)
|
|
30
|
+
turns.push(current);
|
|
31
|
+
const role = USER_RE.test(line)
|
|
32
|
+
? "user"
|
|
33
|
+
: ASSISTANT_RE.test(line)
|
|
34
|
+
? "assistant"
|
|
35
|
+
: /^System:/i.test(line)
|
|
36
|
+
? "system"
|
|
37
|
+
: "other";
|
|
38
|
+
current = {
|
|
39
|
+
role,
|
|
40
|
+
content: line.replace(SPEAKER_RE, ""),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
else if (current) {
|
|
44
|
+
current.content += `\n${line}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (current)
|
|
48
|
+
turns.push(current);
|
|
49
|
+
return turns;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=exchange-pair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exchange-pair.js","sourceRoot":"","sources":["../../../src/lib/chunkers/exchange-pair.ts"],"names":[],"mappings":";;AAWA,kDAeC;AAxBD,MAAM,UAAU,GAAG,0CAA0C,CAAC;AAC9D,MAAM,OAAO,GAAG,sBAAsB,CAAC;AACvC,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAO9C,SAAgB,mBAAmB,CAAC,KAAa;IAC/C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACtB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;QAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,SAAS,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,kBAAkB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACnF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;YACtE,CAAC;YACD,CAAC,EAAE,CAAC,CAAC,sCAAsC;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAmB,IAAI,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,IAAI,OAAO;gBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,MAAM,IAAI,GAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC9C,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;oBACvB,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;wBACtB,CAAC,CAAC,QAAQ;wBACV,CAAC,CAAC,OAAO,CAAC;YAChB,OAAO,GAAG;gBACR,IAAI;gBACJ,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;aACtC,CAAC;QACJ,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,OAAO,IAAI,KAAK,IAAI,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IACD,IAAI,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.paragraphChunker = exports.lineGroupChunker = exports.exchangePairChunker = void 0;
|
|
4
|
+
exports.pickChunker = pickChunker;
|
|
5
|
+
exports.chunk = chunk;
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const exchange_pair_1 = require("./exchange-pair");
|
|
8
|
+
const line_group_1 = require("./line-group");
|
|
9
|
+
const paragraph_1 = require("./paragraph");
|
|
10
|
+
var exchange_pair_2 = require("./exchange-pair");
|
|
11
|
+
Object.defineProperty(exports, "exchangePairChunker", { enumerable: true, get: function () { return exchange_pair_2.exchangePairChunker; } });
|
|
12
|
+
var line_group_2 = require("./line-group");
|
|
13
|
+
Object.defineProperty(exports, "lineGroupChunker", { enumerable: true, get: function () { return line_group_2.lineGroupChunker; } });
|
|
14
|
+
var paragraph_2 = require("./paragraph");
|
|
15
|
+
Object.defineProperty(exports, "paragraphChunker", { enumerable: true, get: function () { return paragraph_2.paragraphChunker; } });
|
|
16
|
+
const CODE_EXTS = new Set([
|
|
17
|
+
".ts",
|
|
18
|
+
".tsx",
|
|
19
|
+
".js",
|
|
20
|
+
".jsx",
|
|
21
|
+
".mjs",
|
|
22
|
+
".cjs",
|
|
23
|
+
".py",
|
|
24
|
+
".rb",
|
|
25
|
+
".go",
|
|
26
|
+
".rs",
|
|
27
|
+
".java",
|
|
28
|
+
".kt",
|
|
29
|
+
".swift",
|
|
30
|
+
".c",
|
|
31
|
+
".h",
|
|
32
|
+
".cc",
|
|
33
|
+
".cpp",
|
|
34
|
+
".hpp",
|
|
35
|
+
".cs",
|
|
36
|
+
".php",
|
|
37
|
+
".sh",
|
|
38
|
+
".bash",
|
|
39
|
+
".zsh",
|
|
40
|
+
".sql",
|
|
41
|
+
".css",
|
|
42
|
+
".scss",
|
|
43
|
+
".vue",
|
|
44
|
+
".svelte",
|
|
45
|
+
]);
|
|
46
|
+
const PROSE_EXTS = new Set([".md", ".markdown", ".txt", ".rst", ".org"]);
|
|
47
|
+
const SPEAKER_SNIFFER = /(^|\n)(User|Human|Assistant|AI):\s/;
|
|
48
|
+
/** Pick a chunker for `path` + `content`. Content sniffing wins ties: a
|
|
49
|
+
* `.md` file that contains User:/Assistant: markers chunks as a transcript,
|
|
50
|
+
* not as paragraphs. */
|
|
51
|
+
function pickChunker(path, content) {
|
|
52
|
+
if (SPEAKER_SNIFFER.test(content))
|
|
53
|
+
return "exchange-pair";
|
|
54
|
+
const ext = (0, node_path_1.extname)(path).toLowerCase();
|
|
55
|
+
if (CODE_EXTS.has(ext))
|
|
56
|
+
return "line-group";
|
|
57
|
+
if (PROSE_EXTS.has(ext))
|
|
58
|
+
return "paragraph";
|
|
59
|
+
// Default: paragraph for unknown types — most "data" files are prose-shaped
|
|
60
|
+
// (configs, notes, templates).
|
|
61
|
+
return "paragraph";
|
|
62
|
+
}
|
|
63
|
+
function chunk(path, content) {
|
|
64
|
+
const kind = pickChunker(path, content);
|
|
65
|
+
switch (kind) {
|
|
66
|
+
case "exchange-pair":
|
|
67
|
+
return { kind, chunks: (0, exchange_pair_1.exchangePairChunker)(content) };
|
|
68
|
+
case "line-group":
|
|
69
|
+
return { kind, chunks: (0, line_group_1.lineGroupChunker)(content) };
|
|
70
|
+
case "paragraph":
|
|
71
|
+
return { kind, chunks: (0, paragraph_1.paragraphChunker)(content) };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/chunkers/index.ts"],"names":[],"mappings":";;;AAiDA,kCAWC;AAED,sBAaC;AA3ED,yCAAoC;AACpC,mDAAsD;AACtD,6CAAgD;AAChD,2CAA+C;AAI/C,iDAAsD;AAA7C,oHAAA,mBAAmB,OAAA;AAC5B,2CAAgD;AAAvC,8GAAA,gBAAgB,OAAA;AACzB,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AAEzB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IACxB,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,OAAO;IACP,KAAK;IACL,QAAQ;IACR,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzE,MAAM,eAAe,GAAG,oCAAoC,CAAC;AAE7D;;yBAEyB;AACzB,SAAgB,WAAW,CACzB,IAAY,EACZ,OAAe;IAEf,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,eAAe,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAA,mBAAO,EAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IAC5C,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC;IAC5C,4EAA4E;IAC5E,+BAA+B;IAC/B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAgB,KAAK,CACnB,IAAY,EACZ,OAAe;IAEf,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,eAAe;YAClB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAA,mCAAmB,EAAC,OAAO,CAAC,EAAE,CAAC;QACxD,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAA,6BAAgB,EAAC,OAAO,CAAC,EAAE,CAAC;QACrD,KAAK,WAAW;YACd,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAA,4BAAgB,EAAC,OAAO,CAAC,EAAE,CAAC;IACvD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lineGroupChunker = lineGroupChunker;
|
|
4
|
+
function lineGroupChunker(input, opts = {}) {
|
|
5
|
+
const window = opts.windowSize ?? 25;
|
|
6
|
+
const lines = input.split(/\r?\n/);
|
|
7
|
+
const chunks = [];
|
|
8
|
+
for (let start = 0; start < lines.length; start += window) {
|
|
9
|
+
const end = Math.min(start + window, lines.length);
|
|
10
|
+
const slice = lines.slice(start, end).join("\n");
|
|
11
|
+
if (slice.trim().length === 0)
|
|
12
|
+
continue;
|
|
13
|
+
chunks.push({
|
|
14
|
+
content: slice,
|
|
15
|
+
location: `lines ${start + 1}-${end}`,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return chunks;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=line-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-group.js","sourceRoot":"","sources":["../../../src/lib/chunkers/line-group.ts"],"names":[],"mappings":";;AAOA,4CAiBC;AAjBD,SAAgB,gBAAgB,CAC9B,KAAa,EACb,OAAgC,EAAE;IAElC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,MAAM,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACxC,MAAM,CAAC,IAAI,CAAC;YACV,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,SAAS,KAAK,GAAG,CAAC,IAAI,GAAG,EAAE;SACtC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.paragraphChunker = paragraphChunker;
|
|
4
|
+
function paragraphChunker(input, opts = {}) {
|
|
5
|
+
const minSize = opts.minSize ?? 500;
|
|
6
|
+
const paragraphs = input.split(/\n{2,}/).map((p) => p.trim()).filter((p) => p.length > 0);
|
|
7
|
+
const chunks = [];
|
|
8
|
+
let buffer = [];
|
|
9
|
+
let size = 0;
|
|
10
|
+
const flush = () => {
|
|
11
|
+
if (buffer.length === 0)
|
|
12
|
+
return;
|
|
13
|
+
chunks.push({
|
|
14
|
+
content: buffer.join("\n\n"),
|
|
15
|
+
location: `paragraph ${chunks.length + 1}`,
|
|
16
|
+
});
|
|
17
|
+
buffer = [];
|
|
18
|
+
size = 0;
|
|
19
|
+
};
|
|
20
|
+
for (const p of paragraphs) {
|
|
21
|
+
buffer.push(p);
|
|
22
|
+
size += p.length;
|
|
23
|
+
if (size >= minSize)
|
|
24
|
+
flush();
|
|
25
|
+
}
|
|
26
|
+
flush();
|
|
27
|
+
return chunks;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=paragraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paragraph.js","sourceRoot":"","sources":["../../../src/lib/chunkers/paragraph.ts"],"names":[],"mappings":";;AAOA,4CA2BC;AA3BD,SAAgB,gBAAgB,CAC9B,KAAa,EACb,OAAgC,EAAE;IAElC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC;IACpC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,IAAI,MAAM,GAAa,EAAE,CAAC;IAC1B,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAChC,MAAM,CAAC,IAAI,CAAC;YACV,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5B,QAAQ,EAAE,aAAa,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;SAC3C,CAAC,CAAC;QACH,MAAM,GAAG,EAAE,CAAC;QACZ,IAAI,GAAG,CAAC,CAAC;IACX,CAAC,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC;QACjB,IAAI,IAAI,IAAI,OAAO;YAAE,KAAK,EAAE,CAAC;IAC/B,CAAC;IACD,KAAK,EAAE,CAAC;IACR,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/chunkers/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configDir = configDir;
|
|
4
|
+
exports.credentialsPath = credentialsPath;
|
|
5
|
+
exports.configPath = configPath;
|
|
6
|
+
exports.repoBindingsPath = repoBindingsPath;
|
|
7
|
+
const node_os_1 = require("node:os");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
/**
|
|
10
|
+
* Returns the directory where Axgram CLI persists credentials, project config,
|
|
11
|
+
* and per-project hook state.
|
|
12
|
+
*
|
|
13
|
+
* Honors `AXGRAM_CONFIG_DIR` so tests can isolate filesystem effects.
|
|
14
|
+
*/
|
|
15
|
+
function configDir() {
|
|
16
|
+
const override = process.env.AXGRAM_CONFIG_DIR;
|
|
17
|
+
if (override && override.length > 0)
|
|
18
|
+
return override;
|
|
19
|
+
return (0, node_path_1.resolve)((0, node_os_1.homedir)(), ".axgram");
|
|
20
|
+
}
|
|
21
|
+
function credentialsPath() {
|
|
22
|
+
return (0, node_path_1.resolve)(configDir(), "credentials.json");
|
|
23
|
+
}
|
|
24
|
+
function configPath() {
|
|
25
|
+
return (0, node_path_1.resolve)(configDir(), "config.json");
|
|
26
|
+
}
|
|
27
|
+
function repoBindingsPath() {
|
|
28
|
+
return (0, node_path_1.resolve)(configDir(), "repo-bindings.json");
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=config-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-dir.js","sourceRoot":"","sources":["../../src/lib/config-dir.ts"],"names":[],"mappings":";;AASA,8BAIC;AAED,0CAEC;AAED,gCAEC;AAED,4CAEC;AAzBD,qCAAkC;AAClC,yCAAoC;AAEpC;;;;;GAKG;AACH,SAAgB,SAAS;IACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC/C,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrD,OAAO,IAAA,mBAAO,EAAC,IAAA,iBAAO,GAAE,EAAE,SAAS,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,eAAe;IAC7B,OAAO,IAAA,mBAAO,EAAC,SAAS,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAClD,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO,IAAA,mBAAO,EAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,SAAgB,gBAAgB;IAC9B,OAAO,IAAA,mBAAO,EAAC,SAAS,EAAE,EAAE,oBAAoB,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Plan 5 Task 9: shared type-to-confirm helper for orgs/teams/projects
|
|
3
|
+
// delete commands. The CLI prompts the user to type the target's exact
|
|
4
|
+
// name; non-interactive callers must pass --yes AND --name <exact-name>.
|
|
5
|
+
// The server-side RPC re-validates p_confirm_name as a defense in depth.
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.confirmDestructive = confirmDestructive;
|
|
11
|
+
const node_readline_1 = __importDefault(require("node:readline"));
|
|
12
|
+
/**
|
|
13
|
+
* Returns the confirmed name string if the user agrees to proceed, or
|
|
14
|
+
* null if they declined / mismatched / non-TTY without --yes.
|
|
15
|
+
*
|
|
16
|
+
* Server-side type-to-confirm fires regardless: a stale CLI confirmation
|
|
17
|
+
* combined with a renamed target on the server still aborts cleanly via
|
|
18
|
+
* the RPC's name_confirmation_mismatch shape.
|
|
19
|
+
*/
|
|
20
|
+
async function confirmDestructive(preview, options, deps = {}) {
|
|
21
|
+
const log = deps.log ?? ((m) => process.stdout.write(`${m}\n`));
|
|
22
|
+
const errOut = deps.err ?? ((m) => process.stderr.write(`${m}\n`));
|
|
23
|
+
// Print the cascade preview.
|
|
24
|
+
log("");
|
|
25
|
+
log(`You are about to delete ${preview.targetKind} "${preview.targetName}".`);
|
|
26
|
+
log("");
|
|
27
|
+
log("This will also delete:");
|
|
28
|
+
for (const [k, v] of Object.entries(preview.counts)) {
|
|
29
|
+
log(` ${v} ${k}`);
|
|
30
|
+
}
|
|
31
|
+
log("");
|
|
32
|
+
log("This cannot be undone.");
|
|
33
|
+
log("");
|
|
34
|
+
// Non-interactive path: --yes alone is insufficient.
|
|
35
|
+
if (options.yes) {
|
|
36
|
+
if (!options.name) {
|
|
37
|
+
errOut("--yes requires --name <exact-name> to also be set. Confirm explicitly.");
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (options.name !== preview.targetName) {
|
|
41
|
+
errOut(`--name "${options.name}" does not match the ${preview.targetKind} name "${preview.targetName}".`);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return options.name;
|
|
45
|
+
}
|
|
46
|
+
const tty = deps.isTTY ?? !!process.stdin.isTTY;
|
|
47
|
+
if (!tty && !deps.prompt) {
|
|
48
|
+
errOut("Refusing to confirm destructively in a non-TTY context. Pass --yes --name <exact-name>.");
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const ask = deps.prompt ??
|
|
52
|
+
((q) => {
|
|
53
|
+
const rl = node_readline_1.default.createInterface({
|
|
54
|
+
input: process.stdin,
|
|
55
|
+
output: process.stdout,
|
|
56
|
+
});
|
|
57
|
+
return new Promise((res) => {
|
|
58
|
+
rl.question(q, (a) => {
|
|
59
|
+
rl.close();
|
|
60
|
+
res(a.trim());
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
const answer = await ask(`Type "${preview.targetName}" to confirm: `);
|
|
65
|
+
if (answer !== preview.targetName) {
|
|
66
|
+
errOut("Confirmation did not match. Aborted.");
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return answer;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=destructive-confirm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destructive-confirm.js","sourceRoot":"","sources":["../../src/lib/destructive-confirm.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractEntities = extractEntities;
|
|
4
|
+
const slugify_1 = require("./slugify");
|
|
5
|
+
const tool_vocab_1 = require("./tool-vocab");
|
|
6
|
+
const ENGLISH_STOPWORDS = new Set([
|
|
7
|
+
"the", "and", "for", "are", "but", "not", "you", "your", "yours",
|
|
8
|
+
"with", "this", "that", "these", "those", "have", "has", "had",
|
|
9
|
+
"was", "were", "been", "being", "from", "about", "into", "than",
|
|
10
|
+
"they", "them", "their", "what", "which", "when", "while", "where",
|
|
11
|
+
"would", "could", "should", "will", "shall", "may", "might", "must",
|
|
12
|
+
"any", "some", "much", "more", "most", "such", "very", "just", "also",
|
|
13
|
+
"only", "even", "ever", "out", "over", "under", "after", "before",
|
|
14
|
+
"between", "through", "during", "across", "into", "onto", "upon",
|
|
15
|
+
"her", "him", "his", "she", "its", "our", "ours", "all", "one", "two",
|
|
16
|
+
"three", "four", "five", "six", "seven", "eight", "nine", "ten",
|
|
17
|
+
"yes", "no", "okay", "sure",
|
|
18
|
+
]);
|
|
19
|
+
const CODE_STOPWORDS = new Set([
|
|
20
|
+
"function", "class", "const", "let", "var", "import", "export",
|
|
21
|
+
"return", "async", "await", "from", "true", "false", "null", "undefined",
|
|
22
|
+
"if", "else", "for", "while", "switch", "case", "default", "throw",
|
|
23
|
+
"try", "catch", "finally", "this", "new", "typeof", "instanceof",
|
|
24
|
+
"void", "yield", "static", "public", "private", "protected", "extends",
|
|
25
|
+
"implements", "interface", "type", "enum", "namespace", "module",
|
|
26
|
+
"lib", "src", "dist", "node", "main", "test", "tests",
|
|
27
|
+
]);
|
|
28
|
+
const PERSON_VERBS = new Set([
|
|
29
|
+
"said", "asked", "decided", "wrote", "noted", "argued",
|
|
30
|
+
"agreed", "disagreed", "asked", "thought", "believed",
|
|
31
|
+
]);
|
|
32
|
+
const PLACE_VOCAB = new Set([
|
|
33
|
+
"london", "paris", "tokyo", "newyork", "york", "sf", "francisco",
|
|
34
|
+
"berlin", "amsterdam", "dublin", "seattle", "boston", "chicago",
|
|
35
|
+
"austin", "denver", "atlanta", "toronto", "vancouver", "sydney",
|
|
36
|
+
]);
|
|
37
|
+
const PROJECT_HINT_WORDS = new Set([
|
|
38
|
+
"project", "platform", "system", "service", "app", "application",
|
|
39
|
+
]);
|
|
40
|
+
/** Pre-filter pass — tokenize, drop stopwords, build positions.
|
|
41
|
+
* Captures multi-word capitalized phrases (likely person names) before the
|
|
42
|
+
* single-word scan so "Alice Bob" stays as one entity. */
|
|
43
|
+
function passOne(text) {
|
|
44
|
+
const out = new Map();
|
|
45
|
+
// Multi-word capitalized names: "Alice", "Alice Bob", "Mary Jane Smith".
|
|
46
|
+
// Two- and three-word forms only — longer phrases are usually titles, not names.
|
|
47
|
+
const nameRe = /[A-Z][a-z]+(?: [A-Z][a-z]+){1,2}/g;
|
|
48
|
+
// Build a "mask" that tracks consumed character ranges so the single-word
|
|
49
|
+
// scan below skips anything already claimed as a multi-word entity.
|
|
50
|
+
const masked = new Array(text.length).fill(false);
|
|
51
|
+
let match;
|
|
52
|
+
while ((match = nameRe.exec(text)) !== null) {
|
|
53
|
+
const surface = match[0];
|
|
54
|
+
// Skip phrases that start with a sentence-initial stopword like "The Hono"
|
|
55
|
+
// — those aren't multi-word names, they're a stopword followed by a real
|
|
56
|
+
// single-word entity. Let the single-word scan handle the entity.
|
|
57
|
+
const firstWord = surface.split(" ", 1)[0].toLowerCase();
|
|
58
|
+
if (ENGLISH_STOPWORDS.has(firstWord))
|
|
59
|
+
continue;
|
|
60
|
+
addToMap(out, surface, match.index);
|
|
61
|
+
for (let i = match.index; i < match.index + surface.length; i++) {
|
|
62
|
+
masked[i] = true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Single-word tokens. Internal `.` survives ("Next.js"), trailing `.` does
|
|
66
|
+
// not (so "Postgres." → "Postgres" matches the tool vocab).
|
|
67
|
+
const wordRe = /[A-Za-z][A-Za-z0-9+#-]*(?:\.[A-Za-z0-9]+)*/g;
|
|
68
|
+
while ((match = wordRe.exec(text)) !== null) {
|
|
69
|
+
if (masked[match.index])
|
|
70
|
+
continue;
|
|
71
|
+
const surface = match[0].replace(/\.+$/, "");
|
|
72
|
+
if (surface.length < 3)
|
|
73
|
+
continue;
|
|
74
|
+
if (!/[A-Za-z]/.test(surface))
|
|
75
|
+
continue;
|
|
76
|
+
const lower = surface.toLowerCase();
|
|
77
|
+
if (ENGLISH_STOPWORDS.has(lower))
|
|
78
|
+
continue;
|
|
79
|
+
if (CODE_STOPWORDS.has(lower))
|
|
80
|
+
continue;
|
|
81
|
+
addToMap(out, surface, match.index);
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
function addToMap(map, surface, position) {
|
|
86
|
+
const key = surface.toLowerCase();
|
|
87
|
+
const existing = map.get(key);
|
|
88
|
+
if (existing) {
|
|
89
|
+
existing.positions.push(position);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
map.set(key, {
|
|
93
|
+
name: surface,
|
|
94
|
+
positions: [position],
|
|
95
|
+
firstIsCapitalized: /^[A-Z]/.test(surface),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Score a single candidate. */
|
|
100
|
+
function scoreOne(c, textLength) {
|
|
101
|
+
const freq = c.positions.length;
|
|
102
|
+
const firstPos = c.positions[0];
|
|
103
|
+
const lastPos = c.positions[c.positions.length - 1];
|
|
104
|
+
const cap = c.firstIsCapitalized ? 0.3 : 0;
|
|
105
|
+
const head = firstPos < 100 ? 0.5 : 0;
|
|
106
|
+
const tail = lastPos > textLength - 100 ? 0.2 : 0;
|
|
107
|
+
return freq + cap + head + tail;
|
|
108
|
+
}
|
|
109
|
+
function inferType(name, text, positions) {
|
|
110
|
+
if ((0, tool_vocab_1.isKnownTool)(name))
|
|
111
|
+
return "tool";
|
|
112
|
+
// Multi-word person name: "Alice Bob", "Mary-Jane Smith".
|
|
113
|
+
if (/^[A-Z][a-z]+( [A-Z][a-z]+){1,2}$/.test(name))
|
|
114
|
+
return "person";
|
|
115
|
+
// Person verb context: "Alice said", "Bob asked"
|
|
116
|
+
for (const pos of positions) {
|
|
117
|
+
const after = text.slice(pos + name.length).trimStart();
|
|
118
|
+
const nextWord = after.split(/[^A-Za-z]/, 1)[0]?.toLowerCase();
|
|
119
|
+
if (nextWord && PERSON_VERBS.has(nextWord))
|
|
120
|
+
return "person";
|
|
121
|
+
}
|
|
122
|
+
// Project hints: "the X platform", "X project".
|
|
123
|
+
const lowerName = name.toLowerCase();
|
|
124
|
+
if (PROJECT_HINT_WORDS.has(lowerName))
|
|
125
|
+
return "concept";
|
|
126
|
+
for (const pos of positions) {
|
|
127
|
+
const after = text.slice(pos + name.length).trimStart();
|
|
128
|
+
const nextWord = after.split(/[^A-Za-z]/, 1)[0]?.toLowerCase();
|
|
129
|
+
if (nextWord && PROJECT_HINT_WORDS.has(nextWord))
|
|
130
|
+
return "project";
|
|
131
|
+
}
|
|
132
|
+
// All-caps acronyms (≥3 chars) or kebab-case → likely a project.
|
|
133
|
+
if (/^[A-Z]{3,}$/.test(name) || /[a-z]+-[a-z]+/.test(name))
|
|
134
|
+
return "project";
|
|
135
|
+
if (PLACE_VOCAB.has(lowerName))
|
|
136
|
+
return "place";
|
|
137
|
+
// Capitalized single-word — could be many things; default to concept.
|
|
138
|
+
if (/^[A-Z]/.test(name))
|
|
139
|
+
return "concept";
|
|
140
|
+
return "unknown";
|
|
141
|
+
}
|
|
142
|
+
function extractEntities(text, opts = {}) {
|
|
143
|
+
const topN = opts.topN ?? 5;
|
|
144
|
+
const filterBelowMedian = opts.filterBelowMedian ?? true;
|
|
145
|
+
const pass1 = passOne(text);
|
|
146
|
+
const scored = [];
|
|
147
|
+
for (const c of pass1.values()) {
|
|
148
|
+
const score = scoreOne(c, text.length);
|
|
149
|
+
scored.push({ c, score });
|
|
150
|
+
}
|
|
151
|
+
scored.sort((a, b) => b.score - a.score);
|
|
152
|
+
const top = scored.slice(0, topN);
|
|
153
|
+
if (top.length === 0)
|
|
154
|
+
return [];
|
|
155
|
+
let kept = top;
|
|
156
|
+
if (filterBelowMedian && top.length >= 2) {
|
|
157
|
+
const sortedScores = top.map((s) => s.score).slice().sort((a, b) => a - b);
|
|
158
|
+
const mid = Math.floor(sortedScores.length / 2);
|
|
159
|
+
const median = sortedScores.length % 2 === 0
|
|
160
|
+
? (sortedScores[mid - 1] + sortedScores[mid]) / 2
|
|
161
|
+
: sortedScores[mid];
|
|
162
|
+
kept = top.filter((s) => s.score >= median);
|
|
163
|
+
}
|
|
164
|
+
return kept.map(({ c, score }) => {
|
|
165
|
+
let slug;
|
|
166
|
+
try {
|
|
167
|
+
slug = (0, slugify_1.slugify)(c.name);
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Pathological surface form (all punctuation after lowering); skip.
|
|
171
|
+
slug = c.name.toLowerCase();
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
name: c.name,
|
|
175
|
+
slug,
|
|
176
|
+
score: Number(score.toFixed(3)),
|
|
177
|
+
positions: c.positions.slice(),
|
|
178
|
+
type: inferType(c.name, text, c.positions),
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=entity-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-extractor.js","sourceRoot":"","sources":["../../src/lib/entity-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadGlobalConfig = loadGlobalConfig;
|
|
4
|
+
exports.setDefaultProject = setDefaultProject;
|
|
5
|
+
exports.clearDefaultProject = clearDefaultProject;
|
|
6
|
+
const promises_1 = require("node:fs/promises");
|
|
7
|
+
const config_dir_1 = require("./config-dir");
|
|
8
|
+
function emptyConfig() {
|
|
9
|
+
return { version: 1 };
|
|
10
|
+
}
|
|
11
|
+
async function loadGlobalConfig() {
|
|
12
|
+
try {
|
|
13
|
+
const raw = await (0, promises_1.readFile)((0, config_dir_1.configPath)(), "utf8");
|
|
14
|
+
const parsed = JSON.parse(raw);
|
|
15
|
+
return {
|
|
16
|
+
version: 1,
|
|
17
|
+
...(typeof parsed.default_project_id === "string"
|
|
18
|
+
? { default_project_id: parsed.default_project_id }
|
|
19
|
+
: {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
if (err.code === "ENOENT")
|
|
24
|
+
return emptyConfig();
|
|
25
|
+
return emptyConfig();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async function setDefaultProject(projectId) {
|
|
29
|
+
const cfg = await loadGlobalConfig();
|
|
30
|
+
cfg.default_project_id = projectId;
|
|
31
|
+
await persist(cfg);
|
|
32
|
+
}
|
|
33
|
+
async function clearDefaultProject() {
|
|
34
|
+
const cfg = await loadGlobalConfig();
|
|
35
|
+
delete cfg.default_project_id;
|
|
36
|
+
await persist(cfg);
|
|
37
|
+
}
|
|
38
|
+
async function persist(cfg) {
|
|
39
|
+
await (0, promises_1.mkdir)((0, config_dir_1.configDir)(), { recursive: true, mode: 0o700 });
|
|
40
|
+
await (0, promises_1.writeFile)((0, config_dir_1.configPath)(), JSON.stringify(cfg, null, 2), { encoding: "utf8", mode: 0o644 });
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=global-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-config.js","sourceRoot":"","sources":["../../src/lib/global-config.ts"],"names":[],"mappings":";;AAYA,4CAcC;AAED,8CAIC;AAED,kDAIC;AAtCD,+CAA8D;AAC9D,6CAAqD;AAOrD,SAAS,WAAW;IAClB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AACxB,CAAC;AAEM,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAA,uBAAU,GAAE,EAAE,MAAM,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,OAAO;YACL,OAAO,EAAE,CAAC;YACV,GAAG,CAAC,OAAO,MAAM,CAAC,kBAAkB,KAAK,QAAQ;gBAC/C,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,EAAE;gBACnD,CAAC,CAAC,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,WAAW,EAAE,CAAC;QAC3E,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IACvD,MAAM,GAAG,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACrC,GAAG,CAAC,kBAAkB,GAAG,SAAS,CAAC;IACnC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAEM,KAAK,UAAU,mBAAmB;IACvC,MAAM,GAAG,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACrC,OAAO,GAAG,CAAC,kBAAkB,CAAC;IAC9B,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,GAAiB;IACtC,MAAM,IAAA,gBAAK,EAAC,IAAA,sBAAS,GAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,IAAA,oBAAS,EACb,IAAA,uBAAU,GAAE,EACZ,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAC5B,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAClC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getEffectiveHookSettings = getEffectiveHookSettings;
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const config_dir_1 = require("./config-dir");
|
|
7
|
+
const mcp_client_1 = require("./mcp-client");
|
|
8
|
+
const remote_url_1 = require("./remote-url");
|
|
9
|
+
/** Cache TTL — keeps round-trips down on a per-Stop basis without
|
|
10
|
+
* pinning a setting forever. */
|
|
11
|
+
const CACHE_TTL_MS = 30 * 60 * 1000;
|
|
12
|
+
const DEFAULT_THRESHOLD = 15;
|
|
13
|
+
const DEFAULT_WORKER_URL = (0, remote_url_1.resolveRemoteUrl)();
|
|
14
|
+
function cachePath(projectId) {
|
|
15
|
+
return (0, node_path_1.resolve)((0, config_dir_1.configDir)(), `hook-settings-${projectId}.json`);
|
|
16
|
+
}
|
|
17
|
+
async function loadCache(projectId) {
|
|
18
|
+
try {
|
|
19
|
+
const raw = await (0, promises_1.readFile)(cachePath(projectId), "utf8");
|
|
20
|
+
const parsed = JSON.parse(raw);
|
|
21
|
+
if (typeof parsed.threshold !== "number" ||
|
|
22
|
+
typeof parsed.enabled !== "boolean" ||
|
|
23
|
+
typeof parsed.fetched_at !== "string") {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return parsed;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function saveCache(projectId, settings) {
|
|
33
|
+
await (0, promises_1.mkdir)((0, config_dir_1.configDir)(), { recursive: true, mode: 0o700 });
|
|
34
|
+
await (0, promises_1.writeFile)(cachePath(projectId), JSON.stringify(settings, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
35
|
+
}
|
|
36
|
+
function isFresh(cached, now = Date.now()) {
|
|
37
|
+
const fetched = Date.parse(cached.fetched_at);
|
|
38
|
+
if (Number.isNaN(fetched))
|
|
39
|
+
return false;
|
|
40
|
+
return now - fetched < CACHE_TTL_MS;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the effective hook settings for the given project. Prefers a
|
|
44
|
+
* fresh cache (≤30min). On cache miss, fetches axgram_hook_settings via
|
|
45
|
+
* MCP and caches the result. On fetch failure: returns stale cache if
|
|
46
|
+
* present, else the hardcoded default of 15 enabled.
|
|
47
|
+
*/
|
|
48
|
+
async function getEffectiveHookSettings(projectId, opts = {}) {
|
|
49
|
+
const cached = opts.noCache ? null : await loadCache(projectId);
|
|
50
|
+
if (cached && isFresh(cached)) {
|
|
51
|
+
return { threshold: cached.threshold, enabled: cached.enabled };
|
|
52
|
+
}
|
|
53
|
+
const factory = opts.mcpClientFactory ?? mcp_client_1.authenticatedMcpClient;
|
|
54
|
+
const workerUrl = opts.workerUrl ?? DEFAULT_WORKER_URL;
|
|
55
|
+
const errOut = opts.err ?? (() => { });
|
|
56
|
+
let client = null;
|
|
57
|
+
try {
|
|
58
|
+
client = await factory(workerUrl);
|
|
59
|
+
const raw = await client.callTool("axgram_hook_settings", {
|
|
60
|
+
project_id: projectId,
|
|
61
|
+
});
|
|
62
|
+
const parsed = (0, mcp_client_1.parseToolResult)(raw);
|
|
63
|
+
const settings = {
|
|
64
|
+
threshold: parsed.effective.exchange_threshold,
|
|
65
|
+
enabled: parsed.effective.enabled,
|
|
66
|
+
};
|
|
67
|
+
await saveCache(projectId, {
|
|
68
|
+
...settings,
|
|
69
|
+
fetched_at: new Date().toISOString(),
|
|
70
|
+
});
|
|
71
|
+
return settings;
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
errOut(`axgram-hook: could not fetch hook_settings (${e.message}); ` +
|
|
75
|
+
(cached
|
|
76
|
+
? "using stale cached settings"
|
|
77
|
+
: `defaulting to threshold=${DEFAULT_THRESHOLD}, enabled=true`));
|
|
78
|
+
if (cached)
|
|
79
|
+
return { threshold: cached.threshold, enabled: cached.enabled };
|
|
80
|
+
return { threshold: DEFAULT_THRESHOLD, enabled: true };
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
if (client)
|
|
84
|
+
await client.close().catch(() => { });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=hook-settings.js.map
|