@dv.nghiem/flowdeck 0.3.8 → 0.4.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.
Files changed (136) hide show
  1. package/README.md +13 -122
  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.map +1 -1
  9. package/dist/hooks/file-tracker.d.ts +6 -0
  10. package/dist/hooks/file-tracker.d.ts.map +1 -1
  11. package/dist/hooks/notifications.d.ts.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +752 -785
  14. package/dist/lib/completion-validator.d.ts +51 -0
  15. package/dist/lib/completion-validator.d.ts.map +1 -0
  16. package/dist/lib/recommended-question.d.ts +24 -0
  17. package/dist/lib/recommended-question.d.ts.map +1 -0
  18. package/dist/lib/research-gate.d.ts +97 -0
  19. package/dist/lib/research-gate.d.ts.map +1 -0
  20. package/dist/lib/research-gate.test.d.ts +2 -0
  21. package/dist/lib/research-gate.test.d.ts.map +1 -0
  22. package/dist/mcp/index.d.ts +14 -3
  23. package/dist/mcp/index.d.ts.map +1 -1
  24. package/dist/services/codegraph.d.ts +36 -0
  25. package/dist/services/codegraph.d.ts.map +1 -0
  26. package/dist/services/codegraph.test.d.ts +2 -0
  27. package/dist/services/codegraph.test.d.ts.map +1 -0
  28. package/dist/services/command-validator.d.ts +11 -0
  29. package/dist/services/command-validator.d.ts.map +1 -1
  30. package/dist/services/preflight-explorer.d.ts +130 -0
  31. package/dist/services/preflight-explorer.d.ts.map +1 -0
  32. package/dist/services/preflight-explorer.test.d.ts +25 -0
  33. package/dist/services/preflight-explorer.test.d.ts.map +1 -0
  34. package/dist/services/question-guard.d.ts +96 -0
  35. package/dist/services/question-guard.d.ts.map +1 -0
  36. package/dist/services/quick-router.d.ts +40 -1
  37. package/dist/services/quick-router.d.ts.map +1 -1
  38. package/dist/services/recommended-question.test.d.ts +2 -0
  39. package/dist/services/recommended-question.test.d.ts.map +1 -0
  40. package/dist/services/supervisor-binding.d.ts +3 -1
  41. package/dist/services/supervisor-binding.d.ts.map +1 -1
  42. package/dist/tools/codebase-index.d.ts +30 -0
  43. package/dist/tools/codebase-index.d.ts.map +1 -0
  44. package/dist/tools/codebase-index.test.d.ts +2 -0
  45. package/dist/tools/codebase-index.test.d.ts.map +1 -0
  46. package/dist/tools/codegraph-tool.d.ts +3 -0
  47. package/dist/tools/codegraph-tool.d.ts.map +1 -0
  48. package/dist/tools/planning-state-lib.d.ts +23 -0
  49. package/dist/tools/planning-state-lib.d.ts.map +1 -1
  50. package/docs/agents/index.md +154 -0
  51. package/docs/commands/fd-ask.md +71 -39
  52. package/docs/commands/fd-checkpoint.md +63 -8
  53. package/docs/commands/fd-deploy-check.md +166 -9
  54. package/docs/commands/fd-design.md +101 -0
  55. package/docs/commands/fd-discuss.md +87 -20
  56. package/docs/commands/fd-doctor.md +100 -13
  57. package/docs/commands/fd-done.md +215 -0
  58. package/docs/commands/fd-execute.md +104 -0
  59. package/docs/commands/fd-fix-bug.md +144 -24
  60. package/docs/commands/fd-map-codebase.md +85 -21
  61. package/docs/commands/fd-multi-repo.md +155 -40
  62. package/docs/commands/fd-new-feature.md +63 -19
  63. package/docs/commands/fd-plan.md +80 -27
  64. package/docs/commands/fd-quick.md +143 -29
  65. package/docs/commands/fd-reflect.md +81 -13
  66. package/docs/commands/fd-resume.md +65 -8
  67. package/docs/commands/fd-status.md +80 -12
  68. package/docs/commands/fd-suggest.md +114 -0
  69. package/docs/commands/fd-translate-intent.md +69 -9
  70. package/docs/commands/fd-verify.md +71 -14
  71. package/docs/commands/fd-write-docs.md +121 -8
  72. package/docs/concepts/architecture.md +163 -0
  73. package/docs/concepts/governance.md +242 -0
  74. package/docs/concepts/intelligence.md +145 -0
  75. package/docs/concepts/multi-repo.md +227 -0
  76. package/docs/concepts/workflows.md +205 -0
  77. package/docs/configuration/index.md +208 -0
  78. package/docs/configuration/opencode-settings.md +98 -0
  79. package/docs/getting-started/first-project.md +126 -0
  80. package/docs/getting-started/installation.md +73 -0
  81. package/docs/getting-started/quick-start.md +74 -0
  82. package/docs/index.md +36 -72
  83. package/docs/reference/hooks.md +176 -0
  84. package/docs/reference/rules.md +109 -0
  85. package/docs/skills/code-review.md +47 -0
  86. package/docs/skills/index.md +148 -0
  87. package/docs/skills/planning.md +39 -0
  88. package/package.json +1 -1
  89. package/src/commands/fd-deploy-check.md +2 -2
  90. package/src/commands/fd-discuss.md +128 -7
  91. package/src/commands/fd-done.md +196 -0
  92. package/src/commands/fd-execute.md +43 -6
  93. package/src/commands/fd-fix-bug.md +43 -6
  94. package/src/commands/fd-map-codebase.md +100 -20
  95. package/src/commands/fd-multi-repo.md +1 -1
  96. package/src/commands/fd-new-feature.md +14 -5
  97. package/src/commands/fd-plan.md +38 -1
  98. package/src/commands/fd-quick.md +77 -14
  99. package/src/commands/fd-resume.md +1 -1
  100. package/src/commands/fd-status.md +1 -1
  101. package/src/commands/fd-verify.md +16 -2
  102. package/src/commands/fd-write-docs.md +30 -5
  103. package/src/rules/common/behavioral.md +63 -0
  104. package/src/skills/codebase-mapping/SKILL.md +1 -1
  105. package/src/skills/context-load/SKILL.md +1 -1
  106. package/src/skills/multi-repo/SKILL.md +1 -1
  107. package/src/skills/repo-memory-graph/SKILL.md +1 -1
  108. package/dist/hooks/memory-hook.d.ts +0 -28
  109. package/dist/hooks/memory-hook.d.ts.map +0 -1
  110. package/dist/services/memory-store.d.ts +0 -73
  111. package/dist/services/memory-store.d.ts.map +0 -1
  112. package/dist/services/memory-store.test.d.ts +0 -2
  113. package/dist/services/memory-store.test.d.ts.map +0 -1
  114. package/dist/tools/memory-search.d.ts +0 -3
  115. package/dist/tools/memory-search.d.ts.map +0 -1
  116. package/dist/tools/memory-status.d.ts +0 -3
  117. package/dist/tools/memory-status.d.ts.map +0 -1
  118. package/docs/USER_GUIDE.md +0 -20
  119. package/docs/agents.md +0 -544
  120. package/docs/best-practices.md +0 -47
  121. package/docs/commands/fd-new-project.md +0 -24
  122. package/docs/commands.md +0 -557
  123. package/docs/configuration.md +0 -325
  124. package/docs/design-first-workflow.md +0 -94
  125. package/docs/feature-integration-architecture.md +0 -227
  126. package/docs/installation.md +0 -123
  127. package/docs/intelligence.md +0 -370
  128. package/docs/memory.md +0 -69
  129. package/docs/multi-repo.md +0 -201
  130. package/docs/notifications.md +0 -170
  131. package/docs/optimization-baseline.md +0 -21
  132. package/docs/quick-start.md +0 -197
  133. package/docs/rules.md +0 -432
  134. package/docs/skills.md +0 -417
  135. package/docs/workflows.md +0 -134
  136. package/src/commands/fd-new-project.md +0 -114
@@ -0,0 +1,51 @@
1
+ import type { PlanningState } from "../tools/planning-state-lib";
2
+ export interface CompletionReadiness {
3
+ valid: boolean;
4
+ /** Why it's ready (when valid) */
5
+ summary?: string;
6
+ /** Blocking reasons (when not valid) */
7
+ blockers: string[];
8
+ }
9
+ /**
10
+ * Validate whether a feature/workflow is in a finishable state.
11
+ *
12
+ * Rules:
13
+ * - STATE.md must exist (caller is responsible for passing state)
14
+ * - status must not be "planned" (nothing has started)
15
+ * - plan_confirmed must be true (plan must have been confirmed)
16
+ * - no active blockers
17
+ * - if design-first was required, it must be satisfied
18
+ * - status must be "verified" or "in_progress" (not already "complete")
19
+ */
20
+ export declare function validateCompletionReadiness(state: PlanningState): CompletionReadiness;
21
+ export interface CompletionMetadata {
22
+ /** Feature/phase number */
23
+ phase: number;
24
+ /** ISO timestamp of completion */
25
+ completedAt: string;
26
+ /** Who/what triggered completion */
27
+ completedBy: string;
28
+ /** Final status before done was called */
29
+ priorStatus: string;
30
+ /** Steps that were complete at time of closing */
31
+ stepsComplete: number[];
32
+ /** Whether /fd-verify had been run */
33
+ wasVerified: boolean;
34
+ /** Changed files summary from git diff */
35
+ changedFiles: string[];
36
+ /** Whether verify was explicitly skipped */
37
+ verifySkipped: boolean;
38
+ /** Whether codebase mapping was refreshed */
39
+ mappingRefreshed: boolean;
40
+ /** Freshness status of mapping after done */
41
+ mappingFreshnessStatus: "fresh" | "stale" | "skipped";
42
+ }
43
+ /**
44
+ * Build a human-readable DONE.md summary artifact for the current phase.
45
+ */
46
+ export declare function buildCompletionSummary(meta: CompletionMetadata): string;
47
+ /**
48
+ * Check whether the prior status indicates /fd-verify was run.
49
+ */
50
+ export declare function wasVerified(status: string): boolean;
51
+ //# sourceMappingURL=completion-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-validator.d.ts","sourceRoot":"","sources":["../../src/lib/completion-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAEhE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAA;IACd,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,aAAa,GAAG,mBAAmB,CAoDrF;AAED,MAAM,WAAW,kBAAkB;IACjC,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAA;IACnB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,kDAAkD;IAClD,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,sCAAsC;IACtC,WAAW,EAAE,OAAO,CAAA;IACpB,0CAA0C;IAC1C,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,4CAA4C;IAC5C,aAAa,EAAE,OAAO,CAAA;IACtB,6CAA6C;IAC7C,gBAAgB,EAAE,OAAO,CAAA;IACzB,6CAA6C;IAC7C,sBAAsB,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAA;CACtD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAuCvE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD"}
@@ -0,0 +1,24 @@
1
+ export interface RecommendedQuestion {
2
+ question: string;
3
+ recommendation: string;
4
+ rationale: string;
5
+ alternatives?: string[];
6
+ defaultIfNoResponse: string;
7
+ }
8
+ /**
9
+ * Render a RecommendedQuestion to a human-readable string format.
10
+ */
11
+ export declare function formatRecommendedQuestion(q: RecommendedQuestion): string;
12
+ /**
13
+ * Type guard — returns true only if the value is a valid RecommendedQuestion
14
+ * with all required fields present and non-empty.
15
+ *
16
+ * Also returns false for trivially bare question patterns.
17
+ */
18
+ export declare function validateRecommendedQuestion(value: unknown): value is RecommendedQuestion;
19
+ /**
20
+ * Parse a formatted RecommendedQuestion string back into an object.
21
+ * Returns null if the text does not contain the required fields.
22
+ */
23
+ export declare function parseQuestionBlocks(text: string): RecommendedQuestion | null;
24
+ //# sourceMappingURL=recommended-question.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommended-question.d.ts","sourceRoot":"","sources":["../../src/lib/recommended-question.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,mBAAmB,EAAE,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,CAOxE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAmCxF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAsC5E"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Research Gate — shared research-first enforcement for FlowDeck commands.
3
+ *
4
+ * Enforces that major workflow stages (discuss, plan, execute, fix-bug)
5
+ * perform targeted research BEFORE asking human questions or producing plans.
6
+ *
7
+ * Research is scoped to the stage:
8
+ * - discuss: gather facts and open questions from repo evidence
9
+ * - plan: gather implementation constraints and design options
10
+ * - execute: verify actual code paths and impacted files
11
+ * - fix-bug: inspect bug path, reproduction, and known remedies
12
+ *
13
+ * Research results are persisted in shared state so later stages can reuse them.
14
+ * Freshness metadata determines whether existing research is sufficient or
15
+ * new research is needed.
16
+ */
17
+ import { type PlanningState } from "../tools/planning-state-lib";
18
+ export type ResearchScope = "discuss" | "plan" | "execute" | "fix-bug";
19
+ /** Evidence collected during a research pass. */
20
+ export interface ResearchEvidence {
21
+ /** Which scope this evidence is for. */
22
+ scope: ResearchScope;
23
+ /** When this evidence was collected. */
24
+ collectedAt: string;
25
+ /** Files that were read/inspected. */
26
+ filesExplored: string[];
27
+ /** Key findings from the research. */
28
+ findings: string[];
29
+ /** Whether MCP tools were used. */
30
+ mcpToolsUsed: string[];
31
+ /** Whether the research gate was satisfied (enough evidence gathered). */
32
+ gateSatisfied: boolean;
33
+ /** Whether additional exploration was skipped (fresh evidence existed). */
34
+ skippedExploration: boolean;
35
+ /** Summary version when this research was conducted. */
36
+ summaryVersion: number;
37
+ }
38
+ /** Diagnostics logged during research. */
39
+ export interface ResearchDiagnostics {
40
+ /** Research scope. */
41
+ scope: ResearchScope;
42
+ /** Timestamp of research. */
43
+ timestamp: string;
44
+ /** Sources consulted. */
45
+ sourcesUsed: string[];
46
+ /** MCP tools invoked. */
47
+ mcpToolsInvoked: string[];
48
+ /** Evidence collected. */
49
+ evidenceCollected: string[];
50
+ /** Whether gate was satisfied. */
51
+ gateSatisfied: boolean;
52
+ /** Whether additional exploration was skipped. */
53
+ skippedExploration: boolean;
54
+ }
55
+ /**
56
+ * Check whether existing research in shared state is still fresh enough to reuse.
57
+ * Research is considered fresh if:
58
+ * 1. The summaryVersion matches the current state's summaryVersion
59
+ * 2. The state itself is fresh (within 5 minutes)
60
+ * 3. The research scope matches
61
+ */
62
+ export declare function isResearchFresh(state: PlanningState, scope: ResearchScope): boolean;
63
+ /**
64
+ * Persist research evidence to STATE.md so later stages can reuse it.
65
+ */
66
+ export declare function persistResearchEvidence(dir: string, scope: ResearchScope, evidence: ResearchEvidence): void;
67
+ /**
68
+ * Load persisted research evidence for a given scope.
69
+ */
70
+ export declare function loadResearchEvidence(dir: string, scope: ResearchScope): ResearchEvidence | null;
71
+ /**
72
+ * Build diagnostics log entry for a research pass.
73
+ */
74
+ export declare function buildResearchDiagnostics(evidence: ResearchEvidence): ResearchDiagnostics;
75
+ /**
76
+ * Log research diagnostics to console (for agent visibility).
77
+ */
78
+ export declare function logResearchDiagnostics(diags: ResearchDiagnostics): void;
79
+ /**
80
+ * Perform a research pass for a given scope, checking freshness first.
81
+ *
82
+ * Returns ResearchEvidence with gateSatisfied=true if enough evidence was gathered.
83
+ * If existing research is fresh, returns that and sets skippedExploration=true.
84
+ */
85
+ export declare function runResearchGate(dir: string, scope: ResearchScope, options?: {
86
+ forceRefresh?: boolean;
87
+ customEvidence?: Partial<ResearchEvidence>;
88
+ }): Promise<ResearchEvidence>;
89
+ /**
90
+ * Check if a stage should proceed or block based on research gate.
91
+ * Returns an error message if the gate is not satisfied and the stage should block.
92
+ */
93
+ export declare function researchGateStatus(evidence: ResearchEvidence): {
94
+ satisfied: boolean;
95
+ blocker?: string;
96
+ };
97
+ //# sourceMappingURL=research-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research-gate.d.ts","sourceRoot":"","sources":["../../src/lib/research-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAA0F,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAGxJ,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;AAEtE,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,KAAK,EAAE,aAAa,CAAA;IACpB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,mCAAmC;IACnC,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,0EAA0E;IAC1E,aAAa,EAAE,OAAO,CAAA;IACtB,2EAA2E;IAC3E,kBAAkB,EAAE,OAAO,CAAA;IAC3B,wDAAwD;IACxD,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,0CAA0C;AAC1C,MAAM,WAAW,mBAAmB;IAClC,sBAAsB;IACtB,KAAK,EAAE,aAAa,CAAA;IACpB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,yBAAyB;IACzB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,yBAAyB;IACzB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,0BAA0B;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,kCAAkC;IAClC,aAAa,EAAE,OAAO,CAAA;IACtB,kDAAkD;IAClD,kBAAkB,EAAE,OAAO,CAAA;CAC5B;AAID;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAInF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CA0B3G;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAa/F;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,mBAAmB,CAUxF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAUvE;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE;IACR,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;CAC3C,GACA,OAAO,CAAC,gBAAgB,CAAC,CAyH3B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAQvG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=research-gate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research-gate.test.d.ts","sourceRoot":"","sources":["../../src/lib/research-gate.test.ts"],"names":[],"mappings":""}
@@ -1,12 +1,16 @@
1
1
  /**
2
2
  * FlowDeck built-in MCP server configurations.
3
3
  *
4
- * Three free, read-only remote MCPs are enabled by default:
4
+ * Four free, read-only remote MCPs are enabled by default:
5
5
  * - context7 https://mcp.context7.com/mcp (library docs lookup)
6
6
  * - websearch https://mcp.exa.ai/mcp (web search via Exa)
7
7
  * - grep_app https://mcp.grep.app (code search)
8
+ * - github https://api.githubcopilot.com/mcp/ (GitHub code search)
8
9
  *
9
- * Disable individual MCPs with: FLOWDECK_DISABLE_MCP=context7,websearch,grep_app
10
+ * Local stdio MCPs (when installed):
11
+ * - codegraph codegraph serve --mcp (code knowledge graph — symbol search, call graphs, impact analysis)
12
+ *
13
+ * Disable individual MCPs with: FLOWDECK_DISABLE_MCP=context7,websearch,grep_app,github,codegraph
10
14
  */
11
15
  type RemoteMcp = {
12
16
  type: "remote";
@@ -15,6 +19,13 @@ type RemoteMcp = {
15
19
  headers?: Record<string, string>;
16
20
  oauth?: false;
17
21
  };
18
- export declare function createFlowDeckMcps(): Record<string, RemoteMcp>;
22
+ type LocalMcp = {
23
+ type: "local";
24
+ command: string;
25
+ args?: string[];
26
+ env?: Record<string, string>;
27
+ enabled: boolean;
28
+ };
29
+ export declare function createFlowDeckMcps(): Record<string, RemoteMcp | LocalMcp>;
19
30
  export {};
20
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAOD,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAuC9D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,KAAK,CAAA;CACd,CAAA;AAED,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAOD,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC,CAgEzE"}
@@ -0,0 +1,36 @@
1
+ export interface CodegraphMeta {
2
+ installed: boolean;
3
+ indexed: boolean;
4
+ lastIndexedAt: string;
5
+ lastIndexedRevision: string;
6
+ lastIndexedBy: string;
7
+ freshnessStatus: "fresh" | "stale" | "unknown";
8
+ installLog: string;
9
+ indexLog: string;
10
+ }
11
+ export declare function isCodegraphInstalled(): boolean;
12
+ export declare function isCodegraphIndexed(dir: string): boolean;
13
+ export declare function readCodegraphMeta(dir: string): CodegraphMeta;
14
+ export declare function writeCodegraphMeta(dir: string, meta: CodegraphMeta): void;
15
+ export declare function isCodegraphFresh(dir: string, maxAgeMs?: number): boolean;
16
+ export declare function getCurrentRevision(dir: string): string;
17
+ export declare function getChangedFilesSince(dir: string, revision: string): string[];
18
+ export declare function hasChangedSinceLastIndex(dir: string): boolean;
19
+ export interface InstallResult {
20
+ success: boolean;
21
+ alreadyInstalled: boolean;
22
+ log: string;
23
+ error?: string;
24
+ }
25
+ export declare function installCodegraph(): InstallResult;
26
+ export interface IndexResult {
27
+ success: boolean;
28
+ full: boolean;
29
+ log: string;
30
+ changedFiles: string[];
31
+ error?: string;
32
+ }
33
+ export declare function initCodegraphIndex(dir: string, agent: string): IndexResult;
34
+ export declare function refreshCodegraphIndex(dir: string, agent: string): IndexResult;
35
+ export declare function markCodegraphStale(dir: string): void;
36
+ //# sourceMappingURL=codegraph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegraph.d.ts","sourceRoot":"","sources":["../../src/services/codegraph.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAA;IAC9C,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAMD,wBAAgB,oBAAoB,IAAI,OAAO,CAW9C;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CA6B5D;AAkDD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAgBzE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAmB,GAAG,OAAO,CAOlF;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYtD;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAc5E;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAK7D;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,gBAAgB,EAAE,OAAO,CAAA;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAmChD;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CA8E1E;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CA+D7E;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAGpD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codegraph.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegraph.test.d.ts","sourceRoot":"","sources":["../../src/services/codegraph.test.ts"],"names":[],"mappings":""}
@@ -43,6 +43,17 @@ export declare function auditTextForInvalidCommands(text: string): AuditResult;
43
43
  * a note that the command is unavailable. Leaves valid commands untouched.
44
44
  */
45
45
  export declare function rewriteInvalidCommandRefs(text: string): string;
46
+ /**
47
+ * Combined full audit: checks both invalid /fd-* command references AND
48
+ * bare /word references missing the fd- prefix. Use this for file integrity tests.
49
+ */
50
+ export interface FullAuditResult extends AuditResult {
51
+ /** Bare /word references that are missing the fd- prefix (e.g. /plan → /fd-plan) */
52
+ barePrefixErrors: string[];
53
+ /** True if any issue was found — either invalid /fd-* refs or bare prefix errors */
54
+ hasAnyIssue: boolean;
55
+ }
56
+ export declare function auditTextFull(text: string): FullAuditResult;
46
57
  /**
47
58
  * Return the full canonical command inventory for inspection/testing.
48
59
  */
@@ -1 +1 @@
1
- {"version":3,"file":"command-validator.d.ts","sourceRoot":"","sources":["../../src/services/command-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,KAAK,EAAE,uBAAuB,EAAE,CAAA;IAChC,UAAU,EAAE,OAAO,CAAA;CACpB;AAQD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAmB7E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAG/D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAY9D;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAqBrE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,MAAM,EAAE,CAEvD"}
1
+ {"version":3,"file":"command-validator.d.ts","sourceRoot":"","sources":["../../src/services/command-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,EAAE,uBAAuB,EAAE,CAAA;IAClC,KAAK,EAAE,uBAAuB,EAAE,CAAA;IAChC,UAAU,EAAE,OAAO,CAAA;CACpB;AAYD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGnD;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,uBAAuB,CAmB7E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAG/D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAY9D;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAqBrE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,oFAAoF;IACpF,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,oFAAoF;IACpF,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAQ3D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,MAAM,EAAE,CAEvD"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Preflight Explorer Service
3
+ *
4
+ * Performs autonomous codebase exploration before any clarifying question is
5
+ * emitted to the user. Both /fd-quick and /fd-discuss run this first.
6
+ *
7
+ * Contract:
8
+ * 1. exploreRepo(dir) → ExplorationResult (what exists in the project)
9
+ * 2. canAnswerFromEvidence(question, result) → boolean (suppress logic)
10
+ * 3. shouldSuppressQuestion(q, result, history) → SuppressResult
11
+ * 4. deriveTaskContext(task, result) → DerivedTaskContext (task-relative findings)
12
+ *
13
+ * This module reads the filesystem synchronously so it can be used in both
14
+ * synchronous test harnesses and async agent runtimes.
15
+ */
16
+ export interface ExplorationResult {
17
+ /** Whether .planning/STATE.md was found */
18
+ hasStateMD: boolean;
19
+ /** Whether .planning/PROJECT.md was found */
20
+ hasProjectMD: boolean;
21
+ /** Whether AGENTS.md was found at repo root */
22
+ hasAgentsMD: boolean;
23
+ /** Whether .planning/phases/ has any prior phase directories */
24
+ hasPriorPhases: boolean;
25
+ /** Whether .planning/phases/ has any DISCUSS.md from prior sessions */
26
+ hasPriorDiscussions: boolean;
27
+ /** fd-* command names found on disk (from src/commands/*.md) */
28
+ availableCommands: string[];
29
+ /** Agent names registered in this FlowDeck installation */
30
+ availableAgents: string[];
31
+ /** Skill directory names found on disk (from src/skills/ subdirectories) */
32
+ availableSkills: string[];
33
+ /** Tech stack indicators inferred from package.json / go.mod / Cargo.toml etc. */
34
+ techStack: string[];
35
+ /** Config keys present in flowdeck.json if it exists */
36
+ configKeys: string[];
37
+ /** Rules / governance keys declared in flowdeck.json */
38
+ governanceEnabled: boolean;
39
+ /** Implementation pattern hints inferred from src/ directory layout */
40
+ implementationPatterns: string[];
41
+ /** Relative paths of files that seem relevant to the task keywords */
42
+ relevantFiles: string[];
43
+ /** Evidence items that can answer common scoping questions */
44
+ evidenceItems: EvidenceItem[];
45
+ /** ISO timestamp when exploration ran */
46
+ exploredAt: string;
47
+ }
48
+ export interface EvidenceItem {
49
+ /** The kind of question this evidence answers */
50
+ answersQuestion: EvidenceQuestionKind;
51
+ /** Human-readable evidence summary */
52
+ summary: string;
53
+ /** Source path (relative) */
54
+ source: string;
55
+ }
56
+ export type EvidenceQuestionKind = "what-tech-stack" | "is-project-initialized" | "what-is-current-phase" | "what-patterns-exist" | "is-ui-heavy" | "has-existing-tests" | "has-existing-docs" | "has-ci-cd" | "what-agents-available" | "what-commands-available" | "what-skills-available" | "has-prior-decisions" | "has-governance";
57
+ export interface DerivedTaskContext {
58
+ /** Whether the task appears to touch frontend/UI code based on repo evidence */
59
+ likelyUITask: boolean;
60
+ /** Whether the task appears to touch API/backend based on repo evidence */
61
+ likelyBackendTask: boolean;
62
+ /** Whether CI/CD config exists (relevant for deploy tasks) */
63
+ hasCICD: boolean;
64
+ /** Whether existing tests exist in the project */
65
+ hasTests: boolean;
66
+ /** Whether existing documentation exists */
67
+ hasDocs: boolean;
68
+ /** Whether governance layer is active */
69
+ hasGovernance: boolean;
70
+ /** Relevant files for this specific task */
71
+ relevantFiles: string[];
72
+ /** Tech stack summary */
73
+ techStack: string[];
74
+ }
75
+ export interface SuppressResult {
76
+ /** Whether the question should be suppressed */
77
+ suppress: boolean;
78
+ /** Reason for suppression (if suppressed) */
79
+ reason?: string;
80
+ /** True when the question was answered by repo evidence (vs. session dedup) */
81
+ answeredByEvidence?: boolean;
82
+ /** The evidence that answers the question (if suppressed) */
83
+ evidence?: EvidenceItem[];
84
+ }
85
+ /**
86
+ * Explore the repository at `dir` and return structured findings.
87
+ * All filesystem reads are synchronous so this can be called in test harnesses.
88
+ *
89
+ * @param dir - Absolute path to repo root (or closest available directory)
90
+ */
91
+ export declare function exploreRepo(dir: string): ExplorationResult;
92
+ /**
93
+ * Narrow the exploration result to what is specifically relevant for a given task.
94
+ * Populates `relevantFiles` based on task keywords.
95
+ */
96
+ export declare function deriveTaskContext(taskDescription: string, result: ExplorationResult, dir: string): DerivedTaskContext;
97
+ /**
98
+ * Determine whether a candidate question should be suppressed because it can
99
+ * already be answered from repo evidence.
100
+ *
101
+ * A question is suppressed when:
102
+ * 1. The repo contains direct evidence that answers it, OR
103
+ * 2. It was already asked in the current session history, OR
104
+ * 3. It is a trivially answerable question given known project state
105
+ */
106
+ export declare function shouldSuppressQuestion(question: string, result: ExplorationResult, sessionHistory: string[]): SuppressResult;
107
+ /**
108
+ * Check if a specific question can be answered from the exploration result alone.
109
+ */
110
+ export declare function canAnswerFromEvidence(question: string, result: ExplorationResult): boolean;
111
+ /**
112
+ * Attempt to resolve a `clarificationNeeded` classification using exploration
113
+ * context. Returns an updated `clarificationNeeded` flag and an optional
114
+ * resolved task type hint.
115
+ *
116
+ * Called by quick-router after classifyTask when clarificationNeeded=true.
117
+ */
118
+ export interface ExplorationRefinement {
119
+ /** Whether clarification is still required after applying exploration data */
120
+ clarificationStillNeeded: boolean;
121
+ /** Reason clarification is no longer needed (if resolved) */
122
+ resolvedReason?: string;
123
+ /**
124
+ * Evidence-based context to pass to @supervisor if clarification is still needed.
125
+ * This lets the supervisor ask a tighter question.
126
+ */
127
+ supervisorContext?: string;
128
+ }
129
+ export declare function refineClassification(clarificationPrompt: string, result: ExplorationResult, sessionHistory: string[]): ExplorationRefinement;
130
+ //# sourceMappingURL=preflight-explorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight-explorer.d.ts","sourceRoot":"","sources":["../../src/services/preflight-explorer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,UAAU,EAAE,OAAO,CAAA;IACnB,6CAA6C;IAC7C,YAAY,EAAE,OAAO,CAAA;IACrB,+CAA+C;IAC/C,WAAW,EAAE,OAAO,CAAA;IACpB,gEAAgE;IAChE,cAAc,EAAE,OAAO,CAAA;IACvB,uEAAuE;IACvE,mBAAmB,EAAE,OAAO,CAAA;IAC5B,gEAAgE;IAChE,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,2DAA2D;IAC3D,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,4EAA4E;IAC5E,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,kFAAkF;IAClF,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,wDAAwD;IACxD,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,wDAAwD;IACxD,iBAAiB,EAAE,OAAO,CAAA;IAC1B,uEAAuE;IACvE,sBAAsB,EAAE,MAAM,EAAE,CAAA;IAChC,sEAAsE;IACtE,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,8DAA8D;IAC9D,aAAa,EAAE,YAAY,EAAE,CAAA;IAC7B,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,eAAe,EAAE,oBAAoB,CAAA;IACrC,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAA;IACf,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,oBAAoB,GAC5B,iBAAiB,GACjB,wBAAwB,GACxB,uBAAuB,GACvB,qBAAqB,GACrB,aAAa,GACb,oBAAoB,GACpB,mBAAmB,GACnB,WAAW,GACX,uBAAuB,GACvB,yBAAyB,GACzB,uBAAuB,GACvB,qBAAqB,GACrB,gBAAgB,CAAA;AAEpB,MAAM,WAAW,kBAAkB;IACjC,gFAAgF;IAChF,YAAY,EAAE,OAAO,CAAA;IACrB,2EAA2E;IAC3E,iBAAiB,EAAE,OAAO,CAAA;IAC1B,8DAA8D;IAC9D,OAAO,EAAE,OAAO,CAAA;IAChB,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAA;IACjB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAA;IAChB,yCAAyC;IACzC,aAAa,EAAE,OAAO,CAAA;IACtB,4CAA4C;IAC5C,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,yBAAyB;IACzB,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,QAAQ,EAAE,OAAO,CAAA;IACjB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAA;CAC1B;AA2DD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAoE1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,iBAAiB,EACzB,GAAG,EAAE,MAAM,GACV,kBAAkB,CAoCpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,EACzB,cAAc,EAAE,MAAM,EAAE,GACvB,cAAc,CA4BhB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAIT;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,8EAA8E;IAC9E,wBAAwB,EAAE,OAAO,CAAA;IACjC,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,oBAAoB,CAClC,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,iBAAiB,EACzB,cAAc,EAAE,MAAM,EAAE,GACvB,qBAAqB,CA8CvB"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Preflight Explorer Tests
3
+ *
4
+ * Covers:
5
+ * - exploreRepo: discovers commands, agents, skills, tech stack from filesystem
6
+ * - canAnswerFromEvidence: correctly identifies suppressible questions
7
+ * - shouldSuppressQuestion: suppresses answered / duplicate questions
8
+ * - deriveTaskContext: narrows findings to task-relevant context
9
+ * - refineClassification: resolves ambiguous classification via evidence
10
+ * - createQuestionGuard: tracks asked questions and prevents duplicates
11
+ * - filterQuestions: returns only questions that pass the guard
12
+ * - needsSupervisorClarification: returns false when all questions are answered
13
+ * - classifyTaskWithContext: uses exploration to resolve ambiguity
14
+ * - createQuickRunState: persists exploration snapshot
15
+ * - /fd-quick performs codebase exploration before asking questions
16
+ * - /fd-discuss performs codebase exploration before asking questions
17
+ * - repo evidence prevents unnecessary human questions
18
+ * - supervisor-agent receives only genuine ambiguity
19
+ * - worker agents do not ask ad hoc questions
20
+ * - feature/bug/UI/docs tasks route correctly after preflight
21
+ * - exploration results are stored and reused
22
+ * - repeated question suppression works
23
+ */
24
+ export {};
25
+ //# sourceMappingURL=preflight-explorer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preflight-explorer.test.d.ts","sourceRoot":"","sources":["../../src/services/preflight-explorer.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Question Guard Service
3
+ *
4
+ * Prevents redundant or unnecessary questions from being emitted to the user.
5
+ *
6
+ * Both /fd-quick and /fd-discuss use this guard before forwarding any
7
+ * clarifying question to @supervisor. Worker agents MUST NOT call ask_user
8
+ * directly — they check this guard first, and if the answer exists in repo
9
+ * evidence or session history, the question is dropped.
10
+ *
11
+ * Contract:
12
+ * 1. createQuestionGuard(history?) → QuestionGuard instance
13
+ * 2. guard.check(question, evidence) → CheckResult
14
+ * 3. guard.record(question) → void
15
+ * 4. guard.getAsked() → string[]
16
+ *
17
+ * Only questions that pass the guard should be forwarded to @supervisor.
18
+ * @supervisor asks the human. Worker agents never ask the human directly.
19
+ */
20
+ import type { ExplorationResult } from "./preflight-explorer";
21
+ export interface CheckResult {
22
+ /** Whether the question should be allowed through to @supervisor */
23
+ allow: boolean;
24
+ /** Reason the question was blocked (when allow=false) */
25
+ blockReason?: string;
26
+ /** Whether the block was due to repo evidence answering it */
27
+ answeredByEvidence?: boolean;
28
+ /** Whether the block was due to a duplicate question */
29
+ duplicate?: boolean;
30
+ /** Field names missing from the question block (when allow=false due to missing recommendation) */
31
+ missingRecommendationFields?: string[];
32
+ /** Hint for how to rewrite a bare question into a recommended question */
33
+ rewriteHint?: string;
34
+ }
35
+ export interface QuestionGuard {
36
+ /**
37
+ * Check whether a question should be forwarded to @supervisor.
38
+ *
39
+ * Returns allow=true only when:
40
+ * - The question has not been asked before in this session
41
+ * - The question cannot be answered from repo evidence
42
+ * - The question is not trivially implied by known state
43
+ */
44
+ check(question: string, exploration: ExplorationResult | null): CheckResult;
45
+ /**
46
+ * Record that a question was asked. Call this after forwarding to @supervisor
47
+ * so future identical questions are suppressed.
48
+ */
49
+ record(question: string): void;
50
+ /** Return all questions recorded in this guard instance. */
51
+ getAsked(): string[];
52
+ /** Reset the guard (for new session/run). */
53
+ reset(): void;
54
+ }
55
+ /**
56
+ * Create a QuestionGuard.
57
+ *
58
+ * @param initialHistory - Questions already asked in this session (for
59
+ * persistence across restarts). Pass an empty array for new sessions.
60
+ */
61
+ export declare function createQuestionGuard(initialHistory?: string[]): QuestionGuard;
62
+ /**
63
+ * Convenience: check a list of candidate questions and return only those
64
+ * that should be forwarded to @supervisor. Records allowed questions.
65
+ */
66
+ export declare function filterQuestions(candidates: string[], guard: QuestionGuard, exploration: ExplorationResult | null): string[];
67
+ /**
68
+ * Determine whether supervisor clarification is warranted at all.
69
+ * Returns false when:
70
+ * - No questions remain after evidence filtering
71
+ * - All questions were answered by the exploration result
72
+ *
73
+ * Call this before invoking @supervisor to avoid empty escalations.
74
+ */
75
+ export declare function needsSupervisorClarification(questions: string[], guard: QuestionGuard, exploration: ExplorationResult | null): boolean;
76
+ /**
77
+ * Strict check for worker agents (coder, planner, tester, etc.).
78
+ *
79
+ * Worker agents MUST NOT ask the human directly. They must either:
80
+ * a) use repo evidence (this returns { canProceed: true, evidence })
81
+ * b) report missing data to orchestrator/supervisor
82
+ *
83
+ * This function decides which path to take.
84
+ */
85
+ export interface WorkerAgentDecision {
86
+ /** True when the worker can proceed using evidence alone */
87
+ canProceed: boolean;
88
+ /** True when the worker must stop and report missing data upward */
89
+ mustEscalate: boolean;
90
+ /** Evidence that allows the worker to proceed (when canProceed=true) */
91
+ evidence?: string;
92
+ /** What data is missing (when mustEscalate=true) */
93
+ missingData?: string;
94
+ }
95
+ export declare function workerAgentDecision(requiredInfo: string, exploration: ExplorationResult): WorkerAgentDecision;
96
+ //# sourceMappingURL=question-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question-guard.d.ts","sourceRoot":"","sources":["../../src/services/question-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAK7D,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,KAAK,EAAE,OAAO,CAAA;IACd,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,mGAAmG;IACnG,2BAA2B,CAAC,EAAE,MAAM,EAAE,CAAA;IACtC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI,GAAG,WAAW,CAAA;IAC3E;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,4DAA4D;IAC5D,QAAQ,IAAI,MAAM,EAAE,CAAA;IACpB,6CAA6C;IAC7C,KAAK,IAAI,IAAI,CAAA;CACd;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,cAAc,GAAE,MAAM,EAAO,GAAG,aAAa,CAuFhF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAAE,EACpB,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,iBAAiB,GAAG,IAAI,GACpC,MAAM,EAAE,CASV;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EAAE,EACnB,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,iBAAiB,GAAG,IAAI,GACpC,OAAO,CAGT;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,UAAU,EAAE,OAAO,CAAA;IACnB,oEAAoE;IACpE,YAAY,EAAE,OAAO,CAAA;IACrB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,iBAAiB,GAC7B,mBAAmB,CAmBrB"}
@@ -12,7 +12,14 @@
12
12
  *
13
13
  * It does NOT create new workflows. It routes to the existing commands:
14
14
  * fd-discuss, fd-design, fd-plan, fd-execute, fd-fix-bug, fd-write-docs, fd-verify
15
+ *
16
+ * Autonomy contract:
17
+ * - classifyTaskWithContext() must be preferred over classifyTask() when a
18
+ * preflight ExplorationResult is available.
19
+ * - classificationNeeded is set to false whenever exploration evidence
20
+ * supplies the missing context, eliminating the human question entirely.
15
21
  */
22
+ import type { ExplorationResult } from "./preflight-explorer";
16
23
  export type TaskType = "feature" | "ui-feature" | "bugfix" | "docs" | "simple" | "ambiguous";
17
24
  /** A single stage in a workflow sequence, mapping to an existing fd-* command. */
18
25
  export interface WorkflowStage {
@@ -110,9 +117,41 @@ export interface QuickRunState {
110
117
  updatedAt: string;
111
118
  /** Final run outcome */
112
119
  outcome: "running" | "complete" | "blocked" | "failed";
120
+ /**
121
+ * Preflight exploration snapshot — persisted so later stages can
122
+ * reuse it without re-running exploration or re-asking the user.
123
+ */
124
+ preflightExploration?: {
125
+ exploredAt: string;
126
+ techStack: string[];
127
+ availableCommands: string[];
128
+ availableSkills: string[];
129
+ implementationPatterns: string[];
130
+ evidenceCount: number;
131
+ /** Whether clarification was resolved via evidence (no human asked) */
132
+ clarificationResolvedByEvidence: boolean;
133
+ /** The resolved reason when evidence answered the question */
134
+ clarificationResolvedReason?: string;
135
+ };
136
+ /** Questions that were suppressed by the guard (not sent to human) */
137
+ suppressedQuestions: string[];
113
138
  }
114
139
  /**
115
140
  * Create a fresh QuickRunState record for a new /fd-quick run.
116
141
  */
117
- export declare function createQuickRunState(taskDescription: string, classification: ClassificationResult): QuickRunState;
142
+ export declare function createQuickRunState(taskDescription: string, classification: ClassificationResult, exploration?: ExplorationResult): QuickRunState;
143
+ /**
144
+ * Classify a task description, using repo exploration evidence to resolve
145
+ * ambiguity before falling back to supervisor clarification.
146
+ *
147
+ * Prefer this over `classifyTask` whenever a preflight ExplorationResult is
148
+ * available. It eliminates unnecessary human questions when the repo already
149
+ * contains the answer.
150
+ *
151
+ * @param description - Free-text task from the user
152
+ * @param exploration - ExplorationResult from exploreRepo()
153
+ * @param sessionHistory - Questions already asked in this session (for
154
+ * deduplication via the question guard)
155
+ */
156
+ export declare function classifyTaskWithContext(description: string, exploration: ExplorationResult, sessionHistory?: string[]): ClassificationResult;
118
157
  //# sourceMappingURL=quick-router.d.ts.map