@opensip-cli/contracts 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.
Files changed (92) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +31 -0
  4. package/dist/__tests__/exit-codes.test.d.ts +2 -0
  5. package/dist/__tests__/exit-codes.test.d.ts.map +1 -0
  6. package/dist/__tests__/exit-codes.test.js +185 -0
  7. package/dist/__tests__/exit-codes.test.js.map +1 -0
  8. package/dist/__tests__/manifest-reexport.test.d.ts +6 -0
  9. package/dist/__tests__/manifest-reexport.test.d.ts.map +1 -0
  10. package/dist/__tests__/manifest-reexport.test.js +38 -0
  11. package/dist/__tests__/manifest-reexport.test.js.map +1 -0
  12. package/dist/__tests__/types-only.test.d.ts +10 -0
  13. package/dist/__tests__/types-only.test.d.ts.map +1 -0
  14. package/dist/__tests__/types-only.test.js +49 -0
  15. package/dist/__tests__/types-only.test.js.map +1 -0
  16. package/dist/cli-flags.d.ts +56 -0
  17. package/dist/cli-flags.d.ts.map +1 -0
  18. package/dist/cli-flags.js +85 -0
  19. package/dist/cli-flags.js.map +1 -0
  20. package/dist/cli-flags.test.d.ts +2 -0
  21. package/dist/cli-flags.test.d.ts.map +1 -0
  22. package/dist/cli-flags.test.js +51 -0
  23. package/dist/cli-flags.test.js.map +1 -0
  24. package/dist/command-outcome.d.ts +87 -0
  25. package/dist/command-outcome.d.ts.map +1 -0
  26. package/dist/command-outcome.js +32 -0
  27. package/dist/command-outcome.js.map +1 -0
  28. package/dist/command-outcome.test.d.ts +10 -0
  29. package/dist/command-outcome.test.d.ts.map +1 -0
  30. package/dist/command-outcome.test.js +68 -0
  31. package/dist/command-outcome.test.js.map +1 -0
  32. package/dist/command-results.d.ts +501 -0
  33. package/dist/command-results.d.ts.map +1 -0
  34. package/dist/command-results.js +14 -0
  35. package/dist/command-results.js.map +1 -0
  36. package/dist/exit-codes.d.ts +44 -0
  37. package/dist/exit-codes.d.ts.map +1 -0
  38. package/dist/exit-codes.js +186 -0
  39. package/dist/exit-codes.js.map +1 -0
  40. package/dist/graph-catalog.d.ts +143 -0
  41. package/dist/graph-catalog.d.ts.map +1 -0
  42. package/dist/graph-catalog.js +13 -0
  43. package/dist/graph-catalog.js.map +1 -0
  44. package/dist/index.d.ts +62 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +56 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/recipe-default.d.ts +53 -0
  49. package/dist/recipe-default.d.ts.map +1 -0
  50. package/dist/recipe-default.js +55 -0
  51. package/dist/recipe-default.js.map +1 -0
  52. package/dist/recipe-default.test.d.ts +2 -0
  53. package/dist/recipe-default.test.d.ts.map +1 -0
  54. package/dist/recipe-default.test.js +32 -0
  55. package/dist/recipe-default.test.js.map +1 -0
  56. package/dist/score.d.ts +26 -0
  57. package/dist/score.d.ts.map +1 -0
  58. package/dist/score.js +25 -0
  59. package/dist/score.js.map +1 -0
  60. package/dist/score.test.d.ts +2 -0
  61. package/dist/score.test.d.ts.map +1 -0
  62. package/dist/score.test.js +22 -0
  63. package/dist/score.test.js.map +1 -0
  64. package/dist/session-types.d.ts +132 -0
  65. package/dist/session-types.d.ts.map +1 -0
  66. package/dist/session-types.js +11 -0
  67. package/dist/session-types.js.map +1 -0
  68. package/dist/signal-envelope.d.ts +118 -0
  69. package/dist/signal-envelope.d.ts.map +1 -0
  70. package/dist/signal-envelope.js +84 -0
  71. package/dist/signal-envelope.js.map +1 -0
  72. package/dist/signal-envelope.test.d.ts +2 -0
  73. package/dist/signal-envelope.test.d.ts.map +1 -0
  74. package/dist/signal-envelope.test.js +168 -0
  75. package/dist/signal-envelope.test.js.map +1 -0
  76. package/dist/types.d.ts +78 -0
  77. package/dist/types.d.ts.map +1 -0
  78. package/dist/types.js +5 -0
  79. package/dist/types.js.map +1 -0
  80. package/dist/verbose-detail.d.ts +26 -0
  81. package/dist/verbose-detail.d.ts.map +1 -0
  82. package/dist/verbose-detail.js +75 -0
  83. package/dist/verbose-detail.js.map +1 -0
  84. package/dist/verbose-detail.test.d.ts +2 -0
  85. package/dist/verbose-detail.test.d.ts.map +1 -0
  86. package/dist/verbose-detail.test.js +53 -0
  87. package/dist/verbose-detail.test.js.map +1 -0
  88. package/dist/verdict-envelope.test.d.ts +8 -0
  89. package/dist/verdict-envelope.test.d.ts.map +1 -0
  90. package/dist/verdict-envelope.test.js +67 -0
  91. package/dist/verdict-envelope.test.js.map +1 -0
  92. package/package.json +56 -0
@@ -0,0 +1,186 @@
1
+ import { ConfigurationError, NetworkError, NotFoundError, PluginIncompatibleError, TimeoutError, ValidationError, } from '@opensip-cli/core';
2
+ export const EXIT_CODES = {
3
+ SUCCESS: 0,
4
+ RUNTIME_ERROR: 1,
5
+ CONFIGURATION_ERROR: 2,
6
+ CHECK_NOT_FOUND: 3,
7
+ REPORT_FAILED: 4,
8
+ /**
9
+ * A plugin was rejected by the compatibility gate (launch) — its
10
+ * declared `apiVersion` is out of range and it was explicitly requested
11
+ * (fail-closed; the skip path is silent). Dedicated rather than reusing
12
+ * `CONFIGURATION_ERROR` so an incompatible plugin is diagnosable from the
13
+ * exit code alone. Read by the CLI fail-closed admission path (Phase 3).
14
+ */
15
+ PLUGIN_INCOMPATIBLE: 5,
16
+ };
17
+ /**
18
+ * Canonical mapping from typed `ToolError` subclasses to CLI exit
19
+ * codes. This is the single source of truth for how typed errors flow
20
+ * into the process exit code — both the CLI's top-level
21
+ * `handleParseError` and any tool that chooses to handle its own
22
+ * `ToolError` locally route through this function.
23
+ *
24
+ * The mapping policy (see `Tool` interface JSDoc in
25
+ * `@opensip-cli/core` for the full contract):
26
+ *
27
+ * - `NotFoundError` → `CHECK_NOT_FOUND` (exit 3)
28
+ * - `ConfigurationError` → `CONFIGURATION_ERROR` (exit 2)
29
+ * - `ValidationError` → `CONFIGURATION_ERROR` (exit 2)
30
+ * - `NetworkError` → `REPORT_FAILED` (exit 4)
31
+ * - `PluginIncompatibleError`→ `PLUGIN_INCOMPATIBLE` (exit 5)
32
+ * - `TimeoutError` → `RUNTIME_ERROR` (exit 1)
33
+ * - any other `ToolError` → `RUNTIME_ERROR` (exit 1)
34
+ */
35
+ export function mapToolErrorToExitCode(error) {
36
+ if (error instanceof NotFoundError)
37
+ return EXIT_CODES.CHECK_NOT_FOUND;
38
+ if (error instanceof ConfigurationError)
39
+ return EXIT_CODES.CONFIGURATION_ERROR;
40
+ if (error instanceof ValidationError)
41
+ return EXIT_CODES.CONFIGURATION_ERROR;
42
+ if (error instanceof NetworkError)
43
+ return EXIT_CODES.REPORT_FAILED;
44
+ if (error instanceof PluginIncompatibleError)
45
+ return EXIT_CODES.PLUGIN_INCOMPATIBLE;
46
+ if (error instanceof TimeoutError)
47
+ return EXIT_CODES.RUNTIME_ERROR;
48
+ return EXIT_CODES.RUNTIME_ERROR;
49
+ }
50
+ /**
51
+ * True when any of the supplied substrings appear in `message`.
52
+ *
53
+ * Wraps the substring checks the rule table needs without spreading
54
+ * `String#includes` ladders back through `getErrorSuggestion`. Each
55
+ * rule keeps its own readable list of substrings and the function
56
+ * body stays a pure data walk.
57
+ */
58
+ function containsAny(haystack, needles) {
59
+ return needles.some((needle) => haystack.includes(needle));
60
+ }
61
+ /**
62
+ * Ordered list of suggestion rules. Walked top-down by
63
+ * `getErrorSuggestion`; first hit wins, so order is load-bearing.
64
+ *
65
+ * Adding a new error category is one tuple. Do NOT replace this with
66
+ * a Chain-of-Responsibility class — a flat array is the contract here.
67
+ *
68
+ * The over-broad bare `'config'` substring from the previous
69
+ * implementation has been narrowed into two explicit rules — one for
70
+ * `opensip-cli.config.yml` (file shape) and one for `YAML` (parse
71
+ * shape). The bare substring matched common English words like
72
+ * `'configurable'` and `'reconfigure'` and produced false positives.
73
+ */
74
+ const SUGGESTION_RULES = [
75
+ // Recipe not found — must come BEFORE the check-not-found rule because
76
+ // the fitness engine throws `Recipe not found: <id>` and the broad
77
+ // `/not found: (.+)/` regex would otherwise mis-classify it as
78
+ // CHECK_NOT_FOUND (exit 3) instead of CONFIGURATION_ERROR (exit 2).
79
+ {
80
+ match: (message) => {
81
+ const recipeRegex = /Recipe not found: (.+)/;
82
+ const m = recipeRegex.exec(message);
83
+ if (m)
84
+ return { capture: m[1] ?? null };
85
+ if (containsAny(message, ['Recipe not found:']))
86
+ return { capture: null };
87
+ return null;
88
+ },
89
+ suggest: (capture) => ({
90
+ message: `Recipe '${capture ?? 'unknown'}' not found.`,
91
+ action: 'Run opensip fit --recipes to see available recipes.',
92
+ exitCode: EXIT_CODES.CONFIGURATION_ERROR,
93
+ }),
94
+ },
95
+ // Check not found — only the explicit "Check not found: <slug>" form (plus
96
+ // the substring for no-capture cases). We deliberately dropped the previous
97
+ // broad `/not found: (.+)/` and bare "not found" contains check to avoid
98
+ // mis-classifying other "not found" errors (recipes, files, symbols, etc.)
99
+ // as CHECK_NOT_FOUND via the string suggestion path. The *typed* mapper
100
+ // (mapToolErrorToExitCode) already routes real NotFoundError correctly; this
101
+ // table is only for unstructured Error messages.
102
+ {
103
+ match: (message) => {
104
+ const slugMatch = /Check not found: (.+)/.exec(message);
105
+ if (slugMatch) {
106
+ return { capture: slugMatch[1] };
107
+ }
108
+ if (containsAny(message, ['Check not found:'])) {
109
+ return { capture: null };
110
+ }
111
+ return null;
112
+ },
113
+ suggest: (capture) => ({
114
+ message: `Check '${capture ?? 'unknown'}' not found.`,
115
+ action: 'Run opensip fit --list to see available checks.',
116
+ exitCode: EXIT_CODES.CHECK_NOT_FOUND,
117
+ }),
118
+ },
119
+ // Recipe not found — captures the verbatim error message so the
120
+ // surfaced suggestion preserves the recipe name.
121
+ {
122
+ match: (message) => (containsAny(message, ['Unknown recipe']) ? { capture: message } : null),
123
+ suggest: (capture) => ({
124
+ message: capture ?? 'Unknown recipe.',
125
+ action: 'Run opensip fit --recipes to see available recipes.',
126
+ exitCode: EXIT_CODES.CONFIGURATION_ERROR,
127
+ }),
128
+ },
129
+ // Config file error — opensip-cli.config.yml shape.
130
+ {
131
+ match: (message) => containsAny(message, ['opensip-cli.config.yml']) ? { capture: null } : null,
132
+ suggest: () => ({
133
+ message: 'Configuration error.',
134
+ action: 'Check opensip-cli.config.yml for syntax errors.',
135
+ exitCode: EXIT_CODES.CONFIGURATION_ERROR,
136
+ }),
137
+ },
138
+ // Config file error — YAML parse shape (paired with the file rule above).
139
+ {
140
+ match: (message) => (containsAny(message, ['YAML']) ? { capture: null } : null),
141
+ suggest: () => ({
142
+ message: 'Configuration error.',
143
+ action: 'Check opensip-cli.config.yml for syntax errors.',
144
+ exitCode: EXIT_CODES.CONFIGURATION_ERROR,
145
+ }),
146
+ },
147
+ // Permission denied
148
+ {
149
+ match: (message) => containsAny(message, ['EACCES', 'permission denied']) ? { capture: null } : null,
150
+ suggest: () => ({
151
+ message: 'Permission denied reading files.',
152
+ action: 'Check file permissions in the target directory.',
153
+ exitCode: EXIT_CODES.RUNTIME_ERROR,
154
+ }),
155
+ },
156
+ // No checks available
157
+ {
158
+ match: (message) => containsAny(message, ['No checks registered', 'No checks to run']) ? { capture: null } : null,
159
+ suggest: () => ({
160
+ message: 'No checks available to run.',
161
+ action: 'Install at least one @opensip-cli/checks-* package, or declare plugins.checkPackages in opensip-cli.config.yml.',
162
+ exitCode: EXIT_CODES.RUNTIME_ERROR,
163
+ }),
164
+ },
165
+ // Network error (report-to)
166
+ {
167
+ match: (message) => containsAny(message, ['fetch', 'ECONNREFUSED', 'network']) ? { capture: null } : null,
168
+ suggest: () => ({
169
+ message: 'Network error sending report.',
170
+ action: 'Check the --report-to URL and your network connection.',
171
+ exitCode: EXIT_CODES.REPORT_FAILED,
172
+ }),
173
+ },
174
+ ];
175
+ /** Matches an arbitrary error against the suggestion-rule table; returns null if no rule fires. */
176
+ export function getErrorSuggestion(err) {
177
+ const message = err instanceof Error ? err.message : String(err);
178
+ for (const rule of SUGGESTION_RULES) {
179
+ const result = rule.match(message);
180
+ if (result !== null) {
181
+ return rule.suggest(result.capture);
182
+ }
183
+ }
184
+ return null;
185
+ }
186
+ //# sourceMappingURL=exit-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../src/exit-codes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,YAAY,EACZ,eAAe,GAEhB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO,EAAE,CAAC;IACV,aAAa,EAAE,CAAC;IAChB,mBAAmB,EAAE,CAAC;IACtB,eAAe,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC;IAChB;;;;;;OAMG;IACH,mBAAmB,EAAE,CAAC;CACd,CAAC;AAEX;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAgB;IACrD,IAAI,KAAK,YAAY,aAAa;QAAE,OAAO,UAAU,CAAC,eAAe,CAAC;IACtE,IAAI,KAAK,YAAY,kBAAkB;QAAE,OAAO,UAAU,CAAC,mBAAmB,CAAC;IAC/E,IAAI,KAAK,YAAY,eAAe;QAAE,OAAO,UAAU,CAAC,mBAAmB,CAAC;IAC5E,IAAI,KAAK,YAAY,YAAY;QAAE,OAAO,UAAU,CAAC,aAAa,CAAC;IACnE,IAAI,KAAK,YAAY,uBAAuB;QAAE,OAAO,UAAU,CAAC,mBAAmB,CAAC;IACpF,IAAI,KAAK,YAAY,YAAY;QAAE,OAAO,UAAU,CAAC,aAAa,CAAC;IACnE,OAAO,UAAU,CAAC,aAAa,CAAC;AAClC,CAAC;AA0BD;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,QAAgB,EAAE,OAA0B;IAC/D,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,gBAAgB,GAA8B;IAClD,uEAAuE;IACvE,mEAAmE;IACnE,+DAA+D;IAC/D,oEAAoE;IACpE;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,MAAM,WAAW,GAAG,wBAAwB,CAAC;YAC7C,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC;gBAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YACxC,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC,mBAAmB,CAAC,CAAC;gBAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC1E,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACrB,OAAO,EAAE,WAAW,OAAO,IAAI,SAAS,cAAc;YACtD,MAAM,EAAE,qDAAqD;YAC7D,QAAQ,EAAE,UAAU,CAAC,mBAAmB;SACzC,CAAC;KACH;IAED,2EAA2E;IAC3E,4EAA4E;IAC5E,yEAAyE;IACzE,2EAA2E;IAC3E,wEAAwE;IACxE,6EAA6E;IAC7E,iDAAiD;IACjD;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE;YACjB,MAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,CAAC;YACD,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC;gBAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACrB,OAAO,EAAE,UAAU,OAAO,IAAI,SAAS,cAAc;YACrD,MAAM,EAAE,iDAAiD;YACzD,QAAQ,EAAE,UAAU,CAAC,eAAe;SACrC,CAAC;KACH;IAED,gEAAgE;IAChE,iDAAiD;IACjD;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5F,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACrB,OAAO,EAAE,OAAO,IAAI,iBAAiB;YACrC,MAAM,EAAE,qDAAqD;YAC7D,QAAQ,EAAE,UAAU,CAAC,mBAAmB;SACzC,CAAC;KACH;IAED,oDAAoD;IACpD;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CACjB,WAAW,CAAC,OAAO,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;QAC7E,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YACd,OAAO,EAAE,sBAAsB;YAC/B,MAAM,EAAE,iDAAiD;YACzD,QAAQ,EAAE,UAAU,CAAC,mBAAmB;SACzC,CAAC;KACH;IAED,0EAA0E;IAC1E;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/E,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YACd,OAAO,EAAE,sBAAsB;YAC/B,MAAM,EAAE,iDAAiD;YACzD,QAAQ,EAAE,UAAU,CAAC,mBAAmB;SACzC,CAAC;KACH;IAED,oBAAoB;IACpB;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CACjB,WAAW,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;QAClF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YACd,OAAO,EAAE,kCAAkC;YAC3C,MAAM,EAAE,iDAAiD;YACzD,QAAQ,EAAE,UAAU,CAAC,aAAa;SACnC,CAAC;KACH;IAED,sBAAsB;IACtB;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CACjB,WAAW,CAAC,OAAO,EAAE,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;QAC/F,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YACd,OAAO,EAAE,6BAA6B;YACtC,MAAM,EACJ,iHAAiH;YACnH,QAAQ,EAAE,UAAU,CAAC,aAAa;SACnC,CAAC;KACH;IAED,4BAA4B;IAC5B;QACE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CACjB,WAAW,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;QACvF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;YACd,OAAO,EAAE,+BAA+B;YACxC,MAAM,EAAE,wDAAwD;YAChE,QAAQ,EAAE,UAAU,CAAC,aAAa;SACnC,CAAC;KACH;CACF,CAAC;AAEF,mGAAmG;AACnG,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAEjE,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Type-only structural shapes for the v0.3 Code Paths panel.
3
+ *
4
+ * The graph engine's catalog.json is consumed here purely by JSON shape;
5
+ * this file MUST NOT import from `@opensip-cli/graph`. The shape is
6
+ * intentionally duplicated as readonly structural types — this decouples
7
+ * the dashboard panel from the graph engine's runtime types so
8
+ * @opensip-cli/contracts stays a pure type-only kernel boundary.
9
+ *
10
+ * Runtime exports are forbidden. Only `export type` and `export interface`.
11
+ */
12
+ export type GraphFunctionKind = 'function-declaration' | 'function-expression' | 'arrow' | 'method' | 'constructor' | 'getter' | 'setter' | 'module-init';
13
+ export type GraphCallResolution = 'static' | 'method-dispatch' | 'jsx' | 'constructor' | 'unknown' | 'dynamic-string'
14
+ /** Fast-mode (syntactic) edge: resolved from name + import graph, no
15
+ * type checker. Always approximate — carries capped confidence. */
16
+ | 'syntactic'
17
+ /** Cross-shard boundary edge recovered by the semantic linker: the import
18
+ * specifier + callee name resolved to a UNIQUE exported occurrence in the
19
+ * imported package (the type checker's conclusion). High-confidence; the
20
+ * linker declines on ambiguity rather than guessing. */
21
+ | 'semantic';
22
+ export type GraphCallConfidence = 'high' | 'medium' | 'low';
23
+ /** Mirror of the engine's `ResolutionMode`. `exact` = semantic;
24
+ * `fast` = syntactic (approximate). Kept structurally in sync. */
25
+ export type GraphResolutionMode = 'exact' | 'fast';
26
+ export type GraphVisibility = 'exported' | 'module-local' | 'private';
27
+ export interface GraphParam {
28
+ readonly name: string;
29
+ readonly optional: boolean;
30
+ readonly rest: boolean;
31
+ }
32
+ export interface GraphCallEdge {
33
+ readonly to: readonly string[];
34
+ readonly line: number;
35
+ readonly column: number;
36
+ readonly resolution: GraphCallResolution;
37
+ readonly confidence: GraphCallConfidence;
38
+ readonly text: string;
39
+ /** True for an edge recovered by the cross-shard boundary pass (always
40
+ * syntactic). Mirrors the engine `CallEdge.crossShard`. */
41
+ readonly crossShard?: boolean;
42
+ }
43
+ export interface GraphFunctionOccurrence {
44
+ readonly bodyHash: string;
45
+ readonly simpleName: string;
46
+ readonly qualifiedName: string;
47
+ readonly filePath: string;
48
+ /**
49
+ * The package this occurrence belongs to — the `name` of its nearest
50
+ * enclosing `package.json` (e.g. `@opensip-cli/fitness`), or the
51
+ * top-level path segment when there is no manifest. Computed at build
52
+ * time (the dashboard has no filesystem access). Absent on legacy
53
+ * catalogs; consumers fall back to deriving it from `filePath`.
54
+ */
55
+ readonly package?: string;
56
+ readonly line: number;
57
+ readonly column: number;
58
+ readonly endLine: number;
59
+ readonly kind: GraphFunctionKind;
60
+ readonly params: readonly GraphParam[];
61
+ readonly returnType: string | null;
62
+ readonly enclosingClass: string | null;
63
+ readonly decorators: readonly string[];
64
+ readonly visibility: GraphVisibility;
65
+ readonly inTestFile: boolean;
66
+ readonly definedInGenerated: boolean;
67
+ readonly calls: readonly GraphCallEdge[];
68
+ }
69
+ /** Mirror of the engine `BlastScore`. */
70
+ export interface GraphBlastScore {
71
+ readonly direct: number;
72
+ readonly transitive: number;
73
+ readonly score: number;
74
+ }
75
+ /** Mirror of the engine `FunctionFeatures` (per-function columns). */
76
+ export interface GraphFunctionFeatures {
77
+ readonly bodyLines: number;
78
+ readonly blast?: GraphBlastScore;
79
+ readonly reachableFromEntry?: boolean;
80
+ readonly testReachable?: boolean;
81
+ readonly reachableOnlyFromTests?: boolean;
82
+ }
83
+ /** Mirror of the engine `PackageFeatures` (per-package coupling degrees). */
84
+ export interface GraphPackageFeatures {
85
+ readonly couplingOut: number;
86
+ readonly couplingIn: number;
87
+ }
88
+ /** Mirror of the engine `SccFeatures` (one strongly-connected component). */
89
+ export interface GraphSccFeatures {
90
+ readonly id: string;
91
+ readonly members: readonly string[];
92
+ readonly sccSize: number;
93
+ readonly crossesPackages: boolean;
94
+ }
95
+ /** Mirror of the engine `PackageEdgeFeature` (one directed coupling edge). */
96
+ export interface GraphPackageEdgeFeature {
97
+ readonly callerPackage: string;
98
+ readonly calleePackage: string;
99
+ readonly count: number;
100
+ }
101
+ /**
102
+ * Structural mirror of the engine `PersistedFeatures`. Every entity is
103
+ * optional — only the columns a dashboard-bound run materialized are present.
104
+ * The dashboard reads these instead of recomputing blast / SCC / coupling
105
+ * client-side.
106
+ */
107
+ export interface GraphFeatures {
108
+ readonly function?: Readonly<Record<string, GraphFunctionFeatures>>;
109
+ readonly package?: Readonly<Record<string, GraphPackageFeatures>>;
110
+ readonly scc?: readonly GraphSccFeatures[];
111
+ readonly edge?: readonly GraphPackageEdgeFeature[];
112
+ }
113
+ /**
114
+ * Public catalog shape consumed by the dashboard.
115
+ *
116
+ * The `language` field carries the adapter id (e.g. 'typescript', 'python',
117
+ * 'rust') and `cacheKey` is an opaque per-adapter invalidation string. Legacy
118
+ * catalog payloads classify as `invalid` at load time.
119
+ *
120
+ * `cacheKey` is optional here because external callers parsing
121
+ * an older catalog they have on disk would otherwise fail to load the file with
122
+ * this type. Engine-internal code requires it.
123
+ */
124
+ export interface GraphCatalog {
125
+ readonly version: string;
126
+ readonly tool: string;
127
+ readonly language: string;
128
+ readonly builtAt: string;
129
+ readonly cacheKey?: string;
130
+ readonly filesFingerprint?: string;
131
+ /** The resolution tier that produced this catalog. Absent ⇒ `'exact'`
132
+ * (historical behavior). Mirrors the engine `Catalog.resolutionMode`. */
133
+ readonly resolutionMode?: GraphResolutionMode;
134
+ readonly functions: Readonly<Record<string, readonly GraphFunctionOccurrence[]>>;
135
+ /**
136
+ * Derived feature columns (blast / SCC / package coupling). Present only on
137
+ * catalogs produced by a dashboard-bound run (ADR-0006); the dashboard falls
138
+ * back to a no-data state when absent. Mirrors the engine
139
+ * `Catalog.features` so `loadCatalogContract` stays a cast-free widening.
140
+ */
141
+ readonly features?: GraphFeatures;
142
+ }
143
+ //# sourceMappingURL=graph-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-catalog.d.ts","sourceRoot":"","sources":["../src/graph-catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Type-only structural shapes for the v0.3 Code Paths panel.
3
+ *
4
+ * The graph engine's catalog.json is consumed here purely by JSON shape;
5
+ * this file MUST NOT import from `@opensip-cli/graph`. The shape is
6
+ * intentionally duplicated as readonly structural types — this decouples
7
+ * the dashboard panel from the graph engine's runtime types so
8
+ * @opensip-cli/contracts stays a pure type-only kernel boundary.
9
+ *
10
+ * Runtime exports are forbidden. Only `export type` and `export interface`.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=graph-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-catalog.js","sourceRoot":"","sources":["../src/graph-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @opensip-cli/contracts — shared contract types.
3
+ *
4
+ * Tool packages (fitness, simulation) and the CLI entry-point both
5
+ * depend on this package for:
6
+ * - CLI option / output / result types
7
+ * - Exit code constants and error suggestions
8
+ * - The cross-tool StoredSession type (the SessionRepo runtime + the
9
+ * sessions schema live in @opensip-cli/session-store)
10
+ *
11
+ * The GraphCatalog shape is DEFINED here (./graph-catalog.ts), not
12
+ * re-exported from elsewhere. It is the contract surface between the
13
+ * graph tool (which writes catalog.json) and @opensip-cli/dashboard
14
+ * (which renders it): both producer and consumer depend on contracts
15
+ * from below, so the shape lives in the layer beneath both. contracts
16
+ * holds zero runtime dependency on dashboard or graph — these are
17
+ * type-only declarations.
18
+ *
19
+ * contracts depends only on @opensip-cli/core. Tools depend on
20
+ * contracts. The CLI entry-point depends on contracts and on every
21
+ * tool package — the dependency graph stays acyclic.
22
+ */
23
+ export type { FitOptions, InitOptions, ToolOptions } from './types.js';
24
+ export type { SignalEnvelope, RunVerdict, UnitResult, BuildEnvelopeInput, } from './signal-envelope.js';
25
+ export { buildSignalEnvelope } from './signal-envelope.js';
26
+ export type { CommandResult, ClearDoneResult, ConfigureDoneResult, UninstallDoneResult, FitDoneResult, SimDoneResult, GraphDoneResult, GateDoneResult, GraphStatusResult, TextLinesResult, ToolsListResult, ToolsListRow, ToolsValidateResult, ToolsValidateSection, ToolsInstallResult, ToolsUninstallResult, ToolsDataPurgeResult, ListChecksResult, ListRecipesResult, HistorySession, HistoryResult, ReportResult, InitResult, PreExistingFile, SimNoticeResult, PluginResult, PluginInfo, SyncEntry, SessionReplayResult, HelpResult, ErrorResult, VerboseDetail, FindingGroup, FindingLine, } from './command-results.js';
27
+ export type { CommandOutcome, CommandOutcomeStatus, ErrorDetail, WarningDetail, RenderHints, } from './command-outcome.js';
28
+ export type { RunDiagnostics, DiagnosticEvent, DiagnosticPhase, DiagnosticLevel, } from '@opensip-cli/core';
29
+ export { passRate } from './score.js';
30
+ export { EXIT_CODES, getErrorSuggestion, mapToolErrorToExitCode } from './exit-codes.js';
31
+ export type { ErrorSuggestion } from './exit-codes.js';
32
+ export { PLUGIN_API_VERSION, checkCompatibility } from '@opensip-cli/core';
33
+ export type { RawToolPluginManifest, ToolPluginManifest, ToolCommandManifest, ToolProvenance, ToolSource, CompatibilityVerdict, CapabilityDomainSpec, ToolCapabilityDeclaration, CapabilityContributionKind, } from '@opensip-cli/core';
34
+ export { defineCommand, COMMON_FLAG_KEYS, RAW_STREAM_REASONS } from '@opensip-cli/core';
35
+ export type { CommandSpec, OptionSpec, ArgSpec, CommandHandler, CommandContext, CommandOutputMode, CommandScopeRequirement, RawStreamReason, } from '@opensip-cli/core';
36
+ export { resolveToolRecipeName, BUILTIN_DEFAULT_RECIPE } from './recipe-default.js';
37
+ export type { ResolvedRecipe, RecipeSource } from './recipe-default.js';
38
+ export { commonFlags, applyCommonFlags, MANDATORY_COMMON_FLAGS } from './cli-flags.js';
39
+ export type { CommonFlagKey, CommonFlagSpec } from './cli-flags.js';
40
+ export { buildFindingGroups } from './verbose-detail.js';
41
+ export type { FindingGroupUnit } from './verbose-detail.js';
42
+ export type { StoredSession, StoredSessionHostMetrics, ToolSessionReplay, } from './session-types.js';
43
+ export type { GraphCatalog, GraphFunctionOccurrence, GraphCallEdge, GraphParam, GraphFunctionKind, GraphCallResolution, GraphCallConfidence, GraphResolutionMode, GraphVisibility, GraphFeatures, GraphFunctionFeatures, GraphPackageFeatures, GraphSccFeatures, GraphPackageEdgeFeature, GraphBlastScore, } from './graph-catalog.js';
44
+ import type { Command } from 'commander';
45
+ /**
46
+ * Type alias for Commander's `Command` class — re-exported here so the
47
+ * host's command-spec mounting (`mountCommandSpec`) and the tool lifecycle
48
+ * can type the root `program` handle without a direct `commander` import or
49
+ * an `as Command` cast. (Tools themselves no longer touch Commander — they
50
+ * declare `commandSpecs`; the host owns `program`.)
51
+ *
52
+ * `commander` is an OPTIONAL peer dependency of
53
+ * `@opensip-cli/contracts`. `CliProgram` is now primarily a host-side
54
+ * type (the `Tool` contract no longer surfaces it — tools declare
55
+ * `commandSpecs`), so any code referencing it needs `commander` resolvable
56
+ * in its own `node_modules`; pnpm/npm will surface the peer requirement in
57
+ * install output. Code that never touches `CliProgram` can skip commander
58
+ * entirely. The alias erases at compile time — no runtime commander require
59
+ * lands in `dist/index.js`.
60
+ */
61
+ export type CliProgram = Command;
62
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @opensip-cli/contracts — shared contract types.
3
+ *
4
+ * Tool packages (fitness, simulation) and the CLI entry-point both
5
+ * depend on this package for:
6
+ * - CLI option / output / result types
7
+ * - Exit code constants and error suggestions
8
+ * - The cross-tool StoredSession type (the SessionRepo runtime + the
9
+ * sessions schema live in @opensip-cli/session-store)
10
+ *
11
+ * The GraphCatalog shape is DEFINED here (./graph-catalog.ts), not
12
+ * re-exported from elsewhere. It is the contract surface between the
13
+ * graph tool (which writes catalog.json) and @opensip-cli/dashboard
14
+ * (which renders it): both producer and consumer depend on contracts
15
+ * from below, so the shape lives in the layer beneath both. contracts
16
+ * holds zero runtime dependency on dashboard or graph — these are
17
+ * type-only declarations.
18
+ *
19
+ * contracts depends only on @opensip-cli/core. Tools depend on
20
+ * contracts. The CLI entry-point depends on contracts and on every
21
+ * tool package — the dependency graph stays acyclic.
22
+ */
23
+ export { buildSignalEnvelope } from './signal-envelope.js';
24
+ // Canonical pass-rate (`score`) computation — shared by every tool that
25
+ // builds a signal envelope so the dashboard "PASS RATE" stays consistent
26
+ // across fit/graph and cannot drift back into per-tool formulas.
27
+ export { passRate } from './score.js';
28
+ // Exit codes + error suggestion helper + typed-error → exit-code mapping
29
+ export { EXIT_CODES, getErrorSuggestion, mapToolErrorToExitCode } from './exit-codes.js';
30
+ // Static tool-plugin manifest + the plugin-API epoch + provenance types +
31
+ // the pure compatibility gate (launch raw-vs-admitted contract).
32
+ // DEFINED in @opensip-cli/core (next to the Tool contract; core cannot
33
+ // import contracts); re-exported here for the public Tool↔runner surface.
34
+ export { PLUGIN_API_VERSION, checkCompatibility } from '@opensip-cli/core';
35
+ // The `cli:` block loader (`loadCliDefaults` / `CliDefaults`) moved to
36
+ // `@opensip-cli/config` in ADR-0023 — its runtime YAML projection
37
+ // was the standing "contracts is types-only" charter violation. Importers now
38
+ // take it from the config layer.
39
+ // Command-plane types (launch, §5.4) — the declarative CommandSpec a
40
+ // tool exports for the host to mount, replacing raw-Commander access. DEFINED in
41
+ // @opensip-cli/core (beside the Tool contract; core cannot import contracts);
42
+ // re-exported here for the public Tool↔runner surface. `CommonFlagKey` is also
43
+ // re-exported from ./cli-flags (which now sources it from core) — both paths
44
+ // resolve to the same kernel type.
45
+ export { defineCommand, COMMON_FLAG_KEYS, RAW_STREAM_REASONS } from '@opensip-cli/core';
46
+ // Tool-scoped recipe-default resolution (ADR-0022). The pure resolver every
47
+ // tool uses to pick its recipe name from --recipe / <tool>.recipe / default.
48
+ export { resolveToolRecipeName, BUILTIN_DEFAULT_RECIPE } from './recipe-default.js';
49
+ // Cross-tool common-flag registry (ADR-0021). One source of truth for the flags
50
+ // every tool's run command shares; tools apply them via applyCommonFlags rather
51
+ // than re-declaring `--json`/`--cwd`/`--report-to`/… per tool.
52
+ export { commonFlags, applyCommonFlags, MANDATORY_COMMON_FLAGS } from './cli-flags.js';
53
+ // Verbose-detail builder (ADR-0021) — shared Signal[] → FindingGroup[] mapping
54
+ // for the tools' `verboseDetail` carrier (fit + sim; one source, not per-tool).
55
+ export { buildFindingGroups } from './verbose-detail.js';
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAcH,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAiE3D,wEAAwE;AACxE,yEAAyE;AACzE,iEAAiE;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,yEAAyE;AACzE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGzF,0EAA0E;AAC1E,iEAAiE;AACjE,uEAAuE;AACvE,0EAA0E;AAC1E,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAe3E,uEAAuE;AACvE,kEAAkE;AAClE,8EAA8E;AAC9E,iCAAiC;AAEjC,qEAAqE;AACrE,iFAAiF;AACjF,8EAA8E;AAC9E,+EAA+E;AAC/E,6EAA6E;AAC7E,mCAAmC;AACnC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAYxF,4EAA4E;AAC5E,6EAA6E;AAC7E,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGpF,gFAAgF;AAChF,gFAAgF;AAChF,+DAA+D;AAC/D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAGvF,+EAA+E;AAC/E,gFAAgF;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * recipe-default — resolve which recipe NAME a tool should use (ADR-0022).
3
+ *
4
+ * Recipes are tool-scoped: `fit`, `graph`, and `sim` each own a separate recipe
5
+ * registry with a disjoint namespace, so a default recipe is a per-tool setting.
6
+ * Each tool reads its own `<tool>.recipe` config block.
7
+ *
8
+ * This helper is pure — the caller supplies the two already-read inputs and
9
+ * gets back the chosen name plus a `tolerant` flag. Tolerance is the ADR-0022
10
+ * guardrail split: a name that came from CONFIG (`<tool>.recipe`) but is absent
11
+ * from the active tool's registry should
12
+ * fall back to the tool's built-in `default` rather than abort the run — the
13
+ * default may legitimately belong to a different tool. An EXPLICIT `--recipe`
14
+ * flag stays strict (`tolerant: false`) so a typo still hard-fails.
15
+ *
16
+ * Lives in contracts (not core, not a single tool) because all three tools
17
+ * consume it and it is part of the CLI↔tool config seam. Resolution precedence:
18
+ *
19
+ * explicit `--recipe` > `<tool>.recipe` > `default`
20
+ */
21
+ /** Where the resolved recipe name came from, in precedence order. */
22
+ export type RecipeSource = 'flag' | 'tool-config' | 'builtin';
23
+ /** Built-in recipe name every tool registers (all rules / all checks). */
24
+ export declare const BUILTIN_DEFAULT_RECIPE = "default";
25
+ /**
26
+ * The outcome of {@link resolveToolRecipeName}: the chosen recipe `name`, which
27
+ * input it came from (`source`), and whether an unknown `name` should be
28
+ * tolerated (fall back to the built-in default) or hard-fail.
29
+ */
30
+ export interface ResolvedRecipe {
31
+ /** The recipe name the tool should look up in its registry. */
32
+ readonly name: string;
33
+ /** Which input supplied {@link name}. */
34
+ readonly source: RecipeSource;
35
+ /**
36
+ * `false` only when `source === 'flag'`. When `true`, an unknown `name`
37
+ * should fall back to {@link BUILTIN_DEFAULT_RECIPE} with a warning instead
38
+ * of aborting — the name came from config and may target another tool.
39
+ */
40
+ readonly tolerant: boolean;
41
+ }
42
+ /**
43
+ * Resolve the recipe name for a tool from its three possible sources. See the
44
+ * module docstring for precedence and the tolerance contract (ADR-0022).
45
+ *
46
+ * @param input.explicit The `--recipe <name>` flag value (strict if present).
47
+ * @param input.toolRecipe The tool's own `<tool>.recipe` config default.
48
+ */
49
+ export declare function resolveToolRecipeName(input: {
50
+ readonly explicit?: string;
51
+ readonly toolRecipe?: string;
52
+ }): ResolvedRecipe;
53
+ //# sourceMappingURL=recipe-default.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipe-default.d.ts","sourceRoot":"","sources":["../src/recipe-default.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,qEAAqE;AACrE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,SAAS,CAAC;AAE9D,0EAA0E;AAC1E,eAAO,MAAM,sBAAsB,YAAY,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAOD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,cAAc,CAoBjB"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * recipe-default — resolve which recipe NAME a tool should use (ADR-0022).
3
+ *
4
+ * Recipes are tool-scoped: `fit`, `graph`, and `sim` each own a separate recipe
5
+ * registry with a disjoint namespace, so a default recipe is a per-tool setting.
6
+ * Each tool reads its own `<tool>.recipe` config block.
7
+ *
8
+ * This helper is pure — the caller supplies the two already-read inputs and
9
+ * gets back the chosen name plus a `tolerant` flag. Tolerance is the ADR-0022
10
+ * guardrail split: a name that came from CONFIG (`<tool>.recipe`) but is absent
11
+ * from the active tool's registry should
12
+ * fall back to the tool's built-in `default` rather than abort the run — the
13
+ * default may legitimately belong to a different tool. An EXPLICIT `--recipe`
14
+ * flag stays strict (`tolerant: false`) so a typo still hard-fails.
15
+ *
16
+ * Lives in contracts (not core, not a single tool) because all three tools
17
+ * consume it and it is part of the CLI↔tool config seam. Resolution precedence:
18
+ *
19
+ * explicit `--recipe` > `<tool>.recipe` > `default`
20
+ */
21
+ /** Built-in recipe name every tool registers (all rules / all checks). */
22
+ export const BUILTIN_DEFAULT_RECIPE = 'default';
23
+ /** A config value counts as "set" only when it is a non-empty string. */
24
+ function isSet(value) {
25
+ return value !== undefined && value !== '';
26
+ }
27
+ /**
28
+ * Resolve the recipe name for a tool from its three possible sources. See the
29
+ * module docstring for precedence and the tolerance contract (ADR-0022).
30
+ *
31
+ * @param input.explicit The `--recipe <name>` flag value (strict if present).
32
+ * @param input.toolRecipe The tool's own `<tool>.recipe` config default.
33
+ */
34
+ export function resolveToolRecipeName(input) {
35
+ if (isSet(input.explicit)) {
36
+ return {
37
+ name: input.explicit,
38
+ source: 'flag',
39
+ tolerant: false,
40
+ };
41
+ }
42
+ if (isSet(input.toolRecipe)) {
43
+ return {
44
+ name: input.toolRecipe,
45
+ source: 'tool-config',
46
+ tolerant: true,
47
+ };
48
+ }
49
+ return {
50
+ name: BUILTIN_DEFAULT_RECIPE,
51
+ source: 'builtin',
52
+ tolerant: true,
53
+ };
54
+ }
55
+ //# sourceMappingURL=recipe-default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipe-default.js","sourceRoot":"","sources":["../src/recipe-default.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAoBhD,yEAAyE;AACzE,SAAS,KAAK,CAAC,KAAyB;IACtC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAGrC;IACC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,QAAQ;YACpB,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,KAAK;SAChB,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,UAAU;YACtB,MAAM,EAAE,aAAa;YACrB,QAAQ,EAAE,IAAI;SACf,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,sBAAsB;QAC5B,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=recipe-default.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipe-default.test.d.ts","sourceRoot":"","sources":["../src/recipe-default.test.ts"],"names":[],"mappings":""}