@brainervirus/workit-cli 8.42.0 → 8.43.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 (2) hide show
  1. package/dist/index.js +395 -340
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -9417,7 +9417,7 @@ var package_default;
9417
9417
  var init_package = __esm(() => {
9418
9418
  package_default = {
9419
9419
  name: "@brainervirus/workit-cli",
9420
- version: "8.42.0",
9420
+ version: "8.43.0",
9421
9421
  private: false,
9422
9422
  description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
9423
9423
  keywords: [
@@ -9455,13 +9455,13 @@ var init_package = __esm(() => {
9455
9455
  },
9456
9456
  dependencies: {
9457
9457
  "@babel/parser": "7.29.9",
9458
- "@brainervirus/workit-cursor": "^8.42.0",
9458
+ "@brainervirus/workit-cursor": "^8.43.0",
9459
9459
  "@inkjs/ui": "2.0.0",
9460
9460
  ink: "7.1.1",
9461
9461
  react: "19.2.8"
9462
9462
  },
9463
9463
  devDependencies: {
9464
- "@brainervirus/workit-core": "^8.42.0"
9464
+ "@brainervirus/workit-core": "^8.43.0"
9465
9465
  },
9466
9466
  engines: {
9467
9467
  node: ">=24"
@@ -73938,13 +73938,59 @@ var init_workspace_screens = __esm(async () => {
73938
73938
  jsx_dev_runtime5 = __toESM(require_jsx_dev_runtime(), 1);
73939
73939
  });
73940
73940
 
73941
+ // packages/workit-cli/src/steps/sphere-spinner.tsx
73942
+ function SphereSpinner({
73943
+ label,
73944
+ stream = process.stdout,
73945
+ env = process.env,
73946
+ now = Date.now
73947
+ }) {
73948
+ const mode = terminalMode({ stream, env });
73949
+ const [began] = import_react68.useState(now);
73950
+ const [tick, setTick] = import_react68.useState(0);
73951
+ import_react68.useEffect(() => {
73952
+ if (mode === "off")
73953
+ return;
73954
+ const timer = setInterval(() => setTick((n) => n + 1), SPINNER_FRAME_MS);
73955
+ return () => clearInterval(timer);
73956
+ }, [mode]);
73957
+ if (mode === "off")
73958
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
73959
+ children: [
73960
+ label,
73961
+ "…"
73962
+ ]
73963
+ }, undefined, true, undefined, this);
73964
+ const elapsed = now() - began;
73965
+ const frame = SPINNER_FRAMES[tick % SPINNER_FRAMES.length] ?? "";
73966
+ const glyph = mode === "spinner" ? spinnerPaint(elapsed, env, frame) : frame;
73967
+ const shown = env.TERM === "dumb" ? "..." : glyph;
73968
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
73969
+ children: [
73970
+ shown,
73971
+ " ",
73972
+ label,
73973
+ " (",
73974
+ Math.floor(elapsed / 1000),
73975
+ "s)"
73976
+ ]
73977
+ }, undefined, true, undefined, this);
73978
+ }
73979
+ var import_react68, jsx_dev_runtime6;
73980
+ var init_sphere_spinner = __esm(async () => {
73981
+ init_style();
73982
+ await init_build2();
73983
+ import_react68 = __toESM(require_react(), 1);
73984
+ jsx_dev_runtime6 = __toESM(require_jsx_dev_runtime(), 1);
73985
+ });
73986
+
73941
73987
  // packages/workit-cli/src/steps/finish-screens.tsx
73942
73988
  function BranchPolicyScreen({ draft, dispatch }) {
73943
73989
  const detected = draft.values.branchPolicyDetected;
73944
73990
  const policy = draft.values.branchPolicy ?? detected;
73945
- const [mode, setMode] = import_react68.useState("menu");
73991
+ const [mode, setMode] = import_react69.useState("menu");
73946
73992
  const basePath = resolveBasePath(draft.values);
73947
- import_react68.useEffect(() => {
73993
+ import_react69.useEffect(() => {
73948
73994
  if (detected)
73949
73995
  return;
73950
73996
  dispatch({
@@ -73954,15 +74000,15 @@ function BranchPolicyScreen({ draft, dispatch }) {
73954
74000
  });
73955
74001
  }, [detected, dispatch, basePath]);
73956
74002
  if (mode === "integration") {
73957
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74003
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
73958
74004
  flexDirection: "column",
73959
74005
  gap: 1,
73960
74006
  children: [
73961
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74007
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
73962
74008
  bold: true,
73963
74009
  children: "Step 5 — Branch policy · Integration"
73964
74010
  }, undefined, false, undefined, this),
73965
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(SelectList, {
74011
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
73966
74012
  options: INTEGRATION_OPTIONS,
73967
74013
  value: policy?.integration ?? "merge",
73968
74014
  onSelect: (value) => {
@@ -73970,77 +74016,76 @@ function BranchPolicyScreen({ draft, dispatch }) {
73970
74016
  setMode("menu");
73971
74017
  }
73972
74018
  }, undefined, false, undefined, this),
73973
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74019
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
73974
74020
  dimColor: true,
73975
74021
  children: "Enter to select · b Back · Esc Cancel"
73976
74022
  }, undefined, false, undefined, this)
73977
74023
  ]
73978
74024
  }, undefined, true, undefined, this);
73979
74025
  }
73980
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74026
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
73981
74027
  flexDirection: "column",
73982
74028
  gap: 1,
73983
74029
  children: [
73984
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74030
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
73985
74031
  bold: true,
73986
74032
  children: "Step 5 — Branch policy"
73987
74033
  }, undefined, false, undefined, this),
73988
- policy ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74034
+ policy ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
73989
74035
  flexDirection: "column",
73990
74036
  gap: 0,
73991
74037
  children: [
73992
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74038
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
73993
74039
  children: [
73994
74040
  "Detected preset: ",
73995
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74041
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
73996
74042
  color: "green",
73997
74043
  children: policy.preset
73998
74044
  }, undefined, false, undefined, this)
73999
74045
  ]
74000
74046
  }, undefined, true, undefined, this),
74001
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74047
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74002
74048
  children: [
74003
74049
  "Develop branch: ",
74004
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74050
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74005
74051
  color: "green",
74006
74052
  children: policy.developBranch ?? "—"
74007
74053
  }, undefined, false, undefined, this)
74008
74054
  ]
74009
74055
  }, undefined, true, undefined, this),
74010
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74056
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74011
74057
  children: [
74012
74058
  "Integration: ",
74013
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74059
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74014
74060
  color: "green",
74015
74061
  children: policy.integration
74016
74062
  }, undefined, false, undefined, this)
74017
74063
  ]
74018
74064
  }, undefined, true, undefined, this),
74019
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74065
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74020
74066
  children: [
74021
74067
  "Prefixes:",
74022
74068
  " ",
74023
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74069
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74024
74070
  color: "green",
74025
74071
  children: Object.values(policy.prefixes ?? {}).join(", ") || "—"
74026
74072
  }, undefined, false, undefined, this)
74027
74073
  ]
74028
74074
  }, undefined, true, undefined, this),
74029
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74075
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74030
74076
  children: [
74031
74077
  "Protected: ",
74032
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74078
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74033
74079
  color: "green",
74034
74080
  children: policy.protected?.join(", ") || "—"
74035
74081
  }, undefined, false, undefined, this)
74036
74082
  ]
74037
74083
  }, undefined, true, undefined, this)
74038
74084
  ]
74039
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74040
- dimColor: true,
74041
- children: "Detecting branch policy…"
74085
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SphereSpinner, {
74086
+ label: "Detecting branch policy"
74042
74087
  }, undefined, false, undefined, this),
74043
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(SelectList, {
74088
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
74044
74089
  options: BRANCH_POLICY_ACTIONS,
74045
74090
  value: "accept",
74046
74091
  onSelect: (value) => {
@@ -74056,7 +74101,7 @@ function BranchPolicyScreen({ draft, dispatch }) {
74056
74101
  dispatch({ type: "next" });
74057
74102
  }
74058
74103
  }, undefined, false, undefined, this),
74059
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74104
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74060
74105
  dimColor: true,
74061
74106
  children: "Enter to continue · b Back · Esc Cancel"
74062
74107
  }, undefined, false, undefined, this)
@@ -74093,33 +74138,33 @@ function mutationRows(mutations) {
74093
74138
  });
74094
74139
  }
74095
74140
  function BasePathScreen({ draft, dispatch }) {
74096
- const onChange = import_react68.useCallback((value) => dispatch({ type: "set", field: "basePath", value }), [dispatch]);
74097
- const onSubmit = import_react68.useCallback((value) => {
74141
+ const onChange = import_react69.useCallback((value) => dispatch({ type: "set", field: "basePath", value }), [dispatch]);
74142
+ const onSubmit = import_react69.useCallback((value) => {
74098
74143
  dispatch({ type: "set", field: "basePath", value });
74099
74144
  dispatch({ type: "next" });
74100
74145
  }, [dispatch]);
74101
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74146
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74102
74147
  flexDirection: "column",
74103
74148
  gap: 1,
74104
74149
  children: [
74105
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74150
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74106
74151
  bold: true,
74107
74152
  children: "Step 5 — Workspace root"
74108
74153
  }, undefined, false, undefined, this),
74109
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74154
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74110
74155
  dimColor: true,
74111
74156
  children: "Absolute path where your projects live (e.g. /work):"
74112
74157
  }, undefined, false, undefined, this),
74113
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(TextInput, {
74158
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TextInput, {
74114
74159
  defaultValue: draft.values.basePath,
74115
74160
  onChange,
74116
74161
  onSubmit
74117
74162
  }, undefined, false, undefined, this),
74118
- draft.errors.basePath && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74163
+ draft.errors.basePath && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74119
74164
  color: "red",
74120
74165
  children: draft.errors.basePath
74121
74166
  }, undefined, false, undefined, this),
74122
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74167
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74123
74168
  dimColor: true,
74124
74169
  children: "Enter to continue · Esc Back"
74125
74170
  }, undefined, false, undefined, this)
@@ -74127,19 +74172,19 @@ function BasePathScreen({ draft, dispatch }) {
74127
74172
  }, undefined, true, undefined, this);
74128
74173
  }
74129
74174
  function BranchPolicyDevelopScreen({ draft, dispatch }) {
74130
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74175
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74131
74176
  flexDirection: "column",
74132
74177
  gap: 1,
74133
74178
  children: [
74134
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74179
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74135
74180
  bold: true,
74136
74181
  children: "Step 5 — Branch policy · Develop branch"
74137
74182
  }, undefined, false, undefined, this),
74138
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74183
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74139
74184
  dimColor: true,
74140
74185
  children: "Integration/develop branch name (leave empty to unset):"
74141
74186
  }, undefined, false, undefined, this),
74142
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(TextInput, {
74187
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TextInput, {
74143
74188
  placeholder: SCREEN_PLACEHOLDERS.branchPolicyDevelop,
74144
74189
  defaultValue: draft.values.branchPolicy?.developBranch ?? draft.values.branchPolicyDetected?.developBranch ?? "",
74145
74190
  onSubmit: (value) => {
@@ -74147,7 +74192,7 @@ function BranchPolicyDevelopScreen({ draft, dispatch }) {
74147
74192
  dispatch({ type: "next" });
74148
74193
  }
74149
74194
  }, undefined, false, undefined, this),
74150
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74195
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74151
74196
  dimColor: true,
74152
74197
  children: "Enter to save · Esc Back"
74153
74198
  }, undefined, false, undefined, this)
@@ -74157,22 +74202,22 @@ function BranchPolicyDevelopScreen({ draft, dispatch }) {
74157
74202
  function ProjectScreen({ draft, dispatch }) {
74158
74203
  const target = projectTargetFor(resolveBasePath(draft.values));
74159
74204
  if (!target.ok) {
74160
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74205
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74161
74206
  flexDirection: "column",
74162
74207
  gap: 1,
74163
74208
  children: [
74164
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74209
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74165
74210
  bold: true,
74166
74211
  children: "Step 6 — Project setup"
74167
74212
  }, undefined, false, undefined, this),
74168
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74213
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74169
74214
  color: "yellow",
74170
74215
  children: [
74171
74216
  "Skipped: ",
74172
74217
  target.refused
74173
74218
  ]
74174
74219
  }, undefined, true, undefined, this),
74175
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ConfirmInput, {
74220
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(ConfirmInput, {
74176
74221
  defaultChoice: "confirm",
74177
74222
  submitOnEnter: false,
74178
74223
  onConfirm: () => {
@@ -74184,22 +74229,22 @@ function ProjectScreen({ draft, dispatch }) {
74184
74229
  dispatch({ type: "next" });
74185
74230
  }
74186
74231
  }, undefined, false, undefined, this),
74187
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74232
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74188
74233
  dimColor: true,
74189
74234
  children: "y to keep this note in the summary · n to skip it · either adds no project files · b Back · Esc Cancel"
74190
74235
  }, undefined, false, undefined, this)
74191
74236
  ]
74192
74237
  }, undefined, true, undefined, this);
74193
74238
  }
74194
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74239
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74195
74240
  flexDirection: "column",
74196
74241
  gap: 1,
74197
74242
  children: [
74198
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74243
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74199
74244
  bold: true,
74200
74245
  children: "Step 6 — Project setup"
74201
74246
  }, undefined, false, undefined, this),
74202
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74247
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74203
74248
  dimColor: true,
74204
74249
  children: [
74205
74250
  "Apply gitignore + hygiene in ",
@@ -74207,7 +74252,7 @@ function ProjectScreen({ draft, dispatch }) {
74207
74252
  "? (Existing files are never overwritten.)"
74208
74253
  ]
74209
74254
  }, undefined, true, undefined, this),
74210
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ConfirmInput, {
74255
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(ConfirmInput, {
74211
74256
  defaultChoice: "cancel",
74212
74257
  submitOnEnter: false,
74213
74258
  onConfirm: () => {
@@ -74219,7 +74264,7 @@ function ProjectScreen({ draft, dispatch }) {
74219
74264
  dispatch({ type: "next" });
74220
74265
  }
74221
74266
  }, undefined, false, undefined, this),
74222
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74267
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74223
74268
  dimColor: true,
74224
74269
  children: "y to add project files · n to skip · b Back · Esc Cancel"
74225
74270
  }, undefined, false, undefined, this)
@@ -74259,37 +74304,37 @@ function SummaryScreen({ draft, dispatch }) {
74259
74304
  }
74260
74305
  })();
74261
74306
  const canApply = preview.ok && policyPreview.error === null;
74262
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74307
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74263
74308
  flexDirection: "column",
74264
74309
  gap: 1,
74265
74310
  children: [
74266
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74311
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74267
74312
  bold: true,
74268
74313
  color: "cyan",
74269
74314
  children: "Review"
74270
74315
  }, undefined, false, undefined, this),
74271
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74316
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74272
74317
  children: [
74273
74318
  "Platforms: ",
74274
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74319
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74275
74320
  color: "green",
74276
74321
  children: draft.values.platforms.join(", ") || "—"
74277
74322
  }, undefined, false, undefined, this)
74278
74323
  ]
74279
74324
  }, undefined, true, undefined, this),
74280
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74325
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74281
74326
  children: [
74282
74327
  "Locale: ",
74283
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74328
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74284
74329
  color: "green",
74285
74330
  children: draft.values.locale
74286
74331
  }, undefined, false, undefined, this)
74287
74332
  ]
74288
74333
  }, undefined, true, undefined, this),
74289
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74334
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74290
74335
  children: [
74291
74336
  "Branch policy: ",
74292
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74337
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74293
74338
  color: "green",
74294
74339
  children: policy.preset
74295
74340
  }, undefined, false, undefined, this),
@@ -74300,24 +74345,24 @@ function SummaryScreen({ draft, dispatch }) {
74300
74345
  policy.protected.join(", ")
74301
74346
  ]
74302
74347
  }, undefined, true, undefined, this),
74303
- policyPreview.error === null ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74348
+ policyPreview.error === null ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74304
74349
  flexDirection: "column",
74305
74350
  gap: 0,
74306
74351
  children: [
74307
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74352
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74308
74353
  children: [
74309
74354
  "Sample checkout: ",
74310
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74355
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74311
74356
  color: "green",
74312
74357
  children: resolveBasePath(draft.values)
74313
74358
  }, undefined, false, undefined, this),
74314
74359
  policyPreview.workspace ? ` · workspace ${policyPreview.workspace}` : " · no matching workspace"
74315
74360
  ]
74316
74361
  }, undefined, true, undefined, this),
74317
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74362
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74318
74363
  children: [
74319
74364
  "Effective branch policy: ",
74320
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74365
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74321
74366
  color: "green",
74322
74367
  children: policyPreview.branchPreset
74323
74368
  }, undefined, false, undefined, this),
@@ -74327,10 +74372,10 @@ function SummaryScreen({ draft, dispatch }) {
74327
74372
  policyPreview.branchSource
74328
74373
  ]
74329
74374
  }, undefined, true, undefined, this),
74330
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74375
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74331
74376
  children: [
74332
74377
  "Effective commit policy: ",
74333
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74378
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74334
74379
  color: "green",
74335
74380
  children: policyPreview.commitPreset
74336
74381
  }, undefined, false, undefined, this),
@@ -74339,57 +74384,57 @@ function SummaryScreen({ draft, dispatch }) {
74339
74384
  ]
74340
74385
  }, undefined, true, undefined, this)
74341
74386
  ]
74342
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74387
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74343
74388
  color: "red",
74344
74389
  children: [
74345
74390
  "Policy preview failed: ",
74346
74391
  policyPreview.error
74347
74392
  ]
74348
74393
  }, undefined, true, undefined, this),
74349
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74394
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74350
74395
  children: [
74351
74396
  "YouTrack base URL:",
74352
74397
  " ",
74353
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74398
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74354
74399
  color: "green",
74355
74400
  children: draft.values.issueTracker === "youtrack" ? draft.values.baseUrl.trim() ? draft.values.baseUrl : "— (skip)" : "—"
74356
74401
  }, undefined, false, undefined, this)
74357
74402
  ]
74358
74403
  }, undefined, true, undefined, this),
74359
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74404
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74360
74405
  children: [
74361
74406
  "VCS provider: ",
74362
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74407
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74363
74408
  color: "green",
74364
74409
  children: draft.values.vcsProvider
74365
74410
  }, undefined, false, undefined, this)
74366
74411
  ]
74367
74412
  }, undefined, true, undefined, this),
74368
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74413
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74369
74414
  children: [
74370
74415
  "Project hygiene:",
74371
74416
  " ",
74372
- preview.projectRefused ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74417
+ preview.projectRefused ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74373
74418
  color: "yellow",
74374
74419
  children: [
74375
74420
  "skipped — ",
74376
74421
  preview.projectRefused
74377
74422
  ]
74378
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74423
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74379
74424
  color: "green",
74380
74425
  children: draft.values.applyProject ? "yes" : "no"
74381
74426
  }, undefined, false, undefined, this)
74382
74427
  ]
74383
74428
  }, undefined, true, undefined, this),
74384
- preview.overrides.length > 0 && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74429
+ preview.overrides.length > 0 && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74385
74430
  flexDirection: "column",
74386
74431
  gap: 0,
74387
74432
  children: [
74388
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74433
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74389
74434
  bold: true,
74390
74435
  children: "Environment overrides (not applied by the wizard):"
74391
74436
  }, undefined, false, undefined, this),
74392
- preview.overrides.map((o) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74437
+ preview.overrides.map((o) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74393
74438
  color: "yellow",
74394
74439
  children: [
74395
74440
  o.envKey,
@@ -74401,18 +74446,18 @@ function SummaryScreen({ draft, dispatch }) {
74401
74446
  }, o.envKey, true, undefined, this))
74402
74447
  ]
74403
74448
  }, undefined, true, undefined, this),
74404
- canApply ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74449
+ canApply ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74405
74450
  flexDirection: "column",
74406
74451
  gap: 0,
74407
74452
  children: [
74408
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74453
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74409
74454
  bold: true,
74410
74455
  children: "Will apply:"
74411
74456
  }, undefined, false, undefined, this),
74412
- mutationRows(preview.mutations).map((row) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74457
+ mutationRows(preview.mutations).map((row) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74413
74458
  children: row.text
74414
74459
  }, row.key, false, undefined, this)),
74415
- preview.preserved.map((p) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74460
+ preview.preserved.map((p) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74416
74461
  color: "green",
74417
74462
  children: [
74418
74463
  "preserve ",
@@ -74421,32 +74466,32 @@ function SummaryScreen({ draft, dispatch }) {
74421
74466
  ]
74422
74467
  }, p, true, undefined, this))
74423
74468
  ]
74424
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74469
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74425
74470
  flexDirection: "column",
74426
74471
  gap: 0,
74427
74472
  children: [
74428
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74473
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74429
74474
  bold: true,
74430
74475
  color: "red",
74431
74476
  children: "Apply blocked — malformed configuration:"
74432
74477
  }, undefined, false, undefined, this),
74433
- preview.blocked.map((b) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74478
+ preview.blocked.map((b) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74434
74479
  color: "red",
74435
74480
  children: b
74436
74481
  }, b, false, undefined, this)),
74437
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74482
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74438
74483
  dimColor: true,
74439
74484
  children: "Fix or remove the blocked file above, then return here. Esc Cancel."
74440
74485
  }, undefined, false, undefined, this)
74441
74486
  ]
74442
74487
  }, undefined, true, undefined, this),
74443
- canApply && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ConfirmInput, {
74488
+ canApply && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(ConfirmInput, {
74444
74489
  defaultChoice: "confirm",
74445
74490
  submitOnEnter: false,
74446
74491
  onConfirm: () => dispatch({ type: "apply" }),
74447
74492
  onCancel: () => {}
74448
74493
  }, undefined, false, undefined, this),
74449
- /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74494
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74450
74495
  dimColor: true,
74451
74496
  children: canApply ? "y to apply · b Back · Esc Cancel" : "b Back · Esc Cancel"
74452
74497
  }, undefined, false, undefined, this)
@@ -74454,16 +74499,16 @@ function SummaryScreen({ draft, dispatch }) {
74454
74499
  }, undefined, true, undefined, this);
74455
74500
  }
74456
74501
  function ExitScreen() {
74457
- return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
74502
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74458
74503
  flexDirection: "column",
74459
74504
  gap: 1,
74460
- children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
74505
+ children: /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74461
74506
  dimColor: true,
74462
74507
  children: "Exiting…"
74463
74508
  }, undefined, false, undefined, this)
74464
74509
  }, undefined, false, undefined, this);
74465
74510
  }
74466
- var import_react68, jsx_dev_runtime6, lastProjectTarget = null, projectTargetFor = (base) => {
74511
+ var import_react69, jsx_dev_runtime7, lastProjectTarget = null, projectTargetFor = (base) => {
74467
74512
  if (lastProjectTarget?.base !== base)
74468
74513
  lastProjectTarget = { base, target: projectTarget(base) };
74469
74514
  return lastProjectTarget.target;
@@ -74479,10 +74524,11 @@ var init_finish_screens = __esm(async () => {
74479
74524
  init_build2(),
74480
74525
  init_build3(),
74481
74526
  init_select_list(),
74527
+ init_sphere_spinner(),
74482
74528
  init_options()
74483
74529
  ]);
74484
- import_react68 = __toESM(require_react(), 1);
74485
- jsx_dev_runtime6 = __toESM(require_jsx_dev_runtime(), 1);
74530
+ import_react69 = __toESM(require_react(), 1);
74531
+ jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
74486
74532
  BRANCH_POLICY_ACTIONS = [
74487
74533
  { label: "Accept defaults", value: "accept" },
74488
74534
  { label: "Edit integration", value: "integration" },
@@ -74500,32 +74546,32 @@ function WorkspaceCollectionEditor({
74500
74546
  draft,
74501
74547
  dispatch
74502
74548
  }) {
74503
- const [view, setView] = import_react69.useState({ mode: "main" });
74549
+ const [view, setView] = import_react70.useState({ mode: "main" });
74504
74550
  const workspace = draft.workspaceDraft;
74505
74551
  if (!workspace)
74506
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74552
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74507
74553
  color: "red",
74508
74554
  children: "Workspace draft is unavailable."
74509
74555
  }, undefined, false, undefined, this);
74510
74556
  switch (view.mode) {
74511
74557
  case "main":
74512
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(MainMenu, {
74558
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(MainMenu, {
74513
74559
  workspace,
74514
74560
  dispatch,
74515
74561
  setView
74516
74562
  }, undefined, false, undefined, this);
74517
74563
  case "menu":
74518
- return view.kind === "profile" ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(ProfilesMenu, {
74564
+ return view.kind === "profile" ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(ProfilesMenu, {
74519
74565
  workspace,
74520
74566
  dispatch,
74521
74567
  setView
74522
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TracksMenu, {
74568
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(TracksMenu, {
74523
74569
  workspace,
74524
74570
  dispatch,
74525
74571
  setView
74526
74572
  }, undefined, false, undefined, this);
74527
74573
  case "name":
74528
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(NameInput, {
74574
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(NameInput, {
74529
74575
  collection: COLLECTIONS[view.kind],
74530
74576
  workspace,
74531
74577
  onCreate: (name) => {
@@ -74534,7 +74580,7 @@ function WorkspaceCollectionEditor({
74534
74580
  }
74535
74581
  }, undefined, false, undefined, this);
74536
74582
  case "edit":
74537
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(EntryFields, {
74583
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(EntryFields, {
74538
74584
  collection: COLLECTIONS[view.kind],
74539
74585
  workspace,
74540
74586
  name: view.name,
@@ -74542,7 +74588,7 @@ function WorkspaceCollectionEditor({
74542
74588
  onPick: (field) => setView({ ...view, mode: "value", field })
74543
74589
  }, undefined, false, undefined, this);
74544
74590
  case "value":
74545
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(EntryFieldValue, {
74591
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(EntryFieldValue, {
74546
74592
  collection: COLLECTIONS[view.kind],
74547
74593
  workspace,
74548
74594
  name: view.name,
@@ -74555,22 +74601,22 @@ function WorkspaceCollectionEditor({
74555
74601
  }
74556
74602
  }
74557
74603
  function MainMenu({ workspace, dispatch, setView }) {
74558
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74604
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
74559
74605
  flexDirection: "column",
74560
74606
  gap: 1,
74561
74607
  children: [
74562
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74608
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74563
74609
  bold: true,
74564
74610
  children: [
74565
74611
  "Advanced workspace settings · ",
74566
74612
  workspace.name
74567
74613
  ]
74568
74614
  }, undefined, true, undefined, this),
74569
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74615
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74570
74616
  dimColor: true,
74571
74617
  children: "Choose a setting to edit. Lists use comma-separated values; blank clears an override."
74572
74618
  }, undefined, false, undefined, this),
74573
- [...WORKSPACE_ADVANCED_FIELDS].map(({ label, value }) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74619
+ [...WORKSPACE_ADVANCED_FIELDS].map(({ label, value }) => /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74574
74620
  dimColor: true,
74575
74621
  children: [
74576
74622
  label,
@@ -74578,7 +74624,7 @@ function MainMenu({ workspace, dispatch, setView }) {
74578
74624
  workspaceEditorValue(workspace, value) || "inherited / unset"
74579
74625
  ]
74580
74626
  }, value, true, undefined, this)),
74581
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
74627
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(SelectList, {
74582
74628
  options: MAIN_OPTIONS,
74583
74629
  value: "save",
74584
74630
  onSelect: (value) => {
@@ -74605,22 +74651,22 @@ function ProfilesMenu({ workspace, dispatch, setView }) {
74605
74651
  { label: "Create profile", value: "create" },
74606
74652
  { label: "Back to advanced settings", value: "back" }
74607
74653
  ];
74608
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74654
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
74609
74655
  flexDirection: "column",
74610
74656
  gap: 1,
74611
74657
  children: [
74612
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74658
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74613
74659
  bold: true,
74614
74660
  children: [
74615
74661
  "Profiles · default: ",
74616
74662
  workspace.defaultProfile ?? "none"
74617
74663
  ]
74618
74664
  }, undefined, true, undefined, this),
74619
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74665
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74620
74666
  dimColor: true,
74621
74667
  children: "Profiles can override branch rules and commit conventions."
74622
74668
  }, undefined, false, undefined, this),
74623
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
74669
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(SelectList, {
74624
74670
  options,
74625
74671
  value: "back",
74626
74672
  onSelect: (value) => {
@@ -74649,19 +74695,19 @@ function TracksMenu({ workspace, dispatch, setView }) {
74649
74695
  { label: "Create release track", value: "create" },
74650
74696
  { label: "Back to advanced settings", value: "back" }
74651
74697
  ];
74652
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74698
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
74653
74699
  flexDirection: "column",
74654
74700
  gap: 1,
74655
74701
  children: [
74656
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74702
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74657
74703
  bold: true,
74658
74704
  children: "Named release tracks"
74659
74705
  }, undefined, false, undefined, this),
74660
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74706
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74661
74707
  dimColor: true,
74662
74708
  children: "Each track has its own branches, naming, version source, and checks."
74663
74709
  }, undefined, false, undefined, this),
74664
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
74710
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(SelectList, {
74665
74711
  options,
74666
74712
  value: "back",
74667
74713
  onSelect: (value) => {
@@ -74684,20 +74730,20 @@ function NameInput({
74684
74730
  workspace,
74685
74731
  onCreate
74686
74732
  }) {
74687
- const [error, setError] = import_react69.useState("");
74688
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74733
+ const [error, setError] = import_react70.useState("");
74734
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
74689
74735
  flexDirection: "column",
74690
74736
  gap: 1,
74691
74737
  children: [
74692
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74738
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74693
74739
  bold: true,
74694
74740
  children: collection.createTitle
74695
74741
  }, undefined, false, undefined, this),
74696
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74742
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74697
74743
  dimColor: true,
74698
74744
  children: collection.nameLabel
74699
74745
  }, undefined, false, undefined, this),
74700
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TextInput, {
74746
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(TextInput, {
74701
74747
  onSubmit: (value) => {
74702
74748
  const next = value.trim();
74703
74749
  if (!next)
@@ -74708,11 +74754,11 @@ function NameInput({
74708
74754
  onCreate(next);
74709
74755
  }
74710
74756
  }, undefined, false, undefined, this),
74711
- error && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74757
+ error && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74712
74758
  color: "red",
74713
74759
  children: error
74714
74760
  }, undefined, false, undefined, this),
74715
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74761
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74716
74762
  dimColor: true,
74717
74763
  children: "Enter to create · Esc Back"
74718
74764
  }, undefined, false, undefined, this)
@@ -74727,11 +74773,11 @@ function EntryFields({
74727
74773
  onPick
74728
74774
  }) {
74729
74775
  const options = [...collection.fields, { label: "Done editing", value: "done" }];
74730
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74776
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
74731
74777
  flexDirection: "column",
74732
74778
  gap: 1,
74733
74779
  children: [
74734
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74780
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74735
74781
  bold: true,
74736
74782
  children: [
74737
74783
  collection.editTitle,
@@ -74741,7 +74787,7 @@ function EntryFields({
74741
74787
  }, undefined, true, undefined, this),
74742
74788
  collection.fields.map((item) => {
74743
74789
  const value = collection.valueOf(workspace, name, item.value);
74744
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74790
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74745
74791
  dimColor: true,
74746
74792
  children: [
74747
74793
  item.label,
@@ -74750,7 +74796,7 @@ function EntryFields({
74750
74796
  ]
74751
74797
  }, item.value, true, undefined, this);
74752
74798
  }),
74753
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
74799
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(SelectList, {
74754
74800
  options,
74755
74801
  value: "done",
74756
74802
  onSelect: (value) => value === "done" ? onDone() : onPick(value)
@@ -74768,11 +74814,11 @@ function EntryFieldValue({
74768
74814
  const item = collection.fields.find((entry) => entry.value === field);
74769
74815
  const choices = enumFieldOptions(field);
74770
74816
  const current = collection.valueOf(workspace, name, field);
74771
- return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
74817
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
74772
74818
  flexDirection: "column",
74773
74819
  gap: 1,
74774
74820
  children: [
74775
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74821
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74776
74822
  bold: true,
74777
74823
  children: [
74778
74824
  collection.valueTitle,
@@ -74782,22 +74828,22 @@ function EntryFieldValue({
74782
74828
  item?.label
74783
74829
  ]
74784
74830
  }, undefined, true, undefined, this),
74785
- choices ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
74831
+ choices ? /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(SelectList, {
74786
74832
  options: choices,
74787
74833
  value: current ?? choices[0].value,
74788
74834
  onSelect: onSave
74789
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TextInput, {
74835
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(TextInput, {
74790
74836
  defaultValue: current ?? "",
74791
74837
  onSubmit: onSave
74792
74838
  }, undefined, false, undefined, this),
74793
- /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
74839
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74794
74840
  dimColor: true,
74795
74841
  children: collection.valueFooter
74796
74842
  }, undefined, false, undefined, this)
74797
74843
  ]
74798
74844
  }, undefined, true, undefined, this);
74799
74845
  }
74800
- var import_react69, jsx_dev_runtime7, COLLECTIONS, MAIN_OPTIONS;
74846
+ var import_react70, jsx_dev_runtime8, COLLECTIONS, MAIN_OPTIONS;
74801
74847
  var init_workspace_editor = __esm(async () => {
74802
74848
  init_logic();
74803
74849
  await __promiseAll([
@@ -74806,8 +74852,8 @@ var init_workspace_editor = __esm(async () => {
74806
74852
  init_select_list(),
74807
74853
  init_options()
74808
74854
  ]);
74809
- import_react69 = __toESM(require_react(), 1);
74810
- jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
74855
+ import_react70 = __toESM(require_react(), 1);
74856
+ jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
74811
74857
  COLLECTIONS = {
74812
74858
  profile: {
74813
74859
  fields: PROFILE_FIELDS,
@@ -74867,14 +74913,14 @@ function Wizard({
74867
74913
  onExit,
74868
74914
  detection = emptyDetection()
74869
74915
  }) {
74870
- const [draft, dispatch] = import_react70.useReducer(reducer3, detection, (found) => {
74916
+ const [draft, dispatch] = import_react71.useReducer(reducer3, detection, (found) => {
74871
74917
  const initial = createInitialDraft();
74872
74918
  const platforms = preselectedPlatforms(found);
74873
74919
  return platforms.length > 0 ? { ...initial, values: { ...initial.values, platforms } } : initial;
74874
74920
  });
74875
- const exitedRef = import_react70.useRef(false);
74876
- const searchRef = import_react70.useRef({ q: "", typed: false });
74877
- import_react70.useEffect(() => {
74921
+ const exitedRef = import_react71.useRef(false);
74922
+ const searchRef = import_react71.useRef({ q: "", typed: false });
74923
+ import_react71.useEffect(() => {
74878
74924
  searchRef.current = { q: "", typed: false };
74879
74925
  }, [draft.screen]);
74880
74926
  use_input_default((input, key) => {
@@ -74892,22 +74938,22 @@ function Wizard({
74892
74938
  dispatch({ type: "back" });
74893
74939
  }
74894
74940
  });
74895
- import_react70.useEffect(() => {
74941
+ import_react71.useEffect(() => {
74896
74942
  if (draft.screen === "exit" && !exitedRef.current) {
74897
74943
  exitedRef.current = true;
74898
74944
  onExit(!draft.cancelled, draft.values);
74899
74945
  }
74900
74946
  }, [draft.screen, draft.cancelled, draft.values, onExit]);
74901
- return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
74947
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
74902
74948
  flexDirection: "column",
74903
74949
  gap: 1,
74904
74950
  children: [
74905
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
74951
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
74906
74952
  bold: true,
74907
74953
  color: "cyan",
74908
74954
  children: "workit — workflow rails for agentic coding"
74909
74955
  }, undefined, false, undefined, this),
74910
- /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Screen, {
74956
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Screen, {
74911
74957
  draft,
74912
74958
  dispatch,
74913
74959
  detection,
@@ -74923,11 +74969,11 @@ function Wizard({
74923
74969
  }
74924
74970
  function Screen(props) {
74925
74971
  const Body = SCREENS[props.draft.screen];
74926
- return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Body, {
74972
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Body, {
74927
74973
  ...props
74928
74974
  }, undefined, false, undefined, this);
74929
74975
  }
74930
- var import_react70, jsx_dev_runtime8, TEXT_SCREENS, SEARCH_SCREENS, SCREENS;
74976
+ var import_react71, jsx_dev_runtime9, TEXT_SCREENS, SEARCH_SCREENS, SCREENS;
74931
74977
  var init_steps = __esm(async () => {
74932
74978
  init_wizard_state();
74933
74979
  init_detect_hosts();
@@ -74941,8 +74987,8 @@ var init_steps = __esm(async () => {
74941
74987
  init_options(),
74942
74988
  init_select_list()
74943
74989
  ]);
74944
- import_react70 = __toESM(require_react(), 1);
74945
- jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
74990
+ import_react71 = __toESM(require_react(), 1);
74991
+ jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
74946
74992
  TEXT_SCREENS = new Set([
74947
74993
  "localeOther",
74948
74994
  "branchAllowed",
@@ -75015,23 +75061,188 @@ var init_diagnostics = __esm(() => {
75015
75061
  });
75016
75062
  });
75017
75063
 
75064
+ // packages/workit-cli/src/progress.ts
75065
+ import { spawn } from "node:child_process";
75066
+ import path44 from "node:path";
75067
+ function createProgress(options = {}) {
75068
+ const env = options.env ?? process.env;
75069
+ const mode = terminalMode({ ...options, env });
75070
+ const stream = options.stream;
75071
+ const now = options.now ?? Date.now;
75072
+ const every = options.setInterval ?? ((tick, ms) => setInterval(tick, ms));
75073
+ const stop = options.clearInterval ?? ((timer) => clearInterval(timer));
75074
+ const proc = options.proc ?? process;
75075
+ const ascii = env.TERM === "dumb";
75076
+ const glyphs = mode === "spinner" ? { done: "\x1B[32m✓\x1B[0m", failed: "\x1B[31m✗\x1B[0m", skipped: "–" } : ascii ? { done: "ok", failed: "x", skipped: "-" } : { done: "✓", failed: "✗", skipped: "–" };
75077
+ const start = (initial, signals = true) => {
75078
+ if (mode === "off" || !stream)
75079
+ return NOOP_STEP;
75080
+ let text = initial;
75081
+ let finished = false;
75082
+ const began = now();
75083
+ let frame = 0;
75084
+ const draw = () => {
75085
+ const seconds = Math.floor((now() - began) / 1000);
75086
+ let line = `${text} (${seconds}s)`;
75087
+ if (stream.columns && line.length + 2 >= stream.columns)
75088
+ line = `${line.slice(0, Math.max(1, stream.columns - 4))}…`;
75089
+ const glyph = spinnerPaint(now() - began, env, FRAMES[frame % FRAMES.length] ?? "");
75090
+ stream.write(`${CLEAR}${glyph} ${line}`);
75091
+ };
75092
+ let timer;
75093
+ if (mode === "spinner") {
75094
+ draw();
75095
+ timer = every(() => {
75096
+ frame += 1;
75097
+ draw();
75098
+ }, FRAME_MS);
75099
+ }
75100
+ const handlers = [];
75101
+ const release = () => {
75102
+ for (const [event, handler] of handlers)
75103
+ proc.off(event, handler);
75104
+ handlers.length = 0;
75105
+ };
75106
+ if (mode === "spinner" && signals) {
75107
+ const onSignal = (signal) => () => {
75108
+ if (!finished) {
75109
+ finished = true;
75110
+ if (timer !== undefined)
75111
+ stop(timer);
75112
+ stream.write(CLEAR);
75113
+ }
75114
+ release();
75115
+ proc.kill(proc.pid, signal);
75116
+ };
75117
+ handlers.push(["SIGINT", onSignal("SIGINT")], ["SIGTERM", onSignal("SIGTERM")]);
75118
+ }
75119
+ if (mode === "spinner") {
75120
+ const onExit = () => {
75121
+ if (!finished)
75122
+ stream.write(CLEAR);
75123
+ };
75124
+ handlers.push(["exit", onExit]);
75125
+ for (const [event, handler] of handlers)
75126
+ proc.on(event, handler);
75127
+ }
75128
+ return {
75129
+ label: (next) => {
75130
+ text = next;
75131
+ if (mode === "spinner" && !finished)
75132
+ draw();
75133
+ },
75134
+ end: (status, note) => {
75135
+ if (finished)
75136
+ return;
75137
+ finished = true;
75138
+ if (timer !== undefined)
75139
+ stop(timer);
75140
+ release();
75141
+ stream.write(`${mode === "spinner" ? CLEAR : ""}${glyphs[status]} ${text}${note ? `: ${note}` : ""}
75142
+ `);
75143
+ }
75144
+ };
75145
+ };
75146
+ return {
75147
+ mode,
75148
+ start,
75149
+ async run(label, fn, classify, runOptions) {
75150
+ const step = start(label, runOptions?.signals === true);
75151
+ try {
75152
+ const value = await fn();
75153
+ step.end(classify ? classify(value) : "done");
75154
+ return value;
75155
+ } catch (error) {
75156
+ step.end("failed");
75157
+ throw error;
75158
+ }
75159
+ },
75160
+ runSync(label, fn, classify) {
75161
+ const step = start(label, false);
75162
+ const ticker = mode === "spinner" && stream ? (options.spawnTicker ?? ((text, began) => defaultTicker(text, began, stream)))(label, now()) : undefined;
75163
+ try {
75164
+ const value = fn();
75165
+ ticker?.stop();
75166
+ step.end(classify ? classify(value) : "done");
75167
+ return value;
75168
+ } catch (error) {
75169
+ ticker?.stop();
75170
+ step.end("failed");
75171
+ throw error;
75172
+ }
75173
+ }
75174
+ };
75175
+ }
75176
+ var FRAMES, FRAME_MS, CLEAR = "\r\x1B[2K", TICKER_SOURCE, defaultTicker = (label, began, stream) => {
75177
+ if (stream !== process.stderr)
75178
+ return;
75179
+ if (!/^(?:node|nodejs|bun)(?:\.exe)?$/i.test(path44.basename(process.execPath)))
75180
+ return;
75181
+ try {
75182
+ const child = spawn(process.execPath, ["-e", TICKER_SOURCE], {
75183
+ env: {
75184
+ ...process.env,
75185
+ WORKIT_TICK_LABEL: label,
75186
+ WORKIT_TICK_BEGAN: String(began),
75187
+ WORKIT_TICK_COLS: String(stream.columns ?? 0)
75188
+ },
75189
+ stdio: ["ignore", "ignore", "inherit"],
75190
+ windowsHide: true
75191
+ });
75192
+ child.on("error", () => {});
75193
+ child.unref();
75194
+ return { stop: () => void child.kill("SIGKILL") };
75195
+ } catch {
75196
+ return;
75197
+ }
75198
+ }, NOOP_STEP, progressFor = (io) => {
75199
+ const stderr = io.terminals?.stderr;
75200
+ const stream = stderr?.write ? stderr : undefined;
75201
+ return createProgress({ json: io.json, env: io.env, ...stream ? { stream } : {} });
75202
+ };
75203
+ var init_progress = __esm(() => {
75204
+ init_style();
75205
+ FRAMES = SPINNER_FRAMES;
75206
+ FRAME_MS = SPINNER_FRAME_MS;
75207
+ TICKER_SOURCE = `
75208
+ const frames = ${JSON.stringify(FRAMES)};
75209
+ const { WORKIT_TICK_LABEL: label, WORKIT_TICK_BEGAN: began, WORKIT_TICK_COLS: cols } = process.env;
75210
+ const spinnerPaint = ${spinnerPaint.toString()};
75211
+ const parent = process.ppid;
75212
+ let frame = 0;
75213
+ const timer = setInterval(() => {
75214
+ let alive = process.ppid === parent;
75215
+ if (alive) try { process.kill(parent, 0); } catch { alive = false; }
75216
+ if (!alive || Date.now() - Number(began) > 600000) process.exit(0);
75217
+ frame += 1;
75218
+ const seconds = Math.floor((Date.now() - Number(began)) / 1000);
75219
+ let line = label + " (" + seconds + "s)";
75220
+ if (Number(cols) && line.length + 2 >= Number(cols)) line = line.slice(0, Math.max(1, Number(cols) - 4)) + "…";
75221
+ process.stderr.write(${JSON.stringify(CLEAR)} + spinnerPaint(Date.now() - Number(began), process.env, frames[frame % frames.length]) + " " + line);
75222
+ }, ${FRAME_MS});
75223
+ `;
75224
+ NOOP_STEP = { label: () => {}, end: () => {} };
75225
+ });
75226
+
75018
75227
  // packages/workit-cli/src/index.tsx
75019
- function printApplySummary(result) {
75228
+ function printApplySummary(result, style) {
75020
75229
  for (const entry of result.entries) {
75021
- console.log(`${entry.status.padEnd(11)} ${entry.file}${entry.detail ? ` — ${entry.detail}` : ""}`);
75230
+ console.log(`${statusPaint(style, entry.status)}${" ".repeat(Math.max(0, 11 - entry.status.length))} ${style.path(entry.file)}${entry.detail ? ` — ${entry.detail}` : ""}`);
75022
75231
  }
75023
75232
  for (const report of result.doctor) {
75024
- console.log(`doctor ${report.host}: ${report.ok ? "healthy" : "problems found"} (${report.summary.failed} failed)`);
75233
+ console.log(`doctor ${report.host}: ${report.ok ? style.ok("healthy") : style.fail("problems found")} (${report.summary.failed} failed)`);
75234
+ }
75235
+ console.log(result.ok ? style.ok("Setup complete.") : style.warn("Setup finished with problems."));
75236
+ for (const line of setupCompletionGuidance()) {
75237
+ console.log(line.replace(/`([^`]+)`/g, (_, command) => style.command(command)));
75025
75238
  }
75026
- console.log(result.ok ? "Setup complete." : "Setup finished with problems.");
75027
- for (const line of setupCompletionGuidance())
75028
- console.log(line);
75029
75239
  }
75030
75240
  function printMalformedBlocked(state) {
75031
- console.log("Apply blocked — malformed configuration:");
75241
+ const style = stdoutStyle();
75242
+ console.log(style.fail("Apply blocked — malformed configuration:"));
75032
75243
  for (const entry of [state.config, state.youtrack, state.vcs, state.workspaces]) {
75033
75244
  if (entry.status === "malformed")
75034
- console.log(` ${entry.error ?? entry.file}`);
75245
+ console.log(` ${style.path(entry.error ?? entry.file)}`);
75035
75246
  }
75036
75247
  }
75037
75248
  async function runInit() {
@@ -75048,12 +75259,13 @@ async function runInit() {
75048
75259
  console.log(line);
75049
75260
  process.exit(1);
75050
75261
  }
75262
+ const progress = initProgress();
75051
75263
  logger.info(EVENT.installSteps, { step: "wizard_start" });
75052
75264
  const exits = [];
75053
75265
  let done = () => {};
75054
75266
  process.stdout.write("\x1B[2J\x1B[H");
75055
- const instance = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Wizard, {
75056
- detection: detectHosts(),
75267
+ const instance = render_default(/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Wizard, {
75268
+ detection: progress.runSync("Detecting installed hosts", () => detectHosts()),
75057
75269
  onExit: (complete, values) => {
75058
75270
  exits.push({ complete, values });
75059
75271
  done();
@@ -75074,19 +75286,21 @@ async function runInit() {
75074
75286
  printMalformedBlocked(preview.state);
75075
75287
  process.exit(1);
75076
75288
  }
75077
- const result = applySetupPreview(preview, { cwd: base, env: process.env });
75289
+ const result = progress.runSync("Installing hosts, writing permissions and checking with doctor", () => applySetupPreview(preview, { cwd: base, env: process.env }), (applied) => applied.ok ? "done" : "failed");
75078
75290
  let exitCode = result.exitCode;
75079
75291
  if (exit.values.branchPolicy) {
75080
- const bp = applyWizardBranchPolicy(exit.values.branchPolicy, base, process.env);
75292
+ const policy = exit.values.branchPolicy;
75293
+ const bp = progress.runSync("Writing the branch policy", () => applyWizardBranchPolicy(policy, base, process.env), (written) => written.ok ? "done" : "failed");
75294
+ const style = stdoutStyle();
75081
75295
  if (bp.ok) {
75082
- console.log(`${String(bp.status).padEnd(11)} ${bp.config_path} — branch policy`);
75296
+ console.log(`${style.ok(String(bp.status).padEnd(11))} ${style.path(bp.config_path)} — branch policy`);
75083
75297
  } else {
75084
- console.log("branch policy apply failed — " + (bp.error ?? "unknown"));
75298
+ console.log(style.fail("branch policy apply failed") + " — " + (bp.error ?? "unknown"));
75085
75299
  exitCode = 1;
75086
75300
  }
75087
75301
  }
75088
75302
  logger.info(EVENT.installSteps, { step: "wizard_apply", ok: result.ok });
75089
- printApplySummary(result);
75303
+ printApplySummary(result, stdoutStyle());
75090
75304
  process.exit(exitCode);
75091
75305
  }
75092
75306
  logger.info(EVENT.installSteps, {
@@ -75096,22 +75310,22 @@ async function runInit() {
75096
75310
  process.exit(exit !== undefined && exit.complete ? 0 : 1);
75097
75311
  }
75098
75312
  function UninstallWizard({ onExit }) {
75099
- const [hosts, setHosts] = import_react71.useState([]);
75100
- const [plan, setPlan] = import_react71.useState(null);
75313
+ const [hosts, setHosts] = import_react72.useState([]);
75314
+ const [plan, setPlan] = import_react72.useState(null);
75101
75315
  if (!plan) {
75102
- return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
75316
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
75103
75317
  flexDirection: "column",
75104
75318
  gap: 1,
75105
75319
  children: [
75106
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
75320
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
75107
75321
  bold: true,
75108
75322
  children: "Uninstall workit"
75109
75323
  }, undefined, false, undefined, this),
75110
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
75324
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
75111
75325
  dimColor: true,
75112
75326
  children: "Select the hosts to remove workit from (space to toggle):"
75113
75327
  }, undefined, false, undefined, this),
75114
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(MultiSelect, {
75328
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(MultiSelect, {
75115
75329
  options: UNINSTALL_HOST_OPTIONS,
75116
75330
  defaultValue: [],
75117
75331
  onChange: (values) => setHosts(values),
@@ -75120,7 +75334,7 @@ function UninstallWizard({ onExit }) {
75120
75334
  setPlan(planUninstall({ env: process.env }));
75121
75335
  }
75122
75336
  }, undefined, false, undefined, this),
75123
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
75337
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
75124
75338
  dimColor: true,
75125
75339
  children: "Enter to continue"
75126
75340
  }, undefined, false, undefined, this)
@@ -75130,17 +75344,17 @@ function UninstallWizard({ onExit }) {
75130
75344
  const chosen = new Set(hosts);
75131
75345
  const selected = plan.hosts.filter((h) => chosen.has(h.host));
75132
75346
  const reviewed = { hosts: selected };
75133
- return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
75347
+ return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
75134
75348
  flexDirection: "column",
75135
75349
  gap: 1,
75136
75350
  children: [
75137
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
75351
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
75138
75352
  bold: true,
75139
75353
  children: "Uninstall workit — review"
75140
75354
  }, undefined, false, undefined, this),
75141
- selected.every((h) => h.actions.length === 0) ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
75355
+ selected.every((h) => h.actions.length === 0) ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
75142
75356
  children: "No workit registrations found for the selected hosts."
75143
- }, undefined, false, undefined, this) : selected.flatMap((h) => h.actions.map((a) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
75357
+ }, undefined, false, undefined, this) : selected.flatMap((h) => h.actions.map((a) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
75144
75358
  children: [
75145
75359
  "• [",
75146
75360
  h.host,
@@ -75150,10 +75364,10 @@ function UninstallWizard({ onExit }) {
75150
75364
  a.path
75151
75365
  ]
75152
75366
  }, `${h.host}:${a.path}`, true, undefined, this))),
75153
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
75367
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
75154
75368
  children: "Apply uninstall? (y/N)"
75155
75369
  }, undefined, false, undefined, this),
75156
- /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(ConfirmInput, {
75370
+ /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(ConfirmInput, {
75157
75371
  onConfirm: () => onExit({ confirmed: true, hosts, plan: reviewed }),
75158
75372
  onCancel: () => onExit({ confirmed: false, hosts, plan: reviewed })
75159
75373
  }, undefined, false, undefined, this)
@@ -75168,7 +75382,7 @@ async function runUninstall() {
75168
75382
  }
75169
75383
  const outcomes = [];
75170
75384
  let done = () => {};
75171
- const instance = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(UninstallWizard, {
75385
+ const instance = render_default(/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(UninstallWizard, {
75172
75386
  onExit: (outcome) => {
75173
75387
  outcomes.push(outcome);
75174
75388
  done();
@@ -75197,7 +75411,7 @@ async function runUninstall() {
75197
75411
  console.log(result.ok ? "Uninstall complete." : "Uninstall finished with problems.");
75198
75412
  process.exit(result.ok ? 0 : 1);
75199
75413
  }
75200
- var import_react71, jsx_dev_runtime9, UNINSTALL_HOST_OPTIONS;
75414
+ var import_react72, jsx_dev_runtime10, stdoutStyle = () => createStyle({ stream: process.stdout, env: process.env }), initProgress = () => createProgress({ stream: process.stderr, env: process.env }), statusPaint = (style, status) => status === "Failed" ? style.fail(status) : status === "Skipped" ? style.warn(status) : style.ok(status), UNINSTALL_HOST_OPTIONS;
75201
75415
  var init_src2 = __esm(async () => {
75202
75416
  init_wizard_state();
75203
75417
  init_boundary();
@@ -75207,13 +75421,15 @@ var init_src2 = __esm(async () => {
75207
75421
  init_uninstall();
75208
75422
  init_logic();
75209
75423
  init_diagnostics();
75424
+ init_progress();
75425
+ init_style();
75210
75426
  await __promiseAll([
75211
75427
  init_build2(),
75212
75428
  init_build3(),
75213
75429
  init_steps()
75214
75430
  ]);
75215
- import_react71 = __toESM(require_react(), 1);
75216
- jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
75431
+ import_react72 = __toESM(require_react(), 1);
75432
+ jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
75217
75433
  UNINSTALL_HOST_OPTIONS = [
75218
75434
  { label: "OpenCode", value: "opencode" },
75219
75435
  { label: "Cursor", value: "cursor" },
@@ -75383,169 +75599,6 @@ var init_setup2 = __esm(() => {
75383
75599
  ALL_HOSTS = ["claude-code", "codex", "cursor", "opencode", "pi"];
75384
75600
  });
75385
75601
 
75386
- // packages/workit-cli/src/progress.ts
75387
- import { spawn } from "node:child_process";
75388
- import path44 from "node:path";
75389
- function createProgress(options = {}) {
75390
- const env = options.env ?? process.env;
75391
- const mode = terminalMode({ ...options, env });
75392
- const stream = options.stream;
75393
- const now = options.now ?? Date.now;
75394
- const every = options.setInterval ?? ((tick, ms) => setInterval(tick, ms));
75395
- const stop = options.clearInterval ?? ((timer) => clearInterval(timer));
75396
- const proc = options.proc ?? process;
75397
- const ascii = env.TERM === "dumb";
75398
- const glyphs = mode === "spinner" ? { done: "\x1B[32m✓\x1B[0m", failed: "\x1B[31m✗\x1B[0m", skipped: "–" } : ascii ? { done: "ok", failed: "x", skipped: "-" } : { done: "✓", failed: "✗", skipped: "–" };
75399
- const start = (initial, signals = true) => {
75400
- if (mode === "off" || !stream)
75401
- return NOOP_STEP;
75402
- let text = initial;
75403
- let finished = false;
75404
- const began = now();
75405
- let frame = 0;
75406
- const draw = () => {
75407
- const seconds = Math.floor((now() - began) / 1000);
75408
- let line = `${text} (${seconds}s)`;
75409
- if (stream.columns && line.length + 2 >= stream.columns)
75410
- line = `${line.slice(0, Math.max(1, stream.columns - 4))}…`;
75411
- const glyph = spinnerPaint(now() - began, env, FRAMES[frame % FRAMES.length] ?? "");
75412
- stream.write(`${CLEAR}${glyph} ${line}`);
75413
- };
75414
- let timer;
75415
- if (mode === "spinner") {
75416
- draw();
75417
- timer = every(() => {
75418
- frame += 1;
75419
- draw();
75420
- }, FRAME_MS);
75421
- }
75422
- const handlers = [];
75423
- const release = () => {
75424
- for (const [event, handler] of handlers)
75425
- proc.off(event, handler);
75426
- handlers.length = 0;
75427
- };
75428
- if (mode === "spinner" && signals) {
75429
- const onSignal = (signal) => () => {
75430
- if (!finished) {
75431
- finished = true;
75432
- if (timer !== undefined)
75433
- stop(timer);
75434
- stream.write(CLEAR);
75435
- }
75436
- release();
75437
- proc.kill(proc.pid, signal);
75438
- };
75439
- handlers.push(["SIGINT", onSignal("SIGINT")], ["SIGTERM", onSignal("SIGTERM")]);
75440
- }
75441
- if (mode === "spinner") {
75442
- const onExit = () => {
75443
- if (!finished)
75444
- stream.write(CLEAR);
75445
- };
75446
- handlers.push(["exit", onExit]);
75447
- for (const [event, handler] of handlers)
75448
- proc.on(event, handler);
75449
- }
75450
- return {
75451
- label: (next) => {
75452
- text = next;
75453
- if (mode === "spinner" && !finished)
75454
- draw();
75455
- },
75456
- end: (status, note) => {
75457
- if (finished)
75458
- return;
75459
- finished = true;
75460
- if (timer !== undefined)
75461
- stop(timer);
75462
- release();
75463
- stream.write(`${mode === "spinner" ? CLEAR : ""}${glyphs[status]} ${text}${note ? `: ${note}` : ""}
75464
- `);
75465
- }
75466
- };
75467
- };
75468
- return {
75469
- mode,
75470
- start,
75471
- async run(label, fn, classify) {
75472
- const step = start(label, false);
75473
- try {
75474
- const value = await fn();
75475
- step.end(classify ? classify(value) : "done");
75476
- return value;
75477
- } catch (error) {
75478
- step.end("failed");
75479
- throw error;
75480
- }
75481
- },
75482
- runSync(label, fn, classify) {
75483
- const step = start(label, false);
75484
- const ticker = mode === "spinner" && stream ? (options.spawnTicker ?? ((text, began) => defaultTicker(text, began, stream)))(label, now()) : undefined;
75485
- try {
75486
- const value = fn();
75487
- ticker?.stop();
75488
- step.end(classify ? classify(value) : "done");
75489
- return value;
75490
- } catch (error) {
75491
- ticker?.stop();
75492
- step.end("failed");
75493
- throw error;
75494
- }
75495
- }
75496
- };
75497
- }
75498
- var FRAMES, FRAME_MS, CLEAR = "\r\x1B[2K", TICKER_SOURCE, defaultTicker = (label, began, stream) => {
75499
- if (stream !== process.stderr)
75500
- return;
75501
- if (!/^(?:node|nodejs|bun)(?:\.exe)?$/i.test(path44.basename(process.execPath)))
75502
- return;
75503
- try {
75504
- const child = spawn(process.execPath, ["-e", TICKER_SOURCE], {
75505
- env: {
75506
- ...process.env,
75507
- WORKIT_TICK_LABEL: label,
75508
- WORKIT_TICK_BEGAN: String(began),
75509
- WORKIT_TICK_COLS: String(stream.columns ?? 0)
75510
- },
75511
- stdio: ["ignore", "ignore", "inherit"],
75512
- windowsHide: true
75513
- });
75514
- child.on("error", () => {});
75515
- child.unref();
75516
- return { stop: () => void child.kill("SIGKILL") };
75517
- } catch {
75518
- return;
75519
- }
75520
- }, NOOP_STEP, progressFor = (io) => {
75521
- const stderr = io.terminals?.stderr;
75522
- const stream = stderr?.write ? stderr : undefined;
75523
- return createProgress({ json: io.json, env: io.env, ...stream ? { stream } : {} });
75524
- };
75525
- var init_progress = __esm(() => {
75526
- init_style();
75527
- FRAMES = SPINNER_FRAMES;
75528
- FRAME_MS = SPINNER_FRAME_MS;
75529
- TICKER_SOURCE = `
75530
- const frames = ${JSON.stringify(FRAMES)};
75531
- const { WORKIT_TICK_LABEL: label, WORKIT_TICK_BEGAN: began, WORKIT_TICK_COLS: cols } = process.env;
75532
- const spinnerPaint = ${spinnerPaint.toString()};
75533
- const parent = process.ppid;
75534
- let frame = 0;
75535
- const timer = setInterval(() => {
75536
- let alive = process.ppid === parent;
75537
- if (alive) try { process.kill(parent, 0); } catch { alive = false; }
75538
- if (!alive || Date.now() - Number(began) > 600000) process.exit(0);
75539
- frame += 1;
75540
- const seconds = Math.floor((Date.now() - Number(began)) / 1000);
75541
- let line = label + " (" + seconds + "s)";
75542
- if (Number(cols) && line.length + 2 >= Number(cols)) line = line.slice(0, Math.max(1, Number(cols) - 4)) + "…";
75543
- process.stderr.write(${JSON.stringify(CLEAR)} + spinnerPaint(Date.now() - Number(began), process.env, frames[frame % frames.length]) + " " + line);
75544
- }, ${FRAME_MS});
75545
- `;
75546
- NOOP_STEP = { label: () => {}, end: () => {} };
75547
- });
75548
-
75549
75602
  // packages/workit-cli/src/upgrade/shared.ts
75550
75603
  import { spawn as spawn2 } from "node:child_process";
75551
75604
  import { existsSync as existsSync21, readFileSync as readFileSync22 } from "node:fs";
@@ -75960,7 +76013,7 @@ async function applyUpgrade(plan, deps = {}) {
75960
76013
  }
75961
76014
  if (plan.cli)
75962
76015
  try {
75963
- hosts.push(await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf));
76016
+ hosts.push(await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf, { signals: true }));
75964
76017
  } catch (error) {
75965
76018
  hosts.push({
75966
76019
  host: "cli",
@@ -108357,7 +108410,9 @@ async function run25(argv, io) {
108357
108410
  }
108358
108411
  const results = [];
108359
108412
  for (const entry of steps) {
108360
- const outcome = await progressFor(io).run(entry.label, () => entry.run());
108413
+ const outcome = await progressFor(io).run(entry.label, () => entry.run(), undefined, {
108414
+ signals: true
108415
+ });
108361
108416
  results.push({
108362
108417
  step: entry.label,
108363
108418
  status: outcome.status,