@agentlayer.tech/wallet 0.1.74 → 0.1.75
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/.openclaw/extensions/agent-wallet/openclaw.plugin.json +1 -1
- package/.openclaw/extensions/agent-wallet/package.json +1 -1
- package/CHANGELOG.md +26 -0
- package/VERSION +1 -1
- package/agent-wallet/agent_wallet/__init__.py +1 -1
- package/agent-wallet/openclaw.plugin.json +1 -1
- package/agent-wallet/pyproject.toml +1 -1
- package/bin/openclaw-agent-wallet.mjs +485 -30
- package/claude-code/plugins/agent-wallet/.claude-plugin/plugin.json +1 -1
- package/codex/plugins/agent-wallet/.codex-plugin/plugin.json +1 -1
- package/hermes/plugins/agent_wallet/plugin.yaml +1 -1
- package/package.json +1 -1
- package/wdk-btc-wallet/package.json +1 -1
- package/wdk-evm-wallet/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "agent-wallet",
|
|
3
3
|
"name": "Agent Wallet",
|
|
4
4
|
"description": "Official OpenClaw plugin bridge for the agent-wallet backends, including Solana, local BTC, and local EVM.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.75",
|
|
6
6
|
"contracts": {
|
|
7
7
|
"tools": [
|
|
8
8
|
"agentlayer_autonomous_approve",
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## v0.1.75 - 2026-07-11
|
|
6
|
+
|
|
7
|
+
- Added a persistent, non-secret ownership registry for OpenClaw, Hermes,
|
|
8
|
+
Codex, and Claude Code integrations. Explicit installs are now distinguishable
|
|
9
|
+
from unrelated external plugins across runtime upgrades.
|
|
10
|
+
|
|
11
|
+
- Fixed `wallet update` so managed framework integrations advance with the
|
|
12
|
+
verified `current` runtime. OpenClaw config and Hermes paths are repaired,
|
|
13
|
+
while Codex and Claude Code registrations and versioned caches are refreshed
|
|
14
|
+
through their host CLIs.
|
|
15
|
+
|
|
16
|
+
- Added guarded adoption for legacy AgentLayer installs. Existing integrations
|
|
17
|
+
are adopted only when their registration and plugin manifests both identify
|
|
18
|
+
AgentLayer; unowned symlinks and external plugins remain untouched.
|
|
19
|
+
|
|
20
|
+
- Added per-framework synchronization details to `wallet status` and
|
|
21
|
+
`wallet doctor`, including failed host registration and restart requirements.
|
|
22
|
+
npm-exec installs also refresh an already-installed stale global CLI without
|
|
23
|
+
making global installation mandatory.
|
|
24
|
+
|
|
25
|
+
- Expanded installer regression coverage for managed upgrades, unmanaged
|
|
26
|
+
integration preservation, global CLI refresh, host registration, and
|
|
27
|
+
hermetic framework/npm homes.
|
|
28
|
+
|
|
29
|
+
## v0.1.74 - 2026-07-10
|
|
30
|
+
|
|
5
31
|
- Added a guarded npm beta-promotion workflow that acceptance-tests the exact
|
|
6
32
|
registry artifact, verifies its integrity, rejects downgrades, serializes with
|
|
7
33
|
publish jobs, and restores the previous `latest` tag if verification fails.
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.75
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "agent-wallet",
|
|
3
3
|
"name": "Agent Wallet",
|
|
4
4
|
"description": "Plugin-friendly wallet backend for OpenClaw agents with safe wallet tools and runtime instructions across Solana, local BTC, and local EVM.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.75",
|
|
6
6
|
"skills": ["skills/wallet-operator"],
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
|
@@ -392,6 +392,60 @@ function updateJournalPath(env = process.env) {
|
|
|
392
392
|
return path.join(resolveRuntimeBase(env), "update-journal.json");
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
+
function integrationRegistryPath(env = process.env) {
|
|
396
|
+
return path.join(resolveRuntimeBase(env), "integrations.json");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function readIntegrationRegistry(env = process.env) {
|
|
400
|
+
const payload = readJsonFile(integrationRegistryPath(env));
|
|
401
|
+
if (!payload || payload.schema_version !== 1 || typeof payload.integrations !== "object") {
|
|
402
|
+
return { schema_version: 1, integrations: {} };
|
|
403
|
+
}
|
|
404
|
+
return payload;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function recordManagedIntegration(name, details = {}, env = process.env) {
|
|
408
|
+
const registry = readIntegrationRegistry(env);
|
|
409
|
+
registry.integrations[name] = {
|
|
410
|
+
...details,
|
|
411
|
+
managed: true,
|
|
412
|
+
installed_version: packageVersion,
|
|
413
|
+
updated_at: new Date().toISOString(),
|
|
414
|
+
};
|
|
415
|
+
registry.updated_at = new Date().toISOString();
|
|
416
|
+
writeJsonFileAtomic(integrationRegistryPath(env), registry);
|
|
417
|
+
return registry.integrations[name];
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function managedIntegration(name, env = process.env) {
|
|
421
|
+
const entry = readIntegrationRegistry(env).integrations[name];
|
|
422
|
+
return entry && entry.managed === true ? entry : null;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function integrationSyncStatus(env = process.env) {
|
|
426
|
+
const active = activeVersion(env);
|
|
427
|
+
const registry = readIntegrationRegistry(env);
|
|
428
|
+
const integrations = Object.entries(registry.integrations)
|
|
429
|
+
.filter(([, entry]) => entry?.managed === true)
|
|
430
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
431
|
+
.map(([name, entry]) => {
|
|
432
|
+
const versionInSync = active === null || entry.installed_version === active;
|
|
433
|
+
const registrationOk = entry.registration_ok !== false;
|
|
434
|
+
return {
|
|
435
|
+
name,
|
|
436
|
+
installed_version: entry.installed_version || null,
|
|
437
|
+
active_version: active,
|
|
438
|
+
in_sync: versionInSync && registrationOk,
|
|
439
|
+
registration_ok: registrationOk,
|
|
440
|
+
restart_required: Boolean(entry.restart_required),
|
|
441
|
+
};
|
|
442
|
+
});
|
|
443
|
+
return {
|
|
444
|
+
in_sync: integrations.every((entry) => entry.in_sync),
|
|
445
|
+
integrations,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
|
|
395
449
|
function writeUpdateJournal(state, details = {}, env = process.env) {
|
|
396
450
|
writeJsonFile(updateJournalPath(env), {
|
|
397
451
|
schema_version: 1,
|
|
@@ -944,6 +998,22 @@ function writeJsonFile(pathname, value) {
|
|
|
944
998
|
fs.writeFileSync(pathname, `${JSON.stringify(value, null, 2)}\n`);
|
|
945
999
|
}
|
|
946
1000
|
|
|
1001
|
+
function writeJsonFileAtomic(pathname, value, mode = 0o600) {
|
|
1002
|
+
fs.mkdirSync(path.dirname(pathname), { recursive: true });
|
|
1003
|
+
const tempPath = `${pathname}.tmp-${process.pid}-${Date.now()}`;
|
|
1004
|
+
try {
|
|
1005
|
+
fs.writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}\n`, { mode });
|
|
1006
|
+
fs.renameSync(tempPath, pathname);
|
|
1007
|
+
fs.chmodSync(pathname, mode);
|
|
1008
|
+
} finally {
|
|
1009
|
+
try {
|
|
1010
|
+
fs.rmSync(tempPath, { force: true });
|
|
1011
|
+
} catch {
|
|
1012
|
+
// ignored
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
|
|
947
1017
|
function currentBootKey(env = process.env) {
|
|
948
1018
|
const currentRoot = resolvedCurrentRuntimeRoot(env);
|
|
949
1019
|
if (!currentRoot) return "";
|
|
@@ -1301,6 +1371,16 @@ function runDoctor(args = []) {
|
|
|
1301
1371
|
fix: rsync.in_sync === false ? "npm run release:local" : "",
|
|
1302
1372
|
});
|
|
1303
1373
|
|
|
1374
|
+
const integrationSync = integrationSyncStatus(env);
|
|
1375
|
+
checks.push({
|
|
1376
|
+
name: "framework_integrations_in_sync",
|
|
1377
|
+
ok: true,
|
|
1378
|
+
in_sync: integrationSync.in_sync,
|
|
1379
|
+
integrations: integrationSync.integrations,
|
|
1380
|
+
error: "",
|
|
1381
|
+
fix: integrationSync.in_sync ? "" : "wallet update --yes",
|
|
1382
|
+
});
|
|
1383
|
+
|
|
1304
1384
|
const ok = checks.every((c) => c.ok);
|
|
1305
1385
|
console.log(
|
|
1306
1386
|
JSON.stringify(
|
|
@@ -1336,6 +1416,7 @@ function runStatus(args = []) {
|
|
|
1336
1416
|
failed_releases: listFailedReleases(),
|
|
1337
1417
|
update_available: computeUpdateAvailability(),
|
|
1338
1418
|
runtime_in_sync: computeRuntimeInSync(),
|
|
1419
|
+
framework_integrations: integrationSyncStatus(),
|
|
1339
1420
|
};
|
|
1340
1421
|
if (hasFlag(args, "--verbose")) {
|
|
1341
1422
|
payload.verbose = true;
|
|
@@ -1562,7 +1643,20 @@ function runInstall(args, { commandName = "install" } = {}) {
|
|
|
1562
1643
|
switchSymlink(currentPath, releaseRoot);
|
|
1563
1644
|
writeUpdateJournal("committed", { release_root: releaseRoot, previous_runtime: previousTarget }, env);
|
|
1564
1645
|
|
|
1646
|
+
recordManagedIntegration(
|
|
1647
|
+
"openclaw",
|
|
1648
|
+
{
|
|
1649
|
+
config_path: path.resolve(
|
|
1650
|
+
expandHome(parseFlagValue(args, "--config-path") || path.join(resolveOpenclawHome(env), "openclaw.json")),
|
|
1651
|
+
),
|
|
1652
|
+
extension_path: path.join(currentPath, ".openclaw", "extensions", "agent-wallet"),
|
|
1653
|
+
package_root: path.join(currentPath, "agent-wallet"),
|
|
1654
|
+
},
|
|
1655
|
+
env,
|
|
1656
|
+
);
|
|
1657
|
+
|
|
1565
1658
|
const integrationRefresh = repairInstalledEditorIntegrations(env);
|
|
1659
|
+
const globalCliRefresh = refreshGlobalCliIfNeeded(env);
|
|
1566
1660
|
|
|
1567
1661
|
const pythonInfo = activePythonRuntimeInfo(env);
|
|
1568
1662
|
const nodeInfo = activeNodeRuntimeInfo(env)
|
|
@@ -1586,6 +1680,7 @@ function runInstall(args, { commandName = "install" } = {}) {
|
|
|
1586
1680
|
staged: Boolean(stagingRoot),
|
|
1587
1681
|
release_state: "verified",
|
|
1588
1682
|
integration_refresh: integrationRefresh,
|
|
1683
|
+
global_cli_refresh: globalCliRefresh,
|
|
1589
1684
|
},
|
|
1590
1685
|
null,
|
|
1591
1686
|
2,
|
|
@@ -2001,6 +2096,14 @@ function runHermesInstall(args) {
|
|
|
2001
2096
|
}
|
|
2002
2097
|
}
|
|
2003
2098
|
|
|
2099
|
+
recordManagedIntegration("hermes", {
|
|
2100
|
+
hermes_home: hermesHome,
|
|
2101
|
+
plugin_target: pluginTarget,
|
|
2102
|
+
env_path: hermesEnvPath,
|
|
2103
|
+
restart_required: true,
|
|
2104
|
+
...(enable.skipped ? {} : { registration_ok: enable.ok }),
|
|
2105
|
+
});
|
|
2106
|
+
|
|
2004
2107
|
console.log(
|
|
2005
2108
|
JSON.stringify(
|
|
2006
2109
|
{
|
|
@@ -2086,6 +2189,15 @@ function runCodexInstall(args) {
|
|
|
2086
2189
|
}
|
|
2087
2190
|
}
|
|
2088
2191
|
|
|
2192
|
+
recordManagedIntegration("codex", {
|
|
2193
|
+
codex_home: codexHome,
|
|
2194
|
+
plugin_target: pluginTarget,
|
|
2195
|
+
marketplace_path: marketplace.marketplace_path,
|
|
2196
|
+
marketplace_name: marketplace.marketplace_name,
|
|
2197
|
+
restart_required: true,
|
|
2198
|
+
...(add.skipped ? {} : { registration_ok: add.ok }),
|
|
2199
|
+
});
|
|
2200
|
+
|
|
2089
2201
|
console.log(
|
|
2090
2202
|
JSON.stringify(
|
|
2091
2203
|
{
|
|
@@ -2281,6 +2393,16 @@ function runClaudeCodeInstall(args) {
|
|
|
2281
2393
|
}
|
|
2282
2394
|
}
|
|
2283
2395
|
|
|
2396
|
+
recordManagedIntegration("claude-code", {
|
|
2397
|
+
marketplace_dir: marketplaceDir,
|
|
2398
|
+
plugin_target: pluginLink,
|
|
2399
|
+
cache_root: path.resolve(
|
|
2400
|
+
expandHome(process.env.AGENT_WALLET_CLAUDE_CODE_CACHE_ROOT || "~/.claude/plugins/cache"),
|
|
2401
|
+
),
|
|
2402
|
+
restart_required: true,
|
|
2403
|
+
...(enable.skipped ? {} : { registration_ok: enable.ok }),
|
|
2404
|
+
});
|
|
2405
|
+
|
|
2284
2406
|
const ok = enable.skipped || enable.ok;
|
|
2285
2407
|
const pinnedCache = pinClaudeCacheCopies();
|
|
2286
2408
|
const pluginDirFlagFull = `claude --plugin-dir ${pluginSource}`;
|
|
@@ -2328,7 +2450,7 @@ function pathEntryExists(pathname) {
|
|
|
2328
2450
|
}
|
|
2329
2451
|
}
|
|
2330
2452
|
|
|
2331
|
-
function repairRuntimeSymlink(name, linkPath, desiredTarget, env = process.env) {
|
|
2453
|
+
function repairRuntimeSymlink(name, linkPath, desiredTarget, env = process.env, { allowExternal = false } = {}) {
|
|
2332
2454
|
let rawTarget;
|
|
2333
2455
|
try {
|
|
2334
2456
|
const stat = fs.lstatSync(linkPath);
|
|
@@ -2348,7 +2470,7 @@ function repairRuntimeSymlink(name, linkPath, desiredTarget, env = process.env)
|
|
|
2348
2470
|
if (absoluteTarget === path.resolve(desiredTarget) || absoluteTarget.startsWith(`${logicalCurrent}${path.sep}`)) {
|
|
2349
2471
|
return { name, attempted: true, ok: true, repaired: false, reason: "already current" };
|
|
2350
2472
|
}
|
|
2351
|
-
if (!runtimeReleasePath(absoluteTarget, env)) {
|
|
2473
|
+
if (!allowExternal && !runtimeReleasePath(absoluteTarget, env)) {
|
|
2352
2474
|
return { name, attempted: false, ok: true, repaired: false, reason: "external target preserved" };
|
|
2353
2475
|
}
|
|
2354
2476
|
if (!fs.existsSync(desiredTarget)) {
|
|
@@ -2358,8 +2480,7 @@ function repairRuntimeSymlink(name, linkPath, desiredTarget, env = process.env)
|
|
|
2358
2480
|
return { name, attempted: true, ok: true, repaired: true, target: desiredTarget };
|
|
2359
2481
|
}
|
|
2360
2482
|
|
|
2361
|
-
function repairHermesEnv(env = process.env) {
|
|
2362
|
-
const envPath = path.join(resolveHermesHome(env), ".env");
|
|
2483
|
+
function repairHermesEnv(envPath, env = process.env) {
|
|
2363
2484
|
const existing = readEnvFile(envPath);
|
|
2364
2485
|
const repaired = [];
|
|
2365
2486
|
const currentPackage = path.join(currentRuntimePath(env), "agent-wallet");
|
|
@@ -2379,44 +2500,378 @@ function repairHermesEnv(env = process.env) {
|
|
|
2379
2500
|
return repaired;
|
|
2380
2501
|
}
|
|
2381
2502
|
|
|
2503
|
+
function legacyHermesIntegration(env = process.env) {
|
|
2504
|
+
const hermesHome = resolveHermesHome(env);
|
|
2505
|
+
const pluginTarget = path.join(hermesHome, "plugins", "agent_wallet");
|
|
2506
|
+
let target;
|
|
2507
|
+
try {
|
|
2508
|
+
if (!fs.lstatSync(pluginTarget).isSymbolicLink()) return null;
|
|
2509
|
+
target = path.resolve(path.dirname(pluginTarget), fs.readlinkSync(pluginTarget));
|
|
2510
|
+
} catch {
|
|
2511
|
+
return null;
|
|
2512
|
+
}
|
|
2513
|
+
const manifest = readTextIfExists(path.join(target, "plugin.yaml"));
|
|
2514
|
+
if (!/^name:\s*agent[-_]wallet\s*$/m.test(manifest)) return null;
|
|
2515
|
+
return recordManagedIntegration(
|
|
2516
|
+
"hermes",
|
|
2517
|
+
{
|
|
2518
|
+
hermes_home: hermesHome,
|
|
2519
|
+
plugin_target: pluginTarget,
|
|
2520
|
+
env_path: path.join(hermesHome, ".env"),
|
|
2521
|
+
adopted_legacy_install: true,
|
|
2522
|
+
},
|
|
2523
|
+
env,
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
function repairOpenclawIntegration(env = process.env) {
|
|
2528
|
+
const entry = managedIntegration("openclaw", env);
|
|
2529
|
+
if (!entry) {
|
|
2530
|
+
return { name: "openclaw", attempted: false, ok: true, repaired: false, reason: "not managed" };
|
|
2531
|
+
}
|
|
2532
|
+
const configPath = path.resolve(
|
|
2533
|
+
expandHome(entry.config_path || path.join(resolveOpenclawHome(env), "openclaw.json")),
|
|
2534
|
+
);
|
|
2535
|
+
let config;
|
|
2536
|
+
try {
|
|
2537
|
+
config = readJsonFile(configPath);
|
|
2538
|
+
} catch (error) {
|
|
2539
|
+
return { name: "openclaw", attempted: true, ok: false, repaired: false, error: error.message };
|
|
2540
|
+
}
|
|
2541
|
+
if (!config || typeof config !== "object") {
|
|
2542
|
+
return { name: "openclaw", attempted: true, ok: false, repaired: false, error: `missing ${configPath}` };
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
const currentRoot = currentRuntimePath(env);
|
|
2546
|
+
const extensionPath = path.join(currentRoot, ".openclaw", "extensions", "agent-wallet");
|
|
2547
|
+
const packageRootPath = path.join(currentRoot, "agent-wallet");
|
|
2548
|
+
const pythonBin = resolveVenvPython(currentRoot);
|
|
2549
|
+
const plugins = config.plugins && typeof config.plugins === "object" ? config.plugins : (config.plugins = {});
|
|
2550
|
+
const load = plugins.load && typeof plugins.load === "object" ? plugins.load : (plugins.load = {});
|
|
2551
|
+
const paths = Array.isArray(load.paths) ? load.paths : [];
|
|
2552
|
+
load.paths = [
|
|
2553
|
+
...paths.filter((item) => {
|
|
2554
|
+
const value = String(item || "");
|
|
2555
|
+
return !value.replaceAll("\\", "/").endsWith("/.openclaw/extensions/agent-wallet");
|
|
2556
|
+
}),
|
|
2557
|
+
extensionPath,
|
|
2558
|
+
];
|
|
2559
|
+
const entries = plugins.entries && typeof plugins.entries === "object" ? plugins.entries : (plugins.entries = {});
|
|
2560
|
+
const walletEntry = entries["agent-wallet"];
|
|
2561
|
+
if (!walletEntry || typeof walletEntry !== "object") {
|
|
2562
|
+
return {
|
|
2563
|
+
name: "openclaw",
|
|
2564
|
+
attempted: false,
|
|
2565
|
+
ok: true,
|
|
2566
|
+
repaired: false,
|
|
2567
|
+
reason: "plugin entry not configured",
|
|
2568
|
+
};
|
|
2569
|
+
}
|
|
2570
|
+
walletEntry.enabled = true;
|
|
2571
|
+
walletEntry.config = walletEntry.config && typeof walletEntry.config === "object" ? walletEntry.config : {};
|
|
2572
|
+
walletEntry.config.packageRoot = packageRootPath;
|
|
2573
|
+
if (pythonBin) walletEntry.config.pythonBin = pythonBin;
|
|
2574
|
+
writeJsonFileAtomic(configPath, config);
|
|
2575
|
+
recordManagedIntegration(
|
|
2576
|
+
"openclaw",
|
|
2577
|
+
{
|
|
2578
|
+
config_path: configPath,
|
|
2579
|
+
extension_path: extensionPath,
|
|
2580
|
+
package_root: packageRootPath,
|
|
2581
|
+
restart_required: true,
|
|
2582
|
+
},
|
|
2583
|
+
env,
|
|
2584
|
+
);
|
|
2585
|
+
return {
|
|
2586
|
+
name: "openclaw",
|
|
2587
|
+
attempted: true,
|
|
2588
|
+
ok: true,
|
|
2589
|
+
repaired: true,
|
|
2590
|
+
config_path: configPath,
|
|
2591
|
+
restart_required: true,
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2595
|
+
function symlinkManifestMatches(linkPath, manifestRelativePath, expectedName) {
|
|
2596
|
+
let target;
|
|
2597
|
+
try {
|
|
2598
|
+
if (!fs.lstatSync(linkPath).isSymbolicLink()) return false;
|
|
2599
|
+
target = path.resolve(path.dirname(linkPath), fs.readlinkSync(linkPath));
|
|
2600
|
+
} catch {
|
|
2601
|
+
return false;
|
|
2602
|
+
}
|
|
2603
|
+
try {
|
|
2604
|
+
const manifest = readJsonFile(path.join(target, manifestRelativePath));
|
|
2605
|
+
return manifest && manifest.name === expectedName;
|
|
2606
|
+
} catch {
|
|
2607
|
+
return false;
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
function legacyCodexIntegration(env = process.env) {
|
|
2612
|
+
const marketplacePath = resolveCodexMarketplacePath(env);
|
|
2613
|
+
let marketplace;
|
|
2614
|
+
try {
|
|
2615
|
+
marketplace = readJsonFile(marketplacePath);
|
|
2616
|
+
} catch {
|
|
2617
|
+
return null;
|
|
2618
|
+
}
|
|
2619
|
+
const pluginTarget = path.join(resolveCodexPluginInstallRoot(env), "agent-wallet");
|
|
2620
|
+
const registered = Array.isArray(marketplace?.plugins) && marketplace.plugins.some(
|
|
2621
|
+
(item) => item?.name === "agent-wallet" && item?.source?.source === "local",
|
|
2622
|
+
);
|
|
2623
|
+
if (!registered || !symlinkManifestMatches(pluginTarget, ".codex-plugin/plugin.json", "agent-wallet")) {
|
|
2624
|
+
return null;
|
|
2625
|
+
}
|
|
2626
|
+
return recordManagedIntegration(
|
|
2627
|
+
"codex",
|
|
2628
|
+
{
|
|
2629
|
+
codex_home: resolveCodexHome(env),
|
|
2630
|
+
plugin_target: pluginTarget,
|
|
2631
|
+
marketplace_path: marketplacePath,
|
|
2632
|
+
marketplace_name: String(marketplace.name || "local"),
|
|
2633
|
+
adopted_legacy_install: true,
|
|
2634
|
+
},
|
|
2635
|
+
env,
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
function legacyClaudeCodeIntegration(env = process.env) {
|
|
2640
|
+
const marketplaceDir = resolveClaudeCodeMarketplaceDir(env);
|
|
2641
|
+
let manifest;
|
|
2642
|
+
try {
|
|
2643
|
+
manifest = readJsonFile(path.join(marketplaceDir, ".claude-plugin", "marketplace.json"));
|
|
2644
|
+
} catch {
|
|
2645
|
+
return null;
|
|
2646
|
+
}
|
|
2647
|
+
const pluginTarget = path.join(marketplaceDir, "plugins", "agent-wallet");
|
|
2648
|
+
const registered = manifest?.name === CLAUDE_CODE_MARKETPLACE_NAME &&
|
|
2649
|
+
Array.isArray(manifest.plugins) && manifest.plugins.some((item) => item?.name === "agent-wallet");
|
|
2650
|
+
if (!registered || !symlinkManifestMatches(pluginTarget, ".claude-plugin/plugin.json", "agent-wallet")) {
|
|
2651
|
+
return null;
|
|
2652
|
+
}
|
|
2653
|
+
return recordManagedIntegration(
|
|
2654
|
+
"claude-code",
|
|
2655
|
+
{
|
|
2656
|
+
marketplace_dir: marketplaceDir,
|
|
2657
|
+
plugin_target: pluginTarget,
|
|
2658
|
+
cache_root: path.resolve(
|
|
2659
|
+
expandHome(env.AGENT_WALLET_CLAUDE_CODE_CACHE_ROOT || "~/.claude/plugins/cache"),
|
|
2660
|
+
),
|
|
2661
|
+
adopted_legacy_install: true,
|
|
2662
|
+
},
|
|
2663
|
+
env,
|
|
2664
|
+
);
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
function runHostRefresh(command, args, env = process.env) {
|
|
2668
|
+
const binary = commandPath(command);
|
|
2669
|
+
if (!binary) {
|
|
2670
|
+
return {
|
|
2671
|
+
attempted: false,
|
|
2672
|
+
ok: false,
|
|
2673
|
+
error: `${command} CLI not found`,
|
|
2674
|
+
fix: args.join(" "),
|
|
2675
|
+
};
|
|
2676
|
+
}
|
|
2677
|
+
const result = spawnSync(binary, args, { cwd: packageRoot, encoding: "utf8", env });
|
|
2678
|
+
return {
|
|
2679
|
+
attempted: true,
|
|
2680
|
+
ok: result.status === 0,
|
|
2681
|
+
error: result.status === 0 ? "" : (result.stderr || result.stdout || "").trim(),
|
|
2682
|
+
fix: result.status === 0 ? "" : `${command} ${args.join(" ")}`,
|
|
2683
|
+
};
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
function globalNpmPackageInfo(env = process.env) {
|
|
2687
|
+
const npmBin = commandPath("npm");
|
|
2688
|
+
if (!npmBin) return null;
|
|
2689
|
+
const rootResult = spawnSync(npmBin, ["root", "--global"], { encoding: "utf8", env });
|
|
2690
|
+
if (rootResult.status !== 0) return null;
|
|
2691
|
+
const packageRoot = path.join(rootResult.stdout.trim(), ...packageJson.name.split("/"));
|
|
2692
|
+
try {
|
|
2693
|
+
const manifest = readJsonFile(path.join(packageRoot, "package.json"));
|
|
2694
|
+
if (manifest?.name !== packageJson.name) return null;
|
|
2695
|
+
return { npm_bin: npmBin, package_root: packageRoot, version: manifest.version || null };
|
|
2696
|
+
} catch {
|
|
2697
|
+
return null;
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
function refreshGlobalCliIfNeeded(env = process.env) {
|
|
2702
|
+
const installed = globalNpmPackageInfo(env);
|
|
2703
|
+
if (!installed) {
|
|
2704
|
+
return { attempted: false, ok: true, reason: "global package is not installed" };
|
|
2705
|
+
}
|
|
2706
|
+
if (installed.version === packageVersion) {
|
|
2707
|
+
return { attempted: false, ok: true, reason: "already current", version: packageVersion };
|
|
2708
|
+
}
|
|
2709
|
+
const fromNpmCache = path.resolve(packageRoot).split(path.sep).includes("_npx");
|
|
2710
|
+
const forced = env.AGENT_WALLET_FORCE_GLOBAL_CLI_REFRESH === "1";
|
|
2711
|
+
if (!fromNpmCache && !forced) {
|
|
2712
|
+
return {
|
|
2713
|
+
attempted: false,
|
|
2714
|
+
ok: false,
|
|
2715
|
+
reason: "installer is not running from npm exec",
|
|
2716
|
+
installed_version: installed.version,
|
|
2717
|
+
target_version: packageVersion,
|
|
2718
|
+
fix: `npm install --global ${packageJson.name}@${packageVersion}`,
|
|
2719
|
+
};
|
|
2720
|
+
}
|
|
2721
|
+
const packageSpec = `${packageJson.name}@${packageVersion}`;
|
|
2722
|
+
const result = spawnSync(
|
|
2723
|
+
installed.npm_bin,
|
|
2724
|
+
["install", "--global", "--no-audit", "--no-fund", packageSpec],
|
|
2725
|
+
{ encoding: "utf8", env },
|
|
2726
|
+
);
|
|
2727
|
+
return {
|
|
2728
|
+
attempted: true,
|
|
2729
|
+
ok: result.status === 0,
|
|
2730
|
+
previous_version: installed.version,
|
|
2731
|
+
target_version: packageVersion,
|
|
2732
|
+
error: result.status === 0 ? "" : (result.stderr || result.stdout || "").trim(),
|
|
2733
|
+
fix: result.status === 0 ? "" : `npm install --global ${packageSpec}`,
|
|
2734
|
+
};
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
function refreshCodexIntegration(entry, env = process.env) {
|
|
2738
|
+
const pluginTarget = path.resolve(
|
|
2739
|
+
expandHome(entry.plugin_target || path.join(resolveCodexPluginInstallRoot(env), "agent-wallet")),
|
|
2740
|
+
);
|
|
2741
|
+
const marketplacePath = path.resolve(
|
|
2742
|
+
expandHome(entry.marketplace_path || resolveCodexMarketplacePath(env)),
|
|
2743
|
+
);
|
|
2744
|
+
const link = repairRuntimeSymlink(
|
|
2745
|
+
"codex",
|
|
2746
|
+
pluginTarget,
|
|
2747
|
+
path.join(currentRuntimePath(env), "codex", "plugins", "agent-wallet"),
|
|
2748
|
+
env,
|
|
2749
|
+
{ allowExternal: true },
|
|
2750
|
+
);
|
|
2751
|
+
if (!link.ok) return link;
|
|
2752
|
+
const marketplace = ensureCodexMarketplaceEntry({ marketplacePath, pluginName: "agent-wallet" });
|
|
2753
|
+
const registration = runHostRefresh(
|
|
2754
|
+
"codex",
|
|
2755
|
+
["plugin", "add", `agent-wallet@${marketplace.marketplace_name}`],
|
|
2756
|
+
{ ...env, CODEX_HOME: entry.codex_home || resolveCodexHome(env) },
|
|
2757
|
+
);
|
|
2758
|
+
recordManagedIntegration(
|
|
2759
|
+
"codex",
|
|
2760
|
+
{
|
|
2761
|
+
...entry,
|
|
2762
|
+
plugin_target: pluginTarget,
|
|
2763
|
+
marketplace_path: marketplacePath,
|
|
2764
|
+
marketplace_name: marketplace.marketplace_name,
|
|
2765
|
+
registration_ok: registration.ok,
|
|
2766
|
+
restart_required: true,
|
|
2767
|
+
},
|
|
2768
|
+
env,
|
|
2769
|
+
);
|
|
2770
|
+
return {
|
|
2771
|
+
...link,
|
|
2772
|
+
ok: link.ok && registration.ok,
|
|
2773
|
+
registration,
|
|
2774
|
+
restart_required: true,
|
|
2775
|
+
};
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
function refreshClaudeCodeIntegration(entry, env = process.env) {
|
|
2779
|
+
const marketplaceDir = path.resolve(
|
|
2780
|
+
expandHome(entry.marketplace_dir || resolveClaudeCodeMarketplaceDir(env)),
|
|
2781
|
+
);
|
|
2782
|
+
const cacheRoot = path.resolve(
|
|
2783
|
+
expandHome(entry.cache_root || env.AGENT_WALLET_CLAUDE_CODE_CACHE_ROOT || "~/.claude/plugins/cache"),
|
|
2784
|
+
);
|
|
2785
|
+
const pluginTarget = path.resolve(
|
|
2786
|
+
expandHome(entry.plugin_target || path.join(marketplaceDir, "plugins", "agent-wallet")),
|
|
2787
|
+
);
|
|
2788
|
+
const link = repairRuntimeSymlink(
|
|
2789
|
+
"claude-code",
|
|
2790
|
+
pluginTarget,
|
|
2791
|
+
path.join(currentRuntimePath(env), "claude-code", "plugins", "agent-wallet"),
|
|
2792
|
+
env,
|
|
2793
|
+
{ allowExternal: true },
|
|
2794
|
+
);
|
|
2795
|
+
if (!link.ok) return link;
|
|
2796
|
+
ensureClaudeCodeMarketplace(
|
|
2797
|
+
marketplaceDir,
|
|
2798
|
+
path.join(currentRuntimePath(env), "claude-code", "plugins", "agent-wallet"),
|
|
2799
|
+
true,
|
|
2800
|
+
);
|
|
2801
|
+
const marketplaceAdd = runHostRefresh(
|
|
2802
|
+
"claude",
|
|
2803
|
+
["plugin", "marketplace", "add", marketplaceDir, "--scope", "user"],
|
|
2804
|
+
env,
|
|
2805
|
+
);
|
|
2806
|
+
const registration = marketplaceAdd.ok
|
|
2807
|
+
? runHostRefresh(
|
|
2808
|
+
"claude",
|
|
2809
|
+
["plugin", "install", `agent-wallet@${CLAUDE_CODE_MARKETPLACE_NAME}`, "--scope", "user"],
|
|
2810
|
+
env,
|
|
2811
|
+
)
|
|
2812
|
+
: { attempted: false, ok: false, error: "marketplace refresh failed", fix: marketplaceAdd.fix };
|
|
2813
|
+
const cachePins = pinClaudeCacheCopies({
|
|
2814
|
+
...env,
|
|
2815
|
+
AGENT_WALLET_CLAUDE_CODE_CACHE_ROOT: cacheRoot,
|
|
2816
|
+
});
|
|
2817
|
+
recordManagedIntegration(
|
|
2818
|
+
"claude-code",
|
|
2819
|
+
{
|
|
2820
|
+
...entry,
|
|
2821
|
+
marketplace_dir: marketplaceDir,
|
|
2822
|
+
plugin_target: pluginTarget,
|
|
2823
|
+
cache_root: cacheRoot,
|
|
2824
|
+
registration_ok: registration.ok,
|
|
2825
|
+
restart_required: true,
|
|
2826
|
+
},
|
|
2827
|
+
env,
|
|
2828
|
+
);
|
|
2829
|
+
return {
|
|
2830
|
+
...link,
|
|
2831
|
+
ok: link.ok && marketplaceAdd.ok && registration.ok,
|
|
2832
|
+
marketplace_add: marketplaceAdd,
|
|
2833
|
+
registration,
|
|
2834
|
+
cache_pins: cachePins,
|
|
2835
|
+
restart_required: true,
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2382
2839
|
function repairInstalledEditorIntegrations(env = process.env) {
|
|
2383
|
-
const results = [];
|
|
2840
|
+
const results = [repairOpenclawIntegration(env)];
|
|
2384
2841
|
const currentRoot = currentRuntimePath(env);
|
|
2385
|
-
const
|
|
2386
|
-
if (
|
|
2842
|
+
const hermesEntry = managedIntegration("hermes", env) || legacyHermesIntegration(env);
|
|
2843
|
+
if (hermesEntry) {
|
|
2844
|
+
const hermesTarget = path.resolve(expandHome(hermesEntry.plugin_target));
|
|
2845
|
+
const hermesEnvPath = path.resolve(expandHome(hermesEntry.env_path));
|
|
2387
2846
|
const result = repairRuntimeSymlink(
|
|
2388
2847
|
"hermes",
|
|
2389
2848
|
hermesTarget,
|
|
2390
2849
|
path.join(currentRoot, "hermes", "plugins", "agent_wallet"),
|
|
2391
2850
|
env,
|
|
2851
|
+
{ allowExternal: true },
|
|
2392
2852
|
);
|
|
2393
|
-
result.env_repaired = repairHermesEnv(env);
|
|
2853
|
+
result.env_repaired = repairHermesEnv(hermesEnvPath, env);
|
|
2854
|
+
result.restart_required = true;
|
|
2855
|
+
if (result.ok) {
|
|
2856
|
+
recordManagedIntegration(
|
|
2857
|
+
"hermes",
|
|
2858
|
+
{
|
|
2859
|
+
...hermesEntry,
|
|
2860
|
+
plugin_target: hermesTarget,
|
|
2861
|
+
env_path: hermesEnvPath,
|
|
2862
|
+
restart_required: true,
|
|
2863
|
+
},
|
|
2864
|
+
env,
|
|
2865
|
+
);
|
|
2866
|
+
}
|
|
2394
2867
|
results.push(result);
|
|
2395
2868
|
}
|
|
2396
2869
|
|
|
2397
|
-
const
|
|
2398
|
-
if (
|
|
2399
|
-
results.push(
|
|
2400
|
-
repairRuntimeSymlink(
|
|
2401
|
-
"codex",
|
|
2402
|
-
codexTarget,
|
|
2403
|
-
path.join(currentRoot, "codex", "plugins", "agent-wallet"),
|
|
2404
|
-
env,
|
|
2405
|
-
),
|
|
2406
|
-
);
|
|
2407
|
-
}
|
|
2870
|
+
const codexEntry = managedIntegration("codex", env) || legacyCodexIntegration(env);
|
|
2871
|
+
if (codexEntry) results.push(refreshCodexIntegration(codexEntry, env));
|
|
2408
2872
|
|
|
2409
|
-
const
|
|
2410
|
-
if (
|
|
2411
|
-
const result = repairRuntimeSymlink(
|
|
2412
|
-
"claude-code",
|
|
2413
|
-
claudeTarget,
|
|
2414
|
-
path.join(currentRoot, "claude-code", "plugins", "agent-wallet"),
|
|
2415
|
-
env,
|
|
2416
|
-
);
|
|
2417
|
-
result.cache_pins = pinClaudeCacheCopies(env);
|
|
2418
|
-
results.push(result);
|
|
2419
|
-
}
|
|
2873
|
+
const claudeEntry = managedIntegration("claude-code", env) || legacyClaudeCodeIntegration(env);
|
|
2874
|
+
if (claudeEntry) results.push(refreshClaudeCodeIntegration(claudeEntry, env));
|
|
2420
2875
|
return results;
|
|
2421
2876
|
}
|
|
2422
2877
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-wallet",
|
|
3
3
|
"displayName": "Agent Wallet",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.75",
|
|
5
5
|
"description": "Claude Code bridge for the existing AgentLayer wallet runtime. Connects to Solana, Bitcoin, and EVM wallets without creating a new one.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "AgentLayer"
|
package/package.json
CHANGED