things-api 0.10.0 → 0.12.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 (239) hide show
  1. package/README.md +50 -13
  2. package/dist/audit/schema.d.ts +7 -0
  3. package/dist/audit/schema.js.map +1 -1
  4. package/dist/cli/clock.d.ts +8 -0
  5. package/dist/cli/clock.js +24 -0
  6. package/dist/cli/clock.js.map +1 -0
  7. package/dist/cli/commands/area.d.ts +18 -11
  8. package/dist/cli/commands/area.js +61 -74
  9. package/dist/cli/commands/area.js.map +1 -1
  10. package/dist/cli/commands/doctor.d.ts +1 -2
  11. package/dist/cli/commands/doctor.js +11 -1
  12. package/dist/cli/commands/doctor.js.map +1 -1
  13. package/dist/cli/commands/install-skill.d.ts +60 -0
  14. package/dist/cli/commands/install-skill.js +256 -0
  15. package/dist/cli/commands/install-skill.js.map +1 -0
  16. package/dist/cli/commands/mcp.js +9 -0
  17. package/dist/cli/commands/mcp.js.map +1 -1
  18. package/dist/cli/commands/project.d.ts +1 -0
  19. package/dist/cli/commands/project.js +27 -34
  20. package/dist/cli/commands/project.js.map +1 -1
  21. package/dist/cli/commands/reads.d.ts +15 -2
  22. package/dist/cli/commands/reads.js +144 -44
  23. package/dist/cli/commands/reads.js.map +1 -1
  24. package/dist/cli/commands/setup.js +7 -2
  25. package/dist/cli/commands/setup.js.map +1 -1
  26. package/dist/cli/commands/show.js +38 -14
  27. package/dist/cli/commands/show.js.map +1 -1
  28. package/dist/cli/commands/todo.js +15 -9
  29. package/dist/cli/commands/todo.js.map +1 -1
  30. package/dist/cli/commands/writes.js +797 -174
  31. package/dist/cli/commands/writes.js.map +1 -1
  32. package/dist/cli/did-you-mean.d.ts +14 -3
  33. package/dist/cli/did-you-mean.js +26 -3
  34. package/dist/cli/did-you-mean.js.map +1 -1
  35. package/dist/cli/glyphs.d.ts +32 -2
  36. package/dist/cli/glyphs.js +83 -12
  37. package/dist/cli/glyphs.js.map +1 -1
  38. package/dist/cli/help.js +121 -16
  39. package/dist/cli/help.js.map +1 -1
  40. package/dist/cli/main.js +33 -2
  41. package/dist/cli/main.js.map +1 -1
  42. package/dist/cli/move-hint.d.ts +46 -0
  43. package/dist/cli/move-hint.js +196 -0
  44. package/dist/cli/move-hint.js.map +1 -0
  45. package/dist/cli/period.d.ts +2 -8
  46. package/dist/cli/period.js +44 -30
  47. package/dist/cli/period.js.map +1 -1
  48. package/dist/cli/read-driver.d.ts +43 -5
  49. package/dist/cli/read-driver.js +91 -15
  50. package/dist/cli/read-driver.js.map +1 -1
  51. package/dist/cli/render.d.ts +19 -8
  52. package/dist/cli/render.js +70 -27
  53. package/dist/cli/render.js.map +1 -1
  54. package/dist/cli/resolve-invocation.d.ts +2 -2
  55. package/dist/cli/resolve-invocation.js +3 -3
  56. package/dist/cli/resolve-invocation.js.map +1 -1
  57. package/dist/cli/skill-check.d.ts +27 -0
  58. package/dist/cli/skill-check.js +99 -0
  59. package/dist/cli/skill-check.js.map +1 -0
  60. package/dist/cli/skill.d.ts +70 -0
  61. package/dist/cli/skill.js +152 -0
  62. package/dist/cli/skill.js.map +1 -0
  63. package/dist/cli/tag-filters.d.ts +6 -2
  64. package/dist/cli/tag-filters.js +8 -6
  65. package/dist/cli/tag-filters.js.map +1 -1
  66. package/dist/cli/verb-hint.js +28 -3
  67. package/dist/cli/verb-hint.js.map +1 -1
  68. package/dist/cli/version.d.ts +4 -0
  69. package/dist/cli/version.js +18 -0
  70. package/dist/cli/version.js.map +1 -0
  71. package/dist/client.d.ts +171 -27
  72. package/dist/client.js +279 -40
  73. package/dist/client.js.map +1 -1
  74. package/dist/config.d.ts +66 -2
  75. package/dist/config.js +120 -12
  76. package/dist/config.js.map +1 -1
  77. package/dist/contracts.d.ts +186 -28
  78. package/dist/contracts.js +22 -1
  79. package/dist/contracts.js.map +1 -1
  80. package/dist/diagnose.d.ts +34 -2
  81. package/dist/diagnose.js +36 -1
  82. package/dist/diagnose.js.map +1 -1
  83. package/dist/index.d.ts +25 -9
  84. package/dist/index.js +22 -3
  85. package/dist/index.js.map +1 -1
  86. package/dist/mcp/server.d.ts +9 -0
  87. package/dist/mcp/server.js +1157 -684
  88. package/dist/mcp/server.js.map +1 -1
  89. package/dist/model/clock.d.ts +61 -0
  90. package/dist/model/clock.js +71 -0
  91. package/dist/model/clock.js.map +1 -0
  92. package/dist/model/dates.d.ts +26 -3
  93. package/dist/model/dates.js +84 -3
  94. package/dist/model/dates.js.map +1 -1
  95. package/dist/model/entities.d.ts +60 -3
  96. package/dist/model/entities.js.map +1 -1
  97. package/dist/model/mappers.d.ts +4 -2
  98. package/dist/model/mappers.js +66 -9
  99. package/dist/model/mappers.js.map +1 -1
  100. package/dist/model/recurrence.d.ts +8 -1
  101. package/dist/model/recurrence.js.map +1 -1
  102. package/dist/read/area-filter.d.ts +76 -0
  103. package/dist/read/area-filter.js +59 -0
  104. package/dist/read/area-filter.js.map +1 -0
  105. package/dist/read/area-view.d.ts +12 -12
  106. package/dist/read/area-view.js +58 -34
  107. package/dist/read/area-view.js.map +1 -1
  108. package/dist/read/detail.d.ts +1 -1
  109. package/dist/read/detail.js +26 -12
  110. package/dist/read/detail.js.map +1 -1
  111. package/dist/read/log-boundary.d.ts +1 -1
  112. package/dist/read/log-boundary.js +13 -3
  113. package/dist/read/log-boundary.js.map +1 -1
  114. package/dist/read/predicates.d.ts +18 -0
  115. package/dist/read/predicates.js +19 -0
  116. package/dist/read/predicates.js.map +1 -1
  117. package/dist/read/project-view.d.ts +32 -16
  118. package/dist/read/project-view.js +80 -45
  119. package/dist/read/project-view.js.map +1 -1
  120. package/dist/read/pseudo-area.d.ts +29 -0
  121. package/dist/read/pseudo-area.js +27 -0
  122. package/dist/read/pseudo-area.js.map +1 -0
  123. package/dist/read/queries.d.ts +108 -19
  124. package/dist/read/queries.js +212 -35
  125. package/dist/read/queries.js.map +1 -1
  126. package/dist/read/scope.d.ts +126 -0
  127. package/dist/read/scope.js +162 -0
  128. package/dist/read/scope.js.map +1 -0
  129. package/dist/read/search-rank.d.ts +2 -5
  130. package/dist/read/shape.d.ts +162 -0
  131. package/dist/read/shape.js +686 -0
  132. package/dist/read/shape.js.map +1 -0
  133. package/dist/read/show-target.d.ts +9 -1
  134. package/dist/read/show-target.js +45 -4
  135. package/dist/read/show-target.js.map +1 -1
  136. package/dist/read/snapshot.d.ts +1 -1
  137. package/dist/read/snapshot.js +9 -2
  138. package/dist/read/snapshot.js.map +1 -1
  139. package/dist/read/stage.d.ts +199 -0
  140. package/dist/read/stage.js +125 -0
  141. package/dist/read/stage.js.map +1 -0
  142. package/dist/read/truncation.d.ts +8 -6
  143. package/dist/read/truncation.js +35 -10
  144. package/dist/read/truncation.js.map +1 -1
  145. package/dist/read/views.d.ts +61 -20
  146. package/dist/read/views.js +240 -82
  147. package/dist/read/views.js.map +1 -1
  148. package/dist/surface-copy.d.ts +9 -0
  149. package/dist/surface-copy.js +9 -0
  150. package/dist/surface-copy.js.map +1 -1
  151. package/dist/write/accessibility-probe.d.ts +1 -1
  152. package/dist/write/accessibility-probe.js +8 -0
  153. package/dist/write/accessibility-probe.js.map +1 -1
  154. package/dist/write/automation-probe.d.ts +1 -1
  155. package/dist/write/automation-probe.js +8 -0
  156. package/dist/write/automation-probe.js.map +1 -1
  157. package/dist/write/batch.d.ts +49 -10
  158. package/dist/write/batch.js +423 -70
  159. package/dist/write/batch.js.map +1 -1
  160. package/dist/write/commands.d.ts +1 -1
  161. package/dist/write/commands.js +316 -66
  162. package/dist/write/commands.js.map +1 -1
  163. package/dist/write/guards.d.ts +1 -1
  164. package/dist/write/guards.js +94 -10
  165. package/dist/write/guards.js.map +1 -1
  166. package/dist/write/heading.d.ts +10 -1
  167. package/dist/write/heading.js +35 -5
  168. package/dist/write/heading.js.map +1 -1
  169. package/dist/write/make-repeating-project.d.ts +2 -2
  170. package/dist/write/make-repeating-project.js +9 -9
  171. package/dist/write/make-repeating-project.js.map +1 -1
  172. package/dist/write/move.d.ts +130 -0
  173. package/dist/write/move.js +1533 -0
  174. package/dist/write/move.js.map +1 -0
  175. package/dist/write/operations.d.ts +105 -19
  176. package/dist/write/operations.js +56 -7
  177. package/dist/write/operations.js.map +1 -1
  178. package/dist/write/opid.d.ts +31 -0
  179. package/dist/write/opid.js +30 -0
  180. package/dist/write/opid.js.map +1 -0
  181. package/dist/write/pipeline.d.ts +122 -3
  182. package/dist/write/pipeline.js +309 -52
  183. package/dist/write/pipeline.js.map +1 -1
  184. package/dist/write/planner.js +8 -1
  185. package/dist/write/planner.js.map +1 -1
  186. package/dist/write/pre-state.d.ts +197 -6
  187. package/dist/write/pre-state.js +427 -20
  188. package/dist/write/pre-state.js.map +1 -1
  189. package/dist/write/recurrence-rule-blob.d.ts +65 -0
  190. package/dist/write/recurrence-rule-blob.js +150 -0
  191. package/dist/write/recurrence-rule-blob.js.map +1 -0
  192. package/dist/write/reorder.d.ts +23 -3
  193. package/dist/write/reorder.js +1871 -85
  194. package/dist/write/reorder.js.map +1 -1
  195. package/dist/write/reversibility.js +19 -7
  196. package/dist/write/reversibility.js.map +1 -1
  197. package/dist/write/scope-guard.d.ts +31 -0
  198. package/dist/write/scope-guard.js +162 -0
  199. package/dist/write/scope-guard.js.map +1 -0
  200. package/dist/write/undo.js +120 -13
  201. package/dist/write/undo.js.map +1 -1
  202. package/dist/write/vectors/applescript.js +16 -7
  203. package/dist/write/vectors/applescript.js.map +1 -1
  204. package/dist/write/vectors/registry.d.ts +5 -7
  205. package/dist/write/vectors/registry.js +49 -2
  206. package/dist/write/vectors/registry.js.map +1 -1
  207. package/dist/write/vectors/shortcuts.js +1 -1
  208. package/dist/write/vectors/shortcuts.js.map +1 -1
  209. package/dist/write/vectors/simulator.d.ts +44 -0
  210. package/dist/write/vectors/simulator.js +1192 -0
  211. package/dist/write/vectors/simulator.js.map +1 -0
  212. package/dist/write/vectors/types.d.ts +46 -0
  213. package/dist/write/vectors/ui-certification.d.ts +10 -4
  214. package/dist/write/vectors/ui-certification.js +43 -10
  215. package/dist/write/vectors/ui-certification.js.map +1 -1
  216. package/dist/write/vectors/ui-drag.d.ts +21 -1
  217. package/dist/write/vectors/ui-drag.js +138 -27
  218. package/dist/write/vectors/ui-drag.js.map +1 -1
  219. package/dist/write/vectors/ui-recipes.d.ts +34 -1
  220. package/dist/write/vectors/ui-recipes.js +217 -6
  221. package/dist/write/vectors/ui-recipes.js.map +1 -1
  222. package/dist/write/vectors/ui.d.ts +40 -1
  223. package/dist/write/vectors/ui.js +196 -39
  224. package/dist/write/vectors/ui.js.map +1 -1
  225. package/dist/write/verify/delta.d.ts +127 -2
  226. package/dist/write/verify/delta.js +255 -16
  227. package/dist/write/verify/delta.js.map +1 -1
  228. package/dist/write/verify/poller.d.ts +7 -1
  229. package/dist/write/verify/poller.js +20 -1
  230. package/dist/write/verify/poller.js.map +1 -1
  231. package/package.json +24 -3
  232. package/schema/envelope.schema.json +383 -0
  233. package/skills/things-cli/SKILL.md +70 -0
  234. package/skills/things-cli/references/banner.md +35 -0
  235. package/skills/things-cli/references/contracts.md +62 -0
  236. package/skills/things-cli/references/errors.md +49 -0
  237. package/skills/things-cli/references/gui.md +11 -0
  238. package/skills/things-cli/references/model.md +60 -0
  239. package/skills/things-cli/references/ordering.md +71 -0
package/dist/config.d.ts CHANGED
@@ -11,10 +11,40 @@ export interface ThingsApiConfig {
11
11
  /** User-accepted drifted fingerprint (loud escape hatch; see design §6). */
12
12
  acceptedFingerprint: string | null;
13
13
  /**
14
- * Opt-in to capabilities riding undocumented app surfaces (the private
15
- * sdef reorder command). Guarded further by the pipeline's sdef canary.
14
+ * The Things app version the behavioral LAWS (docs/reference/assumption-register.md)
15
+ * were last certified against. Set when a baseline ships or by an explicit
16
+ * `things config set certified-app-version <X>`. The schema fingerprint cannot
17
+ * see BEHAVIORAL drift (an app update can move an insertion law with zero schema
18
+ * delta), so `things doctor` compares this against the installed version and
19
+ * emits a PASSIVE, non-blocking notice on a mismatch, pointing at the drift
20
+ * suite. Null when never certified (no notice). Precedent: the skill-version
21
+ * passive drift notice (src/cli/skill-check.ts).
22
+ */
23
+ certifiedAppVersion: string | null;
24
+ /**
25
+ * Allow capabilities that ride the app's PRIVATE, UNDOCUMENTED sdef reorder
26
+ * command (default true). This is a private vendor surface, NOT a half-baked
27
+ * "experimental" one: every write is verify-per-write, fingerprint-gated, and
28
+ * canaried by the o-suite (incl. O17), which together detect any divergence.
29
+ * The bidirectional env/config off-switch is retained for hosts that want the
30
+ * private surface disabled; when off, the planner falls back to a proven bounce
31
+ * wherever one exists and refuses only where no enabled path remains.
16
32
  */
17
33
  allowExperimental: boolean;
34
+ /**
35
+ * Whether the `when=`-bounce reorder protocols may run (default true). When
36
+ * false the move/reorder planner REFUSES every bounce-dependent placement
37
+ * (within-heading order, area-someday order, area-less loose anytime, and the
38
+ * top-level projects / evening scopes) with a teaching error naming this key —
39
+ * it never silently falls back to a destructive or unverified path.
40
+ */
41
+ bounceEnabled: boolean;
42
+ /**
43
+ * Cap on the number of items a single bounce reorder may touch (default 30).
44
+ * Each item costs two verified mutations (~110 ms/item guest-local, BOUNCE2-t);
45
+ * the cap bounds the wall-clock and the Things-Cloud change-record fan-out.
46
+ */
47
+ bounceMaxItems: number;
18
48
  /**
19
49
  * The Accessibility GUI ("ui") write vector. When disabled the vector does
20
50
  * not exist on this machine: its GUI-only operations report unsupported.
@@ -25,6 +55,20 @@ export interface ThingsApiConfig {
25
55
  ui: {
26
56
  enabled: boolean;
27
57
  };
58
+ /**
59
+ * Container-scoped sandbox: a raw ref (uuid / uuid-prefix / unique area or
60
+ * project name) plus where it came from, resolved to a pinned container at
61
+ * `openThings()`. Null when unscoped. A stored `scope` jails EVERY process on
62
+ * this host — including the owner's own terminal — so per-process scoping
63
+ * belongs on `THINGS_API_SCOPE` / the MCP `--scope` flag, not here (see
64
+ * docs/design/container-scope.md, Trust model). The MCP flag outranks env,
65
+ * which outranks this stored key. Optional in the type (a hand-built config
66
+ * omits it = unscoped); {@link loadConfig} always populates it.
67
+ */
68
+ scope?: {
69
+ ref: string;
70
+ source: "env" | "config";
71
+ } | null;
28
72
  host: string;
29
73
  }
30
74
  interface ConfigFile {
@@ -33,10 +77,30 @@ interface ConfigFile {
33
77
  actor?: string;
34
78
  auditEnabled?: boolean;
35
79
  acceptedFingerprint?: string;
80
+ certifiedAppVersion?: string;
36
81
  allowExperimental?: boolean;
82
+ bounceEnabled?: boolean;
83
+ bounceMaxItems?: number;
37
84
  uiEnabled?: boolean;
85
+ scope?: string;
38
86
  }
39
87
  export declare function loadConfig(env?: NodeJS.ProcessEnv): ThingsApiConfig;
40
88
  /** Persist one config key (CLI `things config set`). */
41
89
  export declare function saveConfigKey(key: keyof ConfigFile, value: string | number | boolean | null, env?: NodeJS.ProcessEnv): void;
90
+ /**
91
+ * One config key's effective value and where it came from. `key` is the
92
+ * `things config set` / `things config get` spelling; `value` is the effective
93
+ * value after env override → stored file → built-in default; `source` says which
94
+ * layer supplied it. `derived` marks a read-only value computed from the
95
+ * environment (`host`) or from another key (the profile-derived `maxDisruption`
96
+ * default) rather than settable directly.
97
+ */
98
+ export interface ConfigKeyView {
99
+ key: string;
100
+ value: string | number | boolean | null;
101
+ source: "env" | "stored" | "default" | "derived";
102
+ }
103
+ export declare function describeConfig(env?: NodeJS.ProcessEnv): ConfigKeyView[];
104
+ /** One key's effective view, or undefined for an unknown key (`config get <key>`). */
105
+ export declare function getConfigKey(key: string, env?: NodeJS.ProcessEnv): ConfigKeyView | undefined;
42
106
  export {};
package/dist/config.js CHANGED
@@ -13,6 +13,41 @@ const PROFILE_DEFAULT_TIER = {
13
13
  workstation: 1,
14
14
  "dedicated-server": 2,
15
15
  };
16
+ /**
17
+ * A THINGS_API_* boolean override. Returns the forced value when the env var
18
+ * holds a recognized token, or undefined when unset/unrecognized (so the
19
+ * caller falls through to stored config, then the built-in default). The
20
+ * override is BIDIRECTIONAL — a recognized value always wins over stored
21
+ * config, so an env var can force a vector off as well as on. `trueToken` /
22
+ * `falseToken` let THINGS_API_AUDIT keep its legacy on/off vocabulary while
23
+ * the vectors use true/false.
24
+ */
25
+ function boolEnvOverride(raw, trueToken, falseToken) {
26
+ if (raw === trueToken)
27
+ return true;
28
+ if (raw === falseToken)
29
+ return false;
30
+ return undefined;
31
+ }
32
+ /** THINGS_API_PROFILE override, or undefined when unset/unrecognized. */
33
+ function profileEnvOverride(raw) {
34
+ return raw === "workstation" || raw === "dedicated-server" ? raw : undefined;
35
+ }
36
+ /** THINGS_API_MAX_DISRUPTION override, or undefined when unset/unrecognized. */
37
+ function tierEnvOverride(raw) {
38
+ return raw !== undefined && /^[0-3]$/.test(raw) ? Number(raw) : undefined;
39
+ }
40
+ /**
41
+ * A THINGS_API_BOUNCE_MAX_ITEMS override, or undefined when unset/unrecognized.
42
+ * Only a positive integer is accepted (a bounce touches at least one item);
43
+ * anything else falls through to stored config, then the built-in default.
44
+ */
45
+ function positiveIntEnvOverride(raw) {
46
+ if (raw === undefined || !/^[0-9]+$/.test(raw))
47
+ return undefined;
48
+ const n = Number(raw);
49
+ return Number.isInteger(n) && n > 0 ? n : undefined;
50
+ }
16
51
  function configFilePath(env) {
17
52
  return join(configDir(env), "config.json");
18
53
  }
@@ -27,13 +62,12 @@ export function loadConfig(env = process.env) {
27
62
  // Malformed config falls back to defaults; doctor reports it.
28
63
  }
29
64
  }
30
- const profile = env["THINGS_API_PROFILE"] === "dedicated-server" || file.profile === "dedicated-server"
31
- ? "dedicated-server"
32
- : "workstation";
33
- const envTier = env["THINGS_API_MAX_DISRUPTION"];
34
- const maxDisruption = (envTier !== undefined && /^[0-3]$/.test(envTier)
35
- ? Number(envTier)
36
- : (file.maxDisruption ?? PROFILE_DEFAULT_TIER[profile]));
65
+ // Precedence for every key: env > stored > default. A recognized env value
66
+ // always wins over stored config; an unset/unrecognized one falls through.
67
+ const profile = profileEnvOverride(env["THINGS_API_PROFILE"]) ?? file.profile ?? "workstation";
68
+ const maxDisruption = tierEnvOverride(env["THINGS_API_MAX_DISRUPTION"]) ??
69
+ file.maxDisruption ??
70
+ PROFILE_DEFAULT_TIER[profile];
37
71
  let username = "unknown";
38
72
  try {
39
73
  username = userInfo().username;
@@ -41,16 +75,32 @@ export function loadConfig(env = process.env) {
41
75
  catch {
42
76
  // leave "unknown"
43
77
  }
78
+ const auditEnv = boolEnvOverride(env["THINGS_API_AUDIT"], "on", "off");
79
+ const experimentalEnv = boolEnvOverride(env["THINGS_API_ALLOW_EXPERIMENTAL"], "true", "false");
80
+ const bounceEnabledEnv = boolEnvOverride(env["THINGS_API_BOUNCE_ENABLED"], "true", "false");
81
+ const bounceMaxItemsEnv = positiveIntEnvOverride(env["THINGS_API_BOUNCE_MAX_ITEMS"]);
82
+ const uiEnv = boolEnvOverride(env["THINGS_API_UI_ENABLED"], "true", "false");
83
+ // Scope precedence within the config layer: THINGS_API_SCOPE env > stored
84
+ // `scope` key. The MCP `--scope` flag outranks BOTH and is applied above this
85
+ // layer, at openThings(). Fail-closed resolution to a container happens there.
86
+ const scopeEnv = env["THINGS_API_SCOPE"];
87
+ const scope = scopeEnv !== undefined && scopeEnv !== ""
88
+ ? { ref: scopeEnv, source: "env" }
89
+ : file.scope !== undefined && file.scope !== ""
90
+ ? { ref: file.scope, source: "config" }
91
+ : null;
44
92
  return {
45
93
  profile,
46
94
  maxDisruption,
47
95
  actor: env["THINGS_API_ACTOR"] ?? file.actor ?? `${username}@cli`,
48
- auditEnabled: env["THINGS_API_AUDIT"] === "off" ? false : (file.auditEnabled ?? true),
96
+ auditEnabled: auditEnv ?? file.auditEnabled ?? true,
49
97
  acceptedFingerprint: file.acceptedFingerprint ?? null,
50
- allowExperimental: env["THINGS_API_ALLOW_EXPERIMENTAL"] === "true" || file.allowExperimental === true,
51
- ui: {
52
- enabled: env["THINGS_API_UI_ENABLED"] === "true" || file.uiEnabled === true,
53
- },
98
+ certifiedAppVersion: file.certifiedAppVersion ?? null,
99
+ allowExperimental: experimentalEnv ?? file.allowExperimental ?? true,
100
+ bounceEnabled: bounceEnabledEnv ?? file.bounceEnabled ?? true,
101
+ bounceMaxItems: bounceMaxItemsEnv ?? file.bounceMaxItems ?? 30,
102
+ ui: { enabled: uiEnv ?? file.uiEnabled ?? false },
103
+ scope,
54
104
  host: hostname(),
55
105
  };
56
106
  }
@@ -76,4 +126,62 @@ export function saveConfigKey(key, value, env = process.env) {
76
126
  }
77
127
  writeFileSync(path, `${JSON.stringify(file, null, 2)}\n`);
78
128
  }
129
+ function readConfigFile(env) {
130
+ const path = configFilePath(env);
131
+ if (existsSync(path)) {
132
+ try {
133
+ return JSON.parse(readFileSync(path, "utf8"));
134
+ }
135
+ catch {
136
+ // Malformed config → treated as no stored keys (doctor reports it).
137
+ }
138
+ }
139
+ return {};
140
+ }
141
+ /**
142
+ * The effective value + provenance of every config key, in a stable order —
143
+ * backing `things config get`. Env/stored/default detection mirrors
144
+ * {@link loadConfig} exactly, so a key reads `env` only when an env var actually
145
+ * overrode it (a THINGS_API_* value that loadConfig honors), `stored` when the
146
+ * on-disk config supplied it, `derived` for a read-only value computed from the
147
+ * environment or another key, and `default` otherwise.
148
+ */
149
+ function configKeyView(key, value, stored, fromEnv) {
150
+ return { key, value, source: fromEnv ? "env" : stored ? "stored" : "default" };
151
+ }
152
+ export function describeConfig(env = process.env) {
153
+ const file = readConfigFile(env);
154
+ const cfg = loadConfig(env);
155
+ const view = configKeyView;
156
+ const tierFromEnv = tierEnvOverride(env["THINGS_API_MAX_DISRUPTION"]) !== undefined;
157
+ const maxDisruption = {
158
+ key: "maxDisruption",
159
+ value: cfg.maxDisruption,
160
+ // env > stored > profile-derived default (the built-in fallback is
161
+ // computed from `profile`, so it reports `derived`, not `default`).
162
+ source: tierFromEnv ? "env" : file.maxDisruption !== undefined ? "stored" : "derived",
163
+ };
164
+ return [
165
+ view("profile", cfg.profile, file.profile !== undefined, profileEnvOverride(env["THINGS_API_PROFILE"]) !== undefined),
166
+ maxDisruption,
167
+ view("actor", cfg.actor, file.actor !== undefined, env["THINGS_API_ACTOR"] !== undefined),
168
+ view("auditEnabled", cfg.auditEnabled, file.auditEnabled !== undefined, boolEnvOverride(env["THINGS_API_AUDIT"], "on", "off") !== undefined),
169
+ view("accepted-fingerprint", cfg.acceptedFingerprint, file.acceptedFingerprint !== undefined, false),
170
+ view("certified-app-version", cfg.certifiedAppVersion, file.certifiedAppVersion !== undefined, false),
171
+ view("allow-experimental", cfg.allowExperimental, file.allowExperimental !== undefined, boolEnvOverride(env["THINGS_API_ALLOW_EXPERIMENTAL"], "true", "false") !== undefined),
172
+ view("bounce-enabled", cfg.bounceEnabled, file.bounceEnabled !== undefined, boolEnvOverride(env["THINGS_API_BOUNCE_ENABLED"], "true", "false") !== undefined),
173
+ view("bounce-max-items", cfg.bounceMaxItems, file.bounceMaxItems !== undefined, positiveIntEnvOverride(env["THINGS_API_BOUNCE_MAX_ITEMS"]) !== undefined),
174
+ view("ui-enabled", cfg.ui.enabled, file.uiEnabled !== undefined, boolEnvOverride(env["THINGS_API_UI_ENABLED"], "true", "false") !== undefined),
175
+ // The container scope's RAW ref (resolved to a container at open); env >
176
+ // stored. A stored value jails every process on this host — see the
177
+ // trust-model note in docs/design/container-scope.md.
178
+ view("scope", cfg.scope?.ref ?? null, file.scope !== undefined, env["THINGS_API_SCOPE"] !== undefined && env["THINGS_API_SCOPE"] !== ""),
179
+ // Read-only, computed from the environment; not settable via `config set`.
180
+ { key: "host", value: cfg.host, source: "derived" },
181
+ ];
182
+ }
183
+ /** One key's effective view, or undefined for an unknown key (`config get <key>`). */
184
+ export function getConfigKey(key, env = process.env) {
185
+ return describeConfig(env).find((v) => v.key === key);
186
+ }
79
187
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ export declare const API_VERSION = 1;
13
13
  * Package version, surfaced by `things --version` and the MCP serverInfo.
14
14
  * Kept in lockstep with package.json by a contract test.
15
15
  */
16
- export declare const PKG_VERSION = "0.10.0";
16
+ export declare const PKG_VERSION = "0.12.0";
17
17
  /**
18
18
  * Stable exit-code contract for the `things` CLI (mirrored by MCP error
19
19
  * codes). Part of the public API surface consumed by agents and scripts —
@@ -51,21 +51,29 @@ export interface SectionCount {
51
51
  total: number;
52
52
  }
53
53
  /**
54
- * List-view truncation metadata (ADDITIVE). Present on the meta of any read
55
- * command that applies a row limit; absent on unbounded/structured views.
56
- * `shown` items were returned of `total` that matched after all filters;
57
- * `limit` is the effective cap (null when the caller asked for all rows);
58
- * `truncated` is true exactly when `shown < total`. The dropped remainder is
59
- * `total - shown`. `sections` is present only on a split flat view (the Today
60
- * split), breaking the whole-view counts down per render section.
54
+ * The single truncation-metadata shape for every read (the `meta.truncation`
55
+ * field). `shown` items were returned of `total` that matched after all
56
+ * filters; `limit` is the effective cap (null when the caller asked for all
57
+ * rows, and always null on a grouped view whose caps are per-block); `truncated`
58
+ * is the UNIVERSAL completeness check — true exactly when anything was dropped
59
+ * (`shown < total`, or any block hid rows). The dropped remainder is
60
+ * `total - shown`.
61
+ *
62
+ * Two optional per-shape breakdowns hang off it: `sections` for a split flat
63
+ * view (the Today split — per render-section shown/total), and `blocks` for a
64
+ * grouped view (anytime/someday/`area show` — the identity-carrying per-block
65
+ * nesting). Exactly one of them is present on the shapes that have it; both are
66
+ * absent on a plain flat view.
61
67
  */
62
68
  export interface Truncation {
63
69
  shown: number;
64
70
  total: number;
65
71
  limit: number | null;
66
72
  truncated: boolean;
67
- /** Per-section shown/total breakdown for a split flat view; absent otherwise. */
73
+ /** Per-section shown/total breakdown for a split flat view (Today); absent otherwise. */
68
74
  sections?: SectionCount[];
75
+ /** Per-block nesting for a grouped view (anytime/someday/area card); absent otherwise. */
76
+ blocks?: GroupBlock[];
69
77
  }
70
78
  /**
71
79
  * One identity-carrying block of a grouped catalogue (anytime/someday) or a
@@ -103,12 +111,6 @@ export interface GroupBlock {
103
111
  /** Nested project blocks (anytime item-lists / someday active-project groups). Absent when none. */
104
112
  children?: GroupBlock[];
105
113
  }
106
- /** Grouped-view truncation metadata (ADDITIVE); the per-block counterpart of {@link Truncation}. */
107
- export interface GroupedTruncation {
108
- /** True when any block hid items. */
109
- truncated: boolean;
110
- blocks: GroupBlock[];
111
- }
112
114
  export interface EnvelopeMeta {
113
115
  /** Things database schema version (`Meta.databaseVersion`), null when no DB was opened. */
114
116
  dbVersion: number | null;
@@ -116,10 +118,13 @@ export interface EnvelopeMeta {
116
118
  fingerprint: "ok" | "drift" | "user-accepted" | "unknown";
117
119
  /** Wall-clock duration of the command in milliseconds. */
118
120
  elapsedMs: number;
119
- /** List-view truncation metadata; present only on limited flat read views. */
121
+ /**
122
+ * The read's completeness metadata (the single truncation shape). Present on
123
+ * any read that could drop rows — flat views (row `limit`), the Today split
124
+ * (`sections`), and grouped views (anytime/someday/`area show`, `blocks`).
125
+ * `meta.truncation.truncated` is the universal "did I see everything" check.
126
+ */
120
127
  truncation?: Truncation;
121
- /** Per-block truncation metadata; present only on grouped views (anytime/someday). */
122
- grouped?: GroupedTruncation;
123
128
  /**
124
129
  * The canonical `things …` command a sugar invocation normalized to (bare
125
130
  * noun, keyword-in-show, uuid/share-link routing). Present only on routed
@@ -133,6 +138,42 @@ export interface EnvelopeMeta {
133
138
  * (reads stay best-effort; run `things doctor`). Absent means none.
134
139
  */
135
140
  warnings?: string[];
141
+ /**
142
+ * The effective clock this response's date boundaries were computed for
143
+ * (ADDITIVE honesty field). Present ONLY when a consumer zone (`THINGS_TZ` /
144
+ * the MCP `tz` argument) or a pinned `THINGS_NOW` is in effect; ABSENT on the
145
+ * host clock, so the wire shape is unchanged for ordinary consumers.
146
+ */
147
+ clock?: {
148
+ timezone: string;
149
+ today: string;
150
+ };
151
+ /**
152
+ * The active content filter this response was scoped to (ADDITIVE). Present
153
+ * ONLY when a scope was applied — currently `area` (the `--area` view filter),
154
+ * carrying the resolved area's uuid + title; ABSENT otherwise, so the wire
155
+ * shape is unchanged for unscoped reads (the `meta.clock` precedent).
156
+ */
157
+ filter?: {
158
+ area: {
159
+ uuid: string;
160
+ title: string;
161
+ };
162
+ };
163
+ /**
164
+ * The active container scope this response was jailed to (ADDITIVE). Present
165
+ * ONLY when a scope is in force (the MCP `--scope` flag / `THINGS_API_SCOPE` /
166
+ * a stored `scope`), naming the container + where the scope came from; ABSENT
167
+ * otherwise, so the wire shape is unchanged for unscoped reads. Lets an agent
168
+ * know its own jail — which is not an oracle for what lies outside it (the
169
+ * `meta.clock` / `meta.filter` additive precedent).
170
+ */
171
+ scope?: {
172
+ kind: "area" | "project";
173
+ uuid: string;
174
+ title: string;
175
+ source: "flag" | "env" | "config";
176
+ };
136
177
  }
137
178
  export interface OkEnvelope<T> {
138
179
  apiVersion: typeof API_VERSION;
@@ -142,13 +183,38 @@ export interface OkEnvelope<T> {
142
183
  data: T;
143
184
  meta: EnvelopeMeta;
144
185
  }
186
+ /**
187
+ * The registry of stable machine-readable error codes an error envelope can
188
+ * carry — the compiler IS the registry. Every `error.code` value the surfaces
189
+ * emit is a member of this union, and the human-readable meaning of each is
190
+ * frozen at v1.0 (new codes may still be ADDED after v1.0 — that is
191
+ * non-breaking; a documented code's MEANING never changes). The canonical
192
+ * per-code table (meaning + the `detail` keys each may carry) lives in
193
+ * `docs/contract.md` (The error-code registry).
194
+ *
195
+ * Two members are template-literal families rather than fixed strings, because
196
+ * their suffix is minted in the write layer and the core deliberately never
197
+ * depends on it (see {@link blockedCode} / {@link verifyFailedCode}):
198
+ * - `verify-failed:${reason}` — a single mutation executed but read-after-write
199
+ * verification failed; the suffix is the reason (`timeout` | `mismatch` |
200
+ * `silent-noop`). The bare `verify-failed` (no suffix) is the multi-leg
201
+ * move/reorder failure.
202
+ * - `blocked:${suffix}` — a mutation refused before touching the app; the
203
+ * suffix is the specific hazard id (`H-…`) when one is named, else the block
204
+ * reason (`drift` | `disruption-tier` | `lock` | `environment` | `clock` |
205
+ * `scope`). The bare `blocked` is a policy refusal from the move planner.
206
+ *
207
+ * `blocked:drift` maps to exit code 5 (DriftBlocked); every other `blocked:*`
208
+ * maps to exit code 4 (Blocked).
209
+ */
210
+ export type ErrorCode = "usage" | "not-found" | "ambiguous" | "unsupported" | "environment" | "unexpected" | "bounce-aborted" | "verify-failed" | "blocked" | `verify-failed:${string}` | `blocked:${string}`;
145
211
  export interface ErrorEnvelope {
146
212
  apiVersion: typeof API_VERSION;
147
213
  ok: false;
148
214
  kind: "error";
149
215
  error: {
150
- /** Stable machine-readable code, mirrors the exit-code family (e.g. "verify-failed", "blocked"). */
151
- code: string;
216
+ /** Stable machine-readable code from the {@link ErrorCode} registry (mirrors the exit-code family, e.g. "verify-failed", "blocked:H-UNKNOWN-TAG"). */
217
+ code: ErrorCode;
152
218
  message: string;
153
219
  /**
154
220
  * Advisory attribution when failure signals point somewhere: e.g.
@@ -158,25 +224,117 @@ export interface ErrorEnvelope {
158
224
  likelyCause?: string;
159
225
  /** Actionable next step for the caller, when one exists. */
160
226
  remediation?: string;
161
- detail?: unknown;
162
227
  /**
163
- * Structured, machine-readable failure context (ADDITIVE). For an
164
- * unresolved show/bare-noun subject it carries `candidates` — the
165
- * did-you-mean title matches (standard item shapes, capped) so an agent
166
- * can self-correct without a second round-trip. For a bare mutation verb
167
- * (`things update <ref>`) it carries `suggestions` — the concrete
168
- * namespaced command(s) to run instead.
228
+ * The SINGLE structured, machine-readable failure-context object (there is
229
+ * no separate `details` field — the two were reconciled into this one). Each
230
+ * key is present only for the failures that produce it:
231
+ * - `expected` / `observed` a verify-failed mutation's expected delta and
232
+ * the observed post-write state.
233
+ * - `candidates` the disambiguation list for a not-found / ambiguous
234
+ * resolution (or a show/bare-noun did-you-mean): the ONE fixed, flag-
235
+ * invariant candidate shape (`CandidateRef`; see docs/contract.md), a
236
+ * LIVE-scoped pool capped at 8, so an agent can self-correct without
237
+ * another round-trip.
238
+ * - `suggestions` — for a bare mutation verb (`things update <ref>`), the
239
+ * concrete namespaced command(s) to run instead.
240
+ * - `considered` — the vectors weighed (and why each was rejected) for an
241
+ * unsupported operation.
242
+ * - `placed` / `remaining` / `cause` — a bounce reorder that aborted
243
+ * part-way: the items already placed, those not yet placed, and the cause.
244
+ * - `failed` / `completed` — a multi-leg move that failed mid-way: the leg
245
+ * that failed and the legs already completed before it.
169
246
  */
170
- details?: {
247
+ detail?: {
248
+ expected?: unknown;
249
+ observed?: Record<string, unknown> | null;
171
250
  candidates?: unknown[];
172
251
  suggestions?: string[];
252
+ considered?: {
253
+ vector: string;
254
+ why: string;
255
+ }[];
256
+ placed?: string[];
257
+ remaining?: string[];
258
+ cause?: unknown;
259
+ failed?: unknown;
260
+ completed?: unknown[];
173
261
  };
174
262
  };
175
263
  meta: EnvelopeMeta;
176
264
  }
177
265
  export type Envelope<T> = OkEnvelope<T> | ErrorEnvelope;
266
+ /**
267
+ * The envelope `kind` discriminators a SUCCESSFUL response carries today (the
268
+ * error envelope's `kind` is always the literal `"error"`). This union is the
269
+ * schema's record of the known payload classes — the flat-list reads
270
+ * (`data.items`), the sectioned reads (`data.sections`), the composite cards
271
+ * (`data.view`), the single-entity detail (`data.item`), the mutations/plans
272
+ * (flat `data` fields), and the diagnostic payloads.
273
+ *
274
+ * Per the compatibility covenant (docs/contract.md) a consumer MUST tolerate an
275
+ * UNKNOWN `kind`: adding a new kind is additive / non-breaking. So this union is
276
+ * "the kinds known to THIS build", not a closed set a generic reader may assume
277
+ * complete — the JSON Schema pins it as an enum so drift is caught, but a
278
+ * forward-compatible consumer routes on the wrapper it finds in `data`.
279
+ */
280
+ export type WireOkKind = "inbox" | "upcoming" | "logbook" | "trash" | "changes" | "search" | "projects" | "areas" | "tags" | "today" | "anytime" | "someday" | "area-view" | "project-view" | "detail" | "mutation-result" | "move-result" | "mutation-plan" | "move-plan" | "project-reopen" | "doctor" | "capabilities" | "config" | "legend" | "setup-shortcuts" | "install-skill";
281
+ /**
282
+ * The `data` payload of a successful envelope. Its CONCRETE shape is
283
+ * command-specific — one of the R1/R2 read wrappers (`item` | `view` | `items` |
284
+ * `sections`) or a mutation's flat result fields — and, crucially, entity
285
+ * payloads are omit-empty pruned on the wire (docs/design/contracts.md).
286
+ *
287
+ * COVERAGE BOUNDARY: this schema does NOT model the per-kind payload shapes. It
288
+ * pins the ENVELOPE layer exactly (`apiVersion`, `ok`, `kind`, `meta`, and the
289
+ * whole `error` object) and treats `data` as an open JSON object. Fully typing
290
+ * every kind's payload against the omit-empty wire shape is a separate, larger
291
+ * effort; until then `src/contracts.ts` and `docs/contract.md` remain the
292
+ * authoritative description of what each `kind`'s `data` contains.
293
+ */
294
+ export type WireData = Record<string, unknown>;
295
+ /** A successful `--json` envelope, exactly as emitted on stdout. */
296
+ export interface WireOkEnvelope {
297
+ apiVersion: typeof API_VERSION;
298
+ ok: true;
299
+ /** The payload class — see {@link WireOkKind}. */
300
+ kind: WireOkKind;
301
+ /** Command-specific payload; open at the schema layer (see {@link WireData}). */
302
+ data: WireData;
303
+ meta: EnvelopeMeta;
304
+ }
305
+ /**
306
+ * The machine-readable ROOT the envelope JSON Schema is generated from
307
+ * (`schema/envelope.schema.json`, produced by `npm run schema:gen`): the
308
+ * discriminated union — on the boolean `ok` — of a successful envelope and an
309
+ * {@link ErrorEnvelope}, exactly as written to stdout by the CLI `--json`
310
+ * surface and inherited by the MCP server. This is the same grammar
311
+ * docs/contract.md describes in prose; the schema is its generated, testable
312
+ * rendering. NB: the streaming commands (`batch`, `undo`) emit JSON Lines, a
313
+ * documented exception NOT covered by this envelope type.
314
+ */
315
+ export type WireEnvelope = WireOkEnvelope | ErrorEnvelope;
178
316
  export declare function okEnvelope<T>(kind: string, data: T, meta: EnvelopeMeta): OkEnvelope<T>;
179
317
  export declare function errorEnvelope(error: ErrorEnvelope["error"], meta: EnvelopeMeta): ErrorEnvelope;
318
+ /**
319
+ * Project a successful mutation/reorder/move outcome to its ENVELOPE `data`
320
+ * shape. The wire's mutation-success discriminator is REDUNDANT and is not
321
+ * emitted: the envelope already carries call success (`ok: true`, and the
322
+ * envelope `kind` names the payload class — `mutation-result` / `move-result`).
323
+ * So the result's internal `kind` discriminator is STRIPPED here — the emitted
324
+ * `data` has no `result` and no `kind`, just the payload fields (`op`, `uuid`,
325
+ * `title`, `undoToken`, `observed`, `vector`, `tier`, `touched`, notes, …).
326
+ * Only the internal tags `"ok"` / `"move-ok"` ever reach this boundary
327
+ * (failures route to error envelopes, dry-runs to the `mutation-plan` /
328
+ * `move-plan` kinds), so nothing is lost by dropping it. The library keeps the
329
+ * idiomatic `kind` discriminator on its in-memory
330
+ * `MutationResult`/`ReorderResult`/`MoveResult` unions; it simply never appears
331
+ * on the wire. BOTH consumer surfaces emit through it: the CLI (`mutation-result`
332
+ * / `move-result` envelopes) and the MCP mutation/move content block (phase-2
333
+ * framing sweep, 2026-07-31) — a dry-run routes to the bare `plan` on both.
334
+ */
335
+ export declare function mutationWireData<T extends {
336
+ kind: string;
337
+ }>(ok: T): Omit<T, "kind">;
180
338
  /**
181
339
  * Canonical machine-readable error CODE for a refused ("blocked") mutation: the
182
340
  * specific hazard id when one is named, else the block reason. Every surface —
package/dist/contracts.js CHANGED
@@ -13,7 +13,7 @@ export const API_VERSION = 1;
13
13
  * Package version, surfaced by `things --version` and the MCP serverInfo.
14
14
  * Kept in lockstep with package.json by a contract test.
15
15
  */
16
- export const PKG_VERSION = "0.10.0";
16
+ export const PKG_VERSION = "0.12.0";
17
17
  /**
18
18
  * Stable exit-code contract for the `things` CLI (mirrored by MCP error
19
19
  * codes). Part of the public API surface consumed by agents and scripts —
@@ -43,6 +43,27 @@ export function okEnvelope(kind, data, meta) {
43
43
  export function errorEnvelope(error, meta) {
44
44
  return { apiVersion: API_VERSION, ok: false, kind: "error", error, meta };
45
45
  }
46
+ /**
47
+ * Project a successful mutation/reorder/move outcome to its ENVELOPE `data`
48
+ * shape. The wire's mutation-success discriminator is REDUNDANT and is not
49
+ * emitted: the envelope already carries call success (`ok: true`, and the
50
+ * envelope `kind` names the payload class — `mutation-result` / `move-result`).
51
+ * So the result's internal `kind` discriminator is STRIPPED here — the emitted
52
+ * `data` has no `result` and no `kind`, just the payload fields (`op`, `uuid`,
53
+ * `title`, `undoToken`, `observed`, `vector`, `tier`, `touched`, notes, …).
54
+ * Only the internal tags `"ok"` / `"move-ok"` ever reach this boundary
55
+ * (failures route to error envelopes, dry-runs to the `mutation-plan` /
56
+ * `move-plan` kinds), so nothing is lost by dropping it. The library keeps the
57
+ * idiomatic `kind` discriminator on its in-memory
58
+ * `MutationResult`/`ReorderResult`/`MoveResult` unions; it simply never appears
59
+ * on the wire. BOTH consumer surfaces emit through it: the CLI (`mutation-result`
60
+ * / `move-result` envelopes) and the MCP mutation/move content block (phase-2
61
+ * framing sweep, 2026-07-31) — a dry-run routes to the bare `plan` on both.
62
+ */
63
+ export function mutationWireData(ok) {
64
+ const { kind: _kind, ...rest } = ok;
65
+ return rest;
66
+ }
46
67
  /**
47
68
  * Canonical machine-readable error CODE for a refused ("blocked") mutation: the
48
69
  * specific hazard id when one is named, else the block reason. Every surface —
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,eAAe;IACf,EAAE,EAAE,CAAC;IACL,4DAA4D;IAC5D,UAAU,EAAE,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,CAAC;IACR,uGAAuG;IACvG,YAAY,EAAE,CAAC;IACf,wFAAwF;IACxF,OAAO,EAAE,CAAC;IACV,gGAAgG;IAChG,YAAY,EAAE,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,CAAC;IACd,kFAAkF;IAClF,WAAW,EAAE,CAAC;CACN,CAAC;AAkJX,MAAM,UAAU,UAAU,CAAI,IAAY,EAAE,IAAO,EAAE,IAAkB;IACrE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAA6B,EAAE,IAAkB;IAC7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,OAA4C;IACtE,OAAO,WAAW,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAmB,OAAsB;IACvE,OAAO,iBAAiB,OAAO,CAAC,MAAM,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAsD;IAEtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,EAAE,CAAC;QACvE,OAAO,QAAQ,CAAC,YAAY,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC,OAAO,CAAC;IAClD,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAC,WAAW,CAAC;IAC1D,OAAO,QAAQ,CAAC,YAAY,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,eAAe;IACf,EAAE,EAAE,CAAC;IACL,4DAA4D;IAC5D,UAAU,EAAE,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,CAAC;IACR,uGAAuG;IACvG,YAAY,EAAE,CAAC;IACf,wFAAwF;IACxF,OAAO,EAAE,CAAC;IACV,gGAAgG;IAChG,YAAY,EAAE,CAAC;IACf,6DAA6D;IAC7D,WAAW,EAAE,CAAC;IACd,kFAAkF;IAClF,WAAW,EAAE,CAAC;CACN,CAAC;AAmUX,MAAM,UAAU,UAAU,CAAI,IAAY,EAAE,IAAO,EAAE,IAAkB;IACrE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAA6B,EAAE,IAAkB;IAC7E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC5E,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,gBAAgB,CAA6B,EAAK;IAChE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,OAA4C;IACtE,OAAO,WAAW,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAmB,OAAsB;IACvE,OAAO,iBAAiB,OAAO,CAAC,MAAM,EAAE,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAsD;IAEtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,EAAE,CAAC;QACvE,OAAO,QAAQ,CAAC,YAAY,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC,OAAO,CAAC;IAClD,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;QAAE,OAAO,QAAQ,CAAC,WAAW,CAAC;IAC1D,OAAO,QAAQ,CAAC,YAAY,CAAC;AAC/B,CAAC"}