cc-mirror 1.0.3 → 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 +807 -287
- 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 +1063 -405
- 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;
|
|
@@ -2367,21 +2908,13 @@ var ZAI_BLOCKED_MCP_TOOLS = [
|
|
|
2367
2908
|
"mcp__web_reader__webReader"
|
|
2368
2909
|
];
|
|
2369
2910
|
var ZAI_CLI_TEXT = `
|
|
2370
|
-
# ZAI CLI (embedded reference)
|
|
2371
2911
|
Access Z.AI capabilities via 'npx zai-cli'. The CLI is self-documenting - use '--help' at any level.
|
|
2372
2912
|
|
|
2373
|
-
Setup:
|
|
2374
|
-
- Required env: 'Z_AI_API_KEY'
|
|
2375
|
-
- Get a key at: https://z.ai/manage-apikey/apikey-list
|
|
2376
|
-
|
|
2377
2913
|
Commands:
|
|
2378
2914
|
- vision: Analyze images, screenshots, videos (many subcommands)
|
|
2379
2915
|
- search: Real-time web search (domain/recency/location/count filters)
|
|
2380
2916
|
- read: Fetch web pages as markdown/text (format/no-images/with-links/timeout)
|
|
2381
2917
|
- repo: GitHub exploration (tree/search/read). Run npx zai-cli repo --help for subcommands.
|
|
2382
|
-
- tools/tool/call: MCP tool discovery + raw calls (advanced)
|
|
2383
|
-
- code: TypeScript tool chaining (advanced)
|
|
2384
|
-
- doctor: Environment + connectivity checks
|
|
2385
2918
|
|
|
2386
2919
|
Quick start examples:
|
|
2387
2920
|
- npx zai-cli vision analyze ./screenshot.png "What errors do you see?"
|
|
@@ -2389,11 +2922,6 @@ Quick start examples:
|
|
|
2389
2922
|
- npx zai-cli read https://docs.example.com/api
|
|
2390
2923
|
- npx zai-cli repo search facebook/react "server components"
|
|
2391
2924
|
- npx zai-cli repo --help
|
|
2392
|
-
- npx zai-cli doctor
|
|
2393
|
-
|
|
2394
|
-
Output:
|
|
2395
|
-
- Default: data-only (token efficient).
|
|
2396
|
-
- Use '--output-format json' for { success, data, timestamp } wrapping.
|
|
2397
2925
|
`.trim();
|
|
2398
2926
|
var buildZaiContract = (mode) => `
|
|
2399
2927
|
<explicit_guidance>
|
|
@@ -2417,19 +2945,17 @@ Important:
|
|
|
2417
2945
|
<tool_routing priority="critical">
|
|
2418
2946
|
When you need external info, web content, or image understanding, follow this routing (use the Bash tool):
|
|
2419
2947
|
1) Web search:
|
|
2420
|
-
npx
|
|
2948
|
+
npx -y zai-cli search "<query>" --count 5 --output-format json
|
|
2421
2949
|
2) Read a URL:
|
|
2422
|
-
npx
|
|
2950
|
+
npx -y zai-cli read <url> --output-format json
|
|
2423
2951
|
3) Image analysis:
|
|
2424
|
-
npx
|
|
2952
|
+
npx -y zai-cli vision analyze <image_url_or_path> "<prompt>" --output-format json
|
|
2425
2953
|
4) GitHub repo exploration (public repos only):
|
|
2426
|
-
- Search: npx
|
|
2427
|
-
- Tree: npx
|
|
2428
|
-
- Read: npx
|
|
2429
|
-
5) Troubleshooting:
|
|
2430
|
-
npx --yes zai-cli doctor --output-format json
|
|
2954
|
+
- Search: npx -y zai-cli repo search <owner/repo> "<query>" --output-format json
|
|
2955
|
+
- Tree: npx -y zai-cli repo tree <owner/repo> --depth 2 --output-format json
|
|
2956
|
+
- Read: npx -y zai-cli repo read <owner/repo> <path> --output-format json
|
|
2431
2957
|
|
|
2432
|
-
|
|
2958
|
+
The built in WebSearch/WebFetch tools are NOT available.
|
|
2433
2959
|
</tool_routing>
|
|
2434
2960
|
|
|
2435
2961
|
<warning priority="critical">
|
|
@@ -2451,8 +2977,7 @@ ${verbositySpec}
|
|
|
2451
2977
|
`.trim();
|
|
2452
2978
|
var buildZaiExcerpt = () => `
|
|
2453
2979
|
<tool_info>
|
|
2454
|
-
|
|
2455
|
-
- Use Bash + npx --yes zai-cli for web/search/vision.
|
|
2980
|
+
- Use Bash + npx -y zai-cli for web/search/vision.
|
|
2456
2981
|
- Ignore the Z.ai-injected MCP tools listed below (treat them as non-existent).
|
|
2457
2982
|
- No zai-cli skill is installed; do not use Skill for this.
|
|
2458
2983
|
Blocked MCP tool names (treat as non-existent):
|
|
@@ -2486,13 +3011,17 @@ ${verbositySpec}
|
|
|
2486
3011
|
${ZAI_CLI_TEXT}
|
|
2487
3012
|
|
|
2488
3013
|
<explicit_guidance>
|
|
2489
|
-
When you need web/search/vision,
|
|
3014
|
+
When you need web/search/vision, use these exact commands:
|
|
2490
3015
|
- Web search:
|
|
2491
|
-
npx
|
|
3016
|
+
npx -y zai-cli search "<query>" --count 5 --output-format json
|
|
2492
3017
|
- Read a URL:
|
|
2493
|
-
npx
|
|
2494
|
-
- Vision:
|
|
2495
|
-
npx
|
|
3018
|
+
npx -y zai-cli read <url> --output-format json
|
|
3019
|
+
- Vision: analyze images, screenshots, videos
|
|
3020
|
+
npx -y zai-cli vision analyze <image_url_or_path> "<prompt>" --output-format json
|
|
3021
|
+
- GitHub repo exploration (public repos only):
|
|
3022
|
+
- Search: npx -y zai-cli repo search <owner/repo> "<query>" --output-format json
|
|
3023
|
+
- Tree: npx -y zai-cli repo tree <owner/repo> --depth 2 --output-format json
|
|
3024
|
+
- Read: npx -y zai-cli repo read <owner/repo> <path> --output-format json
|
|
2496
3025
|
</explicit_guidance>
|
|
2497
3026
|
|
|
2498
3027
|
<warning priority="critical">
|
|
@@ -2502,12 +3031,12 @@ Prefer zai-cli via Bash for web/search/vision.
|
|
|
2502
3031
|
`.trim(),
|
|
2503
3032
|
webfetch: `
|
|
2504
3033
|
<explicit_guidance>
|
|
2505
|
-
Z.ai routing: prefer Bash + npx
|
|
3034
|
+
Z.ai routing: prefer Bash + npx -y zai-cli read <url> --output-format json.
|
|
2506
3035
|
</explicit_guidance>
|
|
2507
3036
|
`.trim(),
|
|
2508
3037
|
websearch: `
|
|
2509
3038
|
<explicit_guidance>
|
|
2510
|
-
Z.ai routing: prefer Bash + npx
|
|
3039
|
+
Z.ai routing: prefer Bash + npx -y zai-cli search "<query>" --count 5 --output-format json.
|
|
2511
3040
|
</explicit_guidance>
|
|
2512
3041
|
`.trim(),
|
|
2513
3042
|
mcpsearch: `
|
|
@@ -2527,13 +3056,6 @@ var MINIMAX_WEB_SEARCH = "mcp__MiniMax__web_search";
|
|
|
2527
3056
|
var MINIMAX_UNDERSTAND_IMAGE = "mcp__MiniMax__understand_image";
|
|
2528
3057
|
var buildMinimaxContract = (mode) => `
|
|
2529
3058
|
<explicit_guidance>
|
|
2530
|
-
Provider: MiniMax
|
|
2531
|
-
|
|
2532
|
-
<authentication>
|
|
2533
|
-
- Use API-key auth only.
|
|
2534
|
-
- Ignore ANTHROPIC_AUTH_TOKEN if present.
|
|
2535
|
-
</authentication>
|
|
2536
|
-
|
|
2537
3059
|
<tool_routing priority="critical">
|
|
2538
3060
|
MiniMax MCP tools available (and ONLY these for web + vision):
|
|
2539
3061
|
- ${MINIMAX_WEB_SEARCH} (web search)
|
|
@@ -2755,17 +3277,17 @@ ${block}
|
|
|
2755
3277
|
};
|
|
2756
3278
|
var updatePromptFile = (filePath, overlay) => {
|
|
2757
3279
|
if (!overlay) return false;
|
|
2758
|
-
if (!
|
|
2759
|
-
const content =
|
|
3280
|
+
if (!fs9.existsSync(filePath)) return false;
|
|
3281
|
+
const content = fs9.readFileSync(filePath, "utf8");
|
|
2760
3282
|
const updated = insertOverlay(content, overlay);
|
|
2761
3283
|
if (updated === content) return false;
|
|
2762
|
-
|
|
3284
|
+
fs9.writeFileSync(filePath, updated);
|
|
2763
3285
|
return true;
|
|
2764
3286
|
};
|
|
2765
3287
|
var applyOverlays = (systemPromptsDir, overlays) => {
|
|
2766
3288
|
const updated = [];
|
|
2767
3289
|
for (const target of PROMPT_PACK_TARGETS) {
|
|
2768
|
-
const filePath =
|
|
3290
|
+
const filePath = path11.join(systemPromptsDir, target.filename);
|
|
2769
3291
|
const overlay = overlays[target.key];
|
|
2770
3292
|
if (updatePromptFile(filePath, overlay)) {
|
|
2771
3293
|
updated.push(target.filename);
|
|
@@ -2778,7 +3300,7 @@ var applyPromptPack = (tweakDir, providerKey, mode = "minimal") => {
|
|
|
2778
3300
|
return { changed: false, updated: [], mode };
|
|
2779
3301
|
}
|
|
2780
3302
|
const overlays = resolveOverlays(providerKey, mode);
|
|
2781
|
-
const systemPromptsDir =
|
|
3303
|
+
const systemPromptsDir = path11.join(tweakDir, "system-prompts");
|
|
2782
3304
|
const updated = applyOverlays(systemPromptsDir, overlays);
|
|
2783
3305
|
return { changed: updated.length > 0, updated, mode };
|
|
2784
3306
|
};
|
|
@@ -2845,10 +3367,10 @@ ${reapply.stdout ?? ""}`.trim();
|
|
|
2845
3367
|
};
|
|
2846
3368
|
|
|
2847
3369
|
// src/core/wrapper.ts
|
|
2848
|
-
import
|
|
2849
|
-
import
|
|
3370
|
+
import fs10 from "node:fs";
|
|
3371
|
+
import path12 from "node:path";
|
|
2850
3372
|
var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
2851
|
-
const tweakDir =
|
|
3373
|
+
const tweakDir = path12.join(path12.dirname(configDir), "tweakcc");
|
|
2852
3374
|
const execLine = runtime === "node" ? `exec node "${binaryPath}" "$@"` : `exec "${binaryPath}" "$@"`;
|
|
2853
3375
|
const envLoader = [
|
|
2854
3376
|
"if command -v node >/dev/null 2>&1; then",
|
|
@@ -2920,6 +3442,15 @@ var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
|
2920
3442
|
// Deep blue
|
|
2921
3443
|
ccrDim: "\x1B[38;5;31m",
|
|
2922
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
|
|
2923
3454
|
// Default: White/Gray
|
|
2924
3455
|
defPrimary: "\x1B[38;5;255m",
|
|
2925
3456
|
// White
|
|
@@ -3004,6 +3535,22 @@ var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
|
3004
3535
|
"CCMCCR",
|
|
3005
3536
|
' __cc_show_label="0"',
|
|
3006
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
|
+
" ;;",
|
|
3007
3554
|
" *)",
|
|
3008
3555
|
" cat <<'CCMGEN'",
|
|
3009
3556
|
"",
|
|
@@ -3038,7 +3585,7 @@ var writeWrapper = (wrapperPath, configDir, binaryPath, runtime = "node") => {
|
|
|
3038
3585
|
execLine,
|
|
3039
3586
|
""
|
|
3040
3587
|
].join("\n");
|
|
3041
|
-
|
|
3588
|
+
fs10.writeFileSync(wrapperPath, content, { mode: 493 });
|
|
3042
3589
|
};
|
|
3043
3590
|
|
|
3044
3591
|
// src/core/variant-builder/steps/WrapperStep.ts
|
|
@@ -3055,9 +3602,9 @@ var WrapperStep = class {
|
|
|
3055
3602
|
};
|
|
3056
3603
|
|
|
3057
3604
|
// src/core/shell-env.ts
|
|
3058
|
-
import
|
|
3059
|
-
import
|
|
3060
|
-
import
|
|
3605
|
+
import fs11 from "node:fs";
|
|
3606
|
+
import os5 from "node:os";
|
|
3607
|
+
import path13 from "node:path";
|
|
3061
3608
|
var SETTINGS_FILE2 = "settings.json";
|
|
3062
3609
|
var BLOCK_START = "# cc-mirror: Z.ai env start";
|
|
3063
3610
|
var BLOCK_END = "# cc-mirror: Z.ai env end";
|
|
@@ -3069,22 +3616,22 @@ var normalizeApiKey = (value) => {
|
|
|
3069
3616
|
return trimmed;
|
|
3070
3617
|
};
|
|
3071
3618
|
var resolveShellProfile = () => {
|
|
3072
|
-
const home =
|
|
3619
|
+
const home = os5.homedir();
|
|
3073
3620
|
const shell = process.env.SHELL || "";
|
|
3074
|
-
const name =
|
|
3621
|
+
const name = path13.basename(shell);
|
|
3075
3622
|
if (name === "zsh") {
|
|
3076
|
-
return
|
|
3623
|
+
return path13.join(home, ".zshrc");
|
|
3077
3624
|
}
|
|
3078
3625
|
if (name === "bash") {
|
|
3079
|
-
const bashrc =
|
|
3080
|
-
if (
|
|
3081
|
-
return
|
|
3626
|
+
const bashrc = path13.join(home, ".bashrc");
|
|
3627
|
+
if (fs11.existsSync(bashrc)) return bashrc;
|
|
3628
|
+
return path13.join(home, ".bash_profile");
|
|
3082
3629
|
}
|
|
3083
3630
|
return null;
|
|
3084
3631
|
};
|
|
3085
3632
|
var readSettingsApiKey2 = (configDir) => {
|
|
3086
|
-
const settingsPath =
|
|
3087
|
-
if (!
|
|
3633
|
+
const settingsPath = path13.join(configDir, SETTINGS_FILE2);
|
|
3634
|
+
if (!fs11.existsSync(settingsPath)) return null;
|
|
3088
3635
|
const settings = readJson(settingsPath);
|
|
3089
3636
|
const key = settings?.env?.ANTHROPIC_API_KEY;
|
|
3090
3637
|
if (typeof key !== "string") return null;
|
|
@@ -3139,7 +3686,7 @@ var ensureZaiShellEnv = (opts) => {
|
|
|
3139
3686
|
if (!profile) {
|
|
3140
3687
|
return { status: "failed", message: "Unsupported shell; set Z_AI_API_KEY manually" };
|
|
3141
3688
|
}
|
|
3142
|
-
const existing =
|
|
3689
|
+
const existing = fs11.existsSync(profile) ? fs11.readFileSync(profile, "utf8") : "";
|
|
3143
3690
|
if (hasZaiKeyInProfile(existing)) {
|
|
3144
3691
|
return { status: "skipped", message: "Z_AI_API_KEY already set in shell profile", path: profile };
|
|
3145
3692
|
}
|
|
@@ -3147,7 +3694,7 @@ var ensureZaiShellEnv = (opts) => {
|
|
|
3147
3694
|
if (next === existing) {
|
|
3148
3695
|
return { status: "skipped", message: "Shell profile already up to date", path: profile };
|
|
3149
3696
|
}
|
|
3150
|
-
|
|
3697
|
+
fs11.writeFileSync(profile, next);
|
|
3151
3698
|
return { status: "updated", path: profile, message: `Run: source ${profile}` };
|
|
3152
3699
|
};
|
|
3153
3700
|
|
|
@@ -3186,173 +3733,7 @@ var ShellEnvStep = class {
|
|
|
3186
3733
|
};
|
|
3187
3734
|
|
|
3188
3735
|
// src/core/variant-builder/steps/SkillInstallStep.ts
|
|
3189
|
-
import
|
|
3190
|
-
|
|
3191
|
-
// src/core/skills.ts
|
|
3192
|
-
import fs10 from "node:fs";
|
|
3193
|
-
import os5 from "node:os";
|
|
3194
|
-
import path12 from "node:path";
|
|
3195
|
-
import { spawn as spawn3, spawnSync as spawnSync4 } from "node:child_process";
|
|
3196
|
-
var DEV_BROWSER_REPO = "https://github.com/SawyerHood/dev-browser.git";
|
|
3197
|
-
var DEV_BROWSER_ARCHIVE = "https://github.com/SawyerHood/dev-browser/archive/refs/heads/main.tar.gz";
|
|
3198
|
-
var SKILL_SUBDIR = path12.join("skills", "dev-browser");
|
|
3199
|
-
var MANAGED_MARKER = ".cc-mirror-managed";
|
|
3200
|
-
var ensureDir2 = (dir) => {
|
|
3201
|
-
fs10.mkdirSync(dir, { recursive: true });
|
|
3202
|
-
};
|
|
3203
|
-
var copyDir = (source, target) => {
|
|
3204
|
-
fs10.cpSync(source, target, { recursive: true });
|
|
3205
|
-
};
|
|
3206
|
-
var resolveSkillSourceDir = (repoDir) => {
|
|
3207
|
-
const direct = path12.join(repoDir, SKILL_SUBDIR);
|
|
3208
|
-
if (fs10.existsSync(direct)) return direct;
|
|
3209
|
-
const nested = fs10.readdirSync(repoDir).find((entry) => entry.startsWith("dev-browser-"));
|
|
3210
|
-
if (nested) {
|
|
3211
|
-
const candidate = path12.join(repoDir, nested, SKILL_SUBDIR);
|
|
3212
|
-
if (fs10.existsSync(candidate)) return candidate;
|
|
3213
|
-
}
|
|
3214
|
-
return null;
|
|
3215
|
-
};
|
|
3216
|
-
var cloneRepo = (targetDir) => {
|
|
3217
|
-
if (!commandExists("git")) return { ok: false, message: "git not found" };
|
|
3218
|
-
const result = spawnSync4("git", ["clone", "--depth", "1", DEV_BROWSER_REPO, targetDir], {
|
|
3219
|
-
encoding: "utf8"
|
|
3220
|
-
});
|
|
3221
|
-
if (result.status === 0) return { ok: true };
|
|
3222
|
-
return { ok: false, message: result.stderr?.trim() || result.stdout?.trim() || "git clone failed" };
|
|
3223
|
-
};
|
|
3224
|
-
var downloadArchive = (targetDir) => {
|
|
3225
|
-
if (!commandExists("curl") || !commandExists("tar")) {
|
|
3226
|
-
return { ok: false, message: "curl or tar not found" };
|
|
3227
|
-
}
|
|
3228
|
-
const archivePath = path12.join(targetDir, "dev-browser.tar.gz");
|
|
3229
|
-
const curlResult = spawnSync4("curl", ["-L", "-o", archivePath, DEV_BROWSER_ARCHIVE], { encoding: "utf8" });
|
|
3230
|
-
if (curlResult.status !== 0) {
|
|
3231
|
-
return { ok: false, message: curlResult.stderr?.trim() || "curl failed" };
|
|
3232
|
-
}
|
|
3233
|
-
const tarResult = spawnSync4("tar", ["-xzf", archivePath, "-C", targetDir], { encoding: "utf8" });
|
|
3234
|
-
if (tarResult.status !== 0) {
|
|
3235
|
-
return { ok: false, message: tarResult.stderr?.trim() || "tar extract failed" };
|
|
3236
|
-
}
|
|
3237
|
-
return { ok: true };
|
|
3238
|
-
};
|
|
3239
|
-
var ensureDevBrowserSkill = (opts) => {
|
|
3240
|
-
if (!opts.install) {
|
|
3241
|
-
return { status: "skipped", message: "skill install disabled" };
|
|
3242
|
-
}
|
|
3243
|
-
const skillRoot = opts.targetDir || path12.join(os5.homedir(), ".claude", "skills");
|
|
3244
|
-
const targetDir = path12.join(skillRoot, "dev-browser");
|
|
3245
|
-
const markerPath = path12.join(targetDir, MANAGED_MARKER);
|
|
3246
|
-
const exists = fs10.existsSync(targetDir);
|
|
3247
|
-
const managed = exists && fs10.existsSync(markerPath);
|
|
3248
|
-
if (exists && !managed && !opts.update) {
|
|
3249
|
-
return { status: "skipped", message: "existing skill is user-managed", path: targetDir };
|
|
3250
|
-
}
|
|
3251
|
-
ensureDir2(skillRoot);
|
|
3252
|
-
const tmpDir = fs10.mkdtempSync(path12.join(os5.tmpdir(), "cc-mirror-skill-"));
|
|
3253
|
-
try {
|
|
3254
|
-
let fetchResult = cloneRepo(tmpDir);
|
|
3255
|
-
if (!fetchResult.ok) {
|
|
3256
|
-
fetchResult = downloadArchive(tmpDir);
|
|
3257
|
-
}
|
|
3258
|
-
if (!fetchResult.ok) {
|
|
3259
|
-
return { status: "failed", message: fetchResult.message || "skill fetch failed" };
|
|
3260
|
-
}
|
|
3261
|
-
const sourceDir = resolveSkillSourceDir(tmpDir);
|
|
3262
|
-
if (!sourceDir) {
|
|
3263
|
-
return { status: "failed", message: "skill source not found after download" };
|
|
3264
|
-
}
|
|
3265
|
-
if (exists) {
|
|
3266
|
-
fs10.rmSync(targetDir, { recursive: true, force: true });
|
|
3267
|
-
}
|
|
3268
|
-
copyDir(sourceDir, targetDir);
|
|
3269
|
-
fs10.writeFileSync(
|
|
3270
|
-
markerPath,
|
|
3271
|
-
JSON.stringify({ managedBy: "cc-mirror", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
3272
|
-
);
|
|
3273
|
-
return { status: exists ? "updated" : "installed", path: targetDir };
|
|
3274
|
-
} catch (error) {
|
|
3275
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3276
|
-
return { status: "failed", message };
|
|
3277
|
-
} finally {
|
|
3278
|
-
fs10.rmSync(tmpDir, { recursive: true, force: true });
|
|
3279
|
-
}
|
|
3280
|
-
};
|
|
3281
|
-
var spawnAsync = (cmd, args) => {
|
|
3282
|
-
return new Promise((resolve) => {
|
|
3283
|
-
const child = spawn3(cmd, args, { stdio: "pipe" });
|
|
3284
|
-
let stderr = "";
|
|
3285
|
-
let stdout = "";
|
|
3286
|
-
child.stdout?.on("data", (d) => {
|
|
3287
|
-
stdout += d.toString();
|
|
3288
|
-
});
|
|
3289
|
-
child.stderr?.on("data", (d) => {
|
|
3290
|
-
stderr += d.toString();
|
|
3291
|
-
});
|
|
3292
|
-
child.on("close", (code) => {
|
|
3293
|
-
if (code === 0) resolve({ ok: true });
|
|
3294
|
-
else resolve({ ok: false, message: stderr.trim() || stdout.trim() || `${cmd} failed` });
|
|
3295
|
-
});
|
|
3296
|
-
child.on("error", (err) => resolve({ ok: false, message: err.message }));
|
|
3297
|
-
});
|
|
3298
|
-
};
|
|
3299
|
-
var cloneRepoAsync = async (targetDir) => {
|
|
3300
|
-
if (!commandExists("git")) return { ok: false, message: "git not found" };
|
|
3301
|
-
return spawnAsync("git", ["clone", "--depth", "1", DEV_BROWSER_REPO, targetDir]);
|
|
3302
|
-
};
|
|
3303
|
-
var downloadArchiveAsync = async (targetDir) => {
|
|
3304
|
-
if (!commandExists("curl") || !commandExists("tar")) {
|
|
3305
|
-
return { ok: false, message: "curl or tar not found" };
|
|
3306
|
-
}
|
|
3307
|
-
const archivePath = path12.join(targetDir, "dev-browser.tar.gz");
|
|
3308
|
-
const curlResult = await spawnAsync("curl", ["-L", "-o", archivePath, DEV_BROWSER_ARCHIVE]);
|
|
3309
|
-
if (!curlResult.ok) return curlResult;
|
|
3310
|
-
return spawnAsync("tar", ["-xzf", archivePath, "-C", targetDir]);
|
|
3311
|
-
};
|
|
3312
|
-
var ensureDevBrowserSkillAsync = async (opts) => {
|
|
3313
|
-
if (!opts.install) {
|
|
3314
|
-
return { status: "skipped", message: "skill install disabled" };
|
|
3315
|
-
}
|
|
3316
|
-
const skillRoot = opts.targetDir || path12.join(os5.homedir(), ".claude", "skills");
|
|
3317
|
-
const targetDir = path12.join(skillRoot, "dev-browser");
|
|
3318
|
-
const markerPath = path12.join(targetDir, MANAGED_MARKER);
|
|
3319
|
-
const exists = fs10.existsSync(targetDir);
|
|
3320
|
-
const managed = exists && fs10.existsSync(markerPath);
|
|
3321
|
-
if (exists && !managed && !opts.update) {
|
|
3322
|
-
return { status: "skipped", message: "existing skill is user-managed", path: targetDir };
|
|
3323
|
-
}
|
|
3324
|
-
ensureDir2(skillRoot);
|
|
3325
|
-
const tmpDir = fs10.mkdtempSync(path12.join(os5.tmpdir(), "cc-mirror-skill-"));
|
|
3326
|
-
try {
|
|
3327
|
-
let fetchResult = await cloneRepoAsync(tmpDir);
|
|
3328
|
-
if (!fetchResult.ok) {
|
|
3329
|
-
fetchResult = await downloadArchiveAsync(tmpDir);
|
|
3330
|
-
}
|
|
3331
|
-
if (!fetchResult.ok) {
|
|
3332
|
-
return { status: "failed", message: fetchResult.message || "skill fetch failed" };
|
|
3333
|
-
}
|
|
3334
|
-
const sourceDir = resolveSkillSourceDir(tmpDir);
|
|
3335
|
-
if (!sourceDir) {
|
|
3336
|
-
return { status: "failed", message: "skill source not found after download" };
|
|
3337
|
-
}
|
|
3338
|
-
if (exists) {
|
|
3339
|
-
fs10.rmSync(targetDir, { recursive: true, force: true });
|
|
3340
|
-
}
|
|
3341
|
-
copyDir(sourceDir, targetDir);
|
|
3342
|
-
fs10.writeFileSync(
|
|
3343
|
-
markerPath,
|
|
3344
|
-
JSON.stringify({ managedBy: "cc-mirror", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2)
|
|
3345
|
-
);
|
|
3346
|
-
return { status: exists ? "updated" : "installed", path: targetDir };
|
|
3347
|
-
} catch (error) {
|
|
3348
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3349
|
-
return { status: "failed", message };
|
|
3350
|
-
} finally {
|
|
3351
|
-
fs10.rmSync(tmpDir, { recursive: true, force: true });
|
|
3352
|
-
}
|
|
3353
|
-
};
|
|
3354
|
-
|
|
3355
|
-
// src/core/variant-builder/steps/SkillInstallStep.ts
|
|
3736
|
+
import path14 from "node:path";
|
|
3356
3737
|
var SkillInstallStep = class {
|
|
3357
3738
|
name = "SkillInstall";
|
|
3358
3739
|
execute(ctx) {
|
|
@@ -3364,7 +3745,7 @@ var SkillInstallStep = class {
|
|
|
3364
3745
|
const skillResult = ensureDevBrowserSkill({
|
|
3365
3746
|
install: true,
|
|
3366
3747
|
update: prefs.skillUpdateEnabled,
|
|
3367
|
-
targetDir:
|
|
3748
|
+
targetDir: path14.join(paths.configDir, "skills")
|
|
3368
3749
|
});
|
|
3369
3750
|
if (skillResult.status === "failed") {
|
|
3370
3751
|
state.notes.push(`dev-browser skill install failed: ${skillResult.message || "unknown error"}`);
|
|
@@ -3381,7 +3762,7 @@ var SkillInstallStep = class {
|
|
|
3381
3762
|
const skillResult = await ensureDevBrowserSkillAsync({
|
|
3382
3763
|
install: true,
|
|
3383
3764
|
update: prefs.skillUpdateEnabled,
|
|
3384
|
-
targetDir:
|
|
3765
|
+
targetDir: path14.join(paths.configDir, "skills")
|
|
3385
3766
|
});
|
|
3386
3767
|
if (skillResult.status === "failed") {
|
|
3387
3768
|
state.notes.push(`dev-browser skill install failed: ${skillResult.message || "unknown error"}`);
|
|
@@ -3392,7 +3773,7 @@ var SkillInstallStep = class {
|
|
|
3392
3773
|
};
|
|
3393
3774
|
|
|
3394
3775
|
// src/core/variant-builder/steps/FinalizeStep.ts
|
|
3395
|
-
import
|
|
3776
|
+
import path15 from "node:path";
|
|
3396
3777
|
var FinalizeStep = class {
|
|
3397
3778
|
name = "Finalize";
|
|
3398
3779
|
execute(ctx) {
|
|
@@ -3404,7 +3785,8 @@ var FinalizeStep = class {
|
|
|
3404
3785
|
this.finalize(ctx);
|
|
3405
3786
|
}
|
|
3406
3787
|
finalize(ctx) {
|
|
3407
|
-
const { params, paths, prefs, state } = ctx;
|
|
3788
|
+
const { params, paths, prefs, state, provider } = ctx;
|
|
3789
|
+
const teamModeEnabled = Boolean(params.enableTeamMode) || Boolean(provider.enablesTeamMode);
|
|
3408
3790
|
const meta = {
|
|
3409
3791
|
name: params.name,
|
|
3410
3792
|
provider: params.providerKey,
|
|
@@ -3423,9 +3805,10 @@ var FinalizeStep = class {
|
|
|
3423
3805
|
installType: "npm",
|
|
3424
3806
|
npmDir: paths.npmDir,
|
|
3425
3807
|
npmPackage: prefs.resolvedNpmPackage,
|
|
3426
|
-
npmVersion: prefs.resolvedNpmVersion
|
|
3808
|
+
npmVersion: prefs.resolvedNpmVersion,
|
|
3809
|
+
teamModeEnabled
|
|
3427
3810
|
};
|
|
3428
|
-
writeJson(
|
|
3811
|
+
writeJson(path15.join(paths.variantDir, "variant.json"), meta);
|
|
3429
3812
|
state.meta = meta;
|
|
3430
3813
|
}
|
|
3431
3814
|
};
|
|
@@ -3433,7 +3816,10 @@ var FinalizeStep = class {
|
|
|
3433
3816
|
// src/core/variant-builder/VariantBuilder.ts
|
|
3434
3817
|
var normalizeNpmPackage = (value) => value && value.trim().length > 0 ? value.trim() : DEFAULT_NPM_PACKAGE;
|
|
3435
3818
|
var normalizeNpmVersion = () => DEFAULT_NPM_VERSION;
|
|
3436
|
-
var shouldEnablePromptPack = (providerKey) =>
|
|
3819
|
+
var shouldEnablePromptPack = (providerKey, provider) => {
|
|
3820
|
+
if (provider?.noPromptPack) return false;
|
|
3821
|
+
return providerKey === "zai" || providerKey === "minimax";
|
|
3822
|
+
};
|
|
3437
3823
|
var defaultPromptPackMode = (providerKey) => providerKey === "zai" || providerKey === "minimax" ? "maximal" : "minimal";
|
|
3438
3824
|
var shouldInstallSkills = (providerKey) => providerKey === "zai" || providerKey === "minimax";
|
|
3439
3825
|
var shouldEnableShellEnv = (providerKey) => providerKey === "zai";
|
|
@@ -3444,6 +3830,8 @@ var VariantBuilder = class {
|
|
|
3444
3830
|
this.steps = [
|
|
3445
3831
|
new PrepareDirectoriesStep(),
|
|
3446
3832
|
new InstallNpmStep(),
|
|
3833
|
+
new TeamModeStep(),
|
|
3834
|
+
// Patches cli.js for team mode (if enabled)
|
|
3447
3835
|
new WriteConfigStep(),
|
|
3448
3836
|
new BrandThemeStep(),
|
|
3449
3837
|
new TweakccStep(),
|
|
@@ -3465,11 +3853,11 @@ var VariantBuilder = class {
|
|
|
3465
3853
|
const binDir = params.binDir ?? DEFAULT_BIN_DIR;
|
|
3466
3854
|
const resolvedRoot = expandTilde(rootDir) ?? rootDir;
|
|
3467
3855
|
const resolvedBin = expandTilde(binDir) ?? binDir;
|
|
3468
|
-
const variantDir =
|
|
3469
|
-
const configDir =
|
|
3470
|
-
const tweakDir =
|
|
3471
|
-
const wrapperPath =
|
|
3472
|
-
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");
|
|
3473
3861
|
const paths = {
|
|
3474
3862
|
resolvedRoot,
|
|
3475
3863
|
resolvedBin,
|
|
@@ -3481,7 +3869,7 @@ var VariantBuilder = class {
|
|
|
3481
3869
|
};
|
|
3482
3870
|
const resolvedNpmPackage = normalizeNpmPackage(params.npmPackage);
|
|
3483
3871
|
const resolvedNpmVersion = normalizeNpmVersion();
|
|
3484
|
-
const promptPackPreference = params.promptPack ?? shouldEnablePromptPack(params.providerKey);
|
|
3872
|
+
const promptPackPreference = params.promptPack ?? shouldEnablePromptPack(params.providerKey, provider);
|
|
3485
3873
|
const promptPackModePreference = params.promptPackMode ?? defaultPromptPackMode(params.providerKey);
|
|
3486
3874
|
const promptPackEnabled = !params.noTweak && promptPackPreference;
|
|
3487
3875
|
const skillInstallEnabled = params.skillInstall ?? shouldInstallSkills(params.providerKey);
|
|
@@ -3566,7 +3954,7 @@ var VariantBuilder = class {
|
|
|
3566
3954
|
};
|
|
3567
3955
|
|
|
3568
3956
|
// src/core/variant-builder/VariantUpdater.ts
|
|
3569
|
-
import
|
|
3957
|
+
import path21 from "node:path";
|
|
3570
3958
|
|
|
3571
3959
|
// src/core/variant-builder/update-steps/InstallNpmUpdateStep.ts
|
|
3572
3960
|
var InstallNpmUpdateStep = class {
|
|
@@ -3600,6 +3988,128 @@ var InstallNpmUpdateStep = class {
|
|
|
3600
3988
|
}
|
|
3601
3989
|
};
|
|
3602
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
|
+
|
|
3603
4113
|
// src/core/variant-builder/update-steps/ModelOverridesStep.ts
|
|
3604
4114
|
var ModelOverridesStep = class {
|
|
3605
4115
|
name = "ModelOverrides";
|
|
@@ -3683,7 +4193,7 @@ ${reapply.stdout ?? ""}`.trim();
|
|
|
3683
4193
|
};
|
|
3684
4194
|
|
|
3685
4195
|
// src/core/variant-builder/update-steps/WrapperUpdateStep.ts
|
|
3686
|
-
import
|
|
4196
|
+
import path18 from "node:path";
|
|
3687
4197
|
var WrapperUpdateStep = class {
|
|
3688
4198
|
name = "Wrapper";
|
|
3689
4199
|
execute(ctx) {
|
|
@@ -3701,7 +4211,7 @@ var WrapperUpdateStep = class {
|
|
|
3701
4211
|
const resolvedBin = opts.binDir ? expandTilde(opts.binDir) ?? opts.binDir : meta.binDir;
|
|
3702
4212
|
if (resolvedBin) {
|
|
3703
4213
|
ensureDir(resolvedBin);
|
|
3704
|
-
const wrapperPath =
|
|
4214
|
+
const wrapperPath = path18.join(resolvedBin, name);
|
|
3705
4215
|
writeWrapper(wrapperPath, meta.configDir, meta.binaryPath, "node");
|
|
3706
4216
|
meta.binDir = resolvedBin;
|
|
3707
4217
|
}
|
|
@@ -3793,7 +4303,7 @@ var ShellEnvUpdateStep = class {
|
|
|
3793
4303
|
};
|
|
3794
4304
|
|
|
3795
4305
|
// src/core/variant-builder/update-steps/SkillInstallUpdateStep.ts
|
|
3796
|
-
import
|
|
4306
|
+
import path19 from "node:path";
|
|
3797
4307
|
var SkillInstallUpdateStep = class {
|
|
3798
4308
|
name = "SkillInstall";
|
|
3799
4309
|
execute(ctx) {
|
|
@@ -3813,7 +4323,7 @@ var SkillInstallUpdateStep = class {
|
|
|
3813
4323
|
const skillOpts = {
|
|
3814
4324
|
install: true,
|
|
3815
4325
|
update: prefs.skillUpdateEnabled,
|
|
3816
|
-
targetDir:
|
|
4326
|
+
targetDir: path19.join(meta.configDir, "skills")
|
|
3817
4327
|
};
|
|
3818
4328
|
const skillResult = isAsync ? await ensureDevBrowserSkillAsync(skillOpts) : ensureDevBrowserSkill(skillOpts);
|
|
3819
4329
|
if (skillResult.status === "failed") {
|
|
@@ -3825,7 +4335,7 @@ var SkillInstallUpdateStep = class {
|
|
|
3825
4335
|
};
|
|
3826
4336
|
|
|
3827
4337
|
// src/core/variant-builder/update-steps/FinalizeUpdateStep.ts
|
|
3828
|
-
import
|
|
4338
|
+
import path20 from "node:path";
|
|
3829
4339
|
var FinalizeUpdateStep = class {
|
|
3830
4340
|
name = "Finalize";
|
|
3831
4341
|
execute(ctx) {
|
|
@@ -3843,14 +4353,18 @@ var FinalizeUpdateStep = class {
|
|
|
3843
4353
|
meta.promptPackMode = prefs.promptPackModePreference;
|
|
3844
4354
|
meta.skillInstall = prefs.skillInstallEnabled;
|
|
3845
4355
|
meta.shellEnv = prefs.shellEnvEnabled;
|
|
3846
|
-
writeJson(
|
|
4356
|
+
writeJson(path20.join(paths.variantDir, "variant.json"), meta);
|
|
3847
4357
|
}
|
|
3848
4358
|
};
|
|
3849
4359
|
|
|
3850
4360
|
// src/core/variant-builder/VariantUpdater.ts
|
|
3851
4361
|
var normalizeNpmPackage2 = (value) => value && value.trim().length > 0 ? value.trim() : DEFAULT_NPM_PACKAGE;
|
|
3852
4362
|
var normalizeNpmVersion2 = () => DEFAULT_NPM_VERSION;
|
|
3853
|
-
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
|
+
};
|
|
3854
4368
|
var defaultPromptPackMode2 = (providerKey) => providerKey === "zai" || providerKey === "minimax" ? "maximal" : "minimal";
|
|
3855
4369
|
var shouldInstallSkills2 = (providerKey) => providerKey === "zai" || providerKey === "minimax";
|
|
3856
4370
|
var shouldEnableShellEnv2 = (providerKey) => providerKey === "zai";
|
|
@@ -3860,6 +4374,8 @@ var VariantUpdater = class {
|
|
|
3860
4374
|
this.isAsync = isAsync;
|
|
3861
4375
|
this.steps = [
|
|
3862
4376
|
new InstallNpmUpdateStep(),
|
|
4377
|
+
new TeamModeUpdateStep(),
|
|
4378
|
+
// Patches cli.js for team mode (if enabled)
|
|
3863
4379
|
new ModelOverridesStep(),
|
|
3864
4380
|
new TweakccUpdateStep(),
|
|
3865
4381
|
new WrapperUpdateStep(),
|
|
@@ -3875,7 +4391,7 @@ var VariantUpdater = class {
|
|
|
3875
4391
|
*/
|
|
3876
4392
|
initContext(rootDir, name, opts) {
|
|
3877
4393
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3878
|
-
const variantDir =
|
|
4394
|
+
const variantDir = path21.join(resolvedRoot, name);
|
|
3879
4395
|
const meta = loadVariantMeta(variantDir);
|
|
3880
4396
|
if (!meta) throw new Error(`Variant not found: ${name}`);
|
|
3881
4397
|
const resolvedNpmPackage = normalizeNpmPackage2(opts.npmPackage ?? meta.npmPackage);
|
|
@@ -3891,7 +4407,7 @@ var VariantUpdater = class {
|
|
|
3891
4407
|
resolvedRoot,
|
|
3892
4408
|
resolvedBin: opts.binDir ? expandTilde(opts.binDir) ?? opts.binDir : meta.binDir,
|
|
3893
4409
|
variantDir,
|
|
3894
|
-
npmDir: meta.npmDir ||
|
|
4410
|
+
npmDir: meta.npmDir || path21.join(variantDir, "npm")
|
|
3895
4411
|
};
|
|
3896
4412
|
const prefs = {
|
|
3897
4413
|
resolvedNpmPackage,
|
|
@@ -3973,17 +4489,17 @@ var updateVariant = (rootDir, name, opts = {}) => {
|
|
|
3973
4489
|
};
|
|
3974
4490
|
var removeVariant = (rootDir, name) => {
|
|
3975
4491
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3976
|
-
const variantDir =
|
|
3977
|
-
if (!
|
|
3978
|
-
|
|
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 });
|
|
3979
4495
|
};
|
|
3980
4496
|
var doctor = (rootDir, binDir) => {
|
|
3981
4497
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3982
4498
|
const resolvedBin = expandTilde(binDir || DEFAULT_BIN_DIR) ?? binDir;
|
|
3983
4499
|
const variants = listVariants(resolvedRoot);
|
|
3984
4500
|
return variants.map(({ name, meta }) => {
|
|
3985
|
-
const wrapperPath =
|
|
3986
|
-
const ok = Boolean(meta &&
|
|
4501
|
+
const wrapperPath = path22.join(resolvedBin, name);
|
|
4502
|
+
const ok = Boolean(meta && fs13.existsSync(meta.binaryPath) && fs13.existsSync(wrapperPath));
|
|
3987
4503
|
return {
|
|
3988
4504
|
name,
|
|
3989
4505
|
ok,
|
|
@@ -3995,7 +4511,7 @@ var doctor = (rootDir, binDir) => {
|
|
|
3995
4511
|
var listVariants2 = (rootDir) => listVariants(rootDir);
|
|
3996
4512
|
var tweakVariant = (rootDir, name) => {
|
|
3997
4513
|
const resolvedRoot = expandTilde(rootDir || DEFAULT_ROOT) ?? rootDir;
|
|
3998
|
-
const variantDir =
|
|
4514
|
+
const variantDir = path22.join(resolvedRoot, name);
|
|
3999
4515
|
const meta = loadVariantMeta(variantDir);
|
|
4000
4516
|
if (!meta) throw new Error(`Variant not found: ${name}`);
|
|
4001
4517
|
ensureDir(meta.tweakDir);
|
|
@@ -4069,7 +4585,7 @@ function runTweakCommand({ opts }) {
|
|
|
4069
4585
|
}
|
|
4070
4586
|
|
|
4071
4587
|
// src/cli/commands/update.ts
|
|
4072
|
-
import
|
|
4588
|
+
import path23 from "node:path";
|
|
4073
4589
|
|
|
4074
4590
|
// src/cli/utils/buildShareUrl.ts
|
|
4075
4591
|
function buildShareUrl(providerLabel, variant, mode) {
|
|
@@ -4228,9 +4744,10 @@ function runUpdateCommand({ opts }) {
|
|
|
4228
4744
|
promptPackMode,
|
|
4229
4745
|
skillInstall,
|
|
4230
4746
|
shellEnv,
|
|
4231
|
-
skillUpdate
|
|
4747
|
+
skillUpdate,
|
|
4748
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4232
4749
|
});
|
|
4233
|
-
const wrapperPath =
|
|
4750
|
+
const wrapperPath = path23.join(binDir, name);
|
|
4234
4751
|
printSummary({
|
|
4235
4752
|
action: "Updated",
|
|
4236
4753
|
meta: result.meta,
|
|
@@ -4329,7 +4846,8 @@ async function handleQuickMode(opts, params) {
|
|
|
4329
4846
|
skillInstall,
|
|
4330
4847
|
shellEnv,
|
|
4331
4848
|
skillUpdate,
|
|
4332
|
-
modelOverrides: resolvedModelOverrides
|
|
4849
|
+
modelOverrides: resolvedModelOverrides,
|
|
4850
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4333
4851
|
});
|
|
4334
4852
|
const shareUrl = buildShareUrl(provider.label || params.providerKey, params.name, result.meta.promptPackMode);
|
|
4335
4853
|
const modelNote = formatModelNote(resolvedModelOverrides);
|
|
@@ -4389,7 +4907,8 @@ async function handleInteractiveMode(opts, params) {
|
|
|
4389
4907
|
skillInstall,
|
|
4390
4908
|
shellEnv,
|
|
4391
4909
|
skillUpdate,
|
|
4392
|
-
modelOverrides: resolvedModelOverrides
|
|
4910
|
+
modelOverrides: resolvedModelOverrides,
|
|
4911
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4393
4912
|
});
|
|
4394
4913
|
const shareUrl = buildShareUrl(provider.label || params.providerKey, result.meta.name, result.meta.promptPackMode);
|
|
4395
4914
|
const modelNote = formatModelNote(resolvedModelOverrides);
|
|
@@ -4430,7 +4949,8 @@ async function handleNonInteractiveMode(opts, params) {
|
|
|
4430
4949
|
skillInstall,
|
|
4431
4950
|
shellEnv,
|
|
4432
4951
|
skillUpdate,
|
|
4433
|
-
modelOverrides: resolvedModelOverrides
|
|
4952
|
+
modelOverrides: resolvedModelOverrides,
|
|
4953
|
+
enableTeamMode: Boolean(opts["enable-team-mode"])
|
|
4434
4954
|
});
|
|
4435
4955
|
const shareUrl = buildShareUrl(provider.label || params.providerKey, result.meta.name, result.meta.promptPackMode);
|
|
4436
4956
|
const modelNote = formatModelNote(resolvedModelOverrides);
|