maestro-flow 0.3.23 → 0.3.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/.claude/agents/cli-explore-agent.md +2 -2
  2. package/.claude/commands/learn-investigate.md +26 -0
  3. package/dashboard/dist-server/dashboard/src/server/agents/codex-cli-adapter.d.ts +2 -0
  4. package/dashboard/dist-server/dashboard/src/server/agents/codex-cli-adapter.js +32 -7
  5. package/dashboard/dist-server/dashboard/src/server/agents/codex-cli-adapter.js.map +1 -1
  6. package/dashboard/dist-server/src/agents/cli-agent-runner.d.ts +2 -0
  7. package/dashboard/dist-server/src/agents/cli-agent-runner.js +62 -4
  8. package/dashboard/dist-server/src/agents/cli-agent-runner.js.map +1 -1
  9. package/dashboard/dist-server/src/commands/delegate.d.ts +2 -0
  10. package/dashboard/dist-server/src/commands/delegate.js +1 -0
  11. package/dashboard/dist-server/src/commands/delegate.js.map +1 -1
  12. package/dashboard/dist-server/src/config/cli-tools-config.d.ts +4 -0
  13. package/dashboard/dist-server/src/config/cli-tools-config.js +22 -0
  14. package/dashboard/dist-server/src/config/cli-tools-config.js.map +1 -1
  15. package/dashboard/dist-server/src/config/paths.d.ts +1 -0
  16. package/dashboard/dist-server/src/config/paths.js +1 -0
  17. package/dashboard/dist-server/src/config/paths.js.map +1 -1
  18. package/dashboard/dist-server/src/tools/spec-entry-parser.d.ts +55 -0
  19. package/dashboard/dist-server/src/tools/spec-entry-parser.js +222 -0
  20. package/dashboard/dist-server/src/tools/spec-entry-parser.js.map +1 -0
  21. package/dashboard/dist-server/src/tools/spec-loader.d.ts +51 -0
  22. package/dashboard/dist-server/src/tools/spec-loader.js +267 -0
  23. package/dashboard/dist-server/src/tools/spec-loader.js.map +1 -0
  24. package/dist/src/agents/cli-agent-runner.d.ts +2 -0
  25. package/dist/src/agents/cli-agent-runner.d.ts.map +1 -1
  26. package/dist/src/agents/cli-agent-runner.js +62 -4
  27. package/dist/src/agents/cli-agent-runner.js.map +1 -1
  28. package/dist/src/cli.js +2 -0
  29. package/dist/src/cli.js.map +1 -1
  30. package/dist/src/commands/config-ui/ConfigSourcesView.d.ts +6 -0
  31. package/dist/src/commands/config-ui/ConfigSourcesView.d.ts.map +1 -0
  32. package/dist/src/commands/config-ui/ConfigSourcesView.js +25 -0
  33. package/dist/src/commands/config-ui/ConfigSourcesView.js.map +1 -0
  34. package/dist/src/commands/config-ui/SkillConfigDashboard.d.ts +9 -0
  35. package/dist/src/commands/config-ui/SkillConfigDashboard.d.ts.map +1 -0
  36. package/dist/src/commands/config-ui/SkillConfigDashboard.js +64 -0
  37. package/dist/src/commands/config-ui/SkillConfigDashboard.js.map +1 -0
  38. package/dist/src/commands/config-ui/SkillParamEditor.d.ts +12 -0
  39. package/dist/src/commands/config-ui/SkillParamEditor.d.ts.map +1 -0
  40. package/dist/src/commands/config-ui/SkillParamEditor.js +162 -0
  41. package/dist/src/commands/config-ui/SkillParamEditor.js.map +1 -0
  42. package/dist/src/commands/config-ui/SkillsList.d.ts +12 -0
  43. package/dist/src/commands/config-ui/SkillsList.d.ts.map +1 -0
  44. package/dist/src/commands/config-ui/SkillsList.js +91 -0
  45. package/dist/src/commands/config-ui/SkillsList.js.map +1 -0
  46. package/dist/src/commands/config.d.ts +8 -0
  47. package/dist/src/commands/config.d.ts.map +1 -0
  48. package/dist/src/commands/config.js +172 -0
  49. package/dist/src/commands/config.js.map +1 -0
  50. package/dist/src/commands/delegate.d.ts +2 -0
  51. package/dist/src/commands/delegate.d.ts.map +1 -1
  52. package/dist/src/commands/delegate.js +1 -0
  53. package/dist/src/commands/delegate.js.map +1 -1
  54. package/dist/src/commands/install.d.ts.map +1 -1
  55. package/dist/src/commands/install.js +5 -0
  56. package/dist/src/commands/install.js.map +1 -1
  57. package/dist/src/config/argument-hint-parser.d.ts +49 -0
  58. package/dist/src/config/argument-hint-parser.d.ts.map +1 -0
  59. package/dist/src/config/argument-hint-parser.js +283 -0
  60. package/dist/src/config/argument-hint-parser.js.map +1 -0
  61. package/dist/src/config/cli-tools-config.d.ts +4 -0
  62. package/dist/src/config/cli-tools-config.d.ts.map +1 -1
  63. package/dist/src/config/cli-tools-config.js +22 -0
  64. package/dist/src/config/cli-tools-config.js.map +1 -1
  65. package/dist/src/config/paths.d.ts +1 -0
  66. package/dist/src/config/paths.d.ts.map +1 -1
  67. package/dist/src/config/paths.js +1 -0
  68. package/dist/src/config/paths.js.map +1 -1
  69. package/dist/src/config/skill-config.d.ts +56 -0
  70. package/dist/src/config/skill-config.d.ts.map +1 -0
  71. package/dist/src/config/skill-config.js +188 -0
  72. package/dist/src/config/skill-config.js.map +1 -0
  73. package/dist/src/hooks/skill-context.d.ts +12 -2
  74. package/dist/src/hooks/skill-context.d.ts.map +1 -1
  75. package/dist/src/hooks/skill-context.js +126 -39
  76. package/dist/src/hooks/skill-context.js.map +1 -1
  77. package/package.json +1 -1
  78. package/templates/cli/protocols/analysis-protocol.md +121 -121
  79. package/templates/cli/protocols/write-protocol.md +138 -138
  80. package/workflows/debug.md +35 -0
  81. package/workflows/execute.md +23 -0
  82. package/workflows/milestone-audit.md +28 -0
  83. package/workflows/plan.md +17 -0
  84. package/workflows/review.md +46 -0
  85. package/workflows/test-gen.md +28 -0
  86. package/workflows/verify.md +38 -0
@@ -6,6 +6,7 @@ export declare const paths: {
6
6
  readonly data: string;
7
7
  readonly logs: string;
8
8
  readonly cliHistory: string;
9
+ readonly skillConfig: string;
9
10
  readonly project: (root: string) => {
10
11
  root: string;
11
12
  workflow: string;
@@ -10,6 +10,7 @@ export const paths = {
10
10
  data: join(MAESTRO_HOME, 'data'),
11
11
  logs: join(MAESTRO_HOME, 'logs'),
12
12
  cliHistory: join(MAESTRO_HOME, 'cli-history'),
13
+ skillConfig: join(MAESTRO_HOME, 'skill-config.json'),
13
14
  project(root) {
14
15
  return {
15
16
  root: resolve(root),
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../../src/config/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEhD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC;IACzC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;IAClC,UAAU,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;IAC5C,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;IAChC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;IAChC,UAAU,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC;IAE7C,OAAO,CAAC,IAAY;QAClB,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACnB,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;YACjC,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;SACnC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAG,IAAc;QACtB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;CACO,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../../src/config/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEhD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC;IACzC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;IAClC,UAAU,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;IAC5C,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;IAChC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;IAChC,UAAU,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC;IAC7C,WAAW,EAAE,IAAI,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAEpD,OAAO,CAAC,IAAY;QAClB,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;YACnB,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;YACjC,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;SACnC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAG,IAAc;QACtB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC;CACO,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Spec Entry Parser
3
+ *
4
+ * Parses `<spec-entry>` closed-tag blocks from spec markdown files.
5
+ * Supports dual-format: new `<spec-entry>` tags + legacy heading-based entries.
6
+ */
7
+ export interface SpecEntryParsed {
8
+ category: string;
9
+ keywords: string[];
10
+ date: string;
11
+ source?: string;
12
+ title: string;
13
+ content: string;
14
+ lineStart: number;
15
+ lineEnd: number;
16
+ }
17
+ export interface ParseResult {
18
+ entries: SpecEntryParsed[];
19
+ legacy: LegacyEntry[];
20
+ errors: ParseError[];
21
+ }
22
+ export interface LegacyEntry {
23
+ title: string;
24
+ content: string;
25
+ lineStart: number;
26
+ }
27
+ export interface ParseError {
28
+ line: number;
29
+ message: string;
30
+ }
31
+ export declare const VALID_CATEGORIES: readonly ["coding", "arch", "quality", "debug", "test", "review", "learning"];
32
+ export type ValidCategory = (typeof VALID_CATEGORIES)[number];
33
+ /**
34
+ * Parse spec file content into structured entries.
35
+ * Returns new-format `<spec-entry>` entries, legacy heading entries, and any errors.
36
+ */
37
+ export declare function parseSpecEntries(content: string): ParseResult;
38
+ /**
39
+ * Validate a single parsed entry. Returns array of error messages (empty = valid).
40
+ */
41
+ export declare function validateSpecEntry(entry: SpecEntryParsed): string[];
42
+ /**
43
+ * Validate that entry category matches the expected file category.
44
+ */
45
+ export declare function validateCategoryMatch(entry: SpecEntryParsed, fileCategory: string): string | null;
46
+ /**
47
+ * Format parsed entries for display output.
48
+ * Strips `<spec-entry>` tags, shows clean content.
49
+ * If keyword provided, highlights matched entries.
50
+ */
51
+ export declare function formatSpecEntries(entries: SpecEntryParsed[], keyword?: string): string;
52
+ /**
53
+ * Format a single entry for writing to a spec file.
54
+ */
55
+ export declare function formatNewEntry(category: string, keywords: string[], date: string, title: string, content: string, source?: string): string;
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Spec Entry Parser
3
+ *
4
+ * Parses `<spec-entry>` closed-tag blocks from spec markdown files.
5
+ * Supports dual-format: new `<spec-entry>` tags + legacy heading-based entries.
6
+ */
7
+ // ============================================================================
8
+ // Valid categories (shared with spec-loader)
9
+ // ============================================================================
10
+ export const VALID_CATEGORIES = ['coding', 'arch', 'quality', 'debug', 'test', 'review', 'learning'];
11
+ // ============================================================================
12
+ // Core regex
13
+ // ============================================================================
14
+ /** Matches `<spec-entry ...attributes...>...content...</spec-entry>` across lines */
15
+ const SPEC_ENTRY_RE = /<spec-entry\s+([^>]+)>([\s\S]*?)<\/spec-entry>/g;
16
+ /** Extracts key="value" attribute pairs */
17
+ const ATTR_RE = /([\w-]+)="([^"]*)"/g;
18
+ /** Matches ### heading inside entry content */
19
+ const HEADING_RE = /^###\s+(.+)$/m;
20
+ /** Legacy format: ### [category] [date] title OR ### [date] type: title */
21
+ const LEGACY_HEADING_RE = /^###\s+(?:\[[\w-]+\]\s+)?\[(\d{4}-\d{2}-\d{2}(?:\s[\d:]+)?)\]\s*(.+)$/;
22
+ /** Date validation */
23
+ const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
24
+ // ============================================================================
25
+ // Parser
26
+ // ============================================================================
27
+ /**
28
+ * Parse spec file content into structured entries.
29
+ * Returns new-format `<spec-entry>` entries, legacy heading entries, and any errors.
30
+ */
31
+ export function parseSpecEntries(content) {
32
+ const entries = [];
33
+ const errors = [];
34
+ // Track which character ranges are consumed by <spec-entry> blocks
35
+ const consumed = [];
36
+ // Pass 1: Extract <spec-entry> blocks
37
+ let match;
38
+ SPEC_ENTRY_RE.lastIndex = 0;
39
+ while ((match = SPEC_ENTRY_RE.exec(content)) !== null) {
40
+ const attrStr = match[1];
41
+ const body = match[2];
42
+ const blockStart = match.index;
43
+ const blockEnd = blockStart + match[0].length;
44
+ const lineStart = lineNumber(content, blockStart);
45
+ const lineEnd = lineNumber(content, blockEnd);
46
+ consumed.push({ start: blockStart, end: blockEnd });
47
+ // Parse attributes
48
+ const attrs = parseAttributes(attrStr);
49
+ // Extract title from first ### heading
50
+ const titleMatch = body.match(HEADING_RE);
51
+ const title = titleMatch ? titleMatch[1].trim() : '';
52
+ // Validate and build entry
53
+ const entry = {
54
+ category: attrs.category ?? '',
55
+ keywords: attrs.keywords ? attrs.keywords.split(',').map(k => k.trim().toLowerCase()).filter(Boolean) : [],
56
+ date: attrs.date ?? '',
57
+ source: attrs.source,
58
+ title,
59
+ content: body.trim(),
60
+ lineStart,
61
+ lineEnd,
62
+ };
63
+ entries.push(entry);
64
+ // Collect validation errors
65
+ const validationErrors = validateSpecEntry(entry);
66
+ for (const msg of validationErrors) {
67
+ errors.push({ line: lineStart, message: msg });
68
+ }
69
+ }
70
+ // Pass 2: Extract legacy entries from remaining text
71
+ const legacy = parseLegacyEntries(content, consumed);
72
+ return { entries, legacy, errors };
73
+ }
74
+ // ============================================================================
75
+ // Validation
76
+ // ============================================================================
77
+ /**
78
+ * Validate a single parsed entry. Returns array of error messages (empty = valid).
79
+ */
80
+ export function validateSpecEntry(entry) {
81
+ const errors = [];
82
+ if (!entry.category) {
83
+ errors.push('Missing required attribute: category');
84
+ }
85
+ else if (!VALID_CATEGORIES.includes(entry.category)) {
86
+ errors.push(`Invalid category "${entry.category}". Must be one of: ${VALID_CATEGORIES.join(', ')}`);
87
+ }
88
+ if (entry.keywords.length === 0) {
89
+ errors.push('Missing required attribute: keywords (need at least 1)');
90
+ }
91
+ if (!entry.date) {
92
+ errors.push('Missing required attribute: date');
93
+ }
94
+ else if (!DATE_RE.test(entry.date)) {
95
+ errors.push(`Invalid date format "${entry.date}". Expected YYYY-MM-DD`);
96
+ }
97
+ return errors;
98
+ }
99
+ /**
100
+ * Validate that entry category matches the expected file category.
101
+ */
102
+ export function validateCategoryMatch(entry, fileCategory) {
103
+ if (entry.category && entry.category !== fileCategory) {
104
+ return `Entry category "${entry.category}" does not match file category "${fileCategory}"`;
105
+ }
106
+ return null;
107
+ }
108
+ // ============================================================================
109
+ // Formatting
110
+ // ============================================================================
111
+ /**
112
+ * Format parsed entries for display output.
113
+ * Strips `<spec-entry>` tags, shows clean content.
114
+ * If keyword provided, highlights matched entries.
115
+ */
116
+ export function formatSpecEntries(entries, keyword) {
117
+ const filtered = keyword
118
+ ? entries.filter(e => e.keywords.includes(keyword.toLowerCase()))
119
+ : entries;
120
+ if (filtered.length === 0)
121
+ return '';
122
+ return filtered.map(formatEntryClean).join('\n\n---\n\n');
123
+ }
124
+ /**
125
+ * Format a single parsed entry as clean markdown with metadata line.
126
+ *
127
+ * Input content: `### Title\n\nBody`
128
+ * Output: `### Title\n> category · kw1, kw2 · date · source\n\nBody`
129
+ */
130
+ function formatEntryClean(e) {
131
+ const meta = [];
132
+ if (e.category)
133
+ meta.push(e.category);
134
+ if (e.keywords.length > 0)
135
+ meta.push(e.keywords.join(', '));
136
+ if (e.date)
137
+ meta.push(e.date);
138
+ if (e.source)
139
+ meta.push(e.source);
140
+ if (meta.length === 0)
141
+ return e.content;
142
+ const metaLine = `> ${meta.join(' \u00b7 ')}`;
143
+ // Inject after first ### heading line
144
+ const idx = e.content.indexOf('\n');
145
+ if (idx !== -1 && e.content.trimStart().startsWith('###')) {
146
+ return e.content.slice(0, idx) + '\n' + metaLine + e.content.slice(idx);
147
+ }
148
+ return metaLine + '\n\n' + e.content;
149
+ }
150
+ /**
151
+ * Format a single entry for writing to a spec file.
152
+ */
153
+ export function formatNewEntry(category, keywords, date, title, content, source) {
154
+ const kwStr = keywords.map(k => k.toLowerCase().trim()).filter(Boolean).join(',');
155
+ const sourceAttr = source ? ` source="${source}"` : '';
156
+ return `<spec-entry category="${category}" keywords="${kwStr}" date="${date}"${sourceAttr}>\n\n### ${title}\n\n${content}\n\n</spec-entry>`;
157
+ }
158
+ // ============================================================================
159
+ // Internal helpers
160
+ // ============================================================================
161
+ function parseAttributes(attrStr) {
162
+ const attrs = {};
163
+ let m;
164
+ ATTR_RE.lastIndex = 0;
165
+ while ((m = ATTR_RE.exec(attrStr)) !== null) {
166
+ attrs[m[1]] = m[2];
167
+ }
168
+ return attrs;
169
+ }
170
+ function lineNumber(content, charIndex) {
171
+ let line = 1;
172
+ for (let i = 0; i < charIndex && i < content.length; i++) {
173
+ if (content[i] === '\n')
174
+ line++;
175
+ }
176
+ return line;
177
+ }
178
+ /**
179
+ * Parse legacy heading-based entries from text not consumed by <spec-entry> blocks.
180
+ */
181
+ function parseLegacyEntries(content, consumed) {
182
+ const lines = content.split('\n');
183
+ const legacy = [];
184
+ let currentOffset = 0;
185
+ // Build a set of line numbers that are inside <spec-entry> blocks
186
+ const consumedLines = new Set();
187
+ for (const range of consumed) {
188
+ const startLine = lineNumber(content, range.start);
189
+ const endLine = lineNumber(content, range.end);
190
+ for (let i = startLine; i <= endLine; i++) {
191
+ consumedLines.add(i);
192
+ }
193
+ }
194
+ let current = null;
195
+ for (let i = 0; i < lines.length; i++) {
196
+ const lineNum = i + 1;
197
+ if (consumedLines.has(lineNum))
198
+ continue;
199
+ const line = lines[i];
200
+ const m = line.match(LEGACY_HEADING_RE);
201
+ if (m) {
202
+ if (current) {
203
+ const body = current.bodyLines.join('\n').trim();
204
+ if (body) {
205
+ legacy.push({ title: current.title, content: `### ${current.title}\n\n${body}`, lineStart: current.lineStart });
206
+ }
207
+ }
208
+ current = { title: m[2].trim(), bodyLines: [], lineStart: lineNum };
209
+ }
210
+ else if (current) {
211
+ current.bodyLines.push(line);
212
+ }
213
+ }
214
+ if (current) {
215
+ const body = current.bodyLines.join('\n').trim();
216
+ if (body) {
217
+ legacy.push({ title: current.title, content: `### ${current.title}\n\n${body}`, lineStart: current.lineStart });
218
+ }
219
+ }
220
+ return legacy;
221
+ }
222
+ //# sourceMappingURL=spec-entry-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-entry-parser.js","sourceRoot":"","sources":["../../../../src/tools/spec-entry-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Spec Loader (simplified)
3
+ *
4
+ * Filename-based category routing. No frontmatter dependency.
5
+ * Reads .workflow/specs/*.md, filters by category via static mapping,
6
+ * returns concatenated content.
7
+ */
8
+ export type SpecCategory = 'coding' | 'arch' | 'quality' | 'debug' | 'test' | 'review' | 'learning';
9
+ export type SpecScope = 'project' | 'global' | 'team' | 'personal';
10
+ export interface SpecLoadResult {
11
+ content: string;
12
+ matchedSpecs: string[];
13
+ totalLoaded: number;
14
+ }
15
+ export declare const CATEGORY_MAP: Record<string, SpecCategory>;
16
+ export declare const TEAM_SPECS_DIR = ".workflow/collab/specs";
17
+ /**
18
+ * Resolve the directory for a given spec scope.
19
+ *
20
+ * | scope | directory |
21
+ * |------------|-------------------------------------|
22
+ * | project | .workflow/specs/ |
23
+ * | global | ~/.maestro/specs/ |
24
+ * | team | .workflow/collab/specs/ |
25
+ * | personal | .workflow/collab/specs/{uid}/ |
26
+ */
27
+ export declare function resolveSpecDir(projectPath: string, scope: SpecScope, uid?: string): string;
28
+ /**
29
+ * Load spec files from one or more directories.
30
+ *
31
+ * Layer scanning order (lowest → highest priority):
32
+ * 0. ~/.maestro/specs/ (global — when `scope` includes global)
33
+ * 1. .workflow/specs/ (baseline)
34
+ * 2. .workflow/collab/specs/ (team shared — when `uid` is provided)
35
+ * 3. .workflow/collab/specs/{uid}/ (personal — when `uid` is provided)
36
+ *
37
+ * Content from later layers is appended (never replaces earlier content).
38
+ * Each layer's content is prefixed with a header for clarity.
39
+ *
40
+ * @param scope Controls which extra layers to include beyond baseline.
41
+ * - 'project': baseline only (default)
42
+ * - 'global': global + baseline
43
+ * - 'team': baseline + team shared
44
+ * - 'personal': baseline + team shared + personal (requires uid)
45
+ * - undefined: same as 'project'; uid alone still triggers team+personal for backward compat
46
+ */
47
+ export interface LoadSpecsOptions {
48
+ /** Override global specs directory (for testing). Defaults to ~/.maestro/specs/ */
49
+ globalDir?: string;
50
+ }
51
+ export declare function loadSpecs(projectPath: string, category?: SpecCategory, uid?: string, keyword?: string, scope?: SpecScope, options?: LoadSpecsOptions): SpecLoadResult;
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Spec Loader (simplified)
3
+ *
4
+ * Filename-based category routing. No frontmatter dependency.
5
+ * Reads .workflow/specs/*.md, filters by category via static mapping,
6
+ * returns concatenated content.
7
+ */
8
+ import { readFileSync, existsSync, readdirSync, mkdirSync, writeFileSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ import { parseSpecEntries, formatSpecEntries } from './spec-entry-parser.js';
11
+ import { paths } from '../config/paths.js';
12
+ // ============================================================================
13
+ // Filename → Category mapping (single source of truth)
14
+ // ============================================================================
15
+ export const CATEGORY_MAP = {
16
+ 'coding-conventions.md': 'coding',
17
+ 'architecture-constraints.md': 'arch',
18
+ 'quality-rules.md': 'quality',
19
+ 'debug-notes.md': 'debug',
20
+ 'test-conventions.md': 'test',
21
+ 'review-standards.md': 'review',
22
+ 'learnings.md': 'learning',
23
+ };
24
+ const SPECS_DIR = '.workflow/specs';
25
+ export const TEAM_SPECS_DIR = '.workflow/collab/specs';
26
+ /** Layer labels used as section headers when multi-directory scanning is active. */
27
+ const LAYER_LABELS = {
28
+ global: '# Global Specs',
29
+ baseline: '# Baseline Specs',
30
+ team: '# Team Specs',
31
+ // personal label is dynamic — includes uid
32
+ };
33
+ // ============================================================================
34
+ // Public API
35
+ // ============================================================================
36
+ /**
37
+ * Resolve the directory for a given spec scope.
38
+ *
39
+ * | scope | directory |
40
+ * |------------|-------------------------------------|
41
+ * | project | .workflow/specs/ |
42
+ * | global | ~/.maestro/specs/ |
43
+ * | team | .workflow/collab/specs/ |
44
+ * | personal | .workflow/collab/specs/{uid}/ |
45
+ */
46
+ export function resolveSpecDir(projectPath, scope, uid) {
47
+ switch (scope) {
48
+ case 'global': return paths.specs;
49
+ case 'team': return join(projectPath, TEAM_SPECS_DIR);
50
+ case 'personal': {
51
+ if (!uid)
52
+ throw new Error('personal scope requires uid');
53
+ return join(projectPath, TEAM_SPECS_DIR, uid);
54
+ }
55
+ case 'project':
56
+ default: return join(projectPath, SPECS_DIR);
57
+ }
58
+ }
59
+ export function loadSpecs(projectPath, category, uid, keyword, scope, options) {
60
+ const globalDir = options?.globalDir ?? paths.specs;
61
+ // Build ordered list of (directory, label) pairs to scan
62
+ const layers = buildLayers(projectPath, uid, scope, globalDir);
63
+ // Auto-init baseline and global layers.
64
+ // Team/personal are per-user — auto-creating them for arbitrary uids is wrong.
65
+ autoInitSeeds(join(projectPath, SPECS_DIR));
66
+ autoInitSeeds(globalDir);
67
+ // First pass: collect results per layer (skip empty)
68
+ const layerResults = [];
69
+ for (const { dir, label } of layers) {
70
+ const { sections, matched } = loadFromDir(dir, category, keyword);
71
+ if (sections.length > 0) {
72
+ layerResults.push({ label, sections, matched });
73
+ }
74
+ }
75
+ // Only show layer headers when multiple layers have actual content
76
+ const multiLayer = layerResults.length > 1;
77
+ const allSections = [];
78
+ const allMatched = [];
79
+ let totalCount = 0;
80
+ for (const { label, sections, matched } of layerResults) {
81
+ if (multiLayer) {
82
+ allSections.push(`${label}\n\n${sections.join('\n\n---\n\n')}`);
83
+ }
84
+ else {
85
+ allSections.push(...sections);
86
+ }
87
+ allMatched.push(...matched);
88
+ totalCount += matched.length;
89
+ }
90
+ return {
91
+ content: allSections.length > 0
92
+ ? `# Project Specs (${totalCount} loaded)\n\n${allSections.join('\n\n---\n\n')}`
93
+ : '',
94
+ matchedSpecs: allMatched,
95
+ totalLoaded: totalCount,
96
+ };
97
+ }
98
+ function buildLayers(projectPath, uid, scope, globalDir) {
99
+ const layers = [];
100
+ // Global layer — always included as lowest priority
101
+ layers.push({ dir: globalDir ?? paths.specs, label: LAYER_LABELS.global });
102
+ // Baseline — always included
103
+ layers.push({
104
+ dir: join(projectPath, SPECS_DIR),
105
+ label: LAYER_LABELS.baseline,
106
+ });
107
+ // Team + personal layers
108
+ // Activated by scope='team'|'personal', or by uid (backward compat)
109
+ if (scope === 'team' || scope === 'personal' || uid) {
110
+ layers.push({ dir: join(projectPath, TEAM_SPECS_DIR), label: LAYER_LABELS.team });
111
+ if (uid) {
112
+ layers.push({ dir: join(projectPath, TEAM_SPECS_DIR, uid), label: `# Personal Specs (${uid})` });
113
+ }
114
+ }
115
+ return layers;
116
+ }
117
+ /**
118
+ * Load spec files from a single directory. Returns empty arrays if the
119
+ * directory does not exist or is unreadable.
120
+ */
121
+ function loadFromDir(specsDir, category, keyword) {
122
+ if (!existsSync(specsDir))
123
+ return { sections: [], matched: [] };
124
+ let files;
125
+ try {
126
+ files = readdirSync(specsDir).filter(f => f.endsWith('.md'));
127
+ }
128
+ catch {
129
+ return { sections: [], matched: [] };
130
+ }
131
+ const sections = [];
132
+ const matched = [];
133
+ for (const file of files) {
134
+ if (!shouldInclude(file, category))
135
+ continue;
136
+ const filePath = join(specsDir, file);
137
+ let raw;
138
+ try {
139
+ raw = readFileSync(filePath, 'utf-8');
140
+ }
141
+ catch {
142
+ continue;
143
+ }
144
+ const body = stripFrontmatter(raw).trim();
145
+ if (!body)
146
+ continue;
147
+ const formatted = formatFileContent(body, keyword);
148
+ if (formatted) {
149
+ sections.push(formatted);
150
+ matched.push(file);
151
+ }
152
+ }
153
+ return { sections, matched };
154
+ }
155
+ // ============================================================================
156
+ // Internal
157
+ // ============================================================================
158
+ function shouldInclude(filename, category) {
159
+ // No category filter → load all
160
+ if (!category)
161
+ return true;
162
+ const cat = CATEGORY_MAP[filename];
163
+ if (cat)
164
+ return cat === category;
165
+ // Unknown files: include only when no category filter
166
+ return false;
167
+ }
168
+ /**
169
+ * Parse file body, strip <spec-entry> tags, format clean output with metadata.
170
+ * When keyword is provided, only return matching entries.
171
+ * Falls back to raw body for files with no structured entries.
172
+ */
173
+ function formatFileContent(body, keyword) {
174
+ const { entries, legacy } = parseSpecEntries(body);
175
+ // No structured entries → pass through raw body (or keyword-grep it)
176
+ if (entries.length === 0 && legacy.length === 0) {
177
+ if (keyword) {
178
+ return body.toLowerCase().includes(keyword.toLowerCase()) ? body : null;
179
+ }
180
+ return body;
181
+ }
182
+ const parts = [];
183
+ if (keyword) {
184
+ const kw = keyword.toLowerCase();
185
+ const matchedEntries = entries.filter(e => e.keywords.includes(kw));
186
+ if (matchedEntries.length > 0)
187
+ parts.push(formatSpecEntries(matchedEntries));
188
+ for (const leg of legacy) {
189
+ if (leg.content.toLowerCase().includes(kw))
190
+ parts.push(leg.content);
191
+ }
192
+ }
193
+ else {
194
+ if (entries.length > 0)
195
+ parts.push(formatSpecEntries(entries));
196
+ for (const leg of legacy)
197
+ parts.push(leg.content);
198
+ }
199
+ return parts.length > 0 ? parts.join('\n\n---\n\n') : null;
200
+ }
201
+ function stripFrontmatter(raw) {
202
+ const trimmed = raw.trimStart();
203
+ if (!trimmed.startsWith('---'))
204
+ return raw;
205
+ const endIdx = trimmed.indexOf('\n---', 3);
206
+ if (endIdx === -1)
207
+ return raw;
208
+ return trimmed.substring(endIdx + 4).trim();
209
+ }
210
+ // ============================================================================
211
+ // Auto-init seed files
212
+ // ============================================================================
213
+ /** Directories already checked this process — skip re-checking. */
214
+ const autoInitChecked = new Set();
215
+ /** Minimal seed files (filename + header). */
216
+ const AUTO_INIT_SEEDS = [
217
+ ['coding-conventions.md', '# Coding Conventions\n\n## Entries\n\n'],
218
+ ['architecture-constraints.md', '# Architecture Constraints\n\n## Entries\n\n'],
219
+ ['learnings.md', '# Learnings\n\n## Entries\n\n'],
220
+ ['quality-rules.md', '# Quality Rules\n\n## Entries\n\n'],
221
+ ['debug-notes.md', '# Debug Notes\n\n## Entries\n\n'],
222
+ ['test-conventions.md', '# Test Conventions\n\n## Entries\n\n'],
223
+ ['review-standards.md', '# Review Standards\n\n## Entries\n\n'],
224
+ ];
225
+ /**
226
+ * Auto-create a specs directory with seed files if it does not exist.
227
+ * Applies to every layer (global, baseline, team, personal).
228
+ *
229
+ * For project-local dirs: only runs when `.workflow/` already exists
230
+ * (i.e. the project is maestro-managed).
231
+ * For global (`~/.maestro/specs/`): always creates — the home dir exists by definition.
232
+ *
233
+ * Synchronous, per-directory dedup, best-effort — never throws.
234
+ */
235
+ function autoInitSeeds(specsDir) {
236
+ if (autoInitChecked.has(specsDir))
237
+ return;
238
+ autoInitChecked.add(specsDir);
239
+ if (existsSync(specsDir))
240
+ return;
241
+ // For project-local paths, only auto-init when .workflow/ already exists.
242
+ // Global path (under ~/.maestro/) always qualifies.
243
+ const isGlobal = specsDir === paths.specs;
244
+ if (!isGlobal) {
245
+ // Walk up to check if .workflow/ parent exists
246
+ // specsDir patterns: <project>/.workflow/specs, <project>/.workflow/collab/specs[/<uid>]
247
+ const workflowIdx = specsDir.replace(/\\/g, '/').indexOf('.workflow/');
248
+ if (workflowIdx !== -1) {
249
+ const workflowDir = specsDir.substring(0, workflowIdx + '.workflow'.length);
250
+ if (!existsSync(workflowDir))
251
+ return;
252
+ }
253
+ }
254
+ try {
255
+ mkdirSync(specsDir, { recursive: true });
256
+ for (const [filename, content] of AUTO_INIT_SEEDS) {
257
+ const filePath = join(specsDir, filename);
258
+ if (!existsSync(filePath)) {
259
+ writeFileSync(filePath, content, 'utf-8');
260
+ }
261
+ }
262
+ }
263
+ catch {
264
+ // Best-effort — don't block loading
265
+ }
266
+ }
267
+ //# sourceMappingURL=spec-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-loader.js","sourceRoot":"","sources":["../../../../src/tools/spec-loader.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,8 @@ export interface CliRunOptions {
43
43
  settingsFile?: string;
44
44
  /** Base tool name for aliases — used to resolve agent type when tool is an alias */
45
45
  baseTool?: string;
46
+ /** Delegate role — maps to spec categories for targeted spec injection */
47
+ role?: string;
46
48
  }
47
49
  export declare function generateCliExecId(tool: string): string;
48
50
  export declare class CliAgentRunner {