@cassiomc1/forgeloop 0.1.14 → 0.1.16

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.
Files changed (61) hide show
  1. package/.forgeloop/forgeloop.gitignore +1 -0
  2. package/DOCS_INDEX.md +60 -0
  3. package/EXECUTION_STATE.md +9 -0
  4. package/LOOP_ENGINEERING.md +44 -6
  5. package/LOOP_SYSTEM_DESIGN.md +8 -0
  6. package/PROTOCOL_INTEGRATION.md +41 -0
  7. package/QUALITY_SCORECARD.md +2 -0
  8. package/README.md +183 -643
  9. package/TERMINOLOGY.md +4 -0
  10. package/THREAT_MODEL.md +14 -0
  11. package/docs/assets/forgeloop-flow.svg +1 -0
  12. package/docs/forgeloop-flow.mmd +51 -0
  13. package/package.json +16 -3
  14. package/schemas/check.schema.json +2 -0
  15. package/schemas/continuity.schema.json +57 -0
  16. package/schemas/execution.schema.json +63 -0
  17. package/scripts/CI_VALIDATORS.md +32 -0
  18. package/src/cli.js +351 -196
  19. package/src/commands/clear-continuity.js +9 -0
  20. package/src/commands/continuity.js +25 -0
  21. package/src/commands/doctor.js +17 -2
  22. package/src/commands/reconcile-continuity.js +23 -0
  23. package/src/commands/record-continuity.js +63 -0
  24. package/src/commands/run-check.js +83 -0
  25. package/src/commands/status.js +14 -1
  26. package/src/commands/update.js +12 -13
  27. package/src/commands/validate-protocol.js +37 -0
  28. package/src/core/artifacts.js +9 -0
  29. package/src/core/bundles.js +78 -0
  30. package/src/core/checks.js +16 -0
  31. package/src/core/command-resolution.js +295 -0
  32. package/src/core/command-tokenizer.js +122 -0
  33. package/src/core/completion-artifacts.js +229 -47
  34. package/src/core/completion.js +19 -1
  35. package/src/core/conformance.js +8 -2
  36. package/src/core/continuity-cli-options.js +58 -0
  37. package/src/core/continuity-conformance.js +46 -0
  38. package/src/core/continuity-observability.js +20 -0
  39. package/src/core/continuity-reconciliation.js +224 -0
  40. package/src/core/continuity.js +245 -0
  41. package/src/core/evidence-readiness.js +26 -1
  42. package/src/core/execution.js +185 -0
  43. package/src/core/inspect.js +9 -1
  44. package/src/core/installation-authority.js +178 -0
  45. package/src/core/json-safety.js +17 -13
  46. package/src/core/next-action-artifacts.js +118 -0
  47. package/src/core/next-action-continuity.js +65 -0
  48. package/src/core/next-action-model.js +127 -0
  49. package/src/core/next-action-phases.js +12 -0
  50. package/src/core/next-action.js +22 -249
  51. package/src/core/npm-classifier.js +343 -0
  52. package/src/core/package-manager-classifiers.js +37 -0
  53. package/src/core/preflight-consistency.js +221 -0
  54. package/src/core/preflight-loaders.js +112 -0
  55. package/src/core/preflight-model.js +83 -0
  56. package/src/core/preflight.js +34 -444
  57. package/src/core/protocol.js +7 -0
  58. package/src/core/schema-validation.js +16 -1
  59. package/src/core/templates.js +3 -0
  60. package/src/core/verification-capability.js +31 -495
  61. package/src/core/verification-constants.js +61 -0
@@ -1,30 +1,41 @@
1
1
  import {
2
- E_AUTHORITY_UNTRUSTED_SOURCE,
3
- resolveTrustedAuthority,
4
- } from "./trusted-authority.js";
5
- import path from "node:path";
2
+ E_INSTALLATION_AUTHORITY_REQUIRED,
3
+ E_VERIFICATION_TOOL_UNAVAILABLE,
4
+ } from "./verification-constants.js";
5
+
6
+ export {
7
+ E_COMMAND_RESOLUTION_AMBIGUOUS,
8
+ E_INSTALLATION_AUTHORITY_REQUIRED,
9
+ E_AUTHORITY_INVALID,
10
+ E_AUTHORITY_SCOPE_MISMATCH,
11
+ E_VERIFICATION_TOOL_UNAVAILABLE,
12
+ RESOLUTION_MODES,
13
+ } from "./verification-constants.js";
14
+ export { E_AUTHORITY_UNTRUSTED_SOURCE } from "./installation-authority.js";
15
+ export {
16
+ classifyCommandResolution,
17
+ resolveExecutionResolution,
18
+ MAX_NPM_SCRIPT_DEPTH,
19
+ } from "./command-resolution.js";
20
+ export {
21
+ classifyNpmInvocation,
22
+ getNpmLifecycleCandidates,
23
+ getNpmScriptName,
24
+ npmWorkspaceSelection,
25
+ parseNpmInvocation,
26
+ parseNpmInvocationArgs,
27
+ } from "./npm-classifier.js";
28
+ export {
29
+ getInstallationAuthorityRef,
30
+ validateAuthorityGrant,
31
+ validateVerificationAuthority,
32
+ } from "./installation-authority.js";
6
33
  export {
7
34
  AUTHORITY_TRUST_MODES,
8
35
  createAuthorityContext,
9
36
  createForgeLoopContext,
10
37
  } from "./runtime-context.js";
11
38
 
12
- export const E_VERIFICATION_TOOL_UNAVAILABLE = "E_VERIFICATION_TOOL_UNAVAILABLE";
13
- export const E_INSTALLATION_AUTHORITY_REQUIRED = "E_INSTALLATION_AUTHORITY_REQUIRED";
14
- export const E_AUTHORITY_INVALID = "E_AUTHORITY_INVALID";
15
- export const E_AUTHORITY_SCOPE_MISMATCH = "E_AUTHORITY_SCOPE_MISMATCH";
16
-
17
- export { E_AUTHORITY_UNTRUSTED_SOURCE };
18
-
19
- export const RESOLUTION_MODES = Object.freeze([
20
- "LOCAL_EXECUTABLE",
21
- "LOCAL_PACKAGE_BINARY",
22
- "NON_INSTALLING_RESOLUTION",
23
- "INSTALL_CAPABLE_RESOLUTION",
24
- "EXPLICIT_INSTALLATION",
25
- "UNKNOWN",
26
- ]);
27
-
28
39
  export function classifyVerificationCapability({
29
40
  available = false,
30
41
  equivalentAvailable = false,
@@ -69,478 +80,3 @@ export function classifyVerificationCapability({
69
80
  message: "Verification tool is absent and installation was not authorized.",
70
81
  };
71
82
  }
72
-
73
- function tokenizeCommand(commandString) {
74
- const tokens = [];
75
- let current = "";
76
- let inSingleQuote = false;
77
- let inDoubleQuote = false;
78
-
79
- for (let i = 0; i < commandString.length; i++) {
80
- const char = commandString[i];
81
-
82
- if (char === "'" && !inDoubleQuote) {
83
- inSingleQuote = !inSingleQuote;
84
- } else if (char === '"' && !inSingleQuote) {
85
- inDoubleQuote = !inDoubleQuote;
86
- } else if (/\s/.test(char) && !inSingleQuote && !inDoubleQuote) {
87
- if (current.length > 0) {
88
- tokens.push(current);
89
- current = "";
90
- }
91
- } else {
92
- current += char;
93
- }
94
- }
95
-
96
- if (current.length > 0) {
97
- tokens.push(current);
98
- }
99
-
100
- return tokens;
101
- }
102
-
103
- function splitCommandPipeline(commandString) {
104
- const parts = [];
105
- let current = "";
106
- let inSingleQuote = false;
107
- let inDoubleQuote = false;
108
-
109
- for (let i = 0; i < commandString.length; i++) {
110
- const char = commandString[i];
111
- const next = commandString[i + 1];
112
-
113
- if (char === "'" && !inDoubleQuote) {
114
- inSingleQuote = !inSingleQuote;
115
- current += char;
116
- } else if (char === '"' && !inSingleQuote) {
117
- inDoubleQuote = !inDoubleQuote;
118
- current += char;
119
- } else if (!inSingleQuote && !inDoubleQuote) {
120
- if ((char === "&" && next === "&") || (char === "|" && next === "|")) {
121
- if (current.trim().length > 0) parts.push(current.trim());
122
- current = "";
123
- i++; // skip next char
124
- } else if (char === ";" || char === "|") {
125
- if (current.trim().length > 0) parts.push(current.trim());
126
- current = "";
127
- } else {
128
- current += char;
129
- }
130
- } else {
131
- current += char;
132
- }
133
- }
134
-
135
- if (current.trim().length > 0) parts.push(current.trim());
136
- return parts.length > 0 ? parts : [commandString];
137
- }
138
-
139
- function extractToolFromArgs(args) {
140
- if (!Array.isArray(args) || args.length === 0) return null;
141
- for (let idx = 0; idx < args.length; idx++) {
142
- const arg = args[idx];
143
- if (arg === "-p" || arg === "--package") {
144
- if (args[idx + 1] && !args[idx + 1].startsWith("-")) {
145
- return args[idx + 1];
146
- }
147
- }
148
- if (arg.startsWith("--package=")) {
149
- return arg.split("=")[1];
150
- }
151
- if (!arg.startsWith("-")) {
152
- return arg;
153
- }
154
- }
155
- return null;
156
- }
157
-
158
- function classifySingleCommand(commandString) {
159
- const tokens = tokenizeCommand(commandString);
160
- if (tokens.length === 0) {
161
- return { resolutionMode: "UNKNOWN", mayInstall: false, installer: null, tool: null };
162
- }
163
-
164
- let i = 0;
165
- while (i < tokens.length && /^[A-Za-z_][A-Za-z0-9_]*=/.test(tokens[i])) {
166
- i++;
167
- }
168
- if (i >= tokens.length) {
169
- return { resolutionMode: "UNKNOWN", mayInstall: false, installer: null, tool: null };
170
- }
171
-
172
- const binaryToken = tokens[i];
173
- const binary = path.basename(binaryToken).toLowerCase();
174
- const rest = tokens.slice(i + 1);
175
-
176
- if (binaryToken.includes("node_modules/.bin/") || binaryToken.startsWith("./node_modules/")) {
177
- return { resolutionMode: "LOCAL_PACKAGE_BINARY", mayInstall: false, installer: null, tool: binary };
178
- }
179
-
180
- // Check npx
181
- if (binary === "npx") {
182
- if (rest.some((arg) => arg === "--no-install" || arg === "--no")) {
183
- const nonInstallArgs = rest.filter((arg) => arg !== "--no-install" && arg !== "--no");
184
- return {
185
- resolutionMode: "NON_INSTALLING_RESOLUTION",
186
- mayInstall: false,
187
- installer: "npx",
188
- tool: extractToolFromArgs(nonInstallArgs),
189
- };
190
- }
191
- return {
192
- resolutionMode: "INSTALL_CAPABLE_RESOLUTION",
193
- mayInstall: true,
194
- installer: "npx",
195
- tool: extractToolFromArgs(rest),
196
- };
197
- }
198
-
199
- // Check pnpx, bunx, uvx
200
- if (binary === "pnpx" || binary === "bunx" || binary === "uvx") {
201
- return {
202
- resolutionMode: "INSTALL_CAPABLE_RESOLUTION",
203
- mayInstall: true,
204
- installer: binary,
205
- tool: extractToolFromArgs(rest),
206
- };
207
- }
208
-
209
- // Check pnpm and yarn
210
- if (binary === "pnpm" || binary === "yarn") {
211
- if (rest[0] === "dlx") {
212
- return {
213
- resolutionMode: "INSTALL_CAPABLE_RESOLUTION",
214
- mayInstall: true,
215
- installer: `${binary} dlx`,
216
- tool: extractToolFromArgs(rest.slice(1)),
217
- };
218
- }
219
- if (["add", "install", "i"].includes(rest[0])) {
220
- return {
221
- resolutionMode: "EXPLICIT_INSTALLATION",
222
- mayInstall: true,
223
- installer: binary,
224
- tool: extractToolFromArgs(rest.slice(1)),
225
- };
226
- }
227
- return { resolutionMode: "LOCAL_PACKAGE_BINARY", mayInstall: false, installer: null, tool: null };
228
- }
229
-
230
- // Check bun
231
- if (binary === "bun") {
232
- if (rest[0] === "x") {
233
- return {
234
- resolutionMode: "INSTALL_CAPABLE_RESOLUTION",
235
- mayInstall: true,
236
- installer: "bun x",
237
- tool: extractToolFromArgs(rest.slice(1)),
238
- };
239
- }
240
- if (["add", "install", "i"].includes(rest[0])) {
241
- return {
242
- resolutionMode: "EXPLICIT_INSTALLATION",
243
- mayInstall: true,
244
- installer: "bun",
245
- tool: extractToolFromArgs(rest.slice(1)),
246
- };
247
- }
248
- return { resolutionMode: "LOCAL_PACKAGE_BINARY", mayInstall: false, installer: null, tool: null };
249
- }
250
-
251
- // Check uv
252
- if (binary === "uv") {
253
- if (rest[0] === "tool" && rest[1] === "run") {
254
- return {
255
- resolutionMode: "INSTALL_CAPABLE_RESOLUTION",
256
- mayInstall: true,
257
- installer: "uv tool run",
258
- tool: extractToolFromArgs(rest.slice(2)),
259
- };
260
- }
261
- if (rest[0] === "pip" && rest[1] === "install") {
262
- return {
263
- resolutionMode: "EXPLICIT_INSTALLATION",
264
- mayInstall: true,
265
- installer: "uv pip install",
266
- tool: extractToolFromArgs(rest.slice(2)),
267
- };
268
- }
269
- if (rest[0] === "add") {
270
- return {
271
- resolutionMode: "EXPLICIT_INSTALLATION",
272
- mayInstall: true,
273
- installer: "uv add",
274
- tool: extractToolFromArgs(rest.slice(1)),
275
- };
276
- }
277
- return { resolutionMode: "LOCAL_EXECUTABLE", mayInstall: false, installer: null, tool: null };
278
- }
279
-
280
- // Check pipx
281
- if (binary === "pipx") {
282
- if (rest[0] === "run") {
283
- return {
284
- resolutionMode: "INSTALL_CAPABLE_RESOLUTION",
285
- mayInstall: true,
286
- installer: "pipx run",
287
- tool: extractToolFromArgs(rest.slice(1)),
288
- };
289
- }
290
- if (rest[0] === "install") {
291
- return {
292
- resolutionMode: "EXPLICIT_INSTALLATION",
293
- mayInstall: true,
294
- installer: "pipx install",
295
- tool: extractToolFromArgs(rest.slice(1)),
296
- };
297
- }
298
- return { resolutionMode: "LOCAL_EXECUTABLE", mayInstall: false, installer: null, tool: null };
299
- }
300
-
301
- // Check npm
302
- if (binary === "npm") {
303
- if (["install", "i", "add"].includes(rest[0])) {
304
- return {
305
- resolutionMode: "EXPLICIT_INSTALLATION",
306
- mayInstall: true,
307
- installer: "npm",
308
- tool: extractToolFromArgs(rest.slice(1)),
309
- };
310
- }
311
- return { resolutionMode: "LOCAL_PACKAGE_BINARY", mayInstall: false, installer: null, tool: null };
312
- }
313
-
314
- // Check python/pip
315
- if (binary === "pip" || binary === "pip3") {
316
- if (rest[0] === "install") {
317
- return {
318
- resolutionMode: "EXPLICIT_INSTALLATION",
319
- mayInstall: true,
320
- installer: binary,
321
- tool: extractToolFromArgs(rest.slice(1)),
322
- };
323
- }
324
- }
325
- if (binary === "python" || binary === "python3") {
326
- if (rest[0] === "-m" && rest[1] === "pip" && rest[2] === "install") {
327
- return {
328
- resolutionMode: "EXPLICIT_INSTALLATION",
329
- mayInstall: true,
330
- installer: `${binary} -m pip install`,
331
- tool: extractToolFromArgs(rest.slice(3)),
332
- };
333
- }
334
- }
335
-
336
- // Check cargo
337
- if (binary === "cargo") {
338
- if (rest[0] === "install" || rest[0] === "binstall") {
339
- return {
340
- resolutionMode: "EXPLICIT_INSTALLATION",
341
- mayInstall: true,
342
- installer: binary,
343
- tool: extractToolFromArgs(rest.slice(1)),
344
- };
345
- }
346
- }
347
-
348
- // System package managers
349
- if (["brew", "apt", "apt-get", "apk", "dnf", "pacman"].includes(binary)) {
350
- if (["install", "add", "-S"].includes(rest[0])) {
351
- return {
352
- resolutionMode: "EXPLICIT_INSTALLATION",
353
- mayInstall: true,
354
- installer: binary,
355
- tool: extractToolFromArgs(rest.slice(1)),
356
- };
357
- }
358
- }
359
-
360
- return { resolutionMode: "LOCAL_EXECUTABLE", mayInstall: false, installer: null, tool: null };
361
- }
362
-
363
- export function classifyCommandResolution(commandString) {
364
- if (typeof commandString !== "string" || commandString.trim() === "") {
365
- return { resolutionMode: "UNKNOWN", mayInstall: false, installer: null, tool: null };
366
- }
367
-
368
- const subcommands = splitCommandPipeline(commandString);
369
- for (const subcommand of subcommands) {
370
- const res = classifySingleCommand(subcommand);
371
- if (res.mayInstall) {
372
- return res;
373
- }
374
- }
375
-
376
- return classifySingleCommand(subcommands[0] || commandString);
377
- }
378
-
379
- export function getInstallationAuthorityRef(check) {
380
- return (
381
- check?.details?.installationAuthorityRef
382
- ?? check?.details?.authorityRef
383
- ?? check?.installationAuthorityRef
384
- ?? check?.authorityRef
385
- ?? null
386
- );
387
- }
388
-
389
- function normalizeToolName(toolName) {
390
- if (typeof toolName !== "string") return "";
391
- if (toolName.startsWith("@")) {
392
- const parts = toolName.slice(1).split("@");
393
- return `@${parts[0]}`;
394
- }
395
- return toolName.split("@")[0];
396
- }
397
-
398
- export function validateAuthorityGrant({ authority, taskId, type = "SOFTWARE_INSTALLATION", tool } = {}) {
399
- if (!authority || typeof authority !== "object") {
400
- return {
401
- valid: false,
402
- error: {
403
- code: E_AUTHORITY_INVALID,
404
- message: "Authority grant artifact is missing or invalid",
405
- },
406
- };
407
- }
408
-
409
- if (authority.schemaVersion !== 1 || authority.protocolVersion !== 1) {
410
- return {
411
- valid: false,
412
- error: {
413
- code: E_AUTHORITY_INVALID,
414
- message: `Authority grant schema version (${authority.schemaVersion}) or protocol version (${authority.protocolVersion}) is invalid`,
415
- },
416
- };
417
- }
418
-
419
- if (authority.type !== type) {
420
- return {
421
- valid: false,
422
- error: {
423
- code: E_AUTHORITY_INVALID,
424
- message: `Authority grant type '${authority.type}' does not match expected '${type}'`,
425
- },
426
- };
427
- }
428
-
429
- if (authority.status !== "AUTHORIZED") {
430
- return {
431
- valid: false,
432
- error: {
433
- code: E_AUTHORITY_INVALID,
434
- message: `Authority grant is not active (status: '${authority.status}')`,
435
- },
436
- };
437
- }
438
-
439
- if (authority.source === "agent-self") {
440
- return {
441
- valid: false,
442
- error: {
443
- code: E_AUTHORITY_INVALID,
444
- message: "Self-asserted authority grants with source 'agent-self' are not permitted",
445
- },
446
- };
447
- }
448
-
449
- if (!["operator", "host", "project-policy"].includes(authority.source)) {
450
- return {
451
- valid: false,
452
- error: {
453
- code: E_AUTHORITY_INVALID,
454
- message: `Authority grant source '${authority.source}' is not recognized`,
455
- },
456
- };
457
- }
458
-
459
- if (taskId && authority.taskId && authority.taskId !== taskId) {
460
- return {
461
- valid: false,
462
- error: {
463
- code: E_AUTHORITY_INVALID,
464
- message: `Authority grant taskId '${authority.taskId}' does not match current task '${taskId}'`,
465
- },
466
- };
467
- }
468
-
469
- if (tool && authority.scope?.tool && authority.scope.tool !== "*") {
470
- const requestedNorm = normalizeToolName(tool);
471
- const scopeNorm = normalizeToolName(authority.scope.tool);
472
- const exactMatch = authority.scope.tool === tool
473
- || tool.startsWith(`${authority.scope.tool}@`)
474
- || authority.scope.tool.startsWith(`${tool}@`)
475
- || requestedNorm === scopeNorm;
476
-
477
- if (!exactMatch) {
478
- return {
479
- valid: false,
480
- error: {
481
- code: E_AUTHORITY_SCOPE_MISMATCH,
482
- message: `Authority grant scope tool '${authority.scope.tool}' does not match requested verification tool '${tool}'`,
483
- },
484
- };
485
- }
486
- }
487
-
488
- return { valid: true, error: null };
489
- }
490
-
491
- export function validateVerificationAuthority(check, options = {}) {
492
- const command = check?.details?.command
493
- ?? (check?.kind === "command" && typeof check?.source === "string" && !check.source.startsWith("check:")
494
- ? check.source
495
- : null);
496
-
497
- if (!command || typeof command !== "string") {
498
- return { valid: true, error: null };
499
- }
500
-
501
- const classification = classifyCommandResolution(command);
502
- if (!classification.mayInstall) {
503
- return { valid: true, error: null };
504
- }
505
-
506
- const authorityRef = getInstallationAuthorityRef(check);
507
- if (!authorityRef) {
508
- return {
509
- valid: false,
510
- error: {
511
- code: E_INSTALLATION_AUTHORITY_REQUIRED,
512
- message: `Verification command '${command}' uses installation-capable resolution (${classification.resolutionMode}) without recorded installation authority reference`,
513
- },
514
- };
515
- }
516
-
517
- const resolved = resolveTrustedAuthority({
518
- authorityRef,
519
- target: options.target,
520
- trustedAuthorityFile: options.trustedAuthorityFile,
521
- trustedAuthorityDir: options.trustedAuthorityDir,
522
- authorities: options.authorities,
523
- authority: options.authority,
524
- authorityContext: options.authorityContext,
525
- runtimeContext: options.runtimeContext,
526
- });
527
- if (!resolved.trusted) {
528
- if (resolved.error?.code === E_AUTHORITY_INVALID && resolved.sourceConfigured === false) {
529
- return {
530
- valid: false,
531
- error: {
532
- code: E_INSTALLATION_AUTHORITY_REQUIRED,
533
- message: "Installation-capable verification requires a host-attested authority context",
534
- },
535
- };
536
- }
537
- return { valid: false, error: resolved.error };
538
- }
539
-
540
- return validateAuthorityGrant({
541
- authority: resolved.authority,
542
- taskId: options.taskId,
543
- type: "SOFTWARE_INSTALLATION",
544
- tool: classification.tool,
545
- });
546
- }
@@ -0,0 +1,61 @@
1
+ export const E_VERIFICATION_TOOL_UNAVAILABLE = "E_VERIFICATION_TOOL_UNAVAILABLE";
2
+ export const E_INSTALLATION_AUTHORITY_REQUIRED = "E_INSTALLATION_AUTHORITY_REQUIRED";
3
+ export const E_COMMAND_RESOLUTION_AMBIGUOUS = "E_COMMAND_RESOLUTION_AMBIGUOUS";
4
+ export const E_AUTHORITY_INVALID = "E_AUTHORITY_INVALID";
5
+ export const E_AUTHORITY_SCOPE_MISMATCH = "E_AUTHORITY_SCOPE_MISMATCH";
6
+
7
+ export const RESOLUTION_MODES = Object.freeze([
8
+ "LOCAL_EXECUTABLE",
9
+ "LOCAL_PACKAGE_BINARY",
10
+ "NON_INSTALLING_RESOLUTION",
11
+ "INSTALL_CAPABLE_RESOLUTION",
12
+ "EXPLICIT_INSTALLATION",
13
+ "UNKNOWN",
14
+ ]);
15
+
16
+ export const NPM_INSTALL_COMMANDS = new Set([
17
+ "install", "add", "i", "in", "ins", "inst", "insta", "instal", "isnt", "isnta", "isntal", "isntall",
18
+ ]);
19
+
20
+ export const NPM_CI_COMMANDS = new Set([
21
+ "ci", "clean-install", "ic", "install-clean", "isntall-clean",
22
+ ]);
23
+
24
+ export const NPM_INSTALL_TEST_COMMANDS = new Set([
25
+ "install-test", "it",
26
+ ]);
27
+
28
+ export const NPM_INSTALL_CI_TEST_COMMANDS = new Set([
29
+ "install-ci-test", "cit", "clean-install-test", "sit",
30
+ ]);
31
+
32
+ export const NPM_EXEC_COMMANDS = new Set([
33
+ "exec", "x",
34
+ ]);
35
+
36
+ export const NPM_INIT_COMMANDS = new Set([
37
+ "init", "create", "innit",
38
+ ]);
39
+
40
+ export const NPM_SCRIPT_COMMANDS = new Set([
41
+ "test", "t", "tst", "start", "stop", "restart", "run", "run-script", "rum", "urn",
42
+ ]);
43
+
44
+ export const NPM_KNOWN_NON_INSTALLING_COMMANDS = new Set([
45
+ "v", "view", "info", "show", "list", "ls", "outdated", "config", "help", "help-search", "doctor", "ping", "root", "prefix", "bin", "whoami",
46
+ ]);
47
+
48
+ export const NPM_KNOWN_BOOLEAN_OPTIONS = new Set([
49
+ "--silent", "--json", "--long", "--parseable", "--global", "-g", "--force", "--yes", "-y", "--no",
50
+ ]);
51
+
52
+ export const NPM_OPTIONS_WITH_VALUE = new Set([
53
+ "--workspace",
54
+ "-w",
55
+ "--loglevel",
56
+ "--prefix",
57
+ "-C",
58
+ "--userconfig",
59
+ "--registry",
60
+ "--cache",
61
+ ]);