agentwheel 0.20.19 → 0.20.20
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 +5 -0
- package/dist/{apply-QJHTL7IK.js → apply-Z5GVCPA4.js} +2 -2
- package/dist/{chunk-L37KQVRS.js → chunk-45WVSUJA.js} +1 -1
- package/dist/{chunk-BHT57MK5.js → chunk-FGFPAZ4J.js} +208 -3
- package/dist/index.js +69 -208
- package/dist/{transaction-JHZJWBII.js → transaction-NLAIJ2ZZ.js} +1 -1
- package/openpack.json +1 -1
- package/package.json +1 -1
- package/skills/agentwheel/SKILL.md +30 -1
- package/skills/agentwheel-discovery/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -644,6 +644,11 @@ project's curated selection for a remote runtime.
|
|
|
644
644
|
}
|
|
645
645
|
```
|
|
646
646
|
|
|
647
|
+
Configured packages can opt into adapter runtimes with `"runtimes": ["claude"]`. Profile and
|
|
648
|
+
named-agent plans match the declared target adapter; plain workspace commands match each package's
|
|
649
|
+
configured adapter. Agents sharing an adapter receive the same package roots. Upgrade every member
|
|
650
|
+
to a version supporting this field before using it in shared configuration.
|
|
651
|
+
|
|
647
652
|
The import is data-only: Agentwheel resolves the package first, then reads only
|
|
648
653
|
`exports.selections` from that resolved source's `.agentwheel/config.json`. It never imports the
|
|
649
654
|
source project's agents, profiles, SSH fields, adapter modules, trust policy, or other workspace
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
commitManifestMetadataJournal,
|
|
6
6
|
recoverPendingApply,
|
|
7
7
|
uninstall
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-45WVSUJA.js";
|
|
9
|
+
import "./chunk-FGFPAZ4J.js";
|
|
10
10
|
import "./chunk-BNIF3FUR.js";
|
|
11
11
|
export {
|
|
12
12
|
applyCombinedInstallPlan,
|
|
@@ -1525,6 +1525,188 @@ function readMutationPathDeclarations(operationIdInput) {
|
|
|
1525
1525
|
return [...paths].sort((a, b) => a.localeCompare(b));
|
|
1526
1526
|
}
|
|
1527
1527
|
|
|
1528
|
+
// src/adapters/claude.ts
|
|
1529
|
+
var claudeAdapter = {
|
|
1530
|
+
name: "claude",
|
|
1531
|
+
displayName: "Claude Code",
|
|
1532
|
+
targets: {
|
|
1533
|
+
instructions: {
|
|
1534
|
+
local: { enabled: true, dest: "CLAUDE.md", mode: "managed-block" },
|
|
1535
|
+
user: { enabled: true, root: "home", dest: ".claude/CLAUDE.md", mode: "managed-block" }
|
|
1536
|
+
},
|
|
1537
|
+
rules: {
|
|
1538
|
+
local: { enabled: true, dest: ".claude/rules", formats: ["markdown-rule", "claude-markdown-rule"] },
|
|
1539
|
+
user: { enabled: true, root: "home", dest: ".claude/rules", formats: ["markdown-rule", "claude-markdown-rule"] }
|
|
1540
|
+
},
|
|
1541
|
+
skills: {
|
|
1542
|
+
local: { enabled: true, dest: ".claude/skills" },
|
|
1543
|
+
user: { enabled: true, root: "home", dest: ".claude/skills" }
|
|
1544
|
+
},
|
|
1545
|
+
commands: {
|
|
1546
|
+
local: { enabled: true, dest: ".claude/commands" },
|
|
1547
|
+
user: { enabled: true, root: "home", dest: ".claude/commands" }
|
|
1548
|
+
},
|
|
1549
|
+
subagents: {
|
|
1550
|
+
local: { enabled: true, dest: ".claude/agents" },
|
|
1551
|
+
user: { enabled: true, root: "home", dest: ".claude/agents" }
|
|
1552
|
+
},
|
|
1553
|
+
plugins: {
|
|
1554
|
+
local: { enabled: true, dest: ".agentwheel/plugins/claude", semantic: "claude-plugin" },
|
|
1555
|
+
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/claude", semantic: "claude-plugin" }
|
|
1556
|
+
},
|
|
1557
|
+
mcp: {
|
|
1558
|
+
local: { enabled: true, dest: ".mcp.json", merge: "json-deep" }
|
|
1559
|
+
},
|
|
1560
|
+
hooks: {
|
|
1561
|
+
local: { enabled: true, dest: ".claude/settings.json", merge: "json-deep" },
|
|
1562
|
+
user: { enabled: true, root: "home", dest: ".claude/settings.json", merge: "json-deep" }
|
|
1563
|
+
},
|
|
1564
|
+
settings: {
|
|
1565
|
+
local: { enabled: true, dest: ".claude/settings.json", merge: "json-deep" },
|
|
1566
|
+
user: { enabled: true, root: "home", dest: ".claude/settings.json", merge: "json-deep" }
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1571
|
+
// src/adapters/copilot.ts
|
|
1572
|
+
var copilotAdapter = {
|
|
1573
|
+
name: "copilot",
|
|
1574
|
+
displayName: "GitHub Copilot CLI",
|
|
1575
|
+
targets: {
|
|
1576
|
+
instructions: {
|
|
1577
|
+
local: { enabled: true, dest: ".github/copilot-instructions.md", mode: "managed-block" },
|
|
1578
|
+
user: { enabled: true, root: "home", dest: ".copilot/copilot-instructions.md", mode: "managed-block" }
|
|
1579
|
+
},
|
|
1580
|
+
rules: {
|
|
1581
|
+
local: { enabled: true, dest: ".github/instructions", formats: ["markdown-rule", "copilot-instruction-rule"], semantic: "copilot-instruction" },
|
|
1582
|
+
user: { enabled: true, root: "home", dest: ".copilot/instructions", formats: ["markdown-rule", "copilot-instruction-rule"], semantic: "copilot-instruction" }
|
|
1583
|
+
},
|
|
1584
|
+
commands: {
|
|
1585
|
+
local: { enabled: true, dest: ".github/prompts", semantic: "copilot-prompt" }
|
|
1586
|
+
},
|
|
1587
|
+
skills: {
|
|
1588
|
+
local: { enabled: true, dest: ".github/skills" },
|
|
1589
|
+
user: { enabled: true, root: "home", dest: ".copilot/skills" }
|
|
1590
|
+
},
|
|
1591
|
+
plugins: {
|
|
1592
|
+
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/copilot", semantic: "copilot-plugin" }
|
|
1593
|
+
},
|
|
1594
|
+
subagents: {
|
|
1595
|
+
local: { enabled: true, dest: ".github/agents", semantic: "copilot-agent" },
|
|
1596
|
+
user: { enabled: true, root: "home", dest: ".copilot/agents", semantic: "copilot-agent" }
|
|
1597
|
+
},
|
|
1598
|
+
mcp: {
|
|
1599
|
+
local: { enabled: true, dest: ".github/mcp.json", merge: "json-deep" },
|
|
1600
|
+
user: { enabled: true, root: "home", dest: ".copilot/mcp-config.json", merge: "json-deep" }
|
|
1601
|
+
},
|
|
1602
|
+
hooks: {
|
|
1603
|
+
local: { enabled: true, dest: ".github/hooks" },
|
|
1604
|
+
user: { enabled: true, root: "home", dest: ".copilot/hooks" }
|
|
1605
|
+
},
|
|
1606
|
+
settings: {
|
|
1607
|
+
local: { enabled: true, dest: ".github/settings.json", merge: "json-deep" },
|
|
1608
|
+
user: { enabled: true, root: "home", dest: ".copilot/settings.json", merge: "json-deep" }
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
};
|
|
1612
|
+
|
|
1613
|
+
// src/adapters/codex.ts
|
|
1614
|
+
var codexAdapter = {
|
|
1615
|
+
name: "codex",
|
|
1616
|
+
displayName: "Codex CLI",
|
|
1617
|
+
targets: {
|
|
1618
|
+
instructions: {
|
|
1619
|
+
local: { enabled: true, dest: "AGENTS.md", mode: "managed-block" },
|
|
1620
|
+
user: { enabled: true, root: "home", dest: ".codex/AGENTS.md", mode: "managed-block" }
|
|
1621
|
+
},
|
|
1622
|
+
skills: {
|
|
1623
|
+
local: { enabled: true, dest: ".agents/skills" },
|
|
1624
|
+
user: { enabled: true, root: "home", dest: ".agents/skills" }
|
|
1625
|
+
},
|
|
1626
|
+
plugins: {
|
|
1627
|
+
local: { enabled: true, dest: ".agentwheel/plugins/codex", semantic: "codex-plugin" },
|
|
1628
|
+
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/codex", semantic: "codex-plugin" }
|
|
1629
|
+
},
|
|
1630
|
+
subagents: {
|
|
1631
|
+
local: { enabled: true, dest: ".codex/agents", semantic: "codex-subagent" },
|
|
1632
|
+
user: { enabled: true, root: "home", dest: ".codex/agents", semantic: "codex-subagent" }
|
|
1633
|
+
},
|
|
1634
|
+
mcp: {
|
|
1635
|
+
local: { enabled: true, dest: ".codex/config.toml", merge: "codex-toml-mcp" },
|
|
1636
|
+
user: { enabled: true, root: "home", dest: ".codex/config.toml", merge: "codex-toml-mcp" }
|
|
1637
|
+
},
|
|
1638
|
+
hooks: {
|
|
1639
|
+
local: { enabled: true, dest: ".codex/hooks.json", merge: "json-deep" },
|
|
1640
|
+
user: { enabled: true, root: "home", dest: ".codex/hooks.json", merge: "json-deep" }
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
};
|
|
1644
|
+
|
|
1645
|
+
// src/adapters/hermes.ts
|
|
1646
|
+
var hermesAdapter = {
|
|
1647
|
+
name: "hermes",
|
|
1648
|
+
displayName: "Hermes",
|
|
1649
|
+
targets: {
|
|
1650
|
+
instructions: {
|
|
1651
|
+
local: { enabled: true, dest: "AGENTS.md", mode: "managed-block" },
|
|
1652
|
+
// Hermes documents SOUL.md as the user-level instruction surface.
|
|
1653
|
+
user: { enabled: true, root: "home", dest: ".hermes/SOUL.md", mode: "managed-block" }
|
|
1654
|
+
},
|
|
1655
|
+
skills: {
|
|
1656
|
+
user: { enabled: true, root: "home", dest: ".hermes/skills" }
|
|
1657
|
+
},
|
|
1658
|
+
mcp: {
|
|
1659
|
+
user: { enabled: true, root: "home", dest: ".hermes/config.yaml", merge: "yaml-deep" }
|
|
1660
|
+
},
|
|
1661
|
+
settings: {
|
|
1662
|
+
user: { enabled: true, root: "home", dest: ".hermes/config.yaml", merge: "yaml-deep" }
|
|
1663
|
+
},
|
|
1664
|
+
plugins: {
|
|
1665
|
+
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/hermes", semantic: "hermes-plugin" }
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
};
|
|
1669
|
+
|
|
1670
|
+
// src/adapters/openclaw.ts
|
|
1671
|
+
var openClawAdapter = {
|
|
1672
|
+
name: "openclaw",
|
|
1673
|
+
displayName: "OpenClaw",
|
|
1674
|
+
targets: {
|
|
1675
|
+
instructions: {
|
|
1676
|
+
user: { enabled: true, root: "home", dest: ".openclaw/workspace/AGENTS.md", mode: "managed-block" }
|
|
1677
|
+
},
|
|
1678
|
+
skills: {
|
|
1679
|
+
local: { enabled: true, dest: "skills" },
|
|
1680
|
+
user: { enabled: true, root: "home", dest: ".openclaw/skills" }
|
|
1681
|
+
},
|
|
1682
|
+
subagents: {
|
|
1683
|
+
user: { enabled: true, root: "home", dest: ".openclaw/workspace-subagents", semantic: "openclaw-subagent" }
|
|
1684
|
+
},
|
|
1685
|
+
mcp: {
|
|
1686
|
+
user: { enabled: true, root: "home", dest: ".openclaw/openclaw.json", merge: "openclaw-json-deep" }
|
|
1687
|
+
},
|
|
1688
|
+
settings: {
|
|
1689
|
+
user: { enabled: true, root: "home", dest: ".openclaw/openclaw.json", merge: "openclaw-json-deep" }
|
|
1690
|
+
},
|
|
1691
|
+
plugins: {
|
|
1692
|
+
local: { enabled: true, dest: ".openclaw/plugins", formats: ["openclaw-plugin", "openclaw-clawhub-plugin"], semantic: "openclaw-plugin" }
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
};
|
|
1696
|
+
|
|
1697
|
+
// src/adapters/index.ts
|
|
1698
|
+
var adapters = [openClawAdapter, claudeAdapter, codexAdapter, hermesAdapter, copilotAdapter];
|
|
1699
|
+
function getAdapter(name) {
|
|
1700
|
+
const adapter = adapters.find((candidate) => candidate.name === name);
|
|
1701
|
+
if (!adapter) {
|
|
1702
|
+
throw new Error(`Unknown adapter: ${name}`);
|
|
1703
|
+
}
|
|
1704
|
+
return adapter;
|
|
1705
|
+
}
|
|
1706
|
+
function listAdapters() {
|
|
1707
|
+
return [...adapters];
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1528
1710
|
// src/model/workspace.ts
|
|
1529
1711
|
var artifactSelectorListSchema = z7.array(z7.string().min(1));
|
|
1530
1712
|
var CURRENT_WORKSPACE_SCHEMA_VERSION = 4;
|
|
@@ -1562,6 +1744,9 @@ var workspacePackageBaseSchema = z7.object({
|
|
|
1562
1744
|
source: z7.string().min(1),
|
|
1563
1745
|
driver: z7.enum(["local", "git", "skillkit", "vercel-skills", "mcp-registry", "clawhub"]).default("local"),
|
|
1564
1746
|
adapter: z7.string().min(1).default("openclaw"),
|
|
1747
|
+
runtimes: z7.array(z7.string().min(1)).min(1).refine((runtimes) => new Set(runtimes).size === runtimes.length, {
|
|
1748
|
+
message: "Package runtimes must be unique."
|
|
1749
|
+
}).transform((runtimes) => [...runtimes].sort()).optional(),
|
|
1565
1750
|
adapterConfig: z7.string().min(1).optional(),
|
|
1566
1751
|
adapterModule: z7.string().min(1).optional(),
|
|
1567
1752
|
adapterCodeHash: z7.string().min(16).optional(),
|
|
@@ -1726,7 +1911,25 @@ var workspaceConfigSchema = z7.discriminatedUnion("schemaVersion", [
|
|
|
1726
1911
|
workspaceConfigV2Schema,
|
|
1727
1912
|
workspaceConfigV3Schema,
|
|
1728
1913
|
workspaceConfigV4Schema
|
|
1729
|
-
])
|
|
1914
|
+
]).superRefine((config, ctx) => {
|
|
1915
|
+
const known = /* @__PURE__ */ new Set([
|
|
1916
|
+
...listAdapters().map((adapter) => adapter.name),
|
|
1917
|
+
...Object.values(config.agents).map((agent) => agent.adapter),
|
|
1918
|
+
...Object.values(config.profiles).flatMap((profile) => "runtimes" in profile && profile.runtimes ? profile.runtimes.map((runtime) => runtime.agent ? config.agents[runtime.agent]?.adapter ?? runtime.adapter : runtime.adapter) : [])
|
|
1919
|
+
]);
|
|
1920
|
+
for (const [index, pkg] of config.packages.entries()) {
|
|
1921
|
+
for (const [runtimeIndex, runtime] of (pkg.runtimes ?? []).entries()) {
|
|
1922
|
+
if (!known.has(runtime)) ctx.addIssue({
|
|
1923
|
+
code: "custom",
|
|
1924
|
+
path: ["packages", index, "runtimes", runtimeIndex],
|
|
1925
|
+
message: `Unknown package runtime adapter '${runtime}'. Use a built-in adapter or an adapter declared by an agent/profile runtime.`
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
});
|
|
1930
|
+
function packagesForTarget(packages, target, targetForPackage) {
|
|
1931
|
+
return packages.filter((pkg) => !pkg.runtimes || pkg.runtimes.includes((targetForPackage?.(pkg) ?? target).adapter));
|
|
1932
|
+
}
|
|
1730
1933
|
function supportsFleetConfig(config) {
|
|
1731
1934
|
return config.schemaVersion === 3 || config.schemaVersion === 4;
|
|
1732
1935
|
}
|
|
@@ -2865,8 +3068,8 @@ async function recoverMutationRuntime(operationId, options = {}) {
|
|
|
2865
3068
|
}
|
|
2866
3069
|
mutation = GovernedMutation.activateExisting(receipt, baseline, lock);
|
|
2867
3070
|
const [{ recoverPendingApply }, { readLinkedLocalApplyJournal: readLinkedLocalApplyJournal2, removeApplyJournal: removeApplyJournal2, localPathExists: localPathExists2 }] = await Promise.all([
|
|
2868
|
-
import("./apply-
|
|
2869
|
-
import("./transaction-
|
|
3071
|
+
import("./apply-Z5GVCPA4.js"),
|
|
3072
|
+
import("./transaction-NLAIJ2ZZ.js")
|
|
2870
3073
|
]);
|
|
2871
3074
|
let missingReservation = false;
|
|
2872
3075
|
for (const entry of pending) {
|
|
@@ -3361,6 +3564,7 @@ export {
|
|
|
3361
3564
|
installRootForArtifacts,
|
|
3362
3565
|
installRootForAdapterInstallationType,
|
|
3363
3566
|
loadAdapterConfig,
|
|
3567
|
+
getAdapter,
|
|
3364
3568
|
readMutationReceipt,
|
|
3365
3569
|
listMutationReceipts,
|
|
3366
3570
|
declareMutationPath,
|
|
@@ -3380,6 +3584,7 @@ export {
|
|
|
3380
3584
|
fleetIdSchema,
|
|
3381
3585
|
registeredFleetSchema,
|
|
3382
3586
|
workspaceConfigSchema,
|
|
3587
|
+
packagesForTarget,
|
|
3383
3588
|
supportsFleetConfig,
|
|
3384
3589
|
workspaceConfigPath,
|
|
3385
3590
|
readWorkspaceConfig,
|
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
uninstall,
|
|
38
38
|
withManifestRevision,
|
|
39
39
|
writeInstallManifest
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-45WVSUJA.js";
|
|
41
41
|
import {
|
|
42
42
|
CURRENT_WORKSPACE_SCHEMA_VERSION,
|
|
43
43
|
GovernedMutation,
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
findExistingWorkspaceRoot,
|
|
57
57
|
findWorkspaceRoot,
|
|
58
58
|
fleetIdSchema,
|
|
59
|
+
getAdapter,
|
|
59
60
|
globalWorkspaceConfigPath,
|
|
60
61
|
installManifestPath,
|
|
61
62
|
installRootForAdapterInstallationType,
|
|
@@ -74,6 +75,7 @@ import {
|
|
|
74
75
|
packageItemRequireSchema,
|
|
75
76
|
packageItemSuggestSchema,
|
|
76
77
|
packageSupersedesEntrySchema,
|
|
78
|
+
packagesForTarget,
|
|
77
79
|
parseSemver,
|
|
78
80
|
readApplyJournal,
|
|
79
81
|
readMergedWorkspaceConfig,
|
|
@@ -98,7 +100,7 @@ import {
|
|
|
98
100
|
workspaceSelectionImportSchema,
|
|
99
101
|
writeApplyJournal,
|
|
100
102
|
writeWorkspaceConfig
|
|
101
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-FGFPAZ4J.js";
|
|
102
104
|
import {
|
|
103
105
|
inferSourceDriverName
|
|
104
106
|
} from "./chunk-QABA4WUP.js";
|
|
@@ -125,185 +127,6 @@ import { Command } from "commander";
|
|
|
125
127
|
// src/adapters/resolve.ts
|
|
126
128
|
import { resolve as resolve2 } from "path";
|
|
127
129
|
|
|
128
|
-
// src/adapters/claude.ts
|
|
129
|
-
var claudeAdapter = {
|
|
130
|
-
name: "claude",
|
|
131
|
-
displayName: "Claude Code",
|
|
132
|
-
targets: {
|
|
133
|
-
instructions: {
|
|
134
|
-
local: { enabled: true, dest: "CLAUDE.md", mode: "managed-block" },
|
|
135
|
-
user: { enabled: true, root: "home", dest: ".claude/CLAUDE.md", mode: "managed-block" }
|
|
136
|
-
},
|
|
137
|
-
rules: {
|
|
138
|
-
local: { enabled: true, dest: ".claude/rules", formats: ["markdown-rule", "claude-markdown-rule"] },
|
|
139
|
-
user: { enabled: true, root: "home", dest: ".claude/rules", formats: ["markdown-rule", "claude-markdown-rule"] }
|
|
140
|
-
},
|
|
141
|
-
skills: {
|
|
142
|
-
local: { enabled: true, dest: ".claude/skills" },
|
|
143
|
-
user: { enabled: true, root: "home", dest: ".claude/skills" }
|
|
144
|
-
},
|
|
145
|
-
commands: {
|
|
146
|
-
local: { enabled: true, dest: ".claude/commands" },
|
|
147
|
-
user: { enabled: true, root: "home", dest: ".claude/commands" }
|
|
148
|
-
},
|
|
149
|
-
subagents: {
|
|
150
|
-
local: { enabled: true, dest: ".claude/agents" },
|
|
151
|
-
user: { enabled: true, root: "home", dest: ".claude/agents" }
|
|
152
|
-
},
|
|
153
|
-
plugins: {
|
|
154
|
-
local: { enabled: true, dest: ".agentwheel/plugins/claude", semantic: "claude-plugin" },
|
|
155
|
-
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/claude", semantic: "claude-plugin" }
|
|
156
|
-
},
|
|
157
|
-
mcp: {
|
|
158
|
-
local: { enabled: true, dest: ".mcp.json", merge: "json-deep" }
|
|
159
|
-
},
|
|
160
|
-
hooks: {
|
|
161
|
-
local: { enabled: true, dest: ".claude/settings.json", merge: "json-deep" },
|
|
162
|
-
user: { enabled: true, root: "home", dest: ".claude/settings.json", merge: "json-deep" }
|
|
163
|
-
},
|
|
164
|
-
settings: {
|
|
165
|
-
local: { enabled: true, dest: ".claude/settings.json", merge: "json-deep" },
|
|
166
|
-
user: { enabled: true, root: "home", dest: ".claude/settings.json", merge: "json-deep" }
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// src/adapters/copilot.ts
|
|
172
|
-
var copilotAdapter = {
|
|
173
|
-
name: "copilot",
|
|
174
|
-
displayName: "GitHub Copilot CLI",
|
|
175
|
-
targets: {
|
|
176
|
-
instructions: {
|
|
177
|
-
local: { enabled: true, dest: ".github/copilot-instructions.md", mode: "managed-block" },
|
|
178
|
-
user: { enabled: true, root: "home", dest: ".copilot/copilot-instructions.md", mode: "managed-block" }
|
|
179
|
-
},
|
|
180
|
-
rules: {
|
|
181
|
-
local: { enabled: true, dest: ".github/instructions", formats: ["markdown-rule", "copilot-instruction-rule"], semantic: "copilot-instruction" },
|
|
182
|
-
user: { enabled: true, root: "home", dest: ".copilot/instructions", formats: ["markdown-rule", "copilot-instruction-rule"], semantic: "copilot-instruction" }
|
|
183
|
-
},
|
|
184
|
-
commands: {
|
|
185
|
-
local: { enabled: true, dest: ".github/prompts", semantic: "copilot-prompt" }
|
|
186
|
-
},
|
|
187
|
-
skills: {
|
|
188
|
-
local: { enabled: true, dest: ".github/skills" },
|
|
189
|
-
user: { enabled: true, root: "home", dest: ".copilot/skills" }
|
|
190
|
-
},
|
|
191
|
-
plugins: {
|
|
192
|
-
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/copilot", semantic: "copilot-plugin" }
|
|
193
|
-
},
|
|
194
|
-
subagents: {
|
|
195
|
-
local: { enabled: true, dest: ".github/agents", semantic: "copilot-agent" },
|
|
196
|
-
user: { enabled: true, root: "home", dest: ".copilot/agents", semantic: "copilot-agent" }
|
|
197
|
-
},
|
|
198
|
-
mcp: {
|
|
199
|
-
local: { enabled: true, dest: ".github/mcp.json", merge: "json-deep" },
|
|
200
|
-
user: { enabled: true, root: "home", dest: ".copilot/mcp-config.json", merge: "json-deep" }
|
|
201
|
-
},
|
|
202
|
-
hooks: {
|
|
203
|
-
local: { enabled: true, dest: ".github/hooks" },
|
|
204
|
-
user: { enabled: true, root: "home", dest: ".copilot/hooks" }
|
|
205
|
-
},
|
|
206
|
-
settings: {
|
|
207
|
-
local: { enabled: true, dest: ".github/settings.json", merge: "json-deep" },
|
|
208
|
-
user: { enabled: true, root: "home", dest: ".copilot/settings.json", merge: "json-deep" }
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
// src/adapters/codex.ts
|
|
214
|
-
var codexAdapter = {
|
|
215
|
-
name: "codex",
|
|
216
|
-
displayName: "Codex CLI",
|
|
217
|
-
targets: {
|
|
218
|
-
instructions: {
|
|
219
|
-
local: { enabled: true, dest: "AGENTS.md", mode: "managed-block" },
|
|
220
|
-
user: { enabled: true, root: "home", dest: ".codex/AGENTS.md", mode: "managed-block" }
|
|
221
|
-
},
|
|
222
|
-
skills: {
|
|
223
|
-
local: { enabled: true, dest: ".agents/skills" },
|
|
224
|
-
user: { enabled: true, root: "home", dest: ".agents/skills" }
|
|
225
|
-
},
|
|
226
|
-
plugins: {
|
|
227
|
-
local: { enabled: true, dest: ".agentwheel/plugins/codex", semantic: "codex-plugin" },
|
|
228
|
-
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/codex", semantic: "codex-plugin" }
|
|
229
|
-
},
|
|
230
|
-
subagents: {
|
|
231
|
-
local: { enabled: true, dest: ".codex/agents", semantic: "codex-subagent" },
|
|
232
|
-
user: { enabled: true, root: "home", dest: ".codex/agents", semantic: "codex-subagent" }
|
|
233
|
-
},
|
|
234
|
-
mcp: {
|
|
235
|
-
local: { enabled: true, dest: ".codex/config.toml", merge: "codex-toml-mcp" },
|
|
236
|
-
user: { enabled: true, root: "home", dest: ".codex/config.toml", merge: "codex-toml-mcp" }
|
|
237
|
-
},
|
|
238
|
-
hooks: {
|
|
239
|
-
local: { enabled: true, dest: ".codex/hooks.json", merge: "json-deep" },
|
|
240
|
-
user: { enabled: true, root: "home", dest: ".codex/hooks.json", merge: "json-deep" }
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
// src/adapters/hermes.ts
|
|
246
|
-
var hermesAdapter = {
|
|
247
|
-
name: "hermes",
|
|
248
|
-
displayName: "Hermes",
|
|
249
|
-
targets: {
|
|
250
|
-
instructions: {
|
|
251
|
-
local: { enabled: true, dest: "AGENTS.md", mode: "managed-block" },
|
|
252
|
-
// Hermes documents SOUL.md as the user-level instruction surface.
|
|
253
|
-
user: { enabled: true, root: "home", dest: ".hermes/SOUL.md", mode: "managed-block" }
|
|
254
|
-
},
|
|
255
|
-
skills: {
|
|
256
|
-
user: { enabled: true, root: "home", dest: ".hermes/skills" }
|
|
257
|
-
},
|
|
258
|
-
mcp: {
|
|
259
|
-
user: { enabled: true, root: "home", dest: ".hermes/config.yaml", merge: "yaml-deep" }
|
|
260
|
-
},
|
|
261
|
-
settings: {
|
|
262
|
-
user: { enabled: true, root: "home", dest: ".hermes/config.yaml", merge: "yaml-deep" }
|
|
263
|
-
},
|
|
264
|
-
plugins: {
|
|
265
|
-
user: { enabled: true, root: "home", dest: ".agentwheel/plugins/hermes", semantic: "hermes-plugin" }
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
// src/adapters/openclaw.ts
|
|
271
|
-
var openClawAdapter = {
|
|
272
|
-
name: "openclaw",
|
|
273
|
-
displayName: "OpenClaw",
|
|
274
|
-
targets: {
|
|
275
|
-
instructions: {
|
|
276
|
-
user: { enabled: true, root: "home", dest: ".openclaw/workspace/AGENTS.md", mode: "managed-block" }
|
|
277
|
-
},
|
|
278
|
-
skills: {
|
|
279
|
-
local: { enabled: true, dest: "skills" },
|
|
280
|
-
user: { enabled: true, root: "home", dest: ".openclaw/skills" }
|
|
281
|
-
},
|
|
282
|
-
subagents: {
|
|
283
|
-
user: { enabled: true, root: "home", dest: ".openclaw/workspace-subagents", semantic: "openclaw-subagent" }
|
|
284
|
-
},
|
|
285
|
-
mcp: {
|
|
286
|
-
user: { enabled: true, root: "home", dest: ".openclaw/openclaw.json", merge: "openclaw-json-deep" }
|
|
287
|
-
},
|
|
288
|
-
settings: {
|
|
289
|
-
user: { enabled: true, root: "home", dest: ".openclaw/openclaw.json", merge: "openclaw-json-deep" }
|
|
290
|
-
},
|
|
291
|
-
plugins: {
|
|
292
|
-
local: { enabled: true, dest: ".openclaw/plugins", formats: ["openclaw-plugin", "openclaw-clawhub-plugin"], semantic: "openclaw-plugin" }
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// src/adapters/index.ts
|
|
298
|
-
var adapters = [openClawAdapter, claudeAdapter, codexAdapter, hermesAdapter, copilotAdapter];
|
|
299
|
-
function getAdapter(name) {
|
|
300
|
-
const adapter = adapters.find((candidate) => candidate.name === name);
|
|
301
|
-
if (!adapter) {
|
|
302
|
-
throw new Error(`Unknown adapter: ${name}`);
|
|
303
|
-
}
|
|
304
|
-
return adapter;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
130
|
// src/adapters/programmatic.ts
|
|
308
131
|
import { stat, readFile, writeFile } from "fs/promises";
|
|
309
132
|
import { tmpdir } from "os";
|
|
@@ -6030,7 +5853,7 @@ var SnapshotConflictError = class extends Error {
|
|
|
6030
5853
|
};
|
|
6031
5854
|
var cacheLocks = /* @__PURE__ */ new Map();
|
|
6032
5855
|
async function resolveDependencyGraph(roots, options) {
|
|
6033
|
-
if (roots.length === 0) throw new Error("At least one graph root is required.");
|
|
5856
|
+
if (roots.length === 0 && !options.allowEmptyRoots) throw new Error("At least one graph root is required.");
|
|
6034
5857
|
const fetchCache = /* @__PURE__ */ new Map();
|
|
6035
5858
|
const nodesByKey = /* @__PURE__ */ new Map();
|
|
6036
5859
|
const nodesBySource = /* @__PURE__ */ new Map();
|
|
@@ -8197,7 +8020,7 @@ function targetEndpoint(value, transportKind) {
|
|
|
8197
8020
|
|
|
8198
8021
|
// src/lifecycle/source-plan.ts
|
|
8199
8022
|
async function createGraphSourcePlan(options) {
|
|
8200
|
-
if (options.roots.length === 0) {
|
|
8023
|
+
if (options.roots.length === 0 && !options.allowEmptyRoots) {
|
|
8201
8024
|
throw new Error("At least one source is required for a graph plan.");
|
|
8202
8025
|
}
|
|
8203
8026
|
if (options.freshGraphOnly && options.readOnly !== true) {
|
|
@@ -8313,7 +8136,8 @@ async function createGraphSourcePlan(options) {
|
|
|
8313
8136
|
offline: options.offline,
|
|
8314
8137
|
previousLock,
|
|
8315
8138
|
warn,
|
|
8316
|
-
runtime: options.adapter.name
|
|
8139
|
+
runtime: options.adapter.name,
|
|
8140
|
+
allowEmptyRoots: options.allowEmptyRoots
|
|
8317
8141
|
});
|
|
8318
8142
|
assertFrozenGraph(previousLock, graph, lockMode, lockLabel);
|
|
8319
8143
|
assertTrustArtifactPolicy(graph, trustPolicy);
|
|
@@ -8372,6 +8196,16 @@ async function createGraphSourcePlan(options) {
|
|
|
8372
8196
|
warn
|
|
8373
8197
|
});
|
|
8374
8198
|
const plan = priorState.migration && !basePlan.stateMigration ? { ...basePlan, stateMigration: priorState.migration } : basePlan;
|
|
8199
|
+
if (options.excludedRootIds?.length && previousLock) {
|
|
8200
|
+
const excludedRoots = new Set(options.excludedRootIds);
|
|
8201
|
+
const excludedNodeIds = new Set(previousLock.canonical.roots.filter((root) => excludedRoots.has(root.rootId)).map((root) => root.graphNodeId));
|
|
8202
|
+
for (const operation of plan.operations) {
|
|
8203
|
+
const excludedOwner = operation.owners?.length && operation.owners.every((owner) => excludedRoots.has(owner));
|
|
8204
|
+
if (operation.action === "remove" && (excludedOwner || operation.graphNodeId && excludedNodeIds.has(operation.graphNodeId))) {
|
|
8205
|
+
operation.reason = "excluded by package runtimes";
|
|
8206
|
+
}
|
|
8207
|
+
}
|
|
8208
|
+
}
|
|
8375
8209
|
plan.targetStateFilePreconditions = {
|
|
8376
8210
|
graphLockPath,
|
|
8377
8211
|
graphLockRevision: stableLock ? digestGraphLock(stableLock) : null,
|
|
@@ -9256,8 +9090,17 @@ async function syncProfile(options) {
|
|
|
9256
9090
|
if (selected && packages.some((pkg) => pkg.selection)) {
|
|
9257
9091
|
throw new Error("--select/--skill cannot be combined with a package selection import.");
|
|
9258
9092
|
}
|
|
9093
|
+
if (!options.source) {
|
|
9094
|
+
const adapters = new Set(profile.runtimes.map((runtime) => resolveProfileRuntimeTarget(runtime, config, options.workspaceRoot, options.installationType, options.fleetId).adapter));
|
|
9095
|
+
for (const pkg of packages) {
|
|
9096
|
+
if (pkg.runtimes && !pkg.runtimes.some((runtime) => adapters.has(runtime))) {
|
|
9097
|
+
options.warn?.(`Package '${pkg.name}' matches no runtime in profile '${options.profile}'.`);
|
|
9098
|
+
}
|
|
9099
|
+
}
|
|
9100
|
+
}
|
|
9259
9101
|
for (const runtime of profile.runtimes) {
|
|
9260
9102
|
const target = resolveProfileRuntimeTarget(runtime, config, options.workspaceRoot, options.installationType, options.fleetId);
|
|
9103
|
+
const runtimePackages = options.source ? packages : packagesForTarget(packages, target);
|
|
9261
9104
|
const transport = transportForTarget(target);
|
|
9262
9105
|
const adapter = await resolveAdapter({
|
|
9263
9106
|
adapter: target.adapter,
|
|
@@ -9270,7 +9113,7 @@ async function syncProfile(options) {
|
|
|
9270
9113
|
const installationType = target.installationType ?? defaultInstallationType;
|
|
9271
9114
|
resolveInstallationTypeForAdapter(adapter, installationType);
|
|
9272
9115
|
const graphPlan = await createGraphSourcePlan({
|
|
9273
|
-
roots:
|
|
9116
|
+
roots: runtimePackages.map((pkg) => ({
|
|
9274
9117
|
rootId: pkg.name,
|
|
9275
9118
|
source: pkg.source,
|
|
9276
9119
|
mode: options.mode ?? pkg.mode,
|
|
@@ -9319,14 +9162,16 @@ async function syncProfile(options) {
|
|
|
9319
9162
|
forceConflict: options.forceConflict,
|
|
9320
9163
|
forceForeignState: options.forceForeignState,
|
|
9321
9164
|
replaceConflict: options.replaceConflict,
|
|
9322
|
-
recoverLegacyState: options.recoverLegacyState
|
|
9165
|
+
recoverLegacyState: options.recoverLegacyState,
|
|
9166
|
+
allowEmptyRoots: runtimePackages.length === 0,
|
|
9167
|
+
excludedRootIds: options.source ? [] : packages.filter((pkg) => !runtimePackages.includes(pkg)).map((pkg) => pkg.name)
|
|
9323
9168
|
});
|
|
9324
9169
|
try {
|
|
9325
9170
|
const result = {
|
|
9326
9171
|
runtime: adapter.name,
|
|
9327
9172
|
targetRoot: installRootForAdapterInstallationType(adapter, target.targetRoot, installationType, transport.kind === "ssh"),
|
|
9328
9173
|
transport: transport.kind,
|
|
9329
|
-
packageName:
|
|
9174
|
+
packageName: runtimePackages.map((pkg) => pkg.name).join(",") || "(no packages)",
|
|
9330
9175
|
plan: graphPlan.plan,
|
|
9331
9176
|
graphPlan,
|
|
9332
9177
|
graphLockDigest: graphPlan.graphLockDigest,
|
|
@@ -12468,7 +12313,7 @@ async function planFleetNormalization(request) {
|
|
|
12468
12313
|
const destinationDeclaration = canonicalJson2(destinationPackage);
|
|
12469
12314
|
if (sourceDeclaration !== destinationDeclaration) {
|
|
12470
12315
|
throw new Error(
|
|
12471
|
-
`Package '${name}' has divergent declarations. Source, driver, adapter, adapter configuration, installation type, version policy, selections, aliases, overrides, and suggestions must match before normalization.`
|
|
12316
|
+
`Package '${name}' has divergent declarations. Source, driver, adapter, adapter configuration, installation type, version policy, runtime restrictions, selections, aliases, overrides, and suggestions must match before normalization.`
|
|
12472
12317
|
);
|
|
12473
12318
|
}
|
|
12474
12319
|
packages.push({ name, declarationDigest: sha2565(sourceDeclaration) });
|
|
@@ -14504,8 +14349,9 @@ ownershipCommand.command("recovery-plan").description("write a read-only per-pat
|
|
|
14504
14349
|
}
|
|
14505
14350
|
const installationType = target.installationType ?? resolveInstallationTypeForAdapter(adapter, void 0);
|
|
14506
14351
|
const config = await readMergedWorkspaceConfig(target.workspaceRoot);
|
|
14507
|
-
|
|
14508
|
-
|
|
14352
|
+
const targetPackages = packagesForCliTarget(config.packages, target, {});
|
|
14353
|
+
if (targetPackages.length === 0) throw new Error("Fleet target has no configured source packages.");
|
|
14354
|
+
await withFreshReadOnlyGraphPlan(target, adapter, adapterOptionsForTarget(target, {}), installationType, targetPackages, async (graphPlan) => {
|
|
14509
14355
|
const installRoot = installRootForAdapterInstallationType(adapter, target.targetRoot, installationType, transport.kind === "ssh");
|
|
14510
14356
|
const report = await planLegacyRecovery({
|
|
14511
14357
|
graphPlan,
|
|
@@ -14632,7 +14478,7 @@ ownershipCommand.command("adopt-legacy").description("move proven legacy-keyed o
|
|
|
14632
14478
|
if (target.transport === "ssh") throw new Error("Legacy ownership adoption does not support SSH targets.");
|
|
14633
14479
|
const config = await readMergedWorkspaceConfig(target.workspaceRoot);
|
|
14634
14480
|
const groups = /* @__PURE__ */ new Map();
|
|
14635
|
-
for (const pkg of config.packages) graphGroupForPackage(groups, target, pkg, plainInstallOptions).packages.push(pkg);
|
|
14481
|
+
for (const pkg of packagesForCliTarget(config.packages, target, plainInstallOptions)) graphGroupForPackage(groups, target, pkg, plainInstallOptions).packages.push(pkg);
|
|
14636
14482
|
if (groups.size === 0) throw new Error(`No configured source packages in ${target.workspaceRoot}.`);
|
|
14637
14483
|
const installationTypes = [...new Set([...groups.values()].map((candidate) => candidate.installationType))];
|
|
14638
14484
|
if (installationTypes.length > 1) {
|
|
@@ -14974,7 +14820,7 @@ async function runInstallCommand(nameOrSource, options, behavior) {
|
|
|
14974
14820
|
for (const target of targets) {
|
|
14975
14821
|
const targetOptions = optionsForResolvedTarget(normalizedOptions, target);
|
|
14976
14822
|
const config = await readMergedWorkspaceConfig(target.workspaceRoot);
|
|
14977
|
-
const configured = nameOrSource ? findConfiguredPackageForTarget(config.packages, nameOrSource, targetOptions, target) : void 0;
|
|
14823
|
+
const configured = nameOrSource ? findConfiguredPackageForTarget(packagesForCliTarget(config.packages, target, targetOptions), nameOrSource, targetOptions, target) : void 0;
|
|
14978
14824
|
let source;
|
|
14979
14825
|
let scope = configured?.name;
|
|
14980
14826
|
let extraPackage;
|
|
@@ -15065,11 +14911,11 @@ async function buildPlanReport(nameOrSource, options) {
|
|
|
15065
14911
|
yes: normalizedOptions.yes,
|
|
15066
14912
|
trustPatterns: normalizedOptions.trust ?? [],
|
|
15067
14913
|
readOnly: true,
|
|
15068
|
-
isTTY: false
|
|
14914
|
+
isTTY: false,
|
|
14915
|
+
warn: collectWarning
|
|
15069
14916
|
});
|
|
15070
14917
|
for (const result of results) {
|
|
15071
14918
|
reportTargets.push(installPlanReportTarget(result.plan, result.graphLockDigest));
|
|
15072
|
-
reportWarnings.push(...result.warnings);
|
|
15073
14919
|
}
|
|
15074
14920
|
return planReport(reportTargets, reportWarnings);
|
|
15075
14921
|
}
|
|
@@ -15077,7 +14923,7 @@ async function buildPlanReport(nameOrSource, options) {
|
|
|
15077
14923
|
for (const target of targets) {
|
|
15078
14924
|
const targetOptions = optionsForResolvedTarget(normalizedOptions, target);
|
|
15079
14925
|
const config = await readMergedWorkspaceConfig(target.workspaceRoot);
|
|
15080
|
-
const configured = nameOrSource ? findConfiguredPackageForTarget(config.packages, nameOrSource, targetOptions, target) : void 0;
|
|
14926
|
+
const configured = nameOrSource ? findConfiguredPackageForTarget(packagesForCliTarget(config.packages, target, targetOptions), nameOrSource, targetOptions, target) : void 0;
|
|
15081
14927
|
let source;
|
|
15082
14928
|
let scope = configured?.name;
|
|
15083
14929
|
let extraPackage;
|
|
@@ -15307,13 +15153,13 @@ async function resolveCliTargets(options, behavior = {}) {
|
|
|
15307
15153
|
if (normalizedOptions.profile && (normalizedOptions.all || normalizedOptions.allDetected || normalizedOptions.agent)) {
|
|
15308
15154
|
throw new Error("--profile cannot be combined with --all, --all-detected, or --agent.");
|
|
15309
15155
|
}
|
|
15310
|
-
const
|
|
15311
|
-
if (
|
|
15156
|
+
const adapters = adapterListFromOption(normalizedOptions.adapter);
|
|
15157
|
+
if (adapters.length > 1) {
|
|
15312
15158
|
if (normalizedOptions.all || normalizedOptions.allDetected || normalizedOptions.agent || normalizedOptions.profile) {
|
|
15313
15159
|
throw new Error("--adapter <a,b> cannot be combined with --all, --all-detected, --agent, or --profile. Use a profile for mixed configured targets.");
|
|
15314
15160
|
}
|
|
15315
15161
|
const targets = [];
|
|
15316
|
-
for (const adapter of
|
|
15162
|
+
for (const adapter of adapters) {
|
|
15317
15163
|
targets.push(await resolveRuntimeTarget({
|
|
15318
15164
|
cwd: scopeRoot,
|
|
15319
15165
|
targetRoot: normalizedOptions.targetRoot,
|
|
@@ -15459,7 +15305,7 @@ async function runSkillUpdateCommand(skillName, options) {
|
|
|
15459
15305
|
const targets = await resolveCliTargets(normalizedOptions, { preferAllProfile: true });
|
|
15460
15306
|
for (const target of targets) {
|
|
15461
15307
|
const config = await readMergedWorkspaceConfig(target.workspaceRoot);
|
|
15462
|
-
const owner = await configuredPackageForSkill(target, config.packages, skillName, normalizedOptions, options.package);
|
|
15308
|
+
const owner = await configuredPackageForSkill(target, packagesForCliTarget(config.packages, target, normalizedOptions), skillName, normalizedOptions, options.package);
|
|
15463
15309
|
const mode = owner.mode === "tracking" ? "update" : "install";
|
|
15464
15310
|
console.log(`Skill ${skillName}: ${owner.name} (${mode}).`);
|
|
15465
15311
|
await runConfiguredGraphPackages(target, {
|
|
@@ -15512,22 +15358,28 @@ async function buildGraphPlansForTarget(target, source, options, behavior) {
|
|
|
15512
15358
|
async function collectGraphPlansForTarget(target, source, options, behavior, bundleRoots) {
|
|
15513
15359
|
const targetOptions = optionsForResolvedTarget(options, target);
|
|
15514
15360
|
const config = await readMergedWorkspaceConfig(target.workspaceRoot);
|
|
15361
|
+
const targetPackages = packagesForCliTarget(config.packages, target, targetOptions);
|
|
15515
15362
|
const groups = /* @__PURE__ */ new Map();
|
|
15516
15363
|
const selectedArtifacts = selectedArtifactsFromOptions(targetOptions);
|
|
15517
15364
|
const dependencyUpdateSelectors = sortedUniqueValues(targetOptions.dependency ?? []);
|
|
15518
15365
|
const scopedDependencyUpdate = behavior.mode === "update" && dependencyUpdateSelectors.length > 0;
|
|
15519
|
-
const scopedPackage = targetOptions.scope ? findConfiguredPackage(
|
|
15366
|
+
const scopedPackage = targetOptions.scope ? findConfiguredPackage(targetPackages, targetOptions.scope) : void 0;
|
|
15520
15367
|
const scopedRootId = scopedPackage?.name ?? (source ? targetOptions.scope : void 0);
|
|
15521
15368
|
if (targetOptions.scope && !scopedPackage && !source) throw new Error(`Configured package not found: ${targetOptions.scope}`);
|
|
15522
15369
|
if (scopedPackage && targetOptions.onlySource) {
|
|
15523
15370
|
const group = graphGroupForPackage(groups, target, scopedPackage, targetOptions);
|
|
15524
15371
|
group.packages.push(scopedPackage);
|
|
15525
15372
|
} else if (!source || !targetOptions.onlySource) {
|
|
15526
|
-
for (const pkg of
|
|
15373
|
+
for (const pkg of targetPackages) {
|
|
15527
15374
|
const group = graphGroupForPackage(groups, target, pkg, targetOptions);
|
|
15528
15375
|
group.packages.push(pkg);
|
|
15529
15376
|
}
|
|
15530
15377
|
}
|
|
15378
|
+
if (!source && !targetOptions.scope) {
|
|
15379
|
+
for (const pkg of config.packages.filter((candidate) => !targetPackages.includes(candidate))) {
|
|
15380
|
+
graphGroupForPackage(groups, target, pkg, targetOptions);
|
|
15381
|
+
}
|
|
15382
|
+
}
|
|
15531
15383
|
if (source) {
|
|
15532
15384
|
let entry = targetOptions.extraPackage ?? await packageEntryFromSource(source, target.workspaceRoot, {
|
|
15533
15385
|
...targetOptions,
|
|
@@ -15567,6 +15419,11 @@ async function collectGraphPlansForTarget(target, source, options, behavior, bun
|
|
|
15567
15419
|
const adapter = await resolveAdapterForTarget(group.target, { ...group.adapterOptions, warn: targetOptions.warn });
|
|
15568
15420
|
const transport = transportForTarget(group.target);
|
|
15569
15421
|
const allPackages = [...group.packages, ...group.extraPackages];
|
|
15422
|
+
const excludedRootIds = config.packages.filter((pkg) => !targetPackages.includes(pkg) && graphGroupKey(targetForPackage(target, pkg, targetOptions), {
|
|
15423
|
+
installationType: targetOptions.installationType ?? pkg.installationType ?? target.installationType ?? "local",
|
|
15424
|
+
adapterConfig: targetOptions.adapterConfig ?? target.adapterConfig ?? pkg.adapterConfig,
|
|
15425
|
+
adapterModule: targetOptions.adapterModule ?? target.adapterModule ?? pkg.adapterModule
|
|
15426
|
+
}) === graphGroupKey(group.target, { ...group.adapterOptions, installationType: group.installationType })).map((pkg) => pkg.name);
|
|
15570
15427
|
const groupHasScope = !scopedRootId || allPackages.some((pkg) => pkg.name === scopedRootId || pkg.source === targetOptions.scope);
|
|
15571
15428
|
if (behavior.mode === "install" && scopedRootId && !groupHasScope) continue;
|
|
15572
15429
|
if (behavior.readOnly !== true && targetOptions.dryRun !== true) {
|
|
@@ -15665,15 +15522,16 @@ async function collectGraphPlansForTarget(target, source, options, behavior, bun
|
|
|
15665
15522
|
];
|
|
15666
15523
|
if (behavior.mode === "update") {
|
|
15667
15524
|
const changed = roots.filter((root) => root.useLock === false);
|
|
15668
|
-
if (changed.length === 0 && !scopedDependencyUpdate) {
|
|
15525
|
+
if (changed.length === 0 && !scopedDependencyUpdate && excludedRootIds.length === 0) {
|
|
15669
15526
|
const label = targetOptions.scope ? ` ${targetOptions.scope}` : "";
|
|
15670
15527
|
console.log(`No tracking packages to update${label}.`);
|
|
15671
15528
|
continue;
|
|
15672
15529
|
}
|
|
15673
15530
|
}
|
|
15674
|
-
if (roots.length === 0) continue;
|
|
15675
15531
|
const result = await createGraphSourcePlan({
|
|
15676
15532
|
roots,
|
|
15533
|
+
allowEmptyRoots: roots.length === 0,
|
|
15534
|
+
excludedRootIds,
|
|
15677
15535
|
targetRoot: group.target.targetRoot,
|
|
15678
15536
|
workspaceRoot: group.target.workspaceRoot,
|
|
15679
15537
|
fleetId: group.target.fleetId,
|
|
@@ -16307,7 +16165,7 @@ async function uninstallConfiguredPackage(target, packageName, options) {
|
|
|
16307
16165
|
if (removed.length === 0) {
|
|
16308
16166
|
throw new Error(`Configured package not found: ${packageName}`);
|
|
16309
16167
|
}
|
|
16310
|
-
const remaining = config.packages.filter((pkg) => !removed.includes(pkg));
|
|
16168
|
+
const remaining = packagesForCliTarget(config.packages.filter((pkg) => !removed.includes(pkg)), target, options);
|
|
16311
16169
|
const groups = /* @__PURE__ */ new Map();
|
|
16312
16170
|
for (const pkg of remaining) {
|
|
16313
16171
|
const group = graphGroupForPackage(groups, target, pkg, options);
|
|
@@ -16443,6 +16301,9 @@ function targetForPackage(target, pkg, options) {
|
|
|
16443
16301
|
const installationType = options.installationType ?? pkg.installationType ?? target.installationType;
|
|
16444
16302
|
return options.adapter || target.source !== "cwd" ? { ...target, installationType } : { ...target, adapter: pkg.adapter, installationType };
|
|
16445
16303
|
}
|
|
16304
|
+
function packagesForCliTarget(packages, target, options) {
|
|
16305
|
+
return packagesForTarget(packages, target, (pkg) => targetForPackage(target, pkg, options));
|
|
16306
|
+
}
|
|
16446
16307
|
function graphGroupKey(target, options) {
|
|
16447
16308
|
return JSON.stringify({
|
|
16448
16309
|
adapter: target.adapter,
|
|
@@ -16619,7 +16480,7 @@ async function collectTargetStatus(target, options) {
|
|
|
16619
16480
|
observation.manifestRevision
|
|
16620
16481
|
]).sort())).digest("hex") : null;
|
|
16621
16482
|
const packages = [];
|
|
16622
|
-
for (const pkg of config.packages) {
|
|
16483
|
+
for (const pkg of packagesForCliTarget(config.packages, target, options)) {
|
|
16623
16484
|
const root = effectiveGraphLock?.canonical.roots.find((candidate) => candidate.rootId === pkg.name);
|
|
16624
16485
|
const node = root ? effectiveGraphLock?.canonical.nodes.find((candidate) => candidate.id === root.graphNodeId) : void 0;
|
|
16625
16486
|
const availability = await discoverPackageVersions(pkg, target.workspaceRoot, {
|
|
@@ -17357,9 +17218,9 @@ function isHomePath(path) {
|
|
|
17357
17218
|
}
|
|
17358
17219
|
function adapterListFromOption(adapter) {
|
|
17359
17220
|
if (!adapter) return [];
|
|
17360
|
-
const
|
|
17361
|
-
const unique = [...new Set(
|
|
17362
|
-
if (unique.length !==
|
|
17221
|
+
const adapters = splitSelectorList(adapter);
|
|
17222
|
+
const unique = [...new Set(adapters)];
|
|
17223
|
+
if (unique.length !== adapters.length) {
|
|
17363
17224
|
throw new Error(`Duplicate adapter in --adapter: ${adapter}`);
|
|
17364
17225
|
}
|
|
17365
17226
|
return unique;
|
package/openpack.json
CHANGED
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ allowed-tools: [Bash]
|
|
|
5
5
|
license: MIT
|
|
6
6
|
metadata:
|
|
7
7
|
author: NestDevLab
|
|
8
|
-
version: "0.20.
|
|
8
|
+
version: "0.20.20"
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# agentwheel
|
|
@@ -357,6 +357,12 @@ Current config shape:
|
|
|
357
357
|
|
|
358
358
|
Use named targets:
|
|
359
359
|
|
|
360
|
+
Configured packages may declare `"runtimes": ["claude"]` to select adapter runtimes. All
|
|
361
|
+
configured-package plans honor it, including `--agent`, `--profile`, status, and update. Named
|
|
362
|
+
targets match their declared adapter; plain workspace commands match each package's adapter.
|
|
363
|
+
Agents sharing an adapter cannot be selected separately. Upgrade all members to a version
|
|
364
|
+
supporting this field before adding it to shared configuration.
|
|
365
|
+
|
|
360
366
|
```bash
|
|
361
367
|
agentwheel fleet register example-fleet --root /srv/agentwheel/fleets/example-fleet --required-package core-agent-pack
|
|
362
368
|
agentwheel fleet list
|
|
@@ -475,6 +481,9 @@ Drift means a managed runtime output changed outside agentwheel. Fix drift by ch
|
|
|
475
481
|
colliding upstream artifact.
|
|
476
482
|
- Eject an item into `.agentwheel/ejected` when the user wants local ownership.
|
|
477
483
|
|
|
484
|
+
When the plan instead keeps a file as foreign or refuses because another workspace owns it, that is
|
|
485
|
+
an ownership problem, not drift: see "Choosing an ownership command" under Troubleshooting.
|
|
486
|
+
|
|
478
487
|
Append durable local instruction text:
|
|
479
488
|
|
|
480
489
|
```bash
|
|
@@ -646,3 +655,23 @@ before Fleet qualification, owns paths under a fingerprint-only legacy key, run
|
|
|
646
655
|
--from-workspace-root <previous-owner-root> --json` from that workspace. It moves only proven,
|
|
647
656
|
still-desired entries into the stable state; add `--carry-drift` only after reviewing the drifted
|
|
648
657
|
paths. Apply the emitted command, then require a normal install plan without force flags.
|
|
658
|
+
|
|
659
|
+
### Choosing an ownership command
|
|
660
|
+
|
|
661
|
+
`agentwheel ownership --help` lists the commands; each subcommand's `--help` is the authoritative flag
|
|
662
|
+
reference. All of them dry-run by default and change only manifest metadata.
|
|
663
|
+
|
|
664
|
+
| Situation | Command |
|
|
665
|
+
|---|---|
|
|
666
|
+
| Unclear who owns what | `ownership recovery-plan` (read-only evidence report) |
|
|
667
|
+
| Refused: paths owned under a fingerprint-only legacy key | `ownership adopt-legacy` |
|
|
668
|
+
| `adopt-legacy` says entries are "already owned by the destination owner" (mixed legacy manifest) | Run a normal `install --agent <agent>` first; it migrates the state and keeps the foreign entry. Then hand off that entry. |
|
|
669
|
+
| Plan keeps one file as a `foreign artifact owned by …` in a stable manifest | `ownership handoff <type/name>` with `--from-workspace-root <root>`, or `--from-unknown-owner` for `workspace:unknown`; add `--to-fleet <id>` for a Fleet owner |
|
|
670
|
+
| Stale foreign entry already covered by the Fleet manifest | `ownership retire-stale` |
|
|
671
|
+
|
|
672
|
+
`handoff` refuses a file whose runtime hash differs from the manifest. If the drift is reviewed and
|
|
673
|
+
harmless, add `--carry-drift`; applying then also needs `--expected-runtime-hash` from the dry-run.
|
|
674
|
+
The recorded hash is kept, so the next install reports `DRIFT` for that file. Replacing it needs
|
|
675
|
+
`install --agent <agent> --force-drift`, which also force-refreshes every merge contribution of that
|
|
676
|
+
target (for example hooks): check that each merge destination is byte-identical afterwards. Never
|
|
677
|
+
narrow that install with `--select`: it removes unselected merge contributions.
|