@kitnai/cli 0.1.8 → 0.1.10
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 +234 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -510,6 +510,40 @@ var init_tsconfig_patcher = __esm({
|
|
|
510
510
|
}
|
|
511
511
|
});
|
|
512
512
|
|
|
513
|
+
// src/installers/barrel-manager.ts
|
|
514
|
+
function createBarrelFile() {
|
|
515
|
+
return `${BARREL_COMMENT}
|
|
516
|
+
${EXPORT_LINE}
|
|
517
|
+
`;
|
|
518
|
+
}
|
|
519
|
+
function addImportToBarrel(content, importPath) {
|
|
520
|
+
const importLine = `import "${importPath}";`;
|
|
521
|
+
if (content.includes(importLine)) return content;
|
|
522
|
+
const exportIndex = content.indexOf(EXPORT_LINE);
|
|
523
|
+
if (exportIndex === -1) {
|
|
524
|
+
return `${content.trimEnd()}
|
|
525
|
+
${importLine}
|
|
526
|
+
${EXPORT_LINE}
|
|
527
|
+
`;
|
|
528
|
+
}
|
|
529
|
+
const before = content.slice(0, exportIndex);
|
|
530
|
+
const after = content.slice(exportIndex);
|
|
531
|
+
return `${before}${importLine}
|
|
532
|
+
${after}`;
|
|
533
|
+
}
|
|
534
|
+
function removeImportFromBarrel(content, importPath) {
|
|
535
|
+
const importLine = `import "${importPath}";`;
|
|
536
|
+
return content.split("\n").filter((line) => line.trim() !== importLine).join("\n");
|
|
537
|
+
}
|
|
538
|
+
var EXPORT_LINE, BARREL_COMMENT;
|
|
539
|
+
var init_barrel_manager = __esm({
|
|
540
|
+
"src/installers/barrel-manager.ts"() {
|
|
541
|
+
"use strict";
|
|
542
|
+
EXPORT_LINE = 'export { registerWithPlugin } from "@kitnai/core";';
|
|
543
|
+
BARREL_COMMENT = "// Managed by kitn CLI \u2014 components auto-imported below";
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
|
|
513
547
|
// src/utils/hash.ts
|
|
514
548
|
import { createHash } from "crypto";
|
|
515
549
|
function contentHash(content) {
|
|
@@ -643,6 +677,9 @@ __export(add_exports, {
|
|
|
643
677
|
import * as p3 from "@clack/prompts";
|
|
644
678
|
import pc4 from "picocolors";
|
|
645
679
|
import { join as join7 } from "path";
|
|
680
|
+
import { existsSync } from "fs";
|
|
681
|
+
import { readFile as readFile6, writeFile as writeFile6, mkdir as mkdir3 } from "fs/promises";
|
|
682
|
+
import { relative as relative2 } from "path";
|
|
646
683
|
async function addCommand(components, opts) {
|
|
647
684
|
p3.intro(pc4.bgCyan(pc4.black(" kitn add ")));
|
|
648
685
|
const cwd = process.cwd();
|
|
@@ -695,10 +732,10 @@ async function addCommand(components, opts) {
|
|
|
695
732
|
for (const item of resolved) {
|
|
696
733
|
if (item.dependencies) allDeps.push(...item.dependencies);
|
|
697
734
|
if (item.type === "kitn:package") {
|
|
698
|
-
const
|
|
735
|
+
const baseDir2 = config.aliases.base ?? "src/ai";
|
|
699
736
|
for (const file of item.files) {
|
|
700
|
-
const targetPath = join7(cwd,
|
|
701
|
-
const relativePath = join7(
|
|
737
|
+
const targetPath = join7(cwd, baseDir2, file.path);
|
|
738
|
+
const relativePath = join7(baseDir2, file.path);
|
|
702
739
|
const status = await checkFileStatus(targetPath, file.content);
|
|
703
740
|
switch (status) {
|
|
704
741
|
case "new" /* New */:
|
|
@@ -737,7 +774,7 @@ async function addCommand(components, opts) {
|
|
|
737
774
|
const resolvedPaths = {};
|
|
738
775
|
const installDir = item.installDir ?? item.name;
|
|
739
776
|
for (const [key, values] of Object.entries(item.tsconfig)) {
|
|
740
|
-
resolvedPaths[key] = values.map((v) => `./${join7(
|
|
777
|
+
resolvedPaths[key] = values.map((v) => `./${join7(baseDir2, installDir, v)}`);
|
|
741
778
|
}
|
|
742
779
|
await patchProjectTsconfig(cwd, resolvedPaths);
|
|
743
780
|
p3.log.info(`Patched tsconfig.json with paths: ${Object.keys(resolvedPaths).join(", ")}`);
|
|
@@ -750,7 +787,7 @@ async function addCommand(components, opts) {
|
|
|
750
787
|
registry: ref.namespace,
|
|
751
788
|
version: item.version ?? "1.0.0",
|
|
752
789
|
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
753
|
-
files: item.files.map((f) => join7(
|
|
790
|
+
files: item.files.map((f) => join7(baseDir2, f.path)),
|
|
754
791
|
hash: contentHash(allContent)
|
|
755
792
|
};
|
|
756
793
|
config.installed = installed;
|
|
@@ -838,6 +875,61 @@ async function addCommand(components, opts) {
|
|
|
838
875
|
config.installed = installed;
|
|
839
876
|
}
|
|
840
877
|
}
|
|
878
|
+
const BARREL_ELIGIBLE = /* @__PURE__ */ new Set(["kitn:agent", "kitn:tool", "kitn:skill"]);
|
|
879
|
+
const baseDir = config.aliases.base ?? "src/ai";
|
|
880
|
+
const barrelPath = join7(cwd, baseDir, "index.ts");
|
|
881
|
+
const barrelDir = join7(cwd, baseDir);
|
|
882
|
+
const barrelImports = [];
|
|
883
|
+
for (const item of resolved) {
|
|
884
|
+
if (!BARREL_ELIGIBLE.has(item.type)) continue;
|
|
885
|
+
for (const file of item.files) {
|
|
886
|
+
const aliasKey = (() => {
|
|
887
|
+
switch (item.type) {
|
|
888
|
+
case "kitn:agent":
|
|
889
|
+
return "agents";
|
|
890
|
+
case "kitn:tool":
|
|
891
|
+
return "tools";
|
|
892
|
+
case "kitn:skill":
|
|
893
|
+
return "skills";
|
|
894
|
+
}
|
|
895
|
+
})();
|
|
896
|
+
const fileName = file.path.split("/").pop();
|
|
897
|
+
const filePath = join7(cwd, config.aliases[aliasKey], fileName);
|
|
898
|
+
const importPath = "./" + relative2(barrelDir, filePath).replace(/\\/g, "/");
|
|
899
|
+
barrelImports.push(importPath);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
if (barrelImports.length > 0) {
|
|
903
|
+
const barrelExisted = existsSync(barrelPath);
|
|
904
|
+
let barrelContent;
|
|
905
|
+
if (barrelExisted) {
|
|
906
|
+
barrelContent = await readFile6(barrelPath, "utf-8");
|
|
907
|
+
} else {
|
|
908
|
+
await mkdir3(barrelDir, { recursive: true });
|
|
909
|
+
barrelContent = createBarrelFile();
|
|
910
|
+
}
|
|
911
|
+
for (const importPath of barrelImports) {
|
|
912
|
+
barrelContent = addImportToBarrel(barrelContent, importPath);
|
|
913
|
+
}
|
|
914
|
+
await writeFile6(barrelPath, barrelContent);
|
|
915
|
+
p3.log.info(`Updated barrel file: ${join7(baseDir, "index.ts")}`);
|
|
916
|
+
if (!barrelExisted) {
|
|
917
|
+
p3.note(
|
|
918
|
+
[
|
|
919
|
+
`import { createAIPlugin } from "@kitnai/hono";`,
|
|
920
|
+
`import { registerWithPlugin } from "./ai";`,
|
|
921
|
+
``,
|
|
922
|
+
`const plugin = createAIPlugin({`,
|
|
923
|
+
` model: (model) => yourProvider(model ?? "default-model"),`,
|
|
924
|
+
`});`,
|
|
925
|
+
``,
|
|
926
|
+
`registerWithPlugin(plugin);`,
|
|
927
|
+
`app.route("/api", plugin.app);`
|
|
928
|
+
].join("\n"),
|
|
929
|
+
"Add this to your app setup"
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
841
933
|
await writeConfig(cwd, config);
|
|
842
934
|
const uniqueDeps = [...new Set(allDeps)];
|
|
843
935
|
if (uniqueDeps.length > 0) {
|
|
@@ -886,7 +978,7 @@ async function addCommand(components, opts) {
|
|
|
886
978
|
hints.push(pc4.dim(` import { yourProvider } from "your-ai-provider";`));
|
|
887
979
|
hints.push(pc4.dim(``));
|
|
888
980
|
hints.push(pc4.dim(` const plugin = createAIPlugin({`));
|
|
889
|
-
hints.push(pc4.dim(`
|
|
981
|
+
hints.push(pc4.dim(` model: (model) => yourProvider(model ?? "default-model"),`));
|
|
890
982
|
hints.push(pc4.dim(` });`));
|
|
891
983
|
hints.push(pc4.dim(``));
|
|
892
984
|
hints.push(pc4.dim(` const app = new Hono();`));
|
|
@@ -913,6 +1005,7 @@ var init_add = __esm({
|
|
|
913
1005
|
init_env_writer();
|
|
914
1006
|
init_import_rewriter();
|
|
915
1007
|
init_tsconfig_patcher();
|
|
1008
|
+
init_barrel_manager();
|
|
916
1009
|
init_hash();
|
|
917
1010
|
init_parse_ref();
|
|
918
1011
|
init_schema();
|
|
@@ -926,13 +1019,19 @@ __export(list_exports, {
|
|
|
926
1019
|
});
|
|
927
1020
|
import * as p4 from "@clack/prompts";
|
|
928
1021
|
import pc5 from "picocolors";
|
|
929
|
-
async function listCommand(opts) {
|
|
1022
|
+
async function listCommand(typeFilter, opts) {
|
|
930
1023
|
const cwd = process.cwd();
|
|
931
1024
|
const config = await readConfig(cwd);
|
|
932
1025
|
if (!config) {
|
|
933
1026
|
p4.log.error("No kitn.json found. Run `kitn init` first.");
|
|
934
1027
|
process.exit(1);
|
|
935
1028
|
}
|
|
1029
|
+
const rawType = typeFilter ?? opts.type;
|
|
1030
|
+
const resolvedType = rawType ? TYPE_ALIASES[rawType.toLowerCase()] : void 0;
|
|
1031
|
+
if (rawType && !resolvedType) {
|
|
1032
|
+
p4.log.error(`Unknown type ${pc5.bold(rawType)}. Valid types: agent, tool, skill, storage, package`);
|
|
1033
|
+
process.exit(1);
|
|
1034
|
+
}
|
|
936
1035
|
const fetcher = new RegistryFetcher(config.registries);
|
|
937
1036
|
const namespacesToFetch = opts.registry ? [opts.registry] : Object.keys(config.registries);
|
|
938
1037
|
if (opts.registry && !config.registries[opts.registry]) {
|
|
@@ -940,7 +1039,7 @@ async function listCommand(opts) {
|
|
|
940
1039
|
process.exit(1);
|
|
941
1040
|
}
|
|
942
1041
|
const s = p4.spinner();
|
|
943
|
-
s.start("Fetching registry
|
|
1042
|
+
s.start("Fetching registry...");
|
|
944
1043
|
const allItems = [];
|
|
945
1044
|
const errors = [];
|
|
946
1045
|
for (const namespace of namespacesToFetch) {
|
|
@@ -958,52 +1057,94 @@ async function listCommand(opts) {
|
|
|
958
1057
|
for (const e of errors) p4.log.error(e);
|
|
959
1058
|
process.exit(1);
|
|
960
1059
|
}
|
|
961
|
-
s.stop(`Found ${allItems.length} components
|
|
1060
|
+
s.stop(`Found ${allItems.length} components`);
|
|
962
1061
|
for (const e of errors) {
|
|
963
1062
|
p4.log.warn(`${pc5.yellow("\u26A0")} Failed to fetch ${e}`);
|
|
964
1063
|
}
|
|
965
1064
|
const installed = config.installed ?? {};
|
|
966
1065
|
const typeGroups = /* @__PURE__ */ new Map();
|
|
967
1066
|
for (const item of allItems) {
|
|
968
|
-
if (opts.type && !item.type.endsWith(opts.type)) continue;
|
|
969
1067
|
const group = item.type.replace("kitn:", "");
|
|
1068
|
+
if (resolvedType && group !== resolvedType) continue;
|
|
970
1069
|
if (!typeGroups.has(group)) typeGroups.set(group, []);
|
|
971
1070
|
typeGroups.get(group).push(item);
|
|
972
1071
|
}
|
|
1072
|
+
let maxName = 0;
|
|
1073
|
+
for (const items of typeGroups.values()) {
|
|
1074
|
+
for (const item of items) {
|
|
1075
|
+
const displayName = item.namespace === "@kitn" ? item.name : `${item.namespace}/${item.name}`;
|
|
1076
|
+
if (displayName.length > maxName) maxName = displayName.length;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
const cols = process.stdout.columns ?? 80;
|
|
1080
|
+
const versionLen = opts.verbose ? 10 : 0;
|
|
1081
|
+
const prefixLen = 4 + maxName + 2 + versionLen;
|
|
973
1082
|
let installedCount = 0;
|
|
974
1083
|
let updateCount = 0;
|
|
1084
|
+
let shownCount = 0;
|
|
975
1085
|
for (const [group, items] of typeGroups) {
|
|
976
|
-
|
|
977
|
-
|
|
1086
|
+
items.sort((a, b) => {
|
|
1087
|
+
const aInst = !!(installed[a.name] ?? installed[`${a.namespace}/${a.name}`]);
|
|
1088
|
+
const bInst = !!(installed[b.name] ?? installed[`${b.namespace}/${b.name}`]);
|
|
1089
|
+
if (aInst !== bInst) return aInst ? -1 : 1;
|
|
1090
|
+
return a.name.localeCompare(b.name);
|
|
1091
|
+
});
|
|
1092
|
+
const label = group.charAt(0).toUpperCase() + group.slice(1) + "s";
|
|
1093
|
+
console.log(`
|
|
1094
|
+
${pc5.bold(label)} ${pc5.dim(`(${items.length})`)}`);
|
|
978
1095
|
for (const item of items) {
|
|
979
1096
|
const displayName = item.namespace === "@kitn" ? item.name : `${item.namespace}/${item.name}`;
|
|
980
1097
|
const inst = installed[item.name] ?? installed[displayName];
|
|
981
1098
|
if (opts.installed && !inst) continue;
|
|
982
|
-
const
|
|
1099
|
+
const maxDescLen = Math.max(20, cols - prefixLen);
|
|
1100
|
+
let desc = item.description;
|
|
1101
|
+
if (desc.length > maxDescLen) {
|
|
1102
|
+
desc = desc.slice(0, maxDescLen - 1) + "\u2026";
|
|
1103
|
+
}
|
|
1104
|
+
let line;
|
|
1105
|
+
const nameCol = displayName.padEnd(maxName + 2);
|
|
1106
|
+
const version = opts.verbose ? `${pc5.dim(`v${item.version ?? "1.0.0"}`)} ` : "";
|
|
983
1107
|
if (inst) {
|
|
984
1108
|
installedCount++;
|
|
985
|
-
const status = pc5.green("\u2713");
|
|
986
1109
|
const hasUpdate = item.version && inst.version !== item.version;
|
|
987
|
-
const updateTag = hasUpdate ? pc5.yellow(` \u2B06 v${item.version} available`) : "";
|
|
988
1110
|
if (hasUpdate) updateCount++;
|
|
989
|
-
|
|
1111
|
+
const updateTag = hasUpdate ? pc5.yellow(` \u2191${item.version}`) : "";
|
|
1112
|
+
line = ` ${pc5.green("\u2713")} ${nameCol}${version}${pc5.dim(desc)}${updateTag}`;
|
|
990
1113
|
} else {
|
|
991
|
-
|
|
992
|
-
p4.log.message(` ${status} ${displayName.padEnd(20)} ${version} ${pc5.dim(item.description)}`);
|
|
1114
|
+
line = ` ${pc5.dim("\u25CB")} ${nameCol}${version}${pc5.dim(desc)}`;
|
|
993
1115
|
}
|
|
1116
|
+
console.log(line);
|
|
1117
|
+
shownCount++;
|
|
994
1118
|
}
|
|
995
1119
|
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1120
|
+
if (shownCount === 0 && resolvedType) {
|
|
1121
|
+
console.log(pc5.dim(`
|
|
1122
|
+
No ${resolvedType} components found.`));
|
|
1123
|
+
}
|
|
1124
|
+
const parts = [`${installedCount} installed`, `${allItems.length - installedCount} available`];
|
|
1125
|
+
if (updateCount > 0) parts.push(pc5.yellow(`${updateCount} update${updateCount === 1 ? "" : "s"}`));
|
|
1126
|
+
console.log(`
|
|
1127
|
+
${pc5.dim(parts.join(" \xB7 "))}
|
|
1128
|
+
`);
|
|
1001
1129
|
}
|
|
1130
|
+
var TYPE_ALIASES;
|
|
1002
1131
|
var init_list = __esm({
|
|
1003
1132
|
"src/commands/list.ts"() {
|
|
1004
1133
|
"use strict";
|
|
1005
1134
|
init_config();
|
|
1006
1135
|
init_fetcher();
|
|
1136
|
+
TYPE_ALIASES = {
|
|
1137
|
+
agent: "agent",
|
|
1138
|
+
agents: "agent",
|
|
1139
|
+
tool: "tool",
|
|
1140
|
+
tools: "tool",
|
|
1141
|
+
skill: "skill",
|
|
1142
|
+
skills: "skill",
|
|
1143
|
+
storage: "storage",
|
|
1144
|
+
storages: "storage",
|
|
1145
|
+
package: "package",
|
|
1146
|
+
packages: "package"
|
|
1147
|
+
};
|
|
1007
1148
|
}
|
|
1008
1149
|
});
|
|
1009
1150
|
|
|
@@ -1102,8 +1243,9 @@ __export(remove_exports, {
|
|
|
1102
1243
|
});
|
|
1103
1244
|
import * as p6 from "@clack/prompts";
|
|
1104
1245
|
import pc6 from "picocolors";
|
|
1105
|
-
import { join as join9 } from "path";
|
|
1106
|
-
import { unlink } from "fs/promises";
|
|
1246
|
+
import { join as join9, relative as relative3, dirname as dirname3 } from "path";
|
|
1247
|
+
import { unlink, readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
|
|
1248
|
+
import { existsSync as existsSync2 } from "fs";
|
|
1107
1249
|
async function removeCommand(componentName) {
|
|
1108
1250
|
const cwd = process.cwd();
|
|
1109
1251
|
const config = await readConfig(cwd);
|
|
@@ -1136,6 +1278,32 @@ async function removeCommand(componentName) {
|
|
|
1136
1278
|
p6.log.warn(`Could not delete ${filePath} (may have been moved or renamed)`);
|
|
1137
1279
|
}
|
|
1138
1280
|
}
|
|
1281
|
+
const baseDir = config.aliases.base ?? "src/ai";
|
|
1282
|
+
const barrelPath = join9(cwd, baseDir, "index.ts");
|
|
1283
|
+
const barrelDir = join9(cwd, baseDir);
|
|
1284
|
+
const barrelEligibleDirs = /* @__PURE__ */ new Set([
|
|
1285
|
+
config.aliases.agents,
|
|
1286
|
+
config.aliases.tools,
|
|
1287
|
+
config.aliases.skills
|
|
1288
|
+
]);
|
|
1289
|
+
if (existsSync2(barrelPath) && deleted.length > 0) {
|
|
1290
|
+
let barrelContent = await readFile7(barrelPath, "utf-8");
|
|
1291
|
+
let barrelChanged = false;
|
|
1292
|
+
for (const filePath of deleted) {
|
|
1293
|
+
const fileDir = dirname3(filePath);
|
|
1294
|
+
if (!barrelEligibleDirs.has(fileDir)) continue;
|
|
1295
|
+
const importPath = "./" + relative3(barrelDir, join9(cwd, filePath)).replace(/\\/g, "/");
|
|
1296
|
+
const updated = removeImportFromBarrel(barrelContent, importPath);
|
|
1297
|
+
if (updated !== barrelContent) {
|
|
1298
|
+
barrelContent = updated;
|
|
1299
|
+
barrelChanged = true;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
if (barrelChanged) {
|
|
1303
|
+
await writeFile7(barrelPath, barrelContent);
|
|
1304
|
+
p6.log.info(`Updated barrel file: ${join9(baseDir, "index.ts")}`);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1139
1307
|
delete config.installed[installedKey];
|
|
1140
1308
|
if (Object.keys(config.installed).length === 0) {
|
|
1141
1309
|
delete config.installed;
|
|
@@ -1151,6 +1319,7 @@ var init_remove = __esm({
|
|
|
1151
1319
|
"use strict";
|
|
1152
1320
|
init_config();
|
|
1153
1321
|
init_parse_ref();
|
|
1322
|
+
init_barrel_manager();
|
|
1154
1323
|
}
|
|
1155
1324
|
});
|
|
1156
1325
|
|
|
@@ -1186,7 +1355,7 @@ var init_update = __esm({
|
|
|
1186
1355
|
});
|
|
1187
1356
|
|
|
1188
1357
|
// src/registry/build-output.ts
|
|
1189
|
-
import { readdir, writeFile as
|
|
1358
|
+
import { readdir, writeFile as writeFile8, mkdir as mkdir4, access as access4 } from "fs/promises";
|
|
1190
1359
|
import { join as join10, resolve } from "path";
|
|
1191
1360
|
async function fileExists(path) {
|
|
1192
1361
|
try {
|
|
@@ -1261,11 +1430,11 @@ async function writeRegistryOutput(outputDir, items) {
|
|
|
1261
1430
|
for (const item of items) {
|
|
1262
1431
|
const dir = typeToDir[item.type];
|
|
1263
1432
|
const typeDir = join10(resolvedOutput, dir);
|
|
1264
|
-
await
|
|
1433
|
+
await mkdir4(typeDir, { recursive: true });
|
|
1265
1434
|
const itemJson = JSON.stringify(item, null, 2);
|
|
1266
1435
|
const latestPath = join10(typeDir, `${item.name}.json`);
|
|
1267
1436
|
const latestRelative = `${dir}/${item.name}.json`;
|
|
1268
|
-
await
|
|
1437
|
+
await writeFile8(latestPath, itemJson, "utf-8");
|
|
1269
1438
|
written.push(latestRelative);
|
|
1270
1439
|
if (item.version) {
|
|
1271
1440
|
const versionedFilename = `${item.name}@${item.version}.json`;
|
|
@@ -1274,7 +1443,7 @@ async function writeRegistryOutput(outputDir, items) {
|
|
|
1274
1443
|
if (await fileExists(versionedPath)) {
|
|
1275
1444
|
skipped.push(versionedRelative);
|
|
1276
1445
|
} else {
|
|
1277
|
-
await
|
|
1446
|
+
await writeFile8(versionedPath, itemJson, "utf-8");
|
|
1278
1447
|
written.push(versionedRelative);
|
|
1279
1448
|
}
|
|
1280
1449
|
}
|
|
@@ -1310,7 +1479,7 @@ async function writeRegistryOutput(outputDir, items) {
|
|
|
1310
1479
|
items: indexItems
|
|
1311
1480
|
};
|
|
1312
1481
|
const indexPath = join10(resolvedOutput, "registry.json");
|
|
1313
|
-
await
|
|
1482
|
+
await writeFile8(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
1314
1483
|
written.push("registry.json");
|
|
1315
1484
|
return { written, skipped };
|
|
1316
1485
|
}
|
|
@@ -1332,8 +1501,8 @@ var init_build_output = __esm({
|
|
|
1332
1501
|
});
|
|
1333
1502
|
|
|
1334
1503
|
// src/registry/builder.ts
|
|
1335
|
-
import { readFile as
|
|
1336
|
-
import { join as join11, relative as
|
|
1504
|
+
import { readFile as readFile9, readdir as readdir2 } from "fs/promises";
|
|
1505
|
+
import { join as join11, relative as relative5 } from "path";
|
|
1337
1506
|
function isExcludedDevDep(name) {
|
|
1338
1507
|
return EXCLUDED_DEV_DEPS.has(name) || name.startsWith("@types/");
|
|
1339
1508
|
}
|
|
@@ -1346,7 +1515,7 @@ async function readTsFiles(dir, baseDir, exclude) {
|
|
|
1346
1515
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
1347
1516
|
for (const entry of entries) {
|
|
1348
1517
|
const fullPath = join11(dir, entry.name);
|
|
1349
|
-
const relPath =
|
|
1518
|
+
const relPath = relative5(baseDir, fullPath);
|
|
1350
1519
|
if (entry.isDirectory()) {
|
|
1351
1520
|
const nested = await readTsFiles(fullPath, baseDir, exclude);
|
|
1352
1521
|
results.push(...nested);
|
|
@@ -1354,7 +1523,7 @@ async function readTsFiles(dir, baseDir, exclude) {
|
|
|
1354
1523
|
if (exclude.includes(relPath)) {
|
|
1355
1524
|
continue;
|
|
1356
1525
|
}
|
|
1357
|
-
const content = await
|
|
1526
|
+
const content = await readFile9(fullPath, "utf-8");
|
|
1358
1527
|
results.push({ relativePath: relPath, content });
|
|
1359
1528
|
}
|
|
1360
1529
|
}
|
|
@@ -1363,7 +1532,7 @@ async function readTsFiles(dir, baseDir, exclude) {
|
|
|
1363
1532
|
async function buildComponent(componentDir) {
|
|
1364
1533
|
let rawConfig;
|
|
1365
1534
|
try {
|
|
1366
|
-
rawConfig = await
|
|
1535
|
+
rawConfig = await readFile9(join11(componentDir, "registry.json"), "utf-8");
|
|
1367
1536
|
} catch {
|
|
1368
1537
|
throw new Error(
|
|
1369
1538
|
`No registry.json found in ${componentDir}. Every component must have a registry.json file.`
|
|
@@ -1379,7 +1548,7 @@ async function buildComponent(componentDir) {
|
|
|
1379
1548
|
}
|
|
1380
1549
|
let pkg = null;
|
|
1381
1550
|
try {
|
|
1382
|
-
const rawPkg = await
|
|
1551
|
+
const rawPkg = await readFile9(join11(componentDir, "package.json"), "utf-8");
|
|
1383
1552
|
pkg = JSON.parse(rawPkg);
|
|
1384
1553
|
} catch {
|
|
1385
1554
|
}
|
|
@@ -1462,7 +1631,7 @@ async function buildComponent(componentDir) {
|
|
|
1462
1631
|
const fullPath = join11(componentDir, filePath);
|
|
1463
1632
|
let content;
|
|
1464
1633
|
try {
|
|
1465
|
-
content = await
|
|
1634
|
+
content = await readFile9(fullPath, "utf-8");
|
|
1466
1635
|
} catch {
|
|
1467
1636
|
throw new Error(
|
|
1468
1637
|
`Cannot read file "${filePath}" referenced in registry.json for component "${name}". Make sure the file exists at ${fullPath}.`
|
|
@@ -1526,7 +1695,7 @@ __export(build_exports, {
|
|
|
1526
1695
|
});
|
|
1527
1696
|
import * as p8 from "@clack/prompts";
|
|
1528
1697
|
import pc7 from "picocolors";
|
|
1529
|
-
import { resolve as resolve2, relative as
|
|
1698
|
+
import { resolve as resolve2, relative as relative6 } from "path";
|
|
1530
1699
|
async function buildCommand(paths, opts) {
|
|
1531
1700
|
p8.intro(pc7.bgCyan(pc7.black(" kitn build ")));
|
|
1532
1701
|
const cwd = process.cwd();
|
|
@@ -1543,7 +1712,7 @@ async function buildCommand(paths, opts) {
|
|
|
1543
1712
|
}
|
|
1544
1713
|
s.stop(`Found ${componentDirs.length} component(s)`);
|
|
1545
1714
|
for (const dir of componentDirs) {
|
|
1546
|
-
p8.log.message(` ${pc7.dim(
|
|
1715
|
+
p8.log.message(` ${pc7.dim(relative6(cwd, dir))}`);
|
|
1547
1716
|
}
|
|
1548
1717
|
s.start("Building components...");
|
|
1549
1718
|
const items = [];
|
|
@@ -1553,7 +1722,7 @@ async function buildCommand(paths, opts) {
|
|
|
1553
1722
|
const item = await buildComponent(dir);
|
|
1554
1723
|
items.push(item);
|
|
1555
1724
|
} catch (err) {
|
|
1556
|
-
errors.push({ dir:
|
|
1725
|
+
errors.push({ dir: relative6(cwd, dir), error: err.message });
|
|
1557
1726
|
}
|
|
1558
1727
|
}
|
|
1559
1728
|
if (errors.length > 0) {
|
|
@@ -1577,7 +1746,7 @@ async function buildCommand(paths, opts) {
|
|
|
1577
1746
|
p8.log.message(` ${pc7.dim("-")} ${f}`);
|
|
1578
1747
|
}
|
|
1579
1748
|
}
|
|
1580
|
-
p8.outro(`Output: ${pc7.cyan(
|
|
1749
|
+
p8.outro(`Output: ${pc7.cyan(relative6(cwd, outputDir) || ".")}`);
|
|
1581
1750
|
}
|
|
1582
1751
|
var init_build = __esm({
|
|
1583
1752
|
"src/commands/build.ts"() {
|
|
@@ -1596,7 +1765,7 @@ __export(create_exports, {
|
|
|
1596
1765
|
import * as p9 from "@clack/prompts";
|
|
1597
1766
|
import pc8 from "picocolors";
|
|
1598
1767
|
import { join as join12 } from "path";
|
|
1599
|
-
import { mkdir as
|
|
1768
|
+
import { mkdir as mkdir5, writeFile as writeFile9 } from "fs/promises";
|
|
1600
1769
|
function toCamelCase(str) {
|
|
1601
1770
|
return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
1602
1771
|
}
|
|
@@ -1622,24 +1791,27 @@ function generateRegistryJson(type, name, sourceFile) {
|
|
|
1622
1791
|
}
|
|
1623
1792
|
function generateAgentSource(name) {
|
|
1624
1793
|
const camel = toCamelCase(name);
|
|
1625
|
-
return `import
|
|
1794
|
+
return `import { registerAgent } from "@kitnai/core";
|
|
1795
|
+
|
|
1796
|
+
const SYSTEM_PROMPT = "You are a helpful assistant.";
|
|
1626
1797
|
|
|
1627
|
-
|
|
1798
|
+
registerAgent({
|
|
1628
1799
|
name: "${name}",
|
|
1629
1800
|
description: "",
|
|
1630
|
-
system:
|
|
1631
|
-
tools:
|
|
1632
|
-
};
|
|
1801
|
+
system: SYSTEM_PROMPT,
|
|
1802
|
+
tools: {},
|
|
1803
|
+
});
|
|
1633
1804
|
`;
|
|
1634
1805
|
}
|
|
1635
1806
|
function generateToolSource(name) {
|
|
1636
1807
|
const camel = toCamelCase(name);
|
|
1637
|
-
return `import {
|
|
1808
|
+
return `import { registerTool } from "@kitnai/core";
|
|
1809
|
+
import { tool } from "ai";
|
|
1638
1810
|
import { z } from "zod";
|
|
1639
1811
|
|
|
1640
1812
|
export const ${camel} = tool({
|
|
1641
1813
|
description: "",
|
|
1642
|
-
|
|
1814
|
+
parameters: z.object({
|
|
1643
1815
|
input: z.string().describe("Input parameter"),
|
|
1644
1816
|
}),
|
|
1645
1817
|
execute: async ({ input }) => {
|
|
@@ -1647,6 +1819,13 @@ export const ${camel} = tool({
|
|
|
1647
1819
|
return { result: input };
|
|
1648
1820
|
},
|
|
1649
1821
|
});
|
|
1822
|
+
|
|
1823
|
+
registerTool({
|
|
1824
|
+
name: "${name}",
|
|
1825
|
+
description: "",
|
|
1826
|
+
inputSchema: z.object({ input: z.string() }),
|
|
1827
|
+
tool: ${camel},
|
|
1828
|
+
});
|
|
1650
1829
|
`;
|
|
1651
1830
|
}
|
|
1652
1831
|
function generateSkillSource(name) {
|
|
@@ -1691,11 +1870,11 @@ async function createComponent(type, name, opts) {
|
|
|
1691
1870
|
if (await dirExists(dir)) {
|
|
1692
1871
|
throw new Error(`Directory "${name}" already exists`);
|
|
1693
1872
|
}
|
|
1694
|
-
await
|
|
1873
|
+
await mkdir5(dir, { recursive: true });
|
|
1695
1874
|
const validType = type;
|
|
1696
1875
|
const sourceFile = validType === "skill" ? "README.md" : `${name}.ts`;
|
|
1697
1876
|
const registryJson = generateRegistryJson(validType, name, sourceFile);
|
|
1698
|
-
await
|
|
1877
|
+
await writeFile9(
|
|
1699
1878
|
join12(dir, "registry.json"),
|
|
1700
1879
|
JSON.stringify(registryJson, null, 2) + "\n"
|
|
1701
1880
|
);
|
|
@@ -1714,7 +1893,7 @@ async function createComponent(type, name, opts) {
|
|
|
1714
1893
|
source = generateStorageSource(name);
|
|
1715
1894
|
break;
|
|
1716
1895
|
}
|
|
1717
|
-
await
|
|
1896
|
+
await writeFile9(join12(dir, sourceFile), source);
|
|
1718
1897
|
return { dir, files: ["registry.json", sourceFile] };
|
|
1719
1898
|
}
|
|
1720
1899
|
async function createCommand(type, name) {
|
|
@@ -2017,7 +2196,7 @@ function startUpdateCheck(currentVersion) {
|
|
|
2017
2196
|
}
|
|
2018
2197
|
|
|
2019
2198
|
// src/index.ts
|
|
2020
|
-
var VERSION = true ? "0.1.
|
|
2199
|
+
var VERSION = true ? "0.1.10" : "0.0.0-dev";
|
|
2021
2200
|
var printUpdateNotice = startUpdateCheck(VERSION);
|
|
2022
2201
|
var program = new Command().name("kitn").description("Install AI agent components from the kitn registry").version(VERSION);
|
|
2023
2202
|
program.command("init").description("Initialize kitn in your project").action(async () => {
|
|
@@ -2028,9 +2207,9 @@ program.command("add").description("Add components from the kitn registry").argu
|
|
|
2028
2207
|
const { addCommand: addCommand2 } = await Promise.resolve().then(() => (init_add(), add_exports));
|
|
2029
2208
|
await addCommand2(components, opts);
|
|
2030
2209
|
});
|
|
2031
|
-
program.command("list").description("List available and installed components").option("-i, --installed", "only show installed components").option("-t, --type <type>", "filter by type (agent, tool, skill, storage, package)").option("-r, --registry <namespace>", "only show components from this registry").action(async (opts) => {
|
|
2210
|
+
program.command("list").argument("[type]", "filter by type (agents, tools, skills, storages, packages)").description("List available and installed components").option("-i, --installed", "only show installed components").option("-t, --type <type>", "filter by type (agent, tool, skill, storage, package)").option("-r, --registry <namespace>", "only show components from this registry").option("-v, --verbose", "show version numbers").action(async (type, opts) => {
|
|
2032
2211
|
const { listCommand: listCommand2 } = await Promise.resolve().then(() => (init_list(), list_exports));
|
|
2033
|
-
await listCommand2(opts);
|
|
2212
|
+
await listCommand2(type, opts);
|
|
2034
2213
|
});
|
|
2035
2214
|
program.command("diff").description("Show differences between local and registry version").argument("<component>", "component name").action(async (component) => {
|
|
2036
2215
|
const { diffCommand: diffCommand2 } = await Promise.resolve().then(() => (init_diff(), diff_exports));
|