things-api 0.17.0 → 0.18.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 +1 -1
- package/deputy/VERSION +1 -0
- package/deputy/helpers-Info.plist +23 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/CodeResources +0 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/Info.plist +20 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/MacOS/things-reader +0 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/_CodeSignature/CodeResources +115 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/Info.plist +23 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/MacOS/things-deputy +0 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/_CodeSignature/CodeResources +125 -0
- package/deputy/reader/Info.plist +20 -0
- package/deputy/reader/entitlements.plist +15 -0
- package/deputy/reader/main.swift +491 -0
- package/deputy/src/main.swift +133 -0
- package/deputy/src/osascript.swift +102 -0
- package/deputy/src/server.swift +350 -0
- package/deputy/src/sqlite.swift +121 -0
- package/dist/cli/commands/doctor.js +55 -2
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/helpers.d.ts +17 -0
- package/dist/cli/commands/helpers.js +148 -0
- package/dist/cli/commands/helpers.js.map +1 -0
- package/dist/cli/commands/op-result.d.ts +15 -0
- package/dist/cli/commands/op-result.js +39 -0
- package/dist/cli/commands/op-result.js.map +1 -0
- package/dist/cli/commands/writes.js +22 -3
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/help.js +4 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/helpers-check.d.ts +10 -0
- package/dist/cli/helpers-check.js +59 -0
- package/dist/cli/helpers-check.js.map +1 -0
- package/dist/cli/main.js +22 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/client.js +16 -2
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +31 -0
- package/dist/config.js +9 -0
- package/dist/config.js.map +1 -1
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.js +1 -1
- package/dist/db/baselines/db-v26.js +8 -4
- package/dist/db/baselines/db-v26.js.map +1 -1
- package/dist/db/baselines/db-v27.d.ts +42 -0
- package/dist/db/baselines/db-v27.js +47 -0
- package/dist/db/baselines/db-v27.js.map +1 -0
- package/dist/db/baselines/index.js +2 -1
- package/dist/db/baselines/index.js.map +1 -1
- package/dist/db/locate.d.ts +4 -1
- package/dist/db/locate.js +3 -1
- package/dist/db/locate.js.map +1 -1
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +9 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/deputy/bridge-worker.d.ts +1 -0
- package/dist/deputy/bridge-worker.js +79 -0
- package/dist/deputy/bridge-worker.js.map +1 -0
- package/dist/deputy/bridge.d.ts +14 -0
- package/dist/deputy/bridge.js +70 -0
- package/dist/deputy/bridge.js.map +1 -0
- package/dist/deputy/client.d.ts +19 -0
- package/dist/deputy/client.js +104 -0
- package/dist/deputy/client.js.map +1 -0
- package/dist/deputy/db-facade.d.ts +18 -0
- package/dist/deputy/db-facade.js +71 -0
- package/dist/deputy/db-facade.js.map +1 -0
- package/dist/deputy/files.d.ts +1 -0
- package/dist/deputy/files.js +16 -0
- package/dist/deputy/files.js.map +1 -0
- package/dist/deputy/install.d.ts +105 -0
- package/dist/deputy/install.js +467 -0
- package/dist/deputy/install.js.map +1 -0
- package/dist/deputy/notice.d.ts +6 -0
- package/dist/deputy/notice.js +28 -0
- package/dist/deputy/notice.js.map +1 -0
- package/dist/deputy/notices.d.ts +31 -0
- package/dist/deputy/notices.js +94 -0
- package/dist/deputy/notices.js.map +1 -0
- package/dist/deputy/osa.d.ts +21 -0
- package/dist/deputy/osa.js +72 -0
- package/dist/deputy/osa.js.map +1 -0
- package/dist/deputy/protocol.d.ts +86 -0
- package/dist/deputy/protocol.js +106 -0
- package/dist/deputy/protocol.js.map +1 -0
- package/dist/deputy/routing.d.ts +63 -0
- package/dist/deputy/routing.js +338 -0
- package/dist/deputy/routing.js.map +1 -0
- package/dist/deputy/shortcuts-exec.d.ts +10 -0
- package/dist/deputy/shortcuts-exec.js +50 -0
- package/dist/deputy/shortcuts-exec.js.map +1 -0
- package/dist/diagnose.d.ts +43 -1
- package/dist/diagnose.js +64 -2
- package/dist/diagnose.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +25 -7
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/mappers.d.ts +12 -3
- package/dist/model/mappers.js +6 -1
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/recurrence.d.ts +5 -1
- package/dist/model/recurrence.js +19 -1
- package/dist/model/recurrence.js.map +1 -1
- package/dist/model/template-projection.d.ts +26 -0
- package/dist/model/template-projection.js +113 -0
- package/dist/model/template-projection.js.map +1 -0
- package/dist/op-result.d.ts +46 -0
- package/dist/op-result.js +156 -0
- package/dist/op-result.js.map +1 -0
- package/dist/read/detail.js +7 -1
- package/dist/read/detail.js.map +1 -1
- package/dist/read/queries.js +8 -1
- package/dist/read/queries.js.map +1 -1
- package/dist/read/views.d.ts +6 -4
- package/dist/read/views.js +60 -18
- package/dist/read/views.js.map +1 -1
- package/dist/sync-health.js +6 -2
- package/dist/sync-health.js.map +1 -1
- package/dist/write/accessibility-probe.js +4 -2
- package/dist/write/accessibility-probe.js.map +1 -1
- package/dist/write/automation-probe.js +5 -1
- package/dist/write/automation-probe.js.map +1 -1
- package/dist/write/availability.js +7 -3
- package/dist/write/availability.js.map +1 -1
- package/dist/write/commands.js +58 -13
- package/dist/write/commands.js.map +1 -1
- package/dist/write/experimental.d.ts +19 -0
- package/dist/write/experimental.js +50 -0
- package/dist/write/experimental.js.map +1 -1
- package/dist/write/move.js +14 -6
- package/dist/write/move.js.map +1 -1
- package/dist/write/operations.d.ts +28 -4
- package/dist/write/pipeline.d.ts +2 -0
- package/dist/write/pipeline.js +59 -2
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/pre-state.js +33 -15
- package/dist/write/pre-state.js.map +1 -1
- package/dist/write/promote-clone.js +187 -19
- package/dist/write/promote-clone.js.map +1 -1
- package/dist/write/reorder.js +76 -27
- package/dist/write/reorder.js.map +1 -1
- package/dist/write/repeat-anchor.d.ts +30 -0
- package/dist/write/repeat-anchor.js +166 -1
- package/dist/write/repeat-anchor.js.map +1 -1
- package/dist/write/repeat-rule.js +10 -0
- package/dist/write/repeat-rule.js.map +1 -1
- package/dist/write/vectors/applescript.js +7 -16
- package/dist/write/vectors/applescript.js.map +1 -1
- package/dist/write/vectors/session-reachability.d.ts +55 -0
- package/dist/write/vectors/session-reachability.js +56 -8
- package/dist/write/vectors/session-reachability.js.map +1 -1
- package/dist/write/vectors/shortcuts.js +5 -14
- package/dist/write/vectors/shortcuts.js.map +1 -1
- package/dist/write/vectors/simulator.d.ts +16 -1
- package/dist/write/vectors/simulator.js +61 -10
- package/dist/write/vectors/simulator.js.map +1 -1
- package/dist/write/vectors/types.d.ts +67 -1
- package/dist/write/vectors/ui-recipes.js +128 -38
- package/dist/write/vectors/ui-recipes.js.map +1 -1
- package/dist/write/vectors/ui.d.ts +76 -0
- package/dist/write/vectors/ui.js +443 -37
- package/dist/write/vectors/ui.js.map +1 -1
- package/dist/write/verify/poller.d.ts +13 -0
- package/dist/write/verify/poller.js +38 -0
- package/dist/write/verify/poller.js.map +1 -1
- package/package.json +8 -1
- package/scripts/build-helpers.sh +104 -0
- package/scripts/deputy-cert-setup.sh +60 -0
- package/skills/things-cli/SKILL.md +8 -3
- package/skills/things-cli/references/errors.md +4 -0
- package/skills/things-cli/references/repeating.md +69 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deputy routing: decides ONCE per process whether privileged primitives (SQL
|
|
3
|
+
* reads, osascript, container file reads) go through the things-deputy broker
|
|
4
|
+
* or run direct exactly as they always have.
|
|
5
|
+
*
|
|
6
|
+
* Mode resolution (highest wins): the CLI `--helpers/--no-helpers` flag (which
|
|
7
|
+
* writes THINGS_API_HELPERS before any load) → THINGS_API_HELPERS env → stored
|
|
8
|
+
* `helpers-enabled` config → default `auto`. Direct execution is the contract's
|
|
9
|
+
* ground truth; the helpers are an alternative transport for the same
|
|
10
|
+
* primitives.
|
|
11
|
+
*
|
|
12
|
+
* The tri-state (docs/design/agent-daemon.md §3c):
|
|
13
|
+
*
|
|
14
|
+
* | mode | helper absent | installed, unhealthy | installed, healthy |
|
|
15
|
+
* |---------|--------------------------|----------------------|--------------------|
|
|
16
|
+
* | `auto` | direct, SILENT | direct, LOUD | routed |
|
|
17
|
+
* | `true` | direct, LOUD | direct, LOUD | routed |
|
|
18
|
+
* | `false` | direct, silent | direct, silent | direct, silent |
|
|
19
|
+
*
|
|
20
|
+
* Under `auto` installation IS the intent signal, so absence is not a
|
|
21
|
+
* degradation to report (a fresh machine must not nag) while an installed
|
|
22
|
+
* helper that cannot serve is — silence there would hide the very consent churn
|
|
23
|
+
* the helpers exist to end.
|
|
24
|
+
*
|
|
25
|
+
* Fallback is decided at ACTIVATION, never mid-operation: if a helper is
|
|
26
|
+
* expected but unreachable (or speaks a different protocol), the whole process
|
|
27
|
+
* runs direct with one stderr notice — a half-routed operation is worse than
|
|
28
|
+
* an honestly direct one. A helper that dies mid-request surfaces as that
|
|
29
|
+
* request's error; it is never silently retried on the other path.
|
|
30
|
+
*/
|
|
31
|
+
import { execFileSync } from "node:child_process";
|
|
32
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
33
|
+
import { loadConfig } from "../config.js";
|
|
34
|
+
import { DeputySyncBridge } from "./bridge.js";
|
|
35
|
+
import { DeputyAsyncClient } from "./client.js";
|
|
36
|
+
import { emitHelpersNotice, resetHelpersNoticeForTests } from "./notice.js";
|
|
37
|
+
import { DEPUTY_LAUNCHD_LABEL, DEPUTY_PROTOCOL_VERSION, DeputyRequestError, deputyInstalledBinaryPath, deputySocketPath, deputyTokenPath, EXPECTED_HELPERS_VERSION, readerInstalledAppPath, readerSocketPath, readerTokenPath, } from "./protocol.js";
|
|
38
|
+
let state = null;
|
|
39
|
+
let readerState = null;
|
|
40
|
+
/** Test seam: forget the per-process activation memo (and close transports). */
|
|
41
|
+
export function resetDeputyRoutingForTests() {
|
|
42
|
+
if (state?.active === true) {
|
|
43
|
+
state.bridge.close();
|
|
44
|
+
state.client.close();
|
|
45
|
+
}
|
|
46
|
+
readerState?.bridge?.close();
|
|
47
|
+
state = null;
|
|
48
|
+
readerState = null;
|
|
49
|
+
resetHelpersNoticeForTests();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Report a degradation — but only when the mode asks to hear about it. Under
|
|
53
|
+
* `auto` an ABSENT helper is an ordinary machine, not a fault: `loud` is false
|
|
54
|
+
* there and the process just runs direct.
|
|
55
|
+
*/
|
|
56
|
+
function notice(loud, message) {
|
|
57
|
+
if (loud)
|
|
58
|
+
emitHelpersNotice(message);
|
|
59
|
+
}
|
|
60
|
+
function syncSleep(ms) {
|
|
61
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
62
|
+
}
|
|
63
|
+
function hello(bridge, token) {
|
|
64
|
+
const res = bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token, verb: "hello" }, 2000);
|
|
65
|
+
if (res["ok"] !== true) {
|
|
66
|
+
const err = res["error"];
|
|
67
|
+
throw new DeputyRequestError(err?.code ?? "internal", err?.message ?? "handshake refused");
|
|
68
|
+
}
|
|
69
|
+
return res;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Version-skew policy: a PROTOCOL mismatch always deactivates (the shapes on
|
|
73
|
+
* the wire cannot be trusted). The helpers are versioned on their own line
|
|
74
|
+
* (EXPECTED_HELPERS_VERSION, decoupled from the package version so unchanged
|
|
75
|
+
* helpers never nag across package releases); a helpers-version mismatch on
|
|
76
|
+
* matching protocol gets one automatic `launchctl kickstart` (the installed
|
|
77
|
+
* bundle may already be newer on disk — the daily npm-link reality), then
|
|
78
|
+
* proceeds with a notice: the helpers' verbs are dumb primitives, so
|
|
79
|
+
* cross-version execution is safe by construction as long as the protocol
|
|
80
|
+
* matches.
|
|
81
|
+
*/
|
|
82
|
+
function reconcileVersions(bridge, token, first) {
|
|
83
|
+
if (first.deputyVersion === EXPECTED_HELPERS_VERSION)
|
|
84
|
+
return first;
|
|
85
|
+
try {
|
|
86
|
+
execFileSync("launchctl", ["kickstart", "-k", `gui/${process.getuid?.() ?? 501}/${DEPUTY_LAUNCHD_LABEL}`],
|
|
87
|
+
// Clears the helpers' drain bound: kickstart -k waits for the old
|
|
88
|
+
// process, which finishes an in-flight request before exiting.
|
|
89
|
+
{ stdio: "ignore", timeout: 30_000 });
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Not installed under launchd (foreground/test deputy) — nothing to restart.
|
|
93
|
+
notice(true, `installed helpers are v${first.deputyVersion}, this package expects v${EXPECTED_HELPERS_VERSION} (same protocol) — proceeding; rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers install\` to align`);
|
|
94
|
+
return first;
|
|
95
|
+
}
|
|
96
|
+
for (let attempt = 0; attempt < 8; attempt++) {
|
|
97
|
+
syncSleep(250);
|
|
98
|
+
try {
|
|
99
|
+
const fresh = hello(bridge, token);
|
|
100
|
+
if (fresh.deputyVersion === EXPECTED_HELPERS_VERSION)
|
|
101
|
+
return fresh;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Restart still in flight — keep waiting out the bounded window.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const current = hello(bridge, token);
|
|
108
|
+
notice(true, `installed helpers are v${current.deputyVersion}, this package expects v${EXPECTED_HELPERS_VERSION} (same protocol) — proceeding; rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers install\` to align`);
|
|
109
|
+
return current;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Is a helper half INSTALLED on this machine? Installation is what separates
|
|
113
|
+
* "this host does not use the helpers" (silent under `auto`) from "the helper
|
|
114
|
+
* this host installed cannot serve" (always loud). The installed bundle on disk
|
|
115
|
+
* is the durable signal — a stopped launchd job leaves no socket but the bundle
|
|
116
|
+
* stays put.
|
|
117
|
+
*/
|
|
118
|
+
function halfInstalled(path, socketPath, tokenPath) {
|
|
119
|
+
return existsSync(path) || (existsSync(socketPath) && existsSync(tokenPath));
|
|
120
|
+
}
|
|
121
|
+
function activate(env) {
|
|
122
|
+
const mode = loadConfig(env).helpersMode;
|
|
123
|
+
if (mode === "false")
|
|
124
|
+
return { active: false, reason: "disabled", hello: null };
|
|
125
|
+
const socketPath = deputySocketPath(env);
|
|
126
|
+
const tokenPath = deputyTokenPath(env);
|
|
127
|
+
const installed = halfInstalled(deputyInstalledBinaryPath(env), socketPath, tokenPath);
|
|
128
|
+
// `auto` + nothing installed = an ordinary un-onboarded machine, not a fault.
|
|
129
|
+
const loud = mode === "true" || installed;
|
|
130
|
+
if (!existsSync(socketPath) || !existsSync(tokenPath)) {
|
|
131
|
+
notice(loud, `${installed
|
|
132
|
+
? `installed but not running (no socket at ${socketPath})`
|
|
133
|
+
: "not installed on this machine"} — running DIRECT, so TCC prompts attach to this process. \`things helpers ${installed ? "status` to inspect" : "install` to change that"}.`);
|
|
134
|
+
return {
|
|
135
|
+
active: false,
|
|
136
|
+
reason: installed
|
|
137
|
+
? `deputy not running (no socket at ${socketPath})`
|
|
138
|
+
: "deputy not installed",
|
|
139
|
+
hello: null,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const token = readFileSync(tokenPath, "utf8").trim();
|
|
143
|
+
const bridge = new DeputySyncBridge(socketPath);
|
|
144
|
+
let helloResult;
|
|
145
|
+
try {
|
|
146
|
+
helloResult = reconcileVersions(bridge, token, hello(bridge, token));
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
bridge.close();
|
|
150
|
+
const why = err instanceof Error ? err.message : String(err);
|
|
151
|
+
// A socket that will not handshake is a broken helper under EVERY non-off
|
|
152
|
+
// mode — never silent, whatever the mode says about absence.
|
|
153
|
+
notice(true, `the handshake failed (${why}) — running DIRECT. \`things helpers restart\`, then \`things helpers status\` to inspect.`);
|
|
154
|
+
return { active: false, reason: `handshake failed: ${why}`, hello: null };
|
|
155
|
+
}
|
|
156
|
+
if (helloResult.protocol !== DEPUTY_PROTOCOL_VERSION) {
|
|
157
|
+
bridge.close();
|
|
158
|
+
notice(true, `the deputy speaks protocol ${helloResult.protocol}, this package speaks ${DEPUTY_PROTOCOL_VERSION} — running DIRECT. Rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers install\`.`);
|
|
159
|
+
return {
|
|
160
|
+
active: false,
|
|
161
|
+
reason: `protocol skew (deputy ${helloResult.protocol}, library ${DEPUTY_PROTOCOL_VERSION})`,
|
|
162
|
+
hello: null,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
active: true,
|
|
167
|
+
reason: null,
|
|
168
|
+
hello: helloResult,
|
|
169
|
+
token,
|
|
170
|
+
bridge,
|
|
171
|
+
client: new DeputyAsyncClient(socketPath),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/** The per-process routing decision (activated lazily on first ask). */
|
|
175
|
+
export function deputyRouting(env = process.env) {
|
|
176
|
+
state ??= activate(env);
|
|
177
|
+
return state;
|
|
178
|
+
}
|
|
179
|
+
function activeState(env) {
|
|
180
|
+
const routing = deputyRouting(env);
|
|
181
|
+
return routing.active ? state : null;
|
|
182
|
+
}
|
|
183
|
+
function readerInactive(reason) {
|
|
184
|
+
return { active: false, granted: false, hello: null, token: "", bridge: null, reason };
|
|
185
|
+
}
|
|
186
|
+
function activateReader(env) {
|
|
187
|
+
const mode = loadConfig(env).helpersMode;
|
|
188
|
+
if (mode === "false")
|
|
189
|
+
return readerInactive("disabled");
|
|
190
|
+
const socketPath = readerSocketPath(env);
|
|
191
|
+
const tokenPath = readerTokenPath(env);
|
|
192
|
+
const installed = halfInstalled(readerInstalledAppPath(env), socketPath, tokenPath);
|
|
193
|
+
if (!existsSync(socketPath) || !existsSync(tokenPath)) {
|
|
194
|
+
// Absence is silent under `auto`; under `true` the caller asserted routing.
|
|
195
|
+
// An UNGRANTED reader is deliberately NOT noticed here — that is the
|
|
196
|
+
// ceremony's own state, reported by `things helpers status` and doctor.
|
|
197
|
+
notice(mode === "true" || installed, installed
|
|
198
|
+
? `the reader is installed but not running (no socket at ${socketPath}) — database reads run DIRECT. \`things helpers status\` to inspect.`
|
|
199
|
+
: "the reader is not installed on this machine — database reads run DIRECT. `things helpers install` to change that.");
|
|
200
|
+
return readerInactive(installed ? `reader not running (no socket at ${socketPath})` : "reader not installed");
|
|
201
|
+
}
|
|
202
|
+
const token = readFileSync(tokenPath, "utf8").trim();
|
|
203
|
+
const bridge = new DeputySyncBridge(socketPath);
|
|
204
|
+
try {
|
|
205
|
+
const res = bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token, verb: "hello" }, 2000);
|
|
206
|
+
if (res["ok"] !== true)
|
|
207
|
+
throw new DeputyRequestError("handshake", JSON.stringify(res["error"]));
|
|
208
|
+
const readerHello = res;
|
|
209
|
+
if (readerHello.protocol !== DEPUTY_PROTOCOL_VERSION) {
|
|
210
|
+
bridge.close();
|
|
211
|
+
notice(true, `the reader speaks protocol ${readerHello.protocol}, this package speaks ${DEPUTY_PROTOCOL_VERSION} — database reads run DIRECT. Rebuild with \`bash scripts/build-helpers.sh\` + \`things helpers install\`.`);
|
|
212
|
+
return readerInactive(`protocol skew (reader ${readerHello.protocol})`);
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
active: true,
|
|
216
|
+
granted: readerHello.granted === true,
|
|
217
|
+
hello: readerHello,
|
|
218
|
+
token,
|
|
219
|
+
bridge,
|
|
220
|
+
reason: null,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
bridge.close();
|
|
225
|
+
const why = err instanceof Error ? err.message : String(err);
|
|
226
|
+
notice(true, `the reader handshake failed (${why}) — database reads run DIRECT. \`things helpers restart\`, then \`things helpers status\` to inspect.`);
|
|
227
|
+
return readerInactive(`reader handshake failed: ${why}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/** The reader transport's state (activated lazily; test seam via reset). */
|
|
231
|
+
export function readerRouting(env = process.env) {
|
|
232
|
+
readerState ??= activateReader(env);
|
|
233
|
+
return readerState;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* The transport serving FILE verbs (sql / read-file / locate): the sandboxed
|
|
237
|
+
* reader when present AND granted, else null (direct local access). ONLY the
|
|
238
|
+
* reader — the deputy is mutations-only by design (the maintainer's ruling
|
|
239
|
+
* 2026-08-21: no multi-step fallback chains; its container access would ride
|
|
240
|
+
* the per-process consent class this pair exists to end). A reader that dies
|
|
241
|
+
* mid-request errors that request honestly, never a silent transport switch.
|
|
242
|
+
*/
|
|
243
|
+
function fileTransport(env) {
|
|
244
|
+
const reader = readerRouting(env);
|
|
245
|
+
if (reader.active && reader.granted) {
|
|
246
|
+
const rs = readerState;
|
|
247
|
+
return { bridge: rs.bridge, token: rs.token };
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
export function helpersRouting(env = process.env) {
|
|
252
|
+
const mode = loadConfig(env).helpersMode;
|
|
253
|
+
const deputy = deputyRouting(env);
|
|
254
|
+
const reader = readerRouting(env);
|
|
255
|
+
const files = deputyFilesActive(env);
|
|
256
|
+
return {
|
|
257
|
+
mode,
|
|
258
|
+
automation: deputy.active,
|
|
259
|
+
files,
|
|
260
|
+
deputyReason: deputy.reason,
|
|
261
|
+
readerReason: files
|
|
262
|
+
? null
|
|
263
|
+
: reader.active && !reader.granted
|
|
264
|
+
? "reader running but NOT granted (things helpers grant)"
|
|
265
|
+
: reader.reason,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/** True when file verbs ride the reader (present, protocol-matched, granted). */
|
|
269
|
+
export function deputyFilesActive(env = process.env) {
|
|
270
|
+
return fileTransport(env) !== null;
|
|
271
|
+
}
|
|
272
|
+
/** Blocking FILE-verb round-trip via the granted reader. */
|
|
273
|
+
export function fileSyncRequest(fields, timeoutMs, env = process.env) {
|
|
274
|
+
const transport = fileTransport(env);
|
|
275
|
+
if (transport === null) {
|
|
276
|
+
throw new DeputyRequestError("inactive", "the reader is not active");
|
|
277
|
+
}
|
|
278
|
+
return unwrap(transport.bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token: transport.token, ...fields }, timeoutMs));
|
|
279
|
+
}
|
|
280
|
+
/** Unwrap a protocol response: return it on ok, throw DeputyRequestError otherwise. */
|
|
281
|
+
function unwrap(res) {
|
|
282
|
+
if (res["ok"] === true)
|
|
283
|
+
return res;
|
|
284
|
+
const err = res["error"];
|
|
285
|
+
throw new DeputyRequestError(err?.code ?? "internal", err?.message ?? "deputy refused the request");
|
|
286
|
+
}
|
|
287
|
+
/** Blocking round-trip via the bridge (facade + sync probes only). */
|
|
288
|
+
export function deputySyncRequest(fields, timeoutMs, env = process.env) {
|
|
289
|
+
const active = activeState(env);
|
|
290
|
+
if (active === null)
|
|
291
|
+
throw new DeputyRequestError("inactive", "deputy routing is not active");
|
|
292
|
+
return unwrap(active.bridge.request({ v: DEPUTY_PROTOCOL_VERSION, token: active.token, ...fields }, timeoutMs));
|
|
293
|
+
}
|
|
294
|
+
/** Event-loop-friendly round-trip (vector dispatch). */
|
|
295
|
+
export async function deputyAsyncRequest(fields, timeoutMs, env = process.env) {
|
|
296
|
+
const active = activeState(env);
|
|
297
|
+
if (active === null)
|
|
298
|
+
throw new DeputyRequestError("inactive", "deputy routing is not active");
|
|
299
|
+
return unwrap(await active.client.request({ v: DEPUTY_PROTOCOL_VERSION, token: active.token, ...fields }, timeoutMs));
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* The reader-resolved container database path, or null when no granted reader
|
|
303
|
+
* is active (the caller then locates locally, exactly as before the helpers
|
|
304
|
+
* existed). The reader's scope is grant-checked, never prompted — a locate
|
|
305
|
+
* through it can refuse but can never stall on a consent dialog.
|
|
306
|
+
*/
|
|
307
|
+
export function deputyDbPath(env = process.env) {
|
|
308
|
+
const reader = readerRouting(env);
|
|
309
|
+
if (!reader.active || !reader.granted)
|
|
310
|
+
return null;
|
|
311
|
+
if (reader.hello?.dbPath != null)
|
|
312
|
+
return reader.hello.dbPath;
|
|
313
|
+
const rs = readerState;
|
|
314
|
+
if (rs.dbPathMemo !== undefined)
|
|
315
|
+
return rs.dbPathMemo;
|
|
316
|
+
try {
|
|
317
|
+
const res = fileSyncRequest({ verb: "locate" }, 10_000, env);
|
|
318
|
+
rs.dbPathMemo = typeof res["path"] === "string" ? res["path"] : null;
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
rs.dbPathMemo = null;
|
|
322
|
+
const why = err instanceof Error ? err.message : String(err);
|
|
323
|
+
emitHelpersNotice(`the reader could not resolve the database (${why}) — this read runs DIRECT`);
|
|
324
|
+
}
|
|
325
|
+
return rs.dbPathMemo;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Should DATABASE access route through the deputy? Only for the default
|
|
329
|
+
* container database: an explicit dbPath option or THINGS_DB env names a
|
|
330
|
+
* caller-chosen file (lab clones, fixtures) the deputy knows nothing about —
|
|
331
|
+
* those always open locally, deputy or no deputy.
|
|
332
|
+
*/
|
|
333
|
+
export function deputyRoutesDb(options, env = process.env) {
|
|
334
|
+
if (options?.dbPath !== undefined || (env["THINGS_DB"] ?? "") !== "")
|
|
335
|
+
return false;
|
|
336
|
+
return deputyFilesActive(env);
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/deputy/routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,EAAoB,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EAEvB,kBAAkB,EAClB,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EAExB,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,GAChB,MAAM,eAAe,CAAC;AA8CvB,IAAI,KAAK,GAAwB,IAAI,CAAC;AACtC,IAAI,WAAW,GAAuB,IAAI,CAAC;AAE3C,gFAAgF;AAChF,MAAM,UAAU,0BAA0B;IACxC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,EAAE,CAAC;QAC3B,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IACD,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC7B,KAAK,GAAG,IAAI,CAAC;IACb,WAAW,GAAG,IAAI,CAAC;IACnB,0BAA0B,EAAE,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,SAAS,MAAM,CAAC,IAAa,EAAE,OAAe;IAC5C,IAAI,IAAI;QAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,SAAS,CAAC,EAAU;IAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,KAAK,CAAC,MAAwB,EAAE,KAAa;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IACvF,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAoD,CAAC;QAC5E,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,IAAI,IAAI,UAAU,EAAE,GAAG,EAAE,OAAO,IAAI,mBAAmB,CAAC,CAAC;IAC7F,CAAC;IACD,OAAO,GAA6B,CAAC;AACvC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,iBAAiB,CACxB,MAAwB,EACxB,KAAa,EACb,KAAkB;IAElB,IAAI,KAAK,CAAC,aAAa,KAAK,wBAAwB;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,CAAC;QACH,YAAY,CACV,WAAW,EACX,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC/E,kEAAkE;QAClE,+DAA+D;QAC/D,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CACrC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;QAC7E,MAAM,CACJ,IAAI,EACJ,0BAA0B,KAAK,CAAC,aAAa,2BAA2B,wBAAwB,qHAAqH,CACtN,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,SAAS,CAAC,GAAG,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACnC,IAAI,KAAK,CAAC,aAAa,KAAK,wBAAwB;gBAAE,OAAO,KAAK,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,iEAAiE;QACnE,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,CACJ,IAAI,EACJ,0BAA0B,OAAO,CAAC,aAAa,2BAA2B,wBAAwB,qHAAqH,CACxN,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,IAAY,EAAE,UAAkB,EAAE,SAAiB;IACxE,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,SAAS,QAAQ,CAAC,GAAsB;IACtC,MAAM,IAAI,GAAgB,UAAU,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;IACtD,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAEhF,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,aAAa,CAAC,yBAAyB,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACvF,8EAA8E;IAC9E,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM,IAAI,SAAS,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACtD,MAAM,CACJ,IAAI,EACJ,GACE,SAAS;YACP,CAAC,CAAC,2CAA2C,UAAU,GAAG;YAC1D,CAAC,CAAC,+BACN,8EACE,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,yBACrC,GAAG,CACJ,CAAC;QACF,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,SAAS;gBACf,CAAC,CAAC,oCAAoC,UAAU,GAAG;gBACnD,CAAC,CAAC,sBAAsB;YAC1B,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,WAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,0EAA0E;QAC1E,6DAA6D;QAC7D,MAAM,CACJ,IAAI,EACJ,yBAAyB,GAAG,4FAA4F,CACzH,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,WAAW,CAAC,QAAQ,KAAK,uBAAuB,EAAE,CAAC;QACrD,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,CACJ,IAAI,EACJ,8BAA8B,WAAW,CAAC,QAAQ,yBAAyB,uBAAuB,iGAAiG,CACpM,CAAC;QACF,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,yBAAyB,WAAW,CAAC,QAAQ,aAAa,uBAAuB,GAAG;YAC5F,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;QACZ,KAAK,EAAE,WAAW;QAClB,KAAK;QACL,MAAM;QACN,MAAM,EAAE,IAAI,iBAAiB,CAAC,UAAU,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,aAAa,CAAC,MAAyB,OAAO,CAAC,GAAG;IAChE,KAAK,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,GAAsB;IACzC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAE,KAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC;AAED,SAAS,cAAc,CAAC,MAAc;IACpC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACzF,CAAC;AAED,SAAS,cAAc,CAAC,GAAsB;IAC5C,MAAM,IAAI,GAAgB,UAAU,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;IACtD,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,cAAc,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,aAAa,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACpF,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACtD,4EAA4E;QAC5E,qEAAqE;QACrE,wEAAwE;QACxE,MAAM,CACJ,IAAI,KAAK,MAAM,IAAI,SAAS,EAC5B,SAAS;YACP,CAAC,CAAC,yDAAyD,UAAU,sEAAsE;YAC3I,CAAC,CAAC,mHAAmH,CACxH,CAAC;QACF,OAAO,cAAc,CACnB,SAAS,CAAC,CAAC,CAAC,oCAAoC,UAAU,GAAG,CAAC,CAAC,CAAC,sBAAsB,CACvF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;QACvF,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,MAAM,IAAI,kBAAkB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChG,MAAM,WAAW,GAAG,GAA6B,CAAC;QAClD,IAAI,WAAW,CAAC,QAAQ,KAAK,uBAAuB,EAAE,CAAC;YACrD,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,CACJ,IAAI,EACJ,8BAA8B,WAAW,CAAC,QAAQ,yBAAyB,uBAAuB,4GAA4G,CAC/M,CAAC;YACF,OAAO,cAAc,CAAC,yBAAyB,WAAW,CAAC,QAAQ,GAAG,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,WAAW,CAAC,OAAO,KAAK,IAAI;YACrC,KAAK,EAAE,WAAW;YAClB,KAAK;YACL,MAAM;YACN,MAAM,EAAE,IAAI;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,CACJ,IAAI,EACJ,gCAAgC,GAAG,uGAAuG,CAC3I,CAAC;QACF,OAAO,cAAc,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,MAAyB,OAAO,CAAC,GAAG;IAMhE,WAAW,KAAK,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,GAAsB;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,EAAE,GAAG,WAA0B,CAAC;QACtC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAA0B,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC;IACpE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAoBD,MAAM,UAAU,cAAc,CAAC,MAAyB,OAAO,CAAC,GAAG;IACjE,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC;IACzC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO;QACL,IAAI;QACJ,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,KAAK;QACL,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,YAAY,EAAE,KAAK;YACjB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO;gBAChC,CAAC,CAAC,uDAAuD;gBACzD,CAAC,CAAC,MAAM,CAAC,MAAM;KACpB,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACpE,OAAO,aAAa,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;AACrC,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,eAAe,CAC7B,MAA+B,EAC/B,SAAiB,EACjB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,0BAA0B,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,MAAM,CACX,SAAS,CAAC,MAAM,CAAC,OAAO,CACtB,EAAE,CAAC,EAAE,uBAAuB,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,MAAM,EAAE,EACjE,SAAS,CACV,CACF,CAAC;AACJ,CAAC;AAED,uFAAuF;AACvF,SAAS,MAAM,CAAC,GAA4B;IAC1C,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IACnC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAoD,CAAC;IAC5E,MAAM,IAAI,kBAAkB,CAC1B,GAAG,EAAE,IAAI,IAAI,UAAU,EACvB,GAAG,EAAE,OAAO,IAAI,4BAA4B,CAC7C,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,iBAAiB,CAC/B,MAA+B,EAC/B,SAAiB,EACjB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,IAAI;QAAE,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC;IAC9F,OAAO,MAAM,CACX,MAAM,CAAC,MAAM,CAAC,OAAO,CACnB,EAAE,CAAC,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,EAAE,EAC9D,SAAS,CACV,CACF,CAAC;AACJ,CAAC;AAED,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAA+B,EAC/B,SAAiB,EACjB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,IAAI;QAAE,MAAM,IAAI,kBAAkB,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC;IAC9F,OAAO,MAAM,CACX,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CACzB,EAAE,CAAC,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,MAAM,EAAE,EAC9D,SAAS,CACV,CACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC/D,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,IAAI;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7D,MAAM,EAAE,GAAG,WAA0B,CAAC;IACtC,IAAI,EAAE,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC,UAAU,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAC7D,EAAE,CAAC,UAAU,GAAG,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC;QACrB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,iBAAiB,CAAC,8CAA8C,GAAG,2BAA2B,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,EAAE,CAAC,UAAU,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAwC,EACxC,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,OAAO,EAAE,MAAM,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACnF,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface ShortcutsRunResult {
|
|
2
|
+
exitCode: number;
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
timedOut?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** `shortcuts run <name> --input-path … --output-path …` (the write vector's shape). */
|
|
8
|
+
export declare function shortcutsRunExec(name: string, inputPath: string, outputPath: string, timeoutMs: number): Promise<ShortcutsRunResult>;
|
|
9
|
+
/** `shortcuts list` (availability's proxy census). Returns stdout; throws on failure. */
|
|
10
|
+
export declare function shortcutsListSync(timeoutMs?: number): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Apple Shortcuts execution seam — the `shortcuts` CLI twin of osa.ts.
|
|
3
|
+
* Both call sites (the shortcuts write vector's `run`, availability's `list`)
|
|
4
|
+
* route through the deputy when it is active, so every app-automation surface
|
|
5
|
+
* shares the deputy's one stable identity; direct mode is byte-identical to
|
|
6
|
+
* the pre-deputy behavior. The deputy only accepts this library's bundled
|
|
7
|
+
* `things-proxy-*` shortcut names — it is a paired tool, not a general
|
|
8
|
+
* shortcut runner.
|
|
9
|
+
*/
|
|
10
|
+
import { execFile, execFileSync } from "node:child_process";
|
|
11
|
+
import {} from "./protocol.js";
|
|
12
|
+
import { deputyAsyncRequest, deputyRouting, deputySyncRequest } from "./routing.js";
|
|
13
|
+
/** Deputy-side kill fires at timeoutMs; the client deadline adds grace so the deputy's honest answer wins. */
|
|
14
|
+
const CLIENT_GRACE_MS = 5000;
|
|
15
|
+
/** `shortcuts run <name> --input-path … --output-path …` (the write vector's shape). */
|
|
16
|
+
export async function shortcutsRunExec(name, inputPath, outputPath, timeoutMs) {
|
|
17
|
+
if (deputyRouting().active) {
|
|
18
|
+
const res = (await deputyAsyncRequest({ verb: "shortcuts", op: "run", name, inputPath, outputPath, timeoutMs }, timeoutMs + CLIENT_GRACE_MS));
|
|
19
|
+
return {
|
|
20
|
+
exitCode: res.timedOut === true && res.exitCode === 0 ? 1 : res.exitCode,
|
|
21
|
+
stdout: res.stdout,
|
|
22
|
+
stderr: res.stderr,
|
|
23
|
+
...(res.timedOut === true && { timedOut: true }),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
execFile("shortcuts", ["run", name, "--input-path", inputPath, "--output-path", outputPath], { timeout: timeoutMs }, (err, stdout, stderr) => {
|
|
28
|
+
// A deadline kill (err.killed) is the signature of an unanswered
|
|
29
|
+
// first-run consent dialog — surfaced distinctly for attribution.
|
|
30
|
+
const timedOut = err !== null && err.killed === true;
|
|
31
|
+
resolve({
|
|
32
|
+
exitCode: err === null ? 0 : (err.code ?? 1),
|
|
33
|
+
stdout: String(stdout),
|
|
34
|
+
stderr: String(stderr),
|
|
35
|
+
...(timedOut && { timedOut: true }),
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/** `shortcuts list` (availability's proxy census). Returns stdout; throws on failure. */
|
|
41
|
+
export function shortcutsListSync(timeoutMs = 10_000) {
|
|
42
|
+
if (!deputyRouting().active) {
|
|
43
|
+
return execFileSync("shortcuts", ["list"], { encoding: "utf8", timeout: timeoutMs });
|
|
44
|
+
}
|
|
45
|
+
const res = deputySyncRequest({ verb: "shortcuts", op: "list", timeoutMs }, timeoutMs + CLIENT_GRACE_MS);
|
|
46
|
+
if (res.exitCode === 0 && res.timedOut !== true)
|
|
47
|
+
return res.stdout;
|
|
48
|
+
throw new Error(`Command failed: shortcuts list\n${res.stderr}`);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=shortcuts-exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortcuts-exec.js","sourceRoot":"","sources":["../../src/deputy/shortcuts-exec.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAwB,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEpF,8GAA8G;AAC9G,MAAM,eAAe,GAAG,IAAI,CAAC;AAS7B,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,SAAiB,EACjB,UAAkB,EAClB,SAAiB;IAEjB,IAAI,aAAa,EAAE,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,MAAM,kBAAkB,CACnC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,EACxE,SAAS,GAAG,eAAe,CAC5B,CAA+B,CAAC;QACjC,OAAO;YACL,QAAQ,EAAE,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ;YACxE,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;SACjD,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CACN,WAAW,EACX,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,CAAC,EACrE,EAAE,OAAO,EAAE,SAAS,EAAE,EACtB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACtB,iEAAiE;YACjE,kEAAkE;YAClE,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,IAAK,GAA4B,CAAC,MAAM,KAAK,IAAI,CAAC;YAC/E,OAAO,CAAC;gBACN,QAAQ,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,GAAyB,CAAC,IAAI,IAAI,CAAC,CAAC;gBACnE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;gBACtB,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;aACpC,CAAC,CAAC;QACL,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,iBAAiB,CAAC,SAAS,GAAG,MAAM;IAClD,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,CAAC;QAC5B,OAAO,YAAY,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,GAAG,GAAG,iBAAiB,CAC3B,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAC5C,SAAS,GAAG,eAAe,CACE,CAAC;IAChC,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC;IACnE,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AACnE,CAAC"}
|
package/dist/diagnose.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { type HelpersMode } from "./config.ts";
|
|
2
|
+
import { type HelpersStatus } from "./deputy/install.ts";
|
|
3
|
+
import { type HelpersRouting } from "./deputy/routing.ts";
|
|
1
4
|
import { type AutomationProbeDeps, type AutomationProbeStatus } from "./write/automation-probe.ts";
|
|
2
5
|
import { type AccessibilityProbeDeps, type AccessibilityProbeStatus } from "./write/accessibility-probe.ts";
|
|
3
6
|
import { type CertificationStatus } from "./write/vectors/ui-certification.ts";
|
|
@@ -5,10 +8,35 @@ import { type AvailabilityDeps, type ShortcutsState, type UrlSchemeState } from
|
|
|
5
8
|
import { type EnvironmentChange, type EnvironmentTracker, type EnvironmentTuple } from "./write/environment.ts";
|
|
6
9
|
import { type SyncHealth, type SyncHealthDeps } from "./sync-health.ts";
|
|
7
10
|
import { ExitCode, type EnvelopeMeta, type ErrorCode } from "./contracts.ts";
|
|
11
|
+
/** The helper pair's section of the report — see {@link DiagnoseReport.helpers}. */
|
|
12
|
+
export interface HelpersReport {
|
|
13
|
+
/** Configured routing mode (`helpers-enabled`): auto | true | false. */
|
|
14
|
+
mode: HelpersMode;
|
|
15
|
+
/** What that mode RESOLVED to in this process (per-half, with reasons). */
|
|
16
|
+
routing: HelpersRouting;
|
|
17
|
+
/** Installation + liveness + signing + grant, both halves. */
|
|
18
|
+
status: HelpersStatus;
|
|
19
|
+
/** The installed bundle's version, null when nothing is installed. */
|
|
20
|
+
installedVersion: string | null;
|
|
21
|
+
/** The version this package's protocol/library was built against. */
|
|
22
|
+
expectedVersion: string;
|
|
23
|
+
/** Installed but not the expected version — the remedy is a rebuild + reinstall. */
|
|
24
|
+
versionSkew: boolean;
|
|
25
|
+
/** Either half left a socket behind that no longer answers a handshake. */
|
|
26
|
+
hungSocket: boolean;
|
|
27
|
+
/** One line naming the fix, or null when there is nothing to fix. */
|
|
28
|
+
remedy: string | null;
|
|
29
|
+
detail: string;
|
|
30
|
+
}
|
|
31
|
+
/** Test seam for the helpers section (see {@link DiagnoseOptions.helpers}). */
|
|
32
|
+
export interface HelpersReportDeps {
|
|
33
|
+
status?: HelpersStatus;
|
|
34
|
+
routing?: HelpersRouting;
|
|
35
|
+
}
|
|
8
36
|
export interface DiagnoseReport {
|
|
9
37
|
db: {
|
|
10
38
|
path: string;
|
|
11
|
-
source: "option" | "env" | "container";
|
|
39
|
+
source: "option" | "env" | "container" | "deputy";
|
|
12
40
|
otherCandidates: string[];
|
|
13
41
|
databaseVersion: number | null;
|
|
14
42
|
};
|
|
@@ -128,6 +156,14 @@ export interface DiagnoseReport {
|
|
|
128
156
|
orphanedIntents: number;
|
|
129
157
|
newestOrphanIntent: string | null;
|
|
130
158
|
};
|
|
159
|
+
/**
|
|
160
|
+
* The optional helper pair (docs/design/agent-daemon.md §3b–§3c): what
|
|
161
|
+
* routing is configured to do, what it actually resolved to in THIS process,
|
|
162
|
+
* and each half's installation/liveness/signing/grant state. Prompt-free —
|
|
163
|
+
* every field comes from the same probes `things helpers status` runs, so
|
|
164
|
+
* doctor never triggers a consent dialog of its own.
|
|
165
|
+
*/
|
|
166
|
+
helpers: HelpersReport;
|
|
131
167
|
/**
|
|
132
168
|
* Freshness + sync-liveness proxies for long-running headless operation
|
|
133
169
|
* (docs/lab/headless-research.md SYNC1 + SYNC2): app-running, WAL write
|
|
@@ -158,6 +194,12 @@ export interface DiagnoseOptions {
|
|
|
158
194
|
availability?: AvailabilityDeps;
|
|
159
195
|
/** Test seams for the sync-health section (clock, process check, WAL/plist readers). */
|
|
160
196
|
syncHealth?: SyncHealthDeps;
|
|
197
|
+
/**
|
|
198
|
+
* Test seam for the helpers section. Without it the section probes the real
|
|
199
|
+
* machine (launchd, sockets, codesign) — honest for a diagnostic, useless for
|
|
200
|
+
* an assertion, since the host running the suite may have live helpers.
|
|
201
|
+
*/
|
|
202
|
+
helpers?: HelpersReportDeps;
|
|
161
203
|
/** Directory holding the audit JSONL files; defaults to the state dir. Test seam. */
|
|
162
204
|
auditDir?: string;
|
|
163
205
|
}
|
package/dist/diagnose.js
CHANGED
|
@@ -11,6 +11,10 @@ import { readAuditRecords, scanAuditIntegrity } from "./write/undo.js";
|
|
|
11
11
|
import { decodeRecurrenceRule } from "./model/recurrence.js";
|
|
12
12
|
import { BASELINES } from "./db/baselines/index.js";
|
|
13
13
|
import { openConnection, ThingsDbOpenError } from "./db/connection.js";
|
|
14
|
+
import { createDeputyDbFacade } from "./deputy/db-facade.js";
|
|
15
|
+
import { helpersStatus } from "./deputy/install.js";
|
|
16
|
+
import { EXPECTED_HELPERS_VERSION } from "./deputy/protocol.js";
|
|
17
|
+
import { deputyDbPath, deputyRoutesDb, helpersRouting, } from "./deputy/routing.js";
|
|
14
18
|
import { compareToBaseline, observeSchema } from "./db/fingerprint.js";
|
|
15
19
|
import { locateThingsDb, ThingsDbNotFoundError } from "./db/locate.js";
|
|
16
20
|
import { isThingsRunning, probeAutomation, } from "./write/automation-probe.js";
|
|
@@ -57,6 +61,52 @@ function scanRecurrenceRules(db) {
|
|
|
57
61
|
"templates are unavailable",
|
|
58
62
|
};
|
|
59
63
|
}
|
|
64
|
+
function buildHelpersReport(configMode, deps = {}) {
|
|
65
|
+
// The routing resolution carries the mode it resolved (helpersRouting reads
|
|
66
|
+
// the same config), so the section has ONE source for it.
|
|
67
|
+
const routing = deps.routing ?? helpersRouting();
|
|
68
|
+
const mode = routing.mode;
|
|
69
|
+
const status = deps.status ?? helpersStatus(configMode);
|
|
70
|
+
const installedVersion = status.installedVersion;
|
|
71
|
+
const versionSkew = installedVersion !== null && installedVersion !== EXPECTED_HELPERS_VERSION;
|
|
72
|
+
const hungSocket = status.deputy.hungSocket || status.reader.hungSocket;
|
|
73
|
+
const remedy = versionSkew
|
|
74
|
+
? "rebuild the bundle (`bash scripts/build-helpers.sh`) and rerun `things helpers install`"
|
|
75
|
+
: hungSocket
|
|
76
|
+
? "`things helpers restart` — a socket is present but no handshake comes back"
|
|
77
|
+
: !status.bundleInstalled
|
|
78
|
+
? mode === "false"
|
|
79
|
+
? null
|
|
80
|
+
: "`things helpers install` to move macOS permission grants onto the helpers"
|
|
81
|
+
: status.reader.installed && status.reader.running && !status.reader.granted
|
|
82
|
+
? "`things helpers grant` once, at the machine, to give the reader durable read access"
|
|
83
|
+
: status.bundleInstalled && !status.deputy.running
|
|
84
|
+
? "`things helpers install` (re-registers both helpers with launchd and starts them)"
|
|
85
|
+
: null;
|
|
86
|
+
const detail = mode === "false"
|
|
87
|
+
? "routing off — every primitive runs in this process (`things config set helpers-enabled auto` to use an installed helper)"
|
|
88
|
+
: routing.automation && routing.files
|
|
89
|
+
? "both halves carrying traffic"
|
|
90
|
+
: !status.bundleInstalled
|
|
91
|
+
? mode === "auto"
|
|
92
|
+
? "nothing installed — running direct, which is the normal state for a machine that has not onboarded the helpers"
|
|
93
|
+
: "routing is set to true but nothing is installed — running direct"
|
|
94
|
+
: `running direct for ${[
|
|
95
|
+
...(routing.automation ? [] : [`automation (${routing.deputyReason ?? "unknown"})`]),
|
|
96
|
+
...(routing.files ? [] : [`database reads (${routing.readerReason ?? "unknown"})`]),
|
|
97
|
+
].join(" and ")}`;
|
|
98
|
+
return {
|
|
99
|
+
mode,
|
|
100
|
+
routing,
|
|
101
|
+
status,
|
|
102
|
+
installedVersion,
|
|
103
|
+
expectedVersion: EXPECTED_HELPERS_VERSION,
|
|
104
|
+
versionSkew,
|
|
105
|
+
hungSocket,
|
|
106
|
+
remedy,
|
|
107
|
+
detail,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
60
110
|
/**
|
|
61
111
|
* Which bundled Apple Shortcuts proxies are installed — a standalone
|
|
62
112
|
* environment accessor that needs no database (the shortcuts probe is a pure
|
|
@@ -67,9 +117,17 @@ export function shortcutProxies(deps = {}) {
|
|
|
67
117
|
return readShortcutProxies(deps);
|
|
68
118
|
}
|
|
69
119
|
export function diagnose(dbPath, options = {}) {
|
|
120
|
+
// Mirror openThings: deputy-brokered database access for the default
|
|
121
|
+
// container db, local open for explicit paths (src/deputy/routing.ts).
|
|
122
|
+
const routedDbPath = deputyRoutesDb(dbPath !== undefined ? { dbPath } : undefined)
|
|
123
|
+
? deputyDbPath()
|
|
124
|
+
: null;
|
|
70
125
|
let located;
|
|
71
126
|
try {
|
|
72
|
-
located =
|
|
127
|
+
located =
|
|
128
|
+
routedDbPath !== null
|
|
129
|
+
? { path: routedDbPath, source: "deputy", otherCandidates: [] }
|
|
130
|
+
: locateThingsDb(dbPath ? { dbPath } : undefined);
|
|
73
131
|
}
|
|
74
132
|
catch (err) {
|
|
75
133
|
if (err instanceof ThingsDbNotFoundError) {
|
|
@@ -88,7 +146,10 @@ export function diagnose(dbPath, options = {}) {
|
|
|
88
146
|
}
|
|
89
147
|
let conn;
|
|
90
148
|
try {
|
|
91
|
-
conn =
|
|
149
|
+
conn =
|
|
150
|
+
routedDbPath !== null
|
|
151
|
+
? { db: createDeputyDbFacade(), path: routedDbPath, close() { } }
|
|
152
|
+
: openConnection(located.path);
|
|
92
153
|
}
|
|
93
154
|
catch (err) {
|
|
94
155
|
if (err instanceof ThingsDbOpenError) {
|
|
@@ -237,6 +298,7 @@ export function diagnose(dbPath, options = {}) {
|
|
|
237
298
|
shortcuts: readShortcutProxies(options.availability),
|
|
238
299
|
},
|
|
239
300
|
recurrence: scanRecurrenceRules(conn.db),
|
|
301
|
+
helpers: buildHelpersReport(config.helpersMode, options.helpers),
|
|
240
302
|
syncHealth: computeSyncHealth(conn.db, located.path, options.syncHealth),
|
|
241
303
|
audit: scanAuditIntegrity(readAuditRecords(options.auditDir ?? auditDir())),
|
|
242
304
|
};
|
package/dist/diagnose.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"diagnose.js","sourceRoot":"","sources":["../src/diagnose.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAoB,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAsB,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,GAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EACL,eAAe,EACf,eAAe,GAGhB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,kBAAkB,GAGnB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GAEzB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GAIrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,wBAAwB,EACxB,eAAe,GAIhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAwC,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAqC,MAAM,gBAAgB,CAAC;AAE1F,MAAM,UAAU,GAAG,2BAA2B,CAAC;AAE/C,uEAAuE;AACvE,SAAS,mBAAmB,CAAC,EAE5B;IACC,IAAI,IAA4C,CAAC;IACjD,IAAI,CAAC;QACH,IAAI,GAAG,EAAE;aACN,OAAO,CACN,0FAA0F,CAC3F;aACA,GAAG,EAA4C,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,EAAE,gCAAgC,EAAE,CAAC;IACpF,CAAC;IACD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,IAAI,CAAC,CAAC;YACjB,IAAI,UAAU,KAAK,EAAE;gBAAE,UAAU,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;IACD,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,MAAM;QACtB,WAAW;QACX,MAAM,EACJ,WAAW,KAAK,CAAC;YACf,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;gBACjB,CAAC,CAAC,wBAAwB;gBAC1B,CAAC,CAAC,yCAAyC;YAC7C,CAAC,CAAC,GAAG,WAAW,qCAAqC,UAAU,sBAAsB;gBACnF,4EAA4E;gBAC5E,2BAA2B;KAClC,CAAC;AACJ,CAAC;AA6BD,SAAS,kBAAkB,CAAC,UAAuB,EAAE,OAA0B,EAAE;IAC/E,4EAA4E;IAC5E,0DAA0D;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,cAAc,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;IACjD,MAAM,WAAW,GAAG,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,wBAAwB,CAAC;IAC/F,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;IACxE,MAAM,MAAM,GAAG,WAAW;QACxB,CAAC,CAAC,yFAAyF;QAC3F,CAAC,CAAC,UAAU;YACV,CAAC,CAAC,4EAA4E;YAC9E,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe;gBACvB,CAAC,CAAC,IAAI,KAAK,OAAO;oBAChB,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,2EAA2E;gBAC/E,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO;oBAC1E,CAAC,CAAC,qFAAqF;oBACvF,CAAC,CAAC,MAAM,CAAC,eAAe,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO;wBAChD,CAAC,CAAC,mFAAmF;wBACrF,CAAC,CAAC,IAAI,CAAC;IACjB,MAAM,MAAM,GACV,IAAI,KAAK,OAAO;QACd,CAAC,CAAC,0HAA0H;QAC5H,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,KAAK;YACnC,CAAC,CAAC,8BAA8B;YAChC,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe;gBACvB,CAAC,CAAC,IAAI,KAAK,MAAM;oBACf,CAAC,CAAC,gHAAgH;oBAClH,CAAC,CAAC,kEAAkE;gBACtE,CAAC,CAAC,sBAAsB;oBACpB,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,OAAO,CAAC,YAAY,IAAI,SAAS,GAAG,CAAC,CAAC;oBACpF,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,mBAAmB,OAAO,CAAC,YAAY,IAAI,SAAS,GAAG,CAAC,CAAC;iBACpF,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5B,OAAO;QACL,IAAI;QACJ,OAAO;QACP,MAAM;QACN,gBAAgB;QAChB,eAAe,EAAE,wBAAwB;QACzC,WAAW;QACX,UAAU;QACV,MAAM;QACN,MAAM;KACP,CAAC;AACJ,CAAC;AA8KD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,OAAyB,EAAE;IACzD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAe,EAAE,UAA2B,EAAE;IACrE,qEAAqE;IACrE,uEAAuE;IACvE,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAChF,CAAC,CAAC,YAAY,EAAE;QAChB,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,OAA0C,CAAC;IAC/C,IAAI,CAAC;QACH,OAAO;YACL,YAAY,KAAK,IAAI;gBACnB,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,EAAE,EAAE;gBAC/D,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;YACzC,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE;oBACL,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,WAAW,EAAE,wDAAwD;iBACtE;gBACD,QAAQ,EAAE,QAAQ,CAAC,WAAW;gBAC9B,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE;aAClD,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,IAAuC,CAAC;IAC5C,IAAI,CAAC;QACH,IAAI;YACF,YAAY,KAAK,IAAI;gBACnB,CAAC,CAAC,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,KAAI,CAAC,EAAE;gBAChE,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,iBAAiB,EAAE,CAAC;YACrC,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE;oBACL,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,WAAW,EAAE,2DAA2D;iBACzE;gBACD,QAAQ,EAAE,QAAQ,CAAC,WAAW;gBAC9B,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE;aAClD,CAAC;QACJ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACzD,uEAAuE;QACvE,oEAAoE;QACpE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,QAAQ,GACZ,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,mBAAmB,KAAK,WAAW,CAAC,WAAW,CAAC;QACpF,MAAM,iBAAiB,GAAG,QAAQ;YAChC,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI;gBACpB,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO;oBACvB,CAAC,CAAC,OAAO;oBACT,CAAC,CAAC,iBAAiB,CAAC;QAC1B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;QACvD,MAAM,UAAU,GAAG,0BAA0B,EAAE,CAAC;QAChD,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,wBAAwB,CAAC,WAAW,CAAC,CAAC;QAC7E,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,YAAY,GAA6B,EAAE,CAAC;QAClD,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;gBAAE,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;QACxE,CAAC;QACD,4EAA4E;QAC5E,4EAA4E;QAC5E,4EAA4E;QAC5E,MAAM,WAAW,GAA4B,CAAC,GAAG,EAAE;YACjD,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;gBACzB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;YAC/E,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACvE,OAAO;oBACL,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG;oBAC3B,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;oBAC3B,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE;oBACxD,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,cAAc,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG;iBAC5E,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;oBACL,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG;oBAC3B,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;oBAC3B,QAAQ,EAAE,IAAI;oBACd,MAAM,EACJ,UAAU,MAAM,CAAC,KAAK,CAAC,GAAG,cAAc,MAAM,CAAC,KAAK,CAAC,MAAM,mBAAmB;wBAC9E,sFAAsF;iBACzF,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,MAAM,MAAM,GAAmB;YAC7B,EAAE,EAAE;gBACF,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,eAAe,EAAE,OAAO,CAAC,eAAe;gBACxC,eAAe,EAAE,WAAW,CAAC,eAAe;aAC7C;YACD,WAAW,EAAE;gBACX,MAAM,EAAE,iBAAiB;gBACzB,KAAK,EAAE,WAAW,CAAC,WAAW;gBAC9B,QAAQ,EAAE,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;gBAC1D,MAAM,EAAE,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBACpD,YAAY;aACb;YACD,GAAG,EAAE;gBACH,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC;gBACjC,OAAO,EAAE,UAAU,CAAC,aAAa;gBACjC,gBAAgB,EAAE,MAAM,CAAC,mBAAmB;gBAC5C,eAAe,EACb,UAAU,CAAC,aAAa,KAAK,IAAI;oBACjC,MAAM,CAAC,mBAAmB,KAAK,IAAI;oBACnC,UAAU,CAAC,aAAa,KAAK,MAAM,CAAC,mBAAmB;aAC1D;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,aAAa;gBACtB,MAAM,EAAE,QAAQ;oBACd,CAAC,CAAC,8EAA8E;wBAC9E,gFAAgF;oBAClF,CAAC,CAAC,aAAa;wBACb,CAAC,CAAC,6CAA6C;wBAC/C,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO;4BACvB,CAAC,CAAC,+EAA+E;4BACjF,CAAC,CAAC,2DAA2D;aACpE;YACD,KAAK,EAAE,WAAW;YAClB,YAAY,EAAE;gBACZ,OAAO,EAAE,MAAM,CAAC,iBAAiB;gBACjC,mBAAmB,EAAE,UAAU;gBAC/B,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB;oBAC/B,CAAC,CAAC,uFAAuF;oBACzF,CAAC,CAAC,UAAU;wBACV,CAAC,CAAC,6DAA6D;wBAC/D,CAAC,CAAC,iFAAiF;4BACjF,uDAAuD;aAC9D;YACD,WAAW,EAAE;gBACX,OAAO,EAAE,UAAU;gBACnB,iBAAiB,EAAE,WAAW;gBAC9B,OAAO,EAAE,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC;aAClD;YACD,UAAU,EACR,OAAO,CAAC,eAAe,KAAK,IAAI;gBAC9B,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC;gBACpC,CAAC,CAAC;oBACE,MAAM,EAAE,YAAY;oBACpB,MAAM,EACJ,2EAA2E;wBAC3E,mEAAmE;iBACtE;YACP,EAAE,EAAE;gBACF,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO;gBAC1B,UAAU,EAAE,eAAe,EAAE;gBAC7B,aAAa,EACX,OAAO,CAAC,kBAAkB,KAAK,IAAI;oBACjC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,sBAAsB,CAAC;oBACpD,CAAC,CAAC;wBACE,MAAM,EAAE,YAAY;wBACpB,MAAM,EACJ,gFAAgF;4BAChF,+EAA+E;qBAClF;gBACP,oBAAoB,EAAE,wBAAwB;gBAC9C,aAAa,EAAE,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;oBACzD,EAAE;oBACF,MAAM,EAAE,KAAK,CAAC,MAAM;iBACrB,CAAC,CAAC;gBACH,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO;oBACvB,CAAC,CAAC,qFAAqF;wBACrF,uEAAuE;oBACzE,CAAC,CAAC,mFAAmF;wBACnF,4DAA4D;aACjE;YACD,YAAY,EAAE;gBACZ,SAAS,EAAE,oBAAoB,CAAC,OAAO,CAAC,YAAY,CAAC;gBACrD,SAAS,EAAE,mBAAmB,CAAC,OAAO,CAAC,YAAY,CAAC;aACrD;YACD,UAAU,EAAE,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC;YAChE,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC;YACxE,KAAK,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC;SAC5E,CAAC;QACF,OAAO;YACL,MAAM;YACN,KAAK,EAAE,IAAI;YACX,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY;YAC7D,IAAI,EAAE;gBACJ,SAAS,EAAE,WAAW,CAAC,eAAe;gBACtC,WAAW,EAAE,iBAAiB,KAAK,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB;aACrF;SACF,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;AACH,CAAC"}
|