agent-contracts 0.7.1 → 0.8.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/index.js CHANGED
@@ -58424,13 +58424,21 @@ var TaskSchema = z6.object({
58424
58424
 
58425
58425
  // src/schema/tool.ts
58426
58426
  import { z as z7 } from "zod";
58427
+ var CommandSchema = z7.object({
58428
+ command: z7.string(),
58429
+ category: z7.string(),
58430
+ reads: z7.array(z7.string()).default([]),
58431
+ writes: z7.array(z7.string()).default([]),
58432
+ purpose: z7.string().optional()
58433
+ });
58427
58434
  var ToolSchema = z7.object({
58428
58435
  kind: z7.string(),
58429
58436
  description: z7.string().optional(),
58430
58437
  input_artifacts: z7.array(z7.string()).default([]),
58431
58438
  output_artifacts: z7.array(z7.string()).default([]),
58432
58439
  invokable_by: z7.array(z7.string()),
58433
- side_effects: z7.array(z7.string()).default([])
58440
+ side_effects: z7.array(z7.string()).default([]),
58441
+ commands: z7.array(CommandSchema).default([])
58434
58442
  }).passthrough();
58435
58443
 
58436
58444
  // src/schema/validation.ts
@@ -58446,23 +58454,38 @@ var ValidationSchema = z8.object({
58446
58454
 
58447
58455
  // src/schema/workflow.ts
58448
58456
  import { z as z9 } from "zod";
58457
+ var RetrySchema = z9.object({
58458
+ condition: z9.string(),
58459
+ fix_task: z9.string(),
58460
+ revalidate_task: z9.string().optional()
58461
+ });
58462
+ var ExternalParticipantSchema = z9.object({
58463
+ id: z9.string(),
58464
+ kind: z9.enum(["actor", "participant"]),
58465
+ label: z9.string(),
58466
+ description: z9.string().optional()
58467
+ });
58449
58468
  var WorkflowHandoffStepSchema = z9.object({
58450
58469
  type: z9.literal("handoff"),
58451
58470
  description: z9.string().optional(),
58452
58471
  handoff_kind: z9.string(),
58453
58472
  task: z9.string().optional(),
58454
- from_agent: z9.string().optional()
58473
+ from_agent: z9.string().optional(),
58474
+ group: z9.string().optional(),
58475
+ retry: RetrySchema.optional()
58455
58476
  }).passthrough();
58456
58477
  var WorkflowValidationStepSchema = z9.object({
58457
58478
  type: z9.literal("validation"),
58458
58479
  description: z9.string().optional(),
58459
- validation: z9.string()
58480
+ validation: z9.string(),
58481
+ group: z9.string().optional()
58460
58482
  }).passthrough();
58461
58483
  var WorkflowDecisionStepSchema = z9.object({
58462
58484
  type: z9.literal("decision"),
58463
58485
  description: z9.string().optional(),
58464
58486
  on: z9.string(),
58465
- branches: z9.record(z9.string(), z9.array(z9.string()))
58487
+ branches: z9.record(z9.string(), z9.array(z9.string())),
58488
+ group: z9.string().optional()
58466
58489
  }).passthrough();
58467
58490
  var WorkflowStepSchema = z9.discriminatedUnion("type", [
58468
58491
  WorkflowHandoffStepSchema,
@@ -58473,7 +58496,8 @@ var WorkflowSchema = z9.object({
58473
58496
  description: z9.string().optional(),
58474
58497
  entry_conditions: z9.array(z9.string()).default([]),
58475
58498
  trigger: z9.string().optional(),
58476
- steps: z9.array(WorkflowStepSchema)
58499
+ steps: z9.array(WorkflowStepSchema),
58500
+ external_participants: z9.array(ExternalParticipantSchema).default([])
58477
58501
  }).passthrough();
58478
58502
 
58479
58503
  // src/schema/dsl.ts
@@ -59594,12 +59618,100 @@ var mergeIntegrityRule = {
59594
59618
  }
59595
59619
  };
59596
59620
 
59621
+ // src/linter/rules/artifact-ownership.ts
59622
+ var artifactOwnershipRule = {
59623
+ id: "artifact-ownership",
59624
+ description: "Ensure execution_step produces/reads operations are consistent with artifact producers/editors/consumers",
59625
+ run(dsl) {
59626
+ const diagnostics = [];
59627
+ for (const [taskId, task] of Object.entries(dsl.tasks)) {
59628
+ if (!task.execution_steps) continue;
59629
+ const agentId = task.target_agent;
59630
+ for (const step of task.execution_steps) {
59631
+ if (step.produces_artifact) {
59632
+ const artifact = dsl.artifacts[step.produces_artifact];
59633
+ if (artifact) {
59634
+ const canWrite = artifact.producers.includes(agentId) || artifact.editors.includes(agentId);
59635
+ if (!canWrite) {
59636
+ diagnostics.push({
59637
+ ruleId: "artifact-ownership",
59638
+ severity: "warning",
59639
+ path: `tasks.${taskId}.execution_steps`,
59640
+ message: `Agent "${agentId}" produces artifact "${step.produces_artifact}" but is not listed in its producers or editors`
59641
+ });
59642
+ }
59643
+ }
59644
+ }
59645
+ if (step.reads_artifact) {
59646
+ const artifact = dsl.artifacts[step.reads_artifact];
59647
+ if (artifact) {
59648
+ const canRead = artifact.consumers.includes(agentId) || artifact.producers.includes(agentId) || artifact.editors.includes(agentId);
59649
+ if (!canRead) {
59650
+ diagnostics.push({
59651
+ ruleId: "artifact-ownership",
59652
+ severity: "warning",
59653
+ path: `tasks.${taskId}.execution_steps`,
59654
+ message: `Agent "${agentId}" reads artifact "${step.reads_artifact}" but is not listed in its producers, editors, or consumers`
59655
+ });
59656
+ }
59657
+ }
59658
+ }
59659
+ }
59660
+ }
59661
+ return diagnostics;
59662
+ }
59663
+ };
59664
+
59665
+ // src/linter/rules/tool-commands.ts
59666
+ var toolCommandsRule = {
59667
+ id: "tool-commands",
59668
+ description: "Validate tool commands: reads/writes reference existing artifacts; writes align with output_artifacts",
59669
+ run(dsl) {
59670
+ const diagnostics = [];
59671
+ for (const [toolId, tool] of Object.entries(dsl.tools)) {
59672
+ for (const cmd of tool.commands) {
59673
+ for (const ref of cmd.reads) {
59674
+ if (!dsl.artifacts[ref]) {
59675
+ diagnostics.push({
59676
+ ruleId: "tool-commands",
59677
+ severity: "error",
59678
+ path: `tools.${toolId}.commands`,
59679
+ message: `Command "${cmd.command}" reads artifact "${ref}" which does not exist`
59680
+ });
59681
+ }
59682
+ }
59683
+ for (const ref of cmd.writes) {
59684
+ if (!dsl.artifacts[ref]) {
59685
+ diagnostics.push({
59686
+ ruleId: "tool-commands",
59687
+ severity: "error",
59688
+ path: `tools.${toolId}.commands`,
59689
+ message: `Command "${cmd.command}" writes artifact "${ref}" which does not exist`
59690
+ });
59691
+ }
59692
+ if (dsl.artifacts[ref] && !tool.output_artifacts.includes(ref)) {
59693
+ diagnostics.push({
59694
+ ruleId: "tool-commands",
59695
+ severity: "warning",
59696
+ path: `tools.${toolId}.commands`,
59697
+ message: `Command "${cmd.command}" writes artifact "${ref}" but tool's output_artifacts does not include it`
59698
+ });
59699
+ }
59700
+ }
59701
+ }
59702
+ }
59703
+ return diagnostics;
59704
+ }
59705
+ };
59706
+
59597
59707
  // src/linter/linter.ts
59598
59708
  var builtinRules = [
59599
59709
  validationCoverageRule,
59600
59710
  toolExecutionRule,
59601
59711
  taskAgentBindingRule,
59602
- mergeIntegrityRule
59712
+ mergeIntegrityRule,
59713
+ artifactOwnershipRule,
59714
+ toolCommandsRule
59603
59715
  ];
59604
59716
  function lint(dsl, rules = builtinRules) {
59605
59717
  const diagnostics = [];
@@ -60526,40 +60638,63 @@ function agentAlias(id, agent) {
60526
60638
  }
60527
60639
  function collectReferencedIds(workflow, dsl, relatedTasks) {
60528
60640
  const agents = /* @__PURE__ */ new Set();
60641
+ const auditAgents = /* @__PURE__ */ new Set();
60529
60642
  const tools = /* @__PURE__ */ new Set();
60530
60643
  const artifacts = /* @__PURE__ */ new Set();
60531
60644
  const taskMap = /* @__PURE__ */ new Map();
60532
60645
  for (const t3 of relatedTasks) taskMap.set(t3.id, t3);
60533
60646
  for (const step of workflow.steps) {
60534
60647
  if (step.type === "handoff") {
60535
- if (step.from_agent) agents.add(step.from_agent);
60648
+ if (step.from_agent) addAgent(step.from_agent);
60536
60649
  if (step.task) {
60537
60650
  const task = taskMap.get(step.task);
60538
60651
  if (task) {
60539
- agents.add(task.target_agent);
60652
+ addAgent(task.target_agent);
60540
60653
  for (const es of task.execution_steps ?? []) {
60541
60654
  collectExecutionStepIds(es, tools, artifacts);
60542
60655
  }
60543
60656
  }
60544
60657
  }
60658
+ if (step.retry) {
60659
+ const fixTask = taskMap.get(step.retry.fix_task);
60660
+ if (fixTask) {
60661
+ addAgent(fixTask.target_agent);
60662
+ for (const es of fixTask.execution_steps ?? []) {
60663
+ collectExecutionStepIds(es, tools, artifacts);
60664
+ }
60665
+ }
60666
+ if (step.retry.revalidate_task) {
60667
+ const revalTask = taskMap.get(step.retry.revalidate_task);
60668
+ if (revalTask) {
60669
+ addAgent(revalTask.target_agent);
60670
+ }
60671
+ }
60672
+ }
60545
60673
  } else if (step.type === "validation") {
60546
60674
  const val = dsl.validations[step.validation];
60547
60675
  if (val) {
60548
- if (val.executor_type === "agent") agents.add(val.executor);
60676
+ if (val.executor_type === "agent") addAgent(val.executor);
60549
60677
  else tools.add(val.executor);
60550
60678
  artifacts.add(val.target_artifact);
60551
60679
  }
60552
- } else if (step.type === "decision") {
60553
60680
  }
60554
60681
  }
60555
- return { agents, tools, artifacts };
60682
+ function addAgent(agentId) {
60683
+ const agent = dsl.agents[agentId];
60684
+ if (agent?.mode === "read-only") {
60685
+ auditAgents.add(agentId);
60686
+ } else {
60687
+ agents.add(agentId);
60688
+ }
60689
+ }
60690
+ return { agents, auditAgents, tools, artifacts };
60556
60691
  }
60557
60692
  function collectExecutionStepIds(es, tools, artifacts) {
60558
60693
  if (es.uses_tool) tools.add(es.uses_tool);
60559
60694
  if (es.produces_artifact) artifacts.add(es.produces_artifact);
60560
60695
  if (es.reads_artifact) artifacts.add(es.reads_artifact);
60561
60696
  }
60562
- function buildParticipants(ids, dsl) {
60697
+ function buildParticipants(ids, externals, dsl) {
60563
60698
  const participants = [];
60564
60699
  const usedAliases = /* @__PURE__ */ new Set();
60565
60700
  function uniqueAlias(preferred) {
@@ -60572,12 +60707,22 @@ function buildParticipants(ids, dsl) {
60572
60707
  usedAliases.add(alias);
60573
60708
  return alias;
60574
60709
  }
60710
+ for (const ep of externals) {
60711
+ const alias = uniqueAlias(sanitizeAlias(ep.id));
60712
+ participants.push({ id: ep.id, alias, label: ep.label, group: "external" });
60713
+ }
60575
60714
  for (const id of ids.agents) {
60576
60715
  const agent = dsl.agents[id];
60577
60716
  if (!agent) continue;
60578
60717
  const alias = uniqueAlias(agentAlias(id, agent));
60579
60718
  participants.push({ id, alias, label: agent.role_name, group: "agents" });
60580
60719
  }
60720
+ for (const id of ids.auditAgents) {
60721
+ const agent = dsl.agents[id];
60722
+ if (!agent) continue;
60723
+ const alias = uniqueAlias(agentAlias(id, agent));
60724
+ participants.push({ id, alias, label: agent.role_name, group: "audit" });
60725
+ }
60581
60726
  for (const id of ids.tools) {
60582
60727
  const tool = dsl.tools[id];
60583
60728
  if (!tool) continue;
@@ -60596,15 +60741,33 @@ function participantAlias(participants, id) {
60596
60741
  const p2 = participants.find((pp) => pp.id === id);
60597
60742
  return p2 ? p2.alias : sanitizeAlias(id);
60598
60743
  }
60599
- function emitParticipants(participants, lines, indent) {
60744
+ function emitParticipants(participants, externals, lines, indent) {
60600
60745
  const groups = {
60746
+ external: [],
60601
60747
  agents: [],
60748
+ audit: [],
60602
60749
  toolchain: [],
60603
60750
  artifacts: []
60604
60751
  };
60605
60752
  for (const p2 of participants) groups[p2.group].push(p2);
60753
+ const externalMap = /* @__PURE__ */ new Map();
60754
+ for (const ep of externals) externalMap.set(ep.id, ep);
60755
+ if (groups.external.length > 0) {
60756
+ lines.push(`${indent}box rgb(255,245,230) External`);
60757
+ for (const p2 of groups.external) {
60758
+ const ep = externalMap.get(p2.id);
60759
+ const keyword = ep?.kind === "actor" ? "actor" : "participant";
60760
+ if (p2.alias === p2.label) {
60761
+ lines.push(`${indent}${keyword} ${p2.alias}`);
60762
+ } else {
60763
+ lines.push(`${indent}${keyword} ${p2.alias} as ${p2.label}`);
60764
+ }
60765
+ }
60766
+ lines.push(`${indent}end`);
60767
+ }
60606
60768
  const groupConfig = [
60607
60769
  { key: "agents", label: "Agents", color: "rgb(200,220,255)" },
60770
+ { key: "audit", label: "Audit", color: "rgb(255,220,220)" },
60608
60771
  { key: "toolchain", label: "Toolchain", color: "rgb(220,255,220)" },
60609
60772
  { key: "artifacts", label: "Artifacts", color: "rgb(255,230,210)" }
60610
60773
  ];
@@ -60680,7 +60843,7 @@ function emitValidationStep(step, participants, dsl, lastFromAgent, lines, inden
60680
60843
  function emitDecisionStep(step, participants, lastFromAgent, lines, indent) {
60681
60844
  const branches = Object.entries(step.branches);
60682
60845
  if (branches.length === 0) return;
60683
- const agentAlias2 = lastFromAgent ? participantAlias(participants, lastFromAgent) : null;
60846
+ const agentAl = lastFromAgent ? participantAlias(participants, lastFromAgent) : null;
60684
60847
  for (let i3 = 0; i3 < branches.length; i3++) {
60685
60848
  const [key, values] = branches[i3];
60686
60849
  if (i3 === 0) {
@@ -60688,21 +60851,78 @@ function emitDecisionStep(step, participants, lastFromAgent, lines, indent) {
60688
60851
  } else {
60689
60852
  lines.push(`${indent}else ${key}`);
60690
60853
  }
60691
- if (agentAlias2) {
60692
- lines.push(`${indent} Note over ${agentAlias2}: ${values.join(", ")}`);
60693
- } else {
60694
- lines.push(`${indent} Note right of ${participantAlias(participants, [.../* @__PURE__ */ new Set()].join(""))}: ${values.join(", ")}`);
60854
+ if (agentAl) {
60855
+ lines.push(`${indent} Note over ${agentAl}: ${values.join(", ")}`);
60695
60856
  }
60696
60857
  }
60697
60858
  lines.push(`${indent}end`);
60698
60859
  }
60860
+ function emitRetryBlock(step, participants, dsl, relatedTasks, lines, indent) {
60861
+ const retry = step.retry;
60862
+ if (!retry) return;
60863
+ const taskMap = /* @__PURE__ */ new Map();
60864
+ for (const t3 of relatedTasks) taskMap.set(t3.id, t3);
60865
+ lines.push(`${indent}opt ${retry.condition}`);
60866
+ const innerIndent = indent + " ";
60867
+ const fixTask = taskMap.get(retry.fix_task);
60868
+ if (fixTask) {
60869
+ const fromAlias = step.from_agent ? participantAlias(participants, step.from_agent) : null;
60870
+ const targetAlias = participantAlias(participants, fixTask.target_agent);
60871
+ if (fromAlias) {
60872
+ lines.push(`${innerIndent}${fromAlias}->>${targetAlias}: fix ${retry.fix_task}`);
60873
+ }
60874
+ for (const es of fixTask.execution_steps ?? []) {
60875
+ emitExecutionStep(es, targetAlias, participants, lines, innerIndent);
60876
+ }
60877
+ if (fromAlias) {
60878
+ lines.push(`${innerIndent}${targetAlias}-->>${fromAlias}: ${fixTask.result_handoff}`);
60879
+ }
60880
+ }
60881
+ if (retry.revalidate_task) {
60882
+ const revalTask = taskMap.get(retry.revalidate_task);
60883
+ if (revalTask) {
60884
+ const fromAlias = step.from_agent ? participantAlias(participants, step.from_agent) : null;
60885
+ const revalAlias = participantAlias(participants, revalTask.target_agent);
60886
+ if (fromAlias) {
60887
+ lines.push(`${innerIndent}${fromAlias}->>${revalAlias}: revalidate ${retry.revalidate_task}`);
60888
+ lines.push(`${innerIndent}${revalAlias}-->>${fromAlias}: ${revalTask.result_handoff}`);
60889
+ }
60890
+ }
60891
+ }
60892
+ lines.push(`${indent}end`);
60893
+ }
60894
+ function groupSteps(steps) {
60895
+ const result = [];
60896
+ let currentGroup = null;
60897
+ for (let i3 = 0; i3 < steps.length; i3++) {
60898
+ const step = steps[i3];
60899
+ const group = "group" in step ? step.group : void 0;
60900
+ if (group) {
60901
+ if (currentGroup && currentGroup.group === group) {
60902
+ currentGroup.steps.push({ step, index: i3 });
60903
+ } else {
60904
+ if (currentGroup) result.push(currentGroup);
60905
+ currentGroup = { group, steps: [{ step, index: i3 }] };
60906
+ }
60907
+ } else {
60908
+ if (currentGroup) {
60909
+ result.push(currentGroup);
60910
+ currentGroup = null;
60911
+ }
60912
+ result.push({ group: null, steps: [{ step, index: i3 }] });
60913
+ }
60914
+ }
60915
+ if (currentGroup) result.push(currentGroup);
60916
+ return result;
60917
+ }
60699
60918
  function generateSequenceDiagram(workflow, relatedTasks, dsl) {
60700
60919
  const ids = collectReferencedIds(workflow, dsl, relatedTasks);
60701
- const participants = buildParticipants(ids, dsl);
60920
+ const externals = workflow.external_participants ?? [];
60921
+ const participants = buildParticipants(ids, externals, dsl);
60702
60922
  const lines = [];
60703
60923
  const indent = " ";
60704
60924
  lines.push("sequenceDiagram");
60705
- emitParticipants(participants, lines, indent);
60925
+ emitParticipants(participants, externals, lines, indent);
60706
60926
  lines.push("");
60707
60927
  lines.push(`${indent}rect ${hashToColor(workflow.id, 0.15, 0.95)}`);
60708
60928
  const firstP = participants[0];
@@ -60711,22 +60931,174 @@ function generateSequenceDiagram(workflow, relatedTasks, dsl) {
60711
60931
  const noteLabel = workflow.description ? `${workflow.id} \u2014 ${workflow.description}` : workflow.id;
60712
60932
  lines.push(`${indent}Note over ${firstP.alias},${lastP.alias}: ${noteLabel}`);
60713
60933
  }
60934
+ if (workflow.trigger && externals.some((ep) => ep.kind === "actor")) {
60935
+ const actor = externals.find((ep) => ep.kind === "actor");
60936
+ const actorAlias = participantAlias(participants, actor.id);
60937
+ const firstAgent = participants.find((p2) => p2.group === "agents" || p2.group === "audit");
60938
+ if (firstAgent) {
60939
+ lines.push(`${indent}${actorAlias}->>${firstAgent.alias}: ${workflow.trigger}`);
60940
+ }
60941
+ }
60714
60942
  let lastFromAgent;
60715
- for (const step of workflow.steps) {
60716
- lines.push("");
60717
- if (step.type === "handoff") {
60718
- if (step.from_agent) lastFromAgent = step.from_agent;
60719
- emitHandoffStep(step, participants, dsl, relatedTasks, lines, indent);
60720
- } else if (step.type === "validation") {
60721
- emitValidationStep(step, participants, dsl, lastFromAgent, lines, indent);
60722
- } else if (step.type === "decision") {
60723
- emitDecisionStep(step, participants, lastFromAgent, lines, indent);
60943
+ const grouped = groupSteps(workflow.steps);
60944
+ for (const g2 of grouped) {
60945
+ if (g2.group && g2.steps.length > 1) {
60946
+ lines.push("");
60947
+ lines.push(`${indent}par ${g2.group}`);
60948
+ const parIndent = indent + " ";
60949
+ for (let i3 = 0; i3 < g2.steps.length; i3++) {
60950
+ const { step } = g2.steps[i3];
60951
+ if (i3 > 0) lines.push(`${indent}and`);
60952
+ emitStep(step, participants, dsl, relatedTasks, lines, parIndent, lastFromAgent, (a3) => {
60953
+ lastFromAgent = a3;
60954
+ });
60955
+ }
60956
+ lines.push(`${indent}end`);
60957
+ } else {
60958
+ for (const { step } of g2.steps) {
60959
+ lines.push("");
60960
+ emitStep(step, participants, dsl, relatedTasks, lines, indent, lastFromAgent, (a3) => {
60961
+ lastFromAgent = a3;
60962
+ });
60963
+ }
60724
60964
  }
60725
60965
  }
60726
60966
  lines.push("");
60727
60967
  lines.push(`${indent}end`);
60728
60968
  return lines.join("\n");
60729
60969
  }
60970
+ function emitStep(step, participants, dsl, relatedTasks, lines, indent, lastFromAgent, setLastFromAgent) {
60971
+ if (step.type === "handoff") {
60972
+ if (step.from_agent) setLastFromAgent(step.from_agent);
60973
+ emitHandoffStep(step, participants, dsl, relatedTasks, lines, indent);
60974
+ if (step.retry) {
60975
+ emitRetryBlock(step, participants, dsl, relatedTasks, lines, indent);
60976
+ }
60977
+ } else if (step.type === "validation") {
60978
+ emitValidationStep(step, participants, dsl, lastFromAgent, lines, indent);
60979
+ } else if (step.type === "decision") {
60980
+ emitDecisionStep(step, participants, lastFromAgent, lines, indent);
60981
+ }
60982
+ }
60983
+
60984
+ // src/renderer/overview-flowchart.ts
60985
+ function collectPhaseOps(dsl, wfId) {
60986
+ const ctx = buildWorkflowContext(dsl, wfId);
60987
+ const wf = dsl.workflow[wfId];
60988
+ const agentOps = /* @__PURE__ */ new Map();
60989
+ const artifactOps = /* @__PURE__ */ new Map();
60990
+ const toolOps = /* @__PURE__ */ new Map();
60991
+ function addOp(map, id, op) {
60992
+ if (!map.has(id)) map.set(id, /* @__PURE__ */ new Set());
60993
+ map.get(id).add(op);
60994
+ }
60995
+ const taskMap = new Map(ctx.relatedTasks.map((t3) => [t3.id, t3]));
60996
+ for (const step of wf.steps) {
60997
+ if (step.type === "handoff") {
60998
+ if (step.from_agent) addOp(agentOps, step.from_agent, "delegate");
60999
+ if (step.task) {
61000
+ const task = taskMap.get(step.task);
61001
+ if (task) {
61002
+ addOp(agentOps, task.target_agent, "execute");
61003
+ for (const es of task.execution_steps ?? []) {
61004
+ if (es.reads_artifact) addOp(artifactOps, es.reads_artifact, "R");
61005
+ if (es.produces_artifact) addOp(artifactOps, es.produces_artifact, "W");
61006
+ if (es.uses_tool) {
61007
+ const tool = dsl.tools[es.uses_tool];
61008
+ if (tool) {
61009
+ const cats = tool.commands.map((c2) => c2.category).filter((v2, i3, a3) => a3.indexOf(v2) === i3);
61010
+ for (const cat of cats) addOp(toolOps, es.uses_tool, cat);
61011
+ if (cats.length === 0) addOp(toolOps, es.uses_tool, "\u2713");
61012
+ } else {
61013
+ addOp(toolOps, es.uses_tool, "\u2713");
61014
+ }
61015
+ }
61016
+ }
61017
+ }
61018
+ }
61019
+ } else if (step.type === "validation") {
61020
+ const val = dsl.validations[step.validation];
61021
+ if (val) {
61022
+ if (val.executor_type === "agent") {
61023
+ addOp(agentOps, val.executor, "validate");
61024
+ } else {
61025
+ addOp(toolOps, val.executor, "verification");
61026
+ }
61027
+ addOp(artifactOps, val.target_artifact, "V");
61028
+ }
61029
+ }
61030
+ }
61031
+ return { agentOps, artifactOps, toolOps };
61032
+ }
61033
+ function formatOps(ops) {
61034
+ if (!ops || ops.size === 0) return "\u2014";
61035
+ return [...ops].join(", ");
61036
+ }
61037
+ function buildTable(header, rows) {
61038
+ const lines = [];
61039
+ lines.push("| " + header.join(" | ") + " |");
61040
+ lines.push("|" + header.map(() => "---").join("|") + "|");
61041
+ for (const row of rows) {
61042
+ lines.push("| " + row.join(" | ") + " |");
61043
+ }
61044
+ return lines.join("\n");
61045
+ }
61046
+ function generateOverviewFlowchart(dsl) {
61047
+ const workflowOrder = dsl.system.default_workflow_order ?? Object.keys(dsl.workflow);
61048
+ const phases = workflowOrder.filter((id) => dsl.workflow[id]);
61049
+ const phaseData = /* @__PURE__ */ new Map();
61050
+ for (const wfId of phases) {
61051
+ phaseData.set(wfId, collectPhaseOps(dsl, wfId));
61052
+ }
61053
+ const allAgentIds = /* @__PURE__ */ new Set();
61054
+ const allArtifactIds = /* @__PURE__ */ new Set();
61055
+ const allToolIds = /* @__PURE__ */ new Set();
61056
+ for (const ops of phaseData.values()) {
61057
+ for (const id of ops.agentOps.keys()) allAgentIds.add(id);
61058
+ for (const id of ops.artifactOps.keys()) allArtifactIds.add(id);
61059
+ for (const id of ops.toolOps.keys()) allToolIds.add(id);
61060
+ }
61061
+ const sections = [];
61062
+ if (allAgentIds.size > 0) {
61063
+ const header = ["Agent", ...phases];
61064
+ const rows = [];
61065
+ for (const agentId of allAgentIds) {
61066
+ const agent = dsl.agents[agentId];
61067
+ const label = agent ? agent.role_name : agentId;
61068
+ const row = [label];
61069
+ for (const wfId of phases) {
61070
+ row.push(formatOps(phaseData.get(wfId).agentOps.get(agentId)));
61071
+ }
61072
+ rows.push(row);
61073
+ }
61074
+ sections.push("#### Agent \xD7 Phase\n\n" + buildTable(header, rows));
61075
+ }
61076
+ if (allArtifactIds.size > 0) {
61077
+ const header = ["Artifact", ...phases];
61078
+ const rows = [];
61079
+ for (const artId of allArtifactIds) {
61080
+ const row = [artId];
61081
+ for (const wfId of phases) {
61082
+ row.push(formatOps(phaseData.get(wfId).artifactOps.get(artId)));
61083
+ }
61084
+ rows.push(row);
61085
+ }
61086
+ sections.push("#### Artifact \xD7 Phase\n\n" + buildTable(header, rows));
61087
+ }
61088
+ if (allToolIds.size > 0) {
61089
+ const header = ["Tool", ...phases];
61090
+ const rows = [];
61091
+ for (const toolId of allToolIds) {
61092
+ const row = [toolId];
61093
+ for (const wfId of phases) {
61094
+ row.push(formatOps(phaseData.get(wfId).toolOps.get(toolId)));
61095
+ }
61096
+ rows.push(row);
61097
+ }
61098
+ sections.push("#### Tool \xD7 Phase\n\n" + buildTable(header, rows));
61099
+ }
61100
+ return sections.join("\n\n");
61101
+ }
60730
61102
 
60731
61103
  // src/renderer/renderer.ts
60732
61104
  Handlebars.registerHelper("eq", (a3, b3) => a3 === b3);
@@ -60891,14 +61263,39 @@ Handlebars.registerHelper("size", (obj) => {
60891
61263
  });
60892
61264
  Handlebars.registerHelper(
60893
61265
  "sequenceDiagram",
60894
- function() {
61266
+ function(...args) {
61267
+ const opts = args[args.length - 1];
61268
+ const positionalArgs = args.slice(0, -1);
61269
+ if (typeof positionalArgs[0] === "string" && positionalArgs[1]) {
61270
+ const workflowId = positionalArgs[0];
61271
+ const dsl2 = positionalArgs[1];
61272
+ if (!dsl2.workflow[workflowId]) return "";
61273
+ const ctx = buildWorkflowContext(dsl2, workflowId);
61274
+ return generateSequenceDiagram(
61275
+ ctx.workflow,
61276
+ ctx.relatedTasks,
61277
+ dsl2
61278
+ );
61279
+ }
60895
61280
  const workflow = this["workflow"];
60896
61281
  const relatedTasks = this["relatedTasks"];
60897
- const dsl = this["dsl"];
61282
+ const dsl = opts?.hash?.["dsl"] ?? this["dsl"];
60898
61283
  if (!workflow || !dsl) return "";
60899
61284
  return generateSequenceDiagram(workflow, relatedTasks ?? [], dsl);
60900
61285
  }
60901
61286
  );
61287
+ Handlebars.registerHelper(
61288
+ "overviewFlowchart",
61289
+ function(...args) {
61290
+ const positionalArgs = args.slice(0, -1);
61291
+ if (positionalArgs[0] && typeof positionalArgs[0] === "object") {
61292
+ return generateOverviewFlowchart(positionalArgs[0]);
61293
+ }
61294
+ const dsl = this["dsl"];
61295
+ if (!dsl) return "";
61296
+ return generateOverviewFlowchart(dsl);
61297
+ }
61298
+ );
60902
61299
  function getDslSection(dsl, context) {
60903
61300
  const sectionMap = {
60904
61301
  agent: dsl.agents,
@@ -61140,6 +61537,7 @@ export {
61140
61537
  ArtifactSchema,
61141
61538
  BaseResolveError,
61142
61539
  CONTEXT_TYPES,
61540
+ CommandSchema,
61143
61541
  ConfigLoadError,
61144
61542
  ContextTypeSchema,
61145
61543
  DslLoadError,