oh-my-codex 0.21.30 → 0.21.31

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/Cargo.lock CHANGED
@@ -32,7 +32,7 @@ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
32
32
 
33
33
  [[package]]
34
34
  name = "omx-api"
35
- version = "0.21.30"
35
+ version = "0.21.31"
36
36
  dependencies = [
37
37
  "serde",
38
38
  "serde_json",
@@ -40,14 +40,14 @@ dependencies = [
40
40
 
41
41
  [[package]]
42
42
  name = "omx-explore-harness"
43
- version = "0.21.30"
43
+ version = "0.21.31"
44
44
  dependencies = [
45
45
  "libc",
46
46
  ]
47
47
 
48
48
  [[package]]
49
49
  name = "omx-mux"
50
- version = "0.21.30"
50
+ version = "0.21.31"
51
51
  dependencies = [
52
52
  "serde",
53
53
  "serde_json",
@@ -55,7 +55,7 @@ dependencies = [
55
55
 
56
56
  [[package]]
57
57
  name = "omx-runtime"
58
- version = "0.21.30"
58
+ version = "0.21.31"
59
59
  dependencies = [
60
60
  "fs2",
61
61
  "libc",
@@ -67,7 +67,7 @@ dependencies = [
67
67
 
68
68
  [[package]]
69
69
  name = "omx-runtime-core"
70
- version = "0.21.30"
70
+ version = "0.21.31"
71
71
  dependencies = [
72
72
  "fs2",
73
73
  "serde",
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "omx-sparkshell"
79
- version = "0.21.30"
79
+ version = "0.21.31"
80
80
  dependencies = [
81
81
  "omx-mux",
82
82
  ]
package/Cargo.toml CHANGED
@@ -11,7 +11,7 @@ resolver = "2"
11
11
 
12
12
  [workspace.package]
13
13
 
14
- version = "0.21.30"
14
+ version = "0.21.31"
15
15
 
16
16
  edition = "2021"
17
17
  rust-version = "1.73"
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=setup-symlink-destinations.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-symlink-destinations.test.d.ts","sourceRoot":"","sources":["../../../src/cli/__tests__/setup-symlink-destinations.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,180 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtemp, mkdir, readFile, rm, symlink, writeFile } from 'node:fs/promises';
4
+ import { existsSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { tmpdir } from 'node:os';
7
+ import { setup } from '../setup.js';
8
+ function setMockHome(home) {
9
+ const previousHome = process.env.HOME;
10
+ const previousCodexHome = process.env.CODEX_HOME;
11
+ process.env.HOME = home;
12
+ process.env.CODEX_HOME = join(home, '.codex');
13
+ return () => {
14
+ if (typeof previousHome === 'string')
15
+ process.env.HOME = previousHome;
16
+ else
17
+ delete process.env.HOME;
18
+ if (typeof previousCodexHome === 'string')
19
+ process.env.CODEX_HOME = previousCodexHome;
20
+ else
21
+ delete process.env.CODEX_HOME;
22
+ };
23
+ }
24
+ async function withRepo(run) {
25
+ const parent = await mkdtemp(join(tmpdir(), 'omx-setup-symlink-'));
26
+ const repo = join(parent, 'repo');
27
+ await mkdir(repo);
28
+ const restoreHome = setMockHome(join(parent, 'home'));
29
+ const previousCwd = process.cwd();
30
+ try {
31
+ process.chdir(repo);
32
+ await run(repo, parent);
33
+ }
34
+ finally {
35
+ process.chdir(previousCwd);
36
+ restoreHome();
37
+ await rm(parent, { recursive: true, force: true });
38
+ }
39
+ }
40
+ describe('omx setup symlink destinations', () => {
41
+ it('refuses a symlinked project .gitignore and leaves the target untouched', async () => {
42
+ await withRepo(async (repo, parent) => {
43
+ const victim = join(parent, 'victim.txt');
44
+ await writeFile(victim, 'ORIGINAL-SECRET-CONTENT\n');
45
+ await symlink('../victim.txt', join(repo, '.gitignore'));
46
+ const gitignorePath = join(repo, '.gitignore');
47
+ await assert.rejects(setup({ scope: 'project' }), (err) => {
48
+ const msg = err?.message || '';
49
+ return (msg.includes('Refusing to install through symlink') &&
50
+ msg.includes(gitignorePath) &&
51
+ msg.includes('Either remove the symlink'));
52
+ });
53
+ assert.equal(await readFile(victim, 'utf8'), 'ORIGINAL-SECRET-CONTENT\n');
54
+ });
55
+ });
56
+ it('refuses a symlinked prompt destination and leaves the target untouched', async () => {
57
+ await withRepo(async (repo, parent) => {
58
+ await mkdir(join(repo, '.codex', 'prompts'), { recursive: true });
59
+ const victim = join(parent, 'victim-prompt.txt');
60
+ await writeFile(victim, 'ORIGINAL-PROMPT-CONTENT\n');
61
+ const analystPath = join(repo, '.codex', 'prompts', 'analyst.md');
62
+ await symlink('../../../victim-prompt.txt', analystPath);
63
+ await assert.rejects(setup({ scope: 'project' }), (err) => {
64
+ const msg = err?.message || '';
65
+ return (msg.includes('Refusing to install through symlink') &&
66
+ msg.includes(analystPath) &&
67
+ msg.includes('Either remove the symlink'));
68
+ });
69
+ assert.equal(await readFile(victim, 'utf8'), 'ORIGINAL-PROMPT-CONTENT\n');
70
+ });
71
+ });
72
+ it('rejects a symlinked ancestor directory (.codex)', async () => {
73
+ await withRepo(async (repo, parent) => {
74
+ const targetDir = join(parent, 'external-codex');
75
+ await mkdir(targetDir);
76
+ const victim = join(targetDir, 'secret.txt');
77
+ await writeFile(victim, 'EXTERNAL-SECRET\n');
78
+ // Create .codex as a symlink to external directory
79
+ await symlink(targetDir, join(repo, '.codex'));
80
+ await assert.rejects(setup({ scope: 'project' }), (err) => {
81
+ const msg = err?.message || '';
82
+ return ((msg.includes('Refusing to install through symlink') || msg.includes('Refusing native hook transaction')) &&
83
+ msg.includes('symlink') &&
84
+ (msg.includes('Either remove the symlink') || msg.includes('is a symbolic link')));
85
+ });
86
+ assert.equal(await readFile(victim, 'utf8'), 'EXTERNAL-SECRET\n');
87
+ });
88
+ });
89
+ it('rejects a symlinked auth directory', async () => {
90
+ await withRepo(async (repo, parent) => {
91
+ const targetDir = join(parent, 'external-auth');
92
+ await mkdir(targetDir);
93
+ const victim = join(targetDir, 'token.txt');
94
+ await writeFile(victim, 'SECRET-TOKEN\n');
95
+ // Create .omx as a symlink to external directory
96
+ await symlink(targetDir, join(repo, '.omx'));
97
+ await assert.rejects(setup({ scope: 'project' }), (err) => {
98
+ const msg = err?.message || '';
99
+ return (msg.includes('Refusing to install through symlink') &&
100
+ msg.includes('.omx') &&
101
+ msg.includes('Either remove the symlink'));
102
+ });
103
+ assert.equal(await readFile(victim, 'utf8'), 'SECRET-TOKEN\n');
104
+ });
105
+ });
106
+ it('rejects a symlinked state directory that setup manages', async () => {
107
+ await withRepo(async (repo, parent) => {
108
+ const targetDir = join(parent, 'external-state');
109
+ await mkdir(targetDir);
110
+ const victim = join(targetDir, 'installed-skills.json');
111
+ await writeFile(victim, '{"version": 1}\n');
112
+ // Create .omx/state as a symlink to external directory, which setup writes to for installed-skills.json
113
+ await mkdir(join(repo, '.omx'), { recursive: true });
114
+ await symlink(targetDir, join(repo, '.omx', 'state'));
115
+ await assert.rejects(setup({ scope: 'project' }), (err) => {
116
+ const msg = err?.message || '';
117
+ return (msg.includes('Refusing to install through symlink') &&
118
+ msg.includes('.omx') &&
119
+ msg.includes('Either remove the symlink'));
120
+ });
121
+ assert.equal(await readFile(victim, 'utf8'), '{"version": 1}\n');
122
+ });
123
+ });
124
+ it('rejects a symlinked .omx directory even when hud-config.json would already exist', async () => {
125
+ await withRepo(async (repo, parent) => {
126
+ const targetDir = join(parent, 'external-omx');
127
+ await mkdir(targetDir);
128
+ // Create hud-config.json in the target so that the old code would skip validation
129
+ await mkdir(join(targetDir), { recursive: true });
130
+ await writeFile(join(targetDir, 'hud-config.json'), '{"preset": "focused"}\n');
131
+ // Create .omx as a symlink to external directory
132
+ await symlink(targetDir, join(repo, '.omx'));
133
+ await assert.rejects(setup({ scope: 'project' }), (err) => {
134
+ const msg = err?.message || '';
135
+ return (msg.includes('Refusing to install through symlink') &&
136
+ msg.includes('.omx') &&
137
+ msg.includes('Either remove the symlink'));
138
+ });
139
+ });
140
+ });
141
+ it('rejects a symlinked .omx/backups when backing up a managed file', async () => {
142
+ await withRepo(async (repo, parent) => {
143
+ const targetDir = join(parent, 'external-backups');
144
+ await mkdir(targetDir);
145
+ const victim = join(targetDir, 'secret-backup.txt');
146
+ // Create .omx/backups as a symlink to external directory
147
+ await mkdir(join(repo, '.omx'), { recursive: true });
148
+ await symlink(targetDir, join(repo, '.omx', 'backups'));
149
+ // Create an existing .gitignore to trigger the backup code path
150
+ await writeFile(join(repo, '.gitignore'), 'original-gitignore\n');
151
+ await assert.rejects(setup({ scope: 'project' }), (err) => {
152
+ const msg = err?.message || '';
153
+ return (msg.includes('Refusing to install through symlink') &&
154
+ msg.includes('backups') &&
155
+ msg.includes('Either remove the symlink'));
156
+ });
157
+ // Verify nothing was written to the victim directory
158
+ assert.equal(existsSync(victim), false, 'Backup should not be written outside the scope');
159
+ });
160
+ });
161
+ it('succeeds when scope root is under a symlinked parent (like /tmp on macOS) while still rejecting symlinks inside the managed tree', async () => {
162
+ // Regression test for issue #3887: On macOS, /tmp is a symlink to /private/tmp,
163
+ // so the setup should not reject paths just because they're under /tmp,
164
+ // but should still reject symlinks inside the managed scope (.codex, .omx, etc).
165
+ await withRepo(async (repo, parent) => {
166
+ // The repo is already under /tmp (symlinked parent), so this tests that
167
+ // OS-level symlinks are not rejected.
168
+ // Create a file to install
169
+ const skillDir = join(repo, '.codex', 'skills', 'test-skill');
170
+ await mkdir(skillDir, { recursive: true });
171
+ await writeFile(join(skillDir, 'SKILL.md'), '# Test Skill\n\nA test skill');
172
+ // Setup should succeed even though the scope root is under the /tmp symlink
173
+ await assert.doesNotReject(setup({ scope: 'project' }), 'Setup should succeed when scope root is under /tmp (symlinked OS directory)');
174
+ // Verify the setup actually completed
175
+ assert(existsSync(join(repo, '.gitignore')), '.gitignore should be created');
176
+ assert(existsSync(join(repo, '.codex', 'config.toml')), 'config.toml should be created');
177
+ });
178
+ });
179
+ });
180
+ //# sourceMappingURL=setup-symlink-destinations.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-symlink-destinations.test.js","sourceRoot":"","sources":["../../../src/cli/__tests__/setup-symlink-destinations.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"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"}
package/dist/cli/setup.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * omx setup - Automated installation of oh-my-codex
3
3
  * Installs skills, prompts, MCP servers config, and AGENTS.md
4
4
  */
5
- import { mkdir, cp, copyFile, readdir, readFile, rename, writeFile, stat, lstat, rm, open, chmod, } from "fs/promises";
5
+ import { mkdir, cp, copyFile, readdir, readFile, rename, writeFile, stat, lstat, realpath, rm, open, chmod, } from "fs/promises";
6
6
  import { join, dirname, relative, basename, isAbsolute, sep, win32 } from "path";
7
7
  import { constants, existsSync } from "fs";
8
8
  import { spawnSync } from "child_process";
@@ -1241,7 +1241,88 @@ async function commitNativeHookTransaction(artifacts, preconditions, ancestorPre
1241
1241
  throw new Error(`Native hook transaction failed and was rolled back: ${message}`);
1242
1242
  }
1243
1243
  }
1244
+ /**
1245
+ * Validates that a destination path is safe for managed setup operations (install, read, compare).
1246
+ * Refuses if the destination is a symlink or lies outside the specified scope root,
1247
+ * or if any ancestor component within the scope is a symlink.
1248
+ *
1249
+ * This guard prevents symlink attacks that would redirect reads, backups, and writes outside
1250
+ * the managed tree. It validates every path component without following symlinks, but only
1251
+ * checks ancestors within the scope root—never rejects OS-level symlinks above the managed
1252
+ * scope (e.g., /var, /tmp on macOS which may be systemwide symlinks).
1253
+ *
1254
+ * MUST be called BEFORE reading/comparing contents and BEFORE mkdir of any intermediate dir.
1255
+ * It is the single authoritative source of symlink validation for all managed scope writes.
1256
+ *
1257
+ * Addresses Codex findings:
1258
+ * - 4351464979: validate before compare (filesDiffer) ✓
1259
+ * - 4351464989: validate before compare (readFile) ✓
1260
+ * - 4351560195: respects CODEX_HOME via codexHome() ✓
1261
+ * - 4351560207: validate before compare ✓
1262
+ * - 4351560219: validate before mkdir ✓
1263
+ */
1264
+ async function assertManagedDestination(destinationPath, scopeRoot) {
1265
+ // Resolve paths to absolute forms
1266
+ const absolutePath = isAbsolute(destinationPath) ? destinationPath : join(process.cwd(), destinationPath);
1267
+ const absoluteScopeRoot = isAbsolute(scopeRoot) ? scopeRoot : join(process.cwd(), scopeRoot);
1268
+ // Resolve scope root to its real path (following all symlinks) to properly handle
1269
+ // OS-level symlinks like /tmp -> /private/tmp on macOS. This allows us to detect when
1270
+ // a destination lies outside the real managed scope.
1271
+ let realScopeRoot;
1272
+ try {
1273
+ realScopeRoot = await realpath(absoluteScopeRoot);
1274
+ }
1275
+ catch (error) {
1276
+ if (isMissingPathError(error)) {
1277
+ // Scope root doesn't exist yet; use absolute path
1278
+ realScopeRoot = absoluteScopeRoot;
1279
+ }
1280
+ else {
1281
+ throw error;
1282
+ }
1283
+ }
1284
+ // Verify destination is within the managed scope by checking relative path.
1285
+ // Using realScopeRoot ensures we detect when symlinks in ancestors would escape the scope.
1286
+ const relFromScope = relative(realScopeRoot, absolutePath);
1287
+ if (relFromScope === '..' || relFromScope.startsWith(`..${sep}`)) {
1288
+ throw new Error(`Destination ${absolutePath} is outside managed scope ${realScopeRoot}.`);
1289
+ }
1290
+ // Walk from destination up to and including the scope root, checking each component
1291
+ // for symlinks. We do NOT resolve symlinks while walking (to catch them).
1292
+ // Stop at the scope root (don't check parents of the scope root).
1293
+ let currentPath = absolutePath;
1294
+ const visited = new Set();
1295
+ while (currentPath && currentPath !== dirname(currentPath)) {
1296
+ if (visited.has(currentPath))
1297
+ break; // Avoid infinite loops
1298
+ visited.add(currentPath);
1299
+ // Stop before checking ancestors beyond the scope root
1300
+ if (currentPath === realScopeRoot)
1301
+ break;
1302
+ // Check if this path component is a symlink (using lstat, not stat)
1303
+ let stats;
1304
+ try {
1305
+ stats = await lstat(currentPath);
1306
+ }
1307
+ catch (error) {
1308
+ if (isMissingPathError(error)) {
1309
+ // Path doesn't exist yet, move to parent
1310
+ currentPath = dirname(currentPath);
1311
+ continue;
1312
+ }
1313
+ throw error;
1314
+ }
1315
+ if (stats.isSymbolicLink()) {
1316
+ const msg = `Refusing to install through symlink ${currentPath}. ` +
1317
+ `Either remove the symlink (rm ${currentPath}), ` +
1318
+ `or move the target to the expected location before running setup again.`;
1319
+ throw new Error(msg);
1320
+ }
1321
+ currentPath = dirname(currentPath);
1322
+ }
1323
+ }
1244
1324
  async function ensureBackup(destinationPath, contentChanged, backupContext, options) {
1325
+ await assertManagedDestination(destinationPath, backupContext.baseRoot);
1245
1326
  if (!contentChanged || !existsSync(destinationPath))
1246
1327
  return false;
1247
1328
  const relativePath = relative(backupContext.baseRoot, destinationPath);
@@ -1250,6 +1331,7 @@ async function ensureBackup(destinationPath, contentChanged, backupContext, opti
1250
1331
  : relativePath;
1251
1332
  const backupPath = join(backupContext.backupRoot, safeRelativePath);
1252
1333
  if (!options.dryRun) {
1334
+ await assertManagedDestination(backupPath, backupContext.baseRoot);
1253
1335
  await mkdir(dirname(backupPath), { recursive: true });
1254
1336
  await copyFile(destinationPath, backupPath);
1255
1337
  }
@@ -1435,7 +1517,7 @@ async function isUnmodifiedRecordedInstall(receiptPath, skillName, skillDir) {
1435
1517
  * The receipt therefore describes the installer's own output, and any extra entry present at
1436
1518
  * retirement time makes the comparison fail, which retains the directory.
1437
1519
  */
1438
- async function writeInstalledSkillReceipt(receiptPath, skillsDir, writtenFilesBySkill, options) {
1520
+ async function writeInstalledSkillReceipt(receiptPath, skillsDir, writtenFilesBySkill, options, scopeRoot) {
1439
1521
  if (options.dryRun)
1440
1522
  return;
1441
1523
  const receipt = await readInstalledSkillReceipt(receiptPath);
@@ -1458,11 +1540,16 @@ async function writeInstalledSkillReceipt(receiptPath, skillsDir, writtenFilesBy
1458
1540
  delete receipt.skills[name];
1459
1541
  }
1460
1542
  try {
1543
+ await assertManagedDestination(receiptPath, scopeRoot);
1461
1544
  await mkdir(dirname(receiptPath), { recursive: true });
1462
1545
  await writeFile(receiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
1463
1546
  }
1464
- catch {
1465
- // A receipt we cannot persist simply means the next refresh retains conservatively.
1547
+ catch (error) {
1548
+ // Symlink assertions must propagate to prevent writes through symlinks
1549
+ if (error instanceof Error && error.message.includes('Refusing to install through symlink')) {
1550
+ throw error;
1551
+ }
1552
+ // A receipt we cannot persist for other reasons simply means the next refresh retains conservatively.
1466
1553
  }
1467
1554
  }
1468
1555
  async function isOmxManagedInstalledSkillDir(skillDir) {
@@ -1945,6 +2032,7 @@ function stripLegacyGitignoreEntries(content, legacyEntries) {
1945
2032
  }
1946
2033
  async function ensureProjectGitignore(projectRoot, backupContext, options) {
1947
2034
  const gitignorePath = join(projectRoot, ".gitignore");
2035
+ await assertManagedDestination(gitignorePath, projectRoot);
1948
2036
  const destinationExists = existsSync(gitignorePath);
1949
2037
  const existing = destinationExists
1950
2038
  ? await readFile(gitignorePath, "utf-8")
@@ -2557,6 +2645,21 @@ export async function setup(options = {}) {
2557
2645
  const { disableHooks = false, force = false, repairPluginCache = false, dryRun = false, installMode: requestedInstallMode, mcpMode: requestedMcpMode, teamMode: requestedTeamMode, scope: requestedScope, verbose = false, skipNativeAgentRefresh: requestedSkipNativeAgentRefresh = false, setupScopePrompt, persistedSetupReviewPrompt, installModePrompt, modelUpgradePrompt, pluginAgentsMdPrompt, pluginDeveloperInstructionsPrompt, firstPartyMcpRemovalPrompt, } = options;
2558
2646
  const pkgRoot = getPackageRoot();
2559
2647
  const projectRoot = process.cwd();
2648
+ // Validate .omx is never a symlink before any operations touch it
2649
+ if (!dryRun) {
2650
+ const omxPath = join(projectRoot, ".omx");
2651
+ try {
2652
+ await assertManagedDestination(omxPath, projectRoot);
2653
+ }
2654
+ catch (error) {
2655
+ // Missing .omx is fine, but symlinks must be refused
2656
+ if (error instanceof Error && error.message.includes("Refusing to install through symlink")) {
2657
+ throw error;
2658
+ }
2659
+ // Any other error is unexpected
2660
+ throw error;
2661
+ }
2662
+ }
2560
2663
  const persistedPreferences = await readPersistedSetupPreferences(projectRoot, { warnOnLegacyScope: true });
2561
2664
  let persistedReviewDecision = "keep";
2562
2665
  const effectiveScopeForInstallMode = requestedScope ?? persistedPreferences?.scope ?? DEFAULT_SETUP_SCOPE;
@@ -2788,25 +2891,23 @@ export async function setup(options = {}) {
2788
2891
  }
2789
2892
  // Step 1: Ensure directories exist
2790
2893
  console.log("[1/8] Creating directories...");
2791
- const dirs = isPluginInstallMode
2792
- ? [
2793
- scopeDirs.codexHomeDir,
2794
- scopeDirs.nativeAgentsDir,
2795
- omxStateDir(projectRoot),
2796
- omxPlansDir(projectRoot),
2797
- omxLogsDir(projectRoot),
2798
- ]
2799
- : [
2800
- scopeDirs.codexHomeDir,
2801
- scopeDirs.promptsDir,
2802
- scopeDirs.skillsDir,
2803
- scopeDirs.nativeAgentsDir,
2804
- omxStateDir(projectRoot),
2805
- omxPlansDir(projectRoot),
2806
- omxLogsDir(projectRoot),
2807
- ];
2808
- for (const dir of dirs) {
2894
+ const userScopeDirs = isPluginInstallMode
2895
+ ? [scopeDirs.codexHomeDir, scopeDirs.nativeAgentsDir]
2896
+ : [scopeDirs.codexHomeDir, scopeDirs.promptsDir, scopeDirs.skillsDir, scopeDirs.nativeAgentsDir];
2897
+ const projectScopeDirs = [omxStateDir(projectRoot), omxPlansDir(projectRoot), omxLogsDir(projectRoot)];
2898
+ // Validate and create user-scope directories against user authority root
2899
+ for (const dir of userScopeDirs) {
2900
+ if (!dryRun) {
2901
+ await assertManagedDestination(dir, backupContext.baseRoot);
2902
+ await mkdir(dir, { recursive: true });
2903
+ }
2904
+ if (verbose)
2905
+ console.log(` mkdir ${dir}`);
2906
+ }
2907
+ // Validate and create project-scope directories against project authority root
2908
+ for (const dir of projectScopeDirs) {
2809
2909
  if (!dryRun) {
2910
+ await assertManagedDestination(dir, projectRoot);
2810
2911
  await mkdir(dir, { recursive: true });
2811
2912
  }
2812
2913
  if (verbose)
@@ -3305,6 +3406,10 @@ export async function setup(options = {}) {
3305
3406
  // Step 8: Configure HUD
3306
3407
  console.log("[8/8] Configuring HUD...");
3307
3408
  const hudConfigPath = join(projectRoot, ".omx", "hud-config.json");
3409
+ // Validate .omx even when hud-config.json already exists to catch symlinks
3410
+ if (!dryRun) {
3411
+ await assertManagedDestination(hudConfigPath, projectRoot);
3412
+ }
3308
3413
  if (force || !existsSync(hudConfigPath)) {
3309
3414
  if (!dryRun) {
3310
3415
  const defaultHudConfig = { preset: "focused" };
@@ -3415,6 +3520,7 @@ function isGitHubCliConfigured() {
3415
3520
  return cachedGitHubCliConfigured;
3416
3521
  }
3417
3522
  async function syncManagedFileFromDisk(srcPath, dstPath, summary, backupContext, options, verboseLabel) {
3523
+ await assertManagedDestination(dstPath, backupContext.baseRoot);
3418
3524
  const destinationExists = existsSync(dstPath);
3419
3525
  const changed = !destinationExists || (await filesDiffer(srcPath, dstPath));
3420
3526
  if (!changed) {
@@ -3434,6 +3540,7 @@ async function syncManagedFileFromDisk(srcPath, dstPath, summary, backupContext,
3434
3540
  }
3435
3541
  }
3436
3542
  async function syncManagedContent(content, dstPath, summary, backupContext, options, verboseLabel) {
3543
+ await assertManagedDestination(dstPath, backupContext.baseRoot);
3437
3544
  const destinationExists = existsSync(dstPath);
3438
3545
  let changed = true;
3439
3546
  if (destinationExists) {
@@ -3490,8 +3597,9 @@ async function readNativeAgentInstallManifest(agentsDir) {
3490
3597
  return { version: 1, files: {} };
3491
3598
  }
3492
3599
  }
3493
- async function writeNativeAgentInstallManifest(agentsDir, manifest) {
3600
+ async function writeNativeAgentInstallManifest(agentsDir, manifest, scopeRoot) {
3494
3601
  const manifestPath = nativeAgentInstallManifestPath(agentsDir);
3602
+ await assertManagedDestination(manifestPath, scopeRoot);
3495
3603
  await mkdir(dirname(manifestPath), { recursive: true });
3496
3604
  const sortedFiles = Object.fromEntries(Object.entries(manifest.files).sort(([left], [right]) => left.localeCompare(right)));
3497
3605
  await writeFile(manifestPath, JSON.stringify({ version: 1, files: sortedFiles }, null, 2) + "\n");
@@ -3499,6 +3607,7 @@ async function writeNativeAgentInstallManifest(agentsDir, manifest) {
3499
3607
  async function syncNativeAgentToml(content, dstPath, summary, backupContext, options, verboseLabel, manifest) {
3500
3608
  const fileName = basename(dstPath);
3501
3609
  const nextHash = hashContent(content);
3610
+ await assertManagedDestination(dstPath, backupContext.baseRoot);
3502
3611
  const destinationExists = existsSync(dstPath);
3503
3612
  if (!destinationExists) {
3504
3613
  if (!options.dryRun) {
@@ -3718,6 +3827,7 @@ async function cleanupGeneratedNonInstallableNativeAgents(agentsDir, manifest, b
3718
3827
  async function refreshNativeAgentConfigs(pkgRoot, agentsDir, backupContext, options) {
3719
3828
  const summary = createEmptyCategorySummary();
3720
3829
  if (!options.dryRun) {
3830
+ await assertManagedDestination(agentsDir, backupContext.baseRoot);
3721
3831
  await mkdir(agentsDir, { recursive: true });
3722
3832
  }
3723
3833
  const nativeAgentManifest = await readNativeAgentInstallManifest(agentsDir);
@@ -3800,7 +3910,7 @@ async function refreshNativeAgentConfigs(pkgRoot, agentsDir, backupContext, opti
3800
3910
  }
3801
3911
  }
3802
3912
  if (!options.dryRun) {
3803
- await writeNativeAgentInstallManifest(agentsDir, nativeAgentManifest);
3913
+ await writeNativeAgentInstallManifest(agentsDir, nativeAgentManifest, backupContext.baseRoot);
3804
3914
  }
3805
3915
  return summary;
3806
3916
  }
@@ -3850,6 +3960,10 @@ export async function installSkills(srcDir, dstDir, backupContext, options) {
3850
3960
  const summary = createEmptyCategorySummary();
3851
3961
  if (!existsSync(srcDir))
3852
3962
  return summary;
3963
+ // Validate the skills directory before creating any skill subdirectories
3964
+ if (!options.dryRun) {
3965
+ await assertManagedDestination(dstDir, backupContext.baseRoot);
3966
+ }
3853
3967
  const installableSkillNames = getSetupInstallableSkillNames();
3854
3968
  const installableSkills = [];
3855
3969
  const manifest = tryReadCatalogManifest();
@@ -3906,6 +4020,7 @@ export async function installSkills(srcDir, dstDir, backupContext, options) {
3906
4020
  const skillSrc = skill.sourceDir;
3907
4021
  const skillDst = skill.destinationDir;
3908
4022
  if (!options.dryRun) {
4023
+ await assertManagedDestination(skillDst, backupContext.baseRoot);
3909
4024
  await mkdir(skillDst, { recursive: true });
3910
4025
  }
3911
4026
  const skillFiles = await readdir(skillSrc);
@@ -3929,7 +4044,7 @@ export async function installSkills(srcDir, dstDir, backupContext, options) {
3929
4044
  // Without an authority path, refuse to create a receipt rather than placing deletion authority
3930
4045
  // in the user-writable skills directory.
3931
4046
  if (options.skillReceiptPath) {
3932
- await writeInstalledSkillReceipt(options.skillReceiptPath, dstDir, writtenFilesBySkill, options);
4047
+ await writeInstalledSkillReceipt(options.skillReceiptPath, dstDir, writtenFilesBySkill, options, backupContext.baseRoot);
3933
4048
  }
3934
4049
  if (manifest && existsSync(dstDir)) {
3935
4050
  for (const staleSkill of staleCandidateSkillNames) {