@soleri/cli 1.3.0 → 1.4.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.
@@ -83,7 +83,7 @@ export function registerCreate(program) {
83
83
  // Install selected hook packs
84
84
  if (selectedPacks.length > 0) {
85
85
  for (const packName of selectedPacks) {
86
- const { installed } = installPack(packName);
86
+ const { installed } = installPack(packName, { projectDir: result.agentDir });
87
87
  if (installed.length > 0) {
88
88
  p.log.success(`Hook pack "${packName}" installed (${installed.length} hooks)`);
89
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerGovernance(program: Command): void;
@@ -0,0 +1,97 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { detectAgent } from '../utils/agent-context.js';
5
+ import * as log from '../utils/logger.js';
6
+ const VALID_PRESETS = ['strict', 'moderate', 'permissive'];
7
+ export function registerGovernance(program) {
8
+ program
9
+ .command('governance')
10
+ .description('Manage vault governance policy for an agent')
11
+ .option('--preset <name>', 'Apply preset (strict|moderate|permissive)')
12
+ .option('--show', 'Show current policy and quota status')
13
+ .action(async (opts) => {
14
+ const agent = detectAgent();
15
+ if (!agent) {
16
+ log.fail('Not in a Soleri agent project', 'Run from an agent directory');
17
+ process.exit(1);
18
+ }
19
+ const dbPath = join(homedir(), `.${agent.agentId}`, 'vault.db');
20
+ if (!existsSync(dbPath)) {
21
+ log.fail('Vault DB not found', `Expected ${dbPath}`);
22
+ log.info('Run the agent once to initialize its vault database.');
23
+ process.exit(1);
24
+ }
25
+ // Dynamic import to avoid loading better-sqlite3 unless needed
26
+ const { Vault, Governance } = await import('@soleri/core');
27
+ const vault = new Vault(dbPath);
28
+ try {
29
+ const governance = new Governance(vault);
30
+ if (opts.preset) {
31
+ if (!VALID_PRESETS.includes(opts.preset)) {
32
+ log.fail('Invalid preset', `Must be one of: ${VALID_PRESETS.join(', ')}`);
33
+ process.exit(1);
34
+ }
35
+ governance.applyPreset(agent.agentId, opts.preset, 'soleri-cli');
36
+ log.heading('Governance — Preset Applied');
37
+ log.pass(`Preset "${opts.preset}" applied to ${agent.agentId}`);
38
+ console.log();
39
+ showPolicy(governance, agent.agentId);
40
+ }
41
+ else {
42
+ // Default: --show
43
+ log.heading('Governance — Current Policy');
44
+ showPolicy(governance, agent.agentId);
45
+ console.log();
46
+ showQuotaStatus(governance, agent.agentId);
47
+ }
48
+ }
49
+ finally {
50
+ vault.close();
51
+ }
52
+ });
53
+ }
54
+ function showPolicy(governance, agentId) {
55
+ const policy = governance.getPolicy(agentId);
56
+ log.info('Quotas:');
57
+ log.dim(` Max entries total: ${policy.quotas.maxEntriesTotal}`);
58
+ log.dim(` Max entries per category: ${policy.quotas.maxEntriesPerCategory}`);
59
+ log.dim(` Max entries per type: ${policy.quotas.maxEntriesPerType}`);
60
+ log.dim(` Warn at: ${policy.quotas.warnAtPercent}%`);
61
+ console.log();
62
+ log.info('Retention:');
63
+ log.dim(` Archive after: ${policy.retention.archiveAfterDays} days`);
64
+ log.dim(` Min hits to keep: ${policy.retention.minHitsToKeep}`);
65
+ log.dim(` Delete archived after: ${policy.retention.deleteArchivedAfterDays} days`);
66
+ console.log();
67
+ log.info('Auto-capture:');
68
+ log.dim(` Enabled: ${policy.autoCapture.enabled}`);
69
+ log.dim(` Require review: ${policy.autoCapture.requireReview}`);
70
+ log.dim(` Max pending proposals: ${policy.autoCapture.maxPendingProposals}`);
71
+ log.dim(` Auto-expire: ${policy.autoCapture.autoExpireDays} days`);
72
+ }
73
+ function showQuotaStatus(governance, agentId) {
74
+ const status = governance.getQuotaStatus(agentId);
75
+ log.info(`Quota usage: ${status.total} / ${status.maxTotal}`);
76
+ if (status.isWarning) {
77
+ log.warn('Approaching quota limit', `${Math.round((status.total / status.maxTotal) * 100)}% used`);
78
+ }
79
+ else {
80
+ log.pass('Within quota', `${Math.round((status.total / status.maxTotal) * 100)}% used`);
81
+ }
82
+ if (Object.keys(status.byType).length > 0) {
83
+ console.log();
84
+ log.info('By type:');
85
+ for (const [type, count] of Object.entries(status.byType)) {
86
+ log.dim(` ${type}: ${count}`);
87
+ }
88
+ }
89
+ if (Object.keys(status.byCategory).length > 0) {
90
+ console.log();
91
+ log.info('By category:');
92
+ for (const [cat, count] of Object.entries(status.byCategory)) {
93
+ log.dim(` ${cat}: ${count}`);
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=governance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance.js","sourceRoot":"","sources":["../../src/commands/governance.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -7,11 +7,12 @@ import { registerInstallKnowledge } from './commands/install-knowledge.js';
7
7
  import { registerDev } from './commands/dev.js';
8
8
  import { registerDoctor } from './commands/doctor.js';
9
9
  import { registerHooks } from './commands/hooks.js';
10
+ import { registerGovernance } from './commands/governance.js';
10
11
  const program = new Command();
11
12
  program
12
13
  .name('soleri')
13
14
  .description('Developer CLI for creating and managing Soleri AI agents')
14
- .version('1.0.0');
15
+ .version('1.4.0');
15
16
  registerCreate(program);
16
17
  registerList(program);
17
18
  registerAddDomain(program);
@@ -19,5 +20,6 @@ registerInstallKnowledge(program);
19
20
  registerDev(program);
20
21
  registerDoctor(program);
21
22
  registerHooks(program);
23
+ registerGovernance(program);
22
24
  program.parse();
23
25
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -1 +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"}
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;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,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;AACvB,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAE5B,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soleri/cli",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Developer CLI for creating and managing Soleri AI agents.",
5
5
  "keywords": [
6
6
  "agent",
@@ -37,6 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@clack/prompts": "^1.0.0",
40
+ "@soleri/core": "^2.0.0",
40
41
  "@soleri/forge": "^5.0.0",
41
42
  "commander": "^13.0.0"
42
43
  },
@@ -1,9 +1,10 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mkdirSync, rmSync, existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { mkdirSync, rmSync, existsSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { tmpdir } from 'node:os';
5
5
  import { previewScaffold, scaffold } from '@soleri/forge/lib';
6
6
  import type { AgentConfig } from '@soleri/forge/lib';
7
+ import { installPack } from '../hook-packs/installer.js';
7
8
 
8
9
  describe('create command', () => {
9
10
  let tempDir: string;
@@ -91,4 +92,112 @@ describe('create command', () => {
91
92
  expect(raw.id).toBe('test-agent');
92
93
  expect(raw.domains).toEqual(['testing', 'quality']);
93
94
  });
95
+
96
+ // ─── Hook pack integration tests ──────────────────────────────
97
+
98
+ it('should create .claude/ directory when hookPacks specified', () => {
99
+ const configWithHooks: AgentConfig = {
100
+ ...testConfig,
101
+ hookPacks: ['typescript-safety'],
102
+ };
103
+ const result = scaffold(configWithHooks);
104
+
105
+ expect(result.success).toBe(true);
106
+ expect(existsSync(join(tempDir, 'test-agent', '.claude'))).toBe(true);
107
+ });
108
+
109
+ it('should install hookify files to agent .claude/ via installPack', () => {
110
+ const configWithHooks: AgentConfig = {
111
+ ...testConfig,
112
+ hookPacks: ['typescript-safety'],
113
+ };
114
+ const result = scaffold(configWithHooks);
115
+ expect(result.success).toBe(true);
116
+
117
+ // Simulate what create.ts does: install packs into agent dir
118
+ const { installed } = installPack('typescript-safety', { projectDir: result.agentDir });
119
+ expect(installed.length).toBeGreaterThan(0);
120
+
121
+ // Verify hookify files exist in agent .claude/
122
+ const claudeDir = join(result.agentDir, '.claude');
123
+ const hookFiles = readdirSync(claudeDir).filter(
124
+ (f) => f.startsWith('hookify.') && f.endsWith('.local.md'),
125
+ );
126
+ expect(hookFiles.length).toBeGreaterThan(0);
127
+ expect(hookFiles.some((f) => f.includes('no-any-types'))).toBe(true);
128
+ });
129
+
130
+ it('should not create .claude/ when hookPacks is empty or undefined', () => {
131
+ const result = scaffold(testConfig);
132
+
133
+ expect(result.success).toBe(true);
134
+ expect(existsSync(join(tempDir, 'test-agent', '.claude'))).toBe(false);
135
+ });
136
+
137
+ it('should include hook packs in preview when hookPacks specified', () => {
138
+ const configWithHooks: AgentConfig = {
139
+ ...testConfig,
140
+ hookPacks: ['typescript-safety'],
141
+ };
142
+ const preview = previewScaffold(configWithHooks);
143
+
144
+ const hookEntry = preview.files.find((f) => f.path === '.claude/');
145
+ expect(hookEntry).toBeDefined();
146
+ expect(hookEntry!.description).toContain('typescript-safety');
147
+ });
148
+
149
+ it('should include Hook Packs section in CLAUDE.md when hookPacks specified', () => {
150
+ const configWithHooks: AgentConfig = {
151
+ ...testConfig,
152
+ hookPacks: ['typescript-safety'],
153
+ };
154
+ scaffold(configWithHooks);
155
+
156
+ const claudeMd = readFileSync(
157
+ join(tempDir, 'test-agent', 'src', 'activation', 'claude-md-content.ts'),
158
+ 'utf-8',
159
+ );
160
+ expect(claudeMd).toContain('Hook Packs');
161
+ expect(claudeMd).toContain('no-any-types');
162
+ });
163
+
164
+ it('should not include Hook Packs section in CLAUDE.md when hookPacks undefined', () => {
165
+ scaffold(testConfig);
166
+
167
+ const claudeMd = readFileSync(
168
+ join(tempDir, 'test-agent', 'src', 'activation', 'claude-md-content.ts'),
169
+ 'utf-8',
170
+ );
171
+ expect(claudeMd).not.toContain('Hook Packs');
172
+ });
173
+
174
+ it('should include hook copy logic in setup.sh when hookPacks specified', () => {
175
+ const configWithHooks: AgentConfig = {
176
+ ...testConfig,
177
+ hookPacks: ['typescript-safety'],
178
+ };
179
+ scaffold(configWithHooks);
180
+
181
+ const setupSh = readFileSync(join(tempDir, 'test-agent', 'scripts', 'setup.sh'), 'utf-8');
182
+ expect(setupSh).toContain('Installing hook packs');
183
+ expect(setupSh).toContain('hookify.');
184
+ expect(setupSh).toContain('GLOBAL_CLAUDE_DIR');
185
+ });
186
+
187
+ it('should not include hook copy logic in setup.sh when hookPacks undefined', () => {
188
+ scaffold(testConfig);
189
+
190
+ const setupSh = readFileSync(join(tempDir, 'test-agent', 'scripts', 'setup.sh'), 'utf-8');
191
+ expect(setupSh).not.toContain('Installing hook packs');
192
+ });
193
+
194
+ it('should mention hook packs in scaffold summary', () => {
195
+ const configWithHooks: AgentConfig = {
196
+ ...testConfig,
197
+ hookPacks: ['typescript-safety', 'a11y'],
198
+ };
199
+ const result = scaffold(configWithHooks);
200
+
201
+ expect(result.summary).toContain('2 hook pack(s) bundled in .claude/');
202
+ });
94
203
  });
@@ -93,7 +93,7 @@ export function registerCreate(program: Command): void {
93
93
  // Install selected hook packs
94
94
  if (selectedPacks.length > 0) {
95
95
  for (const packName of selectedPacks) {
96
- const { installed } = installPack(packName);
96
+ const { installed } = installPack(packName, { projectDir: result.agentDir });
97
97
  if (installed.length > 0) {
98
98
  p.log.success(`Hook pack "${packName}" installed (${installed.length} hooks)`);
99
99
  } else {
@@ -0,0 +1,114 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import type { Command } from 'commander';
5
+ import { detectAgent } from '../utils/agent-context.js';
6
+ import * as log from '../utils/logger.js';
7
+
8
+ const VALID_PRESETS = ['strict', 'moderate', 'permissive'] as const;
9
+
10
+ export function registerGovernance(program: Command): void {
11
+ program
12
+ .command('governance')
13
+ .description('Manage vault governance policy for an agent')
14
+ .option('--preset <name>', 'Apply preset (strict|moderate|permissive)')
15
+ .option('--show', 'Show current policy and quota status')
16
+ .action(async (opts: { preset?: string; show?: boolean }) => {
17
+ const agent = detectAgent();
18
+ if (!agent) {
19
+ log.fail('Not in a Soleri agent project', 'Run from an agent directory');
20
+ process.exit(1);
21
+ }
22
+
23
+ const dbPath = join(homedir(), `.${agent.agentId}`, 'vault.db');
24
+ if (!existsSync(dbPath)) {
25
+ log.fail('Vault DB not found', `Expected ${dbPath}`);
26
+ log.info('Run the agent once to initialize its vault database.');
27
+ process.exit(1);
28
+ }
29
+
30
+ // Dynamic import to avoid loading better-sqlite3 unless needed
31
+ const { Vault, Governance } = await import('@soleri/core');
32
+ const vault = new Vault(dbPath);
33
+
34
+ try {
35
+ const governance = new Governance(vault);
36
+
37
+ if (opts.preset) {
38
+ if (!VALID_PRESETS.includes(opts.preset as typeof VALID_PRESETS[number])) {
39
+ log.fail('Invalid preset', `Must be one of: ${VALID_PRESETS.join(', ')}`);
40
+ process.exit(1);
41
+ }
42
+
43
+ governance.applyPreset(
44
+ agent.agentId,
45
+ opts.preset as 'strict' | 'moderate' | 'permissive',
46
+ 'soleri-cli',
47
+ );
48
+ log.heading('Governance — Preset Applied');
49
+ log.pass(`Preset "${opts.preset}" applied to ${agent.agentId}`);
50
+ console.log();
51
+ showPolicy(governance, agent.agentId);
52
+ } else {
53
+ // Default: --show
54
+ log.heading('Governance — Current Policy');
55
+ showPolicy(governance, agent.agentId);
56
+ console.log();
57
+ showQuotaStatus(governance, agent.agentId);
58
+ }
59
+ } finally {
60
+ vault.close();
61
+ }
62
+ });
63
+ }
64
+
65
+ function showPolicy(governance: InstanceType<typeof import('@soleri/core').Governance>, agentId: string): void {
66
+ const policy = governance.getPolicy(agentId);
67
+
68
+ log.info('Quotas:');
69
+ log.dim(` Max entries total: ${policy.quotas.maxEntriesTotal}`);
70
+ log.dim(` Max entries per category: ${policy.quotas.maxEntriesPerCategory}`);
71
+ log.dim(` Max entries per type: ${policy.quotas.maxEntriesPerType}`);
72
+ log.dim(` Warn at: ${policy.quotas.warnAtPercent}%`);
73
+
74
+ console.log();
75
+ log.info('Retention:');
76
+ log.dim(` Archive after: ${policy.retention.archiveAfterDays} days`);
77
+ log.dim(` Min hits to keep: ${policy.retention.minHitsToKeep}`);
78
+ log.dim(` Delete archived after: ${policy.retention.deleteArchivedAfterDays} days`);
79
+
80
+ console.log();
81
+ log.info('Auto-capture:');
82
+ log.dim(` Enabled: ${policy.autoCapture.enabled}`);
83
+ log.dim(` Require review: ${policy.autoCapture.requireReview}`);
84
+ log.dim(` Max pending proposals: ${policy.autoCapture.maxPendingProposals}`);
85
+ log.dim(` Auto-expire: ${policy.autoCapture.autoExpireDays} days`);
86
+ }
87
+
88
+ function showQuotaStatus(governance: InstanceType<typeof import('@soleri/core').Governance>, agentId: string): void {
89
+ const status = governance.getQuotaStatus(agentId);
90
+
91
+ log.info(`Quota usage: ${status.total} / ${status.maxTotal}`);
92
+
93
+ if (status.isWarning) {
94
+ log.warn('Approaching quota limit', `${Math.round((status.total / status.maxTotal) * 100)}% used`);
95
+ } else {
96
+ log.pass('Within quota', `${Math.round((status.total / status.maxTotal) * 100)}% used`);
97
+ }
98
+
99
+ if (Object.keys(status.byType).length > 0) {
100
+ console.log();
101
+ log.info('By type:');
102
+ for (const [type, count] of Object.entries(status.byType)) {
103
+ log.dim(` ${type}: ${count}`);
104
+ }
105
+ }
106
+
107
+ if (Object.keys(status.byCategory).length > 0) {
108
+ console.log();
109
+ log.info('By category:');
110
+ for (const [cat, count] of Object.entries(status.byCategory)) {
111
+ log.dim(` ${cat}: ${count}`);
112
+ }
113
+ }
114
+ }
package/src/main.ts CHANGED
@@ -8,13 +8,14 @@ import { registerInstallKnowledge } from './commands/install-knowledge.js';
8
8
  import { registerDev } from './commands/dev.js';
9
9
  import { registerDoctor } from './commands/doctor.js';
10
10
  import { registerHooks } from './commands/hooks.js';
11
+ import { registerGovernance } from './commands/governance.js';
11
12
 
12
13
  const program = new Command();
13
14
 
14
15
  program
15
16
  .name('soleri')
16
17
  .description('Developer CLI for creating and managing Soleri AI agents')
17
- .version('1.0.0');
18
+ .version('1.4.0');
18
19
 
19
20
  registerCreate(program);
20
21
  registerList(program);
@@ -23,5 +24,6 @@ registerInstallKnowledge(program);
23
24
  registerDev(program);
24
25
  registerDoctor(program);
25
26
  registerHooks(program);
27
+ registerGovernance(program);
26
28
 
27
29
  program.parse();