Step 5 of system-namespace cutover: complete the env-var removal that
step 4 set up. All consumers now import SERVICE_NAME from
src/platform-identity.ts directly; the deprecated PLATFORM_*
re-exports in src/config.ts are gone.
src/config.ts:
- PLATFORM_ID, PLATFORM_SERVICE_NAME, PLATFORM_RUNTIME_USER exports
removed.
- PLATFORM_RUNTIME_HOME stays (derived from SERVICE_NAME, used by
~10 consumers for path construction).
- Env-var allowlist drops PLATFORM_ID / PLATFORM_SERVICE_NAME /
PLATFORM_RUNTIME_USER / PLATFORM_RUNTIME_HOME entries.
- CONTROLPLANE_AIDER_TMUX_SESSION uses SERVICE_NAME directly.
setup/onboarding.ts:
- writeIdentity() simplified to write only ASSISTANT_NAME (display).
PLATFORM_ID / PLATFORM_SERVICE_NAME / PLATFORM_RUNTIME_USER are no
longer written to .env. Fresh installs have no PLATFORM_* keys.
- Status emission switched from PLATFORM_ID to SERVICE_NAME.
setup/env-audit.ts:
- Audit lists SERVICE_NAME instead of PLATFORM_ID; the env-file
PLATFORM_ID read is gone.
24 source files (src/*.ts, setup/*.ts, scripts/dashboard.ts):
- Bare PLATFORM_ID / PLATFORM_SERVICE_NAME / PLATFORM_RUNTIME_USER
references replaced with SERVICE_NAME.
- Imports rewired: SERVICE_NAME comes from
../{src/}platform-identity.js, not from config.js.
- Imports deduped where the sed sweep produced collisions.
Shell scripts (scripts/bhyve-evidence.sh, glass.sh, inspect-system.sh):
- Hardcoded SERVICE_NAME='clawdie' and SERVICE_USER='clawdie'.
No more grep-the-.env fallbacks; the constants are the source.
Tests (middle path):
- Mechanical fixes (import path, renamed assertion text):
src/hostd/privileged-commands.test.ts, src/startup-report.test.ts,
setup/env-audit.test.ts, setup/install-mode.test.ts.
- Skipped with `// system-namespace:` markers (pinned removed
env-driven override behavior; Codex rewrites once the bootstrap-
config service-user override path lands):
setup/verify.test.ts > 'uses the platform service name for PID candidates'
setup/service.test.ts > 'resolves a platform runtime separately from the tenant'
Test files still containing PLATFORM_* strings in vi.mock contents,
ENV_KEYS arrays, or comments are left untouched — they are test
artifacts that don't affect runtime; mock contents resolve to
'clawdie' which still equals SERVICE_NAME.
tsc clean. 2095 tests pass, 4 skipped, 0 fail.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---
Build: pass | Tests: pass — Tests 2095 passed | 4 skipped (2099)
71 lines
2.1 KiB
TypeScript
71 lines
2.1 KiB
TypeScript
/**
|
|
* Step: skills-init — initialize the .nanoclaw/ skills-engine directory.
|
|
*
|
|
* Creates the base snapshot from current source so the skills-engine can
|
|
* track applied skills, detect drift, and support three-way merges.
|
|
*
|
|
* This must run after the tarball is extracted and npm dependencies are
|
|
* installed, but before any skills are applied.
|
|
*/
|
|
import { spawnSync } from 'child_process';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
import { SERVICE_NAME } from '../src/platform-identity.js';
|
|
import { initNanoclawDir } from '../skills-engine/init.js';
|
|
import { readState } from '../skills-engine/state.js';
|
|
import { NANOCLAW_DIR } from '../skills-engine/constants.js';
|
|
import { emitStatus } from './status.js';
|
|
|
|
export async function run(args: string[]): Promise<void> {
|
|
const projectRoot = process.cwd();
|
|
const nanoclawPath = path.join(projectRoot, NANOCLAW_DIR);
|
|
|
|
const force = args.includes('--force');
|
|
|
|
if (fs.existsSync(nanoclawPath) && !force) {
|
|
// Already initialized — report state and exit
|
|
try {
|
|
const state = readState();
|
|
emitStatus('SKILLS_INIT', {
|
|
STATUS: 'already_initialized',
|
|
CORE_VERSION: state.core_version,
|
|
APPLIED_SKILLS: state.applied_skills.length,
|
|
SYSTEM_VERSION: state.skills_system_version,
|
|
});
|
|
} catch {
|
|
// State file exists but is corrupt — reinitialize
|
|
initNanoclawDir();
|
|
emitStatus('SKILLS_INIT', {
|
|
STATUS: 'reinitialized',
|
|
REASON: 'corrupt_state',
|
|
});
|
|
}
|
|
ensureNanoclawOwnership(nanoclawPath);
|
|
return;
|
|
}
|
|
|
|
initNanoclawDir();
|
|
ensureNanoclawOwnership(nanoclawPath);
|
|
|
|
const state = readState();
|
|
emitStatus('SKILLS_INIT', {
|
|
STATUS: 'initialized',
|
|
CORE_VERSION: state.core_version,
|
|
APPLIED_SKILLS: 0,
|
|
SYSTEM_VERSION: state.skills_system_version,
|
|
});
|
|
}
|
|
|
|
function ensureNanoclawOwnership(nanoclawPath: string): void {
|
|
if (typeof process.getuid !== 'function' || process.getuid() !== 0) {
|
|
return;
|
|
}
|
|
spawnSync(
|
|
'chown',
|
|
['-R', `${SERVICE_NAME}:${SERVICE_NAME}`, nanoclawPath],
|
|
{
|
|
stdio: 'ignore',
|
|
},
|
|
);
|
|
}
|