overlord-cli 0.2609270909.0 → 0.2609281350.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 CHANGED
@@ -31,6 +31,7 @@ queue operations all reach persistence through the backend URL you configure —
31
31
  ### First run
32
32
 
33
33
  Install the published package:
34
+
34
35
  ```bash
35
36
  npm install -g --no-fund overlord-cli
36
37
  ```
@@ -86,10 +87,10 @@ Configuration lives in `overlord.toml` — a per-instance, uncommitted file
86
87
  discovered from the current directory upward, or in `~/.ovld/overlord.toml` for a
87
88
  global install.
88
89
 
89
- | Mode | Config key | How to set it |
90
- | ---- | ---------- | ------------- |
91
- | **Local backend** | `backend_url` | `ovld config set local [url]` — defaults to `http://127.0.0.1:4310` |
92
- | **Hosted backend** | `backend_url` | `ovld config set cloud <url>` |
90
+ | Mode | Config key | How to set it |
91
+ | ------------------ | ------------- | ------------------------------------------------------------------- |
92
+ | **Local backend** | `backend_url` | `ovld config set local [url]` — defaults to `http://127.0.0.1:4310` |
93
+ | **Hosted backend** | `backend_url` | `ovld config set cloud <url>` |
93
94
 
94
95
  `ovld config set` without arguments opens the interactive backend selector.
95
96
  `ovld config list` shows the resolved target; `ovld doctor` checks that the
@@ -98,7 +99,7 @@ backend is reachable.
98
99
  Environment overrides (useful in scripts and CI):
99
100
 
100
101
  - `OVLD_HOME` — relocate the entire global `~/.ovld` data directory (SQLite, object storage, objective ledgers, and native-session caches)
101
- - `OVERLORD_BACKEND_URL` — production/global backend target; an *explicit* runtime value (shell export, container/launcher injection) takes precedence over the resolved `overlord.toml` `backend_url`
102
+ - `OVERLORD_BACKEND_URL` — production/global backend target; an _explicit_ runtime value (shell export, container/launcher injection) takes precedence over the resolved `overlord.toml` `backend_url`
102
103
  - `OVERLORD_BACKEND_URL_DEV` — **development-only** backend target, read solely by the in-repo source build and the dev/test tooling that runs it (`yarn dev`, the test harness). An installed/published `ovld` never reads it, and nothing aliases it into the production `OVERLORD_BACKEND_URL`
103
104
  - `OVERLORD_WEB_PORT` — port the local backend binds when launched
104
105
  - `OVERLORD_USER_TOKEN` / `OVLD_USER_TOKEN` / `USER_TOKEN` — bearer token sent to the backend when set (checked in that order; takes precedence over stored credentials)
@@ -139,6 +140,27 @@ Both the desktop app and the CLI authenticate to `/api/*` with a bearer token:
139
140
  previously stored the raw 7-day Better Auth session token, which is why they
140
141
  expired far sooner than cloud logins.)
141
142
 
143
+ For an external automation that files missions in selected projects, create a
144
+ project automation token:
145
+
146
+ ```bash
147
+ ovld user-token create --label "Feedback importer" \
148
+ --scope project-automation --project <project-id> --no-expiry
149
+ ```
150
+
151
+ Repeat `--project` to select more projects. The token can read those projects
152
+ and create missions with initial objectives using `ovld protocol create
153
+ --project-id <project-id> --objectives-json '[{"objective":"..."}]'` or
154
+ `POST /api/missions`. The project default status applies when `statusId` is
155
+ omitted, and the mission is unassigned unless `assignedWorkspaceUserId` is
156
+ supplied. The token label appears as **Created via token** on its missions and
157
+ remains there after rename or revocation. The default expiry is 90 days;
158
+ `--no-expiry` disables it. Read the project's missions before creating a new
159
+ one on retry, since create has no idempotency key. This preset cannot manage
160
+ webhooks or call `prompt`, `record-work`, `add-objectives`, session, or launch
161
+ commands. Its exact REST and protocol route allowlist is in the
162
+ [authentication guide](../docs/src/content/docs/authentication-and-permissions.mdx).
163
+
142
164
  For the **local** backend, desktop and CLI share `~/.ovld/auth.json`:
143
165
 
144
166
  - Signing in through the desktop app writes the session bearer to `auth.json`, so
@@ -1 +1 @@
1
- 0.3.48
1
+ 0.3.49
@@ -1,4 +1,4 @@
1
- contractVersion: "143"
1
+ contractVersion: "151"
2
2
  componentType: connector
3
3
  componentKey: antigravity
4
4
  label: "Antigravity Connector"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://antigravity.google/schemas/v1/plugin.json",
3
3
  "name": "overlord",
4
- "version": "0.3.48",
4
+ "version": "0.3.49",
5
5
  "description": "Chat-driven access to Overlord mission protocol workflows through skills and MCP.",
6
6
  "author": {
7
7
  "name": "Cooperativ",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overlord",
3
- "version": "0.3.48",
3
+ "version": "0.3.49",
4
4
  "description": "Overlord mission protocol workflow for Claude Code — attach/update/ask/deliver, slash commands, and hook-driven activity capture.",
5
5
  "author": {
6
6
  "name": "Cooperativ",
@@ -52,15 +52,6 @@ The plugin prompts for `overlord_url` and, when needed for non-interactive use,
52
52
  claude --plugin-dir /absolute/path/to/Overlord/connectors/adapters/claude
53
53
  ```
54
54
 
55
- ### Install (published marketplace)
56
-
57
- Once published:
58
-
59
- ```bash
60
- claude plugin marketplace add cooperativ/overlord-marketplace
61
- claude plugin install overlord@cooperativ
62
- ```
63
-
64
55
  ### Namespaced components
65
56
 
66
57
  Inside Claude Code the components are surfaced with the plugin prefix:
@@ -1,4 +1,4 @@
1
- contractVersion: "143"
1
+ contractVersion: "151"
2
2
  componentType: connector
3
3
  componentKey: claude
4
4
  label: "Claude Code Connector"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overlord",
3
- "version": "0.3.48",
3
+ "version": "0.3.49",
4
4
  "description": "Chat-driven access to Overlord mission protocol workflows with hook-driven activity capture.",
5
5
  "author": {
6
6
  "name": "Cooperativ",
@@ -1,4 +1,4 @@
1
- contractVersion: "143"
1
+ contractVersion: "151"
2
2
  componentType: connector
3
3
  componentKey: codex
4
4
  label: "Codex Connector"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overlord",
3
- "version": "0.3.48",
3
+ "version": "0.3.49",
4
4
  "description": "Overlord mission protocol workflow for Cursor — attach/update/ask/deliver, slash commands, MCP bridge, and follow-up capture.",
5
5
  "author": {
6
6
  "name": "Cooperativ",
@@ -1,4 +1,4 @@
1
- contractVersion: "143"
1
+ contractVersion: "151"
2
2
  componentType: connector
3
3
  componentKey: cursor
4
4
  label: "Cursor Connector"
@@ -1,4 +1,4 @@
1
- contractVersion: "143"
1
+ contractVersion: "151"
2
2
  componentType: connector
3
3
  componentKey: opencode
4
4
  label: "OpenCode Connector"
@@ -1,4 +1,4 @@
1
- contractVersion: "143"
1
+ contractVersion: "151"
2
2
  componentType: connector
3
3
  componentKey: pi
4
4
  label: "PI Connector"
@@ -222,8 +222,8 @@ nothing qualifies. Omit the report when none of these facts apply.
222
222
 
223
223
  #### Writing a human action the operator can complete
224
224
 
225
- Human actions are collected across every mission into the Feed page's **Human actions** rail,
226
- where the operator reads them without the delivery context. Each item must stand alone:
225
+ Human actions are shown on the delivery card, where the operator reads them without your
226
+ session transcript. Each item must stand alone:
227
227
 
228
228
  | Field | Expected | What to write |
229
229
  | ---------- | ---------- | ------------------------------------------------------------------------------------------------- |
@@ -241,7 +241,7 @@ Vague (the operator has to rediscover everything):
241
241
  { "action": "Set up the env var for Gemini." }
242
242
  ```
243
243
 
244
- Good (the operator can finish it from the rail alone):
244
+ Good (the operator can finish it from the card alone):
245
245
 
246
246
  ```json
247
247
  {
@@ -1228,7 +1228,7 @@ process.stdin.on('data', async chunk => {
1228
1228
  result: {
1229
1229
  protocolVersion: PROTOCOL_VERSION,
1230
1230
  capabilities: { tools: { listChanged: false } },
1231
- serverInfo: { name: 'overlord-__OVERLORD_ADAPTER_KEY__', version: '0.3.48' }
1231
+ serverInfo: { name: 'overlord-__OVERLORD_ADAPTER_KEY__', version: '0.3.49' }
1232
1232
  }
1233
1233
  });
1234
1234
  continue;
package/dist/index.js CHANGED
@@ -4137,6 +4137,7 @@ var init_setup = __esm({
4137
4137
  var user_token_exports = {};
4138
4138
  __export(user_token_exports, {
4139
4139
  durationToIso: () => durationToIso,
4140
+ projectFlags: () => projectFlags,
4140
4141
  runUserTokenCommand: () => runUserTokenCommand
4141
4142
  });
4142
4143
  function durationToIso(value, now = Date.now()) {
@@ -4176,10 +4177,28 @@ function normalizeScope(raw) {
4176
4177
  const value = raw.trim().toLowerCase();
4177
4178
  if (value === "full") return "full";
4178
4179
  if (value === "mission-lifecycle" || value === "mission_lifecycle") return "mission_lifecycle";
4180
+ if (value === "project-automation" || value === "project_automation") return "project_automation";
4179
4181
  throw new CliError({
4180
- message: `Unknown --scope '${raw}'. Use 'full' or 'mission-lifecycle'.`
4182
+ message: `Unknown --scope '${raw}'. Use 'full', 'mission-lifecycle', or 'project-automation'.`
4181
4183
  });
4182
4184
  }
4185
+ function projectFlags(args) {
4186
+ const projects = [];
4187
+ for (let i = 0; i < args.length; i += 1) {
4188
+ const arg = args[i];
4189
+ if (arg === "--project") {
4190
+ const value = args[++i];
4191
+ if (!value || value.startsWith("--"))
4192
+ throw new CliError({ message: "--project requires an ID or name" });
4193
+ projects.push(value);
4194
+ } else if (arg?.startsWith("--project=")) {
4195
+ const value = arg.slice("--project=".length);
4196
+ if (!value) throw new CliError({ message: "--project requires an ID or name" });
4197
+ projects.push(value);
4198
+ }
4199
+ }
4200
+ return projects;
4201
+ }
4183
4202
  function formatDate(iso) {
4184
4203
  return iso ?? "\u2014";
4185
4204
  }
@@ -4194,6 +4213,8 @@ function printTokenTable(tokens) {
4194
4213
  `${token.tokenPrefix}\u2026 ${token.status.padEnd(8)} ${token.scope.padEnd(16)} ${expiry} ${token.label}`
4195
4214
  );
4196
4215
  console.log(` id: ${token.id}`);
4216
+ if (token.projects.length)
4217
+ console.log(` projects: ${token.projects.map((project) => project.name).join(", ")}`);
4197
4218
  }
4198
4219
  }
4199
4220
  async function runUserTokenCommand({ rest }) {
@@ -4208,6 +4229,15 @@ async function runUserTokenCommand({ rest }) {
4208
4229
  throw new CliError({ message: 'A label is required: --label "macbook runner".' });
4209
4230
  }
4210
4231
  const scope = normalizeScope(flagValue(parsed.flags, "--scope"));
4232
+ const selectedProjects = projectFlags(subArgs);
4233
+ if (scope === "project_automation" && selectedProjects.length === 0) {
4234
+ throw new CliError({
4235
+ message: "Project automation tokens require at least one --project."
4236
+ });
4237
+ }
4238
+ if (scope !== "project_automation" && selectedProjects.length > 0) {
4239
+ throw new CliError({ message: "--project requires --scope project-automation." });
4240
+ }
4211
4241
  let expiresAt;
4212
4242
  if (flagBoolean(parsed.flags, "--no-expiry")) {
4213
4243
  expiresAt = null;
@@ -4218,6 +4248,21 @@ async function runUserTokenCommand({ rest }) {
4218
4248
  const body = { label: label.trim() };
4219
4249
  if (expiresAt !== void 0) body.expiresAt = expiresAt;
4220
4250
  if (scope !== void 0) body.scope = scope;
4251
+ if (scope === "project_automation") {
4252
+ const projects = await backend.get(
4253
+ "/api/projects?lifecycle=all"
4254
+ );
4255
+ body.projectIds = selectedProjects.map((selection) => {
4256
+ const matches = projects.filter(
4257
+ (project) => project.id === selection || project.name.toLowerCase() === selection.toLowerCase()
4258
+ );
4259
+ if (matches.length !== 1)
4260
+ throw new CliError({
4261
+ message: `Project '${selection}' must identify one authorized project; use its ID if ambiguous.`
4262
+ });
4263
+ return matches[0].id;
4264
+ });
4265
+ }
4221
4266
  const result = await backend.post({
4222
4267
  path: "/api/user-tokens",
4223
4268
  body
@@ -4231,9 +4276,16 @@ async function runUserTokenCommand({ rest }) {
4231
4276
  `);
4232
4277
  console.log(` label: ${result.token.label}`);
4233
4278
  console.log(` scope: ${result.token.scope}`);
4279
+ if (result.token.projects.length)
4280
+ console.log(` projects: ${result.token.projects.map((project) => project.name).join(", ")}`);
4234
4281
  console.log(
4235
4282
  ` expiry: ${result.token.expiresAt ? formatDate(result.token.expiresAt) : "no expiry"}`
4236
4283
  );
4284
+ if (result.token.scope === "project_automation" && result.token.expiresAt) {
4285
+ console.log(
4286
+ " Renew this automation token before it expires, or choose --no-expiry when creating its replacement."
4287
+ );
4288
+ }
4237
4289
  console.log("\nAuthenticate with: ovld auth login --token <secret>");
4238
4290
  return;
4239
4291
  }
@@ -38714,8 +38766,8 @@ deliver:
38714
38766
  "link": ".env.example" // when known. HTTP(S) URL or repo-relative path only.
38715
38767
  }
38716
38768
  Vague: { "action": "Set up the env var for Gemini." } forces the operator to rediscover
38717
- the name, the place, and the check. Actions are read from the Feed rail without the
38718
- delivery, so each must stand alone. Overlord adds deterministic_rule actions for new
38769
+ the name, the place, and the check. Actions are read from the delivery card without
38770
+ your transcript, so each must stand alone. Overlord adds deterministic_rule actions for new
38719
38771
  migrations, .env.example edits, dependency manifests, and CI workflow files on its own;
38720
38772
  report those yourself when you can supply the real command and verify step.
38721
38773
  Optional:
@@ -41693,7 +41745,7 @@ var COMMAND_FLAGS = {
41693
41745
  "agent-setup": ["--dry-run", "--home", "--export"],
41694
41746
  config: ["--path", "--url"],
41695
41747
  auth: ["--token", "--organization-id"],
41696
- "user-token": ["--label", "--expires-in", "--no-expiry", "--scope", "--id"],
41748
+ "user-token": ["--label", "--expires-in", "--no-expiry", "--scope", "--project", "--id"],
41697
41749
  prune: [],
41698
41750
  "agent-session": AGENT_SESSION_FLAGS,
41699
41751
  "create-project": ["--name", "--directory", "--no-directory"],