robrain 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.
Files changed (53) hide show
  1. package/dist/commands/explain.d.ts +7 -0
  2. package/dist/commands/explain.d.ts.map +1 -0
  3. package/dist/commands/explain.js +145 -0
  4. package/dist/commands/explain.js.map +1 -0
  5. package/dist/commands/init-project.d.ts +6 -0
  6. package/dist/commands/init-project.d.ts.map +1 -0
  7. package/dist/commands/init-project.js +120 -0
  8. package/dist/commands/init-project.js.map +1 -0
  9. package/dist/commands/inject.d.ts +10 -0
  10. package/dist/commands/inject.d.ts.map +1 -0
  11. package/dist/commands/inject.js +123 -0
  12. package/dist/commands/inject.js.map +1 -0
  13. package/dist/commands/install.d.ts +11 -0
  14. package/dist/commands/install.d.ts.map +1 -0
  15. package/dist/commands/install.js +305 -0
  16. package/dist/commands/install.js.map +1 -0
  17. package/dist/commands/review.d.ts +9 -0
  18. package/dist/commands/review.d.ts.map +1 -0
  19. package/dist/commands/review.js +299 -0
  20. package/dist/commands/review.js.map +1 -0
  21. package/dist/commands/status.d.ts +9 -0
  22. package/dist/commands/status.d.ts.map +1 -0
  23. package/dist/commands/status.js +126 -0
  24. package/dist/commands/status.js.map +1 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +135 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/lib/auth.d.ts +21 -0
  30. package/dist/lib/auth.d.ts.map +1 -0
  31. package/dist/lib/auth.js +73 -0
  32. package/dist/lib/auth.js.map +1 -0
  33. package/dist/lib/config.d.ts +22 -0
  34. package/dist/lib/config.d.ts.map +1 -0
  35. package/dist/lib/config.js +49 -0
  36. package/dist/lib/config.js.map +1 -0
  37. package/dist/lib/editor.d.ts +25 -0
  38. package/dist/lib/editor.d.ts.map +1 -0
  39. package/dist/lib/editor.js +195 -0
  40. package/dist/lib/editor.js.map +1 -0
  41. package/dist/lib/load-env.d.ts +3 -0
  42. package/dist/lib/load-env.d.ts.map +1 -0
  43. package/dist/lib/load-env.js +29 -0
  44. package/dist/lib/load-env.js.map +1 -0
  45. package/dist/lib/mcp-bundle.d.ts +14 -0
  46. package/dist/lib/mcp-bundle.d.ts.map +1 -0
  47. package/dist/lib/mcp-bundle.js +42 -0
  48. package/dist/lib/mcp-bundle.js.map +1 -0
  49. package/dist/lib/project.d.ts +20 -0
  50. package/dist/lib/project.d.ts.map +1 -0
  51. package/dist/lib/project.js +201 -0
  52. package/dist/lib/project.js.map +1 -0
  53. package/package.json +39 -0
@@ -0,0 +1,195 @@
1
+ // src/lib/editor.ts
2
+ // ─────────────────────────────────────────────────────────────
3
+ // Detects which AI coding editors are installed and writes
4
+ // the appropriate MCP server configuration for each.
5
+ // Supported: Claude Code, Cursor, GitHub Copilot (VS Code)
6
+ // ─────────────────────────────────────────────────────────────
7
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
8
+ import { homedir } from 'os';
9
+ import { join, dirname } from 'path';
10
+ // ── Detection ──────────────────────────────────────────────────
11
+ export function detectEditors() {
12
+ const found = [];
13
+ const home = homedir();
14
+ // Claude Code — user-scope config lives in ~/.claude.json
15
+ // (not ~/.claude/mcp.json — that path is unread by Claude Code)
16
+ const claudeJson = join(home, '.claude.json');
17
+ const claudeDir = join(home, '.claude');
18
+ if (existsSync(claudeJson) || existsSync(claudeDir)) {
19
+ found.push({ editor: 'claude-code', configPath: claudeJson, label: 'Claude Code' });
20
+ }
21
+ // Cursor — ~/.cursor/mcp.json
22
+ const cursorPath = join(home, '.cursor', 'mcp.json');
23
+ const cursorDir = join(home, '.cursor');
24
+ if (existsSync(cursorDir) || existsSync(cursorPath)) {
25
+ found.push({ editor: 'cursor', configPath: cursorPath, label: 'Cursor' });
26
+ }
27
+ // VS Code + Copilot — check for .vscode in common locations
28
+ // Copilot MCP config lives in VS Code user settings dir
29
+ const vscodeSettings = getVSCodeSettingsPath();
30
+ if (vscodeSettings) {
31
+ found.push({ editor: 'copilot', configPath: vscodeSettings, label: 'GitHub Copilot (VS Code)' });
32
+ }
33
+ return found;
34
+ }
35
+ function getVSCodeSettingsPath() {
36
+ const home = homedir();
37
+ const candidates = [
38
+ join(home, '.vscode'),
39
+ join(home, 'Library', 'Application Support', 'Code', 'User'), // macOS
40
+ join(home, '.config', 'Code', 'User'), // Linux
41
+ join(home, 'AppData', 'Roaming', 'Code', 'User'), // Windows
42
+ ];
43
+ for (const p of candidates) {
44
+ if (existsSync(p)) {
45
+ return join(p, 'mcp.json');
46
+ }
47
+ }
48
+ return null;
49
+ }
50
+ export function writeMcpConfig(configPath, opts) {
51
+ // Read existing config if present.
52
+ // Refuse to proceed on parse failure: configPath may be a shared file (e.g. ~/.claude.json
53
+ // contains theme, projects, history) — overwriting it with `{ mcpServers: ... }` would
54
+ // destroy unrelated user settings.
55
+ let existing = {};
56
+ if (existsSync(configPath)) {
57
+ const raw = readFileSync(configPath, 'utf8');
58
+ try {
59
+ existing = JSON.parse(raw);
60
+ }
61
+ catch {
62
+ throw new Error(`Refusing to overwrite ${configPath}: file exists but is not valid JSON. ` +
63
+ `Fix or remove it manually, then re-run robrain install.`);
64
+ }
65
+ }
66
+ const mcpServers = existing.mcpServers ?? {};
67
+ const includeControl = opts.includeControl ?? true;
68
+ // Add / overwrite sensing (always)
69
+ mcpServers['robrain-sensing'] = {
70
+ command: 'node',
71
+ args: [opts.sensingMcpPath],
72
+ env: {
73
+ ANTHROPIC_API_KEY: opts.anthropicKey,
74
+ EMBEDDING_PROVIDER: opts.embeddingProvider,
75
+ ...(opts.embeddingProvider === 'openai' && { OPENAI_API_KEY: opts.embeddingKey }),
76
+ ...(opts.embeddingProvider === 'voyage' && { VOYAGE_API_KEY: opts.embeddingKey }),
77
+ ...(opts.embeddingProvider === 'cohere' && { COHERE_API_KEY: opts.embeddingKey }),
78
+ PERCEPTION_API_URL: opts.perceptionUrl,
79
+ PERCEPTION_API_KEY: opts.perceptionKey,
80
+ },
81
+ };
82
+ if (includeControl) {
83
+ mcpServers['robrain-control'] = {
84
+ command: 'node',
85
+ args: [opts.controlMcpPath],
86
+ env: {
87
+ PLANNING_API_URL: opts.planningUrl,
88
+ PLANNING_API_KEY: opts.planningKey,
89
+ PERCEPTION_API_URL: opts.perceptionUrl,
90
+ PERCEPTION_API_KEY: opts.perceptionKey,
91
+ },
92
+ };
93
+ }
94
+ else {
95
+ delete mcpServers['robrain-control'];
96
+ }
97
+ const updated = { ...existing, mcpServers };
98
+ // Ensure parent directory exists
99
+ const dir = dirname(configPath);
100
+ if (!existsSync(dir))
101
+ mkdirSync(dir, { recursive: true });
102
+ writeFileSync(configPath, JSON.stringify(updated, null, 2), 'utf8');
103
+ }
104
+ // ── RoBrain instruction text (CLAUDE.md + Cursor rule) ───────
105
+ const ROBRAIN_MARKER_START = '<!-- robrain -->';
106
+ const ROBRAIN_MARKER_END = '<!-- /robrain -->';
107
+ /** Shared body for CLAUDE.md and `.cursor/rules/robrain.mdc` (keep in sync). */
108
+ function roBrainInstructionsMarkdown(projectId) {
109
+ return `## RoBrain — Context Management
110
+
111
+ This project uses RoBrain for persistent institutional memory across sessions.
112
+ Call these tools as instructed to maintain causal memory of decisions.
113
+
114
+ ### Session start (every session, first thing)
115
+ \`\`\`
116
+ sensing_start_session(project_id="${projectId}", session_id="<ISO-timestamp>-<4-random-chars>", working_dir="<cwd>")
117
+ control_get_session_context(project_id="${projectId}", session_id="<same-id>")
118
+ \`\`\`
119
+ Inject the always_on_summary returned by control_get_session_context into your context.
120
+
121
+ ### After every response
122
+ \`\`\`
123
+ sensing_record_turn(session_id=..., sequence=<n>, user_message=..., claude_reply=..., files_touched=[...], injected_memory_ids=[...])
124
+ \`\`\`
125
+ If topic_shift=true is returned, immediately call:
126
+ \`\`\`
127
+ control_inject_context(project_id="${projectId}", session_id=..., task_description=..., files_in_scope=[...])
128
+ \`\`\`
129
+
130
+ ### When you need deeper context
131
+ \`\`\`
132
+ control_get_context(project_id="${projectId}", session_id=..., query=..., files_relevant=[...])
133
+ \`\`\`
134
+
135
+ ### When prior context is wrong or outdated
136
+ \`\`\`
137
+ control_record_correction(session_id=..., decision_id=..., source="user_correction"|"claude_disagreement", invalidate=true)
138
+ \`\`\`
139
+
140
+ ### When user adds a rule
141
+ \`\`\`
142
+ control_add_rule(project_id="${projectId}", rule="...", type="always_include"|"always_exclude"|"preference")
143
+ \`\`\`
144
+
145
+ ### Session end (last thing)
146
+ \`\`\`
147
+ sensing_end_session(session_id=..., summary="one sentence: what was accomplished")
148
+ control_end_session(project_id="${projectId}", session_id=...)
149
+ \`\`\`
150
+
151
+ ### Acknowledgement rule
152
+ When injected context contains a question marked ⚠, you must explicitly state
153
+ whether the constraint applies to the current task before proceeding.
154
+ `;
155
+ }
156
+ function roBrainMarkedBlock(projectId) {
157
+ return `${ROBRAIN_MARKER_START}
158
+ ${roBrainInstructionsMarkdown(projectId)}${ROBRAIN_MARKER_END}
159
+ `;
160
+ }
161
+ // ── CLAUDE.md writer ───────────────────────────────────────────
162
+ export function writeClaudeMd(projectRoot, projectId) {
163
+ const claudeMdPath = join(projectRoot, 'CLAUDE.md');
164
+ // If CLAUDE.md already exists, append the RoBrain block
165
+ let existing = '';
166
+ if (existsSync(claudeMdPath)) {
167
+ existing = readFileSync(claudeMdPath, 'utf8');
168
+ // Don't double-write if already configured
169
+ if (existing.includes(ROBRAIN_MARKER_START))
170
+ return;
171
+ existing = existing.trimEnd() + '\n\n';
172
+ }
173
+ writeFileSync(claudeMdPath, existing + roBrainMarkedBlock(projectId), 'utf8');
174
+ }
175
+ /** Writes `.cursor/rules/robrain.mdc` when Cursor is used; skips if RoBrain block already present. Returns true if a new file was written. */
176
+ export function writeCursorRoBrainRule(projectRoot, projectId) {
177
+ const rulePath = join(projectRoot, '.cursor', 'rules', 'robrain.mdc');
178
+ if (existsSync(rulePath)) {
179
+ const existing = readFileSync(rulePath, 'utf8');
180
+ if (existing.includes(ROBRAIN_MARKER_START))
181
+ return false;
182
+ }
183
+ const dir = dirname(rulePath);
184
+ if (!existsSync(dir))
185
+ mkdirSync(dir, { recursive: true });
186
+ const content = `---
187
+ description: RoBrain MCP — session lifecycle and context tools
188
+ alwaysApply: true
189
+ ---
190
+
191
+ ${roBrainMarkedBlock(projectId)}`;
192
+ writeFileSync(rulePath, content, 'utf8');
193
+ return true;
194
+ }
195
+ //# sourceMappingURL=editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/lib/editor.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,gEAAgE;AAChE,2DAA2D;AAC3D,qDAAqD;AACrD,2DAA2D;AAC3D,gEAAgE;AAEhE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAA;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAUpC,kEAAkE;AAElE,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAqB,EAAE,CAAA;IAClC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IAEtB,0DAA0D;IAC1D,gEAAgE;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;IAC7C,MAAM,SAAS,GAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACxC,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAA;IACrF,CAAC;IAED,8BAA8B;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;IACpD,MAAM,SAAS,GAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IACxC,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC3E,CAAC;IAED,4DAA4D;IAC5D,wDAAwD;IACxD,MAAM,cAAc,GAAG,qBAAqB,EAAE,CAAA;IAC9C,IAAI,cAAc,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAA;IAClG,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,qBAAqB;IAC5B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC;QACrB,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,CAAC,EAAG,QAAQ;QACvE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAA2B,QAAQ;QACxE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAe,UAAU;KAC1E,CAAA;IACD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAkBD,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAE,IAAqB;IACtE,mCAAmC;IACnC,2FAA2F;IAC3F,uFAAuF;IACvF,mCAAmC;IACnC,IAAI,QAAQ,GAA4B,EAAE,CAAA;IAC1C,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;QAC5C,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAA;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,yBAAyB,UAAU,uCAAuC;gBAC1E,yDAAyD,CAC1D,CAAA;QACH,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAI,QAAQ,CAAC,UAAsC,IAAI,EAAE,CAAA;IAEzE,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAA;IAElD,mCAAmC;IACnC,UAAU,CAAC,iBAAiB,CAAC,GAAG;QAC9B,OAAO,EAAE,MAAM;QACf,IAAI,EAAK,CAAC,IAAI,CAAC,cAAc,CAAC;QAC9B,GAAG,EAAE;YACH,iBAAiB,EAAG,IAAI,CAAC,YAAY;YACrC,kBAAkB,EAAE,IAAI,CAAC,iBAAiB;YAC1C,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,QAAQ,IAAK,EAAE,cAAc,EAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACnF,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,QAAQ,IAAK,EAAE,cAAc,EAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACnF,GAAG,CAAC,IAAI,CAAC,iBAAiB,KAAK,QAAQ,IAAK,EAAE,cAAc,EAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACnF,kBAAkB,EAAE,IAAI,CAAC,aAAa;YACtC,kBAAkB,EAAE,IAAI,CAAC,aAAa;SACvC;KACF,CAAA;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,UAAU,CAAC,iBAAiB,CAAC,GAAG;YAC9B,OAAO,EAAE,MAAM;YACf,IAAI,EAAK,CAAC,IAAI,CAAC,cAAc,CAAC;YAC9B,GAAG,EAAE;gBACH,gBAAgB,EAAI,IAAI,CAAC,WAAW;gBACpC,gBAAgB,EAAI,IAAI,CAAC,WAAW;gBACpC,kBAAkB,EAAE,IAAI,CAAC,aAAa;gBACtC,kBAAkB,EAAE,IAAI,CAAC,aAAa;aACvC;SACF,CAAA;IACH,CAAC;SAAM,CAAC;QACN,OAAO,UAAU,CAAC,iBAAiB,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,UAAU,EAAE,CAAA;IAE3C,iCAAiC;IACjC,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEzD,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AACrE,CAAC;AAED,gEAAgE;AAEhE,MAAM,oBAAoB,GAAG,kBAAkB,CAAA;AAC/C,MAAM,kBAAkB,GAAK,mBAAmB,CAAA;AAEhD,gFAAgF;AAChF,SAAS,2BAA2B,CAAC,SAAiB;IACpD,OAAO;;;;;;;oCAO2B,SAAS;0CACH,SAAS;;;;;;;;;;qCAUd,SAAS;;;;;kCAKZ,SAAS;;;;;;;;;;+BAUZ,SAAS;;;;;;kCAMN,SAAS;;;;;;CAM1C,CAAA;AACD,CAAC;AAED,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,OAAO,GAAG,oBAAoB;EAC9B,2BAA2B,CAAC,SAAS,CAAC,GAAG,kBAAkB;CAC5D,CAAA;AACD,CAAC;AAED,kEAAkE;AAElE,MAAM,UAAU,aAAa,CAAC,WAAmB,EAAE,SAAiB;IAClE,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;IAEnD,wDAAwD;IACxD,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,QAAQ,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;QAC7C,2CAA2C;QAC3C,IAAI,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAAE,OAAM;QACnD,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,MAAM,CAAA;IACxC,CAAC;IAED,aAAa,CAAC,YAAY,EAAE,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAA;AAC/E,CAAC;AAED,8IAA8I;AAC9I,MAAM,UAAU,sBAAsB,CAAC,WAAmB,EAAE,SAAiB;IAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;IAErE,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC/C,IAAI,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAAE,OAAO,KAAK,CAAA;IAC3D,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEzD,MAAM,OAAO,GAAG;;;;;EAKhB,kBAAkB,CAAC,SAAS,CAAC,EAAE,CAAA;IAE/B,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IACxC,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Merge `.env` values into `process.env` for install prompts and MCP config. */
2
+ export declare function loadInstallEnv(repoRoot?: string): void;
3
+ //# sourceMappingURL=load-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-env.d.ts","sourceRoot":"","sources":["../../src/lib/load-env.ts"],"names":[],"mappings":"AAuBA,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAMtD"}
@@ -0,0 +1,29 @@
1
+ // Load repo-root `.env` for `robrain install` without overriding the shell environment.
2
+ // ─────────────────────────────────────────────────────────────
3
+ import { config } from 'dotenv';
4
+ import { existsSync } from 'fs';
5
+ import { join } from 'path';
6
+ const COMPOSE_MARKER = join('docker', 'docker-compose.yml');
7
+ /** Paths checked in order; later files do not override earlier vars (override: false). */
8
+ function candidateEnvPaths(repoRoot) {
9
+ const paths = [];
10
+ if (repoRoot) {
11
+ paths.push(join(repoRoot, '.env'));
12
+ }
13
+ const cwd = process.cwd();
14
+ const cwdEnv = join(cwd, '.env');
15
+ if (existsSync(join(cwd, COMPOSE_MARKER)) && existsSync(cwdEnv)) {
16
+ if (!paths.includes(cwdEnv))
17
+ paths.push(cwdEnv);
18
+ }
19
+ return paths;
20
+ }
21
+ /** Merge `.env` values into `process.env` for install prompts and MCP config. */
22
+ export function loadInstallEnv(repoRoot) {
23
+ for (const path of candidateEnvPaths(repoRoot)) {
24
+ if (existsSync(path)) {
25
+ config({ path, override: false });
26
+ }
27
+ }
28
+ }
29
+ //# sourceMappingURL=load-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-env.js","sourceRoot":"","sources":["../../src/lib/load-env.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,gEAAgE;AAEhE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,UAAU,EAAE,MAA6B,IAAI,CAAA;AACtD,OAAO,EAAE,IAAI,EAAE,MAAmC,MAAM,CAAA;AAExD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAA;AAE3D,0FAA0F;AAC1F,SAAS,iBAAiB,CAAC,QAAiB;IAC1C,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;IACpC,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,QAAiB;IAC9C,KAAK,MAAM,IAAI,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/C,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ export declare class McpBundleError extends Error {
2
+ name: string;
3
+ }
4
+ /** True when ~/.robrain/mcp/sensing/dist/index.js exists and is readable. */
5
+ export declare function sensingBundleReady(robrainMcpDir: string): boolean;
6
+ /** True when a Control MCP entrypoint exists (cloud installs only; not in OSS repo). */
7
+ export declare function controlBundleReady(robrainMcpDir: string): boolean;
8
+ /**
9
+ * Ensure ~/.robrain/mcp/sensing points at a built @context-system/sensing-mcp package.
10
+ * Uses a directory symlink on macOS/Linux (preserves pnpm workspace node_modules).
11
+ * On Windows, performs a recursive copy (may require building from the same machine).
12
+ */
13
+ export declare function ensureSensingMcpBundle(repoRoot: string, robrainMcpDir: string): void;
14
+ //# sourceMappingURL=mcp-bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-bundle.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-bundle.ts"],"names":[],"mappings":"AAOA,qBAAa,cAAe,SAAQ,KAAK;IAC9B,IAAI,SAAmB;CACjC;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAuBpF"}
@@ -0,0 +1,42 @@
1
+ // packages/cli/src/lib/mcp-bundle.ts
2
+ // Copy or symlink built MCP packages into ~/.robrain/mcp so editor configs resolve.
3
+ import { cpSync, existsSync, mkdirSync, rmSync, symlinkSync } from 'fs';
4
+ import { platform } from 'os';
5
+ import { join } from 'path';
6
+ export class McpBundleError extends Error {
7
+ name = 'McpBundleError';
8
+ }
9
+ /** True when ~/.robrain/mcp/sensing/dist/index.js exists and is readable. */
10
+ export function sensingBundleReady(robrainMcpDir) {
11
+ return existsSync(join(robrainMcpDir, 'sensing', 'dist', 'index.js'));
12
+ }
13
+ /** True when a Control MCP entrypoint exists (cloud installs only; not in OSS repo). */
14
+ export function controlBundleReady(robrainMcpDir) {
15
+ return existsSync(join(robrainMcpDir, 'control', 'dist', 'index.js'));
16
+ }
17
+ /**
18
+ * Ensure ~/.robrain/mcp/sensing points at a built @context-system/sensing-mcp package.
19
+ * Uses a directory symlink on macOS/Linux (preserves pnpm workspace node_modules).
20
+ * On Windows, performs a recursive copy (may require building from the same machine).
21
+ */
22
+ export function ensureSensingMcpBundle(repoRoot, robrainMcpDir) {
23
+ if (sensingBundleReady(robrainMcpDir))
24
+ return;
25
+ const src = join(repoRoot, 'packages', 'sensing-mcp');
26
+ const srcEntry = join(src, 'dist', 'index.js');
27
+ if (!existsSync(srcEntry)) {
28
+ throw new McpBundleError(`sensing-mcp is not built (missing ${srcEntry}). From the repo root run: pnpm install && pnpm build`);
29
+ }
30
+ mkdirSync(robrainMcpDir, { recursive: true });
31
+ const dest = join(robrainMcpDir, 'sensing');
32
+ if (existsSync(dest)) {
33
+ rmSync(dest, { recursive: true, force: true });
34
+ }
35
+ if (platform() === 'win32') {
36
+ cpSync(src, dest, { recursive: true });
37
+ }
38
+ else {
39
+ symlinkSync(src, dest, 'dir');
40
+ }
41
+ }
42
+ //# sourceMappingURL=mcp-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-bundle.js","sourceRoot":"","sources":["../../src/lib/mcp-bundle.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,oFAAoF;AAEpF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,IAAI,CAAA;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,GAAG,gBAAgB,CAAA;CACjC;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,aAAqB;IACtD,OAAO,UAAU,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAA;AACvE,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,kBAAkB,CAAC,aAAqB;IACtD,OAAO,UAAU,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAA;AACvE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAE,aAAqB;IAC5E,IAAI,kBAAkB,CAAC,aAAa,CAAC;QAAE,OAAM;IAE7C,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;IAC9C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,cAAc,CACtB,qCAAqC,QAAQ,uDAAuD,CACrG,CAAA;IACH,CAAC;IAED,SAAS,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAA;IAE3C,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAChD,CAAC;IAED,IAAI,QAAQ,EAAE,KAAK,OAAO,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;SAAM,CAAC;QACN,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface ProjectInfo {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ stack: string[];
6
+ gitLog: string;
7
+ mission: string;
8
+ }
9
+ /** Derive a stable project ID from the working directory path */
10
+ export declare function deriveProjectId(cwd: string): string;
11
+ /** Collect all available context from the project root */
12
+ export declare function gatherProjectInfo(cwd: string): ProjectInfo;
13
+ /** Format project info as context string for Haiku warm-start call */
14
+ export declare function buildInitContext(info: ProjectInfo): string;
15
+ /** Call Perception to register project and seed warm-start summary */
16
+ export declare function seedProjectMemory(perceptionUrl: string, perceptionKey: string, info: ProjectInfo): Promise<{
17
+ ok: boolean;
18
+ decisionsWritten: number;
19
+ }>;
20
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/lib/project.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAW,MAAM,CAAA;IACnB,IAAI,EAAS,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAQ,MAAM,EAAE,CAAA;IACrB,MAAM,EAAO,MAAM,CAAA;IACnB,OAAO,EAAM,MAAM,CAAA;CACpB;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAoD1D;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAS1D;AAED,sEAAsE;AACtE,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC,CAwIpD"}
@@ -0,0 +1,201 @@
1
+ // src/lib/project.ts
2
+ // ─────────────────────────────────────────────────────────────
3
+ // Handles project initialization — warm-starts the memory store
4
+ // from existing codebase context (package.json, README, git log,
5
+ // CLAUDE.md) so session 1 starts with knowledge rather than blank.
6
+ // ─────────────────────────────────────────────────────────────
7
+ import { existsSync, readFileSync } from 'fs';
8
+ import { join, basename } from 'path';
9
+ import { execSync } from 'child_process';
10
+ import { createHash } from 'crypto';
11
+ /** Derive a stable project ID from the working directory path */
12
+ export function deriveProjectId(cwd) {
13
+ return createHash('sha256').update(cwd).digest('hex').slice(0, 12);
14
+ }
15
+ /** Collect all available context from the project root */
16
+ export function gatherProjectInfo(cwd) {
17
+ const id = deriveProjectId(cwd);
18
+ let name = basename(cwd);
19
+ let desc = '';
20
+ let stack = [];
21
+ // package.json
22
+ const pkgPath = join(cwd, 'package.json');
23
+ if (existsSync(pkgPath)) {
24
+ try {
25
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
26
+ if (pkg.name)
27
+ name = pkg.name;
28
+ if (pkg.description)
29
+ desc = pkg.description;
30
+ stack = Object.keys({
31
+ ...pkg.dependencies,
32
+ ...pkg.devDependencies,
33
+ }).slice(0, 20); // top 20 deps as stack signal
34
+ }
35
+ catch { /* ignore */ }
36
+ }
37
+ // README excerpt (first 500 chars)
38
+ const readmePaths = ['README.md', 'readme.md', 'README.txt', 'README'];
39
+ let readme = '';
40
+ for (const rp of readmePaths) {
41
+ const full = join(cwd, rp);
42
+ if (existsSync(full)) {
43
+ readme = readFileSync(full, 'utf8').slice(0, 500);
44
+ break;
45
+ }
46
+ }
47
+ if (!desc && readme) {
48
+ desc = readme.replace(/^#+\s*/gm, '').replace(/\n+/g, ' ').slice(0, 200);
49
+ }
50
+ // Git log — last 20 commits
51
+ let gitLog = '';
52
+ try {
53
+ gitLog = execSync('git log --oneline -20', { cwd, stdio: ['ignore', 'pipe', 'ignore'] })
54
+ .toString().trim();
55
+ }
56
+ catch { /* not a git repo */ }
57
+ // Synthesise mission from available info
58
+ const mission = desc
59
+ ? desc.slice(0, 120)
60
+ : `${name} — project context being built from sessions`;
61
+ return { id, name, description: desc, stack, gitLog, mission };
62
+ }
63
+ /** Format project info as context string for Haiku warm-start call */
64
+ export function buildInitContext(info) {
65
+ const parts = [];
66
+ parts.push(`Project: ${info.name}`);
67
+ if (info.description)
68
+ parts.push(`Description: ${info.description}`);
69
+ if (info.stack.length)
70
+ parts.push(`Stack: ${info.stack.join(', ')}`);
71
+ if (info.gitLog)
72
+ parts.push(`Recent commits:\n${info.gitLog}`);
73
+ return parts.join('\n\n');
74
+ }
75
+ /** Call Perception to register project and seed warm-start summary */
76
+ export async function seedProjectMemory(perceptionUrl, perceptionKey, info) {
77
+ try {
78
+ // 1. Register the project
79
+ await fetch(`${perceptionUrl}/projects`, {
80
+ method: 'POST',
81
+ headers: {
82
+ 'Content-Type': 'application/json',
83
+ ...(perceptionKey ? { 'Authorization': `Bearer ${perceptionKey}` } : {}),
84
+ },
85
+ body: JSON.stringify({ id: info.id, name: info.name }),
86
+ });
87
+ // 2. Use Anthropic to infer architectural decisions from context
88
+ const anthropicKey = process.env.ANTHROPIC_API_KEY;
89
+ if (!anthropicKey) {
90
+ return { ok: true, decisionsWritten: 0 };
91
+ }
92
+ const context = buildInitContext(info);
93
+ const resp = await fetch('https://api.anthropic.com/v1/messages', {
94
+ method: 'POST',
95
+ headers: {
96
+ 'x-api-key': anthropicKey,
97
+ 'anthropic-version': '2023-06-01',
98
+ 'Content-Type': 'application/json',
99
+ },
100
+ body: JSON.stringify({
101
+ model: 'claude-haiku-4-5-20251001',
102
+ max_tokens: 800,
103
+ system: `You infer architectural decisions from project context for an AI memory system.
104
+ Output ONLY valid JSON: an array of decision objects.
105
+ Each object: {"decision": string, "rationale": string|null, "rejected": [], "confidence": number}
106
+ Infer 3-5 decisions visible from the tech stack and project description.
107
+ Examples: database choice, framework choice, architecture pattern, language choice.
108
+ Confidence 0.7 for inferred decisions. Keep rationale under 15 words.
109
+ If not enough context: output [].
110
+ No explanation outside the JSON.`,
111
+ messages: [{
112
+ role: 'user',
113
+ content: `Infer architectural decisions from this project context:\n\n${context}`,
114
+ }],
115
+ }),
116
+ });
117
+ if (!resp.ok)
118
+ return { ok: true, decisionsWritten: 0 };
119
+ const data = await resp.json();
120
+ const text = data.content.find(c => c.type === 'text')?.text ?? '[]';
121
+ let decisions = [];
122
+ try {
123
+ decisions = JSON.parse(text.trim());
124
+ if (!Array.isArray(decisions))
125
+ decisions = [];
126
+ }
127
+ catch {
128
+ decisions = [];
129
+ }
130
+ // 3. Seed a stub session for init decisions
131
+ const sessionId = `init-${info.id}-${Date.now()}`;
132
+ // Register stub session
133
+ await fetch(`${perceptionUrl}/signals`, {
134
+ method: 'POST',
135
+ headers: {
136
+ 'Content-Type': 'application/json',
137
+ ...(perceptionKey ? { 'Authorization': `Bearer ${perceptionKey}` } : {}),
138
+ 'X-Project-Id': info.id,
139
+ },
140
+ body: JSON.stringify({
141
+ signal: {
142
+ turn: {
143
+ session_id: sessionId,
144
+ sequence: 1,
145
+ user_message: 'Project initialization scan',
146
+ claude_reply: context,
147
+ files_touched: [],
148
+ timestamp: new Date().toISOString(),
149
+ },
150
+ decision_type: 'init',
151
+ confidence: 0.0, // won't pass confidence gate — just registers session
152
+ files_affected: [],
153
+ scope: 'team',
154
+ needs_classification: false,
155
+ },
156
+ }),
157
+ }).catch(() => { });
158
+ // Write each inferred decision
159
+ let written = 0;
160
+ for (const d of decisions.slice(0, 5)) {
161
+ if (!d.decision || d.confidence < 0.5)
162
+ continue;
163
+ const res = await fetch(`${perceptionUrl}/signals`, {
164
+ method: 'POST',
165
+ headers: {
166
+ 'Content-Type': 'application/json',
167
+ ...(perceptionKey ? { 'Authorization': `Bearer ${perceptionKey}` } : {}),
168
+ 'X-Project-Id': info.id,
169
+ },
170
+ body: JSON.stringify({
171
+ signal: {
172
+ turn: {
173
+ session_id: sessionId,
174
+ sequence: written + 2,
175
+ user_message: 'init-project scan',
176
+ claude_reply: `${d.decision}${d.rationale ? ` because ${d.rationale}` : ''}`,
177
+ files_touched: [],
178
+ timestamp: new Date().toISOString(),
179
+ },
180
+ decision_type: 'architectural',
181
+ confidence: d.confidence,
182
+ files_affected: [],
183
+ scope: 'team',
184
+ },
185
+ }),
186
+ });
187
+ if (res.ok)
188
+ written++;
189
+ }
190
+ // 4. Trigger summary regeneration
191
+ await fetch(`${perceptionUrl}/projects/${info.id}/regenerate-summary`, {
192
+ method: 'POST',
193
+ headers: perceptionKey ? { 'Authorization': `Bearer ${perceptionKey}` } : {},
194
+ }).catch(() => { });
195
+ return { ok: true, decisionsWritten: written };
196
+ }
197
+ catch {
198
+ return { ok: false, decisionsWritten: 0 };
199
+ }
200
+ }
201
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/lib/project.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "robrain",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "RoBrain CLI for installation, setup, and memory workflows",
6
+ "license": "Apache-2.0",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/roryplans/robrain.git"
10
+ },
11
+ "homepage": "https://github.com/roryplans/robrain#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/roryplans/robrain/issues"
14
+ },
15
+ "bin": { "robrain": "./dist/index.js" },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "dev": "tsc --watch",
25
+ "typecheck": "tsc --noEmit"
26
+ },
27
+ "dependencies": {
28
+ "dotenv": "^16.4.5",
29
+ "chalk": "^5.3.0",
30
+ "ora": "^8.0.1",
31
+ "prompts": "^2.4.2",
32
+ "commander": "^12.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "typescript": "^5.4.0",
36
+ "@types/node": "^20.0.0",
37
+ "@types/prompts": "^2.4.9"
38
+ }
39
+ }