seatmesh 1.0.2 → 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 +241 -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.map +1 -1
- package/dist/setup/update.js +17 -11
- package/dist/setup/update.js.map +1 -1
- 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 +1 -1
- package/profiles/minimal/roles/common.yaml +3 -0
- package/templates/init/AGENTS.md +87 -0
- package/templates/init/mesh.config.yaml +4 -4
- 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, 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, 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";
|
|
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,9 +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
53
|
update [--dry-run] [--migrate] [--no-restart-inbox]
|
|
51
54
|
refresh _vendor (file-by-file) + paths.json; restart inbox
|
|
55
|
+
version [--json] [--check-registry] CLI vs npm latest vs profile .seatmesh-version
|
|
52
56
|
|
|
53
57
|
Status / diagnostics
|
|
54
58
|
report [--json] [--verbose] stack status (one line default; --verbose = full section dump)
|
|
@@ -56,7 +60,7 @@ Status / diagnostics
|
|
|
56
60
|
test smoke: layout, providers, inbox, proxy
|
|
57
61
|
|
|
58
62
|
Session / layout (infra shape, operator or manager)
|
|
59
|
-
session attach|up|status
|
|
63
|
+
session attach|up|status|init <sm-name>
|
|
60
64
|
reload [--layout] rebuild engine + labels (no session kill; --layout re-grids)
|
|
61
65
|
layout [--no-leads] [--dry-run] [--yes] workers + minis grid (queued)
|
|
62
66
|
layout column list|add <id> [--cli P] [--after ID] [--co-typed]|remove <id>
|
|
@@ -67,70 +71,95 @@ Session / layout (infra shape, operator or manager)
|
|
|
67
71
|
labels re-apply @mesh_* + border strip
|
|
68
72
|
inbox [--json] [--wait N] [--meta] | inbox list|resolve|log|instances|stop|restart
|
|
69
73
|
|
|
70
|
-
Agent runtime (
|
|
71
|
-
|
|
72
|
-
agent
|
|
73
|
-
agent context [roles|init] registered read_first/files; init scaffolds .sm
|
|
74
|
-
|
|
75
|
-
contexts [--json] | peek | pane-meta | ppa
|
|
76
|
-
switch | handoff | set | tag <target|self> <id|--auto> | title | status
|
|
77
|
-
night on|off|status | continue <slot|all> (manager + night on)
|
|
78
|
-
slot-advice <slot> [--send] [note...] (manager; worktree/DB/Redis heuristics)
|
|
79
|
-
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
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
peer <target> <msg...> FYI/ACK only — work goes through assign
|
|
84
|
-
to-slot | to-mini <msg...> enqueue (daemon injects) — to-master retired, use room say
|
|
85
|
-
secretary start|dispatch|collect|status|watch …
|
|
86
|
-
mini list|spawn|prompt|done|dispatch-all
|
|
87
|
-
checkback start|list|cancel|cancel-all|reset|ack (alias: patience)
|
|
88
|
-
coord expect <target> <hub> <snippet...> arm coord-expect on manager (verify + re-assign)
|
|
89
|
-
room | chat | index | proxy | providers | manager | stack | profile show
|
|
90
|
-
notify <session> <check> [--url URL] desktop toast (seat from TMUX pane)
|
|
91
|
-
notify yesno <title> <body> [--target secretary] Yes/No links -> peer (notify-act)
|
|
92
|
-
preview <file...> [--set days] [--notify] publish markdown to mdview.io
|
|
93
|
-
launch [--now] [targets…]
|
|
80
|
+
Shared/operator (outside agent — humans + session ops)
|
|
81
|
+
session | update | init | report | test | layout | save | inbox restart | target …
|
|
94
82
|
|
|
95
|
-
|
|
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>
|
|
96
87
|
`);
|
|
97
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
|
+
}
|
|
98
101
|
async function main() {
|
|
99
|
-
const { maybePrintVersionNudge } = await import("./ui/version-nudge.js");
|
|
100
|
-
maybePrintVersionNudge();
|
|
101
102
|
const { profile: profileArg, rest } = parseArgs(process.argv.slice(2));
|
|
102
103
|
const [cmd, sub, ...tail] = rest;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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("");
|
|
109
118
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const verbose = rest.includes("--verbose") || rest.includes("-v");
|
|
113
|
-
const report = await printStatusReport(loaded, { json, verbose });
|
|
114
|
-
process.exit(report.ok ? 0 : 1);
|
|
119
|
+
printPlainUsage(profileArg);
|
|
120
|
+
return;
|
|
115
121
|
}
|
|
116
|
-
|
|
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;
|
|
117
127
|
try {
|
|
118
|
-
|
|
128
|
+
profileDir = meshLoaded(profileArg).profileDir;
|
|
119
129
|
}
|
|
120
130
|
catch {
|
|
121
|
-
|
|
131
|
+
/* no profile — CLI only */
|
|
122
132
|
}
|
|
133
|
+
printVersionInfo({
|
|
134
|
+
profileDir,
|
|
135
|
+
json: rest.includes("--json"),
|
|
136
|
+
forceRegistryCheck: rest.includes("--check-registry"),
|
|
137
|
+
});
|
|
123
138
|
return;
|
|
124
139
|
}
|
|
125
140
|
if (cmd === "update") {
|
|
126
141
|
const { runUpdate } = await import("./setup/update.js");
|
|
127
|
-
const { isNpxEphemeralInstall } = await import("./ui/version-nudge.js");
|
|
142
|
+
const { formatInstallStatusLine, isNpxEphemeralInstall, readInstalledCliVersion, resolveLatestRegistryVersion, semverLess, } = await import("./ui/version-nudge.js");
|
|
128
143
|
const dryRun = rest.includes("--dry-run");
|
|
129
144
|
const migrate = rest.includes("--migrate");
|
|
130
145
|
const noRestartInbox = rest.includes("--no-restart-inbox");
|
|
146
|
+
const installed = readInstalledCliVersion();
|
|
147
|
+
const npmLatest = resolveLatestRegistryVersion(true);
|
|
148
|
+
console.log(formatInstallStatusLine(installed, npmLatest));
|
|
131
149
|
const r = runUpdate({ profileArg, dryRun, migrate });
|
|
132
150
|
console.log(`OK: update dryRun=${dryRun} migrate=${migrate}`);
|
|
133
|
-
console.log(`
|
|
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
|
+
}
|
|
134
163
|
console.log(` paths: ${r.pathsManifest}`);
|
|
135
164
|
for (const line of r.refreshed)
|
|
136
165
|
console.log(` refreshed: ${line}`);
|
|
@@ -214,7 +243,7 @@ async function main() {
|
|
|
214
243
|
catch {
|
|
215
244
|
/* non-fatal */
|
|
216
245
|
}
|
|
217
|
-
console.log(" next:
|
|
246
|
+
console.log(" next: seatmesh session up");
|
|
218
247
|
return;
|
|
219
248
|
}
|
|
220
249
|
if (cmd === "sessions") {
|
|
@@ -237,6 +266,37 @@ async function main() {
|
|
|
237
266
|
return;
|
|
238
267
|
}
|
|
239
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
|
+
}
|
|
240
300
|
const loaded = meshLoaded(profileArg);
|
|
241
301
|
const touchRegistry = async () => {
|
|
242
302
|
try {
|
|
@@ -263,7 +323,7 @@ async function main() {
|
|
|
263
323
|
sessionStatus(loaded);
|
|
264
324
|
return;
|
|
265
325
|
}
|
|
266
|
-
console.error("usage: session attach|up|status");
|
|
326
|
+
console.error("usage: session attach|up|status|init <sm-name>");
|
|
267
327
|
process.exit(2);
|
|
268
328
|
}
|
|
269
329
|
if (cmd === "verify") {
|
|
@@ -462,7 +522,7 @@ async function main() {
|
|
|
462
522
|
}
|
|
463
523
|
if (cmd === "to-master") {
|
|
464
524
|
// FRAMEWORK-QUEUE #1 (AGENT-FUNC-GUARDS.md): to-master retired — chat-first comms.
|
|
465
|
-
console.error('DEPRECATED: use
|
|
525
|
+
console.error('DEPRECATED: use seatmesh --profile .sm agent room say [-r managers] "DONE|BLOCKED|…"');
|
|
466
526
|
process.exit(2);
|
|
467
527
|
}
|
|
468
528
|
if (cmd === "to-slot") {
|
|
@@ -512,12 +572,34 @@ async function main() {
|
|
|
512
572
|
if (cmd === "peer") {
|
|
513
573
|
const loaded = meshLoaded(profileArg);
|
|
514
574
|
let direct = false;
|
|
575
|
+
let endedId;
|
|
515
576
|
const args = [];
|
|
516
|
-
|
|
517
|
-
|
|
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") {
|
|
518
581
|
direct = true;
|
|
519
|
-
|
|
520
|
-
|
|
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);
|
|
521
603
|
}
|
|
522
604
|
if (args[0] === "verify") {
|
|
523
605
|
requireCoordRole(loaded, "peer verify");
|
|
@@ -531,18 +613,31 @@ async function main() {
|
|
|
531
613
|
const [target, ...textParts] = args;
|
|
532
614
|
const rawMsg = textParts.join(" ").trim();
|
|
533
615
|
if (!target || !rawMsg) {
|
|
534
|
-
console.error("usage: peer verify [target] | peer [--direct] <manager|secretary|slot-N|mini-N|@alias:seat|pane> <msg...>");
|
|
616
|
+
console.error("usage: peer verify [target] | peer [--direct] [--ended <ack-id>] <manager|secretary|slot-N|mini-N|@alias:seat|pane> <msg...>");
|
|
535
617
|
process.exit(2);
|
|
536
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
|
+
};
|
|
537
630
|
try {
|
|
538
631
|
const remote = parseRemotePeerTarget(target);
|
|
539
632
|
if (remote) {
|
|
540
633
|
runRemotePeer(loaded, remote.alias, remote.seat, rawMsg);
|
|
634
|
+
finishEnded();
|
|
541
635
|
return;
|
|
542
636
|
}
|
|
543
637
|
// Workers + minis: universal peer (to-slot/to-mini/enqueue). Coords keep manager stamp.
|
|
544
638
|
try {
|
|
545
639
|
runPeer(loaded, target, rawMsg);
|
|
640
|
+
finishEnded();
|
|
546
641
|
return;
|
|
547
642
|
}
|
|
548
643
|
catch (e) {
|
|
@@ -552,7 +647,7 @@ async function main() {
|
|
|
552
647
|
requireCoordRole(loaded, "peer");
|
|
553
648
|
if (direct) {
|
|
554
649
|
const reg = createRegistryForProfile(loaded.profile);
|
|
555
|
-
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 });
|
|
556
651
|
console.log(`SENT: peer --direct -> ${target} pane=${paneId} provider=${providerId} token=${token ?? "-"} via=${via ?? "direct"}`);
|
|
557
652
|
}
|
|
558
653
|
else {
|
|
@@ -566,6 +661,7 @@ async function main() {
|
|
|
566
661
|
: `SENT: peer -> ${targetLabel} pane=${paneId} token=${token ?? "-"} via=${via ?? "pane-row"}`;
|
|
567
662
|
console.log(line);
|
|
568
663
|
}
|
|
664
|
+
finishEnded();
|
|
569
665
|
}
|
|
570
666
|
catch (e) {
|
|
571
667
|
console.error(e.message);
|
|
@@ -777,6 +873,21 @@ async function main() {
|
|
|
777
873
|
}
|
|
778
874
|
return;
|
|
779
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
|
+
}
|
|
780
891
|
if (cmd === "pane-meta") {
|
|
781
892
|
const loaded = meshLoaded(profileArg);
|
|
782
893
|
try {
|
|
@@ -1127,28 +1238,46 @@ async function main() {
|
|
|
1127
1238
|
if (cmd === "agent") {
|
|
1128
1239
|
const loaded = meshLoaded(profileArg);
|
|
1129
1240
|
const reg = createRegistryForProfile(loaded.profile);
|
|
1130
|
-
if (sub
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
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
|
+
}
|
|
1139
1263
|
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
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;
|
|
1144
1271
|
}
|
|
1145
|
-
if (
|
|
1146
|
-
|
|
1272
|
+
if (decision.kind !== "allow") {
|
|
1273
|
+
printAgentUnauthorized(decision);
|
|
1274
|
+
process.exit(2);
|
|
1147
1275
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1276
|
+
process.argv = stripAgentFromArgv(process.argv);
|
|
1277
|
+
return main();
|
|
1150
1278
|
}
|
|
1151
|
-
|
|
1279
|
+
// Bare `agent` — own card
|
|
1280
|
+
const w = runWhoami(loaded, "here");
|
|
1152
1281
|
printAgentCard(w);
|
|
1153
1282
|
return;
|
|
1154
1283
|
}
|
|
@@ -1168,7 +1297,7 @@ async function main() {
|
|
|
1168
1297
|
}
|
|
1169
1298
|
if (loaded.profile.external.default === "deny") {
|
|
1170
1299
|
console.error(`UNAUTHORIZED: func ${id} denied (external.default=deny)`);
|
|
1171
|
-
console.error("hint:
|
|
1300
|
+
console.error("hint: seatmesh --profile .sm agent");
|
|
1172
1301
|
process.exit(2);
|
|
1173
1302
|
}
|
|
1174
1303
|
try {
|
|
@@ -1178,7 +1307,7 @@ async function main() {
|
|
|
1178
1307
|
const index = loadRoleIndex(paths.rolesDir, kind);
|
|
1179
1308
|
if (!roleAllows(index.funcs, id)) {
|
|
1180
1309
|
console.error(`UNAUTHORIZED: func ${id} denied for role=${kind}`);
|
|
1181
|
-
console.error("hint:
|
|
1310
|
+
console.error("hint: seatmesh --profile .sm agent");
|
|
1182
1311
|
process.exit(2);
|
|
1183
1312
|
}
|
|
1184
1313
|
}
|
|
@@ -1225,7 +1354,7 @@ async function main() {
|
|
|
1225
1354
|
}
|
|
1226
1355
|
if (cmd === "whoami" || cmd === "where") {
|
|
1227
1356
|
if (cmd === "where") {
|
|
1228
|
-
console.error("note: where is deprecated — use
|
|
1357
|
+
console.error("note: where is deprecated — use seatmesh --profile .sm agent whoami");
|
|
1229
1358
|
}
|
|
1230
1359
|
const loaded = meshLoaded(profileArg);
|
|
1231
1360
|
const json = rest.includes("--json");
|
|
@@ -1331,9 +1460,10 @@ async function main() {
|
|
|
1331
1460
|
const prov = reg.detect(snap);
|
|
1332
1461
|
const det = prov?.detect(snap);
|
|
1333
1462
|
const state = prov?.composerState(snap) ?? { phase: "plain_shell" };
|
|
1463
|
+
const role = snap.options.mesh_role?.trim() || "plain";
|
|
1334
1464
|
const slot = snap.options.mesh_slot || "-";
|
|
1335
1465
|
const ports = snap.options.mesh_ports || "-";
|
|
1336
|
-
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}`);
|
|
1337
1467
|
}
|
|
1338
1468
|
return;
|
|
1339
1469
|
}
|
|
@@ -1414,7 +1544,7 @@ async function main() {
|
|
|
1414
1544
|
}
|
|
1415
1545
|
return;
|
|
1416
1546
|
}
|
|
1417
|
-
if (cmd === "checkback" || cmd === "patience") {
|
|
1547
|
+
if (cmd === "checkback" || cmd === "patience" || cmd === "cb") {
|
|
1418
1548
|
const loaded = meshLoaded(profileArg);
|
|
1419
1549
|
const getLoaded = () => loaded;
|
|
1420
1550
|
const branch = buildCheckbackCommands(getLoaded);
|
|
@@ -1433,6 +1563,40 @@ async function main() {
|
|
|
1433
1563
|
}
|
|
1434
1564
|
return;
|
|
1435
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
|
+
}
|
|
1436
1600
|
if (cmd === "notify") {
|
|
1437
1601
|
const loaded = meshLoaded(profileArg);
|
|
1438
1602
|
const getLoaded = () => loaded;
|