@brainervirus/workit-cli 0.7.1 → 0.8.1
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/README.md +28 -3
- package/dist/index.js +162 -97
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# @brainervirus/workit-cli
|
|
2
2
|
|
|
3
|
-
The workit CLI — an interactive wizard that configures workit for OpenCode and/or Cursor.
|
|
3
|
+
The workit CLI — an interactive Ink wizard that configures workit for OpenCode and/or Cursor, plus an offline installation doctor.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- **Node.js ≥ 22** — the published CLI is a self-contained Node bundle (no Bun runtime). Node 21 and below fail (`ERR_MODULE_NOT_FOUND`/ESM syntax or the `>=22` engine gate).
|
|
4
8
|
|
|
5
9
|
## Install
|
|
6
10
|
|
|
@@ -13,10 +17,31 @@ npx @brainervirus/workit-cli init
|
|
|
13
17
|
## Usage
|
|
14
18
|
|
|
15
19
|
```bash
|
|
16
|
-
workit init
|
|
20
|
+
workit init # interactive setup wizard
|
|
21
|
+
workit doctor # offline installation health report
|
|
22
|
+
workit doctor --json # machine-readable report
|
|
23
|
+
workit # help
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`workit init` guides you through: platform selection (OpenCode/Cursor), global config (locale, timezone, branch policy), YouTrack, VCS, workspaces (path globs → provider), and project hygiene files. The wizard is a TTY application — `workit init` requires an interactive terminal and prints guidance (exiting nonzero) when stdin is not a TTY.
|
|
27
|
+
|
|
28
|
+
`workit doctor` checks the offline installation health and exits nonzero when problems are found; `--json` prints the full report as JSON instead of the human-readable table.
|
|
29
|
+
|
|
30
|
+
## Behavior
|
|
31
|
+
|
|
32
|
+
- **Safe apply semantics** — a malformed `config.json` is detected before the wizard renders and reported as a friendly blocked output instead of crashing; the same guard runs after the Apply preview.
|
|
33
|
+
- **Stable interaction** — unchanged wizard inputs are no-ops; they settle without React render warnings and never discard draft state.
|
|
34
|
+
- **Clean terminal** — only `warn`/`error` diagnostics print to stderr; routine structured `info` records stay in the JSONL journal. Nonzero failures and human-readable errors remain visible.
|
|
35
|
+
- **Node support** — the packed CLI runs on Node 22+; installation on Node 22.19 emits no engine warning from workit's dependency tree.
|
|
36
|
+
|
|
37
|
+
## Package scripts
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
bun run build # bundle dist/index.js (self-contained, Node shebang) + assets
|
|
41
|
+
bun run typecheck # tsc --noEmit
|
|
17
42
|
```
|
|
18
43
|
|
|
19
|
-
|
|
44
|
+
The build produces a nonsplitting `dist/index.js` with a portable `#!/usr/bin/env node` shebang and copies the deterministic `assets/` (templates) from core.
|
|
20
45
|
|
|
21
46
|
## Docs
|
|
22
47
|
|
package/dist/index.js
CHANGED
|
@@ -42763,9 +42763,9 @@ function writeFileExclusive(file, content, mode) {
|
|
|
42763
42763
|
|
|
42764
42764
|
// packages/workit-core/src/core/setup.ts
|
|
42765
42765
|
import {
|
|
42766
|
-
|
|
42766
|
+
copyFileSync as copyFileSync2,
|
|
42767
42767
|
cpSync as cpSync2,
|
|
42768
|
-
existsSync as
|
|
42768
|
+
existsSync as existsSync8,
|
|
42769
42769
|
mkdirSync as mkdirSync3,
|
|
42770
42770
|
mkdtempSync,
|
|
42771
42771
|
readFileSync as readFileSync8,
|
|
@@ -42872,7 +42872,6 @@ var readSetupState = (dir = resolveConfigDir()) => ({
|
|
|
42872
42872
|
});
|
|
42873
42873
|
|
|
42874
42874
|
// packages/workit-core/src/core/registration.ts
|
|
42875
|
-
import { existsSync as existsSync6 } from "node:fs";
|
|
42876
42875
|
import path6 from "node:path";
|
|
42877
42876
|
var isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
42878
42877
|
var named = (s, name) => s === name || s.startsWith(`${name}@`);
|
|
@@ -42880,7 +42879,7 @@ function isWorkitPlugin(value) {
|
|
|
42880
42879
|
const s = String(value).replaceAll("\\", "/");
|
|
42881
42880
|
const url = s.startsWith("file://") || s.startsWith("git+file://");
|
|
42882
42881
|
const pkgPath = s.includes("/packages/workit-opencode/") || s.includes("/packages/workit-cursor/") || s.includes("/node_modules/@brainervirus/workit-opencode/") || s.includes("/node_modules/@brainervirus/workit-cursor/");
|
|
42883
|
-
return named(s, "workflow-toolkit") || named(s, "workflow-toolkit-opencode") || named(s, "local/workflow-toolkit") || named(s, "@brainervirus/workit-opencode") || named(s, "@brainervirus/workit-cursor") || url && pkgPath || s.startsWith("git+file://") && s.includes("workflow-toolkit");
|
|
42882
|
+
return named(s, "workflow-toolkit") || named(s, "workflow-toolkit-opencode") || named(s, "local/workflow-toolkit") || named(s, "workit") || named(s, "local/workit") || named(s, "@brainervirus/workit-opencode") || named(s, "@brainervirus/workit-cursor") || url && pkgPath || s.startsWith("git+file://") && s.includes("workflow-toolkit");
|
|
42884
42883
|
}
|
|
42885
42884
|
function mergeOpenCodePlugins(plugin, pin) {
|
|
42886
42885
|
const existing = Array.isArray(plugin) ? plugin : typeof plugin === "string" ? [plugin] : [];
|
|
@@ -42911,7 +42910,8 @@ function mergeOpenCodeConfig(config, pin) {
|
|
|
42911
42910
|
}
|
|
42912
42911
|
function mergeCursorEnabledPlugins(enabled) {
|
|
42913
42912
|
const prev = isRecord(enabled) ? { ...enabled } : {};
|
|
42914
|
-
const next = { ...prev,
|
|
42913
|
+
const next = { ...prev, workit: true };
|
|
42914
|
+
delete next["workflow-toolkit"];
|
|
42915
42915
|
delete next["local/workflow-toolkit"];
|
|
42916
42916
|
const changed = JSON.stringify(next) !== JSON.stringify(prev) ? ["enabled_plugins"] : [];
|
|
42917
42917
|
return { config: next, changed };
|
|
@@ -42922,10 +42922,12 @@ function mergeCursorPluginDirs(pluginDirs, pluginDir) {
|
|
|
42922
42922
|
return path6.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
|
|
42923
42923
|
};
|
|
42924
42924
|
const normalized = strip(pluginDir);
|
|
42925
|
+
const legacy = strip(path6.join(path6.dirname(pluginDir), "workflow-toolkit"));
|
|
42925
42926
|
const prev = Array.isArray(pluginDirs) ? pluginDirs.map(String) : [];
|
|
42926
|
-
const
|
|
42927
|
-
const
|
|
42928
|
-
const
|
|
42927
|
+
const kept = prev.filter((d) => strip(d) !== legacy);
|
|
42928
|
+
const exists = kept.some((d) => strip(d) === normalized);
|
|
42929
|
+
const next = exists ? kept : [...kept, normalized];
|
|
42930
|
+
const changed = JSON.stringify(next) !== JSON.stringify(prev) ? ["plugin_dirs"] : [];
|
|
42929
42931
|
return { config: next, changed };
|
|
42930
42932
|
}
|
|
42931
42933
|
function mergeCursorSettings(settings, pluginDir) {
|
|
@@ -42952,35 +42954,36 @@ function mergeCursorMcp(mcp, serverName, server) {
|
|
|
42952
42954
|
base2.mcpServers = servers;
|
|
42953
42955
|
return { config: base2, changed };
|
|
42954
42956
|
}
|
|
42955
|
-
|
|
42956
|
-
|
|
42957
|
-
|
|
42958
|
-
|
|
42959
|
-
|
|
42960
|
-
|
|
42961
|
-
|
|
42957
|
+
var CURSOR_RUNTIME_PACKAGE = "@brainervirus/workit-cursor@0.8.0";
|
|
42958
|
+
function cursorMcpServerEntry(_packageDir) {
|
|
42959
|
+
return {
|
|
42960
|
+
command: "npx",
|
|
42961
|
+
args: ["-y", `--package=${CURSOR_RUNTIME_PACKAGE}`, "workit-cursor-mcp", "${workspaceFolder}"]
|
|
42962
|
+
};
|
|
42963
|
+
}
|
|
42964
|
+
function cursorHooksEntry(_packageDir) {
|
|
42962
42965
|
return {
|
|
42963
|
-
command:
|
|
42964
|
-
args: [
|
|
42966
|
+
command: `npx -y --package=${CURSOR_RUNTIME_PACKAGE} workit-cursor-session-start`,
|
|
42967
|
+
args: []
|
|
42965
42968
|
};
|
|
42966
42969
|
}
|
|
42967
42970
|
|
|
42968
42971
|
// packages/workit-core/src/core/doctor.ts
|
|
42969
42972
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
42970
|
-
import { existsSync as
|
|
42973
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync2, readFileSync as readFileSync7, statSync as statSync2, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
42971
42974
|
import os4 from "node:os";
|
|
42972
42975
|
import path8 from "node:path";
|
|
42973
42976
|
|
|
42974
42977
|
// packages/workit-core/src/core/support-matrix.ts
|
|
42975
42978
|
var SUPPORT_MATRIX = {
|
|
42976
42979
|
bun: "1.3.14",
|
|
42977
|
-
node: { minimum: "
|
|
42980
|
+
node: { minimum: "22", current: "22" },
|
|
42978
42981
|
opencode: { minimum: "1.15.0", current: "1.17.7" },
|
|
42979
42982
|
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
|
|
42980
42983
|
};
|
|
42981
42984
|
|
|
42982
42985
|
// packages/workit-core/src/core/skill-manifests.ts
|
|
42983
|
-
import { existsSync as
|
|
42986
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync } from "node:fs";
|
|
42984
42987
|
import path7 from "node:path";
|
|
42985
42988
|
var CANONICAL_SKILLS = {
|
|
42986
42989
|
superpowers: [
|
|
@@ -43014,7 +43017,7 @@ var CANONICAL_SKILLS = {
|
|
|
43014
43017
|
"wk-verify"
|
|
43015
43018
|
]
|
|
43016
43019
|
};
|
|
43017
|
-
var skillManifestNames = (root) =>
|
|
43020
|
+
var skillManifestNames = (root) => existsSync6(root) ? readdirSync2(root).filter((name) => existsSync6(path7.join(root, name, "SKILL.md"))).sort() : [];
|
|
43018
43021
|
var validateSkillManifests = (root, expected, label) => {
|
|
43019
43022
|
const actual = skillManifestNames(root);
|
|
43020
43023
|
const missing = expected.filter((name) => !actual.includes(name));
|
|
@@ -43050,7 +43053,7 @@ var TOKEN_PLACEHOLDER = "YOUR_TOKEN_HERE";
|
|
|
43050
43053
|
var findDevFromCwd = (cwd2) => {
|
|
43051
43054
|
let dir = path8.resolve(cwd2);
|
|
43052
43055
|
while (true) {
|
|
43053
|
-
if (
|
|
43056
|
+
if (existsSync7(path8.join(dir, "packages", "workit-core", "package.json")))
|
|
43054
43057
|
return dir;
|
|
43055
43058
|
const parent = path8.dirname(dir);
|
|
43056
43059
|
if (parent === dir)
|
|
@@ -43075,7 +43078,7 @@ var resolve = (options) => {
|
|
|
43075
43078
|
opencodeConfig: options.opencodeConfig ?? path8.join(home, ".config", "opencode", "opencode.json"),
|
|
43076
43079
|
cursorSettings: options.cursorSettings ?? path8.join(home, ".cursor", "settings.json"),
|
|
43077
43080
|
cursorMcp: options.cursorMcp ?? path8.join(home, ".cursor", "mcp.json"),
|
|
43078
|
-
cursorPluginDir: options.cursorPluginDir ?? path8.join(home, ".cursor", "plugins", "local", "
|
|
43081
|
+
cursorPluginDir: options.cursorPluginDir ?? path8.join(home, ".cursor", "plugins", "local", "workit"),
|
|
43079
43082
|
env: env3,
|
|
43080
43083
|
installer: options.installer ?? false
|
|
43081
43084
|
};
|
|
@@ -43136,14 +43139,14 @@ var semverAtLeast = (version, min2) => {
|
|
|
43136
43139
|
return true;
|
|
43137
43140
|
};
|
|
43138
43141
|
var resolveBun = (env3) => {
|
|
43139
|
-
if (env3.BUN &&
|
|
43142
|
+
if (env3.BUN && existsSync7(env3.BUN))
|
|
43140
43143
|
return env3.BUN;
|
|
43141
43144
|
for (const candidate of [
|
|
43142
43145
|
path8.join(os4.homedir(), ".bun/bin/bun"),
|
|
43143
43146
|
"/usr/local/bin/bun",
|
|
43144
43147
|
"/usr/bin/bun"
|
|
43145
43148
|
]) {
|
|
43146
|
-
if (
|
|
43149
|
+
if (existsSync7(candidate))
|
|
43147
43150
|
return candidate;
|
|
43148
43151
|
}
|
|
43149
43152
|
return commandOnPath("bun", env3) ? "bun" : null;
|
|
@@ -43253,7 +43256,6 @@ var assetPathsFor = (host, dev) => {
|
|
|
43253
43256
|
return [
|
|
43254
43257
|
path8.join(pkg, "assets", "templates", "spec-template.md"),
|
|
43255
43258
|
path8.join(pkg, "mcp.json"),
|
|
43256
|
-
path8.join(pkg, "marketplace.json"),
|
|
43257
43259
|
path8.join(pkg, ".cursor-plugin")
|
|
43258
43260
|
];
|
|
43259
43261
|
case "cli":
|
|
@@ -43263,7 +43265,7 @@ var assetPathsFor = (host, dev) => {
|
|
|
43263
43265
|
var hostsFor = (host) => host === "cli" ? ["opencode", "cursor", "cli"] : [host];
|
|
43264
43266
|
var checkAssets = (res) => {
|
|
43265
43267
|
const dev = res.dev;
|
|
43266
|
-
const missing = dev ? hostsFor(res.host).flatMap((h) => assetPathsFor(h, dev).filter((p) => !
|
|
43268
|
+
const missing = dev ? hostsFor(res.host).flatMap((h) => assetPathsFor(h, dev).filter((p) => !existsSync7(p)).map((p) => `${h}: ${p}`)) : [];
|
|
43267
43269
|
if (res.host === "cursor" || res.host === "cli") {
|
|
43268
43270
|
const cursorError = validateCursorSkills(res.cursorPluginDir);
|
|
43269
43271
|
if (cursorError)
|
|
@@ -43297,11 +43299,8 @@ var launcherSlotsFor = (host, dev) => {
|
|
|
43297
43299
|
return [[path8.join(pkg, "src", "plugin.ts"), path8.join(pkg, "dist", "plugin.js")]];
|
|
43298
43300
|
case "cursor":
|
|
43299
43301
|
return [
|
|
43300
|
-
[path8.join(pkg, "dist", "mcp-server.js")
|
|
43301
|
-
[
|
|
43302
|
-
path8.join(pkg, "dist", "cursor-session-start.js"),
|
|
43303
|
-
path8.join(pkg, "hooks", "session-start")
|
|
43304
|
-
]
|
|
43302
|
+
[path8.join(pkg, "dist", "mcp-server.js")],
|
|
43303
|
+
[path8.join(pkg, "dist", "cursor-session-start.js")]
|
|
43305
43304
|
];
|
|
43306
43305
|
case "cli":
|
|
43307
43306
|
return [[path8.join(pkg, "src", "index.tsx"), path8.join(pkg, "dist", "index.js")]];
|
|
@@ -43320,7 +43319,7 @@ var validNodeEntry = (entry, runtime, env3) => {
|
|
|
43320
43319
|
}
|
|
43321
43320
|
};
|
|
43322
43321
|
var registeredCursorLauncher = (res) => {
|
|
43323
|
-
if (!
|
|
43322
|
+
if (!existsSync7(res.cursorMcp))
|
|
43324
43323
|
return "invalid";
|
|
43325
43324
|
const config = readJson(res.cursorMcp);
|
|
43326
43325
|
if (!config)
|
|
@@ -43334,28 +43333,60 @@ var registeredCursorLauncher = (res) => {
|
|
|
43334
43333
|
return "invalid";
|
|
43335
43334
|
}
|
|
43336
43335
|
const executable = path8.basename(command).toLowerCase();
|
|
43336
|
+
if (executable === "npx" || executable === "npx.exe" || executable === "npx.cmd") {
|
|
43337
|
+
if (args[0] !== "-y")
|
|
43338
|
+
return "invalid";
|
|
43339
|
+
if (args[1] !== `--package=${CURSOR_RUNTIME_PACKAGE}`)
|
|
43340
|
+
return "invalid";
|
|
43341
|
+
if (args[2] !== "workit-cursor-mcp")
|
|
43342
|
+
return "invalid";
|
|
43343
|
+
return { kind: "npx" };
|
|
43344
|
+
}
|
|
43337
43345
|
if (executable !== "node" && executable !== "node.exe")
|
|
43338
43346
|
return "invalid";
|
|
43339
43347
|
return {
|
|
43348
|
+
kind: "node",
|
|
43340
43349
|
runtime: command,
|
|
43341
43350
|
entry: path8.isAbsolute(args[0]) ? args[0] : path8.resolve(path8.dirname(res.cursorMcp), args[0])
|
|
43342
43351
|
};
|
|
43343
43352
|
};
|
|
43353
|
+
var canonicalCursorHook = cursorHooksEntry("").command;
|
|
43354
|
+
var registeredCursorHook = (res) => {
|
|
43355
|
+
const hooksFile = path8.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
|
|
43356
|
+
if (!existsSync7(hooksFile))
|
|
43357
|
+
return "invalid";
|
|
43358
|
+
const config = readJson(hooksFile);
|
|
43359
|
+
if (!config)
|
|
43360
|
+
return "invalid";
|
|
43361
|
+
const sessionStart = config.hooks?.sessionStart;
|
|
43362
|
+
if (!Array.isArray(sessionStart) || sessionStart.length !== 1)
|
|
43363
|
+
return "invalid";
|
|
43364
|
+
const entry = sessionStart[0];
|
|
43365
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
43366
|
+
return "invalid";
|
|
43367
|
+
return typeof entry.command === "string" ? entry.command : "invalid";
|
|
43368
|
+
};
|
|
43344
43369
|
var checkLauncher = (res) => {
|
|
43345
43370
|
const dev = res.dev;
|
|
43346
43371
|
const hosts = hostsFor(res.host);
|
|
43347
43372
|
const registered = hosts.includes("cursor") ? registeredCursorLauncher(res) : null;
|
|
43348
|
-
const runtime = registered && registered !== "invalid" ? registered.runtime : "node";
|
|
43373
|
+
const runtime = registered && registered !== "invalid" && registered.kind === "node" ? registered.runtime : "node";
|
|
43349
43374
|
const missing = hosts.includes("cursor") ? ["dist/mcp-server.js", "dist/cursor-session-start.js"].map((rel) => path8.join(res.cursorPluginDir, rel)).filter((p) => !validNodeEntry(p, runtime, res.env)).map((p) => `cursor: ${p}`) : [];
|
|
43350
43375
|
if (hosts.includes("cursor")) {
|
|
43351
43376
|
if (registered === "invalid") {
|
|
43352
43377
|
missing.push(`cursor: canonical workit MCP launcher in ${res.cursorMcp}`);
|
|
43353
|
-
} else if (registered && !validNodeEntry(registered.entry, registered.runtime, res.env)) {
|
|
43378
|
+
} else if (registered && registered.kind === "node" && !validNodeEntry(registered.entry, registered.runtime, res.env)) {
|
|
43354
43379
|
missing.push(`cursor: registered ${registered.entry}`);
|
|
43355
43380
|
}
|
|
43381
|
+
const hook = registeredCursorHook(res);
|
|
43382
|
+
if (hook === "invalid") {
|
|
43383
|
+
missing.push(`cursor: canonical session-start hook in ${path8.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")}`);
|
|
43384
|
+
} else if (hook !== null && hook !== canonicalCursorHook) {
|
|
43385
|
+
missing.push(`cursor: canonical session-start hook in ${path8.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")} (registered ${hook})`);
|
|
43386
|
+
}
|
|
43356
43387
|
}
|
|
43357
43388
|
if (dev) {
|
|
43358
|
-
missing.push(...hosts.filter((h) => h !== "cursor").flatMap((h) => launcherSlotsFor(h, dev).filter((slot) => !slot.some((p) =>
|
|
43389
|
+
missing.push(...hosts.filter((h) => h !== "cursor").flatMap((h) => launcherSlotsFor(h, dev).filter((slot) => !slot.some((p) => existsSync7(p))).map((slot) => `${h}: ${slot.join(" or ")}`)));
|
|
43359
43390
|
}
|
|
43360
43391
|
if (missing.length > 0) {
|
|
43361
43392
|
return {
|
|
@@ -43401,7 +43432,7 @@ var staleEntry = (entry) => {
|
|
|
43401
43432
|
return "stale";
|
|
43402
43433
|
if (entry.startsWith("file:")) {
|
|
43403
43434
|
const target = entry.replace(/^file:\/\//, "").replace(/^file:/, "");
|
|
43404
|
-
return
|
|
43435
|
+
return existsSync7(target) ? "ok" : "missing-file";
|
|
43405
43436
|
}
|
|
43406
43437
|
return "ok";
|
|
43407
43438
|
};
|
|
@@ -43413,7 +43444,7 @@ var checkStalePin = (res) => {
|
|
|
43413
43444
|
detail: "opencode pin not inspected on the cursor host"
|
|
43414
43445
|
};
|
|
43415
43446
|
}
|
|
43416
|
-
if (!
|
|
43447
|
+
if (!existsSync7(res.opencodeConfig)) {
|
|
43417
43448
|
return { id: "stale_pin", status: "pass", detail: "no opencode config — not registered" };
|
|
43418
43449
|
}
|
|
43419
43450
|
const cfg = readJson(res.opencodeConfig);
|
|
@@ -43449,13 +43480,13 @@ var checkDuplicateRegistration = (res) => {
|
|
|
43449
43480
|
const problems = [];
|
|
43450
43481
|
const opencodeHost = res.host !== "cursor";
|
|
43451
43482
|
const cursorHost = res.host !== "opencode";
|
|
43452
|
-
if (opencodeHost &&
|
|
43483
|
+
if (opencodeHost && existsSync7(res.opencodeConfig)) {
|
|
43453
43484
|
const cfg = readJson(res.opencodeConfig);
|
|
43454
43485
|
const entries = pluginEntries(cfg);
|
|
43455
43486
|
if (entries.length > 1)
|
|
43456
43487
|
problems.push(`opencode registers ${entries.length} workit plugin entries`);
|
|
43457
43488
|
}
|
|
43458
|
-
if (cursorHost &&
|
|
43489
|
+
if (cursorHost && existsSync7(res.cursorSettings)) {
|
|
43459
43490
|
const settings = readJson(res.cursorSettings);
|
|
43460
43491
|
const enabled = settings?.enabled_plugins;
|
|
43461
43492
|
if (enabled && typeof enabled === "object") {
|
|
@@ -43463,11 +43494,14 @@ var checkDuplicateRegistration = (res) => {
|
|
|
43463
43494
|
if (keys2.length > 1)
|
|
43464
43495
|
problems.push(`cursor enables ${keys2.length} workit plugin identities (${keys2.join(", ")})`);
|
|
43465
43496
|
}
|
|
43466
|
-
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs.map(String).filter((d) =>
|
|
43497
|
+
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs.map(String).filter((d) => {
|
|
43498
|
+
const n = d.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
43499
|
+
return isWorkitPlugin(d) || n.endsWith("local/workit") || n.endsWith("local/workflow-toolkit");
|
|
43500
|
+
}) : [];
|
|
43467
43501
|
if (dirs.length > 1)
|
|
43468
43502
|
problems.push(`cursor plugin_dirs has ${dirs.length} workit entries`);
|
|
43469
43503
|
}
|
|
43470
|
-
if (cursorHost &&
|
|
43504
|
+
if (cursorHost && existsSync7(res.cursorMcp)) {
|
|
43471
43505
|
const mcp = readJson(res.cursorMcp);
|
|
43472
43506
|
const servers = mcp?.mcpServers ?? {};
|
|
43473
43507
|
if (servers && typeof servers === "object") {
|
|
@@ -43490,16 +43524,16 @@ var checkMalformedConfig = (res) => {
|
|
|
43490
43524
|
const files = [];
|
|
43491
43525
|
for (const name of ["config.json", "youtrack.json", "vcs.json", "workspaces.json"]) {
|
|
43492
43526
|
const p = path8.join(res.configDir, name);
|
|
43493
|
-
if (
|
|
43527
|
+
if (existsSync7(p))
|
|
43494
43528
|
files.push(p);
|
|
43495
43529
|
}
|
|
43496
43530
|
const opencodeHost = res.host !== "cursor";
|
|
43497
43531
|
const cursorHost = res.host !== "opencode";
|
|
43498
|
-
if (opencodeHost &&
|
|
43532
|
+
if (opencodeHost && existsSync7(res.opencodeConfig))
|
|
43499
43533
|
files.push(res.opencodeConfig);
|
|
43500
|
-
if (cursorHost &&
|
|
43534
|
+
if (cursorHost && existsSync7(res.cursorSettings))
|
|
43501
43535
|
files.push(res.cursorSettings);
|
|
43502
|
-
if (cursorHost &&
|
|
43536
|
+
if (cursorHost && existsSync7(res.cursorMcp))
|
|
43503
43537
|
files.push(res.cursorMcp);
|
|
43504
43538
|
const bad = files.filter((p) => !parsesAsConfigObject(p));
|
|
43505
43539
|
if (bad.length === 0)
|
|
@@ -43513,7 +43547,7 @@ var checkMalformedConfig = (res) => {
|
|
|
43513
43547
|
};
|
|
43514
43548
|
var checkWorkspaceMismatch = (res) => {
|
|
43515
43549
|
const file = path8.join(res.configDir, "workspaces.json");
|
|
43516
|
-
if (!
|
|
43550
|
+
if (!existsSync7(file))
|
|
43517
43551
|
return { id: "workspace_mismatch", status: "pass", detail: "no workspaces configured" };
|
|
43518
43552
|
const ws = readJson(file);
|
|
43519
43553
|
if (!Array.isArray(ws?.workspaces)) {
|
|
@@ -43545,7 +43579,7 @@ var checkCredentialMetadata = (res) => {
|
|
|
43545
43579
|
const youtrackJson = readJson(path8.join(res.configDir, "youtrack.json"));
|
|
43546
43580
|
if (youtrackJson) {
|
|
43547
43581
|
tokenPaths.push(typeof youtrackJson.tokenFile === "string" ? youtrackJson.tokenFile : path8.join(res.configDir, "youtrack.token"));
|
|
43548
|
-
} else if (
|
|
43582
|
+
} else if (existsSync7(path8.join(res.configDir, "youtrack.token"))) {
|
|
43549
43583
|
tokenPaths.push(path8.join(res.configDir, "youtrack.token"));
|
|
43550
43584
|
}
|
|
43551
43585
|
const vcsJson = readJson(path8.join(res.configDir, "vcs.json"));
|
|
@@ -43554,7 +43588,7 @@ var checkCredentialMetadata = (res) => {
|
|
|
43554
43588
|
if (provider && typeof provider === "object") {
|
|
43555
43589
|
const tf = provider.tokenFile;
|
|
43556
43590
|
tokenPaths.push(typeof tf === "string" ? tf : path8.join(res.configDir, `${key}.token`));
|
|
43557
|
-
} else if (!vcsJson &&
|
|
43591
|
+
} else if (!vcsJson && existsSync7(path8.join(res.configDir, `${key}.token`))) {
|
|
43558
43592
|
tokenPaths.push(path8.join(res.configDir, `${key}.token`));
|
|
43559
43593
|
}
|
|
43560
43594
|
}
|
|
@@ -43564,7 +43598,7 @@ var checkCredentialMetadata = (res) => {
|
|
|
43564
43598
|
const problems = [];
|
|
43565
43599
|
for (const raw of tokenPaths) {
|
|
43566
43600
|
const p = path8.isAbsolute(raw) ? raw : path8.resolve(res.configDir, raw);
|
|
43567
|
-
if (!
|
|
43601
|
+
if (!existsSync7(p)) {
|
|
43568
43602
|
problems.push(`${p} is missing`);
|
|
43569
43603
|
continue;
|
|
43570
43604
|
}
|
|
@@ -43830,7 +43864,7 @@ function buildSetupPreview(values2, opts = {}) {
|
|
|
43830
43864
|
path: ytPath,
|
|
43831
43865
|
value: draft
|
|
43832
43866
|
});
|
|
43833
|
-
if (
|
|
43867
|
+
if (existsSync8(tokenPath))
|
|
43834
43868
|
preserved.push(tokenPath);
|
|
43835
43869
|
else
|
|
43836
43870
|
mutations.push({
|
|
@@ -43869,7 +43903,7 @@ function buildSetupPreview(values2, opts = {}) {
|
|
|
43869
43903
|
value: draft
|
|
43870
43904
|
});
|
|
43871
43905
|
const activeToken = values2.vcsProvider === "gitlab" ? gitlabToken : githubToken;
|
|
43872
|
-
if (
|
|
43906
|
+
if (existsSync8(activeToken))
|
|
43873
43907
|
preserved.push(activeToken);
|
|
43874
43908
|
else
|
|
43875
43909
|
mutations.push({
|
|
@@ -43896,7 +43930,7 @@ function buildSetupPreview(values2, opts = {}) {
|
|
|
43896
43930
|
if (values2.applyProject) {
|
|
43897
43931
|
const root = path9.resolve(opts.cwd ?? process.cwd());
|
|
43898
43932
|
const gitignorePath = path9.join(root, ".gitignore");
|
|
43899
|
-
const existing =
|
|
43933
|
+
const existing = existsSync8(gitignorePath) ? readFileSync8(gitignorePath, "utf8") : "";
|
|
43900
43934
|
const existingLines = new Set(existing.split(`
|
|
43901
43935
|
`).map((l) => l.trim()).filter(Boolean));
|
|
43902
43936
|
const entries = GITIGNORE_ENTRIES.filter((e) => e.trim() !== "" && !existingLines.has(e.trim()));
|
|
@@ -43927,7 +43961,7 @@ var resolveSetupPaths = (options, configDir2) => {
|
|
|
43927
43961
|
opencodeConfig: options.opencodeConfig ?? path9.join(home, ".config", "opencode", "opencode.json"),
|
|
43928
43962
|
cursorSettings: options.cursorSettings ?? path9.join(home, ".cursor", "settings.json"),
|
|
43929
43963
|
cursorMcp: options.cursorMcp ?? path9.join(home, ".cursor", "mcp.json"),
|
|
43930
|
-
cursorPluginDir: options.cursorPluginDir ?? path9.join(home, ".cursor", "plugins", "local", "
|
|
43964
|
+
cursorPluginDir: options.cursorPluginDir ?? path9.join(home, ".cursor", "plugins", "local", "workit")
|
|
43931
43965
|
};
|
|
43932
43966
|
};
|
|
43933
43967
|
function resolveApply(preview, options) {
|
|
@@ -43943,7 +43977,7 @@ var readExisting = (p) => {
|
|
|
43943
43977
|
try {
|
|
43944
43978
|
raw = readFileSync8(p, "utf8");
|
|
43945
43979
|
} catch {
|
|
43946
|
-
if (
|
|
43980
|
+
if (existsSync8(p))
|
|
43947
43981
|
return { kind: "malformed", error: `${p} is not readable` };
|
|
43948
43982
|
return { kind: "missing" };
|
|
43949
43983
|
}
|
|
@@ -44117,7 +44151,7 @@ function adapterRoot(platform2, res) {
|
|
|
44117
44151
|
var opencodePin = (root) => {
|
|
44118
44152
|
for (const rel of ["src/plugin.ts", "dist/plugin.js"]) {
|
|
44119
44153
|
const entry = path9.join(root, rel);
|
|
44120
|
-
if (
|
|
44154
|
+
if (existsSync8(entry))
|
|
44121
44155
|
return `file://${entry}`;
|
|
44122
44156
|
}
|
|
44123
44157
|
return null;
|
|
@@ -44165,15 +44199,11 @@ function applyOpenCode(root, res) {
|
|
|
44165
44199
|
detail: `pinned ${pin}`
|
|
44166
44200
|
};
|
|
44167
44201
|
}
|
|
44168
|
-
var cursorMcpManifest = (dir) => JSON.stringify({ mcpServers: { workit: cursorMcpServerEntry(dir) } }, null, 2) + `
|
|
44169
|
-
`;
|
|
44170
44202
|
var samePluginContent = (src, dest, relative = "") => {
|
|
44171
44203
|
try {
|
|
44172
44204
|
for (const entry of readdirSync3(src, { withFileTypes: true })) {
|
|
44173
44205
|
if (entry.name === "node_modules")
|
|
44174
44206
|
continue;
|
|
44175
|
-
if (relative === "" && entry.name === "mcp.json")
|
|
44176
|
-
continue;
|
|
44177
44207
|
const source = path9.join(src, entry.name);
|
|
44178
44208
|
const installed = path9.join(dest, entry.name);
|
|
44179
44209
|
if (entry.isDirectory()) {
|
|
@@ -44184,15 +44214,13 @@ var samePluginContent = (src, dest, relative = "") => {
|
|
|
44184
44214
|
}
|
|
44185
44215
|
}
|
|
44186
44216
|
for (const entry of readdirSync3(dest, { withFileTypes: true })) {
|
|
44187
|
-
if (
|
|
44217
|
+
if (existsSync8(path9.join(src, entry.name)))
|
|
44188
44218
|
continue;
|
|
44189
44219
|
const rel = path9.join(relative, entry.name);
|
|
44190
44220
|
if (rel === ".workflow-toolkit-root")
|
|
44191
44221
|
continue;
|
|
44192
44222
|
if (relative === "rules" && entry.isFile() && entry.name.endsWith(".mdc"))
|
|
44193
44223
|
continue;
|
|
44194
|
-
if (relative === "" && entry.name === "mcp.json")
|
|
44195
|
-
continue;
|
|
44196
44224
|
return false;
|
|
44197
44225
|
}
|
|
44198
44226
|
return true;
|
|
@@ -44208,7 +44236,7 @@ var preservedCursorRules = (src, dest) => {
|
|
|
44208
44236
|
for (const entry of readdirSync3(installedRules, { withFileTypes: true })) {
|
|
44209
44237
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
44210
44238
|
continue;
|
|
44211
|
-
if (
|
|
44239
|
+
if (existsSync8(path9.join(sourceRules, entry.name)))
|
|
44212
44240
|
continue;
|
|
44213
44241
|
preserved.set(entry.name, readFileSync8(path9.join(installedRules, entry.name)));
|
|
44214
44242
|
}
|
|
@@ -44217,10 +44245,10 @@ var preservedCursorRules = (src, dest) => {
|
|
|
44217
44245
|
};
|
|
44218
44246
|
function copyPluginDir(src, dest) {
|
|
44219
44247
|
const marker = path9.join(dest, ".workflow-toolkit-root");
|
|
44220
|
-
const synced = readFileSafe(marker)?.trim() === src && samePluginContent(src, dest)
|
|
44248
|
+
const synced = readFileSafe(marker)?.trim() === src && samePluginContent(src, dest);
|
|
44221
44249
|
if (synced)
|
|
44222
44250
|
return "Skipped";
|
|
44223
|
-
const hadDir =
|
|
44251
|
+
const hadDir = existsSync8(dest);
|
|
44224
44252
|
const rules = preservedCursorRules(src, dest);
|
|
44225
44253
|
const parent = path9.dirname(dest);
|
|
44226
44254
|
mkdirSync3(parent, { recursive: true });
|
|
@@ -44238,11 +44266,6 @@ function copyPluginDir(src, dest) {
|
|
|
44238
44266
|
}
|
|
44239
44267
|
writeFileSync5(path9.join(stage, ".workflow-toolkit-root"), src + `
|
|
44240
44268
|
`, "utf8");
|
|
44241
|
-
for (const rel of ["hooks/session-start", "mcp/run-server.sh"]) {
|
|
44242
|
-
try {
|
|
44243
|
-
chmodSync(path9.join(stage, rel), 493);
|
|
44244
|
-
} catch {}
|
|
44245
|
-
}
|
|
44246
44269
|
if (!samePluginContent(src, stage))
|
|
44247
44270
|
throw new Error("staged adapter content is incomplete");
|
|
44248
44271
|
if (hadDir)
|
|
@@ -44250,17 +44273,35 @@ function copyPluginDir(src, dest) {
|
|
|
44250
44273
|
try {
|
|
44251
44274
|
renameSync(stage, dest);
|
|
44252
44275
|
} catch (error) {
|
|
44253
|
-
if (hadDir && !
|
|
44276
|
+
if (hadDir && !existsSync8(dest))
|
|
44254
44277
|
renameSync(backup, dest);
|
|
44255
44278
|
throw error;
|
|
44256
44279
|
}
|
|
44257
|
-
writeFileSync5(path9.join(dest, "mcp.json"), cursorMcpManifest(dest), "utf8");
|
|
44258
44280
|
rmSync(backup, { recursive: true, force: true });
|
|
44259
44281
|
} finally {
|
|
44260
44282
|
rmSync(swap, { recursive: true, force: true });
|
|
44261
44283
|
}
|
|
44262
44284
|
return hadDir ? "Configured" : "Installed";
|
|
44263
44285
|
}
|
|
44286
|
+
var removeLegacyCursorDir = (res) => {
|
|
44287
|
+
const legacy = path9.join(res.home, ".cursor", "plugins", "local", "workflow-toolkit");
|
|
44288
|
+
if (legacy === res.cursorPluginDir || !existsSync8(legacy))
|
|
44289
|
+
return;
|
|
44290
|
+
const legacyRules = path9.join(legacy, "rules");
|
|
44291
|
+
if (existsSync8(legacyRules)) {
|
|
44292
|
+
try {
|
|
44293
|
+
mkdirSync3(path9.join(res.cursorPluginDir, "rules"), { recursive: true });
|
|
44294
|
+
for (const entry of readdirSync3(legacyRules, { withFileTypes: true })) {
|
|
44295
|
+
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
44296
|
+
continue;
|
|
44297
|
+
const target = path9.join(res.cursorPluginDir, "rules", entry.name);
|
|
44298
|
+
if (!existsSync8(target))
|
|
44299
|
+
copyFileSync2(path9.join(legacyRules, entry.name), target);
|
|
44300
|
+
}
|
|
44301
|
+
} catch {}
|
|
44302
|
+
}
|
|
44303
|
+
rmSync(legacy, { recursive: true, force: true });
|
|
44304
|
+
};
|
|
44264
44305
|
function applyCursorSettings(root, res) {
|
|
44265
44306
|
mkdirSync3(path9.dirname(res.cursorSettings), { recursive: true });
|
|
44266
44307
|
const settingsExisting = readExisting(res.cursorSettings);
|
|
@@ -44318,9 +44359,9 @@ function applyCursorMcp(root, res) {
|
|
|
44318
44359
|
};
|
|
44319
44360
|
}
|
|
44320
44361
|
function verifyPlatform(platform2, res) {
|
|
44321
|
-
if (platform2 === "opencode" && !
|
|
44362
|
+
if (platform2 === "opencode" && !existsSync8(res.opencodeConfig))
|
|
44322
44363
|
return null;
|
|
44323
|
-
if (platform2 === "cursor" && !
|
|
44364
|
+
if (platform2 === "cursor" && !existsSync8(res.cursorSettings) && !existsSync8(res.cursorMcp)) {
|
|
44324
44365
|
return null;
|
|
44325
44366
|
}
|
|
44326
44367
|
return runDoctor({
|
|
@@ -44364,6 +44405,7 @@ function applySetupPreview(preview, options = {}) {
|
|
|
44364
44405
|
const res = resolveApply(preview, options);
|
|
44365
44406
|
const entries = [];
|
|
44366
44407
|
const rootFor = new Map;
|
|
44408
|
+
let cursorCopyOk = false;
|
|
44367
44409
|
for (const mutation of preview.mutations) {
|
|
44368
44410
|
if (mutation.type !== "register-platform" && mutation.type !== "install-adapter") {
|
|
44369
44411
|
entries.push(applyMutation(mutation));
|
|
@@ -44396,7 +44438,9 @@ function applySetupPreview(preview, options = {}) {
|
|
|
44396
44438
|
}
|
|
44397
44439
|
if (mutation.type === "install-adapter") {
|
|
44398
44440
|
try {
|
|
44399
|
-
|
|
44441
|
+
const status = copyPluginDir(root, mutation.path);
|
|
44442
|
+
cursorCopyOk = true;
|
|
44443
|
+
entries.push({ platform: platform2, file: mutation.path, status });
|
|
44400
44444
|
} catch (error) {
|
|
44401
44445
|
entries.push({
|
|
44402
44446
|
platform: platform2,
|
|
@@ -44407,10 +44451,15 @@ function applySetupPreview(preview, options = {}) {
|
|
|
44407
44451
|
}
|
|
44408
44452
|
} else if (platform2 === "opencode") {
|
|
44409
44453
|
entries.push(applyOpenCode(root, res));
|
|
44454
|
+
} else if (!cursorCopyOk) {
|
|
44455
|
+
continue;
|
|
44410
44456
|
} else {
|
|
44411
44457
|
entries.push(mutation.path === res.cursorSettings ? applyCursorSettings(root, res) : applyCursorMcp(root, res));
|
|
44412
44458
|
}
|
|
44413
44459
|
}
|
|
44460
|
+
if (preview.platforms.includes("cursor") && cursorCopyOk && !entries.some((e) => e.platform === "cursor" && e.status === "Failed")) {
|
|
44461
|
+
removeLegacyCursorDir(res);
|
|
44462
|
+
}
|
|
44414
44463
|
for (const preserved of preview.preserved) {
|
|
44415
44464
|
entries.push({
|
|
44416
44465
|
platform: "core",
|
|
@@ -44558,8 +44607,9 @@ function applyWizardBranchPolicy(branchPolicy, workspace_root, env3 = process.en
|
|
|
44558
44607
|
}
|
|
44559
44608
|
|
|
44560
44609
|
// packages/workit-cli/src/wizard-state.ts
|
|
44561
|
-
import { existsSync as
|
|
44610
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
44562
44611
|
import path10 from "node:path";
|
|
44612
|
+
import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
|
|
44563
44613
|
var NEXT = {
|
|
44564
44614
|
platforms: "locale",
|
|
44565
44615
|
locale: "timezone",
|
|
@@ -44603,7 +44653,7 @@ var PREV = {
|
|
|
44603
44653
|
exit: null
|
|
44604
44654
|
};
|
|
44605
44655
|
var skipsCustomBranch = (screen, preset) => (screen === "branchAllowed" || screen === "branchProtected") && preset !== "custom";
|
|
44606
|
-
var skipsBranchPolicy = (screen) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !
|
|
44656
|
+
var skipsBranchPolicy = (screen) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync9(path10.join(process.env.WORKFLOW_WORKSPACE_ROOT ?? process.cwd(), ".git"));
|
|
44607
44657
|
function nextScreen(screen, preset) {
|
|
44608
44658
|
let next = NEXT[screen];
|
|
44609
44659
|
while (next && (skipsCustomBranch(next, preset) || skipsBranchPolicy(next)))
|
|
@@ -44660,6 +44710,9 @@ var decodeBranchPreset = (value, fallback) => value === "gitflow" || value === "
|
|
|
44660
44710
|
var decodeVcsProvider = (value, fallback) => value === "gitlab" || value === "github" || value === "skip" ? value : fallback;
|
|
44661
44711
|
function setTextValue(draft, field, value) {
|
|
44662
44712
|
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);
|
|
44713
|
+
if (draft.values[field] === value && (draft.errors[field] ?? undefined) === (message ?? undefined)) {
|
|
44714
|
+
return draft;
|
|
44715
|
+
}
|
|
44663
44716
|
const errors = { ...draft.errors };
|
|
44664
44717
|
if (message)
|
|
44665
44718
|
errors[field] = message;
|
|
@@ -44694,24 +44747,24 @@ function reducer3(draft, action) {
|
|
|
44694
44747
|
case "set":
|
|
44695
44748
|
switch (action.field) {
|
|
44696
44749
|
case "platforms":
|
|
44750
|
+
if (isDeepStrictEqual3(action.value, draft.values.platforms))
|
|
44751
|
+
return draft;
|
|
44697
44752
|
return { ...draft, values: { ...draft.values, platforms: action.value } };
|
|
44698
|
-
case "branchPreset":
|
|
44699
|
-
|
|
44700
|
-
|
|
44701
|
-
|
|
44702
|
-
|
|
44703
|
-
|
|
44704
|
-
|
|
44705
|
-
|
|
44706
|
-
|
|
44707
|
-
|
|
44708
|
-
|
|
44709
|
-
|
|
44710
|
-
...draft.values,
|
|
44711
|
-
vcsProvider: decodeVcsProvider(action.value, draft.values.vcsProvider)
|
|
44712
|
-
}
|
|
44713
|
-
};
|
|
44753
|
+
case "branchPreset": {
|
|
44754
|
+
const next = decodeBranchPreset(action.value, draft.values.branchPreset);
|
|
44755
|
+
if (next === draft.values.branchPreset)
|
|
44756
|
+
return draft;
|
|
44757
|
+
return { ...draft, values: { ...draft.values, branchPreset: next } };
|
|
44758
|
+
}
|
|
44759
|
+
case "vcsProvider": {
|
|
44760
|
+
const next = decodeVcsProvider(action.value, draft.values.vcsProvider);
|
|
44761
|
+
if (next === draft.values.vcsProvider)
|
|
44762
|
+
return draft;
|
|
44763
|
+
return { ...draft, values: { ...draft.values, vcsProvider: next } };
|
|
44764
|
+
}
|
|
44714
44765
|
case "applyProject":
|
|
44766
|
+
if (action.value === draft.values.applyProject)
|
|
44767
|
+
return draft;
|
|
44715
44768
|
return { ...draft, values: { ...draft.values, applyProject: action.value } };
|
|
44716
44769
|
case "branchPolicyDetected":
|
|
44717
44770
|
return { ...draft, values: { ...draft.values, branchPolicyDetected: action.value } };
|
|
@@ -44732,6 +44785,8 @@ function reducer3(draft, action) {
|
|
|
44732
44785
|
const base2 = draft.values.branchPolicy ?? draft.values.branchPolicyDetected;
|
|
44733
44786
|
if (!base2)
|
|
44734
44787
|
return draft;
|
|
44788
|
+
if (action.value === base2.integration)
|
|
44789
|
+
return draft;
|
|
44735
44790
|
return {
|
|
44736
44791
|
...draft,
|
|
44737
44792
|
values: {
|
|
@@ -44748,11 +44803,14 @@ function reducer3(draft, action) {
|
|
|
44748
44803
|
const base2 = draft.values.branchPolicy ?? draft.values.branchPolicyDetected;
|
|
44749
44804
|
if (!base2)
|
|
44750
44805
|
return draft;
|
|
44806
|
+
const next = action.value || undefined;
|
|
44807
|
+
if ((base2.developBranch ?? undefined) === next)
|
|
44808
|
+
return draft;
|
|
44751
44809
|
return {
|
|
44752
44810
|
...draft,
|
|
44753
44811
|
values: {
|
|
44754
44812
|
...draft.values,
|
|
44755
|
-
branchPolicy: { ...base2, developBranch:
|
|
44813
|
+
branchPolicy: { ...base2, developBranch: next }
|
|
44756
44814
|
}
|
|
44757
44815
|
};
|
|
44758
44816
|
}
|
|
@@ -44874,6 +44932,9 @@ function defaultWorkspaceProvider(vcs) {
|
|
|
44874
44932
|
function workspaceDraftText(draft, field, value) {
|
|
44875
44933
|
const errorKey = field === "name" ? "workspaceName" : "workspaceGlob";
|
|
44876
44934
|
const message = field === "name" ? value.trim() ? null : "workspace name is required" : value.trim() ? null : "workspace pattern is required";
|
|
44935
|
+
if ((draft.workspaceDraft?.[field] ?? "") === value && (draft.errors[errorKey] ?? undefined) === (message ?? undefined)) {
|
|
44936
|
+
return draft;
|
|
44937
|
+
}
|
|
44877
44938
|
const errors = { ...draft.errors };
|
|
44878
44939
|
if (message)
|
|
44879
44940
|
errors[errorKey] = message;
|
|
@@ -46124,8 +46185,12 @@ var createLogger = (options = {}) => {
|
|
|
46124
46185
|
// packages/workit-cli/src/index.tsx
|
|
46125
46186
|
var jsx_dev_runtime2 = __toESM(require_jsx_dev_runtime(), 1);
|
|
46126
46187
|
var logger = createLogger({
|
|
46127
|
-
stderr: (event) =>
|
|
46128
|
-
|
|
46188
|
+
stderr: (event) => {
|
|
46189
|
+
if (event.level === "debug" || event.level === "info")
|
|
46190
|
+
return;
|
|
46191
|
+
process.stderr.write(`${JSON.stringify(event)}
|
|
46192
|
+
`);
|
|
46193
|
+
}
|
|
46129
46194
|
});
|
|
46130
46195
|
var HELP = `workit — workflow rails for agentic coding
|
|
46131
46196
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit interactive setup wizard (Ink TUI)",
|
|
6
6
|
"keywords": [
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"typecheck": "tsc --noEmit"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@brainervirus/workit-core": "^0.
|
|
38
|
-
"@brainervirus/workit-cursor": "^0.
|
|
39
|
-
"@brainervirus/workit-opencode": "^0.
|
|
37
|
+
"@brainervirus/workit-core": "^0.8.1",
|
|
38
|
+
"@brainervirus/workit-cursor": "^0.8.1",
|
|
39
|
+
"@brainervirus/workit-opencode": "^0.8.1",
|
|
40
40
|
"@inkjs/ui": "2.0.0",
|
|
41
41
|
"ink": "7.1.1",
|
|
42
42
|
"react": "19.2.8"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
|
45
|
-
"node": ">=
|
|
45
|
+
"node": ">=22"
|
|
46
46
|
}
|
|
47
47
|
}
|