@fro.bot/systematic 3.15.0 → 3.15.1

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/cli.js CHANGED
@@ -1,20 +1,50 @@
1
1
  #!/usr/bin/env node
2
2
  // @bun
3
3
  import {
4
+ parseFrontmatter,
5
+ parse,
6
+ parseTree,
7
+ modify,
4
8
  applyEdits,
5
- discoverSkills,
6
- exports_external,
9
+ _isoDateTime,
10
+ _isoDate,
11
+ _isoTime,
12
+ _isoDuration,
13
+ string,
14
+ ZodISODateTime,
15
+ ZodISODate,
16
+ ZodISOTime,
17
+ ZodISODuration,
18
+ number,
19
+ boolean,
20
+ array,
21
+ object,
22
+ union,
23
+ discriminatedUnion,
24
+ _enum,
25
+ literal,
26
+ loadConfigWithSources,
27
+ getConfigPaths,
7
28
  extractString,
8
29
  findAgentsInDir,
9
30
  findCommandsInDir,
10
31
  findSkillsInDir,
11
- getConfigPaths,
12
- loadConfigWithSources,
13
- modify,
14
- parse,
15
- parseFrontmatter,
16
- parseTree
17
- } from "./index-0stf3ag0.js";
32
+ discoverSkills
33
+ } from "./index-7cyxcwf5.js";
34
+ var __defProp = Object.defineProperty;
35
+ var __returnValue = (v) => v;
36
+ function __exportSetter(name, newValue) {
37
+ this[name] = __returnValue.bind(null, newValue);
38
+ }
39
+ var __export = (target, all) => {
40
+ for (var name in all)
41
+ __defProp(target, name, {
42
+ get: all[name],
43
+ enumerable: true,
44
+ configurable: true,
45
+ set: __exportSetter.bind(all, name)
46
+ });
47
+ };
18
48
 
19
49
  // src/cli.ts
20
50
  import fs6 from "fs";
@@ -778,7 +808,30 @@ function buildCapabilitySnapshot(options) {
778
808
  options.outputSink?.(serialized);
779
809
  return snapshot;
780
810
  }
781
-
811
+ // node_modules/.bun/zod@4.5.4/node_modules/zod/v4/classic/iso.js
812
+ var exports_iso = {};
813
+ __export(exports_iso, {
814
+ ZodISODate: () => ZodISODate,
815
+ ZodISODateTime: () => ZodISODateTime,
816
+ ZodISODuration: () => ZodISODuration,
817
+ ZodISOTime: () => ZodISOTime,
818
+ date: () => date,
819
+ datetime: () => datetime,
820
+ duration: () => duration,
821
+ time: () => time
822
+ });
823
+ function datetime(params) {
824
+ return _isoDateTime(ZodISODateTime, params);
825
+ }
826
+ function date(params) {
827
+ return _isoDate(ZodISODate, params);
828
+ }
829
+ function time(params) {
830
+ return _isoTime(ZodISOTime, params);
831
+ }
832
+ function duration(params) {
833
+ return _isoDuration(ZodISODuration, params);
834
+ }
782
835
  // src/lib/pi-subagents-export.ts
783
836
  import * as crypto2 from "crypto";
784
837
  import * as fs3 from "fs";
@@ -1424,10 +1477,10 @@ function ownedFilenames(manifest) {
1424
1477
  function parseSourceCategoryAndKey(sourceRelPath) {
1425
1478
  const parts = sourceRelPath.split("/");
1426
1479
  if (parts.length >= 3 && parts[0] === "agents") {
1427
- const fileName2 = parts.at(-1) ?? "";
1480
+ const fileName = parts.at(-1) ?? "";
1428
1481
  return {
1429
1482
  category: parts[1],
1430
- agentKey: fileName2.replace(/\.md$/, "")
1483
+ agentKey: fileName.replace(/\.md$/, "")
1431
1484
  };
1432
1485
  }
1433
1486
  const fileName = parts.at(-1) ?? sourceRelPath;
@@ -1949,7 +2002,7 @@ function cleanup(agentsRoot, configOptions) {
1949
2002
  ...targets.map((t) => t.path),
1950
2003
  ...manifestPath ? [manifestPath] : []
1951
2004
  ];
1952
- const tx2 = runWithRollback(pathsToWatch, [
2005
+ const tx = runWithRollback(pathsToWatch, [
1953
2006
  ...targets.map(({ path: p, filename, hash }) => () => {
1954
2007
  if (fs3.existsSync(p)) {
1955
2008
  assertHashMatchesOrThrow(p, hash, filename, "delete");
@@ -1963,7 +2016,7 @@ function cleanup(agentsRoot, configOptions) {
1963
2016
  }
1964
2017
  ] : []
1965
2018
  ]);
1966
- return { kind: "tx", tx: tx2 };
2019
+ return { kind: "tx", tx };
1967
2020
  });
1968
2021
  if (!lockResult.locked) {
1969
2022
  if (lockResult.isContention)
@@ -2010,8 +2063,8 @@ function hasParentDirectoryTraversal(input) {
2010
2063
  }
2011
2064
  function pathContainsSymlink(candidate) {
2012
2065
  let current = path3.parse(candidate).root;
2013
- const relative2 = path3.relative(current, candidate);
2014
- for (const segment of relative2.split(path3.sep)) {
2066
+ const relative = path3.relative(current, candidate);
2067
+ for (const segment of relative.split(path3.sep)) {
2015
2068
  if (!segment)
2016
2069
  continue;
2017
2070
  current = path3.join(current, segment);
@@ -2025,8 +2078,8 @@ function pathContainsSymlink(candidate) {
2025
2078
  return false;
2026
2079
  }
2027
2080
  function isWithinDirectory(candidate, directory) {
2028
- const relative2 = path3.relative(directory, candidate);
2029
- return relative2 !== "" && relative2 !== ".." && !relative2.startsWith(`..${path3.sep}`) && !path3.isAbsolute(relative2);
2081
+ const relative = path3.relative(directory, candidate);
2082
+ return relative !== "" && relative !== ".." && !relative.startsWith(`..${path3.sep}`) && !path3.isAbsolute(relative);
2030
2083
  }
2031
2084
  function resolveReviewArtifactPath(input, cwd) {
2032
2085
  if (hasParentDirectoryTraversal(input)) {
@@ -2096,14 +2149,14 @@ var REVIEW_ARTIFACT_CUSTOM_MESSAGES = [
2096
2149
  "unsatisfied risk coverage must not cite an input finding ID",
2097
2150
  "passed validation must not include a reason; non-passed validation requires a reason"
2098
2151
  ];
2099
- var boundedText = (maxLength) => exports_external.string().min(1).max(maxLength).regex(/\S/);
2100
- var DispatchOutcomeSchema = exports_external.enum([
2152
+ var boundedText = (maxLength) => string().min(1).max(maxLength).regex(/\S/);
2153
+ var DispatchOutcomeSchema = _enum([
2101
2154
  "findings",
2102
2155
  "empty",
2103
2156
  "malformed",
2104
2157
  "never_returned"
2105
2158
  ]);
2106
- var DispositionSchema = exports_external.enum([
2159
+ var DispositionSchema = _enum([
2107
2160
  "surviving",
2108
2161
  "merged",
2109
2162
  "suppressed",
@@ -2111,12 +2164,12 @@ var DispositionSchema = exports_external.enum([
2111
2164
  "rejected"
2112
2165
  ]);
2113
2166
  var AdmittedDispositionSchema = DispositionSchema.exclude(["rejected"]);
2114
- var HarnessSchema = exports_external.enum(["opencode", "pi", "claude-code"]);
2167
+ var HarnessSchema = _enum(["opencode", "pi", "claude-code"]);
2115
2168
  var RepoRelativePathSchema = boundedText(256).regex(/^(?!\/)(?![A-Za-z]:[\\/])(?!\\).+/);
2116
2169
  var ReviewerSchema = boundedText(MAX_REVIEWER_LENGTH);
2117
- var BranchSchema = exports_external.string().max(MAX_BRANCH_LENGTH);
2118
- var HeadShaSchema = exports_external.string().regex(/^[0-9a-f]{40}$/);
2119
- var CompletedAtSchema = exports_external.iso.datetime({ offset: false });
2170
+ var BranchSchema = string().max(MAX_BRANCH_LENGTH);
2171
+ var HeadShaSchema = string().regex(/^[0-9a-f]{40}$/);
2172
+ var CompletedAtSchema = exports_iso.datetime({ offset: false });
2120
2173
  var ReasonSchema = boundedText(MAX_REASON_LENGTH);
2121
2174
  var RISK_CRITICAL_PERSONAS = [
2122
2175
  "security",
@@ -2125,42 +2178,42 @@ var RISK_CRITICAL_PERSONAS = [
2125
2178
  "reliability",
2126
2179
  "performance"
2127
2180
  ];
2128
- var RiskCriticalPersonaSchema = exports_external.enum(RISK_CRITICAL_PERSONAS);
2181
+ var RiskCriticalPersonaSchema = _enum(RISK_CRITICAL_PERSONAS);
2129
2182
  var FindingTitleSchema = boundedText(256);
2130
- var SeveritySchema = exports_external.enum(["P0", "P1", "P2", "P3", "unknown"]);
2183
+ var SeveritySchema = _enum(["P0", "P1", "P2", "P3", "unknown"]);
2131
2184
  var FindingSeveritySchema = SeveritySchema.exclude(["unknown"]);
2132
- var AutofixClassSchema = exports_external.enum([
2185
+ var AutofixClassSchema = _enum([
2133
2186
  "safe_auto",
2134
2187
  "gated_auto",
2135
2188
  "manual",
2136
2189
  "advisory"
2137
2190
  ]);
2138
- var OwnerSchema = exports_external.enum([
2191
+ var OwnerSchema = _enum([
2139
2192
  "review-fixer",
2140
2193
  "downstream-resolver",
2141
2194
  "human",
2142
2195
  "release"
2143
2196
  ]);
2144
2197
  var BoundedEvidenceStringSchema = boundedText(500).regex(/^(?!\/)(?![A-Za-z]:[\\/])(?!\\).+/);
2145
- var OverflowEvidenceSchema = exports_external.object({
2146
- overflow: exports_external.literal(true),
2198
+ var OverflowEvidenceSchema = object({
2199
+ overflow: literal(true),
2147
2200
  excerpt: BoundedEvidenceStringSchema
2148
2201
  }).strict();
2149
- var EvidenceSchema = exports_external.array(exports_external.union([BoundedEvidenceStringSchema, OverflowEvidenceSchema])).min(1).max(5);
2150
- var AdmittedInputFindingSchema = exports_external.object({
2151
- record_type: exports_external.literal("admitted"),
2202
+ var EvidenceSchema = array(union([BoundedEvidenceStringSchema, OverflowEvidenceSchema])).min(1).max(5);
2203
+ var AdmittedInputFindingSchema = object({
2204
+ record_type: literal("admitted"),
2152
2205
  input_id: boundedText(MAX_INPUT_ID_LENGTH),
2153
2206
  reviewer: ReviewerSchema,
2154
- confidence: exports_external.number().min(0).max(1),
2207
+ confidence: number().min(0).max(1),
2155
2208
  disposition: AdmittedDispositionSchema,
2156
2209
  reason: ReasonSchema
2157
2210
  }).strict();
2158
- var RejectedInputFindingSchema = exports_external.object({
2159
- record_type: exports_external.literal("rejected_summary"),
2211
+ var RejectedInputFindingSchema = object({
2212
+ record_type: literal("rejected_summary"),
2160
2213
  reviewer: ReviewerSchema,
2161
2214
  dispatch_outcome: DispatchOutcomeSchema,
2162
- rejected_finding_count: exports_external.number().int().positive().max(MAX_FINDINGS),
2163
- rejected_severities: exports_external.array(SeveritySchema).max(MAX_FINDINGS),
2215
+ rejected_finding_count: number().int().positive().max(MAX_FINDINGS),
2216
+ rejected_severities: array(SeveritySchema).max(MAX_FINDINGS),
2164
2217
  disposition: DispositionSchema.extract(["rejected"]),
2165
2218
  reason: ReasonSchema
2166
2219
  }).strict().superRefine((row, ctx) => {
@@ -2172,31 +2225,31 @@ var RejectedInputFindingSchema = exports_external.object({
2172
2225
  });
2173
2226
  }
2174
2227
  });
2175
- var InputFindingSchema = exports_external.discriminatedUnion("record_type", [
2228
+ var InputFindingSchema = discriminatedUnion("record_type", [
2176
2229
  AdmittedInputFindingSchema,
2177
2230
  RejectedInputFindingSchema
2178
2231
  ]);
2179
- var ProvenanceSchema = exports_external.object({
2232
+ var ProvenanceSchema = object({
2180
2233
  fingerprint: boundedText(512),
2181
- submitters: exports_external.array(ReviewerSchema).max(MAX_PERSONAS),
2182
- agreement_credit: exports_external.array(ReviewerSchema).max(MAX_PERSONAS)
2234
+ submitters: array(ReviewerSchema).max(MAX_PERSONAS),
2235
+ agreement_credit: array(ReviewerSchema).max(MAX_PERSONAS)
2183
2236
  }).strict();
2184
- var SynthesizedFindingFieldsSchema = exports_external.object({
2237
+ var SynthesizedFindingFieldsSchema = object({
2185
2238
  title: FindingTitleSchema,
2186
2239
  severity: FindingSeveritySchema,
2187
2240
  file: RepoRelativePathSchema,
2188
- line: exports_external.number().int().positive(),
2241
+ line: number().int().positive(),
2189
2242
  why_it_matters: boundedText(2048),
2190
2243
  autofix_class: AutofixClassSchema,
2191
2244
  owner: OwnerSchema,
2192
- requires_verification: exports_external.boolean(),
2193
- confidence: exports_external.number().min(0).max(1),
2245
+ requires_verification: boolean(),
2246
+ confidence: number().min(0).max(1),
2194
2247
  evidence: EvidenceSchema,
2195
- pre_existing: exports_external.boolean(),
2196
- suggested_fix: exports_external.string().max(2048).nullable().optional(),
2197
- validated: exports_external.boolean().optional(),
2248
+ pre_existing: boolean(),
2249
+ suggested_fix: string().max(2048).nullable().optional(),
2250
+ validated: boolean().optional(),
2198
2251
  validation_reason: ReasonSchema.optional(),
2199
- input_finding_ids: exports_external.array(boundedText(MAX_INPUT_ID_LENGTH)).min(1).max(MAX_FINDINGS),
2252
+ input_finding_ids: array(boundedText(MAX_INPUT_ID_LENGTH)).min(1).max(MAX_FINDINGS),
2200
2253
  provenance: ProvenanceSchema
2201
2254
  }).strict();
2202
2255
  var SynthesizedFindingSchema = SynthesizedFindingFieldsSchema.superRefine((finding, ctx) => {
@@ -2208,12 +2261,12 @@ var SynthesizedFindingSchema = SynthesizedFindingFieldsSchema.superRefine((findi
2208
2261
  });
2209
2262
  }
2210
2263
  });
2211
- var DispatchSchema = exports_external.object({
2264
+ var DispatchSchema = object({
2212
2265
  persona: ReviewerSchema,
2213
2266
  dispatch_outcome: DispatchOutcomeSchema,
2214
- input_finding_count: exports_external.number().int().nonnegative().max(MAX_FINDINGS),
2267
+ input_finding_count: number().int().nonnegative().max(MAX_FINDINGS),
2215
2268
  rejection_reason: ReasonSchema.optional(),
2216
- selection_surface: exports_external.array(RepoRelativePathSchema).max(MAX_FINDINGS).optional(),
2269
+ selection_surface: array(RepoRelativePathSchema).max(MAX_FINDINGS).optional(),
2217
2270
  selection_reason: ReasonSchema.optional()
2218
2271
  }).strict().superRefine((dispatch, ctx) => {
2219
2272
  if (RISK_CRITICAL_PERSONAS.includes(dispatch.persona) && (!dispatch.selection_surface || dispatch.selection_surface.length === 0)) {
@@ -2224,29 +2277,29 @@ var DispatchSchema = exports_external.object({
2224
2277
  });
2225
2278
  }
2226
2279
  });
2227
- var DispositionCountsSchema = exports_external.object({
2228
- surviving: exports_external.number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2229
- merged: exports_external.number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2230
- suppressed: exports_external.number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2231
- filtered: exports_external.number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2232
- rejected: exports_external.number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS)
2280
+ var DispositionCountsSchema = object({
2281
+ surviving: number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2282
+ merged: number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2283
+ suppressed: number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2284
+ filtered: number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS),
2285
+ rejected: number().int().nonnegative().max(MAX_FINDINGS * MAX_PERSONAS)
2233
2286
  }).strict();
2234
- var CoverageSchema = exports_external.object({
2235
- reviewers: exports_external.number().int().nonnegative().max(MAX_PERSONAS).optional(),
2236
- validators: exports_external.number().int().nonnegative().max(MAX_PERSONAS).optional(),
2237
- residual_risks: exports_external.array(ReasonSchema).max(MAX_PERSONAS),
2238
- testing_gaps: exports_external.array(ReasonSchema).max(MAX_PERSONAS),
2239
- failed_reviewers: exports_external.array(ReviewerSchema).max(MAX_PERSONAS),
2240
- validator_failures: exports_external.array(ReasonSchema).max(MAX_PERSONAS),
2241
- intent_uncertainty: exports_external.array(ReasonSchema).max(MAX_PERSONAS)
2287
+ var CoverageSchema = object({
2288
+ reviewers: number().int().nonnegative().max(MAX_PERSONAS).optional(),
2289
+ validators: number().int().nonnegative().max(MAX_PERSONAS).optional(),
2290
+ residual_risks: array(ReasonSchema).max(MAX_PERSONAS),
2291
+ testing_gaps: array(ReasonSchema).max(MAX_PERSONAS),
2292
+ failed_reviewers: array(ReviewerSchema).max(MAX_PERSONAS),
2293
+ validator_failures: array(ReasonSchema).max(MAX_PERSONAS),
2294
+ intent_uncertainty: array(ReasonSchema).max(MAX_PERSONAS)
2242
2295
  }).strict();
2243
- var DeclinedMergeSchema = exports_external.object({
2296
+ var DeclinedMergeSchema = object({
2244
2297
  file: RepoRelativePathSchema,
2245
- input_finding_ids: exports_external.array(boundedText(MAX_INPUT_ID_LENGTH)).min(2).max(MAX_FINDINGS),
2298
+ input_finding_ids: array(boundedText(MAX_INPUT_ID_LENGTH)).min(2).max(MAX_FINDINGS),
2246
2299
  reason: ReasonSchema
2247
2300
  }).strict();
2248
- var ValidationSchema = exports_external.object({
2249
- status: exports_external.enum([
2301
+ var ValidationSchema = object({
2302
+ status: _enum([
2250
2303
  "passed",
2251
2304
  "failed",
2252
2305
  "unavailable",
@@ -2269,9 +2322,9 @@ var ValidationSchema = exports_external.object({
2269
2322
  });
2270
2323
  }
2271
2324
  });
2272
- var RiskCoverageSchema = exports_external.object({
2325
+ var RiskCoverageSchema = object({
2273
2326
  persona: RiskCriticalPersonaSchema,
2274
- satisfied: exports_external.boolean(),
2327
+ satisfied: boolean(),
2275
2328
  input_finding_id: boundedText(MAX_INPUT_ID_LENGTH).optional()
2276
2329
  }).strict().superRefine((coverage, ctx) => {
2277
2330
  if (coverage.satisfied && coverage.input_finding_id === undefined) {
@@ -2289,14 +2342,14 @@ var RiskCoverageSchema = exports_external.object({
2289
2342
  });
2290
2343
  }
2291
2344
  });
2292
- var ReviewArtifactSchema = exports_external.object({
2293
- schema_version: exports_external.literal(1),
2345
+ var ReviewArtifactSchema = object({
2346
+ schema_version: literal(1),
2294
2347
  run_id: boundedText(MAX_RUN_ID_LENGTH),
2295
2348
  branch: BranchSchema,
2296
2349
  head_sha: HeadShaSchema,
2297
- mode: exports_external.enum(["interactive", "autofix", "headless"]),
2350
+ mode: _enum(["interactive", "autofix", "headless"]),
2298
2351
  harness: HarnessSchema,
2299
- run_status: exports_external.enum([
2352
+ run_status: _enum([
2300
2353
  "in_progress",
2301
2354
  "completed",
2302
2355
  "degraded",
@@ -2304,15 +2357,15 @@ var ReviewArtifactSchema = exports_external.object({
2304
2357
  ]),
2305
2358
  verdict: boundedText(256),
2306
2359
  completed_at: CompletedAtSchema,
2307
- dispatches: exports_external.array(DispatchSchema).max(MAX_PERSONAS),
2308
- input_findings: exports_external.array(InputFindingSchema).max(MAX_FINDINGS * MAX_PERSONAS),
2309
- findings: exports_external.array(SynthesizedFindingSchema).max(MAX_FINDINGS),
2310
- declined_merges: exports_external.array(DeclinedMergeSchema).max(MAX_FINDINGS).optional(),
2311
- risk_coverage: exports_external.array(RiskCoverageSchema).max(MAX_PERSONAS).optional(),
2360
+ dispatches: array(DispatchSchema).max(MAX_PERSONAS),
2361
+ input_findings: array(InputFindingSchema).max(MAX_FINDINGS * MAX_PERSONAS),
2362
+ findings: array(SynthesizedFindingSchema).max(MAX_FINDINGS),
2363
+ declined_merges: array(DeclinedMergeSchema).max(MAX_FINDINGS).optional(),
2364
+ risk_coverage: array(RiskCoverageSchema).max(MAX_PERSONAS).optional(),
2312
2365
  disposition_counts: DispositionCountsSchema,
2313
- applied_fixes: exports_external.array(ReasonSchema).max(MAX_FINDINGS),
2314
- residual_actionable_work: exports_external.array(ReasonSchema).max(MAX_FINDINGS),
2315
- advisory_outputs: exports_external.array(ReasonSchema).max(MAX_FINDINGS),
2366
+ applied_fixes: array(ReasonSchema).max(MAX_FINDINGS),
2367
+ residual_actionable_work: array(ReasonSchema).max(MAX_FINDINGS),
2368
+ advisory_outputs: array(ReasonSchema).max(MAX_FINDINGS),
2316
2369
  coverage: CoverageSchema,
2317
2370
  validation: ValidationSchema.optional()
2318
2371
  }).strict();
@@ -2365,8 +2418,8 @@ function lstatOrNull(targetPath) {
2365
2418
  function assertRealpathUnderCwd(dir, cwd) {
2366
2419
  const realDir = fs5.realpathSync(dir);
2367
2420
  const realCwd = fs5.realpathSync(cwd);
2368
- const relative2 = path4.relative(realCwd, realDir);
2369
- if (relative2.startsWith("..") || path4.isAbsolute(relative2)) {
2421
+ const relative = path4.relative(realCwd, realDir);
2422
+ if (relative.startsWith("..") || path4.isAbsolute(relative)) {
2370
2423
  throw createSetupError(`Refusing to write under ${dir}: resolved directory escapes the project root`);
2371
2424
  }
2372
2425
  }
@@ -2459,8 +2512,8 @@ function writeTempAndRename(destPath, content, mode, preserveExactMode, ops) {
2459
2512
  throw error;
2460
2513
  }
2461
2514
  }
2462
- function makeTempPath(parentDir, basename2) {
2463
- return path4.join(parentDir, `.${basename2}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
2515
+ function makeTempPath(parentDir, basename) {
2516
+ return path4.join(parentDir, `.${basename}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
2464
2517
  }
2465
2518
  function cleanupTemp(tempPath, ops) {
2466
2519
  if (!fs5.existsSync(tempPath))
@@ -2515,8 +2568,8 @@ function setupOpenCode(cwd, ops) {
2515
2568
  throw createSetupError(`Invalid OpenCode config in ${targetPath}: \`plugins\` (plural) is not supported by OpenCode's schema; use singular \`plugin\``);
2516
2569
  }
2517
2570
  if (!Object.hasOwn(parsed, "plugin")) {
2518
- const edits2 = modify(rawText, ["plugin"], [SYSTEMATIC_PACKAGE_NAME], {});
2519
- atomicWrite(targetPath, applyEdits(rawText, edits2), existing.bytes, existing.mode, ops);
2571
+ const edits = modify(rawText, ["plugin"], [SYSTEMATIC_PACKAGE_NAME], {});
2572
+ atomicWrite(targetPath, applyEdits(rawText, edits), existing.bytes, existing.mode, ops);
2520
2573
  return { status: "configured", targetPath };
2521
2574
  }
2522
2575
  const existingValue = parsed.plugin;
@@ -2577,8 +2630,8 @@ function setupPi(cwd, ops) {
2577
2630
  }
2578
2631
  const existingPackages = parsed.packages;
2579
2632
  if (existingPackages === undefined) {
2580
- const edits2 = modify(rawText, ["packages"], [PI_PACKAGE_IDENTIFIER], {});
2581
- atomicWrite(targetPath, applyEdits(rawText, edits2), existing.bytes, existing.mode, ops);
2633
+ const edits = modify(rawText, ["packages"], [PI_PACKAGE_IDENTIFIER], {});
2634
+ atomicWrite(targetPath, applyEdits(rawText, edits), existing.bytes, existing.mode, ops);
2582
2635
  return { status: "configured", targetPath };
2583
2636
  }
2584
2637
  if (!Array.isArray(existingPackages)) {