lastlight 0.1.15 → 0.2.1
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 +377 -432
- 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 +30 -1
- package/dist/setup.js +241 -25
- 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 -9
- 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
package/dist/sandbox/index.js
CHANGED
|
@@ -1,65 +1,10 @@
|
|
|
1
1
|
import { execFileSync } from "child_process";
|
|
2
|
-
import { mkdirSync,
|
|
3
|
-
import { join, resolve, sep } from "path";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
3
|
+
import { isAbsolute, join, relative, resolve, sep } from "path";
|
|
4
4
|
import { DockerSandbox } from "./docker.js";
|
|
5
|
+
import { SANDBOX_IMAGE, isSandboxAvailable } from "./images.js";
|
|
5
6
|
export { DockerSandbox } from "./docker.js";
|
|
6
|
-
|
|
7
|
-
* Refresh the project-local sandbox credentials from the macOS keychain
|
|
8
|
-
* before spawning a sandbox.
|
|
9
|
-
*
|
|
10
|
-
* Why this exists:
|
|
11
|
-
* In LASTLIGHT_LOCAL_DEV mode the dev-local.sh script seeds
|
|
12
|
-
* ./data/sandbox-data/claude-home/.credentials.json from the host claude
|
|
13
|
-
* login at harness startup. But during a long dev session the host's
|
|
14
|
-
* `claude` CLI will refresh its OAuth token (rotating the access token in
|
|
15
|
-
* the keychain). When that happens the seeded file becomes stale — the
|
|
16
|
-
* server invalidates the old access token immediately on rotation, so the
|
|
17
|
-
* in-sandbox claude starts returning 401 even though the file's recorded
|
|
18
|
-
* expiresAt is still in the future.
|
|
19
|
-
*
|
|
20
|
-
* Re-reading the keychain on every sandbox spawn keeps the in-sandbox
|
|
21
|
-
* credentials current without requiring the user to restart the harness.
|
|
22
|
-
*
|
|
23
|
-
* This is a no-op when:
|
|
24
|
-
* - LASTLIGHT_LOCAL_DEV is not set (production / Docker harness)
|
|
25
|
-
* - We're not on macOS
|
|
26
|
-
* - The keychain entry doesn't exist
|
|
27
|
-
* - SANDBOX_DATA_VOLUME doesn't look like a host path
|
|
28
|
-
*/
|
|
29
|
-
function refreshLocalDevCredentials() {
|
|
30
|
-
if (process.env.LASTLIGHT_LOCAL_DEV !== "1")
|
|
31
|
-
return;
|
|
32
|
-
if (process.platform !== "darwin")
|
|
33
|
-
return;
|
|
34
|
-
const dataVolume = process.env.SANDBOX_DATA_VOLUME;
|
|
35
|
-
if (!dataVolume)
|
|
36
|
-
return;
|
|
37
|
-
// Only path-like values (the bind-mount form used in local dev)
|
|
38
|
-
if (!dataVolume.startsWith("/") &&
|
|
39
|
-
!dataVolume.startsWith("./") &&
|
|
40
|
-
!dataVolume.startsWith("../") &&
|
|
41
|
-
!dataVolume.startsWith("~")) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
let dataDir = dataVolume;
|
|
45
|
-
if (dataDir.startsWith("~")) {
|
|
46
|
-
dataDir = (process.env.HOME || "") + dataDir.slice(1);
|
|
47
|
-
}
|
|
48
|
-
dataDir = resolve(dataDir);
|
|
49
|
-
try {
|
|
50
|
-
const creds = execFileSync("security", ["find-generic-password", "-s", "Claude Code-credentials", "-a", process.env.USER || "", "-w"], { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 5000 }).trim();
|
|
51
|
-
if (!creds)
|
|
52
|
-
return;
|
|
53
|
-
const credPath = join(dataDir, "claude-home", ".credentials.json");
|
|
54
|
-
writeFileSync(credPath, creds);
|
|
55
|
-
chmodSync(credPath, 0o644);
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// Keychain entry missing, security command unavailable, or write failed.
|
|
59
|
-
// Don't fail sandbox creation on this — the existing seeded file may
|
|
60
|
-
// still be valid.
|
|
61
|
-
}
|
|
62
|
-
}
|
|
7
|
+
export { SANDBOX_IMAGE, SANDBOX_IMAGE_QA, isSandboxAvailable, qaImageAvailable, } from "./images.js";
|
|
63
8
|
/**
|
|
64
9
|
* Clean up orphaned sandbox containers from previous runs.
|
|
65
10
|
* Called on startup to remove containers that survived a harness restart.
|
|
@@ -79,34 +24,6 @@ export function cleanupOrphanedSandboxes() {
|
|
|
79
24
|
// Docker not available or no containers — fine
|
|
80
25
|
}
|
|
81
26
|
}
|
|
82
|
-
const SANDBOX_IMAGE = "lastlight-sandbox:latest";
|
|
83
|
-
/**
|
|
84
|
-
* Check if Docker sandbox mode is available.
|
|
85
|
-
*/
|
|
86
|
-
export function isSandboxAvailable() {
|
|
87
|
-
return dockerAvailable() && sandboxImageExists(SANDBOX_IMAGE);
|
|
88
|
-
}
|
|
89
|
-
function dockerAvailable() {
|
|
90
|
-
try {
|
|
91
|
-
execFileSync("docker", ["info"], { stdio: "ignore", timeout: 5000 });
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
catch {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
function sandboxImageExists(imageName) {
|
|
99
|
-
try {
|
|
100
|
-
const out = execFileSync("docker", ["images", "-q", imageName], {
|
|
101
|
-
encoding: "utf-8",
|
|
102
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
103
|
-
});
|
|
104
|
-
return out.trim().length > 0;
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
27
|
/** Cached check — only probe Docker once per process */
|
|
111
28
|
let _sandboxAvailable = null;
|
|
112
29
|
export function sandboxAvailable() {
|
|
@@ -124,6 +41,25 @@ export function sandboxAvailable() {
|
|
|
124
41
|
function isWithinDir(parent, child) {
|
|
125
42
|
return child === parent || child.startsWith(`${parent}${sep}`);
|
|
126
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Set up the per-task worktree directory (mkdir + optional pre-clone) without
|
|
46
|
+
* touching Docker. Used by the non-docker sandbox modes (gondolin / none) where
|
|
47
|
+
* agentic-pi runs in-process or in a VM rather than a container, but still
|
|
48
|
+
* wants a per-task workspace cloned from the target branch.
|
|
49
|
+
*/
|
|
50
|
+
export function setupTaskWorktree(opts) {
|
|
51
|
+
const sandboxBase = resolve(opts.sandboxDir || join(opts.stateDir, "sandboxes"));
|
|
52
|
+
mkdirSync(sandboxBase, { recursive: true });
|
|
53
|
+
const workDir = resolve(sandboxBase, opts.taskId);
|
|
54
|
+
if (!isWithinDir(sandboxBase, workDir)) {
|
|
55
|
+
throw new Error(`Invalid taskId path escape attempt: ${opts.taskId}`);
|
|
56
|
+
}
|
|
57
|
+
mkdirSync(workDir, { recursive: true });
|
|
58
|
+
if (opts.prePopulate) {
|
|
59
|
+
prePopulateWorkspace(workDir, opts.prePopulate);
|
|
60
|
+
}
|
|
61
|
+
return workDir;
|
|
62
|
+
}
|
|
127
63
|
/**
|
|
128
64
|
* Create a sandbox for a task. Returns the sandbox and a cleanup function.
|
|
129
65
|
* If Docker is not available, returns null (caller should fall back to direct execution).
|
|
@@ -131,10 +67,6 @@ function isWithinDir(parent, child) {
|
|
|
131
67
|
export async function createTaskSandbox(opts) {
|
|
132
68
|
if (!sandboxAvailable())
|
|
133
69
|
return null;
|
|
134
|
-
// In LASTLIGHT_LOCAL_DEV mode, refresh the project-local claude credentials
|
|
135
|
-
// from the host keychain before each sandbox spawn (handles token rotation
|
|
136
|
-
// during long dev sessions). No-op in production.
|
|
137
|
-
refreshLocalDevCredentials();
|
|
138
70
|
const sandboxBase = resolve(opts.sandboxDir || join(opts.stateDir, "sandboxes"));
|
|
139
71
|
mkdirSync(sandboxBase, { recursive: true });
|
|
140
72
|
const workDir = resolve(sandboxBase, opts.taskId);
|
|
@@ -142,12 +74,21 @@ export async function createTaskSandbox(opts) {
|
|
|
142
74
|
throw new Error(`Invalid taskId path escape attempt: ${opts.taskId}`);
|
|
143
75
|
}
|
|
144
76
|
mkdirSync(workDir, { recursive: true });
|
|
77
|
+
if (opts.prePopulate) {
|
|
78
|
+
prePopulateWorkspace(workDir, opts.prePopulate);
|
|
79
|
+
}
|
|
145
80
|
const sandbox = new DockerSandbox({
|
|
146
|
-
imageName: SANDBOX_IMAGE,
|
|
81
|
+
imageName: opts.imageName || SANDBOX_IMAGE,
|
|
147
82
|
env: opts.env || {},
|
|
83
|
+
memoryLimit: process.env.SANDBOX_MEMORY_LIMIT || undefined,
|
|
84
|
+
dnsIp: opts.dnsIp,
|
|
148
85
|
});
|
|
149
86
|
try {
|
|
150
|
-
await sandbox.create({
|
|
87
|
+
await sandbox.create({
|
|
88
|
+
taskId: opts.taskId,
|
|
89
|
+
worktreePath: workDir,
|
|
90
|
+
workspaceMount: resolveWorkspaceMount(opts.stateDir, workDir),
|
|
91
|
+
});
|
|
151
92
|
return {
|
|
152
93
|
sandbox,
|
|
153
94
|
workDir,
|
|
@@ -159,4 +100,193 @@ export async function createTaskSandbox(opts) {
|
|
|
159
100
|
return null;
|
|
160
101
|
}
|
|
161
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Decide how the sandbox container should mount `/home/agent/workspace`.
|
|
105
|
+
*
|
|
106
|
+
* The harness writes the per-task workspace to `workDir`, which is always
|
|
107
|
+
* under `stateDir` (`sandboxes/<taskId>/`). In production, `stateDir` is
|
|
108
|
+
* served by a named docker volume mounted into the harness container. A
|
|
109
|
+
* plain `-v workDir:/home/agent/workspace` bind makes the daemon resolve
|
|
110
|
+
* `workDir` against the *host* filesystem, where the named volume's
|
|
111
|
+
* content is not visible — docker silently creates an empty dir at that
|
|
112
|
+
* host path and mounts it, so the sandbox sees an empty workspace and the
|
|
113
|
+
* skills the harness staged are never reachable.
|
|
114
|
+
*
|
|
115
|
+
* In volume mode we ask docker for a `volume-subpath` mount instead, so
|
|
116
|
+
* the sandbox sees exactly the harness's view. In path mode (local dev,
|
|
117
|
+
* or any deployment where SANDBOX_DATA_VOLUME is a host path) a normal
|
|
118
|
+
* bind is correct because both views point at the same FS path.
|
|
119
|
+
*
|
|
120
|
+
* Edge case: if `opts.sandboxDir` was overridden to live outside `stateDir`,
|
|
121
|
+
* we can't carve a volume-subpath out of the data volume — fall back to
|
|
122
|
+
* a bind mount. That keeps the no-data-volume dev path working; the
|
|
123
|
+
* named-volume + custom-sandboxDir combination isn't currently used.
|
|
124
|
+
*/
|
|
125
|
+
function resolveWorkspaceMount(stateDir, workDir) {
|
|
126
|
+
const dataVolumeRaw = process.env.SANDBOX_DATA_VOLUME || "lastlight_agent-data";
|
|
127
|
+
if (isPathLike(dataVolumeRaw)) {
|
|
128
|
+
return { type: "bind", hostPath: workDir };
|
|
129
|
+
}
|
|
130
|
+
const rel = relative(resolve(stateDir), workDir);
|
|
131
|
+
if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
|
|
132
|
+
return { type: "bind", hostPath: workDir };
|
|
133
|
+
}
|
|
134
|
+
return { type: "volume-subpath", volume: dataVolumeRaw, subpath: rel };
|
|
135
|
+
}
|
|
136
|
+
function isPathLike(value) {
|
|
137
|
+
return value.startsWith("/") ||
|
|
138
|
+
value.startsWith("./") ||
|
|
139
|
+
value.startsWith("../") ||
|
|
140
|
+
value.startsWith("~");
|
|
141
|
+
}
|
|
142
|
+
/** Marker file (at the workspace root, outside the repo so `git clean` can't
|
|
143
|
+
* touch it) recording which run last provisioned this workspace. */
|
|
144
|
+
const RUN_MARKER = ".lastlight-run";
|
|
145
|
+
/**
|
|
146
|
+
* Clone the repo into `<workDir>/<repo>` at the given branch.
|
|
147
|
+
*
|
|
148
|
+
* Three cases:
|
|
149
|
+
* - **Fresh dir** (no `.git`): clone. `--depth 1 --single-branch` for
|
|
150
|
+
* read-only workflows (`pre.shallow`), `--depth 50` otherwise.
|
|
151
|
+
* - **Same run revisiting the workspace** (`.git` exists, run marker matches
|
|
152
|
+
* `pre.runId`): preserve — this is a later phase of the same run reading
|
|
153
|
+
* what an earlier phase wrote (architect's `plan.md`, the reviewer's
|
|
154
|
+
* checkout). No git ops.
|
|
155
|
+
* - **A fresh run reusing an old per-PR workspace** (`.git` exists, marker
|
|
156
|
+
* differs/absent): fetch + hard-reset to the remote branch + `git clean`
|
|
157
|
+
* that **keeps `node_modules`** so the next `npm install` is incremental.
|
|
158
|
+
* This is the re-review fast path from issue #107.
|
|
159
|
+
*/
|
|
160
|
+
export { prePopulateWorkspace as __prePopulateWorkspaceForTest };
|
|
161
|
+
function prePopulateWorkspace(workDir, pre) {
|
|
162
|
+
// Token shape is asserted in src/engine/git-auth.ts before we get here,
|
|
163
|
+
// but re-check the narrow set here too — defense in depth, this string
|
|
164
|
+
// crosses a process boundary into git's command line.
|
|
165
|
+
if (!/^[A-Za-z0-9_-]+$/.test(pre.token)) {
|
|
166
|
+
throw new Error("prePopulate: refusing to embed a token outside [A-Za-z0-9_-]");
|
|
167
|
+
}
|
|
168
|
+
const url = `https://x-access-token:${pre.token}@github.com/${pre.owner}/${pre.repo}.git`;
|
|
169
|
+
// The agent's cwd is `workDir` (the workspace). The harness writes
|
|
170
|
+
// `AGENTS.md` there, so cloning into the workDir root would collide.
|
|
171
|
+
// Instead, clone into a `<repo>/` subdirectory — keeps the layout
|
|
172
|
+
// consistent regardless of whether the harness or the agent did the
|
|
173
|
+
// clone, and leaves room for `.lastlight/issue-N/` scratch space at
|
|
174
|
+
// the workspace root.
|
|
175
|
+
const repoDir = join(workDir, pre.repo);
|
|
176
|
+
const markerPath = join(workDir, RUN_MARKER);
|
|
177
|
+
// Repo dir might already exist — from a later phase of the same run, or a
|
|
178
|
+
// *different* run reusing a stable per-PR workspace (issue #107).
|
|
179
|
+
if (existsSync(join(repoDir, ".git"))) {
|
|
180
|
+
const lastRun = readMarker(markerPath);
|
|
181
|
+
// Same run (or a caller that doesn't track runs): preserve the workspace
|
|
182
|
+
// exactly — earlier phases may have written uncommitted scratch here.
|
|
183
|
+
if (!pre.runId || lastRun === pre.runId) {
|
|
184
|
+
console.log(`[sandbox] Pre-clone skipped: ${repoDir} already a git repo (same run).`);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
// Different run reusing this PR's workspace — refresh in place.
|
|
188
|
+
refreshExistingClone(repoDir, markerPath, pre);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const scrub = (s) => typeof s === "string" ? s.replaceAll(pre.token, "[REDACTED-TOKEN]") : "";
|
|
192
|
+
const start = Date.now();
|
|
193
|
+
const depth = pre.shallow ? "1" : "50";
|
|
194
|
+
const shallowArgs = pre.shallow ? ["--single-branch"] : [];
|
|
195
|
+
try {
|
|
196
|
+
execFileSync("git", ["clone", "--branch", pre.branch, "--depth", depth, ...shallowArgs, url, repoDir], { stdio: "pipe", timeout: 120_000 });
|
|
197
|
+
writeMarker(markerPath, pre.runId);
|
|
198
|
+
const ms = Date.now() - start;
|
|
199
|
+
console.log(`[sandbox] Pre-cloned ${pre.owner}/${pre.repo}@${pre.branch} into ${repoDir} ` +
|
|
200
|
+
`(depth ${depth}, ${ms}ms)`);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
const firstError = scrub(err?.message) || scrub(err?.stderr?.toString?.()) || "unknown error";
|
|
204
|
+
const looksLikeMissingBranch = /Remote branch .* not found|not found in upstream/i.test(firstError);
|
|
205
|
+
if (looksLikeMissingBranch) {
|
|
206
|
+
// Build-style workflows create a brand-new branch (e.g. `lastlight/N-slug`)
|
|
207
|
+
// and push it later. The remote doesn't have it yet at pre-clone time —
|
|
208
|
+
// clone the default branch, then create the target branch locally so
|
|
209
|
+
// the agent enters a workspace already on the right branch with the
|
|
210
|
+
// right upstream URL configured.
|
|
211
|
+
try {
|
|
212
|
+
execFileSync("git", ["clone", "--depth", depth, ...shallowArgs, url, repoDir], { stdio: "pipe", timeout: 120_000 });
|
|
213
|
+
execFileSync("git", ["-C", repoDir, "checkout", "-b", pre.branch], { stdio: "pipe", timeout: 30_000 });
|
|
214
|
+
writeMarker(markerPath, pre.runId);
|
|
215
|
+
const ms = Date.now() - start;
|
|
216
|
+
console.log(`[sandbox] Pre-cloned ${pre.owner}/${pre.repo} (default branch) into ${repoDir} ` +
|
|
217
|
+
`and created local branch ${pre.branch} (${ms}ms)`);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
catch (err2) {
|
|
221
|
+
const secondError = scrub(err2?.message) || scrub(err2?.stderr?.toString?.()) || "unknown error";
|
|
222
|
+
console.warn(`[sandbox] Pre-clone fallback of ${pre.owner}/${pre.repo} failed (${secondError}). ` +
|
|
223
|
+
`Agent will need to clone via MCP.`);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Don't kill the run on a failed pre-clone — fall through to an empty
|
|
228
|
+
// workspace and let the agent clone via the MCP path as a backup.
|
|
229
|
+
//
|
|
230
|
+
// CRITICAL: execFileSync errors echo the failing command line, which
|
|
231
|
+
// includes the auth URL `https://x-access-token:<token>@github.com/…`.
|
|
232
|
+
// The token is scrubbed above before anything reaches the logs.
|
|
233
|
+
console.warn(`[sandbox] Pre-clone of ${pre.owner}/${pre.repo}@${pre.branch} failed (${firstError}). ` +
|
|
234
|
+
`Agent will need to clone via MCP.`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function readMarker(markerPath) {
|
|
238
|
+
try {
|
|
239
|
+
return readFileSync(markerPath, "utf-8").trim() || null;
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function writeMarker(markerPath, runId) {
|
|
246
|
+
if (!runId)
|
|
247
|
+
return;
|
|
248
|
+
try {
|
|
249
|
+
writeFileSync(markerPath, runId);
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// Best-effort — a missing marker just means the next reuse refreshes
|
|
253
|
+
// (the safe direction), never a wrong-preserve.
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Refresh a reused per-PR workspace in place: fetch the branch, hard-reset the
|
|
258
|
+
* checkout to it, and `git clean` away stale tracked/untracked build output —
|
|
259
|
+
* but **keep `node_modules`** (and any nested ones) so the next install is
|
|
260
|
+
* incremental against a warm tree. The shared package cache (docker backend)
|
|
261
|
+
* lives on a separate mount and is untouched by `git clean`.
|
|
262
|
+
*
|
|
263
|
+
* On any failure we leave the workspace as-is and do NOT advance the marker,
|
|
264
|
+
* so the next run retries the refresh rather than reviewing a half-reset tree.
|
|
265
|
+
*/
|
|
266
|
+
function refreshExistingClone(repoDir, markerPath, pre) {
|
|
267
|
+
const scrub = (s) => typeof s === "string" ? s.replaceAll(pre.token, "[REDACTED-TOKEN]") : "";
|
|
268
|
+
const url = `https://x-access-token:${pre.token}@github.com/${pre.owner}/${pre.repo}.git`;
|
|
269
|
+
const depth = pre.shallow ? ["--depth", "1"] : ["--depth", "50"];
|
|
270
|
+
const start = Date.now();
|
|
271
|
+
try {
|
|
272
|
+
// Fetch the branch from the authenticated URL directly so we don't depend
|
|
273
|
+
// on the stored remote (and never persist the token into .git/config).
|
|
274
|
+
execFileSync("git", ["-C", repoDir, "fetch", ...depth, url, pre.branch], { stdio: "pipe", timeout: 120_000 });
|
|
275
|
+
execFileSync("git", ["-C", repoDir, "checkout", "-B", pre.branch, "FETCH_HEAD"], { stdio: "pipe", timeout: 30_000 });
|
|
276
|
+
execFileSync("git", ["-C", repoDir, "reset", "--hard", "FETCH_HEAD"], { stdio: "pipe", timeout: 30_000 });
|
|
277
|
+
// -x removes ignored files (stale dist/, .turbo, coverage, …); -e keeps the
|
|
278
|
+
// dependency trees warm so install is incremental. `node_modules` with no
|
|
279
|
+
// leading slash matches at any depth (monorepos / workspaces).
|
|
280
|
+
execFileSync("git", ["-C", repoDir, "clean", "-fdx", "-e", "node_modules"], { stdio: "pipe", timeout: 60_000 });
|
|
281
|
+
writeMarker(markerPath, pre.runId);
|
|
282
|
+
const ms = Date.now() - start;
|
|
283
|
+
console.log(`[sandbox] Refreshed reused workspace ${repoDir} → ${pre.branch} ` +
|
|
284
|
+
`(fetch+reset+clean, node_modules kept, ${ms}ms)`);
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
const reason = scrub(err?.message) || scrub(err?.stderr?.toString?.()) || "unknown error";
|
|
288
|
+
console.warn(`[sandbox] Refresh of reused workspace ${repoDir} failed (${reason}). ` +
|
|
289
|
+
`Leaving it untouched; agent can re-fetch via MCP.`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
162
292
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
vi.mock("child_process", async (importOriginal) => {
|
|
3
|
+
const actual = await importOriginal();
|
|
4
|
+
return { ...actual, execFileSync: vi.fn() };
|
|
5
|
+
});
|
|
6
|
+
import { execFileSync } from "child_process";
|
|
7
|
+
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync, } from "fs";
|
|
8
|
+
import { tmpdir } from "os";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
import { __prePopulateWorkspaceForTest as prePopulateWorkspace } from "./index.js";
|
|
11
|
+
const mockExec = vi.mocked(execFileSync);
|
|
12
|
+
const TOKEN = "ghs_secret123ABC_xyz";
|
|
13
|
+
/** Flatten every execFileSync invocation's argv (args[1]) for assertions. */
|
|
14
|
+
function calledArgs() {
|
|
15
|
+
return mockExec.mock.calls.map((c) => c[1] ?? []);
|
|
16
|
+
}
|
|
17
|
+
describe("prePopulateWorkspace token-leak protection", () => {
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
vi.restoreAllMocks();
|
|
20
|
+
mockExec.mockReset();
|
|
21
|
+
});
|
|
22
|
+
it("does not leak the token into the success log line", () => {
|
|
23
|
+
const logSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
24
|
+
mockExec.mockReturnValue(Buffer.from(""));
|
|
25
|
+
prePopulateWorkspace("/tmp/work", {
|
|
26
|
+
owner: "cliftonc",
|
|
27
|
+
repo: "lastlight",
|
|
28
|
+
branch: "opencode-fork",
|
|
29
|
+
token: TOKEN,
|
|
30
|
+
});
|
|
31
|
+
const joined = logSpy.mock.calls.flat().join("\n");
|
|
32
|
+
expect(joined).not.toContain(TOKEN);
|
|
33
|
+
});
|
|
34
|
+
it("redacts the token from the warning when git clone fails", () => {
|
|
35
|
+
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
36
|
+
// execFileSync surfaces command failures with an Error whose .message
|
|
37
|
+
// echoes the full command — including the authenticated URL. Reproduce
|
|
38
|
+
// that shape here.
|
|
39
|
+
const failure = new Error(`Command failed: git clone --branch opencode-fork --depth 50 ` +
|
|
40
|
+
`https://x-access-token:${TOKEN}@github.com/cliftonc/lastlight.git /tmp/work\n` +
|
|
41
|
+
`fatal: could not create work tree dir '/tmp/work'`);
|
|
42
|
+
mockExec.mockImplementation(() => { throw failure; });
|
|
43
|
+
prePopulateWorkspace("/tmp/work", {
|
|
44
|
+
owner: "cliftonc",
|
|
45
|
+
repo: "lastlight",
|
|
46
|
+
branch: "opencode-fork",
|
|
47
|
+
token: TOKEN,
|
|
48
|
+
});
|
|
49
|
+
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
50
|
+
const logged = warnSpy.mock.calls[0].join(" ");
|
|
51
|
+
expect(logged).not.toContain(TOKEN);
|
|
52
|
+
expect(logged).toContain("[REDACTED-TOKEN]");
|
|
53
|
+
// Sanity: the non-secret part of the diagnostic is preserved.
|
|
54
|
+
expect(logged).toContain("opencode-fork");
|
|
55
|
+
expect(logged).toContain("Pre-clone");
|
|
56
|
+
});
|
|
57
|
+
it("refuses to embed tokens containing characters outside [A-Za-z0-9_-]", () => {
|
|
58
|
+
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
59
|
+
expect(() => prePopulateWorkspace("/tmp/work", {
|
|
60
|
+
owner: "x",
|
|
61
|
+
repo: "y",
|
|
62
|
+
branch: "z",
|
|
63
|
+
token: 'evil";rm -rf /;"',
|
|
64
|
+
})).toThrow(/outside \[A-Za-z0-9_-\]/);
|
|
65
|
+
expect(mockExec).not.toHaveBeenCalled();
|
|
66
|
+
warnSpy.mockRestore();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe("prePopulateWorkspace clone depth + per-PR reuse (issue #107)", () => {
|
|
70
|
+
let workDir;
|
|
71
|
+
const REPO = "lastlight";
|
|
72
|
+
beforeEach(() => {
|
|
73
|
+
workDir = mkdtempSync(join(tmpdir(), "ll-prepop-"));
|
|
74
|
+
vi.spyOn(console, "log").mockImplementation(() => { });
|
|
75
|
+
vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
76
|
+
mockExec.mockReturnValue(Buffer.from(""));
|
|
77
|
+
});
|
|
78
|
+
afterEach(() => {
|
|
79
|
+
vi.restoreAllMocks();
|
|
80
|
+
mockExec.mockReset();
|
|
81
|
+
rmSync(workDir, { recursive: true, force: true });
|
|
82
|
+
});
|
|
83
|
+
/** Pretend the workspace already has a clone, with `marker` as last run. */
|
|
84
|
+
function seedExistingClone(marker) {
|
|
85
|
+
mkdirSync(join(workDir, REPO, ".git"), { recursive: true });
|
|
86
|
+
if (marker !== undefined)
|
|
87
|
+
writeFileSync(join(workDir, ".lastlight-run"), marker);
|
|
88
|
+
}
|
|
89
|
+
it("clones read-only workflows shallow (--depth 1 --single-branch)", () => {
|
|
90
|
+
prePopulateWorkspace(workDir, {
|
|
91
|
+
owner: "cliftonc", repo: REPO, branch: "main", token: TOKEN,
|
|
92
|
+
runId: "run-1", shallow: true,
|
|
93
|
+
});
|
|
94
|
+
const clone = calledArgs().find((a) => a[0] === "clone");
|
|
95
|
+
expect(clone).toContain("--depth");
|
|
96
|
+
expect(clone[clone.indexOf("--depth") + 1]).toBe("1");
|
|
97
|
+
expect(clone).toContain("--single-branch");
|
|
98
|
+
// Marker stamped so a later same-run phase preserves the workspace.
|
|
99
|
+
expect(readFileSync(join(workDir, ".lastlight-run"), "utf-8")).toBe("run-1");
|
|
100
|
+
});
|
|
101
|
+
it("clones code-writing workflows deep (--depth 50, no --single-branch)", () => {
|
|
102
|
+
prePopulateWorkspace(workDir, {
|
|
103
|
+
owner: "cliftonc", repo: REPO, branch: "main", token: TOKEN,
|
|
104
|
+
runId: "run-1", shallow: false,
|
|
105
|
+
});
|
|
106
|
+
const clone = calledArgs().find((a) => a[0] === "clone");
|
|
107
|
+
expect(clone[clone.indexOf("--depth") + 1]).toBe("50");
|
|
108
|
+
expect(clone).not.toContain("--single-branch");
|
|
109
|
+
});
|
|
110
|
+
it("preserves the workspace when a later phase of the SAME run revisits it", () => {
|
|
111
|
+
seedExistingClone("run-1");
|
|
112
|
+
prePopulateWorkspace(workDir, {
|
|
113
|
+
owner: "cliftonc", repo: REPO, branch: "main", token: TOKEN, runId: "run-1",
|
|
114
|
+
});
|
|
115
|
+
// No git ops — the architect's uncommitted scratch must survive.
|
|
116
|
+
expect(mockExec).not.toHaveBeenCalled();
|
|
117
|
+
});
|
|
118
|
+
it("preserves the workspace for callers that don't track a run id", () => {
|
|
119
|
+
seedExistingClone();
|
|
120
|
+
prePopulateWorkspace(workDir, {
|
|
121
|
+
owner: "cliftonc", repo: REPO, branch: "main", token: TOKEN,
|
|
122
|
+
});
|
|
123
|
+
expect(mockExec).not.toHaveBeenCalled();
|
|
124
|
+
});
|
|
125
|
+
it("refreshes (fetch+reset+clean) when a DIFFERENT run reuses the PR dir", () => {
|
|
126
|
+
seedExistingClone("old-run");
|
|
127
|
+
prePopulateWorkspace(workDir, {
|
|
128
|
+
owner: "cliftonc", repo: REPO, branch: "pr-head", token: TOKEN,
|
|
129
|
+
runId: "new-run", shallow: true,
|
|
130
|
+
});
|
|
131
|
+
const verbs = calledArgs().map((a) => a[a.indexOf("-C") + 2]);
|
|
132
|
+
expect(verbs).toEqual(["fetch", "checkout", "reset", "clean"]);
|
|
133
|
+
// node_modules is kept warm so the next install is incremental.
|
|
134
|
+
const clean = calledArgs().find((a) => a.includes("clean"));
|
|
135
|
+
expect(clean).toContain("-e");
|
|
136
|
+
expect(clean).toContain("node_modules");
|
|
137
|
+
// Never re-clones from scratch.
|
|
138
|
+
expect(calledArgs().some((a) => a[0] === "clone")).toBe(false);
|
|
139
|
+
// Marker advanced to the new run.
|
|
140
|
+
expect(readFileSync(join(workDir, ".lastlight-run"), "utf-8")).toBe("new-run");
|
|
141
|
+
});
|
|
142
|
+
it("does not advance the marker if the refresh fetch fails", () => {
|
|
143
|
+
seedExistingClone("old-run");
|
|
144
|
+
mockExec.mockImplementation((_cmd, args) => {
|
|
145
|
+
if (args.includes("fetch"))
|
|
146
|
+
throw new Error("network down");
|
|
147
|
+
return Buffer.from("");
|
|
148
|
+
});
|
|
149
|
+
prePopulateWorkspace(workDir, {
|
|
150
|
+
owner: "cliftonc", repo: REPO, branch: "pr-head", token: TOKEN,
|
|
151
|
+
runId: "new-run", shallow: true,
|
|
152
|
+
});
|
|
153
|
+
// Stale marker retained → the next run retries the refresh.
|
|
154
|
+
expect(readFileSync(join(workDir, ".lastlight-run"), "utf-8")).toBe("old-run");
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/sandbox/index.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export declare const CHAT_PROJECT_SLUG = "-app";
|
|
2
|
+
export type SessionLogScope = "sandbox" | "chat";
|
|
3
|
+
/** Normalized message shape returned by session-log readers. */
|
|
4
|
+
export interface JsonlMessage {
|
|
5
|
+
role: string;
|
|
6
|
+
content?: unknown;
|
|
7
|
+
tool_calls?: unknown;
|
|
8
|
+
tool_name?: string;
|
|
9
|
+
tool_call_id?: string;
|
|
10
|
+
timestamp?: string;
|
|
11
|
+
reasoning?: unknown;
|
|
12
|
+
finish_reason?: string;
|
|
13
|
+
[k: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface SessionLogRef {
|
|
16
|
+
projectSlug: string;
|
|
17
|
+
sessionId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SessionLogEntry {
|
|
20
|
+
id: string;
|
|
21
|
+
filePath: string;
|
|
22
|
+
mtimeMs: number;
|
|
23
|
+
projectSlug: string;
|
|
24
|
+
}
|
|
25
|
+
export interface NormalizedLogRecord {
|
|
26
|
+
timestamp: string;
|
|
27
|
+
msg: JsonlMessage;
|
|
28
|
+
raw: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Filesystem cwd → project-dir slug (matches the SDK convention). The
|
|
32
|
+
* absolute path with `/` replaced by `-`. `/app` → `-app`,
|
|
33
|
+
* `/home/agent/workspace` → `-home-agent-workspace`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function projectSlugForCwd(cwd: string): string;
|
|
36
|
+
export declare class SessionLog {
|
|
37
|
+
private homeDir;
|
|
38
|
+
constructor(homeDir: string);
|
|
39
|
+
normalizeSessionId(sessionId: string): string | null;
|
|
40
|
+
pathForProject(projectSlug: string, sessionId: string, opts?: {
|
|
41
|
+
requireExists?: boolean;
|
|
42
|
+
}): string | null;
|
|
43
|
+
findSession(scope: SessionLogScope, sessionId: string): SessionLogEntry | null;
|
|
44
|
+
listSessions(scope: SessionLogScope): SessionLogEntry[];
|
|
45
|
+
relatedFilesForSession(scope: SessionLogScope, sessionId: string, opts?: {
|
|
46
|
+
includeAgents?: boolean;
|
|
47
|
+
}): string[];
|
|
48
|
+
appendEnvelopeLines(ref: SessionLogRef, lines: object[]): Promise<void>;
|
|
49
|
+
readNormalizedFile(filePath: string, opts?: {
|
|
50
|
+
skipEmptySystem?: boolean;
|
|
51
|
+
}): Promise<NormalizedLogRecord[]>;
|
|
52
|
+
readNormalizedSession(scope: SessionLogScope, sessionId: string, opts?: {
|
|
53
|
+
includeAgents?: boolean;
|
|
54
|
+
skipEmptySystem?: boolean;
|
|
55
|
+
}): Promise<Array<{
|
|
56
|
+
index: number;
|
|
57
|
+
msg: JsonlMessage;
|
|
58
|
+
}>>;
|
|
59
|
+
normalizeLine(raw: Record<string, unknown>): JsonlMessage[];
|
|
60
|
+
private isSafeProjectSlug;
|
|
61
|
+
private projectDirs;
|
|
62
|
+
private mtimeMs;
|
|
63
|
+
}
|