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,351 @@
1
+ /**
2
+ * LocalAdapter — the file-backed implementation of {@link WorkspaceAdapter} (spec §2.2).
3
+ *
4
+ * It never touches the network. Every method either
5
+ * - delegates to an entity module in `./entities/*` (tasks, work items, planning, docs),
6
+ * - is answered here from the store + `./shapes.js` (context, areas, overview, prompts), or
7
+ * - throws `NOT_SUPPORTED_IN_LOCAL_MODE` for the cloud-only surfaces of §1 (orbits,
8
+ * document patching/sharing/visibility, presigned uploads).
9
+ *
10
+ * Commands never branch on the mode: everything mode-specific lives behind this class.
11
+ */
12
+ import type { AreaSource } from '../../workspace-resolve.js';
13
+ import type { WorkspaceAdapter } from '../types.js';
14
+ import { LocalStore, type LocalStoreOptions } from './store.js';
15
+ export interface LocalAdapterOptions {
16
+ workspacePath: string;
17
+ area?: string;
18
+ /** Rung that produced `area`; `'config'` marks it as the weak machine-wide default. */
19
+ areaSource?: AreaSource;
20
+ storeOptions?: LocalStoreOptions;
21
+ store?: LocalStore;
22
+ }
23
+ export declare class LocalAdapter implements WorkspaceAdapter {
24
+ private readonly options;
25
+ private context?;
26
+ constructor(options: LocalAdapterOptions);
27
+ /** Build (and memoise) the shared context: store + `workspace.yml` + resolved area. */
28
+ private ctx;
29
+ getContext(areaId?: string): Promise<unknown>;
30
+ /**
31
+ * The resolved area slug (§3.3, including the "workspace has exactly one area"
32
+ * auto-selection). Reads `workspace.yml` only — no credentials involved.
33
+ */
34
+ getDefaultArea(): Promise<string | undefined>;
35
+ getTasks(options?: {
36
+ status?: string;
37
+ priority?: string;
38
+ areaId?: string;
39
+ orbit?: string;
40
+ }): Promise<unknown>;
41
+ getTask(taskId: string): Promise<unknown>;
42
+ getTaskByNumber(taskNumber: string): Promise<unknown>;
43
+ startTask(taskId?: string): Promise<unknown>;
44
+ updateTaskStatus(taskId: string, status?: string, deliveryStatus?: string | null, force?: boolean): Promise<unknown>;
45
+ createSubtasks(parentId: string, subtasks: Array<{
46
+ title: string;
47
+ description?: string;
48
+ priority?: string;
49
+ estimated_effort?: string;
50
+ }>): Promise<unknown>;
51
+ createTask(data: {
52
+ title: string;
53
+ description?: string;
54
+ status?: string;
55
+ priority?: string;
56
+ agent_instructions?: string;
57
+ branch_name?: string;
58
+ estimated_effort?: string;
59
+ agent_id?: string;
60
+ area_id?: string;
61
+ source_issue_id?: string;
62
+ intent_id?: string;
63
+ orbit_id?: string | null;
64
+ }): Promise<unknown>;
65
+ editTaskContent(taskId: string, data: {
66
+ title?: string;
67
+ description?: string;
68
+ agent_instructions?: string;
69
+ }): Promise<unknown>;
70
+ assignTask(taskId: string, assignment: {
71
+ agent_id: string;
72
+ } | {
73
+ user_id: number;
74
+ }): Promise<unknown>;
75
+ assignItem(objectType: 'task' | 'issue' | 'idea' | 'intent', objectId: string, assignment: {
76
+ agent_id: string;
77
+ } | {
78
+ user_id: number;
79
+ }): Promise<unknown>;
80
+ addTaskDependency(taskId: string, data: {
81
+ target_task_id: string;
82
+ type?: string;
83
+ note?: string;
84
+ }): Promise<unknown>;
85
+ removeTaskDependency(taskId: string, targetTaskId: string, type?: string): Promise<unknown>;
86
+ logWork(taskId: string, type: string, content: string, metadata?: Record<string, unknown>): Promise<unknown>;
87
+ getDocuments(options?: {
88
+ type?: string;
89
+ search?: string;
90
+ areaId?: string;
91
+ }): Promise<unknown>;
92
+ getDocument(idOrSlug: string, mode?: 'inline' | 'file', options?: {
93
+ full?: boolean;
94
+ section?: string;
95
+ }): Promise<unknown>;
96
+ importDocument(data: {
97
+ title: string;
98
+ type: string;
99
+ content: string;
100
+ source_path?: string;
101
+ context?: string;
102
+ workspace_id?: string;
103
+ }): Promise<unknown>;
104
+ updateDocument(idOrSlug: string, content: string, changelog?: string): Promise<unknown>;
105
+ patchDocument(_idOrSlug: string, _operations: Array<Record<string, unknown>>, _baseVersion: number, _changelog?: string): Promise<unknown>;
106
+ requestUploadUrl(_data: {
107
+ title: string;
108
+ type: string;
109
+ filename?: string;
110
+ source_path?: string;
111
+ context?: string;
112
+ workspace_id?: string;
113
+ }): Promise<{
114
+ data: {
115
+ upload_id: string;
116
+ document_id: string;
117
+ presigned_url: string;
118
+ storage_path: string;
119
+ expires_at: string;
120
+ };
121
+ }>;
122
+ confirmUpload(_uploadId: string): Promise<{
123
+ data: {
124
+ document_id: string;
125
+ slug: string;
126
+ imported: boolean;
127
+ };
128
+ }>;
129
+ requestUpdateUploadUrl(_idOrSlug: string, _changelog?: string): Promise<{
130
+ data: {
131
+ upload_id: string;
132
+ document_id: string;
133
+ version: number;
134
+ presigned_url: string;
135
+ storage_path: string;
136
+ expires_at: string;
137
+ };
138
+ }>;
139
+ confirmUpdateUpload(_idOrSlug: string, _uploadId: string): Promise<{
140
+ data: {
141
+ document_id: string;
142
+ version: number;
143
+ updated: boolean;
144
+ };
145
+ }>;
146
+ uploadToPresignedUrl(_presignedUrl: string, _filePath: string, _onProgress?: (bytesUploaded: number, totalBytes: number) => void): Promise<void>;
147
+ /**
148
+ * Presigned upload *negotiation* — never a user-facing surface: `doc-import` calls this
149
+ * first and falls back to `importDocument` when it returns `null` (exactly what
150
+ * `CloudAdapter` returns when the server declines the endpoint with 404). Local mode has
151
+ * no object storage, so it always declines instead of throwing.
152
+ */
153
+ presignedImport(_filePath: string, _data: {
154
+ title: string;
155
+ type: string;
156
+ source_path?: string;
157
+ context?: string;
158
+ workspace_id?: string;
159
+ }, _onProgress?: (bytesUploaded: number, totalBytes: number) => void): Promise<{
160
+ data: {
161
+ document_id: string;
162
+ slug: string;
163
+ imported: boolean;
164
+ };
165
+ upload_method: string;
166
+ } | null>;
167
+ /** Same negotiation contract as {@link presignedImport}; `doc-update` falls back. */
168
+ presignedUpdate(_idOrSlug: string, _filePath: string, _changelog?: string, _onProgress?: (bytesUploaded: number, totalBytes: number) => void): Promise<{
169
+ data: {
170
+ document_id: string;
171
+ version: number;
172
+ updated: boolean;
173
+ };
174
+ upload_method: string;
175
+ } | null>;
176
+ shareDocument(_documentId: string, _areaId: string, _agentIds?: string[]): Promise<unknown>;
177
+ unshareDocument(_documentId: string, _areaId: string): Promise<unknown>;
178
+ setDocumentVisibility(_documentId: string, _areaId: string, _agentIds: string[]): Promise<unknown>;
179
+ getAreas(): Promise<unknown>;
180
+ getAreaMembers(areaId: string): Promise<unknown>;
181
+ getAreaOverview(areaId: string): Promise<unknown>;
182
+ createArea(data: {
183
+ name: string;
184
+ description?: string;
185
+ slug?: string;
186
+ workspace_id?: string;
187
+ }): Promise<unknown>;
188
+ registerIssue(data: {
189
+ title: string;
190
+ description: string;
191
+ severity?: string;
192
+ related_task_id?: string;
193
+ intent_id?: string;
194
+ }): Promise<unknown>;
195
+ listIssues(options?: {
196
+ status?: string;
197
+ severity?: string;
198
+ limit?: string;
199
+ }): Promise<unknown>;
200
+ getIssue(idOrNumber: string): Promise<unknown>;
201
+ getIssueByNumber(issueNumber: string): Promise<unknown>;
202
+ resolveIssueByNumber(issueNumber: string, data: {
203
+ status: string;
204
+ resolution?: string;
205
+ resolved_by_task_id?: string;
206
+ }): Promise<unknown>;
207
+ resolveIssue(idOrNumber: string, data: {
208
+ status: string;
209
+ resolution?: string;
210
+ resolved_by_task_id?: string;
211
+ }): Promise<unknown>;
212
+ updateIssueStatus(idOrNumber: string, data: {
213
+ status: string;
214
+ resolution?: string;
215
+ resolved_task_id?: string;
216
+ }): Promise<unknown>;
217
+ updateIssueStatusByNumber(issueNumber: string, data: {
218
+ status: string;
219
+ resolution?: string;
220
+ resolved_task_id?: string;
221
+ }): Promise<unknown>;
222
+ logVibe(data: {
223
+ content: string;
224
+ type: string;
225
+ title?: string;
226
+ task_id?: string;
227
+ }): Promise<unknown>;
228
+ listVibes(options?: {
229
+ type?: string;
230
+ since?: string;
231
+ limit?: string;
232
+ }): Promise<unknown>;
233
+ getVibe(id: string): Promise<unknown>;
234
+ updateVibe(id: string, data: {
235
+ type?: string;
236
+ title?: string;
237
+ content?: string;
238
+ metadata?: Record<string, unknown>;
239
+ }): Promise<unknown>;
240
+ listIdeas(options?: {
241
+ status?: string;
242
+ priority?: string;
243
+ limit?: string;
244
+ }): Promise<unknown>;
245
+ getIdea(idOrNumber: string): Promise<unknown>;
246
+ getIdeaByNumber(ideaNumber: string): Promise<unknown>;
247
+ createIdea(data: {
248
+ content: string;
249
+ title?: string;
250
+ priority?: string;
251
+ metadata?: Record<string, unknown>;
252
+ }): Promise<unknown>;
253
+ updateIdeaStatus(idOrNumber: string, data: {
254
+ status: string;
255
+ }): Promise<unknown>;
256
+ updateIdeaStatusByNumber(ideaNumber: string, data: {
257
+ status: string;
258
+ }): Promise<unknown>;
259
+ listOrbits(_options?: {
260
+ areaId?: string;
261
+ workspaceId?: string;
262
+ }): Promise<unknown>;
263
+ getOrbit(_idOrSlug: string): Promise<unknown>;
264
+ createOrbit(_data: {
265
+ name: string;
266
+ description?: string;
267
+ color?: string;
268
+ area_ids?: string[];
269
+ }): Promise<unknown>;
270
+ updateOrbit(_idOrSlug: string, _data: {
271
+ name?: string;
272
+ description?: string;
273
+ status?: string;
274
+ color?: string;
275
+ }): Promise<unknown>;
276
+ getOrbitItems(_orbitIdOrSlug: string, _options?: {
277
+ type?: string;
278
+ }): Promise<unknown>;
279
+ orbitAttach(_orbitIdOrSlug: string, _data: {
280
+ object_type: string;
281
+ object_id: string;
282
+ note?: string;
283
+ }): Promise<unknown>;
284
+ orbitDetach(_orbitIdOrSlug: string, _data: {
285
+ object_type: string;
286
+ object_id: string;
287
+ }): Promise<unknown>;
288
+ addOrbitArea(_orbitIdOrSlug: string, _areaId: string): Promise<unknown>;
289
+ removeOrbitArea(_orbitIdOrSlug: string, _areaId: string): Promise<unknown>;
290
+ addOrbitDependency(_orbitIdOrSlug: string, _data: {
291
+ target_orbit_id: string;
292
+ note?: string;
293
+ }): Promise<unknown>;
294
+ listIntents(options?: {
295
+ status?: string;
296
+ limit?: string;
297
+ }): Promise<unknown>;
298
+ getIntent(idOrNumber: string): Promise<unknown>;
299
+ createIntent(data: {
300
+ name: string;
301
+ outcome?: string;
302
+ status?: string;
303
+ area_id?: string;
304
+ }): Promise<unknown>;
305
+ updateIntent(idOrNumber: string, data: {
306
+ name?: string;
307
+ outcome?: string;
308
+ status?: string;
309
+ }): Promise<unknown>;
310
+ linkIntentItem(idOrNumber: string, data: {
311
+ item_type: string;
312
+ item_id: string;
313
+ }): Promise<unknown>;
314
+ unlinkIntentItem(idOrNumber: string, data: {
315
+ item_type: string;
316
+ item_id: string;
317
+ }): Promise<unknown>;
318
+ setIntentOrbit(_idOrNumber: string, _orbitId: string | null): Promise<unknown>;
319
+ listMissions(options?: {
320
+ status?: string;
321
+ limit?: string;
322
+ }): Promise<unknown>;
323
+ getMission(idOrNumber: string): Promise<unknown>;
324
+ createMission(data: {
325
+ name: string;
326
+ description?: string;
327
+ outcome?: string;
328
+ end_date?: string;
329
+ area_id?: string;
330
+ }): Promise<unknown>;
331
+ updateMission(idOrNumber: string, data: {
332
+ name?: string;
333
+ description?: string;
334
+ outcome?: string;
335
+ end_date?: string;
336
+ }): Promise<unknown>;
337
+ setMissionStatus(idOrNumber: string, data: {
338
+ status: string;
339
+ move_target_mission_id?: string;
340
+ }): Promise<unknown>;
341
+ linkMissionItem(idOrNumber: string, data: {
342
+ item_type: string;
343
+ item_id: string;
344
+ }): Promise<unknown>;
345
+ unlinkMissionItem(idOrNumber: string, data: {
346
+ item_type: string;
347
+ item_id: string;
348
+ }): Promise<unknown>;
349
+ getWorkPrompt(): Promise<unknown>;
350
+ getImportDocsPrompt(): Promise<unknown>;
351
+ }
@@ -0,0 +1,346 @@
1
+ /**
2
+ * LocalAdapter — the file-backed implementation of {@link WorkspaceAdapter} (spec §2.2).
3
+ *
4
+ * It never touches the network. Every method either
5
+ * - delegates to an entity module in `./entities/*` (tasks, work items, planning, docs),
6
+ * - is answered here from the store + `./shapes.js` (context, areas, overview, prompts), or
7
+ * - throws `NOT_SUPPORTED_IN_LOCAL_MODE` for the cloud-only surfaces of §1 (orbits,
8
+ * document patching/sharing/visibility, presigned uploads).
9
+ *
10
+ * Commands never branch on the mode: everything mode-specific lives behind this class.
11
+ */
12
+ import { createLocalContext, notSupported, requireAreaFile, resolveAreaRef, } from './context.js';
13
+ import * as documents from './entities/documents.js';
14
+ import * as planning from './entities/planning.js';
15
+ import * as tasks from './entities/tasks.js';
16
+ import * as workItems from './entities/work-items.js';
17
+ import { assertUniqueAreaSlug, selectNextTask } from './rules.js';
18
+ import { areaCreateEnvelope, areaMembersEnvelope, areaOverviewEnvelope, areasListEnvelope, contextEnvelope, documentEntry, findActiveMission, importDocsPromptEnvelope, parseDescription, workPromptEnvelope, } from './shapes.js';
19
+ import { slugify } from './store.js';
20
+ /** Statuses `orbitmap context` reports as "active tasks". */
21
+ const CONTEXT_TASK_STATUSES = ['todo', 'in_progress'];
22
+ export class LocalAdapter {
23
+ options;
24
+ context;
25
+ constructor(options) {
26
+ this.options = options;
27
+ }
28
+ /** Build (and memoise) the shared context: store + `workspace.yml` + resolved area. */
29
+ async ctx() {
30
+ if (!this.context) {
31
+ this.context = await createLocalContext({
32
+ workspacePath: this.options.workspacePath,
33
+ area: this.options.area,
34
+ areaSource: this.options.areaSource,
35
+ storeOptions: this.options.storeOptions,
36
+ store: this.options.store,
37
+ });
38
+ }
39
+ return this.context;
40
+ }
41
+ // ── Context ──
42
+ async getContext(areaId) {
43
+ const ctx = await this.ctx();
44
+ let area;
45
+ if (areaId || ctx.areaSlug) {
46
+ area = await resolveAreaRef(ctx, areaId);
47
+ }
48
+ let areaTasks = [];
49
+ if (area) {
50
+ const files = await ctx.store.listEntities('task', { area: area.slug });
51
+ areaTasks = files
52
+ .map((file) => file.frontmatter)
53
+ .filter((task) => CONTEXT_TASK_STATUSES.includes(task.status));
54
+ }
55
+ const missions = (await ctx.store.listEntities('mission')).map((file) => file.frontmatter);
56
+ const docs = (await ctx.store.listDocuments()).map((doc) => documentEntry(doc.frontmatter, doc.body));
57
+ return contextEnvelope({
58
+ workspace: ctx.workspace,
59
+ area,
60
+ activeMission: findActiveMission(missions),
61
+ tasks: areaTasks,
62
+ documents: docs,
63
+ });
64
+ }
65
+ /**
66
+ * The resolved area slug (§3.3, including the "workspace has exactly one area"
67
+ * auto-selection). Reads `workspace.yml` only — no credentials involved.
68
+ */
69
+ async getDefaultArea() {
70
+ return (await this.ctx()).areaSlug;
71
+ }
72
+ // ── Tasks ──
73
+ async getTasks(options) {
74
+ return tasks.listTasks(await this.ctx(), options ?? {});
75
+ }
76
+ async getTask(taskId) {
77
+ return tasks.getTask(await this.ctx(), taskId);
78
+ }
79
+ async getTaskByNumber(taskNumber) {
80
+ return tasks.getTaskByNumber(await this.ctx(), taskNumber);
81
+ }
82
+ async startTask(taskId) {
83
+ return tasks.startTask(await this.ctx(), taskId);
84
+ }
85
+ async updateTaskStatus(taskId, status, deliveryStatus, force) {
86
+ return tasks.updateTaskStatus(await this.ctx(), taskId, status, deliveryStatus, force);
87
+ }
88
+ async createSubtasks(parentId, subtasks) {
89
+ return tasks.createSubtasks(await this.ctx(), parentId, subtasks);
90
+ }
91
+ async createTask(data) {
92
+ return tasks.createTask(await this.ctx(), data);
93
+ }
94
+ async editTaskContent(taskId, data) {
95
+ return tasks.editTaskContent(await this.ctx(), taskId, data);
96
+ }
97
+ // ── Assignment ──
98
+ async assignTask(taskId, assignment) {
99
+ return tasks.assignTask(await this.ctx(), taskId, assignment);
100
+ }
101
+ async assignItem(objectType, objectId, assignment) {
102
+ return tasks.assignItem(await this.ctx(), objectType, objectId, assignment);
103
+ }
104
+ // ── Task Dependencies ──
105
+ async addTaskDependency(taskId, data) {
106
+ return tasks.addTaskDependency(await this.ctx(), taskId, data);
107
+ }
108
+ async removeTaskDependency(taskId, targetTaskId, type) {
109
+ return tasks.removeTaskDependency(await this.ctx(), taskId, targetTaskId, type);
110
+ }
111
+ // ── Logs ──
112
+ async logWork(taskId, type, content, metadata) {
113
+ return tasks.logWork(await this.ctx(), taskId, type, content, metadata);
114
+ }
115
+ // ── Documents ──
116
+ async getDocuments(options) {
117
+ return documents.getDocuments(await this.ctx(), options);
118
+ }
119
+ async getDocument(idOrSlug, mode, options) {
120
+ return documents.getDocument(await this.ctx(), idOrSlug, mode, options);
121
+ }
122
+ async importDocument(data) {
123
+ return documents.importDocument(await this.ctx(), data);
124
+ }
125
+ async updateDocument(idOrSlug, content, changelog) {
126
+ return documents.updateDocument(await this.ctx(), idOrSlug, content, changelog);
127
+ }
128
+ async patchDocument(_idOrSlug, _operations, _baseVersion, _changelog) {
129
+ throw notSupported('Section-level document patching (`doc-patch`)');
130
+ }
131
+ // ── Presigned URL upload ──
132
+ async requestUploadUrl(_data) {
133
+ throw notSupported('Presigned document uploads');
134
+ }
135
+ async confirmUpload(_uploadId) {
136
+ throw notSupported('Presigned document uploads');
137
+ }
138
+ async requestUpdateUploadUrl(_idOrSlug, _changelog) {
139
+ throw notSupported('Presigned document uploads');
140
+ }
141
+ async confirmUpdateUpload(_idOrSlug, _uploadId) {
142
+ throw notSupported('Presigned document uploads');
143
+ }
144
+ async uploadToPresignedUrl(_presignedUrl, _filePath, _onProgress) {
145
+ throw notSupported('Presigned document uploads');
146
+ }
147
+ /**
148
+ * Presigned upload *negotiation* — never a user-facing surface: `doc-import` calls this
149
+ * first and falls back to `importDocument` when it returns `null` (exactly what
150
+ * `CloudAdapter` returns when the server declines the endpoint with 404). Local mode has
151
+ * no object storage, so it always declines instead of throwing.
152
+ */
153
+ async presignedImport(_filePath, _data, _onProgress) {
154
+ return null;
155
+ }
156
+ /** Same negotiation contract as {@link presignedImport}; `doc-update` falls back. */
157
+ async presignedUpdate(_idOrSlug, _filePath, _changelog, _onProgress) {
158
+ return null;
159
+ }
160
+ // ── Document sharing ──
161
+ async shareDocument(_documentId, _areaId, _agentIds) {
162
+ throw notSupported('Cross-area document sharing (`doc-share`)');
163
+ }
164
+ async unshareDocument(_documentId, _areaId) {
165
+ throw notSupported('Cross-area document sharing (`doc-unshare`)');
166
+ }
167
+ async setDocumentVisibility(_documentId, _areaId, _agentIds) {
168
+ throw notSupported('Document visibility (`doc-visibility`)');
169
+ }
170
+ // ── Areas ──
171
+ async getAreas() {
172
+ const ctx = await this.ctx();
173
+ const areas = await ctx.store.listAreas();
174
+ return areasListEnvelope(areas, ctx.workspace, ctx.areaSlug);
175
+ }
176
+ async getAreaMembers(areaId) {
177
+ const ctx = await this.ctx();
178
+ await resolveAreaRef(ctx, areaId);
179
+ return areaMembersEnvelope();
180
+ }
181
+ async getAreaOverview(areaId) {
182
+ const ctx = await this.ctx();
183
+ const area = await resolveAreaRef(ctx, areaId);
184
+ const files = await ctx.store.listEntities('task', { area: area.slug });
185
+ return areaOverviewEnvelope(area, files.map((file) => file.frontmatter));
186
+ }
187
+ async createArea(data) {
188
+ const ctx = await this.ctx();
189
+ const slug = data.slug ? slugify(data.slug) : slugify(data.name);
190
+ const existing = await ctx.store.listAreas();
191
+ assertUniqueAreaSlug(slug, existing.map((area) => area.slug));
192
+ const area = await ctx.store.scaffoldArea({
193
+ name: data.name,
194
+ slug,
195
+ description: data.description,
196
+ });
197
+ return areaCreateEnvelope(area, ctx.workspace);
198
+ }
199
+ // ── Issues ──
200
+ async registerIssue(data) {
201
+ return workItems.registerIssue(await this.ctx(), data);
202
+ }
203
+ async listIssues(options) {
204
+ return workItems.listIssues(await this.ctx(), options);
205
+ }
206
+ async getIssue(idOrNumber) {
207
+ return workItems.getIssue(await this.ctx(), idOrNumber);
208
+ }
209
+ async getIssueByNumber(issueNumber) {
210
+ return workItems.getIssueByNumber(await this.ctx(), issueNumber);
211
+ }
212
+ async resolveIssueByNumber(issueNumber, data) {
213
+ return workItems.resolveIssueByNumber(await this.ctx(), issueNumber, data);
214
+ }
215
+ async resolveIssue(idOrNumber, data) {
216
+ return workItems.resolveIssue(await this.ctx(), idOrNumber, data);
217
+ }
218
+ async updateIssueStatus(idOrNumber, data) {
219
+ return workItems.updateIssueStatus(await this.ctx(), idOrNumber, data);
220
+ }
221
+ async updateIssueStatusByNumber(issueNumber, data) {
222
+ return workItems.updateIssueStatusByNumber(await this.ctx(), issueNumber, data);
223
+ }
224
+ // ── Vibes ──
225
+ async logVibe(data) {
226
+ return workItems.logVibe(await this.ctx(), data);
227
+ }
228
+ async listVibes(options) {
229
+ return workItems.listVibes(await this.ctx(), options);
230
+ }
231
+ async getVibe(id) {
232
+ return workItems.getVibe(await this.ctx(), id);
233
+ }
234
+ async updateVibe(id, data) {
235
+ return workItems.updateVibe(await this.ctx(), id, data);
236
+ }
237
+ // ── Ideas ──
238
+ async listIdeas(options) {
239
+ return workItems.listIdeas(await this.ctx(), options);
240
+ }
241
+ async getIdea(idOrNumber) {
242
+ return workItems.getIdea(await this.ctx(), idOrNumber);
243
+ }
244
+ async getIdeaByNumber(ideaNumber) {
245
+ return workItems.getIdeaByNumber(await this.ctx(), ideaNumber);
246
+ }
247
+ async createIdea(data) {
248
+ return workItems.createIdea(await this.ctx(), data);
249
+ }
250
+ async updateIdeaStatus(idOrNumber, data) {
251
+ return workItems.updateIdeaStatus(await this.ctx(), idOrNumber, data);
252
+ }
253
+ async updateIdeaStatusByNumber(ideaNumber, data) {
254
+ return workItems.updateIdeaStatusByNumber(await this.ctx(), ideaNumber, data);
255
+ }
256
+ // ── Orbits (out of scope for the PoC — spec §1) ──
257
+ async listOrbits(_options) {
258
+ throw notSupported('Orbits (`orbit` commands)');
259
+ }
260
+ async getOrbit(_idOrSlug) {
261
+ throw notSupported('Orbits (`orbit` commands)');
262
+ }
263
+ async createOrbit(_data) {
264
+ throw notSupported('Orbits (`orbit` commands)');
265
+ }
266
+ async updateOrbit(_idOrSlug, _data) {
267
+ throw notSupported('Orbits (`orbit` commands)');
268
+ }
269
+ async getOrbitItems(_orbitIdOrSlug, _options) {
270
+ throw notSupported('Orbits (`orbit` commands)');
271
+ }
272
+ async orbitAttach(_orbitIdOrSlug, _data) {
273
+ throw notSupported('Orbits (`orbit` commands)');
274
+ }
275
+ async orbitDetach(_orbitIdOrSlug, _data) {
276
+ throw notSupported('Orbits (`orbit` commands)');
277
+ }
278
+ async addOrbitArea(_orbitIdOrSlug, _areaId) {
279
+ throw notSupported('Orbits (`orbit` commands)');
280
+ }
281
+ async removeOrbitArea(_orbitIdOrSlug, _areaId) {
282
+ throw notSupported('Orbits (`orbit` commands)');
283
+ }
284
+ async addOrbitDependency(_orbitIdOrSlug, _data) {
285
+ throw notSupported('Orbits (`orbit` commands)');
286
+ }
287
+ // ── Intents ──
288
+ async listIntents(options) {
289
+ return planning.listIntents(await this.ctx(), options);
290
+ }
291
+ async getIntent(idOrNumber) {
292
+ return planning.getIntent(await this.ctx(), idOrNumber);
293
+ }
294
+ async createIntent(data) {
295
+ return planning.createIntent(await this.ctx(), data);
296
+ }
297
+ async updateIntent(idOrNumber, data) {
298
+ return planning.updateIntent(await this.ctx(), idOrNumber, data);
299
+ }
300
+ async linkIntentItem(idOrNumber, data) {
301
+ return planning.linkIntentItem(await this.ctx(), idOrNumber, data);
302
+ }
303
+ async unlinkIntentItem(idOrNumber, data) {
304
+ return planning.unlinkIntentItem(await this.ctx(), idOrNumber, data);
305
+ }
306
+ async setIntentOrbit(_idOrNumber, _orbitId) {
307
+ throw notSupported('Orbits (`orbit` commands)');
308
+ }
309
+ // ── Missions ──
310
+ async listMissions(options) {
311
+ return planning.listMissions(await this.ctx(), options);
312
+ }
313
+ async getMission(idOrNumber) {
314
+ return planning.getMission(await this.ctx(), idOrNumber);
315
+ }
316
+ async createMission(data) {
317
+ return planning.createMission(await this.ctx(), data);
318
+ }
319
+ async updateMission(idOrNumber, data) {
320
+ return planning.updateMission(await this.ctx(), idOrNumber, data);
321
+ }
322
+ async setMissionStatus(idOrNumber, data) {
323
+ return planning.setMissionStatus(await this.ctx(), idOrNumber, data);
324
+ }
325
+ async linkMissionItem(idOrNumber, data) {
326
+ return planning.linkMissionItem(await this.ctx(), idOrNumber, data);
327
+ }
328
+ async unlinkMissionItem(idOrNumber, data) {
329
+ return planning.unlinkMissionItem(await this.ctx(), idOrNumber, data);
330
+ }
331
+ // ── Prompts ──
332
+ async getWorkPrompt() {
333
+ const ctx = await this.ctx();
334
+ const area = await requireAreaFile(ctx);
335
+ const files = await ctx.store.listEntities('task', { area: area.slug });
336
+ const picked = selectNextTask(files.map((file) => file.frontmatter));
337
+ if (!picked)
338
+ return workPromptEnvelope(area, null, null);
339
+ const file = files.find((entry) => entry.frontmatter.task_number === picked.task_number);
340
+ return workPromptEnvelope(area, file ? file.frontmatter : null, file ? parseDescription(file.body) : null);
341
+ }
342
+ async getImportDocsPrompt() {
343
+ return importDocsPromptEnvelope(await requireAreaFile(await this.ctx()));
344
+ }
345
+ }
346
+ //# sourceMappingURL=adapter.js.map