@vxnus/siduri 0.1.1 → 0.1.3
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 +7 -1
- package/dist/clean-machine-e2e.test.js +11 -3
- package/dist/configurators/body.js +26 -10
- package/dist/configurators/voice.js +317 -32
- package/dist/configurators.test.js +10 -3
- package/dist/generator.js +9 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/release-check.js +2 -2
- package/dist/web-dist/404/index.html +1 -1
- package/dist/web-dist/404.html +1 -1
- package/dist/web-dist/__next.__PAGE__.txt +1 -1
- package/dist/web-dist/__next._full.txt +1 -1
- package/dist/web-dist/__next._tree.txt +1 -1
- package/dist/web-dist/_next/static/chunks/01iq592nolf0t.js +30 -0
- package/dist/web-dist/_not-found/__next._full.txt +1 -1
- package/dist/web-dist/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/web-dist/_not-found/__next._tree.txt +1 -1
- package/dist/web-dist/_not-found/index.html +1 -1
- package/dist/web-dist/_not-found/index.txt +1 -1
- package/dist/web-dist/chat/__next._full.txt +2 -2
- package/dist/web-dist/chat/__next._tree.txt +1 -1
- package/dist/web-dist/chat/__next.chat.__PAGE__.txt +2 -2
- package/dist/web-dist/chat/index.html +1 -1
- package/dist/web-dist/chat/index.txt +2 -2
- package/dist/web-dist/index.html +1 -1
- package/dist/web-dist/index.txt +1 -1
- package/dist/web-dist/operator/__next._full.txt +1 -1
- package/dist/web-dist/operator/__next._tree.txt +1 -1
- package/dist/web-dist/operator/__next.operator.__PAGE__.txt +1 -1
- package/dist/web-dist/operator/index.html +1 -1
- package/dist/web-dist/operator/index.txt +1 -1
- package/package.json +7 -7
- package/dist/web-dist/_next/static/chunks/39nefv-hczfy7.js +0 -30
- package/dist/web-dist/live2d/akaituno/akaituno.8192/texture_00.png +0 -0
- package/dist/web-dist/live2d/akaituno/akaituno.cdi3.json +0 -296
- package/dist/web-dist/live2d/akaituno/akaituno.moc3 +0 -0
- package/dist/web-dist/live2d/akaituno/akaituno.model3.json +0 -42
- package/dist/web-dist/live2d/akaituno/akaituno.physics3.json +0 -839
- package/dist/web-dist/live2d/akaituno/eye_color.exp3.json +0 -12
- package/dist/web-dist/live2d/akaituno/eyes_zetubou.exp3.json +0 -12
- package/dist/web-dist/live2d/akaituno/face_aozame.exp3.json +0 -12
- package/dist/web-dist/live2d/akaituno/hair_open.exp3.json +0 -12
- /package/dist/web-dist/_next/static/{_zOqKpMPc6RDqk04fUScI → jA7i3F3whceXTT5sOtVhE}/_buildManifest.js +0 -0
- /package/dist/web-dist/_next/static/{_zOqKpMPc6RDqk04fUScI → jA7i3F3whceXTT5sOtVhE}/_clientMiddlewareManifest.js +0 -0
- /package/dist/web-dist/_next/static/{_zOqKpMPc6RDqk04fUScI → jA7i3F3whceXTT5sOtVhE}/_ssgManifest.js +0 -0
|
@@ -32,7 +32,7 @@ exports.BUILTIN_ORGAN_MANIFESTS = [
|
|
|
32
32
|
{
|
|
33
33
|
name: '@siduri-x/body',
|
|
34
34
|
organType: 'body',
|
|
35
|
-
version: '1.0.
|
|
35
|
+
version: '1.0.2',
|
|
36
36
|
displayName: 'Body (Live2D & Avatar State)',
|
|
37
37
|
description: 'Renderer-agnostic avatar expression and embodiment event adapter',
|
|
38
38
|
entrypoint: './dist/index.js',
|
|
@@ -49,6 +49,12 @@ exports.BUILTIN_ORGAN_MANIFESTS = [
|
|
|
49
49
|
initialExpression: {
|
|
50
50
|
type: 'string',
|
|
51
51
|
default: 'neutral'
|
|
52
|
+
},
|
|
53
|
+
modelPath: {
|
|
54
|
+
type: 'string'
|
|
55
|
+
},
|
|
56
|
+
modelUrl: {
|
|
57
|
+
type: 'string'
|
|
52
58
|
}
|
|
53
59
|
}
|
|
54
60
|
},
|
|
@@ -24,7 +24,7 @@ describe('Phase 5: Clean-Machine Distribution & E2E Integration Suite', () => {
|
|
|
24
24
|
{ filter: '@siduri-x/body', tarName: 'siduri-x-body-1.0.1.tgz', isOrgan: true },
|
|
25
25
|
{ filter: '@siduri-x/voice', tarName: 'siduri-x-voice-1.0.2.tgz', isOrgan: true },
|
|
26
26
|
{ filter: '@siduri-x/observation', tarName: 'siduri-x-observation-1.0.1.tgz', isOrgan: true },
|
|
27
|
-
{ filter: '@vxnus/siduri', tarName: 'vxnus-siduri-0.1.
|
|
27
|
+
{ filter: '@vxnus/siduri', tarName: 'vxnus-siduri-0.1.2.tgz', isOrgan: false },
|
|
28
28
|
];
|
|
29
29
|
beforeAll(() => {
|
|
30
30
|
// 1. Prepare clean directories
|
|
@@ -123,7 +123,11 @@ describe('Phase 5: Clean-Machine Distribution & E2E Integration Suite', () => {
|
|
|
123
123
|
expect(node_fs_1.default.existsSync(node_path_1.default.join(instanceDir, 'node_modules/@siduri-x/voice'))).toBe(false);
|
|
124
124
|
expect(node_fs_1.default.existsSync(node_path_1.default.join(instanceDir, 'siduri-x-runtime.js'))).toBe(false);
|
|
125
125
|
// 3. Run node src/index.js (starts cleanly without PostgreSQL or unselected organs)
|
|
126
|
-
const startOutput = (0, node_child_process_1.execSync)('node src/index.js', {
|
|
126
|
+
const startOutput = (0, node_child_process_1.execSync)('node src/index.js', {
|
|
127
|
+
cwd: instanceDir,
|
|
128
|
+
env: { ...process.env, PORT: '0' },
|
|
129
|
+
encoding: 'utf8',
|
|
130
|
+
});
|
|
127
131
|
expect(startOutput).toContain('✓ Siduri [CleanBrainOnly] initialized with [Brain].');
|
|
128
132
|
// 4. Verify doctor from standalone directory
|
|
129
133
|
const doctorPass = (0, node_child_process_1.execSync)(`node ${node_path_1.default.resolve(repoRoot, 'cli/dist/index.js')} doctor`, {
|
|
@@ -162,7 +166,11 @@ describe('Phase 5: Clean-Machine Distribution & E2E Integration Suite', () => {
|
|
|
162
166
|
node_fs_1.default.writeFileSync(node_path_1.default.join(instanceDir, 'src/index.js'), files['src/index.js']);
|
|
163
167
|
(0, node_child_process_1.execSync)('npm install --no-audit --no-fund', { cwd: instanceDir, stdio: 'pipe' });
|
|
164
168
|
expect(node_fs_1.default.existsSync(node_path_1.default.join(instanceDir, 'node_modules/@siduri-x/memory'))).toBe(false);
|
|
165
|
-
const startOutput = (0, node_child_process_1.execSync)('node src/index.js', {
|
|
169
|
+
const startOutput = (0, node_child_process_1.execSync)('node src/index.js', {
|
|
170
|
+
cwd: instanceDir,
|
|
171
|
+
env: { ...process.env, PORT: '0' },
|
|
172
|
+
encoding: 'utf8',
|
|
173
|
+
});
|
|
166
174
|
expect(startOutput).toContain('✓ Siduri [CleanBrainHands] initialized with [Brain, Hands].');
|
|
167
175
|
const doctorOutput = (0, node_child_process_1.execSync)(`node ${node_path_1.default.resolve(repoRoot, 'cli/dist/index.js')} doctor`, {
|
|
168
176
|
cwd: instanceDir,
|
|
@@ -21,23 +21,39 @@ async function configureBody(_context) {
|
|
|
21
21
|
summary: { Provider: 'None (Headless)' },
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
const companionSlug = _context.companionName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
25
|
+
const { modelSource, initialExpression } = await inquirer_1.default.prompt([
|
|
26
|
+
{
|
|
27
|
+
type: 'input',
|
|
28
|
+
name: 'modelSource',
|
|
29
|
+
message: 'Live2D Model path / URL (.model3.json):',
|
|
30
|
+
default: `./assets/body/model/${companionSlug}/model.model3.json`,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'list',
|
|
34
|
+
name: 'initialExpression',
|
|
35
|
+
message: 'Initial avatar expression:',
|
|
36
|
+
choices: [
|
|
37
|
+
{ name: 'Neutral', value: 'neutral' },
|
|
38
|
+
{ name: 'Happy / Cheerful', value: 'happy' },
|
|
39
|
+
{ name: 'Calm', value: 'calm' },
|
|
40
|
+
],
|
|
41
|
+
default: 'neutral',
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
const modelPath = modelSource.trim() || `./assets/body/model/${companionSlug}/model.model3.json`;
|
|
45
|
+
const isHttpOrAbsolute = modelPath.startsWith('http://') || modelPath.startsWith('https://') || modelPath.startsWith('/');
|
|
46
|
+
const webModelUrl = isHttpOrAbsolute ? modelPath : `/live2d/${companionSlug}/model.model3.json`;
|
|
34
47
|
return {
|
|
35
48
|
config: {
|
|
36
49
|
provider: 'live2d',
|
|
50
|
+
modelPath,
|
|
51
|
+
modelUrl: webModelUrl,
|
|
37
52
|
initialExpression,
|
|
38
53
|
},
|
|
39
54
|
summary: {
|
|
40
55
|
Provider: 'Live2D',
|
|
56
|
+
'Model Path': modelPath,
|
|
41
57
|
Expression: initialExpression,
|
|
42
58
|
},
|
|
43
59
|
};
|
|
@@ -6,13 +6,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.configureVoice = configureVoice;
|
|
7
7
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
8
|
async function configureVoice(_context) {
|
|
9
|
+
const companionSlug = _context.companionName.toLowerCase().replace(/[^a-z0-9_-]/g, '') || 'default';
|
|
9
10
|
const { provider } = await inquirer_1.default.prompt({
|
|
10
11
|
type: 'list',
|
|
11
12
|
name: 'provider',
|
|
12
13
|
message: 'Voice provider?',
|
|
13
14
|
choices: [
|
|
14
|
-
{
|
|
15
|
-
|
|
15
|
+
{
|
|
16
|
+
name: 'RVC (Custom user-owned voice model via .pth / .index weights)',
|
|
17
|
+
value: 'rvc',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'VOICEVOX (Standard VOICEVOX stock character voice banks)',
|
|
21
|
+
value: 'voicevox',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'None (Disable voice synthesis)',
|
|
25
|
+
value: 'none',
|
|
26
|
+
},
|
|
16
27
|
],
|
|
17
28
|
});
|
|
18
29
|
if (provider === 'none') {
|
|
@@ -21,53 +32,327 @@ async function configureVoice(_context) {
|
|
|
21
32
|
summary: { Provider: 'None (Voice disabled)' },
|
|
22
33
|
};
|
|
23
34
|
}
|
|
24
|
-
|
|
35
|
+
if (provider === 'rvc') {
|
|
36
|
+
const rvcAnswers = await inquirer_1.default.prompt([
|
|
37
|
+
{
|
|
38
|
+
type: 'input',
|
|
39
|
+
name: 'modelPath',
|
|
40
|
+
message: 'RVC Model Path (.pth weights):',
|
|
41
|
+
default: `./assets/voice/${companionSlug}/${companionSlug}.pth`,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: 'input',
|
|
45
|
+
name: 'indexPath',
|
|
46
|
+
message: 'RVC Feature Index Path (.index, optional):',
|
|
47
|
+
default: `./assets/voice/${companionSlug}/${companionSlug}.index`,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: 'input',
|
|
51
|
+
name: 'pitchShift',
|
|
52
|
+
message: 'Pitch Shift (semitones, e.g. 0 for neutral, 12 for male-to-female, -12 for female-to-male):',
|
|
53
|
+
default: '0',
|
|
54
|
+
validate: (v) => !isNaN(parseInt(v, 10)) || 'Pitch shift must be an integer.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'list',
|
|
58
|
+
name: 'f0Method',
|
|
59
|
+
message: 'Pitch Extraction Algorithm (F0 Method):',
|
|
60
|
+
choices: ['rmvpe', 'pm', 'harvest', 'crepe'],
|
|
61
|
+
default: 'rmvpe',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: 'input',
|
|
65
|
+
name: 'baseUrl',
|
|
66
|
+
message: 'Base TTS Synthesis Engine URL (VOICEVOX):',
|
|
67
|
+
default: 'http://localhost:50021',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
type: 'input',
|
|
71
|
+
name: 'serviceUrl',
|
|
72
|
+
message: 'RVC Headless Service URL:',
|
|
73
|
+
default: 'http://localhost:50055',
|
|
74
|
+
},
|
|
75
|
+
]);
|
|
76
|
+
const pitchShift = parseInt(rvcAnswers.pitchShift, 10) || 0;
|
|
77
|
+
const config = {
|
|
78
|
+
provider: 'voicevox',
|
|
79
|
+
baseUrl: rvcAnswers.baseUrl.trim(),
|
|
80
|
+
speakerId: 1,
|
|
81
|
+
maxQueueDepth: 50,
|
|
82
|
+
rvc: {
|
|
83
|
+
enabled: true,
|
|
84
|
+
serviceUrl: rvcAnswers.serviceUrl.trim(),
|
|
85
|
+
modelName: companionSlug,
|
|
86
|
+
modelPath: rvcAnswers.modelPath.trim(),
|
|
87
|
+
indexPath: rvcAnswers.indexPath.trim() || undefined,
|
|
88
|
+
pitchShift,
|
|
89
|
+
f0Method: rvcAnswers.f0Method,
|
|
90
|
+
indexRate: 0.75,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
const summary = {
|
|
94
|
+
Provider: 'RVC (Custom Voice Model)',
|
|
95
|
+
'Model Path': rvcAnswers.modelPath.trim(),
|
|
96
|
+
'Pitch Shift': pitchShift,
|
|
97
|
+
'F0 Method': rvcAnswers.f0Method,
|
|
98
|
+
'RVC Service': rvcAnswers.serviceUrl.trim(),
|
|
99
|
+
'Base TTS': rvcAnswers.baseUrl.trim(),
|
|
100
|
+
};
|
|
101
|
+
return {
|
|
102
|
+
config,
|
|
103
|
+
summary,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const DEFAULT_VOICEVOX_SPEAKERS = [
|
|
107
|
+
{
|
|
108
|
+
name: '四国めたん (Shikoku Metan)',
|
|
109
|
+
speaker_uuid: '7ffcb7ce-00ec-4bdc-82cd-45a8889e43ff',
|
|
110
|
+
styles: [
|
|
111
|
+
{ id: 2, name: 'ノーマル (Normal)' },
|
|
112
|
+
{ id: 0, name: 'あまあま (Sweet)' },
|
|
113
|
+
{ id: 4, name: 'ツンツン (Tsundere)' },
|
|
114
|
+
{ id: 6, name: 'セクシー (Sexy)' },
|
|
115
|
+
{ id: 36, name: 'ささやき (Whisper)' },
|
|
116
|
+
{ id: 37, name: 'ヒソヒソ (Hisoniso)' },
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'ずんだもん (Zundamon)',
|
|
121
|
+
speaker_uuid: '388f24ea-105d-4354-b46e-22d7d7ff4479',
|
|
122
|
+
styles: [
|
|
123
|
+
{ id: 3, name: 'ノーマル (Normal)' },
|
|
124
|
+
{ id: 1, name: 'あまあま (Sweet)' },
|
|
125
|
+
{ id: 5, name: 'ツンツン (Tsundere)' },
|
|
126
|
+
{ id: 7, name: 'セクシー (Sexy)' },
|
|
127
|
+
{ id: 22, name: 'ささやき (Whisper)' },
|
|
128
|
+
{ id: 38, name: 'ヒソヒソ (Hisoniso)' },
|
|
129
|
+
{ id: 75, name: 'ヘロヘロ (Herohero)' },
|
|
130
|
+
{ id: 76, name: 'なみだめ (Namidame)' },
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: '春日部つむぎ (Kasukabe Tsumugi)',
|
|
135
|
+
speaker_uuid: '35b2c544-660e-401e-b033-0ab4756917cd',
|
|
136
|
+
styles: [{ id: 8, name: 'ノーマル (Normal)' }],
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: '雨晴はう (Rainy Hau)',
|
|
140
|
+
speaker_uuid: '3474ee95-c274-47f9-aa1a-8322163d77f1',
|
|
141
|
+
styles: [{ id: 10, name: 'ノーマル (Normal)' }],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: '波音リツ (Namine Ritsu)',
|
|
145
|
+
speaker_uuid: 'b1a81618-b27b-40d2-b0ea-27a9ad408c4b',
|
|
146
|
+
styles: [{ id: 9, name: 'ノーマル (Normal)' }],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: '玄野武宏 (Kurono Takehiro)',
|
|
150
|
+
speaker_uuid: 'c30dc15a-0992-4f8d-8bb8-ad3b76579016',
|
|
151
|
+
styles: [
|
|
152
|
+
{ id: 11, name: 'ノーマル (Normal)' },
|
|
153
|
+
{ id: 39, name: '喜び (Joy)' },
|
|
154
|
+
{ id: 40, name: 'ツンツン (Tsundere)' },
|
|
155
|
+
{ id: 41, name: '悲しみ (Sadness)' },
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: '白上虎太郎 (Shirakami Kotaro)',
|
|
160
|
+
speaker_uuid: 'e50289b4-43ff-49e6-9b58-d894c23fb4ac',
|
|
161
|
+
styles: [
|
|
162
|
+
{ id: 12, name: 'ふつう (Normal)' },
|
|
163
|
+
{ id: 32, name: 'わーい (Yay)' },
|
|
164
|
+
{ id: 33, name: 'びくびく (Timid)' },
|
|
165
|
+
{ id: 34, name: 'おこ (Angry)' },
|
|
166
|
+
{ id: 35, name: 'びえーん (Crying)' },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: '青山龍星 (Aoyama Ryusei)',
|
|
171
|
+
speaker_uuid: '4f51116a-d9ee-4516-925d-02f183e2af8d',
|
|
172
|
+
styles: [
|
|
173
|
+
{ id: 13, name: 'ノーマル (Normal)' },
|
|
174
|
+
{ id: 81, name: '熱血 (Passionate)' },
|
|
175
|
+
{ id: 82, name: '不気味 (Eerie)' },
|
|
176
|
+
{ id: 83, name: '囁き (Whisper)' },
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: '冥鳴ひまり (Meimei Himari)',
|
|
181
|
+
speaker_uuid: '8ea4fcd4-a013-4095-abb3-11b5bf837d37',
|
|
182
|
+
styles: [{ id: 14, name: 'ノーマル (Normal)' }],
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: '九州そら (Kyushu Sora)',
|
|
186
|
+
speaker_uuid: '481fb609-6446-4870-9f46-90c4dd623403',
|
|
187
|
+
styles: [
|
|
188
|
+
{ id: 16, name: 'ノーマル (Normal)' },
|
|
189
|
+
{ id: 15, name: 'あまあま (Sweet)' },
|
|
190
|
+
{ id: 17, name: 'ツンツン (Tsundere)' },
|
|
191
|
+
{ id: 18, name: 'セクシー (Sexy)' },
|
|
192
|
+
{ id: 19, name: 'ささやき (Whisper)' },
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'モチノ・キョウコ (Mochino Kyoko)',
|
|
197
|
+
speaker_uuid: 'a402a5d2-085e-4b44-a034-7164ff24a3cf',
|
|
198
|
+
styles: [
|
|
199
|
+
{ id: 20, name: 'ノーマル (Normal)' },
|
|
200
|
+
{ id: 60, name: 'セクシー/タレント (Sexy)' },
|
|
201
|
+
{ id: 61, name: '泣き (Crying)' },
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: '剣崎雌雄 (Kenzaki Mesuo)',
|
|
206
|
+
speaker_uuid: '1a1756a4-263d-42ea-86a2-96f107f474e9',
|
|
207
|
+
styles: [{ id: 21, name: 'ノーマル (Normal)' }],
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: '後鬼 (Goki)',
|
|
211
|
+
speaker_uuid: '80991a54-61c4-4b5f-8700-11234c062085',
|
|
212
|
+
styles: [
|
|
213
|
+
{ id: 27, name: '人間ver. (Human)' },
|
|
214
|
+
{ id: 28, name: '鬼ver. (Oni)' },
|
|
215
|
+
],
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'No.7 (Seven)',
|
|
219
|
+
speaker_uuid: 'c86c757c-cb24-4ea0-b6f7-33c872ff72e2',
|
|
220
|
+
styles: [
|
|
221
|
+
{ id: 29, name: 'ノーマル (Normal)' },
|
|
222
|
+
{ id: 30, name: 'アナウンス (Announce)' },
|
|
223
|
+
{ id: 31, name: '読み聞かせ (Storytelling)' },
|
|
224
|
+
],
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: 'ちび式じい (Chibishiki Jii)',
|
|
228
|
+
speaker_uuid: '1e19d52b-426b-4e12-b250-bfbe55c0c9cb',
|
|
229
|
+
styles: [{ id: 42, name: 'ノーマル (Normal)' }],
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: '櫻歌ミコ (Ouka Miko)',
|
|
233
|
+
speaker_uuid: '06155980-bfab-443b-a9b8-3e4b786c7ccb',
|
|
234
|
+
styles: [
|
|
235
|
+
{ id: 43, name: 'ノーマル (Normal)' },
|
|
236
|
+
{ id: 44, name: '第二形態 (2nd Form)' },
|
|
237
|
+
{ id: 45, name: 'ロリ (Loli)' },
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: '小夜/SAYO',
|
|
242
|
+
speaker_uuid: 'a8fb71e1-8738-4e16-b541-002f23ea3e45',
|
|
243
|
+
styles: [{ id: 46, name: 'ノーマル (Normal)' }],
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'ナースロボ_タイプT (Nurse Robot Type T)',
|
|
247
|
+
speaker_uuid: '882a636f-3bac-431a-966d-c5e6bba9f949',
|
|
248
|
+
styles: [
|
|
249
|
+
{ id: 47, name: 'ノーマル (Normal)' },
|
|
250
|
+
{ id: 48, name: '楽々 (Relaxed)' },
|
|
251
|
+
{ id: 49, name: '恐怖 (Fear)' },
|
|
252
|
+
{ id: 50, name: '内緒話 (Secret Talk)' },
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: '猫使アル (Nekotsuka Aru)',
|
|
257
|
+
speaker_uuid: '7253579b-240e-4328-b0a6-574ab57597ea',
|
|
258
|
+
styles: [
|
|
259
|
+
{ id: 55, name: 'ノーマル (Normal)' },
|
|
260
|
+
{ id: 56, name: 'おちつき (Calm)' },
|
|
261
|
+
{ id: 57, name: 'うきうき (Excited)' },
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: '猫使ビィ (Nekotsuka Bi)',
|
|
266
|
+
speaker_uuid: 'cf6204c3-6316-43b9-a095-2eb49e29a914',
|
|
267
|
+
styles: [
|
|
268
|
+
{ id: 58, name: 'ノーマル (Normal)' },
|
|
269
|
+
{ id: 59, name: 'おちつき (Calm)' },
|
|
270
|
+
{ id: 62, name: '人見知り (Shy)' },
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
];
|
|
274
|
+
async function getVoicevoxSpeakers(baseUrl) {
|
|
275
|
+
try {
|
|
276
|
+
const controller = new AbortController();
|
|
277
|
+
const timeout = setTimeout(() => controller.abort(), 2000);
|
|
278
|
+
const res = await fetch(new URL('/speakers', baseUrl).toString(), {
|
|
279
|
+
signal: controller.signal,
|
|
280
|
+
});
|
|
281
|
+
clearTimeout(timeout);
|
|
282
|
+
if (res.ok) {
|
|
283
|
+
const data = (await res.json());
|
|
284
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
285
|
+
return data;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch (_e) {
|
|
290
|
+
// If local instance is unreachable, fallback to the pre-populated list
|
|
291
|
+
}
|
|
292
|
+
return DEFAULT_VOICEVOX_SPEAKERS;
|
|
293
|
+
}
|
|
294
|
+
function buildSpeakerChoices(speakers) {
|
|
295
|
+
const choices = [];
|
|
296
|
+
for (const speaker of speakers) {
|
|
297
|
+
for (const style of speaker.styles) {
|
|
298
|
+
const label = `${speaker.name} - ${style.name} (ID: ${style.id})`;
|
|
299
|
+
choices.push({
|
|
300
|
+
name: label,
|
|
301
|
+
value: { id: style.id, label },
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return choices;
|
|
306
|
+
}
|
|
307
|
+
// provider === 'voicevox'
|
|
308
|
+
const urlAnswer = await inquirer_1.default.prompt([
|
|
25
309
|
{
|
|
26
310
|
type: 'input',
|
|
27
311
|
name: 'baseUrl',
|
|
28
312
|
message: 'VOICEVOX Engine Base URL:',
|
|
29
313
|
default: 'http://localhost:50021',
|
|
30
314
|
},
|
|
315
|
+
]);
|
|
316
|
+
const baseUrl = urlAnswer.baseUrl.trim() || 'http://localhost:50021';
|
|
317
|
+
const speakers = await getVoicevoxSpeakers(baseUrl);
|
|
318
|
+
const speakerChoices = buildSpeakerChoices(speakers);
|
|
319
|
+
const speakerAnswer = await inquirer_1.default.prompt([
|
|
31
320
|
{
|
|
32
|
-
type: '
|
|
33
|
-
name: '
|
|
34
|
-
message: '
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
type: 'confirm',
|
|
40
|
-
name: 'enableRvc',
|
|
41
|
-
message: 'Enable Headless RVC (Voice Conversion via ./assets/voice/[name])?',
|
|
42
|
-
default: false,
|
|
321
|
+
type: 'list',
|
|
322
|
+
name: 'speaker',
|
|
323
|
+
message: 'Select VOICEVOX Character Voice Bank & Style:',
|
|
324
|
+
choices: speakerChoices,
|
|
325
|
+
pageSize: 15,
|
|
43
326
|
},
|
|
44
327
|
]);
|
|
45
|
-
|
|
46
|
-
|
|
328
|
+
let speakerId = 1;
|
|
329
|
+
let speakerLabel = '四国めたん (Shikoku Metan) - ノーマル (Normal) (ID: 2)';
|
|
330
|
+
if (speakerAnswer && speakerAnswer.speaker) {
|
|
331
|
+
if (typeof speakerAnswer.speaker === 'object' && 'id' in speakerAnswer.speaker) {
|
|
332
|
+
speakerId = speakerAnswer.speaker.id;
|
|
333
|
+
speakerLabel = speakerAnswer.speaker.label;
|
|
334
|
+
}
|
|
335
|
+
else if (typeof speakerAnswer.speaker === 'number') {
|
|
336
|
+
speakerId = speakerAnswer.speaker;
|
|
337
|
+
speakerLabel = `Speaker ID: ${speakerId}`;
|
|
338
|
+
}
|
|
339
|
+
else if (typeof speakerAnswer.speaker === 'string') {
|
|
340
|
+
speakerId = parseInt(speakerAnswer.speaker, 10) || 1;
|
|
341
|
+
speakerLabel = `Speaker ID: ${speakerId}`;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
47
344
|
const config = {
|
|
48
345
|
provider: 'voicevox',
|
|
49
|
-
baseUrl
|
|
346
|
+
baseUrl,
|
|
50
347
|
speakerId,
|
|
51
348
|
maxQueueDepth: 50,
|
|
52
349
|
};
|
|
53
350
|
const summary = {
|
|
54
|
-
Provider: 'VOICEVOX',
|
|
351
|
+
Provider: 'VOICEVOX (Stock Voice Bank)',
|
|
352
|
+
'Voice Bank': speakerLabel,
|
|
55
353
|
'Speaker ID': speakerId,
|
|
56
|
-
'Base URL':
|
|
354
|
+
'Base URL': baseUrl,
|
|
57
355
|
};
|
|
58
|
-
if (answers.enableRvc) {
|
|
59
|
-
config.rvc = {
|
|
60
|
-
enabled: true,
|
|
61
|
-
serviceUrl: 'http://localhost:50055',
|
|
62
|
-
modelName: companionSlug,
|
|
63
|
-
modelPath: `./assets/voice/${companionSlug}/${companionSlug}.pth`,
|
|
64
|
-
indexPath: `./assets/voice/${companionSlug}/${companionSlug}.index`,
|
|
65
|
-
pitchShift: 0,
|
|
66
|
-
f0Method: 'rmvpe',
|
|
67
|
-
indexRate: 0.75,
|
|
68
|
-
};
|
|
69
|
-
summary['RVC Post-Processor'] = `Enabled (assets/voice/${companionSlug}/)`;
|
|
70
|
-
}
|
|
71
356
|
return {
|
|
72
357
|
config,
|
|
73
358
|
summary,
|
|
@@ -191,19 +191,26 @@ describe('Guided Manifest-Driven Configuration UX Specification Tests', () => {
|
|
|
191
191
|
test('Voice configurator configures VOICEVOX engine and speaker ID', async () => {
|
|
192
192
|
inquirer_1.default.prompt
|
|
193
193
|
.mockResolvedValueOnce({ provider: 'voicevox' })
|
|
194
|
-
.mockResolvedValueOnce({ baseUrl: 'http://localhost:50021'
|
|
194
|
+
.mockResolvedValueOnce({ baseUrl: 'http://localhost:50021' })
|
|
195
|
+
.mockResolvedValueOnce({ speaker: { id: 2, label: '四国めたん (Shikoku Metan) - ノーマル (Normal) (ID: 2)' } });
|
|
195
196
|
const result = await (0, voice_1.configureVoice)({ companionName: 'Sparkle', manifest: voiceManifest });
|
|
196
197
|
expect(result.config.provider).toBe('voicevox');
|
|
197
198
|
expect(result.config.speakerId).toBe(2);
|
|
198
199
|
expect(result.summary?.['Speaker ID']).toBe(2);
|
|
199
200
|
});
|
|
200
|
-
test('Body configurator configures Live2D and expression', async () => {
|
|
201
|
+
test('Body configurator configures Live2D, custom model path, and expression', async () => {
|
|
201
202
|
inquirer_1.default.prompt
|
|
202
203
|
.mockResolvedValueOnce({ provider: 'live2d' })
|
|
203
|
-
.mockResolvedValueOnce({
|
|
204
|
+
.mockResolvedValueOnce({
|
|
205
|
+
modelSource: './assets/body/model/sparkle/model.model3.json',
|
|
206
|
+
initialExpression: 'happy',
|
|
207
|
+
});
|
|
204
208
|
const result = await (0, body_1.configureBody)({ companionName: 'Sparkle', manifest: bodyManifest });
|
|
205
209
|
expect(result.config.provider).toBe('live2d');
|
|
210
|
+
expect(result.config.modelPath).toBe('./assets/body/model/sparkle/model.model3.json');
|
|
211
|
+
expect(result.config.modelUrl).toBe('/live2d/sparkle/model.model3.json');
|
|
206
212
|
expect(result.config.initialExpression).toBe('happy');
|
|
213
|
+
expect(result.summary?.['Model Path']).toBe('./assets/body/model/sparkle/model.model3.json');
|
|
207
214
|
});
|
|
208
215
|
test('Hands configurator configures MCP tool execution timeout', async () => {
|
|
209
216
|
inquirer_1.default.prompt.mockResolvedValueOnce({ timeoutSeconds: '15' });
|
package/dist/generator.js
CHANGED
|
@@ -46,6 +46,8 @@ function getDefaultConfigForManifest(manifest) {
|
|
|
46
46
|
else if (manifest.organType === 'body') {
|
|
47
47
|
config.provider = config.provider || 'live2d';
|
|
48
48
|
config.initialExpression = config.initialExpression || 'neutral';
|
|
49
|
+
config.modelPath = config.modelPath || './assets/body/model/default/model.model3.json';
|
|
50
|
+
config.modelUrl = config.modelUrl || '/live2d/default/model.model3.json';
|
|
49
51
|
}
|
|
50
52
|
else if (manifest.organType === 'hands') {
|
|
51
53
|
config.defaultTimeoutMs = config.defaultTimeoutMs || 10000;
|
|
@@ -406,6 +408,13 @@ function generateInstanceFiles(options) {
|
|
|
406
408
|
` return;`,
|
|
407
409
|
` }`,
|
|
408
410
|
'',
|
|
411
|
+
` // Live2D assets route mapping: /live2d/<modelName>/... -> ./assets/body/model/<modelName>/...`,
|
|
412
|
+
` if (pathname.startsWith('/live2d/')) {`,
|
|
413
|
+
` const relativeAssetPath = pathname.slice('/live2d/'.length);`,
|
|
414
|
+
` candidatePaths.unshift(path.join(rootDir, 'assets', 'body', 'model', relativeAssetPath));`,
|
|
415
|
+
` candidatePaths.unshift(path.join(rootDir, 'public', 'live2d', relativeAssetPath));`,
|
|
416
|
+
` }`,
|
|
417
|
+
'',
|
|
409
418
|
` // Static files & Next.js apps/web export routing`,
|
|
410
419
|
` const normalizedPath = pathname.replace(/^[/]+|[/]+$/g, '');`,
|
|
411
420
|
` const candidatePaths = [`,
|
package/dist/index.d.ts
CHANGED
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 = '0.1.
|
|
29
|
+
exports.CLI_VERSION = '0.1.2';
|
|
30
30
|
exports.colors = {
|
|
31
31
|
cyan: '\u001b[36m',
|
|
32
32
|
dim: '\u001b[2m',
|
package/dist/release-check.js
CHANGED
|
@@ -25,10 +25,10 @@ function runReleaseCheck(repoRoot = node_path_1.default.resolve(__dirname, '../.
|
|
|
25
25
|
{ name: '@siduri-x/ear', dir: 'packages/organs/ear', isOrgan: true, tarName: 'siduri-x-ear-1.0.1.tgz' },
|
|
26
26
|
{ name: '@siduri-x/vision', dir: 'packages/organs/vision', isOrgan: true, tarName: 'siduri-x-vision-1.0.1.tgz' },
|
|
27
27
|
{ name: '@siduri-x/hands', dir: 'packages/organs/hands', isOrgan: true, tarName: 'siduri-x-hands-1.0.1.tgz' },
|
|
28
|
-
{ name: '@siduri-x/body', dir: 'packages/organs/body', isOrgan: true, tarName: 'siduri-x-body-1.0.
|
|
28
|
+
{ name: '@siduri-x/body', dir: 'packages/organs/body', isOrgan: true, tarName: 'siduri-x-body-1.0.2.tgz' },
|
|
29
29
|
{ name: '@siduri-x/voice', dir: 'packages/organs/voice', isOrgan: true, tarName: 'siduri-x-voice-1.0.2.tgz' },
|
|
30
30
|
{ name: '@siduri-x/observation', dir: 'packages/organs/observation', isOrgan: true, tarName: 'siduri-x-observation-1.0.1.tgz' },
|
|
31
|
-
{ name: '@vxnus/siduri', dir: 'cli', isOrgan: false, tarName: 'vxnus-siduri-0.1.
|
|
31
|
+
{ name: '@vxnus/siduri', dir: 'cli', isOrgan: false, tarName: 'vxnus-siduri-0.1.3.tgz' },
|
|
32
32
|
];
|
|
33
33
|
let packagesChecked = 0;
|
|
34
34
|
let tarballsInspected = 0;
|
|
@@ -1 +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/2bu5_paf4sm3x.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.2vob68tjqpejf.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/favicon.ico"/><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/2bu5_paf4sm3x.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/2bu5_paf4sm3x.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/2bu5_paf4sm3x.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"
|
|
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/2bu5_paf4sm3x.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.2vob68tjqpejf.ico" sizes="256x256" type="image/x-icon"/><link rel="icon" href="/favicon.ico"/><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/2bu5_paf4sm3x.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/2bu5_paf4sm3x.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/2bu5_paf4sm3x.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]]],\"S\":true,\"h\":null,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"jA7i3F3whceXTT5sOtVhE\"}\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.2vob68tjqpejf.ico\",\"sizes\":\"256x256\",\"type\":\"image/x-icon\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\"}],[\"$\",\"$Ld\",\"4\",{}]]\n"])</script></body></html>
|