@soleri/cli 1.3.0 → 1.5.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.
@@ -41,6 +41,15 @@ export function registerCreate(program) {
41
41
  let selectedPacks = [];
42
42
  if (config.hookPacks && config.hookPacks.length > 0) {
43
43
  selectedPacks = config.hookPacks;
44
+ // Validate pack names against registry — warn and skip unknown
45
+ const available = listPacks().map((pk) => pk.name);
46
+ const unknown = selectedPacks.filter((pk) => !available.includes(pk));
47
+ if (unknown.length > 0) {
48
+ for (const name of unknown) {
49
+ p.log.warn(`Unknown hook pack "${name}" — skipping. Available: ${available.join(', ')}`);
50
+ }
51
+ selectedPacks = selectedPacks.filter((pk) => available.includes(pk));
52
+ }
44
53
  }
45
54
  else if (!opts?.config) {
46
55
  const packs = listPacks();
@@ -83,7 +92,7 @@ export function registerCreate(program) {
83
92
  // Install selected hook packs
84
93
  if (selectedPacks.length > 0) {
85
94
  for (const packName of selectedPacks) {
86
- const { installed } = installPack(packName);
95
+ const { installed } = installPack(packName, { projectDir: result.agentDir });
87
96
  if (installed.length > 0) {
88
97
  p.log.success(`Hook pack "${packName}" installed (${installed.length} hooks)`);
89
98
  }
@@ -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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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerTest(program: Command): void;
@@ -0,0 +1,51 @@
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 registerTest(program) {
5
+ program
6
+ .command('test')
7
+ .description('Run agent tests via vitest')
8
+ .option('-w, --watch', 'Run in watch mode')
9
+ .option('--coverage', 'Run with coverage')
10
+ .allowUnknownOption(true)
11
+ .action((opts, cmd) => {
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 args = [];
18
+ if (opts.watch) {
19
+ // vitest (no "run") enables watch mode
20
+ args.push('vitest');
21
+ }
22
+ else {
23
+ args.push('vitest', 'run');
24
+ }
25
+ if (opts.coverage)
26
+ args.push('--coverage');
27
+ // Forward any extra args the user passed
28
+ const extra = cmd.args;
29
+ if (extra.length > 0)
30
+ args.push(...extra);
31
+ p.log.info(`Running tests for ${ctx.agentId}...`);
32
+ const child = spawn('npx', args, {
33
+ cwd: ctx.agentPath,
34
+ stdio: 'inherit',
35
+ env: { ...process.env },
36
+ });
37
+ child.on('error', (err) => {
38
+ p.log.error(`Failed to start: ${err.message}`);
39
+ p.log.info('Make sure vitest is available: npm install -D vitest');
40
+ process.exit(1);
41
+ });
42
+ child.on('exit', (code, signal) => {
43
+ if (signal) {
44
+ p.log.warn(`Process terminated by signal ${signal}`);
45
+ process.exit(1);
46
+ }
47
+ process.exit(code ?? 0);
48
+ });
49
+ });
50
+ }
51
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.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,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4BAA4B,CAAC;SACzC,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAAC;SAC1C,MAAM,CAAC,YAAY,EAAE,mBAAmB,CAAC;SACzC,kBAAkB,CAAC,IAAI,CAAC;SACxB,MAAM,CAAC,CAAC,IAA6C,EAAE,GAAG,EAAE,EAAE;QAC7D,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,IAAI,GAAa,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,uCAAuC;YACvC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE3C,yCAAyC;QACzC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAgB,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QAE1C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC;QAElD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE;YAC/B,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,sDAAsD,CAAC,CAAC;YACnE,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,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerUpgrade(program: Command): void;
@@ -0,0 +1,61 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { execFileSync } from 'node:child_process';
5
+ import * as log from '../utils/logger.js';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = dirname(__filename);
8
+ function getCurrentVersion() {
9
+ const pkgPath = join(__dirname, '..', '..', 'package.json');
10
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
11
+ return pkg.version;
12
+ }
13
+ function getLatestVersion() {
14
+ return execFileSync('npm', ['view', '@soleri/cli', 'version'], {
15
+ encoding: 'utf-8',
16
+ timeout: 10_000,
17
+ }).trim();
18
+ }
19
+ export function registerUpgrade(program) {
20
+ program
21
+ .command('upgrade')
22
+ .description('Upgrade @soleri/cli to the latest version')
23
+ .option('--check', 'Show current vs latest version without upgrading')
24
+ .action((opts) => {
25
+ const current = getCurrentVersion();
26
+ log.heading('@soleri/cli upgrade');
27
+ let latest;
28
+ try {
29
+ latest = getLatestVersion();
30
+ }
31
+ catch {
32
+ log.fail('Could not reach npm registry');
33
+ log.info('Check your internet connection and try again.');
34
+ process.exit(1);
35
+ }
36
+ if (current === latest) {
37
+ log.pass(`@soleri/cli@${current}`, 'already up to date');
38
+ return;
39
+ }
40
+ log.info(`Current: ${current}`);
41
+ log.info(`Latest: ${latest}`);
42
+ if (opts.check) {
43
+ log.dim(`Run "npm install -g @soleri/cli@latest" to upgrade.`);
44
+ return;
45
+ }
46
+ log.info('Upgrading...');
47
+ try {
48
+ execFileSync('npm', ['install', '-g', '@soleri/cli@latest'], {
49
+ stdio: 'inherit',
50
+ timeout: 60_000,
51
+ });
52
+ log.pass(`Upgraded to @soleri/cli@${latest}`);
53
+ }
54
+ catch {
55
+ log.fail('Upgrade failed');
56
+ log.info(`Try manually: npm install -g @soleri/cli@${latest}`);
57
+ process.exit(1);
58
+ }
59
+ });
60
+ }
61
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,KAAK,GAAG,MAAM,oBAAoB,CAAC;AAE1C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,SAAS,iBAAiB;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,OAAO,GAAG,CAAC,OAAiB,CAAC;AAC/B,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE;QAC7D,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,MAAM;KAChB,CAAC,CAAC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,SAAS,EAAE,kDAAkD,CAAC;SACrE,MAAM,CAAC,CAAC,IAAyB,EAAE,EAAE;QACpC,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;QAEpC,GAAG,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QAEnC,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YACvB,GAAG,CAAC,IAAI,CAAC,eAAe,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;QAE/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzB,IAAI,CAAC;YACH,YAAY,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,oBAAoB,CAAC,EAAE;gBAC3D,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,MAAM;aAChB,CAAC,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,2BAA2B,MAAM,EAAE,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC,4CAA4C,MAAM,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
package/dist/main.js CHANGED
@@ -7,11 +7,14 @@ 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';
11
+ import { registerTest } from './commands/test.js';
12
+ import { registerUpgrade } from './commands/upgrade.js';
10
13
  const program = new Command();
11
14
  program
12
15
  .name('soleri')
13
16
  .description('Developer CLI for creating and managing Soleri AI agents')
14
- .version('1.0.0');
17
+ .version('1.5.0');
15
18
  registerCreate(program);
16
19
  registerList(program);
17
20
  registerAddDomain(program);
@@ -19,5 +22,8 @@ registerInstallKnowledge(program);
19
22
  registerDev(program);
20
23
  registerDoctor(program);
21
24
  registerHooks(program);
25
+ registerGovernance(program);
26
+ registerTest(program);
27
+ registerUpgrade(program);
22
28
  program.parse();
23
29
  //# 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;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,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;AAC5B,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,eAAe,CAAC,OAAO,CAAC,CAAC;AAEzB,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.5.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
  });
@@ -44,6 +44,16 @@ export function registerCreate(program: Command): void {
44
44
  let selectedPacks: string[] = [];
45
45
  if (config.hookPacks && config.hookPacks.length > 0) {
46
46
  selectedPacks = config.hookPacks;
47
+
48
+ // Validate pack names against registry — warn and skip unknown
49
+ const available = listPacks().map((pk) => pk.name);
50
+ const unknown = selectedPacks.filter((pk) => !available.includes(pk));
51
+ if (unknown.length > 0) {
52
+ for (const name of unknown) {
53
+ p.log.warn(`Unknown hook pack "${name}" — skipping. Available: ${available.join(', ')}`);
54
+ }
55
+ selectedPacks = selectedPacks.filter((pk) => available.includes(pk));
56
+ }
47
57
  } else if (!opts?.config) {
48
58
  const packs = listPacks();
49
59
  const packChoices = packs.map((pk) => ({
@@ -93,7 +103,7 @@ export function registerCreate(program: Command): void {
93
103
  // Install selected hook packs
94
104
  if (selectedPacks.length > 0) {
95
105
  for (const packName of selectedPacks) {
96
- const { installed } = installPack(packName);
106
+ const { installed } = installPack(packName, { projectDir: result.agentDir });
97
107
  if (installed.length > 0) {
98
108
  p.log.success(`Hook pack "${packName}" installed (${installed.length} hooks)`);
99
109
  } else {
@@ -0,0 +1,123 @@
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(
66
+ governance: InstanceType<typeof import('@soleri/core').Governance>,
67
+ agentId: string,
68
+ ): void {
69
+ const policy = governance.getPolicy(agentId);
70
+
71
+ log.info('Quotas:');
72
+ log.dim(` Max entries total: ${policy.quotas.maxEntriesTotal}`);
73
+ log.dim(` Max entries per category: ${policy.quotas.maxEntriesPerCategory}`);
74
+ log.dim(` Max entries per type: ${policy.quotas.maxEntriesPerType}`);
75
+ log.dim(` Warn at: ${policy.quotas.warnAtPercent}%`);
76
+
77
+ console.log();
78
+ log.info('Retention:');
79
+ log.dim(` Archive after: ${policy.retention.archiveAfterDays} days`);
80
+ log.dim(` Min hits to keep: ${policy.retention.minHitsToKeep}`);
81
+ log.dim(` Delete archived after: ${policy.retention.deleteArchivedAfterDays} days`);
82
+
83
+ console.log();
84
+ log.info('Auto-capture:');
85
+ log.dim(` Enabled: ${policy.autoCapture.enabled}`);
86
+ log.dim(` Require review: ${policy.autoCapture.requireReview}`);
87
+ log.dim(` Max pending proposals: ${policy.autoCapture.maxPendingProposals}`);
88
+ log.dim(` Auto-expire: ${policy.autoCapture.autoExpireDays} days`);
89
+ }
90
+
91
+ function showQuotaStatus(
92
+ governance: InstanceType<typeof import('@soleri/core').Governance>,
93
+ agentId: string,
94
+ ): void {
95
+ const status = governance.getQuotaStatus(agentId);
96
+
97
+ log.info(`Quota usage: ${status.total} / ${status.maxTotal}`);
98
+
99
+ if (status.isWarning) {
100
+ log.warn(
101
+ 'Approaching quota limit',
102
+ `${Math.round((status.total / status.maxTotal) * 100)}% used`,
103
+ );
104
+ } else {
105
+ log.pass('Within quota', `${Math.round((status.total / status.maxTotal) * 100)}% used`);
106
+ }
107
+
108
+ if (Object.keys(status.byType).length > 0) {
109
+ console.log();
110
+ log.info('By type:');
111
+ for (const [type, count] of Object.entries(status.byType)) {
112
+ log.dim(` ${type}: ${count}`);
113
+ }
114
+ }
115
+
116
+ if (Object.keys(status.byCategory).length > 0) {
117
+ console.log();
118
+ log.info('By category:');
119
+ for (const [cat, count] of Object.entries(status.byCategory)) {
120
+ log.dim(` ${cat}: ${count}`);
121
+ }
122
+ }
123
+ }
@@ -0,0 +1,55 @@
1
+ import { spawn } from 'node:child_process';
2
+ import type { Command } from 'commander';
3
+ import * as p from '@clack/prompts';
4
+ import { detectAgent } from '../utils/agent-context.js';
5
+
6
+ export function registerTest(program: Command): void {
7
+ program
8
+ .command('test')
9
+ .description('Run agent tests via vitest')
10
+ .option('-w, --watch', 'Run in watch mode')
11
+ .option('--coverage', 'Run with coverage')
12
+ .allowUnknownOption(true)
13
+ .action((opts: { watch?: boolean; coverage?: boolean }, cmd) => {
14
+ const ctx = detectAgent();
15
+ if (!ctx) {
16
+ p.log.error('No agent project detected in current directory. Run this from an agent root.');
17
+ process.exit(1);
18
+ }
19
+
20
+ const args: string[] = [];
21
+ if (opts.watch) {
22
+ // vitest (no "run") enables watch mode
23
+ args.push('vitest');
24
+ } else {
25
+ args.push('vitest', 'run');
26
+ }
27
+ if (opts.coverage) args.push('--coverage');
28
+
29
+ // Forward any extra args the user passed
30
+ const extra = cmd.args as string[];
31
+ if (extra.length > 0) args.push(...extra);
32
+
33
+ p.log.info(`Running tests for ${ctx.agentId}...`);
34
+
35
+ const child = spawn('npx', args, {
36
+ cwd: ctx.agentPath,
37
+ stdio: 'inherit',
38
+ env: { ...process.env },
39
+ });
40
+
41
+ child.on('error', (err) => {
42
+ p.log.error(`Failed to start: ${err.message}`);
43
+ p.log.info('Make sure vitest is available: npm install -D vitest');
44
+ process.exit(1);
45
+ });
46
+
47
+ child.on('exit', (code, signal) => {
48
+ if (signal) {
49
+ p.log.warn(`Process terminated by signal ${signal}`);
50
+ process.exit(1);
51
+ }
52
+ process.exit(code ?? 0);
53
+ });
54
+ });
55
+ }
@@ -0,0 +1,69 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { execFileSync } from 'node:child_process';
5
+ import type { Command } from 'commander';
6
+ import * as log from '../utils/logger.js';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+
11
+ function getCurrentVersion(): string {
12
+ const pkgPath = join(__dirname, '..', '..', 'package.json');
13
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
14
+ return pkg.version as string;
15
+ }
16
+
17
+ function getLatestVersion(): string {
18
+ return execFileSync('npm', ['view', '@soleri/cli', 'version'], {
19
+ encoding: 'utf-8',
20
+ timeout: 10_000,
21
+ }).trim();
22
+ }
23
+
24
+ export function registerUpgrade(program: Command): void {
25
+ program
26
+ .command('upgrade')
27
+ .description('Upgrade @soleri/cli to the latest version')
28
+ .option('--check', 'Show current vs latest version without upgrading')
29
+ .action((opts: { check?: boolean }) => {
30
+ const current = getCurrentVersion();
31
+
32
+ log.heading('@soleri/cli upgrade');
33
+
34
+ let latest: string;
35
+ try {
36
+ latest = getLatestVersion();
37
+ } catch {
38
+ log.fail('Could not reach npm registry');
39
+ log.info('Check your internet connection and try again.');
40
+ process.exit(1);
41
+ }
42
+
43
+ if (current === latest) {
44
+ log.pass(`@soleri/cli@${current}`, 'already up to date');
45
+ return;
46
+ }
47
+
48
+ log.info(`Current: ${current}`);
49
+ log.info(`Latest: ${latest}`);
50
+
51
+ if (opts.check) {
52
+ log.dim(`Run "npm install -g @soleri/cli@latest" to upgrade.`);
53
+ return;
54
+ }
55
+
56
+ log.info('Upgrading...');
57
+ try {
58
+ execFileSync('npm', ['install', '-g', '@soleri/cli@latest'], {
59
+ stdio: 'inherit',
60
+ timeout: 60_000,
61
+ });
62
+ log.pass(`Upgraded to @soleri/cli@${latest}`);
63
+ } catch {
64
+ log.fail('Upgrade failed');
65
+ log.info(`Try manually: npm install -g @soleri/cli@${latest}`);
66
+ process.exit(1);
67
+ }
68
+ });
69
+ }
package/src/main.ts CHANGED
@@ -8,13 +8,16 @@ 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';
12
+ import { registerTest } from './commands/test.js';
13
+ import { registerUpgrade } from './commands/upgrade.js';
11
14
 
12
15
  const program = new Command();
13
16
 
14
17
  program
15
18
  .name('soleri')
16
19
  .description('Developer CLI for creating and managing Soleri AI agents')
17
- .version('1.0.0');
20
+ .version('1.5.0');
18
21
 
19
22
  registerCreate(program);
20
23
  registerList(program);
@@ -23,5 +26,8 @@ registerInstallKnowledge(program);
23
26
  registerDev(program);
24
27
  registerDoctor(program);
25
28
  registerHooks(program);
29
+ registerGovernance(program);
30
+ registerTest(program);
31
+ registerUpgrade(program);
26
32
 
27
33
  program.parse();