things-api 0.18.0 → 0.19.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 -9
- package/deputy/AppIcon.icns +0 -0
- package/deputy/VERSION +1 -1
- package/deputy/helpers-Info.plist +4 -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 +3 -1
- 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/Resources/AppIcon.icns +0 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/Helpers/things-reader.app/Contents/_CodeSignature/CodeResources +15 -2
- package/deputy/prebuilt/Things API Helper.app/Contents/Info.plist +5 -1
- package/deputy/prebuilt/Things API Helper.app/Contents/MacOS/things-deputy +0 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/Resources/AppIcon.icns +0 -0
- package/deputy/prebuilt/Things API Helper.app/Contents/_CodeSignature/CodeResources +14 -2
- package/deputy/reader/Info.plist +2 -0
- package/deputy/reader/entitlements.plist +30 -0
- package/deputy/reader/main.swift +129 -40
- package/deputy/src/server.swift +25 -2
- package/deputy/src/tcc.swift +58 -0
- package/dist/audit/schema.d.ts +13 -1
- package/dist/audit/schema.js.map +1 -1
- package/dist/capability.d.ts +160 -0
- package/dist/capability.js +416 -0
- package/dist/capability.js.map +1 -0
- package/dist/cli/commands/doctor.js +127 -1
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/helpers.js +178 -51
- package/dist/cli/commands/helpers.js.map +1 -1
- package/dist/cli/commands/op-result.js +6 -0
- package/dist/cli/commands/op-result.js.map +1 -1
- package/dist/cli/commands/reads.js +47 -1
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/setup.d.ts +9 -0
- package/dist/cli/commands/setup.js +63 -83
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/writes.d.ts +1 -1
- package/dist/cli/commands/writes.js +241 -107
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/dry-run.d.ts +1 -1
- package/dist/cli/dry-run.js +1 -1
- package/dist/cli/glyphs.d.ts +23 -4
- package/dist/cli/glyphs.js +46 -19
- package/dist/cli/glyphs.js.map +1 -1
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +49 -27
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/period.d.ts +3 -1
- package/dist/cli/period.js +1 -1
- package/dist/cli/period.js.map +1 -1
- package/dist/cli/read-driver.js +26 -1
- package/dist/cli/read-driver.js.map +1 -1
- package/dist/cli/render.d.ts +31 -4
- package/dist/cli/render.js +127 -15
- package/dist/cli/render.js.map +1 -1
- package/dist/client.d.ts +22 -2
- package/dist/client.js +36 -13
- package/dist/client.js.map +1 -1
- package/dist/contracts.d.ts +6 -2
- package/dist/contracts.js +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deputy/install.d.ts +219 -5
- package/dist/deputy/install.js +803 -31
- package/dist/deputy/install.js.map +1 -1
- package/dist/deputy/notices.js +2 -2
- package/dist/deputy/notices.js.map +1 -1
- package/dist/deputy/protocol.d.ts +59 -5
- package/dist/deputy/protocol.js +48 -11
- package/dist/deputy/protocol.js.map +1 -1
- package/dist/deputy/routing.d.ts +21 -0
- package/dist/deputy/routing.js +111 -27
- package/dist/deputy/routing.js.map +1 -1
- package/dist/diagnose.d.ts +14 -1
- package/dist/diagnose.js +46 -6
- package/dist/diagnose.js.map +1 -1
- package/dist/direct-setup.d.ts +78 -0
- package/dist/direct-setup.js +484 -0
- package/dist/direct-setup.js.map +1 -0
- package/dist/host-access.d.ts +63 -0
- package/dist/host-access.js +165 -0
- package/dist/host-access.js.map +1 -0
- package/dist/index.d.ts +20 -5
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +27 -1
- package/dist/mcp/server.js +285 -100
- package/dist/mcp/server.js.map +1 -1
- package/dist/op-result.d.ts +9 -0
- package/dist/op-result.js +5 -0
- package/dist/op-result.js.map +1 -1
- package/dist/read/filter-contract.d.ts +1 -1
- package/dist/read/filter-contract.js +4 -0
- package/dist/read/filter-contract.js.map +1 -1
- package/dist/read/shape.js +4 -0
- package/dist/read/shape.js.map +1 -1
- package/dist/read/views.d.ts +29 -0
- package/dist/read/views.js +60 -0
- package/dist/read/views.js.map +1 -1
- package/dist/session-grant.d.ts +48 -0
- package/dist/session-grant.js +170 -0
- package/dist/session-grant.js.map +1 -0
- package/dist/surface-copy.d.ts +8 -0
- package/dist/surface-copy.js +8 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/wizard.d.ts +58 -0
- package/dist/wizard.js +167 -0
- package/dist/wizard.js.map +1 -0
- package/dist/write/availability.d.ts +1 -1
- package/dist/write/availability.js +3 -3
- package/dist/write/availability.js.map +1 -1
- package/dist/write/batch.d.ts +20 -0
- package/dist/write/batch.js +94 -15
- package/dist/write/batch.js.map +1 -1
- package/dist/write/capabilities.d.ts +9 -0
- package/dist/write/capabilities.js +2 -0
- package/dist/write/capabilities.js.map +1 -1
- package/dist/write/clear-reminder.js +1 -1
- package/dist/write/clear-reminder.js.map +1 -1
- package/dist/write/commands.d.ts +12 -1
- package/dist/write/commands.js +112 -224
- package/dist/write/commands.js.map +1 -1
- package/dist/write/failure-hints.d.ts +3 -1
- package/dist/write/failure-hints.js.map +1 -1
- package/dist/write/guards.js +19 -2
- package/dist/write/guards.js.map +1 -1
- package/dist/write/lock.d.ts +16 -13
- package/dist/write/lock.js +55 -0
- package/dist/write/lock.js.map +1 -1
- package/dist/write/make-repeating-project.js +9 -13
- package/dist/write/make-repeating-project.js.map +1 -1
- package/dist/write/operations.d.ts +36 -21
- package/dist/write/operations.js +7 -0
- package/dist/write/operations.js.map +1 -1
- package/dist/write/opid.d.ts +14 -0
- package/dist/write/opid.js +22 -0
- package/dist/write/opid.js.map +1 -1
- package/dist/write/param-schema.d.ts +124 -0
- package/dist/write/param-schema.js +747 -0
- package/dist/write/param-schema.js.map +1 -0
- package/dist/write/pipeline.d.ts +76 -2
- package/dist/write/pipeline.js +190 -2
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/pre-state.d.ts +8 -0
- package/dist/write/pre-state.js +29 -2
- package/dist/write/pre-state.js.map +1 -1
- package/dist/write/promote-clone.js +539 -439
- package/dist/write/promote-clone.js.map +1 -1
- package/dist/write/reorder.js +25 -8
- package/dist/write/reorder.js.map +1 -1
- package/dist/write/repeat-rule.d.ts +28 -1
- package/dist/write/repeat-rule.js +54 -4
- package/dist/write/repeat-rule.js.map +1 -1
- package/dist/write/resolution-timestamps.d.ts +11 -0
- package/dist/write/resolution-timestamps.js +83 -38
- package/dist/write/resolution-timestamps.js.map +1 -1
- package/dist/write/reversibility.js +4 -0
- package/dist/write/reversibility.js.map +1 -1
- package/dist/write/template-mutation.d.ts +137 -0
- package/dist/write/template-mutation.js +451 -0
- package/dist/write/template-mutation.js.map +1 -0
- package/dist/write/undo.js +10 -20
- package/dist/write/undo.js.map +1 -1
- package/dist/write/update-fields.d.ts +151 -0
- package/dist/write/update-fields.js +427 -0
- package/dist/write/update-fields.js.map +1 -0
- package/dist/write/vectors/applescript.js +3 -0
- package/dist/write/vectors/applescript.js.map +1 -1
- package/dist/write/vectors/registry.d.ts +1 -1
- package/dist/write/vectors/registry.js +10 -2
- package/dist/write/vectors/registry.js.map +1 -1
- package/dist/write/vectors/shortcuts.js +2 -2
- package/dist/write/vectors/shortcuts.js.map +1 -1
- package/dist/write/vectors/simulator.js +7 -2
- package/dist/write/vectors/simulator.js.map +1 -1
- package/dist/write/vectors/types.d.ts +57 -0
- package/dist/write/vectors/ui-recipes.d.ts +19 -0
- package/dist/write/vectors/ui-recipes.js +30 -0
- package/dist/write/vectors/ui-recipes.js.map +1 -1
- package/dist/write/vectors/ui.d.ts +13 -0
- package/dist/write/vectors/ui.js +62 -13
- package/dist/write/vectors/ui.js.map +1 -1
- package/dist/write/verify/delta.d.ts +21 -0
- package/dist/write/verify/delta.js.map +1 -1
- package/package.json +2 -1
- package/schema/envelope.schema.json +5 -3
- package/scripts/build-helpers.sh +5 -0
- package/skills/things-cli/SKILL.md +5 -3
- package/skills/things-cli/references/contracts.md +1 -0
- package/skills/things-cli/references/data-model.md +3 -0
- package/skills/things-cli/references/errors.md +1 -1
- package/skills/things-cli/references/gui.md +1 -0
- package/skills/things-cli/references/repeating.md +6 -0
- package/skills/things-cli/references/tag-cleanup.md +64 -0
package/dist/audit/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/audit/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/audit/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA8EzC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,SAAS,CACvB,MAA0E;IAE1E,IAAI,MAAM,CAAC,GAAG,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACzD,yEAAyE;IACzE,wEAAwE;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,IAAI,IAAI,EAAE;KAClB,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChF,OAAO,KAAK,MAAM,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { type HostAccessDeps, type HostApp } from "./host-access.ts";
|
|
2
|
+
export { fdaGranted, type FdaVerdict, type HostApp, hostApp, hostDisplayName, tccDbPath, } from "./host-access.ts";
|
|
3
|
+
/** The Things application's bundle identifier — the Automation grant's target. */
|
|
4
|
+
export declare const THINGS_BUNDLE_ID = "com.culturedcode.ThingsMac";
|
|
5
|
+
/** How reads may reach the live library, if at all. */
|
|
6
|
+
export type ReadCapabilityMode =
|
|
7
|
+
/** A caller-supplied database path — outside the doctrine entirely (Article VI). */
|
|
8
|
+
"explicit-db"
|
|
9
|
+
/** Reads ride the sandboxed reader; the read itself is the capability check. */
|
|
10
|
+
| "helpers"
|
|
11
|
+
/** The helpers are expected here but cannot serve — refuse, never fall back. */
|
|
12
|
+
| "helpers-unavailable"
|
|
13
|
+
/** No helpers, but the host app holds Full Disk Access. */
|
|
14
|
+
| "direct-fda"
|
|
15
|
+
/** A ceremony witnessed an app-data grant that is still live for this app instance. */
|
|
16
|
+
| "session-grant"
|
|
17
|
+
/** Nothing can open the container — the caller must run a setup ceremony. */
|
|
18
|
+
| "none";
|
|
19
|
+
/** How GUI-driving may be delivered, if at all (Article IV). */
|
|
20
|
+
export type UiCapabilityMode =
|
|
21
|
+
/** The helper pair holds Accessibility + Automation→System Events. */
|
|
22
|
+
"helpers"
|
|
23
|
+
/** The lab's documented in-guest escape (see {@link UI_DIRECT_ESCAPE_ENV}). */
|
|
24
|
+
| "direct-escape"
|
|
25
|
+
/** GUI-driving is switched off in config — nothing has been asked for yet. */
|
|
26
|
+
| "config-disabled"
|
|
27
|
+
/** No deputy answers, so there is no identity that could hold the grants. */
|
|
28
|
+
| "helpers-missing"
|
|
29
|
+
/** The deputy answers but the `--gui` tier is incomplete. */
|
|
30
|
+
| "tier-incomplete";
|
|
31
|
+
/** How app automation may be delivered, if at all. */
|
|
32
|
+
export type WriteCapabilityMode =
|
|
33
|
+
/** The deputy is onboarded; Apple Events are sent under the helper identity. */
|
|
34
|
+
"deputy"
|
|
35
|
+
/** macOS records an Automation grant for the host app against Things. */
|
|
36
|
+
| "direct-granted"
|
|
37
|
+
/** macOS records a REFUSAL. It will not re-ask; the human must re-arm it. */
|
|
38
|
+
| "direct-denied"
|
|
39
|
+
/** No record either way, or none readable — never resolved by prompting. */
|
|
40
|
+
| "direct-unknown";
|
|
41
|
+
export interface Capability<Mode> {
|
|
42
|
+
mode: Mode;
|
|
43
|
+
/** One sentence of provenance, for `doctor` and for refusal copy. */
|
|
44
|
+
detail: string;
|
|
45
|
+
/**
|
|
46
|
+
* The remediation lines a refusal prints, in the order they should be
|
|
47
|
+
* offered. Empty when the capability is present.
|
|
48
|
+
*/
|
|
49
|
+
remediation: string[];
|
|
50
|
+
/** The identity a direct-mode grant would attach to. */
|
|
51
|
+
host: HostApp;
|
|
52
|
+
}
|
|
53
|
+
export type ReadCapability = Capability<ReadCapabilityMode>;
|
|
54
|
+
export type WriteCapability = Capability<WriteCapabilityMode>;
|
|
55
|
+
export type UiCapability = Capability<UiCapabilityMode>;
|
|
56
|
+
/** True when this verdict permits opening the live container. */
|
|
57
|
+
export declare function readAllowed(capability: ReadCapability): boolean;
|
|
58
|
+
/** True when this verdict permits driving the Things window. */
|
|
59
|
+
export declare function uiAllowed(capability: UiCapability): boolean;
|
|
60
|
+
/** True when app automation may be dispatched. */
|
|
61
|
+
export declare function writeAllowed(capability: WriteCapability): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Injection seams. Every one of these defaults to a real, prompt-free probe;
|
|
64
|
+
* tests replace them so no test ever touches the host's TCC state.
|
|
65
|
+
*/
|
|
66
|
+
export interface CapabilityDeps extends HostAccessDeps {
|
|
67
|
+
/** Are this process's database reads actually being served by the reader? */
|
|
68
|
+
helpersServing?: () => boolean;
|
|
69
|
+
/** Are the helpers expected on this machine (enabled, and installed under auto)? */
|
|
70
|
+
helpersExpected?: () => boolean;
|
|
71
|
+
/** Why the helpers are not serving, for the loud refusal. */
|
|
72
|
+
helpersReason?: () => string | null;
|
|
73
|
+
/** The deputy's `automation.things` standing, from its handshake. */
|
|
74
|
+
deputyAutomation?: () => string | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* The deputy's GUI-driving standing, from the same handshake: whether it is
|
|
77
|
+
* Accessibility-trusted and where its Automation→System Events grant stands.
|
|
78
|
+
* `null` means no deputy answered at all.
|
|
79
|
+
*/
|
|
80
|
+
deputyGuiStanding?: () => {
|
|
81
|
+
axTrusted: boolean | undefined;
|
|
82
|
+
systemEvents: string | undefined;
|
|
83
|
+
} | null;
|
|
84
|
+
/** Is GUI-driving switched on in config (`ui-enabled`)? */
|
|
85
|
+
uiEnabled?: () => boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Read one Automation row out of TCC.db. Returns the raw `auth_value`, or
|
|
88
|
+
* null when there is no row / the file cannot be read.
|
|
89
|
+
*/
|
|
90
|
+
automationAuthValue?: (client: string, target: string) => number | null;
|
|
91
|
+
/** Resolve a running app's display name from its bundle id (LaunchServices). */
|
|
92
|
+
lookupAppName?: (bundleId: string) => string | null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Can this process read the live Things library, and on whose authority?
|
|
96
|
+
*
|
|
97
|
+
* Stateless: every call re-derives the verdict, because a grant can appear or
|
|
98
|
+
* vanish between one invocation and the next and a cached "yes" would be a
|
|
99
|
+
* stored onboarding flag by another name. The common case costs one `open(2)`.
|
|
100
|
+
*/
|
|
101
|
+
export declare function readCapability(options?: {
|
|
102
|
+
dbPath?: string;
|
|
103
|
+
}, deps?: CapabilityDeps): ReadCapability;
|
|
104
|
+
/** Thrown when a read is refused for want of capability (Article II). */
|
|
105
|
+
export declare class ReadCapabilityError extends Error {
|
|
106
|
+
readonly remediation: string[];
|
|
107
|
+
readonly capability: ReadCapability;
|
|
108
|
+
constructor(capability: ReadCapability);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* May this process drive Things over Apple Events, and on whose authority?
|
|
112
|
+
*
|
|
113
|
+
* The deputy wins when it is onboarded (its own handshake reports the grant it
|
|
114
|
+
* holds). Otherwise the host app's own Automation record is read out of TCC —
|
|
115
|
+
* granted, denied, or, when there is no record at all, `direct-unknown`. That
|
|
116
|
+
* last state is deliberately NOT resolved here: resolving it means sending a
|
|
117
|
+
* real Apple Event, which is what raises the dialog, and Article I reserves
|
|
118
|
+
* that for `things setup`.
|
|
119
|
+
*/
|
|
120
|
+
export declare function writeCapability(deps?: CapabilityDeps): WriteCapability;
|
|
121
|
+
/** Thrown when app automation is refused for want of capability (Article II). */
|
|
122
|
+
export declare class WriteCapabilityError extends Error {
|
|
123
|
+
readonly remediation: string[];
|
|
124
|
+
readonly capability: WriteCapability;
|
|
125
|
+
constructor(capability: WriteCapability);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The LAB's escape hatch, and deliberately not consumer surface. The VM lab and
|
|
129
|
+
* the guest e2e bundle drive the UI vector DIRECT — the in-guest Accessibility
|
|
130
|
+
* grant is held by the runner's own processes (the AXVM1 layer), there is no
|
|
131
|
+
* helper bundle in a disposable clone, and there is nobody to answer a dialog
|
|
132
|
+
* either. Setting this to `1` restores direct UI-vector availability for that
|
|
133
|
+
* one situation. It is documented in docs/lab/harness.md and exported by the
|
|
134
|
+
* lab's guest environment; nothing consumer-facing mentions it, and it does not
|
|
135
|
+
* bypass `ui.enabled` — a lab clone still sets that key explicitly.
|
|
136
|
+
*/
|
|
137
|
+
export declare const UI_DIRECT_ESCAPE_ENV = "THINGS_API_UI_DIRECT";
|
|
138
|
+
/**
|
|
139
|
+
* May this process drive the Things WINDOW, and on whose authority?
|
|
140
|
+
*
|
|
141
|
+
* Article IV admits exactly one provenance: the helper pair. Accessibility on a
|
|
142
|
+
* general-purpose host app (a terminal, an agent harness, an MCP host) has a
|
|
143
|
+
* blast radius far beyond Things, churns with every host update, and has no
|
|
144
|
+
* sane story at all over ssh — so direct AX is unsupported, and a refusal here
|
|
145
|
+
* names the config knob and `things helpers setup --gui` rather than raising an
|
|
146
|
+
* Accessibility prompt against whatever happens to be running us.
|
|
147
|
+
*
|
|
148
|
+
* Every answer is prompt-free: the config key is a file read, and the deputy's
|
|
149
|
+
* `hello` carries `AXIsProcessTrusted()` plus its own `AEDeterminePermission`
|
|
150
|
+
* verdict for System Events.
|
|
151
|
+
*/
|
|
152
|
+
export declare function uiCapability(deps?: CapabilityDeps): UiCapability;
|
|
153
|
+
/** Thrown when GUI-driving is refused for want of capability (Article IV). */
|
|
154
|
+
export declare class UiCapabilityError extends Error {
|
|
155
|
+
readonly remediation: string[];
|
|
156
|
+
readonly capability: UiCapability;
|
|
157
|
+
constructor(capability: UiCapability);
|
|
158
|
+
}
|
|
159
|
+
/** Test seam: forget the one memo this module keeps (the host's display name). */
|
|
160
|
+
export declare function resetCapabilityForTests(): void;
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt-free capability detection (docs/design/permissions-doctrine.md,
|
|
3
|
+
* Articles I–III).
|
|
4
|
+
*
|
|
5
|
+
* Every entry point must know what it is allowed to do BEFORE it touches the
|
|
6
|
+
* live library, and it must find out without putting a macOS consent dialog on
|
|
7
|
+
* screen. This module is the single place that answers that question, so the
|
|
8
|
+
* read gate, the write gate, `things doctor`, and the `things setup` ceremony
|
|
9
|
+
* all quote the same verdict.
|
|
10
|
+
*
|
|
11
|
+
* Read capability is GROUND TRUTH per invocation, never a stored flag. Nothing
|
|
12
|
+
* here is memoized across calls and nothing is persisted except the one marker
|
|
13
|
+
* that records a live-instance fact (./session-grant.ts). The whole preflight
|
|
14
|
+
* is a single `open(2)` in the common case.
|
|
15
|
+
*
|
|
16
|
+
* The paths, in the order they are consulted:
|
|
17
|
+
*
|
|
18
|
+
* 1. an explicit database path — outside the doctrine entirely (Article VI);
|
|
19
|
+
* 2. the helpers — when the reader is serving this process's reads, the READ
|
|
20
|
+
* ITSELF is the check. The reader resolves its security-scoped bookmark on
|
|
21
|
+
* every verb and answers `not-granted` / `not-found` as typed errors, so
|
|
22
|
+
* there is nothing to pre-probe and no hello round-trip is added here. When
|
|
23
|
+
* the helpers are expected but cannot serve, the read FAILS LOUDLY — a
|
|
24
|
+
* silent fall-through to direct would move consent back onto the terminal,
|
|
25
|
+
* which is the exact churn the helpers exist to end;
|
|
26
|
+
* 3. Full Disk Access — one read-open of the user TCC database. FDA-class
|
|
27
|
+
* files never raise a dialog: the open either works or fails with a silent
|
|
28
|
+
* EPERM;
|
|
29
|
+
* 4. a witnessed session app-data grant — see ./session-grant.ts;
|
|
30
|
+
* 5. otherwise: refuse, naming both setup ceremonies.
|
|
31
|
+
*
|
|
32
|
+
* Step 2 asks nothing of this host's grants. Since helpers 1.3.0 the reader's
|
|
33
|
+
* socket and token live in `<state>/reader` — launchd owns the socket, install
|
|
34
|
+
* mints the token, and both are ordinary files this user owns — so "is the
|
|
35
|
+
* reader serving?" is answerable identically from every host app, with no
|
|
36
|
+
* consent class in play. (Before 1.3.0 they sat in the reader's App Sandbox
|
|
37
|
+
* container and that question was itself a cross-app container access.)
|
|
38
|
+
*
|
|
39
|
+
* The Things group container is NEVER opened as a probe (Article I corollary):
|
|
40
|
+
* the open is itself what raises the app-data consent, so "try it and see" is
|
|
41
|
+
* forbidden — except inside `things setup`, which provokes it deliberately.
|
|
42
|
+
*
|
|
43
|
+
* On the direct WRITE probe — why TCC introspection and not the AppleEvents
|
|
44
|
+
* API. The doctrine names `AEDeterminePermissionToAutomateTarget(askUserIfNeeded:
|
|
45
|
+
* false)` as the direct-path Automation probe, which is exactly what the deputy
|
|
46
|
+
* calls (deputy/src/tcc.swift). From a JXA/ObjC host that call is NOT reachable:
|
|
47
|
+
* JavaScriptCore's bridge cannot marshal an `AEDesc` struct. MEASURED 2026-08-24
|
|
48
|
+
* on macOS 24.6 — `AECreateDesc` fills an untyped `Ref()`, but passing that Ref
|
|
49
|
+
* to any function taking `^{AEDesc=…}` throws "Ref has incompatible type", and
|
|
50
|
+
* the one spelling the bridge accepts (`ref[0]`, a dereferenced copy) arrives
|
|
51
|
+
* zeroed: `AEGetDescDataSize` reports 0 bytes for a 36-byte bundle id, and every
|
|
52
|
+
* target then answers -50 paramErr. A probe that returns the same wrong answer
|
|
53
|
+
* for every input is worse than no probe, so it is not shipped. Reading the
|
|
54
|
+
* Automation row out of TCC.db is the other introspection the Article I
|
|
55
|
+
* corollary names, it is exactly as prompt-free, and it costs nothing extra:
|
|
56
|
+
* direct mode's floor is FDA anyway, so a process that can act at all can
|
|
57
|
+
* already read that file. Where the row cannot be read the verdict is an honest
|
|
58
|
+
* "unknown", which the write gate refuses on rather than resolving with a dialog.
|
|
59
|
+
*/
|
|
60
|
+
import { DatabaseSync } from "node:sqlite";
|
|
61
|
+
import { loadConfig } from "./config.js";
|
|
62
|
+
import { deputyRouting, deputyRoutesDb, helpersExpected } from "./deputy/routing.js";
|
|
63
|
+
import { fdaGranted, hostApp, hostDisplayName, resetHostAccessForTests, tccDbPath, } from "./host-access.js";
|
|
64
|
+
import { sessionGrantValid } from "./session-grant.js";
|
|
65
|
+
export { fdaGranted, hostApp, hostDisplayName, tccDbPath, } from "./host-access.js";
|
|
66
|
+
/** The Things application's bundle identifier — the Automation grant's target. */
|
|
67
|
+
export const THINGS_BUNDLE_ID = "com.culturedcode.ThingsMac";
|
|
68
|
+
/** True when this verdict permits opening the live container. */
|
|
69
|
+
export function readAllowed(capability) {
|
|
70
|
+
return capability.mode !== "none" && capability.mode !== "helpers-unavailable";
|
|
71
|
+
}
|
|
72
|
+
/** True when this verdict permits driving the Things window. */
|
|
73
|
+
export function uiAllowed(capability) {
|
|
74
|
+
return capability.mode === "helpers" || capability.mode === "direct-escape";
|
|
75
|
+
}
|
|
76
|
+
/** True when app automation may be dispatched. */
|
|
77
|
+
export function writeAllowed(capability) {
|
|
78
|
+
return capability.mode === "deputy" || capability.mode === "direct-granted";
|
|
79
|
+
}
|
|
80
|
+
// ── The prompt-free probes ───────────────────────────────────────────────────
|
|
81
|
+
/**
|
|
82
|
+
* One Automation row from TCC.db: the `auth_value` macOS records for `client`
|
|
83
|
+
* driving `target`, or null when there is no row (never asked) or the file is
|
|
84
|
+
* unreadable (no FDA). Read-only, prompt-free, and defensive — the schema is
|
|
85
|
+
* Apple's private business, so ANY failure degrades to null rather than
|
|
86
|
+
* throwing into a caller that asked a yes/no question.
|
|
87
|
+
*/
|
|
88
|
+
function automationAuthValueDefault(env, client, target) {
|
|
89
|
+
let db;
|
|
90
|
+
try {
|
|
91
|
+
db = new DatabaseSync(tccDbPath(env), { readOnly: true });
|
|
92
|
+
const row = db
|
|
93
|
+
.prepare("SELECT auth_value FROM access WHERE service = 'kTCCServiceAppleEvents' " +
|
|
94
|
+
"AND client = ? AND indirect_object_identifier = ? LIMIT 1")
|
|
95
|
+
.get(client, target);
|
|
96
|
+
const value = row?.auth_value;
|
|
97
|
+
return typeof value === "number" ? value : null;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
try {
|
|
104
|
+
db?.close();
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// A close failure cannot change the answer we already have.
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// ── Read capability (Article I + II) ─────────────────────────────────────────
|
|
112
|
+
/**
|
|
113
|
+
* Errnos that mean a plain "no" rather than something worth telling the user
|
|
114
|
+
* about. EPERM is the FDA denial proper; EACCES is its sandboxed cousin; ENOENT
|
|
115
|
+
* simply means this account has no TCC database yet. Anything else is an
|
|
116
|
+
* anomaly and gets named, so a genuinely odd failure is never silently folded
|
|
117
|
+
* into "you lack permission".
|
|
118
|
+
*/
|
|
119
|
+
const ORDINARY_DENIALS = new Set(["EPERM", "EACCES", "ENOENT"]);
|
|
120
|
+
/** The ways a machine can earn read capability, phrased for a human. */
|
|
121
|
+
function readRemediation(hostName) {
|
|
122
|
+
return [
|
|
123
|
+
"run `things helpers setup` — reads then flow through a helper that holds its own durable grant",
|
|
124
|
+
`or grant Full Disk Access to ${hostName} in System Settings ▸ Privacy & Security ▸ Full Disk Access`,
|
|
125
|
+
"or run `things setup`, which walks through both",
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Can this process read the live Things library, and on whose authority?
|
|
130
|
+
*
|
|
131
|
+
* Stateless: every call re-derives the verdict, because a grant can appear or
|
|
132
|
+
* vanish between one invocation and the next and a cached "yes" would be a
|
|
133
|
+
* stored onboarding flag by another name. The common case costs one `open(2)`.
|
|
134
|
+
*/
|
|
135
|
+
export function readCapability(options = {}, deps = {}) {
|
|
136
|
+
const env = deps.env ?? process.env;
|
|
137
|
+
const host = hostApp(deps);
|
|
138
|
+
// Article VI — a path the caller already owns gets plain file semantics.
|
|
139
|
+
if (options.dbPath !== undefined || (env["THINGS_DB"] ?? "") !== "") {
|
|
140
|
+
return {
|
|
141
|
+
mode: "explicit-db",
|
|
142
|
+
detail: "an explicit database path was supplied — plain file semantics apply",
|
|
143
|
+
remediation: [],
|
|
144
|
+
host,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// The helpers path. Reads that ride the reader are not pre-checked here: the
|
|
148
|
+
// reader resolves its bookmark on every verb, so the read IS the check and a
|
|
149
|
+
// probe would only add latency and a second answer to disagree with.
|
|
150
|
+
const serving = (deps.helpersServing ?? (() => deputyRoutesDb(options, env)))();
|
|
151
|
+
if (serving) {
|
|
152
|
+
return {
|
|
153
|
+
mode: "helpers",
|
|
154
|
+
detail: "database reads are served by the sandboxed reader",
|
|
155
|
+
remediation: [],
|
|
156
|
+
host,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
// No silent fall-through: a machine that asked for the helpers and cannot
|
|
160
|
+
// have them is refused, not quietly downgraded onto the terminal's own grants.
|
|
161
|
+
// Nothing gates this question any more — the rendezvous is ours, so whether
|
|
162
|
+
// the helpers are expected and whether they are serving are both answerable
|
|
163
|
+
// from every host app alike.
|
|
164
|
+
const expected = (deps.helpersExpected ?? (() => helpersExpected(env)))();
|
|
165
|
+
if (expected) {
|
|
166
|
+
const why = (deps.helpersReason ?? (() => null))();
|
|
167
|
+
return {
|
|
168
|
+
mode: "helpers-unavailable",
|
|
169
|
+
detail: `the helpers are enabled on this machine but are not serving reads${why !== null ? ` (${why})` : ""}`,
|
|
170
|
+
remediation: [
|
|
171
|
+
"run `things helpers setup` to finish onboarding them",
|
|
172
|
+
"or `things helpers status` to see which half is unhealthy",
|
|
173
|
+
"or `things --no-helpers …` to run this one invocation directly",
|
|
174
|
+
],
|
|
175
|
+
host,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const fda = fdaGranted(deps);
|
|
179
|
+
if (fda.granted) {
|
|
180
|
+
return {
|
|
181
|
+
mode: "direct-fda",
|
|
182
|
+
detail: `Full Disk Access is held by ${hostDisplayName(deps)}${host.bundleId !== null ? ` (${host.bundleId})` : ""}`,
|
|
183
|
+
remediation: [],
|
|
184
|
+
host,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// The sub-FDA tier: a grant a ceremony witnessed, still live for this very
|
|
188
|
+
// app instance. Only consulted when FDA has already said no.
|
|
189
|
+
const session = sessionGrantValid(host.bundleId, deps);
|
|
190
|
+
if (session.valid) {
|
|
191
|
+
return {
|
|
192
|
+
mode: "session-grant",
|
|
193
|
+
detail: `${hostDisplayName(deps)} was granted access to the Things data folder for as long as it stays open`,
|
|
194
|
+
remediation: [],
|
|
195
|
+
host,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
mode: "none",
|
|
200
|
+
detail: `${hostDisplayName(deps)} cannot open the Things data folder — ${session.reason}` +
|
|
201
|
+
(fda.code !== null && !ORDINARY_DENIALS.has(fda.code)
|
|
202
|
+
? ` (the access check ended in ${fda.code})`
|
|
203
|
+
: ""),
|
|
204
|
+
remediation: readRemediation(hostDisplayName(deps)),
|
|
205
|
+
host,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/** Thrown when a read is refused for want of capability (Article II). */
|
|
209
|
+
export class ReadCapabilityError extends Error {
|
|
210
|
+
remediation;
|
|
211
|
+
capability;
|
|
212
|
+
constructor(capability) {
|
|
213
|
+
super(`the Things database cannot be read: ${capability.detail}. ` +
|
|
214
|
+
`${capability.remediation.join("; ")}.`);
|
|
215
|
+
this.name = "ReadCapabilityError";
|
|
216
|
+
this.remediation = capability.remediation;
|
|
217
|
+
this.capability = capability;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// ── Write capability (Article I + II) ────────────────────────────────────────
|
|
221
|
+
/**
|
|
222
|
+
* macOS `auth_value` for an Automation record. 0 is a refusal; 2 (allowed) and
|
|
223
|
+
* 3 both mean the event will be delivered.
|
|
224
|
+
*/
|
|
225
|
+
function classifyAuthValue(value) {
|
|
226
|
+
if (value === null)
|
|
227
|
+
return "unknown";
|
|
228
|
+
if (value === 0)
|
|
229
|
+
return "denied";
|
|
230
|
+
if (value >= 2)
|
|
231
|
+
return "granted";
|
|
232
|
+
return "unknown";
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* May this process drive Things over Apple Events, and on whose authority?
|
|
236
|
+
*
|
|
237
|
+
* The deputy wins when it is onboarded (its own handshake reports the grant it
|
|
238
|
+
* holds). Otherwise the host app's own Automation record is read out of TCC —
|
|
239
|
+
* granted, denied, or, when there is no record at all, `direct-unknown`. That
|
|
240
|
+
* last state is deliberately NOT resolved here: resolving it means sending a
|
|
241
|
+
* real Apple Event, which is what raises the dialog, and Article I reserves
|
|
242
|
+
* that for `things setup`.
|
|
243
|
+
*/
|
|
244
|
+
export function writeCapability(deps = {}) {
|
|
245
|
+
const env = deps.env ?? process.env;
|
|
246
|
+
const host = hostApp(deps);
|
|
247
|
+
const deputyThings = (deps.deputyAutomation ?? (() => deputyRouting(env).hello?.automation?.things))();
|
|
248
|
+
if (deputyThings === "granted") {
|
|
249
|
+
return {
|
|
250
|
+
mode: "deputy",
|
|
251
|
+
detail: "the deputy is onboarded and holds app control for Things",
|
|
252
|
+
remediation: [],
|
|
253
|
+
host,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
if (host.bundleId === null) {
|
|
257
|
+
return {
|
|
258
|
+
mode: "direct-unknown",
|
|
259
|
+
detail: "this process does not descend from an application bundle, so macOS has no identity " +
|
|
260
|
+
"to record app control against",
|
|
261
|
+
remediation: [
|
|
262
|
+
"run `things helpers setup` — app control then attaches to a helper that always has an identity",
|
|
263
|
+
],
|
|
264
|
+
host,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const authValue = (deps.automationAuthValue ??
|
|
268
|
+
((client, target) => automationAuthValueDefault(env, client, target)))(host.bundleId, THINGS_BUNDLE_ID);
|
|
269
|
+
const hostName = hostDisplayName(deps);
|
|
270
|
+
switch (classifyAuthValue(authValue)) {
|
|
271
|
+
case "granted":
|
|
272
|
+
return {
|
|
273
|
+
mode: "direct-granted",
|
|
274
|
+
detail: `${hostName} (${host.bundleId}) holds app control for Things`,
|
|
275
|
+
remediation: [],
|
|
276
|
+
host,
|
|
277
|
+
};
|
|
278
|
+
case "denied":
|
|
279
|
+
return {
|
|
280
|
+
mode: "direct-denied",
|
|
281
|
+
detail: `macOS records a refusal of app control for ${hostName} (${host.bundleId}) — it will not ask again`,
|
|
282
|
+
remediation: [
|
|
283
|
+
`turn on Things3 for ${hostName} under System Settings ▸ Privacy & Security ▸ Automation`,
|
|
284
|
+
`or re-arm the request with \`tccutil reset AppleEvents ${host.bundleId}\`, then run \`things setup\``,
|
|
285
|
+
],
|
|
286
|
+
host,
|
|
287
|
+
};
|
|
288
|
+
default:
|
|
289
|
+
return {
|
|
290
|
+
mode: "direct-unknown",
|
|
291
|
+
detail: `macOS has no app-control record for ${hostName} (${host.bundleId}) yet`,
|
|
292
|
+
remediation: [
|
|
293
|
+
"run `things setup` — it asks for app control once, while you are at the machine",
|
|
294
|
+
"or run `things helpers setup` to attach the grant to a helper instead",
|
|
295
|
+
],
|
|
296
|
+
host,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/** Thrown when app automation is refused for want of capability (Article II). */
|
|
301
|
+
export class WriteCapabilityError extends Error {
|
|
302
|
+
remediation;
|
|
303
|
+
capability;
|
|
304
|
+
constructor(capability) {
|
|
305
|
+
super(`Things cannot be driven: ${capability.detail}. ${capability.remediation.join("; ")}.`);
|
|
306
|
+
this.name = "WriteCapabilityError";
|
|
307
|
+
this.remediation = capability.remediation;
|
|
308
|
+
this.capability = capability;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// ── UI capability (Article IV) ───────────────────────────────────────────────
|
|
312
|
+
/**
|
|
313
|
+
* The LAB's escape hatch, and deliberately not consumer surface. The VM lab and
|
|
314
|
+
* the guest e2e bundle drive the UI vector DIRECT — the in-guest Accessibility
|
|
315
|
+
* grant is held by the runner's own processes (the AXVM1 layer), there is no
|
|
316
|
+
* helper bundle in a disposable clone, and there is nobody to answer a dialog
|
|
317
|
+
* either. Setting this to `1` restores direct UI-vector availability for that
|
|
318
|
+
* one situation. It is documented in docs/lab/harness.md and exported by the
|
|
319
|
+
* lab's guest environment; nothing consumer-facing mentions it, and it does not
|
|
320
|
+
* bypass `ui.enabled` — a lab clone still sets that key explicitly.
|
|
321
|
+
*/
|
|
322
|
+
export const UI_DIRECT_ESCAPE_ENV = "THINGS_API_UI_DIRECT";
|
|
323
|
+
/** The command that gathers the GUI-driving tier, named in every UI refusal. */
|
|
324
|
+
const GUI_SETUP_COMMAND = "run `things helpers setup --gui` to grant GUI-driving to the helpers";
|
|
325
|
+
function deputyGuiStandingDefault(env) {
|
|
326
|
+
const hello = deputyRouting(env).hello;
|
|
327
|
+
if (hello === undefined || hello === null)
|
|
328
|
+
return null;
|
|
329
|
+
return { axTrusted: hello.axTrusted, systemEvents: hello.automation?.systemEvents };
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* May this process drive the Things WINDOW, and on whose authority?
|
|
333
|
+
*
|
|
334
|
+
* Article IV admits exactly one provenance: the helper pair. Accessibility on a
|
|
335
|
+
* general-purpose host app (a terminal, an agent harness, an MCP host) has a
|
|
336
|
+
* blast radius far beyond Things, churns with every host update, and has no
|
|
337
|
+
* sane story at all over ssh — so direct AX is unsupported, and a refusal here
|
|
338
|
+
* names the config knob and `things helpers setup --gui` rather than raising an
|
|
339
|
+
* Accessibility prompt against whatever happens to be running us.
|
|
340
|
+
*
|
|
341
|
+
* Every answer is prompt-free: the config key is a file read, and the deputy's
|
|
342
|
+
* `hello` carries `AXIsProcessTrusted()` plus its own `AEDeterminePermission`
|
|
343
|
+
* verdict for System Events.
|
|
344
|
+
*/
|
|
345
|
+
export function uiCapability(deps = {}) {
|
|
346
|
+
const env = deps.env ?? process.env;
|
|
347
|
+
const host = hostApp(deps);
|
|
348
|
+
const enabled = (deps.uiEnabled ?? (() => loadConfig(env).ui.enabled))();
|
|
349
|
+
if (!enabled) {
|
|
350
|
+
return {
|
|
351
|
+
mode: "config-disabled",
|
|
352
|
+
detail: "GUI-driving is switched off on this machine (`ui-enabled` is false)",
|
|
353
|
+
remediation: [
|
|
354
|
+
"run `things config set ui-enabled true` to opt in",
|
|
355
|
+
`then ${GUI_SETUP_COMMAND}`,
|
|
356
|
+
],
|
|
357
|
+
host,
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
if ((env[UI_DIRECT_ESCAPE_ENV] ?? "") === "1") {
|
|
361
|
+
return {
|
|
362
|
+
mode: "direct-escape",
|
|
363
|
+
detail: `${UI_DIRECT_ESCAPE_ENV}=1 — GUI-driving runs directly under this process (lab escape)`,
|
|
364
|
+
remediation: [],
|
|
365
|
+
host,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
const standing = (deps.deputyGuiStanding ?? (() => deputyGuiStandingDefault(env)))();
|
|
369
|
+
if (standing === null) {
|
|
370
|
+
return {
|
|
371
|
+
mode: "helpers-missing",
|
|
372
|
+
detail: "GUI-driving is granted only to the helpers, and no helper is answering on this machine",
|
|
373
|
+
remediation: [GUI_SETUP_COMMAND, "or `things helpers status` to see which half is unhealthy"],
|
|
374
|
+
host,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
const missing = [];
|
|
378
|
+
if (standing.axTrusted !== true) {
|
|
379
|
+
missing.push(standing.axTrusted === undefined
|
|
380
|
+
? "Accessibility (these helpers predate the permission handshake — rebuild)"
|
|
381
|
+
: "Accessibility");
|
|
382
|
+
}
|
|
383
|
+
if (standing.systemEvents !== "granted") {
|
|
384
|
+
missing.push(`automation → System Events (${standing.systemEvents ?? "unknown"})`);
|
|
385
|
+
}
|
|
386
|
+
if (missing.length === 0) {
|
|
387
|
+
return {
|
|
388
|
+
mode: "helpers",
|
|
389
|
+
detail: "the helpers hold Accessibility and app control for System Events",
|
|
390
|
+
remediation: [],
|
|
391
|
+
host,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
return {
|
|
395
|
+
mode: "tier-incomplete",
|
|
396
|
+
detail: `the helpers are onboarded but the GUI-driving tier is incomplete — missing ${missing.join("; ")}`,
|
|
397
|
+
remediation: [GUI_SETUP_COMMAND],
|
|
398
|
+
host,
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
/** Thrown when GUI-driving is refused for want of capability (Article IV). */
|
|
402
|
+
export class UiCapabilityError extends Error {
|
|
403
|
+
remediation;
|
|
404
|
+
capability;
|
|
405
|
+
constructor(capability) {
|
|
406
|
+
super(`the Things window cannot be driven: ${capability.detail}. ${capability.remediation.join("; ")}.`);
|
|
407
|
+
this.name = "UiCapabilityError";
|
|
408
|
+
this.remediation = capability.remediation;
|
|
409
|
+
this.capability = capability;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/** Test seam: forget the one memo this module keeps (the host's display name). */
|
|
413
|
+
export function resetCapabilityForTests() {
|
|
414
|
+
resetHostAccessForTests();
|
|
415
|
+
}
|
|
416
|
+
//# sourceMappingURL=capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|