hzl-cli 1.9.3 → 1.11.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 (44) hide show
  1. package/README.md +113 -25
  2. package/dist/commands/task/add.d.ts +2 -0
  3. package/dist/commands/task/add.d.ts.map +1 -1
  4. package/dist/commands/task/add.js +23 -2
  5. package/dist/commands/task/add.js.map +1 -1
  6. package/dist/commands/task/add.test.js +66 -0
  7. package/dist/commands/task/add.test.js.map +1 -1
  8. package/dist/commands/task/archive.d.ts +2 -0
  9. package/dist/commands/task/archive.d.ts.map +1 -1
  10. package/dist/commands/task/archive.js +46 -16
  11. package/dist/commands/task/archive.js.map +1 -1
  12. package/dist/commands/task/archive.test.js +87 -0
  13. package/dist/commands/task/archive.test.js.map +1 -1
  14. package/dist/commands/task/list.d.ts +3 -0
  15. package/dist/commands/task/list.d.ts.map +1 -1
  16. package/dist/commands/task/list.js +24 -3
  17. package/dist/commands/task/list.js.map +1 -1
  18. package/dist/commands/task/list.test.js +53 -0
  19. package/dist/commands/task/list.test.js.map +1 -1
  20. package/dist/commands/task/move.d.ts +1 -0
  21. package/dist/commands/task/move.d.ts.map +1 -1
  22. package/dist/commands/task/move.js +43 -20
  23. package/dist/commands/task/move.js.map +1 -1
  24. package/dist/commands/task/move.test.js +41 -0
  25. package/dist/commands/task/move.test.js.map +1 -1
  26. package/dist/commands/task/next.d.ts +2 -0
  27. package/dist/commands/task/next.d.ts.map +1 -1
  28. package/dist/commands/task/next.js +16 -7
  29. package/dist/commands/task/next.js.map +1 -1
  30. package/dist/commands/task/next.test.js +59 -0
  31. package/dist/commands/task/next.test.js.map +1 -1
  32. package/dist/commands/task/show.d.ts +7 -0
  33. package/dist/commands/task/show.d.ts.map +1 -1
  34. package/dist/commands/task/show.js +30 -5
  35. package/dist/commands/task/show.js.map +1 -1
  36. package/dist/commands/task/show.test.js +27 -0
  37. package/dist/commands/task/show.test.js.map +1 -1
  38. package/dist/commands/task/update.d.ts +1 -0
  39. package/dist/commands/task/update.d.ts.map +1 -1
  40. package/dist/commands/task/update.js +21 -1
  41. package/dist/commands/task/update.js.map +1 -1
  42. package/dist/commands/task/update.test.js +96 -0
  43. package/dist/commands/task/update.test.js.map +1 -1
  44. package/package.json +2 -2
package/README.md CHANGED
@@ -123,6 +123,15 @@ HZL includes a basic [Kanban dashboard](#web-dashboard) for human visibility. Fo
123
123
 
124
124
  Requires Node.js 22.14+.
125
125
 
126
+ #### Via Homebrew (macOS/Linux)
127
+
128
+ ```bash
129
+ brew tap tmchow/hzl
130
+ brew install hzl
131
+ ```
132
+
133
+ #### Via NPM
134
+
126
135
  ```bash
127
136
  npm install -g hzl-cli
128
137
  hzl init
@@ -259,6 +268,66 @@ hzl task checkpoint "$TASK_ID" "Endpoints scaffolded; next: auth middleware"
259
268
  hzl task complete "$TASK_ID"
260
269
  ```
261
270
 
271
+ ### Pattern: Breaking down work with subtasks
272
+
273
+ HZL supports one level of parent/subtask hierarchy for organizing related work.
274
+
275
+ **Key behavior: Parent tasks are organizational containers, not actionable work.**
276
+
277
+ When you call `hzl task next`, only leaf tasks (tasks without children) are returned. Parent tasks are never returned because they represent the umbrella—work happens on the subtasks.
278
+
279
+ ```bash
280
+ # Create parent task
281
+ hzl task add "Implement user authentication" -P myapp --priority 2
282
+ # → Created task abc123
283
+
284
+ # Create subtasks (project inherited automatically from parent)
285
+ hzl task add "Add login endpoint" --parent abc123
286
+ hzl task add "Add logout endpoint" --parent abc123
287
+ hzl task add "Add session management" --parent abc123
288
+
289
+ # View the breakdown
290
+ hzl task show abc123
291
+ # Shows task details plus list of subtasks
292
+
293
+ # Get next available subtask (parent is never returned)
294
+ hzl task next --project myapp
295
+ # → [def456] Add login endpoint
296
+
297
+ # Scope work to a specific parent's subtasks
298
+ hzl task next --parent abc123
299
+ # → [def456] Add login endpoint
300
+
301
+ # When all subtasks done, manually complete the parent
302
+ hzl task complete abc123
303
+ ```
304
+
305
+ **Constraints:**
306
+ - Maximum 1 level of nesting (subtasks cannot have their own subtasks)
307
+ - Subtasks are always in the same project as parent (auto-inherited)
308
+ - Moving a parent moves all subtasks atomically
309
+
310
+ **Filtering:**
311
+ ```bash
312
+ # See all subtasks of a task
313
+ hzl task list --parent abc123
314
+
315
+ # See only top-level tasks (no parent)
316
+ hzl task list --root
317
+
318
+ # Combine with other filters
319
+ hzl task list --root --status ready
320
+ ```
321
+
322
+ **Archiving:**
323
+ ```bash
324
+ # Archive parent with all subtasks
325
+ hzl task archive abc123 --cascade
326
+
327
+ # Archive parent only (subtasks promoted to top-level)
328
+ hzl task archive abc123 --orphan
329
+ ```
330
+
262
331
  ### Pattern: Personal todo list (it works, but bring your own UI)
263
332
 
264
333
  HZL can track personal tasks and has the advantage of centralizing agent and personal tasks.
@@ -293,34 +362,44 @@ If your coding agent supports an instruction file (for example `CLAUDE.md`, `AGE
293
362
 
294
363
  ### Drop-in policy snippet
295
364
 
365
+ <!-- START [code:md] docs/snippets/agent-policy.md -->
296
366
  ```md
297
- ### HZL task ledger (durable, cross-agent task tracking)
298
-
299
- HZL is a shared task database that persists across sessions and works across different agents.
300
- Use it when work spans multiple sessions, involves handoffs to other agents, or needs durable backup.
301
- If this agent has built-in task tracking, HZL complements it for cross-agent and multi-session work.
302
-
303
- When to use HZL:
304
- - Multi-session work that must survive restarts
305
- - Coordination with other agents (Claude Code ↔ Codex ↔ Gemini, etc.)
306
- - Work delegated to sub-agents that need explicit handoff
307
- - When you need task state backed up to cloud
308
-
309
- Workflow:
310
- 1) Create or use an HZL project for the work.
311
- 2) Break work into tasks with dependencies. Use `--links` to reference design docs or specs.
312
- 3) Claim tasks before work and checkpoint after meaningful progress.
313
- 4) Use `--json` when producing output another tool will parse.
314
-
315
- Key commands:
316
- - `hzl project create <name>`
317
- - `hzl task add "<title>" -P <project> [--depends-on <id>] [--links <file>]`
318
- - `hzl task claim <id> --author <agent-id> [--lease 30]`
319
- - `hzl task checkpoint <id> "<progress + next step>"`
367
+ ### HZL task ledger (external task tracking for multi-session/multi-agent work)
368
+
369
+ HZL is an external task database. Use it when work outlives this session or involves other agents.
370
+ Built-in task tracking (if available) is fine for single-session work you'll complete now.
371
+
372
+ **When to use HZL:**
373
+ - Work spanning multiple sessions or days
374
+ - Coordination with other agents (Claude Code ↔ Codex ↔ Gemini)
375
+ - Delegating to sub-agents with explicit handoff
376
+ - User explicitly asks to track work in HZL
377
+
378
+ **When NOT to use HZL:**
379
+ - Single-session work you'll complete in this conversation
380
+ - User hasn't mentioned persistence or multi-agent needs
381
+
382
+ **Structure:**
383
+ - **Project** = stable container (typically one per repo or long-running initiative). Check `hzl project list` before creating.
384
+ - **Task** = top-level work item (often a feature). Use `--depends-on` to sequence separate tasks.
385
+ - **Subtask** = breakdown of a task into parts (`--parent <id>`). Max 1 level of nesting.
386
+
387
+ **Workflow:**
388
+ 1. `hzl project list` to find existing, or `hzl project create <name>`
389
+ 2. Add tasks. Use `--depends-on` for sequencing, `--parent` for breakdown, `--links` for context docs.
390
+ 3. Claim before work, checkpoint progress, complete when done.
391
+ 4. Use `--json` for scripted output.
392
+
393
+ **Key commands:**
394
+ - `hzl task add "<title>" -P <project> [--depends-on <id>] [--parent <id>] [--links <file>]`
395
+ - `hzl task claim <id> --author claude-code [--lease 30]`
396
+ - `hzl task checkpoint <id> "<progress>"`
320
397
  - `hzl task complete <id>`
398
+ - `hzl task next --project <project>` (returns next available; never returns parent tasks)
321
399
  ```
400
+ <!-- END [code:md] docs/snippets/agent-policy.md -->
322
401
 
323
- That snippet is intentionally short. The goal is consistency, not ceremony.
402
+ That snippet is intentionally concise. The goal is clear triggers and structure, not ceremony.
324
403
 
325
404
  ### Claude Code marketplace (optional)
326
405
 
@@ -418,6 +497,15 @@ hzl task stuck # Find expired leases
418
497
  hzl task steal <id> --if-expired # Take over abandoned task
419
498
  hzl task show <id> --json # Task details (--json for scripting)
420
499
 
500
+ # Subtasks (organization)
501
+ hzl task add "<title>" --parent <id> # Create subtask (inherits project)
502
+ hzl task list --parent <id> # List subtasks of a task
503
+ hzl task list --root # List only top-level tasks
504
+ hzl task next --parent <id> # Next available subtask
505
+ hzl task show <id> # Shows subtasks inline
506
+ hzl task archive <id> --cascade # Archive parent and all subtasks
507
+ hzl task archive <id> --orphan # Archive parent, promote subtasks
508
+
421
509
  # Diagnostics
422
510
  hzl sync # Sync with cloud (if configured)
423
511
  hzl status # Show database and sync state
@@ -488,7 +576,7 @@ HZL is a monorepo with three packages:
488
576
 
489
577
  | Package | Description | Install |
490
578
  |---------|-------------|---------|
491
- | [`hzl-cli`](https://www.npmjs.com/package/hzl-cli) | CLI for task management (`hzl` command) | `npm install -g hzl-cli` |
579
+ | [`hzl-cli`](https://www.npmjs.com/package/hzl-cli) | CLI for task management (`hzl` command) | `brew install hzl`<br/>`npm install -g hzl-cli` |
492
580
  | [`hzl-core`](https://www.npmjs.com/package/hzl-core) | Core library for programmatic use | `npm install hzl-core` |
493
581
  | [`hzl-web`](https://www.npmjs.com/package/hzl-web) | Web server and Kanban dashboard | `npm install hzl-web` |
494
582
 
@@ -7,6 +7,7 @@ export interface AddResult {
7
7
  status: string;
8
8
  priority: number;
9
9
  tags: string[];
10
+ parent_id: string | null;
10
11
  }
11
12
  export interface AddOptions {
12
13
  services: Services;
@@ -16,6 +17,7 @@ export interface AddOptions {
16
17
  tags?: string[];
17
18
  priority?: number;
18
19
  dependsOn?: string[];
20
+ parent?: string;
19
21
  json: boolean;
20
22
  }
21
23
  export declare function runAdd(options: AddOptions): AddResult;
@@ -1 +1 @@
1
- {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAInE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;CACf;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,CA4BrD;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CA8B1C"}
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAKnE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAWD,wBAAgB,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,CAkDrD;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAgC1C"}
@@ -2,10 +2,27 @@
2
2
  import { Command } from 'commander';
3
3
  import { resolveDbPaths } from '../../config.js';
4
4
  import { initializeDb, closeDb } from '../../db.js';
5
- import { handleError } from '../../errors.js';
5
+ import { CLIError, ExitCode, handleError } from '../../errors.js';
6
+ import { TaskStatus } from 'hzl-core/events/types.js';
6
7
  import { GlobalOptionsSchema } from '../../types.js';
7
8
  export function runAdd(options) {
8
- const { services, project, title, description, tags, priority, dependsOn, json } = options;
9
+ const { services, title, description, tags, priority, dependsOn, parent, json } = options;
10
+ let project = options.project;
11
+ // Validate parent and inherit project
12
+ if (parent) {
13
+ const parentTask = services.taskService.getTaskById(parent);
14
+ if (!parentTask) {
15
+ throw new CLIError(`Parent task not found: ${parent}`, ExitCode.NotFound);
16
+ }
17
+ if (parentTask.status === TaskStatus.Archived) {
18
+ throw new CLIError(`Cannot create subtask of archived parent: ${parent}`, ExitCode.InvalidInput);
19
+ }
20
+ if (parentTask.parent_id) {
21
+ throw new CLIError('Cannot create subtask of a subtask (max 1 level of nesting)', ExitCode.InvalidInput);
22
+ }
23
+ // Always inherit project from parent
24
+ project = parentTask.project;
25
+ }
9
26
  const task = services.taskService.createTask({
10
27
  title,
11
28
  project,
@@ -13,6 +30,7 @@ export function runAdd(options) {
13
30
  tags,
14
31
  priority,
15
32
  depends_on: dependsOn,
33
+ parent_id: parent,
16
34
  });
17
35
  const result = {
18
36
  task_id: task.task_id,
@@ -21,6 +39,7 @@ export function runAdd(options) {
21
39
  status: task.status,
22
40
  priority: task.priority,
23
41
  tags: task.tags,
42
+ parent_id: task.parent_id ?? null,
24
43
  };
25
44
  if (json) {
26
45
  console.log(JSON.stringify(result));
@@ -39,6 +58,7 @@ export function createAddCommand() {
39
58
  .option('-t, --tags <tags>', 'Comma-separated tags')
40
59
  .option('-p, --priority <n>', 'Priority (0-3)', '0')
41
60
  .option('--depends-on <ids>', 'Comma-separated task IDs this depends on')
61
+ .option('--parent <taskId>', 'Parent task ID (creates subtask, inherits project)')
42
62
  .action(function (title, opts) {
43
63
  const globalOpts = GlobalOptionsSchema.parse(this.optsWithGlobals());
44
64
  const { eventsDbPath, cacheDbPath } = resolveDbPaths(globalOpts.db);
@@ -52,6 +72,7 @@ export function createAddCommand() {
52
72
  tags: opts.tags?.split(','),
53
73
  priority: parseInt(opts.priority ?? '0', 10),
54
74
  dependsOn: opts.dependsOn?.split(','),
75
+ parent: opts.parent,
55
76
  json: globalOpts.json ?? false,
56
77
  });
57
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/commands/task/add.ts"],"names":[],"mappings":"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"}
@@ -57,5 +57,71 @@ describe('runAdd', () => {
57
57
  const task = services.taskService.getTaskById(result.task_id);
58
58
  expect(task).toBeDefined();
59
59
  });
60
+ it('creates a subtask with parent', () => {
61
+ services.projectService.createProject('myproject');
62
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
63
+ const result = runAdd({
64
+ services,
65
+ project: 'inbox', // ignored when parent specified
66
+ title: 'Subtask',
67
+ parent: parent.task_id,
68
+ json: false,
69
+ });
70
+ expect(result.task_id).toBeDefined();
71
+ const task = services.taskService.getTaskById(result.task_id);
72
+ expect(task?.parent_id).toBe(parent.task_id);
73
+ expect(task?.project).toBe('myproject'); // inherited from parent
74
+ });
75
+ it('inherits project from parent, ignoring --project', () => {
76
+ services.projectService.createProject('myproject');
77
+ services.projectService.createProject('other');
78
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
79
+ const result = runAdd({
80
+ services,
81
+ project: 'other', // should be ignored
82
+ title: 'Subtask',
83
+ parent: parent.task_id,
84
+ json: false,
85
+ });
86
+ const task = services.taskService.getTaskById(result.task_id);
87
+ expect(task?.project).toBe('myproject'); // not 'other'
88
+ });
89
+ it('errors when parent does not exist', () => {
90
+ expect(() => runAdd({
91
+ services,
92
+ project: 'inbox',
93
+ title: 'Subtask',
94
+ parent: 'nonexistent',
95
+ json: false,
96
+ })).toThrow(/parent.*not found/i);
97
+ });
98
+ it('errors when parent is archived', () => {
99
+ services.projectService.createProject('myproject');
100
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
101
+ services.taskService.archiveTask(parent.task_id);
102
+ expect(() => runAdd({
103
+ services,
104
+ project: 'inbox',
105
+ title: 'Subtask',
106
+ parent: parent.task_id,
107
+ json: false,
108
+ })).toThrow(/(archived.*parent|parent.*archived)/i);
109
+ });
110
+ it('errors when parent already has a parent (max 1 level)', () => {
111
+ services.projectService.createProject('myproject');
112
+ const grandparent = services.taskService.createTask({ title: 'Grandparent', project: 'myproject' });
113
+ const parent = services.taskService.createTask({
114
+ title: 'Parent',
115
+ project: 'myproject',
116
+ parent_id: grandparent.task_id
117
+ });
118
+ expect(() => runAdd({
119
+ services,
120
+ project: 'inbox',
121
+ title: 'Grandchild',
122
+ parent: parent.task_id,
123
+ json: false,
124
+ })).toThrow(/max.*level|cannot create subtask of a subtask/i);
125
+ });
60
126
  });
61
127
  //# sourceMappingURL=add.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add.test.js","sourceRoot":"","sources":["../../../src/commands/task/add.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"add.test.js","sourceRoot":"","sources":["../../../src/commands/task/add.test.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,8 @@ export declare function runArchive(options: {
10
10
  taskId: string;
11
11
  reason?: string;
12
12
  author?: string;
13
+ cascade?: boolean;
14
+ orphan?: boolean;
13
15
  json: boolean;
14
16
  }): ArchiveResult;
15
17
  export declare function createArchiveCommand(): Command;
@@ -1 +1 @@
1
- {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/commands/task/archive.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAInE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAOD,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,aAAa,CAmBhB;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAwB9C"}
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/commands/task/archive.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAInE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AASD,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf,GAAG,aAAa,CA4ChB;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CA4B9C"}
@@ -1,26 +1,52 @@
1
- // packages/hzl-cli/src/commands/archive.ts
1
+ // packages/hzl-cli/src/commands/task/archive.ts
2
2
  import { Command } from 'commander';
3
3
  import { resolveDbPaths } from '../../config.js';
4
4
  import { initializeDb, closeDb } from '../../db.js';
5
- import { handleError } from '../../errors.js';
5
+ import { handleError, CLIError, ExitCode } from '../../errors.js';
6
6
  import { GlobalOptionsSchema } from '../../types.js';
7
7
  export function runArchive(options) {
8
- const { services, taskId, reason, author, json } = options;
9
- const task = services.taskService.archiveTask(taskId, { reason, author });
10
- const result = {
11
- task_id: task.task_id,
12
- title: task.title,
13
- status: task.status,
14
- };
15
- if (json) {
16
- console.log(JSON.stringify(result));
8
+ const { services, taskId, reason, author, cascade, orphan, json } = options;
9
+ try {
10
+ // Use service method which handles validation and transaction atomically
11
+ const { task, archivedSubtaskCount, orphanedSubtaskCount } = services.taskService.archiveWithSubtasks(taskId, {
12
+ cascade,
13
+ orphan,
14
+ reason,
15
+ author,
16
+ });
17
+ const result = {
18
+ task_id: task.task_id,
19
+ title: task.title,
20
+ status: task.status,
21
+ };
22
+ if (json) {
23
+ console.log(JSON.stringify(result));
24
+ }
25
+ else {
26
+ console.log(`✓ Archived task ${result.task_id}: ${result.title}`);
27
+ if (archivedSubtaskCount > 0) {
28
+ console.log(` Also archived ${archivedSubtaskCount} subtask(s)`);
29
+ }
30
+ else if (orphanedSubtaskCount > 0) {
31
+ console.log(` Promoted ${orphanedSubtaskCount} subtask(s) to top-level`);
32
+ }
33
+ if (reason)
34
+ console.log(` Reason: ${reason}`);
35
+ }
36
+ return result;
17
37
  }
18
- else {
19
- console.log(`✓ Archived task ${task.task_id}: ${task.title}`);
20
- if (reason)
21
- console.log(` Reason: ${reason}`);
38
+ catch (error) {
39
+ if (error instanceof Error) {
40
+ // Map service layer errors to CLI errors with appropriate exit codes
41
+ if (error.message.includes('not found')) {
42
+ throw new CLIError(error.message, ExitCode.NotFound);
43
+ }
44
+ if (error.message.includes('Cannot') || error.message.includes('already archived')) {
45
+ throw new CLIError(error.message, ExitCode.InvalidInput);
46
+ }
47
+ }
48
+ throw error;
22
49
  }
23
- return result;
24
50
  }
25
51
  export function createArchiveCommand() {
26
52
  return new Command('archive')
@@ -28,6 +54,8 @@ export function createArchiveCommand() {
28
54
  .argument('<taskId>', 'Task ID')
29
55
  .option('--reason <reason>', 'Archive reason')
30
56
  .option('--author <name>', 'Author name')
57
+ .option('--cascade', 'Archive all subtasks (if task has children)', false)
58
+ .option('--orphan', 'Promote subtasks to top-level (if task has children)', false)
31
59
  .action(function (taskId, opts) {
32
60
  const globalOpts = GlobalOptionsSchema.parse(this.optsWithGlobals());
33
61
  const { eventsDbPath, cacheDbPath } = resolveDbPaths(globalOpts.db);
@@ -38,6 +66,8 @@ export function createArchiveCommand() {
38
66
  taskId,
39
67
  reason: opts.reason,
40
68
  author: opts.author,
69
+ cascade: opts.cascade,
70
+ orphan: opts.orphan,
41
71
  json: globalOpts.json ?? false,
42
72
  });
43
73
  }
@@ -1 +1 @@
1
- {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/commands/task/archive.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAarD,MAAM,UAAU,UAAU,CAAC,OAM1B;IACC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAE3D,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE1E,MAAM,MAAM,GAAkB;QAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9D,IAAI,MAAM;YAAE,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B,WAAW,CAAC,gBAAgB,CAAC;SAC7B,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;SAC/B,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CAAC;SAC7C,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;SACxC,MAAM,CAAC,UAAyB,MAAc,EAAE,IAA2B;QAC1E,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;QACrE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC;YACH,UAAU,CAAC;gBACT,QAAQ;gBACR,MAAM;gBACN,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,KAAK;aAC/B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,WAAW,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/commands/task/archive.ts"],"names":[],"mappings":"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"}
@@ -44,5 +44,92 @@ describe('runArchive', () => {
44
44
  });
45
45
  expect(result.status).toBe(TaskStatus.Archived);
46
46
  });
47
+ it('errors when archiving parent with active subtasks without flag', () => {
48
+ services.projectService.createProject('myproject');
49
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
50
+ services.taskService.createTask({
51
+ title: 'Child',
52
+ project: 'myproject',
53
+ parent_id: parent.task_id
54
+ });
55
+ expect(() => runArchive({
56
+ services,
57
+ taskId: parent.task_id,
58
+ json: false,
59
+ })).toThrow(/active subtask/i);
60
+ });
61
+ it('archives parent and subtasks with --cascade', () => {
62
+ services.projectService.createProject('myproject');
63
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
64
+ const child = services.taskService.createTask({
65
+ title: 'Child',
66
+ project: 'myproject',
67
+ parent_id: parent.task_id
68
+ });
69
+ runArchive({
70
+ services,
71
+ taskId: parent.task_id,
72
+ cascade: true,
73
+ json: false,
74
+ });
75
+ const archivedParent = services.taskService.getTaskById(parent.task_id);
76
+ const archivedChild = services.taskService.getTaskById(child.task_id);
77
+ expect(archivedParent?.status).toBe(TaskStatus.Archived);
78
+ expect(archivedChild?.status).toBe(TaskStatus.Archived);
79
+ });
80
+ it('archives parent and promotes subtasks with --orphan', () => {
81
+ services.projectService.createProject('myproject');
82
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
83
+ const child = services.taskService.createTask({
84
+ title: 'Child',
85
+ project: 'myproject',
86
+ parent_id: parent.task_id
87
+ });
88
+ runArchive({
89
+ services,
90
+ taskId: parent.task_id,
91
+ orphan: true,
92
+ json: false,
93
+ });
94
+ const archivedParent = services.taskService.getTaskById(parent.task_id);
95
+ const promotedChild = services.taskService.getTaskById(child.task_id);
96
+ expect(archivedParent?.status).toBe(TaskStatus.Archived);
97
+ expect(promotedChild?.status).not.toBe(TaskStatus.Archived);
98
+ expect(promotedChild?.parent_id).toBeNull();
99
+ });
100
+ it('archives normally when no active subtasks', () => {
101
+ services.projectService.createProject('myproject');
102
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
103
+ const child = services.taskService.createTask({
104
+ title: 'Child',
105
+ project: 'myproject',
106
+ parent_id: parent.task_id
107
+ });
108
+ services.taskService.setStatus(child.task_id, TaskStatus.Done);
109
+ // Should work without flags since child is done
110
+ runArchive({
111
+ services,
112
+ taskId: parent.task_id,
113
+ json: false,
114
+ });
115
+ const archivedParent = services.taskService.getTaskById(parent.task_id);
116
+ expect(archivedParent?.status).toBe(TaskStatus.Archived);
117
+ });
118
+ it('errors when both --cascade and --orphan specified', () => {
119
+ services.projectService.createProject('myproject');
120
+ const parent = services.taskService.createTask({ title: 'Parent', project: 'myproject' });
121
+ services.taskService.createTask({
122
+ title: 'Child',
123
+ project: 'myproject',
124
+ parent_id: parent.task_id
125
+ });
126
+ expect(() => runArchive({
127
+ services,
128
+ taskId: parent.task_id,
129
+ cascade: true,
130
+ orphan: true,
131
+ json: false,
132
+ })).toThrow(/cannot use both.*cascade.*orphan/i);
133
+ });
47
134
  });
48
135
  //# sourceMappingURL=archive.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"archive.test.js","sourceRoot":"","sources":["../../../src/commands/task/archive.test.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,OAAe,CAAC;IACpB,IAAI,MAAc,CAAC;IACnB,IAAI,QAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC;QACtE,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QACvC,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClB,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAClF,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/D,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,UAAU,CAAC;YACxB,QAAQ;YACR,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC1B,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAClF,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QAC/D,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,UAAU,CAAC;YACxB,QAAQ;YACR,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,MAAM,EAAE,mBAAmB;YAC3B,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"archive.test.js","sourceRoot":"","sources":["../../../src/commands/task/archive.test.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ export interface TaskListItem {
7
7
  project: string;
8
8
  status: string;
9
9
  priority: number;
10
+ parent_id: string | null;
10
11
  created_at: string;
11
12
  }
12
13
  export interface ListResult {
@@ -18,6 +19,8 @@ export interface ListOptions {
18
19
  project?: string;
19
20
  status?: TaskStatus;
20
21
  availableOnly?: boolean;
22
+ parent?: string;
23
+ rootOnly?: boolean;
21
24
  limit?: number;
22
25
  json: boolean;
23
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/task/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAKtD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AASD,wBAAgB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CAwDxD;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CA6B3C"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/task/list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAKtD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAWD,wBAAgB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CA4ExD;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAiC3C"}