@actant/cli 0.1.2 → 0.2.0

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,6 +1,8 @@
1
1
  // src/program.ts
2
- import { Command as Command72 } from "commander";
3
- import { getDefaultIpcPath } from "@actant/shared";
2
+ import { Command as Command74 } from "commander";
3
+ import { readFileSync as readFileSync4 } from "fs";
4
+ import { join as join7 } from "path";
5
+ import { getDefaultIpcPath as getDefaultIpcPath2 } from "@actant/shared";
4
6
 
5
7
  // src/client/rpc-client.ts
6
8
  import { createConnection } from "net";
@@ -572,19 +574,56 @@ function createTemplateLoadCommand(client, printer = defaultPrinter) {
572
574
 
573
575
  // src/commands/template/install.ts
574
576
  import { Command as Command5 } from "commander";
575
- function createTemplateInstallCommand(_client, printer = defaultPrinter) {
576
- 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) => {
577
581
  try {
578
582
  const at = spec.indexOf("@");
579
- if (at < 0) {
580
- 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
+ }
581
625
  process.exitCode = 1;
582
- return;
583
626
  }
584
- const source = spec.slice(0, at);
585
- printer.log(
586
- `Template install not yet implemented via RPC - use "actant source sync ${source}" to sync templates from the source.`
587
- );
588
627
  } catch (err) {
589
628
  presentError(err, printer);
590
629
  process.exitCode = 1;
@@ -604,14 +643,14 @@ function createTemplateCommand(client, printer) {
604
643
  }
605
644
 
606
645
  // src/commands/agent/index.ts
607
- import { Command as Command23 } from "commander";
646
+ import { Command as Command24 } from "commander";
608
647
 
609
648
  // src/commands/agent/create.ts
610
649
  import { existsSync } from "fs";
611
650
  import { resolve as resolve3 } from "path";
612
651
  import { createInterface } from "readline";
613
652
  import { Command as Command7 } from "commander";
614
- import chalk7 from "chalk";
653
+ import chalk8 from "chalk";
615
654
  var VALID_LAUNCH_MODES = /* @__PURE__ */ new Set(["direct", "acp-background", "acp-service", "one-shot"]);
616
655
  function askQuestion(question) {
617
656
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -626,12 +665,12 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
626
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) => {
627
666
  try {
628
667
  if (opts.launchMode && !VALID_LAUNCH_MODES.has(opts.launchMode)) {
629
- printer.error(`${chalk7.red(`Invalid launch mode: ${opts.launchMode}`)}`);
668
+ printer.error(`${chalk8.red(`Invalid launch mode: ${opts.launchMode}`)}`);
630
669
  process.exitCode = 1;
631
670
  return;
632
671
  }
633
672
  if (opts.overwrite && opts.append) {
634
- printer.error(`${chalk7.red("Cannot use both --overwrite and --append")}`);
673
+ printer.error(`${chalk8.red("Cannot use both --overwrite and --append")}`);
635
674
  process.exitCode = 1;
636
675
  return;
637
676
  }
@@ -646,7 +685,7 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
646
685
  } else {
647
686
  printer.warn(`Directory already exists: ${workDir}`);
648
687
  const answer = await askQuestion(
649
- ` ${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? `
650
689
  );
651
690
  if (answer === "o" || answer === "overwrite") {
652
691
  workDirConflict = "overwrite";
@@ -667,7 +706,7 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
667
706
  template: opts.template,
668
707
  overrides: Object.keys(overrides).length > 0 ? overrides : void 0
669
708
  });
670
- printer.log(`${chalk7.green("Agent created successfully.")}
709
+ printer.log(`${chalk8.green("Agent created successfully.")}
671
710
  `);
672
711
  printer.log(formatAgentDetail(meta, opts.format));
673
712
  } catch (err) {
@@ -679,12 +718,12 @@ function createAgentCreateCommand(client, printer = defaultPrinter) {
679
718
 
680
719
  // src/commands/agent/start.ts
681
720
  import { Command as Command8 } from "commander";
682
- import chalk8 from "chalk";
721
+ import chalk9 from "chalk";
683
722
  function createAgentStartCommand(client, printer = defaultPrinter) {
684
723
  return new Command8("start").description("Start an agent").argument("<name>", "Agent name").action(async (name) => {
685
724
  try {
686
725
  await client.call("agent.start", { name });
687
- printer.log(`${chalk8.green("Started")} ${name}`);
726
+ printer.log(`${chalk9.green("Started")} ${name}`);
688
727
  } catch (err) {
689
728
  presentError(err, printer);
690
729
  process.exitCode = 1;
@@ -694,12 +733,12 @@ function createAgentStartCommand(client, printer = defaultPrinter) {
694
733
 
695
734
  // src/commands/agent/stop.ts
696
735
  import { Command as Command9 } from "commander";
697
- import chalk9 from "chalk";
736
+ import chalk10 from "chalk";
698
737
  function createAgentStopCommand(client, printer = defaultPrinter) {
699
738
  return new Command9("stop").description("Stop a running agent").argument("<name>", "Agent name").action(async (name) => {
700
739
  try {
701
740
  await client.call("agent.stop", { name });
702
- printer.log(`${chalk9.green("Stopped")} ${name}`);
741
+ printer.log(`${chalk10.green("Stopped")} ${name}`);
703
742
  } catch (err) {
704
743
  presentError(err, printer);
705
744
  process.exitCode = 1;
@@ -741,7 +780,7 @@ function createAgentListCommand(client, printer = defaultPrinter) {
741
780
  }
742
781
 
743
782
  // src/commands/agent/adopt.ts
744
- import chalk10 from "chalk";
783
+ import chalk11 from "chalk";
745
784
  import { Command as Command12 } from "commander";
746
785
  function formatAdoptResult(result, format) {
747
786
  if (format === "json") {
@@ -751,14 +790,14 @@ function formatAdoptResult(result, format) {
751
790
  return result.name;
752
791
  }
753
792
  const lines = [
754
- chalk10.green("Agent adopted successfully."),
793
+ chalk11.green("Agent adopted successfully."),
755
794
  "",
756
- `${chalk10.bold("Name:")} ${result.name}`,
757
- `${chalk10.bold("Template:")} ${result.template}`,
758
- `${chalk10.bold("Workspace:")} ${result.workspacePath}`,
759
- `${chalk10.bold("Location:")} ${result.location}`,
760
- `${chalk10.bold("Status:")} ${result.status}`,
761
- `${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}`
762
801
  ];
763
802
  return lines.join("\n");
764
803
  }
@@ -779,7 +818,7 @@ function createAgentAdoptCommand(client, printer = defaultPrinter) {
779
818
 
780
819
  // src/commands/agent/destroy.ts
781
820
  import { Command as Command13 } from "commander";
782
- import chalk11 from "chalk";
821
+ import chalk12 from "chalk";
783
822
  function createAgentDestroyCommand(client, printer = defaultPrinter) {
784
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) => {
785
824
  if (!opts.force) {
@@ -790,7 +829,7 @@ function createAgentDestroyCommand(client, printer = defaultPrinter) {
790
829
  }
791
830
  try {
792
831
  await client.call("agent.destroy", { name });
793
- printer.log(`${chalk11.green("Destroyed")} ${name}`);
832
+ printer.log(`${chalk12.green("Destroyed")} ${name}`);
794
833
  } catch (err) {
795
834
  presentError(err, printer);
796
835
  process.exitCode = 1;
@@ -800,7 +839,7 @@ function createAgentDestroyCommand(client, printer = defaultPrinter) {
800
839
 
801
840
  // src/commands/agent/resolve.ts
802
841
  import { Command as Command14 } from "commander";
803
- import chalk12 from "chalk";
842
+ import chalk13 from "chalk";
804
843
  function createAgentResolveCommand(client, printer = defaultPrinter) {
805
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) => {
806
845
  try {
@@ -814,16 +853,16 @@ function createAgentResolveCommand(client, printer = defaultPrinter) {
814
853
  printer.log([result.command, ...result.args].join(" "));
815
854
  } else {
816
855
  if (result.created) {
817
- printer.log(`${chalk12.green("Instance created.")}
856
+ printer.log(`${chalk13.green("Instance created.")}
818
857
  `);
819
858
  }
820
- printer.log(`${chalk12.bold("Instance:")} ${result.instanceName}`);
821
- printer.log(`${chalk12.bold("Backend:")} ${result.backendType}`);
822
- printer.log(`${chalk12.bold("Workspace:")} ${result.workspaceDir}`);
823
- printer.log(`${chalk12.bold("Command:")} ${result.command}`);
824
- 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(" ")}`);
825
864
  if (result.env && Object.keys(result.env).length > 0) {
826
- printer.log(chalk12.bold("Env:"));
865
+ printer.log(chalk13.bold("Env:"));
827
866
  for (const [k, v] of Object.entries(result.env)) {
828
867
  printer.log(` ${k}=${v}`);
829
868
  }
@@ -836,15 +875,32 @@ function createAgentResolveCommand(client, printer = defaultPrinter) {
836
875
  });
837
876
  }
838
877
 
839
- // src/commands/agent/attach.ts
878
+ // src/commands/agent/open.ts
879
+ import { spawn } from "child_process";
840
880
  import { Command as Command15 } from "commander";
841
- 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";
842
898
  function createAgentAttachCommand(client, printer = defaultPrinter) {
843
- 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) => {
844
900
  try {
845
901
  const pid = parseInt(opts.pid, 10);
846
902
  if (isNaN(pid) || pid <= 0) {
847
- printer.error(chalk13.red("Invalid PID: must be a positive integer"));
903
+ printer.error(chalk15.red("Invalid PID: must be a positive integer"));
848
904
  process.exitCode = 1;
849
905
  return;
850
906
  }
@@ -853,13 +909,13 @@ function createAgentAttachCommand(client, printer = defaultPrinter) {
853
909
  try {
854
910
  metadata = JSON.parse(opts.metadata);
855
911
  } catch {
856
- printer.error(chalk13.red("Invalid --metadata: must be valid JSON"));
912
+ printer.error(chalk15.red("Invalid --metadata: must be valid JSON"));
857
913
  process.exitCode = 1;
858
914
  return;
859
915
  }
860
916
  }
861
917
  const meta = await client.call("agent.attach", { name, pid, metadata });
862
- printer.log(`${chalk13.green("Process attached.")}
918
+ printer.log(`${chalk15.green("Process attached.")}
863
919
  `);
864
920
  printer.log(formatAgentDetail(meta, opts.format));
865
921
  } catch (err) {
@@ -870,9 +926,9 @@ function createAgentAttachCommand(client, printer = defaultPrinter) {
870
926
  }
871
927
 
872
928
  // src/commands/agent/detach.ts
873
- import { Command as Command16 } from "commander";
929
+ import { Command as Command17 } from "commander";
874
930
  function createAgentDetachCommand(client, printer = defaultPrinter) {
875
- 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) => {
876
932
  try {
877
933
  const result = await client.call("agent.detach", {
878
934
  name,
@@ -890,9 +946,9 @@ function createAgentDetachCommand(client, printer = defaultPrinter) {
890
946
  }
891
947
 
892
948
  // src/commands/agent/run.ts
893
- import { Command as Command17 } from "commander";
949
+ import { Command as Command18 } from "commander";
894
950
  function createAgentRunCommand(client, printer = defaultPrinter) {
895
- 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) => {
896
952
  try {
897
953
  const rpcTimeout = (opts.timeout ?? 3e5) + 5e3;
898
954
  const result = await client.call("agent.run", {
@@ -918,9 +974,9 @@ function createAgentRunCommand(client, printer = defaultPrinter) {
918
974
  }
919
975
 
920
976
  // src/commands/agent/prompt.ts
921
- import { Command as Command18 } from "commander";
977
+ import { Command as Command19 } from "commander";
922
978
  function createAgentPromptCommand(client, printer = defaultPrinter) {
923
- 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) => {
924
980
  try {
925
981
  const result = await client.call("agent.prompt", {
926
982
  name,
@@ -941,11 +997,11 @@ function createAgentPromptCommand(client, printer = defaultPrinter) {
941
997
 
942
998
  // src/commands/agent/chat.ts
943
999
  import { createInterface as createInterface2 } from "readline";
944
- import { Command as Command19 } from "commander";
945
- import chalk14 from "chalk";
1000
+ import { Command as Command20 } from "commander";
1001
+ import chalk16 from "chalk";
946
1002
  import { AcpConnection } from "@actant/acp";
947
1003
  function createAgentChatCommand(client, printer = defaultPrinter) {
948
- 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) => {
949
1005
  try {
950
1006
  await runChat(client, name, opts, printer);
951
1007
  } catch (err) {
@@ -978,9 +1034,9 @@ async function runChat(client, name, opts, printer) {
978
1034
  async function runDaemonChat(client, name, printer) {
979
1035
  const meta = await client.call("agent.status", { name });
980
1036
  printer.log(
981
- 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]`)
982
1038
  );
983
- 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'));
984
1040
  const rl = createReadline();
985
1041
  rl.prompt();
986
1042
  let sessionId;
@@ -995,7 +1051,7 @@ async function runDaemonChat(client, name, printer) {
995
1051
  return;
996
1052
  }
997
1053
  try {
998
- process.stdout.write(chalk14.cyan("agent> "));
1054
+ process.stdout.write(chalk16.cyan("agent> "));
999
1055
  const result = await client.call("agent.prompt", {
1000
1056
  name,
1001
1057
  message: trimmed,
@@ -1009,7 +1065,7 @@ async function runDaemonChat(client, name, printer) {
1009
1065
  rl.prompt();
1010
1066
  });
1011
1067
  rl.on("close", () => {
1012
- process.stdout.write(chalk14.dim("\nChat ended.\n"));
1068
+ process.stdout.write(chalk16.dim("\nChat ended.\n"));
1013
1069
  });
1014
1070
  return new Promise((resolve9) => {
1015
1071
  rl.on("close", resolve9);
@@ -1045,9 +1101,9 @@ async function runDirectBridgeChat(client, name, opts, printer) {
1045
1101
  const agentName = initResult.agentInfo?.name ?? name;
1046
1102
  session = await conn.newSession(resolved.workspaceDir);
1047
1103
  printer.log(
1048
- chalk14.bold(`Chat with ${agentName}`) + chalk14.dim(` (direct bridge, session ${session.sessionId.slice(0, 8)}...)`)
1104
+ chalk16.bold(`Chat with ${agentName}`) + chalk16.dim(` (direct bridge, session ${session.sessionId.slice(0, 8)}...)`)
1049
1105
  );
1050
- printer.log(chalk14.dim('Type your message and press Enter. Use "exit" or Ctrl+C to quit.\n'));
1106
+ printer.log(chalk16.dim('Type your message and press Enter. Use "exit" or Ctrl+C to quit.\n'));
1051
1107
  const rl = createReadline();
1052
1108
  process.on("SIGINT", () => {
1053
1109
  if (session) {
@@ -1079,7 +1135,7 @@ async function runDirectBridgeChat(client, name, opts, printer) {
1079
1135
  rl.prompt();
1080
1136
  });
1081
1137
  rl.on("close", () => {
1082
- process.stdout.write(chalk14.dim("\nChat ended.\n"));
1138
+ process.stdout.write(chalk16.dim("\nChat ended.\n"));
1083
1139
  });
1084
1140
  await new Promise((resolve9) => {
1085
1141
  rl.on("close", resolve9);
@@ -1092,7 +1148,7 @@ function createReadline() {
1092
1148
  return createInterface2({
1093
1149
  input: process.stdin,
1094
1150
  output: process.stdout,
1095
- prompt: chalk14.green("you> "),
1151
+ prompt: chalk16.green("you> "),
1096
1152
  terminal: process.stdin.isTTY ?? false
1097
1153
  });
1098
1154
  }
@@ -1134,9 +1190,9 @@ function notificationToChunk(notification) {
1134
1190
  }
1135
1191
 
1136
1192
  // src/commands/agent/dispatch.ts
1137
- import { Command as Command20 } from "commander";
1193
+ import { Command as Command21 } from "commander";
1138
1194
  function createAgentDispatchCommand(client, printer = defaultPrinter) {
1139
- 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) => {
1195
+ 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) => {
1140
1196
  try {
1141
1197
  const result = await client.call("agent.dispatch", {
1142
1198
  name,
@@ -1156,9 +1212,9 @@ function createAgentDispatchCommand(client, printer = defaultPrinter) {
1156
1212
  }
1157
1213
 
1158
1214
  // src/commands/agent/tasks.ts
1159
- import { Command as Command21 } from "commander";
1215
+ import { Command as Command22 } from "commander";
1160
1216
  function createAgentTasksCommand(client, printer = defaultPrinter) {
1161
- 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) => {
1217
+ 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) => {
1162
1218
  try {
1163
1219
  const result = await client.call("agent.tasks", { name });
1164
1220
  if (opts.format === "json") {
@@ -1180,9 +1236,9 @@ function createAgentTasksCommand(client, printer = defaultPrinter) {
1180
1236
  }
1181
1237
 
1182
1238
  // src/commands/agent/logs.ts
1183
- import { Command as Command22 } from "commander";
1239
+ import { Command as Command23 } from "commander";
1184
1240
  function createAgentLogsCommand(client, printer = defaultPrinter) {
1185
- 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) => {
1241
+ 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) => {
1186
1242
  try {
1187
1243
  const result = await client.call("agent.logs", { name, limit: opts.limit });
1188
1244
  if (opts.format === "json") {
@@ -1208,7 +1264,7 @@ function createAgentLogsCommand(client, printer = defaultPrinter) {
1208
1264
 
1209
1265
  // src/commands/agent/index.ts
1210
1266
  function createAgentCommand(client, printer) {
1211
- const cmd = new Command23("agent").description("Manage agent instances");
1267
+ const cmd = new Command24("agent").description("Manage agent instances");
1212
1268
  cmd.addCommand(createAgentCreateCommand(client, printer));
1213
1269
  cmd.addCommand(createAgentStartCommand(client, printer));
1214
1270
  cmd.addCommand(createAgentStopCommand(client, printer));
@@ -1217,6 +1273,7 @@ function createAgentCommand(client, printer) {
1217
1273
  cmd.addCommand(createAgentAdoptCommand(client, printer));
1218
1274
  cmd.addCommand(createAgentDestroyCommand(client, printer));
1219
1275
  cmd.addCommand(createAgentResolveCommand(client, printer));
1276
+ cmd.addCommand(createAgentOpenCommand(client, printer));
1220
1277
  cmd.addCommand(createAgentAttachCommand(client, printer));
1221
1278
  cmd.addCommand(createAgentDetachCommand(client, printer));
1222
1279
  cmd.addCommand(createAgentRunCommand(client, printer));
@@ -1229,13 +1286,13 @@ function createAgentCommand(client, printer) {
1229
1286
  }
1230
1287
 
1231
1288
  // src/commands/help.ts
1232
- import { Command as Command24 } from "commander";
1233
- import chalk15 from "chalk";
1289
+ import { Command as Command25 } from "commander";
1290
+ import chalk17 from "chalk";
1234
1291
 
1235
1292
  // package.json
1236
1293
  var package_default = {
1237
1294
  name: "@actant/cli",
1238
- version: "0.1.2",
1295
+ version: "0.2.0",
1239
1296
  description: "CLI for the Actant AI agent platform \u2014 build, manage, and compose AI agents",
1240
1297
  type: "module",
1241
1298
  license: "MIT",
@@ -1247,11 +1304,27 @@ var package_default = {
1247
1304
  },
1248
1305
  homepage: "https://github.com/blackplume233/Actant#readme",
1249
1306
  bugs: "https://github.com/blackplume233/Actant/issues",
1250
- keywords: ["actant", "ai-agent", "cli", "agent-platform"],
1307
+ keywords: [
1308
+ "actant",
1309
+ "ai-agent",
1310
+ "cli",
1311
+ "agent-platform"
1312
+ ],
1251
1313
  publishConfig: {
1252
1314
  access: "public"
1253
1315
  },
1254
- files: ["dist", "scripts/postinstall.mjs"],
1316
+ files: [
1317
+ "dist",
1318
+ "scripts/postinstall.mjs"
1319
+ ],
1320
+ main: "./dist/index.js",
1321
+ types: "./dist/index.d.ts",
1322
+ exports: {
1323
+ ".": {
1324
+ import: "./dist/index.js",
1325
+ types: "./dist/index.d.ts"
1326
+ }
1327
+ },
1255
1328
  bin: {
1256
1329
  actant: "./dist/bin/actant.js"
1257
1330
  },
@@ -1268,7 +1341,9 @@ var package_default = {
1268
1341
  "@actant/acp": "workspace:*",
1269
1342
  "@actant/api": "workspace:*",
1270
1343
  "@actant/core": "workspace:*",
1344
+ "@actant/pi": "workspace:*",
1271
1345
  "@actant/shared": "workspace:*",
1346
+ "@inquirer/prompts": "^8.3.0",
1272
1347
  chalk: "^5.6.2",
1273
1348
  "cli-table3": "^0.6.5",
1274
1349
  commander: "^14.0.3"
@@ -1280,42 +1355,42 @@ function showOverview() {
1280
1355
  const version = package_default.version ?? "0.1.0";
1281
1356
  const lines = [
1282
1357
  "",
1283
- chalk15.bold(" Actant \u2014 Build, manage, and compose AI agents"),
1284
- chalk15.gray(` v${version}`),
1358
+ chalk17.bold(" Actant \u2014 Build, manage, and compose AI agents"),
1359
+ chalk17.gray(` v${version}`),
1285
1360
  "",
1286
- chalk15.bold(" Quick Start:"),
1287
- ` ${chalk15.cyan("actant daemon start")} Start the daemon`,
1288
- ` ${chalk15.cyan("actant agent create my-agent")} Create an Agent`,
1289
- ` ${chalk15.cyan("actant agent start my-agent")} Start an Agent`,
1290
- ` ${chalk15.cyan("actant agent chat my-agent")} Chat with an Agent`,
1361
+ chalk17.bold(" Quick Start:"),
1362
+ ` ${chalk17.cyan("actant daemon start")} Start the daemon`,
1363
+ ` ${chalk17.cyan("actant agent create my-agent")} Create an Agent`,
1364
+ ` ${chalk17.cyan("actant agent start my-agent")} Start an Agent`,
1365
+ ` ${chalk17.cyan("actant agent chat my-agent")} Chat with an Agent`,
1291
1366
  "",
1292
- chalk15.bold(" Agent Management:"),
1293
- ` ${chalk15.cyan("agent")} create|start|stop|list|chat|run Agent lifecycle`,
1294
- ` ${chalk15.cyan("agent adopt")} <path> Adopt existing workspace`,
1295
- ` ${chalk15.cyan("template")} list|show Agent templates`,
1296
- ` ${chalk15.cyan("proxy")} <name> ACP proxy forwarding`,
1367
+ chalk17.bold(" Agent Management:"),
1368
+ ` ${chalk17.cyan("agent")} create|start|stop|list|chat|run Agent lifecycle`,
1369
+ ` ${chalk17.cyan("agent adopt")} <path> Adopt existing workspace`,
1370
+ ` ${chalk17.cyan("template")} list|show Agent templates`,
1371
+ ` ${chalk17.cyan("proxy")} <name> ACP proxy forwarding`,
1297
1372
  "",
1298
- chalk15.bold(" Component Management:"),
1299
- ` ${chalk15.cyan("skill")} list|add|remove|show Manage skills`,
1300
- ` ${chalk15.cyan("prompt")} list|add|remove|show Manage prompts`,
1301
- ` ${chalk15.cyan("mcp")} list|show Manage MCP server configs`,
1302
- ` ${chalk15.cyan("workflow")} list|show Manage workflows`,
1303
- ` ${chalk15.cyan("plugin")} list|add|remove|show Manage plugins`,
1373
+ chalk17.bold(" Component Management:"),
1374
+ ` ${chalk17.cyan("skill")} list|add|remove|show Manage skills`,
1375
+ ` ${chalk17.cyan("prompt")} list|add|remove|show Manage prompts`,
1376
+ ` ${chalk17.cyan("mcp")} list|show Manage MCP server configs`,
1377
+ ` ${chalk17.cyan("workflow")} list|show Manage workflows`,
1378
+ ` ${chalk17.cyan("plugin")} list|add|remove|show Manage plugins`,
1304
1379
  "",
1305
- chalk15.bold(" Ecosystem:"),
1306
- ` ${chalk15.cyan("source")} list|add|remove|sync Manage component sources`,
1307
- ` ${chalk15.cyan("preset")} list|apply Manage preset packs`,
1380
+ chalk17.bold(" Ecosystem:"),
1381
+ ` ${chalk17.cyan("source")} list|add|remove|sync Manage component sources`,
1382
+ ` ${chalk17.cyan("preset")} list|apply Manage preset packs`,
1308
1383
  "",
1309
- chalk15.bold(" Scheduling:"),
1310
- ` ${chalk15.cyan("schedule")} list Manage employee agent scheduling`,
1384
+ chalk17.bold(" Scheduling:"),
1385
+ ` ${chalk17.cyan("schedule")} list Manage employee agent scheduling`,
1311
1386
  "",
1312
- chalk15.bold(" System:"),
1313
- ` ${chalk15.cyan("daemon")} start|stop|status Daemon management`,
1314
- ` ${chalk15.cyan("help")} [command] Show help`,
1315
- ` ${chalk15.cyan("--version")} Show version`,
1387
+ chalk17.bold(" System:"),
1388
+ ` ${chalk17.cyan("daemon")} start|stop|status Daemon management`,
1389
+ ` ${chalk17.cyan("help")} [command] Show help`,
1390
+ ` ${chalk17.cyan("--version")} Show version`,
1316
1391
  "",
1317
- chalk15.bold(" Tips:"),
1318
- chalk15.gray(" Use 'actant help <command>' for detailed help on a command"),
1392
+ chalk17.bold(" Tips:"),
1393
+ chalk17.gray(" Use 'actant help <command>' for detailed help on a command"),
1319
1394
  ""
1320
1395
  ];
1321
1396
  process.stdout.write(lines.join("\n"));
@@ -1326,13 +1401,13 @@ function showCommandHelp(program, commandName) {
1326
1401
  subcmd.outputHelp();
1327
1402
  } else {
1328
1403
  process.stdout.write(
1329
- chalk15.red(`Unknown command: ${commandName}
1330
- `) + chalk15.gray("Run 'actant help' to see available commands.\n")
1404
+ chalk17.red(`Unknown command: ${commandName}
1405
+ `) + chalk17.gray("Run 'actant help' to see available commands.\n")
1331
1406
  );
1332
1407
  }
1333
1408
  }
1334
1409
  function createHelpCommand() {
1335
- return new Command24("help").argument("[command]", "Command to get help for").description("Show help information").action(function(command) {
1410
+ return new Command25("help").argument("[command]", "Command to get help for").description("Show help information").action(function(command) {
1336
1411
  const program = this.parent;
1337
1412
  if (command) {
1338
1413
  showCommandHelp(program, command);
@@ -1343,12 +1418,12 @@ function createHelpCommand() {
1343
1418
  }
1344
1419
 
1345
1420
  // src/commands/skill/index.ts
1346
- import { Command as Command30 } from "commander";
1421
+ import { Command as Command31 } from "commander";
1347
1422
 
1348
1423
  // src/commands/skill/list.ts
1349
- import { Command as Command25 } from "commander";
1424
+ import { Command as Command26 } from "commander";
1350
1425
  function createSkillListCommand(client, printer = defaultPrinter) {
1351
- return new Command25("list").alias("ls").description("List all loaded skills").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1426
+ return new Command26("list").alias("ls").description("List all loaded skills").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1352
1427
  try {
1353
1428
  const skills = await client.call("skill.list", {});
1354
1429
  printer.log(formatSkillList(skills, opts.format));
@@ -1360,9 +1435,9 @@ function createSkillListCommand(client, printer = defaultPrinter) {
1360
1435
  }
1361
1436
 
1362
1437
  // src/commands/skill/show.ts
1363
- import { Command as Command26 } from "commander";
1438
+ import { Command as Command27 } from "commander";
1364
1439
  function createSkillShowCommand(client, printer = defaultPrinter) {
1365
- 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) => {
1440
+ 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) => {
1366
1441
  try {
1367
1442
  const skill = await client.call("skill.get", { name });
1368
1443
  printer.log(formatSkillDetail(skill, opts.format));
@@ -1376,9 +1451,9 @@ function createSkillShowCommand(client, printer = defaultPrinter) {
1376
1451
  // src/commands/skill/add.ts
1377
1452
  import { readFile } from "fs/promises";
1378
1453
  import { resolve as resolve4 } from "path";
1379
- import { Command as Command27 } from "commander";
1454
+ import { Command as Command28 } from "commander";
1380
1455
  function createSkillAddCommand(client, printer = defaultPrinter) {
1381
- return new Command27("add").description("Add a skill from a JSON file").argument("<file>", "Path to skill definition JSON file").action(async (file) => {
1456
+ return new Command28("add").description("Add a skill from a JSON file").argument("<file>", "Path to skill definition JSON file").action(async (file) => {
1382
1457
  try {
1383
1458
  const raw = await readFile(resolve4(file), "utf-8");
1384
1459
  const component = JSON.parse(raw);
@@ -1392,9 +1467,9 @@ function createSkillAddCommand(client, printer = defaultPrinter) {
1392
1467
  }
1393
1468
 
1394
1469
  // src/commands/skill/remove.ts
1395
- import { Command as Command28 } from "commander";
1470
+ import { Command as Command29 } from "commander";
1396
1471
  function createSkillRemoveCommand(client, printer = defaultPrinter) {
1397
- return new Command28("remove").alias("rm").description("Remove a loaded skill").argument("<name>", "Skill name").action(async (name) => {
1472
+ return new Command29("remove").alias("rm").description("Remove a loaded skill").argument("<name>", "Skill name").action(async (name) => {
1398
1473
  try {
1399
1474
  const result = await client.call("skill.remove", { name });
1400
1475
  if (result.success) {
@@ -1410,9 +1485,9 @@ function createSkillRemoveCommand(client, printer = defaultPrinter) {
1410
1485
  }
1411
1486
 
1412
1487
  // src/commands/skill/export.ts
1413
- import { Command as Command29 } from "commander";
1488
+ import { Command as Command30 } from "commander";
1414
1489
  function createSkillExportCommand(client, printer = defaultPrinter) {
1415
- 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) => {
1490
+ 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) => {
1416
1491
  try {
1417
1492
  const outPath = opts.out.replace("{name}", name);
1418
1493
  await client.call("skill.export", { name, filePath: outPath });
@@ -1426,7 +1501,7 @@ function createSkillExportCommand(client, printer = defaultPrinter) {
1426
1501
 
1427
1502
  // src/commands/skill/index.ts
1428
1503
  function createSkillCommand(client, printer) {
1429
- const cmd = new Command30("skill").description("Manage loaded skills");
1504
+ const cmd = new Command31("skill").description("Manage loaded skills");
1430
1505
  cmd.addCommand(createSkillListCommand(client, printer));
1431
1506
  cmd.addCommand(createSkillShowCommand(client, printer));
1432
1507
  cmd.addCommand(createSkillAddCommand(client, printer));
@@ -1436,12 +1511,12 @@ function createSkillCommand(client, printer) {
1436
1511
  }
1437
1512
 
1438
1513
  // src/commands/prompt/index.ts
1439
- import { Command as Command36 } from "commander";
1514
+ import { Command as Command37 } from "commander";
1440
1515
 
1441
1516
  // src/commands/prompt/list.ts
1442
- import { Command as Command31 } from "commander";
1517
+ import { Command as Command32 } from "commander";
1443
1518
  function createPromptListCommand(client, printer = defaultPrinter) {
1444
- return new Command31("list").alias("ls").description("List all loaded prompts").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1519
+ return new Command32("list").alias("ls").description("List all loaded prompts").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1445
1520
  try {
1446
1521
  const prompts = await client.call("prompt.list", {});
1447
1522
  printer.log(formatPromptList(prompts, opts.format));
@@ -1453,9 +1528,9 @@ function createPromptListCommand(client, printer = defaultPrinter) {
1453
1528
  }
1454
1529
 
1455
1530
  // src/commands/prompt/show.ts
1456
- import { Command as Command32 } from "commander";
1531
+ import { Command as Command33 } from "commander";
1457
1532
  function createPromptShowCommand(client, printer = defaultPrinter) {
1458
- 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) => {
1533
+ 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) => {
1459
1534
  try {
1460
1535
  const prompt = await client.call("prompt.get", { name });
1461
1536
  printer.log(formatPromptDetail(prompt, opts.format));
@@ -1469,9 +1544,9 @@ function createPromptShowCommand(client, printer = defaultPrinter) {
1469
1544
  // src/commands/prompt/add.ts
1470
1545
  import { readFile as readFile2 } from "fs/promises";
1471
1546
  import { resolve as resolve5 } from "path";
1472
- import { Command as Command33 } from "commander";
1547
+ import { Command as Command34 } from "commander";
1473
1548
  function createPromptAddCommand(client, printer = defaultPrinter) {
1474
- return new Command33("add").description("Add a prompt from a JSON file").argument("<file>", "Path to prompt definition JSON file").action(async (file) => {
1549
+ return new Command34("add").description("Add a prompt from a JSON file").argument("<file>", "Path to prompt definition JSON file").action(async (file) => {
1475
1550
  try {
1476
1551
  const raw = await readFile2(resolve5(file), "utf-8");
1477
1552
  const component = JSON.parse(raw);
@@ -1485,9 +1560,9 @@ function createPromptAddCommand(client, printer = defaultPrinter) {
1485
1560
  }
1486
1561
 
1487
1562
  // src/commands/prompt/remove.ts
1488
- import { Command as Command34 } from "commander";
1563
+ import { Command as Command35 } from "commander";
1489
1564
  function createPromptRemoveCommand(client, printer = defaultPrinter) {
1490
- return new Command34("remove").alias("rm").description("Remove a loaded prompt").argument("<name>", "Prompt name").action(async (name) => {
1565
+ return new Command35("remove").alias("rm").description("Remove a loaded prompt").argument("<name>", "Prompt name").action(async (name) => {
1491
1566
  try {
1492
1567
  const result = await client.call("prompt.remove", { name });
1493
1568
  if (result.success) {
@@ -1503,9 +1578,9 @@ function createPromptRemoveCommand(client, printer = defaultPrinter) {
1503
1578
  }
1504
1579
 
1505
1580
  // src/commands/prompt/export.ts
1506
- import { Command as Command35 } from "commander";
1581
+ import { Command as Command36 } from "commander";
1507
1582
  function createPromptExportCommand(client, printer = defaultPrinter) {
1508
- 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) => {
1583
+ 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) => {
1509
1584
  try {
1510
1585
  const outPath = opts.out.replace("{name}", name);
1511
1586
  await client.call("prompt.export", { name, filePath: outPath });
@@ -1519,7 +1594,7 @@ function createPromptExportCommand(client, printer = defaultPrinter) {
1519
1594
 
1520
1595
  // src/commands/prompt/index.ts
1521
1596
  function createPromptCommand(client, printer) {
1522
- const cmd = new Command36("prompt").description("Manage loaded prompts");
1597
+ const cmd = new Command37("prompt").description("Manage loaded prompts");
1523
1598
  cmd.addCommand(createPromptListCommand(client, printer));
1524
1599
  cmd.addCommand(createPromptShowCommand(client, printer));
1525
1600
  cmd.addCommand(createPromptAddCommand(client, printer));
@@ -1529,12 +1604,12 @@ function createPromptCommand(client, printer) {
1529
1604
  }
1530
1605
 
1531
1606
  // src/commands/mcp/index.ts
1532
- import { Command as Command42 } from "commander";
1607
+ import { Command as Command43 } from "commander";
1533
1608
 
1534
1609
  // src/commands/mcp/list.ts
1535
- import { Command as Command37 } from "commander";
1610
+ import { Command as Command38 } from "commander";
1536
1611
  function createMcpListCommand(client, printer = defaultPrinter) {
1537
- 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) => {
1612
+ 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) => {
1538
1613
  try {
1539
1614
  const servers = await client.call("mcp.list", {});
1540
1615
  printer.log(formatMcpList(servers, opts.format));
@@ -1546,9 +1621,9 @@ function createMcpListCommand(client, printer = defaultPrinter) {
1546
1621
  }
1547
1622
 
1548
1623
  // src/commands/mcp/show.ts
1549
- import { Command as Command38 } from "commander";
1624
+ import { Command as Command39 } from "commander";
1550
1625
  function createMcpShowCommand(client, printer = defaultPrinter) {
1551
- 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) => {
1626
+ 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) => {
1552
1627
  try {
1553
1628
  const server = await client.call("mcp.get", { name });
1554
1629
  printer.log(formatMcpDetail(server, opts.format));
@@ -1562,9 +1637,9 @@ function createMcpShowCommand(client, printer = defaultPrinter) {
1562
1637
  // src/commands/mcp/add.ts
1563
1638
  import { readFile as readFile3 } from "fs/promises";
1564
1639
  import { resolve as resolve6 } from "path";
1565
- import { Command as Command39 } from "commander";
1640
+ import { Command as Command40 } from "commander";
1566
1641
  function createMcpAddCommand(client, printer = defaultPrinter) {
1567
- 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) => {
1642
+ 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) => {
1568
1643
  try {
1569
1644
  const raw = await readFile3(resolve6(file), "utf-8");
1570
1645
  const component = JSON.parse(raw);
@@ -1578,9 +1653,9 @@ function createMcpAddCommand(client, printer = defaultPrinter) {
1578
1653
  }
1579
1654
 
1580
1655
  // src/commands/mcp/remove.ts
1581
- import { Command as Command40 } from "commander";
1656
+ import { Command as Command41 } from "commander";
1582
1657
  function createMcpRemoveCommand(client, printer = defaultPrinter) {
1583
- return new Command40("remove").alias("rm").description("Remove a loaded MCP server config").argument("<name>", "MCP server name").action(async (name) => {
1658
+ return new Command41("remove").alias("rm").description("Remove a loaded MCP server config").argument("<name>", "MCP server name").action(async (name) => {
1584
1659
  try {
1585
1660
  const result = await client.call("mcp.remove", { name });
1586
1661
  if (result.success) {
@@ -1596,9 +1671,9 @@ function createMcpRemoveCommand(client, printer = defaultPrinter) {
1596
1671
  }
1597
1672
 
1598
1673
  // src/commands/mcp/export.ts
1599
- import { Command as Command41 } from "commander";
1674
+ import { Command as Command42 } from "commander";
1600
1675
  function createMcpExportCommand(client, printer = defaultPrinter) {
1601
- 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) => {
1676
+ 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) => {
1602
1677
  try {
1603
1678
  const outPath = opts.out.replace("{name}", name);
1604
1679
  await client.call("mcp.export", { name, filePath: outPath });
@@ -1612,7 +1687,7 @@ function createMcpExportCommand(client, printer = defaultPrinter) {
1612
1687
 
1613
1688
  // src/commands/mcp/index.ts
1614
1689
  function createMcpCommand(client, printer) {
1615
- const cmd = new Command42("mcp").description("Manage loaded MCP server configs");
1690
+ const cmd = new Command43("mcp").description("Manage loaded MCP server configs");
1616
1691
  cmd.addCommand(createMcpListCommand(client, printer));
1617
1692
  cmd.addCommand(createMcpShowCommand(client, printer));
1618
1693
  cmd.addCommand(createMcpAddCommand(client, printer));
@@ -1622,12 +1697,12 @@ function createMcpCommand(client, printer) {
1622
1697
  }
1623
1698
 
1624
1699
  // src/commands/workflow/index.ts
1625
- import { Command as Command48 } from "commander";
1700
+ import { Command as Command49 } from "commander";
1626
1701
 
1627
1702
  // src/commands/workflow/list.ts
1628
- import { Command as Command43 } from "commander";
1703
+ import { Command as Command44 } from "commander";
1629
1704
  function createWorkflowListCommand(client, printer = defaultPrinter) {
1630
- return new Command43("list").alias("ls").description("List all loaded workflows").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1705
+ return new Command44("list").alias("ls").description("List all loaded workflows").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1631
1706
  try {
1632
1707
  const workflows = await client.call("workflow.list", {});
1633
1708
  printer.log(formatWorkflowList(workflows, opts.format));
@@ -1639,9 +1714,9 @@ function createWorkflowListCommand(client, printer = defaultPrinter) {
1639
1714
  }
1640
1715
 
1641
1716
  // src/commands/workflow/show.ts
1642
- import { Command as Command44 } from "commander";
1717
+ import { Command as Command45 } from "commander";
1643
1718
  function createWorkflowShowCommand(client, printer = defaultPrinter) {
1644
- 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) => {
1719
+ 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) => {
1645
1720
  try {
1646
1721
  const workflow = await client.call("workflow.get", { name });
1647
1722
  printer.log(formatWorkflowDetail(workflow, opts.format));
@@ -1655,9 +1730,9 @@ function createWorkflowShowCommand(client, printer = defaultPrinter) {
1655
1730
  // src/commands/workflow/add.ts
1656
1731
  import { readFile as readFile4 } from "fs/promises";
1657
1732
  import { resolve as resolve7 } from "path";
1658
- import { Command as Command45 } from "commander";
1733
+ import { Command as Command46 } from "commander";
1659
1734
  function createWorkflowAddCommand(client, printer = defaultPrinter) {
1660
- return new Command45("add").description("Add a workflow from a JSON file").argument("<file>", "Path to workflow definition JSON file").action(async (file) => {
1735
+ return new Command46("add").description("Add a workflow from a JSON file").argument("<file>", "Path to workflow definition JSON file").action(async (file) => {
1661
1736
  try {
1662
1737
  const raw = await readFile4(resolve7(file), "utf-8");
1663
1738
  const component = JSON.parse(raw);
@@ -1671,9 +1746,9 @@ function createWorkflowAddCommand(client, printer = defaultPrinter) {
1671
1746
  }
1672
1747
 
1673
1748
  // src/commands/workflow/remove.ts
1674
- import { Command as Command46 } from "commander";
1749
+ import { Command as Command47 } from "commander";
1675
1750
  function createWorkflowRemoveCommand(client, printer = defaultPrinter) {
1676
- return new Command46("remove").alias("rm").description("Remove a loaded workflow").argument("<name>", "Workflow name").action(async (name) => {
1751
+ return new Command47("remove").alias("rm").description("Remove a loaded workflow").argument("<name>", "Workflow name").action(async (name) => {
1677
1752
  try {
1678
1753
  const result = await client.call("workflow.remove", { name });
1679
1754
  if (result.success) {
@@ -1689,9 +1764,9 @@ function createWorkflowRemoveCommand(client, printer = defaultPrinter) {
1689
1764
  }
1690
1765
 
1691
1766
  // src/commands/workflow/export.ts
1692
- import { Command as Command47 } from "commander";
1767
+ import { Command as Command48 } from "commander";
1693
1768
  function createWorkflowExportCommand(client, printer = defaultPrinter) {
1694
- 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) => {
1769
+ 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) => {
1695
1770
  try {
1696
1771
  const outPath = opts.out.replace("{name}", name);
1697
1772
  await client.call("workflow.export", { name, filePath: outPath });
@@ -1705,7 +1780,7 @@ function createWorkflowExportCommand(client, printer = defaultPrinter) {
1705
1780
 
1706
1781
  // src/commands/workflow/index.ts
1707
1782
  function createWorkflowCommand(client, printer) {
1708
- const cmd = new Command48("workflow").description("Manage loaded workflows");
1783
+ const cmd = new Command49("workflow").description("Manage loaded workflows");
1709
1784
  cmd.addCommand(createWorkflowListCommand(client, printer));
1710
1785
  cmd.addCommand(createWorkflowShowCommand(client, printer));
1711
1786
  cmd.addCommand(createWorkflowAddCommand(client, printer));
@@ -1715,12 +1790,12 @@ function createWorkflowCommand(client, printer) {
1715
1790
  }
1716
1791
 
1717
1792
  // src/commands/plugin/index.ts
1718
- import { Command as Command54 } from "commander";
1793
+ import { Command as Command55 } from "commander";
1719
1794
 
1720
1795
  // src/commands/plugin/list.ts
1721
- import { Command as Command49 } from "commander";
1796
+ import { Command as Command50 } from "commander";
1722
1797
  function createPluginListCommand(client, printer = defaultPrinter) {
1723
- return new Command49("list").alias("ls").description("List all plugins").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1798
+ return new Command50("list").alias("ls").description("List all plugins").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1724
1799
  try {
1725
1800
  const plugins = await client.call("plugin.list", {});
1726
1801
  printer.log(formatPluginList(plugins, opts.format));
@@ -1732,9 +1807,9 @@ function createPluginListCommand(client, printer = defaultPrinter) {
1732
1807
  }
1733
1808
 
1734
1809
  // src/commands/plugin/show.ts
1735
- import { Command as Command50 } from "commander";
1810
+ import { Command as Command51 } from "commander";
1736
1811
  function createPluginShowCommand(client, printer = defaultPrinter) {
1737
- 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) => {
1812
+ 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) => {
1738
1813
  try {
1739
1814
  const plugin = await client.call("plugin.get", { name });
1740
1815
  printer.log(formatPluginDetail(plugin, opts.format));
@@ -1748,9 +1823,9 @@ function createPluginShowCommand(client, printer = defaultPrinter) {
1748
1823
  // src/commands/plugin/add.ts
1749
1824
  import { readFile as readFile5 } from "fs/promises";
1750
1825
  import { resolve as resolve8 } from "path";
1751
- import { Command as Command51 } from "commander";
1826
+ import { Command as Command52 } from "commander";
1752
1827
  function createPluginAddCommand(client, printer = defaultPrinter) {
1753
- return new Command51("add").description("Add a plugin from a JSON file").argument("<file>", "Path to plugin definition JSON file").action(async (file) => {
1828
+ return new Command52("add").description("Add a plugin from a JSON file").argument("<file>", "Path to plugin definition JSON file").action(async (file) => {
1754
1829
  try {
1755
1830
  const raw = await readFile5(resolve8(file), "utf-8");
1756
1831
  const component = JSON.parse(raw);
@@ -1764,9 +1839,9 @@ function createPluginAddCommand(client, printer = defaultPrinter) {
1764
1839
  }
1765
1840
 
1766
1841
  // src/commands/plugin/remove.ts
1767
- import { Command as Command52 } from "commander";
1842
+ import { Command as Command53 } from "commander";
1768
1843
  function createPluginRemoveCommand(client, printer = defaultPrinter) {
1769
- return new Command52("remove").alias("rm").description("Remove a loaded plugin").argument("<name>", "Plugin name").action(async (name) => {
1844
+ return new Command53("remove").alias("rm").description("Remove a loaded plugin").argument("<name>", "Plugin name").action(async (name) => {
1770
1845
  try {
1771
1846
  const result = await client.call("plugin.remove", { name });
1772
1847
  if (result.success) {
@@ -1782,9 +1857,9 @@ function createPluginRemoveCommand(client, printer = defaultPrinter) {
1782
1857
  }
1783
1858
 
1784
1859
  // src/commands/plugin/export.ts
1785
- import { Command as Command53 } from "commander";
1860
+ import { Command as Command54 } from "commander";
1786
1861
  function createPluginExportCommand(client, printer = defaultPrinter) {
1787
- 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) => {
1862
+ 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) => {
1788
1863
  try {
1789
1864
  const outPath = opts.out.replace("{name}", name);
1790
1865
  await client.call("plugin.export", { name, filePath: outPath });
@@ -1798,7 +1873,7 @@ function createPluginExportCommand(client, printer = defaultPrinter) {
1798
1873
 
1799
1874
  // src/commands/plugin/index.ts
1800
1875
  function createPluginCommand(client, printer) {
1801
- const cmd = new Command54("plugin").description("Manage loaded plugins");
1876
+ const cmd = new Command55("plugin").description("Manage loaded plugins");
1802
1877
  cmd.addCommand(createPluginListCommand(client, printer));
1803
1878
  cmd.addCommand(createPluginShowCommand(client, printer));
1804
1879
  cmd.addCommand(createPluginAddCommand(client, printer));
@@ -1808,12 +1883,12 @@ function createPluginCommand(client, printer) {
1808
1883
  }
1809
1884
 
1810
1885
  // src/commands/source/index.ts
1811
- import { Command as Command59 } from "commander";
1886
+ import { Command as Command60 } from "commander";
1812
1887
 
1813
1888
  // src/commands/source/list.ts
1814
- import { Command as Command55 } from "commander";
1889
+ import { Command as Command56 } from "commander";
1815
1890
  function createSourceListCommand(client, printer = defaultPrinter) {
1816
- return new Command55("list").alias("ls").description("List registered component sources").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1891
+ return new Command56("list").alias("ls").description("List registered component sources").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
1817
1892
  try {
1818
1893
  const sources = await client.call("source.list", {});
1819
1894
  if (opts.format === "json") {
@@ -1839,9 +1914,9 @@ function createSourceListCommand(client, printer = defaultPrinter) {
1839
1914
  }
1840
1915
 
1841
1916
  // src/commands/source/add.ts
1842
- import { Command as Command56 } from "commander";
1917
+ import { Command as Command57 } from "commander";
1843
1918
  function createSourceAddCommand(client, printer = defaultPrinter) {
1844
- 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) => {
1919
+ 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) => {
1845
1920
  try {
1846
1921
  const config = opts.type === "local" ? { type: "local", path: urlOrPath } : { type: "github", url: urlOrPath, branch: opts.branch };
1847
1922
  const result = await client.call("source.add", { name: opts.name, config });
@@ -1857,9 +1932,9 @@ function createSourceAddCommand(client, printer = defaultPrinter) {
1857
1932
  }
1858
1933
 
1859
1934
  // src/commands/source/remove.ts
1860
- import { Command as Command57 } from "commander";
1935
+ import { Command as Command58 } from "commander";
1861
1936
  function createSourceRemoveCommand(client, printer = defaultPrinter) {
1862
- return new Command57("remove").alias("rm").description("Remove a registered source").argument("<name>", "Source name").action(async (name) => {
1937
+ return new Command58("remove").alias("rm").description("Remove a registered source").argument("<name>", "Source name").action(async (name) => {
1863
1938
  try {
1864
1939
  const result = await client.call("source.remove", { name });
1865
1940
  if (result.success) {
@@ -1875,19 +1950,19 @@ function createSourceRemoveCommand(client, printer = defaultPrinter) {
1875
1950
  }
1876
1951
 
1877
1952
  // src/commands/source/sync.ts
1878
- import chalk16 from "chalk";
1879
- import { Command as Command58 } from "commander";
1953
+ import chalk18 from "chalk";
1954
+ import { Command as Command59 } from "commander";
1880
1955
  function createSourceSyncCommand(client, printer = defaultPrinter) {
1881
- return new Command58("sync").description("Sync component source(s)").argument("[name]", "Source name (syncs all if omitted)").action(async (name) => {
1956
+ return new Command59("sync").description("Sync component source(s)").argument("[name]", "Source name (syncs all if omitted)").action(async (name) => {
1882
1957
  try {
1883
1958
  const result = await client.call("source.sync", { name });
1884
1959
  printer.success(`Synced: ${result.synced.join(", ")}`);
1885
1960
  const report = result.report;
1886
1961
  if (report) {
1887
1962
  const parts = [];
1888
- if (report.addedCount > 0) parts.push(chalk16.green(`+${report.addedCount} added`));
1889
- if (report.updatedCount > 0) parts.push(chalk16.yellow(`${report.updatedCount} updated`));
1890
- if (report.removedCount > 0) parts.push(chalk16.red(`-${report.removedCount} removed`));
1963
+ if (report.addedCount > 0) parts.push(chalk18.green(`+${report.addedCount} added`));
1964
+ if (report.updatedCount > 0) parts.push(chalk18.yellow(`${report.updatedCount} updated`));
1965
+ if (report.removedCount > 0) parts.push(chalk18.red(`-${report.removedCount} removed`));
1891
1966
  if (parts.length > 0) {
1892
1967
  printer.log(` ${parts.join(", ")}`);
1893
1968
  }
@@ -1904,7 +1979,7 @@ function createSourceSyncCommand(client, printer = defaultPrinter) {
1904
1979
 
1905
1980
  // src/commands/source/index.ts
1906
1981
  function createSourceCommand(client, printer) {
1907
- const cmd = new Command59("source").description("Manage component sources (GitHub repos, local dirs)");
1982
+ const cmd = new Command60("source").description("Manage component sources (GitHub repos, local dirs)");
1908
1983
  cmd.addCommand(createSourceListCommand(client, printer));
1909
1984
  cmd.addCommand(createSourceAddCommand(client, printer));
1910
1985
  cmd.addCommand(createSourceRemoveCommand(client, printer));
@@ -1913,12 +1988,12 @@ function createSourceCommand(client, printer) {
1913
1988
  }
1914
1989
 
1915
1990
  // src/commands/preset/index.ts
1916
- import { Command as Command63 } from "commander";
1991
+ import { Command as Command64 } from "commander";
1917
1992
 
1918
1993
  // src/commands/preset/list.ts
1919
- import { Command as Command60 } from "commander";
1994
+ import { Command as Command61 } from "commander";
1920
1995
  function createPresetListCommand(client, printer = defaultPrinter) {
1921
- 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) => {
1996
+ return new Command61("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) => {
1922
1997
  try {
1923
1998
  const presets = await client.call("preset.list", { packageName });
1924
1999
  if (opts.format === "json") {
@@ -1943,9 +2018,9 @@ function createPresetListCommand(client, printer = defaultPrinter) {
1943
2018
  }
1944
2019
 
1945
2020
  // src/commands/preset/show.ts
1946
- import { Command as Command61 } from "commander";
2021
+ import { Command as Command62 } from "commander";
1947
2022
  function createPresetShowCommand(client, printer = defaultPrinter) {
1948
- 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) => {
2023
+ return new Command62("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) => {
1949
2024
  try {
1950
2025
  const preset = await client.call("preset.show", { qualifiedName });
1951
2026
  if (opts.format === "json") {
@@ -1966,9 +2041,9 @@ function createPresetShowCommand(client, printer = defaultPrinter) {
1966
2041
  }
1967
2042
 
1968
2043
  // src/commands/preset/apply.ts
1969
- import { Command as Command62 } from "commander";
2044
+ import { Command as Command63 } from "commander";
1970
2045
  function createPresetApplyCommand(client, printer = defaultPrinter) {
1971
- 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) => {
2046
+ return new Command63("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) => {
1972
2047
  try {
1973
2048
  const result = await client.call("preset.apply", { qualifiedName, templateName });
1974
2049
  printer.success(`Preset "${qualifiedName}" applied to template "${result.name}".`);
@@ -1981,7 +2056,7 @@ function createPresetApplyCommand(client, printer = defaultPrinter) {
1981
2056
 
1982
2057
  // src/commands/preset/index.ts
1983
2058
  function createPresetCommand(client, printer) {
1984
- const cmd = new Command63("preset").description("Manage component presets (bundled compositions)");
2059
+ const cmd = new Command64("preset").description("Manage component presets (bundled compositions)");
1985
2060
  cmd.addCommand(createPresetListCommand(client, printer));
1986
2061
  cmd.addCommand(createPresetShowCommand(client, printer));
1987
2062
  cmd.addCommand(createPresetApplyCommand(client, printer));
@@ -1989,12 +2064,12 @@ function createPresetCommand(client, printer) {
1989
2064
  }
1990
2065
 
1991
2066
  // src/commands/schedule/index.ts
1992
- import { Command as Command65 } from "commander";
2067
+ import { Command as Command66 } from "commander";
1993
2068
 
1994
2069
  // src/commands/schedule/list.ts
1995
- import { Command as Command64 } from "commander";
2070
+ import { Command as Command65 } from "commander";
1996
2071
  function createScheduleListCommand(client, printer = defaultPrinter) {
1997
- 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) => {
2072
+ return new Command65("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) => {
1998
2073
  try {
1999
2074
  const result = await client.call("schedule.list", { name });
2000
2075
  if (opts.format === "json") {
@@ -2018,31 +2093,31 @@ function createScheduleListCommand(client, printer = defaultPrinter) {
2018
2093
 
2019
2094
  // src/commands/schedule/index.ts
2020
2095
  function createScheduleCommand(client, printer) {
2021
- const cmd = new Command65("schedule").description("Manage agent schedules (heartbeat, cron, hooks)");
2096
+ const cmd = new Command66("schedule").description("Manage agent schedules (heartbeat, cron, hooks)");
2022
2097
  cmd.addCommand(createScheduleListCommand(client, printer));
2023
2098
  return cmd;
2024
2099
  }
2025
2100
 
2026
2101
  // src/commands/daemon/index.ts
2027
- import { Command as Command69 } from "commander";
2102
+ import { Command as Command70 } from "commander";
2028
2103
 
2029
2104
  // src/commands/daemon/start.ts
2030
- import { Command as Command66 } from "commander";
2105
+ import { Command as Command67 } from "commander";
2031
2106
  import { join } from "path";
2032
- import { fork, spawn } from "child_process";
2033
- import chalk17 from "chalk";
2107
+ import { fork, spawn as spawn2 } from "child_process";
2108
+ import chalk19 from "chalk";
2034
2109
  import { onShutdownSignal, isWindows, isSingleExecutable } from "@actant/shared";
2035
2110
  var SEA_DAEMON_FLAG = "--__actant-daemon";
2036
2111
  function spawnDaemonChild() {
2037
2112
  if (isSingleExecutable()) {
2038
- return spawn(process.execPath, [SEA_DAEMON_FLAG], {
2113
+ return spawn2(process.execPath, [SEA_DAEMON_FLAG], {
2039
2114
  detached: true,
2040
2115
  stdio: ["ignore", "ignore", "pipe"],
2041
2116
  env: process.env
2042
2117
  });
2043
2118
  }
2044
2119
  const daemonScript = join(import.meta.dirname, "daemon-entry.js");
2045
- return isWindows() ? spawn(process.execPath, [daemonScript], {
2120
+ return isWindows() ? spawn2(process.execPath, [daemonScript], {
2046
2121
  detached: true,
2047
2122
  stdio: ["ignore", "ignore", "pipe"],
2048
2123
  env: process.env
@@ -2053,7 +2128,7 @@ function spawnDaemonChild() {
2053
2128
  });
2054
2129
  }
2055
2130
  function createDaemonStartCommand(printer = defaultPrinter) {
2056
- return new Command66("start").description("Start the Actant daemon").option("--foreground", "Run in foreground (don't daemonize)", false).action(async (opts) => {
2131
+ return new Command67("start").description("Start the Actant daemon").option("--foreground", "Run in foreground (don't daemonize)", false).action(async (opts) => {
2057
2132
  const client = new RpcClient(defaultSocketPath());
2058
2133
  const alive = await client.ping();
2059
2134
  if (alive) {
@@ -2069,7 +2144,7 @@ function createDaemonStartCommand(printer = defaultPrinter) {
2069
2144
  process.exit(0);
2070
2145
  });
2071
2146
  await daemon.start();
2072
- printer.log(`${chalk17.green("Daemon started (foreground).")} PID: ${process.pid}`);
2147
+ printer.log(`${chalk19.green("Daemon started (foreground).")} PID: ${process.pid}`);
2073
2148
  printer.dim("Press Ctrl+C to stop.");
2074
2149
  await new Promise(() => {
2075
2150
  });
@@ -2107,7 +2182,7 @@ function createDaemonStartCommand(printer = defaultPrinter) {
2107
2182
  if ("connected" in child && child.connected) child.disconnect();
2108
2183
  child.unref();
2109
2184
  if (healthy) {
2110
- printer.log(`${chalk17.green("Daemon started.")} PID: ${child.pid}`);
2185
+ printer.log(`${chalk19.green("Daemon started.")} PID: ${child.pid}`);
2111
2186
  } else {
2112
2187
  const stderr = Buffer.concat(stderrChunks).toString().trim();
2113
2188
  printer.error("Daemon process started but is not responding.");
@@ -2119,9 +2194,9 @@ function createDaemonStartCommand(printer = defaultPrinter) {
2119
2194
  }
2120
2195
 
2121
2196
  // src/commands/daemon/stop.ts
2122
- import { Command as Command67 } from "commander";
2197
+ import { Command as Command68 } from "commander";
2123
2198
  function createDaemonStopCommand(printer = defaultPrinter, client) {
2124
- return new Command67("stop").description("Stop the Actant daemon").action(async () => {
2199
+ return new Command68("stop").description("Stop the Actant daemon").action(async () => {
2125
2200
  const rpc = client ?? new RpcClient(defaultSocketPath());
2126
2201
  try {
2127
2202
  await rpc.call("daemon.shutdown", {});
@@ -2133,10 +2208,10 @@ function createDaemonStopCommand(printer = defaultPrinter, client) {
2133
2208
  }
2134
2209
 
2135
2210
  // src/commands/daemon/status.ts
2136
- import { Command as Command68 } from "commander";
2137
- import chalk18 from "chalk";
2211
+ import { Command as Command69 } from "commander";
2212
+ import chalk20 from "chalk";
2138
2213
  function createDaemonStatusCommand(printer = defaultPrinter) {
2139
- return new Command68("status").description("Check if the daemon is running").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
2214
+ return new Command69("status").description("Check if the daemon is running").option("-f, --format <format>", "Output format: table, json, quiet", "table").action(async (opts) => {
2140
2215
  const client = new RpcClient(defaultSocketPath());
2141
2216
  try {
2142
2217
  const result = await client.call("daemon.ping", {});
@@ -2156,7 +2231,7 @@ function createDaemonStatusCommand(printer = defaultPrinter) {
2156
2231
  } else if (opts.format === "quiet") {
2157
2232
  printer.log("stopped");
2158
2233
  } else {
2159
- printer.log(chalk18.red("Daemon is not running."));
2234
+ printer.log(chalk20.red("Daemon is not running."));
2160
2235
  printer.dim("Start with: actant daemon start");
2161
2236
  }
2162
2237
  process.exitCode = 1;
@@ -2166,7 +2241,7 @@ function createDaemonStatusCommand(printer = defaultPrinter) {
2166
2241
 
2167
2242
  // src/commands/daemon/index.ts
2168
2243
  function createDaemonCommand(printer) {
2169
- const cmd = new Command69("daemon").description("Manage the Actant daemon");
2244
+ const cmd = new Command70("daemon").description("Manage the Actant daemon");
2170
2245
  cmd.addCommand(createDaemonStartCommand(printer));
2171
2246
  cmd.addCommand(createDaemonStopCommand(printer));
2172
2247
  cmd.addCommand(createDaemonStatusCommand(printer));
@@ -2174,11 +2249,11 @@ function createDaemonCommand(printer) {
2174
2249
  }
2175
2250
 
2176
2251
  // src/commands/proxy.ts
2177
- import { Command as Command70 } from "commander";
2178
- import { spawn as spawn2 } from "child_process";
2252
+ import { Command as Command71 } from "commander";
2253
+ import { spawn as spawn3 } from "child_process";
2179
2254
  import { createInterface as createInterface3 } from "readline";
2180
2255
  function createProxyCommand(printer = defaultPrinter) {
2181
- 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) => {
2256
+ return new Command71("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) => {
2182
2257
  if (opts.lease) {
2183
2258
  await runSessionLease(name, printer);
2184
2259
  } else {
@@ -2243,7 +2318,7 @@ async function runDirectBridge(name, opts, printer) {
2243
2318
  const command = targetInstance.command;
2244
2319
  const args = targetInstance.args;
2245
2320
  const env = { ...process.env, ...targetInstance.env };
2246
- child = spawn2(command, args, {
2321
+ child = spawn3(command, args, {
2247
2322
  cwd: workspaceDir,
2248
2323
  stdio: ["pipe", "pipe", "pipe"],
2249
2324
  env
@@ -2496,14 +2571,14 @@ function writeAcpError(id, code, message) {
2496
2571
  }
2497
2572
 
2498
2573
  // src/commands/self-update.ts
2499
- import { Command as Command71 } from "commander";
2500
- import { spawn as spawn3 } from "child_process";
2574
+ import { Command as Command72 } from "commander";
2575
+ import { spawn as spawn4 } from "child_process";
2501
2576
  import { writeFileSync, mkdirSync, readFileSync, existsSync as existsSync2 } from "fs";
2502
2577
  import { join as join2 } from "path";
2503
2578
  import { homedir } from "os";
2504
- import chalk19 from "chalk";
2579
+ import chalk21 from "chalk";
2505
2580
  function createSelfUpdateCommand() {
2506
- 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) => {
2581
+ return new Command72("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) => {
2507
2582
  const actantHome = process.env.ACTANT_HOME || join2(homedir(), ".actant");
2508
2583
  let devSourcePath = opts.source;
2509
2584
  if (!devSourcePath) {
@@ -2516,7 +2591,7 @@ function createSelfUpdateCommand() {
2516
2591
  }
2517
2592
  if (!devSourcePath) {
2518
2593
  console.error(
2519
- chalk19.red(
2594
+ chalk21.red(
2520
2595
  "No source path specified. Use --source <path> or set devSourcePath in ~/.actant/config.json"
2521
2596
  )
2522
2597
  );
@@ -2551,37 +2626,37 @@ function createSelfUpdateCommand() {
2551
2626
  };
2552
2627
  mkdirSync(actantHome, { recursive: true });
2553
2628
  writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
2554
- console.log(chalk19.cyan("=== Actant Self-Update ==="));
2629
+ console.log(chalk21.cyan("=== Actant Self-Update ==="));
2555
2630
  console.log(`Update ID: ${updateId}`);
2556
2631
  console.log(`Source: ${devSourcePath}`);
2557
2632
  const scriptPath = join2(devSourcePath, "scripts", "self-update.js");
2558
2633
  const scriptArgs = ["--manifest", manifestPath];
2559
2634
  if (opts.dryRun) scriptArgs.push("--dry-run");
2560
2635
  if (opts.skipBuild) scriptArgs.push("--skip-build");
2561
- console.log(chalk19.gray(`Spawning: node ${scriptPath} ${scriptArgs.join(" ")}`));
2562
- const child = spawn3("node", [scriptPath, ...scriptArgs], {
2636
+ console.log(chalk21.gray(`Spawning: node ${scriptPath} ${scriptArgs.join(" ")}`));
2637
+ const child = spawn4("node", [scriptPath, ...scriptArgs], {
2563
2638
  detached: !opts.noAgent,
2564
2639
  stdio: opts.noAgent ? "inherit" : "ignore"
2565
2640
  });
2566
2641
  if (!opts.noAgent) {
2567
2642
  child.unref();
2568
- console.log(chalk19.green("Update script spawned in background. Check logs at:"));
2569
- console.log(chalk19.gray(` ${join2(actantHome, "logs", `update-${updateId}.log`)}`));
2643
+ console.log(chalk21.green("Update script spawned in background. Check logs at:"));
2644
+ console.log(chalk21.gray(` ${join2(actantHome, "logs", `update-${updateId}.log`)}`));
2570
2645
  } else {
2571
2646
  child.on("exit", (code) => {
2572
2647
  if (code === 0) {
2573
- console.log(chalk19.green("\nUpdate completed successfully!"));
2648
+ console.log(chalk21.green("\nUpdate completed successfully!"));
2574
2649
  } else if (code === 1) {
2575
- console.log(chalk19.yellow("\nUpdate failed, rolled back to previous version."));
2650
+ console.log(chalk21.yellow("\nUpdate failed, rolled back to previous version."));
2576
2651
  } else {
2577
- console.log(chalk19.red("\nSevere failure \u2014 manual intervention may be needed."));
2652
+ console.log(chalk21.red("\nSevere failure \u2014 manual intervention may be needed."));
2578
2653
  }
2579
2654
  });
2580
2655
  }
2581
2656
  });
2582
2657
  }
2583
2658
  function showVersionCheck(sourcePath, actantHome) {
2584
- console.log(chalk19.cyan("=== Version Check ==="));
2659
+ console.log(chalk21.cyan("=== Version Check ==="));
2585
2660
  try {
2586
2661
  const pkg = JSON.parse(readFileSync(join2(sourcePath, "package.json"), "utf-8"));
2587
2662
  console.log(`Source version: ${pkg.version || "unknown"}`);
@@ -2597,14 +2672,790 @@ function showVersionCheck(sourcePath, actantHome) {
2597
2672
  }
2598
2673
  }
2599
2674
 
2675
+ // src/commands/setup/setup.ts
2676
+ import { Command as Command73 } from "commander";
2677
+ import chalk29 from "chalk";
2678
+ import { getDefaultIpcPath } from "@actant/shared";
2679
+
2680
+ // src/commands/setup/steps/choose-home.ts
2681
+ import { join as join3 } from "path";
2682
+ import { homedir as homedir2 } from "os";
2683
+ import { mkdirSync as mkdirSync2, existsSync as existsSync3, writeFileSync as writeFileSync2 } from "fs";
2684
+ import { select, input } from "@inquirer/prompts";
2685
+ import chalk22 from "chalk";
2686
+ var DEFAULT_HOME = join3(homedir2(), ".actant");
2687
+ var SUBDIRS = [
2688
+ "configs/skills",
2689
+ "configs/prompts",
2690
+ "configs/mcp",
2691
+ "configs/workflows",
2692
+ "configs/plugins",
2693
+ "configs/templates",
2694
+ "instances",
2695
+ "sources/cache",
2696
+ "logs",
2697
+ "backups"
2698
+ ];
2699
+ async function chooseHome(printer) {
2700
+ printer.log(`
2701
+ ${chalk22.cyan("[ Step 1/7 ]")} ${chalk22.bold("\u9009\u62E9\u5DE5\u4F5C\u76EE\u5F55")}
2702
+ `);
2703
+ const choice = await select({
2704
+ message: "Actant \u5DE5\u4F5C\u76EE\u5F55 (ACTANT_HOME):",
2705
+ choices: [
2706
+ { name: `\u4F7F\u7528\u9ED8\u8BA4 ${DEFAULT_HOME}`, value: "default" },
2707
+ { name: "\u81EA\u5B9A\u4E49\u8DEF\u5F84...", value: "custom" }
2708
+ ]
2709
+ });
2710
+ let actantHome = DEFAULT_HOME;
2711
+ if (choice === "custom") {
2712
+ actantHome = await input({
2713
+ message: "\u8BF7\u8F93\u5165\u5DE5\u4F5C\u76EE\u5F55\u8DEF\u5F84:",
2714
+ validate: (val) => val.trim().length > 0 || "\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A"
2715
+ });
2716
+ actantHome = actantHome.trim();
2717
+ }
2718
+ ensureDirectoryStructure(actantHome);
2719
+ const configFile = join3(actantHome, "config.json");
2720
+ if (!existsSync3(configFile)) {
2721
+ writeFileSync2(
2722
+ configFile,
2723
+ JSON.stringify(
2724
+ {
2725
+ devSourcePath: "",
2726
+ update: {
2727
+ maxBackups: 3,
2728
+ preUpdateTestCommand: "pnpm test:changed",
2729
+ autoRestartAgents: true
2730
+ }
2731
+ },
2732
+ null,
2733
+ 2
2734
+ ) + "\n"
2735
+ );
2736
+ }
2737
+ printer.success(`\u2713 \u5DE5\u4F5C\u76EE\u5F55: ${actantHome}`);
2738
+ if (actantHome !== DEFAULT_HOME) {
2739
+ printer.warn(
2740
+ ` \u8BF7\u5C06\u4EE5\u4E0B\u5185\u5BB9\u6DFB\u52A0\u5230\u4F60\u7684 shell \u914D\u7F6E\u6587\u4EF6 (~/.bashrc, ~/.zshrc, \u6216 $PROFILE):
2741
+ ${chalk22.cyan(`export ACTANT_HOME="${actantHome}"`)}`
2742
+ );
2743
+ }
2744
+ return actantHome;
2745
+ }
2746
+ function ensureDirectoryStructure(base) {
2747
+ for (const dir of SUBDIRS) {
2748
+ mkdirSync2(join3(base, dir), { recursive: true });
2749
+ }
2750
+ }
2751
+
2752
+ // src/commands/setup/steps/configure-provider.ts
2753
+ import { join as join4 } from "path";
2754
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
2755
+ import { select as select2, input as input2, password, confirm } from "@inquirer/prompts";
2756
+ import chalk23 from "chalk";
2757
+ var PROVIDER_DEFAULTS = {
2758
+ anthropic: { protocol: "http", baseUrl: "https://api.anthropic.com", apiKeyEnv: "ANTHROPIC_API_KEY" },
2759
+ openai: { protocol: "http", baseUrl: "https://api.openai.com/v1", apiKeyEnv: "OPENAI_API_KEY" },
2760
+ "openai-compatible": { protocol: "http", baseUrl: "http://localhost:11434/v1", apiKeyEnv: "LLM_API_KEY" },
2761
+ custom: { protocol: "http", baseUrl: "http://localhost:8080", apiKeyEnv: "LLM_API_KEY" }
2762
+ };
2763
+ async function configureProvider(printer, actantHome) {
2764
+ printer.log(`
2765
+ ${chalk23.cyan("[ Step 2/7 ]")} ${chalk23.bold("\u914D\u7F6E Model Provider")}
2766
+ `);
2767
+ const providerType = await select2({
2768
+ message: "\u9009\u62E9 Model Provider:",
2769
+ default: "anthropic",
2770
+ choices: [
2771
+ { name: "Anthropic (Claude)", value: "anthropic" },
2772
+ { name: "OpenAI", value: "openai" },
2773
+ { name: "OpenAI-Compatible (vLLM / Ollama / LM Studio \u7B49)", value: "openai-compatible" },
2774
+ { name: "Custom", value: "custom" }
2775
+ ]
2776
+ });
2777
+ const fallback = {
2778
+ protocol: "http",
2779
+ baseUrl: "",
2780
+ apiKeyEnv: "LLM_API_KEY"
2781
+ };
2782
+ const defaults = PROVIDER_DEFAULTS[providerType] ?? fallback;
2783
+ const protocol = await select2({
2784
+ message: "\u534F\u8BAE\u7C7B\u578B:",
2785
+ choices: [
2786
+ { name: "HTTP / REST", value: "http" },
2787
+ { name: "WebSocket", value: "websocket" },
2788
+ { name: "gRPC", value: "grpc" }
2789
+ ],
2790
+ default: defaults.protocol
2791
+ });
2792
+ const baseUrl = await input2({
2793
+ message: "Base URL:",
2794
+ default: defaults.baseUrl,
2795
+ validate: (val) => {
2796
+ try {
2797
+ new URL(val);
2798
+ return true;
2799
+ } catch {
2800
+ return "\u8BF7\u8F93\u5165\u6709\u6548\u7684 URL";
2801
+ }
2802
+ }
2803
+ });
2804
+ const apiKeyEnvName = await input2({
2805
+ message: "API Key \u73AF\u5883\u53D8\u91CF\u540D:",
2806
+ default: defaults.apiKeyEnv
2807
+ });
2808
+ const apiKey = await password({
2809
+ message: `${apiKeyEnvName} \u7684\u503C (API Key):`,
2810
+ mask: "*"
2811
+ });
2812
+ if (apiKey) {
2813
+ const shouldValidate = await confirm({
2814
+ message: "\u9A8C\u8BC1\u8FDE\u63A5?",
2815
+ default: true
2816
+ });
2817
+ if (shouldValidate) {
2818
+ printer.log(chalk23.dim(" \u6B63\u5728\u9A8C\u8BC1\u8FDE\u63A5..."));
2819
+ const ok = await validateConnection(providerType, protocol, baseUrl, apiKey);
2820
+ if (ok) {
2821
+ printer.success(" \u2713 \u8FDE\u63A5\u9A8C\u8BC1\u6210\u529F");
2822
+ } else {
2823
+ printer.warn(" \u26A0 \u8FDE\u63A5\u9A8C\u8BC1\u5931\u8D25\uFF0C\u914D\u7F6E\u5DF2\u4FDD\u5B58\u4F46\u53EF\u80FD\u9700\u8981\u68C0\u67E5");
2824
+ }
2825
+ }
2826
+ printer.warn(
2827
+ ` \u8BF7\u786E\u4FDD\u73AF\u5883\u53D8\u91CF ${chalk23.cyan(apiKeyEnvName)} \u5DF2\u8BBE\u7F6E:
2828
+ ${chalk23.dim(`export ${apiKeyEnvName}="${apiKey.slice(0, 8)}..."`)}`
2829
+ );
2830
+ }
2831
+ const providerConfig = {
2832
+ type: providerType,
2833
+ protocol,
2834
+ baseUrl,
2835
+ apiKeyEnv: apiKeyEnvName
2836
+ };
2837
+ saveProviderConfig(actantHome, providerConfig);
2838
+ printer.success(`\u2713 Model Provider \u5DF2\u914D\u7F6E: ${providerType} (${protocol}) \u2192 ${baseUrl}`);
2839
+ }
2840
+ function saveProviderConfig(actantHome, provider) {
2841
+ const configFile = join4(actantHome, "config.json");
2842
+ let config = {};
2843
+ try {
2844
+ config = JSON.parse(readFileSync2(configFile, "utf-8"));
2845
+ } catch {
2846
+ }
2847
+ config.provider = provider;
2848
+ writeFileSync3(configFile, JSON.stringify(config, null, 2) + "\n");
2849
+ }
2850
+ async function validateConnection(type, _protocol, baseUrl, apiKey) {
2851
+ try {
2852
+ if (type === "anthropic") {
2853
+ const res2 = await fetch(`${baseUrl}/v1/messages`, {
2854
+ method: "POST",
2855
+ headers: {
2856
+ "x-api-key": apiKey,
2857
+ "anthropic-version": "2023-06-01",
2858
+ "content-type": "application/json"
2859
+ },
2860
+ body: JSON.stringify({
2861
+ model: "claude-sonnet-4-20250514",
2862
+ max_tokens: 1,
2863
+ messages: [{ role: "user", content: "hi" }]
2864
+ }),
2865
+ signal: AbortSignal.timeout(15e3)
2866
+ });
2867
+ return res2.status === 200 || res2.status === 400;
2868
+ }
2869
+ if (type === "openai" || type === "openai-compatible") {
2870
+ const res2 = await fetch(`${baseUrl}/models`, {
2871
+ headers: { Authorization: `Bearer ${apiKey}` },
2872
+ signal: AbortSignal.timeout(1e4)
2873
+ });
2874
+ return res2.ok;
2875
+ }
2876
+ const res = await fetch(baseUrl, {
2877
+ headers: { Authorization: `Bearer ${apiKey}` },
2878
+ signal: AbortSignal.timeout(1e4)
2879
+ });
2880
+ return res.ok;
2881
+ } catch {
2882
+ return false;
2883
+ }
2884
+ }
2885
+
2886
+ // src/commands/setup/steps/configure-source.ts
2887
+ import { confirm as confirm2, input as input3, select as select3 } from "@inquirer/prompts";
2888
+ import chalk24 from "chalk";
2889
+ var DEFAULT_SOURCE_NAME = "actant-hub";
2890
+ var DEFAULT_SOURCE_URL = "https://github.com/blackplume233/actant-hub.git";
2891
+ async function configureSource(printer, client) {
2892
+ printer.log(`
2893
+ ${chalk24.cyan("[ Step 3/7 ]")} ${chalk24.bold("\u914D\u7F6E\u7EC4\u4EF6\u6E90 (Source)")}
2894
+ `);
2895
+ const addDefault = await confirm2({
2896
+ message: `\u6DFB\u52A0\u5B98\u65B9\u7EC4\u4EF6\u6E90 ${DEFAULT_SOURCE_NAME}?`,
2897
+ default: true
2898
+ });
2899
+ if (addDefault) {
2900
+ try {
2901
+ printer.log(chalk24.dim(` \u6B63\u5728\u6CE8\u518C ${DEFAULT_SOURCE_NAME}...`));
2902
+ const result = await client.call("source.add", {
2903
+ name: DEFAULT_SOURCE_NAME,
2904
+ config: { type: "github", url: DEFAULT_SOURCE_URL, branch: "main" }
2905
+ });
2906
+ const c = result.components;
2907
+ printer.success(
2908
+ ` \u2713 ${DEFAULT_SOURCE_NAME} \u5DF2\u6DFB\u52A0: ${c.skills} skills, ${c.prompts} prompts, ${c.mcp} mcp, ${c.workflows} workflows, ${c.presets} presets`
2909
+ );
2910
+ } catch (err) {
2911
+ const message = err instanceof Error ? err.message : String(err);
2912
+ if (message.includes("already exists") || message.includes("already registered")) {
2913
+ printer.dim(` ${DEFAULT_SOURCE_NAME} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7`);
2914
+ } else {
2915
+ printer.warn(` \u26A0 \u6DFB\u52A0 ${DEFAULT_SOURCE_NAME} \u5931\u8D25: ${message}`);
2916
+ printer.dim(" \u4F60\u53EF\u4EE5\u7A0D\u540E\u624B\u52A8\u8FD0\u884C: actant source add --name actant-hub <url>");
2917
+ }
2918
+ }
2919
+ }
2920
+ let addMore = await confirm2({
2921
+ message: "\u6DFB\u52A0\u5176\u4ED6 Source?",
2922
+ default: false
2923
+ });
2924
+ while (addMore) {
2925
+ const sourceType = await select3({
2926
+ message: "Source \u7C7B\u578B:",
2927
+ choices: [
2928
+ { name: "GitHub \u4ED3\u5E93", value: "github" },
2929
+ { name: "\u672C\u5730\u76EE\u5F55", value: "local" }
2930
+ ]
2931
+ });
2932
+ const name = await input3({
2933
+ message: "Source \u540D\u79F0 (\u547D\u540D\u7A7A\u95F4\u524D\u7F00):",
2934
+ validate: (val) => val.trim().length > 0 || "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"
2935
+ });
2936
+ if (sourceType === "github") {
2937
+ const url = await input3({
2938
+ message: "GitHub \u4ED3\u5E93 URL:",
2939
+ validate: (val) => val.trim().length > 0 || "URL \u4E0D\u80FD\u4E3A\u7A7A"
2940
+ });
2941
+ const branch = await input3({
2942
+ message: "\u5206\u652F:",
2943
+ default: "main"
2944
+ });
2945
+ try {
2946
+ const result = await client.call("source.add", {
2947
+ name: name.trim(),
2948
+ config: { type: "github", url: url.trim(), branch }
2949
+ });
2950
+ const c = result.components;
2951
+ printer.success(
2952
+ ` \u2713 ${name.trim()} \u5DF2\u6DFB\u52A0: ${c.skills} skills, ${c.prompts} prompts`
2953
+ );
2954
+ } catch (err) {
2955
+ printer.warn(` \u26A0 \u6DFB\u52A0\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
2956
+ }
2957
+ } else {
2958
+ const path = await input3({
2959
+ message: "\u672C\u5730\u76EE\u5F55\u8DEF\u5F84:",
2960
+ validate: (val) => val.trim().length > 0 || "\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A"
2961
+ });
2962
+ try {
2963
+ const result = await client.call("source.add", {
2964
+ name: name.trim(),
2965
+ config: { type: "local", path: path.trim() }
2966
+ });
2967
+ const c = result.components;
2968
+ printer.success(
2969
+ ` \u2713 ${name.trim()} \u5DF2\u6DFB\u52A0: ${c.skills} skills, ${c.prompts} prompts`
2970
+ );
2971
+ } catch (err) {
2972
+ printer.warn(` \u26A0 \u6DFB\u52A0\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
2973
+ }
2974
+ }
2975
+ addMore = await confirm2({
2976
+ message: "\u7EE7\u7EED\u6DFB\u52A0\u5176\u4ED6 Source?",
2977
+ default: false
2978
+ });
2979
+ }
2980
+ printer.success("\u2713 \u7EC4\u4EF6\u6E90\u914D\u7F6E\u5B8C\u6210");
2981
+ }
2982
+
2983
+ // src/commands/setup/steps/materialize-agent.ts
2984
+ import { checkbox, input as input4 } from "@inquirer/prompts";
2985
+ import chalk25 from "chalk";
2986
+ async function materializeAgent(printer, client) {
2987
+ printer.log(`
2988
+ ${chalk25.cyan("[ Step 4/7 ]")} ${chalk25.bold("\u9009\u62E9\u5E76\u521B\u5EFA Agent")}
2989
+ `);
2990
+ let templates;
2991
+ try {
2992
+ templates = await client.call("template.list", {});
2993
+ } catch (err) {
2994
+ printer.warn(` \u26A0 \u65E0\u6CD5\u83B7\u53D6\u6A21\u677F\u5217\u8868: ${err instanceof Error ? err.message : String(err)}`);
2995
+ printer.dim(" \u4F60\u53EF\u4EE5\u7A0D\u540E\u4F7F\u7528 actant agent create <name> -t <template> \u521B\u5EFA Agent");
2996
+ return [];
2997
+ }
2998
+ if (templates.length === 0) {
2999
+ printer.dim(" \u6682\u65E0\u53EF\u7528\u6A21\u677F\u3002\u8BF7\u5148\u901A\u8FC7 actant source sync \u540C\u6B65\u7EC4\u4EF6\uFF0C\u6216\u4F7F\u7528 actant template load \u52A0\u8F7D\u6A21\u677F\u3002");
3000
+ return [];
3001
+ }
3002
+ const selected = await checkbox({
3003
+ message: "\u9009\u62E9\u8981\u521B\u5EFA\u7684 Agent \u6A21\u677F (\u7A7A\u683C\u9009\u62E9, \u56DE\u8F66\u786E\u8BA4):",
3004
+ choices: templates.map((t, i) => ({
3005
+ name: `${t.name} (v${t.version})${t.description ? ` \u2014 ${t.description}` : ""}`,
3006
+ value: t.name,
3007
+ checked: i === 0
3008
+ }))
3009
+ });
3010
+ if (selected.length === 0) {
3011
+ printer.dim(" \u672A\u9009\u62E9\u4EFB\u4F55\u6A21\u677F\uFF0C\u8DF3\u8FC7 Agent \u521B\u5EFA");
3012
+ return [];
3013
+ }
3014
+ const createdAgents = [];
3015
+ for (const templateName of selected) {
3016
+ const instanceName = await input4({
3017
+ message: `Agent \u5B9E\u4F8B\u540D\u79F0 (\u6A21\u677F: ${templateName}):`,
3018
+ default: templateName,
3019
+ validate: (val) => {
3020
+ if (val.trim().length === 0) return "\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A";
3021
+ if (!/^[a-zA-Z0-9_-]+$/.test(val.trim())) return "\u4EC5\u5141\u8BB8\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u548C\u8FDE\u5B57\u7B26";
3022
+ return true;
3023
+ }
3024
+ });
3025
+ try {
3026
+ printer.log(chalk25.dim(` \u6B63\u5728\u521B\u5EFA ${instanceName.trim()}...`));
3027
+ await client.call("agent.create", {
3028
+ name: instanceName.trim(),
3029
+ template: templateName
3030
+ });
3031
+ printer.success(` \u2713 Agent "${instanceName.trim()}" \u5DF2\u521B\u5EFA (\u6A21\u677F: ${templateName})`);
3032
+ createdAgents.push(instanceName.trim());
3033
+ } catch (err) {
3034
+ printer.warn(` \u26A0 \u521B\u5EFA "${instanceName.trim()}" \u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
3035
+ }
3036
+ }
3037
+ if (createdAgents.length > 0) {
3038
+ printer.success(`\u2713 \u5DF2\u521B\u5EFA ${createdAgents.length} \u4E2A Agent`);
3039
+ }
3040
+ return createdAgents;
3041
+ }
3042
+
3043
+ // src/commands/setup/steps/configure-autostart.ts
3044
+ import { execSync } from "child_process";
3045
+ import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "fs";
3046
+ import { join as join5 } from "path";
3047
+ import { homedir as homedir3 } from "os";
3048
+ import { confirm as confirm3 } from "@inquirer/prompts";
3049
+ import chalk26 from "chalk";
3050
+ import { isWindows as isWindows2 } from "@actant/shared";
3051
+ async function configureAutostart(printer) {
3052
+ printer.log(`
3053
+ ${chalk26.cyan("[ Step 5/7 ]")} ${chalk26.bold("\u914D\u7F6E\u81EA\u52A8\u542F\u52A8")}
3054
+ `);
3055
+ const platform = process.platform;
3056
+ const platformName = platform === "win32" ? "Windows" : platform === "darwin" ? "macOS" : "Linux";
3057
+ printer.log(` \u68C0\u6D4B\u5230\u5E73\u53F0: ${chalk26.bold(platformName)}`);
3058
+ const enable = await confirm3({
3059
+ message: "\u914D\u7F6E Actant Daemon \u5F00\u673A\u81EA\u542F?",
3060
+ default: true
3061
+ });
3062
+ if (!enable) {
3063
+ printer.dim(" \u8DF3\u8FC7\u81EA\u52A8\u542F\u52A8\u914D\u7F6E");
3064
+ return;
3065
+ }
3066
+ try {
3067
+ if (isWindows2()) {
3068
+ configureWindows(printer);
3069
+ } else if (platform === "darwin") {
3070
+ configureMacOS(printer);
3071
+ } else {
3072
+ configureLinux(printer);
3073
+ }
3074
+ printer.success("\u2713 \u81EA\u52A8\u542F\u52A8\u5DF2\u914D\u7F6E");
3075
+ } catch (err) {
3076
+ printer.warn(` \u26A0 \u81EA\u52A8\u542F\u52A8\u914D\u7F6E\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
3077
+ printer.dim(" \u4F60\u53EF\u4EE5\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\u81EA\u52A8\u542F\u52A8");
3078
+ }
3079
+ }
3080
+ function configureWindows(printer) {
3081
+ printer.log(chalk26.dim(" \u6B63\u5728\u6CE8\u518C Windows Task Scheduler \u4EFB\u52A1..."));
3082
+ const actantPath = findActantExecutable();
3083
+ const taskXml = `<?xml version="1.0" encoding="UTF-16"?>
3084
+ <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
3085
+ <Triggers>
3086
+ <LogonTrigger>
3087
+ <Enabled>true</Enabled>
3088
+ </LogonTrigger>
3089
+ </Triggers>
3090
+ <Principals>
3091
+ <Principal>
3092
+ <LogonType>InteractiveToken</LogonType>
3093
+ <RunLevel>LeastPrivilege</RunLevel>
3094
+ </Principal>
3095
+ </Principals>
3096
+ <Settings>
3097
+ <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
3098
+ <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
3099
+ <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
3100
+ <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
3101
+ </Settings>
3102
+ <Actions>
3103
+ <Exec>
3104
+ <Command>${actantPath}</Command>
3105
+ <Arguments>daemon start</Arguments>
3106
+ </Exec>
3107
+ </Actions>
3108
+ </Task>`;
3109
+ const tempXmlPath = join5(process.env["TEMP"] || homedir3(), "actant-task.xml");
3110
+ writeFileSync4(tempXmlPath, taskXml, "utf-16le");
3111
+ execSync(`schtasks /Create /TN "ActantDaemon" /XML "${tempXmlPath}" /F`, { stdio: "pipe" });
3112
+ printer.dim(" \u5DF2\u6CE8\u518C\u4EFB\u52A1: ActantDaemon (\u767B\u5F55\u65F6\u81EA\u52A8\u542F\u52A8)");
3113
+ }
3114
+ function configureMacOS(printer) {
3115
+ printer.log(chalk26.dim(" \u6B63\u5728\u751F\u6210 launchd plist..."));
3116
+ const actantPath = findActantExecutable();
3117
+ const plistDir = join5(homedir3(), "Library", "LaunchAgents");
3118
+ mkdirSync3(plistDir, { recursive: true });
3119
+ const plistPath = join5(plistDir, "com.actant.daemon.plist");
3120
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
3121
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3122
+ <plist version="1.0">
3123
+ <dict>
3124
+ <key>Label</key>
3125
+ <string>com.actant.daemon</string>
3126
+ <key>ProgramArguments</key>
3127
+ <array>
3128
+ <string>${actantPath}</string>
3129
+ <string>daemon</string>
3130
+ <string>start</string>
3131
+ <string>--foreground</string>
3132
+ </array>
3133
+ <key>RunAtLoad</key>
3134
+ <true/>
3135
+ <key>KeepAlive</key>
3136
+ <true/>
3137
+ <key>StandardOutPath</key>
3138
+ <string>${join5(homedir3(), ".actant", "logs", "daemon-stdout.log")}</string>
3139
+ <key>StandardErrorPath</key>
3140
+ <string>${join5(homedir3(), ".actant", "logs", "daemon-stderr.log")}</string>
3141
+ </dict>
3142
+ </plist>`;
3143
+ writeFileSync4(plistPath, plist);
3144
+ execSync(`launchctl load "${plistPath}"`, { stdio: "pipe" });
3145
+ printer.dim(` \u5DF2\u52A0\u8F7D: ${plistPath}`);
3146
+ }
3147
+ function configureLinux(printer) {
3148
+ printer.log(chalk26.dim(" \u6B63\u5728\u751F\u6210 systemd user service..."));
3149
+ const actantPath = findActantExecutable();
3150
+ const serviceDir = join5(homedir3(), ".config", "systemd", "user");
3151
+ mkdirSync3(serviceDir, { recursive: true });
3152
+ const servicePath = join5(serviceDir, "actant-daemon.service");
3153
+ const unit = `[Unit]
3154
+ Description=Actant Daemon \u2014 AI Agent Platform
3155
+ After=network.target
3156
+
3157
+ [Service]
3158
+ Type=simple
3159
+ ExecStart=${actantPath} daemon start --foreground
3160
+ Restart=on-failure
3161
+ RestartSec=5
3162
+ Environment=NODE_ENV=production
3163
+
3164
+ [Install]
3165
+ WantedBy=default.target
3166
+ `;
3167
+ writeFileSync4(servicePath, unit);
3168
+ execSync("systemctl --user daemon-reload", { stdio: "pipe" });
3169
+ execSync("systemctl --user enable actant-daemon.service", { stdio: "pipe" });
3170
+ printer.dim(` \u5DF2\u542F\u7528: actant-daemon.service`);
3171
+ }
3172
+ function findActantExecutable() {
3173
+ try {
3174
+ const result = execSync(isWindows2() ? "where.exe actant" : "which actant", {
3175
+ encoding: "utf-8",
3176
+ stdio: ["pipe", "pipe", "pipe"]
3177
+ });
3178
+ const first = result.trim().split("\n")[0];
3179
+ return first ? first.trim() : "actant";
3180
+ } catch {
3181
+ return "actant";
3182
+ }
3183
+ }
3184
+
3185
+ // src/commands/setup/steps/hello-world.ts
3186
+ import chalk27 from "chalk";
3187
+ async function helloWorld(printer, client, createdAgents) {
3188
+ printer.log(`
3189
+ ${chalk27.cyan("[ Step 6/7 ]")} ${chalk27.bold("Hello World \u9A8C\u8BC1")}
3190
+ `);
3191
+ const alive = await client.ping();
3192
+ if (!alive) {
3193
+ printer.warn(" \u26A0 Daemon \u672A\u8FD0\u884C\uFF0C\u8DF3\u8FC7\u9A8C\u8BC1");
3194
+ printer.dim(' \u542F\u52A8\u540E\u53EF\u624B\u52A8\u9A8C\u8BC1: actant agent run <name> --prompt "Hello, World!"');
3195
+ return;
3196
+ }
3197
+ printer.success(" \u2713 Daemon \u8FDE\u63A5\u6B63\u5E38");
3198
+ if (createdAgents.length === 0) {
3199
+ printer.dim(" \u65E0\u5DF2\u521B\u5EFA\u7684 Agent\uFF0C\u8DF3\u8FC7\u7AEF\u5230\u7AEF\u9A8C\u8BC1");
3200
+ printer.dim(' \u521B\u5EFA Agent \u540E\u53EF\u8FD0\u884C: actant agent run <name> --prompt "Hello, World!"');
3201
+ return;
3202
+ }
3203
+ const testAgent = createdAgents[0];
3204
+ if (!testAgent) {
3205
+ printer.dim(" \u65E0\u53EF\u7528 Agent\uFF0C\u8DF3\u8FC7\u7AEF\u5230\u7AEF\u9A8C\u8BC1");
3206
+ return;
3207
+ }
3208
+ printer.log(chalk27.dim(` \u6B63\u5728\u4F7F\u7528 Agent "${testAgent}" \u8FDB\u884C\u9A8C\u8BC1...`));
3209
+ try {
3210
+ await client.call("agent.start", { name: testAgent });
3211
+ printer.success(` \u2713 Agent "${testAgent}" \u5DF2\u542F\u52A8`);
3212
+ await waitForAgentReady(client, testAgent, 15e3);
3213
+ printer.log(chalk27.dim(` \u53D1\u9001\u6D4B\u8BD5\u6D88\u606F: "Hello, World!"`));
3214
+ const runResult = await client.call("agent.run", {
3215
+ name: testAgent,
3216
+ prompt: "Please respond with exactly: Hello from Actant! (keep it short)"
3217
+ });
3218
+ if (runResult) {
3219
+ printer.success(" \u2713 \u6536\u5230 Agent \u56DE\u590D \u2014 \u7AEF\u5230\u7AEF\u9A8C\u8BC1\u901A\u8FC7!");
3220
+ } else {
3221
+ printer.warn(" \u26A0 Agent \u672A\u8FD4\u56DE\u7ED3\u679C\uFF0C\u4F46\u542F\u52A8\u6B63\u5E38");
3222
+ }
3223
+ } catch (err) {
3224
+ const message = err instanceof Error ? err.message : String(err);
3225
+ if (message.includes("not found") || message.includes("NOT_FOUND")) {
3226
+ printer.warn(` \u26A0 Agent "${testAgent}" \u672A\u627E\u5230\uFF0C\u8DF3\u8FC7\u9A8C\u8BC1`);
3227
+ } else if (message.includes("Cannot connect")) {
3228
+ printer.warn(" \u26A0 \u65E0\u6CD5\u8FDE\u63A5\u540E\u7AEF (backend)\uFF0C\u8BF7\u786E\u8BA4\u540E\u7AEF\u5DF2\u5B89\u88C5");
3229
+ printer.dim(" \u63D0\u793A: claude-code \u540E\u7AEF\u9700\u8981\u5B89\u88C5 claude-agent-acp");
3230
+ } else {
3231
+ printer.warn(` \u26A0 \u9A8C\u8BC1\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u9519\u8BEF: ${message}`);
3232
+ }
3233
+ printer.dim(' \u4F60\u53EF\u4EE5\u7A0D\u540E\u624B\u52A8\u9A8C\u8BC1: actant agent run <name> --prompt "Hello!"');
3234
+ }
3235
+ }
3236
+ async function waitForAgentReady(client, name, timeoutMs) {
3237
+ const start = Date.now();
3238
+ while (Date.now() - start < timeoutMs) {
3239
+ try {
3240
+ const status = await client.call("agent.status", { name });
3241
+ if (status.status === "running") return;
3242
+ } catch {
3243
+ }
3244
+ await new Promise((r) => setTimeout(r, 1e3));
3245
+ }
3246
+ }
3247
+
3248
+ // src/commands/setup/steps/configure-update.ts
3249
+ import { join as join6 } from "path";
3250
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync5, existsSync as existsSync4 } from "fs";
3251
+ import { confirm as confirm4, input as input5 } from "@inquirer/prompts";
3252
+ import chalk28 from "chalk";
3253
+ function detectDevSourcePath() {
3254
+ const candidates = [
3255
+ process.cwd(),
3256
+ join6(process.cwd(), "..")
3257
+ ];
3258
+ for (const dir of candidates) {
3259
+ if (existsSync4(join6(dir, "packages", "cli", "package.json"))) {
3260
+ return dir;
3261
+ }
3262
+ }
3263
+ return process.cwd();
3264
+ }
3265
+ async function configureUpdate(printer, actantHome) {
3266
+ printer.log(`
3267
+ ${chalk28.cyan("[ Step 7/7 ]")} ${chalk28.bold("\u66F4\u65B0\u9009\u9879")}
3268
+ `);
3269
+ const wantConfigure = await confirm4({
3270
+ message: "\u914D\u7F6E\u81EA\u52A8\u66F4\u65B0\u6E90? (\u7528\u4E8E\u4ECE\u672C\u5730\u6E90\u7801\u66F4\u65B0 Actant)",
3271
+ default: false
3272
+ });
3273
+ if (!wantConfigure) {
3274
+ printer.dim(" \u8DF3\u8FC7\u66F4\u65B0\u914D\u7F6E");
3275
+ printUpdateHelp(printer);
3276
+ return;
3277
+ }
3278
+ const defaultPath = detectDevSourcePath();
3279
+ const devSourcePath = await input5({
3280
+ message: "\u5F00\u53D1\u6E90\u76EE\u5F55\u8DEF\u5F84 (AgentCraft \u9879\u76EE\u6839\u76EE\u5F55):",
3281
+ default: defaultPath,
3282
+ validate: (val) => val.trim().length > 0 || "\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A"
3283
+ });
3284
+ const configFile = join6(actantHome, "config.json");
3285
+ let config = {};
3286
+ try {
3287
+ config = JSON.parse(readFileSync3(configFile, "utf-8"));
3288
+ } catch {
3289
+ }
3290
+ config.devSourcePath = devSourcePath.trim();
3291
+ writeFileSync5(configFile, JSON.stringify(config, null, 2) + "\n");
3292
+ printer.success(`\u2713 \u66F4\u65B0\u6E90\u5DF2\u914D\u7F6E: ${devSourcePath.trim()}`);
3293
+ printUpdateHelp(printer);
3294
+ }
3295
+ function printUpdateHelp(printer) {
3296
+ printer.log("");
3297
+ printer.dim(" \u66F4\u65B0\u547D\u4EE4:");
3298
+ printer.dim(` ${chalk28.cyan("actant self-update")} \u4ECE\u6E90\u7801\u6784\u5EFA\u5E76\u66F4\u65B0`);
3299
+ printer.dim(` ${chalk28.cyan("actant self-update --check")} \u68C0\u67E5\u7248\u672C\u5DEE\u5F02`);
3300
+ printer.dim(` ${chalk28.cyan("npm install -g @actant/cli")} \u4ECE npm \u66F4\u65B0`);
3301
+ }
3302
+
3303
+ // src/commands/setup/setup.ts
3304
+ function createSetupCommand(printer = defaultPrinter) {
3305
+ return new Command73("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) => {
3306
+ try {
3307
+ printBanner(printer);
3308
+ let actantHome;
3309
+ if (opts.skipHome) {
3310
+ const { homedir: homedir4 } = await import("os");
3311
+ const { join: join8 } = await import("path");
3312
+ const { existsSync: existsSync5, writeFileSync: writeFileSync6 } = await import("fs");
3313
+ actantHome = process.env["ACTANT_HOME"] || join8(homedir4(), ".actant");
3314
+ ensureDirectoryStructure(actantHome);
3315
+ const configFile = join8(actantHome, "config.json");
3316
+ if (!existsSync5(configFile)) {
3317
+ writeFileSync6(configFile, JSON.stringify({
3318
+ devSourcePath: "",
3319
+ update: { maxBackups: 3, preUpdateTestCommand: "pnpm test:changed", autoRestartAgents: true }
3320
+ }, null, 2) + "\n");
3321
+ }
3322
+ printer.dim(` \u4F7F\u7528\u9ED8\u8BA4\u5DE5\u4F5C\u76EE\u5F55: ${actantHome}`);
3323
+ } else {
3324
+ actantHome = await chooseHome(printer);
3325
+ }
3326
+ if (!opts.skipProvider) {
3327
+ await configureProvider(printer, actantHome);
3328
+ }
3329
+ const daemonNeeded = !opts.skipSource || !opts.skipAgent || !opts.skipHello;
3330
+ let client;
3331
+ let daemonStartedBySetup = false;
3332
+ if (daemonNeeded) {
3333
+ const socketPath = process.env["ACTANT_SOCKET"] ?? getDefaultIpcPath(actantHome);
3334
+ client = new RpcClient(socketPath);
3335
+ const alive = await client.ping();
3336
+ if (!alive) {
3337
+ printer.log(chalk29.dim("\n \u6B63\u5728\u542F\u52A8 Daemon..."));
3338
+ daemonStartedBySetup = await tryStartDaemon(printer, socketPath);
3339
+ if (!daemonStartedBySetup) {
3340
+ printer.warn(" \u26A0 \u65E0\u6CD5\u81EA\u52A8\u542F\u52A8 Daemon\uFF0C\u8DF3\u8FC7\u9700\u8981 Daemon \u7684\u6B65\u9AA4");
3341
+ printer.dim(" \u8BF7\u624B\u52A8\u8FD0\u884C: actant daemon start");
3342
+ client = void 0;
3343
+ }
3344
+ } else {
3345
+ printer.dim("\n Daemon \u5DF2\u5728\u8FD0\u884C\u4E2D");
3346
+ }
3347
+ }
3348
+ if (!opts.skipSource && client) {
3349
+ await configureSource(printer, client);
3350
+ }
3351
+ let createdAgents = [];
3352
+ if (!opts.skipAgent && client) {
3353
+ createdAgents = await materializeAgent(printer, client);
3354
+ }
3355
+ if (!opts.skipAutostart) {
3356
+ await configureAutostart(printer);
3357
+ }
3358
+ if (!opts.skipHello && client) {
3359
+ await helloWorld(printer, client, createdAgents);
3360
+ }
3361
+ if (!opts.skipUpdate) {
3362
+ await configureUpdate(printer, actantHome);
3363
+ }
3364
+ printSummary(printer, actantHome);
3365
+ } catch (err) {
3366
+ if (isUserCancellation(err)) {
3367
+ printer.log(chalk29.dim("\n \u5DF2\u53D6\u6D88\u8BBE\u7F6E\u5411\u5BFC"));
3368
+ return;
3369
+ }
3370
+ presentError(err, printer);
3371
+ process.exitCode = 1;
3372
+ }
3373
+ });
3374
+ }
3375
+ function printBanner(printer) {
3376
+ printer.log("");
3377
+ printer.log(chalk29.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"));
3378
+ printer.log(chalk29.cyan("\u2551") + chalk29.bold(" Actant Setup Wizard ") + chalk29.cyan("\u2551"));
3379
+ printer.log(chalk29.cyan("\u2551") + chalk29.dim(" Build, manage, and compose AI agents ") + chalk29.cyan("\u2551"));
3380
+ printer.log(chalk29.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"));
3381
+ }
3382
+ function printSummary(printer, actantHome) {
3383
+ printer.log("");
3384
+ printer.log(chalk29.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"));
3385
+ printer.log(chalk29.green.bold(" Setup Complete!"));
3386
+ printer.log(chalk29.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"));
3387
+ printer.log("");
3388
+ printer.dim(` \u5DE5\u4F5C\u76EE\u5F55: ${actantHome}`);
3389
+ printer.log("");
3390
+ printer.log(" \u5FEB\u901F\u5F00\u59CB:");
3391
+ printer.log(` ${chalk29.cyan("actant daemon start")} \u542F\u52A8 Daemon`);
3392
+ printer.log(` ${chalk29.cyan("actant template list")} \u6D4F\u89C8\u6A21\u677F`);
3393
+ printer.log(` ${chalk29.cyan("actant agent list")} \u67E5\u770B Agent`);
3394
+ printer.log(` ${chalk29.cyan("actant agent chat <n>")} \u4E0E Agent \u5BF9\u8BDD`);
3395
+ printer.log(` ${chalk29.cyan("actant setup")} \u91CD\u65B0\u8FD0\u884C\u6B64\u5411\u5BFC`);
3396
+ printer.log("");
3397
+ printer.dim(" \u66F4\u591A\u5E2E\u52A9: actant help");
3398
+ printer.log("");
3399
+ }
3400
+ async function tryStartDaemon(printer, socketPath) {
3401
+ try {
3402
+ const { fork: fork2, spawn: spawn5 } = await import("child_process");
3403
+ const { join: join8 } = await import("path");
3404
+ const { isWindows: isWindows3, isSingleExecutable: isSingleExecutable2 } = await import("@actant/shared");
3405
+ let child;
3406
+ if (isSingleExecutable2()) {
3407
+ child = spawn5(process.execPath, ["--__actant-daemon"], {
3408
+ detached: true,
3409
+ stdio: ["ignore", "ignore", "ignore"],
3410
+ env: process.env
3411
+ });
3412
+ } else {
3413
+ const daemonScript = join8(import.meta.dirname, "..", "daemon-entry.js");
3414
+ child = isWindows3() ? spawn5(process.execPath, [daemonScript], {
3415
+ detached: true,
3416
+ stdio: ["ignore", "ignore", "ignore"],
3417
+ env: process.env
3418
+ }) : fork2(daemonScript, [], {
3419
+ detached: true,
3420
+ stdio: ["ignore", "ignore", "ignore", "ipc"],
3421
+ env: process.env
3422
+ });
3423
+ }
3424
+ if ("connected" in child && child.connected) child.disconnect();
3425
+ child.unref();
3426
+ const client = new RpcClient(socketPath);
3427
+ for (let i = 0; i < 10; i++) {
3428
+ await new Promise((r) => setTimeout(r, 1e3));
3429
+ if (await client.ping()) {
3430
+ printer.success(" \u2713 Daemon \u5DF2\u542F\u52A8");
3431
+ return true;
3432
+ }
3433
+ }
3434
+ printer.warn(" \u26A0 Daemon \u8FDB\u7A0B\u5DF2\u542F\u52A8\u4F46\u672A\u54CD\u5E94");
3435
+ return false;
3436
+ } catch (err) {
3437
+ printer.warn(` \u26A0 \u542F\u52A8 Daemon \u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
3438
+ return false;
3439
+ }
3440
+ }
3441
+ function isUserCancellation(err) {
3442
+ if (err instanceof Error) {
3443
+ return err.message.includes("User force closed") || err.message.includes("prompt was canceled") || err.name === "ExitPromptError";
3444
+ }
3445
+ return false;
3446
+ }
3447
+
2600
3448
  // src/program.ts
2601
3449
  function defaultSocketPath() {
2602
- return process.env["ACTANT_SOCKET"] ?? getDefaultIpcPath();
3450
+ const home = process.env["ACTANT_HOME"];
3451
+ return process.env["ACTANT_SOCKET"] ?? getDefaultIpcPath2(home);
2603
3452
  }
2604
3453
  function createProgram(socketPath, printer) {
2605
3454
  const sock = socketPath ?? defaultSocketPath();
2606
3455
  const client = new RpcClient(sock);
2607
- const program = new Command72("actant").version("0.1.0").description("Actant \u2014 Build, manage, and compose AI agents");
3456
+ const pkgPath = join7(import.meta.dirname, "..", "package.json");
3457
+ const { version } = JSON.parse(readFileSync4(pkgPath, "utf-8"));
3458
+ const program = new Command74("actant").version(version).description("Actant \u2014 Build, manage, and compose AI agents");
2608
3459
  program.addCommand(createTemplateCommand(client, printer));
2609
3460
  program.addCommand(createAgentCommand(client, printer));
2610
3461
  program.addCommand(createSkillCommand(client, printer));
@@ -2619,6 +3470,7 @@ function createProgram(socketPath, printer) {
2619
3470
  program.addCommand(createProxyCommand(printer));
2620
3471
  program.addCommand(createHelpCommand());
2621
3472
  program.addCommand(createSelfUpdateCommand());
3473
+ program.addCommand(createSetupCommand(printer));
2622
3474
  program.exitOverride();
2623
3475
  return program;
2624
3476
  }
@@ -2631,7 +3483,7 @@ async function run(argv) {
2631
3483
  if (!versionRequested && !helpRequested) {
2632
3484
  const sock = defaultSocketPath();
2633
3485
  const client = new RpcClient(sock);
2634
- const { startRepl } = await import("./repl-JIMJ2V2Y.js");
3486
+ const { startRepl } = await import("./repl-ZVBJSFT5.js");
2635
3487
  await startRepl(client, sock);
2636
3488
  return;
2637
3489
  }
@@ -2660,4 +3512,4 @@ export {
2660
3512
  createProgram,
2661
3513
  run
2662
3514
  };
2663
- //# sourceMappingURL=chunk-2FKBVXMH.js.map
3515
+ //# sourceMappingURL=chunk-664FYMDI.js.map