orbitmap 0.4.4 → 0.5.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 +73 -10
- package/dist/adapters/cloud.d.ts +85 -10
- package/dist/adapters/cloud.js +118 -17
- package/dist/adapters/cloud.js.map +1 -1
- package/dist/adapters/factory.js +7 -0
- package/dist/adapters/factory.js.map +1 -1
- package/dist/adapters/local/adapter.d.ts +47 -8
- package/dist/adapters/local/adapter.js +37 -17
- package/dist/adapters/local/adapter.js.map +1 -1
- package/dist/adapters/local/context.d.ts +13 -1
- package/dist/adapters/local/context.js +7 -2
- package/dist/adapters/local/context.js.map +1 -1
- package/dist/adapters/local/entities/documents.d.ts +18 -4
- package/dist/adapters/local/entities/documents.js +46 -7
- package/dist/adapters/local/entities/documents.js.map +1 -1
- package/dist/adapters/local/entities/planning.d.ts +36 -7
- package/dist/adapters/local/entities/planning.js +245 -39
- package/dist/adapters/local/entities/planning.js.map +1 -1
- package/dist/adapters/local/entities/tasks.d.ts +16 -7
- package/dist/adapters/local/entities/tasks.js +55 -42
- package/dist/adapters/local/entities/tasks.js.map +1 -1
- package/dist/adapters/local/entities/work-items.d.ts +28 -7
- package/dist/adapters/local/entities/work-items.js +111 -39
- package/dist/adapters/local/entities/work-items.js.map +1 -1
- package/dist/adapters/local/lists.d.ts +139 -0
- package/dist/adapters/local/lists.js +230 -0
- package/dist/adapters/local/lists.js.map +1 -0
- package/dist/adapters/local/rules.js +22 -0
- package/dist/adapters/local/rules.js.map +1 -1
- package/dist/adapters/local/shapes.d.ts +165 -22
- package/dist/adapters/local/shapes.js +338 -50
- package/dist/adapters/local/shapes.js.map +1 -1
- package/dist/adapters/local/types.d.ts +5 -0
- package/dist/adapters/local/types.js.map +1 -1
- package/dist/adapters/types.d.ts +72 -9
- package/dist/agent-instructions.d.ts +39 -10
- package/dist/agent-instructions.js +268 -68
- package/dist/agent-instructions.js.map +1 -1
- package/dist/commands/context.d.ts +62 -37
- package/dist/commands/context.js +105 -36
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/docs.d.ts +4 -0
- package/dist/commands/docs.js +12 -5
- package/dist/commands/docs.js.map +1 -1
- package/dist/commands/ideas.d.ts +3 -0
- package/dist/commands/ideas.js +14 -7
- package/dist/commands/ideas.js.map +1 -1
- package/dist/commands/intent.d.ts +26 -0
- package/dist/commands/intent.js +110 -7
- package/dist/commands/intent.js.map +1 -1
- package/dist/commands/issues.d.ts +4 -0
- package/dist/commands/issues.js +15 -7
- package/dist/commands/issues.js.map +1 -1
- package/dist/commands/mission.d.ts +2 -0
- package/dist/commands/mission.js +9 -5
- package/dist/commands/mission.js.map +1 -1
- package/dist/commands/setup-agent.d.ts +34 -0
- package/dist/commands/setup-agent.js +95 -4
- package/dist/commands/setup-agent.js.map +1 -1
- package/dist/commands/start.d.ts +13 -0
- package/dist/commands/start.js +125 -13
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/tasks.d.ts +23 -5
- package/dist/commands/tasks.js +46 -23
- package/dist/commands/tasks.js.map +1 -1
- package/dist/commands/vibes.d.ts +3 -0
- package/dist/commands/vibes.js +11 -5
- package/dist/commands/vibes.js.map +1 -1
- package/dist/errors.d.ts +23 -2
- package/dist/errors.js +31 -3
- package/dist/errors.js.map +1 -1
- package/dist/index.js +108 -36
- package/dist/index.js.map +1 -1
- package/dist/list-meta.d.ts +117 -0
- package/dist/list-meta.js +160 -0
- package/dist/list-meta.js.map +1 -0
- package/dist/list-options.d.ts +33 -0
- package/dist/list-options.js +70 -0
- package/dist/list-options.js.map +1 -0
- package/dist/workspace-resolve.d.ts +47 -1
- package/dist/workspace-resolve.js +74 -11
- package/dist/workspace-resolve.js.map +1 -1
- package/dist/write-target.d.ts +9 -0
- package/dist/write-target.js +11 -2
- package/dist/write-target.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -155,7 +155,7 @@ OrbitMap organises work on several levels. The CLI mirrors them 1:1:
|
|
|
155
155
|
|
|
156
156
|
| Command | Description |
|
|
157
157
|
|---------|-------------|
|
|
158
|
-
| `orbitmap tasks` | List
|
|
158
|
+
| `orbitmap tasks` | List tasks across every area you reach and every assignee (`--area`, `--status`, `--priority`, `--orbit`, `--intent`, `--mission`, `--agent`, `--unassigned`, `--limit`, `--all`) |
|
|
159
159
|
| `orbitmap task <id-or-number>` | Show full task details |
|
|
160
160
|
| `orbitmap start [id-or-number]` | Start working on a task (auto-picks next TODO if no ID) |
|
|
161
161
|
| `orbitmap status <id-or-number> <status>` | Update task status (`--force` to move a parent to `done` with unfinished subtasks) |
|
|
@@ -169,6 +169,59 @@ OrbitMap organises work on several levels. The CLI mirrors them 1:1:
|
|
|
169
169
|
|
|
170
170
|
**Valid statuses:** `backlog`, `todo`, `in_progress`, `in_review`, `review_changes`, `done`, `blocked`
|
|
171
171
|
|
|
172
|
+
### What a list shows, and what it hides
|
|
173
|
+
|
|
174
|
+
Every list — `tasks`, `issues`, `ideas`, `vibes`, `docs`, `intents`, `missions` — spans
|
|
175
|
+
**every area your key reaches and every assignee**. It is not scoped to your own work, and it
|
|
176
|
+
is not scoped to the area your directory maps to: that area is the context for *writes* and
|
|
177
|
+
for single-object reads, and the server deliberately ignores it when listing.
|
|
178
|
+
|
|
179
|
+
Narrowing is explicit, and always visible in the output:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
orbitmap tasks # everything you can reach
|
|
183
|
+
orbitmap tasks --area demo # one area
|
|
184
|
+
orbitmap tasks --area demo,web # two areas (comma-separated, no spaces)
|
|
185
|
+
orbitmap tasks --area all # cancel an ORBITMAP_AREA narrowing for this call
|
|
186
|
+
orbitmap tasks --agent me # only your own tasks — the pre-9.0.0 default
|
|
187
|
+
orbitmap tasks --agent jakub-agent # a colleague's
|
|
188
|
+
orbitmap tasks --unassigned # the free backlog
|
|
189
|
+
orbitmap tasks --intent IN-nahetc # everything under one intent, in one call
|
|
190
|
+
orbitmap tasks --mission MS-abc123
|
|
191
|
+
orbitmap tasks --status all # every status, on every list
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Lists are paged: **30 rows by default, 100 at most** per page. The page is not the answer —
|
|
195
|
+
`--all` is:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
orbitmap tasks --limit 100 # one bigger page
|
|
199
|
+
orbitmap tasks --all # follow every page and print all 143 rows
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Under every result the CLI prints what produced it, whether the list was empty, truncated or
|
|
203
|
+
complete:
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
30 of 143 shown across 7 areas — run with --all for every row.
|
|
207
|
+
Scope: all 7 reachable areas, status todo,in_progress (46 hidden, add --status all), assignee any.
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
An empty list carries the same line, so "nothing exists" and "you did not ask for it" are
|
|
211
|
+
never the same sentence:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
No tasks. Scope: areas demo (1 of 7), status todo,in_progress (46 hidden, add --status all), assignee unassigned.
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`--json` carries the whole `meta` block: `total`, `next_cursor`, `per_area`
|
|
218
|
+
(`{slug, shown, total}` per area), `applied_filters`, `scope` and `workspace`, plus each row's
|
|
219
|
+
own `area`, `agent_id` and `assigned_user_id`.
|
|
220
|
+
|
|
221
|
+
`--area` names *one* area everywhere else (`create`, `log`, `status`, `doc-import`, …) — that
|
|
222
|
+
is the area a write lands in, so a comma-separated `--area` is refused there rather than
|
|
223
|
+
silently taking the first.
|
|
224
|
+
|
|
172
225
|
### Referring to objects: `<id-or-number>`
|
|
173
226
|
|
|
174
227
|
Every command that takes an object reference accepts all three forms interchangeably:
|
|
@@ -234,7 +287,7 @@ when there is none — so a rejected transition is re-run with `--log`, not retr
|
|
|
234
287
|
|
|
235
288
|
| Command | Description |
|
|
236
289
|
|---------|-------------|
|
|
237
|
-
| `orbitmap docs` | List area
|
|
290
|
+
| `orbitmap docs` | List documents across every area you reach, plus workspace-level ones (`--area`, `--type`, `--search`, `--limit`, `--all`) |
|
|
238
291
|
| `orbitmap doc <id-or-slug>` | Show document (TOC by default, `--full`, `--section`) |
|
|
239
292
|
| `orbitmap doc-import <title>` | Import a markdown file (`--context` to set when-to-use hint) |
|
|
240
293
|
| `orbitmap doc-update <id-or-slug>` | Replace a document from a file |
|
|
@@ -278,7 +331,7 @@ orbitmap doc-share <doc-uuid> <area-uuid> --agents agent1-uuid,agent2-uuid
|
|
|
278
331
|
|
|
279
332
|
| Command | Description |
|
|
280
333
|
|---------|-------------|
|
|
281
|
-
| `orbitmap context` |
|
|
334
|
+
| `orbitmap context` | Session matching material: agent identity, area/workspace, missions and intents with TL;DRs, mission workitems, areas, document metadata |
|
|
282
335
|
| `orbitmap areas` | List all areas assigned to this agent |
|
|
283
336
|
| `orbitmap create-area <name>` | Create a new area (`--desc`, `--slug`, `--workspace-id`) |
|
|
284
337
|
| `orbitmap members <area-id>` | List agents and users in an area (accepts slug) |
|
|
@@ -288,16 +341,16 @@ orbitmap doc-share <doc-uuid> <area-uuid> --agents agent1-uuid,agent2-uuid
|
|
|
288
341
|
|
|
289
342
|
| Command | Description |
|
|
290
343
|
|---------|-------------|
|
|
291
|
-
| `orbitmap issues` | List open issues |
|
|
344
|
+
| `orbitmap issues` | List open issues across every area you reach (`--area`, `--status`, `--severity`, `--intent`, `--limit`, `--all`) |
|
|
292
345
|
| `orbitmap issue show <id>` | Show issue details (UUID or number) |
|
|
293
346
|
| `orbitmap issue register` | Register a new issue (`--intent` to link it to an intent) |
|
|
294
347
|
| `orbitmap issue status <id> <status>` | Update issue status |
|
|
295
348
|
| `orbitmap issue resolve <id>` | Resolve an issue |
|
|
296
|
-
| `orbitmap ideas` | List ideas |
|
|
349
|
+
| `orbitmap ideas` | List ideas across every area you reach (`--area`, `--status`, `--priority`, `--limit`, `--all`) |
|
|
297
350
|
| `orbitmap idea add` | Add a new idea |
|
|
298
351
|
| `orbitmap idea show <id>` | Show idea details (UUID or number) |
|
|
299
352
|
| `orbitmap idea status <id>` | Update idea status |
|
|
300
|
-
| `orbitmap vibes` | List vibes |
|
|
353
|
+
| `orbitmap vibes` | List vibes across every area you reach (`--area`, `--type`, `--since`, `--limit`, `--all`) |
|
|
301
354
|
| `orbitmap vibe log` | Log a new vibe |
|
|
302
355
|
| `orbitmap vibe show <id>` | Show vibe details |
|
|
303
356
|
| `orbitmap vibe update <id>` | Update a vibe |
|
|
@@ -308,10 +361,10 @@ Workspace-level desired outcomes. Tasks and issues hang off an intent; an intent
|
|
|
308
361
|
|
|
309
362
|
| Command | Description |
|
|
310
363
|
|---------|-------------|
|
|
311
|
-
| `orbitmap intents` | List intents (
|
|
312
|
-
| `orbitmap intent show <id-or-number>` | Show an intent (UUID or `IN-xxxxxx`) |
|
|
364
|
+
| `orbitmap intents` | List intents — workspace-wide (`--status`, `--mission`, `--limit`, `--all`) |
|
|
365
|
+
| `orbitmap intent show <id-or-number>` | Show an intent (UUID or `IN-xxxxxx`) — embeds the context bundle (`--no-bundle` strips it, `--no-logs` skips the work-log tail, `--slim` is the freshness probe) |
|
|
313
366
|
| `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) |
|
|
367
|
+
| `orbitmap intent update <id>` | Update title, outcome, design, plan, or status (`--areas <slug>,<slug>` declares its areas; `--log <type>:<content>`, repeatable) |
|
|
315
368
|
| `orbitmap intent link <id> --type task\|issue --id <uuid>` | Link a task or issue |
|
|
316
369
|
| `orbitmap intent unlink <id> --type task\|issue --id <uuid>` | Unlink a task or issue |
|
|
317
370
|
| `orbitmap intent orbit <id> [orbit-id]` | Set the intent's orbit (`--clear` to remove) |
|
|
@@ -335,13 +388,23 @@ orbitmap intent update IN-a1b2c3 --status plan \
|
|
|
335
388
|
|
|
336
389
|
`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.
|
|
337
390
|
|
|
391
|
+
**The context bundle.** `intent show` prints a `Context bundle:` block after the intent's own outcome/design/plan and before the work-log tail: the mission handle with its outcome TL;DR, the documents that surround the intent (listed by their `when_to_use`, with the slug to pass to `orbitmap doc`), sibling intent handles, and the intent's own tasks and issues. It is handle tier — TL;DRs and titles, never bodies. `--no-bundle` strips it when you only want the intent itself.
|
|
392
|
+
|
|
393
|
+
**The freshness probe.** `--slim` replaces the whole body with a ~150-token probe: handle, the outcome/design/plan TL;DRs, declared areas, mission, task counts per status, and the `updated_at` + `last_log_id` pair. Hold that pair from a full fetch; run the probe to see whether the intent moved. Unchanged means your copy is current — do not re-fetch. A work log never touches `updated_at`, so both halves have to be compared. `--slim` wins over `--no-bundle` and `--no-logs`.
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
orbitmap intent show IN-a1b2c3 # intent + context bundle + work-log tail
|
|
397
|
+
orbitmap intent show IN-a1b2c3 --no-bundle # just the intent and its logs
|
|
398
|
+
orbitmap intent show IN-a1b2c3 --slim # freshness probe: TL;DRs + updated_at/last_log_id
|
|
399
|
+
```
|
|
400
|
+
|
|
338
401
|
### Missions
|
|
339
402
|
|
|
340
403
|
Time-boxed workspace focus. Only one mission can be `active` at a time.
|
|
341
404
|
|
|
342
405
|
| Command | Description |
|
|
343
406
|
|---------|-------------|
|
|
344
|
-
| `orbitmap missions` | List missions (
|
|
407
|
+
| `orbitmap missions` | List missions — workspace-wide (`--status`, `--limit`, `--all`) |
|
|
345
408
|
| `orbitmap mission show <id-or-number>` | Show a mission (UUID or `MS-xxxxxx`) |
|
|
346
409
|
| `orbitmap mission create <title>` | Create a mission (`--desc`, `--outcome`, `--end-date`) |
|
|
347
410
|
| `orbitmap mission update <id>` | Update title, description, outcome, or end date (`--log <type>:<content>`, repeatable) |
|
package/dist/adapters/cloud.d.ts
CHANGED
|
@@ -12,13 +12,25 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
12
12
|
* both or neither may be set.
|
|
13
13
|
*/
|
|
14
14
|
private readonly workspace?;
|
|
15
|
+
/**
|
|
16
|
+
* The areas the caller EXPLICITLY narrowed a LIST to (`--area a,b`, `ORBITMAP_AREA=a,b`),
|
|
17
|
+
* already resolved by the one area ladder. Sent as the `area_id` query parameter.
|
|
18
|
+
*
|
|
19
|
+
* It is deliberately NOT {@link CloudAdapter.area}. Since API 9.0.0 the `X-Orbitmap-Area`
|
|
20
|
+
* header no longer narrows a list — the CLI sends it on every call made from an
|
|
21
|
+
* area-mapped directory, so honouring it there would leave `orbitmap tasks` answering with
|
|
22
|
+
* one area's work, which is the bug IN-nahetc exists to fix. The header stays the context
|
|
23
|
+
* for writes and single-entity reads; `area_id` is the only narrowing, and only an
|
|
24
|
+
* explicit `--area` fills it.
|
|
25
|
+
*/
|
|
26
|
+
private readonly areaFilter;
|
|
15
27
|
/**
|
|
16
28
|
* Task reference → uuid, for the lifetime of this adapter. A command that touches the same
|
|
17
29
|
* task twice (`dep add TS-a TS-b` resolves two, `status` then reads back) pays for one
|
|
18
30
|
* `/tasks/by-number/{n}` lookup per distinct reference, not per call site.
|
|
19
31
|
*/
|
|
20
32
|
private readonly taskIdCache;
|
|
21
|
-
constructor(apiKey: string, area?: string, apiUrl?: string, workspace?: string);
|
|
33
|
+
constructor(apiKey: string, area?: string, apiUrl?: string, workspace?: string, areaFilter?: string[]);
|
|
22
34
|
private request;
|
|
23
35
|
/**
|
|
24
36
|
* Add the client half of the story to the workspace-context errors the server can raise.
|
|
@@ -49,11 +61,39 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
49
61
|
* No request is made.
|
|
50
62
|
*/
|
|
51
63
|
getWorkspaceId(): string | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* The `area_id` query value for a LIST: what the caller explicitly asked for, falling back
|
|
66
|
+
* to the areas the ladder resolved from `--area` / `ORBITMAP_AREA`.
|
|
67
|
+
*
|
|
68
|
+
* Comma-joined, exactly as the API's own parser expects
|
|
69
|
+
* (`BaseAgentApiController::splitAreaRefs`). `undefined` — never an empty string — when
|
|
70
|
+
* nothing narrows, so the request carries no `area_id` at all and the answer spans every
|
|
71
|
+
* area the key reaches.
|
|
72
|
+
*/
|
|
73
|
+
private listAreaParam;
|
|
74
|
+
/** `limit` / `cursor`, the two paging params every list shares. */
|
|
75
|
+
private pagingParams;
|
|
76
|
+
/**
|
|
77
|
+
* `GET /tasks` — every area the key reaches and every assignee, unless a filter says
|
|
78
|
+
* otherwise (API 9.0.0).
|
|
79
|
+
*
|
|
80
|
+
* `areaId` accepts one ref or several; several are comma-joined, which is the only way to
|
|
81
|
+
* narrow to two areas without two calls. `agentId` (`me`, a slug or a uuid), `unassigned`
|
|
82
|
+
* and `all` are the owner scope — `all` now names the default rather than escaping one.
|
|
83
|
+
* `intentId` / `missionId` take a uuid, `IN-xxxxxx`/`MS-xxxxxx` or the bare code.
|
|
84
|
+
*/
|
|
52
85
|
getTasks(options?: {
|
|
53
86
|
status?: string;
|
|
54
87
|
priority?: string;
|
|
55
|
-
areaId?: string;
|
|
88
|
+
areaId?: string | string[];
|
|
56
89
|
orbit?: string;
|
|
90
|
+
intentId?: string;
|
|
91
|
+
missionId?: string;
|
|
92
|
+
agentId?: string;
|
|
93
|
+
unassigned?: boolean;
|
|
94
|
+
all?: boolean;
|
|
95
|
+
limit?: string | number;
|
|
96
|
+
cursor?: string;
|
|
57
97
|
}): Promise<unknown>;
|
|
58
98
|
/**
|
|
59
99
|
* Resolve any task reference — uuid, `TS-uw9yh5` or the bare code — to the uuid the task
|
|
@@ -63,7 +103,18 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
63
103
|
private taskId;
|
|
64
104
|
getTask(taskId: string): Promise<unknown>;
|
|
65
105
|
getTaskByNumber(taskNumber: string): Promise<unknown>;
|
|
66
|
-
|
|
106
|
+
/**
|
|
107
|
+
* `POST /tasks/{id}/start`, or `POST /tasks/start` to let the server auto-pick.
|
|
108
|
+
*
|
|
109
|
+
* `confirmReassign` is the USER's answer to a 409 `REASSIGN_CONFIRMATION_REQUIRED`
|
|
110
|
+
* travelling back: it reassigns a task that belongs to another agent and starts it in one
|
|
111
|
+
* call. It is never sent on its own initiative — see `askToTakeOver` in
|
|
112
|
+
* `src/commands/start.ts`. Auto-confirming would turn "ask before taking someone else's
|
|
113
|
+
* work" into theatre.
|
|
114
|
+
*/
|
|
115
|
+
startTask(taskId?: string, options?: {
|
|
116
|
+
confirmReassign?: boolean;
|
|
117
|
+
}): Promise<unknown>;
|
|
67
118
|
updateTaskStatus(taskId: string, status?: string, deliveryStatus?: string | null, _force?: boolean): Promise<unknown>;
|
|
68
119
|
createSubtasks(parentId: string, subtasks: Array<{
|
|
69
120
|
title: string;
|
|
@@ -112,7 +163,10 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
112
163
|
getDocuments(options?: {
|
|
113
164
|
type?: string;
|
|
114
165
|
search?: string;
|
|
115
|
-
areaId?: string;
|
|
166
|
+
areaId?: string | string[];
|
|
167
|
+
status?: string;
|
|
168
|
+
limit?: string | number;
|
|
169
|
+
cursor?: string;
|
|
116
170
|
}): Promise<unknown>;
|
|
117
171
|
getDocument(idOrSlug: string, mode?: 'inline' | 'file', options?: {
|
|
118
172
|
full?: boolean;
|
|
@@ -221,7 +275,10 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
221
275
|
listIssues(options?: {
|
|
222
276
|
status?: string;
|
|
223
277
|
severity?: string;
|
|
224
|
-
|
|
278
|
+
areaId?: string | string[];
|
|
279
|
+
intentId?: string;
|
|
280
|
+
limit?: string | number;
|
|
281
|
+
cursor?: string;
|
|
225
282
|
}): Promise<unknown>;
|
|
226
283
|
/**
|
|
227
284
|
* `GET /issues/{id_or_number}` — the single issue-read route. It accepts a uuid, a bare
|
|
@@ -247,7 +304,9 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
247
304
|
listVibes(options?: {
|
|
248
305
|
type?: string;
|
|
249
306
|
since?: string;
|
|
250
|
-
|
|
307
|
+
areaId?: string | string[];
|
|
308
|
+
limit?: string | number;
|
|
309
|
+
cursor?: string;
|
|
251
310
|
}): Promise<unknown>;
|
|
252
311
|
getVibe(id: string): Promise<unknown>;
|
|
253
312
|
updateVibe(id: string, data: {
|
|
@@ -259,7 +318,9 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
259
318
|
listIdeas(options?: {
|
|
260
319
|
status?: string;
|
|
261
320
|
priority?: string;
|
|
262
|
-
|
|
321
|
+
areaId?: string | string[];
|
|
322
|
+
limit?: string | number;
|
|
323
|
+
cursor?: string;
|
|
263
324
|
}): Promise<unknown>;
|
|
264
325
|
/**
|
|
265
326
|
* `GET /ideas/{id_or_number}` — accepts a uuid, a bare code or `ID-xxxxxx`; the server
|
|
@@ -313,9 +374,15 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
313
374
|
}): Promise<unknown>;
|
|
314
375
|
listIntents(options?: {
|
|
315
376
|
status?: string;
|
|
316
|
-
|
|
377
|
+
missionId?: string;
|
|
378
|
+
limit?: string | number;
|
|
379
|
+
cursor?: string;
|
|
380
|
+
}): Promise<unknown>;
|
|
381
|
+
getIntent(idOrNumber: string, options?: {
|
|
382
|
+
logs?: boolean;
|
|
383
|
+
bundle?: boolean;
|
|
384
|
+
slim?: boolean;
|
|
317
385
|
}): Promise<unknown>;
|
|
318
|
-
getIntent(idOrNumber: string): Promise<unknown>;
|
|
319
386
|
createIntent(data: {
|
|
320
387
|
name: string;
|
|
321
388
|
outcome?: string;
|
|
@@ -330,6 +397,7 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
330
397
|
design?: string;
|
|
331
398
|
plan?: string;
|
|
332
399
|
status?: string;
|
|
400
|
+
area_ids?: string[];
|
|
333
401
|
logs?: WorkLogEntry[];
|
|
334
402
|
}): Promise<unknown>;
|
|
335
403
|
linkIntentItem(idOrNumber: string, data: {
|
|
@@ -343,7 +411,8 @@ export declare class CloudAdapter implements WorkspaceAdapter {
|
|
|
343
411
|
setIntentOrbit(idOrNumber: string, orbitId: string | null): Promise<unknown>;
|
|
344
412
|
listMissions(options?: {
|
|
345
413
|
status?: string;
|
|
346
|
-
limit?: string;
|
|
414
|
+
limit?: string | number;
|
|
415
|
+
cursor?: string;
|
|
347
416
|
}): Promise<unknown>;
|
|
348
417
|
getMission(idOrNumber: string): Promise<unknown>;
|
|
349
418
|
createMission(data: {
|
|
@@ -391,6 +460,12 @@ export interface CreateClientOptions {
|
|
|
391
460
|
* when the caller has it so the ladder runs once per command.
|
|
392
461
|
*/
|
|
393
462
|
workspace?: string;
|
|
463
|
+
/**
|
|
464
|
+
* The areas the caller EXPLICITLY narrowed to, already produced by the same ladder — the
|
|
465
|
+
* `area_id` list filter. See {@link CloudAdapter.areaFilter} for why this is not
|
|
466
|
+
* {@link CreateClientOptions.area}.
|
|
467
|
+
*/
|
|
468
|
+
areas?: string[];
|
|
394
469
|
/** Global config the caller already loaded, to avoid a second read of the same file. */
|
|
395
470
|
config?: OrbitMapConfig;
|
|
396
471
|
}
|
package/dist/adapters/cloud.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createReadStream, statSync } from 'node:fs';
|
|
2
2
|
import { basename, extname } from 'node:path';
|
|
3
|
-
import { AREA_CONTEXT_REQUIRED,
|
|
3
|
+
import { AREA_CONTEXT_REQUIRED, OrbitMapAPIError, WORKSPACE_CONTEXT_REQUIRED, } from '../errors.js';
|
|
4
4
|
import { loadConfig, resolveAuth, DEFAULT_API_URL } from '../config.js';
|
|
5
5
|
import { areaContextHint, ORBITMAP_DIR, resolveArea, resolveWorkspaceId, } from '../workspace-resolve.js';
|
|
6
6
|
import { isObjectNumber, resolveTaskRef, stripPrefix } from '../id-resolve.js';
|
|
@@ -15,16 +15,29 @@ export class CloudAdapter {
|
|
|
15
15
|
* both or neither may be set.
|
|
16
16
|
*/
|
|
17
17
|
workspace;
|
|
18
|
+
/**
|
|
19
|
+
* The areas the caller EXPLICITLY narrowed a LIST to (`--area a,b`, `ORBITMAP_AREA=a,b`),
|
|
20
|
+
* already resolved by the one area ladder. Sent as the `area_id` query parameter.
|
|
21
|
+
*
|
|
22
|
+
* It is deliberately NOT {@link CloudAdapter.area}. Since API 9.0.0 the `X-Orbitmap-Area`
|
|
23
|
+
* header no longer narrows a list — the CLI sends it on every call made from an
|
|
24
|
+
* area-mapped directory, so honouring it there would leave `orbitmap tasks` answering with
|
|
25
|
+
* one area's work, which is the bug IN-nahetc exists to fix. The header stays the context
|
|
26
|
+
* for writes and single-entity reads; `area_id` is the only narrowing, and only an
|
|
27
|
+
* explicit `--area` fills it.
|
|
28
|
+
*/
|
|
29
|
+
areaFilter;
|
|
18
30
|
/**
|
|
19
31
|
* Task reference → uuid, for the lifetime of this adapter. A command that touches the same
|
|
20
32
|
* task twice (`dep add TS-a TS-b` resolves two, `status` then reads back) pays for one
|
|
21
33
|
* `/tasks/by-number/{n}` lookup per distinct reference, not per call site.
|
|
22
34
|
*/
|
|
23
35
|
taskIdCache = new Map();
|
|
24
|
-
constructor(apiKey, area, apiUrl, workspace) {
|
|
36
|
+
constructor(apiKey, area, apiUrl, workspace, areaFilter) {
|
|
25
37
|
this.apiKey = apiKey;
|
|
26
38
|
this.area = area;
|
|
27
39
|
this.workspace = workspace;
|
|
40
|
+
this.areaFilter = areaFilter ?? [];
|
|
28
41
|
this.baseUrl = (apiUrl ?? DEFAULT_API_URL).replace(/\/$/, '');
|
|
29
42
|
}
|
|
30
43
|
async request(method, path, options) {
|
|
@@ -120,8 +133,11 @@ export class CloudAdapter {
|
|
|
120
133
|
explainContextError(error) {
|
|
121
134
|
// Dispatch on the canonical code, not the wire code: the API is renaming `PROJECT_*` to
|
|
122
135
|
// `AREA_*` and both spellings must land here (see ERROR_CODE_ALIASES in errors.ts).
|
|
136
|
+
// `AREA_WORKSPACE_MISMATCH` (422) used to be handled here too. API 9.0.0 REMOVED it:
|
|
137
|
+
// the workspace ceiling refuses a foreign `X-Orbitmap-Workspace` with 403 ACCESS_DENIED
|
|
138
|
+
// before the area and the workspace are ever compared, so the code is unreachable and
|
|
139
|
+
// the dual-read is gone.
|
|
123
140
|
if (error.canonicalCode !== WORKSPACE_CONTEXT_REQUIRED &&
|
|
124
|
-
error.canonicalCode !== AREA_WORKSPACE_MISMATCH &&
|
|
125
141
|
error.canonicalCode !== AREA_CONTEXT_REQUIRED) {
|
|
126
142
|
return error;
|
|
127
143
|
}
|
|
@@ -173,14 +189,55 @@ export class CloudAdapter {
|
|
|
173
189
|
getWorkspaceId() {
|
|
174
190
|
return this.workspace;
|
|
175
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* The `area_id` query value for a LIST: what the caller explicitly asked for, falling back
|
|
194
|
+
* to the areas the ladder resolved from `--area` / `ORBITMAP_AREA`.
|
|
195
|
+
*
|
|
196
|
+
* Comma-joined, exactly as the API's own parser expects
|
|
197
|
+
* (`BaseAgentApiController::splitAreaRefs`). `undefined` — never an empty string — when
|
|
198
|
+
* nothing narrows, so the request carries no `area_id` at all and the answer spans every
|
|
199
|
+
* area the key reaches.
|
|
200
|
+
*/
|
|
201
|
+
listAreaParam(areaId) {
|
|
202
|
+
const explicit = Array.isArray(areaId) ? areaId : areaId ? [areaId] : [];
|
|
203
|
+
const refs = explicit.length > 0 ? explicit : this.areaFilter;
|
|
204
|
+
const joined = refs
|
|
205
|
+
.flatMap((ref) => ref.split(','))
|
|
206
|
+
.map((ref) => ref.trim())
|
|
207
|
+
.filter((ref) => ref !== '')
|
|
208
|
+
.join(',');
|
|
209
|
+
return joined === '' ? undefined : joined;
|
|
210
|
+
}
|
|
211
|
+
/** `limit` / `cursor`, the two paging params every list shares. */
|
|
212
|
+
pagingParams(options) {
|
|
213
|
+
return {
|
|
214
|
+
limit: options?.limit === undefined ? undefined : String(options.limit),
|
|
215
|
+
cursor: options?.cursor,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
176
218
|
// ── Tasks ──
|
|
219
|
+
/**
|
|
220
|
+
* `GET /tasks` — every area the key reaches and every assignee, unless a filter says
|
|
221
|
+
* otherwise (API 9.0.0).
|
|
222
|
+
*
|
|
223
|
+
* `areaId` accepts one ref or several; several are comma-joined, which is the only way to
|
|
224
|
+
* narrow to two areas without two calls. `agentId` (`me`, a slug or a uuid), `unassigned`
|
|
225
|
+
* and `all` are the owner scope — `all` now names the default rather than escaping one.
|
|
226
|
+
* `intentId` / `missionId` take a uuid, `IN-xxxxxx`/`MS-xxxxxx` or the bare code.
|
|
227
|
+
*/
|
|
177
228
|
async getTasks(options) {
|
|
178
229
|
return this.request('GET', '/tasks', {
|
|
179
230
|
params: {
|
|
180
231
|
status: options?.status,
|
|
181
232
|
priority: options?.priority,
|
|
182
|
-
area_id: options?.areaId,
|
|
233
|
+
area_id: this.listAreaParam(options?.areaId),
|
|
183
234
|
orbit_id: options?.orbit,
|
|
235
|
+
intent_id: options?.intentId,
|
|
236
|
+
mission_id: options?.missionId,
|
|
237
|
+
agent_id: options?.agentId,
|
|
238
|
+
unassigned: options?.unassigned ? '1' : undefined,
|
|
239
|
+
all: options?.all ? '1' : undefined,
|
|
240
|
+
...this.pagingParams(options),
|
|
184
241
|
},
|
|
185
242
|
});
|
|
186
243
|
}
|
|
@@ -217,11 +274,21 @@ export class CloudAdapter {
|
|
|
217
274
|
async getTaskByNumber(taskNumber) {
|
|
218
275
|
return this.request('GET', `/tasks/by-number/${taskNumber}`);
|
|
219
276
|
}
|
|
220
|
-
|
|
277
|
+
/**
|
|
278
|
+
* `POST /tasks/{id}/start`, or `POST /tasks/start` to let the server auto-pick.
|
|
279
|
+
*
|
|
280
|
+
* `confirmReassign` is the USER's answer to a 409 `REASSIGN_CONFIRMATION_REQUIRED`
|
|
281
|
+
* travelling back: it reassigns a task that belongs to another agent and starts it in one
|
|
282
|
+
* call. It is never sent on its own initiative — see `askToTakeOver` in
|
|
283
|
+
* `src/commands/start.ts`. Auto-confirming would turn "ask before taking someone else's
|
|
284
|
+
* work" into theatre.
|
|
285
|
+
*/
|
|
286
|
+
async startTask(taskId, options) {
|
|
287
|
+
const body = options?.confirmReassign ? { confirm_reassign: true } : undefined;
|
|
221
288
|
if (taskId) {
|
|
222
|
-
return this.request('POST', `/tasks/${await this.taskId(taskId)}/start
|
|
289
|
+
return this.request('POST', `/tasks/${await this.taskId(taskId)}/start`, { body });
|
|
223
290
|
}
|
|
224
|
-
return this.request('POST', '/tasks/start');
|
|
291
|
+
return this.request('POST', '/tasks/start', { body });
|
|
225
292
|
}
|
|
226
293
|
async updateTaskStatus(taskId, status, deliveryStatus,
|
|
227
294
|
// `force` (spec §6.2) is deliberately ignored in cloud mode: the API already allows
|
|
@@ -315,7 +382,9 @@ export class CloudAdapter {
|
|
|
315
382
|
params: {
|
|
316
383
|
type: options?.type,
|
|
317
384
|
search: options?.search,
|
|
318
|
-
|
|
385
|
+
status: options?.status,
|
|
386
|
+
area_id: this.listAreaParam(options?.areaId),
|
|
387
|
+
...this.pagingParams(options),
|
|
319
388
|
},
|
|
320
389
|
});
|
|
321
390
|
}
|
|
@@ -468,7 +537,9 @@ export class CloudAdapter {
|
|
|
468
537
|
params: {
|
|
469
538
|
status: options?.status,
|
|
470
539
|
severity: options?.severity,
|
|
471
|
-
|
|
540
|
+
area_id: this.listAreaParam(options?.areaId),
|
|
541
|
+
intent_id: options?.intentId,
|
|
542
|
+
...this.pagingParams(options),
|
|
472
543
|
},
|
|
473
544
|
});
|
|
474
545
|
}
|
|
@@ -498,7 +569,8 @@ export class CloudAdapter {
|
|
|
498
569
|
params: {
|
|
499
570
|
type: options?.type,
|
|
500
571
|
since: options?.since,
|
|
501
|
-
|
|
572
|
+
area_id: this.listAreaParam(options?.areaId),
|
|
573
|
+
...this.pagingParams(options),
|
|
502
574
|
},
|
|
503
575
|
});
|
|
504
576
|
}
|
|
@@ -511,7 +583,12 @@ export class CloudAdapter {
|
|
|
511
583
|
// ── Ideas ──
|
|
512
584
|
async listIdeas(options) {
|
|
513
585
|
return this.request('GET', '/ideas', {
|
|
514
|
-
params: {
|
|
586
|
+
params: {
|
|
587
|
+
status: options?.status,
|
|
588
|
+
priority: options?.priority,
|
|
589
|
+
area_id: this.listAreaParam(options?.areaId),
|
|
590
|
+
...this.pagingParams(options),
|
|
591
|
+
},
|
|
515
592
|
});
|
|
516
593
|
}
|
|
517
594
|
/**
|
|
@@ -577,11 +654,26 @@ export class CloudAdapter {
|
|
|
577
654
|
// ── Intents ──
|
|
578
655
|
async listIntents(options) {
|
|
579
656
|
return this.request('GET', '/intents', {
|
|
580
|
-
params: {
|
|
657
|
+
params: {
|
|
658
|
+
status: options?.status,
|
|
659
|
+
mission_id: options?.missionId,
|
|
660
|
+
...this.pagingParams(options),
|
|
661
|
+
},
|
|
581
662
|
});
|
|
582
663
|
}
|
|
583
|
-
async getIntent(idOrNumber) {
|
|
584
|
-
return this.request('GET', `/intents/${idOrNumber}
|
|
664
|
+
async getIntent(idOrNumber, options) {
|
|
665
|
+
return this.request('GET', `/intents/${idOrNumber}`, {
|
|
666
|
+
params: {
|
|
667
|
+
// `?logs=0` (API 10.0.0) skips the embedded work-log tail. The default —
|
|
668
|
+
// no parameter at all — keeps the body the endpoint always returned.
|
|
669
|
+
logs: options?.logs === false ? '0' : undefined,
|
|
670
|
+
// `?bundle=0` (API 10.1.0) strips the context bundle show embeds by default.
|
|
671
|
+
bundle: options?.bundle === false ? '0' : undefined,
|
|
672
|
+
// `?slim=1` (API 10.1.0) answers the freshness probe instead of the full
|
|
673
|
+
// body; server-side it wins over every other parameter.
|
|
674
|
+
slim: options?.slim ? '1' : undefined,
|
|
675
|
+
},
|
|
676
|
+
});
|
|
585
677
|
}
|
|
586
678
|
async createIntent(data) {
|
|
587
679
|
return this.request('POST', '/intents', { body: data });
|
|
@@ -606,7 +698,10 @@ export class CloudAdapter {
|
|
|
606
698
|
// ── Missions ──
|
|
607
699
|
async listMissions(options) {
|
|
608
700
|
return this.request('GET', '/missions', {
|
|
609
|
-
params: {
|
|
701
|
+
params: {
|
|
702
|
+
status: options?.status,
|
|
703
|
+
...this.pagingParams(options),
|
|
704
|
+
},
|
|
610
705
|
});
|
|
611
706
|
}
|
|
612
707
|
async getMission(idOrNumber) {
|
|
@@ -654,8 +749,14 @@ export { CloudAdapter as OrbitMapClient };
|
|
|
654
749
|
export async function createClient(explicitArea, options = {}) {
|
|
655
750
|
const config = options.config ?? (await loadConfig());
|
|
656
751
|
const auth = await resolveAuth({ config });
|
|
657
|
-
|
|
752
|
+
// The ladder is walked once when the caller already did it (`createAdapter` always has),
|
|
753
|
+
// and only re-walked here for the historical `createClient(area)` entry point. `--area a,b`
|
|
754
|
+
// names a LIST filter and no context area, so the raw flag can no longer be used as the
|
|
755
|
+
// header value — it goes through `resolveArea`, which splits the two apart.
|
|
756
|
+
const resolved = options.area !== undefined || options.areas !== undefined
|
|
757
|
+
? { area: options.area, areas: options.areas ?? [] }
|
|
758
|
+
: resolveArea({ config, ...(explicitArea !== undefined ? { area: explicitArea } : {}) });
|
|
658
759
|
const workspace = options.workspace ?? resolveWorkspaceId({ config }).workspace;
|
|
659
|
-
return new CloudAdapter(auth.apiKey, area, auth.apiUrl, workspace);
|
|
760
|
+
return new CloudAdapter(auth.apiKey, resolved.area, auth.apiUrl, workspace, resolved.areas);
|
|
660
761
|
}
|
|
661
762
|
//# sourceMappingURL=cloud.js.map
|