@xn-intenton-z2a/agentic-lib 7.1.86 → 7.1.88

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.
@@ -23,6 +23,7 @@ on:
23
23
 
24
24
  permissions:
25
25
  contents: write
26
+ actions: write
26
27
 
27
28
  jobs:
28
29
  test:
@@ -67,7 +68,7 @@ jobs:
67
68
  HOME: /root
68
69
 
69
70
  - name: Upload screenshot
70
- if: always()
71
+ if: ${{ !cancelled() }}
71
72
  uses: actions/upload-artifact@v4
72
73
  with:
73
74
  name: screenshot
@@ -95,3 +96,24 @@ jobs:
95
96
  echo "::warning::Failed to push screenshot after 3 attempts"
96
97
  fi
97
98
  done
99
+
100
+ # ─── Dispatch fix workflow when tests fail on main ─────────────────
101
+ dispatch-fix:
102
+ needs: [test, behaviour]
103
+ if: >-
104
+ !cancelled()
105
+ && github.ref == 'refs/heads/main'
106
+ && github.event_name != 'pull_request'
107
+ && github.repository != 'xn-intenton-z2a/agentic-lib'
108
+ && (needs.test.result == 'failure' || needs.behaviour.result == 'failure')
109
+ runs-on: ubuntu-latest
110
+ steps:
111
+ - name: Dispatch agentic-lib-workflow to fix broken build
112
+ env:
113
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
114
+ run: |
115
+ echo "Tests failed on main — dispatching agentic-lib-workflow to fix"
116
+ gh workflow run agentic-lib-workflow.yml \
117
+ --repo "${{ github.repository }}" \
118
+ -f mode=full \
119
+ -f message="Build broken on main: agentic-lib-test run ${{ github.run_id }} failed. Please fix."
@@ -298,7 +298,7 @@ jobs:
298
298
  maintain:
299
299
  needs: [params]
300
300
  if: |
301
- always() &&
301
+ !cancelled() &&
302
302
  (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'maintain-only') &&
303
303
  needs.params.result == 'success'
304
304
  runs-on: ubuntu-latest
@@ -386,7 +386,7 @@ jobs:
386
386
  supervisor:
387
387
  needs: [params, pr-cleanup, telemetry, maintain]
388
388
  if: |
389
- always() &&
389
+ !cancelled() &&
390
390
  (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'dev-only') &&
391
391
  needs.params.result == 'success'
392
392
  runs-on: ubuntu-latest
@@ -422,7 +422,7 @@ jobs:
422
422
  fix-stuck:
423
423
  needs: [params, supervisor]
424
424
  if: |
425
- always() &&
425
+ !cancelled() &&
426
426
  needs.params.outputs.mode == 'full' &&
427
427
  needs.params.result == 'success'
428
428
  runs-on: ubuntu-latest
@@ -438,6 +438,10 @@ jobs:
438
438
  - name: Install project dependencies
439
439
  run: npm ci
440
440
 
441
+ - name: Install Playwright (for behaviour tests)
442
+ if: hashFiles('playwright.config.js') != '' || hashFiles('playwright.config.ts') != ''
443
+ run: npx playwright install --with-deps chromium
444
+
441
445
  - name: Self-init (agentic-lib dev only)
442
446
  if: hashFiles('scripts/self-init.sh') != '' && hashFiles('.github/agentic-lib/actions/agentic-step/package.json') == ''
443
447
  run: bash scripts/self-init.sh
@@ -456,7 +460,7 @@ jobs:
456
460
  echo "mission-complete=false" >> $GITHUB_OUTPUT
457
461
  fi
458
462
 
459
- - name: Find and fix stuck PRs
463
+ - name: Find and fix stuck PRs or broken main build
460
464
  if: steps.fix-mission-check.outputs.mission-complete != 'true'
461
465
  uses: actions/github-script@v8
462
466
  env:
@@ -480,6 +484,7 @@ jobs:
480
484
  owner, repo, state: 'open', per_page: 10,
481
485
  });
482
486
 
487
+ let foundPR = false;
483
488
  for (const pr of openPRs) {
484
489
  const hasAutomerge = pr.labels.some(l => l.name === 'automerge');
485
490
  if (!hasAutomerge) continue;
@@ -514,9 +519,42 @@ jobs:
514
519
  core.info(`Will attempt to fix PR #${pr.number} (${reason})`);
515
520
  core.exportVariable('FIX_PR_NUMBER', String(pr.number));
516
521
  core.exportVariable('FIX_REASON', reason);
522
+ foundPR = true;
517
523
  break;
518
524
  }
519
525
 
526
+ // If no stuck PR found, check for broken main build
527
+ if (!foundPR) {
528
+ try {
529
+ const { data: testRuns } = await github.rest.actions.listWorkflowRuns({
530
+ owner, repo,
531
+ workflow_id: 'agentic-lib-test.yml',
532
+ branch: 'main',
533
+ per_page: 1,
534
+ });
535
+ if (testRuns.workflow_runs.length > 0) {
536
+ const latestTest = testRuns.workflow_runs[0];
537
+ if (latestTest.conclusion === 'failure') {
538
+ // Check we haven't already opened a fix branch for this
539
+ const { data: existingPRs } = await github.rest.pulls.list({
540
+ owner, repo, state: 'open', head: `${owner}:agentic-lib-fix-main-build`, per_page: 1,
541
+ });
542
+ if (existingPRs.length > 0) {
543
+ core.info(`Fix PR already open for main build (#${existingPRs[0].number}) — skipping`);
544
+ } else {
545
+ core.info(`Main build broken (run ${latestTest.id}) — will create fix branch`);
546
+ core.exportVariable('FIX_MAIN_BUILD', 'true');
547
+ core.exportVariable('FIX_RUN_ID', String(latestTest.id));
548
+ }
549
+ } else {
550
+ core.info(`Latest agentic-lib-test on main: ${latestTest.conclusion} — no fix needed`);
551
+ }
552
+ }
553
+ } catch (err) {
554
+ core.warning(`Could not check main build status: ${err.message}`);
555
+ }
556
+ }
557
+
520
558
  - name: Checkout PR branch
521
559
  if: env.FIX_PR_NUMBER != '' && steps.fix-mission-check.outputs.mission-complete != 'true'
522
560
  run: |
@@ -524,6 +562,11 @@ jobs:
524
562
  env:
525
563
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
526
564
 
565
+ - name: Create fix branch for broken main build
566
+ if: env.FIX_MAIN_BUILD == 'true' && steps.fix-mission-check.outputs.mission-complete != 'true'
567
+ run: |
568
+ git checkout -b agentic-lib-fix-main-build
569
+
527
570
  - name: "Tier 1: Auto-resolve trivial merge conflicts"
528
571
  if: env.FIX_PR_NUMBER != '' && env.FIX_REASON == 'merge conflicts' && steps.fix-mission-check.outputs.mission-complete != 'true'
529
572
  id: trivial-resolve
@@ -573,17 +616,57 @@ jobs:
573
616
  # test-command read from [execution].test in agentic-lib.toml
574
617
  model: ${{ needs.params.outputs.model }}
575
618
 
619
+ - name: "LLM fix for broken main build"
620
+ if: |
621
+ env.FIX_MAIN_BUILD == 'true' &&
622
+ steps.fix-mission-check.outputs.mission-complete != 'true'
623
+ uses: ./.github/agentic-lib/actions/agentic-step
624
+ env:
625
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
626
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
627
+ FIX_RUN_ID: ${{ env.FIX_RUN_ID }}
628
+ with:
629
+ task: "fix-code"
630
+ config: ${{ needs.params.outputs.config-path }}
631
+ instructions: ".github/agentic-lib/agents/agent-apply-fix.md"
632
+ model: ${{ needs.params.outputs.model }}
633
+
634
+ - name: Build website and run behaviour tests (fix)
635
+ if: |
636
+ steps.fix-mission-check.outputs.mission-complete != 'true' &&
637
+ (env.FIX_PR_NUMBER != '' || env.FIX_MAIN_BUILD == 'true')
638
+ run: |
639
+ npm run build:web 2>/dev/null || echo "No build:web script"
640
+ npm run --if-present test:behaviour || echo "Behaviour tests failed (non-blocking for fix)"
641
+
576
642
  - name: Commit and push fixes
577
643
  if: github.repository != 'xn-intenton-z2a/agentic-lib' && env.FIX_PR_NUMBER != '' && steps.fix-mission-check.outputs.mission-complete != 'true'
578
644
  uses: ./.github/agentic-lib/actions/commit-if-changed
579
645
  with:
580
646
  commit-message: "agentic-step: fix failing tests / resolve conflicts"
581
647
 
648
+ - name: Commit, push, and open PR for main build fix
649
+ if: github.repository != 'xn-intenton-z2a/agentic-lib' && env.FIX_MAIN_BUILD == 'true' && steps.fix-mission-check.outputs.mission-complete != 'true'
650
+ env:
651
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
652
+ run: |
653
+ if git diff --quiet && git diff --cached --quiet; then
654
+ echo "No changes to commit"
655
+ exit 0
656
+ fi
657
+ git add -A
658
+ git commit -m "agentic-step: fix broken main build (run ${{ env.FIX_RUN_ID }})"
659
+ git push -u origin agentic-lib-fix-main-build
660
+ gh pr create \
661
+ --title "fix: auto-fix broken main build" \
662
+ --body "Automated fix for failing agentic-lib-test run [${{ env.FIX_RUN_ID }}](https://github.com/${{ github.repository }}/actions/runs/${{ env.FIX_RUN_ID }})." \
663
+ --label automerge
664
+
582
665
  # ─── Review: close resolved issues, enhance with criteria ──────────
583
666
  review-features:
584
667
  needs: [params, supervisor]
585
668
  if: |
586
- always() &&
669
+ !cancelled() &&
587
670
  (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'review-only') &&
588
671
  needs.params.result == 'success'
589
672
  runs-on: ubuntu-latest
@@ -628,7 +711,7 @@ jobs:
628
711
  dev:
629
712
  needs: [params, review-features]
630
713
  if: |
631
- always() &&
714
+ !cancelled() &&
632
715
  (needs.params.outputs.mode == 'full' || needs.params.outputs.mode == 'dev-only') &&
633
716
  needs.params.result == 'success'
634
717
  runs-on: ubuntu-latest
@@ -645,6 +728,10 @@ jobs:
645
728
  - name: Install project dependencies
646
729
  run: npm ci
647
730
 
731
+ - name: Install Playwright (for behaviour tests)
732
+ if: hashFiles('playwright.config.js') != '' || hashFiles('playwright.config.ts') != ''
733
+ run: npx playwright install --with-deps chromium
734
+
648
735
  - name: Self-init (agentic-lib dev only)
649
736
  if: hashFiles('scripts/self-init.sh') != '' && hashFiles('.github/agentic-lib/actions/agentic-step/package.json') == ''
650
737
  run: bash scripts/self-init.sh
@@ -739,18 +826,26 @@ jobs:
739
826
  CONFIG="${{ needs.params.outputs.config-path }}"
740
827
  TEST_CMD=$(grep -E '^\s*test\s*=' "$CONFIG" 2>/dev/null | sed 's/.*=\s*"\(.*\)"/\1/' | head -1)
741
828
  TEST_CMD="${TEST_CMD:-npm ci && npm test}"
742
- echo "Running: $TEST_CMD"
829
+ echo "Running unit tests: $TEST_CMD"
743
830
  set +e
744
831
  eval "$TEST_CMD" 2>&1 | tail -30
745
832
  EXIT_CODE=$?
746
833
  set -e
747
834
  if [ $EXIT_CODE -ne 0 ]; then
748
835
  echo "tests-passed=false" >> $GITHUB_OUTPUT
749
- echo "WARNING: Tests failed (exit $EXIT_CODE) — skipping commit and PR"
836
+ echo "WARNING: Unit tests failed (exit $EXIT_CODE) — skipping commit and PR"
837
+ exit 0
838
+ fi
839
+ # Run behaviour tests if available
840
+ if npm run --if-present test:behaviour; then
841
+ echo "Behaviour tests passed"
750
842
  else
751
- echo "tests-passed=true" >> $GITHUB_OUTPUT
752
- echo "Tests passed"
843
+ echo "tests-passed=false" >> $GITHUB_OUTPUT
844
+ echo "WARNING: Behaviour tests failed — skipping commit and PR"
845
+ exit 0
753
846
  fi
847
+ echo "tests-passed=true" >> $GITHUB_OUTPUT
848
+ echo "All tests passed"
754
849
 
755
850
  - name: Commit and push
756
851
  if: github.repository != 'xn-intenton-z2a/agentic-lib' && steps.issue.outputs.issue-number != '' && needs.params.outputs.dry-run != 'true' && steps.pre-commit-test.outputs.tests-passed == 'true'
@@ -850,7 +945,7 @@ jobs:
850
945
  # ─── Post-merge: stats, schedule, mission check ────────────────────
851
946
  post-merge:
852
947
  needs: [params, dev, pr-cleanup]
853
- if: always() && needs.params.result == 'success'
948
+ if: ${{ !cancelled() && needs.params.result == 'success' }}
854
949
  runs-on: ubuntu-latest
855
950
  steps:
856
951
  - uses: actions/checkout@v6
@@ -872,7 +967,7 @@ jobs:
872
967
  # ─── Schedule change (if requested) ────────────────────────────────
873
968
  update-schedule:
874
969
  needs: [params, dev]
875
- if: always() && needs.params.outputs.dry-run != 'true' && needs.params.outputs.schedule != '' && needs.params.result == 'success'
970
+ if: ${{ !cancelled() && needs.params.outputs.dry-run != 'true' && needs.params.outputs.schedule != '' && needs.params.result == 'success' }}
876
971
  uses: ./.github/workflows/agentic-lib-schedule.yml
877
972
  with:
878
973
  frequency: ${{ needs.params.outputs.schedule }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xn-intenton-z2a/agentic-lib",
3
- "version": "7.1.86",
3
+ "version": "7.1.88",
4
4
  "description": "Agentic-lib Agentic Coding Systems SDK powering automated GitHub workflows.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -121,9 +121,67 @@ async function resolveConflicts({ config, pr, prNumber, instructions, model, wri
121
121
  }
122
122
 
123
123
  /**
124
- * Fix failing code or resolve merge conflicts on a pull request.
124
+ * Fix a broken main branch build.
125
+ * Called when no PR is involved — just a failing workflow run on main.
126
+ */
127
+ async function fixMainBuild({ config, runId, instructions, model, writablePaths, testCommand }) {
128
+ const logContent = fetchRunLog(runId);
129
+ if (!logContent) {
130
+ core.info(`Could not fetch log for run ${runId}. Returning nop.`);
131
+ return { outcome: "nop", details: `Could not fetch log for run ${runId}` };
132
+ }
133
+
134
+ const agentInstructions = instructions || "Fix the failing tests by modifying the source code.";
135
+ const readOnlyPaths = config.readOnlyPaths;
136
+
137
+ const prompt = [
138
+ "## Instructions",
139
+ agentInstructions,
140
+ "",
141
+ "## Broken Build on Main",
142
+ `Workflow run ${runId} failed on the main branch.`,
143
+ "Fix the code so that the build passes.",
144
+ "",
145
+ "## Failed Run Log",
146
+ logContent,
147
+ "",
148
+ formatPathsSection(writablePaths, readOnlyPaths, config),
149
+ "",
150
+ "## Constraints",
151
+ `- Run \`${testCommand}\` to validate your fixes`,
152
+ "- Make minimal changes to fix the failing tests",
153
+ "- Do not introduce new features — focus on making the build green",
154
+ ].join("\n");
155
+
156
+ const t = config.tuning || {};
157
+ const { tokensUsed, inputTokens, outputTokens, cost, content: resultContent } = await runCopilotTask({
158
+ model,
159
+ systemMessage: `You are an autonomous coding agent fixing a broken build on the main branch. The test/build workflow has failed. Analyze the error log and make minimal, targeted changes to fix it.` + NARRATIVE_INSTRUCTION,
160
+ prompt,
161
+ writablePaths,
162
+ tuning: t,
163
+ });
164
+
165
+ core.info(`Main build fix completed (${tokensUsed} tokens)`);
166
+
167
+ return {
168
+ outcome: "fix-applied",
169
+ tokensUsed,
170
+ inputTokens,
171
+ outputTokens,
172
+ cost,
173
+ model,
174
+ details: `Applied fix for broken main build (run ${runId})`,
175
+ narrative: extractNarrative(resultContent, `Fixed broken main build (run ${runId}).`),
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Fix failing code or resolve merge conflicts on a pull request,
181
+ * or fix a broken build on main.
125
182
  *
126
- * Priority: conflicts first (if NON_TRIVIAL_FILES env is set), then failing checks.
183
+ * Priority: main build fix (if FIX_RUN_ID env is set),
184
+ * then conflicts (if NON_TRIVIAL_FILES env is set), then failing checks.
127
185
  *
128
186
  * @param {Object} context - Task context from index.js
129
187
  * @returns {Promise<Object>} Result with outcome, tokensUsed, model
@@ -131,8 +189,14 @@ async function resolveConflicts({ config, pr, prNumber, instructions, model, wri
131
189
  export async function fixCode(context) {
132
190
  const { octokit, repo, config, prNumber, instructions, writablePaths, testCommand, model } = context;
133
191
 
192
+ // Fix main build (no PR involved)
193
+ const fixRunId = process.env.FIX_RUN_ID || "";
194
+ if (fixRunId && !prNumber) {
195
+ return fixMainBuild({ config, runId: fixRunId, instructions, model, writablePaths, testCommand });
196
+ }
197
+
134
198
  if (!prNumber) {
135
- throw new Error("fix-code task requires pr-number input");
199
+ throw new Error("fix-code task requires pr-number input or FIX_RUN_ID env var");
136
200
  }
137
201
 
138
202
  // Fetch the PR
@@ -15,6 +15,10 @@ do it. Don't limit yourself to the minimal fix when you can deliver the whole mi
15
15
  The repository has a website in `src/web/` that uses the JS library. If a fix affects library
16
16
  exports or behaviour, also update the website files to stay in sync.
17
17
 
18
+ **Both unit tests AND behaviour tests must pass.** If the project has a `test:behaviour` npm script
19
+ (typically Playwright-based, testing the website), run it after your changes. If the behaviour test
20
+ expects elements like `#demo-output`, `#lib-name`, or `#lib-version`, ensure the website provides them.
21
+
18
22
  ## Merge Conflict Resolution
19
23
 
20
24
  When resolving merge conflicts (files containing <<<<<<< / ======= / >>>>>>> markers):
@@ -21,6 +21,11 @@ When writing both tests and implementation:
21
21
  - Ensure the implementation passes those tests before delivering
22
22
  - Do not write tests with different expectations than the implementation produces
23
23
 
24
+ **Both unit tests AND behaviour tests must pass.** If the project has a `test:behaviour` npm script
25
+ (typically Playwright-based, testing the website), run it after your changes. If your changes affect
26
+ the website (`src/web/`) or library exports, ensure the behaviour test still finds the expected
27
+ elements (e.g. `#demo-output`, `#lib-name`, `#lib-version`).
28
+
24
29
  Follow the linting guidelines and the formatting guidelines from the included config.
25
30
 
26
31
  ## Evidence Gathering
@@ -17,7 +17,7 @@
17
17
  "author": "",
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
- "@xn-intenton-z2a/agentic-lib": "^7.1.86"
20
+ "@xn-intenton-z2a/agentic-lib": "^7.1.88"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@playwright/test": "^1.58.0",