things-api 0.11.0 → 0.13.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.
Files changed (208) hide show
  1. package/README.md +16 -5
  2. package/dist/audit/schema.d.ts +7 -0
  3. package/dist/audit/schema.js.map +1 -1
  4. package/dist/cli/canonical-ref.d.ts +21 -0
  5. package/dist/cli/canonical-ref.js +23 -0
  6. package/dist/cli/canonical-ref.js.map +1 -0
  7. package/dist/cli/commands/area.d.ts +18 -11
  8. package/dist/cli/commands/area.js +81 -77
  9. package/dist/cli/commands/area.js.map +1 -1
  10. package/dist/cli/commands/doctor.d.ts +1 -2
  11. package/dist/cli/commands/doctor.js +11 -1
  12. package/dist/cli/commands/doctor.js.map +1 -1
  13. package/dist/cli/commands/install-skill.d.ts +19 -4
  14. package/dist/cli/commands/install-skill.js +130 -52
  15. package/dist/cli/commands/install-skill.js.map +1 -1
  16. package/dist/cli/commands/mcp.js +21 -1
  17. package/dist/cli/commands/mcp.js.map +1 -1
  18. package/dist/cli/commands/project.d.ts +1 -0
  19. package/dist/cli/commands/project.js +92 -48
  20. package/dist/cli/commands/project.js.map +1 -1
  21. package/dist/cli/commands/reads.d.ts +5 -1
  22. package/dist/cli/commands/reads.js +110 -31
  23. package/dist/cli/commands/reads.js.map +1 -1
  24. package/dist/cli/commands/setup.js +11 -4
  25. package/dist/cli/commands/setup.js.map +1 -1
  26. package/dist/cli/commands/show.js +75 -36
  27. package/dist/cli/commands/show.js.map +1 -1
  28. package/dist/cli/commands/todo.js +2 -2
  29. package/dist/cli/commands/todo.js.map +1 -1
  30. package/dist/cli/commands/writes.js +795 -144
  31. package/dist/cli/commands/writes.js.map +1 -1
  32. package/dist/cli/did-you-mean.d.ts +14 -3
  33. package/dist/cli/did-you-mean.js +44 -7
  34. package/dist/cli/did-you-mean.js.map +1 -1
  35. package/dist/cli/dry-run.d.ts +55 -0
  36. package/dist/cli/dry-run.js +92 -0
  37. package/dist/cli/dry-run.js.map +1 -0
  38. package/dist/cli/glyphs.d.ts +16 -2
  39. package/dist/cli/glyphs.js +60 -12
  40. package/dist/cli/glyphs.js.map +1 -1
  41. package/dist/cli/help.js +69 -13
  42. package/dist/cli/help.js.map +1 -1
  43. package/dist/cli/main.js +8 -1
  44. package/dist/cli/main.js.map +1 -1
  45. package/dist/cli/move-hint.d.ts +3 -2
  46. package/dist/cli/move-hint.js +2 -2
  47. package/dist/cli/move-hint.js.map +1 -1
  48. package/dist/cli/read-driver.d.ts +53 -5
  49. package/dist/cli/read-driver.js +82 -15
  50. package/dist/cli/read-driver.js.map +1 -1
  51. package/dist/cli/ref-render.d.ts +14 -0
  52. package/dist/cli/ref-render.js +9 -0
  53. package/dist/cli/ref-render.js.map +1 -0
  54. package/dist/cli/render.d.ts +40 -14
  55. package/dist/cli/render.js +128 -55
  56. package/dist/cli/render.js.map +1 -1
  57. package/dist/cli/resolve-invocation.d.ts +7 -5
  58. package/dist/cli/resolve-invocation.js +16 -7
  59. package/dist/cli/resolve-invocation.js.map +1 -1
  60. package/dist/cli/skill-check.d.ts +12 -6
  61. package/dist/cli/skill-check.js +31 -14
  62. package/dist/cli/skill-check.js.map +1 -1
  63. package/dist/cli/skill.d.ts +8 -0
  64. package/dist/cli/skill.js +10 -0
  65. package/dist/cli/skill.js.map +1 -1
  66. package/dist/cli/verb-hint.js +1 -1
  67. package/dist/cli/verb-hint.js.map +1 -1
  68. package/dist/client.d.ts +158 -26
  69. package/dist/client.js +254 -38
  70. package/dist/client.js.map +1 -1
  71. package/dist/config.d.ts +66 -2
  72. package/dist/config.js +120 -12
  73. package/dist/config.js.map +1 -1
  74. package/dist/contracts.d.ts +187 -28
  75. package/dist/contracts.js +22 -1
  76. package/dist/contracts.js.map +1 -1
  77. package/dist/db/baselines/db-v26.js +4 -1
  78. package/dist/db/baselines/db-v26.js.map +1 -1
  79. package/dist/diagnose.d.ts +34 -2
  80. package/dist/diagnose.js +36 -1
  81. package/dist/diagnose.js.map +1 -1
  82. package/dist/index.d.ts +21 -8
  83. package/dist/index.js +26 -3
  84. package/dist/index.js.map +1 -1
  85. package/dist/mcp/server.d.ts +9 -0
  86. package/dist/mcp/server.js +790 -322
  87. package/dist/mcp/server.js.map +1 -1
  88. package/dist/model/entities.d.ts +57 -4
  89. package/dist/model/entities.js.map +1 -1
  90. package/dist/model/mappers.d.ts +2 -0
  91. package/dist/model/mappers.js +44 -2
  92. package/dist/model/mappers.js.map +1 -1
  93. package/dist/model/recurrence.d.ts +8 -1
  94. package/dist/model/recurrence.js.map +1 -1
  95. package/dist/model/serialize.js +15 -3
  96. package/dist/model/serialize.js.map +1 -1
  97. package/dist/read/area-filter.d.ts +76 -0
  98. package/dist/read/area-filter.js +58 -0
  99. package/dist/read/area-filter.js.map +1 -0
  100. package/dist/read/area-view.d.ts +22 -11
  101. package/dist/read/area-view.js +54 -28
  102. package/dist/read/area-view.js.map +1 -1
  103. package/dist/read/detail.js +15 -8
  104. package/dist/read/detail.js.map +1 -1
  105. package/dist/read/predicates.d.ts +18 -0
  106. package/dist/read/predicates.js +19 -0
  107. package/dist/read/predicates.js.map +1 -1
  108. package/dist/read/project-view.d.ts +91 -15
  109. package/dist/read/project-view.js +135 -37
  110. package/dist/read/project-view.js.map +1 -1
  111. package/dist/read/pseudo-area.d.ts +29 -0
  112. package/dist/read/pseudo-area.js +27 -0
  113. package/dist/read/pseudo-area.js.map +1 -0
  114. package/dist/read/queries.d.ts +175 -19
  115. package/dist/read/queries.js +376 -32
  116. package/dist/read/queries.js.map +1 -1
  117. package/dist/read/scope.d.ts +126 -0
  118. package/dist/read/scope.js +161 -0
  119. package/dist/read/scope.js.map +1 -0
  120. package/dist/read/search-rank.d.ts +2 -5
  121. package/dist/read/shape.d.ts +181 -0
  122. package/dist/read/shape.js +737 -0
  123. package/dist/read/shape.js.map +1 -0
  124. package/dist/read/show-target.d.ts +9 -1
  125. package/dist/read/show-target.js +77 -17
  126. package/dist/read/show-target.js.map +1 -1
  127. package/dist/read/stage.d.ts +199 -0
  128. package/dist/read/stage.js +125 -0
  129. package/dist/read/stage.js.map +1 -0
  130. package/dist/read/truncation.d.ts +7 -12
  131. package/dist/read/truncation.js +56 -21
  132. package/dist/read/truncation.js.map +1 -1
  133. package/dist/read/views.d.ts +68 -16
  134. package/dist/read/views.js +206 -52
  135. package/dist/read/views.js.map +1 -1
  136. package/dist/surface-copy.d.ts +16 -0
  137. package/dist/surface-copy.js +16 -0
  138. package/dist/surface-copy.js.map +1 -1
  139. package/dist/write/batch.d.ts +49 -10
  140. package/dist/write/batch.js +423 -71
  141. package/dist/write/batch.js.map +1 -1
  142. package/dist/write/commands.js +268 -55
  143. package/dist/write/commands.js.map +1 -1
  144. package/dist/write/guards.d.ts +1 -1
  145. package/dist/write/guards.js +71 -10
  146. package/dist/write/guards.js.map +1 -1
  147. package/dist/write/heading.d.ts +10 -1
  148. package/dist/write/heading.js +35 -5
  149. package/dist/write/heading.js.map +1 -1
  150. package/dist/write/make-repeating-project.d.ts +2 -2
  151. package/dist/write/make-repeating-project.js +9 -9
  152. package/dist/write/make-repeating-project.js.map +1 -1
  153. package/dist/write/move.d.ts +134 -0
  154. package/dist/write/move.js +1874 -0
  155. package/dist/write/move.js.map +1 -0
  156. package/dist/write/operations.d.ts +105 -19
  157. package/dist/write/operations.js +56 -7
  158. package/dist/write/operations.js.map +1 -1
  159. package/dist/write/opid.d.ts +31 -0
  160. package/dist/write/opid.js +30 -0
  161. package/dist/write/opid.js.map +1 -0
  162. package/dist/write/pipeline.d.ts +70 -3
  163. package/dist/write/pipeline.js +198 -33
  164. package/dist/write/pipeline.js.map +1 -1
  165. package/dist/write/pre-state.d.ts +172 -8
  166. package/dist/write/pre-state.js +467 -25
  167. package/dist/write/pre-state.js.map +1 -1
  168. package/dist/write/reorder.d.ts +23 -3
  169. package/dist/write/reorder.js +2106 -86
  170. package/dist/write/reorder.js.map +1 -1
  171. package/dist/write/reversibility.js +19 -7
  172. package/dist/write/reversibility.js.map +1 -1
  173. package/dist/write/scope-guard.d.ts +31 -0
  174. package/dist/write/scope-guard.js +162 -0
  175. package/dist/write/scope-guard.js.map +1 -0
  176. package/dist/write/undo.js +120 -13
  177. package/dist/write/undo.js.map +1 -1
  178. package/dist/write/vectors/applescript.js +16 -7
  179. package/dist/write/vectors/applescript.js.map +1 -1
  180. package/dist/write/vectors/shortcuts.js +1 -1
  181. package/dist/write/vectors/shortcuts.js.map +1 -1
  182. package/dist/write/vectors/simulator.js +83 -27
  183. package/dist/write/vectors/simulator.js.map +1 -1
  184. package/dist/write/vectors/types.d.ts +11 -0
  185. package/dist/write/vectors/ui-certification.d.ts +3 -3
  186. package/dist/write/vectors/ui-certification.js +41 -5
  187. package/dist/write/vectors/ui-certification.js.map +1 -1
  188. package/dist/write/vectors/ui-drag.d.ts +21 -1
  189. package/dist/write/vectors/ui-drag.js +138 -27
  190. package/dist/write/vectors/ui-drag.js.map +1 -1
  191. package/dist/write/vectors/ui-recipes.d.ts +21 -1
  192. package/dist/write/vectors/ui-recipes.js +166 -7
  193. package/dist/write/vectors/ui-recipes.js.map +1 -1
  194. package/dist/write/vectors/ui.d.ts +25 -1
  195. package/dist/write/vectors/ui.js +142 -33
  196. package/dist/write/vectors/ui.js.map +1 -1
  197. package/dist/write/verify/delta.d.ts +17 -1
  198. package/dist/write/verify/delta.js +106 -29
  199. package/dist/write/verify/delta.js.map +1 -1
  200. package/package.json +7 -1
  201. package/schema/envelope.schema.json +397 -0
  202. package/skills/things-cli/SKILL.md +36 -17
  203. package/skills/things-cli/references/banner.md +35 -0
  204. package/skills/things-cli/references/contracts.md +32 -9
  205. package/skills/things-cli/references/errors.md +57 -0
  206. package/skills/things-cli/references/gui.md +1 -1
  207. package/skills/things-cli/references/model.md +18 -7
  208. package/skills/things-cli/references/ordering.md +88 -0
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Composite project view mirroring the native UI (validated T17 + "later
3
3
  * items" findings): active items, headings with their children, later
4
- * (scheduled by date / repeating templates / someday), logged, trashed.
4
+ * (scheduled by date / repeating templates / someday), logged. Trashed
5
+ * children are excluded entirely (GUI-faithful — the app filters trashed
6
+ * children out of the project view, §6½/PLOG1-a).
5
7
  *
6
8
  * Child membership: `project = ? OR heading IN (project's headings)` — the
7
9
  * DB invariant is that headed to-dos have project = NULL (atlas §TMTask).
@@ -10,24 +12,88 @@
10
12
  import type { DatabaseSync } from "node:sqlite";
11
13
  import type { Heading, IsoDateGroup, Project, Todo } from "../model/entities.ts";
12
14
  import { type ViewFilter } from "./views.ts";
15
+ /**
16
+ * A heading group inside a project view. Mirrors the GUI: the heading owns its
17
+ * OWN display sub-buckets (§1 of the demotion/move design) — the anytime/current
18
+ * `items`, its future-dated `scheduled` children grouped per day, its resting
19
+ * `repeating` templates, and its `someday` children. The project-level buckets
20
+ * (below) hold ONLY the UNHEADED members; a headed child lives here, under its
21
+ * heading, never pooled at the project level.
22
+ */
23
+ export interface ProjectHeadingGroup {
24
+ heading: Heading;
25
+ /** Open/current children under this heading, by index. */
26
+ items: Todo[];
27
+ /** This heading's future-dated children grouped by date ascending. */
28
+ scheduled: IsoDateGroup<Todo>[];
29
+ /** This heading's someday (incubated, undated) children. */
30
+ someday: Todo[];
31
+ /** This heading's repeating template rows (invisible in list views). */
32
+ repeating: Todo[];
33
+ }
34
+ /**
35
+ * An ARCHIVED heading rendered inside the logged region (HEADARC2-A). Unlike a
36
+ * live {@link ProjectHeadingGroup}, an archived heading is itself a logged item,
37
+ * and its children — ALL of them, whatever their own state — nest beneath it as
38
+ * a grouped section (most-recently-completed first). That includes any odd OPEN
39
+ * child a GUI "Put Back" left stranded under the archived heading (HEADARC2-C):
40
+ * the group renders what is there, it does NOT filter to status=3.
41
+ */
42
+ export interface LoggedHeadingGroup {
43
+ /** The archived heading (status "completed"); the wire emits its `archived`. */
44
+ heading: Heading;
45
+ /** Every child of the archived heading, most-recently-completed first. */
46
+ items: Todo[];
47
+ }
13
48
  export interface ProjectView {
14
49
  project: Project;
15
- /** Open, unscheduled/current children not under a heading, by index. */
50
+ /**
51
+ * ALL live (non-logbook, non-trash) children of the project — unheaded AND
52
+ * headed — in project `index` order, each headed row carrying its `heading`
53
+ * ref (and `headingProject`). This is the flat wire representation (the read
54
+ * doctrine's project-view `items[]`): membership in a heading is a per-row
55
+ * attribute, not a bucket. The structured buckets below (`active`, `headings`,
56
+ * `scheduled`, …) are the SAME children re-grouped into the GUI's render layout
57
+ * for the TTY projection — the library owns the clock + `todayIndex`, so the
58
+ * renderer reconstructs the exact GUI placement from them without re-deriving
59
+ * dates. The two are always consistent (built from one child fetch).
60
+ */
61
+ items: Todo[];
62
+ /**
63
+ * The full heading catalog — EVERY heading (live AND swept archived) in project
64
+ * `index` order (read-shape doctrine §3.12 / #C3). This is the flat wire
65
+ * representation of `headings[]` (`[{uuid,title,archived?}]`): which headings
66
+ * exist, in what order, and whether each is archived — the ORDER axis that
67
+ * earns the bucket its place. A live-group's row membership rides the flat
68
+ * `items[]` refs; a swept archived heading's children ride the flat `logbook`
69
+ * refs. The structured `headings` / `loggedHeadings` below re-group the SAME
70
+ * headings + children into the GUI render layout for the byte-stable TTY.
71
+ */
72
+ headingCatalog: Heading[];
73
+ /** Open, unscheduled/current UNHEADED children, by index. */
16
74
  active: Todo[];
17
- /** Headings in project order, each with its open children. */
18
- headings: Array<{
19
- heading: Heading;
20
- items: Todo[];
21
- }>;
22
- later: {
23
- /** Future-dated children grouped by date ascending. */
24
- scheduled: IsoDateGroup<Todo>[];
25
- /** Repeating template rows owned by this project (invisible in list views). */
26
- repeating: Todo[];
27
- someday: Todo[];
28
- };
75
+ /** OPEN headings in project order, each with its own sub-buckets. An archived heading never renders here. */
76
+ headings: ProjectHeadingGroup[];
77
+ /** UNHEADED future-dated children grouped by date ascending. */
78
+ scheduled: IsoDateGroup<Todo>[];
79
+ /** UNHEADED someday (incubated, undated) children. */
80
+ someday: Todo[];
81
+ /** UNHEADED repeating template rows owned by this project (invisible in list views). */
82
+ repeating: Todo[];
83
+ /**
84
+ * The flat logged region: swept children of OPEN headings (each carrying its
85
+ * heading ref) plus swept un-headed children, most-recently-completed first.
86
+ * Children of ARCHIVED headings are NOT here — they group under their heading
87
+ * in {@link ProjectView.loggedHeadings}.
88
+ */
29
89
  logged: Todo[];
30
- trashed: Todo[];
90
+ /**
91
+ * The archived-heading GROUPS of the logged region (HEADARC2-A), in project
92
+ * (heading `index`) order — each an archived heading with its children nested.
93
+ * Rendered only under `--show-logged`, after the flat {@link ProjectView.logged}
94
+ * rows (the flat-then-grouped ordering is a defensible choice, not GUI-probed).
95
+ */
96
+ loggedHeadings: LoggedHeadingGroup[];
31
97
  /**
32
98
  * PLOG1 (additive): count of untrashed OPEN (status=0) children this project
33
99
  * still holds while it is ITSELF completed or canceled — including once swept
@@ -38,6 +104,16 @@ export interface ProjectView {
38
104
  * child.
39
105
  */
40
106
  openChildrenWhileResolved: number;
107
+ /**
108
+ * HEADARC2-C (additive): count of untrashed OPEN (status=0) children buried
109
+ * under an ARCHIVED heading of this project — the heading analog of the §6¾
110
+ * odd state. The GUI's "Put Back" of a trashed open child restores it in place
111
+ * under the archived heading WITHOUT reopening the heading, leaving an open,
112
+ * actionable to-do invisible to every live view (reachable only by expanding
113
+ * this card's logged region). Counted regardless of the PROJECT's own status.
114
+ * 0 when no archived heading holds an open child.
115
+ */
116
+ openChildrenUnderArchivedHeading: number;
41
117
  }
42
118
  export declare class ProjectNotFoundError extends Error {
43
119
  constructor(uuid: string);
@@ -11,6 +11,24 @@ export class ProjectNotFoundError extends Error {
11
11
  this.name = "ProjectNotFoundError";
12
12
  }
13
13
  }
14
+ /** Append `value` to the list at `key`, creating it on first use. */
15
+ function pushInto(map, key, value) {
16
+ const list = map.get(key) ?? [];
17
+ list.push(value);
18
+ map.set(key, list);
19
+ }
20
+ /** Group scheduled rows into per-day buckets (date ASC, within-day todayIndex ASC). */
21
+ function groupByDate(rows) {
22
+ const out = [];
23
+ for (const { date, todo } of rows.toSorted((a, b) => a.date.localeCompare(b.date) || a.ti - b.ti)) {
24
+ const last = out[out.length - 1];
25
+ if (last && last.date === date)
26
+ last.items.push(todo);
27
+ else
28
+ out.push({ date, items: [todo] });
29
+ }
30
+ return out;
31
+ }
14
32
  export function projectView(db, uuid, now, filter = {}, zone) {
15
33
  const overdue = filter.overdue === true;
16
34
  const projectRow = fetchTaskByUuid(db, uuid);
@@ -43,7 +61,7 @@ export function projectView(db, uuid, now, filter = {}, zone) {
43
61
  // the two uuid binds and lead the overdue bind, matching their left-to-right
44
62
  // order in the SQL.
45
63
  const tf = tagFilter(db, filter, { container: true });
46
- const childRows = fetchTaskRows(db, `t.type = 0 AND (t.project = ? OR t.heading IN (
64
+ const childRows = fetchTaskRows(db, `t.type = 0 AND t.trashed = 0 AND (t.project = ? OR t.heading IN (
47
65
  SELECT uuid FROM TMTask WHERE type = 2 AND project = ?
48
66
  ))${tf.sql}${overdueSql}
49
67
  ORDER BY t."index" ASC`, [uuid, uuid, ...tf.binds, ...overdueBinds]);
@@ -54,24 +72,68 @@ export function projectView(db, uuid, now, filter = {}, zone) {
54
72
  todo: mapTodo(r, refs, childTags.get(r.uuid) ?? [], packedToday),
55
73
  }));
56
74
  markLogged([project, ...todos.map((t) => t.todo)], boundary);
75
+ // TRINARY heading split (the completion≠logged law, applied to headings): an
76
+ // OPEN heading — or an archived one NOT yet past the log-move boundary — stays
77
+ // a LIVE group IN PLACE (an archived-unswept heading carries `archived` yet
78
+ // renders among the live groups, exactly as a completed-unswept to-do row
79
+ // stays checked in place, §above / log-boundary.ts). Only a SWEPT archived
80
+ // heading moves into the logged region as a grouped section (HEADARC2-A).
81
+ const headingSwept = (h) => h.status !== "open" && h.stopped !== null && h.stopped <= boundary;
82
+ const liveHeadings = headings.filter((h) => !headingSwept(h));
83
+ const sweptHeadings = headings.filter((h) => headingSwept(h));
84
+ const liveHeadingSet = new Set(liveHeadings.map((h) => h.uuid));
85
+ const sweptHeadingSet = new Set(sweptHeadings.map((h) => h.uuid));
86
+ // The owning-project ref stamped on every headed child — so the heading ref a
87
+ // flat logged row carries promotes its `headingUuid` in the project's scope
88
+ // (the round-trip predicate is project-scoped), mirroring the list views.
89
+ const projectRef = { uuid: project.uuid, title: project.title };
90
+ // Project-level (UNHEADED) buckets.
57
91
  const active = [];
58
- const byHeading = new Map();
59
92
  const scheduledRows = [];
60
93
  const repeating = [];
61
94
  const someday = [];
62
95
  const logged = [];
63
- const trashed = [];
96
+ // Children of a SWEPT archived heading — grouped under their heading in the
97
+ // logged region (keyed by heading uuid), ALL of them regardless of state.
98
+ const sweptHeadingChildren = new Map();
99
+ // Per-heading LIVE sub-buckets, keyed by heading uuid (§9 fidelity fix): a
100
+ // headed scheduled/someday/repeating child nests under its heading, NOT at the
101
+ // project level.
102
+ const headingItems = new Map();
103
+ const headingScheduled = new Map();
104
+ const headingSomeday = new Map();
105
+ const headingRepeating = new Map();
106
+ // A child whose heading FK is not a LIVE heading (an unknown/trashed heading,
107
+ // OR a swept archived heading handled above) falls back to the project-level
108
+ // (unheaded) buckets rather than vanishing (mirrors the render's loose fallback).
109
+ const liveHeadingUuidOf = (row) => row.heading !== null && liveHeadingSet.has(row.heading) ? row.heading : null;
64
110
  // Every untrashed, non-template OPEN child, regardless of which bucket it
65
111
  // lands in below — surfaced (only when the project is itself resolved) as
66
112
  // the PLOG1 stranded-open-child count.
67
113
  let openChildren = 0;
114
+ // Open children buried under a SWEPT archived heading — the §6¾ odd state for
115
+ // headings (HEADARC2-C), surfaced regardless of the project's own status.
116
+ let openChildrenUnderArchivedHeading = 0;
68
117
  for (const { row, todo } of todos) {
69
- if (row.trashed === 1) {
70
- trashed.push(todo);
118
+ if (todo.heading !== null)
119
+ todo.headingProject = projectRef;
120
+ // A child of a SWEPT archived heading groups under it in the logged region,
121
+ // WHATEVER its own state — including the odd OPEN child a GUI Put-Back
122
+ // stranded (HEADARC2-C): render what is there, do NOT filter to status=3.
123
+ if (row.heading !== null && sweptHeadingSet.has(row.heading)) {
124
+ pushInto(sweptHeadingChildren, row.heading, todo);
125
+ if (row.status === 0 && !todo.repeating.isTemplate) {
126
+ openChildren += 1; // also stranded when the project itself is resolved
127
+ openChildrenUnderArchivedHeading += 1;
128
+ }
71
129
  continue;
72
130
  }
131
+ const h = liveHeadingUuidOf(row);
73
132
  if (todo.repeating.isTemplate) {
74
- repeating.push(todo);
133
+ if (h !== null)
134
+ pushInto(headingRepeating, h, todo);
135
+ else
136
+ repeating.push(todo);
75
137
  continue;
76
138
  }
77
139
  if (row.status === 0)
@@ -84,62 +146,98 @@ export function projectView(db, uuid, now, filter = {}, zone) {
84
146
  logged.push(todo);
85
147
  continue;
86
148
  }
87
- if (row.heading) {
88
- const list = byHeading.get(row.heading) ?? [];
89
- list.push(todo);
90
- byHeading.set(row.heading, list);
91
- }
92
- else {
149
+ if (h !== null)
150
+ pushInto(headingItems, h, todo);
151
+ else
93
152
  active.push(todo);
94
- }
95
153
  continue;
96
154
  }
97
155
  if (row.start === 2 && row.startDate === null) {
98
- someday.push(todo);
156
+ if (h !== null)
157
+ pushInto(headingSomeday, h, todo);
158
+ else
159
+ someday.push(todo);
99
160
  continue;
100
161
  }
101
162
  if (row.startDate !== null && row.startDate > packedToday) {
102
- scheduledRows.push({
163
+ const sr = {
103
164
  date: decodePackedDate(row.startDate) ?? "",
104
165
  ti: row.todayIndex ?? 0,
105
166
  todo,
106
- });
107
- continue;
108
- }
109
- if (row.heading) {
110
- const list = byHeading.get(row.heading) ?? [];
111
- list.push(todo);
112
- byHeading.set(row.heading, list);
167
+ };
168
+ if (h !== null)
169
+ pushInto(headingScheduled, h, sr);
170
+ else
171
+ scheduledRows.push(sr);
113
172
  continue;
114
173
  }
115
- active.push(todo);
174
+ if (h !== null)
175
+ pushInto(headingItems, h, todo);
176
+ else
177
+ active.push(todo);
116
178
  }
117
179
  logged.sort((a, b) => (b.stopped?.getTime() ?? 0) - (a.stopped?.getTime() ?? 0));
118
- const scheduled = [];
119
180
  // Within a day the UI sorts by todayIndex ASC (Upcoming drag order).
120
- for (const { date, todo } of scheduledRows.toSorted((a, b) => a.date.localeCompare(b.date) || a.ti - b.ti)) {
121
- const last = scheduled[scheduled.length - 1];
122
- if (last && last.date === date)
123
- last.items.push(todo);
124
- else
125
- scheduled.push({ date, items: [todo] });
126
- }
181
+ const scheduled = groupByDate(scheduledRows);
127
182
  // Under any content scope (`--overdue` or a tag filter), a heading whose
128
183
  // children were all filtered out collapses rather than rendering an empty
129
- // section; a heading with a surviving child is kept. With no scope active
130
- // every heading renders (its own empty state).
184
+ // section; a heading with any surviving child (in ANY sub-bucket) is kept.
185
+ // With no scope active every heading renders (its own empty state).
131
186
  const contentScoped = overdue || tf.sql !== "";
132
- const headingGroups = headings
133
- .map((heading) => ({ heading, items: byHeading.get(heading.uuid) ?? [] }))
187
+ const headingGroups = liveHeadings
188
+ .map((heading) => ({
189
+ heading,
190
+ items: headingItems.get(heading.uuid) ?? [],
191
+ scheduled: groupByDate(headingScheduled.get(heading.uuid) ?? []),
192
+ someday: headingSomeday.get(heading.uuid) ?? [],
193
+ repeating: headingRepeating.get(heading.uuid) ?? [],
194
+ }))
195
+ .filter((g) => !contentScoped ||
196
+ g.items.length > 0 ||
197
+ g.scheduled.length > 0 ||
198
+ g.someday.length > 0 ||
199
+ g.repeating.length > 0);
200
+ // The logged-region archived-heading groups, in project (heading index) order;
201
+ // each group's children most-recently-completed first (open odd children, with
202
+ // no stopDate, sort last — the same null-last convention the flat logged list
203
+ // uses). Under a content scope (--overdue / --tag) an empty group collapses.
204
+ const loggedHeadings = sweptHeadings
205
+ .map((heading) => ({
206
+ heading,
207
+ items: (sweptHeadingChildren.get(heading.uuid) ?? []).toSorted((a, b) => (b.stopped?.getTime() ?? 0) - (a.stopped?.getTime() ?? 0)),
208
+ }))
134
209
  .filter((g) => !contentScoped || g.items.length > 0);
210
+ // The flat wire `items[]`: every LIVE child in project index order (the
211
+ // `todos` fetch is already `ORDER BY index ASC`). Excludes swept logged rows
212
+ // (→ `logged`) and children of swept archived headings (→ `loggedHeadings`) —
213
+ // exactly the rows that leave the live region. Each headed row already carries
214
+ // its `heading` ref + `headingProject` (stamped in the loop above).
215
+ const items = todos
216
+ .map((t) => t.todo)
217
+ .filter((td) => !td.logged && !(td.heading !== null && sweptHeadingSet.has(td.heading.uuid)));
218
+ // The catalog: every heading (live + swept archived) in index order — but under
219
+ // a content scope (`--overdue` / `--tag`) a heading whose children were all
220
+ // filtered out COLLAPSES, exactly as it does for the live groups + logged groups
221
+ // and the TTY. With no scope every heading survives (empty ones included), so
222
+ // this is a no-op there. Built from the SAME survivors the render layout uses.
223
+ const survivingHeadings = new Set([
224
+ ...headingGroups.map((g) => g.heading.uuid),
225
+ ...loggedHeadings.map((g) => g.heading.uuid),
226
+ ]);
227
+ const headingCatalog = headings.filter((h) => survivingHeadings.has(h.uuid));
135
228
  return {
136
229
  project,
230
+ items,
231
+ headingCatalog,
137
232
  active,
138
233
  headings: headingGroups,
139
- later: { scheduled, repeating, someday },
234
+ scheduled,
235
+ someday,
236
+ repeating,
140
237
  logged,
141
- trashed,
238
+ loggedHeadings,
142
239
  openChildrenWhileResolved: project.status === "open" ? 0 : openChildren,
240
+ openChildrenUnderArchivedHeading,
143
241
  };
144
242
  }
145
243
  //# sourceMappingURL=project-view.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"project-view.js","sourceRoot":"","sources":["../../src/read/project-view.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-view.js","sourceRoot":"","sources":["../../src/read/project-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The `loose` pseudo-area: a reserved, case-insensitive ref that addresses the
3
+ * NULL area (area-less items) as if it were an area, on READ surfaces only. It
4
+ * mirrors the GUI sidebar's leading loose block — area-less projects, then loose
5
+ * direct to-dos — plus the "Later Projects" someday/scheduled block under
6
+ * `--show-later`. The reserved word ALWAYS wins over a real area that happens to
7
+ * be named "Loose" (that area is reachable only by uuid); when one shadows, the
8
+ * read surfaces a resolution disclosure. Every WRITE verb and the `open` command
9
+ * refuse the reserved word by name — the pseudo-area is a derived view, not a
10
+ * mutable container.
11
+ */
12
+ import type { DatabaseSync } from "node:sqlite";
13
+ /** The reserved ref (lowercase canonical form) that names the loose pseudo-area. */
14
+ export declare const LOOSE_REF = "loose";
15
+ /** True when a ref names the reserved `loose` pseudo-area (case-insensitive, trimmed). */
16
+ export declare function isLooseRef(ref: string): boolean;
17
+ /**
18
+ * The uuid of a real area whose title case-insensitively equals the reserved
19
+ * word, if any — for the resolution-shadow disclosure. Lowest sidebar index
20
+ * wins on the (pathological) chance of duplicates. Returns undefined when no
21
+ * real area shadows the reserved word.
22
+ */
23
+ export declare function shadowingLooseArea(db: DatabaseSync): string | undefined;
24
+ /** The disclosure appended to a loose read when a real area shadows the reserved word. */
25
+ export declare function looseShadowNotice(uuid: string): string;
26
+ /** Refusal for opening the loose pseudo-area — it is a derived view, not an app screen. */
27
+ export declare const LOOSE_OPEN_REFUSAL = "the loose pseudo-area is a derived view \u2014 it cannot be opened; open a specific project or area by ref";
28
+ /** Refusal for `--to-area loose` — the reserved word is a read-only view, not a destination. */
29
+ export declare const LOOSE_TO_AREA_REFUSAL = "the loose pseudo-area is a derived view \u2014 it cannot be modified; to leave a to-do area-less use --loose (a project: --no-area), or target a real area named \"Loose\" by uuid";
@@ -0,0 +1,27 @@
1
+ /** The reserved ref (lowercase canonical form) that names the loose pseudo-area. */
2
+ export const LOOSE_REF = "loose";
3
+ /** True when a ref names the reserved `loose` pseudo-area (case-insensitive, trimmed). */
4
+ export function isLooseRef(ref) {
5
+ return ref.trim().toLowerCase() === LOOSE_REF;
6
+ }
7
+ /**
8
+ * The uuid of a real area whose title case-insensitively equals the reserved
9
+ * word, if any — for the resolution-shadow disclosure. Lowest sidebar index
10
+ * wins on the (pathological) chance of duplicates. Returns undefined when no
11
+ * real area shadows the reserved word.
12
+ */
13
+ export function shadowingLooseArea(db) {
14
+ const row = db
15
+ .prepare(`SELECT uuid FROM TMArea WHERE lower(title) = ? ORDER BY "index" ASC LIMIT 1`)
16
+ .get(LOOSE_REF);
17
+ return row?.uuid;
18
+ }
19
+ /** The disclosure appended to a loose read when a real area shadows the reserved word. */
20
+ export function looseShadowNotice(uuid) {
21
+ return `resolved to the loose pseudo-area; an area named "Loose" exists (uuid ${uuid}) — target it by uuid`;
22
+ }
23
+ /** Refusal for opening the loose pseudo-area — it is a derived view, not an app screen. */
24
+ export const LOOSE_OPEN_REFUSAL = "the loose pseudo-area is a derived view — it cannot be opened; open a specific project or area by ref";
25
+ /** Refusal for `--to-area loose` — the reserved word is a read-only view, not a destination. */
26
+ export const LOOSE_TO_AREA_REFUSAL = 'the loose pseudo-area is a derived view — it cannot be modified; to leave a to-do area-less use --loose (a project: --no-area), or target a real area named "Loose" by uuid';
27
+ //# sourceMappingURL=pseudo-area.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pseudo-area.js","sourceRoot":"","sources":["../../src/read/pseudo-area.ts"],"names":[],"mappings":"AAaA,oFAAoF;AACpF,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC;AAEjC,0FAA0F;AAC1F,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAgB;IACjD,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CAAC,6EAA6E,CAAC;SACtF,GAAG,CAAC,SAAS,CAAiC,CAAC;IAClD,OAAO,GAAG,EAAE,IAAI,CAAC;AACnB,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,yEAAyE,IAAI,uBAAuB,CAAC;AAC9G,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,MAAM,kBAAkB,GAC7B,uGAAuG,CAAC;AAE1G,gGAAgG;AAChG,MAAM,CAAC,MAAM,qBAAqB,GAChC,6KAA6K,CAAC"}