@crouton-kit/crouter 0.3.70 → 0.3.79

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 (193) hide show
  1. package/README.md +1 -1
  2. package/dist/build-root.d.ts +12 -4
  3. package/dist/build-root.js +25 -6
  4. package/dist/builtin-memory/00-runtime-base.md +3 -10
  5. package/dist/builtin-memory/04-base-worker.md +18 -0
  6. package/dist/builtin-memory/04-orchestration-kernel.md +1 -1
  7. package/dist/builtin-memory/crouter-development/plugins.md +82 -5
  8. package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +13 -34
  9. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +1115 -1
  10. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +234 -71
  11. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +2 -9
  12. package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.ts +2 -516
  13. package/dist/builtin-pi-packages/pi-crtr-extensions/package-lock.json +2 -2
  14. package/dist/builtin-pi-packages/pi-mode-switch/README.md +11 -39
  15. package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +20 -15
  16. package/dist/builtin-pi-packages/pi-mode-switch/package.json +1 -1
  17. package/dist/builtin-views/canvas/tui.mjs +8 -9
  18. package/dist/builtin-views/chat/tui.mjs +12 -12
  19. package/dist/builtin-views/git-pr/tui.mjs +7 -8
  20. package/dist/builtin-views/inbox/tui.mjs +27 -41
  21. package/dist/builtin-views/linkedin/tui.mjs +23 -37
  22. package/dist/builtin-views/prompt-review/tui.mjs +11 -11
  23. package/dist/builtin-views/settings/tui.mjs +11 -11
  24. package/dist/builtin-views/workspace-sidebar/tui.mjs +8 -9
  25. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +11 -6
  26. package/dist/clients/attach/__tests__/attach-keybindings.test.d.ts +1 -0
  27. package/dist/clients/attach/__tests__/attach-keybindings.test.js +113 -0
  28. package/dist/clients/attach/__tests__/crtr-output-render.test.js +1 -1
  29. package/dist/clients/attach/__tests__/mermaid-render.test.d.ts +1 -0
  30. package/dist/clients/attach/__tests__/mermaid-render.test.js +28 -0
  31. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +1 -0
  32. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +110 -0
  33. package/dist/clients/attach/attach-cmd.d.ts +9 -1
  34. package/dist/clients/attach/attach-cmd.js +841 -792
  35. package/dist/clients/attach/auth-pickers.d.ts +0 -12
  36. package/dist/clients/attach/auth-pickers.js +64 -15
  37. package/dist/clients/attach/canvas-panels.js +2 -3
  38. package/dist/clients/attach/chat-view.d.ts +7 -8
  39. package/dist/clients/attach/chat-view.js +119 -79
  40. package/dist/clients/attach/edit-diff-render.d.ts +6 -0
  41. package/dist/clients/attach/edit-diff-render.js +263 -0
  42. package/dist/clients/attach/graph-overlay.d.ts +12 -2
  43. package/dist/clients/attach/graph-overlay.js +83 -33
  44. package/dist/clients/attach/input-controller.d.ts +28 -2
  45. package/dist/clients/attach/input-controller.js +38 -5
  46. package/dist/clients/attach/mermaid-render.js +5 -2
  47. package/dist/clients/attach/pickers.d.ts +8 -7
  48. package/dist/clients/attach/pickers.js +11 -17
  49. package/dist/clients/attach/slash-commands.d.ts +9 -0
  50. package/dist/clients/attach/slash-commands.js +127 -7
  51. package/dist/clients/attach/titled-editor.d.ts +12 -1
  52. package/dist/clients/attach/titled-editor.js +103 -8
  53. package/dist/commands/canvas-browse.js +2 -2
  54. package/dist/commands/human/queue.js +3 -4
  55. package/dist/commands/memory/lint.js +39 -5
  56. package/dist/commands/memory/write.js +1 -0
  57. package/dist/commands/node.js +9 -2
  58. package/dist/commands/pkg/plugin-inspect.js +22 -1
  59. package/dist/commands/pkg/plugin-manage.js +31 -9
  60. package/dist/commands/surface-tmux-spread.js +1 -3
  61. package/dist/commands/sys/__tests__/config-keybindings.test.d.ts +1 -0
  62. package/dist/commands/sys/__tests__/config-keybindings.test.js +55 -0
  63. package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +1 -0
  64. package/dist/commands/sys/__tests__/config-model-ladders.test.js +121 -0
  65. package/dist/commands/sys/__tests__/setup-core.test.js +158 -1
  66. package/dist/commands/sys/config.js +18 -21
  67. package/dist/commands/sys/doctor.js +42 -4
  68. package/dist/commands/sys/setup-core.d.ts +49 -1
  69. package/dist/commands/sys/setup-core.js +161 -4
  70. package/dist/commands/sys/setup.d.ts +88 -0
  71. package/dist/commands/sys/setup.js +943 -169
  72. package/dist/commands/view-pick.d.ts +4 -0
  73. package/dist/commands/view-pick.js +17 -7
  74. package/dist/core/__tests__/base-worker-prompt.test.d.ts +1 -0
  75. package/dist/core/__tests__/base-worker-prompt.test.js +24 -0
  76. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +232 -1
  77. package/dist/core/__tests__/canvas-inbox-watcher.test.js +34 -9
  78. package/dist/core/__tests__/command-plugins-surfaces.test.d.ts +1 -0
  79. package/dist/core/__tests__/command-plugins-surfaces.test.js +298 -0
  80. package/dist/core/__tests__/command-plugins.test.d.ts +1 -0
  81. package/dist/core/__tests__/command-plugins.test.js +444 -0
  82. package/dist/core/__tests__/fault-classifier.test.js +15 -0
  83. package/dist/core/__tests__/fixtures/fake-engine.d.ts +6 -0
  84. package/dist/core/__tests__/fixtures/fake-engine.js +9 -1
  85. package/dist/core/__tests__/full/broker-dialogs.test.js +7 -2
  86. package/dist/core/__tests__/host-teardown-process-group.test.js +15 -4
  87. package/dist/core/__tests__/preview-registry-sync.test.js +30 -1
  88. package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +1 -0
  89. package/dist/core/__tests__/scope-crouter-home-fence.test.js +55 -0
  90. package/dist/core/__tests__/stream-watchdog.test.d.ts +1 -0
  91. package/dist/core/__tests__/stream-watchdog.test.js +70 -0
  92. package/dist/core/__tests__/tmux-surface.test.js +72 -0
  93. package/dist/core/canvas/browse/__tests__/model.test.js +23 -5
  94. package/dist/core/canvas/browse/__tests__/render.test.js +1 -0
  95. package/dist/core/canvas/browse/app.d.ts +6 -0
  96. package/dist/core/canvas/browse/app.js +230 -41
  97. package/dist/core/canvas/browse/model.d.ts +10 -6
  98. package/dist/core/canvas/browse/model.js +20 -12
  99. package/dist/core/canvas/browse/pins.d.ts +4 -0
  100. package/dist/core/canvas/browse/pins.js +29 -0
  101. package/dist/core/canvas/browse/render.d.ts +13 -1
  102. package/dist/core/canvas/browse/render.js +72 -15
  103. package/dist/core/canvas/nav-model.js +5 -11
  104. package/dist/core/canvas/paths.d.ts +5 -0
  105. package/dist/core/canvas/paths.js +7 -0
  106. package/dist/core/command-plugins/adapter.d.ts +15 -0
  107. package/dist/core/command-plugins/adapter.js +145 -0
  108. package/dist/core/command-plugins/compose.d.ts +5 -0
  109. package/dist/core/command-plugins/compose.js +56 -0
  110. package/dist/core/command-plugins/discovery.d.ts +104 -0
  111. package/dist/core/command-plugins/discovery.js +565 -0
  112. package/dist/core/config.d.ts +48 -0
  113. package/dist/core/config.js +228 -110
  114. package/dist/core/fault-classifier.js +1 -1
  115. package/dist/core/fs-utils.d.ts +1 -0
  116. package/dist/core/fs-utils.js +15 -1
  117. package/dist/core/keybindings/__tests__/bespoke-consumers.test.d.ts +1 -0
  118. package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +40 -0
  119. package/dist/core/keybindings/__tests__/resolve.test.d.ts +1 -0
  120. package/dist/core/keybindings/__tests__/resolve.test.js +224 -0
  121. package/dist/core/keybindings/catalog.d.ts +14 -0
  122. package/dist/core/keybindings/catalog.js +257 -0
  123. package/dist/core/keybindings/index.d.ts +5 -0
  124. package/dist/core/keybindings/index.js +4 -0
  125. package/dist/core/keybindings/match.d.ts +29 -0
  126. package/dist/core/keybindings/match.js +99 -0
  127. package/dist/core/keybindings/persistence.d.ts +14 -0
  128. package/dist/core/keybindings/persistence.js +31 -0
  129. package/dist/core/keybindings/resolve.d.ts +14 -0
  130. package/dist/core/keybindings/resolve.js +305 -0
  131. package/dist/core/keybindings/types.d.ts +37 -0
  132. package/dist/core/keybindings/types.js +1 -0
  133. package/dist/core/memory-resolver.d.ts +1 -1
  134. package/dist/core/memory-resolver.js +10 -3
  135. package/dist/core/predicate.d.ts +5 -3
  136. package/dist/core/predicate.js +5 -3
  137. package/dist/core/profiles/select.d.ts +6 -0
  138. package/dist/core/profiles/select.js +86 -52
  139. package/dist/core/provider-management.d.ts +12 -0
  140. package/dist/core/provider-management.js +24 -0
  141. package/dist/core/runtime/broker-protocol.d.ts +33 -5
  142. package/dist/core/runtime/broker.js +164 -14
  143. package/dist/core/runtime/launch.d.ts +39 -6
  144. package/dist/core/runtime/launch.js +78 -20
  145. package/dist/core/runtime/naming.js +3 -3
  146. package/dist/core/runtime/pi-cli.d.ts +6 -0
  147. package/dist/core/runtime/pi-cli.js +16 -2
  148. package/dist/core/runtime/pi-vendored.d.ts +8 -0
  149. package/dist/core/runtime/pi-vendored.js +14 -0
  150. package/dist/core/runtime/placement.d.ts +2 -2
  151. package/dist/core/runtime/placement.js +4 -1
  152. package/dist/core/runtime/promote.js +4 -0
  153. package/dist/core/runtime/recap.d.ts +3 -3
  154. package/dist/core/runtime/recap.js +75 -47
  155. package/dist/core/runtime/recycle.js +6 -1
  156. package/dist/core/runtime/reset.js +5 -0
  157. package/dist/core/runtime/session-list-cache.d.ts +33 -0
  158. package/dist/core/runtime/session-list-cache.js +338 -0
  159. package/dist/core/runtime/spawn.js +52 -45
  160. package/dist/core/runtime/stream-watchdog.d.ts +26 -0
  161. package/dist/core/runtime/stream-watchdog.js +75 -0
  162. package/dist/core/runtime/tmux-chrome.d.ts +1 -1
  163. package/dist/core/runtime/tmux-chrome.js +2 -2
  164. package/dist/core/runtime/tmux.d.ts +18 -15
  165. package/dist/core/runtime/tmux.js +217 -110
  166. package/dist/core/scope.js +27 -4
  167. package/dist/core/subscription-state.d.ts +90 -0
  168. package/dist/core/subscription-state.js +762 -0
  169. package/dist/core/tui/__tests__/host-keybindings.test.d.ts +1 -0
  170. package/dist/core/tui/__tests__/host-keybindings.test.js +112 -0
  171. package/dist/core/tui/host.d.ts +30 -1
  172. package/dist/core/tui/host.js +148 -34
  173. package/dist/core/view/contract.d.ts +17 -3
  174. package/dist/daemon/crtrd.js +253 -12
  175. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +41 -0
  176. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +1 -0
  177. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +121 -0
  178. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +1 -1
  179. package/dist/pi-extensions/canvas-inbox-watcher.js +203 -25
  180. package/dist/pi-extensions/canvas-recap.d.ts +4 -0
  181. package/dist/pi-extensions/canvas-recap.js +73 -46
  182. package/dist/pi-extensions/canvas-stophook.d.ts +11 -0
  183. package/dist/pi-extensions/canvas-stophook.js +33 -4
  184. package/dist/types.d.ts +9 -26
  185. package/dist/types.js +1 -28
  186. package/dist/web-client/assets/{index-DiFuLcp6.js → index--md2ylfi.js} +1 -1
  187. package/dist/web-client/index.html +1 -1
  188. package/dist/web-client/sw.js +1 -1
  189. package/package.json +8 -4
  190. package/dist/pi-extensions/canvas-nav.d.ts +0 -43
  191. package/dist/pi-extensions/canvas-nav.js +0 -640
  192. package/dist/pi-extensions/widget-order-bus.d.ts +0 -6
  193. package/dist/pi-extensions/widget-order-bus.js +0 -34
@@ -1,10 +1,131 @@
1
1
  import { spawnSync } from 'node:child_process';
2
2
  import { chmod, mkdir, writeFile } from 'node:fs/promises';
3
+ import { readFileSync } from 'node:fs';
3
4
  import { homedir } from 'node:os';
4
5
  import { basename, dirname, join, resolve } from 'node:path';
6
+ import { isDeepStrictEqual } from 'node:util';
7
+ import { BINDING_CATALOG, normalizeGesture, resolveKeybindings, } from '../../core/keybindings/index.js';
5
8
  import { builtinPiPackageDir } from '../../core/scope.js';
6
9
  import { readJsonIfExists } from '../../core/fs-utils.js';
7
10
  import { resolveBundledPiCliPath } from '../../core/runtime/pi-cli.js';
11
+ function isKeybindingsObject(value) {
12
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
13
+ }
14
+ function cloneKeybindings(value) {
15
+ if (!isKeybindingsObject(value))
16
+ return {};
17
+ return Object.fromEntries(Object.entries(value).map(([id, gestures]) => [
18
+ id,
19
+ Array.isArray(gestures) ? [...gestures] : gestures,
20
+ ]));
21
+ }
22
+ /** Transactional sparse keybinding draft used by the full-screen setup tab. */
23
+ export class SetupKeybindingsDraft {
24
+ expected;
25
+ baseline;
26
+ current;
27
+ baselineInvalidRoot;
28
+ invalidRoot;
29
+ constructor(rawKeybindings) {
30
+ this.expected = rawKeybindings;
31
+ this.baseline = cloneKeybindings(rawKeybindings);
32
+ this.current = cloneKeybindings(rawKeybindings);
33
+ this.baselineInvalidRoot = rawKeybindings !== undefined && !isKeybindingsObject(rawKeybindings) ? rawKeybindings : undefined;
34
+ this.invalidRoot = this.baselineInvalidRoot;
35
+ }
36
+ get dirty() {
37
+ return !isDeepStrictEqual(this.current, this.baseline)
38
+ || !isDeepStrictEqual(this.invalidRoot, this.baselineInvalidRoot);
39
+ }
40
+ overrides() {
41
+ return cloneKeybindings(this.current);
42
+ }
43
+ expectedKeybindings() {
44
+ return this.expected;
45
+ }
46
+ resolution() {
47
+ return resolveKeybindings(this.invalidRoot === undefined ? this.current : this.invalidRoot);
48
+ }
49
+ /** True while the persisted `keybindings` root is a non-object (e.g. a string):
50
+ * edits cannot be layered onto an invalid root, so the tab must reset-all first. */
51
+ hasInvalidRoot() {
52
+ return this.invalidRoot !== undefined;
53
+ }
54
+ expression(id) {
55
+ return this.resolution().gestures(id).join(', ');
56
+ }
57
+ edit(id, expression) {
58
+ if (this.invalidRoot !== undefined) {
59
+ return {
60
+ ok: false,
61
+ diagnostics: [{
62
+ severity: 'error',
63
+ code: 'invalid-keybindings',
64
+ offendingValue: this.invalidRoot,
65
+ message: 'Reset all before editing: the saved keybindings root is invalid.',
66
+ }],
67
+ };
68
+ }
69
+ const definition = BINDING_CATALOG.find((candidate) => candidate.id === id);
70
+ let gestures;
71
+ try {
72
+ gestures = expression.trim() === ''
73
+ ? []
74
+ : expression.split(',').map((gesture) => normalizeGesture(gesture.trim(), definition));
75
+ }
76
+ catch (error) {
77
+ return {
78
+ ok: false,
79
+ diagnostics: [{
80
+ severity: 'error',
81
+ code: 'invalid-override',
82
+ bindingId: id,
83
+ offendingValue: expression,
84
+ message: error instanceof Error ? error.message : String(error),
85
+ }],
86
+ };
87
+ }
88
+ const deduped = [...new Set(gestures)];
89
+ // Sparse invariant: a member is stored only when it changes the effective
90
+ // resolution. If the committed gestures equal the catalog default for this
91
+ // id, drop the member instead of recording a redundant override — otherwise
92
+ // committing an unchanged default flips the row to a spurious user/unsaved
93
+ // state that persistence would then strip anyway.
94
+ const withoutId = { ...this.current };
95
+ delete withoutId[id];
96
+ const defaultGestures = [...resolveKeybindings(withoutId).gestures(id)];
97
+ const prospective = isDeepStrictEqual(deduped, defaultGestures)
98
+ ? withoutId
99
+ : { ...this.current, [id]: deduped };
100
+ const resolution = resolveKeybindings(prospective);
101
+ const relevant = resolution.diagnostics.filter((diagnostic) => diagnostic.bindingId === id || diagnostic.relatedBindingIds?.includes(id));
102
+ if (relevant.length > 0)
103
+ return { ok: false, diagnostics: relevant };
104
+ this.current = prospective;
105
+ return { ok: true, diagnostics: resolution.diagnostics };
106
+ }
107
+ unbind(id) {
108
+ return this.edit(id, '');
109
+ }
110
+ resetRow(id) {
111
+ delete this.current[id];
112
+ }
113
+ resetAll() {
114
+ this.current = {};
115
+ this.invalidRoot = undefined;
116
+ }
117
+ discard() {
118
+ this.current = cloneKeybindings(this.baseline);
119
+ this.invalidRoot = this.baselineInvalidRoot;
120
+ }
121
+ markSaved(overrides) {
122
+ this.expected = Object.keys(overrides).length === 0 ? undefined : cloneKeybindings(overrides);
123
+ this.baseline = cloneKeybindings(overrides);
124
+ this.current = cloneKeybindings(overrides);
125
+ this.baselineInvalidRoot = undefined;
126
+ this.invalidRoot = undefined;
127
+ }
128
+ }
8
129
  const PACKAGE_COPY = {
9
130
  'crtr-extensions': {
10
131
  name: 'pi-crtr-extensions',
@@ -13,8 +134,8 @@ const PACKAGE_COPY = {
13
134
  },
14
135
  'mode-switch': {
15
136
  name: 'pi-mode-switch',
16
- shortDescription: 'Alt+M cycles spec / plan / normal modes; injects mode-specific guidance on change.',
17
- longDescription: 'Press Alt+M to rotate between three operating modes — spec (requirements gathering), plan (design before code), and normal (execution). Each switch appends mode-tailored guidance to keep the agent in the right gear.',
137
+ shortDescription: 'Alt+Shift+P cycles spec / plan / normal modes; injects mode-specific guidance on change.',
138
+ longDescription: 'Press Alt+Shift+P to rotate between three operating modes — spec (requirements gathering), plan (design before code), and normal (execution). Each switch appends mode-tailored guidance to keep the agent in the right gear.',
18
139
  },
19
140
  'oauth-adapter': {
20
141
  name: 'pi-claude-oauth-adapter',
@@ -231,6 +352,25 @@ export function resolveSettingsPath(homeDir = homedir()) {
231
352
  export function resolveExaKeyPath(homeDir = homedir()) {
232
353
  return join(homeDir, '.crouter', 'exa.key');
233
354
  }
355
+ export function resolveComposioKeyPath(homeDir = homedir()) {
356
+ return join(homeDir, '.crouter', 'composio.key');
357
+ }
358
+ function detectApiKey(envVar, keyPath) {
359
+ if ((process.env[envVar] ?? '').trim() !== '')
360
+ return { present: true, source: 'env' };
361
+ try {
362
+ if (readFileSync(keyPath, 'utf8').trim() !== '')
363
+ return { present: true, source: 'file' };
364
+ }
365
+ catch { /* absent/unreadable → not present */ }
366
+ return { present: false };
367
+ }
368
+ export function detectExaKey(homeDir = homedir()) {
369
+ return detectApiKey('EXA_API_KEY', resolveExaKeyPath(homeDir));
370
+ }
371
+ export function detectComposioKey(homeDir = homedir()) {
372
+ return detectApiKey('COMPOSIO_API_KEY', resolveComposioKeyPath(homeDir));
373
+ }
234
374
  export function buildSetupInitialState(opts = {}) {
235
375
  const homeDir = opts.homeDir ?? homedir();
236
376
  const settingsPath = opts.settingsPath ?? resolveSettingsPath(homeDir);
@@ -240,7 +380,7 @@ export function buildSetupInitialState(opts = {}) {
240
380
  const commandExists = opts.commandExists ?? detectCommandOnPath;
241
381
  const packageManager = opts.packageManager ?? detectPackageManager(process.platform, commandExists);
242
382
  const systemTools = ['tmux', 'nvim'].map((tool) => buildSystemToolState(tool, packageManager, commandExists));
243
- return { manifest, installedPackageIds, systemTools, exaKeyPath: resolveExaKeyPath(homeDir) };
383
+ return { manifest, installedPackageIds, systemTools, exaKeyPath: resolveExaKeyPath(homeDir), composioKeyPath: resolveComposioKeyPath(homeDir) };
244
384
  }
245
385
  export function buildSetupStaticInstructions(opts) {
246
386
  return {
@@ -257,6 +397,7 @@ export function buildSetupStaticInstructions(opts) {
257
397
  return `- ${plan.tool}: ${plan.hint}`;
258
398
  }),
259
399
  exaLine: `- Exa key: write to ${opts.exaKeyPath} or set EXA_API_KEY`,
400
+ composioLine: `- Composio key: write to ${opts.composioKeyPath} or set COMPOSIO_API_KEY`,
260
401
  footer: 'Run `crtr sys setup` in a TTY to open the wizard.',
261
402
  };
262
403
  }
@@ -266,11 +407,12 @@ export function renderSetupStaticInstructions(state) {
266
407
  installedPackageIds: state.installedPackageIds,
267
408
  systemPlans: state.systemTools.map((tool) => tool.plan),
268
409
  exaKeyPath: state.exaKeyPath,
410
+ composioKeyPath: state.composioKeyPath,
269
411
  });
270
412
  return [
271
413
  instructions.headline,
272
414
  '',
273
- 'Provider login: open the wizard in a TTY and use the Login tab (same flow as /login) to authenticate a model provider.',
415
+ 'Provider login: open the wizard in a TTY and use the Providers tab (same flow as /login) to authenticate a model provider.',
274
416
  '',
275
417
  'Packages:',
276
418
  ...instructions.packageLines,
@@ -279,6 +421,7 @@ export function renderSetupStaticInstructions(state) {
279
421
  ...instructions.systemLines,
280
422
  '',
281
423
  instructions.exaLine,
424
+ instructions.composioLine,
282
425
  instructions.footer,
283
426
  ].join('\n') + '\n';
284
427
  }
@@ -299,12 +442,19 @@ export async function writeExaKey(exaKeyPath, exaKey) {
299
442
  await writeFile(exaKeyPath, `${exaKey}\n`, 'utf8');
300
443
  await chmod(exaKeyPath, 0o600).catch(() => undefined);
301
444
  }
445
+ export async function writeComposioKey(composioKeyPath, composioKey) {
446
+ await mkdir(dirname(composioKeyPath), { recursive: true });
447
+ await writeFile(composioKeyPath, `${composioKey}\n`, 'utf8');
448
+ await chmod(composioKeyPath, 0o600).catch(() => undefined);
449
+ }
302
450
  export function summarizeSetupExecution(result) {
303
451
  return {
304
452
  installed: [...result.installedPackages, ...result.installedSystemDeps],
305
453
  skipped: [...result.skippedPackages, ...result.skippedSystemDeps],
306
454
  exaKeyWritten: result.exaKeyWritten,
307
455
  exaKeyPath: result.exaKeyPath,
456
+ composioKeyWritten: result.composioKeyWritten,
457
+ composioKeyPath: result.composioKeyPath,
308
458
  };
309
459
  }
310
460
  export function formatSetupExecutionSummary(summary) {
@@ -313,6 +463,7 @@ export function formatSetupExecutionSummary(summary) {
313
463
  summary.installed.length > 0 ? `installed: ${summary.installed.join(', ')}` : 'installed: none',
314
464
  summary.skipped.length > 0 ? `skipped: ${summary.skipped.join(', ')}` : 'skipped: none',
315
465
  summary.exaKeyWritten ? `exa key written: ${summary.exaKeyPath}` : 'exa key written: no',
466
+ summary.composioKeyWritten ? `composio key written: ${summary.composioKeyPath}` : 'composio key written: no',
316
467
  ].join('\n') + '\n';
317
468
  }
318
469
  export async function executeSetupSubmission(submission) {
@@ -344,6 +495,10 @@ export async function executeSetupSubmission(submission) {
344
495
  if (exaKeyWritten) {
345
496
  await writeExaKey(submission.exaKeyPath, submission.exaKey);
346
497
  }
498
+ const composioKeyWritten = submission.composioKey.trim() !== '';
499
+ if (composioKeyWritten) {
500
+ await writeComposioKey(submission.composioKeyPath, submission.composioKey);
501
+ }
347
502
  return summarizeSetupExecution({
348
503
  installedPackages,
349
504
  skippedPackages,
@@ -351,5 +506,7 @@ export async function executeSetupSubmission(submission) {
351
506
  skippedSystemDeps,
352
507
  exaKeyWritten,
353
508
  exaKeyPath: submission.exaKeyPath,
509
+ composioKeyWritten,
510
+ composioKeyPath: submission.composioKeyPath,
354
511
  });
355
512
  }
@@ -1,2 +1,90 @@
1
1
  import type { LeafDef } from '../../core/command.js';
2
+ import { TUI, type Component, type Focusable } from '@earendil-works/pi-tui';
3
+ import { type BindingId, type BindingResolution } from '../../core/keybindings/index.js';
4
+ import { type SetupPackageId, type SetupPackageManifestEntry, type SetupSubmission, type SetupSystemToolState } from './setup-core.js';
5
+ export declare class SetupWizard implements Component, Focusable {
6
+ private readonly manifest;
7
+ private readonly installedPackageIds;
8
+ private readonly systemTools;
9
+ private readonly exaInput;
10
+ private readonly composioInput;
11
+ private readonly keyInput;
12
+ private readonly openingBindings;
13
+ private readonly keyDraft;
14
+ private readonly terminalRows;
15
+ private readonly selectedPackageIds;
16
+ private readonly selectedSystemTools;
17
+ private readonly providers;
18
+ private activeTab;
19
+ private pluginIndex;
20
+ private systemIndex;
21
+ private expandedPluginId;
22
+ private confirming;
23
+ private keyIndex;
24
+ private keyScroll;
25
+ private keyFilter;
26
+ private filteringKeys;
27
+ private editingKey;
28
+ private keyEditError;
29
+ private keyDiagnostics;
30
+ private keyConfirm;
31
+ private keyNotice;
32
+ private cachedWidth;
33
+ private cachedLines;
34
+ private _focused;
35
+ onSubmit?: (submission: SetupSubmission) => void;
36
+ onCancel?: () => void;
37
+ constructor(manifest: SetupPackageManifestEntry[], installedPackageIds: Set<SetupPackageId>, systemTools: SetupSystemToolState[], tui: TUI, agentDir: string, openingBindings: BindingResolution<BindingId>, rawKeybindings: unknown, terminalRows: () => number);
38
+ set focused(value: boolean);
39
+ get focused(): boolean;
40
+ invalidate(): void;
41
+ private setTab;
42
+ private moveTab;
43
+ private cancel;
44
+ dispose(): void;
45
+ private matches;
46
+ /** Human hint label for an action, derived from the opening snapshot so footers
47
+ * reflect the effective (possibly remapped) gestures the wizard actually honors. */
48
+ private label;
49
+ /** Like `label`, but drops gestures a focused pi text Input consumes as data
50
+ * (single printable chars and the arrow keys), so the Exa/Composio footers do
51
+ * not claim keys that never reach the wizard while a field owns focus. */
52
+ private fieldSafeLabel;
53
+ private handleGlobalTabSwitch;
54
+ private selectedPackage;
55
+ private selectedSystem;
56
+ private movePlugin;
57
+ private moveSystem;
58
+ private togglePackage;
59
+ private toggleSystem;
60
+ private toggleDetails;
61
+ private hasPendingInstalls;
62
+ private buildSubmission;
63
+ private finalize;
64
+ private filteredKeybindings;
65
+ private selectedKeybinding;
66
+ private moveKey;
67
+ private keyViewportLines;
68
+ private keyPageSize;
69
+ private beginKeyEdit;
70
+ private commitKeyEdit;
71
+ private cancelKeyEdit;
72
+ private saveKeybindings;
73
+ private refreshTmuxBindingsAfterSave;
74
+ private confirmKeyAction;
75
+ private handleKeybindingsInput;
76
+ handleInput(data: string): void;
77
+ private renderHeader;
78
+ private renderFooter;
79
+ private renderProviders;
80
+ private renderPlugins;
81
+ private renderSystems;
82
+ private renderExa;
83
+ private renderComposio;
84
+ private renderConfirm;
85
+ private keyRowHasMessage;
86
+ private keyLineCost;
87
+ private renderKeybindings;
88
+ render(width: number): string[];
89
+ }
2
90
  export declare const sysSetupLeaf: LeafDef;