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/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Command } from 'commander';
|
|
2
|
+
import { Command, Option } from 'commander';
|
|
3
3
|
import { initCommand } from './commands/init.js';
|
|
4
4
|
import { contextCommand } from './commands/context.js';
|
|
5
5
|
import { areasCommand } from './commands/areas.js';
|
|
@@ -35,7 +35,7 @@ import { depAddCommand, depRemoveCommand } from './commands/dep.js';
|
|
|
35
35
|
import { getCommand } from './commands/get.js';
|
|
36
36
|
import { createRequire } from 'node:module';
|
|
37
37
|
import { createAreaCommand } from './commands/create-area.js';
|
|
38
|
-
import { setWorkspaceFlag } from './workspace-resolve.js';
|
|
38
|
+
import { setWorkspaceFlag, setWorkspaceIdFlag } from './workspace-resolve.js';
|
|
39
39
|
const program = new Command();
|
|
40
40
|
/**
|
|
41
41
|
* `--version` reads the real package version instead of a hardcoded literal, which had gone
|
|
@@ -44,25 +44,55 @@ const program = new Command();
|
|
|
44
44
|
* always ships package.json in the tarball regardless of the `files` allow-list.
|
|
45
45
|
*/
|
|
46
46
|
const { version } = createRequire(import.meta.url)('../package.json');
|
|
47
|
+
/**
|
|
48
|
+
* Commander collector for a REPEATABLE option: each occurrence is appended, so `--log a
|
|
49
|
+
* --log b` arrives as `['a', 'b']` in the order typed. Without it Commander keeps only the
|
|
50
|
+
* last value, and a work log batch would silently lose every entry but one.
|
|
51
|
+
*
|
|
52
|
+
* Register with an explicit `[]` default (`.option(..., collect, [])`) — the default is the
|
|
53
|
+
* accumulator's seed, and Commander does not supply one.
|
|
54
|
+
*/
|
|
55
|
+
function collect(value, previous) {
|
|
56
|
+
return [...previous, value];
|
|
57
|
+
}
|
|
58
|
+
/** `--log` help text, identical on every command that carries a work log batch. */
|
|
59
|
+
const LOG_FLAG_HELP = 'Work log entry as <type>:<content>; repeatable, order preserved. ' +
|
|
60
|
+
'Types: note, code_change, decision, blocker. Required by the API when the status changes';
|
|
47
61
|
program
|
|
48
62
|
.name('orbitmap')
|
|
49
63
|
.description('CLI tool for OrbitMap Agent API')
|
|
50
64
|
.version(version)
|
|
51
65
|
.option('--json', 'Output in JSON format', false)
|
|
52
66
|
.option('--area <id>', 'Area ID or slug to use')
|
|
53
|
-
.option('--workspace <path>', 'Local workspace directory to use (local mode)')
|
|
54
|
-
|
|
55
|
-
//
|
|
56
|
-
|
|
67
|
+
.option('--workspace <path>', 'Local workspace directory to use (local mode)')
|
|
68
|
+
.option('--workspace-id <slug-or-uuid>', 'Workspace to use (slug or UUID)')
|
|
69
|
+
// Satisfies the write-target confirmation non-interactively (see src/write-target.ts).
|
|
70
|
+
.option('--yes', 'Accept the resolved target area for writes without confirming', false);
|
|
71
|
+
// Both workspace flags are consumed by the resolver, not by the command modules, so
|
|
72
|
+
// capture them once before any action runs. They are different things: `--workspace` is a
|
|
73
|
+
// directory on this disk (and forces local mode), `--workspace-id` names a workspace in the
|
|
74
|
+
// backend and does not touch the mode.
|
|
75
|
+
//
|
|
76
|
+
// `--workspace-id` is read from the SUBCOMMAND first and only then from the program level.
|
|
77
|
+
// Previously only `thisCommand` (the program) was consulted, so `create-area --workspace-id`,
|
|
78
|
+
// `doc-import --workspace-id` and `init --workspace-id` put the value in the request body
|
|
79
|
+
// but never sent `X-Orbitmap-Workspace` — the same flag reached the header ladder or not
|
|
80
|
+
// purely depending on where the user typed it.
|
|
81
|
+
program.hook('preAction', (thisCommand, actionCommand) => {
|
|
57
82
|
setWorkspaceFlag(thisCommand.opts()['workspace']);
|
|
83
|
+
const subcommandWorkspaceId = actionCommand.opts()['workspaceId'];
|
|
84
|
+
setWorkspaceIdFlag(subcommandWorkspaceId ?? thisCommand.opts()['workspaceId']);
|
|
58
85
|
});
|
|
59
86
|
program
|
|
60
87
|
.command('init')
|
|
61
88
|
.description('Set up OrbitMap (cloud account or local files) and install the agent skills')
|
|
62
89
|
.option('--key <api-key>', 'Agent API key (enables non-interactive mode)')
|
|
63
90
|
.option('--token <api-key>', 'Alias for --key')
|
|
64
|
-
.option('--area <id>', '
|
|
91
|
+
.option('--area <id>', 'Area this directory is (cloud) or first area name (local)')
|
|
92
|
+
.option('--workspace-id <slug-or-uuid>', 'Cloud: workspace to set up (skips the workspace question)')
|
|
65
93
|
.option('--profile <profile>', 'MCP profile: full, lite, manager (default: full)')
|
|
94
|
+
.option('--allow-nested', 'Cloud: set up a workspace here even though another workspace root sits above or below ' +
|
|
95
|
+
'this directory')
|
|
66
96
|
.option('--advanced', 'Show advanced options (e.g. custom API URL)')
|
|
67
97
|
.option('--local', 'Set up local-files mode without the interactive question')
|
|
68
98
|
.option('--workspace <path>', 'Local workspace directory (default: ./.orbitmap)')
|
|
@@ -70,6 +100,8 @@ program
|
|
|
70
100
|
.option('--no-skills', 'Skip installing the OrbitMap agent skills')
|
|
71
101
|
.option('--agent <type>', 'Coding agent to install the skills for: claude, gemini, codex, cursor, windsurf, generic ' +
|
|
72
102
|
'(default: detected from this directory, or asked)')
|
|
103
|
+
.option('--scope <scope>', 'Where to install the skills: user (default, ~/.claude/skills — visible from every ' +
|
|
104
|
+
'directory) or project (this directory only)')
|
|
73
105
|
.option('--global', 'Cloud: write to ~/.orbitmap/config.json instead of ./.orbitmap/config.json')
|
|
74
106
|
.action(async (opts, command) => {
|
|
75
107
|
// `--workspace` also exists as a program-level flag, and Commander binds it there;
|
|
@@ -80,12 +112,17 @@ program
|
|
|
80
112
|
key: opts.key,
|
|
81
113
|
token: opts.token,
|
|
82
114
|
area: opts.area ?? all['area'],
|
|
115
|
+
// `--workspace-id` is also a program-level flag; take it from whichever position it
|
|
116
|
+
// was given in (same pattern as `--workspace` above).
|
|
117
|
+
workspaceId: opts.workspaceId ?? all['workspaceId'],
|
|
83
118
|
profile: opts.profile,
|
|
119
|
+
allowNested: opts.allowNested,
|
|
84
120
|
local: opts.local,
|
|
85
121
|
workspace: opts.workspace ?? all['workspace'],
|
|
86
122
|
workspaceName: opts.workspaceName,
|
|
87
123
|
skills: opts.skills,
|
|
88
124
|
agent: opts.agent,
|
|
125
|
+
scope: opts.scope,
|
|
89
126
|
global: opts.global,
|
|
90
127
|
});
|
|
91
128
|
});
|
|
@@ -121,7 +158,7 @@ program
|
|
|
121
158
|
.description('Create a new area')
|
|
122
159
|
.option('--desc <description>', 'Area description')
|
|
123
160
|
.option('--slug <slug>', 'Area slug (auto-generated from name if omitted)')
|
|
124
|
-
.option('--workspace-id <uuid>', 'Workspace to create the area in')
|
|
161
|
+
.option('--workspace-id <slug-or-uuid>', 'Workspace to create the area in (slug or UUID)')
|
|
125
162
|
.action(async (name, opts, cmd) => {
|
|
126
163
|
const globalOpts = cmd.optsWithGlobals();
|
|
127
164
|
await createAreaCommand(name, {
|
|
@@ -129,7 +166,9 @@ program
|
|
|
129
166
|
area: globalOpts.area,
|
|
130
167
|
desc: opts.desc,
|
|
131
168
|
slug: opts.slug,
|
|
132
|
-
|
|
169
|
+
// `--workspace-id` also exists as a program-level flag; `optsWithGlobals()` picks it
|
|
170
|
+
// up whichever position it was given in (same pattern as `--workspace` on `init`).
|
|
171
|
+
workspaceId: opts.workspaceId ?? globalOpts.workspaceId,
|
|
133
172
|
});
|
|
134
173
|
});
|
|
135
174
|
program
|
|
@@ -148,7 +187,8 @@ program
|
|
|
148
187
|
});
|
|
149
188
|
program
|
|
150
189
|
.command('tasks')
|
|
151
|
-
.description('List
|
|
190
|
+
.description('List tasks in the current area — or, when the context is workspace-scoped, every ' +
|
|
191
|
+
'area in the workspace grouped by area')
|
|
152
192
|
.option('--status <statuses>', 'Filter by status (comma-separated)', 'todo,in_progress')
|
|
153
193
|
.option('--priority <priority>', 'Filter by priority')
|
|
154
194
|
.option('--orbit <id-or-slug>', 'Filter by orbit (UUID or slug)')
|
|
@@ -209,6 +249,7 @@ program
|
|
|
209
249
|
await statusCommand(taskId, status, {
|
|
210
250
|
json: globalOpts.json,
|
|
211
251
|
area: globalOpts.area,
|
|
252
|
+
yes: globalOpts.yes,
|
|
212
253
|
delivery: opts.delivery,
|
|
213
254
|
force: opts.force,
|
|
214
255
|
});
|
|
@@ -220,17 +261,18 @@ program
|
|
|
220
261
|
.option('--priority <priority>', 'Priority (critical, high, medium, low)')
|
|
221
262
|
.option('--status <status>', 'Initial status')
|
|
222
263
|
.option('--effort <effort>', 'Estimated effort (e.g. 4h, 2d)')
|
|
223
|
-
.option('--agent-id <id>', 'Assign to agent')
|
|
264
|
+
.option('--agent-id <id-or-slug>', 'Assign to agent (UUID or slug)')
|
|
224
265
|
.option('--branch <name>', 'Git branch name')
|
|
225
266
|
.option('--instructions <text>', 'Agent instructions')
|
|
226
|
-
.option('--from-issue <id-or-number>', 'Link task to an existing issue (UUID
|
|
227
|
-
.option('--intent <id>', 'Link task to an intent')
|
|
228
|
-
.option('--orbit <id>', 'Attach task to an orbit (omit to inherit the intent orbit)')
|
|
267
|
+
.option('--from-issue <id-or-number>', 'Link task to an existing issue (UUID or display number, e.g. IS-8hv2wn)')
|
|
268
|
+
.option('--intent <id-or-number>', 'Link task to an intent (UUID or display number, e.g. IN-rwb5qu)')
|
|
269
|
+
.option('--orbit <id-or-slug>', 'Attach task to an orbit (UUID or slug; omit to inherit the intent orbit)')
|
|
229
270
|
.action(async (title, opts, cmd) => {
|
|
230
271
|
const globalOpts = cmd.optsWithGlobals();
|
|
231
272
|
await createCommand(title, {
|
|
232
273
|
json: globalOpts.json,
|
|
233
274
|
area: globalOpts.area,
|
|
275
|
+
yes: globalOpts.yes,
|
|
234
276
|
desc: opts.desc,
|
|
235
277
|
priority: opts.priority,
|
|
236
278
|
status: opts.status,
|
|
@@ -254,14 +296,15 @@ program
|
|
|
254
296
|
await subtaskCommand(parentId, title, {
|
|
255
297
|
json: globalOpts.json,
|
|
256
298
|
area: globalOpts.area,
|
|
299
|
+
yes: globalOpts.yes,
|
|
257
300
|
desc: opts.desc,
|
|
258
301
|
priority: opts.priority,
|
|
259
302
|
effort: opts.effort,
|
|
260
303
|
});
|
|
261
304
|
});
|
|
262
305
|
program
|
|
263
|
-
.command('assign <id-or-number> [agent-id]')
|
|
264
|
-
.description('Assign a task, issue, idea, or intent to an agent or user')
|
|
306
|
+
.command('assign <id-or-number> [agent-id-or-slug]')
|
|
307
|
+
.description('Assign a task, issue, idea, or intent to an agent (UUID or slug) or user')
|
|
265
308
|
.option('--user-id <id>', 'Assign to a user (by user ID) instead of an agent')
|
|
266
309
|
.option('--type <type>', 'Object type: task, issue, idea, intent (auto-detected from prefixed IDs; default task)')
|
|
267
310
|
.action(async (objectId, agentId, opts, cmd) => {
|
|
@@ -269,21 +312,26 @@ program
|
|
|
269
312
|
await assignCommand(objectId, agentId, {
|
|
270
313
|
json: globalOpts.json,
|
|
271
314
|
area: globalOpts.area,
|
|
315
|
+
yes: globalOpts.yes,
|
|
272
316
|
userId: opts.userId,
|
|
273
317
|
type: opts.type,
|
|
274
318
|
});
|
|
275
319
|
});
|
|
276
320
|
program
|
|
277
321
|
.command('log <id-or-number> <message>')
|
|
278
|
-
.description('Log work on a task')
|
|
279
|
-
.option('--type <type>', 'Log type: note, code_change, decision, blocker
|
|
322
|
+
.description('Log work on a task, intent or mission (TS-/IN-/MS- number, or a UUID)')
|
|
323
|
+
.option('--type <type>', 'Log type: note, code_change, decision, blocker', 'note')
|
|
324
|
+
.option('--target <kind>', 'Which object a bare UUID names: task, intent, mission (default: read from the ' +
|
|
325
|
+
'TS-/IN-/MS- prefix, else task)')
|
|
280
326
|
.option('--meta <json>', 'JSON metadata (e.g. \'{"files":["..."]}\')')
|
|
281
|
-
.action(async (
|
|
327
|
+
.action(async (idOrNumber, message, opts, cmd) => {
|
|
282
328
|
const globalOpts = cmd.optsWithGlobals();
|
|
283
|
-
await logCommand(
|
|
329
|
+
await logCommand(idOrNumber, message, {
|
|
284
330
|
json: globalOpts.json,
|
|
285
331
|
area: globalOpts.area,
|
|
332
|
+
yes: globalOpts.yes,
|
|
286
333
|
type: opts.type,
|
|
334
|
+
target: opts.target,
|
|
287
335
|
meta: opts.meta,
|
|
288
336
|
});
|
|
289
337
|
});
|
|
@@ -343,17 +391,20 @@ program
|
|
|
343
391
|
.requiredOption('--file <path>', 'Path to markdown file')
|
|
344
392
|
.option('--source-path <path>', 'Original source path for reference')
|
|
345
393
|
.option('--context <text>', 'Short description of when this document is relevant')
|
|
346
|
-
.option('--workspace-id <uuid>', 'Create as workspace-level document (cross-area knowledge)')
|
|
394
|
+
.option('--workspace-id <slug-or-uuid>', 'Create as workspace-level document (cross-area knowledge); slug or UUID')
|
|
347
395
|
.action(async (title, opts, cmd) => {
|
|
348
396
|
const globalOpts = cmd.optsWithGlobals();
|
|
349
397
|
await docImportCommand(title, {
|
|
350
398
|
json: globalOpts.json,
|
|
351
399
|
area: globalOpts.area,
|
|
400
|
+
yes: globalOpts.yes,
|
|
352
401
|
type: opts.type,
|
|
353
402
|
file: opts.file,
|
|
354
403
|
sourcePath: opts.sourcePath,
|
|
355
404
|
context: opts.context,
|
|
356
|
-
|
|
405
|
+
// Program-level `--workspace-id` is the fallback when it was given before the
|
|
406
|
+
// subcommand name (see `create-area`).
|
|
407
|
+
workspaceId: opts.workspaceId ?? globalOpts.workspaceId,
|
|
357
408
|
});
|
|
358
409
|
});
|
|
359
410
|
program
|
|
@@ -437,21 +488,33 @@ program
|
|
|
437
488
|
.description('Refresh the OrbitMap agent instructions/skills, or add another agent type ' +
|
|
438
489
|
'(`init` already installs them once)')
|
|
439
490
|
.option('--agent <type>', 'Agent type: claude, gemini, codex, cursor, windsurf, generic')
|
|
491
|
+
.option('--scope <scope>', 'Where to install: user (default, ~/.claude/skills — visible from every directory) ' +
|
|
492
|
+
'or project (this directory only)')
|
|
493
|
+
.option('--clean-project', 'With --scope user: remove an older project-scope install in this directory ' +
|
|
494
|
+
'(its four OrbitMap skill dirs + the OrbitMap block in the config file) without asking')
|
|
440
495
|
.action(async (opts) => {
|
|
441
|
-
await setupAgentCommand({
|
|
496
|
+
await setupAgentCommand({
|
|
497
|
+
agent: opts.agent,
|
|
498
|
+
scope: opts.scope,
|
|
499
|
+
cleanProject: opts.cleanProject,
|
|
500
|
+
});
|
|
442
501
|
});
|
|
443
502
|
program
|
|
444
503
|
.command('setup-mcp')
|
|
445
504
|
.description('Install OrbitMap MCP entry into .mcp.json in the current directory (no API calls)')
|
|
446
505
|
.option('--token <api-key>', 'Agent API key (Bearer auth)')
|
|
447
506
|
.option('--oauth', 'Use OAuth (no Authorization header; auth happens on first MCP use)')
|
|
448
|
-
.option('--
|
|
507
|
+
.option('--workspace-id <slug-or-uuid>', 'Workspace to pin in the generated block (X-Orbitmap-Workspace)')
|
|
508
|
+
.option('--area <slug>', 'Area slug or UUID to pin as well (X-Orbitmap-Area, optional)')
|
|
449
509
|
.option('--profile <profile>', 'MCP profile: full, lite, manager (default: full)')
|
|
450
510
|
.action(async (opts, cmd) => {
|
|
511
|
+
// `--workspace-id` also exists as a program-level flag; `optsWithGlobals()` picks it up
|
|
512
|
+
// whichever position it was given in (same pattern as `--area`).
|
|
451
513
|
const globalOpts = cmd.optsWithGlobals();
|
|
452
514
|
await setupMcpCommand({
|
|
453
515
|
token: opts.token,
|
|
454
516
|
oauth: opts.oauth,
|
|
517
|
+
workspaceId: opts.workspaceId || globalOpts.workspaceId,
|
|
455
518
|
area: opts.area || globalOpts.area,
|
|
456
519
|
profile: opts.profile,
|
|
457
520
|
});
|
|
@@ -538,19 +601,26 @@ const issue = program
|
|
|
538
601
|
.command('issue')
|
|
539
602
|
.description('Manage issues');
|
|
540
603
|
issue
|
|
541
|
-
.command('register')
|
|
604
|
+
.command('register [title]')
|
|
542
605
|
.description('Register a new issue')
|
|
543
|
-
|
|
606
|
+
// Title is positional, like `create`, `intent create`, `mission create` and `orbit create`.
|
|
607
|
+
// `--title` stays as a hidden back-compat alias.
|
|
608
|
+
.addOption(new Option('--title <title>', 'Deprecated: pass the title positionally').hideHelp())
|
|
544
609
|
.requiredOption('--description <text>', 'Issue description')
|
|
545
610
|
.option('--severity <level>', 'Severity: critical, high, medium, low')
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
611
|
+
// These two stay UUID-only: TS-av6332 relaxed `intent_id`/`orbit_id`/`source_issue_id` on
|
|
612
|
+
// POST /tasks to `App\Rules\EntityRef`, but IssueController still validates
|
|
613
|
+
// `related_task_id` and `intent_id` as `uuid`. Do not translate client-side — see the
|
|
614
|
+
// OrbitMap issue linked from TS-zhmvnc.
|
|
615
|
+
.option('--related-task <uuid>', 'Related task UUID (this endpoint does not accept display numbers)')
|
|
616
|
+
.option('--intent <uuid>', 'Link issue to an intent, by UUID (no display numbers here)')
|
|
617
|
+
.action(async (title, opts, cmd) => {
|
|
549
618
|
const globalOpts = cmd.optsWithGlobals();
|
|
550
619
|
await issueRegisterCommand({
|
|
551
620
|
json: globalOpts.json,
|
|
552
621
|
area: globalOpts.area,
|
|
553
|
-
|
|
622
|
+
yes: globalOpts.yes,
|
|
623
|
+
title: title ?? opts.title,
|
|
554
624
|
description: opts.description,
|
|
555
625
|
severity: opts.severity,
|
|
556
626
|
relatedTask: opts.relatedTask,
|
|
@@ -586,9 +656,11 @@ issue
|
|
|
586
656
|
issue
|
|
587
657
|
.command('resolve <id-or-number>')
|
|
588
658
|
.description('Resolve an issue')
|
|
589
|
-
|
|
659
|
+
// The command is named `resolve`, so `resolved` is the obvious default; --status stays
|
|
660
|
+
// available for the other two terminal states (wont_fix, duplicate).
|
|
661
|
+
.option('--status <status>', 'Resolve status: resolved, wont_fix, duplicate', 'resolved')
|
|
590
662
|
.option('--resolution <text>', 'Resolution description (required for resolved/wont_fix)')
|
|
591
|
-
.option('--resolved-task <
|
|
663
|
+
.option('--resolved-task <uuid>', 'Task UUID that resolved this issue (no display numbers here)')
|
|
592
664
|
.action(async (idOrNumber, opts, cmd) => {
|
|
593
665
|
const globalOpts = cmd.optsWithGlobals();
|
|
594
666
|
await issueResolveCommand(idOrNumber, {
|
|
@@ -601,9 +673,11 @@ issue
|
|
|
601
673
|
});
|
|
602
674
|
issue
|
|
603
675
|
.command('status <id-or-number> <status>')
|
|
604
|
-
.description('Update issue status
|
|
676
|
+
.description('Update issue status. Which move is legal depends on the current status ' +
|
|
677
|
+
'(open <-> investigating <-> backlog, any of them -> resolved/wont_fix/duplicate, ' +
|
|
678
|
+
'and those back to open); the server rejects anything else with INVALID_TRANSITION')
|
|
605
679
|
.option('--resolution <text>', 'Resolution description (required for resolved/wont_fix)')
|
|
606
|
-
.option('--resolved-task <
|
|
680
|
+
.option('--resolved-task <uuid>', 'Task UUID that resolved this issue (no display numbers here)')
|
|
607
681
|
.action(async (idOrNumber, status, opts, cmd) => {
|
|
608
682
|
const globalOpts = cmd.optsWithGlobals();
|
|
609
683
|
await issueStatusCommand(idOrNumber, status, {
|
|
@@ -618,18 +692,21 @@ const vibe = program
|
|
|
618
692
|
.command('vibe')
|
|
619
693
|
.description('Manage vibes');
|
|
620
694
|
vibe
|
|
621
|
-
.command('log')
|
|
695
|
+
.command('log [content]')
|
|
622
696
|
.description('Log a new vibe')
|
|
623
|
-
|
|
624
|
-
|
|
697
|
+
// Content is positional, matching every other "create something" command.
|
|
698
|
+
// `--content` stays as a hidden back-compat alias.
|
|
699
|
+
.addOption(new Option('--content <text>', 'Deprecated: pass the content positionally').hideHelp())
|
|
700
|
+
.requiredOption('--type <type>', 'Type: note, code_change, decision, discovery, exploration, fix')
|
|
625
701
|
.option('--title <title>', 'Optional title')
|
|
626
|
-
.option('--task <
|
|
627
|
-
.action(async (opts, cmd) => {
|
|
702
|
+
.option('--task <uuid>', 'Related task UUID (this endpoint does not accept display numbers)')
|
|
703
|
+
.action(async (content, opts, cmd) => {
|
|
628
704
|
const globalOpts = cmd.optsWithGlobals();
|
|
629
705
|
await vibeLogCommand({
|
|
630
706
|
json: globalOpts.json,
|
|
631
707
|
area: globalOpts.area,
|
|
632
|
-
|
|
708
|
+
yes: globalOpts.yes,
|
|
709
|
+
content: content ?? opts.content,
|
|
633
710
|
type: opts.type,
|
|
634
711
|
title: opts.title,
|
|
635
712
|
task: opts.task,
|
|
@@ -652,8 +729,8 @@ vibe
|
|
|
652
729
|
});
|
|
653
730
|
});
|
|
654
731
|
vibe
|
|
655
|
-
.command('show <id>')
|
|
656
|
-
.description('Show full vibe details')
|
|
732
|
+
.command('show <id-or-number>')
|
|
733
|
+
.description('Show full vibe details (UUID or display number, e.g. VB-a1b2c3)')
|
|
657
734
|
.action(async (id, _opts, cmd) => {
|
|
658
735
|
const globalOpts = cmd.optsWithGlobals();
|
|
659
736
|
await vibeShowCommand(id, {
|
|
@@ -662,8 +739,8 @@ vibe
|
|
|
662
739
|
});
|
|
663
740
|
});
|
|
664
741
|
vibe
|
|
665
|
-
.command('update <id>')
|
|
666
|
-
.description('Update a vibe')
|
|
742
|
+
.command('update <id-or-number>')
|
|
743
|
+
.description('Update a vibe (UUID or display number, e.g. VB-a1b2c3)')
|
|
667
744
|
.option('--type <type>', 'New type')
|
|
668
745
|
.option('--title <title>', 'New title')
|
|
669
746
|
.option('--content <text>', 'New content')
|
|
@@ -710,17 +787,20 @@ idea
|
|
|
710
787
|
});
|
|
711
788
|
});
|
|
712
789
|
idea
|
|
713
|
-
.command('add')
|
|
790
|
+
.command('add [content]')
|
|
714
791
|
.description('Add a new idea')
|
|
715
|
-
|
|
792
|
+
// Content is positional, matching every other "create something" command.
|
|
793
|
+
// `--content` stays as a hidden back-compat alias.
|
|
794
|
+
.addOption(new Option('--content <text>', 'Deprecated: pass the content positionally').hideHelp())
|
|
716
795
|
.option('--title <title>', 'Optional short title')
|
|
717
796
|
.option('--priority <priority>', 'Priority (critical, high, medium, low)')
|
|
718
|
-
.action(async (opts, cmd) => {
|
|
797
|
+
.action(async (content, opts, cmd) => {
|
|
719
798
|
const globalOpts = cmd.optsWithGlobals();
|
|
720
799
|
await ideaAddCommand({
|
|
721
800
|
json: globalOpts.json,
|
|
722
801
|
area: globalOpts.area,
|
|
723
|
-
|
|
802
|
+
yes: globalOpts.yes,
|
|
803
|
+
content: content ?? opts.content,
|
|
724
804
|
title: opts.title,
|
|
725
805
|
priority: opts.priority,
|
|
726
806
|
});
|
|
@@ -744,13 +824,23 @@ const orbit = program
|
|
|
744
824
|
orbit
|
|
745
825
|
.command('list')
|
|
746
826
|
.description('List orbits (workspace-scoped from the area context)')
|
|
747
|
-
.option('--workspace <
|
|
827
|
+
.option('--workspace-id <slug-or-uuid>', 'Filter by workspace (slug or UUID)')
|
|
828
|
+
// Back-compat: `--workspace <id>` was this filter's original spelling, which collided with
|
|
829
|
+
// the program-level `--workspace <path>` (a local directory that forces local mode).
|
|
830
|
+
// Hidden, still accepted, warns once.
|
|
831
|
+
.addOption(new Option('--workspace <slug-or-uuid>', 'Deprecated alias for --workspace-id').hideHelp())
|
|
748
832
|
.action(async (opts, cmd) => {
|
|
749
833
|
const globalOpts = cmd.optsWithGlobals();
|
|
834
|
+
if (opts.workspace && !opts.workspaceId) {
|
|
835
|
+
console.error('Warning: `orbit list --workspace` is deprecated (it collides with the global ' +
|
|
836
|
+
'`--workspace <path>`). Use `--workspace-id` instead.');
|
|
837
|
+
}
|
|
750
838
|
await orbitListCommand({
|
|
751
839
|
json: globalOpts.json,
|
|
752
840
|
area: globalOpts.area,
|
|
753
|
-
|
|
841
|
+
// Only the *subcommand* flags are considered: the global `--workspace` is a directory,
|
|
842
|
+
// never a filter. The global `--workspace-id` is picked up as the last fallback.
|
|
843
|
+
workspaceId: opts.workspaceId ?? opts.workspace ?? globalOpts.workspaceId,
|
|
754
844
|
});
|
|
755
845
|
});
|
|
756
846
|
orbit
|
|
@@ -813,7 +903,10 @@ orbit
|
|
|
813
903
|
.command('attach <orbit-id-or-slug>')
|
|
814
904
|
.description('Attach an object to an orbit')
|
|
815
905
|
.requiredOption('--type <type>', 'Object type: task, issue, vibe, idea, document')
|
|
816
|
-
|
|
906
|
+
// OrbitController::findOrbitItemObject now resolves display numbers via entityRefColumn()
|
|
907
|
+
// for the numbered types (task/issue/vibe/idea). Documents have no display number, so
|
|
908
|
+
// `--type document` still requires a UUID.
|
|
909
|
+
.requiredOption('--id <id-or-number>', 'Object UUID or display number (TS-/IS-/VB-/ID-); documents are UUID-only')
|
|
817
910
|
.option('--note <text>', 'Optional note for the attachment')
|
|
818
911
|
.action(async (orbitIdOrSlug, opts, cmd) => {
|
|
819
912
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -829,7 +922,7 @@ orbit
|
|
|
829
922
|
.command('detach <orbit-id-or-slug>')
|
|
830
923
|
.description('Detach an object from an orbit')
|
|
831
924
|
.requiredOption('--type <type>', 'Object type: task, issue, vibe, idea, document')
|
|
832
|
-
.requiredOption('--id <
|
|
925
|
+
.requiredOption('--id <id-or-number>', 'Object UUID or display number (TS-/IS-/VB-/ID-); documents are UUID-only')
|
|
833
926
|
.action(async (orbitIdOrSlug, opts, cmd) => {
|
|
834
927
|
const globalOpts = cmd.optsWithGlobals();
|
|
835
928
|
await orbitDetachCommand(orbitIdOrSlug, {
|
|
@@ -906,24 +999,33 @@ intent
|
|
|
906
999
|
.command('create <title>')
|
|
907
1000
|
.description('Create a new intent')
|
|
908
1001
|
.option('--outcome <text>', 'Desired outcome')
|
|
1002
|
+
.option('--design <text>', 'Design notes (markdown)')
|
|
1003
|
+
.option('--plan <text>', 'Plan notes (markdown)')
|
|
909
1004
|
.option('--status <status>', 'Initial status: new, design, plan, build, done, cancelled (default new)')
|
|
910
|
-
|
|
1005
|
+
// PUT /intents/{id}/orbit validates `orbit_id` as `uuid|exists:orbits,id` — unlike
|
|
1006
|
+
// POST /tasks it takes no slug. `orbit list` prints the UUID (TS-adanc8).
|
|
1007
|
+
.option('--orbit <uuid>', 'Attach the intent to an orbit after creation (UUID, not a slug)')
|
|
911
1008
|
.action(async (title, opts, cmd) => {
|
|
912
1009
|
const globalOpts = cmd.optsWithGlobals();
|
|
913
1010
|
await intentCreateCommand(title, {
|
|
914
1011
|
json: globalOpts.json,
|
|
915
1012
|
area: globalOpts.area,
|
|
916
1013
|
outcome: opts.outcome,
|
|
1014
|
+
design: opts.design,
|
|
1015
|
+
plan: opts.plan,
|
|
917
1016
|
status: opts.status,
|
|
918
1017
|
orbit: opts.orbit,
|
|
919
1018
|
});
|
|
920
1019
|
});
|
|
921
1020
|
intent
|
|
922
1021
|
.command('update <id-or-number>')
|
|
923
|
-
.description('Update an intent (title, outcome, status)')
|
|
1022
|
+
.description('Update an intent (title, outcome, design, plan, status)')
|
|
924
1023
|
.option('--title <title>', 'New title')
|
|
925
1024
|
.option('--outcome <text>', 'New outcome')
|
|
1025
|
+
.option('--design <text>', 'New design notes (markdown)')
|
|
1026
|
+
.option('--plan <text>', 'New plan notes (markdown)')
|
|
926
1027
|
.option('--status <status>', 'Status: new, design, plan, build, done, cancelled')
|
|
1028
|
+
.option('--log <type:content>', LOG_FLAG_HELP, collect, [])
|
|
927
1029
|
.action(async (idOrNumber, opts, cmd) => {
|
|
928
1030
|
const globalOpts = cmd.optsWithGlobals();
|
|
929
1031
|
await intentUpdateCommand(idOrNumber, {
|
|
@@ -931,14 +1033,17 @@ intent
|
|
|
931
1033
|
area: globalOpts.area,
|
|
932
1034
|
title: opts.title,
|
|
933
1035
|
outcome: opts.outcome,
|
|
1036
|
+
design: opts.design,
|
|
1037
|
+
plan: opts.plan,
|
|
934
1038
|
status: opts.status,
|
|
1039
|
+
log: opts.log,
|
|
935
1040
|
});
|
|
936
1041
|
});
|
|
937
1042
|
intent
|
|
938
1043
|
.command('link <id-or-number>')
|
|
939
1044
|
.description('Link a task or issue to an intent')
|
|
940
1045
|
.requiredOption('--type <type>', 'Object type: task, issue')
|
|
941
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1046
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
942
1047
|
.action(async (idOrNumber, opts, cmd) => {
|
|
943
1048
|
const globalOpts = cmd.optsWithGlobals();
|
|
944
1049
|
await intentLinkCommand(idOrNumber, {
|
|
@@ -952,7 +1057,7 @@ intent
|
|
|
952
1057
|
.command('unlink <id-or-number>')
|
|
953
1058
|
.description('Unlink a task or issue from an intent')
|
|
954
1059
|
.requiredOption('--type <type>', 'Object type: task, issue')
|
|
955
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1060
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
956
1061
|
.action(async (idOrNumber, opts, cmd) => {
|
|
957
1062
|
const globalOpts = cmd.optsWithGlobals();
|
|
958
1063
|
await intentUnlinkCommand(idOrNumber, {
|
|
@@ -963,8 +1068,8 @@ intent
|
|
|
963
1068
|
});
|
|
964
1069
|
});
|
|
965
1070
|
intent
|
|
966
|
-
.command('orbit <id-or-number> [orbit-
|
|
967
|
-
.description('Set or clear the orbit of an intent')
|
|
1071
|
+
.command('orbit <id-or-number> [orbit-uuid]')
|
|
1072
|
+
.description('Set or clear the orbit of an intent (the orbit is named by UUID, not by slug)')
|
|
968
1073
|
.option('--clear', 'Clear the orbit instead of setting one')
|
|
969
1074
|
.action(async (idOrNumber, orbitId, opts, cmd) => {
|
|
970
1075
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -1025,6 +1130,7 @@ mission
|
|
|
1025
1130
|
.option('--desc <description>', 'New description')
|
|
1026
1131
|
.option('--outcome <text>', 'New outcome')
|
|
1027
1132
|
.option('--end-date <date>', 'New end date (YYYY-MM-DD)')
|
|
1133
|
+
.option('--log <type:content>', LOG_FLAG_HELP, collect, [])
|
|
1028
1134
|
.action(async (idOrNumber, opts, cmd) => {
|
|
1029
1135
|
const globalOpts = cmd.optsWithGlobals();
|
|
1030
1136
|
await missionUpdateCommand(idOrNumber, {
|
|
@@ -1034,25 +1140,28 @@ mission
|
|
|
1034
1140
|
desc: opts.desc,
|
|
1035
1141
|
outcome: opts.outcome,
|
|
1036
1142
|
endDate: opts.endDate,
|
|
1143
|
+
log: opts.log,
|
|
1037
1144
|
});
|
|
1038
1145
|
});
|
|
1039
1146
|
mission
|
|
1040
1147
|
.command('status <id-or-number> <status>')
|
|
1041
1148
|
.description('Set mission lifecycle status (active, completed, cancelled; only one mission can be active)')
|
|
1042
1149
|
.option('--move-to <mission-id>', 'Mission to move unfinished work to when completing/cancelling')
|
|
1150
|
+
.option('--log <type:content>', LOG_FLAG_HELP, collect, [])
|
|
1043
1151
|
.action(async (idOrNumber, status, opts, cmd) => {
|
|
1044
1152
|
const globalOpts = cmd.optsWithGlobals();
|
|
1045
1153
|
await missionStatusCommand(idOrNumber, status, {
|
|
1046
1154
|
json: globalOpts.json,
|
|
1047
1155
|
area: globalOpts.area,
|
|
1048
1156
|
moveTo: opts.moveTo,
|
|
1157
|
+
log: opts.log,
|
|
1049
1158
|
});
|
|
1050
1159
|
});
|
|
1051
1160
|
mission
|
|
1052
1161
|
.command('link <id-or-number>')
|
|
1053
1162
|
.description('Link a task, issue, idea, or intent to a mission (clears intent_id on tasks/issues)')
|
|
1054
1163
|
.requiredOption('--type <type>', 'Object type: task, issue, idea, intent')
|
|
1055
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1164
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
1056
1165
|
.action(async (idOrNumber, opts, cmd) => {
|
|
1057
1166
|
const globalOpts = cmd.optsWithGlobals();
|
|
1058
1167
|
await missionLinkCommand(idOrNumber, {
|
|
@@ -1066,7 +1175,7 @@ mission
|
|
|
1066
1175
|
.command('unlink <id-or-number>')
|
|
1067
1176
|
.description('Unlink a directly-linked item from a mission')
|
|
1068
1177
|
.requiredOption('--type <type>', 'Object type: task, issue, idea, intent')
|
|
1069
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1178
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
1070
1179
|
.action(async (idOrNumber, opts, cmd) => {
|
|
1071
1180
|
const globalOpts = cmd.optsWithGlobals();
|
|
1072
1181
|
await missionUnlinkCommand(idOrNumber, {
|