@soleri/cli 0.0.1 → 1.0.1

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 (67) hide show
  1. package/README.md +98 -0
  2. package/dist/commands/add-domain.d.ts +2 -0
  3. package/dist/commands/add-domain.js +41 -0
  4. package/dist/commands/add-domain.js.map +1 -0
  5. package/dist/commands/create.d.ts +2 -0
  6. package/dist/commands/create.js +68 -0
  7. package/dist/commands/create.js.map +1 -0
  8. package/dist/commands/dev.d.ts +2 -0
  9. package/dist/commands/dev.js +34 -0
  10. package/dist/commands/dev.js.map +1 -0
  11. package/dist/commands/doctor.d.ts +2 -0
  12. package/dist/commands/doctor.js +31 -0
  13. package/dist/commands/doctor.js.map +1 -0
  14. package/dist/commands/hooks.d.ts +2 -0
  15. package/dist/commands/hooks.js +76 -0
  16. package/dist/commands/hooks.js.map +1 -0
  17. package/dist/commands/install-knowledge.d.ts +2 -0
  18. package/dist/commands/install-knowledge.js +43 -0
  19. package/dist/commands/install-knowledge.js.map +1 -0
  20. package/dist/commands/list.d.ts +2 -0
  21. package/dist/commands/list.js +33 -0
  22. package/dist/commands/list.js.map +1 -0
  23. package/dist/hooks/generator.d.ts +15 -0
  24. package/dist/hooks/generator.js +58 -0
  25. package/dist/hooks/generator.js.map +1 -0
  26. package/dist/hooks/templates.d.ts +3 -0
  27. package/dist/hooks/templates.js +156 -0
  28. package/dist/hooks/templates.js.map +1 -0
  29. package/dist/main.d.ts +2 -0
  30. package/dist/main.js +23 -0
  31. package/dist/main.js.map +1 -0
  32. package/dist/prompts/create-wizard.d.ts +6 -0
  33. package/dist/prompts/create-wizard.js +126 -0
  34. package/dist/prompts/create-wizard.js.map +1 -0
  35. package/dist/utils/agent-context.d.ts +12 -0
  36. package/dist/utils/agent-context.js +31 -0
  37. package/dist/utils/agent-context.js.map +1 -0
  38. package/dist/utils/checks.d.ts +12 -0
  39. package/dist/utils/checks.js +138 -0
  40. package/dist/utils/checks.js.map +1 -0
  41. package/dist/utils/logger.d.ts +10 -0
  42. package/dist/utils/logger.js +33 -0
  43. package/dist/utils/logger.js.map +1 -0
  44. package/package.json +40 -4
  45. package/src/__tests__/add-domain.test.ts +117 -0
  46. package/src/__tests__/create.test.ts +92 -0
  47. package/src/__tests__/dev.test.ts +62 -0
  48. package/src/__tests__/doctor.test.ts +121 -0
  49. package/src/__tests__/hooks.test.ts +133 -0
  50. package/src/__tests__/install-knowledge.test.ts +117 -0
  51. package/src/__tests__/list.test.ts +80 -0
  52. package/src/commands/add-domain.ts +46 -0
  53. package/src/commands/create.ts +73 -0
  54. package/src/commands/dev.ts +39 -0
  55. package/src/commands/doctor.ts +33 -0
  56. package/src/commands/hooks.ts +86 -0
  57. package/src/commands/install-knowledge.ts +49 -0
  58. package/src/commands/list.ts +42 -0
  59. package/src/hooks/generator.ts +65 -0
  60. package/src/hooks/templates.ts +185 -0
  61. package/src/main.ts +27 -0
  62. package/src/prompts/create-wizard.ts +129 -0
  63. package/src/utils/agent-context.ts +38 -0
  64. package/src/utils/checks.ts +148 -0
  65. package/src/utils/logger.ts +39 -0
  66. package/tsconfig.json +21 -0
  67. package/vitest.config.ts +8 -0
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Editor-specific hook/config templates.
3
+ *
4
+ * Each template function reads agent identity and generates
5
+ * editor-appropriate configuration files.
6
+ */
7
+ import { detectAgent } from '../utils/agent-context.js';
8
+ export const SUPPORTED_EDITORS = ['claude-code', 'cursor', 'windsurf', 'copilot'];
9
+ /** Sanitize agent ID for safe interpolation into shell commands and templates. */
10
+ function sanitizeId(id) {
11
+ return id.replace(/[^a-z0-9-]/g, '');
12
+ }
13
+ function getAgentMeta(dir) {
14
+ const ctx = detectAgent(dir);
15
+ if (!ctx)
16
+ return null;
17
+ return { agentId: sanitizeId(ctx.agentId), packageName: ctx.packageName };
18
+ }
19
+ // ── Claude Code ──
20
+ function generateClaudeCodeSettings(dir) {
21
+ const meta = getAgentMeta(dir);
22
+ const agentId = meta?.agentId ?? 'my-agent';
23
+ const settings = JSON.stringify({
24
+ hooks: {
25
+ PreToolUse: [
26
+ {
27
+ matcher: '*',
28
+ hooks: [
29
+ {
30
+ type: 'command',
31
+ command: `echo "[${agentId}] tool: $TOOL_NAME"`,
32
+ },
33
+ ],
34
+ },
35
+ ],
36
+ PostToolUse: [
37
+ {
38
+ matcher: 'Edit|Write',
39
+ hooks: [
40
+ {
41
+ type: 'command',
42
+ command: `echo "[${agentId}] file changed"`,
43
+ },
44
+ ],
45
+ },
46
+ ],
47
+ SessionStart: [
48
+ {
49
+ hooks: [
50
+ {
51
+ type: 'command',
52
+ command: `echo "[${agentId}] session started"`,
53
+ },
54
+ ],
55
+ },
56
+ ],
57
+ },
58
+ }, null, 2);
59
+ return {
60
+ '.claude/settings.json': settings,
61
+ };
62
+ }
63
+ // ── Cursor ──
64
+ function generateCursorRules(dir) {
65
+ const meta = getAgentMeta(dir);
66
+ const agentId = meta?.agentId ?? 'my-agent';
67
+ const rules = `# ${agentId} — Cursor Rules
68
+ # Generated by soleri hooks add cursor
69
+
70
+ ## Agent Context
71
+ This project is a Soleri AI agent (${agentId}).
72
+ The agent uses the MCP protocol and is structured with facades, a vault, and a brain.
73
+
74
+ ## Key Directories
75
+ - src/facades/ — MCP tool facades (one per domain)
76
+ - src/intelligence/data/ — Knowledge bundles (JSON)
77
+ - src/identity/ — Persona definition
78
+ - src/activation/ — Activation and CLAUDE.md injection
79
+
80
+ ## Conventions
81
+ - All facades follow the FacadeConfig pattern from @soleri/core
82
+ - Knowledge entries use the pattern/anti-pattern/rule taxonomy
83
+ - Domain names are kebab-case
84
+ - Facade names use the pattern: {agentId}_{domain}
85
+ `;
86
+ return {
87
+ '.cursorrules': rules,
88
+ };
89
+ }
90
+ // ── Windsurf ──
91
+ function generateWindsurfRules(dir) {
92
+ const meta = getAgentMeta(dir);
93
+ const agentId = meta?.agentId ?? 'my-agent';
94
+ const rules = `# ${agentId} — Windsurf Rules
95
+ # Generated by soleri hooks add windsurf
96
+
97
+ ## Agent Context
98
+ This project is a Soleri AI agent (${agentId}).
99
+ The agent uses the MCP protocol and is structured with facades, a vault, and a brain.
100
+
101
+ ## Key Directories
102
+ - src/facades/ — MCP tool facades (one per domain)
103
+ - src/intelligence/data/ — Knowledge bundles (JSON)
104
+ - src/identity/ — Persona definition
105
+ - src/activation/ — Activation and CLAUDE.md injection
106
+
107
+ ## Conventions
108
+ - All facades follow the FacadeConfig pattern from @soleri/core
109
+ - Knowledge entries use the pattern/anti-pattern/rule taxonomy
110
+ - Domain names are kebab-case
111
+ - Facade names use the pattern: {agentId}_{domain}
112
+ `;
113
+ return {
114
+ '.windsurfrules': rules,
115
+ };
116
+ }
117
+ // ── GitHub Copilot ──
118
+ function generateCopilotInstructions(dir) {
119
+ const meta = getAgentMeta(dir);
120
+ const agentId = meta?.agentId ?? 'my-agent';
121
+ const instructions = `# ${agentId} — Copilot Instructions
122
+ <!-- Generated by soleri hooks add copilot -->
123
+
124
+ ## Agent Context
125
+ This project is a Soleri AI agent (${agentId}).
126
+ The agent uses the MCP protocol and is structured with facades, a vault, and a brain.
127
+
128
+ ## Key Directories
129
+ - \`src/facades/\` — MCP tool facades (one per domain)
130
+ - \`src/intelligence/data/\` — Knowledge bundles (JSON)
131
+ - \`src/identity/\` — Persona definition
132
+ - \`src/activation/\` — Activation and CLAUDE.md injection
133
+
134
+ ## Conventions
135
+ - All facades follow the FacadeConfig pattern from @soleri/core
136
+ - Knowledge entries use the pattern/anti-pattern/rule taxonomy
137
+ - Domain names are kebab-case
138
+ - Facade names use the pattern: \`{agentId}_{domain}\`
139
+ `;
140
+ return {
141
+ '.github/copilot-instructions.md': instructions,
142
+ };
143
+ }
144
+ export function getEditorFiles(editor, dir) {
145
+ switch (editor) {
146
+ case 'claude-code':
147
+ return generateClaudeCodeSettings(dir);
148
+ case 'cursor':
149
+ return generateCursorRules(dir);
150
+ case 'windsurf':
151
+ return generateWindsurfRules(dir);
152
+ case 'copilot':
153
+ return generateCopilotInstructions(dir);
154
+ }
155
+ }
156
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/hooks/templates.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { registerCreate } from './commands/create.js';
4
+ import { registerList } from './commands/list.js';
5
+ import { registerAddDomain } from './commands/add-domain.js';
6
+ import { registerInstallKnowledge } from './commands/install-knowledge.js';
7
+ import { registerDev } from './commands/dev.js';
8
+ import { registerDoctor } from './commands/doctor.js';
9
+ import { registerHooks } from './commands/hooks.js';
10
+ const program = new Command();
11
+ program
12
+ .name('soleri')
13
+ .description('Developer CLI for creating and managing Soleri AI agents')
14
+ .version('1.0.0');
15
+ registerCreate(program);
16
+ registerList(program);
17
+ registerAddDomain(program);
18
+ registerInstallKnowledge(program);
19
+ registerDev(program);
20
+ registerDoctor(program);
21
+ registerHooks(program);
22
+ program.parse();
23
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAClC,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,aAAa,CAAC,OAAO,CAAC,CAAC;AAEvB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { AgentConfig } from '@soleri/forge/lib';
2
+ /**
3
+ * Run the interactive create wizard and return an AgentConfig.
4
+ * Returns null if the user cancels.
5
+ */
6
+ export declare function runCreateWizard(initialName?: string): Promise<AgentConfig | null>;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Interactive create wizard using @clack/prompts.
3
+ */
4
+ import * as p from '@clack/prompts';
5
+ /**
6
+ * Run the interactive create wizard and return an AgentConfig.
7
+ * Returns null if the user cancels.
8
+ */
9
+ export async function runCreateWizard(initialName) {
10
+ p.intro('Create a new Soleri agent');
11
+ const id = initialName ??
12
+ (await p.text({
13
+ message: 'Agent ID (kebab-case)',
14
+ placeholder: 'my-agent',
15
+ validate: (v = '') => {
16
+ if (!/^[a-z][a-z0-9-]*$/.test(v))
17
+ return 'Must be kebab-case (e.g., "my-agent")';
18
+ },
19
+ }));
20
+ if (p.isCancel(id))
21
+ return null;
22
+ const name = (await p.text({
23
+ message: 'Display name',
24
+ placeholder: 'My Agent',
25
+ validate: (v) => {
26
+ if (!v || v.length > 50)
27
+ return 'Required (max 50 chars)';
28
+ },
29
+ }));
30
+ if (p.isCancel(name))
31
+ return null;
32
+ const role = (await p.text({
33
+ message: 'Role (one line)',
34
+ placeholder: 'A helpful AI assistant for...',
35
+ validate: (v) => {
36
+ if (!v || v.length > 100)
37
+ return 'Required (max 100 chars)';
38
+ },
39
+ }));
40
+ if (p.isCancel(role))
41
+ return null;
42
+ const description = (await p.text({
43
+ message: 'Description',
44
+ placeholder: 'This agent helps developers with...',
45
+ validate: (v) => {
46
+ if (!v || v.length < 10 || v.length > 500)
47
+ return 'Required (10-500 chars)';
48
+ },
49
+ }));
50
+ if (p.isCancel(description))
51
+ return null;
52
+ const domainsRaw = (await p.text({
53
+ message: 'Domains (comma-separated, kebab-case)',
54
+ placeholder: 'api-design, security, testing',
55
+ validate: (v = '') => {
56
+ const parts = v
57
+ .split(',')
58
+ .map((s) => s.trim())
59
+ .filter(Boolean);
60
+ if (parts.length === 0)
61
+ return 'At least one domain required';
62
+ for (const d of parts) {
63
+ if (!/^[a-z][a-z0-9-]*$/.test(d))
64
+ return `Invalid domain "${d}" — must be kebab-case`;
65
+ }
66
+ },
67
+ }));
68
+ if (p.isCancel(domainsRaw))
69
+ return null;
70
+ const domains = domainsRaw
71
+ .split(',')
72
+ .map((s) => s.trim())
73
+ .filter(Boolean);
74
+ const principlesRaw = (await p.text({
75
+ message: 'Principles (one per line)',
76
+ placeholder: 'Security first\nSimplicity over cleverness\nTest everything',
77
+ validate: (v = '') => {
78
+ const lines = v
79
+ .split('\n')
80
+ .map((s) => s.trim())
81
+ .filter(Boolean);
82
+ if (lines.length === 0)
83
+ return 'At least one principle required';
84
+ if (lines.length > 10)
85
+ return 'Max 10 principles';
86
+ },
87
+ }));
88
+ if (p.isCancel(principlesRaw))
89
+ return null;
90
+ const principles = principlesRaw
91
+ .split('\n')
92
+ .map((s) => s.trim())
93
+ .filter(Boolean);
94
+ const greeting = (await p.text({
95
+ message: 'Greeting message',
96
+ placeholder: `Hello! I'm ${name}, your AI assistant for...`,
97
+ validate: (v) => {
98
+ if (!v || v.length < 10 || v.length > 300)
99
+ return 'Required (10-300 chars)';
100
+ },
101
+ }));
102
+ if (p.isCancel(greeting))
103
+ return null;
104
+ const outputDir = (await p.text({
105
+ message: 'Output directory',
106
+ defaultValue: process.cwd(),
107
+ placeholder: process.cwd(),
108
+ validate: (v) => {
109
+ if (!v)
110
+ return 'Required';
111
+ },
112
+ }));
113
+ if (p.isCancel(outputDir))
114
+ return null;
115
+ return {
116
+ id,
117
+ name,
118
+ role,
119
+ description,
120
+ domains,
121
+ principles,
122
+ greeting,
123
+ outputDir,
124
+ };
125
+ }
126
+ //# sourceMappingURL=create-wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-wizard.js","sourceRoot":"","sources":["../../src/prompts/create-wizard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ interface AgentContext {
2
+ agentPath: string;
3
+ agentId: string;
4
+ packageName: string;
5
+ hasBrain: boolean;
6
+ }
7
+ /**
8
+ * Detect an agent in the given directory.
9
+ * Returns null if the directory is not a valid agent project.
10
+ */
11
+ export declare function detectAgent(dir?: string): AgentContext | null;
12
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Detect and validate an agent project in the current working directory.
3
+ */
4
+ import { existsSync, readFileSync } from 'node:fs';
5
+ import { join, resolve } from 'node:path';
6
+ /**
7
+ * Detect an agent in the given directory.
8
+ * Returns null if the directory is not a valid agent project.
9
+ */
10
+ export function detectAgent(dir) {
11
+ const agentPath = resolve(dir ?? process.cwd());
12
+ const pkgPath = join(agentPath, 'package.json');
13
+ if (!existsSync(pkgPath))
14
+ return null;
15
+ try {
16
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
17
+ const name = pkg.name ?? '';
18
+ if (!name.endsWith('-mcp'))
19
+ return null;
20
+ return {
21
+ agentPath,
22
+ agentId: name.replace(/-mcp$/, ''),
23
+ packageName: name,
24
+ hasBrain: existsSync(join(agentPath, 'src', 'brain')),
25
+ };
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ //# sourceMappingURL=agent-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-context.js","sourceRoot":"","sources":["../../src/utils/agent-context.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAS1C;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAEhD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,IAAI,GAAW,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAExC,OAAO;YACL,SAAS;YACT,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAClC,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;SACtD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ interface CheckResult {
2
+ status: 'pass' | 'fail' | 'warn';
3
+ label: string;
4
+ detail?: string;
5
+ }
6
+ export declare function checkNodeVersion(): CheckResult;
7
+ export declare function checkNpm(): CheckResult;
8
+ export declare function checkAgentProject(dir?: string): CheckResult;
9
+ export declare function checkAgentBuild(dir?: string): CheckResult;
10
+ export declare function checkNodeModules(dir?: string): CheckResult;
11
+ export declare function runAllChecks(dir?: string): CheckResult[];
12
+ export {};
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Health check utilities for the doctor command.
3
+ */
4
+ import { existsSync, readFileSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { execFileSync } from 'node:child_process';
7
+ import { homedir } from 'node:os';
8
+ import { detectAgent } from './agent-context.js';
9
+ export function checkNodeVersion() {
10
+ const [major] = process.versions.node.split('.').map(Number);
11
+ if (major >= 18) {
12
+ return { status: 'pass', label: 'Node.js', detail: `v${process.versions.node}` };
13
+ }
14
+ return { status: 'fail', label: 'Node.js', detail: `v${process.versions.node} (>=18 required)` };
15
+ }
16
+ export function checkNpm() {
17
+ try {
18
+ const version = execFileSync('npm', ['--version'], { encoding: 'utf-8' }).trim();
19
+ return { status: 'pass', label: 'npm', detail: `v${version}` };
20
+ }
21
+ catch {
22
+ return { status: 'fail', label: 'npm', detail: 'not found' };
23
+ }
24
+ }
25
+ function checkTsx() {
26
+ try {
27
+ const version = execFileSync('npx', ['tsx', '--version'], {
28
+ encoding: 'utf-8',
29
+ timeout: 10_000,
30
+ }).trim();
31
+ return { status: 'pass', label: 'tsx', detail: `v${version}` };
32
+ }
33
+ catch {
34
+ return { status: 'warn', label: 'tsx', detail: 'not found — needed for soleri dev' };
35
+ }
36
+ }
37
+ export function checkAgentProject(dir) {
38
+ const ctx = detectAgent(dir);
39
+ if (!ctx) {
40
+ return { status: 'warn', label: 'Agent project', detail: 'not detected in current directory' };
41
+ }
42
+ return { status: 'pass', label: 'Agent project', detail: `${ctx.agentId} (${ctx.packageName})` };
43
+ }
44
+ export function checkAgentBuild(dir) {
45
+ const ctx = detectAgent(dir);
46
+ if (!ctx)
47
+ return { status: 'warn', label: 'Agent build', detail: 'no agent detected' };
48
+ if (!existsSync(join(ctx.agentPath, 'dist'))) {
49
+ return { status: 'fail', label: 'Agent build', detail: 'dist/ not found — run npm run build' };
50
+ }
51
+ if (!existsSync(join(ctx.agentPath, 'dist', 'index.js'))) {
52
+ return {
53
+ status: 'fail',
54
+ label: 'Agent build',
55
+ detail: 'dist/index.js not found — run npm run build',
56
+ };
57
+ }
58
+ return { status: 'pass', label: 'Agent build', detail: 'dist/index.js exists' };
59
+ }
60
+ export function checkNodeModules(dir) {
61
+ const ctx = detectAgent(dir);
62
+ if (!ctx)
63
+ return { status: 'warn', label: 'Dependencies', detail: 'no agent detected' };
64
+ if (!existsSync(join(ctx.agentPath, 'node_modules'))) {
65
+ return {
66
+ status: 'fail',
67
+ label: 'Dependencies',
68
+ detail: 'node_modules/ not found — run npm install',
69
+ };
70
+ }
71
+ return { status: 'pass', label: 'Dependencies', detail: 'node_modules/ exists' };
72
+ }
73
+ function checkMcpRegistration(dir) {
74
+ const ctx = detectAgent(dir);
75
+ if (!ctx)
76
+ return { status: 'warn', label: 'MCP registration', detail: 'no agent detected' };
77
+ const claudeJsonPath = join(homedir(), '.claude.json');
78
+ if (!existsSync(claudeJsonPath)) {
79
+ return {
80
+ status: 'warn',
81
+ label: 'MCP registration',
82
+ detail: '~/.claude.json not found',
83
+ };
84
+ }
85
+ try {
86
+ const config = JSON.parse(readFileSync(claudeJsonPath, 'utf-8'));
87
+ const servers = config.mcpServers ?? {};
88
+ if (ctx.agentId in servers) {
89
+ return {
90
+ status: 'pass',
91
+ label: 'MCP registration',
92
+ detail: `registered as "${ctx.agentId}"`,
93
+ };
94
+ }
95
+ return {
96
+ status: 'warn',
97
+ label: 'MCP registration',
98
+ detail: `"${ctx.agentId}" not found in ~/.claude.json`,
99
+ };
100
+ }
101
+ catch {
102
+ return { status: 'fail', label: 'MCP registration', detail: 'failed to parse ~/.claude.json' };
103
+ }
104
+ }
105
+ function checkCognee() {
106
+ const url = process.env.COGNEE_URL ?? 'http://localhost:8000/';
107
+ let host;
108
+ try {
109
+ host = new URL(url).host;
110
+ }
111
+ catch {
112
+ return { status: 'warn', label: 'Cognee', detail: `invalid COGNEE_URL: ${url}` };
113
+ }
114
+ try {
115
+ execFileSync('curl', ['-fsS', '--max-time', '5', url], { stdio: 'ignore', timeout: 7_000 });
116
+ return { status: 'pass', label: 'Cognee', detail: `available at ${host}` };
117
+ }
118
+ catch {
119
+ return {
120
+ status: 'warn',
121
+ label: 'Cognee',
122
+ detail: `not running at ${host} — vector search disabled (FTS5 still works)`,
123
+ };
124
+ }
125
+ }
126
+ export function runAllChecks(dir) {
127
+ return [
128
+ checkNodeVersion(),
129
+ checkNpm(),
130
+ checkTsx(),
131
+ checkAgentProject(dir),
132
+ checkNodeModules(dir),
133
+ checkAgentBuild(dir),
134
+ checkMcpRegistration(dir),
135
+ checkCognee(),
136
+ ];
137
+ }
138
+ //# sourceMappingURL=checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../../src/utils/checks.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQjD,MAAM,UAAU,gBAAgB;IAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7D,IAAI,KAAK,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACjF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,QAAQ;IACf,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE;YACxD,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,EAAE,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAC;IACvF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC5C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAC;IACjG,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAEvF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;IACjG,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,aAAa;YACpB,MAAM,EAAE,6CAA6C;SACtD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;AAClF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAExF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACrD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,2CAA2C;SACpD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;AACnF,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAY;IACxC,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAE5F,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,kBAAkB;YACzB,MAAM,EAAE,0BAA0B;SACnC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;QACxC,IAAI,GAAG,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC;YAC3B,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,KAAK,EAAE,kBAAkB;gBACzB,MAAM,EAAE,kBAAkB,GAAG,CAAC,OAAO,GAAG;aACzC,CAAC;QACJ,CAAC;QACD,OAAO;YACL,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,kBAAkB;YACzB,MAAM,EAAE,IAAI,GAAG,CAAC,OAAO,+BAA+B;SACvD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;IACjG,CAAC;AACH,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,wBAAwB,CAAC;IAC/D,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,uBAAuB,GAAG,EAAE,EAAE,CAAC;IACnF,CAAC;IACD,IAAI,CAAC;QACH,YAAY,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5F,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,IAAI,EAAE,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,QAAQ;YACf,MAAM,EAAE,kBAAkB,IAAI,8CAA8C;SAC7E,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,OAAO;QACL,gBAAgB,EAAE;QAClB,QAAQ,EAAE;QACV,QAAQ,EAAE;QACV,iBAAiB,CAAC,GAAG,CAAC;QACtB,gBAAgB,CAAC,GAAG,CAAC;QACrB,eAAe,CAAC,GAAG,CAAC;QACpB,oBAAoB,CAAC,GAAG,CAAC;QACzB,WAAW,EAAE;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Simple colored output helpers for the CLI.
3
+ * Uses ANSI codes directly — no chalk dependency needed.
4
+ */
5
+ export declare function pass(label: string, detail?: string): void;
6
+ export declare function fail(label: string, detail?: string): void;
7
+ export declare function warn(label: string, detail?: string): void;
8
+ export declare function info(message: string): void;
9
+ export declare function heading(title: string): void;
10
+ export declare function dim(message: string): void;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Simple colored output helpers for the CLI.
3
+ * Uses ANSI codes directly — no chalk dependency needed.
4
+ */
5
+ const RESET = '\x1b[0m';
6
+ const GREEN = '\x1b[32m';
7
+ const RED = '\x1b[31m';
8
+ const YELLOW = '\x1b[33m';
9
+ const CYAN = '\x1b[36m';
10
+ const DIM = '\x1b[2m';
11
+ const BOLD = '\x1b[1m';
12
+ export function pass(label, detail) {
13
+ const suffix = detail ? ` ${DIM}${detail}${RESET}` : '';
14
+ console.log(` ${GREEN}✓${RESET} ${label}${suffix}`);
15
+ }
16
+ export function fail(label, detail) {
17
+ const suffix = detail ? ` ${DIM}${detail}${RESET}` : '';
18
+ console.log(` ${RED}✗${RESET} ${label}${suffix}`);
19
+ }
20
+ export function warn(label, detail) {
21
+ const suffix = detail ? ` ${DIM}${detail}${RESET}` : '';
22
+ console.log(` ${YELLOW}!${RESET} ${label}${suffix}`);
23
+ }
24
+ export function info(message) {
25
+ console.log(` ${CYAN}ℹ${RESET} ${message}`);
26
+ }
27
+ export function heading(title) {
28
+ console.log(`\n${BOLD}${title}${RESET}\n`);
29
+ }
30
+ export function dim(message) {
31
+ console.log(` ${DIM}${message}${RESET}`);
32
+ }
33
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,KAAK,GAAG,SAAS,CAAC;AACxB,MAAM,KAAK,GAAG,UAAU,CAAC;AACzB,MAAM,GAAG,GAAG,UAAU,CAAC;AACvB,MAAM,MAAM,GAAG,UAAU,CAAC;AAC1B,MAAM,IAAI,GAAG,UAAU,CAAC;AACxB,MAAM,GAAG,GAAG,SAAS,CAAC;AACtB,MAAM,IAAI,GAAG,SAAS,CAAC;AAEvB,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,MAAe;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,OAAe;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC"}
package/package.json CHANGED
@@ -1,10 +1,46 @@
1
1
  {
2
2
  "name": "@soleri/cli",
3
- "version": "0.0.1",
4
- "description": "Soleri cli",
5
- "license": "MIT",
3
+ "version": "1.0.1",
4
+ "description": "Developer CLI for creating and managing Soleri AI agents.",
5
+ "keywords": [
6
+ "agent",
7
+ "ai",
8
+ "cli",
9
+ "mcp",
10
+ "scaffold",
11
+ "soleri"
12
+ ],
13
+ "homepage": "https://soleri.dev",
14
+ "license": "Apache-2.0",
15
+ "author": "adrozdenko",
6
16
  "repository": {
7
17
  "type": "git",
8
- "url": "https://github.com/adrozdenko/soleri.git"
18
+ "url": "https://github.com/adrozdenko/soleri.git",
19
+ "directory": "packages/cli"
20
+ },
21
+ "bin": {
22
+ "soleri": "dist/main.js"
23
+ },
24
+ "type": "module",
25
+ "main": "dist/main.js",
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "scripts": {
30
+ "dev": "tsx src/main.ts",
31
+ "build": "tsc",
32
+ "start": "node dist/main.js",
33
+ "typecheck": "tsc --noEmit",
34
+ "test": "vitest run",
35
+ "test:watch": "vitest",
36
+ "test:coverage": "vitest run --coverage"
37
+ },
38
+ "dependencies": {
39
+ "@clack/prompts": "^1.0.0",
40
+ "@soleri/forge": "^4.1.0",
41
+ "commander": "^13.0.0"
42
+ },
43
+ "engines": {
44
+ "node": ">=18.0.0"
9
45
  }
10
46
  }