aimux-cli 0.1.18 → 0.1.20
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 +13 -4
- package/bin/aimux +4 -0
- package/bin/aimux-dev +2 -6
- package/dist/agent-events.js +0 -1
- package/dist/agent-output-parser-audit.d.ts +23 -0
- package/dist/agent-output-parser-audit.js +187 -0
- package/dist/agent-output-parser-contract.d.ts +9 -0
- package/dist/agent-output-parser-contract.js +33 -0
- package/dist/agent-output-parser-fixtures.d.ts +15 -0
- package/dist/agent-output-parser-fixtures.js +593 -0
- package/dist/agent-output-parser-harness.d.ts +21 -0
- package/dist/agent-output-parser-harness.js +43 -0
- package/dist/agent-output-parser-test-utils.d.ts +1 -0
- package/dist/agent-output-parser-test-utils.js +7 -0
- package/dist/agent-output-parser.js +215 -36
- package/dist/agent-prompt-delivery.js +0 -1
- package/dist/agent-tracker.js +0 -1
- package/dist/agent-watcher.js +0 -1
- package/dist/alert-display.js +0 -1
- package/dist/atomic-write.d.ts +15 -0
- package/dist/atomic-write.js +69 -5
- package/dist/attachment-store.d.ts +7 -0
- package/dist/attachment-store.js +64 -6
- package/dist/backend-session-discovery.d.ts +17 -0
- package/dist/backend-session-discovery.js +57 -0
- package/dist/builtin-metadata-watchers.js +0 -1
- package/dist/claude-hooks.js +0 -1
- package/dist/config.js +9 -5
- package/dist/connection-targets.js +20 -2
- package/dist/context/compactor.js +0 -1
- package/dist/context/context-bridge.js +4 -2
- package/dist/context/context-file.js +0 -1
- package/dist/context/history.js +0 -1
- package/dist/credentials.js +3 -7
- package/dist/daemon.d.ts +1 -0
- package/dist/daemon.js +16 -1
- package/dist/dashboard/command-spec.js +0 -1
- package/dist/dashboard/feedback.js +0 -1
- package/dist/dashboard/index.d.ts +1 -0
- package/dist/dashboard/index.js +1 -1
- package/dist/dashboard/operation-failures.js +0 -1
- package/dist/dashboard/order.js +0 -1
- package/dist/dashboard/pending-actions.js +0 -1
- package/dist/dashboard/quick-jump.js +0 -1
- package/dist/dashboard/runtime-evidence.js +0 -1
- package/dist/dashboard/session-actions.js +0 -1
- package/dist/dashboard/session-registry.js +0 -1
- package/dist/dashboard/sort.js +0 -1
- package/dist/dashboard/state.js +0 -1
- package/dist/dashboard/targets.js +14 -3
- package/dist/dashboard/ui-state-store.js +4 -4
- package/dist/debug-state.js +0 -1
- package/dist/debug.js +0 -1
- package/dist/default-plugins/gh-pr-context.js +0 -1
- package/dist/default-plugins/transcript-length.js +0 -1
- package/dist/fast-control.js +0 -1
- package/dist/hotkeys.js +0 -1
- package/dist/http-client.js +0 -1
- package/dist/key-parser.js +0 -1
- package/dist/last-used.js +3 -3
- package/dist/launcher-env.d.ts +4 -0
- package/dist/launcher-env.js +70 -0
- package/dist/local-ui-server.js +0 -1
- package/dist/login-flow.js +0 -1
- package/dist/main.js +16 -2
- package/dist/managed-launch-env.js +0 -1
- package/dist/metadata-server.d.ts +13 -2
- package/dist/metadata-server.js +60 -5
- package/dist/metadata-store.js +4 -4
- package/dist/mobile-push-bridge.d.ts +8 -0
- package/dist/mobile-push-bridge.js +22 -0
- package/dist/mobile-push-throttle.d.ts +23 -0
- package/dist/mobile-push-throttle.js +53 -0
- package/dist/multiplexer/agent-io-methods.js +0 -1
- package/dist/multiplexer/archives.js +0 -1
- package/dist/multiplexer/dashboard-actions-methods.js +0 -1
- package/dist/multiplexer/dashboard-control.js +0 -1
- package/dist/multiplexer/dashboard-interaction.js +0 -1
- package/dist/multiplexer/dashboard-model.js +3 -3
- package/dist/multiplexer/dashboard-ops.d.ts +3 -2
- package/dist/multiplexer/dashboard-ops.js +2 -3
- package/dist/multiplexer/dashboard-state-methods.js +0 -1
- package/dist/multiplexer/dashboard-tail-methods.d.ts +3 -2
- package/dist/multiplexer/dashboard-tail-methods.js +2 -3
- package/dist/multiplexer/dashboard-view-methods.js +2 -1
- package/dist/multiplexer/graveyard-view-model.js +0 -1
- package/dist/multiplexer/index.d.ts +1 -1
- package/dist/multiplexer/index.js +4 -5
- package/dist/multiplexer/navigation.js +0 -1
- package/dist/multiplexer/notifications.js +0 -1
- package/dist/multiplexer/persistence-methods.js +2 -2
- package/dist/multiplexer/runtime-lifecycle-methods.js +6 -3
- package/dist/multiplexer/runtime-state.js +13 -2
- package/dist/multiplexer/runtime-sync.js +0 -1
- package/dist/multiplexer/service-state-snapshot.js +4 -3
- package/dist/multiplexer/services.js +5 -5
- package/dist/multiplexer/session-capture.js +0 -1
- package/dist/multiplexer/session-launch.d.ts +1 -1
- package/dist/multiplexer/session-launch.js +18 -7
- package/dist/multiplexer/session-runtime-core.js +9 -3
- package/dist/multiplexer/subscreens.js +0 -1
- package/dist/multiplexer/tool-picker.d.ts +2 -1
- package/dist/multiplexer/tool-picker.js +29 -22
- package/dist/multiplexer/worktree-graveyard.js +0 -1
- package/dist/multiplexer/worktrees.js +0 -1
- package/dist/notification-context.js +0 -1
- package/dist/notifications.js +0 -1
- package/dist/notify.d.ts +1 -1
- package/dist/notify.js +8 -6
- package/dist/orchestration-actions.js +0 -1
- package/dist/orchestration-routing.js +0 -1
- package/dist/orchestration.js +0 -1
- package/dist/osc-notifications.js +0 -1
- package/dist/paths.js +50 -5
- package/dist/pending-actions.js +0 -1
- package/dist/plugin-runtime.js +0 -1
- package/dist/project-events.js +0 -1
- package/dist/project-scanner.js +0 -1
- package/dist/project-service-manifest.js +0 -1
- package/dist/project-takeover.d.ts +1 -0
- package/dist/project-takeover.js +117 -0
- package/dist/recency.js +0 -1
- package/dist/recorder.js +0 -1
- package/dist/relay-client.d.ts +10 -0
- package/dist/relay-client.js +5 -1
- package/dist/remote-access.js +0 -1
- package/dist/runtime-core/backend-id-reconcile.d.ts +13 -0
- package/dist/runtime-core/backend-id-reconcile.js +23 -0
- package/dist/runtime-core/exchange-derived.js +0 -1
- package/dist/runtime-core/exchange-import.js +0 -1
- package/dist/runtime-core/exchange-store.js +3 -9
- package/dist/runtime-core/topology-services.js +0 -1
- package/dist/runtime-core/topology-sessions.js +0 -1
- package/dist/runtime-core/topology-store.js +3 -9
- package/dist/runtime-core/topology-worktrees.js +0 -1
- package/dist/runtime-migration.js +0 -1
- package/dist/runtime-owner.d.ts +3 -0
- package/dist/runtime-owner.js +10 -0
- package/dist/session-bootstrap.js +0 -1
- package/dist/session-runtime.js +0 -1
- package/dist/session-semantics.js +0 -1
- package/dist/shell-args.d.ts +13 -0
- package/dist/shell-args.js +25 -1
- package/dist/shell-hooks.d.ts +1 -0
- package/dist/shell-hooks.js +1 -1
- package/dist/shell-state.js +0 -1
- package/dist/status-detector.js +0 -1
- package/dist/statusline-model.js +0 -1
- package/dist/task-workflow.js +0 -1
- package/dist/tasks.js +0 -1
- package/dist/team.js +4 -4
- package/dist/terminal-host.js +0 -1
- package/dist/threads.js +0 -1
- package/dist/tmux/doctor.js +0 -1
- package/dist/tmux/inbox-popup.js +0 -1
- package/dist/tmux/runtime-manager.js +2 -1
- package/dist/tmux/session-transport.js +0 -1
- package/dist/tmux/statusline-cache.js +0 -1
- package/dist/tmux/statusline.js +0 -1
- package/dist/tmux/switcher.js +0 -1
- package/dist/tmux/window-open.js +0 -1
- package/dist/tool-output-watchers.js +0 -1
- package/dist/tui/render/box.js +0 -1
- package/dist/tui/render/text.js +0 -1
- package/dist/tui/screens/dashboard-renderers.js +6 -7
- package/dist/tui/screens/overlay-renderers.js +0 -1
- package/dist/tui/screens/subscreen-renderers.js +0 -1
- package/dist/vitest.setup.d.ts +1 -0
- package/dist/vitest.setup.js +9 -0
- package/dist/workflow.js +0 -1
- package/dist/worktree.js +0 -1
- package/dist-ui/_expo/static/css/web-8782287775683e5a944b821b854d0f60.css +1 -0
- package/dist-ui/_expo/static/js/web/{entry-477c745b2adc79367a4380ecf07d9ff6.js → entry-90d00d223eefabe5cc21e4329b274fa5.js} +260 -252
- package/dist-ui/index.html +2 -2
- package/package.json +5 -2
- package/dist/agent-events.js.map +0 -1
- package/dist/agent-output-parser.js.map +0 -1
- package/dist/agent-prompt-delivery.js.map +0 -1
- package/dist/agent-tracker.js.map +0 -1
- package/dist/agent-watcher.js.map +0 -1
- package/dist/alert-display.js.map +0 -1
- package/dist/atomic-write.js.map +0 -1
- package/dist/attachment-store.js.map +0 -1
- package/dist/builtin-metadata-watchers.js.map +0 -1
- package/dist/claude-hooks.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/connection-targets.js.map +0 -1
- package/dist/context/compactor.js.map +0 -1
- package/dist/context/context-bridge.js.map +0 -1
- package/dist/context/context-file.js.map +0 -1
- package/dist/context/history.js.map +0 -1
- package/dist/credentials.js.map +0 -1
- package/dist/daemon.js.map +0 -1
- package/dist/dashboard/command-spec.js.map +0 -1
- package/dist/dashboard/feedback.js.map +0 -1
- package/dist/dashboard/index.js.map +0 -1
- package/dist/dashboard/operation-failures.js.map +0 -1
- package/dist/dashboard/order.js.map +0 -1
- package/dist/dashboard/pending-actions.js.map +0 -1
- package/dist/dashboard/quick-jump.js.map +0 -1
- package/dist/dashboard/runtime-evidence.js.map +0 -1
- package/dist/dashboard/session-actions.js.map +0 -1
- package/dist/dashboard/session-registry.js.map +0 -1
- package/dist/dashboard/sort.js.map +0 -1
- package/dist/dashboard/state.js.map +0 -1
- package/dist/dashboard/targets.js.map +0 -1
- package/dist/dashboard/ui-state-store.js.map +0 -1
- package/dist/debug-state.js.map +0 -1
- package/dist/debug.js.map +0 -1
- package/dist/default-plugins/gh-pr-context.js.map +0 -1
- package/dist/default-plugins/transcript-length.js.map +0 -1
- package/dist/fast-control.js.map +0 -1
- package/dist/hotkeys.js.map +0 -1
- package/dist/http-client.js.map +0 -1
- package/dist/key-parser.js.map +0 -1
- package/dist/last-used.js.map +0 -1
- package/dist/local-ui-server.js.map +0 -1
- package/dist/login-flow.js.map +0 -1
- package/dist/main.js.map +0 -1
- package/dist/managed-launch-env.js.map +0 -1
- package/dist/metadata-server.js.map +0 -1
- package/dist/metadata-store.js.map +0 -1
- package/dist/multiplexer/agent-io-methods.js.map +0 -1
- package/dist/multiplexer/archives.js.map +0 -1
- package/dist/multiplexer/dashboard-actions-methods.js.map +0 -1
- package/dist/multiplexer/dashboard-control.js.map +0 -1
- package/dist/multiplexer/dashboard-interaction.js.map +0 -1
- package/dist/multiplexer/dashboard-model.js.map +0 -1
- package/dist/multiplexer/dashboard-ops.js.map +0 -1
- package/dist/multiplexer/dashboard-state-methods.js.map +0 -1
- package/dist/multiplexer/dashboard-tail-methods.js.map +0 -1
- package/dist/multiplexer/dashboard-view-methods.js.map +0 -1
- package/dist/multiplexer/graveyard-view-model.js.map +0 -1
- package/dist/multiplexer/index.js.map +0 -1
- package/dist/multiplexer/navigation.js.map +0 -1
- package/dist/multiplexer/notifications.js.map +0 -1
- package/dist/multiplexer/persistence-methods.js.map +0 -1
- package/dist/multiplexer/runtime-lifecycle-methods.js.map +0 -1
- package/dist/multiplexer/runtime-state.js.map +0 -1
- package/dist/multiplexer/runtime-sync.js.map +0 -1
- package/dist/multiplexer/service-state-snapshot.js.map +0 -1
- package/dist/multiplexer/services.js.map +0 -1
- package/dist/multiplexer/session-capture.js.map +0 -1
- package/dist/multiplexer/session-launch.js.map +0 -1
- package/dist/multiplexer/session-runtime-core.js.map +0 -1
- package/dist/multiplexer/subscreens.js.map +0 -1
- package/dist/multiplexer/tool-picker.js.map +0 -1
- package/dist/multiplexer/worktree-graveyard.js.map +0 -1
- package/dist/multiplexer/worktrees.js.map +0 -1
- package/dist/notification-context.js.map +0 -1
- package/dist/notifications.js.map +0 -1
- package/dist/notify.js.map +0 -1
- package/dist/orchestration-actions.js.map +0 -1
- package/dist/orchestration-routing.js.map +0 -1
- package/dist/orchestration.js.map +0 -1
- package/dist/osc-notifications.js.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/pending-actions.js.map +0 -1
- package/dist/plugin-runtime.js.map +0 -1
- package/dist/project-events.js.map +0 -1
- package/dist/project-scanner.js.map +0 -1
- package/dist/project-service-manifest.js.map +0 -1
- package/dist/recency.js.map +0 -1
- package/dist/recorder.js.map +0 -1
- package/dist/relay-client.js.map +0 -1
- package/dist/remote-access.js.map +0 -1
- package/dist/runtime-core/exchange-derived.js.map +0 -1
- package/dist/runtime-core/exchange-import.js.map +0 -1
- package/dist/runtime-core/exchange-store.js.map +0 -1
- package/dist/runtime-core/topology-services.js.map +0 -1
- package/dist/runtime-core/topology-sessions.js.map +0 -1
- package/dist/runtime-core/topology-store.js.map +0 -1
- package/dist/runtime-core/topology-worktrees.js.map +0 -1
- package/dist/runtime-migration.js.map +0 -1
- package/dist/session-bootstrap.js.map +0 -1
- package/dist/session-runtime.js.map +0 -1
- package/dist/session-semantics.js.map +0 -1
- package/dist/shell-args.js.map +0 -1
- package/dist/shell-hooks.js.map +0 -1
- package/dist/shell-state.js.map +0 -1
- package/dist/status-detector.js.map +0 -1
- package/dist/statusline-model.js.map +0 -1
- package/dist/task-workflow.js.map +0 -1
- package/dist/tasks.js.map +0 -1
- package/dist/team.js.map +0 -1
- package/dist/terminal-host.js.map +0 -1
- package/dist/threads.js.map +0 -1
- package/dist/tmux/doctor.js.map +0 -1
- package/dist/tmux/inbox-popup.js.map +0 -1
- package/dist/tmux/runtime-manager.js.map +0 -1
- package/dist/tmux/session-transport.js.map +0 -1
- package/dist/tmux/statusline-cache.js.map +0 -1
- package/dist/tmux/statusline.js.map +0 -1
- package/dist/tmux/switcher.js.map +0 -1
- package/dist/tmux/window-open.js.map +0 -1
- package/dist/tool-output-watchers.js.map +0 -1
- package/dist/tui/render/box.js.map +0 -1
- package/dist/tui/render/text.js.map +0 -1
- package/dist/tui/screens/dashboard-renderers.js.map +0 -1
- package/dist/tui/screens/overlay-renderers.js.map +0 -1
- package/dist/tui/screens/subscreen-renderers.js.map +0 -1
- package/dist/workflow.js.map +0 -1
- package/dist/worktree.js.map +0 -1
- package/dist-ui/_expo/static/css/web-30453ede1678c16acb08b97e83e8646d.css +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
5
|
+
import { getGlobalAimuxDir, getProjectIdFor } from "./paths.js";
|
|
6
|
+
import { writeJsonAtomic } from "./atomic-write.js";
|
|
7
|
+
import { requestJson } from "./http-client.js";
|
|
8
|
+
import { log } from "./debug.js";
|
|
9
|
+
function isPidAlive(pid) {
|
|
10
|
+
try {
|
|
11
|
+
process.kill(pid, 0);
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function knownOwners() {
|
|
19
|
+
return [
|
|
20
|
+
{ home: join(homedir(), ".aimux"), port: 43190 },
|
|
21
|
+
{ home: join(homedir(), ".aimux-dev"), port: 43191 },
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
function readJson(path) {
|
|
25
|
+
if (!existsSync(path))
|
|
26
|
+
return null;
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function writeJson(path, value) {
|
|
35
|
+
writeJsonAtomic(path, value);
|
|
36
|
+
}
|
|
37
|
+
function isAimuxProjectServiceProcess(pid) {
|
|
38
|
+
try {
|
|
39
|
+
const args = execFileSync("ps", ["-o", "args=", "-p", String(pid)], {
|
|
40
|
+
encoding: "utf8",
|
|
41
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
42
|
+
});
|
|
43
|
+
return args.includes("__project-service-internal");
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function requestOtherOwnerStop(owner, projectRoot) {
|
|
50
|
+
const info = readJson(join(owner.home, "daemon", "daemon.json"));
|
|
51
|
+
const port = info?.port ?? owner.port;
|
|
52
|
+
if (!info?.pid || !isPidAlive(info.pid))
|
|
53
|
+
return false;
|
|
54
|
+
try {
|
|
55
|
+
const { status, json } = await requestJson(`http://127.0.0.1:${port}/projects/stop`, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "content-type": "application/json" },
|
|
58
|
+
body: { projectRoot },
|
|
59
|
+
timeoutMs: 1500,
|
|
60
|
+
});
|
|
61
|
+
return status >= 200 && status < 300 && json?.ok !== false;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function cleanOtherOwnerProjectState(owner, projectId) {
|
|
68
|
+
const statePath = join(owner.home, "daemon", "state.json");
|
|
69
|
+
const state = readJson(statePath);
|
|
70
|
+
const entry = state?.projects?.[projectId];
|
|
71
|
+
if (entry?.pid && isPidAlive(entry.pid)) {
|
|
72
|
+
if (isAimuxProjectServiceProcess(entry.pid)) {
|
|
73
|
+
try {
|
|
74
|
+
process.kill(entry.pid, "SIGTERM");
|
|
75
|
+
}
|
|
76
|
+
catch { }
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
log.warn("skipping stale takeover pid with unverified identity", "daemon", {
|
|
80
|
+
ownerHome: owner.home,
|
|
81
|
+
projectId,
|
|
82
|
+
projectRoot: entry.projectRoot,
|
|
83
|
+
pid: entry.pid,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (state?.projects?.[projectId]) {
|
|
88
|
+
delete state.projects[projectId];
|
|
89
|
+
writeJson(statePath, state);
|
|
90
|
+
}
|
|
91
|
+
const projectStateDir = join(owner.home, "projects", projectId);
|
|
92
|
+
for (const file of ["metadata-api.json", "metadata-api.txt", "host.json"]) {
|
|
93
|
+
try {
|
|
94
|
+
rmSync(join(projectStateDir, file), { force: true });
|
|
95
|
+
}
|
|
96
|
+
catch { }
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function takeOverProjectFromOtherOwners(projectRoot) {
|
|
100
|
+
const currentHome = resolve(getGlobalAimuxDir());
|
|
101
|
+
const projectId = getProjectIdFor(projectRoot);
|
|
102
|
+
for (const owner of knownOwners()) {
|
|
103
|
+
if (resolve(owner.home) === currentHome)
|
|
104
|
+
continue;
|
|
105
|
+
try {
|
|
106
|
+
await requestOtherOwnerStop(owner, projectRoot);
|
|
107
|
+
cleanOtherOwnerProjectState(owner, projectId);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
log.warn("project takeover cleanup failed for alternate owner", "daemon", {
|
|
111
|
+
ownerHome: owner.home,
|
|
112
|
+
projectRoot,
|
|
113
|
+
error: error instanceof Error ? error.message : String(error),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
package/dist/recency.js
CHANGED
package/dist/recorder.js
CHANGED
package/dist/relay-client.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { AimuxDaemon } from "./daemon.js";
|
|
2
|
+
export interface RelayNotificationPush {
|
|
3
|
+
title: string;
|
|
4
|
+
body: string;
|
|
5
|
+
kind?: string;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
projectId?: string;
|
|
8
|
+
projectRoot?: string;
|
|
9
|
+
dedupeKey?: string;
|
|
10
|
+
}
|
|
2
11
|
export type RelayConnectionStatus = "connected" | "connecting" | "reconnecting" | "disconnected" | "auth_failed";
|
|
3
12
|
export interface RelayStatusSnapshot {
|
|
4
13
|
status: RelayConnectionStatus;
|
|
@@ -22,6 +31,7 @@ export declare class RelayClient {
|
|
|
22
31
|
constructor(relayUrl: string, token: string, daemon: AimuxDaemon);
|
|
23
32
|
getStatus(): RelayStatusSnapshot;
|
|
24
33
|
connect(): void;
|
|
34
|
+
pushNotification(notification: RelayNotificationPush): void;
|
|
25
35
|
disconnect(): void;
|
|
26
36
|
private handleMessage;
|
|
27
37
|
private sendRaw;
|
package/dist/relay-client.js
CHANGED
|
@@ -100,6 +100,11 @@ export class RelayClient {
|
|
|
100
100
|
catch { }
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
|
+
pushNotification(notification) {
|
|
104
|
+
if (!notification.title)
|
|
105
|
+
return;
|
|
106
|
+
this.sendRaw(JSON.stringify({ type: "notification_push", notification }));
|
|
107
|
+
}
|
|
103
108
|
disconnect() {
|
|
104
109
|
this.stopped = true;
|
|
105
110
|
this.status = "disconnected";
|
|
@@ -188,4 +193,3 @@ export class RelayClient {
|
|
|
188
193
|
this.retryMs = Math.min(this.retryMs * 2, MAX_RETRY_MS);
|
|
189
194
|
}
|
|
190
195
|
}
|
|
191
|
-
//# sourceMappingURL=relay-client.js.map
|
package/dist/remote-access.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface BackendIdReconcileResult {
|
|
2
|
+
reconciled: Array<{
|
|
3
|
+
id: string;
|
|
4
|
+
backendSessionId: string;
|
|
5
|
+
}>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Backfill missing backend session ids for offline sessions from each tool's
|
|
9
|
+
* on-disk session store, so a crash that lost the id before capture does not
|
|
10
|
+
* leave the agent unresumable. Idempotent: sessions that already have an id,
|
|
11
|
+
* or whose id cannot be found on disk, are left untouched.
|
|
12
|
+
*/
|
|
13
|
+
export declare function reconcileOfflineBackendSessionIds(projectRoot?: string): BackendIdReconcileResult;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { discoverBackendSessionId } from "../backend-session-discovery.js";
|
|
2
|
+
import { getRepoRoot } from "../paths.js";
|
|
3
|
+
import { listTopologySessionStates, upsertTopologySession } from "./topology-sessions.js";
|
|
4
|
+
/**
|
|
5
|
+
* Backfill missing backend session ids for offline sessions from each tool's
|
|
6
|
+
* on-disk session store, so a crash that lost the id before capture does not
|
|
7
|
+
* leave the agent unresumable. Idempotent: sessions that already have an id,
|
|
8
|
+
* or whose id cannot be found on disk, are left untouched.
|
|
9
|
+
*/
|
|
10
|
+
export function reconcileOfflineBackendSessionIds(projectRoot = getRepoRoot()) {
|
|
11
|
+
const reconciled = [];
|
|
12
|
+
for (const session of listTopologySessionStates({ statuses: ["offline"] })) {
|
|
13
|
+
if (session.backendSessionId)
|
|
14
|
+
continue;
|
|
15
|
+
const cwd = session.worktreePath ?? projectRoot;
|
|
16
|
+
const discovered = discoverBackendSessionId(session.toolConfigKey, cwd);
|
|
17
|
+
if (!discovered)
|
|
18
|
+
continue;
|
|
19
|
+
upsertTopologySession({ ...session, backendSessionId: discovered }, "offline", { projectRoot });
|
|
20
|
+
reconciled.push({ id: session.id, backendSessionId: discovered });
|
|
21
|
+
}
|
|
22
|
+
return { reconciled };
|
|
23
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync,
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { parse, stringify } from "yaml";
|
|
4
|
+
import { atomicWrite } from "../atomic-write.js";
|
|
4
5
|
import { getRuntimeExchangePath } from "../paths.js";
|
|
5
6
|
export const RUNTIME_EXCHANGE_VERSION = 1;
|
|
6
7
|
const UPDATE_LOCK_TIMEOUT_MS = 5_000;
|
|
@@ -376,14 +377,8 @@ export class RuntimeExchangeStore {
|
|
|
376
377
|
return coerceRuntimeExchange(parsed);
|
|
377
378
|
}
|
|
378
379
|
write(exchange) {
|
|
379
|
-
mkdirSync(dirname(this.path), { recursive: true });
|
|
380
380
|
const normalized = coerceRuntimeExchange(exchange);
|
|
381
|
-
|
|
382
|
-
writeFileSync(tmpPath, stringify(normalized, {
|
|
383
|
-
lineWidth: 120,
|
|
384
|
-
sortMapEntries: false,
|
|
385
|
-
}));
|
|
386
|
-
renameSync(tmpPath, this.path);
|
|
381
|
+
atomicWrite(this.path, stringify(normalized, { lineWidth: 120, sortMapEntries: false }));
|
|
387
382
|
return normalized;
|
|
388
383
|
}
|
|
389
384
|
acquireUpdateLock() {
|
|
@@ -450,4 +445,3 @@ export class RuntimeExchangeStore {
|
|
|
450
445
|
export function createRuntimeExchangeStore(path) {
|
|
451
446
|
return new RuntimeExchangeStore(path);
|
|
452
447
|
}
|
|
453
|
-
//# sourceMappingURL=exchange-store.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync,
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { parse, stringify } from "yaml";
|
|
4
|
+
import { atomicWrite } from "../atomic-write.js";
|
|
4
5
|
import { getRuntimeTopologyPath } from "../paths.js";
|
|
5
6
|
export const RUNTIME_TOPOLOGY_VERSION = 1;
|
|
6
7
|
const UPDATE_LOCK_TIMEOUT_MS = 5_000;
|
|
@@ -370,14 +371,8 @@ export class RuntimeTopologyStore {
|
|
|
370
371
|
return coerceRuntimeTopology(parsed);
|
|
371
372
|
}
|
|
372
373
|
write(topology) {
|
|
373
|
-
mkdirSync(dirname(this.path), { recursive: true });
|
|
374
374
|
const normalized = coerceRuntimeTopology(topology);
|
|
375
|
-
|
|
376
|
-
writeFileSync(tmpPath, stringify(normalized, {
|
|
377
|
-
lineWidth: 120,
|
|
378
|
-
sortMapEntries: false,
|
|
379
|
-
}));
|
|
380
|
-
renameSync(tmpPath, this.path);
|
|
375
|
+
atomicWrite(this.path, stringify(normalized, { lineWidth: 120, sortMapEntries: false }));
|
|
381
376
|
return normalized;
|
|
382
377
|
}
|
|
383
378
|
acquireUpdateLock() {
|
|
@@ -417,4 +412,3 @@ export class RuntimeTopologyStore {
|
|
|
417
412
|
export function createRuntimeTopologyStore(path) {
|
|
418
413
|
return new RuntimeTopologyStore(path);
|
|
419
414
|
}
|
|
420
|
-
//# sourceMappingURL=topology-store.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getGlobalAimuxDir } from "./paths.js";
|
|
2
|
+
const DEFAULT_DAEMON_PORT = "43190";
|
|
3
|
+
export const TMUX_RUNTIME_OWNER_OPTION = "@aimux-runtime-owner";
|
|
4
|
+
export const TMUX_DASHBOARD_OWNER_OPTION = "@aimux-dashboard-owner";
|
|
5
|
+
export function getRuntimeOwnerId() {
|
|
6
|
+
return JSON.stringify({
|
|
7
|
+
home: getGlobalAimuxDir(),
|
|
8
|
+
port: process.env.AIMUX_DAEMON_PORT?.trim() || DEFAULT_DAEMON_PORT,
|
|
9
|
+
});
|
|
10
|
+
}
|
package/dist/session-runtime.js
CHANGED
package/dist/shell-args.d.ts
CHANGED
|
@@ -1 +1,14 @@
|
|
|
1
|
+
export interface LaunchOverride {
|
|
2
|
+
/** Binary to exec. May differ from the tool's configured command. */
|
|
3
|
+
command: string;
|
|
4
|
+
/** Full argument list (replaces the tool's default args, not appended). */
|
|
5
|
+
args: string[];
|
|
6
|
+
/** Extra env vars merged into the managed launch environment. */
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse a full command line where leading NAME=VALUE tokens are environment
|
|
11
|
+
* assignments, the next token is the command, and the rest are its args.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseLaunchCommandLine(input: string): LaunchOverride;
|
|
1
14
|
export declare function parseShellArgs(input: string): string[];
|
package/dist/shell-args.js
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
const ENV_ASSIGNMENT = /^([A-Za-z_][A-Za-z0-9_]*)=([\s\S]*)$/;
|
|
2
|
+
/**
|
|
3
|
+
* Parse a full command line where leading NAME=VALUE tokens are environment
|
|
4
|
+
* assignments, the next token is the command, and the rest are its args.
|
|
5
|
+
*/
|
|
6
|
+
export function parseLaunchCommandLine(input) {
|
|
7
|
+
const tokens = parseShellArgs(input);
|
|
8
|
+
const env = {};
|
|
9
|
+
let i = 0;
|
|
10
|
+
for (; i < tokens.length; i++) {
|
|
11
|
+
const match = ENV_ASSIGNMENT.exec(tokens[i]);
|
|
12
|
+
if (!match)
|
|
13
|
+
break;
|
|
14
|
+
env[match[1]] = match[2];
|
|
15
|
+
}
|
|
16
|
+
const command = tokens[i];
|
|
17
|
+
if (!command) {
|
|
18
|
+
throw new Error("no command to launch");
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
command,
|
|
22
|
+
args: tokens.slice(i + 1),
|
|
23
|
+
env: Object.keys(env).length ? env : undefined,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
1
26
|
export function parseShellArgs(input) {
|
|
2
27
|
const args = [];
|
|
3
28
|
let current = "";
|
|
@@ -54,4 +79,3 @@ export function parseShellArgs(input) {
|
|
|
54
79
|
}
|
|
55
80
|
return args;
|
|
56
81
|
}
|
|
57
|
-
//# sourceMappingURL=shell-args.js.map
|
package/dist/shell-hooks.d.ts
CHANGED
package/dist/shell-hooks.js
CHANGED
|
@@ -163,6 +163,7 @@ export function prepareShellIntegration(projectRoot, shellPath = process.env.SHE
|
|
|
163
163
|
export function wrapCommandWithShellIntegration(opts) {
|
|
164
164
|
const prepared = prepareShellIntegration(opts.projectRoot, opts.shellPath);
|
|
165
165
|
const envArgs = [
|
|
166
|
+
...Object.entries(opts.extraEnv ?? {}).map(([key, value]) => `${key}=${value}`),
|
|
166
167
|
`AIMUX_SESSION_ID=${opts.sessionId}`,
|
|
167
168
|
`AIMUX_TOOL=${opts.tool}`,
|
|
168
169
|
`AIMUX_METADATA_ENDPOINT_FILE=${join(getProjectStateDirFor(opts.projectRoot), "metadata-api.txt")}`,
|
|
@@ -195,4 +196,3 @@ export function wrapInteractiveShellWithIntegration(opts) {
|
|
|
195
196
|
env: opts.env,
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
|
-
//# sourceMappingURL=shell-hooks.js.map
|
package/dist/shell-state.js
CHANGED
package/dist/status-detector.js
CHANGED
package/dist/statusline-model.js
CHANGED
package/dist/task-workflow.js
CHANGED
package/dist/tasks.js
CHANGED
package/dist/team.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync, readFileSync,
|
|
1
|
+
import { existsSync, readFileSync, mkdirSync } from "node:fs";
|
|
2
2
|
import { getLocalAimuxDir, getProjectTeamPath, getGlobalTeamPath, getGlobalAimuxDir } from "./paths.js";
|
|
3
|
+
import { writeJsonAtomic } from "./atomic-write.js";
|
|
3
4
|
export function isTeammateSession(session) {
|
|
4
5
|
return Boolean(session?.team?.parentSessionId);
|
|
5
6
|
}
|
|
@@ -91,7 +92,7 @@ export function saveTeamConfig(config) {
|
|
|
91
92
|
if (!existsSync(dir)) {
|
|
92
93
|
mkdirSync(dir, { recursive: true });
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
+
writeJsonAtomic(getProjectTeamPath(), config);
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
98
|
* Save team config at the global level (~/.aimux/team.json).
|
|
@@ -101,7 +102,7 @@ export function saveGlobalTeamConfig(config) {
|
|
|
101
102
|
if (!existsSync(dir)) {
|
|
102
103
|
mkdirSync(dir, { recursive: true });
|
|
103
104
|
}
|
|
104
|
-
|
|
105
|
+
writeJsonAtomic(getGlobalTeamPath(), config);
|
|
105
106
|
}
|
|
106
107
|
/**
|
|
107
108
|
* Build a role-specific preamble string for injection into an agent's system prompt.
|
|
@@ -128,4 +129,3 @@ export function buildRolePreamble(role, config) {
|
|
|
128
129
|
}
|
|
129
130
|
return lines.join("\n");
|
|
130
131
|
}
|
|
131
|
-
//# sourceMappingURL=team.js.map
|
package/dist/terminal-host.js
CHANGED
package/dist/threads.js
CHANGED
package/dist/tmux/doctor.js
CHANGED
package/dist/tmux/inbox-popup.js
CHANGED
|
@@ -7,6 +7,7 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { loadConfig } from "../config.js";
|
|
8
8
|
import { debug, log } from "../debug.js";
|
|
9
9
|
import { getProjectStateDirFor } from "../paths.js";
|
|
10
|
+
import { getRuntimeOwnerId, TMUX_RUNTIME_OWNER_OPTION } from "../runtime-owner.js";
|
|
10
11
|
export function isDashboardWindowName(name) {
|
|
11
12
|
return name === "dashboard" || name.startsWith("dashboard-");
|
|
12
13
|
}
|
|
@@ -677,6 +678,7 @@ export class TmuxRuntimeManager {
|
|
|
677
678
|
const statuslineCommand = this.getStatuslineCommandSpec();
|
|
678
679
|
const projectStateDir = getProjectStateDirFor(projectRoot);
|
|
679
680
|
this.exec(["set-option", "-t", sessionName, "@aimux-project-root", projectRoot]);
|
|
681
|
+
this.exec(["set-option", "-t", sessionName, TMUX_RUNTIME_OWNER_OPTION, getRuntimeOwnerId()]);
|
|
680
682
|
this.exec(["set-option", "-t", sessionName, "prefix", MANAGED_TMUX_SESSION_OPTIONS.prefix]);
|
|
681
683
|
this.exec(["set-option", "-t", sessionName, "prefix2", MANAGED_TMUX_SESSION_OPTIONS.prefix2]);
|
|
682
684
|
this.exec(["set-option", "-t", sessionName, "mouse", MANAGED_TMUX_SESSION_OPTIONS.mouse]);
|
|
@@ -970,4 +972,3 @@ export class TmuxRuntimeManager {
|
|
|
970
972
|
function shellQuote(value) {
|
|
971
973
|
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
972
974
|
}
|
|
973
|
-
//# sourceMappingURL=runtime-manager.js.map
|
package/dist/tmux/statusline.js
CHANGED
|
@@ -252,4 +252,3 @@ export function renderTmuxStatuslineFromData(data, projectRoot, line, options =
|
|
|
252
252
|
export function renderTmuxStatusline(projectRoot, line, options = {}) {
|
|
253
253
|
return renderTmuxStatuslineFromData(loadStatusline(projectRoot), projectRoot, line, options);
|
|
254
254
|
}
|
|
255
|
-
//# sourceMappingURL=statusline.js.map
|
package/dist/tmux/switcher.js
CHANGED
package/dist/tmux/window-open.js
CHANGED
|
@@ -82,4 +82,3 @@ export function classifyToolPane(tool, text) {
|
|
|
82
82
|
const promptVisible = !updatePromptVisible && tracksPromptReadiness(tool) && hasToolInputPrompt(tool, text, lastLine);
|
|
83
83
|
return { promptVisible, errorVisible, interruptedVisible, updatePromptVisible, blockedMessage };
|
|
84
84
|
}
|
|
85
|
-
//# sourceMappingURL=tool-output-watchers.js.map
|
package/dist/tui/render/box.js
CHANGED
package/dist/tui/render/text.js
CHANGED
|
@@ -422,12 +422,12 @@ export function renderDashboardFrame(state, cols, rows) {
|
|
|
422
422
|
lines.push("");
|
|
423
423
|
return lines.slice(0, height);
|
|
424
424
|
};
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
"─".repeat(Math.max(0, cols))
|
|
429
|
-
"",
|
|
430
|
-
];
|
|
425
|
+
const devBadge = state.isDevRuntime ? "\x1b[1;30;43m DEV \x1b[0m " : "";
|
|
426
|
+
const title = `${devBadge}\x1b[1maimux\x1b[0m — agent multiplexer${state.runtimeLabel ? ` \x1b[32m● ${state.runtimeLabel}\x1b[0m` : ""}`;
|
|
427
|
+
const divider = state.isDevRuntime
|
|
428
|
+
? `\x1b[33m${"─".repeat(Math.max(0, cols))}\x1b[0m`
|
|
429
|
+
: "─".repeat(Math.max(0, cols));
|
|
430
|
+
const header = ["", centerInBlock(title), divider, ""];
|
|
431
431
|
const content = [];
|
|
432
432
|
const operationFailures = state.operationFailures ?? [];
|
|
433
433
|
if (operationFailures.length > 0) {
|
|
@@ -491,4 +491,3 @@ export function renderDashboardFrame(state, cols, rows) {
|
|
|
491
491
|
scrollOffset,
|
|
492
492
|
};
|
|
493
493
|
}
|
|
494
|
-
//# sourceMappingURL=dashboard-renderers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterAll } from "vitest";
|
|
5
|
+
const aimuxTestHome = mkdtempSync(join(tmpdir(), "aimux-vitest-home-"));
|
|
6
|
+
process.env.AIMUX_HOME = aimuxTestHome;
|
|
7
|
+
afterAll(() => {
|
|
8
|
+
rmSync(aimuxTestHome, { recursive: true, force: true });
|
|
9
|
+
});
|
package/dist/workflow.js
CHANGED
package/dist/worktree.js
CHANGED