@actant/cli 0.1.3 → 0.2.1

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.
@@ -1,5 +1,5 @@
1
1
  // src/program.ts
2
- import { Command as Command73 } from "commander";
2
+ import { Command as Command75 } from "commander";
3
3
  import { readFileSync as readFileSync4 } from "fs";
4
4
  import { join as join7 } from "path";
5
5
  import { getDefaultIpcPath as getDefaultIpcPath2 } from "@actant/shared";
@@ -116,7 +116,7 @@ function formatTemplateList(templates, format) {
116
116
  t.name,
117
117
  t.version,
118
118
  t.backend.type,
119
- t.provider.type,
119
+ t.provider?.type ?? chalk.dim("(default)"),
120
120
  t.description ?? chalk.dim("\u2014")
121
121
  ]);
122
122
  }
@@ -134,7 +134,7 @@ function formatTemplateDetail(template, format) {
134
134
  `${chalk.bold("Template:")} ${template.name}`,
135
135
  `${chalk.bold("Version:")} ${template.version}`,
136
136
  `${chalk.bold("Backend:")} ${template.backend.type}`,
137
- `${chalk.bold("Provider:")} ${template.provider.type}`
137
+ `${chalk.bold("Provider:")} ${template.provider?.type ?? "(default)"}`
138
138
  ];
139
139
  if (template.description) {
140
140
  lines.push(`${chalk.bold("Desc:")} ${template.description}`);
@@ -574,19 +574,56 @@ function createTemplateLoadCommand(client, printer = defaultPrinter) {
574
574
 
575
575
  // src/commands/template/install.ts
576
576
  import { Command as Command5 } from "commander";
577
- function createTemplateInstallCommand(_client, printer = defaultPrinter) {
578
- return new Command5("install").description("Install a template from a source (source@name)").argument("<spec>", "Source and template name, e.g. my-source@my-template").action(async (spec) => {
577
+ import chalk7 from "chalk";
578
+ var DEFAULT_SOURCE = "actant-hub";
579
+ function createTemplateInstallCommand(client, printer = defaultPrinter) {
580
+ return new Command5("install").description("Install a template from a source (source@name or just name for default source)").argument("<spec>", 'Template spec: "source@name" or just "name" (uses actant-hub)').action(async (spec) => {
579
581
  try {
580
582
  const at = spec.indexOf("@");
581
- if (at < 0) {
582
- printer.error("Expected format: <source>@<name>");
583
+ const sourceName = at >= 0 ? spec.slice(0, at) : DEFAULT_SOURCE;
584
+ const templateName = at >= 0 ? spec.slice(at + 1) : spec;
585
+ const qualifiedName = `${sourceName}@${templateName}`;
586
+ printer.log(chalk7.dim(` Syncing source "${sourceName}"...`));
587
+ try {
588
+ await client.call("source.sync", { name: sourceName });
589
+ } catch (err) {
590
+ const msg = err instanceof Error ? err.message : String(err);
591
+ if (!msg.includes("not found")) {
592
+ printer.warn(` Warning: sync failed (${msg}), checking local cache...`);
593
+ } else {
594
+ printer.error(`Source "${sourceName}" not found. Add it first: actant source add <url> --name ${sourceName}`);
595
+ process.exitCode = 1;
596
+ return;
597
+ }
598
+ }
599
+ try {
600
+ const template = await client.call("template.get", { name: qualifiedName });
601
+ printer.success(` Template "${qualifiedName}" is available.`);
602
+ printer.log("");
603
+ printer.log(` ${chalk7.bold("Name:")} ${template.name}`);
604
+ if (template.description) {
605
+ printer.log(` ${chalk7.bold("Description:")} ${template.description}`);
606
+ }
607
+ printer.log(` ${chalk7.bold("Backend:")} ${template.backend.type}`);
608
+ printer.log(` ${chalk7.bold("Version:")} ${template.version}`);
609
+ printer.log("");
610
+ printer.log(` Create an agent: ${chalk7.cyan(`actant agent create <agent-name> --template ${qualifiedName}`)}`);
611
+ } catch {
612
+ printer.error(`Template "${qualifiedName}" not found in source "${sourceName}".`);
613
+ printer.log(chalk7.dim(" Available templates:"));
614
+ try {
615
+ const templates = await client.call("template.list", {});
616
+ const fromSource = templates.filter((t) => t.name.startsWith(`${sourceName}@`));
617
+ for (const t of fromSource) {
618
+ printer.log(chalk7.dim(` - ${t.name}`));
619
+ }
620
+ if (fromSource.length === 0) {
621
+ printer.log(chalk7.dim(" (none from this source)"));
622
+ }
623
+ } catch {
624
+ }
583
625
  process.exitCode = 1;
584
- return;
585
626
  }
586
- const source = spec.slice(0, at);
587
- printer.log(
588
- `Template install not yet implemented via RPC - use "actant source sync ${source}" to sync templates from the source.`
589
- );
590
627
  } catch (err) {
591
628
  presentError(err, printer);
592
629
  process.exitCode = 1;
@@ -606,14 +643,14 @@ function createTemplateCommand(client, printer) {
606
643
  }
607
644
 
608
645
  // src/commands/agent/index.ts
609
- import { Command as Command23 } from "commander";
646
+ import { Command as Command24 } from "commander";
610
647
 
611
648
  // src/commands/agent/create.ts
612
649
  import { existsSync } from "fs";
613
650
  import { resolve as resolve3 } from "path";
614
651
  import { createInterface } from "readline";
615
652
  import { Command as Command7 } from "commander";
616
- import chalk7 from "chalk";
653
+ import chalk8 from "chalk";
617
654
  var VALID_LAUNCH_MODES = /* @__PURE__ */ new Set(["direct", "acp-background", "acp-service", "one-shot"]);
618
655
  function askQuestion(question) {
619
656
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -628,12 +665,12 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
628
665
  return new Command7("create").description("Create a new agent from a template").argument("<name>", "Agent instance name").requiredOption("-t, --template <template>", "Template name to use").option("--launch-mode <mode>", "Launch mode: direct, acp-background, acp-service, one-shot").option("--work-dir <path>", "Custom workspace directory (absolute or relative path)").option("--workspace <path>", "Same as --work-dir: create instance at external path instead of builtin location").option("--overwrite", "If work-dir exists, remove it and recreate").option("--append", "If work-dir exists, add agent files into it").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
629
666
  try {
630
667
  if (opts.launchMode && !VALID_LAUNCH_MODES.has(opts.launchMode)) {
631
- printer.error(`${chalk7.red(`Invalid launch mode: ${opts.launchMode}`)}`);
668
+ printer.error(`${chalk8.red(`Invalid launch mode: ${opts.launchMode}`)}`);
632
669
  process.exitCode = 1;
633
670
  return;
634
671
  }
635
672
  if (opts.overwrite && opts.append) {
636
- printer.error(`${chalk7.red("Cannot use both --overwrite and --append")}`);
673
+ printer.error(`${chalk8.red("Cannot use both --overwrite and --append")}`);
637
674
  process.exitCode = 1;
638
675
  return;
639
676
  }
@@ -648,7 +685,7 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
648
685
  } else {
649
686
  printer.warn(`Directory already exists: ${workDir}`);
650
687
  const answer = await askQuestion(
651
- ` ${chalk7.yellow("(o)")}verwrite / ${chalk7.cyan("(a)")}ppend / ${chalk7.dim("(c)")}ancel? `
688
+ ` ${chalk8.yellow("(o)")}verwrite / ${chalk8.cyan("(a)")}ppend / ${chalk8.dim("(c)")}ancel? `
652
689
  );
653
690
  if (answer === "o" || answer === "overwrite") {
654
691
  workDirConflict = "overwrite";
@@ -669,7 +706,7 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
669
706
  template: opts.template,
670
707
  overrides: Object.keys(overrides).length > 0 ? overrides : void 0
671
708
  });
672
- printer.log(`${chalk7.green("Agent created successfully.")}
709
+ printer.log(`${chalk8.green("Agent created successfully.")}
673
710
  `);
674
711
  printer.log(formatAgentDetail(meta, opts.format));
675
712
  } catch (err) {
@@ -681,12 +718,12 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
681
718
 
682
719
  // src/commands/agent/start.ts
683
720
  import { Command as Command8 } from "commander";
684
- import chalk8 from "chalk";
721
+ import chalk9 from "chalk";
685
722
  function createAgentStartCommand(client, printer = defaultPrinter) {
686
723
  return new Command8("start").description("Start an agent").argument("<name>", "Agent name").action(async (name) => {
687
724
  try {
688
725
  await client.call("agent.start", { name });
689
- printer.log(`${chalk8.green("Started")} ${name}`);
726
+ printer.log(`${chalk9.green("Started")} ${name}`);
690
727
  } catch (err) {
691
728
  presentError(err, printer);
692
729
  process.exitCode = 1;
@@ -696,12 +733,12 @@ function createAgentStartCommand(client, printer = defaultPrinter) {
696
733
 
697
734
  // src/commands/agent/stop.ts
698
735
  import { Command as Command9 } from "commander";
699
- import chalk9 from "chalk";
736
+ import chalk10 from "chalk";
700
737
  function createAgentStopCommand(client, printer = defaultPrinter) {
701
738
  return new Command9("stop").description("Stop a running agent").argument("<name>", "Agent name").action(async (name) => {
702
739
  try {
703
740
  await client.call("agent.stop", { name });
704
- printer.log(`${chalk9.green("Stopped")} ${name}`);
741
+ printer.log(`${chalk10.green("Stopped")} ${name}`);
705
742
  } catch (err) {
706
743
  presentError(err, printer);
707
744
  process.exitCode = 1;
@@ -743,7 +780,7 @@ function createAgentListCommand(client, printer = defaultPrinter) {
743
780
  }
744
781
 
745
782
  // src/commands/agent/adopt.ts
746
- import chalk10 from "chalk";
783
+ import chalk11 from "chalk";
747
784
  import { Command as Command12 } from "commander";
748
785
  function formatAdoptResult(result, format) {
749
786
  if (format === "json") {
@@ -753,14 +790,14 @@ function formatAdoptResult(result, format) {
753
790
  return result.name;
754
791
  }
755
792
  const lines = [
756
- chalk10.green("Agent adopted successfully."),
793
+ chalk11.green("Agent adopted successfully."),
757
794
  "",
758
- `${chalk10.bold("Name:")} ${result.name}`,
759
- `${chalk10.bold("Template:")} ${result.template}`,
760
- `${chalk10.bold("Workspace:")} ${result.workspacePath}`,
761
- `${chalk10.bold("Location:")} ${result.location}`,
762
- `${chalk10.bold("Status:")} ${result.status}`,
763
- `${chalk10.bold("Created:")} ${result.createdAt}`
795
+ `${chalk11.bold("Name:")} ${result.name}`,
796
+ `${chalk11.bold("Template:")} ${result.template}`,
797
+ `${chalk11.bold("Workspace:")} ${result.workspacePath}`,
798
+ `${chalk11.bold("Location:")} ${result.location}`,
799
+ `${chalk11.bold("Status:")} ${result.status}`,
800
+ `${chalk11.bold("Created:")} ${result.createdAt}`
764
801
  ];
765
802
  return lines.join("\n");
766
803
  }
@@ -781,7 +818,7 @@ function createAgentAdoptCommand(client, printer = defaultPrinter) {
781
818
 
782
819
  // src/commands/agent/destroy.ts
783
820
  import { Command as Command13 } from "commander";
784
- import chalk11 from "chalk";
821
+ import chalk12 from "chalk";
785
822
  function createAgentDestroyCommand(client, printer = defaultPrinter) {
786
823
  return new Command13("destroy").alias("rm").description("Destroy an agent (removes workspace directory)").argument("<name>", "Agent name").option("--force", "Skip confirmation", false).action(async (name, opts) => {
787
824
  if (!opts.force) {
@@ -792,7 +829,7 @@ function createAgentDestroyCommand(client, printer = defaultPrinter) {
792
829
  }
793
830
  try {
794
831
  await client.call("agent.destroy", { name });
795
- printer.log(`${chalk11.green("Destroyed")} ${name}`);
832
+ printer.log(`${chalk12.green("Destroyed")} ${name}`);
796
833
  } catch (err) {
797
834
  presentError(err, printer);
798
835
  process.exitCode = 1;
@@ -802,7 +839,7 @@ function createAgentDestroyCommand(client, printer = defaultPrinter) {
802
839
 
803
840
  // src/commands/agent/resolve.ts
804
841
  import { Command as Command14 } from "commander";
805
- import chalk12 from "chalk";
842
+ import chalk13 from "chalk";
806
843
  function createAgentResolveCommand(client, printer = defaultPrinter) {
807
844
  return new Command14("resolve").description("Resolve spawn info for an agent (external spawn support)").argument("<name>", "Agent instance name").option("-t, --template <template>", "Template name (auto-creates instance if not found)").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
808
845
  try {
@@ -816,16 +853,16 @@ function createAgentResolveCommand(client, printer = defaultPrinter) {
816
853
  printer.log([result.command, ...result.args].join(" "));
817
854
  } else {
818
855
  if (result.created) {
819
- printer.log(`${chalk12.green("Instance created.")}
856
+ printer.log(`${chalk13.green("Instance created.")}
820
857
  `);
821
858
  }
822
- printer.log(`${chalk12.bold("Instance:")} ${result.instanceName}`);
823
- printer.log(`${chalk12.bold("Backend:")} ${result.backendType}`);
824
- printer.log(`${chalk12.bold("Workspace:")} ${result.workspaceDir}`);
825
- printer.log(`${chalk12.bold("Command:")} ${result.command}`);
826
- printer.log(`${chalk12.bold("Args:")} ${result.args.join(" ")}`);
859
+ printer.log(`${chalk13.bold("Instance:")} ${result.instanceName}`);
860
+ printer.log(`${chalk13.bold("Backend:")} ${result.backendType}`);
861
+ printer.log(`${chalk13.bold("Workspace:")} ${result.workspaceDir}`);
862
+ printer.log(`${chalk13.bold("Command:")} ${result.command}`);
863
+ printer.log(`${chalk13.bold("Args:")} ${result.args.join(" ")}`);
827
864
  if (result.env && Object.keys(result.env).length > 0) {
828
- printer.log(chalk12.bold("Env:"));
865
+ printer.log(chalk13.bold("Env:"));
829
866
  for (const [k, v] of Object.entries(result.env)) {
830
867
  printer.log(` ${k}=${v}`);
831
868
  }
@@ -838,15 +875,32 @@ function createAgentResolveCommand(client, printer = defaultPrinter) {
838
875
  });
839
876
  }
840
877
 
841
- // src/commands/agent/attach.ts
878
+ // src/commands/agent/open.ts
879
+ import { spawn } from "child_process";
842
880
  import { Command as Command15 } from "commander";
843
- import chalk13 from "chalk";
881
+ import chalk14 from "chalk";
882
+ function createAgentOpenCommand(client, printer = defaultPrinter) {
883
+ return new Command15("open").description("Open an agent's native TUI/UI (e.g. Cursor IDE)").argument("<name>", "Agent name").action(async (name) => {
884
+ try {
885
+ const result = await client.call("agent.open", { name });
886
+ printer.log(`${chalk14.green("Opening")} ${name} \u2192 ${result.command} ${result.args.join(" ")}`);
887
+ spawn(result.command, result.args, { detached: true, stdio: "ignore" }).unref();
888
+ } catch (err) {
889
+ presentError(err, printer);
890
+ process.exitCode = 1;
891
+ }
892
+ });
893
+ }
894
+
895
+ // src/commands/agent/attach.ts
896
+ import { Command as Command16 } from "commander";
897
+ import chalk15 from "chalk";
844
898
  function createAgentAttachCommand(client, printer = defaultPrinter) {
845
- return new Command15("attach").description("Attach an externally-spawned process to an agent").argument("<name>", "Agent instance name").requiredOption("--pid <pid>", "Process ID of the externally-spawned agent").option("--metadata <json>", "Additional metadata as JSON object").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
899
+ return new Command16("attach").description("Attach an externally-spawned process to an agent").argument("<name>", "Agent instance name").requiredOption("--pid <pid>", "Process ID of the externally-spawned agent").option("--metadata <json>", "Additional metadata as JSON object").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
846
900
  try {
847
901
  const pid = parseInt(opts.pid, 10);
848
902
  if (isNaN(pid) || pid <= 0) {
849
- printer.error(chalk13.red("Invalid PID: must be a positive integer"));
903
+ printer.error(chalk15.red("Invalid PID: must be a positive integer"));
850
904
  process.exitCode = 1;
851
905
  return;
852
906
  }
@@ -855,13 +909,13 @@ function createAgentAttachCommand(client, printer = defaultPrinter) {
855
909
  try {
856
910
  metadata = JSON.parse(opts.metadata);
857
911
  } catch {
858
- printer.error(chalk13.red("Invalid --metadata: must be valid JSON"));
912
+ printer.error(chalk15.red("Invalid --metadata: must be valid JSON"));
859
913
  process.exitCode = 1;
860
914
  return;
861
915
  }
862
916
  }
863
917
  const meta = await client.call("agent.attach", { name, pid, metadata });
864
- printer.log(`${chalk13.green("Process attached.")}
918
+ printer.log(`${chalk15.green("Process attached.")}
865
919
  `);
866
920
  printer.log(formatAgentDetail(meta, opts.format));
867
921
  } catch (err) {
@@ -872,9 +926,9 @@ function createAgentAttachCommand(client, printer = defaultPrinter) {
872
926
  }
873
927
 
874
928
  // src/commands/agent/detach.ts
875
- import { Command as Command16 } from "commander";
929
+ import { Command as Command17 } from "commander";
876
930
  function createAgentDetachCommand(client, printer = defaultPrinter) {
877
- return new Command16("detach").description("Detach an externally-managed process from an agent").argument("<name>", "Agent instance name").option("--cleanup", "Clean up ephemeral workspace after detach").action(async (name, opts) => {
931
+ return new Command17("detach").description("Detach an externally-managed process from an agent").argument("<name>", "Agent instance name").option("--cleanup", "Clean up ephemeral workspace after detach").action(async (name, opts) => {
878
932
  try {
879
933
  const result = await client.call("agent.detach", {
880
934
  name,
@@ -892,9 +946,9 @@ function createAgentDetachCommand(client, printer = defaultPrinter) {
892
946
  }
893
947
 
894
948
  // src/commands/agent/run.ts
895
- import { Command as Command17 } from "commander";
949
+ import { Command as Command18 } from "commander";
896
950
  function createAgentRunCommand(client, printer = defaultPrinter) {
897
- return new Command17("run").description("Send a prompt to an agent and get the response").argument("<name>", "Agent name").requiredOption("--prompt <prompt>", "The prompt to send").option("--model <model>", "Model to use (e.g. sonnet, opus)").option("--max-turns <turns>", "Maximum agentic turns", parseInt).option("--timeout <ms>", "Timeout in milliseconds", parseInt).option("--session-id <id>", "Resume a specific session").option("-f, --format <format>", "Output format: text, json", "text").action(async (name, opts) => {
951
+ return new Command18("run").description("Send a prompt to an agent and get the response").argument("<name>", "Agent name").requiredOption("--prompt <prompt>", "The prompt to send").option("--model <model>", "Model to use (e.g. sonnet, opus)").option("--max-turns <turns>", "Maximum agentic turns", parseInt).option("--timeout <ms>", "Timeout in milliseconds", parseInt).option("--session-id <id>", "Resume a specific session").option("-f, --format <format>", "Output format: text, json", "text").action(async (name, opts) => {
898
952
  try {
899
953
  const rpcTimeout = (opts.timeout ?? 3e5) + 5e3;
900
954
  const result = await client.call("agent.run", {
@@ -920,9 +974,9 @@ function createAgentRunCommand(client, printer = defaultPrinter) {
920
974
  }
921
975
 
922
976
  // src/commands/agent/prompt.ts
923
- import { Command as Command18 } from "commander";
977
+ import { Command as Command19 } from "commander";
924
978
  function createAgentPromptCommand(client, printer = defaultPrinter) {
925
- return new Command18("prompt").description("Send a message to a running agent's ACP session").argument("<name>", "Agent name (must be started with `agent start`)").requiredOption("-m, --message <message>", "The message to send").option("--session-id <id>", "Specific ACP session ID (uses primary session if omitted)").option("-f, --format <format>", "Output format: text, json", "text").action(async (name, opts) => {
979
+ return new Command19("prompt").description("Send a message to a running agent's ACP session").argument("<name>", "Agent name (must be started with `agent start`)").requiredOption("-m, --message <message>", "The message to send").option("--session-id <id>", "Specific ACP session ID (uses primary session if omitted)").option("-f, --format <format>", "Output format: text, json", "text").action(async (name, opts) => {
926
980
  try {
927
981
  const result = await client.call("agent.prompt", {
928
982
  name,
@@ -943,11 +997,11 @@ function createAgentPromptCommand(client, printer = defaultPrinter) {
943
997
 
944
998
  // src/commands/agent/chat.ts
945
999
  import { createInterface as createInterface2 } from "readline";
946
- import { Command as Command19 } from "commander";
947
- import chalk14 from "chalk";
1000
+ import { Command as Command20 } from "commander";
1001
+ import chalk16 from "chalk";
948
1002
  import { AcpConnection } from "@actant/acp";
949
1003
  function createAgentChatCommand(client, printer = defaultPrinter) {
950
- return new Command19("chat").description("Start an interactive chat session with an agent").argument("<name>", "Agent name").option("-t, --template <template>", "Template name (auto-creates instance if not found)").action(async (name, opts) => {
1004
+ return new Command20("chat").description("Start an interactive chat session with an agent").argument("<name>", "Agent name").option("-t, --template <template>", "Template name (auto-creates instance if not found)").action(async (name, opts) => {
951
1005
  try {
952
1006
  await runChat(client, name, opts, printer);
953
1007
  } catch (err) {
@@ -980,9 +1034,9 @@ async function runChat(client, name, opts, printer) {
980
1034
  async function runDaemonChat(client, name, printer) {
981
1035
  const meta = await client.call("agent.status", { name });
982
1036
  printer.log(
983
- chalk14.bold(`Chat with ${meta.name}`) + chalk14.dim(` (${meta.templateName}@${meta.templateVersion}) [daemon-managed]`)
1037
+ chalk16.bold(`Chat with ${meta.name}`) + chalk16.dim(` (${meta.templateName}@${meta.templateVersion}) [daemon-managed]`)
984
1038
  );
985
- printer.log(chalk14.dim('Type your message and press Enter. Use "exit" or Ctrl+C to quit.\n'));
1039
+ printer.log(chalk16.dim('Type your message and press Enter. Use "exit" or Ctrl+C to quit.\n'));
986
1040
  const rl = createReadline();
987
1041
  rl.prompt();
988
1042
  let sessionId;
@@ -997,7 +1051,7 @@ async function runDaemonChat(client, name, printer) {
997
1051
  return;
998
1052
  }
999
1053
  try {
1000
- process.stdout.write(chalk14.cyan("agent> "));
1054
+ process.stdout.write(chalk16.cyan("agent> "));
1001
1055
  const result = await client.call("agent.prompt", {
1002
1056
  name,
1003
1057
  message: trimmed,
@@ -1011,7 +1065,7 @@ async function runDaemonChat(client, name, printer) {
1011
1065
  rl.prompt();
1012
1066
  });
1013
1067
  rl.on("close", () => {
1014
- process.stdout.write(chalk14.dim("\nChat ended.\n"));
1068
+ process.stdout.write(chalk16.dim("\nChat ended.\n"));
1015
1069
  });
1016
1070
  return new Promise((resolve9) => {
1017
1071
  rl.on("close", resolve9);
@@ -1035,7 +1089,19 @@ async function runDirectBridgeChat(client, name, opts, printer) {
1035
1089
  }
1036
1090
  };
1037
1091
  try {
1038
- await conn.spawn(resolved.command, resolved.args, resolved.workspaceDir);
1092
+ try {
1093
+ await conn.spawn(resolved.command, resolved.args, resolved.workspaceDir);
1094
+ } catch (spawnErr) {
1095
+ const msg = spawnErr instanceof Error ? spawnErr.message : String(spawnErr);
1096
+ if (/ENOENT|EINVAL|is not recognized|not found/i.test(msg)) {
1097
+ throw new Error(
1098
+ `Cannot start "${resolved.command}". Is it installed?
1099
+ ` + (resolved.backendType === "claude-code" ? ` Install with: npm install -g @zed-industries/claude-agent-acp` : ` Ensure the backend CLI is installed and in your PATH.`),
1100
+ { cause: spawnErr }
1101
+ );
1102
+ }
1103
+ throw spawnErr;
1104
+ }
1039
1105
  await client.call("agent.attach", {
1040
1106
  name: resolved.instanceName,
1041
1107
  pid: process.pid,
@@ -1047,9 +1113,9 @@ async function runDirectBridgeChat(client, name, opts, printer) {
1047
1113
  const agentName = initResult.agentInfo?.name ?? name;
1048
1114
  session = await conn.newSession(resolved.workspaceDir);
1049
1115
  printer.log(
1050
- chalk14.bold(`Chat with ${agentName}`) + chalk14.dim(` (direct bridge, session ${session.sessionId.slice(0, 8)}...)`)
1116
+ chalk16.bold(`Chat with ${agentName}`) + chalk16.dim(` (direct bridge, session ${session.sessionId.slice(0, 8)}...)`)
1051
1117
  );
1052
- printer.log(chalk14.dim('Type your message and press Enter. Use "exit" or Ctrl+C to quit.\n'));
1118
+ printer.log(chalk16.dim('Type your message and press Enter. Use "exit" or Ctrl+C to quit.\n'));
1053
1119
  const rl = createReadline();
1054
1120
  process.on("SIGINT", () => {
1055
1121
  if (session) {
@@ -1081,7 +1147,7 @@ async function runDirectBridgeChat(client, name, opts, printer) {
1081
1147
  rl.prompt();
1082
1148
  });
1083
1149
  rl.on("close", () => {
1084
- process.stdout.write(chalk14.dim("\nChat ended.\n"));
1150
+ process.stdout.write(chalk16.dim("\nChat ended.\n"));
1085
1151
  });
1086
1152
  await new Promise((resolve9) => {
1087
1153
  rl.on("close", resolve9);
@@ -1094,7 +1160,7 @@ function createReadline() {
1094
1160
  return createInterface2({
1095
1161
  input: process.stdin,
1096
1162
  output: process.stdout,
1097
- prompt: chalk14.green("you> "),
1163
+ prompt: chalk16.green("you> "),
1098
1164
  terminal: process.stdin.isTTY ?? false
1099
1165
  });
1100
1166
  }
@@ -1136,9 +1202,9 @@ function notificationToChunk(notification) {
1136
1202
  }
1137
1203
 
1138
1204
  // src/commands/agent/dispatch.ts
1139
- import { Command as Command20 } from "commander";
1205
+ import { Command as Command21 } from "commander";
1140
1206
  function createAgentDispatchCommand(client, printer = defaultPrinter) {
1141
- return new Command20("dispatch").description("Queue a one-off task for an agent's scheduler").argument("<name>", "Agent name").requiredOption("-m, --message <message>", "The prompt/message to dispatch").option("-p, --priority <priority>", "Task priority: low, normal, high, critical", "normal").action(async (name, opts) => {
1207
+ return new Command21("dispatch").description("Queue a one-off task for an agent's scheduler").argument("<name>", "Agent name").requiredOption("-m, --message <message>", "The prompt/message to dispatch").option("-p, --priority <priority>", "Task priority: low, normal, high, critical", "normal").action(async (name, opts) => {
1142
1208
  try {
1143
1209
  const result = await client.call("agent.dispatch", {
1144
1210
  name,
@@ -1149,6 +1215,8 @@ function createAgentDispatchCommand(client, printer = defaultPrinter) {
1149
1215
  printer.log("Task queued.");
1150
1216
  } else {
1151
1217
  printer.dim(`No scheduler for agent "${name}". Task not queued.`);
1218
+ printer.dim(`Hint: use "actant agent run ${name} --prompt <message>" for one-shot execution.`);
1219
+ process.exitCode = 1;
1152
1220
  }
1153
1221
  } catch (err) {
1154
1222
  presentError(err, printer);
@@ -1158,9 +1226,9 @@ function createAgentDispatchCommand(client, printer = defaultPrinter) {
1158
1226
  }
1159
1227
 
1160
1228
  // src/commands/agent/tasks.ts
1161
- import { Command as Command21 } from "commander";
1229
+ import { Command as Command22 } from "commander";
1162
1230
  function createAgentTasksCommand(client, printer = defaultPrinter) {
1163
- return new Command21("tasks").description("List queued tasks for an agent's scheduler").argument("<name>", "Agent name").option("-f, --format <format>", "Output format: table, json", "table").action(async (name, opts) => {
1231
+ return new Command22("tasks").description("List queued tasks for an agent's scheduler").argument("<name>", "Agent name").option("-f, --format <format>", "Output format: table, json", "table").action(async (name, opts) => {
1164
1232
  try {
1165
1233
  const result = await client.call("agent.tasks", { name });
1166
1234
  if (opts.format === "json") {
@@ -1182,9 +1250,9 @@ function createAgentTasksCommand(client, printer = defaultPrinter) {
1182
1250
  }
1183
1251
 
1184
1252
  // src/commands/agent/logs.ts
1185
- import { Command as Command22 } from "commander";
1253
+ import { Command as Command23 } from "commander";
1186
1254
  function createAgentLogsCommand(client, printer = defaultPrinter) {
1187
- return new Command22("logs").description("Show execution logs for an agent's scheduler").argument("<name>", "Agent name").option("--limit <n>", "Maximum number of records to show", parseInt, 20).option("-f, --format <format>", "Output format: table, json", "table").action(async (name, opts) => {
1255
+ return new Command23("logs").description("Show execution logs for an agent's scheduler").argument("<name>", "Agent name").option("--limit <n>", "Maximum number of records to show", parseInt, 20).option("-f, --format <format>", "Output format: table, json", "table").action(async (name, opts) => {
1188
1256
  try {
1189
1257
  const result = await client.call("agent.logs", { name, limit: opts.limit });
1190
1258
  if (opts.format === "json") {
@@ -1210,7 +1278,7 @@ function createAgentLogsCommand(client, printer = defaultPrinter) {
1210
1278
 
1211
1279
  // src/commands/agent/index.ts
1212
1280
  function createAgentCommand(client, printer) {
1213
- const cmd = new Command23("agent").description("Manage agent instances");
1281
+ const cmd = new Command24("agent").description("Manage agent instances");
1214
1282
  cmd.addCommand(createAgentCreateCommand(client, printer));
1215
1283
  cmd.addCommand(createAgentStartCommand(client, printer));
1216
1284
  cmd.addCommand(createAgentStopCommand(client, printer));
@@ -1219,6 +1287,7 @@ function createAgentCommand(client, printer) {
1219
1287
  cmd.addCommand(createAgentAdoptCommand(client, printer));
1220
1288
  cmd.addCommand(createAgentDestroyCommand(client, printer));
1221
1289
  cmd.addCommand(createAgentResolveCommand(client, printer));
1290
+ cmd.addCommand(createAgentOpenCommand(client, printer));
1222
1291
  cmd.addCommand(createAgentAttachCommand(client, printer));
1223
1292
  cmd.addCommand(createAgentDetachCommand(client, printer));
1224
1293
  cmd.addCommand(createAgentRunCommand(client, printer));
@@ -1231,13 +1300,13 @@ function createAgentCommand(client, printer) {
1231
1300
  }
1232
1301
 
1233
1302
  // src/commands/help.ts
1234
- import { Command as Command24 } from "commander";
1235
- import chalk15 from "chalk";
1303
+ import { Command as Command25 } from "commander";
1304
+ import chalk17 from "chalk";
1236
1305
 
1237
1306
  // package.json
1238
1307
  var package_default = {
1239
1308
  name: "@actant/cli",
1240
- version: "0.1.3",
1309
+ version: "0.2.1",
1241
1310
  description: "CLI for the Actant AI agent platform \u2014 build, manage, and compose AI agents",
1242
1311
  type: "module",
1243
1312
  license: "MIT",
@@ -1262,6 +1331,15 @@ var package_default = {
1262
1331
  "dist",
1263
1332
  "scripts/postinstall.mjs"
1264
1333
  ],
1334
+ main: "./dist/index.js",
1335
+ types: "./dist/index.d.ts",
1336
+ exports: {
1337
+ ".": {
1338
+ import: "./dist/index.js",
1339
+ types: "./dist/index.d.ts"
1340
+ },
1341
+ "./dist/bin/actant.js": "./dist/bin/actant.js"
1342
+ },
1265
1343
  bin: {
1266
1344
  actant: "./dist/bin/actant.js"
1267
1345
  },
@@ -1278,6 +1356,7 @@ var package_default = {
1278
1356
  "@actant/acp": "workspace:*",
1279
1357
  "@actant/api": "workspace:*",
1280
1358
  "@actant/core": "workspace:*",
1359
+ "@actant/pi": "workspace:*",
1281
1360
  "@actant/shared": "workspace:*",
1282
1361
  "@inquirer/prompts": "^8.3.0",
1283
1362
  chalk: "^5.6.2",
@@ -1291,42 +1370,42 @@ function showOverview() {
1291
1370
  const version = package_default.version ?? "0.1.0";
1292
1371
  const lines = [
1293
1372
  "",
1294
- chalk15.bold(" Actant \u2014 Build, manage, and compose AI agents"),
1295
- chalk15.gray(` v${version}`),
1373
+ chalk17.bold(" Actant \u2014 Build, manage, and compose AI agents"),
1374
+ chalk17.gray(` v${version}`),
1296
1375
  "",
1297
- chalk15.bold(" Quick Start:"),
1298
- ` ${chalk15.cyan("actant daemon start")} Start the daemon`,
1299
- ` ${chalk15.cyan("actant agent create my-agent")} Create an Agent`,
1300
- ` ${chalk15.cyan("actant agent start my-agent")} Start an Agent`,
1301
- ` ${chalk15.cyan("actant agent chat my-agent")} Chat with an Agent`,
1376
+ chalk17.bold(" Quick Start:"),
1377
+ ` ${chalk17.cyan("actant daemon start")} Start the daemon`,
1378
+ ` ${chalk17.cyan("actant agent create my-agent")} Create an Agent`,
1379
+ ` ${chalk17.cyan("actant agent start my-agent")} Start an Agent`,
1380
+ ` ${chalk17.cyan("actant agent chat my-agent")} Chat with an Agent`,
1302
1381
  "",
1303
- chalk15.bold(" Agent Management:"),
1304
- ` ${chalk15.cyan("agent")} create|start|stop|list|chat|run Agent lifecycle`,
1305
- ` ${chalk15.cyan("agent adopt")} <path> Adopt existing workspace`,
1306
- ` ${chalk15.cyan("template")} list|show Agent templates`,
1307
- ` ${chalk15.cyan("proxy")} <name> ACP proxy forwarding`,
1382
+ chalk17.bold(" Agent Management:"),
1383
+ ` ${chalk17.cyan("agent")} create|start|stop|list|chat|run Agent lifecycle`,
1384
+ ` ${chalk17.cyan("agent adopt")} <path> Adopt existing workspace`,
1385
+ ` ${chalk17.cyan("template")} list|show Agent templates`,
1386
+ ` ${chalk17.cyan("proxy")} <name> ACP proxy forwarding`,
1308
1387
  "",
1309
- chalk15.bold(" Component Management:"),
1310
- ` ${chalk15.cyan("skill")} list|add|remove|show Manage skills`,
1311
- ` ${chalk15.cyan("prompt")} list|add|remove|show Manage prompts`,
1312
- ` ${chalk15.cyan("mcp")} list|show Manage MCP server configs`,
1313
- ` ${chalk15.cyan("workflow")} list|show Manage workflows`,
1314
- ` ${chalk15.cyan("plugin")} list|add|remove|show Manage plugins`,
1388
+ chalk17.bold(" Component Management:"),
1389
+ ` ${chalk17.cyan("skill")} list|add|remove|show Manage skills`,
1390
+ ` ${chalk17.cyan("prompt")} list|add|remove|show Manage prompts`,
1391
+ ` ${chalk17.cyan("mcp")} list|show Manage MCP server configs`,
1392
+ ` ${chalk17.cyan("workflow")} list|show Manage workflows`,
1393
+ ` ${chalk17.cyan("plugin")} list|add|remove|show Manage plugins`,
1315
1394
  "",
1316
- chalk15.bold(" Ecosystem:"),
1317
- ` ${chalk15.cyan("source")} list|add|remove|sync Manage component sources`,
1318
- ` ${chalk15.cyan("preset")} list|apply Manage preset packs`,
1395
+ chalk17.bold(" Ecosystem:"),
1396
+ ` ${chalk17.cyan("source")} list|add|remove|sync Manage component sources`,
1397
+ ` ${chalk17.cyan("preset")} list|apply Manage preset packs`,
1319
1398
  "",
1320
- chalk15.bold(" Scheduling:"),
1321
- ` ${chalk15.cyan("schedule")} list Manage employee agent scheduling`,
1399
+ chalk17.bold(" Scheduling:"),
1400
+ ` ${chalk17.cyan("schedule")} list Manage employee agent scheduling`,
1322
1401
  "",
1323
- chalk15.bold(" System:"),
1324
- ` ${chalk15.cyan("daemon")} start|stop|status Daemon management`,
1325
- ` ${chalk15.cyan("help")} [command] Show help`,
1326
- ` ${chalk15.cyan("--version")} Show version`,
1402
+ chalk17.bold(" System:"),
1403
+ ` ${chalk17.cyan("daemon")} start|stop|status Daemon management`,
1404
+ ` ${chalk17.cyan("help")} [command] Show help`,
1405
+ ` ${chalk17.cyan("--version")} Show version`,
1327
1406
  "",
1328
- chalk15.bold(" Tips:"),
1329
- chalk15.gray(" Use 'actant help <command>' for detailed help on a command"),
1407
+ chalk17.bold(" Tips:"),
1408
+ chalk17.gray(" Use 'actant help <command>' for detailed help on a command"),
1330
1409
  ""
1331
1410
  ];
1332
1411
  process.stdout.write(lines.join("\n"));
@@ -1337,13 +1416,13 @@ function showCommandHelp(program, commandName) {
1337
1416
  subcmd.outputHelp();
1338
1417
  } else {
1339
1418
  process.stdout.write(
1340
- chalk15.red(`Unknown command: ${commandName}
1341
- `) + chalk15.gray("Run 'actant help' to see available commands.\n")
1419
+ chalk17.red(`Unknown command: ${commandName}
1420
+ `) + chalk17.gray("Run 'actant help' to see available commands.\n")
1342
1421
  );
1343
1422
  }
1344
1423
  }
1345
1424
  function createHelpCommand() {
1346
- return new Command24("help").argument("[command]", "Command to get help for").description("Show help information").action(function(command) {
1425
+ return new Command25("help").argument("[command]", "Command to get help for").description("Show help information").action(function(command) {
1347
1426
  const program = this.parent;
1348
1427
  if (command) {
1349
1428
  showCommandHelp(program, command);
@@ -1354,12 +1433,12 @@ function createHelpCommand() {
1354
1433
  }
1355
1434
 
1356
1435
  // src/commands/skill/index.ts
1357
- import { Command as Command30 } from "commander";
1436
+ import { Command as Command31 } from "commander";
1358
1437
 
1359
1438
  // src/commands/skill/list.ts
1360
- import { Command as Command25 } from "commander";
1439
+ import { Command as Command26 } from "commander";
1361
1440
  function createSkillListCommand(client, printer = defaultPrinter) {
1362
- return new Command25("list").alias("ls").description("List all loaded skills").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1441
+ return new Command26("list").alias("ls").description("List all loaded skills").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1363
1442
  try {
1364
1443
  const skills = await client.call("skill.list", {});
1365
1444
  printer.log(formatSkillList(skills, opts.format));
@@ -1371,9 +1450,9 @@ function createSkillListCommand(client, printer = defaultPrinter) {
1371
1450
  }
1372
1451
 
1373
1452
  // src/commands/skill/show.ts
1374
- import { Command as Command26 } from "commander";
1453
+ import { Command as Command27 } from "commander";
1375
1454
  function createSkillShowCommand(client, printer = defaultPrinter) {
1376
- return new Command26("show").description("Show skill details").argument("<name>", "Skill name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1455
+ return new Command27("show").description("Show skill details").argument("<name>", "Skill name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1377
1456
  try {
1378
1457
  const skill = await client.call("skill.get", { name });
1379
1458
  printer.log(formatSkillDetail(skill, opts.format));
@@ -1387,9 +1466,9 @@ function createSkillShowCommand(client, printer = defaultPrinter) {
1387
1466
  // src/commands/skill/add.ts
1388
1467
  import { readFile } from "fs/promises";
1389
1468
  import { resolve as resolve4 } from "path";
1390
- import { Command as Command27 } from "commander";
1469
+ import { Command as Command28 } from "commander";
1391
1470
  function createSkillAddCommand(client, printer = defaultPrinter) {
1392
- return new Command27("add").description("Add a skill from a JSON file").argument("<file>", "Path to skill definition JSON file").action(async (file) => {
1471
+ return new Command28("add").description("Add a skill from a JSON file").argument("<file>", "Path to skill definition JSON file").action(async (file) => {
1393
1472
  try {
1394
1473
  const raw = await readFile(resolve4(file), "utf-8");
1395
1474
  const component = JSON.parse(raw);
@@ -1403,9 +1482,9 @@ function createSkillAddCommand(client, printer = defaultPrinter) {
1403
1482
  }
1404
1483
 
1405
1484
  // src/commands/skill/remove.ts
1406
- import { Command as Command28 } from "commander";
1485
+ import { Command as Command29 } from "commander";
1407
1486
  function createSkillRemoveCommand(client, printer = defaultPrinter) {
1408
- return new Command28("remove").alias("rm").description("Remove a loaded skill").argument("<name>", "Skill name").action(async (name) => {
1487
+ return new Command29("remove").alias("rm").description("Remove a loaded skill").argument("<name>", "Skill name").action(async (name) => {
1409
1488
  try {
1410
1489
  const result = await client.call("skill.remove", { name });
1411
1490
  if (result.success) {
@@ -1421,9 +1500,9 @@ function createSkillRemoveCommand(client, printer = defaultPrinter) {
1421
1500
  }
1422
1501
 
1423
1502
  // src/commands/skill/export.ts
1424
- import { Command as Command29 } from "commander";
1503
+ import { Command as Command30 } from "commander";
1425
1504
  function createSkillExportCommand(client, printer = defaultPrinter) {
1426
- return new Command29("export").description("Export a skill to a JSON file").argument("<name>", "Skill name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1505
+ return new Command30("export").description("Export a skill to a JSON file").argument("<name>", "Skill name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1427
1506
  try {
1428
1507
  const outPath = opts.out.replace("{name}", name);
1429
1508
  await client.call("skill.export", { name, filePath: outPath });
@@ -1437,7 +1516,7 @@ function createSkillExportCommand(client, printer = defaultPrinter) {
1437
1516
 
1438
1517
  // src/commands/skill/index.ts
1439
1518
  function createSkillCommand(client, printer) {
1440
- const cmd = new Command30("skill").description("Manage loaded skills");
1519
+ const cmd = new Command31("skill").description("Manage loaded skills");
1441
1520
  cmd.addCommand(createSkillListCommand(client, printer));
1442
1521
  cmd.addCommand(createSkillShowCommand(client, printer));
1443
1522
  cmd.addCommand(createSkillAddCommand(client, printer));
@@ -1447,12 +1526,12 @@ function createSkillCommand(client, printer) {
1447
1526
  }
1448
1527
 
1449
1528
  // src/commands/prompt/index.ts
1450
- import { Command as Command36 } from "commander";
1529
+ import { Command as Command37 } from "commander";
1451
1530
 
1452
1531
  // src/commands/prompt/list.ts
1453
- import { Command as Command31 } from "commander";
1532
+ import { Command as Command32 } from "commander";
1454
1533
  function createPromptListCommand(client, printer = defaultPrinter) {
1455
- return new Command31("list").alias("ls").description("List all loaded prompts").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1534
+ return new Command32("list").alias("ls").description("List all loaded prompts").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1456
1535
  try {
1457
1536
  const prompts = await client.call("prompt.list", {});
1458
1537
  printer.log(formatPromptList(prompts, opts.format));
@@ -1464,9 +1543,9 @@ function createPromptListCommand(client, printer = defaultPrinter) {
1464
1543
  }
1465
1544
 
1466
1545
  // src/commands/prompt/show.ts
1467
- import { Command as Command32 } from "commander";
1546
+ import { Command as Command33 } from "commander";
1468
1547
  function createPromptShowCommand(client, printer = defaultPrinter) {
1469
- return new Command32("show").description("Show prompt details").argument("<name>", "Prompt name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1548
+ return new Command33("show").description("Show prompt details").argument("<name>", "Prompt name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1470
1549
  try {
1471
1550
  const prompt = await client.call("prompt.get", { name });
1472
1551
  printer.log(formatPromptDetail(prompt, opts.format));
@@ -1480,9 +1559,9 @@ function createPromptShowCommand(client, printer = defaultPrinter) {
1480
1559
  // src/commands/prompt/add.ts
1481
1560
  import { readFile as readFile2 } from "fs/promises";
1482
1561
  import { resolve as resolve5 } from "path";
1483
- import { Command as Command33 } from "commander";
1562
+ import { Command as Command34 } from "commander";
1484
1563
  function createPromptAddCommand(client, printer = defaultPrinter) {
1485
- return new Command33("add").description("Add a prompt from a JSON file").argument("<file>", "Path to prompt definition JSON file").action(async (file) => {
1564
+ return new Command34("add").description("Add a prompt from a JSON file").argument("<file>", "Path to prompt definition JSON file").action(async (file) => {
1486
1565
  try {
1487
1566
  const raw = await readFile2(resolve5(file), "utf-8");
1488
1567
  const component = JSON.parse(raw);
@@ -1496,9 +1575,9 @@ function createPromptAddCommand(client, printer = defaultPrinter) {
1496
1575
  }
1497
1576
 
1498
1577
  // src/commands/prompt/remove.ts
1499
- import { Command as Command34 } from "commander";
1578
+ import { Command as Command35 } from "commander";
1500
1579
  function createPromptRemoveCommand(client, printer = defaultPrinter) {
1501
- return new Command34("remove").alias("rm").description("Remove a loaded prompt").argument("<name>", "Prompt name").action(async (name) => {
1580
+ return new Command35("remove").alias("rm").description("Remove a loaded prompt").argument("<name>", "Prompt name").action(async (name) => {
1502
1581
  try {
1503
1582
  const result = await client.call("prompt.remove", { name });
1504
1583
  if (result.success) {
@@ -1514,9 +1593,9 @@ function createPromptRemoveCommand(client, printer = defaultPrinter) {
1514
1593
  }
1515
1594
 
1516
1595
  // src/commands/prompt/export.ts
1517
- import { Command as Command35 } from "commander";
1596
+ import { Command as Command36 } from "commander";
1518
1597
  function createPromptExportCommand(client, printer = defaultPrinter) {
1519
- return new Command35("export").description("Export a prompt to a JSON file").argument("<name>", "Prompt name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1598
+ return new Command36("export").description("Export a prompt to a JSON file").argument("<name>", "Prompt name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1520
1599
  try {
1521
1600
  const outPath = opts.out.replace("{name}", name);
1522
1601
  await client.call("prompt.export", { name, filePath: outPath });
@@ -1530,7 +1609,7 @@ function createPromptExportCommand(client, printer = defaultPrinter) {
1530
1609
 
1531
1610
  // src/commands/prompt/index.ts
1532
1611
  function createPromptCommand(client, printer) {
1533
- const cmd = new Command36("prompt").description("Manage loaded prompts");
1612
+ const cmd = new Command37("prompt").description("Manage loaded prompts");
1534
1613
  cmd.addCommand(createPromptListCommand(client, printer));
1535
1614
  cmd.addCommand(createPromptShowCommand(client, printer));
1536
1615
  cmd.addCommand(createPromptAddCommand(client, printer));
@@ -1540,12 +1619,12 @@ function createPromptCommand(client, printer) {
1540
1619
  }
1541
1620
 
1542
1621
  // src/commands/mcp/index.ts
1543
- import { Command as Command42 } from "commander";
1622
+ import { Command as Command43 } from "commander";
1544
1623
 
1545
1624
  // src/commands/mcp/list.ts
1546
- import { Command as Command37 } from "commander";
1625
+ import { Command as Command38 } from "commander";
1547
1626
  function createMcpListCommand(client, printer = defaultPrinter) {
1548
- return new Command37("list").alias("ls").description("List all loaded MCP server configs").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1627
+ return new Command38("list").alias("ls").description("List all loaded MCP server configs").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1549
1628
  try {
1550
1629
  const servers = await client.call("mcp.list", {});
1551
1630
  printer.log(formatMcpList(servers, opts.format));
@@ -1557,9 +1636,9 @@ function createMcpListCommand(client, printer = defaultPrinter) {
1557
1636
  }
1558
1637
 
1559
1638
  // src/commands/mcp/show.ts
1560
- import { Command as Command38 } from "commander";
1639
+ import { Command as Command39 } from "commander";
1561
1640
  function createMcpShowCommand(client, printer = defaultPrinter) {
1562
- return new Command38("show").description("Show MCP server config details").argument("<name>", "MCP server name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1641
+ return new Command39("show").description("Show MCP server config details").argument("<name>", "MCP server name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1563
1642
  try {
1564
1643
  const server = await client.call("mcp.get", { name });
1565
1644
  printer.log(formatMcpDetail(server, opts.format));
@@ -1573,9 +1652,9 @@ function createMcpShowCommand(client, printer = defaultPrinter) {
1573
1652
  // src/commands/mcp/add.ts
1574
1653
  import { readFile as readFile3 } from "fs/promises";
1575
1654
  import { resolve as resolve6 } from "path";
1576
- import { Command as Command39 } from "commander";
1655
+ import { Command as Command40 } from "commander";
1577
1656
  function createMcpAddCommand(client, printer = defaultPrinter) {
1578
- return new Command39("add").description("Add an MCP server config from a JSON file").argument("<file>", "Path to MCP server definition JSON file").action(async (file) => {
1657
+ return new Command40("add").description("Add an MCP server config from a JSON file").argument("<file>", "Path to MCP server definition JSON file").action(async (file) => {
1579
1658
  try {
1580
1659
  const raw = await readFile3(resolve6(file), "utf-8");
1581
1660
  const component = JSON.parse(raw);
@@ -1589,9 +1668,9 @@ function createMcpAddCommand(client, printer = defaultPrinter) {
1589
1668
  }
1590
1669
 
1591
1670
  // src/commands/mcp/remove.ts
1592
- import { Command as Command40 } from "commander";
1671
+ import { Command as Command41 } from "commander";
1593
1672
  function createMcpRemoveCommand(client, printer = defaultPrinter) {
1594
- return new Command40("remove").alias("rm").description("Remove a loaded MCP server config").argument("<name>", "MCP server name").action(async (name) => {
1673
+ return new Command41("remove").alias("rm").description("Remove a loaded MCP server config").argument("<name>", "MCP server name").action(async (name) => {
1595
1674
  try {
1596
1675
  const result = await client.call("mcp.remove", { name });
1597
1676
  if (result.success) {
@@ -1607,9 +1686,9 @@ function createMcpRemoveCommand(client, printer = defaultPrinter) {
1607
1686
  }
1608
1687
 
1609
1688
  // src/commands/mcp/export.ts
1610
- import { Command as Command41 } from "commander";
1689
+ import { Command as Command42 } from "commander";
1611
1690
  function createMcpExportCommand(client, printer = defaultPrinter) {
1612
- return new Command41("export").description("Export an MCP server config to a JSON file").argument("<name>", "MCP server name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1691
+ return new Command42("export").description("Export an MCP server config to a JSON file").argument("<name>", "MCP server name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1613
1692
  try {
1614
1693
  const outPath = opts.out.replace("{name}", name);
1615
1694
  await client.call("mcp.export", { name, filePath: outPath });
@@ -1623,7 +1702,7 @@ function createMcpExportCommand(client, printer = defaultPrinter) {
1623
1702
 
1624
1703
  // src/commands/mcp/index.ts
1625
1704
  function createMcpCommand(client, printer) {
1626
- const cmd = new Command42("mcp").description("Manage loaded MCP server configs");
1705
+ const cmd = new Command43("mcp").description("Manage loaded MCP server configs");
1627
1706
  cmd.addCommand(createMcpListCommand(client, printer));
1628
1707
  cmd.addCommand(createMcpShowCommand(client, printer));
1629
1708
  cmd.addCommand(createMcpAddCommand(client, printer));
@@ -1633,12 +1712,12 @@ function createMcpCommand(client, printer) {
1633
1712
  }
1634
1713
 
1635
1714
  // src/commands/workflow/index.ts
1636
- import { Command as Command48 } from "commander";
1715
+ import { Command as Command49 } from "commander";
1637
1716
 
1638
1717
  // src/commands/workflow/list.ts
1639
- import { Command as Command43 } from "commander";
1718
+ import { Command as Command44 } from "commander";
1640
1719
  function createWorkflowListCommand(client, printer = defaultPrinter) {
1641
- return new Command43("list").alias("ls").description("List all loaded workflows").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1720
+ return new Command44("list").alias("ls").description("List all loaded workflows").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1642
1721
  try {
1643
1722
  const workflows = await client.call("workflow.list", {});
1644
1723
  printer.log(formatWorkflowList(workflows, opts.format));
@@ -1650,9 +1729,9 @@ function createWorkflowListCommand(client, printer = defaultPrinter) {
1650
1729
  }
1651
1730
 
1652
1731
  // src/commands/workflow/show.ts
1653
- import { Command as Command44 } from "commander";
1732
+ import { Command as Command45 } from "commander";
1654
1733
  function createWorkflowShowCommand(client, printer = defaultPrinter) {
1655
- return new Command44("show").description("Show workflow details").argument("<name>", "Workflow name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1734
+ return new Command45("show").description("Show workflow details").argument("<name>", "Workflow name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1656
1735
  try {
1657
1736
  const workflow = await client.call("workflow.get", { name });
1658
1737
  printer.log(formatWorkflowDetail(workflow, opts.format));
@@ -1666,9 +1745,9 @@ function createWorkflowShowCommand(client, printer = defaultPrinter) {
1666
1745
  // src/commands/workflow/add.ts
1667
1746
  import { readFile as readFile4 } from "fs/promises";
1668
1747
  import { resolve as resolve7 } from "path";
1669
- import { Command as Command45 } from "commander";
1748
+ import { Command as Command46 } from "commander";
1670
1749
  function createWorkflowAddCommand(client, printer = defaultPrinter) {
1671
- return new Command45("add").description("Add a workflow from a JSON file").argument("<file>", "Path to workflow definition JSON file").action(async (file) => {
1750
+ return new Command46("add").description("Add a workflow from a JSON file").argument("<file>", "Path to workflow definition JSON file").action(async (file) => {
1672
1751
  try {
1673
1752
  const raw = await readFile4(resolve7(file), "utf-8");
1674
1753
  const component = JSON.parse(raw);
@@ -1682,9 +1761,9 @@ function createWorkflowAddCommand(client, printer = defaultPrinter) {
1682
1761
  }
1683
1762
 
1684
1763
  // src/commands/workflow/remove.ts
1685
- import { Command as Command46 } from "commander";
1764
+ import { Command as Command47 } from "commander";
1686
1765
  function createWorkflowRemoveCommand(client, printer = defaultPrinter) {
1687
- return new Command46("remove").alias("rm").description("Remove a loaded workflow").argument("<name>", "Workflow name").action(async (name) => {
1766
+ return new Command47("remove").alias("rm").description("Remove a loaded workflow").argument("<name>", "Workflow name").action(async (name) => {
1688
1767
  try {
1689
1768
  const result = await client.call("workflow.remove", { name });
1690
1769
  if (result.success) {
@@ -1700,9 +1779,9 @@ function createWorkflowRemoveCommand(client, printer = defaultPrinter) {
1700
1779
  }
1701
1780
 
1702
1781
  // src/commands/workflow/export.ts
1703
- import { Command as Command47 } from "commander";
1782
+ import { Command as Command48 } from "commander";
1704
1783
  function createWorkflowExportCommand(client, printer = defaultPrinter) {
1705
- return new Command47("export").description("Export a workflow to a JSON file").argument("<name>", "Workflow name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1784
+ return new Command48("export").description("Export a workflow to a JSON file").argument("<name>", "Workflow name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1706
1785
  try {
1707
1786
  const outPath = opts.out.replace("{name}", name);
1708
1787
  await client.call("workflow.export", { name, filePath: outPath });
@@ -1716,7 +1795,7 @@ function createWorkflowExportCommand(client, printer = defaultPrinter) {
1716
1795
 
1717
1796
  // src/commands/workflow/index.ts
1718
1797
  function createWorkflowCommand(client, printer) {
1719
- const cmd = new Command48("workflow").description("Manage loaded workflows");
1798
+ const cmd = new Command49("workflow").description("Manage loaded workflows");
1720
1799
  cmd.addCommand(createWorkflowListCommand(client, printer));
1721
1800
  cmd.addCommand(createWorkflowShowCommand(client, printer));
1722
1801
  cmd.addCommand(createWorkflowAddCommand(client, printer));
@@ -1726,12 +1805,12 @@ function createWorkflowCommand(client, printer) {
1726
1805
  }
1727
1806
 
1728
1807
  // src/commands/plugin/index.ts
1729
- import { Command as Command54 } from "commander";
1808
+ import { Command as Command55 } from "commander";
1730
1809
 
1731
1810
  // src/commands/plugin/list.ts
1732
- import { Command as Command49 } from "commander";
1811
+ import { Command as Command50 } from "commander";
1733
1812
  function createPluginListCommand(client, printer = defaultPrinter) {
1734
- return new Command49("list").alias("ls").description("List all plugins").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1813
+ return new Command50("list").alias("ls").description("List all plugins").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1735
1814
  try {
1736
1815
  const plugins = await client.call("plugin.list", {});
1737
1816
  printer.log(formatPluginList(plugins, opts.format));
@@ -1743,9 +1822,9 @@ function createPluginListCommand(client, printer = defaultPrinter) {
1743
1822
  }
1744
1823
 
1745
1824
  // src/commands/plugin/show.ts
1746
- import { Command as Command50 } from "commander";
1825
+ import { Command as Command51 } from "commander";
1747
1826
  function createPluginShowCommand(client, printer = defaultPrinter) {
1748
- return new Command50("show").description("Show plugin details").argument("<name>", "Plugin name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1827
+ return new Command51("show").description("Show plugin details").argument("<name>", "Plugin name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (name, opts) => {
1749
1828
  try {
1750
1829
  const plugin = await client.call("plugin.get", { name });
1751
1830
  printer.log(formatPluginDetail(plugin, opts.format));
@@ -1759,9 +1838,9 @@ function createPluginShowCommand(client, printer = defaultPrinter) {
1759
1838
  // src/commands/plugin/add.ts
1760
1839
  import { readFile as readFile5 } from "fs/promises";
1761
1840
  import { resolve as resolve8 } from "path";
1762
- import { Command as Command51 } from "commander";
1841
+ import { Command as Command52 } from "commander";
1763
1842
  function createPluginAddCommand(client, printer = defaultPrinter) {
1764
- return new Command51("add").description("Add a plugin from a JSON file").argument("<file>", "Path to plugin definition JSON file").action(async (file) => {
1843
+ return new Command52("add").description("Add a plugin from a JSON file").argument("<file>", "Path to plugin definition JSON file").action(async (file) => {
1765
1844
  try {
1766
1845
  const raw = await readFile5(resolve8(file), "utf-8");
1767
1846
  const component = JSON.parse(raw);
@@ -1775,9 +1854,9 @@ function createPluginAddCommand(client, printer = defaultPrinter) {
1775
1854
  }
1776
1855
 
1777
1856
  // src/commands/plugin/remove.ts
1778
- import { Command as Command52 } from "commander";
1857
+ import { Command as Command53 } from "commander";
1779
1858
  function createPluginRemoveCommand(client, printer = defaultPrinter) {
1780
- return new Command52("remove").alias("rm").description("Remove a loaded plugin").argument("<name>", "Plugin name").action(async (name) => {
1859
+ return new Command53("remove").alias("rm").description("Remove a loaded plugin").argument("<name>", "Plugin name").action(async (name) => {
1781
1860
  try {
1782
1861
  const result = await client.call("plugin.remove", { name });
1783
1862
  if (result.success) {
@@ -1793,9 +1872,9 @@ function createPluginRemoveCommand(client, printer = defaultPrinter) {
1793
1872
  }
1794
1873
 
1795
1874
  // src/commands/plugin/export.ts
1796
- import { Command as Command53 } from "commander";
1875
+ import { Command as Command54 } from "commander";
1797
1876
  function createPluginExportCommand(client, printer = defaultPrinter) {
1798
- return new Command53("export").description("Export a plugin to a JSON file").argument("<name>", "Plugin name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1877
+ return new Command54("export").description("Export a plugin to a JSON file").argument("<name>", "Plugin name").option("-o, --out <file>", "Output file path", "./{name}.json").action(async (name, opts) => {
1799
1878
  try {
1800
1879
  const outPath = opts.out.replace("{name}", name);
1801
1880
  await client.call("plugin.export", { name, filePath: outPath });
@@ -1809,7 +1888,7 @@ function createPluginExportCommand(client, printer = defaultPrinter) {
1809
1888
 
1810
1889
  // src/commands/plugin/index.ts
1811
1890
  function createPluginCommand(client, printer) {
1812
- const cmd = new Command54("plugin").description("Manage loaded plugins");
1891
+ const cmd = new Command55("plugin").description("Manage loaded plugins");
1813
1892
  cmd.addCommand(createPluginListCommand(client, printer));
1814
1893
  cmd.addCommand(createPluginShowCommand(client, printer));
1815
1894
  cmd.addCommand(createPluginAddCommand(client, printer));
@@ -1819,12 +1898,12 @@ function createPluginCommand(client, printer) {
1819
1898
  }
1820
1899
 
1821
1900
  // src/commands/source/index.ts
1822
- import { Command as Command59 } from "commander";
1901
+ import { Command as Command61 } from "commander";
1823
1902
 
1824
1903
  // src/commands/source/list.ts
1825
- import { Command as Command55 } from "commander";
1904
+ import { Command as Command56 } from "commander";
1826
1905
  function createSourceListCommand(client, printer = defaultPrinter) {
1827
- return new Command55("list").alias("ls").description("List registered component sources").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1906
+ return new Command56("list").alias("ls").description("List registered component sources").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1828
1907
  try {
1829
1908
  const sources = await client.call("source.list", {});
1830
1909
  if (opts.format === "json") {
@@ -1850,9 +1929,9 @@ function createSourceListCommand(client, printer = defaultPrinter) {
1850
1929
  }
1851
1930
 
1852
1931
  // src/commands/source/add.ts
1853
- import { Command as Command56 } from "commander";
1932
+ import { Command as Command57 } from "commander";
1854
1933
  function createSourceAddCommand(client, printer = defaultPrinter) {
1855
- return new Command56("add").description("Register a component source").argument("<url-or-path>", "GitHub URL or local directory path").requiredOption("--name <name>", "Package name (namespace prefix)").option("--type <type>", "Source type: github, local", "github").option("--branch <branch>", "Git branch (for github type)", "main").action(async (urlOrPath, opts) => {
1934
+ return new Command57("add").description("Register a component source").argument("<url-or-path>", "GitHub URL or local directory path").requiredOption("--name <name>", "Package name (namespace prefix)").option("--type <type>", "Source type: github, local", "github").option("--branch <branch>", "Git branch (for github type)", "main").action(async (urlOrPath, opts) => {
1856
1935
  try {
1857
1936
  const config = opts.type === "local" ? { type: "local", path: urlOrPath } : { type: "github", url: urlOrPath, branch: opts.branch };
1858
1937
  const result = await client.call("source.add", { name: opts.name, config });
@@ -1868,9 +1947,9 @@ function createSourceAddCommand(client, printer = defaultPrinter) {
1868
1947
  }
1869
1948
 
1870
1949
  // src/commands/source/remove.ts
1871
- import { Command as Command57 } from "commander";
1950
+ import { Command as Command58 } from "commander";
1872
1951
  function createSourceRemoveCommand(client, printer = defaultPrinter) {
1873
- return new Command57("remove").alias("rm").description("Remove a registered source").argument("<name>", "Source name").action(async (name) => {
1952
+ return new Command58("remove").alias("rm").description("Remove a registered source").argument("<name>", "Source name").action(async (name) => {
1874
1953
  try {
1875
1954
  const result = await client.call("source.remove", { name });
1876
1955
  if (result.success) {
@@ -1886,19 +1965,19 @@ function createSourceRemoveCommand(client, printer = defaultPrinter) {
1886
1965
  }
1887
1966
 
1888
1967
  // src/commands/source/sync.ts
1889
- import chalk16 from "chalk";
1890
- import { Command as Command58 } from "commander";
1968
+ import chalk18 from "chalk";
1969
+ import { Command as Command59 } from "commander";
1891
1970
  function createSourceSyncCommand(client, printer = defaultPrinter) {
1892
- return new Command58("sync").description("Sync component source(s)").argument("[name]", "Source name (syncs all if omitted)").action(async (name) => {
1971
+ return new Command59("sync").description("Sync component source(s)").argument("[name]", "Source name (syncs all if omitted)").action(async (name) => {
1893
1972
  try {
1894
1973
  const result = await client.call("source.sync", { name });
1895
1974
  printer.success(`Synced: ${result.synced.join(", ")}`);
1896
1975
  const report = result.report;
1897
1976
  if (report) {
1898
1977
  const parts = [];
1899
- if (report.addedCount > 0) parts.push(chalk16.green(`+${report.addedCount} added`));
1900
- if (report.updatedCount > 0) parts.push(chalk16.yellow(`${report.updatedCount} updated`));
1901
- if (report.removedCount > 0) parts.push(chalk16.red(`-${report.removedCount} removed`));
1978
+ if (report.addedCount > 0) parts.push(chalk18.green(`+${report.addedCount} added`));
1979
+ if (report.updatedCount > 0) parts.push(chalk18.yellow(`${report.updatedCount} updated`));
1980
+ if (report.removedCount > 0) parts.push(chalk18.red(`-${report.removedCount} removed`));
1902
1981
  if (parts.length > 0) {
1903
1982
  printer.log(` ${parts.join(", ")}`);
1904
1983
  }
@@ -1913,23 +1992,110 @@ function createSourceSyncCommand(client, printer = defaultPrinter) {
1913
1992
  });
1914
1993
  }
1915
1994
 
1995
+ // src/commands/source/validate.ts
1996
+ import chalk19 from "chalk";
1997
+ import { Command as Command60 } from "commander";
1998
+ function createSourceValidateCommand(client, printer = defaultPrinter) {
1999
+ return new Command60("validate").description("Validate all assets in a component source").argument("[name]", "Registered source name to validate").option("--path <dir>", "Validate a local directory directly (no registration needed)").option("-f, --format <format>", "Output format: table, json", "table").option("--strict", "Treat warnings as errors", false).option("--compat <standard>", "Enable compatibility checks (e.g. agent-skills)").action(async (name, opts) => {
2000
+ try {
2001
+ if (!name && !opts?.path) {
2002
+ printer.error("Provide a source name or --path <dir>");
2003
+ process.exitCode = 1;
2004
+ return;
2005
+ }
2006
+ const result = await client.call("source.validate", {
2007
+ name: name || void 0,
2008
+ path: opts?.path || void 0,
2009
+ strict: opts?.strict || false,
2010
+ compat: opts?.compat || void 0
2011
+ });
2012
+ if (opts?.format === "json") {
2013
+ printer.log(JSON.stringify(result, null, 2));
2014
+ } else {
2015
+ printTableReport(result, printer);
2016
+ }
2017
+ if (!result.valid) {
2018
+ process.exitCode = 1;
2019
+ }
2020
+ } catch (err) {
2021
+ presentError(err, printer);
2022
+ process.exitCode = 1;
2023
+ }
2024
+ });
2025
+ }
2026
+ function printTableReport(report, printer) {
2027
+ printer.log("");
2028
+ printer.log(`Validating source: ${chalk19.bold(report.sourceName)} (${report.rootDir})`);
2029
+ printer.log("");
2030
+ const grouped = groupByPath(report.issues);
2031
+ const reportedPaths = /* @__PURE__ */ new Set();
2032
+ for (const [path, issues] of grouped) {
2033
+ reportedPaths.add(path);
2034
+ for (const issue of issues) {
2035
+ const tag = severityTag(issue.severity);
2036
+ const comp = issue.component ? ` (${issue.component})` : "";
2037
+ printer.log(` ${tag} ${path}${comp} \u2014 ${issue.message}`);
2038
+ }
2039
+ }
2040
+ if (report.summary.pass > 0) {
2041
+ const passMsg = chalk19.green(`${report.summary.pass} component(s) passed`);
2042
+ const errMsg = report.summary.error > 0 ? chalk19.red(`, ${report.summary.error} error(s)`) : "";
2043
+ const warnMsg = report.summary.warn > 0 ? chalk19.yellow(`, ${report.summary.warn} warning(s)`) : "";
2044
+ printer.log("");
2045
+ printer.log(`Summary: ${passMsg}${warnMsg}${errMsg}`);
2046
+ } else if (report.issues.length === 0) {
2047
+ printer.log(chalk19.dim(" No components found to validate."));
2048
+ }
2049
+ printer.log("");
2050
+ if (report.valid) {
2051
+ printer.log(chalk19.green("Validation passed."));
2052
+ } else {
2053
+ printer.log(chalk19.red("Validation failed."));
2054
+ }
2055
+ }
2056
+ function severityTag(severity) {
2057
+ switch (severity) {
2058
+ case "error":
2059
+ return chalk19.red("[ERROR]");
2060
+ case "warning":
2061
+ return chalk19.yellow("[WARN] ");
2062
+ case "info":
2063
+ return chalk19.blue("[INFO] ");
2064
+ default:
2065
+ return `[${severity}]`;
2066
+ }
2067
+ }
2068
+ function groupByPath(issues) {
2069
+ const map = /* @__PURE__ */ new Map();
2070
+ for (const issue of issues) {
2071
+ let arr = map.get(issue.path);
2072
+ if (!arr) {
2073
+ arr = [];
2074
+ map.set(issue.path, arr);
2075
+ }
2076
+ arr.push(issue);
2077
+ }
2078
+ return map;
2079
+ }
2080
+
1916
2081
  // src/commands/source/index.ts
1917
2082
  function createSourceCommand(client, printer) {
1918
- const cmd = new Command59("source").description("Manage component sources (GitHub repos, local dirs)");
2083
+ const cmd = new Command61("source").description("Manage component sources (GitHub repos, local dirs)");
1919
2084
  cmd.addCommand(createSourceListCommand(client, printer));
1920
2085
  cmd.addCommand(createSourceAddCommand(client, printer));
1921
2086
  cmd.addCommand(createSourceRemoveCommand(client, printer));
1922
2087
  cmd.addCommand(createSourceSyncCommand(client, printer));
2088
+ cmd.addCommand(createSourceValidateCommand(client, printer));
1923
2089
  return cmd;
1924
2090
  }
1925
2091
 
1926
2092
  // src/commands/preset/index.ts
1927
- import { Command as Command63 } from "commander";
2093
+ import { Command as Command65 } from "commander";
1928
2094
 
1929
2095
  // src/commands/preset/list.ts
1930
- import { Command as Command60 } from "commander";
2096
+ import { Command as Command62 } from "commander";
1931
2097
  function createPresetListCommand(client, printer = defaultPrinter) {
1932
- return new Command60("list").alias("ls").description("List available presets from registered sources").argument("[package]", "Filter by source package name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (packageName, opts) => {
2098
+ return new Command62("list").alias("ls").description("List available presets from registered sources").argument("[package]", "Filter by source package name").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (packageName, opts) => {
1933
2099
  try {
1934
2100
  const presets = await client.call("preset.list", { packageName });
1935
2101
  if (opts.format === "json") {
@@ -1954,9 +2120,9 @@ function createPresetListCommand(client, printer = defaultPrinter) {
1954
2120
  }
1955
2121
 
1956
2122
  // src/commands/preset/show.ts
1957
- import { Command as Command61 } from "commander";
2123
+ import { Command as Command63 } from "commander";
1958
2124
  function createPresetShowCommand(client, printer = defaultPrinter) {
1959
- return new Command61("show").description("Show preset details").argument("<qualified-name>", "Preset qualified name (package@preset)").option("-f, --format <format>", "Output format: table, json", "table").action(async (qualifiedName, opts) => {
2125
+ return new Command63("show").description("Show preset details").argument("<qualified-name>", "Preset qualified name (package@preset)").option("-f, --format <format>", "Output format: table, json", "table").action(async (qualifiedName, opts) => {
1960
2126
  try {
1961
2127
  const preset = await client.call("preset.show", { qualifiedName });
1962
2128
  if (opts.format === "json") {
@@ -1977,9 +2143,9 @@ function createPresetShowCommand(client, printer = defaultPrinter) {
1977
2143
  }
1978
2144
 
1979
2145
  // src/commands/preset/apply.ts
1980
- import { Command as Command62 } from "commander";
2146
+ import { Command as Command64 } from "commander";
1981
2147
  function createPresetApplyCommand(client, printer = defaultPrinter) {
1982
- return new Command62("apply").description("Apply a preset to a template (adds all preset components)").argument("<qualified-name>", "Preset qualified name (package@preset)").argument("<template>", "Template name to apply to").action(async (qualifiedName, templateName) => {
2148
+ return new Command64("apply").description("Apply a preset to a template (adds all preset components)").argument("<qualified-name>", "Preset qualified name (package@preset)").argument("<template>", "Template name to apply to").action(async (qualifiedName, templateName) => {
1983
2149
  try {
1984
2150
  const result = await client.call("preset.apply", { qualifiedName, templateName });
1985
2151
  printer.success(`Preset "${qualifiedName}" applied to template "${result.name}".`);
@@ -1992,7 +2158,7 @@ function createPresetApplyCommand(client, printer = defaultPrinter) {
1992
2158
 
1993
2159
  // src/commands/preset/index.ts
1994
2160
  function createPresetCommand(client, printer) {
1995
- const cmd = new Command63("preset").description("Manage component presets (bundled compositions)");
2161
+ const cmd = new Command65("preset").description("Manage component presets (bundled compositions)");
1996
2162
  cmd.addCommand(createPresetListCommand(client, printer));
1997
2163
  cmd.addCommand(createPresetShowCommand(client, printer));
1998
2164
  cmd.addCommand(createPresetApplyCommand(client, printer));
@@ -2000,12 +2166,12 @@ function createPresetCommand(client, printer) {
2000
2166
  }
2001
2167
 
2002
2168
  // src/commands/schedule/index.ts
2003
- import { Command as Command65 } from "commander";
2169
+ import { Command as Command67 } from "commander";
2004
2170
 
2005
2171
  // src/commands/schedule/list.ts
2006
- import { Command as Command64 } from "commander";
2172
+ import { Command as Command66 } from "commander";
2007
2173
  function createScheduleListCommand(client, printer = defaultPrinter) {
2008
- return new Command64("list").alias("ls").description("List schedule sources for an agent").argument("<name>", "Agent name").option("-f, --format <format>", "Output format: table, json", "table").action(async (name, opts) => {
2174
+ return new Command66("list").alias("ls").description("List schedule sources for an agent").argument("<name>", "Agent name").option("-f, --format <format>", "Output format: table, json", "table").action(async (name, opts) => {
2009
2175
  try {
2010
2176
  const result = await client.call("schedule.list", { name });
2011
2177
  if (opts.format === "json") {
@@ -2013,6 +2179,7 @@ function createScheduleListCommand(client, printer = defaultPrinter) {
2013
2179
  } else {
2014
2180
  if (result.sources.length === 0 && !result.running) {
2015
2181
  printer.dim(`No scheduler for agent "${name}".`);
2182
+ process.exitCode = 1;
2016
2183
  } else {
2017
2184
  printer.log(`Scheduler: ${result.running ? "running" : "stopped"}`);
2018
2185
  for (const s of result.sources) {
@@ -2029,31 +2196,31 @@ function createScheduleListCommand(client, printer = defaultPrinter) {
2029
2196
 
2030
2197
  // src/commands/schedule/index.ts
2031
2198
  function createScheduleCommand(client, printer) {
2032
- const cmd = new Command65("schedule").description("Manage agent schedules (heartbeat, cron, hooks)");
2199
+ const cmd = new Command67("schedule").description("Manage agent schedules (heartbeat, cron, hooks)");
2033
2200
  cmd.addCommand(createScheduleListCommand(client, printer));
2034
2201
  return cmd;
2035
2202
  }
2036
2203
 
2037
2204
  // src/commands/daemon/index.ts
2038
- import { Command as Command69 } from "commander";
2205
+ import { Command as Command71 } from "commander";
2039
2206
 
2040
2207
  // src/commands/daemon/start.ts
2041
- import { Command as Command66 } from "commander";
2208
+ import { Command as Command68 } from "commander";
2042
2209
  import { join } from "path";
2043
- import { fork, spawn } from "child_process";
2044
- import chalk17 from "chalk";
2210
+ import { fork, spawn as spawn2 } from "child_process";
2211
+ import chalk20 from "chalk";
2045
2212
  import { onShutdownSignal, isWindows, isSingleExecutable } from "@actant/shared";
2046
2213
  var SEA_DAEMON_FLAG = "--__actant-daemon";
2047
2214
  function spawnDaemonChild() {
2048
2215
  if (isSingleExecutable()) {
2049
- return spawn(process.execPath, [SEA_DAEMON_FLAG], {
2216
+ return spawn2(process.execPath, [SEA_DAEMON_FLAG], {
2050
2217
  detached: true,
2051
2218
  stdio: ["ignore", "ignore", "pipe"],
2052
2219
  env: process.env
2053
2220
  });
2054
2221
  }
2055
2222
  const daemonScript = join(import.meta.dirname, "daemon-entry.js");
2056
- return isWindows() ? spawn(process.execPath, [daemonScript], {
2223
+ return isWindows() ? spawn2(process.execPath, [daemonScript], {
2057
2224
  detached: true,
2058
2225
  stdio: ["ignore", "ignore", "pipe"],
2059
2226
  env: process.env
@@ -2064,7 +2231,7 @@ function spawnDaemonChild() {
2064
2231
  });
2065
2232
  }
2066
2233
  function createDaemonStartCommand(printer = defaultPrinter) {
2067
- return new Command66("start").description("Start the Actant daemon").option("--foreground", "Run in foreground (don't daemonize)", false).action(async (opts) => {
2234
+ return new Command68("start").description("Start the Actant daemon").option("--foreground", "Run in foreground (don't daemonize)", false).action(async (opts) => {
2068
2235
  const client = new RpcClient(defaultSocketPath());
2069
2236
  const alive = await client.ping();
2070
2237
  if (alive) {
@@ -2080,7 +2247,7 @@ function createDaemonStartCommand(printer = defaultPrinter) {
2080
2247
  process.exit(0);
2081
2248
  });
2082
2249
  await daemon.start();
2083
- printer.log(`${chalk17.green("Daemon started (foreground).")} PID: ${process.pid}`);
2250
+ printer.log(`${chalk20.green("Daemon started (foreground).")} PID: ${process.pid}`);
2084
2251
  printer.dim("Press Ctrl+C to stop.");
2085
2252
  await new Promise(() => {
2086
2253
  });
@@ -2118,7 +2285,7 @@ function createDaemonStartCommand(printer = defaultPrinter) {
2118
2285
  if ("connected" in child && child.connected) child.disconnect();
2119
2286
  child.unref();
2120
2287
  if (healthy) {
2121
- printer.log(`${chalk17.green("Daemon started.")} PID: ${child.pid}`);
2288
+ printer.log(`${chalk20.green("Daemon started.")} PID: ${child.pid}`);
2122
2289
  } else {
2123
2290
  const stderr = Buffer.concat(stderrChunks).toString().trim();
2124
2291
  printer.error("Daemon process started but is not responding.");
@@ -2130,9 +2297,9 @@ function createDaemonStartCommand(printer = defaultPrinter) {
2130
2297
  }
2131
2298
 
2132
2299
  // src/commands/daemon/stop.ts
2133
- import { Command as Command67 } from "commander";
2300
+ import { Command as Command69 } from "commander";
2134
2301
  function createDaemonStopCommand(printer = defaultPrinter, client) {
2135
- return new Command67("stop").description("Stop the Actant daemon").action(async () => {
2302
+ return new Command69("stop").description("Stop the Actant daemon").action(async () => {
2136
2303
  const rpc = client ?? new RpcClient(defaultSocketPath());
2137
2304
  try {
2138
2305
  await rpc.call("daemon.shutdown", {});
@@ -2144,10 +2311,10 @@ function createDaemonStopCommand(printer = defaultPrinter, client) {
2144
2311
  }
2145
2312
 
2146
2313
  // src/commands/daemon/status.ts
2147
- import { Command as Command68 } from "commander";
2148
- import chalk18 from "chalk";
2314
+ import { Command as Command70 } from "commander";
2315
+ import chalk21 from "chalk";
2149
2316
  function createDaemonStatusCommand(printer = defaultPrinter) {
2150
- return new Command68("status").description("Check if the daemon is running").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
2317
+ return new Command70("status").description("Check if the daemon is running").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
2151
2318
  const client = new RpcClient(defaultSocketPath());
2152
2319
  try {
2153
2320
  const result = await client.call("daemon.ping", {});
@@ -2167,7 +2334,7 @@ function createDaemonStatusCommand(printer = defaultPrinter) {
2167
2334
  } else if (opts.format === "quiet") {
2168
2335
  printer.log("stopped");
2169
2336
  } else {
2170
- printer.log(chalk18.red("Daemon is not running."));
2337
+ printer.log(chalk21.red("Daemon is not running."));
2171
2338
  printer.dim("Start with: actant daemon start");
2172
2339
  }
2173
2340
  process.exitCode = 1;
@@ -2177,7 +2344,7 @@ function createDaemonStatusCommand(printer = defaultPrinter) {
2177
2344
 
2178
2345
  // src/commands/daemon/index.ts
2179
2346
  function createDaemonCommand(printer) {
2180
- const cmd = new Command69("daemon").description("Manage the Actant daemon");
2347
+ const cmd = new Command71("daemon").description("Manage the Actant daemon");
2181
2348
  cmd.addCommand(createDaemonStartCommand(printer));
2182
2349
  cmd.addCommand(createDaemonStopCommand(printer));
2183
2350
  cmd.addCommand(createDaemonStatusCommand(printer));
@@ -2185,11 +2352,11 @@ function createDaemonCommand(printer) {
2185
2352
  }
2186
2353
 
2187
2354
  // src/commands/proxy.ts
2188
- import { Command as Command70 } from "commander";
2189
- import { spawn as spawn2 } from "child_process";
2355
+ import { Command as Command72 } from "commander";
2356
+ import { spawn as spawn3 } from "child_process";
2190
2357
  import { createInterface as createInterface3 } from "readline";
2191
2358
  function createProxyCommand(printer = defaultPrinter) {
2192
- return new Command70("proxy").description("Run an ACP proxy for an agent (stdin/stdout ACP protocol)").argument("<name>", "Agent name to proxy").option("--lease", "Use Session Lease mode (requires running agent)", false).option("-t, --template <template>", "Template name (auto-creates instance if not found)").action(async (name, opts) => {
2359
+ return new Command72("proxy").description("Run an ACP proxy for an agent (stdin/stdout ACP protocol)").argument("<name>", "Agent name to proxy").option("--lease", "Use Session Lease mode (requires running agent)", false).option("-t, --template <template>", "Template name (auto-creates instance if not found)").action(async (name, opts) => {
2193
2360
  if (opts.lease) {
2194
2361
  await runSessionLease(name, printer);
2195
2362
  } else {
@@ -2254,7 +2421,7 @@ async function runDirectBridge(name, opts, printer) {
2254
2421
  const command = targetInstance.command;
2255
2422
  const args = targetInstance.args;
2256
2423
  const env = { ...process.env, ...targetInstance.env };
2257
- child = spawn2(command, args, {
2424
+ child = spawn3(command, args, {
2258
2425
  cwd: workspaceDir,
2259
2426
  stdio: ["pipe", "pipe", "pipe"],
2260
2427
  env
@@ -2507,14 +2674,14 @@ function writeAcpError(id, code, message) {
2507
2674
  }
2508
2675
 
2509
2676
  // src/commands/self-update.ts
2510
- import { Command as Command71 } from "commander";
2511
- import { spawn as spawn3 } from "child_process";
2677
+ import { Command as Command73 } from "commander";
2678
+ import { spawn as spawn4 } from "child_process";
2512
2679
  import { writeFileSync, mkdirSync, readFileSync, existsSync as existsSync2 } from "fs";
2513
2680
  import { join as join2 } from "path";
2514
2681
  import { homedir } from "os";
2515
- import chalk19 from "chalk";
2682
+ import chalk22 from "chalk";
2516
2683
  function createSelfUpdateCommand() {
2517
- return new Command71("self-update").description("Update Actant from local source").option("--source <path>", "Source directory path").option("--check", "Only check for updates, don't apply").option("--force", "Skip active session warnings").option("--dry-run", "Show what would be done without doing it").option("--no-agent", "Skip agent supervisor, run script directly").option("--skip-build", "Skip build step (use pre-built dist)").action(async (opts) => {
2684
+ return new Command73("self-update").description("Update Actant from local source").option("--source <path>", "Source directory path").option("--check", "Only check for updates, don't apply").option("--force", "Skip active session warnings").option("--dry-run", "Show what would be done without doing it").option("--no-agent", "Skip agent supervisor, run script directly").option("--skip-build", "Skip build step (use pre-built dist)").action(async (opts) => {
2518
2685
  const actantHome = process.env.ACTANT_HOME || join2(homedir(), ".actant");
2519
2686
  let devSourcePath = opts.source;
2520
2687
  if (!devSourcePath) {
@@ -2527,7 +2694,7 @@ function createSelfUpdateCommand() {
2527
2694
  }
2528
2695
  if (!devSourcePath) {
2529
2696
  console.error(
2530
- chalk19.red(
2697
+ chalk22.red(
2531
2698
  "No source path specified. Use --source <path> or set devSourcePath in ~/.actant/config.json"
2532
2699
  )
2533
2700
  );
@@ -2562,37 +2729,37 @@ function createSelfUpdateCommand() {
2562
2729
  };
2563
2730
  mkdirSync(actantHome, { recursive: true });
2564
2731
  writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
2565
- console.log(chalk19.cyan("=== Actant Self-Update ==="));
2732
+ console.log(chalk22.cyan("=== Actant Self-Update ==="));
2566
2733
  console.log(`Update ID: ${updateId}`);
2567
2734
  console.log(`Source: ${devSourcePath}`);
2568
2735
  const scriptPath = join2(devSourcePath, "scripts", "self-update.js");
2569
2736
  const scriptArgs = ["--manifest", manifestPath];
2570
2737
  if (opts.dryRun) scriptArgs.push("--dry-run");
2571
2738
  if (opts.skipBuild) scriptArgs.push("--skip-build");
2572
- console.log(chalk19.gray(`Spawning: node ${scriptPath} ${scriptArgs.join(" ")}`));
2573
- const child = spawn3("node", [scriptPath, ...scriptArgs], {
2739
+ console.log(chalk22.gray(`Spawning: node ${scriptPath} ${scriptArgs.join(" ")}`));
2740
+ const child = spawn4("node", [scriptPath, ...scriptArgs], {
2574
2741
  detached: !opts.noAgent,
2575
2742
  stdio: opts.noAgent ? "inherit" : "ignore"
2576
2743
  });
2577
2744
  if (!opts.noAgent) {
2578
2745
  child.unref();
2579
- console.log(chalk19.green("Update script spawned in background. Check logs at:"));
2580
- console.log(chalk19.gray(` ${join2(actantHome, "logs", `update-${updateId}.log`)}`));
2746
+ console.log(chalk22.green("Update script spawned in background. Check logs at:"));
2747
+ console.log(chalk22.gray(` ${join2(actantHome, "logs", `update-${updateId}.log`)}`));
2581
2748
  } else {
2582
2749
  child.on("exit", (code) => {
2583
2750
  if (code === 0) {
2584
- console.log(chalk19.green("\nUpdate completed successfully!"));
2751
+ console.log(chalk22.green("\nUpdate completed successfully!"));
2585
2752
  } else if (code === 1) {
2586
- console.log(chalk19.yellow("\nUpdate failed, rolled back to previous version."));
2753
+ console.log(chalk22.yellow("\nUpdate failed, rolled back to previous version."));
2587
2754
  } else {
2588
- console.log(chalk19.red("\nSevere failure \u2014 manual intervention may be needed."));
2755
+ console.log(chalk22.red("\nSevere failure \u2014 manual intervention may be needed."));
2589
2756
  }
2590
2757
  });
2591
2758
  }
2592
2759
  });
2593
2760
  }
2594
2761
  function showVersionCheck(sourcePath, actantHome) {
2595
- console.log(chalk19.cyan("=== Version Check ==="));
2762
+ console.log(chalk22.cyan("=== Version Check ==="));
2596
2763
  try {
2597
2764
  const pkg = JSON.parse(readFileSync(join2(sourcePath, "package.json"), "utf-8"));
2598
2765
  console.log(`Source version: ${pkg.version || "unknown"}`);
@@ -2609,8 +2776,8 @@ function showVersionCheck(sourcePath, actantHome) {
2609
2776
  }
2610
2777
 
2611
2778
  // src/commands/setup/setup.ts
2612
- import { Command as Command72 } from "commander";
2613
- import chalk27 from "chalk";
2779
+ import { Command as Command74 } from "commander";
2780
+ import chalk30 from "chalk";
2614
2781
  import { getDefaultIpcPath } from "@actant/shared";
2615
2782
 
2616
2783
  // src/commands/setup/steps/choose-home.ts
@@ -2618,7 +2785,7 @@ import { join as join3 } from "path";
2618
2785
  import { homedir as homedir2 } from "os";
2619
2786
  import { mkdirSync as mkdirSync2, existsSync as existsSync3, writeFileSync as writeFileSync2 } from "fs";
2620
2787
  import { select, input } from "@inquirer/prompts";
2621
- import chalk20 from "chalk";
2788
+ import chalk23 from "chalk";
2622
2789
  var DEFAULT_HOME = join3(homedir2(), ".actant");
2623
2790
  var SUBDIRS = [
2624
2791
  "configs/skills",
@@ -2634,7 +2801,7 @@ var SUBDIRS = [
2634
2801
  ];
2635
2802
  async function chooseHome(printer) {
2636
2803
  printer.log(`
2637
- ${chalk20.cyan("[ Step 1/7 ]")} ${chalk20.bold("\u9009\u62E9\u5DE5\u4F5C\u76EE\u5F55")}
2804
+ ${chalk23.cyan("[ Step 1/7 ]")} ${chalk23.bold("\u9009\u62E9\u5DE5\u4F5C\u76EE\u5F55")}
2638
2805
  `);
2639
2806
  const choice = await select({
2640
2807
  message: "Actant \u5DE5\u4F5C\u76EE\u5F55 (ACTANT_HOME):",
@@ -2674,7 +2841,7 @@ ${chalk20.cyan("[ Step 1/7 ]")} ${chalk20.bold("\u9009\u62E9\u5DE5\u4F5C\u76EE\u
2674
2841
  if (actantHome !== DEFAULT_HOME) {
2675
2842
  printer.warn(
2676
2843
  ` \u8BF7\u5C06\u4EE5\u4E0B\u5185\u5BB9\u6DFB\u52A0\u5230\u4F60\u7684 shell \u914D\u7F6E\u6587\u4EF6 (~/.bashrc, ~/.zshrc, \u6216 $PROFILE):
2677
- ${chalk20.cyan(`export ACTANT_HOME="${actantHome}"`)}`
2844
+ ${chalk23.cyan(`export ACTANT_HOME="${actantHome}"`)}`
2678
2845
  );
2679
2846
  }
2680
2847
  return actantHome;
@@ -2689,45 +2856,36 @@ function ensureDirectoryStructure(base) {
2689
2856
  import { join as join4 } from "path";
2690
2857
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
2691
2858
  import { select as select2, input as input2, password, confirm } from "@inquirer/prompts";
2692
- import chalk21 from "chalk";
2693
- var PROVIDER_DEFAULTS = {
2694
- anthropic: { protocol: "http", baseUrl: "https://api.anthropic.com", apiKeyEnv: "ANTHROPIC_API_KEY" },
2695
- openai: { protocol: "http", baseUrl: "https://api.openai.com/v1", apiKeyEnv: "OPENAI_API_KEY" },
2696
- "openai-compatible": { protocol: "http", baseUrl: "http://localhost:11434/v1", apiKeyEnv: "LLM_API_KEY" },
2697
- custom: { protocol: "http", baseUrl: "http://localhost:8080", apiKeyEnv: "LLM_API_KEY" }
2698
- };
2859
+ import chalk24 from "chalk";
2860
+ import { modelProviderRegistry, registerBuiltinProviders } from "@actant/core";
2699
2861
  async function configureProvider(printer, actantHome) {
2700
2862
  printer.log(`
2701
- ${chalk21.cyan("[ Step 2/7 ]")} ${chalk21.bold("\u914D\u7F6E Model Provider")}
2863
+ ${chalk24.cyan("[ Step 2/7 ]")} ${chalk24.bold("\u914D\u7F6E Model Provider")}
2702
2864
  `);
2865
+ registerBuiltinProviders();
2866
+ const registeredProviders = modelProviderRegistry.list();
2867
+ const choices = registeredProviders.map((p) => ({
2868
+ name: p.displayName,
2869
+ value: p.type
2870
+ }));
2703
2871
  const providerType = await select2({
2704
2872
  message: "\u9009\u62E9 Model Provider:",
2705
2873
  default: "anthropic",
2706
- choices: [
2707
- { name: "Anthropic (Claude)", value: "anthropic" },
2708
- { name: "OpenAI", value: "openai" },
2709
- { name: "OpenAI-Compatible (vLLM / Ollama / LM Studio \u7B49)", value: "openai-compatible" },
2710
- { name: "Custom", value: "custom" }
2711
- ]
2874
+ choices
2712
2875
  });
2713
- const fallback = {
2714
- protocol: "http",
2715
- baseUrl: "",
2716
- apiKeyEnv: "LLM_API_KEY"
2717
- };
2718
- const defaults = PROVIDER_DEFAULTS[providerType] ?? fallback;
2876
+ const descriptor = modelProviderRegistry.get(providerType);
2719
2877
  const protocol = await select2({
2720
- message: "\u534F\u8BAE\u7C7B\u578B:",
2878
+ message: "API \u534F\u8BAE\u683C\u5F0F:",
2721
2879
  choices: [
2722
- { name: "HTTP / REST", value: "http" },
2723
- { name: "WebSocket", value: "websocket" },
2724
- { name: "gRPC", value: "grpc" }
2880
+ { name: "OpenAI Compatible (Chat Completions API)", value: "openai" },
2881
+ { name: "Anthropic (Messages API)", value: "anthropic" },
2882
+ { name: "Custom", value: "custom" }
2725
2883
  ],
2726
- default: defaults.protocol
2884
+ default: descriptor?.protocol ?? "custom"
2727
2885
  });
2728
2886
  const baseUrl = await input2({
2729
2887
  message: "Base URL:",
2730
- default: defaults.baseUrl,
2888
+ default: descriptor?.defaultBaseUrl ?? "http://localhost:8080",
2731
2889
  validate: (val) => {
2732
2890
  try {
2733
2891
  new URL(val);
@@ -2737,12 +2895,8 @@ ${chalk21.cyan("[ Step 2/7 ]")} ${chalk21.bold("\u914D\u7F6E Model Provider")}
2737
2895
  }
2738
2896
  }
2739
2897
  });
2740
- const apiKeyEnvName = await input2({
2741
- message: "API Key \u73AF\u5883\u53D8\u91CF\u540D:",
2742
- default: defaults.apiKeyEnv
2743
- });
2744
2898
  const apiKey = await password({
2745
- message: `${apiKeyEnvName} \u7684\u503C (API Key):`,
2899
+ message: "API Key:",
2746
2900
  mask: "*"
2747
2901
  });
2748
2902
  if (apiKey) {
@@ -2751,27 +2905,26 @@ ${chalk21.cyan("[ Step 2/7 ]")} ${chalk21.bold("\u914D\u7F6E Model Provider")}
2751
2905
  default: true
2752
2906
  });
2753
2907
  if (shouldValidate) {
2754
- printer.log(chalk21.dim(" \u6B63\u5728\u9A8C\u8BC1\u8FDE\u63A5..."));
2755
- const ok = await validateConnection(providerType, protocol, baseUrl, apiKey);
2908
+ printer.log(chalk24.dim(" \u6B63\u5728\u9A8C\u8BC1\u8FDE\u63A5..."));
2909
+ const ok = await validateConnection(protocol, baseUrl, apiKey);
2756
2910
  if (ok) {
2757
- printer.success(" \u2713 \u8FDE\u63A5\u9A8C\u8BC1\u6210\u529F");
2911
+ printer.success(" \u8FDE\u63A5\u9A8C\u8BC1\u6210\u529F");
2758
2912
  } else {
2759
- printer.warn(" \u26A0 \u8FDE\u63A5\u9A8C\u8BC1\u5931\u8D25\uFF0C\u914D\u7F6E\u5DF2\u4FDD\u5B58\u4F46\u53EF\u80FD\u9700\u8981\u68C0\u67E5");
2913
+ printer.warn(" \u8FDE\u63A5\u9A8C\u8BC1\u5931\u8D25\uFF0C\u914D\u7F6E\u5DF2\u4FDD\u5B58\u4F46\u53EF\u80FD\u9700\u8981\u68C0\u67E5");
2760
2914
  }
2761
2915
  }
2762
- printer.warn(
2763
- ` \u8BF7\u786E\u4FDD\u73AF\u5883\u53D8\u91CF ${chalk21.cyan(apiKeyEnvName)} \u5DF2\u8BBE\u7F6E:
2764
- ${chalk21.dim(`export ${apiKeyEnvName}="${apiKey.slice(0, 8)}..."`)}`
2765
- );
2766
2916
  }
2767
2917
  const providerConfig = {
2768
2918
  type: providerType,
2769
2919
  protocol,
2770
2920
  baseUrl,
2771
- apiKeyEnv: apiKeyEnvName
2921
+ ...apiKey ? { apiKey } : {}
2772
2922
  };
2773
2923
  saveProviderConfig(actantHome, providerConfig);
2774
- printer.success(`\u2713 Model Provider \u5DF2\u914D\u7F6E: ${providerType} (${protocol}) \u2192 ${baseUrl}`);
2924
+ printer.success(`Model Provider \u5DF2\u914D\u7F6E: ${providerType} (${protocol} protocol) \u2192 ${baseUrl}`);
2925
+ if (apiKey) {
2926
+ printer.success(`API Key \u5DF2\u4FDD\u5B58\u5230 ${chalk24.cyan("~/.actant/config.json")}`);
2927
+ }
2775
2928
  }
2776
2929
  function saveProviderConfig(actantHome, provider) {
2777
2930
  const configFile = join4(actantHome, "config.json");
@@ -2783,9 +2936,9 @@ function saveProviderConfig(actantHome, provider) {
2783
2936
  config.provider = provider;
2784
2937
  writeFileSync3(configFile, JSON.stringify(config, null, 2) + "\n");
2785
2938
  }
2786
- async function validateConnection(type, _protocol, baseUrl, apiKey) {
2939
+ async function validateConnection(protocol, baseUrl, apiKey) {
2787
2940
  try {
2788
- if (type === "anthropic") {
2941
+ if (protocol === "anthropic") {
2789
2942
  const res2 = await fetch(`${baseUrl}/v1/messages`, {
2790
2943
  method: "POST",
2791
2944
  headers: {
@@ -2802,7 +2955,7 @@ async function validateConnection(type, _protocol, baseUrl, apiKey) {
2802
2955
  });
2803
2956
  return res2.status === 200 || res2.status === 400;
2804
2957
  }
2805
- if (type === "openai" || type === "openai-compatible") {
2958
+ if (protocol === "openai") {
2806
2959
  const res2 = await fetch(`${baseUrl}/models`, {
2807
2960
  headers: { Authorization: `Bearer ${apiKey}` },
2808
2961
  signal: AbortSignal.timeout(1e4)
@@ -2821,12 +2974,12 @@ async function validateConnection(type, _protocol, baseUrl, apiKey) {
2821
2974
 
2822
2975
  // src/commands/setup/steps/configure-source.ts
2823
2976
  import { confirm as confirm2, input as input3, select as select3 } from "@inquirer/prompts";
2824
- import chalk22 from "chalk";
2977
+ import chalk25 from "chalk";
2825
2978
  var DEFAULT_SOURCE_NAME = "actant-hub";
2826
2979
  var DEFAULT_SOURCE_URL = "https://github.com/blackplume233/actant-hub.git";
2827
2980
  async function configureSource(printer, client) {
2828
2981
  printer.log(`
2829
- ${chalk22.cyan("[ Step 3/7 ]")} ${chalk22.bold("\u914D\u7F6E\u7EC4\u4EF6\u6E90 (Source)")}
2982
+ ${chalk25.cyan("[ Step 3/7 ]")} ${chalk25.bold("\u914D\u7F6E\u7EC4\u4EF6\u6E90 (Source)")}
2830
2983
  `);
2831
2984
  const addDefault = await confirm2({
2832
2985
  message: `\u6DFB\u52A0\u5B98\u65B9\u7EC4\u4EF6\u6E90 ${DEFAULT_SOURCE_NAME}?`,
@@ -2834,7 +2987,7 @@ ${chalk22.cyan("[ Step 3/7 ]")} ${chalk22.bold("\u914D\u7F6E\u7EC4\u4EF6\u6E90 (
2834
2987
  });
2835
2988
  if (addDefault) {
2836
2989
  try {
2837
- printer.log(chalk22.dim(` \u6B63\u5728\u6CE8\u518C ${DEFAULT_SOURCE_NAME}...`));
2990
+ printer.log(chalk25.dim(` \u6B63\u5728\u6CE8\u518C ${DEFAULT_SOURCE_NAME}...`));
2838
2991
  const result = await client.call("source.add", {
2839
2992
  name: DEFAULT_SOURCE_NAME,
2840
2993
  config: { type: "github", url: DEFAULT_SOURCE_URL, branch: "main" }
@@ -2918,10 +3071,10 @@ ${chalk22.cyan("[ Step 3/7 ]")} ${chalk22.bold("\u914D\u7F6E\u7EC4\u4EF6\u6E90 (
2918
3071
 
2919
3072
  // src/commands/setup/steps/materialize-agent.ts
2920
3073
  import { checkbox, input as input4 } from "@inquirer/prompts";
2921
- import chalk23 from "chalk";
3074
+ import chalk26 from "chalk";
2922
3075
  async function materializeAgent(printer, client) {
2923
3076
  printer.log(`
2924
- ${chalk23.cyan("[ Step 4/7 ]")} ${chalk23.bold("\u9009\u62E9\u5E76\u521B\u5EFA Agent")}
3077
+ ${chalk26.cyan("[ Step 4/7 ]")} ${chalk26.bold("\u9009\u62E9\u5E76\u521B\u5EFA Agent")}
2925
3078
  `);
2926
3079
  let templates;
2927
3080
  try {
@@ -2959,7 +3112,7 @@ ${chalk23.cyan("[ Step 4/7 ]")} ${chalk23.bold("\u9009\u62E9\u5E76\u521B\u5EFA A
2959
3112
  }
2960
3113
  });
2961
3114
  try {
2962
- printer.log(chalk23.dim(` \u6B63\u5728\u521B\u5EFA ${instanceName.trim()}...`));
3115
+ printer.log(chalk26.dim(` \u6B63\u5728\u521B\u5EFA ${instanceName.trim()}...`));
2963
3116
  await client.call("agent.create", {
2964
3117
  name: instanceName.trim(),
2965
3118
  template: templateName
@@ -2982,15 +3135,15 @@ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
2982
3135
  import { join as join5 } from "path";
2983
3136
  import { homedir as homedir3 } from "os";
2984
3137
  import { confirm as confirm3 } from "@inquirer/prompts";
2985
- import chalk24 from "chalk";
3138
+ import chalk27 from "chalk";
2986
3139
  import { isWindows as isWindows2 } from "@actant/shared";
2987
3140
  async function configureAutostart(printer) {
2988
3141
  printer.log(`
2989
- ${chalk24.cyan("[ Step 5/7 ]")} ${chalk24.bold("\u914D\u7F6E\u81EA\u52A8\u542F\u52A8")}
3142
+ ${chalk27.cyan("[ Step 5/7 ]")} ${chalk27.bold("\u914D\u7F6E\u81EA\u52A8\u542F\u52A8")}
2990
3143
  `);
2991
3144
  const platform = process.platform;
2992
3145
  const platformName = platform === "win32" ? "Windows" : platform === "darwin" ? "macOS" : "Linux";
2993
- printer.log(` \u68C0\u6D4B\u5230\u5E73\u53F0: ${chalk24.bold(platformName)}`);
3146
+ printer.log(` \u68C0\u6D4B\u5230\u5E73\u53F0: ${chalk27.bold(platformName)}`);
2994
3147
  const enable = await confirm3({
2995
3148
  message: "\u914D\u7F6E Actant Daemon \u5F00\u673A\u81EA\u542F?",
2996
3149
  default: true
@@ -3014,7 +3167,7 @@ ${chalk24.cyan("[ Step 5/7 ]")} ${chalk24.bold("\u914D\u7F6E\u81EA\u52A8\u542F\u
3014
3167
  }
3015
3168
  }
3016
3169
  function configureWindows(printer) {
3017
- printer.log(chalk24.dim(" \u6B63\u5728\u6CE8\u518C Windows Task Scheduler \u4EFB\u52A1..."));
3170
+ printer.log(chalk27.dim(" \u6B63\u5728\u6CE8\u518C Windows Task Scheduler \u4EFB\u52A1..."));
3018
3171
  const actantPath = findActantExecutable();
3019
3172
  const taskXml = `<?xml version="1.0" encoding="UTF-16"?>
3020
3173
  <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
@@ -3048,7 +3201,7 @@ function configureWindows(printer) {
3048
3201
  printer.dim(" \u5DF2\u6CE8\u518C\u4EFB\u52A1: ActantDaemon (\u767B\u5F55\u65F6\u81EA\u52A8\u542F\u52A8)");
3049
3202
  }
3050
3203
  function configureMacOS(printer) {
3051
- printer.log(chalk24.dim(" \u6B63\u5728\u751F\u6210 launchd plist..."));
3204
+ printer.log(chalk27.dim(" \u6B63\u5728\u751F\u6210 launchd plist..."));
3052
3205
  const actantPath = findActantExecutable();
3053
3206
  const plistDir = join5(homedir3(), "Library", "LaunchAgents");
3054
3207
  mkdirSync3(plistDir, { recursive: true });
@@ -3081,7 +3234,7 @@ function configureMacOS(printer) {
3081
3234
  printer.dim(` \u5DF2\u52A0\u8F7D: ${plistPath}`);
3082
3235
  }
3083
3236
  function configureLinux(printer) {
3084
- printer.log(chalk24.dim(" \u6B63\u5728\u751F\u6210 systemd user service..."));
3237
+ printer.log(chalk27.dim(" \u6B63\u5728\u751F\u6210 systemd user service..."));
3085
3238
  const actantPath = findActantExecutable();
3086
3239
  const serviceDir = join5(homedir3(), ".config", "systemd", "user");
3087
3240
  mkdirSync3(serviceDir, { recursive: true });
@@ -3119,10 +3272,10 @@ function findActantExecutable() {
3119
3272
  }
3120
3273
 
3121
3274
  // src/commands/setup/steps/hello-world.ts
3122
- import chalk25 from "chalk";
3275
+ import chalk28 from "chalk";
3123
3276
  async function helloWorld(printer, client, createdAgents) {
3124
3277
  printer.log(`
3125
- ${chalk25.cyan("[ Step 6/7 ]")} ${chalk25.bold("Hello World \u9A8C\u8BC1")}
3278
+ ${chalk28.cyan("[ Step 6/7 ]")} ${chalk28.bold("Hello World \u9A8C\u8BC1")}
3126
3279
  `);
3127
3280
  const alive = await client.ping();
3128
3281
  if (!alive) {
@@ -3141,12 +3294,12 @@ ${chalk25.cyan("[ Step 6/7 ]")} ${chalk25.bold("Hello World \u9A8C\u8BC1")}
3141
3294
  printer.dim(" \u65E0\u53EF\u7528 Agent\uFF0C\u8DF3\u8FC7\u7AEF\u5230\u7AEF\u9A8C\u8BC1");
3142
3295
  return;
3143
3296
  }
3144
- printer.log(chalk25.dim(` \u6B63\u5728\u4F7F\u7528 Agent "${testAgent}" \u8FDB\u884C\u9A8C\u8BC1...`));
3297
+ printer.log(chalk28.dim(` \u6B63\u5728\u4F7F\u7528 Agent "${testAgent}" \u8FDB\u884C\u9A8C\u8BC1...`));
3145
3298
  try {
3146
3299
  await client.call("agent.start", { name: testAgent });
3147
3300
  printer.success(` \u2713 Agent "${testAgent}" \u5DF2\u542F\u52A8`);
3148
3301
  await waitForAgentReady(client, testAgent, 15e3);
3149
- printer.log(chalk25.dim(` \u53D1\u9001\u6D4B\u8BD5\u6D88\u606F: "Hello, World!"`));
3302
+ printer.log(chalk28.dim(` \u53D1\u9001\u6D4B\u8BD5\u6D88\u606F: "Hello, World!"`));
3150
3303
  const runResult = await client.call("agent.run", {
3151
3304
  name: testAgent,
3152
3305
  prompt: "Please respond with exactly: Hello from Actant! (keep it short)"
@@ -3185,7 +3338,7 @@ async function waitForAgentReady(client, name, timeoutMs) {
3185
3338
  import { join as join6 } from "path";
3186
3339
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync5, existsSync as existsSync4 } from "fs";
3187
3340
  import { confirm as confirm4, input as input5 } from "@inquirer/prompts";
3188
- import chalk26 from "chalk";
3341
+ import chalk29 from "chalk";
3189
3342
  function detectDevSourcePath() {
3190
3343
  const candidates = [
3191
3344
  process.cwd(),
@@ -3200,7 +3353,7 @@ function detectDevSourcePath() {
3200
3353
  }
3201
3354
  async function configureUpdate(printer, actantHome) {
3202
3355
  printer.log(`
3203
- ${chalk26.cyan("[ Step 7/7 ]")} ${chalk26.bold("\u66F4\u65B0\u9009\u9879")}
3356
+ ${chalk29.cyan("[ Step 7/7 ]")} ${chalk29.bold("\u66F4\u65B0\u9009\u9879")}
3204
3357
  `);
3205
3358
  const wantConfigure = await confirm4({
3206
3359
  message: "\u914D\u7F6E\u81EA\u52A8\u66F4\u65B0\u6E90? (\u7528\u4E8E\u4ECE\u672C\u5730\u6E90\u7801\u66F4\u65B0 Actant)",
@@ -3231,14 +3384,14 @@ ${chalk26.cyan("[ Step 7/7 ]")} ${chalk26.bold("\u66F4\u65B0\u9009\u9879")}
3231
3384
  function printUpdateHelp(printer) {
3232
3385
  printer.log("");
3233
3386
  printer.dim(" \u66F4\u65B0\u547D\u4EE4:");
3234
- printer.dim(` ${chalk26.cyan("actant self-update")} \u4ECE\u6E90\u7801\u6784\u5EFA\u5E76\u66F4\u65B0`);
3235
- printer.dim(` ${chalk26.cyan("actant self-update --check")} \u68C0\u67E5\u7248\u672C\u5DEE\u5F02`);
3236
- printer.dim(` ${chalk26.cyan("npm install -g @actant/cli")} \u4ECE npm \u66F4\u65B0`);
3387
+ printer.dim(` ${chalk29.cyan("actant self-update")} \u4ECE\u6E90\u7801\u6784\u5EFA\u5E76\u66F4\u65B0`);
3388
+ printer.dim(` ${chalk29.cyan("actant self-update --check")} \u68C0\u67E5\u7248\u672C\u5DEE\u5F02`);
3389
+ printer.dim(` ${chalk29.cyan("npm install -g @actant/cli")} \u4ECE npm \u66F4\u65B0`);
3237
3390
  }
3238
3391
 
3239
3392
  // src/commands/setup/setup.ts
3240
3393
  function createSetupCommand(printer = defaultPrinter) {
3241
- return new Command72("setup").description("Interactive setup wizard \u2014 configure Actant step by step").option("--skip-home", "Skip work directory selection").option("--skip-provider", "Skip model provider configuration").option("--skip-source", "Skip component source configuration").option("--skip-agent", "Skip agent creation").option("--skip-autostart", "Skip auto-start configuration").option("--skip-hello", "Skip hello world verification").option("--skip-update", "Skip update options").action(async (opts) => {
3394
+ return new Command74("setup").description("Interactive setup wizard \u2014 configure Actant step by step").option("--skip-home", "Skip work directory selection").option("--skip-provider", "Skip model provider configuration").option("--skip-source", "Skip component source configuration").option("--skip-agent", "Skip agent creation").option("--skip-autostart", "Skip auto-start configuration").option("--skip-hello", "Skip hello world verification").option("--skip-update", "Skip update options").action(async (opts) => {
3242
3395
  try {
3243
3396
  printBanner(printer);
3244
3397
  let actantHome;
@@ -3270,7 +3423,7 @@ function createSetupCommand(printer = defaultPrinter) {
3270
3423
  client = new RpcClient(socketPath);
3271
3424
  const alive = await client.ping();
3272
3425
  if (!alive) {
3273
- printer.log(chalk27.dim("\n \u6B63\u5728\u542F\u52A8 Daemon..."));
3426
+ printer.log(chalk30.dim("\n \u6B63\u5728\u542F\u52A8 Daemon..."));
3274
3427
  daemonStartedBySetup = await tryStartDaemon(printer, socketPath);
3275
3428
  if (!daemonStartedBySetup) {
3276
3429
  printer.warn(" \u26A0 \u65E0\u6CD5\u81EA\u52A8\u542F\u52A8 Daemon\uFF0C\u8DF3\u8FC7\u9700\u8981 Daemon \u7684\u6B65\u9AA4");
@@ -3300,7 +3453,7 @@ function createSetupCommand(printer = defaultPrinter) {
3300
3453
  printSummary(printer, actantHome);
3301
3454
  } catch (err) {
3302
3455
  if (isUserCancellation(err)) {
3303
- printer.log(chalk27.dim("\n \u5DF2\u53D6\u6D88\u8BBE\u7F6E\u5411\u5BFC"));
3456
+ printer.log(chalk30.dim("\n \u5DF2\u53D6\u6D88\u8BBE\u7F6E\u5411\u5BFC"));
3304
3457
  return;
3305
3458
  }
3306
3459
  presentError(err, printer);
@@ -3310,44 +3463,44 @@ function createSetupCommand(printer = defaultPrinter) {
3310
3463
  }
3311
3464
  function printBanner(printer) {
3312
3465
  printer.log("");
3313
- printer.log(chalk27.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
3314
- printer.log(chalk27.cyan("\u2551") + chalk27.bold(" Actant Setup Wizard ") + chalk27.cyan("\u2551"));
3315
- printer.log(chalk27.cyan("\u2551") + chalk27.dim(" Build, manage, and compose AI agents ") + chalk27.cyan("\u2551"));
3316
- printer.log(chalk27.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
3466
+ printer.log(chalk30.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
3467
+ printer.log(chalk30.cyan("\u2551") + chalk30.bold(" Actant Setup Wizard ") + chalk30.cyan("\u2551"));
3468
+ printer.log(chalk30.cyan("\u2551") + chalk30.dim(" Build, manage, and compose AI agents ") + chalk30.cyan("\u2551"));
3469
+ printer.log(chalk30.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
3317
3470
  }
3318
3471
  function printSummary(printer, actantHome) {
3319
3472
  printer.log("");
3320
- printer.log(chalk27.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
3321
- printer.log(chalk27.green.bold(" Setup Complete!"));
3322
- printer.log(chalk27.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
3473
+ printer.log(chalk30.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
3474
+ printer.log(chalk30.green.bold(" Setup Complete!"));
3475
+ printer.log(chalk30.green("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"));
3323
3476
  printer.log("");
3324
3477
  printer.dim(` \u5DE5\u4F5C\u76EE\u5F55: ${actantHome}`);
3325
3478
  printer.log("");
3326
3479
  printer.log(" \u5FEB\u901F\u5F00\u59CB:");
3327
- printer.log(` ${chalk27.cyan("actant daemon start")} \u542F\u52A8 Daemon`);
3328
- printer.log(` ${chalk27.cyan("actant template list")} \u6D4F\u89C8\u6A21\u677F`);
3329
- printer.log(` ${chalk27.cyan("actant agent list")} \u67E5\u770B Agent`);
3330
- printer.log(` ${chalk27.cyan("actant agent chat <n>")} \u4E0E Agent \u5BF9\u8BDD`);
3331
- printer.log(` ${chalk27.cyan("actant setup")} \u91CD\u65B0\u8FD0\u884C\u6B64\u5411\u5BFC`);
3480
+ printer.log(` ${chalk30.cyan("actant daemon start")} \u542F\u52A8 Daemon`);
3481
+ printer.log(` ${chalk30.cyan("actant template list")} \u6D4F\u89C8\u6A21\u677F`);
3482
+ printer.log(` ${chalk30.cyan("actant agent list")} \u67E5\u770B Agent`);
3483
+ printer.log(` ${chalk30.cyan("actant agent chat <n>")} \u4E0E Agent \u5BF9\u8BDD`);
3484
+ printer.log(` ${chalk30.cyan("actant setup")} \u91CD\u65B0\u8FD0\u884C\u6B64\u5411\u5BFC`);
3332
3485
  printer.log("");
3333
3486
  printer.dim(" \u66F4\u591A\u5E2E\u52A9: actant help");
3334
3487
  printer.log("");
3335
3488
  }
3336
3489
  async function tryStartDaemon(printer, socketPath) {
3337
3490
  try {
3338
- const { fork: fork2, spawn: spawn4 } = await import("child_process");
3491
+ const { fork: fork2, spawn: spawn5 } = await import("child_process");
3339
3492
  const { join: join8 } = await import("path");
3340
3493
  const { isWindows: isWindows3, isSingleExecutable: isSingleExecutable2 } = await import("@actant/shared");
3341
3494
  let child;
3342
3495
  if (isSingleExecutable2()) {
3343
- child = spawn4(process.execPath, ["--__actant-daemon"], {
3496
+ child = spawn5(process.execPath, ["--__actant-daemon"], {
3344
3497
  detached: true,
3345
3498
  stdio: ["ignore", "ignore", "ignore"],
3346
3499
  env: process.env
3347
3500
  });
3348
3501
  } else {
3349
3502
  const daemonScript = join8(import.meta.dirname, "..", "daemon-entry.js");
3350
- child = isWindows3() ? spawn4(process.execPath, [daemonScript], {
3503
+ child = isWindows3() ? spawn5(process.execPath, [daemonScript], {
3351
3504
  detached: true,
3352
3505
  stdio: ["ignore", "ignore", "ignore"],
3353
3506
  env: process.env
@@ -3391,7 +3544,7 @@ function createProgram(socketPath, printer) {
3391
3544
  const client = new RpcClient(sock);
3392
3545
  const pkgPath = join7(import.meta.dirname, "..", "package.json");
3393
3546
  const { version } = JSON.parse(readFileSync4(pkgPath, "utf-8"));
3394
- const program = new Command73("actant").version(version).description("Actant \u2014 Build, manage, and compose AI agents");
3547
+ const program = new Command75("actant").version(version).description("Actant \u2014 Build, manage, and compose AI agents");
3395
3548
  program.addCommand(createTemplateCommand(client, printer));
3396
3549
  program.addCommand(createAgentCommand(client, printer));
3397
3550
  program.addCommand(createSkillCommand(client, printer));
@@ -3419,7 +3572,7 @@ async function run(argv) {
3419
3572
  if (!versionRequested && !helpRequested) {
3420
3573
  const sock = defaultSocketPath();
3421
3574
  const client = new RpcClient(sock);
3422
- const { startRepl } = await import("./repl-7TMOU5HY.js");
3575
+ const { startRepl } = await import("./repl-3E2HUEX6.js");
3423
3576
  await startRepl(client, sock);
3424
3577
  return;
3425
3578
  }
@@ -3448,4 +3601,4 @@ export {
3448
3601
  createProgram,
3449
3602
  run
3450
3603
  };
3451
- //# sourceMappingURL=chunk-I3QY66Y6.js.map
3604
+ //# sourceMappingURL=chunk-6OQTL4PN.js.map