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,7 @@
1
+ interface ExplainOptions {
2
+ why?: boolean;
3
+ copy?: boolean;
4
+ }
5
+ export declare function explainCommand(filePath: string, opts: ExplainOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=explain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":"AAqBA,UAAU,cAAc;IACtB,GAAG,CAAC,EAAG,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,IAAI,CAAC,CAkKf"}
@@ -0,0 +1,145 @@
1
+ // src/commands/explain.ts
2
+ // ─────────────────────────────────────────────────────────────
3
+ // npx robrain explain <file> [--why] [--copy]
4
+ //
5
+ // Answers "why does this code exist?" for any file.
6
+ // Queries the decision store for decisions made while
7
+ // that file was in scope, formatted as plain-language
8
+ // explanation rather than a raw context block.
9
+ //
10
+ // npx robrain explain src/store/cart.ts
11
+ // npx robrain explain src/store/cart.ts --why (full rationale + rejected)
12
+ // npx robrain explain src/api/ --why (directory — all files below)
13
+ // ─────────────────────────────────────────────────────────────
14
+ import chalk from 'chalk';
15
+ import ora from 'ora';
16
+ import { readConfig } from '../lib/config.js';
17
+ import { gatherProjectInfo } from '../lib/project.js';
18
+ import { cwd, exit } from 'process';
19
+ import { execSync } from 'child_process';
20
+ export async function explainCommand(filePath, opts) {
21
+ console.log();
22
+ const config = readConfig();
23
+ const info = gatherProjectInfo(cwd());
24
+ const percUrl = config.perceptionUrl ?? 'http://localhost:3001';
25
+ const percKey = config.perceptionKey ?? '';
26
+ // Normalise the file path — strip leading ./ if present
27
+ const normalisedPath = filePath.replace(/^\.\//, '');
28
+ const spinner = ora({ text: `Looking up decisions for ${normalisedPath}...`, color: 'green' }).start();
29
+ let decisions = [];
30
+ try {
31
+ // Search by file overlap + semantic query on the file path
32
+ // This catches decisions where the file was directly touched
33
+ // AND decisions where the file's module was discussed
34
+ const params = new URLSearchParams({
35
+ project_id: info.id,
36
+ files: normalisedPath,
37
+ query: normalisedPath, // semantic search on path as fallback
38
+ limit: '10',
39
+ all: 'true',
40
+ });
41
+ const res = await fetch(`${percUrl}/decisions?${params}`, {
42
+ headers: percKey ? { 'Authorization': `Bearer ${percKey}` } : {},
43
+ });
44
+ if (!res.ok) {
45
+ spinner.fail(`Could not reach Perception API (${res.status})`);
46
+ console.log(chalk.dim(` Make sure Perception is running: pnpm docker:up\n`));
47
+ exit(1);
48
+ }
49
+ const data = await res.json();
50
+ // Filter to decisions actually involving this file or path prefix
51
+ decisions = (data.decisions ?? []).filter(d => d.files_affected.some(f => f.includes(normalisedPath) || normalisedPath.includes(f)));
52
+ // If no file matches, fall back to semantic results
53
+ if (decisions.length === 0) {
54
+ decisions = data.decisions ?? [];
55
+ }
56
+ }
57
+ catch {
58
+ spinner.fail('Could not reach Perception API');
59
+ console.log(chalk.dim(`\n Make sure Perception is running: pnpm docker:up\n`));
60
+ exit(1);
61
+ }
62
+ spinner.stop();
63
+ if (decisions.length === 0) {
64
+ console.log(chalk.dim(` No decisions found for ${chalk.bold(normalisedPath)}\n`));
65
+ console.log(chalk.dim(' RoBrain only knows about files discussed in Claude Code sessions.'));
66
+ console.log(chalk.dim(' Run a session touching this file to start capturing decisions.\n'));
67
+ return;
68
+ }
69
+ // ── Build output ──────────────────────────────────────────
70
+ const lines = [];
71
+ console.log(chalk.bold(` ${normalisedPath}`));
72
+ console.log(chalk.dim(` ${decisions.length} decision${decisions.length === 1 ? '' : 's'} found\n`));
73
+ for (const d of decisions) {
74
+ const date = new Date(d.created_at).toLocaleDateString('en-US', {
75
+ month: 'short', day: 'numeric', year: 'numeric',
76
+ });
77
+ const isSuperseded = !!d.invalidated_at;
78
+ if (opts.why) {
79
+ // ── Deep format: full rationale + rejected ─────────────
80
+ if (isSuperseded) {
81
+ console.log(chalk.dim(` ${date} [superseded]`));
82
+ console.log(chalk.dim(` ${d.decision}`));
83
+ }
84
+ else {
85
+ console.log(chalk.dim(` ${date}`) + ` ${chalk.bold(d.decision)}`);
86
+ }
87
+ if (d.rationale) {
88
+ console.log(chalk.dim(` because: `) + (isSuperseded ? chalk.dim(d.rationale) : d.rationale));
89
+ }
90
+ if (d.rejected.length > 0) {
91
+ const vetoes = d.rejected
92
+ .map(r => `${chalk.dim(r.option)} ${chalk.dim(`(${r.reason})`)}`)
93
+ .join(', ');
94
+ console.log(chalk.dim(` rejected: `) + vetoes);
95
+ }
96
+ if (d.supersedes_id) {
97
+ console.log(chalk.dim(` ↩ replaces earlier decision`));
98
+ }
99
+ console.log();
100
+ // Build plain text for clipboard
101
+ const vetoStr = d.rejected.length > 0
102
+ ? ` Rejected: ${d.rejected.map(r => `${r.option} (${r.reason})`).join(', ')}.`
103
+ : '';
104
+ lines.push(`${date}: ${d.decision}${d.rationale ? ` — ${d.rationale}.` : ''}${vetoStr}`);
105
+ }
106
+ else {
107
+ // ── Short format: one-liner per decision ───────────────
108
+ const vetoes = d.rejected.map(r => `${r.option} (${r.reason})`).join(' over ');
109
+ const vetoStr = vetoes ? ` over ${vetoes}` : '';
110
+ const rationale = d.rationale ? ` — ${d.rationale}` : '';
111
+ const supersededLabel = isSuperseded ? chalk.dim(' [superseded]') : '';
112
+ const line = `• Chose ${d.decision}${vetoStr}${rationale} (${date})`;
113
+ if (isSuperseded) {
114
+ console.log(chalk.dim(` ${line}`) + supersededLabel);
115
+ }
116
+ else {
117
+ console.log(` ${line}`);
118
+ }
119
+ lines.push(line);
120
+ }
121
+ }
122
+ console.log();
123
+ // ── Copy to clipboard ──────────────────────────────────────
124
+ if (opts.copy) {
125
+ const output = [
126
+ `# Why does ${normalisedPath} exist?`,
127
+ ...lines,
128
+ ].join('\n');
129
+ try {
130
+ const cmd = process.platform === 'darwin' ? 'pbcopy'
131
+ : process.platform === 'win32' ? 'clip'
132
+ : 'xclip -selection clipboard';
133
+ execSync(cmd, { input: output });
134
+ console.log(chalk.green(' ✓ Copied to clipboard\n'));
135
+ }
136
+ catch {
137
+ console.log(chalk.yellow(' Could not copy automatically — copy the text above.\n'));
138
+ }
139
+ }
140
+ else {
141
+ console.log(chalk.dim(' Tip: add --why for full rationale and rejected alternatives'));
142
+ console.log(chalk.dim(' Tip: add --copy to copy this to clipboard\n'));
143
+ }
144
+ }
145
+ //# sourceMappingURL=explain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ interface InitProjectOptions {
2
+ projectId?: string;
3
+ }
4
+ export declare function initProjectCommand(opts: InitProjectOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=init-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-project.d.ts","sourceRoot":"","sources":["../../src/commands/init-project.ts"],"names":[],"mappings":"AAqBA,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuHhF"}
@@ -0,0 +1,120 @@
1
+ // src/commands/init-project.ts
2
+ // ─────────────────────────────────────────────────────────────
3
+ // robrain init-project [--project-id ID]
4
+ //
5
+ // Warm-starts the memory store from existing codebase context.
6
+ // Reads: package.json, README, git log, CLAUDE.md
7
+ // Writes: CLAUDE.md instructions, optional .cursor/rules/robrain.mdc,
8
+ // seeds 3-5 inferred decisions,
9
+ // triggers always-on summary generation.
10
+ //
11
+ // Run once per project, in the project root.
12
+ // ─────────────────────────────────────────────────────────────
13
+ import chalk from 'chalk';
14
+ import ora from 'ora';
15
+ import prompts from 'prompts';
16
+ import { cwd } from 'process';
17
+ import { readConfig, isAuthenticated } from '../lib/config.js';
18
+ import { gatherProjectInfo, seedProjectMemory } from '../lib/project.js';
19
+ import { detectEditors, writeClaudeMd, writeCursorRoBrainRule } from '../lib/editor.js';
20
+ export async function initProjectCommand(opts) {
21
+ console.log();
22
+ console.log(chalk.bold(' robrain init-project'));
23
+ console.log(chalk.dim(' Warm-starting memory from your codebase...\n'));
24
+ // ── Auth check ─────────────────────────────────────────────
25
+ if (!isAuthenticated()) {
26
+ console.log(chalk.red(' ✗ Not authenticated. Run: robrain install'));
27
+ process.exit(1);
28
+ }
29
+ const config = readConfig();
30
+ if (!config.perceptionUrl) {
31
+ console.log(chalk.red(' ✗ Perception URL not configured. Run: robrain install'));
32
+ process.exit(1);
33
+ }
34
+ // ── Gather project info ────────────────────────────────────
35
+ const spinner = ora({ text: 'Scanning project...', color: 'green' }).start();
36
+ const projectRoot = cwd();
37
+ const info = gatherProjectInfo(projectRoot);
38
+ spinner.text = `Detected: ${chalk.bold(info.name)}`;
39
+ await sleep(400); // brief pause so user sees the detection
40
+ spinner.succeed(`Project: ${chalk.bold(info.name)} ${chalk.dim(`(id: ${info.id})`)}`);
41
+ // Display what was found
42
+ console.log();
43
+ if (info.description) {
44
+ console.log(chalk.dim(' Description: ') + info.description.slice(0, 80));
45
+ }
46
+ if (info.stack.length > 0) {
47
+ console.log(chalk.dim(' Stack: ') + info.stack.slice(0, 8).join(', '));
48
+ }
49
+ if (info.gitLog) {
50
+ const commits = info.gitLog.split('\n').slice(0, 3);
51
+ console.log(chalk.dim(' Recent commits:'));
52
+ commits.forEach(c => console.log(chalk.dim(` ${c}`)));
53
+ }
54
+ console.log();
55
+ // ── Confirm ────────────────────────────────────────────────
56
+ const { confirm } = await prompts({
57
+ type: 'confirm',
58
+ name: 'confirm',
59
+ message: `Initialize memory for ${chalk.bold(info.name)}?`,
60
+ initial: true,
61
+ });
62
+ if (!confirm) {
63
+ console.log(chalk.dim('\n Cancelled.'));
64
+ process.exit(0);
65
+ }
66
+ // ── Write CLAUDE.md (+ Cursor rule if Cursor is installed) ─
67
+ const hasCursor = detectEditors().some(e => e.editor === 'cursor');
68
+ const mdSpinner = ora({
69
+ text: hasCursor
70
+ ? 'Writing editor instructions (CLAUDE.md + Cursor)...'
71
+ : 'Writing CLAUDE.md instructions...',
72
+ color: 'green',
73
+ }).start();
74
+ writeClaudeMd(projectRoot, info.id);
75
+ let cursorRuleApplied = false;
76
+ if (hasCursor) {
77
+ cursorRuleApplied = writeCursorRoBrainRule(projectRoot, info.id);
78
+ }
79
+ mdSpinner.succeed(hasCursor
80
+ ? 'Editor instructions updated (CLAUDE.md + Cursor rule)'
81
+ : 'CLAUDE.md updated with RoBrain instructions');
82
+ // ── Seed memory ────────────────────────────────────────────
83
+ const seedSpinner = ora({ text: 'Inferring architectural decisions from codebase...', color: 'green' }).start();
84
+ const perceptionKey = config.perceptionKey ?? '';
85
+ const result = await seedProjectMemory(config.perceptionUrl, perceptionKey, info);
86
+ if (result.ok && result.decisionsWritten > 0) {
87
+ seedSpinner.succeed(`Seeded ${result.decisionsWritten} inferred decisions`);
88
+ }
89
+ else if (result.ok) {
90
+ seedSpinner.succeed('Project registered (no decisions inferred — will build from sessions)');
91
+ }
92
+ else {
93
+ seedSpinner.warn('Could not seed decisions — Perception API unreachable. Memory will build from sessions.');
94
+ }
95
+ // ── Done ───────────────────────────────────────────────────
96
+ console.log();
97
+ console.log(chalk.green(' ✓ Project initialized\n'));
98
+ console.log(chalk.dim(' Project ID: ') + chalk.cyan(info.id));
99
+ console.log(chalk.dim(' CLAUDE.md: ') + chalk.dim('updated with RoBrain instructions'));
100
+ if (hasCursor) {
101
+ console.log(chalk.dim(' Cursor: ') +
102
+ chalk.dim(cursorRuleApplied
103
+ ? 'added .cursor/rules/robrain.mdc'
104
+ : 'RoBrain rule already present'));
105
+ }
106
+ console.log();
107
+ console.log(chalk.bold(' You\'re ready.'));
108
+ if (hasCursor) {
109
+ console.log(chalk.dim(' Open Claude Code or Cursor and start a session.'));
110
+ }
111
+ else {
112
+ console.log(chalk.dim(' Open Claude Code and start a session.'));
113
+ }
114
+ console.log(chalk.dim(' Session 2 will remember what happened in session 1.'));
115
+ console.log();
116
+ }
117
+ function sleep(ms) {
118
+ return new Promise(resolve => setTimeout(resolve, ms));
119
+ }
120
+ //# sourceMappingURL=init-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-project.js","sourceRoot":"","sources":["../../src/commands/init-project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ interface InjectOptions {
2
+ query?: string;
3
+ files?: string;
4
+ copy?: boolean;
5
+ limit?: number;
6
+ all?: boolean;
7
+ }
8
+ export declare function injectCommand(opts: InjectOptions): Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=inject.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject.d.ts","sourceRoot":"","sources":["../../src/commands/inject.ts"],"names":[],"mappings":"AAmBA,UAAU,aAAa;IACrB,KAAK,CAAC,EAAG,MAAM,CAAA;IACf,KAAK,CAAC,EAAG,MAAM,CAAA;IACf,IAAI,CAAC,EAAI,OAAO,CAAA;IAChB,KAAK,CAAC,EAAG,MAAM,CAAA;IACf,GAAG,CAAC,EAAK,OAAO,CAAA;CACjB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiItE"}
@@ -0,0 +1,123 @@
1
+ // packages/cli/src/commands/inject.ts
2
+ // ─────────────────────────────────────────────────────────────
3
+ // robrain inject [--query TEXT] [--files file1,file2] [--copy]
4
+ //
5
+ // Queries the local decision store and returns a formatted
6
+ // context string the developer can paste into Claude Code.
7
+ //
8
+ // This is the manual retrieval path for OSS self-hosted users.
9
+ // The Rory Plans cloud version does this automatically at every
10
+ // task boundary via the Control MCP — no paste needed.
11
+ // ─────────────────────────────────────────────────────────────
12
+ import chalk from 'chalk';
13
+ import ora from 'ora';
14
+ import { readConfig } from '../lib/config.js';
15
+ import { gatherProjectInfo } from '../lib/project.js';
16
+ import { cwd } from 'process';
17
+ import { execSync } from 'child_process';
18
+ export async function injectCommand(opts) {
19
+ console.log();
20
+ const config = readConfig();
21
+ const info = gatherProjectInfo(cwd());
22
+ // Determine perception URL — local self-hosted or Rory Plans
23
+ const percUrl = config.perceptionUrl ?? 'http://localhost:3001';
24
+ const percKey = config.perceptionKey ?? '';
25
+ // ── Build query ────────────────────────────────────────────
26
+ // If no query provided, use recent decisions
27
+ const query = opts.query;
28
+ const files = opts.files ? opts.files.split(',').map(f => f.trim()) : [];
29
+ const limit = opts.limit ?? 5;
30
+ const spinner = ora({ text: 'Fetching relevant decisions...', color: 'green' }).start();
31
+ let decisions = [];
32
+ try {
33
+ // Build query params
34
+ const params = new URLSearchParams({
35
+ project_id: info.id,
36
+ limit: String(limit),
37
+ });
38
+ if (query)
39
+ params.set('query', query);
40
+ if (!query)
41
+ params.set('recent', 'true');
42
+ const res = await fetch(`${percUrl}/decisions?${params}`, {
43
+ headers: percKey ? { 'Authorization': `Bearer ${percKey}` } : {},
44
+ });
45
+ if (!res.ok) {
46
+ spinner.fail(`Could not fetch decisions (${res.status}). Is Perception running?`);
47
+ console.log(chalk.dim(` Expected at: ${percUrl}`));
48
+ console.log(chalk.dim(' Start with: pnpm docker:up\n'));
49
+ process.exit(1);
50
+ }
51
+ const data = await res.json();
52
+ decisions = data.decisions ?? [];
53
+ // If files provided, boost file-overlapping decisions to top
54
+ if (files.length > 0) {
55
+ decisions.sort((a, b) => {
56
+ const aOverlap = a.files_affected.filter(f => files.some(fi => f.includes(fi))).length;
57
+ const bOverlap = b.files_affected.filter(f => files.some(fi => f.includes(fi))).length;
58
+ return bOverlap - aOverlap || (b.similarity ?? 0) - (a.similarity ?? 0);
59
+ });
60
+ }
61
+ }
62
+ catch (err) {
63
+ spinner.fail('Could not reach Perception API');
64
+ console.log(chalk.dim(`\n Make sure Perception is running: pnpm docker:up\n`));
65
+ process.exit(1);
66
+ }
67
+ spinner.stop();
68
+ if (decisions.length === 0) {
69
+ console.log(chalk.dim(` No decisions found for "${query ?? 'recent'}"\n`));
70
+ console.log(chalk.dim(' Run a Claude Code session first to capture decisions.\n'));
71
+ return;
72
+ }
73
+ // ── Format context string ──────────────────────────────────
74
+ const lines = [
75
+ `[RoBrain context — ${info.name}${query ? ` — "${query}"` : ' — recent decisions'}]`,
76
+ ];
77
+ for (const d of decisions) {
78
+ const date = new Date(d.created_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
79
+ const conf = d.confidence >= 0.9 ? 'high' : d.confidence >= 0.6 ? 'medium' : 'low';
80
+ const vetoes = (d.rejected ?? []).map(r => `${r.option} (${r.reason})`).join(' over ');
81
+ const vetoStr = vetoes ? ` over ${vetoes}` : '';
82
+ const rationale = d.rationale ? ` — ${d.rationale}` : '';
83
+ const supersedes = d.supersedes_id
84
+ ? ` [supersedes earlier decision]`
85
+ : '';
86
+ lines.push(`• Chose ${d.decision}${vetoStr}${rationale} [${date}, ${conf} confidence${supersedes}]`);
87
+ }
88
+ // Cloud upgrade note (for OSS users)
89
+ lines.push('');
90
+ lines.push('— Generated by RoBrain OSS. Upgrade to Rory Plans for automatic injection.');
91
+ const output = lines.join('\n');
92
+ // ── Display ────────────────────────────────────────────────
93
+ console.log(chalk.bold(` Context for: ${info.name}`));
94
+ console.log(chalk.dim(` ${decisions.length} decision${decisions.length === 1 ? '' : 's'} found\n`));
95
+ console.log(chalk.dim(' ─────────────────────────────────────'));
96
+ console.log();
97
+ console.log(output);
98
+ console.log();
99
+ console.log(chalk.dim(' ─────────────────────────────────────'));
100
+ console.log();
101
+ // ── Copy to clipboard ──────────────────────────────────────
102
+ if (opts.copy) {
103
+ try {
104
+ const cmd = process.platform === 'darwin' ? 'pbcopy'
105
+ : process.platform === 'win32' ? 'clip'
106
+ : 'xclip -selection clipboard';
107
+ execSync(cmd, { input: output });
108
+ console.log(chalk.green(' ✓ Copied to clipboard — paste into Claude Code\n'));
109
+ }
110
+ catch {
111
+ console.log(chalk.yellow(' Could not copy to clipboard automatically.'));
112
+ console.log(chalk.dim(' Copy the text above and paste it into Claude Code.\n'));
113
+ }
114
+ }
115
+ else {
116
+ console.log(chalk.dim(' Tip: add --copy to copy this directly to your clipboard'));
117
+ console.log(chalk.dim(' Tip: add --query "auth decisions" to search for specific context'));
118
+ console.log();
119
+ console.log(chalk.dim(' Want automatic injection without pasting?'));
120
+ console.log(chalk.dim(' → ') + chalk.cyan('roryplans.ai') + chalk.dim(' — Control MCP injects at every task boundary\n'));
121
+ }
122
+ }
123
+ //# sourceMappingURL=inject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject.js","sourceRoot":"","sources":["../../src/commands/inject.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ interface InstallOptions {
2
+ token?: string;
3
+ editor?: string;
4
+ selfHosted?: boolean;
5
+ perceptionUrl?: string;
6
+ /** Path to the robrain monorepo root — used to link/copy built sensing-mcp into ~/.robrain/mcp */
7
+ repoRoot?: string;
8
+ }
9
+ export declare function installCommand(opts: InstallOptions): Promise<void>;
10
+ export {};
11
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AA8BA,UAAU,cAAc;IACtB,KAAK,CAAC,EAAU,MAAM,CAAA;IACtB,MAAM,CAAC,EAAS,MAAM,CAAA;IACtB,UAAU,CAAC,EAAK,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kGAAkG;IAClG,QAAQ,CAAC,EAAO,MAAM,CAAA;CACvB;AA6BD,wBAAsB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAiMxE"}