@vxnus/siduri 2.0.6 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtin-manifests.js +16 -3
- package/dist/colors.d.ts +8 -0
- package/dist/colors.js +11 -0
- package/dist/configurators/behavior.js +59 -16
- package/dist/configurators/voice.js +14 -3
- package/dist/configurators.test.js +18 -3
- package/dist/generator.d.ts +1 -0
- package/dist/generator.js +50 -2
- package/dist/index.d.ts +3 -9
- package/dist/index.js +53 -52
- package/package.json +1 -1
|
@@ -6,8 +6,8 @@ exports.BUILTIN_ORGAN_MANIFESTS = [
|
|
|
6
6
|
name: '@siduri-x/self',
|
|
7
7
|
organType: 'behavior',
|
|
8
8
|
version: '2.0.2',
|
|
9
|
-
displayName: '
|
|
10
|
-
description: '
|
|
9
|
+
displayName: 'Self & Persona (Identity & Directives)',
|
|
10
|
+
description: 'Autonomous persona compiler, relational stances, and .self asset loader',
|
|
11
11
|
entrypoint: './dist/index.js',
|
|
12
12
|
factory: 'ActiveSelfCompiler',
|
|
13
13
|
configKey: 'behavior',
|
|
@@ -19,7 +19,20 @@ exports.BUILTIN_ORGAN_MANIFESTS = [
|
|
|
19
19
|
type: 'string',
|
|
20
20
|
enum: ['active_self', 'none']
|
|
21
21
|
},
|
|
22
|
-
|
|
22
|
+
mode: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
enum: ['blank_slate', 'custom']
|
|
25
|
+
},
|
|
26
|
+
archetype: {
|
|
27
|
+
type: 'string'
|
|
28
|
+
},
|
|
29
|
+
ethos: {
|
|
30
|
+
type: 'string'
|
|
31
|
+
},
|
|
32
|
+
directive: {
|
|
33
|
+
type: 'string'
|
|
34
|
+
},
|
|
35
|
+
selfPath: {
|
|
23
36
|
type: 'string'
|
|
24
37
|
}
|
|
25
38
|
}
|
package/dist/colors.d.ts
ADDED
package/dist/colors.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.colors = void 0;
|
|
4
|
+
exports.colors = {
|
|
5
|
+
cyan: '\u001b[36m',
|
|
6
|
+
dim: '\u001b[2m',
|
|
7
|
+
green: '\u001b[32m',
|
|
8
|
+
yellow: '\u001b[33m',
|
|
9
|
+
bold: '\u001b[1m',
|
|
10
|
+
reset: '\u001b[0m',
|
|
11
|
+
};
|
|
@@ -6,31 +6,74 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.configureBehavior = configureBehavior;
|
|
7
7
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
8
|
async function configureBehavior(_context) {
|
|
9
|
-
const
|
|
9
|
+
const companionName = _context.companionName || 'Companion';
|
|
10
|
+
const companionSlug = companionName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
11
|
+
const { personaMode } = await inquirer_1.default.prompt({
|
|
10
12
|
type: 'list',
|
|
11
|
-
name: '
|
|
12
|
-
message: '
|
|
13
|
+
name: 'personaMode',
|
|
14
|
+
message: 'Define base persona now or later?',
|
|
13
15
|
choices: [
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
{
|
|
17
|
+
name: 'Later (Start as a pure blank slate; evolve via interaction or add .self later)',
|
|
18
|
+
value: 'later',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'Now (Define archetype, ethos, and generate base .self persona asset)',
|
|
22
|
+
value: 'now',
|
|
23
|
+
},
|
|
18
24
|
],
|
|
25
|
+
default: 'later',
|
|
19
26
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
if (personaMode === 'later') {
|
|
28
|
+
return {
|
|
29
|
+
config: {
|
|
30
|
+
provider: 'active_self',
|
|
31
|
+
mode: 'blank_slate',
|
|
32
|
+
},
|
|
33
|
+
summary: {
|
|
34
|
+
Persona: 'Blank Slate (Evolve via interaction)',
|
|
35
|
+
Directives: 'Zero predeclared biases',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const personaAnswers = await inquirer_1.default.prompt([
|
|
40
|
+
{
|
|
41
|
+
type: 'input',
|
|
42
|
+
name: 'archetype',
|
|
43
|
+
message: 'Companion archetype or role:',
|
|
44
|
+
default: 'Knowledge Assistant & Research Partner',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'input',
|
|
48
|
+
name: 'ethos',
|
|
49
|
+
message: 'Core ethos & speaking demeanor:',
|
|
50
|
+
default: 'Direct technical candor, thoughtful, concise, and loyal',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
type: 'input',
|
|
54
|
+
name: 'directive',
|
|
55
|
+
message: 'Primary behavioral directive or rule:',
|
|
56
|
+
default: 'Speak concisely and stay in character without sycophantic filler',
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
const archetype = personaAnswers.archetype.trim() || 'Knowledge Assistant & Research Partner';
|
|
60
|
+
const ethos = personaAnswers.ethos.trim() || 'Direct technical candor, thoughtful, concise, and loyal';
|
|
61
|
+
const directive = personaAnswers.directive.trim() || 'Speak concisely and stay in character without sycophantic filler';
|
|
62
|
+
const selfPath = `./assets/self/${companionSlug}.self`;
|
|
26
63
|
return {
|
|
27
64
|
config: {
|
|
28
65
|
provider: 'active_self',
|
|
29
|
-
|
|
66
|
+
mode: 'custom',
|
|
67
|
+
archetype,
|
|
68
|
+
ethos,
|
|
69
|
+
directive,
|
|
70
|
+
selfPath,
|
|
30
71
|
},
|
|
31
72
|
summary: {
|
|
32
|
-
|
|
33
|
-
|
|
73
|
+
Persona: 'Configured (.self asset)',
|
|
74
|
+
Archetype: archetype,
|
|
75
|
+
Ethos: ethos,
|
|
76
|
+
'Self Asset': selfPath,
|
|
34
77
|
},
|
|
35
78
|
};
|
|
36
79
|
}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.configureVoice = configureVoice;
|
|
7
7
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
const colors_1 = require("../colors");
|
|
8
9
|
async function configureVoice(_context) {
|
|
9
10
|
const companionSlug = _context.companionName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
10
11
|
const { provider } = await inquirer_1.default.prompt({
|
|
@@ -33,6 +34,10 @@ async function configureVoice(_context) {
|
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
if (provider === 'rvc') {
|
|
37
|
+
console.log(`\n ${colors_1.colors.cyan}ℹ RVC Voice Model Setup:${colors_1.colors.reset}`);
|
|
38
|
+
console.log(` • ${colors_1.colors.dim}Voice Weights:${colors_1.colors.reset} Place your trained weights (.pth) in: ${colors_1.colors.green}./assets/voice/${companionSlug}/${companionSlug}.pth${colors_1.colors.reset}`);
|
|
39
|
+
console.log(` • ${colors_1.colors.dim}Feature Index:${colors_1.colors.reset} Place optional .index in: ${colors_1.colors.green}./assets/voice/${companionSlug}/${companionSlug}.index${colors_1.colors.reset}`);
|
|
40
|
+
console.log(` • ${colors_1.colors.dim}RVC Service:${colors_1.colors.reset} Ensure your headless RVC microservice is running before voice inference.\n`);
|
|
36
41
|
const rvcAnswers = await inquirer_1.default.prompt([
|
|
37
42
|
{
|
|
38
43
|
type: 'input',
|
|
@@ -65,9 +70,9 @@ async function configureVoice(_context) {
|
|
|
65
70
|
name: 'baseTts',
|
|
66
71
|
message: 'Base TTS Engine for RVC (Generates initial audio):',
|
|
67
72
|
choices: [
|
|
68
|
-
{ name: 'Edge-TTS (Cloud API, 0MB)', value: 'edge-tts' },
|
|
69
|
-
{ name: 'Kokoro TTS (
|
|
70
|
-
{ name: 'Piper TTS (
|
|
73
|
+
{ name: 'Edge-TTS (Cloud API, 0MB - streams over network, zero local binary)', value: 'edge-tts' },
|
|
74
|
+
{ name: 'Kokoro TTS (Connects to existing local Kokoro server or CLI)', value: 'kokoro' },
|
|
75
|
+
{ name: 'Piper TTS (Connects to existing local Piper server or CLI)', value: 'piper' },
|
|
71
76
|
],
|
|
72
77
|
default: 'edge-tts',
|
|
73
78
|
},
|
|
@@ -308,6 +313,11 @@ async function configureVoice(_context) {
|
|
|
308
313
|
return choices;
|
|
309
314
|
}
|
|
310
315
|
// provider === 'voicevox'
|
|
316
|
+
console.log(`\n ${colors_1.colors.cyan}ℹ VOICEVOX Engine Runtime:${colors_1.colors.reset}`);
|
|
317
|
+
console.log(` • ${colors_1.colors.dim}Download timing:${colors_1.colors.reset} Automatically downloaded on first companion run (${colors_1.colors.green}npm start${colors_1.colors.reset}).`);
|
|
318
|
+
console.log(` • ${colors_1.colors.dim}Install path:${colors_1.colors.reset} ~/.voicevox/engine/ (~1.5GB CPU binary, verified SHA-256).`);
|
|
319
|
+
console.log(` • ${colors_1.colors.dim}Engine execution:${colors_1.colors.reset} Siduri auto-spawns and manages the engine in background on port 50021.`);
|
|
320
|
+
console.log(` • ${colors_1.colors.dim}Pre-existing check:${colors_1.colors.reset} If you already run VOICEVOX (desktop/docker), Siduri connects directly without downloading.\n`);
|
|
311
321
|
const urlAnswer = await inquirer_1.default.prompt([
|
|
312
322
|
{
|
|
313
323
|
type: 'input',
|
|
@@ -355,6 +365,7 @@ async function configureVoice(_context) {
|
|
|
355
365
|
'Voice Bank': speakerLabel,
|
|
356
366
|
'Speaker ID': speakerId,
|
|
357
367
|
'Base URL': baseUrl,
|
|
368
|
+
'Engine Runtime': 'Auto-downloads to ~/.voicevox/engine/ on first npm start (if port free)',
|
|
358
369
|
};
|
|
359
370
|
return {
|
|
360
371
|
config,
|
|
@@ -315,11 +315,26 @@ describe('Guided Manifest-Driven Configuration UX Specification Tests', () => {
|
|
|
315
315
|
expect(result.config.provider).toBe('none');
|
|
316
316
|
expect(result.summary?.Provider).toBe('None (Hands disabled)');
|
|
317
317
|
});
|
|
318
|
-
test('Behavior configurator configures
|
|
319
|
-
inquirer_1.default.prompt.mockResolvedValueOnce({
|
|
318
|
+
test('Behavior configurator configures blank slate mode when later is chosen', async () => {
|
|
319
|
+
inquirer_1.default.prompt.mockResolvedValueOnce({ personaMode: 'later' });
|
|
320
320
|
const result = await (0, behavior_1.configureBehavior)({ companionName: 'Sparkle', manifest: behaviorManifest });
|
|
321
321
|
expect(result.config.provider).toBe('active_self');
|
|
322
|
-
expect(result.config.
|
|
322
|
+
expect(result.config.mode).toBe('blank_slate');
|
|
323
|
+
expect(result.summary?.Persona).toBe('Blank Slate (Evolve via interaction)');
|
|
324
|
+
});
|
|
325
|
+
test('Behavior configurator configures custom persona asset when now is chosen', async () => {
|
|
326
|
+
inquirer_1.default.prompt
|
|
327
|
+
.mockResolvedValueOnce({ personaMode: 'now' })
|
|
328
|
+
.mockResolvedValueOnce({
|
|
329
|
+
archetype: 'System Sentinel',
|
|
330
|
+
ethos: 'Snarky and loyal',
|
|
331
|
+
directive: 'No sycophantic greetings',
|
|
332
|
+
});
|
|
333
|
+
const result = await (0, behavior_1.configureBehavior)({ companionName: 'Sparkle', manifest: behaviorManifest });
|
|
334
|
+
expect(result.config.provider).toBe('active_self');
|
|
335
|
+
expect(result.config.mode).toBe('custom');
|
|
336
|
+
expect(result.config.archetype).toBe('System Sentinel');
|
|
337
|
+
expect(result.config.selfPath).toBe('./assets/self/sparkle.self');
|
|
323
338
|
});
|
|
324
339
|
test('Vision configurator configures OpenRouter vision model', async () => {
|
|
325
340
|
inquirer_1.default.prompt.mockResolvedValueOnce({ model: 'gpt-4-vision' });
|
package/dist/generator.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export interface GeneratedInstanceFiles {
|
|
|
9
9
|
'public/index.html': string;
|
|
10
10
|
createAssetsBodyDir?: boolean;
|
|
11
11
|
createAssetsDirs?: string[];
|
|
12
|
+
[key: string]: string | boolean | string[] | undefined;
|
|
12
13
|
}
|
|
13
14
|
export interface InstanceGeneratorOptions {
|
|
14
15
|
name: string;
|
package/dist/generator.js
CHANGED
|
@@ -73,6 +73,7 @@ function getDefaultConfigForManifest(manifest) {
|
|
|
73
73
|
}
|
|
74
74
|
function generateInstanceFiles(options) {
|
|
75
75
|
const instanceName = options.name || 'my-siduri';
|
|
76
|
+
const companionSlug = instanceName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
76
77
|
const instanceId = options.id || 'default';
|
|
77
78
|
const coreVersion = options.coreVersion || '^2.0.3';
|
|
78
79
|
const manifests = options.selectedManifests;
|
|
@@ -172,7 +173,7 @@ function generateInstanceFiles(options) {
|
|
|
172
173
|
];
|
|
173
174
|
for (const m of manifests) {
|
|
174
175
|
if (m.name === '@siduri-x/self') {
|
|
175
|
-
importLines.push(`import { ActiveSelfCompiler, SqliteSelfRepository } from '@siduri-x/self';`);
|
|
176
|
+
importLines.push(`import { ActiveSelfCompiler, SqliteSelfRepository, SelfPackageParser } from '@siduri-x/self';`);
|
|
176
177
|
}
|
|
177
178
|
else {
|
|
178
179
|
importLines.push(`import { ${m.factory} } from '${m.name}';`);
|
|
@@ -184,6 +185,19 @@ function generateInstanceFiles(options) {
|
|
|
184
185
|
if (m.name === '@siduri-x/self') {
|
|
185
186
|
instantiationLines.push(`const self = new SqliteSelfRepository({ dbPath: path.resolve(rootDir, 'siduri.sqlite') });`);
|
|
186
187
|
instantiationLines.push(`const behavior = new ActiveSelfCompiler(config.organs.behavior);`);
|
|
188
|
+
instantiationLines.push(`const selfFile = path.resolve(rootDir, config.organs.behavior?.selfPath || 'assets/self/${companionSlug}.self');`);
|
|
189
|
+
instantiationLines.push(`try {`);
|
|
190
|
+
instantiationLines.push(` const selfRaw = await readFile(selfFile, 'utf8').catch(() => null);`);
|
|
191
|
+
instantiationLines.push(` if (selfRaw) {`);
|
|
192
|
+
instantiationLines.push(` const parsedSelf = SelfPackageParser.parse(selfRaw);`);
|
|
193
|
+
instantiationLines.push(` if (parsedSelf.isValid && parsedSelf.manifest) {`);
|
|
194
|
+
instantiationLines.push(` await self.setIdentity({ companionId: config.id || 'default', name: parsedSelf.manifest.identity?.name || config.name, archetype: parsedSelf.manifest.identity?.archetype, version: parsedSelf.manifest.version || '1.0.0', updatedAt: new Date().toISOString() });`);
|
|
195
|
+
instantiationLines.push(` if (parsedSelf.manifest.directives) {`);
|
|
196
|
+
instantiationLines.push(` await self.commitDirectives(config.id || 'default', parsedSelf.manifest.directives.map((d) => ({ id: d.id, companionId: config.id || 'default', directive: d.directive, category: (d.category || 'behavioral'), status: 'ACTIVE', priority: d.priority || 50, createdAt: new Date().toISOString() })));`);
|
|
197
|
+
instantiationLines.push(` }`);
|
|
198
|
+
instantiationLines.push(` }`);
|
|
199
|
+
instantiationLines.push(` }`);
|
|
200
|
+
instantiationLines.push(`} catch {}`);
|
|
187
201
|
organMapEntries.push(` behavior,`);
|
|
188
202
|
organMapEntries.push(` self,`);
|
|
189
203
|
}
|
|
@@ -665,7 +679,6 @@ function generateInstanceFiles(options) {
|
|
|
665
679
|
}
|
|
666
680
|
readmeLines.push('', '## Getting Started', '', '### 1. Install Dependencies', '```bash', 'npm install', '```', '', '### 2. Configure Environment', '```bash', 'cp .env.example .env', '```', 'Fill in your LLM API key (e.g. `OPENROUTER_API_KEY`) and any other service credentials in `.env`.');
|
|
667
681
|
readmeLines.push('', '### 3. Diagnostics & Health Probe', 'Verify all environment variables, schema conformance, services, and organ connections:', '```bash', 'npm run doctor', '```', '', '### 4. Start Companion & Web Console', 'Launch your companion runtime and Web UI / Memory Control Panel:', '```bash', 'npm start', '```', 'Then open `http://localhost:3000` in your browser.');
|
|
668
|
-
const companionSlug = instanceName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
669
682
|
const createAssetsDirs = [];
|
|
670
683
|
if (hasBody) {
|
|
671
684
|
createAssetsDirs.push(`assets/body/${companionSlug}`);
|
|
@@ -681,6 +694,38 @@ function generateInstanceFiles(options) {
|
|
|
681
694
|
createAssetsDirs.push(cleanPackDir);
|
|
682
695
|
readmeLines.push('', '### Knowledge Pack Assets', `Local knowledge pack files reside in \`./${cleanPackDir}/\`.`);
|
|
683
696
|
}
|
|
697
|
+
const behaviorConfig = options.organConfigs?.behavior || options.organConfigs?.['@siduri-x/self'];
|
|
698
|
+
let selfPersonaFile = null;
|
|
699
|
+
if (manifests.some((m) => m.organType === 'behavior')) {
|
|
700
|
+
createAssetsDirs.push('assets/self');
|
|
701
|
+
if (behaviorConfig?.mode === 'custom' || behaviorConfig?.archetype) {
|
|
702
|
+
const selfRelPath = `assets/self/${companionSlug}.self`;
|
|
703
|
+
const selfContent = [
|
|
704
|
+
`specVersion: "2.0.0"`,
|
|
705
|
+
`kind: "self"`,
|
|
706
|
+
`id: "${companionSlug}-self"`,
|
|
707
|
+
`name: "${instanceName} Persona"`,
|
|
708
|
+
`version: "1.0.0"`,
|
|
709
|
+
`author:`,
|
|
710
|
+
` name: "Operator"`,
|
|
711
|
+
`license: "MIT"`,
|
|
712
|
+
``,
|
|
713
|
+
`identity:`,
|
|
714
|
+
` name: "${instanceName}"`,
|
|
715
|
+
` archetype: "${(behaviorConfig.archetype || 'Knowledge Assistant & Research Partner').replace(/"/g, '\\"')}"`,
|
|
716
|
+
` origin: "Constructed companion"`,
|
|
717
|
+
` ethos: "${(behaviorConfig.ethos || 'Direct technical candor, thoughtful, concise, and loyal').replace(/"/g, '\\"')}"`,
|
|
718
|
+
``,
|
|
719
|
+
`directives:`,
|
|
720
|
+
` - id: "dir-01"`,
|
|
721
|
+
` category: "behavioral"`,
|
|
722
|
+
` directive: "${(behaviorConfig.directive || 'Speak concisely and stay in character without sycophantic filler').replace(/"/g, '\\"')}"`,
|
|
723
|
+
``,
|
|
724
|
+
].join('\n');
|
|
725
|
+
selfPersonaFile = { path: selfRelPath, content: selfContent };
|
|
726
|
+
readmeLines.push('', '### Self & Persona Assets', `Companion persona manifest resides in \`./${selfRelPath}\`.`);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
684
729
|
readmeLines.push('');
|
|
685
730
|
const readmeMd = readmeLines.join('\n');
|
|
686
731
|
const webHtml = (0, web_template_1.generateWebHtml)(instanceName, manifests);
|
|
@@ -695,5 +740,8 @@ function generateInstanceFiles(options) {
|
|
|
695
740
|
createAssetsBodyDir: hasBody,
|
|
696
741
|
createAssetsDirs,
|
|
697
742
|
};
|
|
743
|
+
if (selfPersonaFile) {
|
|
744
|
+
result[selfPersonaFile.path] = selfPersonaFile.content;
|
|
745
|
+
}
|
|
698
746
|
return result;
|
|
699
747
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { OrganManifest } from './manifest';
|
|
3
|
-
export declare const CLI_VERSION = "2.0.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
dim: string;
|
|
7
|
-
green: string;
|
|
8
|
-
yellow: string;
|
|
9
|
-
bold: string;
|
|
10
|
-
reset: string;
|
|
11
|
-
};
|
|
3
|
+
export declare const CLI_VERSION = "2.0.8";
|
|
4
|
+
import { colors } from './colors';
|
|
5
|
+
export { colors };
|
|
12
6
|
export declare function printHeader(): void;
|
|
13
7
|
export declare function printSection(title: string): void;
|
|
14
8
|
export declare function printSuccess(message: string): void;
|
package/dist/index.js
CHANGED
|
@@ -26,24 +26,18 @@ const doctor_1 = require("./doctor");
|
|
|
26
26
|
const db_1 = require("./db");
|
|
27
27
|
const configurators_1 = require("./configurators");
|
|
28
28
|
const execFile = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
29
|
-
exports.CLI_VERSION = '2.0.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
dim: '\u001b[2m',
|
|
33
|
-
green: '\u001b[32m',
|
|
34
|
-
yellow: '\u001b[33m',
|
|
35
|
-
bold: '\u001b[1m',
|
|
36
|
-
reset: '\u001b[0m',
|
|
37
|
-
};
|
|
29
|
+
exports.CLI_VERSION = '2.0.8';
|
|
30
|
+
const colors_1 = require("./colors");
|
|
31
|
+
Object.defineProperty(exports, "colors", { enumerable: true, get: function () { return colors_1.colors; } });
|
|
38
32
|
function printHeader() {
|
|
39
|
-
console.log(`\n${
|
|
40
|
-
console.log(`${
|
|
33
|
+
console.log(`\n${colors_1.colors.cyan}◈ SIDURI${colors_1.colors.reset} ${colors_1.colors.dim}companion setup (manifest-driven)${colors_1.colors.reset}`);
|
|
34
|
+
console.log(`${colors_1.colors.yellow}Version ${exports.CLI_VERSION}${colors_1.colors.reset} · composable standalone architecture\n`);
|
|
41
35
|
}
|
|
42
36
|
function printSection(title) {
|
|
43
|
-
console.log(`\n${
|
|
37
|
+
console.log(`\n${colors_1.colors.cyan}── ${title} ${'─'.repeat(Math.max(2, 42 - title.length))}${colors_1.colors.reset}\n`);
|
|
44
38
|
}
|
|
45
39
|
function printSuccess(message) {
|
|
46
|
-
console.log(`${
|
|
40
|
+
console.log(`${colors_1.colors.green}✓${colors_1.colors.reset} ${message}`);
|
|
47
41
|
}
|
|
48
42
|
function projectDirectoryName(value) {
|
|
49
43
|
const slug = value
|
|
@@ -55,45 +49,45 @@ function projectDirectoryName(value) {
|
|
|
55
49
|
}
|
|
56
50
|
function formatReviewSummary(companionName, selectedManifests, organSummaries) {
|
|
57
51
|
const lines = [];
|
|
58
|
-
lines.push(`\n${
|
|
59
|
-
lines.push(` ${
|
|
60
|
-
lines.push(` ${
|
|
52
|
+
lines.push(`\n${colors_1.colors.cyan}── Review ${companionName} ${'─'.repeat(Math.max(2, 42 - (companionName.length + 9)))}${colors_1.colors.reset}\n`);
|
|
53
|
+
lines.push(` ${colors_1.colors.bold}Companion${colors_1.colors.reset}`);
|
|
54
|
+
lines.push(` ${colors_1.colors.dim}Name:${colors_1.colors.reset} ${companionName}\n`);
|
|
61
55
|
for (const m of selectedManifests) {
|
|
62
56
|
const isRequired = m.organType === 'brain';
|
|
63
|
-
const tag = isRequired ? ` ${
|
|
64
|
-
lines.push(` ${
|
|
57
|
+
const tag = isRequired ? ` ${colors_1.colors.dim}· required${colors_1.colors.reset}` : '';
|
|
58
|
+
lines.push(` ${colors_1.colors.bold}${m.displayName.split(' ')[0] || m.organType}${colors_1.colors.reset}${tag}`);
|
|
65
59
|
const summary = organSummaries[m.configKey] || organSummaries[m.organType] || {};
|
|
66
60
|
const entries = Object.entries(summary);
|
|
67
61
|
if (entries.length === 0) {
|
|
68
|
-
lines.push(` ${
|
|
62
|
+
lines.push(` ${colors_1.colors.dim}Provider:${colors_1.colors.reset} ${m.displayName}`);
|
|
69
63
|
}
|
|
70
64
|
else {
|
|
71
65
|
for (const [key, val] of entries) {
|
|
72
66
|
const valStr = String(val);
|
|
73
|
-
lines.push(` ${
|
|
67
|
+
lines.push(` ${colors_1.colors.dim}${key}:${colors_1.colors.reset}${' '.repeat(Math.max(1, 10 - key.length))}${valStr}`);
|
|
74
68
|
}
|
|
75
69
|
}
|
|
76
70
|
lines.push('');
|
|
77
71
|
}
|
|
78
|
-
lines.push(`${
|
|
72
|
+
lines.push(`${colors_1.colors.cyan}${'─'.repeat(46)}${colors_1.colors.reset}\n`);
|
|
79
73
|
return lines.join('\n');
|
|
80
74
|
}
|
|
81
75
|
async function withTask(label, task) {
|
|
82
|
-
process.stdout.write(`${
|
|
76
|
+
process.stdout.write(`${colors_1.colors.dim}${label}${colors_1.colors.reset}`);
|
|
83
77
|
const frames = ['·', '•', '●', '•'];
|
|
84
78
|
let index = 0;
|
|
85
79
|
const timer = setInterval(() => {
|
|
86
|
-
process.stdout.write(`\r${
|
|
80
|
+
process.stdout.write(`\r${colors_1.colors.dim}${label} ${frames[index++ % frames.length]}${colors_1.colors.reset}`);
|
|
87
81
|
}, 120);
|
|
88
82
|
try {
|
|
89
83
|
const result = await task();
|
|
90
84
|
clearInterval(timer);
|
|
91
|
-
process.stdout.write(`\r${
|
|
85
|
+
process.stdout.write(`\r${colors_1.colors.green}✓${colors_1.colors.reset} ${label}\n`);
|
|
92
86
|
return result;
|
|
93
87
|
}
|
|
94
88
|
catch (error) {
|
|
95
89
|
clearInterval(timer);
|
|
96
|
-
process.stdout.write(`\r${
|
|
90
|
+
process.stdout.write(`\r${colors_1.colors.yellow}!${colors_1.colors.reset} ${label}\n`);
|
|
97
91
|
throw error;
|
|
98
92
|
}
|
|
99
93
|
}
|
|
@@ -121,7 +115,7 @@ async function runCreateWizard(targetDir) {
|
|
|
121
115
|
const companionName = basicAnswers.name;
|
|
122
116
|
const projectDir = targetDir ? node_path_1.default.resolve(process.cwd(), targetDir) : node_path_1.default.resolve(process.cwd(), projectDirectoryName(companionName));
|
|
123
117
|
printSection('Organ Configuration');
|
|
124
|
-
console.log(`${
|
|
118
|
+
console.log(`${colors_1.colors.dim}Configuring capability organs for ${companionName} sequentially from cognition to physical embodiment.${colors_1.colors.reset}\n`);
|
|
125
119
|
// Canonical organ presentation order: Cognition -> Memory/State -> Identity -> Embodiment & Peripheral
|
|
126
120
|
const canonicalOrder = ['brain', 'memory', 'knowledge', 'behavior', 'voice', 'body', 'mouth', 'hands', 'vision', 'ear', 'observation'];
|
|
127
121
|
const orderedManifests = [...availableManifests].sort((a, b) => {
|
|
@@ -277,7 +271,7 @@ async function runCreateWizard(targetDir) {
|
|
|
277
271
|
});
|
|
278
272
|
}
|
|
279
273
|
catch (err) {
|
|
280
|
-
console.warn(`${
|
|
274
|
+
console.warn(`${colors_1.colors.yellow}!${colors_1.colors.reset} Notice: Could not download or unpack knowledge archive: ${err.message}`);
|
|
281
275
|
}
|
|
282
276
|
}
|
|
283
277
|
printSuccess(`Generated standalone files at ${projectDir}`);
|
|
@@ -289,49 +283,56 @@ async function runCreateWizard(targetDir) {
|
|
|
289
283
|
printSuccess('Dependencies installed successfully.');
|
|
290
284
|
}
|
|
291
285
|
catch (err) {
|
|
292
|
-
console.warn(`${
|
|
286
|
+
console.warn(`${colors_1.colors.yellow}!${colors_1.colors.reset} Notice: npm install had warnings or requires network: ${err.message}`);
|
|
293
287
|
}
|
|
294
288
|
printSection('Instance Ready');
|
|
295
289
|
console.log(`Your Siduri companion is ready! Next steps:\n`);
|
|
296
290
|
console.log(` cd ${node_path_1.default.relative(process.cwd(), projectDir) || '.'}`);
|
|
297
|
-
console.log(` cp .env.example .env ${
|
|
298
|
-
console.log(` npm run doctor ${
|
|
299
|
-
console.log(` npm start ${
|
|
291
|
+
console.log(` cp .env.example .env ${colors_1.colors.dim}# Fill in required API keys/credentials${colors_1.colors.reset}`);
|
|
292
|
+
console.log(` npm run doctor ${colors_1.colors.dim}# Run diagnostic health probes${colors_1.colors.reset}`);
|
|
293
|
+
console.log(` npm start ${colors_1.colors.dim}# Start Web Companion & Memory Console at http://localhost:3000${colors_1.colors.reset}\n`);
|
|
294
|
+
const voiceConfig = organConfigs.voice || organConfigs['@siduri-x/voice'];
|
|
295
|
+
if (voiceConfig?.provider === 'voicevox') {
|
|
296
|
+
console.log(` ${colors_1.colors.cyan}ℹ Voice Runtime:${colors_1.colors.reset} ${colors_1.colors.dim}VOICEVOX engine (~1.5GB) will auto-download to ~/.voicevox/engine/ and launch on port 50021 on first 'npm start' (if not already running).${colors_1.colors.reset}\n`);
|
|
297
|
+
}
|
|
298
|
+
else if (voiceConfig?.rvc?.enabled) {
|
|
299
|
+
console.log(` ${colors_1.colors.cyan}ℹ Voice Model:${colors_1.colors.reset} ${colors_1.colors.dim}Place your RVC weights (.pth) in ${voiceConfig.rvc.modelPath} before starting voice synthesis.${colors_1.colors.reset}\n`);
|
|
300
|
+
}
|
|
300
301
|
}
|
|
301
302
|
async function runCliDoctor(targetDir) {
|
|
302
303
|
printHeader();
|
|
303
304
|
const dir = targetDir ? node_path_1.default.resolve(process.cwd(), targetDir) : process.cwd();
|
|
304
|
-
console.log(`${
|
|
305
|
-
console.log(`${
|
|
305
|
+
console.log(`${colors_1.colors.cyan}Siduri Doctor${colors_1.colors.reset}`);
|
|
306
|
+
console.log(`${colors_1.colors.dim}─────────────${colors_1.colors.reset}\n`);
|
|
306
307
|
try {
|
|
307
308
|
const report = await (0, doctor_1.runDoctor)({ projectDir: dir });
|
|
308
|
-
console.log(`${
|
|
309
|
-
console.log(`${
|
|
309
|
+
console.log(`${colors_1.colors.dim}Instance:${colors_1.colors.reset} ${report.instanceName}`);
|
|
310
|
+
console.log(`${colors_1.colors.dim}Organs:${colors_1.colors.reset} ${report.configuredOrgans.join(', ')}\n`);
|
|
310
311
|
const categories = ['Environment', 'Services', 'Database', 'Health Probe'];
|
|
311
312
|
for (const cat of categories) {
|
|
312
313
|
const items = report.results.filter((r) => r.category === cat);
|
|
313
314
|
if (items.length > 0) {
|
|
314
|
-
console.log(`${
|
|
315
|
+
console.log(`${colors_1.colors.cyan}${cat}${colors_1.colors.reset}`);
|
|
315
316
|
for (const item of items) {
|
|
316
317
|
if (item.status === 'PASS') {
|
|
317
|
-
console.log(` ${
|
|
318
|
+
console.log(` ${colors_1.colors.green}✓${colors_1.colors.reset} ${item.name} ${colors_1.colors.dim}(${item.message || 'OK'})${colors_1.colors.reset}`);
|
|
318
319
|
}
|
|
319
320
|
else if (item.status === 'OPTIONAL_MISSING') {
|
|
320
|
-
console.log(` ${
|
|
321
|
+
console.log(` ${colors_1.colors.dim}○${colors_1.colors.reset} ${item.name} ${colors_1.colors.dim}(Optional, not set)${colors_1.colors.reset}`);
|
|
321
322
|
}
|
|
322
323
|
else if (item.status === 'SKIPPED') {
|
|
323
|
-
console.log(` ${
|
|
324
|
+
console.log(` ${colors_1.colors.dim}— ${item.name} (${item.message})${colors_1.colors.reset}`);
|
|
324
325
|
}
|
|
325
326
|
else {
|
|
326
|
-
console.log(` ${
|
|
327
|
+
console.log(` ${colors_1.colors.yellow}✗${colors_1.colors.reset} ${item.name}`);
|
|
327
328
|
if (item.organName) {
|
|
328
|
-
console.log(` ${
|
|
329
|
+
console.log(` ${colors_1.colors.dim}Required by:${colors_1.colors.reset} ${item.organName}`);
|
|
329
330
|
}
|
|
330
331
|
if (item.message) {
|
|
331
|
-
console.log(` ${
|
|
332
|
+
console.log(` ${colors_1.colors.yellow}${item.message}${colors_1.colors.reset}`);
|
|
332
333
|
}
|
|
333
334
|
if (item.remediation) {
|
|
334
|
-
console.log(` ${
|
|
335
|
+
console.log(` ${colors_1.colors.dim}Remediation:${colors_1.colors.reset} ${item.remediation}`);
|
|
335
336
|
}
|
|
336
337
|
}
|
|
337
338
|
}
|
|
@@ -339,16 +340,16 @@ async function runCliDoctor(targetDir) {
|
|
|
339
340
|
}
|
|
340
341
|
}
|
|
341
342
|
if (report.passed) {
|
|
342
|
-
console.log(`${
|
|
343
|
+
console.log(`${colors_1.colors.green}Result: PASS${colors_1.colors.reset}\n`);
|
|
343
344
|
process.exitCode = 0;
|
|
344
345
|
}
|
|
345
346
|
else {
|
|
346
|
-
console.log(`${
|
|
347
|
+
console.log(`${colors_1.colors.yellow}Result: FAIL${colors_1.colors.reset}\n`);
|
|
347
348
|
process.exitCode = 1;
|
|
348
349
|
}
|
|
349
350
|
}
|
|
350
351
|
catch (err) {
|
|
351
|
-
console.error(`\n${
|
|
352
|
+
console.error(`\n${colors_1.colors.yellow}Doctor Error:${colors_1.colors.reset} ${err.message}\n`);
|
|
352
353
|
process.exitCode = 2;
|
|
353
354
|
}
|
|
354
355
|
}
|
|
@@ -360,24 +361,24 @@ async function runCliDb(subcommand, targetDir) {
|
|
|
360
361
|
return;
|
|
361
362
|
}
|
|
362
363
|
const dir = targetDir ? node_path_1.default.resolve(process.cwd(), targetDir) : process.cwd();
|
|
363
|
-
console.log(`${
|
|
364
|
-
console.log(`${
|
|
364
|
+
console.log(`${colors_1.colors.cyan}Siduri Database Migrations${colors_1.colors.reset}`);
|
|
365
|
+
console.log(`${colors_1.colors.dim}──────────────────────────${colors_1.colors.reset}\n`);
|
|
365
366
|
try {
|
|
366
367
|
const res = await (0, db_1.runDbPush)({ projectDir: dir });
|
|
367
368
|
if (res.status === 'NOOP') {
|
|
368
|
-
console.log(`${
|
|
369
|
+
console.log(`${colors_1.colors.dim}— ${res.message}${colors_1.colors.reset}\n`);
|
|
369
370
|
}
|
|
370
371
|
else {
|
|
371
372
|
printSuccess(res.message);
|
|
372
373
|
if (res.appliedMigrations.length > 0) {
|
|
373
|
-
console.log(`${
|
|
374
|
+
console.log(`${colors_1.colors.dim}Applied:${colors_1.colors.reset} ${res.appliedMigrations.join(', ')}`);
|
|
374
375
|
}
|
|
375
376
|
console.log();
|
|
376
377
|
}
|
|
377
378
|
process.exitCode = 0;
|
|
378
379
|
}
|
|
379
380
|
catch (err) {
|
|
380
|
-
console.error(`\n${
|
|
381
|
+
console.error(`\n${colors_1.colors.yellow}Database Migration Error:${colors_1.colors.reset} ${err.message}\n`);
|
|
381
382
|
process.exitCode = 3;
|
|
382
383
|
}
|
|
383
384
|
}
|
|
@@ -416,7 +417,7 @@ if (require.main === module) {
|
|
|
416
417
|
console.log('\nOperation cancelled.');
|
|
417
418
|
return;
|
|
418
419
|
}
|
|
419
|
-
console.error(`\n${
|
|
420
|
+
console.error(`\n${colors_1.colors.yellow}!${colors_1.colors.reset} ${error instanceof Error ? error.message : error}`);
|
|
420
421
|
process.exitCode = 1;
|
|
421
422
|
});
|
|
422
423
|
}
|