maestro-flow 0.3.9 → 0.3.11
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/agents/workflow-collab-planner.md +1 -1
- package/.claude/agents/workflow-executor.md +1 -1
- package/.claude/agents/workflow-plan-checker.md +1 -1
- package/.claude/agents/workflow-planner.md +1 -1
- package/.claude/commands/learn-decompose.md +176 -176
- package/.claude/commands/learn-follow.md +167 -167
- package/.claude/commands/learn-retro.md +1 -1
- package/.claude/commands/maestro-analyze.md +46 -3
- package/.claude/commands/maestro-coordinate.md +1 -3
- package/.claude/commands/maestro-execute.md +14 -0
- package/.claude/commands/maestro-plan.md +16 -0
- package/.claude/commands/manage-harvest.md +131 -131
- package/.claude/commands/manage-issue-discover.md +2 -2
- package/.claude/commands/manage-issue.md +5 -5
- package/.claude/commands/spec-add.md +67 -56
- package/.claude/commands/spec-load.md +66 -64
- package/.claude/commands/spec-setup.md +5 -9
- package/.codex/skills/learn-decompose/SKILL.md +119 -0
- package/.codex/skills/learn-follow/SKILL.md +83 -0
- package/.codex/skills/learn-investigate/SKILL.md +83 -0
- package/.codex/skills/learn-retro/SKILL.md +83 -0
- package/.codex/skills/learn-second-opinion/SKILL.md +86 -0
- package/.codex/skills/maestro/SKILL.md +335 -0
- package/.codex/skills/maestro-analyze/SKILL.md +84 -75
- package/.codex/skills/maestro-brainstorm/SKILL.md +452 -463
- package/.codex/skills/maestro-chain/SKILL.md +233 -0
- package/.codex/skills/maestro-coordinate/SKILL.md +167 -278
- package/.codex/skills/maestro-execute/SKILL.md +435 -438
- package/.codex/skills/maestro-fork/SKILL.md +68 -0
- package/.codex/skills/maestro-init/SKILL.md +171 -167
- package/.codex/skills/maestro-learn/SKILL.md +80 -0
- package/.codex/skills/maestro-link-coordinate/SKILL.md +224 -220
- package/.codex/skills/maestro-merge/SKILL.md +62 -0
- package/.codex/skills/maestro-milestone-audit/SKILL.md +108 -103
- package/.codex/skills/maestro-milestone-complete/SKILL.md +155 -149
- package/.codex/skills/maestro-milestone-release/SKILL.md +70 -0
- package/.codex/skills/maestro-overlay/SKILL.md +188 -185
- package/.codex/skills/maestro-plan/SKILL.md +66 -69
- package/.codex/skills/maestro-quick/SKILL.md +26 -23
- package/.codex/skills/maestro-roadmap/SKILL.md +65 -73
- package/.codex/skills/maestro-spec-generate/SKILL.md +66 -74
- package/.codex/skills/maestro-ui-design/SKILL.md +34 -31
- package/.codex/skills/maestro-verify/SKILL.md +556 -566
- package/.codex/skills/manage-codebase-rebuild/SKILL.md +397 -405
- package/.codex/skills/manage-codebase-refresh/SKILL.md +93 -82
- package/.codex/skills/manage-harvest/SKILL.md +82 -0
- package/.codex/skills/manage-issue/SKILL.md +80 -65
- package/.codex/skills/manage-issue-discover/SKILL.md +491 -503
- package/.codex/skills/manage-learn/SKILL.md +190 -186
- package/.codex/skills/manage-memory/SKILL.md +95 -72
- package/.codex/skills/manage-memory-capture/SKILL.md +99 -86
- package/.codex/skills/manage-status/SKILL.md +102 -89
- package/.codex/skills/quality-business-test/SKILL.md +228 -223
- package/.codex/skills/quality-debug/SKILL.md +54 -66
- package/.codex/skills/quality-integration-test/SKILL.md +532 -544
- package/.codex/skills/quality-refactor/SKILL.md +197 -191
- package/.codex/skills/quality-retrospective/SKILL.md +512 -505
- package/.codex/skills/quality-review/SKILL.md +93 -105
- package/.codex/skills/quality-sync/SKILL.md +101 -89
- package/.codex/skills/quality-test/SKILL.md +202 -198
- package/.codex/skills/quality-test-gen/SKILL.md +93 -104
- package/.codex/skills/spec-add/SKILL.md +58 -39
- package/.codex/skills/spec-load/SKILL.md +45 -40
- package/.codex/skills/spec-map/SKILL.md +180 -182
- package/.codex/skills/spec-setup/SKILL.md +94 -76
- package/.codex/skills/team-coordinate/SKILL.md +346 -357
- package/.codex/skills/team-executor/SKILL.md +70 -112
- package/.codex/skills/team-lifecycle-v4/SKILL.md +311 -299
- package/.codex/skills/team-quality-assurance/SKILL.md +234 -227
- package/.codex/skills/team-review/SKILL.md +232 -225
- package/.codex/skills/team-tech-debt/SKILL.md +78 -100
- package/.codex/skills/team-testing/SKILL.md +242 -235
- package/.codex/skills/wiki-connect/SKILL.md +75 -0
- package/.codex/skills/wiki-digest/SKILL.md +87 -0
- package/README.md +14 -11
- package/README.zh-CN.md +14 -11
- package/chains/issue-lifecycle.json +13 -13
- package/chains/singles/issue-analyze.json +3 -3
- package/chains/singles/issue-execute.json +3 -3
- package/chains/singles/issue-plan.json +3 -3
- package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js +2 -2
- package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js +3 -3
- package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/issues.js +34 -0
- package/dashboard/dist-server/dashboard/src/server/routes/issues.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/specs.d.ts +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/specs.js +75 -30
- package/dashboard/dist-server/dashboard/src/server/routes/specs.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/state/event-bus.d.ts +5 -0
- package/dashboard/dist-server/dashboard/src/server/state/event-bus.js +5 -0
- package/dashboard/dist-server/dashboard/src/server/state/event-bus.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js +2 -3
- package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/shared/constants.js +5 -0
- package/dashboard/dist-server/dashboard/src/shared/constants.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/shared/issue-types.d.ts +5 -0
- package/dashboard/dist-server/dashboard/src/shared/issue-types.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/shared/normalize-task.d.ts +2 -0
- package/dashboard/dist-server/dashboard/src/shared/normalize-task.js +75 -0
- package/dashboard/dist-server/dashboard/src/shared/normalize-task.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/shared/team-types.d.ts +21 -0
- package/dashboard/dist-server/dashboard/src/shared/team-types.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/shared/types.d.ts +3 -2
- package/dashboard/dist-server/dashboard/src/shared/ws-protocol.d.ts +1 -1
- package/dashboard/dist-server/dashboard/src/shared/ws-protocol.js.map +1 -1
- package/dashboard/dist-server/src/hooks/constants.d.ts +92 -12
- package/dashboard/dist-server/src/hooks/constants.js +151 -16
- package/dashboard/dist-server/src/hooks/constants.js.map +1 -1
- package/dashboard/dist-server/src/types/index.d.ts +5 -0
- package/dist/src/commands/collab.d.ts +1 -34
- package/dist/src/commands/collab.d.ts.map +1 -1
- package/dist/src/commands/collab.js +8 -76
- package/dist/src/commands/collab.js.map +1 -1
- package/dist/src/commands/hooks.d.ts +5 -1
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +115 -10
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/install-ui/InstallConfirm.d.ts +3 -1
- package/dist/src/commands/install-ui/InstallConfirm.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallConfirm.js +3 -1
- package/dist/src/commands/install-ui/InstallConfirm.js.map +1 -1
- package/dist/src/commands/install-ui/InstallExecution.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallExecution.js +5 -1
- package/dist/src/commands/install-ui/InstallExecution.js.map +1 -1
- package/dist/src/commands/install-ui/InstallFlow.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallFlow.js +7 -3
- package/dist/src/commands/install-ui/InstallFlow.js.map +1 -1
- package/dist/src/commands/install-ui/StatuslineConfig.d.ts +6 -1
- package/dist/src/commands/install-ui/StatuslineConfig.d.ts.map +1 -1
- package/dist/src/commands/install-ui/StatuslineConfig.js +27 -5
- package/dist/src/commands/install-ui/StatuslineConfig.js.map +1 -1
- package/dist/src/commands/spec.d.ts.map +1 -1
- package/dist/src/commands/spec.js +7 -2
- package/dist/src/commands/spec.js.map +1 -1
- package/dist/src/hooks/__tests__/statusline-visual-test.d.ts +7 -0
- package/dist/src/hooks/__tests__/statusline-visual-test.d.ts.map +1 -0
- package/dist/src/hooks/__tests__/statusline-visual-test.js +236 -0
- package/dist/src/hooks/__tests__/statusline-visual-test.js.map +1 -0
- package/dist/src/hooks/constants.d.ts +92 -12
- package/dist/src/hooks/constants.d.ts.map +1 -1
- package/dist/src/hooks/constants.js +151 -16
- package/dist/src/hooks/constants.js.map +1 -1
- package/dist/src/hooks/guards/index.d.ts +2 -0
- package/dist/src/hooks/guards/index.d.ts.map +1 -1
- package/dist/src/hooks/guards/index.js +2 -0
- package/dist/src/hooks/guards/index.js.map +1 -1
- package/dist/src/hooks/guards/preflight-guard.d.ts +29 -0
- package/dist/src/hooks/guards/preflight-guard.d.ts.map +1 -0
- package/dist/src/hooks/guards/preflight-guard.js +95 -0
- package/dist/src/hooks/guards/preflight-guard.js.map +1 -0
- package/dist/src/hooks/guards/spec-validator.d.ts +25 -0
- package/dist/src/hooks/guards/spec-validator.d.ts.map +1 -0
- package/dist/src/hooks/guards/spec-validator.js +66 -0
- package/dist/src/hooks/guards/spec-validator.js.map +1 -0
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/index.d.ts.map +1 -1
- package/dist/src/hooks/index.js +1 -0
- package/dist/src/hooks/index.js.map +1 -1
- package/dist/src/hooks/keyword-spec-injector.d.ts +21 -0
- package/dist/src/hooks/keyword-spec-injector.d.ts.map +1 -0
- package/dist/src/hooks/keyword-spec-injector.js +96 -0
- package/dist/src/hooks/keyword-spec-injector.js.map +1 -0
- package/dist/src/hooks/plugins/spec-injection-plugin.d.ts +2 -1
- package/dist/src/hooks/plugins/spec-injection-plugin.d.ts.map +1 -1
- package/dist/src/hooks/plugins/spec-injection-plugin.js +21 -12
- package/dist/src/hooks/plugins/spec-injection-plugin.js.map +1 -1
- package/dist/src/hooks/preflight-core.d.ts +37 -0
- package/dist/src/hooks/preflight-core.d.ts.map +1 -0
- package/dist/src/hooks/preflight-core.js +86 -0
- package/dist/src/hooks/preflight-core.js.map +1 -0
- package/dist/src/hooks/spec-bridge.d.ts +40 -0
- package/dist/src/hooks/spec-bridge.d.ts.map +1 -0
- package/dist/src/hooks/spec-bridge.js +97 -0
- package/dist/src/hooks/spec-bridge.js.map +1 -0
- package/dist/src/hooks/spec-injector.d.ts.map +1 -1
- package/dist/src/hooks/spec-injector.js +18 -12
- package/dist/src/hooks/spec-injector.js.map +1 -1
- package/dist/src/hooks/statusline.d.ts +8 -17
- package/dist/src/hooks/statusline.d.ts.map +1 -1
- package/dist/src/hooks/statusline.js +269 -112
- package/dist/src/hooks/statusline.js.map +1 -1
- package/dist/src/i18n/locales/en.d.ts.map +1 -1
- package/dist/src/i18n/locales/en.js +5 -0
- package/dist/src/i18n/locales/en.js.map +1 -1
- package/dist/src/i18n/locales/zh.d.ts.map +1 -1
- package/dist/src/i18n/locales/zh.js +5 -0
- package/dist/src/i18n/locales/zh.js.map +1 -1
- package/dist/src/i18n/types.d.ts +5 -0
- package/dist/src/i18n/types.d.ts.map +1 -1
- package/dist/src/team/phase-orchestrator.d.ts +52 -0
- package/dist/src/team/phase-orchestrator.d.ts.map +1 -0
- package/dist/src/team/phase-orchestrator.js +165 -0
- package/dist/src/team/phase-orchestrator.js.map +1 -0
- package/dist/src/team/phase-types.d.ts +51 -0
- package/dist/src/team/phase-types.d.ts.map +1 -0
- package/dist/src/team/phase-types.js +41 -0
- package/dist/src/team/phase-types.js.map +1 -0
- package/dist/src/tools/collab-adapter.d.ts +17 -0
- package/dist/src/tools/collab-adapter.d.ts.map +1 -1
- package/dist/src/tools/collab-adapter.js +138 -0
- package/dist/src/tools/collab-adapter.js.map +1 -1
- package/dist/src/tools/index.d.ts.map +1 -1
- package/dist/src/tools/index.js +6 -0
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/merge-validator.d.ts +24 -0
- package/dist/src/tools/merge-validator.d.ts.map +1 -0
- package/dist/src/tools/merge-validator.js +220 -0
- package/dist/src/tools/merge-validator.js.map +1 -0
- package/dist/src/tools/spec-entry-parser.d.ts +56 -0
- package/dist/src/tools/spec-entry-parser.d.ts.map +1 -0
- package/dist/src/tools/spec-entry-parser.js +196 -0
- package/dist/src/tools/spec-entry-parser.js.map +1 -0
- package/dist/src/tools/spec-init.d.ts.map +1 -1
- package/dist/src/tools/spec-init.js +66 -92
- package/dist/src/tools/spec-init.js.map +1 -1
- package/dist/src/tools/spec-keyword-index.d.ts +30 -0
- package/dist/src/tools/spec-keyword-index.d.ts.map +1 -0
- package/dist/src/tools/spec-keyword-index.js +101 -0
- package/dist/src/tools/spec-keyword-index.js.map +1 -0
- package/dist/src/tools/spec-loader.d.ts +3 -3
- package/dist/src/tools/spec-loader.d.ts.map +1 -1
- package/dist/src/tools/spec-loader.js +49 -23
- package/dist/src/tools/spec-loader.js.map +1 -1
- package/dist/src/tools/team-agents.d.ts +27 -0
- package/dist/src/tools/team-agents.d.ts.map +1 -0
- package/dist/src/tools/team-agents.js +362 -0
- package/dist/src/tools/team-agents.js.map +1 -0
- package/dist/src/tools/team-mailbox.d.ts +40 -0
- package/dist/src/tools/team-mailbox.d.ts.map +1 -0
- package/dist/src/tools/team-mailbox.js +384 -0
- package/dist/src/tools/team-mailbox.js.map +1 -0
- package/dist/src/tools/team-msg.d.ts +17 -8
- package/dist/src/tools/team-msg.d.ts.map +1 -1
- package/dist/src/tools/team-msg.js +110 -13
- package/dist/src/tools/team-msg.js.map +1 -1
- package/dist/src/tools/team-tasks-mcp.d.ts +27 -0
- package/dist/src/tools/team-tasks-mcp.d.ts.map +1 -0
- package/dist/src/tools/team-tasks-mcp.js +408 -0
- package/dist/src/tools/team-tasks-mcp.js.map +1 -0
- package/dist/src/types/index.d.ts +5 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/package.json +2 -1
- package/templates/cli/prompts/workflow-skill-conflict-patterns.txt +3 -3
- package/templates/cli/prompts/workflow-skill-lessons-learned.txt +3 -3
- package/templates/search-tools.md +1 -1
- package/workflows/analyze.md +816 -816
- package/workflows/brainstorm.md +471 -471
- package/workflows/cli-tools-usage.md +44 -27
- package/workflows/codebase-rebuild.md +332 -332
- package/workflows/codebase-refresh.md +240 -240
- package/workflows/delegate-usage.md +3 -3
- package/workflows/execute.md +1 -1
- package/workflows/harvest.md +420 -420
- package/workflows/integration-test.md +343 -343
- package/workflows/issue-analyze.md +6 -2
- package/workflows/issue-discover.md +414 -414
- package/workflows/issue-execute.md +6 -3
- package/workflows/issue-plan.md +5 -2
- package/workflows/maestro-coordinate.codex.md +281 -470
- package/workflows/maestro-coordinate.md +14 -14
- package/workflows/maestro-link-coordinate.md +2 -2
- package/workflows/maestro.codex.md +710 -0
- package/workflows/maestro.md +10 -11
- package/workflows/map.md +111 -111
- package/workflows/milestone-complete.md +176 -176
- package/workflows/plan.md +1 -1
- package/workflows/quick.md +497 -497
- package/workflows/refactor.md +300 -300
- package/workflows/retrospective.md +1 -1
- package/workflows/roadmap.md +335 -335
- package/workflows/spec-generate.md +640 -640
- package/workflows/specs-add.md +46 -81
- package/workflows/specs-load.md +15 -17
- package/workflows/specs-setup.md +40 -161
- package/.claude/commands/manage-issue-analyze.md +0 -62
- package/.claude/commands/manage-issue-execute.md +0 -73
- package/.claude/commands/manage-issue-plan.md +0 -62
- package/.codex/skills/manage-issue-analyze/SKILL.md +0 -207
- package/.codex/skills/manage-issue-execute/SKILL.md +0 -200
- package/.codex/skills/manage-issue-plan/SKILL.md +0 -186
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyword Spec Injector — UserPromptSubmit hook
|
|
3
|
+
*
|
|
4
|
+
* Scans user prompt for keywords, matches against <spec-entry> keyword attributes,
|
|
5
|
+
* injects matching entries as additionalContext. Session dedup prevents re-injection.
|
|
6
|
+
*/
|
|
7
|
+
export interface KeywordInjectionResult {
|
|
8
|
+
inject: boolean;
|
|
9
|
+
content?: string;
|
|
10
|
+
matchedKeywords?: string[];
|
|
11
|
+
matchedEntries?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Evaluate whether to inject keyword-matched spec entries for a user prompt.
|
|
15
|
+
*
|
|
16
|
+
* @param prompt The user's prompt text
|
|
17
|
+
* @param projectPath Working directory for spec file resolution
|
|
18
|
+
* @param sessionId Session ID for dedup bridge
|
|
19
|
+
*/
|
|
20
|
+
export declare function evaluateKeywordInjection(prompt: string, projectPath: string, sessionId: string): KeywordInjectionResult;
|
|
21
|
+
//# sourceMappingURL=keyword-spec-injector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-spec-injector.d.ts","sourceRoot":"","sources":["../../../src/hooks/keyword-spec-injector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA+BD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,sBAAsB,CAqCxB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyword Spec Injector — UserPromptSubmit hook
|
|
3
|
+
*
|
|
4
|
+
* Scans user prompt for keywords, matches against <spec-entry> keyword attributes,
|
|
5
|
+
* injects matching entries as additionalContext. Session dedup prevents re-injection.
|
|
6
|
+
*/
|
|
7
|
+
import { buildKeywordIndex, lookupKeywords } from '../tools/spec-keyword-index.js';
|
|
8
|
+
import { markInjected, filterUnjected } from './spec-bridge.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Config
|
|
11
|
+
// ============================================================================
|
|
12
|
+
const MIN_KEYWORD_LENGTH = 3;
|
|
13
|
+
/** Common words to skip when tokenizing prompt */
|
|
14
|
+
const STOP_WORDS = new Set([
|
|
15
|
+
'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can', 'had',
|
|
16
|
+
'her', 'was', 'one', 'our', 'out', 'has', 'his', 'how', 'its', 'may',
|
|
17
|
+
'new', 'now', 'old', 'see', 'way', 'who', 'did', 'get', 'let', 'say',
|
|
18
|
+
'she', 'too', 'use', 'this', 'that', 'with', 'have', 'from', 'they',
|
|
19
|
+
'been', 'said', 'each', 'make', 'like', 'just', 'over', 'such', 'take',
|
|
20
|
+
'than', 'them', 'very', 'when', 'what', 'some', 'time', 'will', 'into',
|
|
21
|
+
'look', 'only', 'come', 'also', 'back', 'after', 'work', 'first', 'well',
|
|
22
|
+
'then', 'year', 'your', 'them', 'would', 'there', 'their', 'which',
|
|
23
|
+
'about', 'could', 'other', 'these', 'think', 'should', 'please',
|
|
24
|
+
// code-related common words to skip
|
|
25
|
+
'file', 'code', 'function', 'class', 'import', 'export', 'const', 'return',
|
|
26
|
+
'true', 'false', 'null', 'undefined', 'string', 'number', 'type', 'interface',
|
|
27
|
+
]);
|
|
28
|
+
/** Max entries to inject per prompt to avoid context bloat */
|
|
29
|
+
const MAX_ENTRIES_PER_INJECTION = 5;
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Public API
|
|
32
|
+
// ============================================================================
|
|
33
|
+
/**
|
|
34
|
+
* Evaluate whether to inject keyword-matched spec entries for a user prompt.
|
|
35
|
+
*
|
|
36
|
+
* @param prompt The user's prompt text
|
|
37
|
+
* @param projectPath Working directory for spec file resolution
|
|
38
|
+
* @param sessionId Session ID for dedup bridge
|
|
39
|
+
*/
|
|
40
|
+
export function evaluateKeywordInjection(prompt, projectPath, sessionId) {
|
|
41
|
+
// 1. Tokenize prompt into candidate keywords
|
|
42
|
+
const promptKeywords = tokenizePrompt(prompt);
|
|
43
|
+
if (promptKeywords.length === 0)
|
|
44
|
+
return { inject: false };
|
|
45
|
+
// 2. Build keyword index from spec files
|
|
46
|
+
const index = buildKeywordIndex(projectPath);
|
|
47
|
+
if (index.size === 0)
|
|
48
|
+
return { inject: false };
|
|
49
|
+
// 3. Look up matching entries
|
|
50
|
+
const matchedAll = lookupKeywords(index, promptKeywords);
|
|
51
|
+
if (matchedAll.length === 0)
|
|
52
|
+
return { inject: false };
|
|
53
|
+
// 4. Filter out already-injected entries (session dedup)
|
|
54
|
+
const unjected = filterUnjected(sessionId, matchedAll);
|
|
55
|
+
if (unjected.length === 0)
|
|
56
|
+
return { inject: false };
|
|
57
|
+
// 5. Limit to avoid context bloat
|
|
58
|
+
const toInject = unjected.slice(0, MAX_ENTRIES_PER_INJECTION);
|
|
59
|
+
// 6. Build injection content
|
|
60
|
+
const content = formatInjectionContent(toInject);
|
|
61
|
+
// 7. Mark as injected
|
|
62
|
+
const injectedKeywords = [...new Set(toInject.flatMap(e => e.keywords))];
|
|
63
|
+
const injectedIds = toInject.map(e => e.id);
|
|
64
|
+
markInjected(sessionId, injectedKeywords, injectedIds);
|
|
65
|
+
// 8. Determine which prompt keywords actually matched
|
|
66
|
+
const matchedKws = promptKeywords.filter(kw => index.has(kw));
|
|
67
|
+
return {
|
|
68
|
+
inject: true,
|
|
69
|
+
content,
|
|
70
|
+
matchedKeywords: matchedKws,
|
|
71
|
+
matchedEntries: toInject.length,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// ============================================================================
|
|
75
|
+
// Internal
|
|
76
|
+
// ============================================================================
|
|
77
|
+
/**
|
|
78
|
+
* Tokenize prompt into candidate keywords for index lookup.
|
|
79
|
+
* Lowercase, deduplicate, filter by length and stop words.
|
|
80
|
+
*/
|
|
81
|
+
function tokenizePrompt(prompt) {
|
|
82
|
+
const words = prompt
|
|
83
|
+
.toLowerCase()
|
|
84
|
+
.replace(/[^a-z0-9\u4e00-\u9fff_-]/g, ' ')
|
|
85
|
+
.split(/\s+/)
|
|
86
|
+
.filter(w => w.length >= MIN_KEYWORD_LENGTH && !STOP_WORDS.has(w));
|
|
87
|
+
return [...new Set(words)];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format matched entries for injection as context.
|
|
91
|
+
*/
|
|
92
|
+
function formatInjectionContent(entries) {
|
|
93
|
+
const sections = entries.map(e => `--- ${e.file} (${e.category}) [${e.keywords.join(', ')}] ---\n\n${e.content}`);
|
|
94
|
+
return `<spec-keyword-match count="${entries.length}">\n\n${sections.join('\n\n---\n\n')}\n\n</spec-keyword-match>`;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=keyword-spec-injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-spec-injector.js","sourceRoot":"","sources":["../../../src/hooks/keyword-spec-injector.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,8 +9,9 @@ import type { WorkflowHookRegistry } from '../workflow-hooks.js';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare class SpecInjectionPlugin implements MaestroPlugin {
|
|
11
11
|
private readonly projectPath;
|
|
12
|
+
private readonly sessionId;
|
|
12
13
|
readonly name = "specInjection";
|
|
13
|
-
constructor(projectPath?: string);
|
|
14
|
+
constructor(projectPath?: string, sessionId?: string);
|
|
14
15
|
apply(registry: WorkflowHookRegistry): void;
|
|
15
16
|
}
|
|
16
17
|
//# sourceMappingURL=spec-injection-plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-injection-plugin.d.ts","sourceRoot":"","sources":["../../../../src/hooks/plugins/spec-injection-plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"spec-injection-plugin.d.ts","sourceRoot":"","sources":["../../../../src/hooks/plugins/spec-injection-plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAKjE;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IAIrD,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,QAAQ,CAAC,IAAI,mBAAmB;gBAGb,WAAW,GAAE,MAAsB,EACnC,SAAS,GAAE,MAAW;IAGzC,KAAK,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;CAuB5C"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
import { loadSpecs } from '../../tools/spec-loader.js';
|
|
5
5
|
import { resolveSelf } from '../../tools/team-members.js';
|
|
6
|
+
import { evaluateKeywordInjection } from '../keyword-spec-injector.js';
|
|
6
7
|
/**
|
|
7
8
|
* In-process plugin for `maestro coordinate` — injects relevant specs
|
|
8
9
|
* into the prompt via the `transformPrompt` waterfall hook.
|
|
@@ -12,20 +13,30 @@ import { resolveSelf } from '../../tools/team-members.js';
|
|
|
12
13
|
*/
|
|
13
14
|
export class SpecInjectionPlugin {
|
|
14
15
|
projectPath;
|
|
16
|
+
sessionId;
|
|
15
17
|
name = 'specInjection';
|
|
16
|
-
constructor(projectPath = process.cwd()) {
|
|
18
|
+
constructor(projectPath = process.cwd(), sessionId = '') {
|
|
17
19
|
this.projectPath = projectPath;
|
|
20
|
+
this.sessionId = sessionId;
|
|
18
21
|
}
|
|
19
22
|
apply(registry) {
|
|
20
23
|
registry.transformPrompt.tap(this.name, (prompt) => {
|
|
21
|
-
|
|
24
|
+
const parts = [prompt];
|
|
25
|
+
// Category-based injection
|
|
22
26
|
const category = inferCategory(prompt);
|
|
23
|
-
// Best-effort uid resolution for personal spec layer
|
|
24
27
|
const uid = resolveUidSafe();
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
const catResult = loadSpecs(this.projectPath, category, uid);
|
|
29
|
+
if (catResult.content) {
|
|
30
|
+
parts.push(catResult.content);
|
|
31
|
+
}
|
|
32
|
+
// Keyword-based injection (with session dedup)
|
|
33
|
+
if (this.sessionId) {
|
|
34
|
+
const kwResult = evaluateKeywordInjection(prompt, this.projectPath, this.sessionId);
|
|
35
|
+
if (kwResult.inject && kwResult.content) {
|
|
36
|
+
parts.push(kwResult.content);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return parts.length > 1 ? parts.join('\n\n---\n\n') : prompt;
|
|
29
40
|
});
|
|
30
41
|
}
|
|
31
42
|
}
|
|
@@ -55,10 +66,8 @@ function inferCategory(prompt) {
|
|
|
55
66
|
return 'test';
|
|
56
67
|
if (/\b(debug|diagnose|fix|error|bug)\b/.test(lower))
|
|
57
68
|
return 'debug';
|
|
58
|
-
if (/\b(plan|design|architect|decompose)\b/.test(lower))
|
|
59
|
-
return '
|
|
60
|
-
|
|
61
|
-
return 'exploration';
|
|
62
|
-
return 'execution'; // Default for implementation work
|
|
69
|
+
if (/\b(plan|design|architect|decompose|explore|discover|search|analyze)\b/.test(lower))
|
|
70
|
+
return 'arch';
|
|
71
|
+
return 'coding'; // Default for implementation work
|
|
63
72
|
}
|
|
64
73
|
//# sourceMappingURL=spec-injection-plugin.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-injection-plugin.js","sourceRoot":"","sources":["../../../../src/hooks/plugins/spec-injection-plugin.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAI9E,OAAO,EAAE,SAAS,EAAqB,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"spec-injection-plugin.js","sourceRoot":"","sources":["../../../../src/hooks/plugins/spec-injection-plugin.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAI9E,OAAO,EAAE,SAAS,EAAqB,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,OAAO,mBAAmB;IAIX;IACA;IAJV,IAAI,GAAG,eAAe,CAAC;IAEhC,YACmB,cAAsB,OAAO,CAAC,GAAG,EAAE,EACnC,YAAoB,EAAE;QADtB,gBAAW,GAAX,WAAW,CAAwB;QACnC,cAAS,GAAT,SAAS,CAAa;IACtC,CAAC;IAEJ,KAAK,CAAC,QAA8B;QAClC,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE;YACzD,MAAM,KAAK,GAAa,CAAC,MAAM,CAAC,CAAC;YAEjC,2BAA2B;YAC3B,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YACvC,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;YAC7D,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBACtB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YAChC,CAAC;YAED,+CAA+C;YAC/C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM,QAAQ,GAAG,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBACpF,IAAI,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;YAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;GAGG;AACH,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;QAC3B,OAAO,IAAI,EAAE,GAAG,IAAI,SAAS,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,MAAc;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,kCAAkC,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACpE,IAAI,iCAAiC,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACjE,IAAI,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACrE,IAAI,uEAAuE,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACvG,OAAO,QAAQ,CAAC,CAAC,kCAAkC;AACrD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type MemberRecord } from '../tools/team-members.js';
|
|
2
|
+
import { type ActivityEvent } from '../tools/team-activity.js';
|
|
3
|
+
export interface PreflightResult {
|
|
4
|
+
exitCode: 0 | 1 | 2;
|
|
5
|
+
warnings: string[];
|
|
6
|
+
conflicts: Array<{
|
|
7
|
+
user: string;
|
|
8
|
+
host: string;
|
|
9
|
+
action: string;
|
|
10
|
+
ts: string;
|
|
11
|
+
relative: string;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
export interface PreflightDeps {
|
|
15
|
+
getSelf?: () => MemberRecord | null;
|
|
16
|
+
getActivity?: (mins: number) => ActivityEvent[];
|
|
17
|
+
now?: () => number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Pure preflight logic — detects whether other team members are active on
|
|
21
|
+
* the given phase within a look-back window.
|
|
22
|
+
*
|
|
23
|
+
* Algorithm:
|
|
24
|
+
* 1. If no self → exit 0 (team mode off is a safe no-op).
|
|
25
|
+
* 2. Fetch recent activity (30 min window, clock tolerance handled by
|
|
26
|
+
* team-activity module).
|
|
27
|
+
* 3. Filter: same phase, different user.
|
|
28
|
+
* 4. Deduplicate by `user@host` keeping the most recent event.
|
|
29
|
+
* 5. Emit one warning line per unique teammate.
|
|
30
|
+
*
|
|
31
|
+
* `force` affects ONLY the exit code — warnings are still returned so
|
|
32
|
+
* callers can display them.
|
|
33
|
+
*/
|
|
34
|
+
export declare function runPreflight(phase: number, opts: {
|
|
35
|
+
force?: boolean;
|
|
36
|
+
}, deps?: PreflightDeps): PreflightResult;
|
|
37
|
+
//# sourceMappingURL=preflight-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-core.d.ts","sourceRoot":"","sources":["../../../src/hooks/preflight-core.ts"],"names":[],"mappings":"AAOA,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAMnF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,KAAK,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,YAAY,GAAG,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACzB,IAAI,CAAC,EAAE,aAAa,GACnB,eAAe,CAyDjB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Preflight Core — Pure conflict detection logic shared between CLI and hooks.
|
|
3
|
+
//
|
|
4
|
+
// Extracted from `src/commands/collab.ts` so that both the `maestro collab
|
|
5
|
+
// preflight` command and the PreToolUse guard can reuse the same algorithm.
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
import { resolveSelf } from '../tools/team-members.js';
|
|
8
|
+
import { readRecentActivity } from '../tools/team-activity.js';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Core algorithm
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* Pure preflight logic — detects whether other team members are active on
|
|
14
|
+
* the given phase within a look-back window.
|
|
15
|
+
*
|
|
16
|
+
* Algorithm:
|
|
17
|
+
* 1. If no self → exit 0 (team mode off is a safe no-op).
|
|
18
|
+
* 2. Fetch recent activity (30 min window, clock tolerance handled by
|
|
19
|
+
* team-activity module).
|
|
20
|
+
* 3. Filter: same phase, different user.
|
|
21
|
+
* 4. Deduplicate by `user@host` keeping the most recent event.
|
|
22
|
+
* 5. Emit one warning line per unique teammate.
|
|
23
|
+
*
|
|
24
|
+
* `force` affects ONLY the exit code — warnings are still returned so
|
|
25
|
+
* callers can display them.
|
|
26
|
+
*/
|
|
27
|
+
export function runPreflight(phase, opts, deps) {
|
|
28
|
+
const getSelf = deps?.getSelf ?? resolveSelf;
|
|
29
|
+
const getActivity = deps?.getActivity ?? readRecentActivity;
|
|
30
|
+
const now = deps?.now ?? Date.now;
|
|
31
|
+
const self = getSelf();
|
|
32
|
+
if (!self) {
|
|
33
|
+
return { exitCode: 0, warnings: [], conflicts: [] };
|
|
34
|
+
}
|
|
35
|
+
const events = getActivity(30);
|
|
36
|
+
const filtered = events.filter((e) => e.phase_id === phase && e.user !== self.uid);
|
|
37
|
+
// Dedupe by user@host, keep the most recent.
|
|
38
|
+
const latest = new Map();
|
|
39
|
+
for (const e of filtered) {
|
|
40
|
+
const key = `${e.user}@${e.host}`;
|
|
41
|
+
const prev = latest.get(key);
|
|
42
|
+
if (!prev || Date.parse(e.ts) > Date.parse(prev.ts)) {
|
|
43
|
+
latest.set(key, e);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (latest.size === 0) {
|
|
47
|
+
return { exitCode: 0, warnings: [], conflicts: [] };
|
|
48
|
+
}
|
|
49
|
+
const nowMs = now();
|
|
50
|
+
const warnings = [];
|
|
51
|
+
const conflicts = [];
|
|
52
|
+
// Stable order: most recent first.
|
|
53
|
+
const rows = Array.from(latest.values()).sort((a, b) => Date.parse(b.ts) - Date.parse(a.ts));
|
|
54
|
+
for (const e of rows) {
|
|
55
|
+
const rel = relTime(e.ts, nowMs);
|
|
56
|
+
warnings.push(`\u26a0 ${e.user}@${e.host} is active on phase ${phase} ` +
|
|
57
|
+
`(last: ${e.action}, ${rel} ago)`);
|
|
58
|
+
conflicts.push({
|
|
59
|
+
user: e.user,
|
|
60
|
+
host: e.host,
|
|
61
|
+
action: e.action,
|
|
62
|
+
ts: e.ts,
|
|
63
|
+
relative: rel,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
exitCode: opts.force ? 0 : 1,
|
|
68
|
+
warnings,
|
|
69
|
+
conflicts,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// Helpers
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
function relTime(ts, now) {
|
|
76
|
+
const ms = now - new Date(ts).getTime();
|
|
77
|
+
const min = Math.floor(ms / 60000);
|
|
78
|
+
if (min < 1)
|
|
79
|
+
return 'just now';
|
|
80
|
+
if (min === 1)
|
|
81
|
+
return '1 min';
|
|
82
|
+
if (min < 60)
|
|
83
|
+
return `${min} min`;
|
|
84
|
+
return `${Math.floor(min / 60)}h ${min % 60}m`;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=preflight-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight-core.js","sourceRoot":"","sources":["../../../src/hooks/preflight-core.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+EAA+E;AAC/E,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAE9E,OAAO,EAAE,WAAW,EAAqB,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAsB,MAAM,2BAA2B,CAAC;AAwBnF,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAa,EACb,IAAyB,EACzB,IAAoB;IAEpB,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,WAAW,CAAC;IAC7C,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,kBAAkB,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAElC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAC5B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,CACnD,CAAC;IAEF,6CAA6C;IAC7C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACpD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC;IACpB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAiC,EAAE,CAAC;IAEnD,mCAAmC;IACnC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAC3C,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAC9C,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACjC,QAAQ,CAAC,IAAI,CACX,UAAU,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,uBAAuB,KAAK,GAAG;YACvD,UAAU,CAAC,CAAC,MAAM,KAAK,GAAG,OAAO,CACpC,CAAC;QACF,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,QAAQ,EAAE,GAAG;SACd,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,QAAQ;QACR,SAAS;KACV,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,OAAO,CAAC,EAAU,EAAE,GAAW;IACtC,MAAM,EAAE,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;IACnC,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAC/B,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAC9B,IAAI,GAAG,GAAG,EAAE;QAAE,OAAO,GAAG,GAAG,MAAM,CAAC;IAClC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,KAAK,GAAG,GAAG,EAAE,GAAG,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec Keyword Bridge — Session-based dedup for keyword-triggered spec injection.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which keywords and entries have already been injected in the current session
|
|
5
|
+
* to prevent duplicate injection when the same keyword appears in multiple prompts.
|
|
6
|
+
*
|
|
7
|
+
* Bridge file: {tmpdir}/maestro-spec-kw-{sessionId}.json
|
|
8
|
+
*/
|
|
9
|
+
export interface SpecKeywordBridge {
|
|
10
|
+
session_id: string;
|
|
11
|
+
injected_keywords: string[];
|
|
12
|
+
injected_entries: string[];
|
|
13
|
+
updated_at: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Read the spec keyword bridge file for a session.
|
|
17
|
+
* Returns null if the file does not exist or is unreadable.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readSpecBridge(sessionId: string): SpecKeywordBridge | null;
|
|
20
|
+
/**
|
|
21
|
+
* Mark keywords and entry IDs as injected for this session.
|
|
22
|
+
* Merges with existing bridge data (additive, never removes).
|
|
23
|
+
*/
|
|
24
|
+
export declare function markInjected(sessionId: string, keywords: string[], entryIds: string[]): void;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a keyword has already been injected this session.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isKeywordInjected(sessionId: string, keyword: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Check if an entry has already been injected this session.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isEntryInjected(sessionId: string, entryId: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Filter entries to only those not yet injected in this session.
|
|
35
|
+
* An entry is considered "already injected" if its ID is in the bridge.
|
|
36
|
+
*/
|
|
37
|
+
export declare function filterUnjected<T extends {
|
|
38
|
+
id: string;
|
|
39
|
+
}>(sessionId: string, entries: T[]): T[];
|
|
40
|
+
//# sourceMappingURL=spec-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-bridge.d.ts","sourceRoot":"","sources":["../../../src/hooks/spec-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAU1E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,IAAI,CA0BN;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAI7E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACrD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,EAAE,GACX,CAAC,EAAE,CAML"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec Keyword Bridge — Session-based dedup for keyword-triggered spec injection.
|
|
3
|
+
*
|
|
4
|
+
* Tracks which keywords and entries have already been injected in the current session
|
|
5
|
+
* to prevent duplicate injection when the same keyword appears in multiple prompts.
|
|
6
|
+
*
|
|
7
|
+
* Bridge file: {tmpdir}/maestro-spec-kw-{sessionId}.json
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { tmpdir } from 'node:os';
|
|
12
|
+
import { SPEC_KW_BRIDGE_PREFIX } from './constants.js';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Public API
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Read the spec keyword bridge file for a session.
|
|
18
|
+
* Returns null if the file does not exist or is unreadable.
|
|
19
|
+
*/
|
|
20
|
+
export function readSpecBridge(sessionId) {
|
|
21
|
+
const path = bridgePath(sessionId);
|
|
22
|
+
if (!existsSync(path))
|
|
23
|
+
return null;
|
|
24
|
+
try {
|
|
25
|
+
const raw = readFileSync(path, 'utf-8');
|
|
26
|
+
return JSON.parse(raw);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Mark keywords and entry IDs as injected for this session.
|
|
34
|
+
* Merges with existing bridge data (additive, never removes).
|
|
35
|
+
*/
|
|
36
|
+
export function markInjected(sessionId, keywords, entryIds) {
|
|
37
|
+
const existing = readSpecBridge(sessionId) ?? {
|
|
38
|
+
session_id: sessionId,
|
|
39
|
+
injected_keywords: [],
|
|
40
|
+
injected_entries: [],
|
|
41
|
+
updated_at: 0,
|
|
42
|
+
};
|
|
43
|
+
const kwSet = new Set(existing.injected_keywords);
|
|
44
|
+
for (const kw of keywords)
|
|
45
|
+
kwSet.add(kw.toLowerCase());
|
|
46
|
+
const entrySet = new Set(existing.injected_entries);
|
|
47
|
+
for (const id of entryIds)
|
|
48
|
+
entrySet.add(id);
|
|
49
|
+
const updated = {
|
|
50
|
+
session_id: sessionId,
|
|
51
|
+
injected_keywords: [...kwSet],
|
|
52
|
+
injected_entries: [...entrySet],
|
|
53
|
+
updated_at: Math.floor(Date.now() / 1000),
|
|
54
|
+
};
|
|
55
|
+
try {
|
|
56
|
+
writeFileSync(bridgePath(sessionId), JSON.stringify(updated), 'utf-8');
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Best-effort — don't fail the hook if bridge write fails
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check if a keyword has already been injected this session.
|
|
64
|
+
*/
|
|
65
|
+
export function isKeywordInjected(sessionId, keyword) {
|
|
66
|
+
const bridge = readSpecBridge(sessionId);
|
|
67
|
+
if (!bridge)
|
|
68
|
+
return false;
|
|
69
|
+
return bridge.injected_keywords.includes(keyword.toLowerCase());
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if an entry has already been injected this session.
|
|
73
|
+
*/
|
|
74
|
+
export function isEntryInjected(sessionId, entryId) {
|
|
75
|
+
const bridge = readSpecBridge(sessionId);
|
|
76
|
+
if (!bridge)
|
|
77
|
+
return false;
|
|
78
|
+
return bridge.injected_entries.includes(entryId);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Filter entries to only those not yet injected in this session.
|
|
82
|
+
* An entry is considered "already injected" if its ID is in the bridge.
|
|
83
|
+
*/
|
|
84
|
+
export function filterUnjected(sessionId, entries) {
|
|
85
|
+
const bridge = readSpecBridge(sessionId);
|
|
86
|
+
if (!bridge)
|
|
87
|
+
return entries;
|
|
88
|
+
const injectedSet = new Set(bridge.injected_entries);
|
|
89
|
+
return entries.filter(e => !injectedSet.has(e.id));
|
|
90
|
+
}
|
|
91
|
+
// ============================================================================
|
|
92
|
+
// Internal
|
|
93
|
+
// ============================================================================
|
|
94
|
+
function bridgePath(sessionId) {
|
|
95
|
+
return join(tmpdir(), `${SPEC_KW_BRIDGE_PREFIX}${sessionId}.json`);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=spec-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-bridge.js","sourceRoot":"","sources":["../../../src/hooks/spec-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-injector.d.ts","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"spec-injector.d.ts","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAIvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAM7D,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,qDAAqD;IACrD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,mBAAmB,EAC5B,GAAG,CAAC,EAAE,MAAM,GACX,mBAAmB,CAmDrB"}
|
|
@@ -15,23 +15,21 @@ import { resolveSelf } from '../tools/team-members.js';
|
|
|
15
15
|
// Default agent-type → spec-category mapping
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
const DEFAULT_AGENT_SPEC_MAP = {
|
|
18
|
-
// Execution agents →
|
|
19
|
-
'code-developer': { categories: ['
|
|
20
|
-
'tdd-developer': { categories: ['
|
|
21
|
-
'workflow-executor': { categories: ['
|
|
22
|
-
'universal-executor': { categories: ['
|
|
23
|
-
'test-fix-agent': { categories: ['
|
|
24
|
-
// Planning agents →
|
|
25
|
-
'cli-lite-planning-agent': { categories: ['
|
|
26
|
-
'action-planning-agent': { categories: ['
|
|
27
|
-
'workflow-planner': { categories: ['
|
|
18
|
+
// Execution agents → coding specs
|
|
19
|
+
'code-developer': { categories: ['coding'], extras: [] },
|
|
20
|
+
'tdd-developer': { categories: ['coding', 'test'], extras: [] },
|
|
21
|
+
'workflow-executor': { categories: ['coding'], extras: [] },
|
|
22
|
+
'universal-executor': { categories: ['coding'], extras: [] },
|
|
23
|
+
'test-fix-agent': { categories: ['coding', 'test'], extras: [] },
|
|
24
|
+
// Planning agents → arch specs
|
|
25
|
+
'cli-lite-planning-agent': { categories: ['arch'], extras: [] },
|
|
26
|
+
'action-planning-agent': { categories: ['arch'], extras: [] },
|
|
27
|
+
'workflow-planner': { categories: ['arch'], extras: [] },
|
|
28
28
|
// Review agents → review specs
|
|
29
29
|
'workflow-reviewer': { categories: ['review'], extras: [] },
|
|
30
30
|
// Debug agents → debug specs
|
|
31
31
|
'debug-explore-agent': { categories: ['debug'], extras: [] },
|
|
32
32
|
'workflow-debugger': { categories: ['debug'], extras: [] },
|
|
33
|
-
// Explore agents → exploration (lightweight)
|
|
34
|
-
'Explore': { categories: ['exploration'], extras: [] },
|
|
35
33
|
};
|
|
36
34
|
// ---------------------------------------------------------------------------
|
|
37
35
|
// Public API
|
|
@@ -65,6 +63,14 @@ export function evaluateSpecInjection(agentType, projectPath, sessionId, config,
|
|
|
65
63
|
totalCount += result.totalLoaded;
|
|
66
64
|
}
|
|
67
65
|
}
|
|
66
|
+
if (sections.length === 0 && !sessionId)
|
|
67
|
+
return { inject: false };
|
|
68
|
+
// Keyword-based injection from agent prompt (if sessionId available)
|
|
69
|
+
if (sessionId && projectPath) {
|
|
70
|
+
// Extract prompt from the original function context — the caller should pass it
|
|
71
|
+
// For now, keyword injection from agent prompts is handled at the hook runner level
|
|
72
|
+
// via evaluateKeywordInjection(), not here. This keeps the two concerns separate.
|
|
73
|
+
}
|
|
68
74
|
if (sections.length === 0)
|
|
69
75
|
return { inject: false };
|
|
70
76
|
const rawContent = sections.join('\n\n---\n\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-injector.js","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAqB,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"spec-injector.js","sourceRoot":"","sources":["../../../src/hooks/spec-injector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Maestro Statusline Hook
|
|
2
|
+
* Maestro Statusline Hook — Powerline × Notion style
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Renders a Nerd-Font Powerline statusline with muted Notion-inspired colors.
|
|
5
|
+
* Segments are conditionally shown — empty segments are omitted for a clean line.
|
|
6
|
+
*
|
|
7
|
+
* Segments (left → right):
|
|
8
|
+
* Model | Phase | Coordinator | Task | Team | Directory+Git | Context bar
|
|
6
9
|
*
|
|
7
10
|
* Input (stdin JSON from Claude Code):
|
|
8
11
|
* { model, workspace, session_id, context_window }
|
|
9
12
|
*
|
|
10
|
-
* Output (stdout): formatted
|
|
13
|
+
* Output (stdout): formatted Powerline string
|
|
11
14
|
*/
|
|
12
15
|
interface StatuslineInput {
|
|
13
16
|
model?: {
|
|
@@ -21,21 +24,9 @@ interface StatuslineInput {
|
|
|
21
24
|
remaining_percentage?: number;
|
|
22
25
|
};
|
|
23
26
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Build the teammate activity segment. Returns empty string if:
|
|
26
|
-
* - Team mode not enabled (no self record)
|
|
27
|
-
* - No recent teammate activity in the last 30 minutes (excluding self)
|
|
28
|
-
* - Any error (never throws)
|
|
29
|
-
*
|
|
30
|
-
* Result is cached per-session for 10 seconds via a JSON file in os.tmpdir().
|
|
31
|
-
*/
|
|
32
27
|
export declare function buildTeamSegment(session: string): string;
|
|
33
|
-
/**
|
|
34
|
-
* Build coordinator progress segment from bridge file.
|
|
35
|
-
* Returns e.g. "[3/6]verify" or "[P]review" (paused) or empty string.
|
|
36
|
-
*/
|
|
37
28
|
export declare function buildCoordinatorSegment(session: string): string;
|
|
38
|
-
/** Main statusline handler — processes input and returns
|
|
29
|
+
/** Main statusline handler — processes input and returns Powerline string */
|
|
39
30
|
export declare function formatStatusline(data: StatuslineInput): string;
|
|
40
31
|
/** Entry point — reads stdin JSON, writes formatted statusline to stdout */
|
|
41
32
|
export declare function runStatusline(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statusline.d.ts","sourceRoot":"","sources":["../../../src/hooks/statusline.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"statusline.d.ts","sourceRoot":"","sources":["../../../src/hooks/statusline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA+BH,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,SAAS,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AA4SD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA2DxD;AAMD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAqB/D;AAMD,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAoH9D;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,IAAI,IAAI,CAepC"}
|