jonah-fleet 1.8.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 +45 -0
- package/README.md +3 -3
- package/dist/commands/labels.d.ts +1 -1
- package/dist/commands/labels.d.ts.map +1 -1
- 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 +666 -151
- package/dist/lib/daemon-keys.d.ts.map +1 -1
- 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 +20 -0
- package/dist/lib/labels.d.ts.map +1 -1
- package/dist/lib/manifest.d.ts.map +1 -1
- package/dist/lib/presets.d.ts +6 -1
- package/dist/lib/presets.d.ts.map +1 -1
- package/dist/lib/runner.d.ts +48 -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 +15 -1
- package/dist/lib/terminal-card.d.ts.map +1 -1
- package/package.json +1 -1
- package/schema.json +10 -5
- package/templates/prompts/ORCHESTRATION.md +49 -11
- package/templates/prompts/_prompt-template.md +10 -13
- package/templates/prompts/analytics-review.md +4 -2
- package/templates/prompts/autowork.md +43 -12
- package/templates/prompts/dependency-update-security-check.md +4 -2
- package/templates/prompts/design-review.md +125 -0
- package/templates/prompts/issues-housekeeping.md +9 -7
- package/templates/prompts/optimizer.md +31 -12
- package/templates/prompts/peer-review.md +29 -4
- package/templates/prompts/product-planning.md +14 -10
- package/templates/workflows/autowork-cron.yml +99 -39
- package/templates/workflows/dependency-check-cron.yml +89 -3
- package/templates/workflows/design-review-cron.yml +221 -0
- package/templates/workflows/issues-housekeeping-cron.yml +89 -3
- package/templates/workflows/prompt-optimizer-cron.yml +96 -10
- package/templates/workflows/sync-fleet.yml +4 -0
- package/templates/workflows/trigger-autowork-manual.yml +116 -12
- package/templates/workflows/trigger-autowork-on-bug.yml +135 -5
- package/templates/workflows/trigger-autowork-on-merge.yml +135 -5
- package/templates/workflows/trigger-review-routine.yml +119 -18
|
@@ -24,7 +24,7 @@ concurrency:
|
|
|
24
24
|
jobs:
|
|
25
25
|
run-autowork:
|
|
26
26
|
runs-on: ubuntu-latest
|
|
27
|
-
timeout-minutes:
|
|
27
|
+
timeout-minutes: 70
|
|
28
28
|
permissions:
|
|
29
29
|
contents: write
|
|
30
30
|
issues: write
|
|
@@ -37,7 +37,7 @@ jobs:
|
|
|
37
37
|
with:
|
|
38
38
|
fetch-depth: 0
|
|
39
39
|
token: ${{ secrets.GH_PAT || github.token }}
|
|
40
|
-
|
|
40
|
+
persist-credentials: false
|
|
41
41
|
|
|
42
42
|
- name: Setup Node.js
|
|
43
43
|
uses: actions/setup-node@v4
|
|
@@ -45,10 +45,13 @@ jobs:
|
|
|
45
45
|
node-version: 22
|
|
46
46
|
|
|
47
47
|
- name: Configure Git author identity
|
|
48
|
+
env:
|
|
49
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
48
50
|
run: |
|
|
49
51
|
git config --global user.name "github-actions[bot]"
|
|
50
52
|
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
51
53
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
54
|
+
gh auth setup-git
|
|
52
55
|
|
|
53
56
|
- name: Cache Antigravity CLI
|
|
54
57
|
id: cache-agy
|
|
@@ -109,7 +112,7 @@ jobs:
|
|
|
109
112
|
id: routine-config
|
|
110
113
|
run: |
|
|
111
114
|
ROUTINE="autowork"
|
|
112
|
-
DEFAULT_MODEL="gemini-3.
|
|
115
|
+
DEFAULT_MODEL="gemini-3.8-flash-high"
|
|
113
116
|
DEFAULT_TIMEOUT="60"
|
|
114
117
|
|
|
115
118
|
MODEL="$DEFAULT_MODEL"
|
|
@@ -144,6 +147,35 @@ jobs:
|
|
|
144
147
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
145
148
|
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
146
149
|
|
|
150
|
+
- name: Initialize Routine Run Issue
|
|
151
|
+
id: run-issue
|
|
152
|
+
env:
|
|
153
|
+
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
154
|
+
TARGET_ARG: ${{ inputs.target_issue || inputs.issue_number }}
|
|
155
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
156
|
+
RUN_ID: ${{ github.run_id }}
|
|
157
|
+
SERVER_URL: ${{ github.server_url }}
|
|
158
|
+
REPOSITORY: ${{ github.repository }}
|
|
159
|
+
run: |
|
|
160
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
161
|
+
if [ -n "$TARGET_ARG" ]; then
|
|
162
|
+
TITLE="[autowork] run ${TIMESTAMP} (Issue #${TARGET_ARG})"
|
|
163
|
+
else
|
|
164
|
+
TITLE="[autowork] run ${TIMESTAMP}"
|
|
165
|
+
fi
|
|
166
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
167
|
+
- **Routine**: \`autowork\`
|
|
168
|
+
- **Timestamp**: \`${TIMESTAMP}\`
|
|
169
|
+
- **Trigger**: \`${EVENT_NAME}\`
|
|
170
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
174
|
+
ISSUE_URL=$(gh issue create --title "$TITLE" --body "$BODY" --label "routine-log,routine:autowork,status:running,runner:github-actions")
|
|
175
|
+
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
|
|
176
|
+
echo "issue_number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT"
|
|
177
|
+
echo "ROUTINE_ISSUE_NUMBER=$ISSUE_NUMBER" >> "$GITHUB_ENV"
|
|
178
|
+
|
|
147
179
|
- name: Run Autowork
|
|
148
180
|
timeout-minutes: 60
|
|
149
181
|
env:
|
|
@@ -152,7 +184,10 @@ jobs:
|
|
|
152
184
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
153
185
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
154
186
|
TARGET_ISSUE: ${{ inputs.target_issue || inputs.issue_number }}
|
|
187
|
+
ROUTINE_ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
155
188
|
SKILLS_PROMPT: ${{ steps.skills.outputs.skills_prompt }}
|
|
189
|
+
MODEL: ${{ steps.routine-config.outputs.model || 'gemini-3.8-flash-high' }}
|
|
190
|
+
PRINT_TIMEOUT: ${{ steps.routine-config.outputs.print_timeout || '60m' }}
|
|
156
191
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
157
192
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
158
193
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -164,17 +199,17 @@ jobs:
|
|
|
164
199
|
fi
|
|
165
200
|
|
|
166
201
|
agy -p "$PROMPT" \
|
|
167
|
-
--model "$
|
|
202
|
+
--model "$MODEL" \
|
|
168
203
|
--output-format text \
|
|
169
|
-
--print-timeout "$
|
|
204
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
170
205
|
--dangerously-skip-permissions
|
|
171
206
|
|
|
172
207
|
- name: Emit run summary
|
|
173
208
|
if: always()
|
|
174
209
|
run: |
|
|
175
|
-
|
|
176
|
-
if [ -
|
|
177
|
-
cat "$
|
|
210
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
211
|
+
if [ -f "$REPORT_FILE" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
|
|
212
|
+
cat "$REPORT_FILE" >> "$GITHUB_STEP_SUMMARY"
|
|
178
213
|
fi
|
|
179
214
|
|
|
180
215
|
- name: Emit Fleet Telemetry (Opt-in)
|
|
@@ -186,9 +221,9 @@ jobs:
|
|
|
186
221
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
187
222
|
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
188
223
|
run: |
|
|
189
|
-
|
|
190
|
-
if [ -
|
|
191
|
-
npx --yes jonah-fleet telemetry --emit --log "$
|
|
224
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
225
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
226
|
+
npx --yes jonah-fleet telemetry --emit --log "$REPORT_FILE" --endpoint "$TELEMETRY_ENDPOINT" || true
|
|
192
227
|
fi
|
|
193
228
|
|
|
194
229
|
- name: Verify Atomic Handoff Invariant (PR Existence Guard)
|
|
@@ -196,10 +231,10 @@ jobs:
|
|
|
196
231
|
env:
|
|
197
232
|
GH_TOKEN: ${{ github.token }}
|
|
198
233
|
run: |
|
|
199
|
-
|
|
200
|
-
if [ -
|
|
201
|
-
if grep -q "Result.*SUCCESS" "$
|
|
202
|
-
WORKED_BRANCH=$(grep -E '^\s*-\s*(Pushed branch|Branch):' "$
|
|
234
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
235
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
236
|
+
if grep -q "Result.*SUCCESS" "$REPORT_FILE"; then
|
|
237
|
+
WORKED_BRANCH=$(grep -E '^\s*-\s*(Pushed branch|Branch):' "$REPORT_FILE" | head -n 1 | sed -E 's/.*`([^`]+)`.*/\1/')
|
|
203
238
|
if [ -n "$WORKED_BRANCH" ] && [[ "$WORKED_BRANCH" =~ (feat|fix)/ ]]; then
|
|
204
239
|
echo "Verifying PR existence for branch: $WORKED_BRANCH"
|
|
205
240
|
PR_COUNT=$(gh pr list --head "$WORKED_BRANCH" --state all --json number --jq 'length' 2>/dev/null || echo "0")
|
|
@@ -212,33 +247,58 @@ jobs:
|
|
|
212
247
|
fi
|
|
213
248
|
fi
|
|
214
249
|
|
|
215
|
-
- name:
|
|
250
|
+
- name: Reconcile Routine Run Issue
|
|
216
251
|
if: always()
|
|
217
252
|
env:
|
|
218
253
|
GH_TOKEN: ${{ secrets.GH_PAT || github.token }}
|
|
254
|
+
ISSUE_NUMBER: ${{ steps.run-issue.outputs.issue_number }}
|
|
255
|
+
JOB_STATUS: ${{ job.status }}
|
|
256
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
257
|
+
RUN_ID: ${{ github.run_id }}
|
|
258
|
+
SERVER_URL: ${{ github.server_url }}
|
|
259
|
+
REPOSITORY: ${{ github.repository }}
|
|
219
260
|
run: |
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
261
|
+
if [ -z "$ISSUE_NUMBER" ]; then
|
|
262
|
+
echo "No routine issue to reconcile."
|
|
263
|
+
exit 0
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
REPORT_FILE=".jonah-fleet/run-report.md"
|
|
267
|
+
|
|
268
|
+
if [ -f "$REPORT_FILE" ]; then
|
|
269
|
+
BODY_CONTENT=$(cat "$REPORT_FILE")
|
|
270
|
+
else
|
|
271
|
+
BODY_CONTENT="### Autonomous Routine Execution Completed (${JOB_STATUS})
|
|
272
|
+
- **Routine**: \`autowork\`
|
|
273
|
+
- **Run ID**: [\`${RUN_ID}\`](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
274
|
+
- **Trigger**: \`${EVENT_NAME}\`"
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
FINAL_BODY="${BODY_CONTENT}
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
281
|
+
|
|
282
|
+
TEMP_BODY=$(mktemp)
|
|
283
|
+
echo "$FINAL_BODY" > "$TEMP_BODY"
|
|
284
|
+
gh issue edit "$ISSUE_NUMBER" --body-file "$TEMP_BODY"
|
|
285
|
+
rm -f "$TEMP_BODY"
|
|
286
|
+
|
|
287
|
+
if [ "$JOB_STATUS" = "success" ]; then
|
|
288
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:success" --remove-label "status:running"
|
|
289
|
+
gh issue close "$ISSUE_NUMBER" --reason completed
|
|
290
|
+
echo "✓ Routine run issue #$ISSUE_NUMBER closed as completed."
|
|
291
|
+
else
|
|
292
|
+
INTERRUPTION_BODY="### ❌ Milestone: Run Interrupted / Failed
|
|
293
|
+
- **Routine**: \`autowork\`
|
|
294
|
+
- **Status**: Workflow job failed or timed out (\`${JOB_STATUS}\`)
|
|
295
|
+
- **Step**: Actions execution halted before normal completion
|
|
296
|
+
- **Action Log**: [View GitHub Actions Run](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
_Generated by [Antigravity](${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID})_"
|
|
300
|
+
gh issue comment "$ISSUE_NUMBER" --body "$INTERRUPTION_BODY" || true
|
|
301
|
+
gh issue edit "$ISSUE_NUMBER" --add-label "status:failure,needs-attention" --remove-label "status:running"
|
|
302
|
+
echo "⚠️ Routine run issue #$ISSUE_NUMBER left open for triage (status: $JOB_STATUS)."
|
|
243
303
|
fi
|
|
244
304
|
|
|
@@ -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
|
|
@@ -69,7 +73,7 @@ jobs:
|
|
|
69
73
|
id: routine-config
|
|
70
74
|
run: |
|
|
71
75
|
ROUTINE="dependency-update-security-check"
|
|
72
|
-
DEFAULT_MODEL="gemini-3.
|
|
76
|
+
DEFAULT_MODEL="gemini-3.8-flash-medium"
|
|
73
77
|
DEFAULT_TIMEOUT="25"
|
|
74
78
|
|
|
75
79
|
MODEL="$DEFAULT_MODEL"
|
|
@@ -104,6 +108,30 @@ jobs:
|
|
|
104
108
|
echo "print_timeout=${TIMEOUT}m" >> "$GITHUB_OUTPUT"
|
|
105
109
|
echo "Resolved routine configuration: model=$MODEL, timeout=${TIMEOUT}m"
|
|
106
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="[dependency-check] run ${TIMESTAMP}"
|
|
122
|
+
BODY="### Autonomous Routine Execution in Progress
|
|
123
|
+
- **Routine**: \`dependency-update-security-check\`
|
|
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:dependency-check,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
|
+
|
|
107
135
|
- name: Run Dependency Update Check
|
|
108
136
|
timeout-minutes: 25
|
|
109
137
|
env:
|
|
@@ -111,6 +139,9 @@ jobs:
|
|
|
111
139
|
GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
112
140
|
ANTIGRAVITY_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
113
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 || '25m' }}
|
|
114
145
|
GITHUB_SERVER_URL: ${{ github.server_url }}
|
|
115
146
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
116
147
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
@@ -118,7 +149,62 @@ jobs:
|
|
|
118
149
|
PROMPT="You are the Dependency Update & Security Check routine. Read and follow .github/prompts/dependency-update-security-check.md exactly. Check dependencies for updates and vulnerabilities, and create or update tracking issues."
|
|
119
150
|
|
|
120
151
|
agy -p "$PROMPT" \
|
|
121
|
-
--model "$
|
|
152
|
+
--model "$MODEL" \
|
|
122
153
|
--output-format text \
|
|
123
|
-
--print-timeout "$
|
|
154
|
+
--print-timeout "$PRINT_TIMEOUT" \
|
|
124
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**: \`dependency-update-security-check\`
|
|
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**: \`dependency-check\`
|
|
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
|
|
@@ -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
|