things-api 0.9.0 → 0.11.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 +57 -12
- package/dist/audit/log.js +56 -2
- package/dist/audit/log.js.map +1 -1
- package/dist/audit/schema.d.ts +26 -8
- package/dist/audit/schema.js +42 -1
- package/dist/audit/schema.js.map +1 -1
- package/dist/cli/clock.d.ts +8 -0
- package/dist/cli/clock.js +24 -0
- package/dist/cli/clock.js.map +1 -0
- package/dist/cli/commands/area.d.ts +26 -3
- package/dist/cli/commands/area.js +129 -75
- package/dist/cli/commands/area.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +1 -1
- package/dist/cli/commands/doctor.js +44 -5
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/install-skill.d.ts +45 -0
- package/dist/cli/commands/install-skill.js +207 -0
- package/dist/cli/commands/install-skill.js.map +1 -0
- package/dist/cli/commands/mcp.js +23 -4
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/project.d.ts +18 -1
- package/dist/cli/commands/project.js +74 -35
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/reads.d.ts +15 -2
- package/dist/cli/commands/reads.js +459 -165
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/repeat-flags.d.ts +20 -0
- package/dist/cli/commands/repeat-flags.js +76 -0
- package/dist/cli/commands/repeat-flags.js.map +1 -0
- package/dist/cli/commands/setup.js +8 -4
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/show.js +53 -30
- package/dist/cli/commands/show.js.map +1 -1
- package/dist/cli/commands/todo.d.ts +1 -1
- package/dist/cli/commands/todo.js +20 -13
- package/dist/cli/commands/todo.js.map +1 -1
- package/dist/cli/commands/writes.js +388 -161
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/did-you-mean.d.ts +1 -1
- package/dist/cli/excess-args.d.ts +15 -0
- package/dist/cli/excess-args.js +51 -0
- package/dist/cli/excess-args.js.map +1 -0
- package/dist/cli/glyphs.d.ts +55 -2
- package/dist/cli/glyphs.js +114 -21
- package/dist/cli/glyphs.js.map +1 -1
- package/dist/cli/help.d.ts +54 -0
- package/dist/cli/help.js +405 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/main.js +64 -26
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/move-hint.d.ts +45 -0
- package/dist/cli/move-hint.js +196 -0
- package/dist/cli/move-hint.js.map +1 -0
- package/dist/cli/period.d.ts +9 -8
- package/dist/cli/period.js +56 -30
- package/dist/cli/period.js.map +1 -1
- package/dist/cli/read-driver.d.ts +26 -19
- package/dist/cli/read-driver.js +77 -33
- package/dist/cli/read-driver.js.map +1 -1
- package/dist/cli/render.d.ts +92 -28
- package/dist/cli/render.js +333 -103
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/resolve-invocation.d.ts +42 -4
- package/dist/cli/resolve-invocation.js +97 -14
- package/dist/cli/resolve-invocation.js.map +1 -1
- package/dist/cli/skill-check.d.ts +21 -0
- package/dist/cli/skill-check.js +82 -0
- package/dist/cli/skill-check.js.map +1 -0
- package/dist/cli/skill.d.ts +62 -0
- package/dist/cli/skill.js +142 -0
- package/dist/cli/skill.js.map +1 -0
- package/dist/cli/tag-filters.d.ts +63 -0
- package/dist/cli/tag-filters.js +59 -0
- package/dist/cli/tag-filters.js.map +1 -0
- package/dist/cli/verb-hint.d.ts +25 -0
- package/dist/cli/verb-hint.js +163 -0
- package/dist/cli/verb-hint.js.map +1 -0
- package/dist/cli/version.d.ts +4 -0
- package/dist/cli/version.js +18 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/cli/width.d.ts +135 -0
- package/dist/cli/width.js +313 -0
- package/dist/cli/width.js.map +1 -0
- package/dist/client.d.ts +160 -24
- package/dist/client.js +132 -19
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/contracts.d.ts +97 -17
- package/dist/contracts.js +44 -1
- package/dist/contracts.js.map +1 -1
- package/dist/db/fingerprint.d.ts +12 -0
- package/dist/db/fingerprint.js +15 -1
- package/dist/db/fingerprint.js.map +1 -1
- package/dist/db/locate.js +1 -1
- package/dist/db/locate.js.map +1 -1
- package/dist/diagnose.d.ts +63 -0
- package/dist/diagnose.js +38 -1
- package/dist/diagnose.js.map +1 -1
- package/dist/index.d.ts +36 -5
- package/dist/index.js +38 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +9 -1
- package/dist/mcp/server.js +1038 -436
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/clock.d.ts +61 -0
- package/dist/model/clock.js +71 -0
- package/dist/model/clock.js.map +1 -0
- package/dist/model/dates.d.ts +26 -3
- package/dist/model/dates.js +84 -3
- package/dist/model/dates.js.map +1 -1
- package/dist/model/entities.d.ts +48 -10
- package/dist/model/entities.js.map +1 -1
- package/dist/model/mappers.d.ts +9 -2
- package/dist/model/mappers.js +32 -9
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/serialize.d.ts +28 -0
- package/dist/model/serialize.js +80 -0
- package/dist/model/serialize.js.map +1 -0
- package/dist/model/when-sugar.d.ts +47 -0
- package/dist/model/when-sugar.js +45 -0
- package/dist/model/when-sugar.js.map +1 -0
- package/dist/read/area-view.d.ts +8 -1
- package/dist/read/area-view.js +55 -17
- package/dist/read/area-view.js.map +1 -1
- package/dist/read/detail.d.ts +1 -1
- package/dist/read/detail.js +11 -4
- package/dist/read/detail.js.map +1 -1
- package/dist/read/filter-contract.d.ts +117 -0
- package/dist/read/filter-contract.js +78 -0
- package/dist/read/filter-contract.js.map +1 -0
- package/dist/read/log-boundary.d.ts +1 -1
- package/dist/read/log-boundary.js +13 -3
- package/dist/read/log-boundary.js.map +1 -1
- package/dist/read/predicates.d.ts +30 -0
- package/dist/read/predicates.js +30 -0
- package/dist/read/predicates.js.map +1 -1
- package/dist/read/project-view.d.ts +12 -1
- package/dist/read/project-view.js +45 -12
- package/dist/read/project-view.js.map +1 -1
- package/dist/read/queries.d.ts +152 -7
- package/dist/read/queries.js +277 -36
- package/dist/read/queries.js.map +1 -1
- package/dist/read/sections.d.ts +51 -0
- package/dist/read/sections.js +37 -0
- package/dist/read/sections.js.map +1 -0
- package/dist/read/sidebar-order.js +2 -1
- package/dist/read/sidebar-order.js.map +1 -1
- package/dist/read/snapshot.d.ts +1 -1
- package/dist/read/snapshot.js +9 -2
- package/dist/read/snapshot.js.map +1 -1
- package/dist/read/tags.d.ts +27 -3
- package/dist/read/tags.js +83 -12
- package/dist/read/tags.js.map +1 -1
- package/dist/read/truncation.d.ts +71 -0
- package/dist/read/{pagination.js → truncation.js} +103 -94
- package/dist/read/truncation.js.map +1 -0
- package/dist/read/views.d.ts +147 -22
- package/dist/read/views.js +282 -80
- package/dist/read/views.js.map +1 -1
- package/dist/surface-copy.d.ts +19 -0
- package/dist/surface-copy.js +32 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/sync-health.d.ts +78 -0
- package/dist/sync-health.js +312 -0
- package/dist/sync-health.js.map +1 -0
- package/dist/write/accessibility-probe.d.ts +12 -0
- package/dist/write/accessibility-probe.js +71 -0
- package/dist/write/accessibility-probe.js.map +1 -0
- package/dist/write/automation-probe.d.ts +8 -1
- package/dist/write/automation-probe.js +16 -1
- package/dist/write/automation-probe.js.map +1 -1
- package/dist/write/batch.js +5 -2
- package/dist/write/batch.js.map +1 -1
- package/dist/write/capabilities.d.ts +8 -0
- package/dist/write/capabilities.js +13 -6
- package/dist/write/capabilities.js.map +1 -1
- package/dist/write/commands.d.ts +3 -1
- package/dist/write/commands.js +602 -49
- package/dist/write/commands.js.map +1 -1
- package/dist/write/edit-checklist.js +3 -2
- package/dist/write/edit-checklist.js.map +1 -1
- package/dist/write/guards.d.ts +2 -7
- package/dist/write/guards.js +87 -6
- package/dist/write/guards.js.map +1 -1
- package/dist/write/heading.js +2 -0
- package/dist/write/heading.js.map +1 -1
- package/dist/write/lock.d.ts +40 -2
- package/dist/write/lock.js +91 -14
- package/dist/write/lock.js.map +1 -1
- package/dist/write/make-repeating-project.d.ts +4 -0
- package/dist/write/make-repeating-project.js +253 -0
- package/dist/write/make-repeating-project.js.map +1 -0
- package/dist/write/operations.d.ts +145 -1
- package/dist/write/operations.js +48 -0
- package/dist/write/operations.js.map +1 -1
- package/dist/write/pipeline.d.ts +73 -2
- package/dist/write/pipeline.js +218 -43
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/planner.js +8 -1
- package/dist/write/planner.js.map +1 -1
- package/dist/write/pre-state.d.ts +105 -3
- package/dist/write/pre-state.js +144 -3
- package/dist/write/pre-state.js.map +1 -1
- package/dist/write/recurrence-rule-blob.d.ts +65 -0
- package/dist/write/recurrence-rule-blob.js +150 -0
- package/dist/write/recurrence-rule-blob.js.map +1 -0
- package/dist/write/reopen.js +3 -2
- package/dist/write/reopen.js.map +1 -1
- package/dist/write/reorder.js +27 -17
- package/dist/write/reorder.js.map +1 -1
- package/dist/write/repeat-rule.d.ts +22 -0
- package/dist/write/repeat-rule.js +258 -0
- package/dist/write/repeat-rule.js.map +1 -0
- package/dist/write/reversibility.js +49 -0
- package/dist/write/reversibility.js.map +1 -1
- package/dist/write/tag-refs.d.ts +47 -0
- package/dist/write/tag-refs.js +126 -0
- package/dist/write/tag-refs.js.map +1 -0
- package/dist/write/undo.d.ts +74 -5
- package/dist/write/undo.js +493 -80
- package/dist/write/undo.js.map +1 -1
- package/dist/write/vectors/registry.d.ts +15 -1
- package/dist/write/vectors/registry.js +65 -2
- package/dist/write/vectors/registry.js.map +1 -1
- package/dist/write/vectors/simulator.d.ts +44 -0
- package/dist/write/vectors/simulator.js +1136 -0
- package/dist/write/vectors/simulator.js.map +1 -0
- package/dist/write/vectors/types.d.ts +154 -3
- package/dist/write/vectors/ui-certification.d.ts +54 -0
- package/dist/write/vectors/ui-certification.js +43 -0
- package/dist/write/vectors/ui-certification.js.map +1 -0
- package/dist/write/vectors/ui-drag.d.ts +188 -0
- package/dist/write/vectors/ui-drag.js +1095 -0
- package/dist/write/vectors/ui-drag.js.map +1 -0
- package/dist/write/vectors/ui-recipes.d.ts +83 -0
- package/dist/write/vectors/ui-recipes.js +610 -0
- package/dist/write/vectors/ui-recipes.js.map +1 -0
- package/dist/write/vectors/ui.d.ts +152 -0
- package/dist/write/vectors/ui.js +704 -0
- package/dist/write/vectors/ui.js.map +1 -0
- package/dist/write/verify/delta.d.ts +141 -4
- package/dist/write/verify/delta.js +199 -21
- package/dist/write/verify/delta.js.map +1 -1
- package/dist/write/verify/poller.d.ts +7 -1
- package/dist/write/verify/poller.js +21 -1
- package/dist/write/verify/poller.js.map +1 -1
- package/package.json +18 -3
- package/skills/things-cli/SKILL.md +53 -0
- package/skills/things-cli/references/contracts.md +41 -0
- package/skills/things-cli/references/gui.md +11 -0
- package/skills/things-cli/references/model.md +51 -0
- package/dist/cli/exit-codes.d.ts +0 -26
- package/dist/cli/exit-codes.js +0 -26
- package/dist/cli/exit-codes.js.map +0 -1
- package/dist/cli/output.d.ts +0 -42
- package/dist/cli/output.js +0 -16
- package/dist/cli/output.js.map +0 -1
- package/dist/read/pagination.d.ts +0 -104
- package/dist/read/pagination.js.map +0 -1
package/dist/model/entities.d.ts
CHANGED
|
@@ -12,6 +12,27 @@ export type TaskType = "to-do" | "project" | "heading";
|
|
|
12
12
|
export interface Ref {
|
|
13
13
|
uuid: string;
|
|
14
14
|
title: string;
|
|
15
|
+
/**
|
|
16
|
+
* Set (and only ever `true`) when this ref points at a repeating-template
|
|
17
|
+
* PROJECT — the blueprint row whose `rt1_recurrenceRule`/`repeater` is
|
|
18
|
+
* non-null (probe-verified: the template's CHILDREN are plain rows, so the
|
|
19
|
+
* fact lives on the parent project). Only container/project refs ever carry
|
|
20
|
+
* it — area and heading refs never do — so a consumer reads its absence as
|
|
21
|
+
* "not a template". It disambiguates the two identical-looking same-title
|
|
22
|
+
* copies a project conversion leaves behind (the template blueprint vs. its
|
|
23
|
+
* spawned instance; see RepeatingInfo). Omitted when false (never `false`).
|
|
24
|
+
*/
|
|
25
|
+
isRepeatingTemplate?: true;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A surfaced tag: its NAME only. Tag uuids are a fully internal implementation
|
|
29
|
+
* detail (like checklist item ids) — names are app-enforced-unique (TAGW1-c),
|
|
30
|
+
* so a name is a sufficient reference, and no surface emits or accepts a tag
|
|
31
|
+
* uuid. Nested-tag context, where it matters, is conveyed by the tag listing's
|
|
32
|
+
* `parent` field, not here on the pill.
|
|
33
|
+
*/
|
|
34
|
+
export interface TagRef {
|
|
35
|
+
title: string;
|
|
15
36
|
}
|
|
16
37
|
export interface RepeatingInfo {
|
|
17
38
|
/** This row is a repeating template (rt1_recurrenceRule / repeater present). Invisible in normal lists. */
|
|
@@ -51,19 +72,29 @@ interface TaskCommon {
|
|
|
51
72
|
/** The "When" date (packed int in DB), null when unscheduled. */
|
|
52
73
|
startDate: IsoDate | null;
|
|
53
74
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
75
|
+
* Today-view section ("today" | "evening"), emitted ONLY for items actually
|
|
76
|
+
* in Today under the evaluation clock: start=active, dated, and not
|
|
77
|
+
* future-scheduled (overdue rows stay in Today). Anytime (undated) and
|
|
78
|
+
* Upcoming (future startDate) rows carry a raw startBucket in the DB but are
|
|
79
|
+
* NOT in Today, so the field is null (omitted) for them. Use
|
|
80
|
+
* TodayView.evening for UI-faithful placement.
|
|
57
81
|
*/
|
|
58
82
|
todaySection: TodaySection | null;
|
|
59
83
|
deadline: IsoDate | null;
|
|
60
84
|
/** Time-of-day reminder (`HH:mm`, 24h); requires a scheduled startDate. */
|
|
61
85
|
reminder: ReminderTime | null;
|
|
62
86
|
area: Ref | null;
|
|
63
|
-
/** Direct tags only — mirrors DB truth (inherited tags are computed; see inheritedTags). */
|
|
64
|
-
tags:
|
|
65
|
-
/**
|
|
66
|
-
|
|
87
|
+
/** Direct tags only, by name — mirrors DB truth (inherited tags are computed; see inheritedTags). */
|
|
88
|
+
tags: TagRef[];
|
|
89
|
+
/**
|
|
90
|
+
* Tags inherited from an ancestor project/area, by NAME — a plain list
|
|
91
|
+
* parallel to {@link tags} (native UI tag filtering includes these — T18).
|
|
92
|
+
* Populated on the detail/card reads (`todo show`, `project show`) as an
|
|
93
|
+
* array (empty when there are none); the emit-time omit-empty transform (#163)
|
|
94
|
+
* drops it from JSON when empty, and it is absent (undefined) on list rows,
|
|
95
|
+
* which surface direct tags only. Never merged into {@link tags}.
|
|
96
|
+
*/
|
|
97
|
+
inheritedTags?: TagRef[];
|
|
67
98
|
repeating: RepeatingInfo;
|
|
68
99
|
created: Date;
|
|
69
100
|
modified: Date;
|
|
@@ -102,13 +133,20 @@ export interface Area {
|
|
|
102
133
|
uuid: string;
|
|
103
134
|
title: string;
|
|
104
135
|
visible: boolean;
|
|
105
|
-
tags:
|
|
136
|
+
tags: TagRef[];
|
|
106
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* A tag in the `things tags` taxonomy listing. Uuid-free (an internal detail):
|
|
140
|
+
* the tree is conveyed by `parent` — the parent tag's NAME (null for a root) —
|
|
141
|
+
* so a consumer can reconstruct the hierarchy, and by indentation in the human
|
|
142
|
+
* render. Names are globally unique (TAGW1-c), so the leaf name alone is a
|
|
143
|
+
* usable tag reference.
|
|
144
|
+
*/
|
|
107
145
|
export interface Tag {
|
|
108
|
-
uuid: string;
|
|
109
146
|
title: string;
|
|
110
147
|
shortcut: string | null;
|
|
111
|
-
|
|
148
|
+
/** Parent tag's NAME, or null for a root tag. */
|
|
149
|
+
parent: string | null;
|
|
112
150
|
}
|
|
113
151
|
/**
|
|
114
152
|
* A checklist item as the API surfaces it: title + status only. The DB uuid
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../../src/model/entities.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entities.js","sourceRoot":"","sources":["../../src/model/entities.ts"],"names":[],"mappings":"AAsLA,0EAA0E;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAA6B;IACzD,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,SAAS;IACZ,CAAC,EAAE,SAAS;CACb,CAAC;AACF,MAAM,CAAC,MAAM,mBAAmB,GAA+B;IAC7D,CAAC,EAAE,MAAM;IACT,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,WAAW;CACf,CAAC;AACF,MAAM,CAAC,MAAM,mBAAmB,GAA+B;IAC7D,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,QAAQ;IACX,CAAC,EAAE,SAAS;CACb,CAAC;AACF,MAAM,CAAC,MAAM,qBAAqB,GAAiC;IACjE,CAAC,EAAE,OAAO;IACV,CAAC,EAAE,SAAS;CACb,CAAC"}
|
package/dist/model/mappers.d.ts
CHANGED
|
@@ -22,6 +22,13 @@ export interface TaskRow {
|
|
|
22
22
|
index: number | null;
|
|
23
23
|
todayIndex: number | null;
|
|
24
24
|
area: string | null;
|
|
25
|
+
/**
|
|
26
|
+
* The row's EFFECTIVE area (queries.ts EFFECTIVE_AREA): its own `area`, else
|
|
27
|
+
* its project's, else its heading's project's. Equals `area` for projects and
|
|
28
|
+
* for area-direct to-dos; resolves the container's area for nested to-dos
|
|
29
|
+
* (whose own `area` is NULL). Surfaced as the entity's `area` Ref.
|
|
30
|
+
*/
|
|
31
|
+
effectiveArea: string | null;
|
|
25
32
|
project: string | null;
|
|
26
33
|
heading: string | null;
|
|
27
34
|
untrashedLeafActionsCount: number | null;
|
|
@@ -49,7 +56,7 @@ export type RefResolver = (uuid: string | null) => Ref | null;
|
|
|
49
56
|
export declare class EnumDomainError extends RangeError {
|
|
50
57
|
constructor(field: string, value: unknown, uuid: string);
|
|
51
58
|
}
|
|
52
|
-
export declare function mapTodo(row: TaskRow, refs: RefResolver, tags: Ref[]): Todo;
|
|
53
|
-
export declare function mapProject(row: TaskRow, refs: RefResolver, tags: Ref[]): Project;
|
|
59
|
+
export declare function mapTodo(row: TaskRow, refs: RefResolver, tags: Ref[], packedToday: number): Todo;
|
|
60
|
+
export declare function mapProject(row: TaskRow, refs: RefResolver, tags: Ref[], packedToday: number): Project;
|
|
54
61
|
export declare function mapHeading(row: TaskRow, refs: RefResolver): Heading;
|
|
55
62
|
export declare function mapChecklistItem(row: ChecklistRow): ChecklistItem;
|
package/dist/model/mappers.js
CHANGED
|
@@ -23,12 +23,30 @@ function mapStart(row) {
|
|
|
23
23
|
throw new EnumDomainError("start", row.start, row.uuid);
|
|
24
24
|
return start;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* `todaySection` is meaningful ONLY for items actually in the Today view. The
|
|
28
|
+
* DB stores a raw `startBucket` (0/1) on EVERY active row — prod carries
|
|
29
|
+
* startBucket=0 on every undated Anytime to-do, and future-scheduled
|
|
30
|
+
* (Upcoming) rows carry it too — so the raw bucket cannot be surfaced as-is:
|
|
31
|
+
* emitting "today" for an Anytime/Upcoming item wrongly implies Today
|
|
32
|
+
* membership (architecture.md; the MCP server note). We gate on the injected
|
|
33
|
+
* clock's `packedToday`: the field is emitted only when the row is active,
|
|
34
|
+
* dated, and not future-scheduled ("evening" via startBucket=1, else "today");
|
|
35
|
+
* overdue scheduled rows (startDate < today) stay in Today and keep it.
|
|
36
|
+
* Undated or future-dated rows OMIT the field (null).
|
|
37
|
+
*/
|
|
38
|
+
function mapTodaySection(row, packedToday) {
|
|
27
39
|
if (row.startBucket === null)
|
|
28
40
|
return null;
|
|
29
41
|
const section = TODAY_SECTION_FROM_DB[row.startBucket];
|
|
30
42
|
if (!section)
|
|
31
43
|
throw new EnumDomainError("startBucket", row.startBucket, row.uuid);
|
|
44
|
+
if ((row.start ?? 0) !== 1)
|
|
45
|
+
return null; // not start=active → not in Today
|
|
46
|
+
if (row.startDate === null)
|
|
47
|
+
return null; // undated (Anytime)
|
|
48
|
+
if (row.startDate > packedToday)
|
|
49
|
+
return null; // future startDate (Upcoming)
|
|
32
50
|
return section;
|
|
33
51
|
}
|
|
34
52
|
function mapRepeating(row) {
|
|
@@ -47,7 +65,7 @@ function mapRepeating(row) {
|
|
|
47
65
|
}
|
|
48
66
|
return info;
|
|
49
67
|
}
|
|
50
|
-
function commonFields(row, refs, tags) {
|
|
68
|
+
function commonFields(row, refs, tags, packedToday) {
|
|
51
69
|
return {
|
|
52
70
|
uuid: row.uuid,
|
|
53
71
|
title: row.title ?? "",
|
|
@@ -60,7 +78,7 @@ function commonFields(row, refs, tags) {
|
|
|
60
78
|
trashed: row.trashed === 1,
|
|
61
79
|
start: mapStart(row),
|
|
62
80
|
startDate: decodePackedDate(row.startDate),
|
|
63
|
-
todaySection: mapTodaySection(row),
|
|
81
|
+
todaySection: mapTodaySection(row, packedToday),
|
|
64
82
|
// A template's own `deadline` column is not a real date: it is NULL
|
|
65
83
|
// (deadline-less) or a far-future sentinel (4001-01-01, deadlined) that
|
|
66
84
|
// flags whether spawned instances deadline. Surface it via
|
|
@@ -69,17 +87,22 @@ function commonFields(row, refs, tags) {
|
|
|
69
87
|
? null
|
|
70
88
|
: decodePackedDate(row.deadline),
|
|
71
89
|
reminder: decodeReminderTime(row.reminderTime),
|
|
72
|
-
area:
|
|
73
|
-
|
|
90
|
+
// The EFFECTIVE area: a to-do nested in a project (own `area` NULL) reports
|
|
91
|
+
// its container's area, restoring useful area info omit-empty (#163) would
|
|
92
|
+
// otherwise hide. Projects and area-direct to-dos are unaffected (effective
|
|
93
|
+
// == direct). Direct-vs-inherited stays derivable from project/heading.
|
|
94
|
+
area: refs(row.effectiveArea),
|
|
95
|
+
// Surface tags by NAME only — tag uuids are an internal detail (TAGW1-c).
|
|
96
|
+
tags: tags.map((t) => ({ title: t.title })),
|
|
74
97
|
repeating: mapRepeating(row),
|
|
75
98
|
created: decodeEpochReal(row.creationDate) ?? new Date(0),
|
|
76
99
|
modified: decodeEpochReal(row.userModificationDate) ?? new Date(0),
|
|
77
100
|
stopped: decodeEpochReal(row.stopDate),
|
|
78
101
|
};
|
|
79
102
|
}
|
|
80
|
-
export function mapTodo(row, refs, tags) {
|
|
103
|
+
export function mapTodo(row, refs, tags, packedToday) {
|
|
81
104
|
return {
|
|
82
|
-
...commonFields(row, refs, tags),
|
|
105
|
+
...commonFields(row, refs, tags, packedToday),
|
|
83
106
|
type: "to-do",
|
|
84
107
|
project: refs(row.project),
|
|
85
108
|
heading: refs(row.heading),
|
|
@@ -87,9 +110,9 @@ export function mapTodo(row, refs, tags) {
|
|
|
87
110
|
openChecklistItemsCount: row.openChecklistItemsCount ?? 0,
|
|
88
111
|
};
|
|
89
112
|
}
|
|
90
|
-
export function mapProject(row, refs, tags) {
|
|
113
|
+
export function mapProject(row, refs, tags, packedToday) {
|
|
91
114
|
return {
|
|
92
|
-
...commonFields(row, refs, tags),
|
|
115
|
+
...commonFields(row, refs, tags, packedToday),
|
|
93
116
|
type: "project",
|
|
94
117
|
untrashedLeafActionsCount: row.untrashedLeafActionsCount ?? 0,
|
|
95
118
|
openUntrashedLeafActionsCount: row.openUntrashedLeafActionsCount ?? 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mappers.js","sourceRoot":"","sources":["../../src/model/mappers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GAUtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"mappers.js","sourceRoot":"","sources":["../../src/model/mappers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The emit-time omit-empty transform for entity/data payloads (the "Omit-empty"
|
|
3
|
+
* contract in docs/design/contracts.md). Applied at the JSON emit boundary of
|
|
4
|
+
* the read surfaces ONLY — the CLI `--json` read envelope (src/cli/read-driver.ts)
|
|
5
|
+
* and the MCP read tool results (src/mcp/server.ts) — never to the in-memory
|
|
6
|
+
* entities the library returns, and never to the error envelope.
|
|
7
|
+
*
|
|
8
|
+
* The rule: an ENTITY object omits any optional field whose value is empty —
|
|
9
|
+
* null, undefined, "" (empty string), or [] (empty array). A consumer MUST
|
|
10
|
+
* read an absent key as unset/empty/default and MUST NOT distinguish absent
|
|
11
|
+
* from empty. Values that are semantically meaningful when "empty" are kept:
|
|
12
|
+
* booleans (a real `false`) and numbers (a `0` count) are never omitted, and
|
|
13
|
+
* the identity keys ({@link IDENTITY_KEYS}) are always present.
|
|
14
|
+
*
|
|
15
|
+
* Why entity-scoped, not a blanket deep prune: the same key means opposite
|
|
16
|
+
* things on different shapes. A to-do's `area: null` is "no area" (omit), but a
|
|
17
|
+
* sidebar section's `area: null` is the load-bearing "top-level/loose block"
|
|
18
|
+
* discriminant (keep). So pruning is gated to the recognized entity shapes;
|
|
19
|
+
* the view scaffolding that CARRIES entities (today/evening split, project/area
|
|
20
|
+
* card sections, grouped blocks) is structural and passes through untouched —
|
|
21
|
+
* only its nested entities are pruned.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Return a deep copy of `payload` with every entity's empty optional fields
|
|
25
|
+
* omitted (the "Omit-empty" contract). Pure — the input is never mutated, so
|
|
26
|
+
* the human-render path keeps the full entity beside the JSON emit.
|
|
27
|
+
*/
|
|
28
|
+
export declare function omitEmpty<T>(payload: T): T;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The emit-time omit-empty transform for entity/data payloads (the "Omit-empty"
|
|
3
|
+
* contract in docs/design/contracts.md). Applied at the JSON emit boundary of
|
|
4
|
+
* the read surfaces ONLY — the CLI `--json` read envelope (src/cli/read-driver.ts)
|
|
5
|
+
* and the MCP read tool results (src/mcp/server.ts) — never to the in-memory
|
|
6
|
+
* entities the library returns, and never to the error envelope.
|
|
7
|
+
*
|
|
8
|
+
* The rule: an ENTITY object omits any optional field whose value is empty —
|
|
9
|
+
* null, undefined, "" (empty string), or [] (empty array). A consumer MUST
|
|
10
|
+
* read an absent key as unset/empty/default and MUST NOT distinguish absent
|
|
11
|
+
* from empty. Values that are semantically meaningful when "empty" are kept:
|
|
12
|
+
* booleans (a real `false`) and numbers (a `0` count) are never omitted, and
|
|
13
|
+
* the identity keys ({@link IDENTITY_KEYS}) are always present.
|
|
14
|
+
*
|
|
15
|
+
* Why entity-scoped, not a blanket deep prune: the same key means opposite
|
|
16
|
+
* things on different shapes. A to-do's `area: null` is "no area" (omit), but a
|
|
17
|
+
* sidebar section's `area: null` is the load-bearing "top-level/loose block"
|
|
18
|
+
* discriminant (keep). So pruning is gated to the recognized entity shapes;
|
|
19
|
+
* the view scaffolding that CARRIES entities (today/evening split, project/area
|
|
20
|
+
* card sections, grouped blocks) is structural and passes through untouched —
|
|
21
|
+
* only its nested entities are pruned.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Keys never omitted from an entity even when empty: the identity a consumer
|
|
25
|
+
* always keys on. `uuid`/`type` are never empty in practice; `title`/`name`
|
|
26
|
+
* can be "" (an untitled to-do) and MUST still be present.
|
|
27
|
+
*/
|
|
28
|
+
const IDENTITY_KEYS = new Set(["uuid", "type", "title", "name"]);
|
|
29
|
+
/** A to-do/project/heading row: uuid + a task-type discriminant. */
|
|
30
|
+
function isTaskEntity(o) {
|
|
31
|
+
return (typeof o["uuid"] === "string" &&
|
|
32
|
+
(o["type"] === "to-do" || o["type"] === "project" || o["type"] === "heading"));
|
|
33
|
+
}
|
|
34
|
+
/** An area: uuid + the `visible` flag (distinguishes it from a bare Ref). */
|
|
35
|
+
function isAreaEntity(o) {
|
|
36
|
+
return typeof o["uuid"] === "string" && typeof o["visible"] === "boolean";
|
|
37
|
+
}
|
|
38
|
+
/** A taxonomy tag row (uuid-free): a title plus the parent/shortcut columns. */
|
|
39
|
+
function isTagEntity(o) {
|
|
40
|
+
return (o["uuid"] === undefined && typeof o["title"] === "string" && "parent" in o && "shortcut" in o);
|
|
41
|
+
}
|
|
42
|
+
/** Whether this object's empty optional fields should be omitted. */
|
|
43
|
+
function prunesEmpties(o) {
|
|
44
|
+
return isTaskEntity(o) || isAreaEntity(o) || isTagEntity(o);
|
|
45
|
+
}
|
|
46
|
+
/** null | undefined | "" | [] — the values an entity omits the key for. */
|
|
47
|
+
function isEmpty(v) {
|
|
48
|
+
return v === null || v === undefined || v === "" || (Array.isArray(v) && v.length === 0);
|
|
49
|
+
}
|
|
50
|
+
function prune(value) {
|
|
51
|
+
if (value === null || value === undefined)
|
|
52
|
+
return value;
|
|
53
|
+
// Dates serialize to ISO strings via JSON.stringify — never recurse into them.
|
|
54
|
+
if (value instanceof Date)
|
|
55
|
+
return value;
|
|
56
|
+
if (Array.isArray(value))
|
|
57
|
+
return value.map(prune);
|
|
58
|
+
if (typeof value === "object") {
|
|
59
|
+
const o = value;
|
|
60
|
+
const omitEmpties = prunesEmpties(o);
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const key of Object.keys(o)) {
|
|
63
|
+
const v = o[key];
|
|
64
|
+
if (omitEmpties && !IDENTITY_KEYS.has(key) && isEmpty(v))
|
|
65
|
+
continue;
|
|
66
|
+
out[key] = prune(v);
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Return a deep copy of `payload` with every entity's empty optional fields
|
|
74
|
+
* omitted (the "Omit-empty" contract). Pure — the input is never mutated, so
|
|
75
|
+
* the human-render path keeps the full entity beside the JSON emit.
|
|
76
|
+
*/
|
|
77
|
+
export function omitEmpty(payload) {
|
|
78
|
+
return prune(payload);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/model/serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;;GAIG;AACH,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAItF,oEAAoE;AACpE,SAAS,YAAY,CAAC,CAAM;IAC1B,OAAO,CACL,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ;QAC7B,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,CAC9E,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAS,YAAY,CAAC,CAAM;IAC1B,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;AAC5E,CAAC;AAED,gFAAgF;AAChF,SAAS,WAAW,CAAC,CAAM;IACzB,OAAO,CACL,CAAC,CAAC,MAAM,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,QAAQ,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,CAC9F,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,SAAS,aAAa,CAAC,CAAM;IAC3B,OAAO,YAAY,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,2EAA2E;AAC3E,SAAS,OAAO,CAAC,CAAU;IACzB,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxD,+EAA+E;IAC/E,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,KAAY,CAAC;QACvB,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,GAAG,GAAQ,EAAE,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACjB,IAAI,WAAW,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;gBAAE,SAAS;YACnE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAI,OAAU;IACrC,OAAO,KAAK,CAAC,OAAO,CAAM,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `<when>@<time>` scheduling sugar, shared by every consumer surface. A
|
|
3
|
+
* single string like `2026-07-05@09:00` (or `today@evening`-style keyword +
|
|
4
|
+
* time) carries BOTH the schedule and its reminder; this splits it into the
|
|
5
|
+
* separate `when` + `reminder` the write pipeline expects, or reports the one
|
|
6
|
+
* usage error. Extracted from the CLI so the CLI and MCP validate the suffix
|
|
7
|
+
* identically instead of each re-deriving it — see docs/design/architecture.md
|
|
8
|
+
* (Consumer boundary).
|
|
9
|
+
*
|
|
10
|
+
* Pure: it neither mutates its input nor validates the DATE/TIME values (the
|
|
11
|
+
* pipeline does that downstream) — it only owns the `@` split and the two
|
|
12
|
+
* usage messages. The flag/parameter LABELS are injected so each surface keeps
|
|
13
|
+
* its own vocabulary (`--when`/`--reminder` vs `when`/`reminder`).
|
|
14
|
+
*/
|
|
15
|
+
/** The surface's spelling of the two parameters, interpolated into usage copy. */
|
|
16
|
+
export interface WhenSugarLabels {
|
|
17
|
+
when: string;
|
|
18
|
+
reminder: string;
|
|
19
|
+
}
|
|
20
|
+
/** CLI flag spellings — the default, since the sugar originated there. */
|
|
21
|
+
export declare const CLI_WHEN_LABELS: WhenSugarLabels;
|
|
22
|
+
/** MCP tool-parameter spellings. */
|
|
23
|
+
export declare const MCP_WHEN_LABELS: WhenSugarLabels;
|
|
24
|
+
/**
|
|
25
|
+
* The result of inspecting a `when` value for the `@time` suffix:
|
|
26
|
+
* - `unchanged` — no suffix; pass `when` through as-is.
|
|
27
|
+
* - `split` — a valid suffix; use the split `when` + `reminder`.
|
|
28
|
+
* - `error` — a malformed suffix, or a suffix given ALONGSIDE a separate
|
|
29
|
+
* reminder; emit `message` as a usage error.
|
|
30
|
+
*/
|
|
31
|
+
export type WhenSugar = {
|
|
32
|
+
kind: "unchanged";
|
|
33
|
+
} | {
|
|
34
|
+
kind: "split";
|
|
35
|
+
when: string;
|
|
36
|
+
reminder: string;
|
|
37
|
+
} | {
|
|
38
|
+
kind: "error";
|
|
39
|
+
message: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Split a `when` value on its `@time` suffix. `reminderProvided` reflects
|
|
43
|
+
* whether the caller ALSO passed a separate reminder — a suffix plus an
|
|
44
|
+
* explicit reminder is ambiguous and rejected. A non-string or suffix-free
|
|
45
|
+
* `when` is `unchanged`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function splitWhenSugar(when: unknown, reminderProvided: boolean, labels?: WhenSugarLabels): WhenSugar;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `<when>@<time>` scheduling sugar, shared by every consumer surface. A
|
|
3
|
+
* single string like `2026-07-05@09:00` (or `today@evening`-style keyword +
|
|
4
|
+
* time) carries BOTH the schedule and its reminder; this splits it into the
|
|
5
|
+
* separate `when` + `reminder` the write pipeline expects, or reports the one
|
|
6
|
+
* usage error. Extracted from the CLI so the CLI and MCP validate the suffix
|
|
7
|
+
* identically instead of each re-deriving it — see docs/design/architecture.md
|
|
8
|
+
* (Consumer boundary).
|
|
9
|
+
*
|
|
10
|
+
* Pure: it neither mutates its input nor validates the DATE/TIME values (the
|
|
11
|
+
* pipeline does that downstream) — it only owns the `@` split and the two
|
|
12
|
+
* usage messages. The flag/parameter LABELS are injected so each surface keeps
|
|
13
|
+
* its own vocabulary (`--when`/`--reminder` vs `when`/`reminder`).
|
|
14
|
+
*/
|
|
15
|
+
/** CLI flag spellings — the default, since the sugar originated there. */
|
|
16
|
+
export const CLI_WHEN_LABELS = { when: "--when", reminder: "--reminder" };
|
|
17
|
+
/** MCP tool-parameter spellings. */
|
|
18
|
+
export const MCP_WHEN_LABELS = { when: "when", reminder: "reminder" };
|
|
19
|
+
/**
|
|
20
|
+
* Split a `when` value on its `@time` suffix. `reminderProvided` reflects
|
|
21
|
+
* whether the caller ALSO passed a separate reminder — a suffix plus an
|
|
22
|
+
* explicit reminder is ambiguous and rejected. A non-string or suffix-free
|
|
23
|
+
* `when` is `unchanged`.
|
|
24
|
+
*/
|
|
25
|
+
export function splitWhenSugar(when, reminderProvided, labels = CLI_WHEN_LABELS) {
|
|
26
|
+
if (typeof when !== "string" || !when.includes("@"))
|
|
27
|
+
return { kind: "unchanged" };
|
|
28
|
+
const at = when.indexOf("@");
|
|
29
|
+
const date = when.slice(0, at);
|
|
30
|
+
const time = when.slice(at + 1);
|
|
31
|
+
if (date === "" || time === "" || time.includes("@")) {
|
|
32
|
+
return {
|
|
33
|
+
kind: "error",
|
|
34
|
+
message: `invalid ${labels.when} "${when}" — expected today | evening | anytime | someday | YYYY-MM-DD (set a reminder with ${labels.reminder} HH:mm)`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (reminderProvided) {
|
|
38
|
+
return {
|
|
39
|
+
kind: "error",
|
|
40
|
+
message: `${labels.when} "${when}" carries an @time suffix and ${labels.reminder} was also given — use one`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return { kind: "split", when: date, reminder: time };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=when-sugar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"when-sugar.js","sourceRoot":"","sources":["../../src/model/when-sugar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAoB,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAE3F,oCAAoC;AACpC,MAAM,CAAC,MAAM,eAAe,GAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAcvF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAa,EACb,gBAAyB,EACzB,SAA0B,eAAe;IAEzC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAClF,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAChC,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO;YACL,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,WAAW,MAAM,CAAC,IAAI,KAAK,IAAI,sFAAsF,MAAM,CAAC,QAAQ,SAAS;SACvJ,CAAC;IACJ,CAAC;IACD,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO;YACL,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,iCAAiC,MAAM,CAAC,QAAQ,2BAA2B;SAC5G,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACvD,CAAC"}
|
package/dist/read/area-view.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { DatabaseSync } from "node:sqlite";
|
|
8
8
|
import type { Area, IsoDateGroup, Project, Todo } from "../model/entities.ts";
|
|
9
|
+
import { type ViewFilter } from "./views.ts";
|
|
9
10
|
export interface AreaView {
|
|
10
11
|
area: Area;
|
|
11
12
|
/** Open, unscheduled/current direct to-dos, by index. */
|
|
@@ -22,5 +23,11 @@ export interface AreaView {
|
|
|
22
23
|
logged: Todo[];
|
|
23
24
|
trashed: Todo[];
|
|
24
25
|
}
|
|
26
|
+
/** A someday project row: open, incubated, no start date. */
|
|
27
|
+
export declare const isSomedayProjectRow: (p: Project) => boolean;
|
|
28
|
+
/** A future-scheduled project row (start date strictly after `todayIso`). */
|
|
29
|
+
export declare const isScheduledProjectRow: (p: Project, todayIso: string) => boolean;
|
|
30
|
+
/** An active project row — everything that is neither someday nor future-scheduled. */
|
|
31
|
+
export declare const isActiveProjectRow: (p: Project, todayIso: string) => boolean;
|
|
25
32
|
/** Resolves by uuid or unique (case-insensitive) title; throws like the ref resolvers. */
|
|
26
|
-
export declare function areaView(db: DatabaseSync, ref: string, now?: Date): AreaView;
|
|
33
|
+
export declare function areaView(db: DatabaseSync, ref: string, now?: Date, filter?: ViewFilter, zone?: string): AreaView;
|
package/dist/read/area-view.js
CHANGED
|
@@ -2,9 +2,25 @@ import { encodePackedDate, localToday, decodePackedDate } from "../model/dates.j
|
|
|
2
2
|
import { mapProject, mapTodo } from "../model/mappers.js";
|
|
3
3
|
import { fetchTagsForTasks, fetchTaskRows, makeRefResolver, resolveAreaUuid } from "./queries.js";
|
|
4
4
|
import { logBoundary, markLogged } from "./log-boundary.js";
|
|
5
|
+
import { OVERDUE } from "./predicates.js";
|
|
5
6
|
import { areaTags } from "./tags.js";
|
|
7
|
+
import { tagFilter } from "./views.js";
|
|
8
|
+
// The area card splits its open projects into three display buckets by their
|
|
9
|
+
// own schedule (the card mirrors the GUI: active projects as rows, scheduled
|
|
10
|
+
// ones under Upcoming, someday ones under Someday). Closed-but-unswept projects
|
|
11
|
+
// stay "active" (checked in place) — start/startDate only classify OPEN rows.
|
|
12
|
+
// Shared by the bounding layer (capAreaSections keeps scheduled/someday whole
|
|
13
|
+
// while capping the active rows) and the human renderer, so the split is
|
|
14
|
+
// defined ONCE and the two never drift.
|
|
15
|
+
/** A someday project row: open, incubated, no start date. */
|
|
16
|
+
export const isSomedayProjectRow = (p) => p.status === "open" && p.start === "someday" && p.startDate === null;
|
|
17
|
+
/** A future-scheduled project row (start date strictly after `todayIso`). */
|
|
18
|
+
export const isScheduledProjectRow = (p, todayIso) => p.status === "open" && p.startDate !== null && p.startDate > todayIso;
|
|
19
|
+
/** An active project row — everything that is neither someday nor future-scheduled. */
|
|
20
|
+
export const isActiveProjectRow = (p, todayIso) => !isSomedayProjectRow(p) && !isScheduledProjectRow(p, todayIso);
|
|
6
21
|
/** Resolves by uuid or unique (case-insensitive) title; throws like the ref resolvers. */
|
|
7
|
-
export function areaView(db, ref, now) {
|
|
22
|
+
export function areaView(db, ref, now, filter = {}, zone) {
|
|
23
|
+
const overdue = filter.overdue === true;
|
|
8
24
|
const uuid = resolveAreaUuid(db, ref);
|
|
9
25
|
const row = db
|
|
10
26
|
.prepare(`SELECT uuid, title, visible, "index" FROM TMArea WHERE uuid = ?`)
|
|
@@ -15,33 +31,55 @@ export function areaView(db, ref, now) {
|
|
|
15
31
|
uuid: row.uuid,
|
|
16
32
|
title: row.title ?? "",
|
|
17
33
|
visible: row.visible !== 0,
|
|
18
|
-
tags
|
|
34
|
+
// Area tags by NAME only (tag uuids are internal).
|
|
35
|
+
tags: areaTags(db, uuid).map((t) => ({ title: t.title })),
|
|
19
36
|
};
|
|
20
37
|
const refs = makeRefResolver(db);
|
|
21
38
|
const tagsOf = (rows) => fetchTagsForTasks(db, rows.map((r) => r.uuid));
|
|
22
|
-
const boundary = logBoundary(db, now);
|
|
39
|
+
const boundary = logBoundary(db, now, zone);
|
|
40
|
+
// The view's injected clock — gates `todaySection` to Today members in the
|
|
41
|
+
// mapper AND drives the scheduled/overdue bucketing below.
|
|
42
|
+
const packedToday = encodePackedDate(localToday(now, zone));
|
|
43
|
+
// OWN-DEADLINE UNIFORM: `--overdue` filters BOTH displayed row kinds by each
|
|
44
|
+
// row's OWN deadline (open, strictly before today) via the shared OVERDUE
|
|
45
|
+
// predicate — the area's child PROJECTS by the project's own deadline AND the
|
|
46
|
+
// loose to-dos by theirs. There is NO descent into project contents (an
|
|
47
|
+
// overdue to-do inside a non-overdue project never surfaces here — that is
|
|
48
|
+
// `project show --overdue`). Sections with no surviving rows collapse.
|
|
49
|
+
const overdueSql = overdue ? ` AND ${OVERDUE}` : "";
|
|
50
|
+
const overdueBinds = overdue ? [encodePackedDate(localToday(now, zone))] : [];
|
|
51
|
+
// Tag scope (§9a): BOTH displayed row kinds — the child PROJECTS and the
|
|
52
|
+
// loose to-dos — are filtered by a tag carried DIRECTLY on the row (the
|
|
53
|
+
// container semantics). The area's own tags are inherited by every row it
|
|
54
|
+
// holds, so an inheritance-inclusive `--tag` would be vacuous; suppressing the
|
|
55
|
+
// container hop makes `--tag` mean "rows with this tag on themselves" (still
|
|
56
|
+
// descendant-expanded) and `--untagged` "rows with no direct tag". Computed
|
|
57
|
+
// once, spliced into both queries; NO descent into project contents (a child
|
|
58
|
+
// of a matching project is never inspected here). The tag binds trail each
|
|
59
|
+
// query's own binds.
|
|
60
|
+
const tf = tagFilter(db, filter, { container: true });
|
|
23
61
|
// Open projects PLUS closed ones the log-move sweep has not passed — the
|
|
24
|
-
// GUI keeps those checked in place (completion ≠ logged).
|
|
62
|
+
// GUI keeps those checked in place (completion ≠ logged). Under --overdue the
|
|
63
|
+
// OVERDUE predicate's own `status = 0` narrows this to open overdue projects.
|
|
25
64
|
const projectRows = fetchTaskRows(db, `t.type = 1 AND t.area = ? AND t.trashed = 0
|
|
26
|
-
AND (t.status = 0 OR t.stopDate > ?) ORDER BY t."index" ASC`, [uuid, boundary.getTime() / 1000]);
|
|
65
|
+
AND (t.status = 0 OR t.stopDate > ?)${overdueSql}${tf.sql} ORDER BY t."index" ASC`, [uuid, boundary.getTime() / 1000, ...overdueBinds, ...tf.binds]);
|
|
27
66
|
const projectTags = tagsOf(projectRows);
|
|
28
|
-
const projects = markLogged(projectRows.map((r) => mapProject(r, refs, projectTags.get(r.uuid) ?? [])), boundary);
|
|
29
|
-
const todoRows = fetchTaskRows(db, `t.type = 0 AND t.area =
|
|
67
|
+
const projects = markLogged(projectRows.map((r) => mapProject(r, refs, projectTags.get(r.uuid) ?? [], packedToday)), boundary);
|
|
68
|
+
const todoRows = fetchTaskRows(db, `t.type = 0 AND t.area = ?${overdueSql}${tf.sql} ORDER BY t."index" ASC`, [uuid, ...overdueBinds, ...tf.binds]);
|
|
30
69
|
const todoTags = tagsOf(todoRows);
|
|
31
70
|
const todos = todoRows.map((r) => ({
|
|
32
71
|
row: r,
|
|
33
|
-
todo: mapTodo(r, refs, todoTags.get(r.uuid) ?? []),
|
|
72
|
+
todo: mapTodo(r, refs, todoTags.get(r.uuid) ?? [], packedToday),
|
|
34
73
|
}));
|
|
35
74
|
markLogged(todos.map((t) => t.todo), boundary);
|
|
36
|
-
const packedToday = encodePackedDate(localToday(now));
|
|
37
75
|
const active = [];
|
|
38
76
|
const scheduledRows = [];
|
|
39
77
|
const repeating = [];
|
|
40
78
|
const someday = [];
|
|
41
79
|
const logged = [];
|
|
42
80
|
const trashed = [];
|
|
43
|
-
for (const { row, todo } of todos) {
|
|
44
|
-
if (
|
|
81
|
+
for (const { row: todoRow, todo } of todos) {
|
|
82
|
+
if (todoRow.trashed === 1) {
|
|
45
83
|
trashed.push(todo);
|
|
46
84
|
continue;
|
|
47
85
|
}
|
|
@@ -49,7 +87,7 @@ export function areaView(db, ref, now) {
|
|
|
49
87
|
repeating.push(todo);
|
|
50
88
|
continue;
|
|
51
89
|
}
|
|
52
|
-
if (
|
|
90
|
+
if (todoRow.status !== 0) {
|
|
53
91
|
// Completion ≠ logged: closed-but-unswept items stay checked in the
|
|
54
92
|
// active block, like the GUI.
|
|
55
93
|
if (todo.logged)
|
|
@@ -58,14 +96,14 @@ export function areaView(db, ref, now) {
|
|
|
58
96
|
active.push(todo);
|
|
59
97
|
continue;
|
|
60
98
|
}
|
|
61
|
-
if (
|
|
99
|
+
if (todoRow.start === 2 && todoRow.startDate === null) {
|
|
62
100
|
someday.push(todo);
|
|
63
101
|
continue;
|
|
64
102
|
}
|
|
65
|
-
if (
|
|
103
|
+
if (todoRow.startDate !== null && todoRow.startDate > packedToday) {
|
|
66
104
|
scheduledRows.push({
|
|
67
|
-
date: decodePackedDate(
|
|
68
|
-
ti:
|
|
105
|
+
date: decodePackedDate(todoRow.startDate) ?? "",
|
|
106
|
+
ti: todoRow.todayIndex ?? 0,
|
|
69
107
|
todo,
|
|
70
108
|
});
|
|
71
109
|
continue;
|
|
@@ -75,7 +113,7 @@ export function areaView(db, ref, now) {
|
|
|
75
113
|
logged.sort((a, b) => (b.stopped?.getTime() ?? 0) - (a.stopped?.getTime() ?? 0));
|
|
76
114
|
const scheduled = [];
|
|
77
115
|
// Within a day the UI sorts by todayIndex ASC (Upcoming drag order).
|
|
78
|
-
for (const { date, todo } of scheduledRows.
|
|
116
|
+
for (const { date, todo } of scheduledRows.toSorted((a, b) => a.date.localeCompare(b.date) || a.ti - b.ti)) {
|
|
79
117
|
const last = scheduled[scheduled.length - 1];
|
|
80
118
|
if (last && last.date === date)
|
|
81
119
|
last.items.push(todo);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"area-view.js","sourceRoot":"","sources":["../../src/read/area-view.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,OAAO,EAAgB,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"area-view.js","sourceRoot":"","sources":["../../src/read/area-view.ts"],"names":[],"mappings":"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"}
|
package/dist/read/detail.d.ts
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { DatabaseSync } from "node:sqlite";
|
|
6
6
|
import type { AnyTask, ChecklistItem } from "../model/entities.ts";
|
|
7
|
-
export declare function byUuid(db: DatabaseSync, uuid: string): AnyTask | null;
|
|
7
|
+
export declare function byUuid(db: DatabaseSync, uuid: string, now?: Date, zone?: string): AnyTask | null;
|
|
8
8
|
export declare function checklistFor(db: DatabaseSync, taskUuid: string): ChecklistItem[];
|