codedeck 0.1.9 → 0.3.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 (99) hide show
  1. package/README.md +97 -1
  2. package/dist/cli/cli-name.js +20 -0
  3. package/dist/cli/cli-name.js.map +1 -0
  4. package/dist/cli/commands/claims.js +170 -0
  5. package/dist/cli/commands/claims.js.map +1 -0
  6. package/dist/cli/commands/doctor.js +22 -1
  7. package/dist/cli/commands/doctor.js.map +1 -1
  8. package/dist/cli/commands/models.js +3 -3
  9. package/dist/cli/commands/models.js.map +1 -1
  10. package/dist/cli/commands/open.js +331 -0
  11. package/dist/cli/commands/open.js.map +1 -0
  12. package/dist/cli/commands/ps.js +260 -23
  13. package/dist/cli/commands/ps.js.map +1 -1
  14. package/dist/cli/commands/rename.js +29 -0
  15. package/dist/cli/commands/rename.js.map +1 -0
  16. package/dist/cli/commands/run.js +68 -30
  17. package/dist/cli/commands/run.js.map +1 -1
  18. package/dist/cli/commands/setup.js +508 -0
  19. package/dist/cli/commands/setup.js.map +1 -0
  20. package/dist/cli/commands/usage.js +37 -0
  21. package/dist/cli/commands/usage.js.map +1 -0
  22. package/dist/cli/commands/wait.js +3 -2
  23. package/dist/cli/commands/wait.js.map +1 -1
  24. package/dist/cli/index.js +37 -21
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/picker-state.js +168 -0
  27. package/dist/cli/picker-state.js.map +1 -0
  28. package/dist/cli/picker.js +157 -0
  29. package/dist/cli/picker.js.map +1 -0
  30. package/dist/cli/ui.js +233 -0
  31. package/dist/cli/ui.js.map +1 -0
  32. package/dist/config/config.js +47 -0
  33. package/dist/config/config.js.map +1 -1
  34. package/dist/config/orchestrator-mode.js +72 -0
  35. package/dist/config/orchestrator-mode.js.map +1 -0
  36. package/dist/config/paths.js +8 -0
  37. package/dist/config/paths.js.map +1 -1
  38. package/dist/core/models.js +23 -4
  39. package/dist/core/models.js.map +1 -1
  40. package/dist/core/pricing.js +65 -0
  41. package/dist/core/pricing.js.map +1 -0
  42. package/dist/core/roles.js +83 -0
  43. package/dist/core/roles.js.map +1 -0
  44. package/dist/core/run-usage.js +46 -0
  45. package/dist/core/run-usage.js.map +1 -0
  46. package/dist/core/session.js +5 -0
  47. package/dist/core/session.js.map +1 -1
  48. package/dist/daemon/daemon.js +90 -3
  49. package/dist/daemon/daemon.js.map +1 -1
  50. package/dist/daemon/ipc.js +10 -3
  51. package/dist/daemon/ipc.js.map +1 -1
  52. package/dist/drivers/opencode/driver.js +1 -114
  53. package/dist/drivers/opencode/driver.js.map +1 -1
  54. package/dist/drivers/opencode/parser.js +86 -0
  55. package/dist/drivers/opencode/parser.js.map +1 -0
  56. package/dist/drivers/session-runtime.js +1 -0
  57. package/dist/drivers/session-runtime.js.map +1 -1
  58. package/dist/git/worktree.js +1 -1
  59. package/dist/git/worktree.js.map +1 -1
  60. package/dist/open/contract.js +104 -0
  61. package/dist/open/contract.js.map +1 -0
  62. package/dist/open/injection.js +59 -0
  63. package/dist/open/injection.js.map +1 -0
  64. package/dist/open/launchers/claude.js +212 -0
  65. package/dist/open/launchers/claude.js.map +1 -0
  66. package/dist/open/launchers/opencode.js +178 -0
  67. package/dist/open/launchers/opencode.js.map +1 -0
  68. package/dist/open/orchestrator-prose.js +12 -0
  69. package/dist/open/orchestrator-prose.js.map +1 -0
  70. package/dist/open/pty.js +281 -0
  71. package/dist/open/pty.js.map +1 -0
  72. package/dist/open/runtime.js +597 -0
  73. package/dist/open/runtime.js.map +1 -0
  74. package/dist/plugin/.claude-plugin/plugin.json +11 -0
  75. package/dist/plugin/agents/auditor.md +36 -0
  76. package/dist/plugin/agents/general.md +35 -0
  77. package/dist/plugin/agents/orchestrator-edit.md +69 -0
  78. package/dist/plugin/agents/orchestrator-read.md +69 -0
  79. package/dist/plugin/agents/orchestrator.md +91 -0
  80. package/dist/plugin/agents/reviewer.md +36 -0
  81. package/dist/plugin/commands/autonomous.md +58 -0
  82. package/dist/plugin/hooks/hooks.json +24 -0
  83. package/dist/plugin/hooks/session-id.sh +23 -0
  84. package/dist/plugin/hooks/session-name-lib.mjs +40 -0
  85. package/dist/plugin/hooks/session-name-worker.mjs +124 -0
  86. package/dist/plugin/hooks/session-name.mjs +66 -0
  87. package/dist/plugin/hooks/session-name.sh +7 -0
  88. package/dist/plugin/pty-shim.mjs +114 -0
  89. package/dist/plugin/statusline.sh +260 -0
  90. package/dist/plugin/themes/codedeck-rage.json +74 -0
  91. package/dist/plugin/themes/codedeck-ultra.json +76 -0
  92. package/dist/plugin/ultra.md +9 -0
  93. package/dist/store/claims.js +152 -0
  94. package/dist/store/claims.js.map +1 -0
  95. package/dist/store/database.js +14 -0
  96. package/dist/store/database.js.map +1 -1
  97. package/dist/store/sessions.js +17 -3
  98. package/dist/store/sessions.js.map +1 -1
  99. package/package.json +6 -4
package/dist/cli/index.js CHANGED
@@ -5,7 +5,9 @@ import { fileURLToPath } from "node:url";
5
5
  import path from "node:path";
6
6
  import { registerRunCommand } from "./commands/run.js";
7
7
  import { registerPsCommand } from "./commands/ps.js";
8
+ import { registerClaimsCommand } from "./commands/claims.js";
8
9
  import { registerShowCommand } from "./commands/show.js";
10
+ import { registerRenameCommand } from "./commands/rename.js";
9
11
  import { registerLogsCommand } from "./commands/logs.js";
10
12
  import { registerWaitCommand } from "./commands/wait.js";
11
13
  import { registerSendCommand } from "./commands/send.js";
@@ -13,6 +15,10 @@ import { registerStopCommand } from "./commands/stop.js";
13
15
  import { registerDiffCommand } from "./commands/diff.js";
14
16
  import { registerDoctorCommand } from "./commands/doctor.js";
15
17
  import { registerModelsCommand } from "./commands/models.js";
18
+ import { registerOpenCommand } from "./commands/open.js";
19
+ import { registerSetupCommand } from "./commands/setup.js";
20
+ import { registerUsageCommand } from "./commands/usage.js";
21
+ import { getCliInvocation, getCliName } from "./cli-name.js";
16
22
  function getVersion() {
17
23
  try {
18
24
  const pkgPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "../../package.json");
@@ -24,8 +30,12 @@ function getVersion() {
24
30
  }
25
31
  }
26
32
  const program = new Command();
33
+ // CODEDECK_CLI_NAME renames the tool (for example a `codedeck-dev`
34
+ // alias), so the help below shows that name instead of `npx codedeck`.
35
+ const cliName = getCliName();
36
+ const cli = getCliInvocation();
27
37
  program
28
- .name("codedeck")
38
+ .name(cliName)
29
39
  .description("CodeDeck — local runtime for coding agents\nManage Claude, Codex, OpenCode and OMP through a single session interface")
30
40
  .version(getVersion())
31
41
  .helpOption("-h, --help", "display help for command")
@@ -33,34 +43,37 @@ program
33
43
  .showSuggestionAfterError(true)
34
44
  .addHelpText("after", `
35
45
  Examples:
36
- $ npx codedeck run "implement authentication" --agent claude --worktree
37
- $ npx codedeck run "fix the tests" --agent codex --bg
38
- $ npx codedeck wait a83f
39
- $ npx codedeck ps
40
- $ npx codedeck ps --json
41
- $ npx codedeck show a83f
42
- $ npx codedeck logs a83f --follow
43
- $ npx codedeck logs a83f --json
44
- $ npx codedeck send a83f "add tests"
45
- $ npx codedeck stop a83f
46
- $ npx codedeck diff a83f --stat
47
- $ npx codedeck doctor
48
- $ npx codedeck models
49
- $ npx codedeck models codex
50
- $ npx codedeck models --search sonnet
46
+ $ ${cli} run "implement authentication" --agent claude --worktree
47
+ $ ${cli} run "fix the tests" --agent codex --bg
48
+ $ ${cli} wait a83f
49
+ $ ${cli} ps
50
+ $ ${cli} ps --json
51
+ $ ${cli} show a83f
52
+ $ ${cli} rename a83f "fix auth tests"
53
+ $ ${cli} logs a83f --follow
54
+ $ ${cli} logs a83f --json
55
+ $ ${cli} send a83f "add tests"
56
+ $ ${cli} stop a83f
57
+ $ ${cli} diff a83f --stat
58
+ $ ${cli} doctor
59
+ $ ${cli} models
60
+ $ ${cli} models codex
61
+ $ ${cli} models --search sonnet
51
62
 
52
63
  Recommended flow:
53
- $ npx codedeck run "task" # blocks and follows logs
54
- $ npx codedeck run "task" --bg --json # starts in background
55
- $ npx codedeck wait <id> # waits without ps/show loop
56
- $ npx codedeck logs <id> --follow # inspect progress
64
+ $ ${cli} run "task" # blocks and follows logs
65
+ $ ${cli} run "task" --bg --json # starts in background
66
+ $ ${cli} wait <id> # waits without ps/show loop
67
+ $ ${cli} logs <id> --follow # inspect progress
57
68
 
58
- Run 'npx codedeck <command> --help' for command-specific options.
69
+ Run '${cli} <command> --help' for command-specific options.
59
70
  Docs: https://github.com/4ndreello/run-agent
60
71
  `);
61
72
  registerRunCommand(program);
62
73
  registerPsCommand(program);
74
+ registerClaimsCommand(program);
63
75
  registerShowCommand(program);
76
+ registerRenameCommand(program);
64
77
  registerLogsCommand(program);
65
78
  registerWaitCommand(program);
66
79
  registerSendCommand(program);
@@ -68,6 +81,9 @@ registerStopCommand(program);
68
81
  registerDiffCommand(program);
69
82
  registerDoctorCommand(program);
70
83
  registerModelsCommand(program);
84
+ registerOpenCommand(program);
85
+ registerSetupCommand(program);
86
+ registerUsageCommand(program);
71
87
  // Make `codedeck help` behave like `codedeck --help`
72
88
  program.command("help", { hidden: true }).action(() => program.outputHelp());
73
89
  program.parseAsync(process.argv).catch((err) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;QAC9F,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,uHAAuH,CAAC;KACpI,OAAO,CAAC,UAAU,EAAE,CAAC;KACrB,UAAU,CAAC,YAAY,EAAE,0BAA0B,CAAC;KACpD,kBAAkB,CAAC,0BAA0B,CAAC;KAC9C,wBAAwB,CAAC,IAAI,CAAC;KAC9B,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BvB,CAAC,CAAC;AAEH,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAE/B,qDAAqD;AACrD,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;AAE7E,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * The catalog is keyed by both halves because a model id alone is ambiguous:
3
+ * two harnesses can list the same one, and `run --agent` needs to know which
4
+ * of them was picked.
5
+ *
6
+ * The separator is ":", the same one free text types and the summary line
7
+ * prints, so the key stays readable wherever it surfaces (the confirm footer
8
+ * shows it verbatim). Splitting it the other way would need a harness name
9
+ * containing ":", and the four there are cannot, so a model id carrying one
10
+ * is still unambiguous.
11
+ */
12
+ export function itemKey(harness, id) {
13
+ return `${harness ?? ""}:${id}`;
14
+ }
15
+ export function initialState(screen) {
16
+ return { screen, filter: "", cursor: 0, offset: 0, pasting: false };
17
+ }
18
+ /**
19
+ * Searches everything the catalog knows about a model, not just what fits on
20
+ * the row. The provider is on screen as a group header, so typing it and
21
+ * getting nothing read as a broken filter, and the readable name is the only
22
+ * place a version like "Opus 5" is spelled the way people say it.
23
+ */
24
+ function matches(item, filter) {
25
+ return [item.label, item.id, item.group, item.name].some((field) => field !== undefined && field.toLowerCase().includes(filter));
26
+ }
27
+ /**
28
+ * Real catalog matches, which is not `visibleItems().length`: that one never
29
+ * returns empty, so counting it reported one hit for a filter that matched
30
+ * nothing.
31
+ */
32
+ export function hitCount(state) {
33
+ const filter = state.filter.trim().toLowerCase();
34
+ if (!filter)
35
+ return state.screen.items.length;
36
+ return state.screen.items.filter((item) => matches(item, filter)).length;
37
+ }
38
+ /**
39
+ * A model typed by hand has to name its harness, because the screen answers a
40
+ * role and a bare id says nothing about who runs it. The separator is ":" and
41
+ * not "/": opencode spells its own ids with a slash ("opencode/gpt-5.6-luna"),
42
+ * so splitting on that would cut a real id in half.
43
+ *
44
+ * Only the first ":" separates. Everything after it is the model, verbatim.
45
+ */
46
+ export function parseFreeText(raw, harnesses) {
47
+ const cut = raw.indexOf(":");
48
+ if (cut <= 0)
49
+ return undefined;
50
+ const harness = raw.slice(0, cut).trim().toLowerCase();
51
+ const id = raw.slice(cut + 1).trim();
52
+ if (!id || !harnesses.has(harness))
53
+ return undefined;
54
+ return { harness, id };
55
+ }
56
+ export function visibleItems(state) {
57
+ const filter = state.filter.trim().toLowerCase();
58
+ const hits = filter ? state.screen.items.filter((item) => matches(item, filter)) : state.screen.items;
59
+ if (hits.length > 0)
60
+ return hits;
61
+ // Nothing to list, so the only way forward is writing the raw text. This is
62
+ // also the whole screen when no installed harness reported a catalog, which
63
+ // would never have a list to filter.
64
+ const raw = state.filter.trim();
65
+ const typed = parseFreeText(raw, state.screen.harnesses);
66
+ if (typed) {
67
+ return [{
68
+ id: typed.id,
69
+ label: `usar "${typed.id}" em ${typed.harness}`,
70
+ harness: typed.harness,
71
+ synthetic: true,
72
+ }];
73
+ }
74
+ // An id with no harness in front of it is not a choice this screen can save,
75
+ // so the row says what is missing rather than offering an Enter that would
76
+ // have to guess. The empty id is what blocks that Enter.
77
+ const example = [...state.screen.harnesses][0] ?? "codex";
78
+ return [{
79
+ id: "",
80
+ label: raw ? `escreva ${example}:${raw}` : `digite harness:modelo, por exemplo ${example}:gpt-5.7`,
81
+ synthetic: true,
82
+ }];
83
+ }
84
+ function scrolled(state, cursor, viewport) {
85
+ const offset = Math.min(state.offset, cursor);
86
+ return { ...state, cursor, offset: Math.max(offset, cursor - viewport + 1) };
87
+ }
88
+ /**
89
+ * Pulls the cursor back into view without moving it. A resize can shrink the
90
+ * viewport under a cursor that was scrolled into the old one, and the frame
91
+ * then rendered a window the cursor was not in.
92
+ */
93
+ export function reanchor(state, viewport) {
94
+ return scrolled(state, state.cursor, viewport);
95
+ }
96
+ const none = (state) => ({
97
+ state,
98
+ action: { kind: "none" },
99
+ });
100
+ export function applyKey(state, key, viewport) {
101
+ if (key.name === "paste-start")
102
+ return none({ ...state, pasting: true });
103
+ if (key.name === "paste-end")
104
+ return none({ ...state, pasting: false });
105
+ // Inside a paste only text gets through. A `\n` in the middle of pasted text
106
+ // must not choose a model, and a pasted `\x1b[A` must not move the cursor.
107
+ if (state.pasting) {
108
+ if (key.ctrl || key.meta || key.sequence.length !== 1)
109
+ return none(state);
110
+ if (key.sequence < " ")
111
+ return none(state);
112
+ // Pasted text edits the filter like typed text does, so it has to drop a
113
+ // pending confirmation the same way. Keeping it meant the footer asked
114
+ // about one id while the row on screen was already another.
115
+ return none({
116
+ ...state,
117
+ confirming: undefined,
118
+ filter: state.filter + key.sequence,
119
+ cursor: 0,
120
+ offset: 0,
121
+ });
122
+ }
123
+ if (key.ctrl && key.name === "c")
124
+ return { state, action: { kind: "aborted" } };
125
+ if (key.ctrl && key.name === "g")
126
+ return { state, action: { kind: "skipped" } };
127
+ const items = visibleItems(state);
128
+ const pending = state.confirming;
129
+ const cleared = pending === undefined ? state : { ...state, confirming: undefined };
130
+ if (key.name === "return") {
131
+ const item = items[cleared.cursor];
132
+ if (!item)
133
+ return none(cleared);
134
+ if (item.synthetic && item.id === "")
135
+ return none(cleared);
136
+ // Both halves or nothing. A row with no harness cannot be saved, and the
137
+ // rows that reach here without one are exactly the ones already refused
138
+ // above, so this only guards the type.
139
+ if (!item.harness)
140
+ return none(cleared);
141
+ const entry = itemKey(item.harness, item.id);
142
+ const picked = { kind: "picked", id: item.id, harness: item.harness };
143
+ if (!item.synthetic || cleared.screen.known.has(entry)) {
144
+ return { state: cleared, action: picked };
145
+ }
146
+ // The pending confirmation is keyed by both halves, so answering it for one
147
+ // harness cannot accept the same id under another.
148
+ if (pending === entry)
149
+ return { state: cleared, action: picked };
150
+ return none({ ...cleared, confirming: entry });
151
+ }
152
+ if (key.name === "up")
153
+ return none(scrolled(cleared, Math.max(0, cleared.cursor - 1), viewport));
154
+ if (key.name === "down") {
155
+ return none(scrolled(cleared, Math.min(items.length - 1, cleared.cursor + 1), viewport));
156
+ }
157
+ if (key.name === "backspace") {
158
+ return none({ ...cleared, filter: cleared.filter.slice(0, -1), cursor: 0, offset: 0 });
159
+ }
160
+ // Esc never skips: an arrow sequence that arrives fragmented shows up as a
161
+ // lone escape, and skipping on that would throw away the user's answer.
162
+ if (key.ctrl || key.meta || key.sequence.length !== 1)
163
+ return none(cleared);
164
+ if (key.sequence < " ")
165
+ return none(cleared);
166
+ return none({ ...cleared, filter: cleared.filter + key.sequence, cursor: 0, offset: 0 });
167
+ }
168
+ //# sourceMappingURL=picker-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker-state.js","sourceRoot":"","sources":["../../src/cli/picker-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ import { emitKeypressEvents } from "node:readline";
2
+ import { applyKey, initialState, reanchor, } from "./picker-state.js";
3
+ import { readDimensions, renderFrame, viewportHeight } from "./ui.js";
4
+ const PASTE_ON = "\x1b[?2004h";
5
+ const PASTE_OFF = "\x1b[?2004l";
6
+ /**
7
+ * `emitKeypressEvents` attaches a parser to the stream and offers no way to
8
+ * take it back: it adds a `newListener` hook that swaps itself for a `data`
9
+ * handler once something listens for keypresses. Removing our own `keypress`
10
+ * handler leaves that parser turning every later byte into keypress events for
11
+ * a picker that is gone. Both names are watched because which one is left
12
+ * behind depends on whether a screen ever started.
13
+ */
14
+ function detachKeypressParser(input, before) {
15
+ const stream = input;
16
+ for (const event of ["data", "newListener"]) {
17
+ for (const listener of stream.listeners(event)) {
18
+ if (!before[event].includes(listener))
19
+ stream.removeListener(event, listener);
20
+ }
21
+ }
22
+ }
23
+ /**
24
+ * Sole owner of raw mode, the listeners and the cleanup. Acquiring per screen
25
+ * would let one screen's type-ahead leak into the next.
26
+ */
27
+ export async function runScreens(screens, io, c) {
28
+ const { input, output } = io;
29
+ const results = [];
30
+ let restored = false;
31
+ const restore = () => {
32
+ if (restored)
33
+ return;
34
+ restored = true;
35
+ try {
36
+ output.write(`${PASTE_OFF}\n`);
37
+ }
38
+ catch {
39
+ // A dead stdout (EPIPE under `| head`) must not cost the terminal its
40
+ // cooked mode: the write is the disposable half of restoring.
41
+ }
42
+ input.setRawMode?.(false);
43
+ input.pause();
44
+ };
45
+ // SIGTERM does not run the `exit` handler, and counting on Node to restore
46
+ // the TTY by itself is counting on luck.
47
+ const onExit = () => restore();
48
+ const onSigterm = () => {
49
+ restore();
50
+ process.exit(143);
51
+ };
52
+ process.on("exit", onExit);
53
+ process.on("SIGTERM", onSigterm);
54
+ // One frame and one resize listener for the whole run: a listener per screen
55
+ // piled up four of them on a four agent run.
56
+ const frame = { height: 0, repaint: () => { } };
57
+ let stopResize;
58
+ const listeners = input;
59
+ const before = {
60
+ data: [...listeners.listeners("data")],
61
+ newListener: [...listeners.listeners("newListener")],
62
+ };
63
+ // Setup lives inside the try because raw mode is on from its second line: a
64
+ // throw between there and the loop used to skip the finally entirely.
65
+ try {
66
+ emitKeypressEvents(input);
67
+ input.setRawMode?.(true);
68
+ input.resume();
69
+ output.write(PASTE_ON);
70
+ stopResize = io.onResize?.(() => frame.repaint());
71
+ const pending = [...screens];
72
+ for (let index = 0; index < pending.length; index += 1) {
73
+ const screen = pending[index];
74
+ const result = await runScreen(screen, io, c, frame);
75
+ results.push(result);
76
+ if (result.kind === "aborted")
77
+ break;
78
+ const followups = screen.next?.(result) ?? [];
79
+ if (followups.length > 0)
80
+ pending.splice(index + 1, 0, ...followups);
81
+ }
82
+ }
83
+ finally {
84
+ frame.repaint = () => { };
85
+ stopResize?.();
86
+ detachKeypressParser(input, before);
87
+ process.off("exit", onExit);
88
+ process.off("SIGTERM", onSigterm);
89
+ restore();
90
+ }
91
+ return results;
92
+ }
93
+ function runScreen(screen, io, c, frame) {
94
+ return new Promise((resolve, reject) => {
95
+ const { input, output } = io;
96
+ let state = initialState(screen);
97
+ const paint = () => {
98
+ const dim = readDimensions(output);
99
+ // A resize can shrink the viewport under a cursor that was scrolled into
100
+ // the old one. Reanchoring here covers the repaint the resize triggers,
101
+ // where no key ran to fix the offset.
102
+ state = reanchor(state, viewportHeight(state, dim));
103
+ const lines = renderFrame(state, dim, c);
104
+ // Go up by the previous frame's height and clear from there down, or a
105
+ // smaller frame leaves the bigger one's leftovers on screen.
106
+ const prefix = frame.height > 0 ? `\x1b[${frame.height}A\x1b[0J` : "";
107
+ output.write(`${prefix}${lines.join("\n")}\n`);
108
+ frame.height = lines.length;
109
+ };
110
+ const detach = () => {
111
+ input.off("keypress", onKey);
112
+ frame.repaint = () => { };
113
+ };
114
+ const onKey = (sequence, key) => {
115
+ const pressed = key
116
+ ? { ...key, sequence: key.sequence ?? sequence ?? "" }
117
+ : { sequence: sequence ?? "", ctrl: false, meta: false };
118
+ try {
119
+ const outcome = applyKey(state, pressed, viewportHeight(state, readDimensions(output)));
120
+ state = outcome.state;
121
+ if (outcome.action.kind === "none") {
122
+ paint();
123
+ return;
124
+ }
125
+ detach();
126
+ if (outcome.action.kind === "picked") {
127
+ resolve({
128
+ kind: "picked",
129
+ role: screen.role,
130
+ harness: outcome.action.harness,
131
+ id: outcome.action.id,
132
+ });
133
+ return;
134
+ }
135
+ if (outcome.action.kind === "skipped") {
136
+ resolve({ kind: "skipped", role: screen.role });
137
+ return;
138
+ }
139
+ resolve({ kind: "aborted" });
140
+ }
141
+ catch (error) {
142
+ detach();
143
+ reject(error);
144
+ }
145
+ };
146
+ input.on("keypress", onKey);
147
+ frame.repaint = paint;
148
+ try {
149
+ paint();
150
+ }
151
+ catch (error) {
152
+ detach();
153
+ reject(error);
154
+ }
155
+ });
156
+ }
157
+ //# sourceMappingURL=picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picker.js","sourceRoot":"","sources":["../../src/cli/picker.ts"],"names":[],"mappings":"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"}