terminal-pilot 0.0.41 → 0.0.43

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -3
  3. package/dist/cli.js +789 -9707
  4. package/dist/cli.js.map +4 -4
  5. package/dist/commands/close-session.js.map +1 -1
  6. package/dist/commands/create-session.js.map +1 -1
  7. package/dist/commands/daemon-runtime.js.map +1 -1
  8. package/dist/commands/fill.js.map +1 -1
  9. package/dist/commands/get-session.js.map +1 -1
  10. package/dist/commands/index.js.map +2 -2
  11. package/dist/commands/install.js.map +2 -2
  12. package/dist/commands/installer.js.map +2 -2
  13. package/dist/commands/list-sessions.js.map +1 -1
  14. package/dist/commands/press-key.js.map +1 -1
  15. package/dist/commands/read-history.js.map +1 -1
  16. package/dist/commands/read-screen.js.map +1 -1
  17. package/dist/commands/resize.js.map +1 -1
  18. package/dist/commands/runtime.js.map +1 -1
  19. package/dist/commands/screenshot.js.map +1 -1
  20. package/dist/commands/send-signal.js.map +1 -1
  21. package/dist/commands/type.js.map +1 -1
  22. package/dist/commands/uninstall.js.map +2 -2
  23. package/dist/commands/wait-for-exit.js.map +1 -1
  24. package/dist/commands/wait-for.js.map +1 -1
  25. package/dist/composition.json +35 -0
  26. package/dist/templates/terminal-pilot.md +1 -1
  27. package/dist/testing/cli-repl.js +795 -9713
  28. package/dist/testing/cli-repl.js.map +4 -4
  29. package/dist/testing/qa-cli.js +804 -9722
  30. package/dist/testing/qa-cli.js.map +4 -4
  31. package/node_modules/@poe-code/agent-defs/LICENSE +21 -0
  32. package/node_modules/@poe-code/agent-defs/package.json +12 -3
  33. package/node_modules/@poe-code/agent-skill-config/README.md +25 -17
  34. package/node_modules/@poe-code/agent-skill-config/dist/templates/poe-generate.md +16 -22
  35. package/node_modules/@poe-code/agent-skill-config/dist/templates/terminal-pilot.md +1 -1
  36. package/node_modules/@poe-code/agent-skill-config/package.json +1 -0
  37. package/node_modules/@poe-code/config-mutations/LICENSE +21 -0
  38. package/node_modules/@poe-code/config-mutations/README.md +8 -8
  39. package/node_modules/@poe-code/config-mutations/package.json +11 -2
  40. package/node_modules/@poe-code/frontmatter/LICENSE +21 -0
  41. package/node_modules/@poe-code/frontmatter/README.md +2 -2
  42. package/node_modules/@poe-code/frontmatter/package.json +11 -2
  43. package/node_modules/toolcraft-design/LICENSE +21 -0
  44. package/node_modules/toolcraft-design/README.md +8 -4
  45. package/node_modules/toolcraft-design/dist/dashboard/terminal.js +48 -6
  46. package/node_modules/toolcraft-design/dist/explorer/actions.d.ts +4 -0
  47. package/node_modules/toolcraft-design/dist/explorer/actions.js +1 -0
  48. package/node_modules/toolcraft-design/dist/explorer/events.d.ts +4 -0
  49. package/node_modules/toolcraft-design/dist/explorer/reducer.js +52 -4
  50. package/node_modules/toolcraft-design/dist/explorer/render/list.js +47 -20
  51. package/node_modules/toolcraft-design/dist/explorer/render/modal.js +13 -1
  52. package/node_modules/toolcraft-design/dist/explorer/render/test-fixtures.js +1 -1
  53. package/node_modules/toolcraft-design/dist/explorer/runtime.js +3 -0
  54. package/node_modules/toolcraft-design/dist/explorer/state.d.ts +9 -0
  55. package/node_modules/toolcraft-design/package.json +3 -2
  56. package/package.json +2 -1
@@ -28,28 +28,34 @@ export function renderList(state, screen, layout) {
28
28
  cache.clear();
29
29
  return;
30
30
  }
31
- let lastGroup;
31
+ const lines = buildDisplayLines(state);
32
+ const start = visibleStart(lines, bodyRect.height);
32
33
  let y = 0;
33
- for (const rowIndex of state.filtered) {
34
- if (y >= bodyRect.height) {
35
- break;
36
- }
37
- const row = state.rows[rowIndex];
38
- if (!row) {
39
- continue;
40
- }
41
- if (row.group && row.group !== lastGroup && y < bodyRect.height) {
42
- const hash = `group:${row.group}`;
34
+ for (let lineIndex = start; lineIndex < lines.length && y < bodyRect.height; lineIndex += 1) {
35
+ const line = lines[lineIndex];
36
+ if (line.kind === "group") {
37
+ const hash = `group:${line.label}`;
43
38
  if (cache.get(y) !== hash) {
44
- writeLine(screen, bodyRect, y, formatGroupHeader(row.group, bodyRect), styles.muted);
39
+ writeLine(screen, bodyRect, y, formatGroupHeader(line.label, bodyRect), styles.muted);
45
40
  cache.set(y, hash);
46
41
  }
47
42
  y += 1;
48
- lastGroup = row.group;
43
+ continue;
44
+ }
45
+ if (line.kind === "subtitle") {
46
+ const subtitleHash = `subtitle:${line.row.id}:${line.text}`;
47
+ if (cache.get(y) !== subtitleHash) {
48
+ writeLine(screen, bodyRect, y, ` ${line.text}`, styles.muted);
49
+ cache.set(y, subtitleHash);
50
+ }
51
+ y += 1;
52
+ continue;
49
53
  }
54
+ const rowIndex = line.rowIndex;
50
55
  if (y >= bodyRect.height) {
51
56
  break;
52
57
  }
58
+ const row = line.row;
53
59
  const selected = state.multiSelect && state.selected.has(row.id);
54
60
  const cursor = rowIndex === state.filtered[state.cursor];
55
61
  const positions = state.matchPositions.get(rowIndex) ?? [];
@@ -64,15 +70,36 @@ export function renderList(state, screen, layout) {
64
70
  cache.set(y, hash);
65
71
  }
66
72
  y += 1;
67
- if (row.subtitle && y < bodyRect.height) {
68
- const subtitleHash = `${hash}:subtitle:${row.subtitle}`;
69
- if (cache.get(y) !== subtitleHash) {
70
- writeLine(screen, bodyRect, y, ` ${row.subtitle}`, styles.muted);
71
- cache.set(y, subtitleHash);
72
- }
73
- y += 1;
73
+ }
74
+ }
75
+ function buildDisplayLines(state) {
76
+ const lines = [];
77
+ let lastGroup;
78
+ for (const rowIndex of state.filtered) {
79
+ const row = state.rows[rowIndex];
80
+ if (!row) {
81
+ continue;
82
+ }
83
+ if (row.group && row.group !== lastGroup) {
84
+ lines.push({ kind: "group", label: row.group });
85
+ lastGroup = row.group;
74
86
  }
87
+ lines.push({ kind: "row", rowIndex, row, cursor: rowIndex === state.filtered[state.cursor] });
88
+ if (row.subtitle) {
89
+ lines.push({ kind: "subtitle", row, text: row.subtitle });
90
+ }
91
+ }
92
+ return lines;
93
+ }
94
+ function visibleStart(lines, height) {
95
+ if (height <= 0) {
96
+ return 0;
97
+ }
98
+ const cursorLine = lines.findIndex((line) => line.kind === "row" && line.cursor);
99
+ if (cursorLine < 0) {
100
+ return 0;
75
101
  }
102
+ return Math.max(0, Math.min(cursorLine, cursorLine - height + 1));
76
103
  }
77
104
  function formatGroupHeader(label, rect) {
78
105
  const text = ` ${label} `;
@@ -4,7 +4,7 @@ export function renderModal(state, screen) {
4
4
  if (state.modal === null || screen.width <= 0 || screen.height <= 0) {
5
5
  return;
6
6
  }
7
- const width = Math.min(screen.width - 2, Math.max(34, Math.floor(screen.width * 0.62)));
7
+ const width = Math.min(screen.width - 2, Math.max(34, Math.floor(screen.width * modalWidthRatio(state))));
8
8
  const height = Math.min(screen.height - 2, modalHeight(state));
9
9
  const x = Math.max(0, Math.floor((screen.width - width) / 2));
10
10
  const y = Math.max(0, Math.floor((screen.height - height) / 2));
@@ -39,6 +39,9 @@ function modalLines(state) {
39
39
  ...paletteLines(state)
40
40
  ];
41
41
  }
42
+ if (state.modal?.kind === "content") {
43
+ return state.modal.content.split("\n").slice(state.modal.scroll);
44
+ }
42
45
  return [];
43
46
  }
44
47
  function title(state) {
@@ -48,11 +51,20 @@ function title(state) {
48
51
  if (state.modal?.kind === "confirm") {
49
52
  return "Confirm";
50
53
  }
54
+ if (state.modal?.kind === "content") {
55
+ return state.modal.title;
56
+ }
51
57
  return "Command Palette";
52
58
  }
53
59
  function modalHeight(state) {
60
+ if (state.modal?.kind === "content") {
61
+ return Math.max(5, state.modal.content.split("\n").length + 2);
62
+ }
54
63
  return Math.max(5, modalLines(state).length + 2);
55
64
  }
65
+ function modalWidthRatio(state) {
66
+ return state.modal?.kind === "content" ? 0.86 : 0.62;
67
+ }
56
68
  function drawBox(screen, x, y, width, height, boxTitle, style) {
57
69
  screen.clearRect({ x, y, width, height });
58
70
  const innerWidth = Math.max(0, width - 2);
@@ -6,7 +6,7 @@ import { renderExplorer } from "./index.js";
6
6
  export function renderStateSnapshot(state) {
7
7
  const screen = new ScreenBuffer(state.size.cols, state.size.rows);
8
8
  renderExplorer(state, screen);
9
- return dumpScreen(screen);
9
+ return dumpScreen(screen).split("\n").map((line) => line.trimEnd()).join("\n");
10
10
  }
11
11
  export function dumpScreen(screen) {
12
12
  const lines = [];
@@ -45,6 +45,9 @@ class ExplorerRuntime {
45
45
  await this.refreshRowsFromSource();
46
46
  },
47
47
  suspendAnd: async (fn) => this.suspendAnd(fn),
48
+ openModal: (content) => {
49
+ this.dispatch({ type: "modalOpened", title: content.title, content: content.content });
50
+ },
48
51
  toast: (msg, tone) => {
49
52
  this.showToast(msg, tone);
50
53
  },
@@ -48,6 +48,10 @@ export interface ActionContext<R> {
48
48
  filter: string;
49
49
  refresh: () => Promise<void>;
50
50
  suspendAnd: <T>(fn: () => Promise<T>) => Promise<T>;
51
+ openModal: (content: {
52
+ title: string;
53
+ content: string;
54
+ }) => void;
51
55
  toast: (msg: string, tone?: Tone) => void;
52
56
  confirm: (prompt: string) => Promise<boolean>;
53
57
  exit: (after?: () => void | Promise<void>) => void;
@@ -114,6 +118,11 @@ export interface ExplorerState {
114
118
  kind: "palette";
115
119
  query: string;
116
120
  cursor: number;
121
+ } | {
122
+ kind: "content";
123
+ title: string;
124
+ content: string;
125
+ scroll: number;
117
126
  };
118
127
  toast: {
119
128
  message: string;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "toolcraft-design",
3
3
  "version": "0.0.2",
4
- "private": true,
4
+ "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -17,7 +17,8 @@
17
17
  "generate:design-docs:all": "tsx scripts/generate-docs.ts all"
18
18
  },
19
19
  "files": [
20
- "dist"
20
+ "dist",
21
+ "LICENSE"
21
22
  ],
22
23
  "dependencies": {
23
24
  "fast-string-width": "^3.0.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-pilot",
3
- "version": "0.0.41",
3
+ "version": "0.0.43",
4
4
  "description": "Playwright-like SDK and CLI for automating interactive CLI apps through a real PTY",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,6 +35,7 @@
35
35
  "smoke:verbose": "cd ../.. && tsx packages/terminal-pilot/scripts/smoke-test.ts --verbose"
36
36
  },
37
37
  "files": [
38
+ "LICENSE",
38
39
  "dist"
39
40
  ],
40
41
  "engines": {