@aidemd-mcp/server 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/.aide/docs/.aide +128 -0
  2. package/.aide/docs/agent-readable-code.md +74 -0
  3. package/.aide/docs/aide-spec.md +201 -0
  4. package/.aide/docs/aide-template.md +110 -0
  5. package/.aide/docs/automated-qa.md +111 -0
  6. package/.aide/docs/cascading-alignment.md +107 -0
  7. package/.aide/docs/index.md +38 -0
  8. package/.aide/docs/plan-aide.md +77 -0
  9. package/.aide/docs/plan.aide +60 -0
  10. package/.aide/docs/progressive-disclosure.md +72 -0
  11. package/.aide/docs/todo-aide.md +77 -0
  12. package/.aide/intent.aide +256 -0
  13. package/.aide/plan.aide +169 -0
  14. package/.aide/todo.aide +47 -0
  15. package/.claude/.aide +246 -0
  16. package/.claude/commands/aide/align.md +15 -0
  17. package/.claude/commands/aide/build.md +17 -0
  18. package/.claude/commands/aide/fix.md +20 -0
  19. package/.claude/commands/aide/init.md +171 -0
  20. package/.claude/commands/aide/plan.md +25 -0
  21. package/.claude/commands/aide/qa.md +25 -0
  22. package/.claude/commands/aide/refactor.md +29 -0
  23. package/.claude/commands/aide/research.md +21 -0
  24. package/.claude/commands/aide/spec.md +24 -0
  25. package/.claude/commands/aide/synthesize.md +20 -0
  26. package/.claude/commands/aide/update-playbook.md +18 -0
  27. package/.claude/commands/aide/upgrade.md +91 -0
  28. package/LICENSE +21 -0
  29. package/README.md +88 -0
  30. package/dist/cli/App/index.d.ts +14 -0
  31. package/dist/cli/App/index.js +282 -0
  32. package/dist/cli/DetailPanel/index.d.ts +24 -0
  33. package/dist/cli/DetailPanel/index.js +57 -0
  34. package/dist/cli/TreePanel/index.d.ts +24 -0
  35. package/dist/cli/TreePanel/index.js +65 -0
  36. package/dist/cli/buildTreeData/index.d.ts +7 -0
  37. package/dist/cli/buildTreeData/index.js +51 -0
  38. package/dist/cli/findPrimaryIntent/index.d.ts +12 -0
  39. package/dist/cli/findPrimaryIntent/index.js +20 -0
  40. package/dist/cli/flattenTree/index.d.ts +16 -0
  41. package/dist/cli/flattenTree/index.js +20 -0
  42. package/dist/cli/index.d.ts +2 -0
  43. package/dist/cli/index.js +15 -0
  44. package/dist/cli/init/index.d.ts +2 -0
  45. package/dist/cli/init/index.js +33 -0
  46. package/dist/cli/init/writeInitCommand/index.d.ts +13 -0
  47. package/dist/cli/init/writeInitCommand/index.js +25 -0
  48. package/dist/cli/init/writeMcpEntry/index.d.ts +12 -0
  49. package/dist/cli/init/writeMcpEntry/index.js +51 -0
  50. package/dist/index.d.ts +2 -0
  51. package/dist/index.js +228 -0
  52. package/dist/tools/discover/buildAncestorChain/index.d.ts +17 -0
  53. package/dist/tools/discover/buildAncestorChain/index.js +98 -0
  54. package/dist/tools/discover/buildTree/index.d.ts +9 -0
  55. package/dist/tools/discover/buildTree/index.js +57 -0
  56. package/dist/tools/discover/index.d.ts +20 -0
  57. package/dist/tools/discover/index.js +49 -0
  58. package/dist/tools/init/applySteps/index.d.ts +30 -0
  59. package/dist/tools/init/applySteps/index.js +76 -0
  60. package/dist/tools/init/configureIde/index.d.ts +21 -0
  61. package/dist/tools/init/configureIde/index.js +135 -0
  62. package/dist/tools/init/detectFramework/index.d.ts +11 -0
  63. package/dist/tools/init/detectFramework/index.js +53 -0
  64. package/dist/tools/init/index.d.ts +46 -0
  65. package/dist/tools/init/index.js +99 -0
  66. package/dist/tools/init/initContent/index.d.ts +99 -0
  67. package/dist/tools/init/initContent/index.js +162 -0
  68. package/dist/tools/init/installAgents/index.d.ts +12 -0
  69. package/dist/tools/init/installAgents/index.js +60 -0
  70. package/dist/tools/init/installMethodologyDocs/index.d.ts +14 -0
  71. package/dist/tools/init/installMethodologyDocs/index.js +62 -0
  72. package/dist/tools/init/installSkills/index.d.ts +12 -0
  73. package/dist/tools/init/installSkills/index.js +60 -0
  74. package/dist/tools/init/provisionBrain/index.d.ts +23 -0
  75. package/dist/tools/init/provisionBrain/index.js +239 -0
  76. package/dist/tools/init/resolveBrainHints/index.d.ts +17 -0
  77. package/dist/tools/init/resolveBrainHints/index.js +44 -0
  78. package/dist/tools/init/scaffoldCommands/index.d.ts +38 -0
  79. package/dist/tools/init/scaffoldCommands/index.js +94 -0
  80. package/dist/tools/init/wireMcp/index.d.ts +16 -0
  81. package/dist/tools/init/wireMcp/index.js +72 -0
  82. package/dist/tools/init/writeMethodology/index.d.ts +20 -0
  83. package/dist/tools/init/writeMethodology/index.js +94 -0
  84. package/dist/tools/read/index.d.ts +15 -0
  85. package/dist/tools/read/index.js +79 -0
  86. package/dist/tools/scaffold/index.d.ts +22 -0
  87. package/dist/tools/scaffold/index.js +128 -0
  88. package/dist/tools/upgrade/applyFiles/index.d.ts +33 -0
  89. package/dist/tools/upgrade/applyFiles/index.js +65 -0
  90. package/dist/tools/upgrade/buildVersionsMeta/index.d.ts +20 -0
  91. package/dist/tools/upgrade/buildVersionsMeta/index.js +51 -0
  92. package/dist/tools/upgrade/checkIdeConfig/index.d.ts +24 -0
  93. package/dist/tools/upgrade/checkIdeConfig/index.js +134 -0
  94. package/dist/tools/upgrade/checkMcpConfig/index.d.ts +17 -0
  95. package/dist/tools/upgrade/checkMcpConfig/index.js +81 -0
  96. package/dist/tools/upgrade/compareFile/index.d.ts +12 -0
  97. package/dist/tools/upgrade/compareFile/index.js +24 -0
  98. package/dist/tools/upgrade/index.d.ts +24 -0
  99. package/dist/tools/upgrade/index.js +139 -0
  100. package/dist/tools/upgrade/spliceStub/index.d.ts +13 -0
  101. package/dist/tools/upgrade/spliceStub/index.js +91 -0
  102. package/dist/tools/validate/index.d.ts +18 -0
  103. package/dist/tools/validate/index.js +65 -0
  104. package/dist/types/index.d.ts +277 -0
  105. package/dist/types/index.js +10 -0
  106. package/dist/util/classify/index.d.ts +17 -0
  107. package/dist/util/classify/index.js +134 -0
  108. package/dist/util/parseBody/index.d.ts +7 -0
  109. package/dist/util/parseBody/index.js +43 -0
  110. package/dist/util/parseFrontmatter/index.d.ts +12 -0
  111. package/dist/util/parseFrontmatter/index.js +64 -0
  112. package/dist/util/scan/index.d.ts +7 -0
  113. package/dist/util/scan/index.js +82 -0
  114. package/package.json +59 -0
@@ -0,0 +1,99 @@
1
+ import { z } from "zod";
2
+ import { join, isAbsolute, dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import detectFramework from "../../tools/init/detectFramework/index.js";
5
+ import resolveBrainHints from "../../tools/init/resolveBrainHints/index.js";
6
+ import { configureZed, configureVscode } from "../../tools/init/configureIde/index.js";
7
+ import writeMethodology from "./writeMethodology/index.js";
8
+ import installMethodologyDocs from "./installMethodologyDocs/index.js";
9
+ import scaffoldCommands from "./scaffoldCommands/index.js";
10
+ import installAgents from "./installAgents/index.js";
11
+ import installSkills from "./installSkills/index.js";
12
+ import wireMcp from "./wireMcp/index.js";
13
+ import provisionBrain from "./provisionBrain/index.js";
14
+ /**
15
+ * Input schema for aide_init.
16
+ *
17
+ * `brainPath` and `skipIde` are removed: the brain path is always resolved
18
+ * through agent-user conversation (not a silent tool parameter), and IDE
19
+ * configuration is presented per-category during the agent interview.
20
+ * `framework` remains so the agent can re-call after user confirms or
21
+ * overrides framework detection.
22
+ */
23
+ export const InitInput = z.object({
24
+ framework: z.enum(["claude", "cursor", "windsurf", "copilot"]).optional().describe("Force a specific framework instead of auto-detecting"),
25
+ path: z.string().optional().describe("Custom project root path (defaults to server working directory)"),
26
+ category: z.enum(["framework", "methodology", "commands", "agents", "skills", "mcp", "brain", "ide"]).optional().describe("When provided, write all would-create files to disk and return a manifest. When omitted, return all steps as a metadata-only summary (no content fields)."),
27
+ brainPath: z.string().optional().describe("Resolved brain vault path for the brain category. The agent provides this after interviewing the user."),
28
+ });
29
+ /**
30
+ * Bootstrap the AIDE development environment into a project.
31
+ *
32
+ * Returns structured JSON (`InitResult`) — no prose, no formatting. The
33
+ * calling agent interprets the result, walks the user through each category,
34
+ * and applies the steps the user confirms.
35
+ *
36
+ * Each step is idempotent: re-running on a fully initialized project returns
37
+ * all steps as `exists`. Brain hints are discovered from env var, sibling
38
+ * path, and conventional path — returned as candidates the agent presents
39
+ * to the user; the agent confirms the path before any vault work is done.
40
+ *
41
+ * @param root - Server working directory (from --root CLI arg or cwd).
42
+ * @param framework - Optional framework override.
43
+ * @param path - Optional project root override (absolute or relative to root).
44
+ * @param brainPath - User-confirmed vault path. When provided, forwarded to
45
+ * provisionBrain instead of using the first discovered hint.
46
+ */
47
+ export default async function init(root, framework, path, brainPath) {
48
+ const projectRoot = path ? (isAbsolute(path) ? path : join(root, path)) : root;
49
+ const config = await detectFramework(projectRoot, framework);
50
+ const brainHints = await resolveBrainHints(projectRoot);
51
+ // Collect planning steps from each helper. Order follows the spec's category
52
+ // list: methodology, commands, agents, skills, mcp, brain, ide.
53
+ const docSteps = await installMethodologyDocs(join(projectRoot, config.docHubDir), config.docHubDir);
54
+ const methodologyStep = await writeMethodology(join(projectRoot, config.configPath), config.docHubDir);
55
+ const commandSteps = await scaffoldCommands(join(projectRoot, config.commandDir));
56
+ const agentSteps = await installAgents(join(projectRoot, config.agentDir));
57
+ const skillSteps = await installSkills(join(projectRoot, config.skillDir));
58
+ const mcpStep = await wireMcp(join(projectRoot, config.mcpConfigPath));
59
+ // Brain steps require a confirmed vault path. When brainPath is explicitly
60
+ // provided (agent-confirmed), use it directly. When hints exist, use the
61
+ // first hint to check existing state. When neither is available, return
62
+ // placeholder steps so the agent knows to interview the user first.
63
+ const brainMcpPath = join(projectRoot, config.mcpConfigPath);
64
+ let brainSteps;
65
+ const resolvedBrainPath = brainPath ?? (brainHints.length > 0 ? brainHints[0].path : undefined);
66
+ if (resolvedBrainPath) {
67
+ brainSteps = await provisionBrain(resolvedBrainPath, brainMcpPath);
68
+ }
69
+ else {
70
+ // No hints discovered and no explicit brainPath — the agent must ask the
71
+ // user for a path. Return would-create steps with empty filePaths so the
72
+ // agent knows brain provisioning is pending user input, not silently resolved.
73
+ brainSteps = [
74
+ { name: "Brain vault", status: "would-create", category: "brain", filePath: "" },
75
+ { name: "Playbook hub", status: "would-create", category: "brain", filePath: "" },
76
+ { name: "Vault CLAUDE.md", status: "would-create", category: "brain", filePath: "" },
77
+ { name: "MCP config (obsidian)", status: "would-create", category: "mcp", filePath: brainMcpPath },
78
+ ];
79
+ }
80
+ const extensionsDir = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "..", "extensions", "vscode");
81
+ const zedStep = await configureZed(projectRoot);
82
+ const vscodeStep = await configureVscode(extensionsDir);
83
+ const steps = [
84
+ methodologyStep,
85
+ ...docSteps,
86
+ ...commandSteps,
87
+ ...agentSteps,
88
+ ...skillSteps,
89
+ mcpStep,
90
+ ...brainSteps,
91
+ zedStep,
92
+ vscodeStep,
93
+ ];
94
+ return {
95
+ framework: config.framework,
96
+ steps,
97
+ brainHints,
98
+ };
99
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Canonical-name → repo-relative-path registry. Consumers ask for content by
3
+ * canonical name; the file layout under the repo root is this helper's
4
+ * private concern and never crosses the interface. If the canonical layout
5
+ * is reorganized, only this map changes.
6
+ */
7
+ declare const DOC_PATHS: {
8
+ readonly index: ".aide/docs/index.md";
9
+ readonly "aide-spec": ".aide/docs/aide-spec.md";
10
+ readonly "aide-template": ".aide/docs/aide-template.md";
11
+ readonly "progressive-disclosure": ".aide/docs/progressive-disclosure.md";
12
+ readonly "agent-readable-code": ".aide/docs/agent-readable-code.md";
13
+ readonly "automated-qa": ".aide/docs/automated-qa.md";
14
+ readonly "commands/aide/research": ".claude/commands/aide/research.md";
15
+ readonly "commands/aide/spec": ".claude/commands/aide/spec.md";
16
+ readonly "commands/aide/plan": ".claude/commands/aide/plan.md";
17
+ readonly "commands/aide/build": ".claude/commands/aide/build.md";
18
+ readonly "commands/aide/qa": ".claude/commands/aide/qa.md";
19
+ readonly "commands/aide/fix": ".claude/commands/aide/fix.md";
20
+ readonly "plan-aide": ".aide/docs/plan-aide.md";
21
+ readonly "todo-aide": ".aide/docs/todo-aide.md";
22
+ readonly "commands/aide/synthesize": ".claude/commands/aide/synthesize.md";
23
+ readonly "commands/aide/upgrade": ".claude/commands/aide/upgrade.md";
24
+ readonly "commands/aide/init": ".claude/commands/aide/init.md";
25
+ readonly "commands/aide/update-playbook": ".claude/commands/aide/update-playbook.md";
26
+ readonly "commands/aide/aide": ".claude/commands/aide.md";
27
+ readonly "commands/aide/refactor": ".claude/commands/aide/refactor.md";
28
+ readonly "agents/aide/aide-spec-writer": ".claude/agents/aide/aide-spec-writer.md";
29
+ readonly "agents/aide/aide-domain-expert": ".claude/agents/aide/aide-domain-expert.md";
30
+ readonly "agents/aide/aide-strategist": ".claude/agents/aide/aide-strategist.md";
31
+ readonly "agents/aide/aide-architect": ".claude/agents/aide/aide-architect.md";
32
+ readonly "agents/aide/aide-implementor": ".claude/agents/aide/aide-implementor.md";
33
+ readonly "agents/aide/aide-qa": ".claude/agents/aide/aide-qa.md";
34
+ readonly "agents/aide/aide-auditor": ".claude/agents/aide/aide-auditor.md";
35
+ readonly "agents/aide/aide-aligner": ".claude/agents/aide/aide-aligner.md";
36
+ readonly "commands/aide/align": ".claude/commands/aide/align.md";
37
+ readonly "cascading-alignment": ".aide/docs/cascading-alignment.md";
38
+ readonly "skills/study-playbook": ".claude/skills/study-playbook/SKILL.md";
39
+ readonly "skills/brain": ".claude/skills/brain/SKILL.md";
40
+ };
41
+ export type CanonicalDocName = keyof typeof DOC_PATHS;
42
+ /**
43
+ * An entry in the methodology-doc enumeration. Consumers iterate this list
44
+ * to install the methodology subset into the host-side doc hub — the
45
+ * `canonical` field is the lookup key into `readCanonicalDoc`, and the
46
+ * `hostFilename` is the basename to write under the host hub directory.
47
+ */
48
+ export interface MethodologyDocEntry {
49
+ readonly canonical: CanonicalDocName;
50
+ readonly hostFilename: string;
51
+ }
52
+ /**
53
+ * An entry in the agent-doc enumeration. Consumers iterate this list to
54
+ * install the pipeline agent files into the host's agent directory.
55
+ */
56
+ export interface AgentDocEntry {
57
+ readonly canonical: CanonicalDocName;
58
+ readonly hostFilename: string;
59
+ }
60
+ /**
61
+ * An entry in the skill-doc enumeration. Consumers iterate this list to
62
+ * install skill templates into the host's skill directory.
63
+ */
64
+ export interface SkillDocEntry {
65
+ readonly canonical: CanonicalDocName;
66
+ readonly hostPath: string;
67
+ }
68
+ /**
69
+ * Read one canonical doc verbatim from disk by canonical name. The returned
70
+ * string is byte-identical to the file on disk: no trimming, no normalization,
71
+ * no frontmatter stripping, no link rewriting. Composition is the consumer's
72
+ * concern and lives downstream. Throws a clear error naming the canonical
73
+ * name and the resolved path on any read failure — there is no fallback to
74
+ * an embedded default, because shipping invented content is exactly the
75
+ * failure mode this helper exists to prevent.
76
+ */
77
+ export declare function readCanonicalDoc(name: CanonicalDocName): string;
78
+ /** Return the idempotency marker used to detect existing methodology. */
79
+ export declare function getMethodologyMarker(): string;
80
+ /**
81
+ * Return the canonical enumeration of methodology docs that belong in the
82
+ * host-side doc hub. Consumers iterate the returned list rather than
83
+ * maintaining their own local copy — hardcoding the membership of "the
84
+ * methodology" anywhere else under the init subtree would be a second
85
+ * source of truth for the same decision and would silently drift on the
86
+ * next canonical-doc addition.
87
+ */
88
+ export declare function listMethodologyDocs(): readonly MethodologyDocEntry[];
89
+ /**
90
+ * Return the canonical enumeration of pipeline agent files that belong in
91
+ * the host's agent directory.
92
+ */
93
+ export declare function listAgents(): readonly AgentDocEntry[];
94
+ /**
95
+ * Return the canonical enumeration of skill templates that belong in the
96
+ * host's skill directory.
97
+ */
98
+ export declare function listSkills(): readonly SkillDocEntry[];
99
+ export {};
@@ -0,0 +1,162 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ /**
5
+ * Idempotency marker that wraps the methodology block in the host's config
6
+ * file. Framework plumbing — not AIDE doctrine — so it is allowed to live as
7
+ * a literal here. Changing its bytes would break duplicate detection in every
8
+ * host project that already has a methodology block installed, so it must
9
+ * stay byte-stable across refactors.
10
+ */
11
+ const METHODOLOGY_MARKER = "<!-- aide-methodology -->";
12
+ /**
13
+ * Resolve the repo root relative to this module's own location. Anchoring to
14
+ * import.meta.url (not process.cwd()) is load-bearing: the MCP server is
15
+ * launched from the host project's directory, so cwd points there and would
16
+ * never find the canonical files. src/ and dist/ are siblings under the repo
17
+ * root at the same depth, so the same four-hop walk reaches the root whether
18
+ * this file runs from src/tools/init/initContent/ or dist/tools/init/initContent/.
19
+ * Canonical content lives under two subtrees of the repo root — `.aide/docs/`
20
+ * for methodology and `.claude/commands/aide/` for slash command templates —
21
+ * so DOC_PATHS values carry the subtree prefix and we resolve from the root.
22
+ */
23
+ const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
24
+ const REPO_ROOT = join(MODULE_DIR, "..", "..", "..", "..");
25
+ /**
26
+ * Canonical-name → repo-relative-path registry. Consumers ask for content by
27
+ * canonical name; the file layout under the repo root is this helper's
28
+ * private concern and never crosses the interface. If the canonical layout
29
+ * is reorganized, only this map changes.
30
+ */
31
+ const DOC_PATHS = {
32
+ "index": ".aide/docs/index.md",
33
+ "aide-spec": ".aide/docs/aide-spec.md",
34
+ "aide-template": ".aide/docs/aide-template.md",
35
+ "progressive-disclosure": ".aide/docs/progressive-disclosure.md",
36
+ "agent-readable-code": ".aide/docs/agent-readable-code.md",
37
+ "automated-qa": ".aide/docs/automated-qa.md",
38
+ "commands/aide/research": ".claude/commands/aide/research.md",
39
+ "commands/aide/spec": ".claude/commands/aide/spec.md",
40
+ "commands/aide/plan": ".claude/commands/aide/plan.md",
41
+ "commands/aide/build": ".claude/commands/aide/build.md",
42
+ "commands/aide/qa": ".claude/commands/aide/qa.md",
43
+ "commands/aide/fix": ".claude/commands/aide/fix.md",
44
+ "plan-aide": ".aide/docs/plan-aide.md",
45
+ "todo-aide": ".aide/docs/todo-aide.md",
46
+ "commands/aide/synthesize": ".claude/commands/aide/synthesize.md",
47
+ "commands/aide/upgrade": ".claude/commands/aide/upgrade.md",
48
+ "commands/aide/init": ".claude/commands/aide/init.md",
49
+ "commands/aide/update-playbook": ".claude/commands/aide/update-playbook.md",
50
+ "commands/aide/aide": ".claude/commands/aide.md",
51
+ "commands/aide/refactor": ".claude/commands/aide/refactor.md",
52
+ "agents/aide/aide-spec-writer": ".claude/agents/aide/aide-spec-writer.md",
53
+ "agents/aide/aide-domain-expert": ".claude/agents/aide/aide-domain-expert.md",
54
+ "agents/aide/aide-strategist": ".claude/agents/aide/aide-strategist.md",
55
+ "agents/aide/aide-architect": ".claude/agents/aide/aide-architect.md",
56
+ "agents/aide/aide-implementor": ".claude/agents/aide/aide-implementor.md",
57
+ "agents/aide/aide-qa": ".claude/agents/aide/aide-qa.md",
58
+ "agents/aide/aide-auditor": ".claude/agents/aide/aide-auditor.md",
59
+ "agents/aide/aide-aligner": ".claude/agents/aide/aide-aligner.md",
60
+ "commands/aide/align": ".claude/commands/aide/align.md",
61
+ "cascading-alignment": ".aide/docs/cascading-alignment.md",
62
+ "skills/study-playbook": ".claude/skills/study-playbook/SKILL.md",
63
+ "skills/brain": ".claude/skills/brain/SKILL.md",
64
+ };
65
+ /**
66
+ * The canonical list of methodology docs that ship into the host-side doc
67
+ * hub. Ordering is the hub's reading order and therefore stable — adding a
68
+ * new methodology doc appends to the end. Owning this list here (alongside
69
+ * the name-to-path registry it depends on) is load-bearing: the parent
70
+ * spec's single-reader invariant extends to enumeration, so downstream
71
+ * consumers iterate this list rather than hardcoding the membership of
72
+ * "the methodology" in their own source.
73
+ */
74
+ const METHODOLOGY_DOCS = [
75
+ { canonical: "index", hostFilename: "index.md" },
76
+ { canonical: "aide-spec", hostFilename: "aide-spec.md" },
77
+ { canonical: "aide-template", hostFilename: "aide-template.md" },
78
+ { canonical: "progressive-disclosure", hostFilename: "progressive-disclosure.md" },
79
+ { canonical: "agent-readable-code", hostFilename: "agent-readable-code.md" },
80
+ { canonical: "automated-qa", hostFilename: "automated-qa.md" },
81
+ { canonical: "plan-aide", hostFilename: "plan-aide.md" },
82
+ { canonical: "todo-aide", hostFilename: "todo-aide.md" },
83
+ { canonical: "cascading-alignment", hostFilename: "cascading-alignment.md" },
84
+ ];
85
+ /**
86
+ * The canonical list of pipeline agent files that ship into the host's
87
+ * agent directory. Ordering is pipeline phase order.
88
+ */
89
+ const AGENT_DOCS = [
90
+ { canonical: "agents/aide/aide-spec-writer", hostFilename: "aide/aide-spec-writer.md" },
91
+ { canonical: "agents/aide/aide-domain-expert", hostFilename: "aide/aide-domain-expert.md" },
92
+ { canonical: "agents/aide/aide-strategist", hostFilename: "aide/aide-strategist.md" },
93
+ { canonical: "agents/aide/aide-architect", hostFilename: "aide/aide-architect.md" },
94
+ { canonical: "agents/aide/aide-implementor", hostFilename: "aide/aide-implementor.md" },
95
+ { canonical: "agents/aide/aide-qa", hostFilename: "aide/aide-qa.md" },
96
+ { canonical: "agents/aide/aide-auditor", hostFilename: "aide/aide-auditor.md" },
97
+ { canonical: "agents/aide/aide-aligner", hostFilename: "aide/aide-aligner.md" },
98
+ ];
99
+ /**
100
+ * The canonical list of skill templates that ship into the host's skill
101
+ * directory.
102
+ */
103
+ const SKILL_DOCS = [
104
+ { canonical: "skills/study-playbook", hostPath: "study-playbook/SKILL.md" },
105
+ { canonical: "skills/brain", hostPath: "brain/SKILL.md" },
106
+ ];
107
+ /** Per-process cache. Populated from disk reads in this process only — never
108
+ * from build-time-embedded content. Keyed by canonical name. */
109
+ const cache = new Map();
110
+ /**
111
+ * Read one canonical doc verbatim from disk by canonical name. The returned
112
+ * string is byte-identical to the file on disk: no trimming, no normalization,
113
+ * no frontmatter stripping, no link rewriting. Composition is the consumer's
114
+ * concern and lives downstream. Throws a clear error naming the canonical
115
+ * name and the resolved path on any read failure — there is no fallback to
116
+ * an embedded default, because shipping invented content is exactly the
117
+ * failure mode this helper exists to prevent.
118
+ */
119
+ export function readCanonicalDoc(name) {
120
+ const cached = cache.get(name);
121
+ if (cached !== undefined)
122
+ return cached;
123
+ const filePath = join(REPO_ROOT, DOC_PATHS[name]);
124
+ let bytes;
125
+ try {
126
+ bytes = readFileSync(filePath, "utf-8");
127
+ }
128
+ catch (cause) {
129
+ throw new Error(`initContent: canonical doc "${name}" not readable at ${filePath}`, { cause });
130
+ }
131
+ cache.set(name, bytes);
132
+ return bytes;
133
+ }
134
+ /** Return the idempotency marker used to detect existing methodology. */
135
+ export function getMethodologyMarker() {
136
+ return METHODOLOGY_MARKER;
137
+ }
138
+ /**
139
+ * Return the canonical enumeration of methodology docs that belong in the
140
+ * host-side doc hub. Consumers iterate the returned list rather than
141
+ * maintaining their own local copy — hardcoding the membership of "the
142
+ * methodology" anywhere else under the init subtree would be a second
143
+ * source of truth for the same decision and would silently drift on the
144
+ * next canonical-doc addition.
145
+ */
146
+ export function listMethodologyDocs() {
147
+ return METHODOLOGY_DOCS;
148
+ }
149
+ /**
150
+ * Return the canonical enumeration of pipeline agent files that belong in
151
+ * the host's agent directory.
152
+ */
153
+ export function listAgents() {
154
+ return AGENT_DOCS;
155
+ }
156
+ /**
157
+ * Return the canonical enumeration of skill templates that belong in the
158
+ * host's skill directory.
159
+ */
160
+ export function listSkills() {
161
+ return SKILL_DOCS;
162
+ }
@@ -0,0 +1,12 @@
1
+ import type { InitStep } from "../../../types/index.js";
2
+ /**
3
+ * Return planning steps for each canonical AIDE pipeline agent file.
4
+ *
5
+ * For each agent named by `listAgents()`, checks whether the host file
6
+ * already exists. Returns `exists` for present files, `would-create` with
7
+ * the canonical content for absent files. A failing canonical read returns
8
+ * `would-skip` for that entry only.
9
+ *
10
+ * This helper never writes to disk — it is a planner only.
11
+ */
12
+ export default function installAgents(agentDir: string, displayPrefix?: string): Promise<InitStep[]>;
@@ -0,0 +1,60 @@
1
+ import { access } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { readCanonicalDoc, listAgents, } from "../../../tools/init/initContent/index.js";
4
+ /** Check if a file exists on disk. */
5
+ async function fileExists(path) {
6
+ try {
7
+ await access(path);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ /**
15
+ * Return planning steps for each canonical AIDE pipeline agent file.
16
+ *
17
+ * For each agent named by `listAgents()`, checks whether the host file
18
+ * already exists. Returns `exists` for present files, `would-create` with
19
+ * the canonical content for absent files. A failing canonical read returns
20
+ * `would-skip` for that entry only.
21
+ *
22
+ * This helper never writes to disk — it is a planner only.
23
+ */
24
+ export default async function installAgents(agentDir, displayPrefix = "agents") {
25
+ const steps = [];
26
+ for (const entry of listAgents()) {
27
+ const targetPath = join(agentDir, entry.hostFilename);
28
+ const displayName = `${displayPrefix}/${entry.hostFilename}`;
29
+ if (await fileExists(targetPath)) {
30
+ steps.push({
31
+ name: displayName,
32
+ status: "exists",
33
+ category: "agents",
34
+ filePath: targetPath,
35
+ });
36
+ continue;
37
+ }
38
+ let content;
39
+ try {
40
+ content = readCanonicalDoc(entry.canonical);
41
+ }
42
+ catch {
43
+ steps.push({
44
+ name: displayName,
45
+ status: "would-skip",
46
+ category: "agents",
47
+ filePath: targetPath,
48
+ });
49
+ continue;
50
+ }
51
+ steps.push({
52
+ name: displayName,
53
+ status: "would-create",
54
+ category: "agents",
55
+ filePath: targetPath,
56
+ content,
57
+ });
58
+ }
59
+ return steps;
60
+ }
@@ -0,0 +1,14 @@
1
+ import type { InitStep } from "../../../types/index.js";
2
+ /**
3
+ * Return planning steps for each canonical AIDE methodology doc.
4
+ *
5
+ * For each doc named by `listMethodologyDocs()` — including the hub index —
6
+ * checks whether the host file already exists. Returns `exists` for present
7
+ * files, `would-create` with the canonical content for absent files.
8
+ *
9
+ * A failing read of one canonical doc returns `would-skip` for that entry
10
+ * only and does not affect the other steps.
11
+ *
12
+ * This helper never writes to disk — it is a planner only.
13
+ */
14
+ export default function installMethodologyDocs(docHubDir: string, displayPrefix?: string): Promise<InitStep[]>;
@@ -0,0 +1,62 @@
1
+ import { access } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { readCanonicalDoc, listMethodologyDocs, } from "../../../tools/init/initContent/index.js";
4
+ /** Check if a file exists on disk. */
5
+ async function fileExists(path) {
6
+ try {
7
+ await access(path);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ /**
15
+ * Return planning steps for each canonical AIDE methodology doc.
16
+ *
17
+ * For each doc named by `listMethodologyDocs()` — including the hub index —
18
+ * checks whether the host file already exists. Returns `exists` for present
19
+ * files, `would-create` with the canonical content for absent files.
20
+ *
21
+ * A failing read of one canonical doc returns `would-skip` for that entry
22
+ * only and does not affect the other steps.
23
+ *
24
+ * This helper never writes to disk — it is a planner only.
25
+ */
26
+ export default async function installMethodologyDocs(docHubDir, displayPrefix = ".aide") {
27
+ const steps = [];
28
+ for (const entry of listMethodologyDocs()) {
29
+ const targetPath = join(docHubDir, entry.hostFilename);
30
+ const displayName = `${displayPrefix}/${entry.hostFilename}`;
31
+ if (await fileExists(targetPath)) {
32
+ steps.push({
33
+ name: displayName,
34
+ status: "exists",
35
+ category: "methodology",
36
+ filePath: targetPath,
37
+ });
38
+ continue;
39
+ }
40
+ let content;
41
+ try {
42
+ content = readCanonicalDoc(entry.canonical);
43
+ }
44
+ catch {
45
+ steps.push({
46
+ name: displayName,
47
+ status: "would-skip",
48
+ category: "methodology",
49
+ filePath: targetPath,
50
+ });
51
+ continue;
52
+ }
53
+ steps.push({
54
+ name: displayName,
55
+ status: "would-create",
56
+ category: "methodology",
57
+ filePath: targetPath,
58
+ content,
59
+ });
60
+ }
61
+ return steps;
62
+ }
@@ -0,0 +1,12 @@
1
+ import type { InitStep } from "../../../types/index.js";
2
+ /**
3
+ * Return planning steps for each canonical AIDE skill template.
4
+ *
5
+ * For each skill named by `listSkills()`, checks whether the host file
6
+ * already exists. Returns `exists` for present files, `would-create` with
7
+ * the canonical content for absent files. A failing canonical read returns
8
+ * `would-skip` for that entry only.
9
+ *
10
+ * This helper never writes to disk — it is a planner only.
11
+ */
12
+ export default function installSkills(skillDir: string, displayPrefix?: string): Promise<InitStep[]>;
@@ -0,0 +1,60 @@
1
+ import { access } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { readCanonicalDoc, listSkills, } from "../../../tools/init/initContent/index.js";
4
+ /** Check if a file exists on disk. */
5
+ async function fileExists(path) {
6
+ try {
7
+ await access(path);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ /**
15
+ * Return planning steps for each canonical AIDE skill template.
16
+ *
17
+ * For each skill named by `listSkills()`, checks whether the host file
18
+ * already exists. Returns `exists` for present files, `would-create` with
19
+ * the canonical content for absent files. A failing canonical read returns
20
+ * `would-skip` for that entry only.
21
+ *
22
+ * This helper never writes to disk — it is a planner only.
23
+ */
24
+ export default async function installSkills(skillDir, displayPrefix = "skills") {
25
+ const steps = [];
26
+ for (const entry of listSkills()) {
27
+ const targetPath = join(skillDir, entry.hostPath);
28
+ const displayName = `${displayPrefix}/${entry.hostPath}`;
29
+ if (await fileExists(targetPath)) {
30
+ steps.push({
31
+ name: displayName,
32
+ status: "exists",
33
+ category: "skills",
34
+ filePath: targetPath,
35
+ });
36
+ continue;
37
+ }
38
+ let content;
39
+ try {
40
+ content = readCanonicalDoc(entry.canonical);
41
+ }
42
+ catch {
43
+ steps.push({
44
+ name: displayName,
45
+ status: "would-skip",
46
+ category: "skills",
47
+ filePath: targetPath,
48
+ });
49
+ continue;
50
+ }
51
+ steps.push({
52
+ name: displayName,
53
+ status: "would-create",
54
+ category: "skills",
55
+ filePath: targetPath,
56
+ content,
57
+ });
58
+ }
59
+ return steps;
60
+ }
@@ -0,0 +1,23 @@
1
+ import type { InitStep } from "../../../types/index.js";
2
+ /**
3
+ * Return planning steps for brain vault scaffolding and Obsidian MCP wiring.
4
+ *
5
+ * The function signature requires a resolved `brainPath` — the caller (agent)
6
+ * guarantees a path is provided before calling. Returns four `InitStep` items:
7
+ *
8
+ * 1. Vault scaffolding (category `"brain"`): `exists` if vault is already
9
+ * populated, `would-create` with the directories list as JSON content.
10
+ * 2. Playbook hub (category `"brain"`): `exists` if `coding-playbook/coding-playbook.md`
11
+ * is present, `would-create` with the five-section Markdown template when absent.
12
+ * Idempotency is per-file — checked independently of the vault-level step.
13
+ * 3. Vault CLAUDE.md (category `"brain"`): `exists` if `CLAUDE.md` is present at the
14
+ * vault root, `would-create` with the navigation guide template when absent.
15
+ * Idempotency is per-file — checked independently of the vault-level step.
16
+ * 4. Obsidian MCP entry (category `"mcp"`): `exists` if the obsidian key is
17
+ * already in the config, `would-create` with a `McpPrescription`.
18
+ * If the config file is malformed JSON, returns `would-create` with
19
+ * `configMalformed: true`.
20
+ *
21
+ * No step writes to disk — this helper is a planner only.
22
+ */
23
+ export default function provisionBrain(brainPath: string, mcpConfigPath: string): Promise<InitStep[]>;