@agentskit/cli 0.12.0 → 0.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createCli } from './chunk-X4PVLZSO.js';
2
+ import { createCli } from './chunk-YT74CXQA.js';
3
3
 
4
4
  // src/bin.ts
5
5
  async function main() {
@@ -4030,12 +4030,12 @@ function scaffoldAgent(schema) {
4030
4030
  return files;
4031
4031
  }
4032
4032
  async function writeScaffold(files, outDir, opts = {}) {
4033
- const { writeFile: writeFile3, mkdir: mkdir3, access } = await import('fs/promises');
4034
- const { dirname: dirname2, join: join6 } = await import('path');
4033
+ const { writeFile: writeFile5, mkdir: mkdir5, access } = await import('fs/promises');
4034
+ const { dirname: dirname4, join: join8 } = await import('path');
4035
4035
  const written = [];
4036
4036
  for (const f of files) {
4037
- const full = join6(outDir, f.path);
4038
- await mkdir3(dirname2(full), { recursive: true });
4037
+ const full = join8(outDir, f.path);
4038
+ await mkdir5(dirname4(full), { recursive: true });
4039
4039
  if (!opts.overwrite) {
4040
4040
  try {
4041
4041
  await access(full);
@@ -4043,7 +4043,7 @@ async function writeScaffold(files, outDir, opts = {}) {
4043
4043
  } catch {
4044
4044
  }
4045
4045
  }
4046
- await writeFile3(full, f.content, "utf8");
4046
+ await writeFile5(full, f.content, "utf8");
4047
4047
  written.push(f.path);
4048
4048
  }
4049
4049
  return written;
@@ -4659,6 +4659,261 @@ rules failed: ${message}
4659
4659
  }
4660
4660
  });
4661
4661
  }
4662
+ var RAW_BASE = "https://raw.githubusercontent.com/AgentsKit-io/agentskit-registry/main";
4663
+ var HOSTED_BASE = `${RAW_BASE}/public/r`;
4664
+ async function getJson(url, fetchImpl) {
4665
+ const res = await fetchImpl(url);
4666
+ if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
4667
+ return res.json();
4668
+ }
4669
+ async function getText(url, fetchImpl) {
4670
+ const res = await fetchImpl(url);
4671
+ if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
4672
+ return res.text();
4673
+ }
4674
+ async function fetchAgent(id, options = {}) {
4675
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
4676
+ try {
4677
+ const hosted = await getJson(`${HOSTED_BASE}/${id}.json`, fetchImpl);
4678
+ if (hosted?.sources?.length) return hosted;
4679
+ throw new Error("hosted entry missing sources");
4680
+ } catch {
4681
+ const meta = await getJson(`${RAW_BASE}/registry/${id}/meta.json`, fetchImpl);
4682
+ const sources = await Promise.all(
4683
+ meta.files.map(async (rel) => ({
4684
+ path: rel,
4685
+ content: await getText(`${RAW_BASE}/registry/${id}/${rel}`, fetchImpl)
4686
+ }))
4687
+ );
4688
+ return { ...meta, sources };
4689
+ }
4690
+ }
4691
+ function resolveSystemPrompt(agent) {
4692
+ if (agent.skill?.systemPrompt) return agent.skill.systemPrompt;
4693
+ const src = agent.sources.find((f) => f.path === "agent.ts")?.content;
4694
+ if (!src) return null;
4695
+ const m = src.match(/systemPrompt:\s*`((?:\\.|[^`\\])*)`/);
4696
+ return m ? m[1].replace(/\\`/g, "`").replace(/\\\$\{/g, "${") : null;
4697
+ }
4698
+ async function defaultExists(path5) {
4699
+ const { access } = await import('fs/promises');
4700
+ try {
4701
+ await access(path5);
4702
+ return true;
4703
+ } catch {
4704
+ return false;
4705
+ }
4706
+ }
4707
+ async function addAgent(id, options = {}) {
4708
+ const agent = await fetchAgent(id, options);
4709
+ const baseDir = options.outDir ?? "agents";
4710
+ const targetDir = join(baseDir, id);
4711
+ const exists = options.existsImpl ?? defaultExists;
4712
+ const write = options.writeFileImpl ?? (async (path5, content) => {
4713
+ await mkdir(dirname(path5), { recursive: true });
4714
+ await writeFile(path5, content, "utf8");
4715
+ });
4716
+ const written = [];
4717
+ for (const file of agent.sources) {
4718
+ const dest = join(targetDir, file.path);
4719
+ if (!options.force && await exists(dest)) {
4720
+ throw new Error(`${dest} already exists (re-run with --force to overwrite)`);
4721
+ }
4722
+ await write(dest, file.content);
4723
+ written.push(dest);
4724
+ }
4725
+ return { agent, written, targetDir };
4726
+ }
4727
+ function lineDiff(a, b) {
4728
+ const x = a.split("\n");
4729
+ const y = b.split("\n");
4730
+ const m = x.length;
4731
+ const n = y.length;
4732
+ const lcs = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
4733
+ for (let i2 = m - 1; i2 >= 0; i2--) {
4734
+ for (let j2 = n - 1; j2 >= 0; j2--) {
4735
+ lcs[i2][j2] = x[i2] === y[j2] ? lcs[i2 + 1][j2 + 1] + 1 : Math.max(lcs[i2 + 1][j2], lcs[i2][j2 + 1]);
4736
+ }
4737
+ }
4738
+ const out = [];
4739
+ let i = 0;
4740
+ let j = 0;
4741
+ while (i < m && j < n) {
4742
+ if (x[i] === y[j]) {
4743
+ out.push({ type: " ", text: x[i] });
4744
+ i++;
4745
+ j++;
4746
+ } else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
4747
+ out.push({ type: "-", text: x[i++] });
4748
+ } else {
4749
+ out.push({ type: "+", text: y[j++] });
4750
+ }
4751
+ }
4752
+ while (i < m) out.push({ type: "-", text: x[i++] });
4753
+ while (j < n) out.push({ type: "+", text: y[j++] });
4754
+ return out;
4755
+ }
4756
+ async function diffAgent(id, options = {}) {
4757
+ const agent = await fetchAgent(id, options);
4758
+ const targetDir = join(options.outDir ?? "agents", id);
4759
+ const readLocal = options.readFileImpl ?? (async (p) => {
4760
+ const { readFile: readFile6 } = await import('fs/promises');
4761
+ try {
4762
+ return await readFile6(p, "utf8");
4763
+ } catch {
4764
+ return null;
4765
+ }
4766
+ });
4767
+ const files = [];
4768
+ for (const f of agent.sources) {
4769
+ const local = await readLocal(join(targetDir, f.path));
4770
+ if (local == null) {
4771
+ files.push({ path: f.path, status: "missing-local", upstream: f.content });
4772
+ } else if (local === f.content) {
4773
+ files.push({ path: f.path, status: "unchanged", upstream: f.content });
4774
+ } else {
4775
+ files.push({ path: f.path, status: "modified", diff: lineDiff(local, f.content), upstream: f.content });
4776
+ }
4777
+ }
4778
+ return { agent, targetDir, files };
4779
+ }
4780
+
4781
+ // src/commands/add.ts
4782
+ function registerAddCommand(program) {
4783
+ program.command("add <agent>").description(
4784
+ 'Add a ready-made agent from the AgentsKit registry (registry.agentskit.io). Copies the agent source into your project \u2014 you own the code. With --run, also executes it. e.g. `agentskit add research` or `agentskit add legal-contract-reviewer --run "review this NDA\u2026" --provider ollama`.'
4785
+ ).option("--out <dir>", "Directory to write the agent into (default: ./agents)").option("-f, --force", "Overwrite existing files").option("--run <task>", "Run the agent on this task right after adding it").option("--provider <provider>", "Provider for --run (openai, anthropic, gemini, ollama, demo)", "demo").option("--model <model>", "Model for --run").option("--api-key <key>", "API key for --run (else read from the provider env var)").action(
4786
+ async (agent, options) => {
4787
+ try {
4788
+ const result = await addAgent(agent, { outDir: options.out, force: options.force === true });
4789
+ process.stdout.write(`
4790
+ Added "${result.agent.title}" \u2192 ${result.targetDir}/
4791
+ `);
4792
+ for (const f of result.written) process.stdout.write(` wrote ${f}
4793
+ `);
4794
+ if (result.agent.packages.length > 0) {
4795
+ process.stdout.write(`
4796
+ Install the packages it uses:
4797
+ `);
4798
+ process.stdout.write(` npm install ${result.agent.packages.join(" ")} @agentskit/adapters
4799
+ `);
4800
+ }
4801
+ const required = (result.agent.env ?? []).filter((e) => e.required);
4802
+ if (required.length > 0) {
4803
+ process.stdout.write(`
4804
+ Required environment:
4805
+ `);
4806
+ for (const e of required) process.stdout.write(` ${e.name} \u2014 ${e.description}
4807
+ `);
4808
+ }
4809
+ const readme2 = result.written.find((f) => f.toLowerCase().endsWith("readme.md"));
4810
+ process.stdout.write(readme2 ? `
4811
+ See ${readme2} for usage.
4812
+ ` : "\n");
4813
+ if (options.run) {
4814
+ const systemPrompt = resolveSystemPrompt(result.agent);
4815
+ if (!systemPrompt) {
4816
+ process.stderr.write(
4817
+ `
4818
+ --run is not supported for "${agent}" (it composes tools/keys). Use it as a library \u2014 see the README.
4819
+ `
4820
+ );
4821
+ process.exit(1);
4822
+ }
4823
+ process.stdout.write(`
4824
+ Running "${result.agent.title}" via ${options.provider}\u2026
4825
+
4826
+ `);
4827
+ await runAgent(options.run, {
4828
+ provider: options.provider,
4829
+ model: options.model,
4830
+ apiKey: options.apiKey,
4831
+ systemPrompt,
4832
+ maxSteps: "8"
4833
+ });
4834
+ }
4835
+ } catch (err) {
4836
+ const message = err instanceof Error ? err.message : String(err);
4837
+ process.stderr.write(`
4838
+ add failed: ${message}
4839
+ `);
4840
+ process.stderr.write(`(browse agents at https://registry.agentskit.io)
4841
+ `);
4842
+ process.exit(1);
4843
+ }
4844
+ }
4845
+ );
4846
+ }
4847
+ function registerDiffCommand(program) {
4848
+ program.command("diff <agent>").description("Show how your local copy of a registry agent differs from the current registry source.").option("--out <dir>", "Directory the agent was added into (default: ./agents)").action(async (agent, options) => {
4849
+ try {
4850
+ const { targetDir, files } = await diffAgent(agent, { outDir: options.out });
4851
+ let changed = 0;
4852
+ for (const f of files) {
4853
+ if (f.status === "unchanged") continue;
4854
+ changed++;
4855
+ process.stdout.write(`
4856
+ ${f.status === "missing-local" ? "missing" : "modified"}: ${join(targetDir, f.path)}
4857
+ `);
4858
+ if (f.diff) {
4859
+ for (const line of f.diff) {
4860
+ if (line.type === " ") continue;
4861
+ process.stdout.write(` ${line.type} ${line.text}
4862
+ `);
4863
+ }
4864
+ }
4865
+ }
4866
+ process.stdout.write(
4867
+ changed === 0 ? `
4868
+ ${agent}: up to date with the registry.
4869
+ ` : `
4870
+ ${changed} file(s) differ. Run \`agentskit update ${agent}\` to apply the registry version.
4871
+ `
4872
+ );
4873
+ } catch (err) {
4874
+ process.stderr.write(`
4875
+ diff failed: ${err instanceof Error ? err.message : String(err)}
4876
+ `);
4877
+ process.exit(1);
4878
+ }
4879
+ });
4880
+ }
4881
+ function registerUpdateCommand(program) {
4882
+ program.command("update <agent>").description("Update your local copy of a registry agent to the current registry source.").option("--out <dir>", "Directory the agent was added into (default: ./agents)").option("-f, --force", "Apply without listing the changes first").action(async (agent, options) => {
4883
+ try {
4884
+ const { targetDir, files } = await diffAgent(agent, { outDir: options.out });
4885
+ const changed = files.filter((f) => f.status !== "unchanged");
4886
+ if (changed.length === 0) {
4887
+ process.stdout.write(`
4888
+ ${agent}: already up to date.
4889
+ `);
4890
+ return;
4891
+ }
4892
+ if (!options.force) {
4893
+ process.stdout.write(`
4894
+ Will overwrite ${changed.length} file(s) with the registry version:
4895
+ `);
4896
+ for (const f of changed) process.stdout.write(` ${f.path} (${f.status})
4897
+ `);
4898
+ }
4899
+ for (const f of changed) {
4900
+ const dest = join(targetDir, f.path);
4901
+ await mkdir(dirname(dest), { recursive: true });
4902
+ await writeFile(dest, f.upstream, "utf8");
4903
+ process.stdout.write(` updated ${dest}
4904
+ `);
4905
+ }
4906
+ process.stdout.write(`
4907
+ Updated ${agent}. Review the changes with your VCS before committing.
4908
+ `);
4909
+ } catch (err) {
4910
+ process.stderr.write(`
4911
+ update failed: ${err instanceof Error ? err.message : String(err)}
4912
+ `);
4913
+ process.exit(1);
4914
+ }
4915
+ });
4916
+ }
4662
4917
 
4663
4918
  // src/commands/index.ts
4664
4919
  function createCli() {
@@ -4676,9 +4931,12 @@ function createCli() {
4676
4931
  registerFlowCommand(program);
4677
4932
  registerPiiCommand(program);
4678
4933
  registerRulesCommand(program);
4934
+ registerAddCommand(program);
4935
+ registerDiffCommand(program);
4936
+ registerUpdateCommand(program);
4679
4937
  return program;
4680
4938
  }
4681
4939
 
4682
4940
  export { ChatApp, HookDispatcher, McpClient, applyPolicyToTool, applyPolicyToTools, bridgeMcpServers, buildRagFromConfig, computeCost, configHooksToHandlers, createCli, createOpenAiEmbedder, defaultPolicy, derivePreview, disposeMcpClients, evaluatePolicy, findLatestSession, findSession, forkSession, generateSessionId, getPricing, indexSources, listSessions, loadConfig, loadPlugins, mergePluginsIntoBundle, registerPricing, renameSession, renderChatHeader, renderReport, resolveChatProvider, resolveSession, runAgent, runDoctor, sessionFilePath, startDev, startTunnel, writeSessionMeta, writeStarterProject };
4683
- //# sourceMappingURL=chunk-X4PVLZSO.js.map
4684
- //# sourceMappingURL=chunk-X4PVLZSO.js.map
4941
+ //# sourceMappingURL=chunk-YT74CXQA.js.map
4942
+ //# sourceMappingURL=chunk-YT74CXQA.js.map