@oprt/cli 0.1.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,37 +1,130 @@
1
- import { C as Command, a as Contract, R as Registry, b as RegistryEntry, A as AddOptions, I as InstallResult } from './read-8a9euzJx.js';
2
- export { c as CliError, d as ComponentDetail, D as DetailProp, e as IndexEntry, f as InstallFile, S as SearchResult, g as applyBlock, h as blockVersion, i as componentDetail, j as componentIndex, r as removeBlock, k as renderAgentBlock, l as renderComponent, s as search } from './read-8a9euzJx.js';
1
+ import { C as Contract, a as ComponentDetail, b as Command, R as Registry, c as RegistryEntry, A as AddOptions, I as InstallResult } from './read-C7rE5UlY.js';
2
+ export { d as CliError, D as DetailProp, e as IndexEntry, f as InstallFile, S as SearchResult, g as applyBlock, h as blockVersion, i as componentDetail, j as componentIndex, r as removeBlock, k as renderAgentBlock, l as renderComponent, s as search } from './read-C7rE5UlY.js';
3
3
 
4
- /** The envelope every `--json` answer comes in. `type` says what `data` holds. */
5
- interface Envelope {
6
- apiVersion: 1;
7
- type: string;
8
- data: unknown;
4
+ /** This program's version: the package's. The contract has its own (`Contract.version`). */
5
+ declare const VERSION: string;
6
+ /**
7
+ * The version of the result model: the envelope and the data of every `--json` answer and MCP
8
+ * structured result. It rises when a field is removed or changes meaning; adding a field does not
9
+ * raise it. The envelope's `apiVersion` is the same number, kept for the readers that branch on it.
10
+ */
11
+ declare const RESULT_SCHEMA_VERSION = 2;
12
+ interface Identity {
13
+ /** This program: the `@oprt/cli` package version. */
14
+ cli_version: string;
15
+ /** The contract it carries: the `@oprt/react` version the contract describes. */
16
+ contract_version: string;
17
+ /**
18
+ * `sha256:` and the hash of the contract as `dist/contract.json` holds it (the file's bytes, so
19
+ * `shasum -a 256 dist/contract.json` gives the same). Two answers with one digest read one contract.
20
+ */
21
+ contract_digest: string;
22
+ /** The result model's version. */
23
+ schema_version: number;
24
+ }
25
+ /** What an answer can say about itself when the contract could not be read. */
26
+ interface ErrorIdentity {
27
+ cli_version: string;
28
+ schema_version: number;
29
+ contract_version?: string;
30
+ contract_digest?: string;
31
+ }
32
+ /** The contract's digest. Computed once per contract: it is one hash of about 160 KB. */
33
+ declare function contractDigest(contract: Contract): string;
34
+ declare function identityOf(contract: Contract): Identity;
35
+
36
+ /** Where the parser came from, for a person or an agent deciding whether to trust the answer. */
37
+ interface ParserInfo {
38
+ name: "@babel/parser";
39
+ version: string;
40
+ /** `bundled`: it ships inside oprt (dist/babel-parser.cjs), so there is nothing to install. */
41
+ source: "bundled";
42
+ }
43
+ /** Why checking cannot run, as a stable word. */
44
+ type ParserBlock = "parser_missing" | "parser_unusable";
45
+ type ParserProbe = {
46
+ ready: true;
47
+ parser: ParserInfo;
48
+ } | {
49
+ ready: false;
50
+ reason: ParserBlock;
51
+ detail: string;
52
+ };
53
+
54
+ declare const RESULT_TYPES: readonly ["check", "search", "component.detail", "component.batch", "component.list", "init", "doctor", "add", "list", "instructions"];
55
+ type ResultType = (typeof RESULT_TYPES)[number];
56
+ /** The envelope every `--json` answer and every structured tool result comes in. */
57
+ interface Envelope<T = unknown> {
58
+ /** The result model's version (same number as `identity.schema_version`), for readers that branch on it. */
59
+ apiVersion: typeof RESULT_SCHEMA_VERSION;
60
+ /** What `data` holds. */
61
+ type: ResultType;
62
+ identity: Identity;
63
+ data: T;
64
+ }
65
+ /** What a failure comes in. `code` is stable and only ever added to. */
66
+ interface ErrorEnvelope {
67
+ apiVersion: typeof RESULT_SCHEMA_VERSION;
68
+ error: string;
69
+ code: string;
70
+ suggestions?: string[];
71
+ identity: ErrorIdentity;
9
72
  }
73
+ declare const envelope: <T>(type: ResultType, data: T, contract: Contract) => Envelope<T>;
74
+ /**
75
+ * A failure as the model carries it. The contract is optional: a failure can come before the
76
+ * contract was read, and the answer still says which program it came from.
77
+ */
78
+ declare function errorEnvelope(error: unknown, contract?: Contract): ErrorEnvelope;
79
+ type ComponentDetailData = Omit<ComponentDetail, "description"> & {
80
+ /** Absent from the compact form. */
81
+ description?: string;
82
+ /** True for the compact form: no component description, one sentence per prop. */
83
+ dense: boolean;
84
+ };
85
+ type Schema = Record<string, unknown>;
86
+ /** The schema of one kind of answer: `schemaFor("check")`, or `schemaFor("error")` for a failure. */
87
+ declare function schemaFor(type: ResultType | "error"): Schema;
88
+ /**
89
+ * The schema an MCP tool declares as its `outputSchema`: one object that is either the answer for
90
+ * its type (`type` and `data`) or the failure (`error` and `code`), since a tool that could not
91
+ * run returns the failure in the same place, and the client checks structured content whether or
92
+ * not the call failed. One object with two ways to be complete is smaller than two schemas under
93
+ * `anyOf`, which repeated the envelope in every tool.
94
+ */
95
+ declare function outputSchemaFor(type: ResultType): Schema;
96
+ /** Every schema, by name: what the library exports for a client that wants to check an answer. */
97
+ declare const RESULT_SCHEMAS: Readonly<Record<ResultType | "error", Schema>>;
98
+
10
99
  interface Answer {
11
100
  /** What a person reads. */
12
101
  text: string;
13
- /** What `--json` prints. */
102
+ /** What `--json` prints: the result model, the same object an MCP tool returns. */
14
103
  json: Envelope;
15
104
  exitCode: number;
16
105
  }
17
106
  type AgentCommand = Extract<Command, {
18
- command: "component" | "search" | "init" | "doctor" | "check";
107
+ command: "component" | "search" | "init" | "doctor" | "check" | "list" | "add";
19
108
  }>;
20
- /** Runs one of the commands an agent reads the contract with, and returns both forms of the answer. */
109
+ /**
110
+ * Runs one of the commands that answers with data, and returns both forms of the answer: the text a
111
+ * person reads and the envelope `--json` prints. The MCP server builds its structured results from
112
+ * the same functions, so the two cannot disagree.
113
+ */
21
114
  declare function runAgentCommand(command: AgentCommand, context: {
22
115
  cwd: string;
23
116
  contract: Contract;
24
117
  registry: Registry;
118
+ /** For doctor: the parser probe to report, when the caller already has it. */
119
+ parser?: ParserProbe;
25
120
  }): Answer;
26
121
 
27
- /**
28
- * The `typescript` module as the project has it. It is opaque in the installer's own types, so
29
- * that using those types does not require TypeScript to be installed.
30
- */
31
- type TypeScript = object;
122
+ /** Every code a finding can carry. Stable, and only ever added to: branch on these, not on messages. */
123
+ declare const FINDING_CODES: readonly ["INVALID_PROP_VALUE", "UNKNOWN_EXPORT", "DOT_NOTATION", "INVALID_NESTING", "INVALID_CHILD", "MISSING_REQUIRED_PROP", "UNKNOWN_PROP", "RAW_COLOR", "ARBITRARY_SIZE", "ROUNDED_CORNER", "NATIVE_CONTROL", "SYNTAX_ERROR"];
124
+ declare const LIMITATION_CODES: readonly ["UNRESOLVED_SPREAD", "UNRESOLVED_VALUE"];
32
125
  interface Finding {
33
126
  /** Stable, and only ever added to. Branch on this, not on the message. */
34
- code: "INVALID_PROP_VALUE" | "UNKNOWN_EXPORT" | "DOT_NOTATION" | "INVALID_NESTING" | "INVALID_CHILD" | "MISSING_REQUIRED_PROP" | "UNKNOWN_PROP" | "RAW_COLOR" | "ARBITRARY_SIZE" | "ROUNDED_CORNER" | "NATIVE_CONTROL";
127
+ code: (typeof FINDING_CODES)[number];
35
128
  /** An error breaks the contract. A warning breaks a house rule, or may be a native attribute. */
36
129
  severity: "error" | "warning";
37
130
  file: string;
@@ -43,26 +136,106 @@ interface Finding {
43
136
  valid_values?: string[];
44
137
  suggestions?: string[];
45
138
  }
139
+ /**
140
+ * Something the check could not read, so it did not judge it. Recorded with its place, never
141
+ * guessed: the code may be right or wrong there, and this says only that it was not looked at.
142
+ */
143
+ interface Limitation {
144
+ /** Stable, and only ever added to. */
145
+ code: (typeof LIMITATION_CODES)[number];
146
+ file: string;
147
+ line: number;
148
+ column: number;
149
+ component: string;
150
+ prop?: string;
151
+ message: string;
152
+ }
153
+ /**
154
+ * What happened to one file. `evaluated`: read in full. `partial`: checked, with limits the
155
+ * report records. `not_evaluated`: it does not parse, so nothing about the contract was checked.
156
+ */
157
+ interface SourceEvaluation {
158
+ file: string;
159
+ status: "evaluated" | "partial" | "not_evaluated";
160
+ findings: Finding[];
161
+ limitations: Limitation[];
162
+ }
163
+ type EvaluationStatus = "evaluated_clean" | "evaluated_with_findings" | "partially_evaluated" | "not_evaluated" | "no_files_evaluated";
164
+ /** An input that was named but not read, and why. */
165
+ interface SkippedInput {
166
+ path: string;
167
+ reason: "unsupported_extension" | "test_or_story_file" | "excluded_folder";
168
+ }
46
169
  interface CheckReport {
47
- /** How many files were read. */
170
+ /**
171
+ * `evaluated_clean` means every file was read in full and nothing was found. Anything less is
172
+ * named: findings, limits, files that did not parse, or no file read at all.
173
+ */
174
+ evaluation_status: EvaluationStatus;
175
+ /** How many files were read (found and opened). */
48
176
  files: number;
49
177
  findings: Finding[];
50
178
  summary: {
51
179
  errors: number;
52
180
  warnings: number;
53
181
  };
182
+ coverage: {
183
+ files_found: number;
184
+ /** Parsed and checked, including those with limits. */
185
+ files_evaluated: number;
186
+ /** Of those evaluated, the ones with a limit. */
187
+ files_partial: number;
188
+ /** Did not parse. */
189
+ files_not_evaluated: number;
190
+ };
191
+ /** Everything that was not read, each with its place. Empty only when nothing was skipped over. */
192
+ limitations: Limitation[];
193
+ /** Inputs that were named and not read, with the reason. */
194
+ skipped_inputs: SkippedInput[];
195
+ /** What this check covers, and what it leaves to other tools. The same on every run. */
196
+ scope: {
197
+ checked: string[];
198
+ not_checked: string[];
199
+ };
200
+ parser: ParserInfo;
54
201
  }
55
- /** Check one file's source. `file` is only the name the findings carry. */
56
- declare function checkSource(typescript: TypeScript, contract: Contract, file: string, text: string): Finding[];
57
202
  /**
58
- * Check every .tsx and .jsx file under the given paths. `typescript` is found in the project when
59
- * it is not passed; null stands for "there is none".
203
+ * Check one file's source. `file` is only the name the findings carry (and, by its extension, the
204
+ * dialect: `.tsx` is read as TypeScript, anything else as JavaScript). A file that does not parse
205
+ * is not checked at all (`not_evaluated`, with the syntax errors as findings): what a parser
206
+ * recovers from broken code is a guess, and the contract is not judged on a guess.
207
+ */
208
+ declare function checkSource(contract: Contract, file: string, text: string): SourceEvaluation;
209
+ /**
210
+ * The report for a set of evaluated files. The status is `evaluated_clean` only when every file
211
+ * was read in full and nothing was found; everything short of that has its own name.
212
+ */
213
+ declare function buildCheckReport(evaluations: readonly SourceEvaluation[], context?: {
214
+ parser?: ParserInfo;
215
+ skipped?: SkippedInput[];
216
+ }): CheckReport;
217
+ /**
218
+ * The exit code of `oprt check`. 0: every file that was read has no errors (and, when strict, no
219
+ * warnings); limits are shown and do not fail the run. 1: an error was found, a file did not
220
+ * parse, or no file was read at all (nothing was checked, which is not a pass). Usage mistakes
221
+ * and a path that is not there exit 2, and a parser that cannot be loaded exits 1, before any report.
222
+ */
223
+ declare function checkExitCode(report: CheckReport, { strict }: {
224
+ strict: boolean;
225
+ }): number;
226
+ /**
227
+ * Check every .tsx and .jsx file under the given paths, with the parser that ships inside oprt.
228
+ * Fails with a code when that parser cannot be loaded, rather than answering without it.
60
229
  */
61
230
  declare function checkPaths(paths: string[], context: {
62
231
  cwd: string;
63
232
  contract: Contract;
64
- typescript?: TypeScript | null;
65
233
  }): CheckReport;
234
+ /**
235
+ * A check as text, for a terminal or a tool result. Findings first, then the limits, then one
236
+ * line that says how much was read: the same words the JSON status carries.
237
+ */
238
+ declare function renderCheckText(report: CheckReport): string;
66
239
 
67
240
  interface DoctorCheck {
68
241
  id: string;
@@ -70,7 +243,32 @@ interface DoctorCheck {
70
243
  message: string;
71
244
  fix?: string;
72
245
  }
246
+ /**
247
+ * Whether one thing oprt does can run here. Lookups (search, component, list) read the contract
248
+ * that ships inside oprt, so they always can. Checking code needs a parser, which also ships inside
249
+ * oprt (Babel's): it needs nothing from the project, and is blocked only if that file is missing
250
+ * or fails a probe, with the reason as a word.
251
+ */
252
+ interface DoctorOperations {
253
+ lookup: {
254
+ status: "ready";
255
+ message: string;
256
+ contract_version: string;
257
+ };
258
+ check_code: {
259
+ status: "ready" | "blocked";
260
+ message: string;
261
+ reason?: ParserBlock;
262
+ fix?: string;
263
+ /** The parser that checking reads code with, when it is ready. */
264
+ parser?: ParserInfo;
265
+ };
266
+ }
73
267
  interface DoctorReport {
268
+ /** The directory every answer here is about: where the project's packages are looked for. */
269
+ consumer_directory: string;
270
+ /** What can run here, one operation at a time. */
271
+ operations: DoctorOperations;
74
272
  checks: DoctorCheck[];
75
273
  summary: {
76
274
  ok: number;
@@ -78,90 +276,46 @@ interface DoctorReport {
78
276
  fail: number;
79
277
  };
80
278
  }
81
- declare function doctor({ cwd, contract }: {
279
+ declare function doctor({ cwd, contract, parser, }: {
82
280
  cwd: string;
83
281
  contract: Contract;
282
+ /** What probing the parser found. Probed here when it is not passed. */
283
+ parser?: ParserProbe;
84
284
  }): DoctorReport;
85
285
 
286
+ interface InputSchema {
287
+ type: "object";
288
+ properties: Record<string, PropertySchema>;
289
+ required?: string[];
290
+ additionalProperties?: boolean;
291
+ description?: string;
292
+ }
293
+ interface PropertySchema {
294
+ type: "string" | "number" | "integer" | "boolean";
295
+ description?: string;
296
+ default?: unknown;
297
+ enum?: unknown[];
298
+ minimum?: number;
299
+ maximum?: number;
300
+ minLength?: number;
301
+ maxLength?: number;
302
+ }
303
+
86
304
  interface McpContext {
87
305
  contract: Contract;
88
306
  registry: Registry;
89
- /** For check_code. Found beside the project or the installer when it is not passed. */
90
- typescript?: TypeScript | null;
91
- cwd?: string;
92
307
  }
93
- declare const TOOLS: ({
308
+ interface ToolDefinition {
94
309
  name: string;
95
310
  description: string;
96
- inputSchema: {
97
- type: string;
98
- properties: {
99
- query: {
100
- type: string;
101
- description: string;
102
- };
103
- limit: {
104
- type: string;
105
- description: string;
106
- };
107
- name?: never;
108
- dense?: never;
109
- code?: never;
110
- };
111
- required: string[];
311
+ inputSchema: InputSchema;
312
+ /** The result model for this tool's answers; a failure comes in the same place. */
313
+ outputSchema: object;
314
+ annotations: {
315
+ readOnlyHint: true;
112
316
  };
113
- } | {
114
- name: string;
115
- description: string;
116
- inputSchema: {
117
- type: string;
118
- properties: {
119
- name: {
120
- type: string;
121
- description: string;
122
- };
123
- dense: {
124
- type: string;
125
- description: string;
126
- };
127
- query?: never;
128
- limit?: never;
129
- code?: never;
130
- };
131
- required: string[];
132
- };
133
- } | {
134
- name: string;
135
- description: string;
136
- inputSchema: {
137
- type: string;
138
- properties: {
139
- query?: never;
140
- limit?: never;
141
- name?: never;
142
- dense?: never;
143
- code?: never;
144
- };
145
- required?: never;
146
- };
147
- } | {
148
- name: string;
149
- description: string;
150
- inputSchema: {
151
- type: string;
152
- properties: {
153
- code: {
154
- type: string;
155
- description: string;
156
- };
157
- query?: never;
158
- limit?: never;
159
- name?: never;
160
- dense?: never;
161
- };
162
- required: string[];
163
- };
164
- })[];
317
+ }
318
+ declare const TOOLS: readonly ToolDefinition[];
165
319
  /**
166
320
  * Answer one message. Returns the response to write, or null for a notification, which gets none.
167
321
  * `raw` is a parsed message, or the line itself when it could not be parsed.
@@ -197,7 +351,6 @@ declare function parseArgs(args: string[]): Command;
197
351
 
198
352
  declare function resolveEntries(names: string[], registry: Registry): RegistryEntry[];
199
353
 
200
- declare const VERSION: string;
201
354
  declare const registry: Registry;
202
355
  /** The contract this installer carries, read from beside it the first time it is asked for. */
203
356
  declare const contract: () => Contract;
@@ -208,4 +361,4 @@ declare function install(options: AddOptions, context?: {
208
361
  registry?: Registry;
209
362
  }): InstallResult;
210
363
 
211
- export { AddOptions, type Answer, type CheckReport, Command, Contract, DEFAULT_OUT, type DoctorCheck, type DoctorReport, type Envelope, type Finding, type InitFile, type InitOptions, type InitResult, InstallResult, type McpContext, Registry, RegistryEntry, TOOLS, type TypeScript, VERSION, checkPaths, checkSource, contract, doctor, handleMessage, init, install, parseArgs, registry, resolveEntries, runAgentCommand, serve };
364
+ export { AddOptions, type Answer, type CheckReport, Command, ComponentDetail, type ComponentDetailData, Contract, DEFAULT_OUT, type DoctorCheck, type DoctorReport, type Envelope, type ErrorEnvelope, type ErrorIdentity, type EvaluationStatus, type Finding, type Identity, type InitFile, type InitOptions, type InitResult, InstallResult, type Limitation, type McpContext, type ParserInfo, RESULT_SCHEMAS, RESULT_SCHEMA_VERSION, RESULT_TYPES, Registry, RegistryEntry, type ResultType, type SkippedInput, type SourceEvaluation, TOOLS, VERSION, buildCheckReport, checkExitCode, checkPaths, checkSource, contract, contractDigest, doctor, envelope, errorEnvelope, handleMessage, identityOf, init, install, outputSchemaFor, parseArgs, registry, renderCheckText, resolveEntries, runAgentCommand, schemaFor, serve };