@versatly/workgraph 0.1.0 → 0.3.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 +94 -11
- package/SKILL.md +10 -10
- package/bin/workgraph.js +0 -0
- package/dist/chunk-65ZMX2WM.js +2846 -0
- package/dist/chunk-E3QU5Y53.js +1062 -0
- package/dist/cli.js +705 -29
- package/dist/index.d.ts +535 -7
- package/dist/index.js +37 -5
- package/dist/mcp-server-fU6U6ht8.d.ts +20 -0
- package/dist/mcp-server.d.ts +2 -0
- package/dist/mcp-server.js +8 -0
- package/package.json +23 -8
- package/dist/chunk-CRQXDCPR.js +0 -1443
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bases_exports,
|
|
3
|
+
board_exports,
|
|
4
|
+
clawdapus_exports,
|
|
3
5
|
command_center_exports,
|
|
6
|
+
integration_exports,
|
|
7
|
+
onboard_exports,
|
|
8
|
+
search_qmd_adapter_exports,
|
|
9
|
+
skill_exports,
|
|
10
|
+
trigger_exports,
|
|
11
|
+
workspace_exports
|
|
12
|
+
} from "./chunk-E3QU5Y53.js";
|
|
13
|
+
import {
|
|
14
|
+
dispatch_exports,
|
|
15
|
+
graph_exports,
|
|
4
16
|
ledger_exports,
|
|
17
|
+
mcp_server_exports,
|
|
18
|
+
orientation_exports,
|
|
19
|
+
policy_exports,
|
|
20
|
+
query_exports,
|
|
5
21
|
registry_exports,
|
|
6
|
-
skill_exports,
|
|
7
22
|
store_exports,
|
|
8
|
-
thread_exports
|
|
9
|
-
|
|
10
|
-
} from "./chunk-CRQXDCPR.js";
|
|
23
|
+
thread_exports
|
|
24
|
+
} from "./chunk-65ZMX2WM.js";
|
|
11
25
|
|
|
12
26
|
// src/cli.ts
|
|
13
27
|
import fs from "fs";
|
|
14
28
|
import path from "path";
|
|
15
29
|
import { Command } from "commander";
|
|
16
|
-
var DEFAULT_ACTOR = process.env.WORKGRAPH_AGENT || process.env.
|
|
30
|
+
var DEFAULT_ACTOR = process.env.WORKGRAPH_AGENT || process.env.USER || "anonymous";
|
|
17
31
|
var CLI_VERSION = (() => {
|
|
18
32
|
try {
|
|
19
33
|
const pkgUrl = new URL("../package.json", import.meta.url);
|
|
@@ -271,7 +285,7 @@ addWorkspaceOption(
|
|
|
271
285
|
);
|
|
272
286
|
var basesCmd = program.command("bases").description("Generate Obsidian .base files from primitive-registry.yaml");
|
|
273
287
|
addWorkspaceOption(
|
|
274
|
-
basesCmd.command("sync-registry").description("Sync .
|
|
288
|
+
basesCmd.command("sync-registry").description("Sync .workgraph/primitive-registry.yaml from active registry").option("--json", "Emit structured JSON output")
|
|
275
289
|
).action(
|
|
276
290
|
(opts) => runCommand(
|
|
277
291
|
opts,
|
|
@@ -280,7 +294,7 @@ addWorkspaceOption(
|
|
|
280
294
|
const manifest = bases_exports.syncPrimitiveRegistryManifest(workspacePath);
|
|
281
295
|
return {
|
|
282
296
|
primitiveCount: manifest.primitives.length,
|
|
283
|
-
manifestPath: ".
|
|
297
|
+
manifestPath: ".workgraph/primitive-registry.yaml"
|
|
284
298
|
};
|
|
285
299
|
},
|
|
286
300
|
(result) => [
|
|
@@ -290,7 +304,7 @@ addWorkspaceOption(
|
|
|
290
304
|
)
|
|
291
305
|
);
|
|
292
306
|
addWorkspaceOption(
|
|
293
|
-
basesCmd.command("generate").description("Generate .base files by reading primitive-registry.yaml").option("--all", "Include non-canonical primitives").option("--refresh-registry", "Refresh primitive-registry.yaml before generation").option("--output-dir <path>", "Output directory for .base files (default: .
|
|
307
|
+
basesCmd.command("generate").description("Generate .base files by reading primitive-registry.yaml").option("--all", "Include non-canonical primitives").option("--refresh-registry", "Refresh primitive-registry.yaml before generation").option("--output-dir <path>", "Output directory for .base files (default: .workgraph/bases)").option("--json", "Emit structured JSON output")
|
|
294
308
|
).action(
|
|
295
309
|
(opts) => runCommand(
|
|
296
310
|
opts,
|
|
@@ -330,17 +344,7 @@ addWorkspaceOption(
|
|
|
330
344
|
opts,
|
|
331
345
|
() => {
|
|
332
346
|
const workspacePath = resolveWorkspacePath(opts);
|
|
333
|
-
const fields = { title };
|
|
334
|
-
for (const pair of opts.set ?? []) {
|
|
335
|
-
const eqIdx = String(pair).indexOf("=");
|
|
336
|
-
if (eqIdx === -1) continue;
|
|
337
|
-
const key = String(pair).slice(0, eqIdx).trim();
|
|
338
|
-
let value = String(pair).slice(eqIdx + 1).trim();
|
|
339
|
-
if (typeof value === "string" && value.includes(",")) {
|
|
340
|
-
value = value.split(",").map((v) => v.trim());
|
|
341
|
-
}
|
|
342
|
-
fields[key] = value;
|
|
343
|
-
}
|
|
347
|
+
const fields = { title, ...parseSetPairs(opts.set ?? []) };
|
|
344
348
|
return {
|
|
345
349
|
instance: store_exports.create(workspacePath, type, fields, opts.body, opts.actor)
|
|
346
350
|
};
|
|
@@ -348,9 +352,28 @@ addWorkspaceOption(
|
|
|
348
352
|
(result) => [`Created ${result.instance.type}: ${result.instance.path}`]
|
|
349
353
|
)
|
|
350
354
|
);
|
|
355
|
+
addWorkspaceOption(
|
|
356
|
+
primitiveCmd.command("update <path>").description("Update an existing primitive instance").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--set <fields...>", 'Set fields as "key=value"').option("--body <text>", "Replace markdown body content").option("--body-file <path>", "Read markdown body content from file").option("--json", "Emit structured JSON output")
|
|
357
|
+
).action(
|
|
358
|
+
(targetPath, opts) => runCommand(
|
|
359
|
+
opts,
|
|
360
|
+
() => {
|
|
361
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
362
|
+
const updates = parseSetPairs(opts.set ?? []);
|
|
363
|
+
let body = opts.body;
|
|
364
|
+
if (opts.bodyFile) {
|
|
365
|
+
body = fs.readFileSync(path.resolve(opts.bodyFile), "utf-8");
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
instance: store_exports.update(workspacePath, targetPath, updates, body, opts.actor)
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
(result) => [`Updated ${result.instance.type}: ${result.instance.path}`]
|
|
372
|
+
)
|
|
373
|
+
);
|
|
351
374
|
var skillCmd = program.command("skill").description("Manage native skill primitives in shared workgraph vaults");
|
|
352
375
|
addWorkspaceOption(
|
|
353
|
-
skillCmd.command("write <title>").description("Create or update a skill primitive").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--owner <name>", "Skill owner").option("--version <semver>", "Skill version").option("--status <status>", "draft | proposed | active | deprecated | archived").option("--distribution <mode>", "Distribution mode", "tailscale-shared-vault").option("--tailscale-path <path>", "Shared Tailscale workspace path").option("--reviewers <list>", "Comma-separated reviewer names").option("--tags <list>", "Comma-separated tags").option("--body <text>", "Skill markdown content").option("--body-file <path>", "Read markdown content from file").option("--json", "Emit structured JSON output")
|
|
376
|
+
skillCmd.command("write <title>").description("Create or update a skill primitive").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--owner <name>", "Skill owner").option("--skill-version <semver>", "Skill version").option("--status <status>", "draft | proposed | active | deprecated | archived").option("--distribution <mode>", "Distribution mode", "tailscale-shared-vault").option("--tailscale-path <path>", "Shared Tailscale workspace path").option("--reviewers <list>", "Comma-separated reviewer names").option("--depends-on <list>", "Comma-separated skill dependencies (slug/path)").option("--expected-updated-at <iso>", "Optimistic concurrency guard for updates").option("--tags <list>", "Comma-separated tags").option("--body <text>", "Skill markdown content").option("--body-file <path>", "Read markdown content from file").option("--json", "Emit structured JSON output")
|
|
354
377
|
).action(
|
|
355
378
|
(title, opts) => runCommand(
|
|
356
379
|
opts,
|
|
@@ -368,11 +391,13 @@ addWorkspaceOption(
|
|
|
368
391
|
opts.actor,
|
|
369
392
|
{
|
|
370
393
|
owner: opts.owner,
|
|
371
|
-
version: opts.
|
|
394
|
+
version: opts.skillVersion,
|
|
372
395
|
status: opts.status,
|
|
373
396
|
distribution: opts.distribution,
|
|
374
397
|
tailscalePath: opts.tailscalePath,
|
|
375
398
|
reviewers: csv(opts.reviewers),
|
|
399
|
+
dependsOn: csv(opts.dependsOn),
|
|
400
|
+
expectedUpdatedAt: opts.expectedUpdatedAt,
|
|
376
401
|
tags: csv(opts.tags)
|
|
377
402
|
}
|
|
378
403
|
);
|
|
@@ -403,18 +428,54 @@ addWorkspaceOption(
|
|
|
403
428
|
)
|
|
404
429
|
);
|
|
405
430
|
addWorkspaceOption(
|
|
406
|
-
skillCmd.command("list").description("List skills").option("--status <status>", "Filter by status").option("--json", "Emit structured JSON output")
|
|
431
|
+
skillCmd.command("list").description("List skills").option("--status <status>", "Filter by status").option("--updated-since <iso>", "Filter by updated timestamp (ISO-8601)").option("--json", "Emit structured JSON output")
|
|
407
432
|
).action(
|
|
408
433
|
(opts) => runCommand(
|
|
409
434
|
opts,
|
|
410
435
|
() => {
|
|
411
436
|
const workspacePath = resolveWorkspacePath(opts);
|
|
412
|
-
const skills = skill_exports.listSkills(workspacePath, {
|
|
437
|
+
const skills = skill_exports.listSkills(workspacePath, {
|
|
438
|
+
status: opts.status,
|
|
439
|
+
updatedSince: opts.updatedSince
|
|
440
|
+
});
|
|
413
441
|
return { skills, count: skills.length };
|
|
414
442
|
},
|
|
415
443
|
(result) => result.skills.map((skill) => `${String(skill.fields.title)} [${String(skill.fields.status)}] -> ${skill.path}`)
|
|
416
444
|
)
|
|
417
445
|
);
|
|
446
|
+
addWorkspaceOption(
|
|
447
|
+
skillCmd.command("history <skillRef>").description("Show ledger history entries for one skill").option("--limit <n>", "Limit number of returned entries").option("--json", "Emit structured JSON output")
|
|
448
|
+
).action(
|
|
449
|
+
(skillRef, opts) => runCommand(
|
|
450
|
+
opts,
|
|
451
|
+
() => {
|
|
452
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
453
|
+
return {
|
|
454
|
+
entries: skill_exports.skillHistory(workspacePath, skillRef, {
|
|
455
|
+
limit: opts.limit ? Number.parseInt(String(opts.limit), 10) : void 0
|
|
456
|
+
})
|
|
457
|
+
};
|
|
458
|
+
},
|
|
459
|
+
(result) => result.entries.map((entry) => `${entry.ts} ${entry.op} ${entry.actor}`)
|
|
460
|
+
)
|
|
461
|
+
);
|
|
462
|
+
addWorkspaceOption(
|
|
463
|
+
skillCmd.command("diff <skillRef>").description("Show latest field-change summary for one skill").option("--json", "Emit structured JSON output")
|
|
464
|
+
).action(
|
|
465
|
+
(skillRef, opts) => runCommand(
|
|
466
|
+
opts,
|
|
467
|
+
() => {
|
|
468
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
469
|
+
return skill_exports.skillDiff(workspacePath, skillRef);
|
|
470
|
+
},
|
|
471
|
+
(result) => [
|
|
472
|
+
`Skill: ${result.path}`,
|
|
473
|
+
`Latest: ${result.latestEntryTs ?? "none"}`,
|
|
474
|
+
`Previous: ${result.previousEntryTs ?? "none"}`,
|
|
475
|
+
`Changed fields: ${result.changedFields.join(", ") || "none"}`
|
|
476
|
+
]
|
|
477
|
+
)
|
|
478
|
+
);
|
|
418
479
|
addWorkspaceOption(
|
|
419
480
|
skillCmd.command("propose <skillRef>").description("Move a skill into proposed state and open review thread").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--proposal-thread <path>", "Explicit proposal thread path").option("--no-create-thread", "Do not create a proposal thread automatically").option("--space <spaceRef>", "Space for created proposal thread").option("--reviewers <list>", "Comma-separated reviewers").option("--json", "Emit structured JSON output")
|
|
420
481
|
).action(
|
|
@@ -438,7 +499,7 @@ addWorkspaceOption(
|
|
|
438
499
|
)
|
|
439
500
|
);
|
|
440
501
|
addWorkspaceOption(
|
|
441
|
-
skillCmd.command("promote <skillRef>").description("Promote a proposed/draft skill to active").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--version <semver>", "Explicit promoted version").option("--json", "Emit structured JSON output")
|
|
502
|
+
skillCmd.command("promote <skillRef>").description("Promote a proposed/draft skill to active").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--skill-version <semver>", "Explicit promoted version").option("--json", "Emit structured JSON output")
|
|
442
503
|
).action(
|
|
443
504
|
(skillRef, opts) => runCommand(
|
|
444
505
|
opts,
|
|
@@ -446,7 +507,7 @@ addWorkspaceOption(
|
|
|
446
507
|
const workspacePath = resolveWorkspacePath(opts);
|
|
447
508
|
return {
|
|
448
509
|
skill: skill_exports.promoteSkill(workspacePath, skillRef, opts.actor, {
|
|
449
|
-
version: opts.
|
|
510
|
+
version: opts.skillVersion
|
|
450
511
|
})
|
|
451
512
|
};
|
|
452
513
|
},
|
|
@@ -456,6 +517,40 @@ addWorkspaceOption(
|
|
|
456
517
|
]
|
|
457
518
|
)
|
|
458
519
|
);
|
|
520
|
+
var integrationCmd = program.command("integration").description("Manage optional third-party integrations");
|
|
521
|
+
addWorkspaceOption(
|
|
522
|
+
integrationCmd.command("list").description("List supported optional integrations").option("--json", "Emit structured JSON output")
|
|
523
|
+
).action(
|
|
524
|
+
(opts) => runCommand(
|
|
525
|
+
opts,
|
|
526
|
+
() => ({
|
|
527
|
+
integrations: integration_exports.listIntegrations()
|
|
528
|
+
}),
|
|
529
|
+
(result) => result.integrations.map((integration) => `${integration.id} (${integration.defaultTitle}) -> ${integration.defaultSourceUrl}`)
|
|
530
|
+
)
|
|
531
|
+
);
|
|
532
|
+
addWorkspaceOption(
|
|
533
|
+
integrationCmd.command("install <integrationName>").description("Install an optional integration into this workspace").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--owner <name>", "Skill owner override").option("--title <title>", "Skill title to store in workgraph").option("--source-url <url>", "Source URL override for integration content").option("--force", "Overwrite an existing imported integration skill").option("--json", "Emit structured JSON output")
|
|
534
|
+
).action(
|
|
535
|
+
(integrationName, opts) => runCommand(
|
|
536
|
+
opts,
|
|
537
|
+
() => installNamedIntegration(resolveWorkspacePath(opts), integrationName, opts),
|
|
538
|
+
renderInstalledIntegrationResult
|
|
539
|
+
)
|
|
540
|
+
);
|
|
541
|
+
addWorkspaceOption(
|
|
542
|
+
integrationCmd.command("clawdapus").description("Import Clawdapus SKILL.md into this workspace").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--owner <name>", "Skill owner override").option("--title <title>", "Skill title to store in workgraph", "clawdapus").option(
|
|
543
|
+
"--source-url <url>",
|
|
544
|
+
"Source URL for Clawdapus SKILL.md",
|
|
545
|
+
clawdapus_exports.DEFAULT_CLAWDAPUS_SKILL_URL
|
|
546
|
+
).option("--force", "Overwrite an existing imported Clawdapus skill").option("--json", "Emit structured JSON output")
|
|
547
|
+
).action(
|
|
548
|
+
(opts) => runCommand(
|
|
549
|
+
opts,
|
|
550
|
+
() => installNamedIntegration(resolveWorkspacePath(opts), "clawdapus", opts),
|
|
551
|
+
renderInstalledIntegrationResult
|
|
552
|
+
)
|
|
553
|
+
);
|
|
459
554
|
var ledgerCmd = program.command("ledger").description("Inspect the append-only workgraph ledger");
|
|
460
555
|
addWorkspaceOption(
|
|
461
556
|
ledgerCmd.command("show").description("Show recent ledger entries").option("-n, --count <n>", "Number of entries", "20").option("--actor <name>", "Filter by actor").option("--json", "Emit structured JSON output")
|
|
@@ -601,7 +696,527 @@ addWorkspaceOption(
|
|
|
601
696
|
]
|
|
602
697
|
)
|
|
603
698
|
);
|
|
604
|
-
|
|
699
|
+
addWorkspaceOption(
|
|
700
|
+
program.command("status").description("Show workspace situational status snapshot").option("--json", "Emit structured JSON output")
|
|
701
|
+
).action(
|
|
702
|
+
(opts) => runCommand(
|
|
703
|
+
opts,
|
|
704
|
+
() => {
|
|
705
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
706
|
+
return orientation_exports.statusSnapshot(workspacePath);
|
|
707
|
+
},
|
|
708
|
+
(result) => [
|
|
709
|
+
`Threads: total=${result.threads.total} open=${result.threads.open} active=${result.threads.active} blocked=${result.threads.blocked} done=${result.threads.done}`,
|
|
710
|
+
`Ready threads: ${result.threads.ready} Active claims: ${result.claims.active}`,
|
|
711
|
+
`Primitive types: ${Object.keys(result.primitives.byType).length}`
|
|
712
|
+
]
|
|
713
|
+
)
|
|
714
|
+
);
|
|
715
|
+
addWorkspaceOption(
|
|
716
|
+
program.command("brief").description("Show actor-centric operational brief").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--recent <count>", "Recent activity count", "12").option("--next <count>", "Next ready threads to include", "5").option("--json", "Emit structured JSON output")
|
|
717
|
+
).action(
|
|
718
|
+
(opts) => runCommand(
|
|
719
|
+
opts,
|
|
720
|
+
() => {
|
|
721
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
722
|
+
return orientation_exports.brief(workspacePath, opts.actor, {
|
|
723
|
+
recentCount: Number.parseInt(String(opts.recent), 10),
|
|
724
|
+
nextCount: Number.parseInt(String(opts.next), 10)
|
|
725
|
+
});
|
|
726
|
+
},
|
|
727
|
+
(result) => [
|
|
728
|
+
`Brief for ${result.actor}`,
|
|
729
|
+
`My claims: ${result.myClaims.length}`,
|
|
730
|
+
`Blocked threads: ${result.blockedThreads.length}`,
|
|
731
|
+
`Next ready: ${result.nextReadyThreads.map((item) => item.path).join(", ") || "none"}`
|
|
732
|
+
]
|
|
733
|
+
)
|
|
734
|
+
);
|
|
735
|
+
addWorkspaceOption(
|
|
736
|
+
program.command("checkpoint <summary>").description("Create a checkpoint primitive for hand-off continuity").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--next <items>", "Comma-separated next actions").option("--blocked <items>", "Comma-separated blockers").option("--tags <items>", "Comma-separated tags").option("--json", "Emit structured JSON output")
|
|
737
|
+
).action(
|
|
738
|
+
(summary, opts) => runCommand(
|
|
739
|
+
opts,
|
|
740
|
+
() => {
|
|
741
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
742
|
+
return {
|
|
743
|
+
checkpoint: orientation_exports.checkpoint(workspacePath, opts.actor, summary, {
|
|
744
|
+
next: csv(opts.next),
|
|
745
|
+
blocked: csv(opts.blocked),
|
|
746
|
+
tags: csv(opts.tags)
|
|
747
|
+
})
|
|
748
|
+
};
|
|
749
|
+
},
|
|
750
|
+
(result) => [`Created checkpoint: ${result.checkpoint.path}`]
|
|
751
|
+
)
|
|
752
|
+
);
|
|
753
|
+
addWorkspaceOption(
|
|
754
|
+
program.command("intake <observation>").description("Capture intake observation as lightweight checkpoint note").option("-a, --actor <name>", "Agent name", DEFAULT_ACTOR).option("--tags <items>", "Comma-separated tags").option("--json", "Emit structured JSON output")
|
|
755
|
+
).action(
|
|
756
|
+
(observation, opts) => runCommand(
|
|
757
|
+
opts,
|
|
758
|
+
() => {
|
|
759
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
760
|
+
return {
|
|
761
|
+
intake: orientation_exports.intake(workspacePath, opts.actor, observation, {
|
|
762
|
+
tags: csv(opts.tags)
|
|
763
|
+
})
|
|
764
|
+
};
|
|
765
|
+
},
|
|
766
|
+
(result) => [`Captured intake: ${result.intake.path}`]
|
|
767
|
+
)
|
|
768
|
+
);
|
|
769
|
+
addWorkspaceOption(
|
|
770
|
+
program.command("query").description("Query primitive instances with multi-field filters").option("--type <type>", "Primitive type").option("--status <status>", "Status value").option("--owner <owner>", "Owner/actor value").option("--tag <tag>", "Tag filter").option("--text <text>", "Full-text contains filter").option("--path-includes <text>", "Path substring filter").option("--updated-after <iso>", "Updated at or after").option("--updated-before <iso>", "Updated at or before").option("--created-after <iso>", "Created at or after").option("--created-before <iso>", "Created at or before").option("--limit <n>", "Result limit").option("--offset <n>", "Result offset").option("--json", "Emit structured JSON output")
|
|
771
|
+
).action(
|
|
772
|
+
(opts) => runCommand(
|
|
773
|
+
opts,
|
|
774
|
+
() => {
|
|
775
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
776
|
+
const results = query_exports.queryPrimitives(workspacePath, {
|
|
777
|
+
type: opts.type,
|
|
778
|
+
status: opts.status,
|
|
779
|
+
owner: opts.owner,
|
|
780
|
+
tag: opts.tag,
|
|
781
|
+
text: opts.text,
|
|
782
|
+
pathIncludes: opts.pathIncludes,
|
|
783
|
+
updatedAfter: opts.updatedAfter,
|
|
784
|
+
updatedBefore: opts.updatedBefore,
|
|
785
|
+
createdAfter: opts.createdAfter,
|
|
786
|
+
createdBefore: opts.createdBefore,
|
|
787
|
+
limit: opts.limit ? Number.parseInt(String(opts.limit), 10) : void 0,
|
|
788
|
+
offset: opts.offset ? Number.parseInt(String(opts.offset), 10) : void 0
|
|
789
|
+
});
|
|
790
|
+
return { results, count: results.length };
|
|
791
|
+
},
|
|
792
|
+
(result) => result.results.map((item) => `${item.type} ${item.path}`)
|
|
793
|
+
)
|
|
794
|
+
);
|
|
795
|
+
addWorkspaceOption(
|
|
796
|
+
program.command("search <text>").description("Keyword search across markdown body/frontmatter with optional QMD-compatible mode").option("--type <type>", "Limit to primitive type").option("--mode <mode>", "auto | core | qmd", "auto").option("--limit <n>", "Result limit").option("--json", "Emit structured JSON output")
|
|
797
|
+
).action(
|
|
798
|
+
(text, opts) => runCommand(
|
|
799
|
+
opts,
|
|
800
|
+
() => {
|
|
801
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
802
|
+
const result = search_qmd_adapter_exports.search(workspacePath, text, {
|
|
803
|
+
mode: opts.mode,
|
|
804
|
+
type: opts.type,
|
|
805
|
+
limit: opts.limit ? Number.parseInt(String(opts.limit), 10) : void 0
|
|
806
|
+
});
|
|
807
|
+
return {
|
|
808
|
+
...result,
|
|
809
|
+
count: result.results.length
|
|
810
|
+
};
|
|
811
|
+
},
|
|
812
|
+
(result) => [
|
|
813
|
+
`Mode: ${result.mode}`,
|
|
814
|
+
...result.fallbackReason ? [`Note: ${result.fallbackReason}`] : [],
|
|
815
|
+
...result.results.map((item) => `${item.type} ${item.path}`)
|
|
816
|
+
]
|
|
817
|
+
)
|
|
818
|
+
);
|
|
819
|
+
var boardCmd = program.command("board").description("Generate and sync Obsidian Kanban board views");
|
|
820
|
+
addWorkspaceOption(
|
|
821
|
+
boardCmd.command("generate").description("Generate Obsidian Kanban board markdown from thread states").option("-o, --output <path>", "Output board path", "ops/Workgraph Board.md").option("--include-cancelled", "Include cancelled lane").option("--json", "Emit structured JSON output")
|
|
822
|
+
).action(
|
|
823
|
+
(opts) => runCommand(
|
|
824
|
+
opts,
|
|
825
|
+
() => {
|
|
826
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
827
|
+
return board_exports.generateKanbanBoard(workspacePath, {
|
|
828
|
+
outputPath: opts.output,
|
|
829
|
+
includeCancelled: !!opts.includeCancelled
|
|
830
|
+
});
|
|
831
|
+
},
|
|
832
|
+
(result) => [
|
|
833
|
+
`Generated board: ${result.outputPath}`,
|
|
834
|
+
`Backlog=${result.counts.backlog} InProgress=${result.counts.inProgress} Blocked=${result.counts.blocked} Done=${result.counts.done}`
|
|
835
|
+
]
|
|
836
|
+
)
|
|
837
|
+
);
|
|
838
|
+
addWorkspaceOption(
|
|
839
|
+
boardCmd.command("sync").description("Sync existing board markdown from current thread states").option("-o, --output <path>", "Output board path", "ops/Workgraph Board.md").option("--include-cancelled", "Include cancelled lane").option("--json", "Emit structured JSON output")
|
|
840
|
+
).action(
|
|
841
|
+
(opts) => runCommand(
|
|
842
|
+
opts,
|
|
843
|
+
() => {
|
|
844
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
845
|
+
return board_exports.syncKanbanBoard(workspacePath, {
|
|
846
|
+
outputPath: opts.output,
|
|
847
|
+
includeCancelled: !!opts.includeCancelled
|
|
848
|
+
});
|
|
849
|
+
},
|
|
850
|
+
(result) => [
|
|
851
|
+
`Synced board: ${result.outputPath}`,
|
|
852
|
+
`Backlog=${result.counts.backlog} InProgress=${result.counts.inProgress} Blocked=${result.counts.blocked} Done=${result.counts.done}`
|
|
853
|
+
]
|
|
854
|
+
)
|
|
855
|
+
);
|
|
856
|
+
var graphCmd = program.command("graph").description("Wiki-link graph indexing and hygiene");
|
|
857
|
+
addWorkspaceOption(
|
|
858
|
+
graphCmd.command("index").description("Build wiki-link graph index").option("--json", "Emit structured JSON output")
|
|
859
|
+
).action(
|
|
860
|
+
(opts) => runCommand(
|
|
861
|
+
opts,
|
|
862
|
+
() => {
|
|
863
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
864
|
+
return graph_exports.refreshWikiLinkGraphIndex(workspacePath);
|
|
865
|
+
},
|
|
866
|
+
(result) => [
|
|
867
|
+
`Nodes: ${result.nodes.length}`,
|
|
868
|
+
`Edges: ${result.edges.length}`,
|
|
869
|
+
`Broken links: ${result.brokenLinks.length}`
|
|
870
|
+
]
|
|
871
|
+
)
|
|
872
|
+
);
|
|
873
|
+
addWorkspaceOption(
|
|
874
|
+
graphCmd.command("hygiene").description("Generate graph hygiene report (orphans, broken links, hubs)").option("--json", "Emit structured JSON output")
|
|
875
|
+
).action(
|
|
876
|
+
(opts) => runCommand(
|
|
877
|
+
opts,
|
|
878
|
+
() => {
|
|
879
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
880
|
+
return graph_exports.graphHygieneReport(workspacePath);
|
|
881
|
+
},
|
|
882
|
+
(result) => [
|
|
883
|
+
`Nodes=${result.nodeCount} Edges=${result.edgeCount}`,
|
|
884
|
+
`Orphans=${result.orphanCount} BrokenLinks=${result.brokenLinkCount}`,
|
|
885
|
+
`Top hub: ${result.hubs[0]?.node ?? "none"}`
|
|
886
|
+
]
|
|
887
|
+
)
|
|
888
|
+
);
|
|
889
|
+
addWorkspaceOption(
|
|
890
|
+
graphCmd.command("neighbors <nodePath>").description("Query incoming/outgoing wiki-link neighbors for one node").option("--refresh", "Refresh graph index before querying").option("--json", "Emit structured JSON output")
|
|
891
|
+
).action(
|
|
892
|
+
(nodePath, opts) => runCommand(
|
|
893
|
+
opts,
|
|
894
|
+
() => {
|
|
895
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
896
|
+
return graph_exports.graphNeighborhood(workspacePath, nodePath, {
|
|
897
|
+
refresh: !!opts.refresh
|
|
898
|
+
});
|
|
899
|
+
},
|
|
900
|
+
(result) => [
|
|
901
|
+
`Node: ${result.node} (${result.exists ? "exists" : "missing"})`,
|
|
902
|
+
`Outgoing: ${result.outgoing.length}`,
|
|
903
|
+
`Incoming: ${result.incoming.length}`
|
|
904
|
+
]
|
|
905
|
+
)
|
|
906
|
+
);
|
|
907
|
+
var policyCmd = program.command("policy").description("Manage policy parties and capabilities");
|
|
908
|
+
var policyPartyCmd = policyCmd.command("party").description("Manage registered policy parties");
|
|
909
|
+
addWorkspaceOption(
|
|
910
|
+
policyPartyCmd.command("upsert <id>").description("Create or update a policy party").option("--roles <roles>", "Comma-separated roles").option("--capabilities <caps>", "Comma-separated capabilities").option("--json", "Emit structured JSON output")
|
|
911
|
+
).action(
|
|
912
|
+
(id, opts) => runCommand(
|
|
913
|
+
opts,
|
|
914
|
+
() => {
|
|
915
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
916
|
+
return {
|
|
917
|
+
party: policy_exports.upsertParty(workspacePath, id, {
|
|
918
|
+
roles: csv(opts.roles),
|
|
919
|
+
capabilities: csv(opts.capabilities)
|
|
920
|
+
})
|
|
921
|
+
};
|
|
922
|
+
},
|
|
923
|
+
(result) => [`Upserted policy party: ${result.party.id}`]
|
|
924
|
+
)
|
|
925
|
+
);
|
|
926
|
+
addWorkspaceOption(
|
|
927
|
+
policyPartyCmd.command("get <id>").description("Get one policy party").option("--json", "Emit structured JSON output")
|
|
928
|
+
).action(
|
|
929
|
+
(id, opts) => runCommand(
|
|
930
|
+
opts,
|
|
931
|
+
() => {
|
|
932
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
933
|
+
const party = policy_exports.getParty(workspacePath, id);
|
|
934
|
+
if (!party) throw new Error(`Policy party not found: ${id}`);
|
|
935
|
+
return { party };
|
|
936
|
+
},
|
|
937
|
+
(result) => [`${result.party.id} roles=${result.party.roles.join(",")}`]
|
|
938
|
+
)
|
|
939
|
+
);
|
|
940
|
+
addWorkspaceOption(
|
|
941
|
+
policyPartyCmd.command("list").description("List policy parties").option("--json", "Emit structured JSON output")
|
|
942
|
+
).action(
|
|
943
|
+
(opts) => runCommand(
|
|
944
|
+
opts,
|
|
945
|
+
() => {
|
|
946
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
947
|
+
const registry = policy_exports.loadPolicyRegistry(workspacePath);
|
|
948
|
+
return {
|
|
949
|
+
parties: Object.values(registry.parties)
|
|
950
|
+
};
|
|
951
|
+
},
|
|
952
|
+
(result) => result.parties.map((party) => `${party.id} [${party.roles.join(", ")}]`)
|
|
953
|
+
)
|
|
954
|
+
);
|
|
955
|
+
var dispatchCmd = program.command("dispatch").description("Programmatic runtime dispatch contract");
|
|
956
|
+
addWorkspaceOption(
|
|
957
|
+
dispatchCmd.command("create <objective>").description("Create a new run dispatch request").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--adapter <name>", "Adapter name", "cursor-cloud").option("--idempotency-key <key>", "Idempotency key").option("--json", "Emit structured JSON output")
|
|
958
|
+
).action(
|
|
959
|
+
(objective, opts) => runCommand(
|
|
960
|
+
opts,
|
|
961
|
+
() => {
|
|
962
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
963
|
+
return {
|
|
964
|
+
run: dispatch_exports.createRun(workspacePath, {
|
|
965
|
+
actor: opts.actor,
|
|
966
|
+
adapter: opts.adapter,
|
|
967
|
+
objective,
|
|
968
|
+
idempotencyKey: opts.idempotencyKey
|
|
969
|
+
})
|
|
970
|
+
};
|
|
971
|
+
},
|
|
972
|
+
(result) => [`Run created: ${result.run.id} [${result.run.status}]`]
|
|
973
|
+
)
|
|
974
|
+
);
|
|
975
|
+
addWorkspaceOption(
|
|
976
|
+
dispatchCmd.command("create-execute <objective>").description("Create and execute a run with autonomous multi-agent coordination").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--adapter <name>", "Adapter name", "cursor-cloud").option("--idempotency-key <key>", "Idempotency key").option("--agents <actors>", "Comma-separated agent identities for autonomous execution").option("--max-steps <n>", "Maximum scheduler steps", "200").option("--step-delay-ms <ms>", "Delay between scheduling steps", "25").option("--space <spaceRef>", "Restrict execution to one space").option("--no-checkpoint", "Skip automatic checkpoint generation after execution").option("--json", "Emit structured JSON output")
|
|
977
|
+
).action(
|
|
978
|
+
(objective, opts) => runCommand(
|
|
979
|
+
opts,
|
|
980
|
+
async () => {
|
|
981
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
982
|
+
return {
|
|
983
|
+
run: await dispatch_exports.createAndExecuteRun(
|
|
984
|
+
workspacePath,
|
|
985
|
+
{
|
|
986
|
+
actor: opts.actor,
|
|
987
|
+
adapter: opts.adapter,
|
|
988
|
+
objective,
|
|
989
|
+
idempotencyKey: opts.idempotencyKey
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
agents: csv(opts.agents),
|
|
993
|
+
maxSteps: Number.parseInt(String(opts.maxSteps), 10),
|
|
994
|
+
stepDelayMs: Number.parseInt(String(opts.stepDelayMs), 10),
|
|
995
|
+
space: opts.space,
|
|
996
|
+
createCheckpoint: opts.checkpoint
|
|
997
|
+
}
|
|
998
|
+
)
|
|
999
|
+
};
|
|
1000
|
+
},
|
|
1001
|
+
(result) => [
|
|
1002
|
+
`Run executed: ${result.run.id} [${result.run.status}]`,
|
|
1003
|
+
...result.run.output ? [`Output: ${result.run.output}`] : [],
|
|
1004
|
+
...result.run.error ? [`Error: ${result.run.error}`] : []
|
|
1005
|
+
]
|
|
1006
|
+
)
|
|
1007
|
+
);
|
|
1008
|
+
addWorkspaceOption(
|
|
1009
|
+
dispatchCmd.command("list").description("List runs").option("--status <status>", "queued|running|succeeded|failed|cancelled").option("--limit <n>", "Result limit").option("--json", "Emit structured JSON output")
|
|
1010
|
+
).action(
|
|
1011
|
+
(opts) => runCommand(
|
|
1012
|
+
opts,
|
|
1013
|
+
() => {
|
|
1014
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1015
|
+
return {
|
|
1016
|
+
runs: dispatch_exports.listRuns(workspacePath, {
|
|
1017
|
+
status: opts.status,
|
|
1018
|
+
limit: opts.limit ? Number.parseInt(String(opts.limit), 10) : void 0
|
|
1019
|
+
})
|
|
1020
|
+
};
|
|
1021
|
+
},
|
|
1022
|
+
(result) => result.runs.map((run) => `${run.id} [${run.status}] ${run.objective}`)
|
|
1023
|
+
)
|
|
1024
|
+
);
|
|
1025
|
+
addWorkspaceOption(
|
|
1026
|
+
dispatchCmd.command("status <runId>").description("Get run status by ID").option("--json", "Emit structured JSON output")
|
|
1027
|
+
).action(
|
|
1028
|
+
(runId, opts) => runCommand(
|
|
1029
|
+
opts,
|
|
1030
|
+
() => {
|
|
1031
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1032
|
+
return {
|
|
1033
|
+
run: dispatch_exports.status(workspacePath, runId)
|
|
1034
|
+
};
|
|
1035
|
+
},
|
|
1036
|
+
(result) => [`${result.run.id} [${result.run.status}]`]
|
|
1037
|
+
)
|
|
1038
|
+
);
|
|
1039
|
+
addWorkspaceOption(
|
|
1040
|
+
dispatchCmd.command("execute <runId>").description("Execute a queued/running run via adapter autonomous scheduling").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--agents <actors>", "Comma-separated agent identities").option("--max-steps <n>", "Maximum scheduler steps", "200").option("--step-delay-ms <ms>", "Delay between scheduling steps", "25").option("--space <spaceRef>", "Restrict execution to one space").option("--no-checkpoint", "Skip automatic checkpoint generation after execution").option("--json", "Emit structured JSON output")
|
|
1041
|
+
).action(
|
|
1042
|
+
(runId, opts) => runCommand(
|
|
1043
|
+
opts,
|
|
1044
|
+
async () => {
|
|
1045
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1046
|
+
return {
|
|
1047
|
+
run: await dispatch_exports.executeRun(workspacePath, runId, {
|
|
1048
|
+
actor: opts.actor,
|
|
1049
|
+
agents: csv(opts.agents),
|
|
1050
|
+
maxSteps: Number.parseInt(String(opts.maxSteps), 10),
|
|
1051
|
+
stepDelayMs: Number.parseInt(String(opts.stepDelayMs), 10),
|
|
1052
|
+
space: opts.space,
|
|
1053
|
+
createCheckpoint: opts.checkpoint
|
|
1054
|
+
})
|
|
1055
|
+
};
|
|
1056
|
+
},
|
|
1057
|
+
(result) => [
|
|
1058
|
+
`Run executed: ${result.run.id} [${result.run.status}]`,
|
|
1059
|
+
...result.run.output ? [`Output: ${result.run.output}`] : [],
|
|
1060
|
+
...result.run.error ? [`Error: ${result.run.error}`] : []
|
|
1061
|
+
]
|
|
1062
|
+
)
|
|
1063
|
+
);
|
|
1064
|
+
addWorkspaceOption(
|
|
1065
|
+
dispatchCmd.command("followup <runId> <input>").description("Send follow-up input to a run").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--json", "Emit structured JSON output")
|
|
1066
|
+
).action(
|
|
1067
|
+
(runId, input, opts) => runCommand(
|
|
1068
|
+
opts,
|
|
1069
|
+
() => {
|
|
1070
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1071
|
+
return {
|
|
1072
|
+
run: dispatch_exports.followup(workspacePath, runId, opts.actor, input)
|
|
1073
|
+
};
|
|
1074
|
+
},
|
|
1075
|
+
(result) => [`Follow-up recorded: ${result.run.id} [${result.run.status}]`]
|
|
1076
|
+
)
|
|
1077
|
+
);
|
|
1078
|
+
addWorkspaceOption(
|
|
1079
|
+
dispatchCmd.command("stop <runId>").description("Cancel a run").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--json", "Emit structured JSON output")
|
|
1080
|
+
).action(
|
|
1081
|
+
(runId, opts) => runCommand(
|
|
1082
|
+
opts,
|
|
1083
|
+
() => {
|
|
1084
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1085
|
+
return {
|
|
1086
|
+
run: dispatch_exports.stop(workspacePath, runId, opts.actor)
|
|
1087
|
+
};
|
|
1088
|
+
},
|
|
1089
|
+
(result) => [`Stopped run: ${result.run.id} [${result.run.status}]`]
|
|
1090
|
+
)
|
|
1091
|
+
);
|
|
1092
|
+
addWorkspaceOption(
|
|
1093
|
+
dispatchCmd.command("mark <runId>").description("Set run status transition explicitly").requiredOption("--status <status>", "running|succeeded|failed|cancelled").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--output <text>", "Optional output payload").option("--error <text>", "Optional error payload").option("--json", "Emit structured JSON output")
|
|
1094
|
+
).action(
|
|
1095
|
+
(runId, opts) => runCommand(
|
|
1096
|
+
opts,
|
|
1097
|
+
() => {
|
|
1098
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1099
|
+
const status = normalizeRunStatus(opts.status);
|
|
1100
|
+
return {
|
|
1101
|
+
run: dispatch_exports.markRun(workspacePath, runId, opts.actor, status, {
|
|
1102
|
+
output: opts.output,
|
|
1103
|
+
error: opts.error
|
|
1104
|
+
})
|
|
1105
|
+
};
|
|
1106
|
+
},
|
|
1107
|
+
(result) => [`Marked run: ${result.run.id} [${result.run.status}]`]
|
|
1108
|
+
)
|
|
1109
|
+
);
|
|
1110
|
+
addWorkspaceOption(
|
|
1111
|
+
dispatchCmd.command("logs <runId>").description("Read logs from a run").option("--json", "Emit structured JSON output")
|
|
1112
|
+
).action(
|
|
1113
|
+
(runId, opts) => runCommand(
|
|
1114
|
+
opts,
|
|
1115
|
+
() => {
|
|
1116
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1117
|
+
return {
|
|
1118
|
+
runId,
|
|
1119
|
+
logs: dispatch_exports.logs(workspacePath, runId)
|
|
1120
|
+
};
|
|
1121
|
+
},
|
|
1122
|
+
(result) => result.logs.map((entry) => `${entry.ts} [${entry.level}] ${entry.message}`)
|
|
1123
|
+
)
|
|
1124
|
+
);
|
|
1125
|
+
var triggerCmd = program.command("trigger").description("Trigger primitives and run dispatch lifecycle");
|
|
1126
|
+
addWorkspaceOption(
|
|
1127
|
+
triggerCmd.command("fire <triggerPath>").description("Fire an approved/active trigger and dispatch a run").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--event-key <key>", "Deterministic event key for idempotency").option("--objective <text>", "Override run objective").option("--json", "Emit structured JSON output")
|
|
1128
|
+
).action(
|
|
1129
|
+
(triggerPath, opts) => runCommand(
|
|
1130
|
+
opts,
|
|
1131
|
+
() => {
|
|
1132
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1133
|
+
return trigger_exports.fireTrigger(workspacePath, triggerPath, {
|
|
1134
|
+
actor: opts.actor,
|
|
1135
|
+
eventKey: opts.eventKey,
|
|
1136
|
+
objective: opts.objective
|
|
1137
|
+
});
|
|
1138
|
+
},
|
|
1139
|
+
(result) => [
|
|
1140
|
+
`Fired trigger: ${result.triggerPath}`,
|
|
1141
|
+
`Run: ${result.run.id} [${result.run.status}]`
|
|
1142
|
+
]
|
|
1143
|
+
)
|
|
1144
|
+
);
|
|
1145
|
+
addWorkspaceOption(
|
|
1146
|
+
program.command("onboard").description("Guided agent-first workspace setup and starter artifacts").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--spaces <list>", "Comma-separated space names").option("--no-demo-threads", "Skip starter onboarding threads").option("--json", "Emit structured JSON output")
|
|
1147
|
+
).action(
|
|
1148
|
+
(opts) => runCommand(
|
|
1149
|
+
opts,
|
|
1150
|
+
() => {
|
|
1151
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1152
|
+
return onboard_exports.onboardWorkspace(workspacePath, {
|
|
1153
|
+
actor: opts.actor,
|
|
1154
|
+
spaces: csv(opts.spaces),
|
|
1155
|
+
createDemoThreads: opts.demoThreads
|
|
1156
|
+
});
|
|
1157
|
+
},
|
|
1158
|
+
(result) => [
|
|
1159
|
+
`Onboarded actor: ${result.actor}`,
|
|
1160
|
+
`Spaces created: ${result.spacesCreated.length}`,
|
|
1161
|
+
`Threads created: ${result.threadsCreated.length}`,
|
|
1162
|
+
`Board: ${result.boardPath}`,
|
|
1163
|
+
`Command center: ${result.commandCenterPath}`,
|
|
1164
|
+
`Onboarding primitive: ${result.onboardingPath}`
|
|
1165
|
+
]
|
|
1166
|
+
)
|
|
1167
|
+
);
|
|
1168
|
+
var onboardingCmd = program.command("onboarding").description("Manage onboarding primitive lifecycle");
|
|
1169
|
+
addWorkspaceOption(
|
|
1170
|
+
onboardingCmd.command("show <onboardingPath>").description("Show one onboarding primitive").option("--json", "Emit structured JSON output")
|
|
1171
|
+
).action(
|
|
1172
|
+
(onboardingPath, opts) => runCommand(
|
|
1173
|
+
opts,
|
|
1174
|
+
() => {
|
|
1175
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1176
|
+
const onboarding = store_exports.read(workspacePath, onboardingPath);
|
|
1177
|
+
if (!onboarding) throw new Error(`Onboarding primitive not found: ${onboardingPath}`);
|
|
1178
|
+
if (onboarding.type !== "onboarding") throw new Error(`Target is not onboarding primitive: ${onboardingPath}`);
|
|
1179
|
+
return { onboarding };
|
|
1180
|
+
},
|
|
1181
|
+
(result) => [
|
|
1182
|
+
`Onboarding: ${result.onboarding.path}`,
|
|
1183
|
+
`Status: ${String(result.onboarding.fields.status)}`,
|
|
1184
|
+
`Actor: ${String(result.onboarding.fields.actor)}`
|
|
1185
|
+
]
|
|
1186
|
+
)
|
|
1187
|
+
);
|
|
1188
|
+
addWorkspaceOption(
|
|
1189
|
+
onboardingCmd.command("update <onboardingPath>").description("Update onboarding lifecycle status").requiredOption("--status <status>", "active|paused|completed").option("-a, --actor <name>", "Actor", DEFAULT_ACTOR).option("--json", "Emit structured JSON output")
|
|
1190
|
+
).action(
|
|
1191
|
+
(onboardingPath, opts) => runCommand(
|
|
1192
|
+
opts,
|
|
1193
|
+
() => {
|
|
1194
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1195
|
+
return {
|
|
1196
|
+
onboarding: onboard_exports.updateOnboardingStatus(
|
|
1197
|
+
workspacePath,
|
|
1198
|
+
onboardingPath,
|
|
1199
|
+
normalizeOnboardingStatus(opts.status),
|
|
1200
|
+
opts.actor
|
|
1201
|
+
)
|
|
1202
|
+
};
|
|
1203
|
+
},
|
|
1204
|
+
(result) => [`Updated onboarding: ${result.onboarding.path} [${String(result.onboarding.fields.status)}]`]
|
|
1205
|
+
)
|
|
1206
|
+
);
|
|
1207
|
+
var mcpCmd = program.command("mcp").description("Run Workgraph MCP server");
|
|
1208
|
+
addWorkspaceOption(
|
|
1209
|
+
mcpCmd.command("serve").description("Serve stdio MCP tools/resources for this workspace").option("-a, --actor <name>", "Default actor for MCP write tools", DEFAULT_ACTOR).option("--read-only", "Disable all MCP write tools")
|
|
1210
|
+
).action(async (opts) => {
|
|
1211
|
+
const workspacePath = resolveWorkspacePath(opts);
|
|
1212
|
+
console.error(`Starting MCP server for workspace: ${workspacePath}`);
|
|
1213
|
+
await mcp_server_exports.startWorkgraphMcpServer({
|
|
1214
|
+
workspacePath,
|
|
1215
|
+
defaultActor: opts.actor,
|
|
1216
|
+
readOnly: !!opts.readOnly
|
|
1217
|
+
});
|
|
1218
|
+
});
|
|
1219
|
+
await program.parseAsync();
|
|
605
1220
|
function addWorkspaceOption(command) {
|
|
606
1221
|
return command.option("-w, --workspace <path>", "Workgraph workspace path").option("--vault <path>", "Alias for --workspace").option("--shared-vault <path>", "Shared vault path (e.g. mounted via Tailscale)");
|
|
607
1222
|
}
|
|
@@ -610,21 +1225,82 @@ function resolveWorkspacePath(opts) {
|
|
|
610
1225
|
if (explicit) return path.resolve(explicit);
|
|
611
1226
|
if (process.env.WORKGRAPH_SHARED_VAULT) return path.resolve(process.env.WORKGRAPH_SHARED_VAULT);
|
|
612
1227
|
if (process.env.WORKGRAPH_PATH) return path.resolve(process.env.WORKGRAPH_PATH);
|
|
613
|
-
if (process.env.CLAWVAULT_PATH) return path.resolve(process.env.CLAWVAULT_PATH);
|
|
614
1228
|
return process.cwd();
|
|
615
1229
|
}
|
|
1230
|
+
function parseSetPairs(pairs) {
|
|
1231
|
+
const fields = {};
|
|
1232
|
+
for (const pair of pairs) {
|
|
1233
|
+
const eqIdx = String(pair).indexOf("=");
|
|
1234
|
+
if (eqIdx === -1) continue;
|
|
1235
|
+
const key = String(pair).slice(0, eqIdx).trim();
|
|
1236
|
+
const raw = String(pair).slice(eqIdx + 1).trim();
|
|
1237
|
+
if (!key) continue;
|
|
1238
|
+
fields[key] = parseScalar(raw);
|
|
1239
|
+
}
|
|
1240
|
+
return fields;
|
|
1241
|
+
}
|
|
616
1242
|
function csv(value) {
|
|
617
1243
|
if (!value) return void 0;
|
|
618
1244
|
return String(value).split(",").map((s) => s.trim()).filter(Boolean);
|
|
619
1245
|
}
|
|
1246
|
+
function installNamedIntegration(workspacePath, integrationName, opts) {
|
|
1247
|
+
return integration_exports.installIntegration(workspacePath, integrationName, {
|
|
1248
|
+
actor: opts.actor,
|
|
1249
|
+
owner: opts.owner,
|
|
1250
|
+
title: opts.title,
|
|
1251
|
+
sourceUrl: opts.sourceUrl,
|
|
1252
|
+
force: !!opts.force
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
function renderInstalledIntegrationResult(result) {
|
|
1256
|
+
return [
|
|
1257
|
+
`${result.replacedExisting ? "Updated" : "Installed"} ${result.provider} integration skill: ${result.skill.path}`,
|
|
1258
|
+
`Source: ${result.sourceUrl}`,
|
|
1259
|
+
`Status: ${String(result.skill.fields.status)}`
|
|
1260
|
+
];
|
|
1261
|
+
}
|
|
1262
|
+
function parseScalar(value) {
|
|
1263
|
+
if (value === "true") return true;
|
|
1264
|
+
if (value === "false") return false;
|
|
1265
|
+
if (value === "null") return null;
|
|
1266
|
+
if (value === "") return "";
|
|
1267
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) return Number(value);
|
|
1268
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
1269
|
+
const inner = value.slice(1, -1).trim();
|
|
1270
|
+
if (!inner) return [];
|
|
1271
|
+
return inner.split(",").map((item) => parseScalar(item.trim()));
|
|
1272
|
+
}
|
|
1273
|
+
if (value.includes(",")) {
|
|
1274
|
+
return value.split(",").map((item) => parseScalar(item.trim()));
|
|
1275
|
+
}
|
|
1276
|
+
try {
|
|
1277
|
+
return JSON.parse(value);
|
|
1278
|
+
} catch {
|
|
1279
|
+
return value;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
function normalizeRunStatus(status) {
|
|
1283
|
+
const normalized = String(status).toLowerCase();
|
|
1284
|
+
if (normalized === "running" || normalized === "succeeded" || normalized === "failed" || normalized === "cancelled") {
|
|
1285
|
+
return normalized;
|
|
1286
|
+
}
|
|
1287
|
+
throw new Error(`Invalid run status "${status}". Expected running|succeeded|failed|cancelled.`);
|
|
1288
|
+
}
|
|
1289
|
+
function normalizeOnboardingStatus(status) {
|
|
1290
|
+
const normalized = String(status).toLowerCase();
|
|
1291
|
+
if (normalized === "active" || normalized === "paused" || normalized === "completed") {
|
|
1292
|
+
return normalized;
|
|
1293
|
+
}
|
|
1294
|
+
throw new Error(`Invalid onboarding status "${status}". Expected active|paused|completed.`);
|
|
1295
|
+
}
|
|
620
1296
|
function wantsJson(opts) {
|
|
621
1297
|
if (opts.json) return true;
|
|
622
1298
|
if (process.env.WORKGRAPH_JSON === "1") return true;
|
|
623
1299
|
return false;
|
|
624
1300
|
}
|
|
625
|
-
function runCommand(opts, action, renderText) {
|
|
1301
|
+
async function runCommand(opts, action, renderText) {
|
|
626
1302
|
try {
|
|
627
|
-
const result = action();
|
|
1303
|
+
const result = await action();
|
|
628
1304
|
if (wantsJson(opts)) {
|
|
629
1305
|
console.log(JSON.stringify({ ok: true, data: result }, null, 2));
|
|
630
1306
|
return;
|