@versatly/workgraph 1.1.0 → 1.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/dist/cli.js CHANGED
@@ -11,9 +11,10 @@ import {
11
11
  onboard_exports,
12
12
  search_qmd_adapter_exports,
13
13
  skill_exports,
14
+ swarm_exports,
14
15
  trigger_exports,
15
16
  workspace_exports
16
- } from "./chunk-TOFSHG5S.js";
17
+ } from "./chunk-NGRQ6T4O.js";
17
18
  import {
18
19
  autonomy_exports,
19
20
  dispatch_exports,
@@ -29,7 +30,7 @@ import {
29
30
  thread_audit_exports,
30
31
  thread_exports,
31
32
  trigger_engine_exports
32
- } from "./chunk-OTSECVE5.js";
33
+ } from "./chunk-BJVBE7F4.js";
33
34
 
34
35
  // src/cli.ts
35
36
  import fs from "fs";
@@ -1898,6 +1899,85 @@ addWorkspaceOption(
1898
1899
  readOnly: !!opts.readOnly
1899
1900
  });
1900
1901
  });
1902
+ var swarmCmd = program.command("swarm").description("Decompose goals into tasks and orchestrate agent swarms");
1903
+ addWorkspaceOption(
1904
+ swarmCmd.command("deploy <planFile>").description("Deploy a swarm plan (JSON) into the workspace as threads").option("-a, --actor <name>", "Actor name", DEFAULT_ACTOR).option("--json", "Emit structured JSON output")
1905
+ ).action(
1906
+ (planFile, opts) => runCommand(
1907
+ opts,
1908
+ () => {
1909
+ const workspacePath = resolveWorkspacePath(opts);
1910
+ const planPath = path.resolve(planFile);
1911
+ const planData = JSON.parse(fs.readFileSync(planPath, "utf-8"));
1912
+ return swarm_exports.deployPlan(workspacePath, planData, opts.actor);
1913
+ },
1914
+ (result) => [
1915
+ `Swarm deployed: ${result.spaceSlug}`,
1916
+ `Threads: ${result.threadPaths.length}`,
1917
+ `Status: ${result.status}`
1918
+ ]
1919
+ )
1920
+ );
1921
+ addWorkspaceOption(
1922
+ swarmCmd.command("status <spaceSlug>").description("Show swarm progress").option("--json", "Emit structured JSON output")
1923
+ ).action(
1924
+ (spaceSlug, opts) => runCommand(
1925
+ opts,
1926
+ () => swarm_exports.getSwarmStatus(resolveWorkspacePath(opts), spaceSlug),
1927
+ (result) => [
1928
+ `Swarm: ${result.deployment.spaceSlug} [${result.deployment.status}]`,
1929
+ `Progress: ${result.done}/${result.total} (${result.percentComplete}%)`,
1930
+ `Claimed: ${result.claimed} | Open: ${result.open} | Blocked: ${result.blocked}`,
1931
+ `Ready to claim: ${result.readyToClaim}`
1932
+ ]
1933
+ )
1934
+ );
1935
+ addWorkspaceOption(
1936
+ swarmCmd.command("claim <spaceSlug>").description("Claim the next available task in a swarm").option("-a, --actor <name>", "Worker agent name", DEFAULT_ACTOR).option("--json", "Emit structured JSON output")
1937
+ ).action(
1938
+ (spaceSlug, opts) => runCommand(
1939
+ opts,
1940
+ () => {
1941
+ const result = swarm_exports.workerClaim(resolveWorkspacePath(opts), spaceSlug, opts.actor);
1942
+ if (!result) return { claimed: false, message: "No tasks available" };
1943
+ return { claimed: true, path: result.path, title: result.fields.title };
1944
+ },
1945
+ (result) => result.claimed ? [`Claimed: ${result.path} \u2014 ${result.title}`] : ["No tasks available to claim"]
1946
+ )
1947
+ );
1948
+ addWorkspaceOption(
1949
+ swarmCmd.command("complete <threadPath>").description("Mark a swarm task as done with result").option("-a, --actor <name>", "Worker agent name", DEFAULT_ACTOR).requiredOption("--result <text>", "Result text (or @file to read from file)").option("--json", "Emit structured JSON output")
1950
+ ).action(
1951
+ (threadPath, opts) => runCommand(
1952
+ opts,
1953
+ () => {
1954
+ let resultText = opts.result;
1955
+ if (resultText.startsWith("@")) {
1956
+ resultText = fs.readFileSync(resultText.slice(1), "utf-8");
1957
+ }
1958
+ return swarm_exports.workerComplete(resolveWorkspacePath(opts), threadPath, opts.actor, resultText);
1959
+ },
1960
+ (result) => [`Completed: ${result.path}`]
1961
+ )
1962
+ );
1963
+ addWorkspaceOption(
1964
+ swarmCmd.command("synthesize <spaceSlug>").description("Merge all completed task results into a single document").option("-o, --output <file>", "Output file path").option("--json", "Emit structured JSON output")
1965
+ ).action(
1966
+ (spaceSlug, opts) => runCommand(
1967
+ opts,
1968
+ () => {
1969
+ const result = swarm_exports.synthesize(resolveWorkspacePath(opts), spaceSlug);
1970
+ if (opts.output) {
1971
+ fs.writeFileSync(path.resolve(opts.output), result.markdown);
1972
+ }
1973
+ return result;
1974
+ },
1975
+ (result) => [
1976
+ `Synthesized: ${result.completedCount}/${result.totalCount} tasks`,
1977
+ opts.output ? `Written to: ${opts.output}` : result.markdown
1978
+ ]
1979
+ )
1980
+ );
1901
1981
  await program.parseAsync();
1902
1982
  function addWorkspaceOption(command) {
1903
1983
  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)").option("--dry-run", "Execute against a temporary workspace copy and discard changes");
package/dist/index.d.ts CHANGED
@@ -614,11 +614,11 @@ interface WriteSkillOptions {
614
614
  version?: string;
615
615
  status?: 'draft' | 'proposed' | 'active' | 'deprecated' | 'archived';
616
616
  distribution?: string;
617
- tailscalePath?: string;
618
617
  reviewers?: string[];
619
618
  tags?: string[];
620
619
  dependsOn?: string[];
621
620
  expectedUpdatedAt?: string;
621
+ tailscalePath?: string;
622
622
  }
623
623
  interface ProposeSkillOptions {
624
624
  proposalThread?: string;
@@ -1448,6 +1448,144 @@ declare function parseCronExpression(expression: string): CronSchedule;
1448
1448
  declare function matchesCronSchedule(schedule: CronSchedule, date: Date): boolean;
1449
1449
  declare function nextCronMatch(scheduleOrExpression: CronSchedule | string, after: Date, maxSearchMinutes?: number): Date | null;
1450
1450
 
1451
+ /**
1452
+ * WorkGraph Swarm — Decompose goals into hundreds of tasks,
1453
+ * spawn agent containers to claim and complete them, merge results.
1454
+ *
1455
+ * Architecture:
1456
+ * 1. Planner: Takes a goal → decomposes into N threads with dependencies
1457
+ * 2. Orchestrator: Spawns containers, each runs a worker that claims threads
1458
+ * 3. Worker: Claims a thread, does work, writes result, marks done
1459
+ * 4. Synthesizer: Watches for completion, merges results
1460
+ */
1461
+
1462
+ interface SwarmGoal {
1463
+ title: string;
1464
+ description: string;
1465
+ outputFormat?: 'markdown' | 'json' | 'code';
1466
+ maxTasks?: number;
1467
+ maxConcurrent?: number;
1468
+ tags?: string[];
1469
+ }
1470
+ interface SwarmTask {
1471
+ title: string;
1472
+ description: string;
1473
+ priority: 'critical' | 'high' | 'medium' | 'low';
1474
+ dependsOn?: string[];
1475
+ estimatedMinutes?: number;
1476
+ outputType?: string;
1477
+ tags?: string[];
1478
+ }
1479
+ interface SwarmPlan {
1480
+ goal: SwarmGoal;
1481
+ tasks: SwarmTask[];
1482
+ phases: SwarmPhase[];
1483
+ createdAt: string;
1484
+ estimatedTotalMinutes: number;
1485
+ }
1486
+ interface SwarmPhase {
1487
+ name: string;
1488
+ description: string;
1489
+ taskIndices: number[];
1490
+ parallel: boolean;
1491
+ }
1492
+ interface SwarmDeployment {
1493
+ planPath: string;
1494
+ workspacePath: string;
1495
+ threadPaths: string[];
1496
+ spaceSlug: string;
1497
+ createdAt: string;
1498
+ status: 'deployed' | 'running' | 'completing' | 'done' | 'failed';
1499
+ }
1500
+ interface SwarmStatus {
1501
+ deployment: SwarmDeployment;
1502
+ total: number;
1503
+ claimed: number;
1504
+ done: number;
1505
+ blocked: number;
1506
+ open: number;
1507
+ readyToClaim: number;
1508
+ percentComplete: number;
1509
+ threads: Array<{
1510
+ path: string;
1511
+ title: string;
1512
+ status: string;
1513
+ owner?: string;
1514
+ priority: string;
1515
+ }>;
1516
+ }
1517
+ /**
1518
+ * Generate a swarm plan from a goal description.
1519
+ * This creates the plan structure — call deployPlan() to create actual threads.
1520
+ *
1521
+ * In production, pipe goal through an LLM for decomposition.
1522
+ * This function provides the structured output format the LLM should produce.
1523
+ */
1524
+ declare function createPlanTemplate(goal: SwarmGoal): SwarmPlan;
1525
+ /**
1526
+ * Validate a swarm plan for internal consistency.
1527
+ */
1528
+ declare function validatePlan(plan: SwarmPlan): {
1529
+ valid: boolean;
1530
+ errors: string[];
1531
+ };
1532
+ /**
1533
+ * Deploy a swarm plan into a WorkGraph workspace.
1534
+ * Creates a space for the swarm and threads for each task.
1535
+ * Dependencies are encoded as wiki-links in thread bodies.
1536
+ */
1537
+ declare function deployPlan(workspacePath: string, plan: SwarmPlan, actor: string): SwarmDeployment;
1538
+ /**
1539
+ * Get the current status of a swarm deployment.
1540
+ */
1541
+ declare function getSwarmStatus(workspacePath: string, spaceSlug: string): SwarmStatus;
1542
+ /**
1543
+ * Worker claims the next available task in a swarm.
1544
+ * Returns the thread to work on, or null if nothing available.
1545
+ */
1546
+ declare function workerClaim(workspacePath: string, spaceSlug: string, agent: string): PrimitiveInstance | null;
1547
+ /**
1548
+ * Worker completes a task, writing result to the thread body.
1549
+ */
1550
+ declare function workerComplete(workspacePath: string, threadPath: string, agent: string, result: string): PrimitiveInstance;
1551
+ /**
1552
+ * Worker loop: claim → work → complete → repeat until no tasks left.
1553
+ * The workFn receives the thread and returns the result string.
1554
+ */
1555
+ declare function workerLoop(workspacePath: string, spaceSlug: string, agent: string, workFn: (thread: PrimitiveInstance) => Promise<string>, options?: {
1556
+ maxTasks?: number;
1557
+ delayMs?: number;
1558
+ }): Promise<{
1559
+ completed: number;
1560
+ errors: number;
1561
+ }>;
1562
+ /**
1563
+ * Collect all completed task results from a swarm into a single document.
1564
+ */
1565
+ declare function synthesize(workspacePath: string, spaceSlug: string): {
1566
+ markdown: string;
1567
+ completedCount: number;
1568
+ totalCount: number;
1569
+ };
1570
+
1571
+ type swarm_SwarmDeployment = SwarmDeployment;
1572
+ type swarm_SwarmGoal = SwarmGoal;
1573
+ type swarm_SwarmPhase = SwarmPhase;
1574
+ type swarm_SwarmPlan = SwarmPlan;
1575
+ type swarm_SwarmStatus = SwarmStatus;
1576
+ type swarm_SwarmTask = SwarmTask;
1577
+ declare const swarm_createPlanTemplate: typeof createPlanTemplate;
1578
+ declare const swarm_deployPlan: typeof deployPlan;
1579
+ declare const swarm_getSwarmStatus: typeof getSwarmStatus;
1580
+ declare const swarm_synthesize: typeof synthesize;
1581
+ declare const swarm_validatePlan: typeof validatePlan;
1582
+ declare const swarm_workerClaim: typeof workerClaim;
1583
+ declare const swarm_workerComplete: typeof workerComplete;
1584
+ declare const swarm_workerLoop: typeof workerLoop;
1585
+ declare namespace swarm {
1586
+ export { type swarm_SwarmDeployment as SwarmDeployment, type swarm_SwarmGoal as SwarmGoal, type swarm_SwarmPhase as SwarmPhase, type swarm_SwarmPlan as SwarmPlan, type swarm_SwarmStatus as SwarmStatus, type swarm_SwarmTask as SwarmTask, swarm_createPlanTemplate as createPlanTemplate, swarm_deployPlan as deployPlan, swarm_getSwarmStatus as getSwarmStatus, swarm_synthesize as synthesize, swarm_validatePlan as validatePlan, swarm_workerClaim as workerClaim, swarm_workerComplete as workerComplete, swarm_workerLoop as workerLoop };
1587
+ }
1588
+
1451
1589
  type DoctorSeverity = 'warning' | 'error';
1452
1590
  interface DoctorIssue {
1453
1591
  code: string;
@@ -1780,4 +1918,4 @@ declare class CursorCloudAdapter implements DispatchAdapter {
1780
1918
  execute(input: DispatchAdapterExecutionInput): Promise<DispatchAdapterExecutionResult>;
1781
1919
  }
1782
1920
 
1783
- export { type CronField, type CronSchedule, CursorCloudAdapter, type DispatchAdapter, type DispatchAdapterCreateInput, type DispatchAdapterExecutionInput, type DispatchAdapterExecutionResult, type DispatchAdapterLogEntry, type DispatchAdapterRunStatus, type DispatchRun, type FieldDefinition, type InstallSkillIntegrationOptions, type InstallSkillIntegrationResult, type LedgerChainState, type LedgerEntry, type LedgerIndex, type LedgerOp, type PolicyParty, type PolicyRegistry, type PrimitiveInstance, type PrimitiveQueryFilters, type PrimitiveTypeDefinition, type Registry, type RunStatus, type SkillIntegrationProvider, THREAD_STATUS_TRANSITIONS, type ThreadStatus, type WorkgraphBrief, type WorkgraphLensDescriptor, type WorkgraphLensId, type WorkgraphLensItem, type WorkgraphLensOptions, type WorkgraphLensResult, type WorkgraphLensSection, type WorkgraphMaterializeLensOptions, type WorkgraphMaterializedLensResult, type WorkgraphStatusSnapshot, type WorkgraphWorkspaceConfig, agent, autonomy, autonomyDaemon, bases, board, claimLease, clawdapus, commandCenter, index as diagnostics, dispatch, fetchSkillMarkdownFromUrl, gate, graph, installSkillIntegration, integration, ledger, lens, matchesCronSchedule, nextCronMatch, onboard, orientation, parseCronExpression, policy, query, registry, searchQmdAdapter, skill, store, thread, threadAudit, trigger, triggerEngine, workspace };
1921
+ export { type CronField, type CronSchedule, CursorCloudAdapter, type DispatchAdapter, type DispatchAdapterCreateInput, type DispatchAdapterExecutionInput, type DispatchAdapterExecutionResult, type DispatchAdapterLogEntry, type DispatchAdapterRunStatus, type DispatchRun, type FieldDefinition, type InstallSkillIntegrationOptions, type InstallSkillIntegrationResult, type LedgerChainState, type LedgerEntry, type LedgerIndex, type LedgerOp, type PolicyParty, type PolicyRegistry, type PrimitiveInstance, type PrimitiveQueryFilters, type PrimitiveTypeDefinition, type Registry, type RunStatus, type SkillIntegrationProvider, THREAD_STATUS_TRANSITIONS, type ThreadStatus, type WorkgraphBrief, type WorkgraphLensDescriptor, type WorkgraphLensId, type WorkgraphLensItem, type WorkgraphLensOptions, type WorkgraphLensResult, type WorkgraphLensSection, type WorkgraphMaterializeLensOptions, type WorkgraphMaterializedLensResult, type WorkgraphStatusSnapshot, type WorkgraphWorkspaceConfig, agent, autonomy, autonomyDaemon, bases, board, claimLease, clawdapus, commandCenter, index as diagnostics, dispatch, fetchSkillMarkdownFromUrl, gate, graph, installSkillIntegration, integration, ledger, lens, matchesCronSchedule, nextCronMatch, onboard, orientation, parseCronExpression, policy, query, registry, searchQmdAdapter, skill, store, swarm, thread, threadAudit, trigger, triggerEngine, workspace };
package/dist/index.js CHANGED
@@ -13,9 +13,10 @@ import {
13
13
  onboard_exports,
14
14
  search_qmd_adapter_exports,
15
15
  skill_exports,
16
+ swarm_exports,
16
17
  trigger_exports,
17
18
  workspace_exports
18
- } from "./chunk-TOFSHG5S.js";
19
+ } from "./chunk-NGRQ6T4O.js";
19
20
  import {
20
21
  CursorCloudAdapter,
21
22
  THREAD_STATUS_TRANSITIONS,
@@ -37,7 +38,7 @@ import {
37
38
  thread_audit_exports,
38
39
  thread_exports,
39
40
  trigger_engine_exports
40
- } from "./chunk-OTSECVE5.js";
41
+ } from "./chunk-BJVBE7F4.js";
41
42
  export {
42
43
  CursorCloudAdapter,
43
44
  THREAD_STATUS_TRANSITIONS,
@@ -70,6 +71,7 @@ export {
70
71
  search_qmd_adapter_exports as searchQmdAdapter,
71
72
  skill_exports as skill,
72
73
  store_exports as store,
74
+ swarm_exports as swarm,
73
75
  thread_exports as thread,
74
76
  thread_audit_exports as threadAudit,
75
77
  trigger_exports as trigger,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createWorkgraphMcpServer,
3
3
  startWorkgraphMcpServer
4
- } from "./chunk-OTSECVE5.js";
4
+ } from "./chunk-BJVBE7F4.js";
5
5
  export {
6
6
  createWorkgraphMcpServer,
7
7
  startWorkgraphMcpServer
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatly/workgraph",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Agent-first workgraph workspace for multi-agent coordination with dynamic primitives, append-only ledger, and markdown-native storage.",
5
5
  "workspaces": [
6
6
  "packages/*"