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
package/dist/chat/env-token.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Telegram / Discord / Slack bot-token loading from env var + .env
|
|
3
|
-
* file (0.7.5+, #148).
|
|
4
|
-
*
|
|
5
|
-
* Priority (highest first):
|
|
6
|
-
* 1. process.env.OPENSQUID_TELEGRAM_BOT_TOKEN (or _DISCORD_, _SLACK_)
|
|
7
|
-
* 2. .env file (first match wins):
|
|
8
|
-
* - $OPENSQUID_ENV_FILE
|
|
9
|
-
* - ~/.loop/.env
|
|
10
|
-
* - ~/.opensquid/.env
|
|
11
|
-
* - <cwd>/.env
|
|
12
|
-
* 3. ~/.opensquid/config.json chat_connections.<platform>.bot_token
|
|
13
|
-
*
|
|
14
|
-
* The .env parser supports standard KEY=VALUE lines AND a tolerant
|
|
15
|
-
* "bare token" fallback (single non-comment line, no `=`) — the user
|
|
16
|
-
* may save just the token. Bare tokens are treated as
|
|
17
|
-
* OPENSQUID_TELEGRAM_BOT_TOKEN.
|
|
18
|
-
*
|
|
19
|
-
* NEVER logs the token value. Only logs which SOURCE the active token
|
|
20
|
-
* came from, so operators can debug "which bot is this daemon
|
|
21
|
-
* actually using" without leaking the secret.
|
|
22
|
-
*/
|
|
23
|
-
export type EnvKey = "OPENSQUID_TELEGRAM_BOT_TOKEN" | "OPENSQUID_DISCORD_BOT_TOKEN" | "OPENSQUID_SLACK_BOT_TOKEN" | "OPENSQUID_SLACK_APP_TOKEN";
|
|
24
|
-
export type EnvSource = "env" | "env-file" | "config-json" | "missing";
|
|
25
|
-
export interface TokenLookup {
|
|
26
|
-
value: string | undefined;
|
|
27
|
-
source: EnvSource;
|
|
28
|
-
/** Path to the .env file used (only set when source === "env-file"). */
|
|
29
|
-
env_file_path?: string;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Resolve a token by priority: process.env → .env file → config.json
|
|
33
|
-
* fallback (caller-supplied). Returns the value AND the source it
|
|
34
|
-
* came from so the caller can log the source without exposing the
|
|
35
|
-
* value.
|
|
36
|
-
*/
|
|
37
|
-
export declare function resolveToken(key: EnvKey, configJsonFallback: string | undefined): Promise<TokenLookup>;
|
|
38
|
-
/**
|
|
39
|
-
* Find the first existing .env file in the search order. Returns null
|
|
40
|
-
* if none exist.
|
|
41
|
-
*/
|
|
42
|
-
export declare function locateEnvFile(): Promise<string | null>;
|
|
43
|
-
/**
|
|
44
|
-
* Parse a .env file into a flat string map. Supports:
|
|
45
|
-
*
|
|
46
|
-
* - `KEY=VALUE` lines (standard dotenv format)
|
|
47
|
-
* - `KEY="quoted value"` (double-quoted)
|
|
48
|
-
* - `KEY='quoted value'` (single-quoted)
|
|
49
|
-
* - `#` comments + blank lines
|
|
50
|
-
* - Bare-token fallback: if the file has exactly ONE non-comment
|
|
51
|
-
* line and that line has no `=`, treat it as
|
|
52
|
-
* OPENSQUID_TELEGRAM_BOT_TOKEN (most common shape for "user
|
|
53
|
-
* saved just the token")
|
|
54
|
-
*
|
|
55
|
-
* Caches by path to avoid re-reading on every call.
|
|
56
|
-
*/
|
|
57
|
-
export declare function loadEnvFile(envPath: string): Promise<Record<string, string>>;
|
|
58
|
-
/** Test-only: clear the .env cache so subsequent loads re-read disk. */
|
|
59
|
-
export declare function _clearEnvFileCache(): void;
|
|
60
|
-
//# sourceMappingURL=env-token.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env-token.d.ts","sourceRoot":"","sources":["../../src.legacy/chat/env-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,MAAM,MAAM,MAAM,GACd,8BAA8B,GAC9B,6BAA6B,GAC7B,2BAA2B,GAC3B,2BAA2B,CAAC;AAEhC,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,SAAS,CAAC;IAClB,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAKD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,GAAG,SAAS,GACrC,OAAO,CAAC,WAAW,CAAC,CAuBtB;AAED;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwClF;AAED,wEAAwE;AACxE,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
package/dist/chat/env-token.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Telegram / Discord / Slack bot-token loading from env var + .env
|
|
3
|
-
* file (0.7.5+, #148).
|
|
4
|
-
*
|
|
5
|
-
* Priority (highest first):
|
|
6
|
-
* 1. process.env.OPENSQUID_TELEGRAM_BOT_TOKEN (or _DISCORD_, _SLACK_)
|
|
7
|
-
* 2. .env file (first match wins):
|
|
8
|
-
* - $OPENSQUID_ENV_FILE
|
|
9
|
-
* - ~/.loop/.env
|
|
10
|
-
* - ~/.opensquid/.env
|
|
11
|
-
* - <cwd>/.env
|
|
12
|
-
* 3. ~/.opensquid/config.json chat_connections.<platform>.bot_token
|
|
13
|
-
*
|
|
14
|
-
* The .env parser supports standard KEY=VALUE lines AND a tolerant
|
|
15
|
-
* "bare token" fallback (single non-comment line, no `=`) — the user
|
|
16
|
-
* may save just the token. Bare tokens are treated as
|
|
17
|
-
* OPENSQUID_TELEGRAM_BOT_TOKEN.
|
|
18
|
-
*
|
|
19
|
-
* NEVER logs the token value. Only logs which SOURCE the active token
|
|
20
|
-
* came from, so operators can debug "which bot is this daemon
|
|
21
|
-
* actually using" without leaking the secret.
|
|
22
|
-
*/
|
|
23
|
-
import { promises as fs } from "node:fs";
|
|
24
|
-
import * as os from "node:os";
|
|
25
|
-
import * as path from "node:path";
|
|
26
|
-
/** In-memory cache for parsed .env files. Invalidated on each new process. */
|
|
27
|
-
let envFileCache = null;
|
|
28
|
-
/**
|
|
29
|
-
* Resolve a token by priority: process.env → .env file → config.json
|
|
30
|
-
* fallback (caller-supplied). Returns the value AND the source it
|
|
31
|
-
* came from so the caller can log the source without exposing the
|
|
32
|
-
* value.
|
|
33
|
-
*/
|
|
34
|
-
export async function resolveToken(key, configJsonFallback) {
|
|
35
|
-
// 1. process.env
|
|
36
|
-
const envVal = process.env[key];
|
|
37
|
-
if (envVal && envVal.trim()) {
|
|
38
|
-
return { value: envVal.trim(), source: "env" };
|
|
39
|
-
}
|
|
40
|
-
// 2. .env file
|
|
41
|
-
const envFile = await locateEnvFile();
|
|
42
|
-
if (envFile) {
|
|
43
|
-
const parsed = await loadEnvFile(envFile);
|
|
44
|
-
const fileVal = parsed[key];
|
|
45
|
-
if (fileVal && fileVal.trim()) {
|
|
46
|
-
return { value: fileVal.trim(), source: "env-file", env_file_path: envFile };
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// 3. config.json fallback
|
|
50
|
-
if (configJsonFallback && configJsonFallback.trim()) {
|
|
51
|
-
return { value: configJsonFallback.trim(), source: "config-json" };
|
|
52
|
-
}
|
|
53
|
-
return { value: undefined, source: "missing" };
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Find the first existing .env file in the search order. Returns null
|
|
57
|
-
* if none exist.
|
|
58
|
-
*/
|
|
59
|
-
export async function locateEnvFile() {
|
|
60
|
-
const candidates = [];
|
|
61
|
-
if (process.env.OPENSQUID_ENV_FILE)
|
|
62
|
-
candidates.push(process.env.OPENSQUID_ENV_FILE);
|
|
63
|
-
const home = os.homedir();
|
|
64
|
-
candidates.push(path.join(home, ".loop", ".env"));
|
|
65
|
-
candidates.push(path.join(home, ".opensquid", ".env"));
|
|
66
|
-
candidates.push(path.join(process.cwd(), ".env"));
|
|
67
|
-
for (const c of candidates) {
|
|
68
|
-
try {
|
|
69
|
-
await fs.access(c);
|
|
70
|
-
return c;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
// not present, keep looking
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Parse a .env file into a flat string map. Supports:
|
|
80
|
-
*
|
|
81
|
-
* - `KEY=VALUE` lines (standard dotenv format)
|
|
82
|
-
* - `KEY="quoted value"` (double-quoted)
|
|
83
|
-
* - `KEY='quoted value'` (single-quoted)
|
|
84
|
-
* - `#` comments + blank lines
|
|
85
|
-
* - Bare-token fallback: if the file has exactly ONE non-comment
|
|
86
|
-
* line and that line has no `=`, treat it as
|
|
87
|
-
* OPENSQUID_TELEGRAM_BOT_TOKEN (most common shape for "user
|
|
88
|
-
* saved just the token")
|
|
89
|
-
*
|
|
90
|
-
* Caches by path to avoid re-reading on every call.
|
|
91
|
-
*/
|
|
92
|
-
export async function loadEnvFile(envPath) {
|
|
93
|
-
if (envFileCache && envFileCache.path === envPath) {
|
|
94
|
-
return envFileCache.parsed;
|
|
95
|
-
}
|
|
96
|
-
const raw = await fs.readFile(envPath, "utf8");
|
|
97
|
-
const lines = raw.split(/\r?\n/);
|
|
98
|
-
const out = {};
|
|
99
|
-
const nonComment = [];
|
|
100
|
-
for (const line of lines) {
|
|
101
|
-
const trimmed = line.trim();
|
|
102
|
-
if (!trimmed || trimmed.startsWith("#"))
|
|
103
|
-
continue;
|
|
104
|
-
nonComment.push(trimmed);
|
|
105
|
-
}
|
|
106
|
-
let hadKeyValue = false;
|
|
107
|
-
for (const line of nonComment) {
|
|
108
|
-
const eq = line.indexOf("=");
|
|
109
|
-
if (eq === -1)
|
|
110
|
-
continue;
|
|
111
|
-
hadKeyValue = true;
|
|
112
|
-
const key = line.slice(0, eq).trim();
|
|
113
|
-
let value = line.slice(eq + 1).trim();
|
|
114
|
-
// Strip surrounding quotes (single or double).
|
|
115
|
-
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
116
|
-
(value.startsWith("'") && value.endsWith("'"))) {
|
|
117
|
-
value = value.slice(1, -1);
|
|
118
|
-
}
|
|
119
|
-
if (key)
|
|
120
|
-
out[key] = value;
|
|
121
|
-
}
|
|
122
|
-
// Bare-token fallback: exactly one non-comment line, no =, looks
|
|
123
|
-
// like a Telegram bot token. Treat as OPENSQUID_TELEGRAM_BOT_TOKEN.
|
|
124
|
-
if (!hadKeyValue && nonComment.length === 1) {
|
|
125
|
-
const bare = nonComment[0];
|
|
126
|
-
// Telegram tokens look like <digits>:<alphanum_-> (47+ chars total).
|
|
127
|
-
if (/^\d+:[A-Za-z0-9_-]{20,}$/.test(bare)) {
|
|
128
|
-
out.OPENSQUID_TELEGRAM_BOT_TOKEN = bare;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
envFileCache = { path: envPath, parsed: out };
|
|
132
|
-
return out;
|
|
133
|
-
}
|
|
134
|
-
/** Test-only: clear the .env cache so subsequent loads re-read disk. */
|
|
135
|
-
export function _clearEnvFileCache() {
|
|
136
|
-
envFileCache = null;
|
|
137
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"env-token.js","sourceRoot":"","sources":["../../src.legacy/chat/env-token.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* env-token.ts tests (#148): priority + .env parsing.
|
|
3
|
-
*/
|
|
4
|
-
import { promises as fs } from "node:fs";
|
|
5
|
-
import * as os from "node:os";
|
|
6
|
-
import * as path from "node:path";
|
|
7
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
8
|
-
import { _clearEnvFileCache, loadEnvFile, locateEnvFile, resolveToken } from "./env-token.js";
|
|
9
|
-
let tmpDir;
|
|
10
|
-
const SAVED_ENV = {};
|
|
11
|
-
function saveEnv(...keys) {
|
|
12
|
-
for (const k of keys)
|
|
13
|
-
SAVED_ENV[k] = process.env[k];
|
|
14
|
-
}
|
|
15
|
-
function restoreEnv() {
|
|
16
|
-
for (const [k, v] of Object.entries(SAVED_ENV)) {
|
|
17
|
-
if (v === undefined)
|
|
18
|
-
delete process.env[k];
|
|
19
|
-
else
|
|
20
|
-
process.env[k] = v;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
beforeEach(async () => {
|
|
24
|
-
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "opensquid-envtoken-"));
|
|
25
|
-
saveEnv("OPENSQUID_TELEGRAM_BOT_TOKEN", "OPENSQUID_DISCORD_BOT_TOKEN", "OPENSQUID_SLACK_BOT_TOKEN", "OPENSQUID_SLACK_APP_TOKEN", "OPENSQUID_ENV_FILE", "HOME");
|
|
26
|
-
// Wipe inherited values so tests run from a known empty state.
|
|
27
|
-
delete process.env.OPENSQUID_TELEGRAM_BOT_TOKEN;
|
|
28
|
-
delete process.env.OPENSQUID_DISCORD_BOT_TOKEN;
|
|
29
|
-
delete process.env.OPENSQUID_SLACK_BOT_TOKEN;
|
|
30
|
-
delete process.env.OPENSQUID_SLACK_APP_TOKEN;
|
|
31
|
-
delete process.env.OPENSQUID_ENV_FILE;
|
|
32
|
-
// Override HOME so the .env candidate paths (~/.loop/.env etc) point
|
|
33
|
-
// at the empty tmpdir, not the real home directory where the user
|
|
34
|
-
// may have a real .env that would taint the test.
|
|
35
|
-
process.env.HOME = tmpDir;
|
|
36
|
-
_clearEnvFileCache();
|
|
37
|
-
});
|
|
38
|
-
afterEach(async () => {
|
|
39
|
-
restoreEnv();
|
|
40
|
-
_clearEnvFileCache();
|
|
41
|
-
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
42
|
-
});
|
|
43
|
-
describe("loadEnvFile — parsing", () => {
|
|
44
|
-
it("parses standard KEY=VALUE lines", async () => {
|
|
45
|
-
const p = path.join(tmpDir, ".env");
|
|
46
|
-
await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=1234:abcdef\nSOMETHING_ELSE=value\n");
|
|
47
|
-
const parsed = await loadEnvFile(p);
|
|
48
|
-
expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBe("1234:abcdef");
|
|
49
|
-
expect(parsed.SOMETHING_ELSE).toBe("value");
|
|
50
|
-
});
|
|
51
|
-
it("strips surrounding double quotes", async () => {
|
|
52
|
-
const p = path.join(tmpDir, ".env");
|
|
53
|
-
await fs.writeFile(p, 'KEY="quoted value with spaces"\n');
|
|
54
|
-
const parsed = await loadEnvFile(p);
|
|
55
|
-
expect(parsed.KEY).toBe("quoted value with spaces");
|
|
56
|
-
});
|
|
57
|
-
it("strips surrounding single quotes", async () => {
|
|
58
|
-
const p = path.join(tmpDir, ".env");
|
|
59
|
-
await fs.writeFile(p, "KEY='quoted value'\n");
|
|
60
|
-
const parsed = await loadEnvFile(p);
|
|
61
|
-
expect(parsed.KEY).toBe("quoted value");
|
|
62
|
-
});
|
|
63
|
-
it("ignores blank lines and # comments", async () => {
|
|
64
|
-
const p = path.join(tmpDir, ".env");
|
|
65
|
-
await fs.writeFile(p, "# top comment\n\nKEY=value\n# trailing comment\n");
|
|
66
|
-
const parsed = await loadEnvFile(p);
|
|
67
|
-
expect(parsed).toEqual({ KEY: "value" });
|
|
68
|
-
});
|
|
69
|
-
it("treats a single bare Telegram-token line as OPENSQUID_TELEGRAM_BOT_TOKEN", async () => {
|
|
70
|
-
const p = path.join(tmpDir, ".env");
|
|
71
|
-
await fs.writeFile(p, "8684088310:AAFgYblhOAadDN_i5osTtfkSTAgwlnneU-4\n");
|
|
72
|
-
const parsed = await loadEnvFile(p);
|
|
73
|
-
expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBe("8684088310:AAFgYblhOAadDN_i5osTtfkSTAgwlnneU-4");
|
|
74
|
-
});
|
|
75
|
-
it("does NOT treat a bare line as a token if it doesn't match the token shape", async () => {
|
|
76
|
-
const p = path.join(tmpDir, ".env");
|
|
77
|
-
await fs.writeFile(p, "just-some-random-text\n");
|
|
78
|
-
const parsed = await loadEnvFile(p);
|
|
79
|
-
expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBeUndefined();
|
|
80
|
-
});
|
|
81
|
-
it("does NOT use bare-line fallback if KEY=VALUE lines are also present", async () => {
|
|
82
|
-
const p = path.join(tmpDir, ".env");
|
|
83
|
-
await fs.writeFile(p, "OTHER=ok\n1234:abcdefghij1234567890\n");
|
|
84
|
-
const parsed = await loadEnvFile(p);
|
|
85
|
-
expect(parsed.OPENSQUID_TELEGRAM_BOT_TOKEN).toBeUndefined();
|
|
86
|
-
expect(parsed.OTHER).toBe("ok");
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
describe("locateEnvFile — search order", () => {
|
|
90
|
-
it("returns the path given by OPENSQUID_ENV_FILE if it exists", async () => {
|
|
91
|
-
const p = path.join(tmpDir, "custom.env");
|
|
92
|
-
await fs.writeFile(p, "KEY=value\n");
|
|
93
|
-
process.env.OPENSQUID_ENV_FILE = p;
|
|
94
|
-
expect(await locateEnvFile()).toBe(p);
|
|
95
|
-
});
|
|
96
|
-
it("returns null if no .env exists in any candidate location", async () => {
|
|
97
|
-
// Override HOME so the function looks at our empty tmpDir
|
|
98
|
-
const savedHome = process.env.HOME;
|
|
99
|
-
process.env.HOME = tmpDir;
|
|
100
|
-
try {
|
|
101
|
-
const r = await locateEnvFile();
|
|
102
|
-
// Could still hit a cwd .env in the actual project — accept that
|
|
103
|
-
// and only assert null when no env file at all.
|
|
104
|
-
if (r) {
|
|
105
|
-
expect(r).not.toBe(path.join(tmpDir, ".loop", ".env"));
|
|
106
|
-
expect(r).not.toBe(path.join(tmpDir, ".opensquid", ".env"));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
finally {
|
|
110
|
-
if (savedHome)
|
|
111
|
-
process.env.HOME = savedHome;
|
|
112
|
-
else
|
|
113
|
-
delete process.env.HOME;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
describe("resolveToken — priority order", () => {
|
|
118
|
-
it("returns env-var value with source='env' when set", async () => {
|
|
119
|
-
process.env.OPENSQUID_TELEGRAM_BOT_TOKEN = "from-env";
|
|
120
|
-
const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
|
|
121
|
-
expect(r.value).toBe("from-env");
|
|
122
|
-
expect(r.source).toBe("env");
|
|
123
|
-
});
|
|
124
|
-
it("falls back to .env file when env-var unset", async () => {
|
|
125
|
-
const p = path.join(tmpDir, ".env");
|
|
126
|
-
await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=from-file\n");
|
|
127
|
-
process.env.OPENSQUID_ENV_FILE = p;
|
|
128
|
-
const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
|
|
129
|
-
expect(r.value).toBe("from-file");
|
|
130
|
-
expect(r.source).toBe("env-file");
|
|
131
|
-
expect(r.env_file_path).toBe(p);
|
|
132
|
-
});
|
|
133
|
-
it("falls back to config.json value when neither env-var nor .env set", async () => {
|
|
134
|
-
const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
|
|
135
|
-
expect(r.value).toBe("from-config");
|
|
136
|
-
expect(r.source).toBe("config-json");
|
|
137
|
-
});
|
|
138
|
-
it("returns missing when no source has a value", async () => {
|
|
139
|
-
const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", undefined);
|
|
140
|
-
expect(r.value).toBeUndefined();
|
|
141
|
-
expect(r.source).toBe("missing");
|
|
142
|
-
});
|
|
143
|
-
it("env-var WINS over .env even when both are set", async () => {
|
|
144
|
-
process.env.OPENSQUID_TELEGRAM_BOT_TOKEN = "from-env";
|
|
145
|
-
const p = path.join(tmpDir, ".env");
|
|
146
|
-
await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=from-file\n");
|
|
147
|
-
process.env.OPENSQUID_ENV_FILE = p;
|
|
148
|
-
const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
|
|
149
|
-
expect(r.value).toBe("from-env");
|
|
150
|
-
expect(r.source).toBe("env");
|
|
151
|
-
});
|
|
152
|
-
it(".env WINS over config.json even when both have values", async () => {
|
|
153
|
-
const p = path.join(tmpDir, ".env");
|
|
154
|
-
await fs.writeFile(p, "OPENSQUID_TELEGRAM_BOT_TOKEN=from-file\n");
|
|
155
|
-
process.env.OPENSQUID_ENV_FILE = p;
|
|
156
|
-
const r = await resolveToken("OPENSQUID_TELEGRAM_BOT_TOKEN", "from-config");
|
|
157
|
-
expect(r.value).toBe("from-file");
|
|
158
|
-
expect(r.source).toBe("env-file");
|
|
159
|
-
});
|
|
160
|
-
});
|
package/dist/chat/factory.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Build a ChatGateway from `~/.opensquid/config.json`'s
|
|
3
|
-
* `chat_connections` block. Skips adapters whose tokens are missing —
|
|
4
|
-
* opensquid works with zero, one, or all three chat platforms wired.
|
|
5
|
-
*
|
|
6
|
-
* Per-platform adapter modules (telegram/discord/slack) are imported
|
|
7
|
-
* dynamically here so the factory doesn't pull all three SDK trees
|
|
8
|
-
* into the cold-start path. Each adapter's own dynamic-import of its
|
|
9
|
-
* SDK runs only inside `.start()`.
|
|
10
|
-
*/
|
|
11
|
-
import { ChatGateway } from "./gateway.js";
|
|
12
|
-
import type { ChatConnectionsConfig } from "./config.js";
|
|
13
|
-
export interface BuildOptions {
|
|
14
|
-
dataRoot?: string;
|
|
15
|
-
/** Inject a pre-loaded config (skips disk read). For tests. */
|
|
16
|
-
config?: ChatConnectionsConfig;
|
|
17
|
-
}
|
|
18
|
-
export interface BuildResult {
|
|
19
|
-
gateway: ChatGateway;
|
|
20
|
-
/** Platforms that ended up in the gateway. */
|
|
21
|
-
activated: Array<"telegram" | "discord" | "slack">;
|
|
22
|
-
/** Validation issues — surfaced but non-fatal for partial activation. */
|
|
23
|
-
issues: Array<{
|
|
24
|
-
platform: string;
|
|
25
|
-
field: string;
|
|
26
|
-
problem: string;
|
|
27
|
-
}>;
|
|
28
|
-
}
|
|
29
|
-
export declare function buildChatGateway(opts?: BuildOptions): Promise<BuildResult>;
|
|
30
|
-
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src.legacy/chat/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,WAAW,EAAoB,MAAM,cAAc,CAAC;AAE7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,8CAA8C;IAC9C,SAAS,EAAE,KAAK,CAAC,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACnD,yEAAyE;IACzE,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CA+CpF"}
|
package/dist/chat/factory.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Build a ChatGateway from `~/.opensquid/config.json`'s
|
|
3
|
-
* `chat_connections` block. Skips adapters whose tokens are missing —
|
|
4
|
-
* opensquid works with zero, one, or all three chat platforms wired.
|
|
5
|
-
*
|
|
6
|
-
* Per-platform adapter modules (telegram/discord/slack) are imported
|
|
7
|
-
* dynamically here so the factory doesn't pull all three SDK trees
|
|
8
|
-
* into the cold-start path. Each adapter's own dynamic-import of its
|
|
9
|
-
* SDK runs only inside `.start()`.
|
|
10
|
-
*/
|
|
11
|
-
import { ChatGateway, ChatGatewayError } from "./gateway.js";
|
|
12
|
-
import { loadChatConfig, validateChatConfig } from "./config.js";
|
|
13
|
-
export async function buildChatGateway(opts = {}) {
|
|
14
|
-
const config = opts.config ?? (await loadChatConfig(opts.dataRoot));
|
|
15
|
-
const issues = validateChatConfig(config);
|
|
16
|
-
const adapters = [];
|
|
17
|
-
const activated = [];
|
|
18
|
-
// Each block: only activate if (a) config block exists AND (b) no
|
|
19
|
-
// validation issue against this platform's tokens. An issue here
|
|
20
|
-
// means the user has a partial config (e.g. typo'd token) — better
|
|
21
|
-
// to skip with a logged warning than throw and prevent the other
|
|
22
|
-
// adapters from working.
|
|
23
|
-
if (config.telegram && !issues.some((i) => i.platform === "telegram")) {
|
|
24
|
-
const { TelegramAdapter } = await import("./adapters/telegram.js");
|
|
25
|
-
adapters.push(new TelegramAdapter(config.telegram));
|
|
26
|
-
activated.push("telegram");
|
|
27
|
-
}
|
|
28
|
-
if (config.discord && !issues.some((i) => i.platform === "discord")) {
|
|
29
|
-
const { DiscordAdapter } = await import("./adapters/discord.js");
|
|
30
|
-
adapters.push(new DiscordAdapter(config.discord));
|
|
31
|
-
activated.push("discord");
|
|
32
|
-
}
|
|
33
|
-
if (config.slack && !issues.some((i) => i.platform === "slack")) {
|
|
34
|
-
const { SlackAdapter } = await import("./adapters/slack.js");
|
|
35
|
-
adapters.push(new SlackAdapter(config.slack));
|
|
36
|
-
activated.push("slack");
|
|
37
|
-
}
|
|
38
|
-
// Throw when the user clearly mis-configured a token. All three
|
|
39
|
-
// platforms are now implemented (v0.7c), so any validation issue
|
|
40
|
-
// against a configured platform is a real problem.
|
|
41
|
-
const blockingIssues = issues.filter((i) => (i.platform === "telegram" && !!config.telegram) ||
|
|
42
|
-
(i.platform === "discord" && !!config.discord) ||
|
|
43
|
-
(i.platform === "slack" && !!config.slack));
|
|
44
|
-
if (blockingIssues.length > 0 && adapters.length === 0) {
|
|
45
|
-
throw new ChatGatewayError("chat connections configured but failed validation — see issues", `validation: ${blockingIssues
|
|
46
|
-
.map((i) => `${i.platform}.${i.field}: ${i.problem}`)
|
|
47
|
-
.join("; ")}`);
|
|
48
|
-
}
|
|
49
|
-
return { gateway: new ChatGateway(adapters), activated, issues };
|
|
50
|
-
}
|
package/dist/chat/factory.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src.legacy/chat/factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { ChatGatewayError } from "./gateway.js";
|
|
3
|
-
import { buildChatGateway } from "./factory.js";
|
|
4
|
-
describe("buildChatGateway", () => {
|
|
5
|
-
it("returns an empty gateway when no chat config is present", async () => {
|
|
6
|
-
const result = await buildChatGateway({ config: {} });
|
|
7
|
-
expect(result.activated).toEqual([]);
|
|
8
|
-
expect(result.gateway.activePlatforms()).toEqual([]);
|
|
9
|
-
expect(result.issues).toEqual([]);
|
|
10
|
-
});
|
|
11
|
-
it("v0.7c: activates all three platforms when all are validly configured", async () => {
|
|
12
|
-
const result = await buildChatGateway({
|
|
13
|
-
config: {
|
|
14
|
-
telegram: { bot_token: "123456:ABC-DEF1234" },
|
|
15
|
-
discord: { bot_token: "MTAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
|
|
16
|
-
slack: { bot_token: "xoxb-1-2-3", app_token: "xapp-1-2-3" },
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
expect(result.activated.sort()).toEqual(["discord", "slack", "telegram"]);
|
|
20
|
-
});
|
|
21
|
-
it("v0.7c: activates discord + slack independently of telegram", async () => {
|
|
22
|
-
const result = await buildChatGateway({
|
|
23
|
-
config: {
|
|
24
|
-
discord: { bot_token: "MTAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
|
|
25
|
-
slack: { bot_token: "xoxb-1-2-3", app_token: "xapp-1-2-3" },
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
expect(result.activated.sort()).toEqual(["discord", "slack"]);
|
|
29
|
-
});
|
|
30
|
-
it("activates telegram when its config block is valid", async () => {
|
|
31
|
-
const result = await buildChatGateway({
|
|
32
|
-
config: { telegram: { bot_token: "123456:ABC-DEF1234" } },
|
|
33
|
-
});
|
|
34
|
-
expect(result.activated).toEqual(["telegram"]);
|
|
35
|
-
expect(result.gateway.activePlatforms()).toEqual(["telegram"]);
|
|
36
|
-
});
|
|
37
|
-
it("skips telegram with invalid token format AND throws because no other adapter activated", async () => {
|
|
38
|
-
await expect(buildChatGateway({
|
|
39
|
-
config: { telegram: { bot_token: "not-a-real-format" } },
|
|
40
|
-
})).rejects.toThrow(ChatGatewayError);
|
|
41
|
-
});
|
|
42
|
-
it("partial config: telegram valid + slack invalid → telegram activates, slack issue logged", async () => {
|
|
43
|
-
const warn = vi.spyOn(console, "warn").mockImplementation(() => { });
|
|
44
|
-
const result = await buildChatGateway({
|
|
45
|
-
config: {
|
|
46
|
-
telegram: { bot_token: "123456:ABC-DEF1234" },
|
|
47
|
-
// slack with wrong-shape tokens triggers validation issues
|
|
48
|
-
slack: { bot_token: "wrong-prefix", app_token: "also-wrong" },
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
expect(result.activated).toEqual(["telegram"]);
|
|
52
|
-
expect(result.issues.find((i) => i.platform === "slack")).toBeTruthy();
|
|
53
|
-
warn.mockRestore();
|
|
54
|
-
});
|
|
55
|
-
});
|