@cleocode/caamp 1.0.0 → 1.0.2

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 CHANGED
@@ -8,6 +8,7 @@
8
8
  <img src="https://img.shields.io/node/v/@cleocode/caamp" alt="node version" />
9
9
  <img src="https://img.shields.io/badge/providers-44-green" alt="providers" />
10
10
  <img src="https://img.shields.io/badge/TypeScript-strict-blue" alt="typescript" />
11
+ <a href="https://codluv.gitbook.io/caamp/"><img src="https://img.shields.io/badge/docs-GitBook-blue?logo=gitbook" alt="docs" /></a>
11
12
  </p>
12
13
 
13
14
  # CAAMP - Central AI Agent Managed Packages
@@ -64,7 +65,7 @@ const installed = getInstalledProviders();
64
65
  const servers = await listAllMcpServers(installed, "global");
65
66
  ```
66
67
 
67
- See [API Reference](docs/API-REFERENCE.md) for full programmatic API documentation.
68
+ See [API Reference](https://codluv.gitbook.io/caamp/api-and-reference/api-reference) for full programmatic API documentation.
68
69
 
69
70
  ## CLI Commands
70
71
 
@@ -209,23 +210,25 @@ Each provider uses a different key name for MCP server configuration:
209
210
 
210
211
  ## Documentation
211
212
 
213
+ **[Read the full documentation on GitBook](https://codluv.gitbook.io/caamp/)**
214
+
212
215
  | Document | Description |
213
216
  |----------|-------------|
214
- | [API Reference](docs/API-REFERENCE.md) | Full library API (signatures and examples) |
215
- | [Advanced CLI](docs/ADVANCED-CLI.md) | LAFS-compliant advanced command wrappers and input/output schemas |
216
- | [Advanced Recipes](docs/ADVANCED-RECIPES.md) | Production TypeScript patterns for tier filtering, rollback, conflict handling, and dual-scope operations |
217
- | [Provider Configuration Guide](docs/PROVIDER-CONFIGURATION.md) | Config keys, formats, scopes, and provider mapping guidance |
218
- | [Migration Guide](docs/MIGRATION-v1.md) | Upgrade notes for moving to v1.0.0 |
219
- | [Troubleshooting](docs/TROUBLESHOOTING.md) | Common failure modes and remediation steps |
220
- | [CLI Help Examples](docs/CLI-HELP-EXAMPLES.md) | `--help` command examples for every command group |
221
- | [Contributing](CONTRIBUTING.md) | Development workflow and PR expectations |
222
- | [Security Policy](SECURITY.md) | Private vulnerability disclosure process |
223
- | [Generated API Docs](docs/api/) | Auto-generated from TSDoc (run `npm run docs:api`) |
224
- | [Vision & Architecture](claudedocs/VISION.md) | Project vision, design philosophy, and architecture |
225
- | [Product Requirements](claudedocs/PRD.md) | Full PRD with user stories and feature requirements |
226
- | [Technical Specification](claudedocs/specs/CAAMP-SPEC.md) | RFC 2119 spec covering all subsystems |
217
+ | [API Reference](https://codluv.gitbook.io/caamp/api-and-reference/api-reference) | Full library API (signatures and examples) |
218
+ | [Advanced CLI](https://codluv.gitbook.io/caamp/advanced-usage/advanced-cli) | LAFS-compliant advanced command wrappers and input/output schemas |
219
+ | [Advanced Recipes](https://codluv.gitbook.io/caamp/advanced-usage/advanced-recipes) | Production TypeScript patterns for tier filtering, rollback, conflict handling, and dual-scope operations |
220
+ | [Provider Configuration Guide](https://codluv.gitbook.io/caamp/user-guides/provider-configuration) | Config keys, formats, scopes, and provider mapping guidance |
221
+ | [Migration Guide](https://codluv.gitbook.io/caamp/getting-started/migration-v1) | Upgrade notes for moving to v1.0.0 |
222
+ | [Troubleshooting](https://codluv.gitbook.io/caamp/user-guides/troubleshooting) | Common failure modes and remediation steps |
223
+ | [CLI Help Examples](https://codluv.gitbook.io/caamp/user-guides/cli-help-examples) | `--help` command examples for every command group |
224
+ | [Skills Recommendations](https://codluv.gitbook.io/caamp/advanced-usage/skills-recommendations) | Marketplace search and recommendation engine |
225
+ | [Contributing](https://codluv.gitbook.io/caamp/contributing/contributing) | Development workflow and PR expectations |
226
+ | [Security Policy](https://codluv.gitbook.io/caamp/contributing/security) | Private vulnerability disclosure process |
227
+ | [LAFS Compliance Profile](https://codluv.gitbook.io/caamp/api-and-reference/lafs-compliance) | CAAMP-specific LAFS adoption scope and compliance mapping |
228
+ | [Agents Directory Standard](https://codluv.gitbook.io/caamp/api-and-reference/agents-directory-standard) | `.agents/` standard directory structure |
227
229
  | [LAFS Specification](https://github.com/kryptobaseddev/lafs-protocol/blob/main/lafs.md) | Canonical cross-language LLM-agent-first protocol |
228
- | [LAFS Compliance Profile](docs/LAFS-COMPLIANCE.md) | CAAMP-specific LAFS adoption scope and compliance mapping |
230
+ | [Technical Specification](claudedocs/specs/CAAMP-SPEC.md) | RFC 2119 spec covering all subsystems |
231
+ | [Vision & Architecture](claudedocs/VISION.md) | Project vision, design philosophy, and architecture |
229
232
  | [Gap Analysis & Roadmap](claudedocs/GAP-ANALYSIS.md) | Current state vs plan, v0.2.0+ roadmap |
230
233
 
231
234
  ## Contributing
@@ -294,8 +294,8 @@ function isQuiet() {
294
294
  }
295
295
 
296
296
  // src/core/registry/detection.ts
297
- import { existsSync as existsSync2 } from "fs";
298
297
  import { execFileSync } from "child_process";
298
+ import { existsSync as existsSync2 } from "fs";
299
299
  import { join as join2 } from "path";
300
300
  var DEFAULT_DETECTION_CACHE_TTL_MS = 3e4;
301
301
  var detectionCache = null;
@@ -377,6 +377,7 @@ function providerSignature(provider) {
377
377
  });
378
378
  }
379
379
  function buildProvidersSignature(providers) {
380
+ if (!providers || !Array.isArray(providers)) return "";
380
381
  return providers.map(providerSignature).join("|");
381
382
  }
382
383
  function cloneDetectionResults(results) {
@@ -407,7 +408,7 @@ function detectProjectProvider(provider, projectDir) {
407
408
  return existsSync2(resolveProviderProjectPath(provider, projectDir));
408
409
  }
409
410
  function detectAllProviders(options = {}) {
410
- const providers = getAllProviders();
411
+ const providers = getAllProviders() ?? [];
411
412
  const signature = buildProvidersSignature(providers);
412
413
  const cached = getCachedResults(signature, options);
413
414
  if (cached) {
@@ -434,8 +435,8 @@ function resetDetectionCache() {
434
435
 
435
436
  // src/core/sources/parser.ts
436
437
  var GITHUB_SHORTHAND = /^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)(?:\/(.+))?$/;
437
- var GITHUB_URL = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+)(?:\/tree\/([^/]+)(?:\/(.+))?)?/;
438
- var GITLAB_URL = /^https?:\/\/(?:www\.)?gitlab\.com\/([^/]+)\/([^/]+)(?:\/-\/tree\/([^/]+)(?:\/(.+))?)?/;
438
+ var GITHUB_URL = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+)(?:\/(?:tree|blob)\/([^/]+)(?:\/(.+))?)?/;
439
+ var GITLAB_URL = /^https?:\/\/(?:www\.)?gitlab\.com\/([^/]+)\/([^/]+)(?:\/-\/(?:tree|blob)\/([^/]+)(?:\/(.+))?)?/;
439
440
  var HTTP_URL = /^https?:\/\//;
440
441
  var NPM_SCOPED = /^@[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+$/;
441
442
  var NPM_PACKAGE = /^[a-zA-Z0-9_.-]+$/;
@@ -487,34 +488,38 @@ function parseSource(input) {
487
488
  if (ghUrlMatch) {
488
489
  const owner = ghUrlMatch[1];
489
490
  const repo = ghUrlMatch[2];
491
+ const path = ghUrlMatch[4];
490
492
  if (!owner || !repo) {
491
493
  return { type: "command", value: input, inferredName: inferName(input, "command") };
492
494
  }
495
+ const inferredName = path ? path.split("/").pop() ?? repo : repo;
493
496
  return {
494
497
  type: "github",
495
498
  value: input,
496
- inferredName: repo,
499
+ inferredName,
497
500
  owner,
498
501
  repo,
499
502
  ref: ghUrlMatch[3],
500
- path: ghUrlMatch[4]
503
+ path
501
504
  };
502
505
  }
503
506
  const glUrlMatch = input.match(GITLAB_URL);
504
507
  if (glUrlMatch) {
505
508
  const owner = glUrlMatch[1];
506
509
  const repo = glUrlMatch[2];
510
+ const path = glUrlMatch[4];
507
511
  if (!owner || !repo) {
508
512
  return { type: "command", value: input, inferredName: inferName(input, "command") };
509
513
  }
514
+ const inferredName = path ? path.split("/").pop() ?? repo : repo;
510
515
  return {
511
516
  type: "gitlab",
512
517
  value: input,
513
- inferredName: repo,
518
+ inferredName,
514
519
  owner,
515
520
  repo,
516
521
  ref: glUrlMatch[3],
517
- path: glUrlMatch[4]
522
+ path
518
523
  };
519
524
  }
520
525
  if (HTTP_URL.test(input)) {
@@ -535,16 +540,18 @@ function parseSource(input) {
535
540
  if (ghShorthand && !NPM_SCOPED.test(input)) {
536
541
  const owner = ghShorthand[1];
537
542
  const repo = ghShorthand[2];
543
+ const path = ghShorthand[3];
538
544
  if (!owner || !repo) {
539
545
  return { type: "command", value: input, inferredName: inferName(input, "command") };
540
546
  }
547
+ const inferredName = path ? path.split("/").pop() ?? repo : repo;
541
548
  return {
542
549
  type: "github",
543
550
  value: `https://github.com/${owner}/${repo}`,
544
- inferredName: repo,
551
+ inferredName,
545
552
  owner,
546
553
  repo,
547
- path: ghShorthand[3]
554
+ path
548
555
  };
549
556
  }
550
557
  if (NPM_SCOPED.test(input)) {
@@ -572,29 +579,26 @@ function isMarketplaceScoped(input) {
572
579
  }
573
580
 
574
581
  // src/core/skills/installer.ts
575
- import { mkdir, symlink, rm, cp } from "fs/promises";
576
582
  import { existsSync as existsSync3, lstatSync } from "fs";
583
+ import { cp, mkdir, rm, symlink } from "fs/promises";
577
584
  import { join as join3 } from "path";
578
-
579
- // src/core/paths/agents.ts
580
- var AGENTS_HOME = getAgentsHome();
581
- var LOCK_FILE_PATH = getLockFilePath();
582
- var CANONICAL_SKILLS_DIR = getCanonicalSkillsDir();
583
- var AGENTS_MCP_DIR = getAgentsMcpDir();
584
- var AGENTS_MCP_SERVERS_PATH = getAgentsMcpServersPath();
585
- var AGENTS_CONFIG_PATH = getAgentsConfigPath();
586
-
587
- // src/core/skills/installer.ts
588
585
  async function ensureCanonicalDir() {
589
- await mkdir(CANONICAL_SKILLS_DIR, { recursive: true });
586
+ await mkdir(getCanonicalSkillsDir(), { recursive: true });
590
587
  }
591
588
  async function installToCanonical(sourcePath, skillName) {
592
589
  await ensureCanonicalDir();
593
- const targetDir = join3(CANONICAL_SKILLS_DIR, skillName);
594
- if (existsSync3(targetDir)) {
595
- await rm(targetDir, { recursive: true });
590
+ const targetDir = join3(getCanonicalSkillsDir(), skillName);
591
+ await rm(targetDir, { recursive: true, force: true });
592
+ try {
593
+ await cp(sourcePath, targetDir, { recursive: true });
594
+ } catch (err) {
595
+ if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
596
+ await rm(targetDir, { recursive: true, force: true });
597
+ await cp(sourcePath, targetDir, { recursive: true });
598
+ } else {
599
+ throw err;
600
+ }
596
601
  }
597
- await cp(sourcePath, targetDir, { recursive: true });
598
602
  return targetDir;
599
603
  }
600
604
  async function linkToAgent(canonicalPath, provider, skillName, isGlobal, projectDir) {
@@ -671,7 +675,7 @@ async function removeSkill(skillName, providers, isGlobal, projectDir) {
671
675
  }
672
676
  }
673
677
  }
674
- const canonicalPath = join3(CANONICAL_SKILLS_DIR, skillName);
678
+ const canonicalPath = join3(getCanonicalSkillsDir(), skillName);
675
679
  if (existsSync3(canonicalPath)) {
676
680
  try {
677
681
  await rm(canonicalPath, { recursive: true });
@@ -682,15 +686,25 @@ async function removeSkill(skillName, providers, isGlobal, projectDir) {
682
686
  return { removed, errors };
683
687
  }
684
688
  async function listCanonicalSkills() {
685
- if (!existsSync3(CANONICAL_SKILLS_DIR)) return [];
689
+ if (!existsSync3(getCanonicalSkillsDir())) return [];
686
690
  const { readdir: readdir2 } = await import("fs/promises");
687
- const entries = await readdir2(CANONICAL_SKILLS_DIR, { withFileTypes: true });
691
+ const entries = await readdir2(getCanonicalSkillsDir(), { withFileTypes: true });
688
692
  return entries.filter((e) => e.isDirectory() || e.isSymbolicLink()).map((e) => e.name);
689
693
  }
690
694
 
691
695
  // src/core/lock-utils.ts
692
696
  import { open, readFile, writeFile, mkdir as mkdir2, rm as rm2, rename } from "fs/promises";
693
697
  import { existsSync as existsSync4 } from "fs";
698
+
699
+ // src/core/paths/agents.ts
700
+ var AGENTS_HOME = getAgentsHome();
701
+ var LOCK_FILE_PATH = getLockFilePath();
702
+ var CANONICAL_SKILLS_DIR = getCanonicalSkillsDir();
703
+ var AGENTS_MCP_DIR = getAgentsMcpDir();
704
+ var AGENTS_MCP_SERVERS_PATH = getAgentsMcpServersPath();
705
+ var AGENTS_CONFIG_PATH = getAgentsConfigPath();
706
+
707
+ // src/core/lock-utils.ts
694
708
  var LOCK_GUARD_PATH = `${LOCK_FILE_PATH}.lock`;
695
709
  function sleep(ms) {
696
710
  return new Promise((resolve3) => setTimeout(resolve3, ms));
@@ -3238,10 +3252,10 @@ export {
3238
3252
  resetDetectionCache,
3239
3253
  parseSource,
3240
3254
  isMarketplaceScoped,
3241
- CANONICAL_SKILLS_DIR,
3242
3255
  installSkill,
3243
3256
  removeSkill,
3244
3257
  listCanonicalSkills,
3258
+ CANONICAL_SKILLS_DIR,
3245
3259
  readLockFile,
3246
3260
  recordSkillInstall,
3247
3261
  removeSkillFromLock,
@@ -3307,4 +3321,4 @@ export {
3307
3321
  updateInstructionsSingleOperation,
3308
3322
  configureProviderGlobalAndProject
3309
3323
  };
3310
- //# sourceMappingURL=chunk-YCSZGZ5W.js.map
3324
+ //# sourceMappingURL=chunk-762HFAUU.js.map