agentwheel 0.21.2 → 0.21.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 +39 -0
- package/dist/index.js +127 -59
- package/openpack.json +1 -1
- package/package.json +1 -1
- package/skills/agentwheel/SKILL.md +1 -1
- package/skills/agentwheel-discovery/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -98,6 +98,7 @@ Fragments are Agentwheel composition inputs, not runtime file-drop targets.
|
|
|
98
98
|
|---|---|
|
|
99
99
|
| `agentwheel search <query>` | Search configured registries and the public enriched/Vercel catalogue; supports stable JSON output for agent reranking. |
|
|
100
100
|
| `agentwheel add <source>` | Validate and save a package entry in `.agentwheel/config.json`; does not touch runtimes. |
|
|
101
|
+
| `agentwheel pin <alias> <commit>` | Change an existing pinned alias's exact commit, preserving its configuration; does not resolve sources or touch runtimes. |
|
|
101
102
|
| `agentwheel plan [name-or-source]` | Preview what `install` would reconcile without writing; supports `--profile <name>` and `--json`. |
|
|
102
103
|
| `agentwheel install` | Reconcile configured packages into the current target or selected fleet. Uses the graph lock as input by default. |
|
|
103
104
|
| `agentwheel install <name-or-source>` | Ensure semantics: configured name/source scopes the install; a new source is added and installed. |
|
|
@@ -583,6 +584,44 @@ agentwheel plan
|
|
|
583
584
|
agentwheel install
|
|
584
585
|
```
|
|
585
586
|
|
|
587
|
+
Use `add --runtimes codex` to restrict a saved package to matching runtime adapters. The option
|
|
588
|
+
accepts comma-separated names and can be repeated. When replacing an existing package alias,
|
|
589
|
+
pass its runtime restrictions and selection again; `add` replaces the saved entry.
|
|
590
|
+
|
|
591
|
+
To change only an existing pinned alias's revision, use its exact configured name and a full
|
|
592
|
+
40-hex commit SHA:
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
agentwheel pin shared-pack 0123456789abcdef0123456789abcdef01234567 --fleet delivery --reason "Pin the reviewed source revision"
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
`pin` preserves the source URL, driver, adapter, runtime restrictions, installation type (including
|
|
599
|
+
its absence), package order and other fields. It accepts the normal workspace selectors
|
|
600
|
+
`--fleet`, `--local`, `--user`, or `--target-root`, and uses the same mutation policy, durable
|
|
601
|
+
receipts and revision provider as other source mutations. Missing or duplicate aliases, tracking
|
|
602
|
+
packages and abbreviated or symbolic revisions are refused. No sources are fetched or rendered;
|
|
603
|
+
use the normal plan/dry-run before installing the new revision.
|
|
604
|
+
|
|
605
|
+
Omitting `--select` preserves the complete existing selection. Supplying repeatable or
|
|
606
|
+
comma-separated `--select type/name` replaces the complete selection, including any legacy
|
|
607
|
+
`skills` or imported `selection` field. An explicit empty selection is refused.
|
|
608
|
+
|
|
609
|
+
For one source mutation with several aliases, use `pin --pins-file reviewed-pins.json --fleet
|
|
610
|
+
delivery --reason "Pin the reviewed source set"`. The JSON file is a nonempty array of objects
|
|
611
|
+
containing only `alias`, `commit` and optional `select`:
|
|
612
|
+
|
|
613
|
+
```json
|
|
614
|
+
[
|
|
615
|
+
{ "alias": "shared-pack", "commit": "0123456789abcdef0123456789abcdef01234567" },
|
|
616
|
+
{ "alias": "companion-pack", "commit": "abcdef0123456789abcdef0123456789abcdef01", "select": ["skills/companion"] }
|
|
617
|
+
]
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
The batch cannot be combined with positional pins or `--select`. Every entry is validated before
|
|
621
|
+
the config write; duplicate aliases and extra fields are refused. An omitted `select` preserves
|
|
622
|
+
that package's selection; an explicit list replaces only that package's complete selection. The
|
|
623
|
+
batch shares one durable receipt and revision-provider transaction.
|
|
624
|
+
|
|
586
625
|
Package authors can mark artifacts as required. Required artifacts are always installed and cannot
|
|
587
626
|
be deselected:
|
|
588
627
|
|
package/dist/index.js
CHANGED
|
@@ -2805,6 +2805,62 @@ var init_semver = __esm({
|
|
|
2805
2805
|
}
|
|
2806
2806
|
});
|
|
2807
2807
|
|
|
2808
|
+
// src/model/selection.ts
|
|
2809
|
+
function artifactSelectorKey(artifact) {
|
|
2810
|
+
return `${artifact.type}/${artifact.name}`;
|
|
2811
|
+
}
|
|
2812
|
+
function artifactSelectorAliases(artifact) {
|
|
2813
|
+
const primary = artifactSelectorKey(artifact);
|
|
2814
|
+
if (artifact.type !== "subagents") return [primary];
|
|
2815
|
+
const baseName = subagentBaseName(artifact.name);
|
|
2816
|
+
if (baseName === artifact.name) return [primary];
|
|
2817
|
+
return [primary, `subagents/${baseName}`];
|
|
2818
|
+
}
|
|
2819
|
+
function normalizeArtifactSelectors(select, legacySkills) {
|
|
2820
|
+
const selected = [
|
|
2821
|
+
...select ?? [],
|
|
2822
|
+
...(legacySkills ?? []).map((name) => `skills/${name}`)
|
|
2823
|
+
].flatMap(splitSelectorList);
|
|
2824
|
+
if (selected.length === 0) return void 0;
|
|
2825
|
+
return [...new Set(selected.map(parseArtifactSelector))];
|
|
2826
|
+
}
|
|
2827
|
+
function filterArtifactsBySelection(artifacts, selectors, legacySkills, options = {}) {
|
|
2828
|
+
const selected = normalizeArtifactSelectors(selectors, legacySkills);
|
|
2829
|
+
if (!selected?.length) return artifacts;
|
|
2830
|
+
const selectedSet = new Set(selected);
|
|
2831
|
+
const available = new Set((options.validationArtifacts ?? artifacts).flatMap(artifactSelectorAliases));
|
|
2832
|
+
const missing = selected.filter((selector) => !available.has(selector));
|
|
2833
|
+
if (missing.length > 0) {
|
|
2834
|
+
throw new Error(`Selected artifact not found in package: ${missing.join(", ")}`);
|
|
2835
|
+
}
|
|
2836
|
+
return artifacts.filter((artifact) => artifact.required || artifactSelectorAliases(artifact).some((selector) => selectedSet.has(selector)));
|
|
2837
|
+
}
|
|
2838
|
+
function splitSelectorList(value) {
|
|
2839
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
2840
|
+
}
|
|
2841
|
+
function parseArtifactSelector(value) {
|
|
2842
|
+
const slash = value.indexOf("/");
|
|
2843
|
+
if (slash <= 0 || slash === value.length - 1) {
|
|
2844
|
+
throw new Error(`Invalid artifact selector: ${value}. Expected <type>/<name>.`);
|
|
2845
|
+
}
|
|
2846
|
+
const type = value.slice(0, slash);
|
|
2847
|
+
const name = value.slice(slash + 1);
|
|
2848
|
+
const parsedType = artifactTypeSchema.safeParse(type);
|
|
2849
|
+
if (!parsedType.success) {
|
|
2850
|
+
throw new Error(`Invalid artifact selector type: ${type}`);
|
|
2851
|
+
}
|
|
2852
|
+
return `${parsedType.data}/${name}`;
|
|
2853
|
+
}
|
|
2854
|
+
function subagentBaseName(name) {
|
|
2855
|
+
return name.replace(/\.agent\.md$/i, "").replace(/\.toml$/i, "").replace(/\.md$/i, "");
|
|
2856
|
+
}
|
|
2857
|
+
var init_selection = __esm({
|
|
2858
|
+
"src/model/selection.ts"() {
|
|
2859
|
+
"use strict";
|
|
2860
|
+
init_artifact();
|
|
2861
|
+
}
|
|
2862
|
+
});
|
|
2863
|
+
|
|
2808
2864
|
// src/model/workspace.ts
|
|
2809
2865
|
import { readFile as readFile10 } from "fs/promises";
|
|
2810
2866
|
import { homedir as homedir4 } from "os";
|
|
@@ -2829,6 +2885,43 @@ async function writeWorkspaceConfig(workspaceRoot, config) {
|
|
|
2829
2885
|
declareMutationPath(path);
|
|
2830
2886
|
await writeJsonAtomic(path, workspaceConfigSchema.parse(config));
|
|
2831
2887
|
}
|
|
2888
|
+
async function pinConfiguredPackages(workspaceRoot, input) {
|
|
2889
|
+
const pins = z10.array(z10.object({
|
|
2890
|
+
alias: z10.string().min(1),
|
|
2891
|
+
commit: z10.string().regex(/^[a-f0-9]{40}$/i, "Pin requires an exact 40-hex commit SHA."),
|
|
2892
|
+
select: z10.array(z10.string().min(1)).min(1).optional()
|
|
2893
|
+
}).strict()).min(1).parse(input).map((pin) => {
|
|
2894
|
+
const select = pin.select === void 0 ? void 0 : normalizeArtifactSelectors(pin.select);
|
|
2895
|
+
if (pin.select !== void 0 && !select?.length) throw new Error("Explicit pin selection must not be empty.");
|
|
2896
|
+
return { ...pin, select };
|
|
2897
|
+
});
|
|
2898
|
+
if (new Set(pins.map((pin) => pin.alias)).size !== pins.length) {
|
|
2899
|
+
throw new Error("Pin requires unique configured aliases.");
|
|
2900
|
+
}
|
|
2901
|
+
const path = workspaceConfigPath(workspaceRoot);
|
|
2902
|
+
const config = JSON.parse(await readFile10(path, "utf8"));
|
|
2903
|
+
workspaceConfigSchema.parse(config);
|
|
2904
|
+
const updates = pins.map(({ alias, commit, select }) => {
|
|
2905
|
+
const matches = (config.packages ?? []).filter((pkg2) => pkg2.name === alias);
|
|
2906
|
+
if (matches.length !== 1) {
|
|
2907
|
+
throw new Error(matches.length === 0 ? `Configured package alias not found: ${alias}` : `Ambiguous configured package alias: ${alias}`);
|
|
2908
|
+
}
|
|
2909
|
+
const pkg = matches[0];
|
|
2910
|
+
if (pkg.mode === "tracking") throw new Error(`Configured package ${alias} is tracking; pin requires pinned mode.`);
|
|
2911
|
+
return { pkg, requestedRef: commit, select };
|
|
2912
|
+
});
|
|
2913
|
+
for (const { pkg, requestedRef, select } of updates) {
|
|
2914
|
+
pkg.requestedRef = requestedRef;
|
|
2915
|
+
if (select !== void 0) {
|
|
2916
|
+
pkg.select = select;
|
|
2917
|
+
delete pkg.skills;
|
|
2918
|
+
delete pkg.selection;
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
workspaceConfigSchema.parse(config);
|
|
2922
|
+
declareMutationPath(path);
|
|
2923
|
+
await writeJsonAtomic(path, config);
|
|
2924
|
+
}
|
|
2832
2925
|
function upsertPackage(config, entry) {
|
|
2833
2926
|
const parsed = workspaceConfigSchema.parse(config);
|
|
2834
2927
|
const packages = parsed.packages.filter((candidate) => candidate.name !== entry.name);
|
|
@@ -2920,6 +3013,7 @@ var init_workspace = __esm({
|
|
|
2920
3013
|
init_mutation();
|
|
2921
3014
|
init_declarations();
|
|
2922
3015
|
init_adapters();
|
|
3016
|
+
init_selection();
|
|
2923
3017
|
artifactSelectorListSchema = z10.array(z10.string().min(1));
|
|
2924
3018
|
CURRENT_WORKSPACE_SCHEMA_VERSION = 4;
|
|
2925
3019
|
workspaceSelectionImportSchema = z10.object({
|
|
@@ -6874,7 +6968,7 @@ var init_identify = __esm({
|
|
|
6874
6968
|
// src/cli/index.ts
|
|
6875
6969
|
import { createHash as createHash28 } from "crypto";
|
|
6876
6970
|
import { existsSync } from "fs";
|
|
6877
|
-
import { mkdir as mkdir27, mkdtemp as mkdtemp6, realpath as realpath4, rm as rm17, writeFile as writeFile24 } from "fs/promises";
|
|
6971
|
+
import { mkdir as mkdir27, mkdtemp as mkdtemp6, readFile as readFile45, realpath as realpath4, rm as rm17, writeFile as writeFile24 } from "fs/promises";
|
|
6878
6972
|
import { homedir as homedir18, tmpdir as tmpdir7 } from "os";
|
|
6879
6973
|
import { basename as basename24, dirname as dirname37, isAbsolute as isAbsolute14, join as join61, relative as relative19, resolve as resolve44 } from "path";
|
|
6880
6974
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -7505,59 +7599,7 @@ init_transport();
|
|
|
7505
7599
|
|
|
7506
7600
|
// src/validation/adapter-targets.ts
|
|
7507
7601
|
init_adapter();
|
|
7508
|
-
|
|
7509
|
-
// src/model/selection.ts
|
|
7510
|
-
init_artifact();
|
|
7511
|
-
function artifactSelectorKey(artifact) {
|
|
7512
|
-
return `${artifact.type}/${artifact.name}`;
|
|
7513
|
-
}
|
|
7514
|
-
function artifactSelectorAliases(artifact) {
|
|
7515
|
-
const primary = artifactSelectorKey(artifact);
|
|
7516
|
-
if (artifact.type !== "subagents") return [primary];
|
|
7517
|
-
const baseName = subagentBaseName(artifact.name);
|
|
7518
|
-
if (baseName === artifact.name) return [primary];
|
|
7519
|
-
return [primary, `subagents/${baseName}`];
|
|
7520
|
-
}
|
|
7521
|
-
function normalizeArtifactSelectors(select, legacySkills) {
|
|
7522
|
-
const selected = [
|
|
7523
|
-
...select ?? [],
|
|
7524
|
-
...(legacySkills ?? []).map((name) => `skills/${name}`)
|
|
7525
|
-
].flatMap(splitSelectorList);
|
|
7526
|
-
if (selected.length === 0) return void 0;
|
|
7527
|
-
return [...new Set(selected.map(parseArtifactSelector))];
|
|
7528
|
-
}
|
|
7529
|
-
function filterArtifactsBySelection(artifacts, selectors, legacySkills, options = {}) {
|
|
7530
|
-
const selected = normalizeArtifactSelectors(selectors, legacySkills);
|
|
7531
|
-
if (!selected?.length) return artifacts;
|
|
7532
|
-
const selectedSet = new Set(selected);
|
|
7533
|
-
const available = new Set((options.validationArtifacts ?? artifacts).flatMap(artifactSelectorAliases));
|
|
7534
|
-
const missing = selected.filter((selector) => !available.has(selector));
|
|
7535
|
-
if (missing.length > 0) {
|
|
7536
|
-
throw new Error(`Selected artifact not found in package: ${missing.join(", ")}`);
|
|
7537
|
-
}
|
|
7538
|
-
return artifacts.filter((artifact) => artifact.required || artifactSelectorAliases(artifact).some((selector) => selectedSet.has(selector)));
|
|
7539
|
-
}
|
|
7540
|
-
function splitSelectorList(value) {
|
|
7541
|
-
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
7542
|
-
}
|
|
7543
|
-
function parseArtifactSelector(value) {
|
|
7544
|
-
const slash = value.indexOf("/");
|
|
7545
|
-
if (slash <= 0 || slash === value.length - 1) {
|
|
7546
|
-
throw new Error(`Invalid artifact selector: ${value}. Expected <type>/<name>.`);
|
|
7547
|
-
}
|
|
7548
|
-
const type = value.slice(0, slash);
|
|
7549
|
-
const name = value.slice(slash + 1);
|
|
7550
|
-
const parsedType = artifactTypeSchema.safeParse(type);
|
|
7551
|
-
if (!parsedType.success) {
|
|
7552
|
-
throw new Error(`Invalid artifact selector type: ${type}`);
|
|
7553
|
-
}
|
|
7554
|
-
return `${parsedType.data}/${name}`;
|
|
7555
|
-
}
|
|
7556
|
-
function subagentBaseName(name) {
|
|
7557
|
-
return name.replace(/\.agent\.md$/i, "").replace(/\.toml$/i, "").replace(/\.md$/i, "");
|
|
7558
|
-
}
|
|
7559
|
-
|
|
7560
|
-
// src/validation/adapter-targets.ts
|
|
7602
|
+
init_selection();
|
|
7561
7603
|
function filterArtifactsByAdapterTargets(artifacts, adapter, installationType, options = {}) {
|
|
7562
7604
|
const skipped = [];
|
|
7563
7605
|
const installable = artifacts.filter((artifact) => {
|
|
@@ -7600,10 +7642,11 @@ function skipWarning(selector, adapter, installationType, artifactType, support)
|
|
|
7600
7642
|
|
|
7601
7643
|
// src/validation/artifacts.ts
|
|
7602
7644
|
init_adapter();
|
|
7645
|
+
init_selection();
|
|
7646
|
+
init_fs();
|
|
7603
7647
|
import { readFile as readFile24 } from "fs/promises";
|
|
7604
7648
|
import { basename as basename7, join as join23 } from "path";
|
|
7605
7649
|
import { parseDocument as parseDocument2 } from "yaml";
|
|
7606
|
-
init_fs();
|
|
7607
7650
|
var behavioralRuleFormats = ["markdown-rule", "claude-markdown-rule", "copilot-instruction-rule"];
|
|
7608
7651
|
var pluginFormats = ["claude-plugin", "codex-plugin", "hermes-plugin", "copilot-plugin", "openclaw-plugin", "openclaw-clawhub-plugin"];
|
|
7609
7652
|
async function filterArtifactsByInstallFormat(artifacts, adapter, installationType, options = {}) {
|
|
@@ -12027,6 +12070,7 @@ function claudeAgentName(artifact) {
|
|
|
12027
12070
|
}
|
|
12028
12071
|
|
|
12029
12072
|
// src/staging/staging.ts
|
|
12073
|
+
init_selection();
|
|
12030
12074
|
async function stageSource(driver, source, options = {}) {
|
|
12031
12075
|
const raw = await stageSourceRaw(driver, source, options);
|
|
12032
12076
|
return removeOnFailure(raw.root, () => renderStagedBundle(raw, options));
|
|
@@ -12232,13 +12276,15 @@ import { readdir as readdir12, readFile as readFile34, stat as stat14 } from "fs
|
|
|
12232
12276
|
import { basename as basename20, extname as extname4, join as join41 } from "path";
|
|
12233
12277
|
init_artifact();
|
|
12234
12278
|
init_fs();
|
|
12279
|
+
init_selection();
|
|
12235
12280
|
|
|
12236
12281
|
// src/model/workspace-composition.ts
|
|
12237
12282
|
init_workspace();
|
|
12283
|
+
init_selection();
|
|
12284
|
+
init_fs();
|
|
12238
12285
|
import { createHash as createHash16 } from "crypto";
|
|
12239
12286
|
import { readFile as readFile32 } from "fs/promises";
|
|
12240
12287
|
import { z as z12 } from "zod";
|
|
12241
|
-
init_fs();
|
|
12242
12288
|
var selectionSourceConfigSchema = z12.object({
|
|
12243
12289
|
schemaVersion: z12.literal(2),
|
|
12244
12290
|
exports: workspaceExportsSchema
|
|
@@ -12397,6 +12443,7 @@ var registryCacheSchema = z13.object({
|
|
|
12397
12443
|
});
|
|
12398
12444
|
|
|
12399
12445
|
// src/registry/client.ts
|
|
12446
|
+
init_selection();
|
|
12400
12447
|
init_workspace();
|
|
12401
12448
|
init_fs();
|
|
12402
12449
|
var DEFAULT_REGISTRY_SOURCE = "github:NestDevLab/agentwheel-registry";
|
|
@@ -13924,6 +13971,7 @@ function formatSelectionImport(root) {
|
|
|
13924
13971
|
}
|
|
13925
13972
|
|
|
13926
13973
|
// src/resolve/render.ts
|
|
13974
|
+
init_selection();
|
|
13927
13975
|
import { createHash as createHash18 } from "crypto";
|
|
13928
13976
|
import { readFile as readFile35, mkdtemp as mkdtemp5 } from "fs/promises";
|
|
13929
13977
|
import { tmpdir as tmpdir6 } from "os";
|
|
@@ -14528,6 +14576,7 @@ function defaultTrustStorePath() {
|
|
|
14528
14576
|
|
|
14529
14577
|
// src/lifecycle/source-plan.ts
|
|
14530
14578
|
init_workspace();
|
|
14579
|
+
init_selection();
|
|
14531
14580
|
|
|
14532
14581
|
// src/model/workspace-owner.ts
|
|
14533
14582
|
import { Buffer as Buffer2 } from "buffer";
|
|
@@ -15998,6 +16047,7 @@ function runtimeScanRoot(request) {
|
|
|
15998
16047
|
// src/lifecycle/profile.ts
|
|
15999
16048
|
init_identify();
|
|
16000
16049
|
init_transport();
|
|
16050
|
+
init_selection();
|
|
16001
16051
|
init_declarations();
|
|
16002
16052
|
async function syncProfile(options) {
|
|
16003
16053
|
const config = await readMergedWorkspaceConfig(options.workspaceRoot);
|
|
@@ -16155,6 +16205,7 @@ function combinedSuggestionAliases(packageAliases, optionAliases) {
|
|
|
16155
16205
|
}
|
|
16156
16206
|
|
|
16157
16207
|
// src/registry/publish.ts
|
|
16208
|
+
init_selection();
|
|
16158
16209
|
var DEFAULT_REGISTRY_SUBMISSION_URL = "https://github.com/NestDevLab/agentwheel-registry/issues/new";
|
|
16159
16210
|
var registryEntryTypes = ["package", "skill", "plugin", "mcp", "adapter"];
|
|
16160
16211
|
var explicitSourcePrefixes = ["github:", "git:", "skillkit:", "vercel:", "mcp-registry:", "clawhub:"];
|
|
@@ -16318,6 +16369,9 @@ function shellQuoteArg(value) {
|
|
|
16318
16369
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
16319
16370
|
}
|
|
16320
16371
|
|
|
16372
|
+
// src/cli/index.ts
|
|
16373
|
+
init_selection();
|
|
16374
|
+
|
|
16321
16375
|
// src/cli/update-check.ts
|
|
16322
16376
|
import { mkdir as mkdir26, readFile as readFile38, writeFile as writeFile22 } from "fs/promises";
|
|
16323
16377
|
import { homedir as homedir14 } from "os";
|
|
@@ -16818,6 +16872,7 @@ init_manifest2();
|
|
|
16818
16872
|
init_apply();
|
|
16819
16873
|
init_paths();
|
|
16820
16874
|
init_transaction();
|
|
16875
|
+
init_selection();
|
|
16821
16876
|
import { createHash as createHash20 } from "crypto";
|
|
16822
16877
|
import { resolve as resolve37 } from "path";
|
|
16823
16878
|
init_declarations();
|
|
@@ -19479,6 +19534,7 @@ function ensureTrailingSlash(value) {
|
|
|
19479
19534
|
}
|
|
19480
19535
|
|
|
19481
19536
|
// src/trial/skill.ts
|
|
19537
|
+
init_selection();
|
|
19482
19538
|
import { createHash as createHash26 } from "crypto";
|
|
19483
19539
|
import { readFile as readFile43, stat as stat16 } from "fs/promises";
|
|
19484
19540
|
import { join as join59 } from "path";
|
|
@@ -21129,6 +21185,7 @@ var commandGovernance = {
|
|
|
21129
21185
|
"fleet normalize": "governed-apply-or-recover",
|
|
21130
21186
|
"cache prune": "governed-apply",
|
|
21131
21187
|
add: "governed-always",
|
|
21188
|
+
pin: "governed-always",
|
|
21132
21189
|
list: "incidental-cache",
|
|
21133
21190
|
search: "incidental-cache",
|
|
21134
21191
|
try: "incidental-cache",
|
|
@@ -21185,6 +21242,7 @@ function requiresCleanMutationPreflight(path) {
|
|
|
21185
21242
|
"init",
|
|
21186
21243
|
"fleet register",
|
|
21187
21244
|
"add",
|
|
21245
|
+
"pin",
|
|
21188
21246
|
"package migrate",
|
|
21189
21247
|
"remember",
|
|
21190
21248
|
"journal abort"
|
|
@@ -21264,13 +21322,22 @@ cacheCommand.command("prune").description("remove old Git source snapshots while
|
|
|
21264
21322
|
for (const path of result.removedPaths) console.log(`${verb} ${path}`);
|
|
21265
21323
|
console.log(`${options.apply ? "Pruned" : "Preview"}: ${result.removedPaths.length} snapshots; retained ${result.retainedPaths.length}.`);
|
|
21266
21324
|
});
|
|
21267
|
-
program.command("add").description("add a package to .agentwheel/config.json without touching runtimes").argument("<source>", "package source").option("--driver <driver>", "source driver (local, git, skillkit, vercel-skills, mcp-registry, or clawhub)").option("--adapter <adapter>", "built-in adapter", "openclaw").option("-i, --installation-type <type>", "installation type (for example local or user)").option("--user", "use the user workspace", false).option("--local", "use the nearest local workspace", false).option("--fleet <id>", "use one registered named fleet").option("--adapter-config <path>", "adapter JSON/JSONC file").option("--adapter-module <path>", "local programmatic adapter module").option("--allow-adapter-code", "allow loading local adapter code", false).option("-t, --target-root <path>", "workspace root").option("--mode <mode>", "pinned or tracking", "pinned").option("--version <range>", "root package version policy (exact, ~, ^, or *)").option("--name <name>", "package alias").option("--select <type/name>", "select an artifact by type/name (repeatable or comma-separated)", collectSelectOption, []).option("--skill <name>", "select a skill by name (repeatable or comma-separated)", collectSkillOption, []).option("--with-suggestions", "include suggested companion artifacts for selected roots on future installs", false).option("--suggestion <alias>", "include one suggested companion alias on future installs (repeatable or comma-separated)", collectSuggestionOption, []).option("--override <source-or-package::type/name>", "allow this package to replace a colliding artifact (repeatable)", collectOverrideOption, []).action(async (source, options) => {
|
|
21325
|
+
program.command("add").description("add a package to .agentwheel/config.json without touching runtimes").argument("<source>", "package source").option("--driver <driver>", "source driver (local, git, skillkit, vercel-skills, mcp-registry, or clawhub)").option("--adapter <adapter>", "built-in adapter", "openclaw").option("--runtimes <adapters>", "restrict package runtimes (repeatable or comma-separated)", collectSelectOption, []).option("-i, --installation-type <type>", "installation type (for example local or user)").option("--user", "use the user workspace", false).option("--local", "use the nearest local workspace", false).option("--fleet <id>", "use one registered named fleet").option("--adapter-config <path>", "adapter JSON/JSONC file").option("--adapter-module <path>", "local programmatic adapter module").option("--allow-adapter-code", "allow loading local adapter code", false).option("-t, --target-root <path>", "workspace root").option("--mode <mode>", "pinned or tracking", "pinned").option("--version <range>", "root package version policy (exact, ~, ^, or *)").option("--name <name>", "package alias").option("--select <type/name>", "select an artifact by type/name (repeatable or comma-separated)", collectSelectOption, []).option("--skill <name>", "select a skill by name (repeatable or comma-separated)", collectSkillOption, []).option("--with-suggestions", "include suggested companion artifacts for selected roots on future installs", false).option("--suggestion <alias>", "include one suggested companion alias on future installs (repeatable or comma-separated)", collectSuggestionOption, []).option("--override <source-or-package::type/name>", "allow this package to replace a colliding artifact (repeatable)", collectOverrideOption, []).action(async (source, options) => {
|
|
21268
21326
|
const normalizedOptions = normalizeRuntimeScopeOptions(options);
|
|
21269
21327
|
const targetRoot = await workspaceRootFromOptions(normalizedOptions);
|
|
21270
21328
|
const entry = await packageEntryFromSource(source, targetRoot, normalizedOptions);
|
|
21271
21329
|
await writeWorkspaceConfig(targetRoot, upsertPackage(await readWorkspaceConfig(targetRoot), entry));
|
|
21272
21330
|
console.log(`Added ${entry.name}. Preview: agentwheel plan - Apply: agentwheel install`);
|
|
21273
21331
|
});
|
|
21332
|
+
program.command("pin").description("pin configured package aliases without resolving sources or touching runtimes").argument("[alias]", "exact configured package alias").argument("[commit]", "exact 40-hex commit SHA").option("--user", "use the user workspace", false).option("--local", "use the nearest local workspace", false).option("--fleet <id>", "use one registered named fleet").option("-t, --target-root <path>", "explicit workspace root").option("--pins-file <path>", "JSON array of {alias, commit, select?} pins in one mutation").option("--select <type/name>", "replace the complete selection (repeatable or comma-separated)", collectSelectOption).action(async (alias, commit, options) => {
|
|
21333
|
+
const workspaceRoot = await workspaceRootFromOptions(normalizeRuntimeScopeOptions(options));
|
|
21334
|
+
if (options.pinsFile ? alias !== void 0 || commit !== void 0 || options.select !== void 0 : !alias || !commit) {
|
|
21335
|
+
throw new Error("Choose pin <alias> <commit> [--select ...] or pin --pins-file <path>, exclusively.");
|
|
21336
|
+
}
|
|
21337
|
+
const pins = options.pinsFile ? JSON.parse(await readFile45(resolve44(options.pinsFile), "utf8")) : [{ alias, commit, ...options.select === void 0 ? {} : { select: options.select } }];
|
|
21338
|
+
await pinConfiguredPackages(workspaceRoot, pins);
|
|
21339
|
+
console.log("Pinned configured package revisions. Preview: agentwheel plan - Apply: agentwheel install");
|
|
21340
|
+
});
|
|
21274
21341
|
program.command("list").description("list artifacts exposed by a package source").argument("<source>", "package source").option("--driver <driver>", "source driver").option("--user", "use the user workspace", false).option("--local", "use the nearest local workspace", false).option("--fleet <id>", "use one registered named fleet").option("-t, --target-root <path>", "explicit workspace root").option("--select <type/name>", "select an artifact by type/name (repeatable or comma-separated)", collectSelectOption, []).option("--skill <name>", "select a skill by name (repeatable or comma-separated)", collectSkillOption, []).action(async (source, options) => {
|
|
21275
21342
|
const targetRoot = await workspaceContextRootFromOptions(normalizeRuntimeScopeOptions(options));
|
|
21276
21343
|
const resolvedInput = await resolvePackageSource(source, targetRoot);
|
|
@@ -22365,6 +22432,7 @@ async function packageEntryFromSource(source, targetRoot, options) {
|
|
|
22365
22432
|
source: resolvedSource,
|
|
22366
22433
|
driver: driverName,
|
|
22367
22434
|
adapter: adapter.name,
|
|
22435
|
+
runtimes: options.runtimes?.length ? options.runtimes : void 0,
|
|
22368
22436
|
installationType,
|
|
22369
22437
|
adapterConfig: options.adapterConfig,
|
|
22370
22438
|
adapterModule: options.adapterModule,
|
|
@@ -24401,7 +24469,7 @@ function shellQuoteArg2(value) {
|
|
|
24401
24469
|
if (/^[A-Za-z0-9_./:@=-]+$/.test(value)) return value;
|
|
24402
24470
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
24403
24471
|
}
|
|
24404
|
-
function collectSelectOption(value, previous) {
|
|
24472
|
+
function collectSelectOption(value, previous = []) {
|
|
24405
24473
|
return [...previous, ...splitSelectorList(value)];
|
|
24406
24474
|
}
|
|
24407
24475
|
function parsePositiveInteger(value) {
|
|
@@ -24808,7 +24876,7 @@ async function governedCommandContext(command, options) {
|
|
|
24808
24876
|
const contextOnly = path === "cache prune";
|
|
24809
24877
|
const workspaceRoot = contextOnly ? await workspaceContextRootFromOptions(normalized) : await workspaceRootFromOptions(normalized);
|
|
24810
24878
|
const anticipatedPaths = [];
|
|
24811
|
-
if (path === "add") anticipatedPaths.push(workspaceConfigPath(workspaceRoot));
|
|
24879
|
+
if (path === "add" || path === "pin") anticipatedPaths.push(workspaceConfigPath(workspaceRoot));
|
|
24812
24880
|
if (path === "remember" && options.runtime) {
|
|
24813
24881
|
anticipatedPaths.push(join61(workspaceRoot, ".agentwheel", "overlays", options.runtime, "instructions.local.md"));
|
|
24814
24882
|
}
|
package/openpack.json
CHANGED
package/package.json
CHANGED