@vxnus/siduri 0.1.10 → 0.1.11
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/README.md +3 -4
- package/dist/builtin-manifests.js +2 -2
- package/dist/clean-machine-e2e.test.js +1 -1
- package/dist/configurators/memory.js +1 -1
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +24 -0
- package/dist/generator.d.ts +0 -1
- package/dist/generator.js +16 -67
- package/dist/generator.test.js +6 -6
- package/dist/index.js +0 -6
- package/dist/runtime-parity.test.js +2 -1
- package/dist/schema-validator.d.ts +9 -0
- package/dist/schema-validator.js +107 -0
- package/dist/web-dist/404/index.html +1 -0
- package/dist/web-dist/404.html +1 -0
- package/dist/web-dist/__next.__PAGE__.txt +35 -0
- package/dist/web-dist/__next._full.txt +32 -0
- package/dist/web-dist/__next._tree.txt +4 -0
- package/dist/web-dist/_next/static/chunks/09y7khbmco_v4.js +1 -0
- package/dist/web-dist/_next/static/chunks/0cz1d0mv5g_q7.js +1 -0
- package/dist/web-dist/_next/static/chunks/0uwih7sydv413.js +1 -0
- package/dist/web-dist/_next/static/chunks/0xhe1hasjan-9.css +1 -0
- package/dist/web-dist/_next/static/chunks/1_yae15ffa5f6.js +1 -0
- package/dist/web-dist/_next/static/chunks/2_duynll0m51m.js +30 -0
- package/dist/web-dist/_next/static/chunks/2kcqevsmv6kh2.js +31 -0
- package/dist/web-dist/_next/static/chunks/2s3d1bfr0l4b0.js +1 -0
- package/dist/web-dist/_next/static/chunks/32z87id9k6i2z.js +22 -0
- package/dist/web-dist/_next/static/chunks/3bx2gs3idjmo1.js +1 -0
- package/dist/web-dist/_next/static/chunks/turbopack-3eipe4c-imn5l.js +1 -0
- package/dist/web-dist/_next/static/media/apple-icon.2g7-yefdphkmy.png +0 -0
- package/dist/web-dist/_next/static/media/favicon.3rlors1ui1gw9.ico +0 -0
- package/dist/web-dist/_next/static/media/icon.0580nb9h-ugue.svg +4 -0
- package/dist/web-dist/_next/static/pWHUixFDDvANZeAf-shqT/_buildManifest.js +11 -0
- package/dist/web-dist/_next/static/pWHUixFDDvANZeAf-shqT/_clientMiddlewareManifest.js +1 -0
- package/dist/web-dist/_next/static/pWHUixFDDvANZeAf-shqT/_ssgManifest.js +1 -0
- package/dist/web-dist/_not-found/__next._full.txt +17 -0
- package/dist/web-dist/_not-found/__next._not-found.__PAGE__.txt +23 -0
- package/dist/web-dist/_not-found/__next._tree.txt +3 -0
- package/dist/web-dist/_not-found/index.html +1 -0
- package/dist/web-dist/_not-found/index.txt +17 -0
- package/dist/web-dist/apple-icon.png +0 -0
- package/dist/web-dist/apple-touch-icon.png +0 -0
- package/dist/web-dist/chat/__next._full.txt +18 -0
- package/dist/web-dist/chat/__next._tree.txt +3 -0
- package/dist/web-dist/chat/__next.chat.__PAGE__.txt +24 -0
- package/dist/web-dist/chat/index.html +1 -0
- package/dist/web-dist/chat/index.txt +18 -0
- package/dist/web-dist/favicon.ico +0 -0
- package/dist/web-dist/favicon.svg +4 -0
- package/dist/web-dist/icon.svg +4 -0
- package/dist/web-dist/index.html +1 -0
- package/dist/web-dist/index.txt +32 -0
- package/dist/web-dist/live2d/live2dcubismcore.min.js +9 -0
- package/dist/web-dist/logo-circle.png +0 -0
- package/dist/web-dist/logo-circle.svg +4 -0
- package/dist/web-dist/logo-white.svg +3 -0
- package/dist/web-dist/logo.png +0 -0
- package/dist/web-dist/logo.svg +3 -0
- package/dist/web-dist/operator/__next._full.txt +18 -0
- package/dist/web-dist/operator/__next._tree.txt +3 -0
- package/dist/web-dist/operator/__next.operator.__PAGE__.txt +24 -0
- package/dist/web-dist/operator/index.html +1 -0
- package/dist/web-dist/operator/index.txt +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,15 +13,15 @@ npx @vxnus/siduri create my-companion
|
|
|
13
13
|
- **Node.js**: `v20.0.0` or newer
|
|
14
14
|
- **LLM API Key**: e.g. `OPENROUTER_API_KEY` for Brain organ
|
|
15
15
|
- **Optional Local Services**:
|
|
16
|
-
- **
|
|
17
|
-
-
|
|
16
|
+
- **PostgreSQL**: Required if PostgreSQL memory organ is enabled (local PostgreSQL server or cloud Supabase/Neon).
|
|
17
|
+
- **VOICEVOX**: For voice synthesis (auto-downloaded at runtime by default, or connect to standalone app).
|
|
18
18
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
21
|
- **Manifest-Driven Organ Discovery**: Dynamically discovers installed `@siduri-x/*` organs and generates custom, standalone ESM instance code.
|
|
22
22
|
- **Interactive Configuration Wizard**: Model catalog discovery for OpenRouter, manifest inspection for E Knowledge Hub, and guided organ parameters.
|
|
23
23
|
- **Zero Monolithic Bundling**: Scaffolds standard Node.js ESM projects with explicit dependency trees.
|
|
24
|
-
- **Diagnostics (`siduri doctor`)**: Runs environment variable validation, external service checks, database health probes, and organ-specific assertions.
|
|
24
|
+
- **Diagnostics (`siduri doctor`)**: Runs environment variable validation, schema conformance checks, external service checks, database health probes, and organ-specific assertions.
|
|
25
25
|
- **Database Migrations (`siduri db push`)**: Inspects database-owning organs (such as `@siduri-x/memory`) and executes SQL migrations with SHA-256 integrity checksums.
|
|
26
26
|
|
|
27
27
|
## CLI Usage
|
|
@@ -41,7 +41,6 @@ my-companion/
|
|
|
41
41
|
├── siduri.schema.json # Composed JSON Schema from organ manifests
|
|
42
42
|
├── .env.example # Only environment variables required by selected organs
|
|
43
43
|
├── README.md # Instance-specific guide
|
|
44
|
-
├── docker-compose.yml # Scaffolds PostgreSQL / VOICEVOX when selected
|
|
45
44
|
└── src/
|
|
46
45
|
└── index.js # Direct runtime bootstrapping with explicit organ factories
|
|
47
46
|
```
|
|
@@ -153,7 +153,7 @@ exports.BUILTIN_ORGAN_MANIFESTS = [
|
|
|
153
153
|
{
|
|
154
154
|
name: '@siduri-x/hands',
|
|
155
155
|
organType: 'hands',
|
|
156
|
-
version: '1.0.
|
|
156
|
+
version: '1.0.4',
|
|
157
157
|
displayName: 'Hands (MCP Tool Execution)',
|
|
158
158
|
description: 'Model Context Protocol tool management and cryptographically authorized action execution',
|
|
159
159
|
entrypoint: './dist/index.js',
|
|
@@ -272,7 +272,7 @@ exports.BUILTIN_ORGAN_MANIFESTS = [
|
|
|
272
272
|
{
|
|
273
273
|
name: '@siduri-x/memory',
|
|
274
274
|
organType: 'memory',
|
|
275
|
-
version: '1.0.
|
|
275
|
+
version: '1.0.7',
|
|
276
276
|
displayName: 'Memory (PostgreSQL FTS Claims)',
|
|
277
277
|
description: 'Relational semantic claims with Full-Text Search and companion isolation',
|
|
278
278
|
entrypoint: './dist/index.js',
|
|
@@ -92,7 +92,7 @@ describe('Phase 5: Clean-Machine Distribution & E2E Integration Suite', () => {
|
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
test('memory organ tarball packages migrations/001_initial_schema.sql', () => {
|
|
95
|
-
const memoryTarPath =
|
|
95
|
+
const memoryTarPath = getTarPath('@siduri-x/memory');
|
|
96
96
|
const listing = (0, node_child_process_1.execSync)(`tar -tzf ${memoryTarPath}`, { encoding: 'utf8' });
|
|
97
97
|
expect(listing).toContain('package/migrations/001_initial_schema.sql');
|
|
98
98
|
});
|
|
@@ -21,7 +21,7 @@ async function configureMemory(_context) {
|
|
|
21
21
|
choices: [
|
|
22
22
|
{ name: 'Supabase (Hosted Postgres with connection pooling)', value: 'supabase' },
|
|
23
23
|
{ name: 'Neon (Serverless Postgres with branch-per-companion)', value: 'neon' },
|
|
24
|
-
{ name: 'Local PostgreSQL (
|
|
24
|
+
{ name: 'Local PostgreSQL (System service or local installation)', value: 'local' },
|
|
25
25
|
{ name: 'Other PostgreSQL URL', value: 'other' },
|
|
26
26
|
],
|
|
27
27
|
});
|
package/dist/doctor.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export interface DoctorCheckResult {
|
|
2
|
-
category: 'Environment' | 'Services' | 'Database' | 'Health Probe';
|
|
2
|
+
category: 'Environment' | 'Services' | 'Database' | 'Health Probe' | 'Configuration';
|
|
3
3
|
name: string;
|
|
4
4
|
status: 'PASS' | 'FAIL' | 'OPTIONAL_MISSING' | 'SKIPPED';
|
|
5
5
|
organName?: string;
|
package/dist/doctor.js
CHANGED
|
@@ -8,6 +8,7 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const discovery_1 = require("./discovery");
|
|
10
10
|
const pg_1 = require("pg");
|
|
11
|
+
const schema_validator_1 = require("./schema-validator");
|
|
11
12
|
async function runDoctor(options = {}) {
|
|
12
13
|
const projectDir = options.projectDir ? node_path_1.default.resolve(options.projectDir) : process.cwd();
|
|
13
14
|
const configPath = node_path_1.default.join(projectDir, 'siduri.config.json');
|
|
@@ -46,6 +47,29 @@ async function runDoctor(options = {}) {
|
|
|
46
47
|
]);
|
|
47
48
|
const selectedManifests = [];
|
|
48
49
|
const results = [];
|
|
50
|
+
// 0. Schema Validation Check
|
|
51
|
+
const schemaPath = node_path_1.default.join(projectDir, 'siduri.schema.json');
|
|
52
|
+
if (node_fs_1.default.existsSync(schemaPath)) {
|
|
53
|
+
try {
|
|
54
|
+
const schema = JSON.parse(node_fs_1.default.readFileSync(schemaPath, 'utf8'));
|
|
55
|
+
(0, schema_validator_1.validateCompanionConfig)(config, schema);
|
|
56
|
+
results.push({
|
|
57
|
+
category: 'Configuration',
|
|
58
|
+
name: 'Schema Conformance',
|
|
59
|
+
status: 'PASS',
|
|
60
|
+
message: 'siduri.config.json conforms to siduri.schema.json',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
results.push({
|
|
65
|
+
category: 'Configuration',
|
|
66
|
+
name: 'Schema Conformance',
|
|
67
|
+
status: 'FAIL',
|
|
68
|
+
message: err.message,
|
|
69
|
+
remediation: 'Update siduri.config.json to conform to the generated schema.',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
49
73
|
// 1. Resolve manifests for selected organs
|
|
50
74
|
for (const organKey of organKeys) {
|
|
51
75
|
const m = registry.get(organKey) || registry.getAll().find((item) => item.configKey === organKey || item.organType === organKey);
|
package/dist/generator.d.ts
CHANGED
package/dist/generator.js
CHANGED
|
@@ -72,7 +72,7 @@ function getDefaultConfigForManifest(manifest) {
|
|
|
72
72
|
function generateInstanceFiles(options) {
|
|
73
73
|
const instanceName = options.name || 'my-siduri';
|
|
74
74
|
const instanceId = options.id || 'default';
|
|
75
|
-
const coreVersion = options.coreVersion || '^1.0.
|
|
75
|
+
const coreVersion = options.coreVersion || '^1.0.9';
|
|
76
76
|
const manifests = options.selectedManifests;
|
|
77
77
|
const hasMemory = manifests.some((m) => m.organType === 'memory');
|
|
78
78
|
const hasVoice = manifests.some((m) => m.organType === 'voice');
|
|
@@ -82,56 +82,7 @@ function generateInstanceFiles(options) {
|
|
|
82
82
|
const isVoicevox = hasVoice && (!voiceConfig || voiceConfig.provider === 'voicevox');
|
|
83
83
|
const memoryConfig = options.organConfigs?.memory || options.organConfigs?.['@siduri-x/memory'];
|
|
84
84
|
const isPostgresLocal = hasMemory && (!memoryConfig || memoryConfig.deployment === 'local' || memoryConfig.provider === 'postgres');
|
|
85
|
-
// 1.
|
|
86
|
-
let dockerComposeYaml;
|
|
87
|
-
const dockerServices = [];
|
|
88
|
-
const dockerVolumes = [];
|
|
89
|
-
if (hasMemory && isPostgresLocal) {
|
|
90
|
-
dockerServices.push([
|
|
91
|
-
' db:',
|
|
92
|
-
' image: postgres:15',
|
|
93
|
-
' environment:',
|
|
94
|
-
' POSTGRES_USER: postgres',
|
|
95
|
-
' POSTGRES_PASSWORD: password',
|
|
96
|
-
' POSTGRES_DB: siduri',
|
|
97
|
-
' ports:',
|
|
98
|
-
' - "5432:5432"',
|
|
99
|
-
' volumes:',
|
|
100
|
-
' - postgres_data:/var/lib/postgresql/data',
|
|
101
|
-
' healthcheck:',
|
|
102
|
-
' test: ["CMD-SHELL", "pg_isready -U postgres"]',
|
|
103
|
-
' interval: 2s',
|
|
104
|
-
' timeout: 5s',
|
|
105
|
-
' retries: 5',
|
|
106
|
-
].join('\n'));
|
|
107
|
-
dockerVolumes.push(' postgres_data:');
|
|
108
|
-
}
|
|
109
|
-
if (hasVoice && voiceConfig?.rvc?.enabled) {
|
|
110
|
-
dockerServices.push([
|
|
111
|
-
' rvc:',
|
|
112
|
-
' image: ghcr.io/vxnus-studio/rvc-headless:latest',
|
|
113
|
-
' ports:',
|
|
114
|
-
' - "50055:50055"',
|
|
115
|
-
' volumes:',
|
|
116
|
-
' - ./assets/voice:/app/models',
|
|
117
|
-
' environment:',
|
|
118
|
-
' - RVC_MODELS_DIR=/app/models',
|
|
119
|
-
].join('\n'));
|
|
120
|
-
}
|
|
121
|
-
if (dockerServices.length > 0) {
|
|
122
|
-
const composeLines = [
|
|
123
|
-
'version: "3.8"',
|
|
124
|
-
'',
|
|
125
|
-
'services:',
|
|
126
|
-
...dockerServices,
|
|
127
|
-
];
|
|
128
|
-
if (dockerVolumes.length > 0) {
|
|
129
|
-
composeLines.push('', 'volumes:', ...dockerVolumes);
|
|
130
|
-
}
|
|
131
|
-
composeLines.push('');
|
|
132
|
-
dockerComposeYaml = composeLines.join('\n');
|
|
133
|
-
}
|
|
134
|
-
// 2. package.json
|
|
85
|
+
// 1. package.json
|
|
135
86
|
const dependencies = {
|
|
136
87
|
'@siduri-x/core': coreVersion,
|
|
137
88
|
};
|
|
@@ -144,11 +95,6 @@ function generateInstanceFiles(options) {
|
|
|
144
95
|
doctor: 'siduri doctor',
|
|
145
96
|
db: 'siduri db',
|
|
146
97
|
};
|
|
147
|
-
if (dockerComposeYaml) {
|
|
148
|
-
scripts['services:up'] = 'docker compose up -d';
|
|
149
|
-
scripts['services:down'] = 'docker compose down';
|
|
150
|
-
scripts['services:logs'] = 'docker compose logs -f';
|
|
151
|
-
}
|
|
152
98
|
const packageJsonObj = {
|
|
153
99
|
name: instanceName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'my-siduri',
|
|
154
100
|
private: true,
|
|
@@ -215,7 +161,7 @@ function generateInstanceFiles(options) {
|
|
|
215
161
|
`import { readFile, stat, readdir } from 'node:fs/promises';`,
|
|
216
162
|
`import path from 'node:path';`,
|
|
217
163
|
`import { fileURLToPath } from 'node:url';`,
|
|
218
|
-
`import { SiduriRuntime, dispatchCompanionChat } from '@siduri-x/core';`,
|
|
164
|
+
`import { SiduriRuntime, dispatchCompanionChat, validateCompanionConfig } from '@siduri-x/core';`,
|
|
219
165
|
];
|
|
220
166
|
for (const m of manifests) {
|
|
221
167
|
importLines.push(`import { ${m.factory} } from '${m.name}';`);
|
|
@@ -241,6 +187,16 @@ function generateInstanceFiles(options) {
|
|
|
241
187
|
`const config = JSON.parse(`,
|
|
242
188
|
` await readFile(path.join(rootDir, 'siduri.config.json'), 'utf8')`,
|
|
243
189
|
`);`,
|
|
190
|
+
`const schemaPath = path.join(rootDir, 'siduri.schema.json');`,
|
|
191
|
+
`try {`,
|
|
192
|
+
` const schema = JSON.parse(await readFile(schemaPath, 'utf8'));`,
|
|
193
|
+
` validateCompanionConfig(config, schema);`,
|
|
194
|
+
`} catch (err) {`,
|
|
195
|
+
` if (err?.code !== 'ENOENT') {`,
|
|
196
|
+
` console.error('Config validation failed:', err.message);`,
|
|
197
|
+
` throw err;`,
|
|
198
|
+
` }`,
|
|
199
|
+
`}`,
|
|
244
200
|
'',
|
|
245
201
|
...instantiationLines,
|
|
246
202
|
'',
|
|
@@ -621,20 +577,16 @@ function generateInstanceFiles(options) {
|
|
|
621
577
|
'- **Environment**: Valid `.env` file (configured from `.env.example`)',
|
|
622
578
|
];
|
|
623
579
|
if (hasMemory) {
|
|
624
|
-
readmeLines.push('- **
|
|
625
|
-
readmeLines.push(' - **PostgreSQL**: Required for memory claims & durable state (or use cloud Supabase/Neon)');
|
|
580
|
+
readmeLines.push('- **PostgreSQL (Optional)**: Required if PostgreSQL memory organ is enabled (local PostgreSQL server or cloud Supabase/Neon).');
|
|
626
581
|
}
|
|
627
582
|
if (isVoicevox) {
|
|
628
583
|
readmeLines.push('- **VOICEVOX**: Note: The Voicevox engine executable will be securely auto-downloaded at runtime by Siduri if no local URL is provided.');
|
|
629
584
|
}
|
|
630
585
|
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`.');
|
|
631
|
-
if (dockerComposeYaml) {
|
|
632
|
-
readmeLines.push('', '### 3. Start Local Services (Docker)', '```bash', 'npm run services:up', '```', '*(To stop services later, run `npm run services:down`)*');
|
|
633
|
-
}
|
|
634
586
|
if (hasMemory) {
|
|
635
|
-
readmeLines.push('',
|
|
587
|
+
readmeLines.push('', '### 3. Database Migrations', 'Ensure `DATABASE_URL` in `.env` is reachable, then push the memory organ PostgreSQL schema:', '```bash', 'npx @vxnus/siduri db push', '```');
|
|
636
588
|
}
|
|
637
|
-
readmeLines.push('', `### ${hasMemory ?
|
|
589
|
+
readmeLines.push('', `### ${hasMemory ? '4' : '3'}. Diagnostics & Health Probe`, 'Verify all environment variables, schema conformance, services, and organ connections:', '```bash', 'npm run doctor', '```', '', `### ${hasMemory ? '5' : '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.');
|
|
638
590
|
const companionSlug = instanceName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
639
591
|
const createAssetsDirs = [];
|
|
640
592
|
if (hasBody) {
|
|
@@ -659,8 +611,5 @@ function generateInstanceFiles(options) {
|
|
|
659
611
|
createAssetsBodyDir: hasBody,
|
|
660
612
|
createAssetsDirs,
|
|
661
613
|
};
|
|
662
|
-
if (dockerComposeYaml) {
|
|
663
|
-
result['docker-compose.yml'] = dockerComposeYaml;
|
|
664
|
-
}
|
|
665
614
|
return result;
|
|
666
615
|
}
|
package/dist/generator.test.js
CHANGED
|
@@ -158,14 +158,13 @@ describe('Instance Generator Composition Invariants (Phase 3)', () => {
|
|
|
158
158
|
expect(files['README.md']).toContain('assets/body/companion-full');
|
|
159
159
|
expect(files['README.md']).toContain('assets/voice/companion-full');
|
|
160
160
|
expect(files['README.md']).toContain('Prerequisites');
|
|
161
|
-
//
|
|
162
|
-
expect(files['docker-compose.yml']).
|
|
163
|
-
expect(files['docker-compose.yml']).toContain('postgres:15');
|
|
161
|
+
// No docker compose generated (Docker completely removed, host-native runtime)
|
|
162
|
+
expect(files['docker-compose.yml']).toBeUndefined();
|
|
164
163
|
expect(files['README.md']).toContain('Voicevox engine executable will be securely auto-downloaded');
|
|
165
|
-
expect(pkg.scripts['services:up']).
|
|
166
|
-
expect(pkg.scripts['services:down']).
|
|
164
|
+
expect(pkg.scripts['services:up']).toBeUndefined();
|
|
165
|
+
expect(pkg.scripts['services:down']).toBeUndefined();
|
|
167
166
|
});
|
|
168
|
-
test('Composition E:
|
|
167
|
+
test('Composition E: Standalone companion never generates docker-compose.yml and validates config', () => {
|
|
169
168
|
const files = (0, generator_1.generateInstanceFiles)({
|
|
170
169
|
name: 'brain-solo',
|
|
171
170
|
selectedManifests: [MOCK_MANIFESTS.brain],
|
|
@@ -173,6 +172,7 @@ describe('Instance Generator Composition Invariants (Phase 3)', () => {
|
|
|
173
172
|
expect(files['docker-compose.yml']).toBeUndefined();
|
|
174
173
|
const pkg = JSON.parse(files['package.json']);
|
|
175
174
|
expect(pkg.scripts['services:up']).toBeUndefined();
|
|
175
|
+
expect(files['src/index.js']).toContain('validateCompanionConfig');
|
|
176
176
|
expect(files['public/index.html']).toBeDefined();
|
|
177
177
|
expect(files['public/index.html']).toContain('Memory Console');
|
|
178
178
|
expect(files['public/index.html']).toContain('Companion Chat');
|
package/dist/index.js
CHANGED
|
@@ -241,9 +241,6 @@ async function runCreateWizard(targetDir) {
|
|
|
241
241
|
else {
|
|
242
242
|
await (0, promises_1.writeFile)(node_path_1.default.join(publicDir, 'index.html'), files['public/index.html'], 'utf8');
|
|
243
243
|
}
|
|
244
|
-
if (files['docker-compose.yml']) {
|
|
245
|
-
await (0, promises_1.writeFile)(node_path_1.default.join(projectDir, 'docker-compose.yml'), files['docker-compose.yml'], 'utf8');
|
|
246
|
-
}
|
|
247
244
|
if (files.createAssetsDirs && files.createAssetsDirs.length > 0) {
|
|
248
245
|
for (const dir of files.createAssetsDirs) {
|
|
249
246
|
await (0, promises_1.mkdir)(node_path_1.default.join(projectDir, dir), { recursive: true });
|
|
@@ -267,9 +264,6 @@ async function runCreateWizard(targetDir) {
|
|
|
267
264
|
console.log(`Your Siduri companion is ready! Next steps:\n`);
|
|
268
265
|
console.log(` cd ${node_path_1.default.relative(process.cwd(), projectDir) || '.'}`);
|
|
269
266
|
console.log(` cp .env.example .env ${exports.colors.dim}# Fill in required API keys/credentials${exports.colors.reset}`);
|
|
270
|
-
if (files['docker-compose.yml']) {
|
|
271
|
-
console.log(` npm run services:up ${exports.colors.dim}# Start local Docker services (PostgreSQL / VOICEVOX)${exports.colors.reset}`);
|
|
272
|
-
}
|
|
273
267
|
const hasMemory = selectedManifests.some((m) => m.organType === 'memory');
|
|
274
268
|
if (hasMemory) {
|
|
275
269
|
console.log(` npx @vxnus/siduri db push ${exports.colors.dim}# Push PostgreSQL memory schema${exports.colors.reset}`);
|
|
@@ -131,7 +131,8 @@ describe('Localweb and CLI Standalone 1:1 Runtime & Chat Parity', () => {
|
|
|
131
131
|
});
|
|
132
132
|
const srcIndexJs = files['src/index.js'];
|
|
133
133
|
// Ensures single source of truth import
|
|
134
|
-
expect(srcIndexJs).toContain("import { SiduriRuntime, dispatchCompanionChat } from '@siduri-x/core';");
|
|
134
|
+
expect(srcIndexJs).toContain("import { SiduriRuntime, dispatchCompanionChat, validateCompanionConfig } from '@siduri-x/core';");
|
|
135
|
+
expect(srcIndexJs).toContain('validateCompanionConfig(config, schema);');
|
|
135
136
|
// Ensures /chat uses dispatchCompanionChat directly without ad-hoc runtimeResult envelope
|
|
136
137
|
expect(srcIndexJs).toContain('const response = await dispatchCompanionChat(runtime,');
|
|
137
138
|
expect(srcIndexJs).toContain('res.end(JSON.stringify(response));');
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class ConfigValidationError extends Error {
|
|
2
|
+
errors: string[];
|
|
3
|
+
constructor(errors: string[]);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Validates a companion configuration object against a JSON schema (draft-07 compatible).
|
|
7
|
+
* Throws ConfigValidationError if validation errors are detected.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateCompanionConfig(config: unknown, schema: any, path?: string): void;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigValidationError = void 0;
|
|
4
|
+
exports.validateCompanionConfig = validateCompanionConfig;
|
|
5
|
+
class ConfigValidationError extends Error {
|
|
6
|
+
errors;
|
|
7
|
+
constructor(errors) {
|
|
8
|
+
super(`Siduri configuration validation failed:\n${errors.map((e) => ` - ${e}`).join('\n')}`);
|
|
9
|
+
this.name = 'ConfigValidationError';
|
|
10
|
+
this.errors = errors;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.ConfigValidationError = ConfigValidationError;
|
|
14
|
+
/**
|
|
15
|
+
* Validates a companion configuration object against a JSON schema (draft-07 compatible).
|
|
16
|
+
* Throws ConfigValidationError if validation errors are detected.
|
|
17
|
+
*/
|
|
18
|
+
function validateCompanionConfig(config, schema, path = '$') {
|
|
19
|
+
const errors = [];
|
|
20
|
+
function validateNode(value, nodeSchema, curPath) {
|
|
21
|
+
if (!nodeSchema || typeof nodeSchema !== 'object')
|
|
22
|
+
return;
|
|
23
|
+
// Type validation
|
|
24
|
+
if (nodeSchema.type !== undefined) {
|
|
25
|
+
const type = nodeSchema.type;
|
|
26
|
+
if (type === 'object') {
|
|
27
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
28
|
+
errors.push(`${curPath}: expected object, received ${value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (type === 'array') {
|
|
33
|
+
if (!Array.isArray(value)) {
|
|
34
|
+
errors.push(`${curPath}: expected array, received ${typeof value}`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (type === 'string') {
|
|
39
|
+
if (typeof value !== 'string') {
|
|
40
|
+
errors.push(`${curPath}: expected string, received ${typeof value}`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (type === 'number') {
|
|
45
|
+
if (typeof value !== 'number' || Number.isNaN(value)) {
|
|
46
|
+
errors.push(`${curPath}: expected number, received ${typeof value}`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (type === 'integer') {
|
|
51
|
+
if (typeof value !== 'number' || !Number.isInteger(value)) {
|
|
52
|
+
errors.push(`${curPath}: expected integer, received ${typeof value}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (type === 'boolean') {
|
|
57
|
+
if (typeof value !== 'boolean') {
|
|
58
|
+
errors.push(`${curPath}: expected boolean, received ${typeof value}`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// Enum validation
|
|
64
|
+
if (Array.isArray(nodeSchema.enum)) {
|
|
65
|
+
if (!nodeSchema.enum.includes(value)) {
|
|
66
|
+
errors.push(`${curPath}: invalid value ${JSON.stringify(value)}, expected one of: ${nodeSchema.enum.map((v) => JSON.stringify(v)).join(', ')}`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Object properties validation
|
|
71
|
+
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
72
|
+
if (Array.isArray(nodeSchema.required)) {
|
|
73
|
+
for (const reqKey of nodeSchema.required) {
|
|
74
|
+
if (value[reqKey] === undefined) {
|
|
75
|
+
errors.push(`${curPath}.${reqKey}: is required`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const definedProps = nodeSchema.properties || {};
|
|
80
|
+
if (nodeSchema.additionalProperties === false) {
|
|
81
|
+
for (const key of Object.keys(value)) {
|
|
82
|
+
// Allow $schema property at root level
|
|
83
|
+
if (curPath === '$' && key === '$schema')
|
|
84
|
+
continue;
|
|
85
|
+
if (!(key in definedProps)) {
|
|
86
|
+
errors.push(`${curPath}.${key}: unexpected property is not allowed`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
for (const [propName, propSchema] of Object.entries(definedProps)) {
|
|
91
|
+
if (value[propName] !== undefined) {
|
|
92
|
+
validateNode(value[propName], propSchema, `${curPath}.${propName}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Array items validation
|
|
97
|
+
if (Array.isArray(value) && nodeSchema.items) {
|
|
98
|
+
value.forEach((item, index) => {
|
|
99
|
+
validateNode(item, nodeSchema.items, `${curPath}[${index}]`);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
validateNode(config, schema, path);
|
|
104
|
+
if (errors.length > 0) {
|
|
105
|
+
throw new ConfigValidationError(errors);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" class="h-full antialiased dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0xhe1hasjan-9.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/2kcqevsmv6kh2.js"/><script src="/_next/static/chunks/1_yae15ffa5f6.js" async=""></script><script src="/_next/static/chunks/3bx2gs3idjmo1.js" async=""></script><script src="/_next/static/chunks/32z87id9k6i2z.js" async=""></script><script src="/_next/static/chunks/turbopack-3eipe4c-imn5l.js" async=""></script><script src="/_next/static/chunks/0uwih7sydv413.js" async="" crossorigin=""></script><link rel="preload" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Serif+JP:wght@400;500;700&display=swap" as="style"/><meta name="robots" content="noindex"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><title>404: This page could not be found.</title><title>Siduri — Local-First Companion</title><meta name="description" content="Siduri — a local-first companion with explicit memory, grounded knowledge, and optional presence."/><link rel="icon" href="/favicon.ico?favicon.3rlors1ui1gw9.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/favicon.ico"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Serif+JP:wght@400;500;700&display=swap" rel="stylesheet"/><script src="/_next/static/chunks/0cz1d0mv5g_q7.js" noModule=""></script></head><body class="min-h-full flex flex-col bg-[#0b0b0e] text-[#eee8df] selection:bg-[#d99a68]/30 selection:text-[#f4c28d]"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/2kcqevsmv6kh2.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[81869,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"default\"]\n3:I[57830,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"default\"]\n4:I[44101,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[44101,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"ViewportBoundary\"]\na:I[44101,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"MetadataBoundary\"]\nc:I[4626,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/0xhe1hasjan-9.css\",\"style\"]\n:HL[\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500\u0026family=Noto+Sans+JP:wght@400;500;700\u0026family=Noto+Serif+JP:wght@400;500;700\u0026display=swap\",\"style\"]\n7:X\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},\"$undefined\",\"$undefined\",4608]},\"$undefined\",\"$undefined\",4608]},\"$undefined\",\"$undefined\",4624],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xhe1hasjan-9.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0uwih7sydv413.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"h-full antialiased dark\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"link\",null,{\"rel\":\"preconnect\",\"href\":\"https://fonts.googleapis.com\"}],[\"$\",\"link\",null,{\"rel\":\"preconnect\",\"href\":\"https://fonts.gstatic.com\",\"crossOrigin\":\"anonymous\"}],[\"$\",\"link\",null,{\"href\":\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500\u0026family=Noto+Sans+JP:wght@400;500;700\u0026family=Noto+Serif+JP:wght@400;500;700\u0026display=swap\",\"rel\":\"stylesheet\"}]]}],[\"$\",\"body\",null,{\"className\":\"min-h-full flex flex-col bg-[#0b0b0e] text-[#eee8df] selection:bg-[#d99a68]/30 selection:text-[#f4c28d]\",\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$7\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xhe1hasjan-9.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"pWHUixFDDvANZeAf-shqT\"}\n"])</script><script>self.__next_f.push([1,"7:C\n9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"d:I[89236,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"IconMark\"]\n6:null\nb:[[\"$\",\"title\",\"0\",{\"children\":\"Siduri — Local-First Companion\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Siduri — a local-first companion with explicit memory, grounded knowledge, and optional presence.\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.3rlors1ui1gw9.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"link\",\"5\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\"}],[\"$\",\"$Ld\",\"6\",{}]]\n"])</script></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" class="h-full antialiased dark"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0xhe1hasjan-9.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/2kcqevsmv6kh2.js"/><script src="/_next/static/chunks/1_yae15ffa5f6.js" async=""></script><script src="/_next/static/chunks/3bx2gs3idjmo1.js" async=""></script><script src="/_next/static/chunks/32z87id9k6i2z.js" async=""></script><script src="/_next/static/chunks/turbopack-3eipe4c-imn5l.js" async=""></script><script src="/_next/static/chunks/0uwih7sydv413.js" async="" crossorigin=""></script><link rel="preload" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Serif+JP:wght@400;500;700&display=swap" as="style"/><meta name="robots" content="noindex"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><title>404: This page could not be found.</title><title>Siduri — Local-First Companion</title><meta name="description" content="Siduri — a local-first companion with explicit memory, grounded knowledge, and optional presence."/><link rel="icon" href="/favicon.ico?favicon.3rlors1ui1gw9.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/favicon.ico"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Serif+JP:wght@400;500;700&display=swap" rel="stylesheet"/><script src="/_next/static/chunks/0cz1d0mv5g_q7.js" noModule=""></script></head><body class="min-h-full flex flex-col bg-[#0b0b0e] text-[#eee8df] selection:bg-[#d99a68]/30 selection:text-[#f4c28d]"><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/2kcqevsmv6kh2.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[81869,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"default\"]\n3:I[57830,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"default\"]\n4:I[44101,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[44101,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"ViewportBoundary\"]\na:I[44101,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"MetadataBoundary\"]\nc:I[4626,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"default\",1]\n:HL[\"/_next/static/chunks/0xhe1hasjan-9.css\",\"style\"]\n:HL[\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500\u0026family=Noto+Sans+JP:wght@400;500;700\u0026family=Noto+Serif+JP:wght@400;500;700\u0026display=swap\",\"style\"]\n7:X\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_not-found\",\"\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},\"$undefined\",\"$undefined\",4608]},\"$undefined\",\"$undefined\",4608]},\"$undefined\",\"$undefined\",4624],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xhe1hasjan-9.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0uwih7sydv413.js\",\"async\":true,\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"h-full antialiased dark\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"link\",null,{\"rel\":\"preconnect\",\"href\":\"https://fonts.googleapis.com\"}],[\"$\",\"link\",null,{\"rel\":\"preconnect\",\"href\":\"https://fonts.gstatic.com\",\"crossOrigin\":\"anonymous\"}],[\"$\",\"link\",null,{\"href\":\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500\u0026family=Noto+Sans+JP:wght@400;500;700\u0026family=Noto+Serif+JP:wght@400;500;700\u0026display=swap\",\"rel\":\"stylesheet\"}]]}],[\"$\",\"body\",null,{\"className\":\"min-h-full flex flex-col bg-[#0b0b0e] text-[#eee8df] selection:bg-[#d99a68]/30 selection:text-[#f4c28d]\",\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:style\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:children:props:children:1:props:style\",\"children\":404}],[\"$\",\"div\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:style\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$0:f:0:1:0:props:children:1:props:children:1:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style\",\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$7\"]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0xhe1hasjan-9.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"pWHUixFDDvANZeAf-shqT\"}\n"])</script><script>self.__next_f.push([1,"7:C\n9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"d:I[89236,[\"/_next/static/chunks/0uwih7sydv413.js\"],\"IconMark\"]\n6:null\nb:[[\"$\",\"title\",\"0\",{\"children\":\"Siduri — Local-First Companion\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Siduri — a local-first companion with explicit memory, grounded knowledge, and optional presence.\"}],[\"$\",\"link\",\"2\",{\"rel\":\"icon\",\"href\":\"/favicon.ico?favicon.3rlors1ui1gw9.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"link\",\"5\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\"}],[\"$\",\"$Ld\",\"6\",{}]]\n"])</script></body></html>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
1:"$Sreact.fragment"
|
|
2
|
+
2:I[80413,["/_next/static/chunks/0uwih7sydv413.js","/_next/static/chunks/2s3d1bfr0l4b0.js"],""]
|
|
3
|
+
:HL["/logo-circle.svg","image"]
|
|
4
|
+
c:X
|
|
5
|
+
0:{"buildId":"pWHUixFDDvANZeAf-shqT","data":[{"rsc":["$","$1","c",{"children":[["$","div",null,{"className":"home-page bg-[#09090c] min-h-screen text-[var(--siduri-text-primary)] font-sans","children":[["$","header",null,{"className":"home-nav","children":["$","div",null,{"className":"home-container home-nav-inner flex items-center justify-between py-4","children":[["$","$L2",null,{"href":"/","className":"brand-link flex items-center gap-2","aria-label":"Siduri Home","children":[["$","img",null,{"src":"/logo-circle.svg","alt":"Siduri-X Logo","className":"w-6 h-6 rounded-full shrink-0","width":24,"height":24}],["$","span",null,{"className":"font-bold tracking-widest text-sm","children":"SIDURI-X"}]]}],["$","nav",null,{"className":"nav-links flex gap-6 text-sm text-[var(--siduri-text-muted)]","aria-label":"Main Navigation","children":[["$","$L2",null,{"href":"/chat","className":"hover:text-[var(--siduri-text-primary)] transition-colors","children":"Chat"}],["$","$L2",null,{"href":"/operator","className":"hover:text-[var(--siduri-text-primary)] transition-colors","children":"Operator Console"}]]}],["$","div",null,{"children":["$","$L2",null,{"href":"/chat","className":"nav-cta inline-flex items-center gap-2 text-xs font-mono border border-[var(--siduri-border-subtle)] px-4 py-2 rounded-full hover:bg-[var(--siduri-surface)] transition-all","children":["Open Chat ",["$","span",null,{"children":"→"}]]}]}]]}]}],["$","main",null,{"children":[["$","section",null,{"className":"py-24 md:py-32 border-b border-[var(--siduri-border-subtle)] relative overflow-hidden","children":["$","div",null,{"className":"home-container relative z-10 text-center flex flex-col items-center","children":[["$","div",null,{"className":"inline-flex items-center gap-2 px-3 py-1 rounded-full border border-[var(--siduri-border-ember)] bg-[var(--siduri-tint-low)] text-[var(--siduri-ember-light)] text-[10px] font-mono tracking-widest uppercase mb-8","children":[["$","span",null,{"className":"w-1.5 h-1.5 rounded-full bg-[var(--siduri-online)] shadow-[0_0_8px_rgba(127,199,154,0.6)]"}],"Standalone Companion Framework · Version 1.0"]}],["$","h1",null,{"className":"text-4xl sm:text-5xl md:text-6xl font-normal font-serif text-[var(--siduri-text-primary)] tracking-tight leading-[1.15] mb-6 max-w-4xl","children":"A companion grown from memory, powered by modular cognition."}],["$","p",null,{"className":"text-base sm:text-lg text-[var(--siduri-text-secondary)] font-sans leading-relaxed mb-10 max-w-2xl font-light","children":"Siduri-X is an intelligent companion designed with authoritative memory, atomic behavioral gating, and a strict 10-organ architecture. She starts as a blank slate and forms her identity entirely through your interactions."}],["$","div",null,{"className":"flex flex-wrap justify-center items-center gap-4","children":[["$","$L2",null,{"href":"/chat","className":"inline-flex items-center gap-3 px-6 py-3.5 rounded-xl bg-[var(--siduri-ember)] text-[#1b1619] font-sans font-semibold text-sm tracking-wide transition-all hover:brightness-110 shadow-[0_4px_20px_rgba(217,154,104,0.2)]","children":["Launch Companion",["$","span",null,{"className":"font-mono text-base","children":"→"}]]}],["$","$L2",null,{"href":"/operator","className":"inline-flex items-center gap-2.5 px-6 py-3.5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] text-[var(--siduri-text-primary)] font-sans font-medium text-sm transition-all hover:border-[var(--siduri-border-ember)] hover:bg-[var(--siduri-tint-low)]","children":[["$","span",null,{"children":"⌘"}],"Operator Console"]}]]}]]}]}],["$","section",null,{"className":"py-20 md:py-28 border-b border-[var(--siduri-border-subtle)] bg-[#0e0e12]","children":["$","div",null,{"className":"home-container","children":[["$","div",null,{"className":"mb-14 text-center max-w-3xl mx-auto","children":[["$","p",null,{"className":"text-[10px] font-mono uppercase tracking-widest text-[var(--siduri-ember)] mb-2","children":"Decoupled Philosophy"}],"$L3","$L4"]}],"$L5"]}]}],"$L6","$L7"]}],"$L8"]}],["$L9"],"$La"]}],"isPartial":"$@b","staleTime":"$c","varyParams":null},{"rsc":"$Ld","isPartial":"$@e","staleTime":"$c","varyParams":null},{"rsc":"$Lf","isPartial":"$@10","staleTime":"$c","varyParams":null}],"isUpgradeableISRFallback":false,"a":"$@11","rootVaryParams":null,"needsRuntimeRequest":"$@12"}
|
|
6
|
+
16:I[44101,["/_next/static/chunks/0uwih7sydv413.js"],"OutletBoundary"]
|
|
7
|
+
17:"$Sreact.suspense"
|
|
8
|
+
19:I[44101,["/_next/static/chunks/0uwih7sydv413.js"],"ViewportBoundary"]
|
|
9
|
+
1a:I[44101,["/_next/static/chunks/0uwih7sydv413.js"],"MetadataBoundary"]
|
|
10
|
+
1b:I[89236,["/_next/static/chunks/0uwih7sydv413.js"],"IconMark"]
|
|
11
|
+
1c:I[81869,["/_next/static/chunks/0uwih7sydv413.js"],"default"]
|
|
12
|
+
1d:I[57830,["/_next/static/chunks/0uwih7sydv413.js"],"default"]
|
|
13
|
+
:HL["/_next/static/chunks/0xhe1hasjan-9.css","style"]
|
|
14
|
+
:HL["https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Serif+JP:wght@400;500;700&display=swap","style"]
|
|
15
|
+
3:["$","h2",null,{"className":"text-2xl sm:text-3xl font-serif font-normal text-[var(--siduri-text-primary)] mb-4","children":"The 10-Organ Architecture"}]
|
|
16
|
+
4:["$","p",null,{"className":"text-sm text-[var(--siduri-text-secondary)] leading-relaxed","children":"Siduri is not a chatbot. She is a cognition runtime composed of independent organs. Every decision originates from the Brain, while other organs perceive, remember, act, and embody."}]
|
|
17
|
+
5:["$","div",null,{"className":"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4","children":[["$","div","Brain",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Brain"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Cognition, planning, and authoritative decision making."}]]}],["$","div","Memory",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Memory"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"PostgreSQL-backed authoritative storage of claims and preferences."}]]}],["$","div","Behavior",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Behavior"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Atomic directive state machine and personality projection."}]]}],["$","div","Knowledge",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Knowledge"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"External factual context and verifiable E-compatible packs."}]]}],["$","div","Hands",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Hands"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Tool execution and strict cryptographic action policy capabilities."}]]}],["$","div","Ear",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Ear"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Audio transcription, perception, and sensory input ingestion."}]]}],["$","div","Vision",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Vision"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Visual observation, cropping, and OCR interpretation."}]]}],["$","div","Voice",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Voice"}],"$L13"]}],"$L14","$L15"]}]
|
|
18
|
+
6:["$","section",null,{"className":"py-20 md:py-28 border-b border-[var(--siduri-border-subtle)]","children":["$","div",null,{"className":"home-container grid grid-cols-1 lg:grid-cols-2 gap-16 items-center","children":[["$","div",null,{"children":[["$","p",null,{"className":"text-[10px] font-mono uppercase tracking-widest text-[var(--siduri-ember)] mb-2","children":"Authoritative State"}],["$","h2",null,{"className":"text-3xl font-serif font-normal text-[var(--siduri-text-primary)] mb-5","children":"Blank Slate Identity"}],["$","p",null,{"className":"text-sm text-[var(--siduri-text-secondary)] leading-relaxed mb-6","children":"Unlike standard conversational agents, Siduri starts with no pre-baked persona. She learns, remembers, and adapts over time. When you share preferences, they are staged as structured candidates. You decide what enters her long-term memory with explicit single-click approval."}],["$","ul",null,{"className":"space-y-3 text-xs text-[var(--siduri-text-muted)] font-mono","children":[["$","li",null,{"className":"flex items-center gap-2.5","children":[["$","span",null,{"className":"text-[var(--siduri-online)]","children":"✓"}],"No hidden relationship assumptions"]}],["$","li",null,{"className":"flex items-center gap-2.5","children":[["$","span",null,{"className":"text-[var(--siduri-online)]","children":"✓"}],"Structured episodic and semantic memory"]}],["$","li",null,{"className":"flex items-center gap-2.5","children":[["$","span",null,{"className":"text-[var(--siduri-online)]","children":"✓"}],"Full revocation and override controls"]}]]}]]}],["$","div",null,{"className":"p-8 rounded-2xl border border-[var(--siduri-border-ember)] bg-[var(--siduri-surface)] shadow-[0_10px_35px_rgba(0,0,0,0.4)] relative","children":[["$","div",null,{"className":"absolute top-0 right-8 -translate-y-1/2 bg-[var(--siduri-bg)] px-3 text-[10px] font-mono text-[var(--siduri-ember)] tracking-widest uppercase","children":"Operator View"}],["$","div",null,{"className":"space-y-4 font-mono text-xs","children":["$","div",null,{"className":"p-3 border border-[var(--siduri-border-subtle)] rounded bg-[#13131a]","children":[["$","div",null,{"className":"text-[var(--siduri-text-muted)] mb-1","children":"Incoming Claim"}],["$","div",null,{"className":"text-[var(--siduri-online)] font-bold","children":"\"User prefers concise, technical explanations.\""}],["$","div",null,{"className":"flex gap-2 mt-3","children":[["$","span",null,{"className":"bg-[var(--siduri-online)] text-black px-2 py-0.5 rounded font-bold cursor-pointer","children":"APPROVE"}],["$","span",null,{"className":"border border-[var(--siduri-border-subtle)] text-[var(--siduri-text-muted)] px-2 py-0.5 rounded cursor-pointer","children":"REJECT"}]]}]]}]}]]}]]}]}]
|
|
19
|
+
7:["$","section",null,{"className":"py-20 md:py-28 bg-[#09090c]","children":["$","div",null,{"className":"home-container text-center max-w-2xl mx-auto","children":[["$","h2",null,{"className":"text-3xl sm:text-4xl font-serif font-normal text-[var(--siduri-text-primary)] mb-5","children":"Private, local, and yours."}],["$","p",null,{"className":"text-sm text-[var(--siduri-text-secondary)] leading-relaxed mb-8","children":"Siduri is designed for local-first operations and explicit consent. The CLI dynamically generates a standalone companion instance leveraging only the organ packages you need. Run it completely on your own machine."}],["$","div",null,{"className":"bg-[#13131a] p-4 rounded-xl border border-[var(--siduri-border-subtle)] inline-block text-left text-sm font-mono text-[var(--siduri-text-primary)] shadow-lg mx-auto","children":[["$","span",null,{"className":"text-emerald-400","children":"$$"}]," npx @vxnus/siduri create my-companion"]}]]}]}]
|
|
20
|
+
8:["$","footer",null,{"className":"py-14 border-t border-[var(--siduri-border-subtle)] bg-[#0e0e12]","children":["$","div",null,{"className":"home-container flex flex-col sm:flex-row items-center justify-between gap-6","children":[["$","div",null,{"className":"flex items-center gap-3","children":[["$","img",null,{"src":"/logo-circle.svg","alt":"Siduri-X Logo","className":"w-5 h-5 rounded-full shrink-0","width":20,"height":20}],["$","span",null,{"className":"font-bold tracking-widest text-xs text-[var(--siduri-text-primary)]","children":"SIDURI-X"}]]}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-dim)] font-sans text-center sm:text-left","children":"Local-first AI companion framework."}],["$","div",null,{"className":"flex items-center gap-5 text-xs text-[var(--siduri-text-muted)]","children":[["$","$L2",null,{"href":"/chat","className":"hover:text-[var(--siduri-text-primary)]","children":"Chat"}],["$","$L2",null,{"href":"/operator","className":"hover:text-[var(--siduri-text-primary)]","children":"Operator"}]]}]]}]}]
|
|
21
|
+
9:["$","script","script-0",{"src":"/_next/static/chunks/2s3d1bfr0l4b0.js","async":true}]
|
|
22
|
+
a:["$","$L16",null,{"children":["$","$17",null,{"name":"Next.MetadataOutlet","children":"$@18"}]}]
|
|
23
|
+
d:["$","$1","h",{"children":[null,["$","$L19",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L1a",null,{"children":["$","$17",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"Siduri — Local-First Companion"}],["$","meta","1",{"name":"description","content":"Siduri — a local-first companion with explicit memory, grounded knowledge, and optional presence."}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.3rlors1ui1gw9.ico","sizes":"256x256","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/favicon.ico"}],["$","link","4",{"rel":"icon","href":"/favicon.svg","type":"image/svg+xml"}],["$","link","5",{"rel":"apple-touch-icon","href":"/apple-touch-icon.png"}],["$","$L1b","6",{}]]}]}]}],null]}]
|
|
24
|
+
f:["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/chunks/0xhe1hasjan-9.css","precedence":"next"}],["$","script","script-0",{"src":"/_next/static/chunks/0uwih7sydv413.js","async":true}]],["$","html",null,{"lang":"en","className":"h-full antialiased dark","children":[["$","head",null,{"children":[["$","link",null,{"rel":"preconnect","href":"https://fonts.googleapis.com"}],["$","link",null,{"rel":"preconnect","href":"https://fonts.gstatic.com","crossOrigin":"anonymous"}],["$","link",null,{"href":"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Noto+Sans+JP:wght@400;500;700&family=Noto+Serif+JP:wght@400;500;700&display=swap","rel":"stylesheet"}]]}],["$","body",null,{"className":"min-h-full flex flex-col bg-[#0b0b0e] text-[#eee8df] selection:bg-[#d99a68]/30 selection:text-[#f4c28d]","children":["$","$L1c",null,{"parallelRouterKey":"children","template":["$","$L1d",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]]}]]}]
|
|
25
|
+
13:["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Queued speech synthesis (Edge-TTS, Piper, VOICEVOX) and auditory expression."}]
|
|
26
|
+
14:["$","div","Body",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Body"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Renderer-agnostic avatar expression (Live2D) and embodiment."}]]}]
|
|
27
|
+
15:["$","div","Observation",{"className":"p-5 rounded-xl border border-[var(--siduri-border-subtle)] bg-[var(--siduri-surface)] transition-all hover:border-[var(--siduri-border-ember)]","children":[["$","h3",null,{"className":"text-sm font-bold font-mono text-[var(--siduri-ember-light)] mb-2","children":"Observation"}],["$","p",null,{"className":"text-xs text-[var(--siduri-text-secondary)] leading-relaxed","children":"Event frame deduplication and real-time evidence extraction."}]]}]
|
|
28
|
+
18:null
|
|
29
|
+
12:true
|
|
30
|
+
c:300
|
|
31
|
+
c:C
|
|
32
|
+
11:0
|
|
33
|
+
e:"$undefined"
|
|
34
|
+
10:"$undefined"
|
|
35
|
+
b:"$undefined"
|