@b-apm/cli 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{run-DV8BK0XR.mjs → run-B56hJHe9.mjs} +322 -54
- package/package.json +21 -21
package/dist/cli.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as runCli } from "./run-
|
|
1
|
+
import { t as runCli } from "./run-B56hJHe9.mjs";
|
|
2
2
|
export { runCli };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { BAPM_LOCK_FILE, BAPM_MANIFEST_FILE, BAPM_NAME, ManifestError, MarketplaceFetchError, MarketplaceNotFoundError, addMarketplace, addMarketplacePackage, assertExperimentalRegistriesEnabled, autoDetectMarketplacePath, buildPublishArchive, cacheClean, cacheInfo, checkMarketplaceAuthoring, checkReleaseTag, checkSelfUpdate, classifyMarketplaceHostKind, clearMarketplaceCache, compileAgentsMd, createDefaultDownloader, createDefaultGitRemote, createDefaultTagLister, createMarketplaceSource, createMinimalManifest, createRegistryClient, declaredTargetIntegrationMap, exportSbom, extractPackArchive, fetchMarketplace, findPath, formatAuditCiJson, formatAuditCiSarif, getMarketplace, getVersion, initMarketplaceAuthoring, listDeps, listMarketplaces, loadManifest, loadMarketplaceAuthoringConfig, migrateMarketplaceYml, persistUserExecutableGrant, removeMarketplace, removeMarketplacePackage, resolveAndLock, resolveEffectiveFrozen, resolveRegistryBaseUrl, runAuditCi, runDoctor, runInstall, runOutdated, runPack, runPolicyStatus, runPrune, runUninstall, runUpdate, setMarketplacePackage, treeDeps, urlNamesRemoteManifest, validateMarketplace, validatePluginName, validateProjectName, viewPackage, whyDeps, writeAgentPluginManifest, writePluginJson, writeProducerManifest } from "@b-apm/core";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
-
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
2
|
+
import { BAPM_LOCK_FILE, BAPM_MANIFEST_FILE, BAPM_NAME, ManifestError, MarketplaceFetchError, MarketplaceNotFoundError, addMarketplace, addMarketplacePackage, assertExperimentalRegistriesEnabled, autoDetectMarketplacePath, buildPublishArchive, cacheClean, cacheInfo, checkMarketplaceAuthoring, checkReleaseTag, checkSelfUpdate, checkVersionAlignment, classifyMarketplaceHostKind, clearMarketplaceCache, compileAgentsMd, createDefaultDownloader, createDefaultGitRemote, createDefaultTagLister, createMarketplaceSource, createMinimalManifest, createRegistryClient, declaredTargetIntegrationMap, detectAuthoringConfigSource, exportSbom, extractPackArchive, fetchMarketplace, findPath, formatAuditCiJson, formatAuditCiSarif, getMarketplace, getVersion, initMarketplaceAuthoring, listDeps, listMarketplaces, loadManifest, loadMarketplaceAuthoringConfig, migrateMarketplaceYml, persistUserExecutableGrant, removeMarketplace, removeMarketplacePackage, resolveAndLock, resolveEffectiveFrozen, resolveRegistryBaseUrl, runAuditCi, runDoctor, runInstall, runOutdated, runPack, runPolicyStatus, runPrune, runUninstall, runUpdate, setMarketplacePackage, treeDeps, urlNamesRemoteManifest, validateMarketplace, validatePluginName, validateProjectName, versionAlignmentErrorMessages, viewPackage, whyDeps, writeAgentPluginManifest, writePluginJson, writeProducerManifest } from "@b-apm/core";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { createInterface } from "node:readline";
|
|
7
7
|
import { pathToFileURL } from "node:url";
|
|
@@ -29,17 +29,17 @@ Commands:
|
|
|
29
29
|
plugin Scaffold a thin plugin project (plugin init)
|
|
30
30
|
lock Resolve dependencies and write the lockfile (no host deploy)
|
|
31
31
|
install Install agentic dependencies from ${deps.manifestFile} (or a pack .zip)
|
|
32
|
-
pack Build a plain-zip producer archive (--archive / --check-release)
|
|
32
|
+
pack Build a plain-zip producer archive (--archive / --check-release / --check-versions)
|
|
33
33
|
publish Publish flat registry zip via PUT (experimental; BAPM_EXPERIMENTAL_REGISTRIES=1)
|
|
34
34
|
self-update Check / apply CLI updates from npm (--check)
|
|
35
|
-
update Re-resolve pins
|
|
35
|
+
update Re-resolve dependency pins; --dry-run / -y
|
|
36
36
|
outdated Compare lock pins to remote tips (exit 0 when outdated)
|
|
37
37
|
uninstall Remove packages from manifest, modules, deploy, lock
|
|
38
38
|
prune Remove orphan modules not in the resolved graph
|
|
39
|
-
deps Inspect lock deps (list | tree | why)
|
|
39
|
+
deps Inspect lock deps (list | tree | why) or wipe modules (clean)
|
|
40
40
|
audit Integrity checks (--ci gate)
|
|
41
41
|
doctor Environment and project sanity checks
|
|
42
|
-
compile Emit AGENTS.md
|
|
42
|
+
compile Emit the agent's instructions file (AGENTS.md, CLAUDE.md, …)
|
|
43
43
|
cache Modules-cache info | clean (apm_modules)
|
|
44
44
|
policy Policy status (read-only governance posture)
|
|
45
45
|
approve Persist user-local MCP allow (~/.bapm/config.json; not project yml)
|
|
@@ -54,6 +54,7 @@ Install flags (see also: bapm help install):
|
|
|
54
54
|
--no-frozen Opt out of frozen (including when CI defaults to frozen)
|
|
55
55
|
--target <id> Force a registered host target (overrides manifest active)
|
|
56
56
|
--trust-transitive-mcp Deploy dependency MCP (default: direct dependencies.mcp only)
|
|
57
|
+
--trust-bin / --no-trust-bin Per-invocation bin/ consent (non-interactive defaults to skip)
|
|
57
58
|
|
|
58
59
|
Experimental registries:
|
|
59
60
|
Set BAPM_EXPERIMENTAL_REGISTRIES=1 to enable registry resolve/install and publish.
|
|
@@ -70,7 +71,7 @@ Usage:
|
|
|
70
71
|
Options:
|
|
71
72
|
--frozen Fail if lock is missing or pins drift; re-verify deployed_file_hashes when present
|
|
72
73
|
--no-frozen Opt out of frozen mode (including CI-default frozen)
|
|
73
|
-
--force
|
|
74
|
+
--force Accepted for APM parity; currently has no effect (does not refresh refs or bypass frozen/policy)
|
|
74
75
|
--allow-insecure Dual-consent half for direct http:// dependencies
|
|
75
76
|
--allow-insecure-host <hostname>
|
|
76
77
|
Allow transitive http:// from this FQDN (repeatable)
|
|
@@ -81,23 +82,32 @@ Options:
|
|
|
81
82
|
--policy <path> Use explicit policy file (wins over apm-policy.yml / bapm-policy.yml)
|
|
82
83
|
--no-policy Skip policy discovery and checks (also: BAPM_POLICY_DISABLE=1)
|
|
83
84
|
--trust-transitive-mcp Deploy MCP from dependencies (default: direct dependencies.mcp only)
|
|
85
|
+
--trust-bin Consent to deploy dependency/plugin bin/ for this run (when policy allows)
|
|
86
|
+
--no-trust-bin Skip bin/ deploy for this run (even when policy would allow)
|
|
84
87
|
--help, -h Show this help
|
|
85
88
|
|
|
86
89
|
Host selection:
|
|
87
|
-
Priority: --target <id> → manifest active:
|
|
90
|
+
Priority: --target <id> → manifest active: { target: <id> } → sole auto-detect → fail.
|
|
88
91
|
Use active in bapm.yml / apm.yml when detect is missing or ambiguous.
|
|
89
92
|
|
|
90
|
-
MCP
|
|
91
|
-
|
|
93
|
+
MCP:
|
|
94
|
+
Eligible MCP servers are written to the active agent's MCP config (for Cursor: .cursor/mcp.json).
|
|
92
95
|
Direct dependencies.mcp are deployed by default. Transitive MCP requires --trust-transitive-mcp
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
or an executables.allow grant for that package. Once any grant exists (bapm.yml executables,
|
|
97
|
+
bapm approve / deny), every dependency with MCP must be approved or denied.
|
|
98
|
+
|
|
99
|
+
Bin consent:
|
|
100
|
+
Non-interactive (CI / frozen / non-TTY) installs skip dependency bin/ unless --trust-bin or a
|
|
101
|
+
persisted executables.allow bin grant applies. Interactive installs deploy with a warning.
|
|
102
|
+
Flags cannot override org/project deny.
|
|
95
103
|
|
|
96
104
|
Unknown flags are rejected. --frozen and --no-frozen cannot be combined.
|
|
105
|
+
--trust-bin and --no-trust-bin cannot be combined.
|
|
97
106
|
Frozen (explicit or when CI is truthy) cannot be combined with --update.
|
|
98
107
|
When the CI environment variable is truthy (not "", "0", or "false"), install
|
|
99
|
-
defaults to frozen unless --no-frozen is passed
|
|
100
|
-
A local .zip path is
|
|
108
|
+
defaults to frozen unless --no-frozen is passed.
|
|
109
|
+
A local .zip path is installed as a pack archive: members are added to the current directory,
|
|
110
|
+
nothing else is removed, and existing files with different content are never overwritten.
|
|
101
111
|
`;
|
|
102
112
|
}
|
|
103
113
|
//#endregion
|
|
@@ -115,8 +125,11 @@ Options:
|
|
|
115
125
|
|
|
116
126
|
Notes:
|
|
117
127
|
Requires BAPM_EXPERIMENTAL_REGISTRIES=1 (experimental registries gate).
|
|
118
|
-
Auth: set BAPM_REGISTRY_TOKEN (Bearer) for protected registries.
|
|
119
|
-
|
|
128
|
+
Auth: set BAPM_REGISTRY_<NAME>_TOKEN or BAPM_REGISTRY_TOKEN (Bearer) for protected registries.
|
|
129
|
+
Requires name: owner/repo, registries.default, and a non-empty .apm/ directory.
|
|
130
|
+
Archive layout: apm.yml + .apm/ at zip root (differs from the bapm pack zip).
|
|
131
|
+
Optional project-root .bapmignore omits matching docs and .apm members (wire apm.yml always kept);
|
|
132
|
+
ignoring all of .apm fails closed. --zip uploads prebuilt bytes without re-applying .bapmignore.
|
|
120
133
|
Unknown flags are rejected.
|
|
121
134
|
`;
|
|
122
135
|
}
|
|
@@ -1630,10 +1643,12 @@ async function outdatedCommand(argv, outdated) {
|
|
|
1630
1643
|
//#endregion
|
|
1631
1644
|
//#region src/commands/pack.ts
|
|
1632
1645
|
async function packCommand(argv, pack) {
|
|
1633
|
-
|
|
1646
|
+
const result = await pack.run({
|
|
1634
1647
|
args: argv,
|
|
1635
1648
|
cwd: process.cwd()
|
|
1636
|
-
})
|
|
1649
|
+
});
|
|
1650
|
+
if (result.ok) return 0;
|
|
1651
|
+
return result.exitCode ?? 1;
|
|
1637
1652
|
}
|
|
1638
1653
|
//#endregion
|
|
1639
1654
|
//#region src/commands/plugin.ts
|
|
@@ -1705,7 +1720,7 @@ async function viewCommand(argv, view) {
|
|
|
1705
1720
|
//#endregion
|
|
1706
1721
|
//#region src/modules/Approve/services/runApprove.ts
|
|
1707
1722
|
function formatApproveHelp(deps) {
|
|
1708
|
-
return `${deps.name} approve — Persist user-local executable allow
|
|
1723
|
+
return `${deps.name} approve — Persist user-local executable allow
|
|
1709
1724
|
|
|
1710
1725
|
Usage:
|
|
1711
1726
|
bapm approve <package-name> [--user]
|
|
@@ -1920,7 +1935,7 @@ Usage:
|
|
|
1920
1935
|
Options:
|
|
1921
1936
|
--ci CI gate: lock present + deployed presence + hash re-verify
|
|
1922
1937
|
-f, --format Output format: text (default), json, or sarif
|
|
1923
|
-
-o, --output Write report
|
|
1938
|
+
-o, --output Write json/sarif report to file (mkdir parents); text always prints to stdout
|
|
1924
1939
|
`;
|
|
1925
1940
|
}
|
|
1926
1941
|
function serializeBody(format, result) {
|
|
@@ -2091,7 +2106,7 @@ Usage:
|
|
|
2091
2106
|
bapm cache clean [-y|--yes] [--dry-run]
|
|
2092
2107
|
|
|
2093
2108
|
Options:
|
|
2094
|
-
-y, --yes
|
|
2109
|
+
-y, --yes Required to clean (there is no interactive prompt)
|
|
2095
2110
|
--dry-run Preview clean without deleting (no -y required)
|
|
2096
2111
|
--help, -h Show this help
|
|
2097
2112
|
|
|
@@ -2278,25 +2293,58 @@ function isContainedUnderRoot(absoluteTarget, projectRoot) {
|
|
|
2278
2293
|
if (targetRelativeToRoot === "") return true;
|
|
2279
2294
|
return !(targetRelativeToRoot === ".." || targetRelativeToRoot.startsWith("..\\") || targetRelativeToRoot.startsWith("../") || isAbsolute(targetRelativeToRoot));
|
|
2280
2295
|
}
|
|
2281
|
-
|
|
2282
|
-
|
|
2296
|
+
let cachedGlobalModuleRoots;
|
|
2297
|
+
/**
|
|
2298
|
+
* Return the node_modules root only when the invoked entrypoint is this CLI
|
|
2299
|
+
* package. Resolving the symlink handles npm and pnpm global bin shims without
|
|
2300
|
+
* spawning a package manager during every CLI process.
|
|
2301
|
+
*/
|
|
2302
|
+
function globalModuleRootForCliEntry(entryPath) {
|
|
2303
|
+
if (!entryPath) return void 0;
|
|
2304
|
+
let entry = resolve(entryPath);
|
|
2305
|
+
try {
|
|
2306
|
+
entry = realpathSync(entry);
|
|
2307
|
+
} catch {}
|
|
2308
|
+
for (let directory = dirname(entry);; directory = dirname(directory)) {
|
|
2309
|
+
if (basename(directory) === "node_modules") {
|
|
2310
|
+
const packagePath = relative(directory, entry).split(sep);
|
|
2311
|
+
return packagePath[0] === "@b-apm" && packagePath[1] === "cli" ? directory : void 0;
|
|
2312
|
+
}
|
|
2313
|
+
if (dirname(directory) === directory) return void 0;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
function isWorkspaceModuleRoot(moduleRoot) {
|
|
2317
|
+
for (let directory = dirname(moduleRoot);; directory = dirname(directory)) {
|
|
2318
|
+
if (existsSync(join(directory, "pnpm-workspace.yaml"))) return true;
|
|
2319
|
+
if (dirname(directory) === directory) return false;
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
/** Locate the global module root of the invoked CLI without consulting dev dependencies. */
|
|
2323
|
+
function globalModuleRoots() {
|
|
2324
|
+
if (cachedGlobalModuleRoots) return cachedGlobalModuleRoots;
|
|
2325
|
+
const root = globalModuleRootForCliEntry(process.argv[1]);
|
|
2326
|
+
cachedGlobalModuleRoots = root && !isWorkspaceModuleRoot(root) ? [root] : [];
|
|
2327
|
+
return cachedGlobalModuleRoots;
|
|
2328
|
+
}
|
|
2329
|
+
/** Resolve a canonical package from the project, global paths, or global module roots. */
|
|
2330
|
+
function resolveNpmProjectOrGlobal(specifier, cwd, globalRoots = globalModuleRoots()) {
|
|
2283
2331
|
const requireFromCwd = createRequire(join(cwd, "package.json"));
|
|
2284
2332
|
try {
|
|
2285
2333
|
return requireFromCwd.resolve(specifier);
|
|
2286
2334
|
} catch (cwdErr) {
|
|
2287
2335
|
const mod = createRequire(import.meta.url)("node:module");
|
|
2288
|
-
const
|
|
2289
|
-
if (
|
|
2336
|
+
const searchRoots = [...Array.isArray(mod.globalPaths) ? mod.globalPaths.filter((path) => !isWorkspaceModuleRoot(path)) : [], ...globalRoots];
|
|
2337
|
+
if (searchRoots.length === 0) throw cwdErr;
|
|
2290
2338
|
try {
|
|
2291
|
-
return requireFromCwd.resolve(specifier, { paths:
|
|
2339
|
+
return requireFromCwd.resolve(specifier, { paths: searchRoots });
|
|
2292
2340
|
} catch {
|
|
2293
2341
|
throw cwdErr;
|
|
2294
2342
|
}
|
|
2295
2343
|
}
|
|
2296
2344
|
}
|
|
2297
|
-
/** npm package: project cwd first, then CLI
|
|
2345
|
+
/** npm package: project cwd first, then CLI fallback (map) or global lookup (canonical). */
|
|
2298
2346
|
function resolveNpmPackageSpecifier(specifier, cwd, options = {}) {
|
|
2299
|
-
if (!(options.allowCliFallback !== false)) return resolveNpmProjectOrGlobal(specifier, cwd);
|
|
2347
|
+
if (!(options.allowCliFallback !== false)) return resolveNpmProjectOrGlobal(specifier, cwd, options.globalRoots);
|
|
2300
2348
|
const requireFromCwd = createRequire(join(cwd, "package.json"));
|
|
2301
2349
|
try {
|
|
2302
2350
|
return requireFromCwd.resolve(specifier);
|
|
@@ -2354,7 +2402,10 @@ async function loadIntegrationFromPackage(specifier, expectedId, cwd, options =
|
|
|
2354
2402
|
let resolved;
|
|
2355
2403
|
if (isLocalPathSpecifier(specifier)) resolved = resolveLocalIntegrationPath(specifier, expectedId, cwd);
|
|
2356
2404
|
else try {
|
|
2357
|
-
resolved = resolveNpmPackageSpecifier(specifier, cwd, {
|
|
2405
|
+
resolved = resolveNpmPackageSpecifier(specifier, cwd, {
|
|
2406
|
+
allowCliFallback: options.allowCliFallback,
|
|
2407
|
+
globalRoots: options.globalRoots
|
|
2408
|
+
});
|
|
2358
2409
|
} catch (cause) {
|
|
2359
2410
|
throw new ManifestIntegrationLoadError(expectedId, specifier, "unresolvable", `unresolvable module: ${cause instanceof Error ? cause.message : "cannot find module / unresolvable package"}`);
|
|
2360
2411
|
}
|
|
@@ -2433,7 +2484,7 @@ function createCliIntegrationRegistry() {
|
|
|
2433
2484
|
/**
|
|
2434
2485
|
* Append actionable install guidance for unknown-target / missing-detect diagnostics.
|
|
2435
2486
|
*/
|
|
2436
|
-
const ALREADY_GUIDED = /@
|
|
2487
|
+
const ALREADY_GUIDED = /@b-apm\/integration-|install the (?:host )?integration|npm i |not installed or resolvable/i;
|
|
2437
2488
|
function extractUnregisteredId(message) {
|
|
2438
2489
|
return message.match(/unknown or unregistered target:\s*([^\s,;]+)/i)?.[1]?.replace(/[."']+$/, "");
|
|
2439
2490
|
}
|
|
@@ -2568,7 +2619,7 @@ function parseCompileArgs(argv) {
|
|
|
2568
2619
|
};
|
|
2569
2620
|
}
|
|
2570
2621
|
function formatCompileHelp(deps) {
|
|
2571
|
-
return `${deps.name} compile — Emit
|
|
2622
|
+
return `${deps.name} compile — Emit the agent's instructions file (AGENTS.md, CLAUDE.md, …)
|
|
2572
2623
|
|
|
2573
2624
|
Usage:
|
|
2574
2625
|
bapm compile [-o PATH] [--target <id>] [--dry-run] [-v] [--validate]
|
|
@@ -2584,6 +2635,7 @@ Options:
|
|
|
2584
2635
|
Host selection: --target <id> → sole manifest active → sole auto-detect → fail.
|
|
2585
2636
|
When active lists multiple hosts, pass --target <id>. Compile stays single-host.
|
|
2586
2637
|
The selected target determines the default output path and rendering.
|
|
2638
|
+
Run from the directory that contains ${deps.manifestFile}.
|
|
2587
2639
|
`;
|
|
2588
2640
|
}
|
|
2589
2641
|
async function runCompileCli(deps, options) {
|
|
@@ -2668,7 +2720,7 @@ const compile = createCompile({
|
|
|
2668
2720
|
//#endregion
|
|
2669
2721
|
//#region src/modules/Deny/services/runDeny.ts
|
|
2670
2722
|
function formatDenyHelp(deps) {
|
|
2671
|
-
return `${deps.name} deny — Persist user-local executable deny
|
|
2723
|
+
return `${deps.name} deny — Persist user-local executable deny
|
|
2672
2724
|
|
|
2673
2725
|
Usage:
|
|
2674
2726
|
bapm deny <package-name> [--user]
|
|
@@ -2980,7 +3032,7 @@ Options:
|
|
|
2980
3032
|
|
|
2981
3033
|
Informational:
|
|
2982
3034
|
auth Whether GITHUB_TOKEN / GH_TOKEN is set (names only, never secrets)
|
|
2983
|
-
network With -v: git ls-remote probe (never critical)
|
|
3035
|
+
network With -v: git ls-remote probe of github.com (never critical)
|
|
2984
3036
|
`;
|
|
2985
3037
|
}
|
|
2986
3038
|
async function runDoctorCli(deps, options) {
|
|
@@ -3197,12 +3249,14 @@ Usage:
|
|
|
3197
3249
|
|
|
3198
3250
|
Options:
|
|
3199
3251
|
-y, --yes Non-interactive defaults (version 0.1.0)
|
|
3200
|
-
--target <id>
|
|
3252
|
+
--target <id> Activate an agent (e.g. cursor); also writes a targets: entry that
|
|
3253
|
+
limits deployment to that agent
|
|
3201
3254
|
--help, -h Show this help
|
|
3202
3255
|
|
|
3203
3256
|
Notes:
|
|
3204
3257
|
Writes ${deps.manifestFile} only. Refuses if apm.yml or bapm.yml already exists.
|
|
3205
|
-
|
|
3258
|
+
Remove the generated targets: block if the project is shared with other agents.
|
|
3259
|
+
Unknown flags are rejected. For plugin or marketplace scaffolds use bapm plugin init / bapm marketplace init.
|
|
3206
3260
|
`;
|
|
3207
3261
|
}
|
|
3208
3262
|
function parseInitArgs(argv) {
|
|
@@ -3269,7 +3323,7 @@ function scaffoldTargetFields(targetId) {
|
|
|
3269
3323
|
const id = targetId.trim();
|
|
3270
3324
|
return {
|
|
3271
3325
|
targets: { [id]: `@b-apm/integration-${id}` },
|
|
3272
|
-
active:
|
|
3326
|
+
active: { target: id }
|
|
3273
3327
|
};
|
|
3274
3328
|
}
|
|
3275
3329
|
async function runInit(deps, options) {
|
|
@@ -3354,6 +3408,90 @@ const init = createInit({
|
|
|
3354
3408
|
detectCursor: (cwd) => existsSync(join(cwd, ".cursor"))
|
|
3355
3409
|
});
|
|
3356
3410
|
//#endregion
|
|
3411
|
+
//#region src/common/formatErrorCauseChain.ts
|
|
3412
|
+
const DEFAULT_MAX_DEPTH = 5;
|
|
3413
|
+
const DEFAULT_INDENT = " ";
|
|
3414
|
+
const CAUSE_LABEL = "cause";
|
|
3415
|
+
const CAUSE_INDENT_CONTINUATION = " ";
|
|
3416
|
+
function isObjectLike(value) {
|
|
3417
|
+
return typeof value === "object" && value !== null || typeof value === "function";
|
|
3418
|
+
}
|
|
3419
|
+
function safeString(value) {
|
|
3420
|
+
try {
|
|
3421
|
+
return String(value);
|
|
3422
|
+
} catch {
|
|
3423
|
+
try {
|
|
3424
|
+
return Object.prototype.toString.call(value);
|
|
3425
|
+
} catch {
|
|
3426
|
+
return "[unprintable value]";
|
|
3427
|
+
}
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
/** Best-effort message for Errors, error-like objects, strings, and primitives. */
|
|
3431
|
+
function formatErrorMessage(value) {
|
|
3432
|
+
if (value instanceof Error) return value.message;
|
|
3433
|
+
if (typeof value === "string") return value;
|
|
3434
|
+
if (isObjectLike(value)) try {
|
|
3435
|
+
if ("message" in value) return safeString(value.message);
|
|
3436
|
+
} catch {}
|
|
3437
|
+
return safeString(value);
|
|
3438
|
+
}
|
|
3439
|
+
function causeOf(value) {
|
|
3440
|
+
if (!isObjectLike(value)) return { present: false };
|
|
3441
|
+
try {
|
|
3442
|
+
if (!("cause" in value)) return { present: false };
|
|
3443
|
+
return {
|
|
3444
|
+
present: true,
|
|
3445
|
+
cause: value.cause
|
|
3446
|
+
};
|
|
3447
|
+
} catch {
|
|
3448
|
+
return { present: false };
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
function renderCause(value, indent) {
|
|
3452
|
+
const [first = "", ...rest] = formatErrorMessage(value).split(/\r?\n/);
|
|
3453
|
+
const continuation = `${indent}${CAUSE_INDENT_CONTINUATION}`;
|
|
3454
|
+
return [`${indent}${CAUSE_LABEL}: ${first}`, ...rest.map((line) => `${continuation}${line}`)].join("\n");
|
|
3455
|
+
}
|
|
3456
|
+
/**
|
|
3457
|
+
* Format `error` for terminal output.
|
|
3458
|
+
*
|
|
3459
|
+
* @example
|
|
3460
|
+
* formatErrorCauseChain(err, { verbose: true })
|
|
3461
|
+
* // "Failed to download https://…\n cause: Local path not found: skills/frontend-design"
|
|
3462
|
+
*/
|
|
3463
|
+
function formatErrorCauseChain(error, options = {}) {
|
|
3464
|
+
const rootMessage = options.message ?? formatErrorMessage(error);
|
|
3465
|
+
if (!options.verbose) return rootMessage;
|
|
3466
|
+
const maxDepth = options.maxDepth !== void 0 && Number.isFinite(options.maxDepth) ? Math.max(0, Math.floor(options.maxDepth)) : DEFAULT_MAX_DEPTH;
|
|
3467
|
+
if (maxDepth === 0) return rootMessage;
|
|
3468
|
+
const indent = options.indent ?? DEFAULT_INDENT;
|
|
3469
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
3470
|
+
if (isObjectLike(error)) visited.add(error);
|
|
3471
|
+
const lines = [rootMessage];
|
|
3472
|
+
let current = error;
|
|
3473
|
+
let depth = 0;
|
|
3474
|
+
for (;;) {
|
|
3475
|
+
const link = causeOf(current);
|
|
3476
|
+
if (!link.present) break;
|
|
3477
|
+
const cause = link.cause;
|
|
3478
|
+
if (cause === void 0 || cause === null) break;
|
|
3479
|
+
if (isObjectLike(cause) && visited.has(cause)) {
|
|
3480
|
+
lines.push(`${indent}${CAUSE_LABEL}: [circular cause]`);
|
|
3481
|
+
break;
|
|
3482
|
+
}
|
|
3483
|
+
if (depth >= maxDepth) {
|
|
3484
|
+
lines.push(`${indent}${CAUSE_LABEL}: [cause chain truncated after ${maxDepth} level(s)]`);
|
|
3485
|
+
break;
|
|
3486
|
+
}
|
|
3487
|
+
if (isObjectLike(cause)) visited.add(cause);
|
|
3488
|
+
lines.push(renderCause(cause, indent));
|
|
3489
|
+
current = cause;
|
|
3490
|
+
depth += 1;
|
|
3491
|
+
}
|
|
3492
|
+
return lines.join("\n");
|
|
3493
|
+
}
|
|
3494
|
+
//#endregion
|
|
3357
3495
|
//#region src/modules/Install/services/runInstall.ts
|
|
3358
3496
|
function formatInstallHelp(deps) {
|
|
3359
3497
|
return `${deps.name} install — Install agentic dependencies from ${deps.manifestFile}
|
|
@@ -3367,7 +3505,7 @@ Options:
|
|
|
3367
3505
|
--frozen Fail if lock is missing or pins drift; re-verify deployed_file_hashes when present
|
|
3368
3506
|
--no-frozen Opt out of frozen mode (including CI-default frozen)
|
|
3369
3507
|
--dry-run Preview direct deps / would-add; no durable project writes
|
|
3370
|
-
--force
|
|
3508
|
+
--force Accepted for APM parity; currently has no effect (does not refresh refs or bypass frozen/policy)
|
|
3371
3509
|
--allow-insecure Allow direct http:// deps that also set allow_insecure: true (dual consent)
|
|
3372
3510
|
--allow-insecure-host <hostname>
|
|
3373
3511
|
Allow transitive http:// deps from this FQDN (repeatable)
|
|
@@ -3381,22 +3519,29 @@ Options:
|
|
|
3381
3519
|
--policy <path> Use explicit policy file (wins over apm-policy.yml / bapm-policy.yml)
|
|
3382
3520
|
--no-policy Skip policy discovery and checks (also: BAPM_POLICY_DISABLE=1)
|
|
3383
3521
|
--trust-transitive-mcp Deploy MCP from dependencies (default: direct dependencies.mcp only)
|
|
3522
|
+
--trust-bin Consent to deploy dependency/plugin bin/ for this run (when policy allows)
|
|
3523
|
+
--no-trust-bin Skip bin/ deploy for this run (even when policy would allow)
|
|
3384
3524
|
--help, -h Show this help
|
|
3385
3525
|
|
|
3386
3526
|
Notes:
|
|
3387
3527
|
Unknown flags are rejected. Combining --frozen with --no-frozen is an error.
|
|
3528
|
+
Combining --trust-bin with --no-trust-bin is an error.
|
|
3388
3529
|
Combining frozen (explicit or CI-default) with --update is an error.
|
|
3389
|
-
Frozen
|
|
3530
|
+
Frozen re-verifies lock pins, deployed file hashes and package tree hashes.
|
|
3390
3531
|
When the CI environment variable is truthy (not "", "0", or "false"), install
|
|
3391
|
-
defaults to frozen unless --no-frozen is passed
|
|
3392
|
-
|
|
3532
|
+
defaults to frozen unless --no-frozen is passed.
|
|
3533
|
+
Non-interactive installs (CI, BAPM_NON_INTERACTIVE, non-TTY, or frozen) do not deploy
|
|
3534
|
+
dependency bin/ by default without --trust-bin or a persisted executables.allow bin grant;
|
|
3535
|
+
interactive installs deploy it with a warning.
|
|
3536
|
+
--trust-bin / --no-trust-bin are per-invocation consent and cannot override org/project deny.
|
|
3537
|
+
A local .zip path is installed as a pack archive: members are added to the current directory,
|
|
3538
|
+
nothing else is removed, and existing files with different content are never overwritten.
|
|
3393
3539
|
Non-zip positionals are package refs added to dependencies.apm (auto-creates
|
|
3394
3540
|
a minimal manifest when missing). Frozen rejects positional package-ref add.
|
|
3395
3541
|
--exclude filters MCP/runtime configure only — not a full skip-install.
|
|
3396
|
-
--
|
|
3397
|
-
Host selection: --target <id> → manifest active: [<id>, …] → sole auto-detect → fail.
|
|
3542
|
+
Host selection: --target <id> → manifest active: { target: <id> } → sole auto-detect → fail.
|
|
3398
3543
|
Set active in bapm.yml / apm.yml when detect is missing or ambiguous.
|
|
3399
|
-
|
|
3544
|
+
Eligible MCP servers are written to the active agent's MCP config (direct mcp by default).
|
|
3400
3545
|
`;
|
|
3401
3546
|
}
|
|
3402
3547
|
function parseInstallArgs(argv, options = {}) {
|
|
@@ -3418,6 +3563,8 @@ function parseInstallArgs(argv, options = {}) {
|
|
|
3418
3563
|
let policyPath;
|
|
3419
3564
|
let noPolicy = false;
|
|
3420
3565
|
let trustTransitiveMcp = false;
|
|
3566
|
+
let trustBinAllow = false;
|
|
3567
|
+
let trustBinDeny = false;
|
|
3421
3568
|
let help = false;
|
|
3422
3569
|
const partial = () => ({
|
|
3423
3570
|
frozen: frozenFlag,
|
|
@@ -3437,7 +3584,8 @@ function parseInstallArgs(argv, options = {}) {
|
|
|
3437
3584
|
parallelDownloads,
|
|
3438
3585
|
policyPath,
|
|
3439
3586
|
noPolicy,
|
|
3440
|
-
trustTransitiveMcp
|
|
3587
|
+
trustTransitiveMcp,
|
|
3588
|
+
trustBin: trustBinAllow ? "allow" : trustBinDeny ? "deny" : "default"
|
|
3441
3589
|
});
|
|
3442
3590
|
for (let i = 0; i < argv.length; i++) {
|
|
3443
3591
|
const arg = argv[i];
|
|
@@ -3485,6 +3633,14 @@ function parseInstallArgs(argv, options = {}) {
|
|
|
3485
3633
|
trustTransitiveMcp = true;
|
|
3486
3634
|
continue;
|
|
3487
3635
|
}
|
|
3636
|
+
if (arg === "--trust-bin") {
|
|
3637
|
+
trustBinAllow = true;
|
|
3638
|
+
continue;
|
|
3639
|
+
}
|
|
3640
|
+
if (arg === "--no-trust-bin") {
|
|
3641
|
+
trustBinDeny = true;
|
|
3642
|
+
continue;
|
|
3643
|
+
}
|
|
3488
3644
|
if (arg === "--allow-insecure-host") {
|
|
3489
3645
|
const next = argv[i + 1];
|
|
3490
3646
|
if (!next || next.startsWith("-")) return {
|
|
@@ -3649,6 +3805,11 @@ function parseInstallArgs(argv, options = {}) {
|
|
|
3649
3805
|
...partial(),
|
|
3650
3806
|
error: "Cannot combine --frozen and --no-frozen (mutually exclusive flags conflict)"
|
|
3651
3807
|
};
|
|
3808
|
+
if (trustBinAllow && trustBinDeny) return {
|
|
3809
|
+
...partial(),
|
|
3810
|
+
error: "Cannot combine --trust-bin and --no-trust-bin (mutually exclusive flags conflict)"
|
|
3811
|
+
};
|
|
3812
|
+
const trustBin = trustBinAllow ? "allow" : trustBinDeny ? "deny" : "default";
|
|
3652
3813
|
const env = options.env ?? process.env;
|
|
3653
3814
|
let frozen;
|
|
3654
3815
|
try {
|
|
@@ -3661,12 +3822,14 @@ function parseInstallArgs(argv, options = {}) {
|
|
|
3661
3822
|
const message = error instanceof Error ? error.message : String(error);
|
|
3662
3823
|
return {
|
|
3663
3824
|
...partial(),
|
|
3825
|
+
trustBin,
|
|
3664
3826
|
error: message
|
|
3665
3827
|
};
|
|
3666
3828
|
}
|
|
3667
3829
|
if (frozen && update) return {
|
|
3668
3830
|
...partial(),
|
|
3669
3831
|
frozen,
|
|
3832
|
+
trustBin,
|
|
3670
3833
|
error: "Frozen mode rejects --update (frozen+update mutation rejected)"
|
|
3671
3834
|
};
|
|
3672
3835
|
return {
|
|
@@ -3688,6 +3851,7 @@ function parseInstallArgs(argv, options = {}) {
|
|
|
3688
3851
|
policyPath,
|
|
3689
3852
|
noPolicy,
|
|
3690
3853
|
trustTransitiveMcp,
|
|
3854
|
+
trustBin,
|
|
3691
3855
|
help
|
|
3692
3856
|
};
|
|
3693
3857
|
}
|
|
@@ -3785,6 +3949,8 @@ async function runCoreInstall(deps, options, parsed, archivePath) {
|
|
|
3785
3949
|
policy: parsed.policyPath,
|
|
3786
3950
|
noPolicy: parsed.noPolicy,
|
|
3787
3951
|
trustTransitiveMcp: parsed.trustTransitiveMcp,
|
|
3952
|
+
trustBin: parsed.trustBin,
|
|
3953
|
+
env: options.env ?? process.env,
|
|
3788
3954
|
gitRemote: createDefaultGitRemote(),
|
|
3789
3955
|
tagLister: createDefaultTagLister(),
|
|
3790
3956
|
downloader: createDefaultDownloader()
|
|
@@ -3797,8 +3963,12 @@ async function runCoreInstall(deps, options, parsed, archivePath) {
|
|
|
3797
3963
|
} else if (result.activeTargets && result.activeTargets.length > 0) console.log(`${deps.name}: installed for ${result.activeTargets.join(", ")}`);
|
|
3798
3964
|
return { ok: true };
|
|
3799
3965
|
} catch (error) {
|
|
3800
|
-
const message = enrichUnregisteredTargetMessage(
|
|
3801
|
-
|
|
3966
|
+
const message = enrichUnregisteredTargetMessage(formatErrorMessage(error), cwd);
|
|
3967
|
+
const rendered = formatErrorCauseChain(error, {
|
|
3968
|
+
verbose: parsed.verbose,
|
|
3969
|
+
message
|
|
3970
|
+
});
|
|
3971
|
+
console.error(`${deps.name}: ${rendered}`);
|
|
3802
3972
|
return {
|
|
3803
3973
|
ok: false,
|
|
3804
3974
|
message
|
|
@@ -4062,10 +4232,12 @@ Usage:
|
|
|
4062
4232
|
bapm pack [options]
|
|
4063
4233
|
|
|
4064
4234
|
Options:
|
|
4065
|
-
--archive Write a plain zip artifact (
|
|
4235
|
+
--archive Write a plain zip artifact (also the default without flags)
|
|
4066
4236
|
--agent-plugins Pack a validated Agent Plugins v1 portable root
|
|
4067
4237
|
--dry-run Validate / collect without durable zip or marketplace.json
|
|
4068
|
-
--check-release
|
|
4238
|
+
--check-release Check that the manifest version matches the git tag
|
|
4239
|
+
--check-versions Marketplace local-package version alignment (lockstep /
|
|
4240
|
+
tag_pattern / per_package); plugin.json fallback when no YAML
|
|
4069
4241
|
--tag <name> Tag under check (optional with --check-release; else HEAD)
|
|
4070
4242
|
--marketplace <all|none|list>
|
|
4071
4243
|
Filter host marketplace emit (claude,codex); default: all configured
|
|
@@ -4077,7 +4249,10 @@ Options:
|
|
|
4077
4249
|
|
|
4078
4250
|
Notes:
|
|
4079
4251
|
Unknown flags are rejected. --check-release never creates or pushes tags.
|
|
4080
|
-
|
|
4252
|
+
--check-versions is distinct from --check-release (marketplace alignment vs tag↔root version).
|
|
4253
|
+
Pack refuses secret-pattern paths (.env, *.pem, …).
|
|
4254
|
+
Optional project-root .bapmignore (gitignore syntax) omits matching files from the zip;
|
|
4255
|
+
root bapm.yml/apm.yml stay included; .gitignore is not used as a fallback.
|
|
4081
4256
|
When marketplace: is present with outputs selected, pack emits Claude/Codex marketplace.json.
|
|
4082
4257
|
Marketplace-only projects (no dependencies:) emit JSON and skip empty zip.
|
|
4083
4258
|
--agent-plugins never emits marketplace output and requires root plugin.json.
|
|
@@ -4088,6 +4263,7 @@ function parsePackArgs(argv) {
|
|
|
4088
4263
|
let agentPlugins = false;
|
|
4089
4264
|
let dryRun = false;
|
|
4090
4265
|
let checkRelease = false;
|
|
4266
|
+
let checkVersions = false;
|
|
4091
4267
|
let tag;
|
|
4092
4268
|
let marketplace;
|
|
4093
4269
|
const marketplacePaths = [];
|
|
@@ -4099,6 +4275,7 @@ function parsePackArgs(argv) {
|
|
|
4099
4275
|
agentPlugins,
|
|
4100
4276
|
dryRun,
|
|
4101
4277
|
checkRelease,
|
|
4278
|
+
checkVersions,
|
|
4102
4279
|
tag,
|
|
4103
4280
|
marketplace,
|
|
4104
4281
|
marketplacePaths,
|
|
@@ -4127,6 +4304,10 @@ function parsePackArgs(argv) {
|
|
|
4127
4304
|
checkRelease = true;
|
|
4128
4305
|
continue;
|
|
4129
4306
|
}
|
|
4307
|
+
if (arg === "--check-versions") {
|
|
4308
|
+
checkVersions = true;
|
|
4309
|
+
continue;
|
|
4310
|
+
}
|
|
4130
4311
|
if (arg === "--offline") {
|
|
4131
4312
|
offline = true;
|
|
4132
4313
|
continue;
|
|
@@ -4205,6 +4386,65 @@ function parsePackArgs(argv) {
|
|
|
4205
4386
|
help
|
|
4206
4387
|
};
|
|
4207
4388
|
}
|
|
4389
|
+
const VERSION_ALIGNMENT_EXIT = 3;
|
|
4390
|
+
function runCheckVersionsGate(deps, cwd) {
|
|
4391
|
+
const root = cwd ?? process.cwd();
|
|
4392
|
+
const detect = deps.detectAuthoringConfigSource;
|
|
4393
|
+
const load = deps.loadMarketplaceAuthoringConfig;
|
|
4394
|
+
const check = deps.checkVersionAlignment;
|
|
4395
|
+
const formatErrors = deps.versionAlignmentErrorMessages;
|
|
4396
|
+
if (!detect || !load || !check || !formatErrors) {
|
|
4397
|
+
const message = "Internal error: --check-versions deps not wired";
|
|
4398
|
+
console.error(`${deps.name}: ${message}`);
|
|
4399
|
+
return {
|
|
4400
|
+
ok: false,
|
|
4401
|
+
message,
|
|
4402
|
+
exitCode: 1
|
|
4403
|
+
};
|
|
4404
|
+
}
|
|
4405
|
+
const detected = detect({ cwd: root });
|
|
4406
|
+
if (!detected.ok || detected.kind === "none") {
|
|
4407
|
+
console.log(`${deps.name}: Version alignment check skipped: no marketplace block; nothing to check.`);
|
|
4408
|
+
return {
|
|
4409
|
+
ok: true,
|
|
4410
|
+
exitCode: 0
|
|
4411
|
+
};
|
|
4412
|
+
}
|
|
4413
|
+
let config;
|
|
4414
|
+
try {
|
|
4415
|
+
config = load({ cwd: root }).config;
|
|
4416
|
+
} catch (error) {
|
|
4417
|
+
const message = error instanceof Error ? error.message : typeof error === "object" && error !== null && "message" in error ? String(error.message) : String(error);
|
|
4418
|
+
console.error(`${deps.name}: ${message}`);
|
|
4419
|
+
return {
|
|
4420
|
+
ok: false,
|
|
4421
|
+
message,
|
|
4422
|
+
exitCode: 1
|
|
4423
|
+
};
|
|
4424
|
+
}
|
|
4425
|
+
const report = check({
|
|
4426
|
+
config,
|
|
4427
|
+
cwd: root,
|
|
4428
|
+
projectRoot: root,
|
|
4429
|
+
root
|
|
4430
|
+
});
|
|
4431
|
+
if (report.ok) {
|
|
4432
|
+
if (report.expected !== null) console.log(`${deps.name}: Version alignment OK [strategy=${report.strategy}, expected=${report.expected}]`);
|
|
4433
|
+
else console.log(`${deps.name}: Version alignment OK [strategy=${report.strategy}]`);
|
|
4434
|
+
return {
|
|
4435
|
+
ok: true,
|
|
4436
|
+
exitCode: 0
|
|
4437
|
+
};
|
|
4438
|
+
}
|
|
4439
|
+
if (report.expected !== null) console.error(`${deps.name}: Version alignment failed [strategy=${report.strategy}, expected=${report.expected}]`);
|
|
4440
|
+
else console.error(`${deps.name}: Version alignment failed [strategy=${report.strategy}]`);
|
|
4441
|
+
for (const msg of formatErrors(report)) console.error(`${deps.name}: ${msg}`);
|
|
4442
|
+
return {
|
|
4443
|
+
ok: false,
|
|
4444
|
+
message: "Version alignment check failed",
|
|
4445
|
+
exitCode: VERSION_ALIGNMENT_EXIT
|
|
4446
|
+
};
|
|
4447
|
+
}
|
|
4208
4448
|
async function runPackCli(deps, options) {
|
|
4209
4449
|
const parsed = parsePackArgs(options.args ?? []);
|
|
4210
4450
|
if (parsed.help) {
|
|
@@ -4220,6 +4460,16 @@ async function runPackCli(deps, options) {
|
|
|
4220
4460
|
}
|
|
4221
4461
|
const cwd = options.cwd;
|
|
4222
4462
|
try {
|
|
4463
|
+
if (parsed.checkVersions && !parsed.archive && parsed.marketplace === void 0) {
|
|
4464
|
+
if (parsed.checkRelease) {
|
|
4465
|
+
const gate = await deps.checkReleaseTag({
|
|
4466
|
+
cwd,
|
|
4467
|
+
tag: parsed.tag
|
|
4468
|
+
});
|
|
4469
|
+
for (const w of gate.warnings ?? []) console.error(`${deps.name}: warning: ${w}`);
|
|
4470
|
+
}
|
|
4471
|
+
return runCheckVersionsGate(deps, cwd);
|
|
4472
|
+
}
|
|
4223
4473
|
if (parsed.checkRelease && !parsed.archive && parsed.marketplace === void 0) {
|
|
4224
4474
|
const gate = await deps.checkReleaseTag({
|
|
4225
4475
|
cwd,
|
|
@@ -4228,7 +4478,11 @@ async function runPackCli(deps, options) {
|
|
|
4228
4478
|
for (const w of gate.warnings ?? []) console.error(`${deps.name}: warning: ${w}`);
|
|
4229
4479
|
return { ok: true };
|
|
4230
4480
|
}
|
|
4231
|
-
if (!parsed.archive && !parsed.checkRelease) parsed.archive = true;
|
|
4481
|
+
if (!parsed.archive && !parsed.checkRelease && !parsed.checkVersions) parsed.archive = true;
|
|
4482
|
+
if (parsed.checkVersions) {
|
|
4483
|
+
const versionGate = runCheckVersionsGate(deps, cwd);
|
|
4484
|
+
if (!versionGate.ok) return versionGate;
|
|
4485
|
+
}
|
|
4232
4486
|
const result = await deps.runPack({
|
|
4233
4487
|
cwd,
|
|
4234
4488
|
agentPlugins: parsed.agentPlugins,
|
|
@@ -4425,7 +4679,21 @@ const pack = createPack({
|
|
|
4425
4679
|
marketplaceOutputs
|
|
4426
4680
|
});
|
|
4427
4681
|
},
|
|
4428
|
-
checkReleaseTag: (options) => checkReleaseTag(options)
|
|
4682
|
+
checkReleaseTag: (options) => checkReleaseTag(options),
|
|
4683
|
+
checkVersionAlignment: (options) => checkVersionAlignment({
|
|
4684
|
+
config: options.config,
|
|
4685
|
+
cwd: options.cwd,
|
|
4686
|
+
projectRoot: options.projectRoot,
|
|
4687
|
+
root: options.root
|
|
4688
|
+
}),
|
|
4689
|
+
loadMarketplaceAuthoringConfig: (options) => loadMarketplaceAuthoringConfig(options),
|
|
4690
|
+
detectAuthoringConfigSource: (options) => detectAuthoringConfigSource(options),
|
|
4691
|
+
versionAlignmentErrorMessages: (report) => versionAlignmentErrorMessages({
|
|
4692
|
+
strategy: "lockstep",
|
|
4693
|
+
expected: null,
|
|
4694
|
+
ok: false,
|
|
4695
|
+
packages: report.packages
|
|
4696
|
+
})
|
|
4429
4697
|
});
|
|
4430
4698
|
//#endregion
|
|
4431
4699
|
//#region src/modules/Plugin/services/runPlugin.ts
|
|
@@ -4457,7 +4725,7 @@ Usage:
|
|
|
4457
4725
|
|
|
4458
4726
|
Options:
|
|
4459
4727
|
-y, --yes Non-interactive defaults (version 0.1.0); allow overwrite
|
|
4460
|
-
--target <id>
|
|
4728
|
+
--target <id> Write target: <id> (limits deployment to that agent; not with --agent-plugins)
|
|
4461
4729
|
--agent-plugins Create an Agent Plugins v1 portable root (no bapm.yml)
|
|
4462
4730
|
--skills Include a minimal portable skills/example/SKILL.md layout
|
|
4463
4731
|
-v, --verbose Extra logging (optional)
|
|
@@ -5480,7 +5748,7 @@ function parseUpdateArgs(argv) {
|
|
|
5480
5748
|
};
|
|
5481
5749
|
}
|
|
5482
5750
|
function formatUpdateHelp(deps) {
|
|
5483
|
-
return `${deps.name} update — Re-resolve dependency pins
|
|
5751
|
+
return `${deps.name} update — Re-resolve dependency pins
|
|
5484
5752
|
|
|
5485
5753
|
Usage:
|
|
5486
5754
|
bapm update [packages...] [options]
|
package/package.json
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@b-apm/cli",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "bapm CLI — Better Agent Package Manager",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"b-apm",
|
|
7
|
+
"bapm",
|
|
8
|
+
"unstable"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/Sdju/bapm#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/Sdju/bapm/issues"
|
|
13
|
+
},
|
|
5
14
|
"license": "MIT",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/Sdju/bapm.git",
|
|
18
|
+
"directory": "packages/cli"
|
|
19
|
+
},
|
|
6
20
|
"bin": {
|
|
7
21
|
"bapm": "./dist/cli.mjs"
|
|
8
22
|
},
|
|
@@ -19,8 +33,8 @@
|
|
|
19
33
|
"access": "public"
|
|
20
34
|
},
|
|
21
35
|
"dependencies": {
|
|
22
|
-
"@b-apm/integration-api": "0.1
|
|
23
|
-
"@b-apm/core": "0.1
|
|
36
|
+
"@b-apm/integration-api": "0.2.1",
|
|
37
|
+
"@b-apm/core": "0.2.1"
|
|
24
38
|
},
|
|
25
39
|
"devDependencies": {
|
|
26
40
|
"@types/node": "^26.1.2",
|
|
@@ -28,7 +42,10 @@
|
|
|
28
42
|
"typescript": "^7.0.2",
|
|
29
43
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
30
44
|
"vite-plus": "latest",
|
|
31
|
-
"@b-apm/integration-cursor": "0.1
|
|
45
|
+
"@b-apm/integration-cursor": "0.2.1"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=22.12.0"
|
|
32
49
|
},
|
|
33
50
|
"feod": {
|
|
34
51
|
"srcRoot": "src",
|
|
@@ -54,23 +71,6 @@
|
|
|
54
71
|
"privateModulesPrefix": null
|
|
55
72
|
}
|
|
56
73
|
},
|
|
57
|
-
"engines": {
|
|
58
|
-
"node": ">=22.12.0"
|
|
59
|
-
},
|
|
60
|
-
"repository": {
|
|
61
|
-
"type": "git",
|
|
62
|
-
"url": "git+https://github.com/Sdju/bapm.git",
|
|
63
|
-
"directory": "packages/cli"
|
|
64
|
-
},
|
|
65
|
-
"homepage": "https://github.com/Sdju/bapm#readme",
|
|
66
|
-
"bugs": {
|
|
67
|
-
"url": "https://github.com/Sdju/bapm/issues"
|
|
68
|
-
},
|
|
69
|
-
"keywords": [
|
|
70
|
-
"unstable",
|
|
71
|
-
"bapm",
|
|
72
|
-
"b-apm"
|
|
73
|
-
],
|
|
74
74
|
"scripts": {
|
|
75
75
|
"build": "vp pack",
|
|
76
76
|
"dev": "vp pack --watch",
|