@kitnai/cli 0.1.19 → 0.1.21
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/index.js +129 -522
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -96,6 +96,10 @@ import { z } from "zod";
|
|
|
96
96
|
function getRegistryUrl(entry) {
|
|
97
97
|
return typeof entry === "string" ? entry : entry.url;
|
|
98
98
|
}
|
|
99
|
+
function resolveRoutesAlias(config) {
|
|
100
|
+
const fw = config.framework ?? "hono";
|
|
101
|
+
return FRAMEWORK_TO_ADAPTER[fw] ?? `${fw}-adapter`;
|
|
102
|
+
}
|
|
99
103
|
async function readConfig(projectDir) {
|
|
100
104
|
try {
|
|
101
105
|
const raw = await readFile2(join2(projectDir, CONFIG_FILE), "utf-8");
|
|
@@ -117,7 +121,7 @@ function getInstallPath(config, type, fileName, namespace) {
|
|
|
117
121
|
}
|
|
118
122
|
return join2(base, fileName);
|
|
119
123
|
}
|
|
120
|
-
var componentType, installedComponentSchema, registryEntrySchema, registryValueSchema, configSchema, CONFIG_FILE, typeToAliasKey;
|
|
124
|
+
var componentType, installedComponentSchema, registryEntrySchema, registryValueSchema, configSchema, FRAMEWORK_TO_ADAPTER, CONFIG_FILE, typeToAliasKey;
|
|
121
125
|
var init_config = __esm({
|
|
122
126
|
"src/utils/config.ts"() {
|
|
123
127
|
"use strict";
|
|
@@ -149,6 +153,10 @@ var init_config = __esm({
|
|
|
149
153
|
registries: z.record(z.string(), registryValueSchema),
|
|
150
154
|
installed: z.record(z.string(), installedComponentSchema).optional()
|
|
151
155
|
});
|
|
156
|
+
FRAMEWORK_TO_ADAPTER = {
|
|
157
|
+
hono: "hono-adapter",
|
|
158
|
+
elysia: "elysia-adapter"
|
|
159
|
+
};
|
|
152
160
|
CONFIG_FILE = "kitn.json";
|
|
153
161
|
typeToAliasKey = {
|
|
154
162
|
"kitn:agent": "agents",
|
|
@@ -330,7 +338,7 @@ async function resolveDependencies(names, fetchItem) {
|
|
|
330
338
|
const visited = /* @__PURE__ */ new Set();
|
|
331
339
|
const items = /* @__PURE__ */ new Map();
|
|
332
340
|
const edges = [];
|
|
333
|
-
async function
|
|
341
|
+
async function resolve(name) {
|
|
334
342
|
if (visited.has(name)) return;
|
|
335
343
|
visited.add(name);
|
|
336
344
|
const item = await fetchItem(name);
|
|
@@ -338,11 +346,11 @@ async function resolveDependencies(names, fetchItem) {
|
|
|
338
346
|
const deps = item.registryDependencies ?? [];
|
|
339
347
|
for (const dep of deps) {
|
|
340
348
|
edges.push([dep, name]);
|
|
341
|
-
await
|
|
349
|
+
await resolve(dep);
|
|
342
350
|
}
|
|
343
351
|
}
|
|
344
352
|
for (const name of names) {
|
|
345
|
-
await
|
|
353
|
+
await resolve(name);
|
|
346
354
|
}
|
|
347
355
|
return topologicalSort(items, edges);
|
|
348
356
|
}
|
|
@@ -814,8 +822,7 @@ async function addCommand(components, opts) {
|
|
|
814
822
|
}
|
|
815
823
|
const resolvedComponents = components.map((c) => {
|
|
816
824
|
if (c === "routes") {
|
|
817
|
-
|
|
818
|
-
return fw2;
|
|
825
|
+
return resolveRoutesAlias(config);
|
|
819
826
|
}
|
|
820
827
|
return c;
|
|
821
828
|
});
|
|
@@ -1131,18 +1138,10 @@ async function addCommand(components, opts) {
|
|
|
1131
1138
|
const resolvedNames = new Set(resolved.map((r) => r.name));
|
|
1132
1139
|
const projectInstalled = new Set(Object.keys(config.installed ?? {}));
|
|
1133
1140
|
const hints = [];
|
|
1134
|
-
const
|
|
1135
|
-
if (resolvedNames.has("core") && !resolvedNames.has(
|
|
1141
|
+
const adapterName = resolveRoutesAlias(config);
|
|
1142
|
+
if (resolvedNames.has("core") && !resolvedNames.has(adapterName) && !projectInstalled.has(adapterName)) {
|
|
1136
1143
|
hints.push(`Run ${pc3.cyan(`kitn add routes`)} to install the HTTP adapter.`);
|
|
1137
1144
|
}
|
|
1138
|
-
if (resolvedNames.has(fw)) {
|
|
1139
|
-
hints.push(`Configure your AI provider in ${pc3.bold(baseDir + "/plugin.ts")}, then add to your server:`);
|
|
1140
|
-
hints.push("");
|
|
1141
|
-
hints.push(pc3.dim(` import { ai } from "./${baseDir.replace(/^src\//, "")}/plugin";`));
|
|
1142
|
-
hints.push(pc3.dim(``));
|
|
1143
|
-
hints.push(pc3.dim(` app.route("/api", ai.router);`));
|
|
1144
|
-
hints.push("");
|
|
1145
|
-
}
|
|
1146
1145
|
if (hints.length > 0) {
|
|
1147
1146
|
p2.log.message(pc3.bold("\nNext steps:") + "\n" + hints.join("\n"));
|
|
1148
1147
|
}
|
|
@@ -1462,7 +1461,7 @@ async function diffCommand(componentName) {
|
|
|
1462
1461
|
p5.log.error("No kitn.json found. Run `kitn init` first.");
|
|
1463
1462
|
process.exit(1);
|
|
1464
1463
|
}
|
|
1465
|
-
const input = componentName === "routes" ? config
|
|
1464
|
+
const input = componentName === "routes" ? resolveRoutesAlias(config) : componentName;
|
|
1466
1465
|
const ref = parseComponentRef(input);
|
|
1467
1466
|
const installedKey = ref.namespace === "@kitn" ? ref.name : `${ref.namespace}/${ref.name}`;
|
|
1468
1467
|
const installed = config.installed?.[installedKey];
|
|
@@ -1553,7 +1552,7 @@ async function removeCommand(componentName) {
|
|
|
1553
1552
|
p6.log.error("No kitn.json found. Run `kitn init` first.");
|
|
1554
1553
|
process.exit(1);
|
|
1555
1554
|
}
|
|
1556
|
-
const input = componentName === "routes" ? config
|
|
1555
|
+
const input = componentName === "routes" ? resolveRoutesAlias(config) : componentName;
|
|
1557
1556
|
const ref = parseComponentRef(input);
|
|
1558
1557
|
const installedKey = ref.namespace === "@kitn" ? ref.name : `${ref.namespace}/${ref.name}`;
|
|
1559
1558
|
const installed = config.installed?.[installedKey];
|
|
@@ -1654,433 +1653,23 @@ var init_update = __esm({
|
|
|
1654
1653
|
}
|
|
1655
1654
|
});
|
|
1656
1655
|
|
|
1657
|
-
// src/registry/build-output.ts
|
|
1658
|
-
import { readdir, writeFile as writeFile9, mkdir as mkdir5, access as access4 } from "fs/promises";
|
|
1659
|
-
import { join as join11, resolve } from "path";
|
|
1660
|
-
async function fileExists(path) {
|
|
1661
|
-
try {
|
|
1662
|
-
await access4(path);
|
|
1663
|
-
return true;
|
|
1664
|
-
} catch {
|
|
1665
|
-
return false;
|
|
1666
|
-
}
|
|
1667
|
-
}
|
|
1668
|
-
async function walkForRegistryJson(dir) {
|
|
1669
|
-
const results = [];
|
|
1670
|
-
let entries;
|
|
1671
|
-
try {
|
|
1672
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
1673
|
-
} catch {
|
|
1674
|
-
return results;
|
|
1675
|
-
}
|
|
1676
|
-
if (await fileExists(join11(dir, "registry.json"))) {
|
|
1677
|
-
results.push(dir);
|
|
1678
|
-
return results;
|
|
1679
|
-
}
|
|
1680
|
-
for (const entry of entries) {
|
|
1681
|
-
if (entry.isDirectory() && !SKIP_DIRS.has(entry.name)) {
|
|
1682
|
-
const subResults = await walkForRegistryJson(join11(dir, entry.name));
|
|
1683
|
-
results.push(...subResults);
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
return results;
|
|
1687
|
-
}
|
|
1688
|
-
async function scanForComponents(cwd, paths) {
|
|
1689
|
-
const resolvedCwd = resolve(cwd);
|
|
1690
|
-
if (paths && paths.length > 0) {
|
|
1691
|
-
const results = [];
|
|
1692
|
-
for (const p13 of paths) {
|
|
1693
|
-
const absPath = resolve(resolvedCwd, p13);
|
|
1694
|
-
if (await fileExists(join11(absPath, "registry.json"))) {
|
|
1695
|
-
results.push(absPath);
|
|
1696
|
-
continue;
|
|
1697
|
-
}
|
|
1698
|
-
let entries;
|
|
1699
|
-
try {
|
|
1700
|
-
entries = await readdir(absPath, { withFileTypes: true });
|
|
1701
|
-
} catch {
|
|
1702
|
-
continue;
|
|
1703
|
-
}
|
|
1704
|
-
for (const entry of entries) {
|
|
1705
|
-
if (entry.isDirectory()) {
|
|
1706
|
-
const subDir = join11(absPath, entry.name);
|
|
1707
|
-
if (await fileExists(join11(subDir, "registry.json"))) {
|
|
1708
|
-
results.push(subDir);
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
return results;
|
|
1714
|
-
}
|
|
1715
|
-
return walkForRegistryJson(resolvedCwd);
|
|
1716
|
-
}
|
|
1717
|
-
function parseVersionFromFilename(name, componentName) {
|
|
1718
|
-
const prefix = `${componentName}@`;
|
|
1719
|
-
const suffix = ".json";
|
|
1720
|
-
if (name.startsWith(prefix) && name.endsWith(suffix)) {
|
|
1721
|
-
return name.slice(prefix.length, -suffix.length);
|
|
1722
|
-
}
|
|
1723
|
-
return null;
|
|
1724
|
-
}
|
|
1725
|
-
async function writeRegistryOutput(outputDir, items) {
|
|
1726
|
-
const written = [];
|
|
1727
|
-
const skipped = [];
|
|
1728
|
-
const resolvedOutput = resolve(outputDir);
|
|
1729
|
-
const indexItems = [];
|
|
1730
|
-
for (const item of items) {
|
|
1731
|
-
const dir = typeToDir[item.type];
|
|
1732
|
-
const typeDir = join11(resolvedOutput, dir);
|
|
1733
|
-
await mkdir5(typeDir, { recursive: true });
|
|
1734
|
-
const itemJson = JSON.stringify(item, null, 2);
|
|
1735
|
-
const latestPath = join11(typeDir, `${item.name}.json`);
|
|
1736
|
-
const latestRelative = `${dir}/${item.name}.json`;
|
|
1737
|
-
await writeFile9(latestPath, itemJson, "utf-8");
|
|
1738
|
-
written.push(latestRelative);
|
|
1739
|
-
if (item.version) {
|
|
1740
|
-
const versionedFilename = `${item.name}@${item.version}.json`;
|
|
1741
|
-
const versionedPath = join11(typeDir, versionedFilename);
|
|
1742
|
-
const versionedRelative = `${dir}/${versionedFilename}`;
|
|
1743
|
-
if (await fileExists(versionedPath)) {
|
|
1744
|
-
skipped.push(versionedRelative);
|
|
1745
|
-
} else {
|
|
1746
|
-
await writeFile9(versionedPath, itemJson, "utf-8");
|
|
1747
|
-
written.push(versionedRelative);
|
|
1748
|
-
}
|
|
1749
|
-
}
|
|
1750
|
-
const versions = [];
|
|
1751
|
-
let entries;
|
|
1752
|
-
try {
|
|
1753
|
-
entries = await readdir(typeDir);
|
|
1754
|
-
} catch {
|
|
1755
|
-
entries = [];
|
|
1756
|
-
}
|
|
1757
|
-
for (const filename of entries) {
|
|
1758
|
-
const ver = parseVersionFromFilename(filename, item.name);
|
|
1759
|
-
if (ver) {
|
|
1760
|
-
versions.push(ver);
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
versions.sort();
|
|
1764
|
-
indexItems.push({
|
|
1765
|
-
name: item.name,
|
|
1766
|
-
type: item.type,
|
|
1767
|
-
description: item.description,
|
|
1768
|
-
...item.registryDependencies && item.registryDependencies.length > 0 && {
|
|
1769
|
-
registryDependencies: item.registryDependencies
|
|
1770
|
-
},
|
|
1771
|
-
...item.categories && item.categories.length > 0 && { categories: item.categories },
|
|
1772
|
-
...item.version && { version: item.version },
|
|
1773
|
-
...versions.length > 0 && { versions },
|
|
1774
|
-
...item.updatedAt && { updatedAt: item.updatedAt }
|
|
1775
|
-
});
|
|
1776
|
-
}
|
|
1777
|
-
const index = {
|
|
1778
|
-
version: "1",
|
|
1779
|
-
items: indexItems
|
|
1780
|
-
};
|
|
1781
|
-
const indexPath = join11(resolvedOutput, "registry.json");
|
|
1782
|
-
await writeFile9(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
1783
|
-
written.push("registry.json");
|
|
1784
|
-
return { written, skipped };
|
|
1785
|
-
}
|
|
1786
|
-
var SKIP_DIRS;
|
|
1787
|
-
var init_build_output = __esm({
|
|
1788
|
-
"src/registry/build-output.ts"() {
|
|
1789
|
-
"use strict";
|
|
1790
|
-
init_schema();
|
|
1791
|
-
SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
1792
|
-
"node_modules",
|
|
1793
|
-
"dist",
|
|
1794
|
-
".git",
|
|
1795
|
-
"r",
|
|
1796
|
-
"test",
|
|
1797
|
-
"tests",
|
|
1798
|
-
".claude"
|
|
1799
|
-
]);
|
|
1800
|
-
}
|
|
1801
|
-
});
|
|
1802
|
-
|
|
1803
|
-
// src/registry/builder.ts
|
|
1804
|
-
import { readFile as readFile9, readdir as readdir2 } from "fs/promises";
|
|
1805
|
-
import { join as join12, relative as relative5 } from "path";
|
|
1806
|
-
function isExcludedDevDep(name) {
|
|
1807
|
-
return EXCLUDED_DEV_DEPS.has(name) || name.startsWith("@types/");
|
|
1808
|
-
}
|
|
1809
|
-
function stripScope(name) {
|
|
1810
|
-
const match = name.match(/^@[^/]+\/(.+)$/);
|
|
1811
|
-
return match ? match[1] : name;
|
|
1812
|
-
}
|
|
1813
|
-
async function readTsFiles(dir, baseDir, exclude) {
|
|
1814
|
-
const results = [];
|
|
1815
|
-
const entries = await readdir2(dir, { withFileTypes: true });
|
|
1816
|
-
for (const entry of entries) {
|
|
1817
|
-
const fullPath = join12(dir, entry.name);
|
|
1818
|
-
const relPath = relative5(baseDir, fullPath);
|
|
1819
|
-
if (entry.isDirectory()) {
|
|
1820
|
-
const nested = await readTsFiles(fullPath, baseDir, exclude);
|
|
1821
|
-
results.push(...nested);
|
|
1822
|
-
} else if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
1823
|
-
if (exclude.includes(relPath)) {
|
|
1824
|
-
continue;
|
|
1825
|
-
}
|
|
1826
|
-
const content = await readFile9(fullPath, "utf-8");
|
|
1827
|
-
results.push({ relativePath: relPath, content });
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
return results;
|
|
1831
|
-
}
|
|
1832
|
-
async function buildComponent(componentDir) {
|
|
1833
|
-
let rawConfig;
|
|
1834
|
-
try {
|
|
1835
|
-
rawConfig = await readFile9(join12(componentDir, "registry.json"), "utf-8");
|
|
1836
|
-
} catch {
|
|
1837
|
-
throw new Error(
|
|
1838
|
-
`No registry.json found in ${componentDir}. Every component must have a registry.json file.`
|
|
1839
|
-
);
|
|
1840
|
-
}
|
|
1841
|
-
let config;
|
|
1842
|
-
try {
|
|
1843
|
-
config = componentConfigSchema.parse(JSON.parse(rawConfig));
|
|
1844
|
-
} catch (err) {
|
|
1845
|
-
throw new Error(
|
|
1846
|
-
`Invalid registry.json in ${componentDir}: ${err instanceof Error ? err.message : String(err)}`
|
|
1847
|
-
);
|
|
1848
|
-
}
|
|
1849
|
-
let pkg = null;
|
|
1850
|
-
try {
|
|
1851
|
-
const rawPkg = await readFile9(join12(componentDir, "package.json"), "utf-8");
|
|
1852
|
-
pkg = JSON.parse(rawPkg);
|
|
1853
|
-
} catch {
|
|
1854
|
-
}
|
|
1855
|
-
const name = config.name ?? (pkg?.name ? stripScope(pkg.name) : void 0);
|
|
1856
|
-
const version = config.version ?? pkg?.version;
|
|
1857
|
-
const description = config.description ?? pkg?.description;
|
|
1858
|
-
if (!name) {
|
|
1859
|
-
throw new Error(
|
|
1860
|
-
`Component in ${componentDir} is missing a name. Provide "name" in registry.json or have a package.json with a "name" field.`
|
|
1861
|
-
);
|
|
1862
|
-
}
|
|
1863
|
-
if (!description) {
|
|
1864
|
-
throw new Error(
|
|
1865
|
-
`Component in ${componentDir} is missing a description. Provide "description" in registry.json or have a package.json with a "description" field.`
|
|
1866
|
-
);
|
|
1867
|
-
}
|
|
1868
|
-
let dependencies = config.dependencies;
|
|
1869
|
-
let devDependencies = config.devDependencies;
|
|
1870
|
-
if (pkg && !config.dependencies) {
|
|
1871
|
-
const deps = [];
|
|
1872
|
-
if (pkg.dependencies) {
|
|
1873
|
-
for (const [depName, depVersion] of Object.entries(pkg.dependencies)) {
|
|
1874
|
-
if (depVersion !== "workspace:*") {
|
|
1875
|
-
deps.push(depName);
|
|
1876
|
-
}
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
if (pkg.peerDependencies) {
|
|
1880
|
-
for (const [depName, depVersion] of Object.entries(pkg.peerDependencies)) {
|
|
1881
|
-
if (depVersion !== "workspace:*") {
|
|
1882
|
-
deps.push(depName);
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
if (deps.length > 0) {
|
|
1887
|
-
dependencies = deps;
|
|
1888
|
-
}
|
|
1889
|
-
}
|
|
1890
|
-
if (pkg && !config.devDependencies) {
|
|
1891
|
-
const devDeps = [];
|
|
1892
|
-
if (pkg.devDependencies) {
|
|
1893
|
-
for (const depName of Object.keys(pkg.devDependencies)) {
|
|
1894
|
-
if (!isExcludedDevDep(depName)) {
|
|
1895
|
-
devDeps.push(depName);
|
|
1896
|
-
}
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
if (devDeps.length > 0) {
|
|
1900
|
-
devDependencies = devDeps;
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
const isPackage = config.type === "kitn:package";
|
|
1904
|
-
const dirPrefix = config.installDir ?? typeToDir[config.type];
|
|
1905
|
-
let files;
|
|
1906
|
-
if (isPackage) {
|
|
1907
|
-
const sourceDir = config.sourceDir ?? "src";
|
|
1908
|
-
const sourcePath = join12(componentDir, sourceDir);
|
|
1909
|
-
const exclude = config.exclude ?? [];
|
|
1910
|
-
let tsFiles;
|
|
1911
|
-
try {
|
|
1912
|
-
tsFiles = await readTsFiles(sourcePath, sourcePath, exclude);
|
|
1913
|
-
} catch {
|
|
1914
|
-
throw new Error(
|
|
1915
|
-
`Cannot read source directory "${sourceDir}" in ${componentDir}. Make sure it exists.`
|
|
1916
|
-
);
|
|
1917
|
-
}
|
|
1918
|
-
files = tsFiles.map((f) => ({
|
|
1919
|
-
path: `${dirPrefix}/${f.relativePath}`,
|
|
1920
|
-
content: f.content,
|
|
1921
|
-
type: config.type
|
|
1922
|
-
}));
|
|
1923
|
-
} else {
|
|
1924
|
-
if (!config.files || config.files.length === 0) {
|
|
1925
|
-
throw new Error(
|
|
1926
|
-
`Component "${name}" (type: ${config.type}) has no "files" array in registry.json. Standalone components must list their source files.`
|
|
1927
|
-
);
|
|
1928
|
-
}
|
|
1929
|
-
files = await Promise.all(
|
|
1930
|
-
config.files.map(async (filePath) => {
|
|
1931
|
-
const fullPath = join12(componentDir, filePath);
|
|
1932
|
-
let content;
|
|
1933
|
-
try {
|
|
1934
|
-
content = await readFile9(fullPath, "utf-8");
|
|
1935
|
-
} catch {
|
|
1936
|
-
throw new Error(
|
|
1937
|
-
`Cannot read file "${filePath}" referenced in registry.json for component "${name}". Make sure the file exists at ${fullPath}.`
|
|
1938
|
-
);
|
|
1939
|
-
}
|
|
1940
|
-
return {
|
|
1941
|
-
path: `${dirPrefix}/${filePath}`,
|
|
1942
|
-
content,
|
|
1943
|
-
type: config.type
|
|
1944
|
-
};
|
|
1945
|
-
})
|
|
1946
|
-
);
|
|
1947
|
-
}
|
|
1948
|
-
const item = {
|
|
1949
|
-
name,
|
|
1950
|
-
type: config.type,
|
|
1951
|
-
description,
|
|
1952
|
-
files
|
|
1953
|
-
};
|
|
1954
|
-
if (version) item.version = version;
|
|
1955
|
-
if (dependencies && dependencies.length > 0) item.dependencies = dependencies;
|
|
1956
|
-
if (devDependencies && devDependencies.length > 0) item.devDependencies = devDependencies;
|
|
1957
|
-
if (config.registryDependencies && config.registryDependencies.length > 0) {
|
|
1958
|
-
item.registryDependencies = config.registryDependencies;
|
|
1959
|
-
}
|
|
1960
|
-
if (config.envVars) item.envVars = config.envVars;
|
|
1961
|
-
if (config.tsconfig) item.tsconfig = config.tsconfig;
|
|
1962
|
-
if (config.docs) item.docs = config.docs;
|
|
1963
|
-
if (config.categories && config.categories.length > 0) item.categories = config.categories;
|
|
1964
|
-
if (config.changelog && config.changelog.length > 0) item.changelog = config.changelog;
|
|
1965
|
-
if (isPackage && config.installDir) item.installDir = config.installDir;
|
|
1966
|
-
try {
|
|
1967
|
-
return registryItemSchema.parse(item);
|
|
1968
|
-
} catch (err) {
|
|
1969
|
-
throw new Error(
|
|
1970
|
-
`Built component "${name}" failed validation: ${err instanceof Error ? err.message : String(err)}`
|
|
1971
|
-
);
|
|
1972
|
-
}
|
|
1973
|
-
}
|
|
1974
|
-
var EXCLUDED_DEV_DEPS;
|
|
1975
|
-
var init_builder = __esm({
|
|
1976
|
-
"src/registry/builder.ts"() {
|
|
1977
|
-
"use strict";
|
|
1978
|
-
init_schema();
|
|
1979
|
-
EXCLUDED_DEV_DEPS = /* @__PURE__ */ new Set([
|
|
1980
|
-
"typescript",
|
|
1981
|
-
"@types/bun",
|
|
1982
|
-
"@types/node",
|
|
1983
|
-
"tsup",
|
|
1984
|
-
"vitest",
|
|
1985
|
-
"jest",
|
|
1986
|
-
"@types/jest"
|
|
1987
|
-
]);
|
|
1988
|
-
}
|
|
1989
|
-
});
|
|
1990
|
-
|
|
1991
|
-
// src/commands/build.ts
|
|
1992
|
-
var build_exports = {};
|
|
1993
|
-
__export(build_exports, {
|
|
1994
|
-
buildCommand: () => buildCommand
|
|
1995
|
-
});
|
|
1996
|
-
import * as p8 from "@clack/prompts";
|
|
1997
|
-
import pc7 from "picocolors";
|
|
1998
|
-
import { resolve as resolve2, relative as relative6 } from "path";
|
|
1999
|
-
async function buildCommand(paths, opts) {
|
|
2000
|
-
p8.intro(pc7.bgCyan(pc7.black(" kitn build ")));
|
|
2001
|
-
const cwd = process.cwd();
|
|
2002
|
-
const outputDir = resolve2(cwd, opts.output ?? "dist/r");
|
|
2003
|
-
const s = p8.spinner();
|
|
2004
|
-
s.start("Scanning for components...");
|
|
2005
|
-
const componentDirs = await scanForComponents(cwd, paths.length > 0 ? paths : void 0);
|
|
2006
|
-
if (componentDirs.length === 0) {
|
|
2007
|
-
s.stop("No components found");
|
|
2008
|
-
p8.log.info(
|
|
2009
|
-
`No directories with ${pc7.bold("registry.json")} found. Run ${pc7.bold("kitn create")} to scaffold a component.`
|
|
2010
|
-
);
|
|
2011
|
-
return;
|
|
2012
|
-
}
|
|
2013
|
-
s.stop(`Found ${componentDirs.length} component(s)`);
|
|
2014
|
-
p8.log.message(componentDirs.map((dir) => ` ${pc7.dim(relative6(cwd, dir))}`).join("\n"));
|
|
2015
|
-
s.start("Building components...");
|
|
2016
|
-
const items = [];
|
|
2017
|
-
const errors = [];
|
|
2018
|
-
for (const dir of componentDirs) {
|
|
2019
|
-
try {
|
|
2020
|
-
const item = await buildComponent(dir);
|
|
2021
|
-
items.push(item);
|
|
2022
|
-
} catch (err) {
|
|
2023
|
-
errors.push({ dir: relative6(cwd, dir), error: err.message });
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
if (errors.length > 0) {
|
|
2027
|
-
s.stop(pc7.red(`Build failed with ${errors.length} error(s)`));
|
|
2028
|
-
p8.log.error(errors.map(({ dir, error }) => `${pc7.bold(dir)}: ${error}`).join("\n"));
|
|
2029
|
-
process.exit(1);
|
|
2030
|
-
}
|
|
2031
|
-
const { written, skipped } = await writeRegistryOutput(outputDir, items);
|
|
2032
|
-
s.stop(pc7.green(`Built ${items.length} component(s)`));
|
|
2033
|
-
if (written.length > 0) {
|
|
2034
|
-
p8.log.success(`Wrote ${written.length} file(s):
|
|
2035
|
-
` + written.map((f) => ` ${pc7.green("+")} ${f}`).join("\n"));
|
|
2036
|
-
}
|
|
2037
|
-
if (skipped.length > 0) {
|
|
2038
|
-
p8.log.info(`Skipped ${skipped.length} file(s) (already exist):
|
|
2039
|
-
` + skipped.map((f) => ` ${pc7.dim("-")} ${f}`).join("\n"));
|
|
2040
|
-
}
|
|
2041
|
-
p8.outro(`Output: ${pc7.cyan(relative6(cwd, outputDir) || ".")}`);
|
|
2042
|
-
}
|
|
2043
|
-
var init_build = __esm({
|
|
2044
|
-
"src/commands/build.ts"() {
|
|
2045
|
-
"use strict";
|
|
2046
|
-
init_build_output();
|
|
2047
|
-
init_builder();
|
|
2048
|
-
}
|
|
2049
|
-
});
|
|
2050
|
-
|
|
2051
1656
|
// src/commands/create.ts
|
|
2052
1657
|
var create_exports = {};
|
|
2053
1658
|
__export(create_exports, {
|
|
2054
1659
|
createCommand: () => createCommand,
|
|
2055
|
-
|
|
1660
|
+
createComponentInProject: () => createComponentInProject
|
|
2056
1661
|
});
|
|
2057
|
-
import * as
|
|
2058
|
-
import
|
|
2059
|
-
import { join as
|
|
2060
|
-
import {
|
|
1662
|
+
import * as p8 from "@clack/prompts";
|
|
1663
|
+
import pc7 from "picocolors";
|
|
1664
|
+
import { join as join11, relative as relative4 } from "path";
|
|
1665
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1666
|
+
import { readFile as readFile8, writeFile as writeFile9, mkdir as mkdir5 } from "fs/promises";
|
|
2061
1667
|
function toCamelCase(str) {
|
|
2062
1668
|
return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
2063
1669
|
}
|
|
2064
1670
|
function toTitleCase(str) {
|
|
2065
1671
|
return str.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
2066
1672
|
}
|
|
2067
|
-
function generateRegistryJson(type, name, sourceFile) {
|
|
2068
|
-
const base = {
|
|
2069
|
-
$schema: "https://kitn.dev/schema/registry.json",
|
|
2070
|
-
name,
|
|
2071
|
-
type: `kitn:${type}`,
|
|
2072
|
-
version: "0.1.0",
|
|
2073
|
-
description: "",
|
|
2074
|
-
files: [sourceFile],
|
|
2075
|
-
categories: []
|
|
2076
|
-
};
|
|
2077
|
-
if (type === "tool") {
|
|
2078
|
-
base.dependencies = ["ai", "zod"];
|
|
2079
|
-
} else if (type === "agent" || type === "storage") {
|
|
2080
|
-
base.dependencies = [];
|
|
2081
|
-
}
|
|
2082
|
-
return base;
|
|
2083
|
-
}
|
|
2084
1673
|
function generateAgentSource(name) {
|
|
2085
1674
|
const camel = toCamelCase(name);
|
|
2086
1675
|
return `import { registerAgent } from "@kitn/core";
|
|
@@ -2103,7 +1692,7 @@ import { z } from "zod";
|
|
|
2103
1692
|
|
|
2104
1693
|
export const ${camel} = tool({
|
|
2105
1694
|
description: "",
|
|
2106
|
-
|
|
1695
|
+
inputSchema: z.object({
|
|
2107
1696
|
input: z.string().describe("Input parameter"),
|
|
2108
1697
|
}),
|
|
2109
1698
|
execute: async ({ input }) => {
|
|
@@ -2142,34 +1731,28 @@ export function ${camel}(config?: Record<string, unknown>): StorageProvider {
|
|
|
2142
1731
|
}
|
|
2143
1732
|
`;
|
|
2144
1733
|
}
|
|
2145
|
-
async function
|
|
2146
|
-
try {
|
|
2147
|
-
const { stat: stat2 } = await import("fs/promises");
|
|
2148
|
-
const s = await stat2(path);
|
|
2149
|
-
return s.isDirectory();
|
|
2150
|
-
} catch {
|
|
2151
|
-
return false;
|
|
2152
|
-
}
|
|
2153
|
-
}
|
|
2154
|
-
async function createComponent(type, name, opts) {
|
|
1734
|
+
async function createComponentInProject(type, name, opts) {
|
|
2155
1735
|
if (!VALID_TYPES.includes(type)) {
|
|
2156
1736
|
throw new Error(
|
|
2157
1737
|
`Invalid component type: "${type}". Valid types: ${VALID_TYPES.join(", ")}`
|
|
2158
1738
|
);
|
|
2159
1739
|
}
|
|
2160
1740
|
const cwd = opts?.cwd ?? process.cwd();
|
|
2161
|
-
const
|
|
2162
|
-
if (
|
|
2163
|
-
throw new Error(
|
|
1741
|
+
const config = await readConfig(cwd);
|
|
1742
|
+
if (!config) {
|
|
1743
|
+
throw new Error(
|
|
1744
|
+
`No kitn.json found in ${cwd}. Run ${pc7.bold("kitn init")} first.`
|
|
1745
|
+
);
|
|
2164
1746
|
}
|
|
2165
|
-
await mkdir6(dir, { recursive: true });
|
|
2166
1747
|
const validType = type;
|
|
2167
|
-
const
|
|
2168
|
-
const
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
)
|
|
1748
|
+
const kitnType = typeToKitnType[validType];
|
|
1749
|
+
const fileName = validType === "skill" ? `${name}.md` : `${name}.ts`;
|
|
1750
|
+
const filePath = join11(cwd, getInstallPath(config, kitnType, fileName));
|
|
1751
|
+
const dummyContent = "";
|
|
1752
|
+
const status = await checkFileStatus(filePath, dummyContent);
|
|
1753
|
+
if (status !== "new" /* New */) {
|
|
1754
|
+
throw new Error(`File already exists: ${filePath}`);
|
|
1755
|
+
}
|
|
2173
1756
|
let source;
|
|
2174
1757
|
switch (validType) {
|
|
2175
1758
|
case "agent":
|
|
@@ -2185,31 +1768,59 @@ async function createComponent(type, name, opts) {
|
|
|
2185
1768
|
source = generateStorageSource(name);
|
|
2186
1769
|
break;
|
|
2187
1770
|
}
|
|
2188
|
-
await
|
|
2189
|
-
|
|
1771
|
+
await writeComponentFile(filePath, source);
|
|
1772
|
+
let barrelUpdated = false;
|
|
1773
|
+
if (BARREL_TYPES.includes(validType)) {
|
|
1774
|
+
const baseDir = config.aliases.base ?? "src/ai";
|
|
1775
|
+
const barrelPath = join11(cwd, baseDir, "index.ts");
|
|
1776
|
+
let barrelContent;
|
|
1777
|
+
if (existsSync3(barrelPath)) {
|
|
1778
|
+
barrelContent = await readFile8(barrelPath, "utf-8");
|
|
1779
|
+
} else {
|
|
1780
|
+
barrelContent = createBarrelFile();
|
|
1781
|
+
await mkdir5(join11(cwd, baseDir), { recursive: true });
|
|
1782
|
+
}
|
|
1783
|
+
const importPath = "./" + relative4(join11(cwd, baseDir), filePath).replace(/\.ts$/, ".js");
|
|
1784
|
+
const updatedBarrel = addImportToBarrel(barrelContent, importPath);
|
|
1785
|
+
if (updatedBarrel !== barrelContent) {
|
|
1786
|
+
await writeFile9(barrelPath, updatedBarrel);
|
|
1787
|
+
barrelUpdated = true;
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
return { filePath, barrelUpdated };
|
|
2190
1791
|
}
|
|
2191
1792
|
async function createCommand(type, name) {
|
|
2192
|
-
|
|
1793
|
+
p8.intro(pc7.bgCyan(pc7.black(" kitn create ")));
|
|
2193
1794
|
try {
|
|
2194
|
-
const {
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
1795
|
+
const { filePath, barrelUpdated } = await createComponentInProject(type, name);
|
|
1796
|
+
p8.log.success(`Created ${pc7.bold(type)} component ${pc7.cyan(name)}`);
|
|
1797
|
+
p8.log.message(` ${pc7.green("+")} ${filePath}`);
|
|
1798
|
+
if (barrelUpdated) {
|
|
1799
|
+
p8.log.message(` ${pc7.green("+")} barrel file updated`);
|
|
2198
1800
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
`Edit ${pc8.cyan(`${name}/${editFile}`)}, then run ${pc8.bold("kitn build")}`
|
|
1801
|
+
p8.outro(
|
|
1802
|
+
`Edit ${pc7.cyan(filePath)} to customize your ${type}.`
|
|
2202
1803
|
);
|
|
2203
1804
|
} catch (err) {
|
|
2204
|
-
|
|
1805
|
+
p8.log.error(err.message);
|
|
2205
1806
|
process.exit(1);
|
|
2206
1807
|
}
|
|
2207
1808
|
}
|
|
2208
|
-
var VALID_TYPES;
|
|
1809
|
+
var VALID_TYPES, typeToKitnType, BARREL_TYPES;
|
|
2209
1810
|
var init_create = __esm({
|
|
2210
1811
|
"src/commands/create.ts"() {
|
|
2211
1812
|
"use strict";
|
|
1813
|
+
init_config();
|
|
1814
|
+
init_file_writer();
|
|
1815
|
+
init_barrel_manager();
|
|
2212
1816
|
VALID_TYPES = ["agent", "tool", "skill", "storage"];
|
|
1817
|
+
typeToKitnType = {
|
|
1818
|
+
agent: "kitn:agent",
|
|
1819
|
+
tool: "kitn:tool",
|
|
1820
|
+
skill: "kitn:skill",
|
|
1821
|
+
storage: "kitn:storage"
|
|
1822
|
+
};
|
|
1823
|
+
BARREL_TYPES = ["agent", "tool", "skill"];
|
|
2213
1824
|
}
|
|
2214
1825
|
});
|
|
2215
1826
|
|
|
@@ -2218,31 +1829,31 @@ var info_exports = {};
|
|
|
2218
1829
|
__export(info_exports, {
|
|
2219
1830
|
infoCommand: () => infoCommand
|
|
2220
1831
|
});
|
|
2221
|
-
import * as
|
|
2222
|
-
import
|
|
1832
|
+
import * as p9 from "@clack/prompts";
|
|
1833
|
+
import pc8 from "picocolors";
|
|
2223
1834
|
async function infoCommand(component) {
|
|
2224
1835
|
const cwd = process.cwd();
|
|
2225
1836
|
const config = await readConfig(cwd);
|
|
2226
1837
|
if (!config) {
|
|
2227
|
-
|
|
1838
|
+
p9.log.error("No kitn.json found. Run `kitn init` first.");
|
|
2228
1839
|
process.exit(1);
|
|
2229
1840
|
}
|
|
2230
1841
|
const ref = parseComponentRef(component);
|
|
2231
1842
|
const fetcher = new RegistryFetcher(config.registries);
|
|
2232
|
-
const s =
|
|
1843
|
+
const s = p9.spinner();
|
|
2233
1844
|
s.start("Fetching component info...");
|
|
2234
1845
|
let index;
|
|
2235
1846
|
try {
|
|
2236
1847
|
index = await fetcher.fetchIndex(ref.namespace);
|
|
2237
1848
|
} catch (err) {
|
|
2238
|
-
s.stop(
|
|
2239
|
-
|
|
1849
|
+
s.stop(pc8.red("Failed to fetch registry"));
|
|
1850
|
+
p9.log.error(err.message);
|
|
2240
1851
|
process.exit(1);
|
|
2241
1852
|
}
|
|
2242
1853
|
const indexItem = index.items.find((i) => i.name === ref.name);
|
|
2243
1854
|
if (!indexItem) {
|
|
2244
|
-
s.stop(
|
|
2245
|
-
|
|
1855
|
+
s.stop(pc8.red("Component not found"));
|
|
1856
|
+
p9.log.error(`Component '${ref.name}' not found in registry.`);
|
|
2246
1857
|
process.exit(1);
|
|
2247
1858
|
}
|
|
2248
1859
|
const dir = typeToDir[indexItem.type];
|
|
@@ -2250,8 +1861,8 @@ async function infoCommand(component) {
|
|
|
2250
1861
|
try {
|
|
2251
1862
|
item = await fetcher.fetchItem(ref.name, dir, ref.namespace, ref.version);
|
|
2252
1863
|
} catch (err) {
|
|
2253
|
-
s.stop(
|
|
2254
|
-
|
|
1864
|
+
s.stop(pc8.red("Failed to fetch component"));
|
|
1865
|
+
p9.log.error(err.message);
|
|
2255
1866
|
process.exit(1);
|
|
2256
1867
|
}
|
|
2257
1868
|
s.stop("Component found");
|
|
@@ -2259,62 +1870,62 @@ async function infoCommand(component) {
|
|
|
2259
1870
|
const typeName = indexItem.type.replace("kitn:", "");
|
|
2260
1871
|
console.log();
|
|
2261
1872
|
console.log(
|
|
2262
|
-
` ${
|
|
1873
|
+
` ${pc8.bold(item.name)} ${pc8.cyan(`v${version}`)}${" ".repeat(Math.max(1, 40 - item.name.length - version.length - 2))}${pc8.dim(ref.namespace)}`
|
|
2263
1874
|
);
|
|
2264
|
-
console.log(` ${
|
|
1875
|
+
console.log(` ${pc8.dim(item.description)}`);
|
|
2265
1876
|
console.log();
|
|
2266
|
-
console.log(` ${
|
|
1877
|
+
console.log(` ${pc8.dim("Type:")} ${typeName}`);
|
|
2267
1878
|
if (item.dependencies?.length) {
|
|
2268
1879
|
console.log(
|
|
2269
|
-
` ${
|
|
1880
|
+
` ${pc8.dim("Dependencies:")} ${item.dependencies.join(", ")}`
|
|
2270
1881
|
);
|
|
2271
1882
|
}
|
|
2272
1883
|
if (item.registryDependencies?.length) {
|
|
2273
1884
|
console.log(
|
|
2274
|
-
` ${
|
|
1885
|
+
` ${pc8.dim("Registry deps:")} ${item.registryDependencies.join(", ")}`
|
|
2275
1886
|
);
|
|
2276
1887
|
}
|
|
2277
1888
|
if (item.categories?.length) {
|
|
2278
1889
|
console.log(
|
|
2279
|
-
` ${
|
|
1890
|
+
` ${pc8.dim("Categories:")} ${item.categories.join(", ")}`
|
|
2280
1891
|
);
|
|
2281
1892
|
}
|
|
2282
1893
|
if (item.updatedAt) {
|
|
2283
|
-
console.log(` ${
|
|
1894
|
+
console.log(` ${pc8.dim("Updated:")} ${item.updatedAt}`);
|
|
2284
1895
|
}
|
|
2285
1896
|
const versions = indexItem.versions;
|
|
2286
1897
|
if (versions?.length) {
|
|
2287
|
-
console.log(` ${
|
|
1898
|
+
console.log(` ${pc8.dim("Versions:")} ${versions.join(", ")}`);
|
|
2288
1899
|
}
|
|
2289
1900
|
if (item.changelog?.length) {
|
|
2290
1901
|
console.log();
|
|
2291
|
-
console.log(` ${
|
|
1902
|
+
console.log(` ${pc8.bold("Changelog:")}`);
|
|
2292
1903
|
for (const entry of item.changelog) {
|
|
2293
|
-
const tag = entry.type === "feature" ?
|
|
1904
|
+
const tag = entry.type === "feature" ? pc8.green(entry.type) : entry.type === "fix" ? pc8.yellow(entry.type) : entry.type === "breaking" ? pc8.red(entry.type) : pc8.dim(entry.type);
|
|
2294
1905
|
console.log(
|
|
2295
|
-
` ${
|
|
1906
|
+
` ${pc8.cyan(entry.version)} ${pc8.dim(entry.date)} ${tag} ${entry.note}`
|
|
2296
1907
|
);
|
|
2297
1908
|
}
|
|
2298
1909
|
}
|
|
2299
1910
|
console.log();
|
|
2300
1911
|
const fileCount = item.files.length;
|
|
2301
|
-
console.log(` ${
|
|
1912
|
+
console.log(` ${pc8.bold(`Files:`)} ${pc8.dim(`(${fileCount})`)}`);
|
|
2302
1913
|
const maxShown = 10;
|
|
2303
1914
|
for (const file of item.files.slice(0, maxShown)) {
|
|
2304
|
-
console.log(` ${
|
|
1915
|
+
console.log(` ${pc8.dim(file.path)}`);
|
|
2305
1916
|
}
|
|
2306
1917
|
if (fileCount > maxShown) {
|
|
2307
|
-
console.log(` ${
|
|
1918
|
+
console.log(` ${pc8.dim(`... and ${fileCount - maxShown} more`)}`);
|
|
2308
1919
|
}
|
|
2309
1920
|
const installed = config.installed?.[item.name];
|
|
2310
1921
|
if (installed) {
|
|
2311
1922
|
console.log();
|
|
2312
1923
|
console.log(
|
|
2313
|
-
` ${
|
|
1924
|
+
` ${pc8.green("Installed")} ${pc8.dim(`v${installed.version}`)}`
|
|
2314
1925
|
);
|
|
2315
1926
|
if (version !== installed.version) {
|
|
2316
1927
|
console.log(
|
|
2317
|
-
` ${
|
|
1928
|
+
` ${pc8.yellow("Update available:")} ${pc8.dim(`v${installed.version}`)} \u2192 ${pc8.cyan(`v${version}`)}`
|
|
2318
1929
|
);
|
|
2319
1930
|
}
|
|
2320
1931
|
}
|
|
@@ -2335,26 +1946,26 @@ var check_exports = {};
|
|
|
2335
1946
|
__export(check_exports, {
|
|
2336
1947
|
checkCommand: () => checkCommand
|
|
2337
1948
|
});
|
|
2338
|
-
import * as
|
|
2339
|
-
import
|
|
1949
|
+
import * as p10 from "@clack/prompts";
|
|
1950
|
+
import pc9 from "picocolors";
|
|
2340
1951
|
async function checkCommand(currentVersion) {
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
const s =
|
|
1952
|
+
p10.intro(pc9.bgCyan(pc9.black(" kitn check ")));
|
|
1953
|
+
p10.log.info(`kitn v${currentVersion}`);
|
|
1954
|
+
const s = p10.spinner();
|
|
2344
1955
|
s.start("Checking for updates...");
|
|
2345
1956
|
const latest = await fetchLatestVersion();
|
|
2346
1957
|
if (!latest) {
|
|
2347
|
-
s.stop(
|
|
2348
|
-
|
|
1958
|
+
s.stop(pc9.yellow("Could not reach the npm registry"));
|
|
1959
|
+
p10.outro("Try again later.");
|
|
2349
1960
|
return;
|
|
2350
1961
|
}
|
|
2351
1962
|
if (isNewer(latest, currentVersion)) {
|
|
2352
|
-
s.stop(
|
|
2353
|
-
|
|
1963
|
+
s.stop(pc9.yellow(`Update available: ${currentVersion} \u2192 ${latest}`));
|
|
1964
|
+
p10.log.message(` Run: ${pc9.cyan("npm i -g @kitnai/cli")}`);
|
|
2354
1965
|
} else {
|
|
2355
|
-
s.stop(
|
|
1966
|
+
s.stop(pc9.green("You're on the latest version"));
|
|
2356
1967
|
}
|
|
2357
|
-
|
|
1968
|
+
p10.outro("");
|
|
2358
1969
|
}
|
|
2359
1970
|
var init_check = __esm({
|
|
2360
1971
|
"src/commands/check.ts"() {
|
|
@@ -2370,8 +1981,8 @@ __export(registry_exports, {
|
|
|
2370
1981
|
registryListCommand: () => registryListCommand,
|
|
2371
1982
|
registryRemoveCommand: () => registryRemoveCommand
|
|
2372
1983
|
});
|
|
2373
|
-
import * as
|
|
2374
|
-
import
|
|
1984
|
+
import * as p11 from "@clack/prompts";
|
|
1985
|
+
import pc10 from "picocolors";
|
|
2375
1986
|
async function registryAddCommand(namespace, url, opts = {}) {
|
|
2376
1987
|
const cwd = opts.cwd ?? process.cwd();
|
|
2377
1988
|
const config = await readConfig(cwd);
|
|
@@ -2397,10 +2008,10 @@ async function registryAddCommand(namespace, url, opts = {}) {
|
|
|
2397
2008
|
config.registries[namespace] = url;
|
|
2398
2009
|
}
|
|
2399
2010
|
await writeConfig(cwd, config);
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
if (opts.homepage)
|
|
2403
|
-
if (opts.description)
|
|
2011
|
+
p11.log.success(`Added registry ${pc10.bold(namespace)}`);
|
|
2012
|
+
p11.log.message(pc10.dim(` ${url}`));
|
|
2013
|
+
if (opts.homepage) p11.log.message(pc10.dim(` Homepage: ${opts.homepage}`));
|
|
2014
|
+
if (opts.description) p11.log.message(pc10.dim(` ${opts.description}`));
|
|
2404
2015
|
}
|
|
2405
2016
|
async function registryRemoveCommand(namespace, opts = {}) {
|
|
2406
2017
|
const cwd = opts.cwd ?? process.cwd();
|
|
@@ -2422,10 +2033,10 @@ async function registryRemoveCommand(namespace, opts = {}) {
|
|
|
2422
2033
|
}
|
|
2423
2034
|
delete config.registries[namespace];
|
|
2424
2035
|
await writeConfig(cwd, config);
|
|
2425
|
-
|
|
2036
|
+
p11.log.success(`Removed registry ${pc10.bold(namespace)}`);
|
|
2426
2037
|
if (affectedComponents.length > 0) {
|
|
2427
|
-
|
|
2428
|
-
` + affectedComponents.map((name) => ` ${
|
|
2038
|
+
p11.log.warn(`${affectedComponents.length} installed component(s) referenced this registry:
|
|
2039
|
+
` + affectedComponents.map((name) => ` ${pc10.yellow("!")} ${name}`).join("\n"));
|
|
2429
2040
|
}
|
|
2430
2041
|
return { affectedComponents };
|
|
2431
2042
|
}
|
|
@@ -2440,15 +2051,15 @@ async function registryListCommand(opts = {}) {
|
|
|
2440
2051
|
return { namespace, url, homepage, description };
|
|
2441
2052
|
});
|
|
2442
2053
|
if (entries.length === 0) {
|
|
2443
|
-
|
|
2054
|
+
p11.log.message(pc10.dim(" No registries configured."));
|
|
2444
2055
|
} else {
|
|
2445
2056
|
const lines = [];
|
|
2446
2057
|
for (const { namespace, url, homepage, description } of entries) {
|
|
2447
|
-
lines.push(` ${
|
|
2058
|
+
lines.push(` ${pc10.bold(namespace.padEnd(16))} ${pc10.dim(url)}`);
|
|
2448
2059
|
if (description) lines.push(` ${" ".repeat(16)} ${description}`);
|
|
2449
|
-
if (homepage) lines.push(` ${" ".repeat(16)} ${
|
|
2060
|
+
if (homepage) lines.push(` ${" ".repeat(16)} ${pc10.dim(homepage)}`);
|
|
2450
2061
|
}
|
|
2451
|
-
|
|
2062
|
+
p11.log.message(lines.join("\n"));
|
|
2452
2063
|
}
|
|
2453
2064
|
return entries;
|
|
2454
2065
|
}
|
|
@@ -2462,7 +2073,7 @@ var init_registry = __esm({
|
|
|
2462
2073
|
// src/index.ts
|
|
2463
2074
|
init_update_check();
|
|
2464
2075
|
import { Command } from "commander";
|
|
2465
|
-
var VERSION = true ? "0.1.
|
|
2076
|
+
var VERSION = true ? "0.1.21" : "0.0.0-dev";
|
|
2466
2077
|
var printUpdateNotice = startUpdateCheck(VERSION);
|
|
2467
2078
|
var program = new Command().name("kitn").description("Install AI agent components from the kitn registry").version(VERSION);
|
|
2468
2079
|
program.command("init").description("Initialize kitn in your project").option("-r, --runtime <runtime>", "runtime to use (bun, node, deno)").option("-b, --base <path>", "base directory for components (default: src/ai)").option("-y, --yes", "accept all defaults without prompting").action(async (opts) => {
|
|
@@ -2489,10 +2100,6 @@ program.command("update").description("Update installed components to latest reg
|
|
|
2489
2100
|
const { updateCommand: updateCommand2 } = await Promise.resolve().then(() => (init_update(), update_exports));
|
|
2490
2101
|
await updateCommand2(components);
|
|
2491
2102
|
});
|
|
2492
|
-
program.command("build").description("Build registry JSON from components with registry.json files").argument("[paths...]", "directories to build (default: scan from cwd)").option("-o, --output <dir>", "output directory", "dist/r").action(async (paths, opts) => {
|
|
2493
|
-
const { buildCommand: buildCommand2 } = await Promise.resolve().then(() => (init_build(), build_exports));
|
|
2494
|
-
await buildCommand2(paths, opts);
|
|
2495
|
-
});
|
|
2496
2103
|
program.command("create").description("Scaffold a new kitn component").argument("<type>", "component type (agent, tool, skill, storage)").argument("<name>", "component name").action(async (type, name) => {
|
|
2497
2104
|
const { createCommand: createCommand2 } = await Promise.resolve().then(() => (init_create(), create_exports));
|
|
2498
2105
|
await createCommand2(type, name);
|