things-api 0.9.0 → 0.10.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 +30 -11
- package/dist/audit/log.js +56 -2
- package/dist/audit/log.js.map +1 -1
- package/dist/audit/schema.d.ts +26 -8
- package/dist/audit/schema.js +42 -1
- package/dist/audit/schema.js.map +1 -1
- package/dist/cli/commands/area.d.ts +26 -3
- package/dist/cli/commands/area.js +125 -70
- package/dist/cli/commands/area.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +1 -1
- package/dist/cli/commands/doctor.js +44 -5
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/mcp.js +23 -4
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/project.d.ts +18 -1
- package/dist/cli/commands/project.js +69 -31
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/reads.js +423 -157
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/repeat-flags.d.ts +20 -0
- package/dist/cli/commands/repeat-flags.js +76 -0
- package/dist/cli/commands/repeat-flags.js.map +1 -0
- package/dist/cli/commands/setup.js +2 -3
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/show.js +47 -24
- package/dist/cli/commands/show.js.map +1 -1
- package/dist/cli/commands/todo.d.ts +1 -1
- package/dist/cli/commands/todo.js +7 -6
- package/dist/cli/commands/todo.js.map +1 -1
- package/dist/cli/commands/writes.js +378 -148
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/did-you-mean.d.ts +1 -1
- package/dist/cli/excess-args.d.ts +15 -0
- package/dist/cli/excess-args.js +51 -0
- package/dist/cli/excess-args.js.map +1 -0
- package/dist/cli/glyphs.d.ts +39 -2
- package/dist/cli/glyphs.js +91 -21
- package/dist/cli/glyphs.js.map +1 -1
- package/dist/cli/help.d.ts +54 -0
- package/dist/cli/help.js +355 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/main.js +32 -25
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/period.d.ts +7 -0
- package/dist/cli/period.js +12 -0
- package/dist/cli/period.js.map +1 -1
- package/dist/cli/read-driver.d.ts +26 -19
- package/dist/cli/read-driver.js +67 -33
- package/dist/cli/read-driver.js.map +1 -1
- package/dist/cli/render.d.ts +92 -28
- package/dist/cli/render.js +318 -97
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/resolve-invocation.d.ts +42 -4
- package/dist/cli/resolve-invocation.js +97 -14
- package/dist/cli/resolve-invocation.js.map +1 -1
- package/dist/cli/tag-filters.d.ts +59 -0
- package/dist/cli/tag-filters.js +57 -0
- package/dist/cli/tag-filters.js.map +1 -0
- package/dist/cli/verb-hint.d.ts +25 -0
- package/dist/cli/verb-hint.js +138 -0
- package/dist/cli/verb-hint.js.map +1 -0
- package/dist/cli/width.d.ts +135 -0
- package/dist/cli/width.js +313 -0
- package/dist/cli/width.js.map +1 -0
- package/dist/client.d.ts +137 -24
- package/dist/client.js +105 -16
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -1
- package/dist/contracts.d.ts +87 -17
- package/dist/contracts.js +44 -1
- package/dist/contracts.js.map +1 -1
- package/dist/db/fingerprint.d.ts +12 -0
- package/dist/db/fingerprint.js +15 -1
- package/dist/db/fingerprint.js.map +1 -1
- package/dist/db/locate.js +1 -1
- package/dist/db/locate.js.map +1 -1
- package/dist/diagnose.d.ts +63 -0
- package/dist/diagnose.js +38 -1
- package/dist/diagnose.js.map +1 -1
- package/dist/index.d.ts +30 -4
- package/dist/index.js +35 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +9 -1
- package/dist/mcp/server.js +691 -133
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/entities.d.ts +31 -7
- package/dist/model/entities.js.map +1 -1
- package/dist/model/mappers.d.ts +7 -0
- package/dist/model/mappers.js +7 -2
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/serialize.d.ts +28 -0
- package/dist/model/serialize.js +80 -0
- package/dist/model/serialize.js.map +1 -0
- package/dist/model/when-sugar.d.ts +47 -0
- package/dist/model/when-sugar.js +45 -0
- package/dist/model/when-sugar.js.map +1 -0
- package/dist/read/area-view.d.ts +8 -1
- package/dist/read/area-view.js +49 -13
- package/dist/read/area-view.js.map +1 -1
- package/dist/read/filter-contract.d.ts +117 -0
- package/dist/read/filter-contract.js +78 -0
- package/dist/read/filter-contract.js.map +1 -0
- package/dist/read/predicates.d.ts +30 -0
- package/dist/read/predicates.js +30 -0
- package/dist/read/predicates.js.map +1 -1
- package/dist/read/project-view.d.ts +12 -1
- package/dist/read/project-view.js +39 -8
- package/dist/read/project-view.js.map +1 -1
- package/dist/read/queries.d.ts +149 -6
- package/dist/read/queries.js +250 -31
- package/dist/read/queries.js.map +1 -1
- package/dist/read/sections.d.ts +51 -0
- package/dist/read/sections.js +37 -0
- package/dist/read/sections.js.map +1 -0
- package/dist/read/sidebar-order.js +2 -1
- package/dist/read/sidebar-order.js.map +1 -1
- package/dist/read/tags.d.ts +27 -3
- package/dist/read/tags.js +83 -12
- package/dist/read/tags.js.map +1 -1
- package/dist/read/truncation.d.ts +71 -0
- package/dist/read/{pagination.js → truncation.js} +103 -94
- package/dist/read/truncation.js.map +1 -0
- package/dist/read/views.d.ts +140 -16
- package/dist/read/views.js +264 -67
- package/dist/read/views.js.map +1 -1
- package/dist/surface-copy.d.ts +19 -0
- package/dist/surface-copy.js +32 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/sync-health.d.ts +78 -0
- package/dist/sync-health.js +312 -0
- package/dist/sync-health.js.map +1 -0
- package/dist/write/accessibility-probe.d.ts +12 -0
- package/dist/write/accessibility-probe.js +63 -0
- package/dist/write/accessibility-probe.js.map +1 -0
- package/dist/write/automation-probe.d.ts +7 -0
- package/dist/write/automation-probe.js +8 -1
- package/dist/write/automation-probe.js.map +1 -1
- package/dist/write/batch.js +4 -2
- package/dist/write/batch.js.map +1 -1
- package/dist/write/capabilities.d.ts +8 -0
- package/dist/write/capabilities.js +13 -6
- package/dist/write/capabilities.js.map +1 -1
- package/dist/write/commands.d.ts +2 -0
- package/dist/write/commands.js +562 -48
- package/dist/write/commands.js.map +1 -1
- package/dist/write/edit-checklist.js +3 -2
- package/dist/write/edit-checklist.js.map +1 -1
- package/dist/write/guards.d.ts +2 -7
- package/dist/write/guards.js +64 -6
- package/dist/write/guards.js.map +1 -1
- package/dist/write/heading.js +2 -0
- package/dist/write/heading.js.map +1 -1
- package/dist/write/lock.d.ts +40 -2
- package/dist/write/lock.js +91 -14
- package/dist/write/lock.js.map +1 -1
- package/dist/write/make-repeating-project.d.ts +4 -0
- package/dist/write/make-repeating-project.js +253 -0
- package/dist/write/make-repeating-project.js.map +1 -0
- package/dist/write/operations.d.ts +145 -1
- package/dist/write/operations.js +48 -0
- package/dist/write/operations.js.map +1 -1
- package/dist/write/pipeline.d.ts +19 -0
- package/dist/write/pipeline.js +109 -26
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/pre-state.d.ts +68 -3
- package/dist/write/pre-state.js +102 -3
- package/dist/write/pre-state.js.map +1 -1
- package/dist/write/reopen.js +3 -2
- package/dist/write/reopen.js.map +1 -1
- package/dist/write/reorder.js +27 -17
- package/dist/write/reorder.js.map +1 -1
- package/dist/write/repeat-rule.d.ts +22 -0
- package/dist/write/repeat-rule.js +258 -0
- package/dist/write/repeat-rule.js.map +1 -0
- package/dist/write/reversibility.js +49 -0
- package/dist/write/reversibility.js.map +1 -1
- package/dist/write/tag-refs.d.ts +47 -0
- package/dist/write/tag-refs.js +126 -0
- package/dist/write/tag-refs.js.map +1 -0
- package/dist/write/undo.d.ts +74 -5
- package/dist/write/undo.js +493 -80
- package/dist/write/undo.js.map +1 -1
- package/dist/write/vectors/registry.d.ts +17 -1
- package/dist/write/vectors/registry.js +18 -2
- package/dist/write/vectors/registry.js.map +1 -1
- package/dist/write/vectors/types.d.ts +119 -3
- package/dist/write/vectors/ui-certification.d.ts +48 -0
- package/dist/write/vectors/ui-certification.js +46 -0
- package/dist/write/vectors/ui-certification.js.map +1 -0
- package/dist/write/vectors/ui-drag.d.ts +188 -0
- package/dist/write/vectors/ui-drag.js +1095 -0
- package/dist/write/vectors/ui-drag.js.map +1 -0
- package/dist/write/vectors/ui-recipes.d.ts +70 -0
- package/dist/write/vectors/ui-recipes.js +558 -0
- package/dist/write/vectors/ui-recipes.js.map +1 -0
- package/dist/write/vectors/ui.d.ts +137 -0
- package/dist/write/vectors/ui.js +656 -0
- package/dist/write/vectors/ui.js.map +1 -0
- package/dist/write/verify/delta.d.ts +31 -3
- package/dist/write/verify/delta.js +22 -6
- package/dist/write/verify/delta.js.map +1 -1
- package/dist/write/verify/poller.js +1 -0
- package/dist/write/verify/poller.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/exit-codes.d.ts +0 -26
- package/dist/cli/exit-codes.js +0 -26
- package/dist/cli/exit-codes.js.map +0 -1
- package/dist/cli/output.d.ts +0 -42
- package/dist/cli/output.js +0 -16
- package/dist/cli/output.js.map +0 -1
- package/dist/read/pagination.d.ts +0 -104
- package/dist/read/pagination.js.map +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure STRUCTURAL decomposition of the sidebar catalogues (anytime/someday)
|
|
3
|
+
* into their innermost item blocks, plus the per-block cap shape the bounding
|
|
4
|
+
* layer applies. No capping and no counts live here — this module only splits a
|
|
5
|
+
* section into (direct/loose to-dos, per-project child lists); the actual
|
|
6
|
+
* truncation is layered on top in ./truncation.ts. Split out so the human
|
|
7
|
+
* renderers (src/cli/render.ts) can re-derive block structure WITHOUT importing
|
|
8
|
+
* the truncation module (the surface/library layering boundary).
|
|
9
|
+
*/
|
|
10
|
+
import type { Ref } from "../model/entities.ts";
|
|
11
|
+
import type { ListItem, SidebarSection } from "./views.ts";
|
|
12
|
+
/**
|
|
13
|
+
* Per-block caps for the grouped catalogues: `area` bounds each area-direct
|
|
14
|
+
* block (and the leading loose block), `project` each project's to-do list.
|
|
15
|
+
* `null` = uncapped (the caller passed --all / all: true, or — for someday's
|
|
16
|
+
* active-projects section — asked for every item).
|
|
17
|
+
*/
|
|
18
|
+
export interface GroupedLimits {
|
|
19
|
+
area: number | null;
|
|
20
|
+
project: number | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Split one sidebar section into its innermost item blocks: the direct
|
|
24
|
+
* to-dos that precede any project row, then one block per project (the
|
|
25
|
+
* project row plus the to-dos that follow it until the next project).
|
|
26
|
+
*/
|
|
27
|
+
export interface SectionBlocks {
|
|
28
|
+
direct: ListItem[];
|
|
29
|
+
projects: Array<{
|
|
30
|
+
project: ListItem;
|
|
31
|
+
items: ListItem[];
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export declare function splitSectionBlocks(section: SidebarSection): SectionBlocks;
|
|
35
|
+
/**
|
|
36
|
+
* Someday sections split differently from anytime: PROJECT rows there are
|
|
37
|
+
* plain ITEMS (a someday project stands for itself — its children are never
|
|
38
|
+
* inline), so a section's "own" block is its project rows + container-less
|
|
39
|
+
* to-dos together, and the to-dos that DO carry a project reference (the
|
|
40
|
+
* activeProjectItems toggle) form separate per-project child groups.
|
|
41
|
+
*/
|
|
42
|
+
export interface SomedayPartition {
|
|
43
|
+
/** Project rows + direct to-dos, in section order. */
|
|
44
|
+
own: ListItem[];
|
|
45
|
+
/** Someday to-dos inside active projects, clustered per project. */
|
|
46
|
+
children: Array<{
|
|
47
|
+
project: Ref;
|
|
48
|
+
items: ListItem[];
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
51
|
+
export declare function partitionSomedaySection(section: SidebarSection): SomedayPartition;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function splitSectionBlocks(section) {
|
|
2
|
+
const direct = [];
|
|
3
|
+
const projects = [];
|
|
4
|
+
let cur = null;
|
|
5
|
+
for (const item of section.items) {
|
|
6
|
+
if (item.type === "project") {
|
|
7
|
+
cur = { project: item, items: [] };
|
|
8
|
+
projects.push(cur);
|
|
9
|
+
}
|
|
10
|
+
else if (cur === null) {
|
|
11
|
+
direct.push(item);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
cur.items.push(item);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return { direct, projects };
|
|
18
|
+
}
|
|
19
|
+
export function partitionSomedaySection(section) {
|
|
20
|
+
const own = [];
|
|
21
|
+
const byProject = new Map();
|
|
22
|
+
for (const item of section.items) {
|
|
23
|
+
const container = item.type === "to-do" ? (item.project ?? item.headingProject ?? null) : null;
|
|
24
|
+
if (container === null) {
|
|
25
|
+
own.push(item);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
let group = byProject.get(container.uuid);
|
|
29
|
+
if (group === undefined) {
|
|
30
|
+
group = { project: container, items: [] };
|
|
31
|
+
byProject.set(container.uuid, group);
|
|
32
|
+
}
|
|
33
|
+
group.items.push(item);
|
|
34
|
+
}
|
|
35
|
+
return { own, children: [...byProject.values()] };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sections.js","sourceRoot":"","sources":["../../src/read/sections.ts"],"names":[],"mappings":"AAiCA,MAAM,UAAU,kBAAkB,CAAC,OAAuB;IACxD,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAoD,EAAE,CAAC;IACrE,IAAI,GAAG,GAAoD,IAAI,CAAC;IAChE,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,GAAG,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YACnC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC;AAgBD,MAAM,UAAU,uBAAuB,CAAC,OAAuB;IAC7D,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAA+C,CAAC;IACzE,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/F,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YAC1C,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;AACpD,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** `?, ?, …` SQL placeholder list of length n. */
|
|
2
|
+
const inList = (n) => Array.from({ length: n }, () => "?").join(", ");
|
|
1
3
|
/**
|
|
2
4
|
* Arranges view members into the UI's flat sidebar-mirroring order: the
|
|
3
5
|
* area-less block first (direct to-dos, then each top-level project followed
|
|
@@ -8,7 +10,6 @@
|
|
|
8
10
|
export function groupBySidebar(db, items) {
|
|
9
11
|
if (items.length === 0)
|
|
10
12
|
return [];
|
|
11
|
-
const inList = (n) => Array.from({ length: n }, () => "?").join(", ");
|
|
12
13
|
// Headed children: resolve heading -> project.
|
|
13
14
|
const headingUuids = [
|
|
14
15
|
...new Set(items.flatMap((i) => (i.type === "to-do" && i.heading !== null ? [i.heading.uuid] : []))),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar-order.js","sourceRoot":"","sources":["../../src/read/sidebar-order.ts"],"names":[],"mappings":"AAaA
|
|
1
|
+
{"version":3,"file":"sidebar-order.js","sourceRoot":"","sources":["../../src/read/sidebar-order.ts"],"names":[],"mappings":"AAaA,kDAAkD;AAClD,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,EAAgB,EAAE,KAAiB;IAChE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,+CAA+C;IAC/C,MAAM,YAAY,GAAG;QACnB,GAAG,IAAI,GAAG,CACR,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACzF;KACF,CAAC;IACF,MAAM,cAAc,GAAG,IAAI,GAAG,EAAyB,CAAC;IACxD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,EAAE;aACjB,OAAO,CAAC,mDAAmD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1F,GAAG,CAAC,GAAG,YAAY,CAAoD,EAAE,CAAC;YAC3E,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,CAAC,CAAW,EAAiB,EAAE,CAChD,CAAC,CAAC,IAAI,KAAK,OAAO;QAChB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI;YAChB,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAElF,4EAA4E;IAC5E,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,EAAE;SAChB,OAAO,CAAC,wEAAwE,CAAC;SACjF,GAAG,EAAmD,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG;QACnB,GAAG,IAAI,GAAG,CAAC;YACT,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC/D,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACrB,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBACxB,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC,CAAC;SACH,CAAC;KACH,CAAC;IACF,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkD,CAAC;IAC9E,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,EAAE;aACjB,OAAO,CACN,yDAAyD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CACxF;aACA,GAAG,CAAC,GAAG,YAAY,CAAuE,EAAE,CAAC;YAC9F,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,gEAAgE;IAChE,MAAM,OAAO,GAAG,CAAC,CAAW,EAAE,GAAW,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;QAChD,OAAO;YACL,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC;YACtE,IAAI,EAAE,IAAI,IAAI,EAAE;YAChB,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,YAAY,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;YAC9B,OAAO,EAAE,OAAO,IAAI,EAAE;YACtB,WAAW,EAAE,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,GAAG;YACH,IAAI,EAAE,CAAC,CAAC,IAAI;SACb,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CACR,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ;QAC3B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAC7B,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACtC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW;QACjC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;QACjB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CACnC,CAAC;IAEF,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjE,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE;gBACzF,KAAK,EAAE,EAAE;aACV,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/read/tags.d.ts
CHANGED
|
@@ -8,10 +8,34 @@
|
|
|
8
8
|
* direct tags.
|
|
9
9
|
*/
|
|
10
10
|
import type { DatabaseSync } from "node:sqlite";
|
|
11
|
-
import type { Area, Ref, Tag } from "../model/entities.ts";
|
|
11
|
+
import type { Area, Ref, Tag, TagRef } from "../model/entities.ts";
|
|
12
12
|
import type { TaskRow } from "../model/mappers.ts";
|
|
13
|
+
/**
|
|
14
|
+
* The `things tags` listing: the tag TREE, depth-first, so a child always
|
|
15
|
+
* FOLLOWS its parent. Siblings (and roots) order by canonical `TMTag."index"`
|
|
16
|
+
* (the app's Tags-window rank), UUID tiebreak (TAGORD1 oracle — the Tags-window
|
|
17
|
+
* order for index-tied tags is uuid-ascending, not alphabetical; see
|
|
18
|
+
* fetchTagsForTasks).
|
|
19
|
+
*
|
|
20
|
+
* DFS is unambiguous here and matches the Tags window: this is a listing of the
|
|
21
|
+
* hierarchy itself, where the parent→child relationship is the structure. That
|
|
22
|
+
* is DISTINCT from a flat multi-tag pill row (fetchTagsForTasks / areaTags),
|
|
23
|
+
* where the ratified order is flat ascending `index` and the nested-tag
|
|
24
|
+
* interleave is an open question — see fetchTagsForTasks for that caveat.
|
|
25
|
+
*/
|
|
13
26
|
export declare function tagsView(db: DatabaseSync): Tag[];
|
|
14
27
|
export declare function areasView(db: DatabaseSync): Area[];
|
|
15
28
|
export declare function areaTags(db: DatabaseSync, areaUuid: string): Ref[];
|
|
16
|
-
/**
|
|
17
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Tags inherited from ancestors (the heading's project, the project, the area),
|
|
31
|
+
* surfaced by NAME as a plain list ({@link TagRef}) parallel to the item's own
|
|
32
|
+
* direct tags. The item's OWN direct tags are excluded (they render on the
|
|
33
|
+
* `tags:` line, not here). Which tags are inherited is still computed — a
|
|
34
|
+
* heading cannot be tagged (TAGINH1, VM-verified), so the chain is
|
|
35
|
+
* heading → project → area — but no container source/provenance is emitted.
|
|
36
|
+
*
|
|
37
|
+
* ORDER: the merged inherited set is returned in the app's CANONICAL tag order
|
|
38
|
+
* — `TMTag."index"`, uuid tiebreak (TAGORD1) — the SAME comparator the direct
|
|
39
|
+
* pill row uses (fetchTagsForTasks), applied across the project+area union.
|
|
40
|
+
*/
|
|
41
|
+
export declare function inheritedTagsFor(db: DatabaseSync, row: TaskRow): TagRef[];
|
package/dist/read/tags.js
CHANGED
|
@@ -1,19 +1,57 @@
|
|
|
1
1
|
import { q, selectList } from "../db/schema.js";
|
|
2
2
|
import { fetchTagsForTasks, fetchTaskByUuid } from "./queries.js";
|
|
3
|
+
/**
|
|
4
|
+
* The `things tags` listing: the tag TREE, depth-first, so a child always
|
|
5
|
+
* FOLLOWS its parent. Siblings (and roots) order by canonical `TMTag."index"`
|
|
6
|
+
* (the app's Tags-window rank), UUID tiebreak (TAGORD1 oracle — the Tags-window
|
|
7
|
+
* order for index-tied tags is uuid-ascending, not alphabetical; see
|
|
8
|
+
* fetchTagsForTasks).
|
|
9
|
+
*
|
|
10
|
+
* DFS is unambiguous here and matches the Tags window: this is a listing of the
|
|
11
|
+
* hierarchy itself, where the parent→child relationship is the structure. That
|
|
12
|
+
* is DISTINCT from a flat multi-tag pill row (fetchTagsForTasks / areaTags),
|
|
13
|
+
* where the ratified order is flat ascending `index` and the nested-tag
|
|
14
|
+
* interleave is an open question — see fetchTagsForTasks for that caveat.
|
|
15
|
+
*/
|
|
3
16
|
export function tagsView(db) {
|
|
4
17
|
const rows = db
|
|
5
|
-
.prepare(`SELECT ${selectList("TMTag")} FROM TMTag ORDER BY ${q("index")} ASC`)
|
|
18
|
+
.prepare(`SELECT ${selectList("TMTag")} FROM TMTag ORDER BY ${q("index")} ASC, uuid ASC`)
|
|
6
19
|
.all();
|
|
7
20
|
const byUuid = new Map(rows.map((r) => [r.uuid, r]));
|
|
8
|
-
|
|
21
|
+
// Children grouped under their parent uuid, each list already in index/title
|
|
22
|
+
// order (the SQL sort is stable and preserves the sibling ordering).
|
|
23
|
+
const childrenOf = new Map();
|
|
24
|
+
for (const row of rows) {
|
|
25
|
+
if (!row.parent)
|
|
26
|
+
continue;
|
|
27
|
+
(childrenOf.get(row.parent) ?? childrenOf.set(row.parent, []).get(row.parent)).push(row);
|
|
28
|
+
}
|
|
29
|
+
const out = [];
|
|
30
|
+
const seen = new Set();
|
|
31
|
+
const visit = (row) => {
|
|
32
|
+
if (seen.has(row.uuid))
|
|
33
|
+
return; // cycle guard (bad parent data can't loop)
|
|
34
|
+
seen.add(row.uuid);
|
|
9
35
|
const parentRow = row.parent ? byUuid.get(row.parent) : undefined;
|
|
10
|
-
|
|
11
|
-
uuid: row.uuid,
|
|
36
|
+
out.push({
|
|
12
37
|
title: row.title ?? "",
|
|
13
38
|
shortcut: row.shortcut,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
39
|
+
// Parent tag's NAME (null for a root) — the tree is reconstructable from
|
|
40
|
+
// names alone; tag uuids are never surfaced.
|
|
41
|
+
parent: parentRow ? (parentRow.title ?? "") : null,
|
|
42
|
+
});
|
|
43
|
+
for (const child of childrenOf.get(row.uuid) ?? [])
|
|
44
|
+
visit(child);
|
|
45
|
+
};
|
|
46
|
+
// Roots first (no parent, or an orphan whose parent uuid is absent), in index
|
|
47
|
+
// order; DFS pulls each subtree. A final pass emits any row a parent cycle
|
|
48
|
+
// left unreached, so the listing never silently drops a tag.
|
|
49
|
+
for (const row of rows)
|
|
50
|
+
if (!row.parent || !byUuid.has(row.parent))
|
|
51
|
+
visit(row);
|
|
52
|
+
for (const row of rows)
|
|
53
|
+
visit(row);
|
|
54
|
+
return out;
|
|
17
55
|
}
|
|
18
56
|
export function areasView(db) {
|
|
19
57
|
const rows = db
|
|
@@ -23,23 +61,41 @@ export function areasView(db) {
|
|
|
23
61
|
uuid: row.uuid,
|
|
24
62
|
title: row.title ?? "",
|
|
25
63
|
visible: row.visible !== 0,
|
|
26
|
-
tags
|
|
64
|
+
// Surface area tags by NAME only (tag uuids are internal).
|
|
65
|
+
tags: areaTags(db, row.uuid).map((t) => ({ title: t.title })),
|
|
27
66
|
}));
|
|
28
67
|
}
|
|
29
68
|
export function areaTags(db, areaUuid) {
|
|
69
|
+
// Canonical pill order: ascending TMTag."index" (the app's Tags-window rank),
|
|
70
|
+
// UUID tiebreak. Same comparator + nested-tag caveat as fetchTagsForTasks.
|
|
30
71
|
const rows = db
|
|
31
72
|
.prepare(`SELECT tg.uuid AS uuid, tg.title AS title
|
|
32
73
|
FROM TMAreaTag at JOIN TMTag tg ON tg.uuid = at.tags
|
|
33
|
-
WHERE at.areas = ? ORDER BY tg.
|
|
74
|
+
WHERE at.areas = ? ORDER BY tg.${q("index")}, tg.uuid`)
|
|
34
75
|
.all(areaUuid);
|
|
35
76
|
return rows.map((r) => ({ uuid: r.uuid, title: r.title ?? "" }));
|
|
36
77
|
}
|
|
37
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Tags inherited from ancestors (the heading's project, the project, the area),
|
|
80
|
+
* surfaced by NAME as a plain list ({@link TagRef}) parallel to the item's own
|
|
81
|
+
* direct tags. The item's OWN direct tags are excluded (they render on the
|
|
82
|
+
* `tags:` line, not here). Which tags are inherited is still computed — a
|
|
83
|
+
* heading cannot be tagged (TAGINH1, VM-verified), so the chain is
|
|
84
|
+
* heading → project → area — but no container source/provenance is emitted.
|
|
85
|
+
*
|
|
86
|
+
* ORDER: the merged inherited set is returned in the app's CANONICAL tag order
|
|
87
|
+
* — `TMTag."index"`, uuid tiebreak (TAGORD1) — the SAME comparator the direct
|
|
88
|
+
* pill row uses (fetchTagsForTasks), applied across the project+area union.
|
|
89
|
+
*/
|
|
38
90
|
export function inheritedTagsFor(db, row) {
|
|
91
|
+
// Work with uuid-carrying rows INTERNALLY (dedup + canonical ranking need the
|
|
92
|
+
// uuid); the surfaced TagRef carries the tag NAME only. First-seen wins on a
|
|
93
|
+
// duplicate — the nearer ancestor (project, collected before area) is kept.
|
|
39
94
|
const collected = new Map();
|
|
40
95
|
const addAll = (refs) => {
|
|
41
96
|
for (const ref of refs)
|
|
42
|
-
collected.
|
|
97
|
+
if (!collected.has(ref.uuid))
|
|
98
|
+
collected.set(ref.uuid, ref);
|
|
43
99
|
};
|
|
44
100
|
let projectUuid = row.project;
|
|
45
101
|
if (!projectUuid && row.heading) {
|
|
@@ -57,6 +113,21 @@ export function inheritedTagsFor(db, row) {
|
|
|
57
113
|
if (areaUuid)
|
|
58
114
|
addAll(areaTags(db, areaUuid));
|
|
59
115
|
const direct = new Set((fetchTagsForTasks(db, [row.uuid]).get(row.uuid) ?? []).map((t) => t.uuid));
|
|
60
|
-
|
|
116
|
+
const result = [...collected.values()].filter((ref) => !direct.has(ref.uuid));
|
|
117
|
+
if (result.length > 1) {
|
|
118
|
+
// Re-rank the project+area union in one canonical `index, uuid` pass so the
|
|
119
|
+
// merged inherited chips match the GUI's tag order (the per-source lists
|
|
120
|
+
// arrive already ordered, but their concatenation is not globally sorted).
|
|
121
|
+
const rank = new Map();
|
|
122
|
+
const uuids = result.map((ref) => ref.uuid);
|
|
123
|
+
const rows = db
|
|
124
|
+
.prepare(`SELECT uuid FROM TMTag WHERE uuid IN (${uuids.map(() => "?").join(", ")})
|
|
125
|
+
ORDER BY ${q("index")}, uuid`)
|
|
126
|
+
.all(...uuids);
|
|
127
|
+
rows.forEach((r, i) => rank.set(r.uuid, i));
|
|
128
|
+
result.sort((a, b) => (rank.get(a.uuid) ?? 0) - (rank.get(b.uuid) ?? 0));
|
|
129
|
+
}
|
|
130
|
+
// Surface the tag NAME only (uuid stays internal).
|
|
131
|
+
return result.map((ref) => ({ title: ref.title }));
|
|
61
132
|
}
|
|
62
133
|
//# sourceMappingURL=tags.js.map
|
package/dist/read/tags.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/read/tags.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWlE,MAAM,UAAU,QAAQ,CAAC,EAAgB;IACvC,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CAAC,UAAU,UAAU,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/read/tags.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared list-view truncation: turn a full, filtered result into the rows a
|
|
3
|
+
* surface actually shows (default 50) plus the exact {@link Truncation}
|
|
4
|
+
* metadata every surface reports so nothing is ever silently dropped. The
|
|
5
|
+
* limit counts ITEMS in render order and truncates mid-group; grouped shapes
|
|
6
|
+
* (the Today split, sidebar sections) drop the trailing groups that fall
|
|
7
|
+
* entirely past the cut so no empty header survives. `limit === null` means
|
|
8
|
+
* "all rows" (the caller passed --all / all: true).
|
|
9
|
+
*/
|
|
10
|
+
import type { GroupedTruncation, Truncation } from "../contracts.ts";
|
|
11
|
+
import { type AreaView } from "./area-view.ts";
|
|
12
|
+
import { AREA_PREVIEW_LIMIT, DEFAULT_LIST_LIMIT, PROJECT_PREVIEW_LIMIT } from "../surface-copy.ts";
|
|
13
|
+
import type { SidebarSection, TodayView } from "./views.ts";
|
|
14
|
+
import { partitionSomedaySection, splitSectionBlocks, type GroupedLimits } from "./sections.ts";
|
|
15
|
+
export { AREA_PREVIEW_LIMIT, DEFAULT_LIST_LIMIT, PROJECT_PREVIEW_LIMIT };
|
|
16
|
+
export { partitionSomedaySection, splitSectionBlocks, type GroupedLimits };
|
|
17
|
+
/** Flat list: slice to the limit; total is the full filtered length. */
|
|
18
|
+
export declare function truncateList<T>(items: T[], limit: number | null): {
|
|
19
|
+
data: T[];
|
|
20
|
+
truncation: Truncation;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Today split: the cut runs across Today then This Evening in render order,
|
|
24
|
+
* so a limit smaller than the Today block trims Evening to nothing. The badge
|
|
25
|
+
* (a whole-view count summary) is preserved unchanged. The truncation carries
|
|
26
|
+
* a per-section (`today`/`evening`) shown/total breakdown so a renderer can
|
|
27
|
+
* keep This Evening honest under the single global cap without a pre-cap copy.
|
|
28
|
+
*/
|
|
29
|
+
export declare function truncateToday(view: TodayView, limit: number | null): {
|
|
30
|
+
data: TodayView;
|
|
31
|
+
truncation: Truncation;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Anytime: the block skeleton is ALWAYS complete — every area header and
|
|
35
|
+
* every project row survives — and the caps apply INDEPENDENTLY to each
|
|
36
|
+
* innermost item list: `limits.area` to the loose block and each area's
|
|
37
|
+
* direct to-dos, `limits.project` to each project's to-dos. Returns the
|
|
38
|
+
* per-block-truncated sections (project rows retained) plus the per-block
|
|
39
|
+
* counts and a top-level `truncated` flag.
|
|
40
|
+
*/
|
|
41
|
+
export declare function previewSections(sections: SidebarSection[], limits: GroupedLimits): {
|
|
42
|
+
data: SidebarSection[];
|
|
43
|
+
grouped: GroupedTruncation;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Someday preview: every group survives; `limits.area` (null = no cap)
|
|
47
|
+
* applies independently to each section's own block (project rows + direct
|
|
48
|
+
* to-dos are items alike there), `limits.project` to each active project's
|
|
49
|
+
* child group (the show-active-project-items toggle). Sections keep their
|
|
50
|
+
* capped children after the own block, still clustered per project.
|
|
51
|
+
*/
|
|
52
|
+
export declare function previewSomedaySections(sections: SidebarSection[], limits: GroupedLimits): {
|
|
53
|
+
data: SidebarSection[];
|
|
54
|
+
grouped: GroupedTruncation;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Sectioned cap for the `area show` detail view: its sections are containers,
|
|
58
|
+
* so there is no strict total limit — instead `limits.project` bounds the
|
|
59
|
+
* ACTIVE project-ROWS section and `limits.area` the direct-to-dos section
|
|
60
|
+
* (null = uncapped). The cap is render-aware: only the area's ACTIVE project
|
|
61
|
+
* rows are capped, while its future-scheduled and someday project rows always
|
|
62
|
+
* survive (the card renders them under its uncapped Upcoming/Someday sections),
|
|
63
|
+
* so the human view derives entirely from this bounded shape. The toggled
|
|
64
|
+
* later/logged lists and the trashed bucket pass through untouched. Counts ride
|
|
65
|
+
* the same grouped-block shape the sidebar catalogues emit (kind "projects" =
|
|
66
|
+
* the active project-rows section). `now` classifies the schedule split.
|
|
67
|
+
*/
|
|
68
|
+
export declare function capAreaSections(view: AreaView, limits: GroupedLimits, now?: Date): {
|
|
69
|
+
data: AreaView;
|
|
70
|
+
grouped: GroupedTruncation;
|
|
71
|
+
};
|