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,321 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
import { Hono } from "hono";
|
|
3
|
-
import { createHmac, timingSafeEqual } from "crypto";
|
|
4
|
-
import { isManagedRepo, setInstallationRepos, addInstallationRepos, removeInstallationRepos, } from "../managed-repos.js";
|
|
5
|
-
/**
|
|
6
|
-
* GitHub webhook actions we skip — these are noisy and never need agent work.
|
|
7
|
-
*
|
|
8
|
-
* NOTE: `synchronize` is intentionally NOT in this set. It fires on every new
|
|
9
|
-
* commit pushed to a PR's branch and is the canonical "needs a fresh review"
|
|
10
|
-
* trigger — without it, branch protection requiring `last-light/review`
|
|
11
|
-
* would block merges after a REQUEST_CHANGES + fix-commit cycle (the new
|
|
12
|
-
* SHA would never get a check posted against it). The handler maps it to
|
|
13
|
-
* `pr.synchronize` and routes to pr-review.
|
|
14
|
-
*/
|
|
15
|
-
const IGNORED_ACTIONS = new Set([
|
|
16
|
-
"deleted",
|
|
17
|
-
"edited",
|
|
18
|
-
"labeled",
|
|
19
|
-
"unlabeled",
|
|
20
|
-
"assigned",
|
|
21
|
-
"unassigned",
|
|
22
|
-
"closed",
|
|
23
|
-
"milestoned",
|
|
24
|
-
"demilestoned",
|
|
25
|
-
"locked",
|
|
26
|
-
"unlocked",
|
|
27
|
-
"transferred",
|
|
28
|
-
"pinned",
|
|
29
|
-
"unpinned",
|
|
30
|
-
]);
|
|
31
|
-
export class GitHubWebhookConnector extends EventEmitter {
|
|
32
|
-
name = "github";
|
|
33
|
-
app;
|
|
34
|
-
config;
|
|
35
|
-
constructor(config) {
|
|
36
|
-
super();
|
|
37
|
-
this.config = config;
|
|
38
|
-
// Register onto the shared app when given one; otherwise self-create (tests).
|
|
39
|
-
this.app = config.app ?? new Hono();
|
|
40
|
-
this.setupRoutes();
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Expose the Hono app so the main server can mount additional routes
|
|
44
|
-
* (e.g., /api/run for the CLI trigger).
|
|
45
|
-
*/
|
|
46
|
-
get honoApp() {
|
|
47
|
-
return this.app;
|
|
48
|
-
}
|
|
49
|
-
setupRoutes() {
|
|
50
|
-
// GitHub webhook endpoint. (`/health` is owned by main()'s shared app so it
|
|
51
|
-
// exists in chat-only mode too — see src/index.ts.)
|
|
52
|
-
this.app.post("/webhooks/github", async (c) => {
|
|
53
|
-
const body = await c.req.text();
|
|
54
|
-
// Verify webhook signature
|
|
55
|
-
const signature = c.req.header("x-hub-signature-256");
|
|
56
|
-
if (!signature || !this.verifySignature(body, signature)) {
|
|
57
|
-
return c.json({ error: "Invalid signature" }, 401);
|
|
58
|
-
}
|
|
59
|
-
const eventType = c.req.header("x-github-event");
|
|
60
|
-
const deliveryId = c.req.header("x-github-delivery") || crypto.randomUUID();
|
|
61
|
-
let payload;
|
|
62
|
-
try {
|
|
63
|
-
payload = JSON.parse(body);
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
return c.json({ error: "Invalid JSON" }, 400);
|
|
67
|
-
}
|
|
68
|
-
const action = payload.action;
|
|
69
|
-
// Keep the discovered installation-repo list live. These events carry no
|
|
70
|
-
// `payload.repository` (they're app-wide) and `installation`/`deleted`
|
|
71
|
-
// would otherwise be dropped by IGNORED_ACTIONS below — so handle them
|
|
72
|
-
// first, before any action/repo filtering. Signature is already verified.
|
|
73
|
-
if (eventType === "installation" || eventType === "installation_repositories") {
|
|
74
|
-
this.handleInstallationEvent(eventType, action, payload);
|
|
75
|
-
return c.json({ accepted: true, kind: "installation-sync" }, 200);
|
|
76
|
-
}
|
|
77
|
-
// Filter out ignored actions
|
|
78
|
-
if (action && IGNORED_ACTIONS.has(action)) {
|
|
79
|
-
return c.json({ filtered: true, reason: `action=${action}` }, 200);
|
|
80
|
-
}
|
|
81
|
-
// Filter out bot events (self-loop prevention).
|
|
82
|
-
//
|
|
83
|
-
// Exception: `pull_request` opened/synchronize/reopened from a bot
|
|
84
|
-
// sender must still flow through. A bot opening its own PR or
|
|
85
|
-
// pushing a fix commit is the canonical "needs a fresh review"
|
|
86
|
-
// signal — without this exception, a REQUEST_CHANGES verdict on a
|
|
87
|
-
// bot-authored PR followed by a fix commit would be invisible to
|
|
88
|
-
// the harness, leaving branch protection (which requires a check
|
|
89
|
-
// on the latest SHA) permanently blocked.
|
|
90
|
-
//
|
|
91
|
-
// Loop risk on this exception is low: pr-review posts a PR Review
|
|
92
|
-
// (`pr_review.submitted`, currently unrouted) and a Check Run
|
|
93
|
-
// (`check_run.completed`, no event type at all here) — nothing the
|
|
94
|
-
// agent acts on. Comment/issue paths still keep the strict filter
|
|
95
|
-
// to avoid the bot replying to its own comments.
|
|
96
|
-
const senderLogin = payload.sender?.login || "";
|
|
97
|
-
const senderType = payload.sender?.type || "";
|
|
98
|
-
const isBotSender = senderType === "Bot" ||
|
|
99
|
-
senderLogin === this.config.botLogin ||
|
|
100
|
-
senderLogin.endsWith("[bot]");
|
|
101
|
-
const isPrAttention = eventType === "pull_request" &&
|
|
102
|
-
(action === "opened" || action === "synchronize" || action === "reopened");
|
|
103
|
-
if (isBotSender && !isPrAttention) {
|
|
104
|
-
return c.json({ filtered: true, reason: "bot sender" }, 200);
|
|
105
|
-
}
|
|
106
|
-
// Never review a PR the bot itself authored. The pr-attention exception
|
|
107
|
-
// above deliberately lets bot *senders* through (a bot fix-commit on a
|
|
108
|
-
// human's PR is a legitimate re-review signal), but a PR whose **author**
|
|
109
|
-
// is the bot is a different thing: the App can't submit a formal review
|
|
110
|
-
// of its own PR (GitHub 422 "Can not approve your own pull request") and
|
|
111
|
-
// a self-review has no gating value. Filter on the author, not the
|
|
112
|
-
// sender, so a bot `synchronize` on a human-authored PR still flows
|
|
113
|
-
// through while the bot's own PRs are dropped before any sandbox spawns.
|
|
114
|
-
const prAuthor = payload.pull_request?.user?.login || "";
|
|
115
|
-
const isBotAuthoredPr = isPrAttention &&
|
|
116
|
-
(prAuthor === this.config.botLogin || prAuthor.endsWith("[bot]"));
|
|
117
|
-
if (isBotAuthoredPr) {
|
|
118
|
-
return c.json({ filtered: true, reason: "bot-authored PR (self-review)" }, 200);
|
|
119
|
-
}
|
|
120
|
-
// Filter out repos not in the managed allowlist. The GitHub App may be
|
|
121
|
-
// installed on additional repos but we only operate on those we explicitly
|
|
122
|
-
// manage. See src/managed-repos.ts.
|
|
123
|
-
const repoFullName = payload.repository?.full_name;
|
|
124
|
-
if (!isManagedRepo(repoFullName)) {
|
|
125
|
-
console.log(`[github] Filtered webhook for unmanaged repo: ${repoFullName}`);
|
|
126
|
-
return c.json({ filtered: true, reason: `repo not managed: ${repoFullName}` }, 200);
|
|
127
|
-
}
|
|
128
|
-
// Normalize to EventEnvelope
|
|
129
|
-
const envelope = this.normalize(eventType, action, payload, deliveryId);
|
|
130
|
-
if (!envelope) {
|
|
131
|
-
return c.json({ filtered: true, reason: "unmapped event" }, 200);
|
|
132
|
-
}
|
|
133
|
-
// Emit asynchronously — don't block the webhook response
|
|
134
|
-
setImmediate(() => this.emit("event", envelope));
|
|
135
|
-
return c.json({ accepted: true, id: deliveryId }, 202);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Apply an `installation` / `installation_repositories` event to the in-memory
|
|
140
|
-
* managed-repo list (src/managed-repos.ts). We apply the payload diff directly
|
|
141
|
-
* — the events carry the affected repos' `full_name`, so no API round-trip is
|
|
142
|
-
* needed. The list is seeded at boot; these keep it current between restarts.
|
|
143
|
-
*/
|
|
144
|
-
handleInstallationEvent(eventType, action, payload) {
|
|
145
|
-
const names = (repos) => Array.isArray(repos) ? repos.map((r) => r?.full_name).filter(Boolean) : [];
|
|
146
|
-
if (eventType === "installation_repositories") {
|
|
147
|
-
if (action === "added") {
|
|
148
|
-
const added = names(payload.repositories_added);
|
|
149
|
-
addInstallationRepos(added);
|
|
150
|
-
console.log(`[github] Installation repos added: ${added.join(", ") || "(none)"}`);
|
|
151
|
-
}
|
|
152
|
-
else if (action === "removed") {
|
|
153
|
-
const removed = names(payload.repositories_removed);
|
|
154
|
-
removeInstallationRepos(removed);
|
|
155
|
-
console.log(`[github] Installation repos removed: ${removed.join(", ") || "(none)"}`);
|
|
156
|
-
}
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
// eventType === "installation"
|
|
160
|
-
if (action === "created") {
|
|
161
|
-
// The initial-install payload lists the granted repos; reset to exactly them.
|
|
162
|
-
const repos = names(payload.repositories);
|
|
163
|
-
setInstallationRepos(repos);
|
|
164
|
-
console.log(`[github] App installed with ${repos.length} repos`);
|
|
165
|
-
}
|
|
166
|
-
else if (action === "deleted") {
|
|
167
|
-
setInstallationRepos([]);
|
|
168
|
-
console.log(`[github] App uninstalled — cleared installation repos`);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
verifySignature(body, signature) {
|
|
172
|
-
const expected = "sha256=" + createHmac("sha256", this.config.webhookSecret)
|
|
173
|
-
.update(body)
|
|
174
|
-
.digest("hex");
|
|
175
|
-
try {
|
|
176
|
-
return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
|
|
177
|
-
}
|
|
178
|
-
catch {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
normalize(githubEvent, action, payload, deliveryId) {
|
|
183
|
-
const repoFullName = payload.repository?.full_name;
|
|
184
|
-
const sender = payload.sender?.login || "unknown";
|
|
185
|
-
// Map GitHub event + action → our EventType
|
|
186
|
-
let type = null;
|
|
187
|
-
let issueNumber;
|
|
188
|
-
let prNumber;
|
|
189
|
-
let body = "";
|
|
190
|
-
let title = "";
|
|
191
|
-
let labels = [];
|
|
192
|
-
let issueAuthor;
|
|
193
|
-
switch (githubEvent) {
|
|
194
|
-
case "issues":
|
|
195
|
-
issueNumber = payload.issue?.number;
|
|
196
|
-
body = payload.issue?.body || "";
|
|
197
|
-
title = payload.issue?.title || "";
|
|
198
|
-
labels = (payload.issue?.labels || []).map((l) => l.name);
|
|
199
|
-
issueAuthor = payload.issue?.user?.login;
|
|
200
|
-
if (action === "opened")
|
|
201
|
-
type = "issue.opened";
|
|
202
|
-
else if (action === "reopened")
|
|
203
|
-
type = "issue.reopened";
|
|
204
|
-
break;
|
|
205
|
-
case "pull_request":
|
|
206
|
-
prNumber = payload.pull_request?.number;
|
|
207
|
-
issueNumber = prNumber; // PRs are issues too
|
|
208
|
-
body = payload.pull_request?.body || "";
|
|
209
|
-
title = payload.pull_request?.title || "";
|
|
210
|
-
labels = (payload.pull_request?.labels || []).map((l) => l.name);
|
|
211
|
-
issueAuthor = payload.pull_request?.user?.login;
|
|
212
|
-
if (action === "opened")
|
|
213
|
-
type = "pr.opened";
|
|
214
|
-
// synchronize fires on every new commit pushed to the PR's branch.
|
|
215
|
-
// We map it through so the pr-review workflow re-runs against the
|
|
216
|
-
// new head SHA — without this, branch protection on the new SHA
|
|
217
|
-
// sits with no `last-light/review` check after the first one.
|
|
218
|
-
else if (action === "synchronize")
|
|
219
|
-
type = "pr.synchronize";
|
|
220
|
-
// reopened: closed-then-reopened PRs deserve a fresh look too.
|
|
221
|
-
else if (action === "reopened")
|
|
222
|
-
type = "pr.reopened";
|
|
223
|
-
break;
|
|
224
|
-
case "issue_comment":
|
|
225
|
-
issueNumber = payload.issue?.number;
|
|
226
|
-
body = payload.comment?.body || "";
|
|
227
|
-
title = payload.issue?.title || "";
|
|
228
|
-
// Carry the parent issue's labels through — the router keys on
|
|
229
|
-
// `security-scan` to divert comments on summary issues to the
|
|
230
|
-
// security-feedback skill. Without this, every comment arrived
|
|
231
|
-
// label-less and fell through to the build path.
|
|
232
|
-
labels = (payload.issue?.labels || []).map((l) => l.name);
|
|
233
|
-
issueAuthor = payload.issue?.user?.login;
|
|
234
|
-
if (action === "created")
|
|
235
|
-
type = "comment.created";
|
|
236
|
-
// Detect if this is on a PR
|
|
237
|
-
if (payload.issue?.pull_request) {
|
|
238
|
-
prNumber = issueNumber;
|
|
239
|
-
}
|
|
240
|
-
break;
|
|
241
|
-
case "pull_request_review":
|
|
242
|
-
prNumber = payload.pull_request?.number;
|
|
243
|
-
issueNumber = prNumber;
|
|
244
|
-
body = payload.review?.body || "";
|
|
245
|
-
title = payload.pull_request?.title || "";
|
|
246
|
-
if (action === "submitted")
|
|
247
|
-
type = "pr_review.submitted";
|
|
248
|
-
break;
|
|
249
|
-
case "pull_request_review_comment":
|
|
250
|
-
prNumber = payload.pull_request?.number;
|
|
251
|
-
issueNumber = prNumber;
|
|
252
|
-
body = payload.comment?.body || "";
|
|
253
|
-
title = payload.pull_request?.title || "";
|
|
254
|
-
if (action === "created")
|
|
255
|
-
type = "pr_review_comment.created";
|
|
256
|
-
break;
|
|
257
|
-
// "Re-run" / "Re-run all checks" on the PR's Checks tab. GitHub fires
|
|
258
|
-
// check_run.rerequested (one check) or check_suite.rerequested (all) to
|
|
259
|
-
// the App that owns the check. Map either to pr.synchronize so the runner
|
|
260
|
-
// re-reviews the PR's current head — the same path a fresh push takes.
|
|
261
|
-
// The associated PR comes from the event's `pull_requests[]` (populated
|
|
262
|
-
// for same-repo PRs). Other check_run/check_suite actions (created /
|
|
263
|
-
// completed / requested, fired on every check) leave `type` null and are
|
|
264
|
-
// ignored. NOTE: requires the GitHub App to be subscribed to the "Check
|
|
265
|
-
// run" / "Check suite" events — without that GitHub never delivers these.
|
|
266
|
-
case "check_run":
|
|
267
|
-
if (action === "rerequested" || action === "requested_action") {
|
|
268
|
-
prNumber = payload.check_run?.pull_requests?.[0]?.number;
|
|
269
|
-
issueNumber = prNumber;
|
|
270
|
-
if (prNumber)
|
|
271
|
-
type = "pr.synchronize";
|
|
272
|
-
}
|
|
273
|
-
break;
|
|
274
|
-
case "check_suite":
|
|
275
|
-
if (action === "rerequested") {
|
|
276
|
-
prNumber = payload.check_suite?.pull_requests?.[0]?.number;
|
|
277
|
-
issueNumber = prNumber;
|
|
278
|
-
if (prNumber)
|
|
279
|
-
type = "pr.synchronize";
|
|
280
|
-
}
|
|
281
|
-
break;
|
|
282
|
-
}
|
|
283
|
-
if (!type)
|
|
284
|
-
return null;
|
|
285
|
-
const [owner, repo] = (repoFullName || "/").split("/");
|
|
286
|
-
const reply = async (msg) => {
|
|
287
|
-
if (this.config.replyFn && repoFullName && issueNumber) {
|
|
288
|
-
await this.config.replyFn(owner, repo, issueNumber, msg);
|
|
289
|
-
}
|
|
290
|
-
};
|
|
291
|
-
return {
|
|
292
|
-
id: deliveryId,
|
|
293
|
-
source: "github",
|
|
294
|
-
type,
|
|
295
|
-
repo: repoFullName,
|
|
296
|
-
issueNumber,
|
|
297
|
-
prNumber,
|
|
298
|
-
sender,
|
|
299
|
-
issueAuthor,
|
|
300
|
-
senderIsBot: false, // already filtered bots above
|
|
301
|
-
body,
|
|
302
|
-
title,
|
|
303
|
-
labels,
|
|
304
|
-
authorAssociation: payload.comment?.author_association || payload.issue?.author_association || payload.pull_request?.author_association,
|
|
305
|
-
raw: payload,
|
|
306
|
-
reply,
|
|
307
|
-
timestamp: new Date(),
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
async start() {
|
|
311
|
-
// No-op: the HTTP listener is owned by main()'s shared server. Routes are
|
|
312
|
-
// already registered on the shared app at construction time. This connector
|
|
313
|
-
// stays registered purely so its `emit("event", …)` flows through the
|
|
314
|
-
// ConnectorRegistry.
|
|
315
|
-
console.log("[github] Webhook routes registered on shared HTTP server");
|
|
316
|
-
}
|
|
317
|
-
async stop() {
|
|
318
|
-
// No-op: no server owned here to close.
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
//# sourceMappingURL=github-webhook.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"github-webhook.js","sourceRoot":"","sources":["../../src/connectors/github-webhook.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Connector, EventEnvelope } from "./types.js";
|
|
2
|
-
export type EventHandler = (envelope: EventEnvelope) => Promise<void>;
|
|
3
|
-
/**
|
|
4
|
-
* ConnectorRegistry manages all event source connectors.
|
|
5
|
-
* Register connectors, attach a unified event handler, start/stop all.
|
|
6
|
-
*/
|
|
7
|
-
export declare class ConnectorRegistry {
|
|
8
|
-
private connectors;
|
|
9
|
-
private handler;
|
|
10
|
-
register(connector: Connector): void;
|
|
11
|
-
onEvent(handler: EventHandler): void;
|
|
12
|
-
startAll(): Promise<void>;
|
|
13
|
-
stopAll(): Promise<void>;
|
|
14
|
-
}
|
|
15
|
-
export { type Connector, type EventEnvelope, type EventType } from "./types.js";
|
|
16
|
-
export { GitHubWebhookConnector, type GitHubWebhookConfig } from "./github-webhook.js";
|
|
17
|
-
export { MessagingConnector, SessionManager, MessageDeliveryService } from "./messaging/index.js";
|
|
18
|
-
export { SlackConnector, type SlackConnectorConfig } from "./slack/index.js";
|
package/dist/connectors/index.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ConnectorRegistry manages all event source connectors.
|
|
3
|
-
* Register connectors, attach a unified event handler, start/stop all.
|
|
4
|
-
*/
|
|
5
|
-
export class ConnectorRegistry {
|
|
6
|
-
connectors = new Map();
|
|
7
|
-
handler = null;
|
|
8
|
-
register(connector) {
|
|
9
|
-
if (this.connectors.has(connector.name)) {
|
|
10
|
-
throw new Error(`Connector "${connector.name}" already registered`);
|
|
11
|
-
}
|
|
12
|
-
this.connectors.set(connector.name, connector);
|
|
13
|
-
// Wire up event handler
|
|
14
|
-
connector.on("event", (envelope) => {
|
|
15
|
-
if (this.handler) {
|
|
16
|
-
this.handler(envelope).catch((err) => {
|
|
17
|
-
console.error(`[${connector.name}] Event handler error:`, err);
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
onEvent(handler) {
|
|
23
|
-
this.handler = handler;
|
|
24
|
-
}
|
|
25
|
-
async startAll() {
|
|
26
|
-
for (const [name, connector] of this.connectors) {
|
|
27
|
-
console.log(`[registry] Starting connector: ${name}`);
|
|
28
|
-
await connector.start();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async stopAll() {
|
|
32
|
-
for (const [name, connector] of this.connectors) {
|
|
33
|
-
console.log(`[registry] Stopping connector: ${name}`);
|
|
34
|
-
await connector.stop();
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
export { GitHubWebhookConnector } from "./github-webhook.js";
|
|
39
|
-
export { MessagingConnector, SessionManager, MessageDeliveryService } from "./messaging/index.js";
|
|
40
|
-
export { SlackConnector } from "./slack/index.js";
|
|
41
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IACpB,UAAU,GAA2B,IAAI,GAAG,EAAE,CAAC;IAC/C,OAAO,GAAwB,IAAI,CAAC;IAE5C,QAAQ,CAAC,SAAoB;QAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,cAAc,SAAS,CAAC,IAAI,sBAAsB,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAE/C,wBAAwB;QACxB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAuB,EAAE,EAAE;YAChD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACnC,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,wBAAwB,EAAE,GAAG,CAAC,CAAC;gBACjE,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,OAAqB;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;YACtD,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAC;YACtD,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;CACF;AAGD,OAAO,EAAE,sBAAsB,EAA4B,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,cAAc,EAA6B,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
import type { Connector } from "../types.js";
|
|
3
|
-
import type { SessionManager } from "./session-manager.js";
|
|
4
|
-
import type { MessagingConfig, IncomingMessageParams } from "./types.js";
|
|
5
|
-
/**
|
|
6
|
-
* Abstract base class for messaging platform connectors.
|
|
7
|
-
*
|
|
8
|
-
* Handles common logic: allowlist checks, DM vs channel behavior,
|
|
9
|
-
* session management, and EventEnvelope construction.
|
|
10
|
-
*
|
|
11
|
-
* Subclasses implement platform-specific transport (Slack Socket Mode,
|
|
12
|
-
* Discord Gateway, Teams Bot Framework, etc.) and the three abstract methods.
|
|
13
|
-
*/
|
|
14
|
-
export declare abstract class MessagingConnector extends EventEmitter implements Connector {
|
|
15
|
-
abstract readonly name: string;
|
|
16
|
-
protected config: MessagingConfig;
|
|
17
|
-
protected sessionManager: SessionManager;
|
|
18
|
-
constructor(config: MessagingConfig, sessionManager: SessionManager);
|
|
19
|
-
abstract start(): Promise<void>;
|
|
20
|
-
abstract stop(): Promise<void>;
|
|
21
|
-
/** Send a text message to a channel/thread */
|
|
22
|
-
abstract sendMessage(channelId: string, threadId: string | null, text: string): Promise<string | void>;
|
|
23
|
-
/** Add an emoji reaction to a message */
|
|
24
|
-
abstract addReaction(channelId: string, messageId: string, emoji: string): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Show a typing/processing indicator.
|
|
27
|
-
* @param messageId the user's message id (e.g. for an emoji reaction fallback)
|
|
28
|
-
* @param threadRootId the thread root id (where status indicators must anchor)
|
|
29
|
-
*/
|
|
30
|
-
abstract showTyping(channelId: string, messageId: string, threadRootId: string): Promise<void>;
|
|
31
|
-
/** Clear the typing/processing indicator (optional — not all platforms need this) */
|
|
32
|
-
clearTyping(_channelId: string, _threadId: string): Promise<void>;
|
|
33
|
-
/**
|
|
34
|
-
* Process an incoming message from any platform.
|
|
35
|
-
* Called by platform-specific event listeners.
|
|
36
|
-
*/
|
|
37
|
-
protected handleIncomingMessage(params: IncomingMessageParams): Promise<void>;
|
|
38
|
-
/** Strip the bot @mention from message text */
|
|
39
|
-
protected stripBotMention(text: string): string;
|
|
40
|
-
/** Split a message into chunks that fit platform limits */
|
|
41
|
-
protected chunkMessage(text: string, maxLength?: number): string[];
|
|
42
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
/**
|
|
3
|
-
* Abstract base class for messaging platform connectors.
|
|
4
|
-
*
|
|
5
|
-
* Handles common logic: allowlist checks, DM vs channel behavior,
|
|
6
|
-
* session management, and EventEnvelope construction.
|
|
7
|
-
*
|
|
8
|
-
* Subclasses implement platform-specific transport (Slack Socket Mode,
|
|
9
|
-
* Discord Gateway, Teams Bot Framework, etc.) and the three abstract methods.
|
|
10
|
-
*/
|
|
11
|
-
export class MessagingConnector extends EventEmitter {
|
|
12
|
-
config;
|
|
13
|
-
sessionManager;
|
|
14
|
-
constructor(config, sessionManager) {
|
|
15
|
-
super();
|
|
16
|
-
this.config = config;
|
|
17
|
-
this.sessionManager = sessionManager;
|
|
18
|
-
}
|
|
19
|
-
/** Clear the typing/processing indicator (optional — not all platforms need this) */
|
|
20
|
-
async clearTyping(_channelId, _threadId) { }
|
|
21
|
-
/**
|
|
22
|
-
* Process an incoming message from any platform.
|
|
23
|
-
* Called by platform-specific event listeners.
|
|
24
|
-
*/
|
|
25
|
-
async handleIncomingMessage(params) {
|
|
26
|
-
const { platformUserId, platformUsername, channelId, threadId, messageId, text, isDM, isMention, raw } = params;
|
|
27
|
-
// Allowlist check
|
|
28
|
-
if (this.config.allowedUsers.length > 0 && !this.config.allowedUsers.includes(platformUserId)) {
|
|
29
|
-
console.log(`[${this.name}] Ignoring message from unauthorized user: ${platformUsername} (${platformUserId})`);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// In channels, respond to @mentions or replies in threads the bot is already in
|
|
33
|
-
if (!isDM && !isMention) {
|
|
34
|
-
if (!threadId || !this.sessionManager.hasActiveThread(this.name, channelId, threadId)) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// Strip bot mention from the message text
|
|
39
|
-
const cleanText = this.stripBotMention(text).trim();
|
|
40
|
-
if (!cleanText)
|
|
41
|
-
return;
|
|
42
|
-
// Thread anchor for status indicators / replies, and the session key.
|
|
43
|
-
// A reply inside an existing thread carries its parent thread ts and
|
|
44
|
-
// continues that thread/session; a top-level message (no thread_ts —
|
|
45
|
-
// e.g. the user starting a NEW conversation in a DM, or a fresh channel
|
|
46
|
-
// @mention) roots a new thread on its own ts. This is exactly Slack's
|
|
47
|
-
// own threading: each distinct thread is its own conversation, so each
|
|
48
|
-
// maps to its own session. (Do NOT collapse top-level DM messages into
|
|
49
|
-
// the most-recent thread — that strands a deliberately-new thread's
|
|
50
|
-
// replies back in the old one.)
|
|
51
|
-
const replyThreadId = threadId || messageId;
|
|
52
|
-
// Show acknowledgment
|
|
53
|
-
this.showTyping(channelId, messageId, replyThreadId).catch(() => { });
|
|
54
|
-
// Get or create session
|
|
55
|
-
const session = this.sessionManager.getOrCreateSession({
|
|
56
|
-
platform: this.name,
|
|
57
|
-
channelId,
|
|
58
|
-
threadId: replyThreadId,
|
|
59
|
-
userId: platformUserId,
|
|
60
|
-
});
|
|
61
|
-
// NOTE: conversation persistence (user + assistant rows in
|
|
62
|
-
// messaging_messages, plus touchSession) is owned solely by the chat
|
|
63
|
-
// engine (src/engine/chat-runner.ts), which is the only path common to
|
|
64
|
-
// every chat surface — Slack here and the CLI /api/chat route, which
|
|
65
|
-
// never touches this connector. Recording here as well double-wrote
|
|
66
|
-
// every turn (a clean copy AND chat-runner's untrusted-wrapped copy)
|
|
67
|
-
// and fed both back into the model's rehydrated history. Build the
|
|
68
|
-
// session for routing/ids only; let chat-runner do the writes.
|
|
69
|
-
// Build the reply callback — sends to same channel/thread
|
|
70
|
-
const reply = async (msg) => {
|
|
71
|
-
// Clear thinking indicator before sending response
|
|
72
|
-
this.clearTyping(channelId, replyThreadId).catch(() => { });
|
|
73
|
-
// Chunk long messages
|
|
74
|
-
const chunks = this.chunkMessage(msg);
|
|
75
|
-
for (const chunk of chunks) {
|
|
76
|
-
await this.sendMessage(channelId, replyThreadId, chunk);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
// Re-show the thinking indicator at the start of each turn. The per-arrival
|
|
80
|
-
// showTyping above is cleared by the first turn's reply, so without this a
|
|
81
|
-
// burst that drains as a second batch would process with no indicator.
|
|
82
|
-
const typing = () => this.showTyping(channelId, messageId, replyThreadId);
|
|
83
|
-
// Build EventEnvelope
|
|
84
|
-
const envelope = {
|
|
85
|
-
id: `${this.name}-${messageId}`,
|
|
86
|
-
source: this.name,
|
|
87
|
-
type: "message",
|
|
88
|
-
sender: platformUsername,
|
|
89
|
-
senderIsBot: false,
|
|
90
|
-
body: cleanText,
|
|
91
|
-
raw: {
|
|
92
|
-
...typeof raw === "object" && raw !== null ? raw : {},
|
|
93
|
-
sessionId: session.id,
|
|
94
|
-
platformUserId,
|
|
95
|
-
channelId,
|
|
96
|
-
threadId: replyThreadId,
|
|
97
|
-
},
|
|
98
|
-
reply,
|
|
99
|
-
typing,
|
|
100
|
-
timestamp: new Date(),
|
|
101
|
-
};
|
|
102
|
-
this.emit("event", envelope);
|
|
103
|
-
}
|
|
104
|
-
/** Strip the bot @mention from message text */
|
|
105
|
-
stripBotMention(text) {
|
|
106
|
-
if (!this.config.botIdentifier)
|
|
107
|
-
return text;
|
|
108
|
-
// Generic pattern — subclasses can override for platform-specific mention formats
|
|
109
|
-
const mentionPattern = new RegExp(`<@${this.config.botIdentifier}>|@${this.config.botIdentifier}`, "gi");
|
|
110
|
-
return text.replace(mentionPattern, "").trim();
|
|
111
|
-
}
|
|
112
|
-
/** Split a message into chunks that fit platform limits */
|
|
113
|
-
chunkMessage(text, maxLength = 3000) {
|
|
114
|
-
if (text.length <= maxLength)
|
|
115
|
-
return [text];
|
|
116
|
-
const chunks = [];
|
|
117
|
-
let remaining = text;
|
|
118
|
-
while (remaining.length > 0) {
|
|
119
|
-
if (remaining.length <= maxLength) {
|
|
120
|
-
chunks.push(remaining);
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
// Try to break at a newline
|
|
124
|
-
let breakPoint = remaining.lastIndexOf("\n", maxLength);
|
|
125
|
-
if (breakPoint < maxLength * 0.5) {
|
|
126
|
-
// No good newline break — try space
|
|
127
|
-
breakPoint = remaining.lastIndexOf(" ", maxLength);
|
|
128
|
-
}
|
|
129
|
-
if (breakPoint < maxLength * 0.3) {
|
|
130
|
-
// No good break — hard cut
|
|
131
|
-
breakPoint = maxLength;
|
|
132
|
-
}
|
|
133
|
-
chunks.push(remaining.slice(0, breakPoint));
|
|
134
|
-
remaining = remaining.slice(breakPoint).trimStart();
|
|
135
|
-
}
|
|
136
|
-
return chunks;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=base.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/connectors/messaging/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Message delivery service for sending output to messaging platforms.
|
|
3
|
-
* Used by cron jobs (health reports, alerts) and other async notifications.
|
|
4
|
-
*/
|
|
5
|
-
export type DeliveryTarget = (message: string) => Promise<void>;
|
|
6
|
-
export declare class MessageDeliveryService {
|
|
7
|
-
private targets;
|
|
8
|
-
/** Register a delivery target for a platform */
|
|
9
|
-
register(platform: string, target: DeliveryTarget): void;
|
|
10
|
-
/** Deliver a message to a specific platform, or all if none specified */
|
|
11
|
-
deliver(message: string, platform?: string): Promise<void>;
|
|
12
|
-
/** Check if any delivery targets are registered */
|
|
13
|
-
hasTargets(): boolean;
|
|
14
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Message delivery service for sending output to messaging platforms.
|
|
3
|
-
* Used by cron jobs (health reports, alerts) and other async notifications.
|
|
4
|
-
*/
|
|
5
|
-
export class MessageDeliveryService {
|
|
6
|
-
targets = new Map();
|
|
7
|
-
/** Register a delivery target for a platform */
|
|
8
|
-
register(platform, target) {
|
|
9
|
-
this.targets.set(platform, target);
|
|
10
|
-
console.log(`[delivery] Registered target: ${platform}`);
|
|
11
|
-
}
|
|
12
|
-
/** Deliver a message to a specific platform, or all if none specified */
|
|
13
|
-
async deliver(message, platform) {
|
|
14
|
-
if (platform) {
|
|
15
|
-
const target = this.targets.get(platform);
|
|
16
|
-
if (!target) {
|
|
17
|
-
console.warn(`[delivery] No target registered for platform: ${platform}`);
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
await target(message);
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
// Deliver to all registered targets
|
|
24
|
-
for (const [name, target] of this.targets) {
|
|
25
|
-
try {
|
|
26
|
-
await target(message);
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
console.error(`[delivery] Failed to deliver to ${name}:`, err);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/** Check if any delivery targets are registered */
|
|
34
|
-
hasTargets() {
|
|
35
|
-
return this.targets.size > 0;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=delivery.js.map
|