@clue-ai/cli 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/clue-cli.mjs CHANGED
@@ -876,13 +876,93 @@ const renderEnvironmentInstructions = (instructions) => {
876
876
  const lines = [
877
877
  "",
878
878
  `環境変数の設定内容を ${instructions.env_file_path} に書き出しました。`,
879
- `Step2で ${instructions.env_file_path} を開き、各サービスの env GitHub Secrets/Variables に反映してください。`,
879
+ `Step2で ${instructions.env_file_path} を開き、各サービスの env、setup-agent 用AI設定、GitHub Secrets/Variables に反映してください。`,
880
+ `Step3で setup-agent を実行する前に ${instructions.setup_agent_required_env_names?.join(", ") ?? "CLUE_AI_PROVIDER, CLUE_AI_PROVIDER_API_KEY, CLUE_AI_MODEL"} を設定してください。`,
881
+ "CLUE_AI_PROVIDER_API_KEY は Clue API key ではなく、OpenAI または Anthropic の API key です。",
882
+ `setup-agent 実行: ${instructions.setup_agent_command ?? clueCliCommand("setup-agent --repo .")}`,
880
883
  `${instructions.env_file_path} は秘密情報を含むため、コミットしないでください。`,
881
884
  "",
882
885
  ];
883
886
  return `${lines.join("\n")}\n`;
884
887
  };
885
888
 
889
+ const renderSetupResult = ({ preparation }) => {
890
+ if (preparation?.status === "ready_for_ai") {
891
+ const envPath =
892
+ preparation.environment_instructions?.env_file_path ?? ".env.clue";
893
+ const manifestPath =
894
+ preparation.artifacts?.setup_manifest_path ?? ".clue/setup-manifest.json";
895
+ const workflowPath =
896
+ preparation.artifacts?.ci_workflow_path ??
897
+ ".github/workflows/clue-semantic-snapshot.yml";
898
+ return [
899
+ "Clue setup Step1 が完了しました。",
900
+ "",
901
+ "作成したファイル:",
902
+ `- ${envPath}`,
903
+ `- ${manifestPath}`,
904
+ `- ${workflowPath}`,
905
+ "",
906
+ "次にやること:",
907
+ `1. setup画面のStep2を見ながら ${envPath} に各サービスのenvとsetup-agent用AI API keyを設定してください。`,
908
+ `2. ${clueCliCommand("setup-agent --repo .")} を実行してください。`,
909
+ "",
910
+ "補足: CLUE_AI_PROVIDER_API_KEY は Clue API key ではなく、OpenAI または Anthropic の API key です。",
911
+ ].join("\n");
912
+ }
913
+
914
+ const blockers = Array.isArray(preparation?.blockers)
915
+ ? preparation.blockers
916
+ .map((blocker) => blocker.message ?? blocker.reason ?? blocker.code)
917
+ .filter(Boolean)
918
+ : [];
919
+ return [
920
+ "Clue setup に失敗しました。",
921
+ "",
922
+ "原因:",
923
+ ...(blockers.length > 0
924
+ ? blockers.map((blocker) => `- ${blocker}`)
925
+ : ["- setup に必要な情報を検出できませんでした。"]),
926
+ ].join("\n");
927
+ };
928
+
929
+ const renderSetupAgentResult = (report) => {
930
+ if (report?.status === "user_verification_pending") {
931
+ return [
932
+ "Clue setup-agent の実行が完了しました。",
933
+ "",
934
+ "コード差分を確認してください。",
935
+ `次の動作確認: ${clueCliCommand("setup-watch --local")}`,
936
+ ].join("\n");
937
+ }
938
+
939
+ if (report?.code === "CLUE_SETUP_AGENT_AI_CONFIG_MISSING") {
940
+ const missingInputs = report.setup_doctor?.missing_inputs ?? [];
941
+ return [
942
+ "Clue setup-agent を開始できません。",
943
+ "",
944
+ `不足している環境変数: ${missingInputs.join(", ")}`,
945
+ "",
946
+ ".env.clue の Setup Agent セクションに値を設定してから、もう一度実行してください。",
947
+ "",
948
+ "例:",
949
+ "CLUE_AI_PROVIDER=openai",
950
+ "CLUE_AI_PROVIDER_API_KEY=<your-openai-api-key>",
951
+ "CLUE_AI_MODEL=gpt-5.4-mini",
952
+ ].join("\n");
953
+ }
954
+
955
+ const blocker = report?.blockers?.[0];
956
+ const reason =
957
+ blocker?.reason ??
958
+ report?.setup_doctor?.reason ??
959
+ report?.code ??
960
+ "原因を特定できませんでした。";
961
+ return ["Clue setup-agent に失敗しました。", "", `原因: ${reason}`].join(
962
+ "\n",
963
+ );
964
+ };
965
+
886
966
  const main = async () => {
887
967
  const { command, flags } = parseArgs(process.argv.slice(2));
888
968
  if (
@@ -938,7 +1018,11 @@ const main = async () => {
938
1018
  flags,
939
1019
  repoRoot,
940
1020
  });
941
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
1021
+ if (flags.has("json")) {
1022
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
1023
+ } else {
1024
+ process.stdout.write(`${renderSetupAgentResult(report)}\n`);
1025
+ }
942
1026
  if (report.status === "blocked") {
943
1027
  process.exitCode = 1;
944
1028
  }
@@ -993,12 +1077,19 @@ const main = async () => {
993
1077
  const environmentInstructions = renderEnvironmentInstructions(
994
1078
  preparation.environment_instructions,
995
1079
  );
996
- if (environmentInstructions) {
1080
+ if (environmentInstructions && flags.has("json")) {
997
1081
  process.stderr.write(environmentInstructions);
998
1082
  }
999
- process.stdout.write(
1000
- `${JSON.stringify({ ...report, preparation }, null, 2)}\n`,
1001
- );
1083
+ if (flags.has("json")) {
1084
+ process.stdout.write(
1085
+ `${JSON.stringify({ ...report, preparation }, null, 2)}\n`,
1086
+ );
1087
+ } else {
1088
+ process.stdout.write(`${renderSetupResult({ preparation })}\n`);
1089
+ }
1090
+ if (!flags.has("json") && preparation.status === "blocked") {
1091
+ process.exitCode = 1;
1092
+ }
1002
1093
  return;
1003
1094
  }
1004
1095
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clue-ai/cli",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "clue-ai": "bin/clue-cli.mjs"
@@ -10,6 +10,11 @@ import { runSetupDoctor } from "./setup-doctor.mjs";
10
10
  const DEFAULT_SETUP_MANIFEST_PATH = ".clue/setup-manifest.json";
11
11
  const DEFAULT_ENV_GUIDE_PATH = ".env.clue";
12
12
  const DEFAULT_MAX_ATTEMPTS = 3;
13
+ const REQUIRED_SETUP_AGENT_AI_ENV_NAMES = [
14
+ "CLUE_AI_PROVIDER",
15
+ "CLUE_AI_PROVIDER_API_KEY",
16
+ "CLUE_AI_MODEL",
17
+ ];
13
18
  const DEPENDENCY_WRITE_FILE_CANDIDATES = [
14
19
  "package.json",
15
20
  "package-lock.json",
@@ -80,6 +85,50 @@ const aiProviderEnvFromFlags = ({ env, flags }) => {
80
85
  };
81
86
  };
82
87
 
88
+ const missingSetupAgentAiEnvNames = (env) =>
89
+ REQUIRED_SETUP_AGENT_AI_ENV_NAMES.filter((name) => !optionalString(env[name]));
90
+
91
+ const blockedMissingAiProviderConfig = ({ manifestPath, missingInputs }) => ({
92
+ status: "blocked",
93
+ code: "CLUE_SETUP_AGENT_AI_CONFIG_MISSING",
94
+ manifest_path: manifestPath,
95
+ attempts: [],
96
+ setup_check: null,
97
+ setup_doctor: {
98
+ status: "skipped",
99
+ reason: "AI provider configuration is missing",
100
+ missing_inputs: missingInputs,
101
+ report: null,
102
+ },
103
+ blockers: [
104
+ {
105
+ reason:
106
+ "setup-agent requires CLUE_AI_PROVIDER, CLUE_AI_PROVIDER_API_KEY, and CLUE_AI_MODEL before lifecycle planning",
107
+ evidence: {
108
+ missing_inputs: missingInputs,
109
+ env_file_path: DEFAULT_ENV_GUIDE_PATH,
110
+ supported_providers: ["openai", "anthropic"],
111
+ cli_flags: [
112
+ "--ai-provider",
113
+ "--ai-provider-api-key",
114
+ "--ai-model",
115
+ ],
116
+ },
117
+ },
118
+ ],
119
+ next_steps: [
120
+ "Open .env.clue and replace CLUE_AI_PROVIDER_API_KEY with an OpenAI API key for codex or an Anthropic API key for claude_code.",
121
+ "Confirm CLUE_AI_PROVIDER and CLUE_AI_MODEL are set in .env.clue or process env.",
122
+ "Alternatively run setup-agent with --ai-provider, --ai-provider-api-key, and --ai-model.",
123
+ ],
124
+ user_verification: {
125
+ setup_watch_owner: "user",
126
+ setup_watch_auto_run: false,
127
+ status: "not_reached",
128
+ required_command: "npx -y @clue-ai/cli setup-watch --local",
129
+ },
130
+ });
131
+
83
132
  const requireManifest = async ({ manifestPath, repoRoot }) => {
84
133
  try {
85
134
  return await readJson(resolve(repoRoot, manifestPath));
@@ -344,6 +393,13 @@ export const runSetupAgent = async ({
344
393
  DEFAULT_MAX_ATTEMPTS,
345
394
  );
346
395
  const aiEnv = aiProviderEnvFromFlags({ env: mergedEnv, flags });
396
+ const missingAiInputs = missingSetupAgentAiEnvNames(aiEnv);
397
+ if (missingAiInputs.length > 0) {
398
+ return blockedMissingAiProviderConfig({
399
+ manifestPath,
400
+ missingInputs: missingAiInputs,
401
+ });
402
+ }
347
403
  const attempts = [];
348
404
  let failureContext = null;
349
405
  let lastSetupCheck = null;
@@ -32,6 +32,11 @@ const BACKEND_RUNTIME_ENV_NAMES = [
32
32
  "CLUE_INGEST_ENDPOINT",
33
33
  "CLUE_API_KEY",
34
34
  ];
35
+ const SETUP_AGENT_AI_ENV_NAMES = [
36
+ "CLUE_AI_PROVIDER",
37
+ "CLUE_AI_PROVIDER_API_KEY",
38
+ "CLUE_AI_MODEL",
39
+ ];
35
40
  const AI_PROVIDER_GUIDES = {
36
41
  codex: {
37
42
  provider: "openai",
@@ -352,6 +357,14 @@ const buildEnvironmentGuideText = (instructions) => {
352
357
  "",
353
358
  );
354
359
  }
360
+ lines.push(
361
+ "Setup Agent",
362
+ "# Before running `npx -y @clue-ai/cli setup-agent --repo .`, set the AI provider values below.",
363
+ "# setup-agent reads CLUE_AI_PROVIDER, CLUE_AI_PROVIDER_API_KEY, and CLUE_AI_MODEL from this file or process env.",
364
+ "# CLUE_AI_PROVIDER_API_KEY is not a Clue key. It must be an OpenAI key for codex or an Anthropic key for claude_code.",
365
+ "# You may also pass --ai-provider, --ai-provider-api-key, and --ai-model directly to setup-agent.",
366
+ "",
367
+ );
355
368
  lines.push(
356
369
  "GitHub Secrets",
357
370
  ...instructions.ci_github.secrets.flatMap(renderEnvironmentEntry),
@@ -374,7 +387,9 @@ const summarizeEnvironmentInstructions = (instructions) => {
374
387
  return {
375
388
  status: "ready",
376
389
  env_file_path: instructions.env_file_path,
377
- message: `${instructions.env_file_path} を開き、各サービスの env GitHub Secrets に反映してください。`,
390
+ message: `${instructions.env_file_path} を開き、各サービスの env、setup-agent 用AI設定、GitHub Secrets/Variables に反映してください。`,
391
+ setup_agent_required_env_names: SETUP_AGENT_AI_ENV_NAMES,
392
+ setup_agent_command: "npx -y @clue-ai/cli setup-agent --repo .",
378
393
  service_env_block_count: instructions.service_env_blocks.length,
379
394
  github_secret_names: instructions.ci_github.secrets.map(
380
395
  (entry) => entry.name,