@codedeck/codedeck 2026.3.1-4.63
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 +38 -0
- package/config/default.yaml +51 -0
- package/dist/agent/brain-dispatcher.d.ts +67 -0
- package/dist/agent/brain-dispatcher.d.ts.map +1 -0
- package/dist/agent/brain-dispatcher.js +136 -0
- package/dist/agent/brain-dispatcher.js.map +1 -0
- package/dist/agent/detect.d.ts +20 -0
- package/dist/agent/detect.d.ts.map +1 -0
- package/dist/agent/detect.js +187 -0
- package/dist/agent/detect.js.map +1 -0
- package/dist/agent/drivers/base.d.ts +57 -0
- package/dist/agent/drivers/base.d.ts.map +1 -0
- package/dist/agent/drivers/base.js +3 -0
- package/dist/agent/drivers/base.js.map +1 -0
- package/dist/agent/drivers/claude-code.d.ts +14 -0
- package/dist/agent/drivers/claude-code.d.ts.map +1 -0
- package/dist/agent/drivers/claude-code.js +112 -0
- package/dist/agent/drivers/claude-code.js.map +1 -0
- package/dist/agent/drivers/codex.d.ts +14 -0
- package/dist/agent/drivers/codex.d.ts.map +1 -0
- package/dist/agent/drivers/codex.js +77 -0
- package/dist/agent/drivers/codex.js.map +1 -0
- package/dist/agent/drivers/gemini.d.ts +24 -0
- package/dist/agent/drivers/gemini.d.ts.map +1 -0
- package/dist/agent/drivers/gemini.js +142 -0
- package/dist/agent/drivers/gemini.js.map +1 -0
- package/dist/agent/drivers/opencode.d.ts +18 -0
- package/dist/agent/drivers/opencode.d.ts.map +1 -0
- package/dist/agent/drivers/opencode.js +50 -0
- package/dist/agent/drivers/opencode.js.map +1 -0
- package/dist/agent/drivers/shell.d.ts +13 -0
- package/dist/agent/drivers/shell.d.ts.map +1 -0
- package/dist/agent/drivers/shell.js +30 -0
- package/dist/agent/drivers/shell.js.map +1 -0
- package/dist/agent/env-isolation.d.ts +26 -0
- package/dist/agent/env-isolation.d.ts.map +1 -0
- package/dist/agent/env-isolation.js +103 -0
- package/dist/agent/env-isolation.js.map +1 -0
- package/dist/agent/notify-setup.d.ts +18 -0
- package/dist/agent/notify-setup.d.ts.map +1 -0
- package/dist/agent/notify-setup.js +68 -0
- package/dist/agent/notify-setup.js.map +1 -0
- package/dist/agent/session-manager.d.ts +75 -0
- package/dist/agent/session-manager.d.ts.map +1 -0
- package/dist/agent/session-manager.js +407 -0
- package/dist/agent/session-manager.js.map +1 -0
- package/dist/agent/signal.d.ts +32 -0
- package/dist/agent/signal.d.ts.map +1 -0
- package/dist/agent/signal.js +199 -0
- package/dist/agent/signal.js.map +1 -0
- package/dist/agent/status-poller.d.ts +27 -0
- package/dist/agent/status-poller.d.ts.map +1 -0
- package/dist/agent/status-poller.js +76 -0
- package/dist/agent/status-poller.js.map +1 -0
- package/dist/agent/templates/brain-prompt.d.ts +14 -0
- package/dist/agent/templates/brain-prompt.d.ts.map +1 -0
- package/dist/agent/templates/brain-prompt.js +57 -0
- package/dist/agent/templates/brain-prompt.js.map +1 -0
- package/dist/agent/templates/identity.d.ts +19 -0
- package/dist/agent/templates/identity.d.ts.map +1 -0
- package/dist/agent/templates/identity.js +97 -0
- package/dist/agent/templates/identity.js.map +1 -0
- package/dist/agent/tmux.d.ts +90 -0
- package/dist/agent/tmux.d.ts.map +1 -0
- package/dist/agent/tmux.js +386 -0
- package/dist/agent/tmux.js.map +1 -0
- package/dist/autofix/audit-engine.d.ts +35 -0
- package/dist/autofix/audit-engine.d.ts.map +1 -0
- package/dist/autofix/audit-engine.js +144 -0
- package/dist/autofix/audit-engine.js.map +1 -0
- package/dist/autofix/branch-manager.d.ts +44 -0
- package/dist/autofix/branch-manager.d.ts.map +1 -0
- package/dist/autofix/branch-manager.js +97 -0
- package/dist/autofix/branch-manager.js.map +1 -0
- package/dist/autofix/decision-engine.d.ts +38 -0
- package/dist/autofix/decision-engine.d.ts.map +1 -0
- package/dist/autofix/decision-engine.js +115 -0
- package/dist/autofix/decision-engine.js.map +1 -0
- package/dist/autofix/index.d.ts +23 -0
- package/dist/autofix/index.d.ts.map +1 -0
- package/dist/autofix/index.js +192 -0
- package/dist/autofix/index.js.map +1 -0
- package/dist/autofix/prompt-builder.d.ts +25 -0
- package/dist/autofix/prompt-builder.d.ts.map +1 -0
- package/dist/autofix/prompt-builder.js +137 -0
- package/dist/autofix/prompt-builder.js.map +1 -0
- package/dist/autofix/report-parser.d.ts +18 -0
- package/dist/autofix/report-parser.d.ts.map +1 -0
- package/dist/autofix/report-parser.js +74 -0
- package/dist/autofix/report-parser.js.map +1 -0
- package/dist/autofix/state-machine.d.ts +40 -0
- package/dist/autofix/state-machine.d.ts.map +1 -0
- package/dist/autofix/state-machine.js +76 -0
- package/dist/autofix/state-machine.js.map +1 -0
- package/dist/bind/bind-flow.d.ts +15 -0
- package/dist/bind/bind-flow.d.ts.map +1 -0
- package/dist/bind/bind-flow.js +198 -0
- package/dist/bind/bind-flow.js.map +1 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +89 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon/codex-watcher.d.ts +46 -0
- package/dist/daemon/codex-watcher.d.ts.map +1 -0
- package/dist/daemon/codex-watcher.js +533 -0
- package/dist/daemon/codex-watcher.js.map +1 -0
- package/dist/daemon/command-handler.d.ts +6 -0
- package/dist/daemon/command-handler.d.ts.map +1 -0
- package/dist/daemon/command-handler.js +770 -0
- package/dist/daemon/command-handler.js.map +1 -0
- package/dist/daemon/discussion-orchestrator.d.ts +63 -0
- package/dist/daemon/discussion-orchestrator.d.ts.map +1 -0
- package/dist/daemon/discussion-orchestrator.js +482 -0
- package/dist/daemon/discussion-orchestrator.js.map +1 -0
- package/dist/daemon/gemini-watcher.d.ts +42 -0
- package/dist/daemon/gemini-watcher.d.ts.map +1 -0
- package/dist/daemon/gemini-watcher.js +463 -0
- package/dist/daemon/gemini-watcher.js.map +1 -0
- package/dist/daemon/hook-server.d.ts +42 -0
- package/dist/daemon/hook-server.d.ts.map +1 -0
- package/dist/daemon/hook-server.js +160 -0
- package/dist/daemon/hook-server.js.map +1 -0
- package/dist/daemon/jsonl-watcher.d.ts +35 -0
- package/dist/daemon/jsonl-watcher.d.ts.map +1 -0
- package/dist/daemon/jsonl-watcher.js +635 -0
- package/dist/daemon/jsonl-watcher.js.map +1 -0
- package/dist/daemon/lifecycle.d.ts +20 -0
- package/dist/daemon/lifecycle.d.ts.map +1 -0
- package/dist/daemon/lifecycle.js +331 -0
- package/dist/daemon/lifecycle.js.map +1 -0
- package/dist/daemon/server-link.d.ts +44 -0
- package/dist/daemon/server-link.d.ts.map +1 -0
- package/dist/daemon/server-link.js +232 -0
- package/dist/daemon/server-link.js.map +1 -0
- package/dist/daemon/subsession-manager.d.ts +37 -0
- package/dist/daemon/subsession-manager.d.ts.map +1 -0
- package/dist/daemon/subsession-manager.js +240 -0
- package/dist/daemon/subsession-manager.js.map +1 -0
- package/dist/daemon/terminal-parser.d.ts +42 -0
- package/dist/daemon/terminal-parser.d.ts.map +1 -0
- package/dist/daemon/terminal-parser.js +278 -0
- package/dist/daemon/terminal-parser.js.map +1 -0
- package/dist/daemon/terminal-streamer.d.ts +93 -0
- package/dist/daemon/terminal-streamer.d.ts.map +1 -0
- package/dist/daemon/terminal-streamer.js +451 -0
- package/dist/daemon/terminal-streamer.js.map +1 -0
- package/dist/daemon/timeline-emitter.d.ts +32 -0
- package/dist/daemon/timeline-emitter.d.ts.map +1 -0
- package/dist/daemon/timeline-emitter.js +97 -0
- package/dist/daemon/timeline-emitter.js.map +1 -0
- package/dist/daemon/timeline-event.d.ts +23 -0
- package/dist/daemon/timeline-event.d.ts.map +1 -0
- package/dist/daemon/timeline-event.js +7 -0
- package/dist/daemon/timeline-event.js.map +1 -0
- package/dist/daemon/timeline-store.d.ts +40 -0
- package/dist/daemon/timeline-store.d.ts.map +1 -0
- package/dist/daemon/timeline-store.js +153 -0
- package/dist/daemon/timeline-store.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +149 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/claude-mem.d.ts +9 -0
- package/dist/memory/claude-mem.d.ts.map +1 -0
- package/dist/memory/claude-mem.js +58 -0
- package/dist/memory/claude-mem.js.map +1 -0
- package/dist/memory/context-builder.d.ts +4 -0
- package/dist/memory/context-builder.d.ts.map +1 -0
- package/dist/memory/context-builder.js +35 -0
- package/dist/memory/context-builder.js.map +1 -0
- package/dist/memory/detector.d.ts +7 -0
- package/dist/memory/detector.d.ts.map +1 -0
- package/dist/memory/detector.js +17 -0
- package/dist/memory/detector.js.map +1 -0
- package/dist/memory/extractor.d.ts +21 -0
- package/dist/memory/extractor.d.ts.map +1 -0
- package/dist/memory/extractor.js +83 -0
- package/dist/memory/extractor.js.map +1 -0
- package/dist/memory/injector.d.ts +7 -0
- package/dist/memory/injector.d.ts.map +1 -0
- package/dist/memory/injector.js +18 -0
- package/dist/memory/injector.js.map +1 -0
- package/dist/memory/interface.d.ts +25 -0
- package/dist/memory/interface.d.ts.map +1 -0
- package/dist/memory/interface.js +3 -0
- package/dist/memory/interface.js.map +1 -0
- package/dist/memory/mem0.d.ts +12 -0
- package/dist/memory/mem0.d.ts.map +1 -0
- package/dist/memory/mem0.js +93 -0
- package/dist/memory/mem0.js.map +1 -0
- package/dist/router/command-parser.d.ts +33 -0
- package/dist/router/command-parser.d.ts.map +1 -0
- package/dist/router/command-parser.js +66 -0
- package/dist/router/command-parser.js.map +1 -0
- package/dist/router/message-router.d.ts +42 -0
- package/dist/router/message-router.d.ts.map +1 -0
- package/dist/router/message-router.js +222 -0
- package/dist/router/message-router.js.map +1 -0
- package/dist/router/response-collector.d.ts +28 -0
- package/dist/router/response-collector.d.ts.map +1 -0
- package/dist/router/response-collector.js +164 -0
- package/dist/router/response-collector.js.map +1 -0
- package/dist/store/project-store.d.ts +37 -0
- package/dist/store/project-store.d.ts.map +1 -0
- package/dist/store/project-store.js +70 -0
- package/dist/store/project-store.js.map +1 -0
- package/dist/store/session-store.d.ts +32 -0
- package/dist/store/session-store.d.ts.map +1 -0
- package/dist/store/session-store.js +67 -0
- package/dist/store/session-store.js.map +1 -0
- package/dist/tracker/branch.d.ts +24 -0
- package/dist/tracker/branch.d.ts.map +1 -0
- package/dist/tracker/branch.js +55 -0
- package/dist/tracker/branch.js.map +1 -0
- package/dist/tracker/github.d.ts +31 -0
- package/dist/tracker/github.d.ts.map +1 -0
- package/dist/tracker/github.js +117 -0
- package/dist/tracker/github.js.map +1 -0
- package/dist/tracker/gitlab.d.ts +31 -0
- package/dist/tracker/gitlab.d.ts.map +1 -0
- package/dist/tracker/gitlab.js +116 -0
- package/dist/tracker/gitlab.js.map +1 -0
- package/dist/tracker/index.d.ts +9 -0
- package/dist/tracker/index.d.ts.map +1 -0
- package/dist/tracker/index.js +28 -0
- package/dist/tracker/index.js.map +1 -0
- package/dist/tracker/interface.d.ts +39 -0
- package/dist/tracker/interface.d.ts.map +1 -0
- package/dist/tracker/interface.js +7 -0
- package/dist/tracker/interface.js.map +1 -0
- package/dist/tracker/priority.d.ts +19 -0
- package/dist/tracker/priority.d.ts.map +1 -0
- package/dist/tracker/priority.js +40 -0
- package/dist/tracker/priority.js.map +1 -0
- package/dist/util/logger.d.ts +4 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +14 -0
- package/dist/util/logger.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.bindChannel = bindChannel;
|
|
7
|
+
exports.unbindChannel = unbindChannel;
|
|
8
|
+
exports.getBinding = getBinding;
|
|
9
|
+
exports.getAllBindings = getAllBindings;
|
|
10
|
+
exports.routeMessage = routeMessage;
|
|
11
|
+
/**
|
|
12
|
+
* Route normalized InboundMessages (received from CF Worker via WebSocket) to the correct
|
|
13
|
+
* session based on channel bindings. Manages channel binding state and checks team permissions.
|
|
14
|
+
*/
|
|
15
|
+
const command_parser_js_1 = require("./command-parser.js");
|
|
16
|
+
const session_store_js_1 = require("../store/session-store.js");
|
|
17
|
+
const logger_js_1 = __importDefault(require("../util/logger.js"));
|
|
18
|
+
const timeline_emitter_js_1 = require("../daemon/timeline-emitter.js");
|
|
19
|
+
// ── In-memory binding store (persisted via CF Worker D1 — this is daemon-side cache) ─────
|
|
20
|
+
const bindings = new Map();
|
|
21
|
+
function bindingKey(platform, channelId, botId) {
|
|
22
|
+
return `${platform}:${channelId}:${botId}`;
|
|
23
|
+
}
|
|
24
|
+
function bindChannel(platform, channelId, botId, projectName, userId, opts) {
|
|
25
|
+
const key = bindingKey(platform, channelId, botId);
|
|
26
|
+
bindings.set(key, {
|
|
27
|
+
platform, channelId, botId, projectName, boundBy: userId, boundAt: Date.now(),
|
|
28
|
+
teamId: opts?.teamId,
|
|
29
|
+
allowedUserIds: opts?.allowedUserIds,
|
|
30
|
+
});
|
|
31
|
+
logger_js_1.default.info({ platform, channelId, botId, projectName, teamId: opts?.teamId }, 'Channel bound to project');
|
|
32
|
+
}
|
|
33
|
+
function unbindChannel(platform, channelId, botId) {
|
|
34
|
+
const key = bindingKey(platform, channelId, botId);
|
|
35
|
+
bindings.delete(key);
|
|
36
|
+
logger_js_1.default.info({ platform, channelId, botId }, 'Channel unbound');
|
|
37
|
+
}
|
|
38
|
+
function getBinding(platform, channelId, botId) {
|
|
39
|
+
return bindings.get(bindingKey(platform, channelId, botId));
|
|
40
|
+
}
|
|
41
|
+
function getAllBindings() {
|
|
42
|
+
return Array.from(bindings.values());
|
|
43
|
+
}
|
|
44
|
+
async function routeMessage(msg, ctx) {
|
|
45
|
+
logger_js_1.default.debug({ platform: msg.platform, channelId: msg.channelId, userId: msg.userId }, 'Routing inbound message');
|
|
46
|
+
// Parse the command
|
|
47
|
+
let parsed;
|
|
48
|
+
if (msg.isCommand && msg.command) {
|
|
49
|
+
parsed = (0, command_parser_js_1.fromPlatformCommand)(msg.command, msg.args ?? [], msg.content);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
parsed = (0, command_parser_js_1.parseCommand)(msg.content);
|
|
53
|
+
}
|
|
54
|
+
// Handle bind command (no binding required for this one)
|
|
55
|
+
if (parsed.isCommand && parsed.command?.name === 'bind') {
|
|
56
|
+
await handleBind(msg, parsed.command.args, ctx);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Handle help command (always available)
|
|
60
|
+
if (parsed.isCommand && parsed.command?.name === 'help') {
|
|
61
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, buildHelpText());
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// All other commands require a channel binding
|
|
65
|
+
const binding = getBinding(msg.platform, msg.channelId, msg.botId);
|
|
66
|
+
if (!binding) {
|
|
67
|
+
if (parsed.isCommand) {
|
|
68
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, 'This channel is not bound to a project. Use /bind <project-name> to get started.');
|
|
69
|
+
}
|
|
70
|
+
// Non-command messages with no binding are silently dropped
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Check team-scoped access: if binding has allowedUserIds, verify membership
|
|
74
|
+
if (binding.allowedUserIds && !binding.allowedUserIds.includes(msg.userId)) {
|
|
75
|
+
logger_js_1.default.debug({ userId: msg.userId, channelId: msg.channelId }, 'Access denied: not in allowed team members');
|
|
76
|
+
return; // silently drop — team membership check happens server-side
|
|
77
|
+
}
|
|
78
|
+
if (parsed.isCommand && parsed.command) {
|
|
79
|
+
await handleCommand(msg, parsed.command, binding, ctx);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Plain text → send to brain session
|
|
83
|
+
await forwardToBrain(msg, binding, ctx);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// ── Command handlers ──────────────────────────────────────────────────────────
|
|
87
|
+
async function handleBind(msg, args, ctx) {
|
|
88
|
+
if (args.length === 0) {
|
|
89
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, 'Usage: /bind <project-name>');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const projectName = args[0];
|
|
93
|
+
const sessions = (0, session_store_js_1.listSessions)();
|
|
94
|
+
const brainSession = sessions.find((s) => s.projectName === projectName && s.role === 'brain');
|
|
95
|
+
if (!brainSession) {
|
|
96
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, `Project "${projectName}" has no active brain session. Start it first with: codedeck project start ${projectName}`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
bindChannel(msg.platform, msg.channelId, msg.botId, projectName, msg.userId);
|
|
100
|
+
// Persist to D1 via CF Worker so inbound webhook routing survives restarts.
|
|
101
|
+
// If persistence fails, roll back the in-memory bind and report the error.
|
|
102
|
+
if (ctx.persistBinding) {
|
|
103
|
+
const ok = await ctx.persistBinding(msg.platform, msg.channelId, msg.botId, 'project', projectName);
|
|
104
|
+
if (!ok) {
|
|
105
|
+
unbindChannel(msg.platform, msg.channelId, msg.botId);
|
|
106
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, `Failed to bind channel — could not reach the server. Please try again.`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, `Channel bound to project "${projectName}". Send messages here to interact with the brain.`);
|
|
111
|
+
}
|
|
112
|
+
async function handleCommand(msg, command, binding, ctx) {
|
|
113
|
+
const { projectName } = binding;
|
|
114
|
+
const brainSessionName = `deck_${projectName}_brain`;
|
|
115
|
+
switch (command.name) {
|
|
116
|
+
case 'status': {
|
|
117
|
+
const sessions = (0, session_store_js_1.listSessions)();
|
|
118
|
+
const projectSessions = sessions.filter((s) => s.projectName === projectName);
|
|
119
|
+
if (projectSessions.length === 0) {
|
|
120
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, `No sessions for project "${projectName}"`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const lines = projectSessions.map((s) => `${s.name}: ${s.state} (${s.agentType})`);
|
|
124
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, lines.join('\n'));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
case 'list': {
|
|
128
|
+
const sessions = (0, session_store_js_1.listSessions)();
|
|
129
|
+
const names = sessions.map((s) => `${s.projectName}/${s.role} [${s.state}]`).join('\n');
|
|
130
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, names || 'No active sessions');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
case 'stop': {
|
|
134
|
+
await ctx.sendToSession(brainSessionName, '@stop');
|
|
135
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, `Stop signal sent to project "${projectName}"`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
case 'screen': {
|
|
139
|
+
const sessionName = command.args[0]
|
|
140
|
+
? `deck_${projectName}_${command.args[0]}`
|
|
141
|
+
: brainSessionName;
|
|
142
|
+
const session = (0, session_store_js_1.getSession)(sessionName);
|
|
143
|
+
if (!session) {
|
|
144
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, `Session "${sessionName}" not found`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
// The response-collector will capture screen and send it; just request it
|
|
148
|
+
await ctx.sendToSession(brainSessionName, `@screen ${sessionName}`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
case 'send': {
|
|
152
|
+
if (command.rawArgs) {
|
|
153
|
+
await forwardTextToBrain(brainSessionName, command.rawArgs, ctx);
|
|
154
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, 'Message sent to brain.');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, 'Usage: /send <message>');
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
case 'team': {
|
|
162
|
+
const sub = command.args[0]?.toLowerCase();
|
|
163
|
+
const teamHelpText = [
|
|
164
|
+
'**Team commands:**',
|
|
165
|
+
'/team create <name> — Create a new team',
|
|
166
|
+
'/team invite — Generate an invite link (must be admin/owner)',
|
|
167
|
+
'/team members — List team members',
|
|
168
|
+
'/team role <userId> <role> — Change member role',
|
|
169
|
+
'/team remove <userId> — Remove a member',
|
|
170
|
+
'/team delete — Delete the team (owner only)',
|
|
171
|
+
'',
|
|
172
|
+
'Team management is available at the web UI or via the REST API.',
|
|
173
|
+
].join('\n');
|
|
174
|
+
if (!sub || sub === 'help') {
|
|
175
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, teamHelpText);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Forward team management commands to brain as structured request
|
|
179
|
+
const teamCommand = `/team ${command.rawArgs}`;
|
|
180
|
+
await forwardTextToBrain(brainSessionName, teamCommand, ctx);
|
|
181
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, `Team command forwarded to brain: \`${teamCommand}\`. Check the web UI for results.`);
|
|
182
|
+
}
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
case 'help': {
|
|
186
|
+
await ctx.sendOutbound(msg.channelId, msg.platform, msg.botId, buildHelpText());
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
default:
|
|
190
|
+
// Forward unknown/unhandled commands as plain text to brain
|
|
191
|
+
await forwardToBrain(msg, binding, ctx);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async function forwardToBrain(msg, binding, ctx) {
|
|
195
|
+
const brainSessionName = `deck_${binding.projectName}_brain`;
|
|
196
|
+
await forwardTextToBrain(brainSessionName, msg.content, ctx);
|
|
197
|
+
}
|
|
198
|
+
async function forwardTextToBrain(brainSessionName, text, ctx) {
|
|
199
|
+
try {
|
|
200
|
+
await ctx.sendToSession(brainSessionName, text);
|
|
201
|
+
timeline_emitter_js_1.timelineEmitter.emit(brainSessionName, 'user.message', { text });
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
logger_js_1.default.error({ brainSessionName, err }, 'Failed to forward text to brain session');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function buildHelpText() {
|
|
208
|
+
return [
|
|
209
|
+
'**Available commands:**',
|
|
210
|
+
'/bind <project> — Bind this channel to a project',
|
|
211
|
+
'/status — Show project session status',
|
|
212
|
+
'/list — List all active sessions',
|
|
213
|
+
'/send <message> — Send message to brain',
|
|
214
|
+
'/screen [session] — Get current screen output',
|
|
215
|
+
'/stop — Send stop signal to brain',
|
|
216
|
+
'/team [subcommand] — Team management (create/invite/members/role/remove)',
|
|
217
|
+
'/cron — Cron job management',
|
|
218
|
+
'/autofix — Run the auto-fix pipeline',
|
|
219
|
+
'/help — Show this help',
|
|
220
|
+
].join('\n');
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=message-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-router.js","sourceRoot":"","sources":["../../src/router/message-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type OutboundSender = (msg: OutboundPayload) => Promise<void>;
|
|
2
|
+
export interface OutboundPayload {
|
|
3
|
+
platform: string;
|
|
4
|
+
botId: string;
|
|
5
|
+
channelId: string;
|
|
6
|
+
content: string;
|
|
7
|
+
replyToId?: string;
|
|
8
|
+
formatting?: 'plain' | 'markdown' | 'code';
|
|
9
|
+
}
|
|
10
|
+
export type AutoFixIdleHandler = (sessionName: string, output: string) => Promise<void>;
|
|
11
|
+
/** Register a session as auto-fix mode — idle will call handler instead of sending to channels. */
|
|
12
|
+
export declare function registerAutoFixSession(sessionName: string, handler: AutoFixIdleHandler): void;
|
|
13
|
+
/** Unregister auto-fix mode for a session (call when pipeline completes/fails). */
|
|
14
|
+
export declare function unregisterAutoFixSession(sessionName: string): void;
|
|
15
|
+
/**
|
|
16
|
+
* Capture the current screen of a session and return the diff since last capture.
|
|
17
|
+
* Returns null if nothing has changed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function captureAndDiff(sessionName: string): Promise<string | null>;
|
|
20
|
+
/**
|
|
21
|
+
* On agent idle, capture output since last idle → clean → dispatch to all bound channels.
|
|
22
|
+
*/
|
|
23
|
+
export declare function onAgentIdle(sessionName: string, projectName: string, sendOutbound: OutboundSender): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Clear the screen tracking for a session (e.g., on session restart).
|
|
26
|
+
*/
|
|
27
|
+
export declare function clearScreenState(sessionName: string): void;
|
|
28
|
+
//# sourceMappingURL=response-collector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-collector.d.ts","sourceRoot":"","sources":["../../src/router/response-collector.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;CAC5C;AAID,MAAM,MAAM,kBAAkB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAKxF,mGAAmG;AACnG,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAE7F;AAED,mFAAmF;AACnF,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAElE;AAMD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAchF;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,cAAc,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyCf;AAyED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAE1D"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.registerAutoFixSession = registerAutoFixSession;
|
|
7
|
+
exports.unregisterAutoFixSession = unregisterAutoFixSession;
|
|
8
|
+
exports.captureAndDiff = captureAndDiff;
|
|
9
|
+
exports.onAgentIdle = onAgentIdle;
|
|
10
|
+
exports.clearScreenState = clearScreenState;
|
|
11
|
+
/**
|
|
12
|
+
* Detect agent idle → diff screen → clean output → send OutboundMessage to CF Worker.
|
|
13
|
+
* CF Worker handler handles platform-specific message splitting and formatting.
|
|
14
|
+
*/
|
|
15
|
+
const tmux_js_1 = require("../agent/tmux.js");
|
|
16
|
+
const message_router_js_1 = require("./message-router.js");
|
|
17
|
+
const logger_js_1 = __importDefault(require("../util/logger.js"));
|
|
18
|
+
/** Sessions registered for auto-fix mode. Idle triggers the handler instead of channel dispatch. */
|
|
19
|
+
const autoFixSessions = new Map();
|
|
20
|
+
/** Register a session as auto-fix mode — idle will call handler instead of sending to channels. */
|
|
21
|
+
function registerAutoFixSession(sessionName, handler) {
|
|
22
|
+
autoFixSessions.set(sessionName, handler);
|
|
23
|
+
}
|
|
24
|
+
/** Unregister auto-fix mode for a session (call when pipeline completes/fails). */
|
|
25
|
+
function unregisterAutoFixSession(sessionName) {
|
|
26
|
+
autoFixSessions.delete(sessionName);
|
|
27
|
+
}
|
|
28
|
+
// ── Screen diff tracking ──────────────────────────────────────────────────────
|
|
29
|
+
const lastScreens = new Map();
|
|
30
|
+
/**
|
|
31
|
+
* Capture the current screen of a session and return the diff since last capture.
|
|
32
|
+
* Returns null if nothing has changed.
|
|
33
|
+
*/
|
|
34
|
+
async function captureAndDiff(sessionName) {
|
|
35
|
+
let current;
|
|
36
|
+
try {
|
|
37
|
+
current = (await (0, tmux_js_1.capturePane)(sessionName)).join('\n');
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
logger_js_1.default.debug({ sessionName, err }, 'capturePane failed');
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const previous = lastScreens.get(sessionName) ?? '';
|
|
44
|
+
if (current === previous)
|
|
45
|
+
return null;
|
|
46
|
+
lastScreens.set(sessionName, current);
|
|
47
|
+
return diffScreens(previous, current);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* On agent idle, capture output since last idle → clean → dispatch to all bound channels.
|
|
51
|
+
*/
|
|
52
|
+
async function onAgentIdle(sessionName, projectName, sendOutbound) {
|
|
53
|
+
const diff = await captureAndDiff(sessionName);
|
|
54
|
+
if (!diff || diff.trim().length === 0) {
|
|
55
|
+
logger_js_1.default.debug({ sessionName }, 'No diff on idle — skipping outbound');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const cleaned = cleanOutput(diff);
|
|
59
|
+
if (!cleaned)
|
|
60
|
+
return;
|
|
61
|
+
// Auto-fix mode: route to state machine instead of channel dispatch
|
|
62
|
+
const autoFixHandler = autoFixSessions.get(sessionName);
|
|
63
|
+
if (autoFixHandler) {
|
|
64
|
+
try {
|
|
65
|
+
await autoFixHandler(sessionName, cleaned);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
logger_js_1.default.error({ sessionName, err }, 'Auto-fix idle handler failed');
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Find all channels bound to this project
|
|
73
|
+
const bindings = (0, message_router_js_1.getAllBindings)().filter((b) => b.projectName === projectName);
|
|
74
|
+
if (bindings.length === 0) {
|
|
75
|
+
logger_js_1.default.debug({ projectName }, 'No channel bindings for project — not sending response');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
for (const binding of bindings) {
|
|
79
|
+
try {
|
|
80
|
+
await sendOutbound({
|
|
81
|
+
platform: binding.platform,
|
|
82
|
+
botId: binding.botId,
|
|
83
|
+
channelId: binding.channelId,
|
|
84
|
+
content: cleaned,
|
|
85
|
+
formatting: detectFormatting(cleaned),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
logger_js_1.default.error({ platform: binding.platform, channelId: binding.channelId, err }, 'sendOutbound failed');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Compute a textual diff between two screen snapshots.
|
|
96
|
+
* Returns the new/changed lines in the current snapshot.
|
|
97
|
+
*/
|
|
98
|
+
function diffScreens(previous, current) {
|
|
99
|
+
const prevLines = previous.split('\n');
|
|
100
|
+
const currLines = current.split('\n');
|
|
101
|
+
// If current is shorter (screen was cleared/reset), return the full current
|
|
102
|
+
if (currLines.length < prevLines.length) {
|
|
103
|
+
return current;
|
|
104
|
+
}
|
|
105
|
+
// Find where the new content starts (first diverging line from the end)
|
|
106
|
+
let diffStart = 0;
|
|
107
|
+
for (let i = 0; i < prevLines.length && i < currLines.length; i++) {
|
|
108
|
+
if (prevLines[i] !== currLines[i]) {
|
|
109
|
+
diffStart = i;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
diffStart = i + 1;
|
|
113
|
+
}
|
|
114
|
+
const newLines = currLines.slice(diffStart);
|
|
115
|
+
return newLines.join('\n');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Clean tmux pane output:
|
|
119
|
+
* - Remove ANSI escape codes
|
|
120
|
+
* - Remove trailing whitespace per line
|
|
121
|
+
* - Collapse runs of blank lines to one
|
|
122
|
+
* - Trim overall
|
|
123
|
+
*/
|
|
124
|
+
function cleanOutput(raw) {
|
|
125
|
+
// Strip ANSI escape sequences
|
|
126
|
+
// eslint-disable-next-line no-control-regex
|
|
127
|
+
const stripped = raw.replace(/\x1b\[[0-9;]*[mGKHFJABCDEFhlr]/g, '');
|
|
128
|
+
const lines = stripped
|
|
129
|
+
.split('\n')
|
|
130
|
+
.map((l) => l.trimEnd());
|
|
131
|
+
// Collapse multiple blank lines
|
|
132
|
+
const collapsed = [];
|
|
133
|
+
let blankCount = 0;
|
|
134
|
+
for (const line of lines) {
|
|
135
|
+
if (line === '') {
|
|
136
|
+
blankCount++;
|
|
137
|
+
if (blankCount <= 1)
|
|
138
|
+
collapsed.push(line);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
blankCount = 0;
|
|
142
|
+
collapsed.push(line);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return collapsed.join('\n').trim();
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Detect whether output is code/markdown or plain text.
|
|
149
|
+
* Simple heuristic: contains code fences → code; contains markdown headers → markdown.
|
|
150
|
+
*/
|
|
151
|
+
function detectFormatting(text) {
|
|
152
|
+
if (text.includes('```'))
|
|
153
|
+
return 'code';
|
|
154
|
+
if (/^#{1,3} /m.test(text))
|
|
155
|
+
return 'markdown';
|
|
156
|
+
return 'plain';
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Clear the screen tracking for a session (e.g., on session restart).
|
|
160
|
+
*/
|
|
161
|
+
function clearScreenState(sessionName) {
|
|
162
|
+
lastScreens.delete(sessionName);
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=response-collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response-collector.js","sourceRoot":"","sources":["../../src/router/response-collector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface ProjectTrackerConfig {
|
|
2
|
+
type: 'github' | 'gitlab';
|
|
3
|
+
apiUrl?: string;
|
|
4
|
+
tokenEnv: string;
|
|
5
|
+
repo?: string;
|
|
6
|
+
projectId?: string;
|
|
7
|
+
baseBranch: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ProjectConfig {
|
|
10
|
+
name: string;
|
|
11
|
+
dir: string;
|
|
12
|
+
coderAgent: string;
|
|
13
|
+
auditorAgent: string;
|
|
14
|
+
maxDiscussionRounds: number;
|
|
15
|
+
autoMerge: boolean;
|
|
16
|
+
tracker?: ProjectTrackerConfig;
|
|
17
|
+
issueFilters?: {
|
|
18
|
+
labels?: string[];
|
|
19
|
+
assignedToMe?: boolean;
|
|
20
|
+
milestone?: string;
|
|
21
|
+
};
|
|
22
|
+
createdAt: number;
|
|
23
|
+
updatedAt: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ProjectStore {
|
|
26
|
+
projects: Record<string, ProjectConfig>;
|
|
27
|
+
}
|
|
28
|
+
export declare function loadProjectStore(): Promise<ProjectStore>;
|
|
29
|
+
export declare function getProject(name: string): ProjectConfig | undefined;
|
|
30
|
+
export declare function upsertProject(config: Omit<ProjectConfig, 'createdAt' | 'updatedAt'> & {
|
|
31
|
+
createdAt?: number;
|
|
32
|
+
}): void;
|
|
33
|
+
export declare function removeProject(name: string): void;
|
|
34
|
+
export declare function listProjects(): ProjectConfig[];
|
|
35
|
+
export declare function updateProject(name: string, patch: Partial<Omit<ProjectConfig, 'name' | 'createdAt'>>): void;
|
|
36
|
+
export declare function flushProjectStore(): Promise<void>;
|
|
37
|
+
//# sourceMappingURL=project-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-store.d.ts","sourceRoot":"","sources":["../../src/store/project-store.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,YAAY,CAAC,EAAE;QACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACzC;AAKD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC,CAS9D;AAUD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAElE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQnH;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGhD;AAED,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAE9C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,GAAG,IAAI,CAK3G;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAMvD"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadProjectStore = loadProjectStore;
|
|
4
|
+
exports.getProject = getProject;
|
|
5
|
+
exports.upsertProject = upsertProject;
|
|
6
|
+
exports.removeProject = removeProject;
|
|
7
|
+
exports.listProjects = listProjects;
|
|
8
|
+
exports.updateProject = updateProject;
|
|
9
|
+
exports.flushProjectStore = flushProjectStore;
|
|
10
|
+
const promises_1 = require("fs/promises");
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
const os_1 = require("os");
|
|
13
|
+
const STORE_DIR = (0, path_1.join)((0, os_1.homedir)(), '.codedeck');
|
|
14
|
+
const STORE_PATH = (0, path_1.join)(STORE_DIR, 'projects.json');
|
|
15
|
+
const DEBOUNCE_MS = 500;
|
|
16
|
+
let writeTimer = null;
|
|
17
|
+
let store = { projects: {} };
|
|
18
|
+
async function loadProjectStore() {
|
|
19
|
+
await (0, promises_1.mkdir)(STORE_DIR, { recursive: true });
|
|
20
|
+
try {
|
|
21
|
+
const raw = await (0, promises_1.readFile)(STORE_PATH, 'utf8');
|
|
22
|
+
store = JSON.parse(raw);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
store = { projects: {} };
|
|
26
|
+
}
|
|
27
|
+
return store;
|
|
28
|
+
}
|
|
29
|
+
function scheduleWrite() {
|
|
30
|
+
if (writeTimer)
|
|
31
|
+
clearTimeout(writeTimer);
|
|
32
|
+
writeTimer = setTimeout(async () => {
|
|
33
|
+
await (0, promises_1.writeFile)(STORE_PATH, JSON.stringify(store, null, 2), 'utf8');
|
|
34
|
+
writeTimer = null;
|
|
35
|
+
}, DEBOUNCE_MS);
|
|
36
|
+
}
|
|
37
|
+
function getProject(name) {
|
|
38
|
+
return store.projects[name];
|
|
39
|
+
}
|
|
40
|
+
function upsertProject(config) {
|
|
41
|
+
const existing = store.projects[config.name];
|
|
42
|
+
store.projects[config.name] = {
|
|
43
|
+
...config,
|
|
44
|
+
createdAt: config.createdAt ?? existing?.createdAt ?? Date.now(),
|
|
45
|
+
updatedAt: Date.now(),
|
|
46
|
+
};
|
|
47
|
+
scheduleWrite();
|
|
48
|
+
}
|
|
49
|
+
function removeProject(name) {
|
|
50
|
+
delete store.projects[name];
|
|
51
|
+
scheduleWrite();
|
|
52
|
+
}
|
|
53
|
+
function listProjects() {
|
|
54
|
+
return Object.values(store.projects);
|
|
55
|
+
}
|
|
56
|
+
function updateProject(name, patch) {
|
|
57
|
+
const p = store.projects[name];
|
|
58
|
+
if (!p)
|
|
59
|
+
return;
|
|
60
|
+
Object.assign(p, patch, { updatedAt: Date.now() });
|
|
61
|
+
scheduleWrite();
|
|
62
|
+
}
|
|
63
|
+
async function flushProjectStore() {
|
|
64
|
+
if (writeTimer) {
|
|
65
|
+
clearTimeout(writeTimer);
|
|
66
|
+
writeTimer = null;
|
|
67
|
+
}
|
|
68
|
+
await (0, promises_1.writeFile)(STORE_PATH, JSON.stringify(store, null, 2), 'utf8');
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=project-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-store.js","sourceRoot":"","sources":["../../src/store/project-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type SessionState = 'running' | 'idle' | 'error' | 'stopped';
|
|
2
|
+
export interface SessionRecord {
|
|
3
|
+
name: string;
|
|
4
|
+
projectName: string;
|
|
5
|
+
role: 'brain' | `w${number}`;
|
|
6
|
+
agentType: string;
|
|
7
|
+
projectDir: string;
|
|
8
|
+
state: SessionState;
|
|
9
|
+
restarts: number;
|
|
10
|
+
restartTimestamps: number[];
|
|
11
|
+
createdAt: number;
|
|
12
|
+
updatedAt: number;
|
|
13
|
+
/** tmux pane ID (e.g. "%42") recorded at session creation. Used for pipe-pane streaming. */
|
|
14
|
+
paneId?: string;
|
|
15
|
+
/** CC session UUID used with --session-id / --resume for deterministic JSONL path. */
|
|
16
|
+
ccSessionId?: string;
|
|
17
|
+
/** Codex session UUID extracted from rollout filename, used for `codex resume <UUID>`. */
|
|
18
|
+
codexSessionId?: string;
|
|
19
|
+
/** Gemini session UUID obtained from stream-json init event, used for `gemini --resume <UUID>`. */
|
|
20
|
+
geminiSessionId?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SessionStore {
|
|
23
|
+
sessions: Record<string, SessionRecord>;
|
|
24
|
+
}
|
|
25
|
+
export declare function loadStore(): Promise<SessionStore>;
|
|
26
|
+
export declare function getSession(name: string): SessionRecord | undefined;
|
|
27
|
+
export declare function upsertSession(record: SessionRecord): void;
|
|
28
|
+
export declare function removeSession(name: string): void;
|
|
29
|
+
export declare function listSessions(projectName?: string): SessionRecord[];
|
|
30
|
+
export declare function updateSessionState(name: string, state: SessionState): void;
|
|
31
|
+
export declare function flushStore(): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=session-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/store/session-store.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,GAAG,IAAI,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mGAAmG;IACnG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACzC;AAKD,wBAAsB,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,CASvD;AAUD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAElE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAGzD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGhD;AAED,wBAAgB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAGlE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAM1E;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAMhD"}
|