@knowsuchagency/fulcrum 1.12.1 → 1.13.0
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/bin/fulcrum.js +265 -6
- package/dist/assets/index-BKrFmyy5.css +1 -0
- package/dist/assets/{index-DHyzdclR.js → index-BiZAwxx6.js} +111 -111
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/index.js +218 -36
- package/dist/assets/index-FDfXVJC8.css +0 -1
package/bin/fulcrum.js
CHANGED
|
@@ -935,10 +935,12 @@ var init_errors = __esm(() => {
|
|
|
935
935
|
ExitCodes = {
|
|
936
936
|
SUCCESS: 0,
|
|
937
937
|
ERROR: 1,
|
|
938
|
+
GENERAL_ERROR: 1,
|
|
938
939
|
INVALID_ARGS: 2,
|
|
939
940
|
SERVER_UNREACHABLE: 3,
|
|
940
941
|
NOT_FOUND: 4,
|
|
941
|
-
VALIDATION_ERROR: 5
|
|
942
|
+
VALIDATION_ERROR: 5,
|
|
943
|
+
NETWORK_ERROR: 6
|
|
942
944
|
};
|
|
943
945
|
CliError = class CliError extends Error {
|
|
944
946
|
code;
|
|
@@ -47082,7 +47084,7 @@ var marketplace_default = `{
|
|
|
47082
47084
|
"name": "fulcrum",
|
|
47083
47085
|
"source": "./",
|
|
47084
47086
|
"description": "Task orchestration for Claude Code",
|
|
47085
|
-
"version": "1.
|
|
47087
|
+
"version": "1.13.0",
|
|
47086
47088
|
"skills": [
|
|
47087
47089
|
"./skills/fulcrum"
|
|
47088
47090
|
],
|
|
@@ -47908,7 +47910,7 @@ var notifyCommand = defineCommand({
|
|
|
47908
47910
|
});
|
|
47909
47911
|
|
|
47910
47912
|
// cli/src/commands/up.ts
|
|
47911
|
-
import { spawn } from "child_process";
|
|
47913
|
+
import { spawn as spawn2 } from "child_process";
|
|
47912
47914
|
import { existsSync as existsSync5 } from "fs";
|
|
47913
47915
|
import { dirname as dirname3, join as join5 } from "path";
|
|
47914
47916
|
import { fileURLToPath } from "url";
|
|
@@ -48191,11 +48193,86 @@ function installUv() {
|
|
|
48191
48193
|
return false;
|
|
48192
48194
|
return installDependency(dep);
|
|
48193
48195
|
}
|
|
48196
|
+
|
|
48197
|
+
// cli/src/commands/update.ts
|
|
48198
|
+
import { spawn, spawnSync as spawnSync3 } from "child_process";
|
|
48199
|
+
init_errors();
|
|
48200
|
+
|
|
48201
|
+
// shared/semver.ts
|
|
48202
|
+
function parseSemver(version) {
|
|
48203
|
+
const cleaned = version.trim().replace(/^v/, "");
|
|
48204
|
+
if (cleaned.length === 0)
|
|
48205
|
+
return null;
|
|
48206
|
+
const [mainAndPre] = cleaned.split("+", 1);
|
|
48207
|
+
const [main, preReleaseRaw] = mainAndPre.split("-", 2);
|
|
48208
|
+
const parts = main.split(".");
|
|
48209
|
+
if (parts.length > 3 || parts.length === 0)
|
|
48210
|
+
return null;
|
|
48211
|
+
if (parts.some((part) => part.length > 1 && part.startsWith("0")))
|
|
48212
|
+
return null;
|
|
48213
|
+
const major = Number(parts[0]);
|
|
48214
|
+
const minor = Number(parts[1] ?? "0");
|
|
48215
|
+
const patch = Number(parts[2] ?? "0");
|
|
48216
|
+
if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(patch))
|
|
48217
|
+
return null;
|
|
48218
|
+
if (major < 0 || minor < 0 || patch < 0)
|
|
48219
|
+
return null;
|
|
48220
|
+
if (preReleaseRaw) {
|
|
48221
|
+
const preReleaseParts = preReleaseRaw.split(".");
|
|
48222
|
+
if (preReleaseParts.some((part) => /^\d+$/.test(part) && part.length > 1 && part.startsWith("0"))) {
|
|
48223
|
+
return null;
|
|
48224
|
+
}
|
|
48225
|
+
}
|
|
48226
|
+
const preRelease = preReleaseRaw ? preReleaseRaw.split(".").map((part) => /^\d+$/.test(part) ? Number(part) : part) : [];
|
|
48227
|
+
return { major, minor, patch, preRelease };
|
|
48228
|
+
}
|
|
48229
|
+
function compareIdentifiers(a2, b2) {
|
|
48230
|
+
if (typeof a2 === "number" && typeof b2 === "number")
|
|
48231
|
+
return a2 - b2;
|
|
48232
|
+
if (typeof a2 === "number")
|
|
48233
|
+
return -1;
|
|
48234
|
+
if (typeof b2 === "number")
|
|
48235
|
+
return 1;
|
|
48236
|
+
return a2.localeCompare(b2);
|
|
48237
|
+
}
|
|
48238
|
+
function compareVersions(v1, v2) {
|
|
48239
|
+
const parsed1 = parseSemver(v1);
|
|
48240
|
+
const parsed2 = parseSemver(v2);
|
|
48241
|
+
if (!parsed1 || !parsed2)
|
|
48242
|
+
return 0;
|
|
48243
|
+
if (parsed1.major !== parsed2.major)
|
|
48244
|
+
return parsed1.major - parsed2.major;
|
|
48245
|
+
if (parsed1.minor !== parsed2.minor)
|
|
48246
|
+
return parsed1.minor - parsed2.minor;
|
|
48247
|
+
if (parsed1.patch !== parsed2.patch)
|
|
48248
|
+
return parsed1.patch - parsed2.patch;
|
|
48249
|
+
const pre1 = parsed1.preRelease;
|
|
48250
|
+
const pre2 = parsed2.preRelease;
|
|
48251
|
+
if (pre1.length === 0 && pre2.length === 0)
|
|
48252
|
+
return 0;
|
|
48253
|
+
if (pre1.length === 0)
|
|
48254
|
+
return 1;
|
|
48255
|
+
if (pre2.length === 0)
|
|
48256
|
+
return -1;
|
|
48257
|
+
const maxLen = Math.max(pre1.length, pre2.length);
|
|
48258
|
+
for (let i2 = 0;i2 < maxLen; i2++) {
|
|
48259
|
+
const id1 = pre1[i2];
|
|
48260
|
+
const id2 = pre2[i2];
|
|
48261
|
+
if (id1 === undefined)
|
|
48262
|
+
return -1;
|
|
48263
|
+
if (id2 === undefined)
|
|
48264
|
+
return 1;
|
|
48265
|
+
const diff = compareIdentifiers(id1, id2);
|
|
48266
|
+
if (diff !== 0)
|
|
48267
|
+
return diff;
|
|
48268
|
+
}
|
|
48269
|
+
return 0;
|
|
48270
|
+
}
|
|
48194
48271
|
// package.json
|
|
48195
48272
|
var package_default = {
|
|
48196
48273
|
name: "@knowsuchagency/fulcrum",
|
|
48197
48274
|
private: true,
|
|
48198
|
-
version: "1.
|
|
48275
|
+
version: "1.13.0",
|
|
48199
48276
|
description: "Harness Attention. Orchestrate Agents. Ship.",
|
|
48200
48277
|
license: "PolyForm-Perimeter-1.0.0",
|
|
48201
48278
|
type: "module",
|
|
@@ -48286,6 +48363,168 @@ var package_default = {
|
|
|
48286
48363
|
}
|
|
48287
48364
|
};
|
|
48288
48365
|
|
|
48366
|
+
// cli/src/commands/update.ts
|
|
48367
|
+
var GITHUB_REPO = "knowsuchagency/fulcrum";
|
|
48368
|
+
var NPM_PACKAGE = "@knowsuchagency/fulcrum";
|
|
48369
|
+
async function fetchLatestVersionFromNpm() {
|
|
48370
|
+
try {
|
|
48371
|
+
const response = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE}/latest`, {
|
|
48372
|
+
headers: { Accept: "application/json" }
|
|
48373
|
+
});
|
|
48374
|
+
if (!response.ok)
|
|
48375
|
+
return null;
|
|
48376
|
+
const data = await response.json();
|
|
48377
|
+
return data.version || null;
|
|
48378
|
+
} catch {
|
|
48379
|
+
return null;
|
|
48380
|
+
}
|
|
48381
|
+
}
|
|
48382
|
+
async function checkForUpdates() {
|
|
48383
|
+
const currentVersion = package_default.version;
|
|
48384
|
+
const latestVersion = await fetchLatestVersionFromNpm();
|
|
48385
|
+
let updateAvailable = false;
|
|
48386
|
+
if (latestVersion) {
|
|
48387
|
+
updateAvailable = compareVersions(latestVersion, currentVersion) > 0;
|
|
48388
|
+
}
|
|
48389
|
+
return { currentVersion, latestVersion, updateAvailable };
|
|
48390
|
+
}
|
|
48391
|
+
function isBunAvailable() {
|
|
48392
|
+
try {
|
|
48393
|
+
const result = spawnSync3("bun", ["--version"], { stdio: "pipe" });
|
|
48394
|
+
return result.status === 0;
|
|
48395
|
+
} catch {
|
|
48396
|
+
return false;
|
|
48397
|
+
}
|
|
48398
|
+
}
|
|
48399
|
+
function getPackageRunner() {
|
|
48400
|
+
if (isBunAvailable()) {
|
|
48401
|
+
return { command: "bunx", execCommand: "bunx" };
|
|
48402
|
+
}
|
|
48403
|
+
return { command: "npx", execCommand: "npx" };
|
|
48404
|
+
}
|
|
48405
|
+
function stopServer() {
|
|
48406
|
+
const { execCommand } = getPackageRunner();
|
|
48407
|
+
console.log("Stopping current server...");
|
|
48408
|
+
const result = spawnSync3(execCommand, [`${NPM_PACKAGE}@latest`, "down"], {
|
|
48409
|
+
stdio: "inherit",
|
|
48410
|
+
shell: true
|
|
48411
|
+
});
|
|
48412
|
+
if (result.status === 0) {
|
|
48413
|
+
console.log("Server stopped.");
|
|
48414
|
+
} else {
|
|
48415
|
+
console.log("Server was not running (or already stopped).");
|
|
48416
|
+
}
|
|
48417
|
+
}
|
|
48418
|
+
function installLatestVersion() {
|
|
48419
|
+
const { execCommand, command } = getPackageRunner();
|
|
48420
|
+
console.log(`
|
|
48421
|
+
Installing latest version via ${command}...`);
|
|
48422
|
+
const args = command === "bunx" ? ["--bun", `${NPM_PACKAGE}@latest`, "--version"] : ["--yes", "--ignore-scripts", `${NPM_PACKAGE}@latest`, "--version"];
|
|
48423
|
+
const result = spawnSync3(execCommand, args, {
|
|
48424
|
+
stdio: "inherit",
|
|
48425
|
+
shell: true
|
|
48426
|
+
});
|
|
48427
|
+
if (result.status === 0) {
|
|
48428
|
+
console.log("Latest version installed.");
|
|
48429
|
+
return true;
|
|
48430
|
+
}
|
|
48431
|
+
console.error("Failed to install latest version.");
|
|
48432
|
+
return false;
|
|
48433
|
+
}
|
|
48434
|
+
function startServer() {
|
|
48435
|
+
return new Promise((resolve) => {
|
|
48436
|
+
const { command, execCommand } = getPackageRunner();
|
|
48437
|
+
const args = [`${NPM_PACKAGE}@latest`, "up"];
|
|
48438
|
+
console.log(`
|
|
48439
|
+
Starting server: ${command} ${args.join(" ")}
|
|
48440
|
+
`);
|
|
48441
|
+
const child = spawn(execCommand, args, {
|
|
48442
|
+
stdio: "inherit",
|
|
48443
|
+
shell: true
|
|
48444
|
+
});
|
|
48445
|
+
child.on("close", (code) => {
|
|
48446
|
+
resolve(code ?? 0);
|
|
48447
|
+
});
|
|
48448
|
+
child.on("error", (err) => {
|
|
48449
|
+
console.error("Failed to start server:", err.message);
|
|
48450
|
+
resolve(1);
|
|
48451
|
+
});
|
|
48452
|
+
});
|
|
48453
|
+
}
|
|
48454
|
+
async function runUpdate() {
|
|
48455
|
+
stopServer();
|
|
48456
|
+
const installed = installLatestVersion();
|
|
48457
|
+
if (!installed) {
|
|
48458
|
+
console.error(`
|
|
48459
|
+
Update failed during installation. Your previous version may still work.`);
|
|
48460
|
+
console.log("Try running: fulcrum up");
|
|
48461
|
+
return 1;
|
|
48462
|
+
}
|
|
48463
|
+
console.log(`
|
|
48464
|
+
Starting updated server...`);
|
|
48465
|
+
return await startServer();
|
|
48466
|
+
}
|
|
48467
|
+
async function handleUpdateCommand(flags) {
|
|
48468
|
+
const checkOnly = flags.check === "true";
|
|
48469
|
+
const { command } = getPackageRunner();
|
|
48470
|
+
if (isJsonOutput()) {
|
|
48471
|
+
const result = await checkForUpdates();
|
|
48472
|
+
output({
|
|
48473
|
+
...result,
|
|
48474
|
+
updateCommand: "fulcrum update",
|
|
48475
|
+
releaseUrl: `https://github.com/${GITHUB_REPO}/releases/latest`
|
|
48476
|
+
});
|
|
48477
|
+
return;
|
|
48478
|
+
}
|
|
48479
|
+
console.log("Checking for updates...");
|
|
48480
|
+
const { currentVersion, latestVersion, updateAvailable } = await checkForUpdates();
|
|
48481
|
+
if (!latestVersion) {
|
|
48482
|
+
throw new CliError("NETWORK_ERROR", "Could not check for updates. Please check your internet connection.", ExitCodes.NETWORK_ERROR);
|
|
48483
|
+
}
|
|
48484
|
+
console.log(`Current version: ${currentVersion}`);
|
|
48485
|
+
console.log(`Latest version: ${latestVersion}`);
|
|
48486
|
+
if (!updateAvailable) {
|
|
48487
|
+
console.log(`
|
|
48488
|
+
\u2713 You are running the latest version.`);
|
|
48489
|
+
return;
|
|
48490
|
+
}
|
|
48491
|
+
console.log(`
|
|
48492
|
+
\u2191 Update available: ${currentVersion} \u2192 ${latestVersion}`);
|
|
48493
|
+
if (checkOnly) {
|
|
48494
|
+
console.log(`
|
|
48495
|
+
To update, run: fulcrum update`);
|
|
48496
|
+
console.log(`Or manually: ${command} ${NPM_PACKAGE}@latest up`);
|
|
48497
|
+
return;
|
|
48498
|
+
}
|
|
48499
|
+
console.log(`
|
|
48500
|
+
Updating Fulcrum...`);
|
|
48501
|
+
console.log(`This will stop the current server, install the update, and restart.
|
|
48502
|
+
`);
|
|
48503
|
+
const exitCode = await runUpdate();
|
|
48504
|
+
if (exitCode !== 0) {
|
|
48505
|
+
throw new CliError("GENERAL_ERROR", "Update failed", ExitCodes.GENERAL_ERROR);
|
|
48506
|
+
}
|
|
48507
|
+
console.log(`
|
|
48508
|
+
\u2713 Fulcrum has been updated and restarted.`);
|
|
48509
|
+
}
|
|
48510
|
+
var updateCommand = defineCommand({
|
|
48511
|
+
meta: {
|
|
48512
|
+
name: "update",
|
|
48513
|
+
description: "Check for updates and update Fulcrum to the latest version"
|
|
48514
|
+
},
|
|
48515
|
+
args: {
|
|
48516
|
+
...globalArgs,
|
|
48517
|
+
check: {
|
|
48518
|
+
type: "boolean",
|
|
48519
|
+
description: "Only check for updates, do not install"
|
|
48520
|
+
}
|
|
48521
|
+
},
|
|
48522
|
+
async run({ args }) {
|
|
48523
|
+
setupJsonOutput(args);
|
|
48524
|
+
await handleUpdateCommand(toFlags(args));
|
|
48525
|
+
}
|
|
48526
|
+
});
|
|
48527
|
+
|
|
48289
48528
|
// cli/src/commands/up.ts
|
|
48290
48529
|
function getPackageRoot() {
|
|
48291
48530
|
const currentFile = fileURLToPath(import.meta.url);
|
|
@@ -48300,6 +48539,24 @@ function getPackageRoot() {
|
|
|
48300
48539
|
}
|
|
48301
48540
|
async function handleUpCommand(flags) {
|
|
48302
48541
|
const autoYes = flags.yes === "true" || flags.y === "true";
|
|
48542
|
+
const shouldUpdate = flags.update === "true";
|
|
48543
|
+
if (shouldUpdate) {
|
|
48544
|
+
console.error("Checking for updates...");
|
|
48545
|
+
const { currentVersion, latestVersion, updateAvailable } = await checkForUpdates();
|
|
48546
|
+
if (latestVersion && updateAvailable) {
|
|
48547
|
+
console.error(`Update available: ${currentVersion} \u2192 ${latestVersion}`);
|
|
48548
|
+
console.error("Installing update...");
|
|
48549
|
+
const installed = installLatestVersion();
|
|
48550
|
+
if (!installed) {
|
|
48551
|
+
throw new CliError("UPDATE_FAILED", "Failed to install update", ExitCodes.ERROR);
|
|
48552
|
+
}
|
|
48553
|
+
console.error("Update installed successfully.");
|
|
48554
|
+
} else if (latestVersion) {
|
|
48555
|
+
console.error(`Already on latest version: ${currentVersion}`);
|
|
48556
|
+
} else {
|
|
48557
|
+
console.error("Could not check for updates, continuing with current version.");
|
|
48558
|
+
}
|
|
48559
|
+
}
|
|
48303
48560
|
if (needsViboraMigration()) {
|
|
48304
48561
|
const viboraDir = getLegacyViboraDir();
|
|
48305
48562
|
console.error(`
|
|
@@ -48402,7 +48659,7 @@ Found existing Vibora data at ${viboraDir}`);
|
|
|
48402
48659
|
const fulcrumDir = getFulcrumDir();
|
|
48403
48660
|
const debug = flags.debug === "true";
|
|
48404
48661
|
console.error(`Starting Fulcrum server${debug ? " (debug mode)" : ""}...`);
|
|
48405
|
-
const serverProc =
|
|
48662
|
+
const serverProc = spawn2("bun", [serverPath], {
|
|
48406
48663
|
detached: true,
|
|
48407
48664
|
stdio: "ignore",
|
|
48408
48665
|
env: {
|
|
@@ -48467,7 +48724,8 @@ var upCommand = defineCommand({
|
|
|
48467
48724
|
args: {
|
|
48468
48725
|
...globalArgs,
|
|
48469
48726
|
yes: { type: "boolean", alias: "y", description: "Auto-answer yes to prompts" },
|
|
48470
|
-
host: { type: "boolean", description: "Bind to 0.0.0.0 (expose to network)" }
|
|
48727
|
+
host: { type: "boolean", description: "Bind to 0.0.0.0 (expose to network)" },
|
|
48728
|
+
update: { type: "boolean", description: "Check for and install updates before starting" }
|
|
48471
48729
|
},
|
|
48472
48730
|
async run({ args }) {
|
|
48473
48731
|
setupJsonOutput(args);
|
|
@@ -48829,6 +49087,7 @@ var main = defineCommand({
|
|
|
48829
49087
|
doctor: doctorCommand,
|
|
48830
49088
|
dev: devCommand,
|
|
48831
49089
|
mcp: mcpCommand,
|
|
49090
|
+
update: updateCommand,
|
|
48832
49091
|
"migrate-from-vibora": migrateFromViboraCommand
|
|
48833
49092
|
}
|
|
48834
49093
|
});
|