@garygentry/system1 0.3.0 → 0.3.2

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.
@@ -6,38 +6,10 @@ import {
6
6
  VERSION,
7
7
  emit,
8
8
  extractFormat
9
- } from "./chunk-NUIZJRI6.mjs";
9
+ } from "./chunk-4ZZ3ZSJN.mjs";
10
10
 
11
11
  // src/bin.ts
12
- import { readFileSync as readFileSync2 } from "node:fs";
13
-
14
- // src/bundled.ts
15
- import { existsSync, readFileSync } from "node:fs";
16
- import { dirname, join } from "node:path";
17
- import { fileURLToPath } from "node:url";
18
- var PACKAGE = "@garygentry/system1";
19
- function bundledSpecsDir(from = fileURLToPath(import.meta.url)) {
20
- const root = packageRoot(dirname(from));
21
- if (!root) return void 0;
22
- const own = join(root, "specs");
23
- if (existsSync(own)) return own;
24
- const checkout = join(root, "..", "..");
25
- const plugin = join(checkout, "plugins", "system1", "specs");
26
- return existsSync(join(checkout, "catalog.yaml")) && existsSync(plugin) ? plugin : void 0;
27
- }
28
- function packageRoot(start) {
29
- for (let dir = start; ; dir = dirname(dir)) {
30
- const manifest = join(dir, "package.json");
31
- if (existsSync(manifest)) {
32
- try {
33
- if (JSON.parse(readFileSync(manifest, "utf8")).name === PACKAGE)
34
- return dir;
35
- } catch {
36
- }
37
- }
38
- if (dirname(dir) === dir) return void 0;
39
- }
40
- }
12
+ import { readFileSync } from "node:fs";
41
13
 
42
14
  // src/main.ts
43
15
  var HELP = `decide ${VERSION} \u2014 typed, calibrated decisions for coding agents
@@ -92,23 +64,23 @@ async function main(argv, io) {
92
64
  }
93
65
  switch (command) {
94
66
  case "ask":
95
- return (await import("./decide-XVVRKQ3V.mjs")).runAskCommand(rest, io, format);
67
+ return (await import("./decide-AAXD3ITT.mjs")).runAskCommand(rest, io, format);
96
68
  case "many":
97
- return (await import("./decide-XVVRKQ3V.mjs")).runManyCommand(rest, io, format);
69
+ return (await import("./decide-AAXD3ITT.mjs")).runManyCommand(rest, io, format);
98
70
  case "usage":
99
- return (await import("./misc-FHOVQJ2G.mjs")).runUsageCommand(rest, io, format);
71
+ return (await import("./misc-IW4I3SO6.mjs")).runUsageCommand(rest, io, format);
100
72
  case "config":
101
- return (await import("./config-REALJZDR.mjs")).runConfigCommand(rest, io, format);
73
+ return (await import("./config-UUPD2JL4.mjs")).runConfigCommand(rest, io, format);
102
74
  case "spec":
103
- return (await import("./spec-734MPBKB.mjs")).runSpecCommand(rest, io, format);
75
+ return (await import("./spec-RKA3K6ZZ.mjs")).runSpecCommand(rest, io, format);
104
76
  case "schema":
105
- return (await import("./misc-FHOVQJ2G.mjs")).runSchemaCommand(rest, io, format);
77
+ return (await import("./misc-IW4I3SO6.mjs")).runSchemaCommand(rest, io, format);
106
78
  case "route":
107
- return (await import("./route-NMFOTXLI.mjs")).runRouteCommand(rest, io, format);
79
+ return (await import("./route-7N3J5NP6.mjs")).runRouteCommand(rest, io, format);
108
80
  case "ping":
109
- return (await import("./misc-FHOVQJ2G.mjs")).runPingCommand(io, format);
81
+ return (await import("./misc-IW4I3SO6.mjs")).runPingCommand(io, format);
110
82
  case "doctor":
111
- return (await import("./doctor-TKFVFCZV.mjs")).runDoctorCommand(io, format);
83
+ return (await import("./doctor-KPJ5KVLS.mjs")).runDoctorCommand(io, format);
112
84
  case "version":
113
85
  case "--version":
114
86
  case "-v":
@@ -138,7 +110,6 @@ process.exitCode = await main(process.argv.slice(2), {
138
110
  err: line(process.stderr),
139
111
  env: process.env,
140
112
  cwd: process.cwd(),
141
- readStdin: () => readFileSync2(0, "utf8"),
142
- interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
143
- ...bundledSpecsDir() ? { bundledSpecs: bundledSpecsDir() } : {}
113
+ readStdin: () => readFileSync(0, "utf8"),
114
+ interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY)
144
115
  });
@@ -70,7 +70,9 @@ var EXIT = {
70
70
  egressRefused: 3,
71
71
  budgetGuard: 4,
72
72
  providerError: 5,
73
- replayMiss: 6
73
+ replayMiss: 6,
74
+ /** `spec check --strict` only: the check ran, and an example did not pass. */
75
+ checkFailed: 7
74
76
  };
75
77
  var BY_CODE = {
76
78
  "invalid-request": EXIT.usage,
@@ -145,7 +147,7 @@ function extractFormat(argv, fallback) {
145
147
  }
146
148
 
147
149
  // ../core/dist/version.js
148
- var VERSION = "0.3.0";
150
+ var VERSION = "0.3.2";
149
151
  var CLI_PACKAGE = "@garygentry/system1";
150
152
 
151
153
  export {
@@ -9,7 +9,7 @@ import {
9
9
  __require,
10
10
  __toESM,
11
11
  isDecisionsError
12
- } from "./chunk-NUIZJRI6.mjs";
12
+ } from "./chunk-4ZZ3ZSJN.mjs";
13
13
 
14
14
  // ../../node_modules/.pnpm/yaml@2.9.1/node_modules/yaml/dist/nodes/identity.js
15
15
  var require_identity = __commonJS({
@@ -9117,54 +9117,6 @@ var require_picomatch2 = __commonJS({
9117
9117
  }
9118
9118
  });
9119
9119
 
9120
- // ../core/dist/config/load.js
9121
- var import_yaml = __toESM(require_dist(), 1);
9122
- import { existsSync, readFileSync, statSync } from "node:fs";
9123
- import { homedir } from "node:os";
9124
- import { dirname, join, resolve } from "node:path";
9125
-
9126
- // ../core/dist/model/answers.js
9127
- var DEFAULT_UNDECIDED_FLOOR = 0.15;
9128
- function noulConfidence(answer) {
9129
- return Math.abs(answer.noul - 0.5) * 2;
9130
- }
9131
- function confidenceOf(answer) {
9132
- return answer.type === "noul" ? noulConfidence(answer) : answer.confidence;
9133
- }
9134
- function undecidedNames(answers, floor = DEFAULT_UNDECIDED_FLOOR) {
9135
- return Object.entries(answers).filter(([, answer]) => confidenceOf(answer) <= floor).map(([name]) => name);
9136
- }
9137
-
9138
- // ../core/dist/model/profiles.js
9139
- var PROFILES = [
9140
- {
9141
- id: "typesafe/jev-1.13",
9142
- displayName: "TypeSafe Jev 1.13",
9143
- transport: "openrouter-decisions",
9144
- maxStateTokens: 32e3,
9145
- // Measured 2026-09-22: 400 options is refused upstream with "at most 255 choices".
9146
- maxChoices: 255,
9147
- usdPerInputToken: 0.042 / 1e6,
9148
- usdPerOutputToken: 0,
9149
- priceAsOf: "2026-09-19",
9150
- undecidedFloor: DEFAULT_UNDECIDED_FLOOR,
9151
- calibrated: true
9152
- }
9153
- ];
9154
- var DEFAULT_MODEL_ID = "typesafe/jev-1.13";
9155
- function resolveProfile(id, profiles = PROFILES) {
9156
- const exact = profiles.find((p) => p.id === id);
9157
- if (exact)
9158
- return exact;
9159
- const family = profiles.find((p) => new RegExp(`^${escapeRegExp(p.id)}-\\d{8}$`).test(id));
9160
- if (family)
9161
- return { ...family, id };
9162
- throw new DecisionsError("unknown-model", `No profile for model "${id}". Known: ${profiles.map((p) => p.id).join(", ")}.`, { model: id, known: profiles.map((p) => p.id) });
9163
- }
9164
- function escapeRegExp(text) {
9165
- return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9166
- }
9167
-
9168
9120
  // ../core/dist/route/route.js
9169
9121
  var ROUTE_DEFAULTS = {
9170
9122
  enabled: true,
@@ -9266,7 +9218,58 @@ function route(prompt, config) {
9266
9218
  };
9267
9219
  }
9268
9220
 
9221
+ // ../core/dist/config/load.js
9222
+ var import_yaml = __toESM(require_dist(), 1);
9223
+ import { existsSync, readFileSync, statSync } from "node:fs";
9224
+ import { homedir } from "node:os";
9225
+ import { dirname, join, resolve } from "node:path";
9226
+
9227
+ // ../core/dist/model/answers.js
9228
+ var DEFAULT_UNDECIDED_FLOOR = 0.15;
9229
+ function noulConfidence(answer) {
9230
+ return Math.abs(answer.noul - 0.5) * 2;
9231
+ }
9232
+ function confidenceOf(answer) {
9233
+ return answer.type === "noul" ? noulConfidence(answer) : answer.confidence;
9234
+ }
9235
+ function undecidedNames(answers, floor = DEFAULT_UNDECIDED_FLOOR) {
9236
+ return Object.entries(answers).filter(([, answer]) => confidenceOf(answer) <= floor).map(([name]) => name);
9237
+ }
9238
+
9239
+ // ../core/dist/model/profiles.js
9240
+ var JEV_CALL_OVERHEAD_TOKENS = 300;
9241
+ var PROFILES = [
9242
+ {
9243
+ id: "typesafe/jev-1.13",
9244
+ displayName: "TypeSafe Jev 1.13",
9245
+ transport: "openrouter-decisions",
9246
+ maxStateTokens: 32e3,
9247
+ // Measured 2026-09-22: 400 options is refused upstream with "at most 255 choices".
9248
+ maxChoices: 255,
9249
+ callOverheadTokens: JEV_CALL_OVERHEAD_TOKENS,
9250
+ usdPerInputToken: 0.042 / 1e6,
9251
+ usdPerOutputToken: 0,
9252
+ priceAsOf: "2026-09-19",
9253
+ undecidedFloor: DEFAULT_UNDECIDED_FLOOR,
9254
+ calibrated: true
9255
+ }
9256
+ ];
9257
+ var DEFAULT_MODEL_ID = "typesafe/jev-1.13";
9258
+ function resolveProfile(id, profiles = PROFILES) {
9259
+ const exact = profiles.find((p) => p.id === id);
9260
+ if (exact)
9261
+ return exact;
9262
+ const family = profiles.find((p) => new RegExp(`^${escapeRegExp(p.id)}-\\d{8}$`).test(id));
9263
+ if (family)
9264
+ return { ...family, id };
9265
+ throw new DecisionsError("unknown-model", `No profile for model "${id}". Known: ${profiles.map((p) => p.id).join(", ")}.`, { model: id, known: profiles.map((p) => p.id) });
9266
+ }
9267
+ function escapeRegExp(text) {
9268
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9269
+ }
9270
+
9269
9271
  // ../core/dist/model/validate.js
9272
+ var QUESTION_KEYS = ["type", "instructions", "criteria"];
9270
9273
  function assertQuestionSet(questions) {
9271
9274
  const problems = [];
9272
9275
  if (!isObject(questions) || Object.keys(questions).length === 0) {
@@ -9277,6 +9280,10 @@ function assertQuestionSet(questions) {
9277
9280
  problems.push(`${name}: must be an object`);
9278
9281
  continue;
9279
9282
  }
9283
+ const extra = Object.keys(q).filter((k) => !QUESTION_KEYS.includes(k));
9284
+ if (extra.length > 0) {
9285
+ problems.push(`${name}: unknown key(s) ${extra.join(", ")} (a question has type, instructions, criteria)`);
9286
+ }
9280
9287
  if (typeof q.instructions !== "string" || q.instructions.trim() === "") {
9281
9288
  problems.push(`${name}: instructions must be a non-empty string`);
9282
9289
  }
@@ -9556,14 +9563,20 @@ function loadConfig(options = {}) {
9556
9563
  const repoFile = repoConfigPath(repoRoot);
9557
9564
  const user = readLayer(userFile);
9558
9565
  const repo = readLayer(repoFile);
9566
+ const warnings = [...unknownKeys(user, userFile, "user"), ...unknownKeys(repo, repoFile, "repo")];
9567
+ const layers2 = [
9568
+ { layer: repo, file: repoFile },
9569
+ { layer: user, file: userFile }
9570
+ ];
9571
+ const pickFrom = (path, rule) => pick(path, rule, layers2, warnings);
9559
9572
  const merged = {
9560
- model: pick("model", "string", repo, user) ?? DEFAULTS.model,
9561
- endpoint: pick("endpoint", "string", repo, user) ?? DEFAULTS.endpoint,
9562
- concurrency: pick("concurrency", "number", repo, user) ?? DEFAULTS.concurrency,
9563
- timeoutMs: pick("timeoutMs", "number", repo, user) ?? DEFAULTS.timeoutMs,
9573
+ model: pickFrom("model", TEXT) ?? DEFAULTS.model,
9574
+ endpoint: pickFrom("endpoint", URL_TEXT) ?? DEFAULTS.endpoint,
9575
+ concurrency: pickFrom("concurrency", WHOLE) ?? DEFAULTS.concurrency,
9576
+ timeoutMs: pickFrom("timeoutMs", POSITIVE) ?? DEFAULTS.timeoutMs,
9564
9577
  budget: {
9565
- maxCalls: pickIn("budget", "maxCalls", repo, user) ?? DEFAULTS.budget.maxCalls,
9566
- maxUsd: pickIn("budget", "maxUsd", repo, user) ?? DEFAULTS.budget.maxUsd
9578
+ maxCalls: pickFrom("budget.maxCalls", NON_NEGATIVE) ?? DEFAULTS.budget.maxCalls,
9579
+ maxUsd: pickFrom("budget.maxUsd", NON_NEGATIVE) ?? DEFAULTS.budget.maxUsd
9567
9580
  },
9568
9581
  egress: {
9569
9582
  consent: readConsent(repo, repoFile),
@@ -9572,7 +9585,7 @@ function loadConfig(options = {}) {
9572
9585
  ...stringList(repo, "egress.exclude", repoFile)
9573
9586
  ]
9574
9587
  },
9575
- profiles: [...profileList(user, userFile), ...profileList(repo, repoFile)],
9588
+ profiles: [...profileList(user, userFile, warnings), ...profileList(repo, repoFile, warnings)],
9576
9589
  route: readRoute(user, userFile, repo, repoFile, env)
9577
9590
  };
9578
9591
  const key = resolveApiKey(env, userDir);
@@ -9591,11 +9604,15 @@ function loadConfig(options = {}) {
9591
9604
  ...user ? { user: userFile } : {},
9592
9605
  ...repo ? { repo: repoFile } : {},
9593
9606
  ...key?.file ? { credentials: key.file } : {}
9594
- }
9607
+ },
9608
+ warnings
9595
9609
  };
9596
9610
  }
9597
9611
  function allProfiles(config) {
9598
- return [...PROFILES, ...config.profiles];
9612
+ const byId = /* @__PURE__ */ new Map();
9613
+ for (const profile of [...PROFILES, ...config.profiles])
9614
+ byId.set(profile.id, profile);
9615
+ return [...byId.values()];
9599
9616
  }
9600
9617
  function readLayer(file) {
9601
9618
  if (!existsSync(file))
@@ -9615,25 +9632,73 @@ function readLayer(file) {
9615
9632
  }
9616
9633
  return parsed;
9617
9634
  }
9618
- function pick(key, type, ...layers2) {
9619
- for (const layer of layers2) {
9620
- const value = layer?.[key];
9621
- if (typeof value === type)
9622
- return value;
9635
+ var KNOWN = {
9636
+ "": ["model", "endpoint", "concurrency", "timeoutMs", "budget", "egress", "profiles", "route"],
9637
+ budget: ["maxCalls", "maxUsd"],
9638
+ egress: ["consent", "exclude"]
9639
+ };
9640
+ function unknownKeys(layer, file, which2) {
9641
+ if (!layer)
9642
+ return [];
9643
+ const warnings = Object.keys(layer).filter((k) => !KNOWN[""]?.includes(k)).map((key) => `${file}: unknown key ${key}`);
9644
+ for (const section2 of ["budget", "egress"]) {
9645
+ const value = layer[section2];
9646
+ if (value === void 0 || value === null)
9647
+ continue;
9648
+ if (!isMapping(value)) {
9649
+ warnings.push(`${file}: ${section2} must be a mapping (ignored)`);
9650
+ continue;
9651
+ }
9652
+ for (const key of Object.keys(value)) {
9653
+ if (!KNOWN[section2]?.includes(key))
9654
+ warnings.push(`${file}: unknown key ${section2}.${key}`);
9655
+ }
9623
9656
  }
9624
- return void 0;
9657
+ const egress = layer.egress;
9658
+ if (which2 === "user" && isMapping(egress) && egress.consent !== void 0) {
9659
+ warnings.push(`${file}: egress.consent is read only from the repo file (ignored)`);
9660
+ }
9661
+ return warnings;
9625
9662
  }
9626
- function pickIn(section2, key, ...layers2) {
9627
- for (const layer of layers2) {
9628
- const value = layer?.[section2]?.[key];
9629
- if (typeof value === "number" && value >= 0)
9630
- return value;
9663
+ var TEXT = { ok: (v) => typeof v === "string", expected: "text" };
9664
+ var URL_TEXT = {
9665
+ ok: (v) => typeof v === "string" && URL.canParse(v) && /^https?:$/.test(new URL(v).protocol),
9666
+ expected: "an http(s) URL"
9667
+ };
9668
+ var WHOLE = {
9669
+ ok: (v) => Number.isInteger(v) && v >= 1,
9670
+ expected: "a whole number of at least 1"
9671
+ };
9672
+ var POSITIVE = {
9673
+ ok: (v) => typeof v === "number" && Number.isFinite(v) && v > 0,
9674
+ expected: "a number above 0"
9675
+ };
9676
+ var NON_NEGATIVE = {
9677
+ ok: (v) => typeof v === "number" && Number.isFinite(v) && v >= 0,
9678
+ expected: "a number of at least 0"
9679
+ };
9680
+ function pick(path, rule, layers2, warnings) {
9681
+ let found2;
9682
+ for (const { layer, file } of layers2) {
9683
+ const [head, key] = path.split(".");
9684
+ let value = layer?.[head];
9685
+ if (key !== void 0)
9686
+ value = isMapping(value) ? value[key] : void 0;
9687
+ if (value === void 0 || value === null)
9688
+ continue;
9689
+ if (!rule.ok(value))
9690
+ warnings.push(`${file}: ${path} must be ${rule.expected} (ignored)`);
9691
+ else if (found2 === void 0)
9692
+ found2 = value;
9631
9693
  }
9632
- return void 0;
9694
+ return found2;
9695
+ }
9696
+ function isMapping(value) {
9697
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9633
9698
  }
9634
9699
  function readConsent(repo, file) {
9635
9700
  const consent = repo?.egress?.consent;
9636
- if (consent === void 0)
9701
+ if (consent === void 0 || consent === null)
9637
9702
  return { granted: false };
9638
9703
  if (typeof consent !== "object" || consent === null || typeof consent.granted !== "boolean") {
9639
9704
  throw new DecisionsError("config-error", `${file}: egress.consent must be {granted: true|false, at?, by?}`, { file });
@@ -9647,7 +9712,7 @@ function readConsent(repo, file) {
9647
9712
  }
9648
9713
  function stringList(layer, path, file) {
9649
9714
  const value = layer?.egress?.exclude;
9650
- if (value === void 0)
9715
+ if (value === void 0 || value === null)
9651
9716
  return [];
9652
9717
  if (!Array.isArray(value) || !value.every((v) => typeof v === "string")) {
9653
9718
  throw new DecisionsError("config-error", `${file}: ${path} must be a list of glob patterns`, {
@@ -9656,29 +9721,57 @@ function stringList(layer, path, file) {
9656
9721
  }
9657
9722
  return value;
9658
9723
  }
9659
- function profileList(layer, file) {
9724
+ var PROFILE_FIELDS = [
9725
+ "id",
9726
+ "displayName",
9727
+ "transport",
9728
+ "maxStateTokens",
9729
+ "maxChoices",
9730
+ "callOverheadTokens",
9731
+ "usdPerInputToken",
9732
+ "usdPerOutputToken",
9733
+ "priceAsOf",
9734
+ "undecidedFloor",
9735
+ "calibrated"
9736
+ ];
9737
+ function profileList(layer, file, warnings) {
9660
9738
  const value = layer?.profiles;
9661
- if (value === void 0)
9739
+ if (value === void 0 || value === null)
9662
9740
  return [];
9663
9741
  if (!Array.isArray(value))
9664
9742
  throw new DecisionsError("config-error", `${file}: profiles must be a list`, { file });
9665
9743
  return value.map((p, i) => {
9666
- const profile = p;
9744
+ const profile = { ...p };
9745
+ for (const [key, v] of Object.entries(profile)) {
9746
+ if (v === null && PROFILE_FIELDS.includes(key)) {
9747
+ delete profile[key];
9748
+ }
9749
+ }
9667
9750
  const ok = typeof profile.id === "string" && typeof profile.maxStateTokens === "number" && typeof profile.usdPerInputToken === "number" && typeof profile.undecidedFloor === "number";
9668
9751
  if (!ok) {
9669
9752
  throw new DecisionsError("config-error", `${file}: profiles[${i}] needs id, maxStateTokens, usdPerInputToken and undecidedFloor`, { file });
9670
9753
  }
9754
+ if (profile.callOverheadTokens !== void 0 && !(Number.isInteger(profile.callOverheadTokens) && profile.callOverheadTokens >= 0)) {
9755
+ throw new DecisionsError("config-error", `${file}: profiles[${i}].callOverheadTokens must be a whole number of at least 0`, { file });
9756
+ }
9671
9757
  if (profile.maxChoices !== void 0 && !(Number.isInteger(profile.maxChoices) && profile.maxChoices >= 2)) {
9672
9758
  throw new DecisionsError("config-error", `${file}: profiles[${i}].maxChoices must be a whole number of at least 2`, { file });
9673
9759
  }
9760
+ const extra = Object.keys(profile).filter((k) => !PROFILE_FIELDS.includes(k));
9761
+ for (const key of extra) {
9762
+ warnings.push(`${file}: unknown key profiles[${i}].${key} (ignored)`);
9763
+ delete profile[key];
9764
+ }
9674
9765
  return {
9675
9766
  displayName: profile.id,
9676
9767
  transport: "openrouter-decisions",
9677
9768
  usdPerOutputToken: 0,
9678
9769
  priceAsOf: "unknown",
9679
9770
  calibrated: true,
9680
- // Same wire contract as Jev unless the config says otherwise.
9771
+ // Same wire contract as Jev unless the config says otherwise. The overhead is
9772
+ // Jev's measured one: unknown for another model, but it errs toward stopping.
9681
9773
  maxChoices: 255,
9774
+ callOverheadTokens: JEV_CALL_OVERHEAD_TOKENS,
9682
9775
  ...profile
9683
9776
  };
9684
9777
  });
@@ -9784,7 +9877,7 @@ function setConsent(repoRoot, granted, by, now = /* @__PURE__ */ new Date()) {
9784
9877
  function assertConsent(consent, repoRoot) {
9785
9878
  if (consent.granted)
9786
9879
  return;
9787
- throw new DecisionsError("egress-refused", `This repo has not agreed to send content to the decision model's provider. Consent is the user's: they run \`decide config egress allow\` in ${repoRoot} themselves (the setup skill explains what gets sent). Replay of recorded answers works without consent.`, { repoRoot });
9880
+ throw new DecisionsError("egress-refused", `This repo has not agreed to send content to the decision model's provider. Consent is the user's, and an agent must not grant it: the user runs \`decide config egress allow\` themselves in a terminal in ${repoRoot}, or through their agent prompt's shell escape (not as a chat message) with --confirm added. The setup skill explains what gets sent. Replay of recorded answers works without consent.`, { repoRoot });
9788
9881
  }
9789
9882
 
9790
9883
  // ../core/dist/egress/exclude.js
@@ -19433,40 +19526,36 @@ function describeExpectation(expectation) {
19433
19526
  }
19434
19527
 
19435
19528
  // ../core/dist/spec/spec.js
19436
- var Threshold = typebox_exports.Object({ value: typebox_exports.Number(), why: typebox_exports.String({ minLength: 1 }) });
19529
+ var CLOSED = { additionalProperties: false };
19530
+ var Threshold = typebox_exports.Object({ value: typebox_exports.Number(), why: typebox_exports.String({ minLength: 1 }) }, CLOSED);
19437
19531
  var SPEC_FORMAT = 1;
19438
- var SpecSchema = typebox_exports.Object(
19439
- {
19440
- /** Spec file format. Absent means 1; a newer one is refused, not guessed. */
19441
- version: typebox_exports.Optional(typebox_exports.Integer({ minimum: 1 })),
19442
- description: typebox_exports.String({ minLength: 1 }),
19443
- questions: typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown()),
19444
- keep: typebox_exports.Optional(typebox_exports.Array(typebox_exports.String())),
19445
- sort: typebox_exports.Optional(typebox_exports.String()),
19446
- policy: typebox_exports.Optional(typebox_exports.Object({ thresholds: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), Threshold)) })),
19447
- source: typebox_exports.Optional(typebox_exports.Object({
19448
- glob: typebox_exports.Optional(typebox_exports.Array(typebox_exports.String())),
19449
- file: typebox_exports.Optional(typebox_exports.String()),
19450
- jsonl: typebox_exports.Optional(typebox_exports.String()),
19451
- diff: typebox_exports.Optional(typebox_exports.String()),
19452
- split: typebox_exports.Optional(typebox_exports.String())
19453
- })),
19454
- examples: typebox_exports.Optional(typebox_exports.Array(typebox_exports.Object({
19455
- id: typebox_exports.String({ minLength: 1 }),
19456
- /** The text (or a JSON value, sent as its JSON text) to judge. Give this or `file`. */
19457
- state: typebox_exports.Optional(typebox_exports.Unknown()),
19458
- /** A repo file to judge, `path` or `path:START-END`. Give this or `state`. */
19459
- file: typebox_exports.Optional(typebox_exports.String()),
19460
- expect: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown()))
19461
- }))),
19462
- provenance: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown())),
19463
- /** Anything else a team wants to carry, ignored by the engine. */
19464
- meta: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown()))
19465
- },
19466
- // A misspelled key (`kepe:`, `exepct:`) must fail rather than silently
19467
- // becoming no policy at all.
19468
- { additionalProperties: false }
19469
- );
19532
+ var SpecSchema = typebox_exports.Object({
19533
+ /** Spec file format. Absent means 1; a newer one is refused, not guessed. */
19534
+ version: typebox_exports.Optional(typebox_exports.Integer({ minimum: 1 })),
19535
+ description: typebox_exports.String({ minLength: 1 }),
19536
+ questions: typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown()),
19537
+ keep: typebox_exports.Optional(typebox_exports.Array(typebox_exports.String())),
19538
+ sort: typebox_exports.Optional(typebox_exports.String()),
19539
+ policy: typebox_exports.Optional(typebox_exports.Object({ thresholds: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), Threshold)) }, CLOSED)),
19540
+ source: typebox_exports.Optional(typebox_exports.Object({
19541
+ glob: typebox_exports.Optional(typebox_exports.Array(typebox_exports.String())),
19542
+ file: typebox_exports.Optional(typebox_exports.String()),
19543
+ jsonl: typebox_exports.Optional(typebox_exports.String()),
19544
+ diff: typebox_exports.Optional(typebox_exports.String()),
19545
+ split: typebox_exports.Optional(typebox_exports.String())
19546
+ }, CLOSED)),
19547
+ examples: typebox_exports.Optional(typebox_exports.Array(typebox_exports.Object({
19548
+ id: typebox_exports.String({ minLength: 1 }),
19549
+ /** The text (or a JSON value, sent as its JSON text) to judge. Give this or `file`. */
19550
+ state: typebox_exports.Optional(typebox_exports.Unknown()),
19551
+ /** A repo file to judge, `path` or `path:START-END`. Give this or `state`. */
19552
+ file: typebox_exports.Optional(typebox_exports.String()),
19553
+ expect: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown()))
19554
+ }, CLOSED))),
19555
+ provenance: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown())),
19556
+ /** Anything else a team wants to carry, ignored by the engine. */
19557
+ meta: typebox_exports.Optional(typebox_exports.Record(typebox_exports.String(), typebox_exports.Unknown()))
19558
+ }, CLOSED);
19470
19559
  var NAME = /^[a-z0-9][a-z0-9._-]*$/;
19471
19560
  function parseSpec(text, file, origin) {
19472
19561
  let raw;
@@ -20116,7 +20205,7 @@ function ledgerFor(ctx) {
20116
20205
 
20117
20206
  // ../core/dist/run/budget.js
20118
20207
  function project2(profile, tokensPerCall) {
20119
- const estimatedInputTokens = tokensPerCall.reduce((a, b) => a + b, 0);
20208
+ const estimatedInputTokens = tokensPerCall.reduce((sum, tokens) => sum + tokens + profile.callOverheadTokens, 0);
20120
20209
  return {
20121
20210
  basis: "projected",
20122
20211
  calls: tokensPerCall.length,
@@ -20125,6 +20214,16 @@ function project2(profile, tokensPerCall) {
20125
20214
  priceAsOf: profile.priceAsOf
20126
20215
  };
20127
20216
  }
20217
+ function combineProjections(profile, parts) {
20218
+ const estimatedInputTokens = parts.reduce((sum, p) => sum + p.estimatedInputTokens, 0);
20219
+ return {
20220
+ basis: "projected",
20221
+ calls: parts.reduce((sum, p) => sum + p.calls, 0),
20222
+ estimatedInputTokens,
20223
+ projectedUsd: estimatedInputTokens * profile.usdPerInputToken,
20224
+ priceAsOf: profile.priceAsOf
20225
+ };
20226
+ }
20128
20227
  function checkBudget(projection, budget, confirmed) {
20129
20228
  if (confirmed)
20130
20229
  return;
@@ -20457,18 +20556,26 @@ async function runDoctor(options) {
20457
20556
  return report2(void 0, false);
20458
20557
  }
20459
20558
  const { config } = ctx;
20559
+ if (config.warnings.length > 0) {
20560
+ checks.push({
20561
+ name: "config-keys",
20562
+ status: "warn",
20563
+ detail: `ignored: ${config.warnings.join("; ")}`,
20564
+ fix: "correct or remove these keys (docs/configuration.md lists every key)"
20565
+ });
20566
+ }
20460
20567
  checks.push(config.apiKey ? { name: "key", status: "ok", detail: `OPENROUTER_API_KEY present (${config.apiKeySource})` } : {
20461
20568
  name: "key",
20462
20569
  status: "warn",
20463
20570
  detail: "no API key: only replay works",
20464
20571
  // The file this shell would read: XDG_CONFIG_HOME moves it.
20465
- fix: `set OPENROUTER_API_KEY, or write \`openrouter_api_key: <key>\` to ${join5(userConfigDir(env, options.home), "credentials")} (chmod 600)`
20572
+ fix: `set OPENROUTER_API_KEY, or write \`openrouter_api_key: <key>\` to ${join5(userConfigDir(env, options.home), "credentials")} (create its directory first; chmod 600)`
20466
20573
  });
20467
20574
  checks.push(config.egress.consent.granted ? { name: "consent", status: "ok", detail: `egress consent granted for ${config.repoRoot}` } : {
20468
20575
  name: "consent",
20469
20576
  status: "warn",
20470
20577
  detail: `no egress consent for ${config.repoRoot}: live calls are refused`,
20471
- fix: "the user runs `decide config egress allow` in this repo, if they agree"
20578
+ fix: "if the user agrees, they grant it themselves (an agent must not): `decide config egress allow` in a terminal in this repo, or through their agent prompt's shell escape (not as a chat message) with --confirm added"
20472
20579
  });
20473
20580
  checks.push(routeCheck(config.route));
20474
20581
  let reach;
@@ -20669,8 +20776,8 @@ async function runSpecCheck(ctx, rawInput) {
20669
20776
  const decider = deciderFor(ctx, profile, input.mode ?? "replay");
20670
20777
  if (decider.mode !== "replay") {
20671
20778
  assertConsent(ctx.config.egress.consent, root);
20672
- const tokens = prepared.flatMap((p) => p.prep ? [p.prep.projection.estimatedInputTokens] : []);
20673
- checkBudget(project2(profile, tokens), ctx.config.budget, input.confirm ?? false);
20779
+ const parts = prepared.flatMap((p) => p.prep ? [p.prep.projection] : []);
20780
+ checkBudget(combineProjections(profile, parts), ctx.config.budget, input.confirm ?? false);
20674
20781
  }
20675
20782
  const results = [];
20676
20783
  const usages = [];
@@ -20792,10 +20899,13 @@ function nonEmpty3(value) {
20792
20899
  }
20793
20900
 
20794
20901
  export {
20902
+ activeTriggers,
20795
20903
  repoConfigPath,
20796
20904
  loadConfig,
20905
+ allProfiles,
20797
20906
  setConsent,
20798
20907
  DEFAULT_EXCLUDES,
20908
+ probeUrl,
20799
20909
  ping,
20800
20910
  parseFileRef,
20801
20911
  exampleProblems,
@@ -2,10 +2,10 @@ import { createRequire as __decideRequire } from "node:module"; const require =
2
2
  import {
3
3
  parseFileRef,
4
4
  parseQuestionSet
5
- } from "./chunk-S5AIBUL7.mjs";
5
+ } from "./chunk-5TUBFH7M.mjs";
6
6
  import {
7
7
  DecisionsError
8
- } from "./chunk-NUIZJRI6.mjs";
8
+ } from "./chunk-4ZZ3ZSJN.mjs";
9
9
 
10
10
  // src/args.ts
11
11
  import { readFileSync } from "node:fs";
@@ -1,18 +1,20 @@
1
1
  import { createRequire as __decideRequire } from "node:module"; const require = __decideRequire(import.meta.url);
2
2
  import {
3
3
  typedParse
4
- } from "./chunk-4BSTNWLV.mjs";
4
+ } from "./chunk-BGL272OK.mjs";
5
5
  import {
6
6
  DEFAULT_EXCLUDES,
7
+ activeTriggers,
8
+ allProfiles,
7
9
  createContext,
8
10
  loadConfig,
9
11
  repoConfigPath,
10
12
  setConsent
11
- } from "./chunk-S5AIBUL7.mjs";
13
+ } from "./chunk-5TUBFH7M.mjs";
12
14
  import {
13
15
  DecisionsError,
14
16
  emit
15
- } from "./chunk-NUIZJRI6.mjs";
17
+ } from "./chunk-4ZZ3ZSJN.mjs";
16
18
 
17
19
  // src/commands/config.ts
18
20
  function runConfigCommand(argv, io, format) {
@@ -49,12 +51,17 @@ function body(argv, io) {
49
51
  if (!io.interactive && !values.confirm) {
50
52
  throw new DecisionsError(
51
53
  "egress-refused",
52
- "Egress consent is the user's decision. Ask the user to run `decide config egress allow` themselves (in Claude Code: `! decide config egress allow`)."
54
+ "Egress consent is the user's decision. An agent must not grant it, with or without --confirm: show the user this message instead. The user grants it by typing `decide config egress allow` in a terminal at the repo root. If they run it through their agent prompt's shell escape instead (not as a chat message), there is no terminal, so they add --confirm to say the decision is theirs."
53
55
  );
54
56
  }
55
57
  return {
56
58
  egress: {
57
- consent: setConsent(config.repoRoot, true, values.by ?? "decide config"),
59
+ // Record which route granted it: a terminal, or --confirm without one.
60
+ consent: setConsent(
61
+ config.repoRoot,
62
+ true,
63
+ values.by ?? (io.interactive ? "decide config" : "decide config --confirm")
64
+ ),
58
65
  file,
59
66
  changed: true
60
67
  }
@@ -82,6 +89,7 @@ function show(io, cwd) {
82
89
  model: config.model,
83
90
  endpoint: config.endpoint,
84
91
  concurrency: config.concurrency,
92
+ timeoutMs: config.timeoutMs,
85
93
  budget: config.budget,
86
94
  egress: {
87
95
  consent: config.egress.consent,
@@ -92,8 +100,15 @@ function show(io, cwd) {
92
100
  replay: config.replay,
93
101
  session: config.session ?? null,
94
102
  sessionOrigin: config.sessionOrigin ?? null,
103
+ /**
104
+ * The profiles in effect for the ids the config files set, one per id: an
105
+ * override of a built-in shows once. Built-ins nobody overrides are not repeated.
106
+ */
107
+ profiles: allProfiles(config).filter((p) => config.profiles.some((c) => c.id === p.id)),
108
+ route: config.route,
95
109
  files: config.layers,
96
- specDirs: ctx.specDirs
110
+ specDirs: ctx.specDirs,
111
+ warnings: config.warnings
97
112
  };
98
113
  }
99
114
  function brief(r) {
@@ -106,12 +121,24 @@ function brief(r) {
106
121
  `repo: ${r.repoRoot}`,
107
122
  `model: ${r.model} via ${r.endpoint}`,
108
123
  `key: ${r.apiKey}${r.replay ? " \xB7 SYSTEM1_REPLAY forces replay" : ""}`,
109
- `egress consent: ${c.granted ? `granted ${c.at ?? ""}`.trim() : "not granted \u2014 run `decide config egress allow`"}`,
124
+ `egress consent: ${c.granted ? `granted ${c.at ?? ""}`.trim() : "not granted (the user grants it; see `decide doctor`)"}`,
110
125
  `excludes: ${r.egress.defaultExcludes} default${r.egress.exclude.length ? ` + ${r.egress.exclude.join(", ")}` : ""}`,
111
- `budget: ${r.budget.maxCalls} calls / $${r.budget.maxUsd} per request \xB7 concurrency ${r.concurrency}`,
112
- `session: ${r.session ? `${r.session} (${r.sessionOrigin === "env" ? "SYSTEM1_SESSION" : `detected from ${r.sessionOrigin}`})` : "none"}`
126
+ `budget: ${r.budget.maxCalls} calls / $${r.budget.maxUsd} per request \xB7 concurrency ${r.concurrency} \xB7 timeout ${r.timeoutMs} ms`,
127
+ ...r.profiles.length ? [`profiles: ${r.profiles.map((p) => p.id).join(", ")}`] : [],
128
+ `route: ${routeLine(r.route)}`,
129
+ `session: ${r.session ? `${r.session} (${r.sessionOrigin === "env" ? "SYSTEM1_SESSION" : `detected from ${r.sessionOrigin}`})` : "none"}`,
130
+ ...r.warnings.length ? [`ignored: ${r.warnings.join("; ")}`] : []
113
131
  ].join("\n");
114
132
  }
133
+ function routeLine(route) {
134
+ if (!route.enabled) return "off";
135
+ try {
136
+ const names = activeTriggers(route).map((t) => t.name);
137
+ return `on \xB7 ${names.join(", ") || "no triggers"}`;
138
+ } catch (error) {
139
+ return `invalid (${error instanceof Error ? error.message : String(error)})`;
140
+ }
141
+ }
115
142
  export {
116
143
  CONFIG_OPTIONS,
117
144
  runConfigCommand
@@ -6,17 +6,17 @@ import {
6
6
  import {
7
7
  buildInput,
8
8
  parseDecideFlags
9
- } from "./chunk-4BSTNWLV.mjs";
9
+ } from "./chunk-BGL272OK.mjs";
10
10
  import {
11
11
  createContext,
12
12
  runAsk,
13
13
  runMany
14
- } from "./chunk-S5AIBUL7.mjs";
14
+ } from "./chunk-5TUBFH7M.mjs";
15
15
  import {
16
16
  DecisionsError,
17
17
  ENVELOPE_VERSION,
18
18
  emit
19
- } from "./chunk-NUIZJRI6.mjs";
19
+ } from "./chunk-4ZZ3ZSJN.mjs";
20
20
 
21
21
  // src/commands/decide.ts
22
22
  import { readFileSync } from "node:fs";
@@ -1,10 +1,10 @@
1
1
  import { createRequire as __decideRequire } from "node:module"; const require = __decideRequire(import.meta.url);
2
2
  import {
3
3
  runDoctor
4
- } from "./chunk-S5AIBUL7.mjs";
4
+ } from "./chunk-5TUBFH7M.mjs";
5
5
  import {
6
6
  emit
7
- } from "./chunk-NUIZJRI6.mjs";
7
+ } from "./chunk-4ZZ3ZSJN.mjs";
8
8
 
9
9
  // src/commands/doctor.ts
10
10
  import { execFile } from "node:child_process";
@@ -1,19 +1,22 @@
1
1
  import { createRequire as __decideRequire } from "node:module"; const require = __decideRequire(import.meta.url);
2
2
  import {
3
3
  typedParse
4
- } from "./chunk-4BSTNWLV.mjs";
4
+ } from "./chunk-BGL272OK.mjs";
5
5
  import {
6
6
  TOOL_SCHEMAS,
7
7
  createContext,
8
+ loadConfig,
8
9
  ping,
10
+ probeUrl,
9
11
  resolveConnection,
10
12
  runUsage
11
- } from "./chunk-S5AIBUL7.mjs";
13
+ } from "./chunk-5TUBFH7M.mjs";
12
14
  import {
13
15
  DecisionsError,
14
16
  EXIT,
15
- emit
16
- } from "./chunk-NUIZJRI6.mjs";
17
+ emit,
18
+ isDecisionsError
19
+ } from "./chunk-4ZZ3ZSJN.mjs";
17
20
 
18
21
  // src/commands/misc.ts
19
22
  function runSchemaCommand(argv, io, format) {
@@ -55,7 +58,20 @@ async function runPingCommand(io, format) {
55
58
  "ping",
56
59
  format,
57
60
  async () => {
58
- const result = await ping(resolveConnection(io.env), io.fetch ? { fetch: io.fetch } : {});
61
+ const { config, configError } = connection(io);
62
+ try {
63
+ probeUrl(config);
64
+ } catch {
65
+ throw new DecisionsError(
66
+ "config-error",
67
+ `endpoint ${config.endpoint} is not a URL: correct SYSTEM1_ENDPOINT or \`endpoint\` in the config file`,
68
+ { endpoint: config.endpoint }
69
+ );
70
+ }
71
+ const result = {
72
+ ...await ping(config, io.fetch ? { fetch: io.fetch } : {}),
73
+ ...configError ? { configError } : {}
74
+ };
59
75
  failed = !result.ok;
60
76
  if (!result.ok && format !== "brief") {
61
77
  throw new DecisionsError("provider-unreachable", result.error ?? "unreachable", {
@@ -67,11 +83,28 @@ async function runPingCommand(io, format) {
67
83
  (r, f) => {
68
84
  if (f !== "brief") return void 0;
69
85
  const key = r.keyPresent ? "key: present" : "key: absent (replay only)";
70
- return r.ok ? `decide ping: ok \u2014 ${r.model} reachable in ${r.latencyMs} ms (${key})` : `decide ping: FAILED \u2014 ${r.probe}: ${r.error} (${key})`;
86
+ const line = r.ok ? `decide ping: ok \u2014 ${r.model} reachable in ${r.latencyMs} ms (${key})` : `decide ping: FAILED \u2014 ${r.probe}: ${r.error} (${key})`;
87
+ return r.configError ? `${line}
88
+ config not loaded, so this used the environment only: ${r.configError}` : line;
71
89
  }
72
90
  );
73
91
  return failed ? EXIT.providerError : code;
74
92
  }
93
+ function connection(io) {
94
+ try {
95
+ const config = loadConfig({
96
+ cwd: io.cwd ?? process.cwd(),
97
+ env: io.env,
98
+ ...io.home ? { home: io.home } : {}
99
+ });
100
+ const { endpoint, model, apiKey, replay } = config;
101
+ return { config: { endpoint, model, apiKey, replay } };
102
+ } catch (error) {
103
+ if (isDecisionsError(error) && error.code === "config-error")
104
+ return { config: resolveConnection(io.env), configError: error.message };
105
+ throw error;
106
+ }
107
+ }
75
108
  export {
76
109
  USAGE_OPTIONS,
77
110
  runPingCommand,
@@ -1,14 +1,14 @@
1
1
  import { createRequire as __decideRequire } from "node:module"; const require = __decideRequire(import.meta.url);
2
2
  import {
3
3
  typedParse
4
- } from "./chunk-4BSTNWLV.mjs";
4
+ } from "./chunk-BGL272OK.mjs";
5
5
  import {
6
6
  runRoute
7
- } from "./chunk-S5AIBUL7.mjs";
7
+ } from "./chunk-5TUBFH7M.mjs";
8
8
  import {
9
9
  DecisionsError,
10
10
  emit
11
- } from "./chunk-NUIZJRI6.mjs";
11
+ } from "./chunk-4ZZ3ZSJN.mjs";
12
12
 
13
13
  // src/commands/route.ts
14
14
  import { readFileSync } from "node:fs";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-5LVOFZF3.mjs";
5
5
  import {
6
6
  typedParse
7
- } from "./chunk-4BSTNWLV.mjs";
7
+ } from "./chunk-BGL272OK.mjs";
8
8
  import {
9
9
  assertExamples,
10
10
  createContext,
@@ -12,11 +12,12 @@ import {
12
12
  listSpecs,
13
13
  loadSpec,
14
14
  runSpecCheck
15
- } from "./chunk-S5AIBUL7.mjs";
15
+ } from "./chunk-5TUBFH7M.mjs";
16
16
  import {
17
17
  DecisionsError,
18
+ EXIT,
18
19
  emit
19
- } from "./chunk-NUIZJRI6.mjs";
20
+ } from "./chunk-4ZZ3ZSJN.mjs";
20
21
 
21
22
  // src/commands/spec.ts
22
23
  function runSpecCommand(argv, io, format) {
@@ -70,13 +71,7 @@ function runSpecCommand(argv, io, format) {
70
71
  (r, f) => f === "brief" ? `valid: ${r.valid.join(", ") || "(none)"}` : void 0
71
72
  );
72
73
  case "check":
73
- return emit(
74
- io,
75
- "spec",
76
- format,
77
- () => runSpecCheck(ctx(), checkInput(argv.slice(1))),
78
- (r, f) => f === "brief" ? briefSpecCheck(r) : void 0
79
- );
74
+ return check(argv.slice(1), io, format, ctx);
80
75
  default:
81
76
  return emit(io, "spec", format, () => {
82
77
  throw new DecisionsError(
@@ -86,13 +81,28 @@ function runSpecCommand(argv, io, format) {
86
81
  });
87
82
  }
88
83
  }
84
+ async function check(argv, io, format, ctx) {
85
+ let failed = false;
86
+ const code = await emit(
87
+ io,
88
+ "spec",
89
+ format,
90
+ async () => {
91
+ const result = await runSpecCheck(ctx(), checkInput(argv));
92
+ failed = !result.passed;
93
+ return result;
94
+ },
95
+ (r, f) => f === "brief" ? briefSpecCheck(r) : void 0
96
+ );
97
+ return code === EXIT.ok && failed && parse(argv).values.strict ? EXIT.checkFailed : code;
98
+ }
89
99
  function checkInput(argv) {
90
100
  const { values, positionals } = parse(argv);
91
101
  const [spec, extra] = positionals;
92
102
  if (!spec || extra !== void 0) {
93
103
  throw new DecisionsError(
94
104
  "invalid-request",
95
- "Usage: decide spec check <name|path> [--live] [--confirm] [--model <id>]"
105
+ "Usage: decide spec check <name|path> [--live] [--confirm] [--model <id>] [--strict]"
96
106
  );
97
107
  }
98
108
  if (values.live && values.replay) {
@@ -109,7 +119,8 @@ var SPEC_OPTIONS = {
109
119
  live: { type: "boolean" },
110
120
  replay: { type: "boolean" },
111
121
  confirm: { type: "boolean" },
112
- model: { type: "string" }
122
+ model: { type: "string" },
123
+ strict: { type: "boolean" }
113
124
  };
114
125
  function parse(argv) {
115
126
  return typedParse({
@@ -4,4 +4,4 @@ import { createRequire as __decideRequire } from "node:module"; const require =
4
4
  // src/entry.ts
5
5
  import module from "node:module";
6
6
  module.enableCompileCache?.();
7
- await import("./chunks/bin-TCIHP5PC.mjs");
7
+ await import("./chunks/bin-3EWFISFQ.mjs");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@garygentry/system1",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "The `decide` CLI: typed, calibrated decisions for coding agents, hooks and CI.",
5
5
  "type": "module",
6
6
  "license": "MIT",