@jaimevalasek/aioson 1.36.0 → 1.37.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 (105) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/docs/en/1-understand/ecosystem-map.md +1 -1
  3. package/docs/en/1-understand/glossary.md +1 -1
  4. package/docs/en/2-start/first-project.md +1 -1
  5. package/docs/en/2-start/initial-decisions.md +4 -2
  6. package/docs/en/3-recipes/from-idea-to-prd-via-briefing.md +8 -1
  7. package/docs/en/3-recipes/full-feature-with-sheldon.md +3 -1
  8. package/docs/en/4-agents/README.md +6 -3
  9. package/docs/en/4-agents/briefing-refiner.md +146 -0
  10. package/docs/en/5-reference/README.md +1 -0
  11. package/docs/en/5-reference/autopilot-handoff.md +286 -0
  12. package/docs/en/5-reference/cli-reference.md +6 -0
  13. package/docs/pt/1-entender/glossario.md +1 -1
  14. package/docs/pt/1-entender/mapa-do-ecossistema.md +1 -1
  15. package/docs/pt/2-comecar/decisoes-iniciais.md +4 -2
  16. package/docs/pt/2-comecar/primeiro-projeto.md +1 -1
  17. package/docs/pt/3-receitas/da-ideia-ao-prd-via-briefing.md +8 -1
  18. package/docs/pt/3-receitas/feature-completa-com-sheldon.md +3 -1
  19. package/docs/pt/4-agentes/README.md +13 -11
  20. package/docs/pt/4-agentes/briefing-refiner.md +64 -40
  21. package/docs/pt/4-agentes/briefing.md +6 -1
  22. package/docs/pt/4-agentes/dev.md +19 -1
  23. package/docs/pt/4-agentes/deyvin.md +4 -0
  24. package/docs/pt/4-agentes/discover.md +4 -0
  25. package/docs/pt/4-agentes/neo.md +4 -0
  26. package/docs/pt/4-agentes/orache.md +6 -0
  27. package/docs/pt/4-agentes/orchestrator.md +12 -0
  28. package/docs/pt/4-agentes/pentester.md +6 -0
  29. package/docs/pt/4-agentes/product.md +19 -1
  30. package/docs/pt/4-agentes/qa.md +10 -2
  31. package/docs/pt/4-agentes/setup.md +3 -1
  32. package/docs/pt/4-agentes/sheldon.md +12 -0
  33. package/docs/pt/4-agentes/tester.md +6 -0
  34. package/docs/pt/4-agentes/ux-ui.md +2 -1
  35. package/docs/pt/5-referencia/README.md +1 -1
  36. package/docs/pt/5-referencia/agent-chain-continuity.md +1 -1
  37. package/docs/pt/5-referencia/autopilot-handoff.md +191 -74
  38. package/docs/pt/5-referencia/comandos-cli.md +16 -7
  39. package/docs/pt/5-referencia/skills.md +2 -0
  40. package/docs/pt/agentes.md +3 -1
  41. package/package.json +1 -1
  42. package/src/agent-execution/adapters/base.js +15 -0
  43. package/src/agent-execution/adapters/claude.js +3 -0
  44. package/src/agent-execution/adapters/codex.js +3 -0
  45. package/src/agent-execution/adapters/opencode.js +3 -0
  46. package/src/agent-execution/capabilities.js +9 -0
  47. package/src/agent-execution/dispatcher.js +72 -0
  48. package/src/agent-execution/executable-resolver.js +7 -0
  49. package/src/agent-execution/manifest.js +62 -0
  50. package/src/agent-execution/model-catalog.js +80 -0
  51. package/src/agent-execution/model-resolver.js +132 -0
  52. package/src/agent-execution/reports.js +9 -0
  53. package/src/agent-execution/schema.js +48 -0
  54. package/src/agent-execution/telemetry-bridge.js +15 -0
  55. package/src/agents.js +1 -1
  56. package/src/artifact-kinds.js +2 -1
  57. package/src/autopilot-signal.js +71 -0
  58. package/src/cli.js +31 -5
  59. package/src/commands/agent-execution.js +36 -0
  60. package/src/commands/agents.js +18 -2
  61. package/src/commands/briefing.js +337 -1
  62. package/src/commands/feature-close.js +136 -43
  63. package/src/commands/live.js +47 -11
  64. package/src/commands/op-capture.js +33 -3
  65. package/src/commands/op-reinforce.js +10 -22
  66. package/src/commands/update.js +5 -1
  67. package/src/commands/verification-plan.js +56 -12
  68. package/src/commands/verify-artifact.js +64 -1
  69. package/src/commands/workflow-execute.js +168 -36
  70. package/src/commands/workflow-next.js +60 -16
  71. package/src/doctor.js +4 -2
  72. package/src/harness/criteria-runner.js +4 -1
  73. package/src/i18n/messages/en.js +2 -1
  74. package/src/i18n/messages/es.js +2 -1
  75. package/src/i18n/messages/fr.js +2 -1
  76. package/src/i18n/messages/pt-BR.js +2 -1
  77. package/src/lib/briefing-refiner/apply-feedback.js +18 -4
  78. package/src/lib/briefing-refiner/feedback-schema.js +73 -4
  79. package/src/lib/briefing-refiner/refinement-report.js +11 -0
  80. package/src/lib/briefing-refiner/review-html.js +388 -68
  81. package/src/operator-memory/decision.js +41 -0
  82. package/src/parser.js +6 -0
  83. package/src/runtime-store.js +167 -8
  84. package/template/.aioson/agents/briefing-refiner.md +87 -47
  85. package/template/.aioson/agents/briefing.md +4 -0
  86. package/template/.aioson/agents/dev.md +9 -2
  87. package/template/.aioson/agents/deyvin.md +4 -0
  88. package/template/.aioson/agents/discover.md +4 -0
  89. package/template/.aioson/agents/neo.md +4 -0
  90. package/template/.aioson/agents/orache.md +4 -0
  91. package/template/.aioson/agents/orchestrator.md +16 -0
  92. package/template/.aioson/agents/pentester.md +4 -0
  93. package/template/.aioson/agents/product.md +26 -1
  94. package/template/.aioson/agents/qa.md +5 -1
  95. package/template/.aioson/agents/sheldon.md +9 -1
  96. package/template/.aioson/agents/tester.md +4 -0
  97. package/template/.aioson/agents/ux-ui.md +1 -1
  98. package/template/.aioson/docs/agent-help.md +126 -0
  99. package/template/.aioson/docs/autopilot-handoff.md +32 -16
  100. package/template/.aioson/docs/dev/phase-loop.md +9 -7
  101. package/template/.aioson/docs/play/llm-data-and-bindings.md +70 -7
  102. package/template/.aioson/schemas/agent-execution.schema.json +28 -0
  103. package/template/.aioson/skills/design/interface-design/SKILL.md +17 -0
  104. package/template/AGENTS.md +36 -36
  105. package/template/CLAUDE.md +1 -1
@@ -7,6 +7,12 @@ const VALID_SECTION_STATUSES = new Set(['unchanged', 'accepted', 'change_request
7
7
  const VALID_DECISION_STATUSES = new Set(['accepted', 'change_requested', 'remove', 'blocked', 'note']);
8
8
  const VALID_SEVERITIES = new Set(['note', 'suggestion', 'important', 'blocking']);
9
9
  const VALID_EXPORT_METHODS = new Set(['file-system-access', 'download', 'copy-paste', 'manual-save']);
10
+ const VALID_FINDING_CATEGORIES = new Set(['ambiguity', 'redundancy', 'gap', 'risk', 'pending-decision', 'scope-suggestion']);
11
+ const VALID_FINDING_SEVERITIES = new Set(['low', 'medium', 'high']);
12
+ const VALID_FINDING_STATUSES = new Set(['pending', 'accepted', 'rejected', 'deferred']);
13
+ // 1.0 = sections/comments/decisions/blocking_items only; 1.1 adds findings[] (the
14
+ // agent's audit surfaced as reviewable items) and the refinement round counter.
15
+ const SUPPORTED_SCHEMA_VERSIONS = new Set(['1.0', '1.1']);
10
16
 
11
17
  // Normalization only — NOT a security boundary. This strips well-formed tags
12
18
  // and normalizes newlines so the text round-trips cleanly into briefings.md.
@@ -34,17 +40,64 @@ function normalizeSection(section) {
34
40
  };
35
41
  }
36
42
 
37
- function buildInitialFeedback({ slug, sourcePath, sourceHash, sections, exportMethod = 'manual-save', now = new Date() }) {
43
+ function normalizeFinding(finding, index) {
44
+ return {
45
+ id: String(finding.id || `F${index + 1}`),
46
+ section_id: String(finding.section_id || ''),
47
+ category: VALID_FINDING_CATEGORIES.has(finding.category) ? finding.category : 'gap',
48
+ severity: VALID_FINDING_SEVERITIES.has(finding.severity) ? finding.severity : 'medium',
49
+ blocking: Boolean(finding.blocking),
50
+ text: sanitizeText(finding.text),
51
+ recommendation: sanitizeText(finding.recommendation || ''),
52
+ status: VALID_FINDING_STATUSES.has(finding.status) ? finding.status : 'pending',
53
+ note: sanitizeText(finding.note || '')
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Validate agent-supplied audit findings BEFORE they are baked into the review
59
+ * surface. Strict where normalizeFinding is lenient: the agent must name a real
60
+ * section and a valid category, and every finding must carry text.
61
+ */
62
+ function validateFindingsInput(findings, { sectionIds = [] } = {}) {
63
+ const errors = [];
64
+ if (!Array.isArray(findings)) {
65
+ return { ok: false, errors: ['findings must be an array'] };
66
+ }
67
+ const known = new Set(sectionIds);
68
+ findings.forEach((finding, index) => {
69
+ const label = finding && finding.id ? String(finding.id) : `#${index + 1}`;
70
+ if (!finding || typeof finding !== 'object') {
71
+ errors.push(`finding ${label} must be an object`);
72
+ return;
73
+ }
74
+ if (!String(finding.text || '').trim()) errors.push(`finding ${label} has no text`);
75
+ if (!VALID_FINDING_CATEGORIES.has(finding.category)) {
76
+ errors.push(`finding ${label} has invalid category: ${finding.category}`);
77
+ }
78
+ if (finding.severity !== undefined && !VALID_FINDING_SEVERITIES.has(finding.severity)) {
79
+ errors.push(`finding ${label} has invalid severity: ${finding.severity}`);
80
+ }
81
+ if (known.size > 0 && !known.has(String(finding.section_id || ''))) {
82
+ errors.push(`finding ${label} points at unknown section_id: ${finding.section_id}`);
83
+ }
84
+ });
85
+ return { ok: errors.length === 0, errors };
86
+ }
87
+
88
+ function buildInitialFeedback({ slug, sourcePath, sourceHash, sections, findings = [], round = 1, exportMethod = 'manual-save', now = new Date() }) {
38
89
  const timestamp = now.toISOString();
39
90
  return {
40
- schema_version: '1.0',
91
+ schema_version: '1.1',
41
92
  briefing_slug: slug,
42
93
  source_briefing_path: sourcePath,
43
94
  source_hash: sourceHash,
44
95
  review_generated_at: timestamp,
45
96
  last_modified_at: timestamp,
46
97
  export_method: exportMethod,
98
+ round: Number.isInteger(round) && round > 0 ? round : 1,
47
99
  sections: sections.map(normalizeSection),
100
+ findings: findings.map(normalizeFinding),
48
101
  comments: [],
49
102
  decisions: [],
50
103
  blocking_items: []
@@ -66,7 +119,7 @@ function validateFeedback(feedback, { slug, currentSourceHash, allowStale = fals
66
119
  if (!feedback || typeof feedback !== 'object') errors.push('feedback must be an object');
67
120
  if (errors.length > 0) return { ok: false, stale: false, errors, warnings };
68
121
 
69
- if (feedback.schema_version !== '1.0') errors.push('schema_version must be 1.0');
122
+ if (!SUPPORTED_SCHEMA_VERSIONS.has(feedback.schema_version)) errors.push('schema_version must be 1.0 or 1.1');
70
123
  if (slug && feedback.briefing_slug !== slug) errors.push('briefing_slug does not match selected slug');
71
124
  if (!isPathInsideBriefing(feedback.source_briefing_path, feedback.briefing_slug || slug)) {
72
125
  errors.push('source_briefing_path must stay inside the selected briefing directory');
@@ -99,6 +152,17 @@ function validateFeedback(feedback, { slug, currentSourceHash, allowStale = fals
99
152
  }
100
153
  }
101
154
 
155
+ // findings[] is a 1.1 field; a 1.0 payload legitimately has none.
156
+ if (feedback.schema_version === '1.1' && !Array.isArray(feedback.findings)) {
157
+ errors.push('findings must be an array');
158
+ }
159
+ if (Array.isArray(feedback.findings)) {
160
+ for (const finding of feedback.findings) {
161
+ if (!VALID_FINDING_STATUSES.has(finding.status)) errors.push(`invalid finding status: ${finding.status}`);
162
+ if (!VALID_FINDING_CATEGORIES.has(finding.category)) errors.push(`invalid finding category: ${finding.category}`);
163
+ }
164
+ }
165
+
102
166
  const stale = Boolean(currentSourceHash && feedback.source_hash !== currentSourceHash);
103
167
  if (stale) warnings.push('source_hash differs from current briefings.md');
104
168
  if (stale && !allowStale) errors.push('feedback is stale');
@@ -116,7 +180,12 @@ function assertFeedbackPath(projectDir, slug, candidatePath) {
116
180
 
117
181
  module.exports = {
118
182
  buildInitialFeedback,
183
+ normalizeFinding,
119
184
  sanitizeText,
120
185
  validateFeedback,
121
- assertFeedbackPath
186
+ validateFindingsInput,
187
+ assertFeedbackPath,
188
+ VALID_FINDING_CATEGORIES,
189
+ VALID_FINDING_SEVERITIES,
190
+ VALID_FINDING_STATUSES
122
191
  };
@@ -7,6 +7,15 @@ function list(items, formatter) {
7
7
 
8
8
  function buildRefinementReport(data) {
9
9
  const nextAction = data.next_action || 'rerun_review';
10
+ const findings = Array.isArray(data.findings) ? data.findings : [];
11
+ const findingsBlock = findings.length > 0
12
+ ? [
13
+ '## Findings',
14
+ '',
15
+ list(findings, (finding) => `${finding.id} [${finding.category}/${finding.severity}${finding.blocking ? '/blocking' : ''}] (${finding.status}) ${finding.section_id}: ${finding.text}`),
16
+ ''
17
+ ]
18
+ : [];
10
19
  return [
11
20
  `# Refinement Report — ${data.briefing_slug}`,
12
21
  '',
@@ -15,8 +24,10 @@ function buildRefinementReport(data) {
15
24
  `- Source hash: ${data.source_hash || '-'}`,
16
25
  `- Applied hash: ${data.applied_hash || '-'}`,
17
26
  `- Status: ${data.status || 'review_generated'}`,
27
+ `- Round: ${data.round || 1}`,
18
28
  `- Next action: ${nextAction}`,
19
29
  '',
30
+ ...findingsBlock,
20
31
  '## Applied Changes',
21
32
  '',
22
33
  list(data.applied_changes, (change) => `${change.section_id || change.title}: ${change.summary || 'updated'}`),