@aopslabs/aops 0.3.20 → 0.3.21

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 (41) hide show
  1. package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/projectman.md +14 -0
  2. package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/manifest.json +5 -5
  3. package/agent-assets-release/agent-assets/inventory.json +5 -5
  4. package/agent-assets-release/agent-assets/projection.json +1 -1
  5. package/agent-assets-release/agent-assets-release.json +36 -36
  6. package/agent-assets-release/agent-assets-release.sigstore.json +28 -21
  7. package/assets/agent-assets/core/user-guides/projectman.md +14 -0
  8. package/dist/commands/chat-wake-watch.js +369 -0
  9. package/dist/commands/chatv3.js +74 -1
  10. package/dist/commands/codex.js +161 -0
  11. package/dist/commands/pm/index.js +3 -3
  12. package/dist/commands/pm/projectman.js +117 -20
  13. package/dist/lib/agent-assets/native-fs.js +2 -2
  14. package/dist/lib/cli-error-format.js +32 -0
  15. package/dist/lib/community-diagnostic.js +9 -2
  16. package/dist/main.js +9 -2
  17. package/native/manifest.json +1 -1
  18. package/native/qualifications/win32-x64.json +1 -1
  19. package/native/tui/darwin-arm64/aops-tui +0 -0
  20. package/native/tui/win32-x64/aops-tui.exe +0 -0
  21. package/package.json +7 -5
  22. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/SKILL.md +0 -0
  23. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/agentspace/SKILL.md +0 -0
  24. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/aops-cli-core/SKILL.md +0 -0
  25. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/chatv3/SKILL.md +0 -0
  26. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/collaborative-work/SKILL.md +0 -0
  27. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/discuss/SKILL.md +0 -0
  28. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/docman/SKILL.md +0 -0
  29. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/mission/SKILL.md +0 -0
  30. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/projectman/SKILL.md +0 -0
  31. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/sys/SKILL.md +0 -0
  32. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/view/SKILL.md +0 -0
  33. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/references/working-disciplines/SKILL.md +0 -0
  34. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/agent-assets.md +0 -0
  35. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/agentspace.md +0 -0
  36. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/aops-cli.md +0 -0
  37. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/aops-system.md +0 -0
  38. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/chatv3.md +0 -0
  39. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/docman.md +0 -0
  40. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/sys.md +0 -0
  41. /package/agent-assets-release/agent-assets/core/{387548b990d0cfef6a92805f39d18c2ae6b4bb6b1e42ea42e6c597ea7d207447 → 47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a}/files/user-guides/working-disciplines.md +0 -0
@@ -256,7 +256,7 @@ function addUtaskCommands(cmd) {
256
256
  .requiredOption('--sprint <id>', 'Sprint id')
257
257
  .requiredOption('--id <id>', 'Utask id')
258
258
  .option('--title <title>', 'Updated utask title')
259
- .option('--status <value>', 'Updated utask status')
259
+ .option('--status <value>', 'Updated utask status (canonical: completed; aliases: done, complete)')
260
260
  .option('--notes <text>', 'Updated utask notes')
261
261
  .option('--position <index>', 'Optional position override', (value) => Number.parseInt(String(value), 10)), { destructive: false })).action(async (options) => {
262
262
  await runPmUtaskUpdate(options);
@@ -266,7 +266,7 @@ function addUtaskCommands(cmd) {
266
266
  .description('Update only the lifecycle status of a sprint-bound utask')
267
267
  .requiredOption('--sprint <id>', 'Sprint id')
268
268
  .requiredOption('--id <id>', 'Utask id')
269
- .requiredOption('--status <value>', 'Updated utask status'), { destructive: false }).action(async (options) => {
269
+ .requiredOption('--status <value>', 'Updated utask status (canonical: completed; aliases: done, complete)'), { destructive: false }).action(async (options) => {
270
270
  await runPmUtaskSetStatus(options);
271
271
  }));
272
272
  applyPmContextOptions(applyWriteOptions(utask
@@ -344,7 +344,7 @@ function addSprintCommands(cmd) {
344
344
  .command('set-status')
345
345
  .description('Set all microtask statuses in a sprint to the target status, deriving the sprint-level status')
346
346
  .requiredOption('--id <id>', 'Sprint id')
347
- .requiredOption('--status <value>', 'Target status: todo, doing, completed, done, cancelled, paused, blocked, postponed, in_review'), { destructive: false }).action(async (options) => {
347
+ .requiredOption('--status <value>', 'Target status (canonical: completed; aliases: done, complete; plus todo, doing, cancelled, paused, blocked, postponed, in_review)'), { destructive: false }).action(async (options) => {
348
348
  await runPmSprintSetStatus(options);
349
349
  }));
350
350
  applyPmContextOptions(applyWriteOptions(sprint
@@ -112,6 +112,10 @@ const PM_STATUS_AUDIT_CLASS_DEFINITIONS = [
112
112
  class: 'archived_nonterminal',
113
113
  description: 'Archived board/sprint visibility hides non-terminal work from active surfaces; advisory only, never auto-reconciled.',
114
114
  },
115
+ {
116
+ class: 'review_scope_dangling',
117
+ description: 'Accepted review evidence references a sprint phase or microtask that no longer resolves in the current sprint plan.',
118
+ },
115
119
  {
116
120
  class: 'review_approved_pm_nonterminal',
117
121
  description: 'Optional future cross-check: approved review evidence exists while PM entities remain non-terminal.',
@@ -394,10 +398,11 @@ function unwrapResultData(result) {
394
398
  }
395
399
  function normalizeMicrotaskStatusInput(value) {
396
400
  const normalized = normalizeNonEmpty(value)?.toLowerCase() ?? 'todo';
397
- if (!MICROTASK_STATUSES.has(normalized)) {
398
- throw new Error(`Invalid --status "${value}". Expected one of: todo, doing, blocked, paused, in_review, completed, cancelled, postponed.`);
401
+ const canonical = normalized === 'done' || normalized === 'complete' ? 'completed' : normalized;
402
+ if (!MICROTASK_STATUSES.has(canonical)) {
403
+ throw new Error(`Invalid --status "${value}". Expected one of: todo, doing, blocked, paused, in_review, completed, cancelled, postponed. Completion aliases: done, complete.`);
399
404
  }
400
- return normalized;
405
+ return canonical;
401
406
  }
402
407
  function normalizeKanbanTaskStatusColumnInput(value) {
403
408
  const normalized = normalizeNonEmpty(value)?.toLowerCase();
@@ -1428,19 +1433,21 @@ function incrementAuditClassCount(byClass, className) {
1428
1433
  byClass[className] = (byClass[className] ?? 0) + 1;
1429
1434
  }
1430
1435
  function pushAuditFinding(findings, finding) {
1436
+ const reviewRequestId = normalizeNonEmpty(finding.evidence?.reviewRequestId);
1431
1437
  const taskId = normalizeNonEmpty(finding.task?.id);
1432
1438
  const sprintIds = uniqueStringValues([
1433
1439
  finding.sprint?.id,
1434
1440
  ...(finding.sprints ?? []).map((sprint) => sprint.id),
1435
1441
  ]).join(',');
1436
- const key = `${finding.class}:${taskId ?? ''}:${sprintIds}:${finding.message}`;
1442
+ const key = `${finding.class}:${reviewRequestId ?? ''}:${taskId ?? ''}:${sprintIds}:${finding.message}`;
1437
1443
  const existing = findings.some((entry) => {
1444
+ const entryReviewRequestId = normalizeNonEmpty(entry.evidence?.reviewRequestId);
1438
1445
  const entryTaskId = normalizeNonEmpty(entry.task?.id);
1439
1446
  const entrySprintIds = uniqueStringValues([
1440
1447
  entry.sprint?.id,
1441
1448
  ...(entry.sprints ?? []).map((sprint) => sprint.id),
1442
1449
  ]).join(',');
1443
- return `${entry.class}:${entryTaskId ?? ''}:${entrySprintIds}:${entry.message}` === key;
1450
+ return `${entry.class}:${entryReviewRequestId ?? ''}:${entryTaskId ?? ''}:${entrySprintIds}:${entry.message}` === key;
1444
1451
  });
1445
1452
  if (!existing)
1446
1453
  findings.push(finding);
@@ -1477,7 +1484,7 @@ function pushArchivedNonterminalFinding(findings, params) {
1477
1484
  }),
1478
1485
  });
1479
1486
  }
1480
- function summarizePmStatusAudit(tasks, sprints, columnIndex, filters, nowMs = Date.now()) {
1487
+ function summarizePmStatusAudit(tasks, sprints, reviewRequests, columnIndex, filters, nowMs = Date.now()) {
1481
1488
  const taskSummaries = tasks
1482
1489
  .map((task) => summarizePmStatusTask(task, columnIndex))
1483
1490
  .filter((task) => Boolean(task));
@@ -1716,6 +1723,66 @@ function summarizePmStatusAudit(tasks, sprints, columnIndex, filters, nowMs = Da
1716
1723
  });
1717
1724
  }
1718
1725
  }
1726
+ const phaseIds = new Set();
1727
+ const microtaskIds = new Set();
1728
+ for (const sprint of sprints) {
1729
+ for (const phase of toRecordArray(sprint.phases)) {
1730
+ const phaseId = normalizeNonEmpty(phase.id);
1731
+ if (phaseId)
1732
+ phaseIds.add(phaseId);
1733
+ for (const microtask of toRecordArray(phase.microtasks)) {
1734
+ const microtaskId = normalizeNonEmpty(microtask.id);
1735
+ if (microtaskId)
1736
+ microtaskIds.add(microtaskId);
1737
+ }
1738
+ }
1739
+ }
1740
+ const acceptedReviews = reviewRequests.filter((review) => normalizeAuditToken(review.status) === 'accepted');
1741
+ const scopedAcceptedReviews = acceptedReviews.filter((review) => {
1742
+ const reviewTaskId = normalizeNonEmpty(review.kanbanTaskId);
1743
+ const reviewSprintId = normalizeNonEmpty(review.sprintId);
1744
+ if (filters.board || filters.task) {
1745
+ const matchesSelectedTask = Boolean(reviewTaskId && selectedTaskIds.has(reviewTaskId));
1746
+ const matchesSelectedSprint = Boolean(reviewSprintId && selectedSprintIds.has(reviewSprintId));
1747
+ if (!matchesSelectedTask && !matchesSelectedSprint)
1748
+ return false;
1749
+ }
1750
+ if (filters.sprint && (!reviewSprintId || !selectedSprintIds.has(reviewSprintId)))
1751
+ return false;
1752
+ return true;
1753
+ });
1754
+ let danglingReviewCount = 0;
1755
+ for (const review of scopedAcceptedReviews) {
1756
+ const missingReferences = [];
1757
+ const reviewScope = normalizeNonEmpty(review.reviewScope);
1758
+ const phaseMatch = reviewScope?.match(/^sprint-phase:([0-9a-f-]{36})(?:\/.*)?$/i);
1759
+ const scopedPhaseId = phaseMatch?.[1];
1760
+ if (scopedPhaseId && !phaseIds.has(scopedPhaseId)) {
1761
+ missingReferences.push({ kind: 'phase', id: scopedPhaseId });
1762
+ }
1763
+ const linkedMicrotaskId = normalizeNonEmpty(review.microTaskItemId);
1764
+ if (linkedMicrotaskId && !microtaskIds.has(linkedMicrotaskId)) {
1765
+ missingReferences.push({ kind: 'microtask', id: linkedMicrotaskId });
1766
+ }
1767
+ if (missingReferences.length === 0)
1768
+ continue;
1769
+ danglingReviewCount += 1;
1770
+ pushAuditFinding(findings, {
1771
+ class: 'review_scope_dangling',
1772
+ severity: 'warning',
1773
+ message: 'Accepted review evidence references a phase or microtask that no longer resolves.',
1774
+ suggestion: 'Backfill a deterministic current work-unit reference, or record an explicit irrecoverable historical-scope disposition without inventing identity.',
1775
+ evidence: compactPayload({
1776
+ reviewRequestId: normalizeNonEmpty(review.id),
1777
+ title: normalizeNonEmpty(review.title),
1778
+ status: normalizeNonEmpty(review.status),
1779
+ reviewScope,
1780
+ sprintId: normalizeNonEmpty(review.sprintId),
1781
+ microTaskItemId: linkedMicrotaskId,
1782
+ missingReferences,
1783
+ }),
1784
+ });
1785
+ }
1719
1786
  const byClass = Object.fromEntries(PM_STATUS_AUDIT_CLASS_DEFINITIONS.map((definition) => [definition.class, 0]));
1720
1787
  for (const finding of findings)
1721
1788
  incrementAuditClassCount(byClass, finding.class);
@@ -1727,6 +1794,7 @@ function summarizePmStatusAudit(tasks, sprints, columnIndex, filters, nowMs = Da
1727
1794
  hasFindings: findings.length > 0,
1728
1795
  tasksAudited: selectedTaskIds.size,
1729
1796
  sprintsAudited: selectedSprintIds.size,
1797
+ reviewsAudited: scopedAcceptedReviews.length,
1730
1798
  byClass,
1731
1799
  },
1732
1800
  filters: compactPayload({
@@ -1736,9 +1804,11 @@ function summarizePmStatusAudit(tasks, sprints, columnIndex, filters, nowMs = Da
1736
1804
  }),
1737
1805
  taxonomy: PM_STATUS_AUDIT_CLASS_DEFINITIONS.map((definition) => ({ ...definition })),
1738
1806
  reviewAudit: {
1739
- enabled: false,
1740
- class: 'review_approved_pm_nonterminal',
1741
- reason: 'Slice 1 audits PM task/sprint entities only; review-result correlation is reserved for a later explicit read path.',
1807
+ enabled: true,
1808
+ class: 'review_scope_dangling',
1809
+ reviewsAudited: scopedAcceptedReviews.length,
1810
+ danglingReviewCount,
1811
+ acceptedOnly: true,
1742
1812
  },
1743
1813
  findings,
1744
1814
  };
@@ -2226,21 +2296,45 @@ async function resolveBoardColumnReference(execution, options, params) {
2226
2296
  if (!trimmed) {
2227
2297
  throw new Error('Column is required.');
2228
2298
  }
2229
- if (isUuidLike(trimmed)) {
2230
- return { input: trimmed, id: trimmed };
2231
- }
2232
2299
  if (!params.boardId) {
2300
+ if (isUuidLike(trimmed)) {
2301
+ return { input: trimmed, id: trimmed };
2302
+ }
2233
2303
  throw new Error('Board is required when resolving a column by exact name.');
2234
2304
  }
2235
2305
  const boardColumnsPayload = await invokeProjectmanReadTool(execution, options, {
2236
2306
  toolId: 'projectman.kanban-board-column.list',
2237
2307
  input: { board: params.boardId },
2238
2308
  });
2309
+ const boardColumns = toRecordArray(unwrapHostedToolResult(boardColumnsPayload));
2310
+ if (isUuidLike(trimmed)) {
2311
+ const placementMatches = boardColumns.filter((placement) => extractEntityId(placement, ['id', 'boardColumnId']) === trimmed);
2312
+ if (placementMatches.length === 1) {
2313
+ return { input: trimmed, id: trimmed };
2314
+ }
2315
+ if (placementMatches.length > 1) {
2316
+ throw new Error(`Column placement id "${trimmed}" is ambiguous on the selected board.`);
2317
+ }
2318
+ const libraryColumnMatches = boardColumns.filter((placement) => extractEntityId(placement, ['columnId', 'column']) === trimmed);
2319
+ if (libraryColumnMatches.length === 1) {
2320
+ const placementId = extractEntityId(libraryColumnMatches[0], ['id', 'boardColumnId']);
2321
+ if (!placementId) {
2322
+ throw new Error(`Library column "${trimmed}" matched a board placement without an id.`);
2323
+ }
2324
+ return { input: trimmed, id: placementId, assumedId: false };
2325
+ }
2326
+ if (libraryColumnMatches.length > 1) {
2327
+ const candidates = libraryColumnMatches
2328
+ .map((placement) => extractEntityId(placement, ['id', 'boardColumnId']) ?? 'missing-id')
2329
+ .join(', ');
2330
+ throw new Error(`Library column "${trimmed}" is ambiguous on the selected board. Placements: ${candidates}.`);
2331
+ }
2332
+ return { input: trimmed, id: trimmed, assumedId: true };
2333
+ }
2239
2334
  const columnLibraryPayload = await invokeProjectmanReadTool(execution, options, {
2240
2335
  toolId: 'projectman.kanban-column.list',
2241
2336
  input: trimmed.includes(' ') ? { name: trimmed } : { slug: trimmed },
2242
2337
  });
2243
- const boardColumns = toRecordArray(unwrapHostedToolResult(boardColumnsPayload));
2244
2338
  const enrichedBoardColumns = await Promise.all(boardColumns.map(async (placement) => {
2245
2339
  const columnId = extractEntityId(placement, ['columnId', 'column']);
2246
2340
  if (!columnId) {
@@ -3863,6 +3957,7 @@ export async function runPmStatusAudit(options = {}) {
3863
3957
  return;
3864
3958
  const taskInput = buildOwnerScopedInput(execution.resolvedContext);
3865
3959
  const sprintInput = buildOwnerScopedInput(execution.resolvedContext);
3960
+ const reviewInput = buildOwnerScopedInput(execution.resolvedContext);
3866
3961
  const boardValue = normalizeNonEmpty(options.board);
3867
3962
  const taskSelector = normalizeNonEmpty(options.task);
3868
3963
  const sprintSelector = normalizeNonEmpty(options.sprint);
@@ -3870,7 +3965,7 @@ export async function runPmStatusAudit(options = {}) {
3870
3965
  if (boardValue) {
3871
3966
  boardRef = await resolveBoardReference(execution, options, boardValue);
3872
3967
  }
3873
- const [taskPayload, sprintPayload, boards] = await Promise.all([
3968
+ const [taskPayload, sprintPayload, reviewPayload, boards] = await Promise.all([
3874
3969
  invokeProjectmanReadTool(execution, options, {
3875
3970
  toolId: 'projectman.kanban-task.list',
3876
3971
  input: taskInput,
@@ -3879,6 +3974,10 @@ export async function runPmStatusAudit(options = {}) {
3879
3974
  toolId: 'projectman.sprint.list',
3880
3975
  input: sprintInput,
3881
3976
  }),
3977
+ invokeProjectmanReadTool(execution, options, {
3978
+ toolId: 'projectman.review-request.list',
3979
+ input: reviewInput,
3980
+ }),
3882
3981
  listProjectmanBoards(execution, options, { includeArchived: true }),
3883
3982
  ]);
3884
3983
  const columnSourceBoardIds = boardRef
@@ -3911,8 +4010,9 @@ export async function runPmStatusAudit(options = {}) {
3911
4010
  }
3912
4011
  const tasks = toRecordArray(unwrapHostedToolResult(taskPayload));
3913
4012
  const sprints = toRecordArray(unwrapHostedToolResult(sprintPayload));
4013
+ const reviewRequests = toRecordArray(unwrapHostedToolResult(reviewPayload));
3914
4014
  const columnIndex = buildPmStatusAuditColumnIndex(boards, boardColumnRows, columnEntities);
3915
- const audit = summarizePmStatusAudit(tasks, sprints, columnIndex, {
4015
+ const audit = summarizePmStatusAudit(tasks, sprints, reviewRequests, columnIndex, {
3916
4016
  board: boardValue,
3917
4017
  boardId: boardRef?.id,
3918
4018
  task: taskSelector,
@@ -3933,6 +4033,7 @@ export async function runPmStatusAudit(options = {}) {
3933
4033
  input: compactPayload({
3934
4034
  taskInput,
3935
4035
  sprintInput,
4036
+ reviewInput,
3936
4037
  filters: compactPayload({
3937
4038
  board: boardValue,
3938
4039
  task: taskSelector,
@@ -4213,11 +4314,7 @@ export async function runPmSprintSetStatus(options = {}) {
4213
4314
  const targetStatus = normalizeNonEmpty(options.status)?.toLowerCase();
4214
4315
  if (!targetStatus)
4215
4316
  throw new Error('Missing required --status.');
4216
- const validStatuses = new Set(['todo', 'doing', 'blocked', 'paused', 'in_review', 'completed', 'cancelled', 'postponed', 'done']);
4217
- const resolvedStatus = targetStatus === 'done' || targetStatus === 'complete' ? 'completed' : targetStatus;
4218
- if (!validStatuses.has(targetStatus)) {
4219
- throw new Error(`Invalid --status "${targetStatus}". Expected one of: ${[...validStatuses].join(', ')}.`);
4220
- }
4317
+ const resolvedStatus = normalizeMicrotaskStatusInput(targetStatus);
4221
4318
  const execution = await prepareExecution(options, { requireProject: false });
4222
4319
  if (!execution)
4223
4320
  return;
@@ -543,9 +543,9 @@ function defaultNativeRoot() {
543
543
  return moduleDirectory.endsWith(`${path.sep}dist`) ? bundled : compiledOrSource;
544
544
  }
545
545
  function injectedNativeManifestSha256() {
546
- return typeof "1ffbe15b7e7471f9cb11b2b122b5e39117a6bc9e2765c4d84c219b8f30a3f2f1" === 'undefined'
546
+ return typeof "b4889fff291b2df3cd1bb9ba21435af679cccc033caf454af2205d908ca47c28" === 'undefined'
547
547
  ? undefined
548
- : "1ffbe15b7e7471f9cb11b2b122b5e39117a6bc9e2765c4d84c219b8f30a3f2f1";
548
+ : "b4889fff291b2df3cd1bb9ba21435af679cccc033caf454af2205d908ca47c28";
549
549
  }
550
550
  function sha256(bytes) {
551
551
  return createHash('sha256').update(bytes).digest('hex');
@@ -1,6 +1,38 @@
1
1
  function messageOf(error) {
2
2
  return error instanceof Error ? error.message : String(error);
3
3
  }
4
+ const MEMBER_AUTH_REASONS = new Set([
5
+ 'member_token_required',
6
+ 'member_token_invalid_format',
7
+ 'member_token_unknown',
8
+ 'member_token_mismatch',
9
+ 'membership_inactive',
10
+ 'membership_channel_mismatch',
11
+ ]);
12
+ function record(value) {
13
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
14
+ }
15
+ export function buildCliJsonError(error) {
16
+ const candidate = record(error) ? error : null;
17
+ const details = record(candidate?.details) ? candidate.details : null;
18
+ const memberAuthReason = details?.memberAuthReason;
19
+ const errorCode = typeof candidate?.errorCode === 'string'
20
+ ? candidate.errorCode
21
+ : typeof candidate?.code === 'string'
22
+ ? candidate.code
23
+ : undefined;
24
+ return {
25
+ schemaVersion: 1,
26
+ ok: false,
27
+ error: {
28
+ message: messageOf(error),
29
+ ...(errorCode ? { errorCode } : {}),
30
+ ...(typeof memberAuthReason === 'string' && MEMBER_AUTH_REASONS.has(memberAuthReason)
31
+ ? { details: { memberAuthReason } }
32
+ : {}),
33
+ },
34
+ };
35
+ }
4
36
  export function formatCliError(error, depth = 0) {
5
37
  const message = messageOf(error);
6
38
  if (!(error instanceof AggregateError) || error.errors.length === 0 || depth >= 3)
@@ -36,7 +36,7 @@ function categoryFor(code) {
36
36
  return 'migration';
37
37
  if (/config|policy|env|tls/.test(code))
38
38
  return 'configuration';
39
- if (/runtime|server|process|health|source_drift|build(?:_identity)?_drift/.test(code))
39
+ if (/runtime|server|process|health|native_child|source_drift|build(?:_identity)?_drift/.test(code))
40
40
  return 'runtime';
41
41
  return 'unknown';
42
42
  }
@@ -57,7 +57,7 @@ function inferredPhase(code, fallback) {
57
57
  return 'verify';
58
58
  if (/migration|apply/.test(code))
59
59
  return 'apply';
60
- if (/start|health|process/.test(code))
60
+ if (/start|health|process|native_child.*(?:exited|ready)/.test(code))
61
61
  return 'start-server';
62
62
  return fallback;
63
63
  }
@@ -123,6 +123,13 @@ function safeDetails(details, error) {
123
123
  if (SAFE_SQLSTATE.test(sqlState))
124
124
  output.sqlState = sqlState;
125
125
  const message = error instanceof Error ? error.message : String(error ?? '');
126
+ const nativeChildExit = /^community_native_child_exited_before_ready:([^:\s]+):([^:\s]+)/u.exec(message);
127
+ if (nativeChildExit) {
128
+ output.nativeChildExitCode = /^\d+$/u.test(nativeChildExit[1])
129
+ ? Number(nativeChildExit[1])
130
+ : redacted(nativeChildExit[1]);
131
+ output.nativeChildSignal = redacted(nativeChildExit[2]);
132
+ }
126
133
  const semanticPrefix = 'community_strict_semantic_schema_mismatch:';
127
134
  if (message.startsWith(semanticPrefix)) {
128
135
  try {
package/dist/main.js CHANGED
@@ -37,11 +37,12 @@ import { makeCommunityCockpitCommand } from './commands/community-cockpit.js';
37
37
  import { makeCommunityDoctorCommand } from './commands/community-doctor.js';
38
38
  import { makeTargetCommand } from './commands/target.js';
39
39
  import { makeVersionCommand } from './commands/version.js';
40
+ import { makeCodexCommand } from './commands/codex.js';
40
41
  import { makeGlobalUpdateCommand } from './commands/global-update.js';
41
42
  import { launchBundledTui, shouldLaunchBundledTui } from './lib/tui-launcher.js';
42
43
  import { CommunityDiagnosticError, formatCommunityDiagnostic, } from './lib/community-diagnostic.js';
43
44
  import { resolveCliApiBaseUrl } from './utils/api.js';
44
- import { formatCliError } from './lib/cli-error-format.js';
45
+ import { buildCliJsonError, formatCliError } from './lib/cli-error-format.js';
45
46
  const KERNEL_COMMANDS_REPLACED_BY_AOPS = new Set(['agent', 'api', 'auth', 'client', 'host']);
46
47
  function removeReplacedKernelCommands(program) {
47
48
  const mutable = program;
@@ -154,6 +155,7 @@ export function buildCommunityProgram() {
154
155
  program.addCommand(makeCommunityDoctorCommand());
155
156
  program.addCommand(makeTargetCommand());
156
157
  program.addCommand(makeVersionCommand());
158
+ program.addCommand(makeCodexCommand());
157
159
  program.addCommand(makeGlobalUpdateCommand());
158
160
  program.addHelpText('after', `
159
161
  AOPS Community is a single-user, self-hosted/local-trusted distribution.
@@ -205,7 +207,12 @@ async function main() {
205
207
  }
206
208
  }
207
209
  else {
208
- logError(formatCliError(error));
210
+ if (jsonOutputRequested) {
211
+ process.stderr.write(`${JSON.stringify(buildCliJsonError(error))}\n`);
212
+ }
213
+ else {
214
+ logError(formatCliError(error));
215
+ }
209
216
  }
210
217
  process.exitCode = 1;
211
218
  }
@@ -42,7 +42,7 @@
42
42
  "capabilityClass": "windows-ntfs-crash-recoverable-v1",
43
43
  "qualification": {
44
44
  "relativePath": "qualifications/win32-x64.json",
45
- "sha256": "3ba56b89ad82cba1d2005dc0dda0724cd08395cd40af00a3ed4709c5e63b8938"
45
+ "sha256": "8d24367d437618962c3a832af4d3c20742b15cc0ac83802435ee3e01a0f8a16b"
46
46
  }
47
47
  }
48
48
  ]
@@ -7,7 +7,7 @@
7
7
  "filesystem": "NTFS",
8
8
  "primitiveProfile": "windows-createfile-flush-movefileex-v1",
9
9
  "capabilityClass": "windows-ntfs-crash-recoverable-v1",
10
- "evidenceSha256": "138d0d5bdd55ac851084a02e829e0b2f4d66ac03cee92ea28da4dcce2f802eab",
10
+ "evidenceSha256": "f00aecbd6e059cc80440e99411103f7a3dc0fd66fd3faf6522d34c9d9f15dad0",
11
11
  "crashInjectionPoints": [
12
12
  "authority-history",
13
13
  "authority-current",
Binary file
Binary file
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@aopslabs/aops",
3
- "version": "0.3.20",
3
+ "version": "0.3.21",
4
4
  "type": "module",
5
5
  "description": "AOPS CLI and terminal setup application.",
6
- "aopsDockerServerVersion": "0.2.15",
6
+ "aopsDockerServerVersion": "0.2.16",
7
7
  "license": "SEE LICENSE IN LICENSE",
8
8
  "repository": {
9
9
  "type": "git",
@@ -34,6 +34,7 @@
34
34
  "test:chatv3-keyring-parameter-log-effects": "node --test test/chatv3-keyring-parameter-log-effects.test.mjs",
35
35
  "test:chatv3-session-store": "node --test test/chatv3-session-store.test.mjs",
36
36
  "test:projectman-review-evidence": "node --test test/projectman-review-evidence.test.mjs",
37
+ "test:projectman-pm-contract": "node --test test/projectman-pm-contract.test.mjs",
37
38
  "test:commercial-lifecycle-scale-effects": "node --test test/commercial-lifecycle-scale-effects.test.mjs",
38
39
  "test:commercial-lifecycle-managed-effects": "node --test test/commercial-lifecycle-managed-effects.test.mjs",
39
40
  "test:commercial-lifecycle-negative-effects": "node --test test/commercial-lifecycle-negative-effects.test.mjs",
@@ -55,12 +56,13 @@
55
56
  "test:hosted-contract-hardening": "node --test test/hosted-contract-hardening.test.mjs",
56
57
  "test:home": "node --test test/home-menu.test.mjs",
57
58
  "test:launchers": "node --test test/terminal-launchers.test.mjs",
58
- "test:shortcuts": "pnpm --dir ../.. run build && pnpm run test:home && pnpm run test:cockpit && pnpm run test:launchers && pnpm run test:assets-menu && pnpm run test:agent-assets-content && pnpm run test:chatv3-session-store && pnpm run test:projectman-review-evidence && pnpm run test:setup-install && pnpm run test:container-runtime && pnpm run test:native-lifecycle && pnpm run test:operation-journal && pnpm run test:commercial-canonical-order && pnpm run test:commercial-runtime-closure && pnpm run test:commercial-artifact && pnpm run test:commercial-final-readiness && pnpm run test:commercial-admission && pnpm run test:commercial-license && pnpm run test:commercial-runbook && pnpm run test:package-identity && pnpm run test:tui-launcher && pnpm run test:global-update && pnpm run test:skill-discovery && pnpm run test:target-transport && pnpm run test:target-auth && pnpm run test:r6-auth-cutover && pnpm run test:r6-cutover-baseline && pnpm run test:hosted-contract-hardening",
59
+ "test:shortcuts": "pnpm --dir ../.. run build && pnpm run test:home && pnpm run test:cockpit && pnpm run test:launchers && pnpm run test:assets-menu && pnpm run test:agent-assets-content && pnpm run test:chatv3-session-store && pnpm run test:projectman-review-evidence && pnpm run test:projectman-pm-contract && pnpm run test:setup-install && pnpm run test:container-runtime && pnpm run test:native-lifecycle && pnpm run test:operation-journal && pnpm run test:commercial-canonical-order && pnpm run test:commercial-runtime-closure && pnpm run test:commercial-artifact && pnpm run test:commercial-final-readiness && pnpm run test:commercial-admission && pnpm run test:commercial-license && pnpm run test:commercial-runbook && pnpm run test:package-identity && pnpm run test:tui-launcher && pnpm run test:global-update && pnpm run test:skill-discovery && pnpm run test:target-transport && pnpm run test:target-auth && pnpm run test:r6-auth-cutover && pnpm run test:r6-cutover-baseline && pnpm run test:hosted-contract-hardening",
59
60
  "typecheck": "tsc -p tsconfig.json --noEmit",
60
61
  "start": "node dist/main.js"
61
62
  },
62
63
  "dependencies": {
63
- "@aopslabs/aops-server": "0.2.15",
64
+ "@aopslabs/aops-agent-runtime": "0.1.0",
65
+ "@aopslabs/aops-server": "0.2.16",
64
66
  "@aopslabs/artifact-trust-contracts": "0.3.1",
65
67
  "@aopslabs/cli-kit": "0.1.0",
66
68
  "@aopslabs/aops-host-registration": "0.2.1",
@@ -71,7 +73,7 @@
71
73
  "@sigstore/tuf": "4.0.2",
72
74
  "@sigstore/verify": "3.1.1",
73
75
  "@aopslabs/api-client": "0.2.1",
74
- "@aopslabs/domain-product-client-chatv3": "0.4.0",
76
+ "@aopslabs/domain-product-client-chatv3": "0.4.1",
75
77
  "@aopslabs/xf-cli-ui": "0.2.0",
76
78
  "commander": "14.0.3",
77
79
  "pg": "8.20.0",