copperhead 0.7.0 → 0.8.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 (79) hide show
  1. package/README.md +36 -4
  2. package/dist/agent/animate.js +76 -0
  3. package/dist/agent/animate.js.map +1 -0
  4. package/dist/agent/box.js +89 -0
  5. package/dist/agent/box.js.map +1 -0
  6. package/dist/agent/dock-renderer.js +173 -0
  7. package/dist/agent/dock-renderer.js.map +1 -0
  8. package/dist/agent/logo.js +21 -0
  9. package/dist/agent/logo.js.map +1 -0
  10. package/dist/agent/loop.js +15 -5
  11. package/dist/agent/loop.js.map +1 -1
  12. package/dist/agent/providers/claude-code.js +1 -212
  13. package/dist/agent/providers/claude-code.js.map +1 -1
  14. package/dist/agent/providers/cursor.js +317 -0
  15. package/dist/agent/providers/cursor.js.map +1 -0
  16. package/dist/agent/providers/tool-protocol.js +205 -0
  17. package/dist/agent/providers/tool-protocol.js.map +1 -0
  18. package/dist/agent/render.js +32 -15
  19. package/dist/agent/render.js.map +1 -1
  20. package/dist/agent/runmeta.js +4 -5
  21. package/dist/agent/runmeta.js.map +1 -1
  22. package/dist/agent/theme.js +84 -0
  23. package/dist/agent/theme.js.map +1 -0
  24. package/dist/cli.js +134 -13
  25. package/dist/cli.js.map +1 -1
  26. package/dist/commands/create.js +41 -32
  27. package/dist/commands/create.js.map +1 -1
  28. package/dist/commands/demo.js +146 -0
  29. package/dist/commands/demo.js.map +1 -0
  30. package/dist/commands/doctor.js +240 -0
  31. package/dist/commands/doctor.js.map +1 -0
  32. package/dist/commands/repl-inspect.js +342 -0
  33. package/dist/commands/repl-inspect.js.map +1 -0
  34. package/dist/commands/repl.js +618 -0
  35. package/dist/commands/repl.js.map +1 -0
  36. package/dist/config.js +5 -2
  37. package/dist/config.js.map +1 -1
  38. package/dist/kicad/cli.js +126 -6
  39. package/dist/kicad/cli.js.map +1 -1
  40. package/dist/util/cli-args.js +35 -0
  41. package/dist/util/cli-args.js.map +1 -0
  42. package/dist/util/dock.js +155 -0
  43. package/dist/util/dock.js.map +1 -0
  44. package/dist/util/git.js +129 -4
  45. package/dist/util/git.js.map +1 -1
  46. package/dist/util/live-prompt.js +542 -0
  47. package/dist/util/live-prompt.js.map +1 -0
  48. package/dist/util/paths.js +9 -0
  49. package/dist/util/paths.js.map +1 -1
  50. package/dist/util/select.js +172 -0
  51. package/dist/util/select.js.map +1 -0
  52. package/package.json +3 -2
  53. package/src/agent/animate.ts +90 -0
  54. package/src/agent/box.ts +99 -0
  55. package/src/agent/dock-renderer.ts +181 -0
  56. package/src/agent/logo.ts +23 -0
  57. package/src/agent/loop.ts +15 -5
  58. package/src/agent/providers/claude-code.ts +2 -216
  59. package/src/agent/providers/cursor.ts +364 -0
  60. package/src/agent/providers/tool-protocol.ts +212 -0
  61. package/src/agent/render.ts +33 -16
  62. package/src/agent/runmeta.ts +6 -7
  63. package/src/agent/theme.ts +91 -0
  64. package/src/cli.ts +139 -15
  65. package/src/commands/create.ts +81 -30
  66. package/src/commands/demo.ts +184 -0
  67. package/src/commands/doctor.ts +289 -0
  68. package/src/commands/repl-inspect.ts +353 -0
  69. package/src/commands/repl.ts +685 -0
  70. package/src/config.ts +6 -3
  71. package/src/kicad/cli.ts +132 -7
  72. package/src/layout/claude-ui-layout.md +72 -0
  73. package/src/layout/repl-ui-layout.md +139 -0
  74. package/src/util/cli-args.ts +42 -0
  75. package/src/util/dock.ts +161 -0
  76. package/src/util/git.ts +140 -4
  77. package/src/util/live-prompt.ts +595 -0
  78. package/src/util/paths.ts +10 -0
  79. package/src/util/select.ts +192 -0
@@ -0,0 +1,240 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { existsSync } from 'node:fs';
4
+ import path from 'node:path';
5
+ import { DEFAULTS, loadConfig, resolveModel } from '../config.js';
6
+ import { kicadCliVersion } from '../kicad/cli.js';
7
+ import { redactSecrets } from '../util/redact.js';
8
+ const execFileP = promisify(execFile);
9
+ function defaultDeps() {
10
+ return {
11
+ nodeVersion: process.version,
12
+ kicadVersion: kicadCliVersion,
13
+ // `git --version` prints "git version 2.34.1"; keep only the number, the
14
+ // report already labels the row "git".
15
+ gitVersion: async () => (await execFileP('git', ['--version'])).stdout.trim().replace(/^git version\s+/, ''),
16
+ env: process.env,
17
+ };
18
+ }
19
+ const MIN_NODE_MAJOR = 20; // package.json engines: ">=20"
20
+ function nodeCheck(version) {
21
+ const major = Number(version.replace(/^v/, '').split('.')[0]);
22
+ if (Number.isFinite(major) && major >= MIN_NODE_MAJOR) {
23
+ return { name: 'node', status: 'ok', detail: `${version} (>= ${MIN_NODE_MAJOR})` };
24
+ }
25
+ return {
26
+ name: 'node',
27
+ status: 'fail',
28
+ detail: `${version} (< ${MIN_NODE_MAJOR})`,
29
+ hint: `copperhead needs Node >= ${MIN_NODE_MAJOR}; upgrade Node.`,
30
+ };
31
+ }
32
+ async function kicadCheck(probe) {
33
+ try {
34
+ return { name: 'kicad-cli', status: 'ok', detail: await probe() };
35
+ }
36
+ catch {
37
+ return {
38
+ name: 'kicad-cli',
39
+ status: 'fail',
40
+ detail: 'not found on PATH',
41
+ hint: 'install KiCad >= 9 (bundles kicad-cli); ERC/DRC gates need it.',
42
+ };
43
+ }
44
+ }
45
+ async function gitCheck(probe) {
46
+ try {
47
+ return { name: 'git', status: 'ok', detail: await probe() };
48
+ }
49
+ catch {
50
+ return {
51
+ name: 'git',
52
+ status: 'fail',
53
+ detail: 'not found on PATH',
54
+ hint: 'install git; copperhead snapshots and commits its work.',
55
+ };
56
+ }
57
+ }
58
+ /**
59
+ * Map a resolved model to the credential its provider needs, mirroring
60
+ * makeProvider's prefix routing (agent/loop.ts). Presence-only: it checks that a
61
+ * required API key is set, never that it authenticates (that would need network).
62
+ * Saved-login providers (codex, claude-code) need no key and can't be verified
63
+ * offline, so they report `info` (which does not block `ok`).
64
+ */
65
+ export function checkCredential(model, env) {
66
+ // A pasted API key can end up as the model value (--model sk-..., a stray
67
+ // COPPERHEAD_MODEL); redact it before it reaches the report, same policy as
68
+ // transcripts (AC-4.1). Routing below still uses the raw value.
69
+ const shown = redactSecrets(model);
70
+ const savedLogin = {
71
+ codex: 'uses local Codex login',
72
+ 'claude-code': 'uses Claude Code login',
73
+ cursor: 'uses Cursor Agent CLI login',
74
+ };
75
+ for (const [prefix, how] of Object.entries(savedLogin)) {
76
+ if (model === prefix || model.startsWith(`${prefix}:`)) {
77
+ // makeProvider rejects an empty override; a real run would fail here.
78
+ if (model === `${prefix}:`) {
79
+ return {
80
+ name: 'provider',
81
+ status: 'fail',
82
+ detail: `${shown} -> ${prefix}: empty model override`,
83
+ hint: `use "${prefix}" or "${prefix}:<model-id>".`,
84
+ };
85
+ }
86
+ return {
87
+ name: 'provider',
88
+ status: 'info',
89
+ detail: `${shown} -> ${prefix}: ${how} (not verified offline)`,
90
+ };
91
+ }
92
+ }
93
+ if (model === 'claude' || model.startsWith('claude')) {
94
+ return env.ANTHROPIC_API_KEY
95
+ ? { name: 'provider', status: 'ok', detail: `${shown} -> anthropic: ANTHROPIC_API_KEY set` }
96
+ : {
97
+ name: 'provider',
98
+ status: 'fail',
99
+ detail: `${shown} -> anthropic: ANTHROPIC_API_KEY not set`,
100
+ hint: 'export ANTHROPIC_API_KEY=... (or use --model claude-code for saved login).',
101
+ };
102
+ }
103
+ return env.OPENAI_API_KEY
104
+ ? { name: 'provider', status: 'ok', detail: `${shown} -> openai: OPENAI_API_KEY set` }
105
+ : {
106
+ name: 'provider',
107
+ status: 'fail',
108
+ detail: `${shown} -> openai: OPENAI_API_KEY not set`,
109
+ hint: 'export OPENAI_API_KEY=... (or use --model codex for saved login).',
110
+ };
111
+ }
112
+ function providerCheck(flag, config, env) {
113
+ try {
114
+ const { model } = resolveModel(flag, config, env);
115
+ return checkCredential(model, env);
116
+ }
117
+ catch (err) {
118
+ // resolveModel throws only when nothing selects a model at all. Its message
119
+ // starts with "no model configured: " — already this check's detail line —
120
+ // so keep only the remedy part for the hint.
121
+ return {
122
+ name: 'provider',
123
+ status: 'fail',
124
+ detail: 'no model configured',
125
+ hint: err.message.replace(/^no model configured:\s*/, ''),
126
+ };
127
+ }
128
+ }
129
+ function projectCheck(config, repoRoot) {
130
+ const hasConfig = existsSync(path.join(repoRoot, '.copperhead', 'config.json'));
131
+ if (!hasConfig) {
132
+ return {
133
+ name: 'project',
134
+ status: 'info',
135
+ detail: 'no .copperhead/config.json (run `copperhead init` to scaffold)',
136
+ };
137
+ }
138
+ return {
139
+ name: 'project',
140
+ status: 'info',
141
+ detail: `schematic ${config.schematic ?? 'not wired'} · board ${config.board ?? 'not wired'}`,
142
+ };
143
+ }
144
+ // Same shape loadConfig returns when no config file exists at all: a safe
145
+ // fallback so a corrupted config.json degrades the project check, not the
146
+ // whole command (resolveModel's config.model precedence level is simply
147
+ // unavailable; --model/COPPERHEAD_MODEL/an available key still resolve).
148
+ const FALLBACK_CONFIG = { schematic: null, board: null, ...DEFAULTS };
149
+ export async function runDoctor(opts) {
150
+ const deps = { ...defaultDeps(), ...opts.deps };
151
+ let config;
152
+ let configError;
153
+ try {
154
+ config = await loadConfig(opts.repoRoot);
155
+ }
156
+ catch (err) {
157
+ config = FALLBACK_CONFIG;
158
+ // JSON.parse throws a bare SyntaxError for bad content; readFile throws a
159
+ // coded Error (EACCES, EISDIR, ...) for a file that couldn't be read at
160
+ // all. The two need different advice: content is fixed by regenerating
161
+ // the file, unreadable is a permissions/filesystem problem regenerating
162
+ // it will not solve.
163
+ configError =
164
+ err instanceof SyntaxError
165
+ ? {
166
+ name: 'project',
167
+ status: 'fail',
168
+ detail: `.copperhead/config.json is malformed: ${err.message}`,
169
+ hint: 'fix or delete .copperhead/config.json (rerun `copperhead init`/`copperhead create` to regenerate it).',
170
+ }
171
+ : {
172
+ name: 'project',
173
+ status: 'fail',
174
+ detail: `.copperhead/config.json could not be read: ${err.message}`,
175
+ hint: 'check that it is a regular file (not a directory) and that you have permission to read it.',
176
+ };
177
+ }
178
+ const checks = [
179
+ nodeCheck(deps.nodeVersion),
180
+ await kicadCheck(deps.kicadVersion),
181
+ await gitCheck(deps.gitVersion),
182
+ providerCheck(opts.model, config, deps.env),
183
+ configError ?? projectCheck(config, opts.repoRoot),
184
+ ];
185
+ return { ok: checks.every((c) => c.status !== 'fail'), checks };
186
+ }
187
+ const TAG = { ok: '[ok]', fail: '[FAIL]', info: '[info]' };
188
+ const TAG_COL = 2; // leading indent
189
+ const NAME_COL = TAG_COL + 7; // widest tag "[FAIL]" + one space
190
+ const DETAIL_COL = NAME_COL + 10; // widest name "kicad-cli" + one space
191
+ // Plain ANSI, no color dependency: green/red/cyan tags, dim hints. Color is
192
+ // off by default; the CLI opts in only for a real TTY, so piped output and
193
+ // tests see plain text. Colored text is padded before painting — escape codes
194
+ // have zero display width but nonzero string length, so painting first would
195
+ // break the column math.
196
+ const ANSI = { ok: '32', fail: '31', info: '36' };
197
+ const DIM = '2';
198
+ function paint(text, code, on) {
199
+ return on ? `\u001b[${code}m${text}\u001b[0m` : text;
200
+ }
201
+ function wrapWords(text, width) {
202
+ const lines = [];
203
+ let line = '';
204
+ for (const word of text.split(' ')) {
205
+ if (line && line.length + 1 + word.length > width) {
206
+ lines.push(line);
207
+ line = word;
208
+ }
209
+ else {
210
+ line = line ? `${line} ${word}` : word;
211
+ }
212
+ }
213
+ if (line)
214
+ lines.push(line);
215
+ return lines;
216
+ }
217
+ /** Continuation lines land in the same column as the first, so wrapped text reads as one block. */
218
+ function pushWrapped(lines, first, text, col, width) {
219
+ const wrapped = wrapWords(text, Math.max(20, width - col));
220
+ lines.push(first + (wrapped[0] ?? ''));
221
+ for (const rest of wrapped.slice(1))
222
+ lines.push(' '.repeat(col) + rest);
223
+ }
224
+ export function formatDoctor(report, width = 80, color = false) {
225
+ const lines = [];
226
+ for (const c of report.checks) {
227
+ const tag = paint(TAG[c.status], ANSI[c.status], color) + ' '.repeat(NAME_COL - TAG_COL - TAG[c.status].length);
228
+ const head = ' '.repeat(TAG_COL) + tag + c.name.padEnd(DETAIL_COL - NAME_COL);
229
+ pushWrapped(lines, head, c.detail, DETAIL_COL, width);
230
+ if (c.hint) {
231
+ const start = lines.length;
232
+ pushWrapped(lines, `${' '.repeat(NAME_COL)}hint: `, c.hint, NAME_COL + 6, width);
233
+ for (let i = start; i < lines.length; i++)
234
+ lines[i] = paint(lines[i], DIM, color);
235
+ }
236
+ }
237
+ lines.push(report.ok ? paint('ready', ANSI.ok, color) : paint('not ready: fix the [FAIL] items above', ANSI.fail, color));
238
+ return lines;
239
+ }
240
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Read-only inspect helpers for REPL slash commands (/sync, /config, /runs…).
3
+ * All deterministic, no LLM.
4
+ */
5
+ import path from 'node:path';
6
+ import { existsSync } from 'node:fs';
7
+ import { readdir, readFile } from 'node:fs/promises';
8
+ import { execa } from 'execa';
9
+ import { loadConfig } from '../config.js';
10
+ import { checkDrift } from '../memory/drift.js';
11
+ import { loadConstraints } from '../memory/constraints.js';
12
+ import { parseBomTable } from '../memory/bom-table.js';
13
+ import { syncVerify, formatSyncReport } from './sync.js';
14
+ import { listSymbols, listNets, pinNets } from '../kicad/sexp.js';
15
+ import { openspecValidate } from '../openspec/cli.js';
16
+ import { copper, dim, ok, warn, err } from '../agent/theme.js';
17
+ import { traceRule } from '../agent/animate.js';
18
+ import { shortPath } from '../util/paths.js';
19
+ import { branchName, headCommit, isDirty, isGitRepo, uncommittedCount } from '../util/git.js';
20
+ function meta(label, value) {
21
+ return ` ${dim(label.padEnd(12))} ${value}`;
22
+ }
23
+ async function sortedRunIds(repoRoot) {
24
+ const runsDir = path.join(repoRoot, '.copperhead', 'runs');
25
+ if (!existsSync(runsDir))
26
+ return [];
27
+ return (await readdir(runsDir, { withFileTypes: true }))
28
+ .filter((d) => d.isDirectory())
29
+ .map((d) => d.name)
30
+ .sort()
31
+ .reverse();
32
+ }
33
+ async function resolveSchematic(repoRoot) {
34
+ const config = await loadConfig(repoRoot);
35
+ if (!config.schematic) {
36
+ return { message: 'no schematic configured (run copperhead init)' };
37
+ }
38
+ const schPath = path.join(repoRoot, config.schematic);
39
+ if (!existsSync(schPath)) {
40
+ return { message: `schematic missing: ${config.schematic}` };
41
+ }
42
+ return { schPath };
43
+ }
44
+ /** `/sync` — verify-only inconsistency report (never auto-resolves). */
45
+ export async function formatSyncInspect(repoRoot) {
46
+ const report = await syncVerify(repoRoot);
47
+ const body = formatSyncReport(report);
48
+ const headline = !report.resolvable.length && !report.violations.length
49
+ ? ok(' sync: clean')
50
+ : report.violations.length
51
+ ? err(` sync: ${report.violations.length} requirement violation(s), ${report.resolvable.length} resolvable`)
52
+ : warn(` sync: ${report.resolvable.length} resolvable inconsistency(ies)`);
53
+ return ['', copper(' Sync'), traceRule(12), '', headline, '', ...body.split('\n').map((l) => ` ${l}`), ''].join('\n');
54
+ }
55
+ /** `/config` — full resolved config view. */
56
+ export async function formatConfigInspect(repoRoot) {
57
+ const c = await loadConfig(repoRoot);
58
+ const lines = [
59
+ '',
60
+ copper(' Config'),
61
+ traceRule(14),
62
+ '',
63
+ meta('schematic', c.schematic ?? dim('null')),
64
+ meta('board', c.board ?? dim('null')),
65
+ meta('docs', c.docs),
66
+ meta('model', c.model ?? dim('null (use --model / env)')),
67
+ meta('maxTurns', String(c.maxTurns)),
68
+ meta('repair', String(c.maxRepairCycles)),
69
+ meta('origin', c.origin ?? dim('unset')),
70
+ meta('llmCache', c.llmCache ? 'on' : 'off'),
71
+ meta('budgets', Object.keys(c.budgets).length ? JSON.stringify(c.budgets) : dim('{}')),
72
+ ];
73
+ if (c.stageMaxTurns && Object.keys(c.stageMaxTurns).length) {
74
+ lines.push(meta('stageTurns', JSON.stringify(c.stageMaxTurns)));
75
+ }
76
+ lines.push('');
77
+ lines.push(dim(` file ${shortPath(path.join(repoRoot, '.copperhead/config.json'))}`));
78
+ lines.push('');
79
+ return lines.join('\n');
80
+ }
81
+ /** `/git` — porcelain status + branch tip. */
82
+ export async function formatGitInspect(repoRoot) {
83
+ if (!(await isGitRepo(repoRoot))) {
84
+ return ['', warn(' git: not a repository'), ''].join('\n');
85
+ }
86
+ const [branch, commit, dirty, n, porcelain] = await Promise.all([
87
+ branchName(repoRoot).catch(() => 'unknown'),
88
+ headCommit(repoRoot).catch(() => 'unknown'),
89
+ isDirty(repoRoot).catch(() => null),
90
+ uncommittedCount(repoRoot).catch(() => null),
91
+ execa('git', ['status', '--porcelain'], { cwd: repoRoot }).then((r) => r.stdout ? r.stdout.split('\n').filter(Boolean) : []),
92
+ ]);
93
+ const state = dirty === null ? 'unknown' : dirty ? warn(`dirty (${n ?? '?'} file(s))`) : ok('clean');
94
+ const lines = [
95
+ '',
96
+ copper(' Git'),
97
+ traceRule(10),
98
+ '',
99
+ meta('branch', `${branch}@${commit.slice(0, 7)}`),
100
+ meta('state', state),
101
+ '',
102
+ ];
103
+ if (porcelain.length) {
104
+ lines.push(dim(' changes:'));
105
+ for (const row of porcelain.slice(0, 40))
106
+ lines.push(` ${row}`);
107
+ if (porcelain.length > 40)
108
+ lines.push(dim(` … and ${porcelain.length - 40} more`));
109
+ lines.push('');
110
+ }
111
+ return lines.join('\n');
112
+ }
113
+ /** `/drift` — doc↔schematic only (no ERC/DRC). */
114
+ export async function formatDriftInspect(repoRoot) {
115
+ const config = await loadConfig(repoRoot);
116
+ if (!config.schematic) {
117
+ return ['', warn(' drift: no schematic configured (run copperhead init)'), ''].join('\n');
118
+ }
119
+ const mismatches = await checkDrift(repoRoot, config.docs, config.schematic);
120
+ if (!mismatches.length) {
121
+ return ['', ok(' drift: docs match schematic'), ''].join('\n');
122
+ }
123
+ const lines = [
124
+ '',
125
+ copper(' Drift'),
126
+ traceRule(12),
127
+ '',
128
+ warn(` ${mismatches.length} mismatch(es):`),
129
+ '',
130
+ ];
131
+ for (const m of mismatches.slice(0, 30)) {
132
+ lines.push(` ${copper('▸')} ${m.doc}`);
133
+ lines.push(dim(` claim ${m.claim}`));
134
+ lines.push(dim(` actual ${m.actual}`));
135
+ }
136
+ if (mismatches.length > 30)
137
+ lines.push(dim(` … and ${mismatches.length - 30} more`));
138
+ lines.push('');
139
+ return lines.join('\n');
140
+ }
141
+ /** `/constraints` — registry summary. */
142
+ export async function formatConstraintsInspect(repoRoot) {
143
+ const registry = await loadConstraints(repoRoot);
144
+ const keys = Object.keys(registry).sort();
145
+ if (!keys.length) {
146
+ return ['', dim(' constraints: none recorded yet'), ''].join('\n');
147
+ }
148
+ const lines = [
149
+ '',
150
+ copper(' Constraints'),
151
+ traceRule(20),
152
+ '',
153
+ dim(` ${keys.length} open constraint(s)`),
154
+ '',
155
+ ];
156
+ for (const key of keys.slice(0, 40)) {
157
+ const c = registry[key];
158
+ const bound = c.value !== undefined
159
+ ? String(c.value)
160
+ : [c.min !== undefined ? `min ${c.min}` : '', c.max !== undefined ? `max ${c.max}` : '']
161
+ .filter(Boolean)
162
+ .join(', ') || (c.forbidden?.length ? `forbidden ${c.forbidden.join(',')}` : '—');
163
+ lines.push(` ${copper(key)} ${bound}`);
164
+ lines.push(dim(` source ${c.source} · affects ${c.affects.join(', ') || '—'}`));
165
+ }
166
+ if (keys.length > 40)
167
+ lines.push(dim(` … and ${keys.length - 40} more`));
168
+ lines.push('');
169
+ return lines.join('\n');
170
+ }
171
+ /** `/runs` — recent `.copperhead/runs/` summaries. */
172
+ export async function formatRunsInspect(repoRoot) {
173
+ const runsDir = path.join(repoRoot, '.copperhead', 'runs');
174
+ const entries = await sortedRunIds(repoRoot);
175
+ if (!entries.length) {
176
+ return ['', dim(' runs: none yet'), ''].join('\n');
177
+ }
178
+ const lines = ['', copper(' Recent runs'), traceRule(18), ''];
179
+ for (const id of entries.slice(0, 12)) {
180
+ const summaryPath = path.join(runsDir, id, 'summary.md');
181
+ const reportPath = path.join(runsDir, id, 'REPORT.md');
182
+ let outcome = dim('unknown');
183
+ if (existsSync(summaryPath)) {
184
+ const text = await readFile(summaryPath, 'utf8');
185
+ const m = text.match(/exitPath[:\s*`]+([a-z-]+)/i) ||
186
+ text.match(/\*\*Exit(?:\s*path)?:\*\*\s*`?([a-z-]+)/i) ||
187
+ text.match(/## Run stats[\s\S]*?`([a-z-]+)`/);
188
+ if (m?.[1]) {
189
+ const pathName = m[1];
190
+ outcome =
191
+ pathName === 'done' ? ok(pathName) : /fail|error|refus|exhaust|stall/i.test(pathName) ? err(pathName) : warn(pathName);
192
+ }
193
+ else if (/## Run stats/i.test(text)) {
194
+ outcome = dim('recorded');
195
+ }
196
+ }
197
+ const extras = existsSync(reportPath) ? dim(' · report') : '';
198
+ lines.push(` ${copper(id)} ${outcome}${extras}`);
199
+ }
200
+ if (entries.length > 12)
201
+ lines.push(dim(` … and ${entries.length - 12} older`));
202
+ lines.push('');
203
+ lines.push(dim(` dir ${shortPath(runsDir)}`));
204
+ lines.push('');
205
+ return lines.join('\n');
206
+ }
207
+ /** `/parts` — schematic symbol table (refdes / value / footprint). */
208
+ export async function formatPartsInspect(repoRoot) {
209
+ const resolved = await resolveSchematic(repoRoot);
210
+ if ('message' in resolved) {
211
+ return ['', warn(` parts: ${resolved.message}`), ''].join('\n');
212
+ }
213
+ const syms = await listSymbols(resolved.schPath);
214
+ if (!syms.length) {
215
+ return ['', dim(' parts: schematic has no components'), ''].join('\n');
216
+ }
217
+ const refW = Math.max(4, ...syms.map((s) => s.ref.length));
218
+ const valW = Math.min(24, Math.max(5, ...syms.map((s) => s.value.length)));
219
+ const lines = [
220
+ '',
221
+ copper(' Parts'),
222
+ traceRule(12),
223
+ '',
224
+ dim(` ${'ref'.padEnd(refW)} ${'value'.padEnd(valW)} footprint`),
225
+ '',
226
+ ];
227
+ for (const s of syms.slice(0, 60)) {
228
+ const val = s.value.length > valW ? s.value.slice(0, valW - 1) + '…' : s.value;
229
+ lines.push(` ${copper(s.ref.padEnd(refW))} ${val.padEnd(valW)} ${dim(s.footprint || '—')}`);
230
+ }
231
+ if (syms.length > 60)
232
+ lines.push(dim(` … and ${syms.length - 60} more`));
233
+ lines.push('');
234
+ return lines.join('\n');
235
+ }
236
+ /** `/nets` — net names and pin attachments from the schematic. */
237
+ export async function formatNetsInspect(repoRoot) {
238
+ const resolved = await resolveSchematic(repoRoot);
239
+ if ('message' in resolved) {
240
+ return ['', warn(` nets: ${resolved.message}`), ''].join('\n');
241
+ }
242
+ const [names, pins] = await Promise.all([listNets(resolved.schPath), pinNets(resolved.schPath)]);
243
+ const byNet = new Map();
244
+ for (const p of pins) {
245
+ const net = p.net ?? '(unconnected)';
246
+ const tag = p.pinName ? `${p.ref}.${p.pinName}` : `${p.ref}:${p.pinNumber}`;
247
+ const list = byNet.get(net) ?? [];
248
+ list.push(tag);
249
+ byNet.set(net, list);
250
+ }
251
+ const ordered = [...new Set([...names, ...byNet.keys()])].sort((a, b) => {
252
+ if (a === '(unconnected)')
253
+ return 1;
254
+ if (b === '(unconnected)')
255
+ return -1;
256
+ return a.localeCompare(b);
257
+ });
258
+ const lines = ['', copper(' Nets'), traceRule(10), '', dim(` ${ordered.length} net(s)`), ''];
259
+ for (const net of ordered.slice(0, 40)) {
260
+ const attached = (byNet.get(net) ?? []).sort();
261
+ const preview = attached.slice(0, 8).join(', ');
262
+ const extra = attached.length > 8 ? dim(` +${attached.length - 8}`) : '';
263
+ lines.push(` ${copper(net)} ${dim(preview)}${extra}`);
264
+ }
265
+ if (ordered.length > 40)
266
+ lines.push(dim(` … and ${ordered.length - 40} more`));
267
+ lines.push('');
268
+ return lines.join('\n');
269
+ }
270
+ /** `/bom` — parsed docs/BOM.md (inspect only; no export). */
271
+ export async function formatBomInspect(repoRoot) {
272
+ const config = await loadConfig(repoRoot);
273
+ const bomPath = path.join(repoRoot, config.docs, 'BOM.md');
274
+ if (!existsSync(bomPath)) {
275
+ return ['', warn(' bom: docs/BOM.md not found'), ''].join('\n');
276
+ }
277
+ const rows = parseBomTable(await readFile(bomPath, 'utf8'));
278
+ if (!rows.length) {
279
+ return ['', dim(' bom: no parseable rows in BOM.md'), ''].join('\n');
280
+ }
281
+ const refW = Math.max(5, ...rows.map((r) => r.refdes.length));
282
+ const lines = ['', copper(' BOM'), traceRule(8), '', dim(` ${rows.length} row(s) from ${shortPath(bomPath)}`), ''];
283
+ for (const r of rows.slice(0, 50)) {
284
+ const flags = r.flags.length ? dim(` [${r.flags.join(',')}]`) : '';
285
+ lines.push(` ${copper(r.refdes.padEnd(refW))} ${r.value ?? '—'} ${dim(r.footprint ?? '')}${flags}`);
286
+ if (r.mpn)
287
+ lines.push(dim(` mpn ${r.mpn}`));
288
+ }
289
+ if (rows.length > 50)
290
+ lines.push(dim(` … and ${rows.length - 50} more`));
291
+ lines.push('');
292
+ return lines.join('\n');
293
+ }
294
+ /** `/openspec` — `openspec validate` summary (same gate as check). */
295
+ export async function formatOpenSpecInspect(repoRoot) {
296
+ const cfgPath = path.join(repoRoot, 'openspec', 'config.yaml');
297
+ if (!existsSync(cfgPath)) {
298
+ return ['', dim(' openspec: no openspec/config.yaml in this repo'), ''].join('\n');
299
+ }
300
+ const res = await openspecValidate(repoRoot);
301
+ const headline = res.ok ? ok(' openspec: valid') : err(' openspec: validation failed');
302
+ const body = res.output
303
+ .trim()
304
+ .split('\n')
305
+ .slice(0, 30)
306
+ .map((l) => ` ${l}`)
307
+ .join('\n');
308
+ const lines = ['', copper(' OpenSpec'), traceRule(16), '', headline, ''];
309
+ if (body)
310
+ lines.push(body, '');
311
+ return lines.join('\n');
312
+ }
313
+ /** `/last` — preview the newest run summary.md. */
314
+ export async function formatLastInspect(repoRoot) {
315
+ const entries = await sortedRunIds(repoRoot);
316
+ if (!entries.length) {
317
+ return ['', dim(' last: no runs yet'), ''].join('\n');
318
+ }
319
+ const id = entries[0];
320
+ const runsDir = path.join(repoRoot, '.copperhead', 'runs');
321
+ const summaryPath = path.join(runsDir, id, 'summary.md');
322
+ const transcriptPath = path.join(runsDir, id, 'transcript.jsonl');
323
+ const lines = ['', copper(' Last run'), traceRule(14), '', meta('id', id), ''];
324
+ if (!existsSync(summaryPath)) {
325
+ lines.push(dim(' summary.md missing'), '');
326
+ return lines.join('\n');
327
+ }
328
+ const text = await readFile(summaryPath, 'utf8');
329
+ const preview = text.split('\n').slice(0, 40);
330
+ lines.push(dim(` ${shortPath(summaryPath)}`));
331
+ if (existsSync(transcriptPath)) {
332
+ lines.push(dim(` ${shortPath(transcriptPath)}`));
333
+ }
334
+ lines.push('');
335
+ for (const line of preview)
336
+ lines.push(` ${line}`);
337
+ if (text.split('\n').length > 40)
338
+ lines.push(dim(' … truncated'));
339
+ lines.push('');
340
+ return lines.join('\n');
341
+ }
342
+ //# sourceMappingURL=repl-inspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repl-inspect.js","sourceRoot":"","sources":["../../src/commands/repl-inspect.ts"],"names":[],"mappings":"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"}