@autohq/cli 0.1.123 → 0.1.124

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.
@@ -26269,7 +26269,7 @@ Object.assign(lookup, {
26269
26269
  // package.json
26270
26270
  var package_default = {
26271
26271
  name: "@autohq/cli",
26272
- version: "0.1.123",
26272
+ version: "0.1.124",
26273
26273
  license: "SEE LICENSE IN README.md",
26274
26274
  publishConfig: {
26275
26275
  access: "public"
package/dist/index.js CHANGED
@@ -18783,7 +18783,12 @@ var init_run_diagnostics = __esm({
18783
18783
  });
18784
18784
 
18785
18785
  // ../../packages/schemas/src/session-runs.ts
18786
- var SESSION_RUN_STATUSES, SESSION_RUN_DISPLAY_TITLE_MAX_LENGTH, SessionRunStatusSchema, SessionRunDisplayTitleSchema, SESSION_RUN_CHECK_STATUSES, SESSION_RUN_CHECK_CONCLUSIONS, SESSION_RUN_CHECK_TIMEOUT_PHASES, SessionRunCheckStatusSchema, SessionRunCheckConclusionSchema, SessionRunCheckTimeoutPhaseSchema, ManualSessionRunRequestSchema, SessionRunArchiveRequestSchema, SessionRunsArchiveRequestSchema, SessionRunRecordSchema, SessionRunsArchiveResponseSchema;
18786
+ function isSessionRunTerminalStatus(status) {
18787
+ return SESSION_RUN_TERMINAL_STATUSES.some(
18788
+ (terminalStatus) => terminalStatus === status
18789
+ );
18790
+ }
18791
+ var SESSION_RUN_STATUSES, SESSION_RUN_TERMINAL_STATUSES, SESSION_RUN_DISPLAY_TITLE_MAX_LENGTH, SessionRunStatusSchema, SessionRunDisplayTitleSchema, SESSION_RUN_CHECK_STATUSES, SESSION_RUN_CHECK_CONCLUSIONS, SESSION_RUN_CHECK_TIMEOUT_PHASES, SessionRunCheckStatusSchema, SessionRunCheckConclusionSchema, SessionRunCheckTimeoutPhaseSchema, ManualSessionRunRequestSchema, SessionRunArchiveRequestSchema, SessionRunsArchiveRequestSchema, SessionRunRecordSchema, SessionRunsArchiveResponseSchema;
18787
18792
  var init_session_runs = __esm({
18788
18793
  "../../packages/schemas/src/session-runs.ts"() {
18789
18794
  "use strict";
@@ -18802,6 +18807,7 @@ var init_session_runs = __esm({
18802
18807
  "failed",
18803
18808
  "stopped"
18804
18809
  ];
18810
+ SESSION_RUN_TERMINAL_STATUSES = ["failed", "stopped"];
18805
18811
  SESSION_RUN_DISPLAY_TITLE_MAX_LENGTH = 64;
18806
18812
  SessionRunStatusSchema = external_exports.enum(SESSION_RUN_STATUSES);
18807
18813
  SessionRunDisplayTitleSchema = external_exports.string().trim().max(SESSION_RUN_DISPLAY_TITLE_MAX_LENGTH);
@@ -21231,7 +21237,7 @@ var init_package = __esm({
21231
21237
  "package.json"() {
21232
21238
  package_default = {
21233
21239
  name: "@autohq/cli",
21234
- version: "0.1.123",
21240
+ version: "0.1.124",
21235
21241
  license: "SEE LICENSE IN README.md",
21236
21242
  publishConfig: {
21237
21243
  access: "public"
@@ -24907,6 +24913,39 @@ function useUnarchiveRuns(apiUrl) {
24907
24913
  onSuccess: (result) => invalidateRunsQueries(queryClient, apiUrl, result.runs)
24908
24914
  });
24909
24915
  }
24916
+ function useStopRuns(apiUrl) {
24917
+ const client = useApiClient();
24918
+ const queryClient = useQueryClient();
24919
+ return useMutation({
24920
+ mutationFn: (runIds) => stopRunsBatch(
24921
+ (runId) => client.stopRun(runId, { apiBaseUrl: apiUrl }),
24922
+ runIds
24923
+ ),
24924
+ // stopRun returns a command receipt, not run records, so invalidate the
24925
+ // run-list query families directly to pick up the new statuses.
24926
+ onSuccess: () => invalidateRunListQueries(queryClient, apiUrl)
24927
+ });
24928
+ }
24929
+ async function stopRunsBatch(stopRun, runIds) {
24930
+ const outcomes = await Promise.all(
24931
+ runIds.map(async (runId) => {
24932
+ try {
24933
+ await stopRun(runId);
24934
+ return { runId, ok: true, message: "" };
24935
+ } catch (error51) {
24936
+ return {
24937
+ runId,
24938
+ ok: false,
24939
+ message: error51 instanceof Error ? error51.message : String(error51)
24940
+ };
24941
+ }
24942
+ })
24943
+ );
24944
+ return {
24945
+ stopped: outcomes.filter((o) => o.ok).map((o) => o.runId),
24946
+ failed: outcomes.filter((o) => !o.ok).map((o) => ({ runId: o.runId, message: o.message }))
24947
+ };
24948
+ }
24910
24949
  function sessionRunsQueryOptions(client, sessionName, apiUrl, includeArchived = false) {
24911
24950
  return queryOptions({
24912
24951
  queryKey: queryKeys.sessionRuns(sessionName ?? "", apiUrl, includeArchived),
@@ -25047,6 +25086,10 @@ function invalidateRunsQueries(queryClient, apiUrl, runs) {
25047
25086
  });
25048
25087
  }
25049
25088
  }
25089
+ function invalidateRunListQueries(queryClient, apiUrl) {
25090
+ void queryClient.invalidateQueries({ queryKey: ["runs", apiUrl] });
25091
+ void queryClient.invalidateQueries({ queryKey: ["session-runs"] });
25092
+ }
25050
25093
  var TUI_RUN_LIST_LIMIT, queryKeys, RUNS_REFETCH_INTERVAL_MS;
25051
25094
  var init_queries = __esm({
25052
25095
  "src/tui/hooks/queries.ts"() {
@@ -25579,6 +25622,9 @@ function HomeView({ apiUrl, notice, returnToSession }) {
25579
25622
  );
25580
25623
  const [pendingArchiveRunKey, setPendingArchiveRunKey] = useState3(null);
25581
25624
  const [pendingUnarchiveRunKey, setPendingUnarchiveRunKey] = useState3(null);
25625
+ const [pendingStopRunKey, setPendingStopRunKey] = useState3(
25626
+ null
25627
+ );
25582
25628
  const [runNotice, setRunNotice] = useState3(null);
25583
25629
  const [connectionIndex, setConnectionIndex] = useState3(0);
25584
25630
  const [connectionProviderIndex, setConnectionProviderIndex] = useState3(0);
@@ -25644,6 +25690,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
25644
25690
  const triggerRun = useTriggerRun(apiUrl);
25645
25691
  const archiveRuns = useArchiveRuns(apiUrl);
25646
25692
  const unarchiveRuns = useUnarchiveRuns(apiUrl);
25693
+ const stopRuns = useStopRuns(apiUrl);
25647
25694
  const [connectionNotice, setConnectionNotice] = useState3(null);
25648
25695
  const [serviceAccountNotice, setServiceAccountNotice] = useState3(null);
25649
25696
  const [pendingRemoveConnectionKey, setPendingRemoveConnectionKey] = useState3(null);
@@ -25841,8 +25888,10 @@ function HomeView({ apiUrl, notice, returnToSession }) {
25841
25888
  const toggleSelectedRun = useCallback2(() => {
25842
25889
  setPendingArchiveRunKey(null);
25843
25890
  setPendingUnarchiveRunKey(null);
25891
+ setPendingStopRunKey(null);
25844
25892
  archiveRuns.reset();
25845
25893
  unarchiveRuns.reset();
25894
+ stopRuns.reset();
25846
25895
  if (!selectedRun) {
25847
25896
  setRunNotice("Select a run before marking it.");
25848
25897
  return;
@@ -25860,11 +25909,13 @@ function HomeView({ apiUrl, notice, returnToSession }) {
25860
25909
  setRunNotice(
25861
25910
  wasSelected ? `Unmarked run ${shortRunId2(selectedRun.id)}.` : `Marked run ${shortRunId2(selectedRun.id)}.`
25862
25911
  );
25863
- }, [archiveRuns, selectedRun, selectedRunIds, unarchiveRuns]);
25912
+ }, [archiveRuns, selectedRun, selectedRunIds, stopRuns, unarchiveRuns]);
25864
25913
  const archiveSelectedRun = useCallback2(() => {
25865
25914
  archiveRuns.reset();
25866
25915
  unarchiveRuns.reset();
25916
+ stopRuns.reset();
25867
25917
  setPendingUnarchiveRunKey(null);
25918
+ setPendingStopRunKey(null);
25868
25919
  const runIds = runIdsForArchiveAction({
25869
25920
  markedRunIds,
25870
25921
  selectedRun
@@ -25894,12 +25945,15 @@ function HomeView({ apiUrl, notice, returnToSession }) {
25894
25945
  markedRunIds,
25895
25946
  pendingArchiveRunKey,
25896
25947
  selectedRun,
25948
+ stopRuns,
25897
25949
  unarchiveRuns
25898
25950
  ]);
25899
25951
  const unarchiveSelectedRun = useCallback2(() => {
25900
25952
  archiveRuns.reset();
25901
25953
  unarchiveRuns.reset();
25954
+ stopRuns.reset();
25902
25955
  setPendingArchiveRunKey(null);
25956
+ setPendingStopRunKey(null);
25903
25957
  const runIds = runIdsForArchiveAction({
25904
25958
  markedRunIds,
25905
25959
  selectedRun
@@ -25929,8 +25983,59 @@ function HomeView({ apiUrl, notice, returnToSession }) {
25929
25983
  markedRunIds,
25930
25984
  pendingUnarchiveRunKey,
25931
25985
  selectedRun,
25986
+ stopRuns,
25932
25987
  unarchiveRuns
25933
25988
  ]);
25989
+ const stopSelectedRuns = useCallback2(() => {
25990
+ stopRuns.reset();
25991
+ archiveRuns.reset();
25992
+ unarchiveRuns.reset();
25993
+ setPendingArchiveRunKey(null);
25994
+ setPendingUnarchiveRunKey(null);
25995
+ const runIds = runIdsForArchiveAction({ markedRunIds, selectedRun });
25996
+ if (runIds.length === 0) {
25997
+ setPendingStopRunKey(null);
25998
+ setRunNotice("Select a run before stopping.");
25999
+ return;
26000
+ }
26001
+ const runsById = new Map(visibleRuns.map((run) => [run.id, run]));
26002
+ const { stoppableRunIds, skippedRunIds } = partitionRunsForStop(
26003
+ runIds,
26004
+ runsById
26005
+ );
26006
+ if (stoppableRunIds.length === 0) {
26007
+ setPendingStopRunKey(null);
26008
+ setRunNotice(
26009
+ `Nothing to stop \u2014 ${pluralizeRunCount(skippedRunIds.length)} already stopped or failed.`
26010
+ );
26011
+ return;
26012
+ }
26013
+ const actionKey = runArchiveActionKey(stoppableRunIds);
26014
+ if (pendingStopRunKey !== actionKey) {
26015
+ setPendingStopRunKey(actionKey);
26016
+ const skipNote = skippedRunIds.length > 0 ? ` (skipping ${pluralizeRunCount(skippedRunIds.length)} already stopped or failed)` : "";
26017
+ setRunNotice(
26018
+ `Press s again to stop ${stopTargetLabel(stoppableRunIds, markedRunIds.length > 0)}${skipNote}.`
26019
+ );
26020
+ return;
26021
+ }
26022
+ setPendingStopRunKey(null);
26023
+ setRunNotice(null);
26024
+ stopRuns.mutate(stoppableRunIds, {
26025
+ onSuccess: (result) => {
26026
+ setSelectedRunIds(/* @__PURE__ */ new Set());
26027
+ setRunNotice(stopResultNotice(result, skippedRunIds.length));
26028
+ }
26029
+ });
26030
+ }, [
26031
+ archiveRuns,
26032
+ markedRunIds,
26033
+ pendingStopRunKey,
26034
+ selectedRun,
26035
+ stopRuns,
26036
+ unarchiveRuns,
26037
+ visibleRuns
26038
+ ]);
25934
26039
  const projectSelectionRequired = /No active (organization|project)/i.test(authErrorMessage ?? "") && projects.length > 0;
25935
26040
  useEffect3(() => {
25936
26041
  if (projectSelectionRequired) {
@@ -26091,6 +26196,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26091
26196
  setSelectedRunIds(/* @__PURE__ */ new Set());
26092
26197
  setPendingArchiveRunKey(null);
26093
26198
  setPendingUnarchiveRunKey(null);
26199
+ setPendingStopRunKey(null);
26094
26200
  setRunNotice(null);
26095
26201
  triggerRun.reset();
26096
26202
  return;
@@ -26102,6 +26208,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26102
26208
  setSelectedRunIds(/* @__PURE__ */ new Set());
26103
26209
  setPendingArchiveRunKey(null);
26104
26210
  setPendingUnarchiveRunKey(null);
26211
+ setPendingStopRunKey(null);
26105
26212
  setRunNotice(null);
26106
26213
  setSection("runs");
26107
26214
  triggerRun.reset();
@@ -26125,6 +26232,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26125
26232
  setSelectedRunIds(/* @__PURE__ */ new Set());
26126
26233
  setPendingArchiveRunKey(null);
26127
26234
  setPendingUnarchiveRunKey(null);
26235
+ setPendingStopRunKey(null);
26128
26236
  setRunNotice(null);
26129
26237
  setShowArchivedRuns(false);
26130
26238
  }
@@ -26208,6 +26316,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26208
26316
  setSelectedRunIds(/* @__PURE__ */ new Set());
26209
26317
  setPendingArchiveRunKey(null);
26210
26318
  setPendingUnarchiveRunKey(null);
26319
+ setPendingStopRunKey(null);
26211
26320
  setRunNotice(null);
26212
26321
  setSection("runs");
26213
26322
  triggerRun.reset();
@@ -26226,9 +26335,11 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26226
26335
  setSelectedRunIds(/* @__PURE__ */ new Set());
26227
26336
  setPendingArchiveRunKey(null);
26228
26337
  setPendingUnarchiveRunKey(null);
26338
+ setPendingStopRunKey(null);
26229
26339
  setRunNotice(null);
26230
26340
  archiveRuns.reset();
26231
26341
  unarchiveRuns.reset();
26342
+ stopRuns.reset();
26232
26343
  return;
26233
26344
  }
26234
26345
  if (input === " ") {
@@ -26243,6 +26354,10 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26243
26354
  archiveSelectedRun();
26244
26355
  return;
26245
26356
  }
26357
+ if (input === "s" && !showArchivedRuns) {
26358
+ stopSelectedRuns();
26359
+ return;
26360
+ }
26246
26361
  if (input === "u" && showArchivedRuns) {
26247
26362
  unarchiveSelectedRun();
26248
26363
  return;
@@ -26250,12 +26365,14 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26250
26365
  if (key.upArrow) {
26251
26366
  setPendingArchiveRunKey(null);
26252
26367
  setPendingUnarchiveRunKey(null);
26368
+ setPendingStopRunKey(null);
26253
26369
  setRunIndex((i) => Math.max(0, i - 1));
26254
26370
  return;
26255
26371
  }
26256
26372
  if (key.downArrow) {
26257
26373
  setPendingArchiveRunKey(null);
26258
26374
  setPendingUnarchiveRunKey(null);
26375
+ setPendingStopRunKey(null);
26259
26376
  setRunIndex((i) => clampListIndex(i + 1, visibleRuns.length));
26260
26377
  return;
26261
26378
  }
@@ -26616,8 +26733,8 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26616
26733
  if (inspectedResource) {
26617
26734
  sectionTitle = `Inspect ${inspectedResource.kind}/${inspectedResource.name}`;
26618
26735
  }
26619
- const runError = errorMessage2(triggerRun.error) ?? errorMessage2(archiveRuns.error) ?? errorMessage2(unarchiveRuns.error);
26620
- const isRunMutationPending = triggerRun.isPending || archiveRuns.isPending || unarchiveRuns.isPending;
26736
+ const runError = errorMessage2(triggerRun.error) ?? errorMessage2(archiveRuns.error) ?? errorMessage2(unarchiveRuns.error) ?? errorMessage2(stopRuns.error);
26737
+ const isRunMutationPending = triggerRun.isPending || archiveRuns.isPending || unarchiveRuns.isPending || stopRuns.isPending;
26621
26738
  const isConnectionMutationPending = startConnection.isPending || allowConnection.isPending || removeConnection.isPending;
26622
26739
  const serviceAccountStatus = createServiceAccount2.error instanceof Error ? createServiceAccount2.error.message : rotateServiceAccount2.error instanceof Error ? rotateServiceAccount2.error.message : removeServiceAccount2.error instanceof Error ? removeServiceAccount2.error.message : serviceAccountNotice;
26623
26740
  const isServiceAccountMutationPending = createServiceAccount2.isPending || rotateServiceAccount2.isPending || removeServiceAccount2.isPending;
@@ -26639,7 +26756,11 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26639
26756
  value: /* @__PURE__ */ jsx14(
26640
26757
  Spinner,
26641
26758
  {
26642
- label: triggerRun.isPending ? "starting\u2026" : archiveRuns.isPending ? "archiving\u2026" : "restoring\u2026"
26759
+ label: runMutationStatusLabel({
26760
+ starting: triggerRun.isPending,
26761
+ archiving: archiveRuns.isPending,
26762
+ stopping: stopRuns.isPending
26763
+ })
26643
26764
  }
26644
26765
  )
26645
26766
  }
@@ -26728,6 +26849,7 @@ function HomeView({ apiUrl, notice, returnToSession }) {
26728
26849
  },
26729
26850
  ...showArchivedRuns ? [{ k: "u", label: "Restore" }] : [
26730
26851
  { k: "a", label: "Archive" },
26852
+ { k: "s", label: "Stop" },
26731
26853
  ...scopedSession ? [{ k: "n", label: "New run" }] : []
26732
26854
  ],
26733
26855
  { k: "esc", label: "Back" },
@@ -26961,6 +27083,38 @@ function selectedRunIdsForVisibleRuns(runs, selectedRunIds) {
26961
27083
  function runIdsForArchiveAction(input) {
26962
27084
  return input.markedRunIds.length > 0 ? input.markedRunIds : input.selectedRun ? [input.selectedRun.id] : [];
26963
27085
  }
27086
+ function partitionRunsForStop(runIds, runsById) {
27087
+ const stoppableRunIds = [];
27088
+ const skippedRunIds = [];
27089
+ for (const runId of runIds) {
27090
+ const run = runsById.get(runId);
27091
+ if (run && isSessionRunTerminalStatus(run.status)) {
27092
+ skippedRunIds.push(runId);
27093
+ } else {
27094
+ stoppableRunIds.push(runId);
27095
+ }
27096
+ }
27097
+ return { stoppableRunIds, skippedRunIds };
27098
+ }
27099
+ function stopTargetLabel(runIds, bulk) {
27100
+ return bulk ? pluralizeRunCount(runIds.length) : `run ${shortRunId2(runIds[0] ?? "")}`;
27101
+ }
27102
+ function stopResultNotice(result, skippedCount) {
27103
+ const parts = [`Stopped ${pluralizeRunCount(result.stopped.length)}`];
27104
+ if (result.failed.length > 0) {
27105
+ parts.push(`failed to stop ${result.failed.length}`);
27106
+ }
27107
+ if (skippedCount > 0) {
27108
+ parts.push(`skipped ${skippedCount} already stopped or failed`);
27109
+ }
27110
+ return `${parts.join(", ")}.`;
27111
+ }
27112
+ function runMutationStatusLabel(pending) {
27113
+ if (pending.starting) return "starting\u2026";
27114
+ if (pending.archiving) return "archiving\u2026";
27115
+ if (pending.stopping) return "stopping\u2026";
27116
+ return "restoring\u2026";
27117
+ }
26964
27118
  function runArchiveActionKey(runIds) {
26965
27119
  return runIds.join("\0");
26966
27120
  }
@@ -27074,6 +27228,7 @@ var CONNECTION_REFRESH_INTERVAL_MS, CONNECTION_REFRESH_TIMEOUT_MS, DASHBOARD_NAV
27074
27228
  var init_HomeView = __esm({
27075
27229
  "src/tui/HomeView.tsx"() {
27076
27230
  "use strict";
27231
+ init_src();
27077
27232
  init_login();
27078
27233
  init_base_url();
27079
27234
  init_browser();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.123",
3
+ "version": "0.1.124",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"