seatmesh 1.0.0 → 1.0.3
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/dist/commands/ack-cli.d.ts +4 -0
- package/dist/commands/ack-cli.d.ts.map +1 -0
- package/dist/commands/ack-cli.js +105 -0
- package/dist/commands/ack-cli.js.map +1 -0
- package/dist/commands/checkback-cli.d.ts.map +1 -1
- package/dist/commands/checkback-cli.js +1 -0
- package/dist/commands/checkback-cli.js.map +1 -1
- package/dist/commands/notify-cli.d.ts.map +1 -1
- package/dist/commands/notify-cli.js +69 -10
- package/dist/commands/notify-cli.js.map +1 -1
- package/dist/commands/target-cli.d.ts +4 -0
- package/dist/commands/target-cli.d.ts.map +1 -0
- package/dist/commands/target-cli.js +146 -0
- package/dist/commands/target-cli.js.map +1 -0
- package/dist/main.js +266 -77
- package/dist/main.js.map +1 -1
- package/dist/setup/agent-context-init.d.ts.map +1 -1
- package/dist/setup/agent-context-init.js +11 -5
- package/dist/setup/agent-context-init.js.map +1 -1
- package/dist/setup/init.d.ts +23 -3
- package/dist/setup/init.d.ts.map +1 -1
- package/dist/setup/init.js +71 -3
- package/dist/setup/init.js.map +1 -1
- package/dist/setup/update.d.ts +4 -0
- package/dist/setup/update.d.ts.map +1 -1
- package/dist/setup/update.js +63 -26
- package/dist/setup/update.js.map +1 -1
- package/dist/setup/update.test.d.ts +2 -0
- package/dist/setup/update.test.d.ts.map +1 -0
- package/dist/setup/update.test.js +50 -0
- package/dist/setup/update.test.js.map +1 -0
- package/dist/ui/banner.d.ts +17 -2
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +76 -2
- package/dist/ui/banner.js.map +1 -1
- package/dist/ui/banner.test.d.ts +2 -0
- package/dist/ui/banner.test.d.ts.map +1 -0
- package/dist/ui/banner.test.js +47 -0
- package/dist/ui/banner.test.js.map +1 -0
- package/dist/ui/version-nudge.d.ts +16 -2
- package/dist/ui/version-nudge.d.ts.map +1 -1
- package/dist/ui/version-nudge.js +80 -3
- package/dist/ui/version-nudge.js.map +1 -1
- package/dist/ui/version-nudge.test.js +31 -3
- package/dist/ui/version-nudge.test.js.map +1 -1
- package/package.json +6 -6
- package/profiles/minimal/mesh.config.yaml +1 -1
- package/profiles/minimal/paths.json +2 -2
- package/profiles/minimal/roles/common.yaml +3 -0
- package/templates/init/AGENTS.md +87 -0
- package/templates/init/mesh.config.yaml +10 -6
- package/templates/init/roles/common.yaml +4 -1
- package/templates/init/roles/manager.yaml +3 -3
- package/templates/init/roles/mini.yaml +4 -4
- package/templates/init/roles/secretary.yaml +2 -2
- package/templates/init/roles/worker.yaml +5 -5
package/dist/main.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
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, } from "@seat-mesh/core";
|
|
4
|
+
import { loadProfile, profilePaths, loadRoleIndex, renderRoleIndex, validateRoleIndex, runStackPassthrough, roleAllows, isCoordKind, isManagerKind, managerColumnIds, addBaseColumn, removeBaseColumn, listBaseColumns, chatRoomConfigForLoaded, clearAckEndedSync, } from "@seat-mesh/core";
|
|
5
5
|
import { snapshotConnectivity, formatStatus } from "@seat-mesh/connectivity";
|
|
6
6
|
import { createRegistryForProfile } from "@seat-mesh/providers";
|
|
7
|
-
import { printWhoami, whoamiJson, whoamiJsonWithValidate, validateWhoamiRoleIndex, printAgentCard, printAgentContext, printAgentContextAllRoles, runWhoami, roleKindFromWhoami, requireCoordRole, requireInboxLifecycleRole, capturePaneSnapshot, listSessionPanes, sessionAttach, sessionUp, sessionStatus, relayoutMeshSession, realignAllLayouts, reloadMesh, ensureMeshInbox, startMeshInbox, stopMeshInbox, restartMeshInbox, printMeshInboxStatus, waitForMeshInbox, printInboxMeta, tailInboxLog, listInboxInstances, parseInboxStatusFlags, inboxStatusArgv, listInbox, resolveInbox, secretaryLaunch, secretaryRestart, secretaryDispatch, secretaryCollect, secretaryMeshWatch, secretarySupervise, secretaryStatus, printMiniList, miniSpawn, miniPrompt, miniDone, miniSpawnAll, runMeshSmoke, printSmokeResults, launchSession, printLaunchResults, enqueuePrompt, injectPromptDirect, printPeerVerify, runPeerVerify, runRemind, printRemindResults, runNight, runContinue, printContinueResults, runSlotAdvice, verifyMeshSession, printVerify, labelMeshSession, liveMeshSession, ensureBaseLayout, realignBaseLayout, applyMeshSessionBorders, runFlush, printFlushResults, runSwitch, runSet, runTag, setPaneTitle, setPaneStatus, printSeatContexts, runPeek, runPaneMeta, runPpa, runToSlot, runToMini, runPeer, applyMeshState, saveMeshSession, saveMeshSessionDetailed, assertSaveAllowed, formatSaveSummary, submitPaneOp, clearPaneOpsQueue, printPaneOpsList, printRelayoutPlan, assertRelayoutSafe, buildFullColdStartBrief, enqueueColdStart, runSeatInit, applyAgentContractBundle, balanceLeadCommand, } from "@seat-mesh/tmux";
|
|
7
|
+
import { printWhoami, whoamiJson, whoamiJsonWithValidate, validateWhoamiRoleIndex, printAgentCard, printAgentContext, printAgentContextAllRoles, runWhoami, roleKindFromWhoami, requireCoordRole, requireInboxLifecycleRole, assertAgentDispatch, printAgentUnauthorized, stripAgentFromArgv, AGENT_META, capturePaneSnapshot, listSessionPanes, sessionAttach, sessionUp, sessionStatus, relayoutMeshSession, realignAllLayouts, reloadMesh, ensureMeshInbox, startMeshInbox, stopMeshInbox, restartMeshInbox, meshInboxEverConfigured, meshInboxPort, printMeshInboxStatus, waitForMeshInbox, printInboxMeta, tailInboxLog, listInboxInstances, parseInboxStatusFlags, inboxStatusArgv, listInbox, resolveInbox, secretaryLaunch, secretaryRestart, secretaryDispatch, secretaryCollect, secretaryMeshWatch, secretarySupervise, secretaryStatus, printMiniList, miniSpawn, miniPrompt, miniDone, miniSpawnAll, runMeshSmoke, printSmokeResults, launchSession, printLaunchResults, enqueuePrompt, injectPromptDirect, printPeerVerify, runPeerVerify, runRemind, printRemindResults, runNight, runContinue, printContinueResults, runSlotAdvice, verifyMeshSession, printVerify, labelMeshSession, liveMeshSession, ensureBaseLayout, realignBaseLayout, applyMeshSessionBorders, runFlush, printFlushResults, runSwitch, runSet, runTag, setPaneTitle, setPaneStatus, printSeatContexts, 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
8
|
import { parseAgentApplyArgs } from "@seat-mesh/core";
|
|
9
9
|
import { buildChatCommands } from "./commands/chat-cli.js";
|
|
10
10
|
import { buildCheckbackCommands } from "./commands/checkback-cli.js";
|
|
11
|
+
import { buildTargetCommands } from "./commands/target-cli.js";
|
|
12
|
+
import { buildAckCommands } from "./commands/ack-cli.js";
|
|
11
13
|
import { buildNotifyCommand } from "./commands/notify-cli.js";
|
|
12
14
|
import { buildPreviewCommand } from "./commands/preview-cli.js";
|
|
13
15
|
import { buildContractLockCommands } from "./commands/contract-lock-cli.js";
|
|
@@ -46,8 +48,11 @@ function usage(loaded) {
|
|
|
46
48
|
Setup (run once per project, by a human)
|
|
47
49
|
start init (if no .sm/ here) + session up, in one step
|
|
48
50
|
init [--force] [--seats-root PATH] [--name NAME] create .sm/ dotdir
|
|
51
|
+
session init <sm-name> [--force] [--name NAME] create .sm-<name>/ (multi-config)
|
|
49
52
|
sessions [pick|list|attach|forget|register] [--json] global registry + TUI picker
|
|
50
|
-
update [--dry-run] [--migrate]
|
|
53
|
+
update [--dry-run] [--migrate] [--no-restart-inbox]
|
|
54
|
+
refresh _vendor (file-by-file) + paths.json; restart inbox
|
|
55
|
+
version [--json] [--check-registry] CLI vs npm latest vs profile .seatmesh-version
|
|
51
56
|
|
|
52
57
|
Status / diagnostics
|
|
53
58
|
report [--json] [--verbose] stack status (one line default; --verbose = full section dump)
|
|
@@ -55,7 +60,7 @@ Status / diagnostics
|
|
|
55
60
|
test smoke: layout, providers, inbox, proxy
|
|
56
61
|
|
|
57
62
|
Session / layout (infra shape, operator or manager)
|
|
58
|
-
session attach|up|status
|
|
63
|
+
session attach|up|status|init <sm-name>
|
|
59
64
|
reload [--layout] rebuild engine + labels (no session kill; --layout re-grids)
|
|
60
65
|
layout [--no-leads] [--dry-run] [--yes] workers + minis grid (queued)
|
|
61
66
|
layout column list|add <id> [--cli P] [--after ID] [--co-typed]|remove <id>
|
|
@@ -66,78 +71,122 @@ Session / layout (infra shape, operator or manager)
|
|
|
66
71
|
labels re-apply @mesh_* + border strip
|
|
67
72
|
inbox [--json] [--wait N] [--meta] | inbox list|resolve|log|instances|stop|restart
|
|
68
73
|
|
|
69
|
-
Agent runtime (
|
|
70
|
-
|
|
71
|
-
agent
|
|
72
|
-
agent context [roles|init] registered read_first/files; init scaffolds .sm
|
|
73
|
-
|
|
74
|
-
contexts [--json] | peek | pane-meta | ppa
|
|
75
|
-
switch | handoff | set | tag <target|self> <id|--auto> | title | status
|
|
76
|
-
night on|off|status | continue <slot|all> (manager + night on)
|
|
77
|
-
slot-advice <slot> [--send] [note...] (manager; worktree/DB/Redis heuristics)
|
|
78
|
-
prompt | remind | flush
|
|
74
|
+
Agent runtime (pane — always via gateway)
|
|
75
|
+
agent scoped can/cannot for this pane
|
|
76
|
+
agent <cmd> … run <cmd> if allowed; else UNAUTHORIZED
|
|
77
|
+
agent context [roles|init] registered read_first/files; init scaffolds .sm
|
|
78
|
+
agent apply|preflight … contract apply
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
peer <target> <msg...> FYI/ACK only — work goes through assign
|
|
83
|
-
to-slot | to-mini <msg...> enqueue (daemon injects) — to-master retired, use room say
|
|
84
|
-
secretary start|dispatch|collect|status|watch …
|
|
85
|
-
mini list|spawn|prompt|done|dispatch-all
|
|
86
|
-
checkback start|list|cancel|cancel-all|reset|ack (alias: patience)
|
|
87
|
-
coord expect <target> <hub> <snippet...> arm coord-expect on manager (verify + re-assign)
|
|
88
|
-
room | chat | index | proxy | providers | manager | stack | profile show
|
|
89
|
-
notify <session> <check> [--url URL] desktop toast (seat from TMUX pane)
|
|
90
|
-
notify yesno <title> <body> [--target secretary] Yes/No links -> peer (notify-act)
|
|
91
|
-
preview <file...> [--set days] [--notify] publish markdown to mdview.io
|
|
92
|
-
launch [--now] [targets…]
|
|
80
|
+
Shared/operator (outside agent — humans + session ops)
|
|
81
|
+
session | update | init | report | test | layout | save | inbox restart | target …
|
|
93
82
|
|
|
94
|
-
|
|
83
|
+
Examples: agent whoami | agent kind slot-1 | agent peer <t> "<msg>" | agent ack <id> "<note>" | agent cb list
|
|
84
|
+
Operator EOD: target add "finish s13 tickets" [--deadline eod|6h] · target list · target done <id> · target triage <id>
|
|
85
|
+
|
|
86
|
+
--profile <dir|yaml> optional; default walk-up .sm/; multi-config: --profile .sm-<name>
|
|
95
87
|
`);
|
|
96
88
|
}
|
|
89
|
+
function printPlainUsage(profileArg) {
|
|
90
|
+
if (profileArg) {
|
|
91
|
+
try {
|
|
92
|
+
usage(meshLoaded(profileArg));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
/* fall through — plain help without profile load */
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
usage();
|
|
100
|
+
}
|
|
97
101
|
async function main() {
|
|
98
|
-
const { maybePrintVersionNudge } = await import("./ui/version-nudge.js");
|
|
99
|
-
maybePrintVersionNudge();
|
|
100
102
|
const { profile: profileArg, rest } = parseArgs(process.argv.slice(2));
|
|
101
103
|
const [cmd, sub, ...tail] = rest;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
// Bare `npx seatmesh` / help: logo+version once per terminal; later invocations plain usage.
|
|
105
|
+
const helpCmd = cmd === "-h" || cmd === "--help" || cmd === "help";
|
|
106
|
+
const blankCmd = !cmd || (cmd.startsWith("-") && !helpCmd);
|
|
107
|
+
if (blankCmd || helpCmd) {
|
|
108
|
+
const { printSeatmeshBanner } = await import("./ui/banner.js");
|
|
109
|
+
const { formatHelpVersionBlock, installKindLabel, readInstalledCliVersion, resolveLatestRegistryVersion, } = await import("./ui/version-nudge.js");
|
|
110
|
+
const showedBrand = printSeatmeshBanner({ tagline: true });
|
|
111
|
+
if (showedBrand) {
|
|
112
|
+
const installed = readInstalledCliVersion();
|
|
113
|
+
const latest = resolveLatestRegistryVersion(false);
|
|
114
|
+
for (const line of formatHelpVersionBlock(installed, latest, installKindLabel())) {
|
|
115
|
+
console.log(line);
|
|
116
|
+
}
|
|
117
|
+
console.log("");
|
|
108
118
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const verbose = rest.includes("--verbose") || rest.includes("-v");
|
|
112
|
-
const report = await printStatusReport(loaded, { json, verbose });
|
|
113
|
-
process.exit(report.ok ? 0 : 1);
|
|
119
|
+
printPlainUsage(profileArg);
|
|
120
|
+
return;
|
|
114
121
|
}
|
|
115
|
-
|
|
122
|
+
const { maybePrintVersionNudge } = await import("./ui/version-nudge.js");
|
|
123
|
+
maybePrintVersionNudge();
|
|
124
|
+
if (cmd === "version") {
|
|
125
|
+
const { printVersionInfo } = await import("./ui/version-nudge.js");
|
|
126
|
+
let profileDir;
|
|
116
127
|
try {
|
|
117
|
-
|
|
128
|
+
profileDir = meshLoaded(profileArg).profileDir;
|
|
118
129
|
}
|
|
119
130
|
catch {
|
|
120
|
-
|
|
131
|
+
/* no profile — CLI only */
|
|
121
132
|
}
|
|
133
|
+
printVersionInfo({
|
|
134
|
+
profileDir,
|
|
135
|
+
json: rest.includes("--json"),
|
|
136
|
+
forceRegistryCheck: rest.includes("--check-registry"),
|
|
137
|
+
});
|
|
122
138
|
return;
|
|
123
139
|
}
|
|
124
140
|
if (cmd === "update") {
|
|
125
141
|
const { runUpdate } = await import("./setup/update.js");
|
|
142
|
+
const { formatInstallStatusLine, isNpxEphemeralInstall, readInstalledCliVersion, resolveLatestRegistryVersion, semverLess, } = await import("./ui/version-nudge.js");
|
|
126
143
|
const dryRun = rest.includes("--dry-run");
|
|
127
144
|
const migrate = rest.includes("--migrate");
|
|
145
|
+
const noRestartInbox = rest.includes("--no-restart-inbox");
|
|
146
|
+
const installed = readInstalledCliVersion();
|
|
147
|
+
const npmLatest = resolveLatestRegistryVersion(true);
|
|
148
|
+
console.log(formatInstallStatusLine(installed, npmLatest));
|
|
128
149
|
const r = runUpdate({ profileArg, dryRun, migrate });
|
|
129
150
|
console.log(`OK: update dryRun=${dryRun} migrate=${migrate}`);
|
|
151
|
+
console.log(` CLI running: ${r.packageVersion}`);
|
|
152
|
+
if (r.previousVersion != null) {
|
|
153
|
+
console.log(` profile .seatmesh-version: ${r.previousVersion} (last profile update — not npm "installed")`);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.log(` profile .seatmesh-version: (none yet)`);
|
|
157
|
+
}
|
|
158
|
+
if (npmLatest)
|
|
159
|
+
console.log(` npm latest: ${npmLatest}`);
|
|
160
|
+
if (npmLatest && semverLess(installed, npmLatest)) {
|
|
161
|
+
console.error(` WARN: CLI ${installed} < npm ${npmLatest} — upgrade: npm install -g seatmesh@latest or npx seatmesh@latest update`);
|
|
162
|
+
}
|
|
130
163
|
console.log(` paths: ${r.pathsManifest}`);
|
|
131
164
|
for (const line of r.refreshed)
|
|
132
165
|
console.log(` refreshed: ${line}`);
|
|
133
166
|
for (const line of r.skipped)
|
|
134
|
-
console.log(` skipped (
|
|
167
|
+
console.log(` skipped (unchanged): ${line}`);
|
|
135
168
|
if (r.migrate) {
|
|
136
169
|
for (const line of r.migrate.copied)
|
|
137
170
|
console.log(` migrate copied: ${line}`);
|
|
138
171
|
for (const line of r.migrate.skipped)
|
|
139
172
|
console.log(` migrate skipped: ${line}`);
|
|
140
173
|
}
|
|
174
|
+
if (isNpxEphemeralInstall()) {
|
|
175
|
+
console.log(" note: npx cache CLI — profile vendor updated only; npm package is re-fetched each npx run");
|
|
176
|
+
}
|
|
177
|
+
if (!dryRun && !noRestartInbox) {
|
|
178
|
+
const loaded = meshLoaded(profileArg);
|
|
179
|
+
if (meshInboxEverConfigured(loaded)) {
|
|
180
|
+
restartMeshInbox(loaded);
|
|
181
|
+
console.log(`OK: inbox restarted on :${meshInboxPort(loaded)} session=${loaded.sessionName}`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.log(" inbox: skip restart (no inbox for this profile yet)");
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else if (noRestartInbox) {
|
|
188
|
+
console.log(" inbox: skip restart (--no-restart-inbox)");
|
|
189
|
+
}
|
|
141
190
|
return;
|
|
142
191
|
}
|
|
143
192
|
if (cmd === "migrate-runtime") {
|
|
@@ -194,7 +243,7 @@ async function main() {
|
|
|
194
243
|
catch {
|
|
195
244
|
/* non-fatal */
|
|
196
245
|
}
|
|
197
|
-
console.log(" next:
|
|
246
|
+
console.log(" next: seatmesh session up");
|
|
198
247
|
return;
|
|
199
248
|
}
|
|
200
249
|
if (cmd === "sessions") {
|
|
@@ -217,6 +266,37 @@ async function main() {
|
|
|
217
266
|
return;
|
|
218
267
|
}
|
|
219
268
|
if (cmd === "session") {
|
|
269
|
+
if (sub === "init") {
|
|
270
|
+
const { normalizeSmProfileDir } = await import("@seat-mesh/core");
|
|
271
|
+
const rawName = tail[0];
|
|
272
|
+
if (!rawName || rawName.startsWith("-")) {
|
|
273
|
+
console.error("usage: session init <sm-name> [--force] [--name NAME]");
|
|
274
|
+
console.error(" creates .sm-<name>/ (default project config is still .sm via: init)");
|
|
275
|
+
console.error(" then: seatmesh --profile .sm-<name> session up");
|
|
276
|
+
process.exit(2);
|
|
277
|
+
}
|
|
278
|
+
const force = tail.includes("--force");
|
|
279
|
+
const nameIdx = tail.indexOf("--name");
|
|
280
|
+
const profileName = nameIdx >= 0 && tail[nameIdx + 1] ? tail[nameIdx + 1] : undefined;
|
|
281
|
+
const smDirName = normalizeSmProfileDir(rawName);
|
|
282
|
+
const r = runInit({ force, name: profileName, smDirName });
|
|
283
|
+
console.log(`OK: session init ${r.smDir}`);
|
|
284
|
+
console.log(` config: ${r.configPath}`);
|
|
285
|
+
console.log(` created: ${r.created.length} file(s)`);
|
|
286
|
+
if (r.skipped.length)
|
|
287
|
+
console.log(` skipped (exists): ${r.skipped.length}`);
|
|
288
|
+
try {
|
|
289
|
+
const { upsertGlobalSession } = await import("@seat-mesh/core");
|
|
290
|
+
await upsertGlobalSession(meshLoaded(r.configPath));
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
/* non-fatal */
|
|
294
|
+
}
|
|
295
|
+
console.log(` next: seatmesh --profile ${smDirName} session up`);
|
|
296
|
+
console.log(` agents: seatmesh --profile ${smDirName} agent …`);
|
|
297
|
+
console.log(` default .sm/ still needs no --profile (walk-up)`);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
220
300
|
const loaded = meshLoaded(profileArg);
|
|
221
301
|
const touchRegistry = async () => {
|
|
222
302
|
try {
|
|
@@ -243,7 +323,7 @@ async function main() {
|
|
|
243
323
|
sessionStatus(loaded);
|
|
244
324
|
return;
|
|
245
325
|
}
|
|
246
|
-
console.error("usage: session attach|up|status");
|
|
326
|
+
console.error("usage: session attach|up|status|init <sm-name>");
|
|
247
327
|
process.exit(2);
|
|
248
328
|
}
|
|
249
329
|
if (cmd === "verify") {
|
|
@@ -442,7 +522,7 @@ async function main() {
|
|
|
442
522
|
}
|
|
443
523
|
if (cmd === "to-master") {
|
|
444
524
|
// FRAMEWORK-QUEUE #1 (AGENT-FUNC-GUARDS.md): to-master retired — chat-first comms.
|
|
445
|
-
console.error('DEPRECATED: use
|
|
525
|
+
console.error('DEPRECATED: use seatmesh --profile .sm agent room say [-r managers] "DONE|BLOCKED|…"');
|
|
446
526
|
process.exit(2);
|
|
447
527
|
}
|
|
448
528
|
if (cmd === "to-slot") {
|
|
@@ -492,12 +572,34 @@ async function main() {
|
|
|
492
572
|
if (cmd === "peer") {
|
|
493
573
|
const loaded = meshLoaded(profileArg);
|
|
494
574
|
let direct = false;
|
|
575
|
+
let endedId;
|
|
495
576
|
const args = [];
|
|
496
|
-
|
|
497
|
-
|
|
577
|
+
const rawArgs = [sub, ...tail].filter((x) => x != null && x !== "");
|
|
578
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
579
|
+
const a = rawArgs[i];
|
|
580
|
+
if (a === "--direct" || a === "--now") {
|
|
498
581
|
direct = true;
|
|
499
|
-
|
|
500
|
-
|
|
582
|
+
continue;
|
|
583
|
+
}
|
|
584
|
+
if (a === "--ended" || a === "--ack") {
|
|
585
|
+
const id = rawArgs[i + 1];
|
|
586
|
+
if (!id || id.startsWith("-")) {
|
|
587
|
+
console.error("usage: peer … --ended <ack-id>");
|
|
588
|
+
process.exit(2);
|
|
589
|
+
}
|
|
590
|
+
endedId = id;
|
|
591
|
+
i++;
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (a.startsWith("--ended=") || a.startsWith("--ack=")) {
|
|
595
|
+
endedId = a.slice(a.indexOf("=") + 1).trim();
|
|
596
|
+
if (!endedId) {
|
|
597
|
+
console.error("usage: peer … --ended <ack-id>");
|
|
598
|
+
process.exit(2);
|
|
599
|
+
}
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
args.push(a);
|
|
501
603
|
}
|
|
502
604
|
if (args[0] === "verify") {
|
|
503
605
|
requireCoordRole(loaded, "peer verify");
|
|
@@ -511,13 +613,31 @@ async function main() {
|
|
|
511
613
|
const [target, ...textParts] = args;
|
|
512
614
|
const rawMsg = textParts.join(" ").trim();
|
|
513
615
|
if (!target || !rawMsg) {
|
|
514
|
-
console.error("usage: peer verify [target] | peer [--direct] <manager|secretary|slot-N|mini-N|pane> <msg...>");
|
|
616
|
+
console.error("usage: peer verify [target] | peer [--direct] [--ended <ack-id>] <manager|secretary|slot-N|mini-N|@alias:seat|pane> <msg...>");
|
|
515
617
|
process.exit(2);
|
|
516
618
|
}
|
|
619
|
+
const finishEnded = () => {
|
|
620
|
+
if (!endedId)
|
|
621
|
+
return;
|
|
622
|
+
const cfg = chatRoomConfigForLoaded(loaded);
|
|
623
|
+
const res = clearAckEndedSync(cfg.inboxBase, endedId, `peer -> ${target}: ${rawMsg}`);
|
|
624
|
+
if (!res.ok) {
|
|
625
|
+
console.error(`WARN: peer sent but --ended failed: ${res.error ?? "?"}`);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
console.log(`ok ended ack=${res.id ?? endedId}`);
|
|
629
|
+
};
|
|
517
630
|
try {
|
|
631
|
+
const remote = parseRemotePeerTarget(target);
|
|
632
|
+
if (remote) {
|
|
633
|
+
runRemotePeer(loaded, remote.alias, remote.seat, rawMsg);
|
|
634
|
+
finishEnded();
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
518
637
|
// Workers + minis: universal peer (to-slot/to-mini/enqueue). Coords keep manager stamp.
|
|
519
638
|
try {
|
|
520
639
|
runPeer(loaded, target, rawMsg);
|
|
640
|
+
finishEnded();
|
|
521
641
|
return;
|
|
522
642
|
}
|
|
523
643
|
catch (e) {
|
|
@@ -527,7 +647,7 @@ async function main() {
|
|
|
527
647
|
requireCoordRole(loaded, "peer");
|
|
528
648
|
if (direct) {
|
|
529
649
|
const reg = createRegistryForProfile(loaded.profile);
|
|
530
|
-
const { paneId, providerId, token, via } = injectPromptDirect(loaded, reg, target, rawMsg, { manager: true });
|
|
650
|
+
const { paneId, providerId, token, via } = injectPromptDirect(loaded, reg, target, rawMsg, { manager: true, force: true });
|
|
531
651
|
console.log(`SENT: peer --direct -> ${target} pane=${paneId} provider=${providerId} token=${token ?? "-"} via=${via ?? "direct"}`);
|
|
532
652
|
}
|
|
533
653
|
else {
|
|
@@ -541,6 +661,7 @@ async function main() {
|
|
|
541
661
|
: `SENT: peer -> ${targetLabel} pane=${paneId} token=${token ?? "-"} via=${via ?? "pane-row"}`;
|
|
542
662
|
console.log(line);
|
|
543
663
|
}
|
|
664
|
+
finishEnded();
|
|
544
665
|
}
|
|
545
666
|
catch (e) {
|
|
546
667
|
console.error(e.message);
|
|
@@ -752,6 +873,21 @@ async function main() {
|
|
|
752
873
|
}
|
|
753
874
|
return;
|
|
754
875
|
}
|
|
876
|
+
if (cmd === "kind" || cmd === "what" || cmd === "typeof") {
|
|
877
|
+
const loaded = meshLoaded(profileArg);
|
|
878
|
+
const reg = createRegistryForProfile(loaded.profile);
|
|
879
|
+
const args = [sub, ...tail].filter((a) => Boolean(a));
|
|
880
|
+
const json = args.includes("--json");
|
|
881
|
+
const target = args.find((a) => a !== "--json") ?? "here";
|
|
882
|
+
try {
|
|
883
|
+
runPaneKind(loaded, reg, target, { json });
|
|
884
|
+
}
|
|
885
|
+
catch (e) {
|
|
886
|
+
console.error(e.message);
|
|
887
|
+
process.exit(1);
|
|
888
|
+
}
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
755
891
|
if (cmd === "pane-meta") {
|
|
756
892
|
const loaded = meshLoaded(profileArg);
|
|
757
893
|
try {
|
|
@@ -1102,28 +1238,46 @@ async function main() {
|
|
|
1102
1238
|
if (cmd === "agent") {
|
|
1103
1239
|
const loaded = meshLoaded(profileArg);
|
|
1104
1240
|
const reg = createRegistryForProfile(loaded.profile);
|
|
1105
|
-
if (sub
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1241
|
+
if (sub && AGENT_META.has(sub)) {
|
|
1242
|
+
if (sub === "apply") {
|
|
1243
|
+
const { bundle, opts } = parseAgentApplyArgs(tail);
|
|
1244
|
+
applyAgentContractBundle(loaded, reg, bundle, opts);
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
1247
|
+
if (sub === "preflight") {
|
|
1248
|
+
const { bundle, opts } = parseAgentApplyArgs(tail);
|
|
1249
|
+
applyAgentContractBundle(loaded, reg, bundle, { ...opts, preflight: true, dryRun: true });
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
if (sub === "context") {
|
|
1253
|
+
if (tail[0] === "init") {
|
|
1254
|
+
const code = runAgentContextInit(loaded, { coldStartInject: tail.includes("--inject") });
|
|
1255
|
+
process.exit(code);
|
|
1256
|
+
}
|
|
1257
|
+
if (tail[0] === "roles") {
|
|
1258
|
+
process.exit(printAgentContextAllRoles(loaded));
|
|
1259
|
+
}
|
|
1260
|
+
const targetArg = tail.find((a) => !a.startsWith("-"));
|
|
1261
|
+
process.exit(printAgentContext(loaded, targetArg));
|
|
1262
|
+
}
|
|
1114
1263
|
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1264
|
+
// Gateway: agent <cmd> … → authz then re-enter as top-level <cmd>
|
|
1265
|
+
if (sub && !AGENT_META.has(sub)) {
|
|
1266
|
+
const decision = assertAgentDispatch(loaded, sub, tail);
|
|
1267
|
+
if (decision.kind === "card-target") {
|
|
1268
|
+
const w = runWhoami(loaded, decision.target);
|
|
1269
|
+
printAgentCard(w);
|
|
1270
|
+
return;
|
|
1119
1271
|
}
|
|
1120
|
-
if (
|
|
1121
|
-
|
|
1272
|
+
if (decision.kind !== "allow") {
|
|
1273
|
+
printAgentUnauthorized(decision);
|
|
1274
|
+
process.exit(2);
|
|
1122
1275
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1276
|
+
process.argv = stripAgentFromArgv(process.argv);
|
|
1277
|
+
return main();
|
|
1125
1278
|
}
|
|
1126
|
-
|
|
1279
|
+
// Bare `agent` — own card
|
|
1280
|
+
const w = runWhoami(loaded, "here");
|
|
1127
1281
|
printAgentCard(w);
|
|
1128
1282
|
return;
|
|
1129
1283
|
}
|
|
@@ -1143,7 +1297,7 @@ async function main() {
|
|
|
1143
1297
|
}
|
|
1144
1298
|
if (loaded.profile.external.default === "deny") {
|
|
1145
1299
|
console.error(`UNAUTHORIZED: func ${id} denied (external.default=deny)`);
|
|
1146
|
-
console.error("hint:
|
|
1300
|
+
console.error("hint: seatmesh --profile .sm agent");
|
|
1147
1301
|
process.exit(2);
|
|
1148
1302
|
}
|
|
1149
1303
|
try {
|
|
@@ -1153,7 +1307,7 @@ async function main() {
|
|
|
1153
1307
|
const index = loadRoleIndex(paths.rolesDir, kind);
|
|
1154
1308
|
if (!roleAllows(index.funcs, id)) {
|
|
1155
1309
|
console.error(`UNAUTHORIZED: func ${id} denied for role=${kind}`);
|
|
1156
|
-
console.error("hint:
|
|
1310
|
+
console.error("hint: seatmesh --profile .sm agent");
|
|
1157
1311
|
process.exit(2);
|
|
1158
1312
|
}
|
|
1159
1313
|
}
|
|
@@ -1200,7 +1354,7 @@ async function main() {
|
|
|
1200
1354
|
}
|
|
1201
1355
|
if (cmd === "whoami" || cmd === "where") {
|
|
1202
1356
|
if (cmd === "where") {
|
|
1203
|
-
console.error("note: where is deprecated — use
|
|
1357
|
+
console.error("note: where is deprecated — use seatmesh --profile .sm agent whoami");
|
|
1204
1358
|
}
|
|
1205
1359
|
const loaded = meshLoaded(profileArg);
|
|
1206
1360
|
const json = rest.includes("--json");
|
|
@@ -1306,9 +1460,10 @@ async function main() {
|
|
|
1306
1460
|
const prov = reg.detect(snap);
|
|
1307
1461
|
const det = prov?.detect(snap);
|
|
1308
1462
|
const state = prov?.composerState(snap) ?? { phase: "plain_shell" };
|
|
1463
|
+
const role = snap.options.mesh_role?.trim() || "plain";
|
|
1309
1464
|
const slot = snap.options.mesh_slot || "-";
|
|
1310
1465
|
const ports = snap.options.mesh_ports || "-";
|
|
1311
|
-
console.log(`${paneId}\t${prov?.id ?? "?"}\t${det?.resumeId ?? "-"}\t${state.phase}${state.limitKind ? `:${state.limitKind}` : ""}\tslot=${slot}\tports=${ports}\t${snap.windowName}`);
|
|
1466
|
+
console.log(`${paneId}\trole=${role}\t${prov?.id ?? "?"}\t${det?.resumeId ?? "-"}\t${state.phase}${state.limitKind ? `:${state.limitKind}` : ""}\tslot=${slot}\tports=${ports}\t${snap.windowName}`);
|
|
1312
1467
|
}
|
|
1313
1468
|
return;
|
|
1314
1469
|
}
|
|
@@ -1389,7 +1544,7 @@ async function main() {
|
|
|
1389
1544
|
}
|
|
1390
1545
|
return;
|
|
1391
1546
|
}
|
|
1392
|
-
if (cmd === "checkback" || cmd === "patience") {
|
|
1547
|
+
if (cmd === "checkback" || cmd === "patience" || cmd === "cb") {
|
|
1393
1548
|
const loaded = meshLoaded(profileArg);
|
|
1394
1549
|
const getLoaded = () => loaded;
|
|
1395
1550
|
const branch = buildCheckbackCommands(getLoaded);
|
|
@@ -1408,6 +1563,40 @@ async function main() {
|
|
|
1408
1563
|
}
|
|
1409
1564
|
return;
|
|
1410
1565
|
}
|
|
1566
|
+
if (cmd === "target" || cmd === "targets") {
|
|
1567
|
+
const loaded = meshLoaded(profileArg);
|
|
1568
|
+
const getLoaded = () => loaded;
|
|
1569
|
+
const branch = buildTargetCommands(getLoaded);
|
|
1570
|
+
if (!sub) {
|
|
1571
|
+
branch.outputHelp();
|
|
1572
|
+
return;
|
|
1573
|
+
}
|
|
1574
|
+
try {
|
|
1575
|
+
await branch.parseAsync([sub, ...tail], { from: "user" });
|
|
1576
|
+
}
|
|
1577
|
+
catch (e) {
|
|
1578
|
+
const err = e;
|
|
1579
|
+
if (err.code === "commander.helpDisplayed" || err.code === "commander.version")
|
|
1580
|
+
return;
|
|
1581
|
+
throw e;
|
|
1582
|
+
}
|
|
1583
|
+
return;
|
|
1584
|
+
}
|
|
1585
|
+
if (cmd === "ack") {
|
|
1586
|
+
const loaded = meshLoaded(profileArg);
|
|
1587
|
+
const getLoaded = () => loaded;
|
|
1588
|
+
const branch = buildAckCommands(getLoaded);
|
|
1589
|
+
try {
|
|
1590
|
+
await branch.parseAsync(rest.slice(1), { from: "user" });
|
|
1591
|
+
}
|
|
1592
|
+
catch (e) {
|
|
1593
|
+
const err = e;
|
|
1594
|
+
if (err.code === "commander.helpDisplayed" || err.code === "commander.version")
|
|
1595
|
+
return;
|
|
1596
|
+
throw e;
|
|
1597
|
+
}
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1411
1600
|
if (cmd === "notify") {
|
|
1412
1601
|
const loaded = meshLoaded(profileArg);
|
|
1413
1602
|
const getLoaded = () => loaded;
|