@brainervirus/workit-cli 0.9.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1046 -392
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -42358,8 +42358,11 @@ var import_react62 = __toESM(require_react(), 1);
|
|
|
42358
42358
|
// node_modules/@inkjs/ui/build/components/email-input/use-email-input.js
|
|
42359
42359
|
var import_react63 = __toESM(require_react(), 1);
|
|
42360
42360
|
var cursor3 = source_default.inverse(" ");
|
|
42361
|
+
// packages/workit-cli/src/index.tsx
|
|
42362
|
+
var import_react67 = __toESM(require_react(), 1);
|
|
42363
|
+
|
|
42361
42364
|
// packages/workit-cli/src/steps.tsx
|
|
42362
|
-
var
|
|
42365
|
+
var import_react66 = __toESM(require_react(), 1);
|
|
42363
42366
|
|
|
42364
42367
|
// packages/workit-core/src/core/config.ts
|
|
42365
42368
|
import {
|
|
@@ -42463,7 +42466,7 @@ var ensureConfigDir = (dir = resolveConfigDir()) => {
|
|
|
42463
42466
|
return dir;
|
|
42464
42467
|
};
|
|
42465
42468
|
var configDir = () => ensureConfigDir();
|
|
42466
|
-
var LOCALE_RE = /^[a-z]{2,3}(-[A-Z]{2})?$/;
|
|
42469
|
+
var LOCALE_RE = /^[a-z]{2,3}(-(?:[A-Z]{2}|[0-9]{3}))?$/;
|
|
42467
42470
|
var DEFAULTS = {
|
|
42468
42471
|
locale: "en",
|
|
42469
42472
|
localeOptions: ["en", "es-CL", "es-MX", "es-AR", "pt-BR"],
|
|
@@ -44849,7 +44852,7 @@ function applyWizardBranchPolicy(branchPolicy, workspace_root, env3 = process.en
|
|
|
44849
44852
|
}
|
|
44850
44853
|
|
|
44851
44854
|
// packages/workit-cli/src/wizard-state.ts
|
|
44852
|
-
import { existsSync as existsSync9 } from "node:fs";
|
|
44855
|
+
import { existsSync as existsSync9, statSync as statSync4 } from "node:fs";
|
|
44853
44856
|
import path11 from "node:path";
|
|
44854
44857
|
import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
|
|
44855
44858
|
var NEXT = {
|
|
@@ -44860,9 +44863,11 @@ var NEXT = {
|
|
|
44860
44863
|
timezoneOther: "branchPreset",
|
|
44861
44864
|
branchPreset: "branchAllowed",
|
|
44862
44865
|
branchAllowed: "branchProtected",
|
|
44863
|
-
branchProtected: "
|
|
44866
|
+
branchProtected: "issueTracker",
|
|
44867
|
+
issueTracker: "youtrack",
|
|
44864
44868
|
youtrack: "vcs",
|
|
44865
|
-
vcs: "
|
|
44869
|
+
vcs: "basePath",
|
|
44870
|
+
basePath: "workspaces",
|
|
44866
44871
|
workspaces: "branchPolicy",
|
|
44867
44872
|
workspaceName: "workspaceGlob",
|
|
44868
44873
|
workspaceGlob: "workspaceProvider",
|
|
@@ -44882,9 +44887,11 @@ var PREV = {
|
|
|
44882
44887
|
branchPreset: "timezone",
|
|
44883
44888
|
branchAllowed: "branchPreset",
|
|
44884
44889
|
branchProtected: "branchAllowed",
|
|
44885
|
-
|
|
44890
|
+
issueTracker: "branchProtected",
|
|
44891
|
+
youtrack: "issueTracker",
|
|
44886
44892
|
vcs: "youtrack",
|
|
44887
|
-
|
|
44893
|
+
basePath: "vcs",
|
|
44894
|
+
workspaces: "basePath",
|
|
44888
44895
|
workspaceName: "workspaces",
|
|
44889
44896
|
workspaceGlob: "workspaceName",
|
|
44890
44897
|
workspaceProvider: "workspaceGlob",
|
|
@@ -44895,16 +44902,34 @@ var PREV = {
|
|
|
44895
44902
|
exit: null
|
|
44896
44903
|
};
|
|
44897
44904
|
var skipsCustomBranch = (screen, preset) => (screen === "branchAllowed" || screen === "branchProtected") && preset !== "custom";
|
|
44898
|
-
var
|
|
44899
|
-
|
|
44905
|
+
var skipsYoutrack = (screen, tracker) => screen === "youtrack" && tracker !== "youtrack";
|
|
44906
|
+
var skipsBasePath = (screen, basePath) => screen === "basePath" && basePath !== "";
|
|
44907
|
+
function resolveBasePath(values2, env3 = process.env) {
|
|
44908
|
+
return env3.WORKFLOW_WORKSPACE_ROOT?.trim() || values2.basePath.trim();
|
|
44909
|
+
}
|
|
44910
|
+
var isDirectory = (p) => {
|
|
44911
|
+
try {
|
|
44912
|
+
return statSync4(p).isDirectory();
|
|
44913
|
+
} catch {
|
|
44914
|
+
return false;
|
|
44915
|
+
}
|
|
44916
|
+
};
|
|
44917
|
+
var basePathMessage = (value) => {
|
|
44918
|
+
const p = value.trim();
|
|
44919
|
+
if (!p)
|
|
44920
|
+
return "workspace root path is required";
|
|
44921
|
+
return !path11.isAbsolute(p) || !isDirectory(p) ? `invalid workspace root "${p}" — enter an existing absolute directory` : null;
|
|
44922
|
+
};
|
|
44923
|
+
var skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync9(path11.join(basePath, ".git"));
|
|
44924
|
+
function nextScreen(screen, preset, tracker, basePath) {
|
|
44900
44925
|
let next = NEXT[screen];
|
|
44901
|
-
while (next && (skipsCustomBranch(next, preset) || skipsBranchPolicy(next)))
|
|
44926
|
+
while (next && (skipsCustomBranch(next, preset) || skipsBranchPolicy(next, basePath) || skipsYoutrack(next, tracker) || skipsBasePath(next, basePath)))
|
|
44902
44927
|
next = NEXT[next];
|
|
44903
44928
|
return next ?? screen;
|
|
44904
44929
|
}
|
|
44905
|
-
function prevScreen(screen, preset) {
|
|
44930
|
+
function prevScreen(screen, preset, tracker, basePath) {
|
|
44906
44931
|
let prev = PREV[screen];
|
|
44907
|
-
while (prev && (skipsCustomBranch(prev, preset) || skipsBranchPolicy(prev)))
|
|
44932
|
+
while (prev && (skipsCustomBranch(prev, preset) || skipsBranchPolicy(prev, basePath) || skipsYoutrack(prev, tracker) || skipsBasePath(prev, basePath)))
|
|
44908
44933
|
prev = PREV[prev];
|
|
44909
44934
|
return prev ?? screen;
|
|
44910
44935
|
}
|
|
@@ -44935,6 +44960,10 @@ function validateScreen(draft) {
|
|
|
44935
44960
|
const error = validateBaseUrl(values2.baseUrl);
|
|
44936
44961
|
return error ? { field: "baseUrl", message: error } : null;
|
|
44937
44962
|
}
|
|
44963
|
+
case "basePath": {
|
|
44964
|
+
const message = basePathMessage(values2.basePath);
|
|
44965
|
+
return message ? { field: "basePath", message } : null;
|
|
44966
|
+
}
|
|
44938
44967
|
case "workspaceName":
|
|
44939
44968
|
return (draft.workspaceDraft?.name ?? "").trim() ? null : { field: "workspaceName", message: "workspace name is required" };
|
|
44940
44969
|
case "workspaceGlob": {
|
|
@@ -44950,8 +44979,9 @@ function validateScreen(draft) {
|
|
|
44950
44979
|
}
|
|
44951
44980
|
var decodeBranchPreset = (value, fallback) => value === "gitflow" || value === "github-flow" || value === "trunk-based" || value === "custom" ? value : fallback;
|
|
44952
44981
|
var decodeVcsProvider = (value, fallback) => value === "gitlab" || value === "github" || value === "skip" ? value : fallback;
|
|
44982
|
+
var decodeIssueTracker = (value, fallback) => value === "youtrack" || value === "github" || value === "none" ? value : fallback;
|
|
44953
44983
|
function setTextValue(draft, field, value) {
|
|
44954
|
-
const message = field === "locale" ? validateLocale(value) : field === "timezone" ? validateTimezone(value) : field === "branchAllowed" ? parseList(value).length > 0 ? null : "at least one allowed branch pattern is required" : field === "branchProtected" ? parseList(value).length > 0 ? null : "at least one protected branch name is required" : value.trim() === "" ? null : validateBaseUrl(value);
|
|
44984
|
+
const message = field === "locale" ? validateLocale(value) : field === "timezone" ? validateTimezone(value) : field === "branchAllowed" ? parseList(value).length > 0 ? null : "at least one allowed branch pattern is required" : field === "branchProtected" ? parseList(value).length > 0 ? null : "at least one protected branch name is required" : field === "basePath" ? basePathMessage(value) : value.trim() === "" ? null : validateBaseUrl(value);
|
|
44955
44985
|
if (draft.values[field] === value && (draft.errors[field] ?? undefined) === (message ?? undefined)) {
|
|
44956
44986
|
return draft;
|
|
44957
44987
|
}
|
|
@@ -44974,6 +45004,8 @@ function createInitialDraft(config = readConfig()) {
|
|
|
44974
45004
|
branchAllowed: policy.allowed.join(", "),
|
|
44975
45005
|
branchProtected: policy.protected.join(", "),
|
|
44976
45006
|
baseUrl: "",
|
|
45007
|
+
basePath: process.env.WORKFLOW_WORKSPACE_ROOT ?? "",
|
|
45008
|
+
issueTracker: "youtrack",
|
|
44977
45009
|
vcsProvider: "gitlab",
|
|
44978
45010
|
workspaces: loadWorkspaces(),
|
|
44979
45011
|
applyProject: false
|
|
@@ -45004,6 +45036,26 @@ function reducer3(draft, action) {
|
|
|
45004
45036
|
return draft;
|
|
45005
45037
|
return { ...draft, values: { ...draft.values, vcsProvider: next } };
|
|
45006
45038
|
}
|
|
45039
|
+
case "issueTracker": {
|
|
45040
|
+
const next = decodeIssueTracker(action.value, draft.values.issueTracker);
|
|
45041
|
+
if (next === draft.values.issueTracker)
|
|
45042
|
+
return draft;
|
|
45043
|
+
const stripIssues = ({ issues: _, ...rest2 }) => rest2;
|
|
45044
|
+
const needsStrip = next !== "github" && (draft.values.workspaces.some((w) => w.issues !== undefined) || draft.workspaceDraft?.issues !== undefined);
|
|
45045
|
+
const errors = { ...draft.errors };
|
|
45046
|
+
delete errors.baseUrl;
|
|
45047
|
+
return {
|
|
45048
|
+
...draft,
|
|
45049
|
+
errors,
|
|
45050
|
+
workspaceDraft: needsStrip && draft.workspaceDraft ? stripIssues(draft.workspaceDraft) : draft.workspaceDraft,
|
|
45051
|
+
values: {
|
|
45052
|
+
...draft.values,
|
|
45053
|
+
issueTracker: next,
|
|
45054
|
+
baseUrl: next === "youtrack" ? draft.values.baseUrl : "",
|
|
45055
|
+
workspaces: needsStrip ? draft.values.workspaces.map(stripIssues) : draft.values.workspaces
|
|
45056
|
+
}
|
|
45057
|
+
};
|
|
45058
|
+
}
|
|
45007
45059
|
case "applyProject":
|
|
45008
45060
|
if (action.value === draft.values.applyProject)
|
|
45009
45061
|
return draft;
|
|
@@ -45071,10 +45123,16 @@ function reducer3(draft, action) {
|
|
|
45071
45123
|
const invalid = validateScreen(draft);
|
|
45072
45124
|
if (invalid)
|
|
45073
45125
|
return { ...draft, errors: { ...draft.errors, [invalid.field]: invalid.message } };
|
|
45074
|
-
return {
|
|
45126
|
+
return {
|
|
45127
|
+
...draft,
|
|
45128
|
+
screen: nextScreen(draft.screen, draft.values.branchPreset, draft.values.issueTracker, resolveBasePath(draft.values))
|
|
45129
|
+
};
|
|
45075
45130
|
}
|
|
45076
45131
|
case "back":
|
|
45077
|
-
return {
|
|
45132
|
+
return {
|
|
45133
|
+
...draft,
|
|
45134
|
+
screen: prevScreen(draft.screen, draft.values.branchPreset, draft.values.issueTracker, resolveBasePath(draft.values))
|
|
45135
|
+
};
|
|
45078
45136
|
case "cancel":
|
|
45079
45137
|
return { ...draft, screen: "exit", cancelled: true };
|
|
45080
45138
|
case "apply":
|
|
@@ -45084,11 +45142,13 @@ function reducer3(draft, action) {
|
|
|
45084
45142
|
...draft,
|
|
45085
45143
|
screen: "workspaceName",
|
|
45086
45144
|
workspaceIndex: null,
|
|
45087
|
-
workspaceDraft: {
|
|
45145
|
+
workspaceDraft: withGithubIssues({
|
|
45088
45146
|
name: "",
|
|
45089
45147
|
glob: "",
|
|
45090
|
-
vcs: {
|
|
45091
|
-
|
|
45148
|
+
vcs: {
|
|
45149
|
+
provider: defaultWorkspaceProvider(draft.values.vcsProvider, draft.values.issueTracker)
|
|
45150
|
+
}
|
|
45151
|
+
}, draft.values.issueTracker),
|
|
45092
45152
|
errors: {}
|
|
45093
45153
|
};
|
|
45094
45154
|
case "workspaceAddCurrent": {
|
|
@@ -45103,11 +45163,13 @@ function reducer3(draft, action) {
|
|
|
45103
45163
|
...draft.values,
|
|
45104
45164
|
workspaces: [
|
|
45105
45165
|
...draft.values.workspaces,
|
|
45106
|
-
{
|
|
45166
|
+
withGithubIssues({
|
|
45107
45167
|
name,
|
|
45108
45168
|
glob: `${p}/**`,
|
|
45109
|
-
vcs: {
|
|
45110
|
-
|
|
45169
|
+
vcs: {
|
|
45170
|
+
provider: defaultWorkspaceProvider(draft.values.vcsProvider, draft.values.issueTracker)
|
|
45171
|
+
}
|
|
45172
|
+
}, draft.values.issueTracker)
|
|
45111
45173
|
]
|
|
45112
45174
|
}
|
|
45113
45175
|
};
|
|
@@ -45168,9 +45230,13 @@ function reducer3(draft, action) {
|
|
|
45168
45230
|
}
|
|
45169
45231
|
}
|
|
45170
45232
|
}
|
|
45171
|
-
function defaultWorkspaceProvider(vcs) {
|
|
45233
|
+
function defaultWorkspaceProvider(vcs, tracker) {
|
|
45234
|
+
if (tracker === "github")
|
|
45235
|
+
return "github";
|
|
45172
45236
|
return vcs === "gitlab" || vcs === "github" ? vcs : "gitlab";
|
|
45173
45237
|
}
|
|
45238
|
+
var GITHUB_ISSUES = { provider: "github", link_on_pr: true };
|
|
45239
|
+
var withGithubIssues = (draft, tracker) => tracker === "github" ? { ...draft, issues: { ...GITHUB_ISSUES } } : draft;
|
|
45174
45240
|
function workspaceDraftText(draft, field, value) {
|
|
45175
45241
|
const errorKey = field === "name" ? "workspaceName" : "workspaceGlob";
|
|
45176
45242
|
const message = field === "name" ? value.trim() ? null : "workspace name is required" : value.trim() ? null : "workspace pattern is required";
|
|
@@ -45192,8 +45258,99 @@ function workspaceDraftText(draft, field, value) {
|
|
|
45192
45258
|
};
|
|
45193
45259
|
}
|
|
45194
45260
|
|
|
45195
|
-
// packages/workit-cli/src/
|
|
45261
|
+
// packages/workit-cli/src/search-select.tsx
|
|
45262
|
+
var import_react65 = __toESM(require_react(), 1);
|
|
45196
45263
|
var jsx_dev_runtime = __toESM(require_jsx_dev_runtime(), 1);
|
|
45264
|
+
var LOCALE_LANGUAGE_MAP = [
|
|
45265
|
+
{ label: "Español (España)", locale: "es-ES" },
|
|
45266
|
+
{ label: "Español (Latinoamérica)", locale: "es-419" },
|
|
45267
|
+
{ label: "Español (Chile)", locale: "es-CL" },
|
|
45268
|
+
{ label: "Español (México)", locale: "es-MX" },
|
|
45269
|
+
{ label: "Español (Argentina)", locale: "es-AR" },
|
|
45270
|
+
{ label: "English", locale: "en" },
|
|
45271
|
+
{ label: "English (United States)", locale: "en-US" },
|
|
45272
|
+
{ label: "English (United Kingdom)", locale: "en-GB" },
|
|
45273
|
+
{ label: "Português (Brasil)", locale: "pt-BR" },
|
|
45274
|
+
{ label: "Português (Portugal)", locale: "pt-PT" },
|
|
45275
|
+
{ label: "Français (France)", locale: "fr-FR" },
|
|
45276
|
+
{ label: "Français (Canada)", locale: "fr-CA" },
|
|
45277
|
+
{ label: "Deutsch (Deutschland)", locale: "de-DE" },
|
|
45278
|
+
{ label: "中文(简体)", locale: "zh-CN" },
|
|
45279
|
+
{ label: "中文(繁體)", locale: "zh-TW" },
|
|
45280
|
+
{ label: "日本語", locale: "ja-JP" },
|
|
45281
|
+
{ label: "한국어", locale: "ko-KR" },
|
|
45282
|
+
{ label: "Italiano", locale: "it-IT" },
|
|
45283
|
+
{ label: "Русский", locale: "ru-RU" },
|
|
45284
|
+
{ label: "العربية", locale: "ar-SA" },
|
|
45285
|
+
{ label: "हिन्दी", locale: "hi-IN" },
|
|
45286
|
+
{ label: "Nederlands (Nederland)", locale: "nl-NL" },
|
|
45287
|
+
{ label: "Polski (Polska)", locale: "pl-PL" },
|
|
45288
|
+
{ label: "Türkçe (Türkiye)", locale: "tr-TR" },
|
|
45289
|
+
{ label: "Svenska (Sverige)", locale: "sv-SE" }
|
|
45290
|
+
];
|
|
45291
|
+
var VISIBLE_ROWS = 5;
|
|
45292
|
+
var fold = (s) => s.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
45293
|
+
function filterOptions(options, query, limit = VISIBLE_ROWS) {
|
|
45294
|
+
const q = fold(query.trim().toLowerCase());
|
|
45295
|
+
if (!q)
|
|
45296
|
+
return options.slice(0, limit);
|
|
45297
|
+
return options.filter((option) => fold(option.label.toLowerCase()).includes(q) || fold(option.value.toLowerCase()).includes(q)).slice(0, limit);
|
|
45298
|
+
}
|
|
45299
|
+
function SearchSelect({
|
|
45300
|
+
options,
|
|
45301
|
+
value,
|
|
45302
|
+
placeholder,
|
|
45303
|
+
onSelect,
|
|
45304
|
+
onQueryChange
|
|
45305
|
+
}) {
|
|
45306
|
+
const [query, setQuery] = import_react65.useState("");
|
|
45307
|
+
const filtered = import_react65.useMemo(() => filterOptions(options, query), [options, query]);
|
|
45308
|
+
const [rawIndex, setRawIndex] = import_react65.useState(() => Math.max(0, options.findIndex((option) => option.value === value)));
|
|
45309
|
+
const index = Math.min(rawIndex, Math.max(0, filtered.length - 1));
|
|
45310
|
+
use_input_default((input, key) => {
|
|
45311
|
+
const type = (next) => {
|
|
45312
|
+
onQueryChange?.(next);
|
|
45313
|
+
setQuery(next);
|
|
45314
|
+
setRawIndex(0);
|
|
45315
|
+
};
|
|
45316
|
+
if (key.downArrow) {
|
|
45317
|
+
setRawIndex(Math.min(index + 1, filtered.length - 1));
|
|
45318
|
+
} else if (key.upArrow) {
|
|
45319
|
+
setRawIndex(Math.max(index - 1, 0));
|
|
45320
|
+
} else if (key.return) {
|
|
45321
|
+
if (filtered[index])
|
|
45322
|
+
onSelect(filtered[index].value);
|
|
45323
|
+
} else if (key.backspace || key.delete) {
|
|
45324
|
+
type(query.slice(0, -1));
|
|
45325
|
+
} else if (input && !key.ctrl && !key.meta && !key.escape && !key.tab) {
|
|
45326
|
+
type(query + input);
|
|
45327
|
+
}
|
|
45328
|
+
});
|
|
45329
|
+
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Box_default, {
|
|
45330
|
+
flexDirection: "column",
|
|
45331
|
+
gap: 0,
|
|
45332
|
+
children: [
|
|
45333
|
+
/* @__PURE__ */ jsx_dev_runtime.jsxDEV(TextInput, {
|
|
45334
|
+
isDisabled: true,
|
|
45335
|
+
defaultValue: query,
|
|
45336
|
+
placeholder
|
|
45337
|
+
}, query, false, undefined, this),
|
|
45338
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
45339
|
+
dimColor: true,
|
|
45340
|
+
children: "No matches"
|
|
45341
|
+
}, undefined, false, undefined, this) : filtered.map((option, i) => /* @__PURE__ */ jsx_dev_runtime.jsxDEV(Text, {
|
|
45342
|
+
color: i === index ? "cyan" : "dim",
|
|
45343
|
+
children: [
|
|
45344
|
+
i === index ? "❯ " : " ",
|
|
45345
|
+
option.label
|
|
45346
|
+
]
|
|
45347
|
+
}, option.value, true, undefined, this))
|
|
45348
|
+
]
|
|
45349
|
+
}, undefined, true, undefined, this);
|
|
45350
|
+
}
|
|
45351
|
+
|
|
45352
|
+
// packages/workit-cli/src/steps.tsx
|
|
45353
|
+
var jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
|
|
45197
45354
|
var PLATFORMS = [
|
|
45198
45355
|
{ label: "OpenCode", value: "opencode" },
|
|
45199
45356
|
{ label: "Cursor", value: "cursor" }
|
|
@@ -45204,23 +45361,77 @@ var BRANCH_PRESETS = [
|
|
|
45204
45361
|
{ label: "Trunk-based", value: "trunk-based" },
|
|
45205
45362
|
{ label: "Custom", value: "custom" }
|
|
45206
45363
|
];
|
|
45364
|
+
var BRANCH_PRESET_DESCRIPTIONS = {
|
|
45365
|
+
gitflow: `${PRESETS.gitflow.allowed.join(", ")} allowed · ` + `${PRESETS.gitflow.protected.join(", ")} protected · work merges into develop via PRs or merge commits`,
|
|
45366
|
+
"github-flow": `Anything goes (${PRESETS["github-flow"].allowed[0]}) · only ${PRESETS["github-flow"].protected.join(", ")} is protected · branches off main, back to main`,
|
|
45367
|
+
"trunk-based": `Short-lived branches off trunk · ${PRESETS["trunk-based"].protected.join(", ")} is the only protected branch`,
|
|
45368
|
+
custom: "Define your own allowed and protected patterns in the next prompts"
|
|
45369
|
+
};
|
|
45370
|
+
var SCREEN_PLACEHOLDERS = {
|
|
45371
|
+
youtrack: "e.g. https://example.youtrack.cloud",
|
|
45372
|
+
localeOther: "e.g. en-US or es-CL",
|
|
45373
|
+
timezoneOther: "e.g. America/Santiago",
|
|
45374
|
+
branchAllowed: "e.g. feature/*, bugfix/*",
|
|
45375
|
+
branchProtected: "e.g. main, develop",
|
|
45376
|
+
workspaceName: "e.g. work",
|
|
45377
|
+
workspaceGlob: "e.g. /work/**",
|
|
45378
|
+
branchPolicyDevelop: "e.g. develop"
|
|
45379
|
+
};
|
|
45207
45380
|
var VCS_PROVIDERS = [
|
|
45208
45381
|
{ label: "GitLab", value: "gitlab" },
|
|
45209
45382
|
{ label: "GitHub", value: "github" },
|
|
45210
45383
|
{ label: "Skip — configure later", value: "skip" }
|
|
45211
45384
|
];
|
|
45212
|
-
var
|
|
45213
|
-
|
|
45385
|
+
var LOCALE_PICKER_OPTIONS = [
|
|
45386
|
+
...LOCALE_LANGUAGE_MAP.map((entry) => ({ label: entry.label, value: entry.locale })),
|
|
45387
|
+
{ label: "Other…", value: "other" }
|
|
45388
|
+
];
|
|
45389
|
+
var ISSUE_TRACKERS = [
|
|
45390
|
+
{ label: "YouTrack", value: "youtrack" },
|
|
45391
|
+
{ label: "GitHub Issues", value: "github" },
|
|
45392
|
+
{ label: "None", value: "none" }
|
|
45393
|
+
];
|
|
45394
|
+
var TIMEZONE_FALLBACK = [
|
|
45395
|
+
"UTC",
|
|
45396
|
+
"America/New_York",
|
|
45397
|
+
"America/Santiago",
|
|
45398
|
+
"America/Bogota",
|
|
45399
|
+
"America/Mexico_City",
|
|
45400
|
+
"America/Sao_Paulo",
|
|
45401
|
+
"America/Argentina/Buenos_Aires",
|
|
45402
|
+
"Europe/London",
|
|
45403
|
+
"Europe/Madrid",
|
|
45404
|
+
"Europe/Berlin",
|
|
45405
|
+
"Asia/Tokyo",
|
|
45406
|
+
"Asia/Shanghai",
|
|
45407
|
+
"Asia/Kolkata",
|
|
45408
|
+
"Australia/Sydney"
|
|
45409
|
+
];
|
|
45410
|
+
var TIMEZONES = typeof Intl.supportedValuesOf === "function" ? Intl.supportedValuesOf("timeZone") : TIMEZONE_FALLBACK;
|
|
45411
|
+
var DETECTED_TIMEZONE = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
45412
|
+
function timezonePickerOptions() {
|
|
45413
|
+
return TIMEZONE_PICKER_OPTIONS;
|
|
45414
|
+
}
|
|
45415
|
+
var TIMEZONE_PICKER_OPTIONS = [
|
|
45416
|
+
{ label: DETECTED_TIMEZONE, value: DETECTED_TIMEZONE },
|
|
45417
|
+
...TIMEZONES.filter((timezone) => timezone !== DETECTED_TIMEZONE).map((timezone) => ({
|
|
45418
|
+
label: timezone,
|
|
45419
|
+
value: timezone
|
|
45420
|
+
})),
|
|
45421
|
+
{ label: "Other…", value: "other" }
|
|
45422
|
+
];
|
|
45214
45423
|
var TEXT_SCREENS = new Set([
|
|
45215
45424
|
"localeOther",
|
|
45216
45425
|
"timezoneOther",
|
|
45217
45426
|
"branchAllowed",
|
|
45218
45427
|
"branchProtected",
|
|
45219
45428
|
"youtrack",
|
|
45429
|
+
"basePath",
|
|
45220
45430
|
"workspaceName",
|
|
45221
45431
|
"workspaceGlob",
|
|
45222
45432
|
"branchPolicyDevelop"
|
|
45223
45433
|
]);
|
|
45434
|
+
var SEARCH_SCREENS = new Set(["locale", "timezone"]);
|
|
45224
45435
|
function workspacePreviewTargets(cwd2) {
|
|
45225
45436
|
const norm = cwd2.replace(/[\\/]+$/, "");
|
|
45226
45437
|
const idx = norm.lastIndexOf("/");
|
|
@@ -45233,28 +45444,25 @@ function SelectList({
|
|
|
45233
45444
|
onChange,
|
|
45234
45445
|
onSelect
|
|
45235
45446
|
}) {
|
|
45236
|
-
const [index, setIndex] =
|
|
45447
|
+
const [index, setIndex] = import_react66.useState(() => Math.max(0, options.findIndex((option) => option.value === value)));
|
|
45448
|
+
const indexRef = import_react66.useRef(index);
|
|
45449
|
+
indexRef.current = index;
|
|
45237
45450
|
use_input_default((_input, key) => {
|
|
45238
|
-
if (key.downArrow) {
|
|
45239
|
-
|
|
45240
|
-
|
|
45241
|
-
|
|
45242
|
-
|
|
45243
|
-
|
|
45244
|
-
|
|
45245
|
-
setIndex((i) => {
|
|
45246
|
-
const next = Math.max(i - 1, 0);
|
|
45247
|
-
onChange?.(options[next].value);
|
|
45248
|
-
return next;
|
|
45249
|
-
});
|
|
45451
|
+
if (key.downArrow || key.upArrow) {
|
|
45452
|
+
const next = key.downArrow ? Math.min(indexRef.current + 1, options.length - 1) : Math.max(indexRef.current - 1, 0);
|
|
45453
|
+
if (next === indexRef.current)
|
|
45454
|
+
return;
|
|
45455
|
+
indexRef.current = next;
|
|
45456
|
+
setIndex(next);
|
|
45457
|
+
onChange?.(options[next].value);
|
|
45250
45458
|
} else if (key.return) {
|
|
45251
|
-
onSelect(options[
|
|
45459
|
+
onSelect(options[indexRef.current].value);
|
|
45252
45460
|
}
|
|
45253
45461
|
});
|
|
45254
|
-
return /* @__PURE__ */
|
|
45462
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45255
45463
|
flexDirection: "column",
|
|
45256
45464
|
gap: 0,
|
|
45257
|
-
children: options.map((option, i) => /* @__PURE__ */
|
|
45465
|
+
children: options.map((option, i) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45258
45466
|
color: i === index ? "cyan" : "dim",
|
|
45259
45467
|
children: [
|
|
45260
45468
|
i === index ? "❯ " : " ",
|
|
@@ -45263,16 +45471,6 @@ function SelectList({
|
|
|
45263
45471
|
}, option.value, true, undefined, this))
|
|
45264
45472
|
}, undefined, false, undefined, this);
|
|
45265
45473
|
}
|
|
45266
|
-
function localeOptions(current) {
|
|
45267
|
-
const fixed = LOCALE_CHOICES.map((locale) => ({ label: locale, value: locale }));
|
|
45268
|
-
const list = LOCALE_CHOICES.includes(current) ? fixed : [...fixed, { label: `Use current (${current})`, value: current }];
|
|
45269
|
-
return [...list, { label: "Other…", value: "other" }];
|
|
45270
|
-
}
|
|
45271
|
-
function timezoneOptions(current) {
|
|
45272
|
-
const fixed = TIMEZONE_CHOICES.map((timezone) => ({ label: timezone, value: timezone }));
|
|
45273
|
-
const list = TIMEZONE_CHOICES.includes(current) ? fixed : [...fixed, { label: `Use current (${current})`, value: current }];
|
|
45274
|
-
return [...list, { label: "Other…", value: "other" }];
|
|
45275
|
-
}
|
|
45276
45474
|
function effectivePolicy(values2) {
|
|
45277
45475
|
return mergePreset(values2.branchPreset, {
|
|
45278
45476
|
allowed: parseList(values2.branchAllowed),
|
|
@@ -45292,26 +45490,26 @@ var INTEGRATION_OPTIONS = [
|
|
|
45292
45490
|
function BranchPolicyScreen({ draft, dispatch }) {
|
|
45293
45491
|
const detected = draft.values.branchPolicyDetected;
|
|
45294
45492
|
const policy = draft.values.branchPolicy ?? detected;
|
|
45295
|
-
const [mode, setMode] =
|
|
45296
|
-
|
|
45493
|
+
const [mode, setMode] = import_react66.useState("menu");
|
|
45494
|
+
import_react66.useEffect(() => {
|
|
45297
45495
|
if (detected)
|
|
45298
45496
|
return;
|
|
45299
45497
|
dispatch({
|
|
45300
45498
|
type: "set",
|
|
45301
45499
|
field: "branchPolicyDetected",
|
|
45302
|
-
value: detectBranchPolicy(
|
|
45500
|
+
value: detectBranchPolicy(resolveBasePath(draft.values))
|
|
45303
45501
|
});
|
|
45304
45502
|
}, [detected, dispatch]);
|
|
45305
45503
|
if (mode === "integration") {
|
|
45306
|
-
return /* @__PURE__ */
|
|
45504
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45307
45505
|
flexDirection: "column",
|
|
45308
45506
|
gap: 1,
|
|
45309
45507
|
children: [
|
|
45310
|
-
/* @__PURE__ */
|
|
45508
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45311
45509
|
bold: true,
|
|
45312
45510
|
children: "Step 5 — Branch policy · Integration"
|
|
45313
45511
|
}, undefined, false, undefined, this),
|
|
45314
|
-
/* @__PURE__ */
|
|
45512
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
45315
45513
|
options: INTEGRATION_OPTIONS,
|
|
45316
45514
|
value: policy?.integration ?? "merge",
|
|
45317
45515
|
onSelect: (value) => {
|
|
@@ -45319,77 +45517,77 @@ function BranchPolicyScreen({ draft, dispatch }) {
|
|
|
45319
45517
|
setMode("menu");
|
|
45320
45518
|
}
|
|
45321
45519
|
}, undefined, false, undefined, this),
|
|
45322
|
-
/* @__PURE__ */
|
|
45520
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45323
45521
|
dimColor: true,
|
|
45324
45522
|
children: "Enter to select · b Back · Esc Cancel"
|
|
45325
45523
|
}, undefined, false, undefined, this)
|
|
45326
45524
|
]
|
|
45327
45525
|
}, undefined, true, undefined, this);
|
|
45328
45526
|
}
|
|
45329
|
-
return /* @__PURE__ */
|
|
45527
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45330
45528
|
flexDirection: "column",
|
|
45331
45529
|
gap: 1,
|
|
45332
45530
|
children: [
|
|
45333
|
-
/* @__PURE__ */
|
|
45531
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45334
45532
|
bold: true,
|
|
45335
45533
|
children: "Step 5 — Branch policy"
|
|
45336
45534
|
}, undefined, false, undefined, this),
|
|
45337
|
-
policy ? /* @__PURE__ */
|
|
45535
|
+
policy ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45338
45536
|
flexDirection: "column",
|
|
45339
45537
|
gap: 0,
|
|
45340
45538
|
children: [
|
|
45341
|
-
/* @__PURE__ */
|
|
45539
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45342
45540
|
children: [
|
|
45343
45541
|
"Detected preset: ",
|
|
45344
|
-
/* @__PURE__ */
|
|
45542
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45345
45543
|
color: "green",
|
|
45346
45544
|
children: policy.preset
|
|
45347
45545
|
}, undefined, false, undefined, this)
|
|
45348
45546
|
]
|
|
45349
45547
|
}, undefined, true, undefined, this),
|
|
45350
|
-
/* @__PURE__ */
|
|
45548
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45351
45549
|
children: [
|
|
45352
45550
|
"Develop branch: ",
|
|
45353
|
-
/* @__PURE__ */
|
|
45551
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45354
45552
|
color: "green",
|
|
45355
45553
|
children: policy.developBranch ?? "—"
|
|
45356
45554
|
}, undefined, false, undefined, this)
|
|
45357
45555
|
]
|
|
45358
45556
|
}, undefined, true, undefined, this),
|
|
45359
|
-
/* @__PURE__ */
|
|
45557
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45360
45558
|
children: [
|
|
45361
45559
|
"Integration: ",
|
|
45362
|
-
/* @__PURE__ */
|
|
45560
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45363
45561
|
color: "green",
|
|
45364
45562
|
children: policy.integration
|
|
45365
45563
|
}, undefined, false, undefined, this)
|
|
45366
45564
|
]
|
|
45367
45565
|
}, undefined, true, undefined, this),
|
|
45368
|
-
/* @__PURE__ */
|
|
45566
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45369
45567
|
children: [
|
|
45370
45568
|
"Prefixes:",
|
|
45371
45569
|
" ",
|
|
45372
|
-
/* @__PURE__ */
|
|
45570
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45373
45571
|
color: "green",
|
|
45374
45572
|
children: Object.values(policy.prefixes ?? {}).join(", ") || "—"
|
|
45375
45573
|
}, undefined, false, undefined, this)
|
|
45376
45574
|
]
|
|
45377
45575
|
}, undefined, true, undefined, this),
|
|
45378
|
-
/* @__PURE__ */
|
|
45576
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45379
45577
|
children: [
|
|
45380
45578
|
"Protected: ",
|
|
45381
|
-
/* @__PURE__ */
|
|
45579
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45382
45580
|
color: "green",
|
|
45383
45581
|
children: policy.protected?.join(", ") || "—"
|
|
45384
45582
|
}, undefined, false, undefined, this)
|
|
45385
45583
|
]
|
|
45386
45584
|
}, undefined, true, undefined, this)
|
|
45387
45585
|
]
|
|
45388
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
45586
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45389
45587
|
dimColor: true,
|
|
45390
45588
|
children: "Detecting branch policy…"
|
|
45391
45589
|
}, undefined, false, undefined, this),
|
|
45392
|
-
/* @__PURE__ */
|
|
45590
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
45393
45591
|
options: BRANCH_POLICY_ACTIONS,
|
|
45394
45592
|
value: "accept",
|
|
45395
45593
|
onSelect: (value) => {
|
|
@@ -45405,7 +45603,7 @@ function BranchPolicyScreen({ draft, dispatch }) {
|
|
|
45405
45603
|
dispatch({ type: "next" });
|
|
45406
45604
|
}
|
|
45407
45605
|
}, undefined, false, undefined, this),
|
|
45408
|
-
/* @__PURE__ */
|
|
45606
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45409
45607
|
dimColor: true,
|
|
45410
45608
|
children: "Enter to continue · b Back · Esc Cancel"
|
|
45411
45609
|
}, undefined, false, undefined, this)
|
|
@@ -45415,8 +45613,12 @@ function BranchPolicyScreen({ draft, dispatch }) {
|
|
|
45415
45613
|
function Wizard({
|
|
45416
45614
|
onExit
|
|
45417
45615
|
}) {
|
|
45418
|
-
const [draft, dispatch] =
|
|
45419
|
-
const exitedRef =
|
|
45616
|
+
const [draft, dispatch] = import_react66.useReducer(reducer3, undefined, createInitialDraft);
|
|
45617
|
+
const exitedRef = import_react66.useRef(false);
|
|
45618
|
+
const searchRef = import_react66.useRef({ q: "", typed: false });
|
|
45619
|
+
import_react66.useEffect(() => {
|
|
45620
|
+
searchRef.current = { q: "", typed: false };
|
|
45621
|
+
}, [draft.screen]);
|
|
45420
45622
|
use_input_default((input, key) => {
|
|
45421
45623
|
if (key.ctrl && input.toLowerCase() === "c") {
|
|
45422
45624
|
dispatch({ type: "cancel" });
|
|
@@ -45426,27 +45628,36 @@ function Wizard({
|
|
|
45426
45628
|
else
|
|
45427
45629
|
dispatch({ type: "cancel" });
|
|
45428
45630
|
} else if (input.toLowerCase() === "b" && !TEXT_SCREENS.has(draft.screen)) {
|
|
45429
|
-
|
|
45631
|
+
const search = searchRef.current;
|
|
45632
|
+
const searchOwnsB = SEARCH_SCREENS.has(draft.screen) && !(search.typed && search.q === "");
|
|
45633
|
+
if (!searchOwnsB)
|
|
45634
|
+
dispatch({ type: "back" });
|
|
45430
45635
|
}
|
|
45431
45636
|
});
|
|
45432
|
-
|
|
45637
|
+
import_react66.useEffect(() => {
|
|
45433
45638
|
if (draft.screen === "exit" && !exitedRef.current) {
|
|
45434
45639
|
exitedRef.current = true;
|
|
45435
45640
|
onExit(!draft.cancelled, draft.values);
|
|
45436
45641
|
}
|
|
45437
45642
|
}, [draft.screen, draft.cancelled, onExit]);
|
|
45438
|
-
return /* @__PURE__ */
|
|
45643
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45439
45644
|
flexDirection: "column",
|
|
45440
45645
|
gap: 1,
|
|
45441
45646
|
children: [
|
|
45442
|
-
/* @__PURE__ */
|
|
45647
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45443
45648
|
bold: true,
|
|
45444
45649
|
color: "cyan",
|
|
45445
45650
|
children: "workit — workflow rails for agentic coding"
|
|
45446
45651
|
}, undefined, false, undefined, this),
|
|
45447
|
-
/* @__PURE__ */
|
|
45652
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Screen, {
|
|
45448
45653
|
draft,
|
|
45449
|
-
dispatch
|
|
45654
|
+
dispatch,
|
|
45655
|
+
onSearchQueryChange: (query) => {
|
|
45656
|
+
const search = searchRef.current;
|
|
45657
|
+
search.q = query;
|
|
45658
|
+
if (query !== "")
|
|
45659
|
+
search.typed = true;
|
|
45660
|
+
}
|
|
45450
45661
|
}, draft.screen, false, undefined, this)
|
|
45451
45662
|
]
|
|
45452
45663
|
}, undefined, true, undefined, this);
|
|
@@ -45469,22 +45680,56 @@ function describeMutation(m) {
|
|
|
45469
45680
|
return `+ change ${m.key} in ${m.path} → ${m.value}`;
|
|
45470
45681
|
}
|
|
45471
45682
|
}
|
|
45472
|
-
function
|
|
45683
|
+
function BasePathScreen({ draft, dispatch }) {
|
|
45684
|
+
const onChange = import_react66.useCallback((value) => dispatch({ type: "set", field: "basePath", value }), [dispatch]);
|
|
45685
|
+
const onSubmit = import_react66.useCallback((value) => {
|
|
45686
|
+
dispatch({ type: "set", field: "basePath", value });
|
|
45687
|
+
dispatch({ type: "next" });
|
|
45688
|
+
}, [dispatch]);
|
|
45689
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45690
|
+
flexDirection: "column",
|
|
45691
|
+
gap: 1,
|
|
45692
|
+
children: [
|
|
45693
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45694
|
+
bold: true,
|
|
45695
|
+
children: "Step 5 — Workspace root"
|
|
45696
|
+
}, undefined, false, undefined, this),
|
|
45697
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45698
|
+
dimColor: true,
|
|
45699
|
+
children: "Absolute path where your projects live (e.g. /work):"
|
|
45700
|
+
}, undefined, false, undefined, this),
|
|
45701
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
45702
|
+
defaultValue: draft.values.basePath,
|
|
45703
|
+
onChange,
|
|
45704
|
+
onSubmit
|
|
45705
|
+
}, undefined, false, undefined, this),
|
|
45706
|
+
draft.errors.basePath && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45707
|
+
color: "red",
|
|
45708
|
+
children: draft.errors.basePath
|
|
45709
|
+
}, undefined, false, undefined, this),
|
|
45710
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45711
|
+
dimColor: true,
|
|
45712
|
+
children: "Enter to continue · Esc Back"
|
|
45713
|
+
}, undefined, false, undefined, this)
|
|
45714
|
+
]
|
|
45715
|
+
}, undefined, true, undefined, this);
|
|
45716
|
+
}
|
|
45717
|
+
function Screen({ draft, dispatch, onSearchQueryChange }) {
|
|
45473
45718
|
switch (draft.screen) {
|
|
45474
45719
|
case "platforms":
|
|
45475
|
-
return /* @__PURE__ */
|
|
45720
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45476
45721
|
flexDirection: "column",
|
|
45477
45722
|
gap: 1,
|
|
45478
45723
|
children: [
|
|
45479
|
-
/* @__PURE__ */
|
|
45724
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45480
45725
|
bold: true,
|
|
45481
45726
|
children: "Step 1 — Platforms"
|
|
45482
45727
|
}, undefined, false, undefined, this),
|
|
45483
|
-
/* @__PURE__ */
|
|
45728
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45484
45729
|
dimColor: true,
|
|
45485
45730
|
children: "Select the tools to configure (space to toggle):"
|
|
45486
45731
|
}, undefined, false, undefined, this),
|
|
45487
|
-
/* @__PURE__ */
|
|
45732
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(MultiSelect, {
|
|
45488
45733
|
options: PLATFORMS,
|
|
45489
45734
|
defaultValue: draft.values.platforms,
|
|
45490
45735
|
onChange: (values2) => dispatch({ type: "set", field: "platforms", value: values2 }),
|
|
@@ -45493,36 +45738,43 @@ function Screen({ draft, dispatch }) {
|
|
|
45493
45738
|
dispatch({ type: "next" });
|
|
45494
45739
|
}
|
|
45495
45740
|
}, undefined, false, undefined, this),
|
|
45496
|
-
draft.errors.platforms && /* @__PURE__ */
|
|
45741
|
+
draft.errors.platforms && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45497
45742
|
color: "red",
|
|
45498
45743
|
children: draft.errors.platforms
|
|
45499
45744
|
}, undefined, false, undefined, this),
|
|
45500
|
-
/* @__PURE__ */
|
|
45745
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45501
45746
|
dimColor: true,
|
|
45502
45747
|
children: "Enter to continue · Esc Cancel"
|
|
45503
45748
|
}, undefined, false, undefined, this)
|
|
45504
45749
|
]
|
|
45505
45750
|
}, undefined, true, undefined, this);
|
|
45506
45751
|
case "locale":
|
|
45507
|
-
return /* @__PURE__ */
|
|
45752
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45508
45753
|
flexDirection: "column",
|
|
45509
45754
|
gap: 1,
|
|
45510
45755
|
children: [
|
|
45511
|
-
/* @__PURE__ */
|
|
45756
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45512
45757
|
bold: true,
|
|
45513
45758
|
children: "Step 2 — Global config · Locale"
|
|
45514
45759
|
}, undefined, false, undefined, this),
|
|
45515
|
-
/* @__PURE__ */
|
|
45760
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45516
45761
|
dimColor: true,
|
|
45517
45762
|
children: "Locale (BCP-47):"
|
|
45518
45763
|
}, undefined, false, undefined, this),
|
|
45519
|
-
/* @__PURE__ */
|
|
45520
|
-
|
|
45764
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45765
|
+
children: [
|
|
45766
|
+
"Current: ",
|
|
45767
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45768
|
+
color: "green",
|
|
45769
|
+
children: draft.values.locale
|
|
45770
|
+
}, undefined, false, undefined, this)
|
|
45771
|
+
]
|
|
45772
|
+
}, undefined, true, undefined, this),
|
|
45773
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SearchSelect, {
|
|
45774
|
+
options: LOCALE_PICKER_OPTIONS,
|
|
45521
45775
|
value: draft.values.locale,
|
|
45522
|
-
|
|
45523
|
-
|
|
45524
|
-
dispatch({ type: "set", field: "locale", value });
|
|
45525
|
-
},
|
|
45776
|
+
placeholder: "Type to search languages…",
|
|
45777
|
+
onQueryChange: onSearchQueryChange,
|
|
45526
45778
|
onSelect: (value) => {
|
|
45527
45779
|
if (value === "other")
|
|
45528
45780
|
dispatch({ type: "pickOther" });
|
|
@@ -45532,63 +45784,71 @@ function Screen({ draft, dispatch }) {
|
|
|
45532
45784
|
}
|
|
45533
45785
|
}
|
|
45534
45786
|
}, undefined, false, undefined, this),
|
|
45535
|
-
draft.errors.locale && /* @__PURE__ */
|
|
45787
|
+
draft.errors.locale && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45536
45788
|
color: "red",
|
|
45537
45789
|
children: draft.errors.locale
|
|
45538
45790
|
}, undefined, false, undefined, this),
|
|
45539
|
-
/* @__PURE__ */
|
|
45791
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45540
45792
|
dimColor: true,
|
|
45541
|
-
children: "Enter to continue · b Back · Esc Cancel"
|
|
45793
|
+
children: "Type to filter · Enter to continue · b Back · Esc Cancel"
|
|
45542
45794
|
}, undefined, false, undefined, this)
|
|
45543
45795
|
]
|
|
45544
45796
|
}, undefined, true, undefined, this);
|
|
45545
45797
|
case "localeOther":
|
|
45546
|
-
return /* @__PURE__ */
|
|
45798
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45547
45799
|
flexDirection: "column",
|
|
45548
45800
|
gap: 1,
|
|
45549
45801
|
children: [
|
|
45550
|
-
/* @__PURE__ */
|
|
45802
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45551
45803
|
bold: true,
|
|
45552
45804
|
children: "Step 2 — Global config · Locale (custom)"
|
|
45553
45805
|
}, undefined, false, undefined, this),
|
|
45554
|
-
/* @__PURE__ */
|
|
45806
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45555
45807
|
dimColor: true,
|
|
45556
45808
|
children: "Type a BCP-47 locale (e.g. en or es-CL):"
|
|
45557
45809
|
}, undefined, false, undefined, this),
|
|
45558
|
-
/* @__PURE__ */
|
|
45810
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
45811
|
+
placeholder: SCREEN_PLACEHOLDERS.localeOther,
|
|
45559
45812
|
onChange: (value) => dispatch({ type: "set", field: "locale", value }),
|
|
45560
45813
|
onSubmit: () => dispatch({ type: "next" })
|
|
45561
45814
|
}, undefined, false, undefined, this),
|
|
45562
|
-
draft.errors.locale && /* @__PURE__ */
|
|
45815
|
+
draft.errors.locale && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45563
45816
|
color: "red",
|
|
45564
45817
|
children: draft.errors.locale
|
|
45565
45818
|
}, undefined, false, undefined, this),
|
|
45566
|
-
/* @__PURE__ */
|
|
45819
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45567
45820
|
dimColor: true,
|
|
45568
45821
|
children: "Enter to continue · Esc Back"
|
|
45569
45822
|
}, undefined, false, undefined, this)
|
|
45570
45823
|
]
|
|
45571
45824
|
}, undefined, true, undefined, this);
|
|
45572
45825
|
case "timezone":
|
|
45573
|
-
return /* @__PURE__ */
|
|
45826
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45574
45827
|
flexDirection: "column",
|
|
45575
45828
|
gap: 1,
|
|
45576
45829
|
children: [
|
|
45577
|
-
/* @__PURE__ */
|
|
45830
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45578
45831
|
bold: true,
|
|
45579
45832
|
children: "Step 2 — Global config · Timezone"
|
|
45580
45833
|
}, undefined, false, undefined, this),
|
|
45581
|
-
/* @__PURE__ */
|
|
45834
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45582
45835
|
dimColor: true,
|
|
45583
45836
|
children: "Timezone (IANA name):"
|
|
45584
45837
|
}, undefined, false, undefined, this),
|
|
45585
|
-
/* @__PURE__ */
|
|
45586
|
-
|
|
45587
|
-
|
|
45588
|
-
|
|
45589
|
-
|
|
45590
|
-
|
|
45591
|
-
|
|
45838
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45839
|
+
children: [
|
|
45840
|
+
"Current: ",
|
|
45841
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45842
|
+
color: "green",
|
|
45843
|
+
children: draft.values.timezone
|
|
45844
|
+
}, undefined, false, undefined, this)
|
|
45845
|
+
]
|
|
45846
|
+
}, undefined, true, undefined, this),
|
|
45847
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SearchSelect, {
|
|
45848
|
+
options: timezonePickerOptions(),
|
|
45849
|
+
value: draft.values.timezone || DETECTED_TIMEZONE,
|
|
45850
|
+
placeholder: "Type to search timezones…",
|
|
45851
|
+
onQueryChange: onSearchQueryChange,
|
|
45592
45852
|
onSelect: (value) => {
|
|
45593
45853
|
if (value === "other")
|
|
45594
45854
|
dispatch({ type: "pickOther" });
|
|
@@ -45598,38 +45858,39 @@ function Screen({ draft, dispatch }) {
|
|
|
45598
45858
|
}
|
|
45599
45859
|
}
|
|
45600
45860
|
}, undefined, false, undefined, this),
|
|
45601
|
-
draft.errors.timezone && /* @__PURE__ */
|
|
45861
|
+
draft.errors.timezone && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45602
45862
|
color: "red",
|
|
45603
45863
|
children: draft.errors.timezone
|
|
45604
45864
|
}, undefined, false, undefined, this),
|
|
45605
|
-
/* @__PURE__ */
|
|
45865
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45606
45866
|
dimColor: true,
|
|
45607
|
-
children: "Enter to continue · b Back · Esc Cancel"
|
|
45867
|
+
children: "Type to filter · Enter to continue · b Back · Esc Cancel"
|
|
45608
45868
|
}, undefined, false, undefined, this)
|
|
45609
45869
|
]
|
|
45610
45870
|
}, undefined, true, undefined, this);
|
|
45611
45871
|
case "timezoneOther":
|
|
45612
|
-
return /* @__PURE__ */
|
|
45872
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45613
45873
|
flexDirection: "column",
|
|
45614
45874
|
gap: 1,
|
|
45615
45875
|
children: [
|
|
45616
|
-
/* @__PURE__ */
|
|
45876
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45617
45877
|
bold: true,
|
|
45618
45878
|
children: "Step 2 — Global config · Timezone (custom)"
|
|
45619
45879
|
}, undefined, false, undefined, this),
|
|
45620
|
-
/* @__PURE__ */
|
|
45880
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45621
45881
|
dimColor: true,
|
|
45622
45882
|
children: "Type an IANA timezone (e.g. America/Santiago):"
|
|
45623
45883
|
}, undefined, false, undefined, this),
|
|
45624
|
-
/* @__PURE__ */
|
|
45884
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
45885
|
+
placeholder: SCREEN_PLACEHOLDERS.timezoneOther,
|
|
45625
45886
|
onChange: (value) => dispatch({ type: "set", field: "timezone", value }),
|
|
45626
45887
|
onSubmit: () => dispatch({ type: "next" })
|
|
45627
45888
|
}, undefined, false, undefined, this),
|
|
45628
|
-
draft.errors.timezone && /* @__PURE__ */
|
|
45889
|
+
draft.errors.timezone && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45629
45890
|
color: "red",
|
|
45630
45891
|
children: draft.errors.timezone
|
|
45631
45892
|
}, undefined, false, undefined, this),
|
|
45632
|
-
/* @__PURE__ */
|
|
45893
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45633
45894
|
dimColor: true,
|
|
45634
45895
|
children: "Enter to continue · Esc Back"
|
|
45635
45896
|
}, undefined, false, undefined, this)
|
|
@@ -45637,41 +45898,45 @@ function Screen({ draft, dispatch }) {
|
|
|
45637
45898
|
}, undefined, true, undefined, this);
|
|
45638
45899
|
case "branchPreset": {
|
|
45639
45900
|
const policy = effectivePolicy(draft.values);
|
|
45640
|
-
return /* @__PURE__ */
|
|
45901
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45641
45902
|
flexDirection: "column",
|
|
45642
45903
|
gap: 1,
|
|
45643
45904
|
children: [
|
|
45644
|
-
/* @__PURE__ */
|
|
45905
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45645
45906
|
bold: true,
|
|
45646
45907
|
children: "Step 2 — Global config · Branch policy"
|
|
45647
45908
|
}, undefined, false, undefined, this),
|
|
45648
|
-
/* @__PURE__ */
|
|
45909
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45649
45910
|
dimColor: true,
|
|
45650
45911
|
children: "Branch policy preset:"
|
|
45651
45912
|
}, undefined, false, undefined, this),
|
|
45652
|
-
/* @__PURE__ */
|
|
45913
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
45653
45914
|
options: BRANCH_PRESETS,
|
|
45654
45915
|
value: draft.values.branchPreset,
|
|
45655
45916
|
onChange: (value) => dispatch({ type: "set", field: "branchPreset", value }),
|
|
45656
45917
|
onSelect: () => dispatch({ type: "next" })
|
|
45657
45918
|
}, undefined, false, undefined, this),
|
|
45658
|
-
/* @__PURE__ */
|
|
45919
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45920
|
+
dimColor: true,
|
|
45921
|
+
children: BRANCH_PRESET_DESCRIPTIONS[draft.values.branchPreset]
|
|
45922
|
+
}, undefined, false, undefined, this),
|
|
45923
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45659
45924
|
flexDirection: "column",
|
|
45660
45925
|
gap: 0,
|
|
45661
45926
|
children: [
|
|
45662
|
-
/* @__PURE__ */
|
|
45927
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45663
45928
|
children: [
|
|
45664
45929
|
"Allowed: ",
|
|
45665
|
-
/* @__PURE__ */
|
|
45930
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45666
45931
|
color: "green",
|
|
45667
45932
|
children: policy.allowed.join(", ") || "—"
|
|
45668
45933
|
}, undefined, false, undefined, this)
|
|
45669
45934
|
]
|
|
45670
45935
|
}, undefined, true, undefined, this),
|
|
45671
|
-
/* @__PURE__ */
|
|
45936
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45672
45937
|
children: [
|
|
45673
45938
|
"Protected: ",
|
|
45674
|
-
/* @__PURE__ */
|
|
45939
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45675
45940
|
color: "green",
|
|
45676
45941
|
children: policy.protected.join(", ") || "—"
|
|
45677
45942
|
}, undefined, false, undefined, this)
|
|
@@ -45679,7 +45944,7 @@ function Screen({ draft, dispatch }) {
|
|
|
45679
45944
|
}, undefined, true, undefined, this)
|
|
45680
45945
|
]
|
|
45681
45946
|
}, undefined, true, undefined, this),
|
|
45682
|
-
/* @__PURE__ */
|
|
45947
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45683
45948
|
dimColor: true,
|
|
45684
45949
|
children: policy.preset === "custom" ? "Enter to continue — define the patterns next · b Back · Esc Cancel" : "Enter to continue · b Back · Esc Cancel"
|
|
45685
45950
|
}, undefined, false, undefined, this)
|
|
@@ -45687,116 +45952,149 @@ function Screen({ draft, dispatch }) {
|
|
|
45687
45952
|
}, undefined, true, undefined, this);
|
|
45688
45953
|
}
|
|
45689
45954
|
case "branchAllowed":
|
|
45690
|
-
return /* @__PURE__ */
|
|
45955
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45691
45956
|
flexDirection: "column",
|
|
45692
45957
|
gap: 1,
|
|
45693
45958
|
children: [
|
|
45694
|
-
/* @__PURE__ */
|
|
45959
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45695
45960
|
bold: true,
|
|
45696
45961
|
children: "Step 2 — Global config · Allowed branch patterns"
|
|
45697
45962
|
}, undefined, false, undefined, this),
|
|
45698
|
-
/* @__PURE__ */
|
|
45963
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45699
45964
|
dimColor: true,
|
|
45700
45965
|
children: "Allowed branch patterns (comma-separated):"
|
|
45701
45966
|
}, undefined, false, undefined, this),
|
|
45702
|
-
/* @__PURE__ */
|
|
45967
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
45968
|
+
placeholder: SCREEN_PLACEHOLDERS.branchAllowed,
|
|
45703
45969
|
defaultValue: draft.values.branchAllowed,
|
|
45704
45970
|
onChange: (value) => dispatch({ type: "set", field: "branchAllowed", value }),
|
|
45705
45971
|
onSubmit: () => dispatch({ type: "next" })
|
|
45706
45972
|
}, undefined, false, undefined, this),
|
|
45707
|
-
draft.errors.branchAllowed && /* @__PURE__ */
|
|
45973
|
+
draft.errors.branchAllowed && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45708
45974
|
color: "red",
|
|
45709
45975
|
children: draft.errors.branchAllowed
|
|
45710
45976
|
}, undefined, false, undefined, this),
|
|
45711
|
-
/* @__PURE__ */
|
|
45977
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45712
45978
|
dimColor: true,
|
|
45713
45979
|
children: "Enter to continue · Esc Back"
|
|
45714
45980
|
}, undefined, false, undefined, this)
|
|
45715
45981
|
]
|
|
45716
45982
|
}, undefined, true, undefined, this);
|
|
45717
45983
|
case "branchProtected":
|
|
45718
|
-
return /* @__PURE__ */
|
|
45984
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45719
45985
|
flexDirection: "column",
|
|
45720
45986
|
gap: 1,
|
|
45721
45987
|
children: [
|
|
45722
|
-
/* @__PURE__ */
|
|
45988
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45723
45989
|
bold: true,
|
|
45724
45990
|
children: "Step 2 — Global config · Protected branch names"
|
|
45725
45991
|
}, undefined, false, undefined, this),
|
|
45726
|
-
/* @__PURE__ */
|
|
45992
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45727
45993
|
dimColor: true,
|
|
45728
45994
|
children: "Protected branch names (comma-separated):"
|
|
45729
45995
|
}, undefined, false, undefined, this),
|
|
45730
|
-
/* @__PURE__ */
|
|
45996
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
45997
|
+
placeholder: SCREEN_PLACEHOLDERS.branchProtected,
|
|
45731
45998
|
defaultValue: draft.values.branchProtected,
|
|
45732
45999
|
onChange: (value) => dispatch({ type: "set", field: "branchProtected", value }),
|
|
45733
46000
|
onSubmit: () => dispatch({ type: "next" })
|
|
45734
46001
|
}, undefined, false, undefined, this),
|
|
45735
|
-
draft.errors.branchProtected && /* @__PURE__ */
|
|
46002
|
+
draft.errors.branchProtected && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45736
46003
|
color: "red",
|
|
45737
46004
|
children: draft.errors.branchProtected
|
|
45738
46005
|
}, undefined, false, undefined, this),
|
|
45739
|
-
/* @__PURE__ */
|
|
46006
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45740
46007
|
dimColor: true,
|
|
45741
46008
|
children: "Enter to continue · Esc Back"
|
|
45742
46009
|
}, undefined, false, undefined, this)
|
|
45743
46010
|
]
|
|
45744
46011
|
}, undefined, true, undefined, this);
|
|
46012
|
+
case "issueTracker":
|
|
46013
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
46014
|
+
flexDirection: "column",
|
|
46015
|
+
gap: 1,
|
|
46016
|
+
children: [
|
|
46017
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46018
|
+
bold: true,
|
|
46019
|
+
children: "Step 3 — Issue tracker"
|
|
46020
|
+
}, undefined, false, undefined, this),
|
|
46021
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46022
|
+
dimColor: true,
|
|
46023
|
+
children: "Where do issues live?"
|
|
46024
|
+
}, undefined, false, undefined, this),
|
|
46025
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
46026
|
+
options: ISSUE_TRACKERS,
|
|
46027
|
+
value: draft.values.issueTracker,
|
|
46028
|
+
onChange: (value) => dispatch({ type: "set", field: "issueTracker", value }),
|
|
46029
|
+
onSelect: () => dispatch({ type: "next" })
|
|
46030
|
+
}, undefined, false, undefined, this),
|
|
46031
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46032
|
+
dimColor: true,
|
|
46033
|
+
children: "Enter to continue · b Back · Esc Cancel"
|
|
46034
|
+
}, undefined, false, undefined, this)
|
|
46035
|
+
]
|
|
46036
|
+
}, undefined, true, undefined, this);
|
|
45745
46037
|
case "youtrack":
|
|
45746
|
-
return /* @__PURE__ */
|
|
46038
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45747
46039
|
flexDirection: "column",
|
|
45748
46040
|
gap: 1,
|
|
45749
46041
|
children: [
|
|
45750
|
-
/* @__PURE__ */
|
|
46042
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45751
46043
|
bold: true,
|
|
45752
46044
|
children: "Step 3 — YouTrack"
|
|
45753
46045
|
}, undefined, false, undefined, this),
|
|
45754
|
-
/* @__PURE__ */
|
|
46046
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45755
46047
|
dimColor: true,
|
|
45756
46048
|
children: "Base URL (https):"
|
|
45757
46049
|
}, undefined, false, undefined, this),
|
|
45758
|
-
/* @__PURE__ */
|
|
46050
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
46051
|
+
placeholder: SCREEN_PLACEHOLDERS.youtrack,
|
|
45759
46052
|
defaultValue: draft.values.baseUrl,
|
|
45760
46053
|
onChange: (value) => dispatch({ type: "set", field: "baseUrl", value }),
|
|
45761
46054
|
onSubmit: () => dispatch({ type: "next" })
|
|
45762
46055
|
}, undefined, false, undefined, this),
|
|
45763
|
-
draft.errors.baseUrl && /* @__PURE__ */
|
|
46056
|
+
draft.errors.baseUrl && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45764
46057
|
color: "red",
|
|
45765
46058
|
children: draft.errors.baseUrl
|
|
45766
46059
|
}, undefined, false, undefined, this),
|
|
45767
|
-
/* @__PURE__ */
|
|
46060
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45768
46061
|
dimColor: true,
|
|
45769
46062
|
children: "Enter to continue · Esc Back"
|
|
45770
46063
|
}, undefined, false, undefined, this)
|
|
45771
46064
|
]
|
|
45772
46065
|
}, undefined, true, undefined, this);
|
|
45773
46066
|
case "vcs":
|
|
45774
|
-
return /* @__PURE__ */
|
|
46067
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45775
46068
|
flexDirection: "column",
|
|
45776
46069
|
gap: 1,
|
|
45777
46070
|
children: [
|
|
45778
|
-
/* @__PURE__ */
|
|
46071
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45779
46072
|
bold: true,
|
|
45780
46073
|
children: "Step 4 — Version control"
|
|
45781
46074
|
}, undefined, false, undefined, this),
|
|
45782
|
-
/* @__PURE__ */
|
|
46075
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45783
46076
|
dimColor: true,
|
|
45784
46077
|
children: "Provider:"
|
|
45785
46078
|
}, undefined, false, undefined, this),
|
|
45786
|
-
/* @__PURE__ */
|
|
46079
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
45787
46080
|
options: VCS_PROVIDERS,
|
|
45788
46081
|
value: draft.values.vcsProvider,
|
|
45789
46082
|
onChange: (value) => dispatch({ type: "set", field: "vcsProvider", value }),
|
|
45790
46083
|
onSelect: () => dispatch({ type: "next" })
|
|
45791
46084
|
}, undefined, false, undefined, this),
|
|
45792
|
-
/* @__PURE__ */
|
|
46085
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45793
46086
|
dimColor: true,
|
|
45794
46087
|
children: "Enter to continue · b Back · Esc Cancel"
|
|
45795
46088
|
}, undefined, false, undefined, this)
|
|
45796
46089
|
]
|
|
45797
46090
|
}, undefined, true, undefined, this);
|
|
46091
|
+
case "basePath":
|
|
46092
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(BasePathScreen, {
|
|
46093
|
+
draft,
|
|
46094
|
+
dispatch
|
|
46095
|
+
}, undefined, false, undefined, this);
|
|
45798
46096
|
case "workspaces": {
|
|
45799
|
-
const
|
|
46097
|
+
const base2 = resolveBasePath(draft.values);
|
|
45800
46098
|
const options = [
|
|
45801
46099
|
...draft.values.workspaces.map((w, i) => ({
|
|
45802
46100
|
label: `Edit ${w.name} (${w.glob})`,
|
|
@@ -45807,26 +46105,26 @@ function Screen({ draft, dispatch }) {
|
|
|
45807
46105
|
value: `remove:${i}`
|
|
45808
46106
|
})),
|
|
45809
46107
|
{ label: "Add workspace", value: "add" },
|
|
45810
|
-
{ label: `Use current project (${
|
|
46108
|
+
{ label: `Use current project (${base2})`, value: "current" },
|
|
45811
46109
|
{ label: "Done", value: "done" }
|
|
45812
46110
|
];
|
|
45813
|
-
return /* @__PURE__ */
|
|
46111
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45814
46112
|
flexDirection: "column",
|
|
45815
46113
|
gap: 1,
|
|
45816
46114
|
children: [
|
|
45817
|
-
/* @__PURE__ */
|
|
46115
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45818
46116
|
bold: true,
|
|
45819
46117
|
children: "Step 5 — Workspaces"
|
|
45820
46118
|
}, undefined, false, undefined, this),
|
|
45821
|
-
draft.values.workspaces.length === 0 ? /* @__PURE__ */
|
|
46119
|
+
draft.values.workspaces.length === 0 ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45822
46120
|
dimColor: true,
|
|
45823
46121
|
children: "No workspaces configured yet."
|
|
45824
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */
|
|
46122
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45825
46123
|
flexDirection: "column",
|
|
45826
46124
|
gap: 0,
|
|
45827
46125
|
children: draft.values.workspaces.map((w) => {
|
|
45828
|
-
const matches2 = matchWorkspace(w.glob,
|
|
45829
|
-
return /* @__PURE__ */
|
|
46126
|
+
const matches2 = matchWorkspace(w.glob, base2);
|
|
46127
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45830
46128
|
children: [
|
|
45831
46129
|
matches2 ? "✓ matches" : "✗ no match",
|
|
45832
46130
|
" ",
|
|
@@ -45840,7 +46138,7 @@ function Screen({ draft, dispatch }) {
|
|
|
45840
46138
|
}, `${w.name}|${w.glob}|${w.vcs?.provider ?? ""}`, true, undefined, this);
|
|
45841
46139
|
})
|
|
45842
46140
|
}, undefined, false, undefined, this),
|
|
45843
|
-
/* @__PURE__ */
|
|
46141
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
45844
46142
|
options,
|
|
45845
46143
|
value: "done",
|
|
45846
46144
|
onSelect: (value) => {
|
|
@@ -45851,12 +46149,12 @@ function Screen({ draft, dispatch }) {
|
|
|
45851
46149
|
else if (value === "add")
|
|
45852
46150
|
dispatch({ type: "workspaceAdd" });
|
|
45853
46151
|
else if (value === "current")
|
|
45854
|
-
dispatch({ type: "workspaceAddCurrent", path:
|
|
46152
|
+
dispatch({ type: "workspaceAddCurrent", path: base2 });
|
|
45855
46153
|
else
|
|
45856
46154
|
dispatch({ type: "next" });
|
|
45857
46155
|
}
|
|
45858
46156
|
}, draft.values.workspaces.map((w) => `${w.name}:${w.glob}`).join("|"), false, undefined, this),
|
|
45859
|
-
/* @__PURE__ */
|
|
46157
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45860
46158
|
dimColor: true,
|
|
45861
46159
|
children: "Enter to continue · b Back · Esc Cancel"
|
|
45862
46160
|
}, undefined, false, undefined, this)
|
|
@@ -45864,28 +46162,29 @@ function Screen({ draft, dispatch }) {
|
|
|
45864
46162
|
}, undefined, true, undefined, this);
|
|
45865
46163
|
}
|
|
45866
46164
|
case "workspaceName":
|
|
45867
|
-
return /* @__PURE__ */
|
|
46165
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45868
46166
|
flexDirection: "column",
|
|
45869
46167
|
gap: 1,
|
|
45870
46168
|
children: [
|
|
45871
|
-
/* @__PURE__ */
|
|
46169
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45872
46170
|
bold: true,
|
|
45873
46171
|
children: "Step 5 — Workspaces · Name"
|
|
45874
46172
|
}, undefined, false, undefined, this),
|
|
45875
|
-
/* @__PURE__ */
|
|
46173
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45876
46174
|
dimColor: true,
|
|
45877
46175
|
children: draft.workspaceIndex === null ? "New workspace name:" : `Edit workspace name (${draft.values.workspaces[draft.workspaceIndex]?.name ?? ""}):`
|
|
45878
46176
|
}, undefined, false, undefined, this),
|
|
45879
|
-
/* @__PURE__ */
|
|
46177
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
46178
|
+
placeholder: SCREEN_PLACEHOLDERS.workspaceName,
|
|
45880
46179
|
defaultValue: draft.workspaceDraft?.name ?? "",
|
|
45881
46180
|
onChange: (value) => dispatch({ type: "workspaceDraftName", value }),
|
|
45882
46181
|
onSubmit: () => dispatch({ type: "next" })
|
|
45883
46182
|
}, undefined, false, undefined, this),
|
|
45884
|
-
draft.errors.workspaceName && /* @__PURE__ */
|
|
46183
|
+
draft.errors.workspaceName && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45885
46184
|
color: "red",
|
|
45886
46185
|
children: draft.errors.workspaceName
|
|
45887
46186
|
}, undefined, false, undefined, this),
|
|
45888
|
-
/* @__PURE__ */
|
|
46187
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45889
46188
|
dimColor: true,
|
|
45890
46189
|
children: "Enter to continue · Esc Back"
|
|
45891
46190
|
}, undefined, false, undefined, this)
|
|
@@ -45893,34 +46192,35 @@ function Screen({ draft, dispatch }) {
|
|
|
45893
46192
|
}, undefined, true, undefined, this);
|
|
45894
46193
|
case "workspaceGlob": {
|
|
45895
46194
|
const glob = draft.workspaceDraft?.glob ?? "";
|
|
45896
|
-
return /* @__PURE__ */
|
|
46195
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45897
46196
|
flexDirection: "column",
|
|
45898
46197
|
gap: 1,
|
|
45899
46198
|
children: [
|
|
45900
|
-
/* @__PURE__ */
|
|
46199
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45901
46200
|
bold: true,
|
|
45902
46201
|
children: "Step 5 — Workspaces · Pattern"
|
|
45903
46202
|
}, undefined, false, undefined, this),
|
|
45904
|
-
/* @__PURE__ */
|
|
46203
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45905
46204
|
dimColor: true,
|
|
45906
46205
|
children: "Workspace pattern (glob, e.g. /work/**):"
|
|
45907
46206
|
}, undefined, false, undefined, this),
|
|
45908
|
-
/* @__PURE__ */
|
|
46207
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
46208
|
+
placeholder: SCREEN_PLACEHOLDERS.workspaceGlob,
|
|
45909
46209
|
defaultValue: glob,
|
|
45910
46210
|
onChange: (value) => dispatch({ type: "workspaceDraftGlob", value }),
|
|
45911
46211
|
onSubmit: () => dispatch({ type: "next" })
|
|
45912
46212
|
}, undefined, false, undefined, this),
|
|
45913
|
-
glob.trim() !== "" && /* @__PURE__ */
|
|
46213
|
+
glob.trim() !== "" && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45914
46214
|
flexDirection: "column",
|
|
45915
46215
|
gap: 0,
|
|
45916
46216
|
children: [
|
|
45917
|
-
/* @__PURE__ */
|
|
46217
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45918
46218
|
bold: true,
|
|
45919
46219
|
children: "Match preview (shared matcher):"
|
|
45920
46220
|
}, undefined, false, undefined, this),
|
|
45921
|
-
workspacePreviewTargets(
|
|
46221
|
+
workspacePreviewTargets(resolveBasePath(draft.values)).map((target) => {
|
|
45922
46222
|
const matches2 = matchWorkspace(glob, target);
|
|
45923
|
-
return /* @__PURE__ */
|
|
46223
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45924
46224
|
color: matches2 ? "green" : "red",
|
|
45925
46225
|
children: [
|
|
45926
46226
|
matches2 ? "✓ matches" : "✗ no match",
|
|
@@ -45931,11 +46231,11 @@ function Screen({ draft, dispatch }) {
|
|
|
45931
46231
|
})
|
|
45932
46232
|
]
|
|
45933
46233
|
}, undefined, true, undefined, this),
|
|
45934
|
-
draft.errors.workspaceGlob && /* @__PURE__ */
|
|
46234
|
+
draft.errors.workspaceGlob && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45935
46235
|
color: "red",
|
|
45936
46236
|
children: draft.errors.workspaceGlob
|
|
45937
46237
|
}, undefined, false, undefined, this),
|
|
45938
|
-
/* @__PURE__ */
|
|
46238
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45939
46239
|
dimColor: true,
|
|
45940
46240
|
children: "Enter to continue · Esc Back"
|
|
45941
46241
|
}, undefined, false, undefined, this)
|
|
@@ -45943,19 +46243,19 @@ function Screen({ draft, dispatch }) {
|
|
|
45943
46243
|
}, undefined, true, undefined, this);
|
|
45944
46244
|
}
|
|
45945
46245
|
case "workspaceProvider":
|
|
45946
|
-
return /* @__PURE__ */
|
|
46246
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45947
46247
|
flexDirection: "column",
|
|
45948
46248
|
gap: 1,
|
|
45949
46249
|
children: [
|
|
45950
|
-
/* @__PURE__ */
|
|
46250
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45951
46251
|
bold: true,
|
|
45952
46252
|
children: "Step 5 — Workspaces · Provider"
|
|
45953
46253
|
}, undefined, false, undefined, this),
|
|
45954
|
-
/* @__PURE__ */
|
|
46254
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45955
46255
|
dimColor: true,
|
|
45956
46256
|
children: "Version control provider for this workspace:"
|
|
45957
46257
|
}, undefined, false, undefined, this),
|
|
45958
|
-
/* @__PURE__ */
|
|
46258
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(SelectList, {
|
|
45959
46259
|
options: VCS_PROVIDERS.filter((option) => option.value !== "skip"),
|
|
45960
46260
|
value: draft.workspaceDraft?.vcs?.provider ?? "gitlab",
|
|
45961
46261
|
onChange: (value) => dispatch({ type: "workspaceDraftProvider", value }),
|
|
@@ -45964,61 +46264,62 @@ function Screen({ draft, dispatch }) {
|
|
|
45964
46264
|
dispatch({ type: "workspaceSave" });
|
|
45965
46265
|
}
|
|
45966
46266
|
}, undefined, false, undefined, this),
|
|
45967
|
-
/* @__PURE__ */
|
|
46267
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45968
46268
|
dimColor: true,
|
|
45969
46269
|
children: "Enter to save · b Back · Esc Cancel"
|
|
45970
46270
|
}, undefined, false, undefined, this)
|
|
45971
46271
|
]
|
|
45972
46272
|
}, undefined, true, undefined, this);
|
|
45973
46273
|
case "branchPolicy":
|
|
45974
|
-
return /* @__PURE__ */
|
|
46274
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(BranchPolicyScreen, {
|
|
45975
46275
|
draft,
|
|
45976
46276
|
dispatch
|
|
45977
46277
|
}, undefined, false, undefined, this);
|
|
45978
46278
|
case "branchPolicyDevelop":
|
|
45979
|
-
return /* @__PURE__ */
|
|
46279
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
45980
46280
|
flexDirection: "column",
|
|
45981
46281
|
gap: 1,
|
|
45982
46282
|
children: [
|
|
45983
|
-
/* @__PURE__ */
|
|
46283
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45984
46284
|
bold: true,
|
|
45985
46285
|
children: "Step 5 — Branch policy · Develop branch"
|
|
45986
46286
|
}, undefined, false, undefined, this),
|
|
45987
|
-
/* @__PURE__ */
|
|
46287
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45988
46288
|
dimColor: true,
|
|
45989
46289
|
children: "Integration/develop branch name (leave empty to unset):"
|
|
45990
46290
|
}, undefined, false, undefined, this),
|
|
45991
|
-
/* @__PURE__ */
|
|
46291
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(TextInput, {
|
|
46292
|
+
placeholder: SCREEN_PLACEHOLDERS.branchPolicyDevelop,
|
|
45992
46293
|
defaultValue: draft.values.branchPolicy?.developBranch ?? draft.values.branchPolicyDetected?.developBranch ?? "",
|
|
45993
46294
|
onSubmit: (value) => {
|
|
45994
46295
|
dispatch({ type: "set", field: "branchPolicyDevelop", value });
|
|
45995
46296
|
dispatch({ type: "next" });
|
|
45996
46297
|
}
|
|
45997
46298
|
}, undefined, false, undefined, this),
|
|
45998
|
-
/* @__PURE__ */
|
|
46299
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
45999
46300
|
dimColor: true,
|
|
46000
46301
|
children: "Enter to save · Esc Back"
|
|
46001
46302
|
}, undefined, false, undefined, this)
|
|
46002
46303
|
]
|
|
46003
46304
|
}, undefined, true, undefined, this);
|
|
46004
46305
|
case "project":
|
|
46005
|
-
return /* @__PURE__ */
|
|
46306
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
46006
46307
|
flexDirection: "column",
|
|
46007
46308
|
gap: 1,
|
|
46008
46309
|
children: [
|
|
46009
|
-
/* @__PURE__ */
|
|
46310
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46010
46311
|
bold: true,
|
|
46011
46312
|
children: "Step 6 — Project setup"
|
|
46012
46313
|
}, undefined, false, undefined, this),
|
|
46013
|
-
/* @__PURE__ */
|
|
46314
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46014
46315
|
dimColor: true,
|
|
46015
46316
|
children: [
|
|
46016
46317
|
"Will apply gitignore + hygiene in ",
|
|
46017
|
-
|
|
46318
|
+
resolveBasePath(draft.values),
|
|
46018
46319
|
" (existing files are never overwritten):"
|
|
46019
46320
|
]
|
|
46020
46321
|
}, undefined, true, undefined, this),
|
|
46021
|
-
/* @__PURE__ */
|
|
46322
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(ConfirmInput, {
|
|
46022
46323
|
defaultChoice: "confirm",
|
|
46023
46324
|
submitOnEnter: false,
|
|
46024
46325
|
onConfirm: () => {
|
|
@@ -46027,7 +46328,7 @@ function Screen({ draft, dispatch }) {
|
|
|
46027
46328
|
},
|
|
46028
46329
|
onCancel: () => {}
|
|
46029
46330
|
}, undefined, false, undefined, this),
|
|
46030
|
-
/* @__PURE__ */
|
|
46331
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46031
46332
|
dimColor: true,
|
|
46032
46333
|
children: "y to continue · n to stay · b Back · Esc Cancel"
|
|
46033
46334
|
}, undefined, false, undefined, this)
|
|
@@ -46035,47 +46336,47 @@ function Screen({ draft, dispatch }) {
|
|
|
46035
46336
|
}, undefined, true, undefined, this);
|
|
46036
46337
|
case "summary": {
|
|
46037
46338
|
const policy = effectivePolicy(draft.values);
|
|
46038
|
-
const preview = buildSetupPreview(draft.values);
|
|
46039
|
-
return /* @__PURE__ */
|
|
46339
|
+
const preview = buildSetupPreview(draft.values, { cwd: resolveBasePath(draft.values) });
|
|
46340
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
46040
46341
|
flexDirection: "column",
|
|
46041
46342
|
gap: 1,
|
|
46042
46343
|
children: [
|
|
46043
|
-
/* @__PURE__ */
|
|
46344
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46044
46345
|
bold: true,
|
|
46045
46346
|
color: "cyan",
|
|
46046
46347
|
children: "Review"
|
|
46047
46348
|
}, undefined, false, undefined, this),
|
|
46048
|
-
/* @__PURE__ */
|
|
46349
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46049
46350
|
children: [
|
|
46050
46351
|
"Platforms: ",
|
|
46051
|
-
/* @__PURE__ */
|
|
46352
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46052
46353
|
color: "green",
|
|
46053
46354
|
children: draft.values.platforms.join(", ") || "—"
|
|
46054
46355
|
}, undefined, false, undefined, this)
|
|
46055
46356
|
]
|
|
46056
46357
|
}, undefined, true, undefined, this),
|
|
46057
|
-
/* @__PURE__ */
|
|
46358
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46058
46359
|
children: [
|
|
46059
46360
|
"Locale: ",
|
|
46060
|
-
/* @__PURE__ */
|
|
46361
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46061
46362
|
color: "green",
|
|
46062
46363
|
children: draft.values.locale
|
|
46063
46364
|
}, undefined, false, undefined, this)
|
|
46064
46365
|
]
|
|
46065
46366
|
}, undefined, true, undefined, this),
|
|
46066
|
-
/* @__PURE__ */
|
|
46367
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46067
46368
|
children: [
|
|
46068
46369
|
"Timezone: ",
|
|
46069
|
-
/* @__PURE__ */
|
|
46370
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46070
46371
|
color: "green",
|
|
46071
46372
|
children: draft.values.timezone
|
|
46072
46373
|
}, undefined, false, undefined, this)
|
|
46073
46374
|
]
|
|
46074
46375
|
}, undefined, true, undefined, this),
|
|
46075
|
-
/* @__PURE__ */
|
|
46376
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46076
46377
|
children: [
|
|
46077
46378
|
"Branch policy: ",
|
|
46078
|
-
/* @__PURE__ */
|
|
46379
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46079
46380
|
color: "green",
|
|
46080
46381
|
children: policy.preset
|
|
46081
46382
|
}, undefined, false, undefined, this),
|
|
@@ -46086,43 +46387,43 @@ function Screen({ draft, dispatch }) {
|
|
|
46086
46387
|
policy.protected.join(", ")
|
|
46087
46388
|
]
|
|
46088
46389
|
}, undefined, true, undefined, this),
|
|
46089
|
-
/* @__PURE__ */
|
|
46390
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46090
46391
|
children: [
|
|
46091
46392
|
"YouTrack base URL:",
|
|
46092
46393
|
" ",
|
|
46093
|
-
/* @__PURE__ */
|
|
46394
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46094
46395
|
color: "green",
|
|
46095
|
-
children: draft.values.baseUrl.trim() ? draft.values.baseUrl : "— (skip)"
|
|
46396
|
+
children: draft.values.issueTracker === "youtrack" ? draft.values.baseUrl.trim() ? draft.values.baseUrl : "— (skip)" : "—"
|
|
46096
46397
|
}, undefined, false, undefined, this)
|
|
46097
46398
|
]
|
|
46098
46399
|
}, undefined, true, undefined, this),
|
|
46099
|
-
/* @__PURE__ */
|
|
46400
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46100
46401
|
children: [
|
|
46101
46402
|
"VCS provider: ",
|
|
46102
|
-
/* @__PURE__ */
|
|
46403
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46103
46404
|
color: "green",
|
|
46104
46405
|
children: draft.values.vcsProvider
|
|
46105
46406
|
}, undefined, false, undefined, this)
|
|
46106
46407
|
]
|
|
46107
46408
|
}, undefined, true, undefined, this),
|
|
46108
|
-
/* @__PURE__ */
|
|
46409
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46109
46410
|
children: [
|
|
46110
46411
|
"Project hygiene: ",
|
|
46111
|
-
/* @__PURE__ */
|
|
46412
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46112
46413
|
color: "green",
|
|
46113
46414
|
children: draft.values.applyProject ? "yes" : "no"
|
|
46114
46415
|
}, undefined, false, undefined, this)
|
|
46115
46416
|
]
|
|
46116
46417
|
}, undefined, true, undefined, this),
|
|
46117
|
-
preview.overrides.length > 0 && /* @__PURE__ */
|
|
46418
|
+
preview.overrides.length > 0 && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
46118
46419
|
flexDirection: "column",
|
|
46119
46420
|
gap: 0,
|
|
46120
46421
|
children: [
|
|
46121
|
-
/* @__PURE__ */
|
|
46422
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46122
46423
|
bold: true,
|
|
46123
46424
|
children: "Environment overrides (not applied by the wizard):"
|
|
46124
46425
|
}, undefined, false, undefined, this),
|
|
46125
|
-
preview.overrides.map((o) => /* @__PURE__ */
|
|
46426
|
+
preview.overrides.map((o) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46126
46427
|
color: "yellow",
|
|
46127
46428
|
children: [
|
|
46128
46429
|
o.envKey,
|
|
@@ -46134,18 +46435,18 @@ function Screen({ draft, dispatch }) {
|
|
|
46134
46435
|
}, o.envKey, true, undefined, this))
|
|
46135
46436
|
]
|
|
46136
46437
|
}, undefined, true, undefined, this),
|
|
46137
|
-
preview.ok ? /* @__PURE__ */
|
|
46438
|
+
preview.ok ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
46138
46439
|
flexDirection: "column",
|
|
46139
46440
|
gap: 0,
|
|
46140
46441
|
children: [
|
|
46141
|
-
/* @__PURE__ */
|
|
46442
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46142
46443
|
bold: true,
|
|
46143
46444
|
children: "Will apply:"
|
|
46144
46445
|
}, undefined, false, undefined, this),
|
|
46145
|
-
preview.mutations.map((m) => /* @__PURE__ */
|
|
46446
|
+
preview.mutations.map((m) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46146
46447
|
children: describeMutation(m)
|
|
46147
46448
|
}, `${m.type}:${m.path}`, false, undefined, this)),
|
|
46148
|
-
preview.preserved.map((p) => /* @__PURE__ */
|
|
46449
|
+
preview.preserved.map((p) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46149
46450
|
color: "green",
|
|
46150
46451
|
children: [
|
|
46151
46452
|
"preserve ",
|
|
@@ -46154,32 +46455,32 @@ function Screen({ draft, dispatch }) {
|
|
|
46154
46455
|
]
|
|
46155
46456
|
}, p, true, undefined, this))
|
|
46156
46457
|
]
|
|
46157
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
46458
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
46158
46459
|
flexDirection: "column",
|
|
46159
46460
|
gap: 0,
|
|
46160
46461
|
children: [
|
|
46161
|
-
/* @__PURE__ */
|
|
46462
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46162
46463
|
bold: true,
|
|
46163
46464
|
color: "red",
|
|
46164
46465
|
children: "Apply blocked — malformed configuration:"
|
|
46165
46466
|
}, undefined, false, undefined, this),
|
|
46166
|
-
preview.blocked.map((b) => /* @__PURE__ */
|
|
46467
|
+
preview.blocked.map((b) => /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46167
46468
|
color: "red",
|
|
46168
46469
|
children: b
|
|
46169
46470
|
}, b, false, undefined, this)),
|
|
46170
|
-
/* @__PURE__ */
|
|
46471
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46171
46472
|
dimColor: true,
|
|
46172
46473
|
children: "Fix or remove the blocked file above, then return here. Esc Cancel."
|
|
46173
46474
|
}, undefined, false, undefined, this)
|
|
46174
46475
|
]
|
|
46175
46476
|
}, undefined, true, undefined, this),
|
|
46176
|
-
preview.ok && /* @__PURE__ */
|
|
46477
|
+
preview.ok && /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(ConfirmInput, {
|
|
46177
46478
|
defaultChoice: "confirm",
|
|
46178
46479
|
submitOnEnter: false,
|
|
46179
46480
|
onConfirm: () => dispatch({ type: "apply" }),
|
|
46180
46481
|
onCancel: () => {}
|
|
46181
46482
|
}, undefined, false, undefined, this),
|
|
46182
|
-
/* @__PURE__ */
|
|
46483
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46183
46484
|
dimColor: true,
|
|
46184
46485
|
children: preview.ok ? "y to apply · b Back · Esc Cancel" : "b Back · Esc Cancel"
|
|
46185
46486
|
}, undefined, false, undefined, this)
|
|
@@ -46187,10 +46488,10 @@ function Screen({ draft, dispatch }) {
|
|
|
46187
46488
|
}, undefined, true, undefined, this);
|
|
46188
46489
|
}
|
|
46189
46490
|
case "exit":
|
|
46190
|
-
return /* @__PURE__ */
|
|
46491
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
46191
46492
|
flexDirection: "column",
|
|
46192
46493
|
gap: 1,
|
|
46193
|
-
children: /* @__PURE__ */
|
|
46494
|
+
children: /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
46194
46495
|
dimColor: true,
|
|
46195
46496
|
children: "Exiting…"
|
|
46196
46497
|
}, undefined, false, undefined, this)
|
|
@@ -46424,71 +46725,305 @@ var createLogger = (options = {}) => {
|
|
|
46424
46725
|
};
|
|
46425
46726
|
};
|
|
46426
46727
|
|
|
46728
|
+
// packages/workit-core/src/core/uninstall.ts
|
|
46729
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9, realpathSync as realpathSync2, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
46730
|
+
import os7 from "node:os";
|
|
46731
|
+
import path13 from "node:path";
|
|
46732
|
+
var resolveUninstallPaths = (options = {}) => {
|
|
46733
|
+
const home = options.home ?? options.env?.HOME ?? os7.homedir();
|
|
46734
|
+
return {
|
|
46735
|
+
opencodeConfig: options.opencodeConfig ?? path13.join(home, ".config", "opencode", "opencode.json"),
|
|
46736
|
+
cursorSettings: options.cursorSettings ?? path13.join(home, ".cursor", "settings.json"),
|
|
46737
|
+
cursorMcp: options.cursorMcp ?? path13.join(home, ".cursor", "mcp.json"),
|
|
46738
|
+
cursorPluginDir: options.cursorPluginDir ?? path13.join(home, ".cursor", "plugins", "local", "workit")
|
|
46739
|
+
};
|
|
46740
|
+
};
|
|
46741
|
+
var isRecord3 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
46742
|
+
var readJsonRecord = (file) => {
|
|
46743
|
+
let raw;
|
|
46744
|
+
try {
|
|
46745
|
+
raw = readFileSync9(file, "utf8");
|
|
46746
|
+
} catch {
|
|
46747
|
+
if (existsSync10(file))
|
|
46748
|
+
return { kind: "malformed", error: `${file} is not readable` };
|
|
46749
|
+
return { kind: "missing" };
|
|
46750
|
+
}
|
|
46751
|
+
try {
|
|
46752
|
+
const value = JSON.parse(raw);
|
|
46753
|
+
return isRecord3(value) ? { kind: "record", value } : { kind: "malformed", error: `${file} is not a JSON object` };
|
|
46754
|
+
} catch {
|
|
46755
|
+
return { kind: "malformed", error: `${file} is not valid JSON` };
|
|
46756
|
+
}
|
|
46757
|
+
};
|
|
46758
|
+
var stripTrailingSep = (p) => {
|
|
46759
|
+
const j = path13.join(p);
|
|
46760
|
+
return path13.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
|
|
46761
|
+
};
|
|
46762
|
+
var CURSOR_LEGACY_IDENTITIES = ["workflow-toolkit", "local/workflow-toolkit"];
|
|
46763
|
+
function cleanCursorSettings(settings, pluginDir) {
|
|
46764
|
+
const next = { ...settings };
|
|
46765
|
+
let changed = false;
|
|
46766
|
+
if (isRecord3(next.enabled_plugins)) {
|
|
46767
|
+
const enabled = { ...next.enabled_plugins };
|
|
46768
|
+
for (const identity2 of ["workit", ...CURSOR_LEGACY_IDENTITIES]) {
|
|
46769
|
+
if (identity2 in enabled) {
|
|
46770
|
+
delete enabled[identity2];
|
|
46771
|
+
changed = true;
|
|
46772
|
+
}
|
|
46773
|
+
}
|
|
46774
|
+
next.enabled_plugins = enabled;
|
|
46775
|
+
}
|
|
46776
|
+
if (Array.isArray(next.plugin_dirs)) {
|
|
46777
|
+
const canonical = stripTrailingSep(pluginDir);
|
|
46778
|
+
const kept = next.plugin_dirs.map(String).filter((d) => stripTrailingSep(d) !== canonical);
|
|
46779
|
+
if (kept.length !== next.plugin_dirs.length) {
|
|
46780
|
+
next.plugin_dirs = kept;
|
|
46781
|
+
changed = true;
|
|
46782
|
+
}
|
|
46783
|
+
}
|
|
46784
|
+
return { next, changed };
|
|
46785
|
+
}
|
|
46786
|
+
function cleanOpenCodeConfig(config) {
|
|
46787
|
+
const next = { ...config };
|
|
46788
|
+
let changed = false;
|
|
46789
|
+
if (Array.isArray(next.plugin)) {
|
|
46790
|
+
const plugins = next.plugin.map(String);
|
|
46791
|
+
const kept = plugins.filter((p) => !isWorkitPlugin(p));
|
|
46792
|
+
if (kept.length !== plugins.length) {
|
|
46793
|
+
next.plugin = kept;
|
|
46794
|
+
changed = true;
|
|
46795
|
+
}
|
|
46796
|
+
} else if (typeof next.plugin === "string" && isWorkitPlugin(next.plugin)) {
|
|
46797
|
+
delete next.plugin;
|
|
46798
|
+
changed = true;
|
|
46799
|
+
}
|
|
46800
|
+
return { next, changed };
|
|
46801
|
+
}
|
|
46802
|
+
function cleanCursorMcp(mcp) {
|
|
46803
|
+
const next = { ...mcp };
|
|
46804
|
+
let changed = false;
|
|
46805
|
+
if (isRecord3(next.mcpServers)) {
|
|
46806
|
+
const servers = { ...next.mcpServers };
|
|
46807
|
+
for (const name of ["workit", "workflow-toolkit"]) {
|
|
46808
|
+
if (name in servers) {
|
|
46809
|
+
delete servers[name];
|
|
46810
|
+
changed = true;
|
|
46811
|
+
}
|
|
46812
|
+
}
|
|
46813
|
+
next.mcpServers = servers;
|
|
46814
|
+
}
|
|
46815
|
+
return { next, changed };
|
|
46816
|
+
}
|
|
46817
|
+
var jsonCleanerFor = (target, res) => {
|
|
46818
|
+
if (target === res.opencodeConfig)
|
|
46819
|
+
return cleanOpenCodeConfig;
|
|
46820
|
+
if (target === res.cursorSettings)
|
|
46821
|
+
return (r) => cleanCursorSettings(r, res.cursorPluginDir);
|
|
46822
|
+
if (target === res.cursorMcp)
|
|
46823
|
+
return cleanCursorMcp;
|
|
46824
|
+
return null;
|
|
46825
|
+
};
|
|
46826
|
+
function planUninstall(paths = {}) {
|
|
46827
|
+
const res = resolveUninstallPaths(paths);
|
|
46828
|
+
const ocExisting = readJsonRecord(res.opencodeConfig);
|
|
46829
|
+
const ocDirty = ocExisting.kind === "malformed" || ocExisting.kind === "record" && cleanOpenCodeConfig(ocExisting.value).changed;
|
|
46830
|
+
const opencode = {
|
|
46831
|
+
host: "opencode",
|
|
46832
|
+
installed: ocDirty,
|
|
46833
|
+
actions: ocDirty ? [
|
|
46834
|
+
{
|
|
46835
|
+
kind: "edit-json-remove",
|
|
46836
|
+
path: res.opencodeConfig,
|
|
46837
|
+
detail: "remove workit plugin entries from opencode.json"
|
|
46838
|
+
}
|
|
46839
|
+
] : []
|
|
46840
|
+
};
|
|
46841
|
+
const settingsExisting = readJsonRecord(res.cursorSettings);
|
|
46842
|
+
const mcpExisting = readJsonRecord(res.cursorMcp);
|
|
46843
|
+
const settingsDirty = settingsExisting.kind === "malformed" || settingsExisting.kind === "record" && cleanCursorSettings(settingsExisting.value, res.cursorPluginDir).changed;
|
|
46844
|
+
const mcpDirty = mcpExisting.kind === "malformed" || mcpExisting.kind === "record" && cleanCursorMcp(mcpExisting.value).changed;
|
|
46845
|
+
const dirExists = existsSync10(res.cursorPluginDir);
|
|
46846
|
+
const actions = [];
|
|
46847
|
+
if (settingsDirty) {
|
|
46848
|
+
actions.push({
|
|
46849
|
+
kind: "edit-json-remove",
|
|
46850
|
+
path: res.cursorSettings,
|
|
46851
|
+
detail: "remove workit enabled_plugins/plugin_dirs entries from settings.json"
|
|
46852
|
+
});
|
|
46853
|
+
}
|
|
46854
|
+
if (mcpDirty) {
|
|
46855
|
+
actions.push({
|
|
46856
|
+
kind: "edit-json-remove",
|
|
46857
|
+
path: res.cursorMcp,
|
|
46858
|
+
detail: "remove the workit MCP server registration from mcp.json"
|
|
46859
|
+
});
|
|
46860
|
+
}
|
|
46861
|
+
if (dirExists) {
|
|
46862
|
+
actions.push({
|
|
46863
|
+
kind: "remove-dir",
|
|
46864
|
+
path: res.cursorPluginDir,
|
|
46865
|
+
detail: "delete the local workit plugin directory"
|
|
46866
|
+
});
|
|
46867
|
+
}
|
|
46868
|
+
const cursor4 = {
|
|
46869
|
+
host: "cursor",
|
|
46870
|
+
installed: settingsDirty || mcpDirty || dirExists,
|
|
46871
|
+
actions
|
|
46872
|
+
};
|
|
46873
|
+
return { hosts: [opencode, cursor4] };
|
|
46874
|
+
}
|
|
46875
|
+
var canonicalRemoveDirAllowed = (actionPath, res) => {
|
|
46876
|
+
const expected = path13.resolve(res.cursorPluginDir);
|
|
46877
|
+
if (!(actionPath === expected && path13.basename(expected) === "workit" && path13.basename(path13.dirname(expected)) === "local" && path13.basename(path13.dirname(path13.dirname(expected))) === "plugins")) {
|
|
46878
|
+
return false;
|
|
46879
|
+
}
|
|
46880
|
+
try {
|
|
46881
|
+
return realpathSync2(actionPath) === realpathSync2(expected);
|
|
46882
|
+
} catch {
|
|
46883
|
+
return true;
|
|
46884
|
+
}
|
|
46885
|
+
};
|
|
46886
|
+
var applyEditJsonRemove = (target, cleaner) => {
|
|
46887
|
+
const existing = readJsonRecord(target);
|
|
46888
|
+
if (existing.kind === "malformed") {
|
|
46889
|
+
return { status: "failed", detail: `${existing.error} — file untouched` };
|
|
46890
|
+
}
|
|
46891
|
+
if (existing.kind === "missing") {
|
|
46892
|
+
return { status: "skipped", detail: "file already absent" };
|
|
46893
|
+
}
|
|
46894
|
+
const { next, changed } = cleaner(existing.value);
|
|
46895
|
+
if (!changed)
|
|
46896
|
+
return { status: "skipped", detail: "no workit entries present" };
|
|
46897
|
+
const serialized = JSON.stringify(next, null, 2) + `
|
|
46898
|
+
`;
|
|
46899
|
+
let current;
|
|
46900
|
+
try {
|
|
46901
|
+
current = readFileSync9(target, "utf8");
|
|
46902
|
+
} catch (error) {
|
|
46903
|
+
return {
|
|
46904
|
+
status: "failed",
|
|
46905
|
+
detail: `read failed before write: ${error instanceof Error ? error.message : String(error)}`
|
|
46906
|
+
};
|
|
46907
|
+
}
|
|
46908
|
+
if (current === serialized) {
|
|
46909
|
+
return { status: "skipped", detail: "already clean" };
|
|
46910
|
+
}
|
|
46911
|
+
try {
|
|
46912
|
+
writeFileSync6(target, serialized, "utf8");
|
|
46913
|
+
} catch (error) {
|
|
46914
|
+
return {
|
|
46915
|
+
status: "failed",
|
|
46916
|
+
detail: `write failed: ${error instanceof Error ? error.message : String(error)}`
|
|
46917
|
+
};
|
|
46918
|
+
}
|
|
46919
|
+
return { status: "removed" };
|
|
46920
|
+
};
|
|
46921
|
+
function applyUninstall(plan, paths = {}) {
|
|
46922
|
+
const res = resolveUninstallPaths(paths);
|
|
46923
|
+
const entries = [];
|
|
46924
|
+
for (const hostPlan of plan.hosts) {
|
|
46925
|
+
for (const action of hostPlan.actions) {
|
|
46926
|
+
let status;
|
|
46927
|
+
let detail;
|
|
46928
|
+
if (action.kind === "remove-dir") {
|
|
46929
|
+
const resolved = path13.resolve(action.path);
|
|
46930
|
+
if (!canonicalRemoveDirAllowed(resolved, res)) {
|
|
46931
|
+
status = "failed";
|
|
46932
|
+
detail = `refusing to remove non-canonical plugin directory: ${resolved}`;
|
|
46933
|
+
} else if (!existsSync10(resolved)) {
|
|
46934
|
+
status = "skipped";
|
|
46935
|
+
detail = "directory already absent";
|
|
46936
|
+
} else {
|
|
46937
|
+
try {
|
|
46938
|
+
rmSync2(resolved, { recursive: true, force: true });
|
|
46939
|
+
status = "removed";
|
|
46940
|
+
} catch (error) {
|
|
46941
|
+
status = "failed";
|
|
46942
|
+
detail = error instanceof Error ? error.message : String(error);
|
|
46943
|
+
}
|
|
46944
|
+
}
|
|
46945
|
+
} else {
|
|
46946
|
+
const cleaner = jsonCleanerFor(action.path, res);
|
|
46947
|
+
if (cleaner === null) {
|
|
46948
|
+
status = "failed";
|
|
46949
|
+
detail = `${action.path} is not a recognized uninstall target for this host`;
|
|
46950
|
+
} else {
|
|
46951
|
+
const outcome = applyEditJsonRemove(action.path, cleaner);
|
|
46952
|
+
status = outcome.status;
|
|
46953
|
+
detail = outcome.detail;
|
|
46954
|
+
}
|
|
46955
|
+
}
|
|
46956
|
+
entries.push({ host: hostPlan.host, path: action.path, status, detail });
|
|
46957
|
+
}
|
|
46958
|
+
}
|
|
46959
|
+
return { ok: entries.every((e) => e.status !== "failed"), entries };
|
|
46960
|
+
}
|
|
46961
|
+
|
|
46427
46962
|
// packages/workit-cli/src/flow.ts
|
|
46428
46963
|
import { createInterface } from "node:readline/promises";
|
|
46429
|
-
import
|
|
46964
|
+
import path22 from "node:path";
|
|
46430
46965
|
|
|
46431
46966
|
// packages/workit-core/src/core/flow-state.ts
|
|
46432
46967
|
import {
|
|
46433
46968
|
closeSync,
|
|
46434
|
-
existsSync as
|
|
46969
|
+
existsSync as existsSync16,
|
|
46435
46970
|
fstatSync,
|
|
46436
46971
|
fsyncSync,
|
|
46437
46972
|
mkdirSync as mkdirSync8,
|
|
46438
46973
|
openSync,
|
|
46439
46974
|
readdirSync as readdirSync6,
|
|
46440
|
-
readFileSync as
|
|
46975
|
+
readFileSync as readFileSync14,
|
|
46441
46976
|
renameSync as renameSync3,
|
|
46442
|
-
rmSync as
|
|
46443
|
-
statSync as
|
|
46977
|
+
rmSync as rmSync4,
|
|
46978
|
+
statSync as statSync9,
|
|
46444
46979
|
unlinkSync as unlinkSync3,
|
|
46445
|
-
writeFileSync as
|
|
46980
|
+
writeFileSync as writeFileSync9
|
|
46446
46981
|
} from "node:fs";
|
|
46447
46982
|
import { createHash } from "node:crypto";
|
|
46448
|
-
import
|
|
46983
|
+
import path19 from "node:path";
|
|
46449
46984
|
|
|
46450
46985
|
// packages/workit-core/src/core/docs-validate.ts
|
|
46451
|
-
import { existsSync as
|
|
46986
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
46452
46987
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
46453
|
-
import
|
|
46988
|
+
import path15 from "node:path";
|
|
46454
46989
|
|
|
46455
46990
|
// packages/workit-core/src/core/docs-layout.ts
|
|
46456
|
-
import { existsSync as
|
|
46457
|
-
import
|
|
46991
|
+
import { existsSync as existsSync11, lstatSync, mkdirSync as mkdirSync5, realpathSync as realpathSync3, statSync as statSync5 } from "node:fs";
|
|
46992
|
+
import path14 from "node:path";
|
|
46458
46993
|
var SLUG_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
46459
46994
|
var LEGACY_SLUG = "superpowers";
|
|
46460
|
-
var posix = (p) => p.split(
|
|
46995
|
+
var posix = (p) => p.split(path14.sep).join("/");
|
|
46461
46996
|
var canonicalize = (base2, candidate) => {
|
|
46462
|
-
const abs =
|
|
46997
|
+
const abs = path14.resolve(base2, candidate);
|
|
46463
46998
|
let ancestor = abs;
|
|
46464
|
-
while (!
|
|
46465
|
-
ancestor =
|
|
46999
|
+
while (!existsSync11(ancestor))
|
|
47000
|
+
ancestor = path14.dirname(ancestor);
|
|
46466
47001
|
let real;
|
|
46467
47002
|
try {
|
|
46468
|
-
real =
|
|
47003
|
+
real = realpathSync3(ancestor);
|
|
46469
47004
|
} catch (error) {
|
|
46470
47005
|
if (error.code === "EACCES" && !lstatSync(ancestor).isSymbolicLink()) {
|
|
46471
|
-
real =
|
|
47006
|
+
real = path14.join(realpathSync3(path14.dirname(ancestor)), path14.basename(ancestor));
|
|
46472
47007
|
} else {
|
|
46473
47008
|
throw error;
|
|
46474
47009
|
}
|
|
46475
47010
|
}
|
|
46476
|
-
if (real !== base2 && !real.startsWith(base2 +
|
|
47011
|
+
if (real !== base2 && !real.startsWith(base2 + path14.sep)) {
|
|
46477
47012
|
throw new Error(`path must stay inside repository root: ${candidate}`);
|
|
46478
47013
|
}
|
|
46479
|
-
return
|
|
47014
|
+
return path14.join(real, path14.relative(ancestor, abs));
|
|
46480
47015
|
};
|
|
46481
47016
|
var buildLayout = (workspace, slug) => {
|
|
46482
47017
|
const docs = canonicalize(workspace, "docs");
|
|
46483
|
-
const dir = canonicalize(workspace,
|
|
47018
|
+
const dir = canonicalize(workspace, path14.join(docs, slug));
|
|
46484
47019
|
return {
|
|
46485
47020
|
workspace,
|
|
46486
47021
|
slug,
|
|
46487
47022
|
docs,
|
|
46488
47023
|
dir,
|
|
46489
|
-
spec:
|
|
46490
|
-
plan:
|
|
46491
|
-
sdd:
|
|
47024
|
+
spec: path14.join(dir, "spec.md"),
|
|
47025
|
+
plan: path14.join(dir, "plan.md"),
|
|
47026
|
+
sdd: path14.join(dir, "sdd")
|
|
46492
47027
|
};
|
|
46493
47028
|
};
|
|
46494
47029
|
var resolveCanonicalLayout = (input) => {
|
|
@@ -46497,7 +47032,7 @@ var resolveCanonicalLayout = (input) => {
|
|
|
46497
47032
|
return { ok: false, error: "workspace_root required" };
|
|
46498
47033
|
let workspace;
|
|
46499
47034
|
try {
|
|
46500
|
-
workspace =
|
|
47035
|
+
workspace = realpathSync3(path14.resolve(workspace_root));
|
|
46501
47036
|
} catch {
|
|
46502
47037
|
return { ok: false, error: `workspace root not found: ${workspace_root}` };
|
|
46503
47038
|
}
|
|
@@ -46508,7 +47043,7 @@ var resolveCanonicalLayout = (input) => {
|
|
|
46508
47043
|
]) {
|
|
46509
47044
|
if (!candidate)
|
|
46510
47045
|
continue;
|
|
46511
|
-
if (
|
|
47046
|
+
if (path14.isAbsolute(candidate)) {
|
|
46512
47047
|
return { ok: false, error: `absolute path not allowed: ${candidate}` };
|
|
46513
47048
|
}
|
|
46514
47049
|
const spelling = posix(candidate);
|
|
@@ -46529,7 +47064,7 @@ var resolveCanonicalLayout = (input) => {
|
|
|
46529
47064
|
if (match[2] !== kind) {
|
|
46530
47065
|
return {
|
|
46531
47066
|
ok: false,
|
|
46532
|
-
error: `wrong basename for ${kind}: expected ${kind}.md, got ${
|
|
47067
|
+
error: `wrong basename for ${kind}: expected ${kind}.md, got ${path14.basename(candidate)}`
|
|
46533
47068
|
};
|
|
46534
47069
|
}
|
|
46535
47070
|
if (derived && derived !== pathSlug) {
|
|
@@ -46545,7 +47080,7 @@ var resolveCanonicalLayout = (input) => {
|
|
|
46545
47080
|
} catch (error) {
|
|
46546
47081
|
return { ok: false, error: error instanceof Error ? error.message : String(error) };
|
|
46547
47082
|
}
|
|
46548
|
-
if (posix(
|
|
47083
|
+
if (posix(path14.relative(workspace, abs)) !== spelling) {
|
|
46549
47084
|
return {
|
|
46550
47085
|
ok: false,
|
|
46551
47086
|
error: `path must resolve to ${JSON.stringify(spelling)}: ${candidate}`
|
|
@@ -46578,18 +47113,18 @@ var resolveCanonicalLayout = (input) => {
|
|
|
46578
47113
|
}
|
|
46579
47114
|
};
|
|
46580
47115
|
var resolveDocsPath = (input) => {
|
|
46581
|
-
if (
|
|
47116
|
+
if (path14.isAbsolute(input.path)) {
|
|
46582
47117
|
return { ok: false, error: `absolute path not allowed: ${input.path}` };
|
|
46583
47118
|
}
|
|
46584
47119
|
let workspace;
|
|
46585
47120
|
try {
|
|
46586
|
-
workspace =
|
|
47121
|
+
workspace = realpathSync3(path14.resolve(input.workspace_root));
|
|
46587
47122
|
} catch {
|
|
46588
47123
|
return { ok: false, error: `workspace root not found: ${input.workspace_root}` };
|
|
46589
47124
|
}
|
|
46590
47125
|
try {
|
|
46591
47126
|
const abs = canonicalize(workspace, input.path);
|
|
46592
|
-
const relative = posix(
|
|
47127
|
+
const relative = posix(path14.relative(workspace, abs));
|
|
46593
47128
|
if (!relative.startsWith("docs/") || relative === `docs/${LEGACY_SLUG}` || relative.startsWith(`docs/${LEGACY_SLUG}/`)) {
|
|
46594
47129
|
return {
|
|
46595
47130
|
ok: false,
|
|
@@ -46606,10 +47141,10 @@ var resolveDocsPath = (input) => {
|
|
|
46606
47141
|
var BRANCH_RE = /^\s*\*+Branch:\*+\s*`?([^`\s|]+)`?\s*$/im;
|
|
46607
47142
|
var SPEC_LINK_RE = /^\s*\*+Spec:\*+\s*(?:`([^`]+)`|(\S+))\s*$/im;
|
|
46608
47143
|
var TASK_RE = /^###\s+Task\s+(\d+):\s*(.*)$/i;
|
|
46609
|
-
var err = (code, message,
|
|
47144
|
+
var err = (code, message, path16) => {
|
|
46610
47145
|
const item = { code, message };
|
|
46611
|
-
if (
|
|
46612
|
-
item.path =
|
|
47146
|
+
if (path16)
|
|
47147
|
+
item.path = path16;
|
|
46613
47148
|
return item;
|
|
46614
47149
|
};
|
|
46615
47150
|
var failValidate = (errors) => ({
|
|
@@ -46696,7 +47231,7 @@ var docsValidate = ({
|
|
|
46696
47231
|
const errors = [];
|
|
46697
47232
|
const read = (p) => {
|
|
46698
47233
|
try {
|
|
46699
|
-
return
|
|
47234
|
+
return readFileSync10(p, "utf8");
|
|
46700
47235
|
} catch {
|
|
46701
47236
|
return null;
|
|
46702
47237
|
}
|
|
@@ -46749,8 +47284,8 @@ var docsValidate = ({
|
|
|
46749
47284
|
return failValidate([err("task_order", `task mismatch at position ${i + 1}`, plan_path)]);
|
|
46750
47285
|
}
|
|
46751
47286
|
}
|
|
46752
|
-
const relSpec =
|
|
46753
|
-
const relPlan =
|
|
47287
|
+
const relSpec = path15.isAbsolute(spec_path) ? path15.relative(cwd2, specAbs) : spec_path;
|
|
47288
|
+
const relPlan = path15.isAbsolute(plan_path) ? path15.relative(cwd2, planAbs) : plan_path;
|
|
46754
47289
|
const quality = qualitySpec(specText);
|
|
46755
47290
|
if (!sddIgnored(cwd2, slug)) {
|
|
46756
47291
|
quality.push({
|
|
@@ -46881,8 +47416,8 @@ var qualitySpec = (text) => {
|
|
|
46881
47416
|
return findings;
|
|
46882
47417
|
};
|
|
46883
47418
|
var sddIgnored = (cwd2, slug) => {
|
|
46884
|
-
const sddDir =
|
|
46885
|
-
if (!
|
|
47419
|
+
const sddDir = path15.join(cwd2, "docs", slug, "sdd");
|
|
47420
|
+
if (!existsSync12(sddDir))
|
|
46886
47421
|
return true;
|
|
46887
47422
|
try {
|
|
46888
47423
|
execFileSync2("git", ["-C", cwd2, "rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
|
|
@@ -46890,7 +47425,7 @@ var sddIgnored = (cwd2, slug) => {
|
|
|
46890
47425
|
return true;
|
|
46891
47426
|
}
|
|
46892
47427
|
try {
|
|
46893
|
-
execFileSync2("git", ["-C", cwd2, "check-ignore",
|
|
47428
|
+
execFileSync2("git", ["-C", cwd2, "check-ignore", path15.posix.join("docs", slug, "sdd", "progress.md")], { stdio: "pipe" });
|
|
46894
47429
|
return true;
|
|
46895
47430
|
} catch {
|
|
46896
47431
|
return false;
|
|
@@ -46900,22 +47435,22 @@ var sddIgnored = (cwd2, slug) => {
|
|
|
46900
47435
|
// packages/workit-core/src/core/sdd.ts
|
|
46901
47436
|
import {
|
|
46902
47437
|
appendFileSync as appendFileSync2,
|
|
46903
|
-
existsSync as
|
|
47438
|
+
existsSync as existsSync13,
|
|
46904
47439
|
mkdirSync as mkdirSync6,
|
|
46905
|
-
readFileSync as
|
|
46906
|
-
statSync as
|
|
46907
|
-
writeFileSync as
|
|
47440
|
+
readFileSync as readFileSync11,
|
|
47441
|
+
statSync as statSync6,
|
|
47442
|
+
writeFileSync as writeFileSync7
|
|
46908
47443
|
} from "node:fs";
|
|
46909
47444
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
46910
|
-
import
|
|
46911
|
-
var posix2 = (p) => p.split(
|
|
47445
|
+
import path16 from "node:path";
|
|
47446
|
+
var posix2 = (p) => p.split(path16.sep).join("/");
|
|
46912
47447
|
function ledgerCompletion(root, slug) {
|
|
46913
47448
|
let started = false;
|
|
46914
47449
|
const completed = [];
|
|
46915
|
-
const absProgress =
|
|
46916
|
-
if (
|
|
47450
|
+
const absProgress = path16.join(root, "docs", slug, "sdd", "progress.md");
|
|
47451
|
+
if (existsSync13(absProgress)) {
|
|
46917
47452
|
try {
|
|
46918
|
-
for (const line of
|
|
47453
|
+
for (const line of readFileSync11(absProgress, "utf8").split(`
|
|
46919
47454
|
`)) {
|
|
46920
47455
|
const match = /^Task\s+(\d+):/i.exec(line);
|
|
46921
47456
|
if (match) {
|
|
@@ -46928,9 +47463,9 @@ function ledgerCompletion(root, slug) {
|
|
|
46928
47463
|
}
|
|
46929
47464
|
const required = [];
|
|
46930
47465
|
try {
|
|
46931
|
-
const absPlan =
|
|
46932
|
-
if (
|
|
46933
|
-
for (const task of parseTasksFromPlan(
|
|
47466
|
+
const absPlan = path16.join(root, "docs", slug, "plan.md");
|
|
47467
|
+
if (existsSync13(absPlan)) {
|
|
47468
|
+
for (const task of parseTasksFromPlan(readFileSync11(absPlan, "utf8")))
|
|
46934
47469
|
required.push(task.id);
|
|
46935
47470
|
}
|
|
46936
47471
|
} catch {}
|
|
@@ -46962,7 +47497,7 @@ function sddReviewPackage({
|
|
|
46962
47497
|
const dir = contained.path;
|
|
46963
47498
|
const base7 = base_sha.slice(0, 7);
|
|
46964
47499
|
const head7 = head_sha.slice(0, 7);
|
|
46965
|
-
const diffPath =
|
|
47500
|
+
const diffPath = path16.join(dir, `review-${base7}..${head7}.diff`);
|
|
46966
47501
|
try {
|
|
46967
47502
|
const diff2 = execFileSync3("git", ["diff", base_sha, head_sha], {
|
|
46968
47503
|
cwd: contained.base,
|
|
@@ -46976,8 +47511,8 @@ function sddReviewPackage({
|
|
|
46976
47511
|
};
|
|
46977
47512
|
}
|
|
46978
47513
|
mkdirSync6(dir, { recursive: true });
|
|
46979
|
-
|
|
46980
|
-
const rel = posix2(
|
|
47514
|
+
writeFileSync7(diffPath, diff2, "utf8");
|
|
47515
|
+
const rel = posix2(path16.relative(contained.base, diffPath));
|
|
46981
47516
|
return { diff_path: rel, base_sha, head_sha, base7, head7 };
|
|
46982
47517
|
} catch (error) {
|
|
46983
47518
|
return { error: error instanceof Error ? error.message : "git diff failed" };
|
|
@@ -47022,24 +47557,24 @@ function sddAppendAdvisory({
|
|
|
47022
47557
|
if (!contained.ok)
|
|
47023
47558
|
return { error: contained.error, code: "advisory_path_invalid" };
|
|
47024
47559
|
const abs = contained.path;
|
|
47025
|
-
if (
|
|
47560
|
+
if (existsSync13(abs) && statSync6(abs).isDirectory()) {
|
|
47026
47561
|
return {
|
|
47027
47562
|
error: `advisory target is a directory: ${advisories_path}`,
|
|
47028
47563
|
code: "advisory_target_invalid"
|
|
47029
47564
|
};
|
|
47030
47565
|
}
|
|
47031
|
-
mkdirSync6(
|
|
47566
|
+
mkdirSync6(path16.dirname(abs), { recursive: true });
|
|
47032
47567
|
const line = `- Task ${task_id}: ${collapsed}
|
|
47033
47568
|
`;
|
|
47034
47569
|
appendFileSync2(abs, line, "utf8");
|
|
47035
|
-
const rel = posix2(
|
|
47570
|
+
const rel = posix2(path16.relative(contained.base, abs));
|
|
47036
47571
|
return { ok: true, advisory: collapsed, advisories_path: rel };
|
|
47037
47572
|
}
|
|
47038
47573
|
|
|
47039
47574
|
// packages/workit-core/src/core/verify-project.ts
|
|
47040
47575
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
47041
|
-
import { existsSync as
|
|
47042
|
-
import
|
|
47576
|
+
import { existsSync as existsSync15, readFileSync as readFileSync13, statSync as statSync8 } from "node:fs";
|
|
47577
|
+
import path18 from "node:path";
|
|
47043
47578
|
|
|
47044
47579
|
// packages/workit-core/src/core/repo-context.ts
|
|
47045
47580
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
@@ -47048,16 +47583,16 @@ import { spawnSync as spawnSync3 } from "node:child_process";
|
|
|
47048
47583
|
import {
|
|
47049
47584
|
copyFileSync as copyFileSync3,
|
|
47050
47585
|
cpSync as cpSync3,
|
|
47051
|
-
existsSync as
|
|
47586
|
+
existsSync as existsSync14,
|
|
47052
47587
|
mkdirSync as mkdirSync7,
|
|
47053
|
-
readFileSync as
|
|
47588
|
+
readFileSync as readFileSync12,
|
|
47054
47589
|
readdirSync as readdirSync5,
|
|
47055
47590
|
renameSync as renameSync2,
|
|
47056
|
-
rmSync as
|
|
47057
|
-
statSync as
|
|
47058
|
-
writeFileSync as
|
|
47591
|
+
rmSync as rmSync3,
|
|
47592
|
+
statSync as statSync7,
|
|
47593
|
+
writeFileSync as writeFileSync8
|
|
47059
47594
|
} from "node:fs";
|
|
47060
|
-
import
|
|
47595
|
+
import path17 from "node:path";
|
|
47061
47596
|
|
|
47062
47597
|
// packages/workit-core/src/core/git.ts
|
|
47063
47598
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
@@ -47136,7 +47671,7 @@ var DECLARE_RE = /^\s*\*+Branch:\*+\s*`?([^`\s|]+)`?\s*$/gim;
|
|
|
47136
47671
|
var USE_CURRENT_RE = /^\s*\*+Branch:\*+\s*use-current\s*$/im;
|
|
47137
47672
|
var readSafe2 = (p) => {
|
|
47138
47673
|
try {
|
|
47139
|
-
return
|
|
47674
|
+
return readFileSync12(p, "utf8");
|
|
47140
47675
|
} catch {
|
|
47141
47676
|
return null;
|
|
47142
47677
|
}
|
|
@@ -47153,7 +47688,7 @@ var normalizeBranch = (root, name) => {
|
|
|
47153
47688
|
return parts.join("/");
|
|
47154
47689
|
};
|
|
47155
47690
|
var deriveSlug = (planPath) => {
|
|
47156
|
-
const dirName =
|
|
47691
|
+
const dirName = path17.basename(path17.dirname(planPath));
|
|
47157
47692
|
return dirName === "." || dirName === "/" || dirName === "" ? "" : dirName;
|
|
47158
47693
|
};
|
|
47159
47694
|
var deriveKind = (planPath, fallback = "feature") => {
|
|
@@ -47176,8 +47711,8 @@ var resolveBranch = ({
|
|
|
47176
47711
|
plan_path,
|
|
47177
47712
|
workspace_root
|
|
47178
47713
|
}) => {
|
|
47179
|
-
const cwd2 =
|
|
47180
|
-
const abs = (p) =>
|
|
47714
|
+
const cwd2 = path17.resolve(workspace_root);
|
|
47715
|
+
const abs = (p) => path17.isAbsolute(p) ? p : path17.join(cwd2, p);
|
|
47181
47716
|
const spec = abs(spec_path);
|
|
47182
47717
|
const plan = abs(plan_path);
|
|
47183
47718
|
const git = gitContext(cwd2);
|
|
@@ -47242,17 +47777,17 @@ var repoRoot2 = (cwd2) => {
|
|
|
47242
47777
|
|
|
47243
47778
|
// packages/workit-core/src/core/verify-project.ts
|
|
47244
47779
|
var commandOnPath2 = (name) => {
|
|
47245
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
47780
|
+
const dirs = (process.env.PATH ?? "").split(path18.delimiter);
|
|
47246
47781
|
const names = process.platform === "win32" ? [name, `${name}.exe`] : [name];
|
|
47247
47782
|
for (const dir of dirs) {
|
|
47248
47783
|
if (!dir)
|
|
47249
47784
|
continue;
|
|
47250
47785
|
for (const candidateName of names) {
|
|
47251
|
-
const candidate =
|
|
47786
|
+
const candidate = path18.join(dir, candidateName);
|
|
47252
47787
|
try {
|
|
47253
|
-
|
|
47788
|
+
statSync8(candidate);
|
|
47254
47789
|
if (process.platform !== "win32") {
|
|
47255
|
-
const mode =
|
|
47790
|
+
const mode = statSync8(candidate).mode & 73;
|
|
47256
47791
|
if (mode === 0)
|
|
47257
47792
|
continue;
|
|
47258
47793
|
}
|
|
@@ -47263,29 +47798,29 @@ var commandOnPath2 = (name) => {
|
|
|
47263
47798
|
return false;
|
|
47264
47799
|
};
|
|
47265
47800
|
var hasScript = (cwd2, name) => {
|
|
47266
|
-
const pkgPath =
|
|
47267
|
-
if (!
|
|
47801
|
+
const pkgPath = path18.join(cwd2, "package.json");
|
|
47802
|
+
if (!existsSync15(pkgPath))
|
|
47268
47803
|
return false;
|
|
47269
47804
|
try {
|
|
47270
|
-
const pkg = JSON.parse(
|
|
47805
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
|
|
47271
47806
|
return Boolean(pkg.scripts && typeof pkg.scripts[name] === "string");
|
|
47272
47807
|
} catch {
|
|
47273
47808
|
return false;
|
|
47274
47809
|
}
|
|
47275
47810
|
};
|
|
47276
47811
|
var packageRunner = (cwd2) => {
|
|
47277
|
-
if (
|
|
47812
|
+
if (existsSync15(path18.join(cwd2, "pnpm-lock.yaml")))
|
|
47278
47813
|
return "pnpm";
|
|
47279
|
-
const pkgPath =
|
|
47280
|
-
if (
|
|
47814
|
+
const pkgPath = path18.join(cwd2, "package.json");
|
|
47815
|
+
if (existsSync15(pkgPath)) {
|
|
47281
47816
|
try {
|
|
47282
|
-
const pkg = JSON.parse(
|
|
47817
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
|
|
47283
47818
|
if (typeof pkg.packageManager === "string" && pkg.packageManager.startsWith("pnpm")) {
|
|
47284
47819
|
return "pnpm";
|
|
47285
47820
|
}
|
|
47286
47821
|
} catch {}
|
|
47287
47822
|
}
|
|
47288
|
-
if (
|
|
47823
|
+
if (existsSync15(path18.join(cwd2, "yarn.lock")))
|
|
47289
47824
|
return "yarn";
|
|
47290
47825
|
return "npm";
|
|
47291
47826
|
};
|
|
@@ -47345,8 +47880,8 @@ root: ${cwd2}
|
|
|
47345
47880
|
`);
|
|
47346
47881
|
lines.push(`dry_run: ${String(dryRun)}
|
|
47347
47882
|
`);
|
|
47348
|
-
const pkgPath =
|
|
47349
|
-
if (
|
|
47883
|
+
const pkgPath = path18.join(cwd2, "package.json");
|
|
47884
|
+
if (existsSync15(pkgPath)) {
|
|
47350
47885
|
const runner = packageRunner(cwd2);
|
|
47351
47886
|
for (const script of ["lint", "format:check", "test", "build"]) {
|
|
47352
47887
|
if (hasScript(cwd2, script)) {
|
|
@@ -47361,7 +47896,7 @@ root: ${cwd2}
|
|
|
47361
47896
|
} else {
|
|
47362
47897
|
skipCheck("javascript", "package.json not found");
|
|
47363
47898
|
}
|
|
47364
|
-
const cargoManifest =
|
|
47899
|
+
const cargoManifest = existsSync15(path18.join(cwd2, "Cargo.toml")) ? "Cargo.toml" : existsSync15(path18.join(cwd2, "src-tauri/Cargo.toml")) ? "src-tauri/Cargo.toml" : "";
|
|
47365
47900
|
if (cargoManifest) {
|
|
47366
47901
|
runCheck("cargo fmt", "cargo", ["fmt", "--manifest-path", cargoManifest, "--", "--check"]);
|
|
47367
47902
|
runCheck("cargo clippy", "cargo", [
|
|
@@ -47377,7 +47912,7 @@ root: ${cwd2}
|
|
|
47377
47912
|
} else {
|
|
47378
47913
|
skipCheck("rust", "Cargo.toml not found");
|
|
47379
47914
|
}
|
|
47380
|
-
if (
|
|
47915
|
+
if (existsSync15(path18.join(cwd2, "pyproject.toml")) || existsSync15(path18.join(cwd2, "pytest.ini")) || existsSync15(path18.join(cwd2, "tests"))) {
|
|
47381
47916
|
if (commandOnPath2("pytest"))
|
|
47382
47917
|
runCheck("pytest", "pytest", []);
|
|
47383
47918
|
else
|
|
@@ -47394,13 +47929,13 @@ root: ${cwd2}
|
|
|
47394
47929
|
lines.push(`command: grep -qi "## [Unreleased]" CHANGELOG.md
|
|
47395
47930
|
|
|
47396
47931
|
`);
|
|
47397
|
-
const changelogPath =
|
|
47932
|
+
const changelogPath = path18.join(cwd2, "CHANGELOG.md");
|
|
47398
47933
|
if (dryRun) {
|
|
47399
47934
|
lines.push(`status: skipped (dry run)
|
|
47400
47935
|
`);
|
|
47401
47936
|
skipped += 1;
|
|
47402
|
-
} else if (
|
|
47403
|
-
if (/## \[Unreleased\]/i.test(
|
|
47937
|
+
} else if (existsSync15(changelogPath)) {
|
|
47938
|
+
if (/## \[Unreleased\]/i.test(readFileSync13(changelogPath, "utf8"))) {
|
|
47404
47939
|
lines.push(`status: pass
|
|
47405
47940
|
`);
|
|
47406
47941
|
passed += 1;
|
|
@@ -47453,7 +47988,7 @@ var SLUG_RE2 = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
|
47453
47988
|
var flowPath = (root, slug) => {
|
|
47454
47989
|
if (!SLUG_RE2.test(slug))
|
|
47455
47990
|
throw new Error(`invalid slug: ${JSON.stringify(slug)}`);
|
|
47456
|
-
return
|
|
47991
|
+
return path19.join(root, "docs", slug, "sdd", "flow.json");
|
|
47457
47992
|
};
|
|
47458
47993
|
var resolveDoc = (root, slug, docPath, kind) => {
|
|
47459
47994
|
const resolved = resolveCanonicalLayout({
|
|
@@ -47468,11 +48003,11 @@ var resolveDoc = (root, slug, docPath, kind) => {
|
|
|
47468
48003
|
var HEX64_RE = /^[0-9a-f]{64}$/;
|
|
47469
48004
|
var FLOW_STATUSES = ["draft", "self_reviewed", "approved"];
|
|
47470
48005
|
var EXECUTION_STATUSES = ["pending", "active", "paused", "completed"];
|
|
47471
|
-
var
|
|
48006
|
+
var isRecord4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
47472
48007
|
var validateEvidenceValue = (v, allowCli) => {
|
|
47473
48008
|
if (v === null)
|
|
47474
48009
|
return true;
|
|
47475
|
-
if (!
|
|
48010
|
+
if (!isRecord4(v))
|
|
47476
48011
|
return false;
|
|
47477
48012
|
if (v.host === "opencode") {
|
|
47478
48013
|
return v.attested === true && typeof v.callID === "string" && typeof v.selectedLabel === "string" && typeof v.recordedAt === "number";
|
|
@@ -47485,7 +48020,7 @@ var validateEvidenceValue = (v, allowCli) => {
|
|
|
47485
48020
|
return false;
|
|
47486
48021
|
};
|
|
47487
48022
|
var validateState = (parsed, slug) => {
|
|
47488
|
-
if (!
|
|
48023
|
+
if (!isRecord4(parsed))
|
|
47489
48024
|
return { ok: false, error: "flow state must be a JSON object" };
|
|
47490
48025
|
if (parsed.slug !== undefined && (typeof parsed.slug !== "string" || parsed.slug !== slug)) {
|
|
47491
48026
|
return { ok: false, error: `flow state slug must be ${JSON.stringify(slug)}` };
|
|
@@ -47500,8 +48035,8 @@ var validateState = (parsed, slug) => {
|
|
|
47500
48035
|
return { ok: false, error: "flow state updated_at must be a finite number" };
|
|
47501
48036
|
}
|
|
47502
48037
|
const doc = (value, name) => {
|
|
47503
|
-
const p =
|
|
47504
|
-
if (!
|
|
48038
|
+
const p = isRecord4(value) ? value : {};
|
|
48039
|
+
if (!isRecord4(value) && value !== undefined) {
|
|
47505
48040
|
return `flow state ${name} must be an object`;
|
|
47506
48041
|
}
|
|
47507
48042
|
if (p.status !== undefined && !FLOW_STATUSES.includes(p.status)) {
|
|
@@ -47529,8 +48064,8 @@ var validateState = (parsed, slug) => {
|
|
|
47529
48064
|
const plan = doc(parsed.plan, "plan");
|
|
47530
48065
|
if (typeof plan === "string")
|
|
47531
48066
|
return { ok: false, error: plan };
|
|
47532
|
-
const menuRaw =
|
|
47533
|
-
if (parsed.menu !== undefined && !
|
|
48067
|
+
const menuRaw = isRecord4(parsed.menu) ? parsed.menu : undefined;
|
|
48068
|
+
if (parsed.menu !== undefined && !isRecord4(parsed.menu)) {
|
|
47534
48069
|
return { ok: false, error: "flow state menu must be an object" };
|
|
47535
48070
|
}
|
|
47536
48071
|
if (menuRaw?.presented !== undefined && typeof menuRaw.presented !== "boolean") {
|
|
@@ -47548,8 +48083,8 @@ var validateState = (parsed, slug) => {
|
|
|
47548
48083
|
if (menuRaw?.evidence !== undefined && !validateEvidenceValue(menuRaw.evidence, false)) {
|
|
47549
48084
|
return { ok: false, error: "flow state menu.evidence has an unsupported shape" };
|
|
47550
48085
|
}
|
|
47551
|
-
const execRaw =
|
|
47552
|
-
if (parsed.execution !== undefined && !
|
|
48086
|
+
const execRaw = isRecord4(parsed.execution) ? parsed.execution : undefined;
|
|
48087
|
+
if (parsed.execution !== undefined && !isRecord4(parsed.execution)) {
|
|
47553
48088
|
return { ok: false, error: "flow state execution must be an object" };
|
|
47554
48089
|
}
|
|
47555
48090
|
if (execRaw?.status !== undefined && !EXECUTION_STATUSES.includes(execRaw.status)) {
|
|
@@ -47598,13 +48133,13 @@ var validateState = (parsed, slug) => {
|
|
|
47598
48133
|
};
|
|
47599
48134
|
var readFlowStrict = (root, slug) => {
|
|
47600
48135
|
const file = flowPath(root, slug);
|
|
47601
|
-
const rel =
|
|
47602
|
-
if (!
|
|
48136
|
+
const rel = path19.posix.join("docs", slug, "sdd", "flow.json");
|
|
48137
|
+
if (!existsSync16(file)) {
|
|
47603
48138
|
return err2("flow_not_activated", `flow not activated for ${slug} — run workit_flow_status first`);
|
|
47604
48139
|
}
|
|
47605
48140
|
let text;
|
|
47606
48141
|
try {
|
|
47607
|
-
text =
|
|
48142
|
+
text = readFileSync14(file, "utf8");
|
|
47608
48143
|
} catch (error) {
|
|
47609
48144
|
return err2("flow_io_error", `cannot read flow state at ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
47610
48145
|
}
|
|
@@ -47628,11 +48163,11 @@ var writeFlowFileAtomic = (file, state) => {
|
|
|
47628
48163
|
const text = JSON.stringify(state, null, 2) + `
|
|
47629
48164
|
`;
|
|
47630
48165
|
const tmp = uniqueTempPath(file);
|
|
47631
|
-
mkdirSync8(
|
|
48166
|
+
mkdirSync8(path19.dirname(file), { recursive: true });
|
|
47632
48167
|
let fd = null;
|
|
47633
48168
|
try {
|
|
47634
48169
|
fd = openSync(tmp, "w");
|
|
47635
|
-
|
|
48170
|
+
writeFileSync9(fd, text, "utf8");
|
|
47636
48171
|
fsyncSync(fd);
|
|
47637
48172
|
closeSync(fd);
|
|
47638
48173
|
fd = null;
|
|
@@ -47643,8 +48178,8 @@ var writeFlowFileAtomic = (file, state) => {
|
|
|
47643
48178
|
closeSync(fd);
|
|
47644
48179
|
} catch {}
|
|
47645
48180
|
try {
|
|
47646
|
-
if (
|
|
47647
|
-
|
|
48181
|
+
if (existsSync16(tmp))
|
|
48182
|
+
rmSync4(tmp, { force: true });
|
|
47648
48183
|
} catch {}
|
|
47649
48184
|
}
|
|
47650
48185
|
};
|
|
@@ -47652,14 +48187,14 @@ var MAX_WRITE_ATTEMPTS = 5;
|
|
|
47652
48187
|
var STALE_LOCK_MS = 1000;
|
|
47653
48188
|
var lockMtimeMs = (lock) => {
|
|
47654
48189
|
try {
|
|
47655
|
-
return
|
|
48190
|
+
return statSync9(lock).mtimeMs;
|
|
47656
48191
|
} catch {
|
|
47657
48192
|
return null;
|
|
47658
48193
|
}
|
|
47659
48194
|
};
|
|
47660
48195
|
var lockOwnedBy = (fd, lock) => {
|
|
47661
48196
|
try {
|
|
47662
|
-
return fstatSync(fd).ino ===
|
|
48197
|
+
return fstatSync(fd).ino === statSync9(lock).ino;
|
|
47663
48198
|
} catch {
|
|
47664
48199
|
return false;
|
|
47665
48200
|
}
|
|
@@ -47675,16 +48210,16 @@ var writeFlowStateIfCurrent = (root, expected, next) => {
|
|
|
47675
48210
|
const tmp = uniqueTempPath(file);
|
|
47676
48211
|
let fd = null;
|
|
47677
48212
|
try {
|
|
47678
|
-
const currentText =
|
|
48213
|
+
const currentText = existsSync16(file) ? readFileSync14(file, "utf8") : null;
|
|
47679
48214
|
if (currentText !== expectedText)
|
|
47680
48215
|
return { ok: false, conflict: true };
|
|
47681
|
-
mkdirSync8(
|
|
48216
|
+
mkdirSync8(path19.dirname(file), { recursive: true });
|
|
47682
48217
|
fd = openSync(tmp, "w");
|
|
47683
|
-
|
|
48218
|
+
writeFileSync9(fd, nextText, "utf8");
|
|
47684
48219
|
fsyncSync(fd);
|
|
47685
48220
|
closeSync(fd);
|
|
47686
48221
|
fd = null;
|
|
47687
|
-
const reRead =
|
|
48222
|
+
const reRead = existsSync16(file) ? readFileSync14(file, "utf8") : null;
|
|
47688
48223
|
if (reRead !== expectedText)
|
|
47689
48224
|
return { ok: false, conflict: true };
|
|
47690
48225
|
renameSync3(tmp, file);
|
|
@@ -47697,16 +48232,16 @@ var writeFlowStateIfCurrent = (root, expected, next) => {
|
|
|
47697
48232
|
closeSync(fd);
|
|
47698
48233
|
} catch {}
|
|
47699
48234
|
try {
|
|
47700
|
-
if (
|
|
47701
|
-
|
|
48235
|
+
if (existsSync16(tmp))
|
|
48236
|
+
rmSync4(tmp, { force: true });
|
|
47702
48237
|
} catch {}
|
|
47703
48238
|
}
|
|
47704
48239
|
};
|
|
47705
48240
|
var readCanonicalDigest = (root, rel) => {
|
|
47706
|
-
const abs =
|
|
48241
|
+
const abs = path19.join(root, ...rel.split("/"));
|
|
47707
48242
|
let bytes;
|
|
47708
48243
|
try {
|
|
47709
|
-
bytes =
|
|
48244
|
+
bytes = readFileSync14(abs);
|
|
47710
48245
|
} catch (error) {
|
|
47711
48246
|
if (error.code === "ENOENT") {
|
|
47712
48247
|
return { ok: false, code: "document_missing" };
|
|
@@ -47744,8 +48279,8 @@ var driftCodeFor = (root, relPath, storedDigest) => {
|
|
|
47744
48279
|
return current.digest !== storedDigest ? "digest_mismatch" : null;
|
|
47745
48280
|
};
|
|
47746
48281
|
var reconcileState = (root, slug, state) => {
|
|
47747
|
-
const specPath =
|
|
47748
|
-
const planPath =
|
|
48282
|
+
const specPath = path19.posix.join("docs", slug, "spec.md");
|
|
48283
|
+
const planPath = path19.posix.join("docs", slug, "plan.md");
|
|
47749
48284
|
if (state.spec.status === "approved") {
|
|
47750
48285
|
const code = driftCodeFor(root, specPath, state.spec.approved_digest);
|
|
47751
48286
|
if (code) {
|
|
@@ -47779,7 +48314,7 @@ var deriveLegacyExecution = (root, slug, state) => {
|
|
|
47779
48314
|
return { status: "pending", mode: null, evidence: null, coordinator_session_id: null };
|
|
47780
48315
|
};
|
|
47781
48316
|
var normalizeCompatibility = (root, slug, parsed, state) => {
|
|
47782
|
-
if (!
|
|
48317
|
+
if (!isRecord4(parsed) || !("execution" in parsed)) {
|
|
47783
48318
|
const derived = deriveLegacyExecution(root, slug, state);
|
|
47784
48319
|
const current = state.execution;
|
|
47785
48320
|
if (derived.status !== current.status || derived.mode !== current.mode) {
|
|
@@ -47787,7 +48322,7 @@ var normalizeCompatibility = (root, slug, parsed, state) => {
|
|
|
47787
48322
|
}
|
|
47788
48323
|
return { state, changed: false };
|
|
47789
48324
|
}
|
|
47790
|
-
const execRaw =
|
|
48325
|
+
const execRaw = isRecord4(parsed.execution) ? parsed.execution : undefined;
|
|
47791
48326
|
if (execRaw && !("coordinator_session_id" in execRaw)) {
|
|
47792
48327
|
return { state: { ...state, updated_at: Date.now() }, changed: true };
|
|
47793
48328
|
}
|
|
@@ -47795,11 +48330,11 @@ var normalizeCompatibility = (root, slug, parsed, state) => {
|
|
|
47795
48330
|
};
|
|
47796
48331
|
var withFlowLock = (file, fn) => {
|
|
47797
48332
|
const lock = `${file}.lock`;
|
|
47798
|
-
if (!
|
|
48333
|
+
if (!existsSync16(path19.dirname(file)))
|
|
47799
48334
|
return { locked: true, value: fn() };
|
|
47800
48335
|
try {
|
|
47801
|
-
if (
|
|
47802
|
-
|
|
48336
|
+
if (existsSync16(`${lock}.stale`))
|
|
48337
|
+
rmSync4(`${lock}.stale`, { force: true });
|
|
47803
48338
|
} catch {}
|
|
47804
48339
|
const wait = new Int32Array(new SharedArrayBuffer(4));
|
|
47805
48340
|
let fd = null;
|
|
@@ -47837,7 +48372,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47837
48372
|
if (attempt2 === MAX_WRITE_ATTEMPTS - 1) {
|
|
47838
48373
|
return {
|
|
47839
48374
|
locked: false,
|
|
47840
|
-
error: err2("flow_concurrent_conflict", `concurrent flow update detected for ${
|
|
48375
|
+
error: err2("flow_concurrent_conflict", `concurrent flow update detected for ${path19.dirname(file)}: re-read the flow state and retry the transition`)
|
|
47841
48376
|
};
|
|
47842
48377
|
}
|
|
47843
48378
|
Atomics.wait(wait, 0, 0, 10);
|
|
@@ -47846,7 +48381,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47846
48381
|
if (fd === null) {
|
|
47847
48382
|
return {
|
|
47848
48383
|
locked: false,
|
|
47849
|
-
error: err2("flow_concurrent_conflict", `concurrent flow update detected for ${
|
|
48384
|
+
error: err2("flow_concurrent_conflict", `concurrent flow update detected for ${path19.dirname(file)}: re-read the flow state and retry the transition`)
|
|
47850
48385
|
};
|
|
47851
48386
|
}
|
|
47852
48387
|
try {
|
|
@@ -47854,7 +48389,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47854
48389
|
} finally {
|
|
47855
48390
|
try {
|
|
47856
48391
|
if (fd !== null && lockOwnedBy(fd, lock))
|
|
47857
|
-
|
|
48392
|
+
rmSync4(lock, { force: true });
|
|
47858
48393
|
} catch {}
|
|
47859
48394
|
try {
|
|
47860
48395
|
if (fd !== null)
|
|
@@ -47864,7 +48399,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47864
48399
|
};
|
|
47865
48400
|
var readEffectiveFlowState = (root, slug) => {
|
|
47866
48401
|
const file = flowPath(root, slug);
|
|
47867
|
-
const rel =
|
|
48402
|
+
const rel = path19.posix.join("docs", slug, "sdd", "flow.json");
|
|
47868
48403
|
const locked = withFlowLock(file, () => {
|
|
47869
48404
|
const strict = readFlowStrict(root, slug);
|
|
47870
48405
|
if (!strict.ok)
|
|
@@ -48293,7 +48828,7 @@ var transitionExecution = (root, slug, planPath, action, evidence, ctx, deps) =>
|
|
|
48293
48828
|
});
|
|
48294
48829
|
};
|
|
48295
48830
|
var slugFromPath = (p) => {
|
|
48296
|
-
const dirName =
|
|
48831
|
+
const dirName = path19.basename(path19.dirname(p));
|
|
48297
48832
|
return dirName === "." || dirName === "/" || dirName === "" ? "" : dirName;
|
|
48298
48833
|
};
|
|
48299
48834
|
var assertSddControlGates = (root, slug, opts = {}, ctx) => {
|
|
@@ -48315,8 +48850,8 @@ var assertSddControlGates = (root, slug, opts = {}, ctx) => {
|
|
|
48315
48850
|
}
|
|
48316
48851
|
if (opts.requireDocs) {
|
|
48317
48852
|
const validated = docsValidate({
|
|
48318
|
-
spec_path:
|
|
48319
|
-
plan_path:
|
|
48853
|
+
spec_path: path19.posix.join("docs", slug, "spec.md"),
|
|
48854
|
+
plan_path: path19.posix.join("docs", slug, "plan.md"),
|
|
48320
48855
|
workspace_root: root
|
|
48321
48856
|
});
|
|
48322
48857
|
if (validated.ok === false)
|
|
@@ -48452,11 +48987,11 @@ var BASH_GIT_VALUE_FLAGS = new Set([
|
|
|
48452
48987
|
var COORDINATOR_SHELL_DENIED_TEXT = "Coordinator shell commands are restricted while a subagent-driven plan is " + "active: only bounded read/test/review commands are allowed (the exact " + "allowlist is in flow-state.ts, isCoordinatorBashAllowed). " + COORDINATOR_RECOVERY_TEXT;
|
|
48453
48988
|
|
|
48454
48989
|
// packages/workit-core/src/core/handoff-tools.ts
|
|
48455
|
-
import
|
|
48990
|
+
import path21 from "node:path";
|
|
48456
48991
|
|
|
48457
48992
|
// packages/workit-core/src/core/handoff-context.ts
|
|
48458
|
-
import { existsSync as
|
|
48459
|
-
import
|
|
48993
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
|
|
48994
|
+
import path20 from "node:path";
|
|
48460
48995
|
var DOC_RE = /docs\/([A-Za-z0-9][A-Za-z0-9._-]*)\/(spec|plan)\.md/g;
|
|
48461
48996
|
var listMd = (dir) => {
|
|
48462
48997
|
try {
|
|
@@ -48476,13 +49011,13 @@ var resolveFromMessagePaths = (root, message) => {
|
|
|
48476
49011
|
const slug = slugs[0];
|
|
48477
49012
|
const plan = `docs/${slug}/plan.md`;
|
|
48478
49013
|
const spec = `docs/${slug}/spec.md`;
|
|
48479
|
-
if (!
|
|
49014
|
+
if (!existsSync17(path20.join(root, plan)) || !existsSync17(path20.join(root, spec))) {
|
|
48480
49015
|
return { error: `docs/${slug}/ must contain both plan.md and spec.md` };
|
|
48481
49016
|
}
|
|
48482
49017
|
return { spec, plan, source: "message_paths" };
|
|
48483
49018
|
};
|
|
48484
49019
|
var resolveActivePair = (root) => {
|
|
48485
|
-
const docsDir =
|
|
49020
|
+
const docsDir = path20.join(root, "docs");
|
|
48486
49021
|
let best = null;
|
|
48487
49022
|
let entries = [];
|
|
48488
49023
|
try {
|
|
@@ -48493,11 +49028,11 @@ var resolveActivePair = (root) => {
|
|
|
48493
49028
|
for (const slug of entries) {
|
|
48494
49029
|
if (slug.startsWith("."))
|
|
48495
49030
|
continue;
|
|
48496
|
-
const plan =
|
|
48497
|
-
const spec =
|
|
48498
|
-
if (!
|
|
49031
|
+
const plan = path20.join("docs", slug, "plan.md");
|
|
49032
|
+
const spec = path20.join("docs", slug, "spec.md");
|
|
49033
|
+
if (!existsSync17(path20.join(root, plan)) || !existsSync17(path20.join(root, spec)))
|
|
48499
49034
|
continue;
|
|
48500
|
-
const score = Math.max(
|
|
49035
|
+
const score = Math.max(statSync10(path20.join(root, spec)).mtimeMs, statSync10(path20.join(root, plan)).mtimeMs);
|
|
48501
49036
|
if (best === null || score > best.score || score === best.score && slug < best.spec.split("/")[1]) {
|
|
48502
49037
|
best = { score, spec, plan, source: "active_pair" };
|
|
48503
49038
|
}
|
|
@@ -48515,8 +49050,8 @@ var resolveWorkflowPaths = (root, message) => {
|
|
|
48515
49050
|
const active = resolveActivePair(root);
|
|
48516
49051
|
if (!("error" in active))
|
|
48517
49052
|
return active;
|
|
48518
|
-
const docsDir =
|
|
48519
|
-
if (!
|
|
49053
|
+
const docsDir = path20.join(root, "docs");
|
|
49054
|
+
if (!existsSync17(docsDir) || listMd(docsDir).length === 0) {
|
|
48520
49055
|
return { error: "no docs/<slug>/ features found under docs/" };
|
|
48521
49056
|
}
|
|
48522
49057
|
return {
|
|
@@ -48540,15 +49075,15 @@ ${JSON.stringify({ ok: false, errors: validated.errors })}`
|
|
|
48540
49075
|
if ("error" in branchResolved)
|
|
48541
49076
|
return { error: branchResolved.error };
|
|
48542
49077
|
const branch = branchResolved.branch;
|
|
48543
|
-
const slug =
|
|
49078
|
+
const slug = path20.basename(path20.dirname(plan));
|
|
48544
49079
|
const sddDir = `docs/${slug}/sdd`;
|
|
48545
|
-
const planText =
|
|
49080
|
+
const planText = readFileSync15(path20.join(root, plan), "utf8");
|
|
48546
49081
|
const tasks = parseTasksFromPlan(planText);
|
|
48547
49082
|
const taskList = tasks.map((t) => `- Task ${t.id}: ${t.title}`).join(`
|
|
48548
49083
|
`);
|
|
48549
49084
|
let contract;
|
|
48550
49085
|
try {
|
|
48551
|
-
contract =
|
|
49086
|
+
contract = readFileSync15(templatePath, "utf8");
|
|
48552
49087
|
} catch {
|
|
48553
49088
|
return { error: "missing template templates/execution-contract.md" };
|
|
48554
49089
|
}
|
|
@@ -48564,7 +49099,7 @@ var buildHandoffPrompt = (root, message) => {
|
|
|
48564
49099
|
const resolved = resolveWorkflowPaths(root, message);
|
|
48565
49100
|
if ("error" in resolved)
|
|
48566
49101
|
return { error: resolved.error };
|
|
48567
|
-
const templatePath =
|
|
49102
|
+
const templatePath = path21.join(assetRoot(), "templates", "execution-contract.md");
|
|
48568
49103
|
const contract = buildHandoffContract({
|
|
48569
49104
|
root,
|
|
48570
49105
|
spec: resolved.spec,
|
|
@@ -48573,7 +49108,7 @@ var buildHandoffPrompt = (root, message) => {
|
|
|
48573
49108
|
});
|
|
48574
49109
|
if ("error" in contract)
|
|
48575
49110
|
return { error: contract.error };
|
|
48576
|
-
const sdd = `docs/${
|
|
49111
|
+
const sdd = `docs/${path21.basename(path21.dirname(resolved.plan))}/sdd`;
|
|
48577
49112
|
return { prompt: contract.prompt, spec: resolved.spec, plan: resolved.plan, sdd };
|
|
48578
49113
|
};
|
|
48579
49114
|
|
|
@@ -48761,7 +49296,7 @@ function statusCommand(root, plan, out, err3) {
|
|
|
48761
49296
|
execution: state.execution,
|
|
48762
49297
|
handoff_destination: state.handoff_destination,
|
|
48763
49298
|
drift,
|
|
48764
|
-
flow_path:
|
|
49299
|
+
flow_path: path22.posix.join("docs", state.slug, "sdd", "flow.json")
|
|
48765
49300
|
});
|
|
48766
49301
|
return 0;
|
|
48767
49302
|
}
|
|
@@ -48788,7 +49323,7 @@ function reviewPackageCommand(root, parsed, out, err3) {
|
|
|
48788
49323
|
if (!resolved.ok)
|
|
48789
49324
|
return domainFail(err3, "path_invalid", resolved.error);
|
|
48790
49325
|
const result2 = sddReviewPackage({
|
|
48791
|
-
sdd_dir:
|
|
49326
|
+
sdd_dir: path22.posix.join("docs", resolved.layout.slug, "sdd"),
|
|
48792
49327
|
base_sha: parsed.base,
|
|
48793
49328
|
head_sha: parsed.head,
|
|
48794
49329
|
workspace_root: root
|
|
@@ -48815,7 +49350,7 @@ function appendAdvisoryCommand(root, parsed, out, err3) {
|
|
|
48815
49350
|
const trimmed = parsed.task.trim();
|
|
48816
49351
|
const taskId = /^-?\d+(\.\d+)?$/.test(trimmed) ? Number(trimmed) : trimmed;
|
|
48817
49352
|
const result2 = sddAppendAdvisory({
|
|
48818
|
-
advisories_path:
|
|
49353
|
+
advisories_path: path22.posix.join("docs", slug, "sdd", "advisories.md"),
|
|
48819
49354
|
task_id: taskId,
|
|
48820
49355
|
text: parsed.text,
|
|
48821
49356
|
workspace_root: root
|
|
@@ -48873,7 +49408,7 @@ async function runHandoffCommand(argv, deps = {}) {
|
|
|
48873
49408
|
}
|
|
48874
49409
|
|
|
48875
49410
|
// packages/workit-cli/src/index.tsx
|
|
48876
|
-
var
|
|
49411
|
+
var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
|
|
48877
49412
|
var logger = createLogger({
|
|
48878
49413
|
stderr: (event) => {
|
|
48879
49414
|
if (event.level === "debug" || event.level === "info")
|
|
@@ -48897,6 +49432,7 @@ var HELP = `workit — workflow rails for agentic coding
|
|
|
48897
49432
|
Usage:
|
|
48898
49433
|
workit init Run the interactive setup wizard
|
|
48899
49434
|
workit doctor Verify the offline installation health (add --json for a machine-readable report)
|
|
49435
|
+
workit uninstall Remove workit host registrations interactively (~/.config/workit is kept)
|
|
48900
49436
|
${COMMAND_DESCRIPTIONS.map(([cmd, desc]) => ` ${cmd.padEnd(helpColumn)}${desc}`).join(`
|
|
48901
49437
|
`)}
|
|
48902
49438
|
workit Show this help
|
|
@@ -48924,10 +49460,12 @@ function printMalformedBlocked(state) {
|
|
|
48924
49460
|
async function runInit() {
|
|
48925
49461
|
const state = readSetupState();
|
|
48926
49462
|
if (state.config.status === "malformed") {
|
|
49463
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
48927
49464
|
printMalformedBlocked(state);
|
|
48928
49465
|
process.exit(1);
|
|
48929
49466
|
}
|
|
48930
49467
|
if (process.stdin.isTTY !== true) {
|
|
49468
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
48931
49469
|
console.log("workit init requires an interactive terminal (TTY).");
|
|
48932
49470
|
for (const line of setupCompletionGuidance())
|
|
48933
49471
|
console.log(line);
|
|
@@ -48936,25 +49474,32 @@ async function runInit() {
|
|
|
48936
49474
|
logger.info(EVENT.installSteps, { step: "wizard_start" });
|
|
48937
49475
|
const exits = [];
|
|
48938
49476
|
let done = () => {};
|
|
48939
|
-
|
|
49477
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
49478
|
+
const instance = render_default(/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Wizard, {
|
|
48940
49479
|
onExit: (complete, values2) => {
|
|
48941
49480
|
exits.push({ complete, values: values2 });
|
|
48942
49481
|
done();
|
|
48943
49482
|
}
|
|
48944
|
-
}, undefined, false, undefined, this));
|
|
48945
|
-
done = unmount;
|
|
48946
|
-
|
|
49483
|
+
}, undefined, false, undefined, this), { interactive: true });
|
|
49484
|
+
done = instance.unmount;
|
|
49485
|
+
try {
|
|
49486
|
+
await instance.waitUntilExit();
|
|
49487
|
+
} finally {
|
|
49488
|
+
instance.unmount();
|
|
49489
|
+
}
|
|
49490
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
48947
49491
|
const exit = exits[0];
|
|
48948
49492
|
if (exit && exit.complete && exit.values) {
|
|
48949
|
-
const
|
|
49493
|
+
const base2 = resolveBasePath(exit.values);
|
|
49494
|
+
const preview = buildSetupPreview(exit.values, { cwd: base2, env: process.env });
|
|
48950
49495
|
if (!preview.ok) {
|
|
48951
49496
|
printMalformedBlocked(preview.state);
|
|
48952
49497
|
process.exit(1);
|
|
48953
49498
|
}
|
|
48954
|
-
const result2 = applySetupPreview(preview, { cwd:
|
|
49499
|
+
const result2 = applySetupPreview(preview, { cwd: base2, env: process.env });
|
|
48955
49500
|
let exitCode = result2.exitCode;
|
|
48956
49501
|
if (exit.values.branchPolicy) {
|
|
48957
|
-
const bp = applyWizardBranchPolicy(exit.values.branchPolicy,
|
|
49502
|
+
const bp = applyWizardBranchPolicy(exit.values.branchPolicy, base2, process.env);
|
|
48958
49503
|
if (bp.ok) {
|
|
48959
49504
|
console.log(`${String(bp.status).padEnd(11)} ${bp.config_path} — branch policy`);
|
|
48960
49505
|
} else {
|
|
@@ -48972,6 +49517,111 @@ async function runInit() {
|
|
|
48972
49517
|
});
|
|
48973
49518
|
process.exit(exit !== undefined && exit.complete ? 0 : 1);
|
|
48974
49519
|
}
|
|
49520
|
+
var UNINSTALL_HOST_OPTIONS = [
|
|
49521
|
+
{ label: "OpenCode", value: "opencode" },
|
|
49522
|
+
{ label: "Cursor", value: "cursor" }
|
|
49523
|
+
];
|
|
49524
|
+
function UninstallWizard({ onExit }) {
|
|
49525
|
+
const [hosts, setHosts] = import_react67.useState([]);
|
|
49526
|
+
const [plan, setPlan] = import_react67.useState(null);
|
|
49527
|
+
if (!plan) {
|
|
49528
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
49529
|
+
flexDirection: "column",
|
|
49530
|
+
gap: 1,
|
|
49531
|
+
children: [
|
|
49532
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
49533
|
+
bold: true,
|
|
49534
|
+
children: "Uninstall workit"
|
|
49535
|
+
}, undefined, false, undefined, this),
|
|
49536
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
49537
|
+
dimColor: true,
|
|
49538
|
+
children: "Select the hosts to remove workit from (space to toggle):"
|
|
49539
|
+
}, undefined, false, undefined, this),
|
|
49540
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(MultiSelect, {
|
|
49541
|
+
options: UNINSTALL_HOST_OPTIONS,
|
|
49542
|
+
defaultValue: [],
|
|
49543
|
+
onChange: (values2) => setHosts(values2),
|
|
49544
|
+
onSubmit: (values2) => {
|
|
49545
|
+
setHosts(values2);
|
|
49546
|
+
setPlan(planUninstall({ env: process.env }));
|
|
49547
|
+
}
|
|
49548
|
+
}, undefined, false, undefined, this),
|
|
49549
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
49550
|
+
dimColor: true,
|
|
49551
|
+
children: "Enter to continue"
|
|
49552
|
+
}, undefined, false, undefined, this)
|
|
49553
|
+
]
|
|
49554
|
+
}, undefined, true, undefined, this);
|
|
49555
|
+
}
|
|
49556
|
+
const selected = plan.hosts.filter((h) => hosts.includes(h.host));
|
|
49557
|
+
const reviewed = { hosts: selected };
|
|
49558
|
+
return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
49559
|
+
flexDirection: "column",
|
|
49560
|
+
gap: 1,
|
|
49561
|
+
children: [
|
|
49562
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
49563
|
+
bold: true,
|
|
49564
|
+
children: "Uninstall workit — review"
|
|
49565
|
+
}, undefined, false, undefined, this),
|
|
49566
|
+
selected.every((h) => h.actions.length === 0) ? /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
49567
|
+
children: "No workit registrations found for the selected hosts."
|
|
49568
|
+
}, undefined, false, undefined, this) : selected.flatMap((h) => h.actions.map((a) => /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
49569
|
+
children: [
|
|
49570
|
+
"• [",
|
|
49571
|
+
h.host,
|
|
49572
|
+
"] ",
|
|
49573
|
+
a.detail,
|
|
49574
|
+
": ",
|
|
49575
|
+
a.path
|
|
49576
|
+
]
|
|
49577
|
+
}, `${h.host}:${a.path}`, true, undefined, this))),
|
|
49578
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
49579
|
+
children: "Apply uninstall? (y/N)"
|
|
49580
|
+
}, undefined, false, undefined, this),
|
|
49581
|
+
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(ConfirmInput, {
|
|
49582
|
+
onConfirm: () => onExit({ confirmed: true, hosts, plan: reviewed }),
|
|
49583
|
+
onCancel: () => onExit({ confirmed: false, hosts, plan: reviewed })
|
|
49584
|
+
}, undefined, false, undefined, this)
|
|
49585
|
+
]
|
|
49586
|
+
}, undefined, true, undefined, this);
|
|
49587
|
+
}
|
|
49588
|
+
async function runUninstall() {
|
|
49589
|
+
if (process.stdin.isTTY !== true) {
|
|
49590
|
+
console.log("workit uninstall requires an interactive terminal (TTY).");
|
|
49591
|
+
console.log("It removes workit registrations from OpenCode and/or Cursor; your ~/.config/workit configuration is always kept.");
|
|
49592
|
+
process.exit(2);
|
|
49593
|
+
}
|
|
49594
|
+
const outcomes = [];
|
|
49595
|
+
let done = () => {};
|
|
49596
|
+
const instance = render_default(/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(UninstallWizard, {
|
|
49597
|
+
onExit: (outcome2) => {
|
|
49598
|
+
outcomes.push(outcome2);
|
|
49599
|
+
done();
|
|
49600
|
+
}
|
|
49601
|
+
}, undefined, false, undefined, this), { interactive: true });
|
|
49602
|
+
done = instance.unmount;
|
|
49603
|
+
try {
|
|
49604
|
+
await instance.waitUntilExit();
|
|
49605
|
+
} finally {
|
|
49606
|
+
instance.unmount();
|
|
49607
|
+
}
|
|
49608
|
+
const outcome = outcomes[0];
|
|
49609
|
+
if (!outcome || !outcome.confirmed || !outcome.plan) {
|
|
49610
|
+
console.log("Uninstall cancelled — nothing was changed.");
|
|
49611
|
+
process.exit(0);
|
|
49612
|
+
}
|
|
49613
|
+
const actions = outcome.plan.hosts.flatMap((h) => h.actions);
|
|
49614
|
+
if (actions.length === 0) {
|
|
49615
|
+
console.log("Nothing to remove for the selected hosts.");
|
|
49616
|
+
process.exit(0);
|
|
49617
|
+
}
|
|
49618
|
+
const result2 = applyUninstall(outcome.plan, { env: process.env });
|
|
49619
|
+
for (const entry of result2.entries) {
|
|
49620
|
+
console.log(`${entry.status.padEnd(8)} ${entry.path}${entry.detail ? ` — ${entry.detail}` : ""}`);
|
|
49621
|
+
}
|
|
49622
|
+
console.log(result2.ok ? "Uninstall complete." : "Uninstall finished with problems.");
|
|
49623
|
+
process.exit(result2.ok ? 0 : 1);
|
|
49624
|
+
}
|
|
48975
49625
|
function runDoctorCommand(args) {
|
|
48976
49626
|
const report = runDoctor({ host: "cli", cwd: process.cwd() });
|
|
48977
49627
|
if (args.includes("--json")) {
|
|
@@ -49006,11 +49656,15 @@ if (__require.main == __require.module) {
|
|
|
49006
49656
|
process.exit(await runFlowCommand(args.slice(1)));
|
|
49007
49657
|
} else if (subcommand === "handoff") {
|
|
49008
49658
|
process.exit(await runHandoffCommand(args.slice(1)));
|
|
49659
|
+
} else if (subcommand === "uninstall") {
|
|
49660
|
+
await runUninstall();
|
|
49009
49661
|
} else {
|
|
49010
49662
|
console.log(HELP);
|
|
49011
49663
|
process.exit(0);
|
|
49012
49664
|
}
|
|
49013
49665
|
}
|
|
49014
49666
|
export {
|
|
49667
|
+
runUninstall,
|
|
49668
|
+
runInit,
|
|
49015
49669
|
logger
|
|
49016
49670
|
};
|