agentwheel 0.16.2 → 0.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/index.js +255 -176
- package/openpack.json +1 -1
- package/package.json +1 -1
- package/skills/agentwheel/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -189,6 +189,12 @@ agentwheel install mcp-registry:publisher/server-name --adapter claude --local
|
|
|
189
189
|
agentwheel install clawhub:@openclaw/whatsapp --adapter openclaw --local
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
### Private GitHub sources
|
|
193
|
+
|
|
194
|
+
OpenPack manifests stay portable and do not contain personal GitHub accounts or tokens. Configure
|
|
195
|
+
local `gh` accounts through a user-local auth profile; see [Git Authentication](docs/git-authentication.md)
|
|
196
|
+
for the configuration format and runtime behavior.
|
|
197
|
+
|
|
192
198
|
`mcp-registry:<server-name>` reads the public MCP Registry and stages a generated OpenPack package
|
|
193
199
|
only when the server exposes a safe unauthenticated `streamable-http` remote. Entries that require
|
|
194
200
|
secret headers or only publish native package instructions remain discovery-only until they are
|
package/dist/index.js
CHANGED
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
import { createHash as createHash12 } from "crypto";
|
|
13
13
|
import { existsSync } from "fs";
|
|
14
14
|
import { mkdir as mkdir23, rm as rm12, writeFile as writeFile22 } from "fs/promises";
|
|
15
|
-
import { homedir as
|
|
16
|
-
import { dirname as dirname32, join as
|
|
15
|
+
import { homedir as homedir11 } from "os";
|
|
16
|
+
import { dirname as dirname32, join as join46, resolve as resolve22 } from "path";
|
|
17
17
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
18
18
|
import { Command } from "commander";
|
|
19
19
|
|
|
@@ -5950,9 +5950,80 @@ function cachePathFor(packageName, cacheRoot) {
|
|
|
5950
5950
|
// src/source/git.ts
|
|
5951
5951
|
import { execFile as execFile4 } from "child_process";
|
|
5952
5952
|
import { cp as cp2, mkdir as mkdir13, rename as rename3, rm as rm6, writeFile as writeFile15 } from "fs/promises";
|
|
5953
|
-
import { homedir as
|
|
5954
|
-
import { basename as basename11, dirname as dirname16, join as
|
|
5953
|
+
import { homedir as homedir3 } from "os";
|
|
5954
|
+
import { basename as basename11, dirname as dirname16, join as join22, resolve as resolve7 } from "path";
|
|
5955
5955
|
import { promisify as promisify4 } from "util";
|
|
5956
|
+
|
|
5957
|
+
// src/source/auth.ts
|
|
5958
|
+
import { readFile as readFile18 } from "fs/promises";
|
|
5959
|
+
import { homedir as homedir2 } from "os";
|
|
5960
|
+
import { join as join21 } from "path";
|
|
5961
|
+
var AUTH_CONFIG_ENV = "AGENTWHEEL_AUTH_CONFIG";
|
|
5962
|
+
async function gitAuthArguments(url) {
|
|
5963
|
+
const profile = await matchingGitAuthProfile(url);
|
|
5964
|
+
if (!profile) return [];
|
|
5965
|
+
if (profile.provider !== "gh") {
|
|
5966
|
+
throw new Error(`Unsupported Agentwheel Git auth provider: ${profile.provider}`);
|
|
5967
|
+
}
|
|
5968
|
+
const account = shellQuote(profile.account);
|
|
5969
|
+
const helper = `!f() { echo username=x-access-token; echo password="$(gh auth token --user ${account})"; }; f`;
|
|
5970
|
+
return ["-c", "credential.helper=", "-c", `credential.helper=${helper}`];
|
|
5971
|
+
}
|
|
5972
|
+
async function matchingGitAuthProfile(url) {
|
|
5973
|
+
const config = await readGitAuthConfig();
|
|
5974
|
+
if (!config) return void 0;
|
|
5975
|
+
const repository = repositoryKey(url);
|
|
5976
|
+
return Object.values(config.profiles).find(
|
|
5977
|
+
(profile) => profile.repositories.some((pattern) => matchesRepository(pattern, repository))
|
|
5978
|
+
);
|
|
5979
|
+
}
|
|
5980
|
+
async function readGitAuthConfig() {
|
|
5981
|
+
const path = process.env[AUTH_CONFIG_ENV] ?? join21(homedir2(), ".agentwheel", "auth.json");
|
|
5982
|
+
try {
|
|
5983
|
+
const parsed = JSON.parse(await readFile18(path, "utf8"));
|
|
5984
|
+
return parseGitAuthConfig(parsed, path);
|
|
5985
|
+
} catch (error) {
|
|
5986
|
+
if (isMissingFile(error)) return void 0;
|
|
5987
|
+
if (error instanceof SyntaxError) throw new Error(`Invalid Agentwheel auth config JSON: ${path}`);
|
|
5988
|
+
throw error;
|
|
5989
|
+
}
|
|
5990
|
+
}
|
|
5991
|
+
function parseGitAuthConfig(value, path) {
|
|
5992
|
+
if (!isRecord8(value) || !isRecord8(value.profiles)) {
|
|
5993
|
+
throw new Error(`Invalid Agentwheel auth config: expected profiles in ${path}`);
|
|
5994
|
+
}
|
|
5995
|
+
const profiles = {};
|
|
5996
|
+
for (const [name, candidate] of Object.entries(value.profiles)) {
|
|
5997
|
+
if (!isRecord8(candidate) || candidate.provider !== "gh" || typeof candidate.account !== "string" || !Array.isArray(candidate.repositories)) {
|
|
5998
|
+
throw new Error(`Invalid Agentwheel auth profile '${name}' in ${path}`);
|
|
5999
|
+
}
|
|
6000
|
+
const repositories = candidate.repositories.filter((repository) => typeof repository === "string" && repository.length > 0);
|
|
6001
|
+
if (repositories.length !== candidate.repositories.length) {
|
|
6002
|
+
throw new Error(`Invalid repository matcher in Agentwheel auth profile '${name}' in ${path}`);
|
|
6003
|
+
}
|
|
6004
|
+
profiles[name] = { provider: "gh", account: candidate.account, repositories };
|
|
6005
|
+
}
|
|
6006
|
+
return { profiles };
|
|
6007
|
+
}
|
|
6008
|
+
function repositoryKey(url) {
|
|
6009
|
+
const parsed = new URL(url);
|
|
6010
|
+
return `${parsed.host}/${parsed.pathname.replace(/^\//, "").replace(/\.git$/, "")}`.toLowerCase();
|
|
6011
|
+
}
|
|
6012
|
+
function matchesRepository(pattern, repository) {
|
|
6013
|
+
const escaped = pattern.toLowerCase().replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
6014
|
+
return new RegExp(`^${escaped}$`).test(repository);
|
|
6015
|
+
}
|
|
6016
|
+
function shellQuote(value) {
|
|
6017
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
6018
|
+
}
|
|
6019
|
+
function isRecord8(value) {
|
|
6020
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6021
|
+
}
|
|
6022
|
+
function isMissingFile(error) {
|
|
6023
|
+
return isRecord8(error) && error.code === "ENOENT";
|
|
6024
|
+
}
|
|
6025
|
+
|
|
6026
|
+
// src/source/git.ts
|
|
5956
6027
|
var execFileAsync4 = promisify4(execFile4);
|
|
5957
6028
|
var GitSourceDriver = class {
|
|
5958
6029
|
name = "git";
|
|
@@ -5975,14 +6046,22 @@ var GitSourceDriver = class {
|
|
|
5975
6046
|
return withFilesystemLock(`${resolved.resolvedPath}.lock`, resolved.cacheLockTimeoutMs ?? 3e4, async () => {
|
|
5976
6047
|
const parsed = parseGitSource(resolved.source);
|
|
5977
6048
|
await mkdir13(resolve7(resolved.resolvedPath, ".."), { recursive: true });
|
|
5978
|
-
if (!await pathExists(
|
|
6049
|
+
if (!await pathExists(join22(resolved.resolvedPath, ".git"))) {
|
|
5979
6050
|
if (resolved.frozenLock) {
|
|
5980
6051
|
throw new Error(`Frozen lock requires cached git checkout at ${resolved.resolvedPath}`);
|
|
5981
6052
|
}
|
|
5982
6053
|
await rm6(resolved.resolvedPath, { recursive: true, force: true });
|
|
5983
|
-
await git(["clone", parsed.url, resolved.resolvedPath]);
|
|
6054
|
+
await git([...await gitAuthArguments(parsed.url), "clone", parsed.url, resolved.resolvedPath]);
|
|
5984
6055
|
} else if (!resolved.frozenLock) {
|
|
5985
|
-
await git([
|
|
6056
|
+
await git([
|
|
6057
|
+
...await gitAuthArguments(parsed.url),
|
|
6058
|
+
"-C",
|
|
6059
|
+
resolved.resolvedPath,
|
|
6060
|
+
"fetch",
|
|
6061
|
+
"--tags",
|
|
6062
|
+
"--prune",
|
|
6063
|
+
"origin"
|
|
6064
|
+
]);
|
|
5986
6065
|
}
|
|
5987
6066
|
const ref = resolved.requestedRef ?? parsed.ref ?? "HEAD";
|
|
5988
6067
|
if (ref === "HEAD") {
|
|
@@ -6042,20 +6121,20 @@ function parseGitSource(source) {
|
|
|
6042
6121
|
throw new Error(`Invalid git source: ${source}`);
|
|
6043
6122
|
}
|
|
6044
6123
|
function cachePathFor2(url, cacheRoot) {
|
|
6045
|
-
const root = cacheRoot ? resolve7(cacheRoot) :
|
|
6124
|
+
const root = cacheRoot ? resolve7(cacheRoot) : join22(homedir3(), ".agentwheel", "cache");
|
|
6046
6125
|
const slug2 = url.replace(/^[a-z]+:\/\//i, "").replace(/\.git$/i, "").replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "");
|
|
6047
|
-
return
|
|
6126
|
+
return join22(root, slug2 || basename11(url));
|
|
6048
6127
|
}
|
|
6049
6128
|
async function git(args) {
|
|
6050
6129
|
return execFileAsync4("git", args, { maxBuffer: 1024 * 1024 * 10 });
|
|
6051
6130
|
}
|
|
6052
6131
|
async function snapshotCheckout(checkoutPath, commit) {
|
|
6053
|
-
const snapshotPath =
|
|
6132
|
+
const snapshotPath = join22(dirname16(checkoutPath), `${basename11(checkoutPath)}-${commit.slice(0, 12)}`);
|
|
6054
6133
|
if (await pathExists(snapshotPath)) return snapshotPath;
|
|
6055
|
-
const tempPath =
|
|
6134
|
+
const tempPath = join22(dirname16(checkoutPath), `${basename11(snapshotPath)}.tmp-${process.pid}-${Date.now()}`);
|
|
6056
6135
|
await rm6(tempPath, { recursive: true, force: true });
|
|
6057
6136
|
await cp2(checkoutPath, tempPath, { recursive: true, dereference: true });
|
|
6058
|
-
await rm6(
|
|
6137
|
+
await rm6(join22(tempPath, ".git"), { recursive: true, force: true });
|
|
6059
6138
|
try {
|
|
6060
6139
|
await rename3(tempPath, snapshotPath);
|
|
6061
6140
|
} catch (error) {
|
|
@@ -6071,7 +6150,7 @@ async function withFilesystemLock(lockPath, timeoutMs, fn) {
|
|
|
6071
6150
|
while (true) {
|
|
6072
6151
|
try {
|
|
6073
6152
|
await mkdir13(lockPath);
|
|
6074
|
-
await writeFile15(
|
|
6153
|
+
await writeFile15(join22(lockPath, "owner.json"), JSON.stringify({ pid: process.pid, createdAt: (/* @__PURE__ */ new Date()).toISOString() }), "utf8");
|
|
6075
6154
|
break;
|
|
6076
6155
|
} catch (error) {
|
|
6077
6156
|
if (!isAlreadyExists2(error)) throw error;
|
|
@@ -6093,7 +6172,7 @@ function isAlreadyExists2(error) {
|
|
|
6093
6172
|
|
|
6094
6173
|
// src/source/mcp-registry.ts
|
|
6095
6174
|
import { mkdir as mkdir14, writeFile as writeFile16 } from "fs/promises";
|
|
6096
|
-
import { basename as basename12, dirname as dirname17, join as
|
|
6175
|
+
import { basename as basename12, dirname as dirname17, join as join23, resolve as resolve8 } from "path";
|
|
6097
6176
|
var registryBaseUrl = "https://registry.modelcontextprotocol.io/v0.1";
|
|
6098
6177
|
var sourcePrefix2 = "mcp-registry:";
|
|
6099
6178
|
var McpRegistrySourceDriver = class {
|
|
@@ -6159,7 +6238,7 @@ var McpRegistrySourceDriver = class {
|
|
|
6159
6238
|
return this.local.list({ ...resolved, driver: "local" });
|
|
6160
6239
|
}
|
|
6161
6240
|
async scan(resolved) {
|
|
6162
|
-
if (!await pathExists(
|
|
6241
|
+
if (!await pathExists(join23(resolved.resolvedPath, "mcp"))) {
|
|
6163
6242
|
return { ok: false, findings: [{ level: "error", message: "MCP registry source has no generated mcp artifact" }] };
|
|
6164
6243
|
}
|
|
6165
6244
|
return { ok: true, findings: [] };
|
|
@@ -6199,9 +6278,9 @@ function isSafeHttpUrl(value) {
|
|
|
6199
6278
|
}
|
|
6200
6279
|
async function writeGeneratedPackage2(root, server) {
|
|
6201
6280
|
const serverId = installNameFor3(server.serverName);
|
|
6202
|
-
const mcpPath =
|
|
6281
|
+
const mcpPath = join23(root, "mcp", `${serverId}.json`);
|
|
6203
6282
|
await mkdir14(dirname17(mcpPath), { recursive: true });
|
|
6204
|
-
await writeFile16(
|
|
6283
|
+
await writeFile16(join23(root, "openpack.json"), `${JSON.stringify({
|
|
6205
6284
|
schemaVersion: 2,
|
|
6206
6285
|
name: `mcp-registry/${server.serverName}`,
|
|
6207
6286
|
version: server.version ?? "latest",
|
|
@@ -6222,20 +6301,20 @@ function installNameFor3(serverName) {
|
|
|
6222
6301
|
return basename12(serverName).replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "mcp-server";
|
|
6223
6302
|
}
|
|
6224
6303
|
function cachePathFor3(serverName, cacheRoot) {
|
|
6225
|
-
const root = cacheRoot ? resolve8(cacheRoot) :
|
|
6304
|
+
const root = cacheRoot ? resolve8(cacheRoot) : join23(process.env.HOME ?? ".", ".agentwheel", "cache");
|
|
6226
6305
|
const slug2 = `mcp-registry-${serverName}`.replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "");
|
|
6227
|
-
return
|
|
6306
|
+
return join23(root, slug2 || "mcp-registry-server");
|
|
6228
6307
|
}
|
|
6229
6308
|
|
|
6230
6309
|
// src/source/skillkit.ts
|
|
6231
|
-
import { cp as cp3, mkdir as mkdir15, readFile as
|
|
6232
|
-
import { homedir as
|
|
6233
|
-
import { basename as basename14, dirname as dirname19, join as
|
|
6310
|
+
import { cp as cp3, mkdir as mkdir15, readFile as readFile19, rm as rm7 } from "fs/promises";
|
|
6311
|
+
import { homedir as homedir4 } from "os";
|
|
6312
|
+
import { basename as basename14, dirname as dirname19, join as join25, resolve as resolve9 } from "path";
|
|
6234
6313
|
import * as defaultSkillKit from "@skillkit/core";
|
|
6235
6314
|
|
|
6236
6315
|
// src/source/skill-artifacts.ts
|
|
6237
6316
|
import { readdir as readdir2, stat as stat4 } from "fs/promises";
|
|
6238
|
-
import { basename as basename13, dirname as dirname18, extname as extname2, join as
|
|
6317
|
+
import { basename as basename13, dirname as dirname18, extname as extname2, join as join24 } from "path";
|
|
6239
6318
|
async function artifactsFromSkillPaths(paths, packageName) {
|
|
6240
6319
|
const artifacts = [];
|
|
6241
6320
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -6257,14 +6336,14 @@ async function discoverSkillPaths(root) {
|
|
|
6257
6336
|
async function artifactFromSkillPath(item, packageName) {
|
|
6258
6337
|
const stats = await stat4(item.path);
|
|
6259
6338
|
if (stats.isDirectory()) {
|
|
6260
|
-
const skillMd =
|
|
6339
|
+
const skillMd = join24(item.path, "SKILL.md");
|
|
6261
6340
|
if (!await pathExists(skillMd)) return void 0;
|
|
6262
6341
|
const name = sanitizeSkillName(item.name ?? basename13(item.path));
|
|
6263
6342
|
return {
|
|
6264
6343
|
type: "skills",
|
|
6265
6344
|
name,
|
|
6266
6345
|
sourcePath: item.path,
|
|
6267
|
-
relativePath:
|
|
6346
|
+
relativePath: join24("skills", name),
|
|
6268
6347
|
kind: "dir",
|
|
6269
6348
|
hash: await hashPath(item.path),
|
|
6270
6349
|
packageName,
|
|
@@ -6278,7 +6357,7 @@ async function artifactFromSkillPath(item, packageName) {
|
|
|
6278
6357
|
type: "skills",
|
|
6279
6358
|
name,
|
|
6280
6359
|
sourcePath: dir,
|
|
6281
|
-
relativePath:
|
|
6360
|
+
relativePath: join24("skills", name),
|
|
6282
6361
|
kind: "dir",
|
|
6283
6362
|
hash: await hashPath(dir),
|
|
6284
6363
|
packageName,
|
|
@@ -6291,7 +6370,7 @@ async function artifactFromSkillPath(item, packageName) {
|
|
|
6291
6370
|
type: "skills",
|
|
6292
6371
|
name,
|
|
6293
6372
|
sourcePath: item.path,
|
|
6294
|
-
relativePath:
|
|
6373
|
+
relativePath: join24("skills", `${name}.md`),
|
|
6295
6374
|
kind: "file",
|
|
6296
6375
|
hash: await hashPath(item.path),
|
|
6297
6376
|
packageName,
|
|
@@ -6309,7 +6388,7 @@ async function walk(dir, paths) {
|
|
|
6309
6388
|
}
|
|
6310
6389
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
6311
6390
|
if (!entry.isDirectory() || entry.name === ".git" || entry.name === "node_modules") continue;
|
|
6312
|
-
await walk(
|
|
6391
|
+
await walk(join24(dir, entry.name), paths);
|
|
6313
6392
|
}
|
|
6314
6393
|
}
|
|
6315
6394
|
function sanitizeSkillName(name) {
|
|
@@ -6409,9 +6488,9 @@ var SkillKitSourceDriver = class {
|
|
|
6409
6488
|
throw new Error("SkillKit translateSkill API unavailable");
|
|
6410
6489
|
}
|
|
6411
6490
|
for (const skill of this.discover(resolved.resolvedPath)) {
|
|
6412
|
-
const skillMd =
|
|
6491
|
+
const skillMd = join25(skill.path, "SKILL.md");
|
|
6413
6492
|
if (await pathExists(skillMd)) {
|
|
6414
|
-
this.core.translateSkill(await
|
|
6493
|
+
this.core.translateSkill(await readFile19(skillMd, "utf8"), "openclaw", { sourceFilename: "SKILL.md" });
|
|
6415
6494
|
}
|
|
6416
6495
|
}
|
|
6417
6496
|
return resolved;
|
|
@@ -6440,8 +6519,8 @@ function normalizeProviderSource(spec) {
|
|
|
6440
6519
|
return spec;
|
|
6441
6520
|
}
|
|
6442
6521
|
function cachePathFor4(spec, cacheRoot) {
|
|
6443
|
-
const root = cacheRoot ? resolve9(cacheRoot) :
|
|
6444
|
-
return
|
|
6522
|
+
const root = cacheRoot ? resolve9(cacheRoot) : join25(homedir4(), ".agentwheel", "cache");
|
|
6523
|
+
return join25(root, "skillkit", packageSlug(spec));
|
|
6445
6524
|
}
|
|
6446
6525
|
function packageSlug(spec) {
|
|
6447
6526
|
return spec.replace(/^[a-z]+:\/\//i, "").replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "source";
|
|
@@ -6454,7 +6533,7 @@ function mapSeverity(severity) {
|
|
|
6454
6533
|
|
|
6455
6534
|
// src/source/vercel-skills.ts
|
|
6456
6535
|
import { stat as stat5 } from "fs/promises";
|
|
6457
|
-
import { basename as basename15, join as
|
|
6536
|
+
import { basename as basename15, join as join26, relative as relative5, resolve as resolve10 } from "path";
|
|
6458
6537
|
var VercelSkillsSourceDriver = class {
|
|
6459
6538
|
name = "vercel-skills";
|
|
6460
6539
|
git = new GitSourceDriver();
|
|
@@ -6517,7 +6596,7 @@ var VercelSkillsSourceDriver = class {
|
|
|
6517
6596
|
};
|
|
6518
6597
|
async function resolveVercelSkillSubpath(root, subpath) {
|
|
6519
6598
|
if (!subpath) return root;
|
|
6520
|
-
const candidates = [
|
|
6599
|
+
const candidates = [join26(root, subpath), join26(root, "skills", subpath)];
|
|
6521
6600
|
for (const candidate of candidates) {
|
|
6522
6601
|
if (await pathExists(candidate)) return candidate;
|
|
6523
6602
|
}
|
|
@@ -6588,13 +6667,13 @@ function getSourceDriver(name = "local") {
|
|
|
6588
6667
|
|
|
6589
6668
|
// src/staging/staging.ts
|
|
6590
6669
|
import { chmod, cp as cp5, mkdir as mkdir18, mkdtemp as mkdtemp3, readdir as readdir5, stat as stat8 } from "fs/promises";
|
|
6591
|
-
import { basename as basename19, dirname as dirname23, join as
|
|
6670
|
+
import { basename as basename19, dirname as dirname23, join as join30, relative as relative7, resolve as resolve12, sep as sep2 } from "path";
|
|
6592
6671
|
import { tmpdir as tmpdir4 } from "os";
|
|
6593
6672
|
|
|
6594
6673
|
// src/compose/markdown.ts
|
|
6595
6674
|
import { createHash as createHash6 } from "crypto";
|
|
6596
|
-
import { readdir as readdir3, readFile as
|
|
6597
|
-
import { basename as basename16, dirname as dirname20, extname as extname3, join as
|
|
6675
|
+
import { readdir as readdir3, readFile as readFile20, stat as stat6, writeFile as writeFile17 } from "fs/promises";
|
|
6676
|
+
import { basename as basename16, dirname as dirname20, extname as extname3, join as join27, relative as relative6, resolve as resolve11, sep } from "path";
|
|
6598
6677
|
var includePattern = /<!--\s*openpack:include(\?)?\s+([^>]+?)\s*-->/g;
|
|
6599
6678
|
var escapedIncludePattern = /<!--\s*openpack\\:include(\?)?\s+([^>]+?)\s*-->/g;
|
|
6600
6679
|
var generatedPattern = /<!--\s*(?:BEGIN|END)\s+openpack:include\b/;
|
|
@@ -6632,7 +6711,7 @@ async function validateMarkdownIncludes(artifacts, packageRoot, options = {}) {
|
|
|
6632
6711
|
}
|
|
6633
6712
|
}
|
|
6634
6713
|
async function expandFile(file, packageRoot, appendEntries, artifactPaths, options) {
|
|
6635
|
-
const raw = await
|
|
6714
|
+
const raw = await readFile20(file, "utf8");
|
|
6636
6715
|
const owner = ownerSelector(packageRoot, file, options.nodeId);
|
|
6637
6716
|
const expanded = await expandContent(raw, packageRoot, [owner], artifactPaths, options);
|
|
6638
6717
|
let content = expanded.content;
|
|
@@ -6725,7 +6804,7 @@ async function expandInclude(selector, packageRoot, artifactPaths, options) {
|
|
|
6725
6804
|
if (!stats.isFile()) {
|
|
6726
6805
|
throw new Error(`OpenPack include is not a file: ${displaySelector}`);
|
|
6727
6806
|
}
|
|
6728
|
-
const raw = sourceContent ?? await
|
|
6807
|
+
const raw = sourceContent ?? await readFile20(sourcePath, "utf8");
|
|
6729
6808
|
const { optional: _optional, markers: _markers, chain: _chain, ...childOptions } = options;
|
|
6730
6809
|
const expanded = await expandContent(raw, includePackageRoot, [...options.chain, displaySelector], includeArtifactPaths, {
|
|
6731
6810
|
...childOptions,
|
|
@@ -6801,7 +6880,7 @@ async function listMarkdownFiles(root) {
|
|
|
6801
6880
|
const out = [];
|
|
6802
6881
|
async function walk2(dir) {
|
|
6803
6882
|
for (const entry of (await readdir3(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
6804
|
-
const full =
|
|
6883
|
+
const full = join27(dir, entry.name);
|
|
6805
6884
|
if (entry.isDirectory()) {
|
|
6806
6885
|
await walk2(full);
|
|
6807
6886
|
} else if (entry.isFile() && extname3(entry.name).toLowerCase() === ".md") {
|
|
@@ -6861,8 +6940,8 @@ function artifactPathMap(artifacts) {
|
|
|
6861
6940
|
}
|
|
6862
6941
|
|
|
6863
6942
|
// src/staging/customize.ts
|
|
6864
|
-
import { cp as cp4, mkdir as mkdir16, readdir as readdir4, readFile as
|
|
6865
|
-
import { dirname as dirname21, join as
|
|
6943
|
+
import { cp as cp4, mkdir as mkdir16, readdir as readdir4, readFile as readFile21, writeFile as writeFile18 } from "fs/promises";
|
|
6944
|
+
import { dirname as dirname21, join as join28 } from "path";
|
|
6866
6945
|
async function applyCustomizations(artifacts, options) {
|
|
6867
6946
|
let next = [...artifacts];
|
|
6868
6947
|
next = await applyReplacements2(next, options, "override", installableArtifactTypes());
|
|
@@ -6878,14 +6957,14 @@ async function applyFragmentCustomizations(artifacts, options) {
|
|
|
6878
6957
|
return next.sort((a, b) => `${a.type}:${a.name}:${a.channel}`.localeCompare(`${b.type}:${b.name}:${b.channel}`));
|
|
6879
6958
|
}
|
|
6880
6959
|
async function applyInstructionOverlay(artifacts, options) {
|
|
6881
|
-
const overlayPath =
|
|
6960
|
+
const overlayPath = join28(options.workspaceRoot, ".agentwheel", "overlays", options.adapter.name, "instructions.local.md");
|
|
6882
6961
|
if (!await pathExists(overlayPath)) return artifacts;
|
|
6883
6962
|
const index = artifacts.findIndex((artifact2) => artifact2.type === "instructions");
|
|
6884
6963
|
if (index < 0) return artifacts;
|
|
6885
6964
|
const artifact = artifacts[index];
|
|
6886
|
-
const managed = await
|
|
6887
|
-
const local = await
|
|
6888
|
-
const composedPath =
|
|
6965
|
+
const managed = await readFile21(artifact.stagedPath ?? artifact.sourcePath, "utf8");
|
|
6966
|
+
const local = await readFile21(overlayPath, "utf8");
|
|
6967
|
+
const composedPath = join28(options.stageRoot, ".agentwheel-composed", "instructions", "AGENTS.md");
|
|
6889
6968
|
await mkdir16(dirname21(composedPath), { recursive: true });
|
|
6890
6969
|
await writeFile18(
|
|
6891
6970
|
composedPath,
|
|
@@ -6913,19 +6992,19 @@ async function applyInstructionOverlay(artifacts, options) {
|
|
|
6913
6992
|
return [...artifacts.slice(0, index), updated, ...artifacts.slice(index + 1)];
|
|
6914
6993
|
}
|
|
6915
6994
|
async function applyAdditions(artifacts, options) {
|
|
6916
|
-
const additionsRoot =
|
|
6917
|
-
const rulesRoot =
|
|
6995
|
+
const additionsRoot = join28(options.workspaceRoot, ".agentwheel", "additions");
|
|
6996
|
+
const rulesRoot = join28(additionsRoot, "rules");
|
|
6918
6997
|
if (!await pathExists(rulesRoot)) return artifacts;
|
|
6919
6998
|
const additions = [];
|
|
6920
6999
|
for (const entry of await sortedDirEntries2(rulesRoot)) {
|
|
6921
|
-
const full =
|
|
7000
|
+
const full = join28(rulesRoot, entry.name);
|
|
6922
7001
|
if (!entry.isFile()) continue;
|
|
6923
7002
|
additions.push({
|
|
6924
7003
|
type: "rules",
|
|
6925
7004
|
name: entry.name,
|
|
6926
7005
|
sourcePath: full,
|
|
6927
7006
|
stagedPath: full,
|
|
6928
|
-
relativePath:
|
|
7007
|
+
relativePath: join28("additions", "rules", entry.name),
|
|
6929
7008
|
kind: "file",
|
|
6930
7009
|
hash: await hashPath(full),
|
|
6931
7010
|
packageName: options.packageName,
|
|
@@ -6949,16 +7028,16 @@ async function applyReplacements2(artifacts, options, channel, artifactTypes) {
|
|
|
6949
7028
|
);
|
|
6950
7029
|
}
|
|
6951
7030
|
for (const type of artifactTypes) {
|
|
6952
|
-
const typeRoot =
|
|
7031
|
+
const typeRoot = join28(root, type);
|
|
6953
7032
|
if (!await pathExists(typeRoot)) continue;
|
|
6954
7033
|
for (const entry of await sortedDirEntries2(typeRoot)) {
|
|
6955
7034
|
const artifactMapKey = `${type}:${entry.name}`;
|
|
6956
7035
|
if (seen.has(artifactMapKey)) continue;
|
|
6957
7036
|
seen.add(artifactMapKey);
|
|
6958
|
-
const full =
|
|
7037
|
+
const full = join28(typeRoot, entry.name);
|
|
6959
7038
|
const artifactKind = entry.isDirectory() ? "dir" : "file";
|
|
6960
7039
|
const existing = byKey.get(artifactMapKey);
|
|
6961
|
-
const stagedPath =
|
|
7040
|
+
const stagedPath = join28(options.stageRoot, ".agentwheel-composed", channel, type, entry.name);
|
|
6962
7041
|
await mkdir16(dirname21(stagedPath), { recursive: true });
|
|
6963
7042
|
await cp4(full, stagedPath, { recursive: artifactKind === "dir", dereference: true });
|
|
6964
7043
|
byKey.set(artifactMapKey, {
|
|
@@ -6967,7 +7046,7 @@ async function applyReplacements2(artifacts, options, channel, artifactTypes) {
|
|
|
6967
7046
|
name: entry.name,
|
|
6968
7047
|
sourcePath: full,
|
|
6969
7048
|
stagedPath,
|
|
6970
|
-
relativePath: existing?.relativePath ??
|
|
7049
|
+
relativePath: existing?.relativePath ?? join28(type, entry.name),
|
|
6971
7050
|
kind: artifactKind,
|
|
6972
7051
|
hash: await hashPath(stagedPath),
|
|
6973
7052
|
packageName,
|
|
@@ -6982,13 +7061,13 @@ function replacementRoots(options, channel) {
|
|
|
6982
7061
|
const stateDir = channel === "override" ? "overrides" : "ejected";
|
|
6983
7062
|
const roots = [];
|
|
6984
7063
|
if (options.graphNodeId) {
|
|
6985
|
-
roots.push({ root:
|
|
7064
|
+
roots.push({ root: join28(options.workspaceRoot, ".agentwheel", stateDir, ...options.graphNodeId.split("/")), kind: "node" });
|
|
6986
7065
|
}
|
|
6987
7066
|
if (options.packageName && options.packageVersion) {
|
|
6988
|
-
roots.push({ root:
|
|
7067
|
+
roots.push({ root: join28(options.workspaceRoot, ".agentwheel", stateDir, ...`${options.packageName}@${options.packageVersion}`.split("/")), kind: "version" });
|
|
6989
7068
|
}
|
|
6990
7069
|
if (options.packageName) {
|
|
6991
|
-
roots.push({ root:
|
|
7070
|
+
roots.push({ root: join28(options.workspaceRoot, ".agentwheel", stateDir, ...options.packageName.split("/")), kind: "package" });
|
|
6992
7071
|
}
|
|
6993
7072
|
return roots;
|
|
6994
7073
|
}
|
|
@@ -7003,8 +7082,8 @@ async function sortedDirEntries2(path) {
|
|
|
7003
7082
|
}
|
|
7004
7083
|
|
|
7005
7084
|
// src/staging/claude-subagents.ts
|
|
7006
|
-
import { mkdir as mkdir17, readFile as
|
|
7007
|
-
import { basename as basename18, dirname as dirname22, join as
|
|
7085
|
+
import { mkdir as mkdir17, readFile as readFile22, writeFile as writeFile19 } from "fs/promises";
|
|
7086
|
+
import { basename as basename18, dirname as dirname22, join as join29 } from "path";
|
|
7008
7087
|
async function renderClaudeSubagents(artifacts, stageRoot, adapter) {
|
|
7009
7088
|
if (adapter?.name !== "claude") return artifacts;
|
|
7010
7089
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -7026,15 +7105,15 @@ async function renderClaudeSubagents(artifacts, stageRoot, adapter) {
|
|
|
7026
7105
|
async function renderClaudeSubagent(artifact, stageRoot) {
|
|
7027
7106
|
const sourcePath = artifact.stagedPath ?? artifact.sourcePath;
|
|
7028
7107
|
const agentName = claudeAgentName(artifact);
|
|
7029
|
-
const markdownPath = artifact.kind === "dir" ?
|
|
7108
|
+
const markdownPath = artifact.kind === "dir" ? join29(sourcePath, "AGENTS.md") : sourcePath;
|
|
7030
7109
|
if (artifact.kind === "dir" && !await pathExists(markdownPath)) {
|
|
7031
7110
|
throw new Error(`Claude subagent directory ${artifact.relativePath} must contain AGENTS.md.`);
|
|
7032
7111
|
}
|
|
7033
7112
|
if (artifact.kind === "file" && !artifact.name.toLowerCase().endsWith(".md") && !sourcePath.toLowerCase().endsWith(".md")) {
|
|
7034
7113
|
throw new Error(`Claude subagent ${artifact.relativePath} must be a .md file or directory containing AGENTS.md.`);
|
|
7035
7114
|
}
|
|
7036
|
-
const content = await
|
|
7037
|
-
const renderedPath =
|
|
7115
|
+
const content = await readFile22(markdownPath, "utf8");
|
|
7116
|
+
const renderedPath = join29(stageRoot, ".agentwheel-rendered", "claude-subagents", `${agentName}.md`);
|
|
7038
7117
|
await mkdir17(dirname22(renderedPath), { recursive: true });
|
|
7039
7118
|
await writeFile19(renderedPath, content.endsWith("\n") ? content : `${content}
|
|
7040
7119
|
`, "utf8");
|
|
@@ -7043,7 +7122,7 @@ async function renderClaudeSubagent(artifact, stageRoot) {
|
|
|
7043
7122
|
name: `${agentName}.md`,
|
|
7044
7123
|
sourcePath: renderedPath,
|
|
7045
7124
|
stagedPath: renderedPath,
|
|
7046
|
-
relativePath:
|
|
7125
|
+
relativePath: join29("subagents", `${agentName}.md`),
|
|
7047
7126
|
kind: "file",
|
|
7048
7127
|
hash: await hashPath(renderedPath)
|
|
7049
7128
|
};
|
|
@@ -7066,10 +7145,10 @@ async function stageResolvedSourceRaw(driver, resolved) {
|
|
|
7066
7145
|
return stageResolvedArtifactsRaw(resolved, artifacts);
|
|
7067
7146
|
}
|
|
7068
7147
|
async function stageResolvedArtifactsRaw(resolved, artifacts) {
|
|
7069
|
-
const root = await mkdtemp3(
|
|
7148
|
+
const root = await mkdtemp3(join30(tmpdir4(), "agentwheel-stage-"));
|
|
7070
7149
|
const stagedArtifacts = [];
|
|
7071
7150
|
for (const artifact of artifacts) {
|
|
7072
|
-
const stagedPath =
|
|
7151
|
+
const stagedPath = join30(root, artifact.relativePath);
|
|
7073
7152
|
await mkdir18(dirname23(stagedPath), { recursive: true });
|
|
7074
7153
|
await cp5(artifact.sourcePath, stagedPath, {
|
|
7075
7154
|
recursive: artifact.kind === "dir",
|
|
@@ -7157,7 +7236,7 @@ async function composeAssets(artifact, packageRoot, stagedPath) {
|
|
|
7157
7236
|
}
|
|
7158
7237
|
for (const asset of artifact.assets) {
|
|
7159
7238
|
const source = resolvePackagePath(packageRoot, asset.from);
|
|
7160
|
-
const dest =
|
|
7239
|
+
const dest = join30(stagedPath, asset.into);
|
|
7161
7240
|
await copyAsset(asset, source, dest);
|
|
7162
7241
|
}
|
|
7163
7242
|
}
|
|
@@ -7166,7 +7245,7 @@ async function copyAsset(asset, source, dest) {
|
|
|
7166
7245
|
if (sourceStats.isFile()) {
|
|
7167
7246
|
if (matchesAny(basename19(source), asset.include)) {
|
|
7168
7247
|
await mkdir18(dest, { recursive: true });
|
|
7169
|
-
await copyAssetFile(source,
|
|
7248
|
+
await copyAssetFile(source, join30(dest, basename19(source)), asset);
|
|
7170
7249
|
}
|
|
7171
7250
|
return;
|
|
7172
7251
|
}
|
|
@@ -7182,7 +7261,7 @@ async function copyAsset(asset, source, dest) {
|
|
|
7182
7261
|
for (const file of await listFiles(source)) {
|
|
7183
7262
|
const rel = relative7(source, file).replaceAll("\\", "/");
|
|
7184
7263
|
if (!matchesAny(rel, asset.include) && !matchesAny(basename19(file), asset.include)) continue;
|
|
7185
|
-
await copyAssetFile(file,
|
|
7264
|
+
await copyAssetFile(file, join30(dest, rel), asset);
|
|
7186
7265
|
}
|
|
7187
7266
|
}
|
|
7188
7267
|
async function copyAssetFile(source, dest, asset) {
|
|
@@ -7202,7 +7281,7 @@ async function listFiles(root) {
|
|
|
7202
7281
|
const out = [];
|
|
7203
7282
|
async function walk2(dir) {
|
|
7204
7283
|
for (const entry of (await readdir5(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
7205
|
-
const full =
|
|
7284
|
+
const full = join30(dir, entry.name);
|
|
7206
7285
|
if (entry.isDirectory()) {
|
|
7207
7286
|
await walk2(full);
|
|
7208
7287
|
} else if (entry.isFile()) {
|
|
@@ -7221,7 +7300,7 @@ async function normalizeCopiedModes(path) {
|
|
|
7221
7300
|
}
|
|
7222
7301
|
if (!stats.isDirectory()) return;
|
|
7223
7302
|
for (const entry of await readdir5(path, { withFileTypes: true })) {
|
|
7224
|
-
await normalizeCopiedModes(
|
|
7303
|
+
await normalizeCopiedModes(join30(path, entry.name));
|
|
7225
7304
|
}
|
|
7226
7305
|
}
|
|
7227
7306
|
function matchesAny(path, patterns) {
|
|
@@ -7234,9 +7313,9 @@ function matchesGlob(path, pattern) {
|
|
|
7234
7313
|
}
|
|
7235
7314
|
|
|
7236
7315
|
// src/model/workspace.ts
|
|
7237
|
-
import { readFile as
|
|
7238
|
-
import { homedir as
|
|
7239
|
-
import { dirname as dirname24, join as
|
|
7316
|
+
import { readFile as readFile23 } from "fs/promises";
|
|
7317
|
+
import { homedir as homedir5 } from "os";
|
|
7318
|
+
import { dirname as dirname24, join as join31, resolve as resolve13 } from "path";
|
|
7240
7319
|
import { z as z6 } from "zod";
|
|
7241
7320
|
|
|
7242
7321
|
// src/resolve/semver.ts
|
|
@@ -7507,12 +7586,12 @@ var workspaceConfigSchema = z6.discriminatedUnion("schemaVersion", [
|
|
|
7507
7586
|
workspaceConfigV2Schema
|
|
7508
7587
|
]);
|
|
7509
7588
|
function workspaceConfigPath(workspaceRoot) {
|
|
7510
|
-
return
|
|
7589
|
+
return join31(workspaceRoot, ".agentwheel", "config.json");
|
|
7511
7590
|
}
|
|
7512
7591
|
async function readWorkspaceConfig(workspaceRoot) {
|
|
7513
7592
|
const path = workspaceConfigPath(workspaceRoot);
|
|
7514
7593
|
if (!await pathExists(path)) return emptyWorkspaceConfig();
|
|
7515
|
-
return workspaceConfigSchema.parse(JSON.parse(await
|
|
7594
|
+
return workspaceConfigSchema.parse(JSON.parse(await readFile23(path, "utf8")));
|
|
7516
7595
|
}
|
|
7517
7596
|
async function writeWorkspaceConfig(workspaceRoot, config) {
|
|
7518
7597
|
await writeJsonAtomic(workspaceConfigPath(workspaceRoot), workspaceConfigSchema.parse(config));
|
|
@@ -7524,8 +7603,8 @@ function upsertPackage(config, entry) {
|
|
|
7524
7603
|
packages.sort((a, b) => a.name.localeCompare(b.name));
|
|
7525
7604
|
return workspaceConfigSchema.parse({ ...parsed, packages });
|
|
7526
7605
|
}
|
|
7527
|
-
function globalWorkspaceConfigPath(globalRoot =
|
|
7528
|
-
return
|
|
7606
|
+
function globalWorkspaceConfigPath(globalRoot = homedir5()) {
|
|
7607
|
+
return join31(globalRoot, ".agentwheel", "config.json");
|
|
7529
7608
|
}
|
|
7530
7609
|
async function findWorkspaceRoot(start = process.cwd()) {
|
|
7531
7610
|
let current = resolve13(start);
|
|
@@ -7561,8 +7640,8 @@ function mergeWorkspaceConfig(global, project) {
|
|
|
7561
7640
|
});
|
|
7562
7641
|
}
|
|
7563
7642
|
function resolveConfigPath(path, baseRoot) {
|
|
7564
|
-
if (path.startsWith("~/")) return resolve13(
|
|
7565
|
-
if (path === "~") return
|
|
7643
|
+
if (path.startsWith("~/")) return resolve13(homedir5(), path.slice(2));
|
|
7644
|
+
if (path === "~") return homedir5();
|
|
7566
7645
|
return path.startsWith("/") ? resolve13(path) : resolve13(baseRoot, path);
|
|
7567
7646
|
}
|
|
7568
7647
|
function emptyWorkspaceConfig() {
|
|
@@ -7573,7 +7652,7 @@ function isCompositeWorkspaceProfile(profile) {
|
|
|
7573
7652
|
}
|
|
7574
7653
|
async function readConfigPath(path) {
|
|
7575
7654
|
if (!await pathExists(path)) return emptyWorkspaceConfig();
|
|
7576
|
-
return workspaceConfigSchema.parse(JSON.parse(await
|
|
7655
|
+
return workspaceConfigSchema.parse(JSON.parse(await readFile23(path, "utf8")));
|
|
7577
7656
|
}
|
|
7578
7657
|
function mergeWorkspaceTrust(global, project) {
|
|
7579
7658
|
return {
|
|
@@ -7589,17 +7668,17 @@ function sortedUnique2(values) {
|
|
|
7589
7668
|
|
|
7590
7669
|
// src/lifecycle/customization.ts
|
|
7591
7670
|
import { appendFile, cp as cp6, mkdir as mkdir19, rm as rm9 } from "fs/promises";
|
|
7592
|
-
import { dirname as dirname26, join as
|
|
7671
|
+
import { dirname as dirname26, join as join34 } from "path";
|
|
7593
7672
|
|
|
7594
7673
|
// src/resolve/graph.ts
|
|
7595
7674
|
import { createHash as createHash8 } from "crypto";
|
|
7596
|
-
import { mkdtemp as mkdtemp4, readdir as readdir6, readFile as
|
|
7675
|
+
import { mkdtemp as mkdtemp4, readdir as readdir6, readFile as readFile26, stat as stat10 } from "fs/promises";
|
|
7597
7676
|
import { tmpdir as tmpdir5 } from "os";
|
|
7598
|
-
import { basename as basename20, extname as extname4, join as
|
|
7677
|
+
import { basename as basename20, extname as extname4, join as join33 } from "path";
|
|
7599
7678
|
|
|
7600
7679
|
// src/model/workspace-composition.ts
|
|
7601
7680
|
import { createHash as createHash7 } from "crypto";
|
|
7602
|
-
import { readFile as
|
|
7681
|
+
import { readFile as readFile24 } from "fs/promises";
|
|
7603
7682
|
import { z as z7 } from "zod";
|
|
7604
7683
|
var selectionSourceConfigSchema = z7.object({
|
|
7605
7684
|
schemaVersion: z7.literal(2),
|
|
@@ -7618,12 +7697,12 @@ async function resolveSelectionImport(sourceRoot, sourceDriver, selection) {
|
|
|
7618
7697
|
}
|
|
7619
7698
|
let raw;
|
|
7620
7699
|
try {
|
|
7621
|
-
raw = JSON.parse(await
|
|
7700
|
+
raw = JSON.parse(await readFile24(path, "utf8"));
|
|
7622
7701
|
} catch (error) {
|
|
7623
7702
|
const message = error instanceof Error ? error.message : String(error);
|
|
7624
7703
|
throw new Error(`Selection import '${parsedSelection.export}' cannot parse ${path}: ${message}`);
|
|
7625
7704
|
}
|
|
7626
|
-
if (!
|
|
7705
|
+
if (!isRecord9(raw) || raw.schemaVersion !== 2) {
|
|
7627
7706
|
throw new Error(`Selection import '${parsedSelection.export}' requires schemaVersion 2 in ${path}.`);
|
|
7628
7707
|
}
|
|
7629
7708
|
let sourceConfig;
|
|
@@ -7711,18 +7790,18 @@ function stableValue2(value) {
|
|
|
7711
7790
|
}
|
|
7712
7791
|
return out;
|
|
7713
7792
|
}
|
|
7714
|
-
function
|
|
7793
|
+
function isRecord9(value) {
|
|
7715
7794
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
7716
7795
|
}
|
|
7717
7796
|
|
|
7718
7797
|
// src/resolve/identity.ts
|
|
7719
|
-
import { homedir as
|
|
7798
|
+
import { homedir as homedir7 } from "os";
|
|
7720
7799
|
import { resolve as resolve15 } from "path";
|
|
7721
7800
|
|
|
7722
7801
|
// src/registry/client.ts
|
|
7723
|
-
import { readFile as
|
|
7724
|
-
import { homedir as
|
|
7725
|
-
import { dirname as dirname25, join as
|
|
7802
|
+
import { readFile as readFile25, rm as rm8, stat as stat9 } from "fs/promises";
|
|
7803
|
+
import { homedir as homedir6 } from "os";
|
|
7804
|
+
import { dirname as dirname25, join as join32, resolve as resolve14 } from "path";
|
|
7726
7805
|
import { fileURLToPath } from "url";
|
|
7727
7806
|
|
|
7728
7807
|
// src/model/registry.ts
|
|
@@ -7819,7 +7898,7 @@ var RegistryClient = class {
|
|
|
7819
7898
|
}
|
|
7820
7899
|
async readCache() {
|
|
7821
7900
|
if (!await pathExists(this.cachePath)) return void 0;
|
|
7822
|
-
return registryCacheSchema.parse(JSON.parse(await
|
|
7901
|
+
return registryCacheSchema.parse(JSON.parse(await readFile25(this.cachePath, "utf8")));
|
|
7823
7902
|
}
|
|
7824
7903
|
isExpired(cache, ttlMs) {
|
|
7825
7904
|
return this.now().getTime() - new Date(cache.fetchedAt).getTime() > ttlMs;
|
|
@@ -7838,10 +7917,10 @@ var RegistryClient = class {
|
|
|
7838
7917
|
if (await pathExists(filePath)) {
|
|
7839
7918
|
const fullPath = resolve14(filePath);
|
|
7840
7919
|
const stats = await stat9(fullPath);
|
|
7841
|
-
return
|
|
7920
|
+
return readFile25(stats.isDirectory() ? join32(fullPath, "index.json") : fullPath, "utf8");
|
|
7842
7921
|
}
|
|
7843
|
-
const resolved = await this.git.fetch(await this.git.resolve(source, { cacheRoot:
|
|
7844
|
-
return
|
|
7922
|
+
const resolved = await this.git.fetch(await this.git.resolve(source, { cacheRoot: join32(dirname25(this.cachePath), "registry-repos") }));
|
|
7923
|
+
return readFile25(join32(resolved.resolvedPath, "index.json"), "utf8");
|
|
7845
7924
|
}
|
|
7846
7925
|
warnCompatibility(entries) {
|
|
7847
7926
|
for (const entry of entries) {
|
|
@@ -7879,7 +7958,7 @@ function mergeIndexes(indexes) {
|
|
|
7879
7958
|
return [...merged.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
7880
7959
|
}
|
|
7881
7960
|
function defaultRegistryCachePath() {
|
|
7882
|
-
return
|
|
7961
|
+
return join32(homedir6(), ".agentwheel", "registry-cache.json");
|
|
7883
7962
|
}
|
|
7884
7963
|
function sameSources(a, b) {
|
|
7885
7964
|
return a.length === b.length && a.every((source, index) => source === b[index]);
|
|
@@ -7964,8 +8043,8 @@ function localSourcePath(source) {
|
|
|
7964
8043
|
return source.startsWith("local:") ? source.slice("local:".length) : source;
|
|
7965
8044
|
}
|
|
7966
8045
|
function resolveLocalPath(path, declaringPackageRoot) {
|
|
7967
|
-
if (path === "~") return
|
|
7968
|
-
if (path.startsWith("~/")) return resolve15(
|
|
8046
|
+
if (path === "~") return homedir7();
|
|
8047
|
+
if (path.startsWith("~/")) return resolve15(homedir7(), path.slice(2));
|
|
7969
8048
|
if (path.startsWith("/")) return resolve15(path);
|
|
7970
8049
|
return resolve15(declaringPackageRoot, path);
|
|
7971
8050
|
}
|
|
@@ -8043,7 +8122,7 @@ function normalizeLiteralProviderSpec(source, prefix) {
|
|
|
8043
8122
|
var cacheLocks = /* @__PURE__ */ new Map();
|
|
8044
8123
|
async function resolveDependencyGraph(roots, options) {
|
|
8045
8124
|
if (roots.length === 0) throw new Error("At least one graph root is required.");
|
|
8046
|
-
const graphRoot = await mkdtemp4(
|
|
8125
|
+
const graphRoot = await mkdtemp4(join33(tmpdir5(), "agentwheel-graph-"));
|
|
8047
8126
|
const fetchCache = /* @__PURE__ */ new Map();
|
|
8048
8127
|
const nodesByKey = /* @__PURE__ */ new Map();
|
|
8049
8128
|
const rootResults = [];
|
|
@@ -8563,7 +8642,7 @@ async function collectIncludeNeeds(artifact, artifactsByRelativePath) {
|
|
|
8563
8642
|
const file = stack.shift();
|
|
8564
8643
|
if (scanned.has(file)) continue;
|
|
8565
8644
|
scanned.add(file);
|
|
8566
|
-
const content = await
|
|
8645
|
+
const content = await readFile26(file, "utf8");
|
|
8567
8646
|
for (const include of extractOpenPackIncludeSelectors(content)) {
|
|
8568
8647
|
await collectIncludeSelector(include.raw, include.optional, artifactsByRelativePath, scanned, stack, needs);
|
|
8569
8648
|
}
|
|
@@ -8606,7 +8685,7 @@ async function listMarkdownFiles2(root) {
|
|
|
8606
8685
|
const out = [];
|
|
8607
8686
|
async function walk2(dir) {
|
|
8608
8687
|
for (const entry of (await readdir6(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
8609
|
-
const full =
|
|
8688
|
+
const full = join33(dir, entry.name);
|
|
8610
8689
|
if (entry.isDirectory()) {
|
|
8611
8690
|
await walk2(full);
|
|
8612
8691
|
} else if (entry.isFile() && extname4(entry.name).toLowerCase() === ".md") {
|
|
@@ -8641,7 +8720,7 @@ async function fetchPackage(normalized, mode, options, fetchCache, refOverride)
|
|
|
8641
8720
|
const promise = (async () => {
|
|
8642
8721
|
const driver = getSourceDriver(normalized.driver);
|
|
8643
8722
|
const resolved = await driver.resolve(normalized.source, {
|
|
8644
|
-
cacheRoot: options.cacheRoot ??
|
|
8723
|
+
cacheRoot: options.cacheRoot ?? join33(options.workspaceRoot, ".agentwheel", "cache"),
|
|
8645
8724
|
mode,
|
|
8646
8725
|
ref: refOverride ?? normalized.requestedRef,
|
|
8647
8726
|
frozenLock: hardLockedCheckout
|
|
@@ -8848,7 +8927,7 @@ async function mapLimit(items, limit, fn) {
|
|
|
8848
8927
|
|
|
8849
8928
|
// src/lifecycle/customization.ts
|
|
8850
8929
|
async function remember(workspaceRoot, runtime, text) {
|
|
8851
|
-
const overlayPath =
|
|
8930
|
+
const overlayPath = join34(workspaceRoot, ".agentwheel", "overlays", runtime, "instructions.local.md");
|
|
8852
8931
|
await mkdir19(dirname26(overlayPath), { recursive: true });
|
|
8853
8932
|
await appendFile(overlayPath, `${text.trim()}
|
|
8854
8933
|
`, "utf8");
|
|
@@ -8872,7 +8951,7 @@ async function ejectArtifact(workspaceRoot, item) {
|
|
|
8872
8951
|
throw new Error(`Artifact not found: ${item}`);
|
|
8873
8952
|
}
|
|
8874
8953
|
const ejectedIdentity = parsed.packageIdentity === parsed.packageName ? parsed.packageIdentity : candidate.nodeId === parsed.packageIdentity ? candidate.nodeId : `${candidate.packageName}@${candidate.packageVersion}`;
|
|
8875
|
-
const ejectedPath =
|
|
8954
|
+
const ejectedPath = join34(workspaceRoot, ".agentwheel", "ejected", ...ejectedIdentity.split("/"), parsed.type, parsed.name);
|
|
8876
8955
|
await mkdir19(dirname26(ejectedPath), { recursive: true });
|
|
8877
8956
|
await rm9(ejectedPath, { recursive: true, force: true });
|
|
8878
8957
|
await cp6(artifact.stagedPath ?? artifact.sourcePath, ejectedPath, { recursive: artifact.kind === "dir", dereference: true });
|
|
@@ -8915,7 +8994,7 @@ async function stageEjectCandidate(workspaceRoot, pkg) {
|
|
|
8915
8994
|
const adapter = pkg.adapterConfig ? await loadAdapterConfig(pkg.adapterConfig) : getAdapter(pkg.adapter);
|
|
8916
8995
|
const bundle = await stageSource(driver, normalized.source, {
|
|
8917
8996
|
adapter,
|
|
8918
|
-
cacheRoot:
|
|
8997
|
+
cacheRoot: join34(workspaceRoot, ".agentwheel", "cache"),
|
|
8919
8998
|
mode: pkg.mode,
|
|
8920
8999
|
ref: normalized.requestedRef ?? pkg.requestedRef
|
|
8921
9000
|
});
|
|
@@ -8967,7 +9046,7 @@ import { rm as rm10 } from "fs/promises";
|
|
|
8967
9046
|
// src/lifecycle/source-plan.ts
|
|
8968
9047
|
import { createHash as createHash10 } from "crypto";
|
|
8969
9048
|
import { mkdir as mkdir21 } from "fs/promises";
|
|
8970
|
-
import { dirname as dirname28, join as
|
|
9049
|
+
import { dirname as dirname28, join as join37 } from "path";
|
|
8971
9050
|
|
|
8972
9051
|
// src/resolve/graph-diff.ts
|
|
8973
9052
|
function diffGraphLocks(previous, next) {
|
|
@@ -9129,11 +9208,11 @@ function formatSelectionImport(root) {
|
|
|
9129
9208
|
|
|
9130
9209
|
// src/resolve/render.ts
|
|
9131
9210
|
import { createHash as createHash9 } from "crypto";
|
|
9132
|
-
import { readFile as
|
|
9211
|
+
import { readFile as readFile27, mkdtemp as mkdtemp5 } from "fs/promises";
|
|
9133
9212
|
import { tmpdir as tmpdir6 } from "os";
|
|
9134
|
-
import { join as
|
|
9213
|
+
import { join as join35 } from "path";
|
|
9135
9214
|
async function renderGraphForTarget(graph, targetContext = {}) {
|
|
9136
|
-
const root = await mkdtemp5(
|
|
9215
|
+
const root = await mkdtemp5(join35(tmpdir6(), "agentwheel-render-"));
|
|
9137
9216
|
const artifacts = [];
|
|
9138
9217
|
const stagedNodes = /* @__PURE__ */ new Map();
|
|
9139
9218
|
const includeEdges = /* @__PURE__ */ new Map();
|
|
@@ -9255,7 +9334,7 @@ async function artifactContentMap(artifacts) {
|
|
|
9255
9334
|
const out = /* @__PURE__ */ new Map();
|
|
9256
9335
|
for (const artifact of artifacts) {
|
|
9257
9336
|
if (artifact.kind !== "file") continue;
|
|
9258
|
-
out.set(artifact.relativePath.replaceAll("\\", "/"), await
|
|
9337
|
+
out.set(artifact.relativePath.replaceAll("\\", "/"), await readFile27(artifact.stagedPath ?? artifact.sourcePath, "utf8"));
|
|
9259
9338
|
}
|
|
9260
9339
|
return out;
|
|
9261
9340
|
}
|
|
@@ -9518,9 +9597,9 @@ function lockArtifactFor(artifact) {
|
|
|
9518
9597
|
}
|
|
9519
9598
|
|
|
9520
9599
|
// src/lifecycle/trust.ts
|
|
9521
|
-
import { mkdir as mkdir20, readFile as
|
|
9522
|
-
import { homedir as
|
|
9523
|
-
import { dirname as dirname27, join as
|
|
9600
|
+
import { mkdir as mkdir20, readFile as readFile28 } from "fs/promises";
|
|
9601
|
+
import { homedir as homedir8 } from "os";
|
|
9602
|
+
import { dirname as dirname27, join as join36 } from "path";
|
|
9524
9603
|
import { z as z9 } from "zod";
|
|
9525
9604
|
var trustStoreSchema = z9.object({
|
|
9526
9605
|
version: z9.literal(1),
|
|
@@ -9594,14 +9673,14 @@ function sortedUnique5(values) {
|
|
|
9594
9673
|
}
|
|
9595
9674
|
async function readTrustStore(path) {
|
|
9596
9675
|
if (!await pathExists(path)) return { version: 1, acceptedSources: [] };
|
|
9597
|
-
return trustStoreSchema.parse(JSON.parse(await
|
|
9676
|
+
return trustStoreSchema.parse(JSON.parse(await readFile28(path, "utf8")));
|
|
9598
9677
|
}
|
|
9599
9678
|
async function writeTrustStore(path, store) {
|
|
9600
9679
|
await mkdir20(dirname27(path), { recursive: true });
|
|
9601
9680
|
await writeJsonAtomic(path, trustStoreSchema.parse(store));
|
|
9602
9681
|
}
|
|
9603
9682
|
function defaultTrustStorePath() {
|
|
9604
|
-
return process.env.AGENTWHEEL_TRUST_STORE ??
|
|
9683
|
+
return process.env.AGENTWHEEL_TRUST_STORE ?? join36(homedir8(), ".agentwheel", "trust.json");
|
|
9605
9684
|
}
|
|
9606
9685
|
|
|
9607
9686
|
// src/lifecycle/ownership.ts
|
|
@@ -9773,7 +9852,7 @@ async function createGraphSourcePlan(options) {
|
|
|
9773
9852
|
const registryClient = new RegistryClient({ workspaceRoot, offline: lockMode, offlineLabel: lockLabel, warn });
|
|
9774
9853
|
const graph = await resolveDependencyGraph(options.roots, {
|
|
9775
9854
|
workspaceRoot,
|
|
9776
|
-
cacheRoot:
|
|
9855
|
+
cacheRoot: join37(workspaceRoot, ".agentwheel", "cache"),
|
|
9777
9856
|
registryClient,
|
|
9778
9857
|
noDeps: options.noDeps,
|
|
9779
9858
|
includeSuggestions: options.includeSuggestions,
|
|
@@ -9879,7 +9958,7 @@ async function readExistingGraphLock(path) {
|
|
|
9879
9958
|
return readGraphLock(path);
|
|
9880
9959
|
}
|
|
9881
9960
|
function pathForGraphLock(workspaceRoot, targetKey2, adapter, targetFingerprint) {
|
|
9882
|
-
return
|
|
9961
|
+
return join37(workspaceRoot, ".agentwheel", "locks", sanitizePathSegment(targetKey2), sanitizePathSegment(adapter), `${targetFingerprint}.graph-lock.json`);
|
|
9883
9962
|
}
|
|
9884
9963
|
function sanitizePathSegment(value) {
|
|
9885
9964
|
return value.replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "default";
|
|
@@ -10011,7 +10090,7 @@ function targetLabel(target) {
|
|
|
10011
10090
|
}
|
|
10012
10091
|
|
|
10013
10092
|
// src/runtime/target.ts
|
|
10014
|
-
import { basename as basename21, dirname as dirname29, join as
|
|
10093
|
+
import { basename as basename21, dirname as dirname29, join as join38, resolve as resolve17 } from "path";
|
|
10015
10094
|
var runtimeMarkers = [
|
|
10016
10095
|
{ adapter: "openclaw", dirs: [".openclaw", ".clawdbot", ".moltbot"] },
|
|
10017
10096
|
{ adapter: "claude", dirs: [".claude"] },
|
|
@@ -10133,7 +10212,7 @@ async function detectRuntimeTargets(cwd = process.cwd(), adapterFilter) {
|
|
|
10133
10212
|
for (const dir of marker.dirs) {
|
|
10134
10213
|
if (basename21(root) === dir) {
|
|
10135
10214
|
matches.push({ adapter: marker.adapter, targetRoot: dirname29(root) });
|
|
10136
|
-
} else if (await pathExists(
|
|
10215
|
+
} else if (await pathExists(join38(root, dir))) {
|
|
10137
10216
|
matches.push({ adapter: marker.adapter, targetRoot: root });
|
|
10138
10217
|
}
|
|
10139
10218
|
}
|
|
@@ -10477,9 +10556,9 @@ function shellQuoteArg(value) {
|
|
|
10477
10556
|
}
|
|
10478
10557
|
|
|
10479
10558
|
// src/cli/update-check.ts
|
|
10480
|
-
import { mkdir as mkdir22, readFile as
|
|
10481
|
-
import { homedir as
|
|
10482
|
-
import { dirname as dirname30, join as
|
|
10559
|
+
import { mkdir as mkdir22, readFile as readFile29, writeFile as writeFile20 } from "fs/promises";
|
|
10560
|
+
import { homedir as homedir9 } from "os";
|
|
10561
|
+
import { dirname as dirname30, join as join39 } from "path";
|
|
10483
10562
|
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
10484
10563
|
var DEFAULT_TIMEOUT_MS = 300;
|
|
10485
10564
|
var REGISTRY_URL = "https://registry.npmjs.org/agentwheel";
|
|
@@ -10487,7 +10566,7 @@ async function maybeCheckForUpdate(options) {
|
|
|
10487
10566
|
if (isDisabled(options)) return;
|
|
10488
10567
|
const now = options.now?.() ?? /* @__PURE__ */ new Date();
|
|
10489
10568
|
const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
10490
|
-
const cachePath = options.cachePath ??
|
|
10569
|
+
const cachePath = options.cachePath ?? join39(homedir9(), ".agentwheel", "update-check.json");
|
|
10491
10570
|
try {
|
|
10492
10571
|
const cached = await readCache(cachePath);
|
|
10493
10572
|
if (cached && now.getTime() - Date.parse(cached.checkedAt) < ttlMs) {
|
|
@@ -10524,7 +10603,7 @@ async function fetchLatestVersion(fetchImpl, timeoutMs) {
|
|
|
10524
10603
|
}
|
|
10525
10604
|
async function readCache(path) {
|
|
10526
10605
|
try {
|
|
10527
|
-
const parsed = JSON.parse(await
|
|
10606
|
+
const parsed = JSON.parse(await readFile29(path, "utf8"));
|
|
10528
10607
|
if (typeof parsed.checkedAt !== "string" || typeof parsed.latest !== "string") return void 0;
|
|
10529
10608
|
return { checkedAt: parsed.checkedAt, latest: parsed.latest };
|
|
10530
10609
|
} catch {
|
|
@@ -10696,13 +10775,13 @@ function isCrossPackageSelector(value) {
|
|
|
10696
10775
|
}
|
|
10697
10776
|
|
|
10698
10777
|
// src/model/package-migrate.ts
|
|
10699
|
-
import { readFile as
|
|
10700
|
-
import { join as
|
|
10778
|
+
import { readFile as readFile30, rename as rename4, writeFile as writeFile21 } from "fs/promises";
|
|
10779
|
+
import { join as join41, resolve as resolve19 } from "path";
|
|
10701
10780
|
import { applyEdits, modify, parse as parse5 } from "jsonc-parser";
|
|
10702
10781
|
async function migratePackageManifest(root) {
|
|
10703
10782
|
const packageRoot = resolve19(root);
|
|
10704
10783
|
for (const name of openPackManifestNames) {
|
|
10705
|
-
const path =
|
|
10784
|
+
const path = join41(packageRoot, name);
|
|
10706
10785
|
if (await pathExists(path)) {
|
|
10707
10786
|
return { changed: false, to: path, message: `Package already uses ${name}.` };
|
|
10708
10787
|
}
|
|
@@ -10711,10 +10790,10 @@ async function migratePackageManifest(root) {
|
|
|
10711
10790
|
if (!legacyName) {
|
|
10712
10791
|
throw new Error(`No legacy package manifest found at ${packageRoot}`);
|
|
10713
10792
|
}
|
|
10714
|
-
const from =
|
|
10793
|
+
const from = join41(packageRoot, legacyName);
|
|
10715
10794
|
const toName = legacyName.endsWith(".jsonc") ? "openpack.jsonc" : "openpack.json";
|
|
10716
|
-
const to =
|
|
10717
|
-
const content = await
|
|
10795
|
+
const to = join41(packageRoot, toName);
|
|
10796
|
+
const content = await readFile30(from, "utf8");
|
|
10718
10797
|
const updated = updateSchemaVersion(content);
|
|
10719
10798
|
await rename4(from, to);
|
|
10720
10799
|
await writeFile21(to, updated, "utf8");
|
|
@@ -10722,7 +10801,7 @@ async function migratePackageManifest(root) {
|
|
|
10722
10801
|
}
|
|
10723
10802
|
async function firstExistingLegacyManifest(root) {
|
|
10724
10803
|
for (const name of legacyPackageManifestNames) {
|
|
10725
|
-
if (await pathExists(
|
|
10804
|
+
if (await pathExists(join41(root, name))) return name;
|
|
10726
10805
|
}
|
|
10727
10806
|
return void 0;
|
|
10728
10807
|
}
|
|
@@ -10740,14 +10819,14 @@ function updateSchemaVersion(content) {
|
|
|
10740
10819
|
|
|
10741
10820
|
// src/cli/version.ts
|
|
10742
10821
|
import { readFileSync } from "fs";
|
|
10743
|
-
import { dirname as dirname31, join as
|
|
10822
|
+
import { dirname as dirname31, join as join42 } from "path";
|
|
10744
10823
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
10745
10824
|
var FALLBACK_VERSION = "0.0.0";
|
|
10746
10825
|
function resolveCliVersion() {
|
|
10747
10826
|
let dir = dirname31(fileURLToPath2(import.meta.url));
|
|
10748
10827
|
while (true) {
|
|
10749
10828
|
try {
|
|
10750
|
-
const pkg = JSON.parse(readFileSync(
|
|
10829
|
+
const pkg = JSON.parse(readFileSync(join42(dir, "package.json"), "utf8"));
|
|
10751
10830
|
if (pkg.name === "agentwheel" && typeof pkg.version === "string") {
|
|
10752
10831
|
return pkg.version;
|
|
10753
10832
|
}
|
|
@@ -10761,8 +10840,8 @@ function resolveCliVersion() {
|
|
|
10761
10840
|
|
|
10762
10841
|
// src/version/policy.ts
|
|
10763
10842
|
import { execFile as execFile5 } from "child_process";
|
|
10764
|
-
import { readFile as
|
|
10765
|
-
import { join as
|
|
10843
|
+
import { readFile as readFile31 } from "fs/promises";
|
|
10844
|
+
import { join as join43, resolve as resolve20 } from "path";
|
|
10766
10845
|
import { promisify as promisify5 } from "util";
|
|
10767
10846
|
import { parse as parseJsonc } from "jsonc-parser";
|
|
10768
10847
|
import { z as z10 } from "zod";
|
|
@@ -10871,7 +10950,7 @@ async function discoverVersionsFromSource(pkg, workspaceRoot) {
|
|
|
10871
10950
|
}
|
|
10872
10951
|
const driver = getSourceDriver(driverName);
|
|
10873
10952
|
const resolved = await driver.resolve(pkg.source, {
|
|
10874
|
-
cacheRoot:
|
|
10953
|
+
cacheRoot: join43(workspaceRoot, ".agentwheel", "cache"),
|
|
10875
10954
|
mode: "tracking",
|
|
10876
10955
|
ref: pkg.requestedRef
|
|
10877
10956
|
});
|
|
@@ -10965,12 +11044,12 @@ function gitUrlFromSource(source) {
|
|
|
10965
11044
|
throw new Error(`Version discovery does not support Git source: ${source}`);
|
|
10966
11045
|
}
|
|
10967
11046
|
function versionCachePath(workspaceRoot) {
|
|
10968
|
-
return
|
|
11047
|
+
return join43(workspaceRoot, ".agentwheel", "cache", "version-index.json");
|
|
10969
11048
|
}
|
|
10970
11049
|
async function readVersionCache(path) {
|
|
10971
11050
|
if (!await pathExists(path)) return { schemaVersion: 1, sources: {} };
|
|
10972
11051
|
try {
|
|
10973
|
-
return versionCacheSchema.parse(JSON.parse(await
|
|
11052
|
+
return versionCacheSchema.parse(JSON.parse(await readFile31(path, "utf8")));
|
|
10974
11053
|
} catch {
|
|
10975
11054
|
return { schemaVersion: 1, sources: {} };
|
|
10976
11055
|
}
|
|
@@ -10978,8 +11057,8 @@ async function readVersionCache(path) {
|
|
|
10978
11057
|
|
|
10979
11058
|
// src/profile/members.ts
|
|
10980
11059
|
import { execFile as execFile6 } from "child_process";
|
|
10981
|
-
import { readFile as
|
|
10982
|
-
import { join as
|
|
11060
|
+
import { readFile as readFile32 } from "fs/promises";
|
|
11061
|
+
import { join as join44, resolve as resolve21 } from "path";
|
|
10983
11062
|
import { promisify as promisify6 } from "util";
|
|
10984
11063
|
import { z as z12 } from "zod";
|
|
10985
11064
|
|
|
@@ -11165,11 +11244,11 @@ async function invokeMemberStatus(member, parentWorkspace, chain, options, cliEn
|
|
|
11165
11244
|
} else {
|
|
11166
11245
|
const sshArgs = sshArguments(member);
|
|
11167
11246
|
const remoteArgs = [
|
|
11168
|
-
`cd ${
|
|
11247
|
+
`cd ${shellQuote2(member.workspace)}`,
|
|
11169
11248
|
"&&",
|
|
11170
|
-
`AGENTWHEEL_COMPOSITE_CHAIN=${
|
|
11249
|
+
`AGENTWHEEL_COMPOSITE_CHAIN=${shellQuote2(JSON.stringify(chain))}`,
|
|
11171
11250
|
"agentwheel",
|
|
11172
|
-
...args.map(
|
|
11251
|
+
...args.map(shellQuote2)
|
|
11173
11252
|
];
|
|
11174
11253
|
const result = await execFileAsync6("ssh", [...sshArgs, remoteArgs.join(" ")], {
|
|
11175
11254
|
env,
|
|
@@ -11208,12 +11287,12 @@ async function runMemberAgentwheel(member, parentWorkspace, args, chain) {
|
|
|
11208
11287
|
return { stdout: result2.stdout, stderr: result2.stderr };
|
|
11209
11288
|
}
|
|
11210
11289
|
const remoteArgs = [
|
|
11211
|
-
`cd ${
|
|
11290
|
+
`cd ${shellQuote2(member.workspace)}`,
|
|
11212
11291
|
"&&",
|
|
11213
|
-
`AGENTWHEEL_COMPOSITE_CHAIN=${
|
|
11292
|
+
`AGENTWHEEL_COMPOSITE_CHAIN=${shellQuote2(JSON.stringify(chain))}`,
|
|
11214
11293
|
"agentwheel",
|
|
11215
11294
|
"--no-update-check",
|
|
11216
|
-
...args.map(
|
|
11295
|
+
...args.map(shellQuote2)
|
|
11217
11296
|
];
|
|
11218
11297
|
const result = await execFileAsync6("ssh", [...sshArguments(member), remoteArgs.join(" ")], {
|
|
11219
11298
|
env,
|
|
@@ -11237,7 +11316,7 @@ function sshArguments(member) {
|
|
|
11237
11316
|
destination
|
|
11238
11317
|
];
|
|
11239
11318
|
}
|
|
11240
|
-
function
|
|
11319
|
+
function shellQuote2(value) {
|
|
11241
11320
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
11242
11321
|
}
|
|
11243
11322
|
function commandErrorDetail(error) {
|
|
@@ -11275,12 +11354,12 @@ function memberFailure(member, health, error) {
|
|
|
11275
11354
|
};
|
|
11276
11355
|
}
|
|
11277
11356
|
function memberCachePath(workspaceRoot, profileName, memberId) {
|
|
11278
|
-
return
|
|
11357
|
+
return join44(workspaceRoot, ".agentwheel", "cache", "member-status", profileName, `${memberId}.json`);
|
|
11279
11358
|
}
|
|
11280
11359
|
async function readMemberCache(path) {
|
|
11281
11360
|
if (!await pathExists(path)) return void 0;
|
|
11282
11361
|
try {
|
|
11283
|
-
return memberCacheSchema.parse(JSON.parse(await
|
|
11362
|
+
return memberCacheSchema.parse(JSON.parse(await readFile32(path, "utf8")));
|
|
11284
11363
|
} catch {
|
|
11285
11364
|
return void 0;
|
|
11286
11365
|
}
|
|
@@ -11349,9 +11428,9 @@ function valueAfter(lines, prefix) {
|
|
|
11349
11428
|
|
|
11350
11429
|
// src/catalogue/client.ts
|
|
11351
11430
|
import { createHash as createHash11 } from "crypto";
|
|
11352
|
-
import { readFile as
|
|
11353
|
-
import { homedir as
|
|
11354
|
-
import { join as
|
|
11431
|
+
import { readFile as readFile33, rm as rm11 } from "fs/promises";
|
|
11432
|
+
import { homedir as homedir10 } from "os";
|
|
11433
|
+
import { join as join45 } from "path";
|
|
11355
11434
|
|
|
11356
11435
|
// src/model/catalogue.ts
|
|
11357
11436
|
import { z as z13 } from "zod";
|
|
@@ -11546,7 +11625,7 @@ var CatalogueClient = class {
|
|
|
11546
11625
|
async readCache() {
|
|
11547
11626
|
if (!await pathExists(this.cachePath)) return void 0;
|
|
11548
11627
|
try {
|
|
11549
|
-
const value = JSON.parse(await
|
|
11628
|
+
const value = JSON.parse(await readFile33(this.cachePath, "utf8"));
|
|
11550
11629
|
const envelope = catalogueCacheEnvelopeSchema.parse(value);
|
|
11551
11630
|
if (envelope.contentHash) {
|
|
11552
11631
|
const contentHash = catalogueContentHash(envelope.enriched, envelope.vercel);
|
|
@@ -11602,7 +11681,7 @@ var CatalogueClient = class {
|
|
|
11602
11681
|
}
|
|
11603
11682
|
};
|
|
11604
11683
|
function defaultCatalogueCachePath() {
|
|
11605
|
-
return
|
|
11684
|
+
return join45(homedir10(), ".agentwheel", "catalogue-cache.json");
|
|
11606
11685
|
}
|
|
11607
11686
|
function sameSources2(a, b) {
|
|
11608
11687
|
return a.length === b.length && a.every((source, index) => source === b[index]);
|
|
@@ -11687,7 +11766,7 @@ function normalizeRegistryEntry(entry) {
|
|
|
11687
11766
|
tags: sortedUniqueStrings(entry.tags),
|
|
11688
11767
|
provides: [],
|
|
11689
11768
|
source: entry.source,
|
|
11690
|
-
installCommand: `npx agentwheel install ${
|
|
11769
|
+
installCommand: `npx agentwheel install ${shellQuote3(entry.name)}`,
|
|
11691
11770
|
installability: "registry",
|
|
11692
11771
|
provenances: ["registry"],
|
|
11693
11772
|
archived: false,
|
|
@@ -11735,7 +11814,7 @@ function normalizeVercelEntry(entry) {
|
|
|
11735
11814
|
provides: ["skills"],
|
|
11736
11815
|
source,
|
|
11737
11816
|
repoUrl: `https://github.com/${entry.o}/${entry.r}`,
|
|
11738
|
-
installCommand: `npx agentwheel install ${
|
|
11817
|
+
installCommand: `npx agentwheel install ${shellQuote3(source)}`,
|
|
11739
11818
|
installability: "source",
|
|
11740
11819
|
provenances: ["vercel"],
|
|
11741
11820
|
archived: false,
|
|
@@ -11932,11 +12011,11 @@ function enrichedInstallCommand(entry, source) {
|
|
|
11932
12011
|
const catalogueCommand = nonEmpty(entry.installCommand);
|
|
11933
12012
|
if (!source) return catalogueCommand;
|
|
11934
12013
|
if (entry.ecosystem === "mcp-registry" || entry.ecosystem === "clawhub") {
|
|
11935
|
-
return catalogueCommand ?? `npx agentwheel install ${
|
|
12014
|
+
return catalogueCommand ?? `npx agentwheel install ${shellQuote3(source)}`;
|
|
11936
12015
|
}
|
|
11937
|
-
return `npx agentwheel install ${
|
|
12016
|
+
return `npx agentwheel install ${shellQuote3(source)}`;
|
|
11938
12017
|
}
|
|
11939
|
-
function
|
|
12018
|
+
function shellQuote3(value) {
|
|
11940
12019
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
11941
12020
|
}
|
|
11942
12021
|
function matchesPhrase(fields, query) {
|
|
@@ -12012,7 +12091,7 @@ program.command("list").description("list artifacts exposed by a package source"
|
|
|
12012
12091
|
const resolvedInput = await resolvePackageSource(source, targetRoot);
|
|
12013
12092
|
const selectedArtifacts = selectedArtifactsFromOptionsOrRegistry(options, resolvedInput.registryEntry);
|
|
12014
12093
|
const driver = getSourceDriver(options.driver ?? inferSourceDriverName(resolvedInput.source));
|
|
12015
|
-
const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot:
|
|
12094
|
+
const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot: join46(targetRoot, ".agentwheel", "cache") }))));
|
|
12016
12095
|
const artifacts = filterArtifactsBySelection(await driver.list(resolved), selectedArtifacts);
|
|
12017
12096
|
for (const artifact of artifacts) {
|
|
12018
12097
|
console.log(`${artifact.type} ${artifact.name} ${artifact.relativePath}`);
|
|
@@ -12064,7 +12143,7 @@ program.command("scan").description("scan a package source for validation findin
|
|
|
12064
12143
|
const targetRoot = normalizeTargetRoot(options.targetRoot);
|
|
12065
12144
|
const resolvedInput = await resolvePackageSource(source, targetRoot);
|
|
12066
12145
|
const driver = getSourceDriver(options.driver ?? inferSourceDriverName(resolvedInput.source));
|
|
12067
|
-
const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot:
|
|
12146
|
+
const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot: join46(targetRoot, ".agentwheel", "cache") }))));
|
|
12068
12147
|
const result = await driver.scan(resolved);
|
|
12069
12148
|
if (result.findings.length === 0) {
|
|
12070
12149
|
console.log("Scan ok: no findings");
|
|
@@ -12332,7 +12411,7 @@ journalCommand.command("list").description("show pending apply journals for reso
|
|
|
12332
12411
|
if (!journal) continue;
|
|
12333
12412
|
pending += 1;
|
|
12334
12413
|
console.log(`PENDING ${state.adapter.name}/${state.installationType} at ${state.installRoot}`);
|
|
12335
|
-
console.log(` journal: ${
|
|
12414
|
+
console.log(` journal: ${join46(state.installRoot, ".agentwheel", `${state.state.stateKey}.apply-journal.json`)}`);
|
|
12336
12415
|
console.log(` stateKey: ${state.state.stateKey}`);
|
|
12337
12416
|
console.log(` createdAt: ${journal.createdAt}`);
|
|
12338
12417
|
console.log(` updatedAt: ${journal.updatedAt}`);
|
|
@@ -12635,7 +12714,7 @@ async function packageEntryFromSource(source, targetRoot, options) {
|
|
|
12635
12714
|
const bundle = await stageSource(driver, resolvedSource, {
|
|
12636
12715
|
workspaceRoot: targetRoot,
|
|
12637
12716
|
adapter,
|
|
12638
|
-
cacheRoot:
|
|
12717
|
+
cacheRoot: join46(targetRoot, ".agentwheel", "cache"),
|
|
12639
12718
|
mode: options.mode,
|
|
12640
12719
|
ref: initialVersion?.ref,
|
|
12641
12720
|
frozenLock: lockMode,
|
|
@@ -13269,7 +13348,7 @@ function keepManifestEntryOperation(entry, targetRoot, scopeDescription, operati
|
|
|
13269
13348
|
artifactType: entry.artifactType,
|
|
13270
13349
|
artifactName: entry.artifactName,
|
|
13271
13350
|
kind: entry.kind,
|
|
13272
|
-
destPath: operation?.destPath ??
|
|
13351
|
+
destPath: operation?.destPath ?? join46(targetRoot, entry.path),
|
|
13273
13352
|
relativeDestPath: entry.path,
|
|
13274
13353
|
desiredHash: entry.sourceHash,
|
|
13275
13354
|
currentHash: operation?.currentHash ?? entry.hash,
|
|
@@ -13854,12 +13933,12 @@ async function printDoctor(target, options) {
|
|
|
13854
13933
|
const requestedSkills = doctorSkillRequests(target, options);
|
|
13855
13934
|
const skills = [];
|
|
13856
13935
|
for (const request of requestedSkills) {
|
|
13857
|
-
const skillPath =
|
|
13936
|
+
const skillPath = join46(state.installRoot, targetMapping.dest, request.name);
|
|
13858
13937
|
const exists = await pathExists(skillPath);
|
|
13859
13938
|
const manifestEntry = manifest?.entries.find((entry) => {
|
|
13860
13939
|
if (entry.artifactType !== "skills") return false;
|
|
13861
13940
|
const legacyInstallName = "installName" in entry && typeof entry.installName === "string" ? entry.installName : void 0;
|
|
13862
|
-
return entry.artifactName === request.name || legacyInstallName === request.name || entry.path ===
|
|
13941
|
+
return entry.artifactName === request.name || legacyInstallName === request.name || entry.path === join46(targetMapping.dest, request.name);
|
|
13863
13942
|
});
|
|
13864
13943
|
const status = manifestEntry ? "managed" : exists ? "present-unmanaged" : "missing";
|
|
13865
13944
|
skills.push({
|
|
@@ -13939,7 +14018,7 @@ function doctorSkillLabel(name) {
|
|
|
13939
14018
|
return `${name} skill`;
|
|
13940
14019
|
}
|
|
13941
14020
|
function isSyncwheelWorkspace(targetRoot) {
|
|
13942
|
-
return existsSync(
|
|
14021
|
+
return existsSync(join46(targetRoot, ".syncwheel", "manifest.json"));
|
|
13943
14022
|
}
|
|
13944
14023
|
function skillInstallCommand(adapter, installationType, options, skill, behavior = {}) {
|
|
13945
14024
|
const args = [
|
|
@@ -14007,7 +14086,7 @@ function normalizeRuntimeScopeOptions(options, behavior = {}) {
|
|
|
14007
14086
|
}
|
|
14008
14087
|
const canDefaultTargetRoot = !options.agent && !options.all && !options.allDetected && !options.profile;
|
|
14009
14088
|
if (!targetRoot && canDefaultTargetRoot && (options.user || installationType === "user" || behavior.defaultUser)) {
|
|
14010
|
-
targetRoot =
|
|
14089
|
+
targetRoot = homedir11();
|
|
14011
14090
|
}
|
|
14012
14091
|
if (!installationType && behavior.defaultUser) {
|
|
14013
14092
|
installationType = "user";
|
|
@@ -14027,12 +14106,12 @@ function looksLikeSourceSpecifier(value) {
|
|
|
14027
14106
|
return value.includes(":") || value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value === "~" || value.startsWith("~/");
|
|
14028
14107
|
}
|
|
14029
14108
|
function normalizeCliPath(value) {
|
|
14030
|
-
if (value === "~") return
|
|
14031
|
-
if (value.startsWith("~/")) return resolve22(
|
|
14109
|
+
if (value === "~") return homedir11();
|
|
14110
|
+
if (value.startsWith("~/")) return resolve22(homedir11(), value.slice(2));
|
|
14032
14111
|
return resolve22(value);
|
|
14033
14112
|
}
|
|
14034
14113
|
function isHomePath(path) {
|
|
14035
|
-
return resolve22(path) === resolve22(
|
|
14114
|
+
return resolve22(path) === resolve22(homedir11());
|
|
14036
14115
|
}
|
|
14037
14116
|
function adapterListFromOption(adapter) {
|
|
14038
14117
|
if (!adapter) return [];
|
|
@@ -14087,10 +14166,10 @@ function filterUninstallPlanBySelection(plan, selected) {
|
|
|
14087
14166
|
};
|
|
14088
14167
|
}
|
|
14089
14168
|
async function initPackage(root) {
|
|
14090
|
-
await mkdir23(
|
|
14091
|
-
await mkdir23(
|
|
14092
|
-
await mkdir23(
|
|
14093
|
-
const manifestPath =
|
|
14169
|
+
await mkdir23(join46(root, "instructions"), { recursive: true });
|
|
14170
|
+
await mkdir23(join46(root, "rules"), { recursive: true });
|
|
14171
|
+
await mkdir23(join46(root, "skills"), { recursive: true });
|
|
14172
|
+
const manifestPath = join46(root, "openpack.json");
|
|
14094
14173
|
const manifest = {
|
|
14095
14174
|
schemaVersion: 2,
|
|
14096
14175
|
name: "example/agentwheel-package",
|
|
@@ -14103,7 +14182,7 @@ async function initPackage(root) {
|
|
|
14103
14182
|
};
|
|
14104
14183
|
await writeFile22(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
14105
14184
|
`, "utf8");
|
|
14106
|
-
await writeFile22(
|
|
14185
|
+
await writeFile22(join46(root, "instructions", "AGENTS.md"), "# Agent Instructions\n", "utf8");
|
|
14107
14186
|
}
|
|
14108
14187
|
async function defaultBootstrapPackage(_root) {
|
|
14109
14188
|
const packageRoot = await findAgentwheelPackageRoot(dirname32(fileURLToPath3(import.meta.url)));
|
package/openpack.json
CHANGED
package/package.json
CHANGED