@paleo/alcode 0.1.0 → 0.3.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/dist/cli.d.ts CHANGED
@@ -15,9 +15,11 @@ export interface AlcodeArgs {
15
15
  protocol?: string;
16
16
  message?: string;
17
17
  model?: string;
18
+ meta?: string;
18
19
  guide: boolean;
19
20
  openclawGuide: boolean;
20
21
  help: boolean;
22
+ version: boolean;
21
23
  }
22
24
  export declare function parseAlcodeArgs(argv: string[]): AlcodeArgs;
23
25
  export declare function validateArgs(args: AlcodeArgs): string | undefined;
package/dist/cli.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { readFileSync } from "node:fs";
1
2
  import { relative } from "node:path";
2
3
  import { parseArgs } from "node:util";
3
4
  import { renderGuide } from "./guide.js";
@@ -18,6 +19,10 @@ export async function main(options) {
18
19
  stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
19
20
  return 1;
20
21
  }
22
+ if (parsed.version) {
23
+ stdout.write(`${readPackageVersion()}\n`);
24
+ return 0;
25
+ }
21
26
  if (parsed.help) {
22
27
  stdout.write(renderHelp());
23
28
  return 0;
@@ -33,6 +38,12 @@ export async function main(options) {
33
38
  }
34
39
  return runSession(parsed, { cwd, env, stdout, stderr });
35
40
  }
41
+ function readPackageVersion() {
42
+ const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
43
+ if (!pkg.version)
44
+ throw new Error("alcode: package.json is missing 'version'");
45
+ return pkg.version;
46
+ }
36
47
  // alcode always runs `claude` in the foreground and blocks until it exits. When OpenClaw drives
37
48
  // alcode, it wraps this call in its own `exec` tool (which backgrounds after `yieldMs` and wakes
38
49
  // the agent on exit) — alcode owns no backgrounding or callback of its own. The per-run session
@@ -64,6 +75,7 @@ function buildFrontmatter(parsed, now) {
64
75
  model: parsed.model ?? null,
65
76
  sessionId: null,
66
77
  command: formatCommand(parsed),
78
+ meta: parsed.meta ?? null,
67
79
  startedAt: now.toISOString(),
68
80
  endedAt: null,
69
81
  exitReason: null,
@@ -96,6 +108,8 @@ function formatCommand(parsed) {
96
108
  parts.push("--model", parsed.model);
97
109
  if (parsed.message)
98
110
  parts.push("--message", JSON.stringify(parsed.message));
111
+ if (parsed.meta)
112
+ parts.push("--meta", JSON.stringify(parsed.meta));
99
113
  return parts.join(" ");
100
114
  }
101
115
  export function parseAlcodeArgs(argv) {
@@ -108,9 +122,11 @@ export function parseAlcodeArgs(argv) {
108
122
  protocol: { type: "string" },
109
123
  message: { type: "string" },
110
124
  model: { type: "string" },
125
+ meta: { type: "string" },
111
126
  guide: { type: "boolean", default: false },
112
127
  "openclaw-guide": { type: "boolean", default: false },
113
128
  help: { type: "boolean", default: false },
129
+ version: { type: "boolean", short: "v", default: false },
114
130
  },
115
131
  strict: true,
116
132
  });
@@ -121,9 +137,11 @@ export function parseAlcodeArgs(argv) {
121
137
  protocol: values.protocol,
122
138
  message: values.message,
123
139
  model: values.model,
140
+ meta: values.meta,
124
141
  guide: values.guide === true,
125
142
  openclawGuide: values["openclaw-guide"] === true,
126
143
  help: values.help === true,
144
+ version: values.version === true,
127
145
  };
128
146
  }
129
147
  export function validateArgs(args) {
@@ -169,6 +187,7 @@ Usage:
169
187
  alcode --guide
170
188
  alcode --openclaw-guide
171
189
  alcode --help
190
+ alcode -v, --version
172
191
 
173
192
  Modes:
174
193
  --new Start a new session.
@@ -179,6 +198,9 @@ Options:
179
198
  --ticket <id> Ticket ID. Required with --new + --protocol.
180
199
  --message "..." Message to send. Required for spec, aad, and when no --protocol.
181
200
  --model <model> Model override.
201
+ --meta "..." Opaque handoff string, stored verbatim in the session file frontmatter
202
+ (\`meta:\`). alcode never interprets it; a later reader of the session file
203
+ (e.g. the caller reporting the run's outcome) can use it.
182
204
 
183
205
  Env:
184
206
  ALIGNFIRST_CODE_SKIP_PERMISSIONS 1 to run the coding agent with permission prompts disabled.
@@ -5,6 +5,7 @@ export interface SessionFrontmatter {
5
5
  model: string | null;
6
6
  sessionId: string | null;
7
7
  command: string;
8
+ meta: string | null;
8
9
  startedAt: string;
9
10
  endedAt: string | null;
10
11
  exitReason: string | null;
@@ -94,6 +94,7 @@ export function parseFrontmatter(block) {
94
94
  model: map.model ?? null,
95
95
  sessionId: map.sessionId ?? null,
96
96
  command: map.command ?? "",
97
+ meta: map.meta ?? null,
97
98
  startedAt: map.startedAt ?? "",
98
99
  endedAt: map.endedAt ?? null,
99
100
  exitReason: map.exitReason ?? null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paleo/alcode",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "license": "CC0-1.0",
5
5
  "author": "Thomas MUR",
6
6
  "description": "Run a coding agent through AlignFirst protocols, with a durable session file per run.",
@@ -2,3 +2,4 @@ Under OpenClaw, background it through the `exec` tool:
2
2
 
3
3
  - Pass `background: true` and `timeout: 0` (no kill timer). Never rely on the auto-yield or a finite timeout.
4
4
  - Set the exec `workdir` to the project root as an **absolute** path (`~` is not expanded there), or `cd` into the project inside the command itself.
5
+ - If the outcome must be reported into a thread **you created yourself** via `message` `action: "thread-create"`, add `--meta "<THREAD_ID>"` with that thread's `chat_id`: the completion wake's plain reply goes to this session's default surface (the channel), and only the session file's `meta` can point your report back at the thread (via `message` `action: "thread-reply"`). In every other case omit `--meta` — platform-threaded replies and thread-bound sessions already report in the right place.
@@ -22,8 +22,8 @@ Every run writes a session file under `.plans/`: `.plans/<ticket>/coding-session
22
22
 
23
23
  {{WAKE}}
24
24
 
25
- 1. **Read the run's session file** (the path `alcode` printed on its first line, under `coding-sessions/`). Its frontmatter holds `status` (`succeeded` / `failed`) and the session id; the `---- Result ----` block holds the outcome.
26
- 2. **Report the outcome to the user** where the work was requested. Send one concise message: succeeded or failed, plus a one-line summary of the result for the audience.
25
+ 1. **Read the run's session file** (the path `alcode` printed on its first line, under `coding-sessions/`). Its frontmatter holds `status` (`succeeded` / `failed`) and the session id; the `---- Result ----` block holds the outcome. If you set `meta` at launch, it is there too.
26
+ 2. **Report the outcome to the user** where the work was requested. Send one concise message: succeeded or failed, plus a one-line summary of the result for the audience. If the frontmatter `meta` carries a destination (e.g. a thread target), route this report there — a plain reply from the wake turn goes to the session's default surface, which may not be where the work was requested.
27
27
  3. Do **not** re-verify the repo, re-run the coding agent, fetch/merge branches, or inspect `git`. The coding agent already did the work and the session file is authoritative. Relay its outcome, nothing more.
28
28
 
29
29
  If the session file says the run failed, report that plainly and propose the next step; don't silently retry.
@@ -44,6 +44,7 @@ alcode --resume <sessionId> [--protocol <protocol>] [--message "..."]
44
44
  | `--ticket <id>` | Ticket ID. Required with `--new` + `--protocol`. |
45
45
  | `--message "..."` | Message to send. Required for `spec`, `aad`, and when no `--protocol`. |
46
46
  | `--model <model>` | Model override. |
47
+ | `--meta "..."` | Opaque handoff string stored verbatim in the session file's `meta:` frontmatter. `alcode` never reads it — it's for you to stash context the run's later reader needs (e.g. where to report the outcome). |
47
48
 
48
49
  For `--new` runs, the `Session ID:` is printed to stdout and written to the session file frontmatter (the durable source of truth). Save it to resume the conversation later.
49
50