@aopslabs/aops 0.3.24 → 0.3.26

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 (64) hide show
  1. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/SKILL.md +0 -1
  2. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/agentspace/SKILL.md +0 -6
  3. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/collaborative-work/SKILL.md +1 -2
  4. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/working-disciplines/SKILL.md +2 -5
  5. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/agentspace.md +1 -16
  6. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/aops-cli.md +4 -33
  7. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/working-disciplines.md +32 -138
  8. package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/manifest.json +17 -22
  9. package/agent-assets-release/agent-assets/inventory.json +5 -5
  10. package/agent-assets-release/agent-assets/projection.json +1 -1
  11. package/agent-assets-release/agent-assets-release.json +48 -53
  12. package/agent-assets-release/agent-assets-release.sigstore.json +27 -28
  13. package/assets/agent-assets/core/SKILL.md +0 -1
  14. package/assets/agent-assets/core/references/agentspace/SKILL.md +0 -6
  15. package/assets/agent-assets/core/references/collaborative-work/SKILL.md +1 -2
  16. package/assets/agent-assets/core/references/working-disciplines/SKILL.md +2 -5
  17. package/assets/agent-assets/core/user-guides/agentspace.md +1 -16
  18. package/assets/agent-assets/core/user-guides/aops-cli.md +4 -33
  19. package/assets/agent-assets/core/user-guides/working-disciplines.md +32 -138
  20. package/dist/commands/checkpoint.js +4 -23
  21. package/dist/commands/community-server.js +212 -6
  22. package/dist/commands/db.js +145 -0
  23. package/dist/commands/experience.js +0 -2
  24. package/dist/commands/memory.js +8 -2
  25. package/dist/commands/official-catalog.js +1 -1
  26. package/dist/commands/plan.js +2 -2
  27. package/dist/commands/pm/index.js +39 -3
  28. package/dist/commands/pm/projectman.js +281 -8
  29. package/dist/commands/start-disciplines.js +8 -21
  30. package/dist/commands/start.js +20 -504
  31. package/dist/lib/agent-assets/native-fs.js +2 -2
  32. package/dist/lib/community-migration-snapshot.js +43 -2
  33. package/dist/lib/community-native-backup.js +386 -0
  34. package/dist/lib/community-native-lifecycle.js +93 -4
  35. package/dist/lib/community-native-migration.js +20 -0
  36. package/dist/main.js +2 -2
  37. package/dist/seeds/agents-md.js +1 -1
  38. package/dist/utils/playbook-workspace.js +5 -33
  39. package/dist/utils/session-guidance.js +0 -7
  40. package/native/bin/darwin-arm64/aops-agent-assets-fs +0 -0
  41. package/native/bin/darwin-x64/aops-agent-assets-fs +0 -0
  42. package/native/bin/win32-x64/aops-agent-assets-fs.exe +0 -0
  43. package/native/manifest.json +4 -4
  44. package/native/qualifications/win32-x64.json +2 -2
  45. package/native/tui/darwin-arm64/aops-tui +0 -0
  46. package/native/tui/linux-x64/aops-tui +0 -0
  47. package/native/tui/win32-x64/aops-tui.exe +0 -0
  48. package/package.json +18 -6
  49. package/agent-assets-release/agent-assets/core/647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09/files/references/mission/SKILL.md +0 -54
  50. package/assets/agent-assets/core/references/mission/SKILL.md +0 -54
  51. package/dist/commands/mission.js +0 -562
  52. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/aops-cli-core/SKILL.md +0 -0
  53. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/chatv3/SKILL.md +0 -0
  54. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/discuss/SKILL.md +0 -0
  55. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/docman/SKILL.md +0 -0
  56. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/projectman/SKILL.md +0 -0
  57. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/sys/SKILL.md +0 -0
  58. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/references/view/SKILL.md +0 -0
  59. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/agent-assets.md +0 -0
  60. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/aops-system.md +0 -0
  61. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/chatv3.md +0 -0
  62. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/docman.md +0 -0
  63. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/projectman.md +0 -0
  64. /package/agent-assets-release/agent-assets/core/{647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09 → bc42dd7792dbe66040e99a7ef3d80b3bc788c72b369b5a065cf936aef29f53fb}/files/user-guides/sys.md +0 -0
@@ -1,562 +0,0 @@
1
- import { Command } from 'commander';
2
- import { logError, logSuccess } from '@aopslabs/xf-cli-ui';
3
- import { applyCommonOptions, compactPayload, normalizeNonEmpty } from '../utils/command.js';
4
- import { loadAopsRepoConfigReadOnly } from '../utils/repo-config.js';
5
- import { buildReadOnlyActivePlaybookNudgePackFromContext, } from '../utils/playbook-workspace.js';
6
- import { buildSessionGuidancePack, } from '../utils/session-guidance.js';
7
- import { invokeHostedToolWithApiState, parseJsonInput, requireApiState, resolveAgentGatewayContext, unwrapHostedToolResult, } from '../utils/agent-gateway.js';
8
- import { buildHostedSugarEnvelope, ensureGuardedWrite, missingScopeIdMessage, } from '../utils/hosted-sugar.js';
9
- function isRecord(value) {
10
- return value !== null && typeof value === 'object' && !Array.isArray(value);
11
- }
12
- function toRecordArray(value) {
13
- if (Array.isArray(value))
14
- return value.filter(isRecord);
15
- return [];
16
- }
17
- function toStringArray(values) {
18
- return Array.isArray(values)
19
- ? values.map((entry) => normalizeNonEmpty(entry)).filter((entry) => Boolean(entry))
20
- : [];
21
- }
22
- function collectRepeatedOption(value, previous = []) {
23
- const normalized = normalizeNonEmpty(value);
24
- return normalized ? [...previous, normalized] : previous;
25
- }
26
- function parsePositiveInteger(value, label) {
27
- if (value === undefined || value === null || value === '')
28
- return undefined;
29
- if (typeof value === 'number' && Number.isInteger(value) && value > 0)
30
- return value;
31
- const normalized = normalizeNonEmpty(value);
32
- if (!normalized)
33
- return undefined;
34
- const parsed = Number.parseInt(normalized, 10);
35
- if (!Number.isInteger(parsed) || parsed <= 0)
36
- throw new Error(`${label} must be a positive integer.`);
37
- return parsed;
38
- }
39
- function parseJsonObject(value, label) {
40
- const normalized = normalizeNonEmpty(value);
41
- if (!normalized)
42
- return undefined;
43
- const parsed = parseJsonInput(normalized, label);
44
- if (!isRecord(parsed))
45
- throw new Error(`${label} must be a JSON object or @file.json object.`);
46
- return parsed;
47
- }
48
- function parseJsonRecordArray(values, label) {
49
- const strings = toStringArray(values);
50
- if (strings.length === 0)
51
- return undefined;
52
- return strings.map((entry, index) => {
53
- const parsed = parseJsonInput(entry, `${label}[${index}]`);
54
- if (!isRecord(parsed))
55
- throw new Error(`${label}[${index}] must be a JSON object or @file.json object.`);
56
- return parsed;
57
- });
58
- }
59
- function unwrapResultData(result) {
60
- if (isRecord(result) && Object.prototype.hasOwnProperty.call(result, 'data'))
61
- return result.data;
62
- return result;
63
- }
64
- function requireMissionId(id) {
65
- const normalized = normalizeNonEmpty(id);
66
- if (!normalized)
67
- throw new Error('Provide --id.');
68
- return normalized;
69
- }
70
- function requireScopeId(context, seed) {
71
- const scopeId = normalizeNonEmpty(context.scopeId) ?? normalizeNonEmpty(seed.scopeId);
72
- if (!scopeId)
73
- throw new Error(missingScopeIdMessage('Mission create'));
74
- return scopeId;
75
- }
76
- function buildResolvedContextRecord(context) {
77
- return compactPayload({
78
- tenantId: context.tenantId,
79
- scopeId: context.scopeId,
80
- projectId: context.projectId,
81
- projectName: context.projectName,
82
- scopeResolution: context.scopeResolution,
83
- });
84
- }
85
- function missionRef(refType, refId, title) {
86
- return compactPayload({ refType, refId, title });
87
- }
88
- function buildMissionCreateData(options, context) {
89
- const seed = parseJsonObject(options.input, '--input') ?? {};
90
- const data = isRecord(seed.data) ? { ...seed.data } : { ...seed };
91
- const scopeId = requireScopeId(context, data);
92
- const objective = normalizeNonEmpty(options.objective) ?? normalizeNonEmpty(data.objective);
93
- if (!objective)
94
- throw new Error('Provide --objective or --input with objective.');
95
- return compactPayload({
96
- ...data,
97
- scopeId,
98
- slug: normalizeNonEmpty(options.slug) ?? normalizeNonEmpty(data.slug),
99
- status: normalizeNonEmpty(options.status) ?? normalizeNonEmpty(data.status),
100
- objective,
101
- taskDefinition: normalizeNonEmpty(options.taskDefinition) ?? normalizeNonEmpty(data.taskDefinition),
102
- successCriteria: toStringArray(options.successCriterion).length > 0 ? toStringArray(options.successCriterion) : data.successCriteria,
103
- constraints: toStringArray(options.constraint).length > 0 ? toStringArray(options.constraint) : data.constraints,
104
- policy: parseJsonObject(options.policyJson, '--policy-json') ?? data.policy,
105
- roles: parseJsonObject(options.rolesJson, '--roles-json') ?? data.roles,
106
- references: parseJsonRecordArray(options.referenceJson, '--reference-json') ?? data.references,
107
- visionDocRef: normalizeNonEmpty(options.visionDoc) ? missionRef('docman.document', normalizeNonEmpty(options.visionDoc)) : data.visionDocRef,
108
- activeImplementationPlanRef: normalizeNonEmpty(options.activePlan)
109
- ? missionRef('projectman.sprint', normalizeNonEmpty(options.activePlan))
110
- : data.activeImplementationPlanRef,
111
- bodyMarkdown: normalizeNonEmpty(options.body) ?? normalizeNonEmpty(data.bodyMarkdown),
112
- });
113
- }
114
- function buildMissionPatch(options) {
115
- const seed = parseJsonObject(options.input, '--input') ?? {};
116
- const patch = isRecord(seed.patch) ? { ...seed.patch } : { ...seed };
117
- return compactPayload({
118
- ...patch,
119
- status: normalizeNonEmpty(options.status) ?? normalizeNonEmpty(patch.status),
120
- objective: normalizeNonEmpty(options.objective) ?? normalizeNonEmpty(patch.objective),
121
- activeImplementationPlanRef: normalizeNonEmpty(options.activePlan)
122
- ? missionRef('projectman.sprint', normalizeNonEmpty(options.activePlan))
123
- : patch.activeImplementationPlanRef,
124
- });
125
- }
126
- function summarizeText(value, maxLength = 180) {
127
- const normalized = normalizeNonEmpty(value);
128
- if (!normalized)
129
- return undefined;
130
- const compact = normalized.replace(/\s+/g, ' ').trim();
131
- return compact.length <= maxLength ? compact : `${compact.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
132
- }
133
- function summarizeRecord(value) {
134
- if (!isRecord(value))
135
- return undefined;
136
- return compactPayload({
137
- id: normalizeNonEmpty(value.id) ?? normalizeNonEmpty(value.localId),
138
- title: normalizeNonEmpty(value.title) ?? normalizeNonEmpty(value.name),
139
- status: normalizeNonEmpty(value.status),
140
- kind: normalizeNonEmpty(value.kind) ?? normalizeNonEmpty(value.entityType),
141
- summary: summarizeText(value.summary ?? value.content ?? value.description),
142
- ref: normalizeNonEmpty(value.ref) ?? normalizeNonEmpty(value.uri),
143
- });
144
- }
145
- function summarizeRecords(value, limit) {
146
- return toRecordArray(value).slice(0, limit).map(summarizeRecord).filter((entry) => Boolean(entry));
147
- }
148
- function summarizeCheckpoint(value) {
149
- if (!isRecord(value))
150
- return undefined;
151
- return compactPayload({
152
- id: normalizeNonEmpty(value.id),
153
- kind: normalizeNonEmpty(value.kind),
154
- checkpointAs: normalizeNonEmpty(value.checkpointAs),
155
- current: typeof value.current === 'boolean' ? value.current : undefined,
156
- superseded: typeof value.superseded === 'boolean' ? value.superseded : undefined,
157
- supersedes: normalizeNonEmpty(value.supersedes),
158
- summary: summarizeText(value.summary, 220),
159
- position: summarizeText(value.position, 160),
160
- doneWork: toStringArray(value.doneWork).slice(0, 5),
161
- nextSteps: toStringArray(value.nextSteps).slice(0, 5),
162
- sourceRefs: Array.isArray(value.sourceRefs) ? value.sourceRefs.slice(0, 5) : undefined,
163
- anchors: value.anchors,
164
- createdAt: normalizeNonEmpty(value.createdAt),
165
- updatedAt: normalizeNonEmpty(value.updatedAt),
166
- });
167
- }
168
- function summarizeCheckpointRecords(value, limit) {
169
- return toRecordArray(value).slice(0, limit).map(summarizeCheckpoint).filter((entry) => Boolean(entry));
170
- }
171
- function summarizeCheckpoints(value, limit) {
172
- if (!isRecord(value))
173
- return undefined;
174
- const current = summarizeCheckpoint(value.current);
175
- const recent = summarizeCheckpointRecords(value.recent, Math.min(limit, 5));
176
- const total = typeof value.total === 'number' ? value.total : undefined;
177
- if (!current && recent.length === 0 && total === undefined)
178
- return undefined;
179
- return compactPayload({ current, recent, total });
180
- }
181
- export function buildMissionResumeInput(options) {
182
- const id = requireMissionId(options.id);
183
- return compactPayload({
184
- id,
185
- options: compactPayload({
186
- depth: normalizeNonEmpty(options.depth) ?? 'light',
187
- limit: parsePositiveInteger(options.limit, '--limit') ?? 8,
188
- }),
189
- });
190
- }
191
- export function summarizeMissionResumePack(result, options, playbookNudges, sessionGuidance) {
192
- const pack = unwrapResultData(result);
193
- if (!isRecord(pack))
194
- return result;
195
- const limit = parsePositiveInteger(options.limit, '--limit') ?? 8;
196
- const mission = isRecord(pack.mission) ? pack.mission : {};
197
- const activePlan = isRecord(pack.activePlan) ? pack.activePlan : {};
198
- const chat = isRecord(pack.chat) ? pack.chat : {};
199
- const refs = Array.isArray(mission.refs) ? mission.refs.slice(0, limit) : [];
200
- return compactPayload({
201
- schemaVersion: pack.schemaVersion,
202
- generatedAt: normalizeNonEmpty(pack.generatedAt),
203
- mission: compactPayload({
204
- id: normalizeNonEmpty(mission.id),
205
- slug: normalizeNonEmpty(mission.slug),
206
- objective: summarizeText(mission.objective, 240),
207
- status: normalizeNonEmpty(mission.status),
208
- policy: isRecord(mission.policy) ? mission.policy : undefined,
209
- refs,
210
- refCount: Array.isArray(mission.refs) ? mission.refs.length : undefined,
211
- }),
212
- activePlan: compactPayload({
213
- sprintId: normalizeNonEmpty(activePlan.sprintId),
214
- ref: activePlan.ref,
215
- currentSlice: activePlan.currentSlice,
216
- nextSlice: activePlan.nextSlice,
217
- progress: activePlan.progress,
218
- }),
219
- memory: summarizeRecords(pack.memory, limit),
220
- checkpoints: summarizeCheckpoints(pack.checkpoints, limit),
221
- reviews: summarizeRecords(pack.reviews, limit),
222
- issues: summarizeRecords(pack.issues, limit),
223
- chat: compactPayload({
224
- unread: typeof chat.unread === 'number' ? chat.unread : 0,
225
- lastN: summarizeRecords(chat.lastN, Math.min(limit, 5)),
226
- }),
227
- playbookNudges,
228
- sessionGuidance,
229
- summary: {
230
- mode: 'mission-resume-summary',
231
- readStrategy: 'mission-deterministic-compact',
232
- limit,
233
- fullRecordHint: 'Use `aops-cli mission resume --id <mission-id> --full --json` for the full hosted resume skeleton.',
234
- },
235
- });
236
- }
237
- async function loadMissionResumePlaybookNudges(options, missionId) {
238
- try {
239
- const loaded = await loadAopsRepoConfigReadOnly(process.cwd());
240
- const activeProject = loaded.config?.projects?.find((project) => project.name === loaded.config?.activeProjectName);
241
- const projectSlug = normalizeNonEmpty(options.projectSlug)
242
- ?? normalizeNonEmpty(activeProject?.slug)
243
- ?? normalizeNonEmpty(activeProject?.name);
244
- return await buildReadOnlyActivePlaybookNudgePackFromContext({
245
- repoRoot: loaded.rootDir,
246
- localRoot: activeProject?.localRoot,
247
- projectSlug,
248
- }, {
249
- missionId,
250
- limit: parsePositiveInteger(options.limit, '--limit') ?? 8,
251
- });
252
- }
253
- catch {
254
- return undefined;
255
- }
256
- }
257
- function sessionGuidanceDisciplineFromPolicy(policy) {
258
- if (!isRecord(policy))
259
- return undefined;
260
- const discipline = isRecord(policy.discipline) ? policy.discipline : {};
261
- const guardrails = toRecordArray(policy.guardrails).map((guardrail) => ({
262
- id: normalizeNonEmpty(guardrail.id),
263
- title: normalizeNonEmpty(guardrail.title),
264
- description: normalizeNonEmpty(guardrail.description),
265
- phase: normalizeNonEmpty(guardrail.phase),
266
- evidence: toStringArray(guardrail.evidence),
267
- enforcementLevel: normalizeNonEmpty(guardrail.enforcementLevel),
268
- }));
269
- return {
270
- selected: normalizeNonEmpty(discipline.id),
271
- recommended: normalizeNonEmpty(discipline.recommended),
272
- explicit: normalizeNonEmpty(discipline.selectedBy) === 'operator',
273
- profile: {
274
- id: normalizeNonEmpty(discipline.id),
275
- version: normalizeNonEmpty(discipline.version),
276
- },
277
- guardrails,
278
- };
279
- }
280
- async function loadMissionResumeSessionGuidance(options, missionId, rawResult, playbookNudges) {
281
- try {
282
- const loaded = await loadAopsRepoConfigReadOnly(process.cwd());
283
- const activeProject = loaded.config?.projects?.find((project) => project.name === loaded.config?.activeProjectName);
284
- const projectSlug = normalizeNonEmpty(options.projectSlug)
285
- ?? normalizeNonEmpty(activeProject?.slug)
286
- ?? normalizeNonEmpty(activeProject?.name);
287
- const pack = unwrapResultData(rawResult);
288
- const mission = isRecord(pack?.mission) ? pack.mission : {};
289
- const activePlan = isRecord(pack?.activePlan) ? pack.activePlan : {};
290
- return await buildSessionGuidancePack({
291
- repoRoot: loaded.rootDir,
292
- localRoot: activeProject?.localRoot,
293
- projectSlug,
294
- }, {
295
- surface: 'mission-resume',
296
- task: normalizeNonEmpty(mission.objective),
297
- missionId,
298
- planId: normalizeNonEmpty(activePlan.sprintId),
299
- playbookNudges,
300
- discipline: sessionGuidanceDisciplineFromPolicy(mission.policy),
301
- });
302
- }
303
- catch {
304
- return undefined;
305
- }
306
- }
307
- export async function loadMissionResumePack(options = {}) {
308
- const input = buildMissionResumeInput(options);
309
- const missionId = normalizeNonEmpty(input.id) ?? requireMissionId(options.id);
310
- const apiState = await requireApiState(options);
311
- if (!apiState)
312
- return null;
313
- const context = await resolveAgentGatewayContext(options);
314
- const payload = await invokeHostedToolWithApiState(apiState, {
315
- ...options,
316
- scopeId: context.scopeId,
317
- projectId: context.projectId,
318
- projectName: context.projectName,
319
- toolId: 'agentspace.mission.resume',
320
- input,
321
- });
322
- const rawResult = unwrapHostedToolResult(payload);
323
- const playbookNudges = await loadMissionResumePlaybookNudges(options, missionId);
324
- const sessionGuidance = options.full === true
325
- ? undefined
326
- : await loadMissionResumeSessionGuidance(options, missionId, rawResult, playbookNudges);
327
- return {
328
- command: 'mission.resume',
329
- toolId: 'agentspace.mission.resume',
330
- input,
331
- resolvedContext: buildResolvedContextRecord(context),
332
- result: options.full === true
333
- ? rawResult
334
- : summarizeMissionResumePack(rawResult, options, playbookNudges, sessionGuidance),
335
- };
336
- }
337
- async function invokeMissionTool(options, params) {
338
- const apiState = await requireApiState(options);
339
- if (!apiState)
340
- return;
341
- const context = await resolveAgentGatewayContext(options);
342
- const payload = await invokeHostedToolWithApiState(apiState, {
343
- ...options,
344
- scopeId: context.scopeId,
345
- projectId: context.projectId,
346
- projectName: context.projectName,
347
- toolId: params.toolId,
348
- input: params.input,
349
- preview: params.preview ?? options.preview,
350
- apply: params.apply ?? options.apply,
351
- idempotencyKey: options.idempotencyKey,
352
- });
353
- const rawResult = unwrapHostedToolResult(payload);
354
- const result = params.transform ? params.transform(rawResult) : rawResult;
355
- if (options.json) {
356
- console.log(JSON.stringify(buildHostedSugarEnvelope({
357
- command: params.command,
358
- toolId: params.toolId,
359
- resolvedContext: buildResolvedContextRecord(context),
360
- input: params.input,
361
- result,
362
- }), null, 2));
363
- return;
364
- }
365
- logSuccess(params.successText);
366
- console.log(JSON.stringify(result, null, 2));
367
- }
368
- export async function runMissionCreate(options = {}) {
369
- try {
370
- ensureGuardedWrite(options, 'This command mutates hosted mission state.');
371
- const apiState = await requireApiState(options);
372
- if (!apiState)
373
- return;
374
- const context = await resolveAgentGatewayContext(options);
375
- const data = buildMissionCreateData(options, context);
376
- const payload = await invokeHostedToolWithApiState(apiState, {
377
- ...options,
378
- scopeId: context.scopeId,
379
- projectId: context.projectId,
380
- projectName: context.projectName,
381
- toolId: 'agentspace.mission.create',
382
- input: { data },
383
- preview: options.preview,
384
- apply: options.apply,
385
- idempotencyKey: options.idempotencyKey,
386
- });
387
- const result = unwrapHostedToolResult(payload);
388
- if (options.json) {
389
- console.log(JSON.stringify(buildHostedSugarEnvelope({
390
- command: 'mission.create',
391
- toolId: 'agentspace.mission.create',
392
- resolvedContext: buildResolvedContextRecord(context),
393
- input: { data },
394
- result,
395
- }), null, 2));
396
- return;
397
- }
398
- logSuccess('Mission created.');
399
- console.log(JSON.stringify(result, null, 2));
400
- }
401
- catch (error) {
402
- logError(`Failed to execute mission create: ${error instanceof Error ? error.message : String(error)}`);
403
- process.exitCode = 1;
404
- }
405
- }
406
- export async function runMissionList(options = {}) {
407
- try {
408
- const filter = compactPayload({
409
- scopeId: normalizeNonEmpty(options.scopeId),
410
- scopeResolution: normalizeNonEmpty(options.scopeResolution),
411
- status: normalizeNonEmpty(options.status),
412
- slug: normalizeNonEmpty(options.slug),
413
- });
414
- await invokeMissionTool(options, {
415
- command: 'mission.list',
416
- toolId: 'agentspace.mission.list',
417
- input: compactPayload({ filter, options: compactPayload({ limit: parsePositiveInteger(options.limit, '--limit') }) }),
418
- successText: 'Missions listed.',
419
- transform: (result) => {
420
- if (!options.summary)
421
- return result;
422
- const rows = toRecordArray(unwrapResultData(result)).slice(0, parsePositiveInteger(options.limit, '--limit') ?? 20);
423
- return {
424
- data: rows.map((row) => compactPayload({
425
- id: normalizeNonEmpty(row.id),
426
- slug: normalizeNonEmpty(row.slug),
427
- objective: summarizeText(row.objective, 160),
428
- status: normalizeNonEmpty(row.status),
429
- activePlan: row.activeImplementationPlanRef,
430
- })),
431
- summary: { mode: 'mission-list-summary', shown: rows.length },
432
- };
433
- },
434
- });
435
- }
436
- catch (error) {
437
- logError(`Failed to execute mission list: ${error instanceof Error ? error.message : String(error)}`);
438
- process.exitCode = 1;
439
- }
440
- }
441
- export async function runMissionGet(options = {}) {
442
- try {
443
- const id = requireMissionId(options.id);
444
- await invokeMissionTool(options, {
445
- command: 'mission.get',
446
- toolId: 'agentspace.mission.get',
447
- input: { id },
448
- successText: 'Mission loaded.',
449
- });
450
- }
451
- catch (error) {
452
- logError(`Failed to execute mission get: ${error instanceof Error ? error.message : String(error)}`);
453
- process.exitCode = 1;
454
- }
455
- }
456
- export async function runMissionUpdate(options = {}) {
457
- try {
458
- ensureGuardedWrite(options, 'This command mutates hosted mission state.');
459
- const id = requireMissionId(options.id);
460
- const patch = buildMissionPatch(options);
461
- if (Object.keys(patch).length === 0)
462
- throw new Error('Provide at least one patch field.');
463
- await invokeMissionTool(options, {
464
- command: 'mission.update',
465
- toolId: 'agentspace.mission.update',
466
- input: { id, patch },
467
- successText: 'Mission updated.',
468
- });
469
- }
470
- catch (error) {
471
- logError(`Failed to execute mission update: ${error instanceof Error ? error.message : String(error)}`);
472
- process.exitCode = 1;
473
- }
474
- }
475
- export async function runMissionResume(options = {}) {
476
- try {
477
- const loaded = await loadMissionResumePack(options);
478
- if (!loaded)
479
- return;
480
- if (options.json) {
481
- console.log(JSON.stringify(buildHostedSugarEnvelope({
482
- command: loaded.command,
483
- toolId: loaded.toolId,
484
- resolvedContext: loaded.resolvedContext,
485
- input: loaded.input,
486
- result: loaded.result,
487
- }), null, 2));
488
- return;
489
- }
490
- logSuccess('Mission resume pack built.');
491
- console.log(JSON.stringify(loaded.result, null, 2));
492
- }
493
- catch (error) {
494
- logError(`Failed to execute mission resume: ${error instanceof Error ? error.message : String(error)}`);
495
- process.exitCode = 1;
496
- }
497
- }
498
- function addMissionContextOptions(cmd) {
499
- applyCommonOptions(cmd, { withProject: true });
500
- cmd.option('--scope-id <id>', 'Canonical owner scope override');
501
- cmd.option('--scope-resolution <mode>', 'Scope resolution for hosted reads: explicit | cascade');
502
- cmd.option('--tenant-id <id>', 'Tenant id header (x-tenant-id)');
503
- cmd.option('--locale <locale>', 'Locale header (x-locale)');
504
- cmd.option('--fallback-locale <locale>', 'Fallback locale header (x-fallback-locale)');
505
- return cmd;
506
- }
507
- export function makeMissionCommand() {
508
- const cmd = new Command('mission')
509
- .description('Agentspace mission commands and token-efficient mission resume packs');
510
- addMissionContextOptions(cmd.command('create')
511
- .description('Create a hosted Agentspace mission')
512
- .option('--input <json-or-@file>', 'Mission data JSON object; may be wrapped as { data }')
513
- .option('--slug <slug>', 'Mission slug')
514
- .option('--status <status>', 'Mission status: draft | active | completed | archived')
515
- .option('--objective <text>', 'Mission objective')
516
- .option('--task-definition <text>', 'Task definition')
517
- .option('--success-criterion <text>', 'Repeatable success criterion', collectRepeatedOption, [])
518
- .option('--constraint <text>', 'Repeatable constraint', collectRepeatedOption, [])
519
- .option('--policy-json <json-or-@file>', 'Mission policy JSON object')
520
- .option('--roles-json <json-or-@file>', 'Mission roles JSON object')
521
- .option('--reference-json <json-or-@file>', 'Repeatable mission ref JSON object', collectRepeatedOption, [])
522
- .option('--vision-doc <id>', 'Docman document id to store as visionDocRef')
523
- .option('--active-plan <sprint-id>', 'Projectman sprint/implementation-plan id to store as activeImplementationPlanRef')
524
- .option('--body <markdown>', 'Mission body markdown')
525
- .option('--preview', 'Validate without mutating hosted state')
526
- .option('--apply', 'Apply hosted mission mutation')
527
- .option('--idempotency-key <key>', 'Optional guarded-write idempotency key')).action(async (options) => runMissionCreate(options));
528
- addMissionContextOptions(cmd.command('list')
529
- .description('List hosted Agentspace missions')
530
- .option('--status <status>', 'Filter by mission status')
531
- .option('--slug <slug>', 'Filter by slug')
532
- .option('--limit <n>', 'Limit returned missions')
533
- .option('--summary', 'Print compact mission records')).action(async (options) => runMissionList(options));
534
- addMissionContextOptions(cmd.command('get')
535
- .description('Get a hosted Agentspace mission by id')
536
- .requiredOption('--id <id>', 'Mission id')).action(async (options) => runMissionGet(options));
537
- addMissionContextOptions(cmd.command('update')
538
- .description('Patch a hosted Agentspace mission')
539
- .requiredOption('--id <id>', 'Mission id')
540
- .option('--input <json-or-@file>', 'Mission patch JSON object; may be wrapped as { patch }')
541
- .option('--status <status>', 'Mission status')
542
- .option('--objective <text>', 'Mission objective')
543
- .option('--active-plan <sprint-id>', 'Projectman sprint/implementation-plan id')
544
- .option('--preview', 'Validate without mutating hosted state')
545
- .option('--apply', 'Apply hosted mission mutation')
546
- .option('--idempotency-key <key>', 'Optional guarded-write idempotency key')).action(async (options) => runMissionUpdate(options));
547
- addMissionContextOptions(cmd.command('resume')
548
- .description('Build a deterministic, token-efficient mission resume pack')
549
- .requiredOption('--id <id>', 'Mission id')
550
- .option('--depth <depth>', 'Resume depth: light | standard', 'light')
551
- .option('--limit <n>', 'Maximum refs/rows to include in compact sections', '8')
552
- .option('--full', 'Return the full hosted mission resume skeleton instead of the compact summary')
553
- .option('--summary', 'Kept for parity; compact summary is the default')).action(async (options) => runMissionResume(options));
554
- cmd.addHelpText('after', `
555
- Notes:
556
- Mission is Agentspace-owned durable intent and policy. Projectman remains execution/review truth.
557
- mission.resume defaults to a compact, token-efficient schemaVersion 1 pack; use --full only when the raw hosted skeleton is needed.
558
- mission handoff is intentionally deferred in this slice; use Projectman handoff or mem summary for handoff records.
559
- activeImplementationPlanRef is a Projectman sprint-backed implementation-plan ref; the plan id is the sprint id.
560
- `);
561
- return cmd;
562
- }