@knowsuchagency/fulcrum 5.0.1 → 5.1.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/README.md +1 -1
- package/bin/fulcrum.js +36 -21
- package/dist/assets/{index-DigGpgRm.js → index-CZjEPZOY.js} +172 -172
- package/dist/assets/{index-rzI9_Ycl.css → index-gpXhA3yE.css} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/server/index.js +110 -129
package/README.md
CHANGED
|
@@ -316,7 +316,7 @@ For browser-only access, use Tailscale or Cloudflare Tunnels to expose your serv
|
|
|
316
316
|
<details>
|
|
317
317
|
<summary><strong>Configuration</strong></summary>
|
|
318
318
|
|
|
319
|
-
All configuration is managed by [fnox](https://github.com/yarlson/fnox) — a single
|
|
319
|
+
All configuration is managed by [fnox](https://github.com/yarlson/fnox) — a single `config/fnox.toml` file inside the fulcrum directory stores both plain and encrypted settings. Sensitive credentials (API keys, tokens, webhook URLs) are encrypted with age; the age key (`age.txt`) lives in the fulcrum directory root. The config is nested under `config/` so fnox's upward directory walk from task worktrees does not merge Fulcrum's recipients into user-invoked `fnox` commands. Existing `settings.json` files are automatically migrated to fnox on server start.
|
|
320
320
|
|
|
321
321
|
The fulcrum directory is resolved in this order:
|
|
322
322
|
|
package/bin/fulcrum.js
CHANGED
|
@@ -795,8 +795,18 @@ function expandPath(p) {
|
|
|
795
795
|
}
|
|
796
796
|
return p;
|
|
797
797
|
}
|
|
798
|
+
function resolveFnoxConfigPath(fulcrumDir) {
|
|
799
|
+
const preferred = join(fulcrumDir, "config", "fnox.toml");
|
|
800
|
+
if (existsSync(preferred))
|
|
801
|
+
return preferred;
|
|
802
|
+
for (const legacy of [join(fulcrumDir, ".fnox.toml"), join(fulcrumDir, "fnox.toml")]) {
|
|
803
|
+
if (existsSync(legacy))
|
|
804
|
+
return legacy;
|
|
805
|
+
}
|
|
806
|
+
return preferred;
|
|
807
|
+
}
|
|
798
808
|
function getPortFromFnox(fulcrumDir) {
|
|
799
|
-
const fnoxConfigPath =
|
|
809
|
+
const fnoxConfigPath = resolveFnoxConfigPath(fulcrumDir);
|
|
800
810
|
const ageKeyPath = join(fulcrumDir, "age.txt");
|
|
801
811
|
if (!existsSync(fnoxConfigPath) || !existsSync(ageKeyPath))
|
|
802
812
|
return null;
|
|
@@ -843,7 +853,7 @@ function discoverServerUrl(urlOverride, portOverride) {
|
|
|
843
853
|
}
|
|
844
854
|
function updateSettingsPort(port) {
|
|
845
855
|
const fulcrumDir = getFulcrumDir();
|
|
846
|
-
const fnoxConfigPath =
|
|
856
|
+
const fnoxConfigPath = resolveFnoxConfigPath(fulcrumDir);
|
|
847
857
|
const ageKeyPath = join(fulcrumDir, "age.txt");
|
|
848
858
|
if (!existsSync(fulcrumDir)) {
|
|
849
859
|
mkdirSync(fulcrumDir, { recursive: true });
|
|
@@ -44633,7 +44643,7 @@ function getTodayInTimezone(timezone) {
|
|
|
44633
44643
|
}
|
|
44634
44644
|
|
|
44635
44645
|
// cli/src/mcp/tools/tasks.ts
|
|
44636
|
-
import { basename as
|
|
44646
|
+
import { basename as basename3 } from "path";
|
|
44637
44647
|
function registerListTasks(server, client) {
|
|
44638
44648
|
server.tool("list_tasks", "List all Fulcrum tasks with flexible filtering. Supports text search across title/tags/project, multi-tag filtering (OR logic), multi-status filtering, date range, and overdue detection.", {
|
|
44639
44649
|
status: exports_external.optional(TaskStatusSchema2).describe("Filter by single task status (use statuses for multiple)"),
|
|
@@ -44776,7 +44786,7 @@ function registerCreateTask(server, client) {
|
|
|
44776
44786
|
recurrenceEndDate
|
|
44777
44787
|
}) => {
|
|
44778
44788
|
try {
|
|
44779
|
-
const repoName = repoPath ?
|
|
44789
|
+
const repoName = repoPath ? basename3(repoPath) : null;
|
|
44780
44790
|
const effectiveBaseBranch = baseBranch ?? "main";
|
|
44781
44791
|
const task = await client.createTask({
|
|
44782
44792
|
title,
|
|
@@ -46828,7 +46838,7 @@ async function runMcpServer(urlOverride, portOverride) {
|
|
|
46828
46838
|
const client = new FulcrumClient(urlOverride, portOverride);
|
|
46829
46839
|
const server = new McpServer({
|
|
46830
46840
|
name: "fulcrum",
|
|
46831
|
-
version: "5.0
|
|
46841
|
+
version: "5.1.0"
|
|
46832
46842
|
});
|
|
46833
46843
|
registerTools(server, client);
|
|
46834
46844
|
const transport = new StdioServerTransport;
|
|
@@ -49177,7 +49187,7 @@ var marketplace_default = `{
|
|
|
49177
49187
|
"name": "fulcrum",
|
|
49178
49188
|
"source": "./",
|
|
49179
49189
|
"description": "Task orchestration for Claude Code",
|
|
49180
|
-
"version": "5.0
|
|
49190
|
+
"version": "5.1.0",
|
|
49181
49191
|
"skills": [
|
|
49182
49192
|
"./skills/fulcrum"
|
|
49183
49193
|
],
|
|
@@ -49200,7 +49210,7 @@ var marketplace_default = `{
|
|
|
49200
49210
|
var plugin_default = `{
|
|
49201
49211
|
"name": "fulcrum",
|
|
49202
49212
|
"description": "Fulcrum task orchestration for Claude Code",
|
|
49203
|
-
"version": "5.0
|
|
49213
|
+
"version": "5.1.0",
|
|
49204
49214
|
"author": {
|
|
49205
49215
|
"name": "Fulcrum"
|
|
49206
49216
|
},
|
|
@@ -49736,7 +49746,7 @@ var notifyCommand = defineCommand({
|
|
|
49736
49746
|
// cli/src/commands/up.ts
|
|
49737
49747
|
import { spawn as spawn2 } from "child_process";
|
|
49738
49748
|
import { existsSync as existsSync6 } from "fs";
|
|
49739
|
-
import { dirname as
|
|
49749
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
49740
49750
|
import { fileURLToPath } from "url";
|
|
49741
49751
|
init_errors();
|
|
49742
49752
|
|
|
@@ -50061,17 +50071,21 @@ function installAge() {
|
|
|
50061
50071
|
// cli/src/utils/fnox-setup.ts
|
|
50062
50072
|
init_errors();
|
|
50063
50073
|
import { execSync as execSync3 } from "child_process";
|
|
50064
|
-
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync4, chmodSync, renameSync as renameSync2 } from "fs";
|
|
50065
|
-
import { join as join5 } from "path";
|
|
50074
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync4, chmodSync, mkdirSync as mkdirSync5, renameSync as renameSync2 } from "fs";
|
|
50075
|
+
import { basename as basename2, dirname as dirname3, join as join5 } from "path";
|
|
50066
50076
|
function ensureFnoxSetup(fulcrumDir) {
|
|
50067
|
-
const oldFnoxPath = join5(fulcrumDir, "fnox.toml");
|
|
50068
|
-
const newFnoxPath = join5(fulcrumDir, ".fnox.toml");
|
|
50069
|
-
if (existsSync5(oldFnoxPath) && !existsSync5(newFnoxPath)) {
|
|
50070
|
-
renameSync2(oldFnoxPath, newFnoxPath);
|
|
50071
|
-
console.error("Migrated fnox.toml \u2192 .fnox.toml");
|
|
50072
|
-
}
|
|
50073
50077
|
const ageKeyPath = join5(fulcrumDir, "age.txt");
|
|
50074
|
-
const fnoxConfigPath = join5(fulcrumDir, "
|
|
50078
|
+
const fnoxConfigPath = join5(fulcrumDir, "config", "fnox.toml");
|
|
50079
|
+
if (!existsSync5(fnoxConfigPath)) {
|
|
50080
|
+
for (const legacy of [join5(fulcrumDir, ".fnox.toml"), join5(fulcrumDir, "fnox.toml")]) {
|
|
50081
|
+
if (existsSync5(legacy)) {
|
|
50082
|
+
mkdirSync5(dirname3(fnoxConfigPath), { recursive: true });
|
|
50083
|
+
renameSync2(legacy, fnoxConfigPath);
|
|
50084
|
+
console.error(`Migrated ${basename2(legacy)} \u2192 config/fnox.toml`);
|
|
50085
|
+
break;
|
|
50086
|
+
}
|
|
50087
|
+
}
|
|
50088
|
+
}
|
|
50075
50089
|
let publicKey;
|
|
50076
50090
|
if (!existsSync5(ageKeyPath)) {
|
|
50077
50091
|
console.error("Generating age encryption key...");
|
|
@@ -50097,6 +50111,7 @@ function ensureFnoxSetup(fulcrumDir) {
|
|
|
50097
50111
|
}
|
|
50098
50112
|
if (!existsSync5(fnoxConfigPath)) {
|
|
50099
50113
|
console.error("Creating fnox configuration...");
|
|
50114
|
+
mkdirSync5(dirname3(fnoxConfigPath), { recursive: true });
|
|
50100
50115
|
const config = `[providers.plain]
|
|
50101
50116
|
type = "plain"
|
|
50102
50117
|
|
|
@@ -50212,7 +50227,7 @@ function compareVersions(v1, v2) {
|
|
|
50212
50227
|
var package_default = {
|
|
50213
50228
|
name: "@knowsuchagency/fulcrum",
|
|
50214
50229
|
private: true,
|
|
50215
|
-
version: "5.0
|
|
50230
|
+
version: "5.1.0",
|
|
50216
50231
|
description: "Harness Attention. Orchestrate Agents. Ship.",
|
|
50217
50232
|
license: "PolyForm-Perimeter-1.0.0",
|
|
50218
50233
|
type: "module",
|
|
@@ -50487,14 +50502,14 @@ var updateCommand = defineCommand({
|
|
|
50487
50502
|
// cli/src/commands/up.ts
|
|
50488
50503
|
function getPackageRoot() {
|
|
50489
50504
|
const currentFile = fileURLToPath(import.meta.url);
|
|
50490
|
-
let dir =
|
|
50505
|
+
let dir = dirname4(currentFile);
|
|
50491
50506
|
for (let i2 = 0;i2 < 5; i2++) {
|
|
50492
50507
|
if (existsSync6(join6(dir, "server", "index.js"))) {
|
|
50493
50508
|
return dir;
|
|
50494
50509
|
}
|
|
50495
|
-
dir =
|
|
50510
|
+
dir = dirname4(dir);
|
|
50496
50511
|
}
|
|
50497
|
-
return
|
|
50512
|
+
return dirname4(dirname4(dirname4(currentFile)));
|
|
50498
50513
|
}
|
|
50499
50514
|
async function ensureDependency(spec, autoYes) {
|
|
50500
50515
|
if (spec.isInstalled())
|