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.
Files changed (154) hide show
  1. package/README.md +6 -3
  2. package/dist/cli/commands/area.d.ts +23 -0
  3. package/dist/cli/commands/area.js +164 -33
  4. package/dist/cli/commands/area.js.map +1 -1
  5. package/dist/cli/commands/project.d.ts +19 -0
  6. package/dist/cli/commands/project.js +142 -29
  7. package/dist/cli/commands/project.js.map +1 -1
  8. package/dist/cli/commands/reads.d.ts +10 -51
  9. package/dist/cli/commands/reads.js +454 -268
  10. package/dist/cli/commands/reads.js.map +1 -1
  11. package/dist/cli/commands/show.d.ts +9 -0
  12. package/dist/cli/commands/show.js +169 -0
  13. package/dist/cli/commands/show.js.map +1 -0
  14. package/dist/cli/commands/snapshot.js +1 -1
  15. package/dist/cli/commands/snapshot.js.map +1 -1
  16. package/dist/cli/commands/todo.d.ts +9 -0
  17. package/dist/cli/commands/todo.js +101 -16
  18. package/dist/cli/commands/todo.js.map +1 -1
  19. package/dist/cli/commands/writes.js +55 -1
  20. package/dist/cli/commands/writes.js.map +1 -1
  21. package/dist/cli/did-you-mean.d.ts +29 -0
  22. package/dist/cli/did-you-mean.js +53 -0
  23. package/dist/cli/did-you-mean.js.map +1 -0
  24. package/dist/cli/glyphs.d.ts +95 -0
  25. package/dist/cli/glyphs.js +282 -0
  26. package/dist/cli/glyphs.js.map +1 -0
  27. package/dist/cli/main.js +11 -1
  28. package/dist/cli/main.js.map +1 -1
  29. package/dist/cli/period.d.ts +32 -0
  30. package/dist/cli/period.js +129 -0
  31. package/dist/cli/period.js.map +1 -0
  32. package/dist/cli/read-driver.d.ts +76 -0
  33. package/dist/cli/read-driver.js +181 -0
  34. package/dist/cli/read-driver.js.map +1 -0
  35. package/dist/cli/render.d.ts +182 -0
  36. package/dist/cli/render.js +585 -0
  37. package/dist/cli/render.js.map +1 -0
  38. package/dist/cli/resolve-invocation.d.ts +78 -0
  39. package/dist/cli/resolve-invocation.js +178 -0
  40. package/dist/cli/resolve-invocation.js.map +1 -0
  41. package/dist/cli/shell-quote.d.ts +9 -0
  42. package/dist/cli/shell-quote.js +12 -0
  43. package/dist/cli/shell-quote.js.map +1 -0
  44. package/dist/cli/style.d.ts +5 -0
  45. package/dist/cli/style.js +5 -0
  46. package/dist/cli/style.js.map +1 -1
  47. package/dist/client.d.ts +45 -39
  48. package/dist/client.js +11 -74
  49. package/dist/client.js.map +1 -1
  50. package/dist/contracts.d.ts +66 -1
  51. package/dist/contracts.js +1 -1
  52. package/dist/contracts.js.map +1 -1
  53. package/dist/db/baselines/db-v26.js +7 -5
  54. package/dist/db/baselines/db-v26.js.map +1 -1
  55. package/dist/db/schema.d.ts +1 -1
  56. package/dist/db/schema.js +7 -1
  57. package/dist/db/schema.js.map +1 -1
  58. package/dist/mcp/server.js +227 -44
  59. package/dist/mcp/server.js.map +1 -1
  60. package/dist/model/entities.d.ts +21 -0
  61. package/dist/model/entities.js.map +1 -1
  62. package/dist/model/mappers.js +17 -1
  63. package/dist/model/mappers.js.map +1 -1
  64. package/dist/model/occurrences.d.ts +6 -1
  65. package/dist/model/occurrences.js +9 -2
  66. package/dist/model/occurrences.js.map +1 -1
  67. package/dist/model/recurrence.d.ts +30 -2
  68. package/dist/model/recurrence.js +20 -0
  69. package/dist/model/recurrence.js.map +1 -1
  70. package/dist/read/area-view.js +21 -5
  71. package/dist/read/area-view.js.map +1 -1
  72. package/dist/read/caps.d.ts +14 -0
  73. package/dist/read/caps.js +21 -0
  74. package/dist/read/caps.js.map +1 -0
  75. package/dist/read/detail.js +12 -2
  76. package/dist/read/detail.js.map +1 -1
  77. package/dist/read/log-boundary.d.ts +29 -0
  78. package/dist/read/log-boundary.js +38 -0
  79. package/dist/read/log-boundary.js.map +1 -0
  80. package/dist/read/pagination.d.ts +104 -0
  81. package/dist/read/pagination.js +208 -0
  82. package/dist/read/pagination.js.map +1 -0
  83. package/dist/read/predicates.d.ts +31 -0
  84. package/dist/read/predicates.js +48 -0
  85. package/dist/read/predicates.js.map +1 -0
  86. package/dist/read/project-view.js +28 -3
  87. package/dist/read/project-view.js.map +1 -1
  88. package/dist/read/queries.d.ts +21 -3
  89. package/dist/read/queries.js +35 -8
  90. package/dist/read/queries.js.map +1 -1
  91. package/dist/read/search-rank.d.ts +36 -0
  92. package/dist/read/search-rank.js +31 -0
  93. package/dist/read/search-rank.js.map +1 -0
  94. package/dist/read/show-target.d.ts +25 -0
  95. package/dist/read/show-target.js +41 -0
  96. package/dist/read/show-target.js.map +1 -0
  97. package/dist/read/sidebar-order.d.ts +19 -0
  98. package/dist/read/sidebar-order.js +92 -0
  99. package/dist/read/sidebar-order.js.map +1 -0
  100. package/dist/read/snapshot.js +2 -0
  101. package/dist/read/snapshot.js.map +1 -1
  102. package/dist/read/views.d.ts +64 -8
  103. package/dist/read/views.js +290 -155
  104. package/dist/read/views.js.map +1 -1
  105. package/dist/surface-copy.d.ts +23 -0
  106. package/dist/surface-copy.js +23 -0
  107. package/dist/surface-copy.js.map +1 -1
  108. package/dist/write/automation-probe.js +14 -6
  109. package/dist/write/automation-probe.js.map +1 -1
  110. package/dist/write/capabilities.d.ts +3 -0
  111. package/dist/write/capabilities.js +3 -0
  112. package/dist/write/capabilities.js.map +1 -1
  113. package/dist/write/checklist.d.ts +50 -0
  114. package/dist/write/checklist.js +61 -0
  115. package/dist/write/checklist.js.map +1 -0
  116. package/dist/write/clear-reminder.d.ts +3 -0
  117. package/dist/write/clear-reminder.js +205 -0
  118. package/dist/write/clear-reminder.js.map +1 -0
  119. package/dist/write/commands.js +122 -8
  120. package/dist/write/commands.js.map +1 -1
  121. package/dist/write/edit-checklist.d.ts +3 -0
  122. package/dist/write/edit-checklist.js +184 -0
  123. package/dist/write/edit-checklist.js.map +1 -0
  124. package/dist/write/failure-hints.d.ts +7 -0
  125. package/dist/write/failure-hints.js +25 -2
  126. package/dist/write/failure-hints.js.map +1 -1
  127. package/dist/write/guards.d.ts +1 -1
  128. package/dist/write/guards.js +16 -0
  129. package/dist/write/guards.js.map +1 -1
  130. package/dist/write/operations.d.ts +32 -1
  131. package/dist/write/operations.js +3 -0
  132. package/dist/write/operations.js.map +1 -1
  133. package/dist/write/pipeline.d.ts +3 -0
  134. package/dist/write/pipeline.js +23 -1
  135. package/dist/write/pipeline.js.map +1 -1
  136. package/dist/write/reversibility.d.ts +46 -0
  137. package/dist/write/reversibility.js +164 -0
  138. package/dist/write/reversibility.js.map +1 -0
  139. package/dist/write/undo.d.ts +29 -2
  140. package/dist/write/undo.js +357 -9
  141. package/dist/write/undo.js.map +1 -1
  142. package/dist/write/vectors/registry.js +2 -1
  143. package/dist/write/vectors/registry.js.map +1 -1
  144. package/dist/write/vectors/shortcuts.d.ts +9 -0
  145. package/dist/write/vectors/shortcuts.js +90 -0
  146. package/dist/write/vectors/shortcuts.js.map +1 -0
  147. package/dist/write/vectors/types.d.ts +11 -3
  148. package/dist/write/vectors/url-scheme.js +16 -0
  149. package/dist/write/vectors/url-scheme.js.map +1 -1
  150. package/dist/write/verify/delta.d.ts +1 -1
  151. package/dist/write/verify/delta.js +1 -1
  152. package/dist/write/verify/delta.js.map +1 -1
  153. package/package.json +1 -1
  154. package/shortcuts/things-proxy-find-items.shortcut +0 -0
@@ -0,0 +1,282 @@
1
+ import { blue, bold, brightBlue, dim, green, red, strike, underline, yellow } from "./style.js";
2
+ const MONTHS = [
3
+ "Jan",
4
+ "Feb",
5
+ "Mar",
6
+ "Apr",
7
+ "May",
8
+ "Jun",
9
+ "Jul",
10
+ "Aug",
11
+ "Sep",
12
+ "Oct",
13
+ "Nov",
14
+ "Dec",
15
+ ];
16
+ const WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
17
+ /** `Jul 31` — the year is appended only when it differs from today's. */
18
+ export function shortDate(iso, todayIso) {
19
+ const [y, m, d] = iso.split("-").map(Number);
20
+ const label = `${MONTHS[(m ?? 1) - 1]} ${d}`;
21
+ return String(y) === todayIso.slice(0, 4) ? label : `${label} ${y}`;
22
+ }
23
+ /**
24
+ * `Fri, Aug 28` — the GUI's detail-header date form: weekday abbreviation +
25
+ * month + day, the year appended only when it differs from today's (same
26
+ * convention as {@link shortDate} / the ‹date› chip).
27
+ */
28
+ export function weekdayDate(iso, todayIso) {
29
+ const [y, m, d] = iso.split("-").map(Number);
30
+ const weekday = WEEKDAYS[new Date(Date.UTC(y ?? 0, (m ?? 1) - 1, d ?? 1)).getUTCDay()];
31
+ return `${weekday}, ${shortDate(iso, todayIso)}`;
32
+ }
33
+ /** The GUI's grey schedule pill: `‹Jul 31›` on future-scheduled rows. */
34
+ export function dateChip(iso, todayIso) {
35
+ return dim(`‹${shortDate(iso, todayIso)}›`);
36
+ }
37
+ /** Completion date on logged rows (the GUI's blue date before the title). */
38
+ export function loggedDate(stopped, todayIso) {
39
+ const iso = `${stopped.getFullYear()}-${String(stopped.getMonth() + 1).padStart(2, "0")}-${String(stopped.getDate()).padStart(2, "0")}`;
40
+ return bold(blue(shortDate(iso, todayIso)));
41
+ }
42
+ /**
43
+ * To-do checkbox: `[ ]` open, `[✓]` completed, `[×]` canceled, `[~]`
44
+ * someday (undated — a dated someday row reads as scheduled and keeps the
45
+ * plain box; its date chip carries the state).
46
+ */
47
+ export function todoBox(item) {
48
+ if (item.status === "completed")
49
+ return blue("[✓]");
50
+ if (item.status === "canceled")
51
+ return blue("[×]");
52
+ // A repeating TEMPLATE is the rule itself, not a checkable instance — the
53
+ // GUI shows only the ↻ glyph where a checkbox would be. We keep the
54
+ // brackets (still a to-do) but seat ↻ INSIDE them so the row reads as
55
+ // "the recurring one" at a glance, distinct from its spawned instances
56
+ // (which are ordinary [ ] rows). Never someday, though the DB stores it so.
57
+ if (item.repeating.isTemplate)
58
+ return dim("[↻]");
59
+ if (item.start === "someday" && item.startDate === null)
60
+ return dim("[~]");
61
+ return "[ ]";
62
+ }
63
+ /**
64
+ * Project circle — round where to-dos are square, same marks: `( )` open,
65
+ * `(✓)` completed, `(×)` canceled, `(~)` someday. (The pie-fill progress
66
+ * glyphs were tried and dropped — they render inconsistently at cell size;
67
+ * progress lives in the ratio chip instead.)
68
+ */
69
+ export function projectCircle(item) {
70
+ if (item.status === "completed")
71
+ return blue("(✓)");
72
+ if (item.status === "canceled")
73
+ return blue("(×)");
74
+ // Repeating project template: ↻ inside the circle (the to-do rule above).
75
+ if (item.repeating.isTemplate)
76
+ return dim("(↻)");
77
+ // Open projects render blue — GUI parity (the sidebar/list accent) and a
78
+ // second, color-independent cue on top of the round bracket that this row
79
+ // is a project, not a to-do.
80
+ if (item.start === "someday" && item.startDate === null)
81
+ return blue("(~)");
82
+ return blue("( )");
83
+ }
84
+ /** Progress chip on project rows: `‹remaining/total›` (the GUI shows only the remaining count). */
85
+ export function countChip(item) {
86
+ const total = item.untrashedLeafActionsCount;
87
+ return dim(total === 0 ? "‹0›" : `‹${item.openUntrashedLeafActionsCount}/${total}›`);
88
+ }
89
+ /** Area marker (the GUI's green cube icon; a hexagon is a cube's silhouette). */
90
+ export const areaMark = () => green("⬡");
91
+ /** Whole-day difference between two ISO dates (positive = `to` is later). */
92
+ function daysBetween(fromIso, toIso) {
93
+ const [fy, fm, fd] = fromIso.split("-").map(Number);
94
+ const [ty, tm, td] = toIso.split("-").map(Number);
95
+ return Math.round((Date.UTC(ty ?? 0, (tm ?? 1) - 1, td ?? 1) - Date.UTC(fy ?? 0, (fm ?? 1) - 1, fd ?? 1)) /
96
+ 86_400_000);
97
+ }
98
+ /**
99
+ * Uncapped relative phrasing for the detail-card deadline hint, GUI wording:
100
+ * `due today`, `46 days left`, `3 days overdue`.
101
+ */
102
+ function deadlineRelative(iso, todayIso) {
103
+ const diff = daysBetween(todayIso, iso);
104
+ if (diff === 0)
105
+ return "due today";
106
+ return diff > 0
107
+ ? `${diff} day${diff === 1 ? "" : "s"} left`
108
+ : `${-diff} day${diff === -1 ? "" : "s"} overdue`;
109
+ }
110
+ /**
111
+ * Detail-card deadline line value (to-do / project / area cards). GUI parity:
112
+ * the full `Fri, Aug 28` weekday date (year appended when not the current
113
+ * year), then a muted relative hint — `(46 days left)` / `(due today)` /
114
+ * `(3 days overdue)`. The date is bold red once due or overdue, bold otherwise;
115
+ * the hint is always muted. LIST rows keep the compact {@link deadlineToken}.
116
+ */
117
+ export function deadlineDetail(deadlineIso, todayIso) {
118
+ const date = weekdayDate(deadlineIso, todayIso);
119
+ const styledDate = daysBetween(todayIso, deadlineIso) <= 0 ? bold(red(date)) : bold(date);
120
+ return `${styledDate} ${dim(`(${deadlineRelative(deadlineIso, todayIso)})`)}`;
121
+ }
122
+ /** The share link the GUI's context menu copies — pasteable back into any ref argument. */
123
+ export function thingsLink(uuid) {
124
+ return dim(`things:///show?id=${uuid}`);
125
+ }
126
+ /**
127
+ * The detail card's "when" value, GUI semantics: any past or current
128
+ * schedule collapses to Today / This Evening (the data model keeps the real
129
+ * date; the card does not), future dates show the date, undated someday
130
+ * shows Someday. Appends the reminder time (clock glyph) when set.
131
+ */
132
+ export function whenValue(item, todayIso) {
133
+ let label = null;
134
+ if (item.startDate !== null) {
135
+ label =
136
+ item.startDate <= todayIso
137
+ ? item.todaySection === "evening"
138
+ ? `${eveningMoon()} This Evening`
139
+ : `${todayStar()} Today`
140
+ : shortDate(item.startDate, todayIso);
141
+ }
142
+ else if (item.start === "someday") {
143
+ label = "Someday";
144
+ }
145
+ if (label === null)
146
+ return null;
147
+ return item.reminder === null ? label : `${label} ${dim(REMINDER_MARK)} ${item.reminder}`;
148
+ }
149
+ /**
150
+ * Deadline token, mirroring the GUI's flag chip: relative phrasing near the
151
+ * deadline (`⚑ 3 days left` up to 14 days out; `⚑ 4 days ago` up to 59 days
152
+ * past; `⚑ today` on the day), then the date shorthand — `Sep 16` within
153
+ * the current year, `Feb 2027` beyond it. Overdue and due-today render
154
+ * bold red; upcoming renders bold dim (the GUI's gray).
155
+ */
156
+ export function deadlineToken(deadlineIso, todayIso) {
157
+ const diff = daysBetween(todayIso, deadlineIso);
158
+ let label;
159
+ if (diff === 0)
160
+ label = "today";
161
+ else if (diff > 0 && diff <= 14)
162
+ label = `${diff} day${diff === 1 ? "" : "s"} left`;
163
+ else if (diff < 0 && diff >= -59)
164
+ label = `${-diff} day${diff === -1 ? "" : "s"} ago`;
165
+ else {
166
+ const [y, m, d] = deadlineIso.split("-").map(Number);
167
+ const month = MONTHS[(m ?? 1) - 1];
168
+ label = String(y) === todayIso.slice(0, 4) ? `${month} ${d}` : `${month} ${y}`;
169
+ }
170
+ const chip = `⚑ ${label}`;
171
+ return diff <= 0 ? bold(red(chip)) : bold(dim(chip));
172
+ }
173
+ /** Notes-present marker (the GUI's small document icon). */
174
+ export const NOTES_MARK = "≡";
175
+ /**
176
+ * Reminder-set marker (the GUI's small bell icon; no Unicode bell renders
177
+ * well — the clock-face quadrant won Mike's font test, accepted despite its
178
+ * family resemblance to the project pies).
179
+ */
180
+ export const REMINDER_MARK = "◷";
181
+ /** Checklist-present marker (the GUI's small list icon). */
182
+ export const CHECKLIST_MARK = "≔";
183
+ /** Today star / This-Evening crescent, rendered after the box in today-aware views. */
184
+ export const todayStar = () => yellow("★");
185
+ export const eveningMoon = () => brightBlue("⏾");
186
+ export const LEGEND_GROUPS = [
187
+ "To-dos",
188
+ "Projects",
189
+ "Markers & chips",
190
+ "Colors & styles",
191
+ "Sections & hints",
192
+ ];
193
+ /**
194
+ * The rendered visual language, derived from the glyph helpers above so it
195
+ * documents what actually renders — never a hand-kept copy that can drift.
196
+ * Each `glyph` is a real sample built from the same styling the list rows use;
197
+ * `things legend` groups these for humans and `--json` emits them ANSI-stripped.
198
+ */
199
+ export const LEGEND = [
200
+ // To-dos — the [ ]-family box carries state with color stripped.
201
+ { glyph: "[ ]", meaning: "to-do, open", group: "To-dos" },
202
+ { glyph: blue("[✓]"), meaning: "to-do, completed", group: "To-dos" },
203
+ { glyph: blue("[×]"), meaning: "to-do, canceled (title struck through)", group: "To-dos" },
204
+ { glyph: dim("[~]"), meaning: "to-do, someday (undated)", group: "To-dos" },
205
+ {
206
+ glyph: dim("[↻]"),
207
+ meaning: "repeating to-do — the rule itself (instances are ordinary [ ])",
208
+ group: "To-dos",
209
+ },
210
+ // Projects — round where to-dos are square; open rows render blue.
211
+ { glyph: blue("( )"), meaning: "project, open", group: "Projects" },
212
+ { glyph: blue("(✓)"), meaning: "project, completed", group: "Projects" },
213
+ { glyph: blue("(×)"), meaning: "project, canceled", group: "Projects" },
214
+ { glyph: blue("(~)"), meaning: "project, someday (undated)", group: "Projects" },
215
+ {
216
+ glyph: dim("(↻)"),
217
+ meaning: "repeating project — the recurring rule itself",
218
+ group: "Projects",
219
+ },
220
+ {
221
+ glyph: dim("‹2/5›"),
222
+ meaning: "project progress: remaining/total to-dos (‹0› when it has none)",
223
+ group: "Projects",
224
+ },
225
+ // Markers & chips — trail the title (bell, notes, checklist) or precede it.
226
+ { glyph: todayStar(), meaning: "Today member", group: "Markers & chips" },
227
+ { glyph: eveningMoon(), meaning: "This Evening member", group: "Markers & chips" },
228
+ {
229
+ glyph: bold(dim("⚑")),
230
+ meaning: "deadline — bold gray while upcoming, bold red once due or overdue",
231
+ group: "Markers & chips",
232
+ },
233
+ { glyph: dim(NOTES_MARK), meaning: "has notes", group: "Markers & chips" },
234
+ { glyph: dim(REMINDER_MARK), meaning: "has a reminder time", group: "Markers & chips" },
235
+ { glyph: dim(CHECKLIST_MARK), meaning: "has a checklist", group: "Markers & chips" },
236
+ { glyph: areaMark(), meaning: "area", group: "Markers & chips" },
237
+ {
238
+ glyph: dim("‹Jul 31›"),
239
+ meaning: "scheduled date (year appended when not the current year)",
240
+ group: "Markers & chips",
241
+ },
242
+ {
243
+ glyph: green("#tag"),
244
+ meaning: "tag — muted on list rows, green on the opened item",
245
+ group: "Markers & chips",
246
+ },
247
+ // Colors & styles — enhancements on top of the shape; never the only cue.
248
+ {
249
+ glyph: dim("a1b2c3d4"),
250
+ meaning: "item id prefix (8+ chars; full id in --json) — pass to any command",
251
+ group: "Colors & styles",
252
+ },
253
+ {
254
+ glyph: dim("dim text"),
255
+ meaning: "later, hidden, inactive, or completed row",
256
+ group: "Colors & styles",
257
+ },
258
+ { glyph: strike("struck"), meaning: "canceled item title", group: "Colors & styles" },
259
+ { glyph: blue("blue"), meaning: "open project (its circle and title)", group: "Colors & styles" },
260
+ {
261
+ glyph: bold(underline("bold underline")),
262
+ meaning: "container header — a project title row, or a section header",
263
+ group: "Colors & styles",
264
+ },
265
+ // Sections & hints — structure and the never-silent truncation notices.
266
+ {
267
+ glyph: bold("──"),
268
+ meaning: "section divider (area, Upcoming date bucket, Logbook month heading)",
269
+ group: "Sections & hints",
270
+ },
271
+ {
272
+ glyph: dim("… 14 more"),
273
+ meaning: "a block was truncated; a drill-down command follows",
274
+ group: "Sections & hints",
275
+ },
276
+ {
277
+ glyph: dim("(23 later — --show-later)"),
278
+ meaning: "default-hidden rows, and the flag that reveals them",
279
+ group: "Sections & hints",
280
+ },
281
+ ];
282
+ //# sourceMappingURL=glyphs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glyphs.js","sourceRoot":"","sources":["../../src/cli/glyphs.ts"],"names":[],"mappings":"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"}
package/dist/cli/main.js CHANGED
@@ -13,9 +13,11 @@ import { registerAreaCommands } from "./commands/area.js";
13
13
  import { registerProjectCommands } from "./commands/project.js";
14
14
  import { registerReadCommands } from "./commands/reads.js";
15
15
  import { registerSetup } from "./commands/setup.js";
16
+ import { registerShowCommands } from "./commands/show.js";
16
17
  import { registerSnapshot } from "./commands/snapshot.js";
17
18
  import { registerTodoCommands } from "./commands/todo.js";
18
19
  import { registerWriteCommands } from "./commands/writes.js";
20
+ import { resolveInvocation } from "./resolve-invocation.js";
19
21
  import { ExitCode, PKG_VERSION } from "../contracts.js";
20
22
  const AGENT_NOTES = `
21
23
  AGENT NOTES:
@@ -25,11 +27,14 @@ AGENT NOTES:
25
27
  fail with the candidates listed.
26
28
  - A Things share link (Share > Copy Link, "things:///show?id=<uuid>") is
27
29
  accepted anywhere a uuid or name is expected — it is stripped to the id.
30
+ - The word \`show\` may be omitted: \`things <ref>\` shows the referenced
31
+ item whenever <ref> is not a command name (command names always win).
28
32
  - Exit codes are stable: 0 ok, 2 usage, 3 verify-failed, 4 blocked,
29
33
  5 drift-blocked, 6 unsupported, 7 environment.
30
34
  - No command ever prompts interactively; operations with cascading or
31
35
  permanent effects require explicit flags documented in their --help.
32
36
  - Discover the full operation catalog with: things capabilities --json
37
+ - Symbols & colors in list output: run \`things legend\` (add --json for the table).
33
38
  - Every write supports --dry-run: preview the planned change and its
34
39
  expected effect without executing anything.
35
40
  - Failures are loud: a change that does not take effect exits 3; refused
@@ -44,6 +49,7 @@ export function buildProgram() {
44
49
  .addHelpText("after", AGENT_NOTES);
45
50
  registerDoctor(program);
46
51
  registerReadCommands(program);
52
+ registerShowCommands(program);
47
53
  registerProjectCommands(program);
48
54
  registerAreaCommands(program);
49
55
  registerTodoCommands(program);
@@ -58,7 +64,11 @@ export function runCli() {
58
64
  program.exitOverride((err) => {
59
65
  process.exit(err.exitCode === 0 ? ExitCode.Ok : ExitCode.Usage);
60
66
  });
61
- program.parse();
67
+ // The single router (docs/design/cli-grammar.md): classify the invocation,
68
+ // then dispatch its normalized argv. Sugar forms (bare noun, keyword-in-show)
69
+ // normalize into the canonical grammar here.
70
+ const { argv } = resolveInvocation(program, process.argv.slice(2));
71
+ program.parse(argv, { from: "user" });
62
72
  }
63
73
  // Direct-run detection must survive the npm .bin symlink (argv[1] ends with
64
74
  // "things", not "main.js") — resolve through realpath and compare to this
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AACA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;CAiBnB,CAAC;AAEF,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,QAAQ,CAAC;SACd,WAAW,CAAC,oDAAoD,CAAC;SACjE,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IACrC,cAAc,CAAC,OAAO,CAAC,CAAC;IACxB,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,CAAC,OAAO,CAAC,CAAC;IACvB,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1B,WAAW,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,MAAM;IACpB,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;IAC/B,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC;AAED,4EAA4E;AAC5E,0EAA0E;AAC1E,wEAAwE;AACxE,4EAA4E;AAC5E,+BAA+B;AAC/B,MAAM,WAAW,GAAG,CAAC,GAAY,EAAE;IACjC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC,EAAE,CAAC;AACL,IAAI,WAAW,EAAE,CAAC;IAChB,MAAM,EAAE,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Period-and-calendar grammar shared by the read views: the `--since`/`--until`
3
+ * whole-period parsers, the relative-period (`3d`/`2w`/`1m`/`1y`) grammar, and
4
+ * the Upcoming date-bucket labeller. Fully pure — no CLI or app imports — so
5
+ * the renderers and command registrations can both draw on it.
6
+ */
7
+ declare const FULL_MONTHS: readonly ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
8
+ export { FULL_MONTHS };
9
+ /**
10
+ * `--until` accepting whole periods: `2024` means through Dec 31 2024,
11
+ * `2024-03` through Mar 31, `2024-03-05` through end of that day; relative
12
+ * periods (`2w`, `1m`, `1y`) count FORWARD from now through the end of the
13
+ * landing day; anything else parses as an instant.
14
+ */
15
+ export declare function parsePeriodEnd(s: string, now?: Date): Date;
16
+ /**
17
+ * `--since` accepting the same vocabulary at the period's START: `2024` =
18
+ * Jan 1 2024 00:00, `2024-03` = Mar 1, `2024-03-05` = that midnight;
19
+ * relative periods (`2w`, `1m`) count BACKWARD from now to the landing
20
+ * day's midnight; anything else parses as an instant.
21
+ */
22
+ export declare function parsePeriodStart(s: string, now?: Date): Date;
23
+ /**
24
+ * GUI-style Upcoming bucket for a date, granularity decaying with distance:
25
+ * individual days for the next week ("Wed Jul 15"), the remainder of the
26
+ * current month ("Jul 19–31"), months through the end of NEXT year
27
+ * ("August", "January 2027"), then bare years ("2028").
28
+ */
29
+ export declare function upcomingBucket(iso: string, todayIso: string): {
30
+ label: string;
31
+ isDay: boolean;
32
+ };
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Period-and-calendar grammar shared by the read views: the `--since`/`--until`
3
+ * whole-period parsers, the relative-period (`3d`/`2w`/`1m`/`1y`) grammar, and
4
+ * the Upcoming date-bucket labeller. Fully pure — no CLI or app imports — so
5
+ * the renderers and command registrations can both draw on it.
6
+ */
7
+ const FULL_MONTHS = [
8
+ "January",
9
+ "February",
10
+ "March",
11
+ "April",
12
+ "May",
13
+ "June",
14
+ "July",
15
+ "August",
16
+ "September",
17
+ "October",
18
+ "November",
19
+ "December",
20
+ ];
21
+ const WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
22
+ const SHORT_MONTHS = [
23
+ "Jan",
24
+ "Feb",
25
+ "Mar",
26
+ "Apr",
27
+ "May",
28
+ "Jun",
29
+ "Jul",
30
+ "Aug",
31
+ "Sep",
32
+ "Oct",
33
+ "Nov",
34
+ "Dec",
35
+ ];
36
+ export { FULL_MONTHS };
37
+ /**
38
+ * Relative period: `3d`/`2w`/`1m`/`1y` (days/weeks/calendar months/years),
39
+ * counted from `now` — FORWARD for an until-bound, BACKWARD for a since-
40
+ * bound (each command's natural direction; the flag name carries it).
41
+ */
42
+ const RELATIVE_PERIOD = /^(\d+)([dwmy])$/i;
43
+ function relativePeriodDate(m, now, sign) {
44
+ const n = sign * Number(m[1]);
45
+ const unit = (m[2] ?? "").toLowerCase();
46
+ const d = new Date(now);
47
+ if (unit === "d")
48
+ d.setDate(d.getDate() + n);
49
+ else if (unit === "w")
50
+ d.setDate(d.getDate() + 7 * n);
51
+ else if (unit === "m")
52
+ d.setMonth(d.getMonth() + n);
53
+ else
54
+ d.setFullYear(d.getFullYear() + n);
55
+ return d;
56
+ }
57
+ /**
58
+ * `--until` accepting whole periods: `2024` means through Dec 31 2024,
59
+ * `2024-03` through Mar 31, `2024-03-05` through end of that day; relative
60
+ * periods (`2w`, `1m`, `1y`) count FORWARD from now through the end of the
61
+ * landing day; anything else parses as an instant.
62
+ */
63
+ export function parsePeriodEnd(s, now = new Date()) {
64
+ const rel = RELATIVE_PERIOD.exec(s.trim());
65
+ if (rel !== null) {
66
+ const d = relativePeriodDate(rel, now, 1);
67
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
68
+ }
69
+ const m = /^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?$/.exec(s.trim());
70
+ if (m === null)
71
+ return new Date(s);
72
+ const year = Number(m[1]);
73
+ // Day 0 of month n+1 = the last day of month n.
74
+ if (m[2] === undefined)
75
+ return new Date(year, 11, 31, 23, 59, 59, 999);
76
+ const month = Number(m[2]) - 1;
77
+ if (m[3] === undefined)
78
+ return new Date(year, month + 1, 0, 23, 59, 59, 999);
79
+ return new Date(year, month, Number(m[3]), 23, 59, 59, 999);
80
+ }
81
+ /**
82
+ * `--since` accepting the same vocabulary at the period's START: `2024` =
83
+ * Jan 1 2024 00:00, `2024-03` = Mar 1, `2024-03-05` = that midnight;
84
+ * relative periods (`2w`, `1m`) count BACKWARD from now to the landing
85
+ * day's midnight; anything else parses as an instant.
86
+ */
87
+ export function parsePeriodStart(s, now = new Date()) {
88
+ const rel = RELATIVE_PERIOD.exec(s.trim());
89
+ if (rel !== null) {
90
+ const d = relativePeriodDate(rel, now, -1);
91
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate());
92
+ }
93
+ const m = /^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?$/.exec(s.trim());
94
+ if (m === null)
95
+ return new Date(s);
96
+ const year = Number(m[1]);
97
+ if (m[2] === undefined)
98
+ return new Date(year, 0, 1);
99
+ const month = Number(m[2]) - 1;
100
+ if (m[3] === undefined)
101
+ return new Date(year, month, 1);
102
+ return new Date(year, month, Number(m[3]));
103
+ }
104
+ /**
105
+ * GUI-style Upcoming bucket for a date, granularity decaying with distance:
106
+ * individual days for the next week ("Wed Jul 15"), the remainder of the
107
+ * current month ("Jul 19–31"), months through the end of NEXT year
108
+ * ("August", "January 2027"), then bare years ("2028").
109
+ */
110
+ export function upcomingBucket(iso, todayIso) {
111
+ const [y, m, d] = iso.split("-").map(Number);
112
+ const [y0, m0, d0] = todayIso.split("-").map(Number);
113
+ const diff = Math.round((Date.UTC(y ?? 0, (m ?? 1) - 1, d ?? 1) - Date.UTC(y0 ?? 0, (m0 ?? 1) - 1, d0 ?? 1)) /
114
+ 86_400_000);
115
+ if (diff <= 7) {
116
+ const weekday = WEEKDAYS[new Date(Date.UTC(y ?? 0, (m ?? 1) - 1, d ?? 1)).getUTCDay()];
117
+ return { label: `${weekday} ${SHORT_MONTHS[(m ?? 1) - 1]} ${d}`, isDay: true };
118
+ }
119
+ if (y === y0 && m === m0) {
120
+ const lastDay = new Date(y ?? 0, m ?? 1, 0).getDate();
121
+ return { label: `${SHORT_MONTHS[(m ?? 1) - 1]} ${(d0 ?? 1) + 8}–${lastDay}`, isDay: false };
122
+ }
123
+ if ((y ?? 0) <= (y0 ?? 0) + 1) {
124
+ const month = FULL_MONTHS[(m ?? 1) - 1];
125
+ return { label: y === y0 ? `${month}` : `${month} ${y}`, isDay: false };
126
+ }
127
+ return { label: `${y}`, isDay: false };
128
+ }
129
+ //# sourceMappingURL=period.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"period.js","sourceRoot":"","sources":["../../src/cli/period.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The read driver: open the client, stamp the envelope meta, and emit either
3
+ * the `--json` envelope or human lines (with the TTY-only title preamble,
4
+ * normalized-form echo, and truncation hint). Plus the shared `--limit`/`--all`
5
+ * cap parsing and the invocation-echo helpers every read command reuses. No
6
+ * commander dependency — command registration lives in the command modules.
7
+ */
8
+ import { type ThingsClient } from "../client.ts";
9
+ import { type GroupedPagination, type Pagination } from "../contracts.ts";
10
+ export interface GlobalReadOpts {
11
+ json?: boolean;
12
+ db?: string;
13
+ }
14
+ export interface PagedResult<T> {
15
+ data: T;
16
+ /** Flat-view truncation — carried into meta and the appended hint. */
17
+ pagination?: Pagination;
18
+ /** Grouped-view (anytime/someday) per-block truncation — carried into meta. */
19
+ grouped?: GroupedPagination;
20
+ /**
21
+ * Precomputed human lines. Grouped views render inside `fn` (where the full
22
+ * per-block totals live) and hand the finished lines back here; when absent,
23
+ * `render(data)` produces them.
24
+ */
25
+ lines?: string[];
26
+ }
27
+ /**
28
+ * The shared read driver: open the client, stamp the envelope meta (including
29
+ * fingerprint + optional pagination), and either emit the `--json` envelope or
30
+ * render human lines. When `hintBase` is given and the result was truncated,
31
+ * the muted "N more items" hint (reconstructing the user's own invocation) is
32
+ * appended to the human output — never to `--json`. When `header` names a view,
33
+ * its title preamble leads the human output on a TTY only (viewHeaderLines).
34
+ */
35
+ export declare function runRead<T>(opts: GlobalReadOpts, kind: string, fn: (client: ThingsClient) => PagedResult<T>, render: (data: T) => string[], hintBase?: string, header?: string): void;
36
+ /**
37
+ * Structured single-payload read: `fn` produces the whole payload, `render`
38
+ * turns it into human lines. Generic so `fn`'s return type flows into
39
+ * `render`'s parameter — the compiler verifies the renderer matches the data.
40
+ */
41
+ export declare function withClient<T>(opts: GlobalReadOpts, kind: string, fn: (client: ThingsClient) => T, render: (data: T) => string[]): void;
42
+ /** Result of resolving `--limit`/`--all`; `limit: null` means every row. */
43
+ export type LimitResolution = {
44
+ ok: true;
45
+ limit: number | null;
46
+ } | {
47
+ ok: false;
48
+ };
49
+ /**
50
+ * Resolve the shared `--limit`/`--all` pair (flat views) into a row cap
51
+ * (null = no cap), writing a loud usage error and setting the exit code on
52
+ * bad input: `--limit` must be a positive integer, and it may not combine
53
+ * with `--all`.
54
+ */
55
+ export declare function parseLimit(opts: {
56
+ limit?: string;
57
+ all?: boolean;
58
+ }): LimitResolution;
59
+ /**
60
+ * Resolve one cap flag (`--limit`, `--area-limit`, `--project-limit`) against
61
+ * `--all`: positive integer required, `--all` conflicts with an explicit
62
+ * value and otherwise lifts the cap (null). The conflict/default decision is
63
+ * the shared {@link resolveCap}; this surface adds the string→integer
64
+ * validation and the usage-error emission.
65
+ */
66
+ export declare function parseCap(flag: string, value: string | undefined, defaultLimit: number, all: boolean): LimitResolution;
67
+ export { shellQuote } from "./shell-quote.ts";
68
+ /** Reconstruct `things <name> <flags…>`, dropping falsy/empty parts. */
69
+ export declare function invocation(name: string, parts: Array<string | false | undefined>): string;
70
+ /**
71
+ * The unified truncation hint: a muted `── N more items — see more: … · all:
72
+ * … ──` line whose commands echo the user's actual invocation, so a bigger
73
+ * `--limit` or `--all` is one copy-paste away. Returns null when nothing was
74
+ * dropped or the caller already asked for every row.
75
+ */
76
+ export declare function truncationHint(base: string, pagination: Pagination): string | null;