things-api 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/cli/commands/area.d.ts +23 -0
- package/dist/cli/commands/area.js +164 -33
- package/dist/cli/commands/area.js.map +1 -1
- package/dist/cli/commands/project.d.ts +19 -0
- package/dist/cli/commands/project.js +142 -29
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/reads.d.ts +10 -51
- package/dist/cli/commands/reads.js +454 -268
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/show.d.ts +9 -0
- package/dist/cli/commands/show.js +169 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/snapshot.js +1 -1
- package/dist/cli/commands/snapshot.js.map +1 -1
- package/dist/cli/commands/todo.d.ts +9 -0
- package/dist/cli/commands/todo.js +101 -16
- package/dist/cli/commands/todo.js.map +1 -1
- package/dist/cli/commands/writes.js +55 -1
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/did-you-mean.d.ts +29 -0
- package/dist/cli/did-you-mean.js +53 -0
- package/dist/cli/did-you-mean.js.map +1 -0
- package/dist/cli/glyphs.d.ts +95 -0
- package/dist/cli/glyphs.js +282 -0
- package/dist/cli/glyphs.js.map +1 -0
- package/dist/cli/main.js +11 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/period.d.ts +32 -0
- package/dist/cli/period.js +129 -0
- package/dist/cli/period.js.map +1 -0
- package/dist/cli/read-driver.d.ts +76 -0
- package/dist/cli/read-driver.js +181 -0
- package/dist/cli/read-driver.js.map +1 -0
- package/dist/cli/render.d.ts +182 -0
- package/dist/cli/render.js +585 -0
- package/dist/cli/render.js.map +1 -0
- package/dist/cli/resolve-invocation.d.ts +78 -0
- package/dist/cli/resolve-invocation.js +178 -0
- package/dist/cli/resolve-invocation.js.map +1 -0
- package/dist/cli/shell-quote.d.ts +9 -0
- package/dist/cli/shell-quote.js +12 -0
- package/dist/cli/shell-quote.js.map +1 -0
- package/dist/cli/style.d.ts +5 -0
- package/dist/cli/style.js +5 -0
- package/dist/cli/style.js.map +1 -1
- package/dist/client.d.ts +45 -39
- package/dist/client.js +11 -74
- package/dist/client.js.map +1 -1
- package/dist/contracts.d.ts +66 -1
- package/dist/contracts.js +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/db/baselines/db-v26.js +7 -5
- package/dist/db/baselines/db-v26.js.map +1 -1
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +7 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/mcp/server.js +227 -44
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/entities.d.ts +21 -0
- package/dist/model/entities.js.map +1 -1
- package/dist/model/mappers.js +17 -1
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/occurrences.d.ts +6 -1
- package/dist/model/occurrences.js +9 -2
- package/dist/model/occurrences.js.map +1 -1
- package/dist/model/recurrence.d.ts +30 -2
- package/dist/model/recurrence.js +20 -0
- package/dist/model/recurrence.js.map +1 -1
- package/dist/read/area-view.js +21 -5
- package/dist/read/area-view.js.map +1 -1
- package/dist/read/caps.d.ts +14 -0
- package/dist/read/caps.js +21 -0
- package/dist/read/caps.js.map +1 -0
- package/dist/read/detail.js +12 -2
- package/dist/read/detail.js.map +1 -1
- package/dist/read/log-boundary.d.ts +29 -0
- package/dist/read/log-boundary.js +38 -0
- package/dist/read/log-boundary.js.map +1 -0
- package/dist/read/pagination.d.ts +104 -0
- package/dist/read/pagination.js +208 -0
- package/dist/read/pagination.js.map +1 -0
- package/dist/read/predicates.d.ts +31 -0
- package/dist/read/predicates.js +48 -0
- package/dist/read/predicates.js.map +1 -0
- package/dist/read/project-view.js +28 -3
- package/dist/read/project-view.js.map +1 -1
- package/dist/read/queries.d.ts +21 -3
- package/dist/read/queries.js +35 -8
- package/dist/read/queries.js.map +1 -1
- package/dist/read/search-rank.d.ts +36 -0
- package/dist/read/search-rank.js +31 -0
- package/dist/read/search-rank.js.map +1 -0
- package/dist/read/show-target.d.ts +25 -0
- package/dist/read/show-target.js +41 -0
- package/dist/read/show-target.js.map +1 -0
- package/dist/read/sidebar-order.d.ts +19 -0
- package/dist/read/sidebar-order.js +92 -0
- package/dist/read/sidebar-order.js.map +1 -0
- package/dist/read/snapshot.js +2 -0
- package/dist/read/snapshot.js.map +1 -1
- package/dist/read/views.d.ts +64 -8
- package/dist/read/views.js +290 -155
- package/dist/read/views.js.map +1 -1
- package/dist/surface-copy.d.ts +23 -0
- package/dist/surface-copy.js +23 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/write/automation-probe.js +14 -6
- package/dist/write/automation-probe.js.map +1 -1
- package/dist/write/capabilities.d.ts +3 -0
- package/dist/write/capabilities.js +3 -0
- package/dist/write/capabilities.js.map +1 -1
- package/dist/write/checklist.d.ts +50 -0
- package/dist/write/checklist.js +61 -0
- package/dist/write/checklist.js.map +1 -0
- package/dist/write/clear-reminder.d.ts +3 -0
- package/dist/write/clear-reminder.js +205 -0
- package/dist/write/clear-reminder.js.map +1 -0
- package/dist/write/commands.js +122 -8
- package/dist/write/commands.js.map +1 -1
- package/dist/write/edit-checklist.d.ts +3 -0
- package/dist/write/edit-checklist.js +184 -0
- package/dist/write/edit-checklist.js.map +1 -0
- package/dist/write/failure-hints.d.ts +7 -0
- package/dist/write/failure-hints.js +25 -2
- package/dist/write/failure-hints.js.map +1 -1
- package/dist/write/guards.d.ts +1 -1
- package/dist/write/guards.js +16 -0
- package/dist/write/guards.js.map +1 -1
- package/dist/write/operations.d.ts +32 -1
- package/dist/write/operations.js +3 -0
- package/dist/write/operations.js.map +1 -1
- package/dist/write/pipeline.d.ts +3 -0
- package/dist/write/pipeline.js +23 -1
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/reversibility.d.ts +46 -0
- package/dist/write/reversibility.js +164 -0
- package/dist/write/reversibility.js.map +1 -0
- package/dist/write/undo.d.ts +29 -2
- package/dist/write/undo.js +357 -9
- package/dist/write/undo.js.map +1 -1
- package/dist/write/vectors/registry.js +2 -1
- package/dist/write/vectors/registry.js.map +1 -1
- package/dist/write/vectors/shortcuts.d.ts +9 -0
- package/dist/write/vectors/shortcuts.js +90 -0
- package/dist/write/vectors/shortcuts.js.map +1 -0
- package/dist/write/vectors/types.d.ts +11 -3
- package/dist/write/vectors/url-scheme.js +16 -0
- package/dist/write/vectors/url-scheme.js.map +1 -1
- package/dist/write/verify/delta.d.ts +1 -1
- package/dist/write/verify/delta.js +1 -1
- package/dist/write/verify/delta.js.map +1 -1
- package/package.json +1 -1
- package/shortcuts/things-proxy-find-items.shortcut +0 -0
|
@@ -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
|
-
|
|
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
|
package/dist/cli/main.js.map
CHANGED
|
@@ -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
|
|
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;
|