orbitmap 0.4.2 → 0.4.4
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 +112 -18
- package/dist/adapters/cloud.d.ts +63 -21
- package/dist/adapters/cloud.js +108 -29
- package/dist/adapters/cloud.js.map +1 -1
- package/dist/adapters/factory.d.ts +3 -0
- package/dist/adapters/factory.js +8 -1
- package/dist/adapters/factory.js.map +1 -1
- package/dist/adapters/local/adapter.d.ts +17 -20
- package/dist/adapters/local/adapter.js +28 -21
- package/dist/adapters/local/adapter.js.map +1 -1
- package/dist/adapters/local/context.d.ts +1 -1
- package/dist/adapters/local/context.js +10 -2
- package/dist/adapters/local/context.js.map +1 -1
- package/dist/adapters/local/entities/planning.d.ts +5 -1
- package/dist/adapters/local/entities/planning.js +16 -3
- package/dist/adapters/local/entities/planning.js.map +1 -1
- package/dist/adapters/local/entities/tasks.d.ts +9 -1
- package/dist/adapters/local/entities/tasks.js +47 -5
- package/dist/adapters/local/entities/tasks.js.map +1 -1
- package/dist/adapters/local/entities/work-items.d.ts +14 -30
- package/dist/adapters/local/entities/work-items.js +63 -47
- package/dist/adapters/local/entities/work-items.js.map +1 -1
- package/dist/adapters/local/rules.d.ts +4 -4
- package/dist/adapters/local/rules.js +4 -19
- package/dist/adapters/local/rules.js.map +1 -1
- package/dist/adapters/local/shapes.d.ts +27 -7
- package/dist/adapters/local/shapes.js +41 -5
- package/dist/adapters/local/shapes.js.map +1 -1
- package/dist/adapters/local/store.d.ts +55 -6
- package/dist/adapters/local/store.js +122 -8
- package/dist/adapters/local/store.js.map +1 -1
- package/dist/adapters/local/types.d.ts +11 -2
- package/dist/adapters/local/types.js +9 -2
- package/dist/adapters/local/types.js.map +1 -1
- package/dist/adapters/types.d.ts +30 -20
- package/dist/agent-instructions.d.ts +43 -12
- package/dist/agent-instructions.js +1133 -170
- package/dist/agent-instructions.js.map +1 -1
- package/dist/area-directories.d.ts +75 -0
- package/dist/area-directories.js +162 -0
- package/dist/area-directories.js.map +1 -0
- package/dist/area-grouping.d.ts +55 -0
- package/dist/area-grouping.js +72 -0
- package/dist/area-grouping.js.map +1 -0
- package/dist/commands/areas.js +30 -2
- package/dist/commands/areas.js.map +1 -1
- package/dist/commands/assign.d.ts +1 -0
- package/dist/commands/assign.js +2 -0
- package/dist/commands/assign.js.map +1 -1
- package/dist/commands/context.d.ts +95 -0
- package/dist/commands/context.js +104 -2
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +19 -14
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/dep.js +5 -8
- package/dist/commands/dep.js.map +1 -1
- package/dist/commands/doc-import.d.ts +1 -0
- package/dist/commands/doc-import.js +8 -26
- package/dist/commands/doc-import.js.map +1 -1
- package/dist/commands/doc-patch.js +16 -52
- package/dist/commands/doc-patch.js.map +1 -1
- package/dist/commands/doc-share.js +4 -0
- package/dist/commands/doc-share.js.map +1 -1
- package/dist/commands/doc-update.js +4 -8
- package/dist/commands/doc-update.js.map +1 -1
- package/dist/commands/doc.js +7 -12
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/docs-cache.js +23 -10
- package/dist/commands/docs-cache.js.map +1 -1
- package/dist/commands/docs.js +29 -10
- package/dist/commands/docs.js.map +1 -1
- package/dist/commands/get.js +8 -10
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/ideas.d.ts +3 -1
- package/dist/commands/ideas.js +26 -49
- package/dist/commands/ideas.js.map +1 -1
- package/dist/commands/init.d.ts +24 -1
- package/dist/commands/init.js +0 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/intent.d.ts +16 -0
- package/dist/commands/intent.js +61 -18
- package/dist/commands/intent.js.map +1 -1
- package/dist/commands/issues.d.ts +3 -1
- package/dist/commands/issues.js +47 -72
- package/dist/commands/issues.js.map +1 -1
- package/dist/commands/log.d.ts +14 -2
- package/dist/commands/log.js +35 -20
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/mission.d.ts +8 -0
- package/dist/commands/mission.js +58 -18
- package/dist/commands/mission.js.map +1 -1
- package/dist/commands/orbit.d.ts +7 -1
- package/dist/commands/orbit.js +13 -24
- package/dist/commands/orbit.js.map +1 -1
- package/dist/commands/setup-agent.d.ts +97 -4
- package/dist/commands/setup-agent.js +273 -40
- package/dist/commands/setup-agent.js.map +1 -1
- package/dist/commands/setup-mcp.d.ts +2 -0
- package/dist/commands/setup-mcp.js +17 -40
- package/dist/commands/setup-mcp.js.map +1 -1
- package/dist/commands/start.d.ts +43 -0
- package/dist/commands/start.js +158 -3
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +5 -15
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/subtask.d.ts +1 -0
- package/dist/commands/subtask.js +9 -2
- package/dist/commands/subtask.js.map +1 -1
- package/dist/commands/task-edit-content.js +4 -8
- package/dist/commands/task-edit-content.js.map +1 -1
- package/dist/commands/task.d.ts +7 -0
- package/dist/commands/task.js +5 -2
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/tasks.d.ts +35 -0
- package/dist/commands/tasks.js +45 -9
- package/dist/commands/tasks.js.map +1 -1
- package/dist/commands/vibes.d.ts +3 -1
- package/dist/commands/vibes.js +41 -31
- package/dist/commands/vibes.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.js +14 -1
- package/dist/config.js.map +1 -1
- package/dist/doc-cache.d.ts +74 -5
- package/dist/doc-cache.js +106 -22
- package/dist/doc-cache.js.map +1 -1
- package/dist/enums.d.ts +26 -0
- package/dist/enums.js +53 -0
- package/dist/enums.js.map +1 -0
- package/dist/errors.d.ts +67 -0
- package/dist/errors.js +82 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.js +169 -60
- package/dist/index.js.map +1 -1
- package/dist/mcp-config.d.ts +42 -1
- package/dist/mcp-config.js +82 -2
- package/dist/mcp-config.js.map +1 -1
- package/dist/oauth.js +10 -10
- package/dist/output.d.ts +12 -0
- package/dist/output.js +39 -1
- package/dist/output.js.map +1 -1
- package/dist/paths.d.ts +40 -0
- package/dist/paths.js +174 -9
- package/dist/paths.js.map +1 -1
- package/dist/project-config.d.ts +42 -1
- package/dist/project-config.js +51 -0
- package/dist/project-config.js.map +1 -1
- package/dist/work-log.d.ts +104 -0
- package/dist/work-log.js +181 -0
- package/dist/work-log.js.map +1 -0
- package/dist/workspace-resolve.d.ts +179 -9
- package/dist/workspace-resolve.js +288 -20
- package/dist/workspace-resolve.js.map +1 -1
- package/dist/write-target.d.ts +56 -0
- package/dist/write-target.js +170 -0
- package/dist/write-target.js.map +1 -0
- package/package.json +3 -2
- package/dist/commands/create-project.d.ts +0 -6
- package/dist/commands/create-project.js +0 -28
- package/dist/commands/create-project.js.map +0 -1
- package/dist/commands/projects.d.ts +0 -3
- package/dist/commands/projects.js +0 -28
- package/dist/commands/projects.js.map +0 -1
package/README.md
CHANGED
|
@@ -94,7 +94,8 @@ for the local path.
|
|
|
94
94
|
missions/MS-<num>.md
|
|
95
95
|
intents/IN-<num>.md
|
|
96
96
|
ideas/ID-<num>.md
|
|
97
|
-
|
|
97
|
+
docs/<slug>.md # one copy of each document, same path and format as the
|
|
98
|
+
# cloud doc cache (`<project>/.orbitmap/docs/`)
|
|
98
99
|
issues/IS-<num>.md # workspace-level issues (no area)
|
|
99
100
|
areas/
|
|
100
101
|
<area-slug>/
|
|
@@ -194,10 +195,15 @@ pass `--type task|issue|idea|intent` for bare UUIDs and bare codes.
|
|
|
194
195
|
|
|
195
196
|
| Command | Description |
|
|
196
197
|
|---------|-------------|
|
|
197
|
-
| `orbitmap log <id-or-number> <message>` | Log work on a task |
|
|
198
|
+
| `orbitmap log <id-or-number> <message>` | Log work on a task, intent or mission |
|
|
199
|
+
|
|
200
|
+
The target follows from the reference: `TS-…` writes against the task, `IN-…` against the
|
|
201
|
+
intent, `MS-…` against the mission. A bare UUID or bare code means a **task** unless
|
|
202
|
+
`--target` says otherwise.
|
|
198
203
|
|
|
199
204
|
**Options:**
|
|
200
|
-
- `--type <type>` — Log type: `note` (default), `code_change`, `decision`, `blocker
|
|
205
|
+
- `--type <type>` — Log type: `note` (default), `code_change`, `decision`, `blocker`. For `discovery`, `exploration` and `fix` use `orbitmap vibe log` — those are vibe types, not work-log types. `status_change` is written by the server on a status change and cannot be authored by a client.
|
|
206
|
+
- `--target <kind>` — Which object a bare UUID names: `task` (default), `intent`, `mission`
|
|
201
207
|
- `--meta <json>` — JSON metadata, e.g. `'{"files":["src/app.ts"]}'`
|
|
202
208
|
|
|
203
209
|
**Examples:**
|
|
@@ -205,8 +211,25 @@ pass `--type task|issue|idea|intent` for bare UUIDs and bare codes.
|
|
|
205
211
|
orbitmap log abc123 "Implemented user auth endpoint" --type code_change
|
|
206
212
|
orbitmap log abc123 "Using JWT over sessions for stateless auth" --type decision
|
|
207
213
|
orbitmap log abc123 "Blocked on missing API credentials" --type blocker
|
|
214
|
+
orbitmap log IN-a1b2c3 "Chose 3 FKs + a CHECK over a polymorphic target" --type decision
|
|
215
|
+
orbitmap log MS-a1b2c3 "Mission scope trimmed to the two gating intents" --type note
|
|
208
216
|
```
|
|
209
217
|
|
|
218
|
+
#### Work log entries on a status change
|
|
219
|
+
|
|
220
|
+
`intent update`, `mission update` and `mission status` take a **repeatable** `--log
|
|
221
|
+
<type>:<content>`, sent as one batch with the update. The content is split on the FIRST
|
|
222
|
+
colon only, so it may contain colons of its own.
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
orbitmap intent update IN-a1b2c3 --status plan \
|
|
226
|
+
--log decision:"chose 3 FKs + CHECK" \
|
|
227
|
+
--log note:"resume: CLI next"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The API **requires at least one entry when the status changes** and writes nothing at all
|
|
231
|
+
when there is none — so a rejected transition is re-run with `--log`, not retried as-is.
|
|
232
|
+
|
|
210
233
|
### Documents
|
|
211
234
|
|
|
212
235
|
| Command | Description |
|
|
@@ -287,8 +310,8 @@ Workspace-level desired outcomes. Tasks and issues hang off an intent; an intent
|
|
|
287
310
|
|---------|-------------|
|
|
288
311
|
| `orbitmap intents` | List intents (shortcut for `intent list`) |
|
|
289
312
|
| `orbitmap intent show <id-or-number>` | Show an intent (UUID or `IN-xxxxxx`) |
|
|
290
|
-
| `orbitmap intent create <title>` | Create an intent (`--outcome`, `--status`, `--orbit`) |
|
|
291
|
-
| `orbitmap intent update <id>` | Update title, outcome, or status |
|
|
313
|
+
| `orbitmap intent create <title>` | Create an intent (`--outcome`, `--design`, `--plan`, `--status`, `--orbit`) |
|
|
314
|
+
| `orbitmap intent update <id>` | Update title, outcome, design, plan, or status (`--log <type>:<content>`, repeatable) |
|
|
292
315
|
| `orbitmap intent link <id> --type task\|issue --id <uuid>` | Link a task or issue |
|
|
293
316
|
| `orbitmap intent unlink <id> --type task\|issue --id <uuid>` | Unlink a task or issue |
|
|
294
317
|
| `orbitmap intent orbit <id> [orbit-id]` | Set the intent's orbit (`--clear` to remove) |
|
|
@@ -298,9 +321,16 @@ Workspace-level desired outcomes. Tasks and issues hang off an intent; an intent
|
|
|
298
321
|
```bash
|
|
299
322
|
orbitmap intent create "Cut onboarding time in half" \
|
|
300
323
|
--outcome "New users reach first value in under 5 minutes" \
|
|
324
|
+
--design "Two-step wizard replacing the current five-step form." \
|
|
325
|
+
--plan "Phase 1: wizard skeleton. Phase 2: inline validation." \
|
|
301
326
|
--status design --orbit growth-q3
|
|
302
327
|
|
|
303
328
|
orbitmap intent link IN-a1b2c3 --type task --id <task-uuid>
|
|
329
|
+
|
|
330
|
+
# A status change carries its reason — the API rejects it (422) without at least one entry.
|
|
331
|
+
orbitmap intent update IN-a1b2c3 --status plan \
|
|
332
|
+
--log decision:"chose 3 FKs + CHECK" \
|
|
333
|
+
--log note:"resume: CLI next"
|
|
304
334
|
```
|
|
305
335
|
|
|
306
336
|
`intent create --orbit` is create-then-attach. If the attach step fails the intent is still created — the CLI reports the failure and does not retry.
|
|
@@ -314,8 +344,8 @@ Time-boxed workspace focus. Only one mission can be `active` at a time.
|
|
|
314
344
|
| `orbitmap missions` | List missions (shortcut for `mission list`) |
|
|
315
345
|
| `orbitmap mission show <id-or-number>` | Show a mission (UUID or `MS-xxxxxx`) |
|
|
316
346
|
| `orbitmap mission create <title>` | Create a mission (`--desc`, `--outcome`, `--end-date`) |
|
|
317
|
-
| `orbitmap mission update <id>` | Update title, description, outcome, or end date |
|
|
318
|
-
| `orbitmap mission status <id> <status>` | Set lifecycle status (`--move-to` to relocate unfinished work) |
|
|
347
|
+
| `orbitmap mission update <id>` | Update title, description, outcome, or end date (`--log <type>:<content>`, repeatable) |
|
|
348
|
+
| `orbitmap mission status <id> <status>` | Set lifecycle status (`--move-to` to relocate unfinished work; `--log` required by the API) |
|
|
319
349
|
| `orbitmap mission link <id> --type <t> --id <uuid>` | Link a task, issue, idea, or intent |
|
|
320
350
|
| `orbitmap mission unlink <id> --type <t> --id <uuid>` | Unlink a directly-linked item |
|
|
321
351
|
|
|
@@ -369,7 +399,7 @@ orbitmap status abc123 done --delivery released
|
|
|
369
399
|
|
|
370
400
|
| Command | Description |
|
|
371
401
|
|---------|-------------|
|
|
372
|
-
| `orbitmap init` | Full setup — mode, then
|
|
402
|
+
| `orbitmap init` | Full setup — mode, then the workspace + its area directories (cloud) or a local workspace, then `.mcp.json` and the agent skills (`--key`, `--workspace-id`, `--area`, `--profile`, `--allow-nested`, `--advanced`, `--global`; `--local`, `--workspace`, `--workspace-name`; `--agent <type>`, `--no-skills`) |
|
|
373
403
|
| `orbitmap login` / `orbitmap logout` | Browser-based OAuth login / token revocation |
|
|
374
404
|
| `orbitmap setup-agent` | Refresh the installed instructions (after a CLI upgrade) or add another agent type — `init` installs them once already |
|
|
375
405
|
| `orbitmap setup-mcp` | Write/merge an `orbitmap` entry into `.mcp.json` (no API calls) |
|
|
@@ -390,11 +420,15 @@ that, see the ADR's Consequences section).
|
|
|
390
420
|
|
|
391
421
|
### Setup
|
|
392
422
|
|
|
393
|
-
Run `npx orbitmap init` for interactive setup.
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
423
|
+
Run `npx orbitmap init` for interactive setup. Cloud setup is **workspace-first**: the key is
|
|
424
|
+
validated with `GET /areas`, you pick the workspace (`--workspace-id` in a script), and `init`
|
|
425
|
+
works out which directory holds which area — by directory name, by the `origin` git remote
|
|
426
|
+
matched against the area's repository URL, by the slugified name, or by asking. It writes
|
|
427
|
+
`<root>/.orbitmap/config.json` (committable, no secrets) by default; pass `--global` to write
|
|
428
|
+
`~/.orbitmap/config.json` instead (a machine-wide default, like `git config --global`). The API
|
|
429
|
+
key always goes to `~/.orbitmap/credentials.json`, under a named **agent profile** — never into
|
|
430
|
+
a config file, either way. Re-running `init` merges, so running it inside a newly cloned area
|
|
431
|
+
adds that area to the workspace map that already exists above it.
|
|
398
432
|
|
|
399
433
|
### Project config file — `<project>/.orbitmap/config.json`
|
|
400
434
|
|
|
@@ -403,15 +437,22 @@ never into a config file, either way.
|
|
|
403
437
|
"schema_version": 1,
|
|
404
438
|
"mode": "cloud",
|
|
405
439
|
"agent": "orbitmap-app-bot",
|
|
406
|
-
"
|
|
440
|
+
"workspace": "my-workspace",
|
|
441
|
+
"areas": { "orbitmap-cli": "orbitmap-cli", "packages/api": "api" }
|
|
407
442
|
}
|
|
408
443
|
```
|
|
409
444
|
|
|
410
445
|
`mode` is `"cloud"` (the default when the key is absent) or `"local"`. `agent` names a
|
|
411
446
|
profile in `~/.orbitmap/credentials.json` — the project says *which* agent to use, the
|
|
412
|
-
credentials file (below) holds *that agent's* key.
|
|
413
|
-
|
|
414
|
-
|
|
447
|
+
credentials file (below) holds *that agent's* key. `workspace` is a workspace slug or UUID,
|
|
448
|
+
never a path. `areas` maps directories (relative to this file's parent; `"."` is that
|
|
449
|
+
directory) to area slugs, which is how one root can hold several areas; each mapped
|
|
450
|
+
subdirectory also gets a marker config of its own holding nothing but `{"area": "<slug>"}`.
|
|
451
|
+
The older single `area` field is still read for back-compat. This file is meant to be
|
|
452
|
+
committed: a team shares the workspace, the `agent` name and the area layout through version
|
|
453
|
+
control, and each member's own copy of `credentials.json` supplies their own agent's key.
|
|
454
|
+
Areas living **outside** the tree cannot be expressed portably, so they go to the gitignored
|
|
455
|
+
`<root>/.orbitmap/link.json` instead (`"areas": { "<slug>": "/abs/path" }`).
|
|
415
456
|
|
|
416
457
|
### Global config file — `~/.orbitmap/config.json`
|
|
417
458
|
|
|
@@ -528,13 +569,66 @@ npx orbitmap setup-agent # auto-detects your agent
|
|
|
528
569
|
npx orbitmap setup-agent --agent claude
|
|
529
570
|
```
|
|
530
571
|
|
|
572
|
+
### Where it installs: `--scope user` (global) vs `--scope project`
|
|
573
|
+
|
|
574
|
+
Run interactively, both commands **ask** where the skills should go — global (your home directory)
|
|
575
|
+
or project (this directory only) — right after the agent-type question. Global is recommended and
|
|
576
|
+
is what Enter picks; `--scope` skips the question; a scripted run takes global without prompting
|
|
577
|
+
and says so in its output.
|
|
578
|
+
|
|
579
|
+
Global (user) scope means `~/.claude/skills/` and `~/.claude/CLAUDE.md`
|
|
580
|
+
for Claude Code, `~/.gemini/GEMINI.md` and `~/.codex/AGENTS.md` for Gemini and Codex. Agent skills
|
|
581
|
+
do **not** traverse directories: a project-level `.claude/skills/` is invisible to a session
|
|
582
|
+
started in a sibling or child repository, while `CLAUDE.md` *is* inherited downwards. A user-scope
|
|
583
|
+
install is the only one that is consistent everywhere — and it matters now that one workspace
|
|
584
|
+
routinely spans several area directories, where a single project install would cover just one.
|
|
585
|
+
|
|
586
|
+
A user-scope install writes **nothing** into your project directory.
|
|
587
|
+
|
|
588
|
+
```bash
|
|
589
|
+
npx orbitmap setup-agent --scope project # this directory only (the old behaviour)
|
|
590
|
+
npx orbitmap init --agent claude --scope project
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
At project scope the hook says so explicitly, so an agent that inherits `CLAUDE.md` from a parent
|
|
594
|
+
directory but cannot load the skills knows why, and knows to re-run with `--scope user`.
|
|
595
|
+
|
|
596
|
+
**Upgrading from an older setup?** If you already have skills in `./.claude/skills/`, that project
|
|
597
|
+
copy silently wins in this directory. A user-scope install detects it and names the paths; it
|
|
598
|
+
offers to clean up when run interactively, and otherwise tells you to run:
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
npx orbitmap setup-agent --agent claude --scope user --clean-project
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
Cleanup removes only the six OrbitMap skill directories and OrbitMap's own marker block — never
|
|
605
|
+
your own skills, never unrelated `CLAUDE.md` content, never a whole `.claude` directory.
|
|
606
|
+
|
|
531
607
|
Either way it installs two layers, mirroring the OrbitMap MCP server:
|
|
532
608
|
|
|
533
609
|
- A **thin always-on hook** (~10 lines) in your agent config (`CLAUDE.md`, `AGENTS.md`, …) so the agent always knows the project uses OrbitMap and knows the workflow skeleton.
|
|
534
|
-
- The **deep, on-demand instructions** — full parity with the MCP `full` profile. For **Claude Code** these are installed as loaded-on-demand skills (
|
|
610
|
+
- The **deep, on-demand instructions** — full parity with the MCP `full` profile (plus `orbitmap-brainstorm` and `orbitmap-design`, CLI-native, no MCP counterpart). For **Claude Code** these are installed as loaded-on-demand skills (`orbitmap`, `orbitmap-execute`, `orbitmap-plan`, `orbitmap-brainstorm`, `orbitmap-design`, `orbitmap-docs`, zero per-turn context cost) under `~/.claude/skills/` (or `./.claude/skills/` at project scope); for other agents they're inlined as a markdown fallback.
|
|
611
|
+
|
|
612
|
+
A skill is not always a single file: `orbitmap-execute` ships `SKILL.md` **plus**
|
|
613
|
+
`references/worker-contract.md` (the rules a dispatched worker subagent follows). `init` and
|
|
614
|
+
`setup-agent` install every file a skill carries, and refresh them all on a re-run.
|
|
535
615
|
|
|
536
616
|
The instructions are mode-agnostic: they reference CLI commands only, so the same skills drive an agent whether the data goes to the cloud or to local files.
|
|
537
617
|
|
|
618
|
+
### Executing work: two flows
|
|
619
|
+
|
|
620
|
+
The installed `orbitmap-execute` skill covers two ways of working, chosen by what you ask for:
|
|
621
|
+
|
|
622
|
+
- **"work on TS-x"** runs a single tracked task — start or resume it, implement, log, and
|
|
623
|
+
finish with the correct status (`in_review` by default, so a human verifies before closing).
|
|
624
|
+
- **"execute IN-x"** delivers a **whole planned intent** in the background: tasks are built by
|
|
625
|
+
parallel workers in dependency-ordered waves, each task gated by its own tests, then the
|
|
626
|
+
intent-level test and an impact pass diffed against a test baseline captured before the run,
|
|
627
|
+
with a goal-based fix loop (no retry cap) until the gates are green. A stuck task ends
|
|
628
|
+
`blocked` with a logged blocker while the rest of the intent completes. The run ends with
|
|
629
|
+
every completed task `in_review` on an `intent/<number>-<slug>` branch — **merging is left
|
|
630
|
+
to you**: the run never merges and never pushes to the default branch.
|
|
631
|
+
|
|
538
632
|
See [Agent Instructions](docs/agent-instructions.md) for details.
|
|
539
633
|
|
|
540
634
|
## Requirements
|
package/dist/adapters/cloud.d.ts
CHANGED
|
@@ -1,17 +1,40 @@
|
|
|
1
1
|
import { type OrbitMapConfig } from '../config.js';
|
|
2
|
+
import type { WorkLogEntry } from '../work-log.js';
|
|
2
3
|
import type { WorkspaceAdapter } from './types.js';
|
|
3
4
|
export declare class CloudAdapter implements WorkspaceAdapter {
|
|
4
5
|
private readonly apiKey;
|
|
5
6
|
private readonly baseUrl;
|
|
6
7
|
private readonly area?;
|
|
8
|
+
/**
|
|
9
|
+
* Workspace **identity** (slug or uuid, never a path) from the separate workspace ladder
|
|
10
|
+
* (`--workspace-id` → `ORBITMAP_WORKSPACE_ID` → project config `workspace` → global config
|
|
11
|
+
* `workspace`; see `resolveWorkspaceId`). Independent of {@link CloudAdapter.area}: either,
|
|
12
|
+
* both or neither may be set.
|
|
13
|
+
*/
|
|
14
|
+
private readonly workspace?;
|
|
7
15
|
/**
|
|
8
16
|
* Task reference → uuid, for the lifetime of this adapter. A command that touches the same
|
|
9
17
|
* task twice (`dep add TS-a TS-b` resolves two, `status` then reads back) pays for one
|
|
10
18
|
* `/tasks/by-number/{n}` lookup per distinct reference, not per call site.
|
|
11
19
|
*/
|
|
12
20
|
private readonly taskIdCache;
|
|
13
|
-
constructor(apiKey: string, area?: string, apiUrl?: string);
|
|
21
|
+
constructor(apiKey: string, area?: string, apiUrl?: string, workspace?: string);
|
|
14
22
|
private request;
|
|
23
|
+
/**
|
|
24
|
+
* Add the client half of the story to the workspace-context errors the server can raise.
|
|
25
|
+
* The API knows what it received; only the CLI knows what it *sent* and which knobs could
|
|
26
|
+
* change that, and a bare "workspace context is required" is unactionable without it.
|
|
27
|
+
* Every other error is returned untouched.
|
|
28
|
+
*
|
|
29
|
+
* `AREA_CONTEXT_REQUIRED` is here too (TS-jt6q36 follow-up). The CLI raises that code
|
|
30
|
+
* itself — with the areas of the current workspace spelled out — but the *server* raises
|
|
31
|
+
* it as well, in HTTP terms ("set the X-Orbitmap-Area header. Call GET /api/agent/areas"),
|
|
32
|
+
* and that text used to reach the terminal verbatim: identical situation, two different
|
|
33
|
+
* answers depending on which side noticed first. The client-side advice is now attached to
|
|
34
|
+
* both, and the server's own sentence is kept (parenthesised) rather than dropped, because
|
|
35
|
+
* it is the only part that says what the API actually objected to.
|
|
36
|
+
*/
|
|
37
|
+
private explainContextError;
|
|
15
38
|
getContext(areaId?: string): Promise<unknown>;
|
|
16
39
|
/**
|
|
17
40
|
* The area this client was constructed with (`--area` → `ORBITMAP_AREA` →
|
|
@@ -20,6 +43,12 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
20
43
|
* `workspace-resolve.ts`, applied by `createClient`). No request is made.
|
|
21
44
|
*/
|
|
22
45
|
getDefaultArea(): Promise<string | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* The workspace identity this client sends as `X-Orbitmap-Workspace`, or `undefined` when
|
|
48
|
+
* none resolved (in which case the server derives one from the area or auto-detects it).
|
|
49
|
+
* No request is made.
|
|
50
|
+
*/
|
|
51
|
+
getWorkspaceId(): string | undefined;
|
|
23
52
|
getTasks(options?: {
|
|
24
53
|
status?: string;
|
|
25
54
|
priority?: string;
|
|
@@ -78,6 +107,8 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
78
107
|
}): Promise<unknown>;
|
|
79
108
|
removeTaskDependency(taskId: string, targetTaskId: string, type?: string): Promise<unknown>;
|
|
80
109
|
logWork(taskId: string, type: string, content: string, metadata?: Record<string, unknown>): Promise<unknown>;
|
|
110
|
+
logIntentWork(idOrNumber: string, type: string, content: string, metadata?: Record<string, unknown>): Promise<unknown>;
|
|
111
|
+
logMissionWork(idOrNumber: string, type: string, content: string, metadata?: Record<string, unknown>): Promise<unknown>;
|
|
81
112
|
getDocuments(options?: {
|
|
82
113
|
type?: string;
|
|
83
114
|
search?: string;
|
|
@@ -192,28 +223,21 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
192
223
|
severity?: string;
|
|
193
224
|
limit?: string;
|
|
194
225
|
}): Promise<unknown>;
|
|
226
|
+
/**
|
|
227
|
+
* `GET /issues/{id_or_number}` — the single issue-read route. It accepts a uuid, a bare
|
|
228
|
+
* six-char code or the prefixed `IS-xxxxxx` form; the server strips the prefix and resolves
|
|
229
|
+
* the number workspace-scoped. There is no `/issues/by-number/{n}` route — never add one.
|
|
230
|
+
*/
|
|
195
231
|
getIssue(idOrNumber: string): Promise<unknown>;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
resolved_by_task_id?: string;
|
|
201
|
-
}): Promise<unknown>;
|
|
202
|
-
resolveIssue(idOrNumber: string, data: {
|
|
203
|
-
status: string;
|
|
204
|
-
resolution?: string;
|
|
205
|
-
resolved_by_task_id?: string;
|
|
206
|
-
}): Promise<unknown>;
|
|
232
|
+
/**
|
|
233
|
+
* `PATCH /issues/{id_or_number}/status` — the only issue-write route besides `/link` and
|
|
234
|
+
* `/assign`. `issue resolve` rides on it too: the API has no `/issues/{id}/resolve`.
|
|
235
|
+
*/
|
|
207
236
|
updateIssueStatus(idOrNumber: string, data: {
|
|
208
237
|
status: string;
|
|
209
238
|
resolution?: string;
|
|
210
239
|
resolved_task_id?: string;
|
|
211
240
|
}): Promise<unknown>;
|
|
212
|
-
updateIssueStatusByNumber(issueNumber: string, data: {
|
|
213
|
-
status: string;
|
|
214
|
-
resolution?: string;
|
|
215
|
-
resolved_task_id?: string;
|
|
216
|
-
}): Promise<unknown>;
|
|
217
241
|
logVibe(data: {
|
|
218
242
|
content: string;
|
|
219
243
|
type: string;
|
|
@@ -237,20 +261,21 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
237
261
|
priority?: string;
|
|
238
262
|
limit?: string;
|
|
239
263
|
}): Promise<unknown>;
|
|
264
|
+
/**
|
|
265
|
+
* `GET /ideas/{id_or_number}` — accepts a uuid, a bare code or `ID-xxxxxx`; the server
|
|
266
|
+
* strips the prefix and resolves the number. There is no `/ideas/by-number/{n}` route.
|
|
267
|
+
*/
|
|
240
268
|
getIdea(idOrNumber: string): Promise<unknown>;
|
|
241
|
-
getIdeaByNumber(ideaNumber: string): Promise<unknown>;
|
|
242
269
|
createIdea(data: {
|
|
243
270
|
content: string;
|
|
244
271
|
title?: string;
|
|
245
272
|
priority?: string;
|
|
246
273
|
metadata?: Record<string, unknown>;
|
|
247
274
|
}): Promise<unknown>;
|
|
275
|
+
/** `PATCH /ideas/{id_or_number}/status`. */
|
|
248
276
|
updateIdeaStatus(idOrNumber: string, data: {
|
|
249
277
|
status: string;
|
|
250
278
|
}): Promise<unknown>;
|
|
251
|
-
updateIdeaStatusByNumber(ideaNumber: string, data: {
|
|
252
|
-
status: string;
|
|
253
|
-
}): Promise<unknown>;
|
|
254
279
|
listOrbits(options?: {
|
|
255
280
|
areaId?: string;
|
|
256
281
|
workspaceId?: string;
|
|
@@ -294,13 +319,18 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
294
319
|
createIntent(data: {
|
|
295
320
|
name: string;
|
|
296
321
|
outcome?: string;
|
|
322
|
+
design?: string;
|
|
323
|
+
plan?: string;
|
|
297
324
|
status?: string;
|
|
298
325
|
area_id?: string;
|
|
299
326
|
}): Promise<unknown>;
|
|
300
327
|
updateIntent(idOrNumber: string, data: {
|
|
301
328
|
name?: string;
|
|
302
329
|
outcome?: string;
|
|
330
|
+
design?: string;
|
|
331
|
+
plan?: string;
|
|
303
332
|
status?: string;
|
|
333
|
+
logs?: WorkLogEntry[];
|
|
304
334
|
}): Promise<unknown>;
|
|
305
335
|
linkIntentItem(idOrNumber: string, data: {
|
|
306
336
|
item_type: string;
|
|
@@ -328,10 +358,12 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
328
358
|
description?: string;
|
|
329
359
|
outcome?: string;
|
|
330
360
|
end_date?: string;
|
|
361
|
+
logs?: WorkLogEntry[];
|
|
331
362
|
}): Promise<unknown>;
|
|
332
363
|
setMissionStatus(idOrNumber: string, data: {
|
|
333
364
|
status: string;
|
|
334
365
|
move_target_mission_id?: string;
|
|
366
|
+
logs?: WorkLogEntry[];
|
|
335
367
|
}): Promise<unknown>;
|
|
336
368
|
linkMissionItem(idOrNumber: string, data: {
|
|
337
369
|
item_type: string;
|
|
@@ -353,6 +385,12 @@ export interface CreateClientOptions {
|
|
|
353
385
|
* once per command instead of twice.
|
|
354
386
|
*/
|
|
355
387
|
area?: string;
|
|
388
|
+
/**
|
|
389
|
+
* Workspace identity already produced by the workspace ladder (`resolveWorkspaceId`, via
|
|
390
|
+
* `resolveWorkspaceContext`). Same reasoning as {@link CreateClientOptions.area}: pass it
|
|
391
|
+
* when the caller has it so the ladder runs once per command.
|
|
392
|
+
*/
|
|
393
|
+
workspace?: string;
|
|
356
394
|
/** Global config the caller already loaded, to avoid a second read of the same file. */
|
|
357
395
|
config?: OrbitMapConfig;
|
|
358
396
|
}
|
|
@@ -363,5 +401,9 @@ export interface CreateClientOptions {
|
|
|
363
401
|
* 0002 §2). `resolveAuth` used to carry a second, shorter copy of it that was missing the
|
|
364
402
|
* `link.json` rung, so a cloud project with a `.orbitmap/link.json` got a different area
|
|
365
403
|
* depending on which entry point it came through.
|
|
404
|
+
*
|
|
405
|
+
* The workspace identity comes from its own, separate ladder (`resolveWorkspaceId`) and is
|
|
406
|
+
* resolved here too: an area is no longer required, so a command run outside every area
|
|
407
|
+
* directory still has a context to send.
|
|
366
408
|
*/
|
|
367
409
|
export declare function createClient(explicitArea?: string, options?: CreateClientOptions): Promise<CloudAdapter>;
|
package/dist/adapters/cloud.js
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import { createReadStream, statSync } from 'node:fs';
|
|
2
2
|
import { basename, extname } from 'node:path';
|
|
3
|
-
import { OrbitMapAPIError } from '../errors.js';
|
|
3
|
+
import { AREA_CONTEXT_REQUIRED, AREA_WORKSPACE_MISMATCH, OrbitMapAPIError, WORKSPACE_CONTEXT_REQUIRED, } from '../errors.js';
|
|
4
4
|
import { loadConfig, resolveAuth, DEFAULT_API_URL } from '../config.js';
|
|
5
|
-
import { resolveArea } from '../workspace-resolve.js';
|
|
5
|
+
import { areaContextHint, ORBITMAP_DIR, resolveArea, resolveWorkspaceId, } from '../workspace-resolve.js';
|
|
6
6
|
import { isObjectNumber, resolveTaskRef, stripPrefix } from '../id-resolve.js';
|
|
7
7
|
export class CloudAdapter {
|
|
8
8
|
apiKey;
|
|
9
9
|
baseUrl;
|
|
10
10
|
area;
|
|
11
|
+
/**
|
|
12
|
+
* Workspace **identity** (slug or uuid, never a path) from the separate workspace ladder
|
|
13
|
+
* (`--workspace-id` → `ORBITMAP_WORKSPACE_ID` → project config `workspace` → global config
|
|
14
|
+
* `workspace`; see `resolveWorkspaceId`). Independent of {@link CloudAdapter.area}: either,
|
|
15
|
+
* both or neither may be set.
|
|
16
|
+
*/
|
|
17
|
+
workspace;
|
|
11
18
|
/**
|
|
12
19
|
* Task reference → uuid, for the lifetime of this adapter. A command that touches the same
|
|
13
20
|
* task twice (`dep add TS-a TS-b` resolves two, `status` then reads back) pays for one
|
|
14
21
|
* `/tasks/by-number/{n}` lookup per distinct reference, not per call site.
|
|
15
22
|
*/
|
|
16
23
|
taskIdCache = new Map();
|
|
17
|
-
constructor(apiKey, area, apiUrl) {
|
|
24
|
+
constructor(apiKey, area, apiUrl, workspace) {
|
|
18
25
|
this.apiKey = apiKey;
|
|
19
26
|
this.area = area;
|
|
27
|
+
this.workspace = workspace;
|
|
20
28
|
this.baseUrl = (apiUrl ?? DEFAULT_API_URL).replace(/\/$/, '');
|
|
21
29
|
}
|
|
22
30
|
async request(method, path, options) {
|
|
@@ -32,6 +40,14 @@ export class CloudAdapter {
|
|
|
32
40
|
Authorization: `Bearer ${this.apiKey}`,
|
|
33
41
|
Accept: 'application/json',
|
|
34
42
|
};
|
|
43
|
+
// The two context headers are independent and both optional. The server resolves the
|
|
44
|
+
// workspace from `X-Orbitmap-Workspace` first, then from the area, then by auto-detecting
|
|
45
|
+
// a unique one — so a workspace-level command (intent, mission, idea, docs) run outside
|
|
46
|
+
// any area directory works with the workspace header alone, and an area-only client
|
|
47
|
+
// (everything before schema v2) keeps behaving exactly as it did.
|
|
48
|
+
if (this.workspace) {
|
|
49
|
+
headers['X-Orbitmap-Workspace'] = this.workspace;
|
|
50
|
+
}
|
|
35
51
|
if (this.area) {
|
|
36
52
|
headers['X-Orbitmap-Area'] = this.area;
|
|
37
53
|
}
|
|
@@ -64,7 +80,7 @@ export class CloudAdapter {
|
|
|
64
80
|
}
|
|
65
81
|
if (!response.ok) {
|
|
66
82
|
if (OrbitMapAPIError.isApiErrorBody(json)) {
|
|
67
|
-
throw OrbitMapAPIError.fromResponse(json);
|
|
83
|
+
throw this.explainContextError(OrbitMapAPIError.fromResponse(json));
|
|
68
84
|
}
|
|
69
85
|
// Billing/usage-limit rejections (402, 429) use a flat shape where
|
|
70
86
|
// `error` is a string — dispatch on the type of `error`, not status.
|
|
@@ -87,6 +103,53 @@ export class CloudAdapter {
|
|
|
87
103
|
clearTimeout(timeout);
|
|
88
104
|
}
|
|
89
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Add the client half of the story to the workspace-context errors the server can raise.
|
|
108
|
+
* The API knows what it received; only the CLI knows what it *sent* and which knobs could
|
|
109
|
+
* change that, and a bare "workspace context is required" is unactionable without it.
|
|
110
|
+
* Every other error is returned untouched.
|
|
111
|
+
*
|
|
112
|
+
* `AREA_CONTEXT_REQUIRED` is here too (TS-jt6q36 follow-up). The CLI raises that code
|
|
113
|
+
* itself — with the areas of the current workspace spelled out — but the *server* raises
|
|
114
|
+
* it as well, in HTTP terms ("set the X-Orbitmap-Area header. Call GET /api/agent/areas"),
|
|
115
|
+
* and that text used to reach the terminal verbatim: identical situation, two different
|
|
116
|
+
* answers depending on which side noticed first. The client-side advice is now attached to
|
|
117
|
+
* both, and the server's own sentence is kept (parenthesised) rather than dropped, because
|
|
118
|
+
* it is the only part that says what the API actually objected to.
|
|
119
|
+
*/
|
|
120
|
+
explainContextError(error) {
|
|
121
|
+
// Dispatch on the canonical code, not the wire code: the API is renaming `PROJECT_*` to
|
|
122
|
+
// `AREA_*` and both spellings must land here (see ERROR_CODE_ALIASES in errors.ts).
|
|
123
|
+
if (error.canonicalCode !== WORKSPACE_CONTEXT_REQUIRED &&
|
|
124
|
+
error.canonicalCode !== AREA_WORKSPACE_MISMATCH &&
|
|
125
|
+
error.canonicalCode !== AREA_CONTEXT_REQUIRED) {
|
|
126
|
+
return error;
|
|
127
|
+
}
|
|
128
|
+
const sent = {};
|
|
129
|
+
if (this.workspace)
|
|
130
|
+
sent['X-Orbitmap-Workspace'] = this.workspace;
|
|
131
|
+
if (this.area)
|
|
132
|
+
sent['X-Orbitmap-Area'] = this.area;
|
|
133
|
+
if (error.canonicalCode === AREA_CONTEXT_REQUIRED) {
|
|
134
|
+
const { message, mappedDirectories } = areaContextHint();
|
|
135
|
+
return new OrbitMapAPIError(`${message} (The API added: ${error.message})`, error.code, error.status, {
|
|
136
|
+
...error.details,
|
|
137
|
+
...(mappedDirectories.length > 0
|
|
138
|
+
? { mapped_directories: mappedDirectories }
|
|
139
|
+
: {}),
|
|
140
|
+
...(Object.keys(sent).length > 0 ? { sent_context: sent } : {}),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
const hint = error.canonicalCode === WORKSPACE_CONTEXT_REQUIRED
|
|
144
|
+
? 'Name a workspace with --workspace-id <slug-or-uuid>, ORBITMAP_WORKSPACE_ID, or a ' +
|
|
145
|
+
`"workspace" in ${ORBITMAP_DIR}/config.json.`
|
|
146
|
+
: 'The workspace and the area disagree — check --workspace-id/--area, ' +
|
|
147
|
+
`ORBITMAP_WORKSPACE_ID/ORBITMAP_AREA and ${ORBITMAP_DIR}/config.json.`;
|
|
148
|
+
return new OrbitMapAPIError(`${error.message} ${hint}`, error.code, error.status, {
|
|
149
|
+
...error.details,
|
|
150
|
+
...(Object.keys(sent).length > 0 ? { sent_context: sent } : {}),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
90
153
|
// ── Context ──
|
|
91
154
|
async getContext(areaId) {
|
|
92
155
|
return this.request('GET', '/context', {
|
|
@@ -102,6 +165,14 @@ export class CloudAdapter {
|
|
|
102
165
|
async getDefaultArea() {
|
|
103
166
|
return this.area;
|
|
104
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* The workspace identity this client sends as `X-Orbitmap-Workspace`, or `undefined` when
|
|
170
|
+
* none resolved (in which case the server derives one from the area or auto-detects it).
|
|
171
|
+
* No request is made.
|
|
172
|
+
*/
|
|
173
|
+
getWorkspaceId() {
|
|
174
|
+
return this.workspace;
|
|
175
|
+
}
|
|
105
176
|
// ── Tasks ──
|
|
106
177
|
async getTasks(options) {
|
|
107
178
|
return this.request('GET', '/tasks', {
|
|
@@ -225,6 +296,19 @@ export class CloudAdapter {
|
|
|
225
296
|
body: { type, content, metadata },
|
|
226
297
|
});
|
|
227
298
|
}
|
|
299
|
+
async logIntentWork(idOrNumber, type, content, metadata) {
|
|
300
|
+
// No client-side resolution: `/intents/{id_or_number}/logs` accepts a uuid, an `IN-`
|
|
301
|
+
// display number or a bare code and resolves it server-side, exactly like every other
|
|
302
|
+
// intent route (see `tests/reference-passthrough.test.ts`).
|
|
303
|
+
return this.request('POST', `/intents/${idOrNumber}/logs`, {
|
|
304
|
+
body: { type, content, metadata },
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
async logMissionWork(idOrNumber, type, content, metadata) {
|
|
308
|
+
return this.request('POST', `/missions/${idOrNumber}/logs`, {
|
|
309
|
+
body: { type, content, metadata },
|
|
310
|
+
});
|
|
311
|
+
}
|
|
228
312
|
// ── Documents ──
|
|
229
313
|
async getDocuments(options) {
|
|
230
314
|
return this.request('GET', '/documents', {
|
|
@@ -388,32 +472,23 @@ export class CloudAdapter {
|
|
|
388
472
|
},
|
|
389
473
|
});
|
|
390
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* `GET /issues/{id_or_number}` — the single issue-read route. It accepts a uuid, a bare
|
|
477
|
+
* six-char code or the prefixed `IS-xxxxxx` form; the server strips the prefix and resolves
|
|
478
|
+
* the number workspace-scoped. There is no `/issues/by-number/{n}` route — never add one.
|
|
479
|
+
*/
|
|
391
480
|
async getIssue(idOrNumber) {
|
|
392
481
|
return this.request('GET', `/issues/${idOrNumber}`);
|
|
393
482
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
return this.request('PATCH', `/issues/by-number/${issueNumber}/resolve`, {
|
|
399
|
-
body: data,
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
async resolveIssue(idOrNumber, data) {
|
|
403
|
-
return this.request('PATCH', `/issues/${idOrNumber}/resolve`, {
|
|
404
|
-
body: data,
|
|
405
|
-
});
|
|
406
|
-
}
|
|
483
|
+
/**
|
|
484
|
+
* `PATCH /issues/{id_or_number}/status` — the only issue-write route besides `/link` and
|
|
485
|
+
* `/assign`. `issue resolve` rides on it too: the API has no `/issues/{id}/resolve`.
|
|
486
|
+
*/
|
|
407
487
|
async updateIssueStatus(idOrNumber, data) {
|
|
408
488
|
return this.request('PATCH', `/issues/${idOrNumber}/status`, {
|
|
409
489
|
body: data,
|
|
410
490
|
});
|
|
411
491
|
}
|
|
412
|
-
async updateIssueStatusByNumber(issueNumber, data) {
|
|
413
|
-
return this.request('PATCH', `/issues/by-number/${issueNumber}/status`, {
|
|
414
|
-
body: data,
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
492
|
// ── Vibes ──
|
|
418
493
|
async logVibe(data) {
|
|
419
494
|
return this.request('POST', '/vibes', { body: data });
|
|
@@ -439,21 +514,20 @@ export class CloudAdapter {
|
|
|
439
514
|
params: { status: options?.status, priority: options?.priority, limit: options?.limit },
|
|
440
515
|
});
|
|
441
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* `GET /ideas/{id_or_number}` — accepts a uuid, a bare code or `ID-xxxxxx`; the server
|
|
519
|
+
* strips the prefix and resolves the number. There is no `/ideas/by-number/{n}` route.
|
|
520
|
+
*/
|
|
442
521
|
async getIdea(idOrNumber) {
|
|
443
522
|
return this.request('GET', `/ideas/${idOrNumber}`);
|
|
444
523
|
}
|
|
445
|
-
async getIdeaByNumber(ideaNumber) {
|
|
446
|
-
return this.request('GET', `/ideas/by-number/${ideaNumber}`);
|
|
447
|
-
}
|
|
448
524
|
async createIdea(data) {
|
|
449
525
|
return this.request('POST', '/ideas', { body: data });
|
|
450
526
|
}
|
|
527
|
+
/** `PATCH /ideas/{id_or_number}/status`. */
|
|
451
528
|
async updateIdeaStatus(idOrNumber, data) {
|
|
452
529
|
return this.request('PATCH', `/ideas/${idOrNumber}/status`, { body: data });
|
|
453
530
|
}
|
|
454
|
-
async updateIdeaStatusByNumber(ideaNumber, data) {
|
|
455
|
-
return this.request('PATCH', `/ideas/by-number/${ideaNumber}/status`, { body: data });
|
|
456
|
-
}
|
|
457
531
|
// ── Orbits ──
|
|
458
532
|
async listOrbits(options) {
|
|
459
533
|
return this.request('GET', '/orbits', {
|
|
@@ -572,11 +646,16 @@ export { CloudAdapter as OrbitMapClient };
|
|
|
572
646
|
* 0002 §2). `resolveAuth` used to carry a second, shorter copy of it that was missing the
|
|
573
647
|
* `link.json` rung, so a cloud project with a `.orbitmap/link.json` got a different area
|
|
574
648
|
* depending on which entry point it came through.
|
|
649
|
+
*
|
|
650
|
+
* The workspace identity comes from its own, separate ladder (`resolveWorkspaceId`) and is
|
|
651
|
+
* resolved here too: an area is no longer required, so a command run outside every area
|
|
652
|
+
* directory still has a context to send.
|
|
575
653
|
*/
|
|
576
654
|
export async function createClient(explicitArea, options = {}) {
|
|
577
655
|
const config = options.config ?? (await loadConfig());
|
|
578
656
|
const auth = await resolveAuth({ config });
|
|
579
657
|
const area = explicitArea ?? options.area ?? resolveArea({ config }).area;
|
|
580
|
-
|
|
658
|
+
const workspace = options.workspace ?? resolveWorkspaceId({ config }).workspace;
|
|
659
|
+
return new CloudAdapter(auth.apiKey, area, auth.apiUrl, workspace);
|
|
581
660
|
}
|
|
582
661
|
//# sourceMappingURL=cloud.js.map
|