lastlight 0.15.0 → 0.16.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 +71 -692
- package/dist/cli-config.js.map +1 -0
- package/dist/cli-format.js.map +1 -0
- package/dist/{cli/cli-server.d.ts → cli-server.d.ts} +26 -1
- package/dist/{cli/cli-server.js → cli-server.js} +40 -5
- package/dist/cli-server.js.map +1 -0
- package/dist/cli-timeline.js.map +1 -0
- package/dist/{cli/cli.js → cli.js} +4 -3
- package/dist/cli.js.map +1 -0
- package/dist/{cli/fork-cli.d.ts → fork-cli.d.ts} +3 -3
- package/dist/{cli/fork-cli.js → fork-cli.js} +28 -27
- package/dist/fork-cli.js.map +1 -0
- package/dist/{cli/oauth-cli.js → oauth-cli.js} +1 -1
- package/dist/oauth-cli.js.map +1 -0
- package/dist/{cli/setup.js → setup.js} +10 -4
- package/dist/setup.js.map +1 -0
- package/dist/{cli/skills-install.d.ts → skills-install.d.ts} +6 -0
- package/dist/{cli/skills-install.js → skills-install.js} +6 -2
- package/dist/skills-install.js.map +1 -0
- package/package.json +20 -65
- package/plugins/lastlight/.claude-plugin/plugin.json +1 -1
- package/agent-context/rules.md +0 -80
- package/agent-context/security.md +0 -69
- package/agent-context/soul.md +0 -21
- package/config/default.yaml +0 -119
- package/deploy/.env.production.example +0 -100
- package/deploy/entrypoint.sh +0 -82
- package/deploy/native/README.md +0 -160
- package/deploy/native/install.sh +0 -110
- package/deploy/native/lastlight.env.example +0 -95
- package/deploy/native/lastlight.service +0 -50
- package/deploy/sandbox-entrypoint.sh +0 -93
- package/dist/admin/auth.d.ts +0 -51
- package/dist/admin/auth.js +0 -121
- package/dist/admin/auth.js.map +0 -1
- package/dist/admin/chat-session-reader.d.ts +0 -39
- package/dist/admin/chat-session-reader.js +0 -84
- package/dist/admin/chat-session-reader.js.map +0 -1
- package/dist/admin/docker.d.ts +0 -61
- package/dist/admin/docker.js +0 -187
- package/dist/admin/docker.js.map +0 -1
- package/dist/admin/index.d.ts +0 -9
- package/dist/admin/index.js +0 -59
- package/dist/admin/index.js.map +0 -1
- package/dist/admin/routes.d.ts +0 -81
- package/dist/admin/routes.js +0 -1381
- package/dist/admin/routes.js.map +0 -1
- package/dist/admin/sessions.d.ts +0 -89
- package/dist/admin/sessions.js +0 -204
- package/dist/admin/sessions.js.map +0 -1
- package/dist/admin/tail.d.ts +0 -12
- package/dist/admin/tail.js +0 -145
- package/dist/admin/tail.js.map +0 -1
- package/dist/admin/version.d.ts +0 -22
- package/dist/admin/version.js +0 -92
- package/dist/admin/version.js.map +0 -1
- package/dist/cli/cli-config.js.map +0 -1
- package/dist/cli/cli-format.js.map +0 -1
- package/dist/cli/cli-server.js.map +0 -1
- package/dist/cli/cli-timeline.js.map +0 -1
- package/dist/cli/cli.js.map +0 -1
- package/dist/cli/fork-cli.js.map +0 -1
- package/dist/cli/oauth-cli.js.map +0 -1
- package/dist/cli/setup.js.map +0 -1
- package/dist/cli/skills-install.js.map +0 -1
- package/dist/config/config-resolve.d.ts +0 -28
- package/dist/config/config-resolve.js +0 -47
- package/dist/config/config-resolve.js.map +0 -1
- package/dist/config/config.d.ts +0 -157
- package/dist/config/config.js +0 -581
- package/dist/config/config.js.map +0 -1
- package/dist/config/core-pin.d.ts +0 -16
- package/dist/config/core-pin.js +0 -85
- package/dist/config/core-pin.js.map +0 -1
- package/dist/config/overlay-assets.d.ts +0 -20
- package/dist/config/overlay-assets.js +0 -114
- package/dist/config/overlay-assets.js.map +0 -1
- package/dist/config/overlay-bootstrap.d.ts +0 -44
- package/dist/config/overlay-bootstrap.js +0 -304
- package/dist/config/overlay-bootstrap.js.map +0 -1
- package/dist/connectors/github-webhook.d.ts +0 -45
- package/dist/connectors/github-webhook.js +0 -321
- package/dist/connectors/github-webhook.js.map +0 -1
- package/dist/connectors/index.d.ts +0 -18
- package/dist/connectors/index.js +0 -41
- package/dist/connectors/index.js.map +0 -1
- package/dist/connectors/messaging/base.d.ts +0 -42
- package/dist/connectors/messaging/base.js +0 -139
- package/dist/connectors/messaging/base.js.map +0 -1
- package/dist/connectors/messaging/delivery.d.ts +0 -14
- package/dist/connectors/messaging/delivery.js +0 -38
- package/dist/connectors/messaging/delivery.js.map +0 -1
- package/dist/connectors/messaging/index.d.ts +0 -4
- package/dist/connectors/messaging/index.js +0 -4
- package/dist/connectors/messaging/index.js.map +0 -1
- package/dist/connectors/messaging/session-manager.d.ts +0 -53
- package/dist/connectors/messaging/session-manager.js +0 -255
- package/dist/connectors/messaging/session-manager.js.map +0 -1
- package/dist/connectors/messaging/types.d.ts +0 -58
- package/dist/connectors/messaging/types.js +0 -7
- package/dist/connectors/messaging/types.js.map +0 -1
- package/dist/connectors/slack/connector.d.ts +0 -100
- package/dist/connectors/slack/connector.js +0 -341
- package/dist/connectors/slack/connector.js.map +0 -1
- package/dist/connectors/slack/index.d.ts +0 -2
- package/dist/connectors/slack/index.js +0 -3
- package/dist/connectors/slack/index.js.map +0 -1
- package/dist/connectors/slack/mrkdwn.d.ts +0 -8
- package/dist/connectors/slack/mrkdwn.js +0 -123
- package/dist/connectors/slack/mrkdwn.js.map +0 -1
- package/dist/connectors/types.d.ts +0 -61
- package/dist/connectors/types.js +0 -2
- package/dist/connectors/types.js.map +0 -1
- package/dist/cron/fanout.d.ts +0 -33
- package/dist/cron/fanout.js +0 -55
- package/dist/cron/fanout.js.map +0 -1
- package/dist/cron/jobs.d.ts +0 -18
- package/dist/cron/jobs.js +0 -37
- package/dist/cron/jobs.js.map +0 -1
- package/dist/cron/scheduler.d.ts +0 -45
- package/dist/cron/scheduler.js +0 -105
- package/dist/cron/scheduler.js.map +0 -1
- package/dist/engine/agent-executor.d.ts +0 -34
- package/dist/engine/agent-executor.js +0 -246
- package/dist/engine/agent-executor.js.map +0 -1
- package/dist/engine/chat/chat-runner.d.ts +0 -132
- package/dist/engine/chat/chat-runner.js +0 -424
- package/dist/engine/chat/chat-runner.js.map +0 -1
- package/dist/engine/chat/chat-skills.d.ts +0 -45
- package/dist/engine/chat/chat-skills.js +0 -184
- package/dist/engine/chat/chat-skills.js.map +0 -1
- package/dist/engine/chat/chat.d.ts +0 -54
- package/dist/engine/chat/chat.js +0 -316
- package/dist/engine/chat/chat.js.map +0 -1
- package/dist/engine/chat/message-batcher.d.ts +0 -32
- package/dist/engine/chat/message-batcher.js +0 -109
- package/dist/engine/chat/message-batcher.js.map +0 -1
- package/dist/engine/dispatcher.d.ts +0 -73
- package/dist/engine/dispatcher.js +0 -663
- package/dist/engine/dispatcher.js.map +0 -1
- package/dist/engine/event-shim.d.ts +0 -117
- package/dist/engine/event-shim.js +0 -435
- package/dist/engine/event-shim.js.map +0 -1
- package/dist/engine/executors/orchestrator.d.ts +0 -81
- package/dist/engine/executors/orchestrator.js +0 -365
- package/dist/engine/executors/orchestrator.js.map +0 -1
- package/dist/engine/executors/shared.d.ts +0 -189
- package/dist/engine/executors/shared.js +0 -616
- package/dist/engine/executors/shared.js.map +0 -1
- package/dist/engine/github/git-auth.d.ts +0 -62
- package/dist/engine/github/git-auth.js +0 -161
- package/dist/engine/github/git-auth.js.map +0 -1
- package/dist/engine/github/github-app-client.d.ts +0 -23
- package/dist/engine/github/github-app-client.js +0 -33
- package/dist/engine/github/github-app-client.js.map +0 -1
- package/dist/engine/github/github-tools.d.ts +0 -18
- package/dist/engine/github/github-tools.js +0 -263
- package/dist/engine/github/github-tools.js.map +0 -1
- package/dist/engine/github/github.d.ts +0 -1193
- package/dist/engine/github/github.js +0 -357
- package/dist/engine/github/github.js.map +0 -1
- package/dist/engine/github/profiles.d.ts +0 -279
- package/dist/engine/github/profiles.js +0 -42
- package/dist/engine/github/profiles.js.map +0 -1
- package/dist/engine/github/review-poster.d.ts +0 -98
- package/dist/engine/github/review-poster.js +0 -177
- package/dist/engine/github/review-poster.js.map +0 -1
- package/dist/engine/llm.d.ts +0 -79
- package/dist/engine/llm.js +0 -269
- package/dist/engine/llm.js.map +0 -1
- package/dist/engine/oauth.d.ts +0 -43
- package/dist/engine/oauth.js +0 -103
- package/dist/engine/oauth.js.map +0 -1
- package/dist/engine/router.d.ts +0 -29
- package/dist/engine/router.js +0 -680
- package/dist/engine/router.js.map +0 -1
- package/dist/engine/screen/classifier.d.ts +0 -93
- package/dist/engine/screen/classifier.js +0 -215
- package/dist/engine/screen/classifier.js.map +0 -1
- package/dist/engine/screen/screen.d.ts +0 -41
- package/dist/engine/screen/screen.js +0 -93
- package/dist/engine/screen/screen.js.map +0 -1
- package/dist/evals-api.d.ts +0 -24
- package/dist/evals-api.js +0 -22
- package/dist/evals-api.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -923
- package/dist/index.js.map +0 -1
- package/dist/managed-repos.d.ts +0 -30
- package/dist/managed-repos.js +0 -72
- package/dist/managed-repos.js.map +0 -1
- package/dist/notify/index.d.ts +0 -15
- package/dist/notify/index.js +0 -6
- package/dist/notify/index.js.map +0 -1
- package/dist/notify/model.d.ts +0 -57
- package/dist/notify/model.js +0 -89
- package/dist/notify/model.js.map +0 -1
- package/dist/notify/notifier.d.ts +0 -17
- package/dist/notify/notifier.js +0 -87
- package/dist/notify/notifier.js.map +0 -1
- package/dist/notify/render.d.ts +0 -21
- package/dist/notify/render.js +0 -59
- package/dist/notify/render.js.map +0 -1
- package/dist/notify/transports/github.d.ts +0 -26
- package/dist/notify/transports/github.js +0 -26
- package/dist/notify/transports/github.js.map +0 -1
- package/dist/notify/transports/slack.d.ts +0 -26
- package/dist/notify/transports/slack.js +0 -28
- package/dist/notify/transports/slack.js.map +0 -1
- package/dist/notify/types.d.ts +0 -95
- package/dist/notify/types.js +0 -16
- package/dist/notify/types.js.map +0 -1
- package/dist/providers.d.ts +0 -125
- package/dist/providers.js +0 -279
- package/dist/providers.js.map +0 -1
- package/dist/sandbox/docker.d.ts +0 -180
- package/dist/sandbox/docker.js +0 -517
- package/dist/sandbox/docker.js.map +0 -1
- package/dist/sandbox/egress-allowlist.d.ts +0 -74
- package/dist/sandbox/egress-allowlist.js +0 -164
- package/dist/sandbox/egress-allowlist.js.map +0 -1
- package/dist/sandbox/egress-firewall-config.d.ts +0 -127
- package/dist/sandbox/egress-firewall-config.js +0 -434
- package/dist/sandbox/egress-firewall-config.js.map +0 -1
- package/dist/sandbox/images.d.ts +0 -23
- package/dist/sandbox/images.js +0 -55
- package/dist/sandbox/images.js.map +0 -1
- package/dist/sandbox/index.d.ts +0 -112
- package/dist/sandbox/index.js +0 -332
- package/dist/sandbox/index.js.map +0 -1
- package/dist/sandbox/sandbox.d.ts +0 -214
- package/dist/sandbox/sandbox.js +0 -453
- package/dist/sandbox/sandbox.js.map +0 -1
- package/dist/sandbox/smol.d.ts +0 -162
- package/dist/sandbox/smol.js +0 -485
- package/dist/sandbox/smol.js.map +0 -1
- package/dist/session-log.d.ts +0 -63
- package/dist/session-log.js +0 -290
- package/dist/session-log.js.map +0 -1
- package/dist/state/approval-store.d.ts +0 -88
- package/dist/state/approval-store.js +0 -149
- package/dist/state/approval-store.js.map +0 -1
- package/dist/state/build-assets.d.ts +0 -50
- package/dist/state/build-assets.js +0 -154
- package/dist/state/build-assets.js.map +0 -1
- package/dist/state/db.d.ts +0 -81
- package/dist/state/db.js +0 -155
- package/dist/state/db.js.map +0 -1
- package/dist/state/execution-store.d.ts +0 -257
- package/dist/state/execution-store.js +0 -527
- package/dist/state/execution-store.js.map +0 -1
- package/dist/state/migrate.d.ts +0 -15
- package/dist/state/migrate.js +0 -175
- package/dist/state/migrate.js.map +0 -1
- package/dist/state/workflow-run-store.d.ts +0 -216
- package/dist/state/workflow-run-store.js +0 -403
- package/dist/state/workflow-run-store.js.map +0 -1
- package/dist/telemetry/index.d.ts +0 -38
- package/dist/telemetry/index.js +0 -253
- package/dist/telemetry/index.js.map +0 -1
- package/dist/telemetry/pi-events.d.ts +0 -12
- package/dist/telemetry/pi-events.js +0 -134
- package/dist/telemetry/pi-events.js.map +0 -1
- package/dist/workflows/dag.d.ts +0 -37
- package/dist/workflows/dag.js +0 -118
- package/dist/workflows/dag.js.map +0 -1
- package/dist/workflows/loader.d.ts +0 -53
- package/dist/workflows/loader.js +0 -421
- package/dist/workflows/loader.js.map +0 -1
- package/dist/workflows/loop-eval.d.ts +0 -28
- package/dist/workflows/loop-eval.js +0 -74
- package/dist/workflows/loop-eval.js.map +0 -1
- package/dist/workflows/phase-executor.d.ts +0 -215
- package/dist/workflows/phase-executor.js +0 -1144
- package/dist/workflows/phase-executor.js.map +0 -1
- package/dist/workflows/phase-ref.d.ts +0 -50
- package/dist/workflows/phase-ref.js +0 -91
- package/dist/workflows/phase-ref.js.map +0 -1
- package/dist/workflows/resume.d.ts +0 -58
- package/dist/workflows/resume.js +0 -313
- package/dist/workflows/resume.js.map +0 -1
- package/dist/workflows/runner.d.ts +0 -63
- package/dist/workflows/runner.js +0 -364
- package/dist/workflows/runner.js.map +0 -1
- package/dist/workflows/schema.d.ts +0 -344
- package/dist/workflows/schema.js +0 -460
- package/dist/workflows/schema.js.map +0 -1
- package/dist/workflows/simple.d.ts +0 -90
- package/dist/workflows/simple.js +0 -393
- package/dist/workflows/simple.js.map +0 -1
- package/dist/workflows/target-policy.d.ts +0 -74
- package/dist/workflows/target-policy.js +0 -80
- package/dist/workflows/target-policy.js.map +0 -1
- package/dist/workflows/templates.d.ts +0 -88
- package/dist/workflows/templates.js +0 -127
- package/dist/workflows/templates.js.map +0 -1
- package/dist/workflows/triggers.d.ts +0 -21
- package/dist/workflows/triggers.js +0 -45
- package/dist/workflows/triggers.js.map +0 -1
- package/dist/workflows/verdict.d.ts +0 -19
- package/dist/workflows/verdict.js +0 -30
- package/dist/workflows/verdict.js.map +0 -1
- package/dist/worktree/manager.d.ts +0 -43
- package/dist/worktree/manager.js +0 -127
- package/dist/worktree/manager.js.map +0 -1
- package/docker-compose.yml +0 -274
- package/sandbox.Dockerfile +0 -68
- package/skills/README.md +0 -42
- package/skills/browser-qa/SKILL.md +0 -208
- package/skills/browser-qa/scripts/agent-browser.mjs +0 -531
- package/skills/building/SKILL.md +0 -95
- package/skills/chat/SKILL.md +0 -36
- package/skills/code-review/SKILL.md +0 -82
- package/skills/debug-production/SKILL.md +0 -108
- package/skills/demo/SKILL.md +0 -228
- package/skills/demo/scripts/compose-demo.sh +0 -243
- package/skills/issue-answer/SKILL.md +0 -91
- package/skills/issue-comment/SKILL.md +0 -49
- package/skills/issue-triage/SKILL.md +0 -149
- package/skills/issue-triage/references/AGENT-BRIEF.md +0 -65
- package/skills/pr-comment/SKILL.md +0 -64
- package/skills/pr-review/SKILL.md +0 -148
- package/skills/pr-review/references/findings-schema.md +0 -89
- package/skills/qa-test/SKILL.md +0 -97
- package/skills/repo-health/SKILL.md +0 -67
- package/skills/security-feedback/SKILL.md +0 -173
- package/skills/security-feedback/references/templates.md +0 -77
- package/skills/security-review/SKILL.md +0 -215
- package/skills/security-review/references/issue-format.md +0 -302
- package/skills/verify/SKILL.md +0 -118
- package/workflows/answer.yaml +0 -44
- package/workflows/build.yaml +0 -129
- package/workflows/cron-health.yaml +0 -6
- package/workflows/cron-review.yaml +0 -8
- package/workflows/cron-security.yaml +0 -6
- package/workflows/cron-triage.yaml +0 -8
- package/workflows/demo.yaml +0 -62
- package/workflows/examples/bash-smoke.yaml +0 -41
- package/workflows/examples/parallel-review.yaml +0 -36
- package/workflows/examples/tdd-loop.yaml +0 -17
- package/workflows/explore.yaml +0 -80
- package/workflows/issue-comment.yaml +0 -15
- package/workflows/issue-triage.yaml +0 -22
- package/workflows/pr-comment.yaml +0 -16
- package/workflows/pr-fix.yaml +0 -17
- package/workflows/pr-review.yaml +0 -50
- package/workflows/prompts/answer.md +0 -68
- package/workflows/prompts/architect.md +0 -44
- package/workflows/prompts/classifier.md +0 -60
- package/workflows/prompts/classify-adds-info.md +0 -17
- package/workflows/prompts/demo.md +0 -125
- package/workflows/prompts/executor.md +0 -42
- package/workflows/prompts/explore-ask.md +0 -99
- package/workflows/prompts/explore-publish.md +0 -31
- package/workflows/prompts/explore-read.md +0 -120
- package/workflows/prompts/explore-synthesize.md +0 -88
- package/workflows/prompts/fix.md +0 -18
- package/workflows/prompts/guardrails.md +0 -96
- package/workflows/prompts/pr-fix.md +0 -26
- package/workflows/prompts/pr.md +0 -39
- package/workflows/prompts/qa-browser.md +0 -95
- package/workflows/prompts/qa-synth.md +0 -44
- package/workflows/prompts/qa-test.md +0 -60
- package/workflows/prompts/re-reviewer.md +0 -33
- package/workflows/prompts/reviewer.md +0 -60
- package/workflows/prompts/verify-browser.md +0 -93
- package/workflows/prompts/verify-synth.md +0 -44
- package/workflows/prompts/verify.md +0 -63
- package/workflows/qa-test.yaml +0 -94
- package/workflows/repo-health.yaml +0 -15
- package/workflows/security-feedback.yaml +0 -25
- package/workflows/security-review.yaml +0 -37
- package/workflows/verify.yaml +0 -93
- /package/dist/{cli/cli-config.d.ts → cli-config.d.ts} +0 -0
- /package/dist/{cli/cli-config.js → cli-config.js} +0 -0
- /package/dist/{cli/cli-format.d.ts → cli-format.d.ts} +0 -0
- /package/dist/{cli/cli-format.js → cli-format.js} +0 -0
- /package/dist/{cli/cli-timeline.d.ts → cli-timeline.d.ts} +0 -0
- /package/dist/{cli/cli-timeline.js → cli-timeline.js} +0 -0
- /package/dist/{cli/cli.d.ts → cli.d.ts} +0 -0
- /package/dist/{cli/oauth-cli.d.ts → oauth-cli.d.ts} +0 -0
- /package/dist/{cli/setup.d.ts → setup.d.ts} +0 -0
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server-side store for build handoff docs ("server mode").
|
|
3
|
-
*
|
|
4
|
-
* In the default "repo" mode the per-phase docs (architect-plan.md, status.md,
|
|
5
|
-
* executor-summary.md, reviewer-verdict.md, …) are committed into the target
|
|
6
|
-
* repo under `.lastlight/<issueKey>/` and ride the working branch. In "server"
|
|
7
|
-
* mode they live here instead — on the Last Light host, never committed — and
|
|
8
|
-
* are staged into each sandbox phase from outside the repo (the same way skills
|
|
9
|
-
* are) and harvested back after the phase runs.
|
|
10
|
-
*
|
|
11
|
-
* Layout mirrors the rest of `$STATE_DIR` (opencode-home/projects, sandboxes):
|
|
12
|
-
*
|
|
13
|
-
* <root>/<owner>/<repo>/<issueKey>/<file>.md
|
|
14
|
-
*
|
|
15
|
-
* `root` defaults to `$STATE_DIR/build-assets` (override `BUILD_ASSETS_DIR`).
|
|
16
|
-
* Every path segment is validated to stay inside `root` — the admin API serves
|
|
17
|
-
* these by name, so traversal must be impossible.
|
|
18
|
-
*/
|
|
19
|
-
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from "fs";
|
|
20
|
-
import { join, resolve, sep } from "path";
|
|
21
|
-
/**
|
|
22
|
-
* Derive the stable per-run key used both as the store sub-path and (with a
|
|
23
|
-
* `.lastlight/` prefix) as the in-repo `issueDir`. Issue-scoped runs share a
|
|
24
|
-
* key by issue number; non-issue runs (explore, health, …) get a run-scoped
|
|
25
|
-
* key so concurrent sessions never overlap. Mirrors the derivation that lived
|
|
26
|
-
* inline in `src/workflows/simple.ts`.
|
|
27
|
-
*/
|
|
28
|
-
export function buildAssetIssueKey(workflowName, issueNumber, workflowId) {
|
|
29
|
-
return issueNumber !== undefined
|
|
30
|
-
? `issue-${issueNumber}`
|
|
31
|
-
: `${workflowName}-${workflowId.slice(0, 8)}`;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* A single path segment (owner / repo / issueKey / filename) is safe when it is
|
|
35
|
-
* non-empty, carries no path separators, and is not a `.`/`..` traversal token.
|
|
36
|
-
* GitHub owners/repos and our own issueKeys/filenames all satisfy this; anything
|
|
37
|
-
* else is rejected rather than sanitized so a bad input fails loudly.
|
|
38
|
-
*/
|
|
39
|
-
function assertSafeSegment(segment, label) {
|
|
40
|
-
if (!segment ||
|
|
41
|
-
segment === "." ||
|
|
42
|
-
segment === ".." ||
|
|
43
|
-
segment.includes("/") ||
|
|
44
|
-
segment.includes("\\") ||
|
|
45
|
-
segment.includes("\0")) {
|
|
46
|
-
throw new Error(`Unsafe build-asset ${label}: ${JSON.stringify(segment)}`);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
/** True when `child` resolves to a path inside `parent`. */
|
|
50
|
-
function isInside(parent, child) {
|
|
51
|
-
const p = resolve(parent);
|
|
52
|
-
const c = resolve(child);
|
|
53
|
-
return c === p || c.startsWith(p + sep);
|
|
54
|
-
}
|
|
55
|
-
export class BuildAssetStore {
|
|
56
|
-
root;
|
|
57
|
-
constructor(root) {
|
|
58
|
-
this.root = resolve(root);
|
|
59
|
-
}
|
|
60
|
-
/** Absolute directory for a run's doc set. Validates every segment. */
|
|
61
|
-
dirFor(ref) {
|
|
62
|
-
assertSafeSegment(ref.owner, "owner");
|
|
63
|
-
assertSafeSegment(ref.repo, "repo");
|
|
64
|
-
assertSafeSegment(ref.issueKey, "issueKey");
|
|
65
|
-
const dir = join(this.root, ref.owner, ref.repo, ref.issueKey);
|
|
66
|
-
if (!isInside(this.root, dir)) {
|
|
67
|
-
throw new Error(`build-asset dir escapes store root: ${dir}`);
|
|
68
|
-
}
|
|
69
|
-
return dir;
|
|
70
|
-
}
|
|
71
|
-
/** Absolute path for one doc file, with traversal validation on the name. */
|
|
72
|
-
fileFor(ref, file) {
|
|
73
|
-
assertSafeSegment(file, "filename");
|
|
74
|
-
const path = join(this.dirFor(ref), file);
|
|
75
|
-
if (!isInside(this.root, path)) {
|
|
76
|
-
throw new Error(`build-asset file escapes store root: ${path}`);
|
|
77
|
-
}
|
|
78
|
-
return path;
|
|
79
|
-
}
|
|
80
|
-
/** Read one doc, or undefined when it does not exist. */
|
|
81
|
-
read(ref, file) {
|
|
82
|
-
const path = this.fileFor(ref, file);
|
|
83
|
-
if (!existsSync(path))
|
|
84
|
-
return undefined;
|
|
85
|
-
return readFileSync(path, "utf-8");
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Read one doc as raw bytes, or undefined when it does not exist. Same
|
|
89
|
-
* traversal validation as {@link read}, but no text decoding — the admin
|
|
90
|
-
* API uses this to serve binary artifacts (e.g. PNG screenshot evidence)
|
|
91
|
-
* intact, since `read()`'s utf-8 decode corrupts binary content.
|
|
92
|
-
*/
|
|
93
|
-
readBuffer(ref, file) {
|
|
94
|
-
const path = this.fileFor(ref, file);
|
|
95
|
-
if (!existsSync(path))
|
|
96
|
-
return undefined;
|
|
97
|
-
return readFileSync(path);
|
|
98
|
-
}
|
|
99
|
-
/** Write (create or overwrite) one doc, creating the run dir as needed. */
|
|
100
|
-
write(ref, file, content) {
|
|
101
|
-
const path = this.fileFor(ref, file);
|
|
102
|
-
mkdirSync(this.dirFor(ref), { recursive: true });
|
|
103
|
-
writeFileSync(path, content);
|
|
104
|
-
}
|
|
105
|
-
/** List the `<owner>/<repo>` run keys present in the store (issueKeys). */
|
|
106
|
-
listKeys(owner, repo) {
|
|
107
|
-
assertSafeSegment(owner, "owner");
|
|
108
|
-
assertSafeSegment(repo, "repo");
|
|
109
|
-
const dir = join(this.root, owner, repo);
|
|
110
|
-
if (!isInside(this.root, dir) || !existsSync(dir))
|
|
111
|
-
return [];
|
|
112
|
-
return readdirSync(dir, { withFileTypes: true })
|
|
113
|
-
.filter((e) => e.isDirectory())
|
|
114
|
-
.map((e) => e.name)
|
|
115
|
-
.sort();
|
|
116
|
-
}
|
|
117
|
-
/** List the doc filenames stored for one run. */
|
|
118
|
-
listFiles(ref) {
|
|
119
|
-
const dir = this.dirFor(ref);
|
|
120
|
-
if (!existsSync(dir))
|
|
121
|
-
return [];
|
|
122
|
-
return readdirSync(dir, { withFileTypes: true })
|
|
123
|
-
.filter((e) => e.isFile())
|
|
124
|
-
.map((e) => e.name)
|
|
125
|
-
.sort();
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Stage the run's stored docs into `localDir` (created fresh) so a sandbox
|
|
129
|
-
* phase reads prior-phase context. A no-op-with-empty-dir when nothing is
|
|
130
|
-
* stored yet — the first phase starts from a clean slate, identical to repo
|
|
131
|
-
* mode's empty `.lastlight/<issueKey>/`.
|
|
132
|
-
*/
|
|
133
|
-
stageInto(ref, localDir) {
|
|
134
|
-
mkdirSync(localDir, { recursive: true });
|
|
135
|
-
const src = this.dirFor(ref);
|
|
136
|
-
if (!existsSync(src))
|
|
137
|
-
return;
|
|
138
|
-
cpSync(src, localDir, { recursive: true });
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Harvest docs written by a phase back into the store, replacing the stored
|
|
142
|
-
* set with whatever the phase left in `localDir`. Last-harvest-wins; the
|
|
143
|
-
* runner is sequential per workspace so there is no concurrent writer.
|
|
144
|
-
*/
|
|
145
|
-
harvestFrom(ref, localDir) {
|
|
146
|
-
if (!existsSync(localDir) || !statSync(localDir).isDirectory())
|
|
147
|
-
return;
|
|
148
|
-
const dest = this.dirFor(ref);
|
|
149
|
-
rmSync(dest, { recursive: true, force: true });
|
|
150
|
-
mkdirSync(dest, { recursive: true });
|
|
151
|
-
cpSync(localDir, dest, { recursive: true });
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
//# sourceMappingURL=build-assets.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-assets.js","sourceRoot":"","sources":["../../src/state/build-assets.ts"],"names":[],"mappings":"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"}
|
package/dist/state/db.d.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import Database from "better-sqlite3";
|
|
2
|
-
import { ExecutionStore } from "./execution-store.js";
|
|
3
|
-
import { ApprovalStore } from "./approval-store.js";
|
|
4
|
-
import { WorkflowRunStore } from "./workflow-run-store.js";
|
|
5
|
-
export type { ExecutionRecord } from "./execution-store.js";
|
|
6
|
-
export type { WorkflowApproval } from "./approval-store.js";
|
|
7
|
-
export type { WorkflowRun, PhaseHistoryEntry, PhaseMarker } from "./workflow-run-store.js";
|
|
8
|
-
export { ExecutionStore } from "./execution-store.js";
|
|
9
|
-
export { ApprovalStore } from "./approval-store.js";
|
|
10
|
-
export { WorkflowRunStore } from "./workflow-run-store.js";
|
|
11
|
-
export interface CronOverride {
|
|
12
|
-
name: string;
|
|
13
|
-
enabled: boolean;
|
|
14
|
-
/** Cron expression overriding the YAML default; null means use the YAML value. */
|
|
15
|
-
schedule: string | null;
|
|
16
|
-
updatedAt: string;
|
|
17
|
-
updatedBy: string | null;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Per-workflow kill switch persisted to SQLite. When `enabled` is false,
|
|
21
|
-
* `runSimpleWorkflow` short-circuits and does not create a `workflow_runs`
|
|
22
|
-
* row — applies to every trigger source (cron, webhooks, mentions, Slack).
|
|
23
|
-
* No row at all means "enabled" (default).
|
|
24
|
-
*/
|
|
25
|
-
export interface WorkflowOverride {
|
|
26
|
-
name: string;
|
|
27
|
-
enabled: boolean;
|
|
28
|
-
updatedAt: string;
|
|
29
|
-
updatedBy: string | null;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Lightweight SQLite state for operational tracking.
|
|
33
|
-
* NOT for conversation history — only execution logs and rate limits.
|
|
34
|
-
*
|
|
35
|
-
* Construction root for the three per-table stores (issue #97): it opens the
|
|
36
|
-
* single `Database` connection, runs {@link migrate}, and builds
|
|
37
|
-
* {@link ExecutionStore} / {@link ApprovalStore} / {@link WorkflowRunStore} on
|
|
38
|
-
* top of it (all sharing the one connection so better-sqlite3 transactions
|
|
39
|
-
* span every store). Callers reach the stores via `db.runs` / `db.approvals` /
|
|
40
|
-
* `db.executions`. StateDb itself retains only the cross-cutting cron-override
|
|
41
|
-
* and workflow kill-switch concerns.
|
|
42
|
-
*/
|
|
43
|
-
export declare class StateDb {
|
|
44
|
-
private db;
|
|
45
|
-
/** Owns the `executions` ledger. */
|
|
46
|
-
readonly executions: ExecutionStore;
|
|
47
|
-
/** Owns the `workflow_approvals` table. */
|
|
48
|
-
readonly approvals: ApprovalStore;
|
|
49
|
-
/** Aggregate root for `workflow_runs` + the atomic lifecycle operations. */
|
|
50
|
-
readonly runs: WorkflowRunStore;
|
|
51
|
-
constructor(dbPath?: string);
|
|
52
|
-
/** Get the override row for a single cron, or null if none. */
|
|
53
|
-
getCronOverride(name: string): CronOverride | null;
|
|
54
|
-
/** All override rows keyed by cron name. */
|
|
55
|
-
getAllCronOverrides(): Map<string, CronOverride>;
|
|
56
|
-
/**
|
|
57
|
-
* Upsert an override. Pass only the fields you want to change — undefined
|
|
58
|
-
* fields preserve the existing value (or default to enabled=1, schedule=null
|
|
59
|
-
* on insert).
|
|
60
|
-
*/
|
|
61
|
-
setCronOverride(name: string, patch: {
|
|
62
|
-
enabled?: boolean;
|
|
63
|
-
schedule?: string | null;
|
|
64
|
-
updatedBy?: string;
|
|
65
|
-
}): void;
|
|
66
|
-
/** Remove the override entirely (revert to YAML defaults). */
|
|
67
|
-
clearCronOverride(name: string): void;
|
|
68
|
-
private deserializeCronOverride;
|
|
69
|
-
/**
|
|
70
|
-
* Cheap check used by every dispatch path. Returns true unless an explicit
|
|
71
|
-
* `workflow_overrides` row says otherwise.
|
|
72
|
-
*/
|
|
73
|
-
isWorkflowEnabled(name: string): boolean;
|
|
74
|
-
getWorkflowOverride(name: string): WorkflowOverride | null;
|
|
75
|
-
getAllWorkflowOverrides(): Map<string, WorkflowOverride>;
|
|
76
|
-
setWorkflowEnabled(name: string, enabled: boolean, updatedBy?: string): void;
|
|
77
|
-
private deserializeWorkflowOverride;
|
|
78
|
-
/** Expose the underlying Database instance (for SessionManager, etc.) */
|
|
79
|
-
get database(): Database.Database;
|
|
80
|
-
close(): void;
|
|
81
|
-
}
|
package/dist/state/db.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import Database from "better-sqlite3";
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
import { migrate } from "./migrate.js";
|
|
4
|
-
import { ExecutionStore } from "./execution-store.js";
|
|
5
|
-
import { ApprovalStore } from "./approval-store.js";
|
|
6
|
-
import { WorkflowRunStore } from "./workflow-run-store.js";
|
|
7
|
-
export { ExecutionStore } from "./execution-store.js";
|
|
8
|
-
export { ApprovalStore } from "./approval-store.js";
|
|
9
|
-
export { WorkflowRunStore } from "./workflow-run-store.js";
|
|
10
|
-
const DEFAULT_DB_PATH = "lastlight.db";
|
|
11
|
-
/**
|
|
12
|
-
* Lightweight SQLite state for operational tracking.
|
|
13
|
-
* NOT for conversation history — only execution logs and rate limits.
|
|
14
|
-
*
|
|
15
|
-
* Construction root for the three per-table stores (issue #97): it opens the
|
|
16
|
-
* single `Database` connection, runs {@link migrate}, and builds
|
|
17
|
-
* {@link ExecutionStore} / {@link ApprovalStore} / {@link WorkflowRunStore} on
|
|
18
|
-
* top of it (all sharing the one connection so better-sqlite3 transactions
|
|
19
|
-
* span every store). Callers reach the stores via `db.runs` / `db.approvals` /
|
|
20
|
-
* `db.executions`. StateDb itself retains only the cross-cutting cron-override
|
|
21
|
-
* and workflow kill-switch concerns.
|
|
22
|
-
*/
|
|
23
|
-
export class StateDb {
|
|
24
|
-
db;
|
|
25
|
-
/** Owns the `executions` ledger. */
|
|
26
|
-
executions;
|
|
27
|
-
/** Owns the `workflow_approvals` table. */
|
|
28
|
-
approvals;
|
|
29
|
-
/** Aggregate root for `workflow_runs` + the atomic lifecycle operations. */
|
|
30
|
-
runs;
|
|
31
|
-
constructor(dbPath) {
|
|
32
|
-
// ":memory:" stays a real per-connection in-memory DB (used by tests for
|
|
33
|
-
// isolation) — only filesystem paths go through resolve(). Previously
|
|
34
|
-
// resolve(":memory:") produced a shared on-disk file named ":memory:",
|
|
35
|
-
// which let parallel test files contend on one DB and deadlock once the
|
|
36
|
-
// stores started holding write transactions.
|
|
37
|
-
const target = dbPath === ":memory:" ? ":memory:" : resolve(dbPath || DEFAULT_DB_PATH);
|
|
38
|
-
this.db = new Database(target);
|
|
39
|
-
this.db.pragma("journal_mode = WAL");
|
|
40
|
-
migrate(this.db);
|
|
41
|
-
this.executions = new ExecutionStore(this.db);
|
|
42
|
-
this.approvals = new ApprovalStore(this.db);
|
|
43
|
-
this.runs = new WorkflowRunStore(this.db, { approvals: this.approvals });
|
|
44
|
-
}
|
|
45
|
-
// ── Cron overrides ─────────────────────────────────────────────
|
|
46
|
-
/** Get the override row for a single cron, or null if none. */
|
|
47
|
-
getCronOverride(name) {
|
|
48
|
-
const row = this.db
|
|
49
|
-
.prepare(`SELECT name, enabled, schedule, updated_at, updated_by FROM cron_overrides WHERE name = ?`)
|
|
50
|
-
.get(name);
|
|
51
|
-
return row ? this.deserializeCronOverride(row) : null;
|
|
52
|
-
}
|
|
53
|
-
/** All override rows keyed by cron name. */
|
|
54
|
-
getAllCronOverrides() {
|
|
55
|
-
const rows = this.db
|
|
56
|
-
.prepare(`SELECT name, enabled, schedule, updated_at, updated_by FROM cron_overrides`)
|
|
57
|
-
.all();
|
|
58
|
-
const map = new Map();
|
|
59
|
-
for (const row of rows) {
|
|
60
|
-
const o = this.deserializeCronOverride(row);
|
|
61
|
-
map.set(o.name, o);
|
|
62
|
-
}
|
|
63
|
-
return map;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Upsert an override. Pass only the fields you want to change — undefined
|
|
67
|
-
* fields preserve the existing value (or default to enabled=1, schedule=null
|
|
68
|
-
* on insert).
|
|
69
|
-
*/
|
|
70
|
-
setCronOverride(name, patch) {
|
|
71
|
-
const now = new Date().toISOString();
|
|
72
|
-
const existing = this.getCronOverride(name);
|
|
73
|
-
const enabled = patch.enabled ?? existing?.enabled ?? true;
|
|
74
|
-
const schedule = patch.schedule === undefined ? existing?.schedule ?? null : patch.schedule;
|
|
75
|
-
this.db
|
|
76
|
-
.prepare(`INSERT INTO cron_overrides (name, enabled, schedule, updated_at, updated_by)
|
|
77
|
-
VALUES (?, ?, ?, ?, ?)
|
|
78
|
-
ON CONFLICT(name) DO UPDATE SET
|
|
79
|
-
enabled = excluded.enabled,
|
|
80
|
-
schedule = excluded.schedule,
|
|
81
|
-
updated_at = excluded.updated_at,
|
|
82
|
-
updated_by = excluded.updated_by`)
|
|
83
|
-
.run(name, enabled ? 1 : 0, schedule, now, patch.updatedBy ?? null);
|
|
84
|
-
}
|
|
85
|
-
/** Remove the override entirely (revert to YAML defaults). */
|
|
86
|
-
clearCronOverride(name) {
|
|
87
|
-
this.db.prepare(`DELETE FROM cron_overrides WHERE name = ?`).run(name);
|
|
88
|
-
}
|
|
89
|
-
deserializeCronOverride(row) {
|
|
90
|
-
return {
|
|
91
|
-
name: row.name,
|
|
92
|
-
enabled: row.enabled === 1,
|
|
93
|
-
schedule: row.schedule ?? null,
|
|
94
|
-
updatedAt: row.updated_at,
|
|
95
|
-
updatedBy: row.updated_by ?? null,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
// ── Workflow overrides (kill switch) ───────────────────────────
|
|
99
|
-
/**
|
|
100
|
-
* Cheap check used by every dispatch path. Returns true unless an explicit
|
|
101
|
-
* `workflow_overrides` row says otherwise.
|
|
102
|
-
*/
|
|
103
|
-
isWorkflowEnabled(name) {
|
|
104
|
-
const row = this.db
|
|
105
|
-
.prepare(`SELECT enabled FROM workflow_overrides WHERE name = ?`)
|
|
106
|
-
.get(name);
|
|
107
|
-
if (!row)
|
|
108
|
-
return true;
|
|
109
|
-
return row.enabled === 1;
|
|
110
|
-
}
|
|
111
|
-
getWorkflowOverride(name) {
|
|
112
|
-
const row = this.db
|
|
113
|
-
.prepare(`SELECT name, enabled, updated_at, updated_by FROM workflow_overrides WHERE name = ?`)
|
|
114
|
-
.get(name);
|
|
115
|
-
return row ? this.deserializeWorkflowOverride(row) : null;
|
|
116
|
-
}
|
|
117
|
-
getAllWorkflowOverrides() {
|
|
118
|
-
const rows = this.db
|
|
119
|
-
.prepare(`SELECT name, enabled, updated_at, updated_by FROM workflow_overrides`)
|
|
120
|
-
.all();
|
|
121
|
-
const map = new Map();
|
|
122
|
-
for (const row of rows) {
|
|
123
|
-
const o = this.deserializeWorkflowOverride(row);
|
|
124
|
-
map.set(o.name, o);
|
|
125
|
-
}
|
|
126
|
-
return map;
|
|
127
|
-
}
|
|
128
|
-
setWorkflowEnabled(name, enabled, updatedBy) {
|
|
129
|
-
const now = new Date().toISOString();
|
|
130
|
-
this.db
|
|
131
|
-
.prepare(`INSERT INTO workflow_overrides (name, enabled, updated_at, updated_by)
|
|
132
|
-
VALUES (?, ?, ?, ?)
|
|
133
|
-
ON CONFLICT(name) DO UPDATE SET
|
|
134
|
-
enabled = excluded.enabled,
|
|
135
|
-
updated_at = excluded.updated_at,
|
|
136
|
-
updated_by = excluded.updated_by`)
|
|
137
|
-
.run(name, enabled ? 1 : 0, now, updatedBy ?? null);
|
|
138
|
-
}
|
|
139
|
-
deserializeWorkflowOverride(row) {
|
|
140
|
-
return {
|
|
141
|
-
name: row.name,
|
|
142
|
-
enabled: row.enabled === 1,
|
|
143
|
-
updatedAt: row.updated_at,
|
|
144
|
-
updatedBy: row.updated_by ?? null,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
/** Expose the underlying Database instance (for SessionManager, etc.) */
|
|
148
|
-
get database() {
|
|
149
|
-
return this.db;
|
|
150
|
-
}
|
|
151
|
-
close() {
|
|
152
|
-
this.db.close();
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
//# sourceMappingURL=db.js.map
|
package/dist/state/db.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/state/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
import type Database from "better-sqlite3";
|
|
2
|
-
export interface ExecutionRecord {
|
|
3
|
-
id: string;
|
|
4
|
-
triggerType: "webhook" | "cron" | "chat" | "api";
|
|
5
|
-
triggerId: string;
|
|
6
|
-
skill: string;
|
|
7
|
-
repo?: string;
|
|
8
|
-
issueNumber?: number;
|
|
9
|
-
startedAt: string;
|
|
10
|
-
finishedAt?: string;
|
|
11
|
-
success?: boolean;
|
|
12
|
-
error?: string;
|
|
13
|
-
turns?: number;
|
|
14
|
-
durationMs?: number;
|
|
15
|
-
/**
|
|
16
|
-
* Runtime session id (OpenCode `ses_…`) captured from the event stream.
|
|
17
|
-
* Used by the dashboard to look up the session log for a given phase.
|
|
18
|
-
*/
|
|
19
|
-
sessionId?: string;
|
|
20
|
-
/** Total USD cost reported by the runtime on the final step. Zero under OAuth/subscription auth. */
|
|
21
|
-
costUsd?: number;
|
|
22
|
-
/** Fresh input tokens (no cache hit). */
|
|
23
|
-
inputTokens?: number;
|
|
24
|
-
/** Tokens that triggered a cache write. */
|
|
25
|
-
cacheCreationInputTokens?: number;
|
|
26
|
-
/** Tokens served from prompt cache. */
|
|
27
|
-
cacheReadInputTokens?: number;
|
|
28
|
-
/** Output tokens generated by the model. */
|
|
29
|
-
outputTokens?: number;
|
|
30
|
-
/** API-side duration (excludes orchestrator overhead). */
|
|
31
|
-
apiDurationMs?: number;
|
|
32
|
-
/** Result subtype, e.g. "success" or "error_max_turns". */
|
|
33
|
-
stopReason?: string;
|
|
34
|
-
/**
|
|
35
|
-
* JSON-serialized {@link ExtensionStatusMap} — which agentic-pi extensions
|
|
36
|
-
* (file-search / github / web-search) were active for this execution.
|
|
37
|
-
*/
|
|
38
|
-
extensionStatus?: string;
|
|
39
|
-
/**
|
|
40
|
-
* JSON-serialized {@link SkillsStatus} — agentic-pi's skill-loading status
|
|
41
|
-
* for this execution (which skills were discovered/available). Null when
|
|
42
|
-
* the run reported no skills.
|
|
43
|
-
*/
|
|
44
|
-
skillsStatus?: string;
|
|
45
|
-
/**
|
|
46
|
-
* Workflow run that owns this execution. Scopes dedup: a fresh re-trigger
|
|
47
|
-
* creates a new workflow_run_id, so `shouldRunPhase` won't find matching
|
|
48
|
-
* rows from the prior run and will correctly run the phase again.
|
|
49
|
-
*/
|
|
50
|
-
workflowRunId?: string;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Owns every read/write against the `executions` table — the harness's
|
|
54
|
-
* append-only ledger of agent runs. The dashboard derives phase status from
|
|
55
|
-
* this table (primary source, ahead of the `phase_history` fallback), and the
|
|
56
|
-
* runner's resume path skips already-completed phases via {@link shouldRunPhase}.
|
|
57
|
-
*
|
|
58
|
-
* Carved out of the old `StateDb` god-class (issue #97). Constructed from the
|
|
59
|
-
* single shared `Database` so it sits in the same connection / transaction
|
|
60
|
-
* scope as the other stores.
|
|
61
|
-
*/
|
|
62
|
-
export declare class ExecutionStore {
|
|
63
|
-
private db;
|
|
64
|
-
constructor(db: Database.Database);
|
|
65
|
-
recordStart(record: Omit<ExecutionRecord, "finishedAt" | "success" | "error" | "turns" | "durationMs">): void;
|
|
66
|
-
/**
|
|
67
|
-
* Mid-run update: persist the agent session id as soon as the executor sees
|
|
68
|
-
* the stream-json `system/init` line. Lets the dashboard surface the live
|
|
69
|
-
* session log for an in-flight phase, not just for completed ones.
|
|
70
|
-
*/
|
|
71
|
-
recordSessionId(id: string, sessionId: string): void;
|
|
72
|
-
/**
|
|
73
|
-
* Persist the final assistant text for a loop-iteration execution.
|
|
74
|
-
* Used by the runner when a scratch slot would otherwise inline the
|
|
75
|
-
* full LLM output into `workflow_runs.scratch` — the scratch entry
|
|
76
|
-
* stores `lastOutputExecutionId` and resolves the text through
|
|
77
|
-
* `getExecutionOutput` on read.
|
|
78
|
-
*/
|
|
79
|
-
recordOutputText(id: string, output: string): void;
|
|
80
|
-
/** Read the persisted output text for an execution, or null if none. */
|
|
81
|
-
getExecutionOutput(id: string): string | null;
|
|
82
|
-
/**
|
|
83
|
-
* Most recent finished execution's `output_text` for a phase (`skill`), or
|
|
84
|
-
* null. Used by the reviewer loop on resume to re-derive a completed review's
|
|
85
|
-
* verdict from its persisted output (a dedup-`done` review must not be
|
|
86
|
-
* assumed APPROVED — it may have requested changes).
|
|
87
|
-
*/
|
|
88
|
-
getPhaseOutput(skill: string, triggerId: string, workflowRunId?: string): string | null;
|
|
89
|
-
recordFinish(id: string, result: {
|
|
90
|
-
success: boolean;
|
|
91
|
-
error?: string;
|
|
92
|
-
turns?: number;
|
|
93
|
-
durationMs?: number;
|
|
94
|
-
sessionId?: string;
|
|
95
|
-
costUsd?: number;
|
|
96
|
-
inputTokens?: number;
|
|
97
|
-
cacheCreationInputTokens?: number;
|
|
98
|
-
cacheReadInputTokens?: number;
|
|
99
|
-
outputTokens?: number;
|
|
100
|
-
apiDurationMs?: number;
|
|
101
|
-
stopReason?: string;
|
|
102
|
-
/** JSON-serialized ExtensionStatusMap (extensions active this run). */
|
|
103
|
-
extensionStatus?: string;
|
|
104
|
-
/** JSON-serialized SkillsStatus (skills available this run). */
|
|
105
|
-
skillsStatus?: string;
|
|
106
|
-
}): void;
|
|
107
|
-
/**
|
|
108
|
-
* Record a phase that the scheduler skipped because its trigger rule was
|
|
109
|
-
* not satisfied (a failed/skipped upstream cascaded down a chain). The
|
|
110
|
-
* executions ledger is the single source of truth the dashboard derives
|
|
111
|
-
* phase status from, so skips are written here too — as a finished,
|
|
112
|
-
* non-successful row (`success = 0`, `stop_reason = 'skipped'`). Because it
|
|
113
|
-
* is not `success = 1`, `shouldRunPhase` re-evaluates it on resume (the node
|
|
114
|
-
* will simply be re-skipped if the upstream is still failed).
|
|
115
|
-
*/
|
|
116
|
-
recordSkippedPhase(skill: string, triggerId: string, workflowRunId?: string, repo?: string): void;
|
|
117
|
-
/**
|
|
118
|
-
* List chat threads aggregated from the executions table.
|
|
119
|
-
*
|
|
120
|
-
* Each row collapses every execution sharing a `trigger_id` (the messaging
|
|
121
|
-
* session id) into one summary so the dashboard's chat-sessions tab can
|
|
122
|
-
* show one card per Slack thread, not one per turn. Joined with
|
|
123
|
-
* `messaging_sessions` for the agent SDK session id (used to resolve to
|
|
124
|
-
* the on-disk jsonl when streaming messages) and with `messaging_messages`
|
|
125
|
-
* for the most recent assistant text (preview snippet).
|
|
126
|
-
*/
|
|
127
|
-
listChatThreads(limit: number): {
|
|
128
|
-
triggerId: string;
|
|
129
|
-
agentSessionId: string | null;
|
|
130
|
-
platform: string | null;
|
|
131
|
-
firstStartedAt: string;
|
|
132
|
-
lastActivityAt: string;
|
|
133
|
-
turnCount: number;
|
|
134
|
-
totalCost: number;
|
|
135
|
-
inputTokens: number;
|
|
136
|
-
outputTokens: number;
|
|
137
|
-
cacheReadTokens: number;
|
|
138
|
-
lastAssistantContent: string | null;
|
|
139
|
-
}[];
|
|
140
|
-
/** Look up a single chat thread by its messaging session id (= trigger_id). */
|
|
141
|
-
getChatThread(triggerId: string): {
|
|
142
|
-
triggerId: string;
|
|
143
|
-
agentSessionId: string | null;
|
|
144
|
-
platform: string | null;
|
|
145
|
-
firstStartedAt: string;
|
|
146
|
-
lastActivityAt: string;
|
|
147
|
-
turnCount: number;
|
|
148
|
-
totalCost: number;
|
|
149
|
-
inputTokens: number;
|
|
150
|
-
outputTokens: number;
|
|
151
|
-
cacheReadTokens: number;
|
|
152
|
-
lastAssistantContent: string | null;
|
|
153
|
-
} | null;
|
|
154
|
-
/** Check if a skill is currently running for a given trigger */
|
|
155
|
-
isRunning(skill: string, triggerId: string): boolean;
|
|
156
|
-
/** Check if a skill has already completed successfully for a given trigger */
|
|
157
|
-
isCompleted(skill: string, triggerId: string): boolean;
|
|
158
|
-
/**
|
|
159
|
-
* Check if a phase should run: not currently running AND not already
|
|
160
|
-
* succeeded. When `workflowRunId` is provided, scopes the check to that
|
|
161
|
-
* specific run — a fresh re-trigger (new workflow_run_id) will see no
|
|
162
|
-
* matching rows and correctly return "run" even if a prior completed run
|
|
163
|
-
* for the same trigger exists. Omit `workflowRunId` for legacy callers
|
|
164
|
-
* (e.g. chat/status-report dedup) that want the old trigger-wide scope.
|
|
165
|
-
*/
|
|
166
|
-
shouldRunPhase(skill: string, triggerId: string, workflowRunId?: string): "run" | "running" | "done";
|
|
167
|
-
/** Mark all stale "running" executions for a skill/trigger as failed.
|
|
168
|
-
* Called when we detect no matching Docker container is alive. */
|
|
169
|
-
markStaleAsFailed(skill: string, triggerId: string, workflowRunId?: string): number;
|
|
170
|
-
/**
|
|
171
|
-
* Mark every unfinished execution row for a trigger as failed, regardless
|
|
172
|
-
* of skill. Used by the boot-time recovery sweep to clear out phases that
|
|
173
|
-
* were running when the harness crashed/restarted, so the runner's dedup
|
|
174
|
-
* logic doesn't think they're still in flight.
|
|
175
|
-
*/
|
|
176
|
-
markAllStaleForTrigger(triggerId: string, reason: string): number;
|
|
177
|
-
/**
|
|
178
|
-
* Mark the most recent execution for a skill/trigger as failed.
|
|
179
|
-
* Used when the agent SDK reported success but the orchestrator decided
|
|
180
|
-
* the business outcome was a failure (e.g. guardrails BLOCKED, reviewer
|
|
181
|
-
* REQUEST_CHANGES). Without this, runPhase would skip the phase on the
|
|
182
|
-
* next run because the DB still says success=1.
|
|
183
|
-
*/
|
|
184
|
-
markLatestAsFailed(skill: string, triggerId: string, reason: string, workflowRunId?: string): number;
|
|
185
|
-
/** Get recent executions for a skill */
|
|
186
|
-
recentExecutions(skill: string, limit?: number): ExecutionRecord[];
|
|
187
|
-
/** Count consecutive failures for a skill (for cron failure tracking) */
|
|
188
|
-
consecutiveFailures(skill: string): number;
|
|
189
|
-
/** Get all executions with pagination */
|
|
190
|
-
allExecutions(limit?: number, offset?: number): ExecutionRecord[];
|
|
191
|
-
/**
|
|
192
|
-
* Free-text search across the `executions` ledger — matches `error`, `skill`,
|
|
193
|
-
* or `repo` against a substring (case-insensitive via SQLite's LIKE). Used by
|
|
194
|
-
* the `/admin/api/log-search` endpoint and the `lastlight logs search` CLI to
|
|
195
|
-
* find failing/relevant phases without SSHing to the box. Parameterized; the
|
|
196
|
-
* pattern is escaped so user input can't smuggle LIKE wildcards.
|
|
197
|
-
*/
|
|
198
|
-
searchErrors(query: string, limit?: number): Array<{
|
|
199
|
-
id: string;
|
|
200
|
-
skill: string;
|
|
201
|
-
repo?: string;
|
|
202
|
-
error?: string;
|
|
203
|
-
success?: boolean;
|
|
204
|
-
startedAt: string;
|
|
205
|
-
finishedAt?: string;
|
|
206
|
-
sessionId?: string;
|
|
207
|
-
workflowRunId?: string;
|
|
208
|
-
triggerId: string;
|
|
209
|
-
}>;
|
|
210
|
-
/**
|
|
211
|
-
* Get every execution recorded for a workflow run, with camelCase fields
|
|
212
|
-
* ready for the dashboard. Ordered by start time ascending so phases
|
|
213
|
-
* display in the order they ran. Scopes to a specific `workflow_run_id`
|
|
214
|
-
* when provided (preferred — isolates fresh re-triggers from prior runs);
|
|
215
|
-
* falls back to the legacy trigger-wide scope for rows written before the
|
|
216
|
-
* workflow_run_id column existed.
|
|
217
|
-
*/
|
|
218
|
-
getExecutionsForWorkflowRun(workflowRunId: string, triggerId: string, workflowName?: string): ExecutionRecord[];
|
|
219
|
-
/** Get currently running executions (no finished_at) */
|
|
220
|
-
runningExecutions(): ExecutionRecord[];
|
|
221
|
-
/** Aggregate execution stats */
|
|
222
|
-
executionStats(): {
|
|
223
|
-
total_executions: number;
|
|
224
|
-
today_count: number;
|
|
225
|
-
by_skill: Record<string, {
|
|
226
|
-
count: number;
|
|
227
|
-
success: number;
|
|
228
|
-
fail: number;
|
|
229
|
-
}>;
|
|
230
|
-
by_trigger: Record<string, number>;
|
|
231
|
-
running: number;
|
|
232
|
-
};
|
|
233
|
-
/** Daily aggregated stats for the last N days */
|
|
234
|
-
dailyStats(days: number): {
|
|
235
|
-
date: string;
|
|
236
|
-
executions: number;
|
|
237
|
-
successes: number;
|
|
238
|
-
failures: number;
|
|
239
|
-
totalTokens: number;
|
|
240
|
-
inputTokens: number;
|
|
241
|
-
outputTokens: number;
|
|
242
|
-
cacheReadTokens: number;
|
|
243
|
-
costUsd: number;
|
|
244
|
-
}[];
|
|
245
|
-
/** Hourly aggregated stats for the last N hours (UTC). Bucket key is `YYYY-MM-DDTHH`. */
|
|
246
|
-
hourlyStats(hours: number): {
|
|
247
|
-
date: string;
|
|
248
|
-
executions: number;
|
|
249
|
-
successes: number;
|
|
250
|
-
failures: number;
|
|
251
|
-
totalTokens: number;
|
|
252
|
-
inputTokens: number;
|
|
253
|
-
outputTokens: number;
|
|
254
|
-
cacheReadTokens: number;
|
|
255
|
-
costUsd: number;
|
|
256
|
-
}[];
|
|
257
|
-
}
|