@brainervirus/workit-cli 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +82 -22
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -43028,10 +43028,12 @@ import {
43028
43028
  copyFileSync as copyFileSync2,
43029
43029
  cpSync as cpSync3,
43030
43030
  existsSync as existsSync10,
43031
+ lstatSync as lstatSync2,
43031
43032
  mkdirSync as mkdirSync5,
43032
43033
  mkdtempSync,
43033
43034
  readFileSync as readFileSync10,
43034
43035
  readdirSync as readdirSync4,
43036
+ realpathSync as realpathSync2,
43035
43037
  renameSync,
43036
43038
  rmSync as rmSync2,
43037
43039
  statSync as statSync4,
@@ -43135,6 +43137,7 @@ var readSetupState = (dir = resolveConfigDir()) => ({
43135
43137
 
43136
43138
  // packages/workit-core/src/core/registration.ts
43137
43139
  import path7 from "node:path";
43140
+ var OPENCODE_NPM_PIN = "@brainervirus/workit-opencode";
43138
43141
  var isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
43139
43142
  var named = (s, name) => s === name || s.startsWith(`${name}@`);
43140
43143
  function isWorkitPlugin(value) {
@@ -43257,7 +43260,16 @@ function cursorHooksEntry(_packageDir) {
43257
43260
 
43258
43261
  // packages/workit-core/src/core/doctor.ts
43259
43262
  import { spawnSync as spawnSync2 } from "node:child_process";
43260
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, readFileSync as readFileSync9, statSync as statSync3, unlinkSync, writeFileSync as writeFileSync6 } from "node:fs";
43263
+ import {
43264
+ existsSync as existsSync9,
43265
+ lstatSync,
43266
+ mkdirSync as mkdirSync4,
43267
+ readFileSync as readFileSync9,
43268
+ readlinkSync,
43269
+ statSync as statSync3,
43270
+ unlinkSync,
43271
+ writeFileSync as writeFileSync6
43272
+ } from "node:fs";
43261
43273
  import os5 from "node:os";
43262
43274
  import path11 from "node:path";
43263
43275
 
@@ -52358,11 +52370,19 @@ var checkUtility = (res) => {
52358
52370
  detail: "git (and flock where required) on PATH"
52359
52371
  };
52360
52372
  };
52373
+ var isFragileCachePin = (entry) => {
52374
+ const n = entry.replaceAll("\\", "/").toLowerCase();
52375
+ if (!n.startsWith("file:"))
52376
+ return false;
52377
+ return n.includes("/caches/pnpm/dlx/") || n.includes("/_npx/") || n.includes("/.pacquet/") || n.includes("/library/caches/pnpm/");
52378
+ };
52361
52379
  var staleEntry = (entry) => {
52362
52380
  if (!entry)
52363
52381
  return "stale";
52364
52382
  if (entry.includes("git+file"))
52365
52383
  return "stale";
52384
+ if (isFragileCachePin(entry))
52385
+ return "fragile-cache";
52366
52386
  if (entry.startsWith("file:")) {
52367
52387
  const target = entry.replace(/^file:\/\//, "").replace(/^file:/, "");
52368
52388
  return existsSync9(target) ? "ok" : "missing-file";
@@ -52391,7 +52411,7 @@ var checkStalePin = (res) => {
52391
52411
  id: "stale_pin",
52392
52412
  status: "fail",
52393
52413
  detail: "no workit plugin registered in the opencode config",
52394
- fix: "Run install-opencode-plugin.sh to pin the workit plugin entry"
52414
+ fix: 'Run `workit init` and select OpenCode — pin "@brainervirus/workit-opencode"'
52395
52415
  };
52396
52416
  }
52397
52417
  const first = staleEntry(entries[0]);
@@ -52400,7 +52420,15 @@ var checkStalePin = (res) => {
52400
52420
  id: "stale_pin",
52401
52421
  status: "fail",
52402
52422
  detail: `stale workit pin: ${entries[0]}`,
52403
- fix: "Re-run install-opencode-plugin.sh — the pin points at a git+file or non-file source"
52423
+ fix: "Run `workit init` (or install-opencode-plugin.sh for a checkout) — replace git+file pins"
52424
+ };
52425
+ }
52426
+ if (first === "fragile-cache") {
52427
+ return {
52428
+ id: "stale_pin",
52429
+ status: "fail",
52430
+ detail: `workit pin points at a package-manager cache path: ${entries[0]}`,
52431
+ fix: 'Run `workit init` and select OpenCode — pin should be "@brainervirus/workit-opencode"'
52404
52432
  };
52405
52433
  }
52406
52434
  if (first === "missing-file") {
@@ -52408,7 +52436,7 @@ var checkStalePin = (res) => {
52408
52436
  id: "stale_pin",
52409
52437
  status: "fail",
52410
52438
  detail: `workit pin points at a missing file: ${entries[0]}`,
52411
- fix: "Re-run install-opencode-plugin.sh after restoring the checkout the pin references"
52439
+ fix: "Run `workit init` (or restore the checkout and re-run install-opencode-plugin.sh)"
52412
52440
  };
52413
52441
  }
52414
52442
  return { id: "stale_pin", status: "pass", detail: "opencode pin resolves" };
@@ -52458,6 +52486,22 @@ var checkStaleInstall = (res) => {
52458
52486
  detail: "cursor plugin not inspected on the opencode host"
52459
52487
  };
52460
52488
  }
52489
+ if (existsSync9(res.cursorPluginDir) && lstatSync(res.cursorPluginDir).isSymbolicLink()) {
52490
+ let target = "";
52491
+ try {
52492
+ target = readlinkSync(res.cursorPluginDir);
52493
+ } catch {
52494
+ target = "(unreadable)";
52495
+ }
52496
+ const n = target.replaceAll("\\", "/").toLowerCase();
52497
+ const fragile = n.includes("/caches/pnpm/dlx/") || n.includes("/_npx/") || n.includes("/.pacquet/") || n.includes("/library/caches/pnpm/");
52498
+ return {
52499
+ id: "stale_install",
52500
+ status: "fail",
52501
+ detail: fragile ? `stale_install: cursor plugin dir is a symlink into a package-manager cache (${target})` : `stale_install: cursor plugin dir is a symlink (${target}) — expected a real directory copy`,
52502
+ fix: "Run `workit init` and select Cursor — install must copy into ~/.cursor/plugins/local/workit"
52503
+ };
52504
+ }
52461
52505
  const canonicalMcp = cursorMcpServerEntry("").args.find((a) => a.startsWith("--package="));
52462
52506
  const mcpSelectors = pluginMcpSelectors(res);
52463
52507
  const legacyPin = (mcpSelectors ?? []).find((s) => s !== canonicalMcp && s.includes("@brainervirus/workit-cursor@"));
@@ -52657,7 +52701,9 @@ var checkCredentialMetadata = (res) => {
52657
52701
  tokenPaths.push(path11.join(res.configDir, "youtrack.token"));
52658
52702
  }
52659
52703
  const vcsJson = readJson(path11.join(res.configDir, "vcs.json"));
52660
- for (const key of ["gitlab", "github"]) {
52704
+ const active = typeof vcsJson?.provider === "string" ? vcsJson.provider.trim().toLowerCase() : null;
52705
+ const vcsKeys = active === "gitlab" || active === "github" ? [active] : ["gitlab", "github"];
52706
+ for (const key of vcsKeys) {
52661
52707
  const provider = vcsJson?.[key];
52662
52708
  if (provider && typeof provider === "object") {
52663
52709
  const tf = provider.tokenFile;
@@ -53517,7 +53563,15 @@ function adapterRoot(platform, res) {
53517
53563
  }
53518
53564
  return null;
53519
53565
  }
53520
- var opencodePin = (root) => {
53566
+ var isDevOpenCodeAdapterRoot = (root, dev) => {
53567
+ if (dev)
53568
+ return true;
53569
+ const norm = root.replaceAll("\\", "/");
53570
+ return /\/packages\/workit-opencode\/?$/.test(norm);
53571
+ };
53572
+ var resolveOpenCodePin = (root, opts = {}) => {
53573
+ if (!isDevOpenCodeAdapterRoot(root, opts.dev))
53574
+ return OPENCODE_NPM_PIN;
53521
53575
  for (const rel of ["src/plugin.ts", "dist/plugin.js"]) {
53522
53576
  const entry = path12.join(root, rel);
53523
53577
  if (existsSync10(entry))
@@ -53525,8 +53579,9 @@ var opencodePin = (root) => {
53525
53579
  }
53526
53580
  return null;
53527
53581
  };
53582
+ var opencodePin = (root, res) => resolveOpenCodePin(root, { dev: res.dev });
53528
53583
  function applyOpenCode(root, res) {
53529
- const pin = opencodePin(root);
53584
+ const pin = opencodePin(root, res);
53530
53585
  if (!pin) {
53531
53586
  return {
53532
53587
  platform: "opencode",
@@ -53613,30 +53668,35 @@ var preservedCursorRules = (src, dest) => {
53613
53668
  return preserved;
53614
53669
  };
53615
53670
  function copyPluginDir(src, dest) {
53671
+ const realSrc = realpathSync2(src);
53616
53672
  const marker = path12.join(dest, ".workit-root");
53617
- const synced = readFileSafe(marker)?.trim() === src && samePluginContent(src, dest);
53673
+ const destIsLink = existsSync10(dest) && lstatSync2(dest).isSymbolicLink();
53674
+ const synced = !destIsLink && readFileSafe(marker)?.trim() === realSrc && samePluginContent(realSrc, dest);
53618
53675
  if (synced)
53619
53676
  return "Skipped";
53620
53677
  const hadDir = existsSync10(dest);
53621
- const rules = preservedCursorRules(src, dest);
53678
+ const rules = preservedCursorRules(realSrc, dest);
53622
53679
  const parent = path12.dirname(dest);
53623
53680
  mkdirSync5(parent, { recursive: true });
53624
53681
  const swap = mkdtempSync(path12.join(parent, `.${path12.basename(dest)}.swap-`));
53625
53682
  const stage = path12.join(swap, "stage");
53626
53683
  const backup = path12.join(swap, "backup");
53627
53684
  try {
53628
- cpSync3(src, stage, {
53685
+ cpSync3(realSrc, stage, {
53629
53686
  recursive: true,
53630
- filter: (entry) => !path12.relative(src, entry).split(path12.sep).includes("node_modules")
53687
+ filter: (entry) => !path12.relative(realSrc, entry).split(path12.sep).includes("node_modules")
53631
53688
  });
53632
53689
  for (const [name, content] of rules) {
53633
53690
  mkdirSync5(path12.join(stage, "rules"), { recursive: true });
53634
53691
  writeFileSync7(path12.join(stage, "rules", name), content);
53635
53692
  }
53636
- writeFileSync7(path12.join(stage, ".workit-root"), src + `
53693
+ writeFileSync7(path12.join(stage, ".workit-root"), realSrc + `
53637
53694
  `, "utf8");
53638
- if (!samePluginContent(src, stage))
53695
+ if (!samePluginContent(realSrc, stage))
53639
53696
  throw new Error("staged adapter content is incomplete");
53697
+ if (lstatSync2(stage).isSymbolicLink()) {
53698
+ throw new Error("staged adapter resolved to a symlink — refusing fragile cache install");
53699
+ }
53640
53700
  if (hadDir)
53641
53701
  renameSync(dest, backup);
53642
53702
  try {
@@ -54394,7 +54454,7 @@ import os8 from "node:os";
54394
54454
  import path15 from "node:path";
54395
54455
 
54396
54456
  // packages/workit-core/src/core/uninstall.ts
54397
- import { existsSync as existsSync12, readFileSync as readFileSync11, realpathSync as realpathSync2, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
54457
+ import { existsSync as existsSync12, readFileSync as readFileSync11, realpathSync as realpathSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
54398
54458
  import os7 from "node:os";
54399
54459
  import path14 from "node:path";
54400
54460
  var resolveUninstallPaths = (options = {}) => {
@@ -54593,7 +54653,7 @@ var canonicalRemoveDirAllowed = (actionPath, res) => {
54593
54653
  return false;
54594
54654
  }
54595
54655
  try {
54596
- return realpathSync2(actionPath) === realpathSync2(expected);
54656
+ return realpathSync3(actionPath) === realpathSync3(expected);
54597
54657
  } catch {
54598
54658
  return true;
54599
54659
  }
@@ -56430,7 +56490,7 @@ import { createInterface as createInterface2 } from "node:readline/promises";
56430
56490
 
56431
56491
  // packages/workit-core/src/core.ts
56432
56492
  import { spawnSync as spawnSync4 } from "node:child_process";
56433
- import { existsSync as existsSync16, realpathSync as realpathSync7 } from "node:fs";
56493
+ import { existsSync as existsSync16, realpathSync as realpathSync8 } from "node:fs";
56434
56494
  import path22 from "node:path";
56435
56495
 
56436
56496
  // packages/workit-core/src/core/task-store.ts
@@ -59144,7 +59204,7 @@ async function runAuthorizedExternalAction(input, effect) {
59144
59204
  };
59145
59205
  }
59146
59206
  // packages/workit-core/src/core/task-engine.ts
59147
- import { realpathSync as realpathSync6 } from "node:fs";
59207
+ import { realpathSync as realpathSync7 } from "node:fs";
59148
59208
 
59149
59209
  // packages/workit-core/src/core/policy-resolver.ts
59150
59210
  var resolverInputSchema = object({
@@ -59988,7 +60048,7 @@ class WorkitCore {
59988
60048
  }
59989
60049
  contextRootError() {
59990
60050
  try {
59991
- if (realpathSync6(this.context.root) !== this.store.root)
60051
+ if (realpathSync7(this.context.root) !== this.store.root)
59992
60052
  return failure("invalid_input", "operation context root does not match the task store root");
59993
60053
  } catch {
59994
60054
  return failure("invalid_input", "operation context root cannot be resolved");
@@ -61217,7 +61277,7 @@ class WorkitCore {
61217
61277
  if (view.task.workspaceId !== view.workspace.id)
61218
61278
  return failure("invalid_input", "task and workspace bindings are invalid");
61219
61279
  try {
61220
- if (realpathSync6(view.workspace.root) !== this.store.root)
61280
+ if (realpathSync7(view.workspace.root) !== this.store.root)
61221
61281
  return failure("invalid_input", "task view root does not match the task store");
61222
61282
  } catch {
61223
61283
  return failure("invalid_input", "task view root cannot be resolved");
@@ -61486,7 +61546,7 @@ function resolveGitRevision(root, value) {
61486
61546
  }
61487
61547
  }
61488
61548
  function resolveInside(root, candidate) {
61489
- const base = realpathSync7(root);
61549
+ const base = realpathSync8(root);
61490
61550
  const target = path22.resolve(base, candidate);
61491
61551
  if (target !== base && !target.startsWith(base + path22.sep)) {
61492
61552
  throw new Error("path must stay inside repository root");
@@ -61494,14 +61554,14 @@ function resolveInside(root, candidate) {
61494
61554
  let ancestor = target;
61495
61555
  while (!existsSync16(ancestor))
61496
61556
  ancestor = path22.dirname(ancestor);
61497
- const canonicalAncestor = realpathSync7(ancestor);
61557
+ const canonicalAncestor = realpathSync8(ancestor);
61498
61558
  if (canonicalAncestor !== base && !canonicalAncestor.startsWith(base + path22.sep)) {
61499
61559
  throw new Error("path must stay inside repository root");
61500
61560
  }
61501
61561
  return target;
61502
61562
  }
61503
61563
  function run(root, executable, args, env = {}) {
61504
- const cwd = realpathSync7(root);
61564
+ const cwd = realpathSync8(root);
61505
61565
  const result = spawnSync4(executable, args, {
61506
61566
  cwd,
61507
61567
  encoding: "utf8",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "private": false,
5
5
  "description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
6
6
  "keywords": [
@@ -37,9 +37,9 @@
37
37
  "typecheck": "tsc --noEmit"
38
38
  },
39
39
  "dependencies": {
40
- "@brainervirus/workit-core": "^1.0.3",
41
- "@brainervirus/workit-cursor": "^1.0.3",
42
- "@brainervirus/workit-opencode": "^1.0.3",
40
+ "@brainervirus/workit-core": "^1.0.4",
41
+ "@brainervirus/workit-cursor": "^1.0.4",
42
+ "@brainervirus/workit-opencode": "^1.0.4",
43
43
  "@inkjs/ui": "2.0.0",
44
44
  "ink": "7.1.1",
45
45
  "react": "19.2.8"