@codetreker/daynight 0.31.0 → 0.37.2

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 (174) hide show
  1. package/README.md +237 -44
  2. package/config.example.yml +10 -3
  3. package/dist/api/client.d.ts +7 -1
  4. package/dist/api/client.js +117 -21
  5. package/dist/api/client.js.map +1 -1
  6. package/dist/api/json-source.d.ts +3 -0
  7. package/dist/api/json-source.js +113 -0
  8. package/dist/api/json-source.js.map +1 -0
  9. package/dist/api/parse.d.ts +2 -1
  10. package/dist/api/parse.js +16 -1
  11. package/dist/api/parse.js.map +1 -1
  12. package/dist/api/thread.d.ts +6 -0
  13. package/dist/api/thread.js +79 -0
  14. package/dist/api/thread.js.map +1 -0
  15. package/dist/api/types.d.ts +50 -0
  16. package/dist/cli/agent-cli-aliases.d.ts +21 -0
  17. package/dist/cli/agent-cli-aliases.js +57 -0
  18. package/dist/cli/agent-cli-aliases.js.map +1 -0
  19. package/dist/cli/application.js +17 -2
  20. package/dist/cli/application.js.map +1 -1
  21. package/dist/cli/cancellation.d.ts +1 -1
  22. package/dist/cli/cancellation.js.map +1 -1
  23. package/dist/cli/codex-agent-environment.d.ts +5 -0
  24. package/dist/cli/codex-agent-environment.js +28 -0
  25. package/dist/cli/codex-agent-environment.js.map +1 -0
  26. package/dist/cli/commands.js +1 -0
  27. package/dist/cli/commands.js.map +1 -1
  28. package/dist/cli/context.d.ts +9 -1
  29. package/dist/cli/context.js +3 -1
  30. package/dist/cli/context.js.map +1 -1
  31. package/dist/cli/schema.d.ts +5 -1
  32. package/dist/cli/schema.js +10 -10
  33. package/dist/cli/schema.js.map +1 -1
  34. package/dist/commands/controller/archive-upload.d.ts +9 -0
  35. package/dist/commands/controller/archive-upload.js +137 -0
  36. package/dist/commands/controller/archive-upload.js.map +1 -0
  37. package/dist/commands/controller/definition.d.ts +1 -0
  38. package/dist/commands/controller/definition.js +9 -1
  39. package/dist/commands/controller/definition.js.map +1 -1
  40. package/dist/commands/controller/independent-archive.d.ts +7 -0
  41. package/dist/commands/controller/independent-archive.js +71 -0
  42. package/dist/commands/controller/independent-archive.js.map +1 -0
  43. package/dist/commands/controller/independent.js +20 -10
  44. package/dist/commands/controller/independent.js.map +1 -1
  45. package/dist/commands/controller/index.js +14 -1
  46. package/dist/commands/controller/index.js.map +1 -1
  47. package/dist/commands/controller/journal-format.js +25 -1
  48. package/dist/commands/controller/journal-format.js.map +1 -1
  49. package/dist/commands/controller/launch-ticket.js +3 -2
  50. package/dist/commands/controller/launch-ticket.js.map +1 -1
  51. package/dist/commands/controller/lifecycle-store.js +19 -7
  52. package/dist/commands/controller/lifecycle-store.js.map +1 -1
  53. package/dist/commands/controller/local-content.d.ts +2 -2
  54. package/dist/commands/controller/local-content.js +22 -20
  55. package/dist/commands/controller/local-content.js.map +1 -1
  56. package/dist/commands/controller/paths.d.ts +2 -0
  57. package/dist/commands/controller/paths.js +34 -0
  58. package/dist/commands/controller/paths.js.map +1 -0
  59. package/dist/commands/controller/pending-content.d.ts +20 -0
  60. package/dist/commands/controller/pending-content.js +159 -0
  61. package/dist/commands/controller/pending-content.js.map +1 -0
  62. package/dist/commands/controller/providers/codex.js +5 -1
  63. package/dist/commands/controller/providers/codex.js.map +1 -1
  64. package/dist/commands/controller/providers/projection.js +12 -0
  65. package/dist/commands/controller/providers/projection.js.map +1 -1
  66. package/dist/commands/controller/providers/types.d.ts +4 -0
  67. package/dist/commands/controller/resume.js +3 -2
  68. package/dist/commands/controller/resume.js.map +1 -1
  69. package/dist/commands/controller/runtime.js +11 -1
  70. package/dist/commands/controller/runtime.js.map +1 -1
  71. package/dist/commands/controller/sqlite/journal/006-pending-content.sql +12 -0
  72. package/dist/commands/project/definition.js +1 -1
  73. package/dist/commands/project/definition.js.map +1 -1
  74. package/dist/commands/review/definition.js +3 -3
  75. package/dist/commands/review/definition.js.map +1 -1
  76. package/dist/commands/server/runtime.d.ts +10 -1
  77. package/dist/commands/server/runtime.js +24 -7
  78. package/dist/commands/server/runtime.js.map +1 -1
  79. package/dist/commands/skill/read.d.ts +2 -0
  80. package/dist/commands/skill/read.js +36 -0
  81. package/dist/commands/skill/read.js.map +1 -0
  82. package/dist/commands/skill/skills/using-daynight/SKILL.md +4 -2
  83. package/dist/commands/skill/skills/using-daynight/references/authorization.md +2 -1
  84. package/dist/commands/skill/skills/using-daynight/references/goal.md +33 -8
  85. package/dist/commands/skill/skills/using-daynight/references/handbook.md +4 -1
  86. package/dist/commands/skill/skills/using-daynight/references/run-task.md +1 -1
  87. package/dist/commands/skill/skills/using-daynight/references/task-content.md +8 -4
  88. package/dist/commands/skill/skills/using-daynight/references/task-management.md +56 -6
  89. package/dist/commands/skill/skills/using-daynight/references/write-safety.md +22 -3
  90. package/dist/commands/skill/usage.md +237 -0
  91. package/dist/commands/task/command.js +26 -3
  92. package/dist/commands/task/command.js.map +1 -1
  93. package/dist/commands/task/definition.js +41 -7
  94. package/dist/commands/task/definition.js.map +1 -1
  95. package/dist/commands/task/rendering.js +4 -0
  96. package/dist/commands/task/rendering.js.map +1 -1
  97. package/dist/commands/task/thread-diagnostics.d.ts +5 -0
  98. package/dist/commands/task/thread-diagnostics.js +32 -0
  99. package/dist/commands/task/thread-diagnostics.js.map +1 -0
  100. package/dist/commands/task/thread-rendering.d.ts +8 -0
  101. package/dist/commands/task/thread-rendering.js +80 -0
  102. package/dist/commands/task/thread-rendering.js.map +1 -0
  103. package/dist/commands/task/thread.d.ts +11 -0
  104. package/dist/commands/task/thread.js +74 -0
  105. package/dist/commands/task/thread.js.map +1 -0
  106. package/dist/commands/worker/backends/web-process.js +5 -8
  107. package/dist/commands/worker/backends/web-process.js.map +1 -1
  108. package/dist/commands/worker/backends/web-store.d.ts +1 -0
  109. package/dist/commands/worker/backends/web-store.js +1 -0
  110. package/dist/commands/worker/backends/web-store.js.map +1 -1
  111. package/dist/commands/worker/backends/web.d.ts +1 -0
  112. package/dist/commands/worker/backends/web.js +8 -0
  113. package/dist/commands/worker/backends/web.js.map +1 -1
  114. package/dist/commands/worker/coordinator.js +14 -0
  115. package/dist/commands/worker/coordinator.js.map +1 -1
  116. package/dist/commands/worker/definition.js +2 -2
  117. package/dist/commands/worker/definition.js.map +1 -1
  118. package/dist/commands/worker/herdr/agents.d.ts +3 -0
  119. package/dist/commands/worker/herdr/agents.js +14 -3
  120. package/dist/commands/worker/herdr/agents.js.map +1 -1
  121. package/dist/commands/worker/herdr/arguments.d.ts +4 -0
  122. package/dist/commands/worker/herdr/arguments.js +17 -0
  123. package/dist/commands/worker/herdr/arguments.js.map +1 -1
  124. package/dist/commands/worker/herdr/codex-config.d.ts +8 -0
  125. package/dist/commands/worker/herdr/codex-config.js +75 -0
  126. package/dist/commands/worker/herdr/codex-config.js.map +1 -0
  127. package/dist/commands/worker/herdr/preflight.js +1 -18
  128. package/dist/commands/worker/herdr/preflight.js.map +1 -1
  129. package/dist/commands/worker/herdr.d.ts +4 -0
  130. package/dist/commands/worker/herdr.js +3 -2
  131. package/dist/commands/worker/herdr.js.map +1 -1
  132. package/dist/commands/worker/remote.js +3 -4
  133. package/dist/commands/worker/remote.js.map +1 -1
  134. package/dist/commands/worker/remove-worktree-contents.d.ts +3 -0
  135. package/dist/commands/worker/remove-worktree-contents.js +106 -0
  136. package/dist/commands/worker/remove-worktree-contents.js.map +1 -0
  137. package/dist/commands/worker/runtime.js +60 -4
  138. package/dist/commands/worker/runtime.js.map +1 -1
  139. package/dist/commands/worker/worktrees.js +69 -23
  140. package/dist/commands/worker/worktrees.js.map +1 -1
  141. package/dist/config/agent-cli-aliases.d.ts +5 -0
  142. package/dist/config/agent-cli-aliases.js +37 -0
  143. package/dist/config/agent-cli-aliases.js.map +1 -0
  144. package/dist/config/paths.d.ts +1 -1
  145. package/dist/config/paths.js +6 -2
  146. package/dist/config/paths.js.map +1 -1
  147. package/dist/platform/diagnostics.d.ts +5 -0
  148. package/dist/platform/diagnostics.js +12 -0
  149. package/dist/platform/diagnostics.js.map +1 -1
  150. package/dist/platform/sqlite-format.d.ts +1 -1
  151. package/dist/platform/sqlite-format.js +1 -1
  152. package/dist/platform/sqlite-format.js.map +1 -1
  153. package/dist/session/archive.d.ts +25 -0
  154. package/dist/session/archive.js +100 -0
  155. package/dist/session/archive.js.map +1 -0
  156. package/dist/session/codex-subagent-activity.d.ts +4 -0
  157. package/dist/session/codex-subagent-activity.js +13 -0
  158. package/dist/session/codex-subagent-activity.js.map +1 -0
  159. package/dist/session/v2/archive.d.ts +6 -0
  160. package/dist/session/v2/archive.js +163 -0
  161. package/dist/session/v2/archive.js.map +1 -0
  162. package/dist/session/v2/protocol.d.ts +19 -0
  163. package/dist/session/v2/protocol.js +260 -0
  164. package/dist/session/v2/protocol.js.map +1 -0
  165. package/dist/session/v2/responsibility.d.ts +3 -0
  166. package/dist/session/v2/responsibility.js +12 -0
  167. package/dist/session/v2/responsibility.js.map +1 -0
  168. package/dist/session/v2/types.d.ts +293 -0
  169. package/dist/session/v2/types.js +2 -0
  170. package/dist/session/v2/types.js.map +1 -0
  171. package/dist/session/v2/values.d.ts +59 -0
  172. package/dist/session/v2/values.js +201 -0
  173. package/dist/session/v2/values.js.map +1 -0
  174. package/package.json +5 -3
package/README.md CHANGED
@@ -1,25 +1,37 @@
1
1
  # Daynight CLI
2
2
 
3
3
  The `@codetreker/daynight` package provides the `daynight` command and its `dn`
4
- alias. Use it to manage server-backed projects, tasks and attachments, install
5
- the `using-daynight` skill for coding agents, run foreground task workers through
4
+ alias. Use it to manage server-backed projects, tasks, discussion threads and
5
+ attachments, install the `using-daynight` skill for coding agents, run foreground
6
+ task workers through
6
7
  Herdr or browser-connected native Controllers, and run a local GitHub PR reviewer through Copilot CLI. Both command names
7
- share configuration and behavior.
8
+ share configuration and behavior. Supported native platforms are Linux, Windows
9
+ and Apple Silicon (ARM64) macOS. Intel macOS is unsupported.
8
10
 
9
11
  See the [project overview](../../README.md) for the browser workspace and service,
10
12
  and the [development guide](../../docs/development.md) for source builds,
11
- validation, package versions and npm publication. Each command's `--help` owns
12
- its exact usage. Review execution additionally requires Git, an authenticated
13
+ validation, package versions and npm publication. Ordinary test and installed
14
+ acceptance suites exclude stress workloads. From this package, `pnpm test:stress`
15
+ builds the CLI and runs the rendering and full Session-v2 `.stress.ts` suites;
16
+ `pnpm test:stress:budgets` runs the server validation gate with the four full
17
+ 128 MiB/256 MiB installed-CLI byte probes. The latter requires an isolated
18
+ `DAYNIGHT_TEST_DATABASE_URL` and the [server validation prerequisites](../daynight-server/README.md#validate).
19
+ Both commands are explicit local-only validation and refuse CI. The
20
+ [local stress guide](../../docs/development.md#local-stress-validation) owns
21
+ selection and receipt interpretation. Each command's `--help` owns its exact usage. Review execution additionally requires Git, an authenticated
13
22
  GitHub CLI and Copilot CLI on `PATH`.
14
23
 
15
24
  - [Install and update](#install-and-update)
25
+ - [Configuration root](#configuration-root)
16
26
  - [Client commands](#client-commands)
27
+ - [CLI usage manual](#cli-usage-manual)
17
28
  - [Agent skill installation](#agent-skill-installation)
18
29
  - [Shell completion](#shell-completion)
19
30
  - [Configuration setup](#configuration-setup)
20
31
  - [Project management](#project-management)
21
32
  - [Task management](#task-management)
22
33
  - [Task deletion](#task-deletion)
34
+ - [Task discussion threads](#task-discussion-threads)
23
35
  - [Task attachments](#task-attachments)
24
36
  - [Worker configuration and startup](#worker-configuration-and-startup)
25
37
  - [Worker manual management](#worker-manual-management)
@@ -88,12 +100,35 @@ that file and cause the update to fail. The
88
100
  [self-update decision](../../.agents/notes/archived/feature/2026-10-20-cli-self-update.md)
89
101
  records installation ownership and verification requirements.
90
102
 
103
+ ## Configuration root
104
+
105
+ `DN_CONFIG_DIR` selects the absolute directory containing `config.yml` and all
106
+ Daynight user-local state. When unset, it remains `~/.daynight`. Empty or relative
107
+ values and paths containing control characters are rejected; use an expanded
108
+ absolute path such as `DN_CONFIG_DIR="$HOME/.daynight-test"`. Paths shown under
109
+ `~/.daynight` in this manual describe that default and follow the selected root.
110
+
111
+ The root includes credentials, worker identity, Worker/Review SQLite databases,
112
+ locks, logs, caches, Controller launch tickets, journals, content and resume leases.
113
+ Controller IPC identities are scoped to this root; long Unix socket paths use a
114
+ private owner-checked temporary directory. Herdr retains its native socket length
115
+ limit and reports an error for overly long roots; select a shorter root for
116
+ Herdr mode. Native home and Provider session directories remain unchanged.
117
+ Project `.daynight` bindings, Git worktrees, installed skills, npm installations
118
+ and remote service data are not isolated by this setting.
119
+
120
+ Top-level `agentCliAliases` optionally maps `daynight` and/or `dn` to another
121
+ executable for newly launched Worker/Controller Agents. It defaults to disabled.
122
+ The [development channel guide](../../docs/development.md#keep-the-skills-command-spelling)
123
+ explains the mapping, platform limits, fixed build lifetime and shell verification.
124
+
91
125
  ## Client commands
92
126
 
93
127
  ```text
94
128
  daynight # Show root help
95
129
  daynight --help # Also -h
96
130
  daynight --version # Also -v
131
+ daynight --skill # Print the project/task usage manual
97
132
  daynight update
98
133
  daynight login [--no-browser] # Authorize CLI access through the browser
99
134
  daynight logout # Revoke and remove the current CLI credential
@@ -123,13 +158,15 @@ daynight project list [--json]
123
158
  daynight project show <project-id> [--json]
124
159
  daynight task
125
160
  daynight task create --title <title> [options]
126
- daynight task list [--all | --status <status>] [--ready] [--json] [--project <project-id>]
161
+ daynight task list [--all | --status <status>] [--ready] [--assigned-to <assignee>] [--json] [--project <project-id>]
127
162
  daynight task ready [--limit <N>] [--json] [--project <project-id>]
128
163
  daynight task show <task-id> [--json] [--project <project-id>]
129
164
  daynight task update <task-id> [options]
130
165
  daynight task set-status <task-id> <status> [--claim-id <claim-id>] [--if-version <version>] [--project <project-id>]
131
166
  daynight task delete <task-id> [--remove-depends] [--if-version <version>] [--project <project-id>]
132
167
  daynight task graph <task-id> [--depends-only] [--json] [--project <project-id>]
168
+ daynight task thread read <task-id> [--before-id <message-id> | --after-id <message-id>] [--count=N] [--details] [--project <project-id>]
169
+ daynight task thread post <task-id> --body <text> [--reply-to <message-id>] [--claim-id <claim-id>] [--project <project-id>]
133
170
  daynight task attachment
134
171
  daynight task attachment put <task-id> <file> [--path <relative-path>] [--project <project-id>]
135
172
  daynight task attachment list <task-id> [--tree | --json] [--project <project-id>]
@@ -138,8 +175,8 @@ daynight task attachment remove <task-id> <relative-path> [--project <project-id
138
175
  ```
139
176
 
140
177
  Groups and operations show help when `--help` or `-h` is their sole argument.
141
- Help, version and completion generation do not resolve the user home, load review
142
- configuration, open SQLite or require review tools. `review add-repo` accepts one
178
+ Help, version, usage-manual output and completion generation do not resolve the
179
+ user home, load review configuration, open SQLite or require review tools. `review add-repo` accepts one
143
180
  `--path <path>` before or after its remote; `--path=value` and `--` are invalid.
144
181
  Unknown commands and invalid arguments exit with status 2; operation failures
145
182
  exit with status 1 and retain their cause. The old `--daemon-review` and root
@@ -148,6 +185,31 @@ exit with status 1 and retain their cause. The old `--daemon-review` and root
148
185
  the [composition decision](../../.agents/notes/archived/architecture/2026-10-20-client-command-composition.md)
149
186
  records module ownership and the preserved data layout.
150
187
 
188
+ ## CLI usage manual
189
+
190
+ ```bash
191
+ daynight --skill
192
+ dn --skill
193
+ ```
194
+
195
+ `--skill` prints one standalone English project/task usage manual from the
196
+ current package. It covers project selection, task queries and writes,
197
+ dependencies, properties and attachments. Other capabilities are discovered
198
+ through `daynight --help`, with exact options in each subcommand's help. The
199
+ output preserves the manual's original bytes, including YAML
200
+ frontmatter and the final newline. The document has no package-relative
201
+ references to read separately.
202
+
203
+ The option must be the sole argument. Extra arguments or another option exit
204
+ with status 2 and empty stdout before the manual is read. A missing file, read
205
+ failure or invalid UTF-8 exits with status 1 and retains its cause. Reading and
206
+ validation complete before output; an output failure can leave partial stdout.
207
+ The command requires no login, Git repository, configuration, launcher or
208
+ interactive terminal, and creates no files.
209
+
210
+ The `using-daynight` skill owns task orchestration workflows and is installed
211
+ through the separate command below. The CLI manual explains command use.
212
+
151
213
  ## Agent skill installation
152
214
 
153
215
  The public `using-daynight` skill provides task creation, handoff review and
@@ -367,9 +429,7 @@ keep the credential name within 100 characters. The credential never expires by
367
429
  The Web account's token manager can set a future expiration, restore “Never expires”, or
368
430
  revoke it. Changing expiration keeps the same credential, so the saved CLI login
369
431
  continues without replacing its secret. Expired or revoked credentials cannot be
370
- revived. The [token manager mockup](../../packages/daynight-web/tests/mockups/tokens.html)
371
- shares the production components and styles for creating tokens and editing
372
- expiration, including conflict and uncertain-result states. A credential
432
+ revived. A credential
373
433
  represents the account's current project permissions. `daynight logout` revokes the current credential and removes
374
434
  its local value after a confirmed response; an already invalid credential is
375
435
  removed locally. Network or unconfirmed failures remain visible. Configuration
@@ -396,8 +456,8 @@ messages use stderr so stdout retains its normal text or JSON format.
396
456
  Noninteractive missing review configuration fails with a `review add-repo`
397
457
  command. Shared YAML/schema errors, invalid selected values, explicit empty
398
458
  review lists and read failures retain their errors. Unrelated capability values
399
- remain outside the current command's validation. Help, version, completion,
400
- update and invalid arguments do not prompt.
459
+ remain outside the current command's validation. Help, version, usage-manual
460
+ output, completion, update and invalid arguments do not prompt.
401
461
 
402
462
  Test services and noninteractive automation use the existing
403
463
  `~/.daynight/config.yml` fields. For a test service, provision its origin before
@@ -503,6 +563,8 @@ daynight task list --allow-agents false --ready
503
563
  daynight task list --ready
504
564
  daynight task list --all --json
505
565
  daynight task list --status in_progress --json
566
+ daynight task list --ready --assigned-to me --json
567
+ daynight task list --assigned-to unassigned --json
506
568
  daynight task show <task-id> --json
507
569
  daynight task properties <task-id> --json
508
570
  daynight task properties --schema --json
@@ -513,6 +575,9 @@ daynight task update <task-id> --allow-agents true --if-version <version>
513
575
  daynight task create --title "Check Windows build" --required-platform windows
514
576
  daynight task update <task-id> --required-platform macos --if-version <version>
515
577
  daynight task update <task-id> --clear-required-platform --if-version <version>
578
+ daynight task create --title "Review installation" --assigned-to <user-uuid>
579
+ daynight task update <task-id> --assigned-to <user-uuid> --if-version <version>
580
+ daynight task update <task-id> --clear-assigned-to --if-version <version>
516
581
  daynight task set-status <task-id> <status> [--claim-id <claim-id>] [--if-version <version>] [--project <project-id>]
517
582
  daynight task update <task-id> --depends-on <task-a> --depends-on <task-b>
518
583
  daynight task update <task-id> --clear-dependencies
@@ -550,7 +615,7 @@ in the root `.gitignore`. A cached binding is verified against the server on eac
550
615
  use and remains stable if another project later shares that repository.
551
616
 
552
617
  Creation starts in `todo` with `allowAgents=false` and unrestricted
553
- `requiredPlatform=null` unless explicitly set. Unset properties remain absent;
618
+ `requiredPlatform=null` and `assignedTo=null` unless explicitly set. Unset properties remain absent;
554
619
  creation does not inject a PR array or worker null. `task set-status <id> <status>`
555
620
  sets `todo`, `in_progress` or `done`, including reopening and direct completion.
556
621
  Every project member may use ordinary status setting. Active worker completion
@@ -572,7 +637,7 @@ Entering in_progress or done requires all direct prerequisites, ordinary and
572
637
  external, to be done. Reopening done requires no direct in-progress or done
573
638
  dependents. Refusals return sorted blocking task IDs without cascading changes.
574
639
  The project transaction serializes status and dependency writes and preserves
575
- materials, properties/PRs, permission, both dependency sets and attachments.
640
+ materials, assignedTo, properties/PRs, permission, both dependency sets and attachments.
576
641
 
577
642
  Migration `014_task_status_assignment.sql` converts historical proposed rows
578
643
  to todo, increments only those versions and updates their update time while
@@ -678,7 +743,26 @@ service order across all pages. This order applies to human and JSON results.
678
743
  `task ready` accepts neither `--status` nor `--cursor`. `task list` supports the
679
744
  same permission and compatibility filters across every matching page. Both are
680
745
  automatic-selection conditions independent of readiness; explicitly designated
681
- execution retains the manual exception.
746
+ execution retains the manual exception. List also accepts
747
+ `--assigned-to <user-uuid|me|unassigned>`, combined with its other filters and
748
+ preserved across every page. `task ready` has no assignee option; use
749
+ `task list --ready --assigned-to me` for that intersection. Automatic acquisition
750
+ requires the task to be assigned to the worker's authenticated account, in addition
751
+ to permission and other eligibility checks. Existing claim inventory and manual
752
+ control remain execution-based; the
753
+ [self-assigned acquisition decision](../../.agents/notes/implemented/architecture/2026-11-03-worker-self-assigned-claims.md)
754
+ owns the runtime rule.
755
+
756
+ For `me`, each successful task-page response must carry one canonical
757
+ Daynight-User-ID, even when its items array is empty. A complete list traversal
758
+ binds its first successful page to that identity and rejects a different later
759
+ principal or a task assigned to someone else. The binding is per traversal, not
760
+ a global client cache. UUID and unassigned filters also verify every result;
761
+ mismatches are protocol errors, not locally discarded rows. No extra `/me`
762
+ request is issued. Non-me requests without a configured expectedUserId retain
763
+ their existing optional-header behavior. Error responses retain the existing
764
+ service-error and configured-principal admission behavior; me adds no new
765
+ error-response header requirement.
682
766
 
683
767
  Updates preserve omitted fields; an empty description clears it. Repeated
684
768
  `--depends-on` and `--external-depends-on` declare the complete ordinary and
@@ -688,8 +772,18 @@ only those external edges. IDs are canonicalized and sorted; malformed and
688
772
  case-equivalent duplicate/cross-declared UUIDs fail before configuration or
689
773
  network access. `--clear-dependencies` sends two empty sets and conflicts with
690
774
  either dependency option. An update needs at least one mutable
691
- field. `--allow-agents true|false` explicitly changes automatic-execution
692
- permission; omitted preserves it. Creation rejects the option. Existing tasks
775
+ field. Create/update accept `--assigned-to <user-uuid>`; update also accepts
776
+ `--clear-assigned-to` to send null. Omission preserves an existing assignee; the
777
+ set/clear options conflict, and invalid UUIDs or combinations fail before
778
+ configuration, Git or HTTP access. Writes accept UUIDs, not the list tokens
779
+ me/unassigned. A real assignment change atomically sets allowAgents=false; an
780
+ equal assignment causes no permission reset; a pure equal update preserves
781
+ version and timestamps. Other supplied fields keep their ordinary mutation
782
+ rules. Actual changes are refused while in_progress. Assignment grants neither project access nor
783
+ control of another worker, Session or archive.
784
+
785
+ `--allow-agents true|false` explicitly changes automatic-execution permission;
786
+ omission preserves it when assignment does not change. Creation rejects the option. Existing tasks
693
787
  receive true through migration without changing versions or business timestamps.
694
788
  A matching same-value permission PATCH retains version and time, while a stale
695
789
  version still conflicts and an actual in-progress toggle fails atomically.
@@ -702,8 +796,12 @@ are refused atomically. Explicit manual status setting remains available for eve
702
796
  requirement. The query platform selects candidates; it does not configure or
703
797
  prove the environment of a future worker.
704
798
  By default the CLI reads the task version before PATCH; `--if-version <n>`
705
- uses that exact positive int64 version. Conflicts and failed writes are reported
706
- without automatic retries.
799
+ uses that exact positive int64 version without a task pre-read. Existing project
800
+ resolution/admission still applies. Null clearing is serialized literally; only
801
+ undefined fields are omitted. A normal write consumes the full Task response
802
+ without a post-write GET or a name lookup. A combined update may advance its
803
+ version for other fields, so v+1 alone does not establish an assignee change.
804
+ Conflicts and failed writes are reported without automatic retries.
707
805
 
708
806
  Text options accept both separated values and `--option=value`. Inline assignment
709
807
  splits at the first equals sign and supports leading dashes, such as
@@ -714,29 +812,35 @@ inline assignment. Attachment `put` declares its `--path` as text, accepting
714
812
  paths starting with a dash. Property set/remove also accept this terminator for
715
813
  literal property/value positionals; other operations retain their declared syntax.
716
814
 
717
- The internal typed ApiClient accepts optional `workerId` on TaskFilters and
718
- TaskPageQuery. It requests only the authenticated user/worker active claims and
719
- validates active state and matching worker ID in responses. `listTasks` returns
815
+ The internal typed ApiClient accepts optional `assignedTo` and `workerId` on
816
+ TaskFilters and TaskPageQuery. Assignment selectors accept `me`, `unassigned` or
817
+ a user UUID; the worker uses `me` for new candidates across every page. With
818
+ workerId, the client requests only the authenticated user/worker active claims
819
+ and validates active state and matching worker ID in responses. `listTasks` returns
720
820
  only after every page succeeds; `listTaskPage` remains partial. A workerId-only
721
821
  traversal across all relevant projects provides ownership inventory; extra filters
722
- or incomplete pages cannot authorize cleanup. This field is not a public task CLI
723
- option.
822
+ or incomplete pages cannot authorize cleanup. These filters are not public task
823
+ CLI options.
724
824
 
725
825
  Human task lists use labeled blocks containing ID, project, title, complete
726
826
  properties, status, readiness, automatic-execution permission, required platform,
727
- dependencies and blocking. Property rows are ordered by name and rendered as
827
+ assignee, dependencies and blocking. Property rows are ordered by name and rendered as
728
828
  terminal-safe JSON; missing keys are not replaced with default values.
729
829
  Description, version and timestamps
730
830
  remain available in show, ready, create and update output. Graph nodes include
731
- state, permission, required platform, dependencies, blocking and title-preview truncation flags.
831
+ state, permission, required platform, assignee, dependencies, blocking and
832
+ title-preview truncation flags.
732
833
  Task and graph decoders require a boolean `allowAgents`; missing, null or
733
834
  nonboolean values are protocol errors. They also require `requiredPlatform`
734
835
  as null or one of the three platform enums; missing keys or other values fail
735
836
  without a runtime default. Human output uses `Required platform: any` for null
736
- and the enum otherwise. Queries support
837
+ and the enum otherwise. `assignedTo` is also required as null or a canonical
838
+ local user UUID on every Task and graph node; missing, malformed or noncanonical
839
+ values fail instead of defaulting. Human output adds `Assigned to: USER_UUID` or
840
+ `Assigned to: unassigned`, with no profile request or rule narration. Task metadata queries support
737
841
  `--json`: task `list` returns every matching task in one array, omitting only
738
- `description` while retaining every other API field, including raw PR strings,
739
- version and timestamps. This applies to the default list and every filter,
842
+ `description` while retaining every other API field, including explicit nullable
843
+ assignedTo, raw PR strings, version and timestamps. This applies to the default list and every filter,
740
844
  including `--all`. Project lists retain all API fields. Task `ready` returns its
741
845
  selected full tasks as an array, details return one full resource, and graphs
742
846
  return the selected task-chain API object unless `--depends-only` projects the
@@ -854,6 +958,68 @@ outcome unknown. The [deletion requirements](../../docs/spec/daynight-task-delet
854
958
  and [design](../../docs/design/daynight-task-deletion.md) own retained history,
855
959
  reference removal and cache invalidation.
856
960
 
961
+ ## Task discussion threads
962
+
963
+ ```bash
964
+ daynight task thread read <task-id>
965
+ daynight task thread read <task-id> --after-id <last-read-message-id> --count=20
966
+ daynight task thread read <task-id> --before-id <first-shown-message-id> --count=20
967
+ daynight task thread read <task-id> --details --project <project-id>
968
+ daynight task thread post <task-id> --body 'What should the retry policy be?'
969
+ daynight task thread post <task-id> --body 'Use an explicit retry decision.' --reply-to <message-id>
970
+ daynight task thread post <task-id> --body 'The check passed.' --claim-id <active-claim-id>
971
+ ```
972
+
973
+ A Thread holds durable discussion independently of task execution. Reads and
974
+ posts work before execution, while its original environment is offline, and
975
+ after completion. Messages are immutable and replies refer to messages in the
976
+ selected task. Posting neither changes task metadata nor wakes an Agent.
977
+ Descriptions and attachments remain the owners of effective requirements,
978
+ solutions and formal results; Sessions hold execution content.
979
+
980
+ Read fetches one page, defaulting to the latest messages. `--count=N` accepts
981
+ 1 through 100 and defaults to 20; the CLI always sends that value explicitly.
982
+ `--before-id` and `--after-id` are mutually exclusive. Messages display from old
983
+ to new with complete Id, Author and account Id, millisecond UTC CreatedAt,
984
+ optional ReplyTo, and complete Message. Agent authors also have `Agent: True`.
985
+ `--details` expands verified claim, worker and provider attribution. Thread
986
+ commands provide readable text and do not accept `--json`.
987
+
988
+ `... Has more messages before` appears above a page with earlier messages;
989
+ `Has more messages after...` appears below a page with later messages. Continue
990
+ history with the first displayed Id and incremental reading with the last
991
+ fully consumed displayed Id. The 256 KiB output budget can reduce the page
992
+ below its requested count; complete messages remain contiguous and bodies are
993
+ never truncated. A post receipt cannot advance the read position: after reading
994
+ A, another person's B and a local post C must still be read from A.
995
+
996
+ Post requires nonblank `--body`, preserving its original whitespace. For text
997
+ beginning with a dash, use `--body=-example`. The service generates the message
998
+ Id and authenticates the author. Omit `--claim-id` for an ordinary account post;
999
+ provide a current claim explicitly for verified Agent attribution. The CLI does
1000
+ not infer a claim or accept a client message Id, version or submission token.
1001
+ `--reply-to` is optional and must identify a message in the same task.
1002
+
1003
+ Terminal text escapes dangerous controls. Multiline Message lines are indented,
1004
+ retain LF and TAB, and encode literal backslashes before visible control
1005
+ escapes; DEL is `\x7f`, CR is `\r`, and other unsafe controls use `\uXXXX`.
1006
+ The representation preserves the full body without executing terminal escapes.
1007
+ Success prints `Message posted.`, the complete Id and optional ReplyTo, without
1008
+ repeating the body. An uncertain post exits with a clear unknown-outcome message.
1009
+ Read the Thread before deciding whether to send again; equal text cannot prove
1010
+ that a particular request succeeded. The CLI never automatically repeats POST.
1011
+
1012
+ The [Thread requirements](../../docs/spec/daynight-task-thread.md) own the
1013
+ service contract; the [CLI design](../../docs/design/task-thread-cli.md) owns
1014
+ source validation, rendering and submission confirmation. Explicit `--project`
1015
+ uses the supplied UUID directly for the Thread request; otherwise the existing
1016
+ Git binding resolves the project. Origin and credential remain fixed for one
1017
+ invocation. Argument errors exit 2 before configuration or network access;
1018
+ other failures exit 1. Diagnostics remain on stderr and exclude message bodies
1019
+ and untrusted server text. A confirmed post followed by a local receipt-output
1020
+ or cleanup failure retains its confirmed message Id and is not reported as an
1021
+ unknown remote result.
1022
+
857
1023
  ## Task attachments
858
1024
 
859
1025
  Attachment commands use the existing project selection and server configuration:
@@ -901,10 +1067,11 @@ records binary transport and output ownership.
901
1067
  ## Worker configuration and startup
902
1068
 
903
1069
  `daynight worker run` is a foreground reconciler. It claims eligible ready tasks
904
- across configured repositories, runs native agents through the claim's Herdr or
1070
+ assigned to its authenticated account across configured repositories, runs native agents through the claim's Herdr or
905
1071
  Web backend, and cleans resources when the original claim leaves its complete
906
1072
  inventory. The agent owns delivery, acceptance, evidence and final claim-bound
907
- completion.
1073
+ completion. Worker follows the CLI platform support policy: Linux, Windows and
1074
+ Apple Silicon (ARM64) macOS.
908
1075
 
909
1076
  The running worker reports an account-owned runtime snapshot immediately after
910
1077
  identity and authentication are ready, every 30 seconds, and after complete task
@@ -1120,7 +1287,7 @@ daynight worker run
1120
1287
  ```
1121
1288
 
1122
1289
  First use generates and atomically saves stable root workerId. One instance owns
1123
- fixed `~/.daynight/worker/` state, its SQLite, lock, logs, temporary resources and
1290
+ `worker/` state under the selected configuration root (default `~/.daynight/worker/`), its SQLite, lock, logs, temporary resources and
1124
1291
  private Herdr. Each task uses branch `daynight/<task-id>` and directory
1125
1292
  `<repository>/.worktrees/daynight/<task-id>`. Valid claims retain their dirty
1126
1293
  worktree; task branches and commits remain after terminal cleanup.
@@ -1179,7 +1346,13 @@ its migration sequence; the [SQLite migration requirements](../../docs/spec/cli-
1179
1346
  define atomicity, ownership blockers and supported starting formats.
1180
1347
 
1181
1348
  Each reconciliation obtains the complete own-claim inventory for configured and
1182
- saved Projects. Still-owned local active tasks are queued for fresh target
1349
+ saved Projects using only workerId. Assignment does not filter this inventory:
1350
+ existing executions retain their recovery and cleanup authority. New candidates
1351
+ combine assignedTo=me, ready, automatic permission and actual platform before
1352
+ server pagination; the claim transaction rechecks the assignee against the
1353
+ authenticated user ID. Unassigned tasks and tasks assigned to another account
1354
+ are ineligible for automatic acquisition. Explicit manual resume retains its
1355
+ original execution-owner/admin rules. Still-owned local active tasks are queued for fresh target
1183
1356
  observation and recovery before global Git discovery, so a sibling checkout's
1184
1357
  filesystem error does not block an already-reserved task. New pending startup
1185
1358
  and new claims still require complete global resource discovery. Failed or
@@ -1446,18 +1619,35 @@ for its supported options. These commands do not implement a native TUI or chang
1446
1619
  The command prints the Test Session URL and remains in the foreground. Sign in
1447
1620
  to Daynight as the account that started it; the URL itself grants no access.
1448
1621
  The service's `/test-sessions` page lists that account's online Test Sessions.
1449
- Archived history remains available through the original URL and local resume. Use the sidebar or the Session page's back link to
1450
- return to the list; session IDs do not need to be copied manually.
1622
+ Completed history is available through the original URL after its file archive
1623
+ is ready. Native resume creates a separate execution. Use the sidebar or the
1624
+ Session page's back link to return to the list; session IDs do not need to be
1625
+ copied manually.
1451
1626
  The page, history, resources, WebSocket and commands all enforce that ownership.
1452
1627
  An expired or revoked credential cannot continue authorizing access. Tokens stay
1453
1628
  in private local files and never appear in the URL.
1454
1629
 
1455
1630
  Task and Test pages share the same timeline, composer and interaction handling.
1456
1631
  Refreshing or closing a browser does not create or stop an Agent. Ctrl+C stops
1457
- the owned execution; the service retains its archived history as read-only when
1458
- shutdown registration succeeds. Service unavailability does not prevent local
1459
- process cleanup, but leaves remote archival unconfirmed. The current directory
1460
- and user files are never removed by the launcher.
1632
+ the owned execution. Once the service confirms shutdown, the launcher uploads
1633
+ its recorded timeline and resources to file storage for read-only access. The
1634
+ service database stores archive metadata, not conversation payloads. Service
1635
+ unavailability does not prevent local process cleanup; failed uploads retain
1636
+ their private local source. The current directory and user files are never
1637
+ removed by the launcher.
1638
+
1639
+ Retry a failed upload without starting or resuming the Agent:
1640
+
1641
+ ```sh
1642
+ daynight controller codex archive <test-session-id>
1643
+ ```
1644
+
1645
+ The same command supports `claude` and `copilot`. It verifies the original local
1646
+ execution and stop evidence, and does not require the old working directory to
1647
+ still exist. Use `-- archive` to send the literal word as an initial prompt.
1648
+ Archives are limited to 64 MiB including resource encoding, with at most 8 MiB
1649
+ per resource; incomplete or oversized archives fail explicitly and retain their
1650
+ source. Completed pages disable all Agent controls.
1461
1651
 
1462
1652
  Resume a stopped Test Session with its native context:
1463
1653
 
@@ -1527,6 +1717,10 @@ daynight worker resume <task-id> --claim-id <released-claim-id> --if-version <ve
1527
1717
  ```
1528
1718
 
1529
1719
  Resume requires the previous released claim, ready task and original owner/admin.
1720
+ Remote Worker control reads the caller's current `/projects/{id}/access`
1721
+ projection for administrator authority and verifies its project/principal binding;
1722
+ member profile reads retain their separate directory responsibility. Grant
1723
+ versions preserve the full positive int64 range.
1530
1724
  It preserves the explicit manual permission/platform exception, obtains fresh
1531
1725
  claim/worktree identities with current settings, and registers pending with a
1532
1726
  NULL native session ID. Start run to execute it.
@@ -1559,8 +1753,7 @@ daynight review run
1559
1753
  ```
1560
1754
 
1561
1755
  For a local build, run `pnpm daynight review run` from the repository root.
1562
- These commands select `~/.daynight/config.yml` using the current OS user's home
1563
- directory. `review add-repo`
1756
+ These commands select `config.yml` under the [configuration root](#configuration-root). `review add-repo`
1564
1757
  creates the configuration when absent. It reads, validates and saves configuration;
1565
1758
  cloning, authentication checks, GitHub calls, SQLite initialization and PR boundary
1566
1759
  selection belong to review startup. An already running reviewer keeps its loaded
@@ -1643,7 +1836,7 @@ This observes actual case and Unicode rules. Validation removes only the
1643
1836
  directories it created, using nonrecursive removal. Probe permission, inspection,
1644
1837
  or cleanup failures stop validation with an error.
1645
1838
 
1646
- The selected retained-state location is `~/.daynight/` for SQLite, sessions,
1839
+ The selected retained-state location is `DN_CONFIG_DIR` (default `~/.daynight/`) for SQLite, sessions,
1647
1840
  locks, logs, cache, and temporary files. PR worktrees belong to each monitored
1648
1841
  repository root's `.worktrees/` directory. `maxConcurrentWorker` limits concurrent
1649
1842
  review preparation and execution. Startup acquires an exclusive instance lock,
@@ -1744,7 +1937,7 @@ verification.
1744
1937
  Each store's baseline and SQL conversions ship as `.sql` resources with the
1745
1938
  installed dist tree. Top-level SQL files in that store's directory run in lexical
1746
1939
  filename order: the first is its baseline, and consecutive numeric prefixes set
1747
- later versions. Five baselines and five upgrades form the current SQL inventory.
1940
+ later versions. Five baselines and six upgrades form the current SQL inventory.
1748
1941
  TypeScript keeps JSON conversion, ownership checks and the atomic version-0 reset;
1749
1942
  ordinary non-SQL subdirectories do not enter the normal chain. Resource loading and
1750
1943
  sequence validation finish before user-database access; package checks compare
@@ -1,4 +1,4 @@
1
- # Shared CLI configuration: ~/.daynight/config.yml.
1
+ # Shared CLI configuration: $DN_CONFIG_DIR/config.yml (default ~/.daynight/config.yml).
2
2
  # Select the sections needed for your commands and replace the example repositories
3
3
  # and local paths. Merge settings into an existing file to retain credentials and
4
4
  # other configuration; this file is a reference, not an automatically loaded config.
@@ -11,6 +11,13 @@ serverUrl: https://daynight.cc
11
11
  # Remove or replace an old token before changing serverUrl manually. Keep secrets
12
12
  # out of repositories and logs; files containing a token need POSIX mode 0600.
13
13
 
14
+ # Optional Agent-only CLI mappings (macOS/Linux), disabled when omitted or {}.
15
+ # Keys are commands the Agent uses; values are executable names or absolute paths.
16
+ # Only new Worker/Controller Agent environments receive these aliases.
17
+ # agentCliAliases:
18
+ # daynight: daynight-dev
19
+ # dn: daynight-dev
20
+
14
21
  # Review configuration. The numeric values below are the defaults; all are positive
15
22
  # integers, and fields ending in Ms use milliseconds.
16
23
  # Only repositoryRoot expands ~. It selects paths for future review add-repo calls
@@ -28,8 +35,8 @@ review:
28
35
  # copilotReasoningEffort: high
29
36
  repositories:
30
37
  - remote: https://github.com/OWNER/REPO.git
31
- # Repository paths are absolute or relative to ~/.daynight/, never the launch
32
- # directory, and do not expand ~. Keep review clones outside ~/.daynight/.
38
+ # Repository paths are absolute or relative to the selected config directory, never the launch
39
+ # directory, and do not expand ~. Keep review clones outside that directory.
33
40
  path: ../daynights/github.com/owner/repo
34
41
 
35
42
  # Worker configuration. Run daynight worker setup to inspect prerequisites,
@@ -1,5 +1,6 @@
1
+ import type { ThreadReadQuery, PostThreadMessageInput, ThreadMessage, ThreadPage } from "./types.js";
1
2
  import type { Operation } from "./operation.js";
2
- import type { AttachmentConsumer, CreateProjectInput, CreateTaskInput, DeleteTaskInput, ErrorDetails, Project, ProjectMember, PutTaskAttachmentInput, ReadyTaskFilters, ServerError, Task, SetTaskStatusInput, TaskAttachment, TaskFilters, TaskGraph, UpdateTaskInput, ClaimWorkerTaskInput, CompleteWorkerTaskInput, ReleaseWorkerClaimInput, ResumeWorkerTaskInput, WithdrawWorkerClaimInput, UpdateWorkerClaimInput, User, Page, TaskPageQuery, WorkerReport, WorkerReportReceipt, TaskPropertyResource, TaskPropertySchema, SetTaskPropertyInput, RemoveTaskPropertyInput } from "./types.js";
3
+ import type { AttachmentConsumer, CreateProjectInput, CreateTaskInput, DeleteTaskInput, ErrorDetails, Project, ProjectAccess, ProjectMember, PutTaskAttachmentInput, ReadyTaskFilters, ServerError, Task, SetTaskStatusInput, TaskAttachment, TaskFilters, TaskGraph, UpdateTaskInput, ClaimWorkerTaskInput, CompleteWorkerTaskInput, ReleaseWorkerClaimInput, ResumeWorkerTaskInput, WithdrawWorkerClaimInput, UpdateWorkerClaimInput, User, Page, TaskPageQuery, WorkerReport, WorkerReportReceipt, TaskPropertyResource, TaskPropertySchema, SetTaskPropertyInput, RemoveTaskPropertyInput } from "./types.js";
3
4
  type Context = {
4
5
  readonly operation: string;
5
6
  readonly projectId?: string;
@@ -17,19 +18,24 @@ export declare class ApiError extends Error {
17
18
  readonly details?: ErrorDetails;
18
19
  readonly outcomeUnconfirmed: boolean;
19
20
  readonly confirmedRefusal: boolean;
21
+ readonly confirmedMessageId?: string;
20
22
  constructor(context: Context, phase: ApiPhase, options: {
21
23
  readonly cause: unknown;
22
24
  readonly status?: number;
23
25
  readonly serverError?: ServerError;
24
26
  readonly outcomeUnconfirmed?: boolean;
25
27
  readonly confirmedRefusal?: boolean;
28
+ readonly confirmedMessageId?: string;
26
29
  });
27
30
  }
28
31
  export type ApiClient = {
32
+ readTaskThread(projectId: string, taskId: string, query: ThreadReadQuery): Promise<ThreadPage>;
33
+ postTaskThreadMessage(projectId: string, taskId: string, input: PostThreadMessageInput): Promise<ThreadMessage>;
29
34
  getCurrentUser(): Promise<User>;
30
35
  reportWorker(workerId: string, input: WorkerReport): Promise<WorkerReportReceipt>;
31
36
  createProject(input: CreateProjectInput): Promise<Project>;
32
37
  getProject(projectId: string): Promise<Project>;
38
+ getProjectAccess(projectId: string): Promise<ProjectAccess>;
33
39
  listProjects(): Promise<readonly Project[]>;
34
40
  listProjectMembers(projectId: string): Promise<readonly ProjectMember[]>;
35
41
  createTask(projectId: string, input: CreateTaskInput): Promise<Task>;