@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
@@ -0,0 +1,151 @@
1
+ import { createLogger } from '../../logger.js';
2
+ const log = createLogger('streaming');
3
+ export class StreamingHandler {
4
+ adapter;
5
+ activeStreams = new Map();
6
+ throttleMs;
7
+ constructor(adapter, throttleMs = 500) {
8
+ this.adapter = adapter;
9
+ this.throttleMs = throttleMs;
10
+ }
11
+ /** Start a new streaming response. Posts initial placeholder and returns stream key. */
12
+ async startStream(channelId, threadRootId, initialContent) {
13
+ const text = initialContent || '⏳ Working...';
14
+ const messageId = await (threadRootId
15
+ ? this.adapter.replyInThread(channelId, threadRootId, text)
16
+ : this.adapter.sendMessage(channelId, text));
17
+ const key = `${channelId}:${messageId}`;
18
+ this.activeStreams.set(key, {
19
+ channelId,
20
+ messageId,
21
+ content: initialContent ?? '',
22
+ pendingUpdate: null,
23
+ updateTimer: null,
24
+ threadRootId,
25
+ });
26
+ return key;
27
+ }
28
+ /** Append delta content to a stream. Updates are throttled. */
29
+ appendDelta(streamKey, delta) {
30
+ const stream = this.activeStreams.get(streamKey);
31
+ if (!stream || !delta) {
32
+ if (!stream)
33
+ log.warn(`appendDelta: stream not found for key ${streamKey}`);
34
+ return;
35
+ }
36
+ stream.content += delta;
37
+ stream.pendingUpdate = stream.content;
38
+ if (!stream.updateTimer) {
39
+ log.debug(`Scheduled flush for ${streamKey.split(':')[1]?.slice(0, 8)}... (${stream.content.length} chars)`);
40
+ stream.updateTimer = setTimeout(() => {
41
+ this.flushUpdate(streamKey);
42
+ }, this.throttleMs);
43
+ }
44
+ }
45
+ /** Replace the entire stream content (for non-delta updates). */
46
+ replaceContent(streamKey, content) {
47
+ const stream = this.activeStreams.get(streamKey);
48
+ if (!stream)
49
+ return;
50
+ stream.content = content;
51
+ stream.pendingUpdate = content;
52
+ if (!stream.updateTimer) {
53
+ stream.updateTimer = setTimeout(() => {
54
+ this.flushUpdate(streamKey);
55
+ }, this.throttleMs);
56
+ }
57
+ }
58
+ /** Finalize the stream with the complete content. */
59
+ async finalizeStream(streamKey, finalContent) {
60
+ const stream = this.activeStreams.get(streamKey);
61
+ if (!stream) {
62
+ log.warn(`finalizeStream: stream not found for key ${streamKey}`);
63
+ return;
64
+ }
65
+ // Remove from map FIRST to prevent flushUpdate from racing
66
+ this.activeStreams.delete(streamKey);
67
+ if (stream.updateTimer) {
68
+ clearTimeout(stream.updateTimer);
69
+ stream.updateTimer = null;
70
+ }
71
+ const content = finalContent ?? stream.content;
72
+ log.info(`Finalizing ${stream.messageId.slice(0, 8)}...: ${content.length} chars`);
73
+ if (content) {
74
+ try {
75
+ await this.adapter.updateMessage(stream.channelId, stream.messageId, content);
76
+ }
77
+ catch (err) {
78
+ log.error(`Failed to finalize message:`, err);
79
+ }
80
+ }
81
+ }
82
+ /** Cancel and clean up a stream. */
83
+ async cancelStream(streamKey, errorMessage) {
84
+ const stream = this.activeStreams.get(streamKey);
85
+ if (!stream)
86
+ return;
87
+ // Remove from map FIRST to prevent flushUpdate from racing
88
+ this.activeStreams.delete(streamKey);
89
+ if (stream.updateTimer) {
90
+ clearTimeout(stream.updateTimer);
91
+ }
92
+ if (errorMessage) {
93
+ try {
94
+ await this.adapter.updateMessage(stream.channelId, stream.messageId, `❌ ${errorMessage}`);
95
+ }
96
+ catch { /* best-effort */ }
97
+ }
98
+ }
99
+ /** Get the message ID for a stream (useful for threading). */
100
+ getStreamMessageId(streamKey) {
101
+ return this.activeStreams.get(streamKey)?.messageId;
102
+ }
103
+ /** Get current content of a stream (undefined if not found). */
104
+ getStreamContent(streamKey) {
105
+ return this.activeStreams.get(streamKey)?.content;
106
+ }
107
+ /** Get the thread root ID for a stream. */
108
+ getStreamThreadRootId(streamKey) {
109
+ return this.activeStreams.get(streamKey)?.threadRootId;
110
+ }
111
+ /** Delete a stream's message and clean up without posting anything. */
112
+ async deleteStream(streamKey) {
113
+ const stream = this.activeStreams.get(streamKey);
114
+ if (!stream)
115
+ return;
116
+ this.activeStreams.delete(streamKey);
117
+ if (stream.updateTimer) {
118
+ clearTimeout(stream.updateTimer);
119
+ }
120
+ try {
121
+ await this.adapter.deleteMessage(stream.channelId, stream.messageId);
122
+ }
123
+ catch (err) {
124
+ log.warn(`Failed to delete stream message:`, err);
125
+ }
126
+ }
127
+ async flushUpdate(streamKey) {
128
+ const stream = this.activeStreams.get(streamKey);
129
+ if (!stream || !stream.pendingUpdate)
130
+ return;
131
+ const content = stream.pendingUpdate;
132
+ stream.pendingUpdate = null;
133
+ stream.updateTimer = null;
134
+ try {
135
+ log.debug(`Flushing ${content.length} chars to ${stream.messageId.slice(0, 8)}...`);
136
+ await this.adapter.updateMessage(stream.channelId, stream.messageId, content);
137
+ }
138
+ catch (err) {
139
+ log.error(`Failed to update message ${stream.messageId}:`, err);
140
+ }
141
+ }
142
+ /** Clean up all active streams. */
143
+ async cleanup() {
144
+ for (const [, stream] of Array.from(this.activeStreams)) {
145
+ if (stream.updateTimer)
146
+ clearTimeout(stream.updateTimer);
147
+ }
148
+ this.activeStreams.clear();
149
+ }
150
+ }
151
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../../src/channels/mattermost/streaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ import type { AppConfig, ChannelConfig, BotConfig, InterAgentConfig } from './types.js';
2
+ export declare function loadConfig(configPath?: string): AppConfig;
3
+ /** The resolved config file path (available after loadConfig). */
4
+ export declare function getConfigPath(): string | null;
5
+ /** Result of a config reload attempt. */
6
+ export interface ReloadResult {
7
+ success: boolean;
8
+ error?: string;
9
+ changes: string[];
10
+ restartNeeded: string[];
11
+ }
12
+ /**
13
+ * Re-read config from disk, validate, diff, and apply.
14
+ * On failure, keeps existing config and returns the error.
15
+ * Dynamic channels are preserved across reloads.
16
+ */
17
+ export declare function reloadConfig(): ReloadResult;
18
+ export declare function getConfig(): AppConfig;
19
+ export declare function getInterAgentConfig(): InterAgentConfig;
20
+ export declare function getChannelConfig(channelId: string): ChannelConfig & {
21
+ permissionMode: string;
22
+ };
23
+ /** Check if a channel ID is in our configured channels list (static or dynamic) */
24
+ export declare function isConfiguredChannel(channelId: string): boolean;
25
+ /**
26
+ * Dynamically register a channel at runtime (not persisted to config.json).
27
+ * Used for auto-discovered DM channels with bots.
28
+ * Stored separately from static config so they survive reloads.
29
+ */
30
+ export declare function registerDynamicChannel(channel: ChannelConfig): void;
31
+ /** Mark an existing channel as a DM (mutates the source config object and dynamic store). */
32
+ export declare function markChannelAsDM(channelId: string): void;
33
+ /**
34
+ * Get the resolved bot token for a channel.
35
+ * Supports both single-bot (botToken) and multi-bot (bots map) configs.
36
+ */
37
+ export declare function getChannelBotToken(channelId: string): string;
38
+ /** Get the BotConfig for a channel (if multi-bot). */
39
+ export declare function getChannelBotConfig(channelId: string): BotConfig | null;
40
+ /**
41
+ * Get all unique bot tokens for a platform, keyed by bot name.
42
+ * For single-bot configs, returns { "default": token }.
43
+ */
44
+ export declare function getPlatformBots(platformName: string): Map<string, {
45
+ token: string;
46
+ agent?: string | null;
47
+ }>;
48
+ /** Check if a bot is an admin. */
49
+ export declare function isBotAdmin(platformName: string, botName: string): boolean;
50
+ /** Check if a bot name is admin on any platform. */
51
+ export declare function isBotAdminAny(botName: string): boolean;
52
+ /** Get the admin bot name for a platform, if any. */
53
+ export declare function getAdminBotName(platformName: string): string | null;
54
+ /** Get the bot name a channel uses. */
55
+ export declare function getChannelBotName(channelId: string): string;
56
+ /**
57
+ * Hardcoded safety denies — cannot be overridden by config or stored rules.
58
+ * These prevent destructive commands that should never run in any context.
59
+ */
60
+ export declare function isHardDeny(kind: string, command: string | undefined): boolean;
61
+ /** Built-in safety rules surfaced by /remember list — derived from HARDCODED_DENY_RULES. */
62
+ export declare function getHardcodedRules(): Array<{
63
+ spec: string;
64
+ action: 'allow' | 'deny';
65
+ source: 'hardcoded';
66
+ }>;
67
+ /** Config-level rules surfaced by /remember list. */
68
+ export declare function getConfigRules(): Array<{
69
+ spec: string;
70
+ action: 'allow' | 'deny';
71
+ source: 'config';
72
+ }>;
73
+ /**
74
+ * Evaluate config-level permission rules against a permission request.
75
+ * Uses CLI-compatible syntax: shell(cmd), write, read, MCP_SERVER(tool), etc.
76
+ *
77
+ * @returns 'allow' | 'deny' | null (null = no rule matched, ask user)
78
+ */
79
+ export declare function evaluateConfigPermissions(request: {
80
+ kind: string;
81
+ [key: string]: unknown;
82
+ }, channelWorkingDirectory: string, workspaceAllowPaths?: string[], isAdmin?: boolean): 'allow' | 'deny' | null;
83
+ export type ConfigReloadHandler = (result: ReloadResult) => void;
84
+ /**
85
+ * Watches config.json for changes and triggers hot-reload.
86
+ * Follows the same pattern as WorkspaceWatcher: fs.watch + debounce.
87
+ */
88
+ export declare class ConfigWatcher {
89
+ private watcher;
90
+ private handlers;
91
+ private debounceTimer;
92
+ private readonly debounceMs;
93
+ constructor(debounceMs?: number);
94
+ /** Start watching the config file. */
95
+ start(): void;
96
+ /** Stop watching. */
97
+ stop(): void;
98
+ /** Register a reload event handler. */
99
+ onReload(handler: ConfigReloadHandler): void;
100
+ private handleChange;
101
+ }
102
+ /**
103
+ * Reset config state — for testing only.
104
+ * @internal
105
+ */
106
+ export declare function _resetConfigForTest(): void;
107
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}