@clue-ai/cli 0.0.20 → 0.0.22

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
@@ -886,6 +886,83 @@ const renderEnvironmentInstructions = (instructions) => {
886
886
  return `${lines.join("\n")}\n`;
887
887
  };
888
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
+
889
966
  const main = async () => {
890
967
  const { command, flags } = parseArgs(process.argv.slice(2));
891
968
  if (
@@ -941,7 +1018,11 @@ const main = async () => {
941
1018
  flags,
942
1019
  repoRoot,
943
1020
  });
944
- 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
+ }
945
1026
  if (report.status === "blocked") {
946
1027
  process.exitCode = 1;
947
1028
  }
@@ -996,12 +1077,19 @@ const main = async () => {
996
1077
  const environmentInstructions = renderEnvironmentInstructions(
997
1078
  preparation.environment_instructions,
998
1079
  );
999
- if (environmentInstructions) {
1080
+ if (environmentInstructions && flags.has("json")) {
1000
1081
  process.stderr.write(environmentInstructions);
1001
1082
  }
1002
- process.stdout.write(
1003
- `${JSON.stringify({ ...report, preparation }, null, 2)}\n`,
1004
- );
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
+ }
1005
1093
  return;
1006
1094
  }
1007
1095
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clue-ai/cli",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "clue-ai": "bin/clue-cli.mjs"
@@ -329,6 +329,35 @@ const attemptFailureContext = ({ attempt, error, setupCheck, stage }) => ({
329
329
  failed_checks: failedChecks(setupCheck),
330
330
  });
331
331
 
332
+ const summarizeFailedChecks = (checks) => {
333
+ if (!Array.isArray(checks) || checks.length === 0) return null;
334
+ return checks
335
+ .map((check) => {
336
+ const missingApis = Array.isArray(check.details?.missing_apis)
337
+ ? check.details.missing_apis.filter(Boolean)
338
+ : [];
339
+ const parts = [
340
+ check.id,
341
+ check.summary,
342
+ missingApis.length ? `missing APIs: ${missingApis.join(", ")}` : null,
343
+ ].filter(Boolean);
344
+ return parts.join(" - ");
345
+ })
346
+ .join("; ");
347
+ };
348
+
349
+ const summarizeAttemptFailure = (failureContext) => {
350
+ if (!failureContext) return "no attempt details were recorded";
351
+ if (failureContext.error) {
352
+ return `attempt ${failureContext.attempt} ${failureContext.stage} failed: ${failureContext.error}`;
353
+ }
354
+ const failedCheckSummary = summarizeFailedChecks(failureContext.failed_checks);
355
+ if (failedCheckSummary) {
356
+ return `attempt ${failureContext.attempt} setup-check failed: ${failedCheckSummary}`;
357
+ }
358
+ return `attempt ${failureContext.attempt} failed without detailed error output`;
359
+ };
360
+
332
361
  export const runSetupAgent = async ({
333
362
  env = process.env,
334
363
  flags = new Map(),
@@ -490,8 +519,12 @@ export const runSetupAgent = async ({
490
519
  },
491
520
  blockers: [
492
521
  {
493
- reason: "setup-agent retry budget exhausted",
494
- evidence: failureContext,
522
+ reason: summarizeAttemptFailure(failureContext),
523
+ evidence: {
524
+ ...failureContext,
525
+ retry_budget_exhausted: true,
526
+ max_attempts: maxAttempts,
527
+ },
495
528
  },
496
529
  ],
497
530
  user_verification: {