orbitmap 0.4.2 → 0.4.3
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 +60 -13
- package/dist/adapters/cloud.d.ts +53 -21
- package/dist/adapters/cloud.js +95 -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 +0 -20
- package/dist/adapters/local/adapter.js +0 -18
- 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/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 +9 -2
- package/dist/adapters/local/types.js +9 -2
- package/dist/adapters/local/types.js.map +1 -1
- package/dist/adapters/types.d.ts +7 -20
- package/dist/agent-instructions.d.ts +21 -8
- package/dist/agent-instructions.js +91 -35
- 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 +4 -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.js +10 -14
- 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 +1 -0
- package/dist/commands/log.js +18 -17
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/mission.js +3 -12
- 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 +265 -38
- 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 +134 -56
- 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/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 +1 -1
- 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
|
|
@@ -50,19 +50,35 @@ program
|
|
|
50
50
|
.version(version)
|
|
51
51
|
.option('--json', 'Output in JSON format', false)
|
|
52
52
|
.option('--area <id>', 'Area ID or slug to use')
|
|
53
|
-
.option('--workspace <path>', 'Local workspace directory to use (local mode)')
|
|
54
|
-
|
|
55
|
-
//
|
|
56
|
-
|
|
53
|
+
.option('--workspace <path>', 'Local workspace directory to use (local mode)')
|
|
54
|
+
.option('--workspace-id <slug-or-uuid>', 'Workspace to use (slug or UUID)')
|
|
55
|
+
// Satisfies the write-target confirmation non-interactively (see src/write-target.ts).
|
|
56
|
+
.option('--yes', 'Accept the resolved target area for writes without confirming', false);
|
|
57
|
+
// Both workspace flags are consumed by the resolver, not by the command modules, so
|
|
58
|
+
// capture them once before any action runs. They are different things: `--workspace` is a
|
|
59
|
+
// directory on this disk (and forces local mode), `--workspace-id` names a workspace in the
|
|
60
|
+
// backend and does not touch the mode.
|
|
61
|
+
//
|
|
62
|
+
// `--workspace-id` is read from the SUBCOMMAND first and only then from the program level.
|
|
63
|
+
// Previously only `thisCommand` (the program) was consulted, so `create-area --workspace-id`,
|
|
64
|
+
// `doc-import --workspace-id` and `init --workspace-id` put the value in the request body
|
|
65
|
+
// but never sent `X-Orbitmap-Workspace` — the same flag reached the header ladder or not
|
|
66
|
+
// purely depending on where the user typed it.
|
|
67
|
+
program.hook('preAction', (thisCommand, actionCommand) => {
|
|
57
68
|
setWorkspaceFlag(thisCommand.opts()['workspace']);
|
|
69
|
+
const subcommandWorkspaceId = actionCommand.opts()['workspaceId'];
|
|
70
|
+
setWorkspaceIdFlag(subcommandWorkspaceId ?? thisCommand.opts()['workspaceId']);
|
|
58
71
|
});
|
|
59
72
|
program
|
|
60
73
|
.command('init')
|
|
61
74
|
.description('Set up OrbitMap (cloud account or local files) and install the agent skills')
|
|
62
75
|
.option('--key <api-key>', 'Agent API key (enables non-interactive mode)')
|
|
63
76
|
.option('--token <api-key>', 'Alias for --key')
|
|
64
|
-
.option('--area <id>', '
|
|
77
|
+
.option('--area <id>', 'Area this directory is (cloud) or first area name (local)')
|
|
78
|
+
.option('--workspace-id <slug-or-uuid>', 'Cloud: workspace to set up (skips the workspace question)')
|
|
65
79
|
.option('--profile <profile>', 'MCP profile: full, lite, manager (default: full)')
|
|
80
|
+
.option('--allow-nested', 'Cloud: set up a workspace here even though another workspace root sits above or below ' +
|
|
81
|
+
'this directory')
|
|
66
82
|
.option('--advanced', 'Show advanced options (e.g. custom API URL)')
|
|
67
83
|
.option('--local', 'Set up local-files mode without the interactive question')
|
|
68
84
|
.option('--workspace <path>', 'Local workspace directory (default: ./.orbitmap)')
|
|
@@ -70,6 +86,8 @@ program
|
|
|
70
86
|
.option('--no-skills', 'Skip installing the OrbitMap agent skills')
|
|
71
87
|
.option('--agent <type>', 'Coding agent to install the skills for: claude, gemini, codex, cursor, windsurf, generic ' +
|
|
72
88
|
'(default: detected from this directory, or asked)')
|
|
89
|
+
.option('--scope <scope>', 'Where to install the skills: user (default, ~/.claude/skills — visible from every ' +
|
|
90
|
+
'directory) or project (this directory only)')
|
|
73
91
|
.option('--global', 'Cloud: write to ~/.orbitmap/config.json instead of ./.orbitmap/config.json')
|
|
74
92
|
.action(async (opts, command) => {
|
|
75
93
|
// `--workspace` also exists as a program-level flag, and Commander binds it there;
|
|
@@ -80,12 +98,17 @@ program
|
|
|
80
98
|
key: opts.key,
|
|
81
99
|
token: opts.token,
|
|
82
100
|
area: opts.area ?? all['area'],
|
|
101
|
+
// `--workspace-id` is also a program-level flag; take it from whichever position it
|
|
102
|
+
// was given in (same pattern as `--workspace` above).
|
|
103
|
+
workspaceId: opts.workspaceId ?? all['workspaceId'],
|
|
83
104
|
profile: opts.profile,
|
|
105
|
+
allowNested: opts.allowNested,
|
|
84
106
|
local: opts.local,
|
|
85
107
|
workspace: opts.workspace ?? all['workspace'],
|
|
86
108
|
workspaceName: opts.workspaceName,
|
|
87
109
|
skills: opts.skills,
|
|
88
110
|
agent: opts.agent,
|
|
111
|
+
scope: opts.scope,
|
|
89
112
|
global: opts.global,
|
|
90
113
|
});
|
|
91
114
|
});
|
|
@@ -121,7 +144,7 @@ program
|
|
|
121
144
|
.description('Create a new area')
|
|
122
145
|
.option('--desc <description>', 'Area description')
|
|
123
146
|
.option('--slug <slug>', 'Area slug (auto-generated from name if omitted)')
|
|
124
|
-
.option('--workspace-id <uuid>', 'Workspace to create the area in')
|
|
147
|
+
.option('--workspace-id <slug-or-uuid>', 'Workspace to create the area in (slug or UUID)')
|
|
125
148
|
.action(async (name, opts, cmd) => {
|
|
126
149
|
const globalOpts = cmd.optsWithGlobals();
|
|
127
150
|
await createAreaCommand(name, {
|
|
@@ -129,7 +152,9 @@ program
|
|
|
129
152
|
area: globalOpts.area,
|
|
130
153
|
desc: opts.desc,
|
|
131
154
|
slug: opts.slug,
|
|
132
|
-
|
|
155
|
+
// `--workspace-id` also exists as a program-level flag; `optsWithGlobals()` picks it
|
|
156
|
+
// up whichever position it was given in (same pattern as `--workspace` on `init`).
|
|
157
|
+
workspaceId: opts.workspaceId ?? globalOpts.workspaceId,
|
|
133
158
|
});
|
|
134
159
|
});
|
|
135
160
|
program
|
|
@@ -148,7 +173,8 @@ program
|
|
|
148
173
|
});
|
|
149
174
|
program
|
|
150
175
|
.command('tasks')
|
|
151
|
-
.description('List
|
|
176
|
+
.description('List tasks in the current area — or, when the context is workspace-scoped, every ' +
|
|
177
|
+
'area in the workspace grouped by area')
|
|
152
178
|
.option('--status <statuses>', 'Filter by status (comma-separated)', 'todo,in_progress')
|
|
153
179
|
.option('--priority <priority>', 'Filter by priority')
|
|
154
180
|
.option('--orbit <id-or-slug>', 'Filter by orbit (UUID or slug)')
|
|
@@ -209,6 +235,7 @@ program
|
|
|
209
235
|
await statusCommand(taskId, status, {
|
|
210
236
|
json: globalOpts.json,
|
|
211
237
|
area: globalOpts.area,
|
|
238
|
+
yes: globalOpts.yes,
|
|
212
239
|
delivery: opts.delivery,
|
|
213
240
|
force: opts.force,
|
|
214
241
|
});
|
|
@@ -220,17 +247,18 @@ program
|
|
|
220
247
|
.option('--priority <priority>', 'Priority (critical, high, medium, low)')
|
|
221
248
|
.option('--status <status>', 'Initial status')
|
|
222
249
|
.option('--effort <effort>', 'Estimated effort (e.g. 4h, 2d)')
|
|
223
|
-
.option('--agent-id <id>', 'Assign to agent')
|
|
250
|
+
.option('--agent-id <id-or-slug>', 'Assign to agent (UUID or slug)')
|
|
224
251
|
.option('--branch <name>', 'Git branch name')
|
|
225
252
|
.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)')
|
|
253
|
+
.option('--from-issue <id-or-number>', 'Link task to an existing issue (UUID or display number, e.g. IS-8hv2wn)')
|
|
254
|
+
.option('--intent <id-or-number>', 'Link task to an intent (UUID or display number, e.g. IN-rwb5qu)')
|
|
255
|
+
.option('--orbit <id-or-slug>', 'Attach task to an orbit (UUID or slug; omit to inherit the intent orbit)')
|
|
229
256
|
.action(async (title, opts, cmd) => {
|
|
230
257
|
const globalOpts = cmd.optsWithGlobals();
|
|
231
258
|
await createCommand(title, {
|
|
232
259
|
json: globalOpts.json,
|
|
233
260
|
area: globalOpts.area,
|
|
261
|
+
yes: globalOpts.yes,
|
|
234
262
|
desc: opts.desc,
|
|
235
263
|
priority: opts.priority,
|
|
236
264
|
status: opts.status,
|
|
@@ -254,14 +282,15 @@ program
|
|
|
254
282
|
await subtaskCommand(parentId, title, {
|
|
255
283
|
json: globalOpts.json,
|
|
256
284
|
area: globalOpts.area,
|
|
285
|
+
yes: globalOpts.yes,
|
|
257
286
|
desc: opts.desc,
|
|
258
287
|
priority: opts.priority,
|
|
259
288
|
effort: opts.effort,
|
|
260
289
|
});
|
|
261
290
|
});
|
|
262
291
|
program
|
|
263
|
-
.command('assign <id-or-number> [agent-id]')
|
|
264
|
-
.description('Assign a task, issue, idea, or intent to an agent or user')
|
|
292
|
+
.command('assign <id-or-number> [agent-id-or-slug]')
|
|
293
|
+
.description('Assign a task, issue, idea, or intent to an agent (UUID or slug) or user')
|
|
265
294
|
.option('--user-id <id>', 'Assign to a user (by user ID) instead of an agent')
|
|
266
295
|
.option('--type <type>', 'Object type: task, issue, idea, intent (auto-detected from prefixed IDs; default task)')
|
|
267
296
|
.action(async (objectId, agentId, opts, cmd) => {
|
|
@@ -269,6 +298,7 @@ program
|
|
|
269
298
|
await assignCommand(objectId, agentId, {
|
|
270
299
|
json: globalOpts.json,
|
|
271
300
|
area: globalOpts.area,
|
|
301
|
+
yes: globalOpts.yes,
|
|
272
302
|
userId: opts.userId,
|
|
273
303
|
type: opts.type,
|
|
274
304
|
});
|
|
@@ -276,13 +306,14 @@ program
|
|
|
276
306
|
program
|
|
277
307
|
.command('log <id-or-number> <message>')
|
|
278
308
|
.description('Log work on a task')
|
|
279
|
-
.option('--type <type>', 'Log type: note, code_change, decision, blocker
|
|
309
|
+
.option('--type <type>', 'Log type: note, code_change, decision, blocker', 'note')
|
|
280
310
|
.option('--meta <json>', 'JSON metadata (e.g. \'{"files":["..."]}\')')
|
|
281
311
|
.action(async (taskId, message, opts, cmd) => {
|
|
282
312
|
const globalOpts = cmd.optsWithGlobals();
|
|
283
313
|
await logCommand(taskId, message, {
|
|
284
314
|
json: globalOpts.json,
|
|
285
315
|
area: globalOpts.area,
|
|
316
|
+
yes: globalOpts.yes,
|
|
286
317
|
type: opts.type,
|
|
287
318
|
meta: opts.meta,
|
|
288
319
|
});
|
|
@@ -343,17 +374,20 @@ program
|
|
|
343
374
|
.requiredOption('--file <path>', 'Path to markdown file')
|
|
344
375
|
.option('--source-path <path>', 'Original source path for reference')
|
|
345
376
|
.option('--context <text>', 'Short description of when this document is relevant')
|
|
346
|
-
.option('--workspace-id <uuid>', 'Create as workspace-level document (cross-area knowledge)')
|
|
377
|
+
.option('--workspace-id <slug-or-uuid>', 'Create as workspace-level document (cross-area knowledge); slug or UUID')
|
|
347
378
|
.action(async (title, opts, cmd) => {
|
|
348
379
|
const globalOpts = cmd.optsWithGlobals();
|
|
349
380
|
await docImportCommand(title, {
|
|
350
381
|
json: globalOpts.json,
|
|
351
382
|
area: globalOpts.area,
|
|
383
|
+
yes: globalOpts.yes,
|
|
352
384
|
type: opts.type,
|
|
353
385
|
file: opts.file,
|
|
354
386
|
sourcePath: opts.sourcePath,
|
|
355
387
|
context: opts.context,
|
|
356
|
-
|
|
388
|
+
// Program-level `--workspace-id` is the fallback when it was given before the
|
|
389
|
+
// subcommand name (see `create-area`).
|
|
390
|
+
workspaceId: opts.workspaceId ?? globalOpts.workspaceId,
|
|
357
391
|
});
|
|
358
392
|
});
|
|
359
393
|
program
|
|
@@ -437,21 +471,33 @@ program
|
|
|
437
471
|
.description('Refresh the OrbitMap agent instructions/skills, or add another agent type ' +
|
|
438
472
|
'(`init` already installs them once)')
|
|
439
473
|
.option('--agent <type>', 'Agent type: claude, gemini, codex, cursor, windsurf, generic')
|
|
474
|
+
.option('--scope <scope>', 'Where to install: user (default, ~/.claude/skills — visible from every directory) ' +
|
|
475
|
+
'or project (this directory only)')
|
|
476
|
+
.option('--clean-project', 'With --scope user: remove an older project-scope install in this directory ' +
|
|
477
|
+
'(its four OrbitMap skill dirs + the OrbitMap block in the config file) without asking')
|
|
440
478
|
.action(async (opts) => {
|
|
441
|
-
await setupAgentCommand({
|
|
479
|
+
await setupAgentCommand({
|
|
480
|
+
agent: opts.agent,
|
|
481
|
+
scope: opts.scope,
|
|
482
|
+
cleanProject: opts.cleanProject,
|
|
483
|
+
});
|
|
442
484
|
});
|
|
443
485
|
program
|
|
444
486
|
.command('setup-mcp')
|
|
445
487
|
.description('Install OrbitMap MCP entry into .mcp.json in the current directory (no API calls)')
|
|
446
488
|
.option('--token <api-key>', 'Agent API key (Bearer auth)')
|
|
447
489
|
.option('--oauth', 'Use OAuth (no Authorization header; auth happens on first MCP use)')
|
|
448
|
-
.option('--
|
|
490
|
+
.option('--workspace-id <slug-or-uuid>', 'Workspace to pin in the generated block (X-Orbitmap-Workspace)')
|
|
491
|
+
.option('--area <slug>', 'Area slug or UUID to pin as well (X-Orbitmap-Area, optional)')
|
|
449
492
|
.option('--profile <profile>', 'MCP profile: full, lite, manager (default: full)')
|
|
450
493
|
.action(async (opts, cmd) => {
|
|
494
|
+
// `--workspace-id` also exists as a program-level flag; `optsWithGlobals()` picks it up
|
|
495
|
+
// whichever position it was given in (same pattern as `--area`).
|
|
451
496
|
const globalOpts = cmd.optsWithGlobals();
|
|
452
497
|
await setupMcpCommand({
|
|
453
498
|
token: opts.token,
|
|
454
499
|
oauth: opts.oauth,
|
|
500
|
+
workspaceId: opts.workspaceId || globalOpts.workspaceId,
|
|
455
501
|
area: opts.area || globalOpts.area,
|
|
456
502
|
profile: opts.profile,
|
|
457
503
|
});
|
|
@@ -538,19 +584,26 @@ const issue = program
|
|
|
538
584
|
.command('issue')
|
|
539
585
|
.description('Manage issues');
|
|
540
586
|
issue
|
|
541
|
-
.command('register')
|
|
587
|
+
.command('register [title]')
|
|
542
588
|
.description('Register a new issue')
|
|
543
|
-
|
|
589
|
+
// Title is positional, like `create`, `intent create`, `mission create` and `orbit create`.
|
|
590
|
+
// `--title` stays as a hidden back-compat alias.
|
|
591
|
+
.addOption(new Option('--title <title>', 'Deprecated: pass the title positionally').hideHelp())
|
|
544
592
|
.requiredOption('--description <text>', 'Issue description')
|
|
545
593
|
.option('--severity <level>', 'Severity: critical, high, medium, low')
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
594
|
+
// These two stay UUID-only: TS-av6332 relaxed `intent_id`/`orbit_id`/`source_issue_id` on
|
|
595
|
+
// POST /tasks to `App\Rules\EntityRef`, but IssueController still validates
|
|
596
|
+
// `related_task_id` and `intent_id` as `uuid`. Do not translate client-side — see the
|
|
597
|
+
// OrbitMap issue linked from TS-zhmvnc.
|
|
598
|
+
.option('--related-task <uuid>', 'Related task UUID (this endpoint does not accept display numbers)')
|
|
599
|
+
.option('--intent <uuid>', 'Link issue to an intent, by UUID (no display numbers here)')
|
|
600
|
+
.action(async (title, opts, cmd) => {
|
|
549
601
|
const globalOpts = cmd.optsWithGlobals();
|
|
550
602
|
await issueRegisterCommand({
|
|
551
603
|
json: globalOpts.json,
|
|
552
604
|
area: globalOpts.area,
|
|
553
|
-
|
|
605
|
+
yes: globalOpts.yes,
|
|
606
|
+
title: title ?? opts.title,
|
|
554
607
|
description: opts.description,
|
|
555
608
|
severity: opts.severity,
|
|
556
609
|
relatedTask: opts.relatedTask,
|
|
@@ -586,9 +639,11 @@ issue
|
|
|
586
639
|
issue
|
|
587
640
|
.command('resolve <id-or-number>')
|
|
588
641
|
.description('Resolve an issue')
|
|
589
|
-
|
|
642
|
+
// The command is named `resolve`, so `resolved` is the obvious default; --status stays
|
|
643
|
+
// available for the other two terminal states (wont_fix, duplicate).
|
|
644
|
+
.option('--status <status>', 'Resolve status: resolved, wont_fix, duplicate', 'resolved')
|
|
590
645
|
.option('--resolution <text>', 'Resolution description (required for resolved/wont_fix)')
|
|
591
|
-
.option('--resolved-task <
|
|
646
|
+
.option('--resolved-task <uuid>', 'Task UUID that resolved this issue (no display numbers here)')
|
|
592
647
|
.action(async (idOrNumber, opts, cmd) => {
|
|
593
648
|
const globalOpts = cmd.optsWithGlobals();
|
|
594
649
|
await issueResolveCommand(idOrNumber, {
|
|
@@ -601,9 +656,11 @@ issue
|
|
|
601
656
|
});
|
|
602
657
|
issue
|
|
603
658
|
.command('status <id-or-number> <status>')
|
|
604
|
-
.description('Update issue status
|
|
659
|
+
.description('Update issue status. Which move is legal depends on the current status ' +
|
|
660
|
+
'(open <-> investigating <-> backlog, any of them -> resolved/wont_fix/duplicate, ' +
|
|
661
|
+
'and those back to open); the server rejects anything else with INVALID_TRANSITION')
|
|
605
662
|
.option('--resolution <text>', 'Resolution description (required for resolved/wont_fix)')
|
|
606
|
-
.option('--resolved-task <
|
|
663
|
+
.option('--resolved-task <uuid>', 'Task UUID that resolved this issue (no display numbers here)')
|
|
607
664
|
.action(async (idOrNumber, status, opts, cmd) => {
|
|
608
665
|
const globalOpts = cmd.optsWithGlobals();
|
|
609
666
|
await issueStatusCommand(idOrNumber, status, {
|
|
@@ -618,18 +675,21 @@ const vibe = program
|
|
|
618
675
|
.command('vibe')
|
|
619
676
|
.description('Manage vibes');
|
|
620
677
|
vibe
|
|
621
|
-
.command('log')
|
|
678
|
+
.command('log [content]')
|
|
622
679
|
.description('Log a new vibe')
|
|
623
|
-
|
|
624
|
-
|
|
680
|
+
// Content is positional, matching every other "create something" command.
|
|
681
|
+
// `--content` stays as a hidden back-compat alias.
|
|
682
|
+
.addOption(new Option('--content <text>', 'Deprecated: pass the content positionally').hideHelp())
|
|
683
|
+
.requiredOption('--type <type>', 'Type: note, code_change, decision, discovery, exploration, fix')
|
|
625
684
|
.option('--title <title>', 'Optional title')
|
|
626
|
-
.option('--task <
|
|
627
|
-
.action(async (opts, cmd) => {
|
|
685
|
+
.option('--task <uuid>', 'Related task UUID (this endpoint does not accept display numbers)')
|
|
686
|
+
.action(async (content, opts, cmd) => {
|
|
628
687
|
const globalOpts = cmd.optsWithGlobals();
|
|
629
688
|
await vibeLogCommand({
|
|
630
689
|
json: globalOpts.json,
|
|
631
690
|
area: globalOpts.area,
|
|
632
|
-
|
|
691
|
+
yes: globalOpts.yes,
|
|
692
|
+
content: content ?? opts.content,
|
|
633
693
|
type: opts.type,
|
|
634
694
|
title: opts.title,
|
|
635
695
|
task: opts.task,
|
|
@@ -652,8 +712,8 @@ vibe
|
|
|
652
712
|
});
|
|
653
713
|
});
|
|
654
714
|
vibe
|
|
655
|
-
.command('show <id>')
|
|
656
|
-
.description('Show full vibe details')
|
|
715
|
+
.command('show <id-or-number>')
|
|
716
|
+
.description('Show full vibe details (UUID or display number, e.g. VB-a1b2c3)')
|
|
657
717
|
.action(async (id, _opts, cmd) => {
|
|
658
718
|
const globalOpts = cmd.optsWithGlobals();
|
|
659
719
|
await vibeShowCommand(id, {
|
|
@@ -662,8 +722,8 @@ vibe
|
|
|
662
722
|
});
|
|
663
723
|
});
|
|
664
724
|
vibe
|
|
665
|
-
.command('update <id>')
|
|
666
|
-
.description('Update a vibe')
|
|
725
|
+
.command('update <id-or-number>')
|
|
726
|
+
.description('Update a vibe (UUID or display number, e.g. VB-a1b2c3)')
|
|
667
727
|
.option('--type <type>', 'New type')
|
|
668
728
|
.option('--title <title>', 'New title')
|
|
669
729
|
.option('--content <text>', 'New content')
|
|
@@ -710,17 +770,20 @@ idea
|
|
|
710
770
|
});
|
|
711
771
|
});
|
|
712
772
|
idea
|
|
713
|
-
.command('add')
|
|
773
|
+
.command('add [content]')
|
|
714
774
|
.description('Add a new idea')
|
|
715
|
-
|
|
775
|
+
// Content is positional, matching every other "create something" command.
|
|
776
|
+
// `--content` stays as a hidden back-compat alias.
|
|
777
|
+
.addOption(new Option('--content <text>', 'Deprecated: pass the content positionally').hideHelp())
|
|
716
778
|
.option('--title <title>', 'Optional short title')
|
|
717
779
|
.option('--priority <priority>', 'Priority (critical, high, medium, low)')
|
|
718
|
-
.action(async (opts, cmd) => {
|
|
780
|
+
.action(async (content, opts, cmd) => {
|
|
719
781
|
const globalOpts = cmd.optsWithGlobals();
|
|
720
782
|
await ideaAddCommand({
|
|
721
783
|
json: globalOpts.json,
|
|
722
784
|
area: globalOpts.area,
|
|
723
|
-
|
|
785
|
+
yes: globalOpts.yes,
|
|
786
|
+
content: content ?? opts.content,
|
|
724
787
|
title: opts.title,
|
|
725
788
|
priority: opts.priority,
|
|
726
789
|
});
|
|
@@ -744,13 +807,23 @@ const orbit = program
|
|
|
744
807
|
orbit
|
|
745
808
|
.command('list')
|
|
746
809
|
.description('List orbits (workspace-scoped from the area context)')
|
|
747
|
-
.option('--workspace <
|
|
810
|
+
.option('--workspace-id <slug-or-uuid>', 'Filter by workspace (slug or UUID)')
|
|
811
|
+
// Back-compat: `--workspace <id>` was this filter's original spelling, which collided with
|
|
812
|
+
// the program-level `--workspace <path>` (a local directory that forces local mode).
|
|
813
|
+
// Hidden, still accepted, warns once.
|
|
814
|
+
.addOption(new Option('--workspace <slug-or-uuid>', 'Deprecated alias for --workspace-id').hideHelp())
|
|
748
815
|
.action(async (opts, cmd) => {
|
|
749
816
|
const globalOpts = cmd.optsWithGlobals();
|
|
817
|
+
if (opts.workspace && !opts.workspaceId) {
|
|
818
|
+
console.error('Warning: `orbit list --workspace` is deprecated (it collides with the global ' +
|
|
819
|
+
'`--workspace <path>`). Use `--workspace-id` instead.');
|
|
820
|
+
}
|
|
750
821
|
await orbitListCommand({
|
|
751
822
|
json: globalOpts.json,
|
|
752
823
|
area: globalOpts.area,
|
|
753
|
-
|
|
824
|
+
// Only the *subcommand* flags are considered: the global `--workspace` is a directory,
|
|
825
|
+
// never a filter. The global `--workspace-id` is picked up as the last fallback.
|
|
826
|
+
workspaceId: opts.workspaceId ?? opts.workspace ?? globalOpts.workspaceId,
|
|
754
827
|
});
|
|
755
828
|
});
|
|
756
829
|
orbit
|
|
@@ -813,7 +886,10 @@ orbit
|
|
|
813
886
|
.command('attach <orbit-id-or-slug>')
|
|
814
887
|
.description('Attach an object to an orbit')
|
|
815
888
|
.requiredOption('--type <type>', 'Object type: task, issue, vibe, idea, document')
|
|
816
|
-
|
|
889
|
+
// OrbitController::findOrbitItemObject now resolves display numbers via entityRefColumn()
|
|
890
|
+
// for the numbered types (task/issue/vibe/idea). Documents have no display number, so
|
|
891
|
+
// `--type document` still requires a UUID.
|
|
892
|
+
.requiredOption('--id <id-or-number>', 'Object UUID or display number (TS-/IS-/VB-/ID-); documents are UUID-only')
|
|
817
893
|
.option('--note <text>', 'Optional note for the attachment')
|
|
818
894
|
.action(async (orbitIdOrSlug, opts, cmd) => {
|
|
819
895
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -829,7 +905,7 @@ orbit
|
|
|
829
905
|
.command('detach <orbit-id-or-slug>')
|
|
830
906
|
.description('Detach an object from an orbit')
|
|
831
907
|
.requiredOption('--type <type>', 'Object type: task, issue, vibe, idea, document')
|
|
832
|
-
.requiredOption('--id <
|
|
908
|
+
.requiredOption('--id <id-or-number>', 'Object UUID or display number (TS-/IS-/VB-/ID-); documents are UUID-only')
|
|
833
909
|
.action(async (orbitIdOrSlug, opts, cmd) => {
|
|
834
910
|
const globalOpts = cmd.optsWithGlobals();
|
|
835
911
|
await orbitDetachCommand(orbitIdOrSlug, {
|
|
@@ -907,7 +983,9 @@ intent
|
|
|
907
983
|
.description('Create a new intent')
|
|
908
984
|
.option('--outcome <text>', 'Desired outcome')
|
|
909
985
|
.option('--status <status>', 'Initial status: new, design, plan, build, done, cancelled (default new)')
|
|
910
|
-
|
|
986
|
+
// PUT /intents/{id}/orbit validates `orbit_id` as `uuid|exists:orbits,id` — unlike
|
|
987
|
+
// POST /tasks it takes no slug. `orbit list` prints the UUID (TS-adanc8).
|
|
988
|
+
.option('--orbit <uuid>', 'Attach the intent to an orbit after creation (UUID, not a slug)')
|
|
911
989
|
.action(async (title, opts, cmd) => {
|
|
912
990
|
const globalOpts = cmd.optsWithGlobals();
|
|
913
991
|
await intentCreateCommand(title, {
|
|
@@ -938,7 +1016,7 @@ intent
|
|
|
938
1016
|
.command('link <id-or-number>')
|
|
939
1017
|
.description('Link a task or issue to an intent')
|
|
940
1018
|
.requiredOption('--type <type>', 'Object type: task, issue')
|
|
941
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1019
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
942
1020
|
.action(async (idOrNumber, opts, cmd) => {
|
|
943
1021
|
const globalOpts = cmd.optsWithGlobals();
|
|
944
1022
|
await intentLinkCommand(idOrNumber, {
|
|
@@ -952,7 +1030,7 @@ intent
|
|
|
952
1030
|
.command('unlink <id-or-number>')
|
|
953
1031
|
.description('Unlink a task or issue from an intent')
|
|
954
1032
|
.requiredOption('--type <type>', 'Object type: task, issue')
|
|
955
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1033
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
956
1034
|
.action(async (idOrNumber, opts, cmd) => {
|
|
957
1035
|
const globalOpts = cmd.optsWithGlobals();
|
|
958
1036
|
await intentUnlinkCommand(idOrNumber, {
|
|
@@ -963,8 +1041,8 @@ intent
|
|
|
963
1041
|
});
|
|
964
1042
|
});
|
|
965
1043
|
intent
|
|
966
|
-
.command('orbit <id-or-number> [orbit-
|
|
967
|
-
.description('Set or clear the orbit of an intent')
|
|
1044
|
+
.command('orbit <id-or-number> [orbit-uuid]')
|
|
1045
|
+
.description('Set or clear the orbit of an intent (the orbit is named by UUID, not by slug)')
|
|
968
1046
|
.option('--clear', 'Clear the orbit instead of setting one')
|
|
969
1047
|
.action(async (idOrNumber, orbitId, opts, cmd) => {
|
|
970
1048
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -1052,7 +1130,7 @@ mission
|
|
|
1052
1130
|
.command('link <id-or-number>')
|
|
1053
1131
|
.description('Link a task, issue, idea, or intent to a mission (clears intent_id on tasks/issues)')
|
|
1054
1132
|
.requiredOption('--type <type>', 'Object type: task, issue, idea, intent')
|
|
1055
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1133
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
1056
1134
|
.action(async (idOrNumber, opts, cmd) => {
|
|
1057
1135
|
const globalOpts = cmd.optsWithGlobals();
|
|
1058
1136
|
await missionLinkCommand(idOrNumber, {
|
|
@@ -1066,7 +1144,7 @@ mission
|
|
|
1066
1144
|
.command('unlink <id-or-number>')
|
|
1067
1145
|
.description('Unlink a directly-linked item from a mission')
|
|
1068
1146
|
.requiredOption('--type <type>', 'Object type: task, issue, idea, intent')
|
|
1069
|
-
.requiredOption('--id <uuid>', 'Object UUID')
|
|
1147
|
+
.requiredOption('--id <uuid>', 'Object UUID (this endpoint does not accept display numbers)')
|
|
1070
1148
|
.action(async (idOrNumber, opts, cmd) => {
|
|
1071
1149
|
const globalOpts = cmd.optsWithGlobals();
|
|
1072
1150
|
await missionUnlinkCommand(idOrNumber, {
|