@chrisromp/copilot-bridge 0.6.0-dev.2

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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/bin/copilot-bridge.js +61 -0
  4. package/config.sample.json +100 -0
  5. package/dist/channels/mattermost/adapter.d.ts +55 -0
  6. package/dist/channels/mattermost/adapter.d.ts.map +1 -0
  7. package/dist/channels/mattermost/adapter.js +524 -0
  8. package/dist/channels/mattermost/adapter.js.map +1 -0
  9. package/dist/channels/mattermost/streaming.d.ts +29 -0
  10. package/dist/channels/mattermost/streaming.d.ts.map +1 -0
  11. package/dist/channels/mattermost/streaming.js +151 -0
  12. package/dist/channels/mattermost/streaming.js.map +1 -0
  13. package/dist/config.d.ts +107 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +817 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/core/bridge.d.ts +73 -0
  18. package/dist/core/bridge.d.ts.map +1 -0
  19. package/dist/core/bridge.js +166 -0
  20. package/dist/core/bridge.js.map +1 -0
  21. package/dist/core/channel-idle.d.ts +40 -0
  22. package/dist/core/channel-idle.d.ts.map +1 -0
  23. package/dist/core/channel-idle.js +120 -0
  24. package/dist/core/channel-idle.js.map +1 -0
  25. package/dist/core/command-handler.d.ts +51 -0
  26. package/dist/core/command-handler.d.ts.map +1 -0
  27. package/dist/core/command-handler.js +393 -0
  28. package/dist/core/command-handler.js.map +1 -0
  29. package/dist/core/inter-agent.d.ts +52 -0
  30. package/dist/core/inter-agent.d.ts.map +1 -0
  31. package/dist/core/inter-agent.js +179 -0
  32. package/dist/core/inter-agent.js.map +1 -0
  33. package/dist/core/onboarding.d.ts +44 -0
  34. package/dist/core/onboarding.d.ts.map +1 -0
  35. package/dist/core/onboarding.js +205 -0
  36. package/dist/core/onboarding.js.map +1 -0
  37. package/dist/core/scheduler.d.ts +38 -0
  38. package/dist/core/scheduler.d.ts.map +1 -0
  39. package/dist/core/scheduler.js +253 -0
  40. package/dist/core/scheduler.js.map +1 -0
  41. package/dist/core/session-manager.d.ts +166 -0
  42. package/dist/core/session-manager.d.ts.map +1 -0
  43. package/dist/core/session-manager.js +1732 -0
  44. package/dist/core/session-manager.js.map +1 -0
  45. package/dist/core/stream-formatter.d.ts +14 -0
  46. package/dist/core/stream-formatter.d.ts.map +1 -0
  47. package/dist/core/stream-formatter.js +198 -0
  48. package/dist/core/stream-formatter.js.map +1 -0
  49. package/dist/core/thread-utils.d.ts +22 -0
  50. package/dist/core/thread-utils.d.ts.map +1 -0
  51. package/dist/core/thread-utils.js +44 -0
  52. package/dist/core/thread-utils.js.map +1 -0
  53. package/dist/core/workspace-manager.d.ts +38 -0
  54. package/dist/core/workspace-manager.d.ts.map +1 -0
  55. package/dist/core/workspace-manager.js +230 -0
  56. package/dist/core/workspace-manager.js.map +1 -0
  57. package/dist/index.d.ts +2 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +1286 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/logger.d.ts +9 -0
  62. package/dist/logger.d.ts.map +1 -0
  63. package/dist/logger.js +34 -0
  64. package/dist/logger.js.map +1 -0
  65. package/dist/state/store.d.ts +124 -0
  66. package/dist/state/store.d.ts.map +1 -0
  67. package/dist/state/store.js +523 -0
  68. package/dist/state/store.js.map +1 -0
  69. package/dist/types.d.ts +185 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +2 -0
  72. package/dist/types.js.map +1 -0
  73. package/package.json +61 -0
  74. package/scripts/check.ts +267 -0
  75. package/scripts/com.copilot-bridge.plist +41 -0
  76. package/scripts/copilot-bridge.service +30 -0
  77. package/scripts/init.ts +250 -0
  78. package/scripts/install-service.ts +123 -0
  79. package/scripts/lib/config-gen.ts +129 -0
  80. package/scripts/lib/mattermost.ts +109 -0
  81. package/scripts/lib/output.ts +69 -0
  82. package/scripts/lib/prerequisites.ts +86 -0
  83. package/scripts/lib/prompts.ts +65 -0
  84. package/scripts/lib/service.ts +191 -0
  85. package/scripts/uninstall-service.ts +90 -0
  86. package/templates/admin/AGENTS.md +325 -0
  87. package/templates/admin/MEMORY.md +4 -0
  88. package/templates/agents/AGENTS.md +97 -0
  89. package/templates/agents/MEMORY.md +4 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chris Romp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # copilot-bridge
2
+
3
+ <div align="center">
4
+ <img src="docs/images/copilot-bridge.png" alt="Copilot Bridge" width="200" height="200">
5
+ </div>
6
+
7
+ Bridge GitHub Copilot CLI to messaging platforms. Send messages from Mattermost (or other platforms) and get responses from Copilot sessions running on your machine.
8
+
9
+ > [!WARNING]
10
+ > This is all experimental.
11
+
12
+ ```
13
+ Mattermost Channel → copilot-bridge → @github/copilot-sdk → Copilot CLI
14
+ ↑ ↓
15
+ └──────────── streaming response (edit-in-place) ←─────────┘
16
+ ```
17
+
18
+ ## Features
19
+
20
+ - **Multi-bot support** — Run multiple bot identities on the same platform (e.g., `@copilot` for admin, `@alice` for tasks)
21
+ - **Workspaces** — Each bot gets an isolated workspace with its own `AGENTS.md`, `.env` secrets, and `MEMORY.md`
22
+ - **DM auto-discovery** — Just message a bot; no channel config needed for direct messages
23
+ - **Streaming responses** — Edit-in-place message updates with throttling
24
+ - **MCP & skills** — Auto-loads MCP servers and skill directories from Copilot config
25
+ - **Fuzzy model matching** — `/model opus` resolves to `claude-opus-4.6` (mobile-friendly)
26
+ - **Interactive permissions** — Approve/deny tool use via chat, or `/autopilot` to auto-approve
27
+ - **Session management** — `/reload` to refresh config, `/resume` to switch between sessions
28
+ - **Persistent preferences** — Model, agent, verbose mode, permissions saved per-channel
29
+ - **Scheduled tasks** — Recurring (cron) and one-off (datetime) tasks per channel
30
+ - **Inter-agent communication** — Bot-to-bot messaging via `ask_agent` tool
31
+ - **File sharing** — `send_file` and `show_file_in_chat` tools for pushing files to chat
32
+ - **Attachment ingestion** — File and image attachments are extracted and passed to the session
33
+ - **Mid-turn steering** — Send messages while the bot is working to redirect it
34
+ - **Streamer mode** — Hide preview/internal models from `/model` list for on-air use
35
+ - **Thread-aware replies** — Reply in threads via 🧵 trigger or per-channel config
36
+ - **Config hot-reload** — `/reload config` applies safe changes without restarting the bridge
37
+ - **Admin onboarding** — Templates and tools for creating channels, managing workspaces
38
+
39
+ ## Quick Start
40
+
41
+ 1. **Prerequisites**: Node.js 20+, GitHub Copilot CLI installed and authenticated
42
+ 2. **Install** (pick one):
43
+ - **npm**: `npm install -g @chrisromp/copilot-bridge`
44
+ - **From source**: `git clone https://github.com/ChrisRomp/copilot-bridge.git && cd copilot-bridge && npm install`
45
+ 3. **Configure**: `copilot-bridge init` (or `npm run init` from source) — interactive wizard
46
+ 4. **Validate**: `copilot-bridge check` (or `npm run check`)
47
+ 5. **Run**: `copilot-bridge start` (or `npm run dev` for development with watch mode)
48
+
49
+ For DMs, that's it — the bridge auto-discovers DM channels for each bot. For group channels, add a `channels` entry mapping the channel ID to a working directory. See the [Setup Guide](docs/setup.md) for the full walkthrough or [Configuration](docs/configuration.md) for reference.
50
+
51
+ ### Running as a service
52
+
53
+ See the [Setup Guide — Running as a Service](docs/setup.md#running-as-a-service) for macOS (launchd) and Linux (systemd) instructions, or run `npm run install-service` to install automatically.
54
+
55
+ ## Chat Commands
56
+
57
+ | Command | Aliases | Description |
58
+ |---------|---------|-------------|
59
+ | **Session** | | |
60
+ | `/new` | | Start a fresh session |
61
+ | `/stop` | `/cancel` | Stop the current task |
62
+ | `/reload` | | Reload session (re-reads AGENTS.md, workspace config) |
63
+ | `/reload config` | | Hot-reload config.json (safe changes apply without restart) |
64
+ | `/resume [id]` | | List past sessions, or resume one by ID |
65
+ | `/model [name]` | `/models` | List models or switch model (fuzzy match) |
66
+ | `/agent <name>` | | Switch custom agent (empty to deselect) |
67
+ | `/reasoning <level>` | | Set reasoning effort (`low`/`medium`/`high`/`xhigh`) |
68
+ | `/context` | | Show context window usage |
69
+ | `/verbose` | | Toggle tool call visibility |
70
+ | `/status` | | Show session info |
71
+ | **Permissions** | | |
72
+ | `/approve` / `/deny` | | Handle pending permission request |
73
+ | `/remember` | | Approve + persist the permission rule |
74
+ | `/rules` | `/rule` | List saved permission rules |
75
+ | `/rules clear [spec]` | | Clear rules (all, or by spec) |
76
+ | `/autopilot` | `/yolo` | Toggle auto-approve mode |
77
+ | **Scheduling** | | |
78
+ | `/schedule` | `/schedules`, `/tasks` | Manage scheduled tasks (list, cancel, pause, resume, history) |
79
+ | **Tools & Info** | | |
80
+ | `/skills` | `/tools` | Show available skills and MCP tools |
81
+ | `/mcp` | | Show MCP servers and their source |
82
+ | `/streamer-mode` | `/on-air` | Toggle streamer mode (hides preview/internal models) |
83
+ | `/help` | | Show common commands; `/help all` for full list |
84
+
85
+ ## Documentation
86
+
87
+ - **[Configuration](docs/configuration.md)** — Platforms, channels, permissions, defaults
88
+ - **[Workspaces & Agents](docs/workspaces.md)** — Workspace system, .env secrets, templates, agent onboarding
89
+ - **[Architecture](docs/architecture.md)** — Source layout, message flow, adapter pattern, persistence
90
+
91
+ ## License
92
+
93
+ MIT
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from 'node:child_process';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
+ import { readFileSync } from 'node:fs';
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const root = join(__dirname, '..');
10
+
11
+ const commands = {
12
+ start: join(root, 'dist', 'index.js'),
13
+ init: join(root, 'scripts', 'init.ts'),
14
+ check: join(root, 'scripts', 'check.ts'),
15
+ 'install-service': join(root, 'scripts', 'install-service.ts'),
16
+ 'uninstall-service': join(root, 'scripts', 'uninstall-service.ts'),
17
+ };
18
+
19
+ const command = process.argv[2];
20
+
21
+ if (!command || command === '--help' || command === '-h') {
22
+ console.log(`copilot-bridge — Mattermost ↔ GitHub Copilot bridge
23
+
24
+ Usage: copilot-bridge <command>
25
+
26
+ Commands:
27
+ init Interactive setup wizard
28
+ check Validate configuration
29
+ start Start the bridge
30
+ install-service Install as system service
31
+ uninstall-service Remove system service
32
+
33
+ Options:
34
+ --help, -h Show this help
35
+ --version, -v Show version`);
36
+ process.exit(0);
37
+ }
38
+
39
+ if (command === '--version' || command === '-v') {
40
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
41
+ console.log(pkg.version);
42
+ process.exit(0);
43
+ }
44
+
45
+ const script = commands[command];
46
+ if (!script) {
47
+ console.error(`Unknown command: ${command}\nRun 'copilot-bridge --help' for usage.`);
48
+ process.exit(1);
49
+ }
50
+
51
+ // Use --import tsx/esm for TypeScript and ESM compatibility
52
+ const child = spawn(process.execPath, ['--import', 'tsx/esm', script, ...process.argv.slice(3)], {
53
+ stdio: 'inherit',
54
+ cwd: root,
55
+ });
56
+
57
+ child.on('exit', (code) => process.exit(code ?? 1));
58
+ child.on('error', (err) => {
59
+ console.error(`Failed to run command: ${err.message}`);
60
+ process.exit(1);
61
+ });
@@ -0,0 +1,100 @@
1
+ {
2
+ "platforms": {
3
+ "mattermost": {
4
+ "url": "https://chat.example.com",
5
+
6
+ "_comment_auth": "Use ONE of: 'botToken' (single bot) OR 'bots' (multiple identities)",
7
+
8
+ "botToken": "SINGLE_BOT_TOKEN",
9
+
10
+ "_comment_bots": "Multi-bot example (remove 'botToken' above and rename '_bots' to 'bots'):",
11
+ "_bots": {
12
+ "copilot": { "token": "BOT_TOKEN_1", "admin": true },
13
+ "bob": { "token": "BOT_TOKEN_2", "agent": "bob-agent" }
14
+ }
15
+ }
16
+ },
17
+ "channels": [
18
+ {
19
+ "id": "channel-id-from-mattermost",
20
+ "platform": "mattermost",
21
+ "bot": "copilot",
22
+ "name": "My Project",
23
+ "workingDirectory": "/path/to/project",
24
+ "agent": null,
25
+ "model": "claude-sonnet-4.6",
26
+ "triggerMode": "mention",
27
+ "threadedReplies": true,
28
+ "verbose": false
29
+ },
30
+ {
31
+ "id": "another-channel-id",
32
+ "platform": "mattermost",
33
+ "bot": "bob",
34
+ "name": "Bob's Channel",
35
+ "workingDirectory": "/path/to/other-project",
36
+ "model": "claude-sonnet-4.6",
37
+ "triggerMode": "mention",
38
+ "threadedReplies": true,
39
+ "verbose": false
40
+ }
41
+ ],
42
+ "defaults": {
43
+ "model": "claude-sonnet-4.6",
44
+ "agent": null,
45
+ "triggerMode": "mention",
46
+ "threadedReplies": true,
47
+ "verbose": false,
48
+ "permissionMode": "interactive"
49
+ },
50
+ "permissions": {
51
+ "_comment": "CLI-compatible permission syntax: shell(cmd), write, read, MCP_SERVER(tool)",
52
+ "allow": [
53
+ "read",
54
+ "shell(ls)",
55
+ "shell(cat)",
56
+ "shell(head)",
57
+ "shell(tail)",
58
+ "shell(find)",
59
+ "shell(grep)",
60
+ "shell(wc)"
61
+ ],
62
+ "deny": [
63
+ "shell(rm)",
64
+ "shell(git push)",
65
+ "shell(git reset)",
66
+ "shell(shutdown)",
67
+ "shell(reboot)",
68
+ "shell(halt)",
69
+ "shell(systemctl poweroff)",
70
+ "shell(networksetup)",
71
+ "shell(diskutil)"
72
+ ],
73
+ "allowPaths": [],
74
+ "allowUrls": [
75
+ "docs.github.com",
76
+ "learn.microsoft.com",
77
+ "npmjs.com",
78
+ "pypi.org",
79
+ "crates.io",
80
+ "pkg.go.dev",
81
+ "nuget.org",
82
+ "rubygems.org",
83
+ "packagist.org",
84
+ "maven.apache.org",
85
+ "stackoverflow.com",
86
+ "developer.mozilla.org"
87
+ ]
88
+ },
89
+ "_comment_interAgent": "Optional: enable inter-agent communication (ask_agent tool)",
90
+ "interAgent": {
91
+ "enabled": false,
92
+ "defaultTimeout": 60,
93
+ "maxTimeout": 300,
94
+ "maxDepth": 3,
95
+ "allow": {
96
+ "copilot": { "canCall": ["bob"], "canBeCalledBy": ["bob"] },
97
+ "bob": { "canCall": ["copilot"], "canBeCalledBy": ["copilot"] }
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,55 @@
1
+ import type { ChannelAdapter, InboundMessage, InboundReaction, SendOpts, CreateChannelOpts, TeamInfo, ChannelInfo } from '../../types.js';
2
+ export declare class MattermostAdapter implements ChannelAdapter {
3
+ readonly platform: string;
4
+ private client;
5
+ private wsClient;
6
+ private botId;
7
+ private botUsername;
8
+ private url;
9
+ private token;
10
+ private messageHandlers;
11
+ private reactionHandlers;
12
+ private disconnectedAt;
13
+ private lastServerTimestamp;
14
+ private activeChannels;
15
+ private recentPostIds;
16
+ private isReplaying;
17
+ private pendingReplay;
18
+ private static readonly MAX_RECENT_POSTS;
19
+ private static readonly MAX_REPLAY_WINDOW_MS;
20
+ private static readonly CHANNEL_STALENESS_MS;
21
+ constructor(platformName: string, url: string, token: string);
22
+ connect(): Promise<void>;
23
+ disconnect(): Promise<void>;
24
+ /**
25
+ * Discover existing DM channels for this bot via the Mattermost API.
26
+ * Returns channel IDs for direct message conversations the bot is already part of.
27
+ */
28
+ discoverDMChannels(): Promise<{
29
+ channelId: string;
30
+ otherUserId: string;
31
+ }[]>;
32
+ onMessage(handler: (msg: InboundMessage) => void): void;
33
+ onReaction(handler: (reaction: InboundReaction) => void): void;
34
+ sendMessage(channelId: string, content: string, opts?: SendOpts): Promise<string>;
35
+ updateMessage(_channelId: string, messageId: string, content: string): Promise<void>;
36
+ deleteMessage(_channelId: string, messageId: string): Promise<void>;
37
+ setTyping(channelId: string): Promise<void>;
38
+ replyInThread(channelId: string, rootId: string, content: string): Promise<string>;
39
+ getBotUserId(): string;
40
+ addReaction(postId: string, emoji: string): Promise<void>;
41
+ private handlePosted;
42
+ private extractAttachments;
43
+ downloadFile(fileId: string, destPath: string): Promise<string>;
44
+ sendFile(channelId: string, filePath: string, message?: string, opts?: SendOpts): Promise<string>;
45
+ createChannel(opts: CreateChannelOpts): Promise<string>;
46
+ addUserToChannel(channelId: string, userId: string): Promise<void>;
47
+ getTeams(): Promise<TeamInfo[]>;
48
+ getChannelByName(teamId: string, name: string): Promise<ChannelInfo | null>;
49
+ private handleReaction;
50
+ /** Track a post ID and its channel for deduplication and replay targeting. */
51
+ private trackPost;
52
+ /** Fetch and replay messages missed during a WebSocket disconnect. */
53
+ private replayMissedMessages;
54
+ }
55
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/channels/mattermost/adapter.ts"],"names":[],"mappings":"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"}