@manishbht/helpcode 0.2.3 → 0.3.4

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 (49) hide show
  1. package/dist/bin/helpcode.js +0 -0
  2. package/dist/src/commands/ask.js +15 -1
  3. package/dist/src/commands/ask.js.map +1 -1
  4. package/dist/src/commands/cockpit.d.ts +13 -0
  5. package/dist/src/commands/cockpit.js +33 -0
  6. package/dist/src/commands/cockpit.js.map +1 -0
  7. package/dist/src/commands/plan.d.ts +14 -0
  8. package/dist/src/commands/plan.js +117 -0
  9. package/dist/src/commands/plan.js.map +1 -0
  10. package/dist/src/commands/run.js +55 -4
  11. package/dist/src/commands/run.js.map +1 -1
  12. package/dist/src/core/cockpit.d.ts +27 -0
  13. package/dist/src/core/cockpit.js +109 -0
  14. package/dist/src/core/cockpit.js.map +1 -0
  15. package/dist/src/core/cockpitHtml.d.ts +52 -0
  16. package/dist/src/core/cockpitHtml.js +395 -0
  17. package/dist/src/core/cockpitHtml.js.map +1 -0
  18. package/dist/src/core/consent.d.ts +20 -0
  19. package/dist/src/core/consent.js +34 -0
  20. package/dist/src/core/consent.js.map +1 -0
  21. package/dist/src/core/decompose.d.ts +45 -0
  22. package/dist/src/core/decompose.js +86 -0
  23. package/dist/src/core/decompose.js.map +1 -0
  24. package/dist/src/core/gemini.d.ts +41 -0
  25. package/dist/src/core/gemini.js +91 -0
  26. package/dist/src/core/gemini.js.map +1 -0
  27. package/dist/src/core/keys.d.ts +23 -0
  28. package/dist/src/core/keys.js +68 -0
  29. package/dist/src/core/keys.js.map +1 -0
  30. package/dist/src/core/llmSelector.d.ts +6 -0
  31. package/dist/src/core/llmSelector.js +22 -7
  32. package/dist/src/core/llmSelector.js.map +1 -1
  33. package/dist/src/core/selector.d.ts +9 -4
  34. package/dist/src/core/selector.js +88 -29
  35. package/dist/src/core/selector.js.map +1 -1
  36. package/dist/src/core/souschef.d.ts +63 -0
  37. package/dist/src/core/souschef.js +55 -0
  38. package/dist/src/core/souschef.js.map +1 -0
  39. package/dist/src/core/state.d.ts +13 -1
  40. package/dist/src/core/state.js +47 -5
  41. package/dist/src/core/state.js.map +1 -1
  42. package/dist/src/core/triage.d.ts +14 -1
  43. package/dist/src/core/triage.js +23 -5
  44. package/dist/src/core/triage.js.map +1 -1
  45. package/dist/src/index.d.ts +8 -7
  46. package/dist/src/index.js +21 -8
  47. package/dist/src/index.js.map +1 -1
  48. package/dist/src/types.d.ts +64 -1
  49. package/package.json +1 -1
File without changes
@@ -5,7 +5,7 @@
5
5
  import * as fs from 'fs';
6
6
  import * as path from 'path';
7
7
  import { loadProjectConfig } from '../core/project.js';
8
- import { loadState, saveState, createTask } from '../core/state.js';
8
+ import { loadState, saveState, createTask, appendSousChefEvent } from '../core/state.js';
9
9
  import { selectFilesWithStrategy } from '../core/selector.js';
10
10
  import { buildPrompt } from '../core/prompt.js';
11
11
  import { printPasteBlock, log, c } from '../lib/ui.js';
@@ -52,6 +52,20 @@ export async function handleAsk(taskDescription, opts = {}) {
52
52
  forceHeuristic: opts.noLlm,
53
53
  });
54
54
  selectedFiles = result.files.map(f => f.filepath);
55
+ // Record this prep work for the cockpit. Append to the state we already
56
+ // hold (saved at the end of this function) — not a separate load/save,
57
+ // which would be clobbered by our own saveState below.
58
+ appendSousChefEvent(state, {
59
+ at: new Date().toISOString(),
60
+ task: 'file_selection',
61
+ worker: result.strategy === 'llm' ? 'local' : 'deterministic',
62
+ model: result.strategy === 'llm' ? (config.ollama?.model ?? null) : null,
63
+ summary: result.strategy === 'llm'
64
+ ? `selected ${result.files.length} file(s) by reasoning`
65
+ : `selected ${result.files.length} file(s) by keyword heuristic`,
66
+ outcome: result.strategy === 'llm' ? 'ok' : (result.fallbackReason ? 'fallback' : 'ok'),
67
+ estTokensSaved: null,
68
+ });
55
69
  if (result.strategy === 'llm') {
56
70
  log.ok(`selected ${result.files.length} file(s) via local model`);
57
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/commands/ask.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/commands/ask.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `helpcode cockpit` — show the kitchen this session.
3
+ *
4
+ * Read-only window onto the sous-chef event log: which workers did which prep
5
+ * tasks, what was escalated to the principal, rough tokens saved.
6
+ *
7
+ * helpcode cockpit terminal view (v0.3.0)
8
+ * helpcode cockpit --html write a self-contained HTML cockpit (v0.3.4)
9
+ */
10
+ export declare function handleCockpit(opts?: {
11
+ html?: boolean;
12
+ out?: string;
13
+ }): Promise<number>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * `helpcode cockpit` — show the kitchen this session.
3
+ *
4
+ * Read-only window onto the sous-chef event log: which workers did which prep
5
+ * tasks, what was escalated to the principal, rough tokens saved.
6
+ *
7
+ * helpcode cockpit terminal view (v0.3.0)
8
+ * helpcode cockpit --html write a self-contained HTML cockpit (v0.3.4)
9
+ */
10
+ import * as fs from 'fs';
11
+ import * as path from 'path';
12
+ import { loadState } from '../core/state.js';
13
+ import { renderCockpit } from '../core/cockpit.js';
14
+ import { buildCockpitViewModel, renderCockpitHtml } from '../core/cockpitHtml.js';
15
+ import { c, log } from '../lib/ui.js';
16
+ export async function handleCockpit(opts = {}) {
17
+ const state = loadState();
18
+ if (opts.html) {
19
+ const vm = buildCockpitViewModel(state.sousChefLog);
20
+ const html = renderCockpitHtml(vm);
21
+ const outPath = opts.out ?? path.join('.helpcode', 'cockpit.html');
22
+ const dir = path.dirname(outPath);
23
+ if (!fs.existsSync(dir))
24
+ fs.mkdirSync(dir, { recursive: true });
25
+ fs.writeFileSync(outPath, html, 'utf-8');
26
+ log.ok(`wrote cockpit to ${outPath}`);
27
+ log.dim('open it in a browser: ' + c.cyan(`open ${outPath}`));
28
+ return 0;
29
+ }
30
+ console.log(renderCockpit(state.sousChefLog));
31
+ return 0;
32
+ }
33
+ //# sourceMappingURL=cockpit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cockpit.js","sourceRoot":"","sources":["../../../src/commands/cockpit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAyC,EAAE;IAC7E,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAE1B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,EAAE,GAAG,qBAAqB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACzC,GAAG,CAAC,EAAE,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QACtC,GAAG,CAAC,GAAG,CAAC,wBAAwB,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `helpcode plan "<big task>"` — propose an ordered breakdown of a large task
3
+ * into focused sub-steps.
4
+ *
5
+ * Human-in-the-loop by design: this PROPOSES and STOPS. It prints the steps and
6
+ * suggests running `helpcode ask` for the first one. It does NOT auto-run
7
+ * anything. helpcode stays in the loop; it is not an autonomous agent.
8
+ *
9
+ * v0.3.2: decomposition can run on a LOCAL sous-chef (Ollama) or, if local is
10
+ * unavailable and a free-tier key is configured, a REMOTE one (Gemini). The
11
+ * task description is the only thing sent remotely — no source code — so this
12
+ * is privacy-safe under the default rules (see core/souschef.ts).
13
+ */
14
+ export declare function handlePlan(task: string): Promise<number>;
@@ -0,0 +1,117 @@
1
+ /**
2
+ * `helpcode plan "<big task>"` — propose an ordered breakdown of a large task
3
+ * into focused sub-steps.
4
+ *
5
+ * Human-in-the-loop by design: this PROPOSES and STOPS. It prints the steps and
6
+ * suggests running `helpcode ask` for the first one. It does NOT auto-run
7
+ * anything. helpcode stays in the loop; it is not an autonomous agent.
8
+ *
9
+ * v0.3.2: decomposition can run on a LOCAL sous-chef (Ollama) or, if local is
10
+ * unavailable and a free-tier key is configured, a REMOTE one (Gemini). The
11
+ * task description is the only thing sent remotely — no source code — so this
12
+ * is privacy-safe under the default rules (see core/souschef.ts).
13
+ */
14
+ import { loadProjectConfig } from '../core/project.js';
15
+ import { loadState, saveState, appendSousChefEvent } from '../core/state.js';
16
+ import { decomposeTask, buildDecompositionPrompt, parseDecomposition } from '../core/decompose.js';
17
+ import { geminiGenerate, GeminiError } from '../core/gemini.js';
18
+ import { loadGeminiKey } from '../core/keys.js';
19
+ import { c, log } from '../lib/ui.js';
20
+ const GEMINI_MODEL = 'gemini-2.5-flash-lite';
21
+ export async function handlePlan(task) {
22
+ if (!task || !task.trim()) {
23
+ log.err('Usage: helpcode plan "<task to break down>"');
24
+ return 1;
25
+ }
26
+ const config = loadProjectConfig();
27
+ const outcome = await decomposeViaSousChef(task, config);
28
+ if (!outcome.ok) {
29
+ if (outcome.steps.length === 1) {
30
+ log.dim('This looks like a single focused task — no need to break it down.');
31
+ }
32
+ else {
33
+ log.dim(`Couldn't break this down (${outcome.reason}).`);
34
+ }
35
+ log.dim('Just run: ' + c.cyan(`helpcode ask "${task}"`));
36
+ return 0;
37
+ }
38
+ // Record the prep work for the cockpit.
39
+ const state = loadState();
40
+ appendSousChefEvent(state, {
41
+ at: new Date().toISOString(),
42
+ task: 'decomposition',
43
+ worker: outcome.worker,
44
+ model: outcome.model,
45
+ summary: `proposed ${outcome.steps.length}-step breakdown`,
46
+ outcome: 'ok',
47
+ estTokensSaved: null,
48
+ });
49
+ saveState(state);
50
+ // Propose — and stop. The human decides.
51
+ console.log();
52
+ const where = outcome.worker === 'remote'
53
+ ? c.dim(` (via free-tier ${outcome.model})`)
54
+ : '';
55
+ console.log(c.cyan('Proposed breakdown') + c.dim(' (you decide — nothing runs automatically)') + where);
56
+ console.log();
57
+ outcome.steps.forEach((step, i) => {
58
+ console.log(` ${c.cyan(String(i + 1))}. ${step}`);
59
+ });
60
+ console.log();
61
+ log.dim('Tackle these one at a time. Start the first with:');
62
+ console.log(' ' + c.cyan(`helpcode ask "${outcome.steps[0]}"`));
63
+ console.log();
64
+ log.dim('Each focused step gives Claude a tighter brief than the whole task at once.');
65
+ return 0;
66
+ }
67
+ /**
68
+ * Try local decomposition first; if local isn't available and a free-tier key
69
+ * is configured, fall back to the remote sous-chef. Decomposition sends only
70
+ * the task description (no code), so it's privacy-safe by default.
71
+ */
72
+ async function decomposeViaSousChef(task, config) {
73
+ // 1. Local (cheapest), if enabled.
74
+ if (config.ollama?.enabled) {
75
+ log.dim(`thinking through the steps (local model: ${config.ollama.model})...`);
76
+ const local = await decomposeTask(task, config.ollama);
77
+ if (local.ok) {
78
+ return { ok: true, steps: local.steps, worker: 'local', model: config.ollama.model, reason: '' };
79
+ }
80
+ // Local produced a single step (not worth decomposing) — respect that,
81
+ // don't burn a remote call second-guessing it.
82
+ if (local.steps.length === 1) {
83
+ return { ok: false, steps: local.steps, worker: 'local', model: config.ollama.model, reason: local.reason };
84
+ }
85
+ // Local failed for an availability reason — fall through to remote.
86
+ log.dim(`local model unavailable (${local.reason})`);
87
+ }
88
+ // 2. Remote free-tier, if a key is configured. Decomposition is always
89
+ // privacy-allowed (task description only, no code).
90
+ const key = loadGeminiKey();
91
+ if (!key) {
92
+ if (!config.ollama?.enabled) {
93
+ return { ok: false, steps: [], worker: 'local', model: null,
94
+ reason: 'no local model enabled and no free-tier key configured' };
95
+ }
96
+ return { ok: false, steps: [], worker: 'local', model: null, reason: 'local model unavailable' };
97
+ }
98
+ log.dim(`thinking through the steps (free-tier ${GEMINI_MODEL})...`);
99
+ try {
100
+ const text = await geminiGenerate(buildDecompositionPrompt(task), {
101
+ apiKey: key, model: GEMINI_MODEL, timeoutMs: 30000,
102
+ });
103
+ const steps = parseDecomposition(text);
104
+ if (steps.length >= 2) {
105
+ return { ok: true, steps, worker: 'remote', model: GEMINI_MODEL, reason: '' };
106
+ }
107
+ if (steps.length === 1) {
108
+ return { ok: false, steps, worker: 'remote', model: GEMINI_MODEL, reason: 'single step — not worth decomposing' };
109
+ }
110
+ return { ok: false, steps: [], worker: 'remote', model: GEMINI_MODEL, reason: 'no steps parsed' };
111
+ }
112
+ catch (e) {
113
+ const why = e instanceof GeminiError ? e.message : e.message;
114
+ return { ok: false, steps: [], worker: 'remote', model: GEMINI_MODEL, reason: `remote failed: ${why}` };
115
+ }
116
+ }
117
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/commands/plan.ts"],"names":[],"mappings":"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"}
@@ -11,10 +11,28 @@
11
11
  */
12
12
  import { runShellCommand } from '../core/tools.js';
13
13
  import { truncateLines, extractTraceback } from '../lib/compress.js';
14
- import { loadState, saveState } from '../core/state.js';
14
+ import { loadState, saveState, appendSousChefEvent } from '../core/state.js';
15
15
  import { projectExists, loadProjectConfig } from '../core/project.js';
16
16
  import { triageOutput, shouldTriage } from '../core/triage.js';
17
+ import { geminiGenerate } from '../core/gemini.js';
18
+ import { loadGeminiKey } from '../core/keys.js';
19
+ import { shouldShowRemoteCodeNotice, remoteCodeNoticeText } from '../core/consent.js';
17
20
  import { c, log } from '../lib/ui.js';
21
+ const REMOTE_TRIAGE_MODEL = 'gemini-2.5-flash-lite';
22
+ function maybeShowRemoteCodeNotice(task, model) {
23
+ try {
24
+ const s = loadState();
25
+ const alreadyShown = s.flags?.remoteCodeNoticeShown === true;
26
+ if (shouldShowRemoteCodeNotice({ allowRemoteCode: true, task, alreadyShown })) {
27
+ console.error('\n' + remoteCodeNoticeText(model) + '\n');
28
+ s.flags = { ...(s.flags ?? {}), remoteCodeNoticeShown: true };
29
+ saveState(s);
30
+ }
31
+ }
32
+ catch {
33
+ // never block on the notice
34
+ }
35
+ }
18
36
  const MAX_OUTPUT_LINES = 40;
19
37
  export async function handleRun(command, opts = {}) {
20
38
  if (!command || !command.trim()) {
@@ -52,16 +70,34 @@ export async function handleRun(command, opts = {}) {
52
70
  const cfg = loadConfigSafe();
53
71
  const rawForTriage = [result.stdout, result.stderr].filter(Boolean).join('\n').trim();
54
72
  if (cfg?.ollama && shouldTriage(rawForTriage, cfg.ollama)) {
55
- const triaged = await triageOutput(rawForTriage, cfg.ollama);
73
+ // Triage output is code-bearing, so a remote fallback is only offered when
74
+ // the project opted into allowRemoteCode AND a key is present.
75
+ let remoteGenerate;
76
+ let remoteModel = null;
77
+ if (cfg.remote?.allowRemoteCode === true) {
78
+ const key = loadGeminiKey();
79
+ if (key) {
80
+ remoteModel = REMOTE_TRIAGE_MODEL;
81
+ remoteGenerate = (prompt) => geminiGenerate(prompt, {
82
+ apiKey: key, model: REMOTE_TRIAGE_MODEL, timeoutMs: 30000,
83
+ });
84
+ }
85
+ }
86
+ const triaged = await triageOutput(rawForTriage, cfg.ollama, { remoteGenerate });
56
87
  if (triaged.triaged) {
88
+ if (triaged.remote) {
89
+ maybeShowRemoteCodeNotice('output_triage', remoteModel ?? REMOTE_TRIAGE_MODEL);
90
+ }
91
+ const who = triaged.remote ? `free-tier ${remoteModel}` : 'local model';
57
92
  savedOutput = [
58
93
  `$ ${command}`,
59
94
  `Exit: ${result.exitCode} Time: ${(result.durationMs / 1000).toFixed(2)}s`,
60
95
  '',
61
- '--- key failure (summarised by local model) ---',
96
+ `--- key failure (summarised by ${who}) ---`,
62
97
  triaged.text,
63
98
  ].join('\n');
64
- log.dim('(summarised long output with local model for the next brief)');
99
+ log.dim(`(summarised long output with ${who} for the next brief)`);
100
+ recordTriageEvent(state, who, rawForTriage, triaged.text, triaged.remote === true);
65
101
  }
66
102
  }
67
103
  state.currentTask.lastTestOutput = savedOutput;
@@ -106,4 +142,19 @@ function commandMatchesTestCommand(command) {
106
142
  function normalise(cmd) {
107
143
  return cmd.trim().replace(/\s+/g, ' ');
108
144
  }
145
+ /** Append a triage sous-chef event to the in-memory state (saved by caller). */
146
+ function recordTriageEvent(state, workerLabel, rawOutput, triagedText, remote) {
147
+ const rawLines = rawOutput.split('\n').length;
148
+ const triagedLines = triagedText.split('\n').length;
149
+ appendSousChefEvent(state, {
150
+ at: new Date().toISOString(),
151
+ task: 'output_triage',
152
+ worker: remote ? 'remote' : 'local',
153
+ model: workerLabel.replace(/^free-tier /, ''),
154
+ summary: `triaged ${rawLines} lines to key failure`,
155
+ outcome: 'ok',
156
+ // rough: lines dropped ≈ tokens saved, ~8 tokens/line
157
+ estTokensSaved: Math.max(0, (rawLines - triagedLines) * 8),
158
+ });
159
+ }
109
160
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/commands/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The cockpit (v0.3.0) — the instrument panel for helpcode's kitchen.
3
+ *
4
+ * This is the WINDOW: it reads the sous-chef event log from state and renders
5
+ * who did what, what was escalated to the principal, and rough tokens saved.
6
+ * It is read-only. The eventual engine writes the same events; the cockpit will
7
+ * show them live without changing this code. Window now, engine behind the same
8
+ * glass later.
9
+ *
10
+ * Pure aggregation functions (summariseWorkers, sessionMetrics) are separated
11
+ * from rendering so they're easy to unit-test.
12
+ */
13
+ import { SousChefEvent, WorkerStatus } from '../types.js';
14
+ export interface SessionMetrics {
15
+ totalEvents: number;
16
+ escalations: number;
17
+ fallbacks: number;
18
+ estTokensSaved: number;
19
+ }
20
+ /**
21
+ * Collapse the event log into one status per distinct worker, newest summary
22
+ * winning. Events are assumed roughly time-ordered but we sort defensively.
23
+ */
24
+ export declare function summariseWorkers(log: SousChefEvent[]): WorkerStatus[];
25
+ export declare function sessionMetrics(log: SousChefEvent[]): SessionMetrics;
26
+ /** Render the cockpit as a terminal printout. Read-only view of the log. */
27
+ export declare function renderCockpit(log: SousChefEvent[]): string;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * The cockpit (v0.3.0) — the instrument panel for helpcode's kitchen.
3
+ *
4
+ * This is the WINDOW: it reads the sous-chef event log from state and renders
5
+ * who did what, what was escalated to the principal, and rough tokens saved.
6
+ * It is read-only. The eventual engine writes the same events; the cockpit will
7
+ * show them live without changing this code. Window now, engine behind the same
8
+ * glass later.
9
+ *
10
+ * Pure aggregation functions (summariseWorkers, sessionMetrics) are separated
11
+ * from rendering so they're easy to unit-test.
12
+ */
13
+ import { c } from '../lib/ui.js';
14
+ /** Identity for grouping: a worker is a (kind, model) pair. */
15
+ function workerKey(e) {
16
+ return `${e.worker}::${e.model ?? ''}`;
17
+ }
18
+ /**
19
+ * Collapse the event log into one status per distinct worker, newest summary
20
+ * winning. Events are assumed roughly time-ordered but we sort defensively.
21
+ */
22
+ export function summariseWorkers(log) {
23
+ const sorted = [...log].sort((a, b) => a.at.localeCompare(b.at));
24
+ const byWorker = new Map();
25
+ for (const e of sorted) {
26
+ const key = workerKey(e);
27
+ const existing = byWorker.get(key);
28
+ if (existing) {
29
+ existing.eventsThisSession += 1;
30
+ existing.lastSummary = e.summary;
31
+ }
32
+ else {
33
+ byWorker.set(key, {
34
+ kind: e.worker,
35
+ model: e.model,
36
+ quotaUsed: null, // populated for remote workers in v0.3.2+
37
+ eventsThisSession: 1,
38
+ lastSummary: e.summary,
39
+ });
40
+ }
41
+ }
42
+ return [...byWorker.values()];
43
+ }
44
+ export function sessionMetrics(log) {
45
+ let escalations = 0;
46
+ let fallbacks = 0;
47
+ let estTokensSaved = 0;
48
+ for (const e of log) {
49
+ if (e.outcome === 'escalated')
50
+ escalations += 1;
51
+ if (e.outcome === 'fallback')
52
+ fallbacks += 1;
53
+ if (typeof e.estTokensSaved === 'number')
54
+ estTokensSaved += e.estTokensSaved;
55
+ }
56
+ return { totalEvents: log.length, escalations, fallbacks, estTokensSaved };
57
+ }
58
+ // --- rendering (kept out of the tested aggregation functions) ---
59
+ function workerLabel(kind) {
60
+ switch (kind) {
61
+ case 'local': return 'local';
62
+ case 'remote': return 'free-tier';
63
+ case 'deterministic': return 'code';
64
+ case 'principal': return 'principal';
65
+ }
66
+ }
67
+ /** Render the cockpit as a terminal printout. Read-only view of the log. */
68
+ export function renderCockpit(log) {
69
+ const lines = [];
70
+ lines.push(c.cyan('helpcode cockpit') + c.dim(' · the kitchen this session'));
71
+ lines.push('');
72
+ const workers = summariseWorkers(log);
73
+ if (workers.length === 0) {
74
+ lines.push(c.dim(' No sous-chef activity yet this session.'));
75
+ lines.push(c.dim(' Run `helpcode ask` (with Ollama enabled) to put the kitchen to work.'));
76
+ return lines.join('\n');
77
+ }
78
+ lines.push(c.dim(' WORKERS'));
79
+ for (const w of workers) {
80
+ const name = w.model ?? workerLabel(w.kind);
81
+ const tag = c.dim(`[${workerLabel(w.kind)}]`);
82
+ const quota = w.quotaUsed !== null
83
+ ? c.dim(` quota ${Math.round(w.quotaUsed * 100)}%`)
84
+ : '';
85
+ lines.push(` ${name} ${tag} ${c.dim(`· ${w.eventsThisSession} task(s)`)}${quota}`);
86
+ if (w.lastSummary)
87
+ lines.push(c.dim(` last: ${w.lastSummary}`));
88
+ }
89
+ lines.push('');
90
+ const m = sessionMetrics(log);
91
+ lines.push(c.dim(' SESSION'));
92
+ lines.push(` ${m.totalEvents} prep task(s) · ${m.escalations} escalated to principal · ${m.fallbacks} fell back`);
93
+ if (m.estTokensSaved > 0) {
94
+ lines.push(c.dim(` ~${m.estTokensSaved} principal tokens saved (rough estimate)`));
95
+ }
96
+ lines.push('');
97
+ lines.push(c.dim(' RECENT'));
98
+ const recent = [...log].slice(-8);
99
+ for (const e of recent) {
100
+ const t = e.at.slice(11, 16); // HH:MM
101
+ const who = e.model ?? workerLabel(e.worker);
102
+ const mark = e.outcome === 'ok' ? c.green('✓')
103
+ : e.outcome === 'escalated' ? c.yellow('↑')
104
+ : c.dim('·');
105
+ lines.push(` ${c.dim(t)} ${mark} ${c.dim(who)} ${e.summary}`);
106
+ }
107
+ return lines.join('\n');
108
+ }
109
+ //# sourceMappingURL=cockpit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cockpit.js","sourceRoot":"","sources":["../../../src/core/cockpit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Cockpit HTML view — `helpcode cockpit --html`.
3
+ *
4
+ * Reproduces the original orchestration-cockpit mockup's mission-control layout
5
+ * (1fr 2fr 1fr grid: flanking LLM panels, central orchestrator + metrics +
6
+ * pipeline, bottom row of activity/routing panels), filled with REAL data from
7
+ * the sous-chef event log where we have it.
8
+ *
9
+ * Honesty principle: workers that actually ran (local qwen, remote Gemini) are
10
+ * shown live. Panels for providers/features we haven't built (DeepSeek, Kimi,
11
+ * Claude-as-orchestrated, the autonomous pipeline, complexity-based routing)
12
+ * are rendered faithfully to the mockup but marked "demo" — a vision view with
13
+ * real data layered in as we build, not theatre passed off as live.
14
+ *
15
+ * View-model shaping is separated from HTML string-building for unit testing.
16
+ */
17
+ import { SousChefEvent, WorkerKind } from '../types.js';
18
+ import { SessionMetrics } from './cockpit.js';
19
+ export interface PanelVM {
20
+ model: string;
21
+ kind: WorkerKind;
22
+ tierLabel: string;
23
+ events: number;
24
+ lastSummary: string | null;
25
+ quotaUsed: number | null;
26
+ }
27
+ export interface FeedItemVM {
28
+ time: string;
29
+ who: string;
30
+ summary: string;
31
+ outcome: SousChefEvent['outcome'];
32
+ }
33
+ export interface ComingVM {
34
+ name: string;
35
+ note: string;
36
+ }
37
+ export interface CliLineVM {
38
+ kind: 'prefix' | 'ok' | 'warn' | 'dim';
39
+ text: string;
40
+ }
41
+ export interface CockpitViewModel {
42
+ workers: PanelVM[];
43
+ metrics: SessionMetrics;
44
+ recent: FeedItemVM[];
45
+ cli: CliLineVM[];
46
+ coming: ComingVM[];
47
+ generatedAt: string;
48
+ }
49
+ export declare function buildCockpitViewModel(log: SousChefEvent[]): CockpitViewModel;
50
+ /** Turn the real event log into helpcode-shell-style terminal lines. */
51
+ export declare function buildCliLines(log: SousChefEvent[]): CliLineVM[];
52
+ export declare function renderCockpitHtml(vm: CockpitViewModel): string;