clitrigger 0.1.11 → 0.1.12

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 (101) hide show
  1. package/README.md +24 -21
  2. package/README_KR.md +25 -22
  3. package/dist/client/assets/index-CcsvxPmx.css +1 -0
  4. package/dist/client/assets/index-qSpSlrcM.js +606 -0
  5. package/dist/client/index.html +2 -2
  6. package/dist/server/data/cli-models-registry.json +12 -1
  7. package/dist/server/db/queries.d.ts +46 -5
  8. package/dist/server/db/queries.d.ts.map +1 -1
  9. package/dist/server/db/queries.js +138 -9
  10. package/dist/server/db/queries.js.map +1 -1
  11. package/dist/server/db/schema.d.ts.map +1 -1
  12. package/dist/server/db/schema.js +35 -0
  13. package/dist/server/db/schema.js.map +1 -1
  14. package/dist/server/index.d.ts.map +1 -1
  15. package/dist/server/index.js +4 -0
  16. package/dist/server/index.js.map +1 -1
  17. package/dist/server/lib/git.d.ts +1 -0
  18. package/dist/server/lib/git.d.ts.map +1 -1
  19. package/dist/server/lib/git.js +11 -0
  20. package/dist/server/lib/git.js.map +1 -1
  21. package/dist/server/plugins/harness/adapters/claude.d.ts +3 -0
  22. package/dist/server/plugins/harness/adapters/claude.d.ts.map +1 -0
  23. package/dist/server/plugins/harness/adapters/claude.js +98 -0
  24. package/dist/server/plugins/harness/adapters/claude.js.map +1 -0
  25. package/dist/server/plugins/harness/adapters/codex.d.ts +3 -0
  26. package/dist/server/plugins/harness/adapters/codex.d.ts.map +1 -0
  27. package/dist/server/plugins/harness/adapters/codex.js +136 -0
  28. package/dist/server/plugins/harness/adapters/codex.js.map +1 -0
  29. package/dist/server/plugins/harness/adapters/gemini.d.ts +3 -0
  30. package/dist/server/plugins/harness/adapters/gemini.d.ts.map +1 -0
  31. package/dist/server/plugins/harness/adapters/gemini.js +118 -0
  32. package/dist/server/plugins/harness/adapters/gemini.js.map +1 -0
  33. package/dist/server/plugins/harness/index.d.ts +3 -0
  34. package/dist/server/plugins/harness/index.d.ts.map +1 -0
  35. package/dist/server/plugins/harness/index.js +13 -0
  36. package/dist/server/plugins/harness/index.js.map +1 -0
  37. package/dist/server/plugins/harness/io.d.ts +12 -0
  38. package/dist/server/plugins/harness/io.d.ts.map +1 -0
  39. package/dist/server/plugins/harness/io.js +94 -0
  40. package/dist/server/plugins/harness/io.js.map +1 -0
  41. package/dist/server/plugins/harness/router.d.ts +4 -0
  42. package/dist/server/plugins/harness/router.d.ts.map +1 -0
  43. package/dist/server/plugins/harness/router.js +206 -0
  44. package/dist/server/plugins/harness/router.js.map +1 -0
  45. package/dist/server/plugins/harness/types.d.ts +40 -0
  46. package/dist/server/plugins/harness/types.d.ts.map +1 -0
  47. package/dist/server/plugins/harness/types.js +2 -0
  48. package/dist/server/plugins/harness/types.js.map +1 -0
  49. package/dist/server/routes/discussions.d.ts.map +1 -1
  50. package/dist/server/routes/discussions.js +116 -6
  51. package/dist/server/routes/discussions.js.map +1 -1
  52. package/dist/server/routes/logs.d.ts.map +1 -1
  53. package/dist/server/routes/logs.js +16 -5
  54. package/dist/server/routes/logs.js.map +1 -1
  55. package/dist/server/routes/memory.d.ts +3 -0
  56. package/dist/server/routes/memory.d.ts.map +1 -0
  57. package/dist/server/routes/memory.js +259 -0
  58. package/dist/server/routes/memory.js.map +1 -0
  59. package/dist/server/routes/projects.d.ts.map +1 -1
  60. package/dist/server/routes/projects.js +11 -2
  61. package/dist/server/routes/projects.js.map +1 -1
  62. package/dist/server/routes/review.d.ts.map +1 -1
  63. package/dist/server/routes/review.js +152 -1
  64. package/dist/server/routes/review.js.map +1 -1
  65. package/dist/server/routes/todos.d.ts.map +1 -1
  66. package/dist/server/routes/todos.js +17 -3
  67. package/dist/server/routes/todos.js.map +1 -1
  68. package/dist/server/services/discussion-extractor.d.ts +7 -0
  69. package/dist/server/services/discussion-extractor.d.ts.map +1 -0
  70. package/dist/server/services/discussion-extractor.js +167 -0
  71. package/dist/server/services/discussion-extractor.js.map +1 -0
  72. package/dist/server/services/discussion-orchestrator.d.ts.map +1 -1
  73. package/dist/server/services/discussion-orchestrator.js +16 -1
  74. package/dist/server/services/discussion-orchestrator.js.map +1 -1
  75. package/dist/server/services/log-streamer.d.ts +20 -0
  76. package/dist/server/services/log-streamer.d.ts.map +1 -1
  77. package/dist/server/services/log-streamer.js +81 -3
  78. package/dist/server/services/log-streamer.js.map +1 -1
  79. package/dist/server/services/memory-inject-hook.d.ts +9 -0
  80. package/dist/server/services/memory-inject-hook.d.ts.map +1 -0
  81. package/dist/server/services/memory-inject-hook.js +17 -0
  82. package/dist/server/services/memory-inject-hook.js.map +1 -0
  83. package/dist/server/services/memory-injector.d.ts +15 -0
  84. package/dist/server/services/memory-injector.d.ts.map +1 -0
  85. package/dist/server/services/memory-injector.js +77 -0
  86. package/dist/server/services/memory-injector.js.map +1 -0
  87. package/dist/server/services/model-sync.js +1 -1
  88. package/dist/server/services/orchestrator.d.ts.map +1 -1
  89. package/dist/server/services/orchestrator.js +27 -0
  90. package/dist/server/services/orchestrator.js.map +1 -1
  91. package/dist/server/services/pty-output-filter.d.ts +12 -0
  92. package/dist/server/services/pty-output-filter.d.ts.map +1 -1
  93. package/dist/server/services/pty-output-filter.js +94 -1
  94. package/dist/server/services/pty-output-filter.js.map +1 -1
  95. package/dist/server/services/review-capture.d.ts +5 -3
  96. package/dist/server/services/review-capture.d.ts.map +1 -1
  97. package/dist/server/services/review-capture.js +29 -7
  98. package/dist/server/services/review-capture.js.map +1 -1
  99. package/package.json +3 -1
  100. package/dist/client/assets/index-D4Xur2yY.css +0 -1
  101. package/dist/client/assets/index-Dz1uDy_d.js +0 -567
@@ -0,0 +1,136 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import TOML from '@iarna/toml';
4
+ import { safeJoin, exists, readTextOrEmpty, atomicWriteText, deepMerge, pruneUndefined, } from '../io.js';
5
+ function configPath(projectPath) {
6
+ return safeJoin(projectPath, '.codex', 'config.toml');
7
+ }
8
+ function memoryPath(projectPath) {
9
+ return safeJoin(projectPath, 'AGENTS.md');
10
+ }
11
+ async function readConfig(filePath) {
12
+ const text = await readTextOrEmpty(filePath);
13
+ if (!text.trim())
14
+ return {};
15
+ try {
16
+ return TOML.parse(text);
17
+ }
18
+ catch {
19
+ return {};
20
+ }
21
+ }
22
+ async function writeConfig(filePath, obj) {
23
+ const cleaned = pruneUndefined(obj);
24
+ const text = TOML.stringify(cleaned);
25
+ await atomicWriteText(filePath, text);
26
+ }
27
+ function fromMcpEntry(alias, entry) {
28
+ const transport = entry.url ? 'http' : 'stdio';
29
+ return {
30
+ alias,
31
+ transport,
32
+ command: entry.command,
33
+ args: entry.args,
34
+ env: entry.env,
35
+ url: entry.url,
36
+ headers: entry.http_headers,
37
+ enabled: entry.enabled,
38
+ };
39
+ }
40
+ function toMcpEntry(server) {
41
+ if (server.transport === 'stdio') {
42
+ return pruneUndefined({
43
+ command: server.command,
44
+ args: server.args,
45
+ env: server.env,
46
+ enabled: server.enabled,
47
+ });
48
+ }
49
+ return pruneUndefined({
50
+ url: server.url,
51
+ http_headers: server.headers,
52
+ enabled: server.enabled,
53
+ });
54
+ }
55
+ function settingsToView(raw) {
56
+ const approval = typeof raw.approval_policy === 'string' ? raw.approval_policy : undefined;
57
+ return {
58
+ model: raw.model,
59
+ approvalMode: approval,
60
+ sandbox: raw.sandbox_mode,
61
+ };
62
+ }
63
+ async function trustLevelWarning(projectPath) {
64
+ const home = process.env.USERPROFILE || process.env.HOME;
65
+ if (!home)
66
+ return [];
67
+ const userConfig = path.join(home, '.codex', 'config.toml');
68
+ try {
69
+ const text = await fs.readFile(userConfig, 'utf8');
70
+ const parsed = TOML.parse(text);
71
+ const abs = path.resolve(projectPath);
72
+ const entry = parsed.projects?.[abs];
73
+ if (entry?.trust_level === 'trusted')
74
+ return [];
75
+ }
76
+ catch {
77
+ // file missing or unparseable
78
+ }
79
+ return ['codex.trustLevelMissing'];
80
+ }
81
+ export const codexHarnessAdapter = {
82
+ cli: 'codex',
83
+ async read(projectPath) {
84
+ const cp = configPath(projectPath);
85
+ const memp = memoryPath(projectPath);
86
+ const raw = await readConfig(cp);
87
+ const memory = await readTextOrEmpty(memp);
88
+ const configExists = await exists(cp);
89
+ const memoryExists = await exists(memp);
90
+ const mcp = Object.entries(raw.mcp_servers ?? {}).map(([alias, entry]) => fromMcpEntry(alias, entry));
91
+ const warnings = await trustLevelWarning(projectPath);
92
+ const snapshot = {
93
+ cli: 'codex',
94
+ exists: configExists || memoryExists,
95
+ filePaths: { settings: cp, memory: memp },
96
+ settings: settingsToView(raw),
97
+ memory,
98
+ mcp,
99
+ warnings,
100
+ };
101
+ return snapshot;
102
+ },
103
+ async writeSettings(projectPath, patch) {
104
+ const cp = configPath(projectPath);
105
+ const existing = await readConfig(cp);
106
+ const update = {};
107
+ if (patch.model !== undefined)
108
+ update.model = patch.model;
109
+ if (patch.approvalMode !== undefined)
110
+ update.approval_policy = patch.approvalMode;
111
+ if (patch.sandbox !== undefined)
112
+ update.sandbox_mode = patch.sandbox;
113
+ const merged = deepMerge(existing, update);
114
+ await writeConfig(cp, merged);
115
+ },
116
+ async writeMemory(projectPath, content) {
117
+ await atomicWriteText(memoryPath(projectPath), content);
118
+ },
119
+ async upsertMcp(projectPath, server) {
120
+ const cp = configPath(projectPath);
121
+ const existing = await readConfig(cp);
122
+ const servers = { ...(existing.mcp_servers ?? {}) };
123
+ servers[server.alias] = toMcpEntry(server);
124
+ await writeConfig(cp, { ...existing, mcp_servers: servers });
125
+ },
126
+ async removeMcp(projectPath, alias) {
127
+ const cp = configPath(projectPath);
128
+ const existing = await readConfig(cp);
129
+ if (!existing.mcp_servers?.[alias])
130
+ return;
131
+ const servers = { ...existing.mcp_servers };
132
+ delete servers[alias];
133
+ await writeConfig(cp, { ...existing, mcp_servers: servers });
134
+ },
135
+ };
136
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../../../src/server/plugins/harness/adapters/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { HarnessAdapter } from '../types.js';
2
+ export declare const geminiHarnessAdapter: HarnessAdapter;
3
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../../../src/server/plugins/harness/adapters/gemini.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAA+C,MAAM,aAAa,CAAC;AAmF/F,eAAO,MAAM,oBAAoB,EAAE,cAiElC,CAAC"}
@@ -0,0 +1,118 @@
1
+ import { safeJoin, exists, readJsonOrEmpty, readTextOrEmpty, atomicWriteJson, atomicWriteText, deepMerge, pruneUndefined, } from '../io.js';
2
+ function settingsPath(projectPath) {
3
+ return safeJoin(projectPath, '.gemini', 'settings.json');
4
+ }
5
+ function memoryPath(projectPath) {
6
+ return safeJoin(projectPath, 'GEMINI.md');
7
+ }
8
+ function fromMcpEntry(alias, entry) {
9
+ const transport = entry.httpUrl
10
+ ? 'http'
11
+ : entry.url
12
+ ? 'sse'
13
+ : 'stdio';
14
+ return {
15
+ alias,
16
+ transport,
17
+ command: entry.command,
18
+ args: entry.args,
19
+ env: entry.env,
20
+ url: entry.httpUrl ?? entry.url,
21
+ headers: entry.headers,
22
+ enabled: entry.enabled,
23
+ };
24
+ }
25
+ function toMcpEntry(server) {
26
+ if (server.transport === 'stdio') {
27
+ return pruneUndefined({
28
+ command: server.command,
29
+ args: server.args,
30
+ env: server.env,
31
+ enabled: server.enabled,
32
+ });
33
+ }
34
+ if (server.transport === 'http') {
35
+ return pruneUndefined({
36
+ httpUrl: server.url,
37
+ headers: server.headers,
38
+ enabled: server.enabled,
39
+ });
40
+ }
41
+ // sse
42
+ return pruneUndefined({
43
+ url: server.url,
44
+ headers: server.headers,
45
+ enabled: server.enabled,
46
+ });
47
+ }
48
+ function settingsToView(raw) {
49
+ let sandbox;
50
+ const s = raw.tools?.sandbox;
51
+ if (typeof s === 'string')
52
+ sandbox = s;
53
+ else if (typeof s === 'boolean')
54
+ sandbox = s ? 'true' : 'false';
55
+ return {
56
+ model: raw.model?.name,
57
+ approvalMode: raw.general?.defaultApprovalMode,
58
+ sandbox,
59
+ };
60
+ }
61
+ export const geminiHarnessAdapter = {
62
+ cli: 'gemini',
63
+ async read(projectPath) {
64
+ const sp = settingsPath(projectPath);
65
+ const memp = memoryPath(projectPath);
66
+ const raw = await readJsonOrEmpty(sp);
67
+ const memory = await readTextOrEmpty(memp);
68
+ const settingsExists = await exists(sp);
69
+ const memoryExists = await exists(memp);
70
+ const mcp = Object.entries(raw.mcpServers ?? {}).map(([alias, entry]) => fromMcpEntry(alias, entry));
71
+ return {
72
+ cli: 'gemini',
73
+ exists: settingsExists || memoryExists,
74
+ filePaths: { settings: sp, memory: memp },
75
+ settings: settingsToView(raw),
76
+ memory,
77
+ mcp,
78
+ warnings: [],
79
+ };
80
+ },
81
+ async writeSettings(projectPath, patch) {
82
+ const sp = settingsPath(projectPath);
83
+ const existing = await readJsonOrEmpty(sp);
84
+ const update = {};
85
+ if (patch.model !== undefined)
86
+ update.model = { ...(existing.model ?? {}), name: patch.model };
87
+ if (patch.approvalMode !== undefined) {
88
+ update.general = { ...(existing.general ?? {}), defaultApprovalMode: patch.approvalMode };
89
+ }
90
+ if (patch.sandbox !== undefined) {
91
+ update.tools = { ...(existing.tools ?? {}), sandbox: patch.sandbox };
92
+ }
93
+ const merged = deepMerge(existing, update);
94
+ await atomicWriteJson(sp, merged);
95
+ },
96
+ async writeMemory(projectPath, content) {
97
+ await atomicWriteText(memoryPath(projectPath), content);
98
+ },
99
+ async upsertMcp(projectPath, server) {
100
+ const sp = settingsPath(projectPath);
101
+ const existing = await readJsonOrEmpty(sp);
102
+ const servers = { ...(existing.mcpServers ?? {}) };
103
+ servers[server.alias] = toMcpEntry(server);
104
+ const next = { ...existing, mcpServers: servers };
105
+ await atomicWriteJson(sp, next);
106
+ },
107
+ async removeMcp(projectPath, alias) {
108
+ const sp = settingsPath(projectPath);
109
+ const existing = await readJsonOrEmpty(sp);
110
+ if (!existing.mcpServers?.[alias])
111
+ return;
112
+ const servers = { ...existing.mcpServers };
113
+ delete servers[alias];
114
+ const next = { ...existing, mcpServers: servers };
115
+ await atomicWriteJson(sp, next);
116
+ },
117
+ };
118
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../../../src/server/plugins/harness/adapters/gemini.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { PluginManifest } from '../types.js';
2
+ export declare const harnessPlugin: PluginManifest;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/plugins/harness/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,eAAO,MAAM,aAAa,EAAE,cAU3B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { createRouter } from './router.js';
2
+ export const harnessPlugin = {
3
+ id: 'harness',
4
+ version: '1.0.0',
5
+ displayName: 'Harness',
6
+ displayNameKo: '하네스',
7
+ category: 'external-service',
8
+ hasPanel: true,
9
+ routePrefix: '/api/harness',
10
+ configFields: [],
11
+ createRouter,
12
+ };
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/plugins/harness/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,CAAC,MAAM,aAAa,GAAmB;IAC3C,EAAE,EAAE,SAAS;IACb,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,KAAK;IACpB,QAAQ,EAAE,kBAAkB;IAC5B,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,cAAc;IAC3B,YAAY,EAAE,EAAE;IAChB,YAAY;CACb,CAAC"}
@@ -0,0 +1,12 @@
1
+ export declare class HarnessPathError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare function safeJoin(projectPath: string, ...segments: string[]): string;
5
+ export declare function exists(filePath: string): Promise<boolean>;
6
+ export declare function readTextOrEmpty(filePath: string): Promise<string>;
7
+ export declare function readJsonOrEmpty<T extends object>(filePath: string): Promise<T>;
8
+ export declare function atomicWriteText(filePath: string, content: string): Promise<void>;
9
+ export declare function atomicWriteJson(filePath: string, obj: unknown): Promise<void>;
10
+ export declare function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T;
11
+ export declare function pruneUndefined<T extends Record<string, unknown>>(obj: T): T;
12
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../../../src/server/plugins/harness/io.ts"],"names":[],"mappings":"AAGA,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAS3E;AAED,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOvE;AAED,wBAAsB,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAQpF;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKtF;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnF;AAMD,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAY7F;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAY3E"}
@@ -0,0 +1,94 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ export class HarnessPathError extends Error {
4
+ constructor(message) {
5
+ super(message);
6
+ this.name = 'HarnessPathError';
7
+ }
8
+ }
9
+ export function safeJoin(projectPath, ...segments) {
10
+ if (!projectPath)
11
+ throw new HarnessPathError('projectPath is required');
12
+ const root = path.resolve(projectPath);
13
+ const target = path.resolve(root, ...segments);
14
+ const rootWithSep = root.endsWith(path.sep) ? root : root + path.sep;
15
+ if (target !== root && !target.startsWith(rootWithSep)) {
16
+ throw new HarnessPathError(`Path "${target}" escapes project root "${root}"`);
17
+ }
18
+ return target;
19
+ }
20
+ export async function exists(filePath) {
21
+ try {
22
+ await fs.stat(filePath);
23
+ return true;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ export async function readTextOrEmpty(filePath) {
30
+ try {
31
+ return await fs.readFile(filePath, 'utf8');
32
+ }
33
+ catch (err) {
34
+ if (err?.code === 'ENOENT')
35
+ return '';
36
+ throw err;
37
+ }
38
+ }
39
+ export async function readJsonOrEmpty(filePath) {
40
+ const text = await readTextOrEmpty(filePath);
41
+ if (!text.trim())
42
+ return {};
43
+ try {
44
+ return JSON.parse(text);
45
+ }
46
+ catch {
47
+ return {};
48
+ }
49
+ }
50
+ export async function atomicWriteText(filePath, content) {
51
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
52
+ const tmp = `${filePath}.${process.pid}.${Date.now()}.tmp`;
53
+ await fs.writeFile(tmp, content, 'utf8');
54
+ await fs.rename(tmp, filePath);
55
+ }
56
+ export async function atomicWriteJson(filePath, obj) {
57
+ const text = JSON.stringify(obj, null, 2) + '\n';
58
+ await atomicWriteText(filePath, text);
59
+ }
60
+ function isPlainObject(value) {
61
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
62
+ }
63
+ export function deepMerge(target, source) {
64
+ const out = { ...target };
65
+ for (const [key, value] of Object.entries(source)) {
66
+ if (value === undefined)
67
+ continue;
68
+ const existing = out[key];
69
+ if (isPlainObject(existing) && isPlainObject(value)) {
70
+ out[key] = deepMerge(existing, value);
71
+ }
72
+ else {
73
+ out[key] = value;
74
+ }
75
+ }
76
+ return out;
77
+ }
78
+ export function pruneUndefined(obj) {
79
+ const out = {};
80
+ for (const [key, value] of Object.entries(obj)) {
81
+ if (value === undefined)
82
+ continue;
83
+ if (isPlainObject(value)) {
84
+ const pruned = pruneUndefined(value);
85
+ if (Object.keys(pruned).length > 0)
86
+ out[key] = pruned;
87
+ }
88
+ else {
89
+ out[key] = value;
90
+ }
91
+ }
92
+ return out;
93
+ }
94
+ //# sourceMappingURL=io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../../../../src/server/plugins/harness/io.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { Router } from 'express';
2
+ import type { PluginHelpers } from '../types.js';
3
+ export declare function createRouter(_helpers: PluginHelpers): Router;
4
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../../src/server/plugins/harness/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA0CjD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAwK5D"}
@@ -0,0 +1,206 @@
1
+ import { Router } from 'express';
2
+ import { getProjectById } from '../../db/queries.js';
3
+ import { claudeHarnessAdapter } from './adapters/claude.js';
4
+ import { geminiHarnessAdapter } from './adapters/gemini.js';
5
+ import { codexHarnessAdapter } from './adapters/codex.js';
6
+ import { HarnessPathError } from './io.js';
7
+ const adapters = {
8
+ claude: claudeHarnessAdapter,
9
+ gemini: geminiHarnessAdapter,
10
+ codex: codexHarnessAdapter,
11
+ };
12
+ const CLI_IDS = ['claude', 'gemini', 'codex'];
13
+ function resolveProjectPath(projectId) {
14
+ const project = getProjectById(projectId);
15
+ if (!project)
16
+ return null;
17
+ return project.path;
18
+ }
19
+ function isCliId(value) {
20
+ return value === 'claude' || value === 'gemini' || value === 'codex';
21
+ }
22
+ function handleError(res, err) {
23
+ if (err instanceof HarnessPathError) {
24
+ res.status(400).json({ error: err.message });
25
+ return;
26
+ }
27
+ const message = err instanceof Error ? err.message : String(err);
28
+ res.status(500).json({ error: message });
29
+ }
30
+ function isMcpServer(value) {
31
+ if (typeof value !== 'object' || value === null)
32
+ return false;
33
+ const v = value;
34
+ if (typeof v.alias !== 'string' || !v.alias)
35
+ return false;
36
+ if (v.transport !== 'stdio' && v.transport !== 'http' && v.transport !== 'sse')
37
+ return false;
38
+ return true;
39
+ }
40
+ export function createRouter(_helpers) {
41
+ const router = Router();
42
+ router.get('/:projectId', async (req, res) => {
43
+ const projectPath = resolveProjectPath(req.params.projectId);
44
+ if (!projectPath) {
45
+ res.status(404).json({ error: 'Project not found' });
46
+ return;
47
+ }
48
+ try {
49
+ const entries = await Promise.all(CLI_IDS.map(async (cli) => [cli, await adapters[cli].read(projectPath)]));
50
+ res.json(Object.fromEntries(entries));
51
+ }
52
+ catch (err) {
53
+ handleError(res, err);
54
+ }
55
+ });
56
+ router.get('/:projectId/:cli', async (req, res) => {
57
+ const projectPath = resolveProjectPath(req.params.projectId);
58
+ if (!projectPath) {
59
+ res.status(404).json({ error: 'Project not found' });
60
+ return;
61
+ }
62
+ if (!isCliId(req.params.cli)) {
63
+ res.status(400).json({ error: 'Invalid cli identifier' });
64
+ return;
65
+ }
66
+ try {
67
+ const snapshot = await adapters[req.params.cli].read(projectPath);
68
+ res.json(snapshot);
69
+ }
70
+ catch (err) {
71
+ handleError(res, err);
72
+ }
73
+ });
74
+ router.put('/:projectId/:cli/settings', async (req, res) => {
75
+ const projectPath = resolveProjectPath(req.params.projectId);
76
+ if (!projectPath) {
77
+ res.status(404).json({ error: 'Project not found' });
78
+ return;
79
+ }
80
+ if (!isCliId(req.params.cli)) {
81
+ res.status(400).json({ error: 'Invalid cli identifier' });
82
+ return;
83
+ }
84
+ const body = req.body;
85
+ if (!body || typeof body !== 'object') {
86
+ res.status(400).json({ error: 'Body must be a JSON object' });
87
+ return;
88
+ }
89
+ try {
90
+ await adapters[req.params.cli].writeSettings(projectPath, body);
91
+ const snapshot = await adapters[req.params.cli].read(projectPath);
92
+ res.json(snapshot);
93
+ }
94
+ catch (err) {
95
+ handleError(res, err);
96
+ }
97
+ });
98
+ router.get('/:projectId/:cli/memory', async (req, res) => {
99
+ const projectPath = resolveProjectPath(req.params.projectId);
100
+ if (!projectPath) {
101
+ res.status(404).json({ error: 'Project not found' });
102
+ return;
103
+ }
104
+ if (!isCliId(req.params.cli)) {
105
+ res.status(400).json({ error: 'Invalid cli identifier' });
106
+ return;
107
+ }
108
+ try {
109
+ const snapshot = await adapters[req.params.cli].read(projectPath);
110
+ res.json({
111
+ path: snapshot.filePaths.memory,
112
+ content: snapshot.memory,
113
+ exists: !!snapshot.memory,
114
+ });
115
+ }
116
+ catch (err) {
117
+ handleError(res, err);
118
+ }
119
+ });
120
+ router.put('/:projectId/:cli/memory', async (req, res) => {
121
+ const projectPath = resolveProjectPath(req.params.projectId);
122
+ if (!projectPath) {
123
+ res.status(404).json({ error: 'Project not found' });
124
+ return;
125
+ }
126
+ if (!isCliId(req.params.cli)) {
127
+ res.status(400).json({ error: 'Invalid cli identifier' });
128
+ return;
129
+ }
130
+ const body = req.body;
131
+ if (!body || typeof body.content !== 'string') {
132
+ res.status(400).json({ error: 'Body must include string "content"' });
133
+ return;
134
+ }
135
+ try {
136
+ await adapters[req.params.cli].writeMemory(projectPath, body.content);
137
+ res.json({ ok: true });
138
+ }
139
+ catch (err) {
140
+ handleError(res, err);
141
+ }
142
+ });
143
+ router.get('/:projectId/:cli/mcp', async (req, res) => {
144
+ const projectPath = resolveProjectPath(req.params.projectId);
145
+ if (!projectPath) {
146
+ res.status(404).json({ error: 'Project not found' });
147
+ return;
148
+ }
149
+ if (!isCliId(req.params.cli)) {
150
+ res.status(400).json({ error: 'Invalid cli identifier' });
151
+ return;
152
+ }
153
+ try {
154
+ const snapshot = await adapters[req.params.cli].read(projectPath);
155
+ res.json(snapshot.mcp);
156
+ }
157
+ catch (err) {
158
+ handleError(res, err);
159
+ }
160
+ });
161
+ router.put('/:projectId/:cli/mcp/:alias', async (req, res) => {
162
+ const projectPath = resolveProjectPath(req.params.projectId);
163
+ if (!projectPath) {
164
+ res.status(404).json({ error: 'Project not found' });
165
+ return;
166
+ }
167
+ if (!isCliId(req.params.cli)) {
168
+ res.status(400).json({ error: 'Invalid cli identifier' });
169
+ return;
170
+ }
171
+ const body = { ...(req.body ?? {}), alias: req.params.alias };
172
+ if (!isMcpServer(body)) {
173
+ res.status(400).json({ error: 'Body is not a valid McpServer' });
174
+ return;
175
+ }
176
+ try {
177
+ await adapters[req.params.cli].upsertMcp(projectPath, body);
178
+ const snapshot = await adapters[req.params.cli].read(projectPath);
179
+ res.json(snapshot.mcp);
180
+ }
181
+ catch (err) {
182
+ handleError(res, err);
183
+ }
184
+ });
185
+ router.delete('/:projectId/:cli/mcp/:alias', async (req, res) => {
186
+ const projectPath = resolveProjectPath(req.params.projectId);
187
+ if (!projectPath) {
188
+ res.status(404).json({ error: 'Project not found' });
189
+ return;
190
+ }
191
+ if (!isCliId(req.params.cli)) {
192
+ res.status(400).json({ error: 'Invalid cli identifier' });
193
+ return;
194
+ }
195
+ try {
196
+ await adapters[req.params.cli].removeMcp(projectPath, req.params.alias);
197
+ const snapshot = await adapters[req.params.cli].read(projectPath);
198
+ res.json(snapshot.mcp);
199
+ }
200
+ catch (err) {
201
+ handleError(res, err);
202
+ }
203
+ });
204
+ return router;
205
+ }
206
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/server/plugins/harness/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA+B,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,MAAM,QAAQ,GAAkC;IAC9C,MAAM,EAAE,oBAAoB;IAC5B,MAAM,EAAE,oBAAoB;IAC5B,KAAK,EAAE,mBAAmB;CAC3B,CAAC;AAEF,MAAM,OAAO,GAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAEvD,SAAS,kBAAkB,CAAC,SAAiB;IAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC;AACvE,CAAC;AAED,SAAS,WAAW,CAAC,GAAa,EAAE,GAAY;IAC9C,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;QACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,CAAC,CAAC,SAAS,KAAK,OAAO,IAAI,CAAC,CAAC,SAAS,KAAK,MAAM,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC7F,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAuB;IAClD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,GAAmC,EAAE,GAAa,EAAE,EAAE;QACrF,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAU,CAAC,CAClF,CAAC;YACF,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,EAAE,GAAgD,EAAE,GAAa,EAAE,EAAE;QACvG,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,KAAK,EAAE,GAAgD,EAAE,GAAa,EAAE,EAAE;QAChH,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,IAA4C,CAAC;QAC9D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YAChE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,GAAgD,EAAE,GAAa,EAAE,EAAE;QAC9G,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM;gBAC/B,OAAO,EAAE,QAAQ,CAAC,MAAM;gBACxB,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,GAAgD,EAAE,GAAa,EAAE,EAAE;QAC9G,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAyC,CAAC;QAC3D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC9C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACtE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,EAAE,GAAgD,EAAE,GAAa,EAAE,EAAE;QAC3G,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,6BAA6B,EAAE,KAAK,EAAE,GAA+D,EAAE,GAAa,EAAE,EAAE;QACjI,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CAAC,6BAA6B,EAAE,KAAK,EAAE,GAA+D,EAAE,GAAa,EAAE,EAAE;QACpI,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}