runwork 0.21.0 → 0.21.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.
Files changed (2) hide show
  1. package/dist/index.js +436 -360
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -943,6 +943,58 @@ var init_store = __esm(() => {
943
943
  CREDENTIALS_FILE = join2(RUNWORK_DIR, ".credentials");
944
944
  });
945
945
 
946
+ // src/utils/workspace-state.ts
947
+ import { join as join3 } from "path";
948
+ import { homedir as homedir2 } from "os";
949
+ function storePath() {
950
+ return join3(homedir2(), ".runwork", "workspaces.json");
951
+ }
952
+ function readFile() {
953
+ const parsed = readJsonOrNull(storePath());
954
+ if (parsed && parsed.workspaces && typeof parsed.workspaces === "object")
955
+ return parsed;
956
+ return { workspaces: {} };
957
+ }
958
+ function loadWorkspaceRecord(workspaceId) {
959
+ return readFile().workspaces[workspaceId] ?? {};
960
+ }
961
+ function updateWorkspaceRecord(workspaceId, patch) {
962
+ if (!workspaceId)
963
+ return;
964
+ const file = readFile();
965
+ file.workspaces[workspaceId] = { ...file.workspaces[workspaceId], ...patch };
966
+ writeJsonAtomic(storePath(), file);
967
+ }
968
+ function clearParkedState(workspaceId) {
969
+ const file = readFile();
970
+ const record = file.workspaces[workspaceId];
971
+ if (!record?.parked)
972
+ return;
973
+ delete record.parked;
974
+ writeJsonAtomic(storePath(), file);
975
+ }
976
+ function forgetWorkspaceSelection() {
977
+ const statePath = join3(homedir2(), ".runwork", "setup.json");
978
+ const state = readJsonOrNull(statePath);
979
+ if (!state)
980
+ return false;
981
+ if (!state.workspaceId && !state.workspaceName && !state.workspaceSlug)
982
+ return false;
983
+ const next = { ...state };
984
+ delete next.workspaceId;
985
+ delete next.workspaceName;
986
+ delete next.workspaceSlug;
987
+ try {
988
+ writeJsonAtomic(statePath, next);
989
+ return true;
990
+ } catch {
991
+ return false;
992
+ }
993
+ }
994
+ var init_workspace_state = __esm(() => {
995
+ init_atomic_json();
996
+ });
997
+
946
998
  // src/utils/subprocess.ts
947
999
  import {
948
1000
  execFileSync as cpExecFileSync,
@@ -1197,18 +1249,32 @@ function extractBaseUrl(loginUrl) {
1197
1249
  return DEFAULT_BASE_URL2;
1198
1250
  }
1199
1251
  }
1252
+ function forgetWorkspaceIfAccountChanged(previousEmail, nextEmail) {
1253
+ if (!previousEmail || previousEmail === nextEmail)
1254
+ return;
1255
+ forgetWorkspaceSelection();
1256
+ }
1200
1257
  async function pollAndSave(client, sessionId, baseUrl) {
1201
- const maxAttempts = 360;
1202
- const pollInterval = 5000;
1203
- for (let i = 0;i < maxAttempts; i++) {
1204
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
1258
+ const deadline = Date.now() + 1800000;
1259
+ const EAGER_INTERVAL = 1000;
1260
+ const EAGER_WINDOW = 30000;
1261
+ const SETTLED_INTERVAL = 5000;
1262
+ const startedAt = Date.now();
1263
+ const previousEmail = getCredentials()?.email;
1264
+ for (;; ) {
1205
1265
  const result = await client.pollLogin(sessionId);
1206
1266
  if (result) {
1267
+ forgetWorkspaceIfAccountChanged(previousEmail, result.email);
1207
1268
  saveCredentials(result);
1208
1269
  await configureGitCredentials(result.baseUrl || baseUrl);
1209
1270
  console.log(`Logged in as ${result.email}`);
1210
1271
  return result;
1211
1272
  }
1273
+ const remaining = deadline - Date.now();
1274
+ if (remaining <= 0)
1275
+ break;
1276
+ const interval = Date.now() - startedAt < EAGER_WINDOW ? EAGER_INTERVAL : SETTLED_INTERVAL;
1277
+ await new Promise((resolve) => setTimeout(resolve, Math.min(interval, remaining)));
1212
1278
  }
1213
1279
  console.error("Login timed out. Please try again.");
1214
1280
  process.exit(1);
@@ -1217,6 +1283,7 @@ var DEFAULT_BASE_URL2 = "https://runwork.ai";
1217
1283
  var init_login_flow = __esm(() => {
1218
1284
  init_client();
1219
1285
  init_store();
1286
+ init_workspace_state();
1220
1287
  init_credentials();
1221
1288
  });
1222
1289
 
@@ -1315,7 +1382,7 @@ var init_identity = __esm(() => {
1315
1382
  // src/git/preflight.ts
1316
1383
  import { existsSync as existsSync4 } from "fs";
1317
1384
  import { win32 as winPath } from "path";
1318
- import { homedir as homedir2 } from "os";
1385
+ import { homedir as homedir3 } from "os";
1319
1386
  function tryRun(bin) {
1320
1387
  try {
1321
1388
  const out = execFileSync(bin, ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
@@ -1377,7 +1444,7 @@ function canonicalGitCandidates() {
1377
1444
  paths.push(winPath.join(...parts));
1378
1445
  }
1379
1446
  };
1380
- const home = homedir2();
1447
+ const home = homedir3();
1381
1448
  push(process.env.ProgramFiles, "Git", "cmd", "git.exe");
1382
1449
  push(process.env["ProgramFiles(x86)"], "Git", "cmd", "git.exe");
1383
1450
  push(process.env.LOCALAPPDATA, "Programs", "Git", "cmd", "git.exe");
@@ -1570,7 +1637,7 @@ async function resolveApp(client, nameOrId, workspaceId) {
1570
1637
 
1571
1638
  // src/utils/ignore-matcher.ts
1572
1639
  import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
1573
- import { basename, join as join3 } from "path";
1640
+ import { basename, join as join4 } from "path";
1574
1641
  function defaultIgnoreSets() {
1575
1642
  return {
1576
1643
  dirs: new Set(DEFAULT_DIR_NAMES),
@@ -1610,7 +1677,7 @@ function parseGitignoreContent(content) {
1610
1677
  return { dirs, files };
1611
1678
  }
1612
1679
  function loadGitignoreFromDir(dir) {
1613
- const path = join3(dir, ".gitignore");
1680
+ const path = join4(dir, ".gitignore");
1614
1681
  if (!existsSync5(path))
1615
1682
  return { dirs: new Set, files: new Set };
1616
1683
  try {
@@ -1671,7 +1738,7 @@ var init_ignore_matcher = __esm(() => {
1671
1738
  // src/template/manifest.ts
1672
1739
  import { createHash } from "crypto";
1673
1740
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync6, readdirSync, mkdirSync as mkdirSync2 } from "fs";
1674
- import { join as join4, relative, sep } from "path";
1741
+ import { join as join5, relative, sep } from "path";
1675
1742
  function sha256(data) {
1676
1743
  return "sha256:" + createHash("sha256").update(data).digest("hex");
1677
1744
  }
@@ -1688,7 +1755,7 @@ function walkDir(dir, base, sets) {
1688
1755
  if (dotIndex >= 0 && sets.extensions.has(entry.name.slice(dotIndex)))
1689
1756
  continue;
1690
1757
  }
1691
- const fullPath = join4(dir, entry.name);
1758
+ const fullPath = join5(dir, entry.name);
1692
1759
  if (entry.isDirectory()) {
1693
1760
  results.push(...walkDir(fullPath, base, sets));
1694
1761
  } else if (entry.isFile()) {
@@ -1702,20 +1769,20 @@ async function generateManifest(dir) {
1702
1769
  const sets = buildIgnoreSets(dir);
1703
1770
  const allFiles = walkDir(dir, dir, sets);
1704
1771
  for (const relPath of allFiles) {
1705
- const content = readFileSync5(join4(dir, relPath));
1772
+ const content = readFileSync5(join5(dir, relPath));
1706
1773
  files[relPath] = sha256(content);
1707
1774
  }
1708
1775
  return { version: 1, files };
1709
1776
  }
1710
1777
  async function saveManifest(dir, manifest) {
1711
- const manifestDir = join4(dir, ".runwork");
1778
+ const manifestDir = join5(dir, ".runwork");
1712
1779
  if (!existsSync6(manifestDir)) {
1713
1780
  mkdirSync2(manifestDir, { recursive: true });
1714
1781
  }
1715
- writeFileSync2(join4(manifestDir, "template-manifest.json"), JSON.stringify(manifest, null, 2));
1782
+ writeFileSync2(join5(manifestDir, "template-manifest.json"), JSON.stringify(manifest, null, 2));
1716
1783
  }
1717
1784
  async function loadManifest(dir) {
1718
- const manifestPath = join4(dir, ".runwork", "template-manifest.json");
1785
+ const manifestPath = join5(dir, ".runwork", "template-manifest.json");
1719
1786
  if (!existsSync6(manifestPath))
1720
1787
  return null;
1721
1788
  try {
@@ -1752,7 +1819,7 @@ async function detectUserEdits(dir, manifest) {
1752
1819
  continue;
1753
1820
  const expectedHash = manifest.files[relPath];
1754
1821
  if (expectedHash) {
1755
- const content = readFileSync5(join4(dir, relPath));
1822
+ const content = readFileSync5(join5(dir, relPath));
1756
1823
  if (sha256(content) === expectedHash)
1757
1824
  continue;
1758
1825
  }
@@ -1774,7 +1841,7 @@ async function detectUserEdits(dir, manifest) {
1774
1841
  continue;
1775
1842
  if (trackedFiles.has(relPath))
1776
1843
  continue;
1777
- const filePath = join4(dir, relPath);
1844
+ const filePath = join5(dir, relPath);
1778
1845
  try {
1779
1846
  const content = readFileSync5(filePath);
1780
1847
  if (sha256(content) !== expectedHash) {
@@ -1791,7 +1858,7 @@ var init_manifest = __esm(() => {
1791
1858
 
1792
1859
  // src/utils/zip.ts
1793
1860
  import { mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync6, statSync, writeFileSync as writeFileSync3 } from "fs";
1794
- import { join as join5, dirname as dirname2, relative as relative2, sep as sep2 } from "path";
1861
+ import { join as join6, dirname as dirname2, relative as relative2, sep as sep2 } from "path";
1795
1862
  import { unzipSync, zipSync } from "fflate";
1796
1863
  function ensureDirSync(dir) {
1797
1864
  try {
@@ -1804,7 +1871,7 @@ function ensureDirSync(dir) {
1804
1871
  function extractZip(zipData, targetDir) {
1805
1872
  const files = unzipSync(new Uint8Array(zipData));
1806
1873
  for (const [path, data] of Object.entries(files)) {
1807
- const fullPath = join5(targetDir, path);
1874
+ const fullPath = join6(targetDir, path);
1808
1875
  if (path.endsWith("/")) {
1809
1876
  ensureDirSync(fullPath);
1810
1877
  continue;
@@ -1817,7 +1884,7 @@ function createZipFromDir(sourceDir, outputPath) {
1817
1884
  const files = {};
1818
1885
  const walk = (dir) => {
1819
1886
  for (const entry of readdirSync2(dir)) {
1820
- const absPath = join5(dir, entry);
1887
+ const absPath = join6(dir, entry);
1821
1888
  const stats = statSync(absPath);
1822
1889
  if (stats.isDirectory()) {
1823
1890
  walk(absPath);
@@ -1836,14 +1903,14 @@ var init_zip = () => {};
1836
1903
 
1837
1904
  // src/utils/fs.ts
1838
1905
  import { readdirSync as readdirSync3, rmSync as rmSync2 } from "fs";
1839
- import { join as join6, relative as relative3, sep as sep3 } from "path";
1906
+ import { join as join7, relative as relative3, sep as sep3 } from "path";
1840
1907
  function removeNestedGitDirs(rootDir) {
1841
1908
  const entries = readdirSync3(rootDir, { recursive: true, withFileTypes: true });
1842
1909
  for (const entry of entries) {
1843
1910
  if (entry.name !== ".git" || !entry.isDirectory())
1844
1911
  continue;
1845
1912
  const parentPath = "parentPath" in entry ? entry.parentPath : entry.path;
1846
- const fullPath = join6(parentPath, entry.name);
1913
+ const fullPath = join7(parentPath, entry.name);
1847
1914
  const rel = relative3(rootDir, fullPath);
1848
1915
  const depth = rel.split(sep3).length;
1849
1916
  if (depth >= 2) {
@@ -1854,9 +1921,9 @@ function removeNestedGitDirs(rootDir) {
1854
1921
  var init_fs = () => {};
1855
1922
 
1856
1923
  // src/ui/banner.ts
1857
- import { homedir as homedir3 } from "os";
1924
+ import { homedir as homedir4 } from "os";
1858
1925
  function prettyPath(dir) {
1859
- const home = homedir3();
1926
+ const home = homedir4();
1860
1927
  if (dir === home)
1861
1928
  return "~";
1862
1929
  if (dir.startsWith(home + "/"))
@@ -2126,8 +2193,8 @@ __export(exports_init, {
2126
2193
  });
2127
2194
  import { Command as Command2 } from "commander";
2128
2195
  import { writeFileSync as writeFileSync4, existsSync as existsSync7, mkdirSync as mkdirSync4 } from "fs";
2129
- import { join as join7, resolve } from "path";
2130
- import { homedir as homedir4 } from "os";
2196
+ import { join as join8, resolve } from "path";
2197
+ import { homedir as homedir5 } from "os";
2131
2198
  async function execInit(client, appName, workspace, options = {}, creds) {
2132
2199
  const app = await client.initApp(workspace.id, appName);
2133
2200
  const slug = app.slug || appName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
@@ -2135,7 +2202,7 @@ async function execInit(client, appName, workspace, options = {}, creds) {
2135
2202
  if (!options.here && !existsSync7(parentDir)) {
2136
2203
  mkdirSync4(parentDir, { recursive: true });
2137
2204
  }
2138
- const dir = join7(parentDir, slug);
2205
+ const dir = join8(parentDir, slug);
2139
2206
  if (existsSync7(dir)) {
2140
2207
  console.error(`Directory "${dir}" already exists.`);
2141
2208
  process.exit(1);
@@ -2162,8 +2229,8 @@ async function execInit(client, appName, workspace, options = {}, creds) {
2162
2229
  appId: app.id,
2163
2230
  appName: app.name
2164
2231
  };
2165
- writeFileSync4(join7(dir, ".runwork.json"), JSON.stringify(config, null, 2));
2166
- if (!existsSync7(join7(dir, ".git"))) {
2232
+ writeFileSync4(join8(dir, ".runwork.json"), JSON.stringify(config, null, 2));
2233
+ if (!existsSync7(join8(dir, ".git"))) {
2167
2234
  try {
2168
2235
  execFileSync("git", ["init"], { cwd: dir, stdio: "pipe" });
2169
2236
  } catch (err) {
@@ -2181,8 +2248,8 @@ async function execInit(client, appName, workspace, options = {}, creds) {
2181
2248
  } catch {
2182
2249
  execFileSync("git", ["remote", "set-url", "runwork", remoteUrl], { cwd: dir, stdio: "pipe" });
2183
2250
  }
2184
- if (!existsSync7(join7(dir, ".gitignore"))) {
2185
- writeFileSync4(join7(dir, ".gitignore"), `node_modules/
2251
+ if (!existsSync7(join8(dir, ".gitignore"))) {
2252
+ writeFileSync4(join8(dir, ".gitignore"), `node_modules/
2186
2253
  .runwork/
2187
2254
  .dev.vars
2188
2255
  `);
@@ -2273,7 +2340,7 @@ var init_init = __esm(() => {
2273
2340
  init_fs();
2274
2341
  init_banner();
2275
2342
  init_agent_guidance();
2276
- DEFAULT_APPS_DIR = join7(homedir4(), ".runwork", "apps");
2343
+ DEFAULT_APPS_DIR = join8(homedir5(), ".runwork", "apps");
2277
2344
  initCommand = new Command2("init").alias("create").description("Create a new Runwork app").argument("[name]", "App name").option("--workspace <name-or-id>", "Workspace name or ID (skips interactive selection)").option("--here", `Scaffold in the current directory instead of ${DEFAULT_APPS_DIR}/<slug>`).action(async (name, options) => {
2278
2345
  await runCreateFlow(name, options?.workspace, { here: options?.here });
2279
2346
  });
@@ -2435,7 +2502,7 @@ __export(exports_clone, {
2435
2502
  });
2436
2503
  import { Command as Command3 } from "commander";
2437
2504
  import { writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync8 } from "fs";
2438
- import { join as join8, resolve as resolve2 } from "path";
2505
+ import { join as join9, resolve as resolve2 } from "path";
2439
2506
  async function execClone(client, app, directory, creds) {
2440
2507
  const slug = app.slug || app.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2441
2508
  const dir = directory || slug;
@@ -2452,7 +2519,7 @@ async function execClone(client, app, directory, creds) {
2452
2519
  }
2453
2520
  const manifest = await generateManifest(dir);
2454
2521
  await saveManifest(dir, manifest);
2455
- if (!existsSync8(join8(dir, ".git"))) {
2522
+ if (!existsSync8(join9(dir, ".git"))) {
2456
2523
  try {
2457
2524
  execFileSync("git", ["init"], { cwd: dir, stdio: "pipe" });
2458
2525
  } catch (err) {
@@ -2489,11 +2556,11 @@ async function execClone(client, app, directory, creds) {
2489
2556
  appId: app.id,
2490
2557
  appName: app.name
2491
2558
  };
2492
- writeFileSync5(join8(dir, ".runwork.json"), JSON.stringify(config, null, 2));
2559
+ writeFileSync5(join9(dir, ".runwork.json"), JSON.stringify(config, null, 2));
2493
2560
  try {
2494
2561
  const { skill } = await client.getAppSkill(app.id);
2495
2562
  if (skill) {
2496
- writeFileSync5(join8(dir, "SKILL.md"), skill, "utf-8");
2563
+ writeFileSync5(join9(dir, "SKILL.md"), skill, "utf-8");
2497
2564
  }
2498
2565
  } catch {}
2499
2566
  return {
@@ -2627,7 +2694,7 @@ App "${cloneResult.appName}" cloned to ${cloneResult.directory}`);
2627
2694
  // src/git/auto-commit.ts
2628
2695
  import { readFileSync as readFileSync7 } from "fs";
2629
2696
  import { watch } from "chokidar";
2630
- import { join as join9, relative as relative4 } from "path";
2697
+ import { join as join10, relative as relative4 } from "path";
2631
2698
  async function watchAndAutoCommit(directory, client, appId, callbacks) {
2632
2699
  activeCallbacks = callbacks;
2633
2700
  const ignoreSets = buildIgnoreSets(directory);
@@ -2687,7 +2754,7 @@ async function executeFastSync(directory, client, appId) {
2687
2754
  if (BINARY_EXTENSIONS.has(ext.toLowerCase()))
2688
2755
  continue;
2689
2756
  try {
2690
- const contents = readFileSync7(join9(directory, filePath), "utf-8");
2757
+ const contents = readFileSync7(join10(directory, filePath), "utf-8");
2691
2758
  files.push({ filePath, fileContents: contents });
2692
2759
  } catch {}
2693
2760
  }
@@ -2854,7 +2921,7 @@ var init_auto_commit = __esm(() => {
2854
2921
 
2855
2922
  // src/git/sync.ts
2856
2923
  import { unlinkSync as unlinkSync2 } from "fs";
2857
- import { join as join10 } from "path";
2924
+ import { join as join11 } from "path";
2858
2925
  function hasCommits(cwd) {
2859
2926
  try {
2860
2927
  execFileSync("git", ["rev-parse", "HEAD"], { cwd, stdio: "pipe" });
@@ -2888,7 +2955,7 @@ function removeConflictingUntrackedFiles(cwd) {
2888
2955
  for (const file of remoteFiles) {
2889
2956
  if (untracked.has(file)) {
2890
2957
  try {
2891
- unlinkSync2(join10(cwd, file));
2958
+ unlinkSync2(join11(cwd, file));
2892
2959
  } catch {}
2893
2960
  }
2894
2961
  }
@@ -2982,11 +3049,11 @@ var init_sync = __esm(() => {
2982
3049
 
2983
3050
  // src/git/critical-files.ts
2984
3051
  import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync9 } from "fs";
2985
- import { join as join11 } from "path";
3052
+ import { join as join12 } from "path";
2986
3053
  function snapshotCriticalFiles(cwd) {
2987
3054
  const snapshots = [];
2988
3055
  for (const rel of CRITICAL_FILES) {
2989
- const abs = join11(cwd, rel);
3056
+ const abs = join12(cwd, rel);
2990
3057
  if (!existsSync9(abs))
2991
3058
  continue;
2992
3059
  try {
@@ -2998,7 +3065,7 @@ function snapshotCriticalFiles(cwd) {
2998
3065
  function restoreMissingCriticalFiles(cwd, snapshots) {
2999
3066
  const restored = [];
3000
3067
  for (const snap of snapshots) {
3001
- const abs = join11(cwd, snap.path);
3068
+ const abs = join12(cwd, snap.path);
3002
3069
  if (existsSync9(abs))
3003
3070
  continue;
3004
3071
  try {
@@ -3042,7 +3109,7 @@ function buildStartupSyncSummary(input) {
3042
3109
 
3043
3110
  // src/logs/tailer.ts
3044
3111
  import { appendFileSync, mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
3045
- import { join as join12, dirname as dirname3 } from "path";
3112
+ import { join as join13, dirname as dirname3 } from "path";
3046
3113
  function formatTime() {
3047
3114
  const now = new Date;
3048
3115
  return [
@@ -3090,7 +3157,7 @@ function startLogTailer(options) {
3090
3157
  toFile,
3091
3158
  intervalMs = 5000
3092
3159
  } = options;
3093
- const logFilePath = join12(projectDir, LOG_FILE);
3160
+ const logFilePath = join13(projectDir, LOG_FILE);
3094
3161
  if (toFile) {
3095
3162
  mkdirSync6(dirname3(logFilePath), { recursive: true });
3096
3163
  writeFileSync7(logFilePath, `# Runwork dev logs - started ${new Date().toISOString()}
@@ -7503,11 +7570,11 @@ export {};
7503
7570
 
7504
7571
  // src/types-manager.ts
7505
7572
  import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync4, copyFileSync, writeFileSync as writeFileSync9 } from "fs";
7506
- import { join as join14 } from "path";
7573
+ import { join as join15 } from "path";
7507
7574
  async function populateTypes(projectDir) {
7508
- const typesDir = join14(projectDir, TYPES_DIR);
7575
+ const typesDir = join15(projectDir, TYPES_DIR);
7509
7576
  mkdirSync9(typesDir, { recursive: true });
7510
- const frameworkDist = join14(projectDir, "node_modules/@runworkai/framework/dist");
7577
+ const frameworkDist = join15(projectDir, "node_modules/@runworkai/framework/dist");
7511
7578
  if (existsSync14(frameworkDist)) {
7512
7579
  copyDtsFiles(frameworkDist, typesDir);
7513
7580
  console.log("Types populated from node_modules/@runworkai/framework");
@@ -7516,7 +7583,7 @@ async function populateTypes(projectDir) {
7516
7583
  const typeEntries = Object.entries(BUNDLED_TYPES);
7517
7584
  if (typeEntries.length > 0) {
7518
7585
  for (const [filename, content] of typeEntries) {
7519
- writeFileSync9(join14(typesDir, filename), content);
7586
+ writeFileSync9(join15(typesDir, filename), content);
7520
7587
  }
7521
7588
  console.log("Types populated from bundled types");
7522
7589
  return;
@@ -7527,7 +7594,7 @@ function copyDtsFiles(srcDir, destDir) {
7527
7594
  const files = readdirSync4(srcDir);
7528
7595
  for (const file of files) {
7529
7596
  if (file.endsWith(".d.ts")) {
7530
- copyFileSync(join14(srcDir, file), join14(destDir, file));
7597
+ copyFileSync(join15(srcDir, file), join15(destDir, file));
7531
7598
  }
7532
7599
  }
7533
7600
  }
@@ -7645,7 +7712,7 @@ function createKeyboardListener() {
7645
7712
  }
7646
7713
 
7647
7714
  // src/generated/version.ts
7648
- var VERSION = "0.21.0";
7715
+ var VERSION = "0.21.1";
7649
7716
 
7650
7717
  // src/commands/dev.ts
7651
7718
  var exports_dev = {};
@@ -7655,12 +7722,12 @@ __export(exports_dev, {
7655
7722
  });
7656
7723
  import { Command as Command4, Option } from "commander";
7657
7724
  import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as existsSync15 } from "fs";
7658
- import { join as join15 } from "path";
7725
+ import { join as join16 } from "path";
7659
7726
  async function populateSkill(projectDir, client, appId) {
7660
7727
  try {
7661
7728
  const { skill } = await client.getAppSkill(appId);
7662
7729
  if (skill) {
7663
- writeFileSync10(join15(projectDir, "SKILL.md"), skill, "utf-8");
7730
+ writeFileSync10(join16(projectDir, "SKILL.md"), skill, "utf-8");
7664
7731
  }
7665
7732
  } catch {}
7666
7733
  }
@@ -8682,9 +8749,9 @@ import { readFileSync as readFileSync15, existsSync as existsSync18 } from "fs";
8682
8749
  // src/deploy/deploy-state.ts
8683
8750
  init_subprocess();
8684
8751
  import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync11 } from "fs";
8685
- import { dirname as dirname4, join as join16 } from "path";
8752
+ import { dirname as dirname4, join as join17 } from "path";
8686
8753
  function deployStatePath(cwd) {
8687
- return join16(cwd, ".runwork", "last-deploy.json");
8754
+ return join17(cwd, ".runwork", "last-deploy.json");
8688
8755
  }
8689
8756
  function getHeadSha(cwd) {
8690
8757
  try {
@@ -8735,7 +8802,7 @@ function getDeploySummary(cwd) {
8735
8802
  // src/deploy/deploy-status.ts
8736
8803
  init_session();
8737
8804
  import { existsSync as existsSync17, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "fs";
8738
- import { dirname as dirname5, join as join17 } from "path";
8805
+ import { dirname as dirname5, join as join18 } from "path";
8739
8806
  function evaluateDeployStatus(status, deps = {}) {
8740
8807
  if (status.state !== "in-progress") {
8741
8808
  return { status, effectiveState: status.state };
@@ -8751,10 +8818,10 @@ function evaluateDeployStatus(status, deps = {}) {
8751
8818
  return { status, effectiveState: "in-progress" };
8752
8819
  }
8753
8820
  function statusPath(cwd) {
8754
- return join17(cwd, ".runwork", "deploy-status.json");
8821
+ return join18(cwd, ".runwork", "deploy-status.json");
8755
8822
  }
8756
8823
  function deployLogPath(cwd) {
8757
- return join17(cwd, ".runwork", "deploy-stdout.log");
8824
+ return join18(cwd, ".runwork", "deploy-stdout.log");
8758
8825
  }
8759
8826
  function writeDeployStatus(cwd, status) {
8760
8827
  const path2 = statusPath(cwd);
@@ -8786,7 +8853,7 @@ init_session();
8786
8853
  init_detach();
8787
8854
  import * as fs5 from "fs";
8788
8855
  import * as child_process2 from "child_process";
8789
- import { join as join18 } from "path";
8856
+ import { join as join19 } from "path";
8790
8857
  var DEPLOY_DETACHED_CHILD_FLAG = "--internal-detached-deploy-child";
8791
8858
  function isInternalDeployChild(argv = process.argv) {
8792
8859
  return argv.includes(DEPLOY_DETACHED_CHILD_FLAG);
@@ -8802,10 +8869,10 @@ function buildDeployChildArgs(parentArgv) {
8802
8869
  return [...filtered, DEPLOY_DETACHED_CHILD_FLAG];
8803
8870
  }
8804
8871
  function spawnDetachedDeploy(childArgs, cwd) {
8805
- const dir = join18(cwd, ".runwork");
8872
+ const dir = join19(cwd, ".runwork");
8806
8873
  fs5.mkdirSync(dir, { recursive: true });
8807
- const stdoutFd = fs5.openSync(join18(dir, "deploy-stdout.log"), "w");
8808
- const stderrFd = fs5.openSync(join18(dir, "deploy-stderr.log"), "w");
8874
+ const stdoutFd = fs5.openSync(join19(dir, "deploy-stdout.log"), "w");
8875
+ const stderrFd = fs5.openSync(join19(dir, "deploy-stderr.log"), "w");
8809
8876
  try {
8810
8877
  const proc = child_process2.spawn(process.execPath, childArgs, {
8811
8878
  cwd,
@@ -9443,7 +9510,7 @@ import { Command as Command8 } from "commander";
9443
9510
  import { execFileSync as execFileSync2 } from "child_process";
9444
9511
  import { platform as osPlatform, tmpdir as tmpdir2 } from "os";
9445
9512
  import { mkdtempSync as mkdtempSync2, writeFileSync as writeFileSync13, rmSync as rmSync3 } from "fs";
9446
- import { join as join19 } from "path";
9513
+ import { join as join20 } from "path";
9447
9514
  var BASE_URL = "https://runwork.ai";
9448
9515
  var LATEST_JSON_URL = `${BASE_URL}/cli/latest.json`;
9449
9516
  var INSTALL_SH_URL = `${BASE_URL}/install.sh`;
@@ -9494,8 +9561,8 @@ Upgrading via PowerShell installer...
9494
9561
  throw new Error(`Failed to download install.ps1: HTTP ${response2.status}`);
9495
9562
  }
9496
9563
  const script2 = await response2.text();
9497
- const tmpDir = mkdtempSync2(join19(tmpdir2(), "runwork-upgrade-"));
9498
- const scriptPath = join19(tmpDir, "install.ps1");
9564
+ const tmpDir = mkdtempSync2(join20(tmpdir2(), "runwork-upgrade-"));
9565
+ const scriptPath = join20(tmpDir, "install.ps1");
9499
9566
  try {
9500
9567
  writeFileSync13(scriptPath, script2);
9501
9568
  execFileSync2("powershell", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-File", scriptPath], { stdio: "inherit" });
@@ -9651,6 +9718,7 @@ Upgrade failed: ${message}`);
9651
9718
  // src/commands/logout.ts
9652
9719
  init_store();
9653
9720
  init_credentials();
9721
+ init_workspace_state();
9654
9722
  import { Command as Command9 } from "commander";
9655
9723
  var logoutCommand = new Command9("logout").description("Remove stored Runwork credentials").action(async () => {
9656
9724
  const creds = getCredentials();
@@ -9658,6 +9726,7 @@ var logoutCommand = new Command9("logout").description("Remove stored Runwork cr
9658
9726
  await removeGitCredentials(creds.baseUrl);
9659
9727
  }
9660
9728
  clearCredentials();
9729
+ forgetWorkspaceSelection();
9661
9730
  console.log("Logged out.");
9662
9731
  });
9663
9732
 
@@ -10193,7 +10262,7 @@ var openCommand = new Command11("open").description("Open app preview or dashboa
10193
10262
  init_agent_guidance();
10194
10263
  import { Command as Command12 } from "commander";
10195
10264
  import { readFileSync as readFileSync21, existsSync as existsSync24 } from "fs";
10196
- import { join as join20 } from "path";
10265
+ import { join as join21 } from "path";
10197
10266
 
10198
10267
  // src/utils/app-info.ts
10199
10268
  init_colors();
@@ -10393,7 +10462,7 @@ function tryReadConfig() {
10393
10462
  }
10394
10463
  }
10395
10464
  function readBlueprint(cwd) {
10396
- const blueprintPath = join20(cwd, "blueprint.json");
10465
+ const blueprintPath = join21(cwd, "blueprint.json");
10397
10466
  if (!existsSync24(blueprintPath))
10398
10467
  return null;
10399
10468
  try {
@@ -11200,8 +11269,8 @@ init_client();
11200
11269
  // src/agents/claude-code.ts
11201
11270
  init_subprocess();
11202
11271
  import { chmodSync, existsSync as existsSync30, mkdirSync as mkdirSync16, readFileSync as readFileSync25, readdirSync as readdirSync7, rmSync as rmSync5, statSync as statSync4, writeFileSync as writeFileSync16 } from "fs";
11203
- import { join as join23 } from "path";
11204
- import { homedir as homedir6, platform as platform2 } from "os";
11272
+ import { join as join24 } from "path";
11273
+ import { homedir as homedir7, platform as platform2 } from "os";
11205
11274
 
11206
11275
  // src/agents/types.ts
11207
11276
  var RUNWORK_MCP_PREFIX = "Runwork: ";
@@ -11549,15 +11618,15 @@ function skillNameFromPath(path2) {
11549
11618
  // src/utils/trash.ts
11550
11619
  init_atomic_json();
11551
11620
  import { cpSync, existsSync as existsSync26, mkdirSync as mkdirSync13, readdirSync as readdirSync5, renameSync as renameSync3, rmSync as rmSync4, statSync as statSync3 } from "fs";
11552
- import { basename as basename2, dirname as dirname6, join as join21 } from "path";
11553
- import { homedir as homedir5 } from "os";
11621
+ import { basename as basename2, dirname as dirname6, join as join22 } from "path";
11622
+ import { homedir as homedir6 } from "os";
11554
11623
  var TRASH_RETENTION_DAYS = 30;
11555
11624
  function trashRoot() {
11556
- return join21(homedir5(), ".runwork", "trash");
11625
+ return join22(homedir6(), ".runwork", "trash");
11557
11626
  }
11558
11627
  function batchDir(now) {
11559
11628
  const stamp = now.toISOString().replace(/[:.]/g, "-");
11560
- return join21(trashRoot(), `${stamp}-${process.pid}`);
11629
+ return join22(trashRoot(), `${stamp}-${process.pid}`);
11561
11630
  }
11562
11631
  function pruneTrash(now = new Date) {
11563
11632
  const root = trashRoot();
@@ -11565,7 +11634,7 @@ function pruneTrash(now = new Date) {
11565
11634
  return;
11566
11635
  const cutoff = now.getTime() - TRASH_RETENTION_DAYS * 24 * 60 * 60 * 1000;
11567
11636
  for (const entry of readdirSync5(root)) {
11568
- const dir = join21(root, entry);
11637
+ const dir = join22(root, entry);
11569
11638
  try {
11570
11639
  if (statSync3(dir).mtimeMs < cutoff)
11571
11640
  rmSync4(dir, { recursive: true, force: true });
@@ -11582,8 +11651,8 @@ function moveToTrash(sourcePath, reason, now = new Date) {
11582
11651
  }
11583
11652
  const parent = basename2(dirname6(sourcePath));
11584
11653
  const grandparent = basename2(dirname6(dirname6(sourcePath)));
11585
- const destDir = join21(activeBatch, `${grandparent}__${parent}`.replace(/[^a-zA-Z0-9._-]/g, "-"));
11586
- const dest = join21(destDir, basename2(sourcePath));
11654
+ const destDir = join22(activeBatch, `${grandparent}__${parent}`.replace(/[^a-zA-Z0-9._-]/g, "-"));
11655
+ const dest = join22(destDir, basename2(sourcePath));
11587
11656
  try {
11588
11657
  mkdirSync13(destDir, { recursive: true });
11589
11658
  try {
@@ -11595,7 +11664,7 @@ function moveToTrash(sourcePath, reason, now = new Date) {
11595
11664
  } catch {
11596
11665
  return null;
11597
11666
  }
11598
- const manifestPath = join21(activeBatch, "manifest.json");
11667
+ const manifestPath = join22(activeBatch, "manifest.json");
11599
11668
  const manifest = readJsonOrNull(manifestPath) ?? { entries: [] };
11600
11669
  manifest.entries.push({ from: sourcePath, to: dest, reason, at: now.toISOString() });
11601
11670
  try {
@@ -11696,14 +11765,14 @@ function mergeJsonMcpServers(filePath, servers, topKey) {
11696
11765
 
11697
11766
  // src/agents/utils/skill-removal.ts
11698
11767
  import { existsSync as existsSync28, readdirSync as readdirSync6 } from "fs";
11699
- import { join as join22 } from "path";
11768
+ import { join as join23 } from "path";
11700
11769
  function removeMatchingSkillDirs(dir, allowed, reason = "skill removed") {
11701
11770
  if (!allowed.size || !existsSync28(dir))
11702
11771
  return;
11703
11772
  for (const entry of readdirSync6(dir)) {
11704
11773
  if (!allowed.has(entry))
11705
11774
  continue;
11706
- moveToTrash(join22(dir, entry), reason);
11775
+ moveToTrash(join23(dir, entry), reason);
11707
11776
  }
11708
11777
  }
11709
11778
  function removeMatchingSkillFiles(dir, allowed, suffix, reason = "skill removed") {
@@ -11713,7 +11782,7 @@ function removeMatchingSkillFiles(dir, allowed, suffix, reason = "skill removed"
11713
11782
  for (const entry of readdirSync6(dir)) {
11714
11783
  if (!names.has(entry))
11715
11784
  continue;
11716
- moveToTrash(join22(dir, entry), reason);
11785
+ moveToTrash(join23(dir, entry), reason);
11717
11786
  }
11718
11787
  }
11719
11788
 
@@ -12116,7 +12185,7 @@ class ClaudeCodeAdapter {
12116
12185
  }
12117
12186
  async writeMcpServers(servers, scope) {
12118
12187
  if (scope === "project") {
12119
- const filePath = join23(process.cwd(), ".mcp.json");
12188
+ const filePath = join24(process.cwd(), ".mcp.json");
12120
12189
  const entries = {};
12121
12190
  for (const s of servers) {
12122
12191
  entries[s.name] = {
@@ -12128,7 +12197,7 @@ class ClaudeCodeAdapter {
12128
12197
  }
12129
12198
  mergeJsonMcpServers(filePath, entries, "mcpServers");
12130
12199
  } else {
12131
- const settingsPath = join23(homedir6(), ".claude", "settings.json");
12200
+ const settingsPath = join24(homedir7(), ".claude", "settings.json");
12132
12201
  const entries = {};
12133
12202
  for (const s of servers) {
12134
12203
  entries[s.name] = {
@@ -12141,10 +12210,10 @@ class ClaudeCodeAdapter {
12141
12210
  mergeJsonMcpServers(settingsPath, entries, "mcpServers");
12142
12211
  const pluginDir = this.getPluginDir();
12143
12212
  mkdirSync16(pluginDir, { recursive: true });
12144
- const pluginMcpPath = join23(pluginDir, ".mcp.json");
12213
+ const pluginMcpPath = join24(pluginDir, ".mcp.json");
12145
12214
  const marketDir = this.getMarketplaceDir();
12146
12215
  mkdirSync16(marketDir, { recursive: true });
12147
- const marketplaceMcpPath = join23(marketDir, ".mcp.json");
12216
+ const marketplaceMcpPath = join24(marketDir, ".mcp.json");
12148
12217
  const pluginEntries = {};
12149
12218
  for (const s of servers) {
12150
12219
  pluginEntries[s.name] = {
@@ -12159,44 +12228,44 @@ class ClaudeCodeAdapter {
12159
12228
  }
12160
12229
  }
12161
12230
  installSessionStartHook(pluginDir, label) {
12162
- const hooksDir = join23(pluginDir, "hooks");
12231
+ const hooksDir = join24(pluginDir, "hooks");
12163
12232
  mkdirSync16(hooksDir, { recursive: true });
12164
- const scriptPath = join23(hooksDir, "on-session-start.sh");
12233
+ const scriptPath = join24(hooksDir, "on-session-start.sh");
12165
12234
  writeFileSync16(scriptPath, SESSION_START_HOOK_SCRIPT);
12166
12235
  try {
12167
12236
  chmodSync(scriptPath, 493);
12168
12237
  } catch {}
12169
- writeFileSync16(join23(hooksDir, "hooks.json"), JSON.stringify(SESSION_START_HOOKS_MANIFEST, null, 2));
12238
+ writeFileSync16(join24(hooksDir, "hooks.json"), JSON.stringify(SESSION_START_HOOKS_MANIFEST, null, 2));
12170
12239
  vlog(` [Claude Code] Installed SessionStart hook (${label}) -> ${scriptPath}`);
12171
12240
  }
12172
12241
  async writeSkills(skills, scope) {
12173
- const baseDir = scope === "project" ? join23(process.cwd(), ".claude", "skills") : join23(homedir6(), ".claude", "skills");
12242
+ const baseDir = scope === "project" ? join24(process.cwd(), ".claude", "skills") : join24(homedir7(), ".claude", "skills");
12174
12243
  for (const skill of skills) {
12175
- const skillDir = join23(baseDir, skill.filename);
12244
+ const skillDir = join24(baseDir, skill.filename);
12176
12245
  cleanupOldSkillDir(baseDir, skill);
12177
12246
  mkdirSync16(skillDir, { recursive: true });
12178
- writeFileSync16(join23(skillDir, "SKILL.md"), buildSkillMd2(skill));
12247
+ writeFileSync16(join24(skillDir, "SKILL.md"), buildSkillMd2(skill));
12179
12248
  }
12180
12249
  if (scope === "user") {
12181
12250
  const pluginDir = this.getPluginDir();
12182
- const pluginJsonDir = join23(pluginDir, ".claude-plugin");
12251
+ const pluginJsonDir = join24(pluginDir, ".claude-plugin");
12183
12252
  mkdirSync16(pluginJsonDir, { recursive: true });
12184
- writeFileSync16(join23(pluginJsonDir, "plugin.json"), JSON.stringify(getPluginJson(), null, 2));
12253
+ writeFileSync16(join24(pluginJsonDir, "plugin.json"), JSON.stringify(getPluginJson(), null, 2));
12185
12254
  for (const skill of skills) {
12186
- const skillDir = join23(pluginDir, "skills", skill.filename);
12187
- cleanupOldSkillDir(join23(pluginDir, "skills"), skill);
12255
+ const skillDir = join24(pluginDir, "skills", skill.filename);
12256
+ cleanupOldSkillDir(join24(pluginDir, "skills"), skill);
12188
12257
  mkdirSync16(skillDir, { recursive: true });
12189
- writeFileSync16(join23(skillDir, "SKILL.md"), buildSkillMd2(skill));
12258
+ writeFileSync16(join24(skillDir, "SKILL.md"), buildSkillMd2(skill));
12190
12259
  }
12191
12260
  const marketDir = this.getMarketplaceDir();
12192
- const marketPluginJsonDir = join23(marketDir, ".claude-plugin");
12261
+ const marketPluginJsonDir = join24(marketDir, ".claude-plugin");
12193
12262
  mkdirSync16(marketPluginJsonDir, { recursive: true });
12194
- writeFileSync16(join23(marketPluginJsonDir, "plugin.json"), JSON.stringify(getPluginJson(), null, 2));
12263
+ writeFileSync16(join24(marketPluginJsonDir, "plugin.json"), JSON.stringify(getPluginJson(), null, 2));
12195
12264
  for (const skill of skills) {
12196
- const skillDir = join23(marketDir, "skills", skill.filename);
12197
- cleanupOldSkillDir(join23(marketDir, "skills"), skill);
12265
+ const skillDir = join24(marketDir, "skills", skill.filename);
12266
+ cleanupOldSkillDir(join24(marketDir, "skills"), skill);
12198
12267
  mkdirSync16(skillDir, { recursive: true });
12199
- writeFileSync16(join23(skillDir, "SKILL.md"), buildSkillMd2(skill));
12268
+ writeFileSync16(join24(skillDir, "SKILL.md"), buildSkillMd2(skill));
12200
12269
  }
12201
12270
  this.registerPlugin(pluginDir);
12202
12271
  }
@@ -12215,11 +12284,11 @@ class ClaudeCodeAdapter {
12215
12284
  }
12216
12285
  }
12217
12286
  async writeInstructionHint(hint, scope) {
12218
- const filePath = scope === "project" ? join23(process.cwd(), ".claude", "CLAUDE.md") : join23(homedir6(), ".claude", "CLAUDE.md");
12287
+ const filePath = scope === "project" ? join24(process.cwd(), ".claude", "CLAUDE.md") : join24(homedir7(), ".claude", "CLAUDE.md");
12219
12288
  writeHintToFile(filePath, hint);
12220
12289
  }
12221
12290
  async writeTeamInstructions(instructions, scope) {
12222
- const filePath = scope === "project" ? join23(process.cwd(), ".claude", "CLAUDE.md") : join23(homedir6(), ".claude", "CLAUDE.md");
12291
+ const filePath = scope === "project" ? join24(process.cwd(), ".claude", "CLAUDE.md") : join24(homedir7(), ".claude", "CLAUDE.md");
12223
12292
  writeTeamInstructionsToFile(filePath, instructions);
12224
12293
  if (scope === "user") {
12225
12294
  const skillContent = `---
@@ -12231,16 +12300,16 @@ ${instructions}`;
12231
12300
  const pluginDir = this.getPluginDir();
12232
12301
  const marketDir = this.getMarketplaceDir();
12233
12302
  for (const dir of [
12234
- join23(pluginDir, "skills", "runwork-team-instructions"),
12235
- join23(marketDir, "skills", "runwork-team-instructions")
12303
+ join24(pluginDir, "skills", "runwork-team-instructions"),
12304
+ join24(marketDir, "skills", "runwork-team-instructions")
12236
12305
  ]) {
12237
12306
  mkdirSync16(dir, { recursive: true });
12238
- writeFileSync16(join23(dir, "SKILL.md"), skillContent);
12307
+ writeFileSync16(join24(dir, "SKILL.md"), skillContent);
12239
12308
  }
12240
12309
  }
12241
12310
  }
12242
12311
  async writeAgentConfig(config, scope, baseline) {
12243
- const settingsPath = scope === "project" ? join23(process.cwd(), ".claude", "settings.json") : join23(homedir6(), ".claude", "settings.json");
12312
+ const settingsPath = scope === "project" ? join24(process.cwd(), ".claude", "settings.json") : join24(homedir7(), ".claude", "settings.json");
12244
12313
  const hadFile = existsSync30(settingsPath);
12245
12314
  let settings = {};
12246
12315
  if (hadFile) {
@@ -12275,7 +12344,7 @@ ${instructions}`;
12275
12344
  }
12276
12345
  if (!hadFile && !config.modelPreference && !config.permissionRules)
12277
12346
  return;
12278
- mkdirSync16(join23(settingsPath, ".."), { recursive: true });
12347
+ mkdirSync16(join24(settingsPath, ".."), { recursive: true });
12279
12348
  writeFileSync16(settingsPath, JSON.stringify(settings, null, 2));
12280
12349
  }
12281
12350
  async readManagedBlock(_scope) {
@@ -12285,26 +12354,26 @@ ${instructions}`;
12285
12354
  if (!skillFilenames.length)
12286
12355
  return;
12287
12356
  const allowed = new Set(skillFilenames);
12288
- const roots = scope === "project" ? [join23(process.cwd(), ".claude", "skills")] : [
12289
- join23(homedir6(), ".claude", "skills"),
12290
- join23(this.getPluginDir(), "skills"),
12291
- join23(this.getMarketplaceDir(), "skills")
12357
+ const roots = scope === "project" ? [join24(process.cwd(), ".claude", "skills")] : [
12358
+ join24(homedir7(), ".claude", "skills"),
12359
+ join24(this.getPluginDir(), "skills"),
12360
+ join24(this.getMarketplaceDir(), "skills")
12292
12361
  ];
12293
12362
  for (const dir of roots)
12294
12363
  removeMatchingSkillDirs(dir, allowed);
12295
12364
  }
12296
12365
  async cleanup(scope, manifest) {
12297
12366
  if (scope === "project") {
12298
- removeRunworkMcpServers(join23(process.cwd(), ".mcp.json"), "mcpServers");
12367
+ removeRunworkMcpServers(join24(process.cwd(), ".mcp.json"), "mcpServers");
12299
12368
  } else {
12300
- removeRunworkMcpServers(join23(homedir6(), ".claude", "settings.json"), "mcpServers");
12369
+ removeRunworkMcpServers(join24(homedir7(), ".claude", "settings.json"), "mcpServers");
12301
12370
  }
12302
12371
  await this.removeSkills(manifest?.skillFilenames ?? [], scope);
12303
- const instructionFile = scope === "project" ? join23(process.cwd(), ".claude", "CLAUDE.md") : join23(homedir6(), ".claude", "CLAUDE.md");
12372
+ const instructionFile = scope === "project" ? join24(process.cwd(), ".claude", "CLAUDE.md") : join24(homedir7(), ".claude", "CLAUDE.md");
12304
12373
  removeHintFromFile(instructionFile);
12305
12374
  removeTeamInstructionsFromFile(instructionFile);
12306
12375
  if (scope === "user") {
12307
- const settingsPath = join23(homedir6(), ".claude", "settings.json");
12376
+ const settingsPath = join24(homedir7(), ".claude", "settings.json");
12308
12377
  if (existsSync30(settingsPath)) {
12309
12378
  try {
12310
12379
  const settings = JSON.parse(readFileSync25(settingsPath, "utf-8"));
@@ -12336,7 +12405,7 @@ ${instructions}`;
12336
12405
  }
12337
12406
  }
12338
12407
  const pluginsBase = this.getPluginsBaseDir();
12339
- const installedPath = join23(pluginsBase, "installed_plugins.json");
12408
+ const installedPath = join24(pluginsBase, "installed_plugins.json");
12340
12409
  if (existsSync30(installedPath)) {
12341
12410
  try {
12342
12411
  const installed = readJsonConfig(installedPath);
@@ -12349,7 +12418,7 @@ ${instructions}`;
12349
12418
  }
12350
12419
  } catch {}
12351
12420
  }
12352
- const marketplacesPath = join23(pluginsBase, "known_marketplaces.json");
12421
+ const marketplacesPath = join24(pluginsBase, "known_marketplaces.json");
12353
12422
  if (existsSync30(marketplacesPath)) {
12354
12423
  try {
12355
12424
  const marketplaces = readJsonConfig(marketplacesPath);
@@ -12361,10 +12430,10 @@ ${instructions}`;
12361
12430
  }
12362
12431
  async readUsageStats(lastSyncAt) {
12363
12432
  try {
12364
- const claudeDir = join23(homedir6(), ".claude");
12433
+ const claudeDir = join24(homedir7(), ".claude");
12365
12434
  if (!existsSync30(claudeDir))
12366
12435
  return null;
12367
- const projectsDir = join23(claudeDir, "projects");
12436
+ const projectsDir = join24(claudeDir, "projects");
12368
12437
  if (!existsSync30(projectsDir))
12369
12438
  return null;
12370
12439
  const sinceMs = lastSyncAt ? new Date(lastSyncAt).getTime() : 0;
@@ -12384,7 +12453,7 @@ ${instructions}`;
12384
12453
  return null;
12385
12454
  }
12386
12455
  for (const cwd of cwdEntries) {
12387
- const cwdPath = join23(projectsDir, cwd);
12456
+ const cwdPath = join24(projectsDir, cwd);
12388
12457
  let files;
12389
12458
  try {
12390
12459
  files = readdirSync7(cwdPath);
@@ -12394,7 +12463,7 @@ ${instructions}`;
12394
12463
  for (const file of files) {
12395
12464
  if (!file.endsWith(".jsonl"))
12396
12465
  continue;
12397
- const filePath = join23(cwdPath, file);
12466
+ const filePath = join24(cwdPath, file);
12398
12467
  let stat;
12399
12468
  try {
12400
12469
  stat = statSync4(filePath);
@@ -12491,7 +12560,7 @@ ${instructions}`;
12491
12560
  }
12492
12561
  async readSessionDigests(sinceISO) {
12493
12562
  try {
12494
- const projectsDir = join23(homedir6(), ".claude", "projects");
12563
+ const projectsDir = join24(homedir7(), ".claude", "projects");
12495
12564
  if (!existsSync30(projectsDir))
12496
12565
  return null;
12497
12566
  const sinceMs = sinceISO ? new Date(sinceISO).getTime() : 0;
@@ -12503,7 +12572,7 @@ ${instructions}`;
12503
12572
  }
12504
12573
  const digests = [];
12505
12574
  for (const cwd of cwdEntries) {
12506
- const cwdPath = join23(projectsDir, cwd);
12575
+ const cwdPath = join24(projectsDir, cwd);
12507
12576
  let files;
12508
12577
  try {
12509
12578
  files = readdirSync7(cwdPath);
@@ -12513,7 +12582,7 @@ ${instructions}`;
12513
12582
  for (const file of files) {
12514
12583
  if (!file.endsWith(".jsonl"))
12515
12584
  continue;
12516
- const filePath = join23(cwdPath, file);
12585
+ const filePath = join24(cwdPath, file);
12517
12586
  let stat;
12518
12587
  try {
12519
12588
  stat = statSync4(filePath);
@@ -12540,7 +12609,7 @@ ${instructions}`;
12540
12609
  }
12541
12610
  async readSkillUsage(lastSyncAt) {
12542
12611
  try {
12543
- const projectsDir = join23(homedir6(), ".claude", "projects");
12612
+ const projectsDir = join24(homedir7(), ".claude", "projects");
12544
12613
  if (!existsSync30(projectsDir))
12545
12614
  return null;
12546
12615
  const sinceMs = lastSyncAt ? new Date(lastSyncAt).getTime() : 0;
@@ -12562,7 +12631,7 @@ ${instructions}`;
12562
12631
  return null;
12563
12632
  }
12564
12633
  for (const cwd of cwdEntries) {
12565
- const cwdPath = join23(projectsDir, cwd);
12634
+ const cwdPath = join24(projectsDir, cwd);
12566
12635
  let files;
12567
12636
  try {
12568
12637
  files = readdirSync7(cwdPath);
@@ -12572,7 +12641,7 @@ ${instructions}`;
12572
12641
  for (const file of files) {
12573
12642
  if (!file.endsWith(".jsonl"))
12574
12643
  continue;
12575
- const filePath = join23(cwdPath, file);
12644
+ const filePath = join24(cwdPath, file);
12576
12645
  let fileStat;
12577
12646
  try {
12578
12647
  fileStat = statSync4(filePath);
@@ -12673,21 +12742,21 @@ ${instructions}`;
12673
12742
  }
12674
12743
  }
12675
12744
  getPluginsBaseDir() {
12676
- return join23(homedir6(), ".claude", "plugins");
12745
+ return join24(homedir7(), ".claude", "plugins");
12677
12746
  }
12678
12747
  getPluginDir() {
12679
- return join23(this.getPluginsBaseDir(), "cache", "runwork", PLUGIN_NAME, PLUGIN_VERSION);
12748
+ return join24(this.getPluginsBaseDir(), "cache", "runwork", PLUGIN_NAME, PLUGIN_VERSION);
12680
12749
  }
12681
12750
  getMarketplaceRoot() {
12682
- return join23(this.getPluginsBaseDir(), "marketplaces", "runwork");
12751
+ return join24(this.getPluginsBaseDir(), "marketplaces", "runwork");
12683
12752
  }
12684
12753
  getMarketplaceDir() {
12685
- return join23(this.getMarketplaceRoot(), "plugins", PLUGIN_NAME);
12754
+ return join24(this.getMarketplaceRoot(), "plugins", PLUGIN_NAME);
12686
12755
  }
12687
12756
  registerPlugin(pluginDir) {
12688
12757
  const pluginsBase = this.getPluginsBaseDir();
12689
12758
  mkdirSync16(pluginsBase, { recursive: true });
12690
- const installedPath = join23(pluginsBase, "installed_plugins.json");
12759
+ const installedPath = join24(pluginsBase, "installed_plugins.json");
12691
12760
  const installed = readJsonConfig(installedPath);
12692
12761
  if (!installed.version)
12693
12762
  installed.version = 2;
@@ -12704,10 +12773,10 @@ ${instructions}`;
12704
12773
  }];
12705
12774
  writeJsonConfig(installedPath, installed);
12706
12775
  const marketRoot = this.getMarketplaceRoot();
12707
- const marketCatalogDir = join23(marketRoot, ".claude-plugin");
12776
+ const marketCatalogDir = join24(marketRoot, ".claude-plugin");
12708
12777
  mkdirSync16(marketCatalogDir, { recursive: true });
12709
- writeFileSync16(join23(marketCatalogDir, "marketplace.json"), JSON.stringify(getMarketplaceJson(), null, 2));
12710
- const marketplacesPath = join23(pluginsBase, "known_marketplaces.json");
12778
+ writeFileSync16(join24(marketCatalogDir, "marketplace.json"), JSON.stringify(getMarketplaceJson(), null, 2));
12779
+ const marketplacesPath = join24(pluginsBase, "known_marketplaces.json");
12711
12780
  const marketplaces = readJsonConfig(marketplacesPath);
12712
12781
  marketplaces["runwork"] = {
12713
12782
  source: { source: "directory", path: marketRoot },
@@ -12716,7 +12785,7 @@ ${instructions}`;
12716
12785
  };
12717
12786
  writeJsonConfig(marketplacesPath, marketplaces);
12718
12787
  vlog(` [Claude Code] ${wasRegistered ? "Refreshed" : "Registered"} plugin ` + `${pluginKey} v${PLUGIN_VERSION} -> ${installedPath}`);
12719
- const settingsPath = join23(homedir6(), ".claude", "settings.json");
12788
+ const settingsPath = join24(homedir7(), ".claude", "settings.json");
12720
12789
  const settings = readJsonConfig(settingsPath);
12721
12790
  if (!settings["enabledPlugins"]) {
12722
12791
  settings["enabledPlugins"] = {};
@@ -12731,23 +12800,23 @@ ${instructions}`;
12731
12800
  function cleanupOldSkillDir(baseDir, skill) {
12732
12801
  if (skill.name === skill.filename)
12733
12802
  return;
12734
- const oldDir = join23(baseDir, skill.name);
12803
+ const oldDir = join24(baseDir, skill.name);
12735
12804
  moveToTrash(oldDir, `skill renamed to ${skill.filename}`);
12736
12805
  }
12737
12806
 
12738
12807
  // src/agents/claude-desktop.ts
12739
12808
  import { existsSync as existsSync32, mkdtempSync as mkdtempSync3, readdirSync as readdirSync8, readFileSync as readFileSync26, rmSync as rmSync7, statSync as statSync5, writeFileSync as writeFileSync18, mkdirSync as mkdirSync18 } from "fs";
12740
- import { dirname as dirname9, join as join25 } from "path";
12741
- import { homedir as homedir7, platform as platform3, tmpdir as tmpdir3 } from "os";
12809
+ import { dirname as dirname9, join as join26 } from "path";
12810
+ import { homedir as homedir8, platform as platform3, tmpdir as tmpdir3 } from "os";
12742
12811
  init_zip();
12743
12812
 
12744
12813
  // src/agents/claude-desktop-plugin-tree.ts
12745
12814
  import { chmodSync as chmodSync2, mkdirSync as mkdirSync17, rmSync as rmSync6, existsSync as existsSync31, writeFileSync as writeFileSync17 } from "fs";
12746
- import { join as join24 } from "path";
12815
+ import { join as join25 } from "path";
12747
12816
  function writePluginMetadata(destDir, metadata) {
12748
- const pluginJsonDir = join24(destDir, ".claude-plugin");
12817
+ const pluginJsonDir = join25(destDir, ".claude-plugin");
12749
12818
  mkdirSync17(pluginJsonDir, { recursive: true });
12750
- writeFileSync17(join24(pluginJsonDir, "plugin.json"), JSON.stringify({
12819
+ writeFileSync17(join25(pluginJsonDir, "plugin.json"), JSON.stringify({
12751
12820
  name: metadata.pluginName,
12752
12821
  version: metadata.pluginVersion,
12753
12822
  description: metadata.description,
@@ -12774,10 +12843,10 @@ function writePluginMcpConfig(destDir, mcpServers) {
12774
12843
  };
12775
12844
  }
12776
12845
  }
12777
- writeFileSync17(join24(destDir, ".mcp.json"), JSON.stringify({ mcpServers: mcpEntries }, null, 2));
12846
+ writeFileSync17(join25(destDir, ".mcp.json"), JSON.stringify({ mcpServers: mcpEntries }, null, 2));
12778
12847
  }
12779
12848
  function writePluginTeamInstructions(destDir, instructions) {
12780
- const skillDir = join24(destDir, "skills", "runwork-team-instructions");
12849
+ const skillDir = join25(destDir, "skills", "runwork-team-instructions");
12781
12850
  mkdirSync17(skillDir, { recursive: true });
12782
12851
  const skillContent = `---
12783
12852
  name: runwork-team-instructions
@@ -12785,34 +12854,34 @@ description: Team instructions from your Runwork workspace. Always follow these
12785
12854
  ---
12786
12855
 
12787
12856
  ${instructions}`;
12788
- writeFileSync17(join24(skillDir, "SKILL.md"), skillContent);
12857
+ writeFileSync17(join25(skillDir, "SKILL.md"), skillContent);
12789
12858
  }
12790
12859
  function writePluginSkills(destDir, skills) {
12791
- const skillsRoot = join24(destDir, "skills");
12860
+ const skillsRoot = join25(destDir, "skills");
12792
12861
  mkdirSync17(skillsRoot, { recursive: true });
12793
12862
  for (const skill of skills) {
12794
12863
  if (skill.name !== skill.filename) {
12795
- const legacyDir = join24(skillsRoot, skill.name);
12864
+ const legacyDir = join25(skillsRoot, skill.name);
12796
12865
  if (existsSync31(legacyDir)) {
12797
12866
  try {
12798
12867
  rmSync6(legacyDir, { recursive: true, force: true });
12799
12868
  } catch {}
12800
12869
  }
12801
12870
  }
12802
- const skillDir = join24(skillsRoot, skill.filename);
12871
+ const skillDir = join25(skillsRoot, skill.filename);
12803
12872
  mkdirSync17(skillDir, { recursive: true });
12804
- writeFileSync17(join24(skillDir, "SKILL.md"), buildSkillMd2(skill));
12873
+ writeFileSync17(join25(skillDir, "SKILL.md"), buildSkillMd2(skill));
12805
12874
  }
12806
12875
  }
12807
12876
  function writePluginSessionStartHook(destDir) {
12808
- const hooksDir = join24(destDir, "hooks");
12877
+ const hooksDir = join25(destDir, "hooks");
12809
12878
  mkdirSync17(hooksDir, { recursive: true });
12810
- const scriptPath = join24(hooksDir, "on-session-start.sh");
12879
+ const scriptPath = join25(hooksDir, "on-session-start.sh");
12811
12880
  writeFileSync17(scriptPath, SESSION_START_HOOK_SCRIPT);
12812
12881
  try {
12813
12882
  chmodSync2(scriptPath, 493);
12814
12883
  } catch {}
12815
- writeFileSync17(join24(hooksDir, "hooks.json"), JSON.stringify(SESSION_START_HOOKS_MANIFEST, null, 2));
12884
+ writeFileSync17(join25(hooksDir, "hooks.json"), JSON.stringify(SESSION_START_HOOKS_MANIFEST, null, 2));
12816
12885
  console.log(` [Claude Desktop (Cowork)] Bundled SessionStart hook -> ${scriptPath}`);
12817
12886
  }
12818
12887
  function writePluginTree(destDir, input) {
@@ -12847,22 +12916,22 @@ function getPluginMetadata() {
12847
12916
  function getMcpConfigPath() {
12848
12917
  const os2 = platform3();
12849
12918
  if (os2 === "darwin") {
12850
- return join25(homedir7(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
12919
+ return join26(homedir8(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
12851
12920
  }
12852
12921
  if (os2 === "win32") {
12853
- return join25(process.env.APPDATA || join25(homedir7(), "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
12922
+ return join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
12854
12923
  }
12855
- return join25(homedir7(), ".config", "Claude", "claude_desktop_config.json");
12924
+ return join26(homedir8(), ".config", "Claude", "claude_desktop_config.json");
12856
12925
  }
12857
12926
  function getCoworkBaseDir() {
12858
12927
  const os2 = platform3();
12859
12928
  if (os2 === "darwin") {
12860
- return join25(homedir7(), "Library", "Application Support", "Claude", "local-agent-mode-sessions");
12929
+ return join26(homedir8(), "Library", "Application Support", "Claude", "local-agent-mode-sessions");
12861
12930
  }
12862
12931
  if (os2 === "win32") {
12863
- return join25(process.env.APPDATA || join25(homedir7(), "AppData", "Roaming"), "Claude", "local-agent-mode-sessions");
12932
+ return join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude", "local-agent-mode-sessions");
12864
12933
  }
12865
- return join25(homedir7(), ".config", "Claude", "local-agent-mode-sessions");
12934
+ return join26(homedir8(), ".config", "Claude", "local-agent-mode-sessions");
12866
12935
  }
12867
12936
  function listOrgDirs() {
12868
12937
  const baseDir = getCoworkBaseDir();
@@ -12872,10 +12941,10 @@ function listOrgDirs() {
12872
12941
  try {
12873
12942
  const sessionDirs = readdirSync8(baseDir).filter((d) => !d.startsWith(".") && d !== "skills-plugin");
12874
12943
  for (const sessionId of sessionDirs) {
12875
- const sessionPath = join25(baseDir, sessionId);
12944
+ const sessionPath = join26(baseDir, sessionId);
12876
12945
  try {
12877
12946
  for (const orgId of readdirSync8(sessionPath).filter((d) => !d.startsWith("."))) {
12878
- dirs.push(join25(sessionPath, orgId));
12947
+ dirs.push(join26(sessionPath, orgId));
12879
12948
  }
12880
12949
  } catch {
12881
12950
  continue;
@@ -12891,7 +12960,7 @@ function walkOrgDirs(visit) {
12891
12960
  try {
12892
12961
  const sessionDirs = readdirSync8(baseDir).filter((d) => !d.startsWith(".") && d !== "skills-plugin");
12893
12962
  for (const sessionId of sessionDirs) {
12894
- const sessionPath = join25(baseDir, sessionId);
12963
+ const sessionPath = join26(baseDir, sessionId);
12895
12964
  let orgDirs;
12896
12965
  try {
12897
12966
  orgDirs = readdirSync8(sessionPath).filter((d) => !d.startsWith("."));
@@ -12899,7 +12968,7 @@ function walkOrgDirs(visit) {
12899
12968
  continue;
12900
12969
  }
12901
12970
  for (const orgId of orgDirs) {
12902
- const orgDir = join25(sessionPath, orgId);
12971
+ const orgDir = join26(sessionPath, orgId);
12903
12972
  const result = visit(orgDir);
12904
12973
  if (result !== null)
12905
12974
  return result;
@@ -12916,7 +12985,7 @@ function getCoworkMemoryClaudeMdPaths() {
12916
12985
  try {
12917
12986
  const sessionDirs = readdirSync8(baseDir).filter((d) => !d.startsWith(".") && d !== "skills-plugin");
12918
12987
  for (const sessionId of sessionDirs) {
12919
- const sessionPath = join25(baseDir, sessionId);
12988
+ const sessionPath = join26(baseDir, sessionId);
12920
12989
  let orgDirs;
12921
12990
  try {
12922
12991
  orgDirs = readdirSync8(sessionPath).filter((d) => !d.startsWith("."));
@@ -12924,7 +12993,7 @@ function getCoworkMemoryClaudeMdPaths() {
12924
12993
  continue;
12925
12994
  }
12926
12995
  for (const orgId of orgDirs) {
12927
- paths.push(join25(sessionPath, orgId, "memory", "CLAUDE.md"));
12996
+ paths.push(join26(sessionPath, orgId, "memory", "CLAUDE.md"));
12928
12997
  }
12929
12998
  }
12930
12999
  } catch {}
@@ -12932,13 +13001,13 @@ function getCoworkMemoryClaudeMdPaths() {
12932
13001
  }
12933
13002
  function findCoworkPluginsDir() {
12934
13003
  return walkOrgDirs((orgDir) => {
12935
- const pluginsDir = join25(orgDir, "cowork_plugins");
12936
- return existsSync32(join25(pluginsDir, "installed_plugins.json")) ? pluginsDir : null;
13004
+ const pluginsDir = join26(orgDir, "cowork_plugins");
13005
+ return existsSync32(join26(pluginsDir, "installed_plugins.json")) ? pluginsDir : null;
12937
13006
  });
12938
13007
  }
12939
13008
  function findRpmPluginByName(pluginName) {
12940
13009
  return walkOrgDirs((orgDir) => {
12941
- const manifestPath = join25(orgDir, "rpm", "manifest.json");
13010
+ const manifestPath = join26(orgDir, "rpm", "manifest.json");
12942
13011
  if (!existsSync32(manifestPath))
12943
13012
  return null;
12944
13013
  try {
@@ -12947,7 +13016,7 @@ function findRpmPluginByName(pluginName) {
12947
13016
  if (!entry?.id)
12948
13017
  return null;
12949
13018
  return {
12950
- pluginPath: join25(orgDir, "rpm", entry.id),
13019
+ pluginPath: join26(orgDir, "rpm", entry.id),
12951
13020
  orgDir
12952
13021
  };
12953
13022
  } catch {
@@ -12969,7 +13038,7 @@ function getMarketplaceJson2() {
12969
13038
  };
12970
13039
  }
12971
13040
  function getCoworkSettingsPath(pluginsDir) {
12972
- return join25(dirname9(pluginsDir), "cowork_settings.json");
13041
+ return join26(dirname9(pluginsDir), "cowork_settings.json");
12973
13042
  }
12974
13043
  function setCoworkPluginEnabled(pluginsDir, enabled) {
12975
13044
  const settingsPath = getCoworkSettingsPath(pluginsDir);
@@ -13017,8 +13086,8 @@ class ClaudeDesktopAdapter {
13017
13086
  }
13018
13087
  const pluginsDir = findCoworkPluginsDir();
13019
13088
  if (pluginsDir) {
13020
- const cacheDir = join25(pluginsDir, "cache", "runwork", PLUGIN_NAME2, PLUGIN_VERSION2);
13021
- const marketDir = join25(pluginsDir, "marketplaces", "runwork", "plugins", PLUGIN_NAME2);
13089
+ const cacheDir = join26(pluginsDir, "cache", "runwork", PLUGIN_NAME2, PLUGIN_VERSION2);
13090
+ const marketDir = join26(pluginsDir, "marketplaces", "runwork", "plugins", PLUGIN_NAME2);
13022
13091
  for (const dir of [cacheDir, marketDir]) {
13023
13092
  writePluginMcpConfig(dir, servers);
13024
13093
  }
@@ -13036,14 +13105,14 @@ class ClaudeDesktopAdapter {
13036
13105
  console.warn(" [Claude Desktop] Cowork plugins directory not found. Open Claude Desktop at least once first.");
13037
13106
  return 0;
13038
13107
  }
13039
- const cacheDir = join25(pluginsDir, "cache", "runwork", PLUGIN_NAME2, PLUGIN_VERSION2);
13040
- const marketRoot = join25(pluginsDir, "marketplaces", "runwork");
13041
- const marketDir = join25(marketRoot, "plugins", PLUGIN_NAME2);
13108
+ const cacheDir = join26(pluginsDir, "cache", "runwork", PLUGIN_NAME2, PLUGIN_VERSION2);
13109
+ const marketRoot = join26(pluginsDir, "marketplaces", "runwork");
13110
+ const marketDir = join26(marketRoot, "plugins", PLUGIN_NAME2);
13042
13111
  for (const dir of [cacheDir, marketDir]) {
13043
13112
  writePluginMetadata(dir, getPluginMetadata());
13044
13113
  writePluginSkills(dir, skills);
13045
13114
  }
13046
- const installedPath = join25(pluginsDir, "installed_plugins.json");
13115
+ const installedPath = join26(pluginsDir, "installed_plugins.json");
13047
13116
  const installed = readJsonConfig(installedPath);
13048
13117
  if (!installed.version)
13049
13118
  installed.version = 2;
@@ -13057,10 +13126,10 @@ class ClaudeDesktopAdapter {
13057
13126
  lastUpdated: new Date().toISOString()
13058
13127
  }];
13059
13128
  writeJsonConfig(installedPath, installed);
13060
- const marketCatalogDir = join25(marketRoot, ".claude-plugin");
13129
+ const marketCatalogDir = join26(marketRoot, ".claude-plugin");
13061
13130
  mkdirSync18(marketCatalogDir, { recursive: true });
13062
- writeFileSync18(join25(marketCatalogDir, "marketplace.json"), JSON.stringify(getMarketplaceJson2(), null, 2));
13063
- const marketplacesPath = join25(pluginsDir, "known_marketplaces.json");
13131
+ writeFileSync18(join26(marketCatalogDir, "marketplace.json"), JSON.stringify(getMarketplaceJson2(), null, 2));
13132
+ const marketplacesPath = join26(pluginsDir, "known_marketplaces.json");
13064
13133
  const marketplaces = readJsonConfig(marketplacesPath);
13065
13134
  marketplaces["runwork"] = {
13066
13135
  source: { source: "directory", path: marketRoot },
@@ -13079,8 +13148,8 @@ class ClaudeDesktopAdapter {
13079
13148
  }
13080
13149
  }
13081
13150
  async buildPluginZip(skills, mcpServers, teamInstructions, outputPath) {
13082
- const stagingRoot = mkdtempSync3(join25(tmpdir3(), "runwork-plugin-"));
13083
- const pluginStagingDir = join25(stagingRoot, PLUGIN_NAME2);
13151
+ const stagingRoot = mkdtempSync3(join26(tmpdir3(), "runwork-plugin-"));
13152
+ const pluginStagingDir = join26(stagingRoot, PLUGIN_NAME2);
13084
13153
  try {
13085
13154
  writePluginTree(pluginStagingDir, {
13086
13155
  ...getPluginMetadata(),
@@ -13111,8 +13180,8 @@ class ClaudeDesktopAdapter {
13111
13180
  const pluginsDir = findCoworkPluginsDir();
13112
13181
  if (!pluginsDir)
13113
13182
  return;
13114
- writePluginTeamInstructions(join25(pluginsDir, "cache", "runwork", PLUGIN_NAME2, PLUGIN_VERSION2), instructions);
13115
- writePluginTeamInstructions(join25(pluginsDir, "marketplaces", "runwork", "plugins", PLUGIN_NAME2), instructions);
13183
+ writePluginTeamInstructions(join26(pluginsDir, "cache", "runwork", PLUGIN_NAME2, PLUGIN_VERSION2), instructions);
13184
+ writePluginTeamInstructions(join26(pluginsDir, "marketplaces", "runwork", "plugins", PLUGIN_NAME2), instructions);
13116
13185
  }
13117
13186
  async writeAgentConfig(config, _scope) {
13118
13187
  const configPath = getMcpConfigPath();
@@ -13154,7 +13223,7 @@ class ClaudeDesktopAdapter {
13154
13223
  } catch {}
13155
13224
  }
13156
13225
  for (const orgDir of listOrgDirs()) {
13157
- const manifestPath = join25(orgDir, "rpm", "manifest.json");
13226
+ const manifestPath = join26(orgDir, "rpm", "manifest.json");
13158
13227
  if (!existsSync32(manifestPath))
13159
13228
  continue;
13160
13229
  try {
@@ -13167,7 +13236,7 @@ class ClaudeDesktopAdapter {
13167
13236
  for (const entry of ours) {
13168
13237
  if (!entry.id)
13169
13238
  continue;
13170
- moveToTrash(join25(orgDir, "rpm", entry.id), `claude-desktop-plugin:${entry.name}`);
13239
+ moveToTrash(join26(orgDir, "rpm", entry.id), `claude-desktop-plugin:${entry.name}`);
13171
13240
  }
13172
13241
  manifest.plugins = manifest.plugins.filter((p) => !isRunworkRpmPluginName(p.name));
13173
13242
  manifest.lastUpdated = Date.now();
@@ -13175,11 +13244,11 @@ class ClaudeDesktopAdapter {
13175
13244
  } catch {}
13176
13245
  }
13177
13246
  for (const orgDir of listOrgDirs()) {
13178
- const pluginsDir = join25(orgDir, "cowork_plugins");
13179
- if (!existsSync32(join25(pluginsDir, "installed_plugins.json")))
13247
+ const pluginsDir = join26(orgDir, "cowork_plugins");
13248
+ if (!existsSync32(join26(pluginsDir, "installed_plugins.json")))
13180
13249
  continue;
13181
- const cacheRunwork = join25(pluginsDir, "cache", "runwork");
13182
- const marketRunwork = join25(pluginsDir, "marketplaces", "runwork");
13250
+ const cacheRunwork = join26(pluginsDir, "cache", "runwork");
13251
+ const marketRunwork = join26(pluginsDir, "marketplaces", "runwork");
13183
13252
  for (const dir of [cacheRunwork, marketRunwork]) {
13184
13253
  if (existsSync32(dir)) {
13185
13254
  try {
@@ -13187,7 +13256,7 @@ class ClaudeDesktopAdapter {
13187
13256
  } catch {}
13188
13257
  }
13189
13258
  }
13190
- const installedPath = join25(pluginsDir, "installed_plugins.json");
13259
+ const installedPath = join26(pluginsDir, "installed_plugins.json");
13191
13260
  try {
13192
13261
  const installed = readJsonConfig(installedPath);
13193
13262
  if (installed.plugins) {
@@ -13198,7 +13267,7 @@ class ClaudeDesktopAdapter {
13198
13267
  writeJsonConfig(installedPath, installed);
13199
13268
  }
13200
13269
  } catch {}
13201
- const marketplacesPath = join25(pluginsDir, "known_marketplaces.json");
13270
+ const marketplacesPath = join26(pluginsDir, "known_marketplaces.json");
13202
13271
  if (existsSync32(marketplacesPath)) {
13203
13272
  try {
13204
13273
  const marketplaces = readJsonConfig(marketplacesPath);
@@ -13229,11 +13298,11 @@ class ClaudeDesktopAdapter {
13229
13298
  const os2 = platform3();
13230
13299
  let claudeAppDir;
13231
13300
  if (os2 === "darwin") {
13232
- claudeAppDir = join25(homedir7(), "Library", "Application Support", "Claude");
13301
+ claudeAppDir = join26(homedir8(), "Library", "Application Support", "Claude");
13233
13302
  } else if (os2 === "win32") {
13234
- claudeAppDir = join25(process.env.APPDATA || join25(homedir7(), "AppData", "Roaming"), "Claude");
13303
+ claudeAppDir = join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude");
13235
13304
  } else {
13236
- claudeAppDir = join25(homedir7(), ".config", "Claude");
13305
+ claudeAppDir = join26(homedir8(), ".config", "Claude");
13237
13306
  }
13238
13307
  if (!existsSync32(claudeAppDir))
13239
13308
  return null;
@@ -13242,7 +13311,7 @@ class ClaudeDesktopAdapter {
13242
13311
  let latestActivity = 0;
13243
13312
  const modelsUsed = new Set;
13244
13313
  let maxMcpTools = 0;
13245
- const agentSessionsDir = join25(claudeAppDir, "local-agent-mode-sessions");
13314
+ const agentSessionsDir = join26(claudeAppDir, "local-agent-mode-sessions");
13246
13315
  const activeDays = new Set;
13247
13316
  if (existsSync32(agentSessionsDir)) {
13248
13317
  this.walkSessionDirs(agentSessionsDir, sinceMs, (session) => {
@@ -13262,7 +13331,7 @@ class ClaudeDesktopAdapter {
13262
13331
  }
13263
13332
  });
13264
13333
  }
13265
- const codeSessionsDir = join25(claudeAppDir, "claude-code-sessions");
13334
+ const codeSessionsDir = join26(claudeAppDir, "claude-code-sessions");
13266
13335
  if (existsSync32(codeSessionsDir)) {
13267
13336
  this.walkSessionDirs(codeSessionsDir, sinceMs, (session) => {
13268
13337
  const sessionTime = session.lastActivityAt ?? session.createdAt ?? 0;
@@ -13277,7 +13346,7 @@ class ClaudeDesktopAdapter {
13277
13346
  });
13278
13347
  }
13279
13348
  let scheduledTaskRuns = 0;
13280
- const scheduledTasksPath = join25(claudeAppDir, "scheduled-tasks.json");
13349
+ const scheduledTasksPath = join26(claudeAppDir, "scheduled-tasks.json");
13281
13350
  if (existsSync32(scheduledTasksPath)) {
13282
13351
  try {
13283
13352
  const raw = readFileSync26(scheduledTasksPath, "utf-8");
@@ -13316,13 +13385,13 @@ class ClaudeDesktopAdapter {
13316
13385
  const os2 = platform3();
13317
13386
  let claudeAppDir;
13318
13387
  if (os2 === "darwin") {
13319
- claudeAppDir = join25(homedir7(), "Library", "Application Support", "Claude");
13388
+ claudeAppDir = join26(homedir8(), "Library", "Application Support", "Claude");
13320
13389
  } else if (os2 === "win32") {
13321
- claudeAppDir = join25(process.env.APPDATA || join25(homedir7(), "AppData", "Roaming"), "Claude");
13390
+ claudeAppDir = join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude");
13322
13391
  } else {
13323
- claudeAppDir = join25(homedir7(), ".config", "Claude");
13392
+ claudeAppDir = join26(homedir8(), ".config", "Claude");
13324
13393
  }
13325
- const versionPath = join25(claudeAppDir, "claude-code", "sdk-version");
13394
+ const versionPath = join26(claudeAppDir, "claude-code", "sdk-version");
13326
13395
  if (existsSync32(versionPath)) {
13327
13396
  return readFileSync26(versionPath, "utf-8").trim();
13328
13397
  }
@@ -13336,7 +13405,7 @@ class ClaudeDesktopAdapter {
13336
13405
  for (const orgDir of readdirSync8(baseDir)) {
13337
13406
  if (orgDir.startsWith(".") || orgDir === "skills-plugin")
13338
13407
  continue;
13339
- const orgPath = join25(baseDir, orgDir);
13408
+ const orgPath = join26(baseDir, orgDir);
13340
13409
  try {
13341
13410
  if (!statSync5(orgPath).isDirectory())
13342
13411
  continue;
@@ -13346,7 +13415,7 @@ class ClaudeDesktopAdapter {
13346
13415
  for (const userDir of readdirSync8(orgPath)) {
13347
13416
  if (userDir.startsWith("."))
13348
13417
  continue;
13349
- const userPath = join25(orgPath, userDir);
13418
+ const userPath = join26(orgPath, userDir);
13350
13419
  try {
13351
13420
  if (!statSync5(userPath).isDirectory())
13352
13421
  continue;
@@ -13357,7 +13426,7 @@ class ClaudeDesktopAdapter {
13357
13426
  if (!file.endsWith(".json"))
13358
13427
  continue;
13359
13428
  try {
13360
- const session = JSON.parse(readFileSync26(join25(userPath, file), "utf-8"));
13429
+ const session = JSON.parse(readFileSync26(join26(userPath, file), "utf-8"));
13361
13430
  onSession(session);
13362
13431
  } catch {
13363
13432
  continue;
@@ -13372,8 +13441,8 @@ class ClaudeDesktopAdapter {
13372
13441
  // src/agents/cursor.ts
13373
13442
  init_subprocess();
13374
13443
  import { existsSync as existsSync33, mkdirSync as mkdirSync19, unlinkSync as unlinkSync4, writeFileSync as writeFileSync19 } from "fs";
13375
- import { join as join26 } from "path";
13376
- import { homedir as homedir8, platform as platform4 } from "os";
13444
+ import { join as join27 } from "path";
13445
+ import { homedir as homedir9, platform as platform4 } from "os";
13377
13446
 
13378
13447
  // src/utils/sqlite-adapter.ts
13379
13448
  var adapter = null;
@@ -13476,7 +13545,7 @@ class CursorAdapter {
13476
13545
  return true;
13477
13546
  }
13478
13547
  async writeMcpServers(servers, scope) {
13479
- const filePath = scope === "project" ? join26(process.cwd(), ".cursor", "mcp.json") : join26(homedir8(), ".cursor", "mcp.json");
13548
+ const filePath = scope === "project" ? join27(process.cwd(), ".cursor", "mcp.json") : join27(homedir9(), ".cursor", "mcp.json");
13480
13549
  const entries = {};
13481
13550
  for (const s of servers) {
13482
13551
  entries[s.name] = {
@@ -13489,7 +13558,7 @@ class CursorAdapter {
13489
13558
  async writeSkills(skills, scope) {
13490
13559
  if (scope === "user")
13491
13560
  return 0;
13492
- const rulesDir = join26(process.cwd(), ".cursor", "rules");
13561
+ const rulesDir = join27(process.cwd(), ".cursor", "rules");
13493
13562
  mkdirSync19(rulesDir, { recursive: true });
13494
13563
  for (const skill of skills) {
13495
13564
  const mdcContent = `---
@@ -13498,30 +13567,30 @@ alwaysApply: false
13498
13567
  ---
13499
13568
 
13500
13569
  ${skill.content}`;
13501
- writeFileSync19(join26(rulesDir, `${skill.filename}.mdc`), mdcContent);
13570
+ writeFileSync19(join27(rulesDir, `${skill.filename}.mdc`), mdcContent);
13502
13571
  }
13503
13572
  return skills.length;
13504
13573
  }
13505
13574
  async writeInstructionHint(hint, scope) {
13506
- const filePath = scope === "project" ? join26(process.cwd(), ".cursor", "rules", "runwork.mdc") : join26(homedir8(), ".cursor", "rules", "runwork.mdc");
13575
+ const filePath = scope === "project" ? join27(process.cwd(), ".cursor", "rules", "runwork.mdc") : join27(homedir9(), ".cursor", "rules", "runwork.mdc");
13507
13576
  const mdcContent = `---
13508
13577
  description: "Runwork workspace connection"
13509
13578
  alwaysApply: true
13510
13579
  ---
13511
13580
 
13512
13581
  ${hint}`;
13513
- mkdirSync19(join26(filePath, ".."), { recursive: true });
13582
+ mkdirSync19(join27(filePath, ".."), { recursive: true });
13514
13583
  writeFileSync19(filePath, mdcContent);
13515
13584
  }
13516
13585
  async writeTeamInstructions(instructions, scope) {
13517
- const filePath = scope === "project" ? join26(process.cwd(), ".cursor", "rules", "runwork-team.mdc") : join26(homedir8(), ".cursor", "rules", "runwork-team.mdc");
13586
+ const filePath = scope === "project" ? join27(process.cwd(), ".cursor", "rules", "runwork-team.mdc") : join27(homedir9(), ".cursor", "rules", "runwork-team.mdc");
13518
13587
  const mdcContent = `---
13519
13588
  description: "Team instructions from Runwork workspace"
13520
13589
  alwaysApply: true
13521
13590
  ---
13522
13591
 
13523
13592
  ${instructions}`;
13524
- mkdirSync19(join26(filePath, ".."), { recursive: true });
13593
+ mkdirSync19(join27(filePath, ".."), { recursive: true });
13525
13594
  writeFileSync19(filePath, mdcContent);
13526
13595
  }
13527
13596
  async writeAgentConfig(config, scope, baseline) {
@@ -13567,7 +13636,7 @@ ${instructions}`;
13567
13636
  return;
13568
13637
  }
13569
13638
  mergeSandboxAllowlist(domains) {
13570
- const configPath = join26(homedir8(), ".cursor", "sandbox.json");
13639
+ const configPath = join27(homedir9(), ".cursor", "sandbox.json");
13571
13640
  try {
13572
13641
  const config = readJsonConfig(configPath);
13573
13642
  if (!config.networkPolicy)
@@ -13585,15 +13654,15 @@ ${instructions}`;
13585
13654
  async removeSkills(skillFilenames, scope) {
13586
13655
  if (scope !== "project")
13587
13656
  return;
13588
- removeMatchingSkillFiles(join26(process.cwd(), ".cursor", "rules"), new Set(skillFilenames), ".mdc");
13657
+ removeMatchingSkillFiles(join27(process.cwd(), ".cursor", "rules"), new Set(skillFilenames), ".mdc");
13589
13658
  }
13590
13659
  async cleanup(scope, manifest) {
13591
- const mcpPath = scope === "project" ? join26(process.cwd(), ".cursor", "mcp.json") : join26(homedir8(), ".cursor", "mcp.json");
13660
+ const mcpPath = scope === "project" ? join27(process.cwd(), ".cursor", "mcp.json") : join27(homedir9(), ".cursor", "mcp.json");
13592
13661
  removeRunworkMcpServers(mcpPath, "mcpServers");
13593
- const rulesDir = scope === "project" ? join26(process.cwd(), ".cursor", "rules") : join26(homedir8(), ".cursor", "rules");
13662
+ const rulesDir = scope === "project" ? join27(process.cwd(), ".cursor", "rules") : join27(homedir9(), ".cursor", "rules");
13594
13663
  if (existsSync33(rulesDir)) {
13595
13664
  for (const file of ["runwork.mdc", "runwork-team.mdc"]) {
13596
- const filePath = join26(rulesDir, file);
13665
+ const filePath = join27(rulesDir, file);
13597
13666
  if (existsSync33(filePath)) {
13598
13667
  try {
13599
13668
  unlinkSync4(filePath);
@@ -13675,7 +13744,7 @@ ${instructions}`;
13675
13744
  }
13676
13745
  }
13677
13746
  const sessionCount = newComposersWithoutId + activeComposerIds.size;
13678
- const trackingDbPath = join26(homedir8(), ".cursor", "ai-tracking", "ai-code-tracking.db");
13747
+ const trackingDbPath = join27(homedir9(), ".cursor", "ai-tracking", "ai-code-tracking.db");
13679
13748
  let aiCommitCount = 0;
13680
13749
  let avgAiPercent = 0;
13681
13750
  if (existsSync33(trackingDbPath)) {
@@ -13721,12 +13790,12 @@ ${instructions}`;
13721
13790
  globalStorageDbPath() {
13722
13791
  const os2 = platform4();
13723
13792
  if (os2 === "darwin") {
13724
- return join26(homedir8(), "Library", "Application Support", "Cursor", "User", "globalStorage", "state.vscdb");
13793
+ return join27(homedir9(), "Library", "Application Support", "Cursor", "User", "globalStorage", "state.vscdb");
13725
13794
  }
13726
13795
  if (os2 === "win32") {
13727
- return join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Cursor", "User", "globalStorage", "state.vscdb");
13796
+ return join27(process.env.APPDATA || join27(homedir9(), "AppData", "Roaming"), "Cursor", "User", "globalStorage", "state.vscdb");
13728
13797
  }
13729
- return join26(homedir8(), ".config", "Cursor", "User", "globalStorage", "state.vscdb");
13798
+ return join27(homedir9(), ".config", "Cursor", "User", "globalStorage", "state.vscdb");
13730
13799
  }
13731
13800
  async readSessionDigests(sinceISO) {
13732
13801
  try {
@@ -13746,16 +13815,16 @@ ${instructions}`;
13746
13815
 
13747
13816
  // src/agents/windsurf.ts
13748
13817
  import { existsSync as existsSync34, mkdirSync as mkdirSync20, unlinkSync as unlinkSync5, writeFileSync as writeFileSync20 } from "fs";
13749
- import { join as join27 } from "path";
13750
- import { homedir as homedir9, platform as platform5 } from "os";
13818
+ import { join as join28 } from "path";
13819
+ import { homedir as homedir10, platform as platform5 } from "os";
13751
13820
  function getWindsurfDataDir() {
13752
13821
  if (platform5() === "win32") {
13753
- return join27(process.env.APPDATA || join27(homedir9(), "AppData", "Roaming"), "Codeium", "windsurf");
13822
+ return join28(process.env.APPDATA || join28(homedir10(), "AppData", "Roaming"), "Codeium", "windsurf");
13754
13823
  }
13755
- return join27(homedir9(), ".codeium", "windsurf");
13824
+ return join28(homedir10(), ".codeium", "windsurf");
13756
13825
  }
13757
13826
  function getConfigPath() {
13758
- return join27(getWindsurfDataDir(), "mcp_config.json");
13827
+ return join28(getWindsurfDataDir(), "mcp_config.json");
13759
13828
  }
13760
13829
 
13761
13830
  class WindsurfAdapter {
@@ -13787,7 +13856,7 @@ class WindsurfAdapter {
13787
13856
  async writeSkills(skills, scope) {
13788
13857
  if (scope === "user")
13789
13858
  return 0;
13790
- const rulesDir = join27(process.cwd(), ".windsurf", "rules");
13859
+ const rulesDir = join28(process.cwd(), ".windsurf", "rules");
13791
13860
  mkdirSync20(rulesDir, { recursive: true });
13792
13861
  for (const skill of skills) {
13793
13862
  const content = `---
@@ -13795,44 +13864,44 @@ trigger: manual
13795
13864
  ---
13796
13865
 
13797
13866
  ${skill.content}`;
13798
- writeFileSync20(join27(rulesDir, `${skill.filename}.md`), content);
13867
+ writeFileSync20(join28(rulesDir, `${skill.filename}.md`), content);
13799
13868
  }
13800
13869
  return skills.length;
13801
13870
  }
13802
13871
  async writeTeamInstructions(instructions, scope) {
13803
- const filePath = scope === "project" ? join27(process.cwd(), ".windsurf", "rules", "runwork-team.md") : join27(getWindsurfDataDir(), "rules", "runwork-team.md");
13872
+ const filePath = scope === "project" ? join28(process.cwd(), ".windsurf", "rules", "runwork-team.md") : join28(getWindsurfDataDir(), "rules", "runwork-team.md");
13804
13873
  const content = `---
13805
13874
  trigger: always_on
13806
13875
  description: "Team instructions from Runwork workspace"
13807
13876
  ---
13808
13877
 
13809
13878
  ${instructions}`;
13810
- mkdirSync20(join27(filePath, ".."), { recursive: true });
13879
+ mkdirSync20(join28(filePath, ".."), { recursive: true });
13811
13880
  writeFileSync20(filePath, content);
13812
13881
  }
13813
13882
  async writeInstructionHint(hint, scope) {
13814
- const filePath = scope === "project" ? join27(process.cwd(), ".windsurf", "rules", "runwork.md") : join27(getWindsurfDataDir(), "rules", "runwork.md");
13883
+ const filePath = scope === "project" ? join28(process.cwd(), ".windsurf", "rules", "runwork.md") : join28(getWindsurfDataDir(), "rules", "runwork.md");
13815
13884
  const content = `---
13816
13885
  trigger: always
13817
13886
  ---
13818
13887
 
13819
13888
  ${hint}`;
13820
- mkdirSync20(join27(filePath, ".."), { recursive: true });
13889
+ mkdirSync20(join28(filePath, ".."), { recursive: true });
13821
13890
  writeFileSync20(filePath, content);
13822
13891
  }
13823
13892
  async removeSkills(skillFilenames, scope) {
13824
13893
  if (scope !== "project")
13825
13894
  return;
13826
- removeMatchingSkillFiles(join27(process.cwd(), ".windsurf", "rules"), new Set(skillFilenames), ".md");
13895
+ removeMatchingSkillFiles(join28(process.cwd(), ".windsurf", "rules"), new Set(skillFilenames), ".md");
13827
13896
  }
13828
13897
  async cleanup(scope, manifest) {
13829
13898
  if (scope === "user") {
13830
13899
  removeRunworkMcpServers(getConfigPath(), "mcpServers");
13831
13900
  }
13832
- const rulesDir = scope === "project" ? join27(process.cwd(), ".windsurf", "rules") : join27(getWindsurfDataDir(), "rules");
13901
+ const rulesDir = scope === "project" ? join28(process.cwd(), ".windsurf", "rules") : join28(getWindsurfDataDir(), "rules");
13833
13902
  if (existsSync34(rulesDir)) {
13834
13903
  for (const file of ["runwork.md", "runwork-team.md"]) {
13835
- const filePath = join27(rulesDir, file);
13904
+ const filePath = join28(rulesDir, file);
13836
13905
  if (existsSync34(filePath)) {
13837
13906
  try {
13838
13907
  unlinkSync5(filePath);
@@ -13846,20 +13915,20 @@ ${hint}`;
13846
13915
 
13847
13916
  // src/agents/codex.ts
13848
13917
  import { existsSync as existsSync37, mkdirSync as mkdirSync21, readdirSync as readdirSync11, readFileSync as readFileSync27, statSync as statSync6, writeFileSync as writeFileSync21 } from "fs";
13849
- import { join as join30 } from "path";
13850
- import { homedir as homedir12 } from "os";
13918
+ import { join as join31 } from "path";
13919
+ import { homedir as homedir13 } from "os";
13851
13920
  import { parse, stringify } from "smol-toml";
13852
13921
 
13853
13922
  // src/agents/detection.ts
13854
13923
  import { execFile } from "child_process";
13855
13924
  import { existsSync as existsSync36 } from "fs";
13856
- import { homedir as homedir11, platform as platform7 } from "os";
13857
- import { isAbsolute as isAbsolute2, join as join29 } from "path";
13925
+ import { homedir as homedir12, platform as platform7 } from "os";
13926
+ import { isAbsolute as isAbsolute2, join as join30 } from "path";
13858
13927
  import { promisify } from "util";
13859
13928
 
13860
13929
  // src/agents/registry.ts
13861
- import { platform as platform6, homedir as homedir10 } from "os";
13862
- import { isAbsolute, join as join28 } from "path";
13930
+ import { platform as platform6, homedir as homedir11 } from "os";
13931
+ import { isAbsolute, join as join29 } from "path";
13863
13932
  import { existsSync as existsSync35 } from "fs";
13864
13933
 
13865
13934
  // src/agents/registry-data.ts
@@ -14457,7 +14526,7 @@ function resolveToAbsolute(ps, scope) {
14457
14526
  const resolved = resolvePlatformString(ps);
14458
14527
  if (!resolved)
14459
14528
  return;
14460
- return scope === "global" ? join28(homedir10(), resolved) : join28(process.cwd(), resolved);
14529
+ return scope === "global" ? join29(homedir11(), resolved) : join29(process.cwd(), resolved);
14461
14530
  }
14462
14531
  function resolveAgentCliCommand(slug) {
14463
14532
  const agent = getAgent(slug);
@@ -14470,7 +14539,7 @@ function resolveAgentCliCommand(slug) {
14470
14539
  const resolved = resolvePlatformString(candidate);
14471
14540
  if (!resolved)
14472
14541
  continue;
14473
- const absolute = isAbsolute(resolved) ? resolved : join28(homedir10(), resolved);
14542
+ const absolute = isAbsolute(resolved) ? resolved : join29(homedir11(), resolved);
14474
14543
  if (existsSync35(absolute))
14475
14544
  return absolute;
14476
14545
  }
@@ -14514,7 +14583,7 @@ function resolveDetectionPath(target) {
14514
14583
  const resolved = resolvePlatformString(target);
14515
14584
  if (!resolved)
14516
14585
  return null;
14517
- return isAbsolute2(resolved) ? resolved : join29(homedir11(), resolved);
14586
+ return isAbsolute2(resolved) ? resolved : join30(homedir12(), resolved);
14518
14587
  }
14519
14588
  function checkPath(target) {
14520
14589
  const absolute = resolveDetectionPath(target);
@@ -14600,7 +14669,7 @@ class CodexAdapter {
14600
14669
  return true;
14601
14670
  }
14602
14671
  async writeMcpServers(servers, _scope) {
14603
- const configPath = join30(homedir12(), ".codex", "config.toml");
14672
+ const configPath = join31(homedir13(), ".codex", "config.toml");
14604
14673
  let parsed = {};
14605
14674
  if (existsSync37(configPath)) {
14606
14675
  parsed = parse(readFileSync27(configPath, "utf-8"));
@@ -14626,36 +14695,36 @@ class CodexAdapter {
14626
14695
  }
14627
14696
  mcpServers[safeName] = entry;
14628
14697
  }
14629
- mkdirSync21(join30(configPath, ".."), { recursive: true });
14698
+ mkdirSync21(join31(configPath, ".."), { recursive: true });
14630
14699
  writeFileSync21(configPath, stringify(parsed));
14631
14700
  }
14632
14701
  async writeSkills(skills, scope) {
14633
- const root = scope === "project" ? process.cwd() : homedir12();
14634
- const baseDir = join30(root, ".agents", "skills");
14635
- const legacyBaseDir = join30(root, ".codex", "skills");
14702
+ const root = scope === "project" ? process.cwd() : homedir13();
14703
+ const baseDir = join31(root, ".agents", "skills");
14704
+ const legacyBaseDir = join31(root, ".codex", "skills");
14636
14705
  for (const skill of skills) {
14637
14706
  if (skill.name !== skill.filename) {
14638
- for (const dir of [join30(baseDir, skill.name), join30(legacyBaseDir, skill.name)]) {
14707
+ for (const dir of [join31(baseDir, skill.name), join31(legacyBaseDir, skill.name)]) {
14639
14708
  moveToTrash(dir, `skill renamed to ${skill.filename}`);
14640
14709
  }
14641
14710
  }
14642
- moveToTrash(join30(legacyBaseDir, skill.filename), "duplicate skill root consolidated");
14643
- const skillDir = join30(baseDir, skill.filename);
14711
+ moveToTrash(join31(legacyBaseDir, skill.filename), "duplicate skill root consolidated");
14712
+ const skillDir = join31(baseDir, skill.filename);
14644
14713
  mkdirSync21(skillDir, { recursive: true });
14645
- writeFileSync21(join30(skillDir, "SKILL.md"), buildSkillMd2(skill));
14714
+ writeFileSync21(join31(skillDir, "SKILL.md"), buildSkillMd2(skill));
14646
14715
  }
14647
14716
  return skills.length;
14648
14717
  }
14649
14718
  async writeInstructionHint(hint, scope) {
14650
- const filePath = scope === "project" ? join30(process.cwd(), "AGENTS.md") : join30(homedir12(), ".codex", "AGENTS.md");
14719
+ const filePath = scope === "project" ? join31(process.cwd(), "AGENTS.md") : join31(homedir13(), ".codex", "AGENTS.md");
14651
14720
  writeHintToFile(filePath, hint);
14652
14721
  }
14653
14722
  async writeTeamInstructions(instructions, scope) {
14654
- const filePath = scope === "project" ? join30(process.cwd(), "AGENTS.md") : join30(homedir12(), ".codex", "AGENTS.md");
14723
+ const filePath = scope === "project" ? join31(process.cwd(), "AGENTS.md") : join31(homedir13(), ".codex", "AGENTS.md");
14655
14724
  writeTeamInstructionsToFile(filePath, instructions);
14656
14725
  }
14657
14726
  async writeAgentConfig(config, scope) {
14658
- const configPath = scope === "project" ? join30(process.cwd(), ".codex", "config.toml") : join30(homedir12(), ".codex", "config.toml");
14727
+ const configPath = scope === "project" ? join31(process.cwd(), ".codex", "config.toml") : join31(homedir13(), ".codex", "config.toml");
14659
14728
  let parsed = {};
14660
14729
  if (existsSync37(configPath)) {
14661
14730
  parsed = parse(readFileSync27(configPath, "utf-8"));
@@ -14701,20 +14770,20 @@ class CodexAdapter {
14701
14770
  sww.network_access = true;
14702
14771
  }
14703
14772
  }
14704
- mkdirSync21(join30(configPath, ".."), { recursive: true });
14773
+ mkdirSync21(join31(configPath, ".."), { recursive: true });
14705
14774
  writeFileSync21(configPath, stringify(parsed));
14706
14775
  }
14707
14776
  async removeSkills(skillFilenames, scope) {
14708
14777
  if (!skillFilenames.length)
14709
14778
  return;
14710
14779
  const allowed = new Set(skillFilenames);
14711
- const root = scope === "project" ? process.cwd() : homedir12();
14712
- for (const skillsDir of [join30(root, ".agents", "skills"), join30(root, ".codex", "skills")]) {
14780
+ const root = scope === "project" ? process.cwd() : homedir13();
14781
+ for (const skillsDir of [join31(root, ".agents", "skills"), join31(root, ".codex", "skills")]) {
14713
14782
  removeMatchingSkillDirs(skillsDir, allowed);
14714
14783
  }
14715
14784
  }
14716
14785
  async cleanup(scope, manifest) {
14717
- const configPath = join30(homedir12(), ".codex", "config.toml");
14786
+ const configPath = join31(homedir13(), ".codex", "config.toml");
14718
14787
  if (existsSync37(configPath)) {
14719
14788
  try {
14720
14789
  const parsed = parse(readFileSync27(configPath, "utf-8"));
@@ -14730,13 +14799,13 @@ class CodexAdapter {
14730
14799
  } catch {}
14731
14800
  }
14732
14801
  await this.removeSkills(manifest?.skillFilenames ?? [], scope);
14733
- const instructionFile = scope === "project" ? join30(process.cwd(), "AGENTS.md") : join30(homedir12(), ".codex", "AGENTS.md");
14802
+ const instructionFile = scope === "project" ? join31(process.cwd(), "AGENTS.md") : join31(homedir13(), ".codex", "AGENTS.md");
14734
14803
  removeHintFromFile(instructionFile);
14735
14804
  removeTeamInstructionsFromFile(instructionFile);
14736
14805
  }
14737
14806
  async readUsageStats(lastSyncAt) {
14738
14807
  try {
14739
- const codexDir = join30(homedir12(), ".codex");
14808
+ const codexDir = join31(homedir13(), ".codex");
14740
14809
  if (!existsSync37(codexDir))
14741
14810
  return null;
14742
14811
  const sinceMs = lastSyncAt ? new Date(lastSyncAt).getTime() : 0;
@@ -14746,7 +14815,7 @@ class CodexAdapter {
14746
14815
  let tokensUsed = rollout.tokensUsed;
14747
14816
  let latestMs = rollout.latestMs;
14748
14817
  let versions = [];
14749
- const dbPath = join30(codexDir, "state_5.sqlite");
14818
+ const dbPath = join31(codexDir, "state_5.sqlite");
14750
14819
  if (existsSync37(dbPath)) {
14751
14820
  const countResult = queryReadonlySqlite(dbPath, `SELECT count(*) FROM threads WHERE updated_at > ${sinceSec}`);
14752
14821
  const dbSessionCount = parseInt(countResult) || 0;
@@ -14764,7 +14833,7 @@ class CodexAdapter {
14764
14833
  }
14765
14834
  let messageCount = rollout.messageCount;
14766
14835
  if (messageCount === 0) {
14767
- const historyPath = join30(codexDir, "history.jsonl");
14836
+ const historyPath = join31(codexDir, "history.jsonl");
14768
14837
  if (existsSync37(historyPath)) {
14769
14838
  const content = readFileSync27(historyPath, "utf-8").trim();
14770
14839
  if (content) {
@@ -14809,7 +14878,7 @@ class CodexAdapter {
14809
14878
  latestMs: 0,
14810
14879
  activeDays: []
14811
14880
  };
14812
- const sessionsDir = join30(homedir12(), ".codex", "sessions");
14881
+ const sessionsDir = join31(homedir13(), ".codex", "sessions");
14813
14882
  if (!existsSync37(sessionsDir))
14814
14883
  return result;
14815
14884
  const files = [];
@@ -14821,7 +14890,7 @@ class CodexAdapter {
14821
14890
  return;
14822
14891
  }
14823
14892
  for (const e of entries) {
14824
- const full = join30(dir, e.name);
14893
+ const full = join31(dir, e.name);
14825
14894
  if (e.isDirectory())
14826
14895
  walk(full);
14827
14896
  else if (e.name.startsWith("rollout-") && e.name.endsWith(".jsonl"))
@@ -14899,7 +14968,7 @@ class CodexAdapter {
14899
14968
  }
14900
14969
  async readSessionDigests(sinceISO) {
14901
14970
  try {
14902
- const sessionsDir = join30(homedir12(), ".codex", "sessions");
14971
+ const sessionsDir = join31(homedir13(), ".codex", "sessions");
14903
14972
  if (!existsSync37(sessionsDir))
14904
14973
  return null;
14905
14974
  const sinceMs = sinceISO ? new Date(sinceISO).getTime() : 0;
@@ -14912,7 +14981,7 @@ class CodexAdapter {
14912
14981
  return;
14913
14982
  }
14914
14983
  for (const e of entries) {
14915
- const full = join30(dir, e.name);
14984
+ const full = join31(dir, e.name);
14916
14985
  if (e.isDirectory())
14917
14986
  walk(full);
14918
14987
  else if (e.name.startsWith("rollout-") && e.name.endsWith(".jsonl"))
@@ -14947,7 +15016,7 @@ class CodexAdapter {
14947
15016
  }
14948
15017
  async readVersion() {
14949
15018
  try {
14950
- const versionPath = join30(homedir12(), ".codex", "version.json");
15019
+ const versionPath = join31(homedir13(), ".codex", "version.json");
14951
15020
  if (existsSync37(versionPath)) {
14952
15021
  const data = JSON.parse(readFileSync27(versionPath, "utf-8"));
14953
15022
  return data.latest_version ?? null;
@@ -14957,7 +15026,7 @@ class CodexAdapter {
14957
15026
  }
14958
15027
  async readSkillUsage(lastSyncAt) {
14959
15028
  try {
14960
- const sessionsDir = join30(homedir12(), ".codex", "sessions");
15029
+ const sessionsDir = join31(homedir13(), ".codex", "sessions");
14961
15030
  if (!existsSync37(sessionsDir))
14962
15031
  return null;
14963
15032
  const sinceMs = lastSyncAt ? new Date(lastSyncAt).getTime() : 0;
@@ -14970,7 +15039,7 @@ class CodexAdapter {
14970
15039
  return;
14971
15040
  }
14972
15041
  for (const entry of entries) {
14973
- const fullPath = join30(dir, entry);
15042
+ const fullPath = join31(dir, entry);
14974
15043
  if (entry.endsWith(".jsonl")) {
14975
15044
  let fileStat;
14976
15045
  try {
@@ -15059,7 +15128,7 @@ class CodexAdapter {
15059
15128
  }
15060
15129
  }
15061
15130
  registerDesktopWorkspace(workspacePath, label) {
15062
- const statePath = join30(homedir12(), ".codex", ".codex-global-state.json");
15131
+ const statePath = join31(homedir13(), ".codex", ".codex-global-state.json");
15063
15132
  let state = {};
15064
15133
  if (existsSync37(statePath)) {
15065
15134
  try {
@@ -15090,7 +15159,7 @@ class CodexAdapter {
15090
15159
  }
15091
15160
  labels[workspacePath] = label;
15092
15161
  state["electron-workspace-root-labels"] = labels;
15093
- mkdirSync21(join30(statePath, ".."), { recursive: true });
15162
+ mkdirSync21(join31(statePath, ".."), { recursive: true });
15094
15163
  writeFileSync21(statePath, JSON.stringify(state));
15095
15164
  return "written";
15096
15165
  }
@@ -15112,8 +15181,8 @@ class CodexDesktopAdapter extends CodexAdapter {
15112
15181
 
15113
15182
  // src/agents/cline.ts
15114
15183
  import { existsSync as existsSync38, mkdirSync as mkdirSync22, readFileSync as readFileSync28, readdirSync as readdirSync12, rmSync as rmSync10, unlinkSync as unlinkSync6, writeFileSync as writeFileSync22 } from "fs";
15115
- import { join as join31 } from "path";
15116
- import { homedir as homedir13 } from "os";
15184
+ import { join as join32 } from "path";
15185
+ import { homedir as homedir14 } from "os";
15117
15186
  class ClineAdapter {
15118
15187
  name = "Cline";
15119
15188
  slug = "cline";
@@ -15128,7 +15197,7 @@ class ClineAdapter {
15128
15197
  return true;
15129
15198
  }
15130
15199
  async writeMcpServers(servers, _scope) {
15131
- const configPath = join31(homedir13(), ".cline", "data", "settings", "cline_mcp_settings.json");
15200
+ const configPath = join32(homedir14(), ".cline", "data", "settings", "cline_mcp_settings.json");
15132
15201
  const entries = {};
15133
15202
  for (const s of servers) {
15134
15203
  entries[s.name] = {
@@ -15141,31 +15210,31 @@ class ClineAdapter {
15141
15210
  async writeSkills(skills, scope) {
15142
15211
  if (scope === "user")
15143
15212
  return 0;
15144
- const rulesDir = join31(process.cwd(), ".clinerules");
15213
+ const rulesDir = join32(process.cwd(), ".clinerules");
15145
15214
  mkdirSync22(rulesDir, { recursive: true });
15146
15215
  for (const skill of skills) {
15147
- writeFileSync22(join31(rulesDir, `${skill.filename}.md`), buildSkillMd2(skill));
15216
+ writeFileSync22(join32(rulesDir, `${skill.filename}.md`), buildSkillMd2(skill));
15148
15217
  }
15149
15218
  return skills.length;
15150
15219
  }
15151
15220
  async writeInstructionHint(hint, scope) {
15152
15221
  if (scope === "user")
15153
15222
  return;
15154
- const filePath = join31(process.cwd(), ".clinerules", "runwork.md");
15155
- mkdirSync22(join31(filePath, ".."), { recursive: true });
15223
+ const filePath = join32(process.cwd(), ".clinerules", "runwork.md");
15224
+ mkdirSync22(join32(filePath, ".."), { recursive: true });
15156
15225
  writeFileSync22(filePath, hint);
15157
15226
  }
15158
15227
  async writeTeamInstructions(instructions, scope) {
15159
15228
  if (scope === "user")
15160
15229
  return;
15161
- const filePath = join31(process.cwd(), ".clinerules", "runwork-team.md");
15162
- mkdirSync22(join31(filePath, ".."), { recursive: true });
15230
+ const filePath = join32(process.cwd(), ".clinerules", "runwork-team.md");
15231
+ mkdirSync22(join32(filePath, ".."), { recursive: true });
15163
15232
  writeFileSync22(filePath, instructions);
15164
15233
  }
15165
15234
  async writeAgentConfig(config, scope) {
15166
15235
  if (scope !== "user")
15167
15236
  return;
15168
- const globalStatePath = join31(homedir13(), ".cline", "data", "globalState.json");
15237
+ const globalStatePath = join32(homedir14(), ".cline", "data", "globalState.json");
15169
15238
  let state = {};
15170
15239
  if (existsSync38(globalStatePath)) {
15171
15240
  try {
@@ -15190,24 +15259,24 @@ class ClineAdapter {
15190
15259
  state.autoApprovalSettings.enabled = false;
15191
15260
  }
15192
15261
  }
15193
- mkdirSync22(join31(globalStatePath, ".."), { recursive: true });
15262
+ mkdirSync22(join32(globalStatePath, ".."), { recursive: true });
15194
15263
  writeFileSync22(globalStatePath, JSON.stringify(state, null, 2));
15195
15264
  }
15196
15265
  async removeSkills(skillFilenames, scope) {
15197
15266
  if (scope !== "project")
15198
15267
  return;
15199
- removeMatchingSkillFiles(join31(process.cwd(), ".clinerules"), new Set(skillFilenames), ".md");
15268
+ removeMatchingSkillFiles(join32(process.cwd(), ".clinerules"), new Set(skillFilenames), ".md");
15200
15269
  }
15201
15270
  async cleanup(scope, manifest) {
15202
15271
  if (scope === "user") {
15203
- const configPath = join31(homedir13(), ".cline", "data", "settings", "cline_mcp_settings.json");
15272
+ const configPath = join32(homedir14(), ".cline", "data", "settings", "cline_mcp_settings.json");
15204
15273
  removeRunworkMcpServers(configPath, "mcpServers");
15205
15274
  }
15206
15275
  if (scope === "project") {
15207
- const rulesDir = join31(process.cwd(), ".clinerules");
15276
+ const rulesDir = join32(process.cwd(), ".clinerules");
15208
15277
  if (existsSync38(rulesDir)) {
15209
15278
  for (const file of ["runwork.md", "runwork-team.md"]) {
15210
- const filePath = join31(rulesDir, file);
15279
+ const filePath = join32(rulesDir, file);
15211
15280
  if (existsSync38(filePath)) {
15212
15281
  try {
15213
15282
  unlinkSync6(filePath);
@@ -15226,8 +15295,8 @@ class ClineAdapter {
15226
15295
 
15227
15296
  // src/agents/gemini.ts
15228
15297
  import { existsSync as existsSync39, mkdirSync as mkdirSync23, readdirSync as readdirSync13, readFileSync as readFileSync29, statSync as statSync7, writeFileSync as writeFileSync23 } from "fs";
15229
- import { join as join32 } from "path";
15230
- import { homedir as homedir14 } from "os";
15298
+ import { join as join33 } from "path";
15299
+ import { homedir as homedir15 } from "os";
15231
15300
  class GeminiAdapter {
15232
15301
  name = "Gemini CLI";
15233
15302
  slug = "gemini";
@@ -15242,7 +15311,7 @@ class GeminiAdapter {
15242
15311
  return true;
15243
15312
  }
15244
15313
  async writeMcpServers(servers, _scope) {
15245
- const configPath = join32(homedir14(), ".gemini", "settings.json");
15314
+ const configPath = join33(homedir15(), ".gemini", "settings.json");
15246
15315
  const entries = {};
15247
15316
  for (const s of servers) {
15248
15317
  entries[s.name] = {
@@ -15253,27 +15322,27 @@ class GeminiAdapter {
15253
15322
  mergeJsonMcpServers(configPath, entries, "mcpServers");
15254
15323
  }
15255
15324
  async writeSkills(skills, scope) {
15256
- const baseDir = scope === "project" ? join32(process.cwd(), ".gemini", "skills") : join32(homedir14(), ".gemini", "skills");
15325
+ const baseDir = scope === "project" ? join33(process.cwd(), ".gemini", "skills") : join33(homedir15(), ".gemini", "skills");
15257
15326
  for (const skill of skills) {
15258
15327
  if (skill.name !== skill.filename) {
15259
- moveToTrash(join32(baseDir, skill.name), `skill renamed to ${skill.filename}`);
15328
+ moveToTrash(join33(baseDir, skill.name), `skill renamed to ${skill.filename}`);
15260
15329
  }
15261
- const skillDir = join32(baseDir, skill.filename);
15330
+ const skillDir = join33(baseDir, skill.filename);
15262
15331
  mkdirSync23(skillDir, { recursive: true });
15263
- writeFileSync23(join32(skillDir, "SKILL.md"), buildSkillMd2(skill));
15332
+ writeFileSync23(join33(skillDir, "SKILL.md"), buildSkillMd2(skill));
15264
15333
  }
15265
15334
  return skills.length;
15266
15335
  }
15267
15336
  async writeInstructionHint(hint, scope) {
15268
- const filePath = scope === "project" ? join32(process.cwd(), "GEMINI.md") : join32(homedir14(), ".gemini", "GEMINI.md");
15337
+ const filePath = scope === "project" ? join33(process.cwd(), "GEMINI.md") : join33(homedir15(), ".gemini", "GEMINI.md");
15269
15338
  writeHintToFile(filePath, hint);
15270
15339
  }
15271
15340
  async writeTeamInstructions(instructions, scope) {
15272
- const filePath = scope === "project" ? join32(process.cwd(), "GEMINI.md") : join32(homedir14(), ".gemini", "GEMINI.md");
15341
+ const filePath = scope === "project" ? join33(process.cwd(), "GEMINI.md") : join33(homedir15(), ".gemini", "GEMINI.md");
15273
15342
  writeTeamInstructionsToFile(filePath, instructions);
15274
15343
  }
15275
15344
  async writeAgentConfig(config, scope) {
15276
- const settingsPath = scope === "project" ? join32(process.cwd(), ".gemini", "settings.json") : join32(homedir14(), ".gemini", "settings.json");
15345
+ const settingsPath = scope === "project" ? join33(process.cwd(), ".gemini", "settings.json") : join33(homedir15(), ".gemini", "settings.json");
15277
15346
  let settings = {};
15278
15347
  if (existsSync39(settingsPath)) {
15279
15348
  try {
@@ -15295,12 +15364,12 @@ class GeminiAdapter {
15295
15364
  settings.tools = {};
15296
15365
  settings.tools.exclude = config.permissionRules.deny;
15297
15366
  }
15298
- mkdirSync23(join32(settingsPath, ".."), { recursive: true });
15367
+ mkdirSync23(join33(settingsPath, ".."), { recursive: true });
15299
15368
  writeFileSync23(settingsPath, JSON.stringify(settings, null, 2));
15300
15369
  }
15301
15370
  async readUsageStats(lastSyncAt) {
15302
15371
  try {
15303
- const tmpDir = join32(homedir14(), ".gemini", "tmp");
15372
+ const tmpDir = join33(homedir15(), ".gemini", "tmp");
15304
15373
  if (!existsSync39(tmpDir))
15305
15374
  return null;
15306
15375
  const sinceMs = lastSyncAt ? new Date(lastSyncAt).getTime() : 0;
@@ -15317,7 +15386,7 @@ class GeminiAdapter {
15317
15386
  for (const project of projects) {
15318
15387
  if (!project.isDirectory())
15319
15388
  continue;
15320
- const chatsDir = join32(tmpDir, project.name, "chats");
15389
+ const chatsDir = join33(tmpDir, project.name, "chats");
15321
15390
  let files;
15322
15391
  try {
15323
15392
  files = readdirSync13(chatsDir, { withFileTypes: true });
@@ -15327,7 +15396,7 @@ class GeminiAdapter {
15327
15396
  for (const file of files) {
15328
15397
  if (!file.name.startsWith("session-") || !file.name.endsWith(".json"))
15329
15398
  continue;
15330
- const filePath = join32(chatsDir, file.name);
15399
+ const filePath = join33(chatsDir, file.name);
15331
15400
  let stat;
15332
15401
  try {
15333
15402
  stat = statSync7(filePath);
@@ -15379,15 +15448,15 @@ class GeminiAdapter {
15379
15448
  }
15380
15449
  }
15381
15450
  async removeSkills(skillFilenames, scope) {
15382
- const skillsDir = scope === "project" ? join32(process.cwd(), ".gemini", "skills") : join32(homedir14(), ".gemini", "skills");
15451
+ const skillsDir = scope === "project" ? join33(process.cwd(), ".gemini", "skills") : join33(homedir15(), ".gemini", "skills");
15383
15452
  removeMatchingSkillDirs(skillsDir, new Set(skillFilenames));
15384
15453
  }
15385
15454
  async cleanup(scope, manifest) {
15386
15455
  if (scope === "user") {
15387
- removeRunworkMcpServers(join32(homedir14(), ".gemini", "settings.json"), "mcpServers");
15456
+ removeRunworkMcpServers(join33(homedir15(), ".gemini", "settings.json"), "mcpServers");
15388
15457
  }
15389
15458
  await this.removeSkills(manifest?.skillFilenames ?? [], scope);
15390
- const instructionFile = scope === "project" ? join32(process.cwd(), "GEMINI.md") : join32(homedir14(), ".gemini", "GEMINI.md");
15459
+ const instructionFile = scope === "project" ? join33(process.cwd(), "GEMINI.md") : join33(homedir15(), ".gemini", "GEMINI.md");
15391
15460
  removeHintFromFile(instructionFile);
15392
15461
  removeTeamInstructionsFromFile(instructionFile);
15393
15462
  }
@@ -15395,8 +15464,8 @@ class GeminiAdapter {
15395
15464
 
15396
15465
  // src/agents/generic-adapter.ts
15397
15466
  import { existsSync as existsSync40, mkdirSync as mkdirSync24, rmSync as rmSync12, writeFileSync as writeFileSync24 } from "fs";
15398
- import { join as join33 } from "path";
15399
- import { homedir as homedir15 } from "os";
15467
+ import { join as join34 } from "path";
15468
+ import { homedir as homedir16 } from "os";
15400
15469
  class GenericAgentAdapter {
15401
15470
  name;
15402
15471
  slug;
@@ -15421,7 +15490,7 @@ class GenericAgentAdapter {
15421
15490
  async writeMcpServers(servers, _scope) {
15422
15491
  if (!this.def.mcpConfigPath)
15423
15492
  return;
15424
- const filePath = join33(homedir15(), resolvePlatformString(this.def.mcpConfigPath) || "");
15493
+ const filePath = join34(homedir16(), resolvePlatformString(this.def.mcpConfigPath) || "");
15425
15494
  if (!filePath)
15426
15495
  return;
15427
15496
  const entries = {};
@@ -15445,16 +15514,16 @@ class GenericAgentAdapter {
15445
15514
  return 0;
15446
15515
  for (const skill of skills) {
15447
15516
  if (skill.name !== skill.filename) {
15448
- const oldDir = join33(baseDir, skill.name);
15517
+ const oldDir = join34(baseDir, skill.name);
15449
15518
  if (existsSync40(oldDir)) {
15450
15519
  try {
15451
15520
  rmSync12(oldDir, { recursive: true, force: true });
15452
15521
  } catch {}
15453
15522
  }
15454
15523
  }
15455
- const skillDir = join33(baseDir, skill.filename);
15524
+ const skillDir = join34(baseDir, skill.filename);
15456
15525
  mkdirSync24(skillDir, { recursive: true });
15457
- writeFileSync24(join33(skillDir, "SKILL.md"), buildSkillMd2(skill));
15526
+ writeFileSync24(join34(skillDir, "SKILL.md"), buildSkillMd2(skill));
15458
15527
  }
15459
15528
  return skills.length;
15460
15529
  }
@@ -15494,7 +15563,7 @@ class GenericAgentAdapter {
15494
15563
  if (this.def.mcpConfigPath && scope === "user") {
15495
15564
  const resolved = resolvePlatformString(this.def.mcpConfigPath);
15496
15565
  if (resolved) {
15497
- const filePath = join33(homedir15(), resolved);
15566
+ const filePath = join34(homedir16(), resolved);
15498
15567
  removeRunworkMcpServers(filePath, this.def.mcpConfigKey || "mcpServers");
15499
15568
  }
15500
15569
  }
@@ -15576,13 +15645,13 @@ function insightLocalKey(teaches, slug) {
15576
15645
  // src/reflect/insight-store.ts
15577
15646
  init_atomic_json();
15578
15647
  import { existsSync as existsSync41, readFileSync as readFileSync30 } from "fs";
15579
- import { join as join34 } from "path";
15580
- import { homedir as homedir16 } from "os";
15581
- function storePath() {
15582
- return join34(homedir16(), ".runwork", "insights.json");
15648
+ import { join as join35 } from "path";
15649
+ import { homedir as homedir17 } from "os";
15650
+ function storePath2() {
15651
+ return join35(homedir17(), ".runwork", "insights.json");
15583
15652
  }
15584
15653
  function readAll() {
15585
- const path2 = storePath();
15654
+ const path2 = storePath2();
15586
15655
  if (!existsSync41(path2))
15587
15656
  return {};
15588
15657
  try {
@@ -15593,7 +15662,7 @@ function readAll() {
15593
15662
  }
15594
15663
  }
15595
15664
  function writeAll(store) {
15596
- writeJsonAtomic(storePath(), store);
15665
+ writeJsonAtomic(storePath2(), store);
15597
15666
  }
15598
15667
  function notExpired(i, now) {
15599
15668
  const t = new Date(i.expiresAt).getTime();
@@ -15627,15 +15696,15 @@ function getInsight(id, opts = {}) {
15627
15696
  // src/reflect/cadence.ts
15628
15697
  init_atomic_json();
15629
15698
  import { existsSync as existsSync42, readFileSync as readFileSync31 } from "fs";
15630
- import { join as join35 } from "path";
15631
- import { homedir as homedir17 } from "os";
15699
+ import { join as join36 } from "path";
15700
+ import { homedir as homedir18 } from "os";
15632
15701
  var DEFAULT_STATE = { enabled: false, lastReflectedAt: null };
15633
15702
  var COOLDOWN_HOURS = 20;
15634
15703
  var ACTIVE_SESSION_THRESHOLD = 10;
15635
15704
  var MAX_INTERVAL_HOURS = 7 * 24;
15636
15705
  var MIN_SESSIONS_FIRST_RUN = 3;
15637
15706
  function statePath() {
15638
- return join35(homedir17(), ".runwork", "reflect-state.json");
15707
+ return join36(homedir18(), ".runwork", "reflect-state.json");
15639
15708
  }
15640
15709
  function loadCadenceState() {
15641
15710
  try {
@@ -15671,39 +15740,8 @@ function isReflectionDue(state, newSessionCount, now = new Date) {
15671
15740
  return hoursSince >= MAX_INTERVAL_HOURS;
15672
15741
  }
15673
15742
 
15674
- // src/utils/workspace-state.ts
15675
- init_atomic_json();
15676
- import { join as join36 } from "path";
15677
- import { homedir as homedir18 } from "os";
15678
- function storePath2() {
15679
- return join36(homedir18(), ".runwork", "workspaces.json");
15680
- }
15681
- function readFile() {
15682
- const parsed = readJsonOrNull(storePath2());
15683
- if (parsed && parsed.workspaces && typeof parsed.workspaces === "object")
15684
- return parsed;
15685
- return { workspaces: {} };
15686
- }
15687
- function loadWorkspaceRecord(workspaceId) {
15688
- return readFile().workspaces[workspaceId] ?? {};
15689
- }
15690
- function updateWorkspaceRecord(workspaceId, patch) {
15691
- if (!workspaceId)
15692
- return;
15693
- const file = readFile();
15694
- file.workspaces[workspaceId] = { ...file.workspaces[workspaceId], ...patch };
15695
- writeJsonAtomic(storePath2(), file);
15696
- }
15697
- function clearParkedState(workspaceId) {
15698
- const file = readFile();
15699
- const record = file.workspaces[workspaceId];
15700
- if (!record?.parked)
15701
- return;
15702
- delete record.parked;
15703
- writeJsonAtomic(storePath2(), file);
15704
- }
15705
-
15706
15743
  // src/commands/reflect.ts
15744
+ init_workspace_state();
15707
15745
  init_atomic_json();
15708
15746
  init_colors();
15709
15747
  var MAX_NAMES = 40;
@@ -18837,6 +18875,7 @@ function computeSyncPlan(input) {
18837
18875
 
18838
18876
  // src/commands/sync.ts
18839
18877
  init_atomic_json();
18878
+ init_workspace_state();
18840
18879
 
18841
18880
  // src/sync/conflict-ui.ts
18842
18881
  init_prompt();
@@ -19196,9 +19235,31 @@ async function refreshConfiguredAgents(state) {
19196
19235
  state.lastDetectedAt = new Date().toISOString();
19197
19236
  return added;
19198
19237
  }
19238
+ function isNotAMemberError(err) {
19239
+ const message = err instanceof Error ? err.message : String(err);
19240
+ return message.includes("403") && message.includes("not a member of this workspace");
19241
+ }
19242
+ function ensureWorkspacePointer(state, statePath2, credentials) {
19243
+ if (state.workspaceId)
19244
+ return true;
19245
+ if (!credentials.defaultWorkspaceId) {
19246
+ console.error("No workspace selected for this account.");
19247
+ console.error("Run `runwork setup` (or `runwork info`) to choose one.");
19248
+ return false;
19249
+ }
19250
+ state.workspaceId = credentials.defaultWorkspaceId;
19251
+ state.workspaceName = credentials.defaultWorkspaceName || credentials.defaultWorkspaceId;
19252
+ try {
19253
+ writeJsonAtomic(statePath2, state);
19254
+ } catch {}
19255
+ return true;
19256
+ }
19199
19257
  async function syncFromState(state, statePath2, credentials, opts) {
19200
19258
  const client = new ApiClient(credentials);
19201
19259
  setVerbose(!!opts.verbose);
19260
+ if (!ensureWorkspacePointer(state, statePath2, credentials)) {
19261
+ process.exit(1);
19262
+ }
19202
19263
  if (!state.workspaceName || state.workspaceName === state.workspaceId || !state.workspaceSlug) {
19203
19264
  try {
19204
19265
  const workspaces = await client.listWorkspaces();
@@ -19219,14 +19280,28 @@ async function syncFromState(state, statePath2, credentials, opts) {
19219
19280
  }
19220
19281
  }
19221
19282
  console.log(" Fetching workspace data...");
19222
- const [allSkills, mcpServers, externalSkills, registries, connectedIntegrations, resolvedMcpCredentials] = await Promise.all([
19223
- client.listWorkspaceSkills(state.workspaceId, true),
19224
- client.listMcpServers(state.workspaceId),
19225
- client.listExternalSkills(state.workspaceId),
19226
- client.getWorkspaceAll(state.workspaceId).catch(() => null),
19227
- client.listConnectedIntegrations(state.workspaceId).then((list) => list.map((i) => i.canonicalId ?? i.integrationId)).catch(() => []),
19228
- client.resolveMcpCredentials(state.workspaceId).catch(() => ({}))
19229
- ]);
19283
+ let fetched;
19284
+ try {
19285
+ fetched = await Promise.all([
19286
+ client.listWorkspaceSkills(state.workspaceId, true),
19287
+ client.listMcpServers(state.workspaceId),
19288
+ client.listExternalSkills(state.workspaceId),
19289
+ client.getWorkspaceAll(state.workspaceId).catch(() => null),
19290
+ client.listConnectedIntegrations(state.workspaceId).then((list) => list.map((i) => i.canonicalId ?? i.integrationId)).catch(() => []),
19291
+ client.resolveMcpCredentials(state.workspaceId).catch(() => ({}))
19292
+ ]);
19293
+ } catch (err) {
19294
+ if (isNotAMemberError(err)) {
19295
+ forgetWorkspaceSelection();
19296
+ console.error(`
19297
+ This account is not a member of "${state.workspaceName || state.workspaceId}".`);
19298
+ console.error("That workspace belonged to a previous sign in, so it has been forgotten.");
19299
+ console.error("Run `runwork setup` (or `runwork info`) to choose a workspace for this account.");
19300
+ process.exit(1);
19301
+ }
19302
+ throw err;
19303
+ }
19304
+ const [allSkills, mcpServers, externalSkills, registries, connectedIntegrations, resolvedMcpCredentials] = fetched;
19230
19305
  const appCount = allSkills.filter((s) => s.type === "app").length;
19231
19306
  const parts = [];
19232
19307
  if (appCount > 0)
@@ -19766,6 +19841,7 @@ Sync complete.`);
19766
19841
  });
19767
19842
 
19768
19843
  // src/commands/setup.ts
19844
+ init_workspace_state();
19769
19845
  var PERSONA_LABELS = {
19770
19846
  1: "everyday",
19771
19847
  2: "curious",