@brainervirus/workit-cli 0.9.0 → 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 +1060 -395
- 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
|
-
readdirSync as
|
|
46440
|
-
readFileSync as
|
|
46441
|
-
renameSync as
|
|
46442
|
-
rmSync as
|
|
46443
|
-
statSync as
|
|
46974
|
+
readdirSync as readdirSync6,
|
|
46975
|
+
readFileSync as readFileSync14,
|
|
46976
|
+
renameSync as renameSync3,
|
|
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,31 +47557,42 @@ 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";
|
|
47046
47581
|
|
|
47047
47582
|
// packages/workit-core/src/core/branch.ts
|
|
47048
|
-
import {
|
|
47049
|
-
|
|
47583
|
+
import {
|
|
47584
|
+
copyFileSync as copyFileSync3,
|
|
47585
|
+
cpSync as cpSync3,
|
|
47586
|
+
existsSync as existsSync14,
|
|
47587
|
+
mkdirSync as mkdirSync7,
|
|
47588
|
+
readFileSync as readFileSync12,
|
|
47589
|
+
readdirSync as readdirSync5,
|
|
47590
|
+
renameSync as renameSync2,
|
|
47591
|
+
rmSync as rmSync3,
|
|
47592
|
+
statSync as statSync7,
|
|
47593
|
+
writeFileSync as writeFileSync8
|
|
47594
|
+
} from "node:fs";
|
|
47595
|
+
import path17 from "node:path";
|
|
47050
47596
|
|
|
47051
47597
|
// packages/workit-core/src/core/git.ts
|
|
47052
47598
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
@@ -47125,7 +47671,7 @@ var DECLARE_RE = /^\s*\*+Branch:\*+\s*`?([^`\s|]+)`?\s*$/gim;
|
|
|
47125
47671
|
var USE_CURRENT_RE = /^\s*\*+Branch:\*+\s*use-current\s*$/im;
|
|
47126
47672
|
var readSafe2 = (p) => {
|
|
47127
47673
|
try {
|
|
47128
|
-
return
|
|
47674
|
+
return readFileSync12(p, "utf8");
|
|
47129
47675
|
} catch {
|
|
47130
47676
|
return null;
|
|
47131
47677
|
}
|
|
@@ -47142,7 +47688,7 @@ var normalizeBranch = (root, name) => {
|
|
|
47142
47688
|
return parts.join("/");
|
|
47143
47689
|
};
|
|
47144
47690
|
var deriveSlug = (planPath) => {
|
|
47145
|
-
const dirName =
|
|
47691
|
+
const dirName = path17.basename(path17.dirname(planPath));
|
|
47146
47692
|
return dirName === "." || dirName === "/" || dirName === "" ? "" : dirName;
|
|
47147
47693
|
};
|
|
47148
47694
|
var deriveKind = (planPath, fallback = "feature") => {
|
|
@@ -47165,8 +47711,8 @@ var resolveBranch = ({
|
|
|
47165
47711
|
plan_path,
|
|
47166
47712
|
workspace_root
|
|
47167
47713
|
}) => {
|
|
47168
|
-
const cwd2 =
|
|
47169
|
-
const abs = (p) =>
|
|
47714
|
+
const cwd2 = path17.resolve(workspace_root);
|
|
47715
|
+
const abs = (p) => path17.isAbsolute(p) ? p : path17.join(cwd2, p);
|
|
47170
47716
|
const spec = abs(spec_path);
|
|
47171
47717
|
const plan = abs(plan_path);
|
|
47172
47718
|
const git = gitContext(cwd2);
|
|
@@ -47231,17 +47777,17 @@ var repoRoot2 = (cwd2) => {
|
|
|
47231
47777
|
|
|
47232
47778
|
// packages/workit-core/src/core/verify-project.ts
|
|
47233
47779
|
var commandOnPath2 = (name) => {
|
|
47234
|
-
const dirs = (process.env.PATH ?? "").split(
|
|
47780
|
+
const dirs = (process.env.PATH ?? "").split(path18.delimiter);
|
|
47235
47781
|
const names = process.platform === "win32" ? [name, `${name}.exe`] : [name];
|
|
47236
47782
|
for (const dir of dirs) {
|
|
47237
47783
|
if (!dir)
|
|
47238
47784
|
continue;
|
|
47239
47785
|
for (const candidateName of names) {
|
|
47240
|
-
const candidate =
|
|
47786
|
+
const candidate = path18.join(dir, candidateName);
|
|
47241
47787
|
try {
|
|
47242
|
-
|
|
47788
|
+
statSync8(candidate);
|
|
47243
47789
|
if (process.platform !== "win32") {
|
|
47244
|
-
const mode =
|
|
47790
|
+
const mode = statSync8(candidate).mode & 73;
|
|
47245
47791
|
if (mode === 0)
|
|
47246
47792
|
continue;
|
|
47247
47793
|
}
|
|
@@ -47252,29 +47798,29 @@ var commandOnPath2 = (name) => {
|
|
|
47252
47798
|
return false;
|
|
47253
47799
|
};
|
|
47254
47800
|
var hasScript = (cwd2, name) => {
|
|
47255
|
-
const pkgPath =
|
|
47256
|
-
if (!
|
|
47801
|
+
const pkgPath = path18.join(cwd2, "package.json");
|
|
47802
|
+
if (!existsSync15(pkgPath))
|
|
47257
47803
|
return false;
|
|
47258
47804
|
try {
|
|
47259
|
-
const pkg = JSON.parse(
|
|
47805
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
|
|
47260
47806
|
return Boolean(pkg.scripts && typeof pkg.scripts[name] === "string");
|
|
47261
47807
|
} catch {
|
|
47262
47808
|
return false;
|
|
47263
47809
|
}
|
|
47264
47810
|
};
|
|
47265
47811
|
var packageRunner = (cwd2) => {
|
|
47266
|
-
if (
|
|
47812
|
+
if (existsSync15(path18.join(cwd2, "pnpm-lock.yaml")))
|
|
47267
47813
|
return "pnpm";
|
|
47268
|
-
const pkgPath =
|
|
47269
|
-
if (
|
|
47814
|
+
const pkgPath = path18.join(cwd2, "package.json");
|
|
47815
|
+
if (existsSync15(pkgPath)) {
|
|
47270
47816
|
try {
|
|
47271
|
-
const pkg = JSON.parse(
|
|
47817
|
+
const pkg = JSON.parse(readFileSync13(pkgPath, "utf8"));
|
|
47272
47818
|
if (typeof pkg.packageManager === "string" && pkg.packageManager.startsWith("pnpm")) {
|
|
47273
47819
|
return "pnpm";
|
|
47274
47820
|
}
|
|
47275
47821
|
} catch {}
|
|
47276
47822
|
}
|
|
47277
|
-
if (
|
|
47823
|
+
if (existsSync15(path18.join(cwd2, "yarn.lock")))
|
|
47278
47824
|
return "yarn";
|
|
47279
47825
|
return "npm";
|
|
47280
47826
|
};
|
|
@@ -47334,8 +47880,8 @@ root: ${cwd2}
|
|
|
47334
47880
|
`);
|
|
47335
47881
|
lines.push(`dry_run: ${String(dryRun)}
|
|
47336
47882
|
`);
|
|
47337
|
-
const pkgPath =
|
|
47338
|
-
if (
|
|
47883
|
+
const pkgPath = path18.join(cwd2, "package.json");
|
|
47884
|
+
if (existsSync15(pkgPath)) {
|
|
47339
47885
|
const runner = packageRunner(cwd2);
|
|
47340
47886
|
for (const script of ["lint", "format:check", "test", "build"]) {
|
|
47341
47887
|
if (hasScript(cwd2, script)) {
|
|
@@ -47350,7 +47896,7 @@ root: ${cwd2}
|
|
|
47350
47896
|
} else {
|
|
47351
47897
|
skipCheck("javascript", "package.json not found");
|
|
47352
47898
|
}
|
|
47353
|
-
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" : "";
|
|
47354
47900
|
if (cargoManifest) {
|
|
47355
47901
|
runCheck("cargo fmt", "cargo", ["fmt", "--manifest-path", cargoManifest, "--", "--check"]);
|
|
47356
47902
|
runCheck("cargo clippy", "cargo", [
|
|
@@ -47366,7 +47912,7 @@ root: ${cwd2}
|
|
|
47366
47912
|
} else {
|
|
47367
47913
|
skipCheck("rust", "Cargo.toml not found");
|
|
47368
47914
|
}
|
|
47369
|
-
if (
|
|
47915
|
+
if (existsSync15(path18.join(cwd2, "pyproject.toml")) || existsSync15(path18.join(cwd2, "pytest.ini")) || existsSync15(path18.join(cwd2, "tests"))) {
|
|
47370
47916
|
if (commandOnPath2("pytest"))
|
|
47371
47917
|
runCheck("pytest", "pytest", []);
|
|
47372
47918
|
else
|
|
@@ -47383,13 +47929,13 @@ root: ${cwd2}
|
|
|
47383
47929
|
lines.push(`command: grep -qi "## [Unreleased]" CHANGELOG.md
|
|
47384
47930
|
|
|
47385
47931
|
`);
|
|
47386
|
-
const changelogPath =
|
|
47932
|
+
const changelogPath = path18.join(cwd2, "CHANGELOG.md");
|
|
47387
47933
|
if (dryRun) {
|
|
47388
47934
|
lines.push(`status: skipped (dry run)
|
|
47389
47935
|
`);
|
|
47390
47936
|
skipped += 1;
|
|
47391
|
-
} else if (
|
|
47392
|
-
if (/## \[Unreleased\]/i.test(
|
|
47937
|
+
} else if (existsSync15(changelogPath)) {
|
|
47938
|
+
if (/## \[Unreleased\]/i.test(readFileSync13(changelogPath, "utf8"))) {
|
|
47393
47939
|
lines.push(`status: pass
|
|
47394
47940
|
`);
|
|
47395
47941
|
passed += 1;
|
|
@@ -47442,7 +47988,7 @@ var SLUG_RE2 = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
|
47442
47988
|
var flowPath = (root, slug) => {
|
|
47443
47989
|
if (!SLUG_RE2.test(slug))
|
|
47444
47990
|
throw new Error(`invalid slug: ${JSON.stringify(slug)}`);
|
|
47445
|
-
return
|
|
47991
|
+
return path19.join(root, "docs", slug, "sdd", "flow.json");
|
|
47446
47992
|
};
|
|
47447
47993
|
var resolveDoc = (root, slug, docPath, kind) => {
|
|
47448
47994
|
const resolved = resolveCanonicalLayout({
|
|
@@ -47457,11 +48003,11 @@ var resolveDoc = (root, slug, docPath, kind) => {
|
|
|
47457
48003
|
var HEX64_RE = /^[0-9a-f]{64}$/;
|
|
47458
48004
|
var FLOW_STATUSES = ["draft", "self_reviewed", "approved"];
|
|
47459
48005
|
var EXECUTION_STATUSES = ["pending", "active", "paused", "completed"];
|
|
47460
|
-
var
|
|
48006
|
+
var isRecord4 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
47461
48007
|
var validateEvidenceValue = (v, allowCli) => {
|
|
47462
48008
|
if (v === null)
|
|
47463
48009
|
return true;
|
|
47464
|
-
if (!
|
|
48010
|
+
if (!isRecord4(v))
|
|
47465
48011
|
return false;
|
|
47466
48012
|
if (v.host === "opencode") {
|
|
47467
48013
|
return v.attested === true && typeof v.callID === "string" && typeof v.selectedLabel === "string" && typeof v.recordedAt === "number";
|
|
@@ -47474,7 +48020,7 @@ var validateEvidenceValue = (v, allowCli) => {
|
|
|
47474
48020
|
return false;
|
|
47475
48021
|
};
|
|
47476
48022
|
var validateState = (parsed, slug) => {
|
|
47477
|
-
if (!
|
|
48023
|
+
if (!isRecord4(parsed))
|
|
47478
48024
|
return { ok: false, error: "flow state must be a JSON object" };
|
|
47479
48025
|
if (parsed.slug !== undefined && (typeof parsed.slug !== "string" || parsed.slug !== slug)) {
|
|
47480
48026
|
return { ok: false, error: `flow state slug must be ${JSON.stringify(slug)}` };
|
|
@@ -47489,8 +48035,8 @@ var validateState = (parsed, slug) => {
|
|
|
47489
48035
|
return { ok: false, error: "flow state updated_at must be a finite number" };
|
|
47490
48036
|
}
|
|
47491
48037
|
const doc = (value, name) => {
|
|
47492
|
-
const p =
|
|
47493
|
-
if (!
|
|
48038
|
+
const p = isRecord4(value) ? value : {};
|
|
48039
|
+
if (!isRecord4(value) && value !== undefined) {
|
|
47494
48040
|
return `flow state ${name} must be an object`;
|
|
47495
48041
|
}
|
|
47496
48042
|
if (p.status !== undefined && !FLOW_STATUSES.includes(p.status)) {
|
|
@@ -47518,8 +48064,8 @@ var validateState = (parsed, slug) => {
|
|
|
47518
48064
|
const plan = doc(parsed.plan, "plan");
|
|
47519
48065
|
if (typeof plan === "string")
|
|
47520
48066
|
return { ok: false, error: plan };
|
|
47521
|
-
const menuRaw =
|
|
47522
|
-
if (parsed.menu !== undefined && !
|
|
48067
|
+
const menuRaw = isRecord4(parsed.menu) ? parsed.menu : undefined;
|
|
48068
|
+
if (parsed.menu !== undefined && !isRecord4(parsed.menu)) {
|
|
47523
48069
|
return { ok: false, error: "flow state menu must be an object" };
|
|
47524
48070
|
}
|
|
47525
48071
|
if (menuRaw?.presented !== undefined && typeof menuRaw.presented !== "boolean") {
|
|
@@ -47537,8 +48083,8 @@ var validateState = (parsed, slug) => {
|
|
|
47537
48083
|
if (menuRaw?.evidence !== undefined && !validateEvidenceValue(menuRaw.evidence, false)) {
|
|
47538
48084
|
return { ok: false, error: "flow state menu.evidence has an unsupported shape" };
|
|
47539
48085
|
}
|
|
47540
|
-
const execRaw =
|
|
47541
|
-
if (parsed.execution !== undefined && !
|
|
48086
|
+
const execRaw = isRecord4(parsed.execution) ? parsed.execution : undefined;
|
|
48087
|
+
if (parsed.execution !== undefined && !isRecord4(parsed.execution)) {
|
|
47542
48088
|
return { ok: false, error: "flow state execution must be an object" };
|
|
47543
48089
|
}
|
|
47544
48090
|
if (execRaw?.status !== undefined && !EXECUTION_STATUSES.includes(execRaw.status)) {
|
|
@@ -47587,13 +48133,13 @@ var validateState = (parsed, slug) => {
|
|
|
47587
48133
|
};
|
|
47588
48134
|
var readFlowStrict = (root, slug) => {
|
|
47589
48135
|
const file = flowPath(root, slug);
|
|
47590
|
-
const rel =
|
|
47591
|
-
if (!
|
|
48136
|
+
const rel = path19.posix.join("docs", slug, "sdd", "flow.json");
|
|
48137
|
+
if (!existsSync16(file)) {
|
|
47592
48138
|
return err2("flow_not_activated", `flow not activated for ${slug} — run workit_flow_status first`);
|
|
47593
48139
|
}
|
|
47594
48140
|
let text;
|
|
47595
48141
|
try {
|
|
47596
|
-
text =
|
|
48142
|
+
text = readFileSync14(file, "utf8");
|
|
47597
48143
|
} catch (error) {
|
|
47598
48144
|
return err2("flow_io_error", `cannot read flow state at ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
47599
48145
|
}
|
|
@@ -47617,23 +48163,23 @@ var writeFlowFileAtomic = (file, state) => {
|
|
|
47617
48163
|
const text = JSON.stringify(state, null, 2) + `
|
|
47618
48164
|
`;
|
|
47619
48165
|
const tmp = uniqueTempPath(file);
|
|
47620
|
-
mkdirSync8(
|
|
48166
|
+
mkdirSync8(path19.dirname(file), { recursive: true });
|
|
47621
48167
|
let fd = null;
|
|
47622
48168
|
try {
|
|
47623
48169
|
fd = openSync(tmp, "w");
|
|
47624
|
-
|
|
48170
|
+
writeFileSync9(fd, text, "utf8");
|
|
47625
48171
|
fsyncSync(fd);
|
|
47626
48172
|
closeSync(fd);
|
|
47627
48173
|
fd = null;
|
|
47628
|
-
|
|
48174
|
+
renameSync3(tmp, file);
|
|
47629
48175
|
} finally {
|
|
47630
48176
|
try {
|
|
47631
48177
|
if (fd !== null)
|
|
47632
48178
|
closeSync(fd);
|
|
47633
48179
|
} catch {}
|
|
47634
48180
|
try {
|
|
47635
|
-
if (
|
|
47636
|
-
|
|
48181
|
+
if (existsSync16(tmp))
|
|
48182
|
+
rmSync4(tmp, { force: true });
|
|
47637
48183
|
} catch {}
|
|
47638
48184
|
}
|
|
47639
48185
|
};
|
|
@@ -47641,14 +48187,14 @@ var MAX_WRITE_ATTEMPTS = 5;
|
|
|
47641
48187
|
var STALE_LOCK_MS = 1000;
|
|
47642
48188
|
var lockMtimeMs = (lock) => {
|
|
47643
48189
|
try {
|
|
47644
|
-
return
|
|
48190
|
+
return statSync9(lock).mtimeMs;
|
|
47645
48191
|
} catch {
|
|
47646
48192
|
return null;
|
|
47647
48193
|
}
|
|
47648
48194
|
};
|
|
47649
48195
|
var lockOwnedBy = (fd, lock) => {
|
|
47650
48196
|
try {
|
|
47651
|
-
return fstatSync(fd).ino ===
|
|
48197
|
+
return fstatSync(fd).ino === statSync9(lock).ino;
|
|
47652
48198
|
} catch {
|
|
47653
48199
|
return false;
|
|
47654
48200
|
}
|
|
@@ -47664,19 +48210,19 @@ var writeFlowStateIfCurrent = (root, expected, next) => {
|
|
|
47664
48210
|
const tmp = uniqueTempPath(file);
|
|
47665
48211
|
let fd = null;
|
|
47666
48212
|
try {
|
|
47667
|
-
const currentText =
|
|
48213
|
+
const currentText = existsSync16(file) ? readFileSync14(file, "utf8") : null;
|
|
47668
48214
|
if (currentText !== expectedText)
|
|
47669
48215
|
return { ok: false, conflict: true };
|
|
47670
|
-
mkdirSync8(
|
|
48216
|
+
mkdirSync8(path19.dirname(file), { recursive: true });
|
|
47671
48217
|
fd = openSync(tmp, "w");
|
|
47672
|
-
|
|
48218
|
+
writeFileSync9(fd, nextText, "utf8");
|
|
47673
48219
|
fsyncSync(fd);
|
|
47674
48220
|
closeSync(fd);
|
|
47675
48221
|
fd = null;
|
|
47676
|
-
const reRead =
|
|
48222
|
+
const reRead = existsSync16(file) ? readFileSync14(file, "utf8") : null;
|
|
47677
48223
|
if (reRead !== expectedText)
|
|
47678
48224
|
return { ok: false, conflict: true };
|
|
47679
|
-
|
|
48225
|
+
renameSync3(tmp, file);
|
|
47680
48226
|
return { ok: true };
|
|
47681
48227
|
} catch (error) {
|
|
47682
48228
|
return { ok: false, io_error: error instanceof Error ? error.message : String(error) };
|
|
@@ -47686,16 +48232,16 @@ var writeFlowStateIfCurrent = (root, expected, next) => {
|
|
|
47686
48232
|
closeSync(fd);
|
|
47687
48233
|
} catch {}
|
|
47688
48234
|
try {
|
|
47689
|
-
if (
|
|
47690
|
-
|
|
48235
|
+
if (existsSync16(tmp))
|
|
48236
|
+
rmSync4(tmp, { force: true });
|
|
47691
48237
|
} catch {}
|
|
47692
48238
|
}
|
|
47693
48239
|
};
|
|
47694
48240
|
var readCanonicalDigest = (root, rel) => {
|
|
47695
|
-
const abs =
|
|
48241
|
+
const abs = path19.join(root, ...rel.split("/"));
|
|
47696
48242
|
let bytes;
|
|
47697
48243
|
try {
|
|
47698
|
-
bytes =
|
|
48244
|
+
bytes = readFileSync14(abs);
|
|
47699
48245
|
} catch (error) {
|
|
47700
48246
|
if (error.code === "ENOENT") {
|
|
47701
48247
|
return { ok: false, code: "document_missing" };
|
|
@@ -47733,8 +48279,8 @@ var driftCodeFor = (root, relPath, storedDigest) => {
|
|
|
47733
48279
|
return current.digest !== storedDigest ? "digest_mismatch" : null;
|
|
47734
48280
|
};
|
|
47735
48281
|
var reconcileState = (root, slug, state) => {
|
|
47736
|
-
const specPath =
|
|
47737
|
-
const planPath =
|
|
48282
|
+
const specPath = path19.posix.join("docs", slug, "spec.md");
|
|
48283
|
+
const planPath = path19.posix.join("docs", slug, "plan.md");
|
|
47738
48284
|
if (state.spec.status === "approved") {
|
|
47739
48285
|
const code = driftCodeFor(root, specPath, state.spec.approved_digest);
|
|
47740
48286
|
if (code) {
|
|
@@ -47768,7 +48314,7 @@ var deriveLegacyExecution = (root, slug, state) => {
|
|
|
47768
48314
|
return { status: "pending", mode: null, evidence: null, coordinator_session_id: null };
|
|
47769
48315
|
};
|
|
47770
48316
|
var normalizeCompatibility = (root, slug, parsed, state) => {
|
|
47771
|
-
if (!
|
|
48317
|
+
if (!isRecord4(parsed) || !("execution" in parsed)) {
|
|
47772
48318
|
const derived = deriveLegacyExecution(root, slug, state);
|
|
47773
48319
|
const current = state.execution;
|
|
47774
48320
|
if (derived.status !== current.status || derived.mode !== current.mode) {
|
|
@@ -47776,7 +48322,7 @@ var normalizeCompatibility = (root, slug, parsed, state) => {
|
|
|
47776
48322
|
}
|
|
47777
48323
|
return { state, changed: false };
|
|
47778
48324
|
}
|
|
47779
|
-
const execRaw =
|
|
48325
|
+
const execRaw = isRecord4(parsed.execution) ? parsed.execution : undefined;
|
|
47780
48326
|
if (execRaw && !("coordinator_session_id" in execRaw)) {
|
|
47781
48327
|
return { state: { ...state, updated_at: Date.now() }, changed: true };
|
|
47782
48328
|
}
|
|
@@ -47784,11 +48330,11 @@ var normalizeCompatibility = (root, slug, parsed, state) => {
|
|
|
47784
48330
|
};
|
|
47785
48331
|
var withFlowLock = (file, fn) => {
|
|
47786
48332
|
const lock = `${file}.lock`;
|
|
47787
|
-
if (!
|
|
48333
|
+
if (!existsSync16(path19.dirname(file)))
|
|
47788
48334
|
return { locked: true, value: fn() };
|
|
47789
48335
|
try {
|
|
47790
|
-
if (
|
|
47791
|
-
|
|
48336
|
+
if (existsSync16(`${lock}.stale`))
|
|
48337
|
+
rmSync4(`${lock}.stale`, { force: true });
|
|
47792
48338
|
} catch {}
|
|
47793
48339
|
const wait = new Int32Array(new SharedArrayBuffer(4));
|
|
47794
48340
|
let fd = null;
|
|
@@ -47807,7 +48353,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47807
48353
|
const mtime = lockMtimeMs(lock);
|
|
47808
48354
|
if (mtime !== null && Date.now() - mtime > STALE_LOCK_MS) {
|
|
47809
48355
|
try {
|
|
47810
|
-
|
|
48356
|
+
renameSync3(lock, `${lock}.stale`);
|
|
47811
48357
|
unlinkSync3(`${lock}.stale`);
|
|
47812
48358
|
} catch {}
|
|
47813
48359
|
try {
|
|
@@ -47826,7 +48372,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47826
48372
|
if (attempt2 === MAX_WRITE_ATTEMPTS - 1) {
|
|
47827
48373
|
return {
|
|
47828
48374
|
locked: false,
|
|
47829
|
-
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`)
|
|
47830
48376
|
};
|
|
47831
48377
|
}
|
|
47832
48378
|
Atomics.wait(wait, 0, 0, 10);
|
|
@@ -47835,7 +48381,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47835
48381
|
if (fd === null) {
|
|
47836
48382
|
return {
|
|
47837
48383
|
locked: false,
|
|
47838
|
-
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`)
|
|
47839
48385
|
};
|
|
47840
48386
|
}
|
|
47841
48387
|
try {
|
|
@@ -47843,7 +48389,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47843
48389
|
} finally {
|
|
47844
48390
|
try {
|
|
47845
48391
|
if (fd !== null && lockOwnedBy(fd, lock))
|
|
47846
|
-
|
|
48392
|
+
rmSync4(lock, { force: true });
|
|
47847
48393
|
} catch {}
|
|
47848
48394
|
try {
|
|
47849
48395
|
if (fd !== null)
|
|
@@ -47853,7 +48399,7 @@ var withFlowLock = (file, fn) => {
|
|
|
47853
48399
|
};
|
|
47854
48400
|
var readEffectiveFlowState = (root, slug) => {
|
|
47855
48401
|
const file = flowPath(root, slug);
|
|
47856
|
-
const rel =
|
|
48402
|
+
const rel = path19.posix.join("docs", slug, "sdd", "flow.json");
|
|
47857
48403
|
const locked = withFlowLock(file, () => {
|
|
47858
48404
|
const strict = readFlowStrict(root, slug);
|
|
47859
48405
|
if (!strict.ok)
|
|
@@ -48282,7 +48828,7 @@ var transitionExecution = (root, slug, planPath, action, evidence, ctx, deps) =>
|
|
|
48282
48828
|
});
|
|
48283
48829
|
};
|
|
48284
48830
|
var slugFromPath = (p) => {
|
|
48285
|
-
const dirName =
|
|
48831
|
+
const dirName = path19.basename(path19.dirname(p));
|
|
48286
48832
|
return dirName === "." || dirName === "/" || dirName === "" ? "" : dirName;
|
|
48287
48833
|
};
|
|
48288
48834
|
var assertSddControlGates = (root, slug, opts = {}, ctx) => {
|
|
@@ -48304,8 +48850,8 @@ var assertSddControlGates = (root, slug, opts = {}, ctx) => {
|
|
|
48304
48850
|
}
|
|
48305
48851
|
if (opts.requireDocs) {
|
|
48306
48852
|
const validated = docsValidate({
|
|
48307
|
-
spec_path:
|
|
48308
|
-
plan_path:
|
|
48853
|
+
spec_path: path19.posix.join("docs", slug, "spec.md"),
|
|
48854
|
+
plan_path: path19.posix.join("docs", slug, "plan.md"),
|
|
48309
48855
|
workspace_root: root
|
|
48310
48856
|
});
|
|
48311
48857
|
if (validated.ok === false)
|
|
@@ -48441,15 +48987,15 @@ var BASH_GIT_VALUE_FLAGS = new Set([
|
|
|
48441
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;
|
|
48442
48988
|
|
|
48443
48989
|
// packages/workit-core/src/core/handoff-tools.ts
|
|
48444
|
-
import
|
|
48990
|
+
import path21 from "node:path";
|
|
48445
48991
|
|
|
48446
48992
|
// packages/workit-core/src/core/handoff-context.ts
|
|
48447
|
-
import { existsSync as
|
|
48448
|
-
import
|
|
48993
|
+
import { existsSync as existsSync17, readFileSync as readFileSync15, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
|
|
48994
|
+
import path20 from "node:path";
|
|
48449
48995
|
var DOC_RE = /docs\/([A-Za-z0-9][A-Za-z0-9._-]*)\/(spec|plan)\.md/g;
|
|
48450
48996
|
var listMd = (dir) => {
|
|
48451
48997
|
try {
|
|
48452
|
-
return
|
|
48998
|
+
return readdirSync7(dir).filter((f) => f.endsWith(".md")).sort();
|
|
48453
48999
|
} catch {
|
|
48454
49000
|
return [];
|
|
48455
49001
|
}
|
|
@@ -48465,28 +49011,28 @@ var resolveFromMessagePaths = (root, message) => {
|
|
|
48465
49011
|
const slug = slugs[0];
|
|
48466
49012
|
const plan = `docs/${slug}/plan.md`;
|
|
48467
49013
|
const spec = `docs/${slug}/spec.md`;
|
|
48468
|
-
if (!
|
|
49014
|
+
if (!existsSync17(path20.join(root, plan)) || !existsSync17(path20.join(root, spec))) {
|
|
48469
49015
|
return { error: `docs/${slug}/ must contain both plan.md and spec.md` };
|
|
48470
49016
|
}
|
|
48471
49017
|
return { spec, plan, source: "message_paths" };
|
|
48472
49018
|
};
|
|
48473
49019
|
var resolveActivePair = (root) => {
|
|
48474
|
-
const docsDir =
|
|
49020
|
+
const docsDir = path20.join(root, "docs");
|
|
48475
49021
|
let best = null;
|
|
48476
49022
|
let entries = [];
|
|
48477
49023
|
try {
|
|
48478
|
-
entries =
|
|
49024
|
+
entries = readdirSync7(docsDir);
|
|
48479
49025
|
} catch {
|
|
48480
49026
|
return { error: "no pair" };
|
|
48481
49027
|
}
|
|
48482
49028
|
for (const slug of entries) {
|
|
48483
49029
|
if (slug.startsWith("."))
|
|
48484
49030
|
continue;
|
|
48485
|
-
const plan =
|
|
48486
|
-
const spec =
|
|
48487
|
-
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)))
|
|
48488
49034
|
continue;
|
|
48489
|
-
const score = Math.max(
|
|
49035
|
+
const score = Math.max(statSync10(path20.join(root, spec)).mtimeMs, statSync10(path20.join(root, plan)).mtimeMs);
|
|
48490
49036
|
if (best === null || score > best.score || score === best.score && slug < best.spec.split("/")[1]) {
|
|
48491
49037
|
best = { score, spec, plan, source: "active_pair" };
|
|
48492
49038
|
}
|
|
@@ -48504,8 +49050,8 @@ var resolveWorkflowPaths = (root, message) => {
|
|
|
48504
49050
|
const active = resolveActivePair(root);
|
|
48505
49051
|
if (!("error" in active))
|
|
48506
49052
|
return active;
|
|
48507
|
-
const docsDir =
|
|
48508
|
-
if (!
|
|
49053
|
+
const docsDir = path20.join(root, "docs");
|
|
49054
|
+
if (!existsSync17(docsDir) || listMd(docsDir).length === 0) {
|
|
48509
49055
|
return { error: "no docs/<slug>/ features found under docs/" };
|
|
48510
49056
|
}
|
|
48511
49057
|
return {
|
|
@@ -48529,15 +49075,15 @@ ${JSON.stringify({ ok: false, errors: validated.errors })}`
|
|
|
48529
49075
|
if ("error" in branchResolved)
|
|
48530
49076
|
return { error: branchResolved.error };
|
|
48531
49077
|
const branch = branchResolved.branch;
|
|
48532
|
-
const slug =
|
|
49078
|
+
const slug = path20.basename(path20.dirname(plan));
|
|
48533
49079
|
const sddDir = `docs/${slug}/sdd`;
|
|
48534
|
-
const planText =
|
|
49080
|
+
const planText = readFileSync15(path20.join(root, plan), "utf8");
|
|
48535
49081
|
const tasks = parseTasksFromPlan(planText);
|
|
48536
49082
|
const taskList = tasks.map((t) => `- Task ${t.id}: ${t.title}`).join(`
|
|
48537
49083
|
`);
|
|
48538
49084
|
let contract;
|
|
48539
49085
|
try {
|
|
48540
|
-
contract =
|
|
49086
|
+
contract = readFileSync15(templatePath, "utf8");
|
|
48541
49087
|
} catch {
|
|
48542
49088
|
return { error: "missing template templates/execution-contract.md" };
|
|
48543
49089
|
}
|
|
@@ -48553,7 +49099,7 @@ var buildHandoffPrompt = (root, message) => {
|
|
|
48553
49099
|
const resolved = resolveWorkflowPaths(root, message);
|
|
48554
49100
|
if ("error" in resolved)
|
|
48555
49101
|
return { error: resolved.error };
|
|
48556
|
-
const templatePath =
|
|
49102
|
+
const templatePath = path21.join(assetRoot(), "templates", "execution-contract.md");
|
|
48557
49103
|
const contract = buildHandoffContract({
|
|
48558
49104
|
root,
|
|
48559
49105
|
spec: resolved.spec,
|
|
@@ -48562,7 +49108,7 @@ var buildHandoffPrompt = (root, message) => {
|
|
|
48562
49108
|
});
|
|
48563
49109
|
if ("error" in contract)
|
|
48564
49110
|
return { error: contract.error };
|
|
48565
|
-
const sdd = `docs/${
|
|
49111
|
+
const sdd = `docs/${path21.basename(path21.dirname(resolved.plan))}/sdd`;
|
|
48566
49112
|
return { prompt: contract.prompt, spec: resolved.spec, plan: resolved.plan, sdd };
|
|
48567
49113
|
};
|
|
48568
49114
|
|
|
@@ -48750,7 +49296,7 @@ function statusCommand(root, plan, out, err3) {
|
|
|
48750
49296
|
execution: state.execution,
|
|
48751
49297
|
handoff_destination: state.handoff_destination,
|
|
48752
49298
|
drift,
|
|
48753
|
-
flow_path:
|
|
49299
|
+
flow_path: path22.posix.join("docs", state.slug, "sdd", "flow.json")
|
|
48754
49300
|
});
|
|
48755
49301
|
return 0;
|
|
48756
49302
|
}
|
|
@@ -48777,7 +49323,7 @@ function reviewPackageCommand(root, parsed, out, err3) {
|
|
|
48777
49323
|
if (!resolved.ok)
|
|
48778
49324
|
return domainFail(err3, "path_invalid", resolved.error);
|
|
48779
49325
|
const result2 = sddReviewPackage({
|
|
48780
|
-
sdd_dir:
|
|
49326
|
+
sdd_dir: path22.posix.join("docs", resolved.layout.slug, "sdd"),
|
|
48781
49327
|
base_sha: parsed.base,
|
|
48782
49328
|
head_sha: parsed.head,
|
|
48783
49329
|
workspace_root: root
|
|
@@ -48804,7 +49350,7 @@ function appendAdvisoryCommand(root, parsed, out, err3) {
|
|
|
48804
49350
|
const trimmed = parsed.task.trim();
|
|
48805
49351
|
const taskId = /^-?\d+(\.\d+)?$/.test(trimmed) ? Number(trimmed) : trimmed;
|
|
48806
49352
|
const result2 = sddAppendAdvisory({
|
|
48807
|
-
advisories_path:
|
|
49353
|
+
advisories_path: path22.posix.join("docs", slug, "sdd", "advisories.md"),
|
|
48808
49354
|
task_id: taskId,
|
|
48809
49355
|
text: parsed.text,
|
|
48810
49356
|
workspace_root: root
|
|
@@ -48862,7 +49408,7 @@ async function runHandoffCommand(argv, deps = {}) {
|
|
|
48862
49408
|
}
|
|
48863
49409
|
|
|
48864
49410
|
// packages/workit-cli/src/index.tsx
|
|
48865
|
-
var
|
|
49411
|
+
var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
|
|
48866
49412
|
var logger = createLogger({
|
|
48867
49413
|
stderr: (event) => {
|
|
48868
49414
|
if (event.level === "debug" || event.level === "info")
|
|
@@ -48886,6 +49432,7 @@ var HELP = `workit — workflow rails for agentic coding
|
|
|
48886
49432
|
Usage:
|
|
48887
49433
|
workit init Run the interactive setup wizard
|
|
48888
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)
|
|
48889
49436
|
${COMMAND_DESCRIPTIONS.map(([cmd, desc]) => ` ${cmd.padEnd(helpColumn)}${desc}`).join(`
|
|
48890
49437
|
`)}
|
|
48891
49438
|
workit Show this help
|
|
@@ -48913,10 +49460,12 @@ function printMalformedBlocked(state) {
|
|
|
48913
49460
|
async function runInit() {
|
|
48914
49461
|
const state = readSetupState();
|
|
48915
49462
|
if (state.config.status === "malformed") {
|
|
49463
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
48916
49464
|
printMalformedBlocked(state);
|
|
48917
49465
|
process.exit(1);
|
|
48918
49466
|
}
|
|
48919
49467
|
if (process.stdin.isTTY !== true) {
|
|
49468
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
48920
49469
|
console.log("workit init requires an interactive terminal (TTY).");
|
|
48921
49470
|
for (const line of setupCompletionGuidance())
|
|
48922
49471
|
console.log(line);
|
|
@@ -48925,25 +49474,32 @@ async function runInit() {
|
|
|
48925
49474
|
logger.info(EVENT.installSteps, { step: "wizard_start" });
|
|
48926
49475
|
const exits = [];
|
|
48927
49476
|
let done = () => {};
|
|
48928
|
-
|
|
49477
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
49478
|
+
const instance = render_default(/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Wizard, {
|
|
48929
49479
|
onExit: (complete, values2) => {
|
|
48930
49480
|
exits.push({ complete, values: values2 });
|
|
48931
49481
|
done();
|
|
48932
49482
|
}
|
|
48933
|
-
}, undefined, false, undefined, this));
|
|
48934
|
-
done = unmount;
|
|
48935
|
-
|
|
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");
|
|
48936
49491
|
const exit = exits[0];
|
|
48937
49492
|
if (exit && exit.complete && exit.values) {
|
|
48938
|
-
const
|
|
49493
|
+
const base2 = resolveBasePath(exit.values);
|
|
49494
|
+
const preview = buildSetupPreview(exit.values, { cwd: base2, env: process.env });
|
|
48939
49495
|
if (!preview.ok) {
|
|
48940
49496
|
printMalformedBlocked(preview.state);
|
|
48941
49497
|
process.exit(1);
|
|
48942
49498
|
}
|
|
48943
|
-
const result2 = applySetupPreview(preview, { cwd:
|
|
49499
|
+
const result2 = applySetupPreview(preview, { cwd: base2, env: process.env });
|
|
48944
49500
|
let exitCode = result2.exitCode;
|
|
48945
49501
|
if (exit.values.branchPolicy) {
|
|
48946
|
-
const bp = applyWizardBranchPolicy(exit.values.branchPolicy,
|
|
49502
|
+
const bp = applyWizardBranchPolicy(exit.values.branchPolicy, base2, process.env);
|
|
48947
49503
|
if (bp.ok) {
|
|
48948
49504
|
console.log(`${String(bp.status).padEnd(11)} ${bp.config_path} — branch policy`);
|
|
48949
49505
|
} else {
|
|
@@ -48961,6 +49517,111 @@ async function runInit() {
|
|
|
48961
49517
|
});
|
|
48962
49518
|
process.exit(exit !== undefined && exit.complete ? 0 : 1);
|
|
48963
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
|
+
}
|
|
48964
49625
|
function runDoctorCommand(args) {
|
|
48965
49626
|
const report = runDoctor({ host: "cli", cwd: process.cwd() });
|
|
48966
49627
|
if (args.includes("--json")) {
|
|
@@ -48995,11 +49656,15 @@ if (__require.main == __require.module) {
|
|
|
48995
49656
|
process.exit(await runFlowCommand(args.slice(1)));
|
|
48996
49657
|
} else if (subcommand === "handoff") {
|
|
48997
49658
|
process.exit(await runHandoffCommand(args.slice(1)));
|
|
49659
|
+
} else if (subcommand === "uninstall") {
|
|
49660
|
+
await runUninstall();
|
|
48998
49661
|
} else {
|
|
48999
49662
|
console.log(HELP);
|
|
49000
49663
|
process.exit(0);
|
|
49001
49664
|
}
|
|
49002
49665
|
}
|
|
49003
49666
|
export {
|
|
49667
|
+
runUninstall,
|
|
49668
|
+
runInit,
|
|
49004
49669
|
logger
|
|
49005
49670
|
};
|