aligndev 0.0.0 → 0.18.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 (73) hide show
  1. package/README.md +166 -1
  2. package/bin/aligndev.mjs +3 -0
  3. package/dist/alignfirst-cli.d.ts +10 -0
  4. package/dist/alignfirst-cli.js +56 -0
  5. package/dist/cli.d.ts +15 -0
  6. package/dist/cli.js +95 -0
  7. package/dist/code/claude-agent.d.ts +14 -0
  8. package/dist/code/claude-agent.js +168 -0
  9. package/dist/code/code-cli.d.ts +72 -0
  10. package/dist/code/code-cli.js +630 -0
  11. package/dist/code/codex-agent.d.ts +15 -0
  12. package/dist/code/codex-agent.js +168 -0
  13. package/dist/code/codex-rollout.d.ts +18 -0
  14. package/dist/code/codex-rollout.js +114 -0
  15. package/dist/code/coding-agent.d.ts +4 -0
  16. package/dist/code/coding-agent.js +6 -0
  17. package/dist/code/models.d.ts +14 -0
  18. package/dist/code/models.js +89 -0
  19. package/dist/code/prompt.d.ts +11 -0
  20. package/dist/code/prompt.js +26 -0
  21. package/dist/code/quota.d.ts +25 -0
  22. package/dist/code/quota.js +248 -0
  23. package/dist/code/run-agent.d.ts +60 -0
  24. package/dist/code/run-agent.js +212 -0
  25. package/dist/code/session-file.d.ts +50 -0
  26. package/dist/code/session-file.js +263 -0
  27. package/dist/command-form.d.ts +6 -0
  28. package/dist/command-form.js +7 -0
  29. package/dist/config.d.ts +22 -0
  30. package/dist/config.js +72 -0
  31. package/dist/errors.d.ts +2 -0
  32. package/dist/errors.js +6 -0
  33. package/dist/guide/code-guide.d.ts +4 -0
  34. package/dist/guide/code-guide.js +17 -0
  35. package/dist/guide/guide-cli.d.ts +3 -0
  36. package/dist/guide/guide-cli.js +81 -0
  37. package/dist/guide/render-template.d.ts +4 -0
  38. package/dist/guide/render-template.js +62 -0
  39. package/dist/guide/topics.d.ts +3 -0
  40. package/dist/guide/topics.js +16 -0
  41. package/dist/output.d.ts +3 -0
  42. package/dist/output.js +1 -0
  43. package/dist/project/discovery.d.ts +42 -0
  44. package/dist/project/discovery.js +287 -0
  45. package/dist/project/format.d.ts +6 -0
  46. package/dist/project/format.js +31 -0
  47. package/dist/project/guide.d.ts +3 -0
  48. package/dist/project/guide.js +69 -0
  49. package/dist/project/layout.d.ts +36 -0
  50. package/dist/project/layout.js +128 -0
  51. package/dist/project/markers.d.ts +18 -0
  52. package/dist/project/markers.js +90 -0
  53. package/dist/project/ports.d.ts +3 -0
  54. package/dist/project/ports.js +55 -0
  55. package/dist/project/project-cli.d.ts +17 -0
  56. package/dist/project/project-cli.js +227 -0
  57. package/dist/project/render.d.ts +10 -0
  58. package/dist/project/render.js +144 -0
  59. package/dist/project/status.d.ts +24 -0
  60. package/dist/project/status.js +110 -0
  61. package/dist/templates.d.ts +1 -0
  62. package/dist/templates.js +5 -0
  63. package/package.json +38 -3
  64. package/templates/guide/code.md +252 -0
  65. package/templates/guide/playbook/channel-handling.md +110 -0
  66. package/templates/guide/playbook/consultation.md +71 -0
  67. package/templates/guide/playbook/discord-message-tool.md +37 -0
  68. package/templates/guide/playbook/playbook.md +139 -0
  69. package/templates/guide/playbook/project-lifecycle.md +100 -0
  70. package/templates/guide/playbook/project-workspace-setup.md +186 -0
  71. package/templates/guide/playbook/slack-message-tool.md +23 -0
  72. package/templates/guide/playbook/working-session.md +588 -0
  73. package/templates/guide/project.md +33 -0
@@ -0,0 +1,588 @@
1
+ # Working session
2
+
3
+ {{#openclaw}}
4
+ You're handling work inside a Slack or Discord thread. Lifecycle, workspace, consultation, and coding happen here.
5
+
6
+ A thread usually arrives from a channel session, which delivered the starter and may have started this session with a message from AlignFirst Service. A human can also open a thread themselves and tag you in it; "A thread you did not open" below covers what changes. Either way this is a working thread, and you never open another from inside it.
7
+
8
+ Your plain text is your reply, on Discord and Slack alike, and only the message that **ends your turn** is guaranteed to post: on most model providers, text written between tool calls never leaves the transcript. So the message you end a turn with carries everything the user needs from that turn: the workspace state, the launch ack, the report. Never call `message` `send`/`thread-reply` on this thread; it posts everything twice. The single exception is a Discord rename, which travels with a post (see "Thread name" below). Otherwise `message` serves `read`, reactions, cross-surface posts, and attachments.
9
+
10
+ Keep progress and completion reports in this thread. A request to notify the user means reply here; use a DM or another surface only when the user explicitly names that destination.
11
+ {{/openclaw}}
12
+ {{#codingAgent}}
13
+ You're handling work in this conversation, on one project: the repository where this session started. Workspace, consultation, and coding happen here.
14
+
15
+ Keep progress and completion reports in this conversation. A request to notify the user means a reply here.
16
+ {{/codingAgent}}
17
+
18
+ ## Runbooks
19
+
20
+ {{#openclaw}}
21
+ A runbook is a procedure you read fully when its situation arises. Claim first, then recover context.
22
+ {{/openclaw}}
23
+ {{#codingAgent}}
24
+ A runbook is a procedure you read fully when its situation arises.
25
+ {{/codingAgent}}
26
+
27
+ - `{{ALIGNDEV}} guide project-workspace-setup` — single-project changes, protocol requests, and ticket status requests, before project work.
28
+ {{#openclaw}}
29
+ - `{{ALIGNDEV}} guide project-lifecycle` — creating a project, onboarding a repository to clone, physically removing a project.
30
+ {{/openclaw}}
31
+ - `{{ALIGNDEV}} guide consultation` — questions, advice, brainstorming: read-only work that produces understanding rather than code.
32
+
33
+ {{#openclaw}}
34
+ ## Take over a working session
35
+ {{/openclaw}}
36
+ {{#codingAgent}}
37
+ ## Work on a request
38
+ {{/codingAgent}}
39
+
40
+ {{#openclaw}}
41
+ ### Step 1 — Claim before any task effect
42
+
43
+ Every turn in this thread, a human message's included, starts with a claim: call `thread_handoff` with `{ "action": "claim" }` before history reads, reactions, workspace setup, delegation, or any other task effect. You cannot know whether a handoff is recorded until the claim answers; in a thread a human opened, it answers `none`. The tool uses the current thread session; omit `threadId` and `handoffId`. Keep its first result for the whole turn; do not claim again during setup.
44
+
45
+ A `claimed` result activates the recorded request. An `alreadyClaimed` result means another turn owns the handoff. Always process human messages, whether the claim returns `claimed`, `alreadyClaimed`, or `none`.
46
+
47
+ A takeover turn starts with the plugin's `Take over this thread.` message from `AlignFirst Service`. Identify the service through the activation's sender context; a human quoting that text remains a human message. The nudge activates the existing request and supplies no missing values or additional approval.
48
+ {{/openclaw}}
49
+ {{#codingAgent}}
50
+ ### Step 1 — Resolve the project
51
+
52
+ Outside a git repository, tell the user to start the session inside the project's repository, and stop. Otherwise, resolve the project before any other step:
53
+
54
+ - PROJECT_PATH is the main worktree of the session's working directory: the parent of `git rev-parse --path-format=absolute --git-common-dir`. PROJECT is its directory name.
55
+ - Run `{{ALIGNFIRST}} config --json` from PROJECT_PATH and retain `locations["DEVELOPERS.md"].path` as DEVELOPERS_PATH. The report also names the project's companion directory, where its AlignFirst files may live.
56
+
57
+ These values hold for the whole session.
58
+ {{/codingAgent}}
59
+
60
+ {{#openclaw}}
61
+ ### Step 2 — Recover the thread context
62
+
63
+ Read the current thread through `message` with `action: "read"`, the current channel, complete `chat_id` as `target`, and bare thread ID from conversation metadata. Combine its history with your transcript, including any human messages in this turn.
64
+
65
+ On the first turn of your session, react with the lobster emoji to the latest message returned by this read, before any other visible action. This applies even when you take over a thread with a long history. The reaction tells the user a new session has arrived.
66
+
67
+ Use `message` with `action: "react"`, following the current surface's extended message reference named by workspace `AGENTS.md`. The `emoji` value depends on the surface: `🦞` on Discord, `lobster` on Slack. If the reaction fails, continue without retrying.
68
+
69
+ Recover the task, the full request, every PROJECT / PROJECT_PATH pair, and TICKET_ID from that context. With a starter present, its values come from the inventory the channel session consulted; run `{{ALIGNDEV}} project list --json` only where a runbook, the multi-project procedure, or "A thread you did not open" asks for it. Later human messages supply missing values or correct the request. Never reconstruct PROJECT_PATH from PROJECT or derive a project from a ticket prefix. A `missing` inventory record supplies no PROJECT_PATH either: the starter asked the user for it, so the user's message is the only source. Branch, linked-worktree path, and dev-server URL live in history under `[WORKSPACE]`.
70
+
71
+ On a takeover turn:
72
+
73
+ - The claim failed: stop and report the failure in the thread.
74
+ - No human message needs processing and the claim returned `alreadyClaimed`: end on exactly `HEARTBEAT_OK`.
75
+ - The starter asked for a value and no human message has supplied it: end on exactly `HEARTBEAT_OK`. Only the user supplies that value; a lookup of your own is not an answer, and the question is not repeated.
76
+ - The starter asked nothing but a required value is missing (a detailed change request without a ticket, for instance): ask for it now.
77
+ - The request is complete: proceed. It is the go-ahead; respect an explicit request to hold.
78
+
79
+ #### A thread you did not open
80
+
81
+ A human can open a thread and tag you in it. The history then holds their messages and no starter, and `thread_handoff claim` returns `none`. Both are expected here, and neither means you are in a channel: `topic_id` already settled that, and the work belongs in this thread.
82
+
83
+ What changes is where the values come from:
84
+
85
+ - The human messages are the request. Read them as the starter's task and, when detailed, as its full text.
86
+ - PROJECT and PROJECT_PATH are yours to resolve: run `{{ALIGNDEV}} project list --json` and apply the resolution rules of `{{ALIGNDEV}} guide channel-handling`. Ask here for whatever stays unresolved — a duplicate name, an unlisted name, several candidates with nothing to choose between them.
87
+ - The thread keeps the name its author gave it. Skip the Discord rename in "Thread name" below for the whole session.
88
+
89
+ Everything else is unchanged: the same runbooks, the same ticket rules, the same delegation.
90
+ {{/openclaw}}
91
+ {{#codingAgent}}
92
+ ### Step 2 — Recover the request
93
+
94
+ The request comes from this conversation; later messages supply missing values or correct it. TICKET_ID comes from the user, a resource URL, or the current branch name when it carries one. Branch, linked-worktree path, and dev-server URL live in the conversation under `[WORKSPACE]`.
95
+ {{/codingAgent}}
96
+
97
+ ### Step 3 — Resolve deferred context
98
+
99
+ {{#openclaw}}
100
+ The channel deliberately leaves some values for this session:
101
+ {{/openclaw}}
102
+ {{#codingAgent}}
103
+ Resolve what the request leaves open:
104
+ {{/codingAgent}}
105
+
106
+ - A PR/MR, issue, ticket, or other resource URL may identify its project and ticket. Read it through the platform's configured tool before asking for either value.
107
+ {{#openclaw}}
108
+ - For a multi-project request, retain every affected project and path. Do not choose a main project merely to fit a single-project workflow.
109
+ {{/openclaw}}
110
+ {{#openclaw}}
111
+ - A request may need no project. Do not ask for one until the work itself requires project files.
112
+ {{/openclaw}}
113
+ - Code reviews and explicitly requested AlignFirst protocols follow the ticket and workspace flow. Other read-only questions, advice and brainstormings require PROJECT and PROJECT_PATH only. Follow `{{ALIGNDEV}} guide consultation` before ticket preflight, request capture, or workspace setup. A supplied ticket is context, not a requirement to create or update ticket artifacts.
114
+ {{#openclaw}}
115
+ - Single-project changes, protocol requests, and ticket status requests require PROJECT, PROJECT_PATH, and TICKET_ID. Ask only after the available resource, inventory, request, and ticket integration fail to supply them. An explicit no-ticket request follows Step 5 instead of asking for an external ID.
116
+ {{/openclaw}}
117
+ {{#codingAgent}}
118
+ - Single-project changes, protocol requests, and ticket status requests require PROJECT, PROJECT_PATH, and TICKET_ID. Ask only after the available resource, request, and ticket integration fail to supply them. An explicit no-ticket request follows Step 5 instead of asking for an external ID.
119
+ {{/codingAgent}}
120
+
121
+ {{#openclaw}}
122
+ Once a single-project request's PROJECT_PATH is known, run `{{ALIGNDEV}} project status <PROJECT_PATH>` and retain its `DEVELOPERS.md` path as DEVELOPERS_PATH. The report also names the project's companion directory, where its AlignFirst files may live.
123
+ {{/openclaw}}
124
+
125
+ For changes, protocol requests, and ticket status requests, as soon as PROJECT_PATH and TICKET_ID are known, and before project work, run `{{ALIGNFIRST}} sync`, then `{{ALIGNFIRST}} ticket {TICKET_ID}` from PROJECT_PATH. The second command validates the id and creates or restores TICKET_DIR before `{{ALIGNDEV}} code` can create session artifacts. Stop if either command fails. If either value becomes known later in the session, run the preflight then.
126
+
127
+ TICKET_DIR lies in the work-files directory, `.plans/`, which may live in the project's companion. Use TICKET_DIR exactly as `{{ALIGNFIRST}} ticket` prints it, resolved from PROJECT_PATH when relative.
128
+
129
+ Default rule: When the user asks you to handle or implement an existing ticket and a configured account gives you access to its platform, inspect the ticket before workspace setup. If its state is To do or equivalent and its assignee is either empty or your account, ensure it is assigned to your account and move it to In progress or equivalent when that state exists.
130
+
131
+ {{#openclaw}}
132
+ ### Step 4 — Route project lifecycle work
133
+
134
+ When the request creates a project, onboards a repository to clone, or physically removes a project, run `{{ALIGNDEV}} guide project-lifecycle`, read it fully, and follow it before considering a project workspace. Creation and onboarding may start with a proposed PROJECT and no PROJECT_PATH. Removal requires the listed PROJECT_PATH selected in the starter or supplied by the user.
135
+ {{/openclaw}}
136
+ {{#codingAgent}}
137
+ ### Step 4 — Decline project lifecycle work
138
+
139
+ Creating a project, onboarding a repository to clone, or physically removing a project is not handled in this mode. Tell the user so.
140
+ {{/codingAgent}}
141
+
142
+ Project-workspace cleanup is not physical project removal; follow "Cleanup requests" below.
143
+
144
+ ### Step 5 — Reserve a side ticket for explicit no-ticket work
145
+
146
+ {{#openclaw}}
147
+ Skip this step for read-only questions, project lifecycle, and operational work. A new project's bootstrap through its initial commit stays in the lifecycle procedure.
148
+ {{/openclaw}}
149
+ {{#codingAgent}}
150
+ Skip this step for read-only questions and operational work.
151
+ {{/codingAgent}}
152
+
153
+ For new single-project work where the user explicitly says there is no ticket or asks for a side ticket:
154
+
155
+ 1. Read DEVELOPERS_PATH and run `{{ALIGNFIRST}} context` from PROJECT_PATH.
156
+ 2. Run `{{ALIGNFIRST}} sync`, so identifier selection sees the current shared task set.
157
+ {{#openclaw}}
158
+ 3. Run `{{ALIGNFIRST}} ticket --side` from PROJECT_PATH (`exec`). It creates the ticket directory and prints it as TICKET_DIR; TICKET_ID is the `side-N` it reports.
159
+ {{/openclaw}}
160
+ {{#codingAgent}}
161
+ 3. Run `{{ALIGNFIRST}} ticket --side` from PROJECT_PATH. It creates the ticket directory and prints it as TICKET_DIR; TICKET_ID is the `side-N` it reports.
162
+ {{/codingAgent}}
163
+ {{#openclaw}}
164
+ 4. Write `{TICKET_DIR}A1-request.md` with the complete recorded request. For a short request, use the starter's task line and the message that explicitly confirmed no ticket.
165
+ {{/openclaw}}
166
+ {{#codingAgent}}
167
+ 4. Write `{TICKET_DIR}A1-request.md` with the complete request. For a short request, use the user's request and the message that explicitly confirmed no ticket.
168
+ {{/codingAgent}}
169
+ 5. Run `{{ALIGNFIRST}} sync`.
170
+
171
+ {{#openclaw}}
172
+ The bot owns this reservation and the request capture; the coder receives TICKET_ID. Do not use `{{ALIGNDEV}} code new --no-ticket`: TICKET_ID must exist before delegation, for the request file and the workspace. Continue to workspace setup with the side ticket as TICKET_ID, then run the coding protocol from the returned linked worktree.
173
+ {{/openclaw}}
174
+ {{#codingAgent}}
175
+ You own this reservation and the request capture; the coder receives TICKET_ID. Do not use `{{ALIGNDEV}} code new --no-ticket`: TICKET_ID must exist before delegation, for the request file and the workspace. Continue to workspace setup with the side ticket as TICKET_ID, then run the coding protocol from the returned linked worktree.
176
+ {{/codingAgent}}
177
+
178
+ {{#openclaw}}
179
+ ### Step 6 — The thread's state is its workspace
180
+ {{/openclaw}}
181
+ {{#codingAgent}}
182
+ ### Step 6 — The session's state is its workspace
183
+ {{/codingAgent}}
184
+
185
+ The question on every turn is not a mode but a fact: does this request need a project workspace?
186
+
187
+ - **The request is a code review or names an AlignFirst protocol** — follow the ticket and workspace flow below.
188
+ - **The request is another read-only question, advice, or a brainstorming** — run `{{ALIGNDEV}} guide consultation`, read it fully, and follow it.
189
+ {{#openclaw}}
190
+ - **The request is a single-project change, protocol request, or ticket status request** — require PROJECT, PROJECT_PATH, and TICKET_ID. A starter with a request block is filed first ("Detailed requests" below). Then run `{{ALIGNDEV}} guide project-workspace-setup`, read it fully, and complete it before any other action, `git log` and codebase inspection included. Your first post is its setup signal (Step 2); the procedure attaches or sets up the workspace, whatever exists, and posts the `[WORKSPACE]` banner.
191
+ {{/openclaw}}
192
+ {{#codingAgent}}
193
+ - **The request is a single-project change, protocol request, or ticket status request** — require PROJECT, PROJECT_PATH, and TICKET_ID. A detailed request is filed first ("Detailed requests" below). Then run `{{ALIGNDEV}} guide project-workspace-setup`, read it fully, and complete it before any other action, `git log` and codebase inspection included. Your first post is its setup signal (Step 2); the procedure attaches or sets up the workspace, whatever exists, and posts the `[WORKSPACE]` banner.
194
+ {{/codingAgent}}
195
+ - **A required value is missing** — go to Step 7. Resolve or ask for it there. The moment the required values are known, follow the matching path above.
196
+
197
+ {{#openclaw}}
198
+ Changes to an existing project happen inside a linked workspace. Read-only questions use the main worktree by default. The lifecycle procedure also uses it for new-project bootstrap through its initial commit and repository onboarding on a setup branch.
199
+ {{/openclaw}}
200
+ {{#codingAgent}}
201
+ Changes to an existing project happen inside a linked workspace. Read-only questions use the main worktree by default.
202
+ {{/codingAgent}}
203
+
204
+ ### Step 7 — Handle the actual request
205
+
206
+ Use the guidelines.
207
+
208
+ ## Guidelines
209
+
210
+ {{#openclaw}}
211
+ ### Thread name
212
+
213
+ Slack threads have no name — skip this section entirely there; a rename attempt is a failed `message` call whose error notice lands in the thread. Skip it too in a thread a human opened, which keeps its author's name.
214
+
215
+ On Discord, in a thread you opened, keep the name describing the work. As soon as you have a description of what's to be done — the channel opened the thread on a vague message, the user just supplied the ticket, the task turned out to be something else — rename it: `<TICKET_ID> - <PROJECT> - <1-to-5-word description>`, dropping a leading segment you don't have yet. This applies to threads without a workspace too.
216
+
217
+ On Discord the rename travels with a post: `message` `action: "send"` with the current thread's complete `chat_id` as `target`, the new name as `threadName`, and your next user-facing line as `message`. `thread-reply` ignores `threadName`. The work of the turn continues after the post. When the post was the turn's last word, end the turn on exactly `NO_REPLY`; any plain text after it, the line itself or a tool-result echo, would post a second message.
218
+ {{/openclaw}}
219
+
220
+ ### Interpreting requests
221
+
222
+ Interpret every user message in the context of the current project — something to do, investigate, challenge, or advise on inside the codebase. The user is rarely asking you to perform the action _in the chat_; they're asking about the project.
223
+
224
+ - **Code change.** "Set this text bolder" → bold it in the project, not in the chat reply.
225
+
226
+ {{#openclaw}}
227
+ Only when the message is unambiguously about chat content ("summarize this thread", "what does this mean") should you treat it as a regular conversation.
228
+ {{/openclaw}}
229
+ {{#codingAgent}}
230
+ Only when the message is unambiguously about chat content ("summarize this conversation", "what does this mean") should you treat it as a regular conversation.
231
+ {{/codingAgent}}
232
+
233
+ **Question, advice, or a design opinion.** The substance comes from the coder, which reads the repository. Follow `{{ALIGNDEV}} guide consultation`. No code change unless asked.
234
+
235
+ ### Read-only questions
236
+
237
+ A codebase question, advice, or a brainstorming follows `{{ALIGNDEV}} guide consultation`. Read it fully. It resolves the project, delegates the complete question to the coder, and records the discussion when one is worth keeping.
238
+
239
+ A request for a ticket's progress follows "Status update" instead; it needs that ticket's history and workspace state.
240
+
241
+ ### Detailed requests
242
+
243
+ When one project owns a detailed change request, preserve it before delegation:
244
+
245
+ 1. Establish TICKET_ID. When project or deployment instructions provide ticket-system access, create a ticket with a very short description in the user's language. When no access is provided, ask the user for the ticket ID.
246
+ 2. If this step established TICKET_ID, complete the known-ticket preflight now. Then run `{{ALIGNFIRST}} ticket {TICKET_ID} --next request.md` and append FILE_NAME to TICKET_DIR, exactly as printed, to get the request-file path.
247
+ {{#openclaw}}
248
+ 3. Write the complete request text recorded in the starter's request block to that path. Keep its language. You may fix typos; preserve every detail.
249
+ {{/openclaw}}
250
+ {{#codingAgent}}
251
+ 3. Write the complete request text from this conversation to that path. Keep its language. You may fix typos; preserve every detail.
252
+ {{/codingAgent}}
253
+ 4. Run `{{ALIGNFIRST}} sync`.
254
+ 5. When ticket editing is available, add the request-file path relative to the project to the ticket description.
255
+ 6. Continue through project workspace setup and `{{ALIGNDEV}} code` as usual.
256
+
257
+ When Step 5 reserved a side ticket `side-N`, the request is already captured. Continue through project workspace setup and delegate from the linked worktree.
258
+
259
+ {{#openclaw}}
260
+ Skip this capture workflow for a multi-project request with no main project and for operational work such as workspace cleanup or base-branch refresh. Delegate those requests to the coder without an AlignFirst protocol.
261
+ {{/openclaw}}
262
+ {{#codingAgent}}
263
+ Skip this capture workflow for operational work such as workspace cleanup or base-branch refresh. Delegate those requests to the coder without an AlignFirst protocol.
264
+ {{/codingAgent}}
265
+
266
+ {{#openclaw}}
267
+ ### Multi-project and operational work
268
+
269
+ Delegate a multi-project request with no main project, workspace cleanup, base-branch refresh, and similar operational work to the coder without an AlignFirst protocol. Refresh `{{ALIGNDEV}} project list --json` when the affected project set is not already recorded. Run one project-bound coder session from each affected PROJECT_PATH and coordinate their results in the thread. For a base-branch refresh, the coder owns the initial fetch, the fast-forward, and any dependency, build, or migration refresh; an already-current branch is one possible result of that delegation. Supply the ticket ID when one identifies the workspaces and name every configured global tool the run can use. Set up project workspaces only when the operation needs them.
270
+ {{/openclaw}}
271
+ {{#codingAgent}}
272
+ ### Operational work
273
+
274
+ Delegate workspace cleanup, base-branch refresh, and similar operational work to the coder without an AlignFirst protocol, from PROJECT_PATH. For a base-branch refresh, the coder owns the initial fetch, the fast-forward, and any dependency, build, or migration refresh; an already-current branch is one possible result of that delegation. Supply the ticket ID when one identifies the workspaces and name every configured global tool the run can use. Set up project workspaces only when the operation needs them.
275
+ {{/codingAgent}}
276
+
277
+ ### What you delegate vs do
278
+
279
+ Lean toward delegating; the less you touch the project directly, the better.
280
+
281
+ Delegate to the coder: workspace/branch/worktree creation, writing code (`alignfirst` protocols), commits, pushes, opening MR/PRs.
282
+
283
+ Thinking is delegated too. When you need *ideas*, a *design* direction, an *opinion*, or an approach — for the user or for your own next step — put the question to the coder and build on its answer. Never brainstorm alone: the coder grounds its ideas in the codebase; yours would come from memory. `{{ALIGNDEV}} guide consultation` is the procedure.
284
+
285
+ Global tools go in the prompt. Run `{{ALIGNDEV}} code` from the linked workspace for changes and from PROJECT_PATH only when the procedure explicitly works in the main worktree. The coder knows only that directory's project context: it can run the globally installed tools your own context lists, but it doesn't know they exist. When a delegated task can use one, name it in the prompt as **globally installed**. A task you would have kept because it needs such a tool is one more thing to delegate.
286
+
287
+ Every single-project change delegation carries TICKET_ID in the `{{ALIGNDEV}} code` invocation or message as the delegation guide allows. Read-only questions omit the ticket option; a ticket mentioned by the user stays in the question's context. Operational maintenance may instead identify its existing branches and workspaces directly.
288
+
289
+ Feel free to do the rest yourself (except coding) when it's more practical.
290
+
291
+ ### A background run moves the report
292
+
293
+ Launching a background run ends the turn: the closing message is the launch acknowledgement, and the report moves to the run's completion turn. Each further run launched from that turn moves the report again.
294
+
295
+ ### The plan is not a gate
296
+
297
+ Coding work follows spec → plan → implementation, as the delegation guide describes. That chain is how the coder works, not a series of checkpoints for the user: run it end to end. When the plan lands, launch the implementation in a new session right away and tell the user in one line that it started.
298
+
299
+ The coder usually has no question. When it does, answer it: a technical question — architecture, existing behavior, anything the codebase answers — you settle yourself, pushing the coder to investigate. A functional or product question goes to the user, and you relay their answer back.
300
+
301
+ ### Plan files are the coder's material
302
+
303
+ Before acting on any file the user names under `.plans/`, run `{{ALIGNFIRST}} sync`. Then never read a plan file, main plans included. A request to execute a plan means: read the spec next to it when one exists — same directory, same leading letter (`A1-spec.md` for `A2-plan.md`) — then hand the plan's path to the coder, as the delegation guide describes.
304
+
305
+ For the `.plans/` directory's task directories, cycles, filenames, and artifact conventions, run `{{ALIGNFIRST}} guide` from PROJECT_PATH; its output ends with the ticket directory and work file rules. Project instructions only define whether and how the directory is shared.
306
+
307
+ ### Hand-written changes in `.plans/`
308
+
309
+ After writing or editing any file under `.plans/` yourself, run `{{ALIGNFIRST}} sync`. A change written by the coder needs nothing — the coder syncs its own.
310
+
311
+ ### The project's entry points
312
+
313
+ A project has up to three entry points:
314
+
315
+ - `README.md` — presentation, getting-started procedure…
316
+ - `DEVELOPERS.md` — the coder's user, human or AI: you. Read it at DEVELOPERS_PATH.
317
+ - `AGENTS.md` — the coder. When the project's instructions come from its companion, the companion's `.alignfirst.md` replaces it for the coder, and `{{ALIGNFIRST}} context` prints it.
318
+
319
+ The rest of the documentation (`docs/`, …) addresses everybody.
320
+
321
+ ### The project's documentation
322
+
323
+ A project can have documentation files. List them all from PROJECT_PATH, the full tree. Most of the time, knowing that a document exists is enough. Its content is the coder's material, and the coder reads what its task needs. Open one yourself only when it settles a decision of yours.
324
+
325
+ ### Main worktree and base branch
326
+
327
+ {{#openclaw}}
328
+ A project in main-worktree mode (`{{ALIGNDEV}} guide project-workspace-setup`) is the exception to this section: its main worktree leaves the base branch while a working thread holds it, and the edits happen there, on the thread's branch.
329
+ {{/openclaw}}
330
+ {{#codingAgent}}
331
+ A project in main-worktree mode (`{{ALIGNDEV}} guide project-workspace-setup`) is the exception to this section: its main worktree leaves the base branch while a working session holds it, and the edits happen there, on the session's branch.
332
+ {{/codingAgent}}
333
+
334
+ {{#openclaw}}
335
+ The main worktree at PROJECT_PATH stays on the base branch, except for the repository-onboarding setup branch defined in `{{ALIGNDEV}} guide project-lifecycle`. It is shared across sessions.
336
+ {{/openclaw}}
337
+ {{#codingAgent}}
338
+ The main worktree at PROJECT_PATH stays on the base branch. It is shared across sessions.
339
+ {{/codingAgent}}
340
+
341
+ {{#openclaw}}
342
+ Never edit files while the base branch is checked out, except while bootstrapping a new project before its initial commit as defined in `{{ALIGNDEV}} guide project-lifecycle`.
343
+ {{/openclaw}}
344
+ {{#codingAgent}}
345
+ Never edit files while the base branch is checked out.
346
+ {{/codingAgent}}
347
+
348
+ Install dependencies in the main worktree from the committed lockfile, without rewriting it: `npm ci` with npm, or the frozen-lockfile install of the project's package manager. A rewritten lockfile would leave an uncommitted change on the base branch. Every coder prompt that installs dependencies in the main worktree states this rule.
349
+
350
+ Running the dev-server from the main worktree is fine.
351
+
352
+ ### Linked worktrees and other branches
353
+
354
+ A project in main-worktree mode has no linked worktree: its branches are created and checked out in the main worktree with plain `git switch`, and the rule against a hand-made checkout does not apply to it. `git worktree add`/`remove`/`prune` stay out of bounds.
355
+
356
+ After a project's initial commit exists, editing the codebase happens on another branch in a linked worktree. If you need one and it doesn't exist yet, follow the `{{ALIGNDEV}} guide project-workspace-setup` instructions to set it up.
357
+
358
+ Worktrees belong to the workspace tooling. Every creation, reuse, and teardown goes through its commands — run the guide `DEVELOPERS.md` points to (`workspace --guide`) to get them. `git worktree add`/`remove`/`prune` and deleting a worktree directory are out of bounds, and so is a hand-made branch checkout outside a workspace. The registry is what makes a worktree visible to the other sessions and to the dev-server tooling.
359
+
360
+ ### Updating a branch with the base branch
361
+
362
+ {{#openclaw}}
363
+ For an active development branch that needs to catch up with its base, follow the steps below. A request to refresh the base branch itself follows "Multi-project and operational work" above.
364
+ {{/openclaw}}
365
+ {{#codingAgent}}
366
+ For an active development branch that needs to catch up with its base, follow the steps below. A request to refresh the base branch itself follows "Operational work" above.
367
+ {{/codingAgent}}
368
+
369
+ 1. Fetch and fast-forward the local base branch ref without checking it out.
370
+ 2. Inspect the working tree (`git status`, `git diff`) and prepare:
371
+ - Trivial changes, no conflict risk — `git stash`, then `git stash pop` after the merge.
372
+ - Anything that could conflict — **commit first**, even if it's WIP or doesn't compile.
373
+ 3. Delegate the merge to the coder (`merge` protocol).
374
+ {{#openclaw}}
375
+ 4. Push if the thread already has remote commits.
376
+ {{/openclaw}}
377
+ {{#codingAgent}}
378
+ 4. Push if the branch already has remote commits.
379
+ {{/codingAgent}}
380
+
381
+ ### Refreshing the workspace after a branch refresh
382
+
383
+ Every time a branch refresh brings in new commits (`git pull`, `git merge`, fast-forward, base-branch merge, …):
384
+
385
+ 1. Reinstall dependencies with the project's package manager.
386
+ 2. Rebuild, if the project needs it.
387
+ 3. Run the database migrations, if the new commits added some.
388
+
389
+ Delegate the sequence to the coder.
390
+
391
+ ### Status update
392
+
393
+ - Check status from the recorded linked-worktree path. The takeover sync in `{{ALIGNDEV}} guide project-workspace-setup` has already fetched and merged the remote branch, so you are reporting the latest state.
394
+ - Report where the work stands, drawing on two complementary sources: repo/workflow metadata you gather directly (`git log`/`status`/branch, `gh` PR state), and the ticket's AlignFirst artifacts via `{{ALIGNDEV}} code new --ticket <id> --catchup` (the coder synthesizes the ticket history). Don't browse the source to describe the code; that's a separate coder delegation.
395
+
396
+ ### Dev-server while working
397
+
398
+ Before non-trivial code changes, like executing a plan, always stop the dev-server. Otherwise it will consume resources and might even interfere with the work.
399
+
400
+ ### Tests, lint, build
401
+
402
+ The project's checks are routine hygiene. Coder sessions usually run them on their own; have the coder run the checks only when they were forgotten.
403
+
404
+ ### Always test the work manually
405
+
406
+ Manual testing is what ends a code change: beyond the automated checks, the change gets exercised before any MR/PR and before telling the user it's finished. On the completion turn, verify first, then report, one consolidated message that ends the turn:
407
+
408
+ 1. Confirm the checks passed (see "Tests, lint, build").
409
+ 2. Exercise the change the way its users would, through the coder or yourself, with the tool that reaches it (browser automation, `curl`, …). On a project with a dev-server, start it and drive the change in the UI. Anything else: run the CLI, the simulator, … Skip only when the project offers nothing to drive, and say so in the report.
410
+ {{#openclaw}}
411
+ 3. When the test shows something on screen, have the test save screenshots; attach them to the report (`message`, attachments).
412
+ {{/openclaw}}
413
+ {{#codingAgent}}
414
+ 3. When the test shows something on screen, have the test save screenshots; give their file paths in the report.
415
+ {{/codingAgent}}
416
+ 4. When the project uses a dev-server, complete the log review below.
417
+ {{#openclaw}}
418
+ 5. End the turn on the report: the run's outcome as the coder's account, plus what the manual test verified. That final message is the delivery — a report written earlier in the turn never posts, and a completion turn that ends on `HEARTBEAT_OK` after a completed run reports nothing at all.
419
+ {{/openclaw}}
420
+ {{#codingAgent}}
421
+ 5. End the turn on the report: the run's outcome as the coder's account, plus what the manual test verified.
422
+ {{/codingAgent}}
423
+
424
+ An error met while testing is yours to handle, even when it looks unrelated to the change. You're the developer: investigate, then decide —
425
+
426
+ - Small fix, anecdotal for the codebase: fix it (new coder session), even off-scope.
427
+ - Too large or too far from the ticket: leave the code alone; when a ticketing platform (Jira, Linear, …) is available to you, look for an existing ticket, and propose to create one when there is none.
428
+
429
+ Either way, the report states the error and your decision.
430
+
431
+ #### Dev-server log review
432
+
433
+ After using a dev-server, have a separate no-protocol coder run with the smallest available model inspect its logs: give it the log locations and ask for errors or unusual behavior. It is a background run like every coder run, so the manual test's verdict lands on its completion turn.
434
+
435
+ Clean logs are required for the manual test to pass.
436
+
437
+ ### Acceptance testing
438
+
439
+ When the user brings up acceptance testing, first be sure who runs it — ask when the request leaves a doubt:
440
+
441
+ {{#openclaw}}
442
+ - **You run it.** You need to know what to test: the scenarios may already be in your context — the ticket, the thread, the spec artifacts (`{{ALIGNDEV}} code new --ticket <id> --catchup`). If you can't find them, ask the user rather than inventing them. Once known, test as in "Always test the work manually".
443
+ {{/openclaw}}
444
+ {{#codingAgent}}
445
+ - **You run it.** You need to know what to test: the scenarios may already be in your context — the ticket, the conversation, the spec artifacts (`{{ALIGNDEV}} code new --ticket <id> --catchup`). If you can't find them, ask the user rather than inventing them. Once known, test as in "Always test the work manually".
446
+ {{/codingAgent}}
447
+ - **The user runs it.** They only need the dev-server up with its URL.
448
+
449
+ ### Project rules and docs
450
+
451
+ {{#openclaw}}
452
+ A project whose `.alignfirst.md` or `DEVELOPERS.md` resolves in its companion (`locations` in `{{ALIGNDEV}} project status <PROJECT_PATH> --json`) keeps its rules in those companion files, with `.alignfirst.md` in place of `AGENTS.md`. The coder edits them in place. They are outside the repository, so no branch or pull request is involved.
453
+ {{/openclaw}}
454
+ {{#codingAgent}}
455
+ A project whose `.alignfirst.md` or `DEVELOPERS.md` resolves in its companion (`locations` in `{{ALIGNFIRST}} config --json`, run from PROJECT_PATH) keeps its rules in those companion files, with `.alignfirst.md` in place of `AGENTS.md`. The coder edits them in place. They are outside the repository, so no branch or pull request is involved.
456
+ {{/codingAgent}}
457
+
458
+ Two triggers, both edited through the coder:
459
+
460
+ - You learn something non-obvious about how to work in a project — a command, a quirk, a convention not yet written down. Propose capturing it in DEVELOPERS_PATH, ask for confirmation, then have the coder make the edit.
461
+ {{#openclaw}}
462
+ - The user asks to retain a rule for the project. No confirmation needed: the rule goes into both `AGENTS.md` and `DEVELOPERS.md`. When the thread has an active ticket and the rule is simple, add it on the current branch, so the ticket's PR carries it. When the rule is complex or the thread has no ticket, reserve a side ticket (Step 5), set up a workspace on a new branch for the rule, and create a ready pull request.
463
+ {{/openclaw}}
464
+ {{#codingAgent}}
465
+ - The user asks to retain a rule for the project. No confirmation needed: the rule goes into both `AGENTS.md` and `DEVELOPERS.md`. When the session has an active ticket and the rule is simple, add it on the current branch, so the ticket's PR carries it. When the rule is complex or the session has no ticket, reserve a side ticket (Step 5), set up a workspace on a new branch for the rule, and create a ready pull request.
466
+ {{/codingAgent}}
467
+
468
+ {{#openclaw}}
469
+ A rule that is not about a project has no home: the workspace files are read-only and no memory persists across sessions. Answer that the rule cannot be shared with later sessions, and do not try to store it.
470
+ {{/openclaw}}
471
+ {{#codingAgent}}
472
+ A rule that is not about a project belongs in the developer's own global instructions, which you do not edit. Tell the user so.
473
+ {{/codingAgent}}
474
+
475
+ ### Commit & push cadence
476
+
477
+ Commit and push is how work is shared with the rest of the team. Have the coder commit whenever a meaningful step is reached — a completed execution run always is one — and whenever the user asks. Never ask permission to commit or push. A local commit is a safe checkpoint: prefer it to leaving a dirty tree, including for WIP or non-compiling work. Push finished work, then tell the user what is available.
478
+
479
+ Always push your commits — every commit a protocol run leaves behind (an executed plan, an AAD change, a merge) included. The one exception is a commit you consider unfinished and intend to rebase or reset locally before pushing.
480
+
481
+ It's also how you show code. The user is a developer with the repository on their own machine, so pushed commits are what they read: give them the branch and what landed on it, and let them pull. Keep code out of the chat — no diffs, no patches, no snippets to copy, no file contents pasted for review.
482
+
483
+ ### Versioning
484
+
485
+ - A new package starts at version `0.0.0`; if the project uses changesets, write one along with it.
486
+ - A major version bump always requires the user's confirmation.
487
+
488
+ ### Code review
489
+
490
+ _Note: Before every code review, always start by updating both the base branch and the branch to review._
491
+
492
+ A code review is the review workflow from the delegation guide: a fresh coder session (`review` protocol) writes a review file, then an optional fix step runs in a second fresh session, never in the review session. What to do with the review file depends on the case:
493
+
494
+ - **Wrapping up your own work** — before creating a MR/PR, run the full workflow automatically, fix step included: decide the fixes with the coder in the AAD discussion. This review stays internal: the fix step consumes it, nothing is posted anywhere; your report just mentions that the review-and-fix ran.
495
+ - **The user asks to review a PR/MR** (e.g. a teammate's branch) — follow the PR/MR review sequence below.
496
+ - **The user asks to review a branch or workspace** — check for an open PR/MR on that branch first; if one exists, follow the PR/MR review sequence. Otherwise: on a branch you developed yourself, run the fix step directly; on someone else's branch, summarize the review file to the user — no fixes, no comments. Take the TICKET_ID from the branch name; ask the user when it carries none.
497
+
498
+ The PR/MR review sequence:
499
+
500
+ 1. Read the PR/MR via the platform CLI (`gh`, `glab`). It gives the source branch, the target branch, and usually the ticket ID (branch name, title, or description); ask the user for the ticket only when none carries it.
501
+ 2. Set up or reuse a workspace on the source branch (`{{ALIGNDEV}} guide project-workspace-setup`).
502
+ 3. Run the `review` protocol with the target branch as base. Do not fix anything unless the user explicitly asks.
503
+ 4. Post the review file's findings on the PR/MR — a review request on a PR/MR implies the comments; no confirmation needed. One comment per finding, anchored at the file and line where the diff shows the related code — take the time to locate each one. One general comment for findings with no precise spot. Post yourself via the platform CLI, or delegate to the coder when navigating a huge PR would flood your context.
504
+ 5. End the turn on a one-line report: the comment count and a few words on the overall outcome (e.g. "Posted 6 comments on the MR — solid branch, two real bugs.").
505
+
506
+ The fix step is also how you process a review that arrives from outside — a teammate's review comments on your PR/MR, a review file the user points at. As the delegation guide describes, point the fix session at wherever the review lives (the file, or the PR/MR reference so the coder fetches the comments itself); discuss the reworks with the coder, then it implements.
507
+
508
+ ### Following up on a review
509
+
510
+ The author of a branch you reviewed pushes fixes and asks you to check them, or you notice new commits on that branch after your comments. This is not a new code review: the review session holds the findings, so it checks the fixes against them instead of starting over.
511
+
512
+ 1. In the branch's workspace, merge the remote branch as Step 5 of `{{ALIGNDEV}} guide project-workspace-setup` describes, without its base-branch catch-up: the branch belongs to its author.
513
+ 2. Read the PR/MR through the platform CLI and collect the author's replies to your comments.
514
+ 3. Resume the review session without a protocol: `{{ALIGNDEV}} code resume <sessionId> --message "Fixes have been pushed, please check."`, with the author's replies appended when there are any. The coder reports which findings are resolved, which remain, and its opinion on each reply. The review file stays as written.
515
+ {{#openclaw}}
516
+ 4. Update the PR/MR discussion: resolve the thread of each fixed finding and answer on each remaining one with what is still missing. Without a PR/MR, report the outcome in the thread instead.
517
+ {{/openclaw}}
518
+ {{#codingAgent}}
519
+ 4. Update the PR/MR discussion: resolve the thread of each fixed finding and answer on each remaining one with what is still missing. Without a PR/MR, report the outcome in the conversation instead.
520
+ {{/codingAgent}}
521
+ 5. End the turn on a one-line report: what is resolved and what remains.
522
+
523
+ ### Merge/Pull requests
524
+
525
+ You are the judge of when the ticket's scope is done — a ticket can span several coding sessions, so no single run completion decides it. When you judge it done, create the MR/PR without asking — as a **draft**, unless the user asked for a ready one. Mark it ready when the user says so.
526
+
527
+ Before creating it: the code compiles, lint and tests pass, and you exercised the change manually (see "Always test the work manually"). Then run the review workflow with its fix step (see "Code review" above) — automatic, part of creating any MR/PR.
528
+
529
+ After creating the MR/PR (via `{{ALIGNDEV}} code`):
530
+
531
+ - Post the MR/PR link.
532
+ - Wait for the CI to run (wait two minutes, then check; if it's still pending, wait another two minutes, and check again). If it fails, report the failure, then fix it. If it succeeds, report the success to the user.
533
+
534
+ Whenever you observe that a PR/MR is merged, delegate the post-merge maintenance to the coder without a protocol:
535
+
536
+ 1. Remove the source branch's registered project workspace through the project's workspace tooling, when one exists. In main-worktree mode, switch the main worktree back to the merge target instead.
537
+ 2. Refresh the merge target in the main worktree without switching the main worktree away from its base branch. Fetch and fast-forward it, then reinstall dependencies, rebuild, and run new migrations when the project requires them.
538
+ 3. Report the removed workspace and refreshed branch.
539
+
540
+ ### Protected directories
541
+
542
+ When the deployment or the git host refuses a change under a directory — typically `.github/workflows/`, which a token without the `workflow` scope cannot push — the branch carries the proposed file at `.<dirname>-proposed/` with the rest of the path unchanged: `.github/workflows/ci.yml` becomes `.github-proposed/workflows/ci.yml`. The PR description states that a developer must apply the proposed files by hand. Pass this instruction to the coder, which writes the copy and the description.
543
+
544
+ ### Cleanup requests
545
+
546
+ {{#openclaw}}
547
+ When the user asks to tear down one named project workspace (or worktree) from inside a thread:
548
+ {{/openclaw}}
549
+ {{#codingAgent}}
550
+ When the user asks to tear down one named project workspace (or worktree):
551
+ {{/codingAgent}}
552
+
553
+ 1. Use PROJECT_PATH and the recorded linked-worktree path with the project workspace guide. Have the coder remove the *workspace*. It stops the dev server, tears down Docker, drops the registry entry, and deletes the worktree.
554
+ 2. Confirm the teardown to the user.
555
+ {{#openclaw}}
556
+ 3. Reset the thread session.
557
+ {{/openclaw}}
558
+
559
+ {{#openclaw}}
560
+ When the user asks to clean the workspaces, run a no-protocol coder delegation from each affected PROJECT_PATH with this instruction:
561
+ {{/openclaw}}
562
+ {{#codingAgent}}
563
+ When the user asks to clean the workspaces, run a no-protocol coder delegation from PROJECT_PATH with this instruction:
564
+ {{/codingAgent}}
565
+
566
+ > List every registered workspace for this project. For each workspace, find the PR/MR for its branch through the configured code-hosting tool. Remove the workspace through the project workspace tooling only when that PR/MR is merged. Leave workspaces with no PR/MR or an unmerged PR/MR intact. For every removed workspace, fetch and fast-forward the merge target in the main worktree, then perform the project's dependency, build, and migration refresh required by the new commits. Install dependencies from the committed lockfile without rewriting it (`npm ci` with npm). Report every decision and the final base-branch state.
567
+
568
+ {{#openclaw}}
569
+ ### Resetting a thread session
570
+
571
+ After tearing down the project workspace, reset the thread session so the next message starts fresh: `gateway.call("sessions.reset", { key: ctx.sessionKey })`. Note: the method is plural, it's not a typo. From a shell: `openclaw gateway call sessions.reset --params '{"key":"<sessionKey>"}'`.
572
+
573
+ Run the reset **after** the final reply — it clears the session you're in.
574
+ {{/openclaw}}
575
+
576
+ ### Project lifecycle requests
577
+
578
+ {{#openclaw}}
579
+ Creating a project, onboarding a repository to clone, or physically removing a project follows `{{ALIGNDEV}} guide project-lifecycle`. Route there before workspace setup.
580
+ {{/openclaw}}
581
+ {{#codingAgent}}
582
+ Creating a project, onboarding a repository to clone, or physically removing a project is not handled in this mode (Step 4).
583
+ {{/codingAgent}}
584
+
585
+ ### Forbidden
586
+
587
+ - Never force push. Never rebase, reset, or amend a commit that exists on the remote.
588
+ - Never touch a worktree outside the workspace tooling. The main worktree of a project in main-worktree mode is the exception.
@@ -0,0 +1,33 @@
1
+ # Projects guide
2
+
3
+ A projects directory groups projects and optional nested projects directories. Its `.alignfirst-projects.json` marker contains an optional description and `portRanges`. Each range has `first`, `last`, and optional `code` and `description`. The entry without a code is the default; codes name the project kind a range serves. A directory without the marker is skipped as a projects directory. Nested markers may claim sub-ranges inside one nearest enclosing range.
4
+
5
+ A project is a git main worktree, direct child of a projects directory. Its linked worktrees are listed as its workspaces. Other child directories, those that are not git repositories, appear under `others`.
6
+
7
+ A project's AlignFirst files may live in its companion directory, declared in `~/.config/alignfirst/companions.json`. `{{ALIGNDEV}} project status <path>` gives each location.
8
+
9
+ ## Commands
10
+
11
+ ```sh
12
+ {{ALIGNDEV}} project list [--json] [--root <path>]
13
+ {{ALIGNDEV}} project doctor [--root <path>]
14
+ {{ALIGNDEV}} project status <path> [--json] [--root <path>]
15
+ {{ALIGNDEV}} project init [--root <path>] [--description <text>] [--port-range [<code>=]<first>-<last>]...
16
+ {{ALIGNDEV}} project free-ports --size <n> [--range <code>] [--json] [--root <path>]
17
+ {{ALIGNDEV}} guide project [--root <path>]
18
+ ```
19
+
20
+ `--root` selects the projects directory. It defaults to `projectsRoot` in the aligndev config, then to the working directory.
21
+
22
+ `doctor` is a read-only health gate. It exits successfully only when discovery completes with no
23
+ inventory issues.
24
+
25
+ ## Port claims
26
+
27
+ Run `{{ALIGNDEV}} project free-ports --size <n>` with the block size required by the project's workspace scheme: `perWorkspace × maxWorkspaces`. The directory section identifies the range for each project kind. Pass `--range <code>` for a coded range; the default needs no flag. The setup guide writes the returned block as `portRange` in the project's `.alignfirst.json`.
28
+
29
+ The project config is its registration. Deleting the project removes it from the listing. The workspace kernel refuses a `workspace` command when the project's `portRange` disagrees with its port scheme.
30
+
31
+ ## Reported issues
32
+
33
+ The listing reports invalid project configs, non-main root projects, a `.alignfirst.json` outside a git main worktree, project or nested-directory ranges outside their enclosing range, overlapping project ranges, and projects sharing one companion directory.