aligndev 0.20.2 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -4
- package/dist/cli.js +1 -1
- package/dist/code/code-cli.js +2 -2
- package/dist/guide/code-guide.js +1 -1
- package/dist/guide/guide-cli.js +11 -6
- package/dist/guide/guide-file.d.ts +3 -0
- package/dist/guide/guide-file.js +26 -0
- package/dist/guide/render-template.d.ts +9 -2
- package/dist/guide/render-template.js +53 -26
- package/dist/project/guide.js +1 -1
- package/dist/project/layout.d.ts +1 -1
- package/dist/project/layout.js +2 -2
- package/dist/project/project-cli.js +2 -1
- package/dist/project/status.d.ts +1 -1
- package/dist/project/status.js +4 -5
- package/package.json +3 -3
- package/templates/guide/playbook/channel-handling.md +1 -1
- package/templates/guide/playbook/consultation.md +25 -1
- package/templates/guide/playbook/playbook.md +12 -3
- package/templates/guide/playbook/project-lifecycle.md +6 -5
- package/templates/guide/playbook/project-workspace-setup.md +62 -15
- package/templates/guide/playbook/working-session.md +73 -17
package/README.md
CHANGED
|
@@ -2,15 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
Autonomous software development. You say what you want; the assistant drives the coding agents and brings you the decisions.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
See the [product page](https://alignfirst.paroi.tech/aligndev) for an overview.
|
|
6
|
+
|
|
7
|
+
You talk to an **assistant**, the way you would to a developer on your team. It never touches the code itself. It isolates each task in its own workspace, then hands the investigation and the coding to an AI coding agent, **the agent**, which follows the AlignFirst protocols: specify, plan, implement. The assistant reads the agent's work, tests it, asks you what only you can decide, and opens the pull request.
|
|
6
8
|
|
|
7
9
|
`aligndev` is the assistant's CLI. It gives the assistant its playbook, launches and tracks the agent, and keeps the inventory of your projects. You never run it yourself: the assistant does.
|
|
8
10
|
|
|
11
|
+
## The Assistant's Workflow
|
|
12
|
+
|
|
13
|
+
For each task, the assistant:
|
|
14
|
+
|
|
15
|
+
1. Discusses the task with the agent and has it write a **spec**.
|
|
16
|
+
2. Has it write the **plans**.
|
|
17
|
+
3. Has the plans **executed** in a fresh session.
|
|
18
|
+
4. Has a **code review** done in another session.
|
|
19
|
+
5. Has the review findings **fixed** in yet another session.
|
|
20
|
+
6. For UI changes, **tests manually** and checks the dev-server logs.
|
|
21
|
+
7. Has fixes made as needed.
|
|
22
|
+
8. Takes **screenshots** for good measure.
|
|
23
|
+
9. Has the agent **open a draft PR**.
|
|
24
|
+
|
|
25
|
+
A task can also start at any intermediate step.
|
|
26
|
+
|
|
9
27
|
## Two Ways to Run the Assistant
|
|
10
28
|
|
|
11
29
|
**In your coding agent.** A Claude Code or Codex session becomes the assistant of the repository it starts in. You keep chatting in the same session; the agents it launches work in the background.
|
|
12
30
|
|
|
13
|
-
**As an OpenClaw bot.**
|
|
31
|
+
**As an OpenClaw bot.** [AlignDev for OpenClaw](#start-as-an-openclaw-bot) deploys the assistant on a server, under its own name in Slack or Discord. It works on every project of the host, one thread per task.
|
|
14
32
|
|
|
15
33
|
Either way, the agent is Claude Code or Codex. A coding-agent assistant launches its own kind by default.
|
|
16
34
|
|
|
@@ -35,7 +53,7 @@ Then start a session in the project and invoke `/aligndev` in Claude Code, or `$
|
|
|
35
53
|
Add this section to your global agent instructions (`~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, or the equivalent):
|
|
36
54
|
|
|
37
55
|
```markdown
|
|
38
|
-
##
|
|
56
|
+
## AlignDev
|
|
39
57
|
|
|
40
58
|
When the user mentions **aligndev**, follow the `aligndev` playbook if it is already in context. Otherwise, run `npx -y aligndev guide` and follow it.
|
|
41
59
|
```
|
|
@@ -67,6 +85,25 @@ Then ask your session to work with aligndev.
|
|
|
67
85
|
|
|
68
86
|
Unknown keys and invalid values are errors.
|
|
69
87
|
|
|
88
|
+
## Start as an OpenClaw Bot
|
|
89
|
+
|
|
90
|
+
AlignDev for OpenClaw runs the assistant as an OpenClaw bot. One deployment is a dedicated service account running the assistant under its own name and channel identity. The communication surface, the agent and the assistant's model provider are independent choices. Each task moves from a channel into its own thread, then into an isolated project workspace.
|
|
91
|
+
|
|
92
|
+
```mermaid
|
|
93
|
+
flowchart TD
|
|
94
|
+
U([User]) -->|Slack or Discord| O[OpenClaw]
|
|
95
|
+
O -->|aligndev guide and aligndev code| CA[Claude Code or Codex]
|
|
96
|
+
CA -->|AlignFirst protocols| FS[(Managed project)]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Install the setup skill where your agent will assemble the deployment's private administration repository:
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
npx -y skills add https://github.com/paleo/alignfirst --global --skill alignfirst-setup-guide
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then ask the agent to create an assistant. The skill collects the deployment values, renders one Slack or Discord variant and one Claude Code or Codex variant, and writes the installation, security, operation and recovery runbooks. Each managed project receives the full preparation contract: the AlignFirst bootstrap line, an optional work-files repository, docmap, isolated workspaces and a project-specific `DEVELOPERS.md`.
|
|
106
|
+
|
|
70
107
|
## Under the Hood
|
|
71
108
|
|
|
72
|
-
`aligndev` documents itself for the assistant: `aligndev --help`, then `aligndev guide`, print everything it needs. Maintainers: see [aligndev Architecture](https://github.com/paleo/alignfirst/blob/main/docs/aligndev-architecture.md).
|
|
109
|
+
`aligndev` documents itself for the assistant: `aligndev --help`, then `aligndev guide`, print everything it needs. Maintainers: see [aligndev Architecture](https://github.com/paleo/alignfirst/blob/main/docs/aligndev-architecture.md) and the [AlignDev for OpenClaw map](https://github.com/paleo/alignfirst/blob/main/docs/aligndev-openclaw/aligndev-openclaw.md).
|
package/dist/cli.js
CHANGED
package/dist/code/code-cli.js
CHANGED
|
@@ -26,7 +26,7 @@ const SESSION_OPTIONS = {
|
|
|
26
26
|
// Items whose companion copy the agent may edit: the companion becomes a writable directory.
|
|
27
27
|
const WRITABLE_COMPANION_ITEMS = [
|
|
28
28
|
".alignfirst.json",
|
|
29
|
-
".alignfirst
|
|
29
|
+
".alignfirst-instructions",
|
|
30
30
|
"DEVELOPERS.md",
|
|
31
31
|
"docs",
|
|
32
32
|
".plans",
|
|
@@ -34,7 +34,7 @@ const WRITABLE_COMPANION_ITEMS = [
|
|
|
34
34
|
// Items the agent would not find in the repository: a new session gets `alignfirst context`.
|
|
35
35
|
const CONTEXT_COMPANION_ITEMS = [
|
|
36
36
|
".alignfirst.json",
|
|
37
|
-
".alignfirst
|
|
37
|
+
".alignfirst-instructions",
|
|
38
38
|
"docs",
|
|
39
39
|
".plans",
|
|
40
40
|
];
|
package/dist/guide/code-guide.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { renderGuideTemplate } from "./render-template.js";
|
|
2
2
|
export function renderCodeGuide(platform, agent, models, forms) {
|
|
3
|
-
return renderGuideTemplate("code.md", platform, forms, {
|
|
3
|
+
return renderGuideTemplate("code.md", { platform }, forms, {
|
|
4
4
|
AGENT: agent,
|
|
5
5
|
AUTH_COMMAND: agent === "claude" ? "`claude`, then `/login`" : "`codex login`",
|
|
6
6
|
PERMISSIONS: agent === "claude"
|
package/dist/guide/guide-cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import { PLATFORMS, requireProjectsRoot, resolveCodeConfig, } from "../config.js
|
|
|
4
4
|
import { errorMessage } from "../errors.js";
|
|
5
5
|
import { renderProjectsGuideForRoot } from "../project/project-cli.js";
|
|
6
6
|
import { renderCodeGuide } from "./code-guide.js";
|
|
7
|
+
import { resolveGuideFile } from "./guide-file.js";
|
|
7
8
|
import { renderGuideTemplate } from "./render-template.js";
|
|
8
9
|
import { PLAYBOOK_DISPATCHER, PLAYBOOK_TOPICS } from "./topics.js";
|
|
9
10
|
export function runGuide(tokens, config, ctx) {
|
|
@@ -57,20 +58,24 @@ function renderTopic(args, config, ctx) {
|
|
|
57
58
|
if (args.topic === "project" && config.platform === "openclaw") {
|
|
58
59
|
return renderProjectsGuideForRoot({ ...ctx, projectsRoot: config.projectsRoot }, args.root);
|
|
59
60
|
}
|
|
60
|
-
return renderPlaybookTopic(args.topic, config, ctx
|
|
61
|
+
return renderPlaybookTopic(args.topic, config, ctx);
|
|
61
62
|
}
|
|
62
63
|
function renderCodeTopic(config, ctx) {
|
|
63
64
|
const code = resolveCodeConfig(config, ctx.env);
|
|
64
65
|
const models = resolveModels(code.agent, code.models);
|
|
65
66
|
return renderCodeGuide(config.platform, code.agent, models, ctx.forms);
|
|
66
67
|
}
|
|
67
|
-
function renderPlaybookTopic(topic, config,
|
|
68
|
+
function renderPlaybookTopic(topic, config, ctx) {
|
|
68
69
|
if (topic !== undefined)
|
|
69
70
|
assertPlaybookTopic(topic, config.platform);
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
:
|
|
73
|
-
|
|
71
|
+
const name = `playbook/${topic ?? PLAYBOOK_DISPATCHER}.md`;
|
|
72
|
+
if (config.platform === "codingAgent") {
|
|
73
|
+
const active = { platform: config.platform, guideFile: resolveGuideFile(ctx) };
|
|
74
|
+
return renderGuideTemplate(name, active, ctx.forms);
|
|
75
|
+
}
|
|
76
|
+
return renderGuideTemplate(name, { platform: config.platform }, ctx.forms, {
|
|
77
|
+
PROJECTS_ROOT: requireProjectsRoot(config).written,
|
|
78
|
+
});
|
|
74
79
|
}
|
|
75
80
|
function assertPlaybookTopic(topic, platform) {
|
|
76
81
|
const topics = PLAYBOOK_TOPICS[platform];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { readProjectReport } from "../project/layout.js";
|
|
5
|
+
// The project's guide file for the coding-agent assistant, resolved from PROJECT_PATH, the main
|
|
6
|
+
// worktree of the working directory: its `DEVELOPERS.md`, else its `README.md`, else none.
|
|
7
|
+
export function resolveGuideFile(ctx) {
|
|
8
|
+
const projectPath = mainWorktree(ctx);
|
|
9
|
+
if (projectPath === undefined)
|
|
10
|
+
return "noGuide";
|
|
11
|
+
const report = readProjectReport(ctx.alignfirstCommand, projectPath, ctx.env);
|
|
12
|
+
if ("error" in report)
|
|
13
|
+
throw new Error(report.error);
|
|
14
|
+
if (report.locations["DEVELOPERS.md"].exists)
|
|
15
|
+
return "developers";
|
|
16
|
+
return existsSync(join(projectPath, "README.md")) ? "readme" : "noGuide";
|
|
17
|
+
}
|
|
18
|
+
function mainWorktree(ctx) {
|
|
19
|
+
try {
|
|
20
|
+
const commonDir = execFileSync("git", ["-C", ctx.cwd, "rev-parse", "--path-format=absolute", "--git-common-dir"], { encoding: "utf8", env: ctx.env, stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
21
|
+
return dirname(commonDir);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { CommandForms } from "../command-form.js";
|
|
2
2
|
import { type Platform } from "../config.js";
|
|
3
|
-
|
|
4
|
-
export
|
|
3
|
+
declare const GUIDE_FILE_CONDITIONS: readonly ["developers", "readme", "noGuide"];
|
|
4
|
+
export type GuideFileCondition = (typeof GUIDE_FILE_CONDITIONS)[number];
|
|
5
|
+
export interface ActiveBlocks {
|
|
6
|
+
platform: Platform;
|
|
7
|
+
guideFile?: GuideFileCondition;
|
|
8
|
+
}
|
|
9
|
+
export declare function renderGuideTemplate(name: string, active: ActiveBlocks, forms: CommandForms, values?: Readonly<Record<string, string>>): string;
|
|
10
|
+
export declare function renderBlocks(text: string, active: ActiveBlocks, templateName: string): string;
|
|
11
|
+
export {};
|
|
@@ -1,59 +1,86 @@
|
|
|
1
1
|
import { PLATFORMS } from "../config.js";
|
|
2
2
|
import { readTemplate } from "../templates.js";
|
|
3
|
+
const GUIDE_FILE_CONDITIONS = ["developers", "readme", "noGuide"];
|
|
4
|
+
// Active for both guide files: `developers` and `readme`.
|
|
5
|
+
const HAS_GUIDE = "hasGuide";
|
|
3
6
|
const MARKER = /^\{\{([#/])([A-Za-z]+)\}\}$/;
|
|
4
|
-
// Renders `templates/guide/<name>`: the
|
|
5
|
-
//
|
|
6
|
-
export function renderGuideTemplate(name,
|
|
7
|
+
// Renders `templates/guide/<name>`: the blocks first, then the placeholders — the command forms
|
|
8
|
+
// and every key of `values`.
|
|
9
|
+
export function renderGuideTemplate(name, active, forms, values = {}) {
|
|
7
10
|
const placeholders = {
|
|
8
11
|
ALIGNDEV: forms.aligndev,
|
|
9
12
|
ALIGNFIRST: forms.alignfirst,
|
|
10
13
|
...values,
|
|
11
14
|
};
|
|
12
|
-
let text =
|
|
15
|
+
let text = renderBlocks(readTemplate(`guide/${name}`), active, name);
|
|
13
16
|
for (const [key, value] of Object.entries(placeholders)) {
|
|
14
17
|
text = text.replaceAll(`{{${key}}}`, value);
|
|
15
18
|
}
|
|
16
19
|
return text.trimEnd();
|
|
17
20
|
}
|
|
18
|
-
// A block is `{{#<
|
|
19
|
-
//
|
|
20
|
-
// empty lines that removed blocks leave
|
|
21
|
-
|
|
21
|
+
// A block is `{{#<name>}}` … `{{/<name>}}`, each marker alone on its line. A platform block sits
|
|
22
|
+
// at the top level; a condition block sits directly inside a `codingAgent` block. A line
|
|
23
|
+
// is kept when every block around it is active. The runs of empty lines that removed blocks leave
|
|
24
|
+
// collapse to one.
|
|
25
|
+
export function renderBlocks(text, active, templateName) {
|
|
22
26
|
const kept = [];
|
|
23
|
-
|
|
27
|
+
const open = [];
|
|
24
28
|
for (const [index, line] of text.split("\n").entries()) {
|
|
25
29
|
const marker = MARKER.exec(line);
|
|
26
30
|
if (marker === null) {
|
|
27
|
-
if (open
|
|
31
|
+
if (open.every((block) => isActive(block.name, active)))
|
|
28
32
|
kept.push(line);
|
|
29
33
|
continue;
|
|
30
34
|
}
|
|
31
35
|
const [, kind, name] = marker;
|
|
32
36
|
const lineNumber = index + 1;
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
if (kind === "#")
|
|
38
|
+
open.push(openBlock(name, lineNumber, open, templateName));
|
|
39
|
+
else
|
|
40
|
+
closeBlock(name, lineNumber, open, templateName);
|
|
41
|
+
}
|
|
42
|
+
const unclosed = open.at(-1);
|
|
43
|
+
if (unclosed !== undefined) {
|
|
44
|
+
throw blockError(templateName, unclosed.line, `block "${unclosed.name}" is not closed`);
|
|
45
|
+
}
|
|
46
|
+
return collapseEmptyLines(kept).join("\n");
|
|
47
|
+
}
|
|
48
|
+
function isActive(name, active) {
|
|
49
|
+
if (name === HAS_GUIDE)
|
|
50
|
+
return active.guideFile === "developers" || active.guideFile === "readme";
|
|
51
|
+
return name === active.platform || name === active.guideFile;
|
|
52
|
+
}
|
|
53
|
+
function openBlock(name, line, open, templateName) {
|
|
54
|
+
const outer = open.at(-1);
|
|
55
|
+
if (isPlatform(name)) {
|
|
56
|
+
if (outer !== undefined) {
|
|
57
|
+
throw blockError(templateName, line, `platform block "${name}" inside "${outer.name}"`);
|
|
41
58
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
return { name, line };
|
|
60
|
+
}
|
|
61
|
+
if (isCondition(name)) {
|
|
62
|
+
if (outer?.name !== "codingAgent") {
|
|
63
|
+
throw blockError(templateName, line, `condition block "${name}" outside a codingAgent block`);
|
|
47
64
|
}
|
|
65
|
+
return { name, line };
|
|
48
66
|
}
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
throw blockError(templateName, line, `unknown block "${name}"`);
|
|
68
|
+
}
|
|
69
|
+
function closeBlock(name, line, open, templateName) {
|
|
70
|
+
if (!isPlatform(name) && !isCondition(name)) {
|
|
71
|
+
throw blockError(templateName, line, `unknown block "${name}"`);
|
|
51
72
|
}
|
|
52
|
-
|
|
73
|
+
if (open.at(-1)?.name !== name) {
|
|
74
|
+
throw blockError(templateName, line, `closing marker "${name}" without its block`);
|
|
75
|
+
}
|
|
76
|
+
open.pop();
|
|
53
77
|
}
|
|
54
78
|
function isPlatform(name) {
|
|
55
79
|
return PLATFORMS.includes(name);
|
|
56
80
|
}
|
|
81
|
+
function isCondition(name) {
|
|
82
|
+
return name === HAS_GUIDE || GUIDE_FILE_CONDITIONS.includes(name);
|
|
83
|
+
}
|
|
57
84
|
function blockError(templateName, line, detail) {
|
|
58
85
|
return new Error(`Error: template ${templateName}, line ${line}: ${detail}.`);
|
|
59
86
|
}
|
package/dist/project/guide.js
CHANGED
|
@@ -3,7 +3,7 @@ import { renderGuideTemplate } from "../guide/render-template.js";
|
|
|
3
3
|
import { escapeAdditionalJsonCharacters, formatRange } from "./format.js";
|
|
4
4
|
// The projects guide serves the OpenClaw playbook only.
|
|
5
5
|
export function renderProjectsGuide(forms, inventory) {
|
|
6
|
-
const guide = renderGuideTemplate("project.md", "openclaw", forms);
|
|
6
|
+
const guide = renderGuideTemplate("project.md", { platform: "openclaw" }, forms);
|
|
7
7
|
if (inventory === undefined)
|
|
8
8
|
return guide;
|
|
9
9
|
const sections = inventory.directories.map((directory) => renderDirectory(inventory, directory));
|
package/dist/project/layout.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PortRange } from "./markers.js";
|
|
2
|
-
export type ItemName = ".alignfirst.json" | ".alignfirst
|
|
2
|
+
export type ItemName = ".alignfirst.json" | ".alignfirst-instructions" | "DEVELOPERS.md" | "docs" | ".plans" | "_aligndev";
|
|
3
3
|
export interface ProjectReport {
|
|
4
4
|
source: ConfigSource | null;
|
|
5
5
|
cli: ProjectCliReport | null;
|
package/dist/project/layout.js
CHANGED
|
@@ -75,7 +75,7 @@ function parsePlans(value, path) {
|
|
|
75
75
|
throw invalidReport(path);
|
|
76
76
|
return value.folder === undefined ? {} : { folder: value.folder };
|
|
77
77
|
}
|
|
78
|
-
// The report's other companion fields (`
|
|
78
|
+
// The report's other companion fields (`key`, `flags`) are alignfirst's concern.
|
|
79
79
|
function parseCompanion(value, path) {
|
|
80
80
|
if (value === null)
|
|
81
81
|
return null;
|
|
@@ -90,7 +90,7 @@ function parseLocations(value, path) {
|
|
|
90
90
|
const location = (name) => parseLocation(value[name], path);
|
|
91
91
|
return {
|
|
92
92
|
".alignfirst.json": location(".alignfirst.json"),
|
|
93
|
-
".alignfirst
|
|
93
|
+
".alignfirst-instructions": location(".alignfirst-instructions"),
|
|
94
94
|
"DEVELOPERS.md": location("DEVELOPERS.md"),
|
|
95
95
|
docs: location("docs"),
|
|
96
96
|
".plans": location(".plans"),
|
|
@@ -36,7 +36,7 @@ function runProjectCommand(ctx, args) {
|
|
|
36
36
|
return 0;
|
|
37
37
|
}
|
|
38
38
|
if (args.command === "status" && args.path !== undefined) {
|
|
39
|
-
const details = getProjectStatus(inventory, args.path);
|
|
39
|
+
const details = getProjectStatus(inventory, resolve(ctx.cwd, args.path));
|
|
40
40
|
ctx.stdout.write(args.json ? renderProjectStatusJson(details) : renderProjectStatus(details));
|
|
41
41
|
return 0;
|
|
42
42
|
}
|
|
@@ -57,6 +57,7 @@ function renderUsage(aligndev) {
|
|
|
57
57
|
${aligndev} project --help
|
|
58
58
|
|
|
59
59
|
--root defaults to projectsRoot in the aligndev config, then to the working directory.
|
|
60
|
+
A relative status <path> starts from the working directory.
|
|
60
61
|
`;
|
|
61
62
|
}
|
|
62
63
|
// The projects guide, followed by the directory sections when the root carries a marker.
|
package/dist/project/status.d.ts
CHANGED
|
@@ -21,4 +21,4 @@ export interface ProjectWorktree {
|
|
|
21
21
|
name: string;
|
|
22
22
|
path: string;
|
|
23
23
|
}
|
|
24
|
-
export declare function getProjectStatus(inventory: ProjectInventory,
|
|
24
|
+
export declare function getProjectStatus(inventory: ProjectInventory, projectPath: string): ProjectDetails;
|
package/dist/project/status.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
2
|
import { realpathSync } from "node:fs";
|
|
3
|
-
import { basename
|
|
3
|
+
import { basename } from "node:path";
|
|
4
4
|
import { errorMessage, isNodeError } from "../errors.js";
|
|
5
5
|
const URL_WITH_AUTHORITY = /^[A-Za-z][A-Za-z\d+.-]*:\/\//u;
|
|
6
|
-
export function getProjectStatus(inventory,
|
|
7
|
-
const path =
|
|
6
|
+
export function getProjectStatus(inventory, projectPath) {
|
|
7
|
+
const path = realPathOrSelf(projectPath);
|
|
8
8
|
const project = inventory.projects.find((candidate) => candidate.path === path);
|
|
9
9
|
if (project === undefined) {
|
|
10
10
|
throw new Error(`${path} is not a project of ${inventory.root}. Pass the main-worktree path of a git ` +
|
|
@@ -12,8 +12,7 @@ export function getProjectStatus(inventory, inputPath) {
|
|
|
12
12
|
}
|
|
13
13
|
return buildProjectDetails(project);
|
|
14
14
|
}
|
|
15
|
-
function
|
|
16
|
-
const path = isAbsolute(inputPath) ? inputPath : resolve(root, inputPath);
|
|
15
|
+
function realPathOrSelf(path) {
|
|
17
16
|
try {
|
|
18
17
|
return realpathSync(path);
|
|
19
18
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aligndev",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"license": "CC0-1.0",
|
|
5
5
|
"author": "Thomas MUR",
|
|
6
|
-
"description": "The
|
|
6
|
+
"description": "The AlignDev CLI: the assistant's playbook, coding-agent delegation, and project inventory.",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"ai",
|
|
9
9
|
"agent",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"projects",
|
|
16
16
|
"worktrees"
|
|
17
17
|
],
|
|
18
|
-
"homepage": "https://alignfirst.paroi.tech/
|
|
18
|
+
"homepage": "https://alignfirst.paroi.tech/aligndev",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
21
|
"url": "git+https://github.com/paleo/alignfirst.git",
|
|
@@ -62,7 +62,7 @@ A value the user did not supply and the lookup did not resolve stays missing. St
|
|
|
62
62
|
- `threadName`: the name above
|
|
63
63
|
- `channel`: `<channel>`
|
|
64
64
|
|
|
65
|
-
The tool returns the thread's `chat_id` — that is the THREAD_ID. Post the Step 3 starter into the thread: call `message` with `action: "thread-reply"`, `threadId` set to the bare THREAD_ID, `message` set to the starter, and `channel` set to the current surface. Pass no `target`.
|
|
65
|
+
Pass no `message`: content on `thread-create` would post ahead of the starter. The tool returns the thread's `chat_id` — that is the THREAD_ID. Post the Step 3 starter into the thread: call `message` with `action: "thread-reply"`, `threadId` set to the bare THREAD_ID, `message` set to the starter, and `channel` set to the current surface. Pass no `target`.
|
|
66
66
|
|
|
67
67
|
**Slack** — Slack threads have no name. Call `message` with `action: "send"`, `target` set to the raw current `chat_id`, `threadId` set to the triggering message timestamp, `message` set to the Step 3 starter, and `channel` set to the current surface. The bare root timestamp is the THREAD_ID. Slack has no `thread-create`, `thread-reply`, or rename action.
|
|
68
68
|
|
|
@@ -12,16 +12,22 @@ The user consults you, and you consult the agent. It reads the repository; you w
|
|
|
12
12
|
Run `{{ALIGNDEV}} project status <PROJECT_PATH>` and retain its `DEVELOPERS.md` path as DEVELOPERS_PATH. Read DEVELOPERS_PATH and run `{{ALIGNFIRST}} context` from PROJECT_PATH.
|
|
13
13
|
{{/openclaw}}
|
|
14
14
|
{{#codingAgent}}
|
|
15
|
+
{{#hasGuide}}
|
|
15
16
|
Read DEVELOPERS_PATH, retained by Step 1 of `{{ALIGNDEV}} guide working-session`, and run `{{ALIGNFIRST}} context` from PROJECT_PATH.
|
|
17
|
+
{{/hasGuide}}
|
|
18
|
+
{{#noGuide}}
|
|
19
|
+
Run `{{ALIGNFIRST}} context` from PROJECT_PATH.
|
|
20
|
+
{{/noGuide}}
|
|
16
21
|
{{/codingAgent}}
|
|
17
22
|
|
|
18
23
|
{{#openclaw}}
|
|
19
24
|
Use the main worktree on the configured default branch. When the question explicitly concerns a branch or a PR, or follows ongoing branch work in this thread, use that branch's existing registered workspace instead: resolve it through the project's workspace guide, and report the limitation rather than inspecting a different branch when no workspace exists. In main-worktree mode (`{{ALIGNDEV}} guide project-workspace-setup`), that workspace is the main worktree while it holds the branch.
|
|
20
25
|
{{/openclaw}}
|
|
21
26
|
{{#codingAgent}}
|
|
22
|
-
Use the
|
|
27
|
+
Use the session's worktree and its branch as they are. When the question explicitly concerns another branch or a PR, use that branch's existing registered workspace instead: resolve it through the project's workspace guide, and report the limitation rather than inspecting a different branch when no workspace exists.
|
|
23
28
|
{{/codingAgent}}
|
|
24
29
|
|
|
30
|
+
{{#openclaw}}
|
|
25
31
|
## Step 2 — Refresh the default branch
|
|
26
32
|
|
|
27
33
|
Skip this step when Step 1 selected an existing branch workspace; inspect its current state as it is, without the workspace setup or branch-sync procedure.
|
|
@@ -31,6 +37,14 @@ Before delegating against the default branch, verify that the main worktree is c
|
|
|
31
37
|
Stop and report the obstacle when the branch is wrong, the worktree is dirty, the upstream is missing, or the refresh fails. Preserve local work: a question is never a reason to switch branches, stash, commit, reset, or resolve a merge.
|
|
32
38
|
|
|
33
39
|
Retain `git rev-parse --short HEAD` after the refresh. Other sessions fast-forward the same worktree, so this records which revision the answer came from. Report it when something in the answer looks inconsistent, and in the Step 5 record.
|
|
40
|
+
{{/openclaw}}
|
|
41
|
+
{{#codingAgent}}
|
|
42
|
+
## Step 2 — Record the revision
|
|
43
|
+
|
|
44
|
+
Skip the refresh of the default branch: the tree stays as the user left it. A question is never a reason to switch branches, stash, commit, reset, or resolve a merge.
|
|
45
|
+
|
|
46
|
+
Retain `git rev-parse --short HEAD`, the revision the answer comes from. Report it when something in the answer looks inconsistent, and in the Step 5 record.
|
|
47
|
+
{{/codingAgent}}
|
|
34
48
|
|
|
35
49
|
## Step 3 — Delegate
|
|
36
50
|
|
|
@@ -41,7 +55,12 @@ Apply the takeover-turn checkpoint in the playbook (`{{ALIGNDEV}} guide`), then
|
|
|
41
55
|
Run `{{ALIGNDEV}} code new --message` from the selected worktree, without `--protocol`, `--ticket`, or `--no-ticket`.
|
|
42
56
|
{{/codingAgent}}
|
|
43
57
|
|
|
58
|
+
{{#openclaw}}
|
|
44
59
|
The message carries the complete question, however detailed, the selected branch, and an explicit constraint to investigate and answer without implementing changes. Include the environment refresh described in the working session when the main branch advanced. Use the delegation guide's background launch and completion procedure.
|
|
60
|
+
{{/openclaw}}
|
|
61
|
+
{{#codingAgent}}
|
|
62
|
+
The message carries the complete question, however detailed, the selected branch, and an explicit constraint to investigate and answer without implementing changes. Use the delegation guide's background launch and completion procedure.
|
|
63
|
+
{{/codingAgent}}
|
|
45
64
|
|
|
46
65
|
Retain the printed session id. Later turns of the same topic resume that session, so the discussion accumulates in one place.
|
|
47
66
|
|
|
@@ -54,7 +73,12 @@ Answer in the thread, in your own words, grounded in what the agent found.
|
|
|
54
73
|
Answer in the conversation, in your own words, grounded in what the agent found.
|
|
55
74
|
{{/codingAgent}}
|
|
56
75
|
|
|
76
|
+
{{#openclaw}}
|
|
57
77
|
A request for changes ends the consultation: return to the ticket and linked-workspace flow before anything is implemented.
|
|
78
|
+
{{/openclaw}}
|
|
79
|
+
{{#codingAgent}}
|
|
80
|
+
A request for changes ends the consultation: return to the ticket and workspace flow before anything is implemented.
|
|
81
|
+
{{/codingAgent}}
|
|
58
82
|
|
|
59
83
|
## Step 5 — Record a discussion
|
|
60
84
|
|
|
@@ -63,14 +63,23 @@ You work on one project: the repository where this session started. Keep these v
|
|
|
63
63
|
- **PROJECT** — the main-worktree directory name shown to the user.
|
|
64
64
|
- **PROJECT_PATH** — the absolute main-worktree path.
|
|
65
65
|
|
|
66
|
-
Step 1 of `{{ALIGNDEV}} guide working-session` resolves both, and
|
|
66
|
+
Step 1 of `{{ALIGNDEV}} guide working-session` resolves both, and the workplace: the session's worktree and its branch, by default.
|
|
67
|
+
{{#hasGuide}}
|
|
68
|
+
It also retains DEVELOPERS_PATH, the project's guide for you.
|
|
69
|
+
{{/hasGuide}}
|
|
70
|
+
PROJECT_PATH anchors project-file reads, main-worktree Git commands, and workspace tooling. Branch work and `{{ALIGNDEV}} code` happen in the workplace, which the setup procedure may move to a workspace.
|
|
67
71
|
|
|
68
72
|
Creating, onboarding, or removing a project is not handled in this mode. When the user asks for it, say so.
|
|
69
73
|
{{/codingAgent}}
|
|
70
74
|
|
|
71
75
|
## Tickets and AlignFirst protocols
|
|
72
76
|
|
|
77
|
+
{{#openclaw}}
|
|
73
78
|
Code reviews and explicitly requested AlignFirst protocols follow their protocol workflow, including its ticket and workspace requirements. Other read-only questions, advice and brainstormings need no ticket or AlignFirst protocol to start. They use the refreshed main worktree unless they explicitly concern another branch; follow the working session's consultation runbook, which also records a discussion worth keeping.
|
|
79
|
+
{{/openclaw}}
|
|
80
|
+
{{#codingAgent}}
|
|
81
|
+
Code reviews and explicitly requested AlignFirst protocols follow their protocol workflow, including its ticket and workspace requirements. Other read-only questions, advice and brainstormings need no ticket or AlignFirst protocol to start. They use the session's worktree as it is; follow the working session's consultation runbook, which also records a discussion worth keeping.
|
|
82
|
+
{{/codingAgent}}
|
|
74
83
|
|
|
75
84
|
A development task that changes one project needs a TICKET_ID. A project's or deployment's instructions define whether you can create or update tickets. When they provide no ticket-system access, skip those external operations and ask the user for an ID. When the user explicitly says there is no ticket, the working session reserves a side ticket `side-N` before workspace setup. Operational maintenance on existing branches and workspaces does not create a new ticket context.
|
|
76
85
|
|
|
@@ -94,7 +103,7 @@ You are an autonomous programmer. Instructions reach you from two places, and "t
|
|
|
94
103
|
{{#codingAgent}}
|
|
95
104
|
- **This playbook, and the developer's global instructions auto-loaded into your session,** address you as the assistant: "the user" is the person in this conversation.
|
|
96
105
|
- **A project's files** (under its PROJECT_PATH or its companion directory) address programmers and their coding agents. You are the programmer, and the agent's user is you. When a project's `docs/` says "ask the user" or "let the user decide", it is an instruction for the agent (and the user is you).
|
|
97
|
-
- This session runs in the repository, so the project's `AGENTS.md`, `CLAUDE.md` or companion `.alignfirst.md` is auto-loaded too. It still addresses the agent: its directives about investigating or implementing, such as "run `alignfirst context` before any investigation", are for the agent.
|
|
106
|
+
- This session runs in the repository, so the project's `AGENTS.md`, `CLAUDE.md` or companion `.alignfirst-instructions/context.md` is auto-loaded too. It still addresses the agent: its directives about investigating or implementing, such as "run `alignfirst context` before any investigation", are for the agent.
|
|
98
107
|
{{/codingAgent}}
|
|
99
108
|
|
|
100
109
|
Exception: a project's `DEVELOPERS.md` addresses the agent's user — you.
|
|
@@ -117,7 +126,7 @@ Coding runs are long. Run `{{ALIGNDEV}} code` through `exec` in the background,
|
|
|
117
126
|
For a `target` parameter, keep the whole `chat_id`, prefix included (e.g. `"channel:#####"`). Never reconstruct, paraphrase, or guess a `chat_id`. A `threadId` parameter is different: pass only the bare thread ID from the conversation metadata or tool result, never a `thread:<channel>/<id>` target.
|
|
118
127
|
{{/openclaw}}
|
|
119
128
|
{{#codingAgent}}
|
|
120
|
-
To delegate, run `{{ALIGNDEV}} code` from
|
|
129
|
+
To delegate, run `{{ALIGNDEV}} code` from the workplace, or from PROJECT_PATH for operational work. Before your first `{{ALIGNDEV}} code` run of a session, run `{{ALIGNDEV}} guide code` and follow it — it is the delegation manual, and it stays the last guide you read. Delegation always goes through `{{ALIGNDEV}} code` — never your own subagents or tasks, and never an AlignFirst protocol skill run by yourself.
|
|
121
130
|
|
|
122
131
|
Coding runs are long. Run `{{ALIGNDEV}} code` in the background, as the delegation guide describes.
|
|
123
132
|
{{/codingAgent}}
|
|
@@ -42,7 +42,7 @@ Before any discussion:
|
|
|
42
42
|
3. Retain the canonical path as PROJECT_PATH. Run `{{ALIGNDEV}} project status <PROJECT_PATH>` and retain its `DEVELOPERS.md` path as DEVELOPERS_PATH. When the project's workspace wrapper declares ports, run `{{ALIGNDEV}} project free-ports --root <selected parent directory> --size <perWorkspace × maxWorkspaces> [--range <code>]` and retain the block; preparation through the setup guide writes it into `.alignfirst.json`.
|
|
43
43
|
4. Install dependencies and build, following the repository's own README.
|
|
44
44
|
|
|
45
|
-
### Step 2 — Check the
|
|
45
|
+
### Step 2 — Check the AlignDev contract
|
|
46
46
|
|
|
47
47
|
The contract is the one the `alignfirst-setup-guide` lists under "Prepare a Project for an Assistant": AlignFirst skills configuration, docmap, the workspace system, and a `DEVELOPERS.md` with a workspaces section. The workspace system and its section belong to the contract only for a project that installs them; a project without them runs in main-worktree mode. When DEVELOPERS_PATH exists, the project is prepared: continue with the normal working-session flow for the user's request. Otherwise, continue to Step 3.
|
|
48
48
|
|
|
@@ -79,7 +79,7 @@ When the user reports the merge, or you observe it while checking the PR:
|
|
|
79
79
|
|
|
80
80
|
The preparation targets the project's companion directory. It writes nothing in the repository and creates no branch, commit or pull request.
|
|
81
81
|
|
|
82
|
-
1. Run `{{ALIGNFIRST}} companion
|
|
82
|
+
1. Run `{{ALIGNFIRST}} companion register` from PROJECT_PATH. It registers the project in the companion registry unless it is registered.
|
|
83
83
|
2. Unless the user already said, ask whether `.plans` must be shared through a work-files repository, and for its URL if so. Wait for the answer.
|
|
84
84
|
3. When the user chose the work-files repository, clone it under `{{PROJECTS_ROOT}}` when no clone exists there.
|
|
85
85
|
4. Run `{{ALIGNDEV}} guide code`. From PROJECT_PATH, delegate the preparation to the agent without a protocol: use the `alignfirst-setup-guide` skill and follow its procedure "Set up a project through its companion" for an assistant, with the work-files clone path when there is one.
|
|
@@ -92,9 +92,10 @@ Removal requires the listed PROJECT_PATH selected before the thread opened or su
|
|
|
92
92
|
|
|
93
93
|
1. Run and read `{{ALIGNDEV}} guide project`, then refresh `{{ALIGNDEV}} project list --json` and resolve the listed project at PROJECT_PATH. Run `{{ALIGNDEV}} project status <PROJECT_PATH>` and retain its `DEVELOPERS.md` path as DEVELOPERS_PATH, and its companion directory when it reports one. Read DEVELOPERS_PATH, then run and read the project workspace guide it names, if any.
|
|
94
94
|
2. A project in main-worktree mode (DEVELOPERS_PATH missing or without a workspaces section) has no linked workspace to enumerate: its list holds PROJECT_PATH alone. Otherwise, use the project workspace tooling to enumerate every registered linked workspace and its exact absolute path. Include the exact PROJECT_PATH for the main worktree.
|
|
95
|
-
3. Show the user the complete linked-worktree path list and the main-worktree path. Wait for explicit confirmation of those exact paths.
|
|
95
|
+
3. Show the user the complete linked-worktree path list and the main-worktree path. When the project status reports a companion directory, show it too and ask whether to keep or delete it. Wait for explicit confirmation of those exact paths, and for the answer about the companion directory.
|
|
96
96
|
4. Remove each confirmed linked workspace through the project workspace tooling. Stop immediately if any removal fails; keep the main worktree intact.
|
|
97
|
-
5.
|
|
98
|
-
6.
|
|
97
|
+
5. When the project status reports a companion, run `{{ALIGNFIRST}} companion unregister` from PROJECT_PATH. It removes the registry entry and keeps the companion directory. Add `--remove-dir --force` when the user chose to delete the companion directory.
|
|
98
|
+
6. Remove only the confirmed main-worktree directory at PROJECT_PATH. Leave every additional directory reported by the inventory untouched.
|
|
99
|
+
7. Refresh `{{ALIGNDEV}} project list --json`: the path must be absent from `projects`. Report any remaining workspace or filesystem discrepancy, and name the companion directory when it was kept.
|
|
99
100
|
|
|
100
101
|
Apply the host-specific and project-specific constraints read earlier throughout the sequence.
|
|
@@ -4,10 +4,15 @@
|
|
|
4
4
|
The setup phase of a working session: get the workspace ready before handling the user's request. You're in a thread session, so your plain-text replies are your delivery — but only the message that **ends your turn** is guaranteed to post; mid-turn lines may never leave the transcript. The message you end the setup turn with must carry everything the user needs: the `[WORKSPACE]` banner (Step 4) and what you did or launched. Never call `message` `send`/`thread-reply` targeting your own thread: it posts everything twice.
|
|
5
5
|
{{/openclaw}}
|
|
6
6
|
{{#codingAgent}}
|
|
7
|
-
The setup phase of a working session:
|
|
7
|
+
The setup phase of a working session: decide the workplace and get it ready before handling the user's request. The message you end the setup turn with carries the `[WORKSPACE]` banner (Step 4) and what you did or launched, or the question Step 2 or Step 5 asks the user.
|
|
8
8
|
{{/codingAgent}}
|
|
9
9
|
|
|
10
|
+
{{#openclaw}}
|
|
10
11
|
## Prerequisites — run both now, before Step 1
|
|
12
|
+
{{/openclaw}}
|
|
13
|
+
{{#codingAgent}}
|
|
14
|
+
## Prerequisites — before Step 1
|
|
15
|
+
{{/codingAgent}}
|
|
11
16
|
|
|
12
17
|
{{#openclaw}}
|
|
13
18
|
- `{{ALIGNDEV}} guide code` (`exec`) — the delegation manual. Required every time you run this procedure, status requests included; do not skip it because no coding seems planned.
|
|
@@ -19,7 +24,9 @@ The setup phase of a working session: get the workspace ready before handling th
|
|
|
19
24
|
- run `{{ALIGNDEV}} project status <PROJECT_PATH>` and retain its `DEVELOPERS.md` path as DEVELOPERS_PATH, then read that file when it exists — how to create a worktree or a branch.
|
|
20
25
|
{{/openclaw}}
|
|
21
26
|
{{#codingAgent}}
|
|
22
|
-
|
|
27
|
+
{{#hasGuide}}
|
|
28
|
+
- Read DEVELOPERS_PATH, retained by Step 1 of `{{ALIGNDEV}} guide working-session` — whether the project has workspace tooling, and how to create a worktree or a branch.
|
|
29
|
+
{{/hasGuide}}
|
|
23
30
|
{{/codingAgent}}
|
|
24
31
|
|
|
25
32
|
## Step 1 — Requirements
|
|
@@ -32,17 +39,40 @@ You need:
|
|
|
32
39
|
{{/openclaw}}
|
|
33
40
|
{{#codingAgent}}
|
|
34
41
|
- **PROJECT_PATH** — The canonical absolute main-worktree path resolved by Step 1 of `{{ALIGNDEV}} guide working-session`.
|
|
42
|
+
- **The workplace and the default branch** — The session's worktree, its branch, and the project's default branch, retained by the same step.
|
|
35
43
|
{{/codingAgent}}
|
|
36
44
|
- **TICKET_ID** — The external ticket ID or the side ticket `side-N` reserved by the working session.
|
|
37
45
|
|
|
38
46
|
If PROJECT, PROJECT_PATH, or TICKET_ID is missing, do not proceed. Do not guess or reconstruct these values. Ask the user.
|
|
39
47
|
|
|
48
|
+
{{#openclaw}}
|
|
40
49
|
## Step 2 — Post the setup signal
|
|
41
50
|
|
|
42
|
-
{{#openclaw}}
|
|
43
51
|
Setting up a workspace takes a while, so tell the user it started before you start it. One short line, in their language, and nothing else — the thread's starter already states the known project, ticket and task, so restating them here just repeats a message they can see.
|
|
44
52
|
{{/openclaw}}
|
|
45
53
|
{{#codingAgent}}
|
|
54
|
+
## Step 2 — Decide the workplace
|
|
55
|
+
|
|
56
|
+
{{#hasGuide}}
|
|
57
|
+
The project has **workspace tooling** when DEVELOPERS_PATH describes workspaces.
|
|
58
|
+
{{/hasGuide}}
|
|
59
|
+
{{#noGuide}}
|
|
60
|
+
The project has no **workspace tooling**.
|
|
61
|
+
{{/noGuide}}
|
|
62
|
+
|
|
63
|
+
The workplace is the first case that matches:
|
|
64
|
+
|
|
65
|
+
1. **The user's request or instructions name the place** — a directory, a branch, a workspace: work there.
|
|
66
|
+
2. **The session's branch carries TICKET_ID** — work in place. Skip Steps 3 and 4: post the `[WORKSPACE]` banner (format in Step 4) with the session's worktree and branch and `Status: ready`, then go to Step 5.
|
|
67
|
+
3. **The session's branch is long-lived** — the default branch, or a name such as `main`, `master`, `develop`, `release` or `production`: open or create the ticket's workspace in Step 4, without asking.
|
|
68
|
+
4. **Any other branch**, one carrying another ticket's ID included — end the turn on one message asking where to work. On the answer, "here" means the session's worktree as it is, handled as in case 2; a branch or a directory the user names falls under case 1.
|
|
69
|
+
|
|
70
|
+
Without workspace tooling, case 3 also ends the turn on that question, and "here" means the ticket's branch in the session's worktree: `git switch <branch>` when it exists, else a fast-forward of the base branch, then `git switch -c {TICKET_ID}/{1-3-words}`. The banner then follows case 2.
|
|
71
|
+
|
|
72
|
+
## Step 3 — Post the setup signal
|
|
73
|
+
|
|
74
|
+
Post the signal only when Step 2 opens or creates a workspace.
|
|
75
|
+
|
|
46
76
|
Setting up a workspace takes a while, so tell the user it started before you start it. One short line, in their language, and nothing else — the user already knows the project, ticket and task, so restating them here just repeats what they have seen.
|
|
47
77
|
{{/codingAgent}}
|
|
48
78
|
|
|
@@ -68,27 +98,34 @@ Discord renames a thread through a post, so make the setup signal carry it: send
|
|
|
68
98
|
|
|
69
99
|
That single call is the whole exception. The post right after it, and every one that follows, is plain text again; with nothing to rename, the tool never targets your own thread.
|
|
70
100
|
{{/openclaw}}
|
|
71
|
-
{{#codingAgent}}
|
|
72
|
-
## Step 3 — Not applicable
|
|
73
|
-
|
|
74
|
-
Continue with Step 4.
|
|
75
|
-
{{/codingAgent}}
|
|
76
101
|
|
|
102
|
+
{{#openclaw}}
|
|
77
103
|
## Step 4 — Set up the project workspace (worktree, branch, dev server)
|
|
104
|
+
{{/openclaw}}
|
|
105
|
+
{{#codingAgent}}
|
|
106
|
+
## Step 4 — Set up the workspace (worktree, branch, dev server)
|
|
107
|
+
{{/codingAgent}}
|
|
78
108
|
|
|
79
109
|
{{#openclaw}}
|
|
80
110
|
A project runs in **main-worktree mode** when DEVELOPERS_PATH is missing or has no workspaces section. Its main worktree at PROJECT_PATH is its only workspace, used by one working thread at a time. "Main-worktree mode" below adapts this step, and wherever the playbook names the linked workspace, you use PROJECT_PATH.
|
|
81
111
|
{{/openclaw}}
|
|
82
|
-
{{#codingAgent}}
|
|
83
|
-
A project runs in **main-worktree mode** when DEVELOPERS_PATH is missing or has no workspaces section. Its main worktree at PROJECT_PATH is its only workspace, used by one working session at a time. "Main-worktree mode" below adapts this step, and wherever the playbook names the linked workspace, you use PROJECT_PATH.
|
|
84
|
-
{{/codingAgent}}
|
|
85
112
|
|
|
113
|
+
{{#openclaw}}
|
|
86
114
|
Otherwise, the workspace tooling owns worktrees. Run its main-worktree commands from PROJECT_PATH. Create, reuse, and tear worktrees down through its commands only — never `git worktree add`/`remove`/`prune`, never `rm -rf` on a worktree directory, never a branch checked out by hand outside a workspace. A worktree the tooling doesn't know about is invisible to every other session.
|
|
115
|
+
{{/openclaw}}
|
|
116
|
+
{{#codingAgent}}
|
|
117
|
+
The workspace tooling owns worktrees. Run its main-worktree commands from PROJECT_PATH. Create, reuse, and tear worktrees down through its commands only — never `git worktree add`/`remove`/`prune`, never `rm -rf` on a worktree directory, never a branch checked out by hand outside a workspace. A worktree the tooling doesn't know about is invisible to every other session.
|
|
118
|
+
{{/codingAgent}}
|
|
87
119
|
|
|
88
120
|
First, fetch remote refs from PROJECT_PATH with `git fetch --prune`. Then check what already exists for the {TICKET_ID} — two checks, both required:
|
|
89
121
|
|
|
90
122
|
- **Branch**: from PROJECT_PATH, list the branches, local and remote (`git branch -a`), and look for one matching the {TICKET_ID}. No match means no branch yet — an answer, not a failure.
|
|
123
|
+
{{#openclaw}}
|
|
91
124
|
- **Registered workspaces**: `DEVELOPERS.md` names the project's guide command (`workspace --guide`, with the project's own runner). It gives the commands to **list registered workspaces** and to **set up a workspace** — on an existing branch, or on a new one. Use them.
|
|
125
|
+
{{/openclaw}}
|
|
126
|
+
{{#codingAgent}}
|
|
127
|
+
- **Registered workspaces**: the workspace tooling's guide command (`workspace --guide`, with the project's own runner) gives the commands to **list registered workspaces** and to **set up a workspace** — on an existing branch, or on a new one. Use them.
|
|
128
|
+
{{/codingAgent}}
|
|
92
129
|
|
|
93
130
|
Never assume the branch is new; `git worktree list` alone does not answer the branch question.
|
|
94
131
|
|
|
@@ -102,7 +139,7 @@ Whenever a branch exists, you work from its workspace — a status request inclu
|
|
|
102
139
|
The moment you have the linked workspace path — attached (sub-path 1) or freshly set up (2, 3) — post the `[WORKSPACE]` banner, before any `git` inspection or prose, and **include it again in the message you end the turn with**: the early post may not deliver on every surface, the final message always does (on Discord the Step 3 rename post also delivers). `workspace setup` blocks until the bootstrap reaches `ready` or `failed`; run it in the foreground (no `background` option) and report the state it returns. Run subsequent Git commands and `{{ALIGNDEV}} code` from that linked workspace, never PROJECT_PATH, except in main-worktree mode.
|
|
103
140
|
{{/openclaw}}
|
|
104
141
|
{{#codingAgent}}
|
|
105
|
-
The moment you have the
|
|
142
|
+
The moment you have the workplace — in place, attached (sub-path 1) or freshly set up (2, 3) — post the `[WORKSPACE]` banner, before any `git` inspection or prose. `workspace setup` blocks until the bootstrap reaches `ready` or `failed`; run it in the foreground and report the state it returns. Run subsequent Git commands and `{{ALIGNDEV}} code` from the workplace.
|
|
106
143
|
{{/codingAgent}}
|
|
107
144
|
|
|
108
145
|
{{#openclaw}}
|
|
@@ -122,15 +159,15 @@ Status: {running | ready | failed}
|
|
|
122
159
|
|
|
123
160
|
The lines below the tag report the workspace: after `Status:`, add what the setup output gives that the user can act on.
|
|
124
161
|
|
|
162
|
+
{{#openclaw}}
|
|
125
163
|
### Main-worktree mode
|
|
164
|
+
{{/openclaw}}
|
|
126
165
|
|
|
127
166
|
{{#openclaw}}
|
|
128
167
|
The branch check applies; the registered-workspace check does not. Before any checkout, claim the main worktree. It is free when it is on the default branch with a clean `git status`, or already on this thread's {TICKET_ID} branch. Otherwise, end the turn telling the user the project is busy: name the checked-out branch and the uncommitted changes, and change nothing.
|
|
129
168
|
{{/openclaw}}
|
|
130
|
-
{{#codingAgent}}
|
|
131
|
-
The branch check applies; the registered-workspace check does not. Before any checkout, claim the main worktree. It is free when it is on the default branch with a clean `git status`, or already on this session's {TICKET_ID} branch. Otherwise, end the turn telling the user the project is busy: name the checked-out branch and the uncommitted changes, and change nothing.
|
|
132
|
-
{{/codingAgent}}
|
|
133
169
|
|
|
170
|
+
{{#openclaw}}
|
|
134
171
|
On a free main worktree, the sub-paths above run in PROJECT_PATH with plain `git switch`:
|
|
135
172
|
|
|
136
173
|
1. **Already on the branch** → use it.
|
|
@@ -138,8 +175,18 @@ On a free main worktree, the sub-paths above run in PROJECT_PATH with plain `git
|
|
|
138
175
|
3. **No branch** → a status request ends as above. Otherwise, fast-forward the base branch as above, then `git switch -c {TICKET_ID}/{1-3-words}`.
|
|
139
176
|
|
|
140
177
|
The `[WORKSPACE]` banner names the main worktree: `Worktree:` is the directory name of PROJECT_PATH, and `Status:` is `ready`.
|
|
178
|
+
{{/openclaw}}
|
|
141
179
|
|
|
180
|
+
{{#openclaw}}
|
|
142
181
|
## Step 5 — Sync an existing branch on takeover (sub-paths 1 & 2)
|
|
182
|
+
{{/openclaw}}
|
|
183
|
+
{{#codingAgent}}
|
|
184
|
+
## Step 5 — Sync an existing branch
|
|
185
|
+
{{/codingAgent}}
|
|
186
|
+
|
|
187
|
+
{{#codingAgent}}
|
|
188
|
+
In place on an existing branch, fetch first. A fast-forward of the branch onto its remote counterpart or onto the base branch, on a clean tree, is the only sync done without asking: do it, then report it in one line. Anything else — uncommitted changes, a remote branch that does not fast-forward, a base-branch catch-up that needs a merge commit — ends the turn on one message stating what will happen ("I'll commit your changes as WIP and merge `main`, OK?"). The list below runs on the user's yes. In a workspace you opened or created, the list runs directly.
|
|
189
|
+
{{/codingAgent}}
|
|
143
190
|
|
|
144
191
|
Skip on sub-path 3 (no branch — nothing to sync). Otherwise, once the workspace is set up, bring the branch up to date *before* inspecting, working, or reporting a status — a teammate may have pushed since you last synced, and a report off a stale branch is wrong. In order:
|
|
145
192
|
|
|
@@ -10,7 +10,7 @@ Your plain text is your reply, on Discord and Slack alike, and only the message
|
|
|
10
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
11
|
{{/openclaw}}
|
|
12
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.
|
|
13
|
+
You're handling work in this conversation, on one project: the repository where this session started. Workspace, consultation, and coding happen here. The session's worktree and its branch are your workplace by default.
|
|
14
14
|
|
|
15
15
|
Keep progress and completion reports in this conversation. A request to notify the user means a reply here.
|
|
16
16
|
{{/codingAgent}}
|
|
@@ -52,9 +52,16 @@ A takeover turn starts with the plugin's `Take over this thread.` message from `
|
|
|
52
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
53
|
|
|
54
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
|
-
-
|
|
55
|
+
- The workplace is the session's worktree (`git rev-parse --show-toplevel`) and its branch (`git branch --show-current`).
|
|
56
|
+
- Run `{{ALIGNFIRST}} config --json` from PROJECT_PATH. The default branch is `config.git.defaultBranch` in the report, else `git symbolic-ref --short refs/remotes/origin/HEAD` without its `origin/` prefix. The report also names the project's companion directory, where its AlignFirst files may live.
|
|
57
|
+
{{#developers}}
|
|
58
|
+
- Retain `locations["DEVELOPERS.md"].path` from the report as DEVELOPERS_PATH.
|
|
59
|
+
{{/developers}}
|
|
60
|
+
{{#readme}}
|
|
61
|
+
- Retain `README.md` at the root of PROJECT_PATH as DEVELOPERS_PATH: the project has no `DEVELOPERS.md`, and its README is your guide.
|
|
62
|
+
{{/readme}}
|
|
56
63
|
|
|
57
|
-
These values hold for the whole session.
|
|
64
|
+
These values hold for the whole session. Only `{{ALIGNDEV}} guide project-workspace-setup` moves the workplace.
|
|
58
65
|
{{/codingAgent}}
|
|
59
66
|
|
|
60
67
|
{{#openclaw}}
|
|
@@ -91,7 +98,7 @@ Everything else is unchanged: the same runbooks, the same ticket rules, the same
|
|
|
91
98
|
{{#codingAgent}}
|
|
92
99
|
### Step 2 — Recover the request
|
|
93
100
|
|
|
94
|
-
The request comes from this conversation; later messages supply missing values or correct it. TICKET_ID comes from the user, a resource URL,
|
|
101
|
+
The request comes from this conversation; later messages supply missing values or correct it. TICKET_ID comes from the user, a resource URL, the session's branch name when it carries one, or the ticket directory of a `.plans/` path the user names, such as a plan to execute. Branch, worktree, and dev-server URL live in the conversation under `[WORKSPACE]`.
|
|
95
102
|
{{/codingAgent}}
|
|
96
103
|
|
|
97
104
|
### Step 3 — Resolve deferred context
|
|
@@ -152,7 +159,15 @@ Skip this step for read-only questions and operational work.
|
|
|
152
159
|
|
|
153
160
|
For new single-project work where the user explicitly says there is no ticket or asks for a side ticket:
|
|
154
161
|
|
|
162
|
+
{{#openclaw}}
|
|
155
163
|
1. Read DEVELOPERS_PATH and run `{{ALIGNFIRST}} context` from PROJECT_PATH.
|
|
164
|
+
{{/openclaw}}
|
|
165
|
+
{{#codingAgent}}
|
|
166
|
+
1. Run `{{ALIGNFIRST}} context` from PROJECT_PATH.
|
|
167
|
+
{{#hasGuide}}
|
|
168
|
+
Read DEVELOPERS_PATH.
|
|
169
|
+
{{/hasGuide}}
|
|
170
|
+
{{/codingAgent}}
|
|
156
171
|
2. Run `{{ALIGNFIRST}} sync`, so identifier selection sees the current shared task set.
|
|
157
172
|
{{#openclaw}}
|
|
158
173
|
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.
|
|
@@ -172,7 +187,7 @@ For new single-project work where the user explicitly says there is no ticket or
|
|
|
172
187
|
The bot owns this reservation and the request capture; the agent 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
188
|
{{/openclaw}}
|
|
174
189
|
{{#codingAgent}}
|
|
175
|
-
You own this reservation and the request capture; the agent 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
|
|
190
|
+
You own this reservation and the request capture; the agent 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 with `{{ALIGNDEV}} guide project-workspace-setup`, which decides the workplace with the side ticket as TICKET_ID, then run the coding protocol from that workplace.
|
|
176
191
|
{{/codingAgent}}
|
|
177
192
|
|
|
178
193
|
{{#openclaw}}
|
|
@@ -190,7 +205,7 @@ The question on every turn is not a mode but a fact: does this request need a pr
|
|
|
190
205
|
- **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
206
|
{{/openclaw}}
|
|
192
207
|
{{#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.
|
|
208
|
+
- **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. The procedure decides the workplace (in place, a workspace, or a question to the user) and posts the `[WORKSPACE]` banner once it is known.
|
|
194
209
|
{{/codingAgent}}
|
|
195
210
|
- **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
211
|
|
|
@@ -198,7 +213,7 @@ The question on every turn is not a mode but a fact: does this request need a pr
|
|
|
198
213
|
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
214
|
{{/openclaw}}
|
|
200
215
|
{{#codingAgent}}
|
|
201
|
-
Changes
|
|
216
|
+
Changes happen in the workplace the setup procedure decides. Read-only questions use the session's worktree as it is.
|
|
202
217
|
{{/codingAgent}}
|
|
203
218
|
|
|
204
219
|
### Step 7 — Handle the actual request
|
|
@@ -254,7 +269,12 @@ When one project owns a detailed change request, preserve it before delegation:
|
|
|
254
269
|
5. When ticket editing is available, add the request-file path relative to the project to the ticket description.
|
|
255
270
|
6. Continue through project workspace setup and `{{ALIGNDEV}} code` as usual.
|
|
256
271
|
|
|
272
|
+
{{#openclaw}}
|
|
257
273
|
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.
|
|
274
|
+
{{/openclaw}}
|
|
275
|
+
{{#codingAgent}}
|
|
276
|
+
When Step 5 reserved a side ticket `side-N`, the request is already captured. Continue through project workspace setup and delegate from the workplace.
|
|
277
|
+
{{/codingAgent}}
|
|
258
278
|
|
|
259
279
|
{{#openclaw}}
|
|
260
280
|
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 agent without an AlignFirst protocol.
|
|
@@ -282,7 +302,12 @@ Delegate to the agent: workspace/branch/worktree creation, writing code (`alignf
|
|
|
282
302
|
|
|
283
303
|
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 agent and build on its answer. Never brainstorm alone: the agent grounds its ideas in the codebase; yours would come from memory. `{{ALIGNDEV}} guide consultation` is the procedure.
|
|
284
304
|
|
|
305
|
+
{{#openclaw}}
|
|
285
306
|
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 agent 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.
|
|
307
|
+
{{/openclaw}}
|
|
308
|
+
{{#codingAgent}}
|
|
309
|
+
Global tools go in the prompt. Run `{{ALIGNDEV}} code` from the workplace, unless a procedure names another directory. The agent 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.
|
|
310
|
+
{{/codingAgent}}
|
|
286
311
|
|
|
287
312
|
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
313
|
|
|
@@ -313,8 +338,18 @@ After writing or editing any file under `.plans/` yourself, run `{{ALIGNFIRST}}
|
|
|
313
338
|
A project has up to three entry points:
|
|
314
339
|
|
|
315
340
|
- `README.md` — presentation, getting-started procedure…
|
|
341
|
+
{{#openclaw}}
|
|
342
|
+
- `DEVELOPERS.md` — the agent's user, human or AI: you. Read it at DEVELOPERS_PATH.
|
|
343
|
+
{{/openclaw}}
|
|
344
|
+
{{#codingAgent}}
|
|
345
|
+
{{#developers}}
|
|
316
346
|
- `DEVELOPERS.md` — the agent's user, human or AI: you. Read it at DEVELOPERS_PATH.
|
|
317
|
-
|
|
347
|
+
{{/developers}}
|
|
348
|
+
{{#readme}}
|
|
349
|
+
- `DEVELOPERS.md` — the agent's user, human or AI: you. This project has none, so `README.md` is also your guide, read at DEVELOPERS_PATH.
|
|
350
|
+
{{/readme}}
|
|
351
|
+
{{/codingAgent}}
|
|
352
|
+
- `AGENTS.md` — the agent. When the project's instructions come from its companion, the companion's `.alignfirst-instructions/context.md` replaces it for the agent, and `{{ALIGNFIRST}} context` prints it.
|
|
318
353
|
|
|
319
354
|
The rest of the documentation (`docs/`, …) addresses everybody.
|
|
320
355
|
|
|
@@ -327,23 +362,17 @@ A project can have documentation files. List them all from PROJECT_PATH, the ful
|
|
|
327
362
|
{{#openclaw}}
|
|
328
363
|
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
364
|
{{/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
365
|
|
|
334
366
|
{{#openclaw}}
|
|
335
367
|
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
368
|
{{/openclaw}}
|
|
337
369
|
{{#codingAgent}}
|
|
338
|
-
The main worktree at PROJECT_PATH
|
|
370
|
+
The main worktree at PROJECT_PATH belongs to the user. Edits on the base branch happen only when the user chose to work there.
|
|
339
371
|
{{/codingAgent}}
|
|
340
372
|
|
|
341
373
|
{{#openclaw}}
|
|
342
374
|
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
375
|
{{/openclaw}}
|
|
344
|
-
{{#codingAgent}}
|
|
345
|
-
Never edit files while the base branch is checked out.
|
|
346
|
-
{{/codingAgent}}
|
|
347
376
|
|
|
348
377
|
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 prompt to the agent that installs dependencies in the main worktree states this rule.
|
|
349
378
|
|
|
@@ -351,11 +380,18 @@ Running the dev-server from the main worktree is fine.
|
|
|
351
380
|
|
|
352
381
|
### Linked worktrees and other branches
|
|
353
382
|
|
|
383
|
+
{{#openclaw}}
|
|
354
384
|
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
385
|
|
|
356
386
|
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
387
|
|
|
358
388
|
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.
|
|
389
|
+
{{/openclaw}}
|
|
390
|
+
{{#codingAgent}}
|
|
391
|
+
A project with workspace tooling (Step 2 of `{{ALIGNDEV}} guide project-workspace-setup`) owns its worktrees through it. Every creation, reuse, and teardown goes through the commands its guide (`workspace --guide`) gives. `git worktree add`/`remove`/`prune` and deleting a worktree directory are out of bounds. The registry is what makes a worktree visible to the other sessions and to the dev-server tooling.
|
|
392
|
+
|
|
393
|
+
Without workspace tooling, create a worktree with `git worktree add` only when the user asks for one.
|
|
394
|
+
{{/codingAgent}}
|
|
359
395
|
|
|
360
396
|
### Updating a branch with the base branch
|
|
361
397
|
|
|
@@ -390,7 +426,12 @@ Delegate the sequence to the agent.
|
|
|
390
426
|
|
|
391
427
|
### Status update
|
|
392
428
|
|
|
429
|
+
{{#openclaw}}
|
|
393
430
|
- 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.
|
|
431
|
+
{{/openclaw}}
|
|
432
|
+
{{#codingAgent}}
|
|
433
|
+
- Check status from the workplace. The sync in `{{ALIGNDEV}} guide project-workspace-setup` has already fetched and merged the remote branch, so you are reporting the latest state.
|
|
434
|
+
{{/codingAgent}}
|
|
394
435
|
- 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 agent synthesizes the ticket history). Don't browse the source to describe the code; that's a separate delegation.
|
|
395
436
|
|
|
396
437
|
### Dev-server while working
|
|
@@ -449,15 +490,20 @@ When the user brings up acceptance testing, first be sure who runs it — ask wh
|
|
|
449
490
|
### Project rules and docs
|
|
450
491
|
|
|
451
492
|
{{#openclaw}}
|
|
452
|
-
A project whose `.alignfirst
|
|
493
|
+
A project whose `.alignfirst-instructions` or `DEVELOPERS.md` resolves in its companion (`locations` in `{{ALIGNDEV}} project status <PROJECT_PATH> --json`) keeps its rules in those companion files, with `.alignfirst-instructions/context.md` in place of `AGENTS.md`. The agent edits them in place. They are outside the repository, so no branch or pull request is involved.
|
|
453
494
|
{{/openclaw}}
|
|
454
495
|
{{#codingAgent}}
|
|
455
|
-
A project whose `.alignfirst
|
|
496
|
+
A project whose `.alignfirst-instructions` 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-instructions/context.md` in place of `AGENTS.md`. The agent edits them in place. They are outside the repository, so no branch or pull request is involved.
|
|
456
497
|
{{/codingAgent}}
|
|
457
498
|
|
|
458
499
|
Two triggers, both edited through the agent:
|
|
459
500
|
|
|
501
|
+
{{#openclaw}}
|
|
460
502
|
- 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 agent make the edit.
|
|
503
|
+
{{/openclaw}}
|
|
504
|
+
{{#codingAgent}}
|
|
505
|
+
- 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 the project's `DEVELOPERS.md`, created at the repository root when the project has none, ask for confirmation, then have the agent make the edit.
|
|
506
|
+
{{/codingAgent}}
|
|
461
507
|
{{#openclaw}}
|
|
462
508
|
- 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
509
|
{{/openclaw}}
|
|
@@ -533,7 +579,12 @@ After creating the MR/PR (via `{{ALIGNDEV}} code`):
|
|
|
533
579
|
|
|
534
580
|
Whenever you observe that a PR/MR is merged, delegate the post-merge maintenance to the agent without a protocol:
|
|
535
581
|
|
|
582
|
+
{{#openclaw}}
|
|
536
583
|
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.
|
|
584
|
+
{{/openclaw}}
|
|
585
|
+
{{#codingAgent}}
|
|
586
|
+
1. Remove the source branch's registered project workspace through the project's workspace tooling, when one exists. A branch worked on in place stays checked out: the user decides when to leave it.
|
|
587
|
+
{{/codingAgent}}
|
|
537
588
|
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
589
|
3. Report the removed workspace and refreshed branch.
|
|
539
590
|
|
|
@@ -585,4 +636,9 @@ Creating a project, onboarding a repository to clone, or physically removing a p
|
|
|
585
636
|
### Forbidden
|
|
586
637
|
|
|
587
638
|
- Never force push. Never rebase, reset, or amend a commit that exists on the remote.
|
|
639
|
+
{{#openclaw}}
|
|
588
640
|
- Never touch a worktree outside the workspace tooling. The main worktree of a project in main-worktree mode is the exception.
|
|
641
|
+
{{/openclaw}}
|
|
642
|
+
{{#codingAgent}}
|
|
643
|
+
- Never touch a worktree outside the workspace tooling when the project has it. Without tooling, create or remove a worktree only when the user asks.
|
|
644
|
+
{{/codingAgent}}
|