@kinqs/brainrouter-cli 0.3.5 → 0.3.7

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 (125) hide show
  1. package/README.md +29 -52
  2. package/agents/architect.json +18 -0
  3. package/agents/explorer.json +18 -0
  4. package/agents/reviewer.json +18 -0
  5. package/agents/verifier.json +18 -0
  6. package/agents/worker.json +18 -0
  7. package/bin/cli.cjs +71 -0
  8. package/dist/agent/agent.d.ts +224 -3
  9. package/dist/agent/agent.js +561 -55
  10. package/dist/cli/banner.d.ts +80 -0
  11. package/dist/cli/banner.js +232 -0
  12. package/dist/cli/cliPrompt.d.ts +106 -0
  13. package/dist/cli/cliPrompt.js +314 -0
  14. package/dist/cli/commands/_context.d.ts +3 -1
  15. package/dist/cli/commands/_helpers.d.ts +1 -1
  16. package/dist/cli/commands/_helpers.js +6 -6
  17. package/dist/cli/commands/config.d.ts +46 -0
  18. package/dist/cli/commands/config.js +1042 -0
  19. package/dist/cli/commands/guard.js +75 -10
  20. package/dist/cli/commands/init.d.ts +20 -0
  21. package/dist/cli/commands/init.js +64 -0
  22. package/dist/cli/commands/login.d.ts +13 -0
  23. package/dist/cli/commands/login.js +179 -0
  24. package/dist/cli/commands/mcp.d.ts +19 -0
  25. package/dist/cli/commands/mcp.js +286 -0
  26. package/dist/cli/commands/memory.js +2 -2
  27. package/dist/cli/commands/obs.js +22 -22
  28. package/dist/cli/commands/orchestration.js +18 -0
  29. package/dist/cli/commands/session.js +13 -5
  30. package/dist/cli/commands/ui.js +202 -91
  31. package/dist/cli/commands/workflow.d.ts +20 -0
  32. package/dist/cli/commands/workflow.js +368 -51
  33. package/dist/cli/ink/ChatApp.d.ts +206 -0
  34. package/dist/cli/ink/ChatApp.js +493 -0
  35. package/dist/cli/ink/Frame.d.ts +26 -0
  36. package/dist/cli/ink/Frame.js +5 -0
  37. package/dist/cli/ink/Picker.d.ts +65 -0
  38. package/dist/cli/ink/Picker.js +133 -0
  39. package/dist/cli/ink/SlashPalette.d.ts +51 -0
  40. package/dist/cli/ink/SlashPalette.js +136 -0
  41. package/dist/cli/ink/TextField.d.ts +34 -0
  42. package/dist/cli/ink/TextField.js +47 -0
  43. package/dist/cli/ink/WizardApp.d.ts +7 -0
  44. package/dist/cli/ink/WizardApp.js +422 -0
  45. package/dist/cli/ink/ambientChat.d.ts +34 -0
  46. package/dist/cli/ink/ambientChat.js +7 -0
  47. package/dist/cli/ink/consoleCapture.d.ts +11 -0
  48. package/dist/cli/ink/consoleCapture.js +33 -0
  49. package/dist/cli/ink/markdownRender.d.ts +41 -0
  50. package/dist/cli/ink/markdownRender.js +278 -0
  51. package/dist/cli/ink/renderWithResizeClear.d.ts +14 -0
  52. package/dist/cli/ink/renderWithResizeClear.js +33 -0
  53. package/dist/cli/ink/runChat.d.ts +34 -0
  54. package/dist/cli/ink/runChat.js +571 -0
  55. package/dist/cli/ink/runPicker.d.ts +31 -0
  56. package/dist/cli/ink/runPicker.js +139 -0
  57. package/dist/cli/ink/runSlashPalette.d.ts +23 -0
  58. package/dist/cli/ink/runSlashPalette.js +33 -0
  59. package/dist/cli/ink/runWizard.d.ts +22 -0
  60. package/dist/cli/ink/runWizard.js +133 -0
  61. package/dist/cli/ink/stdinHandoff.d.ts +51 -0
  62. package/dist/cli/ink/stdinHandoff.js +78 -0
  63. package/dist/cli/ink/toolFormat.d.ts +73 -0
  64. package/dist/cli/ink/toolFormat.js +180 -0
  65. package/dist/cli/ink/useTerminalSize.d.ts +35 -0
  66. package/dist/cli/ink/useTerminalSize.js +26 -0
  67. package/dist/cli/repl.d.ts +25 -3
  68. package/dist/cli/repl.js +64 -646
  69. package/dist/cli/slashSuggest.d.ts +32 -0
  70. package/dist/cli/slashSuggest.js +146 -0
  71. package/dist/cli/spinner.d.ts +34 -0
  72. package/dist/cli/spinner.js +36 -0
  73. package/dist/cli/statusline.d.ts +67 -0
  74. package/dist/cli/statusline.js +204 -0
  75. package/dist/cli/theme.d.ts +79 -0
  76. package/dist/cli/theme.js +106 -0
  77. package/dist/cli/whereView.d.ts +81 -0
  78. package/dist/cli/whereView.js +245 -0
  79. package/dist/cli/wizard/modelsApi.d.ts +72 -0
  80. package/dist/cli/wizard/modelsApi.js +166 -0
  81. package/dist/cli/wizard/picker.d.ts +202 -0
  82. package/dist/cli/wizard/picker.js +547 -0
  83. package/dist/cli/wizard/providers.d.ts +86 -0
  84. package/dist/cli/wizard/providers.js +190 -0
  85. package/dist/cli/wizard/runner.d.ts +13 -0
  86. package/dist/cli/wizard/runner.js +488 -0
  87. package/dist/cli/wizard/types.d.ts +122 -0
  88. package/dist/cli/wizard/types.js +109 -0
  89. package/dist/config/config.d.ts +52 -0
  90. package/dist/config/config.js +89 -75
  91. package/dist/index.js +215 -206
  92. package/dist/memory/briefing.d.ts +11 -1
  93. package/dist/memory/briefing.js +69 -1
  94. package/dist/memory/consolidation.d.ts +1 -1
  95. package/dist/orchestration/agentRegistry.d.ts +36 -0
  96. package/dist/orchestration/agentRegistry.js +64 -0
  97. package/dist/orchestration/orchestrator.d.ts +7 -0
  98. package/dist/orchestration/orchestrator.js +2 -0
  99. package/dist/orchestration/tools.d.ts +10 -1
  100. package/dist/orchestration/tools.js +48 -4
  101. package/dist/prompt/breadthHint.d.ts +5 -0
  102. package/dist/prompt/breadthHint.js +44 -0
  103. package/dist/prompt/skillCatalog.d.ts +11 -0
  104. package/dist/prompt/skillCatalog.js +134 -0
  105. package/dist/prompt/skillRunner.d.ts +2 -2
  106. package/dist/prompt/skillRunner.js +2 -31
  107. package/dist/prompt/systemPrompt.d.ts +34 -0
  108. package/dist/prompt/systemPrompt.js +128 -108
  109. package/dist/runtime/dangerousCommand.d.ts +53 -0
  110. package/dist/runtime/dangerousCommand.js +105 -0
  111. package/dist/runtime/mcpClient.d.ts +38 -1
  112. package/dist/runtime/mcpClient.js +104 -13
  113. package/dist/runtime/mcpPool.d.ts +162 -0
  114. package/dist/runtime/mcpPool.js +423 -0
  115. package/dist/runtime/mcpUtils.d.ts +3 -1
  116. package/dist/state/goalStore.d.ts +98 -17
  117. package/dist/state/goalStore.js +132 -42
  118. package/dist/state/preferencesStore.d.ts +67 -3
  119. package/dist/state/preferencesStore.js +84 -1
  120. package/dist/state/workflowArtifacts.d.ts +63 -2
  121. package/dist/state/workflowArtifacts.js +120 -8
  122. package/dist/tests/_helpers.d.ts +31 -0
  123. package/dist/tests/_helpers.js +91 -0
  124. package/package.json +12 -5
  125. package/.env.example +0 -109
@@ -0,0 +1,202 @@
1
+ import { type Theme } from '../theme.js';
2
+ /**
3
+ * Internal picker primitive — purpose-built for the wizard / `/config` /
4
+ * `/login` flows.
5
+ *
6
+ * Distinct from `cliPrompt.ts:askChoice` (which backs the LLM-callable
7
+ * `ask_user_choice` tool and is intentionally constrained: 2–4 options,
8
+ * always-on synthetic "Other" row, error envelopes for the agent). This
9
+ * picker has no LLM-tool constraints — N options, optional "Other" row,
10
+ * optional free-text input, optional live-preview callback that returns
11
+ * preview ROWS (rendered INSIDE the picker's frame) instead of writing
12
+ * to stdout.
13
+ *
14
+ * Render contract (atomic frame):
15
+ *
16
+ * 1. Caller passes ALL chrome (title, subtitle, options, footer hint)
17
+ * as fields on `PickerView`. The picker computes the full frame
18
+ * string in one pass and writes it with one `stdout.write`.
19
+ * 2. The picker owns its rendered region for its lifetime. NO call
20
+ * site may write to stdout while the picker is active — preview
21
+ * lines are returned from `onCursorChange` as a string[] that the
22
+ * picker splices into its own frame. (Pattern lifted from
23
+ * `openSrc/codex/codex-rs/tui/src/theme_picker.rs` — preview never
24
+ * writes; the redraw owns the change.)
25
+ * 3. Redraw uses `\x1b[<N>F` (cursor up + col 0) + `\x1b[J` (erase to
26
+ * end of screen) to nuke the previous frame, then writes the new
27
+ * one. No `text + '\n'` off-by-one because we count the actual
28
+ * lines we'll write.
29
+ *
30
+ * Why a separate file (not just an extension of `cliPrompt.ts`)? The
31
+ * LLM-tool contract for `ask_user_choice` is explicit ("2-4 options
32
+ * with mutually exclusive labels, always an Other fallback"), and
33
+ * widening it would weaken the constraint the system prompt teaches
34
+ * the model to follow. Internal CLI flows have different requirements
35
+ * (7 providers in a list, no "Other" for theme picker, free-text-only
36
+ * for API-key entry). Keep them in separate primitives.
37
+ */
38
+ export interface PickerRow {
39
+ /** Stable id used in the resolved result. */
40
+ id: string;
41
+ /** Human-readable left-aligned label. */
42
+ label: string;
43
+ /** Right-aligned value column (current setting, hint text, status). Optional. */
44
+ value?: string;
45
+ /** Sub-line shown muted under the label. Optional. */
46
+ description?: string;
47
+ /** When true, the row is shown but not selectable (separator-like). */
48
+ disabled?: boolean;
49
+ }
50
+ export interface PickFromListOptions {
51
+ /** Bold title rendered at the top of the frame (e.g. "Theme"). */
52
+ title: string;
53
+ /** Muted subtitle under the title (e.g. "Pick a color palette."). Optional. */
54
+ subtitle?: string;
55
+ /** Right-side chip in the title bar (e.g. "Step 1 of 6"). Optional. */
56
+ badge?: string;
57
+ /** Footer hint line (e.g. "↑/↓ navigate · ENTER confirm · q to cancel"). Defaults are sensible. */
58
+ footer?: string;
59
+ /** Picker rows. No upper limit; height clamps automatically. */
60
+ rows: PickerRow[];
61
+ /** Initial cursor index. Clamped to [0, rows.length - 1]. */
62
+ initialCursor?: number;
63
+ /** When true, an "Other" row is appended that drops to free-text entry. */
64
+ allowOther?: boolean;
65
+ /** Label for the appended Other row (default: "Other"). */
66
+ otherLabel?: string;
67
+ /** Description for the Other row. */
68
+ otherDescription?: string;
69
+ /** Pre-fill the Other free-text buffer. Used by env-var-derived defaults. */
70
+ prefilledOther?: string;
71
+ /**
72
+ * Live-preview hook. Fires after a real cursor move only. Returns an
73
+ * array of preview lines to render INSIDE the picker frame (above the
74
+ * footer). Returning `undefined` or `[]` means "no preview".
75
+ *
76
+ * The picker takes care of the redraw — the callback must NOT write
77
+ * to stdout. Mirrors `openSrc/codex/codex-rs/tui/src/theme_picker.rs`
78
+ * (preview returns a row spec, never `stdout.write`).
79
+ */
80
+ onCursorChange?: (cursorId: string, cursorIndex: number) => string[] | undefined;
81
+ /** Theme for chrome coloring; defaults to `dark`. */
82
+ theme?: Theme;
83
+ /**
84
+ * When true, the frame is erased on close so the next picker (or
85
+ * print) lands at the same screen position. Wizard sets this so
86
+ * each step REPLACES the previous frame instead of stacking
87
+ * downward on screen.
88
+ */
89
+ eraseOnClose?: boolean;
90
+ }
91
+ export type PickFromListResult = {
92
+ kind: 'pick';
93
+ id: string;
94
+ } | {
95
+ kind: 'other';
96
+ text: string;
97
+ } | {
98
+ kind: 'cancelled';
99
+ };
100
+ /**
101
+ * Free-text-only entry. Used by the wizard's API-key step.
102
+ *
103
+ * Renders a single masked input row inside a framed panel. Same redraw
104
+ * contract as `pickFromList` — atomic frames, owns its region.
105
+ */
106
+ export interface PromptTextOptions {
107
+ title: string;
108
+ subtitle?: string;
109
+ badge?: string;
110
+ /** Right-side chip in the title bar (e.g. "openai · cloud"). */
111
+ /** Pre-filled buffer (e.g. value from env). ENTER accepts as-is. */
112
+ prefilled?: string;
113
+ /** When true, render input as `·······abcd` (mask all but last 4). */
114
+ mask?: boolean;
115
+ /** Placeholder shown muted when the input is empty. */
116
+ placeholder?: string;
117
+ /** Footer hint. */
118
+ footer?: string;
119
+ /** Optional validator. Return undefined to accept; return string to show as an inline error. */
120
+ validate?: (raw: string) => string | undefined;
121
+ /** Theme for chrome coloring. */
122
+ theme?: Theme;
123
+ /** See PickFromListOptions.eraseOnClose. */
124
+ eraseOnClose?: boolean;
125
+ }
126
+ export type PromptTextResult = {
127
+ kind: 'accept';
128
+ text: string;
129
+ } | {
130
+ kind: 'cancelled';
131
+ };
132
+ export declare function isInternalPickerActive(): boolean;
133
+ interface FrameInputs {
134
+ theme: Theme;
135
+ title: string;
136
+ subtitle?: string;
137
+ badge?: string;
138
+ bodyLines: string[];
139
+ previewLines?: string[];
140
+ footer: string;
141
+ width: number;
142
+ }
143
+ /**
144
+ * Compute the full picker frame as a single string. Pure function so
145
+ * tests can assert on the exact output without driving a TTY.
146
+ *
147
+ * Layout (single column for now — wide-terminal two-column comes in a
148
+ * follow-up):
149
+ *
150
+ * ┌─ <title> ─────────────────────── <badge> ─┐
151
+ * │ <subtitle> │
152
+ * │ │
153
+ * │ <body line 1> │
154
+ * │ <body line 2> │
155
+ * │ ... │
156
+ * │ │ (preview block if present)
157
+ * │ <preview line 1> │
158
+ * │ <preview line 2> │
159
+ * │ │
160
+ * │ <footer> │
161
+ * └───────────────────────────────────────────┘
162
+ */
163
+ export declare function renderFrame(f: FrameInputs): string;
164
+ /** ANSI-aware right-pad. Strips ANSI sequences when counting width. */
165
+ declare function padRightVisible(s: string, w: number): string;
166
+ declare function visibleLength(s: string): number;
167
+ declare function stripAnsi(s: string): string;
168
+ /** Simple word-wrap; doesn't try to be ANSI-aware (subtitle takes plain text). */
169
+ declare function wrap(s: string, w: number): string[];
170
+ declare function formatBodyRow(t: Theme, row: PickerRow, isSelected: boolean, valueColWidth: number, inner: number): string[];
171
+ export declare function pickFromList(opts: PickFromListOptions): Promise<PickFromListResult>;
172
+ declare function computeValueColumn(rows: PickerRow[]): number;
173
+ declare function defaultFooter(phase: 'pick' | 'other', allowOther: boolean): string;
174
+ export declare function promptText(opts: PromptTextOptions): Promise<PromptTextResult>;
175
+ export interface FramedInputOptions {
176
+ /**
177
+ * When true (default), the frame is **erased** when the picker
178
+ * closes — the cursor ends up where the frame started, so the next
179
+ * print overwrites the same screen region. Every caller in the
180
+ * wizard / `/config` / `/login` flows wants this behaviour:
181
+ * pickers are modal, not transcript-y.
182
+ *
183
+ * Set to false explicitly to leave the frame on screen as
184
+ * scrollback after close (the cursor lands one line below).
185
+ * No current callers use this; reserved for future surfaces
186
+ * (e.g. an `/agents` picker where the user wants the list to
187
+ * stay visible).
188
+ */
189
+ eraseOnClose?: boolean;
190
+ }
191
+ /** Pure helpers exposed for unit tests. */
192
+ export declare const __test: {
193
+ renderFrame: typeof renderFrame;
194
+ formatBodyRow: typeof formatBodyRow;
195
+ visibleLength: typeof visibleLength;
196
+ stripAnsi: typeof stripAnsi;
197
+ wrap: typeof wrap;
198
+ padRightVisible: typeof padRightVisible;
199
+ computeValueColumn: typeof computeValueColumn;
200
+ defaultFooter: typeof defaultFooter;
201
+ };
202
+ export {};