knight-os 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/setup.js +54 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knight-os",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "AI companion OS for OpenClaw — memory, reflection, and identity framework",
5
5
  "main": "bin/knight.js",
6
6
  "bin": {
package/src/setup.js CHANGED
@@ -214,14 +214,42 @@ async function setup() {
214
214
  const workspaceExists = fs.existsSync(workspace);
215
215
  const hasCoreFiles = workspaceExists && fs.existsSync(path.join(workspace, 'AGENTS.md'));
216
216
 
217
- let overwrite = true;
217
+ // Files that contain user's personal memory/identity — never overwrite by default
218
+ const PROTECTED_FILES = ['SOUL.md', 'MEMORY.md', 'USER.md', 'REDLINES.md'];
219
+ const hasPersonalMemory = hasCoreFiles && PROTECTED_FILES.some(
220
+ f => fs.existsSync(path.join(workspace, f))
221
+ );
222
+
223
+ let overwrite = false;
224
+ let overwriteProtected = false;
225
+
218
226
  if (hasCoreFiles) {
219
- console.log(`\n⚠️ Workspace already exists at: ${workspace}`);
220
- const answer = await ask(rl, 'Overwrite existing files? (y/N)', 'N');
221
- overwrite = answer.toLowerCase().startsWith('y');
222
- if (!overwrite) {
223
- console.log('\nSkipping template write. Continuing with other setup steps...');
227
+ if (hasPersonalMemory) {
228
+ console.log(`\n⚠️ Existing OpenClaw workspace detected at: ${workspace}`);
229
+ console.log(' Protected files found: SOUL.md, MEMORY.md, USER.md, REDLINES.md');
230
+ console.log(' These contain your personal memory and identity.\n');
231
+ console.log(' Knight OS will add missing files and update scripts/templates.');
232
+ console.log(' Your existing memory files will NOT be touched.\n');
233
+ const answer = await ask(rl, 'Also overwrite protected files? (y/N)', 'N');
234
+ overwriteProtected = answer.toLowerCase().startsWith('y');
235
+ if (overwriteProtected) {
236
+ console.log('\n ⚠️ Protected files WILL be overwritten. Existing content will be lost.');
237
+ } else {
238
+ console.log('\n ✅ Protected files preserved. Only missing/new files will be added.');
239
+ }
240
+ overwrite = true; // always write non-protected files (scripts, AGENTS.md, HEARTBEAT.md, PROJECTS.md)
241
+ } else {
242
+ console.log(`\n⚠️ Workspace already exists at: ${workspace}`);
243
+ const answer = await ask(rl, 'Overwrite existing files? (y/N)', 'N');
244
+ overwrite = answer.toLowerCase().startsWith('y');
245
+ overwriteProtected = overwrite;
246
+ if (!overwrite) {
247
+ console.log('\nSkipping template write. Continuing with other setup steps...');
248
+ }
224
249
  }
250
+ } else {
251
+ overwrite = true;
252
+ overwriteProtected = true;
225
253
  }
226
254
 
227
255
  // Create required dirs
@@ -297,15 +325,32 @@ async function setup() {
297
325
  .replace(/\{\{CHANNEL\}\}/g, 'direct');
298
326
  }
299
327
 
300
- function copyTemplates(srcDir, destDir) {
328
+ function copyTemplates(srcDir, destDir, isRoot) {
301
329
  const entries = fs.readdirSync(srcDir, { withFileTypes: true });
302
330
  for (const entry of entries) {
303
331
  const src = path.join(srcDir, entry.name);
304
332
  const dest = path.join(destDir, entry.name);
305
333
  if (entry.isDirectory()) {
306
334
  fs.mkdirSync(dest, { recursive: true });
307
- copyTemplates(src, dest);
335
+ copyTemplates(src, dest, false);
308
336
  } else {
337
+ // Check if this is a protected file (root level only)
338
+ const isProtected = isRoot && PROTECTED_FILES.includes(entry.name);
339
+ if (isProtected && !overwriteProtected) {
340
+ if (!fs.existsSync(dest)) {
341
+ // File doesn't exist yet — safe to create
342
+ try {
343
+ const content = fs.readFileSync(src, 'utf-8');
344
+ fs.writeFileSync(dest, fillTemplate(content, vars), 'utf-8');
345
+ console.log(` ✅ ${path.relative(workspace, dest)}`);
346
+ } catch (e) {
347
+ console.log(` ⚠️ ${path.relative(workspace, dest)}: ${e.message}`);
348
+ }
349
+ } else {
350
+ console.log(` 🔒 ${path.relative(workspace, dest)} (protected, skipped)`);
351
+ }
352
+ continue;
353
+ }
309
354
  try {
310
355
  const content = fs.readFileSync(src, 'utf-8');
311
356
  fs.writeFileSync(dest, fillTemplate(content, vars), 'utf-8');
@@ -317,7 +362,7 @@ async function setup() {
317
362
  }
318
363
  }
319
364
 
320
- copyTemplates(TEMPLATES_DIR, workspace);
365
+ copyTemplates(TEMPLATES_DIR, workspace, true);
321
366
  } else {
322
367
  console.log(' ⏭️ Templates skipped (existing files preserved)');
323
368
  }