@brainervirus/workit-cli 8.21.0 → 8.21.2

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 +1697 -1616
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ var package_default;
65
65
  var init_package = __esm(() => {
66
66
  package_default = {
67
67
  name: "@brainervirus/workit-cli",
68
- version: "8.21.0",
68
+ version: "8.21.2",
69
69
  private: false,
70
70
  description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
71
71
  keywords: [
@@ -103,13 +103,13 @@ var init_package = __esm(() => {
103
103
  },
104
104
  dependencies: {
105
105
  "@babel/parser": "7.29.9",
106
- "@brainervirus/workit-cursor": "^8.21.0",
106
+ "@brainervirus/workit-cursor": "^8.21.2",
107
107
  "@inkjs/ui": "2.0.0",
108
108
  ink: "7.1.1",
109
109
  react: "19.2.8"
110
110
  },
111
111
  devDependencies: {
112
- "@brainervirus/workit-core": "^8.21.0"
112
+ "@brainervirus/workit-core": "^8.21.2"
113
113
  },
114
114
  engines: {
115
115
  node: ">=24"
@@ -70988,48 +70988,156 @@ var init_search_select = __esm(async () => {
70988
70988
  ];
70989
70989
  });
70990
70990
 
70991
- // packages/workit-cli/src/steps.tsx
70992
- function workspacePreviewTargets(cwd) {
70993
- const norm = cwd.replace(/[\\/]+$/, "");
70994
- const idx = norm.lastIndexOf("/");
70995
- const parent = idx > 0 ? norm.slice(0, idx) : norm;
70996
- return [norm, parent, `${norm}/child-repo`];
70997
- }
70998
- function SelectList({
70999
- options,
71000
- value,
71001
- onChange,
71002
- onSelect
71003
- }) {
71004
- const [index, setIndex] = import_react66.useState(() => Math.max(0, options.findIndex((option) => option.value === value)));
71005
- const indexRef = import_react66.useRef(index);
71006
- import_react66.useEffect(() => {
71007
- indexRef.current = index;
71008
- }, [index]);
71009
- use_input_default((_input, key) => {
71010
- if (key.downArrow || key.upArrow) {
71011
- const next = key.downArrow ? Math.min(indexRef.current + 1, options.length - 1) : Math.max(indexRef.current - 1, 0);
71012
- if (next === indexRef.current)
71013
- return;
71014
- indexRef.current = next;
71015
- setIndex(next);
71016
- onChange?.(options[next].value);
71017
- } else if (key.return) {
71018
- onSelect(options[indexRef.current].value);
71019
- }
70991
+ // packages/workit-cli/src/steps/options.ts
70992
+ function effectivePolicy(values) {
70993
+ return mergePreset(values.branchPreset, {
70994
+ allowed: parseList(values.branchAllowed),
70995
+ protectedNames: parseList(values.branchProtected)
71020
70996
  });
71021
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71022
- flexDirection: "column",
71023
- gap: 0,
71024
- children: options.map((option, i) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71025
- color: i === index ? "cyan" : "dim",
71026
- children: [
71027
- i === index ? "❯ " : " ",
71028
- option.label
71029
- ]
71030
- }, option.value, true, undefined, this))
71031
- }, undefined, false, undefined, this);
71032
70997
  }
70998
+ var PLATFORM_LABELS, BRANCH_PRESETS, BRANCH_PRESET_DESCRIPTIONS, SCREEN_PLACEHOLDERS, VCS_PROVIDERS, LOCALE_PICKER_OPTIONS, ISSUE_TRACKERS, WORKSPACE_ADVANCED_FIELDS, PROFILE_FIELDS, TRACK_FIELDS, enumFieldOptions = (field) => {
70999
+ if (field === "commitPolicy.preset")
71000
+ return [{ label: "Inherit global", value: "inherit" }, ...commitPresetOptions];
71001
+ if (field === "branchPolicy.preset")
71002
+ return [
71003
+ { label: "Inherit global", value: "inherit" },
71004
+ { label: "GitFlow", value: "gitflow" },
71005
+ { label: "GitHub Flow", value: "github-flow" },
71006
+ { label: "Trunk-based", value: "trunk-based" },
71007
+ { label: "Custom", value: "custom" }
71008
+ ];
71009
+ if (field === "strategy")
71010
+ return [
71011
+ { label: "GitFlow", value: "gitflow" },
71012
+ { label: "GitHub Flow", value: "github-flow" },
71013
+ { label: "Trunk-based", value: "trunk-based" },
71014
+ { label: "Custom", value: "custom" }
71015
+ ];
71016
+ if (field.endsWith(".integration"))
71017
+ return [
71018
+ { label: "Pull requests", value: "pr" },
71019
+ { label: "Merge commits", value: "merge" }
71020
+ ];
71021
+ if (field === "versionSource.kind")
71022
+ return [
71023
+ { label: "Package.json", value: "package-json" },
71024
+ { label: "Git tag", value: "git-tag" },
71025
+ { label: "Manual", value: "manual" }
71026
+ ];
71027
+ if (field === "youtrack.link_issues" || field === "issues.link_on_pr")
71028
+ return [
71029
+ { label: "Inherit global behavior", value: "inherit" },
71030
+ { label: "Enabled", value: "true" },
71031
+ { label: "Disabled", value: "false" }
71032
+ ];
71033
+ return null;
71034
+ }, commitPresetOptions;
71035
+ var init_options = __esm(async () => {
71036
+ init_config();
71037
+ init_logic();
71038
+ await init_search_select();
71039
+ PLATFORM_LABELS = [
71040
+ { label: "OpenCode", value: "opencode" },
71041
+ { label: "Cursor", value: "cursor" },
71042
+ { label: "Codex", value: "codex" },
71043
+ { label: "Pi", value: "pi" },
71044
+ { label: "Claude Code", value: "claude-code" }
71045
+ ];
71046
+ BRANCH_PRESETS = [
71047
+ { label: "GitFlow", value: "gitflow" },
71048
+ { label: "GitHub Flow", value: "github-flow" },
71049
+ { label: "Trunk-based", value: "trunk-based" },
71050
+ { label: "Custom", value: "custom" }
71051
+ ];
71052
+ BRANCH_PRESET_DESCRIPTIONS = {
71053
+ gitflow: `${PRESETS.gitflow.allowed.join(", ")} allowed · ` + `${PRESETS.gitflow.protected.join(", ")} protected · work merges into develop via PRs or merge commits`,
71054
+ "github-flow": `Anything goes (${PRESETS["github-flow"].allowed[0]}) · only ${PRESETS["github-flow"].protected.join(", ")} is protected · branches off main, back to main`,
71055
+ "trunk-based": `Short-lived branches off trunk · ${PRESETS["trunk-based"].protected.join(", ")} is the only protected branch`,
71056
+ custom: "Define your own allowed and protected patterns in the next prompts"
71057
+ };
71058
+ SCREEN_PLACEHOLDERS = {
71059
+ youtrack: "e.g. https://example.youtrack.cloud",
71060
+ localeOther: "e.g. en-US or es-CL",
71061
+ branchAllowed: "e.g. feature/*, bugfix/*",
71062
+ branchProtected: "e.g. main, develop",
71063
+ workspaceName: "e.g. work",
71064
+ workspaceGlob: "e.g. /work/**",
71065
+ branchPolicyDevelop: "e.g. develop"
71066
+ };
71067
+ VCS_PROVIDERS = [
71068
+ { label: "GitLab", value: "gitlab" },
71069
+ { label: "GitHub", value: "github" },
71070
+ { label: "Skip — configure later", value: "skip" }
71071
+ ];
71072
+ LOCALE_PICKER_OPTIONS = [
71073
+ ...LOCALE_LANGUAGE_MAP.map((entry) => ({ label: entry.label, value: entry.locale })),
71074
+ { label: "Other…", value: "other" }
71075
+ ];
71076
+ ISSUE_TRACKERS = [
71077
+ { label: "YouTrack", value: "youtrack" },
71078
+ { label: "GitHub Issues", value: "github" },
71079
+ { label: "GitLab Issues", value: "gitlab" },
71080
+ { label: "None", value: "none" }
71081
+ ];
71082
+ WORKSPACE_ADVANCED_FIELDS = [
71083
+ { label: "Hosting provider account", value: "vcs.account" },
71084
+ { label: "Default target branch", value: "vcs.defaultTargetBranch" },
71085
+ { label: "Workspace YouTrack URL", value: "youtrack.baseUrl" },
71086
+ { label: "Link issues in YouTrack", value: "youtrack.link_issues" },
71087
+ { label: "Link GitHub issues on pull requests", value: "issues.link_on_pr" },
71088
+ { label: "Branch preset", value: "branchPolicy.preset" },
71089
+ { label: "Allowed branch patterns", value: "branchPolicy.allowed" },
71090
+ { label: "Protected branches", value: "branchPolicy.protected" },
71091
+ { label: "Develop branch", value: "branchPolicy.developBranch" },
71092
+ { label: "Integration method (pr or merge)", value: "branchPolicy.integration" },
71093
+ { label: "Feature prefix", value: "branchPolicy.prefixes.feature" },
71094
+ { label: "Bugfix prefix", value: "branchPolicy.prefixes.bugfix" },
71095
+ { label: "Release prefix", value: "branchPolicy.prefixes.release" },
71096
+ { label: "Hotfix prefix", value: "branchPolicy.prefixes.hotfix" },
71097
+ { label: "Commit policy preset", value: "commitPolicy.preset" },
71098
+ { label: "Custom commit pattern", value: "commitPolicy.pattern" },
71099
+ { label: "Default profile name", value: "defaultProfile" }
71100
+ ];
71101
+ PROFILE_FIELDS = [
71102
+ { label: "Branch preset", value: "branchPolicy.preset" },
71103
+ { label: "Allowed patterns", value: "branchPolicy.allowed" },
71104
+ { label: "Protected branches", value: "branchPolicy.protected" },
71105
+ { label: "Develop branch", value: "branchPolicy.developBranch" },
71106
+ { label: "Integration (pr or merge)", value: "branchPolicy.integration" },
71107
+ { label: "Feature prefix", value: "branchPolicy.prefixes.feature" },
71108
+ { label: "Bugfix prefix", value: "branchPolicy.prefixes.bugfix" },
71109
+ { label: "Release prefix", value: "branchPolicy.prefixes.release" },
71110
+ { label: "Hotfix prefix", value: "branchPolicy.prefixes.hotfix" },
71111
+ { label: "Commit preset", value: "commitPolicy.preset" },
71112
+ { label: "Commit pattern", value: "commitPolicy.pattern" }
71113
+ ];
71114
+ TRACK_FIELDS = [
71115
+ { label: "Strategy", value: "strategy" },
71116
+ { label: "Production branch", value: "productionBranch" },
71117
+ { label: "Integration branch", value: "integrationBranch" },
71118
+ { label: "Feature branch naming", value: "naming.feature" },
71119
+ { label: "Release branch naming", value: "naming.release" },
71120
+ { label: "Hotfix branch naming", value: "naming.hotfix" },
71121
+ { label: "Base branch", value: "baseBranch" },
71122
+ { label: "Merge-back branches", value: "mergeBackBranches" },
71123
+ { label: "Pull request target", value: "pullRequestTarget" },
71124
+ { label: "Tag namespace", value: "tagNamespace" },
71125
+ { label: "Version source (manual, git-tag, package-json)", value: "versionSource.kind" },
71126
+ { label: "Package.json path", value: "versionSource.path" },
71127
+ { label: "Package version field", value: "versionSource.field" },
71128
+ { label: "Required checks", value: "requiredChecks" }
71129
+ ];
71130
+ commitPresetOptions = [
71131
+ { label: "Conventional commits", value: "conventional" },
71132
+ { label: "Gitmoji", value: "gitmoji" },
71133
+ { label: "Ticket prefix", value: "ticket-prefix" },
71134
+ { label: "Freeform", value: "freeform" },
71135
+ { label: "Custom pattern", value: "custom" },
71136
+ { label: "Auto-detect", value: "auto" }
71137
+ ];
71138
+ });
71139
+
71140
+ // packages/workit-cli/src/steps/host-picker.tsx
71033
71141
  function HostPicker({
71034
71142
  detection,
71035
71143
  selected,
@@ -71044,19 +71152,18 @@ function HostPicker({
71044
71152
  ];
71045
71153
  const [index, setIndex] = import_react66.useState(0);
71046
71154
  const indexRef = import_react66.useRef(index);
71047
- const [chosen, setChosen] = import_react66.useState(selected);
71048
- const chosenRef = import_react66.useRef(chosen);
71155
+ const chosenRef = import_react66.useRef(selected);
71049
71156
  import_react66.useEffect(() => {
71050
71157
  indexRef.current = index;
71051
71158
  }, [index]);
71052
71159
  import_react66.useEffect(() => {
71053
- chosenRef.current = chosen;
71054
- }, [chosen]);
71160
+ chosenRef.current = selected;
71161
+ }, [selected]);
71055
71162
  const update = (next) => {
71056
71163
  chosenRef.current = next;
71057
- setChosen(next);
71058
71164
  onChange(next);
71059
71165
  };
71166
+ const checkedHosts = new Set(selected);
71060
71167
  use_input_default((input, key) => {
71061
71168
  if (key.upArrow || key.downArrow) {
71062
71169
  const next = Math.max(0, Math.min(options.length - 1, indexRef.current + (key.downArrow ? 1 : -1)));
@@ -71089,7 +71196,7 @@ function HostPicker({
71089
71196
  children: options.map((option, row) => {
71090
71197
  const host = option.value === "__all" || option.value === "__none" ? null : option.value;
71091
71198
  const detected = host === null || detection[host].detected;
71092
- const checked = host !== null && chosen.includes(host);
71199
+ const checked = host !== null && checkedHosts.has(host);
71093
71200
  const label = host === null ? option.label : `${checked ? "[✓]" : "[ ]"} ${option.label}${detection[host].configured ? " · already configured" : detection[host].detected ? " · detected" : " · unavailable"}`;
71094
71201
  return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71095
71202
  color: row === index ? "cyan" : undefined,
@@ -71102,436 +71209,745 @@ function HostPicker({
71102
71209
  })
71103
71210
  }, undefined, false, undefined, this);
71104
71211
  }
71105
- function WorkspaceCollectionEditor({
71106
- draft,
71107
- dispatch
71212
+ var import_react66, jsx_dev_runtime2;
71213
+ var init_host_picker = __esm(async () => {
71214
+ await __promiseAll([
71215
+ init_build2(),
71216
+ init_options()
71217
+ ]);
71218
+ import_react66 = __toESM(require_react(), 1);
71219
+ jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
71220
+ });
71221
+
71222
+ // packages/workit-cli/src/steps/select-list.tsx
71223
+ function SelectList({
71224
+ options,
71225
+ value,
71226
+ onChange,
71227
+ onSelect
71108
71228
  }) {
71109
- const [mode, setMode] = import_react66.useState("main");
71110
- const [name, setName] = import_react66.useState("");
71111
- const [field, setField] = import_react66.useState(null);
71112
- const [nameError, setNameError] = import_react66.useState("");
71113
- const workspace = draft.workspaceDraft;
71114
- const profileNames = Object.keys(workspace?.profiles ?? {});
71115
- const trackNames = Object.keys(workspace?.releaseTracks ?? {});
71116
- if (!workspace)
71117
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71118
- color: "red",
71119
- children: "Workspace draft is unavailable."
71120
- }, undefined, false, undefined, this);
71121
- if (mode === "profiles") {
71122
- const options = [
71123
- ...profileNames.flatMap((profile) => [
71124
- { label: `Edit profile ${profile}`, value: `edit:${profile}` },
71125
- { label: `Set ${profile} as default`, value: `default:${profile}` },
71126
- { label: `Delete profile ${profile}`, value: `delete:${profile}` }
71127
- ]),
71128
- { label: "Create profile", value: "create" },
71129
- { label: "Back to advanced settings", value: "back" }
71130
- ];
71131
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71132
- flexDirection: "column",
71133
- gap: 1,
71229
+ const [index, setIndex] = import_react67.useState(() => Math.max(0, options.findIndex((option) => option.value === value)));
71230
+ const indexRef = import_react67.useRef(index);
71231
+ import_react67.useEffect(() => {
71232
+ indexRef.current = index;
71233
+ }, [index]);
71234
+ use_input_default((_input, key) => {
71235
+ if (key.downArrow || key.upArrow) {
71236
+ const next = key.downArrow ? Math.min(indexRef.current + 1, options.length - 1) : Math.max(indexRef.current - 1, 0);
71237
+ if (next === indexRef.current)
71238
+ return;
71239
+ indexRef.current = next;
71240
+ setIndex(next);
71241
+ onChange?.(options[next].value);
71242
+ } else if (key.return) {
71243
+ onSelect(options[indexRef.current].value);
71244
+ }
71245
+ });
71246
+ return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
71247
+ flexDirection: "column",
71248
+ gap: 0,
71249
+ children: options.map((option, i) => /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
71250
+ color: i === index ? "cyan" : "dim",
71134
71251
  children: [
71135
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71136
- bold: true,
71137
- children: [
71138
- "Profiles · default: ",
71139
- workspace.defaultProfile ?? "none"
71140
- ]
71141
- }, undefined, true, undefined, this),
71142
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71143
- dimColor: true,
71144
- children: "Profiles can override branch rules and commit conventions."
71145
- }, undefined, false, undefined, this),
71146
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71147
- options,
71148
- value: "back",
71149
- onSelect: (value) => {
71150
- const profileName = value.slice(value.indexOf(":") + 1);
71151
- if (value === "create") {
71152
- setNameError("");
71153
- setName("");
71154
- setMode("profileName");
71155
- } else if (value.startsWith("edit:")) {
71156
- setName(profileName);
71157
- setMode("profileEdit");
71158
- } else if (value.startsWith("default:"))
71159
- dispatch({ type: "workspaceProfileDefault", name: profileName });
71160
- else if (value.startsWith("delete:"))
71161
- dispatch({ type: "workspaceProfileDelete", name: profileName });
71162
- else
71163
- setMode("main");
71164
- }
71165
- }, undefined, false, undefined, this)
71252
+ i === index ? "❯ " : " ",
71253
+ option.label
71166
71254
  ]
71167
- }, undefined, true, undefined, this);
71168
- }
71169
- if (mode === "profileName")
71170
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71171
- flexDirection: "column",
71172
- gap: 1,
71173
- children: [
71174
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71175
- bold: true,
71176
- children: "Create profile"
71177
- }, undefined, false, undefined, this),
71178
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71179
- dimColor: true,
71180
- children: "Profile name:"
71181
- }, undefined, false, undefined, this),
71182
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
71183
- onSubmit: (value) => {
71184
- const next = value.trim();
71185
- if (!next) {
71186
- setNameError("Enter a profile name.");
71187
- return;
71188
- }
71189
- if (workspace.profiles?.[next]) {
71190
- setNameError(`Profile ${next} already exists. Choose a different name or edit it from the list.`);
71191
- return;
71192
- }
71193
- dispatch({ type: "workspaceProfileCreate", name: next });
71194
- setName(next);
71195
- setMode("profileEdit");
71255
+ }, option.value, true, undefined, this))
71256
+ }, undefined, false, undefined, this);
71257
+ }
71258
+ var import_react67, jsx_dev_runtime3;
71259
+ var init_select_list = __esm(async () => {
71260
+ await init_build2();
71261
+ import_react67 = __toESM(require_react(), 1);
71262
+ jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
71263
+ });
71264
+
71265
+ // packages/workit-cli/src/steps/global-screens.tsx
71266
+ function PlatformsScreen({
71267
+ draft,
71268
+ dispatch,
71269
+ detection = emptyDetection()
71270
+ }) {
71271
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71272
+ flexDirection: "column",
71273
+ gap: 1,
71274
+ children: [
71275
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71276
+ bold: true,
71277
+ children: "Step 1 — Platforms"
71278
+ }, undefined, false, undefined, this),
71279
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71280
+ children: "Choose the detected tools where Workit should be configured."
71281
+ }, undefined, false, undefined, this),
71282
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71283
+ dimColor: true,
71284
+ children: "Use Space to toggle, or choose Select all available / Clear all."
71285
+ }, undefined, false, undefined, this),
71286
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(HostPicker, {
71287
+ detection,
71288
+ selected: draft.values.platforms,
71289
+ onChange: (values) => dispatch({ type: "set", field: "platforms", value: values }),
71290
+ onSubmit: (values) => {
71291
+ dispatch({ type: "set", field: "platforms", value: values });
71292
+ dispatch({ type: "next" });
71293
+ }
71294
+ }, undefined, false, undefined, this),
71295
+ draft.errors.platforms && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71296
+ color: "red",
71297
+ children: draft.errors.platforms
71298
+ }, undefined, false, undefined, this),
71299
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71300
+ dimColor: true,
71301
+ children: "Enter to continue · Esc Cancel"
71302
+ }, undefined, false, undefined, this)
71303
+ ]
71304
+ }, undefined, true, undefined, this);
71305
+ }
71306
+ function LocaleScreen({ draft, dispatch, onSearchQueryChange }) {
71307
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71308
+ flexDirection: "column",
71309
+ gap: 1,
71310
+ children: [
71311
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71312
+ bold: true,
71313
+ children: "Step 2 — Global config · Locale"
71314
+ }, undefined, false, undefined, this),
71315
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71316
+ dimColor: true,
71317
+ children: "Locale (BCP-47):"
71318
+ }, undefined, false, undefined, this),
71319
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71320
+ children: [
71321
+ "Current: ",
71322
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71323
+ color: "green",
71324
+ children: draft.values.locale
71325
+ }, undefined, false, undefined, this)
71326
+ ]
71327
+ }, undefined, true, undefined, this),
71328
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(SearchSelect, {
71329
+ options: LOCALE_PICKER_OPTIONS,
71330
+ value: draft.values.locale,
71331
+ placeholder: "Type to search languages…",
71332
+ onQueryChange: onSearchQueryChange,
71333
+ onSelect: (value) => {
71334
+ if (value === "other")
71335
+ dispatch({ type: "pickOther" });
71336
+ else {
71337
+ dispatch({ type: "set", field: "locale", value });
71338
+ dispatch({ type: "next" });
71196
71339
  }
71197
- }, undefined, false, undefined, this),
71198
- nameError && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71199
- color: "red",
71200
- children: nameError
71201
- }, undefined, false, undefined, this),
71202
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71203
- dimColor: true,
71204
- children: "Enter to create · Esc Back"
71205
- }, undefined, false, undefined, this)
71206
- ]
71207
- }, undefined, true, undefined, this);
71208
- if (mode === "profileEdit" || mode === "profileValue") {
71209
- const selected = workspace.profiles?.[name];
71210
- if (mode === "profileValue" && field) {
71211
- const item = PROFILE_FIELDS.find((entry) => entry.value === field);
71212
- const choices = enumFieldOptions(field);
71213
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71340
+ }
71341
+ }, undefined, false, undefined, this),
71342
+ draft.errors.locale && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71343
+ color: "red",
71344
+ children: draft.errors.locale
71345
+ }, undefined, false, undefined, this),
71346
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71347
+ dimColor: true,
71348
+ children: "Type to filter · Enter to continue · b Back · Esc Cancel"
71349
+ }, undefined, false, undefined, this)
71350
+ ]
71351
+ }, undefined, true, undefined, this);
71352
+ }
71353
+ function LocaleOtherScreen({ draft, dispatch }) {
71354
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71355
+ flexDirection: "column",
71356
+ gap: 1,
71357
+ children: [
71358
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71359
+ bold: true,
71360
+ children: "Step 2 — Global config · Locale (custom)"
71361
+ }, undefined, false, undefined, this),
71362
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71363
+ dimColor: true,
71364
+ children: "Type a BCP-47 locale (e.g. en or es-CL):"
71365
+ }, undefined, false, undefined, this),
71366
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(TextInput, {
71367
+ placeholder: SCREEN_PLACEHOLDERS.localeOther,
71368
+ onChange: (value) => dispatch({ type: "set", field: "locale", value }),
71369
+ onSubmit: () => dispatch({ type: "next" })
71370
+ }, undefined, false, undefined, this),
71371
+ draft.errors.locale && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71372
+ color: "red",
71373
+ children: draft.errors.locale
71374
+ }, undefined, false, undefined, this),
71375
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71376
+ dimColor: true,
71377
+ children: "Enter to continue · Esc Back"
71378
+ }, undefined, false, undefined, this)
71379
+ ]
71380
+ }, undefined, true, undefined, this);
71381
+ }
71382
+ function BranchPresetScreen({ draft, dispatch }) {
71383
+ const policy = effectivePolicy(draft.values);
71384
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71385
+ flexDirection: "column",
71386
+ gap: 1,
71387
+ children: [
71388
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71389
+ bold: true,
71390
+ children: "Step 2 — Global config · Branch policy"
71391
+ }, undefined, false, undefined, this),
71392
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71393
+ dimColor: true,
71394
+ children: "Branch policy preset:"
71395
+ }, undefined, false, undefined, this),
71396
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(SelectList, {
71397
+ options: BRANCH_PRESETS,
71398
+ value: draft.values.branchPreset,
71399
+ onChange: (value) => dispatch({ type: "set", field: "branchPreset", value }),
71400
+ onSelect: () => dispatch({ type: "next" })
71401
+ }, undefined, false, undefined, this),
71402
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71403
+ dimColor: true,
71404
+ children: BRANCH_PRESET_DESCRIPTIONS[draft.values.branchPreset]
71405
+ }, undefined, false, undefined, this),
71406
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71214
71407
  flexDirection: "column",
71215
- gap: 1,
71408
+ gap: 0,
71216
71409
  children: [
71217
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71218
- bold: true,
71410
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71219
71411
  children: [
71220
- "Profile ",
71221
- name,
71222
- " · ",
71223
- item?.label
71412
+ "Allowed: ",
71413
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71414
+ color: "green",
71415
+ children: policy.allowed.join(", ") || "—"
71416
+ }, undefined, false, undefined, this)
71224
71417
  ]
71225
71418
  }, undefined, true, undefined, this),
71226
- choices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71227
- options: choices,
71228
- value: selected ? profileEditorValue(selected, field) : choices[0].value,
71229
- onSelect: (value) => {
71230
- dispatch({
71231
- type: "workspaceProfileSet",
71232
- name,
71233
- field,
71234
- value
71235
- });
71236
- setMode("profileEdit");
71237
- }
71238
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
71239
- defaultValue: selected ? profileEditorValue(selected, field) : "",
71240
- onSubmit: (value) => {
71241
- dispatch({
71242
- type: "workspaceProfileSet",
71243
- name,
71244
- field,
71245
- value
71246
- });
71247
- setMode("profileEdit");
71248
- }
71249
- }, undefined, false, undefined, this),
71250
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71251
- dimColor: true,
71252
- children: "Enter to save · Esc Back"
71253
- }, undefined, false, undefined, this)
71419
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71420
+ children: [
71421
+ "Protected: ",
71422
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71423
+ color: "green",
71424
+ children: policy.protected.join(", ") || "—"
71425
+ }, undefined, false, undefined, this)
71426
+ ]
71427
+ }, undefined, true, undefined, this)
71254
71428
  ]
71255
- }, undefined, true, undefined, this);
71256
- }
71257
- const options = [
71258
- ...PROFILE_FIELDS,
71259
- { label: "Done editing", value: "done" }
71260
- ];
71261
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71262
- flexDirection: "column",
71263
- gap: 1,
71264
- children: [
71265
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71266
- bold: true,
71267
- children: [
71268
- "Edit profile · ",
71269
- name
71270
- ]
71271
- }, undefined, true, undefined, this),
71272
- PROFILE_FIELDS.map((item) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71273
- dimColor: true,
71274
- children: [
71275
- item.label,
71276
- ": ",
71277
- selected ? profileEditorValue(selected, item.value) || "unset" : ""
71278
- ]
71279
- }, item.value, true, undefined, this)),
71280
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71281
- options,
71282
- value: "done",
71283
- onSelect: (value) => {
71284
- if (value === "done")
71285
- setMode("profiles");
71286
- else {
71287
- setField(value);
71288
- setMode("profileValue");
71289
- }
71290
- }
71291
- }, undefined, false, undefined, this)
71292
- ]
71293
- }, undefined, true, undefined, this);
71294
- }
71295
- if (mode === "tracks") {
71296
- const options = [
71297
- ...trackNames.flatMap((track) => [
71298
- { label: `Edit release track ${track}`, value: `edit:${track}` },
71299
- { label: `Delete release track ${track}`, value: `delete:${track}` }
71300
- ]),
71301
- { label: "Create release track", value: "create" },
71302
- { label: "Back to advanced settings", value: "back" }
71303
- ];
71304
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71305
- flexDirection: "column",
71306
- gap: 1,
71307
- children: [
71308
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71309
- bold: true,
71310
- children: "Named release tracks"
71311
- }, undefined, false, undefined, this),
71312
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71313
- dimColor: true,
71314
- children: "Each track has its own branches, naming, version source, and checks."
71315
- }, undefined, false, undefined, this),
71316
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71317
- options,
71318
- value: "back",
71319
- onSelect: (value) => {
71320
- const trackName = value.slice(value.indexOf(":") + 1);
71321
- if (value === "create") {
71322
- setNameError("");
71323
- setName("");
71324
- setMode("trackName");
71325
- } else if (value.startsWith("edit:")) {
71326
- setName(trackName);
71327
- setMode("trackEdit");
71328
- } else if (value.startsWith("delete:"))
71329
- dispatch({ type: "workspaceTrackDelete", name: trackName });
71330
- else
71331
- setMode("main");
71332
- }
71333
- }, undefined, false, undefined, this)
71334
- ]
71335
- }, undefined, true, undefined, this);
71336
- }
71337
- if (mode === "trackName")
71338
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71339
- flexDirection: "column",
71340
- gap: 1,
71341
- children: [
71342
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71343
- bold: true,
71344
- children: "Create release track"
71345
- }, undefined, false, undefined, this),
71346
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71347
- dimColor: true,
71348
- children: "Track name:"
71349
- }, undefined, false, undefined, this),
71350
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
71351
- onSubmit: (value) => {
71352
- const next = value.trim();
71353
- if (!next) {
71354
- setNameError("Enter a release-track name.");
71355
- return;
71356
- }
71357
- if (workspace.releaseTracks?.[next]) {
71358
- setNameError(`Release track ${next} already exists. Choose a different name or edit it from the list.`);
71359
- return;
71360
- }
71361
- dispatch({ type: "workspaceTrackCreate", name: next });
71362
- setName(next);
71363
- setMode("trackEdit");
71364
- }
71365
- }, undefined, false, undefined, this),
71366
- nameError && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71367
- color: "red",
71368
- children: nameError
71369
- }, undefined, false, undefined, this),
71370
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71371
- dimColor: true,
71372
- children: "Enter to create · Esc Back"
71373
- }, undefined, false, undefined, this)
71374
- ]
71375
- }, undefined, true, undefined, this);
71376
- if (mode === "trackEdit" || mode === "trackValue") {
71377
- const selected = workspace.releaseTracks?.[name];
71378
- if (mode === "trackValue" && field) {
71379
- const item = TRACK_FIELDS.find((entry) => entry.value === field);
71380
- const choices = enumFieldOptions(field);
71381
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71429
+ }, undefined, true, undefined, this),
71430
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71431
+ dimColor: true,
71432
+ children: policy.preset === "custom" ? "Enter to continue — define the patterns next · b Back · Esc Cancel" : "Enter to continue · b Back · Esc Cancel"
71433
+ }, undefined, false, undefined, this)
71434
+ ]
71435
+ }, undefined, true, undefined, this);
71436
+ }
71437
+ function BranchAllowedScreen({ draft, dispatch }) {
71438
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71439
+ flexDirection: "column",
71440
+ gap: 1,
71441
+ children: [
71442
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71443
+ bold: true,
71444
+ children: "Step 2 — Global config · Allowed branch patterns"
71445
+ }, undefined, false, undefined, this),
71446
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71447
+ dimColor: true,
71448
+ children: "Allowed branch patterns (comma-separated):"
71449
+ }, undefined, false, undefined, this),
71450
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(TextInput, {
71451
+ placeholder: SCREEN_PLACEHOLDERS.branchAllowed,
71452
+ defaultValue: draft.values.branchAllowed,
71453
+ onChange: (value) => dispatch({ type: "set", field: "branchAllowed", value }),
71454
+ onSubmit: () => dispatch({ type: "next" })
71455
+ }, undefined, false, undefined, this),
71456
+ draft.errors.branchAllowed && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71457
+ color: "red",
71458
+ children: draft.errors.branchAllowed
71459
+ }, undefined, false, undefined, this),
71460
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71461
+ dimColor: true,
71462
+ children: "Enter to continue · Esc Back"
71463
+ }, undefined, false, undefined, this)
71464
+ ]
71465
+ }, undefined, true, undefined, this);
71466
+ }
71467
+ function BranchProtectedScreen({ draft, dispatch }) {
71468
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71469
+ flexDirection: "column",
71470
+ gap: 1,
71471
+ children: [
71472
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71473
+ bold: true,
71474
+ children: "Step 2 — Global config · Protected branch names"
71475
+ }, undefined, false, undefined, this),
71476
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71477
+ dimColor: true,
71478
+ children: "Protected branch names (comma-separated):"
71479
+ }, undefined, false, undefined, this),
71480
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(TextInput, {
71481
+ placeholder: SCREEN_PLACEHOLDERS.branchProtected,
71482
+ defaultValue: draft.values.branchProtected,
71483
+ onChange: (value) => dispatch({ type: "set", field: "branchProtected", value }),
71484
+ onSubmit: () => dispatch({ type: "next" })
71485
+ }, undefined, false, undefined, this),
71486
+ draft.errors.branchProtected && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71487
+ color: "red",
71488
+ children: draft.errors.branchProtected
71489
+ }, undefined, false, undefined, this),
71490
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71491
+ dimColor: true,
71492
+ children: "Enter to continue · Esc Back"
71493
+ }, undefined, false, undefined, this)
71494
+ ]
71495
+ }, undefined, true, undefined, this);
71496
+ }
71497
+ function IssueTrackerScreen({ draft, dispatch }) {
71498
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71499
+ flexDirection: "column",
71500
+ gap: 1,
71501
+ children: [
71502
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71503
+ bold: true,
71504
+ children: "Step 3 — Issue tracker"
71505
+ }, undefined, false, undefined, this),
71506
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71507
+ dimColor: true,
71508
+ children: "Where do issues live?"
71509
+ }, undefined, false, undefined, this),
71510
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(SelectList, {
71511
+ options: ISSUE_TRACKERS,
71512
+ value: draft.values.issueTracker,
71513
+ onChange: (value) => dispatch({ type: "set", field: "issueTracker", value }),
71514
+ onSelect: () => dispatch({ type: "next" })
71515
+ }, undefined, false, undefined, this),
71516
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71517
+ dimColor: true,
71518
+ children: "Enter to continue · b Back · Esc Cancel"
71519
+ }, undefined, false, undefined, this)
71520
+ ]
71521
+ }, undefined, true, undefined, this);
71522
+ }
71523
+ function YoutrackScreen({ draft, dispatch }) {
71524
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71525
+ flexDirection: "column",
71526
+ gap: 1,
71527
+ children: [
71528
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71529
+ bold: true,
71530
+ children: "Step 3 — YouTrack"
71531
+ }, undefined, false, undefined, this),
71532
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71533
+ dimColor: true,
71534
+ children: "Base URL (https):"
71535
+ }, undefined, false, undefined, this),
71536
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(TextInput, {
71537
+ placeholder: SCREEN_PLACEHOLDERS.youtrack,
71538
+ defaultValue: draft.values.baseUrl,
71539
+ onChange: (value) => dispatch({ type: "set", field: "baseUrl", value }),
71540
+ onSubmit: () => dispatch({ type: "next" })
71541
+ }, undefined, false, undefined, this),
71542
+ draft.errors.baseUrl && /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71543
+ color: "red",
71544
+ children: draft.errors.baseUrl
71545
+ }, undefined, false, undefined, this),
71546
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71547
+ dimColor: true,
71548
+ children: "Enter to continue · Esc Back"
71549
+ }, undefined, false, undefined, this)
71550
+ ]
71551
+ }, undefined, true, undefined, this);
71552
+ }
71553
+ function VcsScreen({ draft, dispatch }) {
71554
+ return /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
71555
+ flexDirection: "column",
71556
+ gap: 1,
71557
+ children: [
71558
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71559
+ bold: true,
71560
+ children: "Step 4 — Version control"
71561
+ }, undefined, false, undefined, this),
71562
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71563
+ dimColor: true,
71564
+ children: "Provider:"
71565
+ }, undefined, false, undefined, this),
71566
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(SelectList, {
71567
+ options: VCS_PROVIDERS,
71568
+ value: draft.values.vcsProvider,
71569
+ onChange: (value) => dispatch({ type: "set", field: "vcsProvider", value }),
71570
+ onSelect: () => dispatch({ type: "next" })
71571
+ }, undefined, false, undefined, this),
71572
+ /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
71573
+ dimColor: true,
71574
+ children: "Enter to continue · b Back · Esc Cancel"
71575
+ }, undefined, false, undefined, this)
71576
+ ]
71577
+ }, undefined, true, undefined, this);
71578
+ }
71579
+ var jsx_dev_runtime4;
71580
+ var init_global_screens = __esm(async () => {
71581
+ init_detect_hosts();
71582
+ await __promiseAll([
71583
+ init_build2(),
71584
+ init_build3(),
71585
+ init_search_select(),
71586
+ init_host_picker(),
71587
+ init_select_list(),
71588
+ init_options()
71589
+ ]);
71590
+ jsx_dev_runtime4 = __toESM(require_jsx_dev_runtime(), 1);
71591
+ });
71592
+
71593
+ // packages/workit-cli/src/steps/workspace-screens.tsx
71594
+ function workspacePreviewTargets(cwd) {
71595
+ const norm = cwd.replace(/[\\/]+$/, "");
71596
+ const idx = norm.lastIndexOf("/");
71597
+ const parent = idx > 0 ? norm.slice(0, idx) : norm;
71598
+ return [norm, parent, `${norm}/child-repo`];
71599
+ }
71600
+ function WorkspacesScreen({ draft, dispatch }) {
71601
+ const base = resolveBasePath(draft.values);
71602
+ const options = [
71603
+ ...draft.values.workspaces.map((w, i) => ({
71604
+ label: `Edit ${w.name} (${w.glob})`,
71605
+ value: `edit:${i}`
71606
+ })),
71607
+ ...draft.values.workspaces.map((w, i) => ({
71608
+ label: `Remove ${w.name}`,
71609
+ value: `remove:${i}`
71610
+ })),
71611
+ { label: "Add workspace", value: "add" },
71612
+ { label: `Use current project (${base})`, value: "current" },
71613
+ { label: "Done", value: "done" },
71614
+ { label: "Advanced global commit policy", value: "global-commit" },
71615
+ ...draft.values.workspaces.map((w, i) => ({
71616
+ label: `Advanced settings for ${w.name}`,
71617
+ value: `advanced:${i}`
71618
+ }))
71619
+ ];
71620
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71621
+ flexDirection: "column",
71622
+ gap: 1,
71623
+ children: [
71624
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71625
+ bold: true,
71626
+ children: "Step 5 — Workspaces"
71627
+ }, undefined, false, undefined, this),
71628
+ draft.values.workspaces.length === 0 ? /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71629
+ dimColor: true,
71630
+ children: "No workspaces configured yet."
71631
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71632
+ flexDirection: "column",
71633
+ gap: 0,
71634
+ children: draft.values.workspaces.map((w) => {
71635
+ const matches = matchWorkspace(w.glob, base);
71636
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71637
+ children: [
71638
+ matches ? "✓ matches" : "✗ no match",
71639
+ " ",
71640
+ w.name,
71641
+ " — ",
71642
+ w.vcs?.provider ?? "?",
71643
+ " —",
71644
+ " ",
71645
+ w.glob
71646
+ ]
71647
+ }, `${w.name}|${w.glob}|${w.vcs?.provider ?? ""}`, true, undefined, this);
71648
+ })
71649
+ }, undefined, false, undefined, this),
71650
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(SelectList, {
71651
+ options,
71652
+ value: "done",
71653
+ onSelect: (value) => {
71654
+ if (value.startsWith("edit:"))
71655
+ dispatch({ type: "workspaceEdit", index: Number(value.slice(5)) });
71656
+ else if (value.startsWith("remove:"))
71657
+ dispatch({ type: "workspaceRemove", index: Number(value.slice(7)) });
71658
+ else if (value.startsWith("advanced:"))
71659
+ dispatch({ type: "workspaceAdvancedOpen", index: Number(value.slice(9)) });
71660
+ else if (value === "global-commit")
71661
+ dispatch({ type: "globalCommitOpen" });
71662
+ else if (value === "add")
71663
+ dispatch({ type: "workspaceAdd" });
71664
+ else if (value === "current")
71665
+ dispatch({ type: "workspaceAddCurrent", path: base });
71666
+ else
71667
+ dispatch({ type: "next" });
71668
+ }
71669
+ }, draft.values.workspaces.map((w) => `${w.name}:${w.glob}`).join("|"), false, undefined, this),
71670
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71671
+ dimColor: true,
71672
+ children: "Enter to continue · b Back · Esc Cancel"
71673
+ }, undefined, false, undefined, this)
71674
+ ]
71675
+ }, undefined, true, undefined, this);
71676
+ }
71677
+ function WorkspaceNameScreen({ draft, dispatch }) {
71678
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71679
+ flexDirection: "column",
71680
+ gap: 1,
71681
+ children: [
71682
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71683
+ bold: true,
71684
+ children: "Step 5 — Workspaces · Name"
71685
+ }, undefined, false, undefined, this),
71686
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71687
+ dimColor: true,
71688
+ children: draft.workspaceIndex === null ? "New workspace name:" : `Edit workspace name (${draft.values.workspaces[draft.workspaceIndex]?.name ?? ""}):`
71689
+ }, undefined, false, undefined, this),
71690
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(TextInput, {
71691
+ placeholder: SCREEN_PLACEHOLDERS.workspaceName,
71692
+ defaultValue: draft.workspaceDraft?.name ?? "",
71693
+ onChange: (value) => dispatch({ type: "workspaceDraftName", value }),
71694
+ onSubmit: () => dispatch({ type: "next" })
71695
+ }, undefined, false, undefined, this),
71696
+ draft.errors.workspaceName && /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71697
+ color: "red",
71698
+ children: draft.errors.workspaceName
71699
+ }, undefined, false, undefined, this),
71700
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71701
+ dimColor: true,
71702
+ children: "Enter to continue · Esc Back"
71703
+ }, undefined, false, undefined, this)
71704
+ ]
71705
+ }, undefined, true, undefined, this);
71706
+ }
71707
+ function WorkspaceGlobScreen({ draft, dispatch }) {
71708
+ const glob = draft.workspaceDraft?.glob ?? "";
71709
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71710
+ flexDirection: "column",
71711
+ gap: 1,
71712
+ children: [
71713
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71714
+ bold: true,
71715
+ children: "Step 5 — Workspaces · Pattern"
71716
+ }, undefined, false, undefined, this),
71717
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71718
+ dimColor: true,
71719
+ children: "Workspace pattern (glob, e.g. /work/**):"
71720
+ }, undefined, false, undefined, this),
71721
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(TextInput, {
71722
+ placeholder: SCREEN_PLACEHOLDERS.workspaceGlob,
71723
+ defaultValue: glob,
71724
+ onChange: (value) => dispatch({ type: "workspaceDraftGlob", value }),
71725
+ onSubmit: () => dispatch({ type: "next" })
71726
+ }, undefined, false, undefined, this),
71727
+ glob.trim() !== "" && /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71382
71728
  flexDirection: "column",
71383
- gap: 1,
71729
+ gap: 0,
71384
71730
  children: [
71385
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71731
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71386
71732
  bold: true,
71387
- children: [
71388
- "Release track ",
71389
- name,
71390
- " · ",
71391
- item?.label
71392
- ]
71393
- }, undefined, true, undefined, this),
71394
- choices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71395
- options: choices,
71396
- value: selected ? trackEditorValue(selected, field) : choices[0].value,
71397
- onSelect: (value) => {
71398
- dispatch({
71399
- type: "workspaceTrackSet",
71400
- name,
71401
- field,
71402
- value
71403
- });
71404
- setMode("trackEdit");
71405
- }
71406
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
71407
- defaultValue: selected ? trackEditorValue(selected, field) : "",
71408
- onSubmit: (value) => {
71409
- dispatch({
71410
- type: "workspaceTrackSet",
71411
- name,
71412
- field,
71413
- value
71414
- });
71415
- setMode("trackEdit");
71416
- }
71733
+ children: "Match preview (shared matcher):"
71417
71734
  }, undefined, false, undefined, this),
71418
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71419
- dimColor: true,
71420
- children: "Lists use comma-separated values · Enter to save · Esc Back"
71421
- }, undefined, false, undefined, this)
71735
+ workspacePreviewTargets(resolveBasePath(draft.values)).map((target) => {
71736
+ const matches = matchWorkspace(glob, target);
71737
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71738
+ color: matches ? "green" : "red",
71739
+ children: [
71740
+ matches ? "✓ matches" : "✗ no match",
71741
+ " ",
71742
+ target
71743
+ ]
71744
+ }, target, true, undefined, this);
71745
+ })
71422
71746
  ]
71423
- }, undefined, true, undefined, this);
71424
- }
71425
- const options = [...TRACK_FIELDS, { label: "Done editing", value: "done" }];
71426
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71427
- flexDirection: "column",
71428
- gap: 1,
71429
- children: [
71430
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71431
- bold: true,
71432
- children: [
71433
- "Edit release track · ",
71434
- name
71435
- ]
71436
- }, undefined, true, undefined, this),
71437
- TRACK_FIELDS.map((item) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71438
- dimColor: true,
71439
- children: [
71440
- item.label,
71441
- ": ",
71442
- selected ? trackEditorValue(selected, item.value) || "unset" : ""
71443
- ]
71444
- }, item.value, true, undefined, this)),
71445
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71446
- options,
71447
- value: "done",
71448
- onSelect: (value) => {
71449
- if (value === "done")
71450
- setMode("tracks");
71451
- else {
71452
- setField(value);
71453
- setMode("trackValue");
71454
- }
71455
- }
71456
- }, undefined, false, undefined, this)
71457
- ]
71458
- }, undefined, true, undefined, this);
71459
- }
71460
- const options = [
71461
- ...WORKSPACE_ADVANCED_FIELDS,
71462
- { label: "Manage profiles", value: "profiles" },
71463
- { label: "Manage release tracks", value: "tracks" },
71464
- { label: "Save workspace settings", value: "save" }
71465
- ];
71466
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71747
+ }, undefined, true, undefined, this),
71748
+ draft.errors.workspaceGlob && /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71749
+ color: "red",
71750
+ children: draft.errors.workspaceGlob
71751
+ }, undefined, false, undefined, this),
71752
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71753
+ dimColor: true,
71754
+ children: "Enter to continue · Esc Back"
71755
+ }, undefined, false, undefined, this)
71756
+ ]
71757
+ }, undefined, true, undefined, this);
71758
+ }
71759
+ function WorkspaceProviderScreen({ draft, dispatch }) {
71760
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71761
+ flexDirection: "column",
71762
+ gap: 1,
71763
+ children: [
71764
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71765
+ bold: true,
71766
+ children: "Step 5 — Workspaces · Provider"
71767
+ }, undefined, false, undefined, this),
71768
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71769
+ dimColor: true,
71770
+ children: "Version control provider for this workspace:"
71771
+ }, undefined, false, undefined, this),
71772
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(SelectList, {
71773
+ options: VCS_PROVIDERS,
71774
+ value: draft.workspaceDraft?.vcs?.provider ?? "skip",
71775
+ onChange: (value) => dispatch({ type: "workspaceDraftProvider", value }),
71776
+ onSelect: (value) => {
71777
+ dispatch({ type: "workspaceDraftProvider", value });
71778
+ dispatch({ type: "workspaceSave" });
71779
+ }
71780
+ }, undefined, false, undefined, this),
71781
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71782
+ dimColor: true,
71783
+ children: "Enter to save · b Back · Esc Cancel"
71784
+ }, undefined, false, undefined, this)
71785
+ ]
71786
+ }, undefined, true, undefined, this);
71787
+ }
71788
+ function WorkspaceAdvancedValueScreen({ draft, dispatch }) {
71789
+ const field = draft.workspaceEditorField;
71790
+ const current = draft.workspaceDraft && field ? workspaceEditorValue(draft.workspaceDraft, field) : "";
71791
+ const label = WORKSPACE_ADVANCED_FIELDS.find((entry) => entry.value === field)?.label ?? "Setting";
71792
+ const choices = field ? enumFieldOptions(field) : null;
71793
+ const profileChoices = field === "defaultProfile" ? [
71794
+ { label: "Inherit / no default profile", value: "" },
71795
+ ...Object.keys(draft.workspaceDraft?.profiles ?? {}).map((name) => ({
71796
+ label: name,
71797
+ value: name
71798
+ }))
71799
+ ] : null;
71800
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71467
71801
  flexDirection: "column",
71468
71802
  gap: 1,
71469
71803
  children: [
71470
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71804
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71471
71805
  bold: true,
71472
71806
  children: [
71473
71807
  "Advanced workspace settings · ",
71474
- workspace.name
71808
+ label
71475
71809
  ]
71476
71810
  }, undefined, true, undefined, this),
71477
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71811
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71478
71812
  dimColor: true,
71479
- children: "Choose a setting to edit. Lists use comma-separated values; blank clears an override."
71813
+ children: "Leave empty to clear this override. Use comma-separated values for lists."
71814
+ }, undefined, false, undefined, this),
71815
+ profileChoices ? /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(SelectList, {
71816
+ options: profileChoices,
71817
+ value: current,
71818
+ onSelect: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
71819
+ }, undefined, false, undefined, this) : choices ? /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(SelectList, {
71820
+ options: choices,
71821
+ value: current || choices[0].value,
71822
+ onSelect: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
71823
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(TextInput, {
71824
+ defaultValue: current,
71825
+ onSubmit: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
71826
+ }, undefined, false, undefined, this),
71827
+ field?.endsWith("integration") && /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71828
+ dimColor: true,
71829
+ children: "Enter pr or merge."
71830
+ }, undefined, false, undefined, this),
71831
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71832
+ dimColor: true,
71833
+ children: "Enter to save · Esc Back"
71834
+ }, undefined, false, undefined, this)
71835
+ ]
71836
+ }, undefined, true, undefined, this);
71837
+ }
71838
+ function GlobalCommitPolicyScreen({ draft, dispatch }) {
71839
+ const options = [
71840
+ { label: "Conventional commits", value: "conventional" },
71841
+ { label: "Gitmoji", value: "gitmoji" },
71842
+ { label: "Ticket prefix", value: "ticket-prefix" },
71843
+ { label: "Freeform", value: "freeform" },
71844
+ { label: "Custom pattern", value: "custom" },
71845
+ { label: "Auto-detect", value: "auto" },
71846
+ { label: "Edit custom pattern…", value: "pattern" },
71847
+ { label: "Done", value: "done" }
71848
+ ];
71849
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71850
+ flexDirection: "column",
71851
+ gap: 1,
71852
+ children: [
71853
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71854
+ bold: true,
71855
+ children: "Advanced global commit policy"
71856
+ }, undefined, false, undefined, this),
71857
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71858
+ dimColor: true,
71859
+ children: "Default convention used when a workspace has no commit override."
71480
71860
  }, undefined, false, undefined, this),
71481
- [...WORKSPACE_ADVANCED_FIELDS].map(({ label, value }) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71861
+ draft.values.commitPolicy.pattern && /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71482
71862
  dimColor: true,
71483
71863
  children: [
71484
- label,
71485
- ": ",
71486
- workspaceEditorValue(workspace, value) || "inherited / unset"
71864
+ "Custom pattern: ",
71865
+ draft.values.commitPolicy.pattern
71487
71866
  ]
71488
- }, value, true, undefined, this)),
71489
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71867
+ }, undefined, true, undefined, this),
71868
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(SelectList, {
71490
71869
  options,
71491
- value: "save",
71870
+ value: draft.values.commitPolicy.preset,
71492
71871
  onSelect: (value) => {
71493
- if (value === "save")
71494
- dispatch({ type: "workspaceSave" });
71495
- else if (value === "profiles")
71496
- setMode("profiles");
71497
- else if (value === "tracks")
71498
- setMode("tracks");
71872
+ if (value === "pattern")
71873
+ dispatch({ type: "globalCommitEditPattern" });
71874
+ else if (value === "done")
71875
+ dispatch({ type: "back" });
71499
71876
  else
71500
- dispatch({ type: "workspaceAdvancedSelect", field: value });
71877
+ dispatch({ type: "globalCommitPreset", value });
71501
71878
  }
71879
+ }, undefined, false, undefined, this),
71880
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71881
+ dimColor: true,
71882
+ children: "Enter to select · b Back"
71502
71883
  }, undefined, false, undefined, this)
71503
71884
  ]
71504
71885
  }, undefined, true, undefined, this);
71505
71886
  }
71506
- function effectivePolicy(values) {
71507
- return mergePreset(values.branchPreset, {
71508
- allowed: parseList(values.branchAllowed),
71509
- protectedNames: parseList(values.branchProtected)
71510
- });
71887
+ function GlobalCommitPatternScreen({ draft, dispatch }) {
71888
+ return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
71889
+ flexDirection: "column",
71890
+ gap: 1,
71891
+ children: [
71892
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71893
+ bold: true,
71894
+ children: "Advanced global commit policy · Custom pattern"
71895
+ }, undefined, false, undefined, this),
71896
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71897
+ dimColor: true,
71898
+ children: "Regular expression matched against the commit subject line."
71899
+ }, undefined, false, undefined, this),
71900
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(TextInput, {
71901
+ defaultValue: draft.values.commitPolicy.pattern ?? "",
71902
+ onChange: (value) => dispatch({ type: "globalCommitPattern", value }),
71903
+ onSubmit: () => dispatch({ type: "globalCommitPatternDone" })
71904
+ }, undefined, false, undefined, this),
71905
+ /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
71906
+ dimColor: true,
71907
+ children: "Enter to save · Esc Back"
71908
+ }, undefined, false, undefined, this)
71909
+ ]
71910
+ }, undefined, true, undefined, this);
71511
71911
  }
71912
+ var jsx_dev_runtime5;
71913
+ var init_workspace_screens = __esm(async () => {
71914
+ init_workspaces();
71915
+ init_logic();
71916
+ init_wizard_state();
71917
+ await __promiseAll([
71918
+ init_build2(),
71919
+ init_build3(),
71920
+ init_select_list(),
71921
+ init_options()
71922
+ ]);
71923
+ jsx_dev_runtime5 = __toESM(require_jsx_dev_runtime(), 1);
71924
+ });
71925
+
71926
+ // packages/workit-cli/src/steps/finish-screens.tsx
71512
71927
  function BranchPolicyScreen({ draft, dispatch }) {
71513
71928
  const detected = draft.values.branchPolicyDetected;
71514
71929
  const policy = draft.values.branchPolicy ?? detected;
71515
- const [mode, setMode] = import_react66.useState("menu");
71516
- import_react66.useEffect(() => {
71930
+ const [mode, setMode] = import_react68.useState("menu");
71931
+ const basePath = resolveBasePath(draft.values);
71932
+ import_react68.useEffect(() => {
71517
71933
  if (detected)
71518
71934
  return;
71519
71935
  dispatch({
71520
71936
  type: "set",
71521
71937
  field: "branchPolicyDetected",
71522
- value: detectBranchPolicy(resolveBasePath(draft.values))
71938
+ value: detectBranchPolicy(basePath)
71523
71939
  });
71524
- }, [detected, dispatch]);
71940
+ }, [detected, dispatch, basePath]);
71525
71941
  if (mode === "integration") {
71526
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71942
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
71527
71943
  flexDirection: "column",
71528
71944
  gap: 1,
71529
71945
  children: [
71530
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71946
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71531
71947
  bold: true,
71532
71948
  children: "Step 5 — Branch policy · Integration"
71533
71949
  }, undefined, false, undefined, this),
71534
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71950
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(SelectList, {
71535
71951
  options: INTEGRATION_OPTIONS,
71536
71952
  value: policy?.integration ?? "merge",
71537
71953
  onSelect: (value) => {
@@ -71539,77 +71955,77 @@ function BranchPolicyScreen({ draft, dispatch }) {
71539
71955
  setMode("menu");
71540
71956
  }
71541
71957
  }, undefined, false, undefined, this),
71542
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71958
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71543
71959
  dimColor: true,
71544
71960
  children: "Enter to select · b Back · Esc Cancel"
71545
71961
  }, undefined, false, undefined, this)
71546
71962
  ]
71547
71963
  }, undefined, true, undefined, this);
71548
71964
  }
71549
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71965
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
71550
71966
  flexDirection: "column",
71551
71967
  gap: 1,
71552
71968
  children: [
71553
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71969
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71554
71970
  bold: true,
71555
71971
  children: "Step 5 — Branch policy"
71556
71972
  }, undefined, false, undefined, this),
71557
- policy ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71973
+ policy ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
71558
71974
  flexDirection: "column",
71559
71975
  gap: 0,
71560
71976
  children: [
71561
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71977
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71562
71978
  children: [
71563
71979
  "Detected preset: ",
71564
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71980
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71565
71981
  color: "green",
71566
71982
  children: policy.preset
71567
71983
  }, undefined, false, undefined, this)
71568
71984
  ]
71569
71985
  }, undefined, true, undefined, this),
71570
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71986
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71571
71987
  children: [
71572
71988
  "Develop branch: ",
71573
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71989
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71574
71990
  color: "green",
71575
71991
  children: policy.developBranch ?? "—"
71576
71992
  }, undefined, false, undefined, this)
71577
71993
  ]
71578
71994
  }, undefined, true, undefined, this),
71579
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71995
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71580
71996
  children: [
71581
71997
  "Integration: ",
71582
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71998
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71583
71999
  color: "green",
71584
72000
  children: policy.integration
71585
72001
  }, undefined, false, undefined, this)
71586
72002
  ]
71587
72003
  }, undefined, true, undefined, this),
71588
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72004
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71589
72005
  children: [
71590
72006
  "Prefixes:",
71591
72007
  " ",
71592
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72008
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71593
72009
  color: "green",
71594
72010
  children: Object.values(policy.prefixes ?? {}).join(", ") || "—"
71595
72011
  }, undefined, false, undefined, this)
71596
72012
  ]
71597
72013
  }, undefined, true, undefined, this),
71598
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72014
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71599
72015
  children: [
71600
72016
  "Protected: ",
71601
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72017
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71602
72018
  color: "green",
71603
72019
  children: policy.protected?.join(", ") || "—"
71604
72020
  }, undefined, false, undefined, this)
71605
72021
  ]
71606
72022
  }, undefined, true, undefined, this)
71607
72023
  ]
71608
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72024
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71609
72025
  dimColor: true,
71610
72026
  children: "Detecting branch policy…"
71611
72027
  }, undefined, false, undefined, this),
71612
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
72028
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(SelectList, {
71613
72029
  options: BRANCH_POLICY_ACTIONS,
71614
72030
  value: "accept",
71615
72031
  onSelect: (value) => {
@@ -71625,71 +72041,13 @@ function BranchPolicyScreen({ draft, dispatch }) {
71625
72041
  dispatch({ type: "next" });
71626
72042
  }
71627
72043
  }, undefined, false, undefined, this),
71628
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72044
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71629
72045
  dimColor: true,
71630
72046
  children: "Enter to continue · b Back · Esc Cancel"
71631
72047
  }, undefined, false, undefined, this)
71632
72048
  ]
71633
72049
  }, undefined, true, undefined, this);
71634
72050
  }
71635
- function Wizard({
71636
- onExit,
71637
- detection = emptyDetection()
71638
- }) {
71639
- const [draft, dispatch] = import_react66.useReducer(reducer3, detection, (found) => {
71640
- const initial = createInitialDraft();
71641
- const platforms = preselectedPlatforms(found);
71642
- return platforms.length > 0 ? { ...initial, values: { ...initial.values, platforms } } : initial;
71643
- });
71644
- const exitedRef = import_react66.useRef(false);
71645
- const searchRef = import_react66.useRef({ q: "", typed: false });
71646
- import_react66.useEffect(() => {
71647
- searchRef.current = { q: "", typed: false };
71648
- }, [draft.screen]);
71649
- use_input_default((input, key) => {
71650
- if (key.ctrl && input.toLowerCase() === "c") {
71651
- dispatch({ type: "cancel" });
71652
- } else if (key.escape) {
71653
- if (TEXT_SCREENS.has(draft.screen))
71654
- dispatch({ type: "back" });
71655
- else
71656
- dispatch({ type: "cancel" });
71657
- } else if (input.toLowerCase() === "b" && !TEXT_SCREENS.has(draft.screen)) {
71658
- const search = searchRef.current;
71659
- const searchOwnsB = SEARCH_SCREENS.has(draft.screen) && !(search.typed && search.q === "");
71660
- if (!searchOwnsB)
71661
- dispatch({ type: "back" });
71662
- }
71663
- });
71664
- import_react66.useEffect(() => {
71665
- if (draft.screen === "exit" && !exitedRef.current) {
71666
- exitedRef.current = true;
71667
- onExit(!draft.cancelled, draft.values);
71668
- }
71669
- }, [draft.screen, draft.cancelled, draft.values, onExit]);
71670
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71671
- flexDirection: "column",
71672
- gap: 1,
71673
- children: [
71674
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71675
- bold: true,
71676
- color: "cyan",
71677
- children: "workit — workflow rails for agentic coding"
71678
- }, undefined, false, undefined, this),
71679
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Screen, {
71680
- draft,
71681
- dispatch,
71682
- detection,
71683
- onSearchQueryChange: (query) => {
71684
- const search = searchRef.current;
71685
- search.q = query;
71686
- if (query !== "")
71687
- search.typed = true;
71688
- }
71689
- }, draft.screen, false, undefined, this)
71690
- ]
71691
- }, undefined, true, undefined, this);
71692
- }
71693
72051
  function describeMutation(m) {
71694
72052
  switch (m.type) {
71695
72053
  case "create-file":
@@ -71710,1165 +72068,866 @@ function describeMutation(m) {
71710
72068
  return `+ change ${m.key} in ${m.path} → ${m.value}`;
71711
72069
  }
71712
72070
  }
72071
+ function mutationRows(mutations) {
72072
+ const seen = new Map;
72073
+ return mutations.map((m) => {
72074
+ const text = describeMutation(m);
72075
+ const count = seen.get(text) ?? 0;
72076
+ seen.set(text, count + 1);
72077
+ return { key: count === 0 ? text : `${text}#${count}`, text };
72078
+ });
72079
+ }
71713
72080
  function BasePathScreen({ draft, dispatch }) {
71714
- const onChange = import_react66.useCallback((value) => dispatch({ type: "set", field: "basePath", value }), [dispatch]);
71715
- const onSubmit = import_react66.useCallback((value) => {
72081
+ const onChange = import_react68.useCallback((value) => dispatch({ type: "set", field: "basePath", value }), [dispatch]);
72082
+ const onSubmit = import_react68.useCallback((value) => {
71716
72083
  dispatch({ type: "set", field: "basePath", value });
71717
72084
  dispatch({ type: "next" });
71718
72085
  }, [dispatch]);
71719
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72086
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
71720
72087
  flexDirection: "column",
71721
72088
  gap: 1,
71722
72089
  children: [
71723
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72090
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71724
72091
  bold: true,
71725
72092
  children: "Step 5 — Workspace root"
71726
72093
  }, undefined, false, undefined, this),
71727
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72094
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71728
72095
  dimColor: true,
71729
72096
  children: "Absolute path where your projects live (e.g. /work):"
71730
72097
  }, undefined, false, undefined, this),
71731
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
72098
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(TextInput, {
71732
72099
  defaultValue: draft.values.basePath,
71733
72100
  onChange,
71734
72101
  onSubmit
71735
72102
  }, undefined, false, undefined, this),
71736
- draft.errors.basePath && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72103
+ draft.errors.basePath && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71737
72104
  color: "red",
71738
72105
  children: draft.errors.basePath
71739
72106
  }, undefined, false, undefined, this),
71740
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72107
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
71741
72108
  dimColor: true,
71742
72109
  children: "Enter to continue · Esc Back"
71743
72110
  }, undefined, false, undefined, this)
71744
72111
  ]
71745
72112
  }, undefined, true, undefined, this);
71746
72113
  }
71747
- function Screen({
71748
- draft,
71749
- dispatch,
71750
- detection = emptyDetection(),
71751
- onSearchQueryChange
71752
- }) {
71753
- switch (draft.screen) {
71754
- case "platforms":
71755
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71756
- flexDirection: "column",
71757
- gap: 1,
71758
- children: [
71759
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71760
- bold: true,
71761
- children: "Step 1 — Platforms"
71762
- }, undefined, false, undefined, this),
71763
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71764
- children: "Choose the detected tools where Workit should be configured."
71765
- }, undefined, false, undefined, this),
71766
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71767
- dimColor: true,
71768
- children: "Use Space to toggle, or choose Select all available / Clear all."
71769
- }, undefined, false, undefined, this),
71770
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(HostPicker, {
71771
- detection,
71772
- selected: draft.values.platforms,
71773
- onChange: (values) => dispatch({ type: "set", field: "platforms", value: values }),
71774
- onSubmit: (values) => {
71775
- dispatch({ type: "set", field: "platforms", value: values });
71776
- dispatch({ type: "next" });
71777
- }
71778
- }, undefined, false, undefined, this),
71779
- draft.errors.platforms && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71780
- color: "red",
71781
- children: draft.errors.platforms
71782
- }, undefined, false, undefined, this),
71783
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71784
- dimColor: true,
71785
- children: "Enter to continue · Esc Cancel"
71786
- }, undefined, false, undefined, this)
71787
- ]
71788
- }, undefined, true, undefined, this);
71789
- case "locale":
71790
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71791
- flexDirection: "column",
71792
- gap: 1,
71793
- children: [
71794
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71795
- bold: true,
71796
- children: "Step 2 — Global config · Locale"
71797
- }, undefined, false, undefined, this),
71798
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71799
- dimColor: true,
71800
- children: "Locale (BCP-47):"
71801
- }, undefined, false, undefined, this),
71802
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71803
- children: [
71804
- "Current: ",
71805
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71806
- color: "green",
71807
- children: draft.values.locale
71808
- }, undefined, false, undefined, this)
71809
- ]
71810
- }, undefined, true, undefined, this),
71811
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SearchSelect, {
71812
- options: LOCALE_PICKER_OPTIONS,
71813
- value: draft.values.locale,
71814
- placeholder: "Type to search languages…",
71815
- onQueryChange: onSearchQueryChange,
71816
- onSelect: (value) => {
71817
- if (value === "other")
71818
- dispatch({ type: "pickOther" });
71819
- else {
71820
- dispatch({ type: "set", field: "locale", value });
71821
- dispatch({ type: "next" });
71822
- }
71823
- }
71824
- }, undefined, false, undefined, this),
71825
- draft.errors.locale && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71826
- color: "red",
71827
- children: draft.errors.locale
71828
- }, undefined, false, undefined, this),
71829
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71830
- dimColor: true,
71831
- children: "Type to filter · Enter to continue · b Back · Esc Cancel"
71832
- }, undefined, false, undefined, this)
71833
- ]
71834
- }, undefined, true, undefined, this);
71835
- case "localeOther":
71836
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71837
- flexDirection: "column",
71838
- gap: 1,
71839
- children: [
71840
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71841
- bold: true,
71842
- children: "Step 2 — Global config · Locale (custom)"
71843
- }, undefined, false, undefined, this),
71844
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71845
- dimColor: true,
71846
- children: "Type a BCP-47 locale (e.g. en or es-CL):"
71847
- }, undefined, false, undefined, this),
71848
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
71849
- placeholder: SCREEN_PLACEHOLDERS.localeOther,
71850
- onChange: (value) => dispatch({ type: "set", field: "locale", value }),
71851
- onSubmit: () => dispatch({ type: "next" })
71852
- }, undefined, false, undefined, this),
71853
- draft.errors.locale && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71854
- color: "red",
71855
- children: draft.errors.locale
71856
- }, undefined, false, undefined, this),
71857
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71858
- dimColor: true,
71859
- children: "Enter to continue · Esc Back"
71860
- }, undefined, false, undefined, this)
71861
- ]
71862
- }, undefined, true, undefined, this);
71863
- case "branchPreset": {
71864
- const policy = effectivePolicy(draft.values);
71865
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71866
- flexDirection: "column",
71867
- gap: 1,
71868
- children: [
71869
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71870
- bold: true,
71871
- children: "Step 2 — Global config · Branch policy"
71872
- }, undefined, false, undefined, this),
71873
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71874
- dimColor: true,
71875
- children: "Branch policy preset:"
71876
- }, undefined, false, undefined, this),
71877
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71878
- options: BRANCH_PRESETS,
71879
- value: draft.values.branchPreset,
71880
- onChange: (value) => dispatch({ type: "set", field: "branchPreset", value }),
71881
- onSelect: () => dispatch({ type: "next" })
71882
- }, undefined, false, undefined, this),
71883
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71884
- dimColor: true,
71885
- children: BRANCH_PRESET_DESCRIPTIONS[draft.values.branchPreset]
71886
- }, undefined, false, undefined, this),
71887
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71888
- flexDirection: "column",
71889
- gap: 0,
71890
- children: [
71891
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71892
- children: [
71893
- "Allowed: ",
71894
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71895
- color: "green",
71896
- children: policy.allowed.join(", ") || "—"
71897
- }, undefined, false, undefined, this)
71898
- ]
71899
- }, undefined, true, undefined, this),
71900
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71901
- children: [
71902
- "Protected: ",
71903
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71904
- color: "green",
71905
- children: policy.protected.join(", ") || "—"
71906
- }, undefined, false, undefined, this)
71907
- ]
71908
- }, undefined, true, undefined, this)
71909
- ]
71910
- }, undefined, true, undefined, this),
71911
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71912
- dimColor: true,
71913
- children: policy.preset === "custom" ? "Enter to continue — define the patterns next · b Back · Esc Cancel" : "Enter to continue · b Back · Esc Cancel"
71914
- }, undefined, false, undefined, this)
71915
- ]
71916
- }, undefined, true, undefined, this);
71917
- }
71918
- case "branchAllowed":
71919
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71920
- flexDirection: "column",
71921
- gap: 1,
71922
- children: [
71923
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71924
- bold: true,
71925
- children: "Step 2 — Global config · Allowed branch patterns"
71926
- }, undefined, false, undefined, this),
71927
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71928
- dimColor: true,
71929
- children: "Allowed branch patterns (comma-separated):"
71930
- }, undefined, false, undefined, this),
71931
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
71932
- placeholder: SCREEN_PLACEHOLDERS.branchAllowed,
71933
- defaultValue: draft.values.branchAllowed,
71934
- onChange: (value) => dispatch({ type: "set", field: "branchAllowed", value }),
71935
- onSubmit: () => dispatch({ type: "next" })
71936
- }, undefined, false, undefined, this),
71937
- draft.errors.branchAllowed && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71938
- color: "red",
71939
- children: draft.errors.branchAllowed
71940
- }, undefined, false, undefined, this),
71941
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71942
- dimColor: true,
71943
- children: "Enter to continue · Esc Back"
71944
- }, undefined, false, undefined, this)
71945
- ]
71946
- }, undefined, true, undefined, this);
71947
- case "branchProtected":
71948
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71949
- flexDirection: "column",
71950
- gap: 1,
71951
- children: [
71952
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71953
- bold: true,
71954
- children: "Step 2 — Global config · Protected branch names"
71955
- }, undefined, false, undefined, this),
71956
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71957
- dimColor: true,
71958
- children: "Protected branch names (comma-separated):"
71959
- }, undefined, false, undefined, this),
71960
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
71961
- placeholder: SCREEN_PLACEHOLDERS.branchProtected,
71962
- defaultValue: draft.values.branchProtected,
71963
- onChange: (value) => dispatch({ type: "set", field: "branchProtected", value }),
71964
- onSubmit: () => dispatch({ type: "next" })
71965
- }, undefined, false, undefined, this),
71966
- draft.errors.branchProtected && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71967
- color: "red",
71968
- children: draft.errors.branchProtected
71969
- }, undefined, false, undefined, this),
71970
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71971
- dimColor: true,
71972
- children: "Enter to continue · Esc Back"
71973
- }, undefined, false, undefined, this)
71974
- ]
71975
- }, undefined, true, undefined, this);
71976
- case "issueTracker":
71977
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
71978
- flexDirection: "column",
71979
- gap: 1,
71980
- children: [
71981
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71982
- bold: true,
71983
- children: "Step 3 — Issue tracker"
71984
- }, undefined, false, undefined, this),
71985
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71986
- dimColor: true,
71987
- children: "Where do issues live?"
71988
- }, undefined, false, undefined, this),
71989
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
71990
- options: ISSUE_TRACKERS,
71991
- value: draft.values.issueTracker,
71992
- onChange: (value) => dispatch({ type: "set", field: "issueTracker", value }),
71993
- onSelect: () => dispatch({ type: "next" })
71994
- }, undefined, false, undefined, this),
71995
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
71996
- dimColor: true,
71997
- children: "Enter to continue · b Back · Esc Cancel"
71998
- }, undefined, false, undefined, this)
71999
- ]
72000
- }, undefined, true, undefined, this);
72001
- case "youtrack":
72002
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72003
- flexDirection: "column",
72004
- gap: 1,
72005
- children: [
72006
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72007
- bold: true,
72008
- children: "Step 3 — YouTrack"
72009
- }, undefined, false, undefined, this),
72010
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72011
- dimColor: true,
72012
- children: "Base URL (https):"
72013
- }, undefined, false, undefined, this),
72014
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
72015
- placeholder: SCREEN_PLACEHOLDERS.youtrack,
72016
- defaultValue: draft.values.baseUrl,
72017
- onChange: (value) => dispatch({ type: "set", field: "baseUrl", value }),
72018
- onSubmit: () => dispatch({ type: "next" })
72019
- }, undefined, false, undefined, this),
72020
- draft.errors.baseUrl && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72021
- color: "red",
72022
- children: draft.errors.baseUrl
72023
- }, undefined, false, undefined, this),
72024
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72025
- dimColor: true,
72026
- children: "Enter to continue · Esc Back"
72027
- }, undefined, false, undefined, this)
72028
- ]
72029
- }, undefined, true, undefined, this);
72030
- case "vcs":
72031
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72032
- flexDirection: "column",
72033
- gap: 1,
72034
- children: [
72035
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72036
- bold: true,
72037
- children: "Step 4 — Version control"
72038
- }, undefined, false, undefined, this),
72039
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72040
- dimColor: true,
72041
- children: "Provider:"
72042
- }, undefined, false, undefined, this),
72043
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
72044
- options: VCS_PROVIDERS,
72045
- value: draft.values.vcsProvider,
72046
- onChange: (value) => dispatch({ type: "set", field: "vcsProvider", value }),
72047
- onSelect: () => dispatch({ type: "next" })
72048
- }, undefined, false, undefined, this),
72049
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72050
- dimColor: true,
72051
- children: "Enter to continue · b Back · Esc Cancel"
72052
- }, undefined, false, undefined, this)
72053
- ]
72054
- }, undefined, true, undefined, this);
72055
- case "basePath":
72056
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(BasePathScreen, {
72057
- draft,
72058
- dispatch
72059
- }, undefined, false, undefined, this);
72060
- case "workspaces": {
72061
- const base = resolveBasePath(draft.values);
72062
- const options = [
72063
- ...draft.values.workspaces.map((w, i) => ({
72064
- label: `Edit ${w.name} (${w.glob})`,
72065
- value: `edit:${i}`
72066
- })),
72067
- ...draft.values.workspaces.map((w, i) => ({
72068
- label: `Remove ${w.name}`,
72069
- value: `remove:${i}`
72070
- })),
72071
- { label: "Add workspace", value: "add" },
72072
- { label: `Use current project (${base})`, value: "current" },
72073
- { label: "Done", value: "done" },
72074
- { label: "Advanced global commit policy", value: "global-commit" },
72075
- ...draft.values.workspaces.map((w, i) => ({
72076
- label: `Advanced settings for ${w.name}`,
72077
- value: `advanced:${i}`
72078
- }))
72079
- ];
72080
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72081
- flexDirection: "column",
72082
- gap: 1,
72083
- children: [
72084
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72085
- bold: true,
72086
- children: "Step 5 — Workspaces"
72087
- }, undefined, false, undefined, this),
72088
- draft.values.workspaces.length === 0 ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72089
- dimColor: true,
72090
- children: "No workspaces configured yet."
72091
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72092
- flexDirection: "column",
72093
- gap: 0,
72094
- children: draft.values.workspaces.map((w) => {
72095
- const matches = matchWorkspace(w.glob, base);
72096
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72097
- children: [
72098
- matches ? "✓ matches" : "✗ no match",
72099
- " ",
72100
- w.name,
72101
- " — ",
72102
- w.vcs?.provider ?? "?",
72103
- " —",
72104
- " ",
72105
- w.glob
72106
- ]
72107
- }, `${w.name}|${w.glob}|${w.vcs?.provider ?? ""}`, true, undefined, this);
72108
- })
72109
- }, undefined, false, undefined, this),
72110
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
72111
- options,
72112
- value: "done",
72113
- onSelect: (value) => {
72114
- if (value.startsWith("edit:"))
72115
- dispatch({ type: "workspaceEdit", index: Number(value.slice(5)) });
72116
- else if (value.startsWith("remove:"))
72117
- dispatch({ type: "workspaceRemove", index: Number(value.slice(7)) });
72118
- else if (value.startsWith("advanced:"))
72119
- dispatch({ type: "workspaceAdvancedOpen", index: Number(value.slice(9)) });
72120
- else if (value === "global-commit")
72121
- dispatch({ type: "globalCommitOpen" });
72122
- else if (value === "add")
72123
- dispatch({ type: "workspaceAdd" });
72124
- else if (value === "current")
72125
- dispatch({ type: "workspaceAddCurrent", path: base });
72126
- else
72127
- dispatch({ type: "next" });
72128
- }
72129
- }, draft.values.workspaces.map((w) => `${w.name}:${w.glob}`).join("|"), false, undefined, this),
72130
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72131
- dimColor: true,
72132
- children: "Enter to continue · b Back · Esc Cancel"
72133
- }, undefined, false, undefined, this)
72134
- ]
72135
- }, undefined, true, undefined, this);
72136
- }
72137
- case "workspaceName":
72138
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72139
- flexDirection: "column",
72140
- gap: 1,
72141
- children: [
72142
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72143
- bold: true,
72144
- children: "Step 5 — Workspaces · Name"
72145
- }, undefined, false, undefined, this),
72146
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72147
- dimColor: true,
72148
- children: draft.workspaceIndex === null ? "New workspace name:" : `Edit workspace name (${draft.values.workspaces[draft.workspaceIndex]?.name ?? ""}):`
72149
- }, undefined, false, undefined, this),
72150
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
72151
- placeholder: SCREEN_PLACEHOLDERS.workspaceName,
72152
- defaultValue: draft.workspaceDraft?.name ?? "",
72153
- onChange: (value) => dispatch({ type: "workspaceDraftName", value }),
72154
- onSubmit: () => dispatch({ type: "next" })
72155
- }, undefined, false, undefined, this),
72156
- draft.errors.workspaceName && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72157
- color: "red",
72158
- children: draft.errors.workspaceName
72159
- }, undefined, false, undefined, this),
72160
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72161
- dimColor: true,
72162
- children: "Enter to continue · Esc Back"
72163
- }, undefined, false, undefined, this)
72164
- ]
72165
- }, undefined, true, undefined, this);
72166
- case "workspaceGlob": {
72167
- const glob = draft.workspaceDraft?.glob ?? "";
72168
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72169
- flexDirection: "column",
72170
- gap: 1,
72171
- children: [
72172
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72173
- bold: true,
72174
- children: "Step 5 — Workspaces · Pattern"
72175
- }, undefined, false, undefined, this),
72176
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72177
- dimColor: true,
72178
- children: "Workspace pattern (glob, e.g. /work/**):"
72179
- }, undefined, false, undefined, this),
72180
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
72181
- placeholder: SCREEN_PLACEHOLDERS.workspaceGlob,
72182
- defaultValue: glob,
72183
- onChange: (value) => dispatch({ type: "workspaceDraftGlob", value }),
72184
- onSubmit: () => dispatch({ type: "next" })
72185
- }, undefined, false, undefined, this),
72186
- glob.trim() !== "" && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72187
- flexDirection: "column",
72188
- gap: 0,
72189
- children: [
72190
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72191
- bold: true,
72192
- children: "Match preview (shared matcher):"
72193
- }, undefined, false, undefined, this),
72194
- workspacePreviewTargets(resolveBasePath(draft.values)).map((target) => {
72195
- const matches = matchWorkspace(glob, target);
72196
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72197
- color: matches ? "green" : "red",
72198
- children: [
72199
- matches ? "✓ matches" : "✗ no match",
72200
- " ",
72201
- target
72202
- ]
72203
- }, target, true, undefined, this);
72204
- })
72205
- ]
72206
- }, undefined, true, undefined, this),
72207
- draft.errors.workspaceGlob && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72208
- color: "red",
72209
- children: draft.errors.workspaceGlob
72210
- }, undefined, false, undefined, this),
72211
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72212
- dimColor: true,
72213
- children: "Enter to continue · Esc Back"
72214
- }, undefined, false, undefined, this)
72215
- ]
72216
- }, undefined, true, undefined, this);
72217
- }
72218
- case "workspaceProvider":
72219
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72220
- flexDirection: "column",
72221
- gap: 1,
72222
- children: [
72223
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72224
- bold: true,
72225
- children: "Step 5 — Workspaces · Provider"
72226
- }, undefined, false, undefined, this),
72227
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72228
- dimColor: true,
72229
- children: "Version control provider for this workspace:"
72230
- }, undefined, false, undefined, this),
72231
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
72232
- options: VCS_PROVIDERS,
72233
- value: draft.workspaceDraft?.vcs?.provider ?? "skip",
72234
- onChange: (value) => dispatch({ type: "workspaceDraftProvider", value }),
72235
- onSelect: (value) => {
72236
- dispatch({ type: "workspaceDraftProvider", value });
72237
- dispatch({ type: "workspaceSave" });
72238
- }
72239
- }, undefined, false, undefined, this),
72240
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72241
- dimColor: true,
72242
- children: "Enter to save · b Back · Esc Cancel"
72243
- }, undefined, false, undefined, this)
72244
- ]
72245
- }, undefined, true, undefined, this);
72246
- case "workspaceAdvanced": {
72247
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(WorkspaceCollectionEditor, {
72248
- draft,
72249
- dispatch
72250
- }, undefined, false, undefined, this);
72251
- }
72252
- case "workspaceAdvancedValue": {
72253
- const field = draft.workspaceEditorField;
72254
- const current = draft.workspaceDraft && field ? workspaceEditorValue(draft.workspaceDraft, field) : "";
72255
- const label = WORKSPACE_ADVANCED_FIELDS.find((entry) => entry.value === field)?.label ?? "Setting";
72256
- const choices = field ? enumFieldOptions(field) : null;
72257
- const profileChoices = field === "defaultProfile" ? [
72258
- { label: "Inherit / no default profile", value: "" },
72259
- ...Object.keys(draft.workspaceDraft?.profiles ?? {}).map((name) => ({
72260
- label: name,
72261
- value: name
72262
- }))
72263
- ] : null;
72264
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72265
- flexDirection: "column",
72266
- gap: 1,
72267
- children: [
72268
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72269
- bold: true,
72270
- children: [
72271
- "Advanced workspace settings · ",
72272
- label
72273
- ]
72274
- }, undefined, true, undefined, this),
72275
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72276
- dimColor: true,
72277
- children: "Leave empty to clear this override. Use comma-separated values for lists."
72278
- }, undefined, false, undefined, this),
72279
- profileChoices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
72280
- options: profileChoices,
72281
- value: current,
72282
- onSelect: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
72283
- }, undefined, false, undefined, this) : choices ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
72284
- options: choices,
72285
- value: current || choices[0].value,
72286
- onSelect: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
72287
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
72288
- defaultValue: current,
72289
- onSubmit: (value) => field && dispatch({ type: "workspaceAdvancedSet", field, value })
72290
- }, undefined, false, undefined, this),
72291
- field?.endsWith("integration") && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72292
- dimColor: true,
72293
- children: "Enter pr or merge."
72294
- }, undefined, false, undefined, this),
72295
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72296
- dimColor: true,
72297
- children: "Enter to save · Esc Back"
72298
- }, undefined, false, undefined, this)
72299
- ]
72300
- }, undefined, true, undefined, this);
72301
- }
72302
- case "globalCommitPolicy": {
72303
- const options = [
72304
- { label: "Conventional commits", value: "conventional" },
72305
- { label: "Gitmoji", value: "gitmoji" },
72306
- { label: "Ticket prefix", value: "ticket-prefix" },
72307
- { label: "Freeform", value: "freeform" },
72308
- { label: "Custom pattern", value: "custom" },
72309
- { label: "Auto-detect", value: "auto" },
72310
- { label: "Edit custom pattern…", value: "pattern" },
72311
- { label: "Done", value: "done" }
72312
- ];
72313
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72314
- flexDirection: "column",
72315
- gap: 1,
72114
+ function BranchPolicyDevelopScreen({ draft, dispatch }) {
72115
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72116
+ flexDirection: "column",
72117
+ gap: 1,
72118
+ children: [
72119
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72120
+ bold: true,
72121
+ children: "Step 5 — Branch policy · Develop branch"
72122
+ }, undefined, false, undefined, this),
72123
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72124
+ dimColor: true,
72125
+ children: "Integration/develop branch name (leave empty to unset):"
72126
+ }, undefined, false, undefined, this),
72127
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(TextInput, {
72128
+ placeholder: SCREEN_PLACEHOLDERS.branchPolicyDevelop,
72129
+ defaultValue: draft.values.branchPolicy?.developBranch ?? draft.values.branchPolicyDetected?.developBranch ?? "",
72130
+ onSubmit: (value) => {
72131
+ dispatch({ type: "set", field: "branchPolicyDevelop", value });
72132
+ dispatch({ type: "next" });
72133
+ }
72134
+ }, undefined, false, undefined, this),
72135
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72136
+ dimColor: true,
72137
+ children: "Enter to save · Esc Back"
72138
+ }, undefined, false, undefined, this)
72139
+ ]
72140
+ }, undefined, true, undefined, this);
72141
+ }
72142
+ function ProjectScreen({ draft, dispatch }) {
72143
+ const target = projectTargetFor(resolveBasePath(draft.values));
72144
+ if (!target.ok) {
72145
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72146
+ flexDirection: "column",
72147
+ gap: 1,
72148
+ children: [
72149
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72150
+ bold: true,
72151
+ children: "Step 6 — Project setup"
72152
+ }, undefined, false, undefined, this),
72153
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72154
+ color: "yellow",
72155
+ children: [
72156
+ "Skipped: ",
72157
+ target.refused
72158
+ ]
72159
+ }, undefined, true, undefined, this),
72160
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ConfirmInput, {
72161
+ defaultChoice: "confirm",
72162
+ submitOnEnter: false,
72163
+ onConfirm: () => {
72164
+ dispatch({ type: "set", field: "applyProject", value: true });
72165
+ dispatch({ type: "next" });
72166
+ },
72167
+ onCancel: () => {
72168
+ dispatch({ type: "set", field: "applyProject", value: false });
72169
+ dispatch({ type: "next" });
72170
+ }
72171
+ }, undefined, false, undefined, this),
72172
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72173
+ dimColor: true,
72174
+ children: "y to keep this note in the summary · n to skip it · either adds no project files · b Back · Esc Cancel"
72175
+ }, undefined, false, undefined, this)
72176
+ ]
72177
+ }, undefined, true, undefined, this);
72178
+ }
72179
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72180
+ flexDirection: "column",
72181
+ gap: 1,
72182
+ children: [
72183
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72184
+ bold: true,
72185
+ children: "Step 6 — Project setup"
72186
+ }, undefined, false, undefined, this),
72187
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72188
+ dimColor: true,
72316
72189
  children: [
72317
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72318
- bold: true,
72319
- children: "Advanced global commit policy"
72320
- }, undefined, false, undefined, this),
72321
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72322
- dimColor: true,
72323
- children: "Default convention used when a workspace has no commit override."
72324
- }, undefined, false, undefined, this),
72325
- draft.values.commitPolicy.pattern && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72326
- dimColor: true,
72327
- children: [
72328
- "Custom pattern: ",
72329
- draft.values.commitPolicy.pattern
72330
- ]
72331
- }, undefined, true, undefined, this),
72332
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
72333
- options,
72334
- value: draft.values.commitPolicy.preset,
72335
- onSelect: (value) => {
72336
- if (value === "pattern")
72337
- dispatch({ type: "globalCommitEditPattern" });
72338
- else if (value === "done")
72339
- dispatch({ type: "back" });
72340
- else
72341
- dispatch({ type: "globalCommitPreset", value });
72342
- }
72343
- }, undefined, false, undefined, this),
72344
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72345
- dimColor: true,
72346
- children: "Enter to select · b Back"
72347
- }, undefined, false, undefined, this)
72190
+ "Apply gitignore + hygiene in ",
72191
+ target.root,
72192
+ "? (Existing files are never overwritten.)"
72348
72193
  ]
72349
- }, undefined, true, undefined, this);
72194
+ }, undefined, true, undefined, this),
72195
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ConfirmInput, {
72196
+ defaultChoice: "cancel",
72197
+ submitOnEnter: false,
72198
+ onConfirm: () => {
72199
+ dispatch({ type: "set", field: "applyProject", value: true });
72200
+ dispatch({ type: "next" });
72201
+ },
72202
+ onCancel: () => {
72203
+ dispatch({ type: "set", field: "applyProject", value: false });
72204
+ dispatch({ type: "next" });
72205
+ }
72206
+ }, undefined, false, undefined, this),
72207
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72208
+ dimColor: true,
72209
+ children: "y to add project files · n to skip · b Back · Esc Cancel"
72210
+ }, undefined, false, undefined, this)
72211
+ ]
72212
+ }, undefined, true, undefined, this);
72213
+ }
72214
+ function SummaryScreen({ draft, dispatch }) {
72215
+ const policy = effectivePolicy(draft.values);
72216
+ const preview = buildSetupPreview(draft.values, { cwd: resolveBasePath(draft.values) });
72217
+ const policyPreview = (() => {
72218
+ try {
72219
+ const current = readConfig();
72220
+ const config = {
72221
+ ...current,
72222
+ branchPolicy: mergePreset(draft.values.branchPreset, {
72223
+ allowed: parseList(draft.values.branchAllowed),
72224
+ protectedNames: parseList(draft.values.branchProtected)
72225
+ }, current),
72226
+ commitPolicy: draft.values.commitPolicy
72227
+ };
72228
+ const checkout = resolveBasePath(draft.values);
72229
+ const workspace = resolveWorkspaceFromEntries(checkout, draft.values.workspaces);
72230
+ const resolved = resolveWorkspacePolicy(config, workspace, undefined, () => repoBranchPreset(checkout));
72231
+ if (resolved.status === "invalid")
72232
+ return { error: resolved.error };
72233
+ return {
72234
+ error: null,
72235
+ workspace: workspace?.name ?? null,
72236
+ branchSource: resolved.provenance.branchPolicy,
72237
+ commitSource: resolved.provenance.commitPolicy,
72238
+ target: resolved.branchPolicy.defaultTargetBranch,
72239
+ branchPreset: resolved.branchPolicy.preset,
72240
+ commitPreset: resolved.commitPolicy.preset
72241
+ };
72242
+ } catch (error) {
72243
+ return { error: error instanceof Error ? error.message : String(error) };
72350
72244
  }
72351
- case "globalCommitPattern":
72352
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72353
- flexDirection: "column",
72354
- gap: 1,
72245
+ })();
72246
+ const canApply = preview.ok && policyPreview.error === null;
72247
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72248
+ flexDirection: "column",
72249
+ gap: 1,
72250
+ children: [
72251
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72252
+ bold: true,
72253
+ color: "cyan",
72254
+ children: "Review"
72255
+ }, undefined, false, undefined, this),
72256
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72355
72257
  children: [
72356
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72357
- bold: true,
72358
- children: "Advanced global commit policy · Custom pattern"
72359
- }, undefined, false, undefined, this),
72360
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72361
- dimColor: true,
72362
- children: "Regular expression matched against the commit subject line."
72363
- }, undefined, false, undefined, this),
72364
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
72365
- defaultValue: draft.values.commitPolicy.pattern ?? "",
72366
- onChange: (value) => dispatch({ type: "globalCommitPattern", value }),
72367
- onSubmit: () => dispatch({ type: "globalCommitPatternDone" })
72368
- }, undefined, false, undefined, this),
72369
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72370
- dimColor: true,
72371
- children: "Enter to save · Esc Back"
72258
+ "Platforms: ",
72259
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72260
+ color: "green",
72261
+ children: draft.values.platforms.join(", ") || "—"
72372
72262
  }, undefined, false, undefined, this)
72373
- ]
72374
- }, undefined, true, undefined, this);
72375
- case "branchPolicy":
72376
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(BranchPolicyScreen, {
72377
- draft,
72378
- dispatch
72379
- }, undefined, false, undefined, this);
72380
- case "branchPolicyDevelop":
72381
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72382
- flexDirection: "column",
72383
- gap: 1,
72384
- children: [
72385
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72386
- bold: true,
72387
- children: "Step 5 — Branch policy · Develop branch"
72388
- }, undefined, false, undefined, this),
72389
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72390
- dimColor: true,
72391
- children: "Integration/develop branch name (leave empty to unset):"
72392
- }, undefined, false, undefined, this),
72393
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
72394
- placeholder: SCREEN_PLACEHOLDERS.branchPolicyDevelop,
72395
- defaultValue: draft.values.branchPolicy?.developBranch ?? draft.values.branchPolicyDetected?.developBranch ?? "",
72396
- onSubmit: (value) => {
72397
- dispatch({ type: "set", field: "branchPolicyDevelop", value });
72398
- dispatch({ type: "next" });
72399
- }
72400
- }, undefined, false, undefined, this),
72401
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72402
- dimColor: true,
72403
- children: "Enter to save · Esc Back"
72263
+ ]
72264
+ }, undefined, true, undefined, this),
72265
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72266
+ children: [
72267
+ "Locale: ",
72268
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72269
+ color: "green",
72270
+ children: draft.values.locale
72404
72271
  }, undefined, false, undefined, this)
72405
72272
  ]
72406
- }, undefined, true, undefined, this);
72407
- case "project": {
72408
- const target = projectTargetFor(resolveBasePath(draft.values));
72409
- if (!target.ok) {
72410
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72411
- flexDirection: "column",
72412
- gap: 1,
72413
- children: [
72414
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72415
- bold: true,
72416
- children: "Step 6 — Project setup"
72417
- }, undefined, false, undefined, this),
72418
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72419
- color: "yellow",
72420
- children: [
72421
- "Skipped: ",
72422
- target.refused
72423
- ]
72424
- }, undefined, true, undefined, this),
72425
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(ConfirmInput, {
72426
- defaultChoice: "confirm",
72427
- submitOnEnter: false,
72428
- onConfirm: () => {
72429
- dispatch({ type: "set", field: "applyProject", value: true });
72430
- dispatch({ type: "next" });
72431
- },
72432
- onCancel: () => {
72433
- dispatch({ type: "set", field: "applyProject", value: false });
72434
- dispatch({ type: "next" });
72435
- }
72436
- }, undefined, false, undefined, this),
72437
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72438
- dimColor: true,
72439
- children: "y to keep this note in the summary · n to skip it · either adds no project files · b Back · Esc Cancel"
72440
- }, undefined, false, undefined, this)
72441
- ]
72442
- }, undefined, true, undefined, this);
72443
- }
72444
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72445
- flexDirection: "column",
72446
- gap: 1,
72273
+ }, undefined, true, undefined, this),
72274
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72447
72275
  children: [
72448
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72449
- bold: true,
72450
- children: "Step 6 — Project setup"
72451
- }, undefined, false, undefined, this),
72452
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72453
- dimColor: true,
72454
- children: [
72455
- "Apply gitignore + hygiene in ",
72456
- target.root,
72457
- "? (Existing files are never overwritten.)"
72458
- ]
72459
- }, undefined, true, undefined, this),
72460
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(ConfirmInput, {
72461
- defaultChoice: "cancel",
72462
- submitOnEnter: false,
72463
- onConfirm: () => {
72464
- dispatch({ type: "set", field: "applyProject", value: true });
72465
- dispatch({ type: "next" });
72466
- },
72467
- onCancel: () => {
72468
- dispatch({ type: "set", field: "applyProject", value: false });
72469
- dispatch({ type: "next" });
72470
- }
72276
+ "Branch policy: ",
72277
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72278
+ color: "green",
72279
+ children: policy.preset
72471
72280
  }, undefined, false, undefined, this),
72472
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72473
- dimColor: true,
72474
- children: "y to add project files · n to skip · b Back · Esc Cancel"
72475
- }, undefined, false, undefined, this)
72281
+ " — allowed:",
72282
+ " ",
72283
+ policy.allowed.join(", "),
72284
+ " · protected: ",
72285
+ policy.protected.join(", ")
72476
72286
  ]
72477
- }, undefined, true, undefined, this);
72478
- }
72479
- case "summary": {
72480
- const policy = effectivePolicy(draft.values);
72481
- const preview = buildSetupPreview(draft.values, { cwd: resolveBasePath(draft.values) });
72482
- const policyPreview = (() => {
72483
- try {
72484
- const current = readConfig();
72485
- const config = {
72486
- ...current,
72487
- branchPolicy: mergePreset(draft.values.branchPreset, {
72488
- allowed: parseList(draft.values.branchAllowed),
72489
- protectedNames: parseList(draft.values.branchProtected)
72490
- }, current),
72491
- commitPolicy: draft.values.commitPolicy
72492
- };
72493
- const checkout = resolveBasePath(draft.values);
72494
- const workspace = resolveWorkspaceFromEntries(checkout, draft.values.workspaces);
72495
- const resolved = resolveWorkspacePolicy(config, workspace, undefined, () => repoBranchPreset(checkout));
72496
- if (resolved.status === "invalid")
72497
- return { error: resolved.error };
72498
- return {
72499
- error: null,
72500
- workspace: workspace?.name ?? null,
72501
- branchSource: resolved.provenance.branchPolicy,
72502
- commitSource: resolved.provenance.commitPolicy,
72503
- target: resolved.branchPolicy.defaultTargetBranch,
72504
- branchPreset: resolved.branchPolicy.preset,
72505
- commitPreset: resolved.commitPolicy.preset
72506
- };
72507
- } catch (error) {
72508
- return { error: error instanceof Error ? error.message : String(error) };
72509
- }
72510
- })();
72511
- const canApply = preview.ok && policyPreview.error === null;
72512
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72287
+ }, undefined, true, undefined, this),
72288
+ policyPreview.error === null ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72513
72289
  flexDirection: "column",
72514
- gap: 1,
72290
+ gap: 0,
72515
72291
  children: [
72516
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72517
- bold: true,
72518
- color: "cyan",
72519
- children: "Review"
72520
- }, undefined, false, undefined, this),
72521
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72522
- children: [
72523
- "Platforms: ",
72524
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72525
- color: "green",
72526
- children: draft.values.platforms.join(", ") || "—"
72527
- }, undefined, false, undefined, this)
72528
- ]
72529
- }, undefined, true, undefined, this),
72530
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72531
- children: [
72532
- "Locale: ",
72533
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72534
- color: "green",
72535
- children: draft.values.locale
72536
- }, undefined, false, undefined, this)
72537
- ]
72538
- }, undefined, true, undefined, this),
72539
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72292
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72540
72293
  children: [
72541
- "Branch policy: ",
72542
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72294
+ "Sample checkout: ",
72295
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72543
72296
  color: "green",
72544
- children: policy.preset
72297
+ children: resolveBasePath(draft.values)
72545
72298
  }, undefined, false, undefined, this),
72546
- " — allowed:",
72547
- " ",
72548
- policy.allowed.join(", "),
72549
- " · protected: ",
72550
- policy.protected.join(", ")
72551
- ]
72552
- }, undefined, true, undefined, this),
72553
- policyPreview.error === null ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72554
- flexDirection: "column",
72555
- gap: 0,
72556
- children: [
72557
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72558
- children: [
72559
- "Sample checkout: ",
72560
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72561
- color: "green",
72562
- children: resolveBasePath(draft.values)
72563
- }, undefined, false, undefined, this),
72564
- policyPreview.workspace ? ` · workspace ${policyPreview.workspace}` : " · no matching workspace"
72565
- ]
72566
- }, undefined, true, undefined, this),
72567
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72568
- children: [
72569
- "Effective branch policy: ",
72570
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72571
- color: "green",
72572
- children: policyPreview.branchPreset
72573
- }, undefined, false, undefined, this),
72574
- " · target ",
72575
- policyPreview.target,
72576
- " · source ",
72577
- policyPreview.branchSource
72578
- ]
72579
- }, undefined, true, undefined, this),
72580
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72581
- children: [
72582
- "Effective commit policy: ",
72583
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72584
- color: "green",
72585
- children: policyPreview.commitPreset
72586
- }, undefined, false, undefined, this),
72587
- " · source ",
72588
- policyPreview.commitSource
72589
- ]
72590
- }, undefined, true, undefined, this)
72591
- ]
72592
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72593
- color: "red",
72594
- children: [
72595
- "Policy preview failed: ",
72596
- policyPreview.error
72597
- ]
72598
- }, undefined, true, undefined, this),
72599
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72600
- children: [
72601
- "YouTrack base URL:",
72602
- " ",
72603
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72604
- color: "green",
72605
- children: draft.values.issueTracker === "youtrack" ? draft.values.baseUrl.trim() ? draft.values.baseUrl : "— (skip)" : "—"
72606
- }, undefined, false, undefined, this)
72299
+ policyPreview.workspace ? ` · workspace ${policyPreview.workspace}` : " · no matching workspace"
72607
72300
  ]
72608
72301
  }, undefined, true, undefined, this),
72609
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72302
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72610
72303
  children: [
72611
- "VCS provider: ",
72612
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72304
+ "Effective branch policy: ",
72305
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72613
72306
  color: "green",
72614
- children: draft.values.vcsProvider
72615
- }, undefined, false, undefined, this)
72307
+ children: policyPreview.branchPreset
72308
+ }, undefined, false, undefined, this),
72309
+ " · target ",
72310
+ policyPreview.target,
72311
+ " · source ",
72312
+ policyPreview.branchSource
72616
72313
  ]
72617
72314
  }, undefined, true, undefined, this),
72618
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72315
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72619
72316
  children: [
72620
- "Project hygiene:",
72621
- " ",
72622
- preview.projectRefused ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72623
- color: "yellow",
72624
- children: [
72625
- "skipped — ",
72626
- preview.projectRefused
72627
- ]
72628
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72317
+ "Effective commit policy: ",
72318
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72629
72319
  color: "green",
72630
- children: draft.values.applyProject ? "yes" : "no"
72631
- }, undefined, false, undefined, this)
72320
+ children: policyPreview.commitPreset
72321
+ }, undefined, false, undefined, this),
72322
+ " · source ",
72323
+ policyPreview.commitSource
72632
72324
  ]
72633
- }, undefined, true, undefined, this),
72634
- preview.overrides.length > 0 && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72635
- flexDirection: "column",
72636
- gap: 0,
72325
+ }, undefined, true, undefined, this)
72326
+ ]
72327
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72328
+ color: "red",
72329
+ children: [
72330
+ "Policy preview failed: ",
72331
+ policyPreview.error
72332
+ ]
72333
+ }, undefined, true, undefined, this),
72334
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72335
+ children: [
72336
+ "YouTrack base URL:",
72337
+ " ",
72338
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72339
+ color: "green",
72340
+ children: draft.values.issueTracker === "youtrack" ? draft.values.baseUrl.trim() ? draft.values.baseUrl : "— (skip)" : "—"
72341
+ }, undefined, false, undefined, this)
72342
+ ]
72343
+ }, undefined, true, undefined, this),
72344
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72345
+ children: [
72346
+ "VCS provider: ",
72347
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72348
+ color: "green",
72349
+ children: draft.values.vcsProvider
72350
+ }, undefined, false, undefined, this)
72351
+ ]
72352
+ }, undefined, true, undefined, this),
72353
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72354
+ children: [
72355
+ "Project hygiene:",
72356
+ " ",
72357
+ preview.projectRefused ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72358
+ color: "yellow",
72637
72359
  children: [
72638
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72639
- bold: true,
72640
- children: "Environment overrides (not applied by the wizard):"
72641
- }, undefined, false, undefined, this),
72642
- preview.overrides.map((o) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72643
- color: "yellow",
72644
- children: [
72645
- o.envKey,
72646
- " → ",
72647
- o.affects,
72648
- ": ",
72649
- o.value
72650
- ]
72651
- }, o.envKey, true, undefined, this))
72360
+ "skipped — ",
72361
+ preview.projectRefused
72652
72362
  ]
72653
- }, undefined, true, undefined, this),
72654
- canApply ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72655
- flexDirection: "column",
72656
- gap: 0,
72363
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72364
+ color: "green",
72365
+ children: draft.values.applyProject ? "yes" : "no"
72366
+ }, undefined, false, undefined, this)
72367
+ ]
72368
+ }, undefined, true, undefined, this),
72369
+ preview.overrides.length > 0 && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72370
+ flexDirection: "column",
72371
+ gap: 0,
72372
+ children: [
72373
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72374
+ bold: true,
72375
+ children: "Environment overrides (not applied by the wizard):"
72376
+ }, undefined, false, undefined, this),
72377
+ preview.overrides.map((o) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72378
+ color: "yellow",
72657
72379
  children: [
72658
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72659
- bold: true,
72660
- children: "Will apply:"
72661
- }, undefined, false, undefined, this),
72662
- preview.mutations.map((m, index) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72663
- children: describeMutation(m)
72664
- }, `${m.type}:${index}`, false, undefined, this)),
72665
- preview.preserved.map((p) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72666
- color: "green",
72667
- children: [
72668
- "preserve ",
72669
- p,
72670
- " (existing token)"
72671
- ]
72672
- }, p, true, undefined, this))
72380
+ o.envKey,
72381
+ " → ",
72382
+ o.affects,
72383
+ ": ",
72384
+ o.value
72673
72385
  ]
72674
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72675
- flexDirection: "column",
72676
- gap: 0,
72386
+ }, o.envKey, true, undefined, this))
72387
+ ]
72388
+ }, undefined, true, undefined, this),
72389
+ canApply ? /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72390
+ flexDirection: "column",
72391
+ gap: 0,
72392
+ children: [
72393
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72394
+ bold: true,
72395
+ children: "Will apply:"
72396
+ }, undefined, false, undefined, this),
72397
+ mutationRows(preview.mutations).map((row) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72398
+ children: row.text
72399
+ }, row.key, false, undefined, this)),
72400
+ preview.preserved.map((p) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72401
+ color: "green",
72677
72402
  children: [
72678
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72679
- bold: true,
72680
- color: "red",
72681
- children: "Apply blocked — malformed configuration:"
72682
- }, undefined, false, undefined, this),
72683
- preview.blocked.map((b) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72684
- color: "red",
72685
- children: b
72686
- }, b, false, undefined, this)),
72687
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72688
- dimColor: true,
72689
- children: "Fix or remove the blocked file above, then return here. Esc Cancel."
72690
- }, undefined, false, undefined, this)
72403
+ "preserve ",
72404
+ p,
72405
+ " (existing token)"
72691
72406
  ]
72692
- }, undefined, true, undefined, this),
72693
- canApply && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(ConfirmInput, {
72694
- defaultChoice: "confirm",
72695
- submitOnEnter: false,
72696
- onConfirm: () => dispatch({ type: "apply" }),
72697
- onCancel: () => {}
72407
+ }, p, true, undefined, this))
72408
+ ]
72409
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72410
+ flexDirection: "column",
72411
+ gap: 0,
72412
+ children: [
72413
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72414
+ bold: true,
72415
+ color: "red",
72416
+ children: "Apply blocked — malformed configuration:"
72698
72417
  }, undefined, false, undefined, this),
72699
- /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72418
+ preview.blocked.map((b) => /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72419
+ color: "red",
72420
+ children: b
72421
+ }, b, false, undefined, this)),
72422
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72700
72423
  dimColor: true,
72701
- children: canApply ? "y to apply · b Back · Esc Cancel" : "b Back · Esc Cancel"
72424
+ children: "Fix or remove the blocked file above, then return here. Esc Cancel."
72702
72425
  }, undefined, false, undefined, this)
72703
72426
  ]
72704
- }, undefined, true, undefined, this);
72705
- }
72706
- case "exit":
72707
- return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
72708
- flexDirection: "column",
72709
- gap: 1,
72710
- children: /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
72711
- dimColor: true,
72712
- children: "Exiting…"
72713
- }, undefined, false, undefined, this)
72714
- }, undefined, false, undefined, this);
72715
- }
72427
+ }, undefined, true, undefined, this),
72428
+ canApply && /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(ConfirmInput, {
72429
+ defaultChoice: "confirm",
72430
+ submitOnEnter: false,
72431
+ onConfirm: () => dispatch({ type: "apply" }),
72432
+ onCancel: () => {}
72433
+ }, undefined, false, undefined, this),
72434
+ /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72435
+ dimColor: true,
72436
+ children: canApply ? "y to apply · b Back · Esc Cancel" : "b Back · Esc Cancel"
72437
+ }, undefined, false, undefined, this)
72438
+ ]
72439
+ }, undefined, true, undefined, this);
72440
+ }
72441
+ function ExitScreen() {
72442
+ return /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Box_default, {
72443
+ flexDirection: "column",
72444
+ gap: 1,
72445
+ children: /* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
72446
+ dimColor: true,
72447
+ children: "Exiting…"
72448
+ }, undefined, false, undefined, this)
72449
+ }, undefined, false, undefined, this);
72716
72450
  }
72717
- var import_react66, jsx_dev_runtime2, lastProjectTarget = null, projectTargetFor = (base) => {
72451
+ var import_react68, jsx_dev_runtime6, lastProjectTarget = null, projectTargetFor = (base) => {
72718
72452
  if (lastProjectTarget?.base !== base)
72719
72453
  lastProjectTarget = { base, target: projectTarget(base) };
72720
72454
  return lastProjectTarget.target;
72721
- }, PLATFORM_LABELS, BRANCH_PRESETS, BRANCH_PRESET_DESCRIPTIONS, SCREEN_PLACEHOLDERS, VCS_PROVIDERS, LOCALE_PICKER_OPTIONS, ISSUE_TRACKERS, WORKSPACE_ADVANCED_FIELDS, PROFILE_FIELDS, TRACK_FIELDS, enumFieldOptions = (field) => {
72722
- if (field === "commitPolicy.preset")
72723
- return [{ label: "Inherit global", value: "inherit" }, ...commitPresetOptions];
72724
- if (field === "branchPolicy.preset")
72725
- return [
72726
- { label: "Inherit global", value: "inherit" },
72727
- { label: "GitFlow", value: "gitflow" },
72728
- { label: "GitHub Flow", value: "github-flow" },
72729
- { label: "Trunk-based", value: "trunk-based" },
72730
- { label: "Custom", value: "custom" }
72731
- ];
72732
- if (field === "strategy")
72733
- return [
72734
- { label: "GitFlow", value: "gitflow" },
72735
- { label: "GitHub Flow", value: "github-flow" },
72736
- { label: "Trunk-based", value: "trunk-based" },
72737
- { label: "Custom", value: "custom" }
72738
- ];
72739
- if (field.endsWith(".integration"))
72740
- return [
72741
- { label: "Pull requests", value: "pr" },
72742
- { label: "Merge commits", value: "merge" }
72743
- ];
72744
- if (field === "versionSource.kind")
72745
- return [
72746
- { label: "Package.json", value: "package-json" },
72747
- { label: "Git tag", value: "git-tag" },
72748
- { label: "Manual", value: "manual" }
72749
- ];
72750
- if (field === "youtrack.link_issues" || field === "issues.link_on_pr")
72751
- return [
72752
- { label: "Inherit global behavior", value: "inherit" },
72753
- { label: "Enabled", value: "true" },
72754
- { label: "Disabled", value: "false" }
72755
- ];
72756
- return null;
72757
- }, commitPresetOptions, TEXT_SCREENS, SEARCH_SCREENS, BRANCH_POLICY_ACTIONS, INTEGRATION_OPTIONS;
72758
- var init_steps = __esm(async () => {
72455
+ }, BRANCH_POLICY_ACTIONS, INTEGRATION_OPTIONS;
72456
+ var init_finish_screens = __esm(async () => {
72759
72457
  init_config();
72760
- init_logic();
72761
72458
  init_workspaces();
72762
72459
  init_branch_policy();
72763
72460
  init_hygiene();
72461
+ init_logic();
72764
72462
  init_wizard_state();
72765
- init_detect_hosts();
72766
72463
  await __promiseAll([
72767
72464
  init_build2(),
72768
72465
  init_build3(),
72769
- init_search_select()
72466
+ init_select_list(),
72467
+ init_options()
72770
72468
  ]);
72771
- import_react66 = __toESM(require_react(), 1);
72772
- jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
72773
- PLATFORM_LABELS = [
72774
- { label: "OpenCode", value: "opencode" },
72775
- { label: "Cursor", value: "cursor" },
72776
- { label: "Codex", value: "codex" },
72777
- { label: "Pi", value: "pi" },
72778
- { label: "Claude Code", value: "claude-code" }
72779
- ];
72780
- BRANCH_PRESETS = [
72781
- { label: "GitFlow", value: "gitflow" },
72782
- { label: "GitHub Flow", value: "github-flow" },
72783
- { label: "Trunk-based", value: "trunk-based" },
72784
- { label: "Custom", value: "custom" }
72785
- ];
72786
- BRANCH_PRESET_DESCRIPTIONS = {
72787
- gitflow: `${PRESETS.gitflow.allowed.join(", ")} allowed · ` + `${PRESETS.gitflow.protected.join(", ")} protected · work merges into develop via PRs or merge commits`,
72788
- "github-flow": `Anything goes (${PRESETS["github-flow"].allowed[0]}) · only ${PRESETS["github-flow"].protected.join(", ")} is protected · branches off main, back to main`,
72789
- "trunk-based": `Short-lived branches off trunk · ${PRESETS["trunk-based"].protected.join(", ")} is the only protected branch`,
72790
- custom: "Define your own allowed and protected patterns in the next prompts"
72791
- };
72792
- SCREEN_PLACEHOLDERS = {
72793
- youtrack: "e.g. https://example.youtrack.cloud",
72794
- localeOther: "e.g. en-US or es-CL",
72795
- branchAllowed: "e.g. feature/*, bugfix/*",
72796
- branchProtected: "e.g. main, develop",
72797
- workspaceName: "e.g. work",
72798
- workspaceGlob: "e.g. /work/**",
72799
- branchPolicyDevelop: "e.g. develop"
72800
- };
72801
- VCS_PROVIDERS = [
72802
- { label: "GitLab", value: "gitlab" },
72803
- { label: "GitHub", value: "github" },
72804
- { label: "Skip — configure later", value: "skip" }
72805
- ];
72806
- LOCALE_PICKER_OPTIONS = [
72807
- ...LOCALE_LANGUAGE_MAP.map((entry) => ({ label: entry.label, value: entry.locale })),
72808
- { label: "Other…", value: "other" }
72809
- ];
72810
- ISSUE_TRACKERS = [
72811
- { label: "YouTrack", value: "youtrack" },
72812
- { label: "GitHub Issues", value: "github" },
72813
- { label: "GitLab Issues", value: "gitlab" },
72814
- { label: "None", value: "none" }
72469
+ import_react68 = __toESM(require_react(), 1);
72470
+ jsx_dev_runtime6 = __toESM(require_jsx_dev_runtime(), 1);
72471
+ BRANCH_POLICY_ACTIONS = [
72472
+ { label: "Accept defaults", value: "accept" },
72473
+ { label: "Edit integration", value: "integration" },
72474
+ { label: "Edit develop", value: "develop" },
72475
+ { label: "Skip", value: "skip" }
72815
72476
  ];
72816
- WORKSPACE_ADVANCED_FIELDS = [
72817
- { label: "Hosting provider account", value: "vcs.account" },
72818
- { label: "Default target branch", value: "vcs.defaultTargetBranch" },
72819
- { label: "Workspace YouTrack URL", value: "youtrack.baseUrl" },
72820
- { label: "Link issues in YouTrack", value: "youtrack.link_issues" },
72821
- { label: "Link GitHub issues on pull requests", value: "issues.link_on_pr" },
72822
- { label: "Branch preset", value: "branchPolicy.preset" },
72823
- { label: "Allowed branch patterns", value: "branchPolicy.allowed" },
72824
- { label: "Protected branches", value: "branchPolicy.protected" },
72825
- { label: "Develop branch", value: "branchPolicy.developBranch" },
72826
- { label: "Integration method (pr or merge)", value: "branchPolicy.integration" },
72827
- { label: "Feature prefix", value: "branchPolicy.prefixes.feature" },
72828
- { label: "Bugfix prefix", value: "branchPolicy.prefixes.bugfix" },
72829
- { label: "Release prefix", value: "branchPolicy.prefixes.release" },
72830
- { label: "Hotfix prefix", value: "branchPolicy.prefixes.hotfix" },
72831
- { label: "Commit policy preset", value: "commitPolicy.preset" },
72832
- { label: "Custom commit pattern", value: "commitPolicy.pattern" },
72833
- { label: "Default profile name", value: "defaultProfile" }
72477
+ INTEGRATION_OPTIONS = [
72478
+ { label: "Pull request (pr)", value: "pr" },
72479
+ { label: "Merge commit", value: "merge" }
72834
72480
  ];
72835
- PROFILE_FIELDS = [
72836
- { label: "Branch preset", value: "branchPolicy.preset" },
72837
- { label: "Allowed patterns", value: "branchPolicy.allowed" },
72838
- { label: "Protected branches", value: "branchPolicy.protected" },
72839
- { label: "Develop branch", value: "branchPolicy.developBranch" },
72840
- { label: "Integration (pr or merge)", value: "branchPolicy.integration" },
72841
- { label: "Feature prefix", value: "branchPolicy.prefixes.feature" },
72842
- { label: "Bugfix prefix", value: "branchPolicy.prefixes.bugfix" },
72843
- { label: "Release prefix", value: "branchPolicy.prefixes.release" },
72844
- { label: "Hotfix prefix", value: "branchPolicy.prefixes.hotfix" },
72845
- { label: "Commit preset", value: "commitPolicy.preset" },
72846
- { label: "Commit pattern", value: "commitPolicy.pattern" }
72481
+ });
72482
+
72483
+ // packages/workit-cli/src/steps/workspace-editor.tsx
72484
+ function WorkspaceCollectionEditor({
72485
+ draft,
72486
+ dispatch
72487
+ }) {
72488
+ const [view, setView] = import_react69.useState({ mode: "main" });
72489
+ const workspace = draft.workspaceDraft;
72490
+ if (!workspace)
72491
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72492
+ color: "red",
72493
+ children: "Workspace draft is unavailable."
72494
+ }, undefined, false, undefined, this);
72495
+ switch (view.mode) {
72496
+ case "main":
72497
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(MainMenu, {
72498
+ workspace,
72499
+ dispatch,
72500
+ setView
72501
+ }, undefined, false, undefined, this);
72502
+ case "menu":
72503
+ return view.kind === "profile" ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(ProfilesMenu, {
72504
+ workspace,
72505
+ dispatch,
72506
+ setView
72507
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TracksMenu, {
72508
+ workspace,
72509
+ dispatch,
72510
+ setView
72511
+ }, undefined, false, undefined, this);
72512
+ case "name":
72513
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(NameInput, {
72514
+ collection: COLLECTIONS[view.kind],
72515
+ workspace,
72516
+ onCreate: (name) => {
72517
+ dispatch(COLLECTIONS[view.kind].create(name));
72518
+ setView({ mode: "edit", kind: view.kind, name });
72519
+ }
72520
+ }, undefined, false, undefined, this);
72521
+ case "edit":
72522
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(EntryFields, {
72523
+ collection: COLLECTIONS[view.kind],
72524
+ workspace,
72525
+ name: view.name,
72526
+ onDone: () => setView({ mode: "menu", kind: view.kind }),
72527
+ onPick: (field) => setView({ ...view, mode: "value", field })
72528
+ }, undefined, false, undefined, this);
72529
+ case "value":
72530
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(EntryFieldValue, {
72531
+ collection: COLLECTIONS[view.kind],
72532
+ workspace,
72533
+ name: view.name,
72534
+ field: view.field,
72535
+ onSave: (value) => {
72536
+ dispatch(COLLECTIONS[view.kind].set(view.name, view.field, value));
72537
+ setView({ mode: "edit", kind: view.kind, name: view.name });
72538
+ }
72539
+ }, undefined, false, undefined, this);
72540
+ }
72541
+ }
72542
+ function MainMenu({ workspace, dispatch, setView }) {
72543
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
72544
+ flexDirection: "column",
72545
+ gap: 1,
72546
+ children: [
72547
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72548
+ bold: true,
72549
+ children: [
72550
+ "Advanced workspace settings · ",
72551
+ workspace.name
72552
+ ]
72553
+ }, undefined, true, undefined, this),
72554
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72555
+ dimColor: true,
72556
+ children: "Choose a setting to edit. Lists use comma-separated values; blank clears an override."
72557
+ }, undefined, false, undefined, this),
72558
+ [...WORKSPACE_ADVANCED_FIELDS].map(({ label, value }) => /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72559
+ dimColor: true,
72560
+ children: [
72561
+ label,
72562
+ ": ",
72563
+ workspaceEditorValue(workspace, value) || "inherited / unset"
72564
+ ]
72565
+ }, value, true, undefined, this)),
72566
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
72567
+ options: MAIN_OPTIONS,
72568
+ value: "save",
72569
+ onSelect: (value) => {
72570
+ if (value === "save")
72571
+ dispatch({ type: "workspaceSave" });
72572
+ else if (value === "profiles")
72573
+ setView({ mode: "menu", kind: "profile" });
72574
+ else if (value === "tracks")
72575
+ setView({ mode: "menu", kind: "track" });
72576
+ else
72577
+ dispatch({ type: "workspaceAdvancedSelect", field: value });
72578
+ }
72579
+ }, undefined, false, undefined, this)
72580
+ ]
72581
+ }, undefined, true, undefined, this);
72582
+ }
72583
+ function ProfilesMenu({ workspace, dispatch, setView }) {
72584
+ const options = [
72585
+ ...Object.keys(workspace.profiles ?? {}).flatMap((profile) => [
72586
+ { label: `Edit profile ${profile}`, value: `edit:${profile}` },
72587
+ { label: `Set ${profile} as default`, value: `default:${profile}` },
72588
+ { label: `Delete profile ${profile}`, value: `delete:${profile}` }
72589
+ ]),
72590
+ { label: "Create profile", value: "create" },
72591
+ { label: "Back to advanced settings", value: "back" }
72847
72592
  ];
72848
- TRACK_FIELDS = [
72849
- { label: "Strategy", value: "strategy" },
72850
- { label: "Production branch", value: "productionBranch" },
72851
- { label: "Integration branch", value: "integrationBranch" },
72852
- { label: "Feature branch naming", value: "naming.feature" },
72853
- { label: "Release branch naming", value: "naming.release" },
72854
- { label: "Hotfix branch naming", value: "naming.hotfix" },
72855
- { label: "Base branch", value: "baseBranch" },
72856
- { label: "Merge-back branches", value: "mergeBackBranches" },
72857
- { label: "Pull request target", value: "pullRequestTarget" },
72858
- { label: "Tag namespace", value: "tagNamespace" },
72859
- { label: "Version source (manual, git-tag, package-json)", value: "versionSource.kind" },
72860
- { label: "Package.json path", value: "versionSource.path" },
72861
- { label: "Package version field", value: "versionSource.field" },
72862
- { label: "Required checks", value: "requiredChecks" }
72593
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
72594
+ flexDirection: "column",
72595
+ gap: 1,
72596
+ children: [
72597
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72598
+ bold: true,
72599
+ children: [
72600
+ "Profiles · default: ",
72601
+ workspace.defaultProfile ?? "none"
72602
+ ]
72603
+ }, undefined, true, undefined, this),
72604
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72605
+ dimColor: true,
72606
+ children: "Profiles can override branch rules and commit conventions."
72607
+ }, undefined, false, undefined, this),
72608
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
72609
+ options,
72610
+ value: "back",
72611
+ onSelect: (value) => {
72612
+ const name = value.slice(value.indexOf(":") + 1);
72613
+ if (value === "create")
72614
+ setView({ mode: "name", kind: "profile" });
72615
+ else if (value.startsWith("edit:"))
72616
+ setView({ mode: "edit", kind: "profile", name });
72617
+ else if (value.startsWith("default:"))
72618
+ dispatch({ type: "workspaceProfileDefault", name });
72619
+ else if (value.startsWith("delete:"))
72620
+ dispatch({ type: "workspaceProfileDelete", name });
72621
+ else
72622
+ setView({ mode: "main" });
72623
+ }
72624
+ }, undefined, false, undefined, this)
72625
+ ]
72626
+ }, undefined, true, undefined, this);
72627
+ }
72628
+ function TracksMenu({ workspace, dispatch, setView }) {
72629
+ const options = [
72630
+ ...Object.keys(workspace.releaseTracks ?? {}).flatMap((track) => [
72631
+ { label: `Edit release track ${track}`, value: `edit:${track}` },
72632
+ { label: `Delete release track ${track}`, value: `delete:${track}` }
72633
+ ]),
72634
+ { label: "Create release track", value: "create" },
72635
+ { label: "Back to advanced settings", value: "back" }
72863
72636
  ];
72864
- commitPresetOptions = [
72865
- { label: "Conventional commits", value: "conventional" },
72866
- { label: "Gitmoji", value: "gitmoji" },
72867
- { label: "Ticket prefix", value: "ticket-prefix" },
72868
- { label: "Freeform", value: "freeform" },
72869
- { label: "Custom pattern", value: "custom" },
72870
- { label: "Auto-detect", value: "auto" }
72637
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
72638
+ flexDirection: "column",
72639
+ gap: 1,
72640
+ children: [
72641
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72642
+ bold: true,
72643
+ children: "Named release tracks"
72644
+ }, undefined, false, undefined, this),
72645
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72646
+ dimColor: true,
72647
+ children: "Each track has its own branches, naming, version source, and checks."
72648
+ }, undefined, false, undefined, this),
72649
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
72650
+ options,
72651
+ value: "back",
72652
+ onSelect: (value) => {
72653
+ const name = value.slice(value.indexOf(":") + 1);
72654
+ if (value === "create")
72655
+ setView({ mode: "name", kind: "track" });
72656
+ else if (value.startsWith("edit:"))
72657
+ setView({ mode: "edit", kind: "track", name });
72658
+ else if (value.startsWith("delete:"))
72659
+ dispatch({ type: "workspaceTrackDelete", name });
72660
+ else
72661
+ setView({ mode: "main" });
72662
+ }
72663
+ }, undefined, false, undefined, this)
72664
+ ]
72665
+ }, undefined, true, undefined, this);
72666
+ }
72667
+ function NameInput({
72668
+ collection,
72669
+ workspace,
72670
+ onCreate
72671
+ }) {
72672
+ const [error, setError] = import_react69.useState("");
72673
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
72674
+ flexDirection: "column",
72675
+ gap: 1,
72676
+ children: [
72677
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72678
+ bold: true,
72679
+ children: collection.createTitle
72680
+ }, undefined, false, undefined, this),
72681
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72682
+ dimColor: true,
72683
+ children: collection.nameLabel
72684
+ }, undefined, false, undefined, this),
72685
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TextInput, {
72686
+ onSubmit: (value) => {
72687
+ const next = value.trim();
72688
+ if (!next)
72689
+ setError(collection.emptyError);
72690
+ else if (collection.exists(workspace, next))
72691
+ setError(collection.duplicateError(next));
72692
+ else
72693
+ onCreate(next);
72694
+ }
72695
+ }, undefined, false, undefined, this),
72696
+ error && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72697
+ color: "red",
72698
+ children: error
72699
+ }, undefined, false, undefined, this),
72700
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72701
+ dimColor: true,
72702
+ children: "Enter to create · Esc Back"
72703
+ }, undefined, false, undefined, this)
72704
+ ]
72705
+ }, undefined, true, undefined, this);
72706
+ }
72707
+ function EntryFields({
72708
+ collection,
72709
+ workspace,
72710
+ name,
72711
+ onDone,
72712
+ onPick
72713
+ }) {
72714
+ const options = [...collection.fields, { label: "Done editing", value: "done" }];
72715
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
72716
+ flexDirection: "column",
72717
+ gap: 1,
72718
+ children: [
72719
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72720
+ bold: true,
72721
+ children: [
72722
+ collection.editTitle,
72723
+ " · ",
72724
+ name
72725
+ ]
72726
+ }, undefined, true, undefined, this),
72727
+ collection.fields.map((item) => {
72728
+ const value = collection.valueOf(workspace, name, item.value);
72729
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72730
+ dimColor: true,
72731
+ children: [
72732
+ item.label,
72733
+ ": ",
72734
+ value === undefined ? "" : value || "unset"
72735
+ ]
72736
+ }, item.value, true, undefined, this);
72737
+ }),
72738
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
72739
+ options,
72740
+ value: "done",
72741
+ onSelect: (value) => value === "done" ? onDone() : onPick(value)
72742
+ }, undefined, false, undefined, this)
72743
+ ]
72744
+ }, undefined, true, undefined, this);
72745
+ }
72746
+ function EntryFieldValue({
72747
+ collection,
72748
+ workspace,
72749
+ name,
72750
+ field,
72751
+ onSave
72752
+ }) {
72753
+ const item = collection.fields.find((entry) => entry.value === field);
72754
+ const choices = enumFieldOptions(field);
72755
+ const current = collection.valueOf(workspace, name, field);
72756
+ return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
72757
+ flexDirection: "column",
72758
+ gap: 1,
72759
+ children: [
72760
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72761
+ bold: true,
72762
+ children: [
72763
+ collection.valueTitle,
72764
+ " ",
72765
+ name,
72766
+ " · ",
72767
+ item?.label
72768
+ ]
72769
+ }, undefined, true, undefined, this),
72770
+ choices ? /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(SelectList, {
72771
+ options: choices,
72772
+ value: current ?? choices[0].value,
72773
+ onSelect: onSave
72774
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(TextInput, {
72775
+ defaultValue: current ?? "",
72776
+ onSubmit: onSave
72777
+ }, undefined, false, undefined, this),
72778
+ /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
72779
+ dimColor: true,
72780
+ children: collection.valueFooter
72781
+ }, undefined, false, undefined, this)
72782
+ ]
72783
+ }, undefined, true, undefined, this);
72784
+ }
72785
+ var import_react69, jsx_dev_runtime7, COLLECTIONS, MAIN_OPTIONS;
72786
+ var init_workspace_editor = __esm(async () => {
72787
+ init_logic();
72788
+ await __promiseAll([
72789
+ init_build2(),
72790
+ init_build3(),
72791
+ init_select_list(),
72792
+ init_options()
72793
+ ]);
72794
+ import_react69 = __toESM(require_react(), 1);
72795
+ jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
72796
+ COLLECTIONS = {
72797
+ profile: {
72798
+ fields: PROFILE_FIELDS,
72799
+ exists: (workspace, name) => Boolean(workspace.profiles?.[name]),
72800
+ valueOf: (workspace, name, field) => {
72801
+ const profile = workspace.profiles?.[name];
72802
+ return profile ? profileEditorValue(profile, field) : undefined;
72803
+ },
72804
+ createTitle: "Create profile",
72805
+ nameLabel: "Profile name:",
72806
+ emptyError: "Enter a profile name.",
72807
+ duplicateError: (name) => `Profile ${name} already exists. Choose a different name or edit it from the list.`,
72808
+ editTitle: "Edit profile",
72809
+ valueTitle: "Profile",
72810
+ valueFooter: "Enter to save · Esc Back",
72811
+ create: (name) => ({ type: "workspaceProfileCreate", name }),
72812
+ set: (name, field, value) => ({
72813
+ type: "workspaceProfileSet",
72814
+ name,
72815
+ field,
72816
+ value
72817
+ })
72818
+ },
72819
+ track: {
72820
+ fields: TRACK_FIELDS,
72821
+ exists: (workspace, name) => Boolean(workspace.releaseTracks?.[name]),
72822
+ valueOf: (workspace, name, field) => {
72823
+ const track = workspace.releaseTracks?.[name];
72824
+ return track ? trackEditorValue(track, field) : undefined;
72825
+ },
72826
+ createTitle: "Create release track",
72827
+ nameLabel: "Track name:",
72828
+ emptyError: "Enter a release-track name.",
72829
+ duplicateError: (name) => `Release track ${name} already exists. Choose a different name or edit it from the list.`,
72830
+ editTitle: "Edit release track",
72831
+ valueTitle: "Release track",
72832
+ valueFooter: "Lists use comma-separated values · Enter to save · Esc Back",
72833
+ create: (name) => ({ type: "workspaceTrackCreate", name }),
72834
+ set: (name, field, value) => ({
72835
+ type: "workspaceTrackSet",
72836
+ name,
72837
+ field,
72838
+ value
72839
+ })
72840
+ }
72841
+ };
72842
+ MAIN_OPTIONS = [
72843
+ ...WORKSPACE_ADVANCED_FIELDS,
72844
+ { label: "Manage profiles", value: "profiles" },
72845
+ { label: "Manage release tracks", value: "tracks" },
72846
+ { label: "Save workspace settings", value: "save" }
72871
72847
  ];
72848
+ });
72849
+
72850
+ // packages/workit-cli/src/steps.tsx
72851
+ function Wizard({
72852
+ onExit,
72853
+ detection = emptyDetection()
72854
+ }) {
72855
+ const [draft, dispatch] = import_react70.useReducer(reducer3, detection, (found) => {
72856
+ const initial = createInitialDraft();
72857
+ const platforms = preselectedPlatforms(found);
72858
+ return platforms.length > 0 ? { ...initial, values: { ...initial.values, platforms } } : initial;
72859
+ });
72860
+ const exitedRef = import_react70.useRef(false);
72861
+ const searchRef = import_react70.useRef({ q: "", typed: false });
72862
+ import_react70.useEffect(() => {
72863
+ searchRef.current = { q: "", typed: false };
72864
+ }, [draft.screen]);
72865
+ use_input_default((input, key) => {
72866
+ if (key.ctrl && input.toLowerCase() === "c") {
72867
+ dispatch({ type: "cancel" });
72868
+ } else if (key.escape) {
72869
+ if (TEXT_SCREENS.has(draft.screen))
72870
+ dispatch({ type: "back" });
72871
+ else
72872
+ dispatch({ type: "cancel" });
72873
+ } else if (input.toLowerCase() === "b" && !TEXT_SCREENS.has(draft.screen)) {
72874
+ const search = searchRef.current;
72875
+ const searchOwnsB = SEARCH_SCREENS.has(draft.screen) && !(search.typed && search.q === "");
72876
+ if (!searchOwnsB)
72877
+ dispatch({ type: "back" });
72878
+ }
72879
+ });
72880
+ import_react70.useEffect(() => {
72881
+ if (draft.screen === "exit" && !exitedRef.current) {
72882
+ exitedRef.current = true;
72883
+ onExit(!draft.cancelled, draft.values);
72884
+ }
72885
+ }, [draft.screen, draft.cancelled, draft.values, onExit]);
72886
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
72887
+ flexDirection: "column",
72888
+ gap: 1,
72889
+ children: [
72890
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
72891
+ bold: true,
72892
+ color: "cyan",
72893
+ children: "workit — workflow rails for agentic coding"
72894
+ }, undefined, false, undefined, this),
72895
+ /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Screen, {
72896
+ draft,
72897
+ dispatch,
72898
+ detection,
72899
+ onSearchQueryChange: (query) => {
72900
+ const search = searchRef.current;
72901
+ search.q = query;
72902
+ if (query !== "")
72903
+ search.typed = true;
72904
+ }
72905
+ }, draft.screen, false, undefined, this)
72906
+ ]
72907
+ }, undefined, true, undefined, this);
72908
+ }
72909
+ function Screen(props) {
72910
+ const Body = SCREENS[props.draft.screen];
72911
+ return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Body, {
72912
+ ...props
72913
+ }, undefined, false, undefined, this);
72914
+ }
72915
+ var import_react70, jsx_dev_runtime8, TEXT_SCREENS, SEARCH_SCREENS, SCREENS;
72916
+ var init_steps = __esm(async () => {
72917
+ init_wizard_state();
72918
+ init_detect_hosts();
72919
+ await __promiseAll([
72920
+ init_build2(),
72921
+ init_options(),
72922
+ init_global_screens(),
72923
+ init_workspace_screens(),
72924
+ init_finish_screens(),
72925
+ init_workspace_editor(),
72926
+ init_options(),
72927
+ init_select_list()
72928
+ ]);
72929
+ import_react70 = __toESM(require_react(), 1);
72930
+ jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
72872
72931
  TEXT_SCREENS = new Set([
72873
72932
  "localeOther",
72874
72933
  "branchAllowed",
@@ -72882,16 +72941,31 @@ var init_steps = __esm(async () => {
72882
72941
  "branchPolicyDevelop"
72883
72942
  ]);
72884
72943
  SEARCH_SCREENS = new Set(["locale"]);
72885
- BRANCH_POLICY_ACTIONS = [
72886
- { label: "Accept defaults", value: "accept" },
72887
- { label: "Edit integration", value: "integration" },
72888
- { label: "Edit develop", value: "develop" },
72889
- { label: "Skip", value: "skip" }
72890
- ];
72891
- INTEGRATION_OPTIONS = [
72892
- { label: "Pull request (pr)", value: "pr" },
72893
- { label: "Merge commit", value: "merge" }
72894
- ];
72944
+ SCREENS = {
72945
+ platforms: PlatformsScreen,
72946
+ locale: LocaleScreen,
72947
+ localeOther: LocaleOtherScreen,
72948
+ branchPreset: BranchPresetScreen,
72949
+ branchAllowed: BranchAllowedScreen,
72950
+ branchProtected: BranchProtectedScreen,
72951
+ issueTracker: IssueTrackerScreen,
72952
+ youtrack: YoutrackScreen,
72953
+ vcs: VcsScreen,
72954
+ basePath: BasePathScreen,
72955
+ workspaces: WorkspacesScreen,
72956
+ workspaceName: WorkspaceNameScreen,
72957
+ workspaceGlob: WorkspaceGlobScreen,
72958
+ workspaceProvider: WorkspaceProviderScreen,
72959
+ workspaceAdvanced: WorkspaceCollectionEditor,
72960
+ workspaceAdvancedValue: WorkspaceAdvancedValueScreen,
72961
+ globalCommitPolicy: GlobalCommitPolicyScreen,
72962
+ globalCommitPattern: GlobalCommitPatternScreen,
72963
+ branchPolicy: BranchPolicyScreen,
72964
+ branchPolicyDevelop: BranchPolicyDevelopScreen,
72965
+ project: ProjectScreen,
72966
+ summary: SummaryScreen,
72967
+ exit: ExitScreen
72968
+ };
72895
72969
  });
72896
72970
 
72897
72971
  // packages/workit-cli/src/diagnostics.ts
@@ -72963,7 +73037,7 @@ async function runInit() {
72963
73037
  const exits = [];
72964
73038
  let done = () => {};
72965
73039
  process.stdout.write("\x1B[2J\x1B[H");
72966
- const instance = render_default(/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Wizard, {
73040
+ const instance = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Wizard, {
72967
73041
  detection: detectHosts(),
72968
73042
  onExit: (complete, values) => {
72969
73043
  exits.push({ complete, values });
@@ -73007,22 +73081,22 @@ async function runInit() {
73007
73081
  process.exit(exit !== undefined && exit.complete ? 0 : 1);
73008
73082
  }
73009
73083
  function UninstallWizard({ onExit }) {
73010
- const [hosts, setHosts] = import_react67.useState([]);
73011
- const [plan, setPlan] = import_react67.useState(null);
73084
+ const [hosts, setHosts] = import_react71.useState([]);
73085
+ const [plan, setPlan] = import_react71.useState(null);
73012
73086
  if (!plan) {
73013
- return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
73087
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
73014
73088
  flexDirection: "column",
73015
73089
  gap: 1,
73016
73090
  children: [
73017
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
73091
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
73018
73092
  bold: true,
73019
73093
  children: "Uninstall workit"
73020
73094
  }, undefined, false, undefined, this),
73021
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
73095
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
73022
73096
  dimColor: true,
73023
73097
  children: "Select the hosts to remove workit from (space to toggle):"
73024
73098
  }, undefined, false, undefined, this),
73025
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MultiSelect, {
73099
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(MultiSelect, {
73026
73100
  options: UNINSTALL_HOST_OPTIONS,
73027
73101
  defaultValue: [],
73028
73102
  onChange: (values) => setHosts(values),
@@ -73031,26 +73105,27 @@ function UninstallWizard({ onExit }) {
73031
73105
  setPlan(planUninstall({ env: process.env }));
73032
73106
  }
73033
73107
  }, undefined, false, undefined, this),
73034
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
73108
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
73035
73109
  dimColor: true,
73036
73110
  children: "Enter to continue"
73037
73111
  }, undefined, false, undefined, this)
73038
73112
  ]
73039
73113
  }, undefined, true, undefined, this);
73040
73114
  }
73041
- const selected = plan.hosts.filter((h) => hosts.includes(h.host));
73115
+ const chosen = new Set(hosts);
73116
+ const selected = plan.hosts.filter((h) => chosen.has(h.host));
73042
73117
  const reviewed = { hosts: selected };
73043
- return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
73118
+ return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
73044
73119
  flexDirection: "column",
73045
73120
  gap: 1,
73046
73121
  children: [
73047
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
73122
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
73048
73123
  bold: true,
73049
73124
  children: "Uninstall workit — review"
73050
73125
  }, undefined, false, undefined, this),
73051
- selected.every((h) => h.actions.length === 0) ? /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
73126
+ selected.every((h) => h.actions.length === 0) ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
73052
73127
  children: "No workit registrations found for the selected hosts."
73053
- }, undefined, false, undefined, this) : selected.flatMap((h) => h.actions.map((a) => /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
73128
+ }, undefined, false, undefined, this) : selected.flatMap((h) => h.actions.map((a) => /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
73054
73129
  children: [
73055
73130
  "• [",
73056
73131
  h.host,
@@ -73060,10 +73135,10 @@ function UninstallWizard({ onExit }) {
73060
73135
  a.path
73061
73136
  ]
73062
73137
  }, `${h.host}:${a.path}`, true, undefined, this))),
73063
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
73138
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
73064
73139
  children: "Apply uninstall? (y/N)"
73065
73140
  }, undefined, false, undefined, this),
73066
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(ConfirmInput, {
73141
+ /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(ConfirmInput, {
73067
73142
  onConfirm: () => onExit({ confirmed: true, hosts, plan: reviewed }),
73068
73143
  onCancel: () => onExit({ confirmed: false, hosts, plan: reviewed })
73069
73144
  }, undefined, false, undefined, this)
@@ -73078,7 +73153,7 @@ async function runUninstall() {
73078
73153
  }
73079
73154
  const outcomes = [];
73080
73155
  let done = () => {};
73081
- const instance = render_default(/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(UninstallWizard, {
73156
+ const instance = render_default(/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(UninstallWizard, {
73082
73157
  onExit: (outcome) => {
73083
73158
  outcomes.push(outcome);
73084
73159
  done();
@@ -73107,7 +73182,7 @@ async function runUninstall() {
73107
73182
  console.log(result.ok ? "Uninstall complete." : "Uninstall finished with problems.");
73108
73183
  process.exit(result.ok ? 0 : 1);
73109
73184
  }
73110
- var import_react67, jsx_dev_runtime3, UNINSTALL_HOST_OPTIONS;
73185
+ var import_react71, jsx_dev_runtime9, UNINSTALL_HOST_OPTIONS;
73111
73186
  var init_src2 = __esm(async () => {
73112
73187
  init_wizard_state();
73113
73188
  init_boundary();
@@ -73122,8 +73197,8 @@ var init_src2 = __esm(async () => {
73122
73197
  init_build3(),
73123
73198
  init_steps()
73124
73199
  ]);
73125
- import_react67 = __toESM(require_react(), 1);
73126
- jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
73200
+ import_react71 = __toESM(require_react(), 1);
73201
+ jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
73127
73202
  UNINSTALL_HOST_OPTIONS = [
73128
73203
  { label: "OpenCode", value: "opencode" },
73129
73204
  { label: "Cursor", value: "cursor" },
@@ -73284,8 +73359,8 @@ function applyUpgrade(plan, deps = {}) {
73284
73359
  if (digest2(file) !== expected)
73285
73360
  return { ok: false, error: `configuration changed; preview again: ${file}` };
73286
73361
  const { home, env, configDir } = upgradePaths(deps);
73287
- const active = deps.activeHosts?.() ?? runningHosts(deps);
73288
- if (plan.entries.some((entry) => active.includes(entry.host)))
73362
+ const active = new Set(deps.activeHosts?.() ?? runningHosts(deps));
73363
+ if (plan.entries.some((entry) => active.has(entry.host)))
73289
73364
  return {
73290
73365
  ok: false,
73291
73366
  error: "Stop the selected running hosts before upgrading their loaded plugins"
@@ -75823,8 +75898,12 @@ async function recordInTask(io, storeDir, requested, observation, unblockFor) {
75823
75898
  const requirements = view.data.requirements;
75824
75899
  if (!Array.isArray(requirements))
75825
75900
  return outcome;
75901
+ const byId = new Map;
75902
+ for (const entry of task.data.policy?.requirements ?? [])
75903
+ if (!byId.has(entry.id))
75904
+ byId.set(entry.id, entry);
75826
75905
  for (const item of requirements) {
75827
- const requirement = task.data.policy?.requirements.find((entry) => entry.id === item.requirementId);
75906
+ const requirement = byId.get(item.requirementId);
75828
75907
  if (!requirement)
75829
75908
  continue;
75830
75909
  if (item.status === "satisfied" && item.evidenceIds.includes(recorded.data.id))
@@ -102551,8 +102630,9 @@ async function runMutation(options) {
102551
102630
  if (next)
102552
102631
  runnable.push(next);
102553
102632
  }
102633
+ const scheduled = new Set(runnable);
102554
102634
  for (const mutant of mutants)
102555
- if (!runnable.includes(mutant))
102635
+ if (!scheduled.has(mutant))
102556
102636
  record({ ...mutant, status: "no-tests", durationMs: 0, tests: [] });
102557
102637
  if (runnable.length === 0)
102558
102638
  return finish3(options, 0, results, counts, started);
@@ -102737,7 +102817,8 @@ function parse7(argv) {
102737
102817
  return `${flag} requires a value`;
102738
102818
  if (flag === "--rule") {
102739
102819
  const ids = value.split(",").map((id) => id.trim());
102740
- const unknown = ids.filter((id) => !ruleIds.includes(id));
102820
+ const known = new Set(ruleIds);
102821
+ const unknown = ids.filter((id) => !known.has(id));
102741
102822
  if (unknown.length > 0)
102742
102823
  return `unknown rule ${unknown.join(", ")} (rules: ${ruleIds.join(", ")})`;
102743
102824
  options.rules = new Set(ids);