@redjay/threads-core 1.1.0 → 1.2.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 (55) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +42 -42
  3. package/dist/domain/agenda.d.ts +31 -0
  4. package/dist/domain/agenda.d.ts.map +1 -0
  5. package/dist/domain/agenda.js +60 -0
  6. package/dist/domain/agenda.js.map +1 -0
  7. package/dist/domain/batch.d.ts +67 -0
  8. package/dist/domain/batch.d.ts.map +1 -0
  9. package/dist/domain/batch.js +151 -0
  10. package/dist/domain/batch.js.map +1 -0
  11. package/dist/domain/clone.d.ts +31 -0
  12. package/dist/domain/clone.d.ts.map +1 -0
  13. package/dist/domain/clone.js +69 -0
  14. package/dist/domain/clone.js.map +1 -0
  15. package/dist/domain/index.d.ts +12 -0
  16. package/dist/domain/index.d.ts.map +1 -0
  17. package/dist/domain/index.js +30 -0
  18. package/dist/domain/index.js.map +1 -0
  19. package/dist/domain/merge.d.ts +25 -0
  20. package/dist/domain/merge.d.ts.map +1 -0
  21. package/dist/domain/merge.js +47 -0
  22. package/dist/domain/merge.js.map +1 -0
  23. package/dist/domain/overview.d.ts +41 -0
  24. package/dist/domain/overview.d.ts.map +1 -0
  25. package/dist/domain/overview.js +95 -0
  26. package/dist/domain/overview.js.map +1 -0
  27. package/dist/domain/progress.d.ts +28 -0
  28. package/dist/domain/progress.d.ts.map +1 -0
  29. package/dist/domain/progress.js +45 -0
  30. package/dist/domain/progress.js.map +1 -0
  31. package/dist/domain/scoring.d.ts +40 -0
  32. package/dist/domain/scoring.d.ts.map +1 -0
  33. package/dist/domain/scoring.js +64 -0
  34. package/dist/domain/scoring.js.map +1 -0
  35. package/dist/domain/search.d.ts +31 -0
  36. package/dist/domain/search.d.ts.map +1 -0
  37. package/dist/domain/search.js +59 -0
  38. package/dist/domain/search.js.map +1 -0
  39. package/dist/domain/sorting.d.ts +17 -0
  40. package/dist/domain/sorting.d.ts.map +1 -0
  41. package/dist/domain/sorting.js +32 -0
  42. package/dist/domain/sorting.js.map +1 -0
  43. package/dist/domain/time.d.ts +78 -0
  44. package/dist/domain/time.d.ts.map +1 -0
  45. package/dist/domain/time.js +146 -0
  46. package/dist/domain/time.js.map +1 -0
  47. package/dist/domain/timeline.d.ts +43 -0
  48. package/dist/domain/timeline.d.ts.map +1 -0
  49. package/dist/domain/timeline.js +65 -0
  50. package/dist/domain/timeline.js.map +1 -0
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +2 -0
  54. package/dist/index.js.map +1 -1
  55. package/package.json +62 -54
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Joshua Ramirez
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Joshua Ramirez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,42 +1,42 @@
1
- # @redjay/threads-core
2
-
3
- Core types and models for the Threads platform.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @redjay/threads-core
9
- ```
10
-
11
- ## Usage
12
-
13
- ```typescript
14
- import { Thread, Container, Progress, ThreadStatus, Temperature } from '@redjay/threads-core';
15
- import { createThread, createProgress } from '@redjay/threads-core/models';
16
- ```
17
-
18
- ## Types
19
-
20
- ### Thread
21
-
22
- Represents a stream of activity with:
23
- - `status`: active, paused, stopped, completed, archived
24
- - `temperature`: frozen, freezing, cold, tepid, warm, hot (momentum indicator)
25
- - `size`: tiny, small, medium, large, huge (scope)
26
- - `importance`: 1-5 priority level
27
-
28
- ### Container
29
-
30
- Organizational node for grouping threads without momentum semantics.
31
-
32
- ### Progress
33
-
34
- Timestamped notes for tracking activity on a thread.
35
-
36
- ### Dependencies
37
-
38
- Links between threads with why/what/how/when context.
39
-
40
- ## License
41
-
42
- MIT
1
+ # @redjay/threads-core
2
+
3
+ Core types and models for the Threads platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @redjay/threads-core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { Thread, Container, Progress, ThreadStatus, Temperature } from '@redjay/threads-core';
15
+ import { createThread, createProgress } from '@redjay/threads-core/models';
16
+ ```
17
+
18
+ ## Types
19
+
20
+ ### Thread
21
+
22
+ Represents a stream of activity with:
23
+ - `status`: active, paused, stopped, completed, archived
24
+ - `temperature`: frozen, freezing, cold, tepid, warm, hot (momentum indicator)
25
+ - `size`: tiny, small, medium, large, huge (scope)
26
+ - `importance`: 1-5 priority level
27
+
28
+ ### Container
29
+
30
+ Organizational node for grouping threads without momentum semantics.
31
+
32
+ ### Progress
33
+
34
+ Timestamped notes for tracking activity on a thread.
35
+
36
+ ### Dependencies
37
+
38
+ Links between threads with why/what/how/when context.
39
+
40
+ ## License
41
+
42
+ MIT
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Thread categorization into agenda buckets.
3
+ *
4
+ * Pure function — takes Thread[] and options, returns categorized sections.
5
+ * Uses time.ts + sorting.ts internally.
6
+ */
7
+ import { Thread } from '../models/types';
8
+ /** Categorized thread sections for the agenda view. */
9
+ export interface AgendaCategories {
10
+ hotThreads: Thread[];
11
+ activeInPeriod: Thread[];
12
+ needsAttention: Thread[];
13
+ otherActive: Thread[];
14
+ }
15
+ /**
16
+ * Categorize threads into agenda sections.
17
+ *
18
+ * - hotThreads: temperature === 'hot'
19
+ * - activeInPeriod: progress within lookback period (excludes hot)
20
+ * - needsAttention: active but cold/no recent progress (excludes hot)
21
+ * - otherActive: remaining active threads (only if options.all)
22
+ *
23
+ * @param threads - All threads (pre-filtering not required)
24
+ * @param options - { week?: boolean, all?: boolean }
25
+ * @param now - Current time (injectable for testing)
26
+ */
27
+ export declare function categorizeThreads(threads: Thread[], options: {
28
+ week?: boolean;
29
+ all?: boolean;
30
+ }, now?: Date): AgendaCategories;
31
+ //# sourceMappingURL=agenda.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agenda.d.ts","sourceRoot":"","sources":["../../src/domain/agenda.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIzC,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,EAC1C,GAAG,GAAE,IAAiB,GACrB,gBAAgB,CAkDlB"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /**
3
+ * Thread categorization into agenda buckets.
4
+ *
5
+ * Pure function — takes Thread[] and options, returns categorized sections.
6
+ * Uses time.ts + sorting.ts internally.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.categorizeThreads = categorizeThreads;
10
+ const time_1 = require("./time");
11
+ const sorting_1 = require("./sorting");
12
+ /**
13
+ * Categorize threads into agenda sections.
14
+ *
15
+ * - hotThreads: temperature === 'hot'
16
+ * - activeInPeriod: progress within lookback period (excludes hot)
17
+ * - needsAttention: active but cold/no recent progress (excludes hot)
18
+ * - otherActive: remaining active threads (only if options.all)
19
+ *
20
+ * @param threads - All threads (pre-filtering not required)
21
+ * @param options - { week?: boolean, all?: boolean }
22
+ * @param now - Current time (injectable for testing)
23
+ */
24
+ function categorizeThreads(threads, options, now = new Date()) {
25
+ const lookbackDays = options.week ? 7 : 1;
26
+ const activeThreads = threads.filter(t => t.status === 'active' || t.status === 'paused');
27
+ // Section 1: Hot threads
28
+ const hotThreads = (0, sorting_1.sortByPriority)(activeThreads.filter(t => t.temperature === 'hot'));
29
+ // Section 2: Active in period (has progress within lookback, excludes hot)
30
+ const activeInPeriodRaw = (0, sorting_1.sortByPriority)(activeThreads.filter(t => {
31
+ const lastProgress = (0, time_1.getLastProgressDate)(t);
32
+ if (!lastProgress)
33
+ return false;
34
+ return (0, time_1.isWithinDays)(lastProgress, lookbackDays - 1, now);
35
+ }));
36
+ const activeInPeriod = activeInPeriodRaw.filter(t => t.temperature !== 'hot');
37
+ // Section 3: Needs attention (active, not hot, cold or no recent progress)
38
+ const needsAttention = (0, sorting_1.sortByPriority)(activeThreads.filter(t => {
39
+ if (t.status !== 'active')
40
+ return false;
41
+ if (t.temperature === 'hot')
42
+ return false;
43
+ const lastProgress = (0, time_1.getLastProgressDate)(t);
44
+ const isColdTemp = sorting_1.COLD_TEMPS.includes(t.temperature ?? 'frozen');
45
+ const noRecentProgress = !lastProgress || (0, time_1.daysSince)(lastProgress, now) > 7;
46
+ return isColdTemp || noRecentProgress;
47
+ }));
48
+ // Section 4: Other active (only when --all)
49
+ let otherActive = [];
50
+ if (options.all) {
51
+ const shownIds = new Set([
52
+ ...hotThreads.map(t => t.id),
53
+ ...activeInPeriod.map(t => t.id),
54
+ ...needsAttention.map(t => t.id),
55
+ ]);
56
+ otherActive = (0, sorting_1.sortByPriority)(activeThreads.filter(t => !shownIds.has(t.id)));
57
+ }
58
+ return { hotThreads, activeInPeriod, needsAttention, otherActive };
59
+ }
60
+ //# sourceMappingURL=agenda.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agenda.js","sourceRoot":"","sources":["../../src/domain/agenda.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA0BH,8CAsDC;AA7ED,iCAAsE;AACtE,uCAAuD;AAUvD;;;;;;;;;;;GAWG;AACH,SAAgB,iBAAiB,CAC/B,OAAiB,EACjB,OAA0C,EAC1C,MAAY,IAAI,IAAI,EAAE;IAEtB,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1C,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACvC,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAC/C,CAAC;IAEF,yBAAyB;IACzB,MAAM,UAAU,GAAG,IAAA,wBAAc,EAC/B,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,KAAK,CAAC,CACnD,CAAC;IAEF,2EAA2E;IAC3E,MAAM,iBAAiB,GAAG,IAAA,wBAAc,EACtC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACvB,MAAM,YAAY,GAAG,IAAA,0BAAmB,EAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,YAAY;YAAE,OAAO,KAAK,CAAC;QAChC,OAAO,IAAA,mBAAY,EAAC,YAAY,EAAE,YAAY,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC,CAAC,CACH,CAAC;IACF,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,CAC7C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,KAAK,CAC7B,CAAC;IAEF,2EAA2E;IAC3E,MAAM,cAAc,GAAG,IAAA,wBAAc,EACnC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACvB,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,CAAC,CAAC,WAAW,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QAC1C,MAAM,YAAY,GAAG,IAAA,0BAAmB,EAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,oBAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,IAAI,QAAQ,CAAC,CAAC;QAClE,MAAM,gBAAgB,GAAG,CAAC,YAAY,IAAI,IAAA,gBAAS,EAAC,YAAY,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3E,OAAO,UAAU,IAAI,gBAAgB,CAAC;IACxC,CAAC,CAAC,CACH,CAAC;IAEF,4CAA4C;IAC5C,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;YACvB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5B,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjC,CAAC,CAAC;QACH,WAAW,GAAG,IAAA,wBAAc,EAC1B,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC/C,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;AACrE,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Batch criteria parsing and matching.
3
+ *
4
+ * Pure functions for filtering threads by criteria and parsing batch actions.
5
+ * Storage-coupled functions (findThread, findGroup, getDescendants) stay in CLI/MCP.
6
+ */
7
+ import { Thread, ThreadStatus, Temperature, ThreadSize } from '../models/types';
8
+ /** Valid status values for validation. */
9
+ export declare const validStatuses: ThreadStatus[];
10
+ /** Valid temperature values for filtering. */
11
+ export declare const validTemps: Temperature[];
12
+ /** Valid size values for validation. */
13
+ export declare const validSizes: ThreadSize[];
14
+ /** Criteria for matching threads in batch operations. */
15
+ export interface MatchCriteria {
16
+ under?: string;
17
+ children?: string;
18
+ group?: string;
19
+ status?: ThreadStatus;
20
+ temp?: Temperature;
21
+ tag?: string;
22
+ importance?: string;
23
+ size?: ThreadSize;
24
+ }
25
+ /** Parsed batch action. */
26
+ export interface BatchAction {
27
+ type: 'tag-add' | 'tag-remove' | 'set' | 'archive' | 'progress';
28
+ args: string[];
29
+ }
30
+ /**
31
+ * Parse importance criteria string.
32
+ * Supports: "4" (exact), "4+" (gte), "3-" (lte).
33
+ */
34
+ export declare function parseImportanceCriteria(criteria: string): {
35
+ value: number;
36
+ operator: 'eq' | 'gte' | 'lte';
37
+ };
38
+ /**
39
+ * Check if a thread matches importance criteria.
40
+ */
41
+ export declare function matchesImportance(thread: Thread, criteria: string): boolean;
42
+ /**
43
+ * Check if a thread matches all filter criteria (AND logic).
44
+ * Structural criteria (under/children/group) are resolved externally
45
+ * and passed in as matchedIds.
46
+ *
47
+ * @param thread - Thread to test
48
+ * @param criteria - Filter criteria
49
+ * @param matchedIds - Pre-resolved IDs from structural criteria (under/children/group)
50
+ */
51
+ export declare function matchesCriteria(thread: Thread, criteria: MatchCriteria, matchedIds: Set<string>): boolean;
52
+ /**
53
+ * Parse batch action from CLI arguments.
54
+ */
55
+ export declare function parseAction(actionArgs: string[]): {
56
+ action?: BatchAction;
57
+ error?: string;
58
+ };
59
+ /**
60
+ * Parse tags from arguments (space or comma separated).
61
+ */
62
+ export declare function parseTags(args: string[]): string[];
63
+ /**
64
+ * Format a batch action for display.
65
+ */
66
+ export declare function formatAction(action: BatchAction): string;
67
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/domain/batch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAc,MAAM,iBAAiB,CAAC;AAE5F,0CAA0C;AAC1C,eAAO,MAAM,aAAa,EAAE,YAAY,EAA6D,CAAC;AAEtG,8CAA8C;AAC9C,eAAO,MAAM,UAAU,EAAE,WAAW,EAA2D,CAAC;AAEhG,wCAAwC;AACxC,eAAO,MAAM,UAAU,EAAE,UAAU,EAAiD,CAAC;AAErF,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,2BAA2B;AAC3B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,UAAU,CAAC;IAChE,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,CAAA;CAAE,CAQ3G;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAS3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CA6BzG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAsC1F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAOlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAexD"}
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ /**
3
+ * Batch criteria parsing and matching.
4
+ *
5
+ * Pure functions for filtering threads by criteria and parsing batch actions.
6
+ * Storage-coupled functions (findThread, findGroup, getDescendants) stay in CLI/MCP.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.validSizes = exports.validTemps = exports.validStatuses = void 0;
10
+ exports.parseImportanceCriteria = parseImportanceCriteria;
11
+ exports.matchesImportance = matchesImportance;
12
+ exports.matchesCriteria = matchesCriteria;
13
+ exports.parseAction = parseAction;
14
+ exports.parseTags = parseTags;
15
+ exports.formatAction = formatAction;
16
+ /** Valid status values for validation. */
17
+ exports.validStatuses = ['active', 'paused', 'stopped', 'completed', 'archived'];
18
+ /** Valid temperature values for filtering. */
19
+ exports.validTemps = ['frozen', 'freezing', 'cold', 'tepid', 'warm', 'hot'];
20
+ /** Valid size values for validation. */
21
+ exports.validSizes = ['tiny', 'small', 'medium', 'large', 'huge'];
22
+ /**
23
+ * Parse importance criteria string.
24
+ * Supports: "4" (exact), "4+" (gte), "3-" (lte).
25
+ */
26
+ function parseImportanceCriteria(criteria) {
27
+ if (criteria.endsWith('+')) {
28
+ return { value: parseInt(criteria.slice(0, -1)), operator: 'gte' };
29
+ }
30
+ else if (criteria.endsWith('-')) {
31
+ return { value: parseInt(criteria.slice(0, -1)), operator: 'lte' };
32
+ }
33
+ else {
34
+ return { value: parseInt(criteria), operator: 'eq' };
35
+ }
36
+ }
37
+ /**
38
+ * Check if a thread matches importance criteria.
39
+ */
40
+ function matchesImportance(thread, criteria) {
41
+ const { value, operator } = parseImportanceCriteria(criteria);
42
+ if (isNaN(value) || value < 1 || value > 5)
43
+ return false;
44
+ switch (operator) {
45
+ case 'eq': return thread.importance === value;
46
+ case 'gte': return thread.importance >= value;
47
+ case 'lte': return thread.importance <= value;
48
+ }
49
+ }
50
+ /**
51
+ * Check if a thread matches all filter criteria (AND logic).
52
+ * Structural criteria (under/children/group) are resolved externally
53
+ * and passed in as matchedIds.
54
+ *
55
+ * @param thread - Thread to test
56
+ * @param criteria - Filter criteria
57
+ * @param matchedIds - Pre-resolved IDs from structural criteria (under/children/group)
58
+ */
59
+ function matchesCriteria(thread, criteria, matchedIds) {
60
+ if (matchedIds.size > 0 && !matchedIds.has(thread.id)) {
61
+ return false;
62
+ }
63
+ if (criteria.status && thread.status !== criteria.status) {
64
+ return false;
65
+ }
66
+ if (criteria.temp && thread.temperature !== criteria.temp) {
67
+ return false;
68
+ }
69
+ if (criteria.tag) {
70
+ const tags = thread.tags || [];
71
+ if (!tags.includes(criteria.tag)) {
72
+ return false;
73
+ }
74
+ }
75
+ if (criteria.importance && !matchesImportance(thread, criteria.importance)) {
76
+ return false;
77
+ }
78
+ if (criteria.size && thread.size !== criteria.size) {
79
+ return false;
80
+ }
81
+ return true;
82
+ }
83
+ /**
84
+ * Parse batch action from CLI arguments.
85
+ */
86
+ function parseAction(actionArgs) {
87
+ if (actionArgs.length === 0) {
88
+ return { error: 'No action specified' };
89
+ }
90
+ const [cmd, ...rest] = actionArgs;
91
+ switch (cmd.toLowerCase()) {
92
+ case 'tag':
93
+ if (rest.length < 2) {
94
+ return { error: 'Tag action requires: tag add|remove <tags>' };
95
+ }
96
+ if (rest[0] === 'add') {
97
+ return { action: { type: 'tag-add', args: rest.slice(1) } };
98
+ }
99
+ else if (rest[0] === 'remove') {
100
+ return { action: { type: 'tag-remove', args: rest.slice(1) } };
101
+ }
102
+ else {
103
+ return { error: `Unknown tag action "${rest[0]}". Use: add, remove` };
104
+ }
105
+ case 'set':
106
+ if (rest.length < 2) {
107
+ return { error: 'Set action requires: set <property> <value>' };
108
+ }
109
+ return { action: { type: 'set', args: rest } };
110
+ case 'archive':
111
+ return { action: { type: 'archive', args: [] } };
112
+ case 'progress':
113
+ if (rest.length === 0) {
114
+ return { error: 'Progress action requires: progress <note>' };
115
+ }
116
+ return { action: { type: 'progress', args: rest } };
117
+ default:
118
+ return { error: `Unknown action "${cmd}". Use: tag, set, archive, progress` };
119
+ }
120
+ }
121
+ /**
122
+ * Parse tags from arguments (space or comma separated).
123
+ */
124
+ function parseTags(args) {
125
+ const tags = [];
126
+ for (const arg of args) {
127
+ const parts = arg.split(',').map(t => t.trim()).filter(t => t.length > 0);
128
+ tags.push(...parts);
129
+ }
130
+ return tags;
131
+ }
132
+ /**
133
+ * Format a batch action for display.
134
+ */
135
+ function formatAction(action) {
136
+ switch (action.type) {
137
+ case 'tag-add':
138
+ return `tag add ${action.args.join(' ')}`;
139
+ case 'tag-remove':
140
+ return `tag remove ${action.args.join(' ')}`;
141
+ case 'set':
142
+ return `set ${action.args.join(' ')}`;
143
+ case 'archive':
144
+ return 'archive';
145
+ case 'progress':
146
+ return `progress "${action.args.join(' ')}"`;
147
+ default:
148
+ return 'unknown';
149
+ }
150
+ }
151
+ //# sourceMappingURL=batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.js","sourceRoot":"","sources":["../../src/domain/batch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Thread cloning — single and recursive (with children).
3
+ *
4
+ * Pure functions — no storage dependencies.
5
+ * ID generation uses crypto.randomUUID() (Node 20+).
6
+ */
7
+ import { Thread } from '../models/types';
8
+ /**
9
+ * Filter threads to get direct children of a parent.
10
+ */
11
+ export declare function getChildren(parentId: string, threads: Thread[]): Thread[];
12
+ /**
13
+ * Clone a single thread with a new ID and name.
14
+ * Copies: description, status, importance, size, tags.
15
+ * Resets: progress, details, links, reminders, dependencies.
16
+ *
17
+ * @param source - Thread to clone
18
+ * @param newName - Name for the clone
19
+ * @param parentId - Parent ID for the clone (null for top-level)
20
+ * @param groupId - Group ID for the clone (null for ungrouped)
21
+ * @param now - Current time (injectable for testing)
22
+ */
23
+ export declare function cloneThread(source: Thread, newName: string, parentId: string | null, groupId: string | null, now?: Date): Thread;
24
+ /**
25
+ * Recursively clone a thread and all its children.
26
+ * Children get their parentId set to the cloned parent's new ID.
27
+ *
28
+ * @returns Array of all cloned threads (root first, then children depth-first)
29
+ */
30
+ export declare function cloneWithChildren(source: Thread, newName: string, parentId: string | null, groupId: string | null, allThreads: Thread[], now?: Date): Thread[];
31
+ //# sourceMappingURL=clone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone.d.ts","sourceRoot":"","sources":["../../src/domain/clone.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAEzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,GAAG,GAAE,IAAiB,GACrB,MAAM,CAoBR;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,UAAU,EAAE,MAAM,EAAE,EACpB,GAAG,GAAE,IAAiB,GACrB,MAAM,EAAE,CAkBV"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ /**
3
+ * Thread cloning — single and recursive (with children).
4
+ *
5
+ * Pure functions — no storage dependencies.
6
+ * ID generation uses crypto.randomUUID() (Node 20+).
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getChildren = getChildren;
10
+ exports.cloneThread = cloneThread;
11
+ exports.cloneWithChildren = cloneWithChildren;
12
+ /**
13
+ * Filter threads to get direct children of a parent.
14
+ */
15
+ function getChildren(parentId, threads) {
16
+ return threads.filter(t => t.parentId === parentId);
17
+ }
18
+ /**
19
+ * Clone a single thread with a new ID and name.
20
+ * Copies: description, status, importance, size, tags.
21
+ * Resets: progress, details, links, reminders, dependencies.
22
+ *
23
+ * @param source - Thread to clone
24
+ * @param newName - Name for the clone
25
+ * @param parentId - Parent ID for the clone (null for top-level)
26
+ * @param groupId - Group ID for the clone (null for ungrouped)
27
+ * @param now - Current time (injectable for testing)
28
+ */
29
+ function cloneThread(source, newName, parentId, groupId, now = new Date()) {
30
+ const timestamp = now.toISOString();
31
+ return {
32
+ id: crypto.randomUUID(),
33
+ name: newName,
34
+ description: source.description,
35
+ status: source.status,
36
+ importance: source.importance,
37
+ size: source.size,
38
+ parentId,
39
+ groupId,
40
+ tags: [...source.tags],
41
+ links: [],
42
+ reminders: [],
43
+ dependencies: [],
44
+ progress: [],
45
+ details: [],
46
+ createdAt: timestamp,
47
+ modified: timestamp,
48
+ };
49
+ }
50
+ /**
51
+ * Recursively clone a thread and all its children.
52
+ * Children get their parentId set to the cloned parent's new ID.
53
+ *
54
+ * @returns Array of all cloned threads (root first, then children depth-first)
55
+ */
56
+ function cloneWithChildren(source, newName, parentId, groupId, allThreads, now = new Date()) {
57
+ const cloned = cloneThread(source, newName, parentId, groupId, now);
58
+ const results = [cloned];
59
+ const children = getChildren(source.id, allThreads);
60
+ for (const child of children) {
61
+ const childClones = cloneWithChildren(child, child.name, // Keep original name for children
62
+ cloned.id, // Set parent to the cloned parent
63
+ groupId, // Inherit group from root clone
64
+ allThreads, now);
65
+ results.push(...childClones);
66
+ }
67
+ return results;
68
+ }
69
+ //# sourceMappingURL=clone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clone.js","sourceRoot":"","sources":["../../src/domain/clone.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAOH,kCAEC;AAaD,kCA0BC;AAQD,8CAyBC;AA7ED;;GAEG;AACH,SAAgB,WAAW,CAAC,QAAgB,EAAE,OAAiB;IAC7D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,WAAW,CACzB,MAAc,EACd,OAAe,EACf,QAAuB,EACvB,OAAsB,EACtB,MAAY,IAAI,IAAI,EAAE;IAEtB,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ;QACR,OAAO;QACP,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;QACtB,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;QACb,YAAY,EAAE,EAAE;QAChB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,SAAS;QACpB,QAAQ,EAAE,SAAS;KACpB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAgB,iBAAiB,CAC/B,MAAc,EACd,OAAe,EACf,QAAuB,EACvB,OAAsB,EACtB,UAAoB,EACpB,MAAY,IAAI,IAAI,EAAE;IAEtB,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IACpE,MAAM,OAAO,GAAa,CAAC,MAAM,CAAC,CAAC;IAEnC,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IACpD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,iBAAiB,CACnC,KAAK,EACL,KAAK,CAAC,IAAI,EAAI,kCAAkC;QAChD,MAAM,CAAC,EAAE,EAAK,kCAAkC;QAChD,OAAO,EAAO,gCAAgC;QAC9C,UAAU,EACV,GAAG,CACJ,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,12 @@
1
+ export * from './time';
2
+ export * from './sorting';
3
+ export * from './scoring';
4
+ export * from './agenda';
5
+ export * from './timeline';
6
+ export * from './search';
7
+ export * from './overview';
8
+ export * from './clone';
9
+ export * from './merge';
10
+ export * from './batch';
11
+ export * from './progress';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAGA,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ // Domain logic — pure functions for thread operations.
3
+ // No storage dependencies. All functions take data as input, return computed results.
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ __exportStar(require("./time"), exports);
20
+ __exportStar(require("./sorting"), exports);
21
+ __exportStar(require("./scoring"), exports);
22
+ __exportStar(require("./agenda"), exports);
23
+ __exportStar(require("./timeline"), exports);
24
+ __exportStar(require("./search"), exports);
25
+ __exportStar(require("./overview"), exports);
26
+ __exportStar(require("./clone"), exports);
27
+ __exportStar(require("./merge"), exports);
28
+ __exportStar(require("./batch"), exports);
29
+ __exportStar(require("./progress"), exports);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":";AAAA,uDAAuD;AACvD,sFAAsF;;;;;;;;;;;;;;;;AAEtF,yCAAuB;AACvB,4CAA0B;AAC1B,4CAA0B;AAC1B,2CAAyB;AACzB,6CAA2B;AAC3B,2CAAyB;AACzB,6CAA2B;AAC3B,0CAAwB;AACxB,0CAAwB;AACxB,0CAAwB;AACxB,6CAA2B"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Thread merging — progress, details, tags, dependencies.
3
+ *
4
+ * Pure functions — no storage dependencies.
5
+ * All functions take source and target arrays, return merged result.
6
+ */
7
+ import { ProgressEntry, DetailsEntry, Dependency } from '../models/types';
8
+ /**
9
+ * Merge progress entries from target and source, sorted by timestamp.
10
+ */
11
+ export declare function mergeProgress(target: ProgressEntry[], source: ProgressEntry[]): ProgressEntry[];
12
+ /**
13
+ * Merge details entries from target and source, sorted by timestamp.
14
+ */
15
+ export declare function mergeDetails(target: DetailsEntry[], source: DetailsEntry[]): DetailsEntry[];
16
+ /**
17
+ * Merge tags as a union (no duplicates).
18
+ */
19
+ export declare function mergeTags(target: string[], source: string[]): string[];
20
+ /**
21
+ * Merge dependencies as a union by threadId.
22
+ * If both have the same threadId, target's version wins.
23
+ */
24
+ export declare function mergeDependencies(target: Dependency[], source: Dependency[]): Dependency[];
25
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/domain/merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE1E;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAI/F;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAI3F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAGtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAY1F"}