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.
- package/dist/index.js +436 -360
- 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
|
|
1202
|
-
const
|
|
1203
|
-
|
|
1204
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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(
|
|
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 =
|
|
1778
|
+
const manifestDir = join5(dir, ".runwork");
|
|
1712
1779
|
if (!existsSync6(manifestDir)) {
|
|
1713
1780
|
mkdirSync2(manifestDir, { recursive: true });
|
|
1714
1781
|
}
|
|
1715
|
-
writeFileSync2(
|
|
1782
|
+
writeFileSync2(join5(manifestDir, "template-manifest.json"), JSON.stringify(manifest, null, 2));
|
|
1716
1783
|
}
|
|
1717
1784
|
async function loadManifest(dir) {
|
|
1718
|
-
const manifestPath =
|
|
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(
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
1924
|
+
import { homedir as homedir4 } from "os";
|
|
1858
1925
|
function prettyPath(dir) {
|
|
1859
|
-
const home =
|
|
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
|
|
2130
|
-
import { homedir as
|
|
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 =
|
|
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(
|
|
2166
|
-
if (!existsSync7(
|
|
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(
|
|
2185
|
-
writeFileSync4(
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
7573
|
+
import { join as join15 } from "path";
|
|
7507
7574
|
async function populateTypes(projectDir) {
|
|
7508
|
-
const typesDir =
|
|
7575
|
+
const typesDir = join15(projectDir, TYPES_DIR);
|
|
7509
7576
|
mkdirSync9(typesDir, { recursive: true });
|
|
7510
|
-
const frameworkDist =
|
|
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(
|
|
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(
|
|
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.
|
|
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
|
|
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(
|
|
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
|
|
8752
|
+
import { dirname as dirname4, join as join17 } from "path";
|
|
8686
8753
|
function deployStatePath(cwd) {
|
|
8687
|
-
return
|
|
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
|
|
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
|
|
8821
|
+
return join18(cwd, ".runwork", "deploy-status.json");
|
|
8755
8822
|
}
|
|
8756
8823
|
function deployLogPath(cwd) {
|
|
8757
|
-
return
|
|
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
|
|
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 =
|
|
8872
|
+
const dir = join19(cwd, ".runwork");
|
|
8806
8873
|
fs5.mkdirSync(dir, { recursive: true });
|
|
8807
|
-
const stdoutFd = fs5.openSync(
|
|
8808
|
-
const stderrFd = fs5.openSync(
|
|
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
|
|
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(
|
|
9498
|
-
const scriptPath =
|
|
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
|
|
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 =
|
|
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
|
|
11204
|
-
import { homedir as
|
|
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
|
|
11553
|
-
import { homedir as
|
|
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
|
|
11625
|
+
return join22(homedir6(), ".runwork", "trash");
|
|
11557
11626
|
}
|
|
11558
11627
|
function batchDir(now) {
|
|
11559
11628
|
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
11560
|
-
return
|
|
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 =
|
|
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 =
|
|
11586
|
-
const dest =
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
12213
|
+
const pluginMcpPath = join24(pluginDir, ".mcp.json");
|
|
12145
12214
|
const marketDir = this.getMarketplaceDir();
|
|
12146
12215
|
mkdirSync16(marketDir, { recursive: true });
|
|
12147
|
-
const marketplaceMcpPath =
|
|
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 =
|
|
12231
|
+
const hooksDir = join24(pluginDir, "hooks");
|
|
12163
12232
|
mkdirSync16(hooksDir, { recursive: true });
|
|
12164
|
-
const scriptPath =
|
|
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(
|
|
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" ?
|
|
12242
|
+
const baseDir = scope === "project" ? join24(process.cwd(), ".claude", "skills") : join24(homedir7(), ".claude", "skills");
|
|
12174
12243
|
for (const skill of skills) {
|
|
12175
|
-
const skillDir =
|
|
12244
|
+
const skillDir = join24(baseDir, skill.filename);
|
|
12176
12245
|
cleanupOldSkillDir(baseDir, skill);
|
|
12177
12246
|
mkdirSync16(skillDir, { recursive: true });
|
|
12178
|
-
writeFileSync16(
|
|
12247
|
+
writeFileSync16(join24(skillDir, "SKILL.md"), buildSkillMd2(skill));
|
|
12179
12248
|
}
|
|
12180
12249
|
if (scope === "user") {
|
|
12181
12250
|
const pluginDir = this.getPluginDir();
|
|
12182
|
-
const pluginJsonDir =
|
|
12251
|
+
const pluginJsonDir = join24(pluginDir, ".claude-plugin");
|
|
12183
12252
|
mkdirSync16(pluginJsonDir, { recursive: true });
|
|
12184
|
-
writeFileSync16(
|
|
12253
|
+
writeFileSync16(join24(pluginJsonDir, "plugin.json"), JSON.stringify(getPluginJson(), null, 2));
|
|
12185
12254
|
for (const skill of skills) {
|
|
12186
|
-
const skillDir =
|
|
12187
|
-
cleanupOldSkillDir(
|
|
12255
|
+
const skillDir = join24(pluginDir, "skills", skill.filename);
|
|
12256
|
+
cleanupOldSkillDir(join24(pluginDir, "skills"), skill);
|
|
12188
12257
|
mkdirSync16(skillDir, { recursive: true });
|
|
12189
|
-
writeFileSync16(
|
|
12258
|
+
writeFileSync16(join24(skillDir, "SKILL.md"), buildSkillMd2(skill));
|
|
12190
12259
|
}
|
|
12191
12260
|
const marketDir = this.getMarketplaceDir();
|
|
12192
|
-
const marketPluginJsonDir =
|
|
12261
|
+
const marketPluginJsonDir = join24(marketDir, ".claude-plugin");
|
|
12193
12262
|
mkdirSync16(marketPluginJsonDir, { recursive: true });
|
|
12194
|
-
writeFileSync16(
|
|
12263
|
+
writeFileSync16(join24(marketPluginJsonDir, "plugin.json"), JSON.stringify(getPluginJson(), null, 2));
|
|
12195
12264
|
for (const skill of skills) {
|
|
12196
|
-
const skillDir =
|
|
12197
|
-
cleanupOldSkillDir(
|
|
12265
|
+
const skillDir = join24(marketDir, "skills", skill.filename);
|
|
12266
|
+
cleanupOldSkillDir(join24(marketDir, "skills"), skill);
|
|
12198
12267
|
mkdirSync16(skillDir, { recursive: true });
|
|
12199
|
-
writeFileSync16(
|
|
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" ?
|
|
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" ?
|
|
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
|
-
|
|
12235
|
-
|
|
12303
|
+
join24(pluginDir, "skills", "runwork-team-instructions"),
|
|
12304
|
+
join24(marketDir, "skills", "runwork-team-instructions")
|
|
12236
12305
|
]) {
|
|
12237
12306
|
mkdirSync16(dir, { recursive: true });
|
|
12238
|
-
writeFileSync16(
|
|
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" ?
|
|
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(
|
|
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" ? [
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
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(
|
|
12367
|
+
removeRunworkMcpServers(join24(process.cwd(), ".mcp.json"), "mcpServers");
|
|
12299
12368
|
} else {
|
|
12300
|
-
removeRunworkMcpServers(
|
|
12369
|
+
removeRunworkMcpServers(join24(homedir7(), ".claude", "settings.json"), "mcpServers");
|
|
12301
12370
|
}
|
|
12302
12371
|
await this.removeSkills(manifest?.skillFilenames ?? [], scope);
|
|
12303
|
-
const instructionFile = scope === "project" ?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
12433
|
+
const claudeDir = join24(homedir7(), ".claude");
|
|
12365
12434
|
if (!existsSync30(claudeDir))
|
|
12366
12435
|
return null;
|
|
12367
|
-
const projectsDir =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
12745
|
+
return join24(homedir7(), ".claude", "plugins");
|
|
12677
12746
|
}
|
|
12678
12747
|
getPluginDir() {
|
|
12679
|
-
return
|
|
12748
|
+
return join24(this.getPluginsBaseDir(), "cache", "runwork", PLUGIN_NAME, PLUGIN_VERSION);
|
|
12680
12749
|
}
|
|
12681
12750
|
getMarketplaceRoot() {
|
|
12682
|
-
return
|
|
12751
|
+
return join24(this.getPluginsBaseDir(), "marketplaces", "runwork");
|
|
12683
12752
|
}
|
|
12684
12753
|
getMarketplaceDir() {
|
|
12685
|
-
return
|
|
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 =
|
|
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 =
|
|
12776
|
+
const marketCatalogDir = join24(marketRoot, ".claude-plugin");
|
|
12708
12777
|
mkdirSync16(marketCatalogDir, { recursive: true });
|
|
12709
|
-
writeFileSync16(
|
|
12710
|
-
const marketplacesPath =
|
|
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 =
|
|
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 =
|
|
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
|
|
12741
|
-
import { homedir as
|
|
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
|
|
12815
|
+
import { join as join25 } from "path";
|
|
12747
12816
|
function writePluginMetadata(destDir, metadata) {
|
|
12748
|
-
const pluginJsonDir =
|
|
12817
|
+
const pluginJsonDir = join25(destDir, ".claude-plugin");
|
|
12749
12818
|
mkdirSync17(pluginJsonDir, { recursive: true });
|
|
12750
|
-
writeFileSync17(
|
|
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(
|
|
12846
|
+
writeFileSync17(join25(destDir, ".mcp.json"), JSON.stringify({ mcpServers: mcpEntries }, null, 2));
|
|
12778
12847
|
}
|
|
12779
12848
|
function writePluginTeamInstructions(destDir, instructions) {
|
|
12780
|
-
const skillDir =
|
|
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(
|
|
12857
|
+
writeFileSync17(join25(skillDir, "SKILL.md"), skillContent);
|
|
12789
12858
|
}
|
|
12790
12859
|
function writePluginSkills(destDir, skills) {
|
|
12791
|
-
const skillsRoot =
|
|
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 =
|
|
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 =
|
|
12871
|
+
const skillDir = join25(skillsRoot, skill.filename);
|
|
12803
12872
|
mkdirSync17(skillDir, { recursive: true });
|
|
12804
|
-
writeFileSync17(
|
|
12873
|
+
writeFileSync17(join25(skillDir, "SKILL.md"), buildSkillMd2(skill));
|
|
12805
12874
|
}
|
|
12806
12875
|
}
|
|
12807
12876
|
function writePluginSessionStartHook(destDir) {
|
|
12808
|
-
const hooksDir =
|
|
12877
|
+
const hooksDir = join25(destDir, "hooks");
|
|
12809
12878
|
mkdirSync17(hooksDir, { recursive: true });
|
|
12810
|
-
const scriptPath =
|
|
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(
|
|
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
|
|
12919
|
+
return join26(homedir8(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
12851
12920
|
}
|
|
12852
12921
|
if (os2 === "win32") {
|
|
12853
|
-
return
|
|
12922
|
+
return join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
12854
12923
|
}
|
|
12855
|
-
return
|
|
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
|
|
12929
|
+
return join26(homedir8(), "Library", "Application Support", "Claude", "local-agent-mode-sessions");
|
|
12861
12930
|
}
|
|
12862
12931
|
if (os2 === "win32") {
|
|
12863
|
-
return
|
|
12932
|
+
return join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude", "local-agent-mode-sessions");
|
|
12864
12933
|
}
|
|
12865
|
-
return
|
|
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 =
|
|
12944
|
+
const sessionPath = join26(baseDir, sessionId);
|
|
12876
12945
|
try {
|
|
12877
12946
|
for (const orgId of readdirSync8(sessionPath).filter((d) => !d.startsWith("."))) {
|
|
12878
|
-
dirs.push(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
12936
|
-
return existsSync32(
|
|
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 =
|
|
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:
|
|
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
|
|
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 =
|
|
13021
|
-
const marketDir =
|
|
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 =
|
|
13040
|
-
const marketRoot =
|
|
13041
|
-
const marketDir =
|
|
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 =
|
|
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 =
|
|
13129
|
+
const marketCatalogDir = join26(marketRoot, ".claude-plugin");
|
|
13061
13130
|
mkdirSync18(marketCatalogDir, { recursive: true });
|
|
13062
|
-
writeFileSync18(
|
|
13063
|
-
const marketplacesPath =
|
|
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(
|
|
13083
|
-
const pluginStagingDir =
|
|
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(
|
|
13115
|
-
writePluginTeamInstructions(
|
|
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 =
|
|
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(
|
|
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 =
|
|
13179
|
-
if (!existsSync32(
|
|
13247
|
+
const pluginsDir = join26(orgDir, "cowork_plugins");
|
|
13248
|
+
if (!existsSync32(join26(pluginsDir, "installed_plugins.json")))
|
|
13180
13249
|
continue;
|
|
13181
|
-
const cacheRunwork =
|
|
13182
|
-
const marketRunwork =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
13301
|
+
claudeAppDir = join26(homedir8(), "Library", "Application Support", "Claude");
|
|
13233
13302
|
} else if (os2 === "win32") {
|
|
13234
|
-
claudeAppDir =
|
|
13303
|
+
claudeAppDir = join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude");
|
|
13235
13304
|
} else {
|
|
13236
|
-
claudeAppDir =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
13388
|
+
claudeAppDir = join26(homedir8(), "Library", "Application Support", "Claude");
|
|
13320
13389
|
} else if (os2 === "win32") {
|
|
13321
|
-
claudeAppDir =
|
|
13390
|
+
claudeAppDir = join26(process.env.APPDATA || join26(homedir8(), "AppData", "Roaming"), "Claude");
|
|
13322
13391
|
} else {
|
|
13323
|
-
claudeAppDir =
|
|
13392
|
+
claudeAppDir = join26(homedir8(), ".config", "Claude");
|
|
13324
13393
|
}
|
|
13325
|
-
const versionPath =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
13376
|
-
import { homedir as
|
|
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" ?
|
|
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 =
|
|
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(
|
|
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" ?
|
|
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(
|
|
13582
|
+
mkdirSync19(join27(filePath, ".."), { recursive: true });
|
|
13514
13583
|
writeFileSync19(filePath, mdcContent);
|
|
13515
13584
|
}
|
|
13516
13585
|
async writeTeamInstructions(instructions, scope) {
|
|
13517
|
-
const filePath = scope === "project" ?
|
|
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(
|
|
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 =
|
|
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(
|
|
13657
|
+
removeMatchingSkillFiles(join27(process.cwd(), ".cursor", "rules"), new Set(skillFilenames), ".mdc");
|
|
13589
13658
|
}
|
|
13590
13659
|
async cleanup(scope, manifest) {
|
|
13591
|
-
const mcpPath = scope === "project" ?
|
|
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" ?
|
|
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 =
|
|
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 =
|
|
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
|
|
13793
|
+
return join27(homedir9(), "Library", "Application Support", "Cursor", "User", "globalStorage", "state.vscdb");
|
|
13725
13794
|
}
|
|
13726
13795
|
if (os2 === "win32") {
|
|
13727
|
-
return
|
|
13796
|
+
return join27(process.env.APPDATA || join27(homedir9(), "AppData", "Roaming"), "Cursor", "User", "globalStorage", "state.vscdb");
|
|
13728
13797
|
}
|
|
13729
|
-
return
|
|
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
|
|
13750
|
-
import { homedir as
|
|
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
|
|
13822
|
+
return join28(process.env.APPDATA || join28(homedir10(), "AppData", "Roaming"), "Codeium", "windsurf");
|
|
13754
13823
|
}
|
|
13755
|
-
return
|
|
13824
|
+
return join28(homedir10(), ".codeium", "windsurf");
|
|
13756
13825
|
}
|
|
13757
13826
|
function getConfigPath() {
|
|
13758
|
-
return
|
|
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 =
|
|
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(
|
|
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" ?
|
|
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(
|
|
13879
|
+
mkdirSync20(join28(filePath, ".."), { recursive: true });
|
|
13811
13880
|
writeFileSync20(filePath, content);
|
|
13812
13881
|
}
|
|
13813
13882
|
async writeInstructionHint(hint, scope) {
|
|
13814
|
-
const filePath = scope === "project" ?
|
|
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(
|
|
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(
|
|
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" ?
|
|
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 =
|
|
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
|
|
13850
|
-
import { homedir as
|
|
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
|
|
13857
|
-
import { isAbsolute as isAbsolute2, join as
|
|
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
|
|
13862
|
-
import { isAbsolute, join as
|
|
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" ?
|
|
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 :
|
|
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 :
|
|
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 =
|
|
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(
|
|
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() :
|
|
14634
|
-
const baseDir =
|
|
14635
|
-
const legacyBaseDir =
|
|
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 [
|
|
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(
|
|
14643
|
-
const skillDir =
|
|
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(
|
|
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" ?
|
|
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" ?
|
|
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" ?
|
|
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(
|
|
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() :
|
|
14712
|
-
for (const skillsDir of [
|
|
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 =
|
|
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" ?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
15116
|
-
import { homedir as
|
|
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 =
|
|
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 =
|
|
15213
|
+
const rulesDir = join32(process.cwd(), ".clinerules");
|
|
15145
15214
|
mkdirSync22(rulesDir, { recursive: true });
|
|
15146
15215
|
for (const skill of skills) {
|
|
15147
|
-
writeFileSync22(
|
|
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 =
|
|
15155
|
-
mkdirSync22(
|
|
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 =
|
|
15162
|
-
mkdirSync22(
|
|
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 =
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
15230
|
-
import { homedir as
|
|
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 =
|
|
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" ?
|
|
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(
|
|
15328
|
+
moveToTrash(join33(baseDir, skill.name), `skill renamed to ${skill.filename}`);
|
|
15260
15329
|
}
|
|
15261
|
-
const skillDir =
|
|
15330
|
+
const skillDir = join33(baseDir, skill.filename);
|
|
15262
15331
|
mkdirSync23(skillDir, { recursive: true });
|
|
15263
|
-
writeFileSync23(
|
|
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" ?
|
|
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" ?
|
|
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" ?
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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" ?
|
|
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(
|
|
15456
|
+
removeRunworkMcpServers(join33(homedir15(), ".gemini", "settings.json"), "mcpServers");
|
|
15388
15457
|
}
|
|
15389
15458
|
await this.removeSkills(manifest?.skillFilenames ?? [], scope);
|
|
15390
|
-
const instructionFile = scope === "project" ?
|
|
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
|
|
15399
|
-
import { homedir as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
15524
|
+
const skillDir = join34(baseDir, skill.filename);
|
|
15456
15525
|
mkdirSync24(skillDir, { recursive: true });
|
|
15457
|
-
writeFileSync24(
|
|
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 =
|
|
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
|
|
15580
|
-
import { homedir as
|
|
15581
|
-
function
|
|
15582
|
-
return
|
|
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 =
|
|
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(
|
|
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
|
|
15631
|
-
import { homedir as
|
|
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
|
|
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
|
-
|
|
19223
|
-
|
|
19224
|
-
|
|
19225
|
-
|
|
19226
|
-
|
|
19227
|
-
|
|
19228
|
-
|
|
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",
|