Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b665a4a
chore(codex): bootstrap PR for issue #123
github-actions[bot] Dec 24, 2025
b5e1512
Merge branch 'main' into codex/issue-123
stranske Dec 24, 2025
240ce5e
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 24, 2025
7307d4c
Trim CLI status summary details
Dec 24, 2025
f4fa571
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 24, 2025
4c8f371
Merge branch 'main' into codex/issue-123
stranske Dec 24, 2025
81ccce3
Merge branch 'main' into codex/issue-123
stranske Dec 24, 2025
0439872
Suppress keepalive instructions for CLI agents
Dec 24, 2025
dbe2ff0
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 24, 2025
7348647
Merge branch 'main' into codex/issue-123
stranske Dec 25, 2025
4f32dab
Merge branch 'main' into codex/issue-123
stranske Dec 25, 2025
b10e920
style: fix black formatting in test_keepalive_workflow.py
stranske Dec 25, 2025
cc50f75
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 25, 2025
ce8a5c4
feat(keepalive): emit step summary for agent runs
Dec 25, 2025
41f61e8
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 25, 2025
b4cf71e
test(keepalive): add per-run task delta to step summary
codex Dec 25, 2025
4ca6598
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 25, 2025
798f4b2
feat(pr-meta): infer agent type from labels
codex Dec 25, 2025
30345a3
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 25, 2025
d367b37
feat(gate-summary): skip CLI agent comments
Dec 25, 2025
cf6e4dd
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 25, 2025
ce35620
fix(keepalive): preserve summary when updating state
Dec 25, 2025
4016f3b
chore(codex-keepalive): apply updates (PR #124)
github-actions[bot] Dec 25, 2025
f90f90c
feat(keepalive): add automatic task checkbox reconciliation
stranske Dec 25, 2025
977b944
Merge branch 'main' into codex/issue-123
stranske Dec 25, 2025
55f05a3
feat(keepalive): allow productive work to extend past max_iterations
stranske Dec 25, 2025
18bf62a
fix(agents-verifier): use auth.json instead of fake API key
stranske Dec 25, 2025
686ffec
Update .github/scripts/keepalive_loop.js
stranske Dec 25, 2025
73367d2
Update .github/scripts/keepalive_state.js
stranske Dec 25, 2025
e288c5f
Update .github/scripts/keepalive_state.js
stranske Dec 25, 2025
5f2be33
Update .github/scripts/keepalive_loop.js
stranske Dec 25, 2025
3f4bf68
fix(keepalive): revert broken UI Codex patches that broke syntax
stranske Dec 25, 2025
ad5fb7b
Update .github/scripts/keepalive_loop.js
stranske Dec 25, 2025
a2bb23e
Update .github/workflows/agents-keepalive-loop.yml
stranske Dec 25, 2025
36e1825
fix(keepalive): restore analyzeTaskCompletion function arguments
stranske Dec 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .github/scripts/__tests__/agents-pr-meta-update-body.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const {
ensureChecklist,
extractBlock,
fetchConnectorCheckboxStates,
buildStatusBlock,
resolveAgentType,
} = require('../agents_pr_meta_update_body.js');

test('parseCheckboxStates extracts checked items from a checkbox list', () => {
Expand Down Expand Up @@ -318,3 +320,96 @@ test('fetchConnectorCheckboxStates handles comments with null user', async () =>
assert.strictEqual(states.size, 1);
assert.strictEqual(states.get('valid task'), true);
});

test('resolveAgentType prefers explicit inputs over labels', () => {
const agentType = resolveAgentType({
inputs: { agent_type: 'codex' },
env: { AGENT_TYPE: 'claude' },
pr: { labels: [{ name: 'agent:gemini' }] },
});

assert.strictEqual(agentType, 'codex');
});

test('resolveAgentType falls back to agent label when inputs are missing', () => {
const agentType = resolveAgentType({
inputs: {},
env: {},
pr: { labels: [{ name: 'priority:high' }, { name: 'agent:codex' }] },
});

assert.strictEqual(agentType, 'codex');
});

test('resolveAgentType returns empty string when no agent source is available', () => {
const agentType = resolveAgentType({
inputs: {},
env: {},
pr: { labels: [{ name: 'needs-human' }] },
});

assert.strictEqual(agentType, '');
});

test('buildStatusBlock hides workflow details for CLI agents', () => {
const workflowRuns = new Map([
['gate', {
name: 'Gate',
created_at: '2024-01-02T00:00:00Z',
status: 'completed',
conclusion: 'success',
html_url: 'https://example.com/run',
}],
]);

const output = buildStatusBlock({
scope: '- [ ] Scope item',
tasks: '- [ ] Task item',
acceptance: '- [ ] Acceptance item',
headSha: 'abc123',
workflowRuns,
requiredChecks: ['gate'],
existingBody: '',
connectorStates: new Map(),
core: null,
agentType: 'codex',
});

assert.ok(output.includes('## Automated Status Summary'));
assert.ok(output.includes('#### Scope'));
assert.ok(output.includes('#### Tasks'));
assert.ok(output.includes('#### Acceptance criteria'));
assert.ok(!output.includes('**Head SHA:**'));
assert.ok(!output.includes('**Latest Runs:**'));
assert.ok(!output.includes('**Required:**'));
assert.ok(!output.includes('| Workflow / Job |'));
});

test('buildStatusBlock includes workflow details for non-CLI agents', () => {
const workflowRuns = new Map([
['gate', {
name: 'Gate',
created_at: '2024-01-02T00:00:00Z',
status: 'completed',
conclusion: 'success',
html_url: 'https://example.com/run',
}],
]);

const output = buildStatusBlock({
scope: '- [ ] Scope item',
tasks: '- [ ] Task item',
acceptance: '- [ ] Acceptance item',
headSha: 'abc123',
workflowRuns,
requiredChecks: ['gate'],
existingBody: '',
connectorStates: new Map(),
core: null,
agentType: '',
});

assert.ok(output.includes('**Head SHA:** abc123'));
assert.ok(output.includes('**Required:** gate: ✅ success'));
assert.ok(output.includes('| Workflow / Job |'));
});
35 changes: 35 additions & 0 deletions .github/scripts/__tests__/comment-dedupe.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,38 @@ test('upsertAnchoredComment reads body from file and infers PR from anchor', asy

fs.unlinkSync(commentPath);
});

test('upsertAnchoredComment skips gate summary when agent label is present', async () => {
const actions = [];
const github = {
paginate: async (fn) => {
if (fn === github.rest.issues.listLabelsOnIssue) {
return [{ name: 'agent:codex' }];
}
throw new Error('listComments should not be called');
},
rest: {
issues: {
listLabelsOnIssue: async () => ({ data: [] }),
listComments: async () => ({ data: [] }),
updateComment: async () => actions.push('update'),
createComment: async () => {
actions.push('create');
return { data: { id: 1 } };
},
},
},
};

await upsertAnchoredComment({
github,
context: { repo: { owner: 'octo', repo: 'demo' } },
core: null,
prNumber: 12,
body: 'Gate summary\n<!-- gate-summary: pr=12 head=abc -->',
anchorPattern: /<!--\s*gate-summary:([^>]*)-->/i,
fallbackMarker: '<!-- gate-summary:',
});

assert.deepEqual(actions, []);
});
Loading