@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,386 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.sendKeysDelayedEnter = void 0;
|
|
37
|
+
exports.tmuxExec = tmuxExec;
|
|
38
|
+
exports.capturePane = capturePane;
|
|
39
|
+
exports.capturePaneVisible = capturePaneVisible;
|
|
40
|
+
exports.capturePaneHistory = capturePaneHistory;
|
|
41
|
+
exports.sendKeys = sendKeys;
|
|
42
|
+
exports.sendKey = sendKey;
|
|
43
|
+
exports.newSession = newSession;
|
|
44
|
+
exports.killSession = killSession;
|
|
45
|
+
exports.listSessions = listSessions;
|
|
46
|
+
exports.sessionExists = sessionExists;
|
|
47
|
+
exports.resizeSession = resizeSession;
|
|
48
|
+
exports.getPaneSize = getPaneSize;
|
|
49
|
+
exports.showBuffer = showBuffer;
|
|
50
|
+
exports.getPaneId = getPaneId;
|
|
51
|
+
exports.getPaneCwd = getPaneCwd;
|
|
52
|
+
exports.deleteBuffer = deleteBuffer;
|
|
53
|
+
exports.sendRawInput = sendRawInput;
|
|
54
|
+
exports.checkPipePaneCapability = checkPipePaneCapability;
|
|
55
|
+
exports.startPipePaneStream = startPipePaneStream;
|
|
56
|
+
exports.stopPipePaneStream = stopPipePaneStream;
|
|
57
|
+
exports.cleanupOrphanFifos = cleanupOrphanFifos;
|
|
58
|
+
const child_process_1 = require("child_process");
|
|
59
|
+
const util_1 = require("util");
|
|
60
|
+
const fs = __importStar(require("fs"));
|
|
61
|
+
const fsp = __importStar(require("fs/promises"));
|
|
62
|
+
const os = __importStar(require("os"));
|
|
63
|
+
const path = __importStar(require("path"));
|
|
64
|
+
const net_1 = require("net");
|
|
65
|
+
const exec = (0, util_1.promisify)(child_process_1.exec);
|
|
66
|
+
const execFile = (0, util_1.promisify)(child_process_1.execFile);
|
|
67
|
+
/** Run a raw tmux command. */
|
|
68
|
+
async function tmuxExec(args) {
|
|
69
|
+
const { stdout } = await exec(`tmux ${args}`);
|
|
70
|
+
return stdout.trim();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Capture the visible content of a tmux pane (scrollback history).
|
|
74
|
+
* Returns lines as a string array.
|
|
75
|
+
*/
|
|
76
|
+
async function capturePane(session, lines = 50) {
|
|
77
|
+
const raw = await tmuxExec(`capture-pane -p -t ${session} -S -${lines}`);
|
|
78
|
+
return raw.split('\n');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Capture only the currently visible pane with ANSI color codes.
|
|
82
|
+
* Used for terminal streaming — gives exactly the rows the user sees.
|
|
83
|
+
*/
|
|
84
|
+
async function capturePaneVisible(session) {
|
|
85
|
+
return tmuxExec(`capture-pane -e -p -t ${session}`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Capture scrollback history (above the visible area) with ANSI colors.
|
|
89
|
+
* -S -N starts N lines before visible top; -E -1 ends at the line before visible row 0.
|
|
90
|
+
*/
|
|
91
|
+
async function capturePaneHistory(session, lines = 1000) {
|
|
92
|
+
return tmuxExec(`capture-pane -e -p -t ${session} -S -${lines} -E -1`);
|
|
93
|
+
}
|
|
94
|
+
/** Send a string of keys to a tmux pane (newline = Enter). */
|
|
95
|
+
/**
|
|
96
|
+
* Send text then Enter to a tmux session.
|
|
97
|
+
* Text and Enter are sent separately with a short delay to avoid
|
|
98
|
+
* paste-burst detection in TUI agents (Codex, Gemini, etc.).
|
|
99
|
+
*/
|
|
100
|
+
async function sendKeys(session, keys) {
|
|
101
|
+
const escaped = keys.replace(/'/g, "'\\''");
|
|
102
|
+
await tmuxExec(`send-keys -t ${session} -l -- '${escaped}'`);
|
|
103
|
+
await new Promise((r) => setTimeout(r, 80));
|
|
104
|
+
await tmuxExec(`send-keys -t ${session} Enter`);
|
|
105
|
+
}
|
|
106
|
+
/** @deprecated Use sendKeys — kept as alias for backward compat. */
|
|
107
|
+
exports.sendKeysDelayedEnter = sendKeys;
|
|
108
|
+
/** Send raw keys without appending Enter (e.g. for Ctrl-C). */
|
|
109
|
+
async function sendKey(session, key) {
|
|
110
|
+
await tmuxExec(`send-keys -t ${session} ${key}`);
|
|
111
|
+
}
|
|
112
|
+
/** Create a new detached tmux session. Throws if it already exists. */
|
|
113
|
+
async function newSession(name, command, opts) {
|
|
114
|
+
const cwdArg = opts?.cwd ? `-c ${JSON.stringify(opts.cwd)}` : '';
|
|
115
|
+
const envArgs = opts?.env
|
|
116
|
+
? Object.entries(opts.env)
|
|
117
|
+
.map(([k, v]) => `-e ${k}=${JSON.stringify(v)}`)
|
|
118
|
+
.join(' ')
|
|
119
|
+
: '';
|
|
120
|
+
// Quote the command with single quotes so the outer /bin/sh does NOT interpret
|
|
121
|
+
// shell operators (&&, ||, etc.) — tmux receives the full string and runs it
|
|
122
|
+
// via $SHELL -c internally.
|
|
123
|
+
const cmdArg = command ? `-- '${command.replace(/'/g, "'\\''")}'` : '';
|
|
124
|
+
await tmuxExec(`new-session -d -s ${name} ${cwdArg} ${envArgs} ${cmdArg}`.trim());
|
|
125
|
+
}
|
|
126
|
+
/** Kill a tmux session by name. Does not throw if it doesn't exist. */
|
|
127
|
+
async function killSession(name) {
|
|
128
|
+
try {
|
|
129
|
+
await tmuxExec(`kill-session -t ${name}`);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// session may not exist
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** List all tmux sessions. Returns session names. */
|
|
136
|
+
async function listSessions() {
|
|
137
|
+
try {
|
|
138
|
+
const raw = await tmuxExec(`list-sessions -F '#{session_name}'`);
|
|
139
|
+
return raw.split('\n').filter(Boolean);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** Check if a tmux session exists. */
|
|
146
|
+
async function sessionExists(name) {
|
|
147
|
+
const sessions = await listSessions();
|
|
148
|
+
return sessions.includes(name);
|
|
149
|
+
}
|
|
150
|
+
/** Resize a tmux session window to the given dimensions. */
|
|
151
|
+
async function resizeSession(name, cols, rows) {
|
|
152
|
+
await tmuxExec(`resize-window -t ${name} -x ${cols} -y ${rows}`);
|
|
153
|
+
}
|
|
154
|
+
/** Get the pane size (cols x rows) of a tmux session. */
|
|
155
|
+
async function getPaneSize(session) {
|
|
156
|
+
try {
|
|
157
|
+
const raw = await tmuxExec(`display-message -p -t ${session} '#{pane_width} #{pane_height}'`);
|
|
158
|
+
const [cols, rows] = raw.split(' ').map(Number);
|
|
159
|
+
return { cols: cols || 80, rows: rows || 24 };
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return { cols: 80, rows: 24 };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/** Read the tmux paste buffer (used for CC /copy output). */
|
|
166
|
+
async function showBuffer() {
|
|
167
|
+
return tmuxExec('show-buffer');
|
|
168
|
+
}
|
|
169
|
+
/** Get the pane ID of the first pane in a tmux session (e.g. "%42"). */
|
|
170
|
+
async function getPaneId(session) {
|
|
171
|
+
return tmuxExec(`display-message -p -t ${session} '#{pane_id}'`);
|
|
172
|
+
}
|
|
173
|
+
/** Get the current working directory of the first pane of a session. */
|
|
174
|
+
async function getPaneCwd(session) {
|
|
175
|
+
const raw = await tmuxExec(`display-message -p -t ${session} '#{pane_current_path}'`);
|
|
176
|
+
return raw.trim();
|
|
177
|
+
}
|
|
178
|
+
/** Delete the tmux paste buffer (clipboard cleanup after CC /copy). */
|
|
179
|
+
async function deleteBuffer() {
|
|
180
|
+
try {
|
|
181
|
+
await tmuxExec('delete-buffer');
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// buffer may not exist
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Map xterm.js escape sequences → tmux key names
|
|
188
|
+
const XTERM_KEY_MAP = {
|
|
189
|
+
'\x1b[A': 'Up', '\x1b[B': 'Down',
|
|
190
|
+
'\x1b[C': 'Right', '\x1b[D': 'Left',
|
|
191
|
+
'\x1b[F': 'End', '\x1b[H': 'Home',
|
|
192
|
+
'\x1b[1~': 'Home', '\x1b[3~': 'DC',
|
|
193
|
+
'\x1b[4~': 'End', '\x1b[5~': 'PPage',
|
|
194
|
+
'\x1b[6~': 'NPage', '\x1b[2~': 'IC',
|
|
195
|
+
'\x1b[Z': 'BTab',
|
|
196
|
+
'\r': 'Enter', '\x7f': 'BSpace',
|
|
197
|
+
'\x1b': 'Escape',
|
|
198
|
+
'\x1bOP': 'F1', '\x1bOQ': 'F2',
|
|
199
|
+
'\x1bOR': 'F3', '\x1bOS': 'F4',
|
|
200
|
+
'\x1b[15~': 'F5', '\x1b[17~': 'F6',
|
|
201
|
+
'\x1b[18~': 'F7', '\x1b[19~': 'F8',
|
|
202
|
+
'\x1b[20~': 'F9', '\x1b[21~': 'F10',
|
|
203
|
+
'\x1b[23~': 'F11', '\x1b[24~': 'F12',
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Send raw terminal input to a tmux session.
|
|
207
|
+
* Maps xterm escape sequences to tmux key names; literal text uses -l flag.
|
|
208
|
+
* Used for keyboard passthrough from the browser terminal.
|
|
209
|
+
*/
|
|
210
|
+
async function sendRawInput(session, data) {
|
|
211
|
+
// Check escape sequence map first
|
|
212
|
+
const tmuxKey = XTERM_KEY_MAP[data];
|
|
213
|
+
if (tmuxKey) {
|
|
214
|
+
await tmuxExec(`send-keys -t ${session} ${tmuxKey}`);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// Ctrl+A..Z: \x01..\x1a
|
|
218
|
+
if (data.length === 1) {
|
|
219
|
+
const code = data.charCodeAt(0);
|
|
220
|
+
if (code >= 1 && code <= 26) {
|
|
221
|
+
const letter = String.fromCharCode(code + 96); // 1→'a', 2→'b', ...
|
|
222
|
+
await tmuxExec(`send-keys -t ${session} C-${letter}`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Unknown escape sequence — skip
|
|
227
|
+
if (data.startsWith('\x1b'))
|
|
228
|
+
return;
|
|
229
|
+
// Regular printable text — send literally (no Enter appended)
|
|
230
|
+
const escaped = data.replace(/'/g, "'\\''");
|
|
231
|
+
await tmuxExec(`send-keys -t ${session} -l -- '${escaped}'`);
|
|
232
|
+
}
|
|
233
|
+
// ── pipe-pane streaming ───────────────────────────────────────────────────────
|
|
234
|
+
/** Shell-quote a string using single-quote wrapping. */
|
|
235
|
+
function shellQuote(str) {
|
|
236
|
+
return "'" + str.replace(/'/g, "'\\''") + "'";
|
|
237
|
+
}
|
|
238
|
+
/** Validates the FIFO path against strict character whitelist. */
|
|
239
|
+
function validateFifoPath(p) {
|
|
240
|
+
return /^[A-Za-z0-9/_.\-]+$/.test(p);
|
|
241
|
+
}
|
|
242
|
+
/** Valid session name pattern for pipe-pane. */
|
|
243
|
+
const SESSION_PATTERN = /^deck_([a-z0-9A-Z0-9_]+_(brain|w\d+)|sub_[a-z0-9_]+)$/;
|
|
244
|
+
/** Cached pipe-pane capability (tmux >= 2.6 supports -O). */
|
|
245
|
+
let pipePaneCapability = null;
|
|
246
|
+
/** Fixed path to the pipe-writer helper script. */
|
|
247
|
+
const PIPE_WRITER_SCRIPT = path.join(__dirname, '../../scripts/pipe-writer.sh');
|
|
248
|
+
/**
|
|
249
|
+
* Check if tmux supports `pipe-pane -O` (requires tmux >= 2.6).
|
|
250
|
+
* Result is cached after first call.
|
|
251
|
+
*/
|
|
252
|
+
async function checkPipePaneCapability() {
|
|
253
|
+
if (pipePaneCapability !== null)
|
|
254
|
+
return pipePaneCapability;
|
|
255
|
+
try {
|
|
256
|
+
const { stdout } = await exec('tmux -V');
|
|
257
|
+
const match = stdout.trim().match(/^tmux\s+(\d+)\.(\d+)/);
|
|
258
|
+
if (match) {
|
|
259
|
+
const major = parseInt(match[1], 10);
|
|
260
|
+
const minor = parseInt(match[2], 10);
|
|
261
|
+
pipePaneCapability = major > 2 || (major === 2 && minor >= 6);
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
pipePaneCapability = false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
pipePaneCapability = false;
|
|
269
|
+
}
|
|
270
|
+
return pipePaneCapability;
|
|
271
|
+
}
|
|
272
|
+
/** Track active pipe-pane handles: session → handle info for cleanup. */
|
|
273
|
+
const activePipes = new Map();
|
|
274
|
+
/**
|
|
275
|
+
* Start a `tmux pipe-pane -O` raw PTY stream for a session.
|
|
276
|
+
* Uses a PID-scoped FIFO with O_RDWR|O_NONBLOCK to avoid blocking/premature-EOF.
|
|
277
|
+
* Returns a ReadStream and a cleanup function.
|
|
278
|
+
*/
|
|
279
|
+
async function startPipePaneStream(session, paneId) {
|
|
280
|
+
if (!SESSION_PATTERN.test(session)) {
|
|
281
|
+
throw new Error(`Invalid session name for pipe-pane: ${session}`);
|
|
282
|
+
}
|
|
283
|
+
// Stop any existing pipe for this session
|
|
284
|
+
await stopPipePaneStream(session).catch(() => { });
|
|
285
|
+
// Create PID-scoped temp dir
|
|
286
|
+
const tmpPrefix = path.join(os.tmpdir(), `codedeck-pty-${process.pid}-`);
|
|
287
|
+
const dir = await fsp.mkdtemp(tmpPrefix);
|
|
288
|
+
const fifoPath = path.join(dir, 'stream.fifo');
|
|
289
|
+
if (!validateFifoPath(fifoPath)) {
|
|
290
|
+
await fsp.rmdir(dir).catch(() => { });
|
|
291
|
+
throw new Error(`FIFO path failed character validation: ${fifoPath}`);
|
|
292
|
+
}
|
|
293
|
+
let fd = -1;
|
|
294
|
+
let stream = null;
|
|
295
|
+
try {
|
|
296
|
+
// Create FIFO with 0600 permissions
|
|
297
|
+
await execFile('mkfifo', ['-m', '0600', fifoPath]);
|
|
298
|
+
// Open FIFO with O_RDWR|O_NONBLOCK:
|
|
299
|
+
// - O_RDWR: process holds both read and write ends → no blocking on open, and
|
|
300
|
+
// write-end stays open preventing premature EOF before pipe-pane connects.
|
|
301
|
+
// - O_NONBLOCK: required to avoid the open() syscall itself ever blocking.
|
|
302
|
+
// Do NOT use fs.createReadStream here — it uses thread-pool blocking read() which
|
|
303
|
+
// cannot be interrupted by destroy() when no data is available.
|
|
304
|
+
// Instead, wrap with net.Socket: FIFOs are epoll-pollable on Linux, so net.Socket
|
|
305
|
+
// uses non-blocking I/O multiplexing (handles EAGAIN correctly, destroy() works).
|
|
306
|
+
// Use fs.openSync to get a raw fd (no FileHandle GC issue).
|
|
307
|
+
fd = fs.openSync(fifoPath, fs.constants.O_RDWR | fs.constants.O_NONBLOCK);
|
|
308
|
+
// Wrap fd in a net.Socket (epoll-based, handles EAGAIN → wait, not error)
|
|
309
|
+
stream = new net_1.Socket({ fd, readable: true, writable: false, allowHalfOpen: true });
|
|
310
|
+
// Build pipe-pane command: fixed helper script + shell-quoted FIFO path
|
|
311
|
+
const cmd = shellQuote(PIPE_WRITER_SCRIPT) + ' ' + shellQuote(fifoPath);
|
|
312
|
+
// Start pipe-pane -O (output only, not existing history)
|
|
313
|
+
await execFile('tmux', ['pipe-pane', '-O', '-t', paneId, cmd]);
|
|
314
|
+
// Startup success: pipe-pane exit 0 + verify stream hasn't errored (setImmediate)
|
|
315
|
+
await new Promise((resolve, reject) => {
|
|
316
|
+
setImmediate(() => {
|
|
317
|
+
// If stream emitted error synchronously before setImmediate, it would have thrown.
|
|
318
|
+
// Check stream.destroyed to detect immediate close.
|
|
319
|
+
if (stream.destroyed) {
|
|
320
|
+
reject(new Error('Pipe stream closed immediately after pipe-pane start'));
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
resolve();
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
const handle = {
|
|
328
|
+
stream,
|
|
329
|
+
cleanup: async () => {
|
|
330
|
+
const info = activePipes.get(session);
|
|
331
|
+
if (info) {
|
|
332
|
+
activePipes.delete(session);
|
|
333
|
+
// Stop pipe-pane (suppress errors — pane may be gone)
|
|
334
|
+
await execFile('tmux', ['pipe-pane', '-t', info.paneId]).catch(() => { });
|
|
335
|
+
stream?.destroy();
|
|
336
|
+
await fsp.unlink(info.fifoPath).catch(() => { });
|
|
337
|
+
await fsp.rmdir(info.dir).catch(() => { });
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
activePipes.set(session, { paneId, fifoPath, dir, fd });
|
|
342
|
+
return handle;
|
|
343
|
+
}
|
|
344
|
+
catch (err) {
|
|
345
|
+
// Rollback
|
|
346
|
+
stream?.destroy();
|
|
347
|
+
await execFile('tmux', ['pipe-pane', '-t', paneId]).catch(() => { });
|
|
348
|
+
await fsp.unlink(fifoPath).catch(() => { });
|
|
349
|
+
await fsp.rmdir(dir).catch(() => { });
|
|
350
|
+
throw err;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Stop an active pipe-pane stream for a session.
|
|
355
|
+
* No-op if no active stream exists.
|
|
356
|
+
*/
|
|
357
|
+
async function stopPipePaneStream(session) {
|
|
358
|
+
const info = activePipes.get(session);
|
|
359
|
+
if (!info)
|
|
360
|
+
return;
|
|
361
|
+
activePipes.delete(session);
|
|
362
|
+
await execFile('tmux', ['pipe-pane', '-t', info.paneId]).catch(() => { });
|
|
363
|
+
await fsp.unlink(info.fifoPath).catch(() => { });
|
|
364
|
+
await fsp.rmdir(info.dir).catch(() => { });
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Clean up any FIFO temp dirs leftover from a previous daemon run with the same PID.
|
|
368
|
+
* Only removes dirs scoped to the current process.pid.
|
|
369
|
+
*/
|
|
370
|
+
async function cleanupOrphanFifos() {
|
|
371
|
+
const tmpDir = os.tmpdir();
|
|
372
|
+
const prefix = `codedeck-pty-${process.pid}-`;
|
|
373
|
+
try {
|
|
374
|
+
const entries = await fsp.readdir(tmpDir);
|
|
375
|
+
for (const entry of entries) {
|
|
376
|
+
if (entry.startsWith(prefix)) {
|
|
377
|
+
const dirPath = path.join(tmpDir, entry);
|
|
378
|
+
await fsp.rm(dirPath, { recursive: true, force: true }).catch(() => { });
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
// Best-effort cleanup
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
//# sourceMappingURL=tmux.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux.js","sourceRoot":"","sources":["../../src/agent/tmux.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-agent audit orchestration.
|
|
3
|
+
* Coder (brain/worker) produces designs/code → Auditor reviews → discussion rounds.
|
|
4
|
+
*/
|
|
5
|
+
import type { AutoFixTask } from './state-machine.js';
|
|
6
|
+
export interface AuditResult {
|
|
7
|
+
approved: boolean;
|
|
8
|
+
findings: string[];
|
|
9
|
+
summary: string;
|
|
10
|
+
}
|
|
11
|
+
export interface AuditEngineOptions {
|
|
12
|
+
onTaskUpdate: (task: AutoFixTask) => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare class AuditEngine {
|
|
15
|
+
private opts;
|
|
16
|
+
private coderDriver;
|
|
17
|
+
constructor(opts: AuditEngineOptions);
|
|
18
|
+
/**
|
|
19
|
+
* Run design review: capture coder output, send to auditor, parse result.
|
|
20
|
+
*/
|
|
21
|
+
runDesignReview(task: AutoFixTask): Promise<{
|
|
22
|
+
task: AutoFixTask;
|
|
23
|
+
result: AuditResult;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Run code review: capture diff/output, send to auditor, parse result.
|
|
27
|
+
*/
|
|
28
|
+
runCodeReview(task: AutoFixTask): Promise<{
|
|
29
|
+
task: AutoFixTask;
|
|
30
|
+
result: AuditResult;
|
|
31
|
+
}>;
|
|
32
|
+
private captureAgentOutput;
|
|
33
|
+
private waitForIdle;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=audit-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-engine.d.ts","sourceRoot":"","sources":["../../src/autofix/audit-engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOtD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED,qBAAa,WAAW;IAGV,OAAO,CAAC,IAAI;IAFxB,OAAO,CAAC,WAAW,CAA0B;gBAEzB,IAAI,EAAE,kBAAkB;IAE5C;;OAEG;IACG,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,CAAC;IA+B7F;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,CAAC;YAyB7E,kBAAkB;YAKlB,WAAW;CAe1B"}
|
|
@@ -0,0 +1,144 @@
|
|
|
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.AuditEngine = void 0;
|
|
7
|
+
const state_machine_js_1 = require("./state-machine.js");
|
|
8
|
+
const tmux_js_1 = require("../agent/tmux.js");
|
|
9
|
+
const claude_code_js_1 = require("../agent/drivers/claude-code.js");
|
|
10
|
+
const logger_js_1 = __importDefault(require("../util/logger.js"));
|
|
11
|
+
class AuditEngine {
|
|
12
|
+
opts;
|
|
13
|
+
coderDriver = new claude_code_js_1.ClaudeCodeDriver();
|
|
14
|
+
constructor(opts) {
|
|
15
|
+
this.opts = opts;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Run design review: capture coder output, send to auditor, parse result.
|
|
19
|
+
*/
|
|
20
|
+
async runDesignReview(task) {
|
|
21
|
+
logger_js_1.default.info({ taskId: task.id, state: task.state }, 'Running design review');
|
|
22
|
+
// Capture coder's design document
|
|
23
|
+
const coderOutput = await this.captureAgentOutput(task.coderSession);
|
|
24
|
+
// Send to auditor for design review
|
|
25
|
+
const reviewPrompt = buildDesignReviewPrompt(task.title, coderOutput);
|
|
26
|
+
await (0, tmux_js_1.sendKeys)(task.auditorSession, reviewPrompt);
|
|
27
|
+
// Wait for auditor to complete (up to 120s)
|
|
28
|
+
const auditorOutput = await this.waitForIdle(task.auditorSession, 120_000);
|
|
29
|
+
const result = parseAuditResult(auditorOutput);
|
|
30
|
+
// Transition state
|
|
31
|
+
let updatedTask;
|
|
32
|
+
if (result.approved) {
|
|
33
|
+
updatedTask = (0, state_machine_js_1.transition)(task, 'approve_design');
|
|
34
|
+
logger_js_1.default.info({ taskId: task.id }, 'Design approved');
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
updatedTask = (0, state_machine_js_1.transition)(task, 'reject_design');
|
|
38
|
+
// Send findings back to coder
|
|
39
|
+
const findingsMsg = `Design review findings:\n${result.findings.join('\n')}\n\nPlease revise.`;
|
|
40
|
+
await (0, tmux_js_1.sendKeys)(task.coderSession, findingsMsg);
|
|
41
|
+
logger_js_1.default.info({ taskId: task.id, findings: result.findings.length }, 'Design rejected — findings sent to coder');
|
|
42
|
+
}
|
|
43
|
+
await this.opts.onTaskUpdate(updatedTask);
|
|
44
|
+
return { task: updatedTask, result };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run code review: capture diff/output, send to auditor, parse result.
|
|
48
|
+
*/
|
|
49
|
+
async runCodeReview(task) {
|
|
50
|
+
logger_js_1.default.info({ taskId: task.id, state: task.state }, 'Running code review');
|
|
51
|
+
const coderOutput = await this.captureAgentOutput(task.coderSession);
|
|
52
|
+
const reviewPrompt = buildCodeReviewPrompt(task.title, task.description, coderOutput);
|
|
53
|
+
await (0, tmux_js_1.sendKeys)(task.auditorSession, reviewPrompt);
|
|
54
|
+
const auditorOutput = await this.waitForIdle(task.auditorSession, 120_000);
|
|
55
|
+
const result = parseAuditResult(auditorOutput);
|
|
56
|
+
let updatedTask;
|
|
57
|
+
if (result.approved) {
|
|
58
|
+
updatedTask = (0, state_machine_js_1.transition)(task, 'approve_code');
|
|
59
|
+
logger_js_1.default.info({ taskId: task.id }, 'Code approved');
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
updatedTask = (0, state_machine_js_1.transition)(task, 'reject_code');
|
|
63
|
+
const findingsMsg = `Code review findings:\n${result.findings.join('\n')}\n\nPlease address these issues.`;
|
|
64
|
+
await (0, tmux_js_1.sendKeys)(task.coderSession, findingsMsg);
|
|
65
|
+
logger_js_1.default.info({ taskId: task.id, findings: result.findings.length }, 'Code rejected — findings sent to coder');
|
|
66
|
+
}
|
|
67
|
+
await this.opts.onTaskUpdate(updatedTask);
|
|
68
|
+
return { task: updatedTask, result };
|
|
69
|
+
}
|
|
70
|
+
async captureAgentOutput(sessionName) {
|
|
71
|
+
const lines = await (0, tmux_js_1.capturePane)(sessionName);
|
|
72
|
+
return lines.join('\n');
|
|
73
|
+
}
|
|
74
|
+
async waitForIdle(sessionName, timeoutMs) {
|
|
75
|
+
const deadline = Date.now() + timeoutMs;
|
|
76
|
+
while (Date.now() < deadline) {
|
|
77
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
78
|
+
const lines = await (0, tmux_js_1.capturePane)(sessionName);
|
|
79
|
+
const linesArr = lines;
|
|
80
|
+
const lastLine = linesArr[linesArr.length - 1] ?? '';
|
|
81
|
+
if (lastLine.includes('❯') || lastLine.includes('λ') || lastLine.includes('>')) {
|
|
82
|
+
return linesArr.join('\n');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
logger_js_1.default.warn({ sessionName, timeoutMs }, 'waitForIdle timeout');
|
|
86
|
+
const lines = await (0, tmux_js_1.capturePane)(sessionName);
|
|
87
|
+
return lines.join('\n');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.AuditEngine = AuditEngine;
|
|
91
|
+
// ── Prompt builders ───────────────────────────────────────────────────────────
|
|
92
|
+
function buildDesignReviewPrompt(title, coderOutput) {
|
|
93
|
+
return `Please review this design proposal for: "${title}"
|
|
94
|
+
|
|
95
|
+
${coderOutput}
|
|
96
|
+
|
|
97
|
+
Evaluate:
|
|
98
|
+
1. Is the approach technically sound?
|
|
99
|
+
2. Are there security concerns?
|
|
100
|
+
3. Are edge cases handled?
|
|
101
|
+
4. Is it consistent with the existing architecture?
|
|
102
|
+
|
|
103
|
+
Respond with:
|
|
104
|
+
- APPROVED: <brief summary> (if the design is acceptable)
|
|
105
|
+
- REJECTED: <list of issues, one per line> (if changes are needed)`;
|
|
106
|
+
}
|
|
107
|
+
function buildCodeReviewPrompt(title, description, coderOutput) {
|
|
108
|
+
return `Please review the code implementation for: "${title}"
|
|
109
|
+
|
|
110
|
+
Task description: ${description}
|
|
111
|
+
|
|
112
|
+
Implementation output:
|
|
113
|
+
${coderOutput}
|
|
114
|
+
|
|
115
|
+
Evaluate:
|
|
116
|
+
1. Does it correctly implement the requirements?
|
|
117
|
+
2. Are there bugs or logic errors?
|
|
118
|
+
3. Security issues? (injection, auth bypass, data exposure)
|
|
119
|
+
4. Code quality and test coverage?
|
|
120
|
+
|
|
121
|
+
Respond with:
|
|
122
|
+
- APPROVED: <brief summary> (if the implementation is acceptable)
|
|
123
|
+
- REJECTED: <list of specific issues, one per line> (if changes are needed)`;
|
|
124
|
+
}
|
|
125
|
+
function parseAuditResult(output) {
|
|
126
|
+
const lines = output.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
127
|
+
// Look for APPROVED/REJECTED decision
|
|
128
|
+
const approvedLine = lines.find((l) => l.toUpperCase().startsWith('APPROVED'));
|
|
129
|
+
const rejectedLine = lines.find((l) => l.toUpperCase().startsWith('REJECTED'));
|
|
130
|
+
if (approvedLine) {
|
|
131
|
+
const summary = approvedLine.replace(/^APPROVED:?\s*/i, '').trim();
|
|
132
|
+
return { approved: true, findings: [], summary };
|
|
133
|
+
}
|
|
134
|
+
if (rejectedLine) {
|
|
135
|
+
// Collect findings (lines after REJECTED: that start with - or number)
|
|
136
|
+
const rejectedIdx = lines.indexOf(rejectedLine);
|
|
137
|
+
const findings = lines.slice(rejectedIdx + 1).filter((l) => l.startsWith('-') || /^\d+\./.test(l));
|
|
138
|
+
const summary = rejectedLine.replace(/^REJECTED:?\s*/i, '').trim();
|
|
139
|
+
return { approved: false, findings, summary };
|
|
140
|
+
}
|
|
141
|
+
// Default to rejected if no clear decision
|
|
142
|
+
return { approved: false, findings: ['No clear decision in audit output'], summary: 'Unclear audit result' };
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=audit-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-engine.js","sourceRoot":"","sources":["../../src/autofix/audit-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface BranchInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
baseBranch: string;
|
|
4
|
+
created: boolean;
|
|
5
|
+
sha?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create a feature branch for an issue.
|
|
9
|
+
* Branch name: fix/<issue-id>-<slug>
|
|
10
|
+
*/
|
|
11
|
+
export declare function createBranch(opts: {
|
|
12
|
+
issueId: string;
|
|
13
|
+
title: string;
|
|
14
|
+
baseBranch: string;
|
|
15
|
+
cwd: string;
|
|
16
|
+
}): Promise<BranchInfo>;
|
|
17
|
+
/**
|
|
18
|
+
* Get the current HEAD commit SHA.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCurrentSha(cwd: string): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Merge the feature branch into the base branch.
|
|
23
|
+
* Uses --no-ff to preserve branch history.
|
|
24
|
+
*/
|
|
25
|
+
export declare function mergeBranch(opts: {
|
|
26
|
+
branchName: string;
|
|
27
|
+
baseBranch: string;
|
|
28
|
+
cwd: string;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Check if there are uncommitted changes in the working tree.
|
|
32
|
+
*/
|
|
33
|
+
export declare function hasUncommittedChanges(cwd: string): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Push branch to remote origin.
|
|
36
|
+
*/
|
|
37
|
+
export declare function pushBranch(branchName: string, cwd: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Build a git branch name from issue ID and title.
|
|
40
|
+
* Format: fix/<issue-id>-<slug>
|
|
41
|
+
* Slug: lowercase, special chars → hyphens, max 50 chars total.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildBranchName(issueId: string, title: string): string;
|
|
44
|
+
//# sourceMappingURL=branch-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branch-manager.d.ts","sourceRoot":"","sources":["../../src/autofix/branch-manager.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,UAAU,CAAC,CAmBtB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhE;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGzE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtE"}
|