@promptscript/cli 1.0.0-alpha.6 → 1.0.0-alpha.7
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/CHANGELOG.md +12 -0
- package/README.md +36 -0
- package/index.js +906 -72
- package/package.json +1 -1
- package/src/cli.d.ts.map +1 -1
- package/src/commands/compile.d.ts.map +1 -1
- package/src/commands/diff.d.ts.map +1 -1
- package/src/commands/init.d.ts.map +1 -1
- package/src/commands/update-check.d.ts +6 -0
- package/src/commands/update-check.d.ts.map +1 -0
- package/src/commands/validate.d.ts.map +1 -1
- package/src/index.d.ts +3 -0
- package/src/index.d.ts.map +1 -1
- package/src/types.d.ts +0 -2
- package/src/types.d.ts.map +1 -1
- package/src/utils/manifest-loader.d.ts +157 -0
- package/src/utils/manifest-loader.d.ts.map +1 -0
- package/src/utils/registry-resolver.d.ts +41 -0
- package/src/utils/registry-resolver.d.ts.map +1 -0
- package/src/utils/suggestion-engine.d.ts +56 -0
- package/src/utils/suggestion-engine.d.ts.map +1 -0
- package/src/utils/version-check.d.ts +48 -0
- package/src/utils/version-check.d.ts.map +1 -0
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// packages/cli/src/cli.ts
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import { fileURLToPath as
|
|
4
|
-
import { dirname as
|
|
3
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4
|
+
import { dirname as dirname9 } from "path";
|
|
5
5
|
|
|
6
6
|
// packages/core/src/types/constants.ts
|
|
7
7
|
var BLOCK_TYPES = [
|
|
@@ -306,7 +306,7 @@ var noopLogger = {
|
|
|
306
306
|
|
|
307
307
|
// packages/cli/src/commands/init.ts
|
|
308
308
|
import { fileURLToPath } from "url";
|
|
309
|
-
import { dirname as
|
|
309
|
+
import { dirname as dirname3 } from "path";
|
|
310
310
|
|
|
311
311
|
// packages/cli/src/services.ts
|
|
312
312
|
import { writeFile, mkdir, readFile, readdir } from "fs/promises";
|
|
@@ -1366,9 +1366,410 @@ Before completing migration:
|
|
|
1366
1366
|
- No duplicate content across blocks
|
|
1367
1367
|
`;
|
|
1368
1368
|
|
|
1369
|
+
// packages/cli/src/utils/manifest-loader.ts
|
|
1370
|
+
import { join as join3, dirname as dirname2 } from "path";
|
|
1371
|
+
import { parse as parseYaml2 } from "yaml";
|
|
1372
|
+
var OFFICIAL_REGISTRY = {
|
|
1373
|
+
name: "PromptScript Official Registry",
|
|
1374
|
+
url: "https://github.com/mrwogu/promptscript-registry.git",
|
|
1375
|
+
branch: "main",
|
|
1376
|
+
manifestUrl: "https://raw.githubusercontent.com/mrwogu/promptscript-registry/main/registry-manifest.yaml"
|
|
1377
|
+
};
|
|
1378
|
+
var ManifestLoadError = class extends Error {
|
|
1379
|
+
originalCause;
|
|
1380
|
+
constructor(message, cause) {
|
|
1381
|
+
super(message);
|
|
1382
|
+
this.name = "ManifestLoadError";
|
|
1383
|
+
this.originalCause = cause;
|
|
1384
|
+
}
|
|
1385
|
+
};
|
|
1386
|
+
var manifestCache = /* @__PURE__ */ new Map();
|
|
1387
|
+
var MANIFEST_FILENAME = "registry-manifest.yaml";
|
|
1388
|
+
async function loadManifest(options = {}, services = createDefaultServices()) {
|
|
1389
|
+
const { registryPath = findDefaultRegistryPath(services), useCache = true } = options;
|
|
1390
|
+
const manifestPath = resolveManifestPath(registryPath, services);
|
|
1391
|
+
if (useCache && manifestCache.has(manifestPath)) {
|
|
1392
|
+
return {
|
|
1393
|
+
manifest: manifestCache.get(manifestPath),
|
|
1394
|
+
path: manifestPath,
|
|
1395
|
+
cached: true
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
const manifest = await loadManifestFromPath(manifestPath, services);
|
|
1399
|
+
validateManifest(manifest);
|
|
1400
|
+
if (useCache) {
|
|
1401
|
+
manifestCache.set(manifestPath, manifest);
|
|
1402
|
+
}
|
|
1403
|
+
return {
|
|
1404
|
+
manifest,
|
|
1405
|
+
path: manifestPath,
|
|
1406
|
+
cached: false
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
function findDefaultRegistryPath(services) {
|
|
1410
|
+
const candidates = ["./registry", "../promptscript-registry", "./.promptscript-registry"];
|
|
1411
|
+
for (const candidate of candidates) {
|
|
1412
|
+
const manifestPath = join3(services.cwd, candidate, MANIFEST_FILENAME);
|
|
1413
|
+
if (services.fs.existsSync(manifestPath)) {
|
|
1414
|
+
return candidate;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
return "./registry";
|
|
1418
|
+
}
|
|
1419
|
+
function resolveManifestPath(registryPath, services) {
|
|
1420
|
+
if (registryPath.endsWith(".yaml") || registryPath.endsWith(".yml")) {
|
|
1421
|
+
return join3(services.cwd, registryPath);
|
|
1422
|
+
}
|
|
1423
|
+
return join3(services.cwd, registryPath, MANIFEST_FILENAME);
|
|
1424
|
+
}
|
|
1425
|
+
async function loadManifestFromPath(manifestPath, services) {
|
|
1426
|
+
if (!services.fs.existsSync(manifestPath)) {
|
|
1427
|
+
throw new ManifestLoadError(
|
|
1428
|
+
`Registry manifest not found at: ${manifestPath}
|
|
1429
|
+
Run \`prs pull\` to fetch the registry or check your registry configuration.`
|
|
1430
|
+
);
|
|
1431
|
+
}
|
|
1432
|
+
try {
|
|
1433
|
+
const content = await services.fs.readFile(manifestPath, "utf-8");
|
|
1434
|
+
const manifest = parseYaml2(content);
|
|
1435
|
+
return manifest;
|
|
1436
|
+
} catch (error) {
|
|
1437
|
+
throw new ManifestLoadError(
|
|
1438
|
+
`Failed to parse manifest: ${manifestPath}`,
|
|
1439
|
+
error instanceof Error ? error : void 0
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
function validateManifest(manifest) {
|
|
1444
|
+
if (!manifest.version) {
|
|
1445
|
+
throw new ManifestLoadError("Manifest missing required field: version");
|
|
1446
|
+
}
|
|
1447
|
+
if (manifest.version !== "1") {
|
|
1448
|
+
throw new ManifestLoadError(`Unsupported manifest version: ${manifest.version}`);
|
|
1449
|
+
}
|
|
1450
|
+
if (!manifest.meta) {
|
|
1451
|
+
throw new ManifestLoadError("Manifest missing required field: meta");
|
|
1452
|
+
}
|
|
1453
|
+
if (!manifest.catalog) {
|
|
1454
|
+
throw new ManifestLoadError("Manifest missing required field: catalog");
|
|
1455
|
+
}
|
|
1456
|
+
if (!Array.isArray(manifest.catalog)) {
|
|
1457
|
+
throw new ManifestLoadError("Manifest catalog must be an array");
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
async function loadManifestFromUrl(url = OFFICIAL_REGISTRY.manifestUrl, useCache = true) {
|
|
1461
|
+
if (useCache && manifestCache.has(url)) {
|
|
1462
|
+
return {
|
|
1463
|
+
manifest: manifestCache.get(url),
|
|
1464
|
+
url,
|
|
1465
|
+
cached: true
|
|
1466
|
+
};
|
|
1467
|
+
}
|
|
1468
|
+
try {
|
|
1469
|
+
const response = await fetch(url, {
|
|
1470
|
+
headers: {
|
|
1471
|
+
Accept: "application/x-yaml, text/yaml, text/plain",
|
|
1472
|
+
"User-Agent": "PromptScript-CLI"
|
|
1473
|
+
}
|
|
1474
|
+
});
|
|
1475
|
+
if (!response.ok) {
|
|
1476
|
+
throw new ManifestLoadError(
|
|
1477
|
+
`Failed to fetch manifest from ${url}: ${response.status} ${response.statusText}`
|
|
1478
|
+
);
|
|
1479
|
+
}
|
|
1480
|
+
const content = await response.text();
|
|
1481
|
+
const manifest = parseYaml2(content);
|
|
1482
|
+
validateManifest(manifest);
|
|
1483
|
+
if (useCache) {
|
|
1484
|
+
manifestCache.set(url, manifest);
|
|
1485
|
+
}
|
|
1486
|
+
return {
|
|
1487
|
+
manifest,
|
|
1488
|
+
url,
|
|
1489
|
+
cached: false
|
|
1490
|
+
};
|
|
1491
|
+
} catch (error) {
|
|
1492
|
+
if (error instanceof ManifestLoadError) {
|
|
1493
|
+
throw error;
|
|
1494
|
+
}
|
|
1495
|
+
throw new ManifestLoadError(
|
|
1496
|
+
`Failed to load manifest from ${url}`,
|
|
1497
|
+
error instanceof Error ? error : void 0
|
|
1498
|
+
);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
function isValidGitUrl(url, allowedHosts) {
|
|
1502
|
+
try {
|
|
1503
|
+
if (url.startsWith("git@")) {
|
|
1504
|
+
const hostMatch = url.match(/^git@([^:]+):/);
|
|
1505
|
+
if (hostMatch && hostMatch[1]) {
|
|
1506
|
+
const host = hostMatch[1];
|
|
1507
|
+
return allowedHosts ? allowedHosts.includes(host) : true;
|
|
1508
|
+
}
|
|
1509
|
+
return false;
|
|
1510
|
+
}
|
|
1511
|
+
if (!url.startsWith("https://") && !url.startsWith("http://")) {
|
|
1512
|
+
return false;
|
|
1513
|
+
}
|
|
1514
|
+
const parsed = new URL(url);
|
|
1515
|
+
if (!parsed.hostname || parsed.hostname.length === 0) {
|
|
1516
|
+
return false;
|
|
1517
|
+
}
|
|
1518
|
+
if (allowedHosts) {
|
|
1519
|
+
return allowedHosts.includes(parsed.hostname);
|
|
1520
|
+
}
|
|
1521
|
+
return true;
|
|
1522
|
+
} catch {
|
|
1523
|
+
return false;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
// packages/cli/src/utils/suggestion-engine.ts
|
|
1528
|
+
async function buildProjectContext(projectInfo, services = createDefaultServices()) {
|
|
1529
|
+
const files = await detectProjectFiles(services);
|
|
1530
|
+
const dependencies = await detectDependencies(services);
|
|
1531
|
+
return {
|
|
1532
|
+
files,
|
|
1533
|
+
dependencies,
|
|
1534
|
+
languages: projectInfo.languages,
|
|
1535
|
+
frameworks: projectInfo.frameworks
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
async function detectProjectFiles(services) {
|
|
1539
|
+
const relevantFiles = [
|
|
1540
|
+
"package.json",
|
|
1541
|
+
"tsconfig.json",
|
|
1542
|
+
"pyproject.toml",
|
|
1543
|
+
"requirements.txt",
|
|
1544
|
+
"Cargo.toml",
|
|
1545
|
+
"go.mod",
|
|
1546
|
+
"pom.xml",
|
|
1547
|
+
"build.gradle",
|
|
1548
|
+
".git",
|
|
1549
|
+
".env",
|
|
1550
|
+
".env.example",
|
|
1551
|
+
"jest.config.js",
|
|
1552
|
+
"vitest.config.ts",
|
|
1553
|
+
"vitest.config.js",
|
|
1554
|
+
"pytest.ini",
|
|
1555
|
+
"next.config.js",
|
|
1556
|
+
"next.config.mjs",
|
|
1557
|
+
"next.config.ts",
|
|
1558
|
+
"nuxt.config.js",
|
|
1559
|
+
"nuxt.config.ts",
|
|
1560
|
+
"vite.config.js",
|
|
1561
|
+
"vite.config.ts",
|
|
1562
|
+
"Dockerfile",
|
|
1563
|
+
"docker-compose.yml"
|
|
1564
|
+
];
|
|
1565
|
+
const existingFiles = [];
|
|
1566
|
+
for (const file of relevantFiles) {
|
|
1567
|
+
if (services.fs.existsSync(file)) {
|
|
1568
|
+
existingFiles.push(file);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
return existingFiles;
|
|
1572
|
+
}
|
|
1573
|
+
async function detectDependencies(services) {
|
|
1574
|
+
if (!services.fs.existsSync("package.json")) {
|
|
1575
|
+
return [];
|
|
1576
|
+
}
|
|
1577
|
+
try {
|
|
1578
|
+
const content = await services.fs.readFile("package.json", "utf-8");
|
|
1579
|
+
const pkg = JSON.parse(content);
|
|
1580
|
+
return [...Object.keys(pkg.dependencies ?? {}), ...Object.keys(pkg.devDependencies ?? {})];
|
|
1581
|
+
} catch {
|
|
1582
|
+
return [];
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
function calculateSuggestions(manifest, context) {
|
|
1586
|
+
const result = {
|
|
1587
|
+
inherit: void 0,
|
|
1588
|
+
use: [],
|
|
1589
|
+
skills: [],
|
|
1590
|
+
reasoning: []
|
|
1591
|
+
};
|
|
1592
|
+
const suggestedUse = /* @__PURE__ */ new Set();
|
|
1593
|
+
const suggestedSkills = /* @__PURE__ */ new Set();
|
|
1594
|
+
for (const rule of manifest.suggestionRules) {
|
|
1595
|
+
const match = matchCondition(rule.condition, context);
|
|
1596
|
+
if (match.matches) {
|
|
1597
|
+
if (rule.suggest.inherit) {
|
|
1598
|
+
if (!result.inherit) {
|
|
1599
|
+
result.inherit = rule.suggest.inherit;
|
|
1600
|
+
result.reasoning.push({
|
|
1601
|
+
suggestion: `inherit: ${rule.suggest.inherit}`,
|
|
1602
|
+
reason: match.reason,
|
|
1603
|
+
trigger: match.trigger,
|
|
1604
|
+
matchedValue: match.matchedValue
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
if (rule.suggest.use) {
|
|
1609
|
+
for (const useItem of rule.suggest.use) {
|
|
1610
|
+
if (!suggestedUse.has(useItem)) {
|
|
1611
|
+
suggestedUse.add(useItem);
|
|
1612
|
+
result.use.push(useItem);
|
|
1613
|
+
result.reasoning.push({
|
|
1614
|
+
suggestion: `use: ${useItem}`,
|
|
1615
|
+
reason: match.reason,
|
|
1616
|
+
trigger: match.trigger,
|
|
1617
|
+
matchedValue: match.matchedValue
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
if (rule.suggest.skills) {
|
|
1623
|
+
for (const skill of rule.suggest.skills) {
|
|
1624
|
+
if (!suggestedSkills.has(skill)) {
|
|
1625
|
+
suggestedSkills.add(skill);
|
|
1626
|
+
result.skills.push(skill);
|
|
1627
|
+
result.reasoning.push({
|
|
1628
|
+
suggestion: `skill: ${skill}`,
|
|
1629
|
+
reason: match.reason,
|
|
1630
|
+
trigger: match.trigger,
|
|
1631
|
+
matchedValue: match.matchedValue
|
|
1632
|
+
});
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
return result;
|
|
1639
|
+
}
|
|
1640
|
+
function matchCondition(condition, context) {
|
|
1641
|
+
if (condition.always) {
|
|
1642
|
+
return {
|
|
1643
|
+
matches: true,
|
|
1644
|
+
reason: "Default recommendation",
|
|
1645
|
+
trigger: "always"
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
if (condition.files) {
|
|
1649
|
+
for (const file of condition.files) {
|
|
1650
|
+
if (context.files.includes(file)) {
|
|
1651
|
+
return {
|
|
1652
|
+
matches: true,
|
|
1653
|
+
reason: `Detected file: ${file}`,
|
|
1654
|
+
trigger: "file",
|
|
1655
|
+
matchedValue: file
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
if (condition.dependencies) {
|
|
1661
|
+
for (const dep of condition.dependencies) {
|
|
1662
|
+
if (context.dependencies.includes(dep)) {
|
|
1663
|
+
return {
|
|
1664
|
+
matches: true,
|
|
1665
|
+
reason: `Detected dependency: ${dep}`,
|
|
1666
|
+
trigger: "dependency",
|
|
1667
|
+
matchedValue: dep
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
if (condition.languages) {
|
|
1673
|
+
for (const lang of condition.languages) {
|
|
1674
|
+
if (context.languages.includes(lang)) {
|
|
1675
|
+
return {
|
|
1676
|
+
matches: true,
|
|
1677
|
+
reason: `Detected language: ${lang}`,
|
|
1678
|
+
trigger: "language",
|
|
1679
|
+
matchedValue: lang
|
|
1680
|
+
};
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
if (condition.frameworks) {
|
|
1685
|
+
for (const framework of condition.frameworks) {
|
|
1686
|
+
if (context.frameworks.includes(framework)) {
|
|
1687
|
+
return {
|
|
1688
|
+
matches: true,
|
|
1689
|
+
reason: `Detected framework: ${framework}`,
|
|
1690
|
+
trigger: "framework",
|
|
1691
|
+
matchedValue: framework
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
return {
|
|
1697
|
+
matches: false,
|
|
1698
|
+
reason: "",
|
|
1699
|
+
trigger: "always"
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
function formatSuggestionResult(result) {
|
|
1703
|
+
const lines = [];
|
|
1704
|
+
if (result.inherit) {
|
|
1705
|
+
lines.push(`\u{1F4E6} Inherit: ${result.inherit}`);
|
|
1706
|
+
}
|
|
1707
|
+
if (result.use.length > 0) {
|
|
1708
|
+
lines.push(`\u{1F527} Use: ${result.use.join(", ")}`);
|
|
1709
|
+
}
|
|
1710
|
+
if (result.skills.length > 0) {
|
|
1711
|
+
lines.push(`\u26A1 Skills: ${result.skills.join(", ")}`);
|
|
1712
|
+
}
|
|
1713
|
+
if (result.reasoning.length > 0) {
|
|
1714
|
+
lines.push("");
|
|
1715
|
+
lines.push("Reasoning:");
|
|
1716
|
+
for (const r of result.reasoning) {
|
|
1717
|
+
lines.push(` \u2022 ${r.suggestion} (${r.reason})`);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
return lines;
|
|
1721
|
+
}
|
|
1722
|
+
function createSuggestionChoices(manifest, result) {
|
|
1723
|
+
const choices = [];
|
|
1724
|
+
if (result.inherit) {
|
|
1725
|
+
const entry = manifest.catalog.find((e) => e.id === result.inherit);
|
|
1726
|
+
choices.push({
|
|
1727
|
+
name: `${result.inherit} (inherit)`,
|
|
1728
|
+
value: `inherit:${result.inherit}`,
|
|
1729
|
+
checked: true,
|
|
1730
|
+
description: entry?.description
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
for (const use of result.use) {
|
|
1734
|
+
const entry = manifest.catalog.find((e) => e.id === use);
|
|
1735
|
+
choices.push({
|
|
1736
|
+
name: `${use} (use)`,
|
|
1737
|
+
value: `use:${use}`,
|
|
1738
|
+
checked: true,
|
|
1739
|
+
description: entry?.description
|
|
1740
|
+
});
|
|
1741
|
+
}
|
|
1742
|
+
for (const skill of result.skills) {
|
|
1743
|
+
const entry = manifest.catalog.find((e) => e.id === skill);
|
|
1744
|
+
choices.push({
|
|
1745
|
+
name: `${skill} (skill)`,
|
|
1746
|
+
value: `skill:${skill}`,
|
|
1747
|
+
checked: true,
|
|
1748
|
+
description: entry?.description
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
return choices;
|
|
1752
|
+
}
|
|
1753
|
+
function parseSelectedChoices(selected) {
|
|
1754
|
+
const result = {
|
|
1755
|
+
use: [],
|
|
1756
|
+
skills: []
|
|
1757
|
+
};
|
|
1758
|
+
for (const choice of selected) {
|
|
1759
|
+
if (choice.startsWith("inherit:")) {
|
|
1760
|
+
result.inherit = choice.slice("inherit:".length);
|
|
1761
|
+
} else if (choice.startsWith("use:")) {
|
|
1762
|
+
result.use.push(choice.slice("use:".length));
|
|
1763
|
+
} else if (choice.startsWith("skill:")) {
|
|
1764
|
+
result.skills.push(choice.slice("skill:".length));
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
return result;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1369
1770
|
// packages/cli/src/commands/init.ts
|
|
1370
1771
|
var __filename = fileURLToPath(import.meta.url);
|
|
1371
|
-
var __dirname =
|
|
1772
|
+
var __dirname = dirname3(__filename);
|
|
1372
1773
|
async function initCommand(options, services = createDefaultServices()) {
|
|
1373
1774
|
const { fs: fs4 } = services;
|
|
1374
1775
|
if (fs4.existsSync("promptscript.yaml") && !options.force) {
|
|
@@ -1380,11 +1781,22 @@ async function initCommand(options, services = createDefaultServices()) {
|
|
|
1380
1781
|
const projectInfo = await detectProject(services);
|
|
1381
1782
|
const aiToolsDetection = await detectAITools(services);
|
|
1382
1783
|
const prettierConfigPath = findPrettierConfig(process.cwd());
|
|
1784
|
+
let manifest;
|
|
1785
|
+
try {
|
|
1786
|
+
const registryPath = options.registry ?? "./registry";
|
|
1787
|
+
const { manifest: loadedManifest } = await loadManifest({ registryPath }, services);
|
|
1788
|
+
manifest = loadedManifest;
|
|
1789
|
+
} catch (error) {
|
|
1790
|
+
if (!(error instanceof ManifestLoadError)) {
|
|
1791
|
+
throw error;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1383
1794
|
const config = await resolveConfig(
|
|
1384
1795
|
options,
|
|
1385
1796
|
projectInfo,
|
|
1386
1797
|
aiToolsDetection,
|
|
1387
1798
|
prettierConfigPath,
|
|
1799
|
+
manifest,
|
|
1388
1800
|
services
|
|
1389
1801
|
);
|
|
1390
1802
|
const spinner = createSpinner("Creating PromptScript configuration...").start();
|
|
@@ -1440,7 +1852,14 @@ async function initCommand(options, services = createDefaultServices()) {
|
|
|
1440
1852
|
ConsoleOutput.muted(` Inherit: ${config.inherit}`);
|
|
1441
1853
|
}
|
|
1442
1854
|
if (config.registry) {
|
|
1443
|
-
|
|
1855
|
+
if (config.registry.type === "git") {
|
|
1856
|
+
ConsoleOutput.muted(` Registry: ${config.registry.url} (${config.registry.ref})`);
|
|
1857
|
+
} else {
|
|
1858
|
+
ConsoleOutput.muted(` Registry: ${config.registry.path} (local)`);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
if (config.use && config.use.length > 0) {
|
|
1862
|
+
ConsoleOutput.muted(` Use: ${config.use.join(", ")}`);
|
|
1444
1863
|
}
|
|
1445
1864
|
ConsoleOutput.newline();
|
|
1446
1865
|
if (config.prettierConfigPath) {
|
|
@@ -1494,23 +1913,46 @@ async function initCommand(options, services = createDefaultServices()) {
|
|
|
1494
1913
|
process.exit(1);
|
|
1495
1914
|
}
|
|
1496
1915
|
}
|
|
1497
|
-
async function resolveConfig(options, projectInfo, aiToolsDetection, prettierConfigPath, services) {
|
|
1916
|
+
async function resolveConfig(options, projectInfo, aiToolsDetection, prettierConfigPath, manifest, services) {
|
|
1498
1917
|
if (options.yes) {
|
|
1918
|
+
let inherit = options.inherit;
|
|
1919
|
+
let use;
|
|
1920
|
+
let activeManifest = manifest;
|
|
1921
|
+
if (!activeManifest) {
|
|
1922
|
+
try {
|
|
1923
|
+
const { manifest: remoteManifest } = await loadManifestFromUrl();
|
|
1924
|
+
activeManifest = remoteManifest;
|
|
1925
|
+
} catch {
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
if (activeManifest) {
|
|
1929
|
+
const context = await buildProjectContext(projectInfo, services);
|
|
1930
|
+
const suggestions = calculateSuggestions(activeManifest, context);
|
|
1931
|
+
if (!inherit && suggestions.inherit) {
|
|
1932
|
+
inherit = suggestions.inherit;
|
|
1933
|
+
}
|
|
1934
|
+
if (suggestions.use.length > 0) {
|
|
1935
|
+
use = suggestions.use;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
const registry = options.registry ? { type: "local", path: options.registry } : { type: "git", url: OFFICIAL_REGISTRY.url, ref: OFFICIAL_REGISTRY.branch };
|
|
1499
1939
|
return {
|
|
1500
1940
|
projectId: options.name ?? projectInfo.name,
|
|
1501
1941
|
team: options.team,
|
|
1502
|
-
inherit
|
|
1503
|
-
|
|
1942
|
+
inherit,
|
|
1943
|
+
use,
|
|
1944
|
+
registry,
|
|
1504
1945
|
targets: options.targets ?? getSuggestedTargets(aiToolsDetection),
|
|
1505
1946
|
prettierConfigPath
|
|
1506
1947
|
};
|
|
1507
1948
|
}
|
|
1508
1949
|
if (!options.interactive && options.name && options.targets) {
|
|
1950
|
+
const registry = options.registry ? { type: "local", path: options.registry } : void 0;
|
|
1509
1951
|
return {
|
|
1510
1952
|
projectId: options.name,
|
|
1511
1953
|
team: options.team,
|
|
1512
1954
|
inherit: options.inherit,
|
|
1513
|
-
registry
|
|
1955
|
+
registry,
|
|
1514
1956
|
targets: options.targets,
|
|
1515
1957
|
prettierConfigPath
|
|
1516
1958
|
};
|
|
@@ -1520,10 +1962,11 @@ async function resolveConfig(options, projectInfo, aiToolsDetection, prettierCon
|
|
|
1520
1962
|
projectInfo,
|
|
1521
1963
|
aiToolsDetection,
|
|
1522
1964
|
prettierConfigPath,
|
|
1965
|
+
manifest,
|
|
1523
1966
|
services
|
|
1524
1967
|
);
|
|
1525
1968
|
}
|
|
1526
|
-
async function runInteractivePrompts(options, projectInfo, aiToolsDetection, prettierConfigPath, services) {
|
|
1969
|
+
async function runInteractivePrompts(options, projectInfo, aiToolsDetection, prettierConfigPath, manifest, services) {
|
|
1527
1970
|
const { prompts: prompts2 } = services;
|
|
1528
1971
|
ConsoleOutput.newline();
|
|
1529
1972
|
console.log("\u{1F680} PromptScript Setup");
|
|
@@ -1549,33 +1992,124 @@ async function runInteractivePrompts(options, projectInfo, aiToolsDetection, pre
|
|
|
1549
1992
|
message: "Project name:",
|
|
1550
1993
|
default: options.name ?? projectInfo.name
|
|
1551
1994
|
});
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1995
|
+
let registry;
|
|
1996
|
+
let activeManifest = manifest;
|
|
1997
|
+
const registryChoice = await prompts2.select({
|
|
1998
|
+
message: "Registry configuration:",
|
|
1999
|
+
choices: [
|
|
2000
|
+
{
|
|
2001
|
+
name: `\u{1F4E6} Use official PromptScript Registry (${OFFICIAL_REGISTRY.url})`,
|
|
2002
|
+
value: "official"
|
|
2003
|
+
},
|
|
2004
|
+
{
|
|
2005
|
+
name: "\u{1F517} Connect to a custom Git registry",
|
|
2006
|
+
value: "custom-git"
|
|
2007
|
+
},
|
|
2008
|
+
{
|
|
2009
|
+
name: "\u{1F4C1} Use a local registry directory",
|
|
2010
|
+
value: "local"
|
|
2011
|
+
},
|
|
2012
|
+
{
|
|
2013
|
+
name: "\u23ED\uFE0F Skip registry (configure later)",
|
|
2014
|
+
value: "skip"
|
|
2015
|
+
}
|
|
2016
|
+
],
|
|
2017
|
+
default: manifest ? "official" : "skip"
|
|
1555
2018
|
});
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
2019
|
+
if (registryChoice === "official") {
|
|
2020
|
+
registry = {
|
|
2021
|
+
type: "git",
|
|
2022
|
+
url: OFFICIAL_REGISTRY.url,
|
|
2023
|
+
ref: OFFICIAL_REGISTRY.branch
|
|
2024
|
+
};
|
|
2025
|
+
if (!activeManifest) {
|
|
2026
|
+
try {
|
|
2027
|
+
ConsoleOutput.muted("Fetching registry manifest...");
|
|
2028
|
+
const { manifest: remoteManifest } = await loadManifestFromUrl();
|
|
2029
|
+
activeManifest = remoteManifest;
|
|
2030
|
+
ConsoleOutput.success(
|
|
2031
|
+
`Loaded ${remoteManifest.catalog.length} configurations from official registry`
|
|
2032
|
+
);
|
|
2033
|
+
} catch {
|
|
2034
|
+
ConsoleOutput.warn("Could not fetch registry manifest - suggestions will be limited");
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
} else if (registryChoice === "custom-git") {
|
|
2038
|
+
const gitUrl = await prompts2.input({
|
|
2039
|
+
message: "Git repository URL:",
|
|
2040
|
+
default: "https://github.com/your-org/your-registry.git",
|
|
1561
2041
|
validate: (value) => {
|
|
1562
|
-
if (!value
|
|
1563
|
-
return "
|
|
2042
|
+
if (!isValidGitUrl(value)) {
|
|
2043
|
+
return "Please enter a valid Git repository URL (https:// or git@)";
|
|
1564
2044
|
}
|
|
1565
2045
|
return true;
|
|
1566
2046
|
}
|
|
1567
2047
|
});
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
2048
|
+
const gitRef = await prompts2.input({
|
|
2049
|
+
message: "Branch or tag:",
|
|
2050
|
+
default: "main"
|
|
2051
|
+
});
|
|
2052
|
+
registry = {
|
|
2053
|
+
type: "git",
|
|
2054
|
+
url: gitUrl,
|
|
2055
|
+
ref: gitRef
|
|
2056
|
+
};
|
|
2057
|
+
} else if (registryChoice === "local") {
|
|
2058
|
+
const localPath = await prompts2.input({
|
|
2059
|
+
message: "Local registry path:",
|
|
1577
2060
|
default: options.registry ?? "./registry"
|
|
1578
2061
|
});
|
|
2062
|
+
registry = {
|
|
2063
|
+
type: "local",
|
|
2064
|
+
path: localPath
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
let inherit = options.inherit;
|
|
2068
|
+
let use;
|
|
2069
|
+
if (activeManifest) {
|
|
2070
|
+
const context = await buildProjectContext(projectInfo, services);
|
|
2071
|
+
const suggestions = calculateSuggestions(activeManifest, context);
|
|
2072
|
+
if (suggestions.inherit || suggestions.use.length > 0) {
|
|
2073
|
+
ConsoleOutput.newline();
|
|
2074
|
+
console.log("\u{1F4E6} Suggested configurations based on your project:");
|
|
2075
|
+
const suggestionLines = formatSuggestionResult(suggestions);
|
|
2076
|
+
for (const line of suggestionLines) {
|
|
2077
|
+
ConsoleOutput.muted(` ${line}`);
|
|
2078
|
+
}
|
|
2079
|
+
ConsoleOutput.newline();
|
|
2080
|
+
const choices = createSuggestionChoices(activeManifest, suggestions);
|
|
2081
|
+
if (choices.length > 0) {
|
|
2082
|
+
const selected = await prompts2.checkbox({
|
|
2083
|
+
message: "Select configurations to use:",
|
|
2084
|
+
choices: choices.map((c) => ({
|
|
2085
|
+
name: c.description ? `${c.name} - ${c.description}` : c.name,
|
|
2086
|
+
value: c.value,
|
|
2087
|
+
checked: c.checked
|
|
2088
|
+
}))
|
|
2089
|
+
});
|
|
2090
|
+
const parsed = parseSelectedChoices(selected);
|
|
2091
|
+
inherit = parsed.inherit;
|
|
2092
|
+
use = parsed.use.length > 0 ? parsed.use : void 0;
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
if (!inherit) {
|
|
2097
|
+
const wantsInherit = await prompts2.confirm({
|
|
2098
|
+
message: "Do you want to inherit from a parent configuration?",
|
|
2099
|
+
default: false
|
|
2100
|
+
});
|
|
2101
|
+
if (wantsInherit) {
|
|
2102
|
+
inherit = await prompts2.input({
|
|
2103
|
+
message: "Inheritance path (e.g., @stacks/react):",
|
|
2104
|
+
default: options.inherit ?? "@stacks/react",
|
|
2105
|
+
validate: (value) => {
|
|
2106
|
+
if (!value.startsWith("@")) {
|
|
2107
|
+
return "Inheritance path should start with @";
|
|
2108
|
+
}
|
|
2109
|
+
return true;
|
|
2110
|
+
}
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
1579
2113
|
}
|
|
1580
2114
|
const suggestedTargets = getSuggestedTargets(aiToolsDetection);
|
|
1581
2115
|
const allTargets = getAllTargets();
|
|
@@ -1604,6 +2138,7 @@ async function runInteractivePrompts(options, projectInfo, aiToolsDetection, pre
|
|
|
1604
2138
|
projectId,
|
|
1605
2139
|
team,
|
|
1606
2140
|
inherit,
|
|
2141
|
+
use,
|
|
1607
2142
|
registry,
|
|
1608
2143
|
targets,
|
|
1609
2144
|
prettierConfigPath
|
|
@@ -1627,13 +2162,34 @@ function generateConfig(config) {
|
|
|
1627
2162
|
if (config.inherit) {
|
|
1628
2163
|
lines.push(`inherit: '${config.inherit}'`);
|
|
1629
2164
|
} else {
|
|
1630
|
-
lines.push("# inherit: '@
|
|
2165
|
+
lines.push("# inherit: '@stacks/react'");
|
|
2166
|
+
}
|
|
2167
|
+
lines.push("");
|
|
2168
|
+
if (config.use && config.use.length > 0) {
|
|
2169
|
+
lines.push("use:");
|
|
2170
|
+
for (const useItem of config.use) {
|
|
2171
|
+
lines.push(` - '${useItem}'`);
|
|
2172
|
+
}
|
|
2173
|
+
} else {
|
|
2174
|
+
lines.push("# use:", "# - '@fragments/testing'", "# - '@fragments/typescript'");
|
|
1631
2175
|
}
|
|
1632
2176
|
lines.push("");
|
|
1633
2177
|
if (config.registry) {
|
|
1634
|
-
|
|
2178
|
+
if (config.registry.type === "git") {
|
|
2179
|
+
lines.push("registry:", " git:", ` url: '${config.registry.url}'`);
|
|
2180
|
+
if (config.registry.ref) {
|
|
2181
|
+
lines.push(` ref: '${config.registry.ref}'`);
|
|
2182
|
+
}
|
|
2183
|
+
} else {
|
|
2184
|
+
lines.push("registry:", ` path: '${config.registry.path}'`);
|
|
2185
|
+
}
|
|
1635
2186
|
} else {
|
|
1636
|
-
lines.push(
|
|
2187
|
+
lines.push(
|
|
2188
|
+
"# registry:",
|
|
2189
|
+
"# git:",
|
|
2190
|
+
"# url: 'https://github.com/mrwogu/promptscript-registry.git'",
|
|
2191
|
+
"# ref: 'main'"
|
|
2192
|
+
);
|
|
1637
2193
|
}
|
|
1638
2194
|
lines.push("", "targets:");
|
|
1639
2195
|
for (const target of config.targets) {
|
|
@@ -1654,7 +2210,13 @@ function generateConfig(config) {
|
|
|
1654
2210
|
return lines.join("\n");
|
|
1655
2211
|
}
|
|
1656
2212
|
function generateProjectPs(config, projectInfo) {
|
|
1657
|
-
const inheritLine = config.inherit ? `@inherit ${config.inherit}` : "# @inherit @
|
|
2213
|
+
const inheritLine = config.inherit ? `@inherit ${config.inherit}` : "# @inherit @stacks/react";
|
|
2214
|
+
let useLines = "";
|
|
2215
|
+
if (config.use && config.use.length > 0) {
|
|
2216
|
+
useLines = config.use.map((u) => `@use ${u}`).join("\n");
|
|
2217
|
+
} else {
|
|
2218
|
+
useLines = "# @use @fragments/testing\n# @use @fragments/typescript";
|
|
2219
|
+
}
|
|
1658
2220
|
const languagesLine = projectInfo.languages.length > 0 ? ` languages: [${projectInfo.languages.join(", ")}]` : " # languages: [typescript]";
|
|
1659
2221
|
const frameworksLine = projectInfo.frameworks.length > 0 ? ` frameworks: [${projectInfo.frameworks.join(", ")}]` : " # frameworks: []";
|
|
1660
2222
|
const syntaxVersion = getPackageVersion(__dirname, "./package.json");
|
|
@@ -1667,11 +2229,12 @@ function generateProjectPs(config, projectInfo) {
|
|
|
1667
2229
|
}
|
|
1668
2230
|
|
|
1669
2231
|
${inheritLine}
|
|
2232
|
+
${useLines}
|
|
1670
2233
|
|
|
1671
2234
|
@identity {
|
|
1672
2235
|
"""
|
|
1673
2236
|
You are working on the ${config.projectId} project.
|
|
1674
|
-
|
|
2237
|
+
|
|
1675
2238
|
[Describe your project here]
|
|
1676
2239
|
"""
|
|
1677
2240
|
}
|
|
@@ -1700,7 +2263,7 @@ ${frameworksLine}
|
|
|
1700
2263
|
}
|
|
1701
2264
|
|
|
1702
2265
|
// packages/cli/src/commands/compile.ts
|
|
1703
|
-
import { resolve as resolve4, dirname as
|
|
2266
|
+
import { resolve as resolve4, dirname as dirname6 } from "path";
|
|
1704
2267
|
import { writeFile as writeFile2, mkdir as mkdir2, readFile as readFile6 } from "fs/promises";
|
|
1705
2268
|
import { existsSync as existsSync7 } from "fs";
|
|
1706
2269
|
import chokidar from "chokidar";
|
|
@@ -1708,7 +2271,7 @@ import chokidar from "chokidar";
|
|
|
1708
2271
|
// packages/cli/src/config/loader.ts
|
|
1709
2272
|
import { readFile as readFile3 } from "fs/promises";
|
|
1710
2273
|
import { existsSync as existsSync3 } from "fs";
|
|
1711
|
-
import { parse as
|
|
2274
|
+
import { parse as parseYaml3 } from "yaml";
|
|
1712
2275
|
var CONFIG_FILES = [
|
|
1713
2276
|
"promptscript.yaml",
|
|
1714
2277
|
"promptscript.yml",
|
|
@@ -1755,7 +2318,7 @@ async function loadConfig(customPath) {
|
|
|
1755
2318
|
let content = await readFile3(configFile, "utf-8");
|
|
1756
2319
|
content = interpolateEnvVars(content);
|
|
1757
2320
|
try {
|
|
1758
|
-
return
|
|
2321
|
+
return parseYaml3(content);
|
|
1759
2322
|
} catch (error) {
|
|
1760
2323
|
const message = error instanceof Error ? error.message : "Unknown parse error";
|
|
1761
2324
|
throw new Error(`Failed to parse ${configFile}: ${message}`);
|
|
@@ -15317,7 +15880,7 @@ function parse(source, options = {}) {
|
|
|
15317
15880
|
|
|
15318
15881
|
// packages/resolver/src/loader.ts
|
|
15319
15882
|
import { readFile as readFile4 } from "fs/promises";
|
|
15320
|
-
import { resolve as resolve2, dirname as
|
|
15883
|
+
import { resolve as resolve2, dirname as dirname4, isAbsolute } from "path";
|
|
15321
15884
|
var FileLoader = class {
|
|
15322
15885
|
registryPath;
|
|
15323
15886
|
localPath;
|
|
@@ -15378,7 +15941,7 @@ var FileLoader = class {
|
|
|
15378
15941
|
*/
|
|
15379
15942
|
resolveRef(ref, fromFile) {
|
|
15380
15943
|
if (ref.isRelative) {
|
|
15381
|
-
const dir =
|
|
15944
|
+
const dir = dirname4(fromFile);
|
|
15382
15945
|
const rawPath = ref.raw.endsWith(".prs") ? ref.raw : `${ref.raw}.prs`;
|
|
15383
15946
|
return resolve2(dir, rawPath);
|
|
15384
15947
|
}
|
|
@@ -16040,7 +16603,7 @@ function uniqueConcat3(parent, child) {
|
|
|
16040
16603
|
|
|
16041
16604
|
// packages/resolver/src/skills.ts
|
|
16042
16605
|
import { readFile as readFile5, access } from "fs/promises";
|
|
16043
|
-
import { resolve as resolve3, dirname as
|
|
16606
|
+
import { resolve as resolve3, dirname as dirname5 } from "path";
|
|
16044
16607
|
function parseSkillMd(content) {
|
|
16045
16608
|
const lines = content.split("\n");
|
|
16046
16609
|
let inFrontmatter = false;
|
|
@@ -16095,7 +16658,7 @@ async function resolveNativeSkills(ast, registryPath, sourceFile) {
|
|
|
16095
16658
|
const skillsContent = skillsBlock.content;
|
|
16096
16659
|
const updatedProperties = { ...skillsContent.properties };
|
|
16097
16660
|
let hasUpdates = false;
|
|
16098
|
-
const sourceDir =
|
|
16661
|
+
const sourceDir = dirname5(sourceFile);
|
|
16099
16662
|
const isSkillsDir = sourceDir.includes("@skills");
|
|
16100
16663
|
for (const [skillName, skillValue] of Object.entries(skillsContent.properties)) {
|
|
16101
16664
|
if (typeof skillValue !== "object" || skillValue === null || Array.isArray(skillValue)) {
|
|
@@ -16323,7 +16886,7 @@ var Resolver = class {
|
|
|
16323
16886
|
|
|
16324
16887
|
// packages/resolver/src/registry.ts
|
|
16325
16888
|
import { existsSync as existsSync4, promises as fs } from "fs";
|
|
16326
|
-
import { join as
|
|
16889
|
+
import { join as join4 } from "path";
|
|
16327
16890
|
var FileSystemRegistry = class {
|
|
16328
16891
|
rootPath;
|
|
16329
16892
|
constructor(options) {
|
|
@@ -16333,7 +16896,7 @@ var FileSystemRegistry = class {
|
|
|
16333
16896
|
* Resolve a path relative to the registry root.
|
|
16334
16897
|
*/
|
|
16335
16898
|
resolvePath(path) {
|
|
16336
|
-
return
|
|
16899
|
+
return join4(this.rootPath, path);
|
|
16337
16900
|
}
|
|
16338
16901
|
async fetch(path) {
|
|
16339
16902
|
const fullPath = this.resolvePath(path);
|
|
@@ -16548,12 +17111,12 @@ function createHttpRegistry(options) {
|
|
|
16548
17111
|
|
|
16549
17112
|
// packages/resolver/src/git-registry.ts
|
|
16550
17113
|
import { existsSync as existsSync6, promises as fs3 } from "fs";
|
|
16551
|
-
import { join as
|
|
17114
|
+
import { join as join6 } from "path";
|
|
16552
17115
|
import { simpleGit } from "simple-git";
|
|
16553
17116
|
|
|
16554
17117
|
// packages/resolver/src/git-cache-manager.ts
|
|
16555
17118
|
import { existsSync as existsSync5, promises as fs2 } from "fs";
|
|
16556
|
-
import { join as
|
|
17119
|
+
import { join as join5 } from "path";
|
|
16557
17120
|
import { homedir } from "os";
|
|
16558
17121
|
|
|
16559
17122
|
// packages/resolver/src/git-url-utils.ts
|
|
@@ -16661,7 +17224,7 @@ function parseVersionedPath(path) {
|
|
|
16661
17224
|
}
|
|
16662
17225
|
|
|
16663
17226
|
// packages/resolver/src/git-cache-manager.ts
|
|
16664
|
-
var DEFAULT_CACHE_DIR =
|
|
17227
|
+
var DEFAULT_CACHE_DIR = join5(homedir(), ".promptscript", ".cache", "git");
|
|
16665
17228
|
var DEFAULT_TTL = 36e5;
|
|
16666
17229
|
var METADATA_FILE = ".prs-cache-meta.json";
|
|
16667
17230
|
var GitCacheManager = class {
|
|
@@ -16680,7 +17243,7 @@ var GitCacheManager = class {
|
|
|
16680
17243
|
*/
|
|
16681
17244
|
getCachePath(url, ref) {
|
|
16682
17245
|
const cacheKey = getCacheKey(url, ref);
|
|
16683
|
-
return
|
|
17246
|
+
return join5(this.cacheDir, cacheKey);
|
|
16684
17247
|
}
|
|
16685
17248
|
/**
|
|
16686
17249
|
* Check if a cache entry exists and is not stale.
|
|
@@ -16786,7 +17349,7 @@ var GitCacheManager = class {
|
|
|
16786
17349
|
if (!dir.isDirectory()) {
|
|
16787
17350
|
continue;
|
|
16788
17351
|
}
|
|
16789
|
-
const cachePath =
|
|
17352
|
+
const cachePath = join5(this.cacheDir, dir.name);
|
|
16790
17353
|
const metadata = await this.readMetadata(cachePath);
|
|
16791
17354
|
if (metadata) {
|
|
16792
17355
|
const isStale = Date.now() - metadata.lastUpdated > this.ttl;
|
|
@@ -16834,7 +17397,7 @@ var GitCacheManager = class {
|
|
|
16834
17397
|
let size = 0;
|
|
16835
17398
|
const entries = await fs2.readdir(dirPath, { withFileTypes: true });
|
|
16836
17399
|
for (const entry of entries) {
|
|
16837
|
-
const fullPath =
|
|
17400
|
+
const fullPath = join5(dirPath, entry.name);
|
|
16838
17401
|
if (entry.isDirectory()) {
|
|
16839
17402
|
size += await this.calculateDirSize(fullPath);
|
|
16840
17403
|
} else {
|
|
@@ -16848,7 +17411,7 @@ var GitCacheManager = class {
|
|
|
16848
17411
|
* Read metadata from a cache directory.
|
|
16849
17412
|
*/
|
|
16850
17413
|
async readMetadata(cachePath) {
|
|
16851
|
-
const metadataPath =
|
|
17414
|
+
const metadataPath = join5(cachePath, METADATA_FILE);
|
|
16852
17415
|
if (!existsSync5(metadataPath)) {
|
|
16853
17416
|
return null;
|
|
16854
17417
|
}
|
|
@@ -16863,7 +17426,7 @@ var GitCacheManager = class {
|
|
|
16863
17426
|
* Write metadata to a cache directory.
|
|
16864
17427
|
*/
|
|
16865
17428
|
async writeMetadata(cachePath, metadata) {
|
|
16866
|
-
const metadataPath =
|
|
17429
|
+
const metadataPath = join5(cachePath, METADATA_FILE);
|
|
16867
17430
|
await fs2.writeFile(metadataPath, JSON.stringify(metadata, null, 2), "utf-8");
|
|
16868
17431
|
}
|
|
16869
17432
|
};
|
|
@@ -17154,9 +17717,9 @@ var GitRegistry = class {
|
|
|
17154
17717
|
cleanPath += ".prs";
|
|
17155
17718
|
}
|
|
17156
17719
|
if (this.subPath) {
|
|
17157
|
-
return
|
|
17720
|
+
return join6(repoPath, this.subPath, cleanPath);
|
|
17158
17721
|
}
|
|
17159
|
-
return
|
|
17722
|
+
return join6(repoPath, cleanPath);
|
|
17160
17723
|
}
|
|
17161
17724
|
/**
|
|
17162
17725
|
* Resolve a directory path within the repository.
|
|
@@ -17166,9 +17729,9 @@ var GitRegistry = class {
|
|
|
17166
17729
|
*/
|
|
17167
17730
|
resolveDirectoryPath(repoPath, relativePath) {
|
|
17168
17731
|
if (this.subPath) {
|
|
17169
|
-
return
|
|
17732
|
+
return join6(repoPath, this.subPath, relativePath);
|
|
17170
17733
|
}
|
|
17171
|
-
return
|
|
17734
|
+
return join6(repoPath, relativePath);
|
|
17172
17735
|
}
|
|
17173
17736
|
/**
|
|
17174
17737
|
* Check if an error is an authentication error.
|
|
@@ -17886,8 +18449,8 @@ var Compiler = class _Compiler {
|
|
|
17886
18449
|
*/
|
|
17887
18450
|
async watch(entryPath, options = {}) {
|
|
17888
18451
|
const { default: chokidar2 } = await import("chokidar");
|
|
17889
|
-
const { dirname:
|
|
17890
|
-
const baseDir =
|
|
18452
|
+
const { dirname: dirname10, resolve: resolve9 } = await import("path");
|
|
18453
|
+
const baseDir = dirname10(resolve9(entryPath));
|
|
17891
18454
|
const includePatterns = options.include ?? ["**/*.prs"];
|
|
17892
18455
|
const excludePatterns = options.exclude ?? ["**/node_modules/**"];
|
|
17893
18456
|
const debounceMs = options.debounce ?? 300;
|
|
@@ -18107,6 +18670,69 @@ function createPager(enabled = true) {
|
|
|
18107
18670
|
return new Pager(enabled);
|
|
18108
18671
|
}
|
|
18109
18672
|
|
|
18673
|
+
// packages/cli/src/utils/registry-resolver.ts
|
|
18674
|
+
import { join as join7 } from "path";
|
|
18675
|
+
async function resolveRegistryPath(config) {
|
|
18676
|
+
if (config.registry?.git) {
|
|
18677
|
+
const gitConfig = config.registry.git;
|
|
18678
|
+
const ref = gitConfig.ref ?? "main";
|
|
18679
|
+
const cacheManager = new GitCacheManager({
|
|
18680
|
+
ttl: config.registry.cache?.ttl
|
|
18681
|
+
});
|
|
18682
|
+
const normalizedUrl = normalizeGitUrl(gitConfig.url);
|
|
18683
|
+
const cachePath = cacheManager.getCachePath(normalizedUrl, ref);
|
|
18684
|
+
const isValid = await cacheManager.isValid(normalizedUrl, ref);
|
|
18685
|
+
if (isValid) {
|
|
18686
|
+
const subPath2 = gitConfig.path ?? "";
|
|
18687
|
+
return {
|
|
18688
|
+
path: subPath2 ? join7(cachePath, subPath2) : cachePath,
|
|
18689
|
+
isRemote: true,
|
|
18690
|
+
source: "git"
|
|
18691
|
+
};
|
|
18692
|
+
}
|
|
18693
|
+
const registry = createGitRegistry({
|
|
18694
|
+
url: gitConfig.url,
|
|
18695
|
+
ref,
|
|
18696
|
+
path: gitConfig.path,
|
|
18697
|
+
auth: gitConfig.auth,
|
|
18698
|
+
cache: {
|
|
18699
|
+
enabled: config.registry.cache?.enabled ?? true,
|
|
18700
|
+
ttl: config.registry.cache?.ttl
|
|
18701
|
+
}
|
|
18702
|
+
});
|
|
18703
|
+
try {
|
|
18704
|
+
await registry.fetch("registry-manifest.yaml");
|
|
18705
|
+
} catch (error) {
|
|
18706
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
18707
|
+
if (!message.includes("not found") && !message.includes("FileNotFoundError")) {
|
|
18708
|
+
throw new Error(
|
|
18709
|
+
`Failed to clone registry from ${gitConfig.url}: ${message}. Please check your network connection and registry configuration.`
|
|
18710
|
+
);
|
|
18711
|
+
}
|
|
18712
|
+
}
|
|
18713
|
+
const subPath = gitConfig.path ?? "";
|
|
18714
|
+
return {
|
|
18715
|
+
path: subPath ? join7(cachePath, subPath) : cachePath,
|
|
18716
|
+
isRemote: true,
|
|
18717
|
+
source: "git"
|
|
18718
|
+
};
|
|
18719
|
+
}
|
|
18720
|
+
if (config.registry?.url) {
|
|
18721
|
+
const localPath = config.registry?.path ?? "./registry";
|
|
18722
|
+
return {
|
|
18723
|
+
path: localPath,
|
|
18724
|
+
isRemote: true,
|
|
18725
|
+
source: "http"
|
|
18726
|
+
};
|
|
18727
|
+
}
|
|
18728
|
+
const registryPath = config.registry?.path ?? "./registry";
|
|
18729
|
+
return {
|
|
18730
|
+
path: registryPath,
|
|
18731
|
+
isRemote: false,
|
|
18732
|
+
source: "local"
|
|
18733
|
+
};
|
|
18734
|
+
}
|
|
18735
|
+
|
|
18110
18736
|
// packages/cli/src/commands/compile.ts
|
|
18111
18737
|
var PROMPTSCRIPT_MARKERS = [
|
|
18112
18738
|
"<!-- PromptScript",
|
|
@@ -18207,7 +18833,7 @@ async function writeOutputs(outputs, options, _config, services) {
|
|
|
18207
18833
|
continue;
|
|
18208
18834
|
}
|
|
18209
18835
|
if (!fileExists2) {
|
|
18210
|
-
await mkdir2(
|
|
18836
|
+
await mkdir2(dirname6(outputPath), { recursive: true });
|
|
18211
18837
|
await writeFile2(outputPath, output.content, "utf-8");
|
|
18212
18838
|
ConsoleOutput.success(outputPath);
|
|
18213
18839
|
result.written.push(outputPath);
|
|
@@ -18223,14 +18849,14 @@ async function writeOutputs(outputs, options, _config, services) {
|
|
|
18223
18849
|
result.unchanged.push(outputPath);
|
|
18224
18850
|
continue;
|
|
18225
18851
|
}
|
|
18226
|
-
await mkdir2(
|
|
18852
|
+
await mkdir2(dirname6(outputPath), { recursive: true });
|
|
18227
18853
|
await writeFile2(outputPath, output.content, "utf-8");
|
|
18228
18854
|
ConsoleOutput.success(outputPath);
|
|
18229
18855
|
result.written.push(outputPath);
|
|
18230
18856
|
continue;
|
|
18231
18857
|
}
|
|
18232
18858
|
if (options.force || overwriteAll) {
|
|
18233
|
-
await mkdir2(
|
|
18859
|
+
await mkdir2(dirname6(outputPath), { recursive: true });
|
|
18234
18860
|
await writeFile2(outputPath, output.content, "utf-8");
|
|
18235
18861
|
ConsoleOutput.success(outputPath);
|
|
18236
18862
|
result.written.push(outputPath);
|
|
@@ -18243,7 +18869,7 @@ async function writeOutputs(outputs, options, _config, services) {
|
|
|
18243
18869
|
const response = await promptForOverwrite(outputPath, services);
|
|
18244
18870
|
switch (response) {
|
|
18245
18871
|
case "yes":
|
|
18246
|
-
await mkdir2(
|
|
18872
|
+
await mkdir2(dirname6(outputPath), { recursive: true });
|
|
18247
18873
|
await writeFile2(outputPath, output.content, "utf-8");
|
|
18248
18874
|
ConsoleOutput.success(outputPath);
|
|
18249
18875
|
result.written.push(outputPath);
|
|
@@ -18254,7 +18880,7 @@ async function writeOutputs(outputs, options, _config, services) {
|
|
|
18254
18880
|
break;
|
|
18255
18881
|
case "all":
|
|
18256
18882
|
overwriteAll = true;
|
|
18257
|
-
await mkdir2(
|
|
18883
|
+
await mkdir2(dirname6(outputPath), { recursive: true });
|
|
18258
18884
|
await writeFile2(outputPath, output.content, "utf-8");
|
|
18259
18885
|
ConsoleOutput.success(outputPath);
|
|
18260
18886
|
result.written.push(outputPath);
|
|
@@ -18293,10 +18919,20 @@ async function compileCommand(options, services = createDefaultServices()) {
|
|
|
18293
18919
|
try {
|
|
18294
18920
|
logger.verbose("Loading configuration...");
|
|
18295
18921
|
const config = await loadConfig(options.config);
|
|
18296
|
-
spinner.text = "Compiling...";
|
|
18297
18922
|
const selectedTarget = options.target ?? options.format;
|
|
18298
18923
|
const targets = selectedTarget ? [{ name: selectedTarget }] : parseTargets(config.targets);
|
|
18299
|
-
|
|
18924
|
+
let registryPath;
|
|
18925
|
+
if (options.registry) {
|
|
18926
|
+
registryPath = options.registry;
|
|
18927
|
+
} else {
|
|
18928
|
+
spinner.text = "Resolving registry...";
|
|
18929
|
+
const registry = await resolveRegistryPath(config);
|
|
18930
|
+
registryPath = registry.path;
|
|
18931
|
+
if (registry.isRemote) {
|
|
18932
|
+
logger.verbose(`Using cached git registry: ${registryPath}`);
|
|
18933
|
+
}
|
|
18934
|
+
}
|
|
18935
|
+
spinner.text = "Compiling...";
|
|
18300
18936
|
logger.verbose(`Registry: ${registryPath}`);
|
|
18301
18937
|
logger.debug(`Config: ${JSON.stringify(config, null, 2)}`);
|
|
18302
18938
|
const prettierOptions = await resolvePrettierOptions(config, process.cwd());
|
|
@@ -18472,10 +19108,12 @@ async function validateCommand(options) {
|
|
|
18472
19108
|
const spinner = isJsonFormat ? createSpinner("").stop() : createSpinner("Loading configuration...").start();
|
|
18473
19109
|
try {
|
|
18474
19110
|
const config = await loadConfig();
|
|
19111
|
+
if (!isJsonFormat) spinner.text = "Resolving registry...";
|
|
19112
|
+
const registry = await resolveRegistryPath(config);
|
|
18475
19113
|
if (!isJsonFormat) spinner.text = "Validating...";
|
|
18476
19114
|
const compiler = new Compiler({
|
|
18477
19115
|
resolver: {
|
|
18478
|
-
registryPath:
|
|
19116
|
+
registryPath: registry.path,
|
|
18479
19117
|
localPath: "./.promptscript"
|
|
18480
19118
|
},
|
|
18481
19119
|
validator: config.validation,
|
|
@@ -18524,7 +19162,7 @@ function outputJsonResult(result) {
|
|
|
18524
19162
|
// packages/cli/src/commands/pull.ts
|
|
18525
19163
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
18526
19164
|
import { existsSync as existsSync9 } from "fs";
|
|
18527
|
-
import { resolve as resolve6, dirname as
|
|
19165
|
+
import { resolve as resolve6, dirname as dirname7 } from "path";
|
|
18528
19166
|
async function pullCommand(options) {
|
|
18529
19167
|
const spinner = createSpinner("Loading configuration...").start();
|
|
18530
19168
|
try {
|
|
@@ -18563,7 +19201,7 @@ async function pullCommand(options) {
|
|
|
18563
19201
|
}
|
|
18564
19202
|
return;
|
|
18565
19203
|
}
|
|
18566
|
-
await mkdir3(
|
|
19204
|
+
await mkdir3(dirname7(destPath), { recursive: true });
|
|
18567
19205
|
await writeFile3(destPath, content, "utf-8");
|
|
18568
19206
|
spinner.succeed("Pulled from registry");
|
|
18569
19207
|
ConsoleOutput.success(destPath);
|
|
@@ -18719,11 +19357,13 @@ async function diffCommand(options) {
|
|
|
18719
19357
|
const spinner = createSpinner("Loading configuration...").start();
|
|
18720
19358
|
try {
|
|
18721
19359
|
const config = await loadConfig();
|
|
19360
|
+
spinner.text = "Resolving registry...";
|
|
19361
|
+
const registry = await resolveRegistryPath(config);
|
|
18722
19362
|
spinner.text = "Compiling...";
|
|
18723
19363
|
const targets = options.target ? [{ name: options.target }] : parseTargets2(config.targets);
|
|
18724
19364
|
const compiler = new Compiler({
|
|
18725
19365
|
resolver: {
|
|
18726
|
-
registryPath:
|
|
19366
|
+
registryPath: registry.path,
|
|
18727
19367
|
localPath: "./.promptscript"
|
|
18728
19368
|
},
|
|
18729
19369
|
validator: config.validation,
|
|
@@ -18957,11 +19597,189 @@ function printResults(results) {
|
|
|
18957
19597
|
}
|
|
18958
19598
|
}
|
|
18959
19599
|
|
|
18960
|
-
// packages/cli/src/
|
|
19600
|
+
// packages/cli/src/commands/update-check.ts
|
|
19601
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
19602
|
+
import { dirname as dirname8 } from "path";
|
|
19603
|
+
|
|
19604
|
+
// packages/cli/src/utils/version-check.ts
|
|
19605
|
+
import { homedir as homedir2 } from "os";
|
|
19606
|
+
import { join as join8 } from "path";
|
|
19607
|
+
import { existsSync as existsSync12, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
19608
|
+
var NPM_REGISTRY_URL = "https://registry.npmjs.org/@promptscript/cli/latest";
|
|
19609
|
+
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
19610
|
+
var FETCH_TIMEOUT_MS = 3e3;
|
|
19611
|
+
function getCacheDir() {
|
|
19612
|
+
return join8(homedir2(), ".promptscript", ".cache");
|
|
19613
|
+
}
|
|
19614
|
+
function getCachePath() {
|
|
19615
|
+
return join8(getCacheDir(), "version.json");
|
|
19616
|
+
}
|
|
19617
|
+
function readCache() {
|
|
19618
|
+
try {
|
|
19619
|
+
const cachePath = getCachePath();
|
|
19620
|
+
if (!existsSync12(cachePath)) {
|
|
19621
|
+
return null;
|
|
19622
|
+
}
|
|
19623
|
+
const content = readFileSync3(cachePath, "utf-8");
|
|
19624
|
+
return JSON.parse(content);
|
|
19625
|
+
} catch {
|
|
19626
|
+
return null;
|
|
19627
|
+
}
|
|
19628
|
+
}
|
|
19629
|
+
function writeCache(cache) {
|
|
19630
|
+
try {
|
|
19631
|
+
const cacheDir = getCacheDir();
|
|
19632
|
+
if (!existsSync12(cacheDir)) {
|
|
19633
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
19634
|
+
}
|
|
19635
|
+
const cachePath = getCachePath();
|
|
19636
|
+
writeFileSync(cachePath, JSON.stringify(cache, null, 2), "utf-8");
|
|
19637
|
+
} catch {
|
|
19638
|
+
}
|
|
19639
|
+
}
|
|
19640
|
+
function isCacheValid(cache) {
|
|
19641
|
+
try {
|
|
19642
|
+
const lastCheck = new Date(cache.lastCheck).getTime();
|
|
19643
|
+
const now = Date.now();
|
|
19644
|
+
return now - lastCheck < CACHE_TTL_MS;
|
|
19645
|
+
} catch {
|
|
19646
|
+
return false;
|
|
19647
|
+
}
|
|
19648
|
+
}
|
|
19649
|
+
async function fetchLatestVersion() {
|
|
19650
|
+
try {
|
|
19651
|
+
const controller = new AbortController();
|
|
19652
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
19653
|
+
const response = await fetch(NPM_REGISTRY_URL, {
|
|
19654
|
+
signal: controller.signal,
|
|
19655
|
+
headers: {
|
|
19656
|
+
Accept: "application/json"
|
|
19657
|
+
}
|
|
19658
|
+
});
|
|
19659
|
+
clearTimeout(timeout);
|
|
19660
|
+
if (!response.ok) {
|
|
19661
|
+
if (isVerbose()) {
|
|
19662
|
+
ConsoleOutput.verbose(`Could not check for updates: HTTP ${response.status}`);
|
|
19663
|
+
}
|
|
19664
|
+
return null;
|
|
19665
|
+
}
|
|
19666
|
+
const data = await response.json();
|
|
19667
|
+
return data.version ?? null;
|
|
19668
|
+
} catch (error) {
|
|
19669
|
+
if (isVerbose()) {
|
|
19670
|
+
const code = error.code;
|
|
19671
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
19672
|
+
ConsoleOutput.verbose(`Could not check for updates: ${code ?? message}`);
|
|
19673
|
+
}
|
|
19674
|
+
return null;
|
|
19675
|
+
}
|
|
19676
|
+
}
|
|
19677
|
+
function isNewerVersion(currentVersion, latestVersion) {
|
|
19678
|
+
const cleanCurrent = currentVersion.replace(/^v/, "");
|
|
19679
|
+
const cleanLatest = latestVersion.replace(/^v/, "");
|
|
19680
|
+
const [currentBase, currentPrerelease] = cleanCurrent.split("-");
|
|
19681
|
+
const [latestBase, latestPrerelease] = cleanLatest.split("-");
|
|
19682
|
+
const currentParts = (currentBase ?? "").split(".").map((p) => parseInt(p, 10) || 0);
|
|
19683
|
+
const latestParts = (latestBase ?? "").split(".").map((p) => parseInt(p, 10) || 0);
|
|
19684
|
+
for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
|
|
19685
|
+
const c = currentParts[i] ?? 0;
|
|
19686
|
+
const l = latestParts[i] ?? 0;
|
|
19687
|
+
if (l > c) return true;
|
|
19688
|
+
if (l < c) return false;
|
|
19689
|
+
}
|
|
19690
|
+
if (currentPrerelease && !latestPrerelease) {
|
|
19691
|
+
return true;
|
|
19692
|
+
}
|
|
19693
|
+
return false;
|
|
19694
|
+
}
|
|
19695
|
+
async function checkForUpdates(currentVersion) {
|
|
19696
|
+
if (process.env["PROMPTSCRIPT_NO_UPDATE_CHECK"]) {
|
|
19697
|
+
return null;
|
|
19698
|
+
}
|
|
19699
|
+
if (isQuiet()) {
|
|
19700
|
+
return null;
|
|
19701
|
+
}
|
|
19702
|
+
const cache = readCache();
|
|
19703
|
+
if (cache && isCacheValid(cache) && cache.currentVersion === currentVersion) {
|
|
19704
|
+
if (isNewerVersion(currentVersion, cache.latestVersion)) {
|
|
19705
|
+
return {
|
|
19706
|
+
currentVersion,
|
|
19707
|
+
latestVersion: cache.latestVersion,
|
|
19708
|
+
updateAvailable: true
|
|
19709
|
+
};
|
|
19710
|
+
}
|
|
19711
|
+
return null;
|
|
19712
|
+
}
|
|
19713
|
+
const latestVersion = await fetchLatestVersion();
|
|
19714
|
+
if (!latestVersion) {
|
|
19715
|
+
return null;
|
|
19716
|
+
}
|
|
19717
|
+
writeCache({
|
|
19718
|
+
lastCheck: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19719
|
+
latestVersion,
|
|
19720
|
+
currentVersion
|
|
19721
|
+
});
|
|
19722
|
+
if (isNewerVersion(currentVersion, latestVersion)) {
|
|
19723
|
+
return {
|
|
19724
|
+
currentVersion,
|
|
19725
|
+
latestVersion,
|
|
19726
|
+
updateAvailable: true
|
|
19727
|
+
};
|
|
19728
|
+
}
|
|
19729
|
+
return null;
|
|
19730
|
+
}
|
|
19731
|
+
async function forceCheckForUpdates(currentVersion) {
|
|
19732
|
+
const latestVersion = await fetchLatestVersion();
|
|
19733
|
+
if (!latestVersion) {
|
|
19734
|
+
return { info: null, error: true };
|
|
19735
|
+
}
|
|
19736
|
+
writeCache({
|
|
19737
|
+
lastCheck: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19738
|
+
latestVersion,
|
|
19739
|
+
currentVersion
|
|
19740
|
+
});
|
|
19741
|
+
const updateAvailable = isNewerVersion(currentVersion, latestVersion);
|
|
19742
|
+
return {
|
|
19743
|
+
info: {
|
|
19744
|
+
currentVersion,
|
|
19745
|
+
latestVersion,
|
|
19746
|
+
updateAvailable
|
|
19747
|
+
},
|
|
19748
|
+
error: false
|
|
19749
|
+
};
|
|
19750
|
+
}
|
|
19751
|
+
function printUpdateNotification(info) {
|
|
19752
|
+
console.log(
|
|
19753
|
+
`Update available: ${info.currentVersion} \u2192 ${info.latestVersion} (npm i -g @promptscript/cli)`
|
|
19754
|
+
);
|
|
19755
|
+
}
|
|
19756
|
+
|
|
19757
|
+
// packages/cli/src/commands/update-check.ts
|
|
18961
19758
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
18962
|
-
var __dirname2 =
|
|
19759
|
+
var __dirname2 = dirname8(__filename2);
|
|
19760
|
+
async function updateCheckCommand() {
|
|
19761
|
+
const currentVersion = getPackageVersion(__dirname2, "../../package.json");
|
|
19762
|
+
console.log(`@promptscript/cli v${currentVersion}`);
|
|
19763
|
+
const { info, error } = await forceCheckForUpdates(currentVersion);
|
|
19764
|
+
if (error) {
|
|
19765
|
+
ConsoleOutput.error("Could not check for updates");
|
|
19766
|
+
process.exitCode = 1;
|
|
19767
|
+
return;
|
|
19768
|
+
}
|
|
19769
|
+
if (info?.updateAvailable) {
|
|
19770
|
+
console.log(
|
|
19771
|
+
`Update available: ${info.currentVersion} \u2192 ${info.latestVersion} (npm i -g @promptscript/cli)`
|
|
19772
|
+
);
|
|
19773
|
+
} else {
|
|
19774
|
+
ConsoleOutput.success("Up to date");
|
|
19775
|
+
}
|
|
19776
|
+
}
|
|
19777
|
+
|
|
19778
|
+
// packages/cli/src/cli.ts
|
|
19779
|
+
var __filename3 = fileURLToPath3(import.meta.url);
|
|
19780
|
+
var __dirname3 = dirname9(__filename3);
|
|
18963
19781
|
var program = new Command();
|
|
18964
|
-
program.name("prs").description("PromptScript CLI - Standardize AI instructions").version(getPackageVersion(
|
|
19782
|
+
program.name("prs").description("PromptScript CLI - Standardize AI instructions").version(getPackageVersion(__dirname3, "../package.json")).option("--verbose", "Enable verbose output").option("--debug", "Enable debug output (includes verbose)").option("--quiet", "Suppress non-error output").hook("preAction", async (thisCommand, actionCommand) => {
|
|
18965
19783
|
const opts = thisCommand.opts();
|
|
18966
19784
|
if (opts["quiet"]) {
|
|
18967
19785
|
setContext({ logLevel: 0 /* Quiet */ });
|
|
@@ -18975,13 +19793,22 @@ program.name("prs").description("PromptScript CLI - Standardize AI instructions"
|
|
|
18975
19793
|
} else if (process.env["PROMPTSCRIPT_VERBOSE"] === "1" || process.env["PROMPTSCRIPT_VERBOSE"] === "true") {
|
|
18976
19794
|
setContext({ logLevel: 2 /* Verbose */ });
|
|
18977
19795
|
}
|
|
19796
|
+
if (actionCommand.name() === "update-check") {
|
|
19797
|
+
return;
|
|
19798
|
+
}
|
|
19799
|
+
const currentVersion = getPackageVersion(__dirname3, "../package.json");
|
|
19800
|
+
const updateInfo = await checkForUpdates(currentVersion);
|
|
19801
|
+
if (updateInfo) {
|
|
19802
|
+
printUpdateNotification(updateInfo);
|
|
19803
|
+
}
|
|
18978
19804
|
});
|
|
18979
19805
|
program.command("init").description("Initialize PromptScript in current directory").option("-n, --name <name>", "Project name (auto-detected from package.json, etc.)").option("-t, --team <team>", "Team namespace").option("--inherit <path>", "Inheritance path (e.g., @company/team)").option("--registry <path>", "Registry path").option("--targets <targets...>", "Target AI tools (github, claude, cursor)").option("-i, --interactive", "Force interactive mode").option("-y, --yes", "Skip prompts, use defaults").option("-f, --force", "Force reinitialize even if already initialized").option("-m, --migrate", "Install migration skill for AI-assisted migration").action((opts) => initCommand(opts));
|
|
18980
19806
|
program.command("compile").description("Compile PromptScript to target formats").option("-t, --target <target>", "Specific target (github, claude, cursor)").option("-f, --format <format>", "Output format (alias for --target)").option("-a, --all", "All configured targets", true).option("-w, --watch", "Watch mode").option("-o, --output <dir>", "Output directory").option("--dry-run", "Preview changes").option("--registry <path>", "Registry path (overrides config)").option("-c, --config <path>", "Path to custom config file").option("--force", "Force overwrite existing files without prompts").action((opts) => compileCommand(opts));
|
|
18981
19807
|
program.command("validate").description("Validate PromptScript files").option("--strict", "Treat warnings as errors").option("--format <format>", "Output format (text, json)", "text").action(validateCommand);
|
|
18982
19808
|
program.command("pull").description("Pull updates from registry").option("-f, --force", "Force overwrite").option("--dry-run", "Preview changes without pulling").option("-b, --branch <name>", "Git branch to pull from").option("--tag <name>", "Git tag to pull from").option("--commit <hash>", "Git commit to pull from").option("--refresh", "Force re-fetch from remote (ignore cache)").action(pullCommand);
|
|
18983
19809
|
program.command("diff").description("Show diff for compiled output").option("-t, --target <target>", "Specific target").option("-a, --all", "Show diff for all targets at once").option("--full", "Show full diff without truncation").option("--no-pager", "Disable pager output").option("--color", "Force colored output").option("--no-color", "Disable colored output").action(diffCommand);
|
|
18984
|
-
program.command("check").description("Check configuration and dependencies health").
|
|
19810
|
+
program.command("check").description("Check configuration and dependencies health").action(checkCommand);
|
|
19811
|
+
program.command("update-check").description("Check for CLI updates").action(updateCheckCommand);
|
|
18985
19812
|
function run(args = process.argv) {
|
|
18986
19813
|
program.parse(args);
|
|
18987
19814
|
}
|
|
@@ -18991,18 +19818,25 @@ export {
|
|
|
18991
19818
|
ConsoleOutput,
|
|
18992
19819
|
LogLevel,
|
|
18993
19820
|
checkCommand,
|
|
19821
|
+
checkForUpdates,
|
|
18994
19822
|
compileCommand,
|
|
18995
19823
|
createSpinner,
|
|
18996
19824
|
diffCommand,
|
|
19825
|
+
fetchLatestVersion,
|
|
18997
19826
|
findConfigFile,
|
|
19827
|
+
forceCheckForUpdates,
|
|
19828
|
+
getCacheDir,
|
|
19829
|
+
getCachePath,
|
|
18998
19830
|
getContext,
|
|
18999
19831
|
initCommand,
|
|
19000
19832
|
isQuiet,
|
|
19001
19833
|
isVerbose,
|
|
19002
19834
|
loadConfig,
|
|
19835
|
+
printUpdateNotification,
|
|
19003
19836
|
pullCommand,
|
|
19004
19837
|
run,
|
|
19005
19838
|
setContext,
|
|
19839
|
+
updateCheckCommand,
|
|
19006
19840
|
validateCommand
|
|
19007
19841
|
};
|
|
19008
19842
|
/*! Bundled license information:
|