@cleocode/caamp 0.2.0 → 0.3.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 +1 -0
- package/dist/{chunk-RW745KDU.js → chunk-PCWTRJV2.js} +154 -87
- package/dist/chunk-PCWTRJV2.js.map +1 -0
- package/dist/cli.js +267 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1490 -60
- package/dist/index.js +9 -1
- package/package.json +13 -10
- package/dist/chunk-RW745KDU.js.map +0 -1
package/README.md
CHANGED
|
@@ -184,6 +184,7 @@ Each provider uses a different key name for MCP server configuration:
|
|
|
184
184
|
| Document | Description |
|
|
185
185
|
|----------|-------------|
|
|
186
186
|
| [API Reference](docs/API-REFERENCE.md) | Full library API (82 exports with signatures and examples) |
|
|
187
|
+
| [Generated API Docs](docs/api/) | Auto-generated from TSDoc (run `npm run docs:api`) |
|
|
187
188
|
| [Vision & Architecture](claudedocs/VISION.md) | Project vision, design philosophy, and architecture |
|
|
188
189
|
| [Product Requirements](claudedocs/PRD.md) | Full PRD with user stories and feature requirements |
|
|
189
190
|
| [Technical Specification](claudedocs/specs/CAAMP-SPEC.md) | RFC 2119 spec covering all subsystems |
|
|
@@ -140,13 +140,33 @@ function getRegistryVersion() {
|
|
|
140
140
|
return loadRegistry().version;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
// src/core/logger.ts
|
|
144
|
+
var verboseMode = false;
|
|
145
|
+
var quietMode = false;
|
|
146
|
+
function setVerbose(v) {
|
|
147
|
+
verboseMode = v;
|
|
148
|
+
}
|
|
149
|
+
function setQuiet(q) {
|
|
150
|
+
quietMode = q;
|
|
151
|
+
}
|
|
152
|
+
function debug(...args) {
|
|
153
|
+
if (verboseMode) console.error("[debug]", ...args);
|
|
154
|
+
}
|
|
155
|
+
function isVerbose() {
|
|
156
|
+
return verboseMode;
|
|
157
|
+
}
|
|
158
|
+
function isQuiet() {
|
|
159
|
+
return quietMode;
|
|
160
|
+
}
|
|
161
|
+
|
|
143
162
|
// src/core/registry/detection.ts
|
|
144
163
|
import { existsSync as existsSync2 } from "fs";
|
|
145
164
|
import { execFileSync } from "child_process";
|
|
146
165
|
import { join as join2 } from "path";
|
|
147
166
|
function checkBinary(binary) {
|
|
148
167
|
try {
|
|
149
|
-
|
|
168
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
169
|
+
execFileSync(cmd, [binary], { stdio: "pipe" });
|
|
150
170
|
return true;
|
|
151
171
|
} catch {
|
|
152
172
|
return false;
|
|
@@ -171,10 +191,12 @@ function checkFlatpak(flatpakId) {
|
|
|
171
191
|
function detectProvider(provider) {
|
|
172
192
|
const matchedMethods = [];
|
|
173
193
|
const detection = provider.detection;
|
|
194
|
+
debug(`detecting provider ${provider.id} via methods: ${detection.methods.join(", ")}`);
|
|
174
195
|
for (const method of detection.methods) {
|
|
175
196
|
switch (method) {
|
|
176
197
|
case "binary":
|
|
177
198
|
if (detection.binary && checkBinary(detection.binary)) {
|
|
199
|
+
debug(` ${provider.id}: binary "${detection.binary}" found`);
|
|
178
200
|
matchedMethods.push("binary");
|
|
179
201
|
}
|
|
180
202
|
break;
|
|
@@ -444,7 +466,7 @@ async function listCanonicalSkills() {
|
|
|
444
466
|
return entries.filter((e) => e.isDirectory() || e.isSymbolicLink()).map((e) => e.name);
|
|
445
467
|
}
|
|
446
468
|
|
|
447
|
-
// src/core/
|
|
469
|
+
// src/core/lock-utils.ts
|
|
448
470
|
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
449
471
|
import { existsSync as existsSync4 } from "fs";
|
|
450
472
|
import { homedir as homedir3 } from "os";
|
|
@@ -466,55 +488,9 @@ async function writeLockFile(lock) {
|
|
|
466
488
|
await mkdir2(LOCK_DIR, { recursive: true });
|
|
467
489
|
await writeFile2(LOCK_FILE, JSON.stringify(lock, null, 2) + "\n", "utf-8");
|
|
468
490
|
}
|
|
469
|
-
async function recordMcpInstall(serverName, source, sourceType, agents, isGlobal) {
|
|
470
|
-
const lock = await readLockFile();
|
|
471
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
472
|
-
const existing = lock.mcpServers[serverName];
|
|
473
|
-
lock.mcpServers[serverName] = {
|
|
474
|
-
name: serverName,
|
|
475
|
-
scopedName: serverName,
|
|
476
|
-
source,
|
|
477
|
-
sourceType,
|
|
478
|
-
installedAt: existing?.installedAt ?? now,
|
|
479
|
-
updatedAt: now,
|
|
480
|
-
agents: [.../* @__PURE__ */ new Set([...existing?.agents ?? [], ...agents])],
|
|
481
|
-
canonicalPath: "",
|
|
482
|
-
isGlobal
|
|
483
|
-
};
|
|
484
|
-
await writeLockFile(lock);
|
|
485
|
-
}
|
|
486
|
-
async function removeMcpFromLock(serverName) {
|
|
487
|
-
const lock = await readLockFile();
|
|
488
|
-
if (!(serverName in lock.mcpServers)) return false;
|
|
489
|
-
delete lock.mcpServers[serverName];
|
|
490
|
-
await writeLockFile(lock);
|
|
491
|
-
return true;
|
|
492
|
-
}
|
|
493
|
-
async function getTrackedMcpServers() {
|
|
494
|
-
const lock = await readLockFile();
|
|
495
|
-
return lock.mcpServers;
|
|
496
|
-
}
|
|
497
|
-
async function saveLastSelectedAgents(agents) {
|
|
498
|
-
const lock = await readLockFile();
|
|
499
|
-
lock.lastSelectedAgents = agents;
|
|
500
|
-
await writeLockFile(lock);
|
|
501
|
-
}
|
|
502
|
-
async function getLastSelectedAgents() {
|
|
503
|
-
const lock = await readLockFile();
|
|
504
|
-
return lock.lastSelectedAgents;
|
|
505
|
-
}
|
|
506
491
|
|
|
507
492
|
// src/core/skills/lock.ts
|
|
508
493
|
import { simpleGit } from "simple-git";
|
|
509
|
-
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
510
|
-
import { homedir as homedir4 } from "os";
|
|
511
|
-
import { join as join5 } from "path";
|
|
512
|
-
var LOCK_DIR2 = join5(homedir4(), ".agents");
|
|
513
|
-
var LOCK_FILE2 = join5(LOCK_DIR2, ".caamp-lock.json");
|
|
514
|
-
async function writeLockFile2(lock) {
|
|
515
|
-
await mkdir3(LOCK_DIR2, { recursive: true });
|
|
516
|
-
await writeFile3(LOCK_FILE2, JSON.stringify(lock, null, 2) + "\n", "utf-8");
|
|
517
|
-
}
|
|
518
494
|
async function recordSkillInstall(skillName, scopedName, source, sourceType, agents, canonicalPath, isGlobal, projectDir, version) {
|
|
519
495
|
const lock = await readLockFile();
|
|
520
496
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -532,13 +508,13 @@ async function recordSkillInstall(skillName, scopedName, source, sourceType, age
|
|
|
532
508
|
isGlobal,
|
|
533
509
|
projectDir
|
|
534
510
|
};
|
|
535
|
-
await
|
|
511
|
+
await writeLockFile(lock);
|
|
536
512
|
}
|
|
537
513
|
async function removeSkillFromLock(skillName) {
|
|
538
514
|
const lock = await readLockFile();
|
|
539
515
|
if (!(skillName in lock.skills)) return false;
|
|
540
516
|
delete lock.skills[skillName];
|
|
541
|
-
await
|
|
517
|
+
await writeLockFile(lock);
|
|
542
518
|
return true;
|
|
543
519
|
}
|
|
544
520
|
async function getTrackedSkills() {
|
|
@@ -691,13 +667,42 @@ var SkillsShAdapter = class {
|
|
|
691
667
|
// src/core/marketplace/client.ts
|
|
692
668
|
var MarketplaceClient = class {
|
|
693
669
|
adapters;
|
|
670
|
+
/**
|
|
671
|
+
* Create a new marketplace client.
|
|
672
|
+
*
|
|
673
|
+
* @param adapters - Custom marketplace adapters (defaults to agentskills.in and skills.sh)
|
|
674
|
+
*
|
|
675
|
+
* @example
|
|
676
|
+
* ```typescript
|
|
677
|
+
* // Use default adapters
|
|
678
|
+
* const client = new MarketplaceClient();
|
|
679
|
+
*
|
|
680
|
+
* // Use custom adapters
|
|
681
|
+
* const client = new MarketplaceClient([myAdapter]);
|
|
682
|
+
* ```
|
|
683
|
+
*/
|
|
694
684
|
constructor(adapters) {
|
|
695
685
|
this.adapters = adapters ?? [
|
|
696
686
|
new SkillsMPAdapter(),
|
|
697
687
|
new SkillsShAdapter()
|
|
698
688
|
];
|
|
699
689
|
}
|
|
700
|
-
/**
|
|
690
|
+
/**
|
|
691
|
+
* Search all marketplaces and return deduplicated, sorted results.
|
|
692
|
+
*
|
|
693
|
+
* Queries all adapters in parallel and deduplicates by `scopedName`,
|
|
694
|
+
* keeping the entry with the highest star count. Results are sorted by
|
|
695
|
+
* stars descending.
|
|
696
|
+
*
|
|
697
|
+
* @param query - Search query string
|
|
698
|
+
* @param limit - Maximum number of results to return (default: 20)
|
|
699
|
+
* @returns Deduplicated and sorted marketplace results
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* const results = await client.search("code review", 10);
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
701
706
|
async search(query, limit = 20) {
|
|
702
707
|
const promises = this.adapters.map(
|
|
703
708
|
(adapter) => adapter.search(query, limit).catch(() => [])
|
|
@@ -715,7 +720,19 @@ var MarketplaceClient = class {
|
|
|
715
720
|
deduplicated.sort((a, b) => b.stars - a.stars);
|
|
716
721
|
return deduplicated.slice(0, limit);
|
|
717
722
|
}
|
|
718
|
-
/**
|
|
723
|
+
/**
|
|
724
|
+
* Get a specific skill by its scoped name from any marketplace.
|
|
725
|
+
*
|
|
726
|
+
* Tries each adapter in order and returns the first match.
|
|
727
|
+
*
|
|
728
|
+
* @param scopedName - Scoped skill name (e.g. `"@author/my-skill"`)
|
|
729
|
+
* @returns The marketplace result, or `null` if not found in any marketplace
|
|
730
|
+
*
|
|
731
|
+
* @example
|
|
732
|
+
* ```typescript
|
|
733
|
+
* const skill = await client.getSkill("@anthropic/memory");
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
719
736
|
async getSkill(scopedName) {
|
|
720
737
|
for (const adapter of this.adapters) {
|
|
721
738
|
const result = await adapter.getSkill(scopedName).catch(() => null);
|
|
@@ -728,7 +745,7 @@ var MarketplaceClient = class {
|
|
|
728
745
|
// src/core/skills/discovery.ts
|
|
729
746
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
730
747
|
import { existsSync as existsSync5 } from "fs";
|
|
731
|
-
import { join as
|
|
748
|
+
import { join as join5 } from "path";
|
|
732
749
|
import matter from "gray-matter";
|
|
733
750
|
async function parseSkillFile(filePath) {
|
|
734
751
|
try {
|
|
@@ -752,7 +769,7 @@ async function parseSkillFile(filePath) {
|
|
|
752
769
|
}
|
|
753
770
|
}
|
|
754
771
|
async function discoverSkill(skillDir) {
|
|
755
|
-
const skillFile =
|
|
772
|
+
const skillFile = join5(skillDir, "SKILL.md");
|
|
756
773
|
if (!existsSync5(skillFile)) return null;
|
|
757
774
|
const metadata = await parseSkillFile(skillFile);
|
|
758
775
|
if (!metadata) return null;
|
|
@@ -769,7 +786,7 @@ async function discoverSkills(rootDir) {
|
|
|
769
786
|
const skills = [];
|
|
770
787
|
for (const entry of entries) {
|
|
771
788
|
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
772
|
-
const skillDir =
|
|
789
|
+
const skillDir = join5(rootDir, entry.name);
|
|
773
790
|
const skill = await discoverSkill(skillDir);
|
|
774
791
|
if (skill) {
|
|
775
792
|
skills.push(skill);
|
|
@@ -1205,13 +1222,13 @@ async function scanFile(filePath, rules) {
|
|
|
1205
1222
|
}
|
|
1206
1223
|
async function scanDirectory(dirPath) {
|
|
1207
1224
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
1208
|
-
const { join:
|
|
1225
|
+
const { join: join8 } = await import("path");
|
|
1209
1226
|
if (!existsSync6(dirPath)) return [];
|
|
1210
1227
|
const entries = await readdir2(dirPath, { withFileTypes: true });
|
|
1211
1228
|
const results = [];
|
|
1212
1229
|
for (const entry of entries) {
|
|
1213
1230
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
1214
|
-
const skillFile =
|
|
1231
|
+
const skillFile = join8(dirPath, entry.name, "SKILL.md");
|
|
1215
1232
|
if (existsSync6(skillFile)) {
|
|
1216
1233
|
results.push(await scanFile(skillFile));
|
|
1217
1234
|
}
|
|
@@ -1425,13 +1442,13 @@ function getNestedValue(obj, keyPath) {
|
|
|
1425
1442
|
return current;
|
|
1426
1443
|
}
|
|
1427
1444
|
async function ensureDir(filePath) {
|
|
1428
|
-
const { mkdir:
|
|
1429
|
-
const { dirname:
|
|
1430
|
-
await
|
|
1445
|
+
const { mkdir: mkdir4 } = await import("fs/promises");
|
|
1446
|
+
const { dirname: dirname4 } = await import("path");
|
|
1447
|
+
await mkdir4(dirname4(filePath), { recursive: true });
|
|
1431
1448
|
}
|
|
1432
1449
|
|
|
1433
1450
|
// src/core/formats/json.ts
|
|
1434
|
-
import { readFile as readFile6, writeFile as
|
|
1451
|
+
import { readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
|
|
1435
1452
|
import { existsSync as existsSync8 } from "fs";
|
|
1436
1453
|
import * as jsonc from "jsonc-parser";
|
|
1437
1454
|
async function readJsonConfig(filePath) {
|
|
@@ -1485,7 +1502,7 @@ async function writeJsonConfig(filePath, configKey, serverName, serverConfig) {
|
|
|
1485
1502
|
if (!content.endsWith("\n")) {
|
|
1486
1503
|
content += "\n";
|
|
1487
1504
|
}
|
|
1488
|
-
await
|
|
1505
|
+
await writeFile3(filePath, content, "utf-8");
|
|
1489
1506
|
}
|
|
1490
1507
|
async function removeJsonConfig(filePath, configKey, serverName) {
|
|
1491
1508
|
if (!existsSync8(filePath)) return false;
|
|
@@ -1505,12 +1522,12 @@ async function removeJsonConfig(filePath, configKey, serverName) {
|
|
|
1505
1522
|
if (!content.endsWith("\n")) {
|
|
1506
1523
|
content += "\n";
|
|
1507
1524
|
}
|
|
1508
|
-
await
|
|
1525
|
+
await writeFile3(filePath, content, "utf-8");
|
|
1509
1526
|
return true;
|
|
1510
1527
|
}
|
|
1511
1528
|
|
|
1512
1529
|
// src/core/formats/yaml.ts
|
|
1513
|
-
import { readFile as readFile7, writeFile as
|
|
1530
|
+
import { readFile as readFile7, writeFile as writeFile4 } from "fs/promises";
|
|
1514
1531
|
import { existsSync as existsSync9 } from "fs";
|
|
1515
1532
|
import yaml from "js-yaml";
|
|
1516
1533
|
async function readYamlConfig(filePath) {
|
|
@@ -1535,7 +1552,7 @@ async function writeYamlConfig(filePath, configKey, serverName, serverConfig) {
|
|
|
1535
1552
|
noRefs: true,
|
|
1536
1553
|
sortKeys: false
|
|
1537
1554
|
});
|
|
1538
|
-
await
|
|
1555
|
+
await writeFile4(filePath, content, "utf-8");
|
|
1539
1556
|
}
|
|
1540
1557
|
async function removeYamlConfig(filePath, configKey, serverName) {
|
|
1541
1558
|
if (!existsSync9(filePath)) return false;
|
|
@@ -1555,12 +1572,12 @@ async function removeYamlConfig(filePath, configKey, serverName) {
|
|
|
1555
1572
|
noRefs: true,
|
|
1556
1573
|
sortKeys: false
|
|
1557
1574
|
});
|
|
1558
|
-
await
|
|
1575
|
+
await writeFile4(filePath, content, "utf-8");
|
|
1559
1576
|
return true;
|
|
1560
1577
|
}
|
|
1561
1578
|
|
|
1562
1579
|
// src/core/formats/toml.ts
|
|
1563
|
-
import { readFile as readFile8, writeFile as
|
|
1580
|
+
import { readFile as readFile8, writeFile as writeFile5 } from "fs/promises";
|
|
1564
1581
|
import { existsSync as existsSync10 } from "fs";
|
|
1565
1582
|
import TOML from "@iarna/toml";
|
|
1566
1583
|
async function readTomlConfig(filePath) {
|
|
@@ -1580,7 +1597,7 @@ async function writeTomlConfig(filePath, configKey, serverName, serverConfig) {
|
|
|
1580
1597
|
}
|
|
1581
1598
|
const merged = deepMerge(existing, newEntry);
|
|
1582
1599
|
const content = TOML.stringify(merged);
|
|
1583
|
-
await
|
|
1600
|
+
await writeFile5(filePath, content, "utf-8");
|
|
1584
1601
|
}
|
|
1585
1602
|
async function removeTomlConfig(filePath, configKey, serverName) {
|
|
1586
1603
|
if (!existsSync10(filePath)) return false;
|
|
@@ -1595,12 +1612,13 @@ async function removeTomlConfig(filePath, configKey, serverName) {
|
|
|
1595
1612
|
if (!(serverName in current)) return false;
|
|
1596
1613
|
delete current[serverName];
|
|
1597
1614
|
const content = TOML.stringify(existing);
|
|
1598
|
-
await
|
|
1615
|
+
await writeFile5(filePath, content, "utf-8");
|
|
1599
1616
|
return true;
|
|
1600
1617
|
}
|
|
1601
1618
|
|
|
1602
1619
|
// src/core/formats/index.ts
|
|
1603
1620
|
async function readConfig(filePath, format) {
|
|
1621
|
+
debug(`reading config: ${filePath} (format: ${format})`);
|
|
1604
1622
|
switch (format) {
|
|
1605
1623
|
case "json":
|
|
1606
1624
|
case "jsonc":
|
|
@@ -1614,6 +1632,7 @@ async function readConfig(filePath, format) {
|
|
|
1614
1632
|
}
|
|
1615
1633
|
}
|
|
1616
1634
|
async function writeConfig(filePath, format, key, serverName, serverConfig) {
|
|
1635
|
+
debug(`writing config: ${filePath} (format: ${format}, key: ${key}, server: ${serverName})`);
|
|
1617
1636
|
switch (format) {
|
|
1618
1637
|
case "json":
|
|
1619
1638
|
case "jsonc":
|
|
@@ -1737,17 +1756,18 @@ function getTransform(providerId) {
|
|
|
1737
1756
|
}
|
|
1738
1757
|
|
|
1739
1758
|
// src/core/mcp/reader.ts
|
|
1740
|
-
import { join as
|
|
1759
|
+
import { join as join6 } from "path";
|
|
1741
1760
|
import { existsSync as existsSync11 } from "fs";
|
|
1742
1761
|
function resolveConfigPath(provider, scope, projectDir) {
|
|
1743
1762
|
if (scope === "project") {
|
|
1744
1763
|
if (!provider.configPathProject) return null;
|
|
1745
|
-
return
|
|
1764
|
+
return join6(projectDir ?? process.cwd(), provider.configPathProject);
|
|
1746
1765
|
}
|
|
1747
1766
|
return provider.configPathGlobal;
|
|
1748
1767
|
}
|
|
1749
1768
|
async function listMcpServers(provider, scope, projectDir) {
|
|
1750
1769
|
const configPath = resolveConfigPath(provider, scope, projectDir);
|
|
1770
|
+
debug(`listing MCP servers for ${provider.id} (${scope}) at ${configPath ?? "(none)"}`);
|
|
1751
1771
|
if (!configPath || !existsSync11(configPath)) return [];
|
|
1752
1772
|
try {
|
|
1753
1773
|
const config = await readConfig(configPath, provider.configFormat);
|
|
@@ -1797,6 +1817,8 @@ function buildConfig(provider, serverName, config) {
|
|
|
1797
1817
|
}
|
|
1798
1818
|
async function installMcpServer(provider, serverName, config, scope = "project", projectDir) {
|
|
1799
1819
|
const configPath = resolveConfigPath(provider, scope, projectDir);
|
|
1820
|
+
debug(`installing MCP server "${serverName}" for ${provider.id} (${scope})`);
|
|
1821
|
+
debug(` config path: ${configPath ?? "(none)"}`);
|
|
1800
1822
|
if (!configPath) {
|
|
1801
1823
|
return {
|
|
1802
1824
|
provider,
|
|
@@ -1808,6 +1830,8 @@ async function installMcpServer(provider, serverName, config, scope = "project",
|
|
|
1808
1830
|
}
|
|
1809
1831
|
try {
|
|
1810
1832
|
const transformedConfig = buildConfig(provider, serverName, config);
|
|
1833
|
+
const transform = getTransform(provider.id);
|
|
1834
|
+
debug(` transform applied: ${transform ? "yes" : "no"}`);
|
|
1811
1835
|
await writeConfig(
|
|
1812
1836
|
configPath,
|
|
1813
1837
|
provider.configFormat,
|
|
@@ -1860,11 +1884,50 @@ function buildServerConfig(source, transport, headers) {
|
|
|
1860
1884
|
};
|
|
1861
1885
|
}
|
|
1862
1886
|
|
|
1887
|
+
// src/core/mcp/lock.ts
|
|
1888
|
+
async function recordMcpInstall(serverName, source, sourceType, agents, isGlobal) {
|
|
1889
|
+
const lock = await readLockFile();
|
|
1890
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1891
|
+
const existing = lock.mcpServers[serverName];
|
|
1892
|
+
lock.mcpServers[serverName] = {
|
|
1893
|
+
name: serverName,
|
|
1894
|
+
scopedName: serverName,
|
|
1895
|
+
source,
|
|
1896
|
+
sourceType,
|
|
1897
|
+
installedAt: existing?.installedAt ?? now,
|
|
1898
|
+
updatedAt: now,
|
|
1899
|
+
agents: [.../* @__PURE__ */ new Set([...existing?.agents ?? [], ...agents])],
|
|
1900
|
+
canonicalPath: "",
|
|
1901
|
+
isGlobal
|
|
1902
|
+
};
|
|
1903
|
+
await writeLockFile(lock);
|
|
1904
|
+
}
|
|
1905
|
+
async function removeMcpFromLock(serverName) {
|
|
1906
|
+
const lock = await readLockFile();
|
|
1907
|
+
if (!(serverName in lock.mcpServers)) return false;
|
|
1908
|
+
delete lock.mcpServers[serverName];
|
|
1909
|
+
await writeLockFile(lock);
|
|
1910
|
+
return true;
|
|
1911
|
+
}
|
|
1912
|
+
async function getTrackedMcpServers() {
|
|
1913
|
+
const lock = await readLockFile();
|
|
1914
|
+
return lock.mcpServers;
|
|
1915
|
+
}
|
|
1916
|
+
async function saveLastSelectedAgents(agents) {
|
|
1917
|
+
const lock = await readLockFile();
|
|
1918
|
+
lock.lastSelectedAgents = agents;
|
|
1919
|
+
await writeLockFile(lock);
|
|
1920
|
+
}
|
|
1921
|
+
async function getLastSelectedAgents() {
|
|
1922
|
+
const lock = await readLockFile();
|
|
1923
|
+
return lock.lastSelectedAgents;
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1863
1926
|
// src/core/instructions/injector.ts
|
|
1864
|
-
import { readFile as readFile9, writeFile as
|
|
1927
|
+
import { readFile as readFile9, writeFile as writeFile6 } from "fs/promises";
|
|
1865
1928
|
import { existsSync as existsSync12 } from "fs";
|
|
1866
|
-
import { join as
|
|
1867
|
-
import { mkdir as
|
|
1929
|
+
import { join as join7, dirname as dirname3 } from "path";
|
|
1930
|
+
import { mkdir as mkdir3 } from "fs/promises";
|
|
1868
1931
|
var MARKER_START = "<!-- CAAMP:START -->";
|
|
1869
1932
|
var MARKER_END = "<!-- CAAMP:END -->";
|
|
1870
1933
|
var MARKER_PATTERN = /<!-- CAAMP:START -->[\s\S]*?<!-- CAAMP:END -->/;
|
|
@@ -1893,19 +1956,19 @@ ${MARKER_END}`;
|
|
|
1893
1956
|
}
|
|
1894
1957
|
async function inject(filePath, content) {
|
|
1895
1958
|
const block = buildBlock(content);
|
|
1896
|
-
await
|
|
1959
|
+
await mkdir3(dirname3(filePath), { recursive: true });
|
|
1897
1960
|
if (!existsSync12(filePath)) {
|
|
1898
|
-
await
|
|
1961
|
+
await writeFile6(filePath, block + "\n", "utf-8");
|
|
1899
1962
|
return "created";
|
|
1900
1963
|
}
|
|
1901
1964
|
const existing = await readFile9(filePath, "utf-8");
|
|
1902
1965
|
if (MARKER_PATTERN.test(existing)) {
|
|
1903
1966
|
const updated2 = existing.replace(MARKER_PATTERN, block);
|
|
1904
|
-
await
|
|
1967
|
+
await writeFile6(filePath, updated2, "utf-8");
|
|
1905
1968
|
return "updated";
|
|
1906
1969
|
}
|
|
1907
1970
|
const updated = block + "\n\n" + existing;
|
|
1908
|
-
await
|
|
1971
|
+
await writeFile6(filePath, updated, "utf-8");
|
|
1909
1972
|
return "added";
|
|
1910
1973
|
}
|
|
1911
1974
|
async function removeInjection(filePath) {
|
|
@@ -1917,7 +1980,7 @@ async function removeInjection(filePath) {
|
|
|
1917
1980
|
const { rm: rm2 } = await import("fs/promises");
|
|
1918
1981
|
await rm2(filePath);
|
|
1919
1982
|
} else {
|
|
1920
|
-
await
|
|
1983
|
+
await writeFile6(filePath, cleaned + "\n", "utf-8");
|
|
1921
1984
|
}
|
|
1922
1985
|
return true;
|
|
1923
1986
|
}
|
|
@@ -1925,7 +1988,7 @@ async function checkAllInjections(providers, projectDir, scope, expectedContent)
|
|
|
1925
1988
|
const results = [];
|
|
1926
1989
|
const checked = /* @__PURE__ */ new Set();
|
|
1927
1990
|
for (const provider of providers) {
|
|
1928
|
-
const filePath = scope === "global" ?
|
|
1991
|
+
const filePath = scope === "global" ? join7(provider.pathGlobal, provider.instructFile) : join7(projectDir, provider.instructFile);
|
|
1929
1992
|
if (checked.has(filePath)) continue;
|
|
1930
1993
|
checked.add(filePath);
|
|
1931
1994
|
const status = await checkInjection(filePath, expectedContent);
|
|
@@ -1942,7 +2005,7 @@ async function injectAll(providers, projectDir, scope, content) {
|
|
|
1942
2005
|
const results = /* @__PURE__ */ new Map();
|
|
1943
2006
|
const injected = /* @__PURE__ */ new Set();
|
|
1944
2007
|
for (const provider of providers) {
|
|
1945
|
-
const filePath = scope === "global" ?
|
|
2008
|
+
const filePath = scope === "global" ? join7(provider.pathGlobal, provider.instructFile) : join7(projectDir, provider.instructFile);
|
|
1946
2009
|
if (injected.has(filePath)) continue;
|
|
1947
2010
|
injected.add(filePath);
|
|
1948
2011
|
const action = await inject(filePath, content);
|
|
@@ -1989,6 +2052,10 @@ export {
|
|
|
1989
2052
|
getInstructionFiles,
|
|
1990
2053
|
getProviderCount,
|
|
1991
2054
|
getRegistryVersion,
|
|
2055
|
+
setVerbose,
|
|
2056
|
+
setQuiet,
|
|
2057
|
+
isVerbose,
|
|
2058
|
+
isQuiet,
|
|
1992
2059
|
detectProvider,
|
|
1993
2060
|
detectAllProviders,
|
|
1994
2061
|
getInstalledProviders,
|
|
@@ -1999,11 +2066,6 @@ export {
|
|
|
1999
2066
|
removeSkill,
|
|
2000
2067
|
listCanonicalSkills,
|
|
2001
2068
|
readLockFile,
|
|
2002
|
-
recordMcpInstall,
|
|
2003
|
-
removeMcpFromLock,
|
|
2004
|
-
getTrackedMcpServers,
|
|
2005
|
-
saveLastSelectedAgents,
|
|
2006
|
-
getLastSelectedAgents,
|
|
2007
2069
|
recordSkillInstall,
|
|
2008
2070
|
removeSkillFromLock,
|
|
2009
2071
|
getTrackedSkills,
|
|
@@ -2031,6 +2093,11 @@ export {
|
|
|
2031
2093
|
installMcpServer,
|
|
2032
2094
|
installMcpServerToAll,
|
|
2033
2095
|
buildServerConfig,
|
|
2096
|
+
recordMcpInstall,
|
|
2097
|
+
removeMcpFromLock,
|
|
2098
|
+
getTrackedMcpServers,
|
|
2099
|
+
saveLastSelectedAgents,
|
|
2100
|
+
getLastSelectedAgents,
|
|
2034
2101
|
checkInjection,
|
|
2035
2102
|
inject,
|
|
2036
2103
|
removeInjection,
|
|
@@ -2039,4 +2106,4 @@ export {
|
|
|
2039
2106
|
generateInjectionContent,
|
|
2040
2107
|
groupByInstructFile
|
|
2041
2108
|
};
|
|
2042
|
-
//# sourceMappingURL=chunk-
|
|
2109
|
+
//# sourceMappingURL=chunk-PCWTRJV2.js.map
|