things-api 0.7.0 → 0.9.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 +6 -3
- package/dist/cli/commands/area.d.ts +23 -0
- package/dist/cli/commands/area.js +164 -33
- package/dist/cli/commands/area.js.map +1 -1
- package/dist/cli/commands/project.d.ts +19 -0
- package/dist/cli/commands/project.js +142 -29
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/reads.d.ts +10 -51
- package/dist/cli/commands/reads.js +454 -268
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/show.d.ts +9 -0
- package/dist/cli/commands/show.js +169 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/snapshot.js +1 -1
- package/dist/cli/commands/snapshot.js.map +1 -1
- package/dist/cli/commands/todo.d.ts +9 -0
- package/dist/cli/commands/todo.js +101 -16
- package/dist/cli/commands/todo.js.map +1 -1
- package/dist/cli/commands/writes.js +55 -1
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/did-you-mean.d.ts +29 -0
- package/dist/cli/did-you-mean.js +53 -0
- package/dist/cli/did-you-mean.js.map +1 -0
- package/dist/cli/glyphs.d.ts +95 -0
- package/dist/cli/glyphs.js +282 -0
- package/dist/cli/glyphs.js.map +1 -0
- package/dist/cli/main.js +11 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/period.d.ts +32 -0
- package/dist/cli/period.js +129 -0
- package/dist/cli/period.js.map +1 -0
- package/dist/cli/read-driver.d.ts +76 -0
- package/dist/cli/read-driver.js +181 -0
- package/dist/cli/read-driver.js.map +1 -0
- package/dist/cli/render.d.ts +182 -0
- package/dist/cli/render.js +585 -0
- package/dist/cli/render.js.map +1 -0
- package/dist/cli/resolve-invocation.d.ts +78 -0
- package/dist/cli/resolve-invocation.js +178 -0
- package/dist/cli/resolve-invocation.js.map +1 -0
- package/dist/cli/shell-quote.d.ts +9 -0
- package/dist/cli/shell-quote.js +12 -0
- package/dist/cli/shell-quote.js.map +1 -0
- package/dist/cli/style.d.ts +5 -0
- package/dist/cli/style.js +5 -0
- package/dist/cli/style.js.map +1 -1
- package/dist/client.d.ts +45 -39
- package/dist/client.js +11 -74
- package/dist/client.js.map +1 -1
- package/dist/contracts.d.ts +66 -1
- package/dist/contracts.js +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/db/baselines/db-v26.js +7 -5
- package/dist/db/baselines/db-v26.js.map +1 -1
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +7 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/mcp/server.js +227 -44
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/entities.d.ts +21 -0
- package/dist/model/entities.js.map +1 -1
- package/dist/model/mappers.js +17 -1
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/occurrences.d.ts +6 -1
- package/dist/model/occurrences.js +9 -2
- package/dist/model/occurrences.js.map +1 -1
- package/dist/model/recurrence.d.ts +30 -2
- package/dist/model/recurrence.js +20 -0
- package/dist/model/recurrence.js.map +1 -1
- package/dist/read/area-view.js +21 -5
- package/dist/read/area-view.js.map +1 -1
- package/dist/read/caps.d.ts +14 -0
- package/dist/read/caps.js +21 -0
- package/dist/read/caps.js.map +1 -0
- package/dist/read/detail.js +12 -2
- package/dist/read/detail.js.map +1 -1
- package/dist/read/log-boundary.d.ts +29 -0
- package/dist/read/log-boundary.js +38 -0
- package/dist/read/log-boundary.js.map +1 -0
- package/dist/read/pagination.d.ts +104 -0
- package/dist/read/pagination.js +208 -0
- package/dist/read/pagination.js.map +1 -0
- package/dist/read/predicates.d.ts +31 -0
- package/dist/read/predicates.js +48 -0
- package/dist/read/predicates.js.map +1 -0
- package/dist/read/project-view.js +28 -3
- package/dist/read/project-view.js.map +1 -1
- package/dist/read/queries.d.ts +21 -3
- package/dist/read/queries.js +35 -8
- package/dist/read/queries.js.map +1 -1
- package/dist/read/search-rank.d.ts +36 -0
- package/dist/read/search-rank.js +31 -0
- package/dist/read/search-rank.js.map +1 -0
- package/dist/read/show-target.d.ts +25 -0
- package/dist/read/show-target.js +41 -0
- package/dist/read/show-target.js.map +1 -0
- package/dist/read/sidebar-order.d.ts +19 -0
- package/dist/read/sidebar-order.js +92 -0
- package/dist/read/sidebar-order.js.map +1 -0
- package/dist/read/snapshot.js +2 -0
- package/dist/read/snapshot.js.map +1 -1
- package/dist/read/views.d.ts +64 -8
- package/dist/read/views.js +290 -155
- package/dist/read/views.js.map +1 -1
- package/dist/surface-copy.d.ts +23 -0
- package/dist/surface-copy.js +23 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/write/automation-probe.js +14 -6
- package/dist/write/automation-probe.js.map +1 -1
- package/dist/write/capabilities.d.ts +3 -0
- package/dist/write/capabilities.js +3 -0
- package/dist/write/capabilities.js.map +1 -1
- package/dist/write/checklist.d.ts +50 -0
- package/dist/write/checklist.js +61 -0
- package/dist/write/checklist.js.map +1 -0
- package/dist/write/clear-reminder.d.ts +3 -0
- package/dist/write/clear-reminder.js +205 -0
- package/dist/write/clear-reminder.js.map +1 -0
- package/dist/write/commands.js +122 -8
- package/dist/write/commands.js.map +1 -1
- package/dist/write/edit-checklist.d.ts +3 -0
- package/dist/write/edit-checklist.js +184 -0
- package/dist/write/edit-checklist.js.map +1 -0
- package/dist/write/failure-hints.d.ts +7 -0
- package/dist/write/failure-hints.js +25 -2
- package/dist/write/failure-hints.js.map +1 -1
- package/dist/write/guards.d.ts +1 -1
- package/dist/write/guards.js +16 -0
- package/dist/write/guards.js.map +1 -1
- package/dist/write/operations.d.ts +32 -1
- package/dist/write/operations.js +3 -0
- package/dist/write/operations.js.map +1 -1
- package/dist/write/pipeline.d.ts +3 -0
- package/dist/write/pipeline.js +23 -1
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/reversibility.d.ts +46 -0
- package/dist/write/reversibility.js +164 -0
- package/dist/write/reversibility.js.map +1 -0
- package/dist/write/undo.d.ts +29 -2
- package/dist/write/undo.js +357 -9
- package/dist/write/undo.js.map +1 -1
- package/dist/write/vectors/registry.js +2 -1
- package/dist/write/vectors/registry.js.map +1 -1
- package/dist/write/vectors/shortcuts.d.ts +9 -0
- package/dist/write/vectors/shortcuts.js +90 -0
- package/dist/write/vectors/shortcuts.js.map +1 -0
- package/dist/write/vectors/types.d.ts +11 -3
- package/dist/write/vectors/url-scheme.js +16 -0
- package/dist/write/vectors/url-scheme.js.map +1 -1
- package/dist/write/verify/delta.d.ts +1 -1
- package/dist/write/verify/delta.js +1 -1
- package/dist/write/verify/delta.js.map +1 -1
- package/package.json +1 -1
- package/shortcuts/things-proxy-find-items.shortcut +0 -0
package/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
A typed TypeScript library + CLI (`things`) for programmatic interaction with [Things 3](https://culturedcode.com/things/) by Cultured Code.
|
|
4
4
|
|
|
5
|
-
**Status: read + write + MCP layers live and published to npm (v0.7.0 — see [CHANGELOG.md](CHANGELOG.md)).** Reads go straight to the local SQLite database (UI-exact Today ordering, sidebar-grouped Anytime/Someday with container-status cascade, decoded repeat rules, occurrence projections); writes run a verified pipeline over two lab-validated write vectors (URL scheme + AppleScript) with hazard guards, disruption-tier policy, a JSONL audit trail, batch mode, audit-replay undo (transactional across compound operations), full project lifecycle (complete/cancel/reopen/restore), heading rename/archive/unarchive with children policies, container detach, granular stateful checklists, tag hierarchy management incl. un-nesting, completion/creation backdating, Logbook imports, tiered fuzzy name resolution (uuid prefixes, `things:///show?id=` share links), and ordering across eight scopes (incl. a project's headings and the top-level sidebar projects). A third surface — Apple Shortcuts — is
|
|
5
|
+
**Status: read + write + MCP layers live and published to npm (v0.7.0 — see [CHANGELOG.md](CHANGELOG.md)).** Reads go straight to the local SQLite database (UI-exact Today ordering, sidebar-grouped Anytime/Someday with container-status cascade, decoded repeat rules, occurrence projections); writes run a verified pipeline over two lab-validated write vectors (URL scheme + AppleScript) with hazard guards, disruption-tier policy, a JSONL audit trail, batch mode, audit-replay undo (transactional across compound operations), full project lifecycle (complete/cancel/reopen/restore), heading rename/archive/unarchive with children policies, container detach, granular stateful checklists, tag hierarchy management incl. un-nesting, completion/creation backdating, Logbook imports, tiered fuzzy name resolution (uuid prefixes, `things:///show?id=` share links), and ordering across eight scopes (incl. a project's headings and the top-level sidebar projects). A third surface — Apple Shortcuts — is now wired for the two headless capabilities nothing else can do: creating a heading in an existing project (`things heading add`) and clearing a reminder from a date-scheduled item (`things todo clear-reminder`). Both run through bundled proxy shortcuts (`things setup shortcuts`) and are gated on their presence. Single-item permanent delete stays interactive-only (its macOS consent has no always-allow) and is out of the headless pipeline. See [docs/design/](docs/design/) for the architecture and VM-lab design, [docs/lab/](docs/lab/harness.md) for the probe harness and campaign results the write layer is grounded in, and [docs/atlas/](docs/atlas/schema-v26.md) for the database↔UI map.
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
things today --json # read: your Today list, Evening split, UI order
|
|
9
|
+
things legend # the symbols & colors the list views use
|
|
9
10
|
things upcoming --horizon 5 # date plan incl. projected repeat occurrences
|
|
10
11
|
things todo add "Buy milk" --when today --tags errands --dry-run # plan without executing
|
|
11
12
|
things undo --dry-run # inverse plan for the last mutation (audit replay)
|
|
@@ -26,6 +27,8 @@ things setup shortcuts # opens an install sheet per missing shortcut — click
|
|
|
26
27
|
|
|
27
28
|
On each shortcut's first run macOS asks for permission — choose **Always Allow** so later runs are unattended (the two delete shortcuts re-ask on every run by design; Apple offers no always-allow for deletion). `things setup shortcuts --check` and `things doctor` report installation state.
|
|
28
29
|
|
|
30
|
+
Once installed, these Shortcuts-only operations become available as ordinary commands: `things heading add <project> <title>` (create a heading in an existing project) and `things todo clear-reminder <uuid>` (clear a date-scheduled to-do's reminder while keeping its date). Both are also exposed over MCP (`create_heading`, `clear_reminder`). If a required shortcut is missing, the command is blocked up front with a pointer back to `things setup shortcuts` — nothing is dispatched.
|
|
31
|
+
|
|
29
32
|
### Development install
|
|
30
33
|
|
|
31
34
|
To get a global `things` command that runs the live TypeScript source (no build step — Node ≥ 24 strips types natively):
|
|
@@ -50,8 +53,8 @@ Edits under `src/` take effect immediately. The bin launcher ([bin/things.js](bi
|
|
|
50
53
|
|
|
51
54
|
The CLI is designed to be driven by coding agents with no out-of-band knowledge. The contract:
|
|
52
55
|
|
|
53
|
-
1. **Discovery**: `things --help` (ends with AGENT NOTES), per-command `--help` (states each write's vector, disruption tier, hazards, and exact acknowledgement flag names — regression-tested as API), and `things capabilities [--op <op>] --json` (the lab-validated operation × vector support matrix, with probe-evidence ids).
|
|
54
|
-
2. **Structured output**: every command takes `--json` → versioned envelope `{ apiVersion, ok, kind, data|error, meta }` on stdout; human chatter goes to stderr only.
|
|
56
|
+
1. **Discovery**: `things --help` (ends with AGENT NOTES), per-command `--help` (states each write's vector, disruption tier, hazards, and exact acknowledgement flag names — regression-tested as API), and `things capabilities [--op <op>] --json` (the lab-validated operation × vector support matrix, with probe-evidence ids). Command invocation follows one grammar (`things <view>` · `things <type> <verb> <subject>` · loose `things <verb> <subject>` · bare `things <subject>`) with a single precedence chain — registered command/alias → view keyword → reference resolution — specified in [docs/design/cli-grammar.md](docs/design/cli-grammar.md).
|
|
57
|
+
2. **Structured output**: every command takes `--json` → versioned envelope `{ apiVersion, ok, kind, data|error, meta }` on stdout; human chatter goes to stderr only. List views are **bounded by default**: the flat/chronological views (`inbox`, `today`, `upcoming`, `logbook`, `trash`, `search`, `changes`) return at most 50 items — raise with `--limit <n>` or lift with `--all` — and carry exact truncation counts in `meta.pagination { shown, total, limit, truncated }`. The grouped catalogues (`anytime`, `someday`) always show every area and project row and cap per block instead (no `--limit`): `--area-limit <n>` (default 30) per area block on both, `--project-limit <n>` (default 3) per project block on anytime, `--show-active-project-items [n]` for someday's trailing active-projects section — reporting `meta.grouped { truncated, blocks[] }` with per-block counts. Same defaults and metadata apply over MCP.
|
|
55
58
|
3. **Stable exit codes**: `0` ok · `2` usage · `3` verify-failed (mutation executed, expected delta never appeared) · `4` blocked (hazard guard or disruption policy; error carries `remediation`) · `5` drift-blocked · `6` unsupported · `7` environment.
|
|
56
59
|
4. **Plan before executing**: every write supports `--dry-run` — compiled invocation (token-redacted), chosen vector, tier, hazards checked, expected delta. Nothing runs, nothing is audited.
|
|
57
60
|
5. **No prompts, ever**: risky semantics are explicit flags — `--children require-resolved|auto-complete` (project completion cascades), `--acknowledge-checklist-reset` (checklist replacement destroys per-item state), `--acknowledge-project-reopen` (open child reopens a resolved project), `--dangerously-permanent` (area/tag delete and empty-trash skip the Trash).
|
|
@@ -3,4 +3,27 @@
|
|
|
3
3
|
* under `things area` are registered by writes.ts on the same group).
|
|
4
4
|
*/
|
|
5
5
|
import type { Command } from "commander";
|
|
6
|
+
import type { AreaView } from "../../read/area-view.ts";
|
|
7
|
+
import { type GroupedLimits } from "../../read/pagination.ts";
|
|
8
|
+
export interface AreaShowOpts {
|
|
9
|
+
showLater?: boolean;
|
|
10
|
+
/** Commander optional-value flag: true when bare, the raw string when given a count. */
|
|
11
|
+
showLogged?: boolean | string;
|
|
12
|
+
/**
|
|
13
|
+
* Per-section caps: `project` bounds the project-ROWS section, `area` the
|
|
14
|
+
* direct-to-dos section (null = uncapped). The toggled later/logged
|
|
15
|
+
* sections keep their own existing bounds.
|
|
16
|
+
*/
|
|
17
|
+
limits?: GroupedLimits;
|
|
18
|
+
/** The user's invocation, echoed by the per-section truncation footers. */
|
|
19
|
+
hintBase?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* GUI layout: active projects first (sidebar order), then the area's direct
|
|
23
|
+
* to-dos. `--show-later` reveals the GUI's toggled sections — Upcoming
|
|
24
|
+
* (future-scheduled projects, to-dos, and repeating templates intermixed in
|
|
25
|
+
* date order) and Someday (someday projects as a leading block, then
|
|
26
|
+
* someday to-dos). `--show-logged` reveals the full logbook.
|
|
27
|
+
*/
|
|
28
|
+
export declare function renderAreaView(view: AreaView, opts: AreaShowOpts): string[];
|
|
6
29
|
export declare function registerAreaCommands(program: Command): void;
|
|
@@ -1,41 +1,121 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { ExitCode } from "../../contracts.js";
|
|
2
|
+
import { localToday } from "../../model/dates.js";
|
|
3
|
+
import { bold, dim, green } from "../style.js";
|
|
4
|
+
import { areaMark, thingsLink } from "../glyphs.js";
|
|
5
|
+
import { Option } from "commander";
|
|
6
|
+
import { capAreaSections } from "../../read/pagination.js";
|
|
7
|
+
import { openInThings } from "./reads.js";
|
|
8
|
+
import { invocation, parseCap, runRead, shellQuote, withClient } from "../read-driver.js";
|
|
9
|
+
import { formatItem, uuidDisplayWidth } from "../render.js";
|
|
10
|
+
import { DidYouMeanError } from "../did-you-mean.js";
|
|
11
|
+
import { showToggleFlags } from "./project.js";
|
|
12
|
+
import { AREA_PREVIEW_LIMIT, GROUPED_ALL_DESC } from "../../surface-copy.js";
|
|
13
|
+
/** Bare `--show-logged` shows this many recent entries (areas accumulate thousands). */
|
|
14
|
+
const RECENT_LOGGED_DEFAULT = 15;
|
|
15
|
+
function loggedCount(showLogged) {
|
|
16
|
+
if (showLogged === undefined)
|
|
17
|
+
return 0;
|
|
18
|
+
if (showLogged === true)
|
|
19
|
+
return RECENT_LOGGED_DEFAULT;
|
|
20
|
+
const n = Number(showLogged);
|
|
21
|
+
return Number.isInteger(n) && n > 0 ? n : RECENT_LOGGED_DEFAULT;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* GUI layout: active projects first (sidebar order), then the area's direct
|
|
25
|
+
* to-dos. `--show-later` reveals the GUI's toggled sections — Upcoming
|
|
26
|
+
* (future-scheduled projects, to-dos, and repeating templates intermixed in
|
|
27
|
+
* date order) and Someday (someday projects as a leading block, then
|
|
28
|
+
* someday to-dos). `--show-logged` reveals the full logbook.
|
|
29
|
+
*/
|
|
30
|
+
export function renderAreaView(view, opts) {
|
|
31
|
+
const todayIso = localToday();
|
|
32
|
+
// Closed-but-unswept projects always sit in the active block (checked),
|
|
33
|
+
// never in Upcoming/Someday — start/startDate only classify OPEN rows.
|
|
34
|
+
const isSomedayProject = (p) => p.status === "open" && p.start === "someday" && p.startDate === null;
|
|
35
|
+
const isScheduledProject = (p) => p.status === "open" && p.startDate !== null && p.startDate > todayIso;
|
|
36
|
+
const activeProjects = view.projects.filter((p) => !isSomedayProject(p) && !isScheduledProject(p));
|
|
37
|
+
const somedayProjects = view.projects.filter(isSomedayProject);
|
|
38
|
+
// Upcoming intermixes scheduled projects, scheduled to-dos, and repeating
|
|
39
|
+
// templates in date order (templates sort by their next occurrence).
|
|
40
|
+
const upcoming = [
|
|
41
|
+
...view.projects.filter(isScheduledProject).map((p) => ({ date: p.startDate ?? "", item: p })),
|
|
42
|
+
...view.later.scheduled.flatMap((d) => d.items.map((t) => ({ date: d.date, item: t }))),
|
|
43
|
+
...view.later.repeating.map((t) => ({ date: t.repeating.nextOccurrence ?? "9999", item: t })),
|
|
44
|
+
].sort((a, b) => a.date.localeCompare(b.date));
|
|
45
|
+
const logged = view.logged.slice(0, loggedCount(opts.showLogged));
|
|
46
|
+
const shown = [
|
|
47
|
+
...activeProjects,
|
|
5
48
|
...view.active,
|
|
6
|
-
...
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
...
|
|
10
|
-
...view.logged.slice(0, 10),
|
|
49
|
+
...(opts.showLater === true
|
|
50
|
+
? [...upcoming.map((u) => u.item), ...somedayProjects, ...view.later.someday]
|
|
51
|
+
: []),
|
|
52
|
+
...logged,
|
|
11
53
|
];
|
|
12
|
-
const w = uuidDisplayWidth(
|
|
54
|
+
const w = uuidDisplayWidth(shown);
|
|
55
|
+
// Per-section caps (this view's sections are containers, so there is no
|
|
56
|
+
// strict total limit): the project-ROWS block and the direct-to-dos block
|
|
57
|
+
// truncate independently, each with its own exact-count footer. The card
|
|
58
|
+
// preamble and the toggled later/logged sections are never capped here.
|
|
59
|
+
const limits = opts.limits ?? { area: null, project: null };
|
|
60
|
+
const shownProjects = limits.project === null ? activeProjects : activeProjects.slice(0, limits.project);
|
|
61
|
+
const shownActive = limits.area === null ? view.active : view.active.slice(0, limits.area);
|
|
62
|
+
const sectionMore = (hidden, noun, flag, cap) => {
|
|
63
|
+
if (hidden <= 0 || opts.hintBase === undefined || cap === null)
|
|
64
|
+
return;
|
|
65
|
+
lines.push(dim(` … ${hidden} more ${noun}${hidden === 1 ? "" : "s"} — \`${opts.hintBase} ${flag} ${cap * 2}\``));
|
|
66
|
+
};
|
|
13
67
|
// Rows inside this view never repeat the area's own name.
|
|
14
68
|
const fmt = (i) => formatItem(i, w, { suppressArea: view.area.uuid });
|
|
15
69
|
const fmtProject = (i) => formatItem(i, w, { projectTitle: true, suppressArea: view.area.uuid });
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const lines = [
|
|
20
|
-
|
|
21
|
-
|
|
70
|
+
// Card header: glyph + name, the GUI's share link (carries the uuid — it
|
|
71
|
+
// pastes back into any ref argument), then labeled meta lines. The opened
|
|
72
|
+
// resource shows its tags green (GUI: list pills are gray).
|
|
73
|
+
const lines = [
|
|
74
|
+
`${bold("Area:")} ${areaMark()} ${bold(view.area.title)}`,
|
|
75
|
+
` ${dim("uri:")} ${thingsLink(view.area.uuid)}`,
|
|
76
|
+
];
|
|
77
|
+
if (view.area.tags.length > 0)
|
|
78
|
+
lines.push(` ${dim("tags:")} ${green(`#${view.area.tags.map((t) => t.title).join(" #")}`)}`);
|
|
79
|
+
const block = (rows) => {
|
|
80
|
+
if (rows.length > 0)
|
|
81
|
+
lines.push("", ...rows);
|
|
22
82
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
lines.push("
|
|
83
|
+
block(shownProjects.map(fmtProject));
|
|
84
|
+
sectionMore(activeProjects.length - shownProjects.length, "project", "--project-limit", limits.project);
|
|
85
|
+
block(shownActive.map(fmt));
|
|
86
|
+
sectionMore(view.active.length - shownActive.length, "to-do", "--area-limit", limits.area);
|
|
87
|
+
if (activeProjects.length === 0 && view.active.length === 0)
|
|
88
|
+
lines.push("", "(no active items)");
|
|
89
|
+
if (opts.showLater === true) {
|
|
90
|
+
if (upcoming.length > 0) {
|
|
91
|
+
lines.push("", bold("── Upcoming ──"), ...upcoming.map((u) => fmt(u.item)));
|
|
32
92
|
}
|
|
33
|
-
if (view.later.someday.length) {
|
|
34
|
-
lines.push("
|
|
93
|
+
if (somedayProjects.length > 0 || view.later.someday.length > 0) {
|
|
94
|
+
lines.push("", bold("── Someday ──"), ...somedayProjects.map(fmtProject));
|
|
95
|
+
if (view.later.someday.length > 0) {
|
|
96
|
+
if (somedayProjects.length > 0)
|
|
97
|
+
lines.push("");
|
|
98
|
+
lines.push(...view.later.someday.map(fmt));
|
|
99
|
+
}
|
|
35
100
|
}
|
|
36
101
|
}
|
|
37
|
-
|
|
38
|
-
|
|
102
|
+
// Default-hidden rows are never silent — a muted count names the toggle.
|
|
103
|
+
if (opts.showLater !== true) {
|
|
104
|
+
const hiddenLater = upcoming.length + somedayProjects.length + view.later.someday.length;
|
|
105
|
+
if (hiddenLater > 0)
|
|
106
|
+
lines.push("", dim(`…${hiddenLater} later item${hiddenLater === 1 ? "" : "s"} (--show-later)`));
|
|
107
|
+
}
|
|
108
|
+
if (logged.length > 0) {
|
|
109
|
+
// Truncation is loud: areas accumulate years of history — the full
|
|
110
|
+
// archive belongs to `things logbook --area`.
|
|
111
|
+
const header = logged.length < view.logged.length
|
|
112
|
+
? `── Logged (${logged.length} of ${view.logged.length} — see things logbook --area) ──`
|
|
113
|
+
: `── Logged (${view.logged.length}) ──`;
|
|
114
|
+
lines.push("", bold(header), ...logged.map(fmt));
|
|
115
|
+
}
|
|
116
|
+
else if (view.logged.length > 0) {
|
|
117
|
+
lines.push("", dim(`…${view.logged.length} logged (--show-logged; full history: things logbook --area)`));
|
|
118
|
+
}
|
|
39
119
|
if (view.trashed.length)
|
|
40
120
|
lines.push("", bold(`── Trashed (${view.trashed.length}) ──`));
|
|
41
121
|
return lines;
|
|
@@ -44,13 +124,64 @@ export function registerAreaCommands(program) {
|
|
|
44
124
|
const area = program.command("area").description("Area-scoped operations");
|
|
45
125
|
area
|
|
46
126
|
.command("show <ref>")
|
|
47
|
-
.description("Composite area view mirroring the native UI:
|
|
48
|
-
"
|
|
49
|
-
"logged. Target by uuid or
|
|
127
|
+
.description("Composite area view mirroring the native UI: active projects first, then the " +
|
|
128
|
+
"area's direct to-dos. --show-later adds the Upcoming (date-ordered) and " +
|
|
129
|
+
"Someday sections; --show-logged adds the full logbook. Target by uuid or " +
|
|
130
|
+
"unique name.")
|
|
131
|
+
.option("--show-later", "include Upcoming and Someday sections")
|
|
132
|
+
.option("--show-logged [n]", "include the n most recently logged items (bare flag = 15; full history via `things logbook --area`)")
|
|
133
|
+
.option("--project-limit <n>", `maximum project rows to show (default ${AREA_PREVIEW_LIMIT})`)
|
|
134
|
+
.option("--area-limit <n>", `maximum direct to-dos to show (default ${AREA_PREVIEW_LIMIT})`)
|
|
135
|
+
.option("--all", GROUPED_ALL_DESC)
|
|
136
|
+
.addOption(new Option("--limit <n>").hideHelp())
|
|
137
|
+
.option("--json", "emit versioned JSON envelope on stdout")
|
|
138
|
+
.option("--db <path>", "explicit database path")
|
|
139
|
+
.action((ref, opts) => {
|
|
140
|
+
if (opts.limit !== undefined) {
|
|
141
|
+
process.stderr.write("error: --limit is not available on area show — cap sections with --area-limit / --project-limit, or pass --all\n");
|
|
142
|
+
process.exitCode = ExitCode.Usage;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const areaCap = parseCap("--area-limit", opts.areaLimit, AREA_PREVIEW_LIMIT, opts.all === true);
|
|
146
|
+
if (!areaCap.ok)
|
|
147
|
+
return;
|
|
148
|
+
const projectCap = parseCap("--project-limit", opts.projectLimit, AREA_PREVIEW_LIMIT, opts.all === true);
|
|
149
|
+
if (!projectCap.ok)
|
|
150
|
+
return;
|
|
151
|
+
const limits = { area: areaCap.limit, project: projectCap.limit };
|
|
152
|
+
const hintBase = invocation("area show", [shellQuote(ref), ...showToggleFlags(opts)]);
|
|
153
|
+
runRead(opts, "area-view", (c) => {
|
|
154
|
+
let view;
|
|
155
|
+
try {
|
|
156
|
+
view = c.read.areaView(ref);
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
// Not-found gets a type-scoped did-you-mean; ambiguity is verbatim.
|
|
160
|
+
if (err instanceof RangeError && !err.message.includes("ambiguous")) {
|
|
161
|
+
throw new DidYouMeanError(err.message, ref, c.read.liteTitleSearch(ref, { type: "area" }));
|
|
162
|
+
}
|
|
163
|
+
throw err;
|
|
164
|
+
}
|
|
165
|
+
const { data, grouped } = capAreaSections(view, limits);
|
|
166
|
+
return {
|
|
167
|
+
data,
|
|
168
|
+
grouped,
|
|
169
|
+
lines: renderAreaView(view, { ...opts, limits, hintBase }),
|
|
170
|
+
};
|
|
171
|
+
}, () => []);
|
|
172
|
+
});
|
|
173
|
+
area
|
|
174
|
+
.command("open <ref>")
|
|
175
|
+
.description("Open the area in the Things app — foregrounds the GUI on this Mac (NOT headless). Errors when the reference is not an area.")
|
|
50
176
|
.option("--json", "emit versioned JSON envelope on stdout")
|
|
51
177
|
.option("--db <path>", "explicit database path")
|
|
52
178
|
.action((ref, opts) => {
|
|
53
|
-
withClient(opts, "
|
|
179
|
+
withClient(opts, "open", (c) => {
|
|
180
|
+
const t = c.read.showTarget(ref);
|
|
181
|
+
if (t.kind !== "area")
|
|
182
|
+
throw new RangeError(`"${ref}" is a ${t.viaHeading === true ? "heading" : t.kind}, not an area (try \`things open\`)`);
|
|
183
|
+
return { uri: openInThings(t.uuid) };
|
|
184
|
+
}, (d) => [`opened ${d.uri}`]);
|
|
54
185
|
});
|
|
55
186
|
}
|
|
56
187
|
//# sourceMappingURL=area.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area.js","sourceRoot":"","sources":["../../../src/cli/commands/area.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"area.js","sourceRoot":"","sources":["../../../src/cli/commands/area.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,4 +2,23 @@
|
|
|
2
2
|
* `things project show <uuid>` — the composite project view.
|
|
3
3
|
*/
|
|
4
4
|
import type { Command } from "commander";
|
|
5
|
+
import type { ProjectView } from "../../read/project-view.ts";
|
|
6
|
+
export interface ProjectShowOpts {
|
|
7
|
+
showLater?: boolean;
|
|
8
|
+
/** Optional-value flag: bare = the FULL project logbook (finite lifespans), a count to cap it. */
|
|
9
|
+
showLogged?: boolean | string;
|
|
10
|
+
}
|
|
11
|
+
/** Reconstruct the show-toggle flags the user passed, for footer echoes. */
|
|
12
|
+
export declare function showToggleFlags(opts: {
|
|
13
|
+
showLater?: boolean;
|
|
14
|
+
showLogged?: boolean | string;
|
|
15
|
+
}): Array<string | false>;
|
|
16
|
+
/**
|
|
17
|
+
* GUI parity: later rows (scheduled / repeating / someday) render INLINE
|
|
18
|
+
* beneath their heading — dimmed boxes and date chips carry the state — not
|
|
19
|
+
* exiled to a separate section that disassociates them from their headings.
|
|
20
|
+
* They are hidden by default like the GUI's toggle; `--show-later` reveals
|
|
21
|
+
* them, `--show-logged` reveals the full logbook.
|
|
22
|
+
*/
|
|
23
|
+
export declare function renderProjectView(view: ProjectView, opts: ProjectShowOpts): string[];
|
|
5
24
|
export declare function registerProjectCommands(program: Command): void;
|
|
@@ -1,42 +1,120 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { localToday } from "../../model/dates.js";
|
|
2
|
+
import { bold, dim, green, underline } from "../style.js";
|
|
3
|
+
import { countChip, deadlineDetail, loggedDate, projectCircle, thingsLink, whenValue, } from "../glyphs.js";
|
|
4
|
+
import { openInThings } from "./reads.js";
|
|
5
|
+
import { runRead, withClient } from "../read-driver.js";
|
|
6
|
+
import { formatItem, uuidCol, uuidDisplayWidth } from "../render.js";
|
|
7
|
+
import { DidYouMeanError } from "../did-you-mean.js";
|
|
8
|
+
/** Reconstruct the show-toggle flags the user passed, for footer echoes. */
|
|
9
|
+
export function showToggleFlags(opts) {
|
|
10
|
+
return [
|
|
11
|
+
opts.showLater === true && "--show-later",
|
|
12
|
+
opts.showLogged === true && "--show-logged",
|
|
13
|
+
typeof opts.showLogged === "string" && `--show-logged ${opts.showLogged}`,
|
|
11
14
|
];
|
|
15
|
+
}
|
|
16
|
+
function loggedSlice(view, showLogged) {
|
|
17
|
+
if (showLogged === undefined)
|
|
18
|
+
return [];
|
|
19
|
+
if (showLogged === true)
|
|
20
|
+
return view.logged;
|
|
21
|
+
const n = Number(showLogged);
|
|
22
|
+
return Number.isInteger(n) && n > 0 ? view.logged.slice(0, n) : view.logged;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* GUI parity: later rows (scheduled / repeating / someday) render INLINE
|
|
26
|
+
* beneath their heading — dimmed boxes and date chips carry the state — not
|
|
27
|
+
* exiled to a separate section that disassociates them from their headings.
|
|
28
|
+
* They are hidden by default like the GUI's toggle; `--show-later` reveals
|
|
29
|
+
* them, `--show-logged` reveals the full logbook.
|
|
30
|
+
*/
|
|
31
|
+
export function renderProjectView(view, opts) {
|
|
32
|
+
const later = opts.showLater === true
|
|
33
|
+
? [
|
|
34
|
+
...view.later.scheduled.flatMap((d) => d.items),
|
|
35
|
+
...view.later.repeating,
|
|
36
|
+
...view.later.someday,
|
|
37
|
+
]
|
|
38
|
+
: [];
|
|
39
|
+
const knownHeadings = new Set(view.headings.map((g) => g.heading.uuid));
|
|
40
|
+
const laterByHeading = new Map();
|
|
41
|
+
const looseLater = [];
|
|
42
|
+
for (const item of later) {
|
|
43
|
+
// A later row whose heading is absent from the view falls back to the
|
|
44
|
+
// loose block rather than vanishing.
|
|
45
|
+
if (item.heading !== null && knownHeadings.has(item.heading.uuid)) {
|
|
46
|
+
const list = laterByHeading.get(item.heading.uuid) ?? [];
|
|
47
|
+
list.push(item);
|
|
48
|
+
laterByHeading.set(item.heading.uuid, list);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
looseLater.push(item);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const logged = loggedSlice(view, opts.showLogged);
|
|
55
|
+
const everyItem = [...view.active, ...later, ...view.headings.flatMap((g) => g.items), ...logged];
|
|
12
56
|
const w = uuidDisplayWidth([...everyItem, ...view.headings.map((g) => g.heading)]);
|
|
13
57
|
// Rows inside this view never repeat the project's own name.
|
|
14
58
|
const fmt = (i) => formatItem(i, w, { suppressProject: view.project.uuid });
|
|
59
|
+
// Card header, GUI order: title row (circle, progress chip, area context),
|
|
60
|
+
// share link, then labeled when/deadline/tags lines and the full note.
|
|
61
|
+
// The opened resource shows its tags green (GUI: list pills are gray).
|
|
62
|
+
const p = view.project;
|
|
63
|
+
const todayIso = localToday();
|
|
64
|
+
const areaSuffix = p.area === null ? "" : ` ${dim(`(${p.area.title})`)}`;
|
|
65
|
+
// In the Trash the card says so — the only view where the project's
|
|
66
|
+
// would-be-recovered (untrashed) children remain visible.
|
|
67
|
+
const trashedSuffix = p.trashed ? ` ${dim("(trashed)")}` : "";
|
|
15
68
|
const lines = [
|
|
16
|
-
`${
|
|
17
|
-
`
|
|
69
|
+
`${bold("Project:")} ${projectCircle(p)} ${bold(underline(p.title))} ${countChip(p)}${areaSuffix}${trashedSuffix}`,
|
|
70
|
+
` ${dim("uri:")} ${thingsLink(p.uuid)}`,
|
|
18
71
|
];
|
|
19
|
-
|
|
72
|
+
if (p.status === "open") {
|
|
73
|
+
const when = whenValue(p, todayIso);
|
|
74
|
+
if (when !== null)
|
|
75
|
+
lines.push(` ${dim("when:")} ${when}`);
|
|
76
|
+
}
|
|
77
|
+
if (p.deadline !== null && p.deadline < "4000" && p.status === "open")
|
|
78
|
+
lines.push(` ${dim("deadline:")} ${deadlineDetail(p.deadline, todayIso)}`);
|
|
79
|
+
if (p.status !== "open" && p.stopped !== null)
|
|
80
|
+
lines.push(` ${dim("logged:")} ${loggedDate(p.stopped, todayIso)} ${dim(`(${p.status})`)}`);
|
|
81
|
+
if (p.tags.length > 0)
|
|
82
|
+
lines.push(` ${dim("tags:")} ${green(`#${p.tags.map((t) => t.title).join(" #")}`)}`);
|
|
83
|
+
if (p.inheritedTags !== undefined && p.inheritedTags.length > 0)
|
|
84
|
+
lines.push(` ${dim("inherited:")} ${green(`#${p.inheritedTags.map((t) => t.title).join(" #")}`)}`);
|
|
85
|
+
if (p.repeating.isTemplate)
|
|
86
|
+
lines.push(` ${dim("repeating:")} TEMPLATE (invisible in list views)`);
|
|
87
|
+
if (p.repeating.isInstance)
|
|
88
|
+
lines.push(` ${dim("repeating:")} instance of ${p.repeating.templateUuid}`);
|
|
89
|
+
if (p.notes !== "")
|
|
90
|
+
lines.push("", p.notes);
|
|
91
|
+
const looseRows = [...view.active, ...looseLater];
|
|
92
|
+
if (looseRows.length > 0)
|
|
93
|
+
lines.push("", ...looseRows.map(fmt));
|
|
20
94
|
for (const group of view.headings) {
|
|
21
95
|
// Headings are the GUI's dim in-project subheads, not structural
|
|
22
96
|
// sections — rendered like item rows (their uuid IS addressable:
|
|
23
97
|
// heading rename/archive), title dim+underlined.
|
|
24
|
-
|
|
98
|
+
const members = [...group.items, ...(laterByHeading.get(group.heading.uuid) ?? [])];
|
|
99
|
+
lines.push("", `${dim(uuidCol(group.heading.uuid, w))} ${dim(underline(group.heading.title))}`, ...(members.length > 0 ? members.map(fmt) : ["(none)"]));
|
|
25
100
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (
|
|
32
|
-
lines.push("
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
101
|
+
// Default-hidden rows are never silent — a muted count names the toggle.
|
|
102
|
+
if (opts.showLater !== true) {
|
|
103
|
+
const hiddenLater = view.later.scheduled.reduce((n, d) => n + d.items.length, 0) +
|
|
104
|
+
view.later.repeating.length +
|
|
105
|
+
view.later.someday.length;
|
|
106
|
+
if (hiddenLater > 0)
|
|
107
|
+
lines.push("", dim(`…${hiddenLater} later item${hiddenLater === 1 ? "" : "s"} (--show-later)`));
|
|
108
|
+
}
|
|
109
|
+
if (logged.length > 0) {
|
|
110
|
+
const header = logged.length < view.logged.length
|
|
111
|
+
? `── Logged (${logged.length} of ${view.logged.length}) ──`
|
|
112
|
+
: `── Logged (${view.logged.length}) ──`;
|
|
113
|
+
lines.push("", bold(header), ...logged.map(fmt));
|
|
114
|
+
}
|
|
115
|
+
else if (view.logged.length > 0) {
|
|
116
|
+
lines.push("", dim(`…${view.logged.length} logged (--show-logged)`));
|
|
37
117
|
}
|
|
38
|
-
if (view.logged.length)
|
|
39
|
-
lines.push("", bold(`── Logged (${view.logged.length}) ──`), ...view.logged.slice(0, 10).map(fmt));
|
|
40
118
|
if (view.trashed.length)
|
|
41
119
|
lines.push("", bold(`── Trashed (${view.trashed.length}) ──`));
|
|
42
120
|
return lines;
|
|
@@ -45,11 +123,46 @@ export function registerProjectCommands(program) {
|
|
|
45
123
|
const project = program.command("project").description("Project-scoped operations");
|
|
46
124
|
project
|
|
47
125
|
.command("show <ref>")
|
|
48
|
-
.description("Composite project view mirroring the native UI: active items
|
|
126
|
+
.description("Composite project view mirroring the native UI: active items and headings. --show-later adds scheduled/repeating/someday rows inline under their headings; --show-logged adds the full logbook. Target by uuid or unique name.")
|
|
127
|
+
.option("--show-later", "include scheduled, repeating, and someday rows")
|
|
128
|
+
.option("--show-logged [n]", "include logged items (bare flag = all; pass a count to cap)")
|
|
129
|
+
.option("--all", "reveal the later rows (same as --show-later; logged stays behind --show-logged)")
|
|
130
|
+
.option("--json", "emit versioned JSON envelope on stdout")
|
|
131
|
+
.option("--db <path>", "explicit database path")
|
|
132
|
+
.action((ref, rawOpts) => {
|
|
133
|
+
// --all lifts the view's own default restriction (the hidden later rows).
|
|
134
|
+
// Logged is a SEPARATE content class and stays behind --show-logged.
|
|
135
|
+
const opts = {
|
|
136
|
+
...rawOpts,
|
|
137
|
+
showLater: rawOpts.showLater === true || rawOpts.all === true,
|
|
138
|
+
};
|
|
139
|
+
runRead(opts, "project-view", (c) => {
|
|
140
|
+
try {
|
|
141
|
+
return { data: c.read.projectView(ref) };
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
// Not-found gets a type-scoped did-you-mean; ambiguity is verbatim.
|
|
145
|
+
if (err instanceof RangeError && !err.message.includes("ambiguous")) {
|
|
146
|
+
throw new DidYouMeanError(err.message, ref, c.read.liteTitleSearch(ref, { type: "project" }));
|
|
147
|
+
}
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
}, (d) => renderProjectView(d, opts));
|
|
151
|
+
});
|
|
152
|
+
project
|
|
153
|
+
.command("open <ref>")
|
|
154
|
+
.description("Open the project in the Things app — foregrounds the GUI on this Mac (NOT headless). Errors when the reference is not a project.")
|
|
49
155
|
.option("--json", "emit versioned JSON envelope on stdout")
|
|
50
156
|
.option("--db <path>", "explicit database path")
|
|
51
157
|
.action((ref, opts) => {
|
|
52
|
-
withClient(opts, "
|
|
158
|
+
withClient(opts, "open", (c) => {
|
|
159
|
+
const t = c.read.showTarget(ref);
|
|
160
|
+
if (t.kind !== "project" || t.viaHeading === true) {
|
|
161
|
+
const what = t.viaHeading === true ? "heading" : t.kind;
|
|
162
|
+
throw new RangeError(`"${ref}" is a ${what}, not a project (try \`things open\`)`);
|
|
163
|
+
}
|
|
164
|
+
return { uri: openInThings(t.uuid) };
|
|
165
|
+
}, (d) => [`opened ${d.uri}`]);
|
|
53
166
|
});
|
|
54
167
|
}
|
|
55
168
|
//# sourceMappingURL=project.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/cli/commands/project.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/cli/commands/project.ts"],"names":[],"mappings":"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"}
|