@modootoday/pmcp 0.15.0 → 0.16.1
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/.agents/plugins/marketplace.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +22 -11
- package/dist/cli.js +472 -78
- package/dist/{embed-CVCEz2FH.d.ts → embed-DRROSD3F.d.ts} +1 -1
- package/dist/http.d.ts +5 -4
- package/dist/http.js +4 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/{server-DAcT89iv.d.ts → server-VWSY3Shw.d.ts} +2 -3
- package/dist/stdio.d.ts +1 -1
- package/dist/stdio.js +2 -2
- package/dist/tui-worker.js +271 -12
- package/docs/hosting.md +13 -0
- package/docs/terminal-workspace.md +102 -5
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/plugins/pmcp/.claude-plugin/plugin.json +1 -1
- package/plugins/pmcp/gemini-extension.json +1 -1
- package/plugins/pmcp/plugin.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1837,11 +1837,11 @@ function dockerPolicy(value) {
|
|
|
1837
1837
|
for (const [runtime2, value2] of entries) {
|
|
1838
1838
|
if (!Object.hasOwn(runtimeExecutables, runtime2))
|
|
1839
1839
|
throw new Error("unsupported_docker_runtime");
|
|
1840
|
-
const
|
|
1841
|
-
const executable =
|
|
1842
|
-
if (!isAbsolute10(executable) || posix5.normalize(executable) !== executable ||
|
|
1840
|
+
const command3 = strings2(value2, "docker_runtime_command");
|
|
1841
|
+
const executable = command3[0];
|
|
1842
|
+
if (!isAbsolute10(executable) || posix5.normalize(executable) !== executable || command3.some((argument) => /[\r\n\x1b]/.test(argument)))
|
|
1843
1843
|
throw new Error("invalid_docker_runtime_command");
|
|
1844
|
-
parsed[runtime2] =
|
|
1844
|
+
parsed[runtime2] = command3;
|
|
1845
1845
|
}
|
|
1846
1846
|
return {
|
|
1847
1847
|
schemaVersion: 1,
|
|
@@ -2962,14 +2962,14 @@ function bridgeName(nonce) {
|
|
|
2962
2962
|
function containerEntrypoint(policy, runtime2, nonce, privateProfile) {
|
|
2963
2963
|
const native2 = policy.commands[runtime2];
|
|
2964
2964
|
if (!native2) throw new Error("docker_runtime_command_not_granted");
|
|
2965
|
-
const
|
|
2965
|
+
const command3 = policy.egress?.bridgeExecutable ? [
|
|
2966
2966
|
policy.egress.bridgeExecutable,
|
|
2967
2967
|
`/state/${bridgeName(nonce)}`,
|
|
2968
2968
|
"--",
|
|
2969
2969
|
...native2
|
|
2970
2970
|
] : native2;
|
|
2971
2971
|
const profile = selectedProfile(policy, privateProfile, runtime2);
|
|
2972
|
-
if (!profile) return
|
|
2972
|
+
if (!profile) return command3;
|
|
2973
2973
|
return [
|
|
2974
2974
|
profile.lockExecutable,
|
|
2975
2975
|
"--exclusive",
|
|
@@ -2978,7 +2978,7 @@ function containerEntrypoint(policy, runtime2, nonce, privateProfile) {
|
|
|
2978
2978
|
"--conflict-exit-code",
|
|
2979
2979
|
"73",
|
|
2980
2980
|
`/state/${privateProfileLock}`,
|
|
2981
|
-
...
|
|
2981
|
+
...command3
|
|
2982
2982
|
];
|
|
2983
2983
|
}
|
|
2984
2984
|
var init_entrypoint = __esm({
|
|
@@ -5254,6 +5254,79 @@ var init_runtime2 = __esm({
|
|
|
5254
5254
|
}
|
|
5255
5255
|
});
|
|
5256
5256
|
|
|
5257
|
+
// src/tui/startup/diagnostics.ts
|
|
5258
|
+
function remediation(tools, userManagerAvailable) {
|
|
5259
|
+
const steps = [];
|
|
5260
|
+
if (tools.platform !== "linux")
|
|
5261
|
+
steps.push(
|
|
5262
|
+
"Use a qualified Linux host for the terminal workspace. Other PMCP CLI features do not require this host profile."
|
|
5263
|
+
);
|
|
5264
|
+
const missing = ["tmux", "flock", "systemctl", "systemdRun"].filter(
|
|
5265
|
+
(name) => !tools[name]
|
|
5266
|
+
);
|
|
5267
|
+
if (missing.length)
|
|
5268
|
+
steps.push(
|
|
5269
|
+
`Install the missing tmux, util-linux or systemd tools for your distribution and add them to PATH: ${missing.join(", ")}.`
|
|
5270
|
+
);
|
|
5271
|
+
if (!tools.nodeSupported)
|
|
5272
|
+
steps.push(
|
|
5273
|
+
"Select Node.js 22 or later through your existing version manager and check node --version in this terminal."
|
|
5274
|
+
);
|
|
5275
|
+
if (tools.supported && !userManagerAvailable)
|
|
5276
|
+
steps.push(
|
|
5277
|
+
"Check systemctl --user status in your login session and restore access to its user manager before launching. Doctor does not start or repair services."
|
|
5278
|
+
);
|
|
5279
|
+
return steps;
|
|
5280
|
+
}
|
|
5281
|
+
function inspectTerminalHost() {
|
|
5282
|
+
const tools = dependencies();
|
|
5283
|
+
let userManagerAvailable = false;
|
|
5284
|
+
let reason;
|
|
5285
|
+
try {
|
|
5286
|
+
if (!tools.supported) throw new Error("tui_dependencies_unavailable");
|
|
5287
|
+
assertNativeHost();
|
|
5288
|
+
userManagerAvailable = true;
|
|
5289
|
+
} catch (error) {
|
|
5290
|
+
reason = error instanceof Error ? error.message : "native_host_unavailable";
|
|
5291
|
+
}
|
|
5292
|
+
const runtimes = Object.entries(runtimeExecutables).map(
|
|
5293
|
+
([id2, executable]) => {
|
|
5294
|
+
const path = locateExecutable(executable);
|
|
5295
|
+
return {
|
|
5296
|
+
id: id2,
|
|
5297
|
+
executable,
|
|
5298
|
+
installed: Boolean(path),
|
|
5299
|
+
...path ? { path } : {},
|
|
5300
|
+
nativeAcceptance: "not-assessed",
|
|
5301
|
+
authentication: "not-inspected"
|
|
5302
|
+
};
|
|
5303
|
+
}
|
|
5304
|
+
);
|
|
5305
|
+
return {
|
|
5306
|
+
schemaVersion: 1,
|
|
5307
|
+
ok: true,
|
|
5308
|
+
...tools,
|
|
5309
|
+
supported: tools.supported && userManagerAvailable,
|
|
5310
|
+
userManagerAvailable,
|
|
5311
|
+
...reason ? { reason } : {},
|
|
5312
|
+
runtimes,
|
|
5313
|
+
qualification: "Prerequisite availability only; native behavior and cgroup delegation require separate qualification.",
|
|
5314
|
+
remediation: remediation(tools, userManagerAvailable),
|
|
5315
|
+
nextCommands: ["pmcp tui plan", "pmcp tui recovery"],
|
|
5316
|
+
providerInvoked: false,
|
|
5317
|
+
authenticationInspected: false
|
|
5318
|
+
};
|
|
5319
|
+
}
|
|
5320
|
+
var init_diagnostics = __esm({
|
|
5321
|
+
"src/tui/startup/diagnostics.ts"() {
|
|
5322
|
+
"use strict";
|
|
5323
|
+
init_runtime2();
|
|
5324
|
+
init_admission2();
|
|
5325
|
+
init_registry();
|
|
5326
|
+
init_executable();
|
|
5327
|
+
}
|
|
5328
|
+
});
|
|
5329
|
+
|
|
5257
5330
|
// src/tui/state/store.ts
|
|
5258
5331
|
import { randomUUID as randomUUID13 } from "crypto";
|
|
5259
5332
|
import {
|
|
@@ -5592,13 +5665,19 @@ var init_feedback = __esm({
|
|
|
5592
5665
|
init_store3();
|
|
5593
5666
|
init_store2();
|
|
5594
5667
|
hints = {
|
|
5595
|
-
startup_requires_recovery: "
|
|
5668
|
+
startup_requires_recovery: "Run pmcp tui recovery for saved ownership and exact inspection commands. No runtime was restarted.",
|
|
5596
5669
|
startup_group_paused: "The saved group is paused. Resume it explicitly through the harness CLI before reopening.",
|
|
5597
5670
|
startup_main_unavailable: "Inspect the saved main and recovery state. Stop the old group explicitly before using pmcp tui --new.",
|
|
5598
5671
|
startup_busy: "Another workspace launch is running. Wait and retry.",
|
|
5599
5672
|
startup_runtime_conflict: "The saved main uses another runtime. Stop the old group before creating a new workspace.",
|
|
5600
5673
|
workspace_already_running: "Reopen the existing workspace, or stop its exact owned group before using --new.",
|
|
5601
5674
|
runtime_executable_unavailable: "Install the selected native CLI on PATH, or choose an installed runtime with --runtime.",
|
|
5675
|
+
view_client_unavailable: "Open the view before using the worker menu, or run pmcp tui start-worker with --view and --runtime.",
|
|
5676
|
+
runtime_not_granted: "Choose a runtime granted by this owned group. Inspect the group before creating another workspace.",
|
|
5677
|
+
runtime_capacity_exceeded: "Stop an exact owned worker before adding another, or use the main session alone.",
|
|
5678
|
+
aggregate_memory_budget_exceeded: "Use fewer sessions or start a worker with an explicit smaller --memory-mb reservation.",
|
|
5679
|
+
group_not_ready: "Inspect the group and resume a paused group explicitly before adding a worker.",
|
|
5680
|
+
startup_group_not_ready: "Inspect the group and resume a paused group explicitly before adding a worker.",
|
|
5602
5681
|
control_connection_lost: "The native writer or lease disappeared. Inspect and release control before reconnecting.",
|
|
5603
5682
|
control_busy: "Another controller holds the lease. Release it explicitly before retrying.",
|
|
5604
5683
|
native_writer_active: "A native writer is still attached. Detach that writer before retrying.",
|
|
@@ -5619,6 +5698,20 @@ var init_feedback = __esm({
|
|
|
5619
5698
|
}
|
|
5620
5699
|
});
|
|
5621
5700
|
|
|
5701
|
+
// src/tui/presentation/target.ts
|
|
5702
|
+
function targetStatus(view) {
|
|
5703
|
+
const role = view.target === view.mainId ? "MAIN" : "WORKER";
|
|
5704
|
+
const phase2 = view.phase === "read-only" ? "OBSERVE" : phaseLabel(view.phase);
|
|
5705
|
+
const input = view.phase === "controlled" ? "INPUT ON" : "INPUT OFF";
|
|
5706
|
+
return `${role} ${view.target.slice(0, 8)} | ${phase2} | ${input}`;
|
|
5707
|
+
}
|
|
5708
|
+
var init_target = __esm({
|
|
5709
|
+
"src/tui/presentation/target.ts"() {
|
|
5710
|
+
"use strict";
|
|
5711
|
+
init_feedback();
|
|
5712
|
+
}
|
|
5713
|
+
});
|
|
5714
|
+
|
|
5622
5715
|
// src/tui/adapters/tmux/bindings.ts
|
|
5623
5716
|
function callback(view, file2, action, args = []) {
|
|
5624
5717
|
return [
|
|
@@ -5645,7 +5738,8 @@ function bindKeys(connection, view, file2) {
|
|
|
5645
5738
|
["b", "mailbox"],
|
|
5646
5739
|
["d", "detach"],
|
|
5647
5740
|
["!", "dismiss"],
|
|
5648
|
-
["g", "management"]
|
|
5741
|
+
["g", "management"],
|
|
5742
|
+
["n", "worker-menu"]
|
|
5649
5743
|
])
|
|
5650
5744
|
connection.command([
|
|
5651
5745
|
"bind-key",
|
|
@@ -5666,7 +5760,7 @@ function bindKeys(connection, view, file2) {
|
|
|
5666
5760
|
"bind-key",
|
|
5667
5761
|
"?",
|
|
5668
5762
|
"display-message",
|
|
5669
|
-
"m main; w/1-4 worker; c control; r release; h history; b mailbox; d detach; ! dismiss error; double Ctrl-g forwards native Ctrl-g"
|
|
5763
|
+
"m main; n add worker; w/1-4 worker; c control; r release; h history; b mailbox; d detach; ! dismiss error; double Ctrl-g forwards native Ctrl-g"
|
|
5670
5764
|
]);
|
|
5671
5765
|
connection.command([
|
|
5672
5766
|
"set-hook",
|
|
@@ -5694,7 +5788,7 @@ var init_view = __esm({
|
|
|
5694
5788
|
"src/tui/adapters/tmux/view.ts"() {
|
|
5695
5789
|
"use strict";
|
|
5696
5790
|
init_command();
|
|
5697
|
-
|
|
5791
|
+
init_target();
|
|
5698
5792
|
init_connection2();
|
|
5699
5793
|
init_bindings();
|
|
5700
5794
|
TmuxView = class {
|
|
@@ -5880,7 +5974,7 @@ var init_view = __esm({
|
|
|
5880
5974
|
"set-option",
|
|
5881
5975
|
"-g",
|
|
5882
5976
|
"status-right",
|
|
5883
|
-
`${
|
|
5977
|
+
`${targetStatus(view)}${failure2} | Ctrl-g ?`
|
|
5884
5978
|
]);
|
|
5885
5979
|
}
|
|
5886
5980
|
input(pane, enabled) {
|
|
@@ -5903,6 +5997,32 @@ var init_view = __esm({
|
|
|
5903
5997
|
clients() {
|
|
5904
5998
|
return this.connection.command(["list-clients", "-F", "#{client_pid}"]);
|
|
5905
5999
|
}
|
|
6000
|
+
workerMenu(view) {
|
|
6001
|
+
const pane = view.workerPane ?? view.mainPane;
|
|
6002
|
+
this.connection.assertOwned(pane);
|
|
6003
|
+
const popup = [
|
|
6004
|
+
"tmux",
|
|
6005
|
+
"-S",
|
|
6006
|
+
this.connection.socket,
|
|
6007
|
+
"display-popup",
|
|
6008
|
+
"-E",
|
|
6009
|
+
"-t",
|
|
6010
|
+
pane,
|
|
6011
|
+
"-w",
|
|
6012
|
+
"90%",
|
|
6013
|
+
"-h",
|
|
6014
|
+
"80%",
|
|
6015
|
+
this.shell([
|
|
6016
|
+
view.node,
|
|
6017
|
+
view.worker,
|
|
6018
|
+
"worker-menu",
|
|
6019
|
+
"--view",
|
|
6020
|
+
this.stateFile,
|
|
6021
|
+
"--callback"
|
|
6022
|
+
])
|
|
6023
|
+
];
|
|
6024
|
+
this.connection.command(["run-shell", "-b", popup.map(quote2).join(" ")]);
|
|
6025
|
+
}
|
|
5906
6026
|
copy(pane) {
|
|
5907
6027
|
this.connection.assertOwned(pane);
|
|
5908
6028
|
this.connection.command(["copy-mode", "-t", pane]);
|
|
@@ -6465,6 +6585,11 @@ var init_operations = __esm({
|
|
|
6465
6585
|
close: closeView,
|
|
6466
6586
|
check: checkControl,
|
|
6467
6587
|
dismiss: ({ view, file: file2 }) => dismissFailure(file2, view),
|
|
6588
|
+
"worker-menu": async (context) => {
|
|
6589
|
+
if (!context.renderer.clients()) throw new Error("view_client_unavailable");
|
|
6590
|
+
await releaseControl(context);
|
|
6591
|
+
context.renderer.workerMenu(context.view);
|
|
6592
|
+
},
|
|
6468
6593
|
management: async (context) => {
|
|
6469
6594
|
await releaseControl(context);
|
|
6470
6595
|
if (context.view.managementWindow) {
|
|
@@ -6488,10 +6613,9 @@ __export(invoke_exports2, {
|
|
|
6488
6613
|
invokeTui: () => invokeTui
|
|
6489
6614
|
});
|
|
6490
6615
|
async function invokeTui(invocation2) {
|
|
6491
|
-
if (
|
|
6616
|
+
if (["launch", "plan", "recovery", "start-worker"].includes(invocation2.action))
|
|
6492
6617
|
throw new Error("startup_requires_cli_context");
|
|
6493
|
-
if (invocation2.action === "doctor")
|
|
6494
|
-
return { schemaVersion: 1, ok: true, ...dependencies() };
|
|
6618
|
+
if (invocation2.action === "doctor") return inspectTerminalHost();
|
|
6495
6619
|
if (invocation2.action === "create") return createView(invocation2.create);
|
|
6496
6620
|
if (invocation2.action === "inspect")
|
|
6497
6621
|
return operate("inspect", invocation2.viewFile);
|
|
@@ -6529,7 +6653,7 @@ function failedInvocation(action, error) {
|
|
|
6529
6653
|
var init_invoke2 = __esm({
|
|
6530
6654
|
"src/tui/application/invoke.ts"() {
|
|
6531
6655
|
"use strict";
|
|
6532
|
-
|
|
6656
|
+
init_diagnostics();
|
|
6533
6657
|
init_lock();
|
|
6534
6658
|
init_create();
|
|
6535
6659
|
init_operations();
|
|
@@ -6538,6 +6662,31 @@ var init_invoke2 = __esm({
|
|
|
6538
6662
|
}
|
|
6539
6663
|
});
|
|
6540
6664
|
|
|
6665
|
+
// src/tui/application/worker-start.ts
|
|
6666
|
+
var worker_start_exports = {};
|
|
6667
|
+
__export(worker_start_exports, {
|
|
6668
|
+
startViewWorker: () => startViewWorker
|
|
6669
|
+
});
|
|
6670
|
+
async function startViewWorker(file2, runtime2, memoryMb) {
|
|
6671
|
+
const { view, common: common2 } = openView(file2);
|
|
6672
|
+
if (view.state !== "open") throw new Error("view_closed");
|
|
6673
|
+
const observed = await common2.snapshot();
|
|
6674
|
+
if (observed.group.state !== "ready") throw new Error("group_not_ready");
|
|
6675
|
+
const main2 = observed.sessions.find(
|
|
6676
|
+
(session) => session.id === view.mainId && session.role === "main"
|
|
6677
|
+
);
|
|
6678
|
+
if (!main2?.alive) throw new Error("startup_main_unavailable");
|
|
6679
|
+
return common2.call("session", "start", {
|
|
6680
|
+
input: { role: "worker", runtime: runtime2, memoryMb: memoryMb ?? main2.memoryMb }
|
|
6681
|
+
});
|
|
6682
|
+
}
|
|
6683
|
+
var init_worker_start = __esm({
|
|
6684
|
+
"src/tui/application/worker-start.ts"() {
|
|
6685
|
+
"use strict";
|
|
6686
|
+
init_context2();
|
|
6687
|
+
}
|
|
6688
|
+
});
|
|
6689
|
+
|
|
6541
6690
|
// src/tui/startup/config.ts
|
|
6542
6691
|
import { realpathSync as realpathSync17 } from "fs";
|
|
6543
6692
|
import { resolve as resolve19 } from "path";
|
|
@@ -6664,6 +6813,160 @@ var init_state = __esm({
|
|
|
6664
6813
|
}
|
|
6665
6814
|
});
|
|
6666
6815
|
|
|
6816
|
+
// src/tui/startup/worker.ts
|
|
6817
|
+
var worker_exports = {};
|
|
6818
|
+
__export(worker_exports, {
|
|
6819
|
+
startWorkspaceWorker: () => startWorkspaceWorker
|
|
6820
|
+
});
|
|
6821
|
+
async function startWorkspaceWorker(request3, runtime2, memoryMb) {
|
|
6822
|
+
if (!Object.hasOwn(runtimeExecutables, runtime2))
|
|
6823
|
+
throw new Error("unsupported_runtime");
|
|
6824
|
+
const settings2 = startupSettings({
|
|
6825
|
+
cwd: request3.cwd,
|
|
6826
|
+
config: request3.config
|
|
6827
|
+
});
|
|
6828
|
+
const state = readStartup(
|
|
6829
|
+
startupFile(settings2.projectRoot),
|
|
6830
|
+
settings2.projectRoot
|
|
6831
|
+
);
|
|
6832
|
+
if (!state || state.phase !== "ready" || !state.groupFile || !state.generation)
|
|
6833
|
+
throw new Error("startup_requires_recovery");
|
|
6834
|
+
const store = new GroupStore(state.groupFile);
|
|
6835
|
+
const group = store.state.group;
|
|
6836
|
+
if (group.projectRoot !== settings2.projectRoot)
|
|
6837
|
+
throw new Error("startup_project_mismatch");
|
|
6838
|
+
if (group.generation !== state.generation)
|
|
6839
|
+
throw new Error("stale_group_generation");
|
|
6840
|
+
if (group.state === "paused") throw new Error("startup_group_paused");
|
|
6841
|
+
if (group.state !== "ready") throw new Error("startup_group_not_ready");
|
|
6842
|
+
if (group.profile === "native" && !locateExecutable(runtimeExecutables[runtime2], request3.cwd))
|
|
6843
|
+
throw new Error("runtime_executable_unavailable");
|
|
6844
|
+
const observed = await invoke({
|
|
6845
|
+
family: "session",
|
|
6846
|
+
action: "list",
|
|
6847
|
+
groupFile: store.path
|
|
6848
|
+
});
|
|
6849
|
+
if (observed.ok !== true) return observed;
|
|
6850
|
+
const sessions = observed.sessions;
|
|
6851
|
+
if (!sessions.some((session) => session.role === "main" && session.alive))
|
|
6852
|
+
throw new Error("startup_main_unavailable");
|
|
6853
|
+
return invoke({
|
|
6854
|
+
family: "session",
|
|
6855
|
+
action: "start",
|
|
6856
|
+
groupFile: store.path,
|
|
6857
|
+
generation: group.generation,
|
|
6858
|
+
input: {
|
|
6859
|
+
runtime: runtime2,
|
|
6860
|
+
role: "worker",
|
|
6861
|
+
memoryMb: memoryMb ?? settings2.sessionMemoryMb
|
|
6862
|
+
}
|
|
6863
|
+
});
|
|
6864
|
+
}
|
|
6865
|
+
var init_worker = __esm({
|
|
6866
|
+
"src/tui/startup/worker.ts"() {
|
|
6867
|
+
"use strict";
|
|
6868
|
+
init_invoke();
|
|
6869
|
+
init_store2();
|
|
6870
|
+
init_registry();
|
|
6871
|
+
init_executable();
|
|
6872
|
+
init_config3();
|
|
6873
|
+
init_state();
|
|
6874
|
+
}
|
|
6875
|
+
});
|
|
6876
|
+
|
|
6877
|
+
// src/tui/startup/recovery.ts
|
|
6878
|
+
var recovery_exports = {};
|
|
6879
|
+
__export(recovery_exports, {
|
|
6880
|
+
inspectStartupRecovery: () => inspectStartupRecovery
|
|
6881
|
+
});
|
|
6882
|
+
function command2(args) {
|
|
6883
|
+
return ["pmcp", ...args].map(quote2).join(" ");
|
|
6884
|
+
}
|
|
6885
|
+
function inspectStartupRecovery(request3) {
|
|
6886
|
+
const settings2 = startupSettings(request3);
|
|
6887
|
+
const checkpoint = startupFile(settings2.projectRoot);
|
|
6888
|
+
const state = readStartup(checkpoint, settings2.projectRoot);
|
|
6889
|
+
const config = settings2.configFile ? ["--config", settings2.configFile] : [];
|
|
6890
|
+
const common2 = {
|
|
6891
|
+
schemaVersion: 1,
|
|
6892
|
+
ok: true,
|
|
6893
|
+
checkpoint,
|
|
6894
|
+
projectRoot: settings2.projectRoot,
|
|
6895
|
+
providerInvoked: false,
|
|
6896
|
+
runtimeRestarted: false,
|
|
6897
|
+
inputReplayed: false,
|
|
6898
|
+
observedNativeProcesses: false
|
|
6899
|
+
};
|
|
6900
|
+
if (!state)
|
|
6901
|
+
return {
|
|
6902
|
+
...common2,
|
|
6903
|
+
status: "not-started",
|
|
6904
|
+
hint: "No saved workspace exists. Start explicitly from an interactive terminal.",
|
|
6905
|
+
commands: [command2(["tui", ...config])]
|
|
6906
|
+
};
|
|
6907
|
+
if (!state.groupFile || !state.generation)
|
|
6908
|
+
return {
|
|
6909
|
+
...common2,
|
|
6910
|
+
status: "manual-inspection",
|
|
6911
|
+
phase: state.phase,
|
|
6912
|
+
hint: "Creation stopped before a group reference was saved. Preserve this checkpoint and inspect owned launch evidence before changing it. No group ownership can be inferred from a matching project path.",
|
|
6913
|
+
commands: []
|
|
6914
|
+
};
|
|
6915
|
+
const store = new GroupStore(state.groupFile);
|
|
6916
|
+
const group = store.state.group;
|
|
6917
|
+
if (group.projectRoot !== settings2.projectRoot)
|
|
6918
|
+
throw new Error("startup_project_mismatch");
|
|
6919
|
+
if (group.generation !== state.generation)
|
|
6920
|
+
throw new Error("stale_group_generation");
|
|
6921
|
+
const target2 = ["--group-file", store.path];
|
|
6922
|
+
const generation = ["--generation", group.generation];
|
|
6923
|
+
const inspect = command2([
|
|
6924
|
+
"harness",
|
|
6925
|
+
"recovery",
|
|
6926
|
+
"inspect",
|
|
6927
|
+
...target2,
|
|
6928
|
+
"--include-starts"
|
|
6929
|
+
]);
|
|
6930
|
+
const status = group.state === "ready" ? state.phase : group.state;
|
|
6931
|
+
const commands = [inspect];
|
|
6932
|
+
let hint = "Inspect actual processes and outstanding starts before any recovery action.";
|
|
6933
|
+
if (group.state === "paused") {
|
|
6934
|
+
hint = "The group is paused. Keep it paused until you explicitly decide to resume it.";
|
|
6935
|
+
commands.push(
|
|
6936
|
+
command2(["harness", "group", "resume", ...target2, ...generation])
|
|
6937
|
+
);
|
|
6938
|
+
}
|
|
6939
|
+
if (group.state === "stopped") {
|
|
6940
|
+
hint = "The saved group is stopped. An explicitly confirmed fresh launch can create a replacement.";
|
|
6941
|
+
commands.push(command2(["tui", "--new", ...config]));
|
|
6942
|
+
}
|
|
6943
|
+
if (group.state === "ready" && !["ready", "view-pending"].includes(state.phase)) {
|
|
6944
|
+
hint = "Startup is incomplete. Inspect pending starts; stop the exact owned group before an explicit fresh launch.";
|
|
6945
|
+
commands.push(
|
|
6946
|
+
command2(["harness", "group", "stop", ...target2, ...generation])
|
|
6947
|
+
);
|
|
6948
|
+
}
|
|
6949
|
+
return {
|
|
6950
|
+
...common2,
|
|
6951
|
+
status,
|
|
6952
|
+
phase: state.phase,
|
|
6953
|
+
groupFile: store.path,
|
|
6954
|
+
generation: group.generation,
|
|
6955
|
+
hint,
|
|
6956
|
+
commands,
|
|
6957
|
+
commandsRequireExplicitAction: true
|
|
6958
|
+
};
|
|
6959
|
+
}
|
|
6960
|
+
var init_recovery2 = __esm({
|
|
6961
|
+
"src/tui/startup/recovery.ts"() {
|
|
6962
|
+
"use strict";
|
|
6963
|
+
init_store2();
|
|
6964
|
+
init_command();
|
|
6965
|
+
init_config3();
|
|
6966
|
+
init_state();
|
|
6967
|
+
}
|
|
6968
|
+
});
|
|
6969
|
+
|
|
6667
6970
|
// src/tui/startup/host.ts
|
|
6668
6971
|
var host_exports = {};
|
|
6669
6972
|
__export(host_exports, {
|
|
@@ -6767,13 +7070,48 @@ var init_lock2 = __esm({
|
|
|
6767
7070
|
}
|
|
6768
7071
|
});
|
|
6769
7072
|
|
|
7073
|
+
// src/tui/presentation/runtime-choice.ts
|
|
7074
|
+
import { createInterface as createInterface2 } from "readline/promises";
|
|
7075
|
+
async function chooseRuntime(prompt, choices, preferred) {
|
|
7076
|
+
if (!choices.length) throw new Error("runtime_executable_unavailable");
|
|
7077
|
+
const fallback = Math.max(choices.indexOf(preferred), 0);
|
|
7078
|
+
process.stderr.write(
|
|
7079
|
+
`${choices.map((runtime2, index) => `${index + 1}. ${runtime2}`).join("\n")}
|
|
7080
|
+
`
|
|
7081
|
+
);
|
|
7082
|
+
while (true) {
|
|
7083
|
+
const answer = (await prompt.question(
|
|
7084
|
+
`Runtime [1-${choices.length}, Enter=${fallback + 1}, q=cancel] `
|
|
7085
|
+
)).trim();
|
|
7086
|
+
if (answer === "q") return void 0;
|
|
7087
|
+
if (answer === "") return choices[fallback];
|
|
7088
|
+
if (!/^\d+$/.test(answer)) continue;
|
|
7089
|
+
const index = Number(answer) - 1;
|
|
7090
|
+
if (Number.isSafeInteger(index) && index >= 0 && index < choices.length)
|
|
7091
|
+
return choices[index];
|
|
7092
|
+
}
|
|
7093
|
+
}
|
|
7094
|
+
async function confirmRuntimeStart(prompt, runtime2) {
|
|
7095
|
+
const answer = await prompt.question(
|
|
7096
|
+
`Start ${runtime2}? [Enter=start, q=cancel] `
|
|
7097
|
+
);
|
|
7098
|
+
return answer.trim() === "";
|
|
7099
|
+
}
|
|
7100
|
+
function terminalPrompt() {
|
|
7101
|
+
return createInterface2({ input: process.stdin, output: process.stderr });
|
|
7102
|
+
}
|
|
7103
|
+
var init_runtime_choice = __esm({
|
|
7104
|
+
"src/tui/presentation/runtime-choice.ts"() {
|
|
7105
|
+
"use strict";
|
|
7106
|
+
}
|
|
7107
|
+
});
|
|
7108
|
+
|
|
6770
7109
|
// src/tui/startup/entry.ts
|
|
6771
7110
|
var entry_exports = {};
|
|
6772
7111
|
__export(entry_exports, {
|
|
6773
7112
|
launchStartup: () => launchStartup,
|
|
6774
7113
|
planStartup: () => planStartup
|
|
6775
7114
|
});
|
|
6776
|
-
import { createInterface as createInterface2 } from "readline/promises";
|
|
6777
7115
|
function planStartup(request3) {
|
|
6778
7116
|
const settings2 = startupSettings(request3);
|
|
6779
7117
|
const state = readStartup(
|
|
@@ -6795,26 +7133,41 @@ function planStartup(request3) {
|
|
|
6795
7133
|
}
|
|
6796
7134
|
async function launchStartup(request3, confirmed) {
|
|
6797
7135
|
requireTerminal();
|
|
6798
|
-
|
|
7136
|
+
let settings2 = startupSettings(request3);
|
|
6799
7137
|
const state = readStartup(
|
|
6800
7138
|
startupFile(settings2.projectRoot),
|
|
6801
7139
|
settings2.projectRoot
|
|
6802
7140
|
);
|
|
6803
7141
|
const starting = (!state || request3.fresh) && !settings2.groupFile;
|
|
6804
7142
|
if (starting) {
|
|
7143
|
+
if (!confirmed) {
|
|
7144
|
+
const prompt = terminalPrompt();
|
|
7145
|
+
try {
|
|
7146
|
+
let runtime2 = settings2.runtime;
|
|
7147
|
+
process.stderr.write(`PMCP MAIN | ${settings2.projectRoot}
|
|
7148
|
+
`);
|
|
7149
|
+
if (!request3.runtime) {
|
|
7150
|
+
const installed = settings2.allowedRuntimes.filter(
|
|
7151
|
+
(id2) => locateExecutable(runtimeExecutables[id2], request3.cwd)
|
|
7152
|
+
);
|
|
7153
|
+
const selected = await chooseRuntime(prompt, installed, runtime2);
|
|
7154
|
+
if (!selected) return cancelledStart();
|
|
7155
|
+
runtime2 = selected;
|
|
7156
|
+
}
|
|
7157
|
+
if (!await confirmRuntimeStart(prompt, runtime2))
|
|
7158
|
+
return cancelledStart();
|
|
7159
|
+
request3 = { ...request3, runtime: runtime2 };
|
|
7160
|
+
settings2 = startupSettings(request3);
|
|
7161
|
+
} finally {
|
|
7162
|
+
prompt.close();
|
|
7163
|
+
}
|
|
7164
|
+
}
|
|
6805
7165
|
if (!locateExecutable(runtimeExecutables[settings2.runtime], request3.cwd))
|
|
6806
7166
|
throw new Error("runtime_executable_unavailable");
|
|
6807
7167
|
process.stderr.write(
|
|
6808
7168
|
`PMCP main: ${settings2.runtime} | ${settings2.projectRoot}
|
|
6809
7169
|
`
|
|
6810
7170
|
);
|
|
6811
|
-
if (!confirmed && !await confirmStart(settings2.runtime))
|
|
6812
|
-
return {
|
|
6813
|
-
schemaVersion: 1,
|
|
6814
|
-
ok: true,
|
|
6815
|
-
cancelled: true,
|
|
6816
|
-
providerInvoked: false
|
|
6817
|
-
};
|
|
6818
7171
|
}
|
|
6819
7172
|
const prepared = serializedStartup(request3);
|
|
6820
7173
|
if (prepared.ok !== true) return prepared;
|
|
@@ -6824,19 +7177,13 @@ async function launchStartup(request3, confirmed) {
|
|
|
6824
7177
|
input: {}
|
|
6825
7178
|
});
|
|
6826
7179
|
}
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
`Start ${runtime2}? [Enter=start, q=cancel] `
|
|
6835
|
-
);
|
|
6836
|
-
return answer.trim() === "";
|
|
6837
|
-
} finally {
|
|
6838
|
-
prompt.close();
|
|
6839
|
-
}
|
|
7180
|
+
function cancelledStart() {
|
|
7181
|
+
return {
|
|
7182
|
+
schemaVersion: 1,
|
|
7183
|
+
ok: true,
|
|
7184
|
+
cancelled: true,
|
|
7185
|
+
providerInvoked: false
|
|
7186
|
+
};
|
|
6840
7187
|
}
|
|
6841
7188
|
var init_entry2 = __esm({
|
|
6842
7189
|
"src/tui/startup/entry.ts"() {
|
|
@@ -6848,6 +7195,7 @@ var init_entry2 = __esm({
|
|
|
6848
7195
|
init_state();
|
|
6849
7196
|
init_host();
|
|
6850
7197
|
init_lock2();
|
|
7198
|
+
init_runtime_choice();
|
|
6851
7199
|
}
|
|
6852
7200
|
});
|
|
6853
7201
|
|
|
@@ -6904,15 +7252,15 @@ function one(args, name) {
|
|
|
6904
7252
|
function many(args, name) {
|
|
6905
7253
|
return args.options.get(name) ?? [];
|
|
6906
7254
|
}
|
|
6907
|
-
function printCommandHelp(ui,
|
|
6908
|
-
ui.heading(`pmcp ${
|
|
6909
|
-
ui.line(` ${
|
|
7255
|
+
function printCommandHelp(ui, command3) {
|
|
7256
|
+
ui.heading(`pmcp ${command3.name}`);
|
|
7257
|
+
ui.line(` ${command3.describe}`);
|
|
6910
7258
|
ui.line();
|
|
6911
|
-
ui.line(` ${ui.paint(
|
|
6912
|
-
if (
|
|
7259
|
+
ui.line(` ${ui.paint(command3.usage, "dim")}`);
|
|
7260
|
+
if (command3.options && command3.options.length > 0) {
|
|
6913
7261
|
ui.line();
|
|
6914
7262
|
ui.table(
|
|
6915
|
-
|
|
7263
|
+
command3.options.map((option) => [
|
|
6916
7264
|
`--${option.name}${option.placeholder ? ` ${option.placeholder}` : ""}`,
|
|
6917
7265
|
option.describe
|
|
6918
7266
|
])
|
|
@@ -6923,7 +7271,7 @@ function printCommandHelp(ui, command2) {
|
|
|
6923
7271
|
function printHelp(ui, commands, notImplemented) {
|
|
6924
7272
|
ui.heading("pmcp \u2014 the skills your installed packages ship");
|
|
6925
7273
|
ui.line();
|
|
6926
|
-
ui.table(commands.map((
|
|
7274
|
+
ui.table(commands.map((command3) => [command3.name, command3.describe]));
|
|
6927
7275
|
ui.line();
|
|
6928
7276
|
ui.line(
|
|
6929
7277
|
" With no command, pmcp opens a terminal workspace on a supported TTY."
|
|
@@ -7038,7 +7386,7 @@ init_entry();
|
|
|
7038
7386
|
|
|
7039
7387
|
// src/intent.ts
|
|
7040
7388
|
function normaliseIntent(intent) {
|
|
7041
|
-
return intent.toLowerCase().replaceAll(/[^\p{L}\p{N}\s]/gu, " ").split(/\s+/u).filter(Boolean).join(" ");
|
|
7389
|
+
return intent.normalize("NFC").toLowerCase().replaceAll(/[^\p{L}\p{N}\s]/gu, " ").split(/\s+/u).filter(Boolean).join(" ");
|
|
7042
7390
|
}
|
|
7043
7391
|
|
|
7044
7392
|
// src/cache.ts
|
|
@@ -9511,7 +9859,7 @@ function registerMailboxTools(server, service) {
|
|
|
9511
9859
|
|
|
9512
9860
|
// src/mcp.ts
|
|
9513
9861
|
var SERVER_NAME = "pmcp";
|
|
9514
|
-
var SERVER_VERSION = "0.
|
|
9862
|
+
var SERVER_VERSION = "0.16.1";
|
|
9515
9863
|
function registerSkillTools(server, tools) {
|
|
9516
9864
|
registerCatalogTool(server, tools);
|
|
9517
9865
|
registerFindTool(server, tools);
|
|
@@ -12131,8 +12479,8 @@ var denied = () => ({
|
|
|
12131
12479
|
decision: "deny",
|
|
12132
12480
|
reason: "Shell guard failed validation or execution"
|
|
12133
12481
|
});
|
|
12134
|
-
function guardPath(root,
|
|
12135
|
-
const script =
|
|
12482
|
+
function guardPath(root, command3) {
|
|
12483
|
+
const script = command3[0]?.startsWith(".agents/guards/") ? command3[0] : command3[1];
|
|
12136
12484
|
if (!script?.startsWith(".agents/guards/")) {
|
|
12137
12485
|
throw new Error("Hook command must execute a script under .agents/guards/");
|
|
12138
12486
|
}
|
|
@@ -12190,10 +12538,10 @@ function evaluateShellHook(root, policy, tool, payload) {
|
|
|
12190
12538
|
if (!shellNames[tool].includes(name)) {
|
|
12191
12539
|
return { decision: "allow" };
|
|
12192
12540
|
}
|
|
12193
|
-
const
|
|
12541
|
+
const command3 = scalar(
|
|
12194
12542
|
input[tool === "antigravity" ? "CommandLine" : "command"]
|
|
12195
12543
|
);
|
|
12196
|
-
if (
|
|
12544
|
+
if (command3 === void 0 || command3.length > 65536) {
|
|
12197
12545
|
return denied();
|
|
12198
12546
|
}
|
|
12199
12547
|
const cwd = scalar(input["Cwd"]) ?? scalar(value["cwd"]) ?? root;
|
|
@@ -12214,7 +12562,7 @@ function evaluateShellHook(root, policy, tool, payload) {
|
|
|
12214
12562
|
input: JSON.stringify({
|
|
12215
12563
|
runtime: tool,
|
|
12216
12564
|
event: "before_shell",
|
|
12217
|
-
command:
|
|
12565
|
+
command: command3,
|
|
12218
12566
|
cwd
|
|
12219
12567
|
}),
|
|
12220
12568
|
encoding: "utf8",
|
|
@@ -12402,11 +12750,11 @@ function hookOutputs(spec) {
|
|
|
12402
12750
|
continue;
|
|
12403
12751
|
}
|
|
12404
12752
|
const target2 = native[tool];
|
|
12405
|
-
const
|
|
12753
|
+
const command3 = `d="$PWD"; while [ ! -f "$d/pmcp.toml" ]; do [ "$d" = / ] && exit 1; d=$(dirname "$d"); done; exec node "$d/${ADAPTER}" --pmcp-shell-hook ${tool} "$d/${policyFile}" ${integrity2}`;
|
|
12406
12754
|
const timeout = tool === "gemini" ? hook.timeoutMs + 2e3 : Math.ceil(hook.timeoutMs / 1e3) + 2;
|
|
12407
12755
|
const value = {
|
|
12408
12756
|
matcher: target2.matcher,
|
|
12409
|
-
hooks: [{ type: "command", command:
|
|
12757
|
+
hooks: [{ type: "command", command: command3, timeout }]
|
|
12410
12758
|
};
|
|
12411
12759
|
const path = `${target2.file}#${target2.key.join(".")}`;
|
|
12412
12760
|
const entry2 = desired.get(path) ?? {
|
|
@@ -13120,13 +13468,13 @@ function readHooks(path, root, raw) {
|
|
|
13120
13468
|
return fail2("unknown shell entry field");
|
|
13121
13469
|
}
|
|
13122
13470
|
const name = entry2["name"];
|
|
13123
|
-
const
|
|
13471
|
+
const command3 = entry2["command"];
|
|
13124
13472
|
const targets = entry2["targets"];
|
|
13125
13473
|
const timeoutMs = entry2["timeout_ms"] ?? 15e3;
|
|
13126
13474
|
if (typeof name !== "string" || !/^[a-z0-9][a-z0-9-]*$/u.test(name) || names.has(name)) {
|
|
13127
13475
|
return fail2("shell names must be unique lowercase names");
|
|
13128
13476
|
}
|
|
13129
|
-
if (!Array.isArray(
|
|
13477
|
+
if (!Array.isArray(command3) || command3.length === 0 || !command3.every(
|
|
13130
13478
|
(part) => typeof part === "string" && part.length > 0 && !part.includes("\0")
|
|
13131
13479
|
)) {
|
|
13132
13480
|
return fail2("command must be a nonempty argument list");
|
|
@@ -13140,7 +13488,7 @@ function readHooks(path, root, raw) {
|
|
|
13140
13488
|
return fail2("timeout_ms must be an integer from 100 to 60000");
|
|
13141
13489
|
}
|
|
13142
13490
|
try {
|
|
13143
|
-
guardPath(root,
|
|
13491
|
+
guardPath(root, command3);
|
|
13144
13492
|
} catch (error) {
|
|
13145
13493
|
return fail2(
|
|
13146
13494
|
error instanceof Error ? error.message : "invalid guard path"
|
|
@@ -13149,7 +13497,7 @@ function readHooks(path, root, raw) {
|
|
|
13149
13497
|
names.add(name);
|
|
13150
13498
|
return {
|
|
13151
13499
|
name,
|
|
13152
|
-
command:
|
|
13500
|
+
command: command3,
|
|
13153
13501
|
targets,
|
|
13154
13502
|
timeoutMs
|
|
13155
13503
|
};
|
|
@@ -13372,13 +13720,13 @@ function readMcp(path, value) {
|
|
|
13372
13720
|
fail(path, where, `unknown field ${key}`);
|
|
13373
13721
|
}
|
|
13374
13722
|
}
|
|
13375
|
-
const
|
|
13723
|
+
const command3 = entry2["command"];
|
|
13376
13724
|
const url = entry2["url"];
|
|
13377
|
-
if (
|
|
13725
|
+
if (command3 === void 0 === (url === void 0)) {
|
|
13378
13726
|
fail(path, where, "provide exactly one of command or url");
|
|
13379
13727
|
}
|
|
13380
13728
|
for (const [key, item] of [
|
|
13381
|
-
["command",
|
|
13729
|
+
["command", command3],
|
|
13382
13730
|
["url", url],
|
|
13383
13731
|
["cwd", entry2["cwd"]]
|
|
13384
13732
|
]) {
|
|
@@ -13476,7 +13824,7 @@ function readMcp(path, value) {
|
|
|
13476
13824
|
fail(path, where, "mailbox must be a boolean");
|
|
13477
13825
|
}
|
|
13478
13826
|
servers[alias] = {
|
|
13479
|
-
...typeof
|
|
13827
|
+
...typeof command3 === "string" ? { command: command3 } : { url },
|
|
13480
13828
|
args: list(path, `${where} args`, entry2["args"], false),
|
|
13481
13829
|
env,
|
|
13482
13830
|
...envVars.length > 0 ? { envVars } : {},
|
|
@@ -13879,8 +14227,8 @@ import { spawnSync as spawnSync3 } from "child_process";
|
|
|
13879
14227
|
import { existsSync as existsSync21, readFileSync as readFileSync28 } from "fs";
|
|
13880
14228
|
import { join as join25 } from "path";
|
|
13881
14229
|
import { parse as parse8 } from "smol-toml";
|
|
13882
|
-
var spawnRunner = (
|
|
13883
|
-
const result = spawnSync3(
|
|
14230
|
+
var spawnRunner = (command3, args, cwd, env) => {
|
|
14231
|
+
const result = spawnSync3(command3, [...args], {
|
|
13884
14232
|
cwd,
|
|
13885
14233
|
...env ? { env: { ...process.env, ...env } } : {},
|
|
13886
14234
|
encoding: "utf8",
|
|
@@ -15137,6 +15485,11 @@ var tuiOptions = [
|
|
|
15137
15485
|
},
|
|
15138
15486
|
{ name: "rows", describe: "Terminal rows (12\u20131000)", placeholder: "<count>" },
|
|
15139
15487
|
{ name: "index", describe: "Worker dock index", placeholder: "<count>" },
|
|
15488
|
+
{
|
|
15489
|
+
name: "memory-mb",
|
|
15490
|
+
describe: "Worker memory reservation",
|
|
15491
|
+
placeholder: "<count>"
|
|
15492
|
+
},
|
|
15140
15493
|
{
|
|
15141
15494
|
name: "confirm-session",
|
|
15142
15495
|
describe: "Exact target ID for stop",
|
|
@@ -15149,7 +15502,7 @@ var tuiOptions = [
|
|
|
15149
15502
|
},
|
|
15150
15503
|
{
|
|
15151
15504
|
name: "runtime",
|
|
15152
|
-
describe: "
|
|
15505
|
+
describe: "Native runtime ID for main launch or worker start",
|
|
15153
15506
|
placeholder: "<runtime>"
|
|
15154
15507
|
},
|
|
15155
15508
|
{
|
|
@@ -15171,6 +15524,8 @@ var tuiOptions = [
|
|
|
15171
15524
|
var allowed2 = {
|
|
15172
15525
|
launch: ["config", "runtime", "yes", "new"],
|
|
15173
15526
|
plan: ["config", "runtime"],
|
|
15527
|
+
recovery: ["config"],
|
|
15528
|
+
"start-worker": ["config", "view", "runtime", "memory-mb"],
|
|
15174
15529
|
doctor: [],
|
|
15175
15530
|
create: ["group-file", "columns", "rows", "config", "actor-file"],
|
|
15176
15531
|
inspect: ["view"],
|
|
@@ -15188,6 +15543,7 @@ var allowed2 = {
|
|
|
15188
15543
|
close: ["view"],
|
|
15189
15544
|
dismiss: ["view"],
|
|
15190
15545
|
management: ["view"],
|
|
15546
|
+
"worker-menu": ["view"],
|
|
15191
15547
|
check: ["view"]
|
|
15192
15548
|
};
|
|
15193
15549
|
function parseTui(args) {
|
|
@@ -15212,7 +15568,23 @@ function parseTui(args) {
|
|
|
15212
15568
|
return Number(value);
|
|
15213
15569
|
};
|
|
15214
15570
|
if (action === "doctor") return { action, input: {} };
|
|
15215
|
-
if (action === "
|
|
15571
|
+
if (action === "start-worker") {
|
|
15572
|
+
const config = one(args, "config");
|
|
15573
|
+
const viewFile = one(args, "view");
|
|
15574
|
+
if (config && viewFile)
|
|
15575
|
+
throw new ArgumentError("Choose --config or --view for worker start");
|
|
15576
|
+
return {
|
|
15577
|
+
action,
|
|
15578
|
+
viewFile,
|
|
15579
|
+
input: {},
|
|
15580
|
+
startup: {
|
|
15581
|
+
config,
|
|
15582
|
+
runtime: required2("runtime"),
|
|
15583
|
+
memoryMb: number("memory-mb")
|
|
15584
|
+
}
|
|
15585
|
+
};
|
|
15586
|
+
}
|
|
15587
|
+
if (action === "launch" || action === "plan" || action === "recovery")
|
|
15216
15588
|
return {
|
|
15217
15589
|
action,
|
|
15218
15590
|
input: {},
|
|
@@ -15263,14 +15635,36 @@ function parseTui(args) {
|
|
|
15263
15635
|
var tuiCommand = {
|
|
15264
15636
|
name: "tui",
|
|
15265
15637
|
describe: "Open a native terminal workspace with optional configuration",
|
|
15266
|
-
usage: "pmcp tui [--config <file>] [--runtime <id>] | plan | doctor | operation --view <file>",
|
|
15638
|
+
usage: "pmcp tui [--config <file>] [--runtime <id>] | plan | recovery | doctor | start-worker --runtime <id> | operation --view <file>",
|
|
15267
15639
|
options: tuiOptions,
|
|
15268
15640
|
async run(context) {
|
|
15269
15641
|
const invocation2 = parseTui(context.args);
|
|
15270
15642
|
const { invokeTui: invokeTui2, failedInvocation: failedInvocation2 } = await Promise.resolve().then(() => (init_invoke2(), invoke_exports2));
|
|
15271
15643
|
try {
|
|
15272
15644
|
let receipt;
|
|
15273
|
-
if (invocation2.action === "
|
|
15645
|
+
if (invocation2.action === "start-worker") {
|
|
15646
|
+
if (invocation2.viewFile) {
|
|
15647
|
+
const { startViewWorker: startViewWorker2 } = await Promise.resolve().then(() => (init_worker_start(), worker_start_exports));
|
|
15648
|
+
receipt = await startViewWorker2(
|
|
15649
|
+
invocation2.viewFile,
|
|
15650
|
+
invocation2.startup.runtime,
|
|
15651
|
+
invocation2.startup?.memoryMb
|
|
15652
|
+
);
|
|
15653
|
+
} else {
|
|
15654
|
+
const { startWorkspaceWorker: startWorkspaceWorker2 } = await Promise.resolve().then(() => (init_worker(), worker_exports));
|
|
15655
|
+
receipt = await startWorkspaceWorker2(
|
|
15656
|
+
{ config: invocation2.startup?.config, cwd: context.cwd },
|
|
15657
|
+
invocation2.startup.runtime,
|
|
15658
|
+
invocation2.startup?.memoryMb
|
|
15659
|
+
);
|
|
15660
|
+
}
|
|
15661
|
+
} else if (invocation2.action === "recovery") {
|
|
15662
|
+
const { inspectStartupRecovery: inspectStartupRecovery2 } = await Promise.resolve().then(() => (init_recovery2(), recovery_exports));
|
|
15663
|
+
receipt = inspectStartupRecovery2({
|
|
15664
|
+
...invocation2.startup,
|
|
15665
|
+
cwd: context.cwd
|
|
15666
|
+
});
|
|
15667
|
+
} else if (invocation2.action === "launch" || invocation2.action === "plan") {
|
|
15274
15668
|
const { launchStartup: launchStartup2, planStartup: planStartup2 } = await Promise.resolve().then(() => (init_entry2(), entry_exports));
|
|
15275
15669
|
const request3 = { ...invocation2.startup, cwd: context.cwd };
|
|
15276
15670
|
receipt = invocation2.action === "plan" ? planStartup2(request3) : await launchStartup2(
|
|
@@ -15525,7 +15919,7 @@ function dispatch(argv, options2 = {}) {
|
|
|
15525
15919
|
return defaultEntry(options2, { ui, env, cwd });
|
|
15526
15920
|
}
|
|
15527
15921
|
if (verb === "--help" || verb === "-h" || verb === "help") {
|
|
15528
|
-
const named2 = COMMANDS.find((
|
|
15922
|
+
const named2 = COMMANDS.find((command4) => command4.name === rest[0]);
|
|
15529
15923
|
if (named2) printCommandHelp(ui, named2);
|
|
15530
15924
|
else printHelp(ui, COMMANDS, PLANNED);
|
|
15531
15925
|
return 0;
|
|
@@ -15538,8 +15932,8 @@ function dispatch(argv, options2 = {}) {
|
|
|
15538
15932
|
if (verb.startsWith("-")) {
|
|
15539
15933
|
return run(serveCommand, rest0, { ui, env, cwd });
|
|
15540
15934
|
}
|
|
15541
|
-
const
|
|
15542
|
-
if (
|
|
15935
|
+
const command3 = COMMANDS.find((candidate2) => candidate2.name === verb);
|
|
15936
|
+
if (command3 === void 0) {
|
|
15543
15937
|
if (PLANNED.includes(verb))
|
|
15544
15938
|
ui.error(`"${verb}" is designed but not implemented yet`);
|
|
15545
15939
|
else ui.error(`unknown command "${verb}"`);
|
|
@@ -15547,12 +15941,12 @@ function dispatch(argv, options2 = {}) {
|
|
|
15547
15941
|
return 2;
|
|
15548
15942
|
}
|
|
15549
15943
|
if (rest.includes("--help") || rest.includes("-h")) {
|
|
15550
|
-
printCommandHelp(ui,
|
|
15944
|
+
printCommandHelp(ui, command3);
|
|
15551
15945
|
return 0;
|
|
15552
15946
|
}
|
|
15553
|
-
return run(
|
|
15947
|
+
return run(command3, rest, { ui, env, cwd });
|
|
15554
15948
|
}
|
|
15555
|
-
var VERSION = "0.
|
|
15949
|
+
var VERSION = "0.16.1";
|
|
15556
15950
|
async function defaultEntry(options2, context) {
|
|
15557
15951
|
const terminal = options2.terminal ?? {
|
|
15558
15952
|
stdin: process.stdin.isTTY === true,
|
|
@@ -15576,16 +15970,16 @@ async function defaultEntry(options2, context) {
|
|
|
15576
15970
|
printHelp(context.ui, COMMANDS, PLANNED);
|
|
15577
15971
|
return 0;
|
|
15578
15972
|
}
|
|
15579
|
-
async function run(
|
|
15973
|
+
async function run(command3, argv, context) {
|
|
15580
15974
|
try {
|
|
15581
|
-
return await
|
|
15975
|
+
return await command3.run({
|
|
15582
15976
|
...context,
|
|
15583
|
-
args: parseArgs(argv,
|
|
15977
|
+
args: parseArgs(argv, command3.options)
|
|
15584
15978
|
});
|
|
15585
15979
|
} catch (error) {
|
|
15586
15980
|
if (error instanceof ArgumentError) {
|
|
15587
15981
|
context.ui.error(error.message);
|
|
15588
|
-
printCommandHelp(context.ui,
|
|
15982
|
+
printCommandHelp(context.ui, command3);
|
|
15589
15983
|
return 2;
|
|
15590
15984
|
}
|
|
15591
15985
|
context.ui.error(error instanceof Error ? error.message : "command failed");
|