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.
Files changed (49) hide show
  1. package/CHANGELOG.md +130 -0
  2. package/README.md +25 -2
  3. package/dist/commands/daemon.d.ts.map +1 -1
  4. package/dist/commands/init.d.ts +3 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/labels.d.ts +11 -0
  7. package/dist/commands/labels.d.ts.map +1 -0
  8. package/dist/commands/status.d.ts.map +1 -1
  9. package/dist/commands/sync.d.ts.map +1 -1
  10. package/dist/commands/telemetry.d.ts.map +1 -1
  11. package/dist/index.js +2527 -519
  12. package/dist/lib/daemon-keys.d.ts +103 -0
  13. package/dist/lib/daemon-keys.d.ts.map +1 -0
  14. package/dist/lib/daemon.d.ts +8 -2
  15. package/dist/lib/daemon.d.ts.map +1 -1
  16. package/dist/lib/fleet-query.d.ts.map +1 -1
  17. package/dist/lib/labels.d.ts +68 -0
  18. package/dist/lib/labels.d.ts.map +1 -0
  19. package/dist/lib/manifest.d.ts +6 -0
  20. package/dist/lib/manifest.d.ts.map +1 -1
  21. package/dist/lib/presets.d.ts +52 -1
  22. package/dist/lib/presets.d.ts.map +1 -1
  23. package/dist/lib/runner.d.ts +114 -0
  24. package/dist/lib/runner.d.ts.map +1 -1
  25. package/dist/lib/telemetry.d.ts.map +1 -1
  26. package/dist/lib/terminal-card.d.ts +24 -1
  27. package/dist/lib/terminal-card.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/schema.json +74 -1
  30. package/templates/prompts/ORCHESTRATION.md +84 -41
  31. package/templates/prompts/_prompt-template.md +10 -13
  32. package/templates/prompts/analytics-review.md +4 -2
  33. package/templates/prompts/autowork.md +76 -35
  34. package/templates/prompts/dependency-update-security-check.md +4 -2
  35. package/templates/prompts/design-review.md +125 -0
  36. package/templates/prompts/issues-housekeeping.md +10 -8
  37. package/templates/prompts/optimizer.md +31 -12
  38. package/templates/prompts/peer-review.md +42 -7
  39. package/templates/prompts/product-planning.md +14 -10
  40. package/templates/workflows/autowork-cron.yml +137 -38
  41. package/templates/workflows/dependency-check-cron.yml +127 -2
  42. package/templates/workflows/design-review-cron.yml +221 -0
  43. package/templates/workflows/issues-housekeeping-cron.yml +127 -2
  44. package/templates/workflows/prompt-optimizer-cron.yml +134 -9
  45. package/templates/workflows/sync-fleet.yml +4 -0
  46. package/templates/workflows/trigger-autowork-manual.yml +154 -11
  47. package/templates/workflows/trigger-autowork-on-bug.yml +177 -9
  48. package/templates/workflows/trigger-autowork-on-merge.yml +178 -9
  49. 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 gemini-3.7-flash-high \
152
+ --model "$MODEL" \
83
153
  --output-format text \
84
- --print-timeout 40m \
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: 40
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 gemini-3.7-flash-high \
152
+ --model "$MODEL" \
83
153
  --output-format text \
84
- --print-timeout 35m \
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
- LATEST_LOG=$(ls -t .github/prompts/logs/optimizer/*.md 2>/dev/null | head -n 1)
91
- if [ -n "$LATEST_LOG" ] && [ -n "$GITHUB_STEP_SUMMARY" ]; then
92
- cat "$LATEST_LOG" >> "$GITHUB_STEP_SUMMARY"
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
- LATEST_LOG=$(ls -t .github/prompts/logs/optimizer/*.md 2>/dev/null | head -n 1)
105
- if [ -n "$LATEST_LOG" ] && [ -f "$LATEST_LOG" ]; then
106
- npx --yes jonah-fleet telemetry --emit --log "$LATEST_LOG" --endpoint "$TELEMETRY_ENDPOINT" || true
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