cc-mirror 1.0.4 → 1.1.0
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 +168 -98
- package/dist/cc-mirror.mjs +788 -249
- package/dist/skills/multi-agent-orchestrator/SKILL.md +391 -0
- package/dist/skills/multi-agent-orchestrator/references/code-review.md +266 -0
- package/dist/skills/multi-agent-orchestrator/references/data-analysis.md +315 -0
- package/dist/skills/multi-agent-orchestrator/references/devops.md +309 -0
- package/dist/skills/multi-agent-orchestrator/references/documentation.md +310 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/code-review.md +301 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/data-analysis.md +347 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/devops.md +340 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/documentation.md +343 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/project-management.md +370 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/research.md +322 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/software-development.md +269 -0
- package/dist/skills/multi-agent-orchestrator/references/domains/testing.md +313 -0
- package/dist/skills/multi-agent-orchestrator/references/examples.md +377 -0
- package/dist/skills/multi-agent-orchestrator/references/guide.md +327 -0
- package/dist/skills/multi-agent-orchestrator/references/patterns.md +441 -0
- package/dist/skills/multi-agent-orchestrator/references/project-management.md +345 -0
- package/dist/skills/multi-agent-orchestrator/references/research.md +285 -0
- package/dist/skills/multi-agent-orchestrator/references/software-development.md +242 -0
- package/dist/skills/multi-agent-orchestrator/references/testing.md +282 -0
- package/dist/skills/multi-agent-orchestrator/references/tools.md +454 -0
- package/dist/tui.mjs +1045 -360
- package/package.json +2 -2
package/dist/cc-mirror.mjs
CHANGED
|
@@ -179,8 +179,8 @@ var runTui = async () => {
|
|
|
179
179
|
};
|
|
180
180
|
|
|
181
181
|
// src/core/index.ts
|
|
182
|
-
import
|
|
183
|
-
import
|
|
182
|
+
import fs13 from "node:fs";
|
|
183
|
+
import path22 from "node:path";
|
|
184
184
|
|
|
185
185
|
// src/core/constants.ts
|
|
186
186
|
import os from "node:os";
|
|
@@ -1483,6 +1483,203 @@ var buildCCRouterTweakccConfig = () => ({
|
|
|
1483
1483
|
}
|
|
1484
1484
|
});
|
|
1485
1485
|
|
|
1486
|
+
// src/brands/mirror.ts
|
|
1487
|
+
var clamp5 = (value) => Math.max(0, Math.min(255, Math.round(value)));
|
|
1488
|
+
var hexToRgb5 = (hex) => {
|
|
1489
|
+
const normalized = hex.replace("#", "").trim();
|
|
1490
|
+
if (normalized.length === 3) {
|
|
1491
|
+
const [r, g, b] = normalized.split("");
|
|
1492
|
+
return {
|
|
1493
|
+
r: clamp5(parseInt(r + r, 16)),
|
|
1494
|
+
g: clamp5(parseInt(g + g, 16)),
|
|
1495
|
+
b: clamp5(parseInt(b + b, 16))
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1498
|
+
if (normalized.length !== 6) {
|
|
1499
|
+
throw new Error(`Unsupported hex color: ${hex}`);
|
|
1500
|
+
}
|
|
1501
|
+
return {
|
|
1502
|
+
r: clamp5(parseInt(normalized.slice(0, 2), 16)),
|
|
1503
|
+
g: clamp5(parseInt(normalized.slice(2, 4), 16)),
|
|
1504
|
+
b: clamp5(parseInt(normalized.slice(4, 6), 16))
|
|
1505
|
+
};
|
|
1506
|
+
};
|
|
1507
|
+
var rgb5 = (hex) => {
|
|
1508
|
+
const { r, g, b } = hexToRgb5(hex);
|
|
1509
|
+
return `rgb(${r},${g},${b})`;
|
|
1510
|
+
};
|
|
1511
|
+
var mix5 = (hexA, hexB, weight) => {
|
|
1512
|
+
const a = hexToRgb5(hexA);
|
|
1513
|
+
const b = hexToRgb5(hexB);
|
|
1514
|
+
const w = Math.max(0, Math.min(1, weight));
|
|
1515
|
+
return `rgb(${clamp5(a.r + (b.r - a.r) * w)},${clamp5(a.g + (b.g - a.g) * w)},${clamp5(a.b + (b.b - a.b) * w)})`;
|
|
1516
|
+
};
|
|
1517
|
+
var lighten5 = (hex, weight) => mix5(hex, "#ffffff", weight);
|
|
1518
|
+
var palette5 = {
|
|
1519
|
+
// Base surfaces - near-black with metallic sheen
|
|
1520
|
+
base: "#0d0f12",
|
|
1521
|
+
surface: "#14161a",
|
|
1522
|
+
panel: "#1a1d22",
|
|
1523
|
+
elevated: "#22262d",
|
|
1524
|
+
// Borders - subtle silver
|
|
1525
|
+
border: "#3a3f48",
|
|
1526
|
+
borderStrong: "#4a5058",
|
|
1527
|
+
borderGlow: "#6a7078",
|
|
1528
|
+
// Text
|
|
1529
|
+
text: "#e8eaed",
|
|
1530
|
+
textMuted: "#b0b5bc",
|
|
1531
|
+
textDim: "#7a8088",
|
|
1532
|
+
// Primary: Silver/Chrome
|
|
1533
|
+
silver: "#c0c0c0",
|
|
1534
|
+
chrome: "#a0a0a0",
|
|
1535
|
+
platinum: "#e5e4e2",
|
|
1536
|
+
// Accent: Electric blue
|
|
1537
|
+
electric: "#00d4ff",
|
|
1538
|
+
electricSoft: "#4de1ff",
|
|
1539
|
+
electricDeep: "#00a3cc",
|
|
1540
|
+
// Secondary: Deep purple
|
|
1541
|
+
purple: "#6b5b95",
|
|
1542
|
+
purpleSoft: "#8a7ab4",
|
|
1543
|
+
// Semantic
|
|
1544
|
+
green: "#4ade80",
|
|
1545
|
+
red: "#f87171",
|
|
1546
|
+
orange: "#fb923c",
|
|
1547
|
+
cyan: "#22d3ee"
|
|
1548
|
+
};
|
|
1549
|
+
var theme4 = {
|
|
1550
|
+
name: "Mirror Claude",
|
|
1551
|
+
id: "mirror-claude",
|
|
1552
|
+
colors: {
|
|
1553
|
+
autoAccept: rgb5(palette5.green),
|
|
1554
|
+
bashBorder: rgb5(palette5.electric),
|
|
1555
|
+
claude: rgb5(palette5.silver),
|
|
1556
|
+
claudeShimmer: rgb5(palette5.platinum),
|
|
1557
|
+
claudeBlue_FOR_SYSTEM_SPINNER: rgb5(palette5.electric),
|
|
1558
|
+
claudeBlueShimmer_FOR_SYSTEM_SPINNER: lighten5(palette5.electric, 0.2),
|
|
1559
|
+
permission: rgb5(palette5.electricSoft),
|
|
1560
|
+
permissionShimmer: lighten5(palette5.electricSoft, 0.25),
|
|
1561
|
+
planMode: rgb5(palette5.purple),
|
|
1562
|
+
ide: rgb5(palette5.cyan),
|
|
1563
|
+
promptBorder: rgb5(palette5.border),
|
|
1564
|
+
promptBorderShimmer: rgb5(palette5.borderGlow),
|
|
1565
|
+
text: rgb5(palette5.text),
|
|
1566
|
+
inverseText: rgb5(palette5.base),
|
|
1567
|
+
inactive: rgb5(palette5.textDim),
|
|
1568
|
+
subtle: mix5(palette5.base, palette5.chrome, 0.08),
|
|
1569
|
+
suggestion: rgb5(palette5.electricSoft),
|
|
1570
|
+
remember: rgb5(palette5.purple),
|
|
1571
|
+
background: rgb5(palette5.base),
|
|
1572
|
+
success: rgb5(palette5.green),
|
|
1573
|
+
error: rgb5(palette5.red),
|
|
1574
|
+
warning: rgb5(palette5.orange),
|
|
1575
|
+
warningShimmer: lighten5(palette5.orange, 0.28),
|
|
1576
|
+
diffAdded: mix5(palette5.base, palette5.green, 0.15),
|
|
1577
|
+
diffRemoved: mix5(palette5.base, palette5.red, 0.15),
|
|
1578
|
+
diffAddedDimmed: mix5(palette5.base, palette5.green, 0.08),
|
|
1579
|
+
diffRemovedDimmed: mix5(palette5.base, palette5.red, 0.08),
|
|
1580
|
+
diffAddedWord: mix5(palette5.base, palette5.green, 0.32),
|
|
1581
|
+
diffRemovedWord: mix5(palette5.base, palette5.red, 0.32),
|
|
1582
|
+
diffAddedWordDimmed: mix5(palette5.base, palette5.green, 0.18),
|
|
1583
|
+
diffRemovedWordDimmed: mix5(palette5.base, palette5.red, 0.18),
|
|
1584
|
+
red_FOR_SUBAGENTS_ONLY: rgb5(palette5.red),
|
|
1585
|
+
blue_FOR_SUBAGENTS_ONLY: rgb5(palette5.electric),
|
|
1586
|
+
green_FOR_SUBAGENTS_ONLY: rgb5(palette5.green),
|
|
1587
|
+
yellow_FOR_SUBAGENTS_ONLY: rgb5(palette5.orange),
|
|
1588
|
+
purple_FOR_SUBAGENTS_ONLY: rgb5(palette5.purple),
|
|
1589
|
+
orange_FOR_SUBAGENTS_ONLY: rgb5(palette5.orange),
|
|
1590
|
+
pink_FOR_SUBAGENTS_ONLY: lighten5(palette5.purple, 0.32),
|
|
1591
|
+
cyan_FOR_SUBAGENTS_ONLY: rgb5(palette5.cyan),
|
|
1592
|
+
professionalBlue: rgb5(palette5.electric),
|
|
1593
|
+
rainbow_red: rgb5(palette5.red),
|
|
1594
|
+
rainbow_orange: rgb5(palette5.orange),
|
|
1595
|
+
rainbow_yellow: lighten5(palette5.orange, 0.18),
|
|
1596
|
+
rainbow_green: rgb5(palette5.green),
|
|
1597
|
+
rainbow_blue: rgb5(palette5.electricSoft),
|
|
1598
|
+
rainbow_indigo: rgb5(palette5.electricDeep),
|
|
1599
|
+
rainbow_violet: rgb5(palette5.purple),
|
|
1600
|
+
rainbow_red_shimmer: lighten5(palette5.red, 0.35),
|
|
1601
|
+
rainbow_orange_shimmer: lighten5(palette5.orange, 0.35),
|
|
1602
|
+
rainbow_yellow_shimmer: lighten5(palette5.orange, 0.3),
|
|
1603
|
+
rainbow_green_shimmer: lighten5(palette5.green, 0.35),
|
|
1604
|
+
rainbow_blue_shimmer: lighten5(palette5.electricSoft, 0.35),
|
|
1605
|
+
rainbow_indigo_shimmer: lighten5(palette5.electricDeep, 0.35),
|
|
1606
|
+
rainbow_violet_shimmer: lighten5(palette5.purple, 0.35),
|
|
1607
|
+
clawd_body: rgb5(palette5.silver),
|
|
1608
|
+
clawd_background: rgb5(palette5.base),
|
|
1609
|
+
userMessageBackground: rgb5(palette5.panel),
|
|
1610
|
+
bashMessageBackgroundColor: rgb5(palette5.surface),
|
|
1611
|
+
memoryBackgroundColor: mix5(palette5.panel, palette5.purple, 0.08),
|
|
1612
|
+
rate_limit_fill: rgb5(palette5.electric),
|
|
1613
|
+
rate_limit_empty: rgb5(palette5.borderStrong)
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
var buildMirrorTweakccConfig = () => ({
|
|
1617
|
+
ccVersion: "",
|
|
1618
|
+
ccInstallationPath: null,
|
|
1619
|
+
lastModified: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1620
|
+
changesApplied: false,
|
|
1621
|
+
hidePiebaldAnnouncement: true,
|
|
1622
|
+
settings: {
|
|
1623
|
+
themes: [theme4, ...DEFAULT_THEMES],
|
|
1624
|
+
thinkingVerbs: {
|
|
1625
|
+
format: "{}... ",
|
|
1626
|
+
verbs: [
|
|
1627
|
+
"Reflecting",
|
|
1628
|
+
"Refracting",
|
|
1629
|
+
"Projecting",
|
|
1630
|
+
"Mirroring",
|
|
1631
|
+
"Amplifying",
|
|
1632
|
+
"Focusing",
|
|
1633
|
+
"Polishing",
|
|
1634
|
+
"Crystallizing",
|
|
1635
|
+
"Calibrating",
|
|
1636
|
+
"Synthesizing",
|
|
1637
|
+
"Resolving",
|
|
1638
|
+
"Composing",
|
|
1639
|
+
"Rendering",
|
|
1640
|
+
"Finalizing"
|
|
1641
|
+
]
|
|
1642
|
+
},
|
|
1643
|
+
thinkingStyle: {
|
|
1644
|
+
updateInterval: 100,
|
|
1645
|
+
phases: ["\u25C7", "\u25C6", "\u25C7", "\u25C8"],
|
|
1646
|
+
reverseMirror: true
|
|
1647
|
+
},
|
|
1648
|
+
userMessageDisplay: {
|
|
1649
|
+
format: formatUserMessage(getUserLabel()),
|
|
1650
|
+
styling: ["bold"],
|
|
1651
|
+
foregroundColor: rgb5(palette5.platinum),
|
|
1652
|
+
backgroundColor: rgb5(palette5.panel),
|
|
1653
|
+
borderStyle: "topBottomDouble",
|
|
1654
|
+
borderColor: rgb5(palette5.silver),
|
|
1655
|
+
paddingX: 1,
|
|
1656
|
+
paddingY: 0,
|
|
1657
|
+
fitBoxToContent: true
|
|
1658
|
+
},
|
|
1659
|
+
inputBox: {
|
|
1660
|
+
removeBorder: true
|
|
1661
|
+
},
|
|
1662
|
+
misc: {
|
|
1663
|
+
showTweakccVersion: false,
|
|
1664
|
+
showPatchesApplied: false,
|
|
1665
|
+
expandThinkingBlocks: true,
|
|
1666
|
+
enableConversationTitle: true,
|
|
1667
|
+
hideStartupBanner: true,
|
|
1668
|
+
hideCtrlGToEditPrompt: true,
|
|
1669
|
+
hideStartupClawd: true,
|
|
1670
|
+
increaseFileReadLimit: true
|
|
1671
|
+
},
|
|
1672
|
+
toolsets: [
|
|
1673
|
+
{
|
|
1674
|
+
name: "mirror",
|
|
1675
|
+
allowedTools: "*"
|
|
1676
|
+
}
|
|
1677
|
+
],
|
|
1678
|
+
defaultToolset: "mirror",
|
|
1679
|
+
planModeToolset: "mirror"
|
|
1680
|
+
}
|
|
1681
|
+
});
|
|
1682
|
+
|
|
1486
1683
|
// src/brands/index.ts
|
|
1487
1684
|
var BRAND_PRESETS = {
|
|
1488
1685
|
zai: {
|
|
@@ -1508,6 +1705,12 @@ var BRAND_PRESETS = {
|
|
|
1508
1705
|
label: "CCRouter Sky",
|
|
1509
1706
|
description: "Airy sky-blue accents for Claude Code Router.",
|
|
1510
1707
|
buildTweakccConfig: buildCCRouterTweakccConfig
|
|
1708
|
+
},
|
|
1709
|
+
mirror: {
|
|
1710
|
+
key: "mirror",
|
|
1711
|
+
label: "Mirror Claude",
|
|
1712
|
+
description: "Reflective silver/chrome theme for pure Claude Code experience.",
|
|
1713
|
+
buildTweakccConfig: buildMirrorTweakccConfig
|
|
1511
1714
|
}
|
|
1512
1715
|
};
|
|
1513
1716
|
var listBrandPresets = () => Object.values(BRAND_PRESETS);
|
|
@@ -1534,8 +1737,8 @@ var buildBrandConfig = (brandKey) => {
|
|
|
1534
1737
|
var getBrandThemeId = (brandKey) => {
|
|
1535
1738
|
if (!brandKey) return null;
|
|
1536
1739
|
const config = buildBrandConfig(brandKey);
|
|
1537
|
-
const
|
|
1538
|
-
return
|
|
1740
|
+
const theme5 = config.settings?.themes?.[0];
|
|
1741
|
+
return theme5?.id ?? null;
|
|
1539
1742
|
};
|
|
1540
1743
|
|
|
1541
1744
|
// src/core/tweakcc.ts
|
|
@@ -1558,7 +1761,7 @@ var ensureTweakccConfig = (tweakDir, brandKey) => {
|
|
|
1558
1761
|
let didUpdate = false;
|
|
1559
1762
|
if (brandKey === "minimax" && existingThemes.length > 0) {
|
|
1560
1763
|
const filtered = existingThemes.filter(
|
|
1561
|
-
(
|
|
1764
|
+
(theme5) => theme5?.id !== "minimax-ember" && theme5?.id !== "minimax-glass" && theme5?.id !== "minimax-blade" && theme5?.name !== "MiniMax Ember" && theme5?.name !== "MiniMax Glass" && theme5?.name !== "MiniMax Blade"
|
|
1562
1765
|
);
|
|
1563
1766
|
if (filtered.length !== existingThemes.length) {
|
|
1564
1767
|
existingThemes = filtered;
|
|
@@ -1602,10 +1805,10 @@ var ensureTweakccConfig = (tweakDir, brandKey) => {
|
|
|
1602
1805
|
if (brandThemes.length > 0) {
|
|
1603
1806
|
const mergedThemes = [
|
|
1604
1807
|
...brandThemes,
|
|
1605
|
-
...existingThemes.filter((existingTheme) => !brandThemes.some((
|
|
1808
|
+
...existingThemes.filter((existingTheme) => !brandThemes.some((theme5) => themeMatches(existingTheme, theme5)))
|
|
1606
1809
|
];
|
|
1607
1810
|
const sameLength = mergedThemes.length === existingThemes.length;
|
|
1608
|
-
const sameOrder = sameLength && mergedThemes.every((
|
|
1811
|
+
const sameOrder = sameLength && mergedThemes.every((theme5, idx) => themeMatches(theme5, existingThemes[idx]));
|
|
1609
1812
|
if (!sameOrder) {
|
|
1610
1813
|
existing.settings = { ...existing.settings, themes: mergedThemes };
|
|
1611
1814
|
didUpdate = true;
|
|
@@ -1757,7 +1960,7 @@ var listVariants = (rootDir) => {
|
|
|
1757
1960
|
};
|
|
1758
1961
|
|
|
1759
1962
|
// src/core/variant-builder/VariantBuilder.ts
|
|
1760
|
-
import
|
|
1963
|
+
import path16 from "node:path";
|
|
1761
1964
|
|
|
1762
1965
|
// src/providers/index.ts
|
|
1763
1966
|
var DEFAULT_TIMEOUT_MS = "3000000";
|
|
@@ -1831,6 +2034,29 @@ var PROVIDERS = {
|
|
|
1831
2034
|
credentialOptional: true
|
|
1832
2035
|
// No API key needed - CCRouter handles auth
|
|
1833
2036
|
},
|
|
2037
|
+
mirror: {
|
|
2038
|
+
key: "mirror",
|
|
2039
|
+
label: "Mirror Claude",
|
|
2040
|
+
description: "Pure Claude Code with advanced features (team mode, custom theme)",
|
|
2041
|
+
baseUrl: "",
|
|
2042
|
+
// Empty = use Claude Code defaults (no ANTHROPIC_BASE_URL override)
|
|
2043
|
+
env: {
|
|
2044
|
+
// Only cosmetic settings - no auth or model overrides
|
|
2045
|
+
CC_MIRROR_SPLASH: 1,
|
|
2046
|
+
CC_MIRROR_PROVIDER_LABEL: "Mirror Claude",
|
|
2047
|
+
CC_MIRROR_SPLASH_STYLE: "mirror"
|
|
2048
|
+
},
|
|
2049
|
+
apiKeyLabel: "",
|
|
2050
|
+
// Empty = skip API key prompt
|
|
2051
|
+
authMode: "none",
|
|
2052
|
+
// No auth handling - user authenticates via normal Claude flow
|
|
2053
|
+
credentialOptional: true,
|
|
2054
|
+
// No credentials required at create time
|
|
2055
|
+
enablesTeamMode: true,
|
|
2056
|
+
// Auto-enable team mode patch
|
|
2057
|
+
noPromptPack: true
|
|
2058
|
+
// Skip prompt pack (pure Claude experience)
|
|
2059
|
+
},
|
|
1834
2060
|
custom: {
|
|
1835
2061
|
key: "custom",
|
|
1836
2062
|
label: "Custom",
|
|
@@ -1876,6 +2102,19 @@ var buildEnv = ({ providerKey, baseUrl, apiKey, extraEnv, modelOverrides }) => {
|
|
|
1876
2102
|
}
|
|
1877
2103
|
const env = { ...provider.env };
|
|
1878
2104
|
const authMode = provider.authMode ?? "apiKey";
|
|
2105
|
+
if (authMode === "none") {
|
|
2106
|
+
if (Array.isArray(extraEnv)) {
|
|
2107
|
+
for (const entry of extraEnv) {
|
|
2108
|
+
const idx = entry.indexOf("=");
|
|
2109
|
+
if (idx === -1) continue;
|
|
2110
|
+
const key = entry.slice(0, idx).trim();
|
|
2111
|
+
const value = entry.slice(idx + 1).trim();
|
|
2112
|
+
if (!key) continue;
|
|
2113
|
+
env[key] = value;
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
return env;
|
|
2117
|
+
}
|
|
1879
2118
|
if (!Object.hasOwn(env, "DISABLE_AUTOUPDATER")) {
|
|
1880
2119
|
env.DISABLE_AUTOUPDATER = "1";
|
|
1881
2120
|
}
|
|
@@ -2050,12 +2289,309 @@ var InstallNpmStep = class {
|
|
|
2050
2289
|
}
|
|
2051
2290
|
};
|
|
2052
2291
|
|
|
2053
|
-
// src/core/variant-builder/steps/
|
|
2292
|
+
// src/core/variant-builder/steps/TeamModeStep.ts
|
|
2293
|
+
import fs7 from "node:fs";
|
|
2054
2294
|
import path8 from "node:path";
|
|
2055
2295
|
|
|
2056
|
-
// src/core/
|
|
2296
|
+
// src/core/skills.ts
|
|
2057
2297
|
import fs6 from "node:fs";
|
|
2298
|
+
import os4 from "node:os";
|
|
2058
2299
|
import path7 from "node:path";
|
|
2300
|
+
import { spawn as spawn3, spawnSync as spawnSync4 } from "node:child_process";
|
|
2301
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
2302
|
+
var DEV_BROWSER_REPO = "https://github.com/SawyerHood/dev-browser.git";
|
|
2303
|
+
var DEV_BROWSER_ARCHIVE = "https://github.com/SawyerHood/dev-browser/archive/refs/heads/main.tar.gz";
|
|
2304
|
+
var SKILL_SUBDIR = path7.join("skills", "dev-browser");
|
|
2305
|
+
var MANAGED_MARKER = ".cc-mirror-managed";
|
|
2306
|
+
var ensureDir2 = (dir) => {
|
|
2307
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
2308
|
+
};
|
|
2309
|
+
var copyDir = (source, target) => {
|
|
2310
|
+
fs6.cpSync(source, target, { recursive: true });
|
|
2311
|
+
};
|
|
2312
|
+
var resolveSkillSourceDir = (repoDir) => {
|
|
2313
|
+
const direct = path7.join(repoDir, SKILL_SUBDIR);
|
|
2314
|
+
if (fs6.existsSync(direct)) return direct;
|
|
2315
|
+
const nested = fs6.readdirSync(repoDir).find((entry) => entry.startsWith("dev-browser-"));
|
|
2316
|
+
if (nested) {
|
|
2317
|
+
const candidate = path7.join(repoDir, nested, SKILL_SUBDIR);
|
|
2318
|
+
if (fs6.existsSync(candidate)) return candidate;
|
|
2319
|
+
}
|
|
2320
|
+
return null;
|
|
2321
|
+
};
|
|
2322
|
+
var cloneRepo = (targetDir) => {
|
|
2323
|
+
if (!commandExists("git")) return { ok: false, message: "git not found" };
|
|
2324
|
+
const result = spawnSync4("git", ["clone", "--depth", "1", DEV_BROWSER_REPO, targetDir], {
|
|
2325
|
+
encoding: "utf8"
|
|
2326
|
+
});
|
|
2327
|
+
if (result.status === 0) return { ok: true };
|
|
2328
|
+
return { ok: false, message: result.stderr?.trim() || result.stdout?.trim() || "git clone failed" };
|
|
2329
|
+
};
|
|
2330
|
+
var downloadArchive = (targetDir) => {
|
|
2331
|
+
if (!commandExists("curl") || !commandExists("tar")) {
|
|
2332
|
+
return { ok: false, message: "curl or tar not found" };
|
|
2333
|
+
}
|
|
2334
|
+
const archivePath = path7.join(targetDir, "dev-browser.tar.gz");
|
|
2335
|
+
const curlResult = spawnSync4("curl", ["-L", "-o", archivePath, DEV_BROWSER_ARCHIVE], { encoding: "utf8" });
|
|
2336
|
+
if (curlResult.status !== 0) {
|
|
2337
|
+
return { ok: false, message: curlResult.stderr?.trim() || "curl failed" };
|
|
2338
|
+
}
|
|
2339
|
+
const tarResult = spawnSync4("tar", ["-xzf", archivePath, "-C", targetDir], { encoding: "utf8" });
|
|
2340
|
+
if (tarResult.status !== 0) {
|
|
2341
|
+
return { ok: false, message: tarResult.stderr?.trim() || "tar extract failed" };
|
|
2342
|
+
}
|
|
2343
|
+
return { ok: true };
|
|
2344
|
+
};
|
|
2345
|
+
var ensureDevBrowserSkill = (opts) => {
|
|
2346
|
+
if (!opts.install) {
|
|
2347
|
+
return { status: "skipped", message: "skill install disabled" };
|
|
2348
|
+
}
|
|
2349
|
+
const skillRoot = opts.targetDir || path7.join(os4.homedir(), ".claude", "skills");
|
|
2350
|
+
const targetDir = path7.join(skillRoot, "dev-browser");
|
|
2351
|
+
const markerPath = path7.join(targetDir, MANAGED_MARKER);
|
|
2352
|
+
const exists = fs6.existsSync(targetDir);
|
|
2353
|
+
const managed = exists && fs6.existsSync(markerPath);
|
|
2354
|
+
if (exists && !managed && !opts.update) {
|
|
2355
|
+
return { status: "skipped", message: "existing skill is user-managed", path: targetDir };
|
|
2356
|
+
}
|
|
2357
|
+
ensureDir2(skillRoot);
|
|
2358
|
+
const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "cc-mirror-skill-"));
|
|
2359
|
+
try {
|
|
2360
|
+
let fetchResult = cloneRepo(tmpDir);
|
|
2361
|
+
if (!fetchResult.ok) {
|
|
2362
|
+
fetchResult = downloadArchive(tmpDir);
|
|
2363
|
+
}
|
|
2364
|
+
if (!fetchResult.ok) {
|
|
2365
|
+
return { status: "failed", message: fetchResult.message || "skill fetch failed" };
|
|
2366
|
+
}
|
|
2367
|
+
const sourceDir = resolveSkillSourceDir(tmpDir);
|
|
2368
|
+
if (!sourceDir) {
|
|
2369
|
+
return { status: "failed", message: "skill source not found after download" };
|
|
2370
|
+
}
|
|
2371
|
+
if (exists) {
|
|
2372
|
+
fs6.rmSync(targetDir, { recursive: true, force: true });
|
|
2373
|
+
}
|
|
2374
|
+
copyDir(sourceDir, targetDir);
|
|
2375
|
+
fs6.writeFileSync(
|
|
2376
|
+
markerPath,
|
|
2377
|
+
JSON.stringify({ managedBy: "cc-mirror", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
2378
|
+
);
|
|
2379
|
+
return { status: exists ? "updated" : "installed", path: targetDir };
|
|
2380
|
+
} catch (error) {
|
|
2381
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2382
|
+
return { status: "failed", message };
|
|
2383
|
+
} finally {
|
|
2384
|
+
fs6.rmSync(tmpDir, { recursive: true, force: true });
|
|
2385
|
+
}
|
|
2386
|
+
};
|
|
2387
|
+
var ORCHESTRATOR_SKILL_NAME = "multi-agent-orchestrator";
|
|
2388
|
+
var findBundledSkillDir = () => {
|
|
2389
|
+
const thisFile = fileURLToPath2(import.meta.url);
|
|
2390
|
+
const thisDir = path7.dirname(thisFile);
|
|
2391
|
+
const devPath = path7.join(thisDir, "..", "skills", ORCHESTRATOR_SKILL_NAME);
|
|
2392
|
+
if (fs6.existsSync(devPath)) return devPath;
|
|
2393
|
+
const distPath = path7.join(thisDir, "skills", ORCHESTRATOR_SKILL_NAME);
|
|
2394
|
+
if (fs6.existsSync(distPath)) return distPath;
|
|
2395
|
+
const distPath2 = path7.join(thisDir, "..", "skills", ORCHESTRATOR_SKILL_NAME);
|
|
2396
|
+
if (fs6.existsSync(distPath2)) return distPath2;
|
|
2397
|
+
return null;
|
|
2398
|
+
};
|
|
2399
|
+
var installOrchestratorSkill = (configDir) => {
|
|
2400
|
+
const sourceDir = findBundledSkillDir();
|
|
2401
|
+
if (!sourceDir) {
|
|
2402
|
+
return { status: "failed", message: "bundled orchestrator skill not found" };
|
|
2403
|
+
}
|
|
2404
|
+
const skillsDir = path7.join(configDir, "skills");
|
|
2405
|
+
const targetDir = path7.join(skillsDir, ORCHESTRATOR_SKILL_NAME);
|
|
2406
|
+
const markerPath = path7.join(targetDir, MANAGED_MARKER);
|
|
2407
|
+
try {
|
|
2408
|
+
ensureDir2(skillsDir);
|
|
2409
|
+
if (fs6.existsSync(targetDir) && !fs6.existsSync(markerPath)) {
|
|
2410
|
+
return { status: "skipped", message: "existing skill is user-managed", path: targetDir };
|
|
2411
|
+
}
|
|
2412
|
+
if (fs6.existsSync(targetDir)) {
|
|
2413
|
+
fs6.rmSync(targetDir, { recursive: true, force: true });
|
|
2414
|
+
}
|
|
2415
|
+
copyDir(sourceDir, targetDir);
|
|
2416
|
+
fs6.writeFileSync(
|
|
2417
|
+
markerPath,
|
|
2418
|
+
JSON.stringify({ managedBy: "cc-mirror", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
2419
|
+
);
|
|
2420
|
+
return { status: "installed", path: targetDir };
|
|
2421
|
+
} catch (error) {
|
|
2422
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2423
|
+
return { status: "failed", message };
|
|
2424
|
+
}
|
|
2425
|
+
};
|
|
2426
|
+
var removeOrchestratorSkill = (configDir) => {
|
|
2427
|
+
const skillsDir = path7.join(configDir, "skills");
|
|
2428
|
+
const targetDir = path7.join(skillsDir, ORCHESTRATOR_SKILL_NAME);
|
|
2429
|
+
const markerPath = path7.join(targetDir, MANAGED_MARKER);
|
|
2430
|
+
if (!fs6.existsSync(targetDir)) {
|
|
2431
|
+
return { status: "skipped", message: "skill not installed" };
|
|
2432
|
+
}
|
|
2433
|
+
if (!fs6.existsSync(markerPath)) {
|
|
2434
|
+
return { status: "skipped", message: "skill is user-managed, not removing" };
|
|
2435
|
+
}
|
|
2436
|
+
try {
|
|
2437
|
+
fs6.rmSync(targetDir, { recursive: true, force: true });
|
|
2438
|
+
return { status: "removed", path: targetDir };
|
|
2439
|
+
} catch (error) {
|
|
2440
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2441
|
+
return { status: "failed", message };
|
|
2442
|
+
}
|
|
2443
|
+
};
|
|
2444
|
+
var spawnAsync = (cmd, args) => {
|
|
2445
|
+
return new Promise((resolve) => {
|
|
2446
|
+
const child = spawn3(cmd, args, { stdio: "pipe" });
|
|
2447
|
+
let stderr = "";
|
|
2448
|
+
let stdout = "";
|
|
2449
|
+
child.stdout?.on("data", (d) => {
|
|
2450
|
+
stdout += d.toString();
|
|
2451
|
+
});
|
|
2452
|
+
child.stderr?.on("data", (d) => {
|
|
2453
|
+
stderr += d.toString();
|
|
2454
|
+
});
|
|
2455
|
+
child.on("close", (code) => {
|
|
2456
|
+
if (code === 0) resolve({ ok: true });
|
|
2457
|
+
else resolve({ ok: false, message: stderr.trim() || stdout.trim() || `${cmd} failed` });
|
|
2458
|
+
});
|
|
2459
|
+
child.on("error", (err) => resolve({ ok: false, message: err.message }));
|
|
2460
|
+
});
|
|
2461
|
+
};
|
|
2462
|
+
var cloneRepoAsync = async (targetDir) => {
|
|
2463
|
+
if (!commandExists("git")) return { ok: false, message: "git not found" };
|
|
2464
|
+
return spawnAsync("git", ["clone", "--depth", "1", DEV_BROWSER_REPO, targetDir]);
|
|
2465
|
+
};
|
|
2466
|
+
var downloadArchiveAsync = async (targetDir) => {
|
|
2467
|
+
if (!commandExists("curl") || !commandExists("tar")) {
|
|
2468
|
+
return { ok: false, message: "curl or tar not found" };
|
|
2469
|
+
}
|
|
2470
|
+
const archivePath = path7.join(targetDir, "dev-browser.tar.gz");
|
|
2471
|
+
const curlResult = await spawnAsync("curl", ["-L", "-o", archivePath, DEV_BROWSER_ARCHIVE]);
|
|
2472
|
+
if (!curlResult.ok) return curlResult;
|
|
2473
|
+
return spawnAsync("tar", ["-xzf", archivePath, "-C", targetDir]);
|
|
2474
|
+
};
|
|
2475
|
+
var ensureDevBrowserSkillAsync = async (opts) => {
|
|
2476
|
+
if (!opts.install) {
|
|
2477
|
+
return { status: "skipped", message: "skill install disabled" };
|
|
2478
|
+
}
|
|
2479
|
+
const skillRoot = opts.targetDir || path7.join(os4.homedir(), ".claude", "skills");
|
|
2480
|
+
const targetDir = path7.join(skillRoot, "dev-browser");
|
|
2481
|
+
const markerPath = path7.join(targetDir, MANAGED_MARKER);
|
|
2482
|
+
const exists = fs6.existsSync(targetDir);
|
|
2483
|
+
const managed = exists && fs6.existsSync(markerPath);
|
|
2484
|
+
if (exists && !managed && !opts.update) {
|
|
2485
|
+
return { status: "skipped", message: "existing skill is user-managed", path: targetDir };
|
|
2486
|
+
}
|
|
2487
|
+
ensureDir2(skillRoot);
|
|
2488
|
+
const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "cc-mirror-skill-"));
|
|
2489
|
+
try {
|
|
2490
|
+
let fetchResult = await cloneRepoAsync(tmpDir);
|
|
2491
|
+
if (!fetchResult.ok) {
|
|
2492
|
+
fetchResult = await downloadArchiveAsync(tmpDir);
|
|
2493
|
+
}
|
|
2494
|
+
if (!fetchResult.ok) {
|
|
2495
|
+
return { status: "failed", message: fetchResult.message || "skill fetch failed" };
|
|
2496
|
+
}
|
|
2497
|
+
const sourceDir = resolveSkillSourceDir(tmpDir);
|
|
2498
|
+
if (!sourceDir) {
|
|
2499
|
+
return { status: "failed", message: "skill source not found after download" };
|
|
2500
|
+
}
|
|
2501
|
+
if (exists) {
|
|
2502
|
+
fs6.rmSync(targetDir, { recursive: true, force: true });
|
|
2503
|
+
}
|
|
2504
|
+
copyDir(sourceDir, targetDir);
|
|
2505
|
+
fs6.writeFileSync(
|
|
2506
|
+
markerPath,
|
|
2507
|
+
JSON.stringify({ managedBy: "cc-mirror", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
2508
|
+
);
|
|
2509
|
+
return { status: exists ? "updated" : "installed", path: targetDir };
|
|
2510
|
+
} catch (error) {
|
|
2511
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2512
|
+
return { status: "failed", message };
|
|
2513
|
+
} finally {
|
|
2514
|
+
fs6.rmSync(tmpDir, { recursive: true, force: true });
|
|
2515
|
+
}
|
|
2516
|
+
};
|
|
2517
|
+
|
|
2518
|
+
// src/core/variant-builder/steps/TeamModeStep.ts
|
|
2519
|
+
var TEAM_MODE_DISABLED = "function sU(){return!1}";
|
|
2520
|
+
var TEAM_MODE_ENABLED = "function sU(){return!0}";
|
|
2521
|
+
var TeamModeStep = class {
|
|
2522
|
+
name = "TeamMode";
|
|
2523
|
+
shouldEnableTeamMode(ctx) {
|
|
2524
|
+
return Boolean(ctx.params.enableTeamMode) || Boolean(ctx.provider.enablesTeamMode);
|
|
2525
|
+
}
|
|
2526
|
+
execute(ctx) {
|
|
2527
|
+
if (!this.shouldEnableTeamMode(ctx)) return;
|
|
2528
|
+
ctx.report("Enabling team mode...");
|
|
2529
|
+
this.patchCli(ctx);
|
|
2530
|
+
}
|
|
2531
|
+
async executeAsync(ctx) {
|
|
2532
|
+
if (!this.shouldEnableTeamMode(ctx)) return;
|
|
2533
|
+
await ctx.report("Enabling team mode...");
|
|
2534
|
+
this.patchCli(ctx);
|
|
2535
|
+
}
|
|
2536
|
+
patchCli(ctx) {
|
|
2537
|
+
const { state, params, paths } = ctx;
|
|
2538
|
+
const cliPath = path8.join(paths.npmDir, "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
2539
|
+
const backupPath = `${cliPath}.backup`;
|
|
2540
|
+
if (!fs7.existsSync(cliPath)) {
|
|
2541
|
+
state.notes.push("Warning: cli.js not found, skipping team mode patch");
|
|
2542
|
+
return;
|
|
2543
|
+
}
|
|
2544
|
+
if (!fs7.existsSync(backupPath)) {
|
|
2545
|
+
fs7.copyFileSync(cliPath, backupPath);
|
|
2546
|
+
}
|
|
2547
|
+
let content = fs7.readFileSync(cliPath, "utf8");
|
|
2548
|
+
if (content.includes(TEAM_MODE_ENABLED)) {
|
|
2549
|
+
state.notes.push("Team mode already enabled");
|
|
2550
|
+
return;
|
|
2551
|
+
}
|
|
2552
|
+
if (!content.includes(TEAM_MODE_DISABLED)) {
|
|
2553
|
+
state.notes.push("Warning: Team mode function not found in cli.js, patch may not work");
|
|
2554
|
+
return;
|
|
2555
|
+
}
|
|
2556
|
+
content = content.replace(TEAM_MODE_DISABLED, TEAM_MODE_ENABLED);
|
|
2557
|
+
fs7.writeFileSync(cliPath, content);
|
|
2558
|
+
const verifyContent = fs7.readFileSync(cliPath, "utf8");
|
|
2559
|
+
if (!verifyContent.includes(TEAM_MODE_ENABLED)) {
|
|
2560
|
+
state.notes.push("Warning: Team mode patch verification failed");
|
|
2561
|
+
return;
|
|
2562
|
+
}
|
|
2563
|
+
const settingsPath = path8.join(paths.configDir, "settings.json");
|
|
2564
|
+
if (fs7.existsSync(settingsPath)) {
|
|
2565
|
+
try {
|
|
2566
|
+
const settings = JSON.parse(fs7.readFileSync(settingsPath, "utf8"));
|
|
2567
|
+
settings.env = settings.env || {};
|
|
2568
|
+
if (!settings.env.CLAUDE_CODE_TEAM_NAME) {
|
|
2569
|
+
settings.env.CLAUDE_CODE_TEAM_NAME = params.name;
|
|
2570
|
+
}
|
|
2571
|
+
if (!settings.env.CLAUDE_CODE_AGENT_TYPE) {
|
|
2572
|
+
settings.env.CLAUDE_CODE_AGENT_TYPE = "team-lead";
|
|
2573
|
+
}
|
|
2574
|
+
fs7.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
2575
|
+
} catch {
|
|
2576
|
+
state.notes.push("Warning: Could not update settings.json with team env vars");
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
state.notes.push("Team mode enabled successfully");
|
|
2580
|
+
const skillResult = installOrchestratorSkill(paths.configDir);
|
|
2581
|
+
if (skillResult.status === "installed") {
|
|
2582
|
+
state.notes.push("Multi-agent orchestrator skill installed");
|
|
2583
|
+
} else if (skillResult.status === "failed") {
|
|
2584
|
+
state.notes.push(`Warning: orchestrator skill install failed: ${skillResult.message}`);
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
};
|
|
2588
|
+
|
|
2589
|
+
// src/core/variant-builder/steps/WriteConfigStep.ts
|
|
2590
|
+
import path10 from "node:path";
|
|
2591
|
+
|
|
2592
|
+
// src/core/claude-config.ts
|
|
2593
|
+
import fs8 from "node:fs";
|
|
2594
|
+
import path9 from "node:path";
|
|
2059
2595
|
var SETTINGS_FILE = "settings.json";
|
|
2060
2596
|
var CLAUDE_CONFIG_FILE = ".claude.json";
|
|
2061
2597
|
var PLACEHOLDER_KEY = "<API_KEY>";
|
|
@@ -2066,7 +2602,7 @@ var toStringOrNull = (value) => {
|
|
|
2066
2602
|
return trimmed;
|
|
2067
2603
|
};
|
|
2068
2604
|
var readSettingsApiKey = (configDir) => {
|
|
2069
|
-
const settingsPath =
|
|
2605
|
+
const settingsPath = path9.join(configDir, SETTINGS_FILE);
|
|
2070
2606
|
const settings = readJson(settingsPath);
|
|
2071
2607
|
if (!settings?.env) return null;
|
|
2072
2608
|
const env = settings.env;
|
|
@@ -2078,7 +2614,7 @@ var ZAI_DENY_TOOLS = [
|
|
|
2078
2614
|
"mcp__web_reader__webReader"
|
|
2079
2615
|
];
|
|
2080
2616
|
var ensureZaiMcpDeny = (configDir) => {
|
|
2081
|
-
const settingsPath =
|
|
2617
|
+
const settingsPath = path9.join(configDir, SETTINGS_FILE);
|
|
2082
2618
|
const existing = readJson(settingsPath) || {};
|
|
2083
2619
|
const permissions = existing.permissions || {};
|
|
2084
2620
|
const deny = Array.isArray(permissions.deny) ? [...permissions.deny] : [];
|
|
@@ -2101,7 +2637,7 @@ var ensureZaiMcpDeny = (configDir) => {
|
|
|
2101
2637
|
return true;
|
|
2102
2638
|
};
|
|
2103
2639
|
var ensureSettingsEnvDefaults = (configDir, defaults) => {
|
|
2104
|
-
const settingsPath =
|
|
2640
|
+
const settingsPath = path9.join(configDir, SETTINGS_FILE);
|
|
2105
2641
|
const existing = readJson(settingsPath) || {};
|
|
2106
2642
|
const env = { ...existing.env ?? {} };
|
|
2107
2643
|
let changed = false;
|
|
@@ -2116,7 +2652,7 @@ var ensureSettingsEnvDefaults = (configDir, defaults) => {
|
|
|
2116
2652
|
return true;
|
|
2117
2653
|
};
|
|
2118
2654
|
var ensureSettingsEnvOverrides = (configDir, overrides) => {
|
|
2119
|
-
const settingsPath =
|
|
2655
|
+
const settingsPath = path9.join(configDir, SETTINGS_FILE);
|
|
2120
2656
|
const existing = readJson(settingsPath) || {};
|
|
2121
2657
|
const env = { ...existing.env ?? {} };
|
|
2122
2658
|
let changed = false;
|
|
@@ -2135,8 +2671,8 @@ var ensureApiKeyApproval = (configDir, apiKey) => {
|
|
|
2135
2671
|
const resolvedKey = toStringOrNull(apiKey) || readSettingsApiKey(configDir);
|
|
2136
2672
|
if (!resolvedKey) return false;
|
|
2137
2673
|
const approvedToken = resolvedKey.slice(-20);
|
|
2138
|
-
const configPath =
|
|
2139
|
-
const exists =
|
|
2674
|
+
const configPath = path9.join(configDir, CLAUDE_CONFIG_FILE);
|
|
2675
|
+
const exists = fs8.existsSync(configPath);
|
|
2140
2676
|
let config = null;
|
|
2141
2677
|
if (exists) {
|
|
2142
2678
|
config = readJson(configPath);
|
|
@@ -2160,8 +2696,8 @@ var ensureApiKeyApproval = (configDir, apiKey) => {
|
|
|
2160
2696
|
return true;
|
|
2161
2697
|
};
|
|
2162
2698
|
var ensureOnboardingState = (configDir, opts = {}) => {
|
|
2163
|
-
const configPath =
|
|
2164
|
-
const exists =
|
|
2699
|
+
const configPath = path9.join(configDir, CLAUDE_CONFIG_FILE);
|
|
2700
|
+
const exists = fs8.existsSync(configPath);
|
|
2165
2701
|
let config = null;
|
|
2166
2702
|
if (exists) {
|
|
2167
2703
|
config = readJson(configPath);
|
|
@@ -2182,7 +2718,7 @@ var ensureOnboardingState = (configDir, opts = {}) => {
|
|
|
2182
2718
|
themeChanged = true;
|
|
2183
2719
|
}
|
|
2184
2720
|
}
|
|
2185
|
-
if (config.hasCompletedOnboarding !== true) {
|
|
2721
|
+
if (!opts.skipOnboardingFlag && config.hasCompletedOnboarding !== true) {
|
|
2186
2722
|
config.hasCompletedOnboarding = true;
|
|
2187
2723
|
changed = true;
|
|
2188
2724
|
onboardingChanged = true;
|
|
@@ -2195,8 +2731,8 @@ var ensureOnboardingState = (configDir, opts = {}) => {
|
|
|
2195
2731
|
};
|
|
2196
2732
|
var ensureMinimaxMcpServer = (configDir, apiKey) => {
|
|
2197
2733
|
const resolvedKey = toStringOrNull(apiKey) || readSettingsApiKey(configDir);
|
|
2198
|
-
const configPath =
|
|
2199
|
-
const exists =
|
|
2734
|
+
const configPath = path9.join(configDir, CLAUDE_CONFIG_FILE);
|
|
2735
|
+
const exists = fs8.existsSync(configPath);
|
|
2200
2736
|
let config = null;
|
|
2201
2737
|
if (exists) {
|
|
2202
2738
|
config = readJson(configPath);
|
|
@@ -2253,7 +2789,7 @@ var WriteConfigStep = class {
|
|
|
2253
2789
|
env.ANTHROPIC_API_KEY = "<API_KEY>";
|
|
2254
2790
|
}
|
|
2255
2791
|
const config = { env };
|
|
2256
|
-
writeJson(
|
|
2792
|
+
writeJson(path10.join(paths.configDir, "settings.json"), config);
|
|
2257
2793
|
state.env = env;
|
|
2258
2794
|
state.resolvedApiKey = typeof env.ANTHROPIC_API_KEY === "string" ? env.ANTHROPIC_API_KEY : void 0;
|
|
2259
2795
|
ensureApiKeyApproval(paths.configDir, state.resolvedApiKey);
|
|
@@ -2293,9 +2829,11 @@ var BrandThemeStep = class {
|
|
|
2293
2829
|
prefs.brandKey = brandKey;
|
|
2294
2830
|
ensureTweakccConfig(paths.tweakDir, brandKey);
|
|
2295
2831
|
const brandThemeId = !params.noTweak && brandKey ? getBrandThemeId(brandKey) : null;
|
|
2832
|
+
const skipOnboardingFlag = params.providerKey === "mirror";
|
|
2296
2833
|
const onboarding = ensureOnboardingState(paths.configDir, {
|
|
2297
2834
|
themeId: brandThemeId ?? "dark",
|
|
2298
|
-
forceTheme: Boolean(brandThemeId)
|
|
2835
|
+
forceTheme: Boolean(brandThemeId),
|
|
2836
|
+
skipOnboardingFlag
|
|
2299
2837
|
});
|
|
2300
2838
|
if (onboarding.themeChanged) {
|
|
2301
2839
|
state.notes.push(`Default theme set to ${brandThemeId ?? "dark"}.`);
|
|
@@ -2303,6 +2841,9 @@ var BrandThemeStep = class {
|
|
|
2303
2841
|
if (onboarding.onboardingChanged) {
|
|
2304
2842
|
state.notes.push("Onboarding marked complete.");
|
|
2305
2843
|
}
|
|
2844
|
+
if (skipOnboardingFlag) {
|
|
2845
|
+
state.notes.push("Login screen enabled (authenticate when you run the variant).");
|
|
2846
|
+
}
|
|
2306
2847
|
if (params.providerKey === "minimax") {
|
|
2307
2848
|
ctx.report("Configuring MiniMax MCP server...");
|
|
2308
2849
|
ensureMinimaxMcpServer(paths.configDir, state.resolvedApiKey);
|
|
@@ -2320,8 +2861,8 @@ var BrandThemeStep = class {
|
|
|
2320
2861
|
};
|
|
2321
2862
|
|
|
2322
2863
|
// src/core/prompt-pack.ts
|
|
2323
|
-
import
|
|
2324
|
-
import
|
|
2864
|
+
import fs9 from "node:fs";
|
|
2865
|
+
import path11 from "node:path";
|
|
2325
2866
|
|
|
2326
2867
|
// src/core/prompt-pack/sanitize.ts
|
|
2327
2868
|
var BACKTICK_REGEX = /`/g;
|
|
@@ -2736,17 +3277,17 @@ ${block}
|
|
|
2736
3277
|
};
|
|
2737
3278
|
var updatePromptFile = (filePath, overlay) => {
|
|
2738
3279
|
if (!overlay) return false;
|
|
2739
|
-
if (!
|
|
2740
|
-
const content =
|
|
3280
|
+
if (!fs9.existsSync(filePath)) return false;
|
|
3281
|
+
const content = fs9.readFileSync(filePath, "utf8");
|
|
2741
3282
|
const updated = insertOverlay(content, overlay);
|
|
2742
3283
|
if (updated === content) return false;
|
|
2743
|
-
|
|
3284
|
+
fs9.writeFileSync(filePath, updated);
|
|
2744
3285
|
return true;
|
|
2745
3286
|
};
|
|
2746
3287
|
var applyOverlays = (systemPromptsDir, overlays) => {
|
|
2747
3288
|
const updated = [];
|
|
2748
3289
|
for (const target of PROMPT_PACK_TARGETS) {
|
|
2749
|
-
const filePath =
|
|
3290
|
+
const filePath = path11.join(systemPromptsDir, target.filename);
|
|
2750
3291
|
const overlay = overlays[target.key];
|
|
2751
3292
|
if (updatePromptFile(filePath, overlay)) {
|
|
2752
3293
|
updated.push(target.filename);
|
|
@@ -2759,7 +3300,7 @@ var applyPromptPack = (tweakDir, providerKey, mode = "minimal") => {
|
|
|
2759
3300
|
return { changed: false, updated: [], mode };
|
|
2760
3301
|
}
|
|
2761
3302
|
const overlays = resolveOverlays(providerKey, mode);
|
|
2762
|
-
const systemPromptsDir =
|
|
3303
|
+
const systemPromptsDir = path11.join(tweakDir, "system-prompts");
|
|
2763
3304
|
const updated = applyOverlays(systemPromptsDir, overlays);
|
|
2764
3305
|
return { changed: updated.length > 0, updated, mode };
|
|
2765
3306
|
};
|
|
@@ -2826,10 +3367,10 @@ ${reapply.stdout ?? ""}`.trim();
|
|
|
2826
3367
|
};
|
|
2827
3368
|
|
|
2828
3369
|
// src/core/wrapper.ts
|
|
2829
|
-
import
|
|
2830
|
-
import
|
|
3370
|
+
import fs10 from "node:fs";
|
|
3371
|
+
import path12 from "node:path";
|
|
2831
3372
|
var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
2832
|
-
const tweakDir =
|
|
3373
|
+
const tweakDir = path12.join(path12.dirname(configDir), "tweakcc");
|
|
2833
3374
|
const execLine = runtime === "node" ? `exec node "${binaryPath}" "$@"` : `exec "${binaryPath}" "$@"`;
|
|
2834
3375
|
const envLoader = [
|
|
2835
3376
|
"if command -v node >/dev/null 2>&1; then",
|
|
@@ -2901,6 +3442,15 @@ var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
|
2901
3442
|
// Deep blue
|
|
2902
3443
|
ccrDim: "\x1B[38;5;31m",
|
|
2903
3444
|
// Muted blue
|
|
3445
|
+
// Mirror: Silver/Chrome with electric blue
|
|
3446
|
+
mirPrimary: "\x1B[38;5;252m",
|
|
3447
|
+
// Silver/light gray
|
|
3448
|
+
mirSecondary: "\x1B[38;5;250m",
|
|
3449
|
+
// Platinum
|
|
3450
|
+
mirAccent: "\x1B[38;5;45m",
|
|
3451
|
+
// Electric cyan
|
|
3452
|
+
mirDim: "\x1B[38;5;243m",
|
|
3453
|
+
// Muted silver
|
|
2904
3454
|
// Default: White/Gray
|
|
2905
3455
|
defPrimary: "\x1B[38;5;255m",
|
|
2906
3456
|
// White
|
|
@@ -2985,6 +3535,22 @@ var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
|
2985
3535
|
"CCMCCR",
|
|
2986
3536
|
' __cc_show_label="0"',
|
|
2987
3537
|
" ;;",
|
|
3538
|
+
" mirror)",
|
|
3539
|
+
" cat <<'CCMMIR'",
|
|
3540
|
+
"",
|
|
3541
|
+
`${C.mirPrimary} \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557${C.reset}`,
|
|
3542
|
+
`${C.mirPrimary} \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557${C.reset}`,
|
|
3543
|
+
`${C.mirSecondary} \u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D${C.reset}`,
|
|
3544
|
+
`${C.mirSecondary} \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557${C.reset}`,
|
|
3545
|
+
`${C.mirAccent} \u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551${C.reset}`,
|
|
3546
|
+
`${C.mirAccent} \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D${C.reset}`,
|
|
3547
|
+
"",
|
|
3548
|
+
`${C.mirDim} \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${C.mirAccent}\u25C7${C.mirDim}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${C.reset}`,
|
|
3549
|
+
`${C.mirSecondary} Claude ${C.mirDim}\u2501${C.mirSecondary} Pure Reflection${C.reset}`,
|
|
3550
|
+
"",
|
|
3551
|
+
"CCMMIR",
|
|
3552
|
+
' __cc_show_label="0"',
|
|
3553
|
+
" ;;",
|
|
2988
3554
|
" *)",
|
|
2989
3555
|
" cat <<'CCMGEN'",
|
|
2990
3556
|
"",
|
|
@@ -3019,7 +3585,7 @@ var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
|
3019
3585
|
execLine,
|
|
3020
3586
|
""
|
|
3021
3587
|
].join("\n");
|
|
3022
|
-
|
|
3588
|
+
fs10.writeFileSync(wrapperPath, content, { mode: 493 });
|
|
3023
3589
|
};
|
|
3024
3590
|
|
|
3025
3591
|
// src/core/variant-builder/steps/WrapperStep.ts
|
|
@@ -3036,9 +3602,9 @@ var WrapperStep = class {
|
|
|
3036
3602
|
};
|
|
3037
3603
|
|
|
3038
3604
|
// src/core/shell-env.ts
|
|
3039
|
-
import
|
|
3040
|
-
import
|
|
3041
|
-
import
|
|
3605
|
+
import fs11 from "node:fs";
|
|
3606
|
+
import os5 from "node:os";
|
|
3607
|
+
import path13 from "node:path";
|
|
3042
3608
|
var SETTINGS_FILE2 = "settings.json";
|
|
3043
3609
|
var BLOCK_START = "# cc-mirror: Z.ai env start";
|
|
3044
3610
|
var BLOCK_END = "# cc-mirror: Z.ai env end";
|
|
@@ -3050,22 +3616,22 @@ var normalizeApiKey = (value) => {
|
|
|
3050
3616
|
return trimmed;
|
|
3051
3617
|
};
|
|
3052
3618
|
var resolveShellProfile = () => {
|
|
3053
|
-
const home =
|
|
3619
|
+
const home = os5.homedir();
|
|
3054
3620
|
const shell = process.env.SHELL || "";
|
|
3055
|
-
const name =
|
|
3621
|
+
const name = path13.basename(shell);
|
|
3056
3622
|
if (name === "zsh") {
|
|
3057
|
-
return
|
|
3623
|
+
return path13.join(home, ".zshrc");
|
|
3058
3624
|
}
|
|
3059
3625
|
if (name === "bash") {
|
|
3060
|
-
const bashrc =
|
|
3061
|
-
if (
|
|
3062
|
-
return
|
|
3626
|
+
const bashrc = path13.join(home, ".bashrc");
|
|
3627
|
+
if (fs11.existsSync(bashrc)) return bashrc;
|
|
3628
|
+
return path13.join(home, ".bash_profile");
|
|
3063
3629
|
}
|
|
3064
3630
|
return null;
|
|
3065
3631
|
};
|
|
3066
3632
|
var readSettingsApiKey2 = (configDir) => {
|
|
3067
|
-
const settingsPath =
|
|
3068
|
-
if (!
|
|
3633
|
+
const settingsPath = path13.join(configDir, SETTINGS_FILE2);
|
|
3634
|
+
if (!fs11.existsSync(settingsPath)) return null;
|
|
3069
3635
|
const settings = readJson(settingsPath);
|
|
3070
3636
|
const key = settings?.env?.ANTHROPIC_API_KEY;
|
|
3071
3637
|
if (typeof key !== "string") return null;
|
|
@@ -3120,7 +3686,7 @@ var ensureZaiShellEnv = (opts) => {
|
|
|
3120
3686
|
if (!profile) {
|
|
3121
3687
|
return { status: "failed", message: "Unsupported shell; set Z_AI_API_KEY manually" };
|
|
3122
3688
|
}
|
|
3123
|
-
const existing =
|
|
3689
|
+
const existing = fs11.existsSync(profile) ? fs11.readFileSync(profile, "utf8") : "";
|
|
3124
3690
|
if (hasZaiKeyInProfile(existing)) {
|
|
3125
3691
|
return { status: "skipped", message: "Z_AI_API_KEY already set in shell profile", path: profile };
|
|
3126
3692
|
}
|
|
@@ -3128,7 +3694,7 @@ var ensureZaiShellEnv = (opts) => {
|
|
|
3128
3694
|
if (next === existing) {
|
|
3129
3695
|
return { status: "skipped", message: "Shell profile already up to date", path: profile };
|
|
3130
3696
|
}
|
|
3131
|
-
|
|
3697
|
+
fs11.writeFileSync(profile, next);
|
|
3132
3698
|
return { status: "updated", path: profile, message: `Run: source ${profile}` };
|
|
3133
3699
|
};
|
|
3134
3700
|
|
|
@@ -3167,173 +3733,7 @@ var ShellEnvStep = class {
|
|
|
3167
3733
|
};
|
|
3168
3734
|
|
|
3169
3735
|
// src/core/variant-builder/steps/SkillInstallStep.ts
|
|
3170
|
-
import
|
|
3171
|
-
|
|
3172
|
-
// src/core/skills.ts
|
|
3173
|
-
import fs10 from "node:fs";
|
|
3174
|
-
import os5 from "node:os";
|
|
3175
|
-
import path12 from "node:path";
|
|
3176
|
-
import { spawn as spawn3, spawnSync as spawnSync4 } from "node:child_process";
|
|
3177
|
-
var DEV_BROWSER_REPO = "https://github.com/SawyerHood/dev-browser.git";
|
|
3178
|
-
var DEV_BROWSER_ARCHIVE = "https://github.com/SawyerHood/dev-browser/archive/refs/heads/main.tar.gz";
|
|
3179
|
-
var SKILL_SUBDIR = path12.join("skills", "dev-browser");
|
|
3180
|
-
var MANAGED_MARKER = ".cc-mirror-managed";
|
|
3181
|
-
var ensureDir2 = (dir) => {
|
|
3182
|
-
fs10.mkdirSync(dir, { recursive: true });
|
|
3183
|
-
};
|
|
3184
|
-
var copyDir = (source, target) => {
|
|
3185
|
-
fs10.cpSync(source, target, { recursive: true });
|
|
3186
|
-
};
|
|
3187
|
-
var resolveSkillSourceDir = (repoDir) => {
|
|
3188
|
-
const direct = path12.join(repoDir, SKILL_SUBDIR);
|
|
3189
|
-
if (fs10.existsSync(direct)) return direct;
|
|
3190
|
-
const nested = fs10.readdirSync(repoDir).find((entry) => entry.startsWith("dev-browser-"));
|
|
3191
|
-
if (nested) {
|
|
3192
|
-
const candidate = path12.join(repoDir, nested, SKILL_SUBDIR);
|
|
3193
|
-
if (fs10.existsSync(candidate)) return candidate;
|
|
3194
|
-
}
|
|
3195
|
-
return null;
|
|
3196
|
-
};
|
|
3197
|
-
var cloneRepo = (targetDir) => {
|
|
3198
|
-
if (!commandExists("git")) return { ok: false, message: "git not found" };
|
|
3199
|
-
const result = spawnSync4("git", ["clone", "--depth", "1", DEV_BROWSER_REPO, targetDir], {
|
|
3200
|
-
encoding: "utf8"
|
|
3201
|
-
});
|
|
3202
|
-
if (result.status === 0) return { ok: true };
|
|
3203
|
-
return { ok: false, message: result.stderr?.trim() || result.stdout?.trim() || "git clone failed" };
|
|
3204
|
-
};
|
|
3205
|
-
var downloadArchive = (targetDir) => {
|
|
3206
|
-
if (!commandExists("curl") || !commandExists("tar")) {
|
|
3207
|
-
return { ok: false, message: "curl or tar not found" };
|
|
3208
|
-
}
|
|
3209
|
-
const archivePath = path12.join(targetDir, "dev-browser.tar.gz");
|
|
3210
|
-
const curlResult = spawnSync4("curl", ["-L", "-o", archivePath, DEV_BROWSER_ARCHIVE], { encoding: "utf8" });
|
|
3211
|
-
if (curlResult.status !== 0) {
|
|
3212
|
-
return { ok: false, message: curlResult.stderr?.trim() || "curl failed" };
|
|
3213
|
-
}
|
|
3214
|
-
const tarResult = spawnSync4("tar", ["-xzf", archivePath, "-C", targetDir], { encoding: "utf8" });
|
|
3215
|
-
if (tarResult.status !== 0) {
|
|
3216
|
-
return { ok: false, message: tarResult.stderr?.trim() || "tar extract failed" };
|
|
3217
|
-
}
|
|
3218
|
-
return { ok: true };
|
|
3219
|
-
};
|
|
3220
|
-
var ensureDevBrowserSkill = (opts) => {
|
|
3221
|
-
if (!opts.install) {
|
|
3222
|
-
return { status: "skipped", message: "skill install disabled" };
|
|
3223
|
-
}
|
|
3224
|
-
const skillRoot = opts.targetDir || path12.join(os5.homedir(), ".claude", "skills");
|
|
3225
|
-
const targetDir = path12.join(skillRoot, "dev-browser");
|
|
3226
|
-
const markerPath = path12.join(targetDir, MANAGED_MARKER);
|
|
3227
|
-
const exists = fs10.existsSync(targetDir);
|
|
3228
|
-
const managed = exists && fs10.existsSync(markerPath);
|
|
3229
|
-
if (exists && !managed && !opts.update) {
|
|
3230
|
-
return { status: "skipped", message: "existing skill is user-managed", path: targetDir };
|
|
3231
|
-
}
|
|
3232
|
-
ensureDir2(skillRoot);
|
|
3233
|
-
const tmpDir = fs10.mkdtempSync(path12.join(os5.tmpdir(), "cc-mirror-skill-"));
|
|
3234
|
-
try {
|
|
3235
|
-
let fetchResult = cloneRepo(tmpDir);
|
|
3236
|
-
if (!fetchResult.ok) {
|
|
3237
|
-
fetchResult = downloadArchive(tmpDir);
|
|
3238
|
-
}
|
|
3239
|
-
if (!fetchResult.ok) {
|
|
3240
|
-
return { status: "failed", message: fetchResult.message || "skill fetch failed" };
|
|
3241
|
-
}
|
|
3242
|
-
const sourceDir = resolveSkillSourceDir(tmpDir);
|
|
3243
|
-
if (!sourceDir) {
|
|
3244
|
-
return { status: "failed", message: "skill source not found after download" };
|
|
3245
|
-
}
|
|
3246
|
-
if (exists) {
|
|
3247
|
-
fs10.rmSync(targetDir, { recursive: true, force: true });
|
|
3248
|
-
}
|
|
3249
|
-
copyDir(sourceDir, targetDir);
|
|
3250
|
-
fs10.writeFileSync(
|
|
3251
|
-
markerPath,
|
|
3252
|
-
JSON.stringify({ managedBy: "cc-mirror", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
3253
|
-
);
|
|
3254
|
-
return { status: exists ? "updated" : "installed", path: targetDir };
|
|
3255
|
-
} catch (error) {
|
|
3256
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3257
|
-
return { status: "failed", message };
|
|
3258
|
-
} finally {
|
|
3259
|
-
fs10.rmSync(tmpDir, { recursive: true, force: true });
|
|
3260
|
-
}
|
|
3261
|
-
};
|
|
3262
|
-
var spawnAsync = (cmd, args) => {
|
|
3263
|
-
return new Promise((resolve) => {
|
|
3264
|
-
const child = spawn3(cmd, args, { stdio: "pipe" });
|
|
3265
|
-
let stderr = "";
|
|
3266
|
-
let stdout = "";
|
|
3267
|
-
child.stdout?.on("data", (d) => {
|
|
3268
|
-
stdout += d.toString();
|
|
3269
|
-
});
|
|
3270
|
-
child.stderr?.on("data", (d) => {
|
|
3271
|
-
stderr += d.toString();
|
|
3272
|
-
});
|
|
3273
|
-
child.on("close", (code) => {
|
|
3274
|
-
if (code === 0) resolve({ ok: true });
|
|
3275
|
-
else resolve({ ok: false, message: stderr.trim() || stdout.trim() || `${cmd} failed` });
|
|
3276
|
-
});
|
|
3277
|
-
child.on("error", (err) => resolve({ ok: false, message: err.message }));
|
|
3278
|
-
});
|
|
3279
|
-
};
|
|
3280
|
-
var cloneRepoAsync = async (targetDir) => {
|
|
3281
|
-
if (!commandExists("git")) return { ok: false, message: "git not found" };
|
|
3282
|
-
return spawnAsync("git", ["clone", "--depth", "1", DEV_BROWSER_REPO, targetDir]);
|
|
3283
|
-
};
|
|
3284
|
-
var downloadArchiveAsync = async (targetDir) => {
|
|
3285
|
-
if (!commandExists("curl") || !commandExists("tar")) {
|
|
3286
|
-
return { ok: false, message: "curl or tar not found" };
|
|
3287
|
-
}
|
|
3288
|
-
const archivePath = path12.join(targetDir, "dev-browser.tar.gz");
|
|
3289
|
-
const curlResult = await spawnAsync("curl", ["-L", "-o", archivePath, DEV_BROWSER_ARCHIVE]);
|
|
3290
|
-
if (!curlResult.ok) return curlResult;
|
|
3291
|
-
return spawnAsync("tar", ["-xzf", archivePath, "-C", targetDir]);
|
|
3292
|
-
};
|
|
3293
|
-
var ensureDevBrowserSkillAsync = async (opts) => {
|
|
3294
|
-
if (!opts.install) {
|
|
3295
|
-
return { status: "skipped", message: "skill install disabled" };
|
|
3296
|
-
}
|
|
3297
|
-
const skillRoot = opts.targetDir || path12.join(os5.homedir(), ".claude", "skills");
|
|
3298
|
-
const targetDir = path12.join(skillRoot, "dev-browser");
|
|
3299
|
-
const markerPath = path12.join(targetDir, MANAGED_MARKER);
|
|
3300
|
-
const exists = fs10.existsSync(targetDir);
|
|
3301
|
-
const managed = exists && fs10.existsSync(markerPath);
|
|
3302
|
-
if (exists && !managed && !opts.update) {
|
|
3303
|
-
return { status: "skipped", message: "existing skill is user-managed", path: targetDir };
|
|
3304
|
-
}
|
|
3305
|
-
ensureDir2(skillRoot);
|
|
3306
|
-
const tmpDir = fs10.mkdtempSync(path12.join(os5.tmpdir(), "cc-mirror-skill-"));
|
|
3307
|
-
try {
|
|
3308
|
-
let fetchResult = await cloneRepoAsync(tmpDir);
|
|
3309
|
-
if (!fetchResult.ok) {
|
|
3310
|
-
fetchResult = await downloadArchiveAsync(tmpDir);
|
|
3311
|
-
}
|
|
3312
|
-
if (!fetchResult.ok) {
|
|
3313
|
-
return { status: "failed", message: fetchResult.message || "skill fetch failed" };
|
|
3314
|
-
}
|
|
3315
|
-
const sourceDir = resolveSkillSourceDir(tmpDir);
|
|
3316
|
-
if (!sourceDir) {
|
|
3317
|
-
return { status: "failed", message: "skill source not found after download" };
|
|
3318
|
-
}
|
|
3319
|
-
if (exists) {
|
|
3320
|
-
fs10.rmSync(targetDir, { recursive: true, force: true });
|
|
3321
|
-
}
|
|
3322
|
-
copyDir(sourceDir, targetDir);
|
|
3323
|
-
fs10.writeFileSync(
|
|
3324
|
-
markerPath,
|
|
3325
|
-
JSON.stringify({ managedBy: "cc-mirror", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
3326
|
-
);
|
|
3327
|
-
return { status: exists ? "updated" : "installed", path: targetDir };
|
|
3328
|
-
} catch (error) {
|
|
3329
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3330
|
-
return { status: "failed", message };
|
|
3331
|
-
} finally {
|
|
3332
|
-
fs10.rmSync(tmpDir, { recursive: true, force: true });
|
|
3333
|
-
}
|
|
3334
|
-
};
|
|
3335
|
-
|
|
3336
|
-
// src/core/variant-builder/steps/SkillInstallStep.ts
|
|
3736
|
+
import path14 from "node:path";
|
|
3337
3737
|
var SkillInstallStep = class {
|
|
3338
3738
|
name = "SkillInstall";
|
|
3339
3739
|
execute(ctx) {
|
|
@@ -3345,7 +3745,7 @@ var SkillInstallStep = class {
|
|
|
3345
3745
|
const skillResult = ensureDevBrowserSkill({
|
|
3346
3746
|
install: true,
|
|
3347
3747
|
update: prefs.skillUpdateEnabled,
|
|
3348
|
-
targetDir:
|
|
3748
|
+
targetDir: path14.join(paths.configDir, "skills")
|
|
3349
3749
|
});
|
|
3350
3750
|
if (skillResult.status === "failed") {
|
|
3351
3751
|
state.notes.push(`dev-browser skill install failed: ${skillResult.message || "unknown error"}`);
|
|
@@ -3362,7 +3762,7 @@ var SkillInstallStep = class {
|
|
|
3362
3762
|
const skillResult = await ensureDevBrowserSkillAsync({
|
|
3363
3763
|
install: true,
|
|
3364
3764
|
update: prefs.skillUpdateEnabled,
|
|
3365
|
-
targetDir:
|
|
3765
|
+
targetDir: path14.join(paths.configDir, "skills")
|
|
3366
3766
|
});
|
|
3367
3767
|
if (skillResult.status === "failed") {
|
|
3368
3768
|
state.notes.push(`dev-browser skill install failed: ${skillResult.message || "unknown error"}`);
|
|
@@ -3373,7 +3773,7 @@ var SkillInstallStep = class {
|
|
|
3373
3773
|
};
|
|
3374
3774
|
|
|
3375
3775
|
// src/core/variant-builder/steps/FinalizeStep.ts
|
|
3376
|
-
import
|
|
3776
|
+
import path15 from "node:path";
|
|
3377
3777
|
var FinalizeStep = class {
|
|
3378
3778
|
name = "Finalize";
|
|
3379
3779
|
execute(ctx) {
|
|
@@ -3385,7 +3785,8 @@ var FinalizeStep = class {
|
|
|
3385
3785
|
this.finalize(ctx);
|
|
3386
3786
|
}
|
|
3387
3787
|
finalize(ctx) {
|
|
3388
|
-
const { params, paths, prefs, state } = ctx;
|
|
3788
|
+
const { params, paths, prefs, state, provider } = ctx;
|
|
3789
|
+
const teamModeEnabled = Boolean(params.enableTeamMode) || Boolean(provider.enablesTeamMode);
|
|
3389
3790
|
const meta = {
|
|
3390
3791
|
name: params.name,
|
|
3391
3792
|
provider: params.providerKey,
|
|
@@ -3404,9 +3805,10 @@ var FinalizeStep = class {
|
|
|
3404
3805
|
installType: "npm",
|
|
3405
3806
|
npmDir: paths.npmDir,
|
|
3406
3807
|
npmPackage: prefs.resolvedNpmPackage,
|
|
3407
|
-
npmVersion: prefs.resolvedNpmVersion
|
|
3808
|
+
npmVersion: prefs.resolvedNpmVersion,
|
|
3809
|
+
teamModeEnabled
|
|
3408
3810
|
};
|
|
3409
|
-
writeJson(
|
|
3811
|
+
writeJson(path15.join(paths.variantDir, "variant.json"), meta);
|
|
3410
3812
|
state.meta = meta;
|
|
3411
3813
|
}
|
|
3412
3814
|
};
|
|
@@ -3414,7 +3816,10 @@ var FinalizeStep = class {
|
|
|
3414
3816
|
// src/core/variant-builder/VariantBuilder.ts
|
|
3415
3817
|
var normalizeNpmPackage = (value) => value && value.trim().length > 0 ? value.trim() : DEFAULT_NPM_PACKAGE;
|
|
3416
3818
|
var normalizeNpmVersion = () => DEFAULT_NPM_VERSION;
|
|
3417
|
-
var shouldEnablePromptPack = (providerKey) =>
|
|
3819
|
+
var shouldEnablePromptPack = (providerKey, provider) => {
|
|
3820
|
+
if (provider?.noPromptPack) return false;
|
|
3821
|
+
return providerKey === "zai" || providerKey === "minimax";
|
|
3822
|
+
};
|
|
3418
3823
|
var defaultPromptPackMode = (providerKey) => providerKey === "zai" || providerKey === "minimax" ? "maximal" : "minimal";
|
|
3419
3824
|
var shouldInstallSkills = (providerKey) => providerKey === "zai" || providerKey === "minimax";
|
|
3420
3825
|
var shouldEnableShellEnv = (providerKey) => providerKey === "zai";
|
|
@@ -3425,6 +3830,8 @@ var VariantBuilder = class {
|
|
|
3425
3830
|
this.steps = [
|
|
3426
3831
|
new PrepareDirectoriesStep(),
|
|
3427
3832
|
new InstallNpmStep(),
|
|
3833
|
+
new TeamModeStep(),
|
|
3834
|
+
// Patches cli.js for team mode (if enabled)
|
|
3428
3835
|
new WriteConfigStep(),
|
|
3429
3836
|
new BrandThemeStep(),
|
|
3430
3837
|
new TweakccStep(),
|
|
@@ -3446,11 +3853,11 @@ var VariantBuilder = class {
|
|
|
3446
3853
|
const binDir = params.binDir ?? DEFAULT_BIN_DIR;
|
|
3447
3854
|
const resolvedRoot = expandTilde(rootDir) ?? rootDir;
|
|
3448
3855
|
const resolvedBin = expandTilde(binDir) ?? binDir;
|
|
3449
|
-
const variantDir =
|
|
3450
|
-
const configDir =
|
|
3451
|
-
const tweakDir =
|
|
3452
|
-
const wrapperPath =
|
|
3453
|
-
const npmDir =
|
|
3856
|
+
const variantDir = path16.join(resolvedRoot, params.name);
|
|
3857
|
+
const configDir = path16.join(variantDir, "config");
|
|
3858
|
+
const tweakDir = path16.join(variantDir, "tweakcc");
|
|
3859
|
+
const wrapperPath = path16.join(resolvedBin, params.name);
|
|
3860
|
+
const npmDir = path16.join(variantDir, "npm");
|
|
3454
3861
|
const paths = {
|
|
3455
3862
|
resolvedRoot,
|
|
3456
3863
|
resolvedBin,
|
|
@@ -3462,7 +3869,7 @@ var VariantBuilder = class {
|
|
|
3462
3869
|
};
|
|
3463
3870
|
const resolvedNpmPackage = normalizeNpmPackage(params.npmPackage);
|
|
3464
3871
|
const resolvedNpmVersion = normalizeNpmVersion();
|
|
3465
|
-
const promptPackPreference = params.promptPack ?? shouldEnablePromptPack(params.providerKey);
|
|
3872
|
+
const promptPackPreference = params.promptPack ?? shouldEnablePromptPack(params.providerKey, provider);
|
|
3466
3873
|
const promptPackModePreference = params.promptPackMode ?? defaultPromptPackMode(params.providerKey);
|
|
3467
3874
|
const promptPackEnabled = !params.noTweak && promptPackPreference;
|
|
3468
3875
|
const skillInstallEnabled = params.skillInstall ?? shouldInstallSkills(params.providerKey);
|
|
@@ -3547,7 +3954,7 @@ var VariantBuilder = class {
|
|
|
3547
3954
|
};
|
|
3548
3955
|
|
|
3549
3956
|
// src/core/variant-builder/VariantUpdater.ts
|
|
3550
|
-
import
|
|
3957
|
+
import path21 from "node:path";
|
|
3551
3958
|
|
|
3552
3959
|
// src/core/variant-builder/update-steps/InstallNpmUpdateStep.ts
|
|
3553
3960
|
var InstallNpmUpdateStep = class {
|
|
@@ -3581,6 +3988,128 @@ var InstallNpmUpdateStep = class {
|
|
|
3581
3988
|
}
|
|
3582
3989
|
};
|
|
3583
3990
|
|
|
3991
|
+
// src/core/variant-builder/update-steps/TeamModeUpdateStep.ts
|
|
3992
|
+
import fs12 from "node:fs";
|
|
3993
|
+
import path17 from "node:path";
|
|
3994
|
+
var TEAM_MODE_DISABLED2 = "function sU(){return!1}";
|
|
3995
|
+
var TEAM_MODE_ENABLED2 = "function sU(){return!0}";
|
|
3996
|
+
var TeamModeUpdateStep = class {
|
|
3997
|
+
name = "TeamMode";
|
|
3998
|
+
shouldEnableTeamMode(ctx) {
|
|
3999
|
+
const provider = getProvider(ctx.meta.provider);
|
|
4000
|
+
return Boolean(ctx.opts.enableTeamMode) || Boolean(provider?.enablesTeamMode);
|
|
4001
|
+
}
|
|
4002
|
+
shouldDisableTeamMode(ctx) {
|
|
4003
|
+
return Boolean(ctx.opts.disableTeamMode);
|
|
4004
|
+
}
|
|
4005
|
+
execute(ctx) {
|
|
4006
|
+
if (this.shouldDisableTeamMode(ctx)) {
|
|
4007
|
+
ctx.report("Disabling team mode...");
|
|
4008
|
+
this.unpatchCli(ctx);
|
|
4009
|
+
return;
|
|
4010
|
+
}
|
|
4011
|
+
if (!this.shouldEnableTeamMode(ctx)) return;
|
|
4012
|
+
ctx.report("Enabling team mode...");
|
|
4013
|
+
this.patchCli(ctx);
|
|
4014
|
+
}
|
|
4015
|
+
async executeAsync(ctx) {
|
|
4016
|
+
if (this.shouldDisableTeamMode(ctx)) {
|
|
4017
|
+
await ctx.report("Disabling team mode...");
|
|
4018
|
+
this.unpatchCli(ctx);
|
|
4019
|
+
return;
|
|
4020
|
+
}
|
|
4021
|
+
if (!this.shouldEnableTeamMode(ctx)) return;
|
|
4022
|
+
await ctx.report("Enabling team mode...");
|
|
4023
|
+
this.patchCli(ctx);
|
|
4024
|
+
}
|
|
4025
|
+
unpatchCli(ctx) {
|
|
4026
|
+
const { state, meta } = ctx;
|
|
4027
|
+
const cliPath = path17.join(meta.npmDir || "", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
4028
|
+
if (!fs12.existsSync(cliPath)) {
|
|
4029
|
+
state.notes.push("Warning: cli.js not found, skipping team mode unpatch");
|
|
4030
|
+
return;
|
|
4031
|
+
}
|
|
4032
|
+
let content = fs12.readFileSync(cliPath, "utf8");
|
|
4033
|
+
if (content.includes(TEAM_MODE_DISABLED2)) {
|
|
4034
|
+
state.notes.push("Team mode already disabled");
|
|
4035
|
+
meta.teamModeEnabled = false;
|
|
4036
|
+
return;
|
|
4037
|
+
}
|
|
4038
|
+
if (!content.includes(TEAM_MODE_ENABLED2)) {
|
|
4039
|
+
state.notes.push("Warning: Team mode function not found in cli.js");
|
|
4040
|
+
return;
|
|
4041
|
+
}
|
|
4042
|
+
content = content.replace(TEAM_MODE_ENABLED2, TEAM_MODE_DISABLED2);
|
|
4043
|
+
fs12.writeFileSync(cliPath, content);
|
|
4044
|
+
const verifyContent = fs12.readFileSync(cliPath, "utf8");
|
|
4045
|
+
if (!verifyContent.includes(TEAM_MODE_DISABLED2)) {
|
|
4046
|
+
state.notes.push("Warning: Team mode unpatch verification failed");
|
|
4047
|
+
return;
|
|
4048
|
+
}
|
|
4049
|
+
meta.teamModeEnabled = false;
|
|
4050
|
+
state.notes.push("Team mode disabled successfully");
|
|
4051
|
+
const skillResult = removeOrchestratorSkill(meta.configDir);
|
|
4052
|
+
if (skillResult.status === "removed") {
|
|
4053
|
+
state.notes.push("Multi-agent orchestrator skill removed");
|
|
4054
|
+
} else if (skillResult.status === "failed") {
|
|
4055
|
+
state.notes.push(`Warning: orchestrator skill removal failed: ${skillResult.message}`);
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
patchCli(ctx) {
|
|
4059
|
+
const { state, meta, name } = ctx;
|
|
4060
|
+
const cliPath = path17.join(meta.npmDir || "", "node_modules", "@anthropic-ai", "claude-code", "cli.js");
|
|
4061
|
+
const backupPath = `${cliPath}.backup`;
|
|
4062
|
+
if (!fs12.existsSync(cliPath)) {
|
|
4063
|
+
state.notes.push("Warning: cli.js not found, skipping team mode patch");
|
|
4064
|
+
return;
|
|
4065
|
+
}
|
|
4066
|
+
if (!fs12.existsSync(backupPath)) {
|
|
4067
|
+
fs12.copyFileSync(cliPath, backupPath);
|
|
4068
|
+
}
|
|
4069
|
+
let content = fs12.readFileSync(cliPath, "utf8");
|
|
4070
|
+
if (content.includes(TEAM_MODE_ENABLED2)) {
|
|
4071
|
+
state.notes.push("Team mode already enabled");
|
|
4072
|
+
meta.teamModeEnabled = true;
|
|
4073
|
+
return;
|
|
4074
|
+
}
|
|
4075
|
+
if (!content.includes(TEAM_MODE_DISABLED2)) {
|
|
4076
|
+
state.notes.push("Warning: Team mode function not found in cli.js, patch may not work");
|
|
4077
|
+
return;
|
|
4078
|
+
}
|
|
4079
|
+
content = content.replace(TEAM_MODE_DISABLED2, TEAM_MODE_ENABLED2);
|
|
4080
|
+
fs12.writeFileSync(cliPath, content);
|
|
4081
|
+
const verifyContent = fs12.readFileSync(cliPath, "utf8");
|
|
4082
|
+
if (!verifyContent.includes(TEAM_MODE_ENABLED2)) {
|
|
4083
|
+
state.notes.push("Warning: Team mode patch verification failed");
|
|
4084
|
+
return;
|
|
4085
|
+
}
|
|
4086
|
+
const settingsPath = path17.join(meta.configDir, "settings.json");
|
|
4087
|
+
if (fs12.existsSync(settingsPath)) {
|
|
4088
|
+
try {
|
|
4089
|
+
const settings = JSON.parse(fs12.readFileSync(settingsPath, "utf8"));
|
|
4090
|
+
settings.env = settings.env || {};
|
|
4091
|
+
if (!settings.env.CLAUDE_CODE_TEAM_NAME) {
|
|
4092
|
+
settings.env.CLAUDE_CODE_TEAM_NAME = name;
|
|
4093
|
+
}
|
|
4094
|
+
if (!settings.env.CLAUDE_CODE_AGENT_TYPE) {
|
|
4095
|
+
settings.env.CLAUDE_CODE_AGENT_TYPE = "team-lead";
|
|
4096
|
+
}
|
|
4097
|
+
fs12.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
4098
|
+
} catch {
|
|
4099
|
+
state.notes.push("Warning: Could not update settings.json with team env vars");
|
|
4100
|
+
}
|
|
4101
|
+
}
|
|
4102
|
+
meta.teamModeEnabled = true;
|
|
4103
|
+
state.notes.push("Team mode enabled successfully");
|
|
4104
|
+
const skillResult = installOrchestratorSkill(meta.configDir);
|
|
4105
|
+
if (skillResult.status === "installed") {
|
|
4106
|
+
state.notes.push("Multi-agent orchestrator skill installed");
|
|
4107
|
+
} else if (skillResult.status === "failed") {
|
|
4108
|
+
state.notes.push(`Warning: orchestrator skill install failed: ${skillResult.message}`);
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4111
|
+
};
|
|
4112
|
+
|
|
3584
4113
|
// src/core/variant-builder/update-steps/ModelOverridesStep.ts
|
|
3585
4114
|
var ModelOverridesStep = class {
|
|
3586
4115
|
name = "ModelOverrides";
|
|
@@ -3664,7 +4193,7 @@ ${reapply.stdout ?? ""}`.trim();
|
|
|
3664
4193
|
};
|
|
3665
4194
|
|
|
3666
4195
|
// src/core/variant-builder/update-steps/WrapperUpdateStep.ts
|
|
3667
|
-
import
|
|
4196
|
+
import path18 from "node:path";
|
|
3668
4197
|
var WrapperUpdateStep = class {
|
|
3669
4198
|
name = "Wrapper";
|
|
3670
4199
|
execute(ctx) {
|
|
@@ -3682,7 +4211,7 @@ var WrapperUpdateStep = class {
|
|
|
3682
4211
|
const resolvedBin = opts.binDir ? expandTilde(opts.binDir) ?? opts.binDir : meta.binDir;
|
|
3683
4212
|
if (resolvedBin) {
|
|
3684
4213
|
ensureDir(resolvedBin);
|
|
3685
|
-
const wrapperPath =
|
|
4214
|
+
const wrapperPath = path18.join(resolvedBin, name);
|
|
3686
4215
|
writeWrapper(wrapperPath, meta.configDir, meta.binaryPath, "node");
|
|
3687
4216
|
meta.binDir = resolvedBin;
|
|
3688
4217
|
}
|
|
@@ -3774,7 +4303,7 @@ var ShellEnvUpdateStep = class {
|
|
|
3774
4303
|
};
|
|
3775
4304
|
|
|
3776
4305
|
// src/core/variant-builder/update-steps/SkillInstallUpdateStep.ts
|
|
3777
|
-
import
|
|
4306
|
+
import path19 from "node:path";
|
|
3778
4307
|
var SkillInstallUpdateStep = class {
|
|
3779
4308
|
name = "SkillInstall";
|
|
3780
4309
|
execute(ctx) {
|
|
@@ -3794,7 +4323,7 @@ var SkillInstallUpdateStep = class {
|
|
|
3794
4323
|
const skillOpts = {
|
|
3795
4324
|
install: true,
|
|
3796
4325
|
update: prefs.skillUpdateEnabled,
|
|
3797
|
-
targetDir:
|
|
4326
|
+
targetDir: path19.join(meta.configDir, "skills")
|
|
3798
4327
|
};
|
|
3799
4328
|
const skillResult = isAsync ? await ensureDevBrowserSkillAsync(skillOpts) : ensureDevBrowserSkill(skillOpts);
|
|
3800
4329
|
if (skillResult.status === "failed") {
|
|
@@ -3806,7 +4335,7 @@ var SkillInstallUpdateStep = class {
|
|
|
3806
4335
|
};
|
|
3807
4336
|
|
|
3808
4337
|
// src/core/variant-builder/update-steps/FinalizeUpdateStep.ts
|
|
3809
|
-
import
|
|
4338
|
+
import path20 from "node:path";
|
|
3810
4339
|
var FinalizeUpdateStep = class {
|
|
3811
4340
|
name = "Finalize";
|
|
3812
4341
|
execute(ctx) {
|
|
@@ -3824,14 +4353,18 @@ var FinalizeUpdateStep = class {
|
|
|
3824
4353
|
meta.promptPackMode = prefs.promptPackModePreference;
|
|
3825
4354
|
meta.skillInstall = prefs.skillInstallEnabled;
|
|
3826
4355
|
meta.shellEnv = prefs.shellEnvEnabled;
|
|
3827
|
-
writeJson(
|
|
4356
|
+
writeJson(path20.join(paths.variantDir, "variant.json"), meta);
|
|
3828
4357
|
}
|
|
3829
4358
|
};
|
|
3830
4359
|
|
|
3831
4360
|
// src/core/variant-builder/VariantUpdater.ts
|
|
3832
4361
|
var normalizeNpmPackage2 = (value) => value && value.trim().length > 0 ? value.trim() : DEFAULT_NPM_PACKAGE;
|
|
3833
4362
|
var normalizeNpmVersion2 = () => DEFAULT_NPM_VERSION;
|
|
3834
|
-
var shouldEnablePromptPack2 = (providerKey) =>
|
|
4363
|
+
var shouldEnablePromptPack2 = (providerKey) => {
|
|
4364
|
+
const provider = getProvider(providerKey);
|
|
4365
|
+
if (provider?.noPromptPack) return false;
|
|
4366
|
+
return providerKey === "zai" || providerKey === "minimax";
|
|
4367
|
+
};
|
|
3835
4368
|
var defaultPromptPackMode2 = (providerKey) => providerKey === "zai" || providerKey === "minimax" ? "maximal" : "minimal";
|
|
3836
4369
|
var shouldInstallSkills2 = (providerKey) => providerKey === "zai" || providerKey === "minimax";
|
|
3837
4370
|
var shouldEnableShellEnv2 = (providerKey) => providerKey === "zai";
|
|
@@ -3841,6 +4374,8 @@ var VariantUpdater = class {
|
|
|
3841
4374
|
this.isAsync = isAsync;
|
|
3842
4375
|
this.steps = [
|
|
3843
4376
|
new InstallNpmUpdateStep(),
|
|
4377
|
+
new TeamModeUpdateStep(),
|
|
4378
|
+
// Patches cli.js for team mode (if enabled)
|
|
3844
4379
|
new ModelOverridesStep(),
|
|
3845
4380
|
new TweakccUpdateStep(),
|
|
3846
4381
|
new WrapperUpdateStep(),
|
|
@@ -3856,7 +4391,7 @@ var VariantUpdater = class {
|
|
|
3856
4391
|
*/
|
|
3857
4392
|
initContext(rootDir, name, opts) {
|
|
3858
4393
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3859
|
-
const variantDir =
|
|
4394
|
+
const variantDir = path21.join(resolvedRoot, name);
|
|
3860
4395
|
const meta = loadVariantMeta(variantDir);
|
|
3861
4396
|
if (!meta) throw new Error(`Variant not found: ${name}`);
|
|
3862
4397
|
const resolvedNpmPackage = normalizeNpmPackage2(opts.npmPackage ?? meta.npmPackage);
|
|
@@ -3872,7 +4407,7 @@ var VariantUpdater = class {
|
|
|
3872
4407
|
resolvedRoot,
|
|
3873
4408
|
resolvedBin: opts.binDir ? expandTilde(opts.binDir) ?? opts.binDir : meta.binDir,
|
|
3874
4409
|
variantDir,
|
|
3875
|
-
npmDir: meta.npmDir ||
|
|
4410
|
+
npmDir: meta.npmDir || path21.join(variantDir, "npm")
|
|
3876
4411
|
};
|
|
3877
4412
|
const prefs = {
|
|
3878
4413
|
resolvedNpmPackage,
|
|
@@ -3954,17 +4489,17 @@ var updateVariant = (rootDir, name, opts = {}) => {
|
|
|
3954
4489
|
};
|
|
3955
4490
|
var removeVariant = (rootDir, name) => {
|
|
3956
4491
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3957
|
-
const variantDir =
|
|
3958
|
-
if (!
|
|
3959
|
-
|
|
4492
|
+
const variantDir = path22.join(resolvedRoot, name);
|
|
4493
|
+
if (!fs13.existsSync(variantDir)) throw new Error(`Variant not found: ${name}`);
|
|
4494
|
+
fs13.rmSync(variantDir, { recursive: true, force: true });
|
|
3960
4495
|
};
|
|
3961
4496
|
var doctor = (rootDir, binDir) => {
|
|
3962
4497
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3963
4498
|
const resolvedBin = expandTilde(binDir || DEFAULT_BIN_DIR) ?? binDir;
|
|
3964
4499
|
const variants = listVariants(resolvedRoot);
|
|
3965
4500
|
return variants.map(({ name, meta }) => {
|
|
3966
|
-
const wrapperPath =
|
|
3967
|
-
const ok = Boolean(meta &&
|
|
4501
|
+
const wrapperPath = path22.join(resolvedBin, name);
|
|
4502
|
+
const ok = Boolean(meta && fs13.existsSync(meta.binaryPath) && fs13.existsSync(wrapperPath));
|
|
3968
4503
|
return {
|
|
3969
4504
|
name,
|
|
3970
4505
|
ok,
|
|
@@ -3976,7 +4511,7 @@ var doctor = (rootDir, binDir) => {
|
|
|
3976
4511
|
var listVariants2 = (rootDir) => listVariants(rootDir);
|
|
3977
4512
|
var tweakVariant = (rootDir, name) => {
|
|
3978
4513
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3979
|
-
const variantDir =
|
|
4514
|
+
const variantDir = path22.join(resolvedRoot, name);
|
|
3980
4515
|
const meta = loadVariantMeta(variantDir);
|
|
3981
4516
|
if (!meta) throw new Error(`Variant not found: ${name}`);
|
|
3982
4517
|
ensureDir(meta.tweakDir);
|
|
@@ -4050,7 +4585,7 @@ function runTweakCommand({ opts }) {
|
|
|
4050
4585
|
}
|
|
4051
4586
|
|
|
4052
4587
|
// src/cli/commands/update.ts
|
|
4053
|
-
import
|
|
4588
|
+
import path23 from "node:path";
|
|
4054
4589
|
|
|
4055
4590
|
// src/cli/utils/buildShareUrl.ts
|
|
4056
4591
|
function buildShareUrl(providerLabel, variant, mode) {
|
|
@@ -4209,9 +4744,10 @@ function runUpdateCommand({ opts }) {
|
|
|
4209
4744
|
promptPackMode,
|
|
4210
4745
|
skillInstall,
|
|
4211
4746
|
shellEnv,
|
|
4212
|
-
skillUpdate
|
|
4747
|
+
skillUpdate,
|
|
4748
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4213
4749
|
});
|
|
4214
|
-
const wrapperPath =
|
|
4750
|
+
const wrapperPath = path23.join(binDir, name);
|
|
4215
4751
|
printSummary({
|
|
4216
4752
|
action: "Updated",
|
|
4217
4753
|
meta: result.meta,
|
|
@@ -4310,7 +4846,8 @@ async function handleQuickMode(opts, params) {
|
|
|
4310
4846
|
skillInstall,
|
|
4311
4847
|
shellEnv,
|
|
4312
4848
|
skillUpdate,
|
|
4313
|
-
modelOverrides: resolvedModelOverrides
|
|
4849
|
+
modelOverrides: resolvedModelOverrides,
|
|
4850
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4314
4851
|
});
|
|
4315
4852
|
const shareUrl = buildShareUrl(provider.label || params.providerKey, params.name, result.meta.promptPackMode);
|
|
4316
4853
|
const modelNote = formatModelNote(resolvedModelOverrides);
|
|
@@ -4370,7 +4907,8 @@ async function handleInteractiveMode(opts, params) {
|
|
|
4370
4907
|
skillInstall,
|
|
4371
4908
|
shellEnv,
|
|
4372
4909
|
skillUpdate,
|
|
4373
|
-
modelOverrides: resolvedModelOverrides
|
|
4910
|
+
modelOverrides: resolvedModelOverrides,
|
|
4911
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4374
4912
|
});
|
|
4375
4913
|
const shareUrl = buildShareUrl(provider.label || params.providerKey, result.meta.name, result.meta.promptPackMode);
|
|
4376
4914
|
const modelNote = formatModelNote(resolvedModelOverrides);
|
|
@@ -4411,7 +4949,8 @@ async function handleNonInteractiveMode(opts, params) {
|
|
|
4411
4949
|
skillInstall,
|
|
4412
4950
|
shellEnv,
|
|
4413
4951
|
skillUpdate,
|
|
4414
|
-
modelOverrides: resolvedModelOverrides
|
|
4952
|
+
modelOverrides: resolvedModelOverrides,
|
|
4953
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4415
4954
|
});
|
|
4416
4955
|
const shareUrl = buildShareUrl(provider.label || params.providerKey, result.meta.name, result.meta.promptPackMode);
|
|
4417
4956
|
const modelNote = formatModelNote(resolvedModelOverrides);
|