agents-united 0.7.2 → 0.7.4
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.d.ts +23 -1
- package/dist/cli.js +301 -39
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
type AgentHost = 'agents' | 'gemini' | 'claude' | 'cursor' | 'cline' | 'opencode' | 'codex';
|
|
2
|
+
type ProjectionKind = 'role' | 'skill' | 'rule' | 'team-manifest' | 'workflow' | 'bridge' | 'plugin-manifest';
|
|
3
|
+
interface ProjectionInfo {
|
|
4
|
+
host: string;
|
|
5
|
+
path: string;
|
|
6
|
+
kind?: ProjectionKind;
|
|
7
|
+
warnings: string[];
|
|
8
|
+
}
|
|
2
9
|
|
|
3
10
|
declare function detectWorkspaceHosts(cwd?: string): AgentHost[];
|
|
11
|
+
declare function getTerminalContentWidth(): number;
|
|
12
|
+
declare function wrapText(text: string, maxLen?: number, indent?: string): string[];
|
|
13
|
+
declare function formatWrappedList(items: string[], indent?: string, maxLineLen?: number): string[];
|
|
14
|
+
interface InstallationSummaryOptions {
|
|
15
|
+
bundleName: string;
|
|
16
|
+
scope: string;
|
|
17
|
+
method: string;
|
|
18
|
+
hosts: string[];
|
|
19
|
+
agents: string[];
|
|
20
|
+
skills: string[];
|
|
21
|
+
targetDirs: string[];
|
|
22
|
+
projections?: ProjectionInfo[];
|
|
23
|
+
}
|
|
24
|
+
declare function formatInstallationSummary(options: InstallationSummaryOptions): string;
|
|
25
|
+
declare function renderProjections(projections: ProjectionInfo[]): string;
|
|
4
26
|
|
|
5
|
-
export { detectWorkspaceHosts };
|
|
27
|
+
export { type InstallationSummaryOptions, detectWorkspaceHosts, formatInstallationSummary, formatWrappedList, getTerminalContentWidth, renderProjections, wrapText };
|
package/dist/cli.js
CHANGED
|
@@ -1274,7 +1274,18 @@ var InstallEngine = class _InstallEngine {
|
|
|
1274
1274
|
const hasCanonicalAgents = hosts.includes("agents");
|
|
1275
1275
|
const fanoutHosts = (options.fanout || []).map((h) => typeof h === "string" ? h.trim().toLowerCase() : h).filter((h) => isKnownHost(h) && HOST_REGISTRY[h]?.projectionCapable);
|
|
1276
1276
|
if (options.dryRun) {
|
|
1277
|
-
|
|
1277
|
+
let effectiveDryFanout = fanoutHosts;
|
|
1278
|
+
if (options.fanout === void 0 && hasCanonicalAgents) {
|
|
1279
|
+
const agentsTarget2 = AgentHostAdapter.resolveHostDir(scope, "agents", options.targetDir);
|
|
1280
|
+
const lockfilePath = path5.join(agentsTarget2, "agents-united.json");
|
|
1281
|
+
if (await fs3.pathExists(lockfilePath)) {
|
|
1282
|
+
const lockfile = await fs3.readJson(lockfilePath).catch(() => null);
|
|
1283
|
+
if (lockfile?.fanout) {
|
|
1284
|
+
effectiveDryFanout = lockfile.fanout.filter((h) => isKnownHost(h) && HOST_REGISTRY[h]?.projectionCapable);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
const projections2 = hasCanonicalAgents ? await this.buildProjections(effectiveDryFanout, resolved, registryDir, scope, options.targetDir) : [];
|
|
1278
1289
|
return { installed: resolved, targetDirs, dryRun: true, method, projections: projections2 };
|
|
1279
1290
|
}
|
|
1280
1291
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1710,7 +1721,7 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1710
1721
|
constructor(registry2) {
|
|
1711
1722
|
this.registry = registry2 || new RegistryResolver();
|
|
1712
1723
|
}
|
|
1713
|
-
static formatDisplayLocation(scope, host, targetDir) {
|
|
1724
|
+
static formatDisplayLocation(scope, host, targetDir, fanout) {
|
|
1714
1725
|
const home = os2.homedir();
|
|
1715
1726
|
const cwd = process.cwd();
|
|
1716
1727
|
let prettyPath = targetDir;
|
|
@@ -1721,7 +1732,8 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1721
1732
|
const rel = path7.relative(home, targetDir);
|
|
1722
1733
|
prettyPath = `~/${rel.replace(/\\/g, "/")}`;
|
|
1723
1734
|
}
|
|
1724
|
-
|
|
1735
|
+
const fanoutSuffix = fanout && fanout.length > 0 ? ` + ${fanout.join(", ")}` : "";
|
|
1736
|
+
return `[${scope}: ${prettyPath}${fanoutSuffix}]`;
|
|
1725
1737
|
}
|
|
1726
1738
|
parseHosts(options) {
|
|
1727
1739
|
if (options.hosts && options.hosts.length > 0) return options.hosts;
|
|
@@ -1763,6 +1775,26 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1763
1775
|
const bundleRecords = [];
|
|
1764
1776
|
const standaloneRecords = [];
|
|
1765
1777
|
const scannedTargetDirs = /* @__PURE__ */ new Set();
|
|
1778
|
+
const scannedLocationsMap = /* @__PURE__ */ new Map();
|
|
1779
|
+
const home = os2.homedir();
|
|
1780
|
+
for (const scope of scopes) {
|
|
1781
|
+
const canonicalDir = AgentHostAdapter.resolveHostDir(scope, "agents", options.targetDir);
|
|
1782
|
+
let displayLoc = canonicalDir;
|
|
1783
|
+
if (canonicalDir.startsWith(cwd)) {
|
|
1784
|
+
const rel = path7.relative(cwd, canonicalDir);
|
|
1785
|
+
displayLoc = rel ? `./${rel.replace(/\\/g, "/")}` : ".";
|
|
1786
|
+
} else if (canonicalDir.startsWith(home)) {
|
|
1787
|
+
const rel = path7.relative(home, canonicalDir);
|
|
1788
|
+
displayLoc = `~/${rel.replace(/\\/g, "/")}`;
|
|
1789
|
+
}
|
|
1790
|
+
scannedLocationsMap.set(`${scope}:${canonicalDir}`, {
|
|
1791
|
+
scope,
|
|
1792
|
+
targetDir: canonicalDir,
|
|
1793
|
+
displayLocation: displayLoc,
|
|
1794
|
+
packageCount: 0,
|
|
1795
|
+
fanout: []
|
|
1796
|
+
});
|
|
1797
|
+
}
|
|
1766
1798
|
for (const item of candidateDirs) {
|
|
1767
1799
|
const lockfilePath = path7.join(item.dir, "agents-united.json");
|
|
1768
1800
|
if (!await fs5.pathExists(lockfilePath)) {
|
|
@@ -1775,7 +1807,22 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1775
1807
|
} catch {
|
|
1776
1808
|
continue;
|
|
1777
1809
|
}
|
|
1778
|
-
const
|
|
1810
|
+
const lockfileFanout = lockfile.fanout || [];
|
|
1811
|
+
const displayLocation = _InventoryScanner.formatDisplayLocation(item.scope, item.host, item.dir, lockfileFanout);
|
|
1812
|
+
const locKey = `${item.scope}:${item.dir}`;
|
|
1813
|
+
const locSummary = scannedLocationsMap.get(locKey) || {
|
|
1814
|
+
scope: item.scope,
|
|
1815
|
+
targetDir: item.dir,
|
|
1816
|
+
displayLocation: _InventoryScanner.formatDisplayLocation(item.scope, item.host, item.dir),
|
|
1817
|
+
packageCount: 0,
|
|
1818
|
+
fanout: []
|
|
1819
|
+
};
|
|
1820
|
+
for (const f of lockfileFanout) {
|
|
1821
|
+
if (!locSummary.fanout.includes(f)) {
|
|
1822
|
+
locSummary.fanout.push(f);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
scannedLocationsMap.set(locKey, locSummary);
|
|
1779
1826
|
const bundleOwnedSkills = /* @__PURE__ */ new Set();
|
|
1780
1827
|
const bundleOwnedAgents = /* @__PURE__ */ new Set();
|
|
1781
1828
|
const bundleOwnedWorkflows = /* @__PURE__ */ new Set();
|
|
@@ -1819,6 +1866,7 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1819
1866
|
bundleOwnedWorkflows.add(w.replace(/\.md$/, ""));
|
|
1820
1867
|
});
|
|
1821
1868
|
}
|
|
1869
|
+
locSummary.packageCount++;
|
|
1822
1870
|
const record = {
|
|
1823
1871
|
id: `${bundleName}@${item.scope}:${item.host}`,
|
|
1824
1872
|
name: bundleName,
|
|
@@ -1833,7 +1881,9 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1833
1881
|
method: lockfile.method || "symlink",
|
|
1834
1882
|
fileCount,
|
|
1835
1883
|
title: bundleDef?.name || bundleName,
|
|
1836
|
-
description: bundleDef?.description
|
|
1884
|
+
description: bundleDef?.description,
|
|
1885
|
+
fanout: lockfileFanout,
|
|
1886
|
+
projections: lockfileFanout
|
|
1837
1887
|
};
|
|
1838
1888
|
allRecords.push(record);
|
|
1839
1889
|
bundleRecords.push(record);
|
|
@@ -1841,6 +1891,7 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1841
1891
|
const installedSkills = lockfile.installed?.skills || [];
|
|
1842
1892
|
for (const skillName of installedSkills) {
|
|
1843
1893
|
if (bundleOwnedSkills.has(skillName)) continue;
|
|
1894
|
+
locSummary.packageCount++;
|
|
1844
1895
|
const record = {
|
|
1845
1896
|
id: `skill:${skillName}@${item.scope}:${item.host}`,
|
|
1846
1897
|
name: skillName,
|
|
@@ -1855,7 +1906,9 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1855
1906
|
method: lockfile.method || "symlink",
|
|
1856
1907
|
fileCount: 1,
|
|
1857
1908
|
title: skillName,
|
|
1858
|
-
description: `Standalone skill (${skillName})
|
|
1909
|
+
description: `Standalone skill (${skillName})`,
|
|
1910
|
+
fanout: lockfileFanout,
|
|
1911
|
+
projections: lockfileFanout
|
|
1859
1912
|
};
|
|
1860
1913
|
allRecords.push(record);
|
|
1861
1914
|
standaloneRecords.push(record);
|
|
@@ -1864,6 +1917,7 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1864
1917
|
for (const agentFile of installedAgents) {
|
|
1865
1918
|
if (bundleOwnedAgents.has(agentFile)) continue;
|
|
1866
1919
|
const agentName = agentFile.replace(/\.md$/, "");
|
|
1920
|
+
locSummary.packageCount++;
|
|
1867
1921
|
const record = {
|
|
1868
1922
|
id: `agent:${agentName}@${item.scope}:${item.host}`,
|
|
1869
1923
|
name: agentName,
|
|
@@ -1878,7 +1932,9 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1878
1932
|
method: lockfile.method || "symlink",
|
|
1879
1933
|
fileCount: 1,
|
|
1880
1934
|
title: agentName,
|
|
1881
|
-
description: `Standalone agent (${agentFile})
|
|
1935
|
+
description: `Standalone agent (${agentFile})`,
|
|
1936
|
+
fanout: lockfileFanout,
|
|
1937
|
+
projections: lockfileFanout
|
|
1882
1938
|
};
|
|
1883
1939
|
allRecords.push(record);
|
|
1884
1940
|
standaloneRecords.push(record);
|
|
@@ -1888,7 +1944,9 @@ var InventoryScanner = class _InventoryScanner {
|
|
|
1888
1944
|
records: allRecords,
|
|
1889
1945
|
bundles: bundleRecords,
|
|
1890
1946
|
standaloneItems: standaloneRecords,
|
|
1891
|
-
targetDirs: Array.from(scannedTargetDirs)
|
|
1947
|
+
targetDirs: Array.from(scannedTargetDirs),
|
|
1948
|
+
scannedScopes: scopes,
|
|
1949
|
+
scannedLocations: Array.from(scannedLocationsMap.values())
|
|
1892
1950
|
};
|
|
1893
1951
|
}
|
|
1894
1952
|
};
|
|
@@ -1906,6 +1964,18 @@ var UpdateEngine = class {
|
|
|
1906
1964
|
this.scanner = scanner2 || new InventoryScanner(this.registry);
|
|
1907
1965
|
this.installer = installer2 || new InstallEngine(this.registry);
|
|
1908
1966
|
}
|
|
1967
|
+
deduplicateProjections(projections) {
|
|
1968
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1969
|
+
const deduplicated = [];
|
|
1970
|
+
for (const p of projections) {
|
|
1971
|
+
const key = `${p.host}:${p.path}`;
|
|
1972
|
+
if (!seen.has(key)) {
|
|
1973
|
+
seen.add(key);
|
|
1974
|
+
deduplicated.push(p);
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
return deduplicated;
|
|
1978
|
+
}
|
|
1909
1979
|
async calculateHash(filePath) {
|
|
1910
1980
|
const buffer = await fs6.readFile(filePath);
|
|
1911
1981
|
return "sha256:" + crypto3.createHash("sha256").update(buffer).digest("hex");
|
|
@@ -1962,7 +2032,9 @@ var UpdateEngine = class {
|
|
|
1962
2032
|
items,
|
|
1963
2033
|
outdatedCount,
|
|
1964
2034
|
upToDateCount,
|
|
1965
|
-
totalCount: items.length
|
|
2035
|
+
totalCount: items.length,
|
|
2036
|
+
scannedScopes: inventory.scannedScopes,
|
|
2037
|
+
scannedLocations: inventory.scannedLocations
|
|
1966
2038
|
};
|
|
1967
2039
|
}
|
|
1968
2040
|
async update(targets, options = {}) {
|
|
@@ -1985,19 +2057,39 @@ var UpdateEngine = class {
|
|
|
1985
2057
|
updated: [],
|
|
1986
2058
|
skipped: [],
|
|
1987
2059
|
targetDirs: inventory.targetDirs,
|
|
1988
|
-
dryRun: options.dryRun || false
|
|
2060
|
+
dryRun: options.dryRun || false,
|
|
2061
|
+
projections: []
|
|
1989
2062
|
};
|
|
1990
2063
|
}
|
|
1991
2064
|
if (options.dryRun) {
|
|
2065
|
+
const dryProjections = [];
|
|
2066
|
+
for (const record of recordsToUpdate) {
|
|
2067
|
+
const lockfilePath = path8.join(record.targetDir, "agents-united.json");
|
|
2068
|
+
if (await fs6.pathExists(lockfilePath)) {
|
|
2069
|
+
const dryResult = await this.installer.install(record.name, {
|
|
2070
|
+
scope: record.scope,
|
|
2071
|
+
method: record.method,
|
|
2072
|
+
hosts: [record.host],
|
|
2073
|
+
targetDir: record.targetDir,
|
|
2074
|
+
fanout: options.fanout,
|
|
2075
|
+
dryRun: true
|
|
2076
|
+
});
|
|
2077
|
+
if (dryResult.projections) {
|
|
2078
|
+
dryProjections.push(...dryResult.projections);
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
1992
2082
|
return {
|
|
1993
2083
|
updated: recordsToUpdate,
|
|
1994
2084
|
skipped: [],
|
|
1995
2085
|
targetDirs: inventory.targetDirs,
|
|
1996
|
-
dryRun: true
|
|
2086
|
+
dryRun: true,
|
|
2087
|
+
projections: this.deduplicateProjections(dryProjections)
|
|
1997
2088
|
};
|
|
1998
2089
|
}
|
|
1999
2090
|
const updated = [];
|
|
2000
2091
|
const skipped = [];
|
|
2092
|
+
const collectedProjections = [];
|
|
2001
2093
|
for (const record of recordsToUpdate) {
|
|
2002
2094
|
const lockfilePath = path8.join(record.targetDir, "agents-united.json");
|
|
2003
2095
|
if (!await fs6.pathExists(lockfilePath)) {
|
|
@@ -2038,7 +2130,7 @@ var UpdateEngine = class {
|
|
|
2038
2130
|
continue;
|
|
2039
2131
|
}
|
|
2040
2132
|
}
|
|
2041
|
-
await this.installer.install(record.name, {
|
|
2133
|
+
const installResult = await this.installer.install(record.name, {
|
|
2042
2134
|
scope: record.scope,
|
|
2043
2135
|
method: record.method,
|
|
2044
2136
|
hosts: [record.host],
|
|
@@ -2047,11 +2139,24 @@ var UpdateEngine = class {
|
|
|
2047
2139
|
force: true
|
|
2048
2140
|
// force overwrite since we passed collision check above
|
|
2049
2141
|
});
|
|
2142
|
+
if (installResult.projections) {
|
|
2143
|
+
collectedProjections.push(...installResult.projections);
|
|
2144
|
+
}
|
|
2050
2145
|
if (await fs6.pathExists(lockfilePath)) {
|
|
2051
2146
|
const updatedLockfile = await fs6.readJson(lockfilePath);
|
|
2052
2147
|
updatedLockfile.bundleVersions = updatedLockfile.bundleVersions || {};
|
|
2053
2148
|
updatedLockfile.bundleVersions[record.name] = record.upstreamVersion;
|
|
2054
2149
|
await fs6.writeJson(lockfilePath, updatedLockfile, { spaces: 2 });
|
|
2150
|
+
if (updatedLockfile.fanout) {
|
|
2151
|
+
record.fanout = updatedLockfile.fanout;
|
|
2152
|
+
record.projections = updatedLockfile.fanout;
|
|
2153
|
+
record.displayLocation = InventoryScanner.formatDisplayLocation(
|
|
2154
|
+
record.scope,
|
|
2155
|
+
record.host,
|
|
2156
|
+
record.targetDir,
|
|
2157
|
+
updatedLockfile.fanout
|
|
2158
|
+
);
|
|
2159
|
+
}
|
|
2055
2160
|
}
|
|
2056
2161
|
record.installedVersion = record.upstreamVersion;
|
|
2057
2162
|
record.driftStatus = "up-to-date";
|
|
@@ -2061,7 +2166,8 @@ var UpdateEngine = class {
|
|
|
2061
2166
|
updated,
|
|
2062
2167
|
skipped,
|
|
2063
2168
|
targetDirs: inventory.targetDirs,
|
|
2064
|
-
dryRun: false
|
|
2169
|
+
dryRun: false,
|
|
2170
|
+
projections: this.deduplicateProjections(collectedProjections)
|
|
2065
2171
|
};
|
|
2066
2172
|
}
|
|
2067
2173
|
};
|
|
@@ -3304,6 +3410,112 @@ function detectWorkspaceHosts(cwd = process.cwd()) {
|
|
|
3304
3410
|
}
|
|
3305
3411
|
return detected;
|
|
3306
3412
|
}
|
|
3413
|
+
function getTerminalContentWidth() {
|
|
3414
|
+
const cols = typeof process !== "undefined" && process.stdout?.columns ? process.stdout.columns : 80;
|
|
3415
|
+
return Math.max(40, Math.min(cols - 8, 68));
|
|
3416
|
+
}
|
|
3417
|
+
function wrapText(text2, maxLen, indent = "") {
|
|
3418
|
+
if (!text2) return [];
|
|
3419
|
+
const limit = maxLen ?? getTerminalContentWidth();
|
|
3420
|
+
const words = text2.split(/\s+/);
|
|
3421
|
+
const lines = [];
|
|
3422
|
+
let current = indent;
|
|
3423
|
+
for (const word of words) {
|
|
3424
|
+
if (!word) continue;
|
|
3425
|
+
if (current.length > indent.length && current.length + 1 + word.length > limit) {
|
|
3426
|
+
lines.push(current);
|
|
3427
|
+
current = indent + word;
|
|
3428
|
+
} else {
|
|
3429
|
+
current = current.length === indent.length ? current + word : current + " " + word;
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
if (current.trim().length > 0) {
|
|
3433
|
+
lines.push(current);
|
|
3434
|
+
}
|
|
3435
|
+
return lines;
|
|
3436
|
+
}
|
|
3437
|
+
function formatWrappedList(items, indent = " ", maxLineLen) {
|
|
3438
|
+
if (!items || items.length === 0) return [];
|
|
3439
|
+
const limit = maxLineLen ?? getTerminalContentWidth();
|
|
3440
|
+
const lines = [];
|
|
3441
|
+
let currentLine = indent;
|
|
3442
|
+
for (let i = 0; i < items.length; i++) {
|
|
3443
|
+
const item = items[i];
|
|
3444
|
+
const isLast = i === items.length - 1;
|
|
3445
|
+
const token = isLast ? item : `${item}, `;
|
|
3446
|
+
if (currentLine.length > indent.length && currentLine.length + token.length > limit) {
|
|
3447
|
+
lines.push(currentLine.trimEnd());
|
|
3448
|
+
currentLine = indent + token;
|
|
3449
|
+
} else {
|
|
3450
|
+
currentLine += token;
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
if (currentLine.trim().length > 0) {
|
|
3454
|
+
lines.push(currentLine.trimEnd());
|
|
3455
|
+
}
|
|
3456
|
+
return lines;
|
|
3457
|
+
}
|
|
3458
|
+
function formatInstallationSummary(options) {
|
|
3459
|
+
const { bundleName, scope, method, hosts, agents, skills, targetDirs, projections } = options;
|
|
3460
|
+
const limit = getTerminalContentWidth();
|
|
3461
|
+
const lines = [
|
|
3462
|
+
`Bundle: ${bundleName}`,
|
|
3463
|
+
`Scope: ${scope}`,
|
|
3464
|
+
`Method: ${method}`,
|
|
3465
|
+
`Targets: ${hosts.join(", ")}`
|
|
3466
|
+
];
|
|
3467
|
+
if (agents.length === 0) {
|
|
3468
|
+
lines.push(`Agents: None`);
|
|
3469
|
+
} else {
|
|
3470
|
+
const inlineAgents = `Agents (${agents.length}): ${agents.join(", ")}`;
|
|
3471
|
+
if (inlineAgents.length <= limit) {
|
|
3472
|
+
lines.push(inlineAgents);
|
|
3473
|
+
} else {
|
|
3474
|
+
lines.push(`Agents (${agents.length}):`);
|
|
3475
|
+
lines.push(...formatWrappedList(agents, " ", limit));
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
if (skills.length === 0) {
|
|
3479
|
+
lines.push(`Skills: None`);
|
|
3480
|
+
} else {
|
|
3481
|
+
const inlineSkills = `Skills (${skills.length}): ${skills.join(", ")}`;
|
|
3482
|
+
if (inlineSkills.length <= limit) {
|
|
3483
|
+
lines.push(inlineSkills);
|
|
3484
|
+
} else {
|
|
3485
|
+
lines.push(`Skills (${skills.length}):`);
|
|
3486
|
+
lines.push(...formatWrappedList(skills, " ", limit));
|
|
3487
|
+
}
|
|
3488
|
+
}
|
|
3489
|
+
if (targetDirs.length === 0) {
|
|
3490
|
+
lines.push("Target Directories: None");
|
|
3491
|
+
} else if (targetDirs.length === 1) {
|
|
3492
|
+
const singleDirLine = `Target Directories: ${targetDirs[0]}`;
|
|
3493
|
+
if (singleDirLine.length <= limit) {
|
|
3494
|
+
lines.push(singleDirLine);
|
|
3495
|
+
} else {
|
|
3496
|
+
lines.push("Target Directories:");
|
|
3497
|
+
lines.push(` ${targetDirs[0]}`);
|
|
3498
|
+
}
|
|
3499
|
+
} else {
|
|
3500
|
+
lines.push(`Target Directories (${targetDirs.length}):`);
|
|
3501
|
+
for (const dir of targetDirs) {
|
|
3502
|
+
lines.push(` ${dir}`);
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
if (projections && projections.length > 0) {
|
|
3506
|
+
const byHost = /* @__PURE__ */ new Map();
|
|
3507
|
+
for (const p of projections) {
|
|
3508
|
+
byHost.set(p.host, (byHost.get(p.host) ?? 0) + 1);
|
|
3509
|
+
}
|
|
3510
|
+
const hostSummaries = [];
|
|
3511
|
+
for (const [host, count] of byHost) {
|
|
3512
|
+
const label = HOST_REGISTRY[host]?.label ?? host;
|
|
3513
|
+
hostSummaries.push(`${label} (${count} file${count > 1 ? "s" : ""})`);
|
|
3514
|
+
}
|
|
3515
|
+
lines.push(`Projections: ${hostSummaries.join(", ")}`);
|
|
3516
|
+
}
|
|
3517
|
+
return lines.join("\n");
|
|
3518
|
+
}
|
|
3307
3519
|
function renderProjections(projections) {
|
|
3308
3520
|
const byHost = /* @__PURE__ */ new Map();
|
|
3309
3521
|
for (const p of projections) {
|
|
@@ -3316,7 +3528,12 @@ function renderProjections(projections) {
|
|
|
3316
3528
|
lines.push(`${HOST_REGISTRY[host]?.label ?? host} \u2014 ${items.length} file${items.length > 1 ? "s" : ""}`);
|
|
3317
3529
|
for (const p of items) {
|
|
3318
3530
|
lines.push(` \u2192 ${p.path}`);
|
|
3319
|
-
for (const w of p.warnings)
|
|
3531
|
+
for (const w of p.warnings) {
|
|
3532
|
+
const wrapped = wrapText(`\u26A0 ${w}`, 68, " ");
|
|
3533
|
+
for (const wl of wrapped) {
|
|
3534
|
+
lines.push(pc.yellow(wl));
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3320
3537
|
}
|
|
3321
3538
|
}
|
|
3322
3539
|
return lines.join("\n");
|
|
@@ -3826,22 +4043,28 @@ To bypass this gate and install draft assets anyway, pass: --allow-under-constru
|
|
|
3826
4043
|
return;
|
|
3827
4044
|
}
|
|
3828
4045
|
note(
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
4046
|
+
formatInstallationSummary({
|
|
4047
|
+
bundleName: result.installed.targetBundle || "Single Item",
|
|
4048
|
+
scope,
|
|
4049
|
+
method: result.method,
|
|
4050
|
+
hosts,
|
|
4051
|
+
agents: result.installed.agents,
|
|
4052
|
+
skills: result.installed.skills,
|
|
4053
|
+
targetDirs: result.targetDirs,
|
|
4054
|
+
projections: result.projections
|
|
4055
|
+
}),
|
|
3839
4056
|
"Installation Success"
|
|
3840
4057
|
);
|
|
4058
|
+
if (result.projections.length > 0) {
|
|
4059
|
+
note(renderProjections(result.projections), "Installed Projections");
|
|
4060
|
+
}
|
|
3841
4061
|
const hasClineProjection = result.projections.some((p) => p.host === "cline");
|
|
3842
4062
|
if (hasClineProjection && !options.dryRun) {
|
|
3843
4063
|
note(
|
|
3844
|
-
pc.green(
|
|
4064
|
+
pc.green(
|
|
4065
|
+
`Already active: any Cline session in this workspace now sees this bundle's
|
|
4066
|
+
skills, subagent_* agent tools, rules & workflow commands (ADR 0013 native discovery).`
|
|
4067
|
+
),
|
|
3845
4068
|
"Native Activation"
|
|
3846
4069
|
);
|
|
3847
4070
|
}
|
|
@@ -3919,7 +4142,7 @@ rules & workflows run: agents update ${identifier} --fanout cline
|
|
|
3919
4142
|
if (!options.dryRun && targetBundleDef?.tier === "organization") {
|
|
3920
4143
|
note(
|
|
3921
4144
|
pc.cyan(
|
|
3922
|
-
"\u{1F4A1} In-Session MCP Setup: Your Lead Orchestrator will automatically check
|
|
4145
|
+
"\u{1F4A1} In-Session MCP Setup: Your Lead Orchestrator will automatically check\nyour runtime tools and guide configuration of live browser automation,\ndesign tokens, or cloud APIs on demand."
|
|
3923
4146
|
),
|
|
3924
4147
|
"Adaptive Tooling"
|
|
3925
4148
|
);
|
|
@@ -4036,7 +4259,28 @@ cli.command("update [identifier]", "Update installed packages to upstream regist
|
|
|
4036
4259
|
} else if (options.all || options.yes || !isInteractive) {
|
|
4037
4260
|
targetsToUpdate = "__all__";
|
|
4038
4261
|
} else {
|
|
4039
|
-
const
|
|
4262
|
+
const locationLines = [];
|
|
4263
|
+
if (report.scannedLocations && report.scannedLocations.length > 0) {
|
|
4264
|
+
for (const loc of report.scannedLocations) {
|
|
4265
|
+
const scopeLabel = loc.scope === "project" ? "Project" : "Global";
|
|
4266
|
+
const fanoutStr = loc.fanout.length > 0 ? ` ${pc.magenta(`(projections: ${loc.fanout.join(", ")})`)}` : "";
|
|
4267
|
+
locationLines.push(` \u2022 ${scopeLabel} (${loc.displayLocation}): ${pc.bold(loc.packageCount)} package${loc.packageCount !== 1 ? "s" : ""}${fanoutStr}`);
|
|
4268
|
+
}
|
|
4269
|
+
} else {
|
|
4270
|
+
const projectCount = report.items.filter((i) => i.record.scope === "project").length;
|
|
4271
|
+
const globalCount = report.items.filter((i) => i.record.scope === "global").length;
|
|
4272
|
+
if (!options.global) {
|
|
4273
|
+
locationLines.push(` \u2022 Project (./.agents): ${pc.bold(projectCount)} package${projectCount !== 1 ? "s" : ""}`);
|
|
4274
|
+
}
|
|
4275
|
+
locationLines.push(` \u2022 Global (~/.agents): ${pc.bold(globalCount)} package${globalCount !== 1 ? "s" : ""}`);
|
|
4276
|
+
}
|
|
4277
|
+
const allDetectedFanouts = Array.from(new Set(report.items.flatMap((i) => i.record.fanout || [])));
|
|
4278
|
+
const fanoutSummary = allDetectedFanouts.length > 0 ? `
|
|
4279
|
+
Active Projections: ${allDetectedFanouts.map((h) => `${pc.cyan(h)} (./.${h}/)`).join(", ")}` : "";
|
|
4280
|
+
const statusMessage = `Locations Checked:
|
|
4281
|
+
${locationLines.join("\n")}${fanoutSummary}
|
|
4282
|
+
|
|
4283
|
+
Total Installed Packages: ${report.totalCount}
|
|
4040
4284
|
Updates Available: ${report.outdatedCount > 0 ? pc.yellow(pc.bold(`${report.outdatedCount} package${report.outdatedCount > 1 ? "s" : ""} can be updated`)) : pc.green("0 (All up to date)")}`;
|
|
4041
4285
|
note(statusMessage, "Inventory Status");
|
|
4042
4286
|
const menuOptions = [];
|
|
@@ -4108,6 +4352,9 @@ Updates Available: ${report.outdatedCount > 0 ? pc.yellow(pc.bold(`${report.outd
|
|
|
4108
4352
|
updateSpinner.stop("Update completed");
|
|
4109
4353
|
if (options.dryRun) {
|
|
4110
4354
|
outro(pc.yellow(`[DRY RUN] Would update ${result.updated.length} packages in ${result.targetDirs.join(", ")}`));
|
|
4355
|
+
if (result.projections && result.projections.length > 0) {
|
|
4356
|
+
note(renderProjections(result.projections), "Projection Plan (dry run)");
|
|
4357
|
+
}
|
|
4111
4358
|
return;
|
|
4112
4359
|
}
|
|
4113
4360
|
if (result.updated.length > 0) {
|
|
@@ -4130,6 +4377,9 @@ For Cline configured agents, rules & workflows: agents update ${unprojected[0]}
|
|
|
4130
4377
|
}
|
|
4131
4378
|
const updatedList = result.updated.map((u) => ` \u2714 ${pc.bold(u.name)} ${pc.cyan(u.displayLocation)} ${pc.green(`(v${u.installedVersion})`)}`).join("\n");
|
|
4132
4379
|
note(updatedList, "Updated Packages");
|
|
4380
|
+
if (result.projections && result.projections.length > 0) {
|
|
4381
|
+
note(renderProjections(result.projections), "Updated Projections");
|
|
4382
|
+
}
|
|
4133
4383
|
}
|
|
4134
4384
|
if (result.skipped.length > 0) {
|
|
4135
4385
|
const skippedList = result.skipped.map((s2) => ` \u26A0 ${pc.yellow(s2.record.name)}: ${s2.reason}`).join("\n");
|
|
@@ -4534,21 +4784,28 @@ Planned Capabilities:
|
|
|
4534
4784
|
});
|
|
4535
4785
|
installSpinner.stop(pc.green(`\u2714 Successfully installed ${bundle.name}!`));
|
|
4536
4786
|
note(
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4787
|
+
formatInstallationSummary({
|
|
4788
|
+
bundleName: result.installed.targetBundle || bundle.name,
|
|
4789
|
+
scope: "project",
|
|
4790
|
+
method: result.method,
|
|
4791
|
+
hosts: installHosts,
|
|
4792
|
+
agents: result.installed.agents,
|
|
4793
|
+
skills: result.installed.skills,
|
|
4794
|
+
targetDirs: result.targetDirs,
|
|
4795
|
+
projections: result.projections
|
|
4796
|
+
}),
|
|
4547
4797
|
"Installation Success"
|
|
4548
4798
|
);
|
|
4799
|
+
if (result.projections.length > 0) {
|
|
4800
|
+
note(renderProjections(result.projections), "Installed Projections");
|
|
4801
|
+
}
|
|
4549
4802
|
if (result.projections.some((p) => p.host === "cline")) {
|
|
4550
4803
|
note(
|
|
4551
|
-
pc.green(
|
|
4804
|
+
pc.green(
|
|
4805
|
+
`Already active: any Cline session in this workspace now sees this bundle's
|
|
4806
|
+
skills, subagent_* agent tools, rules & workflow commands (ADR 0013 native discovery).
|
|
4807
|
+
Use "agents start ${bundle.name}" for a pre-seeded team session.`
|
|
4808
|
+
),
|
|
4552
4809
|
"Native Activation"
|
|
4553
4810
|
);
|
|
4554
4811
|
}
|
|
@@ -4939,6 +5196,11 @@ cli.help();
|
|
|
4939
5196
|
cli.version("1.0.0");
|
|
4940
5197
|
cli.parse();
|
|
4941
5198
|
export {
|
|
4942
|
-
detectWorkspaceHosts
|
|
5199
|
+
detectWorkspaceHosts,
|
|
5200
|
+
formatInstallationSummary,
|
|
5201
|
+
formatWrappedList,
|
|
5202
|
+
getTerminalContentWidth,
|
|
5203
|
+
renderProjections,
|
|
5204
|
+
wrapText
|
|
4943
5205
|
};
|
|
4944
5206
|
//# sourceMappingURL=cli.js.map
|