@plainconceptsplatform/workflows 0.5.1 → 0.16.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 (60) hide show
  1. package/README.md +105 -88
  2. package/dist/catalog-installation.d.ts +67 -0
  3. package/dist/catalog-installation.js +485 -0
  4. package/dist/catalog-listing.d.ts +13 -0
  5. package/dist/catalog-listing.js +70 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +273 -0
  8. package/dist/package-baseline.d.ts +25 -0
  9. package/dist/package-baseline.js +138 -0
  10. package/dist/repository-inspection.d.ts +23 -0
  11. package/dist/repository-inspection.js +113 -0
  12. package/dist/route-processing.d.ts +4 -0
  13. package/dist/route-processing.js +80 -0
  14. package/dist/stack-defaults.d.ts +11 -0
  15. package/dist/stack-defaults.js +110 -0
  16. package/dist/tui.d.ts +25 -0
  17. package/dist/tui.js +271 -0
  18. package/dist/worker-env.d.ts +46 -0
  19. package/dist/worker-env.js +179 -0
  20. package/dist/workflow-catalog.d.ts +27 -0
  21. package/dist/workflow-catalog.js +57 -0
  22. package/loops/actions/add-issue-labels/action.yml +22 -2
  23. package/loops/actions/apply-agent-bundle/apply-bundle.sh +14 -1
  24. package/loops/actions/audit-close/action.yml +180 -128
  25. package/loops/actions/classify-route/action.yml +7 -0
  26. package/loops/actions/classify-route/classify-route.sh +28 -7
  27. package/loops/actions/cleanup-artifacts/action.yml +38 -12
  28. package/loops/actions/housekeeping/action.yml +251 -0
  29. package/loops/actions/identify-gate-subject/action.yml +3 -1
  30. package/loops/actions/merge-agent-pr/action.yml +13 -0
  31. package/loops/actions/remove-issue-labels/action.yml +4 -2
  32. package/loops/actions/report-workflow-errors/action.yml +385 -0
  33. package/loops/actions/validate-merge-gate-output/validate-merge-gate-output.sh +13 -1
  34. package/loops/actions/validate-refine-output/validate-refine-output.sh +18 -2
  35. package/loops/actions/validate-triage-output/action.yml +1 -1
  36. package/loops/actions/validate-triage-output/validate-triage-output.sh +9 -5
  37. package/loops/actions/verify-composite-actions/verify-composite-actions.sh +53 -0
  38. package/loops/actions/verify-refine-output/verify-refine-output.sh +20 -0
  39. package/loops/actions/verify-route-matrix/verify-route-matrix.sh +1017 -56
  40. package/loops/scripts/compile-agent-workflows.mjs +96 -1
  41. package/loops/scripts/merge-changelog.mjs +76 -0
  42. package/loops/templates/agentics/actionlint.yaml +13 -0
  43. package/loops/templates/agentics/agentics-checks.yml +203 -86
  44. package/loops/templates/agentics/agentics-error-report.yml +97 -0
  45. package/loops/templates/ci/app-ci-dotnet-next.yml +64 -2
  46. package/loops/templates/ci/app-ci-node-monorepo.yml +52 -0
  47. package/loops/templates/opencode/opencode.ci.json +3 -3
  48. package/loops/templates/opencode/opencode.ci.json.md +4 -1
  49. package/loops/workflows/agent-apply-review.md +452 -465
  50. package/loops/workflows/agent-audit.md +201 -213
  51. package/loops/workflows/agent-implement.md +616 -538
  52. package/loops/workflows/agent-merge-gate.md +830 -730
  53. package/loops/workflows/agent-refine.md +599 -609
  54. package/loops/workflows/agent-release.md +244 -258
  55. package/loops/workflows/agent-triage.md +476 -447
  56. package/loops/workflows/authorize-bot-work.yml +26 -6
  57. package/loops/workflows/work-router.yml +1185 -862
  58. package/package.json +9 -8
  59. package/loops/actions/stale-recovery/action.yml +0 -288
  60. package/loops/actions/update-changelog/action.yml +0 -113
@@ -33,7 +33,17 @@ env:
33
33
  SEED_PROJECT: src/App.Seed
34
34
  PRIMARY_DATABASE: app
35
35
  DATA_LAYER_DATABASE: numa_dl
36
- SQL_SA_PASSWORD: "YourStrong!Passw0rd"
36
+ # Derived per run rather than written down. The container is ephemeral, bound to a random
37
+ # host port and reachable only from this job, so the value protects nothing, but a literal
38
+ # password in a config file is a policy finding wherever it sits, and this file is public.
39
+ # It has to be a workflow-level expression: service containers receive their environment
40
+ # before any step runs, so a value generated in a step would arrive too late.
41
+ #
42
+ # The same expression is repeated inside the service's `options` above rather than read
43
+ # from here, because the `env` context is not available in `jobs.<id>.services` — only
44
+ # inside that service's own `env:`. Written as ${{ env.SQL_SA_PASSWORD }} there, the health
45
+ # check probes with an empty password and the service never reports healthy.
46
+ SQL_SA_PASSWORD: "Aa1!${{ github.run_id }}"
37
47
  WEB_PACKAGE: "@app/web"
38
48
  NPM_REGISTRY_URL: "//npm.pkg.github.com/"
39
49
  TRUFFLEHOG_IMAGE: "trufflesecurity/trufflehog:latest"
@@ -66,7 +76,7 @@ jobs:
66
76
  # exit code 1". Steps read the assigned port from the job.services context.
67
77
  - 1433
68
78
  options: >-
69
- --health-cmd "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P '${{ env.SQL_SA_PASSWORD }}' -Q 'SELECT 1' -C || exit 1"
79
+ --health-cmd "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 'Aa1!${{ github.run_id }}' -Q 'SELECT 1' -C || exit 1"
70
80
  --health-interval 10s --health-timeout 5s --health-retries 12 --health-start-period 30s
71
81
  defaults:
72
82
  run:
@@ -266,3 +276,55 @@ jobs:
266
276
  with:
267
277
  format: cyclonedx-json
268
278
  artifact-name: ${{ env.SBOM_ARTIFACT_NAME }}
279
+
280
+ # A bot pull request is opened with GITHUB_TOKEN, and GitHub delivers no workflow_run event
281
+ # for the CI runs that follow (the run's actor is the bot). The router's CI-completion route
282
+ # never sees them, so this job hands the verdict over from inside CI. workflow_dispatch is
283
+ # one of the two events GITHUB_TOKEN may raise, so no App token is needed here, and the
284
+ # router treats a dispatch as trusted. Human pull requests are left to the workflow_run
285
+ # route, which does fire for them. The reconcile belt remains the hourly fallback.
286
+ #
287
+ # If a deploy pipeline calls this workflow with `uses:`, that caller must also grant
288
+ # `actions: write`. A called workflow may not request a scope its caller withheld, and the
289
+ # whole run fails to start with zero jobs and no annotation when it does.
290
+ dispatch-merge-gate:
291
+ name: Dispatch merge gate
292
+ needs: [api, mutation-api, web, mutation-web]
293
+ if: >
294
+ always() &&
295
+ github.event_name == 'pull_request' &&
296
+ github.event.pull_request.head.repo.full_name == github.repository &&
297
+ github.event.pull_request.draft == false &&
298
+ github.event.pull_request.user.type == 'Bot'
299
+ runs-on: agents-arc
300
+ timeout-minutes: 5
301
+ permissions:
302
+ contents: read
303
+ actions: write
304
+ steps:
305
+ - name: Dispatch the merge gate with this run's verdict
306
+ env:
307
+ GH_TOKEN: ${{ github.token }}
308
+ REPO: ${{ github.repository }}
309
+ REF: ${{ github.event.repository.default_branch }}
310
+ PR_NUMBER: ${{ github.event.pull_request.number }}
311
+ RUN_ID: ${{ github.run_id }}
312
+ RESULTS: ${{ join(needs.*.result, ' ') }}
313
+ run: |
314
+ set -euo pipefail
315
+ conclusion=success
316
+ for result in $RESULTS; do
317
+ case "$result" in
318
+ failure) conclusion=failure; break ;;
319
+ cancelled | timed_out) conclusion=cancelled ;;
320
+ esac
321
+ done
322
+ # A cancelled run was superseded by a newer push, whose own run dispatches.
323
+ if [ "$conclusion" = cancelled ]; then
324
+ echo "CI was cancelled; not dispatching the merge gate."
325
+ exit 0
326
+ fi
327
+ echo "Dispatching the merge gate for PR #$PR_NUMBER with CI $conclusion (run $RUN_ID)."
328
+ gh workflow run work-router.yml --repo "$REPO" --ref "$REF" \
329
+ -f operation=merge-gate -f pr-number="$PR_NUMBER" \
330
+ -f ci-conclusion="$conclusion" -f ci-run-id="$RUN_ID"
@@ -206,3 +206,55 @@ jobs:
206
206
  with:
207
207
  format: cyclonedx-json
208
208
  artifact-name: ${{ env.SBOM_ARTIFACT_NAME }}
209
+
210
+ # A bot pull request is opened with GITHUB_TOKEN, and GitHub delivers no workflow_run event
211
+ # for the CI runs that follow (the run's actor is the bot). The router's CI-completion route
212
+ # never sees them, so this job hands the verdict over from inside CI. workflow_dispatch is
213
+ # one of the two events GITHUB_TOKEN may raise, so no App token is needed here, and the
214
+ # router treats a dispatch as trusted. Human pull requests are left to the workflow_run
215
+ # route, which does fire for them. The reconcile belt remains the hourly fallback.
216
+ #
217
+ # If a deploy pipeline calls this workflow with `uses:`, that caller must also grant
218
+ # `actions: write`. A called workflow may not request a scope its caller withheld, and the
219
+ # whole run fails to start with zero jobs and no annotation when it does.
220
+ dispatch-merge-gate:
221
+ name: Dispatch merge gate
222
+ needs: [lint, web, mutation-web, e2e, desktop, mobile]
223
+ if: >
224
+ always() &&
225
+ github.event_name == 'pull_request' &&
226
+ github.event.pull_request.head.repo.full_name == github.repository &&
227
+ github.event.pull_request.draft == false &&
228
+ github.event.pull_request.user.type == 'Bot'
229
+ runs-on: agents-arc
230
+ timeout-minutes: 5
231
+ permissions:
232
+ contents: read
233
+ actions: write
234
+ steps:
235
+ - name: Dispatch the merge gate with this run's verdict
236
+ env:
237
+ GH_TOKEN: ${{ github.token }}
238
+ REPO: ${{ github.repository }}
239
+ REF: ${{ github.event.repository.default_branch }}
240
+ PR_NUMBER: ${{ github.event.pull_request.number }}
241
+ RUN_ID: ${{ github.run_id }}
242
+ RESULTS: ${{ join(needs.*.result, ' ') }}
243
+ run: |
244
+ set -euo pipefail
245
+ conclusion=success
246
+ for result in $RESULTS; do
247
+ case "$result" in
248
+ failure) conclusion=failure; break ;;
249
+ cancelled | timed_out) conclusion=cancelled ;;
250
+ esac
251
+ done
252
+ # A cancelled run was superseded by a newer push, whose own run dispatches.
253
+ if [ "$conclusion" = cancelled ]; then
254
+ echo "CI was cancelled; not dispatching the merge gate."
255
+ exit 0
256
+ fi
257
+ echo "Dispatching the merge gate for PR #$PR_NUMBER with CI $conclusion (run $RUN_ID)."
258
+ gh workflow run work-router.yml --repo "$REPO" --ref "$REF" \
259
+ -f operation=merge-gate -f pr-number="$PR_NUMBER" \
260
+ -f ci-conclusion="$conclusion" -f ci-run-id="$RUN_ID"
@@ -7,7 +7,7 @@
7
7
  "ci-workflow-agent": {
8
8
  "description": "Executes GitHub Agentic Workflow tasks in CI.",
9
9
  "mode": "primary",
10
- "prompt": "You execute the GitHub Agentic Workflow task in the user prompt. Read AGENTS.md before any non-trivial change. Load only skills the workflow task explicitly names via skill(); when a workflow says load @skill-name, call skill(\"skill-name\"), the @ prefix is just a hint to use the skill tool. Execute only the requested task and required commands. Do not probe or inspect unrelated commands. The GitHub CLI is intentionally unauthenticated: never use `gh` for GitHub reads or writes. Read supplied workflow files first, then use the GitHub MCP tools only when fresh GitHub data is required. Use direct `safeoutputs` commands for GitHub writes. For syntax-only validation of a conventional GitHub Actions YAML file, use Ruby's standard YAML library; do not probe, install, or fall back through PyYAML, js-yaml, actionlint, or Docker. A task is complete only after every required Safe Outputs command succeeds. After the final required Safe Outputs command, stop immediately without further tools, prose, or model turns. Use `mcpscripts` only when the runtime explicitly lists it as available.\n\nOUTPUT DISCIPLINE: Do not narrate. Do not explain what you are about to do before doing it. Do not write prose between tool calls. Call tools silently. The only prose you produce is the final result or a brief error explanation when something fails. Never output sentences like 'Let me check...', 'Now I will...', 'I have enough context...', or 'Next I need to...'. If you are about to call a tool, just call it. If you must think, use the todowrite tool, not prose.\n\nMEMORY: agentmemory is the shared long-term store. Start non-trivial tasks by calling its recall/search tool with the key concepts of the task (component names, error text) and reuse what it returns instead of rediscovering it. Before finishing, store 1-3 concise memories of durable non-obvious learnings: architecture constraints, root causes and their fixes, decisions and their why. Skip trivia the repo already documents. Never store secrets or tokens."
10
+ "prompt": "You execute the GitHub Agentic Workflow task in the user prompt. Read AGENTS.md before any non-trivial change. Load only skills the workflow task explicitly names via skill(); when a workflow says load @skill-name, call skill(\"skill-name\"), the @ prefix is just a hint to use the skill tool. Execute only the requested task and required commands. Do not probe or inspect unrelated commands. The GitHub CLI is intentionally unauthenticated: never use `gh` for GitHub reads or writes. Read supplied workflow files first, then use the GitHub MCP tools only when fresh GitHub data is required. Use direct `safeoutputs` commands for GitHub writes. Each safe-output type has a small per-run allowance, and a call that fails still spends it: never send an empty, partial or test payload to discover what a tool accepts, because that probe can be recorded as a success, take the allowance with it, and leave the real call refused as over the limit, ending a run that did all the work and published none of it. Call each safe-output tool once, with the complete final payload, only when you are ready to commit to the outcome. For syntax-only validation of a conventional GitHub Actions YAML file, use Ruby's standard YAML library; do not probe, install, or fall back through PyYAML, js-yaml, actionlint, or Docker. A task is complete only after every required Safe Outputs command succeeds. After the final required Safe Outputs command, stop immediately without further tools, prose, or model turns. Use `mcpscripts` only when the runtime explicitly lists it as available.\n\nOUTPUT DISCIPLINE: Do not narrate. Do not explain what you are about to do before doing it. Do not write prose between tool calls. Call tools silently. The only prose you produce is the final result or a brief error explanation when something fails. Never output sentences like 'Let me check...', 'Now I will...', 'I have enough context...', or 'Next I need to...'. If you are about to call a tool, just call it. If you must think, use the todowrite tool, not prose.\n\nMEMORY: agentmemory is the shared long-term store. Start non-trivial tasks by calling its recall/search tool with the key concepts of the task (component names, error text) and reuse what it returns instead of rediscovering it. Before finishing, store 1-3 concise memories of durable non-obvious learnings: architecture constraints, root causes and their fixes, decisions and their why. Skip trivia the repo already documents. Never store secrets or tokens."
11
11
  }
12
12
  },
13
13
  "permission": {
@@ -30,9 +30,9 @@
30
30
  },
31
31
  "provider": {
32
32
  "forge": {
33
- "api": "{env:FORGE_API_URL}",
33
+ "api": "{env:OPENAI_BASE_URL}",
34
34
  "options": {
35
- "apiKey": "{env:FORGE_API_KEY}"
35
+ "apiKey": "{env:OPENAI_API_KEY}"
36
36
  },
37
37
  "models": {
38
38
  "glm-5-3": {
@@ -17,7 +17,10 @@ repository root as `opencode.ci.json`.
17
17
  ### Provider
18
18
 
19
19
  - The `forge` provider is OpenAI-compatible and reads its endpoint from
20
- `FORGE_API_URL` and its key from `FORGE_API_KEY` at runtime.
20
+ `OPENAI_BASE_URL` and its key from `OPENAI_API_KEY` at runtime. Those are the
21
+ two variables every worker's agent job sets (`engine.env` in the worker and
22
+ the `OPENAI_API_KEY` secret), so the file works with no consumer wiring. An
23
+ earlier template read `FORGE_API_URL`/`FORGE_API_KEY`, which nothing set.
21
24
  - Each consumer configures its own router endpoint, credential, model IDs, and
22
25
  capabilities. The workflow package does not assume a particular gateway
23
26
  host, authentication system, or model vendor.