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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
+
import { discoverBackendSessionId } from "../backend-session-discovery.js";
|
|
2
3
|
import { loadConfig } from "../config.js";
|
|
3
4
|
import { loadMetadataState, updateSessionMetadata } from "../metadata-store.js";
|
|
4
5
|
import { isToolInternalWorktree, listWorktrees as listAllWorktrees } from "../worktree.js";
|
|
@@ -419,7 +420,18 @@ export function resumeOfflineSession(host, session) {
|
|
|
419
420
|
return;
|
|
420
421
|
const derived = loadMetadataState().sessions[session.id]?.derived;
|
|
421
422
|
const relaunchFresh = derived?.activity === "error" || derived?.attention === "error";
|
|
422
|
-
|
|
423
|
+
let backendSessionId = session.backendSessionId;
|
|
424
|
+
if (!backendSessionId && !relaunchFresh) {
|
|
425
|
+
// The durable backend id can be lost if a crash killed the tmux pane before
|
|
426
|
+
// it was captured. Recover it from the tool's on-disk session store so the
|
|
427
|
+
// agent stays resumable instead of being stranded.
|
|
428
|
+
const discovered = discoverBackendSessionId(session.toolConfigKey, session.worktreePath);
|
|
429
|
+
if (discovered) {
|
|
430
|
+
backendSessionId = discovered;
|
|
431
|
+
session.backendSessionId = discovered;
|
|
432
|
+
host.debug?.(`reconciled backend session id for ${session.id} from disk: ${discovered}`, "session");
|
|
433
|
+
}
|
|
434
|
+
}
|
|
423
435
|
const useBackendResume = !relaunchFresh && host.sessionBootstrap.canResumeWithBackendSessionId(toolCfg, backendSessionId);
|
|
424
436
|
let actionArgs;
|
|
425
437
|
if (useBackendResume) {
|
|
@@ -499,4 +511,3 @@ export function stopProjectServiceRefresh(host) {
|
|
|
499
511
|
export function listDesktopWorktrees(_host) {
|
|
500
512
|
return listAllWorktrees().filter((wt) => !wt.isBare && !isToolInternalWorktree(wt));
|
|
501
513
|
}
|
|
502
|
-
//# sourceMappingURL=runtime-state.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync, readFileSync
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { getStatePath } from "../paths.js";
|
|
3
|
+
import { quarantineCorruptFile, writeJsonAtomic } from "../atomic-write.js";
|
|
3
4
|
import { buildServiceStateFromMetadata } from "./services.js";
|
|
4
5
|
import { listWorktreeGraveyardPaths } from "./worktree-graveyard.js";
|
|
5
6
|
function isAvailableSnapshotWorktree(worktreePath, graveyardPaths = listWorktreeGraveyardPaths()) {
|
|
@@ -61,14 +62,14 @@ export function persistProjectRuntimeSnapshotsBeforeTmuxStop(projectRoot, tmux)
|
|
|
61
62
|
existing = JSON.parse(readFileSync(statePath, "utf-8"));
|
|
62
63
|
}
|
|
63
64
|
catch {
|
|
65
|
+
quarantineCorruptFile(statePath);
|
|
64
66
|
existing = null;
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
const nextState = mergeRuntimeSnapshots(existing, { services }, projectRoot);
|
|
68
|
-
|
|
70
|
+
writeJsonAtomic(statePath, nextState);
|
|
69
71
|
return { sessions: [], services };
|
|
70
72
|
}
|
|
71
73
|
export function persistProjectServiceSnapshotsBeforeRuntimeStop(projectRoot, tmux) {
|
|
72
74
|
return persistProjectRuntimeSnapshotsBeforeTmuxStop(projectRoot, tmux).services;
|
|
73
75
|
}
|
|
74
|
-
//# sourceMappingURL=service-state-snapshot.js.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { existsSync, readFileSync
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import { findMainRepo } from "../worktree.js";
|
|
4
4
|
import { getStatePath } from "../paths.js";
|
|
5
|
+
import { writeJsonAtomic } from "../atomic-write.js";
|
|
5
6
|
import { wrapCommandWithShellIntegration, wrapInteractiveShellWithIntegration } from "../shell-hooks.js";
|
|
6
7
|
import { markLastUsed } from "../last-used.js";
|
|
7
8
|
import { removeTopologyService, upsertTopologyService, } from "../runtime-core/topology-services.js";
|
|
@@ -119,7 +120,7 @@ export function createService(host, commandLine, worktreePath, opts) {
|
|
|
119
120
|
const command = wrapped.command;
|
|
120
121
|
const args = wrapped.args;
|
|
121
122
|
const label = serviceLabelForCommand(trimmed);
|
|
122
|
-
const tmuxSession = host.tmuxRuntimeManager.ensureProjectSession(
|
|
123
|
+
const tmuxSession = host.tmuxRuntimeManager.ensureProjectSession(projectRoot);
|
|
123
124
|
const shouldRenderPending = host.startedInDashboard && host.mode === "dashboard";
|
|
124
125
|
if (shouldRenderPending) {
|
|
125
126
|
host.setPendingDashboardServiceAction(serviceId, "creating", {
|
|
@@ -237,7 +238,7 @@ export function removeOfflineService(host, serviceId) {
|
|
|
237
238
|
try {
|
|
238
239
|
const state = JSON.parse(readFileSync(statePath, "utf-8"));
|
|
239
240
|
state.services = (state.services ?? []).filter((service) => service.id !== serviceId);
|
|
240
|
-
|
|
241
|
+
writeJsonAtomic(statePath, state);
|
|
241
242
|
}
|
|
242
243
|
catch { }
|
|
243
244
|
}
|
|
@@ -299,7 +300,7 @@ export function resumeOfflineService(host, service) {
|
|
|
299
300
|
const command = wrapped.command;
|
|
300
301
|
const args = wrapped.args;
|
|
301
302
|
const label = service.label ?? serviceLabelForCommand(launchCommandLine);
|
|
302
|
-
const tmuxSession = host.tmuxRuntimeManager.ensureProjectSession(
|
|
303
|
+
const tmuxSession = host.tmuxRuntimeManager.ensureProjectSession(projectRoot);
|
|
303
304
|
const retainedTarget = service.tmuxTarget && host.tmuxRuntimeManager.hasWindow?.(service.tmuxTarget) ? service.tmuxTarget : undefined;
|
|
304
305
|
const target = retainedTarget ??
|
|
305
306
|
host.tmuxRuntimeManager.createWindow(tmuxSession.sessionName, label, resumeCwd, command, args, {
|
|
@@ -356,4 +357,3 @@ export function resumeOfflineServiceById(host, serviceId) {
|
|
|
356
357
|
const restored = buildServiceStateFromMetadata(serviceId, existing.metadata);
|
|
357
358
|
return resumeOfflineService(host, restored);
|
|
358
359
|
}
|
|
359
|
-
//# sourceMappingURL=services.js.map
|
|
@@ -10,7 +10,7 @@ export declare function runDashboard(host: SessionLaunchHost): Promise<number>;
|
|
|
10
10
|
export declare function runProjectService(host: SessionLaunchHost): Promise<number>;
|
|
11
11
|
export declare function resumeSessions(host: SessionLaunchHost, toolFilter?: string): Promise<number>;
|
|
12
12
|
export declare function restoreSessions(host: SessionLaunchHost, toolFilter?: string): Promise<number>;
|
|
13
|
-
export declare function createSession(host: SessionLaunchHost, command: string, args: string[], preambleFlag?: string[], toolConfigKey?: string, extraPreamble?: string, sessionIdFlag?: string[], worktreePath?: string, backendSessionIdOverride?: string, sessionIdOverride?: string, detachedInTmux?: boolean, suppressStartupPreamble?: boolean, team?: SessionTeamMetadata): any;
|
|
13
|
+
export declare function createSession(host: SessionLaunchHost, command: string, args: string[], preambleFlag?: string[], toolConfigKey?: string, extraPreamble?: string, sessionIdFlag?: string[], worktreePath?: string, backendSessionIdOverride?: string, sessionIdOverride?: string, detachedInTmux?: boolean, suppressStartupPreamble?: boolean, team?: SessionTeamMetadata, launchEnv?: Record<string, string>): any;
|
|
14
14
|
export declare function migrateAgent(host: SessionLaunchHost, sessionId: string, targetWorktreePath: string): Promise<void>;
|
|
15
15
|
export declare function getSessionWorktreePath(host: SessionLaunchHost, sessionId: string): string | undefined;
|
|
16
16
|
export declare function getSessionsByWorktree(host: SessionLaunchHost): Map<string | undefined, any[]>;
|
|
@@ -306,7 +306,7 @@ export async function restoreSessions(host, toolFilter) {
|
|
|
306
306
|
host.openTmuxDashboardTarget();
|
|
307
307
|
return 0;
|
|
308
308
|
}
|
|
309
|
-
export function createSession(host, command, args, preambleFlag, toolConfigKey, extraPreamble, sessionIdFlag, worktreePath, backendSessionIdOverride, sessionIdOverride, detachedInTmux = false, suppressStartupPreamble = false, team) {
|
|
309
|
+
export function createSession(host, command, args, preambleFlag, toolConfigKey, extraPreamble, sessionIdFlag, worktreePath, backendSessionIdOverride, sessionIdOverride, detachedInTmux = false, suppressStartupPreamble = false, team, launchEnv) {
|
|
310
310
|
const cols = process.stdout.columns ?? 80;
|
|
311
311
|
const sessionId = sessionIdOverride ?? `${command}-${Math.random().toString(36).slice(2, 8)}`;
|
|
312
312
|
if (host.sessions.some((session) => session.id === sessionId)) {
|
|
@@ -314,6 +314,8 @@ export function createSession(host, command, args, preambleFlag, toolConfigKey,
|
|
|
314
314
|
}
|
|
315
315
|
const config = loadConfig();
|
|
316
316
|
const toolCfg = toolConfigKey ? config.tools[toolConfigKey] : undefined;
|
|
317
|
+
// A launch override may swap the binary; aimux flags/preamble only apply to the tool's own command.
|
|
318
|
+
const isConfiguredToolCommand = Boolean(toolCfg && toolCfg.command === command);
|
|
317
319
|
const isClaudeResumeStyleLaunch = Boolean(toolCfg && toolConfigKey === "claude" && toolCfg.command === command) &&
|
|
318
320
|
shouldSkipClaudeSessionIdInjection(args);
|
|
319
321
|
const explicitClaudeBackendSessionId = toolCfg && toolConfigKey === "claude" && toolCfg.command === command
|
|
@@ -323,7 +325,7 @@ export function createSession(host, command, args, preambleFlag, toolConfigKey,
|
|
|
323
325
|
? extractCodexBackendSessionIdFromArgs(args)
|
|
324
326
|
: undefined;
|
|
325
327
|
const effectiveSuppressStartupPreamble = suppressStartupPreamble;
|
|
326
|
-
const effectiveSessionIdFlag = isClaudeResumeStyleLaunch ?
|
|
328
|
+
const effectiveSessionIdFlag = isConfiguredToolCommand && !isClaudeResumeStyleLaunch ? sessionIdFlag : undefined;
|
|
327
329
|
const backendSessionId = backendSessionIdOverride ??
|
|
328
330
|
explicitClaudeBackendSessionId ??
|
|
329
331
|
explicitCodexBackendSessionId ??
|
|
@@ -339,7 +341,7 @@ export function createSession(host, command, args, preambleFlag, toolConfigKey,
|
|
|
339
341
|
includeAimuxPreamble: automaticPreambleEnabled,
|
|
340
342
|
team,
|
|
341
343
|
});
|
|
342
|
-
const shouldInjectLaunchPreamble = Boolean(!effectiveSuppressStartupPreamble && preambleFlag && preamble.trim());
|
|
344
|
+
const shouldInjectLaunchPreamble = Boolean(isConfiguredToolCommand && !effectiveSuppressStartupPreamble && preambleFlag && preamble.trim());
|
|
343
345
|
const shouldInjectCodexDeveloperInstructions = Boolean(!effectiveSuppressStartupPreamble &&
|
|
344
346
|
toolCfg?.command === command &&
|
|
345
347
|
command === "codex" &&
|
|
@@ -375,6 +377,7 @@ export function createSession(host, command, args, preambleFlag, toolConfigKey,
|
|
|
375
377
|
command: launchCommand,
|
|
376
378
|
args: finalArgs,
|
|
377
379
|
extraEnv: {
|
|
380
|
+
...(launchEnv ?? {}),
|
|
378
381
|
AIMUX_SESSION_ID: sessionId,
|
|
379
382
|
AIMUX_TOOL: toolConfigKey ?? command,
|
|
380
383
|
},
|
|
@@ -382,13 +385,23 @@ export function createSession(host, command, args, preambleFlag, toolConfigKey,
|
|
|
382
385
|
launchCommand = wrapped.command;
|
|
383
386
|
finalArgs = wrapped.args;
|
|
384
387
|
}
|
|
385
|
-
else if (
|
|
388
|
+
else if (isConfiguredToolCommand) {
|
|
386
389
|
const wrapped = wrapCommandWithShellIntegration({
|
|
387
390
|
projectRoot,
|
|
388
391
|
sessionId,
|
|
389
392
|
tool: toolConfigKey ?? command,
|
|
390
393
|
command: launchCommand,
|
|
391
394
|
args: finalArgs,
|
|
395
|
+
extraEnv: launchEnv,
|
|
396
|
+
});
|
|
397
|
+
launchCommand = wrapped.command;
|
|
398
|
+
finalArgs = wrapped.args;
|
|
399
|
+
}
|
|
400
|
+
else if (launchEnv && Object.keys(launchEnv).length > 0) {
|
|
401
|
+
const wrapped = wrapCommandWithManagedLaunchEnv({
|
|
402
|
+
command: launchCommand,
|
|
403
|
+
args: finalArgs,
|
|
404
|
+
extraEnv: launchEnv,
|
|
392
405
|
});
|
|
393
406
|
launchCommand = wrapped.command;
|
|
394
407
|
finalArgs = wrapped.args;
|
|
@@ -399,7 +412,7 @@ export function createSession(host, command, args, preambleFlag, toolConfigKey,
|
|
|
399
412
|
debug(`creating session: ${command} (configKey=${toolConfigKey ?? "cli"}, backendId=${backendSessionId ?? "none"}, cwd=${worktreePath ?? process.cwd()}, args=${finalArgs.length})`, "session");
|
|
400
413
|
debug(`spawn args: ${JSON.stringify(summarizeLaunchArgs(finalArgs))}`, "session");
|
|
401
414
|
const sessionStartTime = Date.now();
|
|
402
|
-
const tmuxSession = host.tmuxRuntimeManager.ensureProjectSession(
|
|
415
|
+
const tmuxSession = host.tmuxRuntimeManager.ensureProjectSession(projectRoot);
|
|
403
416
|
const target = host.tmuxRuntimeManager.createWindow(tmuxSession.sessionName, host.getSessionLabel(sessionId) ?? command, worktreePath ?? process.cwd(), launchCommand, finalArgs, { detached: detachedInTmux });
|
|
404
417
|
const tmuxTransport = new TmuxSessionTransport(sessionId, command, target, host.tmuxRuntimeManager, cols, process.stdout.rows ?? 24);
|
|
405
418
|
host.sessionTmuxTargets.set(sessionId, target);
|
|
@@ -409,7 +422,6 @@ export function createSession(host, command, args, preambleFlag, toolConfigKey,
|
|
|
409
422
|
if (session instanceof TmuxSessionTransport) {
|
|
410
423
|
host.syncTmuxWindowMetadata(sessionId);
|
|
411
424
|
}
|
|
412
|
-
void projectRoot;
|
|
413
425
|
host.activeIndex = host.sessions.length - 1;
|
|
414
426
|
if (host.startedInDashboard && host.mode === "dashboard") {
|
|
415
427
|
host.invalidateDesktopStateSnapshot();
|
|
@@ -590,4 +602,3 @@ export function handleAction(host, action) {
|
|
|
590
602
|
break;
|
|
591
603
|
}
|
|
592
604
|
}
|
|
593
|
-
//# sourceMappingURL=session-launch.js.map
|
|
@@ -8,6 +8,7 @@ import { SessionRuntime } from "../session-runtime.js";
|
|
|
8
8
|
import { TmuxSessionTransport } from "../tmux/session-transport.js";
|
|
9
9
|
import { loadMetadataState } from "../metadata-store.js";
|
|
10
10
|
import { parseAgentOutput } from "../agent-output-parser.js";
|
|
11
|
+
import { normalizeSubmittedPrompt, waitForTmuxPromptSubmit } from "../agent-prompt-delivery.js";
|
|
11
12
|
import { captureGitContext } from "../context/context-bridge.js";
|
|
12
13
|
export function getSessionLabel(host, sessionId) {
|
|
13
14
|
return (host.sessionLabels.get(sessionId) ?? host.offlineSessions.find((session) => session.id === sessionId)?.label);
|
|
@@ -166,8 +167,14 @@ export async function sendAgentInput(host, sessionId, text) {
|
|
|
166
167
|
if (!target)
|
|
167
168
|
throw new Error(`Session "${sessionId}" does not have a live tmux target`);
|
|
168
169
|
session.transport.retarget(target);
|
|
169
|
-
|
|
170
|
-
session.transport.write(
|
|
170
|
+
const prompt = normalizeSubmittedPrompt(host.sessionToolKeys.get(sessionId), text, true);
|
|
171
|
+
session.transport.write(prompt);
|
|
172
|
+
await waitForTmuxPromptSubmit({
|
|
173
|
+
tmuxRuntimeManager: host.tmuxRuntimeManager,
|
|
174
|
+
target,
|
|
175
|
+
draft: prompt,
|
|
176
|
+
isTargetCurrent: () => resolveLiveSessionTmuxTarget(host, sessionId, target)?.windowId === target.windowId,
|
|
177
|
+
});
|
|
171
178
|
}
|
|
172
179
|
else {
|
|
173
180
|
session.write(text);
|
|
@@ -384,4 +391,3 @@ export function updateContextWatcherSessions(host) {
|
|
|
384
391
|
};
|
|
385
392
|
}));
|
|
386
393
|
}
|
|
387
|
-
//# sourceMappingURL=session-runtime-core.js.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type ToolConfig } from "../config.js";
|
|
2
|
+
import { type LaunchOverride } from "../shell-args.js";
|
|
2
3
|
type ToolPickerHost = any;
|
|
3
4
|
export declare function buildToolPickerOverlayOutput(host: ToolPickerHost): string;
|
|
4
5
|
export declare function buildToolOptionsOverlayOutput(host: ToolPickerHost): string;
|
|
5
6
|
export declare function renderToolPicker(host: ToolPickerHost): void;
|
|
6
7
|
export declare function runSelectedTool(host: ToolPickerHost, toolKey: string, tool: ToolConfig, opts?: {
|
|
7
|
-
|
|
8
|
+
override?: LaunchOverride;
|
|
8
9
|
}): void;
|
|
9
10
|
export declare function showToolPicker(host: ToolPickerHost, sourceSessionId?: string): void;
|
|
10
11
|
export declare function handleToolPickerKey(host: ToolPickerHost, data: Buffer): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig } from "../config.js";
|
|
2
2
|
import { parseKeys } from "../key-parser.js";
|
|
3
|
-
import {
|
|
3
|
+
import { parseLaunchCommandLine } from "../shell-args.js";
|
|
4
4
|
import { forkDashboardAgentWithFeedback, spawnDashboardAgentWithFeedback } from "./dashboard-ops.js";
|
|
5
5
|
function enabledTools() {
|
|
6
6
|
const config = loadConfig();
|
|
@@ -67,28 +67,37 @@ export function buildToolOptionsOverlayOutput(host) {
|
|
|
67
67
|
}
|
|
68
68
|
const [toolKey, tool] = selected;
|
|
69
69
|
const buffer = host.toolOptionsBuffer ?? "";
|
|
70
|
-
let
|
|
70
|
+
let override;
|
|
71
71
|
let parseError = host.toolOptionsError;
|
|
72
72
|
if (!parseError) {
|
|
73
73
|
try {
|
|
74
|
-
|
|
74
|
+
override = parseLaunchCommandLine(buffer);
|
|
75
75
|
}
|
|
76
76
|
catch (error) {
|
|
77
77
|
parseError = error instanceof Error ? error.message : String(error);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
const defaultArgs = tool.args.length ? tool.args.map(quoteShellArg).join(" ") : "(none)";
|
|
81
|
-
const preview = commandPreview(tool.command, [...tool.args, ...parsedExtraArgs]);
|
|
82
80
|
const lines = [
|
|
83
81
|
host.pickerMode === "fork" && host.forkSourceSessionId
|
|
84
|
-
? `Fork ${toolKey}: launch
|
|
85
|
-
: `${toolKey}: launch
|
|
82
|
+
? `Fork ${toolKey}: launch command`
|
|
83
|
+
: `${toolKey}: launch command`,
|
|
86
84
|
"",
|
|
87
|
-
`
|
|
88
|
-
` Extra args: ${buffer}_`,
|
|
89
|
-
"",
|
|
90
|
-
` Command: ${preview}`,
|
|
85
|
+
` ${buffer}_`,
|
|
91
86
|
];
|
|
87
|
+
if (override) {
|
|
88
|
+
lines.push("");
|
|
89
|
+
if (override.env) {
|
|
90
|
+
const envStr = Object.entries(override.env)
|
|
91
|
+
.map(([key, value]) => `${key}=${quoteShellArg(value)}`)
|
|
92
|
+
.join(" ");
|
|
93
|
+
lines.push(` Env: ${envStr}`);
|
|
94
|
+
}
|
|
95
|
+
lines.push(` Launch: ${commandPreview(override.command, override.args)}`);
|
|
96
|
+
lines.push("");
|
|
97
|
+
lines.push(override.command === tool.command
|
|
98
|
+
? " aimux hooks + session tracking applied"
|
|
99
|
+
: " custom binary — launched without aimux hooks");
|
|
100
|
+
}
|
|
92
101
|
if (parseError) {
|
|
93
102
|
lines.push("");
|
|
94
103
|
lines.push(` Error: ${parseError}`);
|
|
@@ -106,8 +115,7 @@ export function renderToolPicker(host) {
|
|
|
106
115
|
}
|
|
107
116
|
export function runSelectedTool(host, toolKey, tool, opts = {}) {
|
|
108
117
|
const wtPath = host.mode === "dashboard" ? host.dashboardState.focusedWorktreePath : undefined;
|
|
109
|
-
const
|
|
110
|
-
const launchArgs = [...tool.args, ...extraArgs];
|
|
118
|
+
const override = opts.override;
|
|
111
119
|
if (host.pickerMode === "fork") {
|
|
112
120
|
const sourceSessionId = host.forkSourceSessionId;
|
|
113
121
|
host.pickerMode = "create";
|
|
@@ -127,7 +135,7 @@ export function runSelectedTool(host, toolKey, tool, opts = {}) {
|
|
|
127
135
|
targetSessionId,
|
|
128
136
|
tool: toolKey,
|
|
129
137
|
worktreePath: wtPath,
|
|
130
|
-
|
|
138
|
+
launchOverride: override,
|
|
131
139
|
});
|
|
132
140
|
return;
|
|
133
141
|
}
|
|
@@ -137,7 +145,7 @@ export function runSelectedTool(host, toolKey, tool, opts = {}) {
|
|
|
137
145
|
targetSessionId,
|
|
138
146
|
targetWorktreePath: wtPath,
|
|
139
147
|
open: false,
|
|
140
|
-
|
|
148
|
+
launchOverride: override,
|
|
141
149
|
});
|
|
142
150
|
return;
|
|
143
151
|
}
|
|
@@ -153,11 +161,11 @@ export function runSelectedTool(host, toolKey, tool, opts = {}) {
|
|
|
153
161
|
sessionId,
|
|
154
162
|
tool: toolKey,
|
|
155
163
|
worktreePath: wtPath,
|
|
156
|
-
|
|
164
|
+
launchOverride: override,
|
|
157
165
|
});
|
|
158
166
|
return;
|
|
159
167
|
}
|
|
160
|
-
host.createSession(tool.command,
|
|
168
|
+
host.createSession(override?.command ?? tool.command, override?.args ?? tool.args, tool.preambleFlag, toolKey, undefined, tool.sessionIdFlag, wtPath, undefined, sessionId, false, false, undefined, override?.env);
|
|
161
169
|
}
|
|
162
170
|
export function showToolPicker(host, sourceSessionId) {
|
|
163
171
|
host.pickerMode = sourceSessionId ? "fork" : "create";
|
|
@@ -204,7 +212,7 @@ export function handleToolPickerKey(host, data) {
|
|
|
204
212
|
return;
|
|
205
213
|
}
|
|
206
214
|
host.toolOptionsToolKey = picked[0];
|
|
207
|
-
host.toolOptionsBuffer =
|
|
215
|
+
host.toolOptionsBuffer = commandPreview(picked[1].command, picked[1].args);
|
|
208
216
|
host.toolOptionsError = null;
|
|
209
217
|
host.openDashboardOverlay("tool-options");
|
|
210
218
|
if (typeof host.redrawDashboardWithOverlay === "function") {
|
|
@@ -271,9 +279,9 @@ export function handleToolOptionsKey(host, data) {
|
|
|
271
279
|
return;
|
|
272
280
|
}
|
|
273
281
|
const [toolKey, tool] = selected;
|
|
274
|
-
let
|
|
282
|
+
let override;
|
|
275
283
|
try {
|
|
276
|
-
|
|
284
|
+
override = parseLaunchCommandLine(host.toolOptionsBuffer ?? "");
|
|
277
285
|
}
|
|
278
286
|
catch (error) {
|
|
279
287
|
host.toolOptionsError = error instanceof Error ? error.message : String(error);
|
|
@@ -286,7 +294,7 @@ export function handleToolOptionsKey(host, data) {
|
|
|
286
294
|
return;
|
|
287
295
|
}
|
|
288
296
|
host.clearDashboardOverlay();
|
|
289
|
-
runSelectedTool(host, toolKey, tool, {
|
|
297
|
+
runSelectedTool(host, toolKey, tool, { override });
|
|
290
298
|
return;
|
|
291
299
|
}
|
|
292
300
|
if (event.name === "paste" || event.char) {
|
|
@@ -300,4 +308,3 @@ export function handleToolOptionsKey(host, data) {
|
|
|
300
308
|
}
|
|
301
309
|
}
|
|
302
310
|
}
|
|
303
|
-
//# sourceMappingURL=tool-picker.js.map
|
package/dist/notifications.js
CHANGED
package/dist/notify.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare function notifyPrompt(sessionId: string): void;
|
|
|
7
7
|
export declare function notifyError(sessionId: string, message?: string): void;
|
|
8
8
|
/** Notify that an agent completed (exited cleanly) */
|
|
9
9
|
export declare function notifyComplete(sessionId: string): void;
|
|
10
|
-
export declare function notifyAlert(event: AlertEvent):
|
|
10
|
+
export declare function notifyAlert(event: AlertEvent): boolean;
|
|
11
11
|
export declare function notifyRemoteClientConnected(input: {
|
|
12
12
|
title?: unknown;
|
|
13
13
|
body?: unknown;
|
package/dist/notify.js
CHANGED
|
@@ -3,6 +3,7 @@ import { execFile } from "node:child_process";
|
|
|
3
3
|
import { loadConfig } from "./config.js";
|
|
4
4
|
import { debug } from "./debug.js";
|
|
5
5
|
import { shouldSuppressNotification } from "./notification-context.js";
|
|
6
|
+
import { forwardAlertToMobilePush } from "./mobile-push-bridge.js";
|
|
6
7
|
let cachedConfig = null;
|
|
7
8
|
function getNotifyConfig() {
|
|
8
9
|
if (!cachedConfig) {
|
|
@@ -68,9 +69,9 @@ export function notifyComplete(sessionId) {
|
|
|
68
69
|
export function notifyAlert(event) {
|
|
69
70
|
const config = getNotifyConfig();
|
|
70
71
|
if (!config.enabled)
|
|
71
|
-
return;
|
|
72
|
+
return false;
|
|
72
73
|
if (shouldSuppressNotification(event))
|
|
73
|
-
return;
|
|
74
|
+
return false;
|
|
74
75
|
if ((event.kind === "notification" ||
|
|
75
76
|
event.kind === "needs_input" ||
|
|
76
77
|
event.kind === "message_waiting" ||
|
|
@@ -78,17 +79,18 @@ export function notifyAlert(event) {
|
|
|
78
79
|
event.kind === "task_assigned" ||
|
|
79
80
|
event.kind === "review_waiting") &&
|
|
80
81
|
!config.onPrompt) {
|
|
81
|
-
return;
|
|
82
|
+
return false;
|
|
82
83
|
}
|
|
83
84
|
if (event.kind === "task_done" && !config.onComplete)
|
|
84
|
-
return;
|
|
85
|
+
return false;
|
|
85
86
|
if ((event.kind === "task_failed" || event.kind === "blocked") && !config.onError)
|
|
86
|
-
return;
|
|
87
|
+
return false;
|
|
87
88
|
send(event.title || "aimux", event.message || event.sessionId || event.kind);
|
|
89
|
+
forwardAlertToMobilePush(event);
|
|
90
|
+
return true;
|
|
88
91
|
}
|
|
89
92
|
export function notifyRemoteClientConnected(input) {
|
|
90
93
|
const title = typeof input.title === "string" && input.title.trim().length > 0 ? input.title : "aimux remote access";
|
|
91
94
|
const body = typeof input.body === "string" && input.body.trim().length > 0 ? input.body : "Remote client connected";
|
|
92
95
|
sendSecurity(title, body);
|
|
93
96
|
}
|
|
94
|
-
//# sourceMappingURL=notify.js.map
|
package/dist/orchestration.js
CHANGED
package/dist/paths.js
CHANGED
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { createHash } from "node:crypto";
|
|
14
14
|
import { execSync } from "node:child_process";
|
|
15
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
15
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, realpathSync } from "node:fs";
|
|
16
16
|
import { join, basename, resolve, dirname, sep } from "node:path";
|
|
17
|
-
import { homedir } from "node:os";
|
|
17
|
+
import { homedir, tmpdir } from "node:os";
|
|
18
|
+
import { quarantineCorruptFile, writeJsonAtomic } from "./atomic-write.js";
|
|
18
19
|
// ── Cached state (populated by initPaths) ──────────────────────────
|
|
19
20
|
let _repoRoot = null;
|
|
20
21
|
let _projectId = null;
|
|
@@ -264,25 +265,69 @@ export function getGlobalTeamPath() {
|
|
|
264
265
|
export function getProjectsRegistryPath() {
|
|
265
266
|
return join(getGlobalAimuxDir(), "projects.json");
|
|
266
267
|
}
|
|
268
|
+
const MAX_PROJECT_REGISTRY_ENTRIES = 500;
|
|
269
|
+
const OS_TMP_DIR = tmpdir();
|
|
270
|
+
const TEMP_DIR_CANDIDATES = [OS_TMP_DIR, "/tmp", "/private/tmp", "/var/tmp"];
|
|
271
|
+
const TEMP_DIRS = (() => {
|
|
272
|
+
const dirs = new Set();
|
|
273
|
+
for (const dir of TEMP_DIR_CANDIDATES) {
|
|
274
|
+
const resolved = resolve(dir);
|
|
275
|
+
dirs.add(resolved);
|
|
276
|
+
try {
|
|
277
|
+
dirs.add(realpathSync(resolved));
|
|
278
|
+
}
|
|
279
|
+
catch { }
|
|
280
|
+
}
|
|
281
|
+
return [...dirs];
|
|
282
|
+
})();
|
|
283
|
+
function isPathInsideDir(path, dir) {
|
|
284
|
+
return path === dir || path.startsWith(`${dir}${sep}`);
|
|
285
|
+
}
|
|
286
|
+
function isEphemeralTempProjectRoot(repoRoot) {
|
|
287
|
+
const resolved = resolve(repoRoot);
|
|
288
|
+
return basename(resolved).startsWith("aimux-") && TEMP_DIRS.some((dir) => isPathInsideDir(resolved, dir));
|
|
289
|
+
}
|
|
290
|
+
function assertRegistryWithinCap(projects) {
|
|
291
|
+
if (projects.length <= MAX_PROJECT_REGISTRY_ENTRIES)
|
|
292
|
+
return;
|
|
293
|
+
throw new Error(`aimux project registry has ${projects.length} entries; cap is ${MAX_PROJECT_REGISTRY_ENTRIES}. ` +
|
|
294
|
+
`Refusing to continue because the registry is likely polluted. Remove stale entries from ${getProjectsRegistryPath()}.`);
|
|
295
|
+
}
|
|
296
|
+
function normalizeRegistry(registry) {
|
|
297
|
+
const projectsById = new Map();
|
|
298
|
+
for (const project of registry.projects) {
|
|
299
|
+
if (isEphemeralTempProjectRoot(project.repoRoot))
|
|
300
|
+
continue;
|
|
301
|
+
projectsById.set(project.id, project);
|
|
302
|
+
}
|
|
303
|
+
const projects = [...projectsById.values()];
|
|
304
|
+
assertRegistryWithinCap(projects);
|
|
305
|
+
return { version: 1, projects };
|
|
306
|
+
}
|
|
267
307
|
function loadRegistry() {
|
|
268
308
|
const path = getProjectsRegistryPath();
|
|
269
309
|
if (!existsSync(path))
|
|
270
310
|
return { version: 1, projects: [] };
|
|
311
|
+
let registry;
|
|
271
312
|
try {
|
|
272
|
-
|
|
313
|
+
registry = JSON.parse(readFileSync(path, "utf-8"));
|
|
273
314
|
}
|
|
274
315
|
catch {
|
|
316
|
+
quarantineCorruptFile(path);
|
|
275
317
|
return { version: 1, projects: [] };
|
|
276
318
|
}
|
|
319
|
+
return normalizeRegistry(registry);
|
|
277
320
|
}
|
|
278
321
|
function saveRegistry(registry) {
|
|
279
322
|
const dir = getGlobalAimuxDir();
|
|
280
323
|
if (!existsSync(dir))
|
|
281
324
|
mkdirSync(dir, { recursive: true });
|
|
282
|
-
|
|
325
|
+
writeJsonAtomic(getProjectsRegistryPath(), registry);
|
|
283
326
|
}
|
|
284
327
|
function registerProject() {
|
|
285
328
|
assertInitialized();
|
|
329
|
+
if (isEphemeralTempProjectRoot(_repoRoot))
|
|
330
|
+
return;
|
|
286
331
|
const registry = loadRegistry();
|
|
287
332
|
const idx = registry.projects.findIndex((p) => p.id === _projectId);
|
|
288
333
|
const entry = {
|
|
@@ -297,6 +342,7 @@ function registerProject() {
|
|
|
297
342
|
else {
|
|
298
343
|
registry.projects.push(entry);
|
|
299
344
|
}
|
|
345
|
+
assertRegistryWithinCap(registry.projects);
|
|
300
346
|
saveRegistry(registry);
|
|
301
347
|
}
|
|
302
348
|
export function listProjects() {
|
|
@@ -307,4 +353,3 @@ export function removeProject(id) {
|
|
|
307
353
|
registry.projects = registry.projects.filter((p) => p.id !== id);
|
|
308
354
|
saveRegistry(registry);
|
|
309
355
|
}
|
|
310
|
-
//# sourceMappingURL=paths.js.map
|
package/dist/pending-actions.js
CHANGED
package/dist/plugin-runtime.js
CHANGED
package/dist/project-events.js
CHANGED
package/dist/project-scanner.js
CHANGED
|
@@ -51,4 +51,3 @@ export function manifestsMatch(expected, actual) {
|
|
|
51
51
|
const actualCapabilities = actual.capabilities || {};
|
|
52
52
|
return Object.entries(expected.capabilities).every(([key, value]) => actualCapabilities[key] === value);
|
|
53
53
|
}
|
|
54
|
-
//# sourceMappingURL=project-service-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function takeOverProjectFromOtherOwners(projectRoot: string): Promise<void>;
|