@xn-intenton-z2a/agentic-lib 7.1.85 → 7.1.87
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/.github/workflows/agentic-lib-bot.yml +4 -1
- package/.github/workflows/agentic-lib-test.yml +22 -0
- package/.github/workflows/agentic-lib-workflow.yml +100 -5
- package/package.json +1 -1
- package/src/actions/agentic-step/tasks/fix-code.js +67 -3
- package/src/actions/agentic-step/tasks/supervise.js +53 -9
- package/src/agents/agent-apply-fix.md +4 -0
- package/src/agents/agent-issue-resolution.md +5 -0
- package/src/seeds/zero-package.json +1 -1
|
@@ -190,7 +190,10 @@ jobs:
|
|
|
190
190
|
|
|
191
191
|
dispatch-supervisor:
|
|
192
192
|
needs: [params, respond]
|
|
193
|
-
if:
|
|
193
|
+
if: >-
|
|
194
|
+
github.repository != 'xn-intenton-z2a/agentic-lib'
|
|
195
|
+
&& needs.respond.outputs.action == 'request-supervisor'
|
|
196
|
+
&& inputs.message == ''
|
|
194
197
|
runs-on: ubuntu-latest
|
|
195
198
|
steps:
|
|
196
199
|
- name: Dispatch supervisor workflow
|
|
@@ -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:
|
|
@@ -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
|
+
always()
|
|
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."
|
|
@@ -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,12 +616,52 @@ 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]
|
|
@@ -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:
|
|
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=
|
|
752
|
-
echo "
|
|
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'
|
package/package.json
CHANGED
|
@@ -121,9 +121,67 @@ async function resolveConflicts({ config, pr, prNumber, instructions, model, wri
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
* Fix
|
|
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:
|
|
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
|
|
@@ -71,6 +71,36 @@ async function dispatchBot(octokit, repo, message, discussionUrl) {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Post a comment directly to a discussion via GraphQL.
|
|
76
|
+
* Used for supervisor-originated messages to avoid triggering the bot workflow
|
|
77
|
+
* (which could loop back via request-supervisor).
|
|
78
|
+
*/
|
|
79
|
+
async function postDirectReply(octokit, repo, nodeId, body) {
|
|
80
|
+
if (process.env.GITHUB_REPOSITORY === "xn-intenton-z2a/agentic-lib") {
|
|
81
|
+
core.info("Skipping direct reply — running in SDK repo");
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!nodeId || !body) {
|
|
85
|
+
core.warning(`Cannot post direct reply: ${!nodeId ? "no nodeId" : "no body"}`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const mutation = `mutation($discussionId: ID!, $body: String!) {
|
|
90
|
+
addDiscussionComment(input: { discussionId: $discussionId, body: $body }) {
|
|
91
|
+
comment { url }
|
|
92
|
+
}
|
|
93
|
+
}`;
|
|
94
|
+
const { addDiscussionComment } = await octokit.graphql(mutation, {
|
|
95
|
+
discussionId: nodeId,
|
|
96
|
+
body,
|
|
97
|
+
});
|
|
98
|
+
core.info(`Posted direct reply: ${addDiscussionComment.comment.url}`);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
core.warning(`Could not post direct reply: ${err.message}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
74
104
|
async function gatherContext(octokit, repo, config, t) {
|
|
75
105
|
const mission = readOptionalFile(config.paths.mission.path);
|
|
76
106
|
const intentionLogFull = readOptionalFile(config.intentionBot.intentionFilepath);
|
|
@@ -100,11 +130,21 @@ async function gatherContext(octokit, repo, config, t) {
|
|
|
100
130
|
// Extract discussion URL from recent activity for supervisor reporting
|
|
101
131
|
const discussionUrlMatch = recentActivity.match(/https:\/\/github\.com\/[^/]+\/[^/]+\/discussions\/\d+/);
|
|
102
132
|
let activeDiscussionUrl = discussionUrlMatch ? discussionUrlMatch[0] : "";
|
|
133
|
+
let activeDiscussionNodeId = "";
|
|
103
134
|
|
|
104
135
|
// Fallback: look up the "Talk to the repository" discussion if not found in activity log
|
|
105
136
|
if (!activeDiscussionUrl) {
|
|
106
137
|
const talk = await findTalkDiscussion(octokit, repo);
|
|
107
138
|
activeDiscussionUrl = talk.url;
|
|
139
|
+
activeDiscussionNodeId = talk.nodeId;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Resolve node ID from URL if we got the URL from activity log
|
|
143
|
+
if (activeDiscussionUrl && !activeDiscussionNodeId) {
|
|
144
|
+
const talk = await findTalkDiscussion(octokit, repo);
|
|
145
|
+
if (talk.url === activeDiscussionUrl) {
|
|
146
|
+
activeDiscussionNodeId = talk.nodeId;
|
|
147
|
+
}
|
|
108
148
|
}
|
|
109
149
|
|
|
110
150
|
const featuresPath = config.paths.features.path;
|
|
@@ -271,6 +311,7 @@ async function gatherContext(octokit, repo, config, t) {
|
|
|
271
311
|
featureIssuesWipLimit: config.featureDevelopmentIssuesWipLimit,
|
|
272
312
|
maintenanceIssuesWipLimit: config.maintenanceIssuesWipLimit,
|
|
273
313
|
activeDiscussionUrl,
|
|
314
|
+
activeDiscussionNodeId,
|
|
274
315
|
missionComplete,
|
|
275
316
|
missionCompleteInfo,
|
|
276
317
|
missionFailed,
|
|
@@ -670,14 +711,15 @@ export async function supervise(context) {
|
|
|
670
711
|
// Step 2: Auto-announce on first run after init
|
|
671
712
|
// Detect first supervisor run: initTimestamp exists but no prior supervisor workflow runs since init
|
|
672
713
|
if (ctx.initTimestamp && !ctx.missionComplete && !ctx.missionFailed) {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
)
|
|
714
|
+
// Check for any prior agentic-lib-workflow runs since init (count > 1 because current run is included)
|
|
715
|
+
const supervisorRunCount = ctx.actionsSinceInit.filter(
|
|
716
|
+
(a) => a.name === "agentic-lib-workflow",
|
|
717
|
+
).length;
|
|
718
|
+
const hasPriorSupervisor = supervisorRunCount > 1 || ctx.recentActivity.includes("supervised:");
|
|
677
719
|
if (!hasPriorSupervisor && ctx.mission && ctx.activeDiscussionUrl) {
|
|
678
|
-
core.info("First supervisor run after init — announcing mission");
|
|
720
|
+
core.info("First supervisor run after init — announcing mission directly");
|
|
679
721
|
const announcement = `New mission started!\n\n**Mission:** ${ctx.mission.substring(0, 300)}\n\n**Website:** ${websiteUrl}`;
|
|
680
|
-
await
|
|
722
|
+
await postDirectReply(octokit, repo, ctx.activeDiscussionNodeId, announcement);
|
|
681
723
|
}
|
|
682
724
|
}
|
|
683
725
|
|
|
@@ -738,16 +780,18 @@ export async function supervise(context) {
|
|
|
738
780
|
|
|
739
781
|
// Step 3: Auto-respond when a message referral is present
|
|
740
782
|
// If the workflow was triggered with a message (from bot's request-supervisor),
|
|
741
|
-
// and the LLM didn't include a respond:discussions action, post back
|
|
783
|
+
// and the LLM didn't include a respond:discussions action, post back directly.
|
|
784
|
+
// Posts directly via GraphQL to avoid triggering the bot workflow (which would
|
|
785
|
+
// request-supervisor again, creating an infinite loop).
|
|
742
786
|
const workflowMessage = context.discussionUrl ? "" : (process.env.INPUT_MESSAGE || "");
|
|
743
787
|
if (workflowMessage && ctx.activeDiscussionUrl) {
|
|
744
788
|
const hasDiscussionResponse = results.some((r) => r.startsWith("respond-discussions:"));
|
|
745
789
|
if (!hasDiscussionResponse) {
|
|
746
|
-
core.info("Message referral detected — auto-
|
|
790
|
+
core.info("Message referral detected — posting auto-response directly");
|
|
747
791
|
const response = reasoning
|
|
748
792
|
? `Supervisor update: ${reasoning.substring(0, 400)}`
|
|
749
793
|
: `Supervisor processed your request. Actions taken: ${results.join(", ")}`;
|
|
750
|
-
await
|
|
794
|
+
await postDirectReply(octokit, repo, ctx.activeDiscussionNodeId, response);
|
|
751
795
|
results.push(`auto-respond:${ctx.activeDiscussionUrl}`);
|
|
752
796
|
}
|
|
753
797
|
}
|
|
@@ -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
|