@jaimevalasek/aioson 1.30.2 → 1.36.0
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.
- package/CHANGELOG.md +75 -0
- package/README.md +19 -6
- package/docs/en/1-understand/ecosystem-map.md +45 -29
- package/docs/en/1-understand/glossary.md +5 -5
- package/docs/en/1-understand/what-is-aioson.md +5 -5
- package/docs/en/2-start/existing-project.md +7 -7
- package/docs/en/2-start/first-project.md +32 -38
- package/docs/en/2-start/initial-decisions.md +18 -17
- package/docs/en/3-recipes/README.md +2 -2
- package/docs/en/3-recipes/continuity-between-sessions.md +2 -2
- package/docs/en/3-recipes/from-idea-to-prd-via-briefing.md +5 -2
- package/docs/en/3-recipes/full-feature-with-sheldon.md +327 -338
- package/docs/en/4-agents/README.md +28 -14
- package/docs/en/4-agents/discovery-design-doc.md +20 -8
- package/docs/en/4-agents/forge-run.md +3 -2
- package/docs/en/5-reference/cli-reference.md +51 -48
- package/docs/en/5-reference/executable-verification.md +10 -7
- package/docs/en/5-reference/parallel.md +2 -0
- package/docs/en/5-reference/qa-browser.md +2 -2
- package/docs/en/README.md +3 -3
- package/docs/pt/1-entender/glossario.md +4 -4
- package/docs/pt/1-entender/mapa-do-ecossistema.md +32 -21
- package/docs/pt/2-comecar/decisoes-iniciais.md +16 -16
- package/docs/pt/2-comecar/primeiro-projeto.md +1 -1
- package/docs/pt/3-receitas/README.md +1 -1
- package/docs/pt/3-receitas/app-saas-do-zero.md +35 -122
- package/docs/pt/3-receitas/feature-completa-com-sheldon.md +289 -338
- package/docs/pt/4-agentes/analyst.md +9 -5
- package/docs/pt/4-agentes/architect.md +9 -5
- package/docs/pt/4-agentes/dev.md +19 -7
- package/docs/pt/4-agentes/discovery-design-doc.md +25 -23
- package/docs/pt/4-agentes/orchestrator.md +164 -118
- package/docs/pt/4-agentes/pentester.md +5 -5
- package/docs/pt/4-agentes/pm.md +15 -7
- package/docs/pt/4-agentes/sheldon.md +166 -99
- package/docs/pt/4-agentes/ux-ui.md +7 -4
- package/docs/pt/5-referencia/agent-chain-continuity.md +14 -5
- package/docs/pt/5-referencia/comandos-cli.md +1 -1
- package/docs/pt/5-referencia/harness-retro.md +2 -1
- package/docs/pt/5-referencia/sdd-automation-scripts.md +6 -6
- package/docs/pt/5-referencia/sdd-framework.md +53 -16
- package/docs/pt/5-referencia/sdd-planos-e-estrutura.md +27 -15
- package/docs/pt/README.md +4 -4
- package/docs/pt/agentes.md +48 -50
- package/package.json +2 -2
- package/src/artifact-kinds.js +110 -0
- package/src/cli.js +82 -42
- package/src/commands/agent-epilogue.js +251 -186
- package/src/commands/agents.js +104 -48
- package/src/commands/audit-code.js +344 -0
- package/src/commands/classify.js +75 -13
- package/src/commands/feature-close.js +43 -18
- package/src/commands/harness-check.js +259 -175
- package/src/commands/harness-retro-promote.js +387 -0
- package/src/commands/live.js +24 -0
- package/src/commands/prototype-check.js +163 -0
- package/src/commands/review-feature.js +189 -0
- package/src/commands/runtime.js +81 -66
- package/src/commands/sync-agents-copy.js +115 -0
- package/src/commands/verification-plan.js +116 -0
- package/src/commands/verify-artifact.js +530 -0
- package/src/commands/verify-implementation.js +428 -0
- package/src/commands/workflow-execute.js +309 -309
- package/src/commands/workflow-next.js +361 -19
- package/src/commands/workflow-plan.js +5 -5
- package/src/constants.js +4 -0
- package/src/gateway-pointer-merge.js +7 -1
- package/src/handoff-contract.js +267 -172
- package/src/harness/contract-integrity-gate.js +172 -0
- package/src/harness/contract-integrity.js +111 -0
- package/src/harness/contract-schema.js +377 -332
- package/src/harness/detect-runtime-feature.js +90 -0
- package/src/harness/static-criteria.js +192 -0
- package/src/i18n/messages/en.js +8 -4
- package/src/i18n/messages/es.js +8 -4
- package/src/i18n/messages/fr.js +8 -4
- package/src/i18n/messages/pt-BR.js +8 -4
- package/src/install-wizard.js +8 -8
- package/src/installer.js +13 -6
- package/src/lib/retro/retro-render.js +10 -1
- package/src/lib/retro/retro-sources.js +45 -27
- package/src/lib/retro/verification-reports.js +230 -0
- package/src/parser.js +6 -0
- package/src/preflight-engine.js +12 -12
- package/src/runtime-store.js +13 -9
- package/src/verification/evidence-bundle.js +251 -0
- package/src/verification/ledger-store.js +221 -0
- package/src/verification/path-policy.js +74 -0
- package/src/verification/policy-engine.js +95 -0
- package/src/verification/prompt-package.js +314 -0
- package/src/verification/redaction.js +77 -0
- package/src/verification/report-parser.js +132 -0
- package/src/verification/report-store.js +97 -0
- package/src/verification/result.js +16 -0
- package/src/verification/runners/index.js +319 -0
- package/src/verification/runtime-telemetry.js +144 -0
- package/src/verification/schema.js +276 -0
- package/src/verification/source-discovery.js +153 -0
- package/src/verification-policy.js +398 -0
- package/src/version.js +52 -1
- package/template/.aioson/agents/analyst.md +9 -6
- package/template/.aioson/agents/architect.md +34 -5
- package/template/.aioson/agents/briefing-refiner.md +25 -0
- package/template/.aioson/agents/briefing.md +69 -12
- package/template/.aioson/agents/committer.md +2 -1
- package/template/.aioson/agents/copywriter.md +30 -21
- package/template/.aioson/agents/design-hybrid-forge.md +28 -15
- package/template/.aioson/agents/dev.md +28 -10
- package/template/.aioson/agents/deyvin.md +3 -2
- package/template/.aioson/agents/discover.md +12 -3
- package/template/.aioson/agents/discovery-design-doc.md +7 -2
- package/template/.aioson/agents/genome.md +19 -10
- package/template/.aioson/agents/neo.md +30 -30
- package/template/.aioson/agents/orache.md +20 -11
- package/template/.aioson/agents/orchestrator.md +84 -7
- package/template/.aioson/agents/pm.md +8 -8
- package/template/.aioson/agents/product.md +15 -11
- package/template/.aioson/agents/profiler-enricher.md +20 -11
- package/template/.aioson/agents/profiler-forge.md +20 -11
- package/template/.aioson/agents/profiler-researcher.md +20 -11
- package/template/.aioson/agents/qa.md +87 -17
- package/template/.aioson/agents/scope-check.md +19 -5
- package/template/.aioson/agents/setup.md +12 -1
- package/template/.aioson/agents/sheldon.md +92 -9
- package/template/.aioson/agents/site-forge.md +11 -2
- package/template/.aioson/agents/squad.md +20 -5
- package/template/.aioson/agents/ux-ui.md +4 -2
- package/template/.aioson/agents/validator.md +33 -1
- package/template/.aioson/config/verification.json +61 -0
- package/template/.aioson/config.md +13 -9
- package/template/.aioson/docs/LAYERS.md +2 -2
- package/template/.aioson/docs/autopilot-handoff.md +10 -10
- package/template/.aioson/docs/dev/execution-discipline.md +41 -0
- package/template/.aioson/docs/dev/phase-loop.md +47 -0
- package/template/.aioson/docs/feature-expansion-taxonomy.md +31 -3
- package/template/.aioson/docs/presets/workflow.config.full-merged.json +15 -0
- package/template/.aioson/docs/presets/workflow.config.lean.json +15 -0
- package/template/.aioson/docs/product/prd-contract.md +12 -12
- package/template/.aioson/docs/prototype-contract.md +98 -0
- package/template/.aioson/docs/reference-identity.md +94 -0
- package/template/.aioson/docs/sheldon/harness-contract.md +155 -28
- package/template/.aioson/docs/verification-config.md +82 -0
- package/template/.aioson/docs/verify-artifact-gates.md +91 -0
- package/template/.aioson/docs/workflow-lean-lane.md +129 -0
- package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +2 -0
- package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +16 -14
- package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +2 -2
- package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +4 -4
- package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +15 -15
- package/template/.aioson/skills/process/briefing-expansion-scout/SKILL.md +25 -3
- package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +5 -3
- package/template/.aioson/skills/process/design-hybrid-forge/references/external-source-ingestion.md +89 -0
- package/template/.aioson/skills/process/product-scope-expansion/SKILL.md +29 -2
- package/template/.aioson/skills/process/prototype-forge/SKILL.md +98 -0
- package/template/.aioson/skills/process/reference-identity-extract/SKILL.md +164 -0
- package/template/.aioson/skills/process/sheldon-expansion-audit/SKILL.md +23 -2
- package/template/.aioson/skills/static/multi-agent-patterns.md +5 -5
- package/template/CLAUDE.md +15 -11
|
@@ -37,17 +37,17 @@ const {
|
|
|
37
37
|
extractStatusWritePathItems
|
|
38
38
|
} = require('../parallel-workspace');
|
|
39
39
|
|
|
40
|
-
const BAR = '━'.repeat(45);
|
|
41
|
-
const EXECUTION_STATE_RELATIVE_PATH = '.aioson/context/workflow-execute.json';
|
|
42
|
-
const DEFAULT_AGENTIC_MAX_CYCLES = 3;
|
|
40
|
+
const BAR = '━'.repeat(45);
|
|
41
|
+
const EXECUTION_STATE_RELATIVE_PATH = '.aioson/context/workflow-execute.json';
|
|
42
|
+
const DEFAULT_AGENTIC_MAX_CYCLES = 3;
|
|
43
43
|
|
|
44
44
|
const STEP_META = {
|
|
45
45
|
setup: { description: 'Initialize project context', gate_before: null, gate_after: null },
|
|
46
46
|
product: { description: 'Generate PRD', gate_before: null, gate_after: null },
|
|
47
|
-
analyst: { description: 'Map requirements + spec', gate_before: null, gate_after: 'A' },
|
|
48
|
-
architect: { description: 'Architecture design', gate_before: 'A', gate_after: 'B' },
|
|
49
|
-
'discovery-design-doc': { description: 'Prepare design-doc and readiness contract', gate_before: 'B', gate_after: null },
|
|
50
|
-
'ux-ui': { description: 'UI/UX design', gate_before: 'A', gate_after: 'B', optional: true },
|
|
47
|
+
analyst: { description: 'Map requirements + spec', gate_before: null, gate_after: 'A' },
|
|
48
|
+
architect: { description: 'Architecture design', gate_before: 'A', gate_after: 'B' },
|
|
49
|
+
'discovery-design-doc': { description: 'Prepare design-doc and readiness contract', gate_before: 'B', gate_after: null },
|
|
50
|
+
'ux-ui': { description: 'UI/UX design', gate_before: 'A', gate_after: 'B', optional: true },
|
|
51
51
|
pm: { description: 'Backlog + PM plan', gate_before: 'B', gate_after: 'C' },
|
|
52
52
|
orchestrator: { description: 'Coordinate execution lanes', gate_before: 'C', gate_after: null },
|
|
53
53
|
dev: { description: 'Implementation', gate_before: null, gate_after: 'C' },
|
|
@@ -89,105 +89,105 @@ function normalizeClassification(value, fallback = 'SMALL') {
|
|
|
89
89
|
return ['MICRO', 'SMALL', 'MEDIUM'].includes(safe) ? safe : fallback;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
function normalizeAgentName(value) {
|
|
93
|
-
return String(value || '').trim().toLowerCase().replace(/^@/, '');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function quoteCliArg(value) {
|
|
97
|
-
return `'${String(value || '').replace(/'/g, "'\\''")}'`;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function parsePositiveIntegerOption(value, fallback, min = 1, max = 10) {
|
|
101
|
-
const parsed = Number.parseInt(String(value || ''), 10);
|
|
102
|
-
if (!Number.isInteger(parsed)) return fallback;
|
|
103
|
-
if (parsed < min) return min;
|
|
104
|
-
if (parsed > max) return max;
|
|
105
|
-
return parsed;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function isAgenticRequested(options = {}) {
|
|
109
|
-
return Boolean(
|
|
110
|
-
options.agentic ||
|
|
111
|
-
options['agentic-run'] ||
|
|
112
|
-
options.autopilot === 'agentic' ||
|
|
113
|
-
options.autopilot === 'runtime'
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function buildAgenticPolicy(options = {}, classification = 'SMALL') {
|
|
118
|
-
const enabled = isAgenticRequested(options);
|
|
119
|
-
if (!enabled) return null;
|
|
120
|
-
|
|
121
|
-
const maxDevQaCycles = parsePositiveIntegerOption(
|
|
122
|
-
options['max-dev-qa-cycles'] || options.maxDevQaCycles || options['max-cycles'],
|
|
123
|
-
DEFAULT_AGENTIC_MAX_CYCLES
|
|
124
|
-
);
|
|
125
|
-
const maxTesterCycles = parsePositiveIntegerOption(
|
|
126
|
-
options['max-tester-cycles'] || options.maxTesterCycles || options['max-specialist-cycles'],
|
|
127
|
-
DEFAULT_AGENTIC_MAX_CYCLES
|
|
128
|
-
);
|
|
129
|
-
const maxPentesterCycles = parsePositiveIntegerOption(
|
|
130
|
-
options['max-pentester-cycles'] || options.maxPentesterCycles || options['max-specialist-cycles'],
|
|
131
|
-
DEFAULT_AGENTIC_MAX_CYCLES
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
enabled: true,
|
|
136
|
-
mode: 'runtime_policy',
|
|
137
|
-
source: 'workflow:execute',
|
|
138
|
-
stop_conditions: [
|
|
139
|
-
'feature_status_done',
|
|
140
|
-
'human_decision_required',
|
|
141
|
-
'gate_blocked',
|
|
142
|
-
'context_budget_exceeded',
|
|
143
|
-
'cycle_limit_reached',
|
|
144
|
-
'critical_security_human_gate',
|
|
145
|
-
'feature_close_human_gate'
|
|
146
|
-
],
|
|
147
|
-
review_cycle: {
|
|
148
|
-
hub: 'qa',
|
|
149
|
-
max_dev_qa_cycles: maxDevQaCycles,
|
|
150
|
-
max_tester_correction_cycles: maxTesterCycles,
|
|
151
|
-
max_pentester_correction_cycles: maxPentesterCycles,
|
|
152
|
-
qa_fail_route: 'dev',
|
|
153
|
-
tester_route: 'tester after qa coverage trigger',
|
|
154
|
-
pentester_route: 'pentester after sensitive-surface trigger or MEDIUM sequence stage',
|
|
155
|
-
validator_route: 'validator when harness contract is present',
|
|
156
|
-
feature_close: 'human_gate'
|
|
157
|
-
},
|
|
158
|
-
lanes: {
|
|
159
|
-
enabled: classification === 'MEDIUM',
|
|
160
|
-
strategy: 'parallelize_only_independent_write_scopes',
|
|
161
|
-
guard_command: 'aioson parallel:guard . --lane=<n>',
|
|
162
|
-
conflict_action: 'block_lane'
|
|
163
|
-
},
|
|
164
|
-
sidecars: {
|
|
165
|
-
scouts: {
|
|
166
|
-
enabled: true,
|
|
167
|
-
read_only: true,
|
|
168
|
-
max_per_session: 3,
|
|
169
|
-
max_files_in_scope: 20,
|
|
170
|
-
allowed_parent_agents: ['deyvin', 'dev', 'product', 'briefing', 'orache']
|
|
171
|
-
},
|
|
172
|
-
research: {
|
|
173
|
-
enabled: true,
|
|
174
|
-
cache_dir: 'researchs/',
|
|
175
|
-
cache_ttl_days: 7
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function formatAgenticPolicyLines(policy) {
|
|
182
|
-
if (!policy || !policy.enabled) return [];
|
|
183
|
-
return [
|
|
184
|
-
`Agentic policy: enabled (dev<->qa max ${policy.review_cycle.max_dev_qa_cycles} cycles)`,
|
|
185
|
-
`Review loop: qa fail -> dev; tester max ${policy.review_cycle.max_tester_correction_cycles}; pentester max ${policy.review_cycle.max_pentester_correction_cycles}; close=${policy.review_cycle.feature_close}`,
|
|
186
|
-
`Parallel lanes: ${policy.lanes.enabled ? 'enabled for independent write scopes' : 'disabled for this classification'}`
|
|
187
|
-
];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function findNextFromSequence(sequence, completed, skipped = []) {
|
|
92
|
+
function normalizeAgentName(value) {
|
|
93
|
+
return String(value || '').trim().toLowerCase().replace(/^@/, '');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function quoteCliArg(value) {
|
|
97
|
+
return `'${String(value || '').replace(/'/g, "'\\''")}'`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function parsePositiveIntegerOption(value, fallback, min = 1, max = 10) {
|
|
101
|
+
const parsed = Number.parseInt(String(value || ''), 10);
|
|
102
|
+
if (!Number.isInteger(parsed)) return fallback;
|
|
103
|
+
if (parsed < min) return min;
|
|
104
|
+
if (parsed > max) return max;
|
|
105
|
+
return parsed;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function isAgenticRequested(options = {}) {
|
|
109
|
+
return Boolean(
|
|
110
|
+
options.agentic ||
|
|
111
|
+
options['agentic-run'] ||
|
|
112
|
+
options.autopilot === 'agentic' ||
|
|
113
|
+
options.autopilot === 'runtime'
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function buildAgenticPolicy(options = {}, classification = 'SMALL') {
|
|
118
|
+
const enabled = isAgenticRequested(options);
|
|
119
|
+
if (!enabled) return null;
|
|
120
|
+
|
|
121
|
+
const maxDevQaCycles = parsePositiveIntegerOption(
|
|
122
|
+
options['max-dev-qa-cycles'] || options.maxDevQaCycles || options['max-cycles'],
|
|
123
|
+
DEFAULT_AGENTIC_MAX_CYCLES
|
|
124
|
+
);
|
|
125
|
+
const maxTesterCycles = parsePositiveIntegerOption(
|
|
126
|
+
options['max-tester-cycles'] || options.maxTesterCycles || options['max-specialist-cycles'],
|
|
127
|
+
DEFAULT_AGENTIC_MAX_CYCLES
|
|
128
|
+
);
|
|
129
|
+
const maxPentesterCycles = parsePositiveIntegerOption(
|
|
130
|
+
options['max-pentester-cycles'] || options.maxPentesterCycles || options['max-specialist-cycles'],
|
|
131
|
+
DEFAULT_AGENTIC_MAX_CYCLES
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
enabled: true,
|
|
136
|
+
mode: 'runtime_policy',
|
|
137
|
+
source: 'workflow:execute',
|
|
138
|
+
stop_conditions: [
|
|
139
|
+
'feature_status_done',
|
|
140
|
+
'human_decision_required',
|
|
141
|
+
'gate_blocked',
|
|
142
|
+
'context_budget_exceeded',
|
|
143
|
+
'cycle_limit_reached',
|
|
144
|
+
'critical_security_human_gate',
|
|
145
|
+
'feature_close_human_gate'
|
|
146
|
+
],
|
|
147
|
+
review_cycle: {
|
|
148
|
+
hub: 'qa',
|
|
149
|
+
max_dev_qa_cycles: maxDevQaCycles,
|
|
150
|
+
max_tester_correction_cycles: maxTesterCycles,
|
|
151
|
+
max_pentester_correction_cycles: maxPentesterCycles,
|
|
152
|
+
qa_fail_route: 'dev',
|
|
153
|
+
tester_route: 'tester after qa coverage trigger',
|
|
154
|
+
pentester_route: 'pentester after sensitive-surface trigger or MEDIUM sequence stage',
|
|
155
|
+
validator_route: 'validator when harness contract is present',
|
|
156
|
+
feature_close: 'human_gate'
|
|
157
|
+
},
|
|
158
|
+
lanes: {
|
|
159
|
+
enabled: classification === 'MEDIUM',
|
|
160
|
+
strategy: 'parallelize_only_independent_write_scopes',
|
|
161
|
+
guard_command: 'aioson parallel:guard . --lane=<n>',
|
|
162
|
+
conflict_action: 'block_lane'
|
|
163
|
+
},
|
|
164
|
+
sidecars: {
|
|
165
|
+
scouts: {
|
|
166
|
+
enabled: true,
|
|
167
|
+
read_only: true,
|
|
168
|
+
max_per_session: 3,
|
|
169
|
+
max_files_in_scope: 20,
|
|
170
|
+
allowed_parent_agents: ['deyvin', 'dev', 'product', 'briefing', 'orache']
|
|
171
|
+
},
|
|
172
|
+
research: {
|
|
173
|
+
enabled: true,
|
|
174
|
+
cache_dir: 'researchs/',
|
|
175
|
+
cache_ttl_days: 7
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function formatAgenticPolicyLines(policy) {
|
|
182
|
+
if (!policy || !policy.enabled) return [];
|
|
183
|
+
return [
|
|
184
|
+
`Agentic policy: enabled (dev<->qa max ${policy.review_cycle.max_dev_qa_cycles} cycles)`,
|
|
185
|
+
`Review loop: qa fail -> dev; tester max ${policy.review_cycle.max_tester_correction_cycles}; pentester max ${policy.review_cycle.max_pentester_correction_cycles}; close=${policy.review_cycle.feature_close}`,
|
|
186
|
+
`Parallel lanes: ${policy.lanes.enabled ? 'enabled for independent write scopes' : 'disabled for this classification'}`
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function findNextFromSequence(sequence, completed, skipped = []) {
|
|
191
191
|
const done = new Set([...(completed || []), ...(skipped || [])].map(normalizeAgentName));
|
|
192
192
|
return sequence.find((stage) => !done.has(normalizeAgentName(stage))) || null;
|
|
193
193
|
}
|
|
@@ -244,9 +244,9 @@ function inferCompletedStagesFromArtifacts(sequence, artifacts, gates) {
|
|
|
244
244
|
return completed;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
async function seedFeatureWorkflowState(targetDir, slug, classification, startFrom) {
|
|
248
|
-
const statePath = path.join(targetDir, STATE_RELATIVE_PATH);
|
|
249
|
-
const existing = await readJsonIfExists(statePath);
|
|
247
|
+
async function seedFeatureWorkflowState(targetDir, slug, classification, startFrom) {
|
|
248
|
+
const statePath = path.join(targetDir, STATE_RELATIVE_PATH);
|
|
249
|
+
const existing = await readJsonIfExists(statePath);
|
|
250
250
|
const focusStage = getFocusStage(existing);
|
|
251
251
|
|
|
252
252
|
if (
|
|
@@ -301,141 +301,141 @@ async function seedFeatureWorkflowState(targetDir, slug, classification, startFr
|
|
|
301
301
|
detour: null,
|
|
302
302
|
updatedAt: new Date().toISOString()
|
|
303
303
|
};
|
|
304
|
-
|
|
305
|
-
await writeJson(statePath, state);
|
|
306
|
-
return {
|
|
307
|
-
ok: true,
|
|
304
|
+
|
|
305
|
+
await writeJson(statePath, state);
|
|
306
|
+
return {
|
|
307
|
+
ok: true,
|
|
308
308
|
resumed: false,
|
|
309
309
|
state,
|
|
310
310
|
statePath: STATE_RELATIVE_PATH
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
async function previewFeatureWorkflowState(targetDir, slug, classification, startFrom) {
|
|
315
|
-
const existing = await readJsonIfExists(path.join(targetDir, STATE_RELATIVE_PATH));
|
|
316
|
-
const focusStage = getFocusStage(existing);
|
|
317
|
-
|
|
318
|
-
if (
|
|
319
|
-
existing &&
|
|
320
|
-
existing.mode === 'feature' &&
|
|
321
|
-
existing.featureSlug &&
|
|
322
|
-
existing.featureSlug !== slug &&
|
|
323
|
-
focusStage
|
|
324
|
-
) {
|
|
325
|
-
return {
|
|
326
|
-
ok: false,
|
|
327
|
-
reason: 'different_active_feature',
|
|
328
|
-
active_feature: existing.featureSlug,
|
|
329
|
-
active_stage: focusStage
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (existing && existing.mode === 'feature' && existing.featureSlug === slug) {
|
|
334
|
-
return {
|
|
335
|
-
ok: true,
|
|
336
|
-
resumed: true,
|
|
337
|
-
state: existing,
|
|
338
|
-
statePath: STATE_RELATIVE_PATH
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const artifacts = await scanArtifacts(targetDir, slug);
|
|
343
|
-
const gates = await readPhaseGates(targetDir, slug);
|
|
344
|
-
const sequence = await resolveFeatureSequence(targetDir, classification);
|
|
345
|
-
const completed = inferCompletedStagesFromArtifacts(sequence, artifacts, gates);
|
|
346
|
-
const normalizedStartFrom = startFrom ? normalizeAgentName(startFrom) : null;
|
|
347
|
-
|
|
348
|
-
let skipped = [];
|
|
349
|
-
let next = findNextFromSequence(sequence, completed, skipped);
|
|
350
|
-
|
|
351
|
-
if (normalizedStartFrom && sequence.includes(normalizedStartFrom)) {
|
|
352
|
-
const targetIndex = sequence.indexOf(normalizedStartFrom);
|
|
353
|
-
skipped = sequence.slice(0, targetIndex).filter((stage) => !completed.includes(stage));
|
|
354
|
-
next = normalizedStartFrom;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
return {
|
|
358
|
-
ok: true,
|
|
359
|
-
resumed: false,
|
|
360
|
-
state: {
|
|
361
|
-
version: 1,
|
|
362
|
-
mode: 'feature',
|
|
363
|
-
classification,
|
|
364
|
-
sequence,
|
|
365
|
-
current: null,
|
|
366
|
-
next,
|
|
367
|
-
completed,
|
|
368
|
-
skipped,
|
|
369
|
-
featureSlug: slug,
|
|
370
|
-
detour: null,
|
|
371
|
-
updatedAt: new Date().toISOString()
|
|
372
|
-
},
|
|
373
|
-
statePath: STATE_RELATIVE_PATH
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function buildDryRunSuggestion(planData) {
|
|
378
|
-
const active = planData.steps.find((step) => step.status === 'active');
|
|
379
|
-
if (active) {
|
|
380
|
-
return {
|
|
381
|
-
action: active.predicted_blockers.length > 0 ? 'complete_stage' : 'continue_stage',
|
|
382
|
-
agent: active.agent,
|
|
383
|
-
command: `aioson workflow:next . --complete=${active.agent}`,
|
|
384
|
-
reason: `Preview stage @${active.agent}.`
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
const next = planData.steps.find((step) => step.status !== 'completed' && step.status !== 'skipped');
|
|
389
|
-
if (!next) {
|
|
390
|
-
return {
|
|
391
|
-
action: 'workflow_complete',
|
|
392
|
-
agent: null,
|
|
393
|
-
command: null,
|
|
394
|
-
reason: 'Preview workflow has no pending stage.'
|
|
395
|
-
};
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
return {
|
|
399
|
-
action: next.status === 'blocked' ? 'blocked' : 'activate_stage',
|
|
400
|
-
agent: next.agent,
|
|
401
|
-
command: `aioson workflow:next . --agent=${next.agent}`,
|
|
402
|
-
reason: next.status === 'blocked'
|
|
403
|
-
? `Preview stage @${next.agent} is blocked.`
|
|
404
|
-
: `Preview next official stage is @${next.agent}.`
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
function buildDryRunArtifactsSummary(artifacts) {
|
|
409
|
-
return Object.entries(artifacts || {}).map(([id, artifact]) => ({
|
|
410
|
-
id,
|
|
411
|
-
label: artifact && artifact.path ? path.basename(artifact.path) : id,
|
|
412
|
-
file: artifact && artifact.path ? artifact.path : null,
|
|
413
|
-
exists: Boolean(artifact && artifact.exists)
|
|
414
|
-
}));
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
function buildDryRunStatusSnapshot({ targetDir, slug, classification, workflowState, planData, tool }) {
|
|
418
|
-
const suggestion = buildDryRunSuggestion(planData);
|
|
419
|
-
return {
|
|
420
|
-
ok: true,
|
|
421
|
-
projectName: path.basename(targetDir),
|
|
422
|
-
classification,
|
|
423
|
-
mode: 'feature',
|
|
424
|
-
featureSlug: slug,
|
|
425
|
-
tool,
|
|
426
|
-
state: workflowState,
|
|
427
|
-
stateCreated: false,
|
|
428
|
-
dryRun: true,
|
|
429
|
-
activeStage: workflowState.current || workflowState.next || null,
|
|
430
|
-
queuedNextStage: workflowState.next || null,
|
|
431
|
-
pendingGates: [],
|
|
432
|
-
contractCheck: null,
|
|
433
|
-
artifacts: buildDryRunArtifactsSummary(planData.artifacts),
|
|
434
|
-
suggestion
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
async function buildExecutionPlan(targetDir, slug, classification, workflowState = null, startFrom = null) {
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async function previewFeatureWorkflowState(targetDir, slug, classification, startFrom) {
|
|
315
|
+
const existing = await readJsonIfExists(path.join(targetDir, STATE_RELATIVE_PATH));
|
|
316
|
+
const focusStage = getFocusStage(existing);
|
|
317
|
+
|
|
318
|
+
if (
|
|
319
|
+
existing &&
|
|
320
|
+
existing.mode === 'feature' &&
|
|
321
|
+
existing.featureSlug &&
|
|
322
|
+
existing.featureSlug !== slug &&
|
|
323
|
+
focusStage
|
|
324
|
+
) {
|
|
325
|
+
return {
|
|
326
|
+
ok: false,
|
|
327
|
+
reason: 'different_active_feature',
|
|
328
|
+
active_feature: existing.featureSlug,
|
|
329
|
+
active_stage: focusStage
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (existing && existing.mode === 'feature' && existing.featureSlug === slug) {
|
|
334
|
+
return {
|
|
335
|
+
ok: true,
|
|
336
|
+
resumed: true,
|
|
337
|
+
state: existing,
|
|
338
|
+
statePath: STATE_RELATIVE_PATH
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const artifacts = await scanArtifacts(targetDir, slug);
|
|
343
|
+
const gates = await readPhaseGates(targetDir, slug);
|
|
344
|
+
const sequence = await resolveFeatureSequence(targetDir, classification);
|
|
345
|
+
const completed = inferCompletedStagesFromArtifacts(sequence, artifacts, gates);
|
|
346
|
+
const normalizedStartFrom = startFrom ? normalizeAgentName(startFrom) : null;
|
|
347
|
+
|
|
348
|
+
let skipped = [];
|
|
349
|
+
let next = findNextFromSequence(sequence, completed, skipped);
|
|
350
|
+
|
|
351
|
+
if (normalizedStartFrom && sequence.includes(normalizedStartFrom)) {
|
|
352
|
+
const targetIndex = sequence.indexOf(normalizedStartFrom);
|
|
353
|
+
skipped = sequence.slice(0, targetIndex).filter((stage) => !completed.includes(stage));
|
|
354
|
+
next = normalizedStartFrom;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
ok: true,
|
|
359
|
+
resumed: false,
|
|
360
|
+
state: {
|
|
361
|
+
version: 1,
|
|
362
|
+
mode: 'feature',
|
|
363
|
+
classification,
|
|
364
|
+
sequence,
|
|
365
|
+
current: null,
|
|
366
|
+
next,
|
|
367
|
+
completed,
|
|
368
|
+
skipped,
|
|
369
|
+
featureSlug: slug,
|
|
370
|
+
detour: null,
|
|
371
|
+
updatedAt: new Date().toISOString()
|
|
372
|
+
},
|
|
373
|
+
statePath: STATE_RELATIVE_PATH
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function buildDryRunSuggestion(planData) {
|
|
378
|
+
const active = planData.steps.find((step) => step.status === 'active');
|
|
379
|
+
if (active) {
|
|
380
|
+
return {
|
|
381
|
+
action: active.predicted_blockers.length > 0 ? 'complete_stage' : 'continue_stage',
|
|
382
|
+
agent: active.agent,
|
|
383
|
+
command: `aioson workflow:next . --complete=${active.agent}`,
|
|
384
|
+
reason: `Preview stage @${active.agent}.`
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const next = planData.steps.find((step) => step.status !== 'completed' && step.status !== 'skipped');
|
|
389
|
+
if (!next) {
|
|
390
|
+
return {
|
|
391
|
+
action: 'workflow_complete',
|
|
392
|
+
agent: null,
|
|
393
|
+
command: null,
|
|
394
|
+
reason: 'Preview workflow has no pending stage.'
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return {
|
|
399
|
+
action: next.status === 'blocked' ? 'blocked' : 'activate_stage',
|
|
400
|
+
agent: next.agent,
|
|
401
|
+
command: `aioson workflow:next . --agent=${next.agent}`,
|
|
402
|
+
reason: next.status === 'blocked'
|
|
403
|
+
? `Preview stage @${next.agent} is blocked.`
|
|
404
|
+
: `Preview next official stage is @${next.agent}.`
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function buildDryRunArtifactsSummary(artifacts) {
|
|
409
|
+
return Object.entries(artifacts || {}).map(([id, artifact]) => ({
|
|
410
|
+
id,
|
|
411
|
+
label: artifact && artifact.path ? path.basename(artifact.path) : id,
|
|
412
|
+
file: artifact && artifact.path ? artifact.path : null,
|
|
413
|
+
exists: Boolean(artifact && artifact.exists)
|
|
414
|
+
}));
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function buildDryRunStatusSnapshot({ targetDir, slug, classification, workflowState, planData, tool }) {
|
|
418
|
+
const suggestion = buildDryRunSuggestion(planData);
|
|
419
|
+
return {
|
|
420
|
+
ok: true,
|
|
421
|
+
projectName: path.basename(targetDir),
|
|
422
|
+
classification,
|
|
423
|
+
mode: 'feature',
|
|
424
|
+
featureSlug: slug,
|
|
425
|
+
tool,
|
|
426
|
+
state: workflowState,
|
|
427
|
+
stateCreated: false,
|
|
428
|
+
dryRun: true,
|
|
429
|
+
activeStage: workflowState.current || workflowState.next || null,
|
|
430
|
+
queuedNextStage: workflowState.next || null,
|
|
431
|
+
pendingGates: [],
|
|
432
|
+
contractCheck: null,
|
|
433
|
+
artifacts: buildDryRunArtifactsSummary(planData.artifacts),
|
|
434
|
+
suggestion
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
async function buildExecutionPlan(targetDir, slug, classification, workflowState = null, startFrom = null) {
|
|
439
439
|
const sequence = workflowState && Array.isArray(workflowState.sequence) && workflowState.sequence.length > 0
|
|
440
440
|
? [...workflowState.sequence]
|
|
441
441
|
: await resolveFeatureSequence(targetDir, classification);
|
|
@@ -472,11 +472,11 @@ async function buildExecutionPlan(targetDir, slug, classification, workflowState
|
|
|
472
472
|
else if (focusStage === agent) status = 'active';
|
|
473
473
|
|
|
474
474
|
const predictedBlockers = [];
|
|
475
|
-
if (status !== 'completed' && status !== 'skipped' && meta.gate_before && !isGateApproved(gates, meta.gate_before)) {
|
|
476
|
-
const responsible = GATE_RESPONSIBLE_AGENT[meta.gate_before] || 'previous agent';
|
|
477
|
-
const featureArg = slug ? ` --feature=${quoteCliArg(slug)}` : '';
|
|
478
|
-
predictedBlockers.push(
|
|
479
|
-
`Gate ${meta.gate_before} (${GATE_NAMES[meta.gate_before] || meta.gate_before}) not approved — ` +
|
|
475
|
+
if (status !== 'completed' && status !== 'skipped' && meta.gate_before && !isGateApproved(gates, meta.gate_before)) {
|
|
476
|
+
const responsible = GATE_RESPONSIBLE_AGENT[meta.gate_before] || 'previous agent';
|
|
477
|
+
const featureArg = slug ? ` --feature=${quoteCliArg(slug)}` : '';
|
|
478
|
+
predictedBlockers.push(
|
|
479
|
+
`Gate ${meta.gate_before} (${GATE_NAMES[meta.gate_before] || meta.gate_before}) not approved — ` +
|
|
480
480
|
`responsible: ${responsible} — ` +
|
|
481
481
|
`approve with: aioson gate:approve .${featureArg} --gate=${meta.gate_before}`
|
|
482
482
|
);
|
|
@@ -565,10 +565,10 @@ async function writeExecutionCheckpoint(targetDir, payload) {
|
|
|
565
565
|
checkpoint: payload.checkpoint || null,
|
|
566
566
|
status_snapshot: payload.statusSnapshot || null,
|
|
567
567
|
suggestion: payload.suggestion || null,
|
|
568
|
-
resume_command: payload.resumeCommand || null,
|
|
569
|
-
agentic_policy: payload.agenticPolicy || null,
|
|
570
|
-
history
|
|
571
|
-
};
|
|
568
|
+
resume_command: payload.resumeCommand || null,
|
|
569
|
+
agentic_policy: payload.agenticPolicy || null,
|
|
570
|
+
history
|
|
571
|
+
};
|
|
572
572
|
await writeJson(execPath, nextPayload);
|
|
573
573
|
return nextPayload;
|
|
574
574
|
}
|
|
@@ -718,11 +718,11 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
718
718
|
return { ok: false };
|
|
719
719
|
}
|
|
720
720
|
|
|
721
|
-
let classification = options.classification ? String(options.classification).toUpperCase() : null;
|
|
722
|
-
if (!classification) classification = await detectClassification(targetDir, slug);
|
|
723
|
-
if (!classification) classification = 'SMALL';
|
|
724
|
-
classification = normalizeClassification(classification, 'SMALL');
|
|
725
|
-
const agenticPolicy = buildAgenticPolicy(options, classification);
|
|
721
|
+
let classification = options.classification ? String(options.classification).toUpperCase() : null;
|
|
722
|
+
if (!classification) classification = await detectClassification(targetDir, slug);
|
|
723
|
+
if (!classification) classification = 'SMALL';
|
|
724
|
+
classification = normalizeClassification(classification, 'SMALL');
|
|
725
|
+
const agenticPolicy = buildAgenticPolicy(options, classification);
|
|
726
726
|
|
|
727
727
|
const autonomyProtocol = await readAutonomyProtocol(targetDir);
|
|
728
728
|
const toolPolicy = getToolPolicy(autonomyProtocol, tool);
|
|
@@ -756,9 +756,9 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
756
756
|
}
|
|
757
757
|
}
|
|
758
758
|
|
|
759
|
-
const seeded = dryRun
|
|
760
|
-
? await previewFeatureWorkflowState(targetDir, slug, classification, startFrom)
|
|
761
|
-
: await seedFeatureWorkflowState(targetDir, slug, classification, startFrom);
|
|
759
|
+
const seeded = dryRun
|
|
760
|
+
? await previewFeatureWorkflowState(targetDir, slug, classification, startFrom)
|
|
761
|
+
: await seedFeatureWorkflowState(targetDir, slug, classification, startFrom);
|
|
762
762
|
if (!seeded.ok) {
|
|
763
763
|
if (options.json) return seeded;
|
|
764
764
|
logger.error(
|
|
@@ -781,28 +781,28 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
781
781
|
|
|
782
782
|
const activePlan = planData.steps.filter((step) => step.status !== 'completed' && !(skipOptional && step.optional));
|
|
783
783
|
const blockedSteps = planData.steps.filter((step) => step.predicted_blockers.length > 0);
|
|
784
|
-
const statusSnapshot = dryRun
|
|
785
|
-
? buildDryRunStatusSnapshot({ targetDir, slug, classification, workflowState: seeded.state, planData, tool })
|
|
786
|
-
: await readStatusSnapshot(targetDir, tool, t);
|
|
787
|
-
const resumeCommand = [
|
|
788
|
-
'aioson',
|
|
789
|
-
'workflow:execute',
|
|
790
|
-
quoteCliArg(targetDir),
|
|
791
|
-
`--feature=${quoteCliArg(slug)}`,
|
|
792
|
-
`--tool=${quoteCliArg(tool)}`,
|
|
793
|
-
...(requestedMode ? [`--mode=${quoteCliArg(requestedMode)}`] : []),
|
|
794
|
-
...(maxCheckpoints !== 1 ? [`--max-checkpoints=${quoteCliArg(maxCheckpoints)}`] : []),
|
|
795
|
-
...(agenticPolicy ? ['--agentic'] : []),
|
|
796
|
-
...(agenticPolicy && agenticPolicy.review_cycle.max_dev_qa_cycles !== DEFAULT_AGENTIC_MAX_CYCLES
|
|
797
|
-
? [`--max-dev-qa-cycles=${quoteCliArg(agenticPolicy.review_cycle.max_dev_qa_cycles)}`]
|
|
798
|
-
: []),
|
|
799
|
-
...(agenticPolicy && agenticPolicy.review_cycle.max_tester_correction_cycles !== DEFAULT_AGENTIC_MAX_CYCLES
|
|
800
|
-
? [`--max-tester-cycles=${quoteCliArg(agenticPolicy.review_cycle.max_tester_correction_cycles)}`]
|
|
801
|
-
: []),
|
|
802
|
-
...(agenticPolicy && agenticPolicy.review_cycle.max_pentester_correction_cycles !== DEFAULT_AGENTIC_MAX_CYCLES
|
|
803
|
-
? [`--max-pentester-cycles=${quoteCliArg(agenticPolicy.review_cycle.max_pentester_correction_cycles)}`]
|
|
804
|
-
: [])
|
|
805
|
-
].join(' ');
|
|
784
|
+
const statusSnapshot = dryRun
|
|
785
|
+
? buildDryRunStatusSnapshot({ targetDir, slug, classification, workflowState: seeded.state, planData, tool })
|
|
786
|
+
: await readStatusSnapshot(targetDir, tool, t);
|
|
787
|
+
const resumeCommand = [
|
|
788
|
+
'aioson',
|
|
789
|
+
'workflow:execute',
|
|
790
|
+
quoteCliArg(targetDir),
|
|
791
|
+
`--feature=${quoteCliArg(slug)}`,
|
|
792
|
+
`--tool=${quoteCliArg(tool)}`,
|
|
793
|
+
...(requestedMode ? [`--mode=${quoteCliArg(requestedMode)}`] : []),
|
|
794
|
+
...(maxCheckpoints !== 1 ? [`--max-checkpoints=${quoteCliArg(maxCheckpoints)}`] : []),
|
|
795
|
+
...(agenticPolicy ? ['--agentic'] : []),
|
|
796
|
+
...(agenticPolicy && agenticPolicy.review_cycle.max_dev_qa_cycles !== DEFAULT_AGENTIC_MAX_CYCLES
|
|
797
|
+
? [`--max-dev-qa-cycles=${quoteCliArg(agenticPolicy.review_cycle.max_dev_qa_cycles)}`]
|
|
798
|
+
: []),
|
|
799
|
+
...(agenticPolicy && agenticPolicy.review_cycle.max_tester_correction_cycles !== DEFAULT_AGENTIC_MAX_CYCLES
|
|
800
|
+
? [`--max-tester-cycles=${quoteCliArg(agenticPolicy.review_cycle.max_tester_correction_cycles)}`]
|
|
801
|
+
: []),
|
|
802
|
+
...(agenticPolicy && agenticPolicy.review_cycle.max_pentester_correction_cycles !== DEFAULT_AGENTIC_MAX_CYCLES
|
|
803
|
+
? [`--max-pentester-cycles=${quoteCliArg(agenticPolicy.review_cycle.max_pentester_correction_cycles)}`]
|
|
804
|
+
: [])
|
|
805
|
+
].join(' ');
|
|
806
806
|
|
|
807
807
|
if (dryRun) {
|
|
808
808
|
const result = {
|
|
@@ -821,11 +821,11 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
821
821
|
blocked_steps: blockedSteps.length,
|
|
822
822
|
gates: planData.gates,
|
|
823
823
|
status_snapshot: statusSnapshot,
|
|
824
|
-
suggestion: statusSnapshot && statusSnapshot.suggestion ? statusSnapshot.suggestion : null,
|
|
825
|
-
resume_command: resumeCommand,
|
|
826
|
-
agentic_policy: agenticPolicy,
|
|
827
|
-
parallel_guard: parallelGuard
|
|
828
|
-
};
|
|
824
|
+
suggestion: statusSnapshot && statusSnapshot.suggestion ? statusSnapshot.suggestion : null,
|
|
825
|
+
resume_command: resumeCommand,
|
|
826
|
+
agentic_policy: agenticPolicy,
|
|
827
|
+
parallel_guard: parallelGuard
|
|
828
|
+
};
|
|
829
829
|
|
|
830
830
|
if (options.json) return result;
|
|
831
831
|
|
|
@@ -844,14 +844,14 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
844
844
|
logger.log('');
|
|
845
845
|
logger.log(`Blocked steps: ${blockedSteps.length} | Remaining: ${activePlan.length}`);
|
|
846
846
|
logger.log(`Resume state: ${seeded.resumed ? 'existing workflow state reused' : 'new workflow state seeded'}`);
|
|
847
|
-
if (statusSnapshot && statusSnapshot.suggestion && statusSnapshot.suggestion.command) {
|
|
848
|
-
logger.log(`Suggested command: ${statusSnapshot.suggestion.command}`);
|
|
849
|
-
}
|
|
850
|
-
for (const line of formatAgenticPolicyLines(agenticPolicy)) {
|
|
851
|
-
logger.log(line);
|
|
852
|
-
}
|
|
853
|
-
logger.log('');
|
|
854
|
-
return result;
|
|
847
|
+
if (statusSnapshot && statusSnapshot.suggestion && statusSnapshot.suggestion.command) {
|
|
848
|
+
logger.log(`Suggested command: ${statusSnapshot.suggestion.command}`);
|
|
849
|
+
}
|
|
850
|
+
for (const line of formatAgenticPolicyLines(agenticPolicy)) {
|
|
851
|
+
logger.log(line);
|
|
852
|
+
}
|
|
853
|
+
logger.log('');
|
|
854
|
+
return result;
|
|
855
855
|
}
|
|
856
856
|
|
|
857
857
|
const executionTransitions = [];
|
|
@@ -931,11 +931,11 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
931
931
|
resumed: seeded.resumed,
|
|
932
932
|
status: activation && activation.agent ? 'active' : 'completed',
|
|
933
933
|
checkpoint: buildCheckpointPayload(activation, handoff, handoffProtocol),
|
|
934
|
-
statusSnapshot: refreshedStatus,
|
|
935
|
-
suggestion: refreshedStatus && refreshedStatus.suggestion ? refreshedStatus.suggestion : null,
|
|
936
|
-
resumeCommand,
|
|
937
|
-
agenticPolicy
|
|
938
|
-
});
|
|
934
|
+
statusSnapshot: refreshedStatus,
|
|
935
|
+
suggestion: refreshedStatus && refreshedStatus.suggestion ? refreshedStatus.suggestion : null,
|
|
936
|
+
resumeCommand,
|
|
937
|
+
agenticPolicy
|
|
938
|
+
});
|
|
939
939
|
|
|
940
940
|
const result = {
|
|
941
941
|
ok: true,
|
|
@@ -950,10 +950,10 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
950
950
|
checkpoint: executionState.checkpoint,
|
|
951
951
|
execution_state: executionState,
|
|
952
952
|
status_snapshot: refreshedStatus,
|
|
953
|
-
suggestion: refreshedStatus && refreshedStatus.suggestion ? refreshedStatus.suggestion : null,
|
|
954
|
-
resume_command: resumeCommand,
|
|
955
|
-
agentic_policy: agenticPolicy,
|
|
956
|
-
transitions: executionTransitions,
|
|
953
|
+
suggestion: refreshedStatus && refreshedStatus.suggestion ? refreshedStatus.suggestion : null,
|
|
954
|
+
resume_command: resumeCommand,
|
|
955
|
+
agentic_policy: agenticPolicy,
|
|
956
|
+
transitions: executionTransitions,
|
|
957
957
|
active_stage: activation && activation.agent ? activation.agent : null,
|
|
958
958
|
next_stage: activation && activation.next ? activation.next : null,
|
|
959
959
|
handoff,
|
|
@@ -971,10 +971,10 @@ async function runWorkflowExecute({ args, options = {}, logger }) {
|
|
|
971
971
|
return result;
|
|
972
972
|
}
|
|
973
973
|
|
|
974
|
-
module.exports = {
|
|
975
|
-
EXECUTION_STATE_RELATIVE_PATH,
|
|
976
|
-
buildAgenticPolicy,
|
|
977
|
-
buildExecutionPlan,
|
|
978
|
-
seedFeatureWorkflowState,
|
|
979
|
-
runWorkflowExecute
|
|
980
|
-
};
|
|
974
|
+
module.exports = {
|
|
975
|
+
EXECUTION_STATE_RELATIVE_PATH,
|
|
976
|
+
buildAgenticPolicy,
|
|
977
|
+
buildExecutionPlan,
|
|
978
|
+
seedFeatureWorkflowState,
|
|
979
|
+
runWorkflowExecute
|
|
980
|
+
};
|