opensquid 0.5.441 → 0.5.449
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 +1 -0
- package/dist/functions/arm_scope.d.ts +27 -0
- package/dist/functions/arm_scope.d.ts.map +1 -0
- package/dist/functions/arm_scope.js +52 -0
- package/dist/functions/arm_scope.js.map +1 -0
- package/dist/functions/index.d.ts +1 -0
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.js +1 -0
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/recall_pre_inject.d.ts.map +1 -1
- package/dist/functions/recall_pre_inject.js +12 -0
- package/dist/functions/recall_pre_inject.js.map +1 -1
- package/dist/rag/store_git.d.ts +23 -0
- package/dist/rag/store_git.d.ts.map +1 -0
- package/dist/rag/store_git.js +57 -0
- package/dist/rag/store_git.js.map +1 -0
- package/dist/runtime/bootstrap.d.ts.map +1 -1
- package/dist/runtime/bootstrap.js +2 -0
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/handoff/render.d.ts +5 -4
- package/dist/runtime/handoff/render.d.ts.map +1 -1
- package/dist/runtime/handoff/render.js +7 -7
- package/dist/runtime/handoff/render.js.map +1 -1
- package/dist/runtime/hooks/active_task_mirror.js +0 -0
- package/dist/runtime/hooks/apply_patch.js +0 -0
- package/dist/runtime/hooks/dispatch.js +0 -0
- package/dist/runtime/hooks/hook_output.js +0 -0
- package/dist/runtime/hooks/memory_reconcile.js +0 -0
- package/dist/runtime/hooks/new_project_detect.js +0 -0
- package/dist/runtime/hooks/profession_resolver.js +0 -0
- package/dist/runtime/hooks/scope_intent.js +0 -0
- package/dist/runtime/hooks/session-end.js +11 -0
- package/dist/runtime/hooks/session-end.js.map +1 -1
- package/dist/runtime/hooks/session_id.js +0 -0
- package/dist/runtime/hooks/session_liveness.js +0 -0
- package/dist/runtime/hooks/stop_drive.js +0 -0
- package/dist/runtime/hooks/stop_stream.js +0 -0
- package/dist/runtime/hooks/subagent_guard.js +0 -0
- package/dist/runtime/hooks/transcript.js +0 -0
- package/dist/runtime/hooks/transcript_tasks.js +0 -0
- package/dist/runtime/ralph/orchestrator.d.ts.map +1 -1
- package/dist/runtime/ralph/orchestrator.js +2 -1
- package/dist/runtime/ralph/orchestrator.js.map +1 -1
- package/dist/setup/cli/limits_state.d.ts.map +1 -1
- package/dist/setup/cli/limits_state.js +6 -40
- package/dist/setup/cli/limits_state.js.map +1 -1
- package/dist/setup/cli/pack_walk.d.ts +32 -0
- package/dist/setup/cli/pack_walk.d.ts.map +1 -0
- package/dist/setup/cli/pack_walk.js +76 -0
- package/dist/setup/cli/pack_walk.js.map +1 -0
- package/dist/setup/cli/permissions_state.d.ts.map +1 -1
- package/dist/setup/cli/permissions_state.js +6 -37
- package/dist/setup/cli/permissions_state.js.map +1 -1
- package/dist/setup/cli/triggers_state.d.ts.map +1 -1
- package/dist/setup/cli/triggers_state.js +3 -29
- package/dist/setup/cli/triggers_state.js.map +1 -1
- package/dist/workgraph/events.d.ts.map +1 -1
- package/dist/workgraph/events.js +10 -0
- package/dist/workgraph/events.js.map +1 -1
- package/dist/workgraph/store.d.ts.map +1 -1
- package/dist/workgraph/store.js +5 -0
- package/dist/workgraph/store.js.map +1 -1
- package/dist/workgraph/types.d.ts +2 -1
- package/dist/workgraph/types.d.ts.map +1 -1
- package/docs/ARCHITECTURE.md +268 -0
- package/docs/pack-runtime.md +15 -12
- package/docs/skill-grammar-guide.md +4 -4
- package/package.json +5 -3
- package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +13 -17
- package/dist/anti-drift/evaluator.d.ts +0 -88
- package/dist/anti-drift/evaluator.d.ts.map +0 -1
- package/dist/anti-drift/evaluator.js +0 -417
- package/dist/anti-drift/evaluator.js.map +0 -1
- package/dist/anti-drift/evaluator.test.js +0 -78
- package/dist/anti-drift/rules.d.ts +0 -80
- package/dist/anti-drift/rules.d.ts.map +0 -1
- package/dist/anti-drift/rules.js +0 -368
- package/dist/anti-drift/rules.js.map +0 -1
- package/dist/anti-drift/rules.test.js +0 -213
- package/dist/anti-drift/state.d.ts +0 -107
- package/dist/anti-drift/state.d.ts.map +0 -1
- package/dist/anti-drift/state.js +0 -177
- package/dist/anti-drift/state.js.map +0 -1
- package/dist/anti-drift/state.test.js +0 -120
- package/dist/chat/adapters/discord.d.ts +0 -41
- package/dist/chat/adapters/discord.d.ts.map +0 -1
- package/dist/chat/adapters/discord.js +0 -176
- package/dist/chat/adapters/discord.js.map +0 -1
- package/dist/chat/adapters/discord.test.js +0 -25
- package/dist/chat/adapters/slack.d.ts +0 -43
- package/dist/chat/adapters/slack.d.ts.map +0 -1
- package/dist/chat/adapters/slack.js +0 -172
- package/dist/chat/adapters/slack.js.map +0 -1
- package/dist/chat/adapters/slack.test.js +0 -30
- package/dist/chat/adapters/telegram.d.ts +0 -148
- package/dist/chat/adapters/telegram.d.ts.map +0 -1
- package/dist/chat/adapters/telegram.js +0 -498
- package/dist/chat/adapters/telegram.js.map +0 -1
- package/dist/chat/adapters/telegram.test.js +0 -94
- package/dist/chat/config.d.ts +0 -98
- package/dist/chat/config.d.ts.map +0 -1
- package/dist/chat/config.js +0 -185
- package/dist/chat/config.js.map +0 -1
- package/dist/chat/daemon/active-project.d.ts +0 -17
- package/dist/chat/daemon/active-project.d.ts.map +0 -1
- package/dist/chat/daemon/active-project.js +0 -23
- package/dist/chat/daemon/active-project.js.map +0 -1
- package/dist/chat/daemon/autospawn.d.ts +0 -40
- package/dist/chat/daemon/autospawn.d.ts.map +0 -1
- package/dist/chat/daemon/autospawn.js +0 -129
- package/dist/chat/daemon/autospawn.js.map +0 -1
- package/dist/chat/daemon/autospawn.test.js +0 -112
- package/dist/chat/daemon/cli.d.ts +0 -18
- package/dist/chat/daemon/cli.d.ts.map +0 -1
- package/dist/chat/daemon/cli.js +0 -71
- package/dist/chat/daemon/cli.js.map +0 -1
- package/dist/chat/daemon/collisions.js +0 -384
- package/dist/chat/daemon/health-check.d.ts +0 -69
- package/dist/chat/daemon/health-check.d.ts.map +0 -1
- package/dist/chat/daemon/health-check.js +0 -112
- package/dist/chat/daemon/health-check.js.map +0 -1
- package/dist/chat/daemon/inbox-read.d.ts +0 -35
- package/dist/chat/daemon/inbox-read.d.ts.map +0 -1
- package/dist/chat/daemon/inbox-read.js +0 -75
- package/dist/chat/daemon/inbox-read.js.map +0 -1
- package/dist/chat/daemon/inbox-read.test.js +0 -97
- package/dist/chat/daemon/inbox.d.ts +0 -63
- package/dist/chat/daemon/inbox.d.ts.map +0 -1
- package/dist/chat/daemon/inbox.js +0 -56
- package/dist/chat/daemon/inbox.js.map +0 -1
- package/dist/chat/daemon/inbox.test.js +0 -110
- package/dist/chat/daemon/lifecycle.d.ts +0 -71
- package/dist/chat/daemon/lifecycle.d.ts.map +0 -1
- package/dist/chat/daemon/lifecycle.js +0 -221
- package/dist/chat/daemon/lifecycle.js.map +0 -1
- package/dist/chat/daemon/lifecycle.test.js +0 -163
- package/dist/chat/daemon/protocol.d.ts +0 -107
- package/dist/chat/daemon/protocol.d.ts.map +0 -1
- package/dist/chat/daemon/protocol.js +0 -54
- package/dist/chat/daemon/protocol.js.map +0 -1
- package/dist/chat/daemon/routing.d.ts +0 -140
- package/dist/chat/daemon/routing.d.ts.map +0 -1
- package/dist/chat/daemon/routing.js +0 -198
- package/dist/chat/daemon/routing.js.map +0 -1
- package/dist/chat/daemon/routing.test.js +0 -259
- package/dist/chat/daemon/rpc-client.d.ts +0 -45
- package/dist/chat/daemon/rpc-client.d.ts.map +0 -1
- package/dist/chat/daemon/rpc-client.js +0 -133
- package/dist/chat/daemon/rpc-client.js.map +0 -1
- package/dist/chat/daemon/rpc-server.d.ts +0 -39
- package/dist/chat/daemon/rpc-server.d.ts.map +0 -1
- package/dist/chat/daemon/rpc-server.js +0 -385
- package/dist/chat/daemon/rpc-server.js.map +0 -1
- package/dist/chat/daemon/rpc.test.js +0 -177
- package/dist/chat/daemon/subscribers.js +0 -257
- package/dist/chat/daemon/worker.d.ts +0 -27
- package/dist/chat/daemon/worker.d.ts.map +0 -1
- package/dist/chat/daemon/worker.js +0 -313
- package/dist/chat/daemon/worker.js.map +0 -1
- package/dist/chat/daemon/workspace-topic.js +0 -324
- package/dist/chat/env-token.d.ts +0 -60
- package/dist/chat/env-token.d.ts.map +0 -1
- package/dist/chat/env-token.js +0 -137
- package/dist/chat/env-token.js.map +0 -1
- package/dist/chat/env-token.test.js +0 -160
- package/dist/chat/factory.d.ts +0 -30
- package/dist/chat/factory.d.ts.map +0 -1
- package/dist/chat/factory.js +0 -50
- package/dist/chat/factory.js.map +0 -1
- package/dist/chat/factory.test.js +0 -55
- package/dist/chat/gateway.d.ts +0 -176
- package/dist/chat/gateway.d.ts.map +0 -1
- package/dist/chat/gateway.js +0 -146
- package/dist/chat/gateway.js.map +0 -1
- package/dist/chat/gateway.test.js +0 -192
- package/dist/claude-md.d.ts +0 -39
- package/dist/claude-md.d.ts.map +0 -1
- package/dist/claude-md.js +0 -113
- package/dist/claude-md.js.map +0 -1
- package/dist/claude-md.test.js +0 -91
- package/dist/codex/activate.d.ts +0 -66
- package/dist/codex/activate.d.ts.map +0 -1
- package/dist/codex/activate.js +0 -329
- package/dist/codex/activate.js.map +0 -1
- package/dist/codex/activate.test.js +0 -229
- package/dist/codex/bundled-default/bundled-default.test.js +0 -161
- package/dist/codex/cli-publish.test.js +0 -133
- package/dist/codex/cli.d.ts +0 -35
- package/dist/codex/cli.d.ts.map +0 -1
- package/dist/codex/cli.js +0 -554
- package/dist/codex/cli.js.map +0 -1
- package/dist/codex/cli.test.js +0 -277
- package/dist/codex/import-skill-md.d.ts +0 -53
- package/dist/codex/import-skill-md.d.ts.map +0 -1
- package/dist/codex/import-skill-md.js +0 -236
- package/dist/codex/import-skill-md.js.map +0 -1
- package/dist/codex/import-skill-md.test.js +0 -225
- package/dist/codex/loader.d.ts +0 -27
- package/dist/codex/loader.d.ts.map +0 -1
- package/dist/codex/loader.js +0 -86
- package/dist/codex/loader.js.map +0 -1
- package/dist/codex/loader.test.js +0 -75
- package/dist/codex/parse.d.ts +0 -28
- package/dist/codex/parse.d.ts.map +0 -1
- package/dist/codex/parse.js +0 -309
- package/dist/codex/parse.js.map +0 -1
- package/dist/codex/parse.test.js +0 -241
- package/dist/codex/store.d.ts +0 -87
- package/dist/codex/store.d.ts.map +0 -1
- package/dist/codex/store.js +0 -205
- package/dist/codex/store.js.map +0 -1
- package/dist/codex/store.test.js +0 -242
- package/dist/codex/types.d.ts +0 -398
- package/dist/codex/types.d.ts.map +0 -1
- package/dist/codex/types.js +0 -21
- package/dist/codex/types.js.map +0 -1
- package/dist/config.d.ts +0 -53
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -202
- package/dist/config.js.map +0 -1
- package/dist/config.test.js +0 -117
- package/dist/engine/cli.d.ts +0 -14
- package/dist/engine/cli.d.ts.map +0 -1
- package/dist/engine/cli.js +0 -171
- package/dist/engine/cli.js.map +0 -1
- package/dist/engine/client.d.ts +0 -219
- package/dist/engine/client.d.ts.map +0 -1
- package/dist/engine/client.js +0 -312
- package/dist/engine/client.js.map +0 -1
- package/dist/engine/config.d.ts +0 -62
- package/dist/engine/config.d.ts.map +0 -1
- package/dist/engine/config.js +0 -223
- package/dist/engine/config.js.map +0 -1
- package/dist/engine/index.d.ts +0 -17
- package/dist/engine/index.d.ts.map +0 -1
- package/dist/engine/index.js +0 -16
- package/dist/engine/index.js.map +0 -1
- package/dist/engine/resolver.d.ts +0 -62
- package/dist/engine/resolver.d.ts.map +0 -1
- package/dist/engine/resolver.js +0 -103
- package/dist/engine/resolver.js.map +0 -1
- package/dist/engine/singleton.d.ts +0 -95
- package/dist/engine/singleton.d.ts.map +0 -1
- package/dist/engine/singleton.js +0 -325
- package/dist/engine/singleton.js.map +0 -1
- package/dist/engine/types.d.ts +0 -402
- package/dist/engine/types.d.ts.map +0 -1
- package/dist/engine/types.js +0 -22
- package/dist/engine/types.js.map +0 -1
- package/dist/engine-binary-resolver.js +0 -110
- package/dist/engine-binary-resolver.test.js +0 -61
- package/dist/engine-cli.js +0 -60
- package/dist/engine-client.js +0 -301
- package/dist/engine-client.test.js +0 -118
- package/dist/functions/chain_state.d.ts +0 -51
- package/dist/functions/chain_state.d.ts.map +0 -1
- package/dist/functions/chain_state.js +0 -59
- package/dist/functions/chain_state.js.map +0 -1
- package/dist/hooks/drift-catalog.d.ts +0 -68
- package/dist/hooks/drift-catalog.d.ts.map +0 -1
- package/dist/hooks/drift-catalog.js +0 -184
- package/dist/hooks/drift-catalog.js.map +0 -1
- package/dist/hooks/drift-catalog.test.js +0 -154
- package/dist/hooks/drift-patterns.d.ts +0 -110
- package/dist/hooks/drift-patterns.d.ts.map +0 -1
- package/dist/hooks/drift-patterns.js +0 -289
- package/dist/hooks/drift-patterns.js.map +0 -1
- package/dist/hooks/drift-patterns.test.js +0 -325
- package/dist/hooks/engine-vocab-gate.d.ts +0 -108
- package/dist/hooks/engine-vocab-gate.d.ts.map +0 -1
- package/dist/hooks/engine-vocab-gate.js +0 -225
- package/dist/hooks/engine-vocab-gate.js.map +0 -1
- package/dist/hooks/engine-vocab-gate.test.js +0 -170
- package/dist/hooks/heartbeat.d.ts +0 -107
- package/dist/hooks/heartbeat.d.ts.map +0 -1
- package/dist/hooks/heartbeat.js +0 -316
- package/dist/hooks/heartbeat.js.map +0 -1
- package/dist/hooks/heartbeat.test.js +0 -393
- package/dist/hooks/honesty-ledger-session-scope.test.js +0 -100
- package/dist/hooks/honesty-ledger.d.ts +0 -123
- package/dist/hooks/honesty-ledger.d.ts.map +0 -1
- package/dist/hooks/honesty-ledger.js +0 -226
- package/dist/hooks/honesty-ledger.js.map +0 -1
- package/dist/hooks/honesty-ledger.test.js +0 -466
- package/dist/hooks/inline-report-check.d.ts +0 -63
- package/dist/hooks/inline-report-check.d.ts.map +0 -1
- package/dist/hooks/inline-report-check.js +0 -88
- package/dist/hooks/inline-report-check.js.map +0 -1
- package/dist/hooks/inline-report-check.test.js +0 -96
- package/dist/hooks/pre-tool-use.d.ts +0 -62
- package/dist/hooks/pre-tool-use.d.ts.map +0 -1
- package/dist/hooks/pre-tool-use.js +0 -342
- package/dist/hooks/pre-tool-use.js.map +0 -1
- package/dist/hooks/pre-tool-use.test.js +0 -134
- package/dist/hooks/session-end.d.ts +0 -15
- package/dist/hooks/session-end.d.ts.map +0 -1
- package/dist/hooks/session-end.js +0 -60
- package/dist/hooks/session-end.js.map +0 -1
- package/dist/hooks/session-end.test.js +0 -52
- package/dist/hooks/stop.d.ts +0 -35
- package/dist/hooks/stop.d.ts.map +0 -1
- package/dist/hooks/stop.js +0 -136
- package/dist/hooks/stop.js.map +0 -1
- package/dist/hooks/transcript-active-task.test.js +0 -342
- package/dist/hooks/transcript.d.ts +0 -26
- package/dist/hooks/transcript.d.ts.map +0 -1
- package/dist/hooks/transcript.js +0 -266
- package/dist/hooks/transcript.js.map +0 -1
- package/dist/hooks/transcript.test.js +0 -103
- package/dist/hooks/user-prompt-submit.d.ts +0 -74
- package/dist/hooks/user-prompt-submit.d.ts.map +0 -1
- package/dist/hooks/user-prompt-submit.js +0 -256
- package/dist/hooks/user-prompt-submit.js.map +0 -1
- package/dist/hooks/user-prompt-submit.test.js +0 -118
- package/dist/hooks/versioning-gate.d.ts +0 -101
- package/dist/hooks/versioning-gate.d.ts.map +0 -1
- package/dist/hooks/versioning-gate.js +0 -245
- package/dist/hooks/versioning-gate.js.map +0 -1
- package/dist/hooks/versioning-gate.test.js +0 -368
- package/dist/hooks/workflow-gate.d.ts +0 -64
- package/dist/hooks/workflow-gate.d.ts.map +0 -1
- package/dist/hooks/workflow-gate.js +0 -152
- package/dist/hooks/workflow-gate.js.map +0 -1
- package/dist/hooks/workflow-gate.test.js +0 -197
- package/dist/hooks-cli.d.ts +0 -25
- package/dist/hooks-cli.d.ts.map +0 -1
- package/dist/hooks-cli.js +0 -286
- package/dist/hooks-cli.js.map +0 -1
- package/dist/hooks-cli.test.js +0 -148
- package/dist/origin.d.ts +0 -16
- package/dist/origin.d.ts.map +0 -1
- package/dist/origin.js +0 -92
- package/dist/origin.js.map +0 -1
- package/dist/packs/seed_lessons_ingest.d.ts +0 -30
- package/dist/packs/seed_lessons_ingest.d.ts.map +0 -1
- package/dist/packs/seed_lessons_ingest.js +0 -107
- package/dist/packs/seed_lessons_ingest.js.map +0 -1
- package/dist/project-cli.d.ts +0 -7
- package/dist/project-cli.d.ts.map +0 -1
- package/dist/project-cli.js +0 -145
- package/dist/project-cli.js.map +0 -1
- package/dist/project.d.ts +0 -127
- package/dist/project.d.ts.map +0 -1
- package/dist/project.js +0 -281
- package/dist/project.js.map +0 -1
- package/dist/project.test.js +0 -287
- package/dist/rag/backends/loop_engine.d.ts +0 -61
- package/dist/rag/backends/loop_engine.d.ts.map +0 -1
- package/dist/rag/backends/loop_engine.js +0 -160
- package/dist/rag/backends/loop_engine.js.map +0 -1
- package/dist/recall.d.ts +0 -82
- package/dist/recall.d.ts.map +0 -1
- package/dist/recall.js +0 -81
- package/dist/recall.js.map +0 -1
- package/dist/runtime/agent_bridge/autospawn.d.ts +0 -131
- package/dist/runtime/agent_bridge/autospawn.d.ts.map +0 -1
- package/dist/runtime/agent_bridge/autospawn.js +0 -251
- package/dist/runtime/agent_bridge/autospawn.js.map +0 -1
- package/dist/runtime/chain_state.d.ts +0 -124
- package/dist/runtime/chain_state.d.ts.map +0 -1
- package/dist/runtime/chain_state.js +0 -189
- package/dist/runtime/chain_state.js.map +0 -1
- package/dist/runtime/hooks/permission_decision.d.ts +0 -34
- package/dist/runtime/hooks/permission_decision.d.ts.map +0 -1
- package/dist/runtime/hooks/permission_decision.js +0 -39
- package/dist/runtime/hooks/permission_decision.js.map +0 -1
- package/dist/runtime/workflow_fsm.d.ts +0 -21
- package/dist/runtime/workflow_fsm.d.ts.map +0 -1
- package/dist/runtime/workflow_fsm.js +0 -25
- package/dist/runtime/workflow_fsm.js.map +0 -1
- package/dist/runtime/workflow_map.d.ts +0 -26
- package/dist/runtime/workflow_map.d.ts.map +0 -1
- package/dist/runtime/workflow_map.js +0 -38
- package/dist/runtime/workflow_map.js.map +0 -1
- package/dist/scope.d.ts +0 -48
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js +0 -111
- package/dist/scope.js.map +0 -1
- package/dist/setup/cli/topic_create_step.d.ts +0 -84
- package/dist/setup/cli/topic_create_step.d.ts.map +0 -1
- package/dist/setup/cli/topic_create_step.js +0 -213
- package/dist/setup/cli/topic_create_step.js.map +0 -1
- package/dist/system-export.d.ts +0 -65
- package/dist/system-export.d.ts.map +0 -1
- package/dist/system-export.js +0 -194
- package/dist/system-export.js.map +0 -1
- package/dist/utterance/classifier.d.ts +0 -53
- package/dist/utterance/classifier.d.ts.map +0 -1
- package/dist/utterance/classifier.js +0 -184
- package/dist/utterance/classifier.js.map +0 -1
- package/dist/utterance/classifier.test.js +0 -147
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { ChatGatewayError } from "../gateway.js";
|
|
3
|
-
import { DiscordAdapter } from "./discord.js";
|
|
4
|
-
describe("DiscordAdapter constructor", () => {
|
|
5
|
-
it("rejects empty bot_token", () => {
|
|
6
|
-
expect(() => new DiscordAdapter({ bot_token: "" })).toThrow(ChatGatewayError);
|
|
7
|
-
});
|
|
8
|
-
it("rejects whitespace-only bot_token", () => {
|
|
9
|
-
expect(() => new DiscordAdapter({ bot_token: " " })).toThrow(ChatGatewayError);
|
|
10
|
-
});
|
|
11
|
-
it("accepts a real-shaped token", () => {
|
|
12
|
-
const a = new DiscordAdapter({ bot_token: "MTAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" });
|
|
13
|
-
expect(a.platform).toBe("discord");
|
|
14
|
-
});
|
|
15
|
-
it("send before start() throws", async () => {
|
|
16
|
-
const a = new DiscordAdapter({ bot_token: "MTAxxxxx" });
|
|
17
|
-
await expect(a.send({ channel: "discord:123", text: "hi" })).rejects.toThrow(/not started/);
|
|
18
|
-
});
|
|
19
|
-
it("send rejects malformed channel id", async () => {
|
|
20
|
-
const a = new DiscordAdapter({ bot_token: "MTAxxxxx" });
|
|
21
|
-
// We can't easily test the post-start path without spinning up a real
|
|
22
|
-
// Discord gateway, but the not-started path covers the early reject.
|
|
23
|
-
await expect(a.send({ channel: "no-colon", text: "hi" })).rejects.toThrow();
|
|
24
|
-
});
|
|
25
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Slack adapter — Socket Mode via @slack/socket-mode + @slack/web-api
|
|
3
|
-
* (v0.7c). Skips @slack/bolt to avoid dragging Express into opensquid's
|
|
4
|
-
* runtime tree.
|
|
5
|
-
*
|
|
6
|
-
* Two tokens required (Slack architectural decision, not opensquid's):
|
|
7
|
-
* bot_token — `xoxb-...` Bot User OAuth Token, used for Web API calls
|
|
8
|
-
* app_token — `xapp-...` App-Level Token with `connections:write`
|
|
9
|
-
* scope, used for the Socket Mode WebSocket
|
|
10
|
-
*
|
|
11
|
-
* Connection: outbound WebSocket via Socket Mode. No public webhook
|
|
12
|
-
* URL, no signature verification, no 3-second response SLA scrimmage.
|
|
13
|
-
* Works behind any NAT.
|
|
14
|
-
*
|
|
15
|
-
* Setup gotchas (surface in install docs):
|
|
16
|
-
* 1. Two tokens are easy to swap — xoxb→WebClient, xapp→SocketModeClient.
|
|
17
|
-
* Our validator rejects the wrong prefix at config-load time.
|
|
18
|
-
* 2. MUST `await ack()` within 3 seconds of every event even in
|
|
19
|
-
* Socket Mode, or Slack retries. We ack first, dispatch second.
|
|
20
|
-
* 3. Event Subscriptions need to be configured in the Slack dashboard
|
|
21
|
-
* separately from the Socket Mode toggle — easy to miss.
|
|
22
|
-
*/
|
|
23
|
-
import { type ChatAdapter, type MessageHandler, type OutboundMessage, type SendResult } from "../gateway.js";
|
|
24
|
-
import type { SlackConfig } from "../config.js";
|
|
25
|
-
export declare class SlackAdapter implements ChatAdapter {
|
|
26
|
-
private readonly config;
|
|
27
|
-
readonly platform: "slack";
|
|
28
|
-
private web;
|
|
29
|
-
private socket;
|
|
30
|
-
private handlers;
|
|
31
|
-
private botUsername;
|
|
32
|
-
private botId;
|
|
33
|
-
constructor(config: SlackConfig);
|
|
34
|
-
start(): Promise<void>;
|
|
35
|
-
shutdown(): Promise<void>;
|
|
36
|
-
onMessage(handler: MessageHandler): void;
|
|
37
|
-
send(message: OutboundMessage): Promise<SendResult>;
|
|
38
|
-
identity(): Promise<{
|
|
39
|
-
username: string;
|
|
40
|
-
nativeId: string;
|
|
41
|
-
}>;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src.legacy/chat/adapters/slack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,UAAU,EAEhB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AA8ChD,qBAAa,YAAa,YAAW,WAAW;IASlC,OAAO,CAAC,QAAQ,CAAC,MAAM;IARnC,QAAQ,CAAC,QAAQ,EAAG,OAAO,CAAU;IAErC,OAAO,CAAC,GAAG,CAA+B;IAC1C,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,KAAK,CAAM;gBAEU,MAAM,EAAE,WAAW;IAe1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiGtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIlC,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAuBnD,QAAQ,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAMlE"}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Slack adapter — Socket Mode via @slack/socket-mode + @slack/web-api
|
|
3
|
-
* (v0.7c). Skips @slack/bolt to avoid dragging Express into opensquid's
|
|
4
|
-
* runtime tree.
|
|
5
|
-
*
|
|
6
|
-
* Two tokens required (Slack architectural decision, not opensquid's):
|
|
7
|
-
* bot_token — `xoxb-...` Bot User OAuth Token, used for Web API calls
|
|
8
|
-
* app_token — `xapp-...` App-Level Token with `connections:write`
|
|
9
|
-
* scope, used for the Socket Mode WebSocket
|
|
10
|
-
*
|
|
11
|
-
* Connection: outbound WebSocket via Socket Mode. No public webhook
|
|
12
|
-
* URL, no signature verification, no 3-second response SLA scrimmage.
|
|
13
|
-
* Works behind any NAT.
|
|
14
|
-
*
|
|
15
|
-
* Setup gotchas (surface in install docs):
|
|
16
|
-
* 1. Two tokens are easy to swap — xoxb→WebClient, xapp→SocketModeClient.
|
|
17
|
-
* Our validator rejects the wrong prefix at config-load time.
|
|
18
|
-
* 2. MUST `await ack()` within 3 seconds of every event even in
|
|
19
|
-
* Socket Mode, or Slack retries. We ack first, dispatch second.
|
|
20
|
-
* 3. Event Subscriptions need to be configured in the Slack dashboard
|
|
21
|
-
* separately from the Socket Mode toggle — easy to miss.
|
|
22
|
-
*/
|
|
23
|
-
import { ChatGatewayError, formatChannelId, } from "../gateway.js";
|
|
24
|
-
export class SlackAdapter {
|
|
25
|
-
config;
|
|
26
|
-
platform = "slack";
|
|
27
|
-
web = null;
|
|
28
|
-
socket = null;
|
|
29
|
-
handlers = [];
|
|
30
|
-
botUsername = "";
|
|
31
|
-
botId = "";
|
|
32
|
-
constructor(config) {
|
|
33
|
-
this.config = config;
|
|
34
|
-
if (!config.bot_token?.trim()) {
|
|
35
|
-
throw new ChatGatewayError("slack adapter: bot_token is required", "set chat_connections.slack.bot_token (xoxb-...) in ~/.opensquid/config.json");
|
|
36
|
-
}
|
|
37
|
-
if (!config.app_token?.trim()) {
|
|
38
|
-
throw new ChatGatewayError("slack adapter: app_token is required for Socket Mode", "set chat_connections.slack.app_token (xapp-...) in ~/.opensquid/config.json");
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
async start() {
|
|
42
|
-
if (this.socket)
|
|
43
|
-
return;
|
|
44
|
-
let WebClient;
|
|
45
|
-
let SocketModeClient;
|
|
46
|
-
try {
|
|
47
|
-
const web = (await import("@slack/web-api"));
|
|
48
|
-
WebClient = web.WebClient;
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
// v0.7 audit fix (M5): distinguish not-installed from installed-but-threw.
|
|
52
|
-
const code = err?.code;
|
|
53
|
-
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") {
|
|
54
|
-
throw new ChatGatewayError("slack adapter: '@slack/web-api' SDK not installed", "run `npm install @slack/web-api @slack/socket-mode` (or reinstall without --omit=optional)");
|
|
55
|
-
}
|
|
56
|
-
throw new ChatGatewayError(`slack adapter: '@slack/web-api' SDK failed to load: ${err instanceof Error ? err.message : String(err)}`, "the SDK is installed but threw on import — check node version compatibility");
|
|
57
|
-
}
|
|
58
|
-
try {
|
|
59
|
-
const sm = (await import("@slack/socket-mode"));
|
|
60
|
-
SocketModeClient = sm.SocketModeClient;
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
const code = err?.code;
|
|
64
|
-
if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") {
|
|
65
|
-
throw new ChatGatewayError("slack adapter: '@slack/socket-mode' SDK not installed", "run `npm install @slack/socket-mode`");
|
|
66
|
-
}
|
|
67
|
-
throw new ChatGatewayError(`slack adapter: '@slack/socket-mode' SDK failed to load: ${err instanceof Error ? err.message : String(err)}`, "the SDK is installed but threw on import — check node version compatibility");
|
|
68
|
-
}
|
|
69
|
-
this.web = new WebClient(this.config.bot_token);
|
|
70
|
-
const socket = new SocketModeClient({ appToken: this.config.app_token });
|
|
71
|
-
this.socket = socket;
|
|
72
|
-
// Probe identity + bot_token validity in one round-trip.
|
|
73
|
-
const me = await this.web.auth.test();
|
|
74
|
-
if (!me.ok) {
|
|
75
|
-
throw new ChatGatewayError("slack adapter: auth.test failed — bot_token may be revoked");
|
|
76
|
-
}
|
|
77
|
-
this.botUsername = me.user ?? "";
|
|
78
|
-
this.botId = me.user_id ?? me.bot_id ?? "";
|
|
79
|
-
socket.on("message", async ({ event, ack }) => {
|
|
80
|
-
// ack FIRST — Slack's 3-second retry clock is unforgiving even
|
|
81
|
-
// in Socket Mode. Drop the work into the handler stack after.
|
|
82
|
-
await ack();
|
|
83
|
-
// Filter out subtypes (channel_join, bot_message, message_changed,
|
|
84
|
-
// etc.) and our own messages.
|
|
85
|
-
if (event.subtype)
|
|
86
|
-
return;
|
|
87
|
-
if (event.bot_id)
|
|
88
|
-
return;
|
|
89
|
-
if (!event.text || !event.user || !event.channel)
|
|
90
|
-
return;
|
|
91
|
-
if (this.config.allowlist_user_ids &&
|
|
92
|
-
this.config.allowlist_user_ids.length > 0 &&
|
|
93
|
-
!this.config.allowlist_user_ids.includes(event.user)) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const normalized = {
|
|
97
|
-
id: event.ts ?? `${event.channel}-${Date.now()}`,
|
|
98
|
-
platform: "slack",
|
|
99
|
-
channel: formatChannelId("slack", event.channel),
|
|
100
|
-
sender: event.user,
|
|
101
|
-
senderId: event.user,
|
|
102
|
-
text: event.text,
|
|
103
|
-
receivedAt: event.ts ? new Date(Math.floor(Number(event.ts) * 1000)) : new Date(),
|
|
104
|
-
mentionsBot: this.botId ? event.text.includes(`<@${this.botId}>`) : false,
|
|
105
|
-
};
|
|
106
|
-
for (const h of this.handlers) {
|
|
107
|
-
try {
|
|
108
|
-
await h(normalized);
|
|
109
|
-
}
|
|
110
|
-
catch (err) {
|
|
111
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
112
|
-
// eslint-disable-next-line no-console
|
|
113
|
-
console.error(`[slack adapter] handler error: ${msg}`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
await socket.start();
|
|
118
|
-
}
|
|
119
|
-
async shutdown() {
|
|
120
|
-
if (!this.socket)
|
|
121
|
-
return;
|
|
122
|
-
try {
|
|
123
|
-
await this.socket.disconnect();
|
|
124
|
-
}
|
|
125
|
-
catch {
|
|
126
|
-
// best-effort
|
|
127
|
-
}
|
|
128
|
-
this.socket = null;
|
|
129
|
-
this.web = null;
|
|
130
|
-
}
|
|
131
|
-
onMessage(handler) {
|
|
132
|
-
this.handlers.push(handler);
|
|
133
|
-
}
|
|
134
|
-
async send(message) {
|
|
135
|
-
if (!this.web) {
|
|
136
|
-
throw new ChatGatewayError("slack adapter: not started", "call gateway.start() before send()");
|
|
137
|
-
}
|
|
138
|
-
const channel = nativeChannelIdFromChannel(message.channel);
|
|
139
|
-
const sent = await this.web.chat.postMessage({
|
|
140
|
-
channel,
|
|
141
|
-
text: message.text,
|
|
142
|
-
thread_ts: message.replyTo,
|
|
143
|
-
});
|
|
144
|
-
if (!sent.ok || !sent.ts) {
|
|
145
|
-
throw new ChatGatewayError(`slack adapter: chat.postMessage failed for channel '${channel}'`);
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
platform: "slack",
|
|
149
|
-
messageId: sent.ts,
|
|
150
|
-
deliveredAt: new Date(Math.floor(Number(sent.ts) * 1000)),
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
async identity() {
|
|
154
|
-
if (!this.web) {
|
|
155
|
-
throw new ChatGatewayError("slack adapter: not started");
|
|
156
|
-
}
|
|
157
|
-
return { username: this.botUsername, nativeId: this.botId };
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
// ---------------------------------------------------------------------
|
|
161
|
-
// Helpers
|
|
162
|
-
// ---------------------------------------------------------------------
|
|
163
|
-
function nativeChannelIdFromChannel(channel) {
|
|
164
|
-
const idx = channel.indexOf(":");
|
|
165
|
-
if (idx === -1) {
|
|
166
|
-
throw new ChatGatewayError(`malformed channel id '${channel}'`);
|
|
167
|
-
}
|
|
168
|
-
if (channel.slice(0, idx) !== "slack") {
|
|
169
|
-
throw new ChatGatewayError(`slack adapter received non-slack channel: '${channel}'`);
|
|
170
|
-
}
|
|
171
|
-
return channel.slice(idx + 1);
|
|
172
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src.legacy/chat/adapters/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { ChatGatewayError } from "../gateway.js";
|
|
3
|
-
import { SlackAdapter } from "./slack.js";
|
|
4
|
-
describe("SlackAdapter constructor", () => {
|
|
5
|
-
it("rejects empty bot_token", () => {
|
|
6
|
-
expect(() => new SlackAdapter({ bot_token: "", app_token: "xapp-1-2-3" })).toThrow(ChatGatewayError);
|
|
7
|
-
});
|
|
8
|
-
it("rejects empty app_token", () => {
|
|
9
|
-
expect(() => new SlackAdapter({ bot_token: "xoxb-1-2-3", app_token: "" })).toThrow(ChatGatewayError);
|
|
10
|
-
});
|
|
11
|
-
it("rejects whitespace-only tokens", () => {
|
|
12
|
-
expect(() => new SlackAdapter({ bot_token: " ", app_token: "xapp-1-2-3" })).toThrow();
|
|
13
|
-
expect(() => new SlackAdapter({ bot_token: "xoxb-1-2-3", app_token: " " })).toThrow();
|
|
14
|
-
});
|
|
15
|
-
it("accepts both real-shaped tokens", () => {
|
|
16
|
-
const a = new SlackAdapter({
|
|
17
|
-
bot_token: "xoxb-123-456-abc",
|
|
18
|
-
app_token: "xapp-1-A1B2-xyz",
|
|
19
|
-
});
|
|
20
|
-
expect(a.platform).toBe("slack");
|
|
21
|
-
});
|
|
22
|
-
it("send before start() throws", async () => {
|
|
23
|
-
const a = new SlackAdapter({ bot_token: "xoxb-x", app_token: "xapp-x" });
|
|
24
|
-
await expect(a.send({ channel: "slack:C012345", text: "hi" })).rejects.toThrow(/not started/);
|
|
25
|
-
});
|
|
26
|
-
it("identity before start() throws", async () => {
|
|
27
|
-
const a = new SlackAdapter({ bot_token: "xoxb-x", app_token: "xapp-x" });
|
|
28
|
-
await expect(a.identity()).rejects.toThrow(/not started/);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Telegram adapter — long-polling via the official Bot API (v0.7a).
|
|
3
|
-
*
|
|
4
|
-
* SDK: `grammy` (modern, TS-first, actively maintained — recommended
|
|
5
|
-
* over `telegraf` which is frozen at v4.16 from Feb 2024 and over
|
|
6
|
-
* `node-telegram-bot-api` which is untyped).
|
|
7
|
-
*
|
|
8
|
-
* Connection: long-polling via `bot.start()` — no public webhook URL
|
|
9
|
-
* required. The bot opens an outbound HTTPS connection to
|
|
10
|
-
* `api.telegram.org` and polls for updates. Works behind any NAT.
|
|
11
|
-
*
|
|
12
|
-
* Why `grammy` is loaded via dynamic import: opensquid declares all
|
|
13
|
-
* three chat SDKs as optionalDependencies. Users with no Telegram
|
|
14
|
-
* config (and possibly `npm --omit=optional`) shouldn't pay the install
|
|
15
|
-
* cost. The dynamic import only runs in `start()` when this adapter
|
|
16
|
-
* is actually being activated — and produces a clear "install grammy"
|
|
17
|
-
* error if the dep is missing.
|
|
18
|
-
*
|
|
19
|
-
* Gotcha: only ONE polling consumer per token at a time. A second
|
|
20
|
-
* opensquid process with the same token will collide with 409 Conflict.
|
|
21
|
-
* Surface that error clearly on start.
|
|
22
|
-
*/
|
|
23
|
-
import { type ChatAdapter, type MessageHandler, type OutboundMessage, type SendResult } from "../gateway.js";
|
|
24
|
-
import type { TelegramConfig } from "../config.js";
|
|
25
|
-
export declare class TelegramAdapter implements ChatAdapter {
|
|
26
|
-
private readonly config;
|
|
27
|
-
readonly platform: "telegram";
|
|
28
|
-
private bot;
|
|
29
|
-
private handlers;
|
|
30
|
-
private botUsername;
|
|
31
|
-
private botId;
|
|
32
|
-
private startPromise;
|
|
33
|
-
/**
|
|
34
|
-
* 0.7.4 (#147): true when the long-poll lost to a 409 Conflict
|
|
35
|
-
* (another consumer holds the token — typically the Claude Code
|
|
36
|
-
* `plugin:telegram` bun bot). Outbound sendMessage still works via
|
|
37
|
-
* HTTPS, only inbound is dead. A periodic retry attempts to reclaim.
|
|
38
|
-
*/
|
|
39
|
-
private outboundOnly;
|
|
40
|
-
/** 0.7.4 (#147): handle for the periodic long-poll retry timer. */
|
|
41
|
-
private retryTimer;
|
|
42
|
-
/** Retry cadence — long enough that flapping doesn't burn API quota. */
|
|
43
|
-
private static readonly RETRY_INTERVAL_MS;
|
|
44
|
-
/**
|
|
45
|
-
* 0.5.90 (TG.3): chat_ids for which we've already logged an allowlist
|
|
46
|
-
* drop this process. The adapter silently drops messages from non-
|
|
47
|
-
* allowlisted chats (correct policy — never echo policy decisions back
|
|
48
|
-
* to the sender), but operators need a one-time-per-chat log line so
|
|
49
|
-
* they can diagnose "why isn't my message routing?" without reading
|
|
50
|
-
* source. Tracked as a Set keyed by chatIdStr; resets on restart.
|
|
51
|
-
*/
|
|
52
|
-
private allowlistDropLogged;
|
|
53
|
-
constructor(config: TelegramConfig);
|
|
54
|
-
start(): Promise<void>;
|
|
55
|
-
/**
|
|
56
|
-
* 0.7.4 (#147): handle a rejection from `bot.start()`. Extracted
|
|
57
|
-
* from inline catch handler so tests can simulate 409 without
|
|
58
|
-
* needing a live grammy + colliding bot. EXPORTED VIA PROTECTED for
|
|
59
|
-
* test-only direct invocation; not part of the public adapter API.
|
|
60
|
-
*/
|
|
61
|
-
handleStartRejection(err: unknown): void;
|
|
62
|
-
/**
|
|
63
|
-
* 0.7.4 (#147): test-only seed — install a fake bot reference + mark
|
|
64
|
-
* outbound-only so tests can verify isOutboundOnly() + retry timer
|
|
65
|
-
* without spinning up grammy. Must be called before any
|
|
66
|
-
* handleStartRejection in test context.
|
|
67
|
-
*/
|
|
68
|
-
_testSeed(fakeBot: any): void;
|
|
69
|
-
/**
|
|
70
|
-
* 0.7.4 (#147): test-only — clear the retry timer so tests don't
|
|
71
|
-
* leak intervals after a 409 simulation.
|
|
72
|
-
*/
|
|
73
|
-
_testClearRetryTimer(): void;
|
|
74
|
-
/**
|
|
75
|
-
* 0.7.4 (#147): periodically retry the long-poll while in outbound-
|
|
76
|
-
* only mode. If the competing consumer disconnects, we reclaim
|
|
77
|
-
* inbound transparently.
|
|
78
|
-
*/
|
|
79
|
-
private scheduleRetry;
|
|
80
|
-
private tryReclaim;
|
|
81
|
-
shutdown(): Promise<void>;
|
|
82
|
-
/**
|
|
83
|
-
* 0.7.4 (#147): introspection accessor for tests + the
|
|
84
|
-
* `chat_daemon_status` MCP tool to surface "outbound-only" state to
|
|
85
|
-
* operators trying to diagnose "where did my message go?"
|
|
86
|
-
*/
|
|
87
|
-
isOutboundOnly(): boolean;
|
|
88
|
-
onMessage(handler: MessageHandler): void;
|
|
89
|
-
send(message: OutboundMessage): Promise<SendResult>;
|
|
90
|
-
/**
|
|
91
|
-
* v0.7.2 — Create a forum topic in a supergroup. Requires the bot
|
|
92
|
-
* to be admin with "Manage Topics" permission and the supergroup to
|
|
93
|
-
* have Topics enabled in settings. Returns the topic's
|
|
94
|
-
* `message_thread_id` for storage in chat-routing.json.
|
|
95
|
-
*/
|
|
96
|
-
createTopic(chatId: string, name: string, options?: {
|
|
97
|
-
iconColor?: number;
|
|
98
|
-
iconCustomEmojiId?: string;
|
|
99
|
-
}): Promise<{
|
|
100
|
-
message_thread_id: number;
|
|
101
|
-
name: string;
|
|
102
|
-
}>;
|
|
103
|
-
identity(): Promise<{
|
|
104
|
-
username: string;
|
|
105
|
-
nativeId: string;
|
|
106
|
-
}>;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Parse a Telegram channel id (with optional embedded forum-topic
|
|
110
|
-
* thread id) into its native chat_id + message_thread_id parts.
|
|
111
|
-
*
|
|
112
|
-
* Wire format (canonical, mirrors `chat_poll_inbox` output):
|
|
113
|
-
* - `telegram:<chat_id>` → general topic, no thread
|
|
114
|
-
* - `telegram:<chat_id>:<thread_id>` → forum topic (supergroup with
|
|
115
|
-
* Topics enabled)
|
|
116
|
-
*
|
|
117
|
-
* Examples:
|
|
118
|
-
* - `telegram:-1001234567890` → `{ chatId: "-1001234567890" }`
|
|
119
|
-
* - `telegram:-1001234567890:15` → `{ chatId: "-1001234567890",
|
|
120
|
-
* threadId: "15" }`
|
|
121
|
-
* - `telegram:8075471258` → `{ chatId: "8075471258" }` (DM)
|
|
122
|
-
*
|
|
123
|
-
* Why the parser lives in the adapter (not in `gateway.ts`): Slack uses
|
|
124
|
-
* a different colon-in-native-id convention (`slack:C012345:1234.5678`
|
|
125
|
-
* where the trailing segment is `thread_ts`, an opaque part of the
|
|
126
|
-
* native id). Telegram's `<chat_id>:<thread_id>` semantic is
|
|
127
|
-
* platform-specific and shouldn't leak into the cross-platform
|
|
128
|
-
* `nativeIdFromChannel` helper.
|
|
129
|
-
*
|
|
130
|
-
* Exported for unit testing.
|
|
131
|
-
*/
|
|
132
|
-
export declare function parseTelegramChannel(channel: string): {
|
|
133
|
-
chatId: string;
|
|
134
|
-
threadId?: string;
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* Detect whether a message text contains an @-mention of this bot, or
|
|
138
|
-
* uses one of telegram's bot_command entities pointing at the bot
|
|
139
|
-
* (`/cmd@my_bot`).
|
|
140
|
-
*
|
|
141
|
-
* Exported for unit testing.
|
|
142
|
-
*/
|
|
143
|
-
export declare function detectBotMention(text: string, entities: Array<{
|
|
144
|
-
type: string;
|
|
145
|
-
offset: number;
|
|
146
|
-
length: number;
|
|
147
|
-
}> | undefined, botUsername: string): boolean;
|
|
148
|
-
//# sourceMappingURL=telegram.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../../src.legacy/chat/adapters/telegram.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,UAAU,EAEhB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AA0CnD,qBAAa,eAAgB,YAAW,WAAW;IA6BrC,OAAO,CAAC,QAAQ,CAAC,MAAM;IA5BnC,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,YAAY,CAA8B;IAClD;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAAS;IAC7B,mEAAmE;IACnE,OAAO,CAAC,UAAU,CAA+B;IACjD,wEAAwE;IACxE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IACnD;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB,CAAqB;gBAEnB,MAAM,EAAE,cAAc;IAS7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4F5B;;;;;OAKG;IACH,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAmBxC;;;;;OAKG;IAEH,SAAS,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAI7B;;;OAGG;IACH,oBAAoB,IAAI,IAAI;IAO5B;;;;OAIG;IACH,OAAO,CAAC,aAAa;YAOP,UAAU;IA2ClB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB/B;;;;OAIG;IACH,cAAc,IAAI,OAAO;IAIzB,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIlC,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IA+BzD;;;;;OAKG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/D,OAAO,CAAC;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAejD,QAAQ,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAMlE;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAqCA;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,EAC7E,WAAW,EAAE,MAAM,GAClB,OAAO,CAWT"}
|