@brunosps00/dev-workflow 2.1.0 → 2.3.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.
Files changed (129) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +118 -0
  3. package/README.md +17 -6
  4. package/lib/constants.js +24 -20
  5. package/lib/init.js +34 -0
  6. package/lib/instruction-health.js +38 -0
  7. package/lib/post-update.js +2 -1
  8. package/lib/validate.js +3 -1
  9. package/package.json +1 -1
  10. package/scaffold/config/routing.json +61 -23
  11. package/scaffold/en/agent-instructions.md +31 -135
  12. package/scaffold/en/commands/dw-analyze-project.md +2 -0
  13. package/scaffold/en/commands/dw-autopilot.md +22 -243
  14. package/scaffold/en/commands/dw-bugfix.md +9 -35
  15. package/scaffold/en/commands/dw-claude-run.md +29 -45
  16. package/scaffold/en/commands/dw-codex-run.md +30 -45
  17. package/scaffold/en/commands/dw-context-budget.md +6 -14
  18. package/scaffold/en/commands/dw-copilot-run.md +29 -41
  19. package/scaffold/en/commands/dw-generate-pr.md +2 -2
  20. package/scaffold/en/commands/dw-goal.md +11 -5
  21. package/scaffold/en/commands/dw-harness-audit.md +2 -0
  22. package/scaffold/en/commands/dw-help.md +8 -4
  23. package/scaffold/en/commands/dw-pause.md +1 -0
  24. package/scaffold/en/commands/dw-plan.md +14 -7
  25. package/scaffold/en/commands/dw-qa.md +2 -0
  26. package/scaffold/en/commands/dw-report.md +169 -0
  27. package/scaffold/en/commands/dw-resume.md +5 -11
  28. package/scaffold/en/commands/dw-review.md +4 -3
  29. package/scaffold/en/commands/dw-run.md +19 -165
  30. package/scaffold/en/commands/dw-skill-health.md +7 -0
  31. package/scaffold/en/commands/dw-update.md +18 -4
  32. package/scaffold/en/commands/dw-worktree.md +100 -0
  33. package/scaffold/en/references/command-routing.md +53 -0
  34. package/scaffold/en/references/execution-contract.md +55 -0
  35. package/scaffold/en/templates/frontend-quality-template.md +43 -0
  36. package/scaffold/en/templates/task-template.md +20 -40
  37. package/scaffold/en/templates/tasks-template.md +9 -6
  38. package/scaffold/en/templates/techspec-template.md +4 -0
  39. package/scaffold/pt-br/agent-instructions.md +31 -135
  40. package/scaffold/pt-br/commands/dw-analyze-project.md +2 -0
  41. package/scaffold/pt-br/commands/dw-autopilot.md +22 -243
  42. package/scaffold/pt-br/commands/dw-bugfix.md +9 -35
  43. package/scaffold/pt-br/commands/dw-claude-run.md +29 -46
  44. package/scaffold/pt-br/commands/dw-codex-run.md +30 -45
  45. package/scaffold/pt-br/commands/dw-context-budget.md +6 -14
  46. package/scaffold/pt-br/commands/dw-copilot-run.md +29 -43
  47. package/scaffold/pt-br/commands/dw-generate-pr.md +2 -2
  48. package/scaffold/pt-br/commands/dw-goal.md +11 -5
  49. package/scaffold/pt-br/commands/dw-harness-audit.md +2 -0
  50. package/scaffold/pt-br/commands/dw-help.md +8 -4
  51. package/scaffold/pt-br/commands/dw-pause.md +1 -0
  52. package/scaffold/pt-br/commands/dw-plan.md +14 -7
  53. package/scaffold/pt-br/commands/dw-qa.md +2 -0
  54. package/scaffold/pt-br/commands/dw-report.md +169 -0
  55. package/scaffold/pt-br/commands/dw-resume.md +7 -11
  56. package/scaffold/pt-br/commands/dw-review.md +4 -3
  57. package/scaffold/pt-br/commands/dw-run.md +19 -165
  58. package/scaffold/pt-br/commands/dw-skill-health.md +7 -0
  59. package/scaffold/pt-br/commands/dw-update.md +18 -4
  60. package/scaffold/pt-br/commands/dw-worktree.md +100 -0
  61. package/scaffold/pt-br/references/command-routing.md +53 -0
  62. package/scaffold/pt-br/references/execution-contract.md +55 -0
  63. package/scaffold/pt-br/templates/frontend-quality-template.md +43 -0
  64. package/scaffold/pt-br/templates/task-template.md +20 -40
  65. package/scaffold/pt-br/templates/tasks-template.md +9 -6
  66. package/scaffold/pt-br/templates/techspec-template.md +4 -0
  67. package/scaffold/scripts/hooks/git-guardrails.mjs +1 -0
  68. package/scaffold/scripts/lib/workflow-contract.mjs +101 -0
  69. package/scaffold/scripts/lib/worktree-gc.mjs +460 -0
  70. package/scaffold/skill-registry.json +23 -23
  71. package/scaffold/skills/dw-cli-run/SKILL.md +33 -208
  72. package/scaffold/skills/dw-cli-run/references/dispatch-tuning.md +14 -72
  73. package/scaffold/skills/dw-codebase-intel/SKILL.md +5 -39
  74. package/scaffold/skills/dw-codebase-intel/agents/intel-updater.md +1 -1
  75. package/scaffold/skills/dw-codebase-intel/references/agents-detail.md +7 -0
  76. package/scaffold/skills/dw-codebase-intel/references/files-in-dw-intel-detail.md +16 -0
  77. package/scaffold/skills/dw-codebase-intel/references/how-dw-intel-reads-this-detail.md +12 -0
  78. package/scaffold/skills/dw-codebase-intel/references/how-to-compose-the-typical-flow-detail.md +11 -0
  79. package/scaffold/skills/dw-council/SKILL.md +2 -17
  80. package/scaffold/skills/dw-council/references/integration-with-other-dw-commands-detail.md +7 -0
  81. package/scaffold/skills/dw-council/references/phase-2-tensions-and-rebuttals-detail.md +15 -0
  82. package/scaffold/skills/dw-domain-modeling/SKILL.md +1 -1
  83. package/scaffold/skills/dw-execute-phase/SKILL.md +12 -32
  84. package/scaffold/skills/dw-execute-phase/agents/executor.md +15 -252
  85. package/scaffold/skills/dw-execute-phase/agents/plan-checker.md +4 -207
  86. package/scaffold/skills/dw-execute-phase/references/atomic-commits.md +8 -18
  87. package/scaffold/skills/dw-execute-phase/references/de-sloppify-pass-optional-cleanup-task-detail.md +12 -0
  88. package/scaffold/skills/dw-execute-phase/references/deviation-rules-during-execution-detail.md +8 -0
  89. package/scaffold/skills/dw-execute-phase/references/how-the-two-agents-compose-detail.md +7 -0
  90. package/scaffold/skills/dw-execute-phase/references/plan-verification.md +9 -155
  91. package/scaffold/skills/dw-execute-phase/references/wave-coordination.md +6 -97
  92. package/scaffold/skills/dw-git-discipline/SKILL.md +2 -2
  93. package/scaffold/skills/dw-grilling/SKILL.md +1 -1
  94. package/scaffold/skills/dw-incident-response/SKILL.md +1 -64
  95. package/scaffold/skills/dw-incident-response/references/the-five-phases-detail.md +66 -0
  96. package/scaffold/skills/dw-llm-eval/SKILL.md +5 -53
  97. package/scaffold/skills/dw-llm-eval/references/agent-tool-use-evaluation-detail.md +23 -0
  98. package/scaffold/skills/dw-llm-eval/references/anti-patterns-will-block-in-dw-review-code-only-detail.md +9 -0
  99. package/scaffold/skills/dw-llm-eval/references/consistency-run-to-run-stability-detail.md +10 -0
  100. package/scaffold/skills/dw-llm-eval/references/integration-with-dev-workflow-commands-detail.md +6 -0
  101. package/scaffold/skills/dw-llm-eval/references/the-oracle-ladder-detail.md +15 -0
  102. package/scaffold/skills/dw-memory/SKILL.md +4 -50
  103. package/scaffold/skills/dw-memory/references/context-budget.md +8 -56
  104. package/scaffold/skills/dw-memory/references/promotion-decision-test-detail.md +30 -0
  105. package/scaffold/skills/dw-minimalism/SKILL.md +4 -5
  106. package/scaffold/skills/dw-review-rigor/SKILL.md +1 -54
  107. package/scaffold/skills/dw-review-rigor/references/the-five-rules-detail.md +56 -0
  108. package/scaffold/skills/dw-simplification/SKILL.md +2 -55
  109. package/scaffold/skills/dw-simplification/references/pattern-recognition-detail.md +11 -0
  110. package/scaffold/skills/dw-simplification/references/the-five-rules-detail.md +48 -0
  111. package/scaffold/skills/dw-source-grounding/SKILL.md +1 -56
  112. package/scaffold/skills/dw-source-grounding/references/the-protocol-detect-fetch-implement-cite-detail.md +58 -0
  113. package/scaffold/skills/dw-testing-discipline/SKILL.md +25 -177
  114. package/scaffold/skills/dw-testing-discipline/references/agent-guardrails.md +9 -167
  115. package/scaffold/skills/dw-testing-discipline/references/core-rules.md +3 -3
  116. package/scaffold/skills/dw-testing-discipline/references/mutation-testing.md +19 -0
  117. package/scaffold/skills/dw-testing-discipline/references/patterns.md +3 -12
  118. package/scaffold/skills/dw-ui-discipline/SKILL.md +2 -59
  119. package/scaffold/skills/dw-ui-discipline/references/frontend-engineering.md +46 -0
  120. package/scaffold/skills/dw-ui-discipline/references/the-four-grounding-questions-detail.md +61 -0
  121. package/scaffold/skills/dw-verify/SKILL.md +26 -148
  122. package/scaffold/skills/dw-verify/references/verification-discovery-and-attribution.md +2 -2
  123. package/scaffold/skills/humanizer/SKILL.md +2 -1
  124. package/scaffold/skills/security-review/SKILL.md +3 -183
  125. package/scaffold/skills/security-review/references/do-not-flag-detail.md +49 -0
  126. package/scaffold/skills/security-review/references/quick-patterns-reference-detail.md +56 -0
  127. package/scaffold/skills/security-review/references/review-process-detail.md +84 -0
  128. package/scaffold/skills/vercel-react-best-practices/SKILL.md +1 -90
  129. package/scaffold/skills/vercel-react-best-practices/references/quick-reference-detail.md +92 -0
@@ -1,72 +1,52 @@
1
1
  ---
2
2
  type: task
3
- schema_version: "1.0"
3
+ schema_version: "1.1"
4
4
  status: pending
5
5
  ---
6
6
 
7
7
  # Tarefa X.0: [Título da Tarefa Principal]
8
8
 
9
- <critical>Ler os arquivos de prd.md e techspec.md desta pasta, se você não ler esses arquivos sua tarefa será invalidada</critical>
9
+ Leia as seções relevantes do PRD/TechSpec e as restrições da task; use os links abaixo.
10
10
 
11
11
  ## Visão Geral
12
12
 
13
13
  [Breve descrição da tarefa]
14
14
 
15
- **Requisitos Funcionais cobertos**: RF-X.Y, RF-X.Z (máximo 2 por task)
15
+ **Requisitos Funcionais cobertos**: RF-X.Y, RF-X.Z
16
16
  Depends on: none
17
17
 
18
18
  <requirements>
19
19
  [Lista de requisitos obrigatórios]
20
20
  </requirements>
21
21
 
22
- ## Subtarefas
22
+ ## Escolha de execução
23
23
 
24
- ### Implementação
25
- - [ ] X.1 [Descrição da subtarefa]
26
- - [ ] X.2 [Descrição da subtarefa]
24
+ Espelhe a entrada aprovada desta task em `execution-plan.json` (veja `.dw/references/execution-contract.md`).
27
25
 
28
- ### Testes Unitários (Obrigatório para Backend)
29
- - [ ] X.3 Criar testes para [service/use-case]
30
- - [ ] X.4 Criar testes para [controller/adapter]
26
+ | Complexidade + justificativa | Ferramenta | Modelo / esforço | Agentes | Fallbacks aprovados |
27
+ |---|---|---|---|---|
28
+ | standard — [motivo] | local | inherit / inherit | nenhum | nenhum |
31
29
 
32
- ## Testes Unitários
30
+ ## Implementação
33
31
 
34
- ### Casos a Testar
32
+ - [ ] [Comportamento a entregar]
33
+ - [ ] [Verificações relevantes e critérios de aceitação]
35
34
 
36
- | Método | Casos |
37
- |--------|-------|
38
- | `[método1]` | Happy path, edge case, erro |
39
- | `[método2]` | Happy path, not found |
35
+ ## Verificação e critérios de sucesso
40
36
 
41
- ### Mocks Necessários
42
- - `[repositório/service]` - mockado via mock function
37
+ | Comportamento / risco | Suíte existente ou novo teste | Comando / evidência observável |
38
+ |---|---|---|
39
+ | [Resultado exigido] | [Menor camada eficaz; teste novo só se necessário] | [Comando do projeto ou inspeção] |
43
40
 
44
- ## Detalhes de Implementação
41
+ Use a estratégia de testes do projeto. Defina mocks só em fronteiras justificadas; não imponha percentuais de cobertura nem teste novo para toda edição. Inclua falhas relevantes quando aplicável.
45
42
 
46
- [Seções relevantes da spec técnica - referencie a techspec.md ao invés de duplicar conteúdo]
43
+ ## Arquivos e decisões relevantes
47
44
 
48
- ## Critérios de Sucesso
45
+ [Caminhos de código e seções relevantes do TechSpec/ADR; não duplique documentos inteiros.]
49
46
 
50
- - [Resultados mensuráveis]
51
- - [Requisitos de qualidade]
52
- - **Testes unitários passando**
53
- - **Cobertura mínima 80%** em services/use-cases
47
+ ## Commit ao concluir
54
48
 
55
- ## Arquivos Relevantes
56
- - [Arquivos relevantes desta tarefa]
57
- - [Arquivo].spec.ts - Testes unitários
58
-
59
- ## Commit ao Final
60
-
61
- Ao completar esta task, fazer commit:
62
- ```bash
63
- git add .
64
- git commit -m "feat([modulo]): [descrição]
65
-
66
- - [item 1]
67
- - [item 2]
68
- - Add unit tests"
69
- ```
49
+ Use o protocolo de commit atômico com escopo do `/dw-run`. Faça stage apenas dos arquivos desta task, preserve IDs de requisitos, registre o SHA resultante em tasks.md/run-log e inclua os registros finais antes da entrega. Não implica push nem merge.
70
50
 
71
51
  ## Related ADRs
72
52
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  type: tasks-index
3
- schema_version: "1.0"
3
+ schema_version: "1.1"
4
4
  status: draft
5
5
  ---
6
6
 
@@ -34,10 +34,13 @@ feat/prd-[nome-funcionalidade]
34
34
  - [ ] 2.0 Título da Tarefa Principal Depends on: 1.0
35
35
  - [ ] 3.0 Título da Tarefa Principal Depends on: 1.0, 2.0
36
36
 
37
+ ## Plano de execução
38
+
39
+ Proponha desenvolvimento local ou cruzado por task na quebra. Resuma complexidade/justificativa, ferramenta, modelo/esforço, agentes, dependências e verificação. Salve escolhas validadas e fallbacks aprovados em `execution-plan.json`; use `.dw/references/execution-contract.md`. Registre aprovação da mesma matriz antes de executar.
40
+
37
41
  ## Workflow
38
42
 
39
- Cada task segue o fluxo:
40
- 1. `/dw-run [N]_task.md` - Implementa a task
41
- 2. Testes unitários incluídos na implementação
42
- 3. Commit ao final da task (sem push)
43
- 4. Próxima task ou `/dw-generate-pr [branch-alvo]` quando todas concluídas
43
+ 1. `/dw-run` consome escolhas aprovadas em ordem de dependências.
44
+ 2. Cada task implementa, verifica e commita mudanças no escopo; o parent revisa handoffs externos e encaminha correções.
45
+ 3. Continue implementação aprovada até review final e QA aplicável. Pedido somente de planejamento termina no plano.
46
+ 4. Prepare entrega validada; integre/envie/publique só dentro da autorização existente.
@@ -78,6 +78,10 @@ type NomeServico interface {
78
78
 
79
79
  ## Sequenciamento de Desenvolvimento
80
80
 
81
+ ### Qualidade do Frontend (quando aplicável)
82
+
83
+ [Leia a baseline de qualidade existente do módulo. Use linhas relevantes de `.dw/templates/frontend-quality-template.md` para contratos de API, tipos, limites de imports ou ferramentas de qualidade alterados. Registre fontes autoritativas, checks exatos, política atual, adoção proposta e evidência comportamental. Separe diagnósticos consultivos de gates obrigatórios; não transforme uma funcionalidade de UI em migração de ferramentas do repositório inteiro.]
84
+
81
85
  ### Ordem de Construção
82
86
 
83
87
  [Defina sequência de implementação:
@@ -23,6 +23,7 @@ export const DANGEROUS = [
23
23
  { re: /\bgit\s+reset\b[^\n|&;]*--hard\b/, why: 'hard reset discards uncommitted work and rewrites the branch' },
24
24
  { re: /\bgit\s+clean\b[^\n|&;]*-[a-z]*f/, why: 'git clean -f permanently deletes untracked files' },
25
25
  { re: /\bgit\s+branch\b[^\n|&;]*\s-D\b/, why: 'force-deletes a branch that may be unmerged' },
26
+ { re: /\bgit\s+worktree\s+remove\b[^\n|&;]*(--force\b|\s-f\b)/, why: 'force-removes a worktree that may hold uncommitted work — commit first or use /dw-worktree clean (never --force)' },
26
27
  { re: /\bgit\s+checkout\b[^\n|&;]*\s(--\s+\.|\.\s*$)/, why: 'discards all local changes in the working tree' },
27
28
  { re: /\bgit\s+restore\b[^\n|&;]*\s(--\s+)?\.(?=\s*(?:$|[|&;]))/, why: 'discards all local changes in the working tree' },
28
29
  ];
@@ -0,0 +1,101 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { resolve } from 'node:path';
4
+
5
+ const tools = new Set(['local', 'codex', 'claude', 'copilot']);
6
+ const tiers = new Set(['light', 'standard', 'heavy']);
7
+
8
+ // A small executable contract for the agent-authored execution-plan.json.
9
+ // This validates assignments, not account access or authorization on its own.
10
+ export function validatePlan(plan) {
11
+ const issues = [];
12
+ if (!plan || !['1.0', '1.1'].includes(plan.schema_version)) return ['Unsupported execution plan schema'];
13
+ if (!Array.isArray(plan.tasks) || !plan.tasks.length) return ['tasks must be a nonempty array'];
14
+ if (typeof plan.approved !== 'boolean') issues.push('approved must be a boolean');
15
+ const ids = new Set();
16
+ for (const task of plan.tasks) {
17
+ if (!task || typeof task.id !== 'string' || !task.id.trim()) {
18
+ issues.push('Every task needs a nonempty string id');
19
+ continue;
20
+ }
21
+ if (ids.has(task.id)) issues.push(`Duplicate task ${task.id}`);
22
+ ids.add(task.id);
23
+ if (!Array.isArray(task.depends_on) || task.depends_on.some(id => typeof id !== 'string')) issues.push(`${task.id}: depends_on must be a string array`);
24
+ if (plan.schema_version === '1.1' && !task.execution) issues.push(`${task.id}: missing execution assignment`);
25
+ if (task.execution) {
26
+ const e = task.execution;
27
+ if (typeof e !== 'object' || Array.isArray(e)) { issues.push(`${task.id}: execution must be an object`); continue; }
28
+ if (!tiers.has(e.complexity)) issues.push(`${task.id}: invalid complexity`);
29
+ if (typeof e.rationale !== 'string' || !e.rationale.trim()) issues.push(`${task.id}: missing rationale`);
30
+ if (!Array.isArray(e.agents) || e.agents.some(a => typeof a !== 'string')) issues.push(`${task.id}: agents must be a string array`);
31
+ for (const assignment of [e, ...(Array.isArray(e.fallbacks) ? e.fallbacks : [])]) {
32
+ if (!assignment || typeof assignment !== 'object' || Array.isArray(assignment)) { issues.push(`${task.id}: invalid fallback assignment`); continue; }
33
+ if (!tools.has(assignment.tool)) issues.push(`${task.id}: invalid tool`);
34
+ if (typeof assignment.model !== 'string' || !assignment.model.trim()) issues.push(`${task.id}: missing model`);
35
+ if (typeof assignment.effort !== 'string' || !assignment.effort.trim()) issues.push(`${task.id}: missing effort`);
36
+ if (assignment.tool !== 'local' && [assignment.model, assignment.effort].includes('inherit')) issues.push(`${task.id}: external assignments must resolve model and effort`);
37
+ }
38
+ if (e.fallbacks !== undefined && !Array.isArray(e.fallbacks)) issues.push(`${task.id}: fallbacks must be an array`);
39
+ }
40
+ }
41
+ const tasks = new Map(plan.tasks.filter(t => t?.id).map(t => [t.id, t]));
42
+ const visiting = new Set(), visited = new Set();
43
+ function visit(id) {
44
+ if (visiting.has(id)) { issues.push(`Dependency cycle at ${id}`); return; }
45
+ if (visited.has(id)) return;
46
+ visiting.add(id);
47
+ for (const dep of tasks.get(id)?.depends_on || []) {
48
+ if (!ids.has(dep)) issues.push(`${id}: unknown dependency ${dep}`);
49
+ else visit(dep);
50
+ }
51
+ visiting.delete(id); visited.add(id);
52
+ }
53
+ if (!issues.length) for (const id of ids) visit(id);
54
+ return issues;
55
+ }
56
+
57
+ export function resolveAssignment(plan, taskId, availableTools) {
58
+ const issues = validatePlan(plan);
59
+ if (issues.length) throw new Error(issues.join('; '));
60
+ if (plan.approved !== true) throw new Error('Execution plan is not approved');
61
+ const task = plan.tasks.find(t => t.id === taskId);
62
+ if (!task) throw new Error(`Unknown task ${taskId}`);
63
+ // Legacy plans never imply permission to start another CLI.
64
+ const assignment = task.execution || { tool: 'local', model: 'inherit', effort: 'inherit', agents: [] };
65
+ const candidates = [assignment, ...(assignment.fallbacks || [])];
66
+ const chosen = candidates.find(c => availableTools.includes(c.tool));
67
+ if (!chosen) throw new Error(`No approved executor available for ${taskId}`);
68
+ return { ...chosen, agents: assignment.agents || [], fallback: chosen !== assignment };
69
+ }
70
+
71
+ export function readyTasks(plan, completedIds) {
72
+ const issues = validatePlan(plan);
73
+ if (issues.length) throw new Error(issues.join('; '));
74
+ const done = new Set(completedIds);
75
+ return plan.tasks.filter(t => !done.has(t.id) && t.depends_on.every(id => done.has(id))).map(t => t.id);
76
+ }
77
+
78
+ // Callers fingerprint actual inputs (including relevant untracked files) and
79
+ // environment. Unknown values fail closed. Time/message boundaries are irrelevant.
80
+ export function reusableEvidence(evidence, current) {
81
+ if (!evidence || evidence.exit_code !== 0 || !current) return false;
82
+ for (const key of ['command', 'input_fingerprint', 'environment_fingerprint']) {
83
+ if (typeof current[key] !== 'string' || !current[key] || evidence[key] !== current[key]) return false;
84
+ }
85
+ return Array.isArray(current.scope) && current.scope.length > 0 && Array.isArray(evidence.scope)
86
+ && current.scope.every(item => evidence.scope.includes(item));
87
+ }
88
+
89
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
90
+ try {
91
+ const [mode, file, taskId, available = 'local'] = process.argv.slice(2);
92
+ if (!['validate', 'resolve', 'ready'].includes(mode) || !file) throw new Error('Usage: workflow-contract.mjs validate|resolve|ready <plan.json> [task-id|completed-csv] [available-tools-csv]');
93
+ const plan = JSON.parse(readFileSync(file, 'utf8'));
94
+ if (mode === 'validate') {
95
+ const issues = validatePlan(plan);
96
+ console.log(JSON.stringify({ status: issues.length ? 'BLOCKED' : 'PASS', issues }));
97
+ if (issues.length) process.exitCode = 1;
98
+ } else if (mode === 'resolve') console.log(JSON.stringify(resolveAssignment(plan, taskId, available.split(','))));
99
+ else console.log(JSON.stringify(readyTasks(plan, taskId ? taskId.split(',') : [])));
100
+ } catch (error) { console.error(error.message); process.exitCode = 1; }
101
+ }