@cleocode/caamp 2026.4.9 → 2026.4.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-JC77OAHA.js → chunk-XVZT7K6F.js} +98 -36
- package/dist/chunk-XVZT7K6F.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +172 -37
- package/dist/index.js +1 -1
- package/package.json +6 -3
- package/dist/chunk-JC77OAHA.js.map +0 -1
|
@@ -760,19 +760,25 @@ var PiHarness = class {
|
|
|
760
760
|
return scope.kind === "global" ? join5(getPiAgentDir2(), "AGENTS.md") : join5(scope.projectDir, "AGENTS.md");
|
|
761
761
|
}
|
|
762
762
|
// ── Skills ──────────────────────────────────────────────────────────
|
|
763
|
-
/**
|
|
763
|
+
/**
|
|
764
|
+
* Install a skill directory into the resolved Pi skills location.
|
|
765
|
+
*/
|
|
764
766
|
async installSkill(sourcePath, skillName, scope) {
|
|
765
767
|
const targetDir = join5(this.skillsDir(scope), skillName);
|
|
766
768
|
await rm3(targetDir, { recursive: true, force: true });
|
|
767
769
|
await mkdir3(dirname2(targetDir), { recursive: true });
|
|
768
770
|
await cp3(sourcePath, targetDir, { recursive: true });
|
|
769
771
|
}
|
|
770
|
-
/**
|
|
772
|
+
/**
|
|
773
|
+
* Remove a skill directory from the resolved Pi skills location.
|
|
774
|
+
*/
|
|
771
775
|
async removeSkill(skillName, scope) {
|
|
772
776
|
const targetDir = join5(this.skillsDir(scope), skillName);
|
|
773
777
|
await rm3(targetDir, { recursive: true, force: true });
|
|
774
778
|
}
|
|
775
|
-
/**
|
|
779
|
+
/**
|
|
780
|
+
* List the installed skill directories at the given scope.
|
|
781
|
+
*/
|
|
776
782
|
async listSkills(scope) {
|
|
777
783
|
const dir = this.skillsDir(scope);
|
|
778
784
|
if (!existsSync4(dir)) return [];
|
|
@@ -780,7 +786,10 @@ var PiHarness = class {
|
|
|
780
786
|
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
781
787
|
}
|
|
782
788
|
// ── Instructions ────────────────────────────────────────────────────
|
|
783
|
-
/**
|
|
789
|
+
/**
|
|
790
|
+
* Inject or replace a CAAMP-managed instruction block inside the Pi
|
|
791
|
+
* `AGENTS.md` file for the resolved scope.
|
|
792
|
+
*/
|
|
784
793
|
async injectInstructions(content, scope) {
|
|
785
794
|
const filePath = this.agentsMdPath(scope);
|
|
786
795
|
await mkdir3(dirname2(filePath), { recursive: true });
|
|
@@ -804,7 +813,10 @@ ${MARKER_END}`;
|
|
|
804
813
|
}
|
|
805
814
|
await writeFile(filePath, updated, "utf8");
|
|
806
815
|
}
|
|
807
|
-
/**
|
|
816
|
+
/**
|
|
817
|
+
* Remove the CAAMP-managed instruction block from the Pi `AGENTS.md`
|
|
818
|
+
* file at the resolved scope.
|
|
819
|
+
*/
|
|
808
820
|
async removeInstructions(scope) {
|
|
809
821
|
const filePath = this.agentsMdPath(scope);
|
|
810
822
|
if (!existsSync4(filePath)) return;
|
|
@@ -1204,7 +1216,9 @@ ${MARKER_END}`;
|
|
|
1204
1216
|
});
|
|
1205
1217
|
}
|
|
1206
1218
|
// ── Settings ────────────────────────────────────────────────────────
|
|
1207
|
-
/**
|
|
1219
|
+
/**
|
|
1220
|
+
* Read the Pi `settings.json` file for the resolved scope.
|
|
1221
|
+
*/
|
|
1208
1222
|
async readSettings(scope) {
|
|
1209
1223
|
const filePath = this.settingsPath(scope);
|
|
1210
1224
|
if (!existsSync4(filePath)) return {};
|
|
@@ -1215,7 +1229,10 @@ ${MARKER_END}`;
|
|
|
1215
1229
|
return {};
|
|
1216
1230
|
}
|
|
1217
1231
|
}
|
|
1218
|
-
/**
|
|
1232
|
+
/**
|
|
1233
|
+
* Merge a partial patch into the Pi `settings.json` file for the
|
|
1234
|
+
* resolved scope using an atomic write.
|
|
1235
|
+
*/
|
|
1219
1236
|
async writeSettings(patch, scope) {
|
|
1220
1237
|
const filePath = this.settingsPath(scope);
|
|
1221
1238
|
const current = await this.readSettings(scope);
|
|
@@ -1223,7 +1240,10 @@ ${MARKER_END}`;
|
|
|
1223
1240
|
const merged = deepMerge(currentObj, patch);
|
|
1224
1241
|
await atomicWriteJson(filePath, merged);
|
|
1225
1242
|
}
|
|
1226
|
-
/**
|
|
1243
|
+
/**
|
|
1244
|
+
* Persist the supplied model-name patterns into `settings.enabledModels`
|
|
1245
|
+
* at the resolved scope.
|
|
1246
|
+
*/
|
|
1227
1247
|
async configureModels(modelPatterns, scope) {
|
|
1228
1248
|
await this.writeSettings({ enabledModels: modelPatterns }, scope);
|
|
1229
1249
|
}
|
|
@@ -1248,7 +1268,10 @@ ${MARKER_END}`;
|
|
|
1248
1268
|
return join5(getPiAgentDir2(), "sessions");
|
|
1249
1269
|
}
|
|
1250
1270
|
// ── Extensions (Wave-1, T263) ───────────────────────────────────────
|
|
1251
|
-
/**
|
|
1271
|
+
/**
|
|
1272
|
+
* Install a Pi extension `.ts` source file into the resolved tier's
|
|
1273
|
+
* extensions directory, validating that it has a default export.
|
|
1274
|
+
*/
|
|
1252
1275
|
async installExtension(sourcePath, name, tier, projectDir, opts) {
|
|
1253
1276
|
if (!existsSync4(sourcePath)) {
|
|
1254
1277
|
throw new Error(`installExtension: source file does not exist: ${sourcePath}`);
|
|
@@ -1280,7 +1303,9 @@ ${MARKER_END}`;
|
|
|
1280
1303
|
await writeFile(targetPath, contents, "utf8");
|
|
1281
1304
|
return { targetPath, tier };
|
|
1282
1305
|
}
|
|
1283
|
-
/**
|
|
1306
|
+
/**
|
|
1307
|
+
* Remove a Pi extension `.ts` source file from the resolved tier.
|
|
1308
|
+
*/
|
|
1284
1309
|
async removeExtension(name, tier, projectDir) {
|
|
1285
1310
|
const dir = resolveTierDir({ tier, kind: "extensions", projectDir });
|
|
1286
1311
|
const targetPath = join5(dir, `${name}.ts`);
|
|
@@ -1288,7 +1313,10 @@ ${MARKER_END}`;
|
|
|
1288
1313
|
await rm3(targetPath, { force: true });
|
|
1289
1314
|
return true;
|
|
1290
1315
|
}
|
|
1291
|
-
/**
|
|
1316
|
+
/**
|
|
1317
|
+
* List Pi extension files across every tier in precedence order,
|
|
1318
|
+
* flagging shadowed entries from lower tiers.
|
|
1319
|
+
*/
|
|
1292
1320
|
async listExtensions(projectDir) {
|
|
1293
1321
|
const tiers = resolveAllTiers("extensions", projectDir);
|
|
1294
1322
|
const out = [];
|
|
@@ -1319,7 +1347,10 @@ ${MARKER_END}`;
|
|
|
1319
1347
|
return out;
|
|
1320
1348
|
}
|
|
1321
1349
|
// ── Sessions (Wave-1, T264) ─────────────────────────────────────────
|
|
1322
|
-
/**
|
|
1350
|
+
/**
|
|
1351
|
+
* List Pi session JSONL files (including subagent children when
|
|
1352
|
+
* requested), summarising only the header line per file.
|
|
1353
|
+
*/
|
|
1323
1354
|
async listSessions(opts) {
|
|
1324
1355
|
const rootDir = this.sessionsDir();
|
|
1325
1356
|
if (!existsSync4(rootDir)) return [];
|
|
@@ -1359,7 +1390,9 @@ ${MARKER_END}`;
|
|
|
1359
1390
|
summaries.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
1360
1391
|
return summaries;
|
|
1361
1392
|
}
|
|
1362
|
-
/**
|
|
1393
|
+
/**
|
|
1394
|
+
* Show the full entries of a single Pi session by id.
|
|
1395
|
+
*/
|
|
1363
1396
|
async showSession(id) {
|
|
1364
1397
|
const summaries = await this.listSessions({ includeSubagents: true });
|
|
1365
1398
|
const match = summaries.find((s) => s.id === id);
|
|
@@ -1375,7 +1408,10 @@ ${MARKER_END}`;
|
|
|
1375
1408
|
return { summary: match, entries };
|
|
1376
1409
|
}
|
|
1377
1410
|
// ── Models (Wave-1, T265) ───────────────────────────────────────────
|
|
1378
|
-
/**
|
|
1411
|
+
/**
|
|
1412
|
+
* Read the Pi `models.json` file for the resolved scope, tolerating
|
|
1413
|
+
* missing or malformed files by returning an empty provider map.
|
|
1414
|
+
*/
|
|
1379
1415
|
async readModelsConfig(scope) {
|
|
1380
1416
|
const filePath = this.modelsConfigPath(scope);
|
|
1381
1417
|
if (!existsSync4(filePath)) return { providers: {} };
|
|
@@ -1401,12 +1437,18 @@ ${MARKER_END}`;
|
|
|
1401
1437
|
return { providers: {} };
|
|
1402
1438
|
}
|
|
1403
1439
|
}
|
|
1404
|
-
/**
|
|
1440
|
+
/**
|
|
1441
|
+
* Write the Pi `models.json` file for the resolved scope via an atomic
|
|
1442
|
+
* tmp-then-rename sequence.
|
|
1443
|
+
*/
|
|
1405
1444
|
async writeModelsConfig(config, scope) {
|
|
1406
1445
|
const filePath = this.modelsConfigPath(scope);
|
|
1407
1446
|
await atomicWriteJson(filePath, config);
|
|
1408
1447
|
}
|
|
1409
|
-
/**
|
|
1448
|
+
/**
|
|
1449
|
+
* Compose a flat `ModelListEntry` list from `models.json` plus the
|
|
1450
|
+
* `enabledModels` and default-model hints in `settings.json`.
|
|
1451
|
+
*/
|
|
1410
1452
|
async listModels(scope) {
|
|
1411
1453
|
const models = await this.readModelsConfig(scope);
|
|
1412
1454
|
const settings = await this.readSettings(scope);
|
|
@@ -1468,7 +1510,10 @@ ${MARKER_END}`;
|
|
|
1468
1510
|
return out;
|
|
1469
1511
|
}
|
|
1470
1512
|
// ── Prompts (Wave-1, T266) ──────────────────────────────────────────
|
|
1471
|
-
/**
|
|
1513
|
+
/**
|
|
1514
|
+
* Install a Pi prompt directory (containing `prompt.md`) into the
|
|
1515
|
+
* resolved tier's prompts directory.
|
|
1516
|
+
*/
|
|
1472
1517
|
async installPrompt(sourceDir, name, tier, projectDir, opts) {
|
|
1473
1518
|
if (!existsSync4(sourceDir)) {
|
|
1474
1519
|
throw new Error(`installPrompt: source directory does not exist: ${sourceDir}`);
|
|
@@ -1494,7 +1539,10 @@ ${MARKER_END}`;
|
|
|
1494
1539
|
await cp3(sourceDir, targetPath, { recursive: true });
|
|
1495
1540
|
return { targetPath, tier };
|
|
1496
1541
|
}
|
|
1497
|
-
/**
|
|
1542
|
+
/**
|
|
1543
|
+
* List Pi prompt directories across every tier in precedence order,
|
|
1544
|
+
* flagging shadowed entries from lower tiers.
|
|
1545
|
+
*/
|
|
1498
1546
|
async listPrompts(projectDir) {
|
|
1499
1547
|
const tiers = resolveAllTiers("prompts", projectDir);
|
|
1500
1548
|
const out = [];
|
|
@@ -1522,7 +1570,9 @@ ${MARKER_END}`;
|
|
|
1522
1570
|
}
|
|
1523
1571
|
return out;
|
|
1524
1572
|
}
|
|
1525
|
-
/**
|
|
1573
|
+
/**
|
|
1574
|
+
* Remove a Pi prompt directory from the resolved tier.
|
|
1575
|
+
*/
|
|
1526
1576
|
async removePrompt(name, tier, projectDir) {
|
|
1527
1577
|
const dir = resolveTierDir({ tier, kind: "prompts", projectDir });
|
|
1528
1578
|
const targetPath = join5(dir, name);
|
|
@@ -1531,7 +1581,11 @@ ${MARKER_END}`;
|
|
|
1531
1581
|
return true;
|
|
1532
1582
|
}
|
|
1533
1583
|
// ── Themes (Wave-1, T267) ───────────────────────────────────────────
|
|
1534
|
-
/**
|
|
1584
|
+
/**
|
|
1585
|
+
* Install a Pi theme file (`.ts`/`.tsx`/`.mts`/`.json`) into the
|
|
1586
|
+
* resolved tier's themes directory, blocking same-stem conflicts
|
|
1587
|
+
* unless `--force` is supplied.
|
|
1588
|
+
*/
|
|
1535
1589
|
async installTheme(sourceFile, name, tier, projectDir, opts) {
|
|
1536
1590
|
if (!existsSync4(sourceFile)) {
|
|
1537
1591
|
throw new Error(`installTheme: source file does not exist: ${sourceFile}`);
|
|
@@ -1570,7 +1624,10 @@ ${MARKER_END}`;
|
|
|
1570
1624
|
await writeFile(targetPath, contents);
|
|
1571
1625
|
return { targetPath, tier };
|
|
1572
1626
|
}
|
|
1573
|
-
/**
|
|
1627
|
+
/**
|
|
1628
|
+
* List Pi theme files across every tier in precedence order, flagging
|
|
1629
|
+
* shadowed entries from lower tiers.
|
|
1630
|
+
*/
|
|
1574
1631
|
async listThemes(projectDir) {
|
|
1575
1632
|
const tiers = resolveAllTiers("themes", projectDir);
|
|
1576
1633
|
const out = [];
|
|
@@ -1602,7 +1659,10 @@ ${MARKER_END}`;
|
|
|
1602
1659
|
}
|
|
1603
1660
|
return out;
|
|
1604
1661
|
}
|
|
1605
|
-
/**
|
|
1662
|
+
/**
|
|
1663
|
+
* Remove a Pi theme from the resolved tier, matching any of the
|
|
1664
|
+
* supported theme extensions for the given name stem.
|
|
1665
|
+
*/
|
|
1606
1666
|
async removeTheme(name, tier, projectDir) {
|
|
1607
1667
|
const dir = resolveTierDir({ tier, kind: "themes", projectDir });
|
|
1608
1668
|
let removed = false;
|
|
@@ -1617,14 +1677,14 @@ ${MARKER_END}`;
|
|
|
1617
1677
|
}
|
|
1618
1678
|
// ── CANT profiles (Wave-1, T276) ────────────────────────────────────
|
|
1619
1679
|
/**
|
|
1620
|
-
*
|
|
1680
|
+
* Install a `.cant` profile into the resolved tier after passing it
|
|
1681
|
+
* through the cant-core validator.
|
|
1621
1682
|
*
|
|
1622
|
-
* @
|
|
1623
|
-
*
|
|
1624
|
-
*
|
|
1625
|
-
*
|
|
1626
|
-
*
|
|
1627
|
-
* consistent with the other Wave-1 verbs.
|
|
1683
|
+
* Validates the source via {@link PiHarness.validateCantProfile}
|
|
1684
|
+
* before copying so we never persist a `.cant` file the runtime bridge
|
|
1685
|
+
* cannot load. The target layout is `<tier-root>/cant/<name>.cant`,
|
|
1686
|
+
* resolved through `resolveTierDir` so the project/user/global
|
|
1687
|
+
* hierarchy stays consistent with the other Wave-1 verbs.
|
|
1628
1688
|
*/
|
|
1629
1689
|
async installCantProfile(sourcePath, name, tier, projectDir, opts) {
|
|
1630
1690
|
if (!existsSync4(sourcePath)) {
|
|
@@ -1658,7 +1718,9 @@ ${MARKER_END}`;
|
|
|
1658
1718
|
await writeFile(targetPath, contents);
|
|
1659
1719
|
return { targetPath, tier, counts: validation.counts };
|
|
1660
1720
|
}
|
|
1661
|
-
/**
|
|
1721
|
+
/**
|
|
1722
|
+
* Remove a `.cant` profile from the resolved tier.
|
|
1723
|
+
*/
|
|
1662
1724
|
async removeCantProfile(name, tier, projectDir) {
|
|
1663
1725
|
const dir = resolveTierDir({ tier, kind: "cant", projectDir });
|
|
1664
1726
|
const targetPath = join5(dir, `${name}.cant`);
|
|
@@ -1667,10 +1729,10 @@ ${MARKER_END}`;
|
|
|
1667
1729
|
return true;
|
|
1668
1730
|
}
|
|
1669
1731
|
/**
|
|
1670
|
-
*
|
|
1732
|
+
* List installed `.cant` profiles across every tier in precedence
|
|
1733
|
+
* order, parsing each file to extract section counts.
|
|
1671
1734
|
*
|
|
1672
|
-
*
|
|
1673
|
-
* Walks every tier in {@link TIER_PRECEDENCE} order, parsing each
|
|
1735
|
+
* Walks every tier in `TIER_PRECEDENCE` order, parsing each
|
|
1674
1736
|
* discovered `.cant` file via cant-core to extract a
|
|
1675
1737
|
* {@link CantProfileCounts} bag. Higher-precedence tiers shadow
|
|
1676
1738
|
* lower-precedence entries with the same name; shadowed entries
|
|
@@ -1714,9 +1776,9 @@ ${MARKER_END}`;
|
|
|
1714
1776
|
return out;
|
|
1715
1777
|
}
|
|
1716
1778
|
/**
|
|
1717
|
-
*
|
|
1779
|
+
* Validate a `.cant` source file against cant-core's parser and
|
|
1780
|
+
* 42-rule linter, returning section counts and per-diagnostic detail.
|
|
1718
1781
|
*
|
|
1719
|
-
* @remarks
|
|
1720
1782
|
* Pure validator. Reads the file, runs `parseDocument` to derive
|
|
1721
1783
|
* counts (when parsing succeeds) and `validateDocument` to collect
|
|
1722
1784
|
* the 42-rule diagnostic feed. The two calls are kept independent so
|
|
@@ -4624,4 +4686,4 @@ export {
|
|
|
4624
4686
|
discoverSkillsMulti,
|
|
4625
4687
|
validateSkill
|
|
4626
4688
|
};
|
|
4627
|
-
//# sourceMappingURL=chunk-
|
|
4689
|
+
//# sourceMappingURL=chunk-XVZT7K6F.js.map
|