@davidorex/pi-workflows 0.6.1 → 0.9.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 (69) hide show
  1. package/README.md +1 -1
  2. package/agents/audit-finding-verifier.agent.yaml +40 -0
  3. package/agents/audit-results-router.agent.yaml +30 -0
  4. package/agents/gap-resolution-assessor.agent.yaml +40 -0
  5. package/dist/dag.d.ts +13 -2
  6. package/dist/dag.d.ts.map +1 -1
  7. package/dist/dag.js +43 -15
  8. package/dist/dag.js.map +1 -1
  9. package/dist/expression.d.ts.map +1 -1
  10. package/dist/expression.js +6 -0
  11. package/dist/expression.js.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +10 -3
  14. package/dist/index.js.map +1 -1
  15. package/dist/state.d.ts.map +1 -1
  16. package/dist/state.js +14 -1
  17. package/dist/state.js.map +1 -1
  18. package/dist/step-agent.d.ts.map +1 -1
  19. package/dist/step-agent.js +7 -2
  20. package/dist/step-agent.js.map +1 -1
  21. package/dist/step-block.d.ts +18 -0
  22. package/dist/step-block.d.ts.map +1 -0
  23. package/dist/step-block.js +204 -0
  24. package/dist/step-block.js.map +1 -0
  25. package/dist/step-foreach.d.ts.map +1 -1
  26. package/dist/step-foreach.js +5 -0
  27. package/dist/step-foreach.js.map +1 -1
  28. package/dist/step-monitor.d.ts.map +1 -1
  29. package/dist/step-monitor.js +15 -4
  30. package/dist/step-monitor.js.map +1 -1
  31. package/dist/template-validation.d.ts +25 -0
  32. package/dist/template-validation.d.ts.map +1 -0
  33. package/dist/template-validation.js +341 -0
  34. package/dist/template-validation.js.map +1 -0
  35. package/dist/tui.d.ts.map +1 -1
  36. package/dist/tui.js +14 -0
  37. package/dist/tui.js.map +1 -1
  38. package/dist/types.d.ts +33 -0
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/workflow-discovery.js +2 -1
  41. package/dist/workflow-discovery.js.map +1 -1
  42. package/dist/workflow-executor.d.ts +12 -0
  43. package/dist/workflow-executor.d.ts.map +1 -1
  44. package/dist/workflow-executor.js +32 -6
  45. package/dist/workflow-executor.js.map +1 -1
  46. package/dist/workflow-sdk.d.ts +1 -0
  47. package/dist/workflow-sdk.d.ts.map +1 -1
  48. package/dist/workflow-sdk.js +12 -0
  49. package/dist/workflow-sdk.js.map +1 -1
  50. package/dist/workflow-spec.d.ts.map +1 -1
  51. package/dist/workflow-spec.js +147 -60
  52. package/dist/workflow-spec.js.map +1 -1
  53. package/package.json +7 -8
  54. package/schemas/audit-routing-manifest.schema.json +38 -0
  55. package/schemas/finding-verification.schema.json +34 -0
  56. package/schemas/resolution-assessment.schema.json +36 -0
  57. package/skills/pi-workflows/SKILL.md +1 -1
  58. package/skills/pi-workflows/references/bundled-resources.md +12 -3
  59. package/templates/audit-finding-verifier/task.md +59 -0
  60. package/templates/audit-results-router/task.md +37 -0
  61. package/templates/gap-resolution-assessor/task.md +48 -0
  62. package/templates/handoff-writer/task.md +16 -6
  63. package/templates/phase-author/task.md +8 -0
  64. package/workflows/create-handoff.workflow.yaml +56 -35
  65. package/workflows/create-phase.workflow.yaml +27 -32
  66. package/workflows/do-gap.workflow.yaml +47 -27
  67. package/workflows/fix-audit.workflow.yaml +89 -127
  68. package/workflows/gap-to-phase.workflow.yaml +47 -42
  69. package/workflows/plan-from-requirements.workflow.yaml +16 -27
@@ -17,45 +17,45 @@ input:
17
17
  value: id
18
18
 
19
19
  steps:
20
+ load-gap-blocks:
21
+ block:
22
+ read: gaps
23
+ output:
24
+ format: json
25
+
20
26
  load-gap:
21
27
  command: |
22
- node --experimental-strip-types -e "
23
- import fs from 'fs';
24
- const gapId = process.argv[1];
25
- const data = JSON.parse(fs.readFileSync('.project/gaps.json', 'utf8'));
26
- const gap = data.gaps.find(g => g.id === gapId);
28
+ node -e "
29
+ const gaps = JSON.parse(process.argv[1]);
30
+ const gapId = process.argv[2];
31
+ const gap = gaps.gaps.find(g => g.id === gapId);
27
32
  if (!gap) { console.error('Gap not found: ' + gapId); process.exit(1); }
28
- if (gap.status === 'resolved') { console.error('Gap already resolved: ' + gapId); process.exit(1); }
33
+ if (gap.status === 'resolved') { console.error('Gap already resolved'); process.exit(1); }
29
34
  console.log(JSON.stringify({ gap }));
30
- " '${{ input.gap_id }}'
35
+ " '${{ steps.load-gap-blocks.output | json }}' '${{ input.gap_id }}'
31
36
  output:
32
37
  format: json
33
38
 
34
- load-context:
35
- command: |
36
- node --experimental-strip-types -e "
37
- import fs from 'fs';
38
- import path from 'path';
39
-
40
- const phases = [];
41
- const phasesDir = '.project/phases';
42
- if (fs.existsSync(phasesDir)) {
43
- for (const f of fs.readdirSync(phasesDir).filter(f => f.endsWith('.json')).sort()) {
44
- phases.push(JSON.parse(fs.readFileSync(path.join(phasesDir, f), 'utf8')));
45
- }
46
- }
39
+ load-phases:
40
+ block:
41
+ readDir: phases
42
+ output:
43
+ format: json
47
44
 
48
- let architecture = {};
49
- try { architecture = JSON.parse(fs.readFileSync('.project/architecture.json', 'utf8')); } catch {}
50
- let conventions = {};
51
- try { conventions = JSON.parse(fs.readFileSync('.project/conventions.json', 'utf8')); } catch {}
52
- let gaps = { gaps: [] };
53
- try { gaps = JSON.parse(fs.readFileSync('.project/gaps.json', 'utf8')); } catch {}
54
- let inventory = {};
55
- try { inventory = JSON.parse(fs.readFileSync('.project/inventory.json', 'utf8')); } catch {}
45
+ load-context:
46
+ block:
47
+ read: [architecture, conventions, gaps, inventory]
48
+ optional: [architecture, conventions, inventory]
49
+ output:
50
+ format: json
56
51
 
57
- console.log(JSON.stringify({ phases, architecture, conventions, gaps: gaps.gaps.filter(g => g.status === 'open'), inventory }));
58
- "
52
+ filter-gaps:
53
+ command: |
54
+ node -e "
55
+ const data = JSON.parse(process.argv[1]);
56
+ const open = (data.gaps || []).filter(g => g.status === 'open');
57
+ console.log(JSON.stringify(open));
58
+ " '${{ steps.load-context.output.gaps | json }}'
59
59
  output:
60
60
  format: json
61
61
 
@@ -64,34 +64,39 @@ steps:
64
64
  input:
65
65
  intent: "Implement gap ${{ steps.load-gap.output.gap.id }}: ${{ steps.load-gap.output.gap.description }}"
66
66
  gap: "${{ steps.load-gap.output.gap }}"
67
- phases: "${{ steps.load-context.output.phases }}"
67
+ phases: "${{ steps.load-phases.output }}"
68
68
  architecture: "${{ steps.load-context.output.architecture }}"
69
69
  conventions: "${{ steps.load-context.output.conventions }}"
70
- gaps: "${{ steps.load-context.output.gaps }}"
70
+ gaps: "${{ steps.filter-gaps.output }}"
71
71
  inventory: "${{ steps.load-context.output.inventory }}"
72
72
  output:
73
73
  format: json
74
74
  schema: block:phase
75
75
 
76
- write-phase:
76
+ compute-phase-path:
77
77
  command: |
78
- node --experimental-strip-types -e "
79
- import fs from 'fs';
78
+ node -e "
80
79
  const phase = JSON.parse(process.argv[1]);
81
80
  const num = String(phase.number).padStart(2, '0');
82
- const name = phase.name.toLowerCase().replace(/\s+/g, '-');
83
- const filename = '.project/phases/' + num + '-' + name + '.json';
84
- fs.mkdirSync('.project/phases', { recursive: true });
85
- fs.writeFileSync(filename, JSON.stringify(phase, null, 2));
86
- console.log(JSON.stringify({ path: filename, phase_number: phase.number, spec_count: (phase.specs || []).length }));
81
+ const name = phase.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/-+$/g, '');
82
+ console.log(JSON.stringify({ path: 'phases/' + num + '-' + name }));
87
83
  " '${{ steps.author.output | json }}'
88
84
  output:
89
85
  format: json
90
86
 
87
+ write-phase:
88
+ block:
89
+ write:
90
+ name: phase
91
+ data: "${{ steps.author.output }}"
92
+ path: "${{ steps.compute-phase-path.output.path }}"
93
+ output:
94
+ format: json
95
+
91
96
  completion:
92
97
  message: |
93
- Phase ${{ steps.write-phase.output.phase_number }} created: ${{ steps.write-phase.output.path }}
94
- Specs: ${{ steps.write-phase.output.spec_count }}
98
+ Phase ${{ steps.author.output.number }} created: ${{ steps.write-phase.output.path }}
99
+ Specs: ${{ steps.author.output.specs | length }}
95
100
  From gap: ${{ input.gap_id }}
96
101
  include:
97
102
  - steps.author.output
@@ -3,33 +3,22 @@ description: Decompose accepted requirements into phases and tasks
3
3
  version: "1"
4
4
 
5
5
  steps:
6
- load-context:
7
- command: |
8
- node -e "
9
- const fs = require('fs');
10
- const path = require('path');
11
- const projectDir = '.project';
12
- const context = {};
13
-
14
- // Read requirements
15
- try { context.requirements = JSON.parse(fs.readFileSync(path.join(projectDir, 'requirements.json'), 'utf-8')); } catch { context.requirements = { requirements: [] }; }
16
-
17
- // Read architecture
18
- try { context.architecture = JSON.parse(fs.readFileSync(path.join(projectDir, 'architecture.json'), 'utf-8')); } catch { context.architecture = null; }
19
-
20
- // Read project identity
21
- try { context.project = JSON.parse(fs.readFileSync(path.join(projectDir, 'project.json'), 'utf-8')); } catch { context.project = null; }
6
+ load-requirements:
7
+ block:
8
+ read: requirements
9
+ output:
10
+ format: json
22
11
 
23
- // Read existing phases
24
- try {
25
- const phasesDir = path.join(projectDir, 'phases');
26
- context.existing_phases = fs.readdirSync(phasesDir).filter(f => f.endsWith('.json')).map(f => {
27
- try { return JSON.parse(fs.readFileSync(path.join(phasesDir, f), 'utf-8')); } catch { return null; }
28
- }).filter(Boolean);
29
- } catch { context.existing_phases = []; }
12
+ load-context:
13
+ block:
14
+ read: [architecture, project]
15
+ optional: [architecture, project]
16
+ output:
17
+ format: json
30
18
 
31
- console.log(JSON.stringify(context));
32
- "
19
+ load-phases:
20
+ block:
21
+ readDir: phases
33
22
  output:
34
23
  format: json
35
24
 
@@ -37,9 +26,9 @@ steps:
37
26
  agent: plan-creator
38
27
  input:
39
28
  project: ${{ steps.load-context.output.project }}
40
- requirements: ${{ steps.load-context.output.requirements }}
29
+ requirements: ${{ steps.load-requirements.output }}
41
30
  architecture: ${{ steps.load-context.output.architecture }}
42
- existing_phases: ${{ steps.load-context.output.existing_phases }}
31
+ existing_phases: ${{ steps.load-phases.output }}
43
32
  output:
44
33
  format: json
45
34
  schema: block:tasks