@brainervirus/workit-cli 0.8.7 → 0.8.8
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 +168 -13
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -43490,7 +43490,11 @@ var checkLauncher = (res) => {
|
|
|
43490
43490
|
detail: "no dev checkout found (WORKFLOW_TOOLKIT_DEV) — skipping non-Cursor launcher checks"
|
|
43491
43491
|
};
|
|
43492
43492
|
}
|
|
43493
|
-
return {
|
|
43493
|
+
return {
|
|
43494
|
+
id: "launcher",
|
|
43495
|
+
status: "pass",
|
|
43496
|
+
detail: `${res.host} launcher/hook entries present`
|
|
43497
|
+
};
|
|
43494
43498
|
};
|
|
43495
43499
|
var checkUtility = (res) => {
|
|
43496
43500
|
const git = commandOnPath("git", res.env);
|
|
@@ -43510,7 +43514,11 @@ var checkUtility = (res) => {
|
|
|
43510
43514
|
fix: "Install util-linux (flock)"
|
|
43511
43515
|
};
|
|
43512
43516
|
}
|
|
43513
|
-
return {
|
|
43517
|
+
return {
|
|
43518
|
+
id: "utility",
|
|
43519
|
+
status: "pass",
|
|
43520
|
+
detail: "git (and flock where required) on PATH"
|
|
43521
|
+
};
|
|
43514
43522
|
};
|
|
43515
43523
|
var staleEntry = (entry) => {
|
|
43516
43524
|
if (!entry)
|
|
@@ -43532,7 +43540,11 @@ var checkStalePin = (res) => {
|
|
|
43532
43540
|
};
|
|
43533
43541
|
}
|
|
43534
43542
|
if (!existsSync7(res.opencodeConfig)) {
|
|
43535
|
-
return {
|
|
43543
|
+
return {
|
|
43544
|
+
id: "stale_pin",
|
|
43545
|
+
status: "pass",
|
|
43546
|
+
detail: "no opencode config — not registered"
|
|
43547
|
+
};
|
|
43536
43548
|
}
|
|
43537
43549
|
const cfg = readJson(res.opencodeConfig);
|
|
43538
43550
|
const entries = pluginEntries(cfg);
|
|
@@ -43563,6 +43575,118 @@ var checkStalePin = (res) => {
|
|
|
43563
43575
|
}
|
|
43564
43576
|
return { id: "stale_pin", status: "pass", detail: "opencode pin resolves" };
|
|
43565
43577
|
};
|
|
43578
|
+
var pluginMcpSelectors = (res) => {
|
|
43579
|
+
const p = path9.join(res.cursorPluginDir, "mcp.json");
|
|
43580
|
+
if (!existsSync7(p))
|
|
43581
|
+
return null;
|
|
43582
|
+
const cfg = readJson(p);
|
|
43583
|
+
const server = cfg?.mcpServers?.workit;
|
|
43584
|
+
if (!server || typeof server !== "object" || Array.isArray(server))
|
|
43585
|
+
return null;
|
|
43586
|
+
const args = server.args;
|
|
43587
|
+
if (!Array.isArray(args))
|
|
43588
|
+
return null;
|
|
43589
|
+
return args.map(String).filter((a) => a.startsWith("--package="));
|
|
43590
|
+
};
|
|
43591
|
+
var registryLatestVersion = (res) => {
|
|
43592
|
+
const seam = res.env.WORKIT_DOCTOR_STALE_REGISTRY_VERSION;
|
|
43593
|
+
if (typeof seam === "string" && seam) {
|
|
43594
|
+
return /^\d+(?:\.\d+){1,2}$/.test(seam) ? seam : null;
|
|
43595
|
+
}
|
|
43596
|
+
const cmd = res.env.WORKIT_DOCTOR_STALE_REGISTRY_CMD ?? (commandOnPath("npm", res.env) ? "npm" : null);
|
|
43597
|
+
if (!cmd)
|
|
43598
|
+
return null;
|
|
43599
|
+
try {
|
|
43600
|
+
const r = spawnSync2(cmd, ["view", CURSOR_RUNTIME_PACKAGE, "version"], {
|
|
43601
|
+
encoding: "utf8",
|
|
43602
|
+
timeout: 20000,
|
|
43603
|
+
env: res.env
|
|
43604
|
+
});
|
|
43605
|
+
const v = (r.stdout ?? "").trim().split(/\s+/)[0];
|
|
43606
|
+
return r.status === 0 && /^\d+(?:\.\d+){1,2}$/.test(v) ? v : null;
|
|
43607
|
+
} catch {
|
|
43608
|
+
return null;
|
|
43609
|
+
}
|
|
43610
|
+
};
|
|
43611
|
+
var installedPluginVersion = (res) => {
|
|
43612
|
+
const pkg = readJson(path9.join(res.cursorPluginDir, "package.json"));
|
|
43613
|
+
return typeof pkg?.version === "string" && pkg.version ? pkg.version : null;
|
|
43614
|
+
};
|
|
43615
|
+
var checkStaleInstall = (res) => {
|
|
43616
|
+
if (res.host !== "cursor" && res.host !== "cli") {
|
|
43617
|
+
return {
|
|
43618
|
+
id: "stale_install",
|
|
43619
|
+
status: "pass",
|
|
43620
|
+
detail: "cursor plugin not inspected on the opencode host"
|
|
43621
|
+
};
|
|
43622
|
+
}
|
|
43623
|
+
const canonicalMcp = cursorMcpServerEntry("").args.find((a) => a.startsWith("--package="));
|
|
43624
|
+
const mcpSelectors = pluginMcpSelectors(res);
|
|
43625
|
+
const legacyPin = (mcpSelectors ?? []).find((s) => s !== canonicalMcp && s.includes("@brainervirus/workit-cursor@"));
|
|
43626
|
+
if (legacyPin) {
|
|
43627
|
+
return {
|
|
43628
|
+
id: "stale_install",
|
|
43629
|
+
status: "fail",
|
|
43630
|
+
detail: `stale_install: plugin mcp.json pins a legacy selector ${legacyPin} (canonical: ${canonicalMcp})`,
|
|
43631
|
+
fix: "Re-run install-cursor-plugin.sh — it rewrites the workit MCP entry to the canonical @latest selector"
|
|
43632
|
+
};
|
|
43633
|
+
}
|
|
43634
|
+
const hooksFile = path9.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
|
|
43635
|
+
const hookCmd = readJson(hooksFile)?.hooks?.sessionStart?.[0]?.command ?? null;
|
|
43636
|
+
const canonicalHook = canonicalCursorHook;
|
|
43637
|
+
const staleHook = hookCmd !== null && hookCmd !== canonicalHook && !hookCmd.startsWith("node ") && hookCmd.includes("@brainervirus/workit-cursor@");
|
|
43638
|
+
if (staleHook) {
|
|
43639
|
+
return {
|
|
43640
|
+
id: "stale_install",
|
|
43641
|
+
status: "fail",
|
|
43642
|
+
detail: `stale_install: sessionStart hook runs a legacy selector (canonical: ${canonicalHook})`,
|
|
43643
|
+
fix: "Re-run install-cursor-plugin.sh — it rewrites the sessionStart hook to the canonical @latest selector"
|
|
43644
|
+
};
|
|
43645
|
+
}
|
|
43646
|
+
const installed = installedPluginVersion(res);
|
|
43647
|
+
const source = res.dev ? readJson(path9.join(res.dev, "packages/workit-cursor/package.json"))?.version ?? null : readJson(path9.join(packageRoot(), "package.json"))?.version ?? null;
|
|
43648
|
+
const localDist = mcpSelectors === null && hookCmd !== null && hookCmd.startsWith("node ");
|
|
43649
|
+
if (localDist && installed !== null && source !== null && !semverAtLeast(installed, source)) {
|
|
43650
|
+
return {
|
|
43651
|
+
id: "stale_install",
|
|
43652
|
+
status: "fail",
|
|
43653
|
+
detail: `stale_install: installed workit-cursor ${installed} is behind the current runtime ${source}`,
|
|
43654
|
+
fix: "Re-run install-cursor-plugin.sh — it refreshes the plugin directory and rewrites the workit MCP/hook entries"
|
|
43655
|
+
};
|
|
43656
|
+
}
|
|
43657
|
+
if (installed !== null && localDist) {
|
|
43658
|
+
const expected = registryLatestVersion(res);
|
|
43659
|
+
if (expected === null) {
|
|
43660
|
+
return {
|
|
43661
|
+
id: "registry_unreachable",
|
|
43662
|
+
status: "warn",
|
|
43663
|
+
registryProbed: true,
|
|
43664
|
+
detail: "registry_unreachable: cannot compare installed workit-cursor against the published runtime",
|
|
43665
|
+
fix: "Retry when the npm registry is reachable, or re-run install-cursor-plugin.sh to refresh the install"
|
|
43666
|
+
};
|
|
43667
|
+
}
|
|
43668
|
+
if (!semverAtLeast(installed, expected)) {
|
|
43669
|
+
return {
|
|
43670
|
+
id: "stale_install",
|
|
43671
|
+
status: "fail",
|
|
43672
|
+
registryProbed: true,
|
|
43673
|
+
detail: `stale_install: local-dist workit-cursor ${installed} is behind the published runtime ${expected}`,
|
|
43674
|
+
fix: "Re-run install-cursor-plugin.sh — it refreshes the plugin directory with the current build"
|
|
43675
|
+
};
|
|
43676
|
+
}
|
|
43677
|
+
return {
|
|
43678
|
+
id: "stale_install",
|
|
43679
|
+
status: "pass",
|
|
43680
|
+
registryProbed: true,
|
|
43681
|
+
detail: `installed local-dist workit-cursor ${installed} matches the published runtime ${expected}`
|
|
43682
|
+
};
|
|
43683
|
+
}
|
|
43684
|
+
return {
|
|
43685
|
+
id: "stale_install",
|
|
43686
|
+
status: "pass",
|
|
43687
|
+
detail: installed === null ? "installed workit-cursor selectors are canonical" : `installed workit-cursor ${installed} is metadata on the canonical @latest install (fresh at launch)`
|
|
43688
|
+
};
|
|
43689
|
+
};
|
|
43566
43690
|
var checkDuplicateRegistration = (res) => {
|
|
43567
43691
|
const problems = [];
|
|
43568
43692
|
const opencodeHost = res.host !== "cursor";
|
|
@@ -43598,7 +43722,11 @@ var checkDuplicateRegistration = (res) => {
|
|
|
43598
43722
|
}
|
|
43599
43723
|
}
|
|
43600
43724
|
if (problems.length === 0) {
|
|
43601
|
-
return {
|
|
43725
|
+
return {
|
|
43726
|
+
id: "duplicate_registration",
|
|
43727
|
+
status: "pass",
|
|
43728
|
+
detail: "no duplicate registrations"
|
|
43729
|
+
};
|
|
43602
43730
|
}
|
|
43603
43731
|
return {
|
|
43604
43732
|
id: "duplicate_registration",
|
|
@@ -43624,7 +43752,11 @@ var checkMalformedConfig = (res) => {
|
|
|
43624
43752
|
files.push(res.cursorMcp);
|
|
43625
43753
|
const bad = files.filter((p) => !parsesAsConfigObject(p));
|
|
43626
43754
|
if (bad.length === 0)
|
|
43627
|
-
return {
|
|
43755
|
+
return {
|
|
43756
|
+
id: "malformed_config",
|
|
43757
|
+
status: "pass",
|
|
43758
|
+
detail: "config files parse"
|
|
43759
|
+
};
|
|
43628
43760
|
return {
|
|
43629
43761
|
id: "malformed_config",
|
|
43630
43762
|
status: "fail",
|
|
@@ -43635,10 +43767,18 @@ var checkMalformedConfig = (res) => {
|
|
|
43635
43767
|
var checkWorkspaceMismatch = (res) => {
|
|
43636
43768
|
const file = path9.join(res.configDir, "workspaces.json");
|
|
43637
43769
|
if (!existsSync7(file))
|
|
43638
|
-
return {
|
|
43770
|
+
return {
|
|
43771
|
+
id: "workspace_mismatch",
|
|
43772
|
+
status: "pass",
|
|
43773
|
+
detail: "no workspaces configured"
|
|
43774
|
+
};
|
|
43639
43775
|
const ws = readJson(file);
|
|
43640
43776
|
if (!Array.isArray(ws?.workspaces)) {
|
|
43641
|
-
return {
|
|
43777
|
+
return {
|
|
43778
|
+
id: "workspace_mismatch",
|
|
43779
|
+
status: "pass",
|
|
43780
|
+
detail: "no workspaces configured"
|
|
43781
|
+
};
|
|
43642
43782
|
}
|
|
43643
43783
|
const match = resolveWorkspaceFrom(res.cwd, res.configDir);
|
|
43644
43784
|
if (match)
|
|
@@ -43680,7 +43820,11 @@ var checkCredentialMetadata = (res) => {
|
|
|
43680
43820
|
}
|
|
43681
43821
|
}
|
|
43682
43822
|
if (tokenPaths.length === 0) {
|
|
43683
|
-
return {
|
|
43823
|
+
return {
|
|
43824
|
+
id: "credential_metadata",
|
|
43825
|
+
status: "pass",
|
|
43826
|
+
detail: "no credentials configured"
|
|
43827
|
+
};
|
|
43684
43828
|
}
|
|
43685
43829
|
const problems = [];
|
|
43686
43830
|
for (const raw of tokenPaths) {
|
|
@@ -43718,7 +43862,11 @@ var checkLogWritable = (res) => {
|
|
|
43718
43862
|
mkdirSync2(logsDir, { recursive: true, mode: 448 });
|
|
43719
43863
|
writeFileSync4(probe, `{"probe":true}
|
|
43720
43864
|
`, { mode: 384 });
|
|
43721
|
-
return {
|
|
43865
|
+
return {
|
|
43866
|
+
id: "log_writable",
|
|
43867
|
+
status: "pass",
|
|
43868
|
+
detail: "log directory writable"
|
|
43869
|
+
};
|
|
43722
43870
|
} catch (err) {
|
|
43723
43871
|
return {
|
|
43724
43872
|
id: "log_writable",
|
|
@@ -43739,6 +43887,7 @@ var RUN_CHECKS = [
|
|
|
43739
43887
|
checkLauncher,
|
|
43740
43888
|
checkUtility,
|
|
43741
43889
|
checkStalePin,
|
|
43890
|
+
checkStaleInstall,
|
|
43742
43891
|
checkDuplicateRegistration,
|
|
43743
43892
|
checkMalformedConfig,
|
|
43744
43893
|
checkWorkspaceMismatch,
|
|
@@ -43751,21 +43900,27 @@ var INSTALLER_REQUIRED = new Set([
|
|
|
43751
43900
|
"launcher",
|
|
43752
43901
|
"utility",
|
|
43753
43902
|
"stale_pin",
|
|
43903
|
+
"stale_install",
|
|
43754
43904
|
"duplicate_registration",
|
|
43755
43905
|
"malformed_config"
|
|
43756
43906
|
]);
|
|
43757
43907
|
var runDoctor = (options = {}) => {
|
|
43758
43908
|
const res = resolve(options);
|
|
43759
43909
|
const raw = RUN_CHECKS.map((fn) => fn(res));
|
|
43760
|
-
const checks = res.installer ? raw.map((c) => c.status === "fail" && !INSTALLER_REQUIRED.has(c.id) ? {
|
|
43910
|
+
const checks = res.installer ? raw.map((c) => c.status === "fail" && !INSTALLER_REQUIRED.has(c.id) ? {
|
|
43911
|
+
...c,
|
|
43912
|
+
status: "warn",
|
|
43913
|
+
detail: `${c.detail} (not enforced by installer)`
|
|
43914
|
+
} : c) : raw;
|
|
43761
43915
|
const failed = checks.filter((c) => c.status === "fail").length;
|
|
43762
43916
|
const warned = checks.filter((c) => c.status === "warn").length;
|
|
43763
43917
|
const passed = checks.filter((c) => c.status === "pass").length;
|
|
43764
43918
|
const exitCode = failed > 0 ? 1 : 0;
|
|
43919
|
+
const offline = !raw.some((c) => ("registryProbed" in c) && c.registryProbed);
|
|
43765
43920
|
const report = {
|
|
43766
43921
|
ok: failed === 0,
|
|
43767
43922
|
exitCode,
|
|
43768
|
-
offline
|
|
43923
|
+
offline,
|
|
43769
43924
|
host: res.host,
|
|
43770
43925
|
checked_at: new Date().toISOString(),
|
|
43771
43926
|
summary: { passed, warned, failed, total: checks.length },
|
|
@@ -43775,7 +43930,7 @@ var runDoctor = (options = {}) => {
|
|
|
43775
43930
|
getDiagnosticLogger()?.info(EVENT.doctor, {
|
|
43776
43931
|
host: res.host,
|
|
43777
43932
|
exit_code: exitCode,
|
|
43778
|
-
offline
|
|
43933
|
+
offline,
|
|
43779
43934
|
failed: checks.filter((c) => c.status === "fail").map((c) => c.id),
|
|
43780
43935
|
total: checks.length
|
|
43781
43936
|
});
|
|
@@ -48582,7 +48737,7 @@ function runDoctorCommand(args) {
|
|
|
48582
48737
|
if (args.includes("--json")) {
|
|
48583
48738
|
console.log(JSON.stringify(report, null, 2));
|
|
48584
48739
|
} else {
|
|
48585
|
-
console.log(`workit doctor — ${report.ok ? "healthy" : "problems found"} (offline)`);
|
|
48740
|
+
console.log(`workit doctor — ${report.ok ? "healthy" : "problems found"} (${report.offline ? "offline" : "online"})`);
|
|
48586
48741
|
for (const check2 of report.checks) {
|
|
48587
48742
|
const mark = check2.status === "fail" ? "FAIL" : check2.status === "warn" ? "WARN" : "ok ";
|
|
48588
48743
|
console.log(`${mark} ${check2.id} — ${check2.detail}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit interactive setup wizard (Ink TUI)",
|
|
6
6
|
"keywords": [
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"typecheck": "tsc --noEmit"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@brainervirus/workit-core": "^0.8.
|
|
38
|
-
"@brainervirus/workit-cursor": "^0.8.
|
|
39
|
-
"@brainervirus/workit-opencode": "^0.8.
|
|
37
|
+
"@brainervirus/workit-core": "^0.8.8",
|
|
38
|
+
"@brainervirus/workit-cursor": "^0.8.8",
|
|
39
|
+
"@brainervirus/workit-opencode": "^0.8.8",
|
|
40
40
|
"@inkjs/ui": "2.0.0",
|
|
41
41
|
"ink": "7.1.1",
|
|
42
42
|
"react": "19.2.8"
|