@clue-ai/cli 0.0.20 → 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 +93 -5
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
1003
|
-
|
|
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
|
|