@dv.nghiem/flowdeck 0.3.9 → 0.4.1

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.
Files changed (129) hide show
  1. package/README.md +13 -21
  2. package/dist/agents/code-explorer.d.ts.map +1 -1
  3. package/dist/agents/mapper.d.ts.map +1 -1
  4. package/dist/agents/orchestrator.d.ts.map +1 -1
  5. package/dist/agents/planner.d.ts.map +1 -1
  6. package/dist/agents/specialist.d.ts.map +1 -1
  7. package/dist/dashboard/server.mjs +12 -2
  8. package/dist/hooks/compaction-hook.d.ts +1 -2
  9. package/dist/hooks/compaction-hook.d.ts.map +1 -1
  10. package/dist/hooks/file-tracker.d.ts +6 -0
  11. package/dist/hooks/file-tracker.d.ts.map +1 -1
  12. package/dist/hooks/notifications.d.ts +73 -8
  13. package/dist/hooks/notifications.d.ts.map +1 -1
  14. package/dist/hooks/notifications.test.d.ts +14 -0
  15. package/dist/hooks/notifications.test.d.ts.map +1 -0
  16. package/dist/hooks/session-idle-hook.d.ts +5 -3
  17. package/dist/hooks/session-idle-hook.d.ts.map +1 -1
  18. package/dist/hooks/session-start.d.ts.map +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +822 -796
  21. package/dist/lib/completion-validator.d.ts +51 -0
  22. package/dist/lib/completion-validator.d.ts.map +1 -0
  23. package/dist/lib/recommended-question.d.ts +24 -0
  24. package/dist/lib/recommended-question.d.ts.map +1 -0
  25. package/dist/lib/research-gate.d.ts +97 -0
  26. package/dist/lib/research-gate.d.ts.map +1 -0
  27. package/dist/lib/research-gate.test.d.ts +2 -0
  28. package/dist/lib/research-gate.test.d.ts.map +1 -0
  29. package/dist/mcp/index.d.ts +12 -2
  30. package/dist/mcp/index.d.ts.map +1 -1
  31. package/dist/services/codegraph.d.ts +36 -0
  32. package/dist/services/codegraph.d.ts.map +1 -0
  33. package/dist/services/codegraph.test.d.ts +2 -0
  34. package/dist/services/codegraph.test.d.ts.map +1 -0
  35. package/dist/services/question-guard.d.ts +4 -0
  36. package/dist/services/question-guard.d.ts.map +1 -1
  37. package/dist/services/recommended-question.test.d.ts +2 -0
  38. package/dist/services/recommended-question.test.d.ts.map +1 -0
  39. package/dist/services/supervisor-binding.d.ts +3 -1
  40. package/dist/services/supervisor-binding.d.ts.map +1 -1
  41. package/dist/tools/codebase-index.d.ts +30 -0
  42. package/dist/tools/codebase-index.d.ts.map +1 -0
  43. package/dist/tools/codebase-index.test.d.ts +2 -0
  44. package/dist/tools/codebase-index.test.d.ts.map +1 -0
  45. package/dist/tools/codegraph-tool.d.ts +3 -0
  46. package/dist/tools/codegraph-tool.d.ts.map +1 -0
  47. package/dist/tools/planning-state-lib.d.ts +23 -0
  48. package/dist/tools/planning-state-lib.d.ts.map +1 -1
  49. package/docs/agents/index.md +154 -0
  50. package/docs/commands/fd-ask.md +71 -39
  51. package/docs/commands/fd-checkpoint.md +63 -8
  52. package/docs/commands/fd-deploy-check.md +166 -9
  53. package/docs/commands/fd-design.md +101 -0
  54. package/docs/commands/fd-discuss.md +87 -20
  55. package/docs/commands/fd-doctor.md +100 -13
  56. package/docs/commands/fd-done.md +215 -0
  57. package/docs/commands/fd-execute.md +104 -0
  58. package/docs/commands/fd-fix-bug.md +144 -24
  59. package/docs/commands/fd-map-codebase.md +85 -21
  60. package/docs/commands/fd-multi-repo.md +155 -40
  61. package/docs/commands/fd-new-feature.md +63 -19
  62. package/docs/commands/fd-plan.md +80 -27
  63. package/docs/commands/fd-quick.md +143 -29
  64. package/docs/commands/fd-reflect.md +81 -13
  65. package/docs/commands/fd-resume.md +65 -8
  66. package/docs/commands/fd-status.md +80 -12
  67. package/docs/commands/fd-suggest.md +114 -0
  68. package/docs/commands/fd-translate-intent.md +69 -9
  69. package/docs/commands/fd-verify.md +71 -14
  70. package/docs/commands/fd-write-docs.md +121 -8
  71. package/docs/concepts/architecture.md +163 -0
  72. package/docs/concepts/governance.md +242 -0
  73. package/docs/concepts/intelligence.md +145 -0
  74. package/docs/concepts/multi-repo.md +227 -0
  75. package/docs/concepts/workflows.md +205 -0
  76. package/docs/configuration/index.md +208 -0
  77. package/docs/configuration/opencode-settings.md +98 -0
  78. package/docs/getting-started/first-project.md +126 -0
  79. package/docs/getting-started/installation.md +73 -0
  80. package/docs/getting-started/quick-start.md +74 -0
  81. package/docs/index.md +36 -72
  82. package/docs/reference/hooks.md +176 -0
  83. package/docs/reference/rules.md +109 -0
  84. package/docs/skills/code-review.md +47 -0
  85. package/docs/skills/index.md +148 -0
  86. package/docs/skills/planning.md +39 -0
  87. package/package.json +1 -1
  88. package/src/commands/fd-discuss.md +74 -10
  89. package/src/commands/fd-done.md +196 -0
  90. package/src/commands/fd-execute.md +43 -6
  91. package/src/commands/fd-fix-bug.md +43 -6
  92. package/src/commands/fd-map-codebase.md +99 -19
  93. package/src/commands/fd-new-feature.md +14 -5
  94. package/src/commands/fd-plan.md +38 -1
  95. package/src/commands/fd-quick.md +1 -1
  96. package/src/commands/fd-resume.md +1 -1
  97. package/src/commands/fd-status.md +1 -1
  98. package/src/commands/fd-verify.md +16 -2
  99. package/src/commands/fd-write-docs.md +30 -5
  100. package/src/skills/context-load/SKILL.md +1 -1
  101. package/dist/hooks/memory-hook.d.ts +0 -28
  102. package/dist/hooks/memory-hook.d.ts.map +0 -1
  103. package/dist/services/memory-store.d.ts +0 -73
  104. package/dist/services/memory-store.d.ts.map +0 -1
  105. package/dist/services/memory-store.test.d.ts +0 -2
  106. package/dist/services/memory-store.test.d.ts.map +0 -1
  107. package/dist/tools/memory-search.d.ts +0 -3
  108. package/dist/tools/memory-search.d.ts.map +0 -1
  109. package/dist/tools/memory-status.d.ts +0 -3
  110. package/dist/tools/memory-status.d.ts.map +0 -1
  111. package/docs/USER_GUIDE.md +0 -20
  112. package/docs/agents.md +0 -544
  113. package/docs/best-practices.md +0 -47
  114. package/docs/commands/fd-new-project.md +0 -24
  115. package/docs/commands.md +0 -557
  116. package/docs/configuration.md +0 -325
  117. package/docs/design-first-workflow.md +0 -94
  118. package/docs/feature-integration-architecture.md +0 -227
  119. package/docs/installation.md +0 -123
  120. package/docs/intelligence.md +0 -370
  121. package/docs/memory.md +0 -69
  122. package/docs/multi-repo.md +0 -201
  123. package/docs/notifications.md +0 -170
  124. package/docs/optimization-baseline.md +0 -21
  125. package/docs/quick-start.md +0 -197
  126. package/docs/rules.md +0 -432
  127. package/docs/skills.md +0 -417
  128. package/docs/workflows.md +0 -134
  129. package/src/commands/fd-new-project.md +0 -114
package/README.md CHANGED
@@ -9,8 +9,8 @@ FlowDeck adds a structured, multi-agent development workflow to OpenCode. It coo
9
9
  ## Features
10
10
 
11
11
  - 🤖 **25 agents** — architect, planner, coder, reviewer, tester, debugger, risk-analyst, policy-enforcer, and more
12
- - 🛠️ **59 skills** — reusable workflow patterns (TDD, security scan, deploy check, code review, and more)
13
- - ⚡ **20 commands** — workflow commands for all project operations
12
+ - 🛠️ **64 skills** — reusable workflow patterns (TDD, security scan, deploy check, code review, and more)
13
+ - ⚡ **21 commands** — workflow commands for all project operations
14
14
  - 📋 **15 workflows** — pre-built orchestration flows including Spec-Driven Development (SDD)
15
15
  - 🔄 **Persistent state** — resume exactly where you left off across sessions via `.planning/STATE.md`
16
16
  - 🔀 **Parallel execution** — independent tasks run simultaneously in wave-structured batches
@@ -22,7 +22,7 @@ FlowDeck adds a structured, multi-agent development workflow to OpenCode. It coo
22
22
  - 🪝 **Deep System Hooks** — context window monitoring, session idle summaries, shell environment injection, and structured compaction to prevent context loss
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
- - 🧠 **Persistent Memory** — SQLite-based memory stores tool executions, assistant messages, and session summaries. Agents can search past observations with `memory-search` tool.
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.
26
26
  - ⚙️ **Model-agnostic** — no model is hardcoded. Every agent uses your currently selected OpenCode model. Override per-agent in `flowdeck.json`.
27
27
 
28
28
  ---
@@ -50,16 +50,18 @@ See [Installation](docs/installation.md) for prerequisites, verification steps,
50
50
  FlowDeck structures every feature through a six-step cycle:
51
51
 
52
52
  ```
53
- /fd-new-project → /fd-new-feature → /fd-discuss → /fd-plan → /fd-execute → /fd-verify
53
+ /fd-map-codebase → /fd-new-feature → /fd-discuss → /fd-design → /fd-plan → /fd-execute → /fd-verify → /fd-done
54
54
  ```
55
55
 
56
56
  | Step | Command | What happens |
57
57
  |------|---------|--------------|
58
- | **Setup** | `/fd-new-project MyApp` | Creates `.planning/` directory with `PROJECT.md`, `STATE.md`, and `ROADMAP.md` |
58
+ | **Map** | `/fd-map-codebase` | Analyses and indexes the codebase into structured `.codebase/` files |
59
59
  | **Define Feature** | `/fd-new-feature "…"` | Initialize feature context, creates `FEATURE.md` in current phase |
60
60
  | **Discuss** | `/fd-discuss` | `@discusser` runs structured Q&A, saves decisions to `DISCUSS.md` |
61
+ | **Design** | `/fd-design` | `@design` produces UI artifacts — wireframes, visual system, approval gate |
61
62
  | **Plan** | `/fd-plan` | `@planner` builds a wave-structured `PLAN.md`; you type `CONFIRM` to proceed |
62
63
  | **Execute** | `/fd-execute` | `@orchestrator` delegates to `@architect`, `@backend-coder`, `@tester`, `@reviewer` via TDD |
64
+ | **Done** | `/fd-done` | Mark complete — validates readiness, finalizes state, refreshes mapping |
63
65
  | **Verify** | `/fd-verify` | Full test suite, code review, security scan, and deploy check |
64
66
 
65
67
  State is written to `.planning/STATE.md` after each phase. Use `/fd-checkpoint` to save mid-session and `/fd-resume` to reload context in a new session.
@@ -72,39 +74,29 @@ State is written to `.planning/STATE.md` after each phase. Use `/fd-checkpoint`
72
74
 
73
75
  | Command | Purpose |
74
76
  |---------|---------|
75
- | `/fd-new-project` | Bootstrap a new project with PROJECT.md, ROADMAP.md, STATE.md |
76
77
  | `/fd-map-codebase` | Analyse and index the codebase into structured `.codebase/` files |
77
78
  | `/fd-new-feature` | Define a new feature and initialize feature context |
78
79
  | `/fd-discuss` | Pre-planning structured Q&A to capture decisions |
80
+ | `/fd-design` | Design-first workflow for UI-heavy tasks — draft, review, or define design system rules |
79
81
  | `/fd-plan` | Generate a wave-structured execution plan from decisions |
80
82
  | `/fd-execute` | Implement feature with TDD discipline and parallel agents |
83
+ | `/fd-done` | Mark feature/phase complete — validates readiness, finalizes state, refreshes mapping |
81
84
  | `/fd-verify` | Full verification pipeline: tests, code review, security scan, deploy check |
82
85
  | `/fd-fix-bug` | Diagnose, fix, and verify a bug with regression test |
83
86
  | `/fd-write-docs` | Explore APIs and generate accurate documentation |
84
- | `/fd-deploy-check` | Pre-deploy safety check with test, security, and build verification |
87
+ | `/fd-deploy-check` | Pre-change release safety checks and review routing |
85
88
  | `/fd-status` | View project progress, roadmap, and workspace overview |
86
89
  | `/fd-checkpoint` | Save a session checkpoint to STATE.md |
87
90
  | `/fd-resume` | Reload STATE.md and PLAN.md to continue interrupted session |
88
91
  | `/fd-reflect` | Post-session reflection or capture patterns as reusable skills |
89
92
  | `/fd-multi-repo` | Multi-repo orchestration — list, add, remove, or status |
90
- | `/fd-translate-intent` | Convert vague requests into ranked implementation options |
91
- | `/fd-suggest` | Analyze the codebase and suggest high-value feature opportunities |
93
+ | `/fd-translate-intent` | Convert vague requests into ranked implementation options with tradeoffs |
94
+ | `/fd-suggest` | Combined opportunity and risk analysis (impact, volatility, failures, skill gaps) |
92
95
  | `/fd-ask` | Smart agent dispatch — routes to specialist by keyword |
93
96
  | `/fd-quick` | Focused task with automatic agent selection |
94
97
  | `/fd-doctor` | Check FlowDeck installation and environment health |
95
98
 
96
- ### Analysis commands
97
-
98
- These umbrella commands consolidate multiple analysis modules into focused entry points:
99
-
100
- | Command | Purpose |
101
- |---------|---------|
102
- | `/fd-translate-intent` | Convert vague requests into ranked implementation options with tradeoffs |
103
- | `/fd-suggest` | Combined opportunity and risk analysis (impact, volatility, failures, and skill gaps) |
104
- | `/fd-deploy-check` | Pre-change release safety checks and review routing |
105
- | `/fd-verify` | Standalone verification for tests, review, and security checks |
106
-
107
- See [docs/workflows.md](docs/workflows.md) for details on how analysis commands work.
99
+ See [docs/workflows.md](docs/workflows.md) for details on how commands work.
108
100
 
109
101
  ---
110
102
 
@@ -1 +1 @@
1
- {"version":3,"file":"code-explorer.d.ts","sourceRoot":"","sources":["../../src/agents/code-explorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AA8F7D,eAAO,MAAM,uBAAuB,EAAE,YAqBrC,CAAC"}
1
+ {"version":3,"file":"code-explorer.d.ts","sourceRoot":"","sources":["../../src/agents/code-explorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AA6I7D,eAAO,MAAM,uBAAuB,EAAE,YAqBrC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../src/agents/mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AAsE7D,eAAO,MAAM,iBAAiB,EAAE,YAiB/B,CAAC"}
1
+ {"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../src/agents/mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AA8F7D,eAAO,MAAM,iBAAiB,EAAE,YAiB/B,CAAC"}
@@ -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;AA2Q/C;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAsB5E;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,GAC3B,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;AAmS/C;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAsB5E;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,GAC3B,eAAe,CAuBjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/agents/planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AA+N7D,eAAO,MAAM,kBAAkB,EAAE,YAiBhC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,YAqBpC,CAAC"}
1
+ {"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/agents/planner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AAoO7D,eAAO,MAAM,kBAAkB,EAAE,YAiBhC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,YAqBpC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"specialist.d.ts","sourceRoot":"","sources":["../../src/agents/specialist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AAuN7D,eAAO,MAAM,uBAAuB,EAAE,YAqBrC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,YAiBlC,CAAC"}
1
+ {"version":3,"file":"specialist.d.ts","sourceRoot":"","sources":["../../src/agents/specialist.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,SAAS,CAAC;AA2Q7D,eAAO,MAAM,uBAAuB,EAAE,YAqBrC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,YAiBlC,CAAC"}
@@ -12482,7 +12482,12 @@ function readPlanningState(dir) {
12482
12482
  last_action: "",
12483
12483
  next_action: "",
12484
12484
  blockers: [],
12485
- tdd: undefined
12485
+ tdd: undefined,
12486
+ lastUpdatedAt: "",
12487
+ lastUpdatedBy: "",
12488
+ lastUpdatedPhase: 1,
12489
+ summaryVersion: 0,
12490
+ freshnessStatus: "unknown"
12486
12491
  };
12487
12492
  }
12488
12493
  const content = readFileSync2(sp, "utf-8");
@@ -12503,7 +12508,12 @@ function readPlanningState(dir) {
12503
12508
  last_action: parsed.last_action || "",
12504
12509
  next_action: parsed.next_action || "",
12505
12510
  blockers: parsed.blockers || [],
12506
- tdd: parseTDDState(parsed)
12511
+ tdd: parseTDDState(parsed),
12512
+ lastUpdatedAt: parsed.lastUpdatedAt || "",
12513
+ lastUpdatedBy: parsed.lastUpdatedBy || "",
12514
+ lastUpdatedPhase: parsed.lastUpdatedPhase || 1,
12515
+ summaryVersion: parsed.summaryVersion || 0,
12516
+ freshnessStatus: parsed.freshnessStatus || "unknown"
12507
12517
  };
12508
12518
  }
12509
12519
  function parseTDDState(parsed) {
@@ -6,8 +6,7 @@
6
6
  * Context includes:
7
7
  * 1. FlowDeck planning state (phase, status, pending steps)
8
8
  * 2. Recently edited files (from SessionFileTracker)
9
- * 3. Historical session summaries from memory store
10
- * 4. Structured 8-section summary prompt
9
+ * 3. Structured 8-section summary prompt
11
10
  *
12
11
  * Inspired by oh-my-openagent's compaction-context-injector and
13
12
  * ECC's experimental.session.compacting handler.
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/compaction-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAqDxD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,OAAO,EAAE,kBAAkB,IAGzB,QAAQ;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7B,QAAQ;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,mBAsCjD"}
1
+ {"version":3,"file":"compaction-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/compaction-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAoDxD,wBAAgB,oBAAoB,CAClC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC1B,OAAO,EAAE,kBAAkB,IAGzB,QAAQ;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7B,QAAQ;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,mBA8CjD"}
@@ -12,6 +12,8 @@ export interface FileChange {
12
12
  }
13
13
  export declare class SessionFileTracker {
14
14
  private changes;
15
+ private onFileChange?;
16
+ setOnFileChange(callback: (path: string, type: ChangeType) => void): void;
15
17
  record(path: string, type: ChangeType): void;
16
18
  getChanges(): FileChange[];
17
19
  getEditedPaths(): string[];
@@ -26,4 +28,8 @@ export declare function createFileTrackerHooks(tracker: SessionFileTracker): {
26
28
  type: string;
27
29
  }) => void;
28
30
  };
31
+ export declare function createCodebaseIndexFileTracker(directory: string): {
32
+ tracker: SessionFileTracker;
33
+ publishToIndex: (agent: string, stage: string) => void;
34
+ };
29
35
  //# sourceMappingURL=file-tracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-tracker.d.ts","sourceRoot":"","sources":["../../src/hooks/file-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;AAEzD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAgC;IAE/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IAI5C,UAAU,IAAI,UAAU,EAAE;IAI1B,cAAc,IAAI,MAAM,EAAE;IAM1B,KAAK,IAAI,IAAI;CAGd;AAGD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,kBAAkB;wBACrC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;gCAIR;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;EAQlE"}
1
+ {"version":3,"file":"file-tracker.d.ts","sourceRoot":"","sources":["../../src/hooks/file-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;AAEzD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,YAAY,CAAC,CAA0C;IAE/D,eAAe,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAIzE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI;IAO5C,UAAU,IAAI,UAAU,EAAE;IAI1B,cAAc,IAAI,MAAM,EAAE;IAM1B,KAAK,IAAI,IAAI;CAGd;AAGD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,kBAAkB;wBACrC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;gCAIR;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;EAQlE;AAED,wBAAgB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG;IACjE,OAAO,EAAE,kBAAkB,CAAA;IAC3B,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACvD,CAkBA"}
@@ -1,21 +1,86 @@
1
- type NotifyLevel = "info" | "critical";
1
+ export type NotifyLevel = "info" | "critical";
2
+ /**
3
+ * Structured reasons that can trigger a notification.
4
+ * Helps consumers understand why a notification fired.
5
+ */
6
+ export type NotificationReason = "completed" | "input_required" | "confirmation_required" | "error";
7
+ /**
8
+ * Normalise a raw command string to a bare command name.
9
+ * "/fd-discuss" → "discuss", "fd-plan" → "plan", "new-feature" → "new-feature"
10
+ */
11
+ export declare function normalizeCommandName(raw: string): string;
2
12
  /**
3
13
  * Fire a desktop notification without blocking the caller.
4
14
  * Silently ignores failures — notification is best-effort only.
5
15
  */
6
16
  export declare function notify(title: string, body: string, level?: NotifyLevel): void;
17
+ export type NotifyFn = (title: string, body: string, level?: NotifyLevel) => void;
18
+ /**
19
+ * Event-driven notification controller.
20
+ *
21
+ * Lifecycle:
22
+ * 1. onCommandExecuted() — records that a command was dispatched (NOT yet processed)
23
+ * 2. onSessionIdle() — fires notification when the agent finishes processing
24
+ * 3. onSessionError() — fires notification on critical failure
25
+ *
26
+ * Deduplication: the same (command + lifecycle-state) pair is never notified twice,
27
+ * even if session.idle fires multiple times in a row.
28
+ *
29
+ * @param notifyFn — injectable notify function (defaults to the real OS notifier; pass
30
+ * a test stub to avoid spawning OS processes in tests).
31
+ * @param log — optional diagnostic logger.
32
+ */
33
+ export declare class NotificationController {
34
+ /** The command currently awaiting a session.idle notification, or null. */
35
+ private pendingCommand;
36
+ /** Key of the last notification that was fired; used for deduplication. */
37
+ private lastNotifiedKey;
38
+ private readonly notifyFn;
39
+ private readonly log;
40
+ constructor(notifyFn?: NotifyFn, log?: (msg: string) => void);
41
+ /**
42
+ * Called when the `command.executed` event fires.
43
+ * Records the command so the next session.idle can produce the right notification.
44
+ * Must NOT fire a notification — the command has only been dispatched, not completed.
45
+ */
46
+ onCommandExecuted(rawCommand: string): void;
47
+ /**
48
+ * Called when the `session.idle` event fires.
49
+ * Fires at most one notification per pending command.
50
+ * If no command is pending, fires a generic completion notification only when
51
+ * the agent actually edited files (hasEdits = true).
52
+ *
53
+ * @param hasEdits — true when the session file tracker has recorded edits this turn.
54
+ */
55
+ onSessionIdle(hasEdits: boolean): void;
56
+ /**
57
+ * Called when the `session.error` event fires.
58
+ * Always fires unless the identical error was already reported.
59
+ */
60
+ onSessionError(errorMsg: string): void;
61
+ /**
62
+ * Reset all state. Useful in tests or when starting a new session.
63
+ */
64
+ reset(): void;
65
+ getPendingCommand(): string | null;
66
+ getLastNotifiedKey(): string | null;
67
+ }
7
68
  /**
8
- * Fires a notification when a command that needs user interaction starts.
9
- * Call this from command.execute.before after the command result is generated.
69
+ * Fires a notification when a permission is requested.
70
+ * This is event-driven (permission.ask hook fires after the agent's request)
71
+ * so it does not need to go through the NotificationController.
10
72
  */
11
- export declare function notifyCommandInteraction(command: string): void;
73
+ export declare function notifyPermissionNeeded(tool: string): void;
12
74
  /**
13
- * Fires a notification when the session becomes idle (task complete).
75
+ * @deprecated Use NotificationController.onSessionIdle() instead.
76
+ * Kept for backward compatibility — does nothing now that the controller
77
+ * handles all session-idle notifications.
14
78
  */
15
79
  export declare function notifySessionIdle(): void;
16
80
  /**
17
- * Fires a notification when a permission is requested.
81
+ * @deprecated Use NotificationController.onCommandExecuted() + onSessionIdle() instead.
82
+ * This function fired notifications on command ENTRY (too early).
83
+ * It is preserved as a no-op so that any lingering callers compile without error.
18
84
  */
19
- export declare function notifyPermissionNeeded(tool: string): void;
20
- export {};
85
+ export declare function notifyCommandInteraction(_command: string): void;
21
86
  //# sourceMappingURL=notifications.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/hooks/notifications.ts"],"names":[],"mappings":"AAmBA,KAAK,WAAW,GAAG,MAAM,GAAG,UAAU,CAAA;AAEtC;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,WAAoB,GAAG,IAAI,CAoCrF;AAUD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAgB9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAMxC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD"}
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/hooks/notifications.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,CAAA;AAE7C;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,gBAAgB,GAChB,uBAAuB,GACvB,OAAO,CAAA;AAEX;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,WAAoB,GAAG,IAAI,CAoCrF;AAUD,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;AAEjF;;;;;;;;;;;;;;GAcG;AACH,qBAAa,sBAAsB;IACjC,2EAA2E;IAC3E,OAAO,CAAC,cAAc,CAAsB;IAC5C,2EAA2E;IAC3E,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;gBAE/B,QAAQ,GAAE,QAAiB,EAAE,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAe;IAK9E;;;;OAIG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAc3C;;;;;;;OAOG;IACH,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IA4CtC;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAgBtC;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAClC,kBAAkB,IAAI,MAAM,GAAG,IAAI;CACpC;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzD;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE/D"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * NotificationController Tests
3
+ *
4
+ * Covers the core timing contract:
5
+ * - No notification when a command is merely entered (command.execute.before)
6
+ * - Notification fires on session.idle after a completion command
7
+ * - Notification fires on session.idle after an interactive command
8
+ * - Notification fires on session.error
9
+ * - Duplicate notifications are suppressed
10
+ * - Long-running command only notifies at the correct lifecycle point
11
+ * - Generic (non-command) idle notification fires only when edits exist
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=notifications.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.test.d.ts","sourceRoot":"","sources":["../../src/hooks/notifications.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * Session Idle Hook
3
3
  * Fires when OpenCode's session becomes idle (task completed).
4
- * 1. Sends a desktop notification (if notify() succeeds)
5
- * 2. Logs a summary of edited files via client.app.log
4
+ * Logs a summary of edited files via client.app.log.
6
5
  *
7
- * Inspired by oh-my-openagent's session notification + ECC's session.idle handler.
6
+ * NOTE: Desktop notifications are no longer sent from this hook.
7
+ * They are handled by NotificationController in notifications.ts, which
8
+ * fires at the correct lifecycle points (session.idle after a command,
9
+ * session.error on failure) and deduplicates properly.
8
10
  */
9
11
  import type { SessionFileTracker } from "./file-tracker";
10
12
  export declare function createSessionIdleHook(client: {
@@ -1 +1 @@
1
- {"version":3,"file":"session-idle-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/session-idle-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,GAAG,EAAE;QAAE,GAAG,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE,CAAA;CAAE,EAC5I,OAAO,EAAE,kBAAkB,uBAiC5B"}
1
+ {"version":3,"file":"session-idle-hook.d.ts","sourceRoot":"","sources":["../../src/hooks/session-idle-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE;IAAE,GAAG,EAAE;QAAE,GAAG,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE,CAAA;CAAE,EAC5I,OAAO,EAAE,kBAAkB,uBA0B5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/hooks/session-start.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwElC"}
1
+ {"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../src/hooks/session-start.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAkElC"}
@@ -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;AAmGjD,QAAA,MAAM,MAAM,EAAE,MA+Vb,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;AAgGjD,QAAA,MAAM,MAAM,EAAE,MAkVb,CAAA;AAED,eAAe,MAAM,CAAA"}