automata-cli 0.1.0-feature-030-do-work.182 → 0.1.0-feature-030-do-work.184

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.
@@ -69,9 +69,7 @@ function ConfigWizard() {
69
69
  existing.doWork?.baseBranch ?? DEFAULT_DO_WORK.baseBranch
70
70
  );
71
71
  const initialExecutorIndex = EXECUTOR_OPTIONS.findIndex((o) => o.value === existing.doWork?.executor);
72
- const [doWorkExecutorIndex, setDoWorkExecutorIndex] = useState(
73
- initialExecutorIndex >= 0 ? initialExecutorIndex : 0
74
- );
72
+ const [doWorkExecutorIndex, setDoWorkExecutorIndex] = useState(Math.max(initialExecutorIndex, 0));
75
73
  const [doWorkMaxRuns, setDoWorkMaxRuns] = useState(
76
74
  String(existing.doWork?.maxRunsPerTick ?? DEFAULT_DO_WORK.maxRunsPerTick)
77
75
  );
@@ -86,7 +84,118 @@ function ConfigWizard() {
86
84
  existing.issueDiscoveryTechnique ?? "label"
87
85
  );
88
86
  const { exit } = useApp();
87
+ const handleDoWorkInput = (input, key) => {
88
+ if (screen === "do-work-base-branch") {
89
+ if (key.return) {
90
+ setScreen("do-work-executor");
91
+ } else if (key.backspace || key.delete) {
92
+ setDoWorkBaseBranch((v) => v.slice(0, -1));
93
+ } else if (key.escape) {
94
+ setScreen("main");
95
+ } else if (key.ctrl && input === "c") {
96
+ exit();
97
+ } else if (input && !key.ctrl && !key.meta) {
98
+ setDoWorkBaseBranch((v) => v + input);
99
+ }
100
+ return true;
101
+ }
102
+ if (screen === "do-work-executor") {
103
+ if (key.upArrow) {
104
+ setDoWorkExecutorIndex((i) => i > 0 ? i - 1 : EXECUTOR_OPTIONS.length - 1);
105
+ } else if (key.downArrow) {
106
+ setDoWorkExecutorIndex((i) => i < EXECUTOR_OPTIONS.length - 1 ? i + 1 : 0);
107
+ } else if (key.return) {
108
+ setScreen("do-work-max-runs");
109
+ } else if (key.escape) {
110
+ setScreen("do-work-base-branch");
111
+ } else if (key.ctrl && input === "c") {
112
+ exit();
113
+ }
114
+ return true;
115
+ }
116
+ if (screen === "do-work-max-runs") {
117
+ if (key.return) {
118
+ const parsedMaxRuns = Number.parseInt(doWorkMaxRuns, 10);
119
+ const current = readRawConfig();
120
+ writeConfig({
121
+ ...current,
122
+ doWork: {
123
+ ...current.doWork,
124
+ baseBranch: doWorkBaseBranch.trim() || void 0,
125
+ executor: EXECUTOR_OPTIONS[doWorkExecutorIndex].value,
126
+ maxRunsPerTick: Number.isNaN(parsedMaxRuns) || parsedMaxRuns < 0 ? void 0 : parsedMaxRuns
127
+ }
128
+ });
129
+ exit();
130
+ } else if (key.backspace || key.delete) {
131
+ setDoWorkMaxRuns((v) => v.slice(0, -1));
132
+ } else if (key.escape) {
133
+ setScreen("do-work-executor");
134
+ } else if (key.ctrl && input === "c") {
135
+ exit();
136
+ } else if (input && !key.ctrl && !key.meta) {
137
+ setDoWorkMaxRuns((v) => v + input);
138
+ }
139
+ return true;
140
+ }
141
+ if (screen === "do-work-discuss-prompt") {
142
+ if (key.return) {
143
+ let discussValue;
144
+ if (doWorkDiscussPrompt) {
145
+ writePromptFile("do-work-issue-discuss.md", doWorkDiscussPrompt);
146
+ discussValue = "do-work-issue-discuss.md";
147
+ }
148
+ const current = readRawConfig();
149
+ writeConfig({
150
+ ...current,
151
+ doWork: {
152
+ ...current.doWork,
153
+ prompts: { ...current.doWork?.prompts, issueDiscuss: discussValue }
154
+ }
155
+ });
156
+ setScreen("prompts-menu");
157
+ } else if (key.backspace || key.delete) {
158
+ setDoWorkDiscussPrompt((v) => v.slice(0, -1));
159
+ } else if (key.escape) {
160
+ setScreen("prompts-menu");
161
+ } else if (key.ctrl && input === "c") {
162
+ exit();
163
+ } else if (input && !key.ctrl && !key.meta) {
164
+ setDoWorkDiscussPrompt((v) => v + input);
165
+ }
166
+ return true;
167
+ }
168
+ if (screen === "do-work-pr-prompt") {
169
+ if (key.return) {
170
+ let prValue;
171
+ if (doWorkPrPrompt) {
172
+ writePromptFile("do-work-pr-work.md", doWorkPrPrompt);
173
+ prValue = "do-work-pr-work.md";
174
+ }
175
+ const current = readRawConfig();
176
+ writeConfig({
177
+ ...current,
178
+ doWork: {
179
+ ...current.doWork,
180
+ prompts: { ...current.doWork?.prompts, prWork: prValue }
181
+ }
182
+ });
183
+ setScreen("prompts-menu");
184
+ } else if (key.backspace || key.delete) {
185
+ setDoWorkPrPrompt((v) => v.slice(0, -1));
186
+ } else if (key.escape) {
187
+ setScreen("prompts-menu");
188
+ } else if (key.ctrl && input === "c") {
189
+ exit();
190
+ } else if (input && !key.ctrl && !key.meta) {
191
+ setDoWorkPrPrompt((v) => v + input);
192
+ }
193
+ return true;
194
+ }
195
+ return false;
196
+ };
89
197
  useInput((input, key) => {
198
+ if (handleDoWorkInput(input, key)) return;
90
199
  if (screen === "main") {
91
200
  if (key.upArrow) {
92
201
  setMainMenuIndex((i) => i > 0 ? i - 1 : MAIN_MENU_OPTIONS.length - 1);
@@ -301,103 +410,6 @@ function ConfigWizard() {
301
410
  } else if (input && !key.ctrl && !key.meta) {
302
411
  setAgentUser((v) => v + input);
303
412
  }
304
- } else if (screen === "do-work-base-branch") {
305
- if (key.return) {
306
- setScreen("do-work-executor");
307
- } else if (key.backspace || key.delete) {
308
- setDoWorkBaseBranch((v) => v.slice(0, -1));
309
- } else if (key.escape) {
310
- setScreen("main");
311
- } else if (key.ctrl && input === "c") {
312
- exit();
313
- } else if (input && !key.ctrl && !key.meta) {
314
- setDoWorkBaseBranch((v) => v + input);
315
- }
316
- } else if (screen === "do-work-executor") {
317
- if (key.upArrow) {
318
- setDoWorkExecutorIndex((i) => i > 0 ? i - 1 : EXECUTOR_OPTIONS.length - 1);
319
- } else if (key.downArrow) {
320
- setDoWorkExecutorIndex((i) => i < EXECUTOR_OPTIONS.length - 1 ? i + 1 : 0);
321
- } else if (key.return) {
322
- setScreen("do-work-max-runs");
323
- } else if (key.escape) {
324
- setScreen("do-work-base-branch");
325
- } else if (key.ctrl && input === "c") {
326
- exit();
327
- }
328
- } else if (screen === "do-work-max-runs") {
329
- if (key.return) {
330
- const parsedMaxRuns = Number.parseInt(doWorkMaxRuns, 10);
331
- const current = readRawConfig();
332
- writeConfig({
333
- ...current,
334
- doWork: {
335
- ...current.doWork,
336
- baseBranch: doWorkBaseBranch.trim() || void 0,
337
- executor: EXECUTOR_OPTIONS[doWorkExecutorIndex].value,
338
- maxRunsPerTick: Number.isNaN(parsedMaxRuns) || parsedMaxRuns < 0 ? void 0 : parsedMaxRuns
339
- }
340
- });
341
- exit();
342
- } else if (key.backspace || key.delete) {
343
- setDoWorkMaxRuns((v) => v.slice(0, -1));
344
- } else if (key.escape) {
345
- setScreen("do-work-executor");
346
- } else if (key.ctrl && input === "c") {
347
- exit();
348
- } else if (input && !key.ctrl && !key.meta) {
349
- setDoWorkMaxRuns((v) => v + input);
350
- }
351
- } else if (screen === "do-work-discuss-prompt") {
352
- if (key.return) {
353
- let discussValue;
354
- if (doWorkDiscussPrompt) {
355
- writePromptFile("do-work-issue-discuss.md", doWorkDiscussPrompt);
356
- discussValue = "do-work-issue-discuss.md";
357
- }
358
- const current = readRawConfig();
359
- writeConfig({
360
- ...current,
361
- doWork: {
362
- ...current.doWork,
363
- prompts: { ...current.doWork?.prompts, issueDiscuss: discussValue }
364
- }
365
- });
366
- setScreen("prompts-menu");
367
- } else if (key.backspace || key.delete) {
368
- setDoWorkDiscussPrompt((v) => v.slice(0, -1));
369
- } else if (key.escape) {
370
- setScreen("prompts-menu");
371
- } else if (key.ctrl && input === "c") {
372
- exit();
373
- } else if (input && !key.ctrl && !key.meta) {
374
- setDoWorkDiscussPrompt((v) => v + input);
375
- }
376
- } else if (screen === "do-work-pr-prompt") {
377
- if (key.return) {
378
- let prValue;
379
- if (doWorkPrPrompt) {
380
- writePromptFile("do-work-pr-work.md", doWorkPrPrompt);
381
- prValue = "do-work-pr-work.md";
382
- }
383
- const current = readRawConfig();
384
- writeConfig({
385
- ...current,
386
- doWork: {
387
- ...current.doWork,
388
- prompts: { ...current.doWork?.prompts, prWork: prValue }
389
- }
390
- });
391
- setScreen("prompts-menu");
392
- } else if (key.backspace || key.delete) {
393
- setDoWorkPrPrompt((v) => v.slice(0, -1));
394
- } else if (key.escape) {
395
- setScreen("prompts-menu");
396
- } else if (key.ctrl && input === "c") {
397
- exit();
398
- } else if (input && !key.ctrl && !key.meta) {
399
- setDoWorkPrPrompt((v) => v + input);
400
- }
401
413
  }
402
414
  });
403
415
  if (screen === "main") {
package/dist/index.js CHANGED
@@ -175,7 +175,7 @@ var configCommand = new Command("config").description("Configure automata settin
175
175
  const [{ render }, React, { ConfigWizard }] = await Promise.all([
176
176
  import("ink"),
177
177
  import("react"),
178
- import("./ConfigWizard-HIO2ZAEZ.js")
178
+ import("./ConfigWizard-KXVUQJ76.js")
179
179
  ]);
180
180
  const { waitUntilExit } = render(React.createElement(ConfigWizard));
181
181
  await waitUntilExit();
@@ -699,6 +699,22 @@ function checkoutAndPull(targetBranch) {
699
699
  throw new Error(`Failed to pull ${targetBranch}: ${pull.stderr.trim()}`);
700
700
  }
701
701
  }
702
+ function gitCommand(args) {
703
+ const { stderr, status } = run2("git", args);
704
+ return { ok: status === 0, stderr: stderr.trim() };
705
+ }
706
+ function checkoutBranch(branch) {
707
+ return gitCommand(["checkout", branch]);
708
+ }
709
+ function createTrackingBranch(branch) {
710
+ return gitCommand(["checkout", "-b", branch, `origin/${branch}`]);
711
+ }
712
+ function fetchBranch(branch) {
713
+ return gitCommand(["fetch", "origin", branch]);
714
+ }
715
+ function pullFastForwardOnly(branch) {
716
+ return gitCommand(branch === void 0 ? ["pull", "--ff-only"] : ["pull", "--ff-only", "origin", branch]);
717
+ }
702
718
  function fetchPrune() {
703
719
  const result = run2("git", ["fetch", "--prune"]);
704
720
  if (result.status !== 0) {
@@ -1297,7 +1313,7 @@ minor segment is incremented (e.g. 1.2.0 \u2192 1.3.0).`
1297
1313
  `);
1298
1314
  }
1299
1315
  });
1300
- var gitCommand = new Command2("git").description("Git workflow commands (some require gh CLI)").addCommand(getPrInfoCmd).addCommand(getPrCommentsCmd).addCommand(finishFeatureCmd).addCommand(publishReleaseCmd);
1316
+ var gitCommand2 = new Command2("git").description("Git workflow commands (some require gh CLI)").addCommand(getPrInfoCmd).addCommand(getPrCommentsCmd).addCommand(finishFeatureCmd).addCommand(publishReleaseCmd);
1301
1317
 
1302
1318
  // src/commands/getReady.ts
1303
1319
  import { createInterface as createInterface2 } from "readline";
@@ -1901,8 +1917,8 @@ function analyzeSurface(messages, p) {
1901
1917
  }
1902
1918
  function lastAuthorClass(messages, p) {
1903
1919
  if (messages.length === 0) return "none";
1904
- const newest = [...messages].sort(byCreatedAt)[messages.length - 1];
1905
- return classify(newest.author, p);
1920
+ const newest = [...messages].sort(byCreatedAt).at(-1);
1921
+ return newest === void 0 ? "none" : classify(newest.author, p);
1906
1922
  }
1907
1923
  function formatMessages(messages) {
1908
1924
  return messages.map((message) => {
@@ -2330,6 +2346,11 @@ query($owner:String!,$repo:String!,$prNumber:Int!){
2330
2346
  }
2331
2347
  }
2332
2348
  }`.trim();
2349
+ function normalizePrState(state) {
2350
+ if (state === "MERGED") return "MERGED";
2351
+ if (state === "CLOSED") return "CLOSED";
2352
+ return "OPEN";
2353
+ }
2333
2354
  function getPrSurface(prNumber) {
2334
2355
  const raw = ghJson(
2335
2356
  [
@@ -2386,7 +2407,7 @@ function getPrSurface(prNumber) {
2386
2407
  })).sort(byCreatedAt2)
2387
2408
  })
2388
2409
  );
2389
- const state = raw.state === "MERGED" ? "MERGED" : raw.state === "CLOSED" ? "CLOSED" : "OPEN";
2410
+ const state = normalizePrState(raw.state);
2390
2411
  return {
2391
2412
  pr: {
2392
2413
  number: raw.number,
@@ -2562,7 +2583,7 @@ function agentAnsweredAfter(messages, agentUser, marker) {
2562
2583
  function formatThreads(threads) {
2563
2584
  return threads.map((thread) => {
2564
2585
  const location = thread.line === null ? `${thread.path}:(file)` : `${thread.path}:${String(thread.line)}`;
2565
- const newest = thread.comments[thread.comments.length - 1];
2586
+ const newest = thread.comments.at(-1);
2566
2587
  const author = newest?.author ?? "unknown";
2567
2588
  const body = newest?.body ?? "";
2568
2589
  return `[${author}] ${location}
@@ -2629,18 +2650,6 @@ function composePrompt(input) {
2629
2650
  }
2630
2651
 
2631
2652
  // src/git/workspaceService.ts
2632
- import { spawnSync as spawnSync7 } from "child_process";
2633
- function git(args) {
2634
- const result = spawnSync7("git", args, { encoding: "utf8" });
2635
- if (result.error) {
2636
- const err = result.error;
2637
- if (err.code === "ENOENT") {
2638
- throw new Error("`git` is not installed or not on PATH.");
2639
- }
2640
- throw new Error(err.message);
2641
- }
2642
- return { stdout: result.stdout ?? "", stderr: result.stderr ?? "", status: result.status ?? 1 };
2643
- }
2644
2653
  function dirtyTree() {
2645
2654
  return {
2646
2655
  ok: false,
@@ -2650,33 +2659,33 @@ function dirtyTree() {
2650
2659
  }
2651
2660
  function prepareBaseBranch(baseBranch) {
2652
2661
  if (hasUncommittedChanges()) return dirtyTree();
2653
- const checkout = git(["checkout", baseBranch]);
2654
- if (checkout.status !== 0) {
2655
- return { ok: false, reason: "checkout-failed", detail: checkout.stderr.trim() };
2662
+ const checkout = checkoutBranch(baseBranch);
2663
+ if (!checkout.ok) {
2664
+ return { ok: false, reason: "checkout-failed", detail: checkout.stderr };
2656
2665
  }
2657
- const pull = git(["pull", "--ff-only"]);
2658
- if (pull.status !== 0) {
2659
- return { ok: false, reason: "pull-failed", detail: pull.stderr.trim() };
2666
+ const pull = pullFastForwardOnly();
2667
+ if (!pull.ok) {
2668
+ return { ok: false, reason: "pull-failed", detail: pull.stderr };
2660
2669
  }
2661
2670
  return { ok: true, branch: baseBranch };
2662
2671
  }
2663
2672
  function preparePrBranch(headRefName) {
2664
2673
  if (hasUncommittedChanges()) return dirtyTree();
2665
- const fetch2 = git(["fetch", "origin", headRefName]);
2666
- if (fetch2.status !== 0) {
2667
- return { ok: false, reason: "checkout-failed", detail: fetch2.stderr.trim() };
2668
- }
2669
- const checkout = git(["checkout", headRefName]);
2670
- if (checkout.status !== 0) {
2671
- const created = git(["checkout", "-b", headRefName, `origin/${headRefName}`]);
2672
- if (created.status !== 0) {
2673
- return { ok: false, reason: "checkout-failed", detail: created.stderr.trim() };
2674
+ const fetched = fetchBranch(headRefName);
2675
+ if (!fetched.ok) {
2676
+ return { ok: false, reason: "checkout-failed", detail: fetched.stderr };
2677
+ }
2678
+ const checkout = checkoutBranch(headRefName);
2679
+ if (!checkout.ok) {
2680
+ const created = createTrackingBranch(headRefName);
2681
+ if (!created.ok) {
2682
+ return { ok: false, reason: "checkout-failed", detail: created.stderr };
2674
2683
  }
2675
2684
  return { ok: true, branch: headRefName };
2676
2685
  }
2677
- const pull = git(["pull", "--ff-only", "origin", headRefName]);
2678
- if (pull.status !== 0) {
2679
- return { ok: false, reason: "pull-failed", detail: pull.stderr.trim() };
2686
+ const pull = pullFastForwardOnly(headRefName);
2687
+ if (!pull.ok) {
2688
+ return { ok: false, reason: "pull-failed", detail: pull.stderr };
2680
2689
  }
2681
2690
  return { ok: true, branch: headRefName };
2682
2691
  }
@@ -3140,7 +3149,7 @@ function toPlanJson(decision) {
3140
3149
  var program = new Command7();
3141
3150
  program.name("automata").description("Automata CLI tool").version(version, "-v, --version");
3142
3151
  program.addCommand(configCommand);
3143
- program.addCommand(gitCommand);
3152
+ program.addCommand(gitCommand2);
3144
3153
  program.addCommand(implementNextCommand);
3145
3154
  program.addCommand(executeCommand);
3146
3155
  program.addCommand(executePromptCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "automata-cli",
3
- "version": "0.1.0-feature-030-do-work.182",
3
+ "version": "0.1.0-feature-030-do-work.184",
4
4
  "description": "Automata CLI tool",
5
5
  "type": "module",
6
6
  "bin": {