@modootoday/pmcp 0.17.0 → 0.17.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/dist/cli.js +246 -192
- package/dist/http.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +54 -40
- package/dist/stdio.js +1 -1
- 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
|
@@ -1940,45 +1940,45 @@ var init_validation2 = __esm({
|
|
|
1940
1940
|
// src/harness/groups/store.ts
|
|
1941
1941
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
1942
1942
|
import {
|
|
1943
|
-
closeSync as
|
|
1943
|
+
closeSync as closeSync5,
|
|
1944
1944
|
constants as constants3,
|
|
1945
1945
|
fstatSync as fstatSync2,
|
|
1946
1946
|
fsyncSync as fsyncSync2,
|
|
1947
|
-
openSync as
|
|
1948
|
-
readFileSync as
|
|
1947
|
+
openSync as openSync5,
|
|
1948
|
+
readFileSync as readFileSync35,
|
|
1949
1949
|
realpathSync as realpathSync7,
|
|
1950
1950
|
renameSync as renameSync4,
|
|
1951
1951
|
writeFileSync as writeFileSync9
|
|
1952
1952
|
} from "fs";
|
|
1953
|
-
import { dirname as dirname21, join as
|
|
1953
|
+
import { dirname as dirname21, join as join32 } from "path";
|
|
1954
1954
|
function privateJson(path, value) {
|
|
1955
1955
|
const temporary = `${path}.${randomUUID5()}.new`;
|
|
1956
|
-
const descriptor =
|
|
1956
|
+
const descriptor = openSync5(temporary, "wx", 384);
|
|
1957
1957
|
try {
|
|
1958
1958
|
writeFileSync9(descriptor, `${JSON.stringify(value, null, 2)}
|
|
1959
1959
|
`);
|
|
1960
1960
|
fsyncSync2(descriptor);
|
|
1961
1961
|
} finally {
|
|
1962
|
-
|
|
1962
|
+
closeSync5(descriptor);
|
|
1963
1963
|
}
|
|
1964
1964
|
renameSync4(temporary, path);
|
|
1965
|
-
const directory =
|
|
1965
|
+
const directory = openSync5(dirname21(path), "r");
|
|
1966
1966
|
try {
|
|
1967
1967
|
fsyncSync2(directory);
|
|
1968
1968
|
} finally {
|
|
1969
|
-
|
|
1969
|
+
closeSync5(directory);
|
|
1970
1970
|
}
|
|
1971
1971
|
}
|
|
1972
1972
|
function readPrivateJson2(path) {
|
|
1973
|
-
const descriptor =
|
|
1973
|
+
const descriptor = openSync5(path, constants3.O_RDONLY | constants3.O_NOFOLLOW);
|
|
1974
1974
|
try {
|
|
1975
1975
|
const stat = fstatSync2(descriptor);
|
|
1976
1976
|
if (!stat.isFile() || (stat.mode & 63) !== 0 || stat.size > 2097152)
|
|
1977
1977
|
throw new Error("unsafe_state_file");
|
|
1978
1978
|
if (stat.uid !== process.getuid?.()) throw new Error("foreign_state_file");
|
|
1979
|
-
return JSON.parse(
|
|
1979
|
+
return JSON.parse(readFileSync35(descriptor, "utf8"));
|
|
1980
1980
|
} finally {
|
|
1981
|
-
|
|
1981
|
+
closeSync5(descriptor);
|
|
1982
1982
|
}
|
|
1983
1983
|
}
|
|
1984
1984
|
var GroupStore;
|
|
@@ -1994,7 +1994,7 @@ var init_store2 = __esm({
|
|
|
1994
1994
|
this.path = realpathSync7(path);
|
|
1995
1995
|
this.state = validateState(readPrivateJson2(path));
|
|
1996
1996
|
const metadata2 = object8(
|
|
1997
|
-
readPrivateJson2(
|
|
1997
|
+
readPrivateJson2(join32(dirname21(this.path), "harness.json"))
|
|
1998
1998
|
);
|
|
1999
1999
|
if (this.state.group.schemaVersion !== 1 || this.state.group.owner !== metadata2.owner) {
|
|
2000
2000
|
throw new Error("foreign_group");
|
|
@@ -2014,18 +2014,18 @@ var init_store2 = __esm({
|
|
|
2014
2014
|
});
|
|
2015
2015
|
|
|
2016
2016
|
// src/harness/adapters/process/serialized.ts
|
|
2017
|
-
import { spawnSync as
|
|
2017
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
2018
2018
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
2019
2019
|
import { existsSync as existsSync26, unlinkSync as unlinkSync2 } from "fs";
|
|
2020
|
-
import { dirname as dirname22, join as
|
|
2020
|
+
import { dirname as dirname22, join as join33 } from "path";
|
|
2021
2021
|
function serialized(operation) {
|
|
2022
2022
|
const store = new GroupStore(text(operation.groupFile, "group_file"));
|
|
2023
2023
|
const directory = dirname22(store.path);
|
|
2024
|
-
const operationFile =
|
|
2024
|
+
const operationFile = join33(directory, `operation-${randomUUID6()}.json`);
|
|
2025
2025
|
privateJson(operationFile, operation);
|
|
2026
2026
|
const worker = artifact("worker");
|
|
2027
2027
|
try {
|
|
2028
|
-
const result =
|
|
2028
|
+
const result = spawnSync5(
|
|
2029
2029
|
"flock",
|
|
2030
2030
|
[
|
|
2031
2031
|
"--exclusive",
|
|
@@ -2033,7 +2033,7 @@ function serialized(operation) {
|
|
|
2033
2033
|
"--no-fork",
|
|
2034
2034
|
"--conflict-exit-code",
|
|
2035
2035
|
"73",
|
|
2036
|
-
|
|
2036
|
+
join33(directory, "group-control.lock"),
|
|
2037
2037
|
process.execPath,
|
|
2038
2038
|
worker,
|
|
2039
2039
|
operationFile
|
|
@@ -2129,11 +2129,11 @@ var init_command = __esm({
|
|
|
2129
2129
|
});
|
|
2130
2130
|
|
|
2131
2131
|
// src/harness/adapters/process/identity.ts
|
|
2132
|
-
import { readFileSync as
|
|
2132
|
+
import { readFileSync as readFileSync36 } from "fs";
|
|
2133
2133
|
function processIdentity(pid) {
|
|
2134
2134
|
if (!Number.isSafeInteger(pid) || pid < 1)
|
|
2135
2135
|
throw new Error("invalid_process_id");
|
|
2136
|
-
const stat =
|
|
2136
|
+
const stat = readFileSync36(`/proc/${pid}/stat`, "utf8");
|
|
2137
2137
|
const fields = stat.slice(stat.lastIndexOf(")") + 2).split(" ");
|
|
2138
2138
|
if (!/^\d+$/.test(fields[19] ?? ""))
|
|
2139
2139
|
throw new Error("process_identity_unknown");
|
|
@@ -2372,10 +2372,10 @@ import {
|
|
|
2372
2372
|
writeFileSync as writeFileSync10
|
|
2373
2373
|
} from "fs";
|
|
2374
2374
|
import { homedir as homedir7 } from "os";
|
|
2375
|
-
import { join as
|
|
2375
|
+
import { join as join34 } from "path";
|
|
2376
2376
|
function stateDirectory() {
|
|
2377
|
-
return
|
|
2378
|
-
process.env.XDG_STATE_HOME ??
|
|
2377
|
+
return join34(
|
|
2378
|
+
process.env.XDG_STATE_HOME ?? join34(homedir7(), ".local/state"),
|
|
2379
2379
|
"pmcp/harness"
|
|
2380
2380
|
);
|
|
2381
2381
|
}
|
|
@@ -2406,11 +2406,11 @@ var init_records = __esm({
|
|
|
2406
2406
|
if (!stat.isDirectory() || stat.uid !== process.getuid?.() || (stat.mode & 63) !== 0)
|
|
2407
2407
|
throw new Error("unsafe_group_directory");
|
|
2408
2408
|
this.directory = realpathSync8(directory);
|
|
2409
|
-
this.socket =
|
|
2409
|
+
this.socket = join34(this.directory, "s");
|
|
2410
2410
|
if (Buffer.byteLength(this.socket) > 100)
|
|
2411
2411
|
throw new Error("socket_path_too_long");
|
|
2412
|
-
this.metadataPath =
|
|
2413
|
-
this.configPath =
|
|
2412
|
+
this.metadataPath = join34(this.directory, "harness.json");
|
|
2413
|
+
this.configPath = join34(this.directory, "tmux.conf");
|
|
2414
2414
|
this.owner = text(
|
|
2415
2415
|
object8(readPrivateJson2(this.metadataPath)).owner,
|
|
2416
2416
|
"owner"
|
|
@@ -2420,17 +2420,17 @@ var init_records = __esm({
|
|
|
2420
2420
|
static create() {
|
|
2421
2421
|
const root = stateDirectory();
|
|
2422
2422
|
mkdirSync9(root, { recursive: true, mode: 448 });
|
|
2423
|
-
const directory =
|
|
2424
|
-
if (Buffer.byteLength(
|
|
2423
|
+
const directory = join34(root, randomUUID7().slice(0, 16));
|
|
2424
|
+
if (Buffer.byteLength(join34(directory, "s")) > 100)
|
|
2425
2425
|
throw new Error("socket_path_too_long");
|
|
2426
2426
|
mkdirSync9(directory, { mode: 448 });
|
|
2427
|
-
mkdirSync9(
|
|
2428
|
-
privateJson(
|
|
2427
|
+
mkdirSync9(join34(directory, "sessions"), { mode: 448 });
|
|
2428
|
+
privateJson(join34(directory, "harness.json"), {
|
|
2429
2429
|
owner: randomUUID7(),
|
|
2430
2430
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2431
2431
|
});
|
|
2432
2432
|
writeFileSync10(
|
|
2433
|
-
|
|
2433
|
+
join34(directory, "tmux.conf"),
|
|
2434
2434
|
[
|
|
2435
2435
|
"set -g remain-on-exit on",
|
|
2436
2436
|
"set -g history-limit 2000",
|
|
@@ -2446,7 +2446,7 @@ var init_records = __esm({
|
|
|
2446
2446
|
}
|
|
2447
2447
|
path(id2) {
|
|
2448
2448
|
runtimeUnit(id2);
|
|
2449
|
-
return
|
|
2449
|
+
return join34(this.directory, "sessions", `${id2}.json`);
|
|
2450
2450
|
}
|
|
2451
2451
|
read(id2) {
|
|
2452
2452
|
const record = object8(readPrivateJson2(this.path(id2)));
|
|
@@ -2468,7 +2468,7 @@ var init_records = __esm({
|
|
|
2468
2468
|
return record;
|
|
2469
2469
|
}
|
|
2470
2470
|
all() {
|
|
2471
|
-
return readdirSync10(
|
|
2471
|
+
return readdirSync10(join34(this.directory, "sessions")).filter((name) => name.endsWith(".json")).map((name) => this.read(name.slice(0, -5)));
|
|
2472
2472
|
}
|
|
2473
2473
|
save(record) {
|
|
2474
2474
|
privateJson(this.path(record.id), record);
|
|
@@ -2551,7 +2551,7 @@ var init_launch_identity = __esm({
|
|
|
2551
2551
|
// src/harness/launch/journal.ts
|
|
2552
2552
|
import { createHash as createHash16 } from "crypto";
|
|
2553
2553
|
import { existsSync as existsSync27, readdirSync as readdirSync11 } from "fs";
|
|
2554
|
-
import { join as
|
|
2554
|
+
import { join as join35 } from "path";
|
|
2555
2555
|
function launchJournals(records2) {
|
|
2556
2556
|
return readdirSync11(records2.directory).filter((name) => name.endsWith(".intent.json")).map((name) => new LaunchJournal(records2, name.slice(0, -12)));
|
|
2557
2557
|
}
|
|
@@ -2586,7 +2586,7 @@ var init_journal = __esm({
|
|
|
2586
2586
|
path(kind2) {
|
|
2587
2587
|
if (!["intent", "proof", "grant", "committed", "aborted"].includes(kind2))
|
|
2588
2588
|
throw new Error("invalid_launch_artifact");
|
|
2589
|
-
return
|
|
2589
|
+
return join35(this.records.directory, `${this.id}.${kind2}.json`);
|
|
2590
2590
|
}
|
|
2591
2591
|
intent() {
|
|
2592
2592
|
const value = object8(readPrivateJson2(this.path("intent")));
|
|
@@ -2615,13 +2615,13 @@ var init_journal = __esm({
|
|
|
2615
2615
|
throw new Error("invalid_docker_bridge_digest");
|
|
2616
2616
|
if (!bridge && creation.bridgeSha256 !== void 0)
|
|
2617
2617
|
throw new Error("ungranted_docker_bridge_digest");
|
|
2618
|
-
const policy = new GroupStore(
|
|
2618
|
+
const policy = new GroupStore(join35(this.records.directory, "group.json")).state.group.dockerPolicy;
|
|
2619
2619
|
const profile = selectedProfile(
|
|
2620
2620
|
policy,
|
|
2621
2621
|
creation.privateProfile,
|
|
2622
2622
|
text(value.runtime, "runtime")
|
|
2623
2623
|
);
|
|
2624
|
-
const expectedState = profile?.directory ??
|
|
2624
|
+
const expectedState = profile?.directory ?? join35(
|
|
2625
2625
|
this.records.directory,
|
|
2626
2626
|
"containers",
|
|
2627
2627
|
text(value.nonce, "nonce"),
|
|
@@ -2667,7 +2667,7 @@ var init_journal = __esm({
|
|
|
2667
2667
|
}
|
|
2668
2668
|
assertRegistered() {
|
|
2669
2669
|
const intent = this.intent();
|
|
2670
|
-
const group = new GroupStore(
|
|
2670
|
+
const group = new GroupStore(join35(this.records.directory, "group.json")).state.group;
|
|
2671
2671
|
if (group.id !== intent.groupId || group.generation !== intent.generation)
|
|
2672
2672
|
throw new Error("launch_group_generation_mismatch");
|
|
2673
2673
|
if (intent.dockerCreation && JSON.stringify(intent.dockerCreation.egress) !== JSON.stringify(group.dockerPolicy?.egress))
|
|
@@ -2752,16 +2752,16 @@ var init_lifecycle = __esm({
|
|
|
2752
2752
|
// src/harness/adapters/docker/private-profile.ts
|
|
2753
2753
|
import { homedir as homedir8 } from "os";
|
|
2754
2754
|
import {
|
|
2755
|
-
closeSync as
|
|
2755
|
+
closeSync as closeSync6,
|
|
2756
2756
|
constants as constants4,
|
|
2757
2757
|
existsSync as existsSync28,
|
|
2758
2758
|
fstatSync as fstatSync3,
|
|
2759
2759
|
lstatSync as lstatSync7,
|
|
2760
|
-
openSync as
|
|
2760
|
+
openSync as openSync6,
|
|
2761
2761
|
realpathSync as realpathSync9,
|
|
2762
2762
|
statfsSync
|
|
2763
2763
|
} from "fs";
|
|
2764
|
-
import { join as
|
|
2764
|
+
import { join as join36, relative as relative11 } from "path";
|
|
2765
2765
|
function overlap(left, right) {
|
|
2766
2766
|
const scope = relative11(left, right);
|
|
2767
2767
|
return scope === "" || scope !== ".." && !scope.startsWith("../");
|
|
@@ -2774,8 +2774,8 @@ function profileIdentity(directory, projectRoot) {
|
|
|
2774
2774
|
throw new Error("unsafe_private_profile_directory");
|
|
2775
2775
|
if ([26985, 4283649346, 4266872130].includes(statfsSync(directory).type))
|
|
2776
2776
|
throw new Error("remote_private_profile_not_admitted");
|
|
2777
|
-
const lock =
|
|
2778
|
-
|
|
2777
|
+
const lock = openSync6(
|
|
2778
|
+
join36(directory, privateProfileLock),
|
|
2779
2779
|
constants4.O_RDONLY | constants4.O_NOFOLLOW
|
|
2780
2780
|
);
|
|
2781
2781
|
try {
|
|
@@ -2784,7 +2784,7 @@ function profileIdentity(directory, projectRoot) {
|
|
|
2784
2784
|
throw new Error("unsafe_private_profile_lock");
|
|
2785
2785
|
return `${stat.dev}:${stat.ino}:${value.dev}:${value.ino}`;
|
|
2786
2786
|
} finally {
|
|
2787
|
-
|
|
2787
|
+
closeSync6(lock);
|
|
2788
2788
|
}
|
|
2789
2789
|
}
|
|
2790
2790
|
function captureProfile(grant, projectRoot) {
|
|
@@ -2794,8 +2794,8 @@ function captureProfile(grant, projectRoot) {
|
|
|
2794
2794
|
const stat = lstatSync7(directory);
|
|
2795
2795
|
if (!stat.isDirectory() || stat.uid !== process.getuid?.() || (stat.mode & 511) !== 448)
|
|
2796
2796
|
throw new Error("unsafe_private_profile_directory");
|
|
2797
|
-
const lock =
|
|
2798
|
-
if (!existsSync28(lock))
|
|
2797
|
+
const lock = join36(directory, privateProfileLock);
|
|
2798
|
+
if (!existsSync28(lock)) closeSync6(openSync6(lock, "wx", 384));
|
|
2799
2799
|
const identity = profileIdentity(directory, projectRoot);
|
|
2800
2800
|
if (grant.identity && grant.identity !== identity)
|
|
2801
2801
|
throw new Error("private_profile_identity_changed");
|
|
@@ -2813,7 +2813,7 @@ function assertProfileAvailable(grant, projectRoot) {
|
|
|
2813
2813
|
"--nonblock",
|
|
2814
2814
|
"--conflict-exit-code",
|
|
2815
2815
|
"73",
|
|
2816
|
-
|
|
2816
|
+
join36(grant.directory, privateProfileLock),
|
|
2817
2817
|
"true"
|
|
2818
2818
|
]);
|
|
2819
2819
|
} catch (error) {
|
|
@@ -2890,12 +2890,12 @@ var init_profile = __esm({
|
|
|
2890
2890
|
|
|
2891
2891
|
// src/harness/adapters/docker/mounts.ts
|
|
2892
2892
|
import { lstatSync as lstatSync9, realpathSync as realpathSync11 } from "fs";
|
|
2893
|
-
import { join as
|
|
2893
|
+
import { join as join37 } from "path";
|
|
2894
2894
|
function assertContainerMounts(actual, statePath, projectRoot, directory, nonce, policy, privateProfile, runtime2) {
|
|
2895
2895
|
const state = text(statePath, "container_state_directory");
|
|
2896
2896
|
const profile = selectedProfile(policy, privateProfile, runtime2 ?? "");
|
|
2897
2897
|
if (profile) assertProfileIdentity(profile, projectRoot);
|
|
2898
|
-
const expected = profile?.directory ??
|
|
2898
|
+
const expected = profile?.directory ?? join37(directory, "containers", nonce, "profile");
|
|
2899
2899
|
if (state !== expected || realpathSync11(state) !== expected)
|
|
2900
2900
|
throw new Error("foreign_container_state_directory");
|
|
2901
2901
|
const stat = lstatSync9(state);
|
|
@@ -2991,7 +2991,7 @@ var init_entrypoint = __esm({
|
|
|
2991
2991
|
|
|
2992
2992
|
// src/harness/adapters/docker/admission.ts
|
|
2993
2993
|
import { lstatSync as lstatSync10, realpathSync as realpathSync12 } from "fs";
|
|
2994
|
-
import { join as
|
|
2994
|
+
import { join as join38, relative as relative13 } from "path";
|
|
2995
2995
|
function admitResource(path, group, role, directory, memoryMb, runtime2) {
|
|
2996
2996
|
if (group.profile !== "docker" || !group.dockerPolicy)
|
|
2997
2997
|
throw new Error("container_requires_docker_profile");
|
|
@@ -3047,7 +3047,7 @@ function admitClaim(value, group, role, directory, memoryMb, runtime2, cwd = gro
|
|
|
3047
3047
|
)
|
|
3048
3048
|
))
|
|
3049
3049
|
throw new Error("container_runtime_image_not_granted");
|
|
3050
|
-
if (config.WorkingDir !==
|
|
3050
|
+
if (config.WorkingDir !== join38("/workspace", relative13(projectRoot, cwd)))
|
|
3051
3051
|
throw new Error("container_cwd_not_granted");
|
|
3052
3052
|
assertContainerMounts(
|
|
3053
3053
|
actual,
|
|
@@ -3183,20 +3183,20 @@ var init_engine = __esm({
|
|
|
3183
3183
|
// src/harness/adapters/docker/bridge-artifact.ts
|
|
3184
3184
|
import { createHash as createHash17 } from "crypto";
|
|
3185
3185
|
import {
|
|
3186
|
-
closeSync as
|
|
3186
|
+
closeSync as closeSync7,
|
|
3187
3187
|
constants as constants5,
|
|
3188
3188
|
fstatSync as fstatSync4,
|
|
3189
3189
|
fsyncSync as fsyncSync3,
|
|
3190
|
-
openSync as
|
|
3191
|
-
readFileSync as
|
|
3190
|
+
openSync as openSync7,
|
|
3191
|
+
readFileSync as readFileSync37,
|
|
3192
3192
|
writeFileSync as writeFileSync11
|
|
3193
3193
|
} from "fs";
|
|
3194
|
-
import { join as
|
|
3194
|
+
import { join as join39 } from "path";
|
|
3195
3195
|
function source() {
|
|
3196
3196
|
const path = artifact("egress-bridge");
|
|
3197
3197
|
if (!path.endsWith(".js"))
|
|
3198
3198
|
throw new Error("docker_bridge_requires_compiled_cli");
|
|
3199
|
-
return
|
|
3199
|
+
return readFileSync37(path);
|
|
3200
3200
|
}
|
|
3201
3201
|
function digest(value) {
|
|
3202
3202
|
return createHash17("sha256").update(value).digest("hex");
|
|
@@ -3209,8 +3209,8 @@ function prepareBridge(creation) {
|
|
|
3209
3209
|
const content = source();
|
|
3210
3210
|
if (digest(content) !== creation.bridgeSha256)
|
|
3211
3211
|
throw new Error("docker_bridge_source_changed");
|
|
3212
|
-
const descriptor =
|
|
3213
|
-
|
|
3212
|
+
const descriptor = openSync7(
|
|
3213
|
+
join39(creation.state, bridgeName(creation.nonce)),
|
|
3214
3214
|
"wx",
|
|
3215
3215
|
384
|
|
3216
3216
|
);
|
|
@@ -3218,21 +3218,21 @@ function prepareBridge(creation) {
|
|
|
3218
3218
|
writeFileSync11(descriptor, content);
|
|
3219
3219
|
fsyncSync3(descriptor);
|
|
3220
3220
|
} finally {
|
|
3221
|
-
|
|
3221
|
+
closeSync7(descriptor);
|
|
3222
3222
|
}
|
|
3223
3223
|
}
|
|
3224
3224
|
function assertBridge(creation) {
|
|
3225
3225
|
if (!creation.egress?.bridgeExecutable) return;
|
|
3226
|
-
const descriptor =
|
|
3227
|
-
|
|
3226
|
+
const descriptor = openSync7(
|
|
3227
|
+
join39(creation.state, bridgeName(creation.nonce)),
|
|
3228
3228
|
constants5.O_RDONLY | constants5.O_NOFOLLOW
|
|
3229
3229
|
);
|
|
3230
3230
|
try {
|
|
3231
3231
|
const stat = fstatSync4(descriptor);
|
|
3232
|
-
if (!stat.isFile() || stat.uid !== process.getuid?.() || stat.nlink !== 1 || (stat.mode & 63) !== 0 || stat.size > 2097152 || digest(
|
|
3232
|
+
if (!stat.isFile() || stat.uid !== process.getuid?.() || stat.nlink !== 1 || (stat.mode & 63) !== 0 || stat.size > 2097152 || digest(readFileSync37(descriptor)) !== creation.bridgeSha256)
|
|
3233
3233
|
throw new Error("docker_bridge_artifact_changed");
|
|
3234
3234
|
} finally {
|
|
3235
|
-
|
|
3235
|
+
closeSync7(descriptor);
|
|
3236
3236
|
}
|
|
3237
3237
|
}
|
|
3238
3238
|
var init_bridge_artifact = __esm({
|
|
@@ -3244,7 +3244,7 @@ var init_bridge_artifact = __esm({
|
|
|
3244
3244
|
});
|
|
3245
3245
|
|
|
3246
3246
|
// src/harness/adapters/docker/creation-plan.ts
|
|
3247
|
-
import { join as
|
|
3247
|
+
import { join as join40, relative as relative14 } from "path";
|
|
3248
3248
|
function creationPlan(group, directory, id2, nonce, role, runtime2, cwd, preparation) {
|
|
3249
3249
|
if (group.profile !== "docker" || !group.dockerPolicy)
|
|
3250
3250
|
throw new Error("container_requires_docker_profile");
|
|
@@ -3261,7 +3261,7 @@ function creationPlan(group, directory, id2, nonce, role, runtime2, cwd, prepara
|
|
|
3261
3261
|
throw new Error("invalid_container_image_environment");
|
|
3262
3262
|
const profile = selectedProfile(policy, preparation.privateProfile, runtime2);
|
|
3263
3263
|
if (profile) assertProfileAvailable(profile, group.projectRoot);
|
|
3264
|
-
const state = profile?.directory ??
|
|
3264
|
+
const state = profile?.directory ?? join40(directory, "containers", nonce, "profile");
|
|
3265
3265
|
return {
|
|
3266
3266
|
name: containerName(group.owner, id2),
|
|
3267
3267
|
nonce,
|
|
@@ -3278,7 +3278,7 @@ function creationPlan(group, directory, id2, nonce, role, runtime2, cwd, prepara
|
|
|
3278
3278
|
preparation.privateProfile
|
|
3279
3279
|
),
|
|
3280
3280
|
Cmd: preparation.args.length ? preparation.args : null,
|
|
3281
|
-
WorkingDir:
|
|
3281
|
+
WorkingDir: join40("/workspace", relative14(group.projectRoot, cwd)),
|
|
3282
3282
|
User: `${process.getuid?.()}:${process.getgid?.()}`,
|
|
3283
3283
|
Env: [
|
|
3284
3284
|
...environment2.filter(
|
|
@@ -3377,12 +3377,12 @@ var init_creation_plan = __esm({
|
|
|
3377
3377
|
|
|
3378
3378
|
// src/harness/adapters/docker/creation.ts
|
|
3379
3379
|
import { mkdirSync as mkdirSync10 } from "fs";
|
|
3380
|
-
import { join as
|
|
3380
|
+
import { join as join41 } from "path";
|
|
3381
3381
|
async function prepareCreation(journal) {
|
|
3382
3382
|
const intent = journal.intent();
|
|
3383
3383
|
const creation = intent.dockerCreation;
|
|
3384
3384
|
if (!creation) throw new Error("container_creation_missing");
|
|
3385
|
-
const group = new GroupStore(
|
|
3385
|
+
const group = new GroupStore(join41(journal.records.directory, "group.json")).state.group;
|
|
3386
3386
|
const profile = selectedProfile(
|
|
3387
3387
|
group.dockerPolicy,
|
|
3388
3388
|
creation.privateProfile,
|
|
@@ -3396,7 +3396,7 @@ async function prepareCreation(journal) {
|
|
|
3396
3396
|
creation.name,
|
|
3397
3397
|
creation.configuration
|
|
3398
3398
|
);
|
|
3399
|
-
const current = new GroupStore(
|
|
3399
|
+
const current = new GroupStore(join41(journal.records.directory, "group.json")).state.group;
|
|
3400
3400
|
if (current.id !== intent.groupId || current.generation !== intent.generation)
|
|
3401
3401
|
throw new Error("launch_group_generation_mismatch");
|
|
3402
3402
|
const resource = {
|
|
@@ -3464,7 +3464,7 @@ function findCreation(journal) {
|
|
|
3464
3464
|
assertResourceOwner(resource, actual);
|
|
3465
3465
|
assertCreationConfiguration(actual, creation);
|
|
3466
3466
|
if (!intent.resource) {
|
|
3467
|
-
const group = new GroupStore(
|
|
3467
|
+
const group = new GroupStore(join41(journal.records.directory, "group.json")).state.group;
|
|
3468
3468
|
return {
|
|
3469
3469
|
...admitClaim(
|
|
3470
3470
|
{ ...resource, runtime: intent.runtime, state: creation.state },
|
|
@@ -3574,7 +3574,7 @@ var init_recovery = __esm({
|
|
|
3574
3574
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
3575
3575
|
import { existsSync as existsSync30 } from "fs";
|
|
3576
3576
|
import { setTimeout as setTimeout2 } from "timers/promises";
|
|
3577
|
-
import { join as
|
|
3577
|
+
import { join as join42 } from "path";
|
|
3578
3578
|
async function start(connection, spec) {
|
|
3579
3579
|
const records2 = connection.records;
|
|
3580
3580
|
if (spec.budgetSlice !== budgetSlice(records2.owner))
|
|
@@ -3588,7 +3588,7 @@ async function start(connection, spec) {
|
|
|
3588
3588
|
const nonce = randomUUID8();
|
|
3589
3589
|
const journal = new LaunchJournal(records2, id2);
|
|
3590
3590
|
const dockerCreation = spec.dockerPreparation ? creationPlan(
|
|
3591
|
-
new GroupStore(
|
|
3591
|
+
new GroupStore(join42(records2.directory, "group.json")).state.group,
|
|
3592
3592
|
records2.directory,
|
|
3593
3593
|
id2,
|
|
3594
3594
|
nonce,
|
|
@@ -3717,8 +3717,8 @@ var init_lifecycle2 = __esm({
|
|
|
3717
3717
|
|
|
3718
3718
|
// src/harness/adapters/tmux/input.ts
|
|
3719
3719
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
3720
|
-
import { closeSync as
|
|
3721
|
-
import { join as
|
|
3720
|
+
import { closeSync as closeSync8, openSync as openSync8, unlinkSync as unlinkSync3, writeFileSync as writeFileSync12 } from "fs";
|
|
3721
|
+
import { join as join43 } from "path";
|
|
3722
3722
|
function validateText(text3) {
|
|
3723
3723
|
if (typeof text3 !== "string" || Buffer.byteLength(text3) > 16384)
|
|
3724
3724
|
throw new Error("invalid_text");
|
|
@@ -3749,8 +3749,8 @@ function write(connection, id2, text3, submit) {
|
|
|
3749
3749
|
validateText(text3);
|
|
3750
3750
|
const session = connection.inspect(id2);
|
|
3751
3751
|
if (!session.alive) throw new Error("runtime_exited");
|
|
3752
|
-
const lock =
|
|
3753
|
-
const descriptor =
|
|
3752
|
+
const lock = join43(connection.records.directory, `${id2}.input.lock`);
|
|
3753
|
+
const descriptor = openSync8(lock, "wx", 384);
|
|
3754
3754
|
const buffer = `pmcp-${randomUUID9()}`;
|
|
3755
3755
|
try {
|
|
3756
3756
|
writeFileSync12(
|
|
@@ -3791,7 +3791,7 @@ function write(connection, id2, text3, submit) {
|
|
|
3791
3791
|
connection.tmux(["delete-buffer", "-b", buffer]);
|
|
3792
3792
|
} catch {
|
|
3793
3793
|
}
|
|
3794
|
-
|
|
3794
|
+
closeSync8(descriptor);
|
|
3795
3795
|
unlinkSync3(lock);
|
|
3796
3796
|
}
|
|
3797
3797
|
}
|
|
@@ -3908,10 +3908,10 @@ var init_backend = __esm({
|
|
|
3908
3908
|
});
|
|
3909
3909
|
|
|
3910
3910
|
// src/harness/adapters/systemd/budget.ts
|
|
3911
|
-
import { join as
|
|
3911
|
+
import { join as join44 } from "path";
|
|
3912
3912
|
async function budgetOperation(directory, operation) {
|
|
3913
3913
|
const backend = openBackend(directory);
|
|
3914
|
-
const path =
|
|
3914
|
+
const path = join44(directory, "runtime-policy.json");
|
|
3915
3915
|
const metadata2 = object8(readPrivateJson2(backend.metadataPath));
|
|
3916
3916
|
const slice = budgetSlice(backend.owner);
|
|
3917
3917
|
if (operation.action === "configure") {
|
|
@@ -4012,7 +4012,7 @@ var init_budget = __esm({
|
|
|
4012
4012
|
|
|
4013
4013
|
// src/harness/adapters/systemd/configure.ts
|
|
4014
4014
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
4015
|
-
import { join as
|
|
4015
|
+
import { join as join45 } from "path";
|
|
4016
4016
|
function configureBudget(context, input) {
|
|
4017
4017
|
const { store, backend } = context;
|
|
4018
4018
|
assertOwnedRecords(backend);
|
|
@@ -4034,7 +4034,7 @@ function configureBudget(context, input) {
|
|
|
4034
4034
|
throw new Error("capacity_below_active_sessions");
|
|
4035
4035
|
if (active.reduce((total, session) => total + session.memoryMb, 0) > memoryMb)
|
|
4036
4036
|
throw new Error("budget_below_reserved_memory");
|
|
4037
|
-
const path =
|
|
4037
|
+
const path = join45(backend.runDirectory, "runtime-policy.json");
|
|
4038
4038
|
const policy = object8(readPrivateJson2(path));
|
|
4039
4039
|
const metadata2 = object8(readPrivateJson2(backend.metadataPath));
|
|
4040
4040
|
const slice = budgetSlice(backend.owner);
|
|
@@ -4071,14 +4071,14 @@ var init_configure = __esm({
|
|
|
4071
4071
|
});
|
|
4072
4072
|
|
|
4073
4073
|
// src/harness/adapters/process/executable.ts
|
|
4074
|
-
import { accessSync, constants as constants6, statSync as
|
|
4074
|
+
import { accessSync, constants as constants6, statSync as statSync17 } from "fs";
|
|
4075
4075
|
import { delimiter, resolve as resolve18 } from "path";
|
|
4076
4076
|
function locateExecutable(binary, cwd = process.cwd()) {
|
|
4077
4077
|
for (const directory of (process.env.PATH ?? "").split(delimiter)) {
|
|
4078
4078
|
if (!directory) continue;
|
|
4079
4079
|
const path = resolve18(cwd, directory, binary);
|
|
4080
4080
|
try {
|
|
4081
|
-
if (!
|
|
4081
|
+
if (!statSync17(path).isFile()) continue;
|
|
4082
4082
|
accessSync(path, constants6.X_OK);
|
|
4083
4083
|
return path;
|
|
4084
4084
|
} catch {
|
|
@@ -4129,11 +4129,11 @@ var init_admission2 = __esm({
|
|
|
4129
4129
|
|
|
4130
4130
|
// src/harness/groups/service.ts
|
|
4131
4131
|
import { randomUUID as randomUUID10 } from "crypto";
|
|
4132
|
-
import { realpathSync as realpathSync13, statSync as
|
|
4133
|
-
import { join as
|
|
4132
|
+
import { realpathSync as realpathSync13, statSync as statSync18, unlinkSync as unlinkSync4 } from "fs";
|
|
4133
|
+
import { join as join46 } from "path";
|
|
4134
4134
|
async function createGroup(input) {
|
|
4135
4135
|
const projectRoot = realpathSync13(text(input.projectRoot, "project_root"));
|
|
4136
|
-
if (!
|
|
4136
|
+
if (!statSync18(projectRoot).isDirectory())
|
|
4137
4137
|
throw new Error("invalid_project_root");
|
|
4138
4138
|
const allowedRuntimes = strings2(input.allowedRuntimes, "allowed_runtimes");
|
|
4139
4139
|
const profile = input.profile ?? "native";
|
|
@@ -4163,7 +4163,7 @@ async function createGroup(input) {
|
|
|
4163
4163
|
sessions: [],
|
|
4164
4164
|
...dockerPolicy2 ? { dockerPolicy: dockerPolicy2 } : {}
|
|
4165
4165
|
};
|
|
4166
|
-
const groupFile =
|
|
4166
|
+
const groupFile = join46(backend.runDirectory, "group.json");
|
|
4167
4167
|
privateJson(groupFile, { group, leases: [], deliveries: [] });
|
|
4168
4168
|
try {
|
|
4169
4169
|
await budgetOperation(backend.runDirectory, {
|
|
@@ -4176,7 +4176,7 @@ async function createGroup(input) {
|
|
|
4176
4176
|
await budgetOperation(backend.runDirectory, { action: "cleanup" });
|
|
4177
4177
|
unlinkSync4(groupFile);
|
|
4178
4178
|
} catch (cleanupError) {
|
|
4179
|
-
privateJson(
|
|
4179
|
+
privateJson(join46(backend.runDirectory, "initialization-failure.json"), {
|
|
4180
4180
|
error: String(error),
|
|
4181
4181
|
cleanupError: String(cleanupError),
|
|
4182
4182
|
recoveryRequired: true
|
|
@@ -4239,14 +4239,14 @@ var init_service2 = __esm({
|
|
|
4239
4239
|
|
|
4240
4240
|
// src/harness/groups/catalog.ts
|
|
4241
4241
|
import { existsSync as existsSync31, readdirSync as readdirSync12 } from "fs";
|
|
4242
|
-
import { join as
|
|
4242
|
+
import { join as join47 } from "path";
|
|
4243
4243
|
function listGroups() {
|
|
4244
4244
|
const directory = stateDirectory();
|
|
4245
4245
|
if (!existsSync31(directory)) return { groups: [] };
|
|
4246
4246
|
const groups2 = [];
|
|
4247
4247
|
for (const entry2 of readdirSync12(directory, { withFileTypes: true })) {
|
|
4248
4248
|
if (!entry2.isDirectory()) continue;
|
|
4249
|
-
const path =
|
|
4249
|
+
const path = join47(directory, entry2.name, "group.json");
|
|
4250
4250
|
if (!existsSync31(path)) continue;
|
|
4251
4251
|
try {
|
|
4252
4252
|
const store = new GroupStore(path);
|
|
@@ -4444,7 +4444,7 @@ var init_watch = __esm({
|
|
|
4444
4444
|
|
|
4445
4445
|
// src/harness/control/leases.ts
|
|
4446
4446
|
import { randomUUID as randomUUID11 } from "crypto";
|
|
4447
|
-
import { join as
|
|
4447
|
+
import { join as join48 } from "path";
|
|
4448
4448
|
function resolveLease(context, file2, allowExpired = false) {
|
|
4449
4449
|
const credential2 = object8(readPrivateJson2(file2));
|
|
4450
4450
|
const lease = context.store.state.leases.find(
|
|
@@ -4488,7 +4488,7 @@ function acquireControl(context, sessionId, controller, mode) {
|
|
|
4488
4488
|
);
|
|
4489
4489
|
store.state.leases.push(lease);
|
|
4490
4490
|
store.save();
|
|
4491
|
-
const leaseFile =
|
|
4491
|
+
const leaseFile = join48(backend.runDirectory, `lease-${randomUUID11()}.json`);
|
|
4492
4492
|
privateJson(leaseFile, { token: lease.token });
|
|
4493
4493
|
return { sessionId, controller, mode, expiresAt: lease.expiresAt, leaseFile };
|
|
4494
4494
|
}
|
|
@@ -4636,10 +4636,10 @@ var init_service5 = __esm({
|
|
|
4636
4636
|
|
|
4637
4637
|
// src/harness/adapters/process/recover-lock.ts
|
|
4638
4638
|
import { existsSync as existsSync32, lstatSync as lstatSync11, unlinkSync as unlinkSync5 } from "fs";
|
|
4639
|
-
import { join as
|
|
4639
|
+
import { join as join49 } from "path";
|
|
4640
4640
|
function recoverInputLock(backend, sessionId) {
|
|
4641
4641
|
backend.inspect(sessionId);
|
|
4642
|
-
const path =
|
|
4642
|
+
const path = join49(backend.runDirectory, `${sessionId}.input.lock`);
|
|
4643
4643
|
if (!existsSync32(path)) return;
|
|
4644
4644
|
const before = lstatSync11(path);
|
|
4645
4645
|
const record = object8(readPrivateJson2(path));
|
|
@@ -5205,7 +5205,7 @@ var init_invoke = __esm({
|
|
|
5205
5205
|
});
|
|
5206
5206
|
|
|
5207
5207
|
// src/tui/adapters/process/runtime.ts
|
|
5208
|
-
import { dirname as dirname24, join as
|
|
5208
|
+
import { dirname as dirname24, join as join50 } from "path";
|
|
5209
5209
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5210
5210
|
import { existsSync as existsSync34, realpathSync as realpathSync15 } from "fs";
|
|
5211
5211
|
function dependencies() {
|
|
@@ -5241,7 +5241,7 @@ function runtime() {
|
|
|
5241
5241
|
throw new Error("tui_dependencies_unavailable");
|
|
5242
5242
|
const current = fileURLToPath4(import.meta.url);
|
|
5243
5243
|
const directory = dirname24(current);
|
|
5244
|
-
const bundled =
|
|
5244
|
+
const bundled = join50(directory, "tui-worker.js");
|
|
5245
5245
|
if (!existsSync34(bundled)) throw new Error("tui_build_required");
|
|
5246
5246
|
return { node: realpathSync15(available.node), worker: bundled };
|
|
5247
5247
|
}
|
|
@@ -5338,24 +5338,24 @@ import {
|
|
|
5338
5338
|
writeFileSync as writeFileSync13
|
|
5339
5339
|
} from "fs";
|
|
5340
5340
|
import { homedir as homedir10 } from "os";
|
|
5341
|
-
import { dirname as dirname25, join as
|
|
5341
|
+
import { dirname as dirname25, join as join51 } from "path";
|
|
5342
5342
|
function createDirectory() {
|
|
5343
|
-
const root =
|
|
5344
|
-
process.env.XDG_STATE_HOME ??
|
|
5343
|
+
const root = join51(
|
|
5344
|
+
process.env.XDG_STATE_HOME ?? join51(homedir10(), ".local/state"),
|
|
5345
5345
|
"pmcp/tui"
|
|
5346
5346
|
);
|
|
5347
5347
|
mkdirSync11(root, { recursive: true, mode: 448 });
|
|
5348
|
-
const directory =
|
|
5349
|
-
if (Buffer.byteLength(
|
|
5348
|
+
const directory = join51(realpathSync16(root), randomUUID13().slice(0, 16));
|
|
5349
|
+
if (Buffer.byteLength(join51(directory, "s")) > 100)
|
|
5350
5350
|
throw new Error("socket_path_too_long");
|
|
5351
5351
|
mkdirSync11(directory, { mode: 448 });
|
|
5352
5352
|
const owner = randomUUID13();
|
|
5353
|
-
privateJson(
|
|
5353
|
+
privateJson(join51(directory, "owner.json"), {
|
|
5354
5354
|
owner,
|
|
5355
5355
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5356
5356
|
});
|
|
5357
5357
|
writeFileSync13(
|
|
5358
|
-
|
|
5358
|
+
join51(directory, "tmux.conf"),
|
|
5359
5359
|
[
|
|
5360
5360
|
"set -g remain-on-exit on",
|
|
5361
5361
|
"set -g history-limit 2000",
|
|
@@ -5376,7 +5376,7 @@ function readView(path) {
|
|
|
5376
5376
|
if (!stat.isDirectory() || stat.uid !== process.getuid?.() || (stat.mode & 63) !== 0)
|
|
5377
5377
|
throw new Error("unsafe_view_directory");
|
|
5378
5378
|
const value = object8(readPrivateJson2(file2));
|
|
5379
|
-
const metadata2 = object8(readPrivateJson2(
|
|
5379
|
+
const metadata2 = object8(readPrivateJson2(join51(directory, "owner.json")));
|
|
5380
5380
|
if (value.schemaVersion !== 1 || value.directory !== directory || value.owner !== metadata2.owner)
|
|
5381
5381
|
throw new Error("foreign_view_owner");
|
|
5382
5382
|
for (const key of [
|
|
@@ -5413,7 +5413,7 @@ function readView(path) {
|
|
|
5413
5413
|
throw new Error("invalid_view_identity");
|
|
5414
5414
|
}
|
|
5415
5415
|
const view = value;
|
|
5416
|
-
const fallback =
|
|
5416
|
+
const fallback = join51(directory, "callback-failure.json");
|
|
5417
5417
|
if (existsSync35(fallback)) {
|
|
5418
5418
|
const recorded = object8(readPrivateJson2(fallback));
|
|
5419
5419
|
const failure2 = object8(recorded.failure);
|
|
@@ -5425,7 +5425,7 @@ function readView(path) {
|
|
|
5425
5425
|
return { file: file2, view };
|
|
5426
5426
|
}
|
|
5427
5427
|
function dismissFailure(file2, view) {
|
|
5428
|
-
const fallback =
|
|
5428
|
+
const fallback = join51(view.directory, "callback-failure.json");
|
|
5429
5429
|
if (existsSync35(fallback)) unlinkSync6(fallback);
|
|
5430
5430
|
delete view.failure;
|
|
5431
5431
|
saveView(file2, view);
|
|
@@ -5443,7 +5443,7 @@ var init_store3 = __esm({
|
|
|
5443
5443
|
});
|
|
5444
5444
|
|
|
5445
5445
|
// src/tui/adapters/process/lock.ts
|
|
5446
|
-
import { spawnSync as
|
|
5446
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
5447
5447
|
function serializedView(invocation2) {
|
|
5448
5448
|
const { file: file2, view } = readView(invocation2.viewFile);
|
|
5449
5449
|
const args = ["locked", invocation2.action, "--view", file2];
|
|
@@ -5454,7 +5454,7 @@ function serializedView(invocation2) {
|
|
|
5454
5454
|
["confirm-session", invocation2.input.confirmSession]
|
|
5455
5455
|
])
|
|
5456
5456
|
if (value !== void 0) args.push(`--${name}`, String(value));
|
|
5457
|
-
const child =
|
|
5457
|
+
const child = spawnSync6(
|
|
5458
5458
|
"flock",
|
|
5459
5459
|
[
|
|
5460
5460
|
"--wait",
|
|
@@ -5488,7 +5488,7 @@ var init_lock = __esm({
|
|
|
5488
5488
|
});
|
|
5489
5489
|
|
|
5490
5490
|
// src/tui/adapters/process/budget.ts
|
|
5491
|
-
import { readFileSync as
|
|
5491
|
+
import { readFileSync as readFileSync38 } from "fs";
|
|
5492
5492
|
function viewUnit(owner) {
|
|
5493
5493
|
if (!/^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(owner))
|
|
5494
5494
|
throw new Error("invalid_view_owner");
|
|
@@ -5516,7 +5516,7 @@ function startPresentation(owner, args, env) {
|
|
|
5516
5516
|
);
|
|
5517
5517
|
}
|
|
5518
5518
|
function assertPresentationBudget(owner, pid) {
|
|
5519
|
-
if (!
|
|
5519
|
+
if (!readFileSync38(`/proc/${pid}/cgroup`, "utf8").includes(
|
|
5520
5520
|
`/${viewUnit(owner)}
|
|
5521
5521
|
`
|
|
5522
5522
|
))
|
|
@@ -5531,7 +5531,7 @@ var init_budget2 = __esm({
|
|
|
5531
5531
|
|
|
5532
5532
|
// src/tui/adapters/tmux/connection.ts
|
|
5533
5533
|
import { spawn as spawn3 } from "child_process";
|
|
5534
|
-
import { join as
|
|
5534
|
+
import { join as join52 } from "path";
|
|
5535
5535
|
var ViewConnection;
|
|
5536
5536
|
var init_connection2 = __esm({
|
|
5537
5537
|
"src/tui/adapters/tmux/connection.ts"() {
|
|
@@ -5544,7 +5544,7 @@ var init_connection2 = __esm({
|
|
|
5544
5544
|
this.directory = directory;
|
|
5545
5545
|
this.owner = owner;
|
|
5546
5546
|
this.identity = identity;
|
|
5547
|
-
this.socket =
|
|
5547
|
+
this.socket = join52(directory, "s");
|
|
5548
5548
|
}
|
|
5549
5549
|
directory;
|
|
5550
5550
|
owner;
|
|
@@ -5557,14 +5557,14 @@ var init_connection2 = __esm({
|
|
|
5557
5557
|
"-S",
|
|
5558
5558
|
this.socket,
|
|
5559
5559
|
"-f",
|
|
5560
|
-
|
|
5560
|
+
join52(this.directory, "tmux.conf"),
|
|
5561
5561
|
...args
|
|
5562
5562
|
];
|
|
5563
5563
|
if (args[0] === "new-session" && !this.identity)
|
|
5564
5564
|
return startPresentation(this.owner, options2, env).trim();
|
|
5565
5565
|
return command(
|
|
5566
5566
|
"tmux",
|
|
5567
|
-
["-S", this.socket, "-f",
|
|
5567
|
+
["-S", this.socket, "-f", join52(this.directory, "tmux.conf"), ...args],
|
|
5568
5568
|
{ env }
|
|
5569
5569
|
).trim();
|
|
5570
5570
|
}
|
|
@@ -5628,7 +5628,7 @@ var init_connection2 = __esm({
|
|
|
5628
5628
|
});
|
|
5629
5629
|
|
|
5630
5630
|
// src/tui/application/feedback.ts
|
|
5631
|
-
import { join as
|
|
5631
|
+
import { join as join53 } from "path";
|
|
5632
5632
|
function describeFailure(action, error) {
|
|
5633
5633
|
const message = error instanceof Error ? error.message : "view_action_failed";
|
|
5634
5634
|
const code = error instanceof RangeError ? "terminal_size_invalid" : failureCode(message);
|
|
@@ -6080,7 +6080,7 @@ var init_common = __esm({
|
|
|
6080
6080
|
});
|
|
6081
6081
|
|
|
6082
6082
|
// src/tui/application/create.ts
|
|
6083
|
-
import { join as
|
|
6083
|
+
import { join as join54 } from "path";
|
|
6084
6084
|
import { realpathSync as realpathSync17 } from "fs";
|
|
6085
6085
|
async function createView(input) {
|
|
6086
6086
|
const plan2 = planLayout(input.columns, input.rows);
|
|
@@ -6102,7 +6102,7 @@ async function createView(input) {
|
|
|
6102
6102
|
);
|
|
6103
6103
|
if (!main2) throw new Error("view_requires_live_main");
|
|
6104
6104
|
const { directory, owner } = createDirectory();
|
|
6105
|
-
const file2 =
|
|
6105
|
+
const file2 = join54(directory, "view.json");
|
|
6106
6106
|
const connection = new ViewConnection(directory, owner);
|
|
6107
6107
|
const argv = [helpers.node, helpers.worker, "attach", file2, main2.id];
|
|
6108
6108
|
const result = connection.raw([
|
|
@@ -6330,7 +6330,7 @@ var init_navigation = __esm({
|
|
|
6330
6330
|
});
|
|
6331
6331
|
|
|
6332
6332
|
// src/tui/application/history.ts
|
|
6333
|
-
import { join as
|
|
6333
|
+
import { join as join55 } from "path";
|
|
6334
6334
|
async function observeHistory(context) {
|
|
6335
6335
|
const { view, renderer, common: common2, file: file2 } = context;
|
|
6336
6336
|
await releaseControl(context);
|
|
@@ -6338,7 +6338,7 @@ async function observeHistory(context) {
|
|
|
6338
6338
|
sessionId: view.target,
|
|
6339
6339
|
input: { lines: 2e3, maxBytes: 65536 }
|
|
6340
6340
|
});
|
|
6341
|
-
privateJson(
|
|
6341
|
+
privateJson(join55(view.directory, "history.json"), {
|
|
6342
6342
|
sessionId: view.target,
|
|
6343
6343
|
content: history.content,
|
|
6344
6344
|
truncated: history.truncated
|
|
@@ -6415,7 +6415,7 @@ var init_mailbox = __esm({
|
|
|
6415
6415
|
|
|
6416
6416
|
// src/tui/application/lifecycle.ts
|
|
6417
6417
|
import { existsSync as existsSync36, unlinkSync as unlinkSync7 } from "fs";
|
|
6418
|
-
import { join as
|
|
6418
|
+
import { join as join56 } from "path";
|
|
6419
6419
|
function resizeView({ view, renderer, input }) {
|
|
6420
6420
|
renderer.resize(view, planLayout(input.columns, input.rows));
|
|
6421
6421
|
}
|
|
@@ -6430,7 +6430,7 @@ async function stopTarget(context) {
|
|
|
6430
6430
|
async function closeView(context) {
|
|
6431
6431
|
await returnToMain(context);
|
|
6432
6432
|
context.renderer.connection.cleanup();
|
|
6433
|
-
const history =
|
|
6433
|
+
const history = join56(context.view.directory, "history.json");
|
|
6434
6434
|
if (existsSync36(history)) unlinkSync7(history);
|
|
6435
6435
|
context.view.state = "closed";
|
|
6436
6436
|
saveView(context.file, context.view);
|
|
@@ -6772,14 +6772,14 @@ var init_config3 = __esm({
|
|
|
6772
6772
|
import { createHash as createHash19 } from "crypto";
|
|
6773
6773
|
import { existsSync as existsSync37, lstatSync as lstatSync13, mkdirSync as mkdirSync12 } from "fs";
|
|
6774
6774
|
import { homedir as homedir11 } from "os";
|
|
6775
|
-
import { dirname as dirname26, join as
|
|
6775
|
+
import { dirname as dirname26, join as join57 } from "path";
|
|
6776
6776
|
function startupFile(projectRoot) {
|
|
6777
|
-
const root =
|
|
6778
|
-
process.env.XDG_STATE_HOME ??
|
|
6777
|
+
const root = join57(
|
|
6778
|
+
process.env.XDG_STATE_HOME ?? join57(homedir11(), ".local/state"),
|
|
6779
6779
|
"pmcp/launcher"
|
|
6780
6780
|
);
|
|
6781
6781
|
const key = createHash19("sha256").update(projectRoot).digest("hex");
|
|
6782
|
-
return
|
|
6782
|
+
return join57(root, `${key}.json`);
|
|
6783
6783
|
}
|
|
6784
6784
|
function ensureStartupDirectory(file2) {
|
|
6785
6785
|
const directory = dirname26(file2);
|
|
@@ -7009,14 +7009,14 @@ var init_host = __esm({
|
|
|
7009
7009
|
});
|
|
7010
7010
|
|
|
7011
7011
|
// src/tui/startup/lock.ts
|
|
7012
|
-
import { spawnSync as
|
|
7013
|
-
import { closeSync as
|
|
7012
|
+
import { spawnSync as spawnSync7 } from "child_process";
|
|
7013
|
+
import { closeSync as closeSync9, constants as constants7, fstatSync as fstatSync5, openSync as openSync9 } from "fs";
|
|
7014
7014
|
function serializedStartup(request3) {
|
|
7015
7015
|
const settings2 = startupSettings(request3);
|
|
7016
7016
|
const file2 = startupFile(settings2.projectRoot);
|
|
7017
7017
|
ensureStartupDirectory(file2);
|
|
7018
7018
|
const lock = `${file2}.lock`;
|
|
7019
|
-
const descriptor =
|
|
7019
|
+
const descriptor = openSync9(
|
|
7020
7020
|
lock,
|
|
7021
7021
|
constants7.O_CREAT | constants7.O_WRONLY | constants7.O_NOFOLLOW,
|
|
7022
7022
|
384
|
|
@@ -7026,11 +7026,11 @@ function serializedStartup(request3) {
|
|
|
7026
7026
|
if (!stat.isFile() || stat.uid !== process.getuid?.() || (stat.mode & 63) !== 0)
|
|
7027
7027
|
throw new Error("unsafe_startup_lock");
|
|
7028
7028
|
} finally {
|
|
7029
|
-
|
|
7029
|
+
closeSync9(descriptor);
|
|
7030
7030
|
}
|
|
7031
7031
|
const helpers = runtime();
|
|
7032
7032
|
const encoded = Buffer.from(JSON.stringify(request3)).toString("base64url");
|
|
7033
|
-
const child =
|
|
7033
|
+
const child = spawnSync7(
|
|
7034
7034
|
"flock",
|
|
7035
7035
|
[
|
|
7036
7036
|
"--wait",
|
|
@@ -9859,7 +9859,7 @@ function registerMailboxTools(server, service) {
|
|
|
9859
9859
|
|
|
9860
9860
|
// src/mcp.ts
|
|
9861
9861
|
var SERVER_NAME = "pmcp";
|
|
9862
|
-
var SERVER_VERSION = "0.17.
|
|
9862
|
+
var SERVER_VERSION = "0.17.1";
|
|
9863
9863
|
function registerSkillTools(server, tools) {
|
|
9864
9864
|
registerCatalogTool(server, tools);
|
|
9865
9865
|
registerFindTool(server, tools);
|
|
@@ -14317,14 +14317,17 @@ async function execMcp(spec, alias, env) {
|
|
|
14317
14317
|
}
|
|
14318
14318
|
|
|
14319
14319
|
// src/project/doctor.ts
|
|
14320
|
-
import { spawnSync as
|
|
14321
|
-
import { existsSync as existsSync22, readFileSync as
|
|
14322
|
-
import { join as
|
|
14320
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
14321
|
+
import { existsSync as existsSync22, readFileSync as readFileSync29 } from "fs";
|
|
14322
|
+
import { join as join28 } from "path";
|
|
14323
14323
|
import { parse as parse8 } from "smol-toml";
|
|
14324
14324
|
|
|
14325
14325
|
// src/project/adapters/opencode-doctor.ts
|
|
14326
14326
|
import { realpathSync as realpathSync6 } from "fs";
|
|
14327
14327
|
import { join as join26 } from "path";
|
|
14328
|
+
function isOpenCodeInventory(command3, args) {
|
|
14329
|
+
return command3 === "opencode" && args.length === 2 && args[0] === "debug" && args[1] === "skill";
|
|
14330
|
+
}
|
|
14328
14331
|
function connected(out, alias) {
|
|
14329
14332
|
const ansi = new RegExp(
|
|
14330
14333
|
`${String.fromCharCode(27)}\\[[0-?]*[ -/]*[@-~]`,
|
|
@@ -14379,9 +14382,60 @@ function opencodeDoctor(spec, options2, listed2) {
|
|
|
14379
14382
|
return findings;
|
|
14380
14383
|
}
|
|
14381
14384
|
|
|
14385
|
+
// src/project/diagnostics/native-json.ts
|
|
14386
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
14387
|
+
import {
|
|
14388
|
+
closeSync as closeSync4,
|
|
14389
|
+
mkdtempSync as mkdtempSync3,
|
|
14390
|
+
openSync as openSync4,
|
|
14391
|
+
readFileSync as readFileSync28,
|
|
14392
|
+
rmSync as rmSync6,
|
|
14393
|
+
statSync as statSync13
|
|
14394
|
+
} from "fs";
|
|
14395
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
14396
|
+
import { join as join27 } from "path";
|
|
14397
|
+
var MAX_OUTPUT = 1 << 26;
|
|
14398
|
+
var nativeJsonRunner = (command3, args, cwd, env) => {
|
|
14399
|
+
const directory = mkdtempSync3(join27(tmpdir2(), "pmcp-native-json-"));
|
|
14400
|
+
let descriptor;
|
|
14401
|
+
try {
|
|
14402
|
+
const file2 = join27(directory, "stdout.json");
|
|
14403
|
+
descriptor = openSync4(file2, "wx", 384);
|
|
14404
|
+
const result = spawnSync3(command3, [...args], {
|
|
14405
|
+
cwd,
|
|
14406
|
+
...env ? { env: { ...process.env, ...env } } : {},
|
|
14407
|
+
encoding: "utf8",
|
|
14408
|
+
timeout: 18e4,
|
|
14409
|
+
maxBuffer: MAX_OUTPUT,
|
|
14410
|
+
stdio: ["ignore", descriptor, "pipe"]
|
|
14411
|
+
});
|
|
14412
|
+
const code = result.error?.code;
|
|
14413
|
+
if (result.status !== 0 || result.error) {
|
|
14414
|
+
return {
|
|
14415
|
+
missing: code === "ENOENT",
|
|
14416
|
+
status: result.status,
|
|
14417
|
+
stdout: result.stderr || result.error?.message || "Native inventory failed"
|
|
14418
|
+
};
|
|
14419
|
+
}
|
|
14420
|
+
if (statSync13(file2).size > MAX_OUTPUT) {
|
|
14421
|
+
return {
|
|
14422
|
+
missing: false,
|
|
14423
|
+
status: null,
|
|
14424
|
+
stdout: "Native JSON output exceeds 64 MiB"
|
|
14425
|
+
};
|
|
14426
|
+
}
|
|
14427
|
+
return { missing: false, status: 0, stdout: readFileSync28(file2, "utf8") };
|
|
14428
|
+
} finally {
|
|
14429
|
+
if (descriptor !== void 0) closeSync4(descriptor);
|
|
14430
|
+
rmSync6(directory, { recursive: true, force: true });
|
|
14431
|
+
}
|
|
14432
|
+
};
|
|
14433
|
+
|
|
14382
14434
|
// src/project/doctor.ts
|
|
14383
14435
|
var spawnRunner = (command3, args, cwd, env) => {
|
|
14384
|
-
|
|
14436
|
+
if (isOpenCodeInventory(command3, args))
|
|
14437
|
+
return nativeJsonRunner(command3, args, cwd, env);
|
|
14438
|
+
const result = spawnSync4(command3, [...args], {
|
|
14385
14439
|
cwd,
|
|
14386
14440
|
...env ? { env: { ...process.env, ...env } } : {},
|
|
14387
14441
|
encoding: "utf8",
|
|
@@ -14455,10 +14509,10 @@ function claude(spec, o) {
|
|
|
14455
14509
|
}
|
|
14456
14510
|
function codex(spec, o) {
|
|
14457
14511
|
const findings = [];
|
|
14458
|
-
const config =
|
|
14512
|
+
const config = join28(o.home, ".codex/config.toml");
|
|
14459
14513
|
let trusted = false;
|
|
14460
14514
|
if (existsSync22(config)) {
|
|
14461
|
-
const projects = parse8(
|
|
14515
|
+
const projects = parse8(readFileSync29(config, "utf8")).projects ?? {};
|
|
14462
14516
|
const root = spec.root.replace(/\/$/u, "");
|
|
14463
14517
|
trusted = projects[root]?.trust_level === "trusted" || projects[`${root}/`]?.trust_level === "trusted";
|
|
14464
14518
|
}
|
|
@@ -14584,8 +14638,8 @@ function grok(spec, o) {
|
|
|
14584
14638
|
}
|
|
14585
14639
|
function antigravity(spec, options2) {
|
|
14586
14640
|
const foreign = agentNames(spec.root).filter((name) => {
|
|
14587
|
-
const text3 =
|
|
14588
|
-
|
|
14641
|
+
const text3 = readFileSync29(
|
|
14642
|
+
join28(spec.root, ".agents/agents", name, "agent.md"),
|
|
14589
14643
|
"utf8"
|
|
14590
14644
|
);
|
|
14591
14645
|
return splitFrontmatter(text3).meta["tools"] !== void 0;
|
|
@@ -14605,7 +14659,7 @@ function antigravity(spec, options2) {
|
|
|
14605
14659
|
if (serversForTool(spec, "antigravity").length > 0) {
|
|
14606
14660
|
const result = options2.run(
|
|
14607
14661
|
"agy",
|
|
14608
|
-
["plugin", "validate",
|
|
14662
|
+
["plugin", "validate", join28(spec.root, ANTIGRAVITY_MCP_PLUGIN)],
|
|
14609
14663
|
spec.root
|
|
14610
14664
|
);
|
|
14611
14665
|
findings.push(
|
|
@@ -14638,8 +14692,8 @@ function doctor(spec, options2) {
|
|
|
14638
14692
|
}
|
|
14639
14693
|
|
|
14640
14694
|
// src/project/memory.ts
|
|
14641
|
-
import { existsSync as existsSync23, readFileSync as
|
|
14642
|
-
import { isAbsolute as isAbsolute7, join as
|
|
14695
|
+
import { existsSync as existsSync23, readFileSync as readFileSync30 } from "fs";
|
|
14696
|
+
import { isAbsolute as isAbsolute7, join as join29, resolve as resolve15 } from "path";
|
|
14643
14697
|
import { parse as parse9 } from "smol-toml";
|
|
14644
14698
|
function object7(value) {
|
|
14645
14699
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -14651,7 +14705,7 @@ function settings(file2, toml = false) {
|
|
|
14651
14705
|
if (!existsSync23(file2)) {
|
|
14652
14706
|
return {};
|
|
14653
14707
|
}
|
|
14654
|
-
const text3 =
|
|
14708
|
+
const text3 = readFileSync30(file2, "utf8");
|
|
14655
14709
|
return object7(toml ? parse9(text3) : JSON.parse(text3));
|
|
14656
14710
|
}
|
|
14657
14711
|
function configuredState(value) {
|
|
@@ -14668,7 +14722,7 @@ function located(metadata2, path, pathScope) {
|
|
|
14668
14722
|
}
|
|
14669
14723
|
function metadata(tool, spec, options2) {
|
|
14670
14724
|
const env = options2.env ?? {};
|
|
14671
|
-
const directory = (name, fallback) => resolve15(spec.root, env[name] ??
|
|
14725
|
+
const directory = (name, fallback) => resolve15(spec.root, env[name] ?? join29(options2.home, fallback));
|
|
14672
14726
|
if (tool === "opencode") {
|
|
14673
14727
|
return {
|
|
14674
14728
|
state: "unsupported",
|
|
@@ -14698,7 +14752,7 @@ function metadata(tool, spec, options2) {
|
|
|
14698
14752
|
state,
|
|
14699
14753
|
source: result.missing ? "Native CLI not installed" : "codex features list; active session overrides are not inspected"
|
|
14700
14754
|
},
|
|
14701
|
-
|
|
14755
|
+
join29(home2, "memories"),
|
|
14702
14756
|
"store"
|
|
14703
14757
|
);
|
|
14704
14758
|
}
|
|
@@ -14711,12 +14765,12 @@ function metadata(tool, spec, options2) {
|
|
|
14711
14765
|
}
|
|
14712
14766
|
if (tool === "claude") {
|
|
14713
14767
|
const home2 = directory("CLAUDE_CONFIG_DIR", ".claude");
|
|
14714
|
-
const user2 = settings(
|
|
14768
|
+
const user2 = settings(join29(home2, "settings.json"));
|
|
14715
14769
|
const state = env["CLAUDE_CODE_DISABLE_AUTO_MEMORY"] === "1" ? "disabled" : configuredState(user2["autoMemoryEnabled"]);
|
|
14716
14770
|
const source2 = "User configuration and disable environment flag; project trust and active session overrides are not inspected";
|
|
14717
14771
|
const override = user2["autoMemoryDirectory"];
|
|
14718
14772
|
if (typeof override === "string") {
|
|
14719
|
-
const path = override.startsWith("~/") ?
|
|
14773
|
+
const path = override.startsWith("~/") ? join29(options2.home, override.slice(2)) : override;
|
|
14720
14774
|
if (!isAbsolute7(path)) {
|
|
14721
14775
|
return {
|
|
14722
14776
|
state: "unknown",
|
|
@@ -14729,7 +14783,7 @@ function metadata(tool, spec, options2) {
|
|
|
14729
14783
|
if (env["CLAUDE_CONFIG_DIR"] && projectName && !projectName.includes("/") && !projectName.includes("\\") && projectName !== "." && projectName !== "..") {
|
|
14730
14784
|
return located(
|
|
14731
14785
|
{ state, source: source2 },
|
|
14732
|
-
|
|
14786
|
+
join29(home2, "projects", projectName, "memory"),
|
|
14733
14787
|
"store"
|
|
14734
14788
|
);
|
|
14735
14789
|
}
|
|
@@ -14738,14 +14792,14 @@ function metadata(tool, spec, options2) {
|
|
|
14738
14792
|
state,
|
|
14739
14793
|
source: `${source2}; native project directory encoding is not guessed`
|
|
14740
14794
|
},
|
|
14741
|
-
|
|
14795
|
+
join29(home2, "projects"),
|
|
14742
14796
|
"base"
|
|
14743
14797
|
);
|
|
14744
14798
|
}
|
|
14745
14799
|
if (tool === "grok") {
|
|
14746
|
-
const home2 =
|
|
14747
|
-
const user2 = settings(
|
|
14748
|
-
const project2 = settings(
|
|
14800
|
+
const home2 = join29(options2.home, ".grok");
|
|
14801
|
+
const user2 = settings(join29(home2, "config.toml"), true);
|
|
14802
|
+
const project2 = settings(join29(spec.root, ".grok/config.toml"), true);
|
|
14749
14803
|
const userMemory = user2["memory"] === void 0 ? {} : object7(user2["memory"]);
|
|
14750
14804
|
const projectMemory = project2["memory"] === void 0 ? {} : object7(project2["memory"]);
|
|
14751
14805
|
const overridden = projectMemory["enabled"] !== void 0;
|
|
@@ -14755,12 +14809,12 @@ function metadata(tool, spec, options2) {
|
|
|
14755
14809
|
state,
|
|
14756
14810
|
source: "User memory configuration; project trust and workspace encoding are not exposed by a read-only native memory command"
|
|
14757
14811
|
},
|
|
14758
|
-
|
|
14812
|
+
join29(home2, "memory-v2/workspaces"),
|
|
14759
14813
|
"base"
|
|
14760
14814
|
);
|
|
14761
14815
|
}
|
|
14762
14816
|
const home = directory("GEMINI_CLI_HOME", ".gemini");
|
|
14763
|
-
const user = settings(
|
|
14817
|
+
const user = settings(join29(home, "settings.json"));
|
|
14764
14818
|
const context = user["context"] === void 0 ? {} : object7(user["context"]);
|
|
14765
14819
|
const names = context["fileName"] ?? "GEMINI.md";
|
|
14766
14820
|
const contextFileNames = typeof names === "string" ? [names] : names;
|
|
@@ -14776,7 +14830,7 @@ function metadata(tool, spec, options2) {
|
|
|
14776
14830
|
source: "Global memory file existence and user context filenames; active memory tool enablement is not exposed",
|
|
14777
14831
|
contextFileNames
|
|
14778
14832
|
},
|
|
14779
|
-
|
|
14833
|
+
join29(home, "GEMINI.md"),
|
|
14780
14834
|
"store"
|
|
14781
14835
|
);
|
|
14782
14836
|
}
|
|
@@ -14811,12 +14865,12 @@ import {
|
|
|
14811
14865
|
cpSync,
|
|
14812
14866
|
existsSync as existsSync24,
|
|
14813
14867
|
mkdirSync as mkdirSync8,
|
|
14814
|
-
readFileSync as
|
|
14815
|
-
rmSync as
|
|
14816
|
-
statSync as
|
|
14868
|
+
readFileSync as readFileSync31,
|
|
14869
|
+
rmSync as rmSync7,
|
|
14870
|
+
statSync as statSync14,
|
|
14817
14871
|
writeFileSync as writeFileSync7
|
|
14818
14872
|
} from "fs";
|
|
14819
|
-
import { basename as basename7, dirname as dirname20, join as
|
|
14873
|
+
import { basename as basename7, dirname as dirname20, join as join30 } from "path";
|
|
14820
14874
|
var CROSS_TOOL = ["name", "description"];
|
|
14821
14875
|
var tomlValue2 = (value) => JSON.stringify(value);
|
|
14822
14876
|
function findEntry(entries, wanted) {
|
|
@@ -14840,7 +14894,7 @@ function addEntry(root, entry2) {
|
|
|
14840
14894
|
`${entry2.name} is a ${kind2}; only skills and agents are added to .agents/`
|
|
14841
14895
|
);
|
|
14842
14896
|
}
|
|
14843
|
-
const { meta, body } = splitFrontmatter(
|
|
14897
|
+
const { meta, body } = splitFrontmatter(readFileSync31(entry2.path, "utf8"));
|
|
14844
14898
|
const name = basename7(entry2.slug);
|
|
14845
14899
|
if (!/^[a-z0-9][a-z0-9-]*$/u.test(name)) {
|
|
14846
14900
|
throw new ProjectError(
|
|
@@ -14848,12 +14902,12 @@ function addEntry(root, entry2) {
|
|
|
14848
14902
|
);
|
|
14849
14903
|
}
|
|
14850
14904
|
if (kind2 === "skill") {
|
|
14851
|
-
const dest2 =
|
|
14905
|
+
const dest2 = join30(root, ".agents/skills", name);
|
|
14852
14906
|
if (existsSync24(dest2))
|
|
14853
14907
|
throw new ProjectError(`.agents/skills/${name} already exists`);
|
|
14854
14908
|
const source2 = entry2.root ?? dirname20(entry2.path);
|
|
14855
14909
|
mkdirSync8(dirname20(dest2), { recursive: true });
|
|
14856
|
-
if (
|
|
14910
|
+
if (statSync14(source2).isDirectory()) {
|
|
14857
14911
|
cpSync(source2, dest2, { recursive: true });
|
|
14858
14912
|
} else {
|
|
14859
14913
|
mkdirSync8(dest2);
|
|
@@ -14864,13 +14918,13 @@ function addEntry(root, entry2) {
|
|
|
14864
14918
|
description: meta["description"] ?? entry2.description
|
|
14865
14919
|
});
|
|
14866
14920
|
writeFileSync7(
|
|
14867
|
-
|
|
14921
|
+
join30(dest2, "SKILL.md"),
|
|
14868
14922
|
`${head}
|
|
14869
14923
|
${body.replace(/^\n/u, "")}`
|
|
14870
14924
|
);
|
|
14871
14925
|
return { kind: kind2, name, path: `.agents/skills/${name}` };
|
|
14872
14926
|
}
|
|
14873
|
-
const dest =
|
|
14927
|
+
const dest = join30(root, ".agents/agents", name);
|
|
14874
14928
|
if (existsSync24(dest))
|
|
14875
14929
|
throw new ProjectError(`.agents/agents/${name} already exists`);
|
|
14876
14930
|
const kept = {};
|
|
@@ -14881,17 +14935,17 @@ ${body.replace(/^\n/u, "")}`
|
|
|
14881
14935
|
}
|
|
14882
14936
|
mkdirSync8(dest, { recursive: true });
|
|
14883
14937
|
writeFileSync7(
|
|
14884
|
-
|
|
14938
|
+
join30(dest, "agent.md"),
|
|
14885
14939
|
`${renderFrontmatter(kept)}
|
|
14886
14940
|
${body.replace(/^\n/u, "")}`
|
|
14887
14941
|
);
|
|
14888
14942
|
if (Object.keys(moved).length > 0) {
|
|
14889
|
-
const config =
|
|
14943
|
+
const config = join30(root, "pmcp.toml");
|
|
14890
14944
|
const lines2 = [
|
|
14891
14945
|
`[agents.${name}.claude]`,
|
|
14892
14946
|
...Object.entries(moved).map(([k, v]) => `${k} = ${tomlValue2(v)}`)
|
|
14893
14947
|
];
|
|
14894
|
-
const before = existsSync24(config) ?
|
|
14948
|
+
const before = existsSync24(config) ? readFileSync31(config, "utf8") : "";
|
|
14895
14949
|
const sep7 = before === "" || before.endsWith("\n\n") ? "" : "\n";
|
|
14896
14950
|
writeFileSync7(config, `${before}${sep7}${lines2.join("\n")}
|
|
14897
14951
|
`);
|
|
@@ -14914,15 +14968,15 @@ function withoutTables(toml, name) {
|
|
|
14914
14968
|
function removeAsset(root, name) {
|
|
14915
14969
|
const removed = [];
|
|
14916
14970
|
for (const rel of [`.agents/skills/${name}`, `.agents/agents/${name}`]) {
|
|
14917
|
-
if (!existsSync24(
|
|
14918
|
-
|
|
14971
|
+
if (!existsSync24(join30(root, rel))) continue;
|
|
14972
|
+
rmSync7(join30(root, rel), { recursive: true, force: true });
|
|
14919
14973
|
removed.push(rel);
|
|
14920
14974
|
}
|
|
14921
14975
|
if (removed.length === 0)
|
|
14922
14976
|
throw new ProjectError(`no skill or agent named ${name} in .agents/`);
|
|
14923
|
-
const config =
|
|
14977
|
+
const config = join30(root, "pmcp.toml");
|
|
14924
14978
|
if (existsSync24(config)) {
|
|
14925
|
-
const before =
|
|
14979
|
+
const before = readFileSync31(config, "utf8");
|
|
14926
14980
|
const after = withoutTables(before, name);
|
|
14927
14981
|
if (after !== before) writeFileSync7(config, after);
|
|
14928
14982
|
}
|
|
@@ -15161,16 +15215,16 @@ var doctorCommand = {
|
|
|
15161
15215
|
};
|
|
15162
15216
|
|
|
15163
15217
|
// src/validate.ts
|
|
15164
|
-
import { existsSync as existsSync25, readFileSync as
|
|
15165
|
-
import { basename as basename8, join as
|
|
15218
|
+
import { existsSync as existsSync25, readFileSync as readFileSync32, statSync as statSync15 } from "fs";
|
|
15219
|
+
import { basename as basename8, join as join31, resolve as resolve16 } from "path";
|
|
15166
15220
|
function validateSkillDir(dir) {
|
|
15167
15221
|
const root = resolve16(dir);
|
|
15168
|
-
const skillMd = basename8(root) === "SKILL.md" ? root :
|
|
15169
|
-
if (!existsSync25(skillMd) || !
|
|
15222
|
+
const skillMd = basename8(root) === "SKILL.md" ? root : join31(root, "SKILL.md");
|
|
15223
|
+
if (!existsSync25(skillMd) || !statSync15(skillMd).isFile()) {
|
|
15170
15224
|
return [{ path: root, reason: "no SKILL.md", level: "error" }];
|
|
15171
15225
|
}
|
|
15172
|
-
const front = frontmatterObject(
|
|
15173
|
-
const directory = basename8(skillMd === root ?
|
|
15226
|
+
const front = frontmatterObject(readFileSync32(skillMd, "utf8"));
|
|
15227
|
+
const directory = basename8(skillMd === root ? join31(root, "..") : root);
|
|
15174
15228
|
return specProblems(front, directory).map((reason) => ({
|
|
15175
15229
|
path: skillMd,
|
|
15176
15230
|
reason,
|
|
@@ -15215,7 +15269,7 @@ var validateCommand = {
|
|
|
15215
15269
|
};
|
|
15216
15270
|
|
|
15217
15271
|
// src/commands/mailbox.ts
|
|
15218
|
-
import { readFileSync as
|
|
15272
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync8 } from "fs";
|
|
15219
15273
|
import { resolve as resolve17 } from "path";
|
|
15220
15274
|
init_config2();
|
|
15221
15275
|
init_service();
|
|
@@ -15398,7 +15452,7 @@ var mailboxCommand = {
|
|
|
15398
15452
|
ownsBinding = true;
|
|
15399
15453
|
}
|
|
15400
15454
|
const inputFile = one(context.args, "input");
|
|
15401
|
-
const input = inputFile ? JSON.parse(
|
|
15455
|
+
const input = inputFile ? JSON.parse(readFileSync33(inputFile, "utf8")) : {};
|
|
15402
15456
|
const result = await new MailboxService(store, binding).call(
|
|
15403
15457
|
operation,
|
|
15404
15458
|
input
|
|
@@ -15482,7 +15536,7 @@ var harnessOptions = [
|
|
|
15482
15536
|
];
|
|
15483
15537
|
|
|
15484
15538
|
// src/commands/harness/invocation.ts
|
|
15485
|
-
import { readFileSync as
|
|
15539
|
+
import { readFileSync as readFileSync34, statSync as statSync16 } from "fs";
|
|
15486
15540
|
init_validation();
|
|
15487
15541
|
var common = ["group-file", "generation"];
|
|
15488
15542
|
var options = {
|
|
@@ -15519,10 +15573,10 @@ var options = {
|
|
|
15519
15573
|
"recovery:abort-start": [...common, "session"]
|
|
15520
15574
|
};
|
|
15521
15575
|
function file(path) {
|
|
15522
|
-
const stat =
|
|
15576
|
+
const stat = statSync16(path);
|
|
15523
15577
|
if (!stat.isFile() || stat.size > 65536)
|
|
15524
15578
|
throw new ArgumentError("Input file exceeds 65536 bytes");
|
|
15525
|
-
return
|
|
15579
|
+
return readFileSync34(path, "utf8");
|
|
15526
15580
|
}
|
|
15527
15581
|
function parseInvocation(context) {
|
|
15528
15582
|
const [family, action, ...extra] = context.args.positional;
|
|
@@ -15858,11 +15912,11 @@ import {
|
|
|
15858
15912
|
existsSync as existsSync38,
|
|
15859
15913
|
lstatSync as lstatSync14,
|
|
15860
15914
|
mkdirSync as mkdirSync13,
|
|
15861
|
-
readFileSync as
|
|
15915
|
+
readFileSync as readFileSync39,
|
|
15862
15916
|
readdirSync as readdirSync13,
|
|
15863
15917
|
writeFileSync as writeFileSync14
|
|
15864
15918
|
} from "fs";
|
|
15865
|
-
import { dirname as dirname27, join as
|
|
15919
|
+
import { dirname as dirname27, join as join58, resolve as resolve20 } from "path";
|
|
15866
15920
|
var NATIVE_PLUGIN_RUNTIMES = [
|
|
15867
15921
|
"claude",
|
|
15868
15922
|
"codex",
|
|
@@ -15887,7 +15941,7 @@ function readResources(directory, prefix, files) {
|
|
|
15887
15941
|
for (const entry2 of readdirSync13(directory, { withFileTypes: true })) {
|
|
15888
15942
|
if (entry2.isSymbolicLink())
|
|
15889
15943
|
throw new Error("Plugin exports cannot contain symlinks");
|
|
15890
|
-
const path =
|
|
15944
|
+
const path = join58(directory, entry2.name);
|
|
15891
15945
|
const relativePath = `${prefix}/${entry2.name}`;
|
|
15892
15946
|
if (entry2.isDirectory()) {
|
|
15893
15947
|
if (relativePath.split("/").length > 6)
|
|
@@ -15900,7 +15954,7 @@ function readResources(directory, prefix, files) {
|
|
|
15900
15954
|
const stats = lstatSync14(path);
|
|
15901
15955
|
if (stats.size > 1024 * 1024 || files.size >= 256)
|
|
15902
15956
|
throw new Error("Plugin resources exceed the export budget");
|
|
15903
|
-
files.set(relativePath,
|
|
15957
|
+
files.set(relativePath, readFileSync39(path));
|
|
15904
15958
|
}
|
|
15905
15959
|
}
|
|
15906
15960
|
function pluginExportFiles(root, name, runtime2) {
|
|
@@ -15909,7 +15963,7 @@ function pluginExportFiles(root, name, runtime2) {
|
|
|
15909
15963
|
const files = /* @__PURE__ */ new Map();
|
|
15910
15964
|
readResources(containedPath(plugin.directory, "skills"), "skills", files);
|
|
15911
15965
|
for (const name2 of ["LICENSE", "NOTICE"])
|
|
15912
|
-
files.set(name2,
|
|
15966
|
+
files.set(name2, readFileSync39(containedPath(root, name2)));
|
|
15913
15967
|
const manifests = {
|
|
15914
15968
|
claude: [".claude-plugin/plugin.json", ".mcp.json"],
|
|
15915
15969
|
codex: ["plugin.json", "mcp.json"],
|
|
@@ -15918,10 +15972,10 @@ function pluginExportFiles(root, name, runtime2) {
|
|
|
15918
15972
|
agy: []
|
|
15919
15973
|
};
|
|
15920
15974
|
for (const filename of manifests[runtime2]) {
|
|
15921
|
-
if (existsSync38(
|
|
15975
|
+
if (existsSync38(join58(plugin.directory, filename)))
|
|
15922
15976
|
files.set(
|
|
15923
15977
|
filename,
|
|
15924
|
-
|
|
15978
|
+
readFileSync39(containedPath(plugin.directory, filename))
|
|
15925
15979
|
);
|
|
15926
15980
|
}
|
|
15927
15981
|
if (runtime2 === "agy") {
|
|
@@ -15932,11 +15986,11 @@ function pluginExportFiles(root, name, runtime2) {
|
|
|
15932
15986
|
`
|
|
15933
15987
|
)
|
|
15934
15988
|
);
|
|
15935
|
-
const mcp =
|
|
15989
|
+
const mcp = join58(plugin.directory, ".mcp.json");
|
|
15936
15990
|
if (existsSync38(mcp))
|
|
15937
15991
|
files.set(
|
|
15938
15992
|
"mcp_config.json",
|
|
15939
|
-
|
|
15993
|
+
readFileSync39(containedPath(plugin.directory, mcp))
|
|
15940
15994
|
);
|
|
15941
15995
|
}
|
|
15942
15996
|
return files;
|
|
@@ -15955,7 +16009,7 @@ function exportPublicPlugin(root, name, runtime2, output) {
|
|
|
15955
16009
|
throw error;
|
|
15956
16010
|
}
|
|
15957
16011
|
for (const [path, bytes] of files) {
|
|
15958
|
-
const target2 =
|
|
16012
|
+
const target2 = join58(destination, path);
|
|
15959
16013
|
mkdirSync13(dirname27(target2), { recursive: true });
|
|
15960
16014
|
writeFileSync14(target2, bytes, { flag: "wx" });
|
|
15961
16015
|
}
|
|
@@ -16107,7 +16161,7 @@ function dispatch(argv, options2 = {}) {
|
|
|
16107
16161
|
}
|
|
16108
16162
|
return run(command3, rest, { ui, env, cwd });
|
|
16109
16163
|
}
|
|
16110
|
-
var VERSION = "0.17.
|
|
16164
|
+
var VERSION = "0.17.1";
|
|
16111
16165
|
async function defaultEntry(options2, context) {
|
|
16112
16166
|
const terminal = options2.terminal ?? {
|
|
16113
16167
|
stdin: process.stdin.isTTY === true,
|