@somewhere-tech/cli 0.31.21 → 0.31.22
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/README.md +0 -59
- package/dist/commands/check.js +1 -1
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/index.js +4 -11
- package/dist/index.js.map +1 -1
- package/dist/lib/init-install.js +12 -15
- package/dist/lib/init-install.js.map +1 -1
- package/dist/lib/notify/index.js +5 -8
- package/dist/lib/notify/index.js.map +1 -1
- package/dist/lib/temp-auth.js +1 -1
- package/npm-shrinkwrap.json +3 -5
- package/package.json +2 -4
- package/bin/swpm.js +0 -9
- package/bin/swpx.js +0 -9
- package/dist/commands/swpx.js +0 -43
- package/dist/commands/swpx.js.map +0 -1
- package/dist/lib/notify/providers/advisory.js +0 -30
- package/dist/lib/notify/providers/advisory.js.map +0 -1
- package/dist/swpm-bin.js +0 -11
- package/dist/swpm-bin.js.map +0 -1
- package/dist/swpx/check.js +0 -80
- package/dist/swpx/check.js.map +0 -1
- package/dist/swpx/enforce.js +0 -57
- package/dist/swpx/enforce.js.map +0 -1
- package/dist/swpx/registry.js +0 -68
- package/dist/swpx/registry.js.map +0 -1
- package/dist/swpx/render.js +0 -363
- package/dist/swpx/render.js.map +0 -1
- package/dist/swpx/run-common.js +0 -24
- package/dist/swpx/run-common.js.map +0 -1
- package/dist/swpx/run-swpm.js +0 -163
- package/dist/swpx/run-swpm.js.map +0 -1
- package/dist/swpx/run-swpx.js +0 -102
- package/dist/swpx/run-swpx.js.map +0 -1
- package/dist/swpx/spawn.js +0 -30
- package/dist/swpx/spawn.js.map +0 -1
- package/dist/swpx/tree.js +0 -101
- package/dist/swpx/tree.js.map +0 -1
- package/dist/swpx/types.js +0 -14
- package/dist/swpx/types.js.map +0 -1
- package/dist/swpx/verdict-client.js +0 -165
- package/dist/swpx/verdict-client.js.map +0 -1
- package/dist/swpx-bin.js +0 -20
- package/dist/swpx-bin.js.map +0 -1
package/dist/swpx/run-swpm.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/** `swpm <args...>` — the verdict gate in front of `npm`.
|
|
2
|
-
*
|
|
3
|
-
* Only install-family subcommands are gated (install/i/add/ci); everything else
|
|
4
|
-
* (run, test, publish, …) passes straight through to npm untouched. For an
|
|
5
|
-
* install we batch-check the resolved tree and print the summary, then:
|
|
6
|
-
* - any BLOCKED package → stop, exit 1, don't install.
|
|
7
|
-
* - otherwise → run the real npm install (unverified rows warn but
|
|
8
|
-
* don't gate every install).
|
|
9
|
-
* Couldn't verify (unreachable / unresolvable tree) → LOUD warning then fall
|
|
10
|
-
* back to npm, OR refuse under enforce. Summary goes to stderr; npm owns stdout. */
|
|
11
|
-
import { parseSpec } from './registry.js';
|
|
12
|
-
import { renderTree } from './render.js';
|
|
13
|
-
import { bindDeps } from './run-common.js';
|
|
14
|
-
import { dim, yellow } from '../lib/output.js';
|
|
15
|
-
import { resolveEnforce, stripEnforceFlags, loudUnavailable, refused } from './enforce.js';
|
|
16
|
-
import { VerdictUnavailable } from './verdict-client.js';
|
|
17
|
-
/** npm's own install aliases (including its built-in typo aliases). */
|
|
18
|
-
const INSTALL_SUBS = new Set(['install', 'i', 'in', 'ins', 'add', 'ci', 'isntall']);
|
|
19
|
-
function alignVerdicts(toCheck, verdicts) {
|
|
20
|
-
const byKey = new Map(verdicts.map((v) => [`${v.package}@${v.version}`, v]));
|
|
21
|
-
// A row the service didn't return is "unknown" → surfaced as unverified, never
|
|
22
|
-
// silently counted as verified.
|
|
23
|
-
return toCheck.map((t) => byKey.get(`${t.package}@${t.version}`) ?? {
|
|
24
|
-
package: t.package,
|
|
25
|
-
version: t.version,
|
|
26
|
-
verdict: 'unverified',
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
export async function runSwpm(args, deps = {}) {
|
|
30
|
-
const d = bindDeps(deps);
|
|
31
|
-
const enforce = deps.enforce ?? resolveEnforce(args);
|
|
32
|
-
const clean = stripEnforceFlags(args);
|
|
33
|
-
// npm accepts config flags (and a `--` terminator) BEFORE the subcommand, so the
|
|
34
|
-
// command is the first non-flag token, not necessarily clean[0]. Keying off
|
|
35
|
-
// clean[0] let `swpm -g install evil` / `swpm -- install evil` skip the gate
|
|
36
|
-
// silently. (Residual: a value-flag whose value precedes the sub, e.g.
|
|
37
|
-
// `swpm --prefix /x install`, can still hide it — needs npm's flag schema.)
|
|
38
|
-
const subIdx = clean.findIndex((a) => !a.startsWith('-'));
|
|
39
|
-
const sub = subIdx === -1 ? undefined : clean[subIdx];
|
|
40
|
-
if (!sub || !INSTALL_SUBS.has(sub)) {
|
|
41
|
-
return { exitCode: await d.runReal('npm', clean), action: 'passthrough' };
|
|
42
|
-
}
|
|
43
|
-
// Couldn't verify the tree → LOUD, then fall back (default) or refuse (enforce).
|
|
44
|
-
const failOpen = async (rateLimited, cause, timedOut = false) => {
|
|
45
|
-
if (timedOut) {
|
|
46
|
-
d.errLog(`${yellow('⚠')} verdict pending — proceeding with npm install without waiting for a result.`);
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
loudUnavailable(d.errLog, 'this install', rateLimited, cause);
|
|
50
|
-
}
|
|
51
|
-
if (enforce) {
|
|
52
|
-
refused(d.errLog, 'this install', 'npm');
|
|
53
|
-
return { exitCode: 1, action: 'blocked' };
|
|
54
|
-
}
|
|
55
|
-
return { exitCode: await d.runReal('npm', clean), action: 'fallback' };
|
|
56
|
-
};
|
|
57
|
-
const causeOf = (err) => (err instanceof Error ? err.message : String(err));
|
|
58
|
-
const explicit = clean.slice(subIdx + 1).filter((a) => !a.startsWith('-'));
|
|
59
|
-
let toCheck = [];
|
|
60
|
-
let directCount = 0;
|
|
61
|
-
const directPackageNames = new Set();
|
|
62
|
-
try {
|
|
63
|
-
if (explicit.length) {
|
|
64
|
-
toCheck = await Promise.all(explicit.map(async (a) => {
|
|
65
|
-
const s = parseSpec(a);
|
|
66
|
-
return { package: s.name, version: await d.resolveVersion(s.name, s.version) };
|
|
67
|
-
}));
|
|
68
|
-
directCount = toCheck.length;
|
|
69
|
-
for (const pkg of toCheck)
|
|
70
|
-
directPackageNames.add(pkg.package);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
const tree = d.readTree(process.cwd());
|
|
74
|
-
for (const name of tree.directNames)
|
|
75
|
-
directPackageNames.add(name);
|
|
76
|
-
if (tree.locked.length) {
|
|
77
|
-
toCheck = tree.locked;
|
|
78
|
-
const directSet = new Set(tree.directNames);
|
|
79
|
-
directCount = tree.locked.filter((l) => directSet.has(l.package)).length;
|
|
80
|
-
// A dep added to package.json AFTER the lockfile was written isn't in
|
|
81
|
-
// `locked`, but `npm install` will add it — resolve + check those too, or
|
|
82
|
-
// they'd install unchecked behind a clean "N verified" summary.
|
|
83
|
-
const lockedNames = new Set(tree.locked.map((l) => l.package));
|
|
84
|
-
const missing = tree.directNames.filter((n) => !lockedNames.has(n));
|
|
85
|
-
if (missing.length) {
|
|
86
|
-
const extra = await Promise.all(missing.map(async (name) => ({
|
|
87
|
-
package: name,
|
|
88
|
-
version: await d.resolveVersion(name, tree.ranges[name]),
|
|
89
|
-
})));
|
|
90
|
-
toCheck = [...toCheck, ...extra];
|
|
91
|
-
directCount += extra.length;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
else if (tree.directNames.length) {
|
|
95
|
-
toCheck = await Promise.all(tree.directNames.map(async (name) => ({
|
|
96
|
-
package: name,
|
|
97
|
-
version: await d.resolveVersion(name, tree.ranges[name]),
|
|
98
|
-
})));
|
|
99
|
-
directCount = toCheck.length;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
d.errLog(dim('swpm: no dependencies found in package.json — running npm'));
|
|
103
|
-
return { exitCode: await d.runReal('npm', clean), action: 'passthrough' };
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
catch (err) {
|
|
108
|
-
return failOpen(false, causeOf(err));
|
|
109
|
-
}
|
|
110
|
-
let verdicts;
|
|
111
|
-
try {
|
|
112
|
-
verdicts = await d.getVerdictBatch(toCheck);
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
return failOpen(err instanceof VerdictUnavailable && err.rateLimited, causeOf(err), err instanceof VerdictUnavailable && err.timedOut);
|
|
116
|
-
}
|
|
117
|
-
const aligned = alignVerdicts(toCheck, verdicts);
|
|
118
|
-
const pendingIndexes = aligned
|
|
119
|
-
.map((verdict, index) => ({ verdict, index }))
|
|
120
|
-
.filter(({ verdict }) => directPackageNames.has(verdict.package)
|
|
121
|
-
&& verdict.verdict !== 'blocked'
|
|
122
|
-
&& !verdict.summary?.trim())
|
|
123
|
-
.map(({ index }) => index);
|
|
124
|
-
const resolvedSummaryKeys = new Set();
|
|
125
|
-
if (pendingIndexes.length > 0) {
|
|
126
|
-
d.errLog(dim('Generating LLM summary…'));
|
|
127
|
-
const refreshed = await Promise.all(pendingIndexes.map(async (index) => {
|
|
128
|
-
const verdict = aligned[index];
|
|
129
|
-
try {
|
|
130
|
-
return await d.pollVerdictSummary(verdict.package, verdict.version);
|
|
131
|
-
}
|
|
132
|
-
catch {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
}));
|
|
136
|
-
let unresolved = 0;
|
|
137
|
-
refreshed.forEach((verdict, resultIndex) => {
|
|
138
|
-
const alignedIndex = pendingIndexes[resultIndex];
|
|
139
|
-
if (verdict?.summary?.trim()) {
|
|
140
|
-
aligned[alignedIndex] = verdict;
|
|
141
|
-
resolvedSummaryKeys.add(`${verdict.package}@${verdict.version}`);
|
|
142
|
-
}
|
|
143
|
-
else
|
|
144
|
-
unresolved++;
|
|
145
|
-
});
|
|
146
|
-
if (unresolved > 0) {
|
|
147
|
-
d.errLog(dim(unresolved === 1
|
|
148
|
-
? 'LLM summary timed out — continuing with raw verdict metadata.'
|
|
149
|
-
: `LLM summaries timed out for ${unresolved} packages — continuing with raw verdict metadata.`));
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
for (const l of renderTree(aligned, directCount, resolvedSummaryKeys))
|
|
153
|
-
d.errLog(l);
|
|
154
|
-
// Halt on a hard block OR any level we don't recognize as installable. Known
|
|
155
|
-
// installable levels warn but proceed (unverified/suspicious); an unrecognized
|
|
156
|
-
// or future-harsher level (e.g. "quarantined") must NOT install behind a warn.
|
|
157
|
-
const INSTALLABLE = new Set(['verified', 'unverified', 'suspicious']);
|
|
158
|
-
if (aligned.some((v) => !INSTALLABLE.has(v.verdict))) {
|
|
159
|
-
return { exitCode: 1, action: 'blocked' };
|
|
160
|
-
}
|
|
161
|
-
return { exitCode: await d.runReal('npm', clean), action: 'ran' };
|
|
162
|
-
}
|
|
163
|
-
//# sourceMappingURL=run-swpm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-swpm.js","sourceRoot":"","sources":["../../src/swpx/run-swpm.ts"],"names":[],"mappings":"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"}
|
package/dist/swpx/run-swpx.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/** `swpx <package> [args...]` — the verdict gate in front of `npx`.
|
|
2
|
-
*
|
|
3
|
-
* resolve → verdict → act:
|
|
4
|
-
* verified → print the green one-liner, delegate to real npx.
|
|
5
|
-
* unverified/suspicious → print the evidence block, STOP (exit 1). The user's
|
|
6
|
-
* documented override is to run `npx` directly, per
|
|
7
|
-
* the landing page ("your choice, not ours") — so we
|
|
8
|
-
* deliberately do not prompt or take a --yes flag
|
|
9
|
-
* (which would also collide with npx -y).
|
|
10
|
-
* blocked → print the red block, hard refuse (exit 1, no run).
|
|
11
|
-
* can't resolve / verdict unreachable → fall back to npx unchecked. We are a
|
|
12
|
-
* gate, not a wall: our outage must not stop the user.
|
|
13
|
-
*
|
|
14
|
-
* All verdict messaging goes to STDERR so swpx is transparent on stdout — the
|
|
15
|
-
* executed program owns stdout. */
|
|
16
|
-
import { parseSpec } from './registry.js';
|
|
17
|
-
import { decide, renderVerdict } from './render.js';
|
|
18
|
-
import { bindDeps } from './run-common.js';
|
|
19
|
-
import { resolveEnforce, stripEnforceFlags, loudUnavailable, refused } from './enforce.js';
|
|
20
|
-
import { VerdictUnavailable } from './verdict-client.js';
|
|
21
|
-
import { dim } from '../lib/output.js';
|
|
22
|
-
/** The value of npx's -p/--package flag, in either `--package X` / `-p X` or
|
|
23
|
-
* `--package=X` form — the package npx actually installs. Returns the first such
|
|
24
|
-
* value (multiple -p flags are rare; noted as a residual). null if absent. */
|
|
25
|
-
function packageFlagValue(args) {
|
|
26
|
-
for (let i = 0; i < args.length; i++) {
|
|
27
|
-
const a = args[i];
|
|
28
|
-
if (a === '--package' || a === '-p')
|
|
29
|
-
return args[i + 1] ?? null;
|
|
30
|
-
if (a.startsWith('--package='))
|
|
31
|
-
return a.slice('--package='.length);
|
|
32
|
-
if (a.startsWith('-p='))
|
|
33
|
-
return a.slice('-p='.length);
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
export async function runSwpx(args, deps = {}) {
|
|
38
|
-
const d = bindDeps(deps);
|
|
39
|
-
const enforce = deps.enforce ?? resolveEnforce(args);
|
|
40
|
-
const passthrough = stripEnforceFlags(args);
|
|
41
|
-
// npx's -p/--package names the package that actually gets installed and run; the
|
|
42
|
-
// positional is just the binary to invoke from it (`npx -p typescript tsc`). So
|
|
43
|
-
// grade the --package value when present — otherwise `swpx --package=evil helper`
|
|
44
|
-
// would grade `helper`, print a green "verified", and let npx fetch+run `evil`.
|
|
45
|
-
// Falls back to the first non-flag arg (so `swpx -y create-next-app` still works).
|
|
46
|
-
const pkgArg = packageFlagValue(passthrough) ?? passthrough.find((a) => !a.startsWith('-'));
|
|
47
|
-
if (!pkgArg) {
|
|
48
|
-
d.errLog('Usage: swpx <package> [args...]');
|
|
49
|
-
return { exitCode: 1, action: 'stopped' };
|
|
50
|
-
}
|
|
51
|
-
const spec = parseSpec(pkgArg);
|
|
52
|
-
// Couldn't verify → LOUD warning (never silent), then fall back (default) OR
|
|
53
|
-
// refuse (enforce / fail-closed).
|
|
54
|
-
const failOpen = async (rateLimited, cause) => {
|
|
55
|
-
loudUnavailable(d.errLog, spec.name, rateLimited, cause);
|
|
56
|
-
if (enforce) {
|
|
57
|
-
refused(d.errLog, spec.name, 'npx');
|
|
58
|
-
return { exitCode: 1, action: 'blocked' };
|
|
59
|
-
}
|
|
60
|
-
return { exitCode: await d.runReal('npx', passthrough), action: 'fallback' };
|
|
61
|
-
};
|
|
62
|
-
const causeOf = (err) => (err instanceof Error ? err.message : String(err));
|
|
63
|
-
let version;
|
|
64
|
-
try {
|
|
65
|
-
version = await d.resolveVersion(spec.name, spec.version);
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
return failOpen(false, causeOf(err));
|
|
69
|
-
}
|
|
70
|
-
let verdict;
|
|
71
|
-
try {
|
|
72
|
-
verdict = await d.getVerdict(spec.name, version);
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
return failOpen(err instanceof VerdictUnavailable && err.rateLimited, causeOf(err));
|
|
76
|
-
}
|
|
77
|
-
if (verdict.verdict !== 'blocked' && !verdict.summary?.trim()) {
|
|
78
|
-
d.errLog(dim('Generating LLM summary…'));
|
|
79
|
-
let enriched = null;
|
|
80
|
-
try {
|
|
81
|
-
enriched = await d.pollVerdictSummary(spec.name, version);
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
// Summary generation is presentation-only. Keep the mechanical verdict.
|
|
85
|
-
}
|
|
86
|
-
if (enriched?.summary?.trim()) {
|
|
87
|
-
verdict = enriched;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
d.errLog(dim('LLM summary timed out — continuing with raw verdict metadata.'));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
const action = decide(verdict);
|
|
94
|
-
for (const l of renderVerdict(verdict))
|
|
95
|
-
d.errLog(l);
|
|
96
|
-
if (action === 'run') {
|
|
97
|
-
return { exitCode: await d.runReal('npx', passthrough), action: 'ran' };
|
|
98
|
-
}
|
|
99
|
-
// unverified/suspicious and blocked both stop swpx; only the exit reason differs.
|
|
100
|
-
return { exitCode: 1, action: action === 'block' ? 'blocked' : 'stopped' };
|
|
101
|
-
}
|
|
102
|
-
//# sourceMappingURL=run-swpx.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-swpx.js","sourceRoot":"","sources":["../../src/swpx/run-swpx.ts"],"names":[],"mappings":"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"}
|
package/dist/swpx/spawn.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/** Shell out to the REAL npx / npm. swpx/swpm are wrappers, never replacements:
|
|
2
|
-
* once a verdict says "go", the genuine tool runs with the user's exact args,
|
|
3
|
-
* inheriting stdio so its output is untouched (we keep our own messaging on
|
|
4
|
-
* stderr). The child's exit code becomes ours. A launch failure (tool not on
|
|
5
|
-
* PATH) resolves to 127 rather than throwing — the caller already printed the
|
|
6
|
-
* verdict; a missing npm is the user's environment, not a swpx error. */
|
|
7
|
-
import { spawn } from 'node:child_process';
|
|
8
|
-
import { dim } from '../lib/output.js';
|
|
9
|
-
export function runReal(cmd, args) {
|
|
10
|
-
// SWPX_DRY_RUN: show the decision + what WOULD run, without executing. Useful
|
|
11
|
-
// for "what would swpx do?" and for testing the gate end-to-end offline.
|
|
12
|
-
if (process.env.SWPX_DRY_RUN) {
|
|
13
|
-
console.error(dim(`swpx: [dry-run] would run: ${cmd} ${args.join(' ')}`));
|
|
14
|
-
return Promise.resolve(0);
|
|
15
|
-
}
|
|
16
|
-
return new Promise((resolve) => {
|
|
17
|
-
const child = spawn(cmd, args, {
|
|
18
|
-
stdio: 'inherit',
|
|
19
|
-
// On Windows npx/npm are .cmd shims that need a shell; on POSIX we spawn
|
|
20
|
-
// the binary directly (no shell → no quoting/injection surface).
|
|
21
|
-
shell: process.platform === 'win32',
|
|
22
|
-
});
|
|
23
|
-
child.on('error', (err) => {
|
|
24
|
-
console.error(dim(`swpx: failed to launch ${cmd} — ${err.message}`));
|
|
25
|
-
resolve(127);
|
|
26
|
-
});
|
|
27
|
-
child.on('exit', (code, signal) => resolve(signal ? 1 : code ?? 0));
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=spawn.js.map
|
package/dist/swpx/spawn.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/swpx/spawn.ts"],"names":[],"mappings":"AAAA;;;;;0EAK0E;AAE1E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,MAAM,UAAU,OAAO,CAAC,GAAkB,EAAE,IAAc;IACxD,8EAA8E;IAC9E,yEAAyE;IACzE,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1E,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;YAC7B,KAAK,EAAE,SAAS;YAChB,yEAAyE;YACzE,iEAAiE;YACjE,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SACpC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/swpx/tree.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/** Resolve a project's dependency tree for `swpm install`.
|
|
2
|
-
*
|
|
3
|
-
* When a lockfile is present it IS the resolved tree — the exact versions npm
|
|
4
|
-
* would install — so we read it directly (no registry round-trips, no guessing
|
|
5
|
-
* ranges). Without a lockfile we fall back to the direct deps in package.json
|
|
6
|
-
* and let the caller resolve their ranges. Parsing is split from fs reads so
|
|
7
|
-
* the lockfile/manifest parsers are unit-tested against fixture strings. */
|
|
8
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
9
|
-
import { join } from 'node:path';
|
|
10
|
-
export function parsePackageJsonDeps(pkgJson) {
|
|
11
|
-
let obj;
|
|
12
|
-
try {
|
|
13
|
-
obj = JSON.parse(pkgJson);
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return { directNames: [], ranges: {} };
|
|
17
|
-
}
|
|
18
|
-
const ranges = {};
|
|
19
|
-
const o = obj;
|
|
20
|
-
for (const field of ['dependencies', 'devDependencies', 'optionalDependencies']) {
|
|
21
|
-
const d = o?.[field];
|
|
22
|
-
if (d && typeof d === 'object') {
|
|
23
|
-
for (const [k, v] of Object.entries(d)) {
|
|
24
|
-
if (typeof v === 'string')
|
|
25
|
-
ranges[k] = v;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return { directNames: Object.keys(ranges), ranges };
|
|
30
|
-
}
|
|
31
|
-
/** Extract every concrete package@version from a package-lock.json /
|
|
32
|
-
* npm-shrinkwrap.json string. Handles lockfile v2/v3 (`packages` keyed by
|
|
33
|
-
* node_modules paths) and the older v1 (`dependencies` tree). Deduped. */
|
|
34
|
-
export function parseLockfile(lock) {
|
|
35
|
-
let obj;
|
|
36
|
-
try {
|
|
37
|
-
obj = JSON.parse(lock);
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
const out = [];
|
|
43
|
-
const seen = new Set();
|
|
44
|
-
const add = (name, version) => {
|
|
45
|
-
if (!name || typeof version !== 'string')
|
|
46
|
-
return;
|
|
47
|
-
const id = `${name}@${version}`;
|
|
48
|
-
if (seen.has(id))
|
|
49
|
-
return;
|
|
50
|
-
seen.add(id);
|
|
51
|
-
out.push({ package: name, version });
|
|
52
|
-
};
|
|
53
|
-
const packages = obj.packages;
|
|
54
|
-
if (packages && typeof packages === 'object') {
|
|
55
|
-
for (const [key, val] of Object.entries(packages)) {
|
|
56
|
-
if (!key)
|
|
57
|
-
continue; // "" is the root project
|
|
58
|
-
const idx = key.lastIndexOf('node_modules/');
|
|
59
|
-
if (idx === -1)
|
|
60
|
-
continue;
|
|
61
|
-
if (val?.link)
|
|
62
|
-
continue; // workspace symlink, not a real install
|
|
63
|
-
add(key.slice(idx + 'node_modules/'.length), val?.version);
|
|
64
|
-
}
|
|
65
|
-
return out;
|
|
66
|
-
}
|
|
67
|
-
// lockfile v1: recursive `dependencies` tree.
|
|
68
|
-
const walk = (deps) => {
|
|
69
|
-
if (!deps || typeof deps !== 'object')
|
|
70
|
-
return;
|
|
71
|
-
for (const [name, info] of Object.entries(deps)) {
|
|
72
|
-
add(name, info?.version);
|
|
73
|
-
walk(info?.dependencies);
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
walk(obj.dependencies);
|
|
77
|
-
return out;
|
|
78
|
-
}
|
|
79
|
-
/** Read package.json + the first lockfile we find in `dir`. Missing files yield
|
|
80
|
-
* an empty-ish tree rather than throwing — the caller decides what to do with
|
|
81
|
-
* no deps. */
|
|
82
|
-
export function readTree(dir) {
|
|
83
|
-
let directNames = [];
|
|
84
|
-
let ranges = {};
|
|
85
|
-
const pkgPath = join(dir, 'package.json');
|
|
86
|
-
if (existsSync(pkgPath)) {
|
|
87
|
-
const parsed = parsePackageJsonDeps(readFileSync(pkgPath, 'utf-8'));
|
|
88
|
-
directNames = parsed.directNames;
|
|
89
|
-
ranges = parsed.ranges;
|
|
90
|
-
}
|
|
91
|
-
let locked = [];
|
|
92
|
-
for (const lockName of ['package-lock.json', 'npm-shrinkwrap.json']) {
|
|
93
|
-
const lockPath = join(dir, lockName);
|
|
94
|
-
if (existsSync(lockPath)) {
|
|
95
|
-
locked = parseLockfile(readFileSync(lockPath, 'utf-8'));
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return { directNames, ranges, locked };
|
|
100
|
-
}
|
|
101
|
-
//# sourceMappingURL=tree.js.map
|
package/dist/swpx/tree.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/swpx/tree.ts"],"names":[],"mappings":"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"}
|
package/dist/swpx/types.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/** Shared types for the swpx / swpm verdict layer.
|
|
2
|
-
*
|
|
3
|
-
* The verdict API lives on the `npm` platform project (npm.somewhere.tech),
|
|
4
|
-
* NOT the /v1 control plane. It is unauthenticated (free, no login) — the CLI
|
|
5
|
-
* hits it with a plain fetch, independent of `somewhere login`. See
|
|
6
|
-
* verdict-client.ts.
|
|
7
|
-
*
|
|
8
|
-
* The `Verdict` shape mirrors the D1 `verdicts` row (tsk_f30faf55) plus the
|
|
9
|
-
* live MAL advisory check, which is NOT cached (a version can be retroactively
|
|
10
|
-
* flagged). The `--json` output is a stable PROJECTION of this (toJsonVerdict)
|
|
11
|
-
* — that projection is the public contract shown on npm.somewhere.tech, so it
|
|
12
|
-
* is intentionally narrower than the internal row. */
|
|
13
|
-
export {};
|
|
14
|
-
//# sourceMappingURL=types.js.map
|
package/dist/swpx/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/swpx/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;uDAWuD"}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/** Client for the verdict API hosted on the `npm` platform project.
|
|
2
|
-
*
|
|
3
|
-
* This is NOT the /v1 control plane and NOT the runner — it's the public,
|
|
4
|
-
* unauthenticated verdict service at npm.somewhere.tech (FAQ: "Free, no
|
|
5
|
-
* login"). So this client deliberately does not touch ApiClient or the stored
|
|
6
|
-
* developer key. Override the host for staging/tests via SWPX_VERDICT_URL.
|
|
7
|
-
*
|
|
8
|
-
* Reachability is a product guarantee, inverted: if the verdict API is down,
|
|
9
|
-
* the user must still get normal npm behaviour ("a gate, not a wall"). So every
|
|
10
|
-
* failure here raises VerdictUnavailable and the command layer falls back to
|
|
11
|
-
* the real npx/npm. We never block on our own outage. */
|
|
12
|
-
const VERDICT_BASE = process.env.SWPX_VERDICT_URL?.replace(/\/$/, '') || 'https://npm.somewhere.tech';
|
|
13
|
-
/** Budget for one verdict lookup. It sits in front of every `npx`, so it must
|
|
14
|
-
* fail to fallback rather than stall — but 4s was too tight for the COLD path
|
|
15
|
-
* (fresh DNS/TLS from the client + a cold worker + a first-time uncached compute),
|
|
16
|
-
* which spuriously tripped the fail-open banner on the very first call while every
|
|
17
|
-
* warm call after was instant. 15s comfortably covers a cold uncached lookup;
|
|
18
|
-
* override with SWPX_VERDICT_TIMEOUT_MS (e.g. lower it for strict fail-fast in CI). */
|
|
19
|
-
export const verdictTimeoutMs = Number(process.env.SWPX_VERDICT_TIMEOUT_MS) || 15_000;
|
|
20
|
-
/** Summary generation is best-effort, but a missing narrative must never leave
|
|
21
|
-
* the user staring at a blank decision screen forever. Keep one overall budget
|
|
22
|
-
* across every enrich poll; env overrides make staging and tests tunable. */
|
|
23
|
-
const SUMMARY_POLL_TIMEOUT_MS = Number(process.env.SWPX_SUMMARY_TIMEOUT_MS) || 20_000;
|
|
24
|
-
const SUMMARY_POLL_INTERVAL_MS = Number(process.env.SWPX_SUMMARY_POLL_INTERVAL_MS) || 1_500;
|
|
25
|
-
const defaultFetch = (url, init) => fetch(url, init);
|
|
26
|
-
/** Raised whenever the verdict couldn't be obtained — network error, timeout,
|
|
27
|
-
* non-2xx, or unparseable body. The command layer treats it as "fall back to
|
|
28
|
-
* the real tool", never as "block". */
|
|
29
|
-
export class VerdictUnavailable extends Error {
|
|
30
|
-
/** True when the service answered 429 — a throttle, not an outage/tampering. */
|
|
31
|
-
rateLimited;
|
|
32
|
-
/** True when the client deadline elapsed before the service answered. */
|
|
33
|
-
timedOut;
|
|
34
|
-
constructor(message, rateLimited = false, timedOut = false) {
|
|
35
|
-
super(message);
|
|
36
|
-
this.name = 'VerdictUnavailable';
|
|
37
|
-
this.rateLimited = rateLimited;
|
|
38
|
-
this.timedOut = timedOut;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/** Accept either a bare verdict object or a `{ ok, data }` envelope. */
|
|
42
|
-
function unwrap(body) {
|
|
43
|
-
if (body && typeof body === 'object' && 'ok' in body) {
|
|
44
|
-
const env = body;
|
|
45
|
-
if (env.ok === true)
|
|
46
|
-
return env.data;
|
|
47
|
-
throw new VerdictUnavailable(env.message || env.error || 'verdict API returned ok:false');
|
|
48
|
-
}
|
|
49
|
-
return body;
|
|
50
|
-
}
|
|
51
|
-
function timeoutSignal(timeoutMs = verdictTimeoutMs) {
|
|
52
|
-
try {
|
|
53
|
-
return AbortSignal.timeout(timeoutMs);
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return undefined; // very old runtime — let the request run without our timeout
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async function requestVerdict(name, version, fetchImpl, enrich, timeoutMs = verdictTimeoutMs) {
|
|
60
|
-
const suffix = enrich ? '?enrich=1' : '';
|
|
61
|
-
const url = `${VERDICT_BASE}/api/verdict/${encodeURIComponent(name)}/${encodeURIComponent(version)}${suffix}`;
|
|
62
|
-
let res;
|
|
63
|
-
try {
|
|
64
|
-
res = await fetchImpl(url, {
|
|
65
|
-
headers: {
|
|
66
|
-
Accept: 'application/json',
|
|
67
|
-
...(enrich ? { 'Cache-Control': 'no-cache' } : {}),
|
|
68
|
-
},
|
|
69
|
-
signal: timeoutSignal(timeoutMs),
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
catch (err) {
|
|
73
|
-
const timedOut = err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError');
|
|
74
|
-
throw new VerdictUnavailable(err instanceof Error ? err.message : String(err), false, timedOut);
|
|
75
|
-
}
|
|
76
|
-
if (!res.ok)
|
|
77
|
-
throw new VerdictUnavailable(`verdict API returned ${res.status}`, res.status === 429);
|
|
78
|
-
let body;
|
|
79
|
-
try {
|
|
80
|
-
body = await res.json();
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
throw new VerdictUnavailable('verdict API returned a non-JSON body');
|
|
84
|
-
}
|
|
85
|
-
const v = unwrap(body);
|
|
86
|
-
if (!v || typeof v !== 'object' || typeof v.verdict !== 'string') {
|
|
87
|
-
throw new VerdictUnavailable('verdict API returned an unexpected shape');
|
|
88
|
-
}
|
|
89
|
-
// Trust the caller's resolved coordinates over whatever the row echoes back.
|
|
90
|
-
return { ...v, package: name, version };
|
|
91
|
-
}
|
|
92
|
-
/** Look up one package@version. Throws VerdictUnavailable on any failure. */
|
|
93
|
-
export async function getVerdict(name, version, fetchImpl = defaultFetch) {
|
|
94
|
-
return requestVerdict(name, version, fetchImpl, false);
|
|
95
|
-
}
|
|
96
|
-
/** Ask the verdict backend to enrich a mechanical verdict, then keep polling
|
|
97
|
-
* until its LLM narrative appears or the single overall budget expires.
|
|
98
|
-
* Returns null on timeout/unavailability so callers can continue with the raw
|
|
99
|
-
* verdict and metadata; summary generation never changes fail-open behavior. */
|
|
100
|
-
export async function pollVerdictSummary(name, version, fetchImpl = defaultFetch, options = {}) {
|
|
101
|
-
const timeoutMs = Math.max(1, options.timeoutMs ?? SUMMARY_POLL_TIMEOUT_MS);
|
|
102
|
-
const intervalMs = Math.max(1, options.intervalMs ?? SUMMARY_POLL_INTERVAL_MS);
|
|
103
|
-
const now = options.now ?? Date.now;
|
|
104
|
-
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
105
|
-
const deadline = now() + timeoutMs;
|
|
106
|
-
while (now() < deadline) {
|
|
107
|
-
const remaining = Math.max(1, deadline - now());
|
|
108
|
-
try {
|
|
109
|
-
const verdict = await requestVerdict(name, version, fetchImpl, true, Math.min(verdictTimeoutMs, remaining));
|
|
110
|
-
if (typeof verdict.summary === 'string' && verdict.summary.trim())
|
|
111
|
-
return verdict;
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
114
|
-
// A throttle will not clear inside this short budget. Other transient
|
|
115
|
-
// failures get another attempt, still bounded by the same deadline.
|
|
116
|
-
if (err instanceof VerdictUnavailable && err.rateLimited)
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
const waitMs = Math.min(intervalMs, Math.max(0, deadline - now()));
|
|
120
|
-
if (waitMs > 0)
|
|
121
|
-
await sleep(waitMs);
|
|
122
|
-
}
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
/** Batch-check a resolved tree. Throws VerdictUnavailable on any failure so the
|
|
126
|
-
* caller can fall back to a plain `npm install`. The returned array is aligned
|
|
127
|
-
* to the input order; any row the service omits is dropped (caller treats a
|
|
128
|
-
* missing row as "unknown", not "verified"). */
|
|
129
|
-
export async function getVerdictBatch(pkgs, fetchImpl = defaultFetch) {
|
|
130
|
-
if (pkgs.length === 0)
|
|
131
|
-
return [];
|
|
132
|
-
const url = `${VERDICT_BASE}/api/verdict/batch`;
|
|
133
|
-
let res;
|
|
134
|
-
try {
|
|
135
|
-
res = await fetchImpl(url, {
|
|
136
|
-
method: 'POST',
|
|
137
|
-
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
138
|
-
body: JSON.stringify({ packages: pkgs }),
|
|
139
|
-
signal: timeoutSignal(),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
catch (err) {
|
|
143
|
-
const timedOut = err instanceof Error && (err.name === 'TimeoutError' || err.name === 'AbortError');
|
|
144
|
-
throw new VerdictUnavailable(err instanceof Error ? err.message : String(err), false, timedOut);
|
|
145
|
-
}
|
|
146
|
-
if (!res.ok)
|
|
147
|
-
throw new VerdictUnavailable(`verdict API returned ${res.status}`, res.status === 429);
|
|
148
|
-
let body;
|
|
149
|
-
try {
|
|
150
|
-
body = await res.json();
|
|
151
|
-
}
|
|
152
|
-
catch {
|
|
153
|
-
throw new VerdictUnavailable('verdict API returned a non-JSON body');
|
|
154
|
-
}
|
|
155
|
-
const data = unwrap(body);
|
|
156
|
-
const results = Array.isArray(data)
|
|
157
|
-
? data
|
|
158
|
-
: data?.results;
|
|
159
|
-
if (!Array.isArray(results)) {
|
|
160
|
-
throw new VerdictUnavailable('verdict API batch returned an unexpected shape');
|
|
161
|
-
}
|
|
162
|
-
return results.filter((v) => !!v && typeof v === 'object' && typeof v.verdict === 'string');
|
|
163
|
-
}
|
|
164
|
-
export const verdictBaseUrl = VERDICT_BASE;
|
|
165
|
-
//# sourceMappingURL=verdict-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"verdict-client.js","sourceRoot":"","sources":["../../src/swpx/verdict-client.ts"],"names":[],"mappings":"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"}
|