@skillsmith/core 0.12.3 → 0.12.4
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/CHANGELOG.md +164 -0
- package/README.md +2 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/config/owned-lock.acquire.d.ts +8 -0
- package/dist/src/config/owned-lock.acquire.d.ts.map +1 -1
- package/dist/src/config/owned-lock.acquire.js +19 -4
- package/dist/src/config/owned-lock.acquire.js.map +1 -1
- package/dist/src/config/owned-lock.claim.d.ts +4 -2
- package/dist/src/config/owned-lock.claim.d.ts.map +1 -1
- package/dist/src/config/owned-lock.claim.js +42 -8
- package/dist/src/config/owned-lock.claim.js.map +1 -1
- package/dist/src/config/owned-lock.d.ts.map +1 -1
- package/dist/src/config/owned-lock.js +1 -0
- package/dist/src/config/owned-lock.js.map +1 -1
- package/dist/src/config/owned-lock.test.js +126 -2
- package/dist/src/config/owned-lock.test.js.map +1 -1
- package/dist/src/config/owned-lock.types.d.ts +9 -0
- package/dist/src/config/owned-lock.types.d.ts.map +1 -1
- package/dist/src/db/createDatabase.d.ts.map +1 -1
- package/dist/src/db/createDatabase.js +0 -2
- package/dist/src/db/createDatabase.js.map +1 -1
- package/dist/src/exports/services.install.d.ts +1 -0
- package/dist/src/exports/services.install.d.ts.map +1 -1
- package/dist/src/exports/services.install.js +5 -0
- package/dist/src/exports/services.install.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/install/fan-out.cleanup.d.ts +37 -0
- package/dist/src/install/fan-out.cleanup.d.ts.map +1 -0
- package/dist/src/install/fan-out.cleanup.js +75 -0
- package/dist/src/install/fan-out.cleanup.js.map +1 -0
- package/dist/src/install/fan-out.d.ts +41 -31
- package/dist/src/install/fan-out.d.ts.map +1 -1
- package/dist/src/install/fan-out.js +213 -112
- package/dist/src/install/fan-out.js.map +1 -1
- package/dist/src/install/fan-out.leftovers.d.ts +60 -0
- package/dist/src/install/fan-out.leftovers.d.ts.map +1 -0
- package/dist/src/install/fan-out.leftovers.js +251 -0
- package/dist/src/install/fan-out.leftovers.js.map +1 -0
- package/dist/src/install/fan-out.locks.d.ts +12 -0
- package/dist/src/install/fan-out.locks.d.ts.map +1 -0
- package/dist/src/install/fan-out.locks.js +114 -0
- package/dist/src/install/fan-out.locks.js.map +1 -0
- package/dist/src/install/fan-out.manifest.d.ts +64 -0
- package/dist/src/install/fan-out.manifest.d.ts.map +1 -0
- package/dist/src/install/fan-out.manifest.js +130 -0
- package/dist/src/install/fan-out.manifest.js.map +1 -0
- package/dist/src/install/fan-out.overwrite.d.ts +51 -0
- package/dist/src/install/fan-out.overwrite.d.ts.map +1 -0
- package/dist/src/install/fan-out.overwrite.js +343 -0
- package/dist/src/install/fan-out.overwrite.js.map +1 -0
- package/dist/src/install/remove-if-same.d.ts +58 -0
- package/dist/src/install/remove-if-same.d.ts.map +1 -0
- package/dist/src/install/remove-if-same.js +222 -0
- package/dist/src/install/remove-if-same.js.map +1 -0
- package/dist/src/provenance/backfill.d.ts.map +1 -1
- package/dist/src/provenance/backfill.js +15 -2
- package/dist/src/provenance/backfill.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js +8 -1
- package/dist/src/security/scanner/SecurityScanner.scanners.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.value-gate.d.ts +22 -2
- package/dist/src/security/scanner/SecurityScanner.value-gate.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.value-gate.js +143 -6
- package/dist/src/security/scanner/SecurityScanner.value-gate.js.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.d.ts +2 -2
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.d.ts.map +1 -1
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.js +185 -190
- package/dist/src/security/scanner/SecurityScanner.weak-passwords.js.map +1 -1
- package/dist/src/security/scanner/patterns.d.ts +47 -2
- package/dist/src/security/scanner/patterns.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.js +48 -3
- package/dist/src/security/scanner/patterns.js.map +1 -1
- package/dist/src/security/scanner/patterns.sensitive-path.d.ts +31 -3
- package/dist/src/security/scanner/patterns.sensitive-path.d.ts.map +1 -1
- package/dist/src/security/scanner/patterns.sensitive-path.js +59 -4
- package/dist/src/security/scanner/patterns.sensitive-path.js.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.d.ts.map +1 -1
- package/dist/src/services/agent-pack/prompt-source.js +3 -2
- package/dist/src/services/agent-pack/prompt-source.js.map +1 -1
- package/dist/src/services/skill-installation.content.d.ts +7 -2
- package/dist/src/services/skill-installation.content.d.ts.map +1 -1
- package/dist/src/services/skill-installation.content.js +75 -28
- package/dist/src/services/skill-installation.content.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +8 -0
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.io.d.ts +1 -29
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.dirs.d.ts +15 -0
- package/dist/src/services/skill-installation.io.dirs.d.ts.map +1 -0
- package/dist/src/services/skill-installation.io.dirs.js +84 -0
- package/dist/src/services/skill-installation.io.dirs.js.map +1 -0
- package/dist/src/services/skill-installation.io.js +6 -176
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/services/skill-installation.io.rollback.d.ts +138 -0
- package/dist/src/services/skill-installation.io.rollback.d.ts.map +1 -0
- package/dist/src/services/skill-installation.io.rollback.js +218 -0
- package/dist/src/services/skill-installation.io.rollback.js.map +1 -0
- package/dist/src/services/skill-installation.io.write.d.ts +69 -0
- package/dist/src/services/skill-installation.io.write.d.ts.map +1 -0
- package/dist/src/services/skill-installation.io.write.js +417 -0
- package/dist/src/services/skill-installation.io.write.js.map +1 -0
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.finalize.d.ts +62 -0
- package/dist/src/services/skill-installation.service.finalize.d.ts.map +1 -0
- package/dist/src/services/skill-installation.service.finalize.js +136 -0
- package/dist/src/services/skill-installation.service.finalize.js.map +1 -0
- package/dist/src/services/skill-installation.service.js +66 -80
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.target-guard.d.ts +82 -0
- package/dist/src/services/skill-installation.target-guard.d.ts.map +1 -0
- package/dist/src/services/skill-installation.target-guard.js +410 -0
- package/dist/src/services/skill-installation.target-guard.js.map +1 -0
- package/dist/src/services/skill-installation.types.d.ts +13 -1
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/services/skill-installation.uninstall.d.ts +3 -1
- package/dist/src/services/skill-installation.uninstall.d.ts.map +1 -1
- package/dist/src/services/skill-installation.uninstall.helpers.d.ts +59 -0
- package/dist/src/services/skill-installation.uninstall.helpers.d.ts.map +1 -0
- package/dist/src/services/skill-installation.uninstall.helpers.js +124 -0
- package/dist/src/services/skill-installation.uninstall.helpers.js.map +1 -0
- package/dist/src/services/skill-installation.uninstall.js +148 -25
- package/dist/src/services/skill-installation.uninstall.js.map +1 -1
- package/dist/src/utils/safe-fs.d.ts +69 -0
- package/dist/src/utils/safe-fs.d.ts.map +1 -1
- package/dist/src/utils/safe-fs.js +113 -2
- package/dist/src/utils/safe-fs.js.map +1 -1
- package/dist/tests/install/fan-out.test.js +1951 -13
- package/dist/tests/install/fan-out.test.js.map +1 -1
- package/dist/tests/install/remove-if-same.test.d.ts +2 -0
- package/dist/tests/install/remove-if-same.test.d.ts.map +1 -0
- package/dist/tests/install/remove-if-same.test.js +298 -0
- package/dist/tests/install/remove-if-same.test.js.map +1 -0
- package/dist/tests/integration/fan-out-lock-contention.test.d.ts +11 -0
- package/dist/tests/integration/fan-out-lock-contention.test.d.ts.map +1 -0
- package/dist/tests/integration/fan-out-lock-contention.test.js +53 -0
- package/dist/tests/integration/fan-out-lock-contention.test.js.map +1 -0
- package/dist/tests/provenance/backfill.test.js +43 -0
- package/dist/tests/provenance/backfill.test.js.map +1 -1
- package/dist/tests/security/scanner-regression-guard.test.js +33 -5
- package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-adversarial-review.test.js +120 -0
- package/dist/tests/security/sensitive-path-adversarial-review.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-boolean-flag.test.d.ts +2 -0
- package/dist/tests/security/sensitive-path-boolean-flag.test.d.ts.map +1 -0
- package/dist/tests/security/sensitive-path-boolean-flag.test.js +151 -0
- package/dist/tests/security/sensitive-path-boolean-flag.test.js.map +1 -0
- package/dist/tests/security/sensitive-path-fp.test.js +71 -5
- package/dist/tests/security/sensitive-path-fp.test.js.map +1 -1
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.d.ts +2 -0
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.d.ts.map +1 -0
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.js +176 -0
- package/dist/tests/security/sensitive-path-prefixed-secrets.test.js.map +1 -0
- package/dist/tests/security/weak-password-lexicon.test.js +14 -4
- package/dist/tests/security/weak-password-lexicon.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.content.test.js +23 -0
- package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js +35 -14
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.io.rollback.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.test.js +984 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.js +148 -0
- package/dist/tests/unit/services/skill-installation.io.rollback.unit.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js +19 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.service.finalize.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.service.finalize.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.finalize.test.js +147 -0
- package/dist/tests/unit/services/skill-installation.service.finalize.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.test.js +43 -0
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.target-guard.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.target-guard.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.target-guard.test.js +590 -0
- package/dist/tests/unit/services/skill-installation.target-guard.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.d.ts +2 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.js +473 -0
- package/dist/tests/unit/services/skill-installation.uninstall.guard.test.js.map +1 -0
- package/dist/tests/utils/safe-fs.test.js +129 -2
- package/dist/tests/utils/safe-fs.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview checkInstallTarget() — one test per rule.
|
|
3
|
+
* @see SMI-6529 Wave A0
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
6
|
+
import * as fs from 'fs/promises';
|
|
7
|
+
import * as os from 'os';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { checkInstallTarget } from '../../../src/services/skill-installation.target-guard.js';
|
|
10
|
+
const roots = [];
|
|
11
|
+
async function makeRoot(label) {
|
|
12
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'target-guard-' + label + '-'));
|
|
13
|
+
roots.push(root);
|
|
14
|
+
const skillsDir = path.join(root, 'skills');
|
|
15
|
+
await fs.mkdir(skillsDir, { recursive: true });
|
|
16
|
+
return { root, skillsDir };
|
|
17
|
+
}
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
await Promise.all(roots.splice(0).map((r) => fs.rm(r, { recursive: true, force: true })));
|
|
20
|
+
});
|
|
21
|
+
function baseEntry(installPath) {
|
|
22
|
+
return {
|
|
23
|
+
id: 'author/skill',
|
|
24
|
+
name: 'skill',
|
|
25
|
+
version: '1.0.0',
|
|
26
|
+
source: 'github:author/skill',
|
|
27
|
+
installPath,
|
|
28
|
+
installedAt: '2026-01-01T00:00:00.000Z',
|
|
29
|
+
lastUpdated: '2026-01-01T00:00:00.000Z',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
describe('checkInstallTarget (SMI-6529 Wave A0)', () => {
|
|
33
|
+
it('fresh ENOENT: ok, preExisted false', async () => {
|
|
34
|
+
const { skillsDir } = await makeRoot('fresh');
|
|
35
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
36
|
+
const result = await checkInstallTarget({
|
|
37
|
+
installPath,
|
|
38
|
+
skillsDir,
|
|
39
|
+
manifestEntry: undefined,
|
|
40
|
+
force: false,
|
|
41
|
+
});
|
|
42
|
+
expect(result).toEqual({ ok: true, preExisted: false });
|
|
43
|
+
});
|
|
44
|
+
it('rule (a): expectedInstallPath mismatch refuses even on a fresh ENOENT path', async () => {
|
|
45
|
+
const { skillsDir } = await makeRoot('mismatch');
|
|
46
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
47
|
+
const expectedInstallPath = path.join(skillsDir, 'other-dir');
|
|
48
|
+
const result = await checkInstallTarget({
|
|
49
|
+
installPath,
|
|
50
|
+
skillsDir,
|
|
51
|
+
manifestEntry: undefined,
|
|
52
|
+
force: true, // force does NOT override this
|
|
53
|
+
expectedInstallPath,
|
|
54
|
+
});
|
|
55
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_MISMATCH' });
|
|
56
|
+
});
|
|
57
|
+
// F6 (review round 1): both sides of rule (a) must resolve through the
|
|
58
|
+
// identical symmetric helper, so a symlinked path spelling (macOS
|
|
59
|
+
// /var -> /private/var) doesn't produce a false mismatch.
|
|
60
|
+
it('rule (a) / F6: a symlinked parent spelling of expectedInstallPath does NOT false-positive as a mismatch', async () => {
|
|
61
|
+
const { root, skillsDir } = await makeRoot('mismatch-symlink');
|
|
62
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
63
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
64
|
+
// A symlinked ALIAS of skillsDir itself (mirrors macOS's real
|
|
65
|
+
// /var/folders -> /private/var/folders) — expectedInstallPath is spelled
|
|
66
|
+
// through the alias, installPath through the real path. Same real
|
|
67
|
+
// directory, two different lexical strings.
|
|
68
|
+
const skillsDirAlias = path.join(root, 'skills-alias');
|
|
69
|
+
await fs.symlink(skillsDir, skillsDirAlias, 'dir');
|
|
70
|
+
const expectedInstallPath = path.join(skillsDirAlias, 'my-skill');
|
|
71
|
+
const result = await checkInstallTarget({
|
|
72
|
+
installPath,
|
|
73
|
+
skillsDir,
|
|
74
|
+
manifestEntry: baseEntry(installPath),
|
|
75
|
+
force: true,
|
|
76
|
+
expectedInstallPath,
|
|
77
|
+
});
|
|
78
|
+
expect(result).not.toMatchObject({ code: 'INSTALL_TARGET_MISMATCH' });
|
|
79
|
+
expect(result).toEqual({ ok: true, preExisted: true });
|
|
80
|
+
});
|
|
81
|
+
it('rule (c): install target exists but is not a directory', async () => {
|
|
82
|
+
const { skillsDir } = await makeRoot('not-dir');
|
|
83
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
84
|
+
await fs.writeFile(installPath, 'not a directory');
|
|
85
|
+
const result = await checkInstallTarget({
|
|
86
|
+
installPath,
|
|
87
|
+
skillsDir,
|
|
88
|
+
manifestEntry: undefined,
|
|
89
|
+
force: true,
|
|
90
|
+
});
|
|
91
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_NOT_DIRECTORY' });
|
|
92
|
+
});
|
|
93
|
+
it('rule (d): a .git entry directly at the install target refuses, even under force', async () => {
|
|
94
|
+
const { skillsDir } = await makeRoot('git-target');
|
|
95
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
96
|
+
await fs.mkdir(path.join(installPath, '.git'), { recursive: true });
|
|
97
|
+
const result = await checkInstallTarget({
|
|
98
|
+
installPath,
|
|
99
|
+
skillsDir,
|
|
100
|
+
manifestEntry: baseEntry(installPath),
|
|
101
|
+
force: true,
|
|
102
|
+
});
|
|
103
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
104
|
+
});
|
|
105
|
+
it('rule (d): a .git entry in an ancestor STRICTLY BETWEEN installPath and skillsDir refuses', async () => {
|
|
106
|
+
const { skillsDir } = await makeRoot('git-parent');
|
|
107
|
+
// installPath is nested TWO levels below skillsDir; .git sits at the
|
|
108
|
+
// intermediate level (neither installPath itself nor skillsDir itself),
|
|
109
|
+
// proving the walk visits every level in between, not just the endpoints.
|
|
110
|
+
const midDir = path.join(skillsDir, 'mid');
|
|
111
|
+
const installPath = path.join(midDir, 'leaf');
|
|
112
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
113
|
+
await fs.mkdir(path.join(midDir, '.git'), { recursive: true });
|
|
114
|
+
const result = await checkInstallTarget({
|
|
115
|
+
installPath,
|
|
116
|
+
skillsDir,
|
|
117
|
+
manifestEntry: baseEntry(installPath),
|
|
118
|
+
force: true,
|
|
119
|
+
});
|
|
120
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
121
|
+
});
|
|
122
|
+
it('rule (d): a .git FILE (worktree pointer) also counts, not just a directory', async () => {
|
|
123
|
+
const { skillsDir } = await makeRoot('git-file');
|
|
124
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
125
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
126
|
+
await fs.writeFile(path.join(installPath, '.git'), 'gitdir: ../.git/worktrees/my-skill\n');
|
|
127
|
+
const result = await checkInstallTarget({
|
|
128
|
+
installPath,
|
|
129
|
+
skillsDir,
|
|
130
|
+
manifestEntry: baseEntry(installPath),
|
|
131
|
+
force: true,
|
|
132
|
+
});
|
|
133
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
134
|
+
});
|
|
135
|
+
it("rule (d) does not fire above skillsDir: a .git at skillsDir's PARENT is out of scope", async () => {
|
|
136
|
+
const { root, skillsDir } = await makeRoot('git-above');
|
|
137
|
+
await fs.mkdir(path.join(root, '.git'), { recursive: true }); // one level ABOVE skillsDir
|
|
138
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
139
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
140
|
+
const result = await checkInstallTarget({
|
|
141
|
+
installPath,
|
|
142
|
+
skillsDir,
|
|
143
|
+
manifestEntry: baseEntry(installPath),
|
|
144
|
+
force: true,
|
|
145
|
+
});
|
|
146
|
+
// Falls through to the untracked/tracked rules instead — proves the walk
|
|
147
|
+
// never climbed past skillsDir.
|
|
148
|
+
expect(result).not.toMatchObject({ code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
149
|
+
});
|
|
150
|
+
it('rule (e): an untracked pre-existing directory with NO manifest entry refuses, even under force', async () => {
|
|
151
|
+
const { skillsDir } = await makeRoot('untracked-none');
|
|
152
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
153
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
154
|
+
const result = await checkInstallTarget({
|
|
155
|
+
installPath,
|
|
156
|
+
skillsDir,
|
|
157
|
+
manifestEntry: undefined,
|
|
158
|
+
force: true,
|
|
159
|
+
});
|
|
160
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_UNTRACKED' });
|
|
161
|
+
});
|
|
162
|
+
it('rule (e): a manifest entry pointing at a DIFFERENT (e.g. leaked/stale) directory refuses', async () => {
|
|
163
|
+
const { skillsDir } = await makeRoot('untracked-elsewhere');
|
|
164
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
165
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
166
|
+
// A stale entry pointing at a temp dir that no longer exists — the exact
|
|
167
|
+
// "leaked temp install dir" shape a stray/orphaned manifest write can
|
|
168
|
+
// leave behind. realpath() falls back to path.resolve() for this.
|
|
169
|
+
const staleInstallPath = path.join(os.tmpdir(), 'never-existed-' + Date.now());
|
|
170
|
+
const result = await checkInstallTarget({
|
|
171
|
+
installPath,
|
|
172
|
+
skillsDir,
|
|
173
|
+
manifestEntry: baseEntry(staleInstallPath),
|
|
174
|
+
force: true,
|
|
175
|
+
});
|
|
176
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_UNTRACKED' });
|
|
177
|
+
});
|
|
178
|
+
it('rule (e): a manifestEntry.installPath reached via a symlink is still recognized as the SAME tracked path (realpath aliasing)', async () => {
|
|
179
|
+
const { root, skillsDir } = await makeRoot('symlink-alias');
|
|
180
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
181
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
182
|
+
// Mirrors macOS's real /var/folders -> /private/var/folders symlink: the
|
|
183
|
+
// manifest entry's recorded path and the live installPath can be two
|
|
184
|
+
// different (but realpath-equivalent) strings for the SAME directory.
|
|
185
|
+
const symlinkAlias = path.join(root, 'alias-to-install');
|
|
186
|
+
await fs.symlink(installPath, symlinkAlias, 'dir');
|
|
187
|
+
const result = await checkInstallTarget({
|
|
188
|
+
installPath,
|
|
189
|
+
skillsDir,
|
|
190
|
+
manifestEntry: baseEntry(symlinkAlias),
|
|
191
|
+
force: true,
|
|
192
|
+
});
|
|
193
|
+
expect(result).toEqual({ ok: true, preExisted: true });
|
|
194
|
+
});
|
|
195
|
+
// F5 (review round 1) / ADR-155 §3+§5: a path-matching entry that is ITSELF
|
|
196
|
+
// untracked by Skillsmith's own trust model (an ADR-139 adoption, or a
|
|
197
|
+
// user's local assertion) must still refuse — `force` never overrides
|
|
198
|
+
// this. Without this, `skillsmith install <id> --force` over an adopted or
|
|
199
|
+
// local directory would silently overwrite the user's own skill.
|
|
200
|
+
it("F5: a path-matching entry with source:'unknown' (ADR-139 adoption) refuses even under force", async () => {
|
|
201
|
+
const { skillsDir } = await makeRoot('adopted-untracked');
|
|
202
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
203
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
204
|
+
const result = await checkInstallTarget({
|
|
205
|
+
installPath,
|
|
206
|
+
skillsDir,
|
|
207
|
+
manifestEntry: { ...baseEntry(installPath), source: 'unknown' },
|
|
208
|
+
force: true,
|
|
209
|
+
});
|
|
210
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_UNTRACKED' });
|
|
211
|
+
});
|
|
212
|
+
it("F5: a path-matching entry with provenance:'local' refuses even under force", async () => {
|
|
213
|
+
const { skillsDir } = await makeRoot('local-untracked');
|
|
214
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
215
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
216
|
+
const result = await checkInstallTarget({
|
|
217
|
+
installPath,
|
|
218
|
+
skillsDir,
|
|
219
|
+
manifestEntry: { ...baseEntry(installPath), provenance: 'local' },
|
|
220
|
+
force: true,
|
|
221
|
+
});
|
|
222
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_UNTRACKED' });
|
|
223
|
+
});
|
|
224
|
+
it('rule (f): tracked + no force -> ALREADY_INSTALLED', async () => {
|
|
225
|
+
const { skillsDir } = await makeRoot('tracked-noforce');
|
|
226
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
227
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
228
|
+
const result = await checkInstallTarget({
|
|
229
|
+
installPath,
|
|
230
|
+
skillsDir,
|
|
231
|
+
manifestEntry: baseEntry(installPath),
|
|
232
|
+
force: false,
|
|
233
|
+
});
|
|
234
|
+
expect(result).toMatchObject({ ok: false, code: 'ALREADY_INSTALLED' });
|
|
235
|
+
});
|
|
236
|
+
it('rule (f): tracked + force -> ok, preExisted true', async () => {
|
|
237
|
+
const { skillsDir } = await makeRoot('tracked-force');
|
|
238
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
239
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
240
|
+
const result = await checkInstallTarget({
|
|
241
|
+
installPath,
|
|
242
|
+
skillsDir,
|
|
243
|
+
manifestEntry: baseEntry(installPath),
|
|
244
|
+
force: true,
|
|
245
|
+
});
|
|
246
|
+
expect(result).toEqual({ ok: true, preExisted: true });
|
|
247
|
+
});
|
|
248
|
+
// SMI-6529 H1 (round 2, reviewer probe-guard.mjs P1 — "THE exact H1 exploit"):
|
|
249
|
+
// installPath is a symlink into a SUBDIRECTORY of a git clone that itself
|
|
250
|
+
// lives inside skillsDir. The LEXICAL ancestor walk never crosses the
|
|
251
|
+
// symlink boundary (path.dirname on the symlink's own string jumps
|
|
252
|
+
// straight to skillsDir); only a REALPATH walk finds the clone's `.git`.
|
|
253
|
+
describe('H1: symlink-to-git-clone bypass (round 2)', () => {
|
|
254
|
+
it('P1: symlink -> subdirectory of an in-skillsDir git clone refuses, even under force', async () => {
|
|
255
|
+
const { skillsDir } = await makeRoot('h1-p1');
|
|
256
|
+
const clone = path.join(skillsDir, 'anthropic-skills');
|
|
257
|
+
await fs.mkdir(path.join(clone, '.git'), { recursive: true });
|
|
258
|
+
const target = path.join(clone, 'document-skills', 'pdf');
|
|
259
|
+
await fs.mkdir(target, { recursive: true });
|
|
260
|
+
await fs.writeFile(path.join(target, 'SKILL.md'), 'UNCOMMITTED USER WORK');
|
|
261
|
+
const installPath = path.join(skillsDir, 'pdf');
|
|
262
|
+
await fs.symlink(target, installPath, 'dir');
|
|
263
|
+
const result = await checkInstallTarget({
|
|
264
|
+
installPath,
|
|
265
|
+
skillsDir,
|
|
266
|
+
manifestEntry: baseEntry(installPath),
|
|
267
|
+
force: true,
|
|
268
|
+
});
|
|
269
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
270
|
+
});
|
|
271
|
+
it('P2: symlink -> the git clone ROOT itself (not a subdirectory) refuses', async () => {
|
|
272
|
+
const { skillsDir } = await makeRoot('h1-p2');
|
|
273
|
+
const clone = path.join(skillsDir, 'some-clone');
|
|
274
|
+
await fs.mkdir(path.join(clone, '.git'), { recursive: true });
|
|
275
|
+
const installPath = path.join(skillsDir, 'aliased');
|
|
276
|
+
await fs.symlink(clone, installPath, 'dir');
|
|
277
|
+
const result = await checkInstallTarget({
|
|
278
|
+
installPath,
|
|
279
|
+
skillsDir,
|
|
280
|
+
manifestEntry: baseEntry(installPath),
|
|
281
|
+
force: true,
|
|
282
|
+
});
|
|
283
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
284
|
+
});
|
|
285
|
+
it('P4: skillsDir itself is a git repo refuses', async () => {
|
|
286
|
+
const { skillsDir } = await makeRoot('h1-p4');
|
|
287
|
+
await fs.mkdir(path.join(skillsDir, '.git'), { recursive: true });
|
|
288
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
289
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
290
|
+
const result = await checkInstallTarget({
|
|
291
|
+
installPath,
|
|
292
|
+
skillsDir,
|
|
293
|
+
manifestEntry: baseEntry(installPath),
|
|
294
|
+
force: true,
|
|
295
|
+
});
|
|
296
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
297
|
+
});
|
|
298
|
+
it('P5: a symlinked skillsDir whose real ancestry has .git ABOVE its own real target does NOT refuse', async () => {
|
|
299
|
+
const { root } = await makeRoot('h1-p5');
|
|
300
|
+
// A "dotfiles repo" with .git at its root; skillsDir is a symlink
|
|
301
|
+
// pointing at a SUBDIRECTORY of it (never itself carrying .git) — the
|
|
302
|
+
// walk must stop at skillsDir's own real location, never climb past it.
|
|
303
|
+
const dotfilesRepo = path.join(root, 'dotfiles');
|
|
304
|
+
await fs.mkdir(path.join(dotfilesRepo, '.git'), { recursive: true });
|
|
305
|
+
const realSkillsDir = path.join(dotfilesRepo, 'generated', 'skills');
|
|
306
|
+
await fs.mkdir(realSkillsDir, { recursive: true });
|
|
307
|
+
const skillsDirAlias = path.join(root, 'skills-symlink');
|
|
308
|
+
await fs.symlink(realSkillsDir, skillsDirAlias, 'dir');
|
|
309
|
+
const installPath = path.join(skillsDirAlias, 'my-skill');
|
|
310
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
311
|
+
const result = await checkInstallTarget({
|
|
312
|
+
installPath,
|
|
313
|
+
skillsDir: skillsDirAlias,
|
|
314
|
+
manifestEntry: baseEntry(installPath),
|
|
315
|
+
force: true,
|
|
316
|
+
});
|
|
317
|
+
expect(result).not.toMatchObject({ code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
318
|
+
expect(result).toEqual({ ok: true, preExisted: true });
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
// SMI-6529 L13: the GIT_WORKTREE tip/message names the actual git root and
|
|
322
|
+
// is worded differently depending on whether it's installPath itself.
|
|
323
|
+
describe('L13: tailored git-worktree message', () => {
|
|
324
|
+
it('names installPath itself when .git is directly there', async () => {
|
|
325
|
+
const { skillsDir } = await makeRoot('l13-direct');
|
|
326
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
327
|
+
await fs.mkdir(path.join(installPath, '.git'), { recursive: true });
|
|
328
|
+
const result = await checkInstallTarget({
|
|
329
|
+
installPath,
|
|
330
|
+
skillsDir,
|
|
331
|
+
manifestEntry: baseEntry(installPath),
|
|
332
|
+
force: true,
|
|
333
|
+
});
|
|
334
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
335
|
+
if (!result.ok) {
|
|
336
|
+
expect(result.error).toContain(installPath);
|
|
337
|
+
expect(result.error).not.toContain('rooted at');
|
|
338
|
+
expect(result.tips?.[0]).toContain('git -C "' + installPath + '"');
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
it('names the ancestor git root when .git is above installPath', async () => {
|
|
342
|
+
const { skillsDir } = await makeRoot('l13-ancestor');
|
|
343
|
+
const midDir = path.join(skillsDir, 'mid');
|
|
344
|
+
const installPath = path.join(midDir, 'leaf');
|
|
345
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
346
|
+
await fs.mkdir(path.join(midDir, '.git'), { recursive: true });
|
|
347
|
+
const result = await checkInstallTarget({
|
|
348
|
+
installPath,
|
|
349
|
+
skillsDir,
|
|
350
|
+
manifestEntry: baseEntry(installPath),
|
|
351
|
+
force: true,
|
|
352
|
+
});
|
|
353
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
354
|
+
if (!result.ok) {
|
|
355
|
+
expect(result.error).toContain('rooted at');
|
|
356
|
+
expect(result.error).toContain(midDir);
|
|
357
|
+
expect(result.tips?.[0]).toContain('git -C "' + midDir + '"');
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
// SMI-6529 L16: an lstat error the guard can't interpret as "definitely
|
|
362
|
+
// absent" must fail CLOSED (treated as a git-worktree hit), never silently
|
|
363
|
+
// as "no .git here."
|
|
364
|
+
describe('L16: pathHasGitEntry fails closed on an unexpected lstat error', () => {
|
|
365
|
+
it('EACCES on the .git lstat refuses as INSTALL_TARGET_GIT_WORKTREE', async () => {
|
|
366
|
+
const { skillsDir } = await makeRoot('l16-eacces');
|
|
367
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
368
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
369
|
+
const gitPath = path.join(installPath, '.git');
|
|
370
|
+
vi.doMock('fs/promises', async () => {
|
|
371
|
+
const actual = await vi.importActual('fs/promises');
|
|
372
|
+
return {
|
|
373
|
+
...actual,
|
|
374
|
+
default: actual,
|
|
375
|
+
lstat: vi.fn((p, ...rest) => {
|
|
376
|
+
if (p === gitPath) {
|
|
377
|
+
const err = new Error('EACCES: permission denied, lstat');
|
|
378
|
+
err.code = 'EACCES';
|
|
379
|
+
return Promise.reject(err);
|
|
380
|
+
}
|
|
381
|
+
return actual.lstat(p, ...rest);
|
|
382
|
+
}),
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
try {
|
|
386
|
+
vi.resetModules();
|
|
387
|
+
const { checkInstallTarget: checkInstallTargetMocked } = await import('../../../src/services/skill-installation.target-guard.js');
|
|
388
|
+
const result = await checkInstallTargetMocked({
|
|
389
|
+
installPath,
|
|
390
|
+
skillsDir,
|
|
391
|
+
manifestEntry: baseEntry(installPath),
|
|
392
|
+
force: true,
|
|
393
|
+
});
|
|
394
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
395
|
+
}
|
|
396
|
+
finally {
|
|
397
|
+
vi.doUnmock('fs/promises');
|
|
398
|
+
vi.resetModules();
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
// SMI-6529 #16 (round 4): the refusal CODE from the test above is
|
|
402
|
+
// correct and unchanged — L16's fail-closed behavior is not in
|
|
403
|
+
// question. What was wrong is the MESSAGE: a plain boolean collapsed
|
|
404
|
+
// "found a .git entry" and "couldn't tell" into the same `true`, so an
|
|
405
|
+
// EACCES was reported to the user as "is a git working tree," which is
|
|
406
|
+
// simply false — we never actually saw a `.git` entry, we just
|
|
407
|
+
// couldn't check for one. This test asserts the message now names the
|
|
408
|
+
// real reason (the exact errno) instead of the false claim.
|
|
409
|
+
it('EACCES on the .git lstat produces an ACCURATE message ("could not check ... EACCES"), never the false "is a git working tree" claim', async () => {
|
|
410
|
+
const { skillsDir } = await makeRoot('smi16-eacces-message');
|
|
411
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
412
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
413
|
+
const gitPath = path.join(installPath, '.git');
|
|
414
|
+
vi.doMock('fs/promises', async () => {
|
|
415
|
+
const actual = await vi.importActual('fs/promises');
|
|
416
|
+
return {
|
|
417
|
+
...actual,
|
|
418
|
+
default: actual,
|
|
419
|
+
lstat: vi.fn((p, ...rest) => {
|
|
420
|
+
if (p === gitPath) {
|
|
421
|
+
const err = new Error('EACCES: permission denied, lstat');
|
|
422
|
+
err.code = 'EACCES';
|
|
423
|
+
return Promise.reject(err);
|
|
424
|
+
}
|
|
425
|
+
return actual.lstat(p, ...rest);
|
|
426
|
+
}),
|
|
427
|
+
};
|
|
428
|
+
});
|
|
429
|
+
try {
|
|
430
|
+
vi.resetModules();
|
|
431
|
+
const { checkInstallTarget: checkInstallTargetMocked } = await import('../../../src/services/skill-installation.target-guard.js');
|
|
432
|
+
const result = await checkInstallTargetMocked({
|
|
433
|
+
installPath,
|
|
434
|
+
skillsDir,
|
|
435
|
+
manifestEntry: baseEntry(installPath),
|
|
436
|
+
force: true,
|
|
437
|
+
});
|
|
438
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_GIT_WORKTREE' });
|
|
439
|
+
if (!result.ok) {
|
|
440
|
+
expect(result.error).toContain('Could not check');
|
|
441
|
+
expect(result.error).toContain('EACCES');
|
|
442
|
+
expect(result.error).not.toMatch(/is a git working tree/);
|
|
443
|
+
expect(result.error).not.toMatch(/lives inside a git working tree/);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
finally {
|
|
447
|
+
vi.doUnmock('fs/promises');
|
|
448
|
+
vi.resetModules();
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
// SMI-6529 N5 (round 4, reviewer probe-preflight.mjs): a CALLER could hand
|
|
453
|
+
// `checkInstallTarget` an `installPath` that isn't actually inside
|
|
454
|
+
// `skillsDir` at all (e.g. a pre-flight that computed `installPath` from
|
|
455
|
+
// a different client's manifest entry than the `skillsDir` it passed).
|
|
456
|
+
// Without this containment check, rule (d)'s ancestor walk never meets
|
|
457
|
+
// `skillsDir` and silently climbs all the way to the filesystem root —
|
|
458
|
+
// exactly the `~/.claude` (a real git repo) false-refusal probe-preflight
|
|
459
|
+
// .mjs demonstrated.
|
|
460
|
+
describe('N5: containment check — installPath must be inside skillsDir', () => {
|
|
461
|
+
it('refuses when installPath is neither lexically nor (via realpath) really inside skillsDir', async () => {
|
|
462
|
+
const { root, skillsDir } = await makeRoot('n5-outside');
|
|
463
|
+
// A sibling directory, NOT nested under skillsDir at all.
|
|
464
|
+
const outsideDir = path.join(root, 'totally-unrelated');
|
|
465
|
+
await fs.mkdir(outsideDir, { recursive: true });
|
|
466
|
+
const result = await checkInstallTarget({
|
|
467
|
+
installPath: outsideDir,
|
|
468
|
+
skillsDir,
|
|
469
|
+
manifestEntry: undefined,
|
|
470
|
+
force: true,
|
|
471
|
+
});
|
|
472
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_MISMATCH' });
|
|
473
|
+
if (!result.ok) {
|
|
474
|
+
expect(result.error).toContain('not inside skills directory');
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
it('still passes for a legitimate symlinked installPath whose REALPATH resolves inside skillsDir, even though its lexical spelling does not', async () => {
|
|
478
|
+
const { root, skillsDir } = await makeRoot('n5-symlink-inside');
|
|
479
|
+
const realTarget = path.join(skillsDir, 'my-skill');
|
|
480
|
+
await fs.mkdir(realTarget, { recursive: true });
|
|
481
|
+
// A symlink OUTSIDE skillsDir's own lexical tree that resolves INSIDE
|
|
482
|
+
// it — e.g. a fan-out symlink at an unrelated client path.
|
|
483
|
+
const symlinkedInstallPath = path.join(root, 'elsewhere-link');
|
|
484
|
+
await fs.symlink(realTarget, symlinkedInstallPath, 'dir');
|
|
485
|
+
const result = await checkInstallTarget({
|
|
486
|
+
installPath: symlinkedInstallPath,
|
|
487
|
+
skillsDir,
|
|
488
|
+
manifestEntry: baseEntry(realTarget),
|
|
489
|
+
force: false,
|
|
490
|
+
});
|
|
491
|
+
// Must reach the normal tracked/already-installed rules, never the
|
|
492
|
+
// new containment refusal.
|
|
493
|
+
if (!result.ok) {
|
|
494
|
+
expect(result.error).not.toContain('not inside skills directory');
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
// SMI-6529 L17: a manifest entry with a missing/non-absolute installPath
|
|
499
|
+
// refuses with a clear, structured error — never a raw TypeError.
|
|
500
|
+
describe('L17: unusable manifest-entry installPath', () => {
|
|
501
|
+
it('refuses when the matching manifest entry has no installPath', async () => {
|
|
502
|
+
const { skillsDir } = await makeRoot('l17-missing');
|
|
503
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
504
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
505
|
+
const entry = { ...baseEntry(installPath) };
|
|
506
|
+
delete entry.installPath;
|
|
507
|
+
await expect(checkInstallTarget({
|
|
508
|
+
installPath,
|
|
509
|
+
skillsDir,
|
|
510
|
+
manifestEntry: entry,
|
|
511
|
+
force: true,
|
|
512
|
+
})).resolves.toMatchObject({ ok: false, code: 'INSTALL_TARGET_UNTRACKED' });
|
|
513
|
+
});
|
|
514
|
+
it('refuses when the matching manifest entry has a RELATIVE installPath', async () => {
|
|
515
|
+
const { skillsDir } = await makeRoot('l17-relative');
|
|
516
|
+
const installPath = path.join(skillsDir, 'my-skill');
|
|
517
|
+
await fs.mkdir(installPath, { recursive: true });
|
|
518
|
+
const result = await checkInstallTarget({
|
|
519
|
+
installPath,
|
|
520
|
+
skillsDir,
|
|
521
|
+
manifestEntry: { ...baseEntry(installPath), installPath: './my-skill' },
|
|
522
|
+
force: true,
|
|
523
|
+
});
|
|
524
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_UNTRACKED' });
|
|
525
|
+
});
|
|
526
|
+
});
|
|
527
|
+
// SMI-6529 M5 (reviewer probe-expected-enoent.mjs): `update` sets
|
|
528
|
+
// `expectedInstallPath` to a path that no longer exists on disk — must
|
|
529
|
+
// refuse rather than silently create a brand-new directory there.
|
|
530
|
+
describe('M5: expectedInstallPath no longer exists on disk', () => {
|
|
531
|
+
it('refuses INSTALL_TARGET_MISMATCH when expectedInstallPath is gone', async () => {
|
|
532
|
+
const { skillsDir } = await makeRoot('m5-gone');
|
|
533
|
+
const installPath = path.join(skillsDir, 'foo'); // never created — ENOENT
|
|
534
|
+
const result = await checkInstallTarget({
|
|
535
|
+
installPath,
|
|
536
|
+
skillsDir,
|
|
537
|
+
manifestEntry: { ...baseEntry(installPath), source: 'github:a/foo' },
|
|
538
|
+
force: true,
|
|
539
|
+
expectedInstallPath: installPath,
|
|
540
|
+
});
|
|
541
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_MISMATCH' });
|
|
542
|
+
if (!result.ok) {
|
|
543
|
+
expect(result.error).toContain('no longer exists');
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
// SMI-6529 M8 (reviewer probe-guard.mjs P8): a fresh (ENOENT) computed
|
|
548
|
+
// install path must not silently reuse a manifest key whose recorded entry
|
|
549
|
+
// points at a DIFFERENT, still-live directory.
|
|
550
|
+
describe('M8: stale-vs-live manifest entry on a fresh (ENOENT) install path', () => {
|
|
551
|
+
it('refuses when the manifest entry points elsewhere and that path still exists', async () => {
|
|
552
|
+
const { skillsDir } = await makeRoot('m8-live-elsewhere');
|
|
553
|
+
const installPath = path.join(skillsDir, 'foo'); // ENOENT — fresh computed path
|
|
554
|
+
const elsewhere = path.join(skillsDir, 'foo-elsewhere');
|
|
555
|
+
await fs.mkdir(elsewhere, { recursive: true }); // the OTHER path still exists
|
|
556
|
+
const result = await checkInstallTarget({
|
|
557
|
+
installPath,
|
|
558
|
+
skillsDir,
|
|
559
|
+
manifestEntry: baseEntry(elsewhere),
|
|
560
|
+
force: false,
|
|
561
|
+
});
|
|
562
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_MISMATCH' });
|
|
563
|
+
});
|
|
564
|
+
it('refuses when the manifest entry is marked local, even if its recorded path is gone', async () => {
|
|
565
|
+
const { skillsDir } = await makeRoot('m8-local-gone');
|
|
566
|
+
const installPath = path.join(skillsDir, 'foo'); // ENOENT
|
|
567
|
+
const goneElsewhere = path.join(skillsDir, 'foo-gone'); // never created
|
|
568
|
+
const result = await checkInstallTarget({
|
|
569
|
+
installPath,
|
|
570
|
+
skillsDir,
|
|
571
|
+
manifestEntry: { ...baseEntry(goneElsewhere), provenance: 'local' },
|
|
572
|
+
force: true,
|
|
573
|
+
});
|
|
574
|
+
expect(result).toMatchObject({ ok: false, code: 'INSTALL_TARGET_UNTRACKED' });
|
|
575
|
+
});
|
|
576
|
+
it('proceeds as a fresh install when the manifest entry is genuinely stale (recorded path also gone, not local)', async () => {
|
|
577
|
+
const { skillsDir } = await makeRoot('m8-stale');
|
|
578
|
+
const installPath = path.join(skillsDir, 'foo'); // ENOENT
|
|
579
|
+
const goneElsewhere = path.join(skillsDir, 'foo-gone'); // never created, not local
|
|
580
|
+
const result = await checkInstallTarget({
|
|
581
|
+
installPath,
|
|
582
|
+
skillsDir,
|
|
583
|
+
manifestEntry: baseEntry(goneElsewhere),
|
|
584
|
+
force: false,
|
|
585
|
+
});
|
|
586
|
+
expect(result).toEqual({ ok: true, preExisted: false });
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
//# sourceMappingURL=skill-installation.target-guard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-installation.target-guard.test.js","sourceRoot":"","sources":["../../../../tests/unit/services/skill-installation.target-guard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-installation.uninstall.guard.test.d.ts","sourceRoot":"","sources":["../../../../tests/unit/services/skill-installation.uninstall.guard.test.ts"],"names":[],"mappings":""}
|