@nio-cli/cli 0.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 (196) hide show
  1. package/README.md +280 -0
  2. package/dist/adapters/supabase/allocation-gateway.js +236 -0
  3. package/dist/adapters/supabase/allocation-gateway.js.map +1 -0
  4. package/dist/adapters/supabase/analytics-gateway.js +18 -0
  5. package/dist/adapters/supabase/analytics-gateway.js.map +1 -0
  6. package/dist/adapters/supabase/client.js +96 -0
  7. package/dist/adapters/supabase/client.js.map +1 -0
  8. package/dist/adapters/supabase/context-gateway.js +23 -0
  9. package/dist/adapters/supabase/context-gateway.js.map +1 -0
  10. package/dist/adapters/supabase/gateway.js +18 -0
  11. package/dist/adapters/supabase/gateway.js.map +1 -0
  12. package/dist/adapters/supabase/task-gateway.js +450 -0
  13. package/dist/adapters/supabase/task-gateway.js.map +1 -0
  14. package/dist/auth.js +118 -0
  15. package/dist/auth.js.map +1 -0
  16. package/dist/brand.js +91 -0
  17. package/dist/brand.js.map +1 -0
  18. package/dist/cli/commands/auth.js +128 -0
  19. package/dist/cli/commands/auth.js.map +1 -0
  20. package/dist/cli/commands/clean.js +120 -0
  21. package/dist/cli/commands/clean.js.map +1 -0
  22. package/dist/cli/commands/completion.js +114 -0
  23. package/dist/cli/commands/completion.js.map +1 -0
  24. package/dist/cli/commands/exec.js +59 -0
  25. package/dist/cli/commands/exec.js.map +1 -0
  26. package/dist/cli/commands/init/auth-step.js +49 -0
  27. package/dist/cli/commands/init/auth-step.js.map +1 -0
  28. package/dist/cli/commands/init/clients-step.js +76 -0
  29. package/dist/cli/commands/init/clients-step.js.map +1 -0
  30. package/dist/cli/commands/init/context-step.js +71 -0
  31. package/dist/cli/commands/init/context-step.js.map +1 -0
  32. package/dist/cli/commands/init/index.js +76 -0
  33. package/dist/cli/commands/init/index.js.map +1 -0
  34. package/dist/cli/commands/init/project-step.js +105 -0
  35. package/dist/cli/commands/init/project-step.js.map +1 -0
  36. package/dist/cli/commands/init/provision-step.js +103 -0
  37. package/dist/cli/commands/init/provision-step.js.map +1 -0
  38. package/dist/cli/commands/plan.js +45 -0
  39. package/dist/cli/commands/plan.js.map +1 -0
  40. package/dist/cli/commands/skills.js +23 -0
  41. package/dist/cli/commands/skills.js.map +1 -0
  42. package/dist/cli/commands/sync.js +296 -0
  43. package/dist/cli/commands/sync.js.map +1 -0
  44. package/dist/cli/commands/validate-plan.js +42 -0
  45. package/dist/cli/commands/validate-plan.js.map +1 -0
  46. package/dist/cli/copy/auth.json +6 -0
  47. package/dist/cli/copy/flows.json +6 -0
  48. package/dist/cli/copy/init.json +19 -0
  49. package/dist/cli/copy/sync.json +3 -0
  50. package/dist/cli/copy.js +23 -0
  51. package/dist/cli/copy.js.map +1 -0
  52. package/dist/cli/flows/clients.js +130 -0
  53. package/dist/cli/flows/clients.js.map +1 -0
  54. package/dist/cli/flows/completion.js +63 -0
  55. package/dist/cli/flows/completion.js.map +1 -0
  56. package/dist/cli/flows/dependencies.js +114 -0
  57. package/dist/cli/flows/dependencies.js.map +1 -0
  58. package/dist/cli/flows/sections.js +85 -0
  59. package/dist/cli/flows/sections.js.map +1 -0
  60. package/dist/cli/flows/user-config.js +37 -0
  61. package/dist/cli/flows/user-config.js.map +1 -0
  62. package/dist/cli/ui/render.js +237 -0
  63. package/dist/cli/ui/render.js.map +1 -0
  64. package/dist/cli/ui/report.js +117 -0
  65. package/dist/cli/ui/report.js.map +1 -0
  66. package/dist/cli.js +36 -0
  67. package/dist/cli.js.map +1 -0
  68. package/dist/config.js +280 -0
  69. package/dist/config.js.map +1 -0
  70. package/dist/constants.js +9 -0
  71. package/dist/constants.js.map +1 -0
  72. package/dist/core/ports.js +2 -0
  73. package/dist/core/ports.js.map +1 -0
  74. package/dist/core/types.js +7 -0
  75. package/dist/core/types.js.map +1 -0
  76. package/dist/database.types.js +11 -0
  77. package/dist/database.types.js.map +1 -0
  78. package/dist/lib/active-project.js +28 -0
  79. package/dist/lib/active-project.js.map +1 -0
  80. package/dist/lib/autopull.js +13 -0
  81. package/dist/lib/autopull.js.map +1 -0
  82. package/dist/lib/client-configs.js +191 -0
  83. package/dist/lib/client-configs.js.map +1 -0
  84. package/dist/lib/client-install.js +40 -0
  85. package/dist/lib/client-install.js.map +1 -0
  86. package/dist/lib/colors.js +93 -0
  87. package/dist/lib/colors.js.map +1 -0
  88. package/dist/lib/cowork-extension.js +143 -0
  89. package/dist/lib/cowork-extension.js.map +1 -0
  90. package/dist/lib/dependencies.js +145 -0
  91. package/dist/lib/dependencies.js.map +1 -0
  92. package/dist/lib/dependency-install.js +163 -0
  93. package/dist/lib/dependency-install.js.map +1 -0
  94. package/dist/lib/duration.js +5 -0
  95. package/dist/lib/duration.js.map +1 -0
  96. package/dist/lib/exec-delegate.js +167 -0
  97. package/dist/lib/exec-delegate.js.map +1 -0
  98. package/dist/lib/exec-engines.js +72 -0
  99. package/dist/lib/exec-engines.js.map +1 -0
  100. package/dist/lib/file-merge.js +33 -0
  101. package/dist/lib/file-merge.js.map +1 -0
  102. package/dist/lib/harness.js +90 -0
  103. package/dist/lib/harness.js.map +1 -0
  104. package/dist/lib/hooks.js +217 -0
  105. package/dist/lib/hooks.js.map +1 -0
  106. package/dist/lib/patterns.js +61 -0
  107. package/dist/lib/patterns.js.map +1 -0
  108. package/dist/lib/plan-delegate.js +106 -0
  109. package/dist/lib/plan-delegate.js.map +1 -0
  110. package/dist/lib/project-context.js +151 -0
  111. package/dist/lib/project-context.js.map +1 -0
  112. package/dist/lib/prompts.js +69 -0
  113. package/dist/lib/prompts.js.map +1 -0
  114. package/dist/lib/provision-apply.js +220 -0
  115. package/dist/lib/provision-apply.js.map +1 -0
  116. package/dist/lib/provision-collect.js +47 -0
  117. package/dist/lib/provision-collect.js.map +1 -0
  118. package/dist/lib/provision.js +45 -0
  119. package/dist/lib/provision.js.map +1 -0
  120. package/dist/lib/require-config.js +32 -0
  121. package/dist/lib/require-config.js.map +1 -0
  122. package/dist/lib/rules.js +99 -0
  123. package/dist/lib/rules.js.map +1 -0
  124. package/dist/lib/sections.js +89 -0
  125. package/dist/lib/sections.js.map +1 -0
  126. package/dist/lib/skill-serve.js +129 -0
  127. package/dist/lib/skill-serve.js.map +1 -0
  128. package/dist/lib/skills-cache.js +99 -0
  129. package/dist/lib/skills-cache.js.map +1 -0
  130. package/dist/lib/skills.js +236 -0
  131. package/dist/lib/skills.js.map +1 -0
  132. package/dist/lib/targets.js +151 -0
  133. package/dist/lib/targets.js.map +1 -0
  134. package/dist/lib/task-history.js +15 -0
  135. package/dist/lib/task-history.js.map +1 -0
  136. package/dist/lib/telemetry.js +51 -0
  137. package/dist/lib/telemetry.js.map +1 -0
  138. package/dist/lib/tool-result.js +12 -0
  139. package/dist/lib/tool-result.js.map +1 -0
  140. package/dist/lib/validate-plan-delegate.js +107 -0
  141. package/dist/lib/validate-plan-delegate.js.map +1 -0
  142. package/dist/lib/version-check.js +89 -0
  143. package/dist/lib/version-check.js.map +1 -0
  144. package/dist/matrix-logo.js +122 -0
  145. package/dist/matrix-logo.js.map +1 -0
  146. package/dist/mcp-server.js +189 -0
  147. package/dist/mcp-server.js.map +1 -0
  148. package/dist/session-factory.js +19 -0
  149. package/dist/session-factory.js.map +1 -0
  150. package/dist/spinner.js +12 -0
  151. package/dist/spinner.js.map +1 -0
  152. package/dist/tools/comment-task.js +72 -0
  153. package/dist/tools/comment-task.js.map +1 -0
  154. package/dist/tools/create-task.js +129 -0
  155. package/dist/tools/create-task.js.map +1 -0
  156. package/dist/tools/delegate-exec.js +63 -0
  157. package/dist/tools/delegate-exec.js.map +1 -0
  158. package/dist/tools/end-allocation.js +38 -0
  159. package/dist/tools/end-allocation.js.map +1 -0
  160. package/dist/tools/end-task-allocation.js +37 -0
  161. package/dist/tools/end-task-allocation.js.map +1 -0
  162. package/dist/tools/exec-status.js +43 -0
  163. package/dist/tools/exec-status.js.map +1 -0
  164. package/dist/tools/get-active-allocation.js +69 -0
  165. package/dist/tools/get-active-allocation.js.map +1 -0
  166. package/dist/tools/get-context.js +48 -0
  167. package/dist/tools/get-context.js.map +1 -0
  168. package/dist/tools/get-task.js +137 -0
  169. package/dist/tools/get-task.js.map +1 -0
  170. package/dist/tools/index.js +44 -0
  171. package/dist/tools/index.js.map +1 -0
  172. package/dist/tools/list-my-allocations.js +71 -0
  173. package/dist/tools/list-my-allocations.js.map +1 -0
  174. package/dist/tools/list-projects.js +38 -0
  175. package/dist/tools/list-projects.js.map +1 -0
  176. package/dist/tools/list-tasks.js +93 -0
  177. package/dist/tools/list-tasks.js.map +1 -0
  178. package/dist/tools/move-task.js +82 -0
  179. package/dist/tools/move-task.js.map +1 -0
  180. package/dist/tools/plan.js +56 -0
  181. package/dist/tools/plan.js.map +1 -0
  182. package/dist/tools/record-delivery.js +71 -0
  183. package/dist/tools/record-delivery.js.map +1 -0
  184. package/dist/tools/set-project.js +52 -0
  185. package/dist/tools/set-project.js.map +1 -0
  186. package/dist/tools/start-allocation.js +32 -0
  187. package/dist/tools/start-allocation.js.map +1 -0
  188. package/dist/tools/start-task-allocation.js +75 -0
  189. package/dist/tools/start-task-allocation.js.map +1 -0
  190. package/dist/tools/update-task.js +139 -0
  191. package/dist/tools/update-task.js.map +1 -0
  192. package/dist/tools/validate-plan.js +58 -0
  193. package/dist/tools/validate-plan.js.map +1 -0
  194. package/dist/version.js +16 -0
  195. package/dist/version.js.map +1 -0
  196. package/package.json +64 -0
@@ -0,0 +1,163 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join } from 'node:path';
5
+ import { homePath } from '../brand.js';
6
+ /**
7
+ * Decide se uma dependência já está instalada e executa o plano quando o usuário
8
+ * consente. Complementa `dependencies.ts` (resolução doc → plano) — este módulo é
9
+ * a camada de IO: checagem no disco/subprocesso e o marcador de instalações.
10
+ */
11
+ /** Registro do que o nio instalou: `~/.nio/installed-deps.json`. */
12
+ function markerPath() {
13
+ return homePath('installed-deps.json');
14
+ }
15
+ function readMarker() {
16
+ try {
17
+ return JSON.parse(readFileSync(markerPath(), 'utf-8'));
18
+ }
19
+ catch {
20
+ return {};
21
+ }
22
+ }
23
+ /** Grava que instalamos esta dependência (idempotência p/ `skills`, que não tem local padrão). */
24
+ export function recordDependencyInstalled(dep) {
25
+ const plan = dep.plan;
26
+ if (!plan)
27
+ return;
28
+ const ref = plan.kind === 'npm'
29
+ ? plan.pkg
30
+ : plan.kind === 'skills'
31
+ ? plan.repo
32
+ : plan.kind === 'git'
33
+ ? plan.url
34
+ : plan.plugin; // claude-plugin
35
+ const marker = readMarker();
36
+ marker[dep.id] = { kind: plan.kind, ref, at: new Date().toISOString() };
37
+ try {
38
+ mkdirSync(dirname(markerPath()), { recursive: true });
39
+ writeFileSync(markerPath(), JSON.stringify(marker, null, 2) + '\n');
40
+ }
41
+ catch {
42
+ // best-effort — não bloqueia se ~/.nio não for gravável.
43
+ }
44
+ }
45
+ /** Existe no disco (segue symlinks; symlink pendurado conta como ausente). */
46
+ function pathExists(p) {
47
+ try {
48
+ lstatSync(p);
49
+ // lstat pega o link; confirma que o alvo resolve (não é pendurado).
50
+ return existsSync(p);
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+ /** Expande `~` inicial pro home. */
57
+ function expandTilde(p) {
58
+ return p === '~' || p.startsWith('~/') || p.startsWith('~\\')
59
+ ? join(homedir(), p.slice(1))
60
+ : p;
61
+ }
62
+ /**
63
+ * Existe algo casando o glob? Suporta `*` (um segmento) e `**` (qualquer
64
+ * profundidade). Recursão limitada em profundidade pra não varrer demais.
65
+ */
66
+ function globExists(pattern) {
67
+ const expanded = expandTilde(pattern.trim());
68
+ const abs = expanded.startsWith('/') || /^[A-Za-z]:/.test(expanded);
69
+ const segs = expanded.split(/[/\\]+/).filter(Boolean);
70
+ const start = abs ? '/' : process.cwd();
71
+ return matchSegments(start, segs, 0, 0);
72
+ }
73
+ function matchSegments(base, segs, i, depth) {
74
+ if (depth > 12)
75
+ return false;
76
+ if (i >= segs.length)
77
+ return pathExists(base);
78
+ const seg = segs[i];
79
+ if (seg === '**') {
80
+ if (matchSegments(base, segs, i + 1, depth))
81
+ return true; // zero dirs
82
+ for (const child of childDirs(base)) {
83
+ if (matchSegments(join(base, child), segs, i, depth + 1))
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+ if (seg.includes('*')) {
89
+ const re = new RegExp('^' + seg.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$');
90
+ for (const child of childDirs(base)) {
91
+ if (re.test(child) && matchSegments(join(base, child), segs, i + 1, depth + 1))
92
+ return true;
93
+ }
94
+ return false;
95
+ }
96
+ return matchSegments(join(base, seg), segs, i + 1, depth);
97
+ }
98
+ function childDirs(base) {
99
+ try {
100
+ return readdirSync(base, { withFileTypes: true })
101
+ .filter((e) => e.isDirectory() || e.isSymbolicLink())
102
+ .map((e) => e.name);
103
+ }
104
+ catch {
105
+ return [];
106
+ }
107
+ }
108
+ /** Probe de locais conhecidos onde `npx skills add` costuma instalar. */
109
+ function skillInstalledElsewhere(repo) {
110
+ const name = repo.split('/').pop() ?? repo;
111
+ return [
112
+ join(homedir(), '.claude', 'skills', name),
113
+ join(homedir(), '.codex', 'skills', name),
114
+ join(process.cwd(), '.claude', 'skills', name),
115
+ join(process.cwd(), 'skills', name),
116
+ ].some((p) => existsSync(p));
117
+ }
118
+ /**
119
+ * Já instalado? `npm` → `npm ls -g <pkg>` (autoritativo); `git` → dir de destino
120
+ * existe; `skills` → sem local padrão, usa o marcador do nio + probe de dirs
121
+ * conhecidos.
122
+ */
123
+ export function isDependencyInstalled(dep) {
124
+ // `detect:` vale pra qualquer tipo — inclusive `manual:` (plugins), que não têm plano.
125
+ if (dep.detect && dep.detect.some(globExists))
126
+ return true;
127
+ const plan = dep.plan;
128
+ if (!plan)
129
+ return false;
130
+ if (plan.kind === 'git')
131
+ return existsSync(plan.dest);
132
+ if (plan.kind === 'npm') {
133
+ const res = spawnSync('npm', ['ls', '-g', plan.pkg, '--depth=0'], { stdio: 'ignore' });
134
+ return res.status === 0;
135
+ }
136
+ if (plan.kind === 'skills') {
137
+ return Boolean(readMarker()[dep.id]) || skillInstalledElsewhere(plan.repo);
138
+ }
139
+ // claude-plugin: sem local padrão universal — o `detect:` (acima) é o sinal
140
+ // primário; o marcador cobre o caso de já termos instalado nesta máquina.
141
+ return Boolean(readMarker()[dep.id]);
142
+ }
143
+ /** Executa o plano. `spawnSync` com args em array e SEM shell — zero injeção. */
144
+ export function runDependencyInstall(plan) {
145
+ // claude-plugin: vários passos sequenciais (`marketplace add` → `install`).
146
+ if (plan.kind === 'claude-plugin') {
147
+ for (const step of plan.steps) {
148
+ const res = spawnSync(step.program, step.args, { stdio: 'inherit' });
149
+ if (res.error)
150
+ return { ok: false, code: null, error: res.error.message };
151
+ if (res.status !== 0)
152
+ return { ok: false, code: res.status };
153
+ }
154
+ return { ok: true, code: 0 };
155
+ }
156
+ if (plan.kind === 'git')
157
+ mkdirSync(dirname(plan.dest), { recursive: true });
158
+ const res = spawnSync(plan.program, plan.args, { stdio: 'inherit' });
159
+ if (res.error)
160
+ return { ok: false, code: null, error: res.error.message };
161
+ return { ok: res.status === 0, code: res.status };
162
+ }
163
+ //# sourceMappingURL=dependency-install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-install.js","sourceRoot":"","sources":["../../src/lib/dependency-install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export function durationSeconds(start, end) {
2
+ const endMs = end ? new Date(end).getTime() : Date.now();
3
+ return Math.floor((endMs - new Date(start).getTime()) / 1000);
4
+ }
5
+ //# sourceMappingURL=duration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duration.js","sourceRoot":"","sources":["../../src/lib/duration.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,GAAkB;IAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,167 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { skillsDir } from './skills.js';
6
+ import { homePath } from '../brand.js';
7
+ import { HARNESS_RULES_REL, HARNESS_PATTERNS_REL } from './harness.js';
8
+ import { DEFAULT_ENGINE, engineArgs, engineMissingError, resolveEngineBin, } from './exec-engines.js';
9
+ const jobs = new Map();
10
+ function jobsDir() {
11
+ return homePath('exec-jobs');
12
+ }
13
+ function jobPath(id) {
14
+ return join(jobsDir(), `${id}.json`);
15
+ }
16
+ /** Persiste o job — o servidor MCP pode reiniciar entre chamadas. */
17
+ function save(job) {
18
+ jobs.set(job.id, job);
19
+ try {
20
+ mkdirSync(jobsDir(), { recursive: true });
21
+ writeFileSync(jobPath(job.id), JSON.stringify(job, null, 2) + '\n', 'utf8');
22
+ }
23
+ catch {
24
+ /* best-effort */
25
+ }
26
+ return job;
27
+ }
28
+ export function getJob(id) {
29
+ const mem = jobs.get(id);
30
+ if (mem)
31
+ return mem;
32
+ try {
33
+ return JSON.parse(readFileSync(jobPath(id), 'utf8'));
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /** Preâmbulo que ancora o agente de execução no harness do repo. */
40
+ function buildPrompt(instruction) {
41
+ return [
42
+ 'Implemente a tarefa abaixo NESTE worktree.',
43
+ `Antes de codar: leia AGENTS.md, ${HARNESS_RULES_REL} e ${HARNESS_PATTERNS_REL} e SIGA-OS.`,
44
+ 'Regras: mudança mínima; nada de libs/estilos fora do harness.',
45
+ 'Limites: arquivo <300 linhas, função <30 linhas, comentário <=1 linha.',
46
+ 'Rode lint/build/testes do repo. NÃO commite — deixe o trabalho staged.',
47
+ '',
48
+ instruction,
49
+ ].join('\n');
50
+ }
51
+ /** Roda o hook de tamanho (mesma lógica do commit) sobre o que está staged. */
52
+ function checkSize(worktree) {
53
+ let script;
54
+ try {
55
+ script = join(skillsDir(), 'hooks', 'dev', 'check-code-size.py');
56
+ }
57
+ catch {
58
+ return { ok: true, output: 'skills indisponíveis — check pulado' };
59
+ }
60
+ if (!existsSync(script))
61
+ return { ok: true, output: 'check-code-size ausente — pulado' };
62
+ spawnSync('git', ['add', '-A'], { cwd: worktree, stdio: 'ignore' });
63
+ const r = spawnSync('python3', [script], {
64
+ cwd: worktree,
65
+ input: JSON.stringify({ tool_input: { command: 'git commit' } }),
66
+ encoding: 'utf8',
67
+ });
68
+ if (r.error)
69
+ return { ok: true, output: 'python3 ausente — pulado' };
70
+ return { ok: r.status === 0, output: (r.stderr || '').trim() || 'ok' };
71
+ }
72
+ /** Scripts de qualidade que existem no package.json. */
73
+ function npmScripts(worktree) {
74
+ try {
75
+ const pkg = JSON.parse(readFileSync(join(worktree, 'package.json'), 'utf8'));
76
+ return ['lint', 'build', 'test'].filter((s) => pkg.scripts?.[s]);
77
+ }
78
+ catch {
79
+ return [];
80
+ }
81
+ }
82
+ function runScript(worktree, script) {
83
+ const r = spawnSync('npm', ['run', script, '--silent'], { cwd: worktree, encoding: 'utf8' });
84
+ const out = `${r.stdout ?? ''}${r.stderr ?? ''}`.trim();
85
+ return { ok: !r.error && r.status === 0, output: out.slice(-1500) || 'ok' };
86
+ }
87
+ function changedFiles(worktree) {
88
+ const r = spawnSync('git', ['status', '--porcelain'], { cwd: worktree, encoding: 'utf8' });
89
+ return (r.stdout ?? '')
90
+ .split('\n')
91
+ .map((l) => l.slice(3).trim())
92
+ .filter(Boolean);
93
+ }
94
+ /** Checks determinísticos — sem LLM, pra o Opus não gastar ciclo com o mecânico. */
95
+ function runChecks(worktree) {
96
+ const checks = { size: checkSize(worktree) };
97
+ for (const s of npmScripts(worktree))
98
+ checks[s] = runScript(worktree, s);
99
+ return checks;
100
+ }
101
+ function finish(job) {
102
+ return save({ ...job, finishedAt: new Date().toISOString() });
103
+ }
104
+ function spawnEngine(job, bin, prompt, opts = {}) {
105
+ const child = spawn(bin, engineArgs(job.engine, prompt), {
106
+ cwd: job.worktree,
107
+ stdio: ['ignore', 'pipe', 'pipe'],
108
+ });
109
+ let out = '';
110
+ const collect = (d) => {
111
+ const s = d.toString();
112
+ out += s;
113
+ if (opts.echo)
114
+ process.stderr.write(s); // stdout fica pro JSON final
115
+ };
116
+ child.stdout.on('data', collect);
117
+ child.stderr.on('data', collect);
118
+ child.on('error', (e) => opts.onDone?.(finish({ ...job, state: 'failed', error: e.message })));
119
+ child.on('close', (code) => opts.onDone?.(finish({
120
+ ...job,
121
+ state: code === 0 ? 'done' : 'failed',
122
+ exitCode: code,
123
+ summary: out.trim().slice(-2000),
124
+ checks: runChecks(job.worktree),
125
+ changed: changedFiles(job.worktree),
126
+ })));
127
+ }
128
+ function newJob(worktree, engine) {
129
+ return {
130
+ id: randomUUID().slice(0, 8),
131
+ state: 'running',
132
+ worktree,
133
+ engine,
134
+ exitCode: null,
135
+ summary: '',
136
+ checks: {},
137
+ changed: [],
138
+ startedAt: new Date().toISOString(),
139
+ };
140
+ }
141
+ /** Prepara o job: resolve o binário e persiste. Devolve o job já falho se não achar. */
142
+ function prepare(worktree, engine) {
143
+ const job = newJob(worktree, engine);
144
+ const bin = resolveEngineBin(engine);
145
+ if (!bin) {
146
+ return finish({ ...job, state: 'failed', error: engineMissingError(engine) });
147
+ }
148
+ return { job, bin: save(job) && bin };
149
+ }
150
+ /** Background: devolve na hora (uso do MCP, que é processo longo). */
151
+ export function startExec(opts) {
152
+ const p = prepare(opts.worktree, opts.engine ?? DEFAULT_ENGINE);
153
+ if ('state' in p)
154
+ return p;
155
+ spawnEngine(p.job, p.bin, buildPrompt(opts.instruction), { onDone: () => undefined });
156
+ return p.job;
157
+ }
158
+ /** Bloqueante: aguarda o fim (uso do CLI, que é processo curto). `echo` streama pro stderr. */
159
+ export function runExec(opts) {
160
+ return new Promise((resolve) => {
161
+ const p = prepare(opts.worktree, opts.engine ?? DEFAULT_ENGINE);
162
+ if ('state' in p)
163
+ return resolve(p);
164
+ spawnEngine(p.job, p.bin, buildPrompt(opts.instruction), { echo: opts.echo, onDone: resolve });
165
+ });
166
+ }
167
+ //# sourceMappingURL=exec-delegate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-delegate.js","sourceRoot":"","sources":["../../src/lib/exec-delegate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { spawnSync } from 'node:child_process';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { envName } from '../brand.js';
6
+ /**
7
+ * Registro central dos engines da delegação headless. É o **único** lugar que conhece
8
+ * nome de binário, candidatos de PATH e flags. Adicionar engine = adicionar uma entrada.
9
+ */
10
+ export const ENGINES = ['codex', 'claude'];
11
+ export const DEFAULT_ENGINE = 'codex';
12
+ /** Planejar pede raciocínio; executar pede velocidade — daí o default por verbo. */
13
+ export const PLAN_ENGINE = 'claude';
14
+ // O MCP é spawnado por app GUI, com PATH mínimo — daí a busca em locais conhecidos.
15
+ function knownPaths(bin, ...extra) {
16
+ return [
17
+ join(homedir(), '.local', 'bin', bin),
18
+ '/opt/homebrew/bin/' + bin,
19
+ '/usr/local/bin/' + bin,
20
+ ...extra,
21
+ ];
22
+ }
23
+ const SPECS = {
24
+ codex: {
25
+ bin: 'codex',
26
+ candidates: knownPaths('codex'),
27
+ binEnv: envName('CODEX_BIN'),
28
+ argsEnv: envName('CODEX_ARGS'),
29
+ args: (prompt) => ['exec', '--full-auto', prompt],
30
+ missing: `codex não encontrado — instale/logue (\`codex login\`) ou defina ${envName('CODEX_BIN')}`,
31
+ },
32
+ claude: {
33
+ bin: 'claude',
34
+ candidates: knownPaths('claude', join(homedir(), '.claude', 'local', 'claude')),
35
+ binEnv: envName('CLAUDE_BIN'),
36
+ argsEnv: envName('CLAUDE_ARGS'),
37
+ args: (prompt) => ['-p', prompt, '--permission-mode', 'acceptEdits'],
38
+ missing: `claude não encontrado — instale/logue (\`claude login\`) ou defina ${envName('CLAUDE_BIN')}`,
39
+ },
40
+ };
41
+ export function isEngine(value) {
42
+ return typeof value === 'string' && ENGINES.includes(value);
43
+ }
44
+ /** Normaliza o valor pedido; ausente → default do verbo; inválido → `null` (o caller reporta). */
45
+ export function parseEngine(value, fallback = DEFAULT_ENGINE) {
46
+ if (value === undefined || value === null || value === '')
47
+ return fallback;
48
+ return isEngine(value) ? value : null;
49
+ }
50
+ export function engineMissingError(engine) {
51
+ return SPECS[engine].missing;
52
+ }
53
+ /** Args headless do engine; `NIO_<ENGINE>_ARGS` sobrescreve (prompt vai no fim). */
54
+ export function engineArgs(engine, prompt) {
55
+ const spec = SPECS[engine];
56
+ const override = process.env[spec.argsEnv];
57
+ if (override && override.trim())
58
+ return [...override.trim().split(/\s+/), prompt];
59
+ return spec.args(prompt);
60
+ }
61
+ /** Acha o binário: override de env, depois PATH, depois os candidatos conhecidos. */
62
+ export function resolveEngineBin(engine) {
63
+ const spec = SPECS[engine];
64
+ const override = process.env[spec.binEnv];
65
+ if (override && existsSync(override))
66
+ return override;
67
+ const onPath = spawnSync(spec.bin, ['--version'], { stdio: 'ignore' });
68
+ if (!onPath.error)
69
+ return spec.bin;
70
+ return spec.candidates.find((p) => existsSync(p)) ?? null;
71
+ }
72
+ //# sourceMappingURL=exec-engines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec-engines.js","sourceRoot":"","sources":["../../src/lib/exec-engines.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync, } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+ import { parse as parseToml, stringify as stringifyToml } from 'smol-toml';
4
+ export function backupFile(path) {
5
+ const backupPath = `${path}.bak.${Date.now()}`;
6
+ copyFileSync(path, backupPath);
7
+ return backupPath;
8
+ }
9
+ export function readJson(path) {
10
+ if (!existsSync(path))
11
+ return null;
12
+ const raw = readFileSync(path, 'utf-8');
13
+ if (raw.trim().length === 0)
14
+ return null;
15
+ return JSON.parse(raw);
16
+ }
17
+ export function writeJson(path, data) {
18
+ mkdirSync(dirname(path), { recursive: true });
19
+ writeFileSync(path, JSON.stringify(data, null, 2) + '\n', 'utf-8');
20
+ }
21
+ export function readToml(path) {
22
+ if (!existsSync(path))
23
+ return null;
24
+ const raw = readFileSync(path, 'utf-8');
25
+ if (raw.trim().length === 0)
26
+ return null;
27
+ return parseToml(raw);
28
+ }
29
+ export function writeToml(path, data) {
30
+ mkdirSync(dirname(path), { recursive: true });
31
+ writeFileSync(path, stringifyToml(data) + '\n', 'utf-8');
32
+ }
33
+ //# sourceMappingURL=file-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-merge.js","sourceRoot":"","sources":["../../src/lib/file-merge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,UAAU,EACV,SAAS,EACT,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AAE3E,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,UAAU,GAAG,GAAG,IAAI,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC/C,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC/B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAa;IACnD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO,SAAS,CAAC,GAAG,CAA4B,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAA6B;IACnE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
2
+ import { brand } from '../brand.js';
3
+ import { dirname, join } from 'node:path';
4
+ /**
5
+ * Grava o **harness** de código no repo (versionado, do time): o arquivo de rules
6
+ * concatenadas + as âncoras no `AGENTS.md` (com o bloco de overview do NOS) + um
7
+ * `CLAUDE.md` fino. Idempotente e não-destrutivo: só reescreve o que é do nio; o
8
+ * texto do time no `AGENTS.md` (fora do bloco marcado) é preservado.
9
+ */
10
+ export const HARNESS_RULES_REL = `docs/_rules/${brand.name}.md`;
11
+ export const HARNESS_PATTERNS_REL = 'docs/_patterns.md';
12
+ const AGENTS_REL = 'AGENTS.md';
13
+ const CLAUDE_REL = 'CLAUDE.md';
14
+ const OV_START = `<!-- ${brand.name}:overview:start -->`;
15
+ const OV_END = `<!-- ${brand.name}:overview:end -->`;
16
+ function escapeRe(s) {
17
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
18
+ }
19
+ function writeIfChanged(path, content) {
20
+ if (!existsSync(path)) {
21
+ mkdirSync(dirname(path), { recursive: true });
22
+ writeFileSync(path, content, 'utf8');
23
+ return 'created';
24
+ }
25
+ if (readFileSync(path, 'utf8') === content)
26
+ return 'unchanged';
27
+ writeFileSync(path, content, 'utf8');
28
+ return 'updated';
29
+ }
30
+ /** Insere um bloco logo após o primeiro heading `# …`, ou no topo se não houver. */
31
+ function insertAfterTitle(text, block) {
32
+ const lines = text.split('\n');
33
+ const i = lines.findIndex((l) => /^#\s/.test(l));
34
+ if (i === -1)
35
+ return `${block}\n${text}`;
36
+ lines.splice(i + 1, 0, '', block);
37
+ return lines.join('\n');
38
+ }
39
+ /** Garante o bloco de overview (marcado) + as âncoras `@` no `AGENTS.md`. */
40
+ function ensureAgents(path, overview) {
41
+ const anchors = [`@${HARNESS_RULES_REL}`, `@${HARNESS_PATTERNS_REL}`];
42
+ const ovBlock = overview
43
+ ? `${OV_START}\n## Sobre o projeto\n\n${overview.trim()}\n${OV_END}`
44
+ : null;
45
+ if (!existsSync(path)) {
46
+ const ov = ovBlock ? `${ovBlock}\n\n` : '';
47
+ const content = `# AGENTS.md\n\n${ov}## Harness\n\n${anchors.join('\n')}\n`;
48
+ mkdirSync(dirname(path), { recursive: true });
49
+ writeFileSync(path, content, 'utf8');
50
+ return 'created';
51
+ }
52
+ let text = readFileSync(path, 'utf8');
53
+ const before = text;
54
+ if (ovBlock) {
55
+ const re = new RegExp(`${escapeRe(OV_START)}[\\s\\S]*?${escapeRe(OV_END)}`);
56
+ text = re.test(text) ? text.replace(re, ovBlock) : insertAfterTitle(text, ovBlock);
57
+ }
58
+ for (const line of anchors) {
59
+ if (!text.split('\n').some((l) => l.trim() === line)) {
60
+ text = `${text.trimEnd()}\n${line}\n`;
61
+ }
62
+ }
63
+ if (text === before)
64
+ return 'unchanged';
65
+ writeFileSync(path, text, 'utf8');
66
+ return 'updated';
67
+ }
68
+ /**
69
+ * Escreve o harness no repo (`cwd`). `rulesMarkdown` vem do concatenador; `overview` é
70
+ * o texto do NOS (opcional — quando ausente, o bloco de overview não é tocado).
71
+ */
72
+ export function writeRepoHarness(cwd, opts) {
73
+ const result = { rules: 'empty', agents: 'unchanged', claude: 'unchanged' };
74
+ // 1. docs/_rules/<nome-da-marca>.md — totalmente do nio.
75
+ if (opts.rulesMarkdown.trim()) {
76
+ const header = `# Harness de código — ${brand.name}\n\n` +
77
+ `<!-- Gerado por \`${brand.name} sync\`. Não edite à mão — rode \`${brand.name} sync\`. -->\n\n`;
78
+ result.rules = writeIfChanged(join(cwd, HARNESS_RULES_REL), `${header}${opts.rulesMarkdown.trim()}\n`);
79
+ }
80
+ // 2. AGENTS.md — overview (bloco marcado) + âncoras.
81
+ result.agents = ensureAgents(join(cwd, AGENTS_REL), opts.overview ?? null);
82
+ // 3. CLAUDE.md fino — scaffold-if-missing.
83
+ const claudePath = join(cwd, CLAUDE_REL);
84
+ if (!existsSync(claudePath)) {
85
+ writeFileSync(claudePath, `@${AGENTS_REL}\n`, 'utf8');
86
+ result.claude = 'created';
87
+ }
88
+ return result;
89
+ }
90
+ //# sourceMappingURL=harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/lib/harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,KAAK,CAAC,IAAI,KAAK,CAAC;AAChE,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACxD,MAAM,UAAU,GAAG,WAAW,CAAC;AAC/B,MAAM,UAAU,GAAG,WAAW,CAAC;AAC/B,MAAM,QAAQ,GAAG,QAAQ,KAAK,CAAC,IAAI,qBAAqB,CAAC;AACzD,MAAM,MAAM,GAAG,QAAQ,KAAK,CAAC,IAAI,mBAAmB,CAAC;AAUrD,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,OAAe;IACnD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO;QAAE,OAAO,WAAW,CAAC;IAC/D,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,oFAAoF;AACpF,SAAS,gBAAgB,CAAC,IAAY,EAAE,KAAa;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,GAAG,KAAK,KAAK,IAAI,EAAE,CAAC;IACzC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,6EAA6E;AAC7E,SAAS,YAAY,CAAC,IAAY,EAAE,QAAuB;IACzD,MAAM,OAAO,GAAG,CAAC,IAAI,iBAAiB,EAAE,EAAE,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,QAAQ;QACtB,CAAC,CAAC,GAAG,QAAQ,2BAA2B,QAAQ,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE;QACpE,CAAC,CAAC,IAAI,CAAC;IAET,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,kBAAkB,EAAE,iBAAiB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5E,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC;IAEpB,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,aAAa,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5E,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrF,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;YACrD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC;QACxC,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,WAAW,CAAC;IACxC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAClC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAW,EACX,IAAyD;IAEzD,MAAM,MAAM,GAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAE3F,yDAAyD;IACzD,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9B,MAAM,MAAM,GACV,yBAAyB,KAAK,CAAC,IAAI,MAAM;YACzC,qBAAqB,KAAK,CAAC,IAAI,qCAAqC,KAAK,CAAC,IAAI,kBAAkB,CAAC;QACnG,MAAM,CAAC,KAAK,GAAG,cAAc,CAC3B,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAC5B,GAAG,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAC1C,CAAC;IACJ,CAAC;IAED,qDAAqD;IACrD,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;IAE3E,2CAA2C;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,aAAa,CAAC,UAAU,EAAE,IAAI,UAAU,IAAI,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}