@ironbee-ai/cli 0.12.0 → 0.13.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 (138) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +3 -2
  3. package/dist/assets/banner.txt +1 -1
  4. package/dist/clients/claude/hooks/session-status.d.ts.map +1 -1
  5. package/dist/clients/claude/hooks/session-status.js +8 -2
  6. package/dist/clients/claude/hooks/session-status.js.map +1 -1
  7. package/dist/clients/claude/index.d.ts.map +1 -1
  8. package/dist/clients/claude/index.js +5 -0
  9. package/dist/clients/claude/index.js.map +1 -1
  10. package/dist/clients/cursor/index.d.ts.map +1 -1
  11. package/dist/clients/cursor/index.js +6 -0
  12. package/dist/clients/cursor/index.js.map +1 -1
  13. package/dist/clients/registry.d.ts +8 -9
  14. package/dist/clients/registry.d.ts.map +1 -1
  15. package/dist/clients/registry.js +13 -11
  16. package/dist/clients/registry.js.map +1 -1
  17. package/dist/commands/install.d.ts.map +1 -1
  18. package/dist/commands/install.js +4 -5
  19. package/dist/commands/install.js.map +1 -1
  20. package/dist/commands/register.d.ts +0 -1
  21. package/dist/commands/register.d.ts.map +1 -1
  22. package/dist/commands/register.js +7 -27
  23. package/dist/commands/register.js.map +1 -1
  24. package/dist/commands/uninstall.d.ts +2 -3
  25. package/dist/commands/uninstall.d.ts.map +1 -1
  26. package/dist/commands/uninstall.js +3 -4
  27. package/dist/commands/uninstall.js.map +1 -1
  28. package/dist/commands/unregister.d.ts +0 -1
  29. package/dist/commands/unregister.d.ts.map +1 -1
  30. package/dist/commands/unregister.js +3 -24
  31. package/dist/commands/unregister.js.map +1 -1
  32. package/dist/index.js +33 -15
  33. package/dist/index.js.map +1 -1
  34. package/dist/lib/fs-prune.d.ts +20 -0
  35. package/dist/lib/fs-prune.d.ts.map +1 -0
  36. package/dist/lib/fs-prune.js +72 -0
  37. package/dist/lib/fs-prune.js.map +1 -0
  38. package/dist/lib/projects-registry.d.ts +6 -13
  39. package/dist/lib/projects-registry.d.ts.map +1 -1
  40. package/dist/lib/projects-registry.js +11 -46
  41. package/dist/lib/projects-registry.js.map +1 -1
  42. package/dist/tui/command.d.ts +18 -0
  43. package/dist/tui/command.d.ts.map +1 -0
  44. package/dist/tui/command.js +87 -0
  45. package/dist/tui/command.js.map +1 -0
  46. package/dist/tui/config/area.d.ts +6 -0
  47. package/dist/tui/config/area.d.ts.map +1 -0
  48. package/dist/tui/config/area.js +16 -0
  49. package/dist/tui/config/area.js.map +1 -0
  50. package/dist/tui/config/docs.d.ts +28 -0
  51. package/dist/tui/config/docs.d.ts.map +1 -0
  52. package/dist/tui/config/docs.js +68 -0
  53. package/dist/tui/config/docs.js.map +1 -0
  54. package/dist/tui/config/edit.d.ts +36 -0
  55. package/dist/tui/config/edit.d.ts.map +1 -0
  56. package/dist/tui/config/edit.js +69 -0
  57. package/dist/tui/config/edit.js.map +1 -0
  58. package/dist/tui/config/introspect.d.ts +58 -0
  59. package/dist/tui/config/introspect.d.ts.map +1 -0
  60. package/dist/tui/config/introspect.js +93 -0
  61. package/dist/tui/config/introspect.js.map +1 -0
  62. package/dist/tui/config/schema.d.ts +81 -0
  63. package/dist/tui/config/schema.d.ts.map +1 -0
  64. package/dist/tui/config/schema.js +534 -0
  65. package/dist/tui/config/schema.js.map +1 -0
  66. package/dist/tui/config/tree.d.ts +39 -0
  67. package/dist/tui/config/tree.d.ts.map +1 -0
  68. package/dist/tui/config/tree.js +59 -0
  69. package/dist/tui/config/tree.js.map +1 -0
  70. package/dist/tui/config/value.d.ts +75 -0
  71. package/dist/tui/config/value.d.ts.map +1 -0
  72. package/dist/tui/config/value.js +228 -0
  73. package/dist/tui/config/value.js.map +1 -0
  74. package/dist/tui/config/view.d.ts +13 -0
  75. package/dist/tui/config/view.d.ts.map +1 -0
  76. package/dist/tui/config/view.js +423 -0
  77. package/dist/tui/config/view.js.map +1 -0
  78. package/dist/tui/import/area.d.ts +11 -0
  79. package/dist/tui/import/area.d.ts.map +1 -0
  80. package/dist/tui/import/area.js +202 -0
  81. package/dist/tui/import/area.js.map +1 -0
  82. package/dist/tui/index.d.ts +9 -0
  83. package/dist/tui/index.d.ts.map +1 -0
  84. package/dist/tui/index.js +14 -0
  85. package/dist/tui/index.js.map +1 -0
  86. package/dist/tui/platforms/area.d.ts +12 -0
  87. package/dist/tui/platforms/area.d.ts.map +1 -0
  88. package/dist/tui/platforms/area.js +228 -0
  89. package/dist/tui/platforms/area.js.map +1 -0
  90. package/dist/tui/projects/area.d.ts +26 -0
  91. package/dist/tui/projects/area.d.ts.map +1 -0
  92. package/dist/tui/projects/area.js +588 -0
  93. package/dist/tui/projects/area.js.map +1 -0
  94. package/dist/tui/queue/area.d.ts +11 -0
  95. package/dist/tui/queue/area.d.ts.map +1 -0
  96. package/dist/tui/queue/area.js +338 -0
  97. package/dist/tui/queue/area.js.map +1 -0
  98. package/dist/tui/queue/read.d.ts +49 -0
  99. package/dist/tui/queue/read.d.ts.map +1 -0
  100. package/dist/tui/queue/read.js +261 -0
  101. package/dist/tui/queue/read.js.map +1 -0
  102. package/dist/tui/sessions/area.d.ts +10 -0
  103. package/dist/tui/sessions/area.d.ts.map +1 -0
  104. package/dist/tui/sessions/area.js +266 -0
  105. package/dist/tui/sessions/area.js.map +1 -0
  106. package/dist/tui/sessions/read.d.ts +79 -0
  107. package/dist/tui/sessions/read.d.ts.map +1 -0
  108. package/dist/tui/sessions/read.js +202 -0
  109. package/dist/tui/sessions/read.js.map +1 -0
  110. package/dist/tui/shell/area.d.ts +47 -0
  111. package/dist/tui/shell/area.d.ts.map +1 -0
  112. package/dist/tui/shell/area.js +13 -0
  113. package/dist/tui/shell/area.js.map +1 -0
  114. package/dist/tui/shell/frame.d.ts +23 -0
  115. package/dist/tui/shell/frame.d.ts.map +1 -0
  116. package/dist/tui/shell/frame.js +91 -0
  117. package/dist/tui/shell/frame.js.map +1 -0
  118. package/dist/tui/shell/registry.d.ts +11 -0
  119. package/dist/tui/shell/registry.d.ts.map +1 -0
  120. package/dist/tui/shell/registry.js +29 -0
  121. package/dist/tui/shell/registry.js.map +1 -0
  122. package/dist/tui/shell/rerender.d.ts +16 -0
  123. package/dist/tui/shell/rerender.d.ts.map +1 -0
  124. package/dist/tui/shell/rerender.js +34 -0
  125. package/dist/tui/shell/rerender.js.map +1 -0
  126. package/dist/tui/shell/session.d.ts +75 -0
  127. package/dist/tui/shell/session.d.ts.map +1 -0
  128. package/dist/tui/shell/session.js +333 -0
  129. package/dist/tui/shell/session.js.map +1 -0
  130. package/dist/tui/shell/shell.d.ts +16 -0
  131. package/dist/tui/shell/shell.d.ts.map +1 -0
  132. package/dist/tui/shell/shell.js +213 -0
  133. package/dist/tui/shell/shell.js.map +1 -0
  134. package/dist/tui/shell/util.d.ts +18 -0
  135. package/dist/tui/shell/util.d.ts.map +1 -0
  136. package/dist/tui/shell/util.js +31 -0
  137. package/dist/tui/shell/util.js.map +1 -0
  138. package/package.json +3 -1
@@ -0,0 +1,333 @@
1
+ "use strict";
2
+ /**
3
+ * IronBee — TUI shell: session
4
+ *
5
+ * Cross-area state + shared modal helpers. One session per `ironbee tui` run.
6
+ *
7
+ * - `projectDir` — the resolved project directory all areas read/write against.
8
+ * - rerender flag — any area that changes artifact-affecting config calls
9
+ * `markRerenderNeeded()`; the app re-renders client artifacts
10
+ * ONCE on exit (never mid-session — install stdout would
11
+ * corrupt the screen).
12
+ * - `isModalOpen()` — true while a shared modal (prompt/confirm/message/pick) is
13
+ * up, so the shell's global Esc=back doesn't fire underneath it.
14
+ * - modal helpers — prompt / confirm / message / pick, reused by every area so
15
+ * they don't each reimplement (and so modal tracking + focus
16
+ * restore are uniform).
17
+ */
18
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ var desc = Object.getOwnPropertyDescriptor(m, k);
21
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
+ desc = { enumerable: true, get: function() { return m[k]; } };
23
+ }
24
+ Object.defineProperty(o, k2, desc);
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || (function () {
35
+ var ownKeys = function(o) {
36
+ ownKeys = Object.getOwnPropertyNames || function (o) {
37
+ var ar = [];
38
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
39
+ return ar;
40
+ };
41
+ return ownKeys(o);
42
+ };
43
+ return function (mod) {
44
+ if (mod && mod.__esModule) return mod;
45
+ var result = {};
46
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
47
+ __setModuleDefault(result, mod);
48
+ return result;
49
+ };
50
+ })();
51
+ Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.TuiSession = void 0;
53
+ const blessed = __importStar(require("blessed"));
54
+ const util_1 = require("./util");
55
+ class TuiSession {
56
+ constructor(screen, projectDir) {
57
+ /** Project dirs whose artifacts need re-rendering on exit. A Set (not a
58
+ * bool) because the active project is switchable — the user can edit
59
+ * artifact-affecting config across several projects in one session. */
60
+ this.rerenderDirs = new Set();
61
+ this.modalOpen = false;
62
+ this.screen = screen;
63
+ this.launchDir = projectDir;
64
+ this.activeProjectDir = projectDir;
65
+ }
66
+ /** The active project — what every project-scoped area reads at mount. */
67
+ get projectDir() {
68
+ return this.activeProjectDir;
69
+ }
70
+ /** Switch the active project (in-memory, TUI-session only). */
71
+ setProjectDir(dir) {
72
+ this.activeProjectDir = dir;
73
+ }
74
+ /** Flag `dir`'s artifacts for re-render on exit. */
75
+ markRerenderNeeded(dir) {
76
+ this.rerenderDirs.add(dir);
77
+ }
78
+ isRerenderNeeded() {
79
+ return this.rerenderDirs.size > 0;
80
+ }
81
+ /** Drain the set of project dirs needing a rerender (clears it). */
82
+ rerenderProjects() {
83
+ const dirs = [...this.rerenderDirs];
84
+ this.rerenderDirs.clear();
85
+ return dirs;
86
+ }
87
+ isModalOpen() {
88
+ return this.modalOpen;
89
+ }
90
+ /** Capture focus + flag a modal as open; returns the restore function. */
91
+ openModal() {
92
+ const prev = this.screen.focused;
93
+ this.modalOpen = true;
94
+ return () => {
95
+ // Only restore focus to `prev` if it's still attached. If the area
96
+ // that opened the modal was torn down meanwhile, `prev` is a detached
97
+ // widget — focusing it would route keystrokes to a dead element while
98
+ // a different screen is shown.
99
+ if (prev !== undefined && prev !== null && prev.detached !== true) {
100
+ prev.focus();
101
+ }
102
+ this.screen.render();
103
+ // Clear the flag on the NEXT tick, not synchronously: the keypress
104
+ // that dismissed the modal (e.g. Esc) is still being dispatched, and
105
+ // the shell's global Esc=back / q=quit handlers check this flag — we
106
+ // want them to see "modal still open" for that keypress and no-op.
107
+ setImmediate(() => {
108
+ this.modalOpen = false;
109
+ });
110
+ };
111
+ }
112
+ /** Transient auto-dismissing notice (3s or any key). */
113
+ message(text) {
114
+ const restore = this.openModal();
115
+ const msg = blessed.message({
116
+ parent: this.screen,
117
+ top: "center",
118
+ left: "center",
119
+ width: "60%",
120
+ height: "shrink",
121
+ border: { type: "line" },
122
+ tags: true,
123
+ style: { border: { fg: "yellow" } },
124
+ });
125
+ msg.display((0, util_1.escapeTags)(text), 3, () => {
126
+ msg.destroy();
127
+ restore();
128
+ });
129
+ }
130
+ /** Single-line text input. `cb` gets the entered string, or `null` on cancel (Esc). */
131
+ prompt(label, value, cb) {
132
+ const restore = this.openModal();
133
+ const box = blessed.prompt({
134
+ parent: this.screen,
135
+ top: "center",
136
+ left: "center",
137
+ width: "72%",
138
+ height: "shrink",
139
+ border: { type: "line" },
140
+ tags: true,
141
+ keys: true,
142
+ style: { border: { fg: "green" } },
143
+ });
144
+ box.input(label, value, (_err, raw) => {
145
+ box.destroy();
146
+ restore();
147
+ cb(typeof raw === "string" ? raw : null);
148
+ });
149
+ this.screen.render();
150
+ }
151
+ /**
152
+ * Yes/no question. `cb` gets `true` for yes. Rendered as an arrow-navigable
153
+ * Yes/No list (NOT blessed's `question` widget, whose OK/Cancel buttons only
154
+ * respond to y/n/enter/esc keypresses, not ↑/↓ selection). Defaults to "No"
155
+ * (safer for the destructive confirms — uninstall / clear / purge); `Esc`/`q`
156
+ * cancels = no.
157
+ */
158
+ confirm(question, cb) {
159
+ const restore = this.openModal();
160
+ const box = blessed.box({
161
+ parent: this.screen,
162
+ top: "center",
163
+ left: "center",
164
+ width: "60%",
165
+ height: 8,
166
+ border: { type: "line" },
167
+ tags: true,
168
+ style: { border: { fg: "cyan" } },
169
+ content: ` ${(0, util_1.escapeTags)(question)}\n\n {gray-fg}↑/↓ choose · Enter confirm · Esc cancel{/gray-fg}`,
170
+ });
171
+ const choices = blessed.list({
172
+ parent: box,
173
+ bottom: 0,
174
+ left: 1,
175
+ right: 1,
176
+ height: 2,
177
+ keys: true,
178
+ tags: true,
179
+ style: { selected: { bg: "blue", fg: "white" } },
180
+ items: ["Yes", "No"],
181
+ });
182
+ choices.select(1); // default to No
183
+ const finish = (yes) => {
184
+ box.destroy();
185
+ restore();
186
+ cb(yes);
187
+ };
188
+ choices.on("select", (_item, idx) => finish(idx === 0));
189
+ choices.key(["escape", "q"], () => finish(false));
190
+ choices.focus();
191
+ this.screen.render();
192
+ }
193
+ /** Pick one of `items`. `cb` gets the chosen index, or `-1` on cancel. */
194
+ pick(title, items, cb) {
195
+ const restore = this.openModal();
196
+ const list = blessed.list({
197
+ parent: this.screen,
198
+ top: "center",
199
+ left: "center",
200
+ width: "50%",
201
+ height: items.length + 2,
202
+ border: { type: "line" },
203
+ label: ` ${title} `,
204
+ tags: true,
205
+ keys: true,
206
+ style: { selected: { bg: "blue", fg: "white" }, border: { fg: "yellow" } },
207
+ items: items.map((s) => (0, util_1.escapeTags)(s)),
208
+ });
209
+ list.on("select", (_item, idx) => {
210
+ list.destroy();
211
+ restore();
212
+ cb(idx);
213
+ });
214
+ list.key(["escape", "q"], () => {
215
+ list.destroy();
216
+ restore();
217
+ cb(-1);
218
+ });
219
+ list.focus();
220
+ this.screen.render();
221
+ }
222
+ /**
223
+ * Run a synchronous `fn` with stdout/stderr suppressed (discarded), then
224
+ * restored. For calling noisy library functions (loggers!) during a render
225
+ * without their output leaking onto — and corrupting — the blessed screen.
226
+ */
227
+ silently(fn) {
228
+ const origOut = process.stdout.write;
229
+ const origErr = process.stderr.write;
230
+ const noop = () => true;
231
+ process.stdout.write = noop;
232
+ process.stderr.write = noop;
233
+ try {
234
+ return fn();
235
+ }
236
+ finally {
237
+ process.stdout.write = origOut;
238
+ process.stderr.write = origErr;
239
+ }
240
+ }
241
+ /** Bind scroll (↑/↓/PgUp/PgDn) + close (Esc/Enter/q) keys to a pane box. */
242
+ bindPaneKeys(box, onClose) {
243
+ box.key(["up", "k"], () => { box.scroll(-1); this.screen.render(); });
244
+ box.key(["down", "j"], () => { box.scroll(1); this.screen.render(); });
245
+ box.key(["pageup"], () => { box.scroll(-10); this.screen.render(); });
246
+ box.key(["pagedown"], () => { box.scroll(10); this.screen.render(); });
247
+ box.key(["escape", "enter", "q"], () => { box.destroy(); onClose(); });
248
+ box.focus();
249
+ }
250
+ /** Show `content` (must be blessed-tag-safe) in a scrollable modal pane. */
251
+ showPane(title, content) {
252
+ const restore = this.openModal();
253
+ const box = blessed.box({
254
+ parent: this.screen,
255
+ top: "center",
256
+ left: "center",
257
+ width: "82%",
258
+ height: "82%",
259
+ border: { type: "line" },
260
+ label: ` ${title} `,
261
+ tags: true,
262
+ scrollable: true,
263
+ alwaysScroll: true,
264
+ scrollbar: { ch: " " },
265
+ style: { border: { fg: "cyan" } },
266
+ content: `${content}\n\n{gray-fg}[ ↑/↓ scroll · Esc/Enter close ]{/gray-fg}`,
267
+ });
268
+ this.bindPaneKeys(box, restore);
269
+ this.screen.render();
270
+ }
271
+ /**
272
+ * Run `fn` in the FOREGROUND, blocking TUI interaction until it finishes:
273
+ * shows a "running" modal, captures everything `fn` writes to stdout/stderr,
274
+ * then shows the captured output (plus any string `fn` returns) in a
275
+ * scrollable pane. For install / uninstall / drain / import — operations the
276
+ * user wants to watch to completion. Resolves when the pane is closed.
277
+ */
278
+ runWithOutput(label, fn) {
279
+ return new Promise((resolve) => {
280
+ const restore = this.openModal();
281
+ const box = blessed.box({
282
+ parent: this.screen,
283
+ top: "center",
284
+ left: "center",
285
+ width: "82%",
286
+ height: "82%",
287
+ border: { type: "line" },
288
+ label: ` ${label} `,
289
+ tags: true,
290
+ scrollable: true,
291
+ alwaysScroll: true,
292
+ scrollbar: { ch: " " },
293
+ style: { border: { fg: "green" } },
294
+ content: "{gray-fg}Running… (the TUI is blocked until this finishes){/gray-fg}",
295
+ });
296
+ box.focus();
297
+ this.screen.render();
298
+ const chunks = [];
299
+ const origOut = process.stdout.write;
300
+ const origErr = process.stderr.write;
301
+ const capture = (chunk) => {
302
+ chunks.push(typeof chunk === "string" ? chunk : String(chunk));
303
+ return true;
304
+ };
305
+ process.stdout.write = capture;
306
+ process.stderr.write = capture;
307
+ const present = (extra) => {
308
+ process.stdout.write = origOut;
309
+ process.stderr.write = origErr;
310
+ let out = (0, util_1.stripAnsi)(chunks.join(""));
311
+ if (extra.length > 0) {
312
+ out += (out.length > 0 ? "\n" : "") + extra;
313
+ }
314
+ out = out.trim();
315
+ if (out.length === 0) {
316
+ out = "(done — no output)";
317
+ }
318
+ box.setContent(`${(0, util_1.escapeTags)(out)}\n\n{gray-fg}[ ↑/↓ scroll · Esc/Enter close ]{/gray-fg}`);
319
+ box.setScroll(0);
320
+ this.bindPaneKeys(box, () => {
321
+ restore();
322
+ resolve();
323
+ });
324
+ this.screen.render();
325
+ };
326
+ Promise.resolve()
327
+ .then(() => fn())
328
+ .then((ret) => present(typeof ret === "string" ? ret : ""), (e) => present(`✗ ${e instanceof Error ? e.message : String(e)}`));
329
+ });
330
+ }
331
+ }
332
+ exports.TuiSession = TuiSession;
333
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/tui/shell/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * IronBee — TUI shell
3
+ *
4
+ * Owns the screen frame (breadcrumb + content + status), the home menu (the
5
+ * area registry), and routing between home and exactly one mounted area.
6
+ * Global keys: Esc = back to home (when in an area), q / Ctrl-C = quit. Both
7
+ * no-op while a shared modal is open (the deferred modal-flag flip in
8
+ * `TuiSession.openModal` keeps the dismissing keypress from leaking here).
9
+ *
10
+ * Resolves when the user quits. The caller (command.ts) runs the one-shot
11
+ * artifact rerender afterwards if any area flagged it.
12
+ */
13
+ import { TuiSession } from "./session";
14
+ /** Run the TUI shell. `initialAreaId` deep-links straight into an area. */
15
+ export declare function runShell(session: TuiSession, initialAreaId?: string): Promise<void>;
16
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../../src/tui/shell/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAoCvC,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqInF"}
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /**
3
+ * IronBee — TUI shell
4
+ *
5
+ * Owns the screen frame (breadcrumb + content + status), the home menu (the
6
+ * area registry), and routing between home and exactly one mounted area.
7
+ * Global keys: Esc = back to home (when in an area), q / Ctrl-C = quit. Both
8
+ * no-op while a shared modal is open (the deferred modal-flag flip in
9
+ * `TuiSession.openModal` keeps the dismissing keypress from leaking here).
10
+ *
11
+ * Resolves when the user quits. The caller (command.ts) runs the one-shot
12
+ * artifact rerender afterwards if any area flagged it.
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.runShell = runShell;
49
+ const child_process_1 = require("child_process");
50
+ const fs_1 = require("fs");
51
+ const path_1 = require("path");
52
+ const blessed = __importStar(require("blessed"));
53
+ const frame_1 = require("./frame");
54
+ const registry_1 = require("./registry");
55
+ const HOME_STATUS = " {bold}↑/↓{/bold} move {bold}Enter{/bold} open {bold}u{/bold} update CLI {bold}q{/bold} quit";
56
+ /**
57
+ * Self-update via npm. This genuinely shells out — there's no in-process way to
58
+ * npm-install a new global version — so it's the one operation that spawns a
59
+ * child. `2>&1` folds npm's progress (which it writes to stderr) into the
60
+ * captured stdout. Blocks the event loop until npm finishes (acceptable: rare,
61
+ * one-shot, and the "Running…" modal is already on screen).
62
+ */
63
+ function runUpdate() {
64
+ const cmd = "npm install -g @ironbee-ai/cli@latest 2>&1";
65
+ try {
66
+ const out = (0, child_process_1.execSync)(cmd, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
67
+ return `${out}\n✓ Update complete. Restart any running editor / agent sessions to pick it up.`;
68
+ }
69
+ catch (e) {
70
+ const err = e;
71
+ return `${err.stdout ?? ""}${err.stderr ?? ""}\n✗ Update failed: ${err.message ?? String(e)}`;
72
+ }
73
+ }
74
+ /** Read the ASCII brand banner (copied to dist/assets at build time). `""` if absent. */
75
+ function readBanner() {
76
+ const bannerPath = (0, path_1.join)(__dirname, "..", "..", "assets", "banner.txt");
77
+ if (!(0, fs_1.existsSync)(bannerPath)) {
78
+ return "";
79
+ }
80
+ try {
81
+ return (0, fs_1.readFileSync)(bannerPath, "utf-8").replace(/\s+$/, "");
82
+ }
83
+ catch {
84
+ return "";
85
+ }
86
+ }
87
+ /** Run the TUI shell. `initialAreaId` deep-links straight into an area. */
88
+ function runShell(session, initialAreaId) {
89
+ return new Promise((resolve) => {
90
+ const screen = session.screen;
91
+ const frame = (0, frame_1.buildFrame)(screen, () => session.projectDir);
92
+ let currentHandle = null;
93
+ let currentParts = ["IronBee"];
94
+ function setCrumb(parts) {
95
+ currentParts = parts;
96
+ frame.setBreadcrumb(parts);
97
+ }
98
+ const banner = readBanner();
99
+ const bannerHeight = banner.length > 0 ? banner.split("\n").length + 1 : 0;
100
+ const bannerBox = banner.length > 0
101
+ ? blessed.box({
102
+ parent: frame.content,
103
+ top: 0,
104
+ left: 0,
105
+ width: "100%",
106
+ height: bannerHeight,
107
+ tags: true,
108
+ style: { fg: "yellow" },
109
+ content: banner,
110
+ })
111
+ : undefined;
112
+ const home = blessed.list({
113
+ parent: frame.content,
114
+ top: bannerHeight,
115
+ left: 0,
116
+ width: "100%",
117
+ height: `100%-${bannerHeight}`,
118
+ border: { type: "line" },
119
+ label: " IronBee TUI ",
120
+ tags: true,
121
+ keys: true,
122
+ mouse: false,
123
+ scrollbar: { ch: " " },
124
+ style: { selected: { bg: "blue", fg: "white" }, border: { fg: "cyan" } },
125
+ items: registry_1.AREAS.map((a) => `{bold}${a.title}{/bold} {gray-fg}— ${a.summary}{/gray-fg}`),
126
+ });
127
+ function goHome() {
128
+ // Show + focus home BEFORE tearing the area down. blessed runs
129
+ // `rewindFocus()` when the *currently focused* element is destroyed,
130
+ // and over repeated mount/unmount cycles its focus history can carry
131
+ // stale (already-destroyed) area lists — so destroying the focused
132
+ // area list could leave focus dangling on an old list, routing keys
133
+ // to it even though home is on screen. Moving focus to home first
134
+ // means the area widgets are no longer `screen.focused` when removed,
135
+ // so rewindFocus never fires.
136
+ if (bannerBox !== undefined) {
137
+ bannerBox.show();
138
+ }
139
+ home.show();
140
+ home.setFront();
141
+ home.focus();
142
+ if (currentHandle !== null) {
143
+ currentHandle.unmount();
144
+ currentHandle = null;
145
+ }
146
+ setCrumb(["IronBee"]);
147
+ frame.setStatus(HOME_STATUS);
148
+ home.focus(); // re-assert after teardown, belt-and-suspenders
149
+ screen.render();
150
+ }
151
+ function quitApp() {
152
+ if (currentHandle !== null) {
153
+ currentHandle.unmount();
154
+ currentHandle = null;
155
+ }
156
+ screen.destroy();
157
+ resolve();
158
+ }
159
+ function mountArea(area) {
160
+ if (bannerBox !== undefined) {
161
+ bannerBox.hide();
162
+ }
163
+ home.hide();
164
+ setCrumb(["IronBee", area.title]);
165
+ const ctx = {
166
+ screen,
167
+ container: frame.content,
168
+ session,
169
+ back: goHome,
170
+ quit: quitApp,
171
+ setStatus: frame.setStatus,
172
+ setActiveProject: (dir) => {
173
+ session.setProjectDir(dir);
174
+ // refresh breadcrumb so the new active project shows immediately
175
+ frame.setBreadcrumb(currentParts);
176
+ screen.render();
177
+ },
178
+ };
179
+ currentHandle = area.mount(ctx);
180
+ screen.render();
181
+ }
182
+ home.on("select", (_item, idx) => {
183
+ if (idx >= 0 && idx < registry_1.AREAS.length) {
184
+ mountArea(registry_1.AREAS[idx]);
185
+ }
186
+ });
187
+ home.key(["u"], () => {
188
+ void session.runWithOutput("Update IronBee CLI", () => runUpdate());
189
+ });
190
+ screen.key(["q", "C-c"], () => {
191
+ if (session.isModalOpen()) {
192
+ return;
193
+ }
194
+ quitApp();
195
+ });
196
+ screen.key(["escape"], () => {
197
+ if (session.isModalOpen()) {
198
+ return;
199
+ }
200
+ if (currentHandle !== null) {
201
+ goHome();
202
+ }
203
+ });
204
+ goHome();
205
+ if (initialAreaId !== undefined) {
206
+ const area = (0, registry_1.findArea)(initialAreaId);
207
+ if (area !== undefined) {
208
+ mountArea(area);
209
+ }
210
+ }
211
+ });
212
+ }
213
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../../src/tui/shell/shell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * IronBee — TUI shell: small shared helpers (blessed-tag escaping, clamp, ANSI strip).
3
+ */
4
+ /**
5
+ * Escape blessed tag braces so arbitrary text/JSON renders literally.
6
+ *
7
+ * MUST be a single pass: chaining `.replace(/\{/, "{open}").replace(/\}/, "{close}")`
8
+ * is buggy — the first pass injects `}` (inside `{open}`) which the second pass
9
+ * then corrupts into `{open{close}`, and blessed renders that as the literal text
10
+ * `{open}`. One regex with a callback (same as blessed's own `helpers.escape`)
11
+ * never re-processes substituted output.
12
+ */
13
+ export declare function escapeTags(s: string): string;
14
+ /** Clamp `n` into `[lo, hi]`. */
15
+ export declare function clamp(n: number, lo: number, hi: number): number;
16
+ /** Strip ANSI CSI escape sequences (captured console output → plain text for a pane). */
17
+ export declare function stripAnsi(s: string): string;
18
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../src/tui/shell/util.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,iCAAiC;AACjC,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/D;AAKD,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3C"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * IronBee — TUI shell: small shared helpers (blessed-tag escaping, clamp, ANSI strip).
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.escapeTags = escapeTags;
7
+ exports.clamp = clamp;
8
+ exports.stripAnsi = stripAnsi;
9
+ /**
10
+ * Escape blessed tag braces so arbitrary text/JSON renders literally.
11
+ *
12
+ * MUST be a single pass: chaining `.replace(/\{/, "{open}").replace(/\}/, "{close}")`
13
+ * is buggy — the first pass injects `}` (inside `{open}`) which the second pass
14
+ * then corrupts into `{open{close}`, and blessed renders that as the literal text
15
+ * `{open}`. One regex with a callback (same as blessed's own `helpers.escape`)
16
+ * never re-processes substituted output.
17
+ */
18
+ function escapeTags(s) {
19
+ return s.replace(/[{}]/g, (ch) => (ch === "{" ? "{open}" : "{close}"));
20
+ }
21
+ /** Clamp `n` into `[lo, hi]`. */
22
+ function clamp(n, lo, hi) {
23
+ return Math.max(lo, Math.min(hi, n));
24
+ }
25
+ /** Matches ANSI CSI escape sequences (ESC [ … final byte). */
26
+ const ANSI_RE = /\x1b\[[0-9;?]*[ -/]*[@-~]/g;
27
+ /** Strip ANSI CSI escape sequences (captured console output → plain text for a pane). */
28
+ function stripAnsi(s) {
29
+ return s.replace(ANSI_RE, "");
30
+ }
31
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/tui/shell/util.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAWH,gCAEC;AAGD,sBAEC;AAMD,8BAEC;AAxBD;;;;;;;;GAQG;AACH,SAAgB,UAAU,CAAC,CAAS;IAChC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAU,EAAU,EAAE,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,iCAAiC;AACjC,SAAgB,KAAK,CAAC,CAAS,EAAE,EAAU,EAAE,EAAU;IACnD,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,8DAA8D;AAC9D,MAAM,OAAO,GAAW,4BAA4B,CAAC;AAErD,yFAAyF;AACzF,SAAgB,SAAS,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC"}