things-api 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -5
- package/dist/audit/schema.d.ts +7 -0
- package/dist/audit/schema.js.map +1 -1
- package/dist/cli/canonical-ref.d.ts +21 -0
- package/dist/cli/canonical-ref.js +23 -0
- package/dist/cli/canonical-ref.js.map +1 -0
- package/dist/cli/commands/area.d.ts +18 -11
- package/dist/cli/commands/area.js +81 -77
- package/dist/cli/commands/area.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +1 -2
- package/dist/cli/commands/doctor.js +11 -1
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/install-skill.d.ts +19 -4
- package/dist/cli/commands/install-skill.js +130 -52
- package/dist/cli/commands/install-skill.js.map +1 -1
- package/dist/cli/commands/mcp.js +21 -1
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/project.d.ts +1 -0
- package/dist/cli/commands/project.js +92 -48
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/reads.d.ts +5 -1
- package/dist/cli/commands/reads.js +110 -31
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/setup.js +11 -4
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/show.js +75 -36
- package/dist/cli/commands/show.js.map +1 -1
- package/dist/cli/commands/todo.js +2 -2
- package/dist/cli/commands/todo.js.map +1 -1
- package/dist/cli/commands/writes.js +795 -144
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/did-you-mean.d.ts +14 -3
- package/dist/cli/did-you-mean.js +44 -7
- package/dist/cli/did-you-mean.js.map +1 -1
- package/dist/cli/dry-run.d.ts +55 -0
- package/dist/cli/dry-run.js +92 -0
- package/dist/cli/dry-run.js.map +1 -0
- package/dist/cli/glyphs.d.ts +16 -2
- package/dist/cli/glyphs.js +60 -12
- package/dist/cli/glyphs.js.map +1 -1
- package/dist/cli/help.js +69 -13
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/main.js +8 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/move-hint.d.ts +3 -2
- package/dist/cli/move-hint.js +2 -2
- package/dist/cli/move-hint.js.map +1 -1
- package/dist/cli/read-driver.d.ts +53 -5
- package/dist/cli/read-driver.js +82 -15
- package/dist/cli/read-driver.js.map +1 -1
- package/dist/cli/ref-render.d.ts +14 -0
- package/dist/cli/ref-render.js +9 -0
- package/dist/cli/ref-render.js.map +1 -0
- package/dist/cli/render.d.ts +40 -14
- package/dist/cli/render.js +128 -55
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/resolve-invocation.d.ts +7 -5
- package/dist/cli/resolve-invocation.js +16 -7
- package/dist/cli/resolve-invocation.js.map +1 -1
- package/dist/cli/skill-check.d.ts +12 -6
- package/dist/cli/skill-check.js +31 -14
- package/dist/cli/skill-check.js.map +1 -1
- package/dist/cli/skill.d.ts +8 -0
- package/dist/cli/skill.js +10 -0
- package/dist/cli/skill.js.map +1 -1
- package/dist/cli/verb-hint.js +1 -1
- package/dist/cli/verb-hint.js.map +1 -1
- package/dist/client.d.ts +158 -26
- package/dist/client.js +254 -38
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +66 -2
- package/dist/config.js +120 -12
- package/dist/config.js.map +1 -1
- package/dist/contracts.d.ts +187 -28
- package/dist/contracts.js +22 -1
- package/dist/contracts.js.map +1 -1
- package/dist/db/baselines/db-v26.js +4 -1
- package/dist/db/baselines/db-v26.js.map +1 -1
- package/dist/diagnose.d.ts +34 -2
- package/dist/diagnose.js +36 -1
- package/dist/diagnose.js.map +1 -1
- package/dist/index.d.ts +21 -8
- package/dist/index.js +26 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.js +790 -322
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/entities.d.ts +57 -4
- package/dist/model/entities.js.map +1 -1
- package/dist/model/mappers.d.ts +2 -0
- package/dist/model/mappers.js +44 -2
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/recurrence.d.ts +8 -1
- package/dist/model/recurrence.js.map +1 -1
- package/dist/model/serialize.js +15 -3
- package/dist/model/serialize.js.map +1 -1
- package/dist/read/area-filter.d.ts +76 -0
- package/dist/read/area-filter.js +58 -0
- package/dist/read/area-filter.js.map +1 -0
- package/dist/read/area-view.d.ts +22 -11
- package/dist/read/area-view.js +54 -28
- package/dist/read/area-view.js.map +1 -1
- package/dist/read/detail.js +15 -8
- package/dist/read/detail.js.map +1 -1
- package/dist/read/predicates.d.ts +18 -0
- package/dist/read/predicates.js +19 -0
- package/dist/read/predicates.js.map +1 -1
- package/dist/read/project-view.d.ts +91 -15
- package/dist/read/project-view.js +135 -37
- package/dist/read/project-view.js.map +1 -1
- package/dist/read/pseudo-area.d.ts +29 -0
- package/dist/read/pseudo-area.js +27 -0
- package/dist/read/pseudo-area.js.map +1 -0
- package/dist/read/queries.d.ts +175 -19
- package/dist/read/queries.js +376 -32
- package/dist/read/queries.js.map +1 -1
- package/dist/read/scope.d.ts +126 -0
- package/dist/read/scope.js +161 -0
- package/dist/read/scope.js.map +1 -0
- package/dist/read/search-rank.d.ts +2 -5
- package/dist/read/shape.d.ts +181 -0
- package/dist/read/shape.js +737 -0
- package/dist/read/shape.js.map +1 -0
- package/dist/read/show-target.d.ts +9 -1
- package/dist/read/show-target.js +77 -17
- package/dist/read/show-target.js.map +1 -1
- package/dist/read/stage.d.ts +199 -0
- package/dist/read/stage.js +125 -0
- package/dist/read/stage.js.map +1 -0
- package/dist/read/truncation.d.ts +7 -12
- package/dist/read/truncation.js +56 -21
- package/dist/read/truncation.js.map +1 -1
- package/dist/read/views.d.ts +68 -16
- package/dist/read/views.js +206 -52
- package/dist/read/views.js.map +1 -1
- package/dist/surface-copy.d.ts +16 -0
- package/dist/surface-copy.js +16 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/write/batch.d.ts +49 -10
- package/dist/write/batch.js +423 -71
- package/dist/write/batch.js.map +1 -1
- package/dist/write/commands.js +268 -55
- package/dist/write/commands.js.map +1 -1
- package/dist/write/guards.d.ts +1 -1
- package/dist/write/guards.js +71 -10
- package/dist/write/guards.js.map +1 -1
- package/dist/write/heading.d.ts +10 -1
- package/dist/write/heading.js +35 -5
- package/dist/write/heading.js.map +1 -1
- package/dist/write/make-repeating-project.d.ts +2 -2
- package/dist/write/make-repeating-project.js +9 -9
- package/dist/write/make-repeating-project.js.map +1 -1
- package/dist/write/move.d.ts +134 -0
- package/dist/write/move.js +1874 -0
- package/dist/write/move.js.map +1 -0
- package/dist/write/operations.d.ts +105 -19
- package/dist/write/operations.js +56 -7
- package/dist/write/operations.js.map +1 -1
- package/dist/write/opid.d.ts +31 -0
- package/dist/write/opid.js +30 -0
- package/dist/write/opid.js.map +1 -0
- package/dist/write/pipeline.d.ts +70 -3
- package/dist/write/pipeline.js +198 -33
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/pre-state.d.ts +172 -8
- package/dist/write/pre-state.js +467 -25
- package/dist/write/pre-state.js.map +1 -1
- package/dist/write/reorder.d.ts +23 -3
- package/dist/write/reorder.js +2106 -86
- package/dist/write/reorder.js.map +1 -1
- package/dist/write/reversibility.js +19 -7
- package/dist/write/reversibility.js.map +1 -1
- package/dist/write/scope-guard.d.ts +31 -0
- package/dist/write/scope-guard.js +162 -0
- package/dist/write/scope-guard.js.map +1 -0
- package/dist/write/undo.js +120 -13
- package/dist/write/undo.js.map +1 -1
- package/dist/write/vectors/applescript.js +16 -7
- package/dist/write/vectors/applescript.js.map +1 -1
- package/dist/write/vectors/shortcuts.js +1 -1
- package/dist/write/vectors/shortcuts.js.map +1 -1
- package/dist/write/vectors/simulator.js +83 -27
- package/dist/write/vectors/simulator.js.map +1 -1
- package/dist/write/vectors/types.d.ts +11 -0
- package/dist/write/vectors/ui-certification.d.ts +3 -3
- package/dist/write/vectors/ui-certification.js +41 -5
- package/dist/write/vectors/ui-certification.js.map +1 -1
- package/dist/write/vectors/ui-drag.d.ts +21 -1
- package/dist/write/vectors/ui-drag.js +138 -27
- package/dist/write/vectors/ui-drag.js.map +1 -1
- package/dist/write/vectors/ui-recipes.d.ts +21 -1
- package/dist/write/vectors/ui-recipes.js +166 -7
- package/dist/write/vectors/ui-recipes.js.map +1 -1
- package/dist/write/vectors/ui.d.ts +25 -1
- package/dist/write/vectors/ui.js +142 -33
- package/dist/write/vectors/ui.js.map +1 -1
- package/dist/write/verify/delta.d.ts +17 -1
- package/dist/write/verify/delta.js +106 -29
- package/dist/write/verify/delta.js.map +1 -1
- package/package.json +7 -1
- package/schema/envelope.schema.json +397 -0
- package/skills/things-cli/SKILL.md +36 -17
- package/skills/things-cli/references/banner.md +35 -0
- package/skills/things-cli/references/contracts.md +32 -9
- package/skills/things-cli/references/errors.md +57 -0
- package/skills/things-cli/references/gui.md +1 -1
- package/skills/things-cli/references/model.md +18 -7
- package/skills/things-cli/references/ordering.md +88 -0
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
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:
|
|
96
|
+
auditEnabled: auditEnv ?? file.auditEnabled ?? true,
|
|
49
97
|
acceptedFingerprint: file.acceptedFingerprint ?? null,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.d.ts
CHANGED
|
@@ -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.
|
|
16
|
+
export declare const PKG_VERSION = "0.13.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
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* `
|
|
60
|
-
*
|
|
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
|
-
/**
|
|
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
|
|
@@ -143,6 +148,43 @@ export interface EnvelopeMeta {
|
|
|
143
148
|
timezone: string;
|
|
144
149
|
today: string;
|
|
145
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
|
+
* Whole-view aggregate counts (ADDITIVE). Present ONLY on the `today` view: the
|
|
165
|
+
* app's sidebar count split — `dueOrOverdue` (open members whose deadline is
|
|
166
|
+
* due or overdue) vs. `other` (the rest). A convenience aggregate an agent
|
|
167
|
+
* would otherwise recompute over the rows; it lives here so `data` stays pure
|
|
168
|
+
* domain rows. Both counts are OPEN members only, and a `0` is meaningful.
|
|
169
|
+
*/
|
|
170
|
+
counts?: {
|
|
171
|
+
dueOrOverdue: number;
|
|
172
|
+
other: number;
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* The active container scope this response was jailed to (ADDITIVE). Present
|
|
176
|
+
* ONLY when a scope is in force (the MCP `--scope` flag / `THINGS_API_SCOPE` /
|
|
177
|
+
* a stored `scope`), naming the container + where the scope came from; ABSENT
|
|
178
|
+
* otherwise, so the wire shape is unchanged for unscoped reads. Lets an agent
|
|
179
|
+
* know its own jail — which is not an oracle for what lies outside it (the
|
|
180
|
+
* `meta.clock` / `meta.filter` additive precedent).
|
|
181
|
+
*/
|
|
182
|
+
scope?: {
|
|
183
|
+
kind: "area" | "project";
|
|
184
|
+
uuid: string;
|
|
185
|
+
title: string;
|
|
186
|
+
source: "flag" | "env" | "config";
|
|
187
|
+
};
|
|
146
188
|
}
|
|
147
189
|
export interface OkEnvelope<T> {
|
|
148
190
|
apiVersion: typeof API_VERSION;
|
|
@@ -152,13 +194,38 @@ export interface OkEnvelope<T> {
|
|
|
152
194
|
data: T;
|
|
153
195
|
meta: EnvelopeMeta;
|
|
154
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* The registry of stable machine-readable error codes an error envelope can
|
|
199
|
+
* carry — the compiler IS the registry. Every `error.code` value the surfaces
|
|
200
|
+
* emit is a member of this union, and the human-readable meaning of each is
|
|
201
|
+
* frozen at v1.0 (new codes may still be ADDED after v1.0 — that is
|
|
202
|
+
* non-breaking; a documented code's MEANING never changes). The canonical
|
|
203
|
+
* per-code table (meaning + the `detail` keys each may carry) lives in
|
|
204
|
+
* `docs/contract.md` (The error-code registry).
|
|
205
|
+
*
|
|
206
|
+
* Two members are template-literal families rather than fixed strings, because
|
|
207
|
+
* their suffix is minted in the write layer and the core deliberately never
|
|
208
|
+
* depends on it (see {@link blockedCode} / {@link verifyFailedCode}):
|
|
209
|
+
* - `verify-failed:${reason}` — a single mutation executed but read-after-write
|
|
210
|
+
* verification failed; the suffix is the reason (`timeout` | `mismatch` |
|
|
211
|
+
* `silent-noop`). The bare `verify-failed` (no suffix) is the multi-leg
|
|
212
|
+
* move/reorder failure.
|
|
213
|
+
* - `blocked:${suffix}` — a mutation refused before touching the app; the
|
|
214
|
+
* suffix is the specific hazard id (`H-…`) when one is named, else the block
|
|
215
|
+
* reason (`drift` | `disruption-tier` | `lock` | `environment` | `clock` |
|
|
216
|
+
* `scope`). The bare `blocked` is a policy refusal from the move planner.
|
|
217
|
+
*
|
|
218
|
+
* `blocked:drift` maps to exit code 5 (DriftBlocked); every other `blocked:*`
|
|
219
|
+
* maps to exit code 4 (Blocked).
|
|
220
|
+
*/
|
|
221
|
+
export type ErrorCode = "usage" | "not-found" | "ambiguous" | "unsupported" | "environment" | "unexpected" | "bounce-aborted" | "verify-failed" | "blocked" | `verify-failed:${string}` | `blocked:${string}`;
|
|
155
222
|
export interface ErrorEnvelope {
|
|
156
223
|
apiVersion: typeof API_VERSION;
|
|
157
224
|
ok: false;
|
|
158
225
|
kind: "error";
|
|
159
226
|
error: {
|
|
160
|
-
/** Stable machine-readable code
|
|
161
|
-
code:
|
|
227
|
+
/** Stable machine-readable code from the {@link ErrorCode} registry (mirrors the exit-code family, e.g. "verify-failed", "blocked:H-UNKNOWN-TAG"). */
|
|
228
|
+
code: ErrorCode;
|
|
162
229
|
message: string;
|
|
163
230
|
/**
|
|
164
231
|
* Advisory attribution when failure signals point somewhere: e.g.
|
|
@@ -168,25 +235,117 @@ export interface ErrorEnvelope {
|
|
|
168
235
|
likelyCause?: string;
|
|
169
236
|
/** Actionable next step for the caller, when one exists. */
|
|
170
237
|
remediation?: string;
|
|
171
|
-
detail?: unknown;
|
|
172
238
|
/**
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
239
|
+
* The SINGLE structured, machine-readable failure-context object (there is
|
|
240
|
+
* no separate `details` field — the two were reconciled into this one). Each
|
|
241
|
+
* key is present only for the failures that produce it:
|
|
242
|
+
* - `expected` / `observed` — a verify-failed mutation's expected delta and
|
|
243
|
+
* the observed post-write state.
|
|
244
|
+
* - `candidates` — the disambiguation list for a not-found / ambiguous
|
|
245
|
+
* resolution (or a show/bare-noun did-you-mean): the ONE fixed, flag-
|
|
246
|
+
* invariant candidate shape (`CandidateRef`; see docs/contract.md), a
|
|
247
|
+
* LIVE-scoped pool capped at 8, so an agent can self-correct without
|
|
248
|
+
* another round-trip.
|
|
249
|
+
* - `suggestions` — for a bare mutation verb (`things update <ref>`), the
|
|
250
|
+
* concrete namespaced command(s) to run instead.
|
|
251
|
+
* - `considered` — the vectors weighed (and why each was rejected) for an
|
|
252
|
+
* unsupported operation.
|
|
253
|
+
* - `placed` / `remaining` / `cause` — a bounce reorder that aborted
|
|
254
|
+
* part-way: the items already placed, those not yet placed, and the cause.
|
|
255
|
+
* - `failed` / `completed` — a multi-leg move that failed mid-way: the leg
|
|
256
|
+
* that failed and the legs already completed before it.
|
|
179
257
|
*/
|
|
180
|
-
|
|
258
|
+
detail?: {
|
|
259
|
+
expected?: unknown;
|
|
260
|
+
observed?: Record<string, unknown> | null;
|
|
181
261
|
candidates?: unknown[];
|
|
182
262
|
suggestions?: string[];
|
|
263
|
+
considered?: {
|
|
264
|
+
vector: string;
|
|
265
|
+
why: string;
|
|
266
|
+
}[];
|
|
267
|
+
placed?: string[];
|
|
268
|
+
remaining?: string[];
|
|
269
|
+
cause?: unknown;
|
|
270
|
+
failed?: unknown;
|
|
271
|
+
completed?: unknown[];
|
|
183
272
|
};
|
|
184
273
|
};
|
|
185
274
|
meta: EnvelopeMeta;
|
|
186
275
|
}
|
|
187
276
|
export type Envelope<T> = OkEnvelope<T> | ErrorEnvelope;
|
|
277
|
+
/**
|
|
278
|
+
* The envelope `kind` discriminators a SUCCESSFUL response carries today (the
|
|
279
|
+
* error envelope's `kind` is always the literal `"error"`). This union is the
|
|
280
|
+
* schema's record of the known payload classes — the flat-list reads
|
|
281
|
+
* (`data.items`), the sectioned reads (`data.sections`), the composite cards
|
|
282
|
+
* (`data.view`), the single-entity detail (`data.item`), the mutations/plans
|
|
283
|
+
* (flat `data` fields), and the diagnostic payloads.
|
|
284
|
+
*
|
|
285
|
+
* Per the compatibility covenant (docs/contract.md) a consumer MUST tolerate an
|
|
286
|
+
* UNKNOWN `kind`: adding a new kind is additive / non-breaking. So this union is
|
|
287
|
+
* "the kinds known to THIS build", not a closed set a generic reader may assume
|
|
288
|
+
* complete — the JSON Schema pins it as an enum so drift is caught, but a
|
|
289
|
+
* forward-compatible consumer routes on the wrapper it finds in `data`.
|
|
290
|
+
*/
|
|
291
|
+
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";
|
|
292
|
+
/**
|
|
293
|
+
* The `data` payload of a successful envelope. Its CONCRETE shape is
|
|
294
|
+
* command-specific — one of the R1/R2 read wrappers (`item` | `view` | `items` |
|
|
295
|
+
* `sections`) or a mutation's flat result fields — and, crucially, entity
|
|
296
|
+
* payloads are omit-empty pruned on the wire (docs/design/contracts.md).
|
|
297
|
+
*
|
|
298
|
+
* COVERAGE BOUNDARY: this schema does NOT model the per-kind payload shapes. It
|
|
299
|
+
* pins the ENVELOPE layer exactly (`apiVersion`, `ok`, `kind`, `meta`, and the
|
|
300
|
+
* whole `error` object) and treats `data` as an open JSON object. Fully typing
|
|
301
|
+
* every kind's payload against the omit-empty wire shape is a separate, larger
|
|
302
|
+
* effort; until then `src/contracts.ts` and `docs/contract.md` remain the
|
|
303
|
+
* authoritative description of what each `kind`'s `data` contains.
|
|
304
|
+
*/
|
|
305
|
+
export type WireData = Record<string, unknown>;
|
|
306
|
+
/** A successful `--json` envelope, exactly as emitted on stdout. */
|
|
307
|
+
export interface WireOkEnvelope {
|
|
308
|
+
apiVersion: typeof API_VERSION;
|
|
309
|
+
ok: true;
|
|
310
|
+
/** The payload class — see {@link WireOkKind}. */
|
|
311
|
+
kind: WireOkKind;
|
|
312
|
+
/** Command-specific payload; open at the schema layer (see {@link WireData}). */
|
|
313
|
+
data: WireData;
|
|
314
|
+
meta: EnvelopeMeta;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* The machine-readable ROOT the envelope JSON Schema is generated from
|
|
318
|
+
* (`schema/envelope.schema.json`, produced by `npm run schema:gen`): the
|
|
319
|
+
* discriminated union — on the boolean `ok` — of a successful envelope and an
|
|
320
|
+
* {@link ErrorEnvelope}, exactly as written to stdout by the CLI `--json`
|
|
321
|
+
* surface and inherited by the MCP server. This is the same grammar
|
|
322
|
+
* docs/contract.md describes in prose; the schema is its generated, testable
|
|
323
|
+
* rendering. NB: the streaming commands (`batch`, `undo`) emit JSON Lines, a
|
|
324
|
+
* documented exception NOT covered by this envelope type.
|
|
325
|
+
*/
|
|
326
|
+
export type WireEnvelope = WireOkEnvelope | ErrorEnvelope;
|
|
188
327
|
export declare function okEnvelope<T>(kind: string, data: T, meta: EnvelopeMeta): OkEnvelope<T>;
|
|
189
328
|
export declare function errorEnvelope(error: ErrorEnvelope["error"], meta: EnvelopeMeta): ErrorEnvelope;
|
|
329
|
+
/**
|
|
330
|
+
* Project a successful mutation/reorder/move outcome to its ENVELOPE `data`
|
|
331
|
+
* shape. The wire's mutation-success discriminator is REDUNDANT and is not
|
|
332
|
+
* emitted: the envelope already carries call success (`ok: true`, and the
|
|
333
|
+
* envelope `kind` names the payload class — `mutation-result` / `move-result`).
|
|
334
|
+
* So the result's internal `kind` discriminator is STRIPPED here — the emitted
|
|
335
|
+
* `data` has no `result` and no `kind`, just the payload fields (`op`, `uuid`,
|
|
336
|
+
* `title`, `undoToken`, `observed`, `vector`, `tier`, `touched`, notes, …).
|
|
337
|
+
* Only the internal tags `"ok"` / `"move-ok"` ever reach this boundary
|
|
338
|
+
* (failures route to error envelopes, dry-runs to the `mutation-plan` /
|
|
339
|
+
* `move-plan` kinds), so nothing is lost by dropping it. The library keeps the
|
|
340
|
+
* idiomatic `kind` discriminator on its in-memory
|
|
341
|
+
* `MutationResult`/`ReorderResult`/`MoveResult` unions; it simply never appears
|
|
342
|
+
* on the wire. BOTH consumer surfaces emit through it: the CLI (`mutation-result`
|
|
343
|
+
* / `move-result` envelopes) and the MCP mutation/move content block (phase-2
|
|
344
|
+
* framing sweep, 2026-07-31) — a dry-run routes to the bare `plan` on both.
|
|
345
|
+
*/
|
|
346
|
+
export declare function mutationWireData<T extends {
|
|
347
|
+
kind: string;
|
|
348
|
+
}>(ok: T): Omit<T, "kind">;
|
|
190
349
|
/**
|
|
191
350
|
* Canonical machine-readable error CODE for a refused ("blocked") mutation: the
|
|
192
351
|
* 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.
|
|
16
|
+
export const PKG_VERSION = "0.13.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 —
|
package/dist/contracts.js.map
CHANGED
|
@@ -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;
|
|
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;AA2UX,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"}
|
|
@@ -13,6 +13,9 @@ export const DB_V26 = {
|
|
|
13
13
|
// deadlineSuppressionDate):
|
|
14
14
|
// sha256:5526059b10ffffe1b67f796d031857d030403bd5b747374646a2803a55c0e5c3
|
|
15
15
|
fingerprint: "sha256:784bd2f6533e6f85e053b0ec68958083d4ebca11c152ad1d2935178240d4c52b",
|
|
16
|
-
|
|
16
|
+
// Things 3.22.12 (build 32212016) ships the IDENTICAL DB v26 schema (fingerprint
|
|
17
|
+
// byte-identical) and an identical Things.sdef — a behavioral-only update, re-certified
|
|
18
|
+
// 2026-08-03 against golden-v2 (drift-runbook step 3; assumption-register *Confirmed under*).
|
|
19
|
+
knownThingsAppVersions: ["3.22.11", "3.22.12"],
|
|
17
20
|
};
|
|
18
21
|
//# sourceMappingURL=db-v26.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-v26.js","sourceRoot":"","sources":["../../../src/db/baselines/db-v26.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAa;IAC9B,eAAe,EAAE,EAAE;IACnB,oEAAoE;IACpE,0EAA0E;IAC1E,yEAAyE;IACzE,kEAAkE;IAClE,4BAA4B;IAC5B,4EAA4E;IAC5E,WAAW,EAAE,yEAAyE;IACtF,sBAAsB,EAAE,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"db-v26.js","sourceRoot":"","sources":["../../../src/db/baselines/db-v26.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAa;IAC9B,eAAe,EAAE,EAAE;IACnB,oEAAoE;IACpE,0EAA0E;IAC1E,yEAAyE;IACzE,kEAAkE;IAClE,4BAA4B;IAC5B,4EAA4E;IAC5E,WAAW,EAAE,yEAAyE;IACtF,iFAAiF;IACjF,wFAAwF;IACxF,8FAA8F;IAC9F,sBAAsB,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/C,CAAC"}
|
package/dist/diagnose.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type CertificationStatus } from "./write/vectors/ui-certification.ts";
|
|
|
4
4
|
import { type AvailabilityDeps, type ShortcutsState, type UrlSchemeState } from "./write/availability.ts";
|
|
5
5
|
import { type EnvironmentChange, type EnvironmentTracker, type EnvironmentTuple } from "./write/environment.ts";
|
|
6
6
|
import { type SyncHealth, type SyncHealthDeps } from "./sync-health.ts";
|
|
7
|
-
import { ExitCode, type EnvelopeMeta } from "./contracts.ts";
|
|
7
|
+
import { ExitCode, type EnvelopeMeta, type ErrorCode } from "./contracts.ts";
|
|
8
8
|
export interface DiagnoseReport {
|
|
9
9
|
db: {
|
|
10
10
|
path: string;
|
|
@@ -21,11 +21,43 @@ export interface DiagnoseReport {
|
|
|
21
21
|
};
|
|
22
22
|
app: {
|
|
23
23
|
installed: boolean;
|
|
24
|
+
/** Installed app version (CFBundleShortVersionString); null when unreadable. */
|
|
25
|
+
version: string | null;
|
|
26
|
+
/**
|
|
27
|
+
* The app version the behavioral LAWS were last certified against
|
|
28
|
+
* (config `certified-app-version`); null when never set.
|
|
29
|
+
*/
|
|
30
|
+
certifiedVersion: string | null;
|
|
31
|
+
/**
|
|
32
|
+
* True when the installed version is known, a certified version is set, and
|
|
33
|
+
* they differ — a PASSIVE signal that the behavioral laws
|
|
34
|
+
* (docs/reference/assumption-register.md) may have moved with zero schema
|
|
35
|
+
* delta. Non-blocking: writes stay enabled; doctor emits a notice pointing
|
|
36
|
+
* at the drift suite. False when unset/unknown/matching.
|
|
37
|
+
*/
|
|
38
|
+
behavioralDrift: boolean;
|
|
24
39
|
};
|
|
25
40
|
writes: {
|
|
26
41
|
enabled: boolean;
|
|
27
42
|
reason: string;
|
|
28
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* The active container scope (from THINGS_API_SCOPE / the stored `scope` key),
|
|
46
|
+
* so the jail is never silently on. `requested` is the raw ref (null when
|
|
47
|
+
* unscoped); `resolved` names the container it pins to (null when the ref no
|
|
48
|
+
* longer resolves — a fail-closed empty jail). The MCP `--scope` flag is
|
|
49
|
+
* per-process and not visible here.
|
|
50
|
+
*/
|
|
51
|
+
scope: {
|
|
52
|
+
requested: string | null;
|
|
53
|
+
source: "env" | "config" | null;
|
|
54
|
+
resolved: {
|
|
55
|
+
kind: "area" | "project";
|
|
56
|
+
uuid: string;
|
|
57
|
+
title: string;
|
|
58
|
+
} | null;
|
|
59
|
+
detail: string;
|
|
60
|
+
};
|
|
29
61
|
experimental: {
|
|
30
62
|
/** config allowExperimental (opt-in for private-surface capabilities). */
|
|
31
63
|
enabled: boolean;
|
|
@@ -132,7 +164,7 @@ export interface DiagnoseOptions {
|
|
|
132
164
|
export interface DiagnoseResult {
|
|
133
165
|
report: DiagnoseReport | null;
|
|
134
166
|
error: {
|
|
135
|
-
code:
|
|
167
|
+
code: ErrorCode;
|
|
136
168
|
message: string;
|
|
137
169
|
remediation?: string;
|
|
138
170
|
} | null;
|