opensquid 0.5.441 → 0.5.447
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/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_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/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,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RPC server + client integration tests (v0.7.1 Phase B).
|
|
3
|
-
*
|
|
4
|
-
* Exercise the full wire path: real Unix socket / named pipe, real
|
|
5
|
-
* JSON-RPC framing, real client → server round-trip. Stubs the gateway
|
|
6
|
-
* with a tiny fake so the test doesn't need bot tokens. The protocol
|
|
7
|
-
* IS the contract here, so synthetic transport would prove nothing.
|
|
8
|
-
*/
|
|
9
|
-
import { promises as fs } from "node:fs";
|
|
10
|
-
import * as os from "node:os";
|
|
11
|
-
import * as path from "node:path";
|
|
12
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
13
|
-
import { ChatGateway } from "../gateway.js";
|
|
14
|
-
import { DaemonClient, DaemonRpcError, DaemonUnreachableError } from "./rpc-client.js";
|
|
15
|
-
import { daemonSockAddress } from "./protocol.js";
|
|
16
|
-
import { RpcServer } from "./rpc-server.js";
|
|
17
|
-
class StubAdapter {
|
|
18
|
-
platform;
|
|
19
|
-
constructor(platform) {
|
|
20
|
-
this.platform = platform;
|
|
21
|
-
}
|
|
22
|
-
start() {
|
|
23
|
-
return Promise.resolve();
|
|
24
|
-
}
|
|
25
|
-
shutdown() {
|
|
26
|
-
return Promise.resolve();
|
|
27
|
-
}
|
|
28
|
-
onMessage(_) {
|
|
29
|
-
/* noop */
|
|
30
|
-
}
|
|
31
|
-
send(msg) {
|
|
32
|
-
return Promise.resolve({
|
|
33
|
-
platform: this.platform,
|
|
34
|
-
channel: msg.channel,
|
|
35
|
-
messageId: `stub-${Date.now()}`,
|
|
36
|
-
deliveredAt: new Date(),
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
identity() {
|
|
40
|
-
return Promise.resolve({ username: `stub-${this.platform}`, nativeId: "0" });
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
let tmpRoot;
|
|
44
|
-
let server;
|
|
45
|
-
let prevOpensquidHome;
|
|
46
|
-
beforeEach(async () => {
|
|
47
|
-
tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "opensquid-rpc-test-"));
|
|
48
|
-
// The protocol's address calculation looks at process.env.OPENSQUID_HOME
|
|
49
|
-
// via daemonPaths → resolveDataRoot. Set it for the duration of the
|
|
50
|
-
// test so the client and server resolve the same address.
|
|
51
|
-
prevOpensquidHome = process.env.OPENSQUID_HOME;
|
|
52
|
-
process.env.OPENSQUID_HOME = tmpRoot;
|
|
53
|
-
});
|
|
54
|
-
afterEach(async () => {
|
|
55
|
-
if (server) {
|
|
56
|
-
try {
|
|
57
|
-
await server.close();
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
/* ignore */
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (prevOpensquidHome === undefined)
|
|
64
|
-
delete process.env.OPENSQUID_HOME;
|
|
65
|
-
else
|
|
66
|
-
process.env.OPENSQUID_HOME = prevOpensquidHome;
|
|
67
|
-
await fs.rm(tmpRoot, { recursive: true, force: true });
|
|
68
|
-
});
|
|
69
|
-
describe("daemonSockAddress", () => {
|
|
70
|
-
it("returns a filesystem path on POSIX, named pipe on Windows", () => {
|
|
71
|
-
const addr = daemonSockAddress(tmpRoot);
|
|
72
|
-
if (os.platform() === "win32") {
|
|
73
|
-
expect(addr).toMatch(/^\\\\\.\\pipe\\opensquid-chat-daemon-/);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
expect(addr).toBe(path.join(tmpRoot, "chat-daemon.sock"));
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
describe("RpcServer + DaemonClient round-trip", () => {
|
|
81
|
-
it("ping returns pong, pid, and version", async () => {
|
|
82
|
-
const gw = new ChatGateway([new StubAdapter("telegram")]);
|
|
83
|
-
await gw.start();
|
|
84
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot, version: "test-v1" });
|
|
85
|
-
await server.listen();
|
|
86
|
-
const client = new DaemonClient({ dataRoot: tmpRoot });
|
|
87
|
-
const res = await client.ping();
|
|
88
|
-
expect(res.pong).toBe(true);
|
|
89
|
-
expect(res.pid).toBe(process.pid);
|
|
90
|
-
expect(res.version).toBe("test-v1");
|
|
91
|
-
});
|
|
92
|
-
it("list_channels surfaces the gateway's active platforms", async () => {
|
|
93
|
-
const gw = new ChatGateway([new StubAdapter("telegram"), new StubAdapter("discord")]);
|
|
94
|
-
await gw.start();
|
|
95
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot });
|
|
96
|
-
await server.listen();
|
|
97
|
-
const client = new DaemonClient({ dataRoot: tmpRoot });
|
|
98
|
-
const res = await client.listChannels();
|
|
99
|
-
expect(res.active_platforms).toEqual(expect.arrayContaining(["telegram", "discord"]));
|
|
100
|
-
expect(res.uptime_ms).toBeGreaterThanOrEqual(0);
|
|
101
|
-
});
|
|
102
|
-
it("send delegates to gateway.send and returns the message id + delivery time", async () => {
|
|
103
|
-
const gw = new ChatGateway([new StubAdapter("telegram")]);
|
|
104
|
-
await gw.start();
|
|
105
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot });
|
|
106
|
-
await server.listen();
|
|
107
|
-
const client = new DaemonClient({ dataRoot: tmpRoot });
|
|
108
|
-
const res = await client.send({ channel: "telegram:12345", text: "hello world" });
|
|
109
|
-
expect(res.ok).toBe(true);
|
|
110
|
-
expect(res.platform).toBe("telegram");
|
|
111
|
-
expect(res.message_id).toMatch(/^stub-/);
|
|
112
|
-
expect(res.delivered_at).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
|
113
|
-
});
|
|
114
|
-
it("send with missing params returns INVALID_PARAMS (-32602)", async () => {
|
|
115
|
-
const gw = new ChatGateway([new StubAdapter("telegram")]);
|
|
116
|
-
await gw.start();
|
|
117
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot });
|
|
118
|
-
await server.listen();
|
|
119
|
-
const client = new DaemonClient({ dataRoot: tmpRoot });
|
|
120
|
-
await expect(client.call("send", {})).rejects.toMatchObject({
|
|
121
|
-
name: "DaemonRpcError",
|
|
122
|
-
code: -32602,
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
it("unknown method returns METHOD_NOT_FOUND (-32601)", async () => {
|
|
126
|
-
const gw = new ChatGateway([new StubAdapter("telegram")]);
|
|
127
|
-
await gw.start();
|
|
128
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot });
|
|
129
|
-
await server.listen();
|
|
130
|
-
const client = new DaemonClient({ dataRoot: tmpRoot });
|
|
131
|
-
await expect(client.call("does_not_exist", {})).rejects.toMatchObject({
|
|
132
|
-
name: "DaemonRpcError",
|
|
133
|
-
code: -32601,
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
it("pipelines multiple requests on independent connections", async () => {
|
|
137
|
-
const gw = new ChatGateway([new StubAdapter("telegram")]);
|
|
138
|
-
await gw.start();
|
|
139
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot });
|
|
140
|
-
await server.listen();
|
|
141
|
-
const client = new DaemonClient({ dataRoot: tmpRoot });
|
|
142
|
-
const results = await Promise.all([client.ping(), client.ping(), client.ping()]);
|
|
143
|
-
expect(results.length).toBe(3);
|
|
144
|
-
for (const r of results)
|
|
145
|
-
expect(r.pong).toBe(true);
|
|
146
|
-
});
|
|
147
|
-
it("DaemonUnreachableError when no server is listening", async () => {
|
|
148
|
-
// Don't start the server.
|
|
149
|
-
const client = new DaemonClient({ dataRoot: tmpRoot, connectTimeoutMs: 250 });
|
|
150
|
-
await expect(client.ping()).rejects.toBeInstanceOf(DaemonUnreachableError);
|
|
151
|
-
});
|
|
152
|
-
it("DaemonUnreachableError after server.close()", async () => {
|
|
153
|
-
const gw = new ChatGateway([new StubAdapter("telegram")]);
|
|
154
|
-
await gw.start();
|
|
155
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot });
|
|
156
|
-
await server.listen();
|
|
157
|
-
await server.close();
|
|
158
|
-
const client = new DaemonClient({ dataRoot: tmpRoot, connectTimeoutMs: 250 });
|
|
159
|
-
await expect(client.ping()).rejects.toBeInstanceOf(DaemonUnreachableError);
|
|
160
|
-
});
|
|
161
|
-
it("DaemonRpcError surfaces both the message and the code", async () => {
|
|
162
|
-
const gw = new ChatGateway([new StubAdapter("telegram")]);
|
|
163
|
-
await gw.start();
|
|
164
|
-
server = new RpcServer({ gateway: gw, dataRoot: tmpRoot });
|
|
165
|
-
await server.listen();
|
|
166
|
-
const client = new DaemonClient({ dataRoot: tmpRoot });
|
|
167
|
-
try {
|
|
168
|
-
await client.call("does_not_exist", {});
|
|
169
|
-
throw new Error("expected to throw");
|
|
170
|
-
}
|
|
171
|
-
catch (err) {
|
|
172
|
-
expect(err).toBeInstanceOf(DaemonRpcError);
|
|
173
|
-
expect(err.code).toBe(-32601);
|
|
174
|
-
expect(err.message).toContain("unknown method");
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
});
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* subscribers.ts — TPS.6 patch 1 (v0.5.125) subscriber registry.
|
|
3
|
-
*
|
|
4
|
-
* In-process registry of long-lived MCP-bridge subscribers. Each
|
|
5
|
-
* subscriber is an MCP bridge subprocess that opened a UDS connection
|
|
6
|
-
* and called `subscribe` with a session_id + chat_ids selector. The
|
|
7
|
-
* daemon's `gateway.onMessage` handler (wired in TPS.6 patch 2) iterates
|
|
8
|
-
* registry.forChatId(...) and pushes one notification per subscriber.
|
|
9
|
-
*
|
|
10
|
-
* Two indexes:
|
|
11
|
-
* - byId: session_id → Subscriber (idempotency + unregister)
|
|
12
|
-
* - byChat: chat_id → Set<session_id> (broadcast lookup)
|
|
13
|
-
* - wildcardIds: Set<session_id> for subscribers with chat_ids=[]
|
|
14
|
-
*
|
|
15
|
-
* Per-subscriber send queue (bounded, FIFO). When socket.write returns
|
|
16
|
-
* false (kernel buffer full), notifications are queued and drained on
|
|
17
|
-
* the 'drain' event. Queue overflow drops oldest with a logged warning.
|
|
18
|
-
*
|
|
19
|
-
* Lifecycle: register() returns the Subscriber handle; socket close /
|
|
20
|
-
* error events auto-unregister via the listener installed in register().
|
|
21
|
-
* Idempotency: re-register on the same session_id evicts the old slot
|
|
22
|
-
* (with a graceful close of the old socket) before installing the new.
|
|
23
|
-
*
|
|
24
|
-
* No timers; no background work. Purely event-driven from the socket
|
|
25
|
-
* lifecycle + broadcast invocations.
|
|
26
|
-
*
|
|
27
|
-
* Rebuild path: ad-hoc tsc invocation (see telegram.ts header).
|
|
28
|
-
*/
|
|
29
|
-
export const SUBSCRIBER_QUEUE_CAP = 100;
|
|
30
|
-
export class SubscriberRegistry {
|
|
31
|
-
byId = new Map();
|
|
32
|
-
byChat = new Map();
|
|
33
|
-
wildcardIds = new Set();
|
|
34
|
-
/**
|
|
35
|
-
* Install a new subscriber. If `session_id` already exists, the old
|
|
36
|
-
* slot is gracefully closed first (idempotent re-register on
|
|
37
|
-
* MCP-bridge reconnect).
|
|
38
|
-
*
|
|
39
|
-
* Returns the SubscriberRecord. Callers must NOT mutate it.
|
|
40
|
-
*/
|
|
41
|
-
register(args) {
|
|
42
|
-
// Evict any existing slot first.
|
|
43
|
-
const existing = this.byId.get(args.session_id);
|
|
44
|
-
if (existing) {
|
|
45
|
-
this.removeFromIndexes(existing.record);
|
|
46
|
-
this.detachListeners(existing);
|
|
47
|
-
try {
|
|
48
|
-
existing.record.socket.end();
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
/* socket already closed */
|
|
52
|
-
}
|
|
53
|
-
this.byId.delete(args.session_id);
|
|
54
|
-
}
|
|
55
|
-
const record = {
|
|
56
|
-
session_id: args.session_id,
|
|
57
|
-
workspace_uuid: args.workspace_uuid,
|
|
58
|
-
workspace_path: args.workspace_path,
|
|
59
|
-
chat_ids: [...args.chat_ids],
|
|
60
|
-
wildcard: args.chat_ids.length === 0,
|
|
61
|
-
socket: args.socket,
|
|
62
|
-
dropped_count: 0,
|
|
63
|
-
};
|
|
64
|
-
const entry = {
|
|
65
|
-
record,
|
|
66
|
-
queue: [],
|
|
67
|
-
paused: false,
|
|
68
|
-
onClose: () => this.unregister(args.session_id),
|
|
69
|
-
onError: () => this.unregister(args.session_id),
|
|
70
|
-
onDrain: () => this.drainQueue(entry),
|
|
71
|
-
};
|
|
72
|
-
args.socket.on("close", entry.onClose);
|
|
73
|
-
args.socket.on("error", entry.onError);
|
|
74
|
-
args.socket.on("drain", entry.onDrain);
|
|
75
|
-
this.byId.set(args.session_id, entry);
|
|
76
|
-
if (record.wildcard) {
|
|
77
|
-
this.wildcardIds.add(args.session_id);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
for (const chatId of record.chat_ids) {
|
|
81
|
-
let bucket = this.byChat.get(chatId);
|
|
82
|
-
if (!bucket) {
|
|
83
|
-
bucket = new Set();
|
|
84
|
-
this.byChat.set(chatId, bucket);
|
|
85
|
-
}
|
|
86
|
-
bucket.add(args.session_id);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return record;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Remove a subscriber (by session_id). Idempotent — no-op if the
|
|
93
|
-
* session is not registered. The socket is NOT closed by unregister
|
|
94
|
-
* (caller decides; auto-unregister-on-close hooks don't want to
|
|
95
|
-
* loop). Returns true iff something was removed.
|
|
96
|
-
*/
|
|
97
|
-
unregister(session_id) {
|
|
98
|
-
const entry = this.byId.get(session_id);
|
|
99
|
-
if (!entry)
|
|
100
|
-
return false;
|
|
101
|
-
this.removeFromIndexes(entry.record);
|
|
102
|
-
this.detachListeners(entry);
|
|
103
|
-
this.byId.delete(session_id);
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
/** All subscribers whose selector matches `chat_id` (literal chat or wildcard). */
|
|
107
|
-
forChatId(chat_id) {
|
|
108
|
-
const matches = [];
|
|
109
|
-
const specific = this.byChat.get(chat_id);
|
|
110
|
-
if (specific) {
|
|
111
|
-
for (const id of specific) {
|
|
112
|
-
const entry = this.byId.get(id);
|
|
113
|
-
if (entry)
|
|
114
|
-
matches.push(entry.record);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
for (const id of this.wildcardIds) {
|
|
118
|
-
const entry = this.byId.get(id);
|
|
119
|
-
if (entry)
|
|
120
|
-
matches.push(entry.record);
|
|
121
|
-
}
|
|
122
|
-
return matches;
|
|
123
|
-
}
|
|
124
|
-
/** Look up by session_id. */
|
|
125
|
-
get(session_id) {
|
|
126
|
-
return this.byId.get(session_id)?.record;
|
|
127
|
-
}
|
|
128
|
-
/** Total registered subscribers (test/diag use). */
|
|
129
|
-
size() {
|
|
130
|
-
return this.byId.size;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Push a notification to one subscriber. Returns true if the write
|
|
134
|
-
* went out cleanly, false if it was queued (or dropped on overflow).
|
|
135
|
-
* Never throws — write failures are logged + cause eviction.
|
|
136
|
-
*/
|
|
137
|
-
push(session_id, notif) {
|
|
138
|
-
const entry = this.byId.get(session_id);
|
|
139
|
-
if (!entry)
|
|
140
|
-
return false;
|
|
141
|
-
const line = JSON.stringify(notif) + "\n";
|
|
142
|
-
if (entry.paused) {
|
|
143
|
-
this.enqueue(entry, line);
|
|
144
|
-
return false;
|
|
145
|
-
}
|
|
146
|
-
let ok;
|
|
147
|
-
try {
|
|
148
|
-
ok = entry.record.socket.write(line);
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
// Write to a half-closed socket — evict.
|
|
152
|
-
this.unregister(session_id);
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
if (!ok) {
|
|
156
|
-
entry.paused = true;
|
|
157
|
-
}
|
|
158
|
-
return ok;
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Broadcast a notification to every subscriber matching `chat_id`.
|
|
162
|
-
* Returns the count of attempted deliveries (includes queued ones).
|
|
163
|
-
*/
|
|
164
|
-
broadcast(chat_id, notif) {
|
|
165
|
-
let count = 0;
|
|
166
|
-
for (const subscriber of this.forChatId(chat_id)) {
|
|
167
|
-
this.push(subscriber.session_id, notif);
|
|
168
|
-
count += 1;
|
|
169
|
-
}
|
|
170
|
-
return count;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Send a `daemon_shutdown` notification to every subscriber + close
|
|
174
|
-
* their sockets. Called from worker SIGTERM handler.
|
|
175
|
-
*/
|
|
176
|
-
shutdown(reason, restartExpectedAt) {
|
|
177
|
-
const notif = {
|
|
178
|
-
jsonrpc: "2.0",
|
|
179
|
-
method: "daemon_shutdown",
|
|
180
|
-
params: restartExpectedAt
|
|
181
|
-
? { reason, restart_expected_at: restartExpectedAt }
|
|
182
|
-
: { reason },
|
|
183
|
-
};
|
|
184
|
-
for (const session_id of [...this.byId.keys()]) {
|
|
185
|
-
this.push(session_id, notif);
|
|
186
|
-
const entry = this.byId.get(session_id);
|
|
187
|
-
if (entry) {
|
|
188
|
-
try {
|
|
189
|
-
entry.record.socket.end();
|
|
190
|
-
}
|
|
191
|
-
catch {
|
|
192
|
-
/* already closed */
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
// -----------------------------------------------------------------
|
|
198
|
-
// Internals
|
|
199
|
-
// -----------------------------------------------------------------
|
|
200
|
-
enqueue(entry, line) {
|
|
201
|
-
if (entry.queue.length >= SUBSCRIBER_QUEUE_CAP) {
|
|
202
|
-
// Drop oldest, keep newest. Telegram messages are time-sensitive;
|
|
203
|
-
// a backlog of >100 means the subscriber is hopelessly behind
|
|
204
|
-
// and the newest message is more valuable than the oldest.
|
|
205
|
-
entry.queue.shift();
|
|
206
|
-
entry.record.dropped_count += 1;
|
|
207
|
-
process.stderr.write(`[subscribers] queue overflow for session=${entry.record.session_id}; dropped oldest (total dropped=${String(entry.record.dropped_count)})\n`);
|
|
208
|
-
}
|
|
209
|
-
entry.queue.push(line);
|
|
210
|
-
}
|
|
211
|
-
drainQueue(entry) {
|
|
212
|
-
while (entry.queue.length > 0) {
|
|
213
|
-
const line = entry.queue[0];
|
|
214
|
-
if (line === undefined)
|
|
215
|
-
break;
|
|
216
|
-
let ok;
|
|
217
|
-
try {
|
|
218
|
-
ok = entry.record.socket.write(line);
|
|
219
|
-
}
|
|
220
|
-
catch {
|
|
221
|
-
this.unregister(entry.record.session_id);
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
entry.queue.shift();
|
|
225
|
-
if (!ok) {
|
|
226
|
-
// Re-paused mid-drain — wait for next 'drain'.
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
entry.paused = false;
|
|
231
|
-
}
|
|
232
|
-
removeFromIndexes(record) {
|
|
233
|
-
if (record.wildcard) {
|
|
234
|
-
this.wildcardIds.delete(record.session_id);
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
for (const chatId of record.chat_ids) {
|
|
238
|
-
const bucket = this.byChat.get(chatId);
|
|
239
|
-
if (!bucket)
|
|
240
|
-
continue;
|
|
241
|
-
bucket.delete(record.session_id);
|
|
242
|
-
if (bucket.size === 0)
|
|
243
|
-
this.byChat.delete(chatId);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
detachListeners(entry) {
|
|
248
|
-
try {
|
|
249
|
-
entry.record.socket.off("close", entry.onClose);
|
|
250
|
-
entry.record.socket.off("error", entry.onError);
|
|
251
|
-
entry.record.socket.off("drain", entry.onDrain);
|
|
252
|
-
}
|
|
253
|
-
catch {
|
|
254
|
-
/* socket already destroyed */
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chat-daemon worker entrypoint (v0.7.1 Phase A).
|
|
3
|
-
*
|
|
4
|
-
* Spawned as a detached child by `lifecycle.startDaemon()`. Owns the
|
|
5
|
-
* single long-poll connection per chat platform. The MCP server side
|
|
6
|
-
* stays out of the polling business entirely — outbound RPC (Phase B)
|
|
7
|
-
* and inbox tailing (Phase C) replace the in-process gateway.
|
|
8
|
-
*
|
|
9
|
-
* Lifecycle inside the worker:
|
|
10
|
-
* 1. Write our PID to ~/.opensquid/chat-daemon.pid
|
|
11
|
-
* 2. Build the chat gateway from ~/.opensquid/config.json
|
|
12
|
-
* 3. Start every configured adapter (their long-poll loops run as
|
|
13
|
-
* side effects of start())
|
|
14
|
-
* 4. Install SIGTERM / SIGINT handlers that stop the gateway and
|
|
15
|
-
* remove the pidfile before exit
|
|
16
|
-
* 5. Park on process.stdin (which is /dev/null in detached mode)
|
|
17
|
-
* so the event loop stays alive
|
|
18
|
-
*
|
|
19
|
-
* Crash behavior: any unhandled exception from gateway.start() prints
|
|
20
|
-
* to the (parent-redirected) log file and exits non-zero. The pidfile
|
|
21
|
-
* is cleaned up in the SIGTERM handler — if we crash before installing
|
|
22
|
-
* it, the pidfile may linger, and the next `status` call will report
|
|
23
|
-
* `stale_pid` (lifecycle.startDaemon cleans up stale pidfiles before
|
|
24
|
-
* spawning).
|
|
25
|
-
*/
|
|
26
|
-
export declare function runDaemonWorker(dataRoot?: string): Promise<never>;
|
|
27
|
-
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src.legacy/chat/daemon/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAkBH,wBAAsB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAkLvE"}
|