@soleri/cli 1.9.0 → 1.10.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 (94) hide show
  1. package/README.md +4 -0
  2. package/dist/commands/agent.d.ts +8 -0
  3. package/dist/commands/agent.js +150 -0
  4. package/dist/commands/agent.js.map +1 -0
  5. package/dist/commands/create.js +38 -6
  6. package/dist/commands/create.js.map +1 -1
  7. package/dist/commands/install-knowledge.js +65 -3
  8. package/dist/commands/install-knowledge.js.map +1 -1
  9. package/dist/commands/install.d.ts +2 -0
  10. package/dist/commands/install.js +80 -0
  11. package/dist/commands/install.js.map +1 -0
  12. package/dist/commands/pack.d.ts +10 -0
  13. package/dist/commands/pack.js +512 -0
  14. package/dist/commands/pack.js.map +1 -0
  15. package/dist/commands/skills.d.ts +8 -0
  16. package/dist/commands/skills.js +167 -0
  17. package/dist/commands/skills.js.map +1 -0
  18. package/dist/commands/uninstall.d.ts +2 -0
  19. package/dist/commands/uninstall.js +74 -0
  20. package/dist/commands/uninstall.js.map +1 -0
  21. package/dist/hook-packs/installer.d.ts +0 -7
  22. package/dist/hook-packs/installer.js +1 -14
  23. package/dist/hook-packs/installer.js.map +1 -1
  24. package/dist/hook-packs/installer.ts +1 -18
  25. package/dist/hook-packs/registry.d.ts +2 -1
  26. package/dist/hook-packs/registry.ts +1 -1
  27. package/dist/main.js +40 -1
  28. package/dist/main.js.map +1 -1
  29. package/dist/prompts/archetypes.d.ts +1 -0
  30. package/dist/prompts/archetypes.js +177 -62
  31. package/dist/prompts/archetypes.js.map +1 -1
  32. package/dist/prompts/create-wizard.d.ts +3 -3
  33. package/dist/prompts/create-wizard.js +99 -50
  34. package/dist/prompts/create-wizard.js.map +1 -1
  35. package/dist/prompts/playbook.d.ts +8 -7
  36. package/dist/prompts/playbook.js +201 -15
  37. package/dist/prompts/playbook.js.map +1 -1
  38. package/dist/utils/checks.d.ts +0 -1
  39. package/dist/utils/checks.js +1 -1
  40. package/dist/utils/checks.js.map +1 -1
  41. package/package.json +1 -1
  42. package/src/__tests__/archetypes.test.ts +84 -0
  43. package/src/__tests__/doctor.test.ts +2 -2
  44. package/src/__tests__/wizard-e2e.mjs +508 -0
  45. package/src/commands/agent.ts +181 -0
  46. package/src/commands/create.ts +152 -104
  47. package/src/commands/install-knowledge.ts +75 -4
  48. package/src/commands/install.ts +101 -0
  49. package/src/commands/pack.ts +585 -0
  50. package/src/commands/skills.ts +191 -0
  51. package/src/commands/uninstall.ts +93 -0
  52. package/src/hook-packs/installer.ts +1 -18
  53. package/src/hook-packs/registry.ts +1 -1
  54. package/src/main.ts +42 -1
  55. package/src/prompts/archetypes.ts +193 -62
  56. package/src/prompts/create-wizard.ts +117 -61
  57. package/src/prompts/playbook.ts +207 -21
  58. package/src/utils/checks.ts +1 -1
  59. package/code-reviewer/.claude/hookify.focus-ring-required.local.md +0 -21
  60. package/code-reviewer/.claude/hookify.no-ai-attribution.local.md +0 -18
  61. package/code-reviewer/.claude/hookify.no-any-types.local.md +0 -18
  62. package/code-reviewer/.claude/hookify.no-console-log.local.md +0 -21
  63. package/code-reviewer/.claude/hookify.no-important.local.md +0 -18
  64. package/code-reviewer/.claude/hookify.no-inline-styles.local.md +0 -21
  65. package/code-reviewer/.claude/hookify.semantic-html.local.md +0 -18
  66. package/code-reviewer/.claude/hookify.ux-touch-targets.local.md +0 -18
  67. package/code-reviewer/.mcp.json +0 -11
  68. package/code-reviewer/README.md +0 -346
  69. package/code-reviewer/package-lock.json +0 -4484
  70. package/code-reviewer/package.json +0 -45
  71. package/code-reviewer/scripts/copy-assets.js +0 -15
  72. package/code-reviewer/scripts/setup.sh +0 -130
  73. package/code-reviewer/skills/brainstorming/SKILL.md +0 -170
  74. package/code-reviewer/skills/code-patrol/SKILL.md +0 -176
  75. package/code-reviewer/skills/context-resume/SKILL.md +0 -143
  76. package/code-reviewer/skills/executing-plans/SKILL.md +0 -201
  77. package/code-reviewer/skills/fix-and-learn/SKILL.md +0 -164
  78. package/code-reviewer/skills/health-check/SKILL.md +0 -225
  79. package/code-reviewer/skills/second-opinion/SKILL.md +0 -142
  80. package/code-reviewer/skills/systematic-debugging/SKILL.md +0 -230
  81. package/code-reviewer/skills/verification-before-completion/SKILL.md +0 -170
  82. package/code-reviewer/skills/writing-plans/SKILL.md +0 -207
  83. package/code-reviewer/src/__tests__/facades.test.ts +0 -598
  84. package/code-reviewer/src/activation/activate.ts +0 -125
  85. package/code-reviewer/src/activation/claude-md-content.ts +0 -217
  86. package/code-reviewer/src/activation/inject-claude-md.ts +0 -113
  87. package/code-reviewer/src/extensions/index.ts +0 -47
  88. package/code-reviewer/src/extensions/ops/example.ts +0 -28
  89. package/code-reviewer/src/identity/persona.ts +0 -62
  90. package/code-reviewer/src/index.ts +0 -278
  91. package/code-reviewer/src/intelligence/data/architecture.json +0 -5
  92. package/code-reviewer/src/intelligence/data/code-review.json +0 -5
  93. package/code-reviewer/tsconfig.json +0 -30
  94. package/code-reviewer/vitest.config.ts +0 -23
@@ -1,278 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
- import { dirname, join } from 'node:path';
6
- import { fileURLToPath } from 'node:url';
7
-
8
- import {
9
- createAgentRuntime,
10
- createSemanticFacades,
11
- createDomainFacades,
12
- registerAllFacades,
13
- seedDefaultPlaybooks,
14
- wrapWithMiddleware,
15
- } from '@soleri/core';
16
- import type { OpDefinition, AgentExtensions } from '@soleri/core';
17
- import { z } from 'zod';
18
- import { PERSONA, getPersonaPrompt } from './identity/persona.js';
19
- import { activateAgent, deactivateAgent } from './activation/activate.js';
20
- import { injectClaudeMd, injectClaudeMdGlobal, hasAgentMarker } from './activation/inject-claude-md.js';
21
-
22
- const __dirname = dirname(fileURLToPath(import.meta.url));
23
-
24
- async function main(): Promise<void> {
25
- // ─── Runtime — vault, brain, planner, curator, LLM, key pools ───
26
- const runtime = createAgentRuntime({
27
- agentId: 'code-reviewer',
28
- dataDir: join(__dirname, 'intelligence', 'data'),
29
- });
30
-
31
- const tag = PERSONA.name.toLowerCase();
32
-
33
- // Seed built-in playbooks (idempotent)
34
- const seedResult = seedDefaultPlaybooks(runtime.vault);
35
- if (seedResult.seeded > 0) {
36
- console.error(`[${tag}] Seeded ${seedResult.seeded} built-in playbooks`);
37
- }
38
-
39
- const stats = runtime.vault.stats();
40
- console.error(`[${tag}] Vault: ${stats.totalEntries} entries, Brain: ${runtime.brain.getVocabularySize()} terms`);
41
-
42
- const llmAvail = runtime.llmClient.isAvailable();
43
- console.error(`[${tag}] LLM: OpenAI ${llmAvail.openai ? 'available' : 'not configured'}, Anthropic ${llmAvail.anthropic ? 'available' : 'not configured'}`);
44
-
45
- // ─── Agent-specific ops (reference persona + activation) ────────
46
- const agentOps: OpDefinition[] = [
47
- {
48
- name: 'health',
49
- description: 'Health check — vault status and agent info.',
50
- auth: 'read',
51
- handler: async () => {
52
- const s = runtime.vault.stats();
53
- return {
54
- status: 'ok',
55
- agent: { name: PERSONA.name, role: PERSONA.role },
56
- vault: { entries: s.totalEntries, domains: Object.keys(s.byDomain) },
57
- };
58
- },
59
- },
60
- {
61
- name: 'identity',
62
- description: 'Get agent identity — name, role, principles. Uses IdentityManager with PERSONA fallback.',
63
- auth: 'read',
64
- handler: async () => {
65
- const identity = runtime.identityManager.getIdentity('code-reviewer');
66
- if (identity) return identity;
67
- return PERSONA;
68
- },
69
- },
70
- {
71
- name: 'activate',
72
- description: 'Activate agent persona — returns full context for Claude to adopt. Say "Hello, Code Reviewer!" to trigger.',
73
- auth: 'read',
74
- schema: z.object({
75
- projectPath: z.string().optional().default('.'),
76
- deactivate: z.boolean().optional(),
77
- }),
78
- handler: async (params) => {
79
- if (params.deactivate) {
80
- return deactivateAgent();
81
- }
82
- // Seed identity from PERSONA on first activation
83
- if (!runtime.identityManager.getIdentity('code-reviewer')) {
84
- runtime.identityManager.setIdentity('code-reviewer', {
85
- name: PERSONA.name,
86
- role: PERSONA.role,
87
- description: PERSONA.description ?? '',
88
- personality: PERSONA.principles ?? [],
89
- changedBy: 'system',
90
- changeReason: 'Initial identity seeded from PERSONA',
91
- });
92
- }
93
- return activateAgent(runtime.vault, (params.projectPath as string) ?? '.', runtime.planner);
94
- },
95
- },
96
- {
97
- name: 'inject_claude_md',
98
- description: 'Inject agent sections into CLAUDE.md — project-level or global (~/.claude/CLAUDE.md). Idempotent.',
99
- auth: 'write',
100
- schema: z.object({
101
- projectPath: z.string().optional().default('.'),
102
- global: z.boolean().optional().describe('If true, inject into ~/.claude/CLAUDE.md instead of project-level'),
103
- }),
104
- handler: async (params) => {
105
- if (params.global) {
106
- return injectClaudeMdGlobal();
107
- }
108
- return injectClaudeMd((params.projectPath as string) ?? '.');
109
- },
110
- },
111
- {
112
- name: 'setup',
113
- description: 'Check setup status — CLAUDE.md configured? Vault has entries? What to do next?',
114
- auth: 'read',
115
- schema: z.object({
116
- projectPath: z.string().optional().default('.'),
117
- }),
118
- handler: async (params) => {
119
- const { existsSync } = await import('node:fs');
120
- const { join: joinPath } = await import('node:path');
121
- const { homedir } = await import('node:os');
122
- const projectPath = (params.projectPath as string) ?? '.';
123
-
124
- const projectClaudeMd = joinPath(projectPath, 'CLAUDE.md');
125
- const globalClaudeMd = joinPath(homedir(), '.claude', 'CLAUDE.md');
126
-
127
- const projectExists = existsSync(projectClaudeMd);
128
- const projectHasAgent = hasAgentMarker(projectClaudeMd);
129
- const globalExists = existsSync(globalClaudeMd);
130
- const globalHasAgent = hasAgentMarker(globalClaudeMd);
131
-
132
- const s = runtime.vault.stats();
133
-
134
- const recommendations: string[] = [];
135
- if (!globalHasAgent && !projectHasAgent) {
136
- recommendations.push('No CLAUDE.md configured — run inject_claude_md with global: true for all projects, or without for this project');
137
- } else if (!globalHasAgent) {
138
- recommendations.push('Global ~/.claude/CLAUDE.md not configured — run inject_claude_md with global: true to enable in all projects');
139
- }
140
- if (s.totalEntries === 0) {
141
- recommendations.push('Vault is empty — add intelligence data or capture knowledge via domain facades');
142
- }
143
-
144
- // Check hook status
145
- const { readdirSync } = await import('node:fs');
146
- const agentClaudeDir = joinPath(__dirname, '..', '.claude');
147
- const globalClaudeDir = joinPath(homedir(), '.claude');
148
-
149
- const hookStatus = { agent: [] as string[], global: [] as string[], missing: [] as string[] };
150
-
151
- if (existsSync(agentClaudeDir)) {
152
- try {
153
- const agentHooks = readdirSync(agentClaudeDir)
154
- .filter((f: string) => f.startsWith('hookify.') && f.endsWith('.local.md'))
155
- .map((f: string) => f.replace('hookify.', '').replace('.local.md', ''));
156
- hookStatus.agent = agentHooks;
157
-
158
- for (const hook of agentHooks) {
159
- if (existsSync(joinPath(globalClaudeDir, `hookify.${hook}.local.md`))) {
160
- hookStatus.global.push(hook);
161
- } else {
162
- hookStatus.missing.push(hook);
163
- }
164
- }
165
- } catch {
166
- // ignore read errors
167
- }
168
- }
169
-
170
- if (hookStatus.missing.length > 0) {
171
- recommendations.push(`${hookStatus.missing.length} hook(s) not installed globally — run scripts/setup.sh`);
172
- }
173
-
174
- if (recommendations.length === 0) {
175
- recommendations.push('Code Reviewer is fully set up and ready!');
176
- }
177
-
178
- return {
179
- agent: { name: PERSONA.name, role: PERSONA.role },
180
- claude_md: {
181
- project: { exists: projectExists, has_agent_section: projectHasAgent },
182
- global: { exists: globalExists, has_agent_section: globalHasAgent },
183
- },
184
- vault: { entries: s.totalEntries, domains: Object.keys(s.byDomain) },
185
- hooks: hookStatus,
186
- recommendations,
187
- };
188
- },
189
- },
190
- ];
191
-
192
- // ─── Assemble facades ──────────────────────────────────────────
193
- const semanticFacades = createSemanticFacades(runtime, 'code-reviewer');
194
- const agentFacade = {
195
- name: 'code-reviewer_core',
196
- description: 'Agent-specific operations — health, identity, activation, CLAUDE.md injection, setup.',
197
- ops: agentOps,
198
- };
199
-
200
- const domainFacades = createDomainFacades(runtime, 'code-reviewer', ["code-review","architecture"]);
201
-
202
- // ─── User extensions (auto-discovered from src/extensions/) ────
203
- let extensions: AgentExtensions = {};
204
- try {
205
- const ext = await import('./extensions/index.js');
206
- const loader = ext.default ?? (ext as Record<string, unknown>).loadExtensions;
207
- if (typeof loader === 'function') {
208
- extensions = loader(runtime);
209
- } else if (typeof loader === 'object') {
210
- extensions = loader;
211
- }
212
- if (extensions.ops?.length || extensions.facades?.length || extensions.middleware?.length) {
213
- console.error(`[${tag}] Extensions loaded: ${extensions.ops?.length ?? 0} ops, ${extensions.facades?.length ?? 0} facades, ${extensions.middleware?.length ?? 0} middleware`);
214
- }
215
- } catch {
216
- // No extensions directory or load error — run vanilla
217
- }
218
-
219
- // Merge user ops into agent facade
220
- if (extensions.ops?.length) {
221
- agentFacade.ops.push(...extensions.ops);
222
- }
223
-
224
- // Collect user facades
225
- const userFacades = extensions.facades ?? [];
226
-
227
- // Apply middleware to all facades
228
- const allFacades = [...semanticFacades, agentFacade, ...domainFacades, ...userFacades];
229
- if (extensions.middleware?.length) {
230
- wrapWithMiddleware(allFacades, extensions.middleware);
231
- }
232
-
233
- // Lifecycle: onStartup
234
- if (extensions.hooks?.onStartup) {
235
- await extensions.hooks.onStartup(runtime);
236
- }
237
-
238
- // ─── MCP server ────────────────────────────────────────────────
239
- const server = new McpServer({
240
- name: 'code-reviewer-mcp',
241
- version: '1.0.0',
242
- });
243
-
244
- server.prompt('persona', 'Get agent persona and principles', async () => ({
245
- messages: [{ role: 'assistant' as const, content: { type: 'text' as const, text: getPersonaPrompt() } }],
246
- }));
247
-
248
- registerAllFacades(server, allFacades);
249
-
250
- console.error(`[${tag}] ${PERSONA.name} — ${PERSONA.role}`);
251
- console.error(`[${tag}] Registered ${allFacades.length} facades with ${allFacades.reduce((sum, f) => sum + f.ops.length, 0)} operations`);
252
-
253
- // ─── Transport + shutdown ──────────────────────────────────────
254
- const transport = new StdioServerTransport();
255
- await server.connect(transport);
256
- console.error(`[${tag}] Connected via stdio transport`);
257
- console.error(`[${tag}] Say "Hello, ${PERSONA.name}!" to activate`);
258
-
259
- const shutdown = async (): Promise<void> => {
260
- console.error(`[${tag}] Shutting down...`);
261
- if (extensions.hooks?.onShutdown) {
262
- try {
263
- await extensions.hooks.onShutdown(runtime);
264
- } catch (err) {
265
- console.error(`[${tag}] Extension shutdown error:`, err);
266
- }
267
- }
268
- runtime.close();
269
- process.exit(0);
270
- };
271
- process.on('SIGTERM', shutdown);
272
- process.on('SIGINT', shutdown);
273
- }
274
-
275
- main().catch((err) => {
276
- console.error('[code-reviewer] Fatal error:', err);
277
- process.exit(1);
278
- });
@@ -1,5 +0,0 @@
1
- {
2
- "domain": "architecture",
3
- "version": "1.0.0",
4
- "entries": []
5
- }
@@ -1,5 +0,0 @@
1
- {
2
- "domain": "code-review",
3
- "version": "1.0.0",
4
- "entries": []
5
- }
@@ -1,30 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "lib": [
7
- "ES2022"
8
- ],
9
- "outDir": "dist",
10
- "rootDir": "src",
11
- "strict": true,
12
- "esModuleInterop": true,
13
- "resolveJsonModule": true,
14
- "declaration": true,
15
- "declarationMap": true,
16
- "sourceMap": true,
17
- "forceConsistentCasingInFileNames": true,
18
- "skipLibCheck": true,
19
- "noEmitOnError": true
20
- },
21
- "include": [
22
- "src/**/*.ts"
23
- ],
24
- "exclude": [
25
- "node_modules",
26
- "dist",
27
- "src/**/*.test.ts",
28
- "src/__tests__/**"
29
- ]
30
- }
@@ -1,23 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- environment: 'node',
6
- pool: 'forks',
7
- poolOptions: {
8
- forks: {
9
- singleFork: true,
10
- maxForks: 2,
11
- minForks: 1,
12
- },
13
- },
14
- testTimeout: 30_000,
15
- hookTimeout: 10_000,
16
- teardownTimeout: 5_000,
17
- coverage: {
18
- provider: 'v8',
19
- include: ['src/**/*.ts'],
20
- exclude: ['src/**/*.test.ts', 'src/__tests__/**', 'src/index.ts'],
21
- },
22
- },
23
- });