jonah-fleet 1.6.0 → 1.9.0
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/CHANGELOG.md +130 -0
- package/README.md +25 -2
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/labels.d.ts +11 -0
- package/dist/commands/labels.d.ts.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/telemetry.d.ts.map +1 -1
- package/dist/index.js +2527 -519
- package/dist/lib/daemon-keys.d.ts +103 -0
- package/dist/lib/daemon-keys.d.ts.map +1 -0
- package/dist/lib/daemon.d.ts +8 -2
- package/dist/lib/daemon.d.ts.map +1 -1
- package/dist/lib/fleet-query.d.ts.map +1 -1
- package/dist/lib/labels.d.ts +68 -0
- package/dist/lib/labels.d.ts.map +1 -0
- package/dist/lib/manifest.d.ts +6 -0
- package/dist/lib/manifest.d.ts.map +1 -1
- package/dist/lib/presets.d.ts +52 -1
- package/dist/lib/presets.d.ts.map +1 -1
- package/dist/lib/runner.d.ts +114 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/telemetry.d.ts.map +1 -1
- package/dist/lib/terminal-card.d.ts +24 -1
- package/dist/lib/terminal-card.d.ts.map +1 -1
- package/package.json +1 -1
- package/schema.json +74 -1
- package/templates/prompts/ORCHESTRATION.md +84 -41
- package/templates/prompts/_prompt-template.md +10 -13
- package/templates/prompts/analytics-review.md +4 -2
- package/templates/prompts/autowork.md +76 -35
- package/templates/prompts/dependency-update-security-check.md +4 -2
- package/templates/prompts/design-review.md +125 -0
- package/templates/prompts/issues-housekeeping.md +10 -8
- package/templates/prompts/optimizer.md +31 -12
- package/templates/prompts/peer-review.md +42 -7
- package/templates/prompts/product-planning.md +14 -10
- package/templates/workflows/autowork-cron.yml +137 -38
- package/templates/workflows/dependency-check-cron.yml +127 -2
- package/templates/workflows/design-review-cron.yml +221 -0
- package/templates/workflows/issues-housekeeping-cron.yml +127 -2
- package/templates/workflows/prompt-optimizer-cron.yml +134 -9
- package/templates/workflows/sync-fleet.yml +4 -0
- package/templates/workflows/trigger-autowork-manual.yml +154 -11
- package/templates/workflows/trigger-autowork-on-bug.yml +177 -9
- package/templates/workflows/trigger-autowork-on-merge.yml +178 -9
- package/templates/workflows/trigger-review-routine.yml +162 -22
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
name: Design Review Scheduled Cron (agy)
|
|
2
|
+
|
|
3
|
+
# Scheduled execution of the Design Review routine using Antigravity CLI on Gemini 3.7 Flash.
|
|
4
|
+
# Dispatches bi-weekly ahead of Product Planning, dynamically discovers player-facing surfaces,
|
|
5
|
+
# audits against DESIGN_SYSTEM.md and visual guardrails, files Autowork token cleanups,
|
|
6
|
+
# and stages pruning & redesign recommendations for Product Planning.
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
schedule:
|
|
10
|
+
# Bi-weekly on the 1st and 15th of the month at 06:00 UTC (08:00 Paris CEST)
|
|
11
|
+
# 3 hours prior to Product Planning cron at 09:00 UTC
|
|
12
|
+
- cron: '0 6 1,15 * *'
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
inputs:
|
|
15
|
+
target_surface:
|
|
16
|
+
description: 'Target surface or route to review (optional, e.g. "pronostics", "groupes", "home"; leaves empty for dynamic rotation)'
|
|
17
|
+
required: false
|
|
18
|
+
type: string
|
|
19
|
+
|
|
20
|
+
# Single-flight: do not run overlapping design review runs.
|
|
21
|
+
concurrency:
|
|
22
|
+
group: design-review-agent
|
|
23
|
+
cancel-in-progress: false
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
run-design-review:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
timeout-minutes: 60
|
|
29
|
+
permissions:
|
|
30
|
+
contents: write
|
|
31
|
+
issues: write
|
|
32
|
+
pull-requests: write
|
|
33
|
+
statuses: write
|
|
34
|
+
actions: read
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout repository
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
with:
|
|
39
|
+
fetch-depth: 0
|
|
40
|
+
persist-credentials: false
|
|
41
|
+
|
|
42
|
+
- name: Setup Node.js
|
|
43
|
+
uses: actions/setup-node@v4
|
|
44
|
+
with:
|
|
45
|
+
node-version: 22
|
|
46
|
+
|
|
47
|
+
- name: Configure Git author identity
|
|
48
|
+
env:
|
|
49
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
50
|
+
run: |
|
|
51
|
+
git config --global user.name "github-actions[bot]"
|
|
52
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
53
|
+
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
54
|
+
gh auth setup-git
|
|
55
|
+
|
|
56
|
+
- name: Cache Antigravity CLI
|
|
57
|
+
id: cache-agy
|
|
58
|
+
uses: actions/cache@v4
|
|
59
|
+
with:
|
|
60
|
+
path: ~/.local/bin/agy
|
|
61
|
+
key: agy-cli-linux-amd64-v1
|
|
62
|
+
|
|
63
|
+
- name: Install Antigravity CLI
|
|
64
|
+
if: steps.cache-agy.outputs.cache-hit != 'true'
|
|
65
|
+
run: |
|
|
66
|
+
curl -fsSL https://antigravity.google/cli/install.sh | bash
|
|
67
|
+
|
|
68
|
+
- name: Add Antigravity CLI to PATH
|
|
69
|
+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
70
|
+
|
|
71
|
+
- name: Write Antigravity OAuth Token
|
|
72
|
+
env:
|
|
73
|
+
ANTIGRAVITY_OAUTH_TOKEN: ${{ secrets.ANTIGRAVITY_OAUTH_TOKEN || secrets.GEMINI_API_KEY }}
|
|
74
|
+
run: |
|
|
75
|
+
if [ -z "$ANTIGRAVITY_OAUTH_TOKEN" ]; then
|
|
76
|
+
echo "::error::Neither ANTIGRAVITY_OAUTH_TOKEN nor GEMINI_API_KEY secret is set; cannot authenticate Antigravity CLI." >&2
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
mkdir -p "$HOME/.gemini/antigravity-cli"
|
|
80
|
+
chmod 700 "$HOME/.gemini/antigravity-cli"
|
|
81
|
+
printf '%s' "$ANTIGRAVITY_OAUTH_TOKEN" > "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
82
|
+
chmod 600 "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
83
|
+
|
|
84
|
+
- name: Fast preflight credential validation (SwarmClaw Pattern #2)
|
|
85
|
+
run: |
|
|
86
|
+
if [ ! -s "$HOME/.gemini/antigravity-cli/antigravity-oauth-token" ]; then
|
|
87
|
+
echo "::error::Preflight credential check failed: Antigravity OAuth token file is missing or empty." >&2
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
echo "✓ Preflight credential validation passed."
|
|
91
|
+
|
|
92
|
+
- name: Discover and compile domain skills (SwarmClaw Pattern #4)
|
|
93
|
+
id: skills
|
|
94
|
+
run: |
|
|
95
|
+
SKILLS_LIST="Read and follow .agents/skills/design-system/SKILL.md, .agents/skills/design-critique/SKILL.md, and .agents/skills/run/SKILL.md."
|
|
96
|
+
echo "skills_prompt=$SKILLS_LIST" >> "$GITHUB_OUTPUT"
|
|
97
|
+
|
|
98
|
+
- name: Initialize Routine Run Issue
|
|
99
|
+
id: run-issue
|
|
100
|
+
env:
|
|
101
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
102
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
103
|
+
RUN_ID: ${{ github.run_id }}
|
|
104
|
+
SERVER_URL: ${{ github.server_url }}
|
|
105
|
+
REPOSITORY: ${{ github.repository }}
|
|
106
|
+
run: |
|
|
107
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
108
|
+
TITLE="[design-review] run ${TIMESTAMP}"
|
|
109
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
110
|
+
- **Routine**: \`design-review\`
|
|
111
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
112
|
+
- **Trigger**: \`${EVENT_NAME}\`
|
|
113
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
117
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:design-review,status:running,runner:github-actions")
|
|
118
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
119
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
120
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
121
|
+
|
|
122
|
+
- name: Run Design Review
|
|
123
|
+
timeout-minutes: 50
|
|
124
|
+
env:
|
|
125
|
+
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
126
|
+
GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
127
|
+
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
128
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
129
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
130
|
+
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
|
|
131
|
+
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
|
132
|
+
TARGET_SURFACE: ${{ inputs.target_surface }}
|
|
133
|
+
SKILLS_PROMPT: ${{ steps.skills.outputs.skills_prompt }}
|
|
134
|
+
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
135
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
136
|
+
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
137
|
+
run: |
|
|
138
|
+
PROMPT="You are the Design Review routine for this repository. Read and follow the instructions in .github/prompts/design-review.md exactly. ${SKILLS_PROMPT}"
|
|
139
|
+
|
|
140
|
+
agy -p "$PROMPT" \
|
|
141
|
+
--model gemini-3.8-flash-high \
|
|
142
|
+
--output-format text \
|
|
143
|
+
--print-timeout 50m \
|
|
144
|
+
--dangerously-skip-permissions
|
|
145
|
+
|
|
146
|
+
- name: Emit run summary
|
|
147
|
+
if: always()
|
|
148
|
+
run: |
|
|
149
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
150
|
+
if [ -f "$REPORT_FILE" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
|
|
151
|
+
cat "$REPORT_FILE" >> "$GITHUB_STEP_SUMMARY"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
- name: Emit Fleet Telemetry (Opt-in)
|
|
155
|
+
if: always()
|
|
156
|
+
env:
|
|
157
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
158
|
+
TELEMETRY_ENDPOINT: ${{ secrets.JONAH_FLEET_TELEMETRY_ENDPOINT }}
|
|
159
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
160
|
+
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
161
|
+
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
162
|
+
run: |
|
|
163
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
164
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
165
|
+
npx --yes jonah-fleet telemetry --emit --log "$REPORT_FILE" --endpoint "$TELEMETRY_ENDPOINT" || true
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
- name: Reconcile Routine Run Issue
|
|
169
|
+
if: always()
|
|
170
|
+
env:
|
|
171
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
172
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
173
|
+
JOB_STATUS: ${{ job.status }}
|
|
174
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
175
|
+
RUN_ID: ${{ github.run_id }}
|
|
176
|
+
SERVER_URL: ${{ github.server_url }}
|
|
177
|
+
REPOSITORY: ${{ github.repository }}
|
|
178
|
+
run: |
|
|
179
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
180
|
+
echo "No routine issue to reconcile."
|
|
181
|
+
exit 0
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
185
|
+
|
|
186
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
187
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
188
|
+
else
|
|
189
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
190
|
+
- **Routine**: \`design-review\`
|
|
191
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
192
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
199
|
+
|
|
200
|
+
TEMP_BODY=$(mktemp)
|
|
201
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
202
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
203
|
+
rm -f "$TEMP_BODY"
|
|
204
|
+
|
|
205
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
206
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
207
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
208
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
209
|
+
else
|
|
210
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
211
|
+
- **Routine**: \`design-review\`
|
|
212
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
213
|
+
- **Step**: Actions execution halted before normal completion
|
|
214
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
218
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
219
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
220
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
221
|
+
fi
|
|
@@ -25,6 +25,7 @@ jobs:
|
|
|
25
25
|
uses: actions/checkout@v4
|
|
26
26
|
with:
|
|
27
27
|
fetch-depth: 0
|
|
28
|
+
persist-credentials: false
|
|
28
29
|
|
|
29
30
|
- name: Setup Node.js
|
|
30
31
|
uses: actions/setup-node@v4
|
|
@@ -32,10 +33,13 @@ jobs:
|
|
|
32
33
|
node-version: 22
|
|
33
34
|
|
|
34
35
|
- name: Configure Git author identity
|
|
36
|
+
env:
|
|
37
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
35
38
|
run: |
|
|
36
39
|
git config --global user.name "github-actions[bot]"
|
|
37
40
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
38
41
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
42
|
+
gh auth setup-git
|
|
39
43
|
|
|
40
44
|
- name: Cache Antigravity CLI
|
|
41
45
|
id: cache-agy
|
|
@@ -65,6 +69,69 @@ jobs:
|
|
|
65
69
|
printf '%s' "$ANTIGRAVITY_OAUTH_TOKEN" > "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
66
70
|
chmod 600 "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
67
71
|
|
|
72
|
+
- name: Resolve routine configuration
|
|
73
|
+
id: routine-config
|
|
74
|
+
run: |
|
|
75
|
+
ROUTINE="issues-housekeeping"
|
|
76
|
+
DEFAULT_MODEL="gemini-3.8-flash-medium"
|
|
77
|
+
DEFAULT_TIMEOUT="40"
|
|
78
|
+
|
|
79
|
+
MODEL="$DEFAULT_MODEL"
|
|
80
|
+
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
81
|
+
|
|
82
|
+
if [ -f "agents-manifest.json" ]; then
|
|
83
|
+
CONFIG_JSON=$(node -e '
|
|
84
|
+
try {
|
|
85
|
+
const fs = require("fs");
|
|
86
|
+
const m = JSON.parse(fs.readFileSync("agents-manifest.json", "utf8"));
|
|
87
|
+
const r = process.argv[1];
|
|
88
|
+
const model = m.models?.[r] || m.models?.default;
|
|
89
|
+
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
90
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "" }));
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
93
|
+
}
|
|
94
|
+
' "$ROUTINE")
|
|
95
|
+
|
|
96
|
+
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
97
|
+
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
98
|
+
|
|
99
|
+
if [ -n "$RESOLVED_MODEL" ]; then
|
|
100
|
+
MODEL="$RESOLVED_MODEL"
|
|
101
|
+
fi
|
|
102
|
+
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
103
|
+
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
104
|
+
fi
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
108
|
+
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
109
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
110
|
+
|
|
111
|
+
- name: Initialize Routine Run Issue
|
|
112
|
+
id: run-issue
|
|
113
|
+
env:
|
|
114
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
115
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
116
|
+
RUN_ID: ${{ github.run_id }}
|
|
117
|
+
SERVER_URL: ${{ github.server_url }}
|
|
118
|
+
REPOSITORY: ${{ github.repository }}
|
|
119
|
+
run: |
|
|
120
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
121
|
+
TITLE="[issues-housekeeping] run ${TIMESTAMP}"
|
|
122
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
123
|
+
- **Routine**: \`issues-housekeeping\`
|
|
124
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
125
|
+
- **Trigger**: \`${EVENT_NAME}\`
|
|
126
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
130
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:issues-housekeeping,status:running,runner:github-actions")
|
|
131
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
132
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
133
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
134
|
+
|
|
68
135
|
- name: Run Issues Housekeeping
|
|
69
136
|
timeout-minutes: 40
|
|
70
137
|
env:
|
|
@@ -72,6 +139,9 @@ jobs:
|
|
|
72
139
|
GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
73
140
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
74
141
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
142
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
143
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-medium' }}
|
|
144
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '40m' }}
|
|
75
145
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
76
146
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
77
147
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -79,7 +149,62 @@ jobs:
|
|
|
79
149
|
PROMPT="You are the Issues Housekeeping routine for this repository. Read and follow .github/prompts/issues-housekeeping.md exactly. Sweep open issues for staleness, duplicates, priority accuracy, and orphaned claims."
|
|
80
150
|
|
|
81
151
|
agy -p "$PROMPT" \
|
|
82
|
-
--model
|
|
152
|
+
--model "$MODEL" \
|
|
83
153
|
--output-format text \
|
|
84
|
-
--print-timeout
|
|
154
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
85
155
|
--dangerously-skip-permissions
|
|
156
|
+
|
|
157
|
+
- name: Reconcile Routine Run Issue
|
|
158
|
+
if: always()
|
|
159
|
+
env:
|
|
160
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
161
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
162
|
+
JOB_STATUS: ${{ job.status }}
|
|
163
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
164
|
+
RUN_ID: ${{ github.run_id }}
|
|
165
|
+
SERVER_URL: ${{ github.server_url }}
|
|
166
|
+
REPOSITORY: ${{ github.repository }}
|
|
167
|
+
run: |
|
|
168
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
169
|
+
echo "No routine issue to reconcile."
|
|
170
|
+
exit 0
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
174
|
+
|
|
175
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
176
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
177
|
+
else
|
|
178
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
179
|
+
- **Routine**: \`issues-housekeeping\`
|
|
180
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
181
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
188
|
+
|
|
189
|
+
TEMP_BODY=$(mktemp)
|
|
190
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
191
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
192
|
+
rm -f "$TEMP_BODY"
|
|
193
|
+
|
|
194
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
195
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
196
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
197
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
198
|
+
else
|
|
199
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
200
|
+
- **Routine**: \`issues-housekeeping\`
|
|
201
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
202
|
+
- **Step**: Actions execution halted before normal completion
|
|
203
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
207
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
208
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
209
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
210
|
+
fi
|
|
@@ -13,7 +13,7 @@ concurrency:
|
|
|
13
13
|
jobs:
|
|
14
14
|
run-optimizer:
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
|
-
timeout-minutes:
|
|
16
|
+
timeout-minutes: 45
|
|
17
17
|
permissions:
|
|
18
18
|
contents: write
|
|
19
19
|
issues: write
|
|
@@ -25,6 +25,7 @@ jobs:
|
|
|
25
25
|
uses: actions/checkout@v4
|
|
26
26
|
with:
|
|
27
27
|
fetch-depth: 0
|
|
28
|
+
persist-credentials: false
|
|
28
29
|
|
|
29
30
|
- name: Setup Node.js
|
|
30
31
|
uses: actions/setup-node@v4
|
|
@@ -32,10 +33,13 @@ jobs:
|
|
|
32
33
|
node-version: 22
|
|
33
34
|
|
|
34
35
|
- name: Configure Git author identity
|
|
36
|
+
env:
|
|
37
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
35
38
|
run: |
|
|
36
39
|
git config --global user.name "github-actions[bot]"
|
|
37
40
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
38
41
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
42
|
+
gh auth setup-git
|
|
39
43
|
|
|
40
44
|
- name: Cache Antigravity CLI
|
|
41
45
|
id: cache-agy
|
|
@@ -65,6 +69,69 @@ jobs:
|
|
|
65
69
|
printf '%s' "$ANTIGRAVITY_OAUTH_TOKEN" > "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
66
70
|
chmod 600 "$HOME/.gemini/antigravity-cli/antigravity-oauth-token"
|
|
67
71
|
|
|
72
|
+
- name: Resolve routine configuration
|
|
73
|
+
id: routine-config
|
|
74
|
+
run: |
|
|
75
|
+
ROUTINE="optimizer"
|
|
76
|
+
DEFAULT_MODEL="gemini-3.8-flash-high"
|
|
77
|
+
DEFAULT_TIMEOUT="35"
|
|
78
|
+
|
|
79
|
+
MODEL="$DEFAULT_MODEL"
|
|
80
|
+
TIMEOUT="$DEFAULT_TIMEOUT"
|
|
81
|
+
|
|
82
|
+
if [ -f "agents-manifest.json" ]; then
|
|
83
|
+
CONFIG_JSON=$(node -e '
|
|
84
|
+
try {
|
|
85
|
+
const fs = require("fs");
|
|
86
|
+
const m = JSON.parse(fs.readFileSync("agents-manifest.json", "utf8"));
|
|
87
|
+
const r = process.argv[1];
|
|
88
|
+
const model = m.models?.[r] || m.models?.default;
|
|
89
|
+
const timeout = m.budgets?.timeoutMinutes?.[r] || m.budgets?.timeoutMinutes?.default;
|
|
90
|
+
console.log(JSON.stringify({ model: model || "", timeout: timeout ? String(timeout) : "" }));
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.log(JSON.stringify({ model: "", timeout: "" }));
|
|
93
|
+
}
|
|
94
|
+
' "$ROUTINE")
|
|
95
|
+
|
|
96
|
+
RESOLVED_MODEL=$(node -e "try { console.log(JSON.parse(process.argv[1]).model || ''); } catch {}" "$CONFIG_JSON")
|
|
97
|
+
RESOLVED_TIMEOUT=$(node -e "try { console.log(JSON.parse(process.argv[1]).timeout || ''); } catch {}" "$CONFIG_JSON")
|
|
98
|
+
|
|
99
|
+
if [ -n "$RESOLVED_MODEL" ]; then
|
|
100
|
+
MODEL="$RESOLVED_MODEL"
|
|
101
|
+
fi
|
|
102
|
+
if [ -n "$RESOLVED_TIMEOUT" ]; then
|
|
103
|
+
TIMEOUT="$RESOLVED_TIMEOUT"
|
|
104
|
+
fi
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
108
|
+
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
109
|
+
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
110
|
+
|
|
111
|
+
- name: Initialize Routine Run Issue
|
|
112
|
+
id: run-issue
|
|
113
|
+
env:
|
|
114
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
115
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
116
|
+
RUN_ID: ${{ github.run_id }}
|
|
117
|
+
SERVER_URL: ${{ github.server_url }}
|
|
118
|
+
REPOSITORY: ${{ github.repository }}
|
|
119
|
+
run: |
|
|
120
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
121
|
+
TITLE="[optimizer] run ${TIMESTAMP}"
|
|
122
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
123
|
+
- **Routine**: \`optimizer\`
|
|
124
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
125
|
+
- **Trigger**: \`${EVENT_NAME}\`
|
|
126
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
130
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:optimizer,status:running,runner:github-actions")
|
|
131
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
132
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
133
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
134
|
+
|
|
68
135
|
- name: Run Prompt Optimizer
|
|
69
136
|
timeout-minutes: 35
|
|
70
137
|
env:
|
|
@@ -72,6 +139,9 @@ jobs:
|
|
|
72
139
|
GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
73
140
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
74
141
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
142
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
143
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-high' }}
|
|
144
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '35m' }}
|
|
75
145
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
76
146
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
77
147
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -79,17 +149,17 @@ jobs:
|
|
|
79
149
|
PROMPT="You are the Prompt Optimizer routine for this repository. Read and follow .github/prompts/optimizer.md exactly. Diagnose failures, token anomalies, and review loops, and propose preventative prompt and test fixes."
|
|
80
150
|
|
|
81
151
|
agy -p "$PROMPT" \
|
|
82
|
-
--model
|
|
152
|
+
--model "$MODEL" \
|
|
83
153
|
--output-format text \
|
|
84
|
-
--print-timeout
|
|
154
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
85
155
|
--dangerously-skip-permissions
|
|
86
156
|
|
|
87
157
|
- name: Emit run summary
|
|
88
158
|
if: always()
|
|
89
159
|
run: |
|
|
90
|
-
|
|
91
|
-
if [ -
|
|
92
|
-
cat "$
|
|
160
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
161
|
+
if [ -f "$REPORT_FILE" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
|
|
162
|
+
cat "$REPORT_FILE" >> "$GITHUB_STEP_SUMMARY"
|
|
93
163
|
fi
|
|
94
164
|
|
|
95
165
|
- name: Emit Fleet Telemetry (Opt-in)
|
|
@@ -101,7 +171,62 @@ jobs:
|
|
|
101
171
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
102
172
|
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
103
173
|
run: |
|
|
104
|
-
|
|
105
|
-
if [ -
|
|
106
|
-
npx --yes jonah-fleet telemetry --emit --log "$
|
|
174
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
175
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
176
|
+
npx --yes jonah-fleet telemetry --emit --log "$REPORT_FILE" --endpoint "$TELEMETRY_ENDPOINT" || true
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
- name: Reconcile Routine Run Issue
|
|
180
|
+
if: always()
|
|
181
|
+
env:
|
|
182
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
183
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
184
|
+
JOB_STATUS: ${{ job.status }}
|
|
185
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
186
|
+
RUN_ID: ${{ github.run_id }}
|
|
187
|
+
SERVER_URL: ${{ github.server_url }}
|
|
188
|
+
REPOSITORY: ${{ github.repository }}
|
|
189
|
+
run: |
|
|
190
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
191
|
+
echo "No routine issue to reconcile."
|
|
192
|
+
exit 0
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
196
|
+
|
|
197
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
198
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
199
|
+
else
|
|
200
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
201
|
+
- **Routine**: \`optimizer\`
|
|
202
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
203
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
210
|
+
|
|
211
|
+
TEMP_BODY=$(mktemp)
|
|
212
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
213
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
214
|
+
rm -f "$TEMP_BODY"
|
|
215
|
+
|
|
216
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
217
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
218
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
219
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
220
|
+
else
|
|
221
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
222
|
+
- **Routine**: \`optimizer\`
|
|
223
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
224
|
+
- **Step**: Actions execution halted before normal completion
|
|
225
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
229
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
230
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
231
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
107
232
|
fi
|
|
@@ -19,6 +19,7 @@ jobs:
|
|
|
19
19
|
uses: actions/checkout@v4
|
|
20
20
|
with:
|
|
21
21
|
fetch-depth: 0
|
|
22
|
+
persist-credentials: false
|
|
22
23
|
|
|
23
24
|
- name: Setup Node.js
|
|
24
25
|
uses: actions/setup-node@v4
|
|
@@ -26,9 +27,12 @@ jobs:
|
|
|
26
27
|
node-version: 22
|
|
27
28
|
|
|
28
29
|
- name: Configure Git author identity
|
|
30
|
+
env:
|
|
31
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
29
32
|
run: |
|
|
30
33
|
git config --global user.name "github-actions[bot]"
|
|
31
34
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
35
|
+
gh auth setup-git
|
|
32
36
|
|
|
33
37
|
- name: Run jonah-fleet sync
|
|
34
38
|
id: sync
|