orbitmap 0.3.0 → 0.4.1

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.
Files changed (174) hide show
  1. package/README.md +546 -212
  2. package/dist/adapters/cloud.d.ts +367 -0
  3. package/dist/adapters/cloud.js +582 -0
  4. package/dist/adapters/cloud.js.map +1 -0
  5. package/dist/adapters/factory.d.ts +15 -0
  6. package/dist/adapters/factory.js +31 -0
  7. package/dist/adapters/factory.js.map +1 -0
  8. package/dist/adapters/local/adapter.d.ts +351 -0
  9. package/dist/adapters/local/adapter.js +346 -0
  10. package/dist/adapters/local/adapter.js.map +1 -0
  11. package/dist/adapters/local/context.d.ts +112 -0
  12. package/dist/adapters/local/context.js +137 -0
  13. package/dist/adapters/local/context.js.map +1 -0
  14. package/dist/adapters/local/entities/documents.d.ts +85 -0
  15. package/dist/adapters/local/entities/documents.js +251 -0
  16. package/dist/adapters/local/entities/documents.js.map +1 -0
  17. package/dist/adapters/local/entities/planning.d.ts +108 -0
  18. package/dist/adapters/local/entities/planning.js +540 -0
  19. package/dist/adapters/local/entities/planning.js.map +1 -0
  20. package/dist/adapters/local/entities/tasks.d.ts +95 -0
  21. package/dist/adapters/local/entities/tasks.js +442 -0
  22. package/dist/adapters/local/entities/tasks.js.map +1 -0
  23. package/dist/adapters/local/entities/work-items.d.ts +110 -0
  24. package/dist/adapters/local/entities/work-items.js +623 -0
  25. package/dist/adapters/local/entities/work-items.js.map +1 -0
  26. package/dist/adapters/local/rules.d.ts +172 -0
  27. package/dist/adapters/local/rules.js +319 -0
  28. package/dist/adapters/local/rules.js.map +1 -0
  29. package/dist/adapters/local/shapes.d.ts +209 -0
  30. package/dist/adapters/local/shapes.js +558 -0
  31. package/dist/adapters/local/shapes.js.map +1 -0
  32. package/dist/adapters/local/store.d.ts +200 -0
  33. package/dist/adapters/local/store.js +665 -0
  34. package/dist/adapters/local/store.js.map +1 -0
  35. package/dist/adapters/local/types.d.ts +226 -0
  36. package/dist/adapters/local/types.js +41 -0
  37. package/dist/adapters/local/types.js.map +1 -0
  38. package/dist/adapters/types.d.ts +332 -0
  39. package/dist/adapters/types.js +2 -0
  40. package/dist/adapters/types.js.map +1 -0
  41. package/dist/agent-instructions.d.ts +25 -9
  42. package/dist/agent-instructions.js +285 -237
  43. package/dist/agent-instructions.js.map +1 -1
  44. package/dist/api-client.d.ts +8 -239
  45. package/dist/api-client.js +8 -403
  46. package/dist/api-client.js.map +1 -1
  47. package/dist/commands/agents.d.ts +1 -1
  48. package/dist/commands/agents.js +10 -10
  49. package/dist/commands/agents.js.map +1 -1
  50. package/dist/commands/areas.d.ts +3 -0
  51. package/dist/commands/areas.js +29 -0
  52. package/dist/commands/areas.js.map +1 -0
  53. package/dist/commands/assign.d.ts +3 -2
  54. package/dist/commands/assign.js +52 -15
  55. package/dist/commands/assign.js.map +1 -1
  56. package/dist/commands/context.d.ts +1 -1
  57. package/dist/commands/context.js +18 -12
  58. package/dist/commands/context.js.map +1 -1
  59. package/dist/commands/create-area.d.ts +7 -0
  60. package/dist/commands/create-area.js +29 -0
  61. package/dist/commands/create-area.js.map +1 -0
  62. package/dist/commands/create.d.ts +3 -1
  63. package/dist/commands/create.js +5 -8
  64. package/dist/commands/create.js.map +1 -1
  65. package/dist/commands/dep.d.ts +2 -2
  66. package/dist/commands/dep.js +3 -3
  67. package/dist/commands/dep.js.map +1 -1
  68. package/dist/commands/doc-import.d.ts +1 -1
  69. package/dist/commands/doc-import.js +2 -2
  70. package/dist/commands/doc-import.js.map +1 -1
  71. package/dist/commands/doc-patch.d.ts +1 -1
  72. package/dist/commands/doc-patch.js +2 -2
  73. package/dist/commands/doc-patch.js.map +1 -1
  74. package/dist/commands/doc-share.d.ts +6 -6
  75. package/dist/commands/doc-share.js +13 -13
  76. package/dist/commands/doc-share.js.map +1 -1
  77. package/dist/commands/doc-update.d.ts +1 -1
  78. package/dist/commands/doc-update.js +2 -2
  79. package/dist/commands/doc-update.js.map +1 -1
  80. package/dist/commands/doc.d.ts +1 -1
  81. package/dist/commands/doc.js +5 -4
  82. package/dist/commands/doc.js.map +1 -1
  83. package/dist/commands/docs-cache.d.ts +2 -2
  84. package/dist/commands/docs-cache.js +3 -3
  85. package/dist/commands/docs-cache.js.map +1 -1
  86. package/dist/commands/docs.d.ts +1 -1
  87. package/dist/commands/docs.js +2 -2
  88. package/dist/commands/docs.js.map +1 -1
  89. package/dist/commands/get.d.ts +1 -1
  90. package/dist/commands/get.js +43 -3
  91. package/dist/commands/get.js.map +1 -1
  92. package/dist/commands/ideas.d.ts +4 -4
  93. package/dist/commands/ideas.js +6 -11
  94. package/dist/commands/ideas.js.map +1 -1
  95. package/dist/commands/init.d.ts +45 -3
  96. package/dist/commands/init.js +452 -104
  97. package/dist/commands/init.js.map +1 -1
  98. package/dist/commands/intent.d.ts +41 -0
  99. package/dist/commands/intent.js +237 -0
  100. package/dist/commands/intent.js.map +1 -0
  101. package/dist/commands/issues.d.ts +6 -5
  102. package/dist/commands/issues.js +8 -12
  103. package/dist/commands/issues.js.map +1 -1
  104. package/dist/commands/log.d.ts +1 -1
  105. package/dist/commands/log.js +2 -2
  106. package/dist/commands/log.js.map +1 -1
  107. package/dist/commands/mission.d.ts +42 -0
  108. package/dist/commands/mission.js +219 -0
  109. package/dist/commands/mission.js.map +1 -0
  110. package/dist/commands/orbit.d.ts +40 -3
  111. package/dist/commands/orbit.js +231 -58
  112. package/dist/commands/orbit.js.map +1 -1
  113. package/dist/commands/overview.d.ts +2 -2
  114. package/dist/commands/overview.js +25 -28
  115. package/dist/commands/overview.js.map +1 -1
  116. package/dist/commands/setup-agent.d.ts +27 -0
  117. package/dist/commands/setup-agent.js +85 -30
  118. package/dist/commands/setup-agent.js.map +1 -1
  119. package/dist/commands/setup-mcp.d.ts +1 -1
  120. package/dist/commands/setup-mcp.js +20 -49
  121. package/dist/commands/setup-mcp.js.map +1 -1
  122. package/dist/commands/start.d.ts +1 -1
  123. package/dist/commands/start.js +2 -2
  124. package/dist/commands/start.js.map +1 -1
  125. package/dist/commands/status.d.ts +2 -1
  126. package/dist/commands/status.js +3 -3
  127. package/dist/commands/status.js.map +1 -1
  128. package/dist/commands/subtask.d.ts +1 -1
  129. package/dist/commands/subtask.js +2 -2
  130. package/dist/commands/subtask.js.map +1 -1
  131. package/dist/commands/task-edit-content.d.ts +1 -1
  132. package/dist/commands/task-edit-content.js +2 -2
  133. package/dist/commands/task-edit-content.js.map +1 -1
  134. package/dist/commands/task.d.ts +10 -3
  135. package/dist/commands/task.js +19 -21
  136. package/dist/commands/task.js.map +1 -1
  137. package/dist/commands/tasks.d.ts +1 -1
  138. package/dist/commands/tasks.js +2 -2
  139. package/dist/commands/tasks.js.map +1 -1
  140. package/dist/commands/vibes.d.ts +4 -4
  141. package/dist/commands/vibes.js +5 -5
  142. package/dist/commands/vibes.js.map +1 -1
  143. package/dist/config.d.ts +69 -9
  144. package/dist/config.js +206 -23
  145. package/dist/config.js.map +1 -1
  146. package/dist/doc-cache.d.ts +23 -3
  147. package/dist/doc-cache.js +72 -12
  148. package/dist/doc-cache.js.map +1 -1
  149. package/dist/errors.d.ts +19 -2
  150. package/dist/errors.js +35 -0
  151. package/dist/errors.js.map +1 -1
  152. package/dist/id-resolve.d.ts +61 -0
  153. package/dist/id-resolve.js +87 -0
  154. package/dist/id-resolve.js.map +1 -0
  155. package/dist/index.js +477 -104
  156. package/dist/index.js.map +1 -1
  157. package/dist/mcp-config.d.ts +36 -0
  158. package/dist/mcp-config.js +51 -0
  159. package/dist/mcp-config.js.map +1 -0
  160. package/dist/oauth.d.ts +8 -0
  161. package/dist/oauth.js +54 -15
  162. package/dist/oauth.js.map +1 -1
  163. package/dist/output.js +7 -2
  164. package/dist/output.js.map +1 -1
  165. package/dist/paths.d.ts +97 -0
  166. package/dist/paths.js +178 -0
  167. package/dist/paths.js.map +1 -0
  168. package/dist/project-config.d.ts +75 -0
  169. package/dist/project-config.js +55 -0
  170. package/dist/project-config.js.map +1 -0
  171. package/dist/workspace-resolve.d.ts +158 -0
  172. package/dist/workspace-resolve.js +284 -0
  173. package/dist/workspace-resolve.js.map +1 -0
  174. package/package.json +53 -50
@@ -0,0 +1,219 @@
1
+ import { createAdapter } from '../adapters/factory.js';
2
+ import { formatOutput, printError, printSuccess, formatTable } from '../output.js';
3
+ const VALID_LIFECYCLE_STATUSES = ['active', 'completed', 'cancelled'];
4
+ const VALID_ITEM_TYPES = ['task', 'issue', 'idea', 'intent'];
5
+ function printValidationError(msg, json) {
6
+ if (json) {
7
+ console.error(JSON.stringify({ error: { message: msg } }));
8
+ }
9
+ else {
10
+ console.error(`Error: ${msg}`);
11
+ }
12
+ process.exitCode = 1;
13
+ }
14
+ function printMissionDetail(mission) {
15
+ console.log(`Mission: ${mission.name} [${mission.display_number}]`);
16
+ console.log(`Status: ${mission.status}`);
17
+ if (mission.start_date)
18
+ console.log(`Start: ${mission.start_date}`);
19
+ if (mission.end_date)
20
+ console.log(`End: ${mission.end_date}`);
21
+ if (mission.created_by)
22
+ console.log(`Created by: ${mission.created_by.name} (${mission.created_by.type})`);
23
+ if (mission.description)
24
+ console.log(`\nDescription:\n${mission.description}`);
25
+ if (mission.outcome)
26
+ console.log(`\nOutcome:\n${mission.outcome}`);
27
+ printMissionItems(mission);
28
+ }
29
+ /**
30
+ * Render the linked items of `mission show`. The block is skipped entirely when the
31
+ * response carries no `items` (the cloud envelope today), so the header-only output of
32
+ * backends that do not aggregate stays exactly as it was.
33
+ */
34
+ function printMissionItems(mission) {
35
+ const groups = mission.items;
36
+ if (!groups)
37
+ return;
38
+ const rows = [
39
+ ...(groups.intents ?? []),
40
+ ...(groups.tasks ?? []),
41
+ ...(groups.issues ?? []),
42
+ ...(groups.ideas ?? []),
43
+ ];
44
+ const count = mission.items_count ?? rows.length;
45
+ if (rows.length === 0) {
46
+ console.log(`\nItems (0): none linked yet.`);
47
+ return;
48
+ }
49
+ console.log(`\nItems (${count}):\n`);
50
+ console.log(formatTable(['Type', '#', 'Title', 'Status', 'Linked via'], rows.map((item) => [
51
+ item.type,
52
+ item.display_number,
53
+ item.title,
54
+ item.status,
55
+ item.linked_via ?? '',
56
+ ])));
57
+ }
58
+ export async function missionListCommand(options) {
59
+ try {
60
+ const client = await createAdapter(options.area);
61
+ const response = (await client.listMissions({
62
+ status: options.status,
63
+ limit: options.limit,
64
+ }));
65
+ if (options.json) {
66
+ console.log(formatOutput(response, true));
67
+ return;
68
+ }
69
+ const missions = response.data;
70
+ if (missions.length === 0) {
71
+ console.log('No missions found.');
72
+ return;
73
+ }
74
+ console.log(`Missions (${response.meta?.count ?? missions.length}):\n`);
75
+ console.log(formatTable(['#', 'Name', 'Status', 'Start', 'End'], missions.map((m) => [
76
+ m.display_number,
77
+ m.name,
78
+ m.status,
79
+ m.start_date ?? '',
80
+ m.end_date ?? '',
81
+ ])));
82
+ }
83
+ catch (error) {
84
+ printError(error, options.json);
85
+ process.exitCode = 1;
86
+ }
87
+ }
88
+ export async function missionShowCommand(idOrNumber, options) {
89
+ try {
90
+ const client = await createAdapter(options.area);
91
+ const response = (await client.getMission(idOrNumber));
92
+ if (options.json) {
93
+ console.log(formatOutput(response, true));
94
+ return;
95
+ }
96
+ printMissionDetail(response.data);
97
+ }
98
+ catch (error) {
99
+ printError(error, options.json);
100
+ process.exitCode = 1;
101
+ }
102
+ }
103
+ export async function missionCreateCommand(title, options) {
104
+ try {
105
+ const client = await createAdapter(options.area);
106
+ const response = (await client.createMission({
107
+ name: title,
108
+ description: options.desc,
109
+ outcome: options.outcome,
110
+ end_date: options.endDate,
111
+ }));
112
+ if (options.json) {
113
+ console.log(formatOutput(response, true));
114
+ return;
115
+ }
116
+ const d = response.data;
117
+ printSuccess(`Mission created: ${d.name} [${d.display_number}] (${d.status})`, false);
118
+ }
119
+ catch (error) {
120
+ printError(error, options.json);
121
+ process.exitCode = 1;
122
+ }
123
+ }
124
+ export async function missionUpdateCommand(idOrNumber, options) {
125
+ if (options.title === undefined &&
126
+ options.desc === undefined &&
127
+ options.outcome === undefined &&
128
+ options.endDate === undefined) {
129
+ printValidationError('Provide at least one of --title, --desc, --outcome, --end-date.', options.json);
130
+ return;
131
+ }
132
+ try {
133
+ const client = await createAdapter(options.area);
134
+ const response = (await client.updateMission(idOrNumber, {
135
+ name: options.title,
136
+ description: options.desc,
137
+ outcome: options.outcome,
138
+ end_date: options.endDate,
139
+ }));
140
+ if (options.json) {
141
+ console.log(formatOutput(response, true));
142
+ return;
143
+ }
144
+ const d = response.data;
145
+ printSuccess(`Mission updated: ${d.name} [${d.display_number}] (${d.status})`, false);
146
+ }
147
+ catch (error) {
148
+ printError(error, options.json);
149
+ process.exitCode = 1;
150
+ }
151
+ }
152
+ export async function missionStatusCommand(idOrNumber, status, options) {
153
+ if (!VALID_LIFECYCLE_STATUSES.includes(status)) {
154
+ printValidationError(`Invalid status "${status}". Valid: ${VALID_LIFECYCLE_STATUSES.join(', ')}`, options.json);
155
+ return;
156
+ }
157
+ try {
158
+ const client = await createAdapter(options.area);
159
+ const response = (await client.setMissionStatus(idOrNumber, {
160
+ status,
161
+ move_target_mission_id: options.moveTo,
162
+ }));
163
+ if (options.json) {
164
+ console.log(formatOutput(response, true));
165
+ return;
166
+ }
167
+ const d = response.data;
168
+ printSuccess(`Mission ${d.display_number ?? idOrNumber} status set to ${status}.`, false);
169
+ }
170
+ catch (error) {
171
+ printError(error, options.json);
172
+ process.exitCode = 1;
173
+ }
174
+ }
175
+ export async function missionLinkCommand(idOrNumber, options) {
176
+ if (!VALID_ITEM_TYPES.includes(options.type)) {
177
+ printValidationError(`Invalid type "${options.type}". Valid: ${VALID_ITEM_TYPES.join(', ')}`, options.json);
178
+ return;
179
+ }
180
+ try {
181
+ const client = await createAdapter(options.area);
182
+ const response = await client.linkMissionItem(idOrNumber, {
183
+ item_type: options.type,
184
+ item_id: options.id,
185
+ });
186
+ if (options.json) {
187
+ console.log(formatOutput(response, true));
188
+ return;
189
+ }
190
+ printSuccess(`Linked ${options.type} ${options.id} to mission ${idOrNumber}.`, false);
191
+ }
192
+ catch (error) {
193
+ printError(error, options.json);
194
+ process.exitCode = 1;
195
+ }
196
+ }
197
+ export async function missionUnlinkCommand(idOrNumber, options) {
198
+ if (!VALID_ITEM_TYPES.includes(options.type)) {
199
+ printValidationError(`Invalid type "${options.type}". Valid: ${VALID_ITEM_TYPES.join(', ')}`, options.json);
200
+ return;
201
+ }
202
+ try {
203
+ const client = await createAdapter(options.area);
204
+ const response = await client.unlinkMissionItem(idOrNumber, {
205
+ item_type: options.type,
206
+ item_id: options.id,
207
+ });
208
+ if (options.json) {
209
+ console.log(formatOutput(response, true));
210
+ return;
211
+ }
212
+ printSuccess(`Unlinked ${options.type} ${options.id} from mission ${idOrNumber}.`, false);
213
+ }
214
+ catch (error) {
215
+ printError(error, options.json);
216
+ process.exitCode = 1;
217
+ }
218
+ }
219
+ //# sourceMappingURL=mission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mission.js","sourceRoot":"","sources":["../../src/commands/mission.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,55 @@
1
+ export declare function orbitListCommand(options: {
2
+ json: boolean;
3
+ area?: string;
4
+ workspace?: string;
5
+ }): Promise<void>;
6
+ export declare function orbitShowCommand(orbitIdOrSlug: string, options: {
7
+ json: boolean;
8
+ area?: string;
9
+ }): Promise<void>;
10
+ export declare function orbitCreateCommand(name: string, options: {
11
+ json: boolean;
12
+ area?: string;
13
+ desc?: string;
14
+ color?: string;
15
+ areas?: string;
16
+ }): Promise<void>;
17
+ export declare function orbitUpdateCommand(orbitIdOrSlug: string, options: {
18
+ json: boolean;
19
+ area?: string;
20
+ name?: string;
21
+ desc?: string;
22
+ status?: string;
23
+ color?: string;
24
+ }): Promise<void>;
1
25
  export declare function orbitItemsCommand(orbitIdOrSlug: string, options: {
2
26
  json: boolean;
3
- project?: string;
27
+ area?: string;
4
28
  type?: string;
5
29
  }): Promise<void>;
6
30
  export declare function orbitAttachCommand(orbitIdOrSlug: string, options: {
7
31
  json: boolean;
8
- project?: string;
32
+ area?: string;
9
33
  type: string;
10
34
  id: string;
11
35
  note?: string;
12
36
  }): Promise<void>;
13
37
  export declare function orbitDetachCommand(orbitIdOrSlug: string, options: {
14
38
  json: boolean;
15
- project?: string;
39
+ area?: string;
16
40
  type: string;
17
41
  id: string;
18
42
  }): Promise<void>;
43
+ export declare function orbitAreaLinkCommand(orbitIdOrSlug: string, areaId: string, options: {
44
+ json: boolean;
45
+ area?: string;
46
+ }): Promise<void>;
47
+ export declare function orbitAreaUnlinkCommand(orbitIdOrSlug: string, areaId: string, options: {
48
+ json: boolean;
49
+ area?: string;
50
+ }): Promise<void>;
51
+ export declare function orbitDepAddCommand(orbitIdOrSlug: string, targetOrbitId: string, options: {
52
+ json: boolean;
53
+ area?: string;
54
+ note?: string;
55
+ }): Promise<void>;
@@ -1,11 +1,122 @@
1
- import { createClient } from '../api-client.js';
1
+ import { createAdapter } from '../adapters/factory.js';
2
2
  import { formatOutput, printError, printSuccess, formatTable } from '../output.js';
3
3
  // ── Types ──
4
- const VALID_ITEM_TYPES = ['task', 'issue', 'vibe', 'document'];
4
+ const VALID_OBJECT_TYPES = ['task', 'issue', 'vibe', 'idea', 'document'];
5
+ const VALID_ORBIT_STATUSES = ['active', 'completed', 'archived'];
6
+ function printInvalidType(type, json) {
7
+ const msg = `Invalid type "${type}". Valid: ${VALID_OBJECT_TYPES.join(', ')}`;
8
+ if (json) {
9
+ console.error(JSON.stringify({ error: { message: msg } }));
10
+ }
11
+ else {
12
+ console.error(`Error: ${msg}`);
13
+ }
14
+ process.exitCode = 1;
15
+ }
5
16
  // ── Commands ──
6
- export async function orbitItemsCommand(orbitIdOrSlug, options) {
7
- if (options.type && !VALID_ITEM_TYPES.includes(options.type)) {
8
- const msg = `Invalid type "${options.type}". Valid: ${VALID_ITEM_TYPES.join(', ')}`;
17
+ export async function orbitListCommand(options) {
18
+ try {
19
+ const client = await createAdapter(options.area);
20
+ const response = (await client.listOrbits({
21
+ areaId: options.area,
22
+ workspaceId: options.workspace,
23
+ }));
24
+ if (options.json) {
25
+ console.log(formatOutput(response, true));
26
+ return;
27
+ }
28
+ const orbits = response.data;
29
+ if (orbits.length === 0) {
30
+ console.log('No orbits found.');
31
+ return;
32
+ }
33
+ console.log(`Orbits (${response.meta?.count ?? orbits.length}):\n`);
34
+ console.log(formatTable(['Name', 'Slug', 'Status', 'Color'], orbits.map((o) => [o.name, o.slug, o.status, o.color ?? ''])));
35
+ }
36
+ catch (error) {
37
+ printError(error, options.json);
38
+ process.exitCode = 1;
39
+ }
40
+ }
41
+ export async function orbitShowCommand(orbitIdOrSlug, options) {
42
+ try {
43
+ const client = await createAdapter(options.area);
44
+ const response = (await client.getOrbit(orbitIdOrSlug));
45
+ if (options.json) {
46
+ console.log(formatOutput(response, true));
47
+ return;
48
+ }
49
+ const o = response.data;
50
+ console.log(`Orbit: ${o.name} (${o.slug})`);
51
+ console.log(`ID: ${o.id}`);
52
+ console.log(`Status: ${o.status}`);
53
+ if (o.color)
54
+ console.log(`Color: ${o.color}`);
55
+ if (o.description)
56
+ console.log(`\nDescription:\n${o.description}`);
57
+ if (o.areas && o.areas.length > 0) {
58
+ console.log(`\nAreas (${o.areas.length}):`);
59
+ console.log(formatTable(['Name', 'Slug', 'ID'], o.areas.map((a) => [a.name, a.slug, a.id])));
60
+ }
61
+ if (o.task_counts && !Array.isArray(o.task_counts)) {
62
+ const entries = Object.entries(o.task_counts);
63
+ if (entries.length > 0) {
64
+ console.log('\nTask counts:');
65
+ for (const [status, count] of entries) {
66
+ console.log(` ${status}: ${count}`);
67
+ }
68
+ }
69
+ }
70
+ }
71
+ catch (error) {
72
+ printError(error, options.json);
73
+ process.exitCode = 1;
74
+ }
75
+ }
76
+ export async function orbitCreateCommand(name, options) {
77
+ try {
78
+ const client = await createAdapter(options.area);
79
+ const areaIds = options.areas
80
+ ? options.areas.split(',').map((s) => s.trim())
81
+ : undefined;
82
+ const response = (await client.createOrbit({
83
+ name,
84
+ description: options.desc,
85
+ color: options.color,
86
+ area_ids: areaIds,
87
+ }));
88
+ if (options.json) {
89
+ console.log(formatOutput(response, true));
90
+ return;
91
+ }
92
+ const d = response.data;
93
+ let msg = `Orbit created: ${d.name} (${d.slug})`;
94
+ msg += `\nID: ${d.id}`;
95
+ msg += `\nStatus: ${d.status}`;
96
+ printSuccess(msg, false);
97
+ }
98
+ catch (error) {
99
+ printError(error, options.json);
100
+ process.exitCode = 1;
101
+ }
102
+ }
103
+ export async function orbitUpdateCommand(orbitIdOrSlug, options) {
104
+ if (options.name === undefined &&
105
+ options.desc === undefined &&
106
+ options.status === undefined &&
107
+ options.color === undefined) {
108
+ const msg = 'Provide at least one of --name, --desc, --status, --color.';
109
+ if (options.json) {
110
+ console.error(JSON.stringify({ error: { message: msg } }));
111
+ }
112
+ else {
113
+ console.error(`Error: ${msg}`);
114
+ }
115
+ process.exitCode = 1;
116
+ return;
117
+ }
118
+ if (options.status && !VALID_ORBIT_STATUSES.includes(options.status)) {
119
+ const msg = `Invalid status "${options.status}". Valid: ${VALID_ORBIT_STATUSES.join(', ')}`;
9
120
  if (options.json) {
10
121
  console.error(JSON.stringify({ error: { message: msg } }));
11
122
  }
@@ -16,7 +127,32 @@ export async function orbitItemsCommand(orbitIdOrSlug, options) {
16
127
  return;
17
128
  }
18
129
  try {
19
- const client = await createClient(options.project);
130
+ const client = await createAdapter(options.area);
131
+ const response = (await client.updateOrbit(orbitIdOrSlug, {
132
+ name: options.name,
133
+ description: options.desc,
134
+ status: options.status,
135
+ color: options.color,
136
+ }));
137
+ if (options.json) {
138
+ console.log(formatOutput(response, true));
139
+ return;
140
+ }
141
+ const d = response.data;
142
+ printSuccess(`Orbit updated: ${d.name} (${d.status})`, false);
143
+ }
144
+ catch (error) {
145
+ printError(error, options.json);
146
+ process.exitCode = 1;
147
+ }
148
+ }
149
+ export async function orbitItemsCommand(orbitIdOrSlug, options) {
150
+ if (options.type && !VALID_OBJECT_TYPES.includes(options.type)) {
151
+ printInvalidType(options.type, options.json);
152
+ return;
153
+ }
154
+ try {
155
+ const client = await createAdapter(options.area);
20
156
  const response = (await client.getOrbitItems(orbitIdOrSlug, {
21
157
  type: options.type,
22
158
  }));
@@ -24,27 +160,25 @@ export async function orbitItemsCommand(orbitIdOrSlug, options) {
24
160
  console.log(formatOutput(response, true));
25
161
  return;
26
162
  }
27
- const { orbit, items, summary } = response.data;
28
- // Orbit header
29
- const counts = Object.entries(summary)
30
- .filter(([, count]) => count > 0)
31
- .map(([type, count]) => `${count} ${type}${count !== 1 ? 's' : ''}`)
32
- .join(', ');
163
+ const { orbit, tasks, issues, vibes, ideas, documents } = response.data;
164
+ const counts = [
165
+ tasks?.length ? `${tasks.length} task${tasks.length !== 1 ? 's' : ''}` : '',
166
+ issues?.length ? `${issues.length} issue${issues.length !== 1 ? 's' : ''}` : '',
167
+ vibes?.length ? `${vibes.length} vibe${vibes.length !== 1 ? 's' : ''}` : '',
168
+ ideas?.length ? `${ideas.length} idea${ideas.length !== 1 ? 's' : ''}` : '',
169
+ documents?.length ? `${documents.length} document${documents.length !== 1 ? 's' : ''}` : '',
170
+ ].filter(Boolean).join(', ');
33
171
  console.log(`Orbit: ${orbit.name} (${orbit.status})${counts ? ` — ${counts}` : ''}\n`);
34
- if (items.length === 0) {
172
+ const total = (tasks?.length ?? 0) +
173
+ (issues?.length ?? 0) +
174
+ (vibes?.length ?? 0) +
175
+ (ideas?.length ?? 0) +
176
+ (documents?.length ?? 0);
177
+ if (total === 0) {
35
178
  console.log('No items in this orbit.');
36
179
  return;
37
180
  }
38
- // Group items by type
39
- const grouped = new Map();
40
- for (const item of items) {
41
- const existing = grouped.get(item.item_type) ?? [];
42
- existing.push(item.item);
43
- grouped.set(item.item_type, existing);
44
- }
45
- // Display each group
46
- if (grouped.has('task')) {
47
- const tasks = grouped.get('task');
181
+ if (tasks && tasks.length > 0) {
48
182
  console.log(`Tasks (${tasks.length}):`);
49
183
  console.log(formatTable(['ID', 'Number', 'Title', 'Status', 'Priority'], tasks.map((t) => [
50
184
  String(t.id ?? ''),
@@ -55,8 +189,7 @@ export async function orbitItemsCommand(orbitIdOrSlug, options) {
55
189
  ])));
56
190
  console.log();
57
191
  }
58
- if (grouped.has('issue')) {
59
- const issues = grouped.get('issue');
192
+ if (issues && issues.length > 0) {
60
193
  console.log(`Issues (${issues.length}):`);
61
194
  console.log(formatTable(['ID', 'Number', 'Title', 'Severity', 'Status'], issues.map((i) => [
62
195
  String(i.id ?? ''),
@@ -67,10 +200,19 @@ export async function orbitItemsCommand(orbitIdOrSlug, options) {
67
200
  ])));
68
201
  console.log();
69
202
  }
70
- if (grouped.has('document')) {
71
- const docs = grouped.get('document');
72
- console.log(`Documents (${docs.length}):`);
73
- console.log(formatTable(['ID', 'Slug', 'Title', 'Type'], docs.map((d) => [
203
+ if (ideas && ideas.length > 0) {
204
+ console.log(`Ideas (${ideas.length}):`);
205
+ console.log(formatTable(['ID', 'Number', 'Title', 'Status'], ideas.map((i) => [
206
+ String(i.id ?? ''),
207
+ String(i.display_number ?? i.idea_number ?? ''),
208
+ String(i.title ?? ''),
209
+ String(i.status ?? ''),
210
+ ])));
211
+ console.log();
212
+ }
213
+ if (documents && documents.length > 0) {
214
+ console.log(`Documents (${documents.length}):`);
215
+ console.log(formatTable(['ID', 'Slug', 'Title', 'Type'], documents.map((d) => [
74
216
  String(d.id ?? ''),
75
217
  String(d.slug ?? ''),
76
218
  String(d.title ?? ''),
@@ -78,8 +220,7 @@ export async function orbitItemsCommand(orbitIdOrSlug, options) {
78
220
  ])));
79
221
  console.log();
80
222
  }
81
- if (grouped.has('vibe')) {
82
- const vibes = grouped.get('vibe');
223
+ if (vibes && vibes.length > 0) {
83
224
  console.log(`Vibes (${vibes.length}):`);
84
225
  console.log(formatTable(['ID', 'Type', 'Title', 'Created'], vibes.map((v) => [
85
226
  String(v.id ?? ''),
@@ -96,60 +237,92 @@ export async function orbitItemsCommand(orbitIdOrSlug, options) {
96
237
  }
97
238
  }
98
239
  export async function orbitAttachCommand(orbitIdOrSlug, options) {
99
- if (!VALID_ITEM_TYPES.includes(options.type)) {
100
- const msg = `Invalid type "${options.type}". Valid: ${VALID_ITEM_TYPES.join(', ')}`;
240
+ if (!VALID_OBJECT_TYPES.includes(options.type)) {
241
+ printInvalidType(options.type, options.json);
242
+ return;
243
+ }
244
+ try {
245
+ const client = await createAdapter(options.area);
246
+ const response = await client.orbitAttach(orbitIdOrSlug, {
247
+ object_type: options.type,
248
+ object_id: options.id,
249
+ note: options.note,
250
+ });
101
251
  if (options.json) {
102
- console.error(JSON.stringify({ error: { message: msg } }));
103
- }
104
- else {
105
- console.error(`Error: ${msg}`);
252
+ console.log(formatOutput(response, true));
253
+ return;
106
254
  }
255
+ printSuccess(`Attached ${options.type} ${options.id} to orbit '${orbitIdOrSlug}'.`, false);
256
+ }
257
+ catch (error) {
258
+ printError(error, options.json);
107
259
  process.exitCode = 1;
260
+ }
261
+ }
262
+ export async function orbitDetachCommand(orbitIdOrSlug, options) {
263
+ if (!VALID_OBJECT_TYPES.includes(options.type)) {
264
+ printInvalidType(options.type, options.json);
108
265
  return;
109
266
  }
110
267
  try {
111
- const client = await createClient(options.project);
112
- const response = (await client.orbitAttach(orbitIdOrSlug, {
113
- item_type: options.type,
114
- item_id: options.id,
115
- note: options.note,
116
- }));
268
+ const client = await createAdapter(options.area);
269
+ const response = await client.orbitDetach(orbitIdOrSlug, {
270
+ object_type: options.type,
271
+ object_id: options.id,
272
+ });
117
273
  if (options.json) {
118
274
  console.log(formatOutput(response, true));
119
275
  return;
120
276
  }
121
- const { orbit } = response.data;
122
- printSuccess(`Attached ${options.type} ${options.id} to orbit '${orbit.name}'.`, false);
277
+ printSuccess(`Detached ${options.type} ${options.id} from orbit '${orbitIdOrSlug}'.`, false);
123
278
  }
124
279
  catch (error) {
125
280
  printError(error, options.json);
126
281
  process.exitCode = 1;
127
282
  }
128
283
  }
129
- export async function orbitDetachCommand(orbitIdOrSlug, options) {
130
- if (!VALID_ITEM_TYPES.includes(options.type)) {
131
- const msg = `Invalid type "${options.type}". Valid: ${VALID_ITEM_TYPES.join(', ')}`;
284
+ export async function orbitAreaLinkCommand(orbitIdOrSlug, areaId, options) {
285
+ try {
286
+ const client = await createAdapter(options.area);
287
+ const response = (await client.addOrbitArea(orbitIdOrSlug, areaId));
132
288
  if (options.json) {
133
- console.error(JSON.stringify({ error: { message: msg } }));
289
+ console.log(formatOutput(response, true));
290
+ return;
134
291
  }
135
- else {
136
- console.error(`Error: ${msg}`);
292
+ printSuccess(`Area ${areaId} linked to orbit '${orbitIdOrSlug}'.`, false);
293
+ }
294
+ catch (error) {
295
+ printError(error, options.json);
296
+ process.exitCode = 1;
297
+ }
298
+ }
299
+ export async function orbitAreaUnlinkCommand(orbitIdOrSlug, areaId, options) {
300
+ try {
301
+ const client = await createAdapter(options.area);
302
+ const response = await client.removeOrbitArea(orbitIdOrSlug, areaId);
303
+ if (options.json) {
304
+ console.log(formatOutput(response, true));
305
+ return;
137
306
  }
307
+ printSuccess(`Area ${areaId} unlinked from orbit '${orbitIdOrSlug}'.`, false);
308
+ }
309
+ catch (error) {
310
+ printError(error, options.json);
138
311
  process.exitCode = 1;
139
- return;
140
312
  }
313
+ }
314
+ export async function orbitDepAddCommand(orbitIdOrSlug, targetOrbitId, options) {
141
315
  try {
142
- const client = await createClient(options.project);
143
- const response = (await client.orbitDetach(orbitIdOrSlug, {
144
- item_type: options.type,
145
- item_id: options.id,
316
+ const client = await createAdapter(options.area);
317
+ const response = (await client.addOrbitDependency(orbitIdOrSlug, {
318
+ target_orbit_id: targetOrbitId,
319
+ note: options.note,
146
320
  }));
147
321
  if (options.json) {
148
322
  console.log(formatOutput(response, true));
149
323
  return;
150
324
  }
151
- const { orbit } = response.data;
152
- printSuccess(`Detached ${options.type} ${options.id} from orbit '${orbit.name}'.`, false);
325
+ printSuccess(`Dependency added: orbit '${orbitIdOrSlug}' depends on '${targetOrbitId}'.`, false);
153
326
  }
154
327
  catch (error) {
155
328
  printError(error, options.json);