@xn-intenton-z2a/agentic-lib 7.4.39 → 7.4.41

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.
@@ -84,27 +84,49 @@ env:
84
84
  jobs:
85
85
  params:
86
86
  runs-on: ubuntu-latest
87
+ outputs:
88
+ model: ${{ steps.resolve.outputs.model }}
89
+ dry-run: ${{ steps.resolve.outputs.dry-run }}
90
+ discussion-url: ${{ steps.resolve.outputs.discussion-url }}
91
+ message: ${{ steps.resolve.outputs.message }}
87
92
  steps:
88
93
  - uses: actions/checkout@v6
89
94
  with:
90
95
  ref: ${{ inputs.ref || github.ref }}
91
96
  sparse-checkout: ${{ env.configPath }}
92
97
  sparse-checkout-cone-mode: false
93
- - name: Normalise params
94
- id: normalise
95
- shell: bash
96
- run: |
97
- MODEL='${{ inputs.model }}'
98
- if [ -z "$MODEL" ] && [ -f "${{ env.configPath }}" ]; then
99
- TOML_MODEL=$(grep '^\s*model' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/')
100
- MODEL="${TOML_MODEL}"
101
- fi
102
- echo "model=${MODEL:-gpt-5-mini}" >> $GITHUB_OUTPUT
103
- DRY_RUN='${{ inputs.dry-run }}'
104
- echo "dry-run=${DRY_RUN:-true}" >> $GITHUB_OUTPUT
105
- outputs:
106
- model: ${{ steps.normalise.outputs.model }}
107
- dry-run: ${{ steps.normalise.outputs.dry-run }}
98
+ - id: resolve
99
+ uses: actions/github-script@v8
100
+ with:
101
+ script: |
102
+ const fs = require('fs');
103
+ const configPath = '${{ env.configPath }}';
104
+ let toml = '';
105
+ if (fs.existsSync(configPath)) toml = fs.readFileSync(configPath, 'utf8');
106
+ const readToml = (key) => {
107
+ const m = toml.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, 'm'));
108
+ return m ? m[1] : '';
109
+ };
110
+ const resolve = (name, input, configKey, defaultValue) => {
111
+ let value = input || '';
112
+ let source = 'input';
113
+ if (!value && configKey) {
114
+ value = readToml(configKey);
115
+ source = value ? 'config' : '';
116
+ }
117
+ if (!value) {
118
+ value = defaultValue;
119
+ source = 'default';
120
+ }
121
+ const configVal = configKey ? readToml(configKey) : 'N/A';
122
+ core.info(`param ${name}: input='${input}' config='${configVal}' default='${defaultValue}' → '${value}' (source: ${source})`);
123
+ core.setOutput(name, value);
124
+ return value;
125
+ };
126
+ resolve('model', '${{ inputs.model }}', 'model', 'gpt-5-mini');
127
+ resolve('dry-run', '${{ inputs.dry-run }}', null, 'true');
128
+ resolve('discussion-url', '${{ inputs.discussion-url }}', null, '');
129
+ resolve('message', '${{ inputs.message }}', null, '');
108
130
 
109
131
  respond:
110
132
  needs: params
@@ -11,6 +11,60 @@ name: agentic-lib-flow
11
11
  run-name: "agentic-lib-flow [${{ github.ref_name }}] ${{ inputs.mission-seed }} (${{ inputs.workflow-runs }} runs)"
12
12
 
13
13
  on:
14
+ workflow_call:
15
+ inputs:
16
+ mode:
17
+ type: string
18
+ required: false
19
+ default: "purge"
20
+ mission-seed:
21
+ type: string
22
+ required: false
23
+ default: "7-kyu-understand-fizz-buzz"
24
+ model:
25
+ type: string
26
+ required: false
27
+ default: "gpt-5-mini"
28
+ profile:
29
+ type: string
30
+ required: false
31
+ default: "max"
32
+ workflow-runs:
33
+ type: string
34
+ required: false
35
+ default: "4"
36
+ schedule:
37
+ type: string
38
+ required: false
39
+ default: "off"
40
+ dry-run:
41
+ type: string
42
+ required: false
43
+ default: "false"
44
+ message:
45
+ type: string
46
+ required: false
47
+ default: ""
48
+ config-path:
49
+ type: string
50
+ required: false
51
+ default: ""
52
+ skipMaintain:
53
+ type: string
54
+ required: false
55
+ default: "false"
56
+ mission-text:
57
+ type: string
58
+ required: false
59
+ default: ""
60
+ create-seed-issues:
61
+ type: string
62
+ required: false
63
+ default: "false"
64
+ skip-tests:
65
+ type: string
66
+ required: false
67
+ default: "true"
14
68
  workflow_dispatch:
15
69
  inputs:
16
70
  mode:
@@ -88,29 +142,118 @@ on:
88
142
  - "weekly"
89
143
  - "daily"
90
144
  - "hourly"
145
+ dry-run:
146
+ description: "Skip all push/PR/merge operations"
147
+ type: boolean
148
+ required: false
149
+ default: false
150
+ message:
151
+ description: "Context message for supervisor/bot"
152
+ type: string
153
+ required: false
154
+ default: ""
155
+ config-path:
156
+ description: "Config file path (default: agentic-lib.toml)"
157
+ type: string
158
+ required: false
159
+ default: ""
160
+ skipMaintain:
161
+ description: "Skip maintain job in workflow runs"
162
+ type: boolean
163
+ required: false
164
+ default: false
91
165
 
92
166
  permissions: write-all
93
167
 
94
168
  jobs:
169
+ # ── Params: normalise all inputs ─────────────────────────────────
170
+ params:
171
+ runs-on: ubuntu-latest
172
+ outputs:
173
+ mode: ${{ steps.resolve.outputs.mode }}
174
+ mission-seed: ${{ steps.resolve.outputs.mission-seed }}
175
+ mission-text: ${{ steps.resolve.outputs.mission-text }}
176
+ model: ${{ steps.resolve.outputs.model }}
177
+ profile: ${{ steps.resolve.outputs.profile }}
178
+ workflow-runs: ${{ steps.resolve.outputs.workflow-runs }}
179
+ schedule: ${{ steps.resolve.outputs.schedule }}
180
+ dry-run: ${{ steps.resolve.outputs.dry-run }}
181
+ message: ${{ steps.resolve.outputs.message }}
182
+ config-path: ${{ steps.resolve.outputs.config-path }}
183
+ skipMaintain: ${{ steps.resolve.outputs.skipMaintain }}
184
+ create-seed-issues: ${{ steps.resolve.outputs.create-seed-issues }}
185
+ skip-tests: ${{ steps.resolve.outputs.skip-tests }}
186
+ steps:
187
+ - uses: actions/checkout@v6
188
+ with:
189
+ sparse-checkout: agentic-lib.toml
190
+ sparse-checkout-cone-mode: false
191
+ - id: resolve
192
+ uses: actions/github-script@v8
193
+ with:
194
+ script: |
195
+ const fs = require('fs');
196
+ const configPath = 'agentic-lib.toml';
197
+ let toml = '';
198
+ if (fs.existsSync(configPath)) toml = fs.readFileSync(configPath, 'utf8');
199
+ const readToml = (key) => {
200
+ const m = toml.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, 'm'));
201
+ return m ? m[1] : '';
202
+ };
203
+ const resolve = (name, input, configKey, defaultValue) => {
204
+ let value = input || '';
205
+ let source = 'input';
206
+ if (!value && configKey) {
207
+ value = readToml(configKey);
208
+ source = value ? 'config' : '';
209
+ }
210
+ if (!value) {
211
+ value = defaultValue;
212
+ source = 'default';
213
+ }
214
+ const configVal = configKey ? readToml(configKey) : 'N/A';
215
+ core.info(`param ${name}: input='${input}' config='${configVal}' default='${defaultValue}' → '${value}' (source: ${source})`);
216
+ core.setOutput(name, value);
217
+ return value;
218
+ };
219
+ resolve('mode', '${{ inputs.mode }}', null, 'purge');
220
+ resolve('mission-seed', '${{ inputs.mission-seed }}', null, '7-kyu-understand-fizz-buzz');
221
+ resolve('mission-text', '${{ inputs.mission-text }}', null, '');
222
+ resolve('model', '${{ inputs.model }}', 'model', 'gpt-5-mini');
223
+ resolve('profile', '${{ inputs.profile }}', 'profile', 'max');
224
+ resolve('workflow-runs', '${{ inputs.workflow-runs }}', null, '4');
225
+ resolve('schedule', '${{ inputs.schedule }}', null, 'off');
226
+ resolve('dry-run', '${{ inputs.dry-run }}', null, 'false');
227
+ resolve('message', '${{ inputs.message }}', null, '');
228
+ resolve('config-path', '${{ inputs.config-path }}', null, 'agentic-lib.toml');
229
+ resolve('skipMaintain', '${{ inputs.skipMaintain }}', null, 'false');
230
+ resolve('create-seed-issues', '${{ inputs.create-seed-issues }}', null, 'false');
231
+ resolve('skip-tests', '${{ inputs.skip-tests }}', null, 'true');
232
+
95
233
  # ── Phase 0: Update agentic-lib package ────────────────────────────
96
234
  update:
97
- if: inputs.mode != 'skip'
235
+ needs: [params]
236
+ if: needs.params.outputs.mode != 'skip'
98
237
  uses: ./.github/workflows/agentic-lib-update.yml
99
238
  with:
100
- skip-tests: 'true'
239
+ skip-tests: ${{ needs.params.outputs.skip-tests }}
240
+ dry-run: ${{ needs.params.outputs.dry-run }}
101
241
  secrets: inherit
102
242
 
103
243
  # ── Phase 0b: Init (purge/reseed/update) ───────────────────────────
104
244
  init:
105
- needs: [update]
106
- if: always() && inputs.mode != 'skip' && (needs.update.result == 'success' || needs.update.result == 'skipped')
245
+ needs: [params, update]
246
+ if: always() && needs.params.outputs.mode != 'skip' && (needs.update.result == 'success' || needs.update.result == 'skipped')
107
247
  uses: ./.github/workflows/agentic-lib-init.yml
108
248
  with:
109
- mode: ${{ inputs.mode }}
110
- mission-seed: ${{ inputs.mission-seed }}
111
- model: ${{ inputs.model }}
112
- profile: ${{ inputs.profile }}
113
- schedule: ${{ inputs.schedule }}
249
+ mode: ${{ needs.params.outputs.mode }}
250
+ mission-seed: ${{ needs.params.outputs.mission-seed }}
251
+ mission-text: ${{ needs.params.outputs.mission-text }}
252
+ model: ${{ needs.params.outputs.model }}
253
+ profile: ${{ needs.params.outputs.profile }}
254
+ schedule: ${{ needs.params.outputs.schedule }}
255
+ dry-run: ${{ needs.params.outputs.dry-run }}
256
+ create-seed-issues: ${{ needs.params.outputs.create-seed-issues }}
114
257
  secrets: inherit
115
258
 
116
259
  # ── Round 1: test + bot + up to 4 workflow runs ────────────────────
@@ -124,6 +267,9 @@ jobs:
124
267
  needs: [test-1]
125
268
  if: always() && needs.test-1.result == 'success'
126
269
  uses: ./.github/workflows/agentic-lib-bot.yml
270
+ with:
271
+ model: ${{ inputs.model }}
272
+ message: ${{ inputs.message }}
127
273
  secrets: inherit
128
274
 
129
275
  check-1:
@@ -150,6 +296,13 @@ jobs:
150
296
  needs: [check-1]
151
297
  if: always() && needs.check-1.result == 'success' && needs.check-1.outputs.mission-over != 'true' && inputs.workflow-runs >= 1
152
298
  uses: ./.github/workflows/agentic-lib-workflow.yml
299
+ with:
300
+ model: ${{ inputs.model }}
301
+ profile: ${{ inputs.profile }}
302
+ dry-run: ${{ inputs.dry-run || 'false' }}
303
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
304
+ config-path: ${{ inputs.config-path }}
305
+ message: ${{ inputs.message }}
153
306
  secrets: inherit
154
307
 
155
308
  check-2:
@@ -175,6 +328,13 @@ jobs:
175
328
  needs: [check-2]
176
329
  if: always() && needs.check-2.result == 'success' && needs.check-2.outputs.mission-over != 'true' && inputs.workflow-runs >= 2
177
330
  uses: ./.github/workflows/agentic-lib-workflow.yml
331
+ with:
332
+ model: ${{ inputs.model }}
333
+ profile: ${{ inputs.profile }}
334
+ dry-run: ${{ inputs.dry-run || 'false' }}
335
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
336
+ config-path: ${{ inputs.config-path }}
337
+ message: ${{ inputs.message }}
178
338
  secrets: inherit
179
339
 
180
340
  check-3:
@@ -200,6 +360,13 @@ jobs:
200
360
  needs: [check-3]
201
361
  if: always() && needs.check-3.result == 'success' && needs.check-3.outputs.mission-over != 'true' && inputs.workflow-runs >= 3
202
362
  uses: ./.github/workflows/agentic-lib-workflow.yml
363
+ with:
364
+ model: ${{ inputs.model }}
365
+ profile: ${{ inputs.profile }}
366
+ dry-run: ${{ inputs.dry-run || 'false' }}
367
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
368
+ config-path: ${{ inputs.config-path }}
369
+ message: ${{ inputs.message }}
203
370
  secrets: inherit
204
371
 
205
372
  check-4:
@@ -225,6 +392,13 @@ jobs:
225
392
  needs: [check-4]
226
393
  if: always() && needs.check-4.result == 'success' && needs.check-4.outputs.mission-over != 'true' && inputs.workflow-runs >= 4
227
394
  uses: ./.github/workflows/agentic-lib-workflow.yml
395
+ with:
396
+ model: ${{ inputs.model }}
397
+ profile: ${{ inputs.profile }}
398
+ dry-run: ${{ inputs.dry-run || 'false' }}
399
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
400
+ config-path: ${{ inputs.config-path }}
401
+ message: ${{ inputs.message }}
228
402
  secrets: inherit
229
403
 
230
404
  # ── Round 2: test + bot + up to 4 more workflow runs ───────────────
@@ -238,6 +412,9 @@ jobs:
238
412
  needs: [test-2]
239
413
  if: always() && needs.test-2.result == 'success'
240
414
  uses: ./.github/workflows/agentic-lib-bot.yml
415
+ with:
416
+ model: ${{ inputs.model }}
417
+ message: ${{ inputs.message }}
241
418
  secrets: inherit
242
419
 
243
420
  check-5:
@@ -263,6 +440,13 @@ jobs:
263
440
  needs: [check-5]
264
441
  if: always() && needs.check-5.result == 'success' && needs.check-5.outputs.mission-over != 'true' && inputs.workflow-runs >= 5
265
442
  uses: ./.github/workflows/agentic-lib-workflow.yml
443
+ with:
444
+ model: ${{ inputs.model }}
445
+ profile: ${{ inputs.profile }}
446
+ dry-run: ${{ inputs.dry-run || 'false' }}
447
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
448
+ config-path: ${{ inputs.config-path }}
449
+ message: ${{ inputs.message }}
266
450
  secrets: inherit
267
451
 
268
452
  check-6:
@@ -288,6 +472,13 @@ jobs:
288
472
  needs: [check-6]
289
473
  if: always() && needs.check-6.result == 'success' && needs.check-6.outputs.mission-over != 'true' && inputs.workflow-runs >= 6
290
474
  uses: ./.github/workflows/agentic-lib-workflow.yml
475
+ with:
476
+ model: ${{ inputs.model }}
477
+ profile: ${{ inputs.profile }}
478
+ dry-run: ${{ inputs.dry-run || 'false' }}
479
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
480
+ config-path: ${{ inputs.config-path }}
481
+ message: ${{ inputs.message }}
291
482
  secrets: inherit
292
483
 
293
484
  check-7:
@@ -313,6 +504,13 @@ jobs:
313
504
  needs: [check-7]
314
505
  if: always() && needs.check-7.result == 'success' && needs.check-7.outputs.mission-over != 'true' && inputs.workflow-runs >= 7
315
506
  uses: ./.github/workflows/agentic-lib-workflow.yml
507
+ with:
508
+ model: ${{ inputs.model }}
509
+ profile: ${{ inputs.profile }}
510
+ dry-run: ${{ inputs.dry-run || 'false' }}
511
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
512
+ config-path: ${{ inputs.config-path }}
513
+ message: ${{ inputs.message }}
316
514
  secrets: inherit
317
515
 
318
516
  check-8:
@@ -338,6 +536,13 @@ jobs:
338
536
  needs: [check-8]
339
537
  if: always() && needs.check-8.result == 'success' && needs.check-8.outputs.mission-over != 'true' && inputs.workflow-runs >= 8
340
538
  uses: ./.github/workflows/agentic-lib-workflow.yml
539
+ with:
540
+ model: ${{ inputs.model }}
541
+ profile: ${{ inputs.profile }}
542
+ dry-run: ${{ inputs.dry-run || 'false' }}
543
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
544
+ config-path: ${{ inputs.config-path }}
545
+ message: ${{ inputs.message }}
341
546
  secrets: inherit
342
547
 
343
548
  # ── Round 3: test + bot + up to 4 more workflow runs ───────────────
@@ -351,6 +556,9 @@ jobs:
351
556
  needs: [test-3]
352
557
  if: always() && needs.test-3.result == 'success'
353
558
  uses: ./.github/workflows/agentic-lib-bot.yml
559
+ with:
560
+ model: ${{ inputs.model }}
561
+ message: ${{ inputs.message }}
354
562
  secrets: inherit
355
563
 
356
564
  check-9:
@@ -376,6 +584,13 @@ jobs:
376
584
  needs: [check-9]
377
585
  if: always() && needs.check-9.result == 'success' && needs.check-9.outputs.mission-over != 'true' && inputs.workflow-runs >= 9
378
586
  uses: ./.github/workflows/agentic-lib-workflow.yml
587
+ with:
588
+ model: ${{ inputs.model }}
589
+ profile: ${{ inputs.profile }}
590
+ dry-run: ${{ inputs.dry-run || 'false' }}
591
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
592
+ config-path: ${{ inputs.config-path }}
593
+ message: ${{ inputs.message }}
379
594
  secrets: inherit
380
595
 
381
596
  check-10:
@@ -401,6 +616,13 @@ jobs:
401
616
  needs: [check-10]
402
617
  if: always() && needs.check-10.result == 'success' && needs.check-10.outputs.mission-over != 'true' && inputs.workflow-runs >= 10
403
618
  uses: ./.github/workflows/agentic-lib-workflow.yml
619
+ with:
620
+ model: ${{ inputs.model }}
621
+ profile: ${{ inputs.profile }}
622
+ dry-run: ${{ inputs.dry-run || 'false' }}
623
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
624
+ config-path: ${{ inputs.config-path }}
625
+ message: ${{ inputs.message }}
404
626
  secrets: inherit
405
627
 
406
628
  check-11:
@@ -426,6 +648,13 @@ jobs:
426
648
  needs: [check-11]
427
649
  if: always() && needs.check-11.result == 'success' && needs.check-11.outputs.mission-over != 'true' && inputs.workflow-runs >= 11
428
650
  uses: ./.github/workflows/agentic-lib-workflow.yml
651
+ with:
652
+ model: ${{ inputs.model }}
653
+ profile: ${{ inputs.profile }}
654
+ dry-run: ${{ inputs.dry-run || 'false' }}
655
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
656
+ config-path: ${{ inputs.config-path }}
657
+ message: ${{ inputs.message }}
429
658
  secrets: inherit
430
659
 
431
660
  check-12:
@@ -451,6 +680,13 @@ jobs:
451
680
  needs: [check-12]
452
681
  if: always() && needs.check-12.result == 'success' && needs.check-12.outputs.mission-over != 'true' && inputs.workflow-runs >= 12
453
682
  uses: ./.github/workflows/agentic-lib-workflow.yml
683
+ with:
684
+ model: ${{ inputs.model }}
685
+ profile: ${{ inputs.profile }}
686
+ dry-run: ${{ inputs.dry-run || 'false' }}
687
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
688
+ config-path: ${{ inputs.config-path }}
689
+ message: ${{ inputs.message }}
454
690
  secrets: inherit
455
691
 
456
692
  # ── Round 4: test + bot + up to 4 more workflow runs ───────────────
@@ -464,6 +700,9 @@ jobs:
464
700
  needs: [test-4]
465
701
  if: always() && needs.test-4.result == 'success'
466
702
  uses: ./.github/workflows/agentic-lib-bot.yml
703
+ with:
704
+ model: ${{ inputs.model }}
705
+ message: ${{ inputs.message }}
467
706
  secrets: inherit
468
707
 
469
708
  check-13:
@@ -489,6 +728,13 @@ jobs:
489
728
  needs: [check-13]
490
729
  if: always() && needs.check-13.result == 'success' && needs.check-13.outputs.mission-over != 'true' && inputs.workflow-runs >= 13
491
730
  uses: ./.github/workflows/agentic-lib-workflow.yml
731
+ with:
732
+ model: ${{ inputs.model }}
733
+ profile: ${{ inputs.profile }}
734
+ dry-run: ${{ inputs.dry-run || 'false' }}
735
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
736
+ config-path: ${{ inputs.config-path }}
737
+ message: ${{ inputs.message }}
492
738
  secrets: inherit
493
739
 
494
740
  check-14:
@@ -514,6 +760,13 @@ jobs:
514
760
  needs: [check-14]
515
761
  if: always() && needs.check-14.result == 'success' && needs.check-14.outputs.mission-over != 'true' && inputs.workflow-runs >= 14
516
762
  uses: ./.github/workflows/agentic-lib-workflow.yml
763
+ with:
764
+ model: ${{ inputs.model }}
765
+ profile: ${{ inputs.profile }}
766
+ dry-run: ${{ inputs.dry-run || 'false' }}
767
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
768
+ config-path: ${{ inputs.config-path }}
769
+ message: ${{ inputs.message }}
517
770
  secrets: inherit
518
771
 
519
772
  check-15:
@@ -539,6 +792,13 @@ jobs:
539
792
  needs: [check-15]
540
793
  if: always() && needs.check-15.result == 'success' && needs.check-15.outputs.mission-over != 'true' && inputs.workflow-runs >= 15
541
794
  uses: ./.github/workflows/agentic-lib-workflow.yml
795
+ with:
796
+ model: ${{ inputs.model }}
797
+ profile: ${{ inputs.profile }}
798
+ dry-run: ${{ inputs.dry-run || 'false' }}
799
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
800
+ config-path: ${{ inputs.config-path }}
801
+ message: ${{ inputs.message }}
542
802
  secrets: inherit
543
803
 
544
804
  check-16:
@@ -564,6 +824,13 @@ jobs:
564
824
  needs: [check-16]
565
825
  if: always() && needs.check-16.result == 'success' && needs.check-16.outputs.mission-over != 'true' && inputs.workflow-runs >= 16
566
826
  uses: ./.github/workflows/agentic-lib-workflow.yml
827
+ with:
828
+ model: ${{ inputs.model }}
829
+ profile: ${{ inputs.profile }}
830
+ dry-run: ${{ inputs.dry-run || 'false' }}
831
+ skipMaintain: ${{ inputs.skipMaintain || 'false' }}
832
+ config-path: ${{ inputs.config-path }}
833
+ message: ${{ inputs.message }}
567
834
  secrets: inherit
568
835
 
569
836
  # ── Final: test + bot (always runs) ────────────────────────────────
@@ -577,6 +844,9 @@ jobs:
577
844
  needs: [test-final]
578
845
  if: always() && needs.test-final.result == 'success'
579
846
  uses: ./.github/workflows/agentic-lib-bot.yml
847
+ with:
848
+ model: ${{ inputs.model }}
849
+ message: ${{ inputs.message }}
580
850
  secrets: inherit
581
851
 
582
852
  # ── Verify: MISSION_COMPLETE.md must exist ─────────────────────────
@@ -150,20 +150,42 @@ jobs:
150
150
  runs-on: ubuntu-latest
151
151
  outputs:
152
152
  dry-run: ${{ steps.resolve.outputs.dry-run }}
153
- mission: ${{ steps.resolve.outputs.mission }}
154
- profile: ${{ steps.resolve.outputs.profile }}
153
+ mode: ${{ steps.resolve.outputs.mode }}
154
+ mission-seed: ${{ steps.resolve.outputs.mission-seed }}
155
+ mission-text: ${{ steps.resolve.outputs.mission-text }}
156
+ schedule: ${{ steps.resolve.outputs.schedule }}
155
157
  model: ${{ steps.resolve.outputs.model }}
158
+ profile: ${{ steps.resolve.outputs.profile }}
156
159
  create-seed-issues: ${{ steps.resolve.outputs.create-seed-issues }}
160
+ run-workflow: ${{ steps.resolve.outputs.run-workflow }}
157
161
  steps:
158
162
  - id: resolve
159
163
  uses: actions/github-script@v8
160
164
  with:
161
165
  script: |
162
- core.setOutput('dry-run', context.payload.inputs?.['dry-run'] || 'false');
163
- core.setOutput('mission', context.payload.inputs?.['mission-seed'] || '7-kyu-understand-fizz-buzz');
164
- core.setOutput('profile', context.payload.inputs?.['profile'] || '');
165
- core.setOutput('model', context.payload.inputs?.['model'] || '');
166
- core.setOutput('create-seed-issues', context.payload.inputs?.['create-seed-issues'] || 'false');
166
+ const resolve = (name, input, configKey, defaultValue) => {
167
+ let value = input || '';
168
+ let source = 'input';
169
+ if (!value && configKey) {
170
+ source = '';
171
+ }
172
+ if (!value) {
173
+ value = defaultValue;
174
+ source = 'default';
175
+ }
176
+ core.info(`param ${name}: input='${input}' default='${defaultValue}' → '${value}' (source: ${source})`);
177
+ core.setOutput(name, value);
178
+ return value;
179
+ };
180
+ resolve('dry-run', '${{ inputs.dry-run }}', null, 'false');
181
+ resolve('mode', '${{ inputs.mode }}', null, 'purge');
182
+ resolve('mission-seed', '${{ inputs.mission-seed }}', null, '7-kyu-understand-fizz-buzz');
183
+ resolve('mission-text', '${{ inputs.mission-text }}', null, '');
184
+ resolve('schedule', '${{ inputs.schedule }}', null, '');
185
+ resolve('model', '${{ inputs.model }}', null, '');
186
+ resolve('profile', '${{ inputs.profile }}', null, '');
187
+ resolve('create-seed-issues', '${{ inputs.create-seed-issues }}', null, 'false');
188
+ resolve('run-workflow', '${{ inputs.run-workflow }}', null, 'true');
167
189
 
168
190
  # Step 1: Update agentic-lib and infrastructure (commits to main)
169
191
  # Skip tests when purge/reseed will replace all user code anyway
@@ -98,6 +98,7 @@ jobs:
98
98
  model: ${{ steps.resolve.outputs.model }}
99
99
  profile: ${{ steps.resolve.outputs.profile }}
100
100
  focus: ${{ steps.resolve.outputs.focus }}
101
+ dry-run: ${{ steps.resolve.outputs.dry-run }}
101
102
  maintenance: ${{ steps.resolve.outputs.maintenance }}
102
103
  steps:
103
104
  - uses: actions/checkout@v6
@@ -109,25 +110,42 @@ jobs:
109
110
  with:
110
111
  script: |
111
112
  const fs = require('fs');
112
- const tomlPath = 'agentic-lib.toml';
113
- let tomlContent = '';
114
- if (fs.existsSync(tomlPath)) tomlContent = fs.readFileSync(tomlPath, 'utf8');
113
+ const configPath = 'agentic-lib.toml';
114
+ let toml = '';
115
+ if (fs.existsSync(configPath)) toml = fs.readFileSync(configPath, 'utf8');
115
116
  const readToml = (key) => {
116
- const m = tomlContent.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, 'm'));
117
+ const m = toml.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, 'm'));
117
118
  return m ? m[1] : '';
118
119
  };
119
- let frequency = context.payload.inputs?.['frequency'] || '';
120
- if (!frequency) frequency = readToml('supervisor') || 'off';
121
- const model = context.payload.inputs?.['model'] || '';
122
- const profile = context.payload.inputs?.['profile'] || '';
123
- let focus = context.payload.inputs?.['focus'] || '';
124
- if (!focus) focus = readToml('focus') || 'mission';
125
- if (frequency === 'maintenance') focus = 'maintenance';
126
- core.setOutput('frequency', frequency);
127
- core.setOutput('model', model);
128
- core.setOutput('profile', profile);
129
- core.setOutput('focus', focus);
130
- core.setOutput('maintenance', frequency === 'maintenance' ? 'true' : 'false');
120
+ const resolve = (name, input, configKey, defaultValue) => {
121
+ let value = input || '';
122
+ let source = 'input';
123
+ if (!value && configKey) {
124
+ value = readToml(configKey);
125
+ source = value ? 'config' : '';
126
+ }
127
+ if (!value) {
128
+ value = defaultValue;
129
+ source = 'default';
130
+ }
131
+ const configVal = configKey ? readToml(configKey) : 'N/A';
132
+ core.info(`param ${name}: input='${input}' config='${configVal}' default='${defaultValue}' → '${value}' (source: ${source})`);
133
+ core.setOutput(name, value);
134
+ return value;
135
+ };
136
+ const frequency = resolve('frequency', '${{ inputs.frequency }}', 'supervisor', 'off');
137
+ resolve('model', '${{ inputs.model }}', 'model', 'gpt-5-mini');
138
+ resolve('profile', '${{ inputs.profile }}', 'profile', '');
139
+ let focus = resolve('focus', '${{ inputs.focus }}', 'focus', 'mission');
140
+ if (frequency === 'maintenance') {
141
+ focus = 'maintenance';
142
+ core.info(`param focus: overridden to 'maintenance' (frequency=maintenance)`);
143
+ core.setOutput('focus', focus);
144
+ }
145
+ resolve('dry-run', '${{ inputs.dry-run }}', null, 'false');
146
+ const maintenance = frequency === 'maintenance' ? 'true' : 'false';
147
+ core.info(`param maintenance: derived='${maintenance}' (frequency='${frequency}')`);
148
+ core.setOutput('maintenance', maintenance);
131
149
 
132
150
  update-schedule:
133
151
  needs: [params]
@@ -65,13 +65,29 @@ jobs:
65
65
  params:
66
66
  runs-on: ubuntu-latest
67
67
  outputs:
68
- dry-run: ${{ steps.resolve.outputs.dry-run }}
68
+ push-screenshot: ${{ steps.resolve.outputs.push-screenshot }}
69
+ log-branch: ${{ steps.resolve.outputs.log-branch }}
69
70
  steps:
70
71
  - id: resolve
71
72
  uses: actions/github-script@v8
72
73
  with:
73
74
  script: |
74
- core.setOutput('dry-run', context.payload.inputs?.['dry-run'] || 'false');
75
+ const resolve = (name, input, configKey, defaultValue) => {
76
+ let value = input || '';
77
+ let source = 'input';
78
+ if (!value && configKey) {
79
+ source = '';
80
+ }
81
+ if (!value) {
82
+ value = defaultValue;
83
+ source = 'default';
84
+ }
85
+ core.info(`param ${name}: input='${input}' default='${defaultValue}' → '${value}' (source: ${source})`);
86
+ core.setOutput(name, value);
87
+ return value;
88
+ };
89
+ resolve('push-screenshot', '${{ inputs.push-screenshot }}', null, 'false');
90
+ resolve('log-branch', '${{ inputs.log-branch }}', null, 'agentic-lib-logs');
75
91
 
76
92
  test:
77
93
  needs: [params]
@@ -41,12 +41,28 @@ jobs:
41
41
  runs-on: ubuntu-latest
42
42
  outputs:
43
43
  dry-run: ${{ steps.resolve.outputs.dry-run }}
44
+ skip-tests: ${{ steps.resolve.outputs.skip-tests }}
44
45
  steps:
45
46
  - id: resolve
46
47
  uses: actions/github-script@v8
47
48
  with:
48
49
  script: |
49
- core.setOutput('dry-run', context.payload.inputs?.['dry-run'] || 'false');
50
+ const resolve = (name, input, configKey, defaultValue) => {
51
+ let value = input || '';
52
+ let source = 'input';
53
+ if (!value && configKey) {
54
+ source = '';
55
+ }
56
+ if (!value) {
57
+ value = defaultValue;
58
+ source = 'default';
59
+ }
60
+ core.info(`param ${name}: input='${input}' default='${defaultValue}' → '${value}' (source: ${source})`);
61
+ core.setOutput(name, value);
62
+ return value;
63
+ };
64
+ resolve('dry-run', '${{ inputs.dry-run }}', null, 'false');
65
+ resolve('skip-tests', '${{ inputs.skip-tests }}', null, 'false');
50
66
 
51
67
  update:
52
68
  needs: [params]
@@ -136,6 +136,21 @@ jobs:
136
136
  # ─── Normalise inputs ──────────────────────────────────────────────
137
137
  params:
138
138
  runs-on: ubuntu-latest
139
+ outputs:
140
+ model: ${{ steps.resolve.outputs.model }}
141
+ profile: ${{ steps.resolve.outputs.profile }}
142
+ mode: ${{ steps.resolve.outputs.mode }}
143
+ message: ${{ steps.resolve.outputs.message }}
144
+ issue-number: ${{ steps.resolve.outputs.issue-number }}
145
+ schedule: ${{ steps.resolve.outputs.schedule }}
146
+ pr-number: ${{ steps.resolve.outputs.pr-number }}
147
+ dry-run: ${{ steps.resolve.outputs.dry-run }}
148
+ config-path: ${{ steps.resolve.outputs.config-path }}
149
+ skipMaintain: ${{ steps.resolve.outputs.skipMaintain }}
150
+ log-prefix: ${{ steps.resolve.outputs.log-prefix }}
151
+ log-branch: ${{ steps.resolve.outputs.log-branch }}
152
+ screenshot-file: ${{ steps.resolve.outputs.screenshot-file }}
153
+ mission-complete: ${{ steps.resolve.outputs.mission-complete }}
139
154
  steps:
140
155
  - uses: actions/checkout@v6
141
156
  with:
@@ -145,85 +160,65 @@ jobs:
145
160
  MISSION_COMPLETE.md
146
161
  MISSION_FAILED.md
147
162
  sparse-checkout-cone-mode: false
148
- - name: Normalise params
149
- id: normalise
150
- shell: bash
151
- run: |
152
- MODEL='${{ inputs.model }}'
153
- if [ -z "$MODEL" ] && [ -f "${{ env.configPath }}" ]; then
154
- TOML_MODEL=$(grep '^\s*model' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
155
- MODEL="${TOML_MODEL}"
156
- fi
157
- echo "model=${MODEL:-gpt-5-mini}" >> $GITHUB_OUTPUT
158
- PROFILE='${{ inputs.profile }}'
159
- if [ -z "$PROFILE" ] && [ -f "${{ env.configPath }}" ]; then
160
- TOML_PROFILE=$(grep '^\s*profile' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
161
- PROFILE="${TOML_PROFILE}"
162
- fi
163
- echo "profile=${PROFILE}" >> $GITHUB_OUTPUT
164
- MODE='${{ inputs.mode }}'
165
- echo "mode=${MODE:-full}" >> $GITHUB_OUTPUT
166
- echo "message=${{ inputs.message }}" >> $GITHUB_OUTPUT
167
- ISSUE='${{ inputs.issue-number }}'
168
- echo "issue-number=${ISSUE}" >> $GITHUB_OUTPUT
169
- SCHEDULE='${{ inputs.schedule }}'
170
- echo "schedule=${SCHEDULE}" >> $GITHUB_OUTPUT
171
- PR='${{ inputs.pr-number }}'
172
- echo "pr-number=${PR}" >> $GITHUB_OUTPUT
173
- DRY_RUN='${{ inputs.dry-run }}'
174
- # Schedule triggers have no inputs, so DRY_RUN is empty.
175
- # Default to false for schedule events (they should run live).
176
- if [ "${{ github.event_name }}" = "schedule" ]; then
177
- DRY_RUN="${DRY_RUN:-false}"
178
- else
179
- DRY_RUN="${DRY_RUN:-true}"
180
- fi
181
- echo "dry-run=${DRY_RUN}" >> $GITHUB_OUTPUT
182
- CONFIG='${{ inputs.config-path }}'
183
- echo "config-path=${CONFIG:-${{ env.configPath }}}" >> $GITHUB_OUTPUT
184
- # Bot config: log prefix, log branch, screenshot file
185
- LOG_PREFIX=""
186
- LOG_BRANCH=""
187
- SCREENSHOT=""
188
- if [ -f "${{ env.configPath }}" ]; then
189
- LOG_PREFIX=$(grep '^\s*log-prefix' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
190
- LOG_BRANCH=$(grep '^\s*log-branch' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
191
- SCREENSHOT=$(grep '^\s*screenshot-file' "${{ env.configPath }}" | head -1 | sed 's/.*= *"\([^"]*\)".*/\1/' || true)
192
- fi
193
- echo "log-prefix=${LOG_PREFIX:-agent-log-}" >> $GITHUB_OUTPUT
194
- echo "log-branch=${LOG_BRANCH:-agentic-lib-logs}" >> $GITHUB_OUTPUT
195
- echo "screenshot-file=${SCREENSHOT:-SCREENSHOT_INDEX.png}" >> $GITHUB_OUTPUT
196
- - name: Check mission-complete signal (W4)
197
- id: mission-check
198
- shell: bash
199
- run: |
200
- SUPERVISOR=""
201
- if [ -f "${{ env.configPath }}" ]; then
202
- SUPERVISOR=$(grep '^\s*supervisor\s*=' "${{ env.configPath }}" 2>/dev/null | head -1 | sed 's/.*=\s*"\([^"]*\)".*/\1/' || true)
203
- fi
204
- if [ -f MISSION_COMPLETE.md ] && [ "$SUPERVISOR" != "maintenance" ]; then
205
- echo "mission-complete=true" >> $GITHUB_OUTPUT
206
- echo "::notice::Mission is complete — most jobs will be skipped"
207
- elif [ -f MISSION_FAILED.md ]; then
208
- echo "mission-complete=true" >> $GITHUB_OUTPUT
209
- echo "::notice::Mission has failed — most jobs will be skipped"
210
- else
211
- echo "mission-complete=false" >> $GITHUB_OUTPUT
212
- fi
213
- outputs:
214
- model: ${{ steps.normalise.outputs.model }}
215
- profile: ${{ steps.normalise.outputs.profile }}
216
- mode: ${{ steps.normalise.outputs.mode }}
217
- message: ${{ steps.normalise.outputs.message }}
218
- issue-number: ${{ steps.normalise.outputs.issue-number }}
219
- schedule: ${{ steps.normalise.outputs.schedule }}
220
- pr-number: ${{ steps.normalise.outputs.pr-number }}
221
- dry-run: ${{ steps.normalise.outputs.dry-run }}
222
- config-path: ${{ steps.normalise.outputs.config-path }}
223
- log-prefix: ${{ steps.normalise.outputs.log-prefix }}
224
- log-branch: ${{ steps.normalise.outputs.log-branch }}
225
- screenshot-file: ${{ steps.normalise.outputs.screenshot-file }}
226
- mission-complete: ${{ steps.mission-check.outputs.mission-complete }}
163
+ - id: resolve
164
+ uses: actions/github-script@v8
165
+ with:
166
+ script: |
167
+ const fs = require('fs');
168
+ const configPath = '${{ env.configPath }}';
169
+ let toml = '';
170
+ if (fs.existsSync(configPath)) toml = fs.readFileSync(configPath, 'utf8');
171
+ const readToml = (key) => {
172
+ const m = toml.match(new RegExp(`^\\s*${key}\\s*=\\s*"([^"]*)"`, 'm'));
173
+ return m ? m[1] : '';
174
+ };
175
+ const resolve = (name, input, configKey, defaultValue) => {
176
+ let value = input || '';
177
+ let source = 'input';
178
+ if (!value && configKey) {
179
+ value = readToml(configKey);
180
+ source = value ? 'config' : '';
181
+ }
182
+ if (!value) {
183
+ value = defaultValue;
184
+ source = 'default';
185
+ }
186
+ const configVal = configKey ? readToml(configKey) : 'N/A';
187
+ core.info(`param ${name}: input='${input}' config='${configVal}' default='${defaultValue}' → '${value}' (source: ${source})`);
188
+ core.setOutput(name, value);
189
+ return value;
190
+ };
191
+ resolve('model', '${{ inputs.model }}', 'model', 'gpt-5-mini');
192
+ resolve('profile', '${{ inputs.profile }}', 'profile', '');
193
+ resolve('mode', '${{ inputs.mode }}', null, 'full');
194
+ resolve('message', '${{ inputs.message }}', null, '');
195
+ resolve('issue-number', '${{ inputs.issue-number }}', null, '');
196
+ resolve('schedule', '${{ inputs.schedule }}', null, '');
197
+ resolve('pr-number', '${{ inputs.pr-number }}', null, '');
198
+ resolve('config-path', '${{ inputs.config-path }}', null, '${{ env.configPath }}');
199
+ resolve('skipMaintain', '${{ inputs.skipMaintain }}', null, 'false');
200
+ // dry-run: schedule events default to false (live), others to true
201
+ const eventName = '${{ github.event_name }}';
202
+ const dryRunDefault = eventName === 'schedule' ? 'false' : 'true';
203
+ resolve('dry-run', '${{ inputs.dry-run }}', null, dryRunDefault);
204
+ // Bot config from TOML
205
+ resolve('log-prefix', '', 'log-prefix', 'agent-log-');
206
+ resolve('log-branch', '', 'log-branch', 'agentic-lib-logs');
207
+ resolve('screenshot-file', '', 'screenshot-file', 'SCREENSHOT_INDEX.png');
208
+ // Mission-complete check (W4)
209
+ const supervisor = readToml('supervisor');
210
+ const hasMissionComplete = fs.existsSync('MISSION_COMPLETE.md');
211
+ const hasMissionFailed = fs.existsSync('MISSION_FAILED.md');
212
+ let missionComplete = 'false';
213
+ if (hasMissionComplete && supervisor !== 'maintenance') {
214
+ missionComplete = 'true';
215
+ core.notice('Mission is complete — most jobs will be skipped');
216
+ } else if (hasMissionFailed) {
217
+ missionComplete = 'true';
218
+ core.notice('Mission has failed — most jobs will be skipped');
219
+ }
220
+ core.info(`param mission-complete: MISSION_COMPLETE.md=${hasMissionComplete} MISSION_FAILED.md=${hasMissionFailed} supervisor='${supervisor}' '${missionComplete}'`);
221
+ core.setOutput('mission-complete', missionComplete);
227
222
 
228
223
  # ─── PR Cleanup: merge/close/delete stale PRs and branches ─────────
229
224
  pr-cleanup:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.4.39",
3
+ "version": "7.4.41",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -17,7 +17,7 @@
17
17
  "author": "",
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
- "@xn-intenton-z2a/agentic-lib": "^7.4.39"
20
+ "@xn-intenton-z2a/agentic-lib": "^7.4.41"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@playwright/test": "^1.58.0",