@s_s/harmonia 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +396 -2
  2. package/build/cli/setup.d.ts +21 -0
  3. package/build/cli/setup.js +72 -0
  4. package/build/cli/setup.js.map +1 -0
  5. package/build/core/dispatch.d.ts +10 -0
  6. package/build/core/dispatch.js +21 -0
  7. package/build/core/dispatch.js.map +1 -1
  8. package/build/core/docs.d.ts +13 -0
  9. package/build/core/docs.js +32 -0
  10. package/build/core/docs.js.map +1 -1
  11. package/build/core/registry.d.ts +1 -1
  12. package/build/core/registry.js +5 -16
  13. package/build/core/registry.js.map +1 -1
  14. package/build/core/schema.d.ts +38 -0
  15. package/build/core/schema.js +187 -0
  16. package/build/core/schema.js.map +1 -0
  17. package/build/core/state.d.ts +11 -1
  18. package/build/core/state.js +23 -2
  19. package/build/core/state.js.map +1 -1
  20. package/build/core/steps.d.ts +34 -0
  21. package/build/core/steps.js +113 -0
  22. package/build/core/steps.js.map +1 -0
  23. package/build/core/types.d.ts +81 -4
  24. package/build/core/workflow.d.ts +26 -6
  25. package/build/core/workflow.js +88 -11
  26. package/build/core/workflow.js.map +1 -1
  27. package/build/hooks/claude-code.d.ts +20 -0
  28. package/build/hooks/claude-code.js +218 -0
  29. package/build/hooks/claude-code.js.map +1 -0
  30. package/build/hooks/content.d.ts +43 -0
  31. package/build/hooks/content.js +109 -0
  32. package/build/hooks/content.js.map +1 -0
  33. package/build/hooks/install.d.ts +40 -0
  34. package/build/hooks/install.js +63 -0
  35. package/build/hooks/install.js.map +1 -0
  36. package/build/hooks/openclaw.d.ts +24 -0
  37. package/build/hooks/openclaw.js +219 -0
  38. package/build/hooks/openclaw.js.map +1 -0
  39. package/build/hooks/opencode.d.ts +29 -0
  40. package/build/hooks/opencode.js +226 -0
  41. package/build/hooks/opencode.js.map +1 -0
  42. package/build/index.d.ts +4 -7
  43. package/build/index.js +80 -42
  44. package/build/index.js.map +1 -1
  45. package/build/setup/inject.d.ts +13 -17
  46. package/build/setup/inject.js +34 -92
  47. package/build/setup/inject.js.map +1 -1
  48. package/build/setup/templates.d.ts +12 -16
  49. package/build/setup/templates.js +52 -69
  50. package/build/setup/templates.js.map +1 -1
  51. package/build/tools/approve-doc.d.ts +1 -1
  52. package/build/tools/approve-doc.js +4 -4
  53. package/build/tools/approve-doc.js.map +1 -1
  54. package/build/tools/dispatch-role.d.ts +2 -2
  55. package/build/tools/dispatch-role.js +41 -11
  56. package/build/tools/dispatch-role.js.map +1 -1
  57. package/build/tools/doc-tools.d.ts +11 -3
  58. package/build/tools/doc-tools.js +257 -13
  59. package/build/tools/doc-tools.js.map +1 -1
  60. package/build/tools/get-project-status.d.ts +4 -2
  61. package/build/tools/get-project-status.js +165 -50
  62. package/build/tools/get-project-status.js.map +1 -1
  63. package/build/tools/get-role-prompt.d.ts +2 -2
  64. package/build/tools/get-role-prompt.js +4 -4
  65. package/build/tools/get-role-prompt.js.map +1 -1
  66. package/build/tools/override-tools.d.ts +1 -1
  67. package/build/tools/override-tools.js +4 -4
  68. package/build/tools/override-tools.js.map +1 -1
  69. package/build/tools/project-init.d.ts +5 -1
  70. package/build/tools/project-init.js +92 -32
  71. package/build/tools/project-init.js.map +1 -1
  72. package/build/tools/report-dispatch.d.ts +6 -3
  73. package/build/tools/report-dispatch.js +45 -8
  74. package/build/tools/report-dispatch.js.map +1 -1
  75. package/build/tools/set-scale.d.ts +6 -0
  76. package/build/tools/set-scale.js +92 -0
  77. package/build/tools/set-scale.js.map +1 -0
  78. package/build/tools/setup-project.d.ts +1 -1
  79. package/build/tools/setup-project.js +33 -5
  80. package/build/tools/setup-project.js.map +1 -1
  81. package/build/tools/update-phase.d.ts +8 -3
  82. package/build/tools/update-phase.js +85 -20
  83. package/build/tools/update-phase.js.map +1 -1
  84. package/package.json +2 -1
  85. package/workflows/dev/roles/architect.md +1 -1
  86. package/workflows/dev/roles/pm.md +5 -5
  87. package/workflows/dev/roles/tester.md +1 -1
  88. package/workflows/dev/schemas/api-design.json +25 -0
  89. package/workflows/dev/schemas/data-model.json +20 -0
  90. package/workflows/dev/schemas/deploy.json +20 -0
  91. package/workflows/dev/schemas/fsd.json +25 -0
  92. package/workflows/dev/schemas/prd.completeness-check.json +24 -0
  93. package/workflows/dev/schemas/prd.draft.json +15 -0
  94. package/workflows/dev/schemas/prd.final.json +30 -0
  95. package/workflows/dev/schemas/prd.json +30 -0
  96. package/workflows/dev/schemas/prd.requirements.json +25 -0
  97. package/workflows/dev/schemas/project-plan.json +20 -0
  98. package/workflows/dev/schemas/prototype.json +4 -0
  99. package/workflows/dev/schemas/retrospective.json +20 -0
  100. package/workflows/dev/schemas/risk-assessment.json +15 -0
  101. package/workflows/dev/schemas/task-breakdown.coarse.json +15 -0
  102. package/workflows/dev/schemas/task-breakdown.dependencies.json +20 -0
  103. package/workflows/dev/schemas/task-breakdown.detailed.json +10 -0
  104. package/workflows/dev/schemas/task-breakdown.final.json +10 -0
  105. package/workflows/dev/schemas/task-breakdown.json +10 -0
  106. package/workflows/dev/schemas/tech-design.analysis.json +25 -0
  107. package/workflows/dev/schemas/tech-design.api-contract.json +20 -0
  108. package/workflows/dev/schemas/tech-design.draft.json +15 -0
  109. package/workflows/dev/schemas/tech-design.final.json +30 -0
  110. package/workflows/dev/schemas/tech-design.json +30 -0
  111. package/workflows/dev/schemas/test-plan.json +20 -0
  112. package/workflows/dev/schemas/test-report.json +25 -0
  113. package/workflows/dev/schemas/user-stories.json +10 -0
  114. package/workflows/dev/workflow.json +85 -5
@@ -0,0 +1,226 @@
1
+ /**
2
+ * OpenCode hook definitions.
3
+ *
4
+ * OpenCode hooks are TypeScript plugins installed to ~/.config/opencode/plugins/.
5
+ * They export a Plugin object with hooks keyed by event name.
6
+ *
7
+ * Limitations vs Claude Code:
8
+ * - `tool.execute.before` can modify args but CANNOT block tool calls.
9
+ * - No true blocking mechanism (permission.ask is too coarse).
10
+ *
11
+ * Strategy: "soft interception + reminder injection"
12
+ * 1. tool.execute.before — detect boundary violations, replace args to neutralize
13
+ * the operation (e.g., prepend echo to bash commands, empty write content)
14
+ * and inject a warning message.
15
+ * 2. experimental.chat.messages.transform — read Harmonia data files, inject
16
+ * reminders about dispatch timeouts, idle phases, pending reviews.
17
+ *
18
+ * Project-agnostic: no project name/dir baked in.
19
+ * - Boundary guard uses tool names + code file extensions only
20
+ * - Reminders scan all projects under DATA_DIR
21
+ */
22
+ import { defineHooks } from '@s_s/agent-kit';
23
+ import { BLOCKED_COMMANDS, CODE_EXTENSIONS, DISPATCH_TIMEOUT_MINUTES, PHASE_IDLE_TIMEOUT_MINUTES, REVIEW_PENDING_TIMEOUT_MINUTES, } from './content.js';
24
+ /**
25
+ * Generate the OpenCode plugin TypeScript source code.
26
+ *
27
+ * This produces a single plugin file that handles both:
28
+ * - tool.execute.before: soft boundary interception
29
+ * - experimental.chat.messages.transform: proactive reminders
30
+ */
31
+ function generateOpenCodePlugin(params) {
32
+ const codeExtsJson = JSON.stringify(CODE_EXTENSIONS);
33
+ const blockedCmdsJson = JSON.stringify(BLOCKED_COMMANDS);
34
+ // We generate raw TS source as a string. All values from params/constants
35
+ // are baked in as literals at generation time.
36
+ return `import type { Plugin } from 'opencode';
37
+ import { readFileSync, readdirSync, statSync } from 'fs';
38
+ import { resolve, join } from 'path';
39
+
40
+ // ── Baked-in constants (generated by Harmonia setup) ──
41
+ const DATA_DIR = ${JSON.stringify(params.dataDir)};
42
+
43
+ const CODE_EXTENSIONS: readonly string[] = ${codeExtsJson};
44
+ const BLOCKED_COMMANDS: readonly string[] = ${blockedCmdsJson};
45
+ const DISPATCH_TIMEOUT_MINUTES = ${DISPATCH_TIMEOUT_MINUTES};
46
+ const PHASE_IDLE_TIMEOUT_MINUTES = ${PHASE_IDLE_TIMEOUT_MINUTES};
47
+ const REVIEW_PENDING_TIMEOUT_MINUTES = ${REVIEW_PENDING_TIMEOUT_MINUTES};
48
+
49
+ // ── Helpers ──
50
+
51
+ function isCodeFile(filePath: string): boolean {
52
+ return CODE_EXTENSIONS.some((ext) => filePath.endsWith(ext));
53
+ }
54
+
55
+ function hasBlockedCommand(command: string): string | null {
56
+ for (const cmd of BLOCKED_COMMANDS) {
57
+ if (command.includes(cmd)) return cmd;
58
+ }
59
+ return null;
60
+ }
61
+
62
+ function readJsonSafe(filePath: string): any {
63
+ try {
64
+ return JSON.parse(readFileSync(filePath, 'utf-8'));
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+
70
+ function minutesSince(isoDate: string): number {
71
+ const then = new Date(isoDate).getTime();
72
+ if (isNaN(then)) return 0;
73
+ return Math.floor((Date.now() - then) / 60000);
74
+ }
75
+
76
+ /** List project directories under DATA_DIR */
77
+ function listProjectDirs(): Array<{ name: string; path: string }> {
78
+ try {
79
+ const entries = readdirSync(DATA_DIR);
80
+ const projects: Array<{ name: string; path: string }> = [];
81
+ for (const entry of entries) {
82
+ const full = join(DATA_DIR, entry);
83
+ try {
84
+ if (statSync(full).isDirectory()) {
85
+ projects.push({ name: entry, path: full });
86
+ }
87
+ } catch {
88
+ // skip inaccessible entries
89
+ }
90
+ }
91
+ return projects;
92
+ } catch {
93
+ return [];
94
+ }
95
+ }
96
+
97
+ export default {
98
+ name: 'harmonia',
99
+ hooks: {
100
+ // ── Soft boundary interception ──
101
+ 'tool.execute.before': async (
102
+ input: { tool: string; sessionID: string; callID: string },
103
+ output: { args: Record<string, any> },
104
+ ) => {
105
+ const toolName = input.tool;
106
+ const args = output.args;
107
+
108
+ // Guard 1: Write/Edit tools — check file extension
109
+ if (['Write', 'Edit', 'MultiEdit', 'write', 'edit'].includes(toolName)) {
110
+ const filePath = args.file_path || args.filePath || args.path || '';
111
+ if (filePath && isCodeFile(filePath)) {
112
+ // Neutralize: replace content with warning
113
+ output.args = {
114
+ ...args,
115
+ content: \`[HARMONIA 拦截] PM 不应直接修改代码文件。请通过 role_dispatch 将编码任务分配给 developer。\\n原目标文件: \${filePath}\`,
116
+ oldString: '__HARMONIA_BLOCKED_EDIT__',
117
+ newString: '__HARMONIA_BLOCKED_EDIT__',
118
+ };
119
+ return;
120
+ }
121
+ }
122
+
123
+ // Guard 2: Bash/Terminal — check for dev commands
124
+ if (['Bash', 'bash', 'Terminal', 'terminal'].includes(toolName)) {
125
+ const command = args.command || args.cmd || '';
126
+ if (command) {
127
+ const blocked = hasBlockedCommand(command);
128
+ if (blocked) {
129
+ output.args = {
130
+ ...args,
131
+ command: \`echo "[HARMONIA 拦截] PM 不应直接执行开发命令 (\${blocked}...)。请通过 role_dispatch 将任务分配给相应角色(developer/tester)。"\`,
132
+ cmd: \`echo "[HARMONIA 拦截] PM 不应直接执行开发命令 (\${blocked}...)。请通过 role_dispatch 将任务分配给相应角色(developer/tester)。"\`,
133
+ };
134
+ return;
135
+ }
136
+ }
137
+ }
138
+ },
139
+
140
+ // ── Proactive reminders ──
141
+ 'experimental.chat.messages.transform': async (
142
+ messages: Array<{ role: string; content: any }>,
143
+ ) => {
144
+ const reminders: string[] = [];
145
+ const projects = listProjectDirs();
146
+
147
+ for (const proj of projects) {
148
+ // Check 1: Running dispatch timeout
149
+ const dispatches = readJsonSafe(resolve(proj.path, 'dispatches.json'));
150
+ if (dispatches && Array.isArray(dispatches)) {
151
+ for (const d of dispatches) {
152
+ if ((d.status === 'running' || d.status === 'dispatched') && d.updatedAt) {
153
+ const elapsed = minutesSince(d.updatedAt);
154
+ if (elapsed >= DISPATCH_TIMEOUT_MINUTES) {
155
+ reminders.push(
156
+ \`- [\${proj.name}] dispatch \${d.id} (\${d.role}) 已运行 \${elapsed} 分钟,建议调用 project_status 检查进度\`,
157
+ );
158
+ }
159
+ }
160
+ }
161
+ }
162
+
163
+ // Check 2: Pending document reviews
164
+ const reviews = readJsonSafe(resolve(proj.path, 'reviews.json'));
165
+ if (reviews && typeof reviews === 'object') {
166
+ const pendingDocs: string[] = [];
167
+ for (const [docId, review] of Object.entries<any>(reviews)) {
168
+ if (review.status === 'pending' && review.submittedAt) {
169
+ const elapsed = minutesSince(review.submittedAt);
170
+ if (elapsed >= REVIEW_PENDING_TIMEOUT_MINUTES) {
171
+ pendingDocs.push(docId);
172
+ }
173
+ }
174
+ }
175
+ if (pendingDocs.length > 0) {
176
+ reminders.push(
177
+ \`- [\${proj.name}] \${pendingDocs.length} 份文档待审核超过 \${REVIEW_PENDING_TIMEOUT_MINUTES} 分钟: \${pendingDocs.join(', ')} — 请尽快处理(doc_approve / reject_doc)\`,
178
+ );
179
+ }
180
+ }
181
+
182
+ // Check 3: Phase idle check
183
+ const state = readJsonSafe(resolve(proj.path, 'state.json'));
184
+ if (state && state.updatedAt && state.currentPhase) {
185
+ const idle = minutesSince(state.updatedAt);
186
+ if (idle >= PHASE_IDLE_TIMEOUT_MINUTES) {
187
+ reminders.push(
188
+ \`- [\${proj.name}] 当前阶段 (\${state.currentPhase}) 已空闲 \${idle} 分钟,建议调用 project_status 检查项目状态\`,
189
+ );
190
+ }
191
+ }
192
+ }
193
+
194
+ // Inject reminders as a system-like message
195
+ if (reminders.length > 0) {
196
+ messages.push({
197
+ role: 'user',
198
+ content: \`<harmonia-reminder>
199
+ 以下事项需要你的关注:
200
+
201
+ \${reminders.join('\\n')}
202
+
203
+ 请根据提醒采取相应行动。
204
+ </harmonia-reminder>\`,
205
+ });
206
+ }
207
+
208
+ return messages;
209
+ },
210
+ },
211
+ } satisfies Plugin;
212
+ `;
213
+ }
214
+ /**
215
+ * Create OpenCode hook definitions using agent-kit's defineHooks.
216
+ *
217
+ * Produces a single plugin file with both tool.execute.before and
218
+ * experimental.chat.messages.transform hooks.
219
+ */
220
+ export function createOpenCodeHooks(params) {
221
+ return defineHooks('opencode', {
222
+ events: ['tool.execute.before', 'experimental.chat.messages.transform'],
223
+ content: generateOpenCodePlugin(params),
224
+ });
225
+ }
226
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../src/hooks/opencode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EACH,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,0BAA0B,EAC1B,8BAA8B,GACjC,MAAM,cAAc,CAAC;AAEtB;;;;;;GAMG;AACH,SAAS,sBAAsB,CAAC,MAAkB;IAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACrD,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAEzD,0EAA0E;IAC1E,+CAA+C;IAC/C,OAAO;;;;;mBAKQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;;6CAEJ,YAAY;8CACX,eAAe;mCAC1B,wBAAwB;qCACtB,0BAA0B;yCACtB,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqKtE,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IAClD,OAAO,WAAW,CAAC,UAAU,EAAE;QAC3B,MAAM,EAAE,CAAC,qBAAqB,EAAE,sCAAsC,CAAC;QACvE,OAAO,EAAE,sBAAsB,CAAC,MAAM,CAAC;KAC1C,CAAC,CAAC;AACP,CAAC"}
package/build/index.d.ts CHANGED
@@ -2,14 +2,11 @@
2
2
  /**
3
3
  * Harmonia — Multi-agent orchestration MCP server with pluggable workflows.
4
4
  *
5
+ * Entry point with two modes:
6
+ * - `harmonia` → Start MCP stdio server (for agent consumers)
7
+ * - `harmonia setup` → CLI project setup (for humans)
8
+ *
5
9
  * All project data is stored under the Harmonia data directory (platform-specific).
6
10
  * Project source directories contain code only — no Harmonia artifacts.
7
- *
8
- * Provides tools for managing projects:
9
- * - project_init: Register a project and create <data_dir>/<project_name>/ data dirs
10
- * - get_project_status: View current project phase and progress
11
- * - get_role_prompt: Get role prompts for agent setup
12
- * - update_phase: Advance project phases
13
- * - write_doc / read_doc / list_docs: Manage project documents
14
11
  */
15
12
  export {};
package/build/index.js CHANGED
@@ -2,56 +2,94 @@
2
2
  /**
3
3
  * Harmonia — Multi-agent orchestration MCP server with pluggable workflows.
4
4
  *
5
+ * Entry point with two modes:
6
+ * - `harmonia` → Start MCP stdio server (for agent consumers)
7
+ * - `harmonia setup` → CLI project setup (for humans)
8
+ *
5
9
  * All project data is stored under the Harmonia data directory (platform-specific).
6
10
  * Project source directories contain code only — no Harmonia artifacts.
7
- *
8
- * Provides tools for managing projects:
9
- * - project_init: Register a project and create <data_dir>/<project_name>/ data dirs
10
- * - get_project_status: View current project phase and progress
11
- * - get_role_prompt: Get role prompts for agent setup
12
- * - update_phase: Advance project phases
13
- * - write_doc / read_doc / list_docs: Manage project documents
14
11
  */
15
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
16
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
17
12
  import { fileURLToPath } from 'node:url';
18
13
  import { dirname, join, resolve } from 'node:path';
19
- import { registerProjectInit } from './tools/project-init.js';
20
- import { registerGetRolePrompt } from './tools/get-role-prompt.js';
21
- import { registerUpdatePhase } from './tools/update-phase.js';
22
- import { registerDocTools } from './tools/doc-tools.js';
23
- import { registerGetProjectStatus } from './tools/get-project-status.js';
24
- import { registerApproveDoc } from './tools/approve-doc.js';
25
- import { registerOverrideTools } from './tools/override-tools.js';
26
- import { registerDispatchRole } from './tools/dispatch-role.js';
27
- import { registerReportDispatch } from './tools/report-dispatch.js';
28
- import { registerSetupProject } from './tools/setup-project.js';
29
14
  const __filename = fileURLToPath(import.meta.url);
30
15
  const __dirname = dirname(__filename);
31
- // Workflows directory is at the package root, sibling to build/
32
- const WORKFLOWS_DIR = process.env.HARMONIA_WORKFLOWS_DIR ?? resolve(join(__dirname, '..', 'workflows'));
33
- const server = new McpServer({
34
- name: 'harmonia',
35
- version: '0.1.0',
36
- });
37
- // Register all tools
38
- registerProjectInit(server, WORKFLOWS_DIR);
39
- registerGetRolePrompt(server, WORKFLOWS_DIR);
40
- registerUpdatePhase(server, WORKFLOWS_DIR);
41
- registerDocTools(server, WORKFLOWS_DIR);
42
- registerGetProjectStatus(server, WORKFLOWS_DIR);
43
- registerApproveDoc(server);
44
- registerOverrideTools(server);
45
- registerDispatchRole(server, WORKFLOWS_DIR);
46
- registerReportDispatch(server);
47
- registerSetupProject(server);
48
- // Connect via stdio
49
- async function main() {
16
+ // Built-in workflows directory (package root, sibling to build/)
17
+ const BUILTIN_WORKFLOWS_DIR = resolve(join(__dirname, '..', 'workflows'));
18
+ const subcommand = process.argv[2];
19
+ if (subcommand === 'setup') {
20
+ // CLI mode — human-facing project setup
21
+ const { parseSetupArgs, runSetup } = await import('./cli/setup.js');
22
+ try {
23
+ const opts = parseSetupArgs(process.argv.slice(3));
24
+ await runSetup(opts);
25
+ }
26
+ catch (err) {
27
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
28
+ process.exit(1);
29
+ }
30
+ }
31
+ else if (subcommand === '--help' || subcommand === '-h') {
32
+ console.log(`
33
+ Harmonia Multi-agent orchestration MCP server
34
+
35
+ Usage:
36
+ harmonia Start MCP stdio server
37
+ harmonia setup Inject PM prompt + install hooks in current directory
38
+ harmonia --help Show this help message
39
+
40
+ Setup options:
41
+ --agent <type> opencode | claude-code | codex | openclaw (default: auto-detect)
42
+ `);
43
+ }
44
+ else if (subcommand && subcommand !== '--version' && subcommand !== '-v') {
45
+ console.error(`Unknown command: ${subcommand}\nRun 'harmonia --help' for usage.`);
46
+ process.exit(1);
47
+ }
48
+ else if (subcommand === '--version' || subcommand === '-v') {
49
+ // Read version from package.json
50
+ const { readFile } = await import('node:fs/promises');
51
+ try {
52
+ const pkg = JSON.parse(await readFile(join(__dirname, '..', 'package.json'), 'utf-8'));
53
+ console.log(pkg.version);
54
+ }
55
+ catch {
56
+ console.log('unknown');
57
+ }
58
+ }
59
+ else {
60
+ // Default: MCP stdio server mode
61
+ const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js');
62
+ const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
63
+ const { getGlobalDir } = await import('./core/registry.js');
64
+ const { registerProjectInit } = await import('./tools/project-init.js');
65
+ const { registerSetScale } = await import('./tools/set-scale.js');
66
+ const { registerGetRolePrompt } = await import('./tools/get-role-prompt.js');
67
+ const { registerUpdatePhase } = await import('./tools/update-phase.js');
68
+ const { registerDocTools } = await import('./tools/doc-tools.js');
69
+ const { registerGetProjectStatus } = await import('./tools/get-project-status.js');
70
+ const { registerApproveDoc } = await import('./tools/approve-doc.js');
71
+ const { registerOverrideTools } = await import('./tools/override-tools.js');
72
+ const { registerDispatchRole } = await import('./tools/dispatch-role.js');
73
+ const { registerReportDispatch } = await import('./tools/report-dispatch.js');
74
+ // Custom workflows directory: <data_dir>/.workflows
75
+ const CUSTOM_WORKFLOWS_DIR = join(getGlobalDir(), '.workflows');
76
+ const server = new McpServer({
77
+ name: 'harmonia',
78
+ version: '0.1.0',
79
+ });
80
+ // Register all tools
81
+ registerProjectInit(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
82
+ registerSetScale(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
83
+ registerGetRolePrompt(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
84
+ registerUpdatePhase(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
85
+ registerDocTools(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
86
+ registerGetProjectStatus(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
87
+ registerApproveDoc(server);
88
+ registerOverrideTools(server);
89
+ registerDispatchRole(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
90
+ registerReportDispatch(server, BUILTIN_WORKFLOWS_DIR, CUSTOM_WORKFLOWS_DIR);
91
+ // Connect via stdio
50
92
  const transport = new StdioServerTransport();
51
93
  await server.connect(transport);
52
94
  }
53
- main().catch((err) => {
54
- console.error('Fatal error:', err);
55
- process.exit(1);
56
- });
57
95
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,gEAAgE;AAChE,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;AAExG,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IACzB,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,OAAO;CACnB,CAAC,CAAC;AAEH,qBAAqB;AACrB,mBAAmB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC3C,qBAAqB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC7C,mBAAmB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC3C,gBAAgB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AACxC,wBAAwB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAChD,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,oBAAoB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC5C,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAE7B,oBAAoB;AACpB,KAAK,UAAU,IAAI;IACf,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,iEAAiE;AACjE,MAAM,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;AAE1E,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;IACzB,wCAAwC;IACxC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACpE,IAAI,CAAC;QACD,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC;KAAM,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;CAUf,CAAC,CAAC;AACH,CAAC;KAAM,IAAI,UAAU,IAAI,UAAU,KAAK,WAAW,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;IACzE,OAAO,CAAC,KAAK,CAAC,oBAAoB,UAAU,oCAAoC,CAAC,CAAC;IAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;KAAM,IAAI,UAAU,KAAK,WAAW,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;IAC3D,iCAAiC;IACjC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACtD,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;AACL,CAAC;KAAM,CAAC;IACJ,iCAAiC;IACjC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,yCAAyC,CAAC,CAAC;IAC9E,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;IAC3F,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAE5D,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;IACxE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAClE,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;IAC7E,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;IACxE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAClE,MAAM,EAAE,wBAAwB,EAAE,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;IACnF,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IACtE,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;IAC5E,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAC1E,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;IAE9E,oDAAoD;IACpD,MAAM,oBAAoB,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,YAAY,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QACzB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,OAAO;KACnB,CAAC,CAAC;IAEH,qBAAqB;IACrB,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IACzE,gBAAgB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IACtE,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IAC3E,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IACzE,gBAAgB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IACtE,wBAAwB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IAC9E,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IAC1E,sBAAsB,CAAC,MAAM,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;IAE5E,oBAAoB;IACpB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC"}
@@ -1,34 +1,30 @@
1
1
  /**
2
2
  * Setup injection — detect host agent type and inject PM guidance into config.
3
3
  *
4
- * V1 supports only OpenCode (AGENTS.md injection).
5
- * The injection is idempotent re-running replaces existing harmonia block.
4
+ * Delegates to @s_s/agent-kit for agent detection, prompt injection, and
5
+ * marker management. Harmonia provides the prompt content via templates.ts.
6
6
  */
7
- import { type PromptTemplateParams } from './templates.js';
8
- /** Supported host agent types */
9
- export type HostAgentType = 'opencode' | 'claude-code' | 'codex';
7
+ import { type AgentType } from '@s_s/agent-kit';
8
+ /** Marker constants for external use (tests, etc.) */
9
+ export declare const HARMONIA_MARKER_START = "<!-- harmonia:start -->";
10
+ export declare const HARMONIA_MARKER_END = "<!-- harmonia:end -->";
10
11
  /**
11
12
  * Detect the host agent type for a given project directory.
12
13
  *
13
- * V1 heuristic:
14
- * - Check for AGENTS.mdopencode
15
- * - Check for .claude/ dir claude-code
16
- * - Default to opencode (most common)
17
- *
18
- * Future: accept explicit override via parameter.
14
+ * Delegates to agent-kit's detectAgent() which checks file-system
15
+ * characteristics in order: opencodeclaude-code → openclaw → codex.
16
+ * Falls back to 'opencode' if no agent is detected.
19
17
  */
20
- export declare function detectHostAgent(projectDir: string): Promise<HostAgentType>;
18
+ export declare function detectHostAgent(projectDir: string): Promise<AgentType>;
21
19
  /**
22
20
  * Inject the Harmonia PM guidance block into a config file.
23
21
  * If a harmonia block already exists, it is replaced (idempotent).
24
22
  * If the file doesn't exist, it is created.
23
+ *
24
+ * Uses agent-kit's injectPrompt which manages <!-- harmonia:start/end --> markers.
25
25
  */
26
- export declare function injectPrompt(projectDir: string, agentType: HostAgentType, params: PromptTemplateParams): Promise<{
26
+ export declare function injectPrompt(projectDir: string, agentType: AgentType): Promise<{
27
27
  filePath: string;
28
28
  created: boolean;
29
29
  replaced: boolean;
30
30
  }>;
31
- /**
32
- * Remove the Harmonia block from a config file.
33
- */
34
- export declare function removePrompt(projectDir: string, agentType: HostAgentType): Promise<boolean>;
@@ -1,115 +1,57 @@
1
1
  /**
2
2
  * Setup injection — detect host agent type and inject PM guidance into config.
3
3
  *
4
- * V1 supports only OpenCode (AGENTS.md injection).
5
- * The injection is idempotent re-running replaces existing harmonia block.
4
+ * Delegates to @s_s/agent-kit for agent detection, prompt injection, and
5
+ * marker management. Harmonia provides the prompt content via templates.ts.
6
6
  */
7
- import { readFile, writeFile, mkdir } from 'node:fs/promises';
8
- import { join, dirname } from 'node:path';
9
- import { generateOpenCodePrompt, HARMONIA_MARKER_START, HARMONIA_MARKER_END, } from './templates.js';
7
+ import { readFile } from 'node:fs/promises';
8
+ import { createKit, detectAgent } from '@s_s/agent-kit';
9
+ import { generatePmPrompt } from './templates.js';
10
+ /** Shared kit instance — binds all marker tags to "harmonia" */
11
+ const kit = createKit('harmonia');
12
+ /** Marker constants for external use (tests, etc.) */
13
+ export const HARMONIA_MARKER_START = '<!-- harmonia:start -->';
14
+ export const HARMONIA_MARKER_END = '<!-- harmonia:end -->';
10
15
  /**
11
16
  * Detect the host agent type for a given project directory.
12
17
  *
13
- * V1 heuristic:
14
- * - Check for AGENTS.mdopencode
15
- * - Check for .claude/ dir claude-code
16
- * - Default to opencode (most common)
17
- *
18
- * Future: accept explicit override via parameter.
18
+ * Delegates to agent-kit's detectAgent() which checks file-system
19
+ * characteristics in order: opencodeclaude-code → openclaw → codex.
20
+ * Falls back to 'opencode' if no agent is detected.
19
21
  */
20
22
  export async function detectHostAgent(projectDir) {
21
- // Check for .claude directory (Claude Code)
22
- try {
23
- await readFile(join(projectDir, '.claude', 'settings.json'), 'utf-8');
24
- return 'claude-code';
25
- }
26
- catch {
27
- // not claude-code
28
- }
29
- // Default to opencode
30
- return 'opencode';
31
- }
32
- /**
33
- * Get the config file path for a host agent type.
34
- */
35
- function getConfigPath(projectDir, agentType) {
36
- switch (agentType) {
37
- case 'opencode':
38
- return join(projectDir, 'AGENTS.md');
39
- case 'claude-code':
40
- return join(projectDir, 'CLAUDE.md');
41
- case 'codex':
42
- return join(projectDir, 'AGENTS.md');
43
- }
23
+ const detected = await detectAgent(projectDir);
24
+ return detected ?? 'opencode';
44
25
  }
45
26
  /**
46
27
  * Inject the Harmonia PM guidance block into a config file.
47
28
  * If a harmonia block already exists, it is replaced (idempotent).
48
29
  * If the file doesn't exist, it is created.
30
+ *
31
+ * Uses agent-kit's injectPrompt which manages <!-- harmonia:start/end --> markers.
49
32
  */
50
- export async function injectPrompt(projectDir, agentType, params) {
51
- const filePath = getConfigPath(projectDir, agentType);
52
- const prompt = generateOpenCodePrompt(params);
53
- let existingContent = '';
33
+ export async function injectPrompt(projectDir, agentType) {
34
+ const prompt = generatePmPrompt();
35
+ // Check pre-existing state for return value
36
+ const hasExisting = await kit.hasPromptInjected(agentType, { scope: 'project', projectRoot: projectDir });
37
+ // Determine if the config file exists (for created flag)
54
38
  let fileExists = true;
55
39
  try {
56
- existingContent = await readFile(filePath, 'utf-8');
40
+ // agent-kit resolves the config path internally; we replicate the check
41
+ // by looking for an existing injection or reading the resolved file
42
+ const configFileName = agentType === 'claude-code' ? 'CLAUDE.md' : 'AGENTS.md';
43
+ await readFile(`${projectDir}/${configFileName}`, 'utf-8');
57
44
  }
58
45
  catch {
59
46
  fileExists = false;
60
47
  }
61
- let replaced = false;
62
- let newContent;
63
- if (fileExists && existingContent.includes(HARMONIA_MARKER_START)) {
64
- // Replace existing harmonia block
65
- const startIdx = existingContent.indexOf(HARMONIA_MARKER_START);
66
- const endIdx = existingContent.indexOf(HARMONIA_MARKER_END) + HARMONIA_MARKER_END.length;
67
- if (endIdx > startIdx) {
68
- newContent = existingContent.substring(0, startIdx) + prompt + existingContent.substring(endIdx);
69
- replaced = true;
70
- }
71
- else {
72
- // Malformed markers — append
73
- newContent = existingContent + '\n\n' + prompt + '\n';
74
- }
75
- }
76
- else if (fileExists) {
77
- // Append to existing file
78
- newContent = existingContent + '\n\n' + prompt + '\n';
79
- }
80
- else {
81
- // Create new file
82
- newContent = prompt + '\n';
83
- }
84
- await mkdir(dirname(filePath), { recursive: true });
85
- await writeFile(filePath, newContent, 'utf-8');
86
- return { filePath, created: !fileExists, replaced };
87
- }
88
- /**
89
- * Remove the Harmonia block from a config file.
90
- */
91
- export async function removePrompt(projectDir, agentType) {
92
- const filePath = getConfigPath(projectDir, agentType);
93
- try {
94
- const content = await readFile(filePath, 'utf-8');
95
- if (!content.includes(HARMONIA_MARKER_START))
96
- return false;
97
- const startIdx = content.indexOf(HARMONIA_MARKER_START);
98
- const endIdx = content.indexOf(HARMONIA_MARKER_END) + HARMONIA_MARKER_END.length;
99
- if (endIdx <= startIdx)
100
- return false;
101
- // Remove the block and any surrounding blank lines
102
- let newContent = content.substring(0, startIdx) + content.substring(endIdx);
103
- newContent = newContent.replace(/\n{3,}/g, '\n\n').trim();
104
- if (newContent.length === 0) {
105
- // File would be empty — could delete it, but safer to leave empty
106
- newContent = '';
107
- }
108
- await writeFile(filePath, newContent + '\n', 'utf-8');
109
- return true;
110
- }
111
- catch {
112
- return false;
113
- }
48
+ // Inject via agent-kit (handles create, append, and idempotent replace)
49
+ await kit.injectPrompt(agentType, prompt, { scope: 'project', projectRoot: projectDir });
50
+ const configFileName = agentType === 'claude-code' ? 'CLAUDE.md' : 'AGENTS.md';
51
+ return {
52
+ filePath: `${projectDir}/${configFileName}`,
53
+ created: !fileExists,
54
+ replaced: hasExisting,
55
+ };
114
56
  }
115
57
  //# sourceMappingURL=inject.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"inject.js","sourceRoot":"","sources":["../../src/setup/inject.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inject.js","sourceRoot":"","sources":["../../src/setup/inject.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,gEAAgE;AAChE,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;AAElC,sDAAsD;AACtD,MAAM,CAAC,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAC/D,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAAkB;IACpD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAC;IAC/C,OAAO,QAAQ,IAAI,UAAU,CAAC;AAClC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,UAAkB,EAClB,SAAoB;IAEpB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAElC,4CAA4C;IAC5C,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,iBAAiB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;IAE1G,yDAAyD;IACzD,IAAI,UAAU,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC;QACD,wEAAwE;QACxE,oEAAoE;QACpE,MAAM,cAAc,GAAG,SAAS,KAAK,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;QAC/E,MAAM,QAAQ,CAAC,GAAG,UAAU,IAAI,cAAc,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACL,UAAU,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,wEAAwE;IACxE,MAAM,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;IAEzF,MAAM,cAAc,GAAG,SAAS,KAAK,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IAE/E,OAAO;QACH,QAAQ,EAAE,GAAG,UAAU,IAAI,cAAc,EAAE;QAC3C,OAAO,EAAE,CAAC,UAAU;QACpB,QAAQ,EAAE,WAAW;KACxB,CAAC;AACN,CAAC"}