@hasna/bridge 0.1.0
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/LICENSE +17 -0
- package/README.md +94 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +6717 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4448 -0
- package/dist/lib/agents.d.ts +13 -0
- package/dist/lib/agents.d.ts.map +1 -0
- package/dist/lib/config.d.ts +11 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/doctor.d.ts +3 -0
- package/dist/lib/doctor.d.ts.map +1 -0
- package/dist/lib/paths.d.ts +4 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/router.d.ts +11 -0
- package/dist/lib/router.d.ts.map +1 -0
- package/dist/lib/state.d.ts +8 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/telegram.d.ts +28 -0
- package/dist/lib/telegram.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +4356 -0
- package/dist/types.d.ts +110 -0
- package/dist/types.d.ts.map +1 -0
- package/docs/architecture.md +47 -0
- package/examples/bridge.config.example.json +49 -0
- package/package.json +71 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
export declare const CONFIG_VERSION: 1;
|
|
2
|
+
export declare const CHANNEL_KINDS: readonly ["telegram", "console", "webhook", "imessage"];
|
|
3
|
+
export type ChannelKind = (typeof CHANNEL_KINDS)[number];
|
|
4
|
+
export declare const AGENT_KINDS: readonly ["codewith", "claude", "aicopilot", "shell"];
|
|
5
|
+
export type AgentKind = (typeof AGENT_KINDS)[number];
|
|
6
|
+
export interface BaseChannelConfig {
|
|
7
|
+
id: string;
|
|
8
|
+
kind: ChannelKind;
|
|
9
|
+
label?: string;
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface TelegramChannelConfig extends BaseChannelConfig {
|
|
13
|
+
kind: "telegram";
|
|
14
|
+
botTokenEnv?: string;
|
|
15
|
+
defaultChatId?: string;
|
|
16
|
+
allowedChatIds?: string[];
|
|
17
|
+
allowAllChats?: boolean;
|
|
18
|
+
pollTimeoutSeconds?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface ConsoleChannelConfig extends BaseChannelConfig {
|
|
21
|
+
kind: "console";
|
|
22
|
+
}
|
|
23
|
+
export interface WebhookChannelConfig extends BaseChannelConfig {
|
|
24
|
+
kind: "webhook";
|
|
25
|
+
secretEnv?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface IMessageChannelConfig extends BaseChannelConfig {
|
|
28
|
+
kind: "imessage";
|
|
29
|
+
account?: string;
|
|
30
|
+
}
|
|
31
|
+
export type ChannelConfig = TelegramChannelConfig | ConsoleChannelConfig | WebhookChannelConfig | IMessageChannelConfig;
|
|
32
|
+
export interface ProfileConfig {
|
|
33
|
+
id: string;
|
|
34
|
+
agentKind: AgentKind;
|
|
35
|
+
label?: string;
|
|
36
|
+
authProfile?: string;
|
|
37
|
+
cwd?: string;
|
|
38
|
+
home?: string;
|
|
39
|
+
command?: string;
|
|
40
|
+
args?: string[];
|
|
41
|
+
env?: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
export interface AgentConfig {
|
|
44
|
+
id: string;
|
|
45
|
+
kind: AgentKind;
|
|
46
|
+
label?: string;
|
|
47
|
+
profileId?: string;
|
|
48
|
+
command?: string;
|
|
49
|
+
args?: string[];
|
|
50
|
+
cwd?: string;
|
|
51
|
+
env?: Record<string, string>;
|
|
52
|
+
timeoutMs?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface RouteMatch {
|
|
55
|
+
chatIds?: string[];
|
|
56
|
+
textRegex?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface RouteConfig {
|
|
59
|
+
id: string;
|
|
60
|
+
fromChannel: string;
|
|
61
|
+
toAgent: string;
|
|
62
|
+
responseChannel?: string;
|
|
63
|
+
enabled?: boolean;
|
|
64
|
+
match?: RouteMatch;
|
|
65
|
+
}
|
|
66
|
+
export interface BridgeConfig {
|
|
67
|
+
version: typeof CONFIG_VERSION;
|
|
68
|
+
channels: Record<string, ChannelConfig>;
|
|
69
|
+
profiles: Record<string, ProfileConfig>;
|
|
70
|
+
agents: Record<string, AgentConfig>;
|
|
71
|
+
routes: RouteConfig[];
|
|
72
|
+
}
|
|
73
|
+
export interface BridgeMessage {
|
|
74
|
+
id: string;
|
|
75
|
+
channelId: string;
|
|
76
|
+
text: string;
|
|
77
|
+
chatId?: string;
|
|
78
|
+
from?: string;
|
|
79
|
+
receivedAt: string;
|
|
80
|
+
raw?: unknown;
|
|
81
|
+
}
|
|
82
|
+
export interface AgentRunInput {
|
|
83
|
+
message: BridgeMessage;
|
|
84
|
+
route: RouteConfig;
|
|
85
|
+
}
|
|
86
|
+
export interface AgentRunResult {
|
|
87
|
+
agentId: string;
|
|
88
|
+
command: string[];
|
|
89
|
+
cwd?: string;
|
|
90
|
+
exitCode: number | null;
|
|
91
|
+
stdout: string;
|
|
92
|
+
stderr: string;
|
|
93
|
+
timedOut: boolean;
|
|
94
|
+
}
|
|
95
|
+
export interface RoutedMessageResult {
|
|
96
|
+
route: RouteConfig;
|
|
97
|
+
agent: AgentRunResult;
|
|
98
|
+
deliveredResponse?: boolean;
|
|
99
|
+
}
|
|
100
|
+
export interface DoctorCheck {
|
|
101
|
+
name: string;
|
|
102
|
+
ok: boolean;
|
|
103
|
+
detail?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface DoctorReport {
|
|
106
|
+
ok: boolean;
|
|
107
|
+
configPath: string;
|
|
108
|
+
checks: DoctorCheck[];
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,EAAG,CAAU,CAAC;AAEzC,eAAO,MAAM,aAAa,yDAA0D,CAAC;AACrF,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,eAAO,MAAM,WAAW,uDAAwD,CAAC;AACjF,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,GACrB,qBAAqB,GACrB,oBAAoB,GACpB,oBAAoB,GACpB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,cAAc,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACpC,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;IACtB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Bridge Architecture
|
|
2
|
+
|
|
3
|
+
`bridge` separates channel connectors from agent adapters.
|
|
4
|
+
|
|
5
|
+
Channels own external transport details such as Telegram bot tokens, chat IDs,
|
|
6
|
+
webhooks, or future iMessage transport. Agents own local execution details such
|
|
7
|
+
as Codewith auth profiles, Claude profile homes, AIcopilot state roots, command
|
|
8
|
+
arguments, cwd, and environment. Routes connect one channel to one agent.
|
|
9
|
+
|
|
10
|
+
The package deliberately keeps Telegram-specific behavior out of Codewith,
|
|
11
|
+
Claude, and AIcopilot integrations. Agent adapters receive plain text prompts
|
|
12
|
+
and return stdout/stderr plus process metadata. Channel connectors decide how
|
|
13
|
+
to receive and deliver messages.
|
|
14
|
+
|
|
15
|
+
## Data Model
|
|
16
|
+
|
|
17
|
+
- `channels`: external message transports.
|
|
18
|
+
- `profiles`: reusable identity/state settings for an agent family.
|
|
19
|
+
- `agents`: runnable targets, usually pointing at one profile.
|
|
20
|
+
- `routes`: mapping rules from channel messages to agents.
|
|
21
|
+
|
|
22
|
+
## Profile Model
|
|
23
|
+
|
|
24
|
+
Codewith profiles use `authProfile` and render as `codewith --auth-profile
|
|
25
|
+
<name> --cd <cwd> exec <prompt>`.
|
|
26
|
+
|
|
27
|
+
Claude profiles can use `home` or custom env vars so multiple accounts do not
|
|
28
|
+
share local state.
|
|
29
|
+
|
|
30
|
+
AIcopilot profiles currently use cwd/env/command isolation. The target repo
|
|
31
|
+
work dispatched on spark02 is expected to add or document first-class profile
|
|
32
|
+
support.
|
|
33
|
+
|
|
34
|
+
## Telegram
|
|
35
|
+
|
|
36
|
+
The first connector uses Telegram Bot API `getUpdates` long polling and
|
|
37
|
+
`sendMessage`. Production deployments should move high-volume bots to webhooks,
|
|
38
|
+
but long polling is the right baseline for local agent machines and early
|
|
39
|
+
testing.
|
|
40
|
+
|
|
41
|
+
Telegram channels fail closed unless `allowedChatIds` are configured or
|
|
42
|
+
`allowAllChats` is explicitly enabled. Channel `allowedChatIds` are enforced
|
|
43
|
+
before route matching. Routes can also add narrower `match.chatIds` filters, but
|
|
44
|
+
they cannot expand beyond the channel allowlist.
|
|
45
|
+
|
|
46
|
+
Long-poll offsets are persisted in a private state file so process restarts do
|
|
47
|
+
not replay already-seen updates and re-run agents.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"channels": {
|
|
4
|
+
"telegram-main": {
|
|
5
|
+
"id": "telegram-main",
|
|
6
|
+
"kind": "telegram",
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"botTokenEnv": "TELEGRAM_BOT_TOKEN",
|
|
9
|
+
"allowedChatIds": ["123456789"],
|
|
10
|
+
"allowAllChats": false
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"profiles": {
|
|
14
|
+
"codewith-account001": {
|
|
15
|
+
"id": "codewith-account001",
|
|
16
|
+
"agentKind": "codewith",
|
|
17
|
+
"authProfile": "account001",
|
|
18
|
+
"cwd": "/Users/hasna"
|
|
19
|
+
},
|
|
20
|
+
"claude-account001": {
|
|
21
|
+
"id": "claude-account001",
|
|
22
|
+
"agentKind": "claude",
|
|
23
|
+
"home": "/Users/hasna/.hasna/accounts/profiles/claude/account001"
|
|
24
|
+
},
|
|
25
|
+
"aicopilot-main": {
|
|
26
|
+
"id": "aicopilot-main",
|
|
27
|
+
"agentKind": "aicopilot",
|
|
28
|
+
"cwd": "/Users/hasna"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"agents": {
|
|
32
|
+
"codewith": {
|
|
33
|
+
"id": "codewith",
|
|
34
|
+
"kind": "codewith",
|
|
35
|
+
"profileId": "codewith-account001"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"routes": [
|
|
39
|
+
{
|
|
40
|
+
"id": "telegram-codewith",
|
|
41
|
+
"fromChannel": "telegram-main",
|
|
42
|
+
"toAgent": "codewith",
|
|
43
|
+
"enabled": true,
|
|
44
|
+
"match": {
|
|
45
|
+
"chatIds": ["123456789"]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hasna/bridge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agent messaging bridge for Telegram and other channels",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"bridge": "dist/cli/index.js",
|
|
10
|
+
"bridge-mcp": "dist/mcp/index.js"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"docs",
|
|
21
|
+
"examples",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "rm -rf dist && bun build src/cli/index.ts --outdir dist/cli --target bun --external @modelcontextprotocol/sdk && bun build src/mcp/index.ts --outdir dist/mcp --target bun --external @modelcontextprotocol/sdk && bun build src/index.ts --outdir dist --target bun && tsc -p tsconfig.build.json",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"test": "bun test",
|
|
29
|
+
"dev:cli": "bun run src/cli/index.ts",
|
|
30
|
+
"dev:mcp": "bun run src/mcp/index.ts",
|
|
31
|
+
"prepublishOnly": "bun run build",
|
|
32
|
+
"postinstall": "bun -e \"const fs=require('node:fs');const path=require('node:path');const dir=path.join(process.env.HOME||process.cwd(),'.hasna','bridge');fs.mkdirSync(dir,{recursive:true,mode:0o700});try{fs.chmodSync(dir,0o700)}catch{}\""
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"bridge",
|
|
36
|
+
"telegram",
|
|
37
|
+
"messaging",
|
|
38
|
+
"agents",
|
|
39
|
+
"codewith",
|
|
40
|
+
"claude",
|
|
41
|
+
"aicopilot",
|
|
42
|
+
"mcp",
|
|
43
|
+
"cli"
|
|
44
|
+
],
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"registry": "https://registry.npmjs.org",
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/hasna/bridge.git"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/hasna/bridge",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/hasna/bridge/issues"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"bun": ">=1.0.0"
|
|
59
|
+
},
|
|
60
|
+
"author": "Andrei Hasna <andrei@hasna.com>",
|
|
61
|
+
"license": "Apache-2.0",
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
64
|
+
"commander": "^13.1.0",
|
|
65
|
+
"zod": "^3.25.76"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/bun": "^1.2.4",
|
|
69
|
+
"typescript": "^5.7.3"
|
|
70
|
+
}
|
|
71
|
+
}
|