lastlight 0.1.8 → 0.2.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/README.md +265 -118
- package/agent-context/rules.md +62 -9
- package/agent-context/security.md +69 -0
- package/config/default.yaml +89 -0
- package/deploy/.env.production.example +20 -2
- package/deploy/entrypoint.sh +16 -17
- package/deploy/native/README.md +160 -0
- package/deploy/native/install.sh +110 -0
- package/deploy/native/lastlight.env.example +95 -0
- package/deploy/native/lastlight.service +50 -0
- package/deploy/sandbox-entrypoint.sh +59 -42
- package/dist/admin/auth.d.ts +1 -1
- package/dist/admin/auth.js +3 -1
- package/dist/admin/auth.js.map +1 -1
- package/dist/admin/chat-session-reader.d.ts +11 -14
- package/dist/admin/chat-session-reader.js +27 -51
- package/dist/admin/chat-session-reader.js.map +1 -1
- package/dist/admin/docker.d.ts +37 -0
- package/dist/admin/docker.js +86 -1
- package/dist/admin/docker.js.map +1 -1
- package/dist/admin/index.js +38 -3
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/log-search.test.d.ts +1 -0
- package/dist/admin/log-search.test.js +78 -0
- package/dist/admin/log-search.test.js.map +1 -0
- package/dist/admin/routes.d.ts +52 -3
- package/dist/admin/routes.js +780 -63
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/routes.test.js +680 -14
- package/dist/admin/routes.test.js.map +1 -1
- package/dist/admin/server-logs.test.d.ts +1 -0
- package/dist/admin/server-logs.test.js +58 -0
- package/dist/admin/server-logs.test.js.map +1 -0
- package/dist/admin/sessions.d.ts +26 -39
- package/dist/admin/sessions.js +86 -310
- package/dist/admin/sessions.js.map +1 -1
- package/dist/admin/sessions.test.d.ts +1 -0
- package/dist/admin/sessions.test.js +78 -0
- package/dist/admin/sessions.test.js.map +1 -0
- package/dist/admin/version.d.ts +15 -0
- package/dist/admin/version.js +73 -0
- package/dist/admin/version.js.map +1 -0
- package/dist/admin/version.test.d.ts +1 -0
- package/dist/admin/version.test.js +71 -0
- package/dist/admin/version.test.js.map +1 -0
- package/dist/cli-config.d.ts +55 -0
- package/dist/cli-config.js +119 -0
- package/dist/cli-config.js.map +1 -0
- package/dist/cli-config.test.d.ts +1 -0
- package/dist/cli-config.test.js +92 -0
- package/dist/cli-config.test.js.map +1 -0
- package/dist/cli-format.d.ts +19 -0
- package/dist/cli-format.js +107 -0
- package/dist/cli-format.js.map +1 -0
- package/dist/cli-server.d.ts +73 -0
- package/dist/cli-server.js +347 -0
- package/dist/cli-server.js.map +1 -0
- package/dist/cli-server.test.d.ts +1 -0
- package/dist/cli-server.test.js +38 -0
- package/dist/cli-server.test.js.map +1 -0
- package/dist/cli-timeline.d.ts +35 -0
- package/dist/cli-timeline.js +373 -0
- package/dist/cli-timeline.js.map +1 -0
- package/dist/cli-timeline.test.d.ts +1 -0
- package/dist/cli-timeline.test.js +104 -0
- package/dist/cli-timeline.test.js.map +1 -0
- package/dist/cli.d.ts +0 -19
- package/dist/cli.js +910 -194
- package/dist/cli.js.map +1 -1
- package/dist/config-overlay.test.d.ts +1 -0
- package/dist/config-overlay.test.js +112 -0
- package/dist/config-overlay.test.js.map +1 -0
- package/dist/config-resolve.d.ts +28 -0
- package/dist/config-resolve.js +47 -0
- package/dist/config-resolve.js.map +1 -0
- package/dist/config-resolve.test.d.ts +1 -0
- package/dist/config-resolve.test.js +68 -0
- package/dist/config-resolve.test.js.map +1 -0
- package/dist/config.d.ts +62 -49
- package/dist/config.js +452 -76
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +201 -32
- package/dist/config.test.js.map +1 -1
- package/dist/connectors/github-webhook.js +83 -5
- package/dist/connectors/github-webhook.js.map +1 -1
- package/dist/connectors/github-webhook.test.d.ts +1 -0
- package/dist/connectors/github-webhook.test.js +156 -0
- package/dist/connectors/github-webhook.test.js.map +1 -0
- package/dist/connectors/messaging/session-manager.d.ts +18 -0
- package/dist/connectors/messaging/session-manager.js +83 -2
- package/dist/connectors/messaging/session-manager.js.map +1 -1
- package/dist/connectors/messaging/session-manager.test.d.ts +1 -0
- package/dist/connectors/messaging/session-manager.test.js +144 -0
- package/dist/connectors/messaging/session-manager.test.js.map +1 -0
- package/dist/connectors/slack/connector.d.ts +9 -0
- package/dist/connectors/slack/connector.js +15 -0
- package/dist/connectors/slack/connector.js.map +1 -1
- package/dist/connectors/slack/mrkdwn.js +81 -0
- package/dist/connectors/slack/mrkdwn.js.map +1 -1
- package/dist/connectors/slack/mrkdwn.test.js +49 -0
- package/dist/connectors/slack/mrkdwn.test.js.map +1 -1
- package/dist/connectors/types.d.ts +1 -1
- package/dist/cron/fanout.d.ts +33 -0
- package/dist/cron/fanout.js +55 -0
- package/dist/cron/fanout.js.map +1 -0
- package/dist/cron/fanout.test.d.ts +1 -0
- package/dist/cron/fanout.test.js +73 -0
- package/dist/cron/fanout.test.js.map +1 -0
- package/dist/cron/jobs.d.ts +5 -0
- package/dist/cron/jobs.js +10 -3
- package/dist/cron/jobs.js.map +1 -1
- package/dist/cron/scheduler.d.ts +12 -0
- package/dist/cron/scheduler.js +27 -1
- package/dist/cron/scheduler.js.map +1 -1
- package/dist/engine/agent-executor.d.ts +158 -0
- package/dist/engine/agent-executor.js +1140 -0
- package/dist/engine/agent-executor.js.map +1 -0
- package/dist/engine/agent-executor.test.d.ts +1 -0
- package/dist/engine/agent-executor.test.js +395 -0
- package/dist/engine/agent-executor.test.js.map +1 -0
- package/dist/engine/chat-runner.d.ts +123 -0
- package/dist/engine/chat-runner.js +379 -0
- package/dist/engine/chat-runner.js.map +1 -0
- package/dist/engine/chat-runner.test.d.ts +1 -0
- package/dist/engine/chat-runner.test.js +104 -0
- package/dist/engine/chat-runner.test.js.map +1 -0
- package/dist/engine/chat-skills.d.ts +45 -0
- package/dist/engine/chat-skills.js +184 -0
- package/dist/engine/chat-skills.js.map +1 -0
- package/dist/engine/chat-skills.test.d.ts +1 -0
- package/dist/engine/chat-skills.test.js +20 -0
- package/dist/engine/chat-skills.test.js.map +1 -0
- package/dist/engine/chat.d.ts +20 -23
- package/dist/engine/chat.js +251 -155
- package/dist/engine/chat.js.map +1 -1
- package/dist/engine/chat.test.d.ts +1 -0
- package/dist/engine/chat.test.js +42 -0
- package/dist/engine/chat.test.js.map +1 -0
- package/dist/engine/classifier.d.ts +35 -2
- package/dist/engine/classifier.js +170 -31
- package/dist/engine/classifier.js.map +1 -1
- package/dist/engine/classifier.test.d.ts +1 -0
- package/dist/engine/classifier.test.js +115 -0
- package/dist/engine/classifier.test.js.map +1 -0
- package/dist/engine/dispatcher.d.ts +60 -0
- package/dist/engine/dispatcher.js +601 -0
- package/dist/engine/dispatcher.js.map +1 -0
- package/dist/engine/dispatcher.test.d.ts +1 -0
- package/dist/engine/dispatcher.test.js +511 -0
- package/dist/engine/dispatcher.test.js.map +1 -0
- package/dist/engine/event-shim.d.ts +117 -0
- package/dist/engine/event-shim.js +435 -0
- package/dist/engine/event-shim.js.map +1 -0
- package/dist/engine/event-shim.test.d.ts +1 -0
- package/dist/engine/event-shim.test.js +194 -0
- package/dist/engine/event-shim.test.js.map +1 -0
- package/dist/engine/git-auth.d.ts +13 -17
- package/dist/engine/git-auth.js +99 -42
- package/dist/engine/git-auth.js.map +1 -1
- package/dist/engine/git-auth.test.d.ts +1 -0
- package/dist/engine/git-auth.test.js +117 -0
- package/dist/engine/git-auth.test.js.map +1 -0
- package/dist/engine/github-app-client.d.ts +7 -0
- package/dist/engine/github-app-client.js +16 -0
- package/dist/engine/github-app-client.js.map +1 -0
- package/dist/engine/github-app-client.test.d.ts +1 -0
- package/dist/engine/github-app-client.test.js +44 -0
- package/dist/engine/github-app-client.test.js.map +1 -0
- package/dist/engine/github-tools.d.ts +12 -0
- package/dist/engine/github-tools.js +261 -0
- package/dist/engine/github-tools.js.map +1 -0
- package/dist/engine/github.d.ts +1027 -43
- package/dist/engine/github.js +153 -14
- package/dist/engine/github.js.map +1 -1
- package/dist/engine/llm.d.ts +47 -0
- package/dist/engine/llm.js +221 -0
- package/dist/engine/llm.js.map +1 -0
- package/dist/engine/llm.test.d.ts +1 -0
- package/dist/engine/llm.test.js +189 -0
- package/dist/engine/llm.test.js.map +1 -0
- package/dist/engine/profiles.d.ts +249 -0
- package/dist/engine/profiles.js +42 -0
- package/dist/engine/profiles.js.map +1 -0
- package/dist/engine/router.d.ts +12 -6
- package/dist/engine/router.js +339 -81
- package/dist/engine/router.js.map +1 -1
- package/dist/engine/router.test.js +428 -78
- package/dist/engine/router.test.js.map +1 -1
- package/dist/engine/screen.d.ts +41 -0
- package/dist/engine/screen.js +93 -0
- package/dist/engine/screen.js.map +1 -0
- package/dist/engine/screen.test.d.ts +1 -0
- package/dist/engine/screen.test.js +82 -0
- package/dist/engine/screen.test.js.map +1 -0
- package/dist/index.js +423 -437
- package/dist/index.js.map +1 -1
- package/dist/managed-repos.d.ts +7 -9
- package/dist/managed-repos.js +12 -15
- package/dist/managed-repos.js.map +1 -1
- package/dist/managed-repos.test.js +24 -19
- package/dist/managed-repos.test.js.map +1 -1
- package/dist/notify/index.d.ts +15 -0
- package/dist/notify/index.js +6 -0
- package/dist/notify/index.js.map +1 -0
- package/dist/notify/model.d.ts +57 -0
- package/dist/notify/model.js +89 -0
- package/dist/notify/model.js.map +1 -0
- package/dist/notify/model.test.d.ts +1 -0
- package/dist/notify/model.test.js +109 -0
- package/dist/notify/model.test.js.map +1 -0
- package/dist/notify/notifier.d.ts +17 -0
- package/dist/notify/notifier.js +87 -0
- package/dist/notify/notifier.js.map +1 -0
- package/dist/notify/notifier.test.d.ts +1 -0
- package/dist/notify/notifier.test.js +100 -0
- package/dist/notify/notifier.test.js.map +1 -0
- package/dist/notify/render.d.ts +21 -0
- package/dist/notify/render.js +59 -0
- package/dist/notify/render.js.map +1 -0
- package/dist/notify/render.test.d.ts +1 -0
- package/dist/notify/render.test.js +65 -0
- package/dist/notify/render.test.js.map +1 -0
- package/dist/notify/transports/github.d.ts +26 -0
- package/dist/notify/transports/github.js +26 -0
- package/dist/notify/transports/github.js.map +1 -0
- package/dist/notify/transports/slack.d.ts +26 -0
- package/dist/notify/transports/slack.js +28 -0
- package/dist/notify/transports/slack.js.map +1 -0
- package/dist/notify/transports.test.d.ts +1 -0
- package/dist/notify/transports.test.js +71 -0
- package/dist/notify/transports.test.js.map +1 -0
- package/dist/notify/types.d.ts +95 -0
- package/dist/notify/types.js +16 -0
- package/dist/notify/types.js.map +1 -0
- package/dist/sandbox/docker-compose.test.d.ts +1 -0
- package/dist/sandbox/docker-compose.test.js +128 -0
- package/dist/sandbox/docker-compose.test.js.map +1 -0
- package/dist/sandbox/docker.d.ts +97 -9
- package/dist/sandbox/docker.js +192 -41
- package/dist/sandbox/docker.js.map +1 -1
- package/dist/sandbox/docker.test.d.ts +1 -0
- package/dist/sandbox/docker.test.js +137 -0
- package/dist/sandbox/docker.test.js.map +1 -0
- package/dist/sandbox/egress-allowlist.d.ts +69 -0
- package/dist/sandbox/egress-allowlist.js +164 -0
- package/dist/sandbox/egress-allowlist.js.map +1 -0
- package/dist/sandbox/egress-allowlist.test.d.ts +1 -0
- package/dist/sandbox/egress-allowlist.test.js +65 -0
- package/dist/sandbox/egress-allowlist.test.js.map +1 -0
- package/dist/sandbox/egress-firewall-config.d.ts +127 -0
- package/dist/sandbox/egress-firewall-config.js +434 -0
- package/dist/sandbox/egress-firewall-config.js.map +1 -0
- package/dist/sandbox/egress-firewall-config.test.d.ts +1 -0
- package/dist/sandbox/egress-firewall-config.test.js +244 -0
- package/dist/sandbox/egress-firewall-config.test.js.map +1 -0
- package/dist/sandbox/images.d.ts +23 -0
- package/dist/sandbox/images.js +55 -0
- package/dist/sandbox/images.js.map +1 -0
- package/dist/sandbox/index.d.ts +82 -3
- package/dist/sandbox/index.js +223 -93
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/index.test.d.ts +1 -0
- package/dist/sandbox/index.test.js +157 -0
- package/dist/sandbox/index.test.js.map +1 -0
- package/dist/session-log.d.ts +63 -0
- package/dist/session-log.js +290 -0
- package/dist/session-log.js.map +1 -0
- package/dist/session-log.test.d.ts +1 -0
- package/dist/session-log.test.js +85 -0
- package/dist/session-log.test.js.map +1 -0
- package/dist/setup.d.ts +31 -12
- package/dist/setup.js +516 -174
- package/dist/setup.js.map +1 -1
- package/dist/setup.test.js +138 -6
- package/dist/setup.test.js.map +1 -1
- package/dist/state/approval-store.d.ts +86 -0
- package/dist/state/approval-store.js +140 -0
- package/dist/state/approval-store.js.map +1 -0
- package/dist/state/build-assets.d.ts +50 -0
- package/dist/state/build-assets.js +154 -0
- package/dist/state/build-assets.js.map +1 -0
- package/dist/state/build-assets.test.d.ts +1 -0
- package/dist/state/build-assets.test.js +106 -0
- package/dist/state/build-assets.test.js.map +1 -0
- package/dist/state/db.d.ts +65 -333
- package/dist/state/db.js +112 -835
- package/dist/state/db.js.map +1 -1
- package/dist/state/db.test.js +127 -91
- package/dist/state/db.test.js.map +1 -1
- package/dist/state/execution-store.d.ts +257 -0
- package/dist/state/execution-store.js +527 -0
- package/dist/state/execution-store.js.map +1 -0
- package/dist/state/migrate.d.ts +15 -0
- package/dist/state/migrate.js +175 -0
- package/dist/state/migrate.js.map +1 -0
- package/dist/state/workflow-run-store.d.ts +195 -0
- package/dist/state/workflow-run-store.js +363 -0
- package/dist/state/workflow-run-store.js.map +1 -0
- package/dist/state/workflow-run-store.test.d.ts +1 -0
- package/dist/state/workflow-run-store.test.js +264 -0
- package/dist/state/workflow-run-store.test.js.map +1 -0
- package/dist/telemetry/index.d.ts +38 -0
- package/dist/telemetry/index.js +253 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/index.test.d.ts +1 -0
- package/dist/telemetry/index.test.js +73 -0
- package/dist/telemetry/index.test.js.map +1 -0
- package/dist/telemetry/pi-events.d.ts +12 -0
- package/dist/telemetry/pi-events.js +134 -0
- package/dist/telemetry/pi-events.js.map +1 -0
- package/dist/telemetry/pi-events.test.d.ts +1 -0
- package/dist/telemetry/pi-events.test.js +69 -0
- package/dist/telemetry/pi-events.test.js.map +1 -0
- package/dist/workflows/dag.d.ts +13 -1
- package/dist/workflows/dag.js +7 -3
- package/dist/workflows/dag.js.map +1 -1
- package/dist/workflows/dag.test.js +22 -0
- package/dist/workflows/dag.test.js.map +1 -1
- package/dist/workflows/golden-build.test.d.ts +1 -0
- package/dist/workflows/golden-build.test.js +45 -0
- package/dist/workflows/golden-build.test.js.map +1 -0
- package/dist/workflows/loader-overlay.test.d.ts +1 -0
- package/dist/workflows/loader-overlay.test.js +101 -0
- package/dist/workflows/loader-overlay.test.js.map +1 -0
- package/dist/workflows/loader.d.ts +36 -11
- package/dist/workflows/loader.js +311 -87
- package/dist/workflows/loader.js.map +1 -1
- package/dist/workflows/loader.test.js +114 -10
- package/dist/workflows/loader.test.js.map +1 -1
- package/dist/workflows/loop-eval.js +2 -0
- package/dist/workflows/loop-eval.js.map +1 -1
- package/dist/workflows/loop-eval.test.js +14 -0
- package/dist/workflows/loop-eval.test.js.map +1 -1
- package/dist/workflows/phase-executor.d.ts +145 -0
- package/dist/workflows/phase-executor.js +691 -0
- package/dist/workflows/phase-executor.js.map +1 -0
- package/dist/workflows/phase-executor.test.d.ts +1 -0
- package/dist/workflows/phase-executor.test.js +434 -0
- package/dist/workflows/phase-executor.test.js.map +1 -0
- package/dist/workflows/phase-ref.d.ts +44 -0
- package/dist/workflows/phase-ref.js +78 -0
- package/dist/workflows/phase-ref.js.map +1 -0
- package/dist/workflows/phase-ref.test.d.ts +1 -0
- package/dist/workflows/phase-ref.test.js +24 -0
- package/dist/workflows/phase-ref.test.js.map +1 -0
- package/dist/workflows/resume.d.ts +5 -11
- package/dist/workflows/resume.js +88 -7
- package/dist/workflows/resume.js.map +1 -1
- package/dist/workflows/runner.d.ts +34 -27
- package/dist/workflows/runner.js +252 -930
- package/dist/workflows/runner.js.map +1 -1
- package/dist/workflows/runner.test.js +346 -35
- package/dist/workflows/runner.test.js.map +1 -1
- package/dist/workflows/schema.d.ts +52 -10
- package/dist/workflows/schema.js +147 -7
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/simple.d.ts +67 -3
- package/dist/workflows/simple.js +248 -87
- package/dist/workflows/simple.js.map +1 -1
- package/dist/workflows/simple.test.d.ts +1 -0
- package/dist/workflows/simple.test.js +107 -0
- package/dist/workflows/simple.test.js.map +1 -0
- package/dist/workflows/templates.d.ts +29 -0
- package/dist/workflows/templates.js +42 -4
- package/dist/workflows/templates.js.map +1 -1
- package/dist/workflows/templates.test.js +103 -0
- package/dist/workflows/templates.test.js.map +1 -1
- package/dist/workflows/triggers.d.ts +21 -0
- package/dist/workflows/triggers.js +44 -0
- package/dist/workflows/triggers.js.map +1 -0
- package/dist/workflows/verdict.d.ts +19 -0
- package/dist/workflows/verdict.js +30 -0
- package/dist/workflows/verdict.js.map +1 -0
- package/dist/workflows/verdict.test.d.ts +1 -0
- package/dist/workflows/verdict.test.js +44 -0
- package/dist/workflows/verdict.test.js.map +1 -0
- package/dist/worktree/manager.d.ts +1 -1
- package/dist/worktree/manager.js +14 -14
- package/dist/worktree/manager.js.map +1 -1
- package/dist/worktree/manager.test.d.ts +1 -0
- package/dist/worktree/manager.test.js +87 -0
- package/dist/worktree/manager.test.js.map +1 -0
- package/docker-compose.yml +206 -5
- package/package.json +19 -7
- package/sandbox.Dockerfile +97 -18
- package/skills/README.md +40 -0
- package/skills/browser-qa/SKILL.md +193 -0
- package/skills/browser-qa/scripts/agent-browser.mjs +380 -0
- package/skills/building/SKILL.md +95 -0
- package/skills/chat/SKILL.md +30 -11
- package/skills/code-review/SKILL.md +59 -0
- package/skills/debug-production/SKILL.md +108 -0
- package/skills/demo/SKILL.md +194 -0
- package/skills/demo/scripts/compose-demo.sh +205 -0
- package/skills/issue-answer/SKILL.md +90 -0
- package/skills/issue-comment/SKILL.md +38 -24
- package/skills/issue-triage/SKILL.md +103 -37
- package/skills/issue-triage/references/AGENT-BRIEF.md +61 -0
- package/skills/pr-comment/SKILL.md +64 -0
- package/skills/pr-review/SKILL.md +65 -49
- package/skills/qa-test/SKILL.md +97 -0
- package/skills/repo-health/SKILL.md +48 -45
- package/skills/security-feedback/SKILL.md +173 -0
- package/skills/security-feedback/references/templates.md +77 -0
- package/skills/security-review/SKILL.md +213 -0
- package/skills/security-review/references/issue-format.md +302 -0
- package/skills/verify/SKILL.md +118 -0
- package/workflows/answer.yaml +37 -0
- package/workflows/build.yaml +32 -22
- package/workflows/cron-security.yaml +6 -0
- package/workflows/demo.yaml +55 -0
- package/workflows/explore.yaml +9 -0
- package/workflows/pr-comment.yaml +16 -0
- package/workflows/pr-fix.yaml +3 -0
- package/workflows/pr-review.yaml +4 -1
- package/workflows/prompts/answer.md +67 -0
- package/workflows/prompts/architect.md +24 -7
- package/workflows/prompts/demo.md +100 -0
- package/workflows/prompts/executor.md +29 -20
- package/workflows/prompts/explore-ask.md +51 -22
- package/workflows/prompts/explore-publish.md +2 -2
- package/workflows/prompts/explore-read.md +24 -10
- package/workflows/prompts/explore-synthesize.md +15 -8
- package/workflows/prompts/fix.md +9 -10
- package/workflows/prompts/guardrails.md +26 -8
- package/workflows/prompts/pr-fix.md +6 -7
- package/workflows/prompts/pr.md +11 -10
- package/workflows/prompts/qa-browser.md +95 -0
- package/workflows/prompts/qa-synth.md +44 -0
- package/workflows/prompts/qa-test.md +60 -0
- package/workflows/prompts/re-reviewer.md +8 -9
- package/workflows/prompts/reviewer.md +10 -9
- package/workflows/prompts/verify-browser.md +93 -0
- package/workflows/prompts/verify-synth.md +44 -0
- package/workflows/prompts/verify.md +63 -0
- package/workflows/qa-test.yaml +87 -0
- package/workflows/security-feedback.yaml +25 -0
- package/workflows/security-review.yaml +29 -0
- package/workflows/verify.yaml +85 -0
- package/deploy/mcp-config.tmpl.json +0 -14
- package/dist/cron/rate-limits.d.ts +0 -26
- package/dist/cron/rate-limits.js +0 -193
- package/dist/cron/rate-limits.js.map +0 -1
- package/dist/engine/executor.d.ts +0 -75
- package/dist/engine/executor.js +0 -292
- package/dist/engine/executor.js.map +0 -1
- package/mcp-github-app/package.json +0 -18
- package/mcp-github-app/src/auth.js +0 -66
- package/mcp-github-app/src/github.js +0 -371
- package/mcp-github-app/src/index.js +0 -534
- package/skills/devops/webhook-subscriptions/SKILL.md +0 -180
- package/skills/github/DESCRIPTION.md +0 -3
- package/skills/github/codebase-inspection/SKILL.md +0 -115
- package/skills/github/github-auth/SKILL.md +0 -54
- package/skills/github/github-auth/scripts/gh-env.sh +0 -66
- package/skills/github/github-code-review/SKILL.md +0 -480
- package/skills/github/github-code-review/references/review-output-template.md +0 -74
- package/skills/github/github-issues/SKILL.md +0 -369
- package/skills/github/github-issues/templates/bug-report.md +0 -35
- package/skills/github/github-issues/templates/feature-request.md +0 -31
- package/skills/github/github-pr-workflow/SKILL.md +0 -395
- package/skills/github/github-pr-workflow/references/ci-troubleshooting.md +0 -183
- package/skills/github/github-pr-workflow/references/conventional-commits.md +0 -71
- package/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +0 -35
- package/skills/github/github-pr-workflow/templates/pr-body-feature.md +0 -33
- package/skills/github/github-repo-management/SKILL.md +0 -515
- package/skills/github/github-repo-management/references/github-api-cheatsheet.md +0 -161
- package/skills/github-orchestrator/SKILL.md +0 -103
- package/skills/mcp/DESCRIPTION.md +0 -3
- package/skills/mcp/mcporter/SKILL.md +0 -122
- package/skills/mcp/native-mcp/SKILL.md +0 -356
- package/skills/software-development/architect/SKILL.md +0 -154
- package/skills/software-development/assure-guardrails/SKILL.md +0 -239
- package/skills/software-development/plan/SKILL.md +0 -64
- package/skills/software-development/requesting-code-review/SKILL.md +0 -291
- package/skills/software-development/subagent-driven-development/SKILL.md +0 -433
- package/skills/software-development/systematic-debugging/SKILL.md +0 -366
- package/skills/software-development/test-driven-development/SKILL.md +0 -342
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# compose-demo.sh — composite a raw browser screen recording into a titled,
|
|
3
|
+
# size-capped demo mp4 using ffmpeg only (NO Remotion, NO headless render).
|
|
4
|
+
#
|
|
5
|
+
# Used by the `/demo` workflow: agent-browser records the session to a .webm,
|
|
6
|
+
# this script turns it into a polished, GitHub-embeddable mp4.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# compose-demo.sh --output demo.mp4 --title "PR #42 — Add dark mode" \
|
|
10
|
+
# [--subtitle "..."] [--layout single|side-by-side] \
|
|
11
|
+
# [--labels "BEFORE (main)" "AFTER (PR)"] [--speed 1.5] \
|
|
12
|
+
# [--trim START:END] [--target-size-mb 5] [--width 1280] [--height 720] \
|
|
13
|
+
# [--title-secs 2.5] <clip1.webm> [clip2.webm]
|
|
14
|
+
#
|
|
15
|
+
# What it does:
|
|
16
|
+
# 1. Normalizes each input clip (optional trim, speed-up, scale+pad to the
|
|
17
|
+
# panel size, fps/pixfmt/SAR normalize, optional per-panel label).
|
|
18
|
+
# 2. Lays out the body: a single panel, or two panels side-by-side (hstack).
|
|
19
|
+
# 3. Prepends a title/subtitle card (solid bg + drawtext).
|
|
20
|
+
# 4. Two-pass H.264 encode targeting --target-size-mb so the mp4 lands under
|
|
21
|
+
# GitHub's inline-embed limit; yuv420p + +faststart for web streaming.
|
|
22
|
+
# 5. Prints an ffprobe summary (resolution / duration / size).
|
|
23
|
+
#
|
|
24
|
+
# Prerequisites: ffmpeg, ffprobe (baked into lastlight-sandbox-qa:latest).
|
|
25
|
+
# Runs fully offline.
|
|
26
|
+
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
die() { echo "compose-demo.sh: error: $*" >&2; exit 1; }
|
|
30
|
+
require_cmd() { command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"; }
|
|
31
|
+
require_cmd ffmpeg
|
|
32
|
+
require_cmd ffprobe
|
|
33
|
+
|
|
34
|
+
# ── Defaults ────────────────────────────────────────────────────────────────
|
|
35
|
+
OUTPUT=""
|
|
36
|
+
TITLE=""
|
|
37
|
+
SUBTITLE=""
|
|
38
|
+
LAYOUT="single"
|
|
39
|
+
LABEL1=""
|
|
40
|
+
LABEL2=""
|
|
41
|
+
SPEED="1"
|
|
42
|
+
TRIM=""
|
|
43
|
+
TARGET_MB="5"
|
|
44
|
+
WIDTH="1280"
|
|
45
|
+
HEIGHT="720"
|
|
46
|
+
TITLE_SECS="2.5"
|
|
47
|
+
CLIPS=()
|
|
48
|
+
|
|
49
|
+
# ── Parse args ──────────────────────────────────────────────────────────────
|
|
50
|
+
while [[ $# -gt 0 ]]; do
|
|
51
|
+
case "$1" in
|
|
52
|
+
--output) OUTPUT="$2"; shift 2;;
|
|
53
|
+
--title) TITLE="$2"; shift 2;;
|
|
54
|
+
--subtitle) SUBTITLE="$2"; shift 2;;
|
|
55
|
+
--layout) LAYOUT="$2"; shift 2;;
|
|
56
|
+
--labels) LABEL1="$2"; LABEL2="$3"; shift 3;;
|
|
57
|
+
--speed) SPEED="$2"; shift 2;;
|
|
58
|
+
--trim) TRIM="$2"; shift 2;;
|
|
59
|
+
--target-size-mb) TARGET_MB="$2"; shift 2;;
|
|
60
|
+
--width) WIDTH="$2"; shift 2;;
|
|
61
|
+
--height) HEIGHT="$2"; shift 2;;
|
|
62
|
+
--title-secs) TITLE_SECS="$2"; shift 2;;
|
|
63
|
+
-*) die "unknown flag: $1";;
|
|
64
|
+
*) CLIPS+=("$1"); shift;;
|
|
65
|
+
esac
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
[[ -n "$OUTPUT" ]] || die "--output is required"
|
|
69
|
+
[[ ${#CLIPS[@]} -ge 1 ]] || die "at least one input clip is required"
|
|
70
|
+
for c in "${CLIPS[@]}"; do [[ -f "$c" ]] || die "clip not found: $c"; done
|
|
71
|
+
if [[ "$LAYOUT" == "side-by-side" ]]; then
|
|
72
|
+
[[ ${#CLIPS[@]} -ge 2 ]] || die "side-by-side layout needs two clips"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
WORK="$(mktemp -d "${TMPDIR:-/tmp}/compose-demo-XXXXXX")"
|
|
76
|
+
cleanup() { rm -rf "$WORK"; }
|
|
77
|
+
trap cleanup EXIT
|
|
78
|
+
|
|
79
|
+
# ── Font for drawtext ────────────────────────────────────────────────────────
|
|
80
|
+
# Prefer an explicit fontfile (Liberation ships in the QA image via
|
|
81
|
+
# fonts-liberation); fall back to fontconfig's default Sans family.
|
|
82
|
+
FONT="${DEMO_FONT:-}"
|
|
83
|
+
if [[ -z "$FONT" ]]; then
|
|
84
|
+
for f in \
|
|
85
|
+
/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf \
|
|
86
|
+
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf; do
|
|
87
|
+
[[ -f "$f" ]] && FONT="$f" && break
|
|
88
|
+
done
|
|
89
|
+
fi
|
|
90
|
+
if [[ -n "$FONT" ]]; then FONTARG="fontfile=${FONT}"; else FONTARG="font=Sans"; fi
|
|
91
|
+
|
|
92
|
+
# drawtext drives the title card and per-panel labels. The Debian `ffmpeg`
|
|
93
|
+
# package (the QA image) is built with libfreetype so it's present; but degrade
|
|
94
|
+
# gracefully on a build without it (omit text overlays) rather than failing the
|
|
95
|
+
# whole compose — the demo video is still worth shipping.
|
|
96
|
+
HAS_DRAWTEXT=0
|
|
97
|
+
if ffmpeg -hide_banner -filters 2>/dev/null | grep -q 'drawtext'; then
|
|
98
|
+
HAS_DRAWTEXT=1
|
|
99
|
+
else
|
|
100
|
+
echo "compose-demo.sh: warning: this ffmpeg lacks the drawtext filter — title card and labels omitted." >&2
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# Panel size: side-by-side splits the width into two equal panels.
|
|
104
|
+
PH="$HEIGHT"
|
|
105
|
+
if [[ "$LAYOUT" == "side-by-side" ]]; then PW=$(( WIDTH / 2 )); else PW="$WIDTH"; fi
|
|
106
|
+
|
|
107
|
+
# ── Stage A: normalize one clip into a body panel ─────────────────────────────
|
|
108
|
+
# Args: <input> <outfile> <label-file-or-empty> <apply-trim:0|1>
|
|
109
|
+
build_panel() {
|
|
110
|
+
local input="$1" outfile="$2" labelfile="$3" apply_trim="$4"
|
|
111
|
+
local trim_args=()
|
|
112
|
+
if [[ "$apply_trim" == "1" && -n "$TRIM" ]]; then
|
|
113
|
+
local start="${TRIM%%:*}" end="${TRIM##*:}"
|
|
114
|
+
[[ -n "$start" ]] && trim_args+=(-ss "$start")
|
|
115
|
+
[[ -n "$end" ]] && trim_args+=(-to "$end")
|
|
116
|
+
fi
|
|
117
|
+
local vf="setpts=PTS/${SPEED}"
|
|
118
|
+
vf+=",scale=${PW}:${PH}:force_original_aspect_ratio=decrease"
|
|
119
|
+
vf+=",pad=${PW}:${PH}:(ow-iw)/2:(oh-ih)/2:color=black"
|
|
120
|
+
vf+=",fps=30,format=yuv420p,setsar=1"
|
|
121
|
+
if [[ -n "$labelfile" && "$HAS_DRAWTEXT" == "1" ]]; then
|
|
122
|
+
vf+=",drawtext=${FONTARG}:textfile=${labelfile}:x=(w-text_w)/2:y=h-th-24"
|
|
123
|
+
vf+=":fontsize=26:fontcolor=white:box=1:boxcolor=black@0.55:boxborderw=12"
|
|
124
|
+
fi
|
|
125
|
+
# `${arr[@]+"${arr[@]}"}` expands to nothing when the array is empty without
|
|
126
|
+
# tripping `set -u` (an empty `"${arr[@]}"` errors on bash < 4.4, e.g. macOS).
|
|
127
|
+
ffmpeg -y -loglevel error ${trim_args[@]+"${trim_args[@]}"} -i "$input" \
|
|
128
|
+
-vf "$vf" -an -c:v libx264 -crf 20 -preset veryfast "$outfile"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Per-panel labels (side-by-side) written to files to avoid drawtext escaping.
|
|
132
|
+
LABELFILE1=""; LABELFILE2=""
|
|
133
|
+
if [[ "$LAYOUT" == "side-by-side" ]]; then
|
|
134
|
+
if [[ -n "$LABEL1" ]]; then LABELFILE1="$WORK/label1.txt"; printf '%s' "$LABEL1" > "$LABELFILE1"; fi
|
|
135
|
+
if [[ -n "$LABEL2" ]]; then LABELFILE2="$WORK/label2.txt"; printf '%s' "$LABEL2" > "$LABELFILE2"; fi
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
echo "compose-demo.sh: normalizing clips (layout=$LAYOUT, speed=${SPEED}x)…" >&2
|
|
139
|
+
build_panel "${CLIPS[0]}" "$WORK/panel0.mp4" "$LABELFILE1" 1
|
|
140
|
+
BODY="$WORK/body.mp4"
|
|
141
|
+
if [[ "$LAYOUT" == "side-by-side" ]]; then
|
|
142
|
+
build_panel "${CLIPS[1]}" "$WORK/panel1.mp4" "$LABELFILE2" 1
|
|
143
|
+
ffmpeg -y -loglevel error -i "$WORK/panel0.mp4" -i "$WORK/panel1.mp4" \
|
|
144
|
+
-filter_complex "[0:v][1:v]hstack=inputs=2,format=yuv420p,setsar=1[v]" \
|
|
145
|
+
-map "[v]" -an -c:v libx264 -crf 20 -preset veryfast "$BODY"
|
|
146
|
+
else
|
|
147
|
+
BODY="$WORK/panel0.mp4"
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# ── Stage B: title card (skipped when drawtext is unavailable) ───────────────
|
|
151
|
+
TITLE_CLIP=""
|
|
152
|
+
TITLE_DUR="0"
|
|
153
|
+
if [[ "$HAS_DRAWTEXT" == "1" ]]; then
|
|
154
|
+
TITLEFILE="$WORK/title.txt"; printf '%s' "${TITLE:-Demo}" > "$TITLEFILE"
|
|
155
|
+
TITLE_VF="drawtext=${FONTARG}:textfile=${TITLEFILE}:x=(w-text_w)/2:y=(h/2)-th-10:fontsize=48:fontcolor=white"
|
|
156
|
+
if [[ -n "$SUBTITLE" ]]; then
|
|
157
|
+
SUBFILE="$WORK/subtitle.txt"; printf '%s' "$SUBTITLE" > "$SUBFILE"
|
|
158
|
+
TITLE_VF+=",drawtext=${FONTARG}:textfile=${SUBFILE}:x=(w-text_w)/2:y=(h/2)+10:fontsize=26:fontcolor=0xb0b0b0"
|
|
159
|
+
fi
|
|
160
|
+
TITLE_VF+=",format=yuv420p"
|
|
161
|
+
ffmpeg -y -loglevel error -f lavfi -i "color=c=0x101418:s=${WIDTH}x${HEIGHT}:d=${TITLE_SECS}:r=30" \
|
|
162
|
+
-vf "$TITLE_VF" -c:v libx264 -crf 20 -preset veryfast "$WORK/title.mp4"
|
|
163
|
+
TITLE_CLIP="$WORK/title.mp4"
|
|
164
|
+
TITLE_DUR="$TITLE_SECS"
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
# ── Stage C: (concat title +) body, two-pass size cap, faststart ─────────────
|
|
168
|
+
BODY_DUR="$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$BODY" || echo 0)"
|
|
169
|
+
TOTAL_DUR="$(awk -v a="$TITLE_DUR" -v b="$BODY_DUR" 'BEGIN{printf "%.3f", a + b}')"
|
|
170
|
+
# Target video bitrate (kbit/s) = target_bytes * 8 / duration / 1000, with a
|
|
171
|
+
# small headroom factor for the muxer; floored so very short clips still encode.
|
|
172
|
+
BR_K="$(awk -v mb="$TARGET_MB" -v d="$TOTAL_DUR" 'BEGIN{
|
|
173
|
+
if (d <= 0) d = 1;
|
|
174
|
+
br = (mb * 1024 * 1024 * 8) / d / 1000 * 0.92;
|
|
175
|
+
if (br < 200) br = 200;
|
|
176
|
+
printf "%d", br;
|
|
177
|
+
}')"
|
|
178
|
+
|
|
179
|
+
# With a title card: concat it ahead of the body. Without: pass the body
|
|
180
|
+
# through (`null`) so the same two-pass/faststart encode applies either way.
|
|
181
|
+
if [[ -n "$TITLE_CLIP" ]]; then
|
|
182
|
+
IN_ARGS=(-i "$TITLE_CLIP" -i "$BODY")
|
|
183
|
+
FILTER='[0:v][1:v]concat=n=2:v=1:a=0[v]'
|
|
184
|
+
else
|
|
185
|
+
IN_ARGS=(-i "$BODY")
|
|
186
|
+
FILTER='[0:v]null[v]'
|
|
187
|
+
fi
|
|
188
|
+
PASSLOG="$WORK/ff2pass"
|
|
189
|
+
echo "compose-demo.sh: encoding (${TOTAL_DUR}s, target ${TARGET_MB}MB → ${BR_K}kbit/s, two-pass)…" >&2
|
|
190
|
+
ffmpeg -y -loglevel error "${IN_ARGS[@]}" \
|
|
191
|
+
-filter_complex "$FILTER" -map "[v]" -an \
|
|
192
|
+
-c:v libx264 -b:v "${BR_K}k" -pass 1 -passlogfile "$PASSLOG" -preset medium -f mp4 /dev/null
|
|
193
|
+
ffmpeg -y -loglevel error "${IN_ARGS[@]}" \
|
|
194
|
+
-filter_complex "$FILTER" -map "[v]" -an \
|
|
195
|
+
-c:v libx264 -b:v "${BR_K}k" -pass 2 -passlogfile "$PASSLOG" -preset medium \
|
|
196
|
+
-pix_fmt yuv420p -movflags +faststart "$OUTPUT"
|
|
197
|
+
|
|
198
|
+
# ── Stage D: report ───────────────────────────────────────────────────────────
|
|
199
|
+
RES="$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0:s=x "$OUTPUT" || echo '?')"
|
|
200
|
+
DUR="$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$OUTPUT" || echo '?')"
|
|
201
|
+
BYTES="$(wc -c < "$OUTPUT" | tr -d ' ')"
|
|
202
|
+
MB="$(awk -v b="$BYTES" 'BEGIN{printf "%.2f", b/1024/1024}')"
|
|
203
|
+
echo "compose-demo.sh: wrote $OUTPUT (${RES}, ${DUR}s, ${MB}MB)" >&2
|
|
204
|
+
# Machine-readable line for the agent to parse.
|
|
205
|
+
echo "{\"output\":\"${OUTPUT}\",\"resolution\":\"${RES}\",\"duration\":\"${DUR}\",\"size_mb\":${MB}}"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: issue-answer
|
|
3
|
+
description: Answer a question directly — a sourced, neutral reply to an information/explanation/comparison request, from a GitHub issue or a Slack thread. Research repo docs and the web, output the answer, label `question` (GitHub only), leave open. Never write an agent brief, mark ready-for-agent, or change code.
|
|
4
|
+
version: 1.1.0
|
|
5
|
+
tags: [github, issues, questions]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Issue Answer
|
|
9
|
+
|
|
10
|
+
A user asked a **question** — they want information, an explanation, or a
|
|
11
|
+
comparison, not a code change. The router already decided this is a question;
|
|
12
|
+
your job is to **answer it well and stop**. Do not re-triage it into a work item.
|
|
13
|
+
|
|
14
|
+
The question reaches you from one of two places, and the prompt tells you which:
|
|
15
|
+
- a **GitHub issue** (an `issueNumber` is set), or
|
|
16
|
+
- a **Slack thread** (no `issueNumber`).
|
|
17
|
+
|
|
18
|
+
## How your answer is delivered
|
|
19
|
+
|
|
20
|
+
Your **final message is the answer** — the harness posts it for you (as a
|
|
21
|
+
comment on the issue for GitHub-initiated runs, or into the Slack thread for
|
|
22
|
+
Slack-initiated runs). So:
|
|
23
|
+
|
|
24
|
+
- Make your final message the complete, self-contained answer in clean markdown.
|
|
25
|
+
- **Do NOT post the answer yourself** with `github_add_issue_comment` — the
|
|
26
|
+
harness delivers it, and posting it too would double-post.
|
|
27
|
+
|
|
28
|
+
## Hard caps
|
|
29
|
+
|
|
30
|
+
This skill answers; it never queues work. Per invocation:
|
|
31
|
+
|
|
32
|
+
- Produce **one** answer (your final message).
|
|
33
|
+
- The only GitHub write you make is the `question` **label**, and only when
|
|
34
|
+
answering a GitHub issue.
|
|
35
|
+
- **Never** write an agent brief, apply `ready-for-agent` / `ready-for-human`,
|
|
36
|
+
create branches, push code, or open a PR.
|
|
37
|
+
- **Never** close the issue — leave it open for the human to close once the
|
|
38
|
+
answer satisfies them.
|
|
39
|
+
|
|
40
|
+
If, while reading, you conclude the request is actually a bug or feature request
|
|
41
|
+
(not a pure question), do **not** answer it as one. Make your final message a
|
|
42
|
+
short note saying it looks like work rather than a question and asking a
|
|
43
|
+
maintainer to `@last-light build` (or `explore`) it — let triage own work items.
|
|
44
|
+
|
|
45
|
+
## Procedure
|
|
46
|
+
|
|
47
|
+
1. **Understand the question.** Read the question from the prompt — the issue
|
|
48
|
+
title/body (and existing comments, for a GitHub issue) or the Slack message.
|
|
49
|
+
Identify exactly what the user wants to know.
|
|
50
|
+
2. **Research.**
|
|
51
|
+
- **The repo** — read what's relevant to the answer: `CONTEXT.md`,
|
|
52
|
+
`README`, `docs/`, `spec/`, and code only as needed to ground claims about
|
|
53
|
+
this project. Don't survey the whole codebase; read what the question needs.
|
|
54
|
+
- **The web** — when the question references anything outside this repo
|
|
55
|
+
(another tool, framework, library, standard, or a "X vs Y" comparison),
|
|
56
|
+
use the `web_search` and `web_fetch` tools to consult current,
|
|
57
|
+
authoritative sources. Prefer official docs and primary sources.
|
|
58
|
+
- **Budget your research and converge.** You have a bounded number of tool
|
|
59
|
+
calls before the run ends — research is for grounding the answer, not
|
|
60
|
+
exhaustive coverage. Front-load the searches you need, then stop looking.
|
|
61
|
+
**Critical:** the moment you think *"I have enough"* (or *"let me just
|
|
62
|
+
confirm one more thing"*), do **not** fire another tool call — write the
|
|
63
|
+
answer **now**, in that same turn. Your reply being cut off mid-research
|
|
64
|
+
delivers a useless half-sentence to the user, which is worse than an
|
|
65
|
+
answer that omits a minor detail. If a fact is unverified, state it as
|
|
66
|
+
unverified in the answer rather than spending your last turn chasing it.
|
|
67
|
+
For broad/open-ended questions (e.g. "what's missing vs tool X"), gather a
|
|
68
|
+
representative sample and answer from it — explicitly noting it's a
|
|
69
|
+
sample, not an exhaustive audit — rather than enumerating everything.
|
|
70
|
+
3. **Label (GitHub issue only).** Apply `question` with `github_add_labels`
|
|
71
|
+
(create it first with `github_create_label`, color `d876e3`; ignore a 422
|
|
72
|
+
"already exists"). If label creation/adding is denied, skip it — the answer
|
|
73
|
+
is the deliverable. For a Slack-initiated question there is no issue to label.
|
|
74
|
+
4. **Write the answer as your final message** (the harness delivers it — see
|
|
75
|
+
above; do not post it yourself):
|
|
76
|
+
- Direct and structured. Lead with the answer; use short sections or a
|
|
77
|
+
comparison table when it helps.
|
|
78
|
+
- **Neutral and grounded.** Claims about this project come from its docs;
|
|
79
|
+
claims about external things are **cited** with links to the sources you
|
|
80
|
+
used. Don't invent pricing, capabilities, or roadmap.
|
|
81
|
+
- **Honest about uncertainty.** If something is fast-moving or you couldn't
|
|
82
|
+
verify it, say so rather than stating it as fact.
|
|
83
|
+
5. **Stop.** The answer is the conversation; a human closes the issue when satisfied.
|
|
84
|
+
|
|
85
|
+
## Tool usage
|
|
86
|
+
|
|
87
|
+
- GitHub operations via `github_*` MCP tools only — never `gh` CLI, `curl`, or
|
|
88
|
+
raw HTTP. In chat you have no GitHub write tools beyond labelling; that's
|
|
89
|
+
expected — the answer is delivered as your final message.
|
|
90
|
+
- External research via the `web_search` / `web_fetch` tools only.
|
|
@@ -1,33 +1,47 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: issue-comment
|
|
3
|
-
description: Handle non-build maintainer
|
|
4
|
-
version:
|
|
3
|
+
description: Handle a non-build maintainer comment on an issue or PR — close, reopen, label, dedupe, answer a brief question, or triage. Action-only; redirect anything that needs code changes to /build.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
tags: [github, issues, comments]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Issue Comment
|
|
8
|
+
# Issue Comment
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
A maintainer @mentioned the bot on an issue or PR with a request that is **not**
|
|
11
|
+
asking for code changes. Do the one bounded thing they asked, confirm it in one
|
|
12
|
+
short comment, and stop.
|
|
13
|
+
|
|
14
|
+
## Hard caps
|
|
15
|
+
|
|
16
|
+
This skill is deliberately small. Per invocation: **at most 2 file reads and 1
|
|
17
|
+
outgoing comment.** Never make code changes, create branches, or push.
|
|
12
18
|
|
|
13
19
|
## Procedure
|
|
14
20
|
|
|
15
|
-
1. **Read the
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
-
|
|
21
|
+
1. **Read the request.** The triggering comment is the job — read it, plus the
|
|
22
|
+
issue/PR title, body, existing labels, and existing comments for context.
|
|
23
|
+
2. **Do the bounded action:**
|
|
24
|
+
- Close / reopen → `github_update_issue`
|
|
25
|
+
- Label → `github_add_labels` / `github_remove_label` (use the canonical
|
|
26
|
+
triage roles from `docs/agents/triage-labels.md` where relevant)
|
|
27
|
+
- Duplicate check → search similar issues, link the original in one comment
|
|
28
|
+
- Answer a direct question → ≤5 sentences, ≤2 file reads. Don't survey the
|
|
29
|
+
codebase or compile a report.
|
|
30
|
+
3. **Confirm** in one short comment what you did. Done.
|
|
31
|
+
|
|
32
|
+
## Redirect, don't comply
|
|
33
|
+
|
|
34
|
+
The classifier owns intent routing. If a request that needs *building* reached
|
|
35
|
+
you anyway, the correct response is to **redirect, not do it** — even if the
|
|
36
|
+
comment seems to greenlight the work, and even if the issue body describes a
|
|
37
|
+
task. An issue titled "Security Review" asking you to "find and fix issues" is a
|
|
38
|
+
build request: reply asking the maintainer to use `@last-light build` (or
|
|
39
|
+
`@last-light explore`). Do **not** run the audit yourself from this skill.
|
|
40
|
+
|
|
41
|
+
If the request is unclear or out of scope, post one short comment asking them to
|
|
42
|
+
clarify or to use the right command. Do nothing else.
|
|
43
|
+
|
|
44
|
+
## Tool usage
|
|
45
|
+
|
|
46
|
+
GitHub operations via `github_*` MCP tools only — never `gh` CLI, `curl`, or raw
|
|
47
|
+
HTTP.
|
|
@@ -1,54 +1,120 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: issue-triage
|
|
3
|
-
description: Triage GitHub issues — label, deduplicate, request info, and manage stale issues
|
|
3
|
+
description: Triage GitHub issues through the canonical state machine — classify, label, deduplicate, request missing info, write agent briefs, and manage stale issues. Use on demand or on a triage cron.
|
|
4
4
|
version: 2.0.0
|
|
5
5
|
tags: [github, issues, triage]
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Issue Triage
|
|
8
|
+
# Issue Triage
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
Move each issue through a small **state machine**. Every triaged issue carries
|
|
11
|
+
exactly **one category role and one state role**:
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
- **Category:** `bug` (something is broken) · `enhancement` (new feature or improvement)
|
|
14
|
+
- **State:** `needs-triage` (awaiting evaluation) · `needs-info` (waiting on the
|
|
15
|
+
reporter) · `ready-for-agent` (fully specified, an AFK agent can take it) ·
|
|
16
|
+
`ready-for-human` (needs human implementation) · `wontfix` (won't be actioned)
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
These are canonical role names; the actual label strings for a repo may differ —
|
|
19
|
+
`docs/agents/triage-labels.md` holds the mapping when present. Run **autonomously**:
|
|
20
|
+
there is no maintainer to ask mid-run. Where you'd want direction, either make
|
|
21
|
+
the call and apply the label, or post a comment and stop — the async comment *is*
|
|
22
|
+
the conversation.
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
2. **Classify** the issue type:
|
|
19
|
-
- Bug report → label `bug` + priority label
|
|
20
|
-
- Feature request → label `enhancement`
|
|
21
|
-
- Question → label `question`
|
|
22
|
-
- Documentation → label `documentation`
|
|
23
|
-
3. **Check for duplicates** by searching existing issues with similar keywords
|
|
24
|
-
- If duplicate found: comment linking to the original, add `duplicate` label, close
|
|
25
|
-
4. **Assess completeness**:
|
|
26
|
-
- Bug without reproduction steps → add `needs-info`, comment asking for steps
|
|
27
|
-
- Feature without use case → add `needs-info`, comment asking for context
|
|
28
|
-
5. **Set priority** based on severity and impact:
|
|
29
|
-
- `p0-critical`: Security, data loss, service down
|
|
30
|
-
- `p1-high`: Major feature broken, affects many users
|
|
31
|
-
- `p2-medium`: Minor feature broken, workaround exists
|
|
32
|
-
- `p3-low`: Cosmetic, edge case, nice-to-have
|
|
33
|
-
6. **Add helpful labels**: `good first issue` for simple fixes, `help wanted` for community
|
|
24
|
+
## 0. Ensure the labels exist
|
|
34
25
|
|
|
35
|
-
|
|
26
|
+
Before applying any label, create the canonical set idempotently with
|
|
27
|
+
`github_create_label` (ignore 422 "already exists"):
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
| Label | Color | Role |
|
|
30
|
+
|-------|-------|------|
|
|
31
|
+
| `bug` | `d73a4a` | category |
|
|
32
|
+
| `enhancement` | `a2eeef` | category |
|
|
33
|
+
| `needs-triage` | `ededed` | state |
|
|
34
|
+
| `needs-info` | `fbca04` | state |
|
|
35
|
+
| `ready-for-agent` | `0e8a16` | state |
|
|
36
|
+
| `ready-for-human` | `1d76db` | state |
|
|
37
|
+
| `wontfix` | `ffffff` | state |
|
|
38
|
+
| `duplicate` | `cfd3d7` | dedupe |
|
|
39
|
+
| `question` | `d876e3` | question |
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
If label creation is denied (the token lacks the permission), fall back to using
|
|
42
|
+
only the labels that already exist on the repo and skip the rest. Done when the
|
|
43
|
+
labels you need are present or you've confirmed you can't create them.
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
## 1. Triage a specific issue
|
|
46
|
+
|
|
47
|
+
1. **Gather context.** Read the full issue — title, body, comments, existing
|
|
48
|
+
labels, author, dates. Search existing issues for **duplicates** by concept
|
|
49
|
+
(not just keyword). If a `.out-of-scope/` directory exists, read it and note
|
|
50
|
+
any prior rejection this resembles. Done when you know the issue's intent and
|
|
51
|
+
whether it's novel.
|
|
52
|
+
2. **Classify the category** — `bug` or `enhancement`. But first, check whether
|
|
53
|
+
the issue is a **question** at all (see below) — questions are neither.
|
|
54
|
+
3. **Decide the state and act** (exactly one applies):
|
|
55
|
+
- **Question** (asks for information, an explanation, or a comparison — wants
|
|
56
|
+
an answer, not a code change) → add `question` and **stop**. Do **not**
|
|
57
|
+
write an agent brief or mark it `ready-for-agent`/`ready-for-human` — a
|
|
58
|
+
pure question is not work. (The router normally sends these to the answer
|
|
59
|
+
path before triage runs; this is the safety net for ones that slip
|
|
60
|
+
through, e.g. reopened issues. If you can answer it briefly and factually
|
|
61
|
+
from the repo itself, do so in one short comment; otherwise just label it
|
|
62
|
+
and leave it for the answer path or a human.)
|
|
63
|
+
- **Duplicate** → comment linking the original, add `duplicate`, close.
|
|
64
|
+
- **Already implemented** → comment pointing to where it lives, add `wontfix`,
|
|
65
|
+
close. (Factual — safe to close autonomously.)
|
|
66
|
+
- **Under-specified** (bug without repro, feature without a use case) → add
|
|
67
|
+
`needs-info`, post the [needs-info template](#needs-info-template), stop.
|
|
68
|
+
- **Fully specified and delegatable** → add `ready-for-agent`, post an agent
|
|
69
|
+
brief ([references/AGENT-BRIEF.md](references/AGENT-BRIEF.md)).
|
|
70
|
+
- **Needs human implementation** (judgment calls, external access, design
|
|
71
|
+
decisions, manual testing) → add `ready-for-human` with a brief noting why
|
|
72
|
+
it can't be delegated.
|
|
73
|
+
- **Looks out of scope** (an enhancement you'd reject) → this is a maintainer
|
|
74
|
+
decision; do **not** auto-close. Add `needs-triage`, post a comment with
|
|
75
|
+
your reasoning (cite any matching `.out-of-scope/` file), and leave it for a
|
|
76
|
+
human.
|
|
77
|
+
4. **Apply exactly one category + one state.** If the existing labels conflict
|
|
78
|
+
(two state roles), flag it in a comment and don't override — a maintainer may
|
|
79
|
+
have set them deliberately.
|
|
80
|
+
|
|
81
|
+
## 2. New unlabelled issues (batch / cron)
|
|
82
|
+
|
|
83
|
+
For each issue with no triage labels yet, run §1. Default new issues that need
|
|
84
|
+
evaluation to `needs-triage`.
|
|
85
|
+
|
|
86
|
+
## 3. Stale `needs-info`
|
|
87
|
+
|
|
88
|
+
1. Find issues labelled `needs-info` with no activity for **14+ days**.
|
|
89
|
+
2. **Check for a prior bot reminder** with `github_list_issue_comments` — look
|
|
90
|
+
for a `last-light[bot]` comment containing "reminder" / "still need" /
|
|
91
|
+
"closing". **Never post a duplicate reminder.**
|
|
92
|
+
3. No reminder yet → post a gentle reminder asking if they still need help.
|
|
93
|
+
4. Reminder exists and **30+ days** have passed with no reporter response since →
|
|
94
|
+
close kindly, noting they can reopen.
|
|
95
|
+
5. Reminder exists, **< 30 days** since → do nothing.
|
|
96
|
+
|
|
97
|
+
## needs-info template
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
## Triage Notes
|
|
101
|
+
|
|
102
|
+
**What we've established so far:**
|
|
103
|
+
- point 1
|
|
104
|
+
|
|
105
|
+
**What we still need from you (@reporter):**
|
|
106
|
+
- specific, actionable question 1
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Questions must be specific and actionable — not "please provide more info".
|
|
110
|
+
|
|
111
|
+
## Tool usage
|
|
112
|
+
|
|
113
|
+
GitHub operations via `github_*` MCP tools only — listing, labelling, commenting,
|
|
114
|
+
closing, creating labels. Never `gh` CLI, `curl`, or raw HTTP.
|
|
46
115
|
|
|
47
116
|
## Pitfalls
|
|
48
|
-
- Don't close issues too aggressively — when in doubt, leave open
|
|
49
|
-
- Don't change priority on issues already triaged by maintainers
|
|
50
|
-
- Don't duplicate labels (check existing labels first)
|
|
51
117
|
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
118
|
+
- Don't close aggressively — when genuinely in doubt, leave it open as `needs-triage`.
|
|
119
|
+
- Don't change priority or state on issues a maintainer already triaged.
|
|
120
|
+
- Check existing labels before adding — don't duplicate.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Writing agent briefs
|
|
2
|
+
|
|
3
|
+
An agent brief is a comment posted when an issue moves to `ready-for-agent`
|
|
4
|
+
(or `ready-for-human`). It is the **contract** an AFK agent will build from — the
|
|
5
|
+
original body and discussion are context; the brief is what gets implemented.
|
|
6
|
+
Post it with `github_add_issue_comment`.
|
|
7
|
+
|
|
8
|
+
## Principles
|
|
9
|
+
|
|
10
|
+
**Durable.** The issue may sit in `ready-for-agent` for weeks while the codebase
|
|
11
|
+
moves. Describe interfaces, types, and behavioural contracts — name specific
|
|
12
|
+
types, function signatures, or config shapes to look for. **Never** reference
|
|
13
|
+
file paths or line numbers; they go stale. Don't assume today's structure survives.
|
|
14
|
+
|
|
15
|
+
**Behavioural, not procedural.** Say *what* the system should do, not *how* to
|
|
16
|
+
code it — the agent explores fresh and makes its own implementation calls.
|
|
17
|
+
- Good: "`SkillConfig` should accept an optional `schedule: CronExpression`."
|
|
18
|
+
- Bad: "Add a `schedule` field in src/types/skill.ts on line 42."
|
|
19
|
+
|
|
20
|
+
**Complete acceptance criteria.** Every brief lists concrete, independently
|
|
21
|
+
testable criteria so the agent knows when it's done.
|
|
22
|
+
- Good: "`gh issue list --label needs-triage` returns issues that passed initial classification."
|
|
23
|
+
- Bad: "Triage should work correctly."
|
|
24
|
+
|
|
25
|
+
**Explicit scope boundaries.** State what is *out of scope* so the agent doesn't
|
|
26
|
+
gold-plate or wander into adjacent features.
|
|
27
|
+
|
|
28
|
+
## Template
|
|
29
|
+
|
|
30
|
+
```markdown
|
|
31
|
+
## Agent Brief
|
|
32
|
+
|
|
33
|
+
**Category:** bug / enhancement
|
|
34
|
+
**Summary:** one line — what needs to happen
|
|
35
|
+
|
|
36
|
+
**Current behavior:**
|
|
37
|
+
What happens now. For a bug, the broken behaviour. For an enhancement, the
|
|
38
|
+
status quo it builds on.
|
|
39
|
+
|
|
40
|
+
**Desired behavior:**
|
|
41
|
+
What should happen after the work is done. Be specific about edge cases and
|
|
42
|
+
error conditions.
|
|
43
|
+
|
|
44
|
+
**Key interfaces:**
|
|
45
|
+
- `TypeName` — what changes and why
|
|
46
|
+
- `functionName()` — current vs intended return/behaviour
|
|
47
|
+
- Config shape — any new options
|
|
48
|
+
|
|
49
|
+
**Acceptance criteria:**
|
|
50
|
+
- [ ] Specific, testable criterion 1
|
|
51
|
+
- [ ] Specific, testable criterion 2
|
|
52
|
+
|
|
53
|
+
**Out of scope:**
|
|
54
|
+
- Thing that should NOT be changed here
|
|
55
|
+
- Adjacent feature that looks related but is separate
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## `ready-for-human` variant
|
|
59
|
+
|
|
60
|
+
Same structure, plus a leading note on **why it can't be delegated** — judgment
|
|
61
|
+
calls, external access, design decisions, or manual testing the agent can't do.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pr-comment
|
|
3
|
+
description: Answer a maintainer's question about an open PR with concrete, code-cited evidence. The PR-side counterpart to issue-comment — for questions tied to the diff, not a full review.
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
tags: [github, pr, comments, qa]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# PR Comment
|
|
9
|
+
|
|
10
|
+
A maintainer @mentioned the bot on a PR with a *question* (not a request to
|
|
11
|
+
write code, and not "review this"). The question is the entire job — answer it
|
|
12
|
+
with evidence, in one comment. Examples: "does this consider X?", "why did we
|
|
13
|
+
change Y?", "is the new function thread-safe?", "regression risk for existing
|
|
14
|
+
callers?".
|
|
15
|
+
|
|
16
|
+
For general issue questions use `issue-comment`; for a full review use
|
|
17
|
+
`pr-review`.
|
|
18
|
+
|
|
19
|
+
## Procedure
|
|
20
|
+
|
|
21
|
+
### 1. Read the PR and the question
|
|
22
|
+
|
|
23
|
+
- `github_get_pull_request` → title, body, base, head.
|
|
24
|
+
- The triggering question is in `context.commentBody`. Answer *that* question —
|
|
25
|
+
don't generalise to a review or answer a different one.
|
|
26
|
+
|
|
27
|
+
### 2. Investigate with the diff in hand
|
|
28
|
+
|
|
29
|
+
Get the diff and read the code needed to answer well — a real answer about
|
|
30
|
+
thread-safety or regression risk needs the surrounding code, not just the hunk.
|
|
31
|
+
|
|
32
|
+
- **Cap: 8 file reads** per invocation.
|
|
33
|
+
- "Does it consider X?" → also check whether tests in the diff cover X.
|
|
34
|
+
- "Regression risk?" → find callers of any function whose signature/behaviour
|
|
35
|
+
changed (`github_search_code`).
|
|
36
|
+
- Don't clone the repo unless a single answer genuinely needs cross-file traces
|
|
37
|
+
no MCP tool can give — most don't. If it truly needs a full audit, say so and
|
|
38
|
+
recommend `@last-light` (which routes to `pr-review`) rather than blowing the cap.
|
|
39
|
+
|
|
40
|
+
### 3. Reply with one comment
|
|
41
|
+
|
|
42
|
+
`github_add_issue_comment` (PRs accept issue comments here). Keep it tight:
|
|
43
|
+
|
|
44
|
+
- **Lead with the answer** — yes / no / it depends. Don't bury it.
|
|
45
|
+
- **Cite `path:line`** — clickable in the GitHub UI.
|
|
46
|
+
- 3–8 sentences or a short bulleted list. No headings.
|
|
47
|
+
- If it's unanswerable from the PR alone, say so and name the specific
|
|
48
|
+
information you'd need.
|
|
49
|
+
|
|
50
|
+
> Yes — `src/foo.ts:42` checks `X` before calling `bar()`, and
|
|
51
|
+
> `tests/foo.test.ts:118` asserts the rejection path. The only place X isn't
|
|
52
|
+
> validated is the legacy `barLegacy` (`src/foo.ts:67`), which this PR doesn't
|
|
53
|
+
> touch — worth a separate issue if you want it covered.
|
|
54
|
+
|
|
55
|
+
## Do not
|
|
56
|
+
|
|
57
|
+
- Post a formal review (`github_create_pull_request_review`) — that's
|
|
58
|
+
`pr-review`'s job and would collide with its blocking check.
|
|
59
|
+
- Modify code, push, or add labels. One comment, nothing else.
|
|
60
|
+
- Answer a tangent you noticed — note it in at most one trailing sentence.
|
|
61
|
+
|
|
62
|
+
## Tool usage
|
|
63
|
+
|
|
64
|
+
GitHub operations via `github_*` MCP tools only — never `gh` CLI, `curl`, or raw HTTP.
|