@soleri/cli 0.0.1 → 1.0.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.
- package/README.md +98 -0
- package/dist/commands/add-domain.d.ts +2 -0
- package/dist/commands/add-domain.js +41 -0
- package/dist/commands/add-domain.js.map +1 -0
- package/dist/commands/create.d.ts +2 -0
- package/dist/commands/create.js +68 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/dev.d.ts +2 -0
- package/dist/commands/dev.js +34 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +31 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/hooks.d.ts +2 -0
- package/dist/commands/hooks.js +76 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/install-knowledge.d.ts +2 -0
- package/dist/commands/install-knowledge.js +43 -0
- package/dist/commands/install-knowledge.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.js +33 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/hooks/generator.d.ts +15 -0
- package/dist/hooks/generator.js +58 -0
- package/dist/hooks/generator.js.map +1 -0
- package/dist/hooks/templates.d.ts +3 -0
- package/dist/hooks/templates.js +156 -0
- package/dist/hooks/templates.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +23 -0
- package/dist/main.js.map +1 -0
- package/dist/prompts/create-wizard.d.ts +6 -0
- package/dist/prompts/create-wizard.js +126 -0
- package/dist/prompts/create-wizard.js.map +1 -0
- package/dist/utils/agent-context.d.ts +12 -0
- package/dist/utils/agent-context.js +31 -0
- package/dist/utils/agent-context.js.map +1 -0
- package/dist/utils/checks.d.ts +12 -0
- package/dist/utils/checks.js +116 -0
- package/dist/utils/checks.js.map +1 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.js +33 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +40 -4
- package/src/__tests__/add-domain.test.ts +117 -0
- package/src/__tests__/create.test.ts +92 -0
- package/src/__tests__/dev.test.ts +62 -0
- package/src/__tests__/doctor.test.ts +121 -0
- package/src/__tests__/hooks.test.ts +133 -0
- package/src/__tests__/install-knowledge.test.ts +117 -0
- package/src/__tests__/list.test.ts +80 -0
- package/src/commands/add-domain.ts +46 -0
- package/src/commands/create.ts +73 -0
- package/src/commands/dev.ts +39 -0
- package/src/commands/doctor.ts +33 -0
- package/src/commands/hooks.ts +86 -0
- package/src/commands/install-knowledge.ts +49 -0
- package/src/commands/list.ts +42 -0
- package/src/hooks/generator.ts +65 -0
- package/src/hooks/templates.ts +185 -0
- package/src/main.ts +27 -0
- package/src/prompts/create-wizard.ts +129 -0
- package/src/utils/agent-context.ts +38 -0
- package/src/utils/checks.ts +127 -0
- package/src/utils/logger.ts +39 -0
- package/tsconfig.json +21 -0
- package/vitest.config.ts +8 -0
package/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# @soleri/cli
|
|
2
|
+
|
|
3
|
+
Developer CLI for creating and managing Soleri AI agents.
|
|
4
|
+
|
|
5
|
+
Part of the [Soleri](https://soleri.dev) framework — building AI assistants that learn, remember, and grow with you.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @soleri/cli create my-agent
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The interactive wizard walks you through agent configuration: name, role, domains, principles, and greeting. When you're done, it scaffolds a complete agent project ready to build and run.
|
|
14
|
+
|
|
15
|
+
## Commands
|
|
16
|
+
|
|
17
|
+
| Command | Description |
|
|
18
|
+
| --------------------------------- | ------------------------------------------------------ |
|
|
19
|
+
| `soleri create [name]` | Interactive wizard to scaffold a new agent |
|
|
20
|
+
| `soleri list [dir]` | Show agents in a directory |
|
|
21
|
+
| `soleri add-domain <domain>` | Add a knowledge domain to the agent in cwd |
|
|
22
|
+
| `soleri install-knowledge <pack>` | Install knowledge packs from a local path |
|
|
23
|
+
| `soleri dev` | Run agent in development mode (stdio MCP server) |
|
|
24
|
+
| `soleri doctor` | Health check — Node, npm, tsx, agent, deps, build, MCP |
|
|
25
|
+
| `soleri hooks add <editor>` | Generate editor hooks/config files |
|
|
26
|
+
| `soleri hooks remove <editor>` | Remove editor hooks/config files |
|
|
27
|
+
| `soleri hooks list` | Show installed editor hooks |
|
|
28
|
+
|
|
29
|
+
### Create
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Interactive wizard
|
|
33
|
+
soleri create my-agent
|
|
34
|
+
|
|
35
|
+
# Non-interactive with config file
|
|
36
|
+
soleri create --config agent.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The config file follows the same schema as the wizard output:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"id": "my-agent",
|
|
44
|
+
"name": "My Agent",
|
|
45
|
+
"role": "Code Review Advisor",
|
|
46
|
+
"description": "Reviews code for quality and security issues.",
|
|
47
|
+
"domains": ["security", "code-quality"],
|
|
48
|
+
"principles": ["Security is not optional"],
|
|
49
|
+
"greeting": "Ready to review.",
|
|
50
|
+
"outputDir": "."
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Editor Hooks
|
|
55
|
+
|
|
56
|
+
Generate editor-specific configuration files for your agent:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
soleri hooks add claude-code # .claude/settings.json with lifecycle hooks
|
|
60
|
+
soleri hooks add cursor # .cursorrules
|
|
61
|
+
soleri hooks add windsurf # .windsurfrules
|
|
62
|
+
soleri hooks add copilot # .github/copilot-instructions.md
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Development Workflow
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
soleri create my-agent # Scaffold
|
|
69
|
+
cd my-agent
|
|
70
|
+
npm install # Install dependencies
|
|
71
|
+
npm run build # Build
|
|
72
|
+
soleri dev # Run locally
|
|
73
|
+
soleri doctor # Verify everything works
|
|
74
|
+
soleri hooks add claude-code # Add editor hooks
|
|
75
|
+
soleri add-domain security # Add a domain later
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## How It Works
|
|
79
|
+
|
|
80
|
+
The CLI wraps [`@soleri/forge`](../forge) — the same scaffolding engine that powers AI-driven agent creation via MCP. The CLI provides a terminal-first interface for the same operations.
|
|
81
|
+
|
|
82
|
+
## Development
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# From monorepo root
|
|
86
|
+
npm install
|
|
87
|
+
npm run build --workspace=@soleri/cli
|
|
88
|
+
npm run test --workspace=@soleri/cli
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Requirements
|
|
92
|
+
|
|
93
|
+
- Node.js 18+
|
|
94
|
+
- npm 8+
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
Apache-2.0
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import { addDomain } from '@soleri/forge/lib';
|
|
3
|
+
import { detectAgent } from '../utils/agent-context.js';
|
|
4
|
+
export function registerAddDomain(program) {
|
|
5
|
+
program
|
|
6
|
+
.command('add-domain')
|
|
7
|
+
.argument('<domain>', 'Domain name in kebab-case (e.g., "security")')
|
|
8
|
+
.option('--no-build', 'Skip the build step after adding the domain')
|
|
9
|
+
.description('Add a new knowledge domain to the agent in the current directory')
|
|
10
|
+
.action(async (domain, opts) => {
|
|
11
|
+
const ctx = detectAgent();
|
|
12
|
+
if (!ctx) {
|
|
13
|
+
p.log.error('No agent project detected in current directory. Run this from an agent root.');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const s = p.spinner();
|
|
17
|
+
s.start(`Adding domain "${domain}" to ${ctx.agentId}...`);
|
|
18
|
+
try {
|
|
19
|
+
const result = await addDomain({
|
|
20
|
+
agentPath: ctx.agentPath,
|
|
21
|
+
domain,
|
|
22
|
+
noBuild: !opts.build,
|
|
23
|
+
});
|
|
24
|
+
s.stop(result.success ? result.summary : 'Failed');
|
|
25
|
+
if (result.warnings.length > 0) {
|
|
26
|
+
for (const w of result.warnings) {
|
|
27
|
+
p.log.warn(w);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (!result.success) {
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
s.stop('Failed');
|
|
36
|
+
p.log.error(err instanceof Error ? err.message : String(err));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=add-domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-domain.js","sourceRoot":"","sources":["../../src/commands/add-domain.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,QAAQ,CAAC,UAAU,EAAE,8CAA8C,CAAC;SACpE,MAAM,CAAC,YAAY,EAAE,6CAA6C,CAAC;SACnE,WAAW,CAAC,kEAAkE,CAAC;SAC/E,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAwB,EAAE,EAAE;QACzD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QACtB,CAAC,CAAC,KAAK,CAAC,kBAAkB,MAAM,QAAQ,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC;QAE1D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;gBAC7B,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,MAAM;gBACN,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK;aACrB,CAAC,CAAC;YAEH,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAEnD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAChC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACjB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import * as p from '@clack/prompts';
|
|
4
|
+
import { previewScaffold, scaffold, AgentConfigSchema } from '@soleri/forge/lib';
|
|
5
|
+
import { runCreateWizard } from '../prompts/create-wizard.js';
|
|
6
|
+
export function registerCreate(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('create')
|
|
9
|
+
.argument('[name]', 'Agent ID (kebab-case)')
|
|
10
|
+
.option('-c, --config <path>', 'Path to JSON config file (skip interactive prompts)')
|
|
11
|
+
.description('Create a new Soleri agent')
|
|
12
|
+
.action(async (name, opts) => {
|
|
13
|
+
try {
|
|
14
|
+
let config;
|
|
15
|
+
if (opts?.config) {
|
|
16
|
+
// Non-interactive: read from config file
|
|
17
|
+
const configPath = resolve(opts.config);
|
|
18
|
+
if (!existsSync(configPath)) {
|
|
19
|
+
p.log.error(`Config file not found: ${configPath}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const raw = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
23
|
+
const parsed = AgentConfigSchema.safeParse(raw);
|
|
24
|
+
if (!parsed.success) {
|
|
25
|
+
p.log.error(`Invalid config: ${parsed.error.message}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
config = parsed.data;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Interactive wizard
|
|
32
|
+
config = await runCreateWizard(name);
|
|
33
|
+
if (!config) {
|
|
34
|
+
p.outro('Cancelled.');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Preview
|
|
39
|
+
const preview = previewScaffold(config);
|
|
40
|
+
p.log.info(`Will create ${preview.files.length} files in ${preview.agentDir}`);
|
|
41
|
+
p.log.info(`Facades: ${preview.facades.map((f) => f.name).join(', ')}`);
|
|
42
|
+
p.log.info(`Domains: ${preview.domains.join(', ')}`);
|
|
43
|
+
const confirmed = await p.confirm({ message: 'Create agent?' });
|
|
44
|
+
if (p.isCancel(confirmed) || !confirmed) {
|
|
45
|
+
p.outro('Cancelled.');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// Scaffold
|
|
49
|
+
const s = p.spinner();
|
|
50
|
+
s.start('Scaffolding agent...');
|
|
51
|
+
const result = scaffold(config);
|
|
52
|
+
s.stop(result.success ? 'Agent created!' : 'Scaffolding failed');
|
|
53
|
+
if (result.success) {
|
|
54
|
+
p.note(result.summary, 'Next steps');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
p.log.error(result.summary);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
p.outro('Done!');
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
p.log.error(err instanceof Error ? err.message : String(err));
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import * as p from '@clack/prompts';
|
|
3
|
+
import { detectAgent } from '../utils/agent-context.js';
|
|
4
|
+
export function registerDev(program) {
|
|
5
|
+
program
|
|
6
|
+
.command('dev')
|
|
7
|
+
.description('Run the agent in development mode (stdio MCP server)')
|
|
8
|
+
.action(() => {
|
|
9
|
+
const ctx = detectAgent();
|
|
10
|
+
if (!ctx) {
|
|
11
|
+
p.log.error('No agent project detected in current directory. Run this from an agent root.');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
p.log.info(`Starting ${ctx.agentId} in dev mode...`);
|
|
15
|
+
const child = spawn('npx', ['tsx', 'src/index.ts'], {
|
|
16
|
+
cwd: ctx.agentPath,
|
|
17
|
+
stdio: 'inherit',
|
|
18
|
+
env: { ...process.env },
|
|
19
|
+
});
|
|
20
|
+
child.on('error', (err) => {
|
|
21
|
+
p.log.error(`Failed to start: ${err.message}`);
|
|
22
|
+
p.log.info('Make sure tsx is available: npm install -g tsx');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
25
|
+
child.on('exit', (code, signal) => {
|
|
26
|
+
if (signal) {
|
|
27
|
+
p.log.warn(`Process terminated by signal ${signal}`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
process.exit(code ?? 0);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC;QAErD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE;YAClD,GAAG,EAAE,GAAG,CAAC,SAAS;YAClB,KAAK,EAAE,SAAS;YAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC/C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAChC,IAAI,MAAM,EAAE,CAAC;gBACX,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,gCAAgC,MAAM,EAAE,CAAC,CAAC;gBACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { runAllChecks } from '../utils/checks.js';
|
|
2
|
+
import * as log from '../utils/logger.js';
|
|
3
|
+
export function registerDoctor(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('doctor')
|
|
6
|
+
.description('Check system health and agent project status')
|
|
7
|
+
.action(() => {
|
|
8
|
+
log.heading('Soleri Doctor');
|
|
9
|
+
const results = runAllChecks();
|
|
10
|
+
let hasFailures = false;
|
|
11
|
+
for (const r of results) {
|
|
12
|
+
if (r.status === 'pass')
|
|
13
|
+
log.pass(r.label, r.detail);
|
|
14
|
+
else if (r.status === 'warn')
|
|
15
|
+
log.warn(r.label, r.detail);
|
|
16
|
+
else {
|
|
17
|
+
log.fail(r.label, r.detail);
|
|
18
|
+
hasFailures = true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
console.log();
|
|
22
|
+
if (hasFailures) {
|
|
23
|
+
log.info('Some checks failed. Fix the issues above and run soleri doctor again.');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
log.info('All checks passed!');
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAE1C,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8CAA8C,CAAC;SAC3D,MAAM,CAAC,GAAG,EAAE;QACX,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAE7B,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;QAC/B,IAAI,WAAW,GAAG,KAAK,CAAC;QAExB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;iBAChD,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;iBACrD,CAAC;gBACJ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC5B,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;QAEd,IAAI,WAAW,EAAE,CAAC;YAChB,GAAG,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;YAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { SUPPORTED_EDITORS } from '../hooks/templates.js';
|
|
2
|
+
import { installHooks, removeHooks, detectInstalledHooks } from '../hooks/generator.js';
|
|
3
|
+
import { detectAgent } from '../utils/agent-context.js';
|
|
4
|
+
import * as log from '../utils/logger.js';
|
|
5
|
+
export function registerHooks(program) {
|
|
6
|
+
const hooks = program.command('hooks').description('Manage editor hooks for this agent');
|
|
7
|
+
hooks
|
|
8
|
+
.command('add')
|
|
9
|
+
.argument('<editor>', `Editor: ${SUPPORTED_EDITORS.join(', ')}`)
|
|
10
|
+
.description('Generate editor hooks/config files')
|
|
11
|
+
.action((editor) => {
|
|
12
|
+
if (!isValidEditor(editor)) {
|
|
13
|
+
log.fail(`Unknown editor "${editor}". Supported: ${SUPPORTED_EDITORS.join(', ')}`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const ctx = detectAgent();
|
|
17
|
+
if (!ctx) {
|
|
18
|
+
log.fail('No agent project detected in current directory.');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
const files = installHooks(editor, ctx.agentPath);
|
|
22
|
+
for (const f of files) {
|
|
23
|
+
log.pass(`Created ${f}`);
|
|
24
|
+
}
|
|
25
|
+
log.info(`${editor} hooks installed for ${ctx.agentId}`);
|
|
26
|
+
});
|
|
27
|
+
hooks
|
|
28
|
+
.command('remove')
|
|
29
|
+
.argument('<editor>', `Editor: ${SUPPORTED_EDITORS.join(', ')}`)
|
|
30
|
+
.description('Remove editor hooks/config files')
|
|
31
|
+
.action((editor) => {
|
|
32
|
+
if (!isValidEditor(editor)) {
|
|
33
|
+
log.fail(`Unknown editor "${editor}". Supported: ${SUPPORTED_EDITORS.join(', ')}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
const ctx = detectAgent();
|
|
37
|
+
if (!ctx) {
|
|
38
|
+
log.fail('No agent project detected in current directory.');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const removed = removeHooks(editor, ctx.agentPath);
|
|
42
|
+
if (removed.length === 0) {
|
|
43
|
+
log.info(`No ${editor} hooks found to remove.`);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
for (const f of removed) {
|
|
47
|
+
log.warn(`Removed ${f}`);
|
|
48
|
+
}
|
|
49
|
+
log.info(`${editor} hooks removed from ${ctx.agentId}`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
hooks
|
|
53
|
+
.command('list')
|
|
54
|
+
.description('Show which editor hooks are installed')
|
|
55
|
+
.action(() => {
|
|
56
|
+
const ctx = detectAgent();
|
|
57
|
+
if (!ctx) {
|
|
58
|
+
log.fail('No agent project detected in current directory.');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const installed = detectInstalledHooks(ctx.agentPath);
|
|
62
|
+
log.heading(`Editor hooks for ${ctx.agentId}`);
|
|
63
|
+
for (const editor of SUPPORTED_EDITORS) {
|
|
64
|
+
if (installed.includes(editor)) {
|
|
65
|
+
log.pass(editor, 'installed');
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
log.dim(` ${editor} — not installed`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function isValidEditor(editor) {
|
|
74
|
+
return SUPPORTED_EDITORS.includes(editor);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import * as p from '@clack/prompts';
|
|
3
|
+
import { installKnowledge } from '@soleri/forge/lib';
|
|
4
|
+
import { detectAgent } from '../utils/agent-context.js';
|
|
5
|
+
export function registerInstallKnowledge(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('install-knowledge')
|
|
8
|
+
.argument('<pack>', 'Path to knowledge bundle file or directory')
|
|
9
|
+
.option('--no-facades', 'Skip facade generation for new domains')
|
|
10
|
+
.description('Install knowledge packs into the agent in the current directory')
|
|
11
|
+
.action(async (pack, opts) => {
|
|
12
|
+
const ctx = detectAgent();
|
|
13
|
+
if (!ctx) {
|
|
14
|
+
p.log.error('No agent project detected in current directory. Run this from an agent root.');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const bundlePath = resolve(pack);
|
|
18
|
+
const s = p.spinner();
|
|
19
|
+
s.start(`Installing knowledge from ${bundlePath}...`);
|
|
20
|
+
try {
|
|
21
|
+
const result = await installKnowledge({
|
|
22
|
+
agentPath: ctx.agentPath,
|
|
23
|
+
bundlePath,
|
|
24
|
+
generateFacades: opts.facades,
|
|
25
|
+
});
|
|
26
|
+
s.stop(result.success ? result.summary : 'Installation failed');
|
|
27
|
+
if (result.warnings.length > 0) {
|
|
28
|
+
for (const w of result.warnings) {
|
|
29
|
+
p.log.warn(w);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (!result.success) {
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
s.stop('Installation failed');
|
|
38
|
+
p.log.error(err instanceof Error ? err.message : String(err));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=install-knowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-knowledge.js","sourceRoot":"","sources":["../../src/commands/install-knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,QAAQ,CAAC,QAAQ,EAAE,4CAA4C,CAAC;SAChE,MAAM,CAAC,cAAc,EAAE,wCAAwC,CAAC;SAChE,WAAW,CAAC,iEAAiE,CAAC;SAC9E,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,IAA0B,EAAE,EAAE;QACzD,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAEjC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;QACtB,CAAC,CAAC,KAAK,CAAC,6BAA6B,UAAU,KAAK,CAAC,CAAC;QAEtD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;gBACpC,SAAS,EAAE,GAAG,CAAC,SAAS;gBACxB,UAAU;gBACV,eAAe,EAAE,IAAI,CAAC,OAAO;aAC9B,CAAC,CAAC;YAEH,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;YAEhE,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAChC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAC9B,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { listAgents } from '@soleri/forge/lib';
|
|
3
|
+
import * as log from '../utils/logger.js';
|
|
4
|
+
function pad(s, len) {
|
|
5
|
+
return s.length >= len ? s.slice(0, len) : s + ' '.repeat(len - s.length);
|
|
6
|
+
}
|
|
7
|
+
export function registerList(program) {
|
|
8
|
+
program
|
|
9
|
+
.command('list')
|
|
10
|
+
.argument('[dir]', 'Directory to scan for agents', process.cwd())
|
|
11
|
+
.description('List all Soleri agents in a directory')
|
|
12
|
+
.action((dir) => {
|
|
13
|
+
const targetDir = resolve(dir);
|
|
14
|
+
const agents = listAgents(targetDir);
|
|
15
|
+
if (agents.length === 0) {
|
|
16
|
+
log.info(`No agents found in ${targetDir}`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
log.heading(`Agents in ${targetDir}`);
|
|
20
|
+
// Table header
|
|
21
|
+
console.log(` ${pad('ID', 16)}${pad('Domains', 26)}${pad('Built', 8)}${pad('Deps', 8)}Path`);
|
|
22
|
+
console.log(' ' + '-'.repeat(80));
|
|
23
|
+
for (const agent of agents) {
|
|
24
|
+
const built = agent.hasDistDir ? '✓' : '✗';
|
|
25
|
+
const deps = agent.hasNodeModules ? '✓' : '✗';
|
|
26
|
+
const domains = agent.domains.join(', ') || '(none)';
|
|
27
|
+
const truncDomains = domains.length > 25 ? domains.slice(0, 22) + '...' : domains;
|
|
28
|
+
console.log(` ${pad(agent.id, 16)}${pad(truncDomains, 26)}${pad(built, 8)}${pad(deps, 8)}${agent.path}`);
|
|
29
|
+
}
|
|
30
|
+
console.log(`\n ${agents.length} agent(s) found`);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAE1C,SAAS,GAAG,CAAC,CAAS,EAAE,GAAW;IACjC,OAAO,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,QAAQ,CAAC,OAAO,EAAE,8BAA8B,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAChE,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,CAAC,GAAW,EAAE,EAAE;QACtB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QAErC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,GAAG,CAAC,OAAO,CAAC,aAAa,SAAS,EAAE,CAAC,CAAC;QAEtC,eAAe;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC9F,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAEnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;YACrD,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;YAClF,OAAO,CAAC,GAAG,CACT,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAC7F,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,iBAAiB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type EditorId } from './templates.js';
|
|
2
|
+
/**
|
|
3
|
+
* Install editor hooks for the given editor.
|
|
4
|
+
* Returns list of files written.
|
|
5
|
+
*/
|
|
6
|
+
export declare function installHooks(editor: EditorId, agentPath: string): string[];
|
|
7
|
+
/**
|
|
8
|
+
* Remove editor hooks for the given editor.
|
|
9
|
+
* Returns list of files removed.
|
|
10
|
+
*/
|
|
11
|
+
export declare function removeHooks(editor: EditorId, agentPath: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Detect which editors have hooks installed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectInstalledHooks(agentPath: string): EditorId[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook file generator — writes and removes editor hook files.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';
|
|
5
|
+
import { join, dirname } from 'node:path';
|
|
6
|
+
import { getEditorFiles, SUPPORTED_EDITORS } from './templates.js';
|
|
7
|
+
/**
|
|
8
|
+
* Install editor hooks for the given editor.
|
|
9
|
+
* Returns list of files written.
|
|
10
|
+
*/
|
|
11
|
+
export function installHooks(editor, agentPath) {
|
|
12
|
+
const files = getEditorFiles(editor, agentPath);
|
|
13
|
+
const written = [];
|
|
14
|
+
const overwritten = [];
|
|
15
|
+
for (const [relPath, content] of Object.entries(files)) {
|
|
16
|
+
const absPath = join(agentPath, relPath);
|
|
17
|
+
if (existsSync(absPath))
|
|
18
|
+
overwritten.push(relPath);
|
|
19
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
20
|
+
writeFileSync(absPath, content, 'utf-8');
|
|
21
|
+
written.push(relPath);
|
|
22
|
+
}
|
|
23
|
+
if (overwritten.length > 0) {
|
|
24
|
+
console.warn(`Warning: overwritten existing file(s): ${overwritten.join(', ')}`);
|
|
25
|
+
}
|
|
26
|
+
return written;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Remove editor hooks for the given editor.
|
|
30
|
+
* Returns list of files removed.
|
|
31
|
+
*/
|
|
32
|
+
export function removeHooks(editor, agentPath) {
|
|
33
|
+
const files = getEditorFiles(editor, agentPath);
|
|
34
|
+
const removed = [];
|
|
35
|
+
for (const relPath of Object.keys(files)) {
|
|
36
|
+
const absPath = join(agentPath, relPath);
|
|
37
|
+
if (existsSync(absPath)) {
|
|
38
|
+
unlinkSync(absPath);
|
|
39
|
+
removed.push(relPath);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return removed;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Detect which editors have hooks installed.
|
|
46
|
+
*/
|
|
47
|
+
export function detectInstalledHooks(agentPath) {
|
|
48
|
+
const installed = [];
|
|
49
|
+
for (const editor of SUPPORTED_EDITORS) {
|
|
50
|
+
const files = getEditorFiles(editor, agentPath);
|
|
51
|
+
const allExist = Object.keys(files).every((relPath) => existsSync(join(agentPath, relPath)));
|
|
52
|
+
if (allExist) {
|
|
53
|
+
installed.push(editor);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return installed;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/hooks/generator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAiB,MAAM,gBAAgB,CAAC;AAElF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAgB,EAAE,SAAiB;IAC9D,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,UAAU,CAAC,OAAO,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnD,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,0CAA0C,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAgB,EAAE,SAAiB;IAC7D,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,UAAU,CAAC,OAAO,CAAC,CAAC;YACpB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,KAAK,MAAM,MAAM,IAAI,iBAAiB,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7F,IAAI,QAAQ,EAAE,CAAC;YACb,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|