aimux-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +743 -0
- package/bin/aimux +2 -0
- package/dist/agent-events.d.ts +20 -0
- package/dist/agent-events.js +2 -0
- package/dist/agent-events.js.map +1 -0
- package/dist/agent-message-parts.d.ts +17 -0
- package/dist/agent-message-parts.js +31 -0
- package/dist/agent-message-parts.js.map +1 -0
- package/dist/agent-output-parser.d.ts +16 -0
- package/dist/agent-output-parser.js +229 -0
- package/dist/agent-output-parser.js.map +1 -0
- package/dist/agent-tracker.d.ts +9 -0
- package/dist/agent-tracker.js +144 -0
- package/dist/agent-tracker.js.map +1 -0
- package/dist/agent-watcher.d.ts +15 -0
- package/dist/agent-watcher.js +2 -0
- package/dist/agent-watcher.js.map +1 -0
- package/dist/attachment-store.d.ts +35 -0
- package/dist/attachment-store.js +129 -0
- package/dist/attachment-store.js.map +1 -0
- package/dist/builtin-metadata-watchers.d.ts +2 -0
- package/dist/builtin-metadata-watchers.js +275 -0
- package/dist/builtin-metadata-watchers.js.map +1 -0
- package/dist/claude-hooks.d.ts +29 -0
- package/dist/claude-hooks.js +106 -0
- package/dist/claude-hooks.js.map +1 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.js +172 -0
- package/dist/config.js.map +1 -0
- package/dist/context/compactor.d.ts +20 -0
- package/dist/context/compactor.js +212 -0
- package/dist/context/compactor.js.map +1 -0
- package/dist/context/context-bridge.d.ts +67 -0
- package/dist/context/context-bridge.js +471 -0
- package/dist/context/context-bridge.js.map +1 -0
- package/dist/context/context-file.d.ts +11 -0
- package/dist/context/context-file.js +93 -0
- package/dist/context/context-file.js.map +1 -0
- package/dist/context/history.d.ts +40 -0
- package/dist/context/history.js +108 -0
- package/dist/context/history.js.map +1 -0
- package/dist/daemon.d.ts +39 -0
- package/dist/daemon.js +344 -0
- package/dist/daemon.js.map +1 -0
- package/dist/dashboard-session-registry.d.ts +47 -0
- package/dist/dashboard-session-registry.js +161 -0
- package/dist/dashboard-session-registry.js.map +1 -0
- package/dist/dashboard-state.d.ts +18 -0
- package/dist/dashboard-state.js +26 -0
- package/dist/dashboard-state.js.map +1 -0
- package/dist/dashboard.d.ts +118 -0
- package/dist/dashboard.js +91 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/debug.d.ts +7 -0
- package/dist/debug.js +41 -0
- package/dist/debug.js.map +1 -0
- package/dist/fast-control.d.ts +45 -0
- package/dist/fast-control.js +174 -0
- package/dist/fast-control.js.map +1 -0
- package/dist/hotkeys.d.ts +44 -0
- package/dist/hotkeys.js +118 -0
- package/dist/hotkeys.js.map +1 -0
- package/dist/http-client.d.ts +10 -0
- package/dist/http-client.js +54 -0
- package/dist/http-client.js.map +1 -0
- package/dist/instance-directory.d.ts +32 -0
- package/dist/instance-directory.js +82 -0
- package/dist/instance-directory.js.map +1 -0
- package/dist/instance-registry.d.ts +38 -0
- package/dist/instance-registry.js +208 -0
- package/dist/instance-registry.js.map +1 -0
- package/dist/key-parser.d.ts +30 -0
- package/dist/key-parser.js +272 -0
- package/dist/key-parser.js.map +1 -0
- package/dist/last-used.d.ts +31 -0
- package/dist/last-used.js +93 -0
- package/dist/last-used.js.map +1 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +2483 -0
- package/dist/main.js.map +1 -0
- package/dist/metadata-server.d.ts +268 -0
- package/dist/metadata-server.js +1379 -0
- package/dist/metadata-server.js.map +1 -0
- package/dist/metadata-store.d.ts +80 -0
- package/dist/metadata-store.js +87 -0
- package/dist/metadata-store.js.map +1 -0
- package/dist/multiplexer.d.ts +471 -0
- package/dist/multiplexer.js +5714 -0
- package/dist/multiplexer.js.map +1 -0
- package/dist/notification-context.d.ts +18 -0
- package/dist/notification-context.js +68 -0
- package/dist/notification-context.js.map +1 -0
- package/dist/notifications.d.ts +38 -0
- package/dist/notifications.js +111 -0
- package/dist/notifications.js.map +1 -0
- package/dist/notify.d.ts +10 -0
- package/dist/notify.js +62 -0
- package/dist/notify.js.map +1 -0
- package/dist/orchestration-actions.d.ts +76 -0
- package/dist/orchestration-actions.js +310 -0
- package/dist/orchestration-actions.js.map +1 -0
- package/dist/orchestration-dispatcher.d.ts +22 -0
- package/dist/orchestration-dispatcher.js +49 -0
- package/dist/orchestration-dispatcher.js.map +1 -0
- package/dist/orchestration-routing.d.ts +20 -0
- package/dist/orchestration-routing.js +78 -0
- package/dist/orchestration-routing.js.map +1 -0
- package/dist/orchestration.d.ts +26 -0
- package/dist/orchestration.js +110 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/osc-notifications.d.ts +15 -0
- package/dist/osc-notifications.js +180 -0
- package/dist/osc-notifications.js.map +1 -0
- package/dist/paths.d.ts +55 -0
- package/dist/paths.js +259 -0
- package/dist/paths.js.map +1 -0
- package/dist/plugin-runtime.d.ts +46 -0
- package/dist/plugin-runtime.js +180 -0
- package/dist/plugin-runtime.js.map +1 -0
- package/dist/project-events.d.ts +36 -0
- package/dist/project-events.js +63 -0
- package/dist/project-events.js.map +1 -0
- package/dist/project-scanner.d.ts +38 -0
- package/dist/project-scanner.js +243 -0
- package/dist/project-scanner.js.map +1 -0
- package/dist/project-service-manifest.d.ts +18 -0
- package/dist/project-service-manifest.js +56 -0
- package/dist/project-service-manifest.js.map +1 -0
- package/dist/recency.d.ts +2 -0
- package/dist/recency.js +34 -0
- package/dist/recency.js.map +1 -0
- package/dist/recorder.d.ts +14 -0
- package/dist/recorder.js +130 -0
- package/dist/recorder.js.map +1 -0
- package/dist/session-bootstrap.d.ts +45 -0
- package/dist/session-bootstrap.js +436 -0
- package/dist/session-bootstrap.js.map +1 -0
- package/dist/session-message-history.d.ts +27 -0
- package/dist/session-message-history.js +105 -0
- package/dist/session-message-history.js.map +1 -0
- package/dist/session-runtime.d.ts +44 -0
- package/dist/session-runtime.js +56 -0
- package/dist/session-runtime.js.map +1 -0
- package/dist/session-semantics.d.ts +35 -0
- package/dist/session-semantics.js +110 -0
- package/dist/session-semantics.js.map +1 -0
- package/dist/status-detector.d.ts +17 -0
- package/dist/status-detector.js +67 -0
- package/dist/status-detector.js.map +1 -0
- package/dist/statusline-model.d.ts +103 -0
- package/dist/statusline-model.js +177 -0
- package/dist/statusline-model.js.map +1 -0
- package/dist/task-dispatcher.d.ts +63 -0
- package/dist/task-dispatcher.js +210 -0
- package/dist/task-dispatcher.js.map +1 -0
- package/dist/task-workflow.d.ts +13 -0
- package/dist/task-workflow.js +153 -0
- package/dist/task-workflow.js.map +1 -0
- package/dist/tasks.d.ts +60 -0
- package/dist/tasks.js +120 -0
- package/dist/tasks.js.map +1 -0
- package/dist/team.d.ts +28 -0
- package/dist/team.js +91 -0
- package/dist/team.js.map +1 -0
- package/dist/terminal-host.d.ts +10 -0
- package/dist/terminal-host.js +52 -0
- package/dist/terminal-host.js.map +1 -0
- package/dist/threads.d.ts +61 -0
- package/dist/threads.js +200 -0
- package/dist/threads.js.map +1 -0
- package/dist/tmux-doctor.d.ts +47 -0
- package/dist/tmux-doctor.js +112 -0
- package/dist/tmux-doctor.js.map +1 -0
- package/dist/tmux-runtime-manager.d.ts +164 -0
- package/dist/tmux-runtime-manager.js +794 -0
- package/dist/tmux-runtime-manager.js.map +1 -0
- package/dist/tmux-session-transport.d.ts +31 -0
- package/dist/tmux-session-transport.js +115 -0
- package/dist/tmux-session-transport.js.map +1 -0
- package/dist/tmux-statusline.d.ts +17 -0
- package/dist/tmux-statusline.js +166 -0
- package/dist/tmux-statusline.js.map +1 -0
- package/dist/tool-output-watchers.d.ts +10 -0
- package/dist/tool-output-watchers.js +190 -0
- package/dist/tool-output-watchers.js.map +1 -0
- package/dist/tui/render/box.d.ts +1 -0
- package/dist/tui/render/box.js +20 -0
- package/dist/tui/render/box.js.map +1 -0
- package/dist/tui/render/text.d.ts +8 -0
- package/dist/tui/render/text.js +92 -0
- package/dist/tui/render/text.js.map +1 -0
- package/dist/tui/screens/dashboard-renderers.d.ts +23 -0
- package/dist/tui/screens/dashboard-renderers.js +411 -0
- package/dist/tui/screens/dashboard-renderers.js.map +1 -0
- package/dist/tui/screens/overlay-renderers.d.ts +10 -0
- package/dist/tui/screens/overlay-renderers.js +274 -0
- package/dist/tui/screens/overlay-renderers.js.map +1 -0
- package/dist/tui/screens/subscreen-renderers.d.ts +9 -0
- package/dist/tui/screens/subscreen-renderers.js +327 -0
- package/dist/tui/screens/subscreen-renderers.js.map +1 -0
- package/dist/workflow.d.ts +19 -0
- package/dist/workflow.js +111 -0
- package/dist/workflow.js.map +1 -0
- package/dist/worktree.d.ts +23 -0
- package/dist/worktree.js +101 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
3
|
+
import { basename, extname, join } from "node:path";
|
|
4
|
+
import { getAttachmentsDir } from "./paths.js";
|
|
5
|
+
const MIME_BY_EXT = {
|
|
6
|
+
".png": "image/png",
|
|
7
|
+
".jpg": "image/jpeg",
|
|
8
|
+
".jpeg": "image/jpeg",
|
|
9
|
+
".gif": "image/gif",
|
|
10
|
+
".webp": "image/webp",
|
|
11
|
+
".bmp": "image/bmp",
|
|
12
|
+
".svg": "image/svg+xml",
|
|
13
|
+
};
|
|
14
|
+
export function ingestAttachmentFromPath(path) {
|
|
15
|
+
const trimmedPath = path.trim();
|
|
16
|
+
if (!trimmedPath) {
|
|
17
|
+
throw new Error("attachment path is required");
|
|
18
|
+
}
|
|
19
|
+
const buffer = readFileSync(trimmedPath);
|
|
20
|
+
const filename = basename(trimmedPath) || "image";
|
|
21
|
+
return writeAttachment(buffer, {
|
|
22
|
+
filename,
|
|
23
|
+
mimeType: inferMimeType(filename),
|
|
24
|
+
source: "path",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export function ingestAttachmentFromBase64(input) {
|
|
28
|
+
const contentBase64 = input.contentBase64.trim();
|
|
29
|
+
if (!contentBase64) {
|
|
30
|
+
throw new Error("contentBase64 is required");
|
|
31
|
+
}
|
|
32
|
+
const buffer = Buffer.from(contentBase64, "base64");
|
|
33
|
+
if (buffer.length === 0) {
|
|
34
|
+
throw new Error("attachment content is empty");
|
|
35
|
+
}
|
|
36
|
+
const filename = input.filename?.trim() || "image";
|
|
37
|
+
const mimeType = input.mimeType?.trim() || inferMimeType(filename);
|
|
38
|
+
return writeAttachment(buffer, {
|
|
39
|
+
filename,
|
|
40
|
+
mimeType,
|
|
41
|
+
source: "upload",
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function getAttachment(id) {
|
|
45
|
+
const record = loadAttachmentRecord(id);
|
|
46
|
+
return record ? toPublicAttachment(record) : null;
|
|
47
|
+
}
|
|
48
|
+
export function getAttachmentContent(id) {
|
|
49
|
+
const record = loadAttachmentRecord(id);
|
|
50
|
+
if (!record)
|
|
51
|
+
return null;
|
|
52
|
+
return {
|
|
53
|
+
attachment: toPublicAttachment(record),
|
|
54
|
+
contentPath: record.contentPath,
|
|
55
|
+
buffer: readFileSync(record.contentPath),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export function resolveAttachmentPath(id) {
|
|
59
|
+
const record = loadAttachmentRecord(id);
|
|
60
|
+
return record?.contentPath ?? null;
|
|
61
|
+
}
|
|
62
|
+
function writeAttachment(buffer, input) {
|
|
63
|
+
ensureAttachmentsDir();
|
|
64
|
+
const sha256 = createHash("sha256").update(buffer).digest("hex");
|
|
65
|
+
const id = `att_${sha256.slice(0, 16)}`;
|
|
66
|
+
const extension = normalizeExtension(extname(input.filename), input.mimeType);
|
|
67
|
+
const contentPath = join(getAttachmentsDir(), `${id}${extension}`);
|
|
68
|
+
const metadataPath = join(getAttachmentsDir(), `${id}.json`);
|
|
69
|
+
if (!existsSync(contentPath)) {
|
|
70
|
+
writeFileSync(contentPath, buffer);
|
|
71
|
+
}
|
|
72
|
+
const record = {
|
|
73
|
+
id,
|
|
74
|
+
kind: "image",
|
|
75
|
+
filename: input.filename,
|
|
76
|
+
mimeType: input.mimeType,
|
|
77
|
+
sizeBytes: buffer.length,
|
|
78
|
+
sha256,
|
|
79
|
+
createdAt: existsSync(metadataPath)
|
|
80
|
+
? loadAttachmentRecord(id)?.createdAt || new Date().toISOString()
|
|
81
|
+
: new Date().toISOString(),
|
|
82
|
+
source: input.source,
|
|
83
|
+
contentPath,
|
|
84
|
+
};
|
|
85
|
+
writeFileSync(metadataPath, `${JSON.stringify(record, null, 2)}\n`, "utf8");
|
|
86
|
+
return toPublicAttachment(record);
|
|
87
|
+
}
|
|
88
|
+
function loadAttachmentRecord(id) {
|
|
89
|
+
const normalizedId = id.trim();
|
|
90
|
+
if (!normalizedId)
|
|
91
|
+
return null;
|
|
92
|
+
const metadataPath = join(getAttachmentsDir(), `${normalizedId}.json`);
|
|
93
|
+
if (!existsSync(metadataPath)) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const parsed = JSON.parse(readFileSync(metadataPath, "utf8"));
|
|
97
|
+
if (!parsed.contentPath || !existsSync(parsed.contentPath)) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
return parsed;
|
|
101
|
+
}
|
|
102
|
+
function toPublicAttachment(record) {
|
|
103
|
+
return {
|
|
104
|
+
id: record.id,
|
|
105
|
+
kind: record.kind,
|
|
106
|
+
filename: record.filename,
|
|
107
|
+
mimeType: record.mimeType,
|
|
108
|
+
sizeBytes: record.sizeBytes,
|
|
109
|
+
sha256: record.sha256,
|
|
110
|
+
createdAt: record.createdAt,
|
|
111
|
+
source: record.source,
|
|
112
|
+
contentUrl: `/attachments/${record.id}/content`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function ensureAttachmentsDir() {
|
|
116
|
+
mkdirSync(getAttachmentsDir(), { recursive: true });
|
|
117
|
+
}
|
|
118
|
+
function inferMimeType(filename) {
|
|
119
|
+
return MIME_BY_EXT[extname(filename).toLowerCase()] || "application/octet-stream";
|
|
120
|
+
}
|
|
121
|
+
function normalizeExtension(extension, mimeType) {
|
|
122
|
+
const trimmed = extension.trim().toLowerCase();
|
|
123
|
+
if (trimmed) {
|
|
124
|
+
return trimmed;
|
|
125
|
+
}
|
|
126
|
+
const matched = Object.entries(MIME_BY_EXT).find(([, candidateMime]) => candidateMime === mimeType)?.[0];
|
|
127
|
+
return matched || "";
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=attachment-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment-store.js","sourceRoot":"","sources":["../src/attachment-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, watch } from "node:fs";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { getPlansDir, getStatusDir, getTasksDir, getHistoryDir } from "./paths.js";
|
|
5
|
+
import { debug } from "./debug.js";
|
|
6
|
+
import { readAllTasks } from "./tasks.js";
|
|
7
|
+
import { listSessionIds, readHistory } from "./context/history.js";
|
|
8
|
+
import { TmuxRuntimeManager } from "./tmux-runtime-manager.js";
|
|
9
|
+
import { listWorktrees } from "./worktree.js";
|
|
10
|
+
function safeRead(path) {
|
|
11
|
+
try {
|
|
12
|
+
return readFileSync(path, "utf-8");
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return "";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function sessionIdFromFile(file, ext) {
|
|
19
|
+
return file.endsWith(ext) ? basename(file, ext) : null;
|
|
20
|
+
}
|
|
21
|
+
function parsePlanProgress(content) {
|
|
22
|
+
const matches = content.match(/^- \[( |x)\] /gim) ?? [];
|
|
23
|
+
const total = matches.length;
|
|
24
|
+
if (total === 0)
|
|
25
|
+
return null;
|
|
26
|
+
const complete = (content.match(/^- \[x\] /gim) ?? []).length;
|
|
27
|
+
return { current: complete, total, label: "plan" };
|
|
28
|
+
}
|
|
29
|
+
function parseStatusHeadline(content) {
|
|
30
|
+
const first = content
|
|
31
|
+
.split("\n")
|
|
32
|
+
.map((line) => line.trim())
|
|
33
|
+
.find(Boolean);
|
|
34
|
+
return first || null;
|
|
35
|
+
}
|
|
36
|
+
class DirectoryWatcher {
|
|
37
|
+
dir;
|
|
38
|
+
onScan;
|
|
39
|
+
watcher = null;
|
|
40
|
+
debounce = null;
|
|
41
|
+
constructor(dir, onScan) {
|
|
42
|
+
this.dir = dir;
|
|
43
|
+
this.onScan = onScan;
|
|
44
|
+
}
|
|
45
|
+
start() {
|
|
46
|
+
mkdirSync(this.dir, { recursive: true });
|
|
47
|
+
this.onScan();
|
|
48
|
+
this.watcher = watch(this.dir, () => this.scheduleScan());
|
|
49
|
+
}
|
|
50
|
+
async stop() {
|
|
51
|
+
this.watcher?.close();
|
|
52
|
+
this.watcher = null;
|
|
53
|
+
if (this.debounce)
|
|
54
|
+
clearTimeout(this.debounce);
|
|
55
|
+
this.debounce = null;
|
|
56
|
+
}
|
|
57
|
+
scheduleScan() {
|
|
58
|
+
if (this.debounce)
|
|
59
|
+
clearTimeout(this.debounce);
|
|
60
|
+
this.debounce = setTimeout(() => {
|
|
61
|
+
this.debounce = null;
|
|
62
|
+
this.onScan();
|
|
63
|
+
}, 100);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
class PollingWatcher {
|
|
67
|
+
intervalMs;
|
|
68
|
+
onPoll;
|
|
69
|
+
timer = null;
|
|
70
|
+
constructor(intervalMs, onPoll) {
|
|
71
|
+
this.intervalMs = intervalMs;
|
|
72
|
+
this.onPoll = onPoll;
|
|
73
|
+
}
|
|
74
|
+
start() {
|
|
75
|
+
this.onPoll();
|
|
76
|
+
this.timer = setInterval(() => this.onPoll(), this.intervalMs);
|
|
77
|
+
this.timer.unref?.();
|
|
78
|
+
}
|
|
79
|
+
async stop() {
|
|
80
|
+
if (this.timer)
|
|
81
|
+
clearInterval(this.timer);
|
|
82
|
+
this.timer = null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function gitOutput(cwd, command) {
|
|
86
|
+
try {
|
|
87
|
+
return execSync(command, {
|
|
88
|
+
cwd,
|
|
89
|
+
encoding: "utf-8",
|
|
90
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
91
|
+
}).trim();
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function gitBranch(cwd) {
|
|
98
|
+
return gitOutput(cwd, "git rev-parse --abbrev-ref HEAD") || undefined;
|
|
99
|
+
}
|
|
100
|
+
function gitRemote(cwd) {
|
|
101
|
+
return gitOutput(cwd, "git remote get-url origin") || undefined;
|
|
102
|
+
}
|
|
103
|
+
function parseRemote(remote) {
|
|
104
|
+
if (!remote)
|
|
105
|
+
return {};
|
|
106
|
+
const match = remote.match(/github\.com[:/](.+?)\/(.+?)(?:\.git)?$/);
|
|
107
|
+
if (!match)
|
|
108
|
+
return { remote };
|
|
109
|
+
return {
|
|
110
|
+
owner: match[1],
|
|
111
|
+
name: match[2],
|
|
112
|
+
remote,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function worktreeNameFor(path, projectRoot) {
|
|
116
|
+
const worktrees = listWorktrees(projectRoot);
|
|
117
|
+
const match = worktrees.find((entry) => entry.path === path);
|
|
118
|
+
return match?.name ?? basename(path);
|
|
119
|
+
}
|
|
120
|
+
const prCache = new Map();
|
|
121
|
+
function ghPr(cwd, branch) {
|
|
122
|
+
if (!branch)
|
|
123
|
+
return undefined;
|
|
124
|
+
const key = `${cwd}:${branch}`;
|
|
125
|
+
const cached = prCache.get(key);
|
|
126
|
+
if (cached && cached.expiresAt > Date.now())
|
|
127
|
+
return cached.value ?? undefined;
|
|
128
|
+
let value = null;
|
|
129
|
+
const raw = gitOutput(cwd, "gh pr view --json number,title,url,headRefName,baseRefName --jq '{number: .number, title: .title, url: .url, headRef: .headRefName, baseRef: .baseRefName}'");
|
|
130
|
+
if (raw) {
|
|
131
|
+
try {
|
|
132
|
+
value = JSON.parse(raw);
|
|
133
|
+
}
|
|
134
|
+
catch { }
|
|
135
|
+
}
|
|
136
|
+
prCache.set(key, { value, expiresAt: Date.now() + 60_000 });
|
|
137
|
+
return value ?? undefined;
|
|
138
|
+
}
|
|
139
|
+
export function createBuiltinMetadataWatchers(api) {
|
|
140
|
+
const { metadata, projectRoot } = api;
|
|
141
|
+
const lastStatusBySession = new Map();
|
|
142
|
+
const lastTaskBySession = new Map();
|
|
143
|
+
const lastHistoryBySession = new Map();
|
|
144
|
+
const planWatcher = new DirectoryWatcher(getPlansDir(), () => {
|
|
145
|
+
for (const file of existsSync(getPlansDir()) ? readdirSync(getPlansDir()) : []) {
|
|
146
|
+
const sessionId = sessionIdFromFile(file, ".md");
|
|
147
|
+
if (!sessionId)
|
|
148
|
+
continue;
|
|
149
|
+
const progress = parsePlanProgress(safeRead(join(getPlansDir(), file)));
|
|
150
|
+
if (progress) {
|
|
151
|
+
metadata.setProgress(sessionId, progress.current, progress.total, progress.label);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
const statusWatcher = new DirectoryWatcher(getStatusDir(), () => {
|
|
156
|
+
for (const file of existsSync(getStatusDir()) ? readdirSync(getStatusDir()) : []) {
|
|
157
|
+
const sessionId = sessionIdFromFile(file, ".md");
|
|
158
|
+
if (!sessionId)
|
|
159
|
+
continue;
|
|
160
|
+
const headline = parseStatusHeadline(safeRead(join(getStatusDir(), file)));
|
|
161
|
+
if (headline) {
|
|
162
|
+
metadata.setStatus(sessionId, headline, "info");
|
|
163
|
+
if (lastStatusBySession.get(sessionId) !== headline) {
|
|
164
|
+
metadata.emitEvent(sessionId, { kind: "status", message: headline, tone: "info", source: "status" });
|
|
165
|
+
lastStatusBySession.set(sessionId, headline);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
const taskWatcher = new DirectoryWatcher(getTasksDir(), () => {
|
|
171
|
+
const tasks = readAllTasks();
|
|
172
|
+
const latestBySession = new Map();
|
|
173
|
+
for (const task of tasks) {
|
|
174
|
+
const sessionId = task.assignedTo ?? task.assignedBy;
|
|
175
|
+
if (!sessionId)
|
|
176
|
+
continue;
|
|
177
|
+
const tone = task.status === "failed" ? "error" : task.status === "done" ? "success" : "warn";
|
|
178
|
+
const prefix = task.status === "assigned"
|
|
179
|
+
? "Task"
|
|
180
|
+
: task.status === "pending"
|
|
181
|
+
? "Queued"
|
|
182
|
+
: task.status === "done"
|
|
183
|
+
? "Done"
|
|
184
|
+
: "Failed";
|
|
185
|
+
latestBySession.set(sessionId, { message: `${prefix}: ${task.description}`, tone });
|
|
186
|
+
}
|
|
187
|
+
for (const [sessionId, entry] of latestBySession) {
|
|
188
|
+
metadata.log(sessionId, entry.message, { source: "tasks", tone: entry.tone });
|
|
189
|
+
if (lastTaskBySession.get(sessionId) !== entry.message) {
|
|
190
|
+
metadata.emitEvent(sessionId, {
|
|
191
|
+
kind: entry.tone === "error" ? "task_failed" : entry.tone === "success" ? "task_done" : "task_assigned",
|
|
192
|
+
message: entry.message,
|
|
193
|
+
tone: entry.tone,
|
|
194
|
+
source: "tasks",
|
|
195
|
+
});
|
|
196
|
+
lastTaskBySession.set(sessionId, entry.message);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
const historyWatcher = new DirectoryWatcher(getHistoryDir(), () => {
|
|
201
|
+
for (const sessionId of listSessionIds()) {
|
|
202
|
+
const turns = readHistory(sessionId, { lastN: 1, maxBytes: 16 * 1024 });
|
|
203
|
+
const turn = turns.at(-1);
|
|
204
|
+
if (!turn)
|
|
205
|
+
continue;
|
|
206
|
+
const historyKey = `${turn.ts}:${turn.type}:${turn.content}`;
|
|
207
|
+
if (turn.type === "prompt") {
|
|
208
|
+
metadata.log(sessionId, `Prompt: ${turn.content.slice(0, 80)}`, { source: "history", tone: "info" });
|
|
209
|
+
if (lastHistoryBySession.get(sessionId) !== historyKey) {
|
|
210
|
+
metadata.emitEvent(sessionId, {
|
|
211
|
+
kind: "prompt",
|
|
212
|
+
message: turn.content.slice(0, 120),
|
|
213
|
+
tone: "info",
|
|
214
|
+
source: "history",
|
|
215
|
+
ts: turn.ts,
|
|
216
|
+
});
|
|
217
|
+
lastHistoryBySession.set(sessionId, historyKey);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if (turn.type === "response") {
|
|
221
|
+
metadata.log(sessionId, `Response: ${turn.content.slice(0, 80)}`, { source: "history" });
|
|
222
|
+
if (lastHistoryBySession.get(sessionId) !== historyKey) {
|
|
223
|
+
metadata.emitEvent(sessionId, {
|
|
224
|
+
kind: "response",
|
|
225
|
+
message: turn.content.slice(0, 120),
|
|
226
|
+
source: "history",
|
|
227
|
+
ts: turn.ts,
|
|
228
|
+
});
|
|
229
|
+
lastHistoryBySession.set(sessionId, historyKey);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else if (turn.type === "git") {
|
|
233
|
+
metadata.log(sessionId, `Git: ${turn.content.slice(0, 80)}`, { source: "git", tone: "success" });
|
|
234
|
+
if (lastHistoryBySession.get(sessionId) !== historyKey) {
|
|
235
|
+
metadata.emitEvent(sessionId, {
|
|
236
|
+
kind: "notify",
|
|
237
|
+
message: turn.content.slice(0, 120),
|
|
238
|
+
source: "git",
|
|
239
|
+
tone: "success",
|
|
240
|
+
ts: turn.ts,
|
|
241
|
+
});
|
|
242
|
+
lastHistoryBySession.set(sessionId, historyKey);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
const contextWatcher = new PollingWatcher(15_000, () => {
|
|
248
|
+
const tmux = new TmuxRuntimeManager();
|
|
249
|
+
let managed = [];
|
|
250
|
+
try {
|
|
251
|
+
managed = tmux.listManagedWindows(tmux.getProjectSession(projectRoot).sessionName);
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
for (const { metadata: windowMeta } of managed) {
|
|
257
|
+
if (!windowMeta.sessionId)
|
|
258
|
+
continue;
|
|
259
|
+
const cwd = windowMeta.worktreePath || projectRoot;
|
|
260
|
+
const branch = gitBranch(cwd);
|
|
261
|
+
const remote = gitRemote(cwd);
|
|
262
|
+
metadata.setContext(windowMeta.sessionId, {
|
|
263
|
+
cwd,
|
|
264
|
+
worktreePath: windowMeta.worktreePath || projectRoot,
|
|
265
|
+
worktreeName: worktreeNameFor(windowMeta.worktreePath || projectRoot, projectRoot),
|
|
266
|
+
branch,
|
|
267
|
+
repo: parseRemote(remote),
|
|
268
|
+
pr: ghPr(cwd, branch),
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
debug("registered builtin metadata watchers", "plugin");
|
|
273
|
+
return [planWatcher, statusWatcher, taskWatcher, historyWatcher, contextWatcher];
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=builtin-metadata-watchers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-metadata-watchers.js","sourceRoot":"","sources":["../src/builtin-metadata-watchers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ClaudeHookPayload {
|
|
2
|
+
session_id?: string;
|
|
3
|
+
cwd?: string;
|
|
4
|
+
transcript_path?: string;
|
|
5
|
+
hook_event_name?: string;
|
|
6
|
+
message?: string;
|
|
7
|
+
stop_reason?: string;
|
|
8
|
+
object?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare function getAimuxCliEntryPath(): string;
|
|
11
|
+
export declare function shouldSkipClaudeSessionIdInjection(args: string[]): boolean;
|
|
12
|
+
export declare function buildClaudeHookSettings(opts: {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
projectRoot: string;
|
|
15
|
+
}): string;
|
|
16
|
+
export declare function injectClaudeHookArgs(args: string[], opts: {
|
|
17
|
+
sessionId: string;
|
|
18
|
+
projectRoot: string;
|
|
19
|
+
backendSessionId?: string;
|
|
20
|
+
}): string[];
|
|
21
|
+
export declare function parseClaudeHookPayload(raw: string): ClaudeHookPayload;
|
|
22
|
+
export declare function summarizeClaudeNotification(payload: ClaudeHookPayload): {
|
|
23
|
+
subtitle: string;
|
|
24
|
+
body: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function summarizeClaudeStop(payload: ClaudeHookPayload): {
|
|
27
|
+
subtitle: string;
|
|
28
|
+
body: string;
|
|
29
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
function shellQuote(value) {
|
|
3
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
4
|
+
}
|
|
5
|
+
export function getAimuxCliEntryPath() {
|
|
6
|
+
return fileURLToPath(new URL("./main.js", import.meta.url));
|
|
7
|
+
}
|
|
8
|
+
export function shouldSkipClaudeSessionIdInjection(args) {
|
|
9
|
+
return args.some((arg) => arg === "--resume" ||
|
|
10
|
+
arg.startsWith("--resume=") ||
|
|
11
|
+
arg === "--session-id" ||
|
|
12
|
+
arg.startsWith("--session-id=") ||
|
|
13
|
+
arg === "--continue" ||
|
|
14
|
+
arg === "-c");
|
|
15
|
+
}
|
|
16
|
+
function buildClaudeHookCommand(action, sessionId, projectRoot) {
|
|
17
|
+
return [
|
|
18
|
+
shellQuote(process.execPath),
|
|
19
|
+
shellQuote(getAimuxCliEntryPath()),
|
|
20
|
+
"claude-hook",
|
|
21
|
+
action,
|
|
22
|
+
"--session",
|
|
23
|
+
shellQuote(sessionId),
|
|
24
|
+
"--project",
|
|
25
|
+
shellQuote(projectRoot),
|
|
26
|
+
].join(" ");
|
|
27
|
+
}
|
|
28
|
+
export function buildClaudeHookSettings(opts) {
|
|
29
|
+
const command = (action) => buildClaudeHookCommand(action, opts.sessionId, opts.projectRoot);
|
|
30
|
+
return JSON.stringify({
|
|
31
|
+
hooks: {
|
|
32
|
+
SessionStart: [
|
|
33
|
+
{
|
|
34
|
+
matcher: "",
|
|
35
|
+
hooks: [{ type: "command", command: command("session-start"), timeout: 10 }],
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
Stop: [
|
|
39
|
+
{
|
|
40
|
+
matcher: "",
|
|
41
|
+
hooks: [{ type: "command", command: command("stop"), timeout: 10 }],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
SessionEnd: [
|
|
45
|
+
{
|
|
46
|
+
matcher: "",
|
|
47
|
+
hooks: [{ type: "command", command: command("session-end"), timeout: 1 }],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
Notification: [
|
|
51
|
+
{
|
|
52
|
+
matcher: "",
|
|
53
|
+
hooks: [{ type: "command", command: command("notification"), timeout: 10 }],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
UserPromptSubmit: [
|
|
57
|
+
{
|
|
58
|
+
matcher: "",
|
|
59
|
+
hooks: [{ type: "command", command: command("prompt-submit"), timeout: 10 }],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
PreToolUse: [
|
|
63
|
+
{
|
|
64
|
+
matcher: "",
|
|
65
|
+
hooks: [{ type: "command", command: command("pre-tool-use"), timeout: 5, async: true }],
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export function injectClaudeHookArgs(args, opts) {
|
|
72
|
+
const injected = ["--settings", buildClaudeHookSettings(opts), ...args];
|
|
73
|
+
if (!opts.backendSessionId || shouldSkipClaudeSessionIdInjection(args)) {
|
|
74
|
+
return injected;
|
|
75
|
+
}
|
|
76
|
+
return ["--session-id", opts.backendSessionId, ...injected];
|
|
77
|
+
}
|
|
78
|
+
export function parseClaudeHookPayload(raw) {
|
|
79
|
+
try {
|
|
80
|
+
return JSON.parse(raw);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return {};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function pickString(...values) {
|
|
87
|
+
for (const value of values) {
|
|
88
|
+
if (typeof value === "string" && value.trim())
|
|
89
|
+
return value.trim();
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
export function summarizeClaudeNotification(payload) {
|
|
94
|
+
const object = payload.object ?? {};
|
|
95
|
+
const subtitle = pickString(object.title, object["subtitle"], payload.hook_event_name) ?? "Needs input";
|
|
96
|
+
const body = pickString(payload.message, object["message"], object["body"], object["question"]) ??
|
|
97
|
+
"Claude needs your attention.";
|
|
98
|
+
return { subtitle, body };
|
|
99
|
+
}
|
|
100
|
+
export function summarizeClaudeStop(payload) {
|
|
101
|
+
const object = payload.object ?? {};
|
|
102
|
+
const subtitle = pickString(payload.stop_reason, object["stop_reason"]) ?? "Session complete";
|
|
103
|
+
const body = pickString(payload.message, object["summary"], object["message"]) ?? "Claude completed its turn.";
|
|
104
|
+
return { subtitle, body };
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=claude-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-hooks.js","sourceRoot":"","sources":["../src/claude-hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface NotificationConfig {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
/** Notify when an agent is waiting for input */
|
|
4
|
+
onPrompt: boolean;
|
|
5
|
+
/** Notify on errors */
|
|
6
|
+
onError: boolean;
|
|
7
|
+
/** Notify when an agent completes a task */
|
|
8
|
+
onComplete: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface WorktreeConfig {
|
|
11
|
+
/** Base directory for created worktrees. Relative paths are resolved from the main repo root. */
|
|
12
|
+
baseDir: string;
|
|
13
|
+
}
|
|
14
|
+
export interface TmuxRuntimeConfig {
|
|
15
|
+
/** Deterministic prefix for managed per-project tmux sessions. */
|
|
16
|
+
sessionPrefix: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RuntimeConfig {
|
|
19
|
+
tmux: TmuxRuntimeConfig;
|
|
20
|
+
}
|
|
21
|
+
export interface AimuxConfig {
|
|
22
|
+
defaultTool: string;
|
|
23
|
+
contextMaxEntries: number;
|
|
24
|
+
liveWindowSize: number;
|
|
25
|
+
compactEveryNTurns: number;
|
|
26
|
+
notifications: NotificationConfig;
|
|
27
|
+
runtime: RuntimeConfig;
|
|
28
|
+
worktrees: WorktreeConfig;
|
|
29
|
+
tools: Record<string, ToolConfig>;
|
|
30
|
+
}
|
|
31
|
+
export interface SessionCaptureConfig {
|
|
32
|
+
/** Directory to watch for new files. Supports {home}, {yyyy}, {mm}, {dd} */
|
|
33
|
+
dir: string;
|
|
34
|
+
/** Regex to extract session ID from filename */
|
|
35
|
+
pattern: string;
|
|
36
|
+
/** Delay before first check in ms */
|
|
37
|
+
delayMs: number;
|
|
38
|
+
}
|
|
39
|
+
export interface ToolConfig {
|
|
40
|
+
command: string;
|
|
41
|
+
args: string[];
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
/** Whether aimux should inject an automatic Claude hook wrapper/config for this tool. */
|
|
44
|
+
wrapperEnabled?: boolean;
|
|
45
|
+
/** Flag/args to inject system prompt preamble, e.g. ["--append-system-prompt"] */
|
|
46
|
+
preambleFlag?: string[];
|
|
47
|
+
/** Args to resume a specific session, with {sessionId} placeholder, e.g. ["--resume", "{sessionId}"] */
|
|
48
|
+
resumeArgs?: string[];
|
|
49
|
+
/**
|
|
50
|
+
* Whether backendSessionId values tracked by aimux are valid inputs for resumeArgs.
|
|
51
|
+
* Some tools expose a session-id flag without guaranteeing that the same value is later resumable.
|
|
52
|
+
*/
|
|
53
|
+
resumeByBackendSessionId?: boolean;
|
|
54
|
+
/** Fallback resume args when backendSessionId is unavailable, e.g. ["--continue"] */
|
|
55
|
+
resumeFallback?: string[];
|
|
56
|
+
/** Flag to set a session ID when starting, with {sessionId} placeholder, e.g. ["--session-id", "{sessionId}"] */
|
|
57
|
+
sessionIdFlag?: string[];
|
|
58
|
+
/** How to capture backend session ID when sessionIdFlag isn't available */
|
|
59
|
+
sessionCapture?: SessionCaptureConfig;
|
|
60
|
+
/** File to write preamble instructions to (created on start, removed on exit), e.g. "AGENTS.md" */
|
|
61
|
+
instructionsFile?: string;
|
|
62
|
+
/** Regex patterns that indicate the tool is idle/waiting for input */
|
|
63
|
+
promptPatterns?: string[];
|
|
64
|
+
/** Regex patterns to detect user prompts in terminal output (for turn extraction) */
|
|
65
|
+
turnPatterns?: string[];
|
|
66
|
+
/** Command to use for LLM compaction (default: "claude --print --output-format text") */
|
|
67
|
+
compactCommand?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Load config with hierarchy: defaults → global (~/.aimux/config.json) → project (.aimux/config.json)
|
|
71
|
+
* Project settings override global, global overrides defaults.
|
|
72
|
+
*/
|
|
73
|
+
export declare function loadConfig(): AimuxConfig;
|
|
74
|
+
/** Save config to project-level .aimux/config.json */
|
|
75
|
+
export declare function saveConfig(config: AimuxConfig): void;
|
|
76
|
+
/** Save config to global ~/.aimux/config.json */
|
|
77
|
+
export declare function saveGlobalConfig(config: Partial<AimuxConfig>): void;
|
|
78
|
+
export declare function initProject(): void;
|