seatmesh 1.2.4 → 1.3.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/bin/seatmesh +6 -1
- package/dist/commands/agent-forum.d.ts +6 -0
- package/dist/commands/agent-forum.d.ts.map +1 -0
- package/dist/commands/agent-forum.js +26 -0
- package/dist/commands/agent-forum.js.map +1 -0
- package/dist/commands/campaign-cli.d.ts +10 -0
- package/dist/commands/campaign-cli.d.ts.map +1 -0
- package/dist/commands/campaign-cli.js +136 -0
- package/dist/commands/campaign-cli.js.map +1 -0
- package/dist/commands/chat-cli.d.ts.map +1 -1
- package/dist/commands/chat-cli.js +55 -0
- package/dist/commands/chat-cli.js.map +1 -1
- package/dist/commands/cli-speed.test.d.ts +2 -0
- package/dist/commands/cli-speed.test.d.ts.map +1 -0
- package/dist/commands/cli-speed.test.js +39 -0
- package/dist/commands/cli-speed.test.js.map +1 -0
- package/dist/commands/cli-vocal.test.d.ts +2 -0
- package/dist/commands/cli-vocal.test.d.ts.map +1 -0
- package/dist/commands/cli-vocal.test.js +58 -0
- package/dist/commands/cli-vocal.test.js.map +1 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +55 -14
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/completion.test.js +37 -2
- package/dist/commands/completion.test.js.map +1 -1
- package/dist/commands/contract-lock-cli.d.ts.map +1 -1
- package/dist/commands/contract-lock-cli.js +150 -29
- package/dist/commands/contract-lock-cli.js.map +1 -1
- package/dist/commands/help-text.d.ts.map +1 -1
- package/dist/commands/help-text.js +90 -26
- package/dist/commands/help-text.js.map +1 -1
- package/dist/commands/host-cli.d.ts +5 -0
- package/dist/commands/host-cli.d.ts.map +1 -0
- package/dist/commands/host-cli.js +120 -0
- package/dist/commands/host-cli.js.map +1 -0
- package/dist/commands/nav-cli.d.ts +8 -0
- package/dist/commands/nav-cli.d.ts.map +1 -0
- package/dist/commands/nav-cli.js +54 -0
- package/dist/commands/nav-cli.js.map +1 -0
- package/dist/commands/notify-cli.d.ts.map +1 -1
- package/dist/commands/notify-cli.js +38 -3
- package/dist/commands/notify-cli.js.map +1 -1
- package/dist/commands/room-cli.d.ts.map +1 -1
- package/dist/commands/room-cli.js +23 -6
- package/dist/commands/room-cli.js.map +1 -1
- package/dist/commands/schedule-cli.d.ts +13 -0
- package/dist/commands/schedule-cli.d.ts.map +1 -0
- package/dist/commands/schedule-cli.js +74 -0
- package/dist/commands/schedule-cli.js.map +1 -0
- package/dist/commands/schedule-cli.test.d.ts +2 -0
- package/dist/commands/schedule-cli.test.d.ts.map +1 -0
- package/dist/commands/schedule-cli.test.js +29 -0
- package/dist/commands/schedule-cli.test.js.map +1 -0
- package/dist/commands/todo-give.test.js +21 -5
- package/dist/commands/todo-give.test.js.map +1 -1
- package/dist/fast-spawn.d.ts +3 -0
- package/dist/fast-spawn.d.ts.map +1 -0
- package/dist/fast-spawn.js +107 -0
- package/dist/fast-spawn.js.map +1 -0
- package/dist/main.js +323 -44
- package/dist/main.js.map +1 -1
- package/dist/setup/init.d.ts +11 -0
- package/dist/setup/init.d.ts.map +1 -1
- package/dist/setup/init.js +38 -0
- package/dist/setup/init.js.map +1 -1
- package/dist/setup/init.test.js +3 -2
- package/dist/setup/init.test.js.map +1 -1
- package/dist/setup/install.js +2 -2
- package/dist/setup/install.js.map +1 -1
- package/package.json +8 -7
- package/profiles/minimal/mesh.config.yaml +1 -0
- package/templates/cursor/rules/seatmesh-agent.mdc +40 -0
- package/templates/docs/RELEASE.md +9 -3
- package/templates/docs/cli/README.md +110 -11
- package/templates/docs/cli/chat.md +4 -3
- package/templates/docs/cli/contract.md +15 -15
- package/templates/docs/cli/host.md +12 -0
- package/templates/docs/cli/human.md +15 -7
- package/templates/docs/cli/kind.md +4 -2
- package/templates/docs/cli/nav.md +12 -0
- package/templates/docs/cli/{oc-proxy.md → opencode-cpe.md} +10 -10
- package/templates/docs/cli/rebuild.md +3 -0
- package/templates/docs/cli/reload.md +8 -5
- package/templates/docs/cli/room.md +5 -7
- package/templates/docs/cli/schedule.md +13 -0
- package/templates/docs/cli/secretary.md +1 -1
- package/templates/docs/cli/spawn.md +13 -0
- package/templates/docs/cli/switch.md +4 -4
- package/templates/init/AGENTS.md +10 -10
- package/templates/init/mesh.config.yaml +11 -4
package/dist/main.js
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
3
|
import { findDotSmConfig } from "@seat-mesh/core";
|
|
4
|
-
import { loadProfile, profilePaths, loadRoleIndex, renderRoleIndex, validateRoleIndex, runStackPassthrough, roleAllows, isCoordKind, isManagerKind, managerColumnIds, addBaseColumn, removeBaseColumn, listBaseColumns, chatRoomConfigForLoaded, clearAckEndedSync, resolveAckRedirectDefaults, } from "@seat-mesh/core";
|
|
4
|
+
import { loadProfile, profilePaths, loadRoleIndex, renderRoleIndex, validateRoleIndex, runStackPassthrough, roleAllows, isCoordKind, isManagerKind, managerColumnIds, addBaseColumn, removeBaseColumn, listBaseColumns, chatRoomConfigForLoaded, clearAckEndedSync, resolveAckRedirectDefaults, expandTargetSpec, targetRangeOptsFromProfile, } from "@seat-mesh/core";
|
|
5
5
|
import { snapshotConnectivity, formatStatus } from "@seat-mesh/connectivity";
|
|
6
|
-
import { createRegistryForProfile } from "@seat-mesh/providers";
|
|
7
|
-
import { printWhoami, whoamiJson, whoamiJsonWithValidate, validateWhoamiRoleIndex, printAgentCard, printAgentContext, printAgentContextAllRoles, runWhoami, roleKindFromWhoami, requireCoordRole, requireInboxLifecycleRole, assertAgentDispatch, printAgentUnauthorized, stripAgentFromArgv, AGENT_META, capturePaneSnapshot, listSessionPanes, sessionAttach, sessionUp, sessionDown, sessionStatus, sessionSync, tmuxHasSession, relayoutMeshSession, realignAllLayouts, reloadMesh, ensureMeshInbox, startMeshInbox, stopMeshInbox, restartMeshInbox, meshInboxEverConfigured, meshInboxPort, printMeshInboxStatus, waitForMeshInbox, printInboxMeta, tailInboxLog, listInboxInstances, parseInboxStatusFlags, inboxStatusArgv, listInbox, resolveInbox, secretaryLaunch, secretaryDispatch, secretaryCollect, secretaryMeshWatch, secretarySupervise, secretaryStatus, printMiniList, miniSpawn, miniPrompt, miniDone, miniSpawnAll, runMeshSmoke, printSmokeResults, launchSession, printLaunchResults, defaultHarnessTypeForSeat, enqueuePrompt, injectPromptDirect, printPeerVerify, runPeerVerify, runRemind, printRemindResults, runNight, runContinue, printContinueResults, runSlotAdvice, verifyMeshSession, printVerify, labelMeshSession, liveMeshSession, ensureBaseLayout, realignBaseLayout, applyMeshSessionBorders, runFlush, printFlushResults, runSwitch, runPaneResume, runSeatSwap, runSet, runTag, setPaneTitle, setPaneStatus, printSeatContexts, runAgentHub, runPeek, runPaneKind, runPaneMeta, runPpa, runToSlot, runToMini, runPeer, parseRemotePeerTarget, runRemotePeer, applyMeshState, saveMeshSession, saveMeshSessionDetailed, assertSaveAllowed, formatSaveSummary, submitPaneOp, clearPaneOpsQueue, printPaneOpsList, printRelayoutPlan, assertRelayoutSafe, buildFullColdStartBrief, enqueueColdStart, runSeatInit, applyAgentContractBundle, balanceLeadCommand, } from "@seat-mesh/tmux";
|
|
8
|
-
import { parseAgentApplyArgs } from "@seat-mesh/core";
|
|
9
|
-
import { buildChatCommands } from "./commands/chat-cli.js";
|
|
6
|
+
import { createRegistryForProfile, loadDropInProviders } from "@seat-mesh/providers";
|
|
7
|
+
import { printWhoami, whoamiJson, whoamiJsonWithValidate, validateWhoamiRoleIndex, printAgentCard, printAgentContext, printAgentContextAllRoles, runWhoami, roleKindFromWhoami, requireCoordRole, requireInboxLifecycleRole, assertAgentDispatch, printAgentUnauthorized, stripAgentFromArgv, AGENT_META, capturePaneSnapshot, listSessionPanes, sessionAttach, sessionUp, sessionDown, sessionStatus, sessionSync, tmuxHasSession, relayoutMeshSession, realignAllLayouts, scaleLayout, layoutReload, reloadMesh, ensureMeshInbox, startMeshInbox, stopMeshInbox, restartMeshInbox, meshInboxEverConfigured, meshInboxPort, printMeshInboxStatus, waitForMeshInbox, printInboxMeta, tailInboxLog, listInboxInstances, parseInboxStatusFlags, inboxStatusArgv, listInbox, resolveInbox, secretaryLaunch, secretaryDispatch, secretaryCollect, secretaryMeshWatch, secretarySupervise, secretaryStatus, printMiniList, miniSpawn, miniPrompt, miniDone, miniSpawnAll, runMeshSmoke, printSmokeResults, launchSession, printLaunchResults, defaultHarnessTypeForSeat, enqueuePrompt, injectPromptDirect, printPeerVerify, runPeerVerify, runRemind, printRemindResults, runNight, runContinue, printContinueResults, runSlotAdvice, verifyMeshSession, printVerify, labelMeshSession, liveMeshSession, ensureBaseLayout, realignBaseLayout, applyMeshSessionBorders, runFlush, printFlushResults, runSwitch, runSwitchFast, runPaneResume, runSeatSwap, runSet, runTag, setPaneTitle, setPaneStatus, printSeatContexts, runAgentHub, runPeek, runPaneKind, runPaneMeta, runPaneCapture, runPpa, runToSlot, runToMini, runPeer, parseRemotePeerTarget, runRemotePeer, applyMeshState, saveMeshSession, saveMeshSessionDetailed, assertSaveAllowed, formatSaveSummary, submitPaneOp, clearPaneOpsQueue, printPaneOpsList, printRelayoutPlan, assertRelayoutSafe, buildFullColdStartBrief, enqueueColdStart, runSeatInit, applyAgentContractBundle, balanceLeadCommand, kindsForLoaded, } from "@seat-mesh/tmux";
|
|
8
|
+
import { parseAgentApplyArgs, lookupResolvedKind } from "@seat-mesh/core";
|
|
10
9
|
import { buildCheckbackCommands } from "./commands/checkback-cli.js";
|
|
11
10
|
import { buildTargetCommands } from "./commands/target-cli.js";
|
|
12
11
|
import { buildAckCommands } from "./commands/ack-cli.js";
|
|
13
12
|
import { resolvePeerEndedAckId, shouldAutoAckReply, } from "./commands/ack-reply.js";
|
|
14
13
|
import { buildLimitCommands } from "./commands/limit-cli.js";
|
|
15
14
|
import { buildRolesCommands } from "./commands/roles-cli.js";
|
|
16
|
-
import { buildNotifyCommand } from "./commands/notify-cli.js";
|
|
17
|
-
import { buildPreviewCommand } from "./commands/preview-cli.js";
|
|
18
|
-
import { runMdsCommand } from "./commands/mds-cli.js";
|
|
19
|
-
import { buildContractLockCommands } from "./commands/contract-lock-cli.js";
|
|
20
|
-
import { buildRoomCommands } from "./commands/room-cli.js";
|
|
21
15
|
import { runInit } from "./setup/init.js";
|
|
22
16
|
import { runAgentContextInit } from "./setup/agent-context-init.js";
|
|
23
17
|
import { printSessionCheck, printSessionRepair, runSessionCheck, runSessionRepair, } from "./setup/session-health.js";
|
|
@@ -62,8 +56,10 @@ Setup
|
|
|
62
56
|
|
|
63
57
|
Put an agent on a pane
|
|
64
58
|
help human ← cheat sheet (aliases: put-agent | panes)
|
|
65
|
-
|
|
66
|
-
|
|
59
|
+
spawn <target> <opencode|opencode-cpe|claude|agent|kiro> empty → CLI
|
|
60
|
+
switch <target> <…|empty> replace live agent (or → shell)
|
|
61
|
+
kill|empty <target> pane → plain terminal (+ save empty)
|
|
62
|
+
launch <target|all> resume configured CLI
|
|
67
63
|
kind <target>
|
|
68
64
|
|
|
69
65
|
Work / status
|
|
@@ -73,7 +69,9 @@ Work / status
|
|
|
73
69
|
report | verify | test | save|auto | inbox […] | labels
|
|
74
70
|
|
|
75
71
|
Session shape
|
|
76
|
-
reload [--layout]
|
|
72
|
+
rebuild|reload [--layout] npm build + labels (not config→pane)
|
|
73
|
+
layout reload re-grid + resume from mesh-agents.json
|
|
74
|
+
layout […] | realign | ops list|clear
|
|
77
75
|
|
|
78
76
|
Agent panes use the gateway (not listed here by default):
|
|
79
77
|
seatmesh agent … · seatmesh agent help
|
|
@@ -104,16 +102,17 @@ Setup (run once per project, by a human)
|
|
|
104
102
|
config check | config upgrade validate yaml · how to bump CLI (npm i -g)
|
|
105
103
|
web up|down|restart|status|open|url operator hub :3190 (npx seatmesh web up)
|
|
106
104
|
roles status|migrate [--to VER]|steps locked role-pack up/down (1.1.x)
|
|
105
|
+
host up|down|status opt-in single host-supervisor for all registered meshes (Phase 1)
|
|
107
106
|
version [--json] [--check-registry] CLI vs npm latest vs profile .seatmesh-version
|
|
108
107
|
|
|
109
108
|
Put an agent on a pane (human — most common)
|
|
110
109
|
help human ← full cheat sheet (aliases: put-agent | panes)
|
|
111
|
-
switch <target> <opencode|
|
|
110
|
+
switch <target> <opencode|opencode-cpe|claude|agent|kiro> empty shell → agent CLI
|
|
112
111
|
switch <target> empty agent → plain shell
|
|
113
112
|
launch <target|all> resume configured CLI (no type pick)
|
|
114
113
|
pane resume [target] autodetect session id → resume/relaunch
|
|
115
114
|
kind <target> agent vs terminal?
|
|
116
|
-
Examples: switch slot-1 opencode · switch secretary
|
|
115
|
+
Examples: switch slot-1 opencode · switch secretary opencode-cpe · pane resume here
|
|
117
116
|
|
|
118
117
|
Give a seat a todo (human or base agent — contracts optional)
|
|
119
118
|
todo give <target> "…" ← FOCUS+TASK+inject+CB≥20m (preferred)
|
|
@@ -284,6 +283,13 @@ async function main() {
|
|
|
284
283
|
console.log(` bin dir: ${r.binDir} (ensure it is on PATH)`);
|
|
285
284
|
return;
|
|
286
285
|
}
|
|
286
|
+
if (cmd === "host") {
|
|
287
|
+
const { runHostCommand } = await import("./commands/host-cli.js");
|
|
288
|
+
const code = runHostCommand([sub, ...tail].filter((a) => a != null));
|
|
289
|
+
if (code !== 0)
|
|
290
|
+
process.exit(code);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
287
293
|
if (cmd === "update") {
|
|
288
294
|
const { runUpdate } = await import("./setup/update.js");
|
|
289
295
|
const { formatInstallStatusLine, isNpxEphemeralInstall, readInstalledCliVersion, resolveLatestRegistryVersion, semverLess, } = await import("./ui/version-nudge.js");
|
|
@@ -645,13 +651,13 @@ async function main() {
|
|
|
645
651
|
const inboxOk = printMeshInboxStatus(loaded);
|
|
646
652
|
process.exit(layoutOk && inboxOk ? 0 : 1);
|
|
647
653
|
}
|
|
648
|
-
if (cmd === "reload") {
|
|
654
|
+
if (cmd === "reload" || cmd === "rebuild") {
|
|
649
655
|
const loaded = meshLoaded(profileArg);
|
|
650
656
|
const layout = rest.includes("--layout");
|
|
651
657
|
reloadMesh(loaded, { layout });
|
|
652
658
|
console.log(layout
|
|
653
|
-
? `OK:
|
|
654
|
-
: `OK:
|
|
659
|
+
? `OK: rebuild + relayout session ${loaded.sessionName}`
|
|
660
|
+
: `OK: rebuild (npm build + labels) session ${loaded.sessionName} — not config→pane`);
|
|
655
661
|
printMeshInboxStatus(loaded);
|
|
656
662
|
return;
|
|
657
663
|
}
|
|
@@ -668,6 +674,87 @@ async function main() {
|
|
|
668
674
|
}
|
|
669
675
|
return;
|
|
670
676
|
}
|
|
677
|
+
if (cmd === "layout" && sub === "scale") {
|
|
678
|
+
const loaded = meshLoaded(profileArg);
|
|
679
|
+
const kindRaw = (tail[0] ?? "").toLowerCase();
|
|
680
|
+
const kind = kindRaw === "workers" || kindRaw === "worker" || kindRaw === "w"
|
|
681
|
+
? "workers"
|
|
682
|
+
: kindRaw === "minis" || kindRaw === "mini" || kindRaw === "m"
|
|
683
|
+
? "minis"
|
|
684
|
+
: null;
|
|
685
|
+
const action = (tail[1] ?? "").toLowerCase();
|
|
686
|
+
const force = rest.includes("--yes");
|
|
687
|
+
const dryRun = rest.includes("--dry-run");
|
|
688
|
+
if (!kind || !action) {
|
|
689
|
+
console.error("usage: layout scale workers|minis up|down|<N> [--yes] [--dry-run]");
|
|
690
|
+
process.exit(2);
|
|
691
|
+
}
|
|
692
|
+
requireCoordRole(loaded, "layout scale");
|
|
693
|
+
if (action !== "up" && action !== "down") {
|
|
694
|
+
const n = Number(action);
|
|
695
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
696
|
+
console.error("usage: layout scale workers|minis up|down|<N> [--yes] [--dry-run]");
|
|
697
|
+
process.exit(2);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
try {
|
|
701
|
+
const r = action === "up" || action === "down"
|
|
702
|
+
? scaleLayout(loaded, {
|
|
703
|
+
kind,
|
|
704
|
+
dir: action,
|
|
705
|
+
force,
|
|
706
|
+
dryRun,
|
|
707
|
+
})
|
|
708
|
+
: scaleLayout(loaded, {
|
|
709
|
+
kind,
|
|
710
|
+
to: Number(action),
|
|
711
|
+
force,
|
|
712
|
+
dryRun,
|
|
713
|
+
});
|
|
714
|
+
if (r.dryRun) {
|
|
715
|
+
console.log(`dry-run: scale ${r.kind} ${r.from} → ${r.to} (${r.grid})`);
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
718
|
+
if (r.from === r.to) {
|
|
719
|
+
console.log(`OK: scale ${r.kind} already ${r.to} (${r.grid})`);
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
console.log(`OK: scale ${r.kind} ${r.from} → ${r.to} (${r.grid})${r.saved ? ` saved ${r.saved}` : ""}`);
|
|
723
|
+
}
|
|
724
|
+
catch (e) {
|
|
725
|
+
console.error(e.message);
|
|
726
|
+
process.exit(1);
|
|
727
|
+
}
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
if (cmd === "layout" && sub === "reload") {
|
|
731
|
+
const loaded = meshLoaded(profileArg);
|
|
732
|
+
const force = rest.includes("--yes");
|
|
733
|
+
const skipLeads = rest.includes("--no-leads");
|
|
734
|
+
const noResume = rest.includes("--no-resume");
|
|
735
|
+
requireCoordRole(loaded, "layout reload");
|
|
736
|
+
try {
|
|
737
|
+
const r = layoutReload(loaded, {
|
|
738
|
+
force,
|
|
739
|
+
skipMinisLeads: skipLeads,
|
|
740
|
+
noResume,
|
|
741
|
+
});
|
|
742
|
+
const launched = r.repaired.filter((x) => x.status === "launched");
|
|
743
|
+
const failed = r.repaired.filter((x) => x.status === "failed");
|
|
744
|
+
console.log(`OK: layout reload ${loaded.sessionName} repaired=${launched.length}${r.saved ? ` saved ${r.saved}` : ""}`);
|
|
745
|
+
for (const x of launched) {
|
|
746
|
+
console.log(` resume ${x.label} ${x.paneId}`);
|
|
747
|
+
}
|
|
748
|
+
for (const x of failed) {
|
|
749
|
+
console.warn(` fail ${x.label}: ${x.reason ?? x.status}`);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
catch (e) {
|
|
753
|
+
console.error(e.message);
|
|
754
|
+
process.exit(1);
|
|
755
|
+
}
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
671
758
|
if (cmd === "layout" && sub === "column") {
|
|
672
759
|
const loaded = meshLoaded(profileArg);
|
|
673
760
|
const action = tail[0];
|
|
@@ -739,7 +826,7 @@ async function main() {
|
|
|
739
826
|
const leadNote = skipLeads || !m
|
|
740
827
|
? ""
|
|
741
828
|
: ` leads=[${Array.isArray(m.leads) ? m.leads.join(",") : "1,2"}]`;
|
|
742
|
-
console.log(`OK: relayout ${loaded.sessionName} (workers
|
|
829
|
+
console.log(`OK: relayout ${loaded.sessionName} (workers ${loaded.profile.layout?.workers.grid ?? "?"}, minis ${grid}${leadNote})`);
|
|
743
830
|
console.log(`OK: layout saved ${saved}`);
|
|
744
831
|
});
|
|
745
832
|
return;
|
|
@@ -962,15 +1049,52 @@ async function main() {
|
|
|
962
1049
|
printPeerVerify(r);
|
|
963
1050
|
process.exit(r.pass ? 0 : 1);
|
|
964
1051
|
}
|
|
965
|
-
const [
|
|
1052
|
+
const [targetRaw, ...textParts] = args;
|
|
966
1053
|
const rawMsg = textParts.join(" ").trim();
|
|
967
|
-
if (!
|
|
1054
|
+
if (!targetRaw || !rawMsg) {
|
|
968
1055
|
console.error("usage: peer verify [target] | peer [--direct] [--ended|--ack [ack-id]] [--redirect-from <seat>] <target> <msg...>\n" +
|
|
1056
|
+
" target: seat | 1..4 | slot-1..3 | mini-1..2 | 1,3,5 (Ruby-style fanout)\n" +
|
|
969
1057
|
" --ack / --ended [id] close open ask (id optional = auto-match from target)\n" +
|
|
970
1058
|
" ack-class msg (ACK/FYI/PASS) auto-closes matching open ask\n" +
|
|
971
1059
|
" or: agent ack reply <id> [msg] (peer back + close in one shot)");
|
|
972
1060
|
process.exit(2);
|
|
973
1061
|
}
|
|
1062
|
+
const peerTargets = expandTargetSpec(targetRaw, targetRangeOptsFromProfile(loaded.profile));
|
|
1063
|
+
if (peerTargets.length > 1 && endedId) {
|
|
1064
|
+
console.error("WARN: --ack/--ended ignored on range fanout (send-only)");
|
|
1065
|
+
endedId = undefined;
|
|
1066
|
+
}
|
|
1067
|
+
const target = peerTargets[0];
|
|
1068
|
+
if (peerTargets.length > 1) {
|
|
1069
|
+
for (const t of peerTargets) {
|
|
1070
|
+
try {
|
|
1071
|
+
runPeer(loaded, t, rawMsg);
|
|
1072
|
+
}
|
|
1073
|
+
catch (e) {
|
|
1074
|
+
if (e.message !== "__peer_coord__") {
|
|
1075
|
+
console.error(`FAIL peer ${t}: ${e.message}`);
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1078
|
+
requireCoordRole(loaded, "peer");
|
|
1079
|
+
if (direct) {
|
|
1080
|
+
const reg = createRegistryForProfile(loaded.profile);
|
|
1081
|
+
injectPromptDirect(loaded, reg, t, rawMsg, { manager: true, force: true });
|
|
1082
|
+
console.log(`SENT: peer --direct -> ${t}`);
|
|
1083
|
+
}
|
|
1084
|
+
else {
|
|
1085
|
+
const { paneId, targetLabel, token, via } = enqueuePrompt(loaded, t, rawMsg, {
|
|
1086
|
+
manager: true,
|
|
1087
|
+
armCheckback: false,
|
|
1088
|
+
});
|
|
1089
|
+
console.log(via === "queued"
|
|
1090
|
+
? `QUEUED: peer -> ${targetLabel} pane=${paneId} token=${token ?? "-"}`
|
|
1091
|
+
: `SENT: peer -> ${targetLabel} pane=${paneId}`);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
console.log(`ok fanout peer → ${peerTargets.join(",")} (${peerTargets.length})`);
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
974
1098
|
if (shouldAutoAckReply(rawMsg, endedId)) {
|
|
975
1099
|
endedId = "__auto__";
|
|
976
1100
|
}
|
|
@@ -1180,6 +1304,13 @@ async function main() {
|
|
|
1180
1304
|
secretaryLaunch(loaded);
|
|
1181
1305
|
return;
|
|
1182
1306
|
}
|
|
1307
|
+
if (sub === "stop") {
|
|
1308
|
+
const reg = createRegistryForProfile(loaded.profile);
|
|
1309
|
+
runSwitch(loaded, reg, "secretary", "empty", { reason: "stop" });
|
|
1310
|
+
saveMeshSession(loaded, reg);
|
|
1311
|
+
console.log("OK: secretary stopped (pane -> empty shell)");
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1183
1314
|
if (sub === "restart" || sub === "switch") {
|
|
1184
1315
|
const reg = createRegistryForProfile(loaded.profile);
|
|
1185
1316
|
const keepResume = rest.includes("--keep-resume") ||
|
|
@@ -1193,7 +1324,8 @@ async function main() {
|
|
|
1193
1324
|
"claude",
|
|
1194
1325
|
"kiro",
|
|
1195
1326
|
"opencode",
|
|
1196
|
-
"
|
|
1327
|
+
"opencode-cpe",
|
|
1328
|
+
"oc-proxy", // legacy alias → normalizeAgentKind → opencode-cpe
|
|
1197
1329
|
"cursor-agent",
|
|
1198
1330
|
"oc",
|
|
1199
1331
|
"cursor",
|
|
@@ -1301,6 +1433,37 @@ async function main() {
|
|
|
1301
1433
|
}
|
|
1302
1434
|
return;
|
|
1303
1435
|
}
|
|
1436
|
+
if (cmd === "kind" && (sub === "list" || sub === "show")) {
|
|
1437
|
+
const loaded = meshLoaded(profileArg);
|
|
1438
|
+
const kinds = kindsForLoaded(loaded);
|
|
1439
|
+
if (sub === "list") {
|
|
1440
|
+
for (const id of Object.keys(kinds).sort()) {
|
|
1441
|
+
const k = kinds[id];
|
|
1442
|
+
const launch = k.launch === undefined
|
|
1443
|
+
? "default"
|
|
1444
|
+
: k.launch === null
|
|
1445
|
+
? "empty"
|
|
1446
|
+
: "builtin" in k.launch
|
|
1447
|
+
? `builtin:${k.launch.builtin}`
|
|
1448
|
+
: `script:${k.launch.command}`;
|
|
1449
|
+
const aliases = k.aliases?.length ? ` aliases=${k.aliases.join(",")}` : "";
|
|
1450
|
+
console.log(`${id}\tprovider=${k.provider}\tlaunch=${launch}${aliases}`);
|
|
1451
|
+
}
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
const id = tail[0];
|
|
1455
|
+
if (!id) {
|
|
1456
|
+
console.error("usage: kind show <id>");
|
|
1457
|
+
process.exit(2);
|
|
1458
|
+
}
|
|
1459
|
+
const found = lookupResolvedKind(kinds, id);
|
|
1460
|
+
if (!found) {
|
|
1461
|
+
console.error(`kind show: unknown kind "${id}" (see: seatmesh kind list)`);
|
|
1462
|
+
process.exit(1);
|
|
1463
|
+
}
|
|
1464
|
+
console.log(JSON.stringify(found, null, 2));
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1304
1467
|
if (cmd === "kind" || cmd === "what" || cmd === "typeof") {
|
|
1305
1468
|
const loaded = meshLoaded(profileArg);
|
|
1306
1469
|
const reg = createRegistryForProfile(loaded.profile);
|
|
@@ -1327,6 +1490,17 @@ async function main() {
|
|
|
1327
1490
|
}
|
|
1328
1491
|
return;
|
|
1329
1492
|
}
|
|
1493
|
+
if (cmd === "capture") {
|
|
1494
|
+
const loaded = meshLoaded(profileArg);
|
|
1495
|
+
try {
|
|
1496
|
+
runPaneCapture(loaded, [sub, ...tail].filter((a) => Boolean(a)));
|
|
1497
|
+
}
|
|
1498
|
+
catch (e) {
|
|
1499
|
+
console.error(e.message);
|
|
1500
|
+
process.exit(1);
|
|
1501
|
+
}
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1330
1504
|
if (cmd === "pane") {
|
|
1331
1505
|
const loaded = meshLoaded(profileArg);
|
|
1332
1506
|
const reg = createRegistryForProfile(loaded.profile);
|
|
@@ -1338,7 +1512,7 @@ async function main() {
|
|
|
1338
1512
|
Targets: here (default) | secretary | manager | slot-N | mini-N
|
|
1339
1513
|
|
|
1340
1514
|
Live OpenCode: pastes resume [ses_…]
|
|
1341
|
-
Shell / dead OC: relaunches
|
|
1515
|
+
Shell / dead OC: relaunches opencode-cpe|opencode|claude with that session`);
|
|
1342
1516
|
return;
|
|
1343
1517
|
}
|
|
1344
1518
|
if (action === "resume") {
|
|
@@ -1475,12 +1649,16 @@ async function main() {
|
|
|
1475
1649
|
const loaded = meshLoaded(profileArg);
|
|
1476
1650
|
requireCoordRole(loaded, "launch");
|
|
1477
1651
|
const rawArgs = [sub, ...tail].filter((a) => Boolean(a) && a !== "--");
|
|
1478
|
-
const launchNow = rawArgs.includes("--now");
|
|
1479
|
-
const
|
|
1480
|
-
const
|
|
1652
|
+
const launchNow = rawArgs.includes("--now") || rawArgs.includes("--fast");
|
|
1653
|
+
const targetsRaw = rawArgs.filter((a) => a !== "--now" && a !== "--fast");
|
|
1654
|
+
const rangeOpts = targetRangeOptsFromProfile(loaded.profile);
|
|
1655
|
+
const targets = targetsRaw.length
|
|
1656
|
+
? targetsRaw.flatMap((t) => expandTargetSpec(t, rangeOpts))
|
|
1657
|
+
: undefined;
|
|
1658
|
+
const label = targets?.length ? targets.join(",") : "all";
|
|
1481
1659
|
const runLaunch = () => {
|
|
1482
1660
|
const results = launchSession(loaded, {
|
|
1483
|
-
targets
|
|
1661
|
+
targets,
|
|
1484
1662
|
});
|
|
1485
1663
|
printLaunchResults(results);
|
|
1486
1664
|
if (results.some((r) => r.status === "failed"))
|
|
@@ -1490,7 +1668,7 @@ async function main() {
|
|
|
1490
1668
|
runLaunch();
|
|
1491
1669
|
return;
|
|
1492
1670
|
}
|
|
1493
|
-
submitPaneOp(loaded, "launch", { targets
|
|
1671
|
+
submitPaneOp(loaded, "launch", { targets }, `launch ${label}`, runLaunch);
|
|
1494
1672
|
return;
|
|
1495
1673
|
}
|
|
1496
1674
|
if (cmd === "prompt") {
|
|
@@ -1614,17 +1792,43 @@ async function main() {
|
|
|
1614
1792
|
printFlushResults(results);
|
|
1615
1793
|
return;
|
|
1616
1794
|
}
|
|
1617
|
-
if (cmd === "
|
|
1795
|
+
if (cmd === "kill" || cmd === "empty") {
|
|
1618
1796
|
const loaded = meshLoaded(profileArg);
|
|
1619
|
-
requireCoordRole(loaded,
|
|
1620
|
-
const
|
|
1797
|
+
requireCoordRole(loaded, "switch");
|
|
1798
|
+
const targetRaw = sub;
|
|
1799
|
+
if (!targetRaw) {
|
|
1800
|
+
console.error(`usage: ${cmd} <target|1..4|slot-N|mini-N|here>`);
|
|
1801
|
+
console.error(" → plain terminal (respawn-pane -k) + save empty in mesh-agents.json");
|
|
1802
|
+
process.exit(2);
|
|
1803
|
+
}
|
|
1804
|
+
const targets = expandTargetSpec(targetRaw, targetRangeOptsFromProfile(loaded.profile));
|
|
1805
|
+
for (const t of targets) {
|
|
1806
|
+
runSwitchFast(loaded, t, "empty", {
|
|
1807
|
+
fresh: true,
|
|
1808
|
+
persistEmpty: true,
|
|
1809
|
+
reason: cmd === "kill" ? "kill" : "empty",
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
if (targets.length > 1) {
|
|
1813
|
+
console.log(`ok fanout ${cmd} → ${targets.join(",")} (${targets.length})`);
|
|
1814
|
+
}
|
|
1815
|
+
return;
|
|
1816
|
+
}
|
|
1817
|
+
if (cmd === "switch" || cmd === "handoff" || cmd === "spawn") {
|
|
1818
|
+
const loaded = meshLoaded(profileArg);
|
|
1819
|
+
requireCoordRole(loaded, cmd === "spawn" ? "switch" : cmd);
|
|
1621
1820
|
const args = [sub, ...tail].filter(Boolean);
|
|
1821
|
+
const vocal = cmd === "spawn" ? "spawn" : "switch";
|
|
1822
|
+
// spawn defaults fast (paste like typing opencode); switch defaults thorough
|
|
1823
|
+
let fast = cmd === "spawn";
|
|
1622
1824
|
if (args.length < 2) {
|
|
1623
|
-
console.error(
|
|
1624
|
-
|
|
1825
|
+
console.error(cmd === "spawn"
|
|
1826
|
+
? "usage: spawn <target|1..4> <agent|cursor|claude|oc|opencode> [--fast|--slow] [--keep-resume] [--resume ID]"
|
|
1827
|
+
: "usage: switch <target|1..4> <agent|…|empty> [--fast|--slow] [--keep-resume] [--resume ID] [reason...]");
|
|
1828
|
+
console.error(" empty→CLI: spawn (fast by default) · replace live: switch · --fast = skip verify waits");
|
|
1625
1829
|
process.exit(2);
|
|
1626
1830
|
}
|
|
1627
|
-
const
|
|
1831
|
+
const targetRaw = args[0];
|
|
1628
1832
|
const newType = args[1];
|
|
1629
1833
|
let fresh;
|
|
1630
1834
|
let queue = false;
|
|
@@ -1636,6 +1840,10 @@ async function main() {
|
|
|
1636
1840
|
fresh = true;
|
|
1637
1841
|
else if (a === "--keep-resume" || a === "--no-fresh")
|
|
1638
1842
|
fresh = false;
|
|
1843
|
+
else if (a === "--fast")
|
|
1844
|
+
fast = true;
|
|
1845
|
+
else if (a === "--slow" || a === "--verify")
|
|
1846
|
+
fast = false;
|
|
1639
1847
|
else if (a === "--queue")
|
|
1640
1848
|
queue = true;
|
|
1641
1849
|
else if (a === "--resume" && args[i + 1])
|
|
@@ -1646,17 +1854,29 @@ async function main() {
|
|
|
1646
1854
|
reasonParts.push(a);
|
|
1647
1855
|
}
|
|
1648
1856
|
const reason = reasonParts.join(" ") || undefined;
|
|
1649
|
-
const
|
|
1857
|
+
const targets = expandTargetSpec(targetRaw, targetRangeOptsFromProfile(loaded.profile));
|
|
1858
|
+
// Fast path skips provider registry build (expensive).
|
|
1859
|
+
const reg = fast ? null : createRegistryForProfile(loaded.profile);
|
|
1860
|
+
const runOne = (target) => runSwitch(loaded, reg, target, newType, {
|
|
1650
1861
|
fresh,
|
|
1651
1862
|
resumeId,
|
|
1652
1863
|
reason,
|
|
1864
|
+
fast,
|
|
1653
1865
|
});
|
|
1866
|
+
const run = () => {
|
|
1867
|
+
for (const t of targets)
|
|
1868
|
+
runOne(t);
|
|
1869
|
+
if (targets.length > 1) {
|
|
1870
|
+
console.log(`ok fanout ${vocal} → ${targets.join(",")} (${targets.length})`);
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1654
1873
|
if (queue) {
|
|
1655
|
-
submitPaneOp(loaded, "switch", { target, newType, fresh, resumeId, reason },
|
|
1874
|
+
submitPaneOp(loaded, "switch", { target: targetRaw, newType, fresh, resumeId, reason, fast }, `${vocal} ${targetRaw} -> ${newType}${fast ? " [fast]" : ""}`, run);
|
|
1656
1875
|
}
|
|
1657
1876
|
else {
|
|
1658
1877
|
run();
|
|
1659
|
-
|
|
1878
|
+
if (!fast && reg)
|
|
1879
|
+
saveMeshSession(loaded, reg);
|
|
1660
1880
|
}
|
|
1661
1881
|
return;
|
|
1662
1882
|
}
|
|
@@ -1776,7 +1996,8 @@ async function main() {
|
|
|
1776
1996
|
}
|
|
1777
1997
|
if (sub && AGENT_META.has(sub)) {
|
|
1778
1998
|
if (sub === "forum" || sub === "golf") {
|
|
1779
|
-
|
|
1999
|
+
const { printAgentForum } = await import("./commands/agent-forum.js");
|
|
2000
|
+
printAgentForum();
|
|
1780
2001
|
return;
|
|
1781
2002
|
}
|
|
1782
2003
|
if (sub === "apply") {
|
|
@@ -1968,7 +2189,7 @@ async function main() {
|
|
|
1968
2189
|
if (sub === "reset") {
|
|
1969
2190
|
const { spawnSync } = await import("node:child_process");
|
|
1970
2191
|
const path = await import("node:path");
|
|
1971
|
-
const script = path.join(loaded.workspace, "scripts/
|
|
2192
|
+
const script = path.join(loaded.workspace, "scripts/opencode-cpe-reset.sh");
|
|
1972
2193
|
const r = spawnSync("bash", [script], {
|
|
1973
2194
|
cwd: loaded.workspace,
|
|
1974
2195
|
encoding: "utf8",
|
|
@@ -1982,6 +2203,10 @@ async function main() {
|
|
|
1982
2203
|
if (cmd === "providers") {
|
|
1983
2204
|
const loaded = meshLoaded(profileArg);
|
|
1984
2205
|
const reg = createRegistryForProfile(loaded.profile);
|
|
2206
|
+
const path = await import("node:path");
|
|
2207
|
+
const dropIn = await loadDropInProviders(path.join(loaded.profileDir, "providers"), (line) => console.error(line));
|
|
2208
|
+
for (const p of dropIn.providers)
|
|
2209
|
+
reg.register(p);
|
|
1985
2210
|
if (sub === "list") {
|
|
1986
2211
|
for (const p of reg.all())
|
|
1987
2212
|
console.log(p.id);
|
|
@@ -2046,10 +2271,10 @@ async function main() {
|
|
|
2046
2271
|
const loaded = meshLoaded(profileArg);
|
|
2047
2272
|
const getLoaded = () => loaded;
|
|
2048
2273
|
const branch = cmd === "room"
|
|
2049
|
-
? buildRoomCommands(getLoaded)
|
|
2274
|
+
? (await import("./commands/room-cli.js")).buildRoomCommands(getLoaded)
|
|
2050
2275
|
: cmd === "contract"
|
|
2051
|
-
? buildContractLockCommands(getLoaded)
|
|
2052
|
-
: buildChatCommands(getLoaded);
|
|
2276
|
+
? (await import("./commands/contract-lock-cli.js")).buildContractLockCommands(getLoaded)
|
|
2277
|
+
: (await import("./commands/chat-cli.js")).buildChatCommands(getLoaded);
|
|
2053
2278
|
// contract with no sub → status (simple agent path)
|
|
2054
2279
|
if (!sub && cmd === "contract") {
|
|
2055
2280
|
try {
|
|
@@ -2173,7 +2398,7 @@ async function main() {
|
|
|
2173
2398
|
if (cmd === "notify") {
|
|
2174
2399
|
const loaded = meshLoaded(profileArg);
|
|
2175
2400
|
const getLoaded = () => loaded;
|
|
2176
|
-
const branch = buildNotifyCommand(getLoaded);
|
|
2401
|
+
const branch = (await import("./commands/notify-cli.js")).buildNotifyCommand(getLoaded);
|
|
2177
2402
|
try {
|
|
2178
2403
|
await branch.parseAsync(rest.slice(1), { from: "user" });
|
|
2179
2404
|
}
|
|
@@ -2187,12 +2412,66 @@ async function main() {
|
|
|
2187
2412
|
}
|
|
2188
2413
|
if (cmd === "mds") {
|
|
2189
2414
|
const loaded = meshLoaded(profileArg);
|
|
2415
|
+
const { runMdsCommand } = await import("./commands/mds-cli.js");
|
|
2190
2416
|
process.exit(await runMdsCommand(loaded, rest.slice(1)));
|
|
2191
2417
|
}
|
|
2192
2418
|
if (cmd === "preview") {
|
|
2193
2419
|
const loaded = meshLoaded(profileArg);
|
|
2194
2420
|
const getLoaded = () => loaded;
|
|
2195
|
-
const branch = buildPreviewCommand(getLoaded);
|
|
2421
|
+
const branch = (await import("./commands/preview-cli.js")).buildPreviewCommand(getLoaded);
|
|
2422
|
+
try {
|
|
2423
|
+
await branch.parseAsync(rest.slice(1), { from: "user" });
|
|
2424
|
+
}
|
|
2425
|
+
catch (e) {
|
|
2426
|
+
const err = e;
|
|
2427
|
+
if (err.code === "commander.helpDisplayed" || err.code === "commander.version")
|
|
2428
|
+
return;
|
|
2429
|
+
throw e;
|
|
2430
|
+
}
|
|
2431
|
+
return;
|
|
2432
|
+
}
|
|
2433
|
+
if (cmd === "nav") {
|
|
2434
|
+
const loaded = meshLoaded(profileArg);
|
|
2435
|
+
const getLoaded = () => loaded;
|
|
2436
|
+
const branch = (await import("./commands/nav-cli.js")).buildNavCommands(getLoaded);
|
|
2437
|
+
if (!sub) {
|
|
2438
|
+
branch.outputHelp();
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2441
|
+
try {
|
|
2442
|
+
await branch.parseAsync([sub, ...tail], { from: "user" });
|
|
2443
|
+
}
|
|
2444
|
+
catch (e) {
|
|
2445
|
+
const err = e;
|
|
2446
|
+
if (err.code === "commander.helpDisplayed" || err.code === "commander.version")
|
|
2447
|
+
return;
|
|
2448
|
+
throw e;
|
|
2449
|
+
}
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
if (cmd === "campaign") {
|
|
2453
|
+
const loaded = meshLoaded(profileArg);
|
|
2454
|
+
const getLoaded = () => loaded;
|
|
2455
|
+
const branch = (await import("./commands/campaign-cli.js")).buildCampaignCommands(getLoaded);
|
|
2456
|
+
if (!sub) {
|
|
2457
|
+
branch.outputHelp();
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
try {
|
|
2461
|
+
await branch.parseAsync([sub, ...tail], { from: "user" });
|
|
2462
|
+
}
|
|
2463
|
+
catch (e) {
|
|
2464
|
+
const err = e;
|
|
2465
|
+
if (err.code === "commander.helpDisplayed" || err.code === "commander.version")
|
|
2466
|
+
return;
|
|
2467
|
+
throw e;
|
|
2468
|
+
}
|
|
2469
|
+
return;
|
|
2470
|
+
}
|
|
2471
|
+
if (cmd === "schedule") {
|
|
2472
|
+
const loaded = meshLoaded(profileArg);
|
|
2473
|
+
const getLoaded = () => loaded;
|
|
2474
|
+
const branch = (await import("./commands/schedule-cli.js")).buildScheduleCommand(getLoaded);
|
|
2196
2475
|
try {
|
|
2197
2476
|
await branch.parseAsync(rest.slice(1), { from: "user" });
|
|
2198
2477
|
}
|