ai-spector 0.3.0 → 0.3.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.
Files changed (84) hide show
  1. package/README.md +136 -14
  2. package/dist/cli.js +97 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/comments.d.ts +41 -0
  5. package/dist/commands/comments.d.ts.map +1 -0
  6. package/dist/commands/comments.js +138 -0
  7. package/dist/commands/comments.js.map +1 -0
  8. package/dist/commands/init.d.ts +4 -0
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +22 -5
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/sync-cursor.d.ts +6 -0
  13. package/dist/commands/sync-cursor.d.ts.map +1 -0
  14. package/dist/commands/sync-cursor.js +18 -0
  15. package/dist/commands/sync-cursor.js.map +1 -0
  16. package/dist/comments/anchor.d.ts +16 -0
  17. package/dist/comments/anchor.d.ts.map +1 -0
  18. package/dist/comments/anchor.js +59 -0
  19. package/dist/comments/anchor.js.map +1 -0
  20. package/dist/comments/inbox.d.ts +83 -0
  21. package/dist/comments/inbox.d.ts.map +1 -0
  22. package/dist/comments/inbox.js +180 -0
  23. package/dist/comments/inbox.js.map +1 -0
  24. package/dist/comments/paths.d.ts +12 -0
  25. package/dist/comments/paths.d.ts.map +1 -0
  26. package/dist/comments/paths.js +54 -0
  27. package/dist/comments/paths.js.map +1 -0
  28. package/dist/comments/plan.d.ts +20 -0
  29. package/dist/comments/plan.d.ts.map +1 -0
  30. package/dist/comments/plan.js +62 -0
  31. package/dist/comments/plan.js.map +1 -0
  32. package/dist/comments/storage.d.ts +30 -0
  33. package/dist/comments/storage.d.ts.map +1 -0
  34. package/dist/comments/storage.js +272 -0
  35. package/dist/comments/storage.js.map +1 -0
  36. package/dist/comments/types.d.ts +54 -0
  37. package/dist/comments/types.d.ts.map +1 -0
  38. package/dist/comments/types.js +2 -0
  39. package/dist/comments/types.js.map +1 -0
  40. package/dist/config/load.d.ts +2 -0
  41. package/dist/config/load.d.ts.map +1 -1
  42. package/dist/config/load.js +4 -0
  43. package/dist/config/load.js.map +1 -1
  44. package/dist/graph/detail-sections.js +1 -1
  45. package/dist/graph/detail-sections.js.map +1 -1
  46. package/dist/graph/doc-extract.d.ts +9 -3
  47. package/dist/graph/doc-extract.d.ts.map +1 -1
  48. package/dist/graph/doc-extract.js +86 -58
  49. package/dist/graph/doc-extract.js.map +1 -1
  50. package/dist/postinstall.d.ts +3 -0
  51. package/dist/postinstall.d.ts.map +1 -0
  52. package/dist/postinstall.js +44 -0
  53. package/dist/postinstall.js.map +1 -0
  54. package/documents-basic-design.json +1 -1
  55. package/package.json +3 -5
  56. package/scaffold/.ai-spector/.docflow/config/dag.basic-design.graph-seeds.json +11 -7
  57. package/scaffold/.ai-spector/.docflow/config/dag.basic-design.json +1 -1
  58. package/scaffold/{.cursor → cursor}/commands/_generate-graph.md +10 -2
  59. package/scaffold/{.cursor → cursor}/commands/_workflow.md +7 -3
  60. package/scaffold/{.cursor → cursor}/commands/generate-basic-design.md +27 -17
  61. package/scaffold/cursor/commands/resolve-comments.md +145 -0
  62. package/scaffold/cursor/skills/_skill-router.md +22 -0
  63. package/scaffold/cursor/skills/ai-spector/SKILL.md +47 -0
  64. package/scaffold/cursor/skills/ai-spector-generate/SKILL.md +41 -0
  65. package/scaffold/cursor/skills/ai-spector-graph/SKILL.md +39 -0
  66. package/scaffold/cursor/skills/ai-spector-resolve-comments/SKILL.md +42 -0
  67. package/templates/basic_design/detail-api-template.md +2 -2
  68. package/templates/basic_design/detail-screen-template.md +2 -2
  69. package/scaffold/.cursor/skills/ai-spector/SKILL.md +0 -62
  70. /package/scaffold/{.cursor → cursor}/commands/_cli-failures.md +0 -0
  71. /package/scaffold/{.cursor → cursor}/commands/_graph.md +0 -0
  72. /package/scaffold/{.cursor → cursor}/commands/_prerequisites.md +0 -0
  73. /package/scaffold/{.cursor → cursor}/commands/analyze.md +0 -0
  74. /package/scaffold/{.cursor → cursor}/commands/generate-detail-design.md +0 -0
  75. /package/scaffold/{.cursor → cursor}/commands/generate-srs.md +0 -0
  76. /package/scaffold/{.cursor → cursor}/commands/graph-impact.md +0 -0
  77. /package/scaffold/{.cursor → cursor}/commands/impact.md +0 -0
  78. /package/scaffold/{.cursor → cursor}/commands/index.md +0 -0
  79. /package/scaffold/{.cursor → cursor}/commands/link-graph.md +0 -0
  80. /package/scaffold/{.cursor → cursor}/commands/summary.md +0 -0
  81. /package/scaffold/{.cursor → cursor}/commands/sync-graph.md +0 -0
  82. /package/scaffold/{.cursor → cursor}/commands/validate-graph.md +0 -0
  83. /package/scaffold/{.cursor → cursor}/commands/visualize-graph.md +0 -0
  84. /package/scaffold/{.cursor → cursor}/mcp.json +0 -0
@@ -1,17 +1,32 @@
1
- import { mkdir, writeFile } from "node:fs/promises";
1
+ import { mkdir, readdir, writeFile } from "node:fs/promises";
2
2
  import { join, resolve } from "node:path";
3
- import { packageBundleRoot, scaffoldBundleRoot } from "../config/load.js";
3
+ import { packageBundleRoot, scaffoldBundleRoot, scaffoldCursorBundleRoot, } from "../config/load.js";
4
4
  import { copyTree, pathExists, writeJson } from "../util/fs.js";
5
5
  import { ensureGraphifyMcpConfig } from "../util/mcp.js";
6
6
  import { ensureAiSpectorGitignore } from "../util/gitignore.js";
7
+ /** Copy bundled `scaffold/cursor/` → project `.cursor/`. */
8
+ export async function copyCursorToProject(projectRoot) {
9
+ await copyTree(scaffoldCursorBundleRoot(), join(projectRoot, ".cursor"));
10
+ }
11
+ /** Copy scaffold into project; `scaffold/cursor/` → `.cursor/` at project root. */
12
+ export async function copyScaffoldToProject(projectRoot) {
13
+ const scaffold = scaffoldBundleRoot();
14
+ const entries = await readdir(scaffold, { withFileTypes: true });
15
+ for (const ent of entries) {
16
+ if (ent.name === "cursor") {
17
+ continue;
18
+ }
19
+ await copyTree(join(scaffold, ent.name), join(projectRoot, ent.name));
20
+ }
21
+ await copyCursorToProject(projectRoot);
22
+ }
7
23
  export async function runInit(opts) {
8
24
  const root = resolve(opts.targetDir);
9
25
  const marker = join(root, ".ai-spector", "docflow.config.json");
10
26
  if (await pathExists(marker) && !opts.force) {
11
27
  throw new Error(`Project already initialized (${marker}). Use --force to overwrite scaffold files.`);
12
28
  }
13
- const scaffold = scaffoldBundleRoot();
14
- await copyTree(scaffold, root);
29
+ await copyScaffoldToProject(root);
15
30
  const projectTemplates = join(root, ".ai-spector", "templates");
16
31
  await mkdir(projectTemplates, { recursive: true });
17
32
  await copyTree(join(packageBundleRoot(), "templates"), projectTemplates);
@@ -47,13 +62,15 @@ export async function runInit(opts) {
47
62
  console.log(` MCP → ${mcpPath} (Graphify server added/updated)`);
48
63
  console.log(` gitignore → ${gitignorePath} (ai-spector block added/updated)`);
49
64
  console.log(` templates → ${projectTemplates} (SRS / basic / detail design)`);
65
+ console.log(` cursor → ${join(root, ".cursor")} (from scaffold/cursor/)`);
50
66
  console.log("");
51
67
  console.log("Next steps (Cursor):");
52
68
  console.log(" 1. Open this folder in Cursor");
53
69
  console.log(" 2. Reload MCP (Settings → MCP) or restart Cursor — needs uv + graphifyy");
54
- console.log(" 3. Enable the ai-spector skill (.cursor/skills/ai-spector/)");
70
+ console.log(" 3. Enable ai-spector skills (.cursor/skills/ — see _skill-router.md)");
55
71
  console.log(" 4. Add files under docs/data-source/");
56
72
  console.log(" 5. Run /analyze → /validate-graph → /generate-srs");
73
+ console.log(" Or ask in chat: \"analyze data source\", \"generate SRS\", \"resolve comments\"");
57
74
  console.log("");
58
75
  console.log("See .cursor/commands/_workflow.md — you do not need other CLI commands.");
59
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface SyncCursorOptions {
2
+ targetDir: string;
3
+ }
4
+ /** Refresh `.cursor/` commands and skills from bundled `scaffold/cursor/`. */
5
+ export declare function runSyncCursor(opts: SyncCursorOptions): Promise<void>;
6
+ //# sourceMappingURL=sync-cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-cursor.d.ts","sourceRoot":"","sources":["../../src/commands/sync-cursor.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,8EAA8E;AAC9E,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAe1E"}
@@ -0,0 +1,18 @@
1
+ import { join, resolve } from "node:path";
2
+ import { scaffoldCursorBundleRoot } from "../config/load.js";
3
+ import { pathExists } from "../util/fs.js";
4
+ import { copyCursorToProject } from "./init.js";
5
+ /** Refresh `.cursor/` commands and skills from bundled `scaffold/cursor/`. */
6
+ export async function runSyncCursor(opts) {
7
+ const root = resolve(opts.targetDir);
8
+ const marker = join(root, ".ai-spector", "docflow.config.json");
9
+ if (!(await pathExists(marker))) {
10
+ throw new Error(`Project not initialized (${marker}). Run: ai-spector init`);
11
+ }
12
+ await copyCursorToProject(root);
13
+ console.log(`Synced Cursor bundle at ${join(root, ".cursor")}`);
14
+ console.log(` source → ${scaffoldCursorBundleRoot()}`);
15
+ console.log("");
16
+ console.log("Reload Cursor skills if needed; slash commands update on next use.");
17
+ }
18
+ //# sourceMappingURL=sync-cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-cursor.js","sourceRoot":"","sources":["../../src/commands/sync-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAMhD,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAuB;IACzD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,qBAAqB,CAAC,CAAC;IAChE,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,4BAA4B,MAAM,yBAAyB,CAC5D,CAAC;IACJ,CAAC;IAED,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAEhC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,cAAc,wBAAwB,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;AACpF,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface DocAnchorContext {
2
+ docPath: string;
3
+ startLine: number;
4
+ endLine: number;
5
+ /** 1-based line range text from the document */
6
+ anchoredText: string;
7
+ /** Nearest markdown heading at or above startLine */
8
+ heading?: string;
9
+ /** Section anchor comment at or above startLine */
10
+ sectionAnchor?: string;
11
+ /** Total lines in document */
12
+ lineCount: number;
13
+ }
14
+ export declare function readDocAnchorContext(projectRoot: string, logicalPath: string, startLine: number, endLine: number): Promise<DocAnchorContext | null>;
15
+ export declare function previewCommentBody(body: string, maxLen?: number): string;
16
+ //# sourceMappingURL=anchor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor.d.ts","sourceRoot":"","sources":["../../src/comments/anchor.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA+ClC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,MAAM,CAMrE"}
@@ -0,0 +1,59 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { pathExists } from "../util/fs.js";
4
+ import { logicalPathToDocPath } from "./paths.js";
5
+ const SECTION_ANCHOR_RE = /<!--\s*section:\s*([^\s>]+)\s*-->/;
6
+ const HEADING_RE = /^(#{1,6})\s+(.+)$/;
7
+ export async function readDocAnchorContext(projectRoot, logicalPath, startLine, endLine) {
8
+ const docPath = logicalPathToDocPath(logicalPath);
9
+ if (!docPath) {
10
+ return null;
11
+ }
12
+ const abs = join(projectRoot, docPath);
13
+ if (!(await pathExists(abs))) {
14
+ return null;
15
+ }
16
+ const raw = await readFile(abs, "utf8");
17
+ const lines = raw.split("\n");
18
+ const start = Math.max(1, startLine);
19
+ const end = Math.min(lines.length, Math.max(endLine, startLine));
20
+ const slice = lines.slice(start - 1, end);
21
+ const anchoredText = slice.join("\n");
22
+ let heading;
23
+ let sectionAnchor;
24
+ for (let i = start - 1; i >= 0; i--) {
25
+ const line = lines[i] ?? "";
26
+ if (!sectionAnchor) {
27
+ const anchorMatch = line.match(SECTION_ANCHOR_RE);
28
+ if (anchorMatch) {
29
+ sectionAnchor = anchorMatch[1];
30
+ }
31
+ }
32
+ if (!heading) {
33
+ const h = line.match(HEADING_RE);
34
+ if (h) {
35
+ heading = h[2].trim();
36
+ }
37
+ }
38
+ if (heading && sectionAnchor) {
39
+ break;
40
+ }
41
+ }
42
+ return {
43
+ docPath,
44
+ startLine: start,
45
+ endLine: end,
46
+ anchoredText,
47
+ heading,
48
+ sectionAnchor,
49
+ lineCount: lines.length,
50
+ };
51
+ }
52
+ export function previewCommentBody(body, maxLen = 120) {
53
+ const oneLine = body.replace(/\s+/g, " ").trim();
54
+ if (oneLine.length <= maxLen) {
55
+ return oneLine;
56
+ }
57
+ return `${oneLine.slice(0, maxLen - 1)}…`;
58
+ }
59
+ //# sourceMappingURL=anchor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor.js","sourceRoot":"","sources":["../../src/comments/anchor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import type { ImpactResult } from "../graph/impact.js";
2
+ import type { ThreadSummary } from "./types.js";
3
+ export interface CommentInboxItem {
4
+ /** Short id for chat selection, e.g. C-001 */
5
+ pickId: string;
6
+ threadId: string;
7
+ filePath: string;
8
+ docPath: string | null;
9
+ status: string;
10
+ language: string;
11
+ lines: string;
12
+ startLine: number;
13
+ endLine: number;
14
+ excerpt?: string;
15
+ /** First comment in thread (reviewer ask) */
16
+ preview: string;
17
+ replyCount: number;
18
+ originBranch: string;
19
+ version: number;
20
+ }
21
+ export interface CommentInbox {
22
+ inbox: CommentInboxItem[];
23
+ count: number;
24
+ openCount: number;
25
+ prompt: string;
26
+ /** Pre-rendered pick list for IDE chat — agent should show this, not raw JSON or thread uuids */
27
+ idePresentation: {
28
+ mode: "thread_pick_list";
29
+ markdown: string;
30
+ rules: string[];
31
+ };
32
+ }
33
+ export declare function buildCommentInbox(threads: ThreadSummary[]): CommentInbox;
34
+ export declare function enrichInboxPreviews(inbox: CommentInbox, firstComments: Map<string, string>): CommentInbox;
35
+ export declare function formatInboxForChat(inbox: CommentInbox): string;
36
+ export interface ImpactSummary {
37
+ regenerate: number;
38
+ review: number;
39
+ downstream: number;
40
+ originId?: string;
41
+ originType?: string;
42
+ topRegenerate: Array<{
43
+ id: string;
44
+ projectionPath?: string;
45
+ }>;
46
+ topReview: Array<{
47
+ id: string;
48
+ projectionPath?: string;
49
+ }>;
50
+ }
51
+ export declare function summarizeImpact(impact: ImpactResult | null): ImpactSummary | null;
52
+ export interface CommentResolvePlan {
53
+ pickId?: string;
54
+ thread: import("./types.js").ThreadDetail;
55
+ anchor: import("./anchor.js").DocAnchorContext | null;
56
+ impact: ImpactResult | null;
57
+ impactSummary: ImpactSummary | null;
58
+ resolvedFrom?: {
59
+ id: string;
60
+ type: string;
61
+ reason: string;
62
+ };
63
+ workflow: {
64
+ phases: string[];
65
+ suggestEdit: {
66
+ docPath: string | null;
67
+ startLine: number;
68
+ endLine: number;
69
+ instruction: string;
70
+ };
71
+ afterApply: {
72
+ indexRefresh?: boolean;
73
+ regenerateCommands?: string[];
74
+ };
75
+ };
76
+ }
77
+ export declare function buildResolvePlan(thread: import("./types.js").ThreadDetail, anchor: import("./anchor.js").DocAnchorContext | null, impact: ImpactResult | null, resolvedFrom?: {
78
+ id: string;
79
+ type: string;
80
+ reason: string;
81
+ }, pickId?: string): CommentResolvePlan;
82
+ export declare function formatPlanForChat(plan: CommentResolvePlan): string;
83
+ //# sourceMappingURL=inbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/comments/inbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,180 @@
1
+ import { previewCommentBody } from "./anchor.js";
2
+ export function buildCommentInbox(threads) {
3
+ const inbox = threads.map((t, index) => ({
4
+ pickId: `C-${String(index + 1).padStart(3, "0")}`,
5
+ threadId: t.threadId,
6
+ filePath: t.filePath,
7
+ docPath: t.docPath,
8
+ status: t.status,
9
+ language: t.anchor.language,
10
+ lines: `${t.anchor.startLine}-${t.anchor.endLine}`,
11
+ startLine: t.anchor.startLine,
12
+ endLine: t.anchor.endLine,
13
+ excerpt: t.anchor.lineExcerpt,
14
+ preview: "(loading…)",
15
+ replyCount: t.replyCount,
16
+ originBranch: t.originBranch,
17
+ version: t.version,
18
+ }));
19
+ return {
20
+ inbox,
21
+ count: inbox.length,
22
+ openCount: inbox.filter((i) => i.status === "open").length,
23
+ prompt: inbox.length === 0
24
+ ? "No open comment threads. Run git pull or check comments/."
25
+ : "Reply with a pick id (e.g. C-001) to start the resolve workflow.",
26
+ idePresentation: buildIdePresentation(inbox),
27
+ };
28
+ }
29
+ const IDE_PRESENTATION_RULES = [
30
+ "Show only the markdown table below — one row per open thread (not per reply).",
31
+ "Do not paste raw JSON or full thread uuids in chat.",
32
+ "Use pick ids (C-001) for user selection; keep threadId internal until running plan/resolve.",
33
+ ];
34
+ function buildIdePresentation(inbox) {
35
+ if (inbox.length === 0) {
36
+ return {
37
+ mode: "thread_pick_list",
38
+ markdown: "_No open comment threads._",
39
+ rules: IDE_PRESENTATION_RULES,
40
+ };
41
+ }
42
+ const header = "| Pick | Document | Lines | Lang | Reviewer ask |";
43
+ const sep = "|------|----------|-------|------|--------------|";
44
+ const rows = inbox.map((item) => {
45
+ const doc = item.docPath ?? item.filePath;
46
+ const ask = item.preview.replace(/\|/g, "\\|").replace(/\n/g, " ");
47
+ const excerpt = item.excerpt && !ask.includes(item.excerpt.slice(0, 20))
48
+ ? ` _(${item.excerpt.replace(/\|/g, "\\|").slice(0, 60)}…)_`
49
+ : "";
50
+ return `| **${item.pickId}** | \`${doc}\` | ${item.lines} | ${item.language} | ${ask}${excerpt} |`;
51
+ });
52
+ return {
53
+ mode: "thread_pick_list",
54
+ markdown: [header, sep, ...rows].join("\n"),
55
+ rules: IDE_PRESENTATION_RULES,
56
+ };
57
+ }
58
+ export function enrichInboxPreviews(inbox, firstComments) {
59
+ const enrichedInbox = inbox.inbox.map((item) => {
60
+ const body = firstComments.get(item.threadId);
61
+ return body ? { ...item, preview: previewCommentBody(body) } : item;
62
+ });
63
+ return {
64
+ ...inbox,
65
+ inbox: enrichedInbox,
66
+ idePresentation: buildIdePresentation(enrichedInbox),
67
+ };
68
+ }
69
+ export function formatInboxForChat(inbox) {
70
+ if (inbox.count === 0) {
71
+ return "No open comment threads under comments/.";
72
+ }
73
+ return [
74
+ `Open comment threads (${inbox.openCount}) — pick one:`,
75
+ "",
76
+ inbox.idePresentation.markdown,
77
+ "",
78
+ inbox.prompt,
79
+ ].join("\n");
80
+ }
81
+ export function summarizeImpact(impact) {
82
+ if (!impact) {
83
+ return null;
84
+ }
85
+ return {
86
+ regenerate: impact.affected.regenerate.length,
87
+ review: impact.affected.review.length,
88
+ downstream: impact.affected.downstream.length,
89
+ originId: impact.origin.id,
90
+ originType: impact.origin.type,
91
+ topRegenerate: impact.affected.regenerate.slice(0, 8).map((e) => ({
92
+ id: e.id,
93
+ projectionPath: e.projectionPath,
94
+ })),
95
+ topReview: impact.affected.review.slice(0, 5).map((e) => ({
96
+ id: e.id,
97
+ projectionPath: e.projectionPath,
98
+ })),
99
+ };
100
+ }
101
+ export function buildResolvePlan(thread, anchor, impact, resolvedFrom, pickId) {
102
+ const firstComment = thread.comments.find((c) => !c.deletedAt);
103
+ const ask = firstComment?.body ?? "(no comment body)";
104
+ const regenerateCommands = impact && impact.affected.regenerate.length > 0
105
+ ? [
106
+ ...new Set(impact.affected.regenerate
107
+ .slice(0, 5)
108
+ .map((e) => `/generate-srs from ${e.id}`)),
109
+ ]
110
+ : [];
111
+ return {
112
+ pickId,
113
+ thread,
114
+ anchor,
115
+ impact,
116
+ impactSummary: summarizeImpact(impact),
117
+ resolvedFrom,
118
+ workflow: {
119
+ phases: [
120
+ "show_plan_in_chat",
121
+ "propose_doc_edit",
122
+ "user_approval",
123
+ "apply_edit_to_doc",
124
+ "git_commit_doc_then_resolve_meta",
125
+ "git_push",
126
+ "optional_index_or_regen",
127
+ ],
128
+ suggestEdit: {
129
+ docPath: anchor?.docPath ?? thread.docPath,
130
+ startLine: thread.anchor.startLine,
131
+ endLine: thread.anchor.endLine,
132
+ instruction: `Address reviewer comment at lines ${thread.anchor.startLine}-${thread.anchor.endLine}: ${previewCommentBody(ask, 200)}`,
133
+ },
134
+ afterApply: {
135
+ indexRefresh: impact != null && (impact.affected.regenerate.length > 0 || impact.affected.review.length > 0),
136
+ regenerateCommands,
137
+ },
138
+ },
139
+ };
140
+ }
141
+ export function formatPlanForChat(plan) {
142
+ const t = plan.thread;
143
+ const lines = [
144
+ plan.pickId ? `# ${plan.pickId} → ${t.threadId}` : `# Thread ${t.threadId}`,
145
+ "",
146
+ `**File:** ${t.filePath} → ${t.docPath ?? "(unknown)"}`,
147
+ `**Anchor:** lines ${t.anchor.startLine}-${t.anchor.endLine} (${t.anchor.language})`,
148
+ ];
149
+ if (t.anchor.lineExcerpt) {
150
+ lines.push(`**Excerpt:** ${t.anchor.lineExcerpt}`);
151
+ }
152
+ lines.push("", "**Comments:**");
153
+ for (const c of t.comments) {
154
+ if (c.deletedAt) {
155
+ continue;
156
+ }
157
+ lines.push(`- ${c.authorId}: ${c.body}`);
158
+ }
159
+ if (plan.anchor?.anchoredText) {
160
+ lines.push("", "**Current text at anchor:**", "```markdown", plan.anchor.anchoredText, "```");
161
+ }
162
+ if (plan.impactSummary) {
163
+ lines.push("", "**Impact if you change this section:**", `- Regenerate: ${plan.impactSummary.regenerate}`, `- Review: ${plan.impactSummary.review}`, `- Downstream: ${plan.impactSummary.downstream}`);
164
+ if (plan.resolvedFrom) {
165
+ lines.push(`- Graph seed: \`${plan.resolvedFrom.id}\` (${plan.resolvedFrom.reason})`);
166
+ }
167
+ if (plan.impactSummary.topRegenerate.length > 0) {
168
+ lines.push("", "Top regen targets:");
169
+ for (const e of plan.impactSummary.topRegenerate) {
170
+ lines.push(`- \`${e.id}\`${e.projectionPath ? ` → ${e.projectionPath}` : ""}`);
171
+ }
172
+ }
173
+ }
174
+ else {
175
+ lines.push("", "**Impact:** (graph unavailable — run /index or /validate-graph first)");
176
+ }
177
+ lines.push("", "**Next (IDE workflow):**", "1. Propose a concrete doc edit addressing the comment", "2. Wait for your approval", "3. Apply the edit", "4. Commit **doc + comment meta in one commit** (amend) → push");
178
+ return lines.join("\n");
179
+ }
180
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/comments/inbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** Strip leading/trailing slashes and `docs/` prefix from logical paths. */
2
+ export declare function normalizeLogicalPath(filePath: string): string;
3
+ /**
4
+ * Map comment logical_path (e.g. `srs/01-overview`) to repo-relative doc file.
5
+ * Returns null when the prefix is unknown.
6
+ */
7
+ export declare function logicalPathToDocPath(logicalPath: string): string | null;
8
+ export declare function commentsRootRel(): string;
9
+ export declare function threadDirRel(logicalPath: string, threadId: string): string;
10
+ export declare function threadMetaRel(logicalPath: string, threadId: string): string;
11
+ export declare function threadEventsRel(logicalPath: string, threadId: string): string;
12
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/comments/paths.ts"],"names":[],"mappings":"AAIA,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwBvE;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7E"}
@@ -0,0 +1,54 @@
1
+ import { join } from "node:path";
2
+ const COMMENTS_ROOT = "comments";
3
+ /** Strip leading/trailing slashes and `docs/` prefix from logical paths. */
4
+ export function normalizeLogicalPath(filePath) {
5
+ let p = filePath.trim().replace(/\\/g, "/");
6
+ p = p.replace(/^\/+|\/+$/g, "");
7
+ if (p.startsWith("docs/")) {
8
+ p = p.slice("docs/".length);
9
+ }
10
+ if (p.endsWith(".md")) {
11
+ p = p.slice(0, -3);
12
+ }
13
+ return p;
14
+ }
15
+ /**
16
+ * Map comment logical_path (e.g. `srs/01-overview`) to repo-relative doc file.
17
+ * Returns null when the prefix is unknown.
18
+ */
19
+ export function logicalPathToDocPath(logicalPath) {
20
+ const p = normalizeLogicalPath(logicalPath);
21
+ if (!p) {
22
+ return null;
23
+ }
24
+ if (p.startsWith("srs/") || p === "srs") {
25
+ return `docs/srs/${p === "srs" ? "" : p.slice("srs/".length)}.md`.replace(/\/\.md$/, ".md");
26
+ }
27
+ if (p.startsWith("basic-design/") || p.startsWith("bd/")) {
28
+ const rest = p.startsWith("basic-design/")
29
+ ? p.slice("basic-design/".length)
30
+ : p.slice("bd/".length);
31
+ return `docs/basic-design/${rest}.md`;
32
+ }
33
+ if (p.startsWith("detail-design/") || p.startsWith("dd/")) {
34
+ const rest = p.startsWith("detail-design/")
35
+ ? p.slice("detail-design/".length)
36
+ : p.slice("dd/".length);
37
+ return `docs/detail-design/${rest}.md`;
38
+ }
39
+ return null;
40
+ }
41
+ export function commentsRootRel() {
42
+ return COMMENTS_ROOT;
43
+ }
44
+ export function threadDirRel(logicalPath, threadId) {
45
+ const lp = normalizeLogicalPath(logicalPath);
46
+ return join(COMMENTS_ROOT, lp, threadId).replace(/\\/g, "/");
47
+ }
48
+ export function threadMetaRel(logicalPath, threadId) {
49
+ return `${threadDirRel(logicalPath, threadId)}/meta_data.json`;
50
+ }
51
+ export function threadEventsRel(logicalPath, threadId) {
52
+ return `${threadDirRel(logicalPath, threadId)}/events.jsonl`;
53
+ }
54
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/comments/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CommentInboxItem } from "./inbox.js";
2
+ import { type CommentInbox, type CommentResolvePlan } from "./inbox.js";
3
+ export interface BuildInboxOptions {
4
+ projectRoot: string;
5
+ filePath?: string;
6
+ status?: "open" | "resolved" | "all";
7
+ }
8
+ export declare function buildCommentInboxPayload(opts: BuildInboxOptions): Promise<CommentInbox>;
9
+ export interface BuildPlanOptions {
10
+ projectRoot: string;
11
+ graphPath: string;
12
+ rulesPath: string;
13
+ threadId: string;
14
+ filePath?: string;
15
+ pickId?: string;
16
+ }
17
+ export declare function buildCommentPlan(opts: BuildPlanOptions): Promise<CommentResolvePlan>;
18
+ export declare function resolvePickId(inbox: CommentInbox, token: string): CommentInboxItem | undefined;
19
+ export declare function pickIdForThread(inbox: CommentInbox, threadId: string): string | undefined;
20
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/comments/plan.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AASpB,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;CACtC;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,YAAY,CAAC,CAUvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA+C7B;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,MAAM,GACZ,gBAAgB,GAAG,SAAS,CAS9B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEzF"}
@@ -0,0 +1,62 @@
1
+ import { computeImpact, loadImpactRules } from "../graph/impact.js";
2
+ import { loadInMemoryGraph } from "../graph/loadGraph.js";
3
+ import { pickPrimaryImpactOrigin, resolveImpactOrigins, } from "../graph/resolve.js";
4
+ import { readDocAnchorContext } from "./anchor.js";
5
+ import { buildCommentInbox, buildResolvePlan, enrichInboxPreviews, } from "./inbox.js";
6
+ import { normalizeLogicalPath } from "./paths.js";
7
+ import { findThreadById, getThread, listThreads, loadCommentBodiesForThreads, } from "./storage.js";
8
+ export async function buildCommentInboxPayload(opts) {
9
+ const threads = await listThreads({
10
+ projectRoot: opts.projectRoot,
11
+ filePath: opts.filePath,
12
+ status: opts.status ?? "open",
13
+ });
14
+ const firstComments = await loadCommentBodiesForThreads(opts.projectRoot, threads);
15
+ const base = buildCommentInbox(threads);
16
+ return enrichInboxPreviews(base, firstComments);
17
+ }
18
+ export async function buildCommentPlan(opts) {
19
+ const thread = opts.filePath
20
+ ? await getThread(opts.projectRoot, normalizeLogicalPath(opts.filePath), opts.threadId)
21
+ : await findThreadById(opts.projectRoot, opts.threadId);
22
+ if (!thread) {
23
+ throw new Error(opts.filePath
24
+ ? `Thread not found: ${opts.threadId} under ${normalizeLogicalPath(opts.filePath)}`
25
+ : `Thread not found: ${opts.threadId}`);
26
+ }
27
+ const anchor = await readDocAnchorContext(opts.projectRoot, thread.filePath, thread.anchor.startLine, thread.anchor.endLine);
28
+ let impact = null;
29
+ let resolvedFrom;
30
+ try {
31
+ const g = await loadInMemoryGraph(opts.graphPath);
32
+ const origins = resolveImpactOrigins(g, {
33
+ file: anchor?.docPath ?? thread.docPath ?? undefined,
34
+ heading: anchor?.heading,
35
+ sectionAnchor: anchor?.sectionAnchor,
36
+ text: thread.anchor.lineExcerpt,
37
+ });
38
+ const primary = pickPrimaryImpactOrigin(origins);
39
+ if (primary) {
40
+ resolvedFrom = primary;
41
+ const rules = await loadImpactRules(opts.rulesPath);
42
+ impact = computeImpact(g, primary.id, "content_change", rules);
43
+ impact.resolvedFrom = primary;
44
+ }
45
+ }
46
+ catch {
47
+ /* graph missing or invalid — plan still usable without impact */
48
+ }
49
+ return buildResolvePlan(thread, anchor, impact, resolvedFrom, opts.pickId);
50
+ }
51
+ export function resolvePickId(inbox, token) {
52
+ const t = token.trim();
53
+ const byPick = inbox.inbox.find((i) => i.pickId.toLowerCase() === t.toLowerCase());
54
+ if (byPick) {
55
+ return byPick;
56
+ }
57
+ return inbox.inbox.find((i) => i.threadId === t || i.threadId.startsWith(t));
58
+ }
59
+ export function pickIdForThread(inbox, threadId) {
60
+ return inbox.inbox.find((i) => i.threadId === threadId)?.pickId;
61
+ }
62
+ //# sourceMappingURL=plan.js.map