@vordsec/cli 0.1.0
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/LICENSE +661 -0
- package/README.md +33 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +86 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/explain.d.ts +20 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +61 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/guard.d.ts +41 -0
- package/dist/commands/guard.d.ts.map +1 -0
- package/dist/commands/guard.js +106 -0
- package/dist/commands/guard.js.map +1 -0
- package/dist/commands/hook.d.ts +66 -0
- package/dist/commands/hook.d.ts.map +1 -0
- package/dist/commands/hook.js +127 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/ignore.d.ts +40 -0
- package/dist/commands/ignore.d.ts.map +1 -0
- package/dist/commands/ignore.js +159 -0
- package/dist/commands/ignore.js.map +1 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +75 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install-gate.d.ts +19 -0
- package/dist/commands/install-gate.d.ts.map +1 -0
- package/dist/commands/install-gate.js +118 -0
- package/dist/commands/install-gate.js.map +1 -0
- package/dist/commands/mcp.d.ts +53 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +155 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/scan.d.ts +21 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +77 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/exit-codes.d.ts +38 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +40 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/report/gate.d.ts +41 -0
- package/dist/report/gate.d.ts.map +1 -0
- package/dist/report/gate.js +111 -0
- package/dist/report/gate.js.map +1 -0
- package/dist/report/scan.d.ts +34 -0
- package/dist/report/scan.d.ts.map +1 -0
- package/dist/report/scan.js +170 -0
- package/dist/report/scan.js.map +1 -0
- package/dist/shim/artifacts.d.ts +54 -0
- package/dist/shim/artifacts.d.ts.map +1 -0
- package/dist/shim/artifacts.js +114 -0
- package/dist/shim/artifacts.js.map +1 -0
- package/dist/shim/decide.d.ts +68 -0
- package/dist/shim/decide.d.ts.map +1 -0
- package/dist/shim/decide.js +62 -0
- package/dist/shim/decide.js.map +1 -0
- package/dist/shim/install.d.ts +76 -0
- package/dist/shim/install.d.ts.map +1 -0
- package/dist/shim/install.js +174 -0
- package/dist/shim/install.js.map +1 -0
- package/dist/shim/log.d.ts +52 -0
- package/dist/shim/log.d.ts.map +1 -0
- package/dist/shim/log.js +78 -0
- package/dist/shim/log.js.map +1 -0
- package/dist/shim/run.d.ts +37 -0
- package/dist/shim/run.d.ts.map +1 -0
- package/dist/shim/run.js +100 -0
- package/dist/shim/run.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { SEVERITY, skipSummary } from '@vordsec/core';
|
|
2
|
+
const at = (f) => where(f.location);
|
|
3
|
+
/**
|
|
4
|
+
* `경로:줄`. **확인 불가도 같은 형식으로 쓴다** — 취약과 톤은 다르지만
|
|
5
|
+
* *"어디를 봐야 하는가"* 는 똑같이 필요하다 (B-10 실측: 없으면 사용자가
|
|
6
|
+
* `howToCheck` 문장을 끝까지 읽어야 파일 이름을 안다).
|
|
7
|
+
*/
|
|
8
|
+
const where = (loc) => loc === undefined ? '' : `${loc.path}${loc.line === undefined ? '' : `:${loc.line}`}`;
|
|
9
|
+
const label = (s) => `${SEVERITY[s].label}(LV${SEVERITY[s].lv})`;
|
|
10
|
+
const ORDER = ['CRITICAL', 'DANGER', 'CAUTION', 'POTENTIAL', 'POTENTIAL_LOW'];
|
|
11
|
+
function bySeverity(a, b) {
|
|
12
|
+
const d = ORDER.indexOf(a.severity) - ORDER.indexOf(b.severity);
|
|
13
|
+
return d !== 0 ? d : (at(a) < at(b) ? -1 : 1);
|
|
14
|
+
}
|
|
15
|
+
// ────────────────────────────────── pretty
|
|
16
|
+
export function renderPretty(out) {
|
|
17
|
+
const { report } = out;
|
|
18
|
+
const lines = [];
|
|
19
|
+
const findings = [...report.findings].sort(bySeverity);
|
|
20
|
+
for (const f of findings) {
|
|
21
|
+
lines.push(`${f.cross === undefined ? '✗' : '↳'} ${f.rule} ${label(f.severity)} ${at(f)}`);
|
|
22
|
+
lines.push(` ${f.message}`);
|
|
23
|
+
if (f.fix !== undefined && f.fix !== '')
|
|
24
|
+
lines.push(` 고치는 법: ${f.fix}`);
|
|
25
|
+
lines.push('');
|
|
26
|
+
}
|
|
27
|
+
if (report.unknowns.length > 0) {
|
|
28
|
+
// **문구를 취약과 분리한다** — 판정 못 함이 아니라 "코드 밖에 근거가 있다" 다
|
|
29
|
+
lines.push('확인 불가 — 코드만으로는 판정되지 않는다. 위험하다는 뜻이 아니다.');
|
|
30
|
+
for (const u of report.unknowns) {
|
|
31
|
+
// 자리가 있으면 **먼저** 보인다. 근거가 코드 밖이면(대시보드·콘솔) 없는 것이 맞다
|
|
32
|
+
const spot = where(u.location);
|
|
33
|
+
lines.push(` ? ${u.rule} ${spot === '' ? '' : `${spot} `}${u.reason}`);
|
|
34
|
+
lines.push(` 확인 방법: ${u.howToCheck}`);
|
|
35
|
+
}
|
|
36
|
+
lines.push('');
|
|
37
|
+
}
|
|
38
|
+
if (report.notApplicable.length > 0) {
|
|
39
|
+
lines.push(`해당 없음: ${report.notApplicable.join(' · ')} (판정할 것이 없다)`);
|
|
40
|
+
}
|
|
41
|
+
const skips = skipSummary(report.skipped);
|
|
42
|
+
const skipped = Object.entries(skips).filter(([, n]) => n > 0);
|
|
43
|
+
if (skipped.length > 0) {
|
|
44
|
+
// 계약 4 — **반드시 표시한다**
|
|
45
|
+
lines.push(`건너뜀: ${skipped.map(([k, n]) => `${k} ${n}`).join(' · ')}`);
|
|
46
|
+
}
|
|
47
|
+
if (out.suppressed.length > 0) {
|
|
48
|
+
lines.push(`무시 규칙으로 뺀 것: ${out.suppressed.length}건 (\`vord ignore list\` 로 확인)`);
|
|
49
|
+
}
|
|
50
|
+
if (report.failures.length > 0) {
|
|
51
|
+
lines.push(`룰 오류: ${report.failures.map((f) => `${f.rule}(${f.error})`).join(' · ')}`);
|
|
52
|
+
}
|
|
53
|
+
const counts = findings.length === 0
|
|
54
|
+
? '취약 0건'
|
|
55
|
+
: `취약 ${findings.length}건`;
|
|
56
|
+
lines.push(`${counts} · 확인 불가 ${report.unknowns.length}건 — ${out.root}`);
|
|
57
|
+
return lines;
|
|
58
|
+
}
|
|
59
|
+
// ────────────────────────────────── json
|
|
60
|
+
export function renderJson(out) {
|
|
61
|
+
const { report } = out;
|
|
62
|
+
return [JSON.stringify({
|
|
63
|
+
root: out.root,
|
|
64
|
+
findings: report.findings.map((f) => ({
|
|
65
|
+
rule: f.rule,
|
|
66
|
+
severity: f.severity,
|
|
67
|
+
lv: SEVERITY[f.severity].lv,
|
|
68
|
+
path: f.location.path,
|
|
69
|
+
line: f.location.line,
|
|
70
|
+
message: f.message,
|
|
71
|
+
fix: f.fix,
|
|
72
|
+
flags: f.flags ?? [],
|
|
73
|
+
cross: f.cross ?? [],
|
|
74
|
+
})),
|
|
75
|
+
unknowns: report.unknowns.map((u) => ({
|
|
76
|
+
rule: u.rule,
|
|
77
|
+
// **기계용 출력에도 자리를 싣는다** — 없으면 소비자가 문장을 파싱해야 한다
|
|
78
|
+
path: u.location?.path ?? null,
|
|
79
|
+
line: u.location?.line ?? null,
|
|
80
|
+
reason: u.reason,
|
|
81
|
+
howToCheck: u.howToCheck,
|
|
82
|
+
flags: u.flags ?? [],
|
|
83
|
+
})),
|
|
84
|
+
notApplicable: report.notApplicable,
|
|
85
|
+
suppressed: out.suppressed.map((f) => ({ rule: f.rule, path: f.location.path })),
|
|
86
|
+
skipped: skipSummary(report.skipped),
|
|
87
|
+
failures: report.failures,
|
|
88
|
+
})];
|
|
89
|
+
}
|
|
90
|
+
// ────────────────────────────────── sarif
|
|
91
|
+
/** SARIF 는 세 등급뿐이다. LV1·2 → error · LV3 → warning · 그 아래 → note */
|
|
92
|
+
function sarifLevel(s) {
|
|
93
|
+
if (s === 'CRITICAL' || s === 'DANGER')
|
|
94
|
+
return 'error';
|
|
95
|
+
if (s === 'CAUTION')
|
|
96
|
+
return 'warning';
|
|
97
|
+
return 'note';
|
|
98
|
+
}
|
|
99
|
+
const location = (path, line) => ({
|
|
100
|
+
physicalLocation: {
|
|
101
|
+
artifactLocation: { uri: path },
|
|
102
|
+
...(line === undefined ? {} : { region: { startLine: line } }),
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* SARIF 2.1.0. GitHub code scanning 이 읽는 형식이다.
|
|
107
|
+
*
|
|
108
|
+
* **확인 불가도 싣는다** — `note` 등급에 `vord.verdict: unknown` 을 붙인다.
|
|
109
|
+
* 안 실으면 "검사했는데 아무것도 없었다" 와 구분이 안 된다.
|
|
110
|
+
*/
|
|
111
|
+
export function renderSarif(out, version = '0.0.0') {
|
|
112
|
+
const { report } = out;
|
|
113
|
+
const ruleIds = [...new Set([
|
|
114
|
+
...report.findings.map((f) => f.rule),
|
|
115
|
+
...report.unknowns.map((u) => u.rule),
|
|
116
|
+
])].sort();
|
|
117
|
+
const results = [
|
|
118
|
+
...report.findings.map((f) => ({
|
|
119
|
+
ruleId: f.rule,
|
|
120
|
+
level: sarifLevel(f.severity),
|
|
121
|
+
message: { text: f.fix === undefined ? f.message : `${f.message}\n\n고치는 법: ${f.fix}` },
|
|
122
|
+
locations: [location(f.location.path, f.location.line)],
|
|
123
|
+
properties: {
|
|
124
|
+
'vord.severity': f.severity,
|
|
125
|
+
'vord.lv': SEVERITY[f.severity].lv,
|
|
126
|
+
'vord.flags': f.flags ?? [],
|
|
127
|
+
...(f.cross === undefined ? {} : { 'vord.cross': f.cross }),
|
|
128
|
+
},
|
|
129
|
+
})),
|
|
130
|
+
...report.unknowns.map((u) => ({
|
|
131
|
+
ruleId: u.rule,
|
|
132
|
+
level: 'note',
|
|
133
|
+
message: { text: `확인 불가 — ${u.reason}\n\n확인 방법: ${u.howToCheck}` },
|
|
134
|
+
// **자리가 있으면 그 파일에 붙인다.** 예전엔 전부 `.` 로 나가 code scanning 에서
|
|
135
|
+
// 확인 불가가 통째로 레포 루트에 뭉쳤다 — 삼항의 양쪽이 같은 값이었다 (B-10)
|
|
136
|
+
locations: [u.location === undefined
|
|
137
|
+
? location('.')
|
|
138
|
+
: location(u.location.path, u.location.line)],
|
|
139
|
+
properties: { 'vord.verdict': 'unknown', 'vord.flags': u.flags ?? [] },
|
|
140
|
+
})),
|
|
141
|
+
];
|
|
142
|
+
return [JSON.stringify({
|
|
143
|
+
$schema: 'https://json.schemastore.org/sarif-2.1.0.json',
|
|
144
|
+
version: '2.1.0',
|
|
145
|
+
runs: [{
|
|
146
|
+
tool: {
|
|
147
|
+
driver: {
|
|
148
|
+
name: 'Vord',
|
|
149
|
+
version,
|
|
150
|
+
informationUri: 'https://github.com/createrman343212/Vord',
|
|
151
|
+
rules: ruleIds.map((id) => ({ id, name: id })),
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
results,
|
|
155
|
+
invocations: [{
|
|
156
|
+
executionSuccessful: report.failures.length === 0,
|
|
157
|
+
// 계약 4 — 건너뛴 파일은 리포트에 남는다
|
|
158
|
+
properties: { 'vord.skipped': skipSummary(report.skipped) },
|
|
159
|
+
}],
|
|
160
|
+
}],
|
|
161
|
+
})];
|
|
162
|
+
}
|
|
163
|
+
export function renderScan(out, format, version) {
|
|
164
|
+
if (format === 'json')
|
|
165
|
+
return renderJson(out);
|
|
166
|
+
if (format === 'sarif')
|
|
167
|
+
return renderSarif(out, version);
|
|
168
|
+
return renderPretty(out);
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/report/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PATH shim 아티팩트 생성 — ADR-026.
|
|
3
|
+
*
|
|
4
|
+
* **확장자별로 파일이 따로 필요하고, 없으면 조용히 통과한다.**
|
|
5
|
+
* 실측에서 `npm` 만 두고 `node -e "execSync('npm install axios')"` 를 돌리니
|
|
6
|
+
* `added 27 packages` 가 그대로 나왔다. Node 의 `execSync` 는 Windows 에서 cmd.exe 를 쓰고
|
|
7
|
+
* cmd.exe 는 `PATHEXT` 로 해석하기 때문이다. `npm.cmd` 를 넣으니 걸렸다.
|
|
8
|
+
* **게이트가 조용히 통과시키는 실패 모드**라 가장 위험하다 — 사용자는 켜 뒀다고 믿는다.
|
|
9
|
+
*
|
|
10
|
+
* 순수 함수다. 파일을 쓰지 않는다 — 내용만 만든다.
|
|
11
|
+
*
|
|
12
|
+
* **모든 래퍼는 자기가 못 뜨면 원본으로 넘긴다.** 깨진 shim 을 넣고 재보니 종료코드 127 로
|
|
13
|
+
* npm 이 전부 죽었다. 그건 fail-closed 가 아니라 **툴체인 브릭**이고, 브릭을 겪은 사용자는
|
|
14
|
+
* shim 을 지운다 — 영구 우회가 된다.
|
|
15
|
+
*/
|
|
16
|
+
/** Phase 1 대상. 데이터셋 기준 JS 레포 71개 중 70개(99%)가 이 둘이다 */
|
|
17
|
+
export declare const SHIM_MANAGERS: readonly ["npm", "pnpm"];
|
|
18
|
+
export type ShimManager = typeof SHIM_MANAGERS[number];
|
|
19
|
+
/** 확장자별 3종. 하나라도 빠지면 그 경로가 조용히 통과한다 */
|
|
20
|
+
export declare const SHIM_EXTENSIONS: readonly ["", ".cmd", ".ps1"];
|
|
21
|
+
export type ShimExtension = typeof SHIM_EXTENSIONS[number];
|
|
22
|
+
/** 런타임 진입점. 세 래퍼가 전부 이 파일 하나로 모인다 — 로직이 갈리면 안 된다 */
|
|
23
|
+
export declare const RUNTIME_FILENAME = "vord-shim.mjs";
|
|
24
|
+
export interface ShimTarget {
|
|
25
|
+
readonly manager: ShimManager;
|
|
26
|
+
readonly extension: ShimExtension;
|
|
27
|
+
/** 원본 실행 파일의 절대 경로. **설치 시점에 박아 둔다** */
|
|
28
|
+
readonly realPath: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ShimArtifact {
|
|
31
|
+
/** shim 디렉터리 안의 파일 이름 */
|
|
32
|
+
readonly filename: string;
|
|
33
|
+
readonly contents: string;
|
|
34
|
+
/** POSIX 에서 실행 비트를 세워야 하는가 */
|
|
35
|
+
readonly executable: boolean;
|
|
36
|
+
}
|
|
37
|
+
/** 셸 문자열 안에 그대로 넣어도 되는 경로인지. 따옴표·개행이 섞이면 거부한다 */
|
|
38
|
+
export declare function isSafePath(p: string): boolean;
|
|
39
|
+
export declare class UnsafePathError extends Error {
|
|
40
|
+
readonly which: string;
|
|
41
|
+
constructor(which: string);
|
|
42
|
+
}
|
|
43
|
+
/** 아티팩트 하나를 만든다 */
|
|
44
|
+
export declare function buildArtifact(target: ShimTarget, runtimePath: string): ShimArtifact;
|
|
45
|
+
/**
|
|
46
|
+
* 대상 전체의 아티팩트를 만든다.
|
|
47
|
+
*
|
|
48
|
+
* **6개가 나와야 한다** (매니저 2 × 확장자 3). 하나라도 빠지면 그 실행 경로가
|
|
49
|
+
* 조용히 통과하고, 사용자는 게이트가 켜져 있다고 믿는다.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildArtifacts(targets: readonly ShimTarget[], runtimePath: string): readonly ShimArtifact[];
|
|
52
|
+
/** 설치돼야 하는 파일 이름 전체 — 검증이 이 목록과 실제를 대조한다 */
|
|
53
|
+
export declare function expectedFilenames(managers?: readonly ShimManager[]): readonly string[];
|
|
54
|
+
//# sourceMappingURL=artifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/shim/artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,sDAAsD;AACtD,eAAO,MAAM,aAAa,0BAA2B,CAAC;AACtD,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAEvD,uCAAuC;AACvC,eAAO,MAAM,eAAe,+BAAgC,CAAC;AAC7D,MAAM,MAAM,aAAa,GAAG,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AAE3D,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE7C;AAED,qBAAa,eAAgB,SAAQ,KAAK;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;CAInC;AAkDD,mBAAmB;AACnB,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY,CAgBnF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,WAAW,EAAE,MAAM,GAClB,SAAS,YAAY,EAAE,CAEzB;AAED,4CAA4C;AAC5C,wBAAgB,iBAAiB,CAC/B,QAAQ,GAAE,SAAS,WAAW,EAAkB,GAC/C,SAAS,MAAM,EAAE,CAInB"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PATH shim 아티팩트 생성 — ADR-026.
|
|
3
|
+
*
|
|
4
|
+
* **확장자별로 파일이 따로 필요하고, 없으면 조용히 통과한다.**
|
|
5
|
+
* 실측에서 `npm` 만 두고 `node -e "execSync('npm install axios')"` 를 돌리니
|
|
6
|
+
* `added 27 packages` 가 그대로 나왔다. Node 의 `execSync` 는 Windows 에서 cmd.exe 를 쓰고
|
|
7
|
+
* cmd.exe 는 `PATHEXT` 로 해석하기 때문이다. `npm.cmd` 를 넣으니 걸렸다.
|
|
8
|
+
* **게이트가 조용히 통과시키는 실패 모드**라 가장 위험하다 — 사용자는 켜 뒀다고 믿는다.
|
|
9
|
+
*
|
|
10
|
+
* 순수 함수다. 파일을 쓰지 않는다 — 내용만 만든다.
|
|
11
|
+
*
|
|
12
|
+
* **모든 래퍼는 자기가 못 뜨면 원본으로 넘긴다.** 깨진 shim 을 넣고 재보니 종료코드 127 로
|
|
13
|
+
* npm 이 전부 죽었다. 그건 fail-closed 가 아니라 **툴체인 브릭**이고, 브릭을 겪은 사용자는
|
|
14
|
+
* shim 을 지운다 — 영구 우회가 된다.
|
|
15
|
+
*/
|
|
16
|
+
/** Phase 1 대상. 데이터셋 기준 JS 레포 71개 중 70개(99%)가 이 둘이다 */
|
|
17
|
+
export const SHIM_MANAGERS = ['npm', 'pnpm'];
|
|
18
|
+
/** 확장자별 3종. 하나라도 빠지면 그 경로가 조용히 통과한다 */
|
|
19
|
+
export const SHIM_EXTENSIONS = ['', '.cmd', '.ps1'];
|
|
20
|
+
/** 런타임 진입점. 세 래퍼가 전부 이 파일 하나로 모인다 — 로직이 갈리면 안 된다 */
|
|
21
|
+
export const RUNTIME_FILENAME = 'vord-shim.mjs';
|
|
22
|
+
/** 셸 문자열 안에 그대로 넣어도 되는 경로인지. 따옴표·개행이 섞이면 거부한다 */
|
|
23
|
+
export function isSafePath(p) {
|
|
24
|
+
return p.length > 0 && p.length < 4096 && !/["'`\r\n$%!^&|<>]/.test(p);
|
|
25
|
+
}
|
|
26
|
+
export class UnsafePathError extends Error {
|
|
27
|
+
which;
|
|
28
|
+
constructor(which) {
|
|
29
|
+
super(`${which} 경로에 셸에서 위험한 문자가 있다 — shim 을 만들지 않는다`);
|
|
30
|
+
this.which = which;
|
|
31
|
+
this.name = 'UnsafePathError';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function posixWrapper(m, real, runtime) {
|
|
35
|
+
return `#!/bin/sh
|
|
36
|
+
# vord 설치 경계 shim (ADR-026). \`vord install-gate --shell --remove\` 로 지운다.
|
|
37
|
+
# 이 파일을 직접 고치지 않는다 — 재설치하면 덮어쓴다.
|
|
38
|
+
VORD_REAL='${real}'
|
|
39
|
+
VORD_RUNTIME='${runtime}'
|
|
40
|
+
|
|
41
|
+
# 런타임을 못 띄우면 원본으로 넘긴다. 툴체인을 죽이지 않는 것이 먼저다.
|
|
42
|
+
if command -v node >/dev/null 2>&1 && [ -f "$VORD_RUNTIME" ]; then
|
|
43
|
+
exec node "$VORD_RUNTIME" ${m} "$VORD_REAL" "$@"
|
|
44
|
+
fi
|
|
45
|
+
exec "$VORD_REAL" "$@"
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
function cmdWrapper(m, real, runtime) {
|
|
49
|
+
// `%*` 는 인자를 원문 그대로 넘긴다. 재조립하면 따옴표가 깨진다.
|
|
50
|
+
return `@echo off
|
|
51
|
+
rem vord 설치 경계 shim (ADR-026). vord install-gate --shell --remove 로 지운다.
|
|
52
|
+
setlocal
|
|
53
|
+
set "VORD_REAL=${real}"
|
|
54
|
+
set "VORD_RUNTIME=${runtime}"
|
|
55
|
+
where node >nul 2>nul || goto vord_passthrough
|
|
56
|
+
if not exist "%VORD_RUNTIME%" goto vord_passthrough
|
|
57
|
+
node "%VORD_RUNTIME%" ${m} "%VORD_REAL%" %*
|
|
58
|
+
exit /b %errorlevel%
|
|
59
|
+
:vord_passthrough
|
|
60
|
+
"%VORD_REAL%" %*
|
|
61
|
+
exit /b %errorlevel%
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
function ps1Wrapper(m, real, runtime) {
|
|
65
|
+
return `# vord 설치 경계 shim (ADR-026). vord install-gate --shell --remove 로 지운다.
|
|
66
|
+
$VordReal = '${real}'
|
|
67
|
+
$VordRuntime = '${runtime}'
|
|
68
|
+
|
|
69
|
+
$node = Get-Command node -ErrorAction SilentlyContinue
|
|
70
|
+
if ($node -and (Test-Path $VordRuntime)) {
|
|
71
|
+
& node $VordRuntime ${m} $VordReal @args
|
|
72
|
+
exit $LASTEXITCODE
|
|
73
|
+
}
|
|
74
|
+
# 런타임을 못 띄우면 원본으로 넘긴다 — 툴체인을 죽이지 않는다
|
|
75
|
+
& $VordReal @args
|
|
76
|
+
exit $LASTEXITCODE
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
/** 아티팩트 하나를 만든다 */
|
|
80
|
+
export function buildArtifact(target, runtimePath) {
|
|
81
|
+
if (!isSafePath(target.realPath))
|
|
82
|
+
throw new UnsafePathError('원본');
|
|
83
|
+
if (!isSafePath(runtimePath))
|
|
84
|
+
throw new UnsafePathError('런타임');
|
|
85
|
+
const { manager, extension, realPath } = target;
|
|
86
|
+
const contents = extension === '.cmd'
|
|
87
|
+
? cmdWrapper(manager, realPath, runtimePath)
|
|
88
|
+
: extension === '.ps1'
|
|
89
|
+
? ps1Wrapper(manager, realPath, runtimePath)
|
|
90
|
+
: posixWrapper(manager, realPath, runtimePath);
|
|
91
|
+
return {
|
|
92
|
+
filename: `${manager}${extension}`,
|
|
93
|
+
contents,
|
|
94
|
+
executable: extension === '',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 대상 전체의 아티팩트를 만든다.
|
|
99
|
+
*
|
|
100
|
+
* **6개가 나와야 한다** (매니저 2 × 확장자 3). 하나라도 빠지면 그 실행 경로가
|
|
101
|
+
* 조용히 통과하고, 사용자는 게이트가 켜져 있다고 믿는다.
|
|
102
|
+
*/
|
|
103
|
+
export function buildArtifacts(targets, runtimePath) {
|
|
104
|
+
return targets.map((t) => buildArtifact(t, runtimePath));
|
|
105
|
+
}
|
|
106
|
+
/** 설치돼야 하는 파일 이름 전체 — 검증이 이 목록과 실제를 대조한다 */
|
|
107
|
+
export function expectedFilenames(managers = SHIM_MANAGERS) {
|
|
108
|
+
const out = [];
|
|
109
|
+
for (const m of managers)
|
|
110
|
+
for (const e of SHIM_EXTENSIONS)
|
|
111
|
+
out.push(`${m}${e}`);
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/shim/artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,sDAAsD;AACtD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,CAAU,CAAC;AAGtD,uCAAuC;AACvC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAG7D,oDAAoD;AACpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC;AAiBhD,iDAAiD;AACjD,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACnB;IAArB,YAAqB,KAAa;QAChC,KAAK,CAAC,GAAG,KAAK,sCAAsC,CAAC,CAAC;QADnC,UAAK,GAAL,KAAK,CAAQ;QAEhC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,SAAS,YAAY,CAAC,CAAc,EAAE,IAAY,EAAE,OAAe;IACjE,OAAO;;;aAGI,IAAI;gBACD,OAAO;;;;8BAIO,CAAC;;;CAG9B,CAAC;AACF,CAAC;AAED,SAAS,UAAU,CAAC,CAAc,EAAE,IAAY,EAAE,OAAe;IAC/D,yCAAyC;IACzC,OAAO;;;iBAGQ,IAAI;oBACD,OAAO;;;wBAGH,CAAC;;;;;CAKxB,CAAC;AACF,CAAC;AAED,SAAS,UAAU,CAAC,CAAc,EAAE,IAAY,EAAE,OAAe;IAC/D,OAAO;eACM,IAAI;kBACD,OAAO;;;;wBAID,CAAC;;;;;;CAMxB,CAAC;AACF,CAAC;AAED,mBAAmB;AACnB,MAAM,UAAU,aAAa,CAAC,MAAkB,EAAE,WAAmB;IACnE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;IAClE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;IAE/D,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAChD,MAAM,QAAQ,GAAG,SAAS,KAAK,MAAM;QACnC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC;QAC5C,CAAC,CAAC,SAAS,KAAK,MAAM;YACpB,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC;YAC5C,CAAC,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEnD,OAAO;QACL,QAAQ,EAAE,GAAG,OAAO,GAAG,SAAS,EAAE;QAClC,QAAQ;QACR,UAAU,EAAE,SAAS,KAAK,EAAE;KAC7B,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,OAA8B,EAC9B,WAAmB;IAEnB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,iBAAiB,CAC/B,WAAmC,aAAa;IAEhD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,KAAK,MAAM,CAAC,IAAI,eAAe;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* shim 이 무엇을 할지 정한다 — **순수 함수** (ADR-026 · ADR-017).
|
|
3
|
+
*
|
|
4
|
+
* 프로세스를 띄우지도 파일을 읽지도 않는다. 게이트 결과와 크래시 여부만 받아
|
|
5
|
+
* "원본을 실행할 것인가" 를 낸다. 그래야 픽스처만으로 시험할 수 있다.
|
|
6
|
+
*
|
|
7
|
+
* ## 실패 종류를 셋으로 가른다
|
|
8
|
+
*
|
|
9
|
+
* ADR-026 이 드러낸 것이 이것이다. ADR-017 은 **레지스트리 조회 실패** 하나만 정했다.
|
|
10
|
+
*
|
|
11
|
+
* | 실패 | 처리 | 근거 |
|
|
12
|
+
* |------|------|------|
|
|
13
|
+
* | 레지스트리 조회 실패 | **막는다** (확인 불가 등급) | ADR-017 — 실패를 유도하는 것이 곧 우회가 된다 |
|
|
14
|
+
* | shim 런타임을 못 띄움 | **통과** + 기록 | 래퍼가 이미 원본으로 넘긴 뒤다. 브릭을 피한다 |
|
|
15
|
+
* | **게이트 코드가 크래시** | **잠정: 통과 + 기록** | **B-3 미결.** 아래 설명 |
|
|
16
|
+
*
|
|
17
|
+
* ## 크래시 기본값이 왜 통과인가 — 잠정이다
|
|
18
|
+
*
|
|
19
|
+
* ADR-017 의 논리(실패 유도 = 우회)는 크래시에도 적용된다. 그런데 실측에서 깨진 shim 은
|
|
20
|
+
* **종료코드 127 로 npm 을 통째로 죽였다.** 브릭을 겪은 사용자는 shim 을 지우고,
|
|
21
|
+
* 지워진 shim 은 **영구 우회**다 — 한 번의 차단보다 나쁘다.
|
|
22
|
+
*
|
|
23
|
+
* 그리고 B-3 을 정하려면 크래시 빈도와 사유가 필요한데, fail-closed 로 두면
|
|
24
|
+
* 사용자가 shim 을 지워서 **그 데이터가 안 모인다.**
|
|
25
|
+
*
|
|
26
|
+
* **이건 보안 결정이고 사람이 정한다.** 여기서는 뒤집을 수 있는 상수 하나로 두고,
|
|
27
|
+
* 어느 쪽이든 **반드시 기록한다** — 그게 ADR-026 이 고정한 유일한 제약이다.
|
|
28
|
+
*/
|
|
29
|
+
import type { ShimOutcome } from './log.js';
|
|
30
|
+
/** 게이트 판정 요약 — `@vordsec/core` 의 `GateReport` 에서 필요한 것만 옮겨 담는다 */
|
|
31
|
+
export interface GateSummary {
|
|
32
|
+
readonly stop: boolean;
|
|
33
|
+
readonly notApplicable?: string;
|
|
34
|
+
/** 사람에게 보여줄 줄들 */
|
|
35
|
+
readonly lines: readonly string[];
|
|
36
|
+
/** 막은 것 중 "확인 불가" 가 있는가 (ADR-017 등급 3) */
|
|
37
|
+
readonly hasUnverifiable: boolean;
|
|
38
|
+
readonly packages: readonly string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* **B-3 이 정할 자리.** 크래시했을 때 통과시킬 것인가.
|
|
42
|
+
*
|
|
43
|
+
* `true` = 통과(잠정 기본값) · `false` = 막음.
|
|
44
|
+
* B-3 이 확정되면 이 상수를 지우고 별도 ADR 을 만든다 (ADR-026 재검토 조건).
|
|
45
|
+
*/
|
|
46
|
+
export declare const CRASH_PASSES_THROUGH_PROVISIONAL = true;
|
|
47
|
+
export interface DecideInput {
|
|
48
|
+
readonly manager: string;
|
|
49
|
+
/** 게이트가 정상적으로 끝났으면 그 요약 */
|
|
50
|
+
readonly gate?: GateSummary;
|
|
51
|
+
/** 게이트가 예외를 던졌으면 그 사유 */
|
|
52
|
+
readonly crash?: string;
|
|
53
|
+
/** 크래시 시 통과 여부. 테스트가 양쪽을 다 시험한다 */
|
|
54
|
+
readonly crashPassesThrough?: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface Decision {
|
|
57
|
+
/** 원본 매니저를 실행할 것인가 */
|
|
58
|
+
readonly runReal: boolean;
|
|
59
|
+
readonly outcome: ShimOutcome;
|
|
60
|
+
/** stderr 로 낼 줄들. **에이전트가 읽는다** (ADR-010 §2) */
|
|
61
|
+
readonly stderr: readonly string[];
|
|
62
|
+
/** 막을 때의 종료 코드. 통과면 원본의 코드를 쓴다 */
|
|
63
|
+
readonly exitCode?: number;
|
|
64
|
+
readonly packages: readonly string[];
|
|
65
|
+
readonly detail?: string;
|
|
66
|
+
}
|
|
67
|
+
export declare function decide(input: DecideInput): Decision;
|
|
68
|
+
//# sourceMappingURL=decide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../../src/shim/decide.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,kEAAkE;AAClE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB;IAClB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,yBAAyB;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,QAAQ;IACvB,sBAAsB;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAID,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,QAAQ,CAyDnD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { EXIT } from '../exit-codes.js';
|
|
2
|
+
/**
|
|
3
|
+
* **B-3 이 정할 자리.** 크래시했을 때 통과시킬 것인가.
|
|
4
|
+
*
|
|
5
|
+
* `true` = 통과(잠정 기본값) · `false` = 막음.
|
|
6
|
+
* B-3 이 확정되면 이 상수를 지우고 별도 ADR 을 만든다 (ADR-026 재검토 조건).
|
|
7
|
+
*/
|
|
8
|
+
export const CRASH_PASSES_THROUGH_PROVISIONAL = true;
|
|
9
|
+
const BANNER = 'vord: 설치 경계';
|
|
10
|
+
export function decide(input) {
|
|
11
|
+
const { manager, gate, crash } = input;
|
|
12
|
+
const passOnCrash = input.crashPassesThrough ?? CRASH_PASSES_THROUGH_PROVISIONAL;
|
|
13
|
+
// ── 게이트가 크래시했다. **B-3 이 정할 자리**
|
|
14
|
+
if (crash !== undefined) {
|
|
15
|
+
return passOnCrash
|
|
16
|
+
? {
|
|
17
|
+
runReal: true,
|
|
18
|
+
outcome: 'gate-crash',
|
|
19
|
+
packages: [],
|
|
20
|
+
detail: crash,
|
|
21
|
+
stderr: [
|
|
22
|
+
`${BANNER}: 검사에 실패해 그대로 진행한다 (${crash}).`,
|
|
23
|
+
'이 설치는 검사되지 않았다. `vord install-gate --shell --status` 로 기록을 본다.',
|
|
24
|
+
],
|
|
25
|
+
}
|
|
26
|
+
: {
|
|
27
|
+
runReal: false,
|
|
28
|
+
outcome: 'gate-crash',
|
|
29
|
+
// 크래시는 "위험하다" 가 아니라 "판단하지 못했다" 다 — 확인 불가 쪽이다
|
|
30
|
+
exitCode: EXIT.UNVERIFIABLE,
|
|
31
|
+
packages: [],
|
|
32
|
+
detail: crash,
|
|
33
|
+
stderr: [`${BANNER}: 검사에 실패해 설치를 멈춘다 (${crash}).`],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (gate === undefined) {
|
|
37
|
+
// 게이트도 크래시도 없다 — 호출부의 버그다. 통과시키되 기록한다
|
|
38
|
+
return {
|
|
39
|
+
runReal: true, outcome: 'gate-crash', packages: [], detail: '판정 결과 없음',
|
|
40
|
+
stderr: [`${BANNER}: 판정 결과가 없어 그대로 진행한다.`],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (gate.notApplicable !== undefined) {
|
|
44
|
+
return { runReal: true, outcome: 'not-applicable', packages: [], stderr: [] };
|
|
45
|
+
}
|
|
46
|
+
if (!gate.stop) {
|
|
47
|
+
return { runReal: true, outcome: 'passed', packages: gate.packages, stderr: [] };
|
|
48
|
+
}
|
|
49
|
+
// ── 막는다. **"위험함" 과 "모름" 을 다른 말로 낸다** (ADR-017 장치 3)
|
|
50
|
+
const head = gate.hasUnverifiable
|
|
51
|
+
? `${BANNER}: 확인하지 못해 설치를 멈췄다. 위험해서 막은 것이 아니다.`
|
|
52
|
+
: `${BANNER}: 설치를 막았다.`;
|
|
53
|
+
return {
|
|
54
|
+
runReal: false,
|
|
55
|
+
outcome: gate.hasUnverifiable ? 'unverifiable' : 'blocked',
|
|
56
|
+
// **차단과 확인 불가를 종료 코드에서도 가른다.** CI 는 메시지를 안 읽고 코드만 본다
|
|
57
|
+
exitCode: gate.hasUnverifiable ? EXIT.UNVERIFIABLE : EXIT.BLOCKED,
|
|
58
|
+
packages: gate.packages,
|
|
59
|
+
stderr: [head, ...gate.lines, `(${manager} 명령은 실행되지 않았다)`],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=decide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decide.js","sourceRoot":"","sources":["../../src/shim/decide.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAaxC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAC;AAwBrD,MAAM,MAAM,GAAG,aAAa,CAAC;AAE7B,MAAM,UAAU,MAAM,CAAC,KAAkB;IACvC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACvC,MAAM,WAAW,GAAG,KAAK,CAAC,kBAAkB,IAAI,gCAAgC,CAAC;IAEjF,iCAAiC;IACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,WAAW;YAChB,CAAC,CAAC;gBACA,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,YAAY;gBACrB,QAAQ,EAAE,EAAE;gBACZ,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE;oBACN,GAAG,MAAM,uBAAuB,KAAK,IAAI;oBACzC,gEAAgE;iBACjE;aACF;YACD,CAAC,CAAC;gBACA,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,YAAY;gBACrB,6CAA6C;gBAC7C,QAAQ,EAAE,IAAI,CAAC,YAAY;gBAC3B,QAAQ,EAAE,EAAE;gBACZ,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,CAAC,GAAG,MAAM,sBAAsB,KAAK,IAAI,CAAC;aACnD,CAAC;IACN,CAAC;IAED,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,sCAAsC;QACtC,OAAO;YACL,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU;YACtE,MAAM,EAAE,CAAC,GAAG,MAAM,uBAAuB,CAAC;SAC3C,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAChF,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACnF,CAAC;IAED,qDAAqD;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe;QAC/B,CAAC,CAAC,GAAG,MAAM,oCAAoC;QAC/C,CAAC,CAAC,GAAG,MAAM,YAAY,CAAC;IAE1B,OAAO;QACL,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS;QAC1D,qDAAqD;QACrD,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO;QACjE,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,OAAO,gBAAgB,CAAC;KAC3D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type ShimExtension, type ShimManager } from './artifacts.js';
|
|
2
|
+
export declare const DEFAULT_SHIM_DIRNAME: string;
|
|
3
|
+
export declare function defaultShimDir(home?: string): string;
|
|
4
|
+
export interface Env {
|
|
5
|
+
readonly PATH: string;
|
|
6
|
+
readonly PATHEXT?: string;
|
|
7
|
+
}
|
|
8
|
+
/** PATH 를 나눈다. 구분자는 플랫폼마다 다르다 */
|
|
9
|
+
export declare function splitPath(pathEnv: string, delimiter?: ";" | ":"): string[];
|
|
10
|
+
/**
|
|
11
|
+
* PATH 에서 **shim 디렉터리를 빼고** 원본을 찾는다.
|
|
12
|
+
*
|
|
13
|
+
* shim 이 이미 깔린 뒤에 다시 설치하면 shim 이 자기 자신을 원본으로 박는다 —
|
|
14
|
+
* 무한 재귀다. 그래서 항상 자기 디렉터리를 빼고 찾는다.
|
|
15
|
+
*/
|
|
16
|
+
export declare function findRealBinary(manager: ShimManager, extension: ShimExtension, env: Env, shimDir: string, exists?: (p: string) => boolean): string | undefined;
|
|
17
|
+
export interface InstallPlanEntry {
|
|
18
|
+
readonly manager: ShimManager;
|
|
19
|
+
readonly extension: ShimExtension;
|
|
20
|
+
readonly realPath?: string;
|
|
21
|
+
/** 원본을 못 찾았다 — 이 경로는 shim 을 만들지 않는다 */
|
|
22
|
+
readonly missing: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface InstallPlan {
|
|
25
|
+
readonly shimDir: string;
|
|
26
|
+
readonly entries: readonly InstallPlanEntry[];
|
|
27
|
+
/**
|
|
28
|
+
* **조용히 통과할 경로가 있는가.** 확장자 하나가 비면 그 실행 경로는 게이트를 지나간다.
|
|
29
|
+
* 사용자가 "켰다" 고 믿는 상태에서 안 걸리는 것이 가장 위험한 실패다.
|
|
30
|
+
*/
|
|
31
|
+
readonly silentGaps: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
export declare function planInstall(env: Env, shimDir: string, managers?: readonly ShimManager[], exists?: (p: string) => boolean): InstallPlan;
|
|
34
|
+
export interface InstallResult {
|
|
35
|
+
readonly shimDir: string;
|
|
36
|
+
readonly written: readonly string[];
|
|
37
|
+
readonly skipped: readonly string[];
|
|
38
|
+
readonly silentGaps: readonly string[];
|
|
39
|
+
/** PATH 에 shim 디렉터리가 **앞쪽에** 있는가 */
|
|
40
|
+
readonly onPath: boolean;
|
|
41
|
+
readonly instructions: readonly string[];
|
|
42
|
+
}
|
|
43
|
+
/** 런타임 진입점 본문. 빌드된 CLI 를 부르는 얇은 파일이다 */
|
|
44
|
+
export declare function runtimeSource(cliRunPath: string): string;
|
|
45
|
+
export declare function install(env: Env, opts: {
|
|
46
|
+
readonly shimDir?: string;
|
|
47
|
+
readonly managers?: readonly ShimManager[];
|
|
48
|
+
readonly cliRunPath: string;
|
|
49
|
+
}): InstallResult;
|
|
50
|
+
/**
|
|
51
|
+
* shim 디렉터리가 PATH 에 있고, **원본보다 앞인가.**
|
|
52
|
+
* 뒤에 있으면 아무것도 안 걸린다 — 있는 것과 없는 것이 같다.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isShimFirst(env: Env, shimDir: string, manager?: ShimManager): boolean;
|
|
55
|
+
export declare function pathInstructions(shimDir: string): readonly string[];
|
|
56
|
+
export interface RemoveResult {
|
|
57
|
+
readonly shimDir: string;
|
|
58
|
+
readonly removed: readonly string[];
|
|
59
|
+
readonly remaining: readonly string[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 우리가 만든 것만 지운다.
|
|
63
|
+
* **사용자가 그 디렉터리에 둔 다른 파일은 건드리지 않는다** — 디렉터리째 지우지 않는다.
|
|
64
|
+
*/
|
|
65
|
+
export declare function remove(shimDir: string): RemoveResult;
|
|
66
|
+
export interface VerifyResult {
|
|
67
|
+
readonly shimDir: string;
|
|
68
|
+
readonly installed: readonly string[];
|
|
69
|
+
/** 있어야 하는데 없는 것. **이게 조용히 통과하는 경로다** */
|
|
70
|
+
readonly missing: readonly string[];
|
|
71
|
+
readonly runtimePresent: boolean;
|
|
72
|
+
readonly onPath: boolean;
|
|
73
|
+
readonly healthy: boolean;
|
|
74
|
+
}
|
|
75
|
+
export declare function verify(env: Env, shimDir: string): VerifyResult;
|
|
76
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/shim/install.ts"],"names":[],"mappings":"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"}
|