me2lon 0.0.0-stage → 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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -2
  3. package/dist/api.d.ts +35 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +286 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/cli.d.ts +4 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +261 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/client.d.ts +23 -0
  12. package/dist/client.d.ts.map +1 -0
  13. package/dist/client.js +272 -0
  14. package/dist/client.js.map +1 -0
  15. package/dist/config.d.ts +19 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +173 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/errors.d.ts +14 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +31 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/index.d.ts +8 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +8 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/presentation.d.ts +12 -0
  28. package/dist/presentation.d.ts.map +1 -0
  29. package/dist/presentation.js +50 -0
  30. package/dist/presentation.js.map +1 -0
  31. package/dist/safe-output.d.ts +20 -0
  32. package/dist/safe-output.d.ts.map +1 -0
  33. package/dist/safe-output.js +770 -0
  34. package/dist/safe-output.js.map +1 -0
  35. package/dist/setup.d.ts +14 -0
  36. package/dist/setup.d.ts.map +1 -0
  37. package/dist/setup.js +92 -0
  38. package/dist/setup.js.map +1 -0
  39. package/dist/skill.d.ts +2 -0
  40. package/dist/skill.d.ts.map +1 -0
  41. package/dist/skill.js +30 -0
  42. package/dist/skill.js.map +1 -0
  43. package/dist/types.d.ts +76 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +8 -0
  46. package/dist/types.js.map +1 -0
  47. package/dist/workspace-source.d.ts +11 -0
  48. package/dist/workspace-source.d.ts.map +1 -0
  49. package/dist/workspace-source.js +387 -0
  50. package/dist/workspace-source.js.map +1 -0
  51. package/package.json +43 -4
  52. package/skill/LICENSE +21 -0
  53. package/skill/SKILL.md +18 -0
  54. package/src/api.ts +426 -0
  55. package/src/cli.ts +305 -0
  56. package/src/client.ts +413 -0
  57. package/src/config.ts +252 -0
  58. package/src/errors.ts +40 -0
  59. package/src/index.ts +37 -0
  60. package/src/presentation.ts +39 -0
  61. package/src/safe-output.ts +826 -0
  62. package/src/setup.ts +95 -0
  63. package/src/skill.ts +22 -0
  64. package/src/types.ts +85 -0
  65. package/src/workspace-source.ts +526 -0
  66. package/tsconfig.build.json +18 -0
  67. package/tsconfig.json +14 -0
@@ -0,0 +1,770 @@
1
+ import { Me2lonClientError } from "./errors.js";
2
+ const forbiddenKeyPattern = /^(?:authorization|cookie|token|secret|source|sources|sourcecode|sourcecontent|sourcebody|sourceexcerpt|sourcetext|sourcefile|sourcefiles|content|contents|filecontent|filecontents|requestbody|responsebody|changes|replacements|patch|difftext|generatedrocq|generatedrocqsource|generatedsource|rocqsource|proof|prooftext|proofbody|proofsource|artifact|artifacts|artifactbody|artifactcontent)$/iu;
3
+ const identifierPattern = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,511}$/u;
4
+ function record(value) {
5
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
6
+ return undefined;
7
+ }
8
+ return value;
9
+ }
10
+ function unwrap(raw, preferred = []) {
11
+ for (const key of [...preferred, "data"]) {
12
+ const nested = record(raw[key]);
13
+ if (nested) {
14
+ return nested;
15
+ }
16
+ }
17
+ return raw;
18
+ }
19
+ function safeString(value, maximum = 8_192) {
20
+ return typeof value === "string" ? value.slice(0, maximum) : undefined;
21
+ }
22
+ function safeScalar(value) {
23
+ if (value === null ||
24
+ typeof value === "string" ||
25
+ typeof value === "boolean" ||
26
+ (typeof value === "number" && Number.isFinite(value))) {
27
+ return typeof value === "string" ? value.slice(0, 8_192) : value;
28
+ }
29
+ return undefined;
30
+ }
31
+ function selectedFields(input, names) {
32
+ const output = {};
33
+ for (const name of names) {
34
+ const value = safeScalar(input[name]);
35
+ if (value !== undefined) {
36
+ output[name] = value;
37
+ }
38
+ }
39
+ return output;
40
+ }
41
+ function safeStructured(value, depth = 0, policyData = false) {
42
+ if (depth > 8) {
43
+ return undefined;
44
+ }
45
+ const scalar = safeScalar(value);
46
+ if (scalar !== undefined) {
47
+ return scalar;
48
+ }
49
+ if (Array.isArray(value)) {
50
+ return value
51
+ .slice(0, 1_000)
52
+ .map((item) => safeStructured(item, depth + 1, policyData))
53
+ .filter((item) => item !== undefined);
54
+ }
55
+ const input = record(value);
56
+ if (!input) {
57
+ return undefined;
58
+ }
59
+ const output = {};
60
+ for (const [key, item] of Object.entries(input).slice(0, 250)) {
61
+ if (forbiddenKeyPattern.test(key)) {
62
+ continue;
63
+ }
64
+ if (!policyData && !/^(?:count|total|passed|failed|skipped|covered|percent|percentage|current|maximum|max|limit|maxChanges|maxFileBytes|maxTotalBytes|maxProjects|maxJobs|name|id|kind|status|code|severity|category|ruleId|digest|version|versions|framework|language|supported|enabled|value|label)$/u.test(key)) {
65
+ continue;
66
+ }
67
+ const safe = safeStructured(item, depth + 1, policyData);
68
+ if (safe !== undefined) {
69
+ output[key] = safe;
70
+ }
71
+ }
72
+ return output;
73
+ }
74
+ export function requireResourceId(raw, preferredContainers, idNames) {
75
+ const candidates = [raw, unwrap(raw, preferredContainers)];
76
+ const data = record(raw.data);
77
+ if (data) {
78
+ candidates.push(data);
79
+ for (const container of preferredContainers) {
80
+ const nested = record(data[container]);
81
+ if (nested) {
82
+ candidates.push(nested);
83
+ }
84
+ }
85
+ }
86
+ for (const candidate of candidates) {
87
+ for (const idName of idNames) {
88
+ const id = candidate[idName];
89
+ if (typeof id === "string" && identifierPattern.test(id)) {
90
+ return id;
91
+ }
92
+ if (typeof id === "number" && Number.isSafeInteger(id) && id >= 0) {
93
+ return String(id);
94
+ }
95
+ }
96
+ }
97
+ throw new Me2lonClientError("ME2LON_API_RESPONSE_INVALID", "The Me2lon API response did not include the expected resource id.");
98
+ }
99
+ export function projectCapabilities(raw, repository) {
100
+ const input = unwrap(raw, ["capabilities"]);
101
+ const output = selectedFields(input, [
102
+ "schemaVersion",
103
+ "apiVersion",
104
+ "version",
105
+ "status",
106
+ "service",
107
+ "brand",
108
+ "profile",
109
+ ]);
110
+ const source = record(input.source);
111
+ if (source) {
112
+ const sourceContract = selectedFields(source, [
113
+ "schemaVersion",
114
+ "baseRevision",
115
+ "snapshotBaseRevision",
116
+ ]);
117
+ const operations = stringArray(source.operations, 32);
118
+ if (operations !== undefined)
119
+ sourceContract.operations = operations;
120
+ const encodings = stringArray(source.encodings, 32);
121
+ if (encodings !== undefined)
122
+ sourceContract.encodings = encodings;
123
+ const supportedSchemas = stringArray(source.supportedSchemas, 8);
124
+ if (supportedSchemas !== undefined)
125
+ sourceContract.supportedSchemas = supportedSchemas;
126
+ output.sourceContract = sourceContract;
127
+ }
128
+ const limits = record(input.limits);
129
+ const sourceLimits = record(limits?.source);
130
+ if (sourceLimits) {
131
+ output.sourceLimits = selectedFields(sourceLimits, [
132
+ "maxChanges",
133
+ "maxFileBytes",
134
+ "maxTotalBytes",
135
+ "maxRetainedRevisions",
136
+ "maxRetainedBytes",
137
+ ]);
138
+ }
139
+ const translation = record(input.translation);
140
+ if (translation) {
141
+ output.translation = selectedFields(translation, [
142
+ "generatedRocqVisible",
143
+ "receiptOnly",
144
+ ]);
145
+ }
146
+ const policy = record(input.policy);
147
+ if (policy) {
148
+ output.policy = selectedFields(policy, [
149
+ "format",
150
+ "approvalRequiresCompleteCoverage",
151
+ "agentMayApprove",
152
+ ]);
153
+ }
154
+ const scopes = stringArray(input.scopes, 128);
155
+ if (scopes !== undefined)
156
+ output.scopes = scopes;
157
+ const supportedScopes = stringArray(input.supportedScopes, 128);
158
+ if (supportedScopes !== undefined)
159
+ output.supportedScopes = supportedScopes;
160
+ for (const key of [
161
+ "capabilities",
162
+ "jobKinds",
163
+ "sourceSchemaVersions",
164
+ "supportedFrameworks",
165
+ "supportedPolicyLanguages",
166
+ ]) {
167
+ const safe = safeStructured(input[key]);
168
+ if (safe !== undefined) {
169
+ output[key] = safe;
170
+ }
171
+ }
172
+ output.repositoryAuthorized = Boolean(repository);
173
+ if (repository) {
174
+ output.repository = selectedFields(repository, [
175
+ "id",
176
+ "repositoryId",
177
+ "name",
178
+ "fullName",
179
+ "provider",
180
+ "defaultBranch",
181
+ ]);
182
+ }
183
+ return output;
184
+ }
185
+ function diagnostic(value) {
186
+ const input = record(value);
187
+ if (!input) {
188
+ return undefined;
189
+ }
190
+ const output = selectedFields(input, [
191
+ "id",
192
+ "code",
193
+ "ruleId",
194
+ "kind",
195
+ "sourceRole",
196
+ "chapter",
197
+ "severity",
198
+ "category",
199
+ "message",
200
+ "detail",
201
+ "suggestion",
202
+ "path",
203
+ "line",
204
+ "column",
205
+ "endLine",
206
+ "endColumn",
207
+ "helpUrl",
208
+ "status",
209
+ ]);
210
+ for (const key of ["start", "end"]) {
211
+ const location = record(input[key]);
212
+ if (location) {
213
+ const safe = selectedFields(location, ["line", "column"]);
214
+ if (Object.keys(safe).length > 0) {
215
+ output[key] = safe;
216
+ }
217
+ }
218
+ }
219
+ return Object.keys(output).length > 0 ? output : undefined;
220
+ }
221
+ function stringArray(value, maximum = 1_000) {
222
+ if (!Array.isArray(value))
223
+ return undefined;
224
+ return value
225
+ .slice(0, maximum)
226
+ .map((item) => safeString(item, 16_384))
227
+ .filter((item) => item !== undefined);
228
+ }
229
+ function projectedObjects(value, projector, maximum = 1_000) {
230
+ if (!Array.isArray(value))
231
+ return undefined;
232
+ return value
233
+ .slice(0, maximum)
234
+ .map(projector)
235
+ .filter((item) => item !== undefined);
236
+ }
237
+ function checkProject(value) {
238
+ const input = record(value);
239
+ if (!input)
240
+ return undefined;
241
+ const output = selectedFields(input, [
242
+ "id", "root", "name",
243
+ "projectId",
244
+ "completeContext",
245
+ "excludedInScopeFiles",
246
+ "filesChecked",
247
+ "diagnosticCount",
248
+ "workflowReadiness",
249
+ "workflowLimitationCount",
250
+ ]);
251
+ const eligibility = record(input.translationEligibility);
252
+ if (eligibility)
253
+ output.translationEligibility = {
254
+ ...selectedFields(eligibility, ["status"]),
255
+ blockers: stringArray(eligibility.blockers, 32) ?? [],
256
+ };
257
+ return Object.keys(output).length > 0 ? output : undefined;
258
+ }
259
+ function checkerProject(value) {
260
+ const input = record(value);
261
+ if (!input)
262
+ return undefined;
263
+ const output = selectedFields(input, ["schemaVersion", "projectId"]);
264
+ const context = record(input.context);
265
+ if (context) {
266
+ output.context = selectedFields(context, [
267
+ "status",
268
+ "prismaPreparation",
269
+ "limitation",
270
+ ]);
271
+ }
272
+ const scope = record(input.scope);
273
+ if (scope) {
274
+ output.scope = selectedFields(scope, [
275
+ "eligibleFiles",
276
+ "filesChecked",
277
+ "tsxFilesExcluded",
278
+ "applicationFilesChecked",
279
+ "testFilesChecked",
280
+ "toolingFilesChecked",
281
+ ]);
282
+ }
283
+ const summary = record(input.summary);
284
+ if (summary) {
285
+ const safeSummary = selectedFields(summary, ["rawDiagnostics", "uniqueSites"]);
286
+ for (const key of ["byChapter", "byCategory"]) {
287
+ const counts = safeStructured(summary[key]);
288
+ if (counts !== undefined)
289
+ safeSummary[key] = counts;
290
+ }
291
+ output.summary = safeSummary;
292
+ }
293
+ const readiness = record(input.workflowReadiness);
294
+ if (readiness) {
295
+ const safeReadiness = selectedFields(readiness, [
296
+ "route",
297
+ "status",
298
+ "blockingDiagnosticCount",
299
+ ]);
300
+ const limitations = projectedObjects(readiness.limitations, (value) => {
301
+ const limitation = record(value);
302
+ if (!limitation)
303
+ return undefined;
304
+ const projected = selectedFields(limitation, [
305
+ "code",
306
+ "capability",
307
+ "message",
308
+ "detail",
309
+ "suggestion",
310
+ "path",
311
+ ]);
312
+ for (const key of ["start", "end"]) {
313
+ const location = record(limitation[key]);
314
+ if (location)
315
+ projected[key] = selectedFields(location, ["line", "column"]);
316
+ }
317
+ return Object.keys(projected).length > 0 ? projected : undefined;
318
+ }, 1_000);
319
+ if (limitations !== undefined)
320
+ safeReadiness.limitations = limitations;
321
+ output.workflowReadiness = safeReadiness;
322
+ }
323
+ return Object.keys(output).length > 0 ? output : undefined;
324
+ }
325
+ function propertyEvidence(value) {
326
+ const input = record(value);
327
+ if (!input)
328
+ return undefined;
329
+ const output = selectedFields(input, [
330
+ "propertyId",
331
+ "projectId",
332
+ "specificationOrigin",
333
+ "resultResolution",
334
+ "title",
335
+ "status",
336
+ "claimScope",
337
+ "evidenceMethod",
338
+ "evidenceClass",
339
+ ]);
340
+ const formalAttempt = record(input.formalAttempt);
341
+ if (formalAttempt) {
342
+ output.formalAttempt = selectedFields(formalAttempt, ["status", "reason"]);
343
+ }
344
+ const rationale = record(input.rationale);
345
+ if (rationale) {
346
+ output.rationale = {
347
+ ...selectedFields(rationale, ["summary", "conclusion"]),
348
+ steps: projectedObjects(rationale.steps, (value) => {
349
+ const step = record(value);
350
+ return step ? selectedFields(step, ["text"]) : undefined;
351
+ }, 64) ?? [],
352
+ };
353
+ }
354
+ else if (input.rationale === null)
355
+ output.rationale = null;
356
+ const limitations = stringArray(input.limitations, 256);
357
+ if (limitations !== undefined)
358
+ output.limitations = limitations;
359
+ return Object.keys(output).length > 0 ? output : undefined;
360
+ }
361
+ function routePolicy(value) {
362
+ const input = record(value);
363
+ if (!input)
364
+ return undefined;
365
+ const output = selectedFields(input, [
366
+ "schemaVersion",
367
+ "sourceIdentity",
368
+ "projectId",
369
+ "evidenceClass",
370
+ "routeCount",
371
+ "routesTruncated",
372
+ ]);
373
+ const policy = record(input.policy);
374
+ if (policy) {
375
+ output.policy = selectedFields(policy, [
376
+ "policyId",
377
+ "languageVersion",
378
+ "declaredReviewStatus",
379
+ "approvalStatus",
380
+ ]);
381
+ }
382
+ else if (input.policy === null) {
383
+ output.policy = null;
384
+ }
385
+ const coverage = record(input.coverage);
386
+ if (coverage) {
387
+ output.coverage = selectedFields(coverage, [
388
+ "totalRoutes",
389
+ "analyzedRoutes",
390
+ "limitedRoutes",
391
+ "blockedRoutes",
392
+ ]);
393
+ }
394
+ const routes = projectedObjects(input.routes, (routeValue) => {
395
+ const route = record(routeValue);
396
+ if (!route)
397
+ return undefined;
398
+ const safeRoute = selectedFields(route, [
399
+ "routeId",
400
+ "path",
401
+ "handler",
402
+ "analysisBasis",
403
+ "operationBinding",
404
+ "assessment",
405
+ "explanation",
406
+ ]);
407
+ for (const key of [
408
+ "methods",
409
+ "reachablePrismaOperationIds",
410
+ "relevantPolicyRuleIds",
411
+ "limitations",
412
+ ]) {
413
+ const values = stringArray(route[key], 10_000);
414
+ if (values !== undefined)
415
+ safeRoute[key] = values;
416
+ }
417
+ const formalEvidence = record(route.formalEvidence);
418
+ if (formalEvidence) {
419
+ safeRoute.formalEvidence = selectedFields(formalEvidence, [
420
+ "status",
421
+ "digest",
422
+ "evidenceClass",
423
+ ]);
424
+ }
425
+ return Object.keys(safeRoute).length > 0 ? safeRoute : undefined;
426
+ }, 100_000);
427
+ if (routes !== undefined)
428
+ output.routes = routes;
429
+ return Object.keys(output).length > 0 ? output : undefined;
430
+ }
431
+ function projectDiagnostics(value) {
432
+ const input = record(value);
433
+ if (!input)
434
+ return {};
435
+ const rawItems = Array.isArray(input.items)
436
+ ? input.items
437
+ : Array.isArray(input.diagnostics)
438
+ ? input.diagnostics
439
+ : [];
440
+ const diagnostics = rawItems
441
+ .slice(0, 2_000)
442
+ .map(diagnostic)
443
+ .filter((item) => item !== undefined);
444
+ const output = { diagnostics };
445
+ const total = safeScalar(input.total);
446
+ if (total !== undefined)
447
+ output.diagnosticsTotal = total;
448
+ output.diagnosticsReturned = diagnostics.length;
449
+ const nextCursor = safeScalar(input.nextCursor);
450
+ if (nextCursor !== undefined)
451
+ output.diagnosticsNextCursor = nextCursor;
452
+ if (typeof input.truncated === "boolean") {
453
+ output.diagnosticsTruncated = input.truncated;
454
+ }
455
+ return output;
456
+ }
457
+ export function projectJob(raw, diagnosticsResponse) {
458
+ const input = unwrap(raw, ["job", "checkJob", "translationJob", "verificationJob"]);
459
+ const output = selectedFields(input, [
460
+ "schemaVersion",
461
+ "id",
462
+ "jobId",
463
+ "kind",
464
+ "type",
465
+ "status",
466
+ "outcome",
467
+ "createdAt",
468
+ "requestedAt",
469
+ "startedAt",
470
+ "completedAt",
471
+ "finishedAt",
472
+ "cancelledAt",
473
+ "canceledAt",
474
+ "workspaceId",
475
+ "workspaceRevisionId",
476
+ "checkJobId",
477
+ "translationJobId",
478
+ "projectId",
479
+ "policySetDigest",
480
+ "expectedPolicySetDigest",
481
+ "resultDigest",
482
+ "summary",
483
+ "sourceIdentity",
484
+ ]);
485
+ output.jobStatus = safeScalar(input.status) ?? null;
486
+ const result = record(input.result);
487
+ output.resultStatus = safeScalar(result?.status ?? result?.outcome) ?? null;
488
+ if (result) {
489
+ Object.assign(output, selectedFields(result, [
490
+ "status",
491
+ "outcome",
492
+ "completion",
493
+ "summary",
494
+ "policySetDigest",
495
+ "resultDigest",
496
+ "projectId",
497
+ "selectionReason",
498
+ "selectionGuidance",
499
+ "sourceIdentity",
500
+ "modelDigest",
501
+ "sourceModelDigest",
502
+ "modelKind",
503
+ "resultResolution",
504
+ "generatedRocqVisible",
505
+ "policyCompliance",
506
+ "diagnosticsSeparate",
507
+ "responseTruncated",
508
+ "projectCount",
509
+ "checkerProjectCount",
510
+ "propertyCount",
511
+ "partial",
512
+ "routePolicyAnalysisCount",
513
+ ]));
514
+ const resultSchemaVersion = safeScalar(result.schemaVersion);
515
+ if (resultSchemaVersion !== undefined) {
516
+ output.resultSchemaVersion = resultSchemaVersion;
517
+ }
518
+ const limitations = stringArray(result.limitations, 1_000);
519
+ if (limitations !== undefined)
520
+ output.limitations = limitations;
521
+ const projectionLimitations = stringArray(result.projectionLimitations, 32);
522
+ if (projectionLimitations !== undefined) {
523
+ output.projectionLimitations = projectionLimitations;
524
+ }
525
+ const projects = projectedObjects(result.projects, checkProject);
526
+ if (projects !== undefined)
527
+ output.projects = projects;
528
+ const checkerProjects = projectedObjects(result.checker, checkerProject);
529
+ if (checkerProjects !== undefined)
530
+ output.checkerProjects = checkerProjects;
531
+ const models = projectedObjects(result.models, (value) => {
532
+ const input = record(value);
533
+ return input ? { ...selectedFields(input, ['projectId', 'state', 'modelKind', 'modelDigest', 'resultResolution']), limitations: stringArray(input.limitations, 64) ?? [] } : undefined;
534
+ });
535
+ if (models !== undefined)
536
+ output.models = models;
537
+ const properties = projectedObjects(result.properties, propertyEvidence, 1_000);
538
+ if (properties !== undefined)
539
+ output.properties = properties;
540
+ const routePolicyAnalyses = projectedObjects(result.routePolicyAnalyses, routePolicy, 1_000);
541
+ if (routePolicyAnalyses !== undefined) {
542
+ output.routePolicyAnalyses = routePolicyAnalyses;
543
+ }
544
+ }
545
+ const rawProgress = record(input.progress);
546
+ const progress = rawProgress ? selectedFields(rawProgress, ["stage", "state", "lastProgressAt", "lastHeartbeatAt", "retryReason", "completedStages", "reusedStages"]) : undefined;
547
+ if (progress !== undefined) {
548
+ output.progress = progress;
549
+ }
550
+ const coverage = safeStructured(result?.coverage ?? input.coverage);
551
+ if (coverage !== undefined) {
552
+ output.coverage = coverage;
553
+ }
554
+ if (diagnosticsResponse) {
555
+ Object.assign(output, projectDiagnostics(diagnosticsResponse));
556
+ }
557
+ else {
558
+ const inline = Array.isArray(input.diagnostics)
559
+ ? input.diagnostics
560
+ : Array.isArray(result?.diagnostics)
561
+ ? result.diagnostics
562
+ : Array.isArray(result?.checker)
563
+ ? result.checker.flatMap((checkerValue) => {
564
+ const checker = record(checkerValue);
565
+ return Array.isArray(checker?.diagnostics)
566
+ ? checker.diagnostics
567
+ : [];
568
+ })
569
+ : [];
570
+ if (inline.length > 0) {
571
+ Object.assign(output, projectDiagnostics({
572
+ items: inline,
573
+ total: inline.length,
574
+ nextCursor: null,
575
+ truncated: inline.length > 2_000,
576
+ }));
577
+ }
578
+ }
579
+ const error = record(input.error);
580
+ if (error) {
581
+ const safeError = selectedFields(error, ["code", "message", "retryable"]);
582
+ if (Object.keys(safeError).length > 0) {
583
+ output.error = safeError;
584
+ }
585
+ }
586
+ return output;
587
+ }
588
+ function projectPolicyUnit(value) {
589
+ const input = record(value);
590
+ if (!input) {
591
+ return undefined;
592
+ }
593
+ const output = selectedFields(input, [
594
+ "id",
595
+ "policyUnitId",
596
+ "name",
597
+ "title",
598
+ "description",
599
+ "status",
600
+ "version",
601
+ "digest",
602
+ "policySetDigest",
603
+ "expectedPolicySetDigest",
604
+ "repositoryId",
605
+ "projectId",
606
+ "schemaPath",
607
+ "activeApprovalId",
608
+ "createdAt",
609
+ "updatedAt",
610
+ "ruleCount",
611
+ "language",
612
+ ]);
613
+ for (const key of ["definition", "rules", "parameters"]) {
614
+ const safe = safeStructured(input[key], 0, true);
615
+ if (safe !== undefined) {
616
+ output[key] = safe;
617
+ }
618
+ }
619
+ for (const key of [
620
+ "validationCapability",
621
+ "activeApproval",
622
+ "drafts",
623
+ ]) {
624
+ const safe = safeStructured(input[key], 0, true);
625
+ if (safe !== undefined)
626
+ output[key] = safe;
627
+ }
628
+ return Object.keys(output).length > 0 ? output : undefined;
629
+ }
630
+ export function projectPolicyUnits(raw) {
631
+ const input = unwrap(raw);
632
+ const units = Array.isArray(input.policyUnits)
633
+ ? input.policyUnits
634
+ : Array.isArray(input.items)
635
+ ? input.items
636
+ : [];
637
+ return {
638
+ policyUnits: units
639
+ .slice(0, 1_000)
640
+ .map(projectPolicyUnit)
641
+ .filter((item) => item !== undefined),
642
+ };
643
+ }
644
+ export function projectPolicy(raw) {
645
+ const input = unwrap(raw, ["policyUnit"]);
646
+ const unit = projectPolicyUnit(input);
647
+ return unit && !Array.isArray(unit) && typeof unit === "object"
648
+ ? unit
649
+ : {};
650
+ }
651
+ export function projectResource(raw, containers) {
652
+ const input = unwrap(raw, containers);
653
+ return selectedFields(input, [
654
+ "schemaVersion",
655
+ "id",
656
+ "workspaceId",
657
+ "workspaceRevisionId",
658
+ "jobId",
659
+ "draftId",
660
+ "revisionId",
661
+ "policyUnitId",
662
+ "repositoryId",
663
+ "projectId",
664
+ "kind",
665
+ "status",
666
+ "outcome",
667
+ "digest",
668
+ "revisionDigest",
669
+ "validationId",
670
+ "validationDigest",
671
+ "validationStatus",
672
+ "sourceIdentity",
673
+ "sourceModelDigest",
674
+ "translationModelDigest",
675
+ "validatorVersion",
676
+ "approvalEligible",
677
+ "ordinal",
678
+ "origin",
679
+ "policySetDigest",
680
+ "expectedPolicySetDigest",
681
+ "createdAt",
682
+ "updatedAt",
683
+ "submittedAt",
684
+ "summary",
685
+ "valid",
686
+ ]);
687
+ }
688
+ export function projectPolicyValidation(raw) {
689
+ const input = unwrap(raw, ["validation"]);
690
+ const output = selectedFields(input, [
691
+ "schemaVersion",
692
+ "id",
693
+ "revisionId",
694
+ "status",
695
+ "valid",
696
+ "sourceIdentity",
697
+ "sourceModelDigest",
698
+ "translationModelDigest",
699
+ "validationDigest",
700
+ "translationJobId",
701
+ "validatorVersion",
702
+ "approvalEligible",
703
+ "createdAt",
704
+ ]);
705
+ for (const key of ["coverage", "diagnostics", "assumptions"]) {
706
+ const safe = safeStructured(input[key], 0, true);
707
+ if (safe !== undefined)
708
+ output[key] = safe;
709
+ }
710
+ return output;
711
+ }
712
+ export function projectPolicyProposal(parts) {
713
+ const diffInput = unwrap(parts.diff, ["diff"]);
714
+ const diffSummary = selectedFields(diffInput, [
715
+ "schemaVersion",
716
+ "status",
717
+ "summary",
718
+ "basis",
719
+ "addedRuleCount",
720
+ "changedRuleCount",
721
+ "removedRuleCount",
722
+ "baseDigest",
723
+ "proposedDigest",
724
+ "revisionDigest",
725
+ "againstRevisionDigest",
726
+ "diffDigest",
727
+ ]);
728
+ const changes = safeStructured(diffInput.changes, 0, true);
729
+ if (changes !== undefined)
730
+ diffSummary.policyChanges = changes;
731
+ const limitations = stringArray(diffInput.limitations, 1_000);
732
+ if (limitations !== undefined)
733
+ diffSummary.limitations = limitations;
734
+ return {
735
+ draft: projectResource(parts.draft, ["draft"]),
736
+ revision: projectResource(parts.revision, ["revision"]),
737
+ validation: projectPolicyValidation(parts.validation),
738
+ diff: diffSummary,
739
+ ...(parts.submission
740
+ ? { submission: projectResource(parts.submission, ["submission"]) }
741
+ : {}),
742
+ submitted: parts.submitted,
743
+ };
744
+ }
745
+ export function repositoryFromList(raw, repositoryId) {
746
+ const input = unwrap(raw);
747
+ const repositories = Array.isArray(input.repositories)
748
+ ? input.repositories
749
+ : Array.isArray(input.items)
750
+ ? input.items
751
+ : [];
752
+ return repositories.find((candidate) => {
753
+ const item = record(candidate);
754
+ return item &&
755
+ (String(item.id ?? "") === repositoryId ||
756
+ String(item.repositoryId ?? "") === repositoryId)
757
+ ? true
758
+ : false;
759
+ });
760
+ }
761
+ export function safeJsonText(result) {
762
+ return JSON.stringify(result, null, 2);
763
+ }
764
+ export function assertNoForbiddenOutput(result) {
765
+ const serialized = JSON.stringify(result);
766
+ if (/"(?:authorization|cookie|token|secret|source|sources|sourceCode|sourceContent|sourceBody|sourceExcerpt|sourceText|sourceFile|sourceFiles|content|contents|fileContent|fileContents|requestBody|responseBody|changes|replacements|patch|diffText|generatedRocq|generatedRocqSource|generatedSource|rocqSource|proof|proofText|proofBody|proofSource|artifact|artifacts|artifactBody|artifactContent)"\s*:/iu.test(serialized)) {
767
+ throw new Me2lonClientError("ME2LON_OUTPUT_SAFETY_FAILURE", "A Me2lon response violated the source-non-disclosure boundary.");
768
+ }
769
+ }
770
+ //# sourceMappingURL=safe-output.js.map