@dv.nghiem/flowdeck 0.5.3 β†’ 0.5.5

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 CHANGED
@@ -18,8 +18,8 @@ FlowDeck adds a structured, multi-agent development workflow to OpenCode. It coo
18
18
  - πŸ—‚οΈ **Multi-repo support** β€” coordinate changes across multiple repositories in one session
19
19
  - πŸ”” **System notifications** β€” desktop alerts when long-running tasks complete
20
20
  - πŸ›‘οΈ **AI Safety layer** β€” patch trust scoring, edit gates, phase gating, arch constraint enforcement, failure replay, and regression prediction built into every workflow
21
- - πŸ” **Governance layer** β€” capability contracts, agent validator, inter-agent trace graph, delegation budget, deadlock/loop detector, and workflow scorecard
22
- - πŸͺ **Deep System Hooks** β€” context window monitoring, session idle summaries, shell environment injection, and structured compaction to prevent context loss
21
+ - πŸ” **Governance layer** β€” capability contracts, agent validator, inter-agent trace graph, deadlock/loop detector, workflow scorecard, and hook-based budget/depth enforcement
22
+ - πŸͺ **Deep System Hooks** β€” context window monitoring, session idle summaries, shell environment injection, structured compaction, and tool.execute.before/after governance hooks
23
23
  - 🌐 **Built-in MCPs** β€” Context7 (docs), Exa (web search), and Grep.app (code search) included and enabled by default
24
24
  - πŸ’Ž **Ensemble Reasoning** β€” `council` tool for synthesized consensus from multiple specialized agents
25
25
  - πŸ—ΊοΈ **Codegraph Integration** β€” Codegraph-backed code understanding maps the codebase at indexing time and serves as the shared intelligence layer for all commands and agents.
@@ -122,18 +122,20 @@ FlowDeck's governance layer makes multi-agent execution trustworthy and debuggab
122
122
  |---------|-------------|
123
123
  | **Agent Contract Registry** | Defines allowed tools, forbidden actions, required inputs, and success criteria for every agent |
124
124
  | **Agent Validator** | Checks each agent invocation against its contract before and after execution; mode: `off` / `advisory` / `strict` |
125
- | **Inter-Agent Trace Graph** | Records every agent-to-agent delegation as a causal span graph; stored in `.codebase/AGENT_SPANS.jsonl` |
126
- | **Delegation Budget** | Per-run limits on tool calls, sub-agent delegations, retries, and delegation depth; stored in `.codebase/BUDGETS.json` |
125
+ | **Inter-Agent Trace Graph** | Records every agent invocation as a causal span graph; stored in `.codebase/AGENT_SPANS.jsonl` |
126
+ | **Hook-Based Budget & Depth Enforcement** | Per-run limits on tool calls and delegation depth enforced via `tool.execute.before` and `session.created` hooks |
127
127
  | **Deadlock / Loop Detector** | Detects agent bounce loops, circular delegation, step retry loops, and stage stalls; stored in `.codebase/DEADLOCK_SIGNALS.jsonl` |
128
128
  | **Workflow Scorecard** | 10-dimension quality score for every run (TDD, design-first, approvals, budget efficiency, etc.); stored in `.codebase/SCORECARDS.jsonl` |
129
129
 
130
+ Agents route work via native OpenCode `@agent-name` mentions. The `delegate` tool has been removed; depth and tool-call budgets are now enforced transparently for every session.
131
+
130
132
  Configure in `flowdeck.json`:
131
133
 
132
134
  ```json
133
135
  {
134
136
  "governance": {
135
137
  "validator": { "mode": "advisory" },
136
- "delegationBudget": { "maxToolCalls": 200, "maxDepth": 8, "maxSameStepRetries": 3 },
138
+ "delegationBudget": { "maxToolCalls": 200, "maxDepth": 3, "maxSameStepRetries": 3 },
137
139
  "deadlockDetection": { "enabled": true, "bounceThreshold": 3, "autoStop": false },
138
140
  "scorecard": { "enabled": true }
139
141
  }
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/agents/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAwV/C,wBAAgB,uBAAuB,CACrC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC5B,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CA6BR;AAED,wBAAgB,uBAAuB,CACrC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACjE,YAAY,CAAC,EAAE,MAAM,EACrB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC5B,aAAa,CAAC,EAAE,MAAM,GACrB,eAAe,CAuBjB"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/agents/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA8W/C,wBAAgB,uBAAuB,CACrC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC5B,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CA6BR;AAED,wBAAgB,uBAAuB,CACrC,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACjE,YAAY,CAAC,EAAE,MAAM,EACrB,kBAAkB,CAAC,EAAE,MAAM,EAC3B,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC5B,aAAa,CAAC,EAAE,MAAM,GACrB,eAAe,CAuBjB"}
@@ -2,14 +2,14 @@ import type { SpanStatus } from "@/services/harness-types";
2
2
  type AppLog = (msg: string) => void;
3
3
  export type OnToolAfterCallback = (toolName: string, args: Record<string, unknown>, output: unknown, sessionId: string, status: string) => void;
4
4
  export interface SpanLifecycleCallbacks {
5
- /** Called when a delegated session starts (span open). */
5
+ /** Called when a subagent session starts (span open). */
6
6
  onSpanOpen?: (props: {
7
7
  spanId: string;
8
8
  agent: string;
9
9
  sessionId: string;
10
10
  parentSessionId?: string;
11
11
  }) => void;
12
- /** Called when a delegated session ends (span close). */
12
+ /** Called when a subagent session ends (span close). */
13
13
  onSpanClose?: (props: {
14
14
  spanId: string;
15
15
  status: Exclude<SpanStatus, "running">;
@@ -1 +1 @@
1
- {"version":3,"file":"event-log-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/event-log-hook.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;AAEnC,MAAM,MAAM,mBAAmB,GAAG,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,KACX,IAAI,CAAA;AAET,MAAM,WAAW,sBAAsB;IACrC,0DAA0D;IAC1D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QACnB,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,MAAM,CAAA;QACjB,eAAe,CAAC,EAAE,MAAM,CAAA;KACzB,KAAK,IAAI,CAAA;IACV,yDAAyD;IACzD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QACpB,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;QACtC,SAAS,EAAE,MAAM,CAAA;KAClB,KAAK,IAAI,CAAA;CACX;AASD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAOjD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,mBAAmB,EACjC,aAAa,CAAC,EAAE,sBAAsB;gBASlB;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,aAAa,GAAG,cAAc,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;eA2BvE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,aAAa,GAAG,cAAc,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;iBA0CvE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,SAAS,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;EA4G1E;AAGD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,SAAS,EAAE,GAAG,EACd,UAAU,EAAE,GAAG,GACd,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,SAAS,EAAE,GAAG,EACd,UAAU,EAAE,GAAG,GACd,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,KAAK,EAAE,GAAG,GACT,OAAO,CAAC,OAAO,CAAC,CAElB"}
1
+ {"version":3,"file":"event-log-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/event-log-hook.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,KAAK,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;AAEnC,MAAM,MAAM,mBAAmB,GAAG,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,KACX,IAAI,CAAA;AAET,MAAM,WAAW,sBAAsB;IACrC,yDAAyD;IACzD,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE;QACnB,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,MAAM,CAAA;QACjB,eAAe,CAAC,EAAE,MAAM,CAAA;KACzB,KAAK,IAAI,CAAA;IACV,wDAAwD;IACxD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QACpB,MAAM,EAAE,MAAM,CAAA;QACd,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;QACtC,SAAS,EAAE,MAAM,CAAA;KAClB,KAAK,IAAI,CAAA;CACX;AASD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAOjD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,mBAAmB,EACjC,aAAa,CAAC,EAAE,sBAAsB;gBASlB;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,aAAa,GAAG,cAAc,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;eA2BvE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,aAAa,GAAG,cAAc,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;iBA0CvE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,SAAS,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC;EA4G1E;AAGD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,SAAS,EAAE,GAAG,EACd,UAAU,EAAE,GAAG,GACd,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,SAAS,EAAE,GAAG,EACd,UAAU,EAAE,GAAG,GACd,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,KAAK,EAAE,GAAG,GACT,OAAO,CAAC,OAAO,CAAC,CAElB"}
@@ -3,8 +3,11 @@
3
3
  *
4
4
  * Enforces the "orchestrator as coordinator, not executor" rule for the primary session.
5
5
  * The guard consults the orchestrator capability contract in agent-contract-registry
6
- * and the harness policy. Any tool not in the orchestrator's allowedTools list is
7
- * blocked when run from the primary session.
6
+ * and the harness policy.
7
+ *
8
+ * IMPORTANT: The guard never throws. When a tool is blocked it returns a block
9
+ * message string that the caller should surface as tool output. This keeps the
10
+ * orchestrator turn alive and gives it a path forward (delegate or ask the human).
8
11
  *
9
12
  * To disable: set FLOWDECK_ORCHESTRATOR_GUARD=off in the environment.
10
13
  * Default is ON.
@@ -13,6 +16,7 @@ import type { HarnessPolicy } from "../services/harness-policy";
13
16
  export declare class OrchestratorGuard {
14
17
  private primarySessionId;
15
18
  private policy?;
19
+ private blockedHistory;
16
20
  setPolicy(policy: HarnessPolicy): void;
17
21
  onEvent(event: {
18
22
  type?: string;
@@ -21,12 +25,19 @@ export declare class OrchestratorGuard {
21
25
  sessionID?: string;
22
26
  sessionId?: string;
23
27
  }): void;
24
- check(sessionId: string, toolName: string): void;
28
+ /**
29
+ * Check whether the tool is allowed for the primary session.
30
+ * Returns undefined when allowed, or a block message string when blocked.
31
+ * Never throws.
32
+ */
33
+ check(sessionId: string, toolName: string): string | undefined;
25
34
  /** Returns true if the tool is not in the orchestrator contract allowlist. */
26
35
  _isBlockedForTest(name: string): boolean;
27
36
  /** Returns true if the tool is in the orchestrator contract allowlist. */
28
37
  _isAllowedForTest(name: string): boolean;
29
38
  /** Exposed for testing. */
30
39
  _setPrimarySessionIdForTest(id: string | null): void;
40
+ /** Exposed for testing. */
41
+ _getRepeatCountForTest(sessionId: string, toolName: string): number;
31
42
  }
32
43
  //# sourceMappingURL=orchestrator-guard-hook.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator-guard-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/orchestrator-guard-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,4BAA4B,CAAA;AA6B/E,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,MAAM,CAAC,CAAe;IAE9B,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAItC,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAkBtH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAyBhD,8EAA8E;IAC9E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOxC,0EAA0E;IAC1E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIxC,2BAA2B;IAC3B,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;CAGrD"}
1
+ {"version":3,"file":"orchestrator-guard-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/orchestrator-guard-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAqF/D,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,MAAM,CAAC,CAAe;IAC9B,OAAO,CAAC,cAAc,CAA8C;IAEpE,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAItC,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAmBtH;;;;OAIG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAyB9D,8EAA8E;IAC9E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOxC,0EAA0E;IAC1E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIxC,2BAA2B;IAC3B,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIpD,2BAA2B;IAC3B,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CAGpE"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAkHjD,QAAA,MAAM,MAAM,EAAE,MAuSb,CAAA;AAED,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAiHjD,QAAA,MAAM,MAAM,EAAE,MAuTb,CAAA;AAED,eAAe,MAAM,CAAA"}