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