maestro-flow 0.3.8 → 0.3.9
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/.claude/commands/learn-decompose.md +3 -3
- package/.claude/commands/learn-follow.md +5 -5
- package/.claude/commands/learn-investigate.md +3 -3
- package/.claude/commands/learn-retro.md +6 -6
- package/.claude/commands/learn-second-opinion.md +3 -3
- package/.claude/commands/maestro-analyze.md +123 -99
- package/.claude/commands/maestro-brainstorm.md +2 -2
- package/.claude/commands/maestro-execute.md +137 -97
- package/.claude/commands/maestro-fork.md +111 -0
- package/.claude/commands/maestro-init.md +6 -6
- package/.claude/commands/maestro-merge.md +77 -0
- package/.claude/commands/maestro-milestone-audit.md +72 -60
- package/.claude/commands/maestro-milestone-complete.md +67 -59
- package/.claude/commands/maestro-milestone-release.md +6 -6
- package/.claude/commands/maestro-plan.md +151 -130
- package/.claude/commands/maestro-quick.md +4 -4
- package/.claude/commands/maestro-roadmap.md +5 -5
- package/.claude/commands/maestro-spec-generate.md +5 -5
- package/.claude/commands/maestro-ui-design.md +3 -3
- package/.claude/commands/maestro-verify.md +106 -87
- package/.claude/commands/maestro.md +10 -4
- package/.claude/commands/manage-codebase-rebuild.md +4 -4
- package/.claude/commands/manage-codebase-refresh.md +1 -1
- package/.claude/commands/manage-harvest.md +5 -5
- package/.claude/commands/manage-issue-discover.md +1 -1
- package/.claude/commands/manage-issue-execute.md +6 -6
- package/.claude/commands/manage-issue.md +6 -6
- package/.claude/commands/manage-learn.md +2 -2
- package/.claude/commands/manage-memory-capture.md +4 -4
- package/.claude/commands/manage-memory.md +2 -2
- package/.claude/commands/manage-status.md +24 -24
- package/.claude/commands/quality-business-test.md +5 -5
- package/.claude/commands/quality-debug.md +4 -4
- package/.claude/commands/quality-integration-test.md +4 -4
- package/.claude/commands/quality-refactor.md +3 -3
- package/.claude/commands/quality-retrospective.md +2 -2
- package/.claude/commands/quality-review.md +4 -4
- package/.claude/commands/quality-sync.md +3 -3
- package/.claude/commands/quality-test-gen.md +4 -4
- package/.claude/commands/quality-test.md +9 -9
- package/.claude/commands/spec-add.md +2 -2
- package/.claude/commands/spec-load.md +1 -1
- package/.claude/commands/spec-setup.md +5 -5
- package/.claude/commands/wiki-connect.md +3 -3
- package/.claude/commands/wiki-digest.md +4 -4
- package/.codex/skills/maestro-analyze/SKILL.md +52 -14
- package/.codex/skills/maestro-execute/SKILL.md +27 -26
- package/.codex/skills/maestro-milestone-audit/SKILL.md +103 -209
- package/.codex/skills/maestro-milestone-complete/SKILL.md +149 -158
- package/.codex/skills/maestro-plan/SKILL.md +47 -17
- package/.codex/skills/maestro-roadmap/SKILL.md +3 -2
- package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +2 -2
- package/.codex/skills/team-executor/roles/executor/commands/monitor.md +1 -1
- package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/monitor.md +2 -2
- package/.codex/skills/team-lifecycle-v4/specs/knowledge-transfer.md +2 -2
- package/.codex/skills/team-quality-assurance/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-review/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-testing/roles/coordinator/commands/monitor.md +1 -1
- package/README.md +19 -14
- package/README.zh-CN.md +16 -12
- package/bin/maestro-mcp.js +1 -1
- package/chains/_intent-map.json +21 -9
- package/chains/_router.json +30 -77
- package/chains/brainstorm-driven.json +17 -6
- package/chains/full-lifecycle.json +22 -23
- package/chains/milestone-close.json +20 -7
- package/chains/milestone-fork-merge.json +50 -0
- package/chains/roadmap-driven.json +17 -6
- package/chains/spec-driven.json +17 -6
- package/dashboard/dist/assets/{ArtifactsPage-BmPOu8sO.js → ArtifactsPage-DZNCi6tn.js} +12 -7
- package/dashboard/dist/assets/ChatInput-Bvr-FeEq.js +49 -0
- package/dashboard/dist/assets/ChatPage-D9zTkJZo.js +22 -0
- package/dashboard/dist/assets/CollabPage-B4NAHXS2.js +1 -0
- package/dashboard/dist/assets/ExecutionPanel-CFt4LJyq.js +1 -0
- package/dashboard/dist/assets/KanbanPage-C8USth6H.js +21 -0
- package/dashboard/dist/assets/{MarkdownRenderer-BjZ43aSa.js → MarkdownRenderer-X4af_WNb.js} +1 -1
- package/dashboard/dist/assets/McpPage-BKfCVIyU.js +21 -0
- package/dashboard/dist/assets/OutputPanel-BlBQFJSW.js +1 -0
- package/dashboard/dist/assets/ProblemsPanel-De3DLvoI.js +1 -0
- package/dashboard/dist/assets/{RequirementBoardPage-B7yRL0s_.js → RequirementBoardPage-Bf1trzqs.js} +2 -2
- package/dashboard/dist/assets/{RequirementPage-D8J_-b6O.js → RequirementPage-Bllxe2XI.js} +10 -5
- package/dashboard/dist/assets/{SpecsPage-6lO8v8_C.js → SpecsPage-9lwxKT27.js} +2 -2
- package/dashboard/dist/assets/{SupervisorPage-Ds5N378a.js → SupervisorPage-SusdfHFq.js} +1 -1
- package/dashboard/dist/assets/{TeamsPage-DrkKr17T.js → TeamsPage-DsuM6OwC.js} +2 -2
- package/dashboard/dist/assets/TreeBrowser-Q12qobZs.js +6 -0
- package/dashboard/dist/assets/WorkflowPage-D_Fzdy3_.js +6 -0
- package/dashboard/dist/assets/{arrow-left-CadP5YgU.js → arrow-left-Bqtb2hle.js} +1 -1
- package/dashboard/dist/assets/{check-5xufDzS8.js → check-u6fGOwQO.js} +1 -1
- package/dashboard/dist/assets/{chevron-right-CYbpR4ev.js → chevron-right-Csu22t58.js} +1 -1
- package/dashboard/dist/assets/{circle-Bm-5Q-Yh.js → circle-CMrkbRNg.js} +1 -1
- package/dashboard/dist/assets/{circle-alert-BqcYuT7x.js → circle-alert-c3tH1P4z.js} +1 -1
- package/dashboard/dist/assets/{circle-check-big-yyzAFysU.js → circle-check-big-TDSeWstm.js} +1 -1
- package/dashboard/dist/assets/{circle-check-DEVzW_lm.js → circle-check-gYxxSYuH.js} +1 -1
- package/dashboard/dist/assets/{code-BBdC8Wmw.js → code-CFN2uX9V.js} +1 -1
- package/dashboard/dist/assets/{columns-3-CQ9Trztr.js → columns-3-38xIDlzy.js} +1 -1
- package/dashboard/dist/assets/{download-DayuF-sn.js → download-DC7KkKyP.js} +1 -1
- package/dashboard/dist/assets/{folder-CqXeSKeC.js → folder-CWq_lAnf.js} +1 -1
- package/dashboard/dist/assets/index-DWG-WrzT.js +231 -0
- package/dashboard/dist/assets/{index-Dru5HYy0.js → index-Do71weNR.js} +1 -1
- package/dashboard/dist/assets/index-GUNJodSR.css +1 -0
- package/dashboard/dist/assets/{list-DBOD6IUt.js → list-CgIP_2A-.js} +1 -1
- package/dashboard/dist/assets/{minus-fQI1Syn2.js → minus-DYoN5UGk.js} +1 -1
- package/dashboard/dist/assets/{pen-line-Bkbbngl5.js → pen-line-Bh_WKYHm.js} +1 -1
- package/dashboard/dist/assets/{proxy-teW12DdZ.js → proxy-BKxDAKTj.js} +1 -1
- package/dashboard/dist/assets/{search-Bq3ygFUW.js → search-SieXnOgr.js} +1 -1
- package/dashboard/dist/assets/{shallow-22ZN8sFt.js → shallow-Bme1JY57.js} +1 -1
- package/dashboard/dist/assets/{table-BEYtdWc4.js → table-llyEtj-7.js} +1 -1
- package/dashboard/dist/assets/terminal-BB3Xfuv5.js +6 -0
- package/dashboard/dist/assets/{trash-2-DMqGBgcF.js → trash-2-C8f4vFFM.js} +1 -1
- package/dashboard/dist/assets/{zap-9DVkGVtt.js → zap-4uwlzVm0.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +8 -4
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.d.ts +1 -0
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js +2 -1
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js +20 -10
- package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/git.d.ts +2 -0
- package/dashboard/dist-server/dashboard/src/server/routes/git.js +79 -0
- package/dashboard/dist-server/dashboard/src/server/routes/git.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/server/routes/index.js +3 -0
- package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/workspace.js +43 -0
- package/dashboard/dist-server/dashboard/src/server/routes/workspace.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/state/state-manager.js +43 -3
- package/dashboard/dist-server/dashboard/src/server/state/state-manager.js.map +1 -1
- package/dashboard/package.json +59 -59
- package/dist/src/cli.js +3 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/{team.d.ts → collab.d.ts} +2 -2
- package/dist/src/commands/collab.d.ts.map +1 -0
- package/dist/src/commands/{team.js → collab.js} +391 -24
- package/dist/src/commands/collab.js.map +1 -0
- package/dist/src/commands/msg.d.ts.map +1 -1
- package/dist/src/commands/msg.js +4 -3
- package/dist/src/commands/msg.js.map +1 -1
- package/dist/src/hooks/team-monitor.d.ts.map +1 -1
- package/dist/src/hooks/team-monitor.js +16 -0
- package/dist/src/hooks/team-monitor.js.map +1 -1
- package/dist/src/tools/collab-adapter.d.ts +85 -0
- package/dist/src/tools/collab-adapter.d.ts.map +1 -0
- package/dist/src/tools/collab-adapter.js +320 -0
- package/dist/src/tools/collab-adapter.js.map +1 -0
- package/dist/src/tools/namespace-guard.d.ts +2 -0
- package/dist/src/tools/namespace-guard.d.ts.map +1 -1
- package/dist/src/tools/namespace-guard.js +12 -0
- package/dist/src/tools/namespace-guard.js.map +1 -1
- package/dist/src/tools/phase-gate-evaluator.d.ts +45 -0
- package/dist/src/tools/phase-gate-evaluator.d.ts.map +1 -0
- package/dist/src/tools/phase-gate-evaluator.js +42 -0
- package/dist/src/tools/phase-gate-evaluator.js.map +1 -0
- package/dist/src/tools/team-members.d.ts +18 -0
- package/dist/src/tools/team-members.d.ts.map +1 -1
- package/dist/src/tools/team-members.js +50 -0
- package/dist/src/tools/team-members.js.map +1 -1
- package/dist/src/tools/team-tasks.d.ts +120 -0
- package/dist/src/tools/team-tasks.d.ts.map +1 -0
- package/dist/src/tools/team-tasks.js +365 -0
- package/dist/src/tools/team-tasks.js.map +1 -0
- package/dist/src/tools/transition-recorder.d.ts +3 -0
- package/dist/src/tools/transition-recorder.d.ts.map +1 -1
- package/dist/src/tools/transition-recorder.js +52 -1
- package/dist/src/tools/transition-recorder.js.map +1 -1
- package/dist/src/utils/get-version.d.ts.map +1 -1
- package/dist/src/utils/get-version.js +15 -4
- package/dist/src/utils/get-version.js.map +1 -1
- package/package.json +1 -1
- package/templates/config.json +7 -0
- package/templates/worktree-scope.json +10 -0
- package/templates/worktrees.json +27 -0
- package/workflows/analyze.md +86 -36
- package/workflows/brainstorm.md +17 -37
- package/workflows/execute.md +94 -28
- package/workflows/fork.md +309 -0
- package/workflows/init.md +10 -1
- package/workflows/issue.md +66 -7
- package/workflows/maestro-coordinate.md +23 -16
- package/workflows/maestro.md +52 -35
- package/workflows/merge.md +285 -0
- package/workflows/milestone-audit.md +89 -70
- package/workflows/milestone-complete.md +89 -156
- package/workflows/plan.md +122 -17
- package/workflows/retrospective.md +3 -3
- package/workflows/roadmap.md +11 -3
- package/workflows/spec-generate.md +9 -0
- package/workflows/status.md +76 -27
- package/workflows/ui-design.md +14 -12
- package/workflows/verify.md +44 -8
- package/.claude/commands/maestro-phase-add.md +0 -63
- package/.claude/commands/maestro-phase-transition.md +0 -75
- package/.codex/skills/maestro-phase-add/SKILL.md +0 -154
- package/.codex/skills/maestro-phase-transition/SKILL.md +0 -173
- package/chains/singles/phase-add.json +0 -31
- package/chains/singles/phase-transition.json +0 -23
- package/dashboard/dist/assets/ChatInput-CL8YDfOU.js +0 -67
- package/dashboard/dist/assets/ChatPage-CT-ozBK2.js +0 -8
- package/dashboard/dist/assets/CollabPage-C0rWMden.js +0 -1
- package/dashboard/dist/assets/KanbanPage-C6WbAlwI.js +0 -16
- package/dashboard/dist/assets/McpPage-BPIXADQi.js +0 -16
- package/dashboard/dist/assets/TreeBrowser-g_QUKemL.js +0 -11
- package/dashboard/dist/assets/WorkflowPage-X8aNkDEr.js +0 -6
- package/dashboard/dist/assets/git-branch-SqFf4Ru5.js +0 -6
- package/dashboard/dist/assets/index-D2Mtyw7I.css +0 -1
- package/dashboard/dist/assets/index-nufWop4p.js +0 -231
- package/dashboard/dist/assets/wrench-B84-zdLI.js +0 -11
- package/dist/src/commands/team.d.ts.map +0 -1
- package/dist/src/commands/team.js.map +0 -1
- package/workflows/phase-add.md +0 -252
- package/workflows/phase-transition.md +0 -399
|
@@ -90,6 +90,22 @@ export function runTeamMonitor(input) {
|
|
|
90
90
|
? input.tool_input.path
|
|
91
91
|
: undefined;
|
|
92
92
|
if (filePath) {
|
|
93
|
+
// Detect task file writes to .workflow/collab/tasks/
|
|
94
|
+
if (filePath.includes('.workflow/collab/tasks/') || filePath.includes('.workflow\\collab\\tasks\\')) {
|
|
95
|
+
const match = filePath.match(/tasks[\\/](TASK-\d+)\.json$/);
|
|
96
|
+
if (match) {
|
|
97
|
+
reportActivity({
|
|
98
|
+
user: self.uid,
|
|
99
|
+
host: self.host,
|
|
100
|
+
action: 'task.edit',
|
|
101
|
+
task_id: match[1],
|
|
102
|
+
target: action.toLowerCase(),
|
|
103
|
+
});
|
|
104
|
+
return; // Report once for task edits; skip generic heartbeat below.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Namespace guard: check file write operations stay within boundaries.
|
|
108
|
+
// V1 is advisory — log warning but never block.
|
|
93
109
|
const guardResult = evaluateNamespaceGuard(filePath, self.uid, getProjectRoot());
|
|
94
110
|
if (!guardResult.allowed) {
|
|
95
111
|
console.error(`[TeamMonitor] WARNING: namespace violation (advisory): ${guardResult.reason}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-monitor.js","sourceRoot":"","sources":["../../../src/hooks/team-monitor.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"team-monitor.js","sourceRoot":"","sources":["../../../src/hooks/team-monitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collaboration adapter interface and registry (team-lite collaboration).
|
|
3
|
+
*
|
|
4
|
+
* Provides a pluggable notification layer that maps collab events to external
|
|
5
|
+
* services (DingTalk, Linear, etc.). Adapters are configured via
|
|
6
|
+
* `.workflow/collab/adapters.json` and instantiated on demand.
|
|
7
|
+
*
|
|
8
|
+
* Fire-and-forget contract: `notifyAdapters()` is synchronous (void return),
|
|
9
|
+
* spawns async work internally, and NEVER throws -- matching the
|
|
10
|
+
* `reportActivity` pattern in `team-activity.ts`.
|
|
11
|
+
*
|
|
12
|
+
* Strict namespace separation: this module belongs to the HUMAN collaboration
|
|
13
|
+
* domain (`.workflow/collab/`).
|
|
14
|
+
*/
|
|
15
|
+
export type CollabEventType = 'task.created' | 'task.assigned' | 'task.status_changed' | 'task.checked' | 'role.changed';
|
|
16
|
+
export interface CollabEvent {
|
|
17
|
+
type: CollabEventType;
|
|
18
|
+
payload: Record<string, unknown>;
|
|
19
|
+
recipients?: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface CollabAdapter {
|
|
22
|
+
name: string;
|
|
23
|
+
sendNotification(event: CollabEvent): Promise<void>;
|
|
24
|
+
validateConfig(config: Record<string, unknown>): boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Adapter configuration shape.
|
|
28
|
+
*
|
|
29
|
+
* `enabled` lists adapter names to activate. Every other top-level key holds
|
|
30
|
+
* the per-adapter config block (arbitrary key-value pairs).
|
|
31
|
+
*
|
|
32
|
+
* The index signature uses `unknown` values so that both `Record<string, unknown>`
|
|
33
|
+
* (adapter config blocks) and `string[]` (the `enabled` field) are valid values.
|
|
34
|
+
*/
|
|
35
|
+
export interface AdapterConfig {
|
|
36
|
+
enabled: string[];
|
|
37
|
+
[adapterName: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
/** DingTalk webhook adapter with HMAC-SHA256 signing. */
|
|
40
|
+
export declare class DingTalkAdapter implements CollabAdapter {
|
|
41
|
+
readonly name = "dingtalk";
|
|
42
|
+
private webhook;
|
|
43
|
+
private secret;
|
|
44
|
+
validateConfig(config: Record<string, unknown>): boolean;
|
|
45
|
+
sendNotification(event: CollabEvent): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/** Linear GraphQL API adapter. */
|
|
48
|
+
export declare class LinearAdapter implements CollabAdapter {
|
|
49
|
+
readonly name = "linear";
|
|
50
|
+
private apiKey;
|
|
51
|
+
private teamId;
|
|
52
|
+
validateConfig(config: Record<string, unknown>): boolean;
|
|
53
|
+
sendNotification(event: CollabEvent): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/** Absolute path to the adapter configuration file. */
|
|
56
|
+
export declare function getAdaptersConfigPath(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Read and parse the adapter config file.
|
|
59
|
+
*
|
|
60
|
+
* Returns `{ enabled: [] }` if the file is missing, empty, or fails to parse.
|
|
61
|
+
* Never throws -- graceful fallback on any I/O or JSON error.
|
|
62
|
+
*/
|
|
63
|
+
export declare function loadAdapterConfig(): AdapterConfig;
|
|
64
|
+
/**
|
|
65
|
+
* Instantiate adapter classes based on the `enabled` array in config.
|
|
66
|
+
*
|
|
67
|
+
* For each name in `config.enabled`:
|
|
68
|
+
* 1. Look up the constructor in the built-in registry.
|
|
69
|
+
* 2. Instantiate and call `validateConfig` with the matching config block.
|
|
70
|
+
* 3. Keep only valid adapters; skip unknown or invalid ones.
|
|
71
|
+
*
|
|
72
|
+
* Returns an empty array when no adapters are configured or valid.
|
|
73
|
+
*/
|
|
74
|
+
export declare function getEnabledAdapters(config: AdapterConfig): CollabAdapter[];
|
|
75
|
+
/**
|
|
76
|
+
* Send a collab event to all enabled adapters.
|
|
77
|
+
*
|
|
78
|
+
* Fire-and-forget: this function is synchronous (returns void), dispatches
|
|
79
|
+
* notifications in parallel via `Promise.allSettled`, and NEVER throws.
|
|
80
|
+
* Individual adapter failures are logged to `console.error`.
|
|
81
|
+
*
|
|
82
|
+
* No-op when no adapters are configured.
|
|
83
|
+
*/
|
|
84
|
+
export declare function notifyAdapters(event: CollabEvent): void;
|
|
85
|
+
//# sourceMappingURL=collab-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collab-adapter.d.ts","sourceRoot":"","sources":["../../../src/tools/collab-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAaH,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,eAAe,GACf,qBAAqB,GACrB,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAC1D;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC;AAMD,yDAAyD;AACzD,qBAAa,eAAgB,YAAW,aAAa;IACnD,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,MAAM,CAAM;IAEpB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAQlD,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAoB1D;AAMD,kCAAkC;AAClC,qBAAa,aAAc,YAAW,aAAa;IACjD,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,MAAM,CAAM;IAEpB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAQlD,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAQ1D;AAeD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,aAAa,CAYjD;AAMD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,EAAE,CAqBzE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAqBvD"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collaboration adapter interface and registry (team-lite collaboration).
|
|
3
|
+
*
|
|
4
|
+
* Provides a pluggable notification layer that maps collab events to external
|
|
5
|
+
* services (DingTalk, Linear, etc.). Adapters are configured via
|
|
6
|
+
* `.workflow/collab/adapters.json` and instantiated on demand.
|
|
7
|
+
*
|
|
8
|
+
* Fire-and-forget contract: `notifyAdapters()` is synchronous (void return),
|
|
9
|
+
* spawns async work internally, and NEVER throws -- matching the
|
|
10
|
+
* `reportActivity` pattern in `team-activity.ts`.
|
|
11
|
+
*
|
|
12
|
+
* Strict namespace separation: this module belongs to the HUMAN collaboration
|
|
13
|
+
* domain (`.workflow/collab/`).
|
|
14
|
+
*/
|
|
15
|
+
import { createHmac } from 'node:crypto';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { request } from 'node:https';
|
|
19
|
+
import { getProjectRoot } from '../utils/path-validator.js';
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Built-in adapter: DingTalk
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/** DingTalk webhook adapter with HMAC-SHA256 signing. */
|
|
24
|
+
export class DingTalkAdapter {
|
|
25
|
+
name = 'dingtalk';
|
|
26
|
+
webhook = '';
|
|
27
|
+
secret = '';
|
|
28
|
+
validateConfig(config) {
|
|
29
|
+
if (typeof config.webhook !== 'string' || !config.webhook)
|
|
30
|
+
return false;
|
|
31
|
+
if (typeof config.secret !== 'string' || !config.secret)
|
|
32
|
+
return false;
|
|
33
|
+
this.webhook = config.webhook;
|
|
34
|
+
this.secret = config.secret;
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
async sendNotification(event) {
|
|
38
|
+
const timestamp = Date.now();
|
|
39
|
+
const stringToSign = `${timestamp}\n${this.secret}`;
|
|
40
|
+
const hmac = createHmac('sha256', this.secret);
|
|
41
|
+
hmac.update(stringToSign);
|
|
42
|
+
const sign = encodeURIComponent(hmac.digest('base64'));
|
|
43
|
+
const url = new URL(this.webhook);
|
|
44
|
+
url.searchParams.set('timestamp', String(timestamp));
|
|
45
|
+
url.searchParams.set('sign', sign);
|
|
46
|
+
const body = JSON.stringify({
|
|
47
|
+
msgtype: 'text',
|
|
48
|
+
text: {
|
|
49
|
+
content: formatEventSummary(event),
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
await postJSON(url.href, body);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Built-in adapter: Linear
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
/** Linear GraphQL API adapter. */
|
|
59
|
+
export class LinearAdapter {
|
|
60
|
+
name = 'linear';
|
|
61
|
+
apiKey = '';
|
|
62
|
+
teamId = '';
|
|
63
|
+
validateConfig(config) {
|
|
64
|
+
if (typeof config.apiKey !== 'string' || !config.apiKey)
|
|
65
|
+
return false;
|
|
66
|
+
if (typeof config.teamId !== 'string' || !config.teamId)
|
|
67
|
+
return false;
|
|
68
|
+
this.apiKey = config.apiKey;
|
|
69
|
+
this.teamId = config.teamId;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
async sendNotification(event) {
|
|
73
|
+
const { query, variables } = buildLinearMutation(event, this.teamId);
|
|
74
|
+
const body = JSON.stringify({ query, variables });
|
|
75
|
+
await postJSON('https://api.linear.app/graphql', body, {
|
|
76
|
+
Authorization: this.apiKey,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Adapter registry
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
const BUILTIN_ADAPTERS = {
|
|
84
|
+
dingtalk: DingTalkAdapter,
|
|
85
|
+
linear: LinearAdapter,
|
|
86
|
+
};
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Path helpers
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
/** Absolute path to the adapter configuration file. */
|
|
91
|
+
export function getAdaptersConfigPath() {
|
|
92
|
+
return join(getProjectRoot(), '.workflow', 'collab', 'adapters.json');
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Config loading
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
/**
|
|
98
|
+
* Read and parse the adapter config file.
|
|
99
|
+
*
|
|
100
|
+
* Returns `{ enabled: [] }` if the file is missing, empty, or fails to parse.
|
|
101
|
+
* Never throws -- graceful fallback on any I/O or JSON error.
|
|
102
|
+
*/
|
|
103
|
+
export function loadAdapterConfig() {
|
|
104
|
+
const configPath = getAdaptersConfigPath();
|
|
105
|
+
try {
|
|
106
|
+
const raw = readFileSync(configPath, 'utf-8');
|
|
107
|
+
const parsed = JSON.parse(raw);
|
|
108
|
+
if (!parsed || typeof parsed !== 'object')
|
|
109
|
+
return { enabled: [] };
|
|
110
|
+
const obj = parsed;
|
|
111
|
+
if (!Array.isArray(obj.enabled))
|
|
112
|
+
return { enabled: [] };
|
|
113
|
+
return parsed;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return { enabled: [] };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
// Adapter instantiation
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
/**
|
|
123
|
+
* Instantiate adapter classes based on the `enabled` array in config.
|
|
124
|
+
*
|
|
125
|
+
* For each name in `config.enabled`:
|
|
126
|
+
* 1. Look up the constructor in the built-in registry.
|
|
127
|
+
* 2. Instantiate and call `validateConfig` with the matching config block.
|
|
128
|
+
* 3. Keep only valid adapters; skip unknown or invalid ones.
|
|
129
|
+
*
|
|
130
|
+
* Returns an empty array when no adapters are configured or valid.
|
|
131
|
+
*/
|
|
132
|
+
export function getEnabledAdapters(config) {
|
|
133
|
+
const adapters = [];
|
|
134
|
+
for (const name of config.enabled) {
|
|
135
|
+
const Ctor = BUILTIN_ADAPTERS[name];
|
|
136
|
+
if (!Ctor) {
|
|
137
|
+
console.error(`[collab-adapter] unknown adapter: ${name}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const instance = new Ctor();
|
|
142
|
+
const block = config[name];
|
|
143
|
+
if (!instance.validateConfig(block ?? {})) {
|
|
144
|
+
console.error(`[collab-adapter] invalid config for adapter: ${name}`);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
adapters.push(instance);
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
console.error(`[collab-adapter] failed to instantiate adapter: ${name}`, err);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return adapters;
|
|
154
|
+
}
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// Main entry point
|
|
157
|
+
// ---------------------------------------------------------------------------
|
|
158
|
+
/**
|
|
159
|
+
* Send a collab event to all enabled adapters.
|
|
160
|
+
*
|
|
161
|
+
* Fire-and-forget: this function is synchronous (returns void), dispatches
|
|
162
|
+
* notifications in parallel via `Promise.allSettled`, and NEVER throws.
|
|
163
|
+
* Individual adapter failures are logged to `console.error`.
|
|
164
|
+
*
|
|
165
|
+
* No-op when no adapters are configured.
|
|
166
|
+
*/
|
|
167
|
+
export function notifyAdapters(event) {
|
|
168
|
+
try {
|
|
169
|
+
const config = loadAdapterConfig();
|
|
170
|
+
const adapters = getEnabledAdapters(config);
|
|
171
|
+
if (adapters.length === 0)
|
|
172
|
+
return;
|
|
173
|
+
const promises = adapters.map((adapter) => adapter.sendNotification(event));
|
|
174
|
+
Promise.allSettled(promises).then((results) => {
|
|
175
|
+
for (let i = 0; i < results.length; i++) {
|
|
176
|
+
const result = results[i];
|
|
177
|
+
if (result.status === 'rejected') {
|
|
178
|
+
console.error(`[collab-adapter] ${adapters[i].name} notification failed:`, result.reason);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
console.error('[collab-adapter] unexpected error in notifyAdapters:', err);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
// Internal helpers
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
/** Format a human-readable one-liner from a collab event. */
|
|
191
|
+
function formatEventSummary(event) {
|
|
192
|
+
const p = event.payload;
|
|
193
|
+
const who = typeof p.actor === 'string' ? p.actor : 'unknown';
|
|
194
|
+
const task = typeof p.task_title === 'string' ? p.task_title : '';
|
|
195
|
+
switch (event.type) {
|
|
196
|
+
case 'task.created':
|
|
197
|
+
return `${who} created task: ${task}`;
|
|
198
|
+
case 'task.assigned':
|
|
199
|
+
return `${who} assigned task: ${task} -> ${p.assignee ?? 'unknown'}`;
|
|
200
|
+
case 'task.status_changed':
|
|
201
|
+
return `${who} changed status: ${task} -> ${p.status ?? 'unknown'}`;
|
|
202
|
+
case 'task.checked':
|
|
203
|
+
return `${who} checked item in: ${task}`;
|
|
204
|
+
case 'role.changed':
|
|
205
|
+
return `${who} changed role: ${p.member ?? 'unknown'} -> ${p.role ?? 'unknown'}`;
|
|
206
|
+
default:
|
|
207
|
+
return `${who}: ${event.type}`;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/** Build a Linear GraphQL mutation for the given event type. */
|
|
211
|
+
function buildLinearMutation(event, teamId) {
|
|
212
|
+
const p = event.payload;
|
|
213
|
+
const title = typeof p.task_title === 'string' ? p.task_title : 'Untitled';
|
|
214
|
+
const description = typeof p.description === 'string' ? p.description : '';
|
|
215
|
+
switch (event.type) {
|
|
216
|
+
case 'task.created':
|
|
217
|
+
return {
|
|
218
|
+
query: `
|
|
219
|
+
mutation CreateIssue($title: String!, $teamId: String!, $description: String) {
|
|
220
|
+
issueCreate(input: { title: $title, teamId: $teamId, description: $description }) {
|
|
221
|
+
success
|
|
222
|
+
issue { id title }
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
`,
|
|
226
|
+
variables: { title, teamId, description },
|
|
227
|
+
};
|
|
228
|
+
case 'task.status_changed': {
|
|
229
|
+
const linearState = mapToLinearState(p.status);
|
|
230
|
+
return {
|
|
231
|
+
query: `
|
|
232
|
+
mutation UpdateIssueState($issueId: String!, $stateId: String!) {
|
|
233
|
+
issueUpdate(id: $issueId, input: { stateId: $stateId }) {
|
|
234
|
+
success
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
`,
|
|
238
|
+
variables: { issueId: p.task_id ?? '', stateId: linearState },
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
case 'task.assigned': {
|
|
242
|
+
return {
|
|
243
|
+
query: `
|
|
244
|
+
mutation AssignIssue($issueId: String!, $assigneeId: String!) {
|
|
245
|
+
issueUpdate(id: $issueId, input: { assigneeId: $assigneeId }) {
|
|
246
|
+
success
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
`,
|
|
250
|
+
variables: { issueId: p.task_id ?? '', assigneeId: p.assignee_id ?? '' },
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
default:
|
|
254
|
+
// For events without a direct Linear mapping, create a comment.
|
|
255
|
+
return {
|
|
256
|
+
query: `
|
|
257
|
+
mutation CreateComment($issueId: String!, $body: String!) {
|
|
258
|
+
commentCreate(input: { issueId: $issueId, body: $body }) {
|
|
259
|
+
success
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
`,
|
|
263
|
+
variables: {
|
|
264
|
+
issueId: p.task_id ?? '',
|
|
265
|
+
body: formatEventSummary(event),
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/** Map collab status strings to Linear state IDs (placeholder heuristic). */
|
|
271
|
+
function mapToLinearState(status) {
|
|
272
|
+
const map = {
|
|
273
|
+
todo: 'Todo',
|
|
274
|
+
in_progress: 'In Progress',
|
|
275
|
+
done: 'Done',
|
|
276
|
+
cancelled: 'Cancelled',
|
|
277
|
+
backlog: 'Backlog',
|
|
278
|
+
};
|
|
279
|
+
return map[status] ?? status;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* POST a JSON body to an HTTPS URL.
|
|
283
|
+
*
|
|
284
|
+
* Returns a promise that resolves on 2xx status and rejects otherwise.
|
|
285
|
+
* Uses only Node.js built-in `node:https` -- no external dependencies.
|
|
286
|
+
*/
|
|
287
|
+
function postJSON(url, body, extraHeaders = {}) {
|
|
288
|
+
return new Promise((resolve, reject) => {
|
|
289
|
+
const parsed = new URL(url);
|
|
290
|
+
const options = {
|
|
291
|
+
hostname: parsed.hostname,
|
|
292
|
+
port: parsed.port || 443,
|
|
293
|
+
path: parsed.pathname + parsed.search,
|
|
294
|
+
method: 'POST',
|
|
295
|
+
headers: {
|
|
296
|
+
'Content-Type': 'application/json',
|
|
297
|
+
'Content-Length': Buffer.byteLength(body),
|
|
298
|
+
...extraHeaders,
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
const req = request(options, (res) => {
|
|
302
|
+
// Drain the response to free the connection.
|
|
303
|
+
const chunks = [];
|
|
304
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
305
|
+
res.on('end', () => {
|
|
306
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
307
|
+
resolve();
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
const responseBody = Buffer.concat(chunks).toString('utf-8');
|
|
311
|
+
reject(new Error(`HTTP ${res.statusCode} from ${parsed.hostname}: ${responseBody.slice(0, 200)}`));
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
req.on('error', reject);
|
|
316
|
+
req.write(body);
|
|
317
|
+
req.end();
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=collab-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collab-adapter.js","sourceRoot":"","sources":["../../../src/tools/collab-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* SHARED (writable by any member):
|
|
13
13
|
* .workflow/collab/activity.jsonl
|
|
14
14
|
* .workflow/collab/overlays/manifest.json
|
|
15
|
+
* .workflow/collab/tasks/TASK-*.json
|
|
16
|
+
* .workflow/collab/tasks/.counter
|
|
15
17
|
* BLOCKED:
|
|
16
18
|
* Other members' files in the above namespaces.
|
|
17
19
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace-guard.d.ts","sourceRoot":"","sources":["../../../src/tools/namespace-guard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"namespace-guard.d.ts","sourceRoot":"","sources":["../../../src/tools/namespace-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AASH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,oBAAoB,CAwFtB;AAMD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAWrF"}
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* SHARED (writable by any member):
|
|
13
13
|
* .workflow/collab/activity.jsonl
|
|
14
14
|
* .workflow/collab/overlays/manifest.json
|
|
15
|
+
* .workflow/collab/tasks/TASK-*.json
|
|
16
|
+
* .workflow/collab/tasks/.counter
|
|
15
17
|
* BLOCKED:
|
|
16
18
|
* Other members' files in the above namespaces.
|
|
17
19
|
*
|
|
@@ -102,6 +104,15 @@ export function evaluateNamespaceGuard(filePath, selfUid, projectRoot) {
|
|
|
102
104
|
// Other overlay files (not a bundle, not manifest) — allow.
|
|
103
105
|
return { allowed: true };
|
|
104
106
|
}
|
|
107
|
+
// --- Tasks namespace (shared writable by any member) ---
|
|
108
|
+
if (collabRel.startsWith('tasks/')) {
|
|
109
|
+
const fileName = collabRel.slice('tasks/'.length);
|
|
110
|
+
if (fileName === '.counter' || /^TASK-\d+\.json$/.test(fileName)) {
|
|
111
|
+
return { allowed: true };
|
|
112
|
+
}
|
|
113
|
+
// Unknown files under tasks/ — allow (finer checks in team-tasks.ts).
|
|
114
|
+
return { allowed: true };
|
|
115
|
+
}
|
|
105
116
|
// Other paths under .workflow/collab/ — allow by default (not namespaced).
|
|
106
117
|
return { allowed: true };
|
|
107
118
|
}
|
|
@@ -121,6 +132,7 @@ export function getNamespaceBoundaries(selfUid, projectRoot) {
|
|
|
121
132
|
// Shared paths
|
|
122
133
|
`${prefix}/activity.jsonl`,
|
|
123
134
|
`${prefix}/overlays/manifest.json`,
|
|
135
|
+
`${prefix}/tasks/`,
|
|
124
136
|
];
|
|
125
137
|
}
|
|
126
138
|
//# sourceMappingURL=namespace-guard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namespace-guard.js","sourceRoot":"","sources":["../../../src/tools/namespace-guard.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"namespace-guard.js","sourceRoot":"","sources":["../../../src/tools/namespace-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase Gate Evaluator — computes whether a phase is ready to be marked complete.
|
|
3
|
+
*
|
|
4
|
+
* Called by transition-recorder before appending a transition entry.
|
|
5
|
+
* Returns a structured result indicating whether completion is allowed,
|
|
6
|
+
* with reasons for blocking and whether --force can override.
|
|
7
|
+
*/
|
|
8
|
+
export interface GateResult {
|
|
9
|
+
/** Whether the phase may be marked complete */
|
|
10
|
+
allowed: boolean;
|
|
11
|
+
/** Human-readable reasons for blocking */
|
|
12
|
+
reasons: string[];
|
|
13
|
+
/** Whether --force can override (false when review verdict is BLOCK) */
|
|
14
|
+
overridable: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Subset of phase index.json fields consumed by the evaluator */
|
|
17
|
+
export interface PhaseGateInput {
|
|
18
|
+
review?: {
|
|
19
|
+
verdict?: string;
|
|
20
|
+
findings_count?: number;
|
|
21
|
+
};
|
|
22
|
+
verification?: {
|
|
23
|
+
status?: string;
|
|
24
|
+
gaps?: Array<{
|
|
25
|
+
id?: string;
|
|
26
|
+
severity?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
30
|
+
validation?: {
|
|
31
|
+
status?: string;
|
|
32
|
+
test_coverage?: {
|
|
33
|
+
statements?: number;
|
|
34
|
+
branches?: number;
|
|
35
|
+
functions?: number;
|
|
36
|
+
lines?: number;
|
|
37
|
+
} | number | null;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Evaluate whether a phase is ready to transition to `completed`.
|
|
42
|
+
* Pure function — no I/O.
|
|
43
|
+
*/
|
|
44
|
+
export declare function evaluatePhaseGate(phase: PhaseGateInput): GateResult;
|
|
45
|
+
//# sourceMappingURL=phase-gate-evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-gate-evaluator.d.ts","sourceRoot":"","sources":["../../../src/tools/phase-gate-evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,UAAU;IACzB,+CAA+C;IAC/C,OAAO,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,KAAK,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACxE,CAAC;IACF,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE;YAAE,UAAU,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,GAAG,MAAM,GAAG,IAAI,CAAC;KAChH,CAAC;CACH;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAkCnE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase Gate Evaluator — computes whether a phase is ready to be marked complete.
|
|
3
|
+
*
|
|
4
|
+
* Called by transition-recorder before appending a transition entry.
|
|
5
|
+
* Returns a structured result indicating whether completion is allowed,
|
|
6
|
+
* with reasons for blocking and whether --force can override.
|
|
7
|
+
*/
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Public API
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* Evaluate whether a phase is ready to transition to `completed`.
|
|
13
|
+
* Pure function — no I/O.
|
|
14
|
+
*/
|
|
15
|
+
export function evaluatePhaseGate(phase) {
|
|
16
|
+
const reasons = [];
|
|
17
|
+
let hasHardBlock = false;
|
|
18
|
+
// Hard rule: review verdict BLOCK — not overridable
|
|
19
|
+
if (phase.review?.verdict === 'BLOCK') {
|
|
20
|
+
reasons.push(`review verdict is BLOCK (${phase.review.findings_count ?? '?'} findings)`);
|
|
21
|
+
hasHardBlock = true;
|
|
22
|
+
}
|
|
23
|
+
// Soft rule: high-severity verification gaps
|
|
24
|
+
if (phase.verification?.status === 'gaps_found') {
|
|
25
|
+
const gaps = phase.verification.gaps ?? [];
|
|
26
|
+
const highGaps = gaps.filter((g) => g.severity === 'high' || g.severity === 'critical');
|
|
27
|
+
if (highGaps.length > 0) {
|
|
28
|
+
reasons.push(`${highGaps.length} high/critical verification gap(s): ${highGaps.map((g) => g.id ?? g.description ?? 'unknown').join(', ')}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Soft rule: zero test coverage
|
|
32
|
+
const cov = phase.validation?.test_coverage;
|
|
33
|
+
if (cov != null && typeof cov === 'object' && cov.lines === 0) {
|
|
34
|
+
reasons.push('0% test coverage');
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
allowed: reasons.length === 0,
|
|
38
|
+
reasons,
|
|
39
|
+
overridable: !hasHardBlock,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=phase-gate-evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-gate-evaluator.js","sourceRoot":"","sources":["../../../src/tools/phase-gate-evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+BH,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAqB;IACrD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,oDAAoD;IACpD,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,EAAE,CAAC;QACtC,OAAO,CAAC,IAAI,CACV,4BAA4B,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,GAAG,YAAY,CAC3E,CAAC;QACF,YAAY,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,6CAA6C;IAC7C,IAAI,KAAK,CAAC,YAAY,EAAE,MAAM,KAAK,YAAY,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC;QACxF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CACV,GAAG,QAAQ,CAAC,MAAM,uCAAuC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,IAAI,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9H,CAAC;QACJ,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,EAAE,aAAa,CAAC;IAC5C,IAAI,GAAG,IAAI,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACnC,CAAC;IAED,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;QAC7B,OAAO;QACP,WAAW,EAAE,CAAC,YAAY;KAC3B,CAAC;AACJ,CAAC"}
|