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,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `things helpers` — lifecycle for the optional helper pair (one installed
|
|
3
|
+
* bundle housing both):
|
|
4
|
+
*
|
|
5
|
+
* things-deputy — app automation (mutations), unsandboxed.
|
|
6
|
+
* things-reader — database/file reads, sandboxed to a user-granted folder.
|
|
7
|
+
*
|
|
8
|
+
* Running them means macOS permission prompts and grants attach to two stable
|
|
9
|
+
* identities instead of every terminal or agent runtime that invokes
|
|
10
|
+
* `things`, so grants stop re-prompting when those runtimes update. Routing is
|
|
11
|
+
* tri-state (`helpers-enabled`: auto | true | false, default auto —
|
|
12
|
+
* installation is the intent signal), overridable per invocation with
|
|
13
|
+
* THINGS_API_HELPERS or the global `--helpers`/`--no-helpers` flags; the CLI
|
|
14
|
+
* always falls back to direct execution when a helper is unavailable.
|
|
15
|
+
*/
|
|
16
|
+
import type { Command } from "commander";
|
|
17
|
+
export declare function registerHelpers(program: Command): void;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { helpersStatus, ExitCode, grantReader, installHelpers, loadConfig, okEnvelope, restartHelpers, uninstallHelpers, } from "../../index.js";
|
|
2
|
+
function envelopeMeta(started) {
|
|
3
|
+
return { dbVersion: null, fingerprint: "unknown", elapsedMs: Date.now() - started };
|
|
4
|
+
}
|
|
5
|
+
/** One line describing what the configured mode means for this machine. */
|
|
6
|
+
function routingLine(status) {
|
|
7
|
+
switch (status.mode) {
|
|
8
|
+
case "true":
|
|
9
|
+
return "enabled — every process routes through the helpers, and reports when it cannot";
|
|
10
|
+
case "false":
|
|
11
|
+
return "disabled (things config set helpers-enabled auto)";
|
|
12
|
+
case "auto":
|
|
13
|
+
return status.bundleInstalled
|
|
14
|
+
? "auto — the installed helpers are used while healthy; a failure is reported, never silent"
|
|
15
|
+
: "auto — nothing installed, so everything runs direct (things helpers install to change that)";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function renderStatus(status) {
|
|
19
|
+
const deputy = status.deputy;
|
|
20
|
+
const lines = [`deputy: ${deputy.running ? "running" : "does not appear to be running"}`];
|
|
21
|
+
// The plain no-socket case needs no elaboration; a socket that exists but
|
|
22
|
+
// misbehaves (not answering, handshake refused) is worth its own line.
|
|
23
|
+
if (!deputy.running && !deputy.detail.startsWith("not running")) {
|
|
24
|
+
lines.push(` detail: ${deputy.detail}`);
|
|
25
|
+
}
|
|
26
|
+
if (deputy.hungSocket) {
|
|
27
|
+
lines.push(" next: `things helpers restart` — the socket is present but no handshake answers");
|
|
28
|
+
}
|
|
29
|
+
lines.push(` routing: ${routingLine(status)}`, ` launchd: ${deputy.plistInstalled ? (deputy.loaded ? "installed + loaded" : "installed, NOT loaded") : "not installed (things helpers install)"}`, ` bundle: ${status.bundleInstalled
|
|
30
|
+
? `installed${status.installedVersion !== null ? ` (v${status.installedVersion})` : ""}`
|
|
31
|
+
: "not installed"}`, ` socket: ${deputy.socketPath}`);
|
|
32
|
+
if (deputy.hello !== null) {
|
|
33
|
+
lines.push(` version: ${deputy.hello.deputyVersion} (protocol ${deputy.hello.protocol}, pid ${deputy.hello.pid})`);
|
|
34
|
+
}
|
|
35
|
+
if (deputy.signing !== null) {
|
|
36
|
+
lines.push(` signing: ${deputy.signing.state}${deputy.signing.authority !== null ? ` (${deputy.signing.authority})` : ""}`);
|
|
37
|
+
if (deputy.signing.state !== "signed") {
|
|
38
|
+
lines.push(" warning: an unsigned/ad-hoc helper loses its macOS grants on every rebuild — run scripts/deputy-cert-setup.sh once, rebuild, reinstall");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const reader = status.reader;
|
|
42
|
+
lines.push(`reader: ${reader.running ? (reader.granted ? "running, granted" : "running, NOT granted") : reader.installed ? reader.detail : "not installed"}`);
|
|
43
|
+
if (reader.running && !reader.granted) {
|
|
44
|
+
lines.push(" next: run `things helpers grant` and accept the panel (one time; the grant survives restarts, reboots, and rebuilds)");
|
|
45
|
+
}
|
|
46
|
+
if (reader.hungSocket) {
|
|
47
|
+
lines.push(" next: `things helpers restart` — the socket is present but no handshake answers");
|
|
48
|
+
}
|
|
49
|
+
return `${lines.join("\n")}\n`;
|
|
50
|
+
}
|
|
51
|
+
export function registerHelpers(program) {
|
|
52
|
+
const helpers = program
|
|
53
|
+
.command("helpers")
|
|
54
|
+
.description("Manage the optional helper pair that performs database reads and app automation " +
|
|
55
|
+
"on the CLI's behalf, so macOS permission grants attach to stable helpers instead " +
|
|
56
|
+
"of every terminal or agent runtime that runs `things`. Subcommands: status, " +
|
|
57
|
+
"install, grant, restart, uninstall.");
|
|
58
|
+
helpers
|
|
59
|
+
.command("status")
|
|
60
|
+
.description("Report both helpers' state: running or not, launchd installation, installed version, " +
|
|
61
|
+
"code-signing identity, the reader's grant, and the routing mode on this machine. " +
|
|
62
|
+
"Read-only.")
|
|
63
|
+
.option("--json", "emit versioned JSON envelope on stdout")
|
|
64
|
+
.action((opts) => {
|
|
65
|
+
const started = Date.now();
|
|
66
|
+
const status = helpersStatus(loadConfig().helpersMode);
|
|
67
|
+
if (opts.json === true) {
|
|
68
|
+
process.stdout.write(`${JSON.stringify(okEnvelope("helpers-status", status, envelopeMeta(started)))}\n`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
process.stdout.write(renderStatus(status));
|
|
72
|
+
}
|
|
73
|
+
process.exitCode = ExitCode.Ok;
|
|
74
|
+
});
|
|
75
|
+
helpers
|
|
76
|
+
.command("install")
|
|
77
|
+
.description("Install the helper bundle: copy it to its stable location, register both helpers " +
|
|
78
|
+
"with launchd (starts now and on every login), and report signing + grant state. " +
|
|
79
|
+
"Under the default helpers-enabled auto, an installed and healthy helper is used from " +
|
|
80
|
+
"the next command on. Rerun after every rebuild.")
|
|
81
|
+
.option("--bundle <path>", "path to a built Things API Helper.app (default: deputy/build/Things API Helper.app in this package)")
|
|
82
|
+
.action((opts) => {
|
|
83
|
+
try {
|
|
84
|
+
const result = installHelpers(opts.bundle !== undefined ? { bundlePath: opts.bundle } : {});
|
|
85
|
+
process.stdout.write(`installed ${result.bundlePath}\nlaunchd agent: ${result.plistPath}\n`);
|
|
86
|
+
if (result.readerInstalled) {
|
|
87
|
+
process.stdout.write(result.readerGranted === true
|
|
88
|
+
? "reader: granted — file reads ride the scoped reader\n"
|
|
89
|
+
: result.readerGranted === false
|
|
90
|
+
? "reader: installed — run `things helpers grant` once to give it durable read access\n"
|
|
91
|
+
: "reader: installed, not answering yet — check `things helpers status`\n");
|
|
92
|
+
}
|
|
93
|
+
for (const warning of result.warnings) {
|
|
94
|
+
process.stderr.write(`warning: ${warning}\n`);
|
|
95
|
+
}
|
|
96
|
+
process.exitCode = ExitCode.Ok;
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
process.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
100
|
+
process.exitCode = ExitCode.Environment;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
helpers
|
|
104
|
+
.command("grant")
|
|
105
|
+
.description("One-time ceremony: opens a folder panel presented by the sandboxed reader helper, " +
|
|
106
|
+
"already showing the Things data folder. Accepting gives the reader durable read " +
|
|
107
|
+
"access to exactly that folder — it survives restarts, reboots, and updates, and " +
|
|
108
|
+
"macOS enforces that the reader can reach nothing else. Interactive: run this at " +
|
|
109
|
+
"the machine, not from an unattended session.")
|
|
110
|
+
.action(() => {
|
|
111
|
+
const result = grantReader();
|
|
112
|
+
if (result.granted) {
|
|
113
|
+
process.stdout.write("granted — file reads now ride the scoped reader\n");
|
|
114
|
+
process.exitCode = ExitCode.Ok;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
process.stderr.write(`not granted: ${result.detail}\n`);
|
|
118
|
+
process.exitCode = ExitCode.Environment;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
helpers
|
|
122
|
+
.command("restart")
|
|
123
|
+
.description("Restart the launchd-managed helpers (picks up a rebuilt installed bundle).")
|
|
124
|
+
.action(() => {
|
|
125
|
+
try {
|
|
126
|
+
restartHelpers();
|
|
127
|
+
process.stdout.write("helpers restarted\n");
|
|
128
|
+
process.exitCode = ExitCode.Ok;
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
process.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
132
|
+
process.exitCode = ExitCode.Environment;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
helpers
|
|
136
|
+
.command("uninstall")
|
|
137
|
+
.description("Stop both helpers and remove their launchd registrations and the installed bundle. " +
|
|
138
|
+
"Local state (access token, logs, the reader's grant) is kept; routing config is " +
|
|
139
|
+
"untouched (commands fall back to direct execution).")
|
|
140
|
+
.action(() => {
|
|
141
|
+
const result = uninstallHelpers();
|
|
142
|
+
process.stdout.write(result.removed.length > 0
|
|
143
|
+
? `removed:\n${result.removed.map((p) => ` ${p}`).join("\n")}\n`
|
|
144
|
+
: "nothing installed\n");
|
|
145
|
+
process.exitCode = ExitCode.Ok;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/cli/commands/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `things op-result <op-id>` — a read-only CALLER-RECOVERY lookup over the local
|
|
3
|
+
* change history (RSPA1 deliverable 3). Thin surface over the library's opResult().
|
|
4
|
+
*
|
|
5
|
+
* When your environment kills long commands (a wall-time cap) before a write's
|
|
6
|
+
* result is printed — a `--dangerously-drive-gui` drive can run its full verify
|
|
7
|
+
* budget — dispatch the op with `--op-id <key>`, let it die, then run this in a
|
|
8
|
+
* fresh process to learn what ACTUALLY happened from the record the killed process
|
|
9
|
+
* already durably wrote. NEVER blind-retry a GUI drive.
|
|
10
|
+
*
|
|
11
|
+
* Always exit 0: this is a successful HISTORY READ regardless of the underlying
|
|
12
|
+
* op's outcome (which lives in `data.status` / `data.result`).
|
|
13
|
+
*/
|
|
14
|
+
import type { Command } from "commander";
|
|
15
|
+
export declare function registerOpResult(program: Command): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { okEnvelope, opResult } from "../../index.js";
|
|
2
|
+
export function registerOpResult(program) {
|
|
3
|
+
program
|
|
4
|
+
.command("op-result")
|
|
5
|
+
.argument("<op-id>", "the --op-id / op_id the original write carried")
|
|
6
|
+
.description("Look up what happened to a write you dispatched with --op-id, from the local change " +
|
|
7
|
+
"history alone (opens no database, drives nothing). Use it to recover the outcome when " +
|
|
8
|
+
"your environment killed the command before it printed its result: let the command die, " +
|
|
9
|
+
"then run this. Reports FOUND (the final result + target + observation), INTENT-ONLY (the " +
|
|
10
|
+
"op started but no outcome was written — still running or the process died mid-flight, " +
|
|
11
|
+
"outcome UNCERTAIN), or UNKNOWN (no such op-id in history). Always exit 0 (a history read).")
|
|
12
|
+
.option("--json", "emit versioned JSON envelope on stdout")
|
|
13
|
+
.action((opId, opts) => {
|
|
14
|
+
const started = Date.now();
|
|
15
|
+
const data = opResult(opId);
|
|
16
|
+
const meta = {
|
|
17
|
+
dbVersion: null,
|
|
18
|
+
fingerprint: "unknown",
|
|
19
|
+
elapsedMs: Date.now() - started,
|
|
20
|
+
};
|
|
21
|
+
if (opts.json) {
|
|
22
|
+
process.stdout.write(`${JSON.stringify(okEnvelope("op-result", data, meta))}\n`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const head = data.status === "found"
|
|
26
|
+
? `${data.result} — ${data.op}${data.uuid !== null ? ` (${data.uuid})` : ""}`
|
|
27
|
+
: data.status === "intent-only"
|
|
28
|
+
? `intent-only — ${data.op} (no final outcome recorded)`
|
|
29
|
+
: "unknown op-id";
|
|
30
|
+
process.stdout.write(`op-result ${opId}: ${head}\n`);
|
|
31
|
+
process.stdout.write(` ${data.note}\n`);
|
|
32
|
+
if (data.status === "found" && data.observed !== null) {
|
|
33
|
+
process.stdout.write(` observed: ${JSON.stringify(data.observed)}\n`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
process.exitCode = 0;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=op-result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"op-result.js","sourceRoot":"","sources":["../../../src/cli/commands/op-result.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAqB,MAAM,gBAAgB,CAAC;AAEzE,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,QAAQ,CAAC,SAAS,EAAE,gDAAgD,CAAC;SACrE,WAAW,CACV,sFAAsF;QACpF,wFAAwF;QACxF,yFAAyF;QACzF,2FAA2F;QAC3F,wFAAwF;QACxF,4FAA4F,CAC/F;SACA,MAAM,CAAC,QAAQ,EAAE,wCAAwC,CAAC;SAC1D,MAAM,CAAC,CAAC,IAAY,EAAE,IAAwB,EAAE,EAAE;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAiB;YACzB,SAAS,EAAE,IAAI;YACf,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;SAChC,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QACnF,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GACR,IAAI,CAAC,MAAM,KAAK,OAAO;gBACrB,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC7E,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;oBAC7B,CAAC,CAAC,iBAAiB,IAAI,CAAC,EAAE,8BAA8B;oBACxD,CAAC,CAAC,eAAe,CAAC;YACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC;YACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QACD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { armInterrupt, disarmInterrupt } from "../interrupt.js";
|
|
|
3
3
|
import { isDevVersion } from "../skill.js";
|
|
4
4
|
import { CLI_VERSION } from "../version.js";
|
|
5
5
|
import { addRepeatCalendarFlags, addRepeatingRuleFieldsFromOpts, addRepeatRuleFlags, repeatRuleFlagsFromOpts, } from "./repeat-flags.js";
|
|
6
|
-
import { aggregateExitCode, blockedCode, capabilitiesTable, ClockError, closeCliTrace, describeConfig, errorEnvelope, ExitCode, installCliTrace, getConfigKey, mutationWireData, okEnvelope, openThings, OP_ID_RE, outcomeFailed, ReferenceResolutionError, saveConfigKey, splitWhenSugar, trace, ThingsDbNotFoundError, ThingsDbOpenError, verifyFailedCode, } from "../../index.js";
|
|
6
|
+
import { aggregateExitCode, blockedCode, capabilitiesTable, ClockError, closeCliTrace, describeConfig, errorEnvelope, ExitCode, HELPERS_MODES, installCliTrace, getConfigKey, parseHelpersMode, mutationWireData, okEnvelope, openThings, OP_ID_RE, outcomeFailed, ReferenceResolutionError, saveConfigKey, splitWhenSugar, trace, ThingsDbNotFoundError, ThingsDbOpenError, verifyFailedCode, } from "../../index.js";
|
|
7
7
|
import { usageError } from "../read-driver.js";
|
|
8
8
|
import { dim } from "../style.js";
|
|
9
9
|
function addWriteFlags(cmd) {
|
|
@@ -354,6 +354,7 @@ function emitResult(result, opts, meta) {
|
|
|
354
354
|
` invocation: ${result.plan.invocation}`,
|
|
355
355
|
` hazards checked: ${result.plan.hazardsChecked.join(", ") || "none"}`,
|
|
356
356
|
` expected delta: ${JSON.stringify(result.plan.expectedDelta)}`,
|
|
357
|
+
...(result.plan.notes ?? []).map((n) => ` note: ${n}`),
|
|
357
358
|
"",
|
|
358
359
|
].join("\n"));
|
|
359
360
|
}
|
|
@@ -1423,7 +1424,12 @@ export function registerWriteCommands(program) {
|
|
|
1423
1424
|
.option("--notes <text>", "notes body")
|
|
1424
1425
|
.option("--when <value>", "today | evening | anytime | someday | YYYY-MM-DD")
|
|
1425
1426
|
.option("--reminder <time>", "HH:mm reminder (needs a schedulable --when)")
|
|
1426
|
-
.option("--deadline <date>", "YYYY-MM-DD"
|
|
1427
|
+
.option("--deadline <date>", "YYYY-MM-DD — deadlines EVERY occurrence: each starts (deadline − --when) days " +
|
|
1428
|
+
"before its own deadline (needs a concrete --when, on or before the deadline; " +
|
|
1429
|
+
"alternative spelling of --start-days-earlier — give one or the other, both must agree)")
|
|
1430
|
+
.option("--start-days-earlier <n>", "deadlines EVERY occurrence, naming the lead directly: each starts N days before " +
|
|
1431
|
+
"its own deadline (needs a concrete --when; alternative spelling of --deadline <date> — " +
|
|
1432
|
+
"give one or the other, both must agree)")
|
|
1427
1433
|
.option("--tag <name>", "tag to attach (repeatable)", collect, [])
|
|
1428
1434
|
.option("--checklist-item <title>", "checklist item (repeatable)", collect, [])
|
|
1429
1435
|
.option("--project <ref>", "destination project (uuid or unique name)")
|
|
@@ -1445,6 +1451,9 @@ export function registerWriteCommands(program) {
|
|
|
1445
1451
|
...(opts["when"] !== undefined && { when: opts["when"] }),
|
|
1446
1452
|
...(opts["reminder"] !== undefined && { reminder: opts["reminder"] }),
|
|
1447
1453
|
...(opts["deadline"] !== undefined && { deadline: opts["deadline"] }),
|
|
1454
|
+
...(opts["startDaysEarlier"] !== undefined && {
|
|
1455
|
+
startDaysEarlier: Number(opts["startDaysEarlier"]),
|
|
1456
|
+
}),
|
|
1448
1457
|
...(tags.length > 0 && { tags }),
|
|
1449
1458
|
...(checklistItems.length > 0 && { checklistItems }),
|
|
1450
1459
|
...(projectRef !== undefined && { project: projectRef }),
|
|
@@ -2155,7 +2164,8 @@ export function registerWriteCommands(program) {
|
|
|
2155
2164
|
.command("set <key> <value>")
|
|
2156
2165
|
.description("Persist a config key: profile | maxDisruption | actor | auditEnabled | " +
|
|
2157
2166
|
"accepted-fingerprint | certified-app-version | allow-experimental | bounce-enabled | " +
|
|
2158
|
-
"bounce-max-items | auto-launch |
|
|
2167
|
+
"bounce-max-items | auto-launch | helpers-enabled (auto | true | false) | ui-enabled | " +
|
|
2168
|
+
"ui-drive-budget-ms | trace | scope")
|
|
2159
2169
|
.action((key, value, opts) => {
|
|
2160
2170
|
const map = {
|
|
2161
2171
|
profile: "profile",
|
|
@@ -2168,6 +2178,7 @@ export function registerWriteCommands(program) {
|
|
|
2168
2178
|
"bounce-enabled": "bounceEnabled",
|
|
2169
2179
|
"bounce-max-items": "bounceMaxItems",
|
|
2170
2180
|
"auto-launch": "autoLaunch",
|
|
2181
|
+
"helpers-enabled": "helpersMode",
|
|
2171
2182
|
"ui-enabled": "uiEnabled",
|
|
2172
2183
|
"ui-drive-budget-ms": "uiDriveBudgetMs",
|
|
2173
2184
|
trace: "traceEnabled",
|
|
@@ -2179,6 +2190,14 @@ export function registerWriteCommands(program) {
|
|
|
2179
2190
|
process.exitCode = ExitCode.Usage;
|
|
2180
2191
|
return;
|
|
2181
2192
|
}
|
|
2193
|
+
// `helpers-enabled` is TRI-state (auto | true | false): anything else is
|
|
2194
|
+
// refused rather than silently coerced to a boolean, so a typo can never
|
|
2195
|
+
// read as "off" on a machine that meant "auto".
|
|
2196
|
+
if (target === "helpersMode" && parseHelpersMode(value) === undefined) {
|
|
2197
|
+
process.stderr.write(`error: helpers-enabled accepts ${HELPERS_MODES.join(" | ")} (got "${value}")\n`);
|
|
2198
|
+
process.exitCode = ExitCode.Usage;
|
|
2199
|
+
return;
|
|
2200
|
+
}
|
|
2182
2201
|
const parsed = target === "maxDisruption" || target === "bounceMaxItems" || target === "uiDriveBudgetMs"
|
|
2183
2202
|
? Number(value)
|
|
2184
2203
|
: target === "auditEnabled" ||
|