@vxnus/siduri 2.0.6 → 2.0.7

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.
@@ -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: 'Behavior & Self (Personality Directives)',
10
- description: 'Atomic directive state machine and personality projection compiler',
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
- preset: {
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
  }
@@ -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 { preset } = await inquirer_1.default.prompt({
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: 'preset',
12
- message: 'Personality projection preset:',
13
+ name: 'personaMode',
14
+ message: 'Define base persona now or later?',
13
15
  choices: [
14
- { name: 'Calm & Precise (Default)', value: 'calm_precise' },
15
- { name: 'Cheerful & Enthusiastic', value: 'cheerful' },
16
- { name: 'Analytical & Methodical', value: 'analytical' },
17
- { name: 'Custom Directive State Machine', value: 'custom' },
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
- const presetLabels = {
21
- calm_precise: 'Calm & Precise',
22
- cheerful: 'Cheerful & Enthusiastic',
23
- analytical: 'Analytical & Methodical',
24
- custom: 'Custom Directives',
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
- preset,
66
+ mode: 'custom',
67
+ archetype,
68
+ ethos,
69
+ directive,
70
+ selfPath,
30
71
  },
31
72
  summary: {
32
- Provider: 'Active Self Directives',
33
- Preset: presetLabels[preset] || preset,
73
+ Persona: 'Configured (.self asset)',
74
+ Archetype: archetype,
75
+ Ethos: ethos,
76
+ 'Self Asset': selfPath,
34
77
  },
35
78
  };
36
79
  }
@@ -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 active self personality preset', async () => {
319
- inquirer_1.default.prompt.mockResolvedValueOnce({ preset: 'cheerful' });
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.preset).toBe('cheerful');
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' });
@@ -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,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { OrganManifest } from './manifest';
3
- export declare const CLI_VERSION = "2.0.6";
3
+ export declare const CLI_VERSION = "2.0.7";
4
4
  export declare const colors: {
5
5
  cyan: string;
6
6
  dim: string;
package/dist/index.js CHANGED
@@ -26,7 +26,7 @@ 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.6';
29
+ exports.CLI_VERSION = '2.0.7';
30
30
  exports.colors = {
31
31
  cyan: '\u001b[36m',
32
32
  dim: '\u001b[2m',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vxnus/siduri",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
4
4
  "description": "Experimental CLI for installing and configuring Siduri companions",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {