@noclaf/cli 0.4.9 → 0.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/exec.js +12 -1
- package/dist/cli/commands/exec.js.map +1 -1
- package/dist/lib/exec-delegate.js +13 -31
- package/dist/lib/exec-delegate.js.map +1 -1
- package/dist/lib/exec-engines.js +69 -0
- package/dist/lib/exec-engines.js.map +1 -0
- package/dist/tools/delegate-exec.js +11 -3
- package/dist/tools/delegate-exec.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { runExec, getJob } from "../../lib/exec-delegate.js";
|
|
3
|
+
import { ENGINES, DEFAULT_ENGINE, parseEngine, } from "../../lib/exec-engines.js";
|
|
3
4
|
/**
|
|
4
5
|
* Superfície de CLI da delegação headless — o que o noclaf Studio (Tauri) chama.
|
|
5
6
|
* Contrato: **stdout = JSON** (parseável), **stderr = log ao vivo** (streamável).
|
|
@@ -10,12 +11,21 @@ function emit(payload) {
|
|
|
10
11
|
export function registerExecCommand(program) {
|
|
11
12
|
program
|
|
12
13
|
.command("exec")
|
|
13
|
-
.description("Delega a implementação a um agente headless
|
|
14
|
+
.description("Delega a implementação a um agente headless num worktree e aguarda. " +
|
|
14
15
|
"stdout = JSON do resultado; stderr = log ao vivo.")
|
|
15
16
|
.requiredOption("--worktree <path>", "worktree onde implementar (criado pelo /implement)")
|
|
16
17
|
.requiredOption("--instruction <texto>", "o que implementar (ticket + critérios)")
|
|
18
|
+
.option("--engine <engine>", `agente de execução (${ENGINES.join(" | ")})`, DEFAULT_ENGINE)
|
|
17
19
|
.option("--quiet", "não streama o log do agente no stderr")
|
|
18
20
|
.action(async (opts) => {
|
|
21
|
+
const engine = parseEngine(opts.engine);
|
|
22
|
+
if (!engine) {
|
|
23
|
+
emit({
|
|
24
|
+
error: `engine inválido: ${opts.engine} — suportados: ${ENGINES.join(", ")}`,
|
|
25
|
+
});
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
19
29
|
if (!existsSync(opts.worktree)) {
|
|
20
30
|
emit({ error: `worktree não encontrado: ${opts.worktree}` });
|
|
21
31
|
process.exitCode = 1;
|
|
@@ -24,6 +34,7 @@ export function registerExecCommand(program) {
|
|
|
24
34
|
const job = await runExec({
|
|
25
35
|
worktree: opts.worktree,
|
|
26
36
|
instruction: opts.instruction,
|
|
37
|
+
engine,
|
|
27
38
|
echo: opts.quiet !== true,
|
|
28
39
|
});
|
|
29
40
|
emit(job);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../../src/cli/commands/exec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../../src/cli/commands/exec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EACL,OAAO,EACP,cAAc,EACd,WAAW,GACZ,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AAEH,SAAS,IAAI,CAAC,OAAgB;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CACV,sEAAsE;QACpE,mDAAmD,CACtD;SACA,cAAc,CACb,mBAAmB,EACnB,oDAAoD,CACrD;SACA,cAAc,CACb,uBAAuB,EACvB,wCAAwC,CACzC;SACA,MAAM,CACL,mBAAmB,EACnB,uBAAuB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAC7C,cAAc,CACf;SACA,MAAM,CAAC,SAAS,EAAE,uCAAuC,CAAC;SAC1D,MAAM,CACL,KAAK,EAAE,IAKN,EAAE,EAAE;QACH,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,KAAK,EAAE,oBAAoB,IAAI,CAAC,MAAM,kBAAkB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aAC7E,CAAC,CAAC;YACH,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;YACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM;YACN,IAAI,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI;SAC1B,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACjD,CAAC,CACF,CAAC;IAEJ,mFAAmF;IACnF,OAAO;SACJ,OAAO,CAAC,qBAAqB,CAAC;SAC9B,WAAW,CAAC,uDAAuD,CAAC;SACpE,MAAM,CAAC,CAAC,KAAa,EAAE,EAAE;QACxB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,KAAK,EAAE,EAAE,CAAC,CAAC;YAChD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { homedir } from 'node:os';
|
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { skillsDir } from './skills.js';
|
|
7
|
+
import { DEFAULT_ENGINE, engineArgs, engineMissingError, resolveEngineBin, } from './exec-engines.js';
|
|
7
8
|
const jobs = new Map();
|
|
8
9
|
function jobsDir() {
|
|
9
10
|
return join(homedir(), '.noclaf', 'exec-jobs');
|
|
@@ -34,21 +35,6 @@ export function getJob(id) {
|
|
|
34
35
|
return null;
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
|
-
const CODEX_CANDIDATES = [
|
|
38
|
-
join(homedir(), '.local', 'bin', 'codex'),
|
|
39
|
-
'/opt/homebrew/bin/codex',
|
|
40
|
-
'/usr/local/bin/codex',
|
|
41
|
-
];
|
|
42
|
-
/** Acha o `codex` — o MCP é spawnado por app GUI, com PATH mínimo. */
|
|
43
|
-
export function resolveCodexBin() {
|
|
44
|
-
const override = process.env.NOCLAF_CODEX_BIN;
|
|
45
|
-
if (override && existsSync(override))
|
|
46
|
-
return override;
|
|
47
|
-
const onPath = spawnSync('codex', ['--version'], { stdio: 'ignore' });
|
|
48
|
-
if (!onPath.error)
|
|
49
|
-
return 'codex';
|
|
50
|
-
return CODEX_CANDIDATES.find((p) => existsSync(p)) ?? null;
|
|
51
|
-
}
|
|
52
38
|
/** Preâmbulo que ancora o agente de execução no harness do repo. */
|
|
53
39
|
function buildPrompt(instruction) {
|
|
54
40
|
return [
|
|
@@ -114,9 +100,8 @@ function runChecks(worktree) {
|
|
|
114
100
|
function finish(job) {
|
|
115
101
|
return save({ ...job, finishedAt: new Date().toISOString() });
|
|
116
102
|
}
|
|
117
|
-
function
|
|
118
|
-
const
|
|
119
|
-
const child = spawn(bin, [...args, prompt], {
|
|
103
|
+
function spawnEngine(job, bin, prompt, opts = {}) {
|
|
104
|
+
const child = spawn(bin, engineArgs(job.engine, prompt), {
|
|
120
105
|
cwd: job.worktree,
|
|
121
106
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
122
107
|
});
|
|
@@ -139,11 +124,12 @@ function spawnCodex(job, bin, prompt, opts = {}) {
|
|
|
139
124
|
changed: changedFiles(job.worktree),
|
|
140
125
|
})));
|
|
141
126
|
}
|
|
142
|
-
function newJob(worktree) {
|
|
127
|
+
function newJob(worktree, engine) {
|
|
143
128
|
return {
|
|
144
129
|
id: randomUUID().slice(0, 8),
|
|
145
130
|
state: 'running',
|
|
146
131
|
worktree,
|
|
132
|
+
engine,
|
|
147
133
|
exitCode: null,
|
|
148
134
|
summary: '',
|
|
149
135
|
checks: {},
|
|
@@ -152,33 +138,29 @@ function newJob(worktree) {
|
|
|
152
138
|
};
|
|
153
139
|
}
|
|
154
140
|
/** Prepara o job: resolve o binário e persiste. Devolve o job já falho se não achar. */
|
|
155
|
-
function prepare(worktree) {
|
|
156
|
-
const job = newJob(worktree);
|
|
157
|
-
const bin =
|
|
141
|
+
function prepare(worktree, engine) {
|
|
142
|
+
const job = newJob(worktree, engine);
|
|
143
|
+
const bin = resolveEngineBin(engine);
|
|
158
144
|
if (!bin) {
|
|
159
|
-
return finish({
|
|
160
|
-
...job,
|
|
161
|
-
state: 'failed',
|
|
162
|
-
error: 'codex não encontrado — instale/logue (`codex login`) ou defina NOCLAF_CODEX_BIN',
|
|
163
|
-
});
|
|
145
|
+
return finish({ ...job, state: 'failed', error: engineMissingError(engine) });
|
|
164
146
|
}
|
|
165
147
|
return { job, bin: save(job) && bin };
|
|
166
148
|
}
|
|
167
149
|
/** Background: devolve na hora (uso do MCP, que é processo longo). */
|
|
168
150
|
export function startExec(opts) {
|
|
169
|
-
const p = prepare(opts.worktree);
|
|
151
|
+
const p = prepare(opts.worktree, opts.engine ?? DEFAULT_ENGINE);
|
|
170
152
|
if ('state' in p)
|
|
171
153
|
return p;
|
|
172
|
-
|
|
154
|
+
spawnEngine(p.job, p.bin, buildPrompt(opts.instruction), { onDone: () => undefined });
|
|
173
155
|
return p.job;
|
|
174
156
|
}
|
|
175
157
|
/** Bloqueante: aguarda o fim (uso do CLI, que é processo curto). `echo` streama pro stderr. */
|
|
176
158
|
export function runExec(opts) {
|
|
177
159
|
return new Promise((resolve) => {
|
|
178
|
-
const p = prepare(opts.worktree);
|
|
160
|
+
const p = prepare(opts.worktree, opts.engine ?? DEFAULT_ENGINE);
|
|
179
161
|
if ('state' in p)
|
|
180
162
|
return resolve(p);
|
|
181
|
-
|
|
163
|
+
spawnEngine(p.job, p.bin, buildPrompt(opts.instruction), { echo: opts.echo, onDone: resolve });
|
|
182
164
|
});
|
|
183
165
|
}
|
|
184
166
|
//# sourceMappingURL=exec-delegate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec-delegate.js","sourceRoot":"","sources":["../../src/lib/exec-delegate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"exec-delegate.js","sourceRoot":"","sources":["../../src/lib/exec-delegate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* Registro central dos engines da delegação headless. É o **único** lugar que conhece
|
|
7
|
+
* nome de binário, candidatos de PATH e flags. Adicionar engine = adicionar uma entrada.
|
|
8
|
+
*/
|
|
9
|
+
export const ENGINES = ['codex', 'claude'];
|
|
10
|
+
export const DEFAULT_ENGINE = 'codex';
|
|
11
|
+
// O MCP é spawnado por app GUI, com PATH mínimo — daí a busca em locais conhecidos.
|
|
12
|
+
function knownPaths(bin, ...extra) {
|
|
13
|
+
return [
|
|
14
|
+
join(homedir(), '.local', 'bin', bin),
|
|
15
|
+
'/opt/homebrew/bin/' + bin,
|
|
16
|
+
'/usr/local/bin/' + bin,
|
|
17
|
+
...extra,
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
const SPECS = {
|
|
21
|
+
codex: {
|
|
22
|
+
bin: 'codex',
|
|
23
|
+
candidates: knownPaths('codex'),
|
|
24
|
+
binEnv: 'NOCLAF_CODEX_BIN',
|
|
25
|
+
argsEnv: 'NOCLAF_CODEX_ARGS',
|
|
26
|
+
args: (prompt) => ['exec', '--full-auto', prompt],
|
|
27
|
+
missing: 'codex não encontrado — instale/logue (`codex login`) ou defina NOCLAF_CODEX_BIN',
|
|
28
|
+
},
|
|
29
|
+
claude: {
|
|
30
|
+
bin: 'claude',
|
|
31
|
+
candidates: knownPaths('claude', join(homedir(), '.claude', 'local', 'claude')),
|
|
32
|
+
binEnv: 'NOCLAF_CLAUDE_BIN',
|
|
33
|
+
argsEnv: 'NOCLAF_CLAUDE_ARGS',
|
|
34
|
+
args: (prompt) => ['-p', prompt, '--permission-mode', 'acceptEdits'],
|
|
35
|
+
missing: 'claude não encontrado — instale/logue (`claude login`) ou defina NOCLAF_CLAUDE_BIN',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export function isEngine(value) {
|
|
39
|
+
return typeof value === 'string' && ENGINES.includes(value);
|
|
40
|
+
}
|
|
41
|
+
/** Normaliza o valor pedido; ausente → default; inválido → `null` (o caller reporta). */
|
|
42
|
+
export function parseEngine(value) {
|
|
43
|
+
if (value === undefined || value === null || value === '')
|
|
44
|
+
return DEFAULT_ENGINE;
|
|
45
|
+
return isEngine(value) ? value : null;
|
|
46
|
+
}
|
|
47
|
+
export function engineMissingError(engine) {
|
|
48
|
+
return SPECS[engine].missing;
|
|
49
|
+
}
|
|
50
|
+
/** Args headless do engine; `NOCLAF_<ENGINE>_ARGS` sobrescreve (prompt vai no fim). */
|
|
51
|
+
export function engineArgs(engine, prompt) {
|
|
52
|
+
const spec = SPECS[engine];
|
|
53
|
+
const override = process.env[spec.argsEnv];
|
|
54
|
+
if (override && override.trim())
|
|
55
|
+
return [...override.trim().split(/\s+/), prompt];
|
|
56
|
+
return spec.args(prompt);
|
|
57
|
+
}
|
|
58
|
+
/** Acha o binário: override de env, depois PATH, depois os candidatos conhecidos. */
|
|
59
|
+
export function resolveEngineBin(engine) {
|
|
60
|
+
const spec = SPECS[engine];
|
|
61
|
+
const override = process.env[spec.binEnv];
|
|
62
|
+
if (override && existsSync(override))
|
|
63
|
+
return override;
|
|
64
|
+
const onPath = spawnSync(spec.bin, ['--version'], { stdio: 'ignore' });
|
|
65
|
+
if (!onPath.error)
|
|
66
|
+
return spec.bin;
|
|
67
|
+
return spec.candidates.find((p) => existsSync(p)) ?? null;
|
|
68
|
+
}
|
|
69
|
+
//# 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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"}
|
|
@@ -2,15 +2,17 @@ import { z } from 'zod';
|
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
3
|
import { jsonResult, errorResult } from '../lib/tool-result.js';
|
|
4
4
|
import { startExec } from '../lib/exec-delegate.js';
|
|
5
|
+
import { ENGINES, DEFAULT_ENGINE } from '../lib/exec-engines.js';
|
|
5
6
|
const ArgsSchema = z
|
|
6
7
|
.object({
|
|
7
8
|
worktree: z.string().min(1),
|
|
8
9
|
instruction: z.string().min(1),
|
|
10
|
+
engine: z.enum(ENGINES).optional(),
|
|
9
11
|
})
|
|
10
12
|
.strict();
|
|
11
13
|
export const definition = {
|
|
12
14
|
name: 'noclaf_delegate_exec',
|
|
13
|
-
description: 'Delega a IMPLEMENTAÇÃO a um agente de execução novo (
|
|
15
|
+
description: 'Delega a IMPLEMENTAÇÃO a um agente de execução novo (codex ou claude local, na assinatura — sem API) ' +
|
|
14
16
|
'num worktree já criado pelo /implement. Roda em background e, ao terminar, mede o resultado ' +
|
|
15
17
|
'(tamanho de arquivo/função, lint, build, testes). NÃO julga qualidade e NÃO commita — o ' +
|
|
16
18
|
'review fica com você (code-reviewer + harness). Consulte o resultado com `noclaf_exec_status`.',
|
|
@@ -26,6 +28,11 @@ export const definition = {
|
|
|
26
28
|
description: 'O que implementar: o ticket + critérios de aceitação. Numa re-tentativa, inclua as ' +
|
|
27
29
|
'violações apontadas pelo review — o agente de execução é novo e não herda a conversa.',
|
|
28
30
|
},
|
|
31
|
+
engine: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
enum: [...ENGINES],
|
|
34
|
+
description: `Agente de execução a usar. Default: ${DEFAULT_ENGINE}.`,
|
|
35
|
+
},
|
|
29
36
|
},
|
|
30
37
|
required: ['worktree', 'instruction'],
|
|
31
38
|
additionalProperties: false,
|
|
@@ -36,17 +43,18 @@ export async function handler(args, _ctx) {
|
|
|
36
43
|
if (!parsed.success) {
|
|
37
44
|
return errorResult(`Argumento inválido: ${parsed.error.message}`);
|
|
38
45
|
}
|
|
39
|
-
const { worktree, instruction } = parsed.data;
|
|
46
|
+
const { worktree, instruction, engine } = parsed.data;
|
|
40
47
|
if (!existsSync(worktree)) {
|
|
41
48
|
return errorResult(`Worktree não encontrado: ${worktree}`);
|
|
42
49
|
}
|
|
43
|
-
const job = startExec({ worktree, instruction });
|
|
50
|
+
const job = startExec({ worktree, instruction, engine });
|
|
44
51
|
if (job.state === 'failed') {
|
|
45
52
|
return errorResult(job.error ?? 'falha ao iniciar a execução');
|
|
46
53
|
}
|
|
47
54
|
return jsonResult({
|
|
48
55
|
job_id: job.id,
|
|
49
56
|
state: job.state,
|
|
57
|
+
engine: job.engine,
|
|
50
58
|
worktree: job.worktree,
|
|
51
59
|
hint: 'Consulte com `noclaf_exec_status` até state=done|failed.',
|
|
52
60
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegate-exec.js","sourceRoot":"","sources":["../../src/tools/delegate-exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"delegate-exec.js","sourceRoot":"","sources":["../../src/tools/delegate-exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGrC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE;CACnC,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,uGAAuG;QACvG,8FAA8F;QAC9F,0FAA0F;QAC1F,gGAAgG;IAClG,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yEAAyE;aACvF;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,qFAAqF;oBACrF,uFAAuF;aAC1F;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC;gBAClB,WAAW,EAAE,uCAAuC,cAAc,GAAG;aACtE;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC;QACrC,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAa,EAAE,IAAiB;IAC5D,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IACtD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,WAAW,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IACzD,IAAI,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,IAAI,6BAA6B,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,UAAU,CAAC;QAChB,MAAM,EAAE,GAAG,CAAC,EAAE;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,IAAI,EAAE,0DAA0D;KACjE,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
CHANGED