ai-ops-cli 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/rules/communication.yaml +3 -2
- package/dist/bin/index.js +182 -236
- package/dist/bin/index.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
|
-
import * as
|
|
7
|
+
import * as p3 from "@clack/prompts";
|
|
8
8
|
|
|
9
9
|
// src/core/schemas/rule.schema.ts
|
|
10
10
|
import { z } from "zod";
|
|
@@ -362,7 +362,7 @@ var partitionRules = (rules) => {
|
|
|
362
362
|
return { global, domain };
|
|
363
363
|
};
|
|
364
364
|
var renderFrontmatter = (paths) => {
|
|
365
|
-
const lines = paths.map((
|
|
365
|
+
const lines = paths.map((p8) => ` - "${p8}"`).join("\n");
|
|
366
366
|
return `---
|
|
367
367
|
paths:
|
|
368
368
|
${lines}
|
|
@@ -973,7 +973,7 @@ var removeDirectories = (basePath, relativeDirs) => {
|
|
|
973
973
|
return removed;
|
|
974
974
|
};
|
|
975
975
|
|
|
976
|
-
// src/lib/
|
|
976
|
+
// src/lib/tool-settings.ts
|
|
977
977
|
import * as p from "@clack/prompts";
|
|
978
978
|
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync6, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
979
979
|
import { join as join11 } from "path";
|
|
@@ -1012,57 +1012,24 @@ var deepRemoveKeys = (base, patch) => {
|
|
|
1012
1012
|
var PROMPT_CANCELLED = /* @__PURE__ */ Symbol("prompt-cancelled");
|
|
1013
1013
|
var isPromptCancelled = (value) => value === PROMPT_CANCELLED;
|
|
1014
1014
|
|
|
1015
|
-
// src/lib/
|
|
1016
|
-
var
|
|
1017
|
-
{
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
hint: "ui.showLineNumbers: false \u2014 \uCF54\uB4DC \uBCF5\uC0AC \uC2DC \uC904 \uBC88\uD638\uAC00 \uD3EC\uD568\uB418\uC9C0 \uC54A\uB3C4\uB85D \uBE44\uD65C\uC131\uD654",
|
|
1021
|
-
patch: { ui: { showLineNumbers: false } }
|
|
1022
|
-
},
|
|
1023
|
-
{
|
|
1024
|
-
value: "plan",
|
|
1025
|
-
label: "Plan \u2014 \uACC4\uD68D \uD30C\uC77C \uC800\uC7A5 \uBC0F \uBAA8\uB378 \uB77C\uC6B0\uD305",
|
|
1026
|
-
hint: "general.plan.directory: .gemini/plans, modelRouting: true \u2014 AI \uACC4\uD68D\uC744 \uD30C\uC77C\uB85C \uC800\uC7A5\uD558\uACE0 \uD0DC\uC2A4\uD06C\uBCC4 \uCD5C\uC801 \uBAA8\uB378 \uC790\uB3D9 \uC120\uD0DD",
|
|
1027
|
-
patch: { general: { plan: { directory: ".gemini/plans", modelRouting: true } } }
|
|
1028
|
-
},
|
|
1029
|
-
{
|
|
1030
|
-
value: "sessionRetention",
|
|
1031
|
-
label: "Session Retention \u2014 \uC138\uC158 30\uC77C \uBCF4\uC874",
|
|
1032
|
-
hint: "general.sessionRetention.maxAge: 30d \u2014 \uC774\uC804 \uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8\uB97C 30\uC77C\uAC04 \uC720\uC9C0",
|
|
1033
|
-
patch: { general: { sessionRetention: { maxAge: "30d" } } }
|
|
1034
|
-
},
|
|
1035
|
-
{
|
|
1036
|
-
value: "experimental",
|
|
1037
|
-
label: "Experimental \u2014 JIT \uCEE8\uD14D\uC2A4\uD2B8 + Plan \uAE30\uB2A5",
|
|
1038
|
-
hint: "experimental.jitContext: true, plan: true \u2014 \uC11C\uBE0C\uB514\uB809\uD1A0\uB9AC \uCEE8\uD14D\uC2A4\uD2B8 \uC9C0\uC5F0 \uB85C\uB529 \uBC0F \uACC4\uD68D \uAE30\uB2A5 \uC2E4\uD5D8\uC801 \uD65C\uC131\uD654",
|
|
1039
|
-
patch: { experimental: { jitContext: true, plan: true } }
|
|
1040
|
-
}
|
|
1041
|
-
];
|
|
1042
|
-
var promptGeminiSettings = async () => {
|
|
1043
|
-
const wantSettings = await p.confirm({
|
|
1044
|
-
message: "Gemini CLI \uC124\uC815 \uD30C\uC77C(.gemini/settings.json)\uC744 \uC124\uCE58\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
1045
|
-
initialValue: true
|
|
1046
|
-
});
|
|
1047
|
-
if (p.isCancel(wantSettings)) return PROMPT_CANCELLED;
|
|
1048
|
-
if (!wantSettings) return null;
|
|
1015
|
+
// src/lib/tool-settings.ts
|
|
1016
|
+
var promptToolSettings = async (config) => {
|
|
1017
|
+
const want = await p.confirm({ message: config.promptMessage, initialValue: true });
|
|
1018
|
+
if (p.isCancel(want)) return PROMPT_CANCELLED;
|
|
1019
|
+
if (!want) return null;
|
|
1049
1020
|
const selected = await p.multiselect({
|
|
1050
1021
|
message: "\uC124\uCE58\uD560 \uC124\uC815 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD558\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4\uB85C \uD1A0\uAE00)",
|
|
1051
|
-
options:
|
|
1052
|
-
|
|
1053
|
-
label: g.label,
|
|
1054
|
-
hint: g.hint
|
|
1055
|
-
})),
|
|
1056
|
-
initialValues: SETTING_GROUPS.map((g) => g.value),
|
|
1022
|
+
options: config.groups.map((g) => ({ value: g.value, label: g.label, hint: g.hint })),
|
|
1023
|
+
initialValues: config.groups.map((g) => g.value),
|
|
1057
1024
|
required: false
|
|
1058
1025
|
});
|
|
1059
1026
|
if (p.isCancel(selected)) return PROMPT_CANCELLED;
|
|
1060
1027
|
return selected;
|
|
1061
1028
|
};
|
|
1062
|
-
var
|
|
1029
|
+
var installToolSettings = (basePath, selectedValues, config) => {
|
|
1063
1030
|
if (selectedValues.length === 0) return;
|
|
1064
|
-
const settingsDir = join11(basePath,
|
|
1065
|
-
const settingsPath = join11(settingsDir,
|
|
1031
|
+
const settingsDir = join11(basePath, config.dirName);
|
|
1032
|
+
const settingsPath = join11(settingsDir, config.fileName);
|
|
1066
1033
|
let existing = {};
|
|
1067
1034
|
if (existsSync5(settingsPath)) {
|
|
1068
1035
|
try {
|
|
@@ -1072,15 +1039,15 @@ var installGeminiSettings = (basePath, selectedValues) => {
|
|
|
1072
1039
|
}
|
|
1073
1040
|
let merged = existing;
|
|
1074
1041
|
for (const val of selectedValues) {
|
|
1075
|
-
const group =
|
|
1042
|
+
const group = config.groups.find((g) => g.value === val);
|
|
1076
1043
|
if (!group) continue;
|
|
1077
1044
|
merged = deepMerge(merged, group.patch);
|
|
1078
1045
|
}
|
|
1079
1046
|
mkdirSync5(settingsDir, { recursive: true });
|
|
1080
1047
|
writeFileSync5(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
1081
1048
|
};
|
|
1082
|
-
var
|
|
1083
|
-
const settingsPath = join11(basePath,
|
|
1049
|
+
var uninstallToolSettings = (basePath, selectedValues, config) => {
|
|
1050
|
+
const settingsPath = join11(basePath, config.dirName, config.fileName);
|
|
1084
1051
|
if (!existsSync5(settingsPath)) return "notFound";
|
|
1085
1052
|
let existing = {};
|
|
1086
1053
|
try {
|
|
@@ -1091,12 +1058,9 @@ var uninstallGeminiSettings = (basePath, selectedValues) => {
|
|
|
1091
1058
|
}
|
|
1092
1059
|
let result = existing;
|
|
1093
1060
|
for (const val of selectedValues) {
|
|
1094
|
-
const group =
|
|
1061
|
+
const group = config.groups.find((g) => g.value === val);
|
|
1095
1062
|
if (!group) continue;
|
|
1096
|
-
result = deepRemoveKeys(
|
|
1097
|
-
result,
|
|
1098
|
-
group.patch
|
|
1099
|
-
);
|
|
1063
|
+
result = deepRemoveKeys(result, group.patch);
|
|
1100
1064
|
}
|
|
1101
1065
|
if (Object.keys(result).length === 0) {
|
|
1102
1066
|
rmSync2(settingsPath, { force: true });
|
|
@@ -1106,10 +1070,44 @@ var uninstallGeminiSettings = (basePath, selectedValues) => {
|
|
|
1106
1070
|
return "cleaned";
|
|
1107
1071
|
};
|
|
1108
1072
|
|
|
1073
|
+
// src/lib/gemini-settings.ts
|
|
1074
|
+
var SETTING_GROUPS = [
|
|
1075
|
+
{
|
|
1076
|
+
value: "ui",
|
|
1077
|
+
label: "UI \u2014 \uC904 \uBC88\uD638 \uC228\uAE30\uAE30",
|
|
1078
|
+
hint: "ui.showLineNumbers: false \u2014 \uCF54\uB4DC \uBCF5\uC0AC \uC2DC \uC904 \uBC88\uD638\uAC00 \uD3EC\uD568\uB418\uC9C0 \uC54A\uB3C4\uB85D \uBE44\uD65C\uC131\uD654",
|
|
1079
|
+
patch: { ui: { showLineNumbers: false } }
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
value: "plan",
|
|
1083
|
+
label: "Plan \u2014 \uACC4\uD68D \uD30C\uC77C \uC800\uC7A5 \uBC0F \uBAA8\uB378 \uB77C\uC6B0\uD305",
|
|
1084
|
+
hint: "general.plan.directory: .gemini/plans, modelRouting: true \u2014 AI \uACC4\uD68D\uC744 \uD30C\uC77C\uB85C \uC800\uC7A5\uD558\uACE0 \uD0DC\uC2A4\uD06C\uBCC4 \uCD5C\uC801 \uBAA8\uB378 \uC790\uB3D9 \uC120\uD0DD",
|
|
1085
|
+
patch: { general: { plan: { directory: ".gemini/plans", modelRouting: true } } }
|
|
1086
|
+
},
|
|
1087
|
+
{
|
|
1088
|
+
value: "sessionRetention",
|
|
1089
|
+
label: "Session Retention \u2014 \uC138\uC158 30\uC77C \uBCF4\uC874",
|
|
1090
|
+
hint: "general.sessionRetention.maxAge: 30d \u2014 \uC774\uC804 \uB300\uD654 \uCEE8\uD14D\uC2A4\uD2B8\uB97C 30\uC77C\uAC04 \uC720\uC9C0",
|
|
1091
|
+
patch: { general: { sessionRetention: { maxAge: "30d" } } }
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
value: "experimental",
|
|
1095
|
+
label: "Experimental \u2014 JIT \uCEE8\uD14D\uC2A4\uD2B8 + Plan \uAE30\uB2A5",
|
|
1096
|
+
hint: "experimental.jitContext: true, plan: true \u2014 \uC11C\uBE0C\uB514\uB809\uD1A0\uB9AC \uCEE8\uD14D\uC2A4\uD2B8 \uC9C0\uC5F0 \uB85C\uB529 \uBC0F \uACC4\uD68D \uAE30\uB2A5 \uC2E4\uD5D8\uC801 \uD65C\uC131\uD654",
|
|
1097
|
+
patch: { experimental: { jitContext: true, plan: true } }
|
|
1098
|
+
}
|
|
1099
|
+
];
|
|
1100
|
+
var CONFIG = {
|
|
1101
|
+
dirName: ".gemini",
|
|
1102
|
+
fileName: "settings.json",
|
|
1103
|
+
promptMessage: "Gemini CLI \uC124\uC815 \uD30C\uC77C(.gemini/settings.json)\uC744 \uC124\uCE58\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
1104
|
+
groups: SETTING_GROUPS
|
|
1105
|
+
};
|
|
1106
|
+
var promptGeminiSettings = () => promptToolSettings(CONFIG);
|
|
1107
|
+
var installGeminiSettings = (basePath, selectedValues) => installToolSettings(basePath, selectedValues, CONFIG);
|
|
1108
|
+
var uninstallGeminiSettings = (basePath, selectedValues) => uninstallToolSettings(basePath, selectedValues, CONFIG);
|
|
1109
|
+
|
|
1109
1110
|
// src/lib/claude-settings.ts
|
|
1110
|
-
import * as p2 from "@clack/prompts";
|
|
1111
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
1112
|
-
import { join as join12 } from "path";
|
|
1113
1111
|
var SETTING_GROUPS2 = [
|
|
1114
1112
|
{
|
|
1115
1113
|
value: "model",
|
|
@@ -1124,77 +1122,20 @@ var SETTING_GROUPS2 = [
|
|
|
1124
1122
|
patch: { plansDirectory: "./.claude/plans" }
|
|
1125
1123
|
}
|
|
1126
1124
|
];
|
|
1127
|
-
var
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
options: SETTING_GROUPS2.map((g) => ({
|
|
1137
|
-
value: g.value,
|
|
1138
|
-
label: g.label,
|
|
1139
|
-
hint: g.hint
|
|
1140
|
-
})),
|
|
1141
|
-
initialValues: SETTING_GROUPS2.map((g) => g.value),
|
|
1142
|
-
required: false
|
|
1143
|
-
});
|
|
1144
|
-
if (p2.isCancel(selected)) return PROMPT_CANCELLED;
|
|
1145
|
-
return selected;
|
|
1146
|
-
};
|
|
1147
|
-
var installClaudeSettings = (basePath, selectedValues) => {
|
|
1148
|
-
if (selectedValues.length === 0) return;
|
|
1149
|
-
const settingsDir = join12(basePath, ".claude");
|
|
1150
|
-
const settingsPath = join12(settingsDir, "settings.local.json");
|
|
1151
|
-
let existing = {};
|
|
1152
|
-
if (existsSync6(settingsPath)) {
|
|
1153
|
-
try {
|
|
1154
|
-
existing = JSON.parse(readFileSync7(settingsPath, "utf-8"));
|
|
1155
|
-
} catch {
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
let merged = existing;
|
|
1159
|
-
for (const val of selectedValues) {
|
|
1160
|
-
const group = SETTING_GROUPS2.find((g) => g.value === val);
|
|
1161
|
-
if (!group) continue;
|
|
1162
|
-
merged = deepMerge(merged, group.patch);
|
|
1163
|
-
}
|
|
1164
|
-
mkdirSync6(settingsDir, { recursive: true });
|
|
1165
|
-
writeFileSync6(settingsPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
|
|
1166
|
-
};
|
|
1167
|
-
var uninstallClaudeSettings = (basePath, selectedValues) => {
|
|
1168
|
-
const settingsPath = join12(basePath, ".claude", "settings.local.json");
|
|
1169
|
-
if (!existsSync6(settingsPath)) return "notFound";
|
|
1170
|
-
let existing = {};
|
|
1171
|
-
try {
|
|
1172
|
-
existing = JSON.parse(readFileSync7(settingsPath, "utf-8"));
|
|
1173
|
-
} catch {
|
|
1174
|
-
rmSync3(settingsPath, { force: true });
|
|
1175
|
-
return "deleted";
|
|
1176
|
-
}
|
|
1177
|
-
let result = existing;
|
|
1178
|
-
for (const val of selectedValues) {
|
|
1179
|
-
const group = SETTING_GROUPS2.find((g) => g.value === val);
|
|
1180
|
-
if (!group) continue;
|
|
1181
|
-
result = deepRemoveKeys(
|
|
1182
|
-
result,
|
|
1183
|
-
group.patch
|
|
1184
|
-
);
|
|
1185
|
-
}
|
|
1186
|
-
if (Object.keys(result).length === 0) {
|
|
1187
|
-
rmSync3(settingsPath, { force: true });
|
|
1188
|
-
return "deleted";
|
|
1189
|
-
}
|
|
1190
|
-
writeFileSync6(settingsPath, JSON.stringify(result, null, 2) + "\n", "utf-8");
|
|
1191
|
-
return "cleaned";
|
|
1192
|
-
};
|
|
1125
|
+
var CONFIG2 = {
|
|
1126
|
+
dirName: ".claude",
|
|
1127
|
+
fileName: "settings.local.json",
|
|
1128
|
+
promptMessage: "Claude Code \uC124\uC815 \uD30C\uC77C(.claude/settings.local.json)\uC744 \uC124\uCE58\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
1129
|
+
groups: SETTING_GROUPS2
|
|
1130
|
+
};
|
|
1131
|
+
var promptClaudeSettings = () => promptToolSettings(CONFIG2);
|
|
1132
|
+
var installClaudeSettings = (basePath, selectedValues) => installToolSettings(basePath, selectedValues, CONFIG2);
|
|
1133
|
+
var uninstallClaudeSettings = (basePath, selectedValues) => uninstallToolSettings(basePath, selectedValues, CONFIG2);
|
|
1193
1134
|
|
|
1194
1135
|
// src/lib/prettier-ignore.ts
|
|
1195
|
-
import * as
|
|
1196
|
-
import { existsSync as
|
|
1197
|
-
import { join as
|
|
1136
|
+
import * as p2 from "@clack/prompts";
|
|
1137
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
1138
|
+
import { join as join12 } from "path";
|
|
1198
1139
|
var PRETTIER_IGNORE_CONTENT = `# CLAUDE
|
|
1199
1140
|
.claude/rules/
|
|
1200
1141
|
**/CLAUDE.md
|
|
@@ -1252,39 +1193,39 @@ var stripAiOpsSection2 = (content) => {
|
|
|
1252
1193
|
return result.join("\n");
|
|
1253
1194
|
};
|
|
1254
1195
|
var promptPrettierIgnore = async () => {
|
|
1255
|
-
const want = await
|
|
1196
|
+
const want = await p2.confirm({
|
|
1256
1197
|
message: ".prettierignore\uB97C \uC124\uCE58\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C? (VSCode Prettier \uC790\uB3D9 \uD3EC\uB9F7\uC73C\uB85C\uBD80\uD130 AI \uADDC\uCE59 \uD30C\uC77C \uBCF4\uD638)",
|
|
1257
1198
|
initialValue: false
|
|
1258
1199
|
});
|
|
1259
|
-
if (
|
|
1200
|
+
if (p2.isCancel(want)) return PROMPT_CANCELLED;
|
|
1260
1201
|
return want;
|
|
1261
1202
|
};
|
|
1262
1203
|
var installPrettierIgnore = (basePath) => {
|
|
1263
|
-
const filePath =
|
|
1204
|
+
const filePath = join12(basePath, ".prettierignore");
|
|
1264
1205
|
const section = wrapSection(PRETTIER_IGNORE_CONTENT);
|
|
1265
|
-
if (!
|
|
1266
|
-
|
|
1206
|
+
if (!existsSync6(filePath)) {
|
|
1207
|
+
writeFileSync6(filePath, section + "\n", "utf-8");
|
|
1267
1208
|
return;
|
|
1268
1209
|
}
|
|
1269
|
-
const existing =
|
|
1210
|
+
const existing = readFileSync7(filePath, "utf-8");
|
|
1270
1211
|
if (hasAiOpsSection2(existing)) {
|
|
1271
|
-
|
|
1212
|
+
writeFileSync6(filePath, replaceSection(existing, PRETTIER_IGNORE_CONTENT), "utf-8");
|
|
1272
1213
|
return;
|
|
1273
1214
|
}
|
|
1274
1215
|
const separator = existing.endsWith("\n") ? "\n" : "\n\n";
|
|
1275
|
-
|
|
1216
|
+
writeFileSync6(filePath, existing + separator + section + "\n", "utf-8");
|
|
1276
1217
|
};
|
|
1277
1218
|
var uninstallPrettierIgnore = (basePath) => {
|
|
1278
|
-
const filePath =
|
|
1279
|
-
if (!
|
|
1280
|
-
const existing =
|
|
1219
|
+
const filePath = join12(basePath, ".prettierignore");
|
|
1220
|
+
if (!existsSync6(filePath)) return "notFound";
|
|
1221
|
+
const existing = readFileSync7(filePath, "utf-8");
|
|
1281
1222
|
if (!hasAiOpsSection2(existing)) return "notFound";
|
|
1282
1223
|
const stripped = stripAiOpsSection2(existing).trim();
|
|
1283
1224
|
if (stripped.length === 0) {
|
|
1284
|
-
|
|
1225
|
+
rmSync3(filePath, { force: true });
|
|
1285
1226
|
return "deleted";
|
|
1286
1227
|
}
|
|
1287
|
-
|
|
1228
|
+
writeFileSync6(filePath, stripped + "\n", "utf-8");
|
|
1288
1229
|
return "cleaned";
|
|
1289
1230
|
};
|
|
1290
1231
|
|
|
@@ -1405,7 +1346,7 @@ var partitionPresetSkills = (params) => {
|
|
|
1405
1346
|
};
|
|
1406
1347
|
};
|
|
1407
1348
|
var selectPresetAndFineTune = async (workspaceName, presets, allRules, allSkills, selectedTools, globalInstalledSkills) => {
|
|
1408
|
-
const preset = await
|
|
1349
|
+
const preset = await p3.select({
|
|
1409
1350
|
message: `[${workspaceName}] \uD504\uB9AC\uC14B\uC744 \uC120\uD0DD\uD558\uC138\uC694`,
|
|
1410
1351
|
options: presets.map((candidate) => ({
|
|
1411
1352
|
value: candidate,
|
|
@@ -1413,10 +1354,10 @@ var selectPresetAndFineTune = async (workspaceName, presets, allRules, allSkills
|
|
|
1413
1354
|
hint: candidate.description
|
|
1414
1355
|
}))
|
|
1415
1356
|
});
|
|
1416
|
-
if (
|
|
1357
|
+
if (p3.isCancel(preset)) return null;
|
|
1417
1358
|
const finalRules = resolvePresetRules(preset, allRules);
|
|
1418
1359
|
if (finalRules.length > 0) {
|
|
1419
|
-
|
|
1360
|
+
p3.note(finalRules.map((rule) => ` \u2713 ${rule.id}`).join("\n"), `[${workspaceName}] core rules (\uC7A0\uAE08)`);
|
|
1420
1361
|
}
|
|
1421
1362
|
const { globalSkills, installableSkills } = partitionPresetSkills({
|
|
1422
1363
|
preset,
|
|
@@ -1428,10 +1369,10 @@ var selectPresetAndFineTune = async (workspaceName, presets, allRules, allSkills
|
|
|
1428
1369
|
const globalLines = globalSkills.map(
|
|
1429
1370
|
({ skill, availableTools }) => ` \u2713 ${skill.id} (${formatToolList(availableTools)})`
|
|
1430
1371
|
);
|
|
1431
|
-
|
|
1372
|
+
p3.note(globalLines.join("\n"), `[${workspaceName}] already available globally`);
|
|
1432
1373
|
}
|
|
1433
1374
|
if (installableSkills.length === 0) {
|
|
1434
|
-
|
|
1375
|
+
p3.note(" \uC0C8\uB85C \uC124\uCE58\uD560 reference skill\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.", `[${workspaceName}] installable reference skills`);
|
|
1435
1376
|
return {
|
|
1436
1377
|
workspace: workspaceName,
|
|
1437
1378
|
preset,
|
|
@@ -1439,7 +1380,7 @@ var selectPresetAndFineTune = async (workspaceName, presets, allRules, allSkills
|
|
|
1439
1380
|
finalSkillTargets: []
|
|
1440
1381
|
};
|
|
1441
1382
|
}
|
|
1442
|
-
const selectedSkillIds = await
|
|
1383
|
+
const selectedSkillIds = await p3.multiselect({
|
|
1443
1384
|
message: `[${workspaceName}] installable reference skills \uC120\uD0DD`,
|
|
1444
1385
|
options: installableSkills.map(({ skill, requestedTools, globalTools }) => ({
|
|
1445
1386
|
value: skill.id,
|
|
@@ -1449,7 +1390,7 @@ var selectPresetAndFineTune = async (workspaceName, presets, allRules, allSkills
|
|
|
1449
1390
|
initialValues: installableSkills.map(({ skill }) => skill.id),
|
|
1450
1391
|
required: false
|
|
1451
1392
|
});
|
|
1452
|
-
if (
|
|
1393
|
+
if (p3.isCancel(selectedSkillIds)) return null;
|
|
1453
1394
|
const selectedSkillSet = new Set(selectedSkillIds);
|
|
1454
1395
|
return {
|
|
1455
1396
|
workspace: workspaceName,
|
|
@@ -1462,28 +1403,28 @@ var selectPresetAndFineTune = async (workspaceName, presets, allRules, allSkills
|
|
|
1462
1403
|
};
|
|
1463
1404
|
};
|
|
1464
1405
|
var selectInitSkillScope = async () => {
|
|
1465
|
-
const scope = await
|
|
1406
|
+
const scope = await p3.select({
|
|
1466
1407
|
message: "\uC120\uD0DD\uB41C skills\uB97C \uC5B4\uB514\uC5D0 \uC124\uCE58\uD560\uAE4C\uC694?",
|
|
1467
1408
|
options: [
|
|
1468
1409
|
{ value: "user", label: "user (global)", hint: "\uAE30\uBCF8\uAC12. \uC5EC\uB7EC \uD504\uB85C\uC81D\uD2B8\uC5D0\uC11C \uC7AC\uC0AC\uC6A9" },
|
|
1469
1410
|
{ value: "project", label: "project", hint: "\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uC5D0\uB9CC \uC124\uCE58" }
|
|
1470
1411
|
]
|
|
1471
1412
|
});
|
|
1472
|
-
return
|
|
1413
|
+
return p3.isCancel(scope) ? null : scope;
|
|
1473
1414
|
};
|
|
1474
1415
|
var initCommand = async () => {
|
|
1475
1416
|
const basePath = resolveBasePath();
|
|
1476
1417
|
const userBasePath = resolveUserBasePath();
|
|
1477
1418
|
const rulesDir = resolveRulesDir();
|
|
1478
1419
|
const skillsDir = resolveSkillsDir();
|
|
1479
|
-
const spinner3 =
|
|
1420
|
+
const spinner3 = p3.spinner();
|
|
1480
1421
|
let spinnerStarted = false;
|
|
1481
1422
|
const cancelInit = (params) => {
|
|
1482
1423
|
if (spinnerStarted) {
|
|
1483
1424
|
spinner3.stop("\uC124\uCE58 \uC911\uB2E8\uB428");
|
|
1484
1425
|
spinnerStarted = false;
|
|
1485
1426
|
}
|
|
1486
|
-
|
|
1427
|
+
p3.cancel(params?.message ?? "\uCDE8\uC18C\uB428");
|
|
1487
1428
|
process.exit(params?.exitCode ?? 0);
|
|
1488
1429
|
};
|
|
1489
1430
|
const handleSigint = () => cancelInit({
|
|
@@ -1492,20 +1433,20 @@ var initCommand = async () => {
|
|
|
1492
1433
|
});
|
|
1493
1434
|
process.once("SIGINT", handleSigint);
|
|
1494
1435
|
try {
|
|
1495
|
-
|
|
1496
|
-
const selectedTools = await
|
|
1436
|
+
p3.intro("ai-ops init");
|
|
1437
|
+
const selectedTools = await p3.multiselect({
|
|
1497
1438
|
message: "AI \uB3C4\uAD6C\uB97C \uC120\uD0DD\uD558\uC138\uC694",
|
|
1498
1439
|
options: TOOL_OPTIONS,
|
|
1499
1440
|
required: true
|
|
1500
1441
|
});
|
|
1501
|
-
if (
|
|
1442
|
+
if (p3.isCancel(selectedTools)) {
|
|
1502
1443
|
cancelInit();
|
|
1503
1444
|
}
|
|
1504
|
-
const isMonorepo = await
|
|
1445
|
+
const isMonorepo = await p3.confirm({
|
|
1505
1446
|
message: "\uBAA8\uB178\uB808\uD3EC \uD504\uB85C\uC81D\uD2B8\uC785\uB2C8\uAE4C?",
|
|
1506
1447
|
initialValue: false
|
|
1507
1448
|
});
|
|
1508
|
-
if (
|
|
1449
|
+
if (p3.isCancel(isMonorepo)) {
|
|
1509
1450
|
cancelInit();
|
|
1510
1451
|
}
|
|
1511
1452
|
const allRules = loadAllRules(rulesDir);
|
|
@@ -1526,12 +1467,12 @@ var initCommand = async () => {
|
|
|
1526
1467
|
mappings.push(mapping);
|
|
1527
1468
|
} else {
|
|
1528
1469
|
const candidates = listWorkspaceCandidates(basePath);
|
|
1529
|
-
const selectedWorkspaces = await
|
|
1470
|
+
const selectedWorkspaces = await p3.multiselect({
|
|
1530
1471
|
message: "\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uB97C \uC120\uD0DD\uD558\uC138\uC694",
|
|
1531
1472
|
options: candidates.map((candidate) => ({ value: candidate, label: candidate })),
|
|
1532
1473
|
required: true
|
|
1533
1474
|
});
|
|
1534
|
-
if (
|
|
1475
|
+
if (p3.isCancel(selectedWorkspaces)) {
|
|
1535
1476
|
cancelInit();
|
|
1536
1477
|
}
|
|
1537
1478
|
for (const workspace of selectedWorkspaces) {
|
|
@@ -1655,29 +1596,29 @@ var initCommand = async () => {
|
|
|
1655
1596
|
});
|
|
1656
1597
|
writeManifest(resolveManifestPath(basePath), manifest);
|
|
1657
1598
|
if (allAppended.length > 0) {
|
|
1658
|
-
|
|
1599
|
+
p3.log.info(`\uAE30\uC874 \uD30C\uC77C\uC5D0 \uC139\uC158 \uCD94\uAC00\uB428 (\uB0B4\uC6A9 \uBCF4\uC874):
|
|
1659
1600
|
${allAppended.map((file) => ` ${file}`).join("\n")}`);
|
|
1660
1601
|
}
|
|
1661
|
-
|
|
1662
|
-
|
|
1602
|
+
p3.log.success(`\uC124\uCE58\uB41C core rules: ${selectedRuleIds.length}\uAC1C`);
|
|
1603
|
+
p3.log.success(`\uC124\uCE58\uB41C skills: ${selectedSkillTargets.length}\uAC1C${skillScope ? ` (${skillScope})` : ""}`);
|
|
1663
1604
|
if (selectedSkillTargets.length > 0 && skillScope === "user") {
|
|
1664
|
-
|
|
1605
|
+
p3.log.info("global skill\uC740 ai-ops uninstall \uB300\uC0C1\uC774 \uC544\uB2D9\uB2C8\uB2E4. ai-ops skill uninstall\uC73C\uB85C \uC81C\uAC70\uD558\uC138\uC694.");
|
|
1665
1606
|
}
|
|
1666
|
-
|
|
1607
|
+
p3.outro("ai-ops init \uC644\uB8CC");
|
|
1667
1608
|
} finally {
|
|
1668
1609
|
process.off("SIGINT", handleSigint);
|
|
1669
1610
|
}
|
|
1670
1611
|
};
|
|
1671
1612
|
|
|
1672
1613
|
// src/commands/update.ts
|
|
1673
|
-
import * as
|
|
1614
|
+
import * as p4 from "@clack/prompts";
|
|
1674
1615
|
var updateCommand = async (opts) => {
|
|
1675
1616
|
const basePath = resolveBasePath();
|
|
1676
1617
|
const manifestPath = resolveManifestPath(basePath);
|
|
1677
|
-
|
|
1618
|
+
p4.intro("ai-ops update");
|
|
1678
1619
|
const manifest = readManifest(manifestPath);
|
|
1679
1620
|
if (!manifest) {
|
|
1680
|
-
|
|
1621
|
+
p4.log.error("manifest\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 ai-ops init\uC744 \uC2E4\uD589\uD558\uC138\uC694.");
|
|
1681
1622
|
process.exit(1);
|
|
1682
1623
|
}
|
|
1683
1624
|
const rulesDir = resolveRulesDir();
|
|
@@ -1704,11 +1645,11 @@ var updateCommand = async (opts) => {
|
|
|
1704
1645
|
currentCliVersion: cliVersion
|
|
1705
1646
|
});
|
|
1706
1647
|
if (diffResult.status === "up-to-date" && !opts.force) {
|
|
1707
|
-
|
|
1708
|
-
|
|
1648
|
+
p4.log.info("\uBCC0\uACBD \uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
1649
|
+
p4.outro("ai-ops update \uC644\uB8CC");
|
|
1709
1650
|
return;
|
|
1710
1651
|
}
|
|
1711
|
-
const s =
|
|
1652
|
+
const s = p4.spinner();
|
|
1712
1653
|
s.start("\uADDC\uCE59 \uAC31\uC2E0 \uC911...");
|
|
1713
1654
|
const meta = { sourceHash, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1714
1655
|
const allInstalledFiles = [];
|
|
@@ -1776,17 +1717,17 @@ var updateCommand = async (opts) => {
|
|
|
1776
1717
|
});
|
|
1777
1718
|
writeManifest(manifestPath, newManifest);
|
|
1778
1719
|
s.stop("\uADDC\uCE59 \uAC31\uC2E0 \uC644\uB8CC");
|
|
1779
|
-
|
|
1720
|
+
p4.outro("ai-ops update \uC644\uB8CC");
|
|
1780
1721
|
};
|
|
1781
1722
|
|
|
1782
1723
|
// src/commands/diff.ts
|
|
1783
|
-
import * as
|
|
1724
|
+
import * as p5 from "@clack/prompts";
|
|
1784
1725
|
var diffCommand = async () => {
|
|
1785
1726
|
const basePath = resolveBasePath();
|
|
1786
|
-
|
|
1727
|
+
p5.intro("ai-ops diff");
|
|
1787
1728
|
const manifest = readManifest(resolveManifestPath(basePath));
|
|
1788
1729
|
if (!manifest) {
|
|
1789
|
-
|
|
1730
|
+
p5.log.error("manifest\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 ai-ops init\uC744 \uC2E4\uD589\uD558\uC138\uC694.");
|
|
1790
1731
|
process.exit(1);
|
|
1791
1732
|
}
|
|
1792
1733
|
const sourceHash = computeSourceHash(resolveCompilerDataDir());
|
|
@@ -1819,31 +1760,31 @@ var diffCommand = async () => {
|
|
|
1819
1760
|
return `- ${skill.id}: ${changed ? "changed" : "up-to-date"} (${previousHash} -> ${next.sourceHash})`;
|
|
1820
1761
|
});
|
|
1821
1762
|
if (result.status === "up-to-date") {
|
|
1822
|
-
|
|
1763
|
+
p5.log.success("\uBCC0\uACBD \uC0AC\uD56D \uC5C6\uC74C. \uCD5C\uC2E0 \uC0C1\uD0DC\uC785\uB2C8\uB2E4.");
|
|
1823
1764
|
} else {
|
|
1824
1765
|
if (result.sourceChanged) {
|
|
1825
|
-
|
|
1766
|
+
p5.log.warn(`\uC18C\uC2A4 \uBCC0\uACBD \uAC10\uC9C0: ${manifest.sourceHash} \u2192 ${sourceHash}`);
|
|
1826
1767
|
}
|
|
1827
1768
|
if (result.added.length > 0) {
|
|
1828
|
-
|
|
1769
|
+
p5.log.info(`\uCD94\uAC00\uB41C \uADDC\uCE59: ${result.added.join(", ")}`);
|
|
1829
1770
|
}
|
|
1830
1771
|
if (result.removed.length > 0) {
|
|
1831
|
-
|
|
1772
|
+
p5.log.info(`\uC81C\uAC70\uB41C \uADDC\uCE59: ${result.removed.join(", ")}`);
|
|
1832
1773
|
}
|
|
1833
1774
|
}
|
|
1834
1775
|
if (skillLines.length > 0) {
|
|
1835
|
-
|
|
1776
|
+
p5.log.info(`project skills:
|
|
1836
1777
|
${skillLines.map((line) => ` ${line}`).join("\n")}`);
|
|
1837
1778
|
}
|
|
1838
|
-
|
|
1779
|
+
p5.outro("ai-ops diff \uC644\uB8CC");
|
|
1839
1780
|
};
|
|
1840
1781
|
|
|
1841
1782
|
// src/commands/uninstall.ts
|
|
1842
|
-
import * as
|
|
1843
|
-
import { rmSync as
|
|
1783
|
+
import * as p6 from "@clack/prompts";
|
|
1784
|
+
import { rmSync as rmSync5 } from "fs";
|
|
1844
1785
|
|
|
1845
1786
|
// src/lib/uninstall.ts
|
|
1846
|
-
import { existsSync as
|
|
1787
|
+
import { existsSync as existsSync7, readFileSync as readFileSync8, rmSync as rmSync4, readdirSync as readdirSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
1847
1788
|
import { resolve as resolve7, dirname as dirname7 } from "path";
|
|
1848
1789
|
var removeFiles = (basePath, relativePaths) => {
|
|
1849
1790
|
const deleted = [];
|
|
@@ -1852,22 +1793,22 @@ var removeFiles = (basePath, relativePaths) => {
|
|
|
1852
1793
|
const notFound = [];
|
|
1853
1794
|
for (const rel of relativePaths) {
|
|
1854
1795
|
const absPath = resolve7(basePath, rel);
|
|
1855
|
-
if (!
|
|
1796
|
+
if (!existsSync7(absPath)) {
|
|
1856
1797
|
notFound.push(rel);
|
|
1857
1798
|
continue;
|
|
1858
1799
|
}
|
|
1859
|
-
const content =
|
|
1800
|
+
const content = readFileSync8(absPath, "utf-8");
|
|
1860
1801
|
if (hasAiOpsSection(content)) {
|
|
1861
1802
|
const stripped = stripAiOpsSection(content);
|
|
1862
1803
|
if (stripped.trim().length === 0) {
|
|
1863
|
-
|
|
1804
|
+
rmSync4(absPath);
|
|
1864
1805
|
deleted.push(rel);
|
|
1865
1806
|
} else {
|
|
1866
|
-
|
|
1807
|
+
writeFileSync7(absPath, stripped, "utf-8");
|
|
1867
1808
|
cleaned.push(rel);
|
|
1868
1809
|
}
|
|
1869
1810
|
} else if (hasLegacyHeader(content)) {
|
|
1870
|
-
|
|
1811
|
+
rmSync4(absPath);
|
|
1871
1812
|
deleted.push(rel);
|
|
1872
1813
|
} else {
|
|
1873
1814
|
skipped.push(rel);
|
|
@@ -1879,11 +1820,11 @@ var cleanEmptyDirs = (basePath, dirs) => {
|
|
|
1879
1820
|
const removed = [];
|
|
1880
1821
|
for (const dir of dirs) {
|
|
1881
1822
|
const absDir = resolve7(basePath, dir);
|
|
1882
|
-
if (!
|
|
1823
|
+
if (!existsSync7(absDir)) continue;
|
|
1883
1824
|
try {
|
|
1884
1825
|
const entries = readdirSync4(absDir);
|
|
1885
1826
|
if (entries.length === 0) {
|
|
1886
|
-
|
|
1827
|
+
rmSync4(absDir, { recursive: true });
|
|
1887
1828
|
removed.push(dir);
|
|
1888
1829
|
}
|
|
1889
1830
|
} catch {
|
|
@@ -1907,10 +1848,10 @@ var SETTINGS_PATHS = /* @__PURE__ */ new Set([".claude/settings.local.json", ".g
|
|
|
1907
1848
|
var uninstallCommand = async () => {
|
|
1908
1849
|
const basePath = resolveBasePath();
|
|
1909
1850
|
const manifestPath = resolveManifestPath(basePath);
|
|
1910
|
-
|
|
1851
|
+
p6.intro("ai-ops uninstall");
|
|
1911
1852
|
const manifest = readManifest(manifestPath);
|
|
1912
1853
|
if (!manifest) {
|
|
1913
|
-
|
|
1854
|
+
p6.log.error("manifest\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uBA3C\uC800 ai-ops init\uC744 \uC2E4\uD589\uD558\uC138\uC694.");
|
|
1914
1855
|
process.exit(1);
|
|
1915
1856
|
}
|
|
1916
1857
|
const targetFiles = [
|
|
@@ -1919,31 +1860,34 @@ var uninstallCommand = async () => {
|
|
|
1919
1860
|
].filter((f) => !SETTINGS_PATHS.has(f));
|
|
1920
1861
|
const targetSkillDirs = (manifest.installed_skills ?? []).flatMap((skill) => skill.installed_paths);
|
|
1921
1862
|
if (targetFiles.length === 0 && targetSkillDirs.length === 0) {
|
|
1922
|
-
|
|
1923
|
-
|
|
1863
|
+
p6.log.warn("\uC0AD\uC81C\uD560 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
1864
|
+
p6.outro("ai-ops uninstall \uC644\uB8CC");
|
|
1924
1865
|
return;
|
|
1925
1866
|
}
|
|
1926
1867
|
if (targetFiles.length > 0) {
|
|
1927
|
-
|
|
1868
|
+
p6.log.info(`\uC0AD\uC81C \uB300\uC0C1 \uD30C\uC77C (${targetFiles.length}\uAC1C):
|
|
1928
1869
|
${targetFiles.map((f) => ` ${f}`).join("\n")}`);
|
|
1929
1870
|
}
|
|
1930
1871
|
if (targetSkillDirs.length > 0) {
|
|
1931
|
-
|
|
1932
|
-
${targetSkillDirs.
|
|
1872
|
+
p6.log.info(
|
|
1873
|
+
`\uC0AD\uC81C \uB300\uC0C1 skill \uB514\uB809\uD1A0\uB9AC (${targetSkillDirs.length}\uAC1C):
|
|
1874
|
+
${targetSkillDirs.map((f) => ` ${f}`).join("\n")}`
|
|
1875
|
+
);
|
|
1933
1876
|
}
|
|
1934
|
-
const confirmed = await
|
|
1877
|
+
const confirmed = await p6.confirm({
|
|
1935
1878
|
message: "\uC704 \uD30C\uC77C\uACFC manifest\uB97C \uBAA8\uB450 \uC0AD\uC81C\uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?",
|
|
1936
1879
|
initialValue: false
|
|
1937
1880
|
});
|
|
1938
|
-
if (
|
|
1939
|
-
|
|
1881
|
+
if (p6.isCancel(confirmed) || !confirmed) {
|
|
1882
|
+
p6.cancel("\uCDE8\uC18C\uB428");
|
|
1940
1883
|
process.exit(0);
|
|
1941
1884
|
}
|
|
1942
1885
|
const settingsMessages = [];
|
|
1943
1886
|
if (manifest.settings?.claude) {
|
|
1944
1887
|
const status = uninstallClaudeSettings(basePath, manifest.settings.claude);
|
|
1945
1888
|
if (status === "deleted") settingsMessages.push("\uC0AD\uC81C: .claude/settings.local.json");
|
|
1946
|
-
else if (status === "cleaned")
|
|
1889
|
+
else if (status === "cleaned")
|
|
1890
|
+
settingsMessages.push("ai-ops \uD0A4 \uC81C\uAC70 (\uC0AC\uC6A9\uC790 \uC124\uC815 \uBCF4\uC874): .claude/settings.local.json");
|
|
1947
1891
|
}
|
|
1948
1892
|
if (manifest.settings?.gemini) {
|
|
1949
1893
|
const status = uninstallGeminiSettings(basePath, manifest.settings.gemini);
|
|
@@ -1957,46 +1901,48 @@ ${targetSkillDirs.map((f) => ` ${f}`).join("\n")}`);
|
|
|
1957
1901
|
const removedSkillDirs = removeDirectories(basePath, targetSkillDirs);
|
|
1958
1902
|
const dirs = collectManagedDirs(targetFiles);
|
|
1959
1903
|
const removedDirs = cleanEmptyDirs(basePath, dirs);
|
|
1960
|
-
|
|
1904
|
+
rmSync5(manifestPath, { force: true });
|
|
1961
1905
|
if (result.deleted.length > 0) {
|
|
1962
|
-
|
|
1906
|
+
p6.log.success(`\uC0AD\uC81C \uC644\uB8CC (${result.deleted.length}\uAC1C):
|
|
1963
1907
|
${result.deleted.map((f) => ` ${f}`).join("\n")}`);
|
|
1964
1908
|
}
|
|
1965
1909
|
if (result.cleaned.length > 0) {
|
|
1966
|
-
|
|
1910
|
+
p6.log.success(
|
|
1967
1911
|
`\uC139\uC158 \uC81C\uAC70 \uC644\uB8CC (\uC0AC\uC6A9\uC790 \uB0B4\uC6A9 \uBCF4\uC874, ${result.cleaned.length}\uAC1C):
|
|
1968
1912
|
${result.cleaned.map((f) => ` ${f}`).join("\n")}`
|
|
1969
1913
|
);
|
|
1970
1914
|
}
|
|
1971
1915
|
if (result.skipped.length > 0) {
|
|
1972
|
-
|
|
1916
|
+
p6.log.warn(
|
|
1973
1917
|
`\uAC74\uB108\uB700 (non-managed \uD30C\uC77C \uBCF4\uD638, ${result.skipped.length}\uAC1C):
|
|
1974
1918
|
${result.skipped.map((f) => ` ${f}`).join("\n")}`
|
|
1975
1919
|
);
|
|
1976
1920
|
}
|
|
1977
1921
|
if (result.notFound.length > 0) {
|
|
1978
|
-
|
|
1922
|
+
p6.log.info(`\uC774\uBBF8 \uC5C6\uC74C (${result.notFound.length}\uAC1C):
|
|
1979
1923
|
${result.notFound.map((f) => ` ${f}`).join("\n")}`);
|
|
1980
1924
|
}
|
|
1981
1925
|
if (removedDirs.length > 0) {
|
|
1982
|
-
|
|
1926
|
+
p6.log.info(`\uBE48 \uB514\uB809\uD1A0\uB9AC \uC815\uB9AC (${removedDirs.length}\uAC1C):
|
|
1983
1927
|
${removedDirs.map((d) => ` ${d}`).join("\n")}`);
|
|
1984
1928
|
}
|
|
1985
1929
|
if (removedSkillDirs.length > 0) {
|
|
1986
|
-
|
|
1987
|
-
${removedSkillDirs.
|
|
1930
|
+
p6.log.success(
|
|
1931
|
+
`skill \uB514\uB809\uD1A0\uB9AC \uC0AD\uC81C (${removedSkillDirs.length}\uAC1C):
|
|
1932
|
+
${removedSkillDirs.map((d) => ` ${d}`).join("\n")}`
|
|
1933
|
+
);
|
|
1988
1934
|
}
|
|
1989
1935
|
if (settingsMessages.length > 0) {
|
|
1990
|
-
|
|
1936
|
+
p6.log.success(`\uC124\uC815 \uD30C\uC77C \uCC98\uB9AC:
|
|
1991
1937
|
${settingsMessages.map((m) => ` ${m}`).join("\n")}`);
|
|
1992
1938
|
}
|
|
1993
|
-
|
|
1994
|
-
|
|
1939
|
+
p6.log.success(`manifest \uC0AD\uC81C: ${MANIFEST_FILENAME}`);
|
|
1940
|
+
p6.outro("ai-ops uninstall \uC644\uB8CC");
|
|
1995
1941
|
};
|
|
1996
1942
|
|
|
1997
1943
|
// src/commands/skill.ts
|
|
1998
|
-
import * as
|
|
1999
|
-
import { rmSync as
|
|
1944
|
+
import * as p7 from "@clack/prompts";
|
|
1945
|
+
import { rmSync as rmSync6 } from "fs";
|
|
2000
1946
|
var resolveScopeContext = (opts) => {
|
|
2001
1947
|
const scope = resolveSkillScope(opts);
|
|
2002
1948
|
return {
|
|
@@ -2032,7 +1978,7 @@ var writeProjectSkillState = (params) => {
|
|
|
2032
1978
|
const nextTools = params.nextSkill !== void 0 ? [.../* @__PURE__ */ new Set([...previous?.tools ?? [], ...params.nextSkill.tools])] : previous?.tools ?? [];
|
|
2033
1979
|
const hasProjectState = (previous?.installed_rules.length ?? 0) > 0 || (previous?.installed_files?.length ?? 0) > 0 || (previous?.appended_files?.length ?? 0) > 0 || installedSkills.length > 0 || previous?.settings !== void 0;
|
|
2034
1980
|
if (!hasProjectState) {
|
|
2035
|
-
|
|
1981
|
+
rmSync6(manifestPath, { force: true });
|
|
2036
1982
|
return;
|
|
2037
1983
|
}
|
|
2038
1984
|
const manifest = buildManifest({
|
|
@@ -2055,7 +2001,7 @@ var writeUserSkillState = (params) => {
|
|
|
2055
2001
|
const previous = readSkillRegistry(registryPath);
|
|
2056
2002
|
const skills = params.removeSkillId ? removeInstalledSkill(previous?.skills ?? [], params.removeSkillId) : params.nextSkill ? upsertInstalledSkill(previous?.skills ?? [], params.nextSkill) : previous?.skills ?? [];
|
|
2057
2003
|
if (skills.length === 0) {
|
|
2058
|
-
|
|
2004
|
+
rmSync6(registryPath, { force: true });
|
|
2059
2005
|
return;
|
|
2060
2006
|
}
|
|
2061
2007
|
writeSkillRegistry(registryPath, {
|
|
@@ -2109,7 +2055,7 @@ var skillListCommand = async (opts) => {
|
|
|
2109
2055
|
const { scope, basePath } = resolveScopeContext(opts);
|
|
2110
2056
|
const { allSkills } = loadCompilerInputs();
|
|
2111
2057
|
const installedSkills = readInstalledSkills(scope, basePath);
|
|
2112
|
-
|
|
2058
|
+
p7.intro(`ai-ops skill list (${scope})`);
|
|
2113
2059
|
const sections = [
|
|
2114
2060
|
{ kind: "reference", title: "reference skills" },
|
|
2115
2061
|
{ kind: "task", title: "task skills" }
|
|
@@ -2125,8 +2071,8 @@ var skillListCommand = async (opts) => {
|
|
|
2125
2071
|
return `${title}
|
|
2126
2072
|
${lines.join("\n")}`;
|
|
2127
2073
|
}).filter((section) => section !== null);
|
|
2128
|
-
|
|
2129
|
-
|
|
2074
|
+
p7.log.info(sections.join("\n\n"));
|
|
2075
|
+
p7.outro("ai-ops skill list \uC644\uB8CC");
|
|
2130
2076
|
};
|
|
2131
2077
|
var skillInstallCommand = async (skillId, opts) => {
|
|
2132
2078
|
const { scope, basePath } = resolveScopeContext(opts);
|
|
@@ -2134,7 +2080,7 @@ var skillInstallCommand = async (skillId, opts) => {
|
|
|
2134
2080
|
const skill = resolveSkillById(allSkills, skillId);
|
|
2135
2081
|
assertScopeAllowed(skill, scope);
|
|
2136
2082
|
const requestedTools = resolveRequestedTools({ requested: opts.tool, supported: skill.supported_tools });
|
|
2137
|
-
|
|
2083
|
+
p7.intro(`ai-ops skill install ${skillId}`);
|
|
2138
2084
|
const installedSkill = installSkill({
|
|
2139
2085
|
skill,
|
|
2140
2086
|
requestedTools,
|
|
@@ -2143,18 +2089,18 @@ var skillInstallCommand = async (skillId, opts) => {
|
|
|
2143
2089
|
cliVersion,
|
|
2144
2090
|
sourceHash
|
|
2145
2091
|
});
|
|
2146
|
-
|
|
2147
|
-
|
|
2092
|
+
p7.log.success(`\uC124\uCE58 \uC644\uB8CC: ${installedSkill.id} (${installedSkill.installed_paths.join(", ")})`);
|
|
2093
|
+
p7.outro("ai-ops skill install \uC644\uB8CC");
|
|
2148
2094
|
};
|
|
2149
2095
|
var skillDiffCommand = async (skillId, opts) => {
|
|
2150
2096
|
const { scope, basePath } = resolveScopeContext(opts);
|
|
2151
2097
|
const { allSkills } = loadCompilerInputs();
|
|
2152
2098
|
const installedSkills = readInstalledSkills(scope, basePath);
|
|
2153
2099
|
const targets = skillId ? installedSkills.filter((skill) => skill.id === skillId) : installedSkills;
|
|
2154
|
-
|
|
2100
|
+
p7.intro(`ai-ops skill diff (${scope})`);
|
|
2155
2101
|
if (targets.length === 0) {
|
|
2156
|
-
|
|
2157
|
-
|
|
2102
|
+
p7.log.warn("\uBE44\uAD50\uD560 \uC124\uCE58\uB41C skill\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
2103
|
+
p7.outro("ai-ops skill diff \uC644\uB8CC");
|
|
2158
2104
|
return;
|
|
2159
2105
|
}
|
|
2160
2106
|
const lines = targets.map((installedSkill) => {
|
|
@@ -2167,18 +2113,18 @@ var skillDiffCommand = async (skillId, opts) => {
|
|
|
2167
2113
|
const changed = next.sourceHash !== installedSkill.sourceHash;
|
|
2168
2114
|
return `- ${installedSkill.id}: ${changed ? "changed" : "up-to-date"} (${installedSkill.sourceHash} -> ${next.sourceHash})`;
|
|
2169
2115
|
});
|
|
2170
|
-
|
|
2171
|
-
|
|
2116
|
+
p7.log.info(lines.join("\n"));
|
|
2117
|
+
p7.outro("ai-ops skill diff \uC644\uB8CC");
|
|
2172
2118
|
};
|
|
2173
2119
|
var skillUpdateCommand = async (skillId, opts) => {
|
|
2174
2120
|
const { scope, basePath } = resolveScopeContext(opts);
|
|
2175
2121
|
const { allSkills, sourceHash, cliVersion } = loadCompilerInputs();
|
|
2176
2122
|
const installedSkills = readInstalledSkills(scope, basePath);
|
|
2177
2123
|
const targets = skillId ? installedSkills.filter((skill) => skill.id === skillId) : installedSkills;
|
|
2178
|
-
|
|
2124
|
+
p7.intro(`ai-ops skill update (${scope})`);
|
|
2179
2125
|
if (targets.length === 0) {
|
|
2180
|
-
|
|
2181
|
-
|
|
2126
|
+
p7.log.warn("\uAC31\uC2E0\uD560 \uC124\uCE58\uB41C skill\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
2127
|
+
p7.outro("ai-ops skill update \uC644\uB8CC");
|
|
2182
2128
|
return;
|
|
2183
2129
|
}
|
|
2184
2130
|
const nextInstalledSkills = targets.map((installedSkill) => {
|
|
@@ -2195,7 +2141,7 @@ var skillUpdateCommand = async (skillId, opts) => {
|
|
|
2195
2141
|
const manifestPath = resolveManifestPath(basePath);
|
|
2196
2142
|
const previous = readManifest(manifestPath);
|
|
2197
2143
|
if (!previous) {
|
|
2198
|
-
|
|
2144
|
+
p7.log.error("project manifest\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
2199
2145
|
process.exit(1);
|
|
2200
2146
|
}
|
|
2201
2147
|
const untouched = (previous.installed_skills ?? []).filter(
|
|
@@ -2229,18 +2175,18 @@ var skillUpdateCommand = async (skillId, opts) => {
|
|
|
2229
2175
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2230
2176
|
});
|
|
2231
2177
|
}
|
|
2232
|
-
|
|
2233
|
-
|
|
2178
|
+
p7.log.success(`\uAC31\uC2E0 \uC644\uB8CC: ${nextInstalledSkills.map((skill) => skill.id).join(", ")}`);
|
|
2179
|
+
p7.outro("ai-ops skill update \uC644\uB8CC");
|
|
2234
2180
|
};
|
|
2235
2181
|
var skillUninstallCommand = async (skillId, opts) => {
|
|
2236
2182
|
const { scope, basePath } = resolveScopeContext(opts);
|
|
2237
2183
|
const { sourceHash, cliVersion } = loadCompilerInputs();
|
|
2238
2184
|
const installedSkills = readInstalledSkills(scope, basePath);
|
|
2239
2185
|
const installedSkill = findInstalledSkill(installedSkills, skillId);
|
|
2240
|
-
|
|
2186
|
+
p7.intro(`ai-ops skill uninstall ${skillId}`);
|
|
2241
2187
|
if (!installedSkill) {
|
|
2242
|
-
|
|
2243
|
-
|
|
2188
|
+
p7.log.warn("\uC124\uCE58\uB41C skill\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
2189
|
+
p7.outro("ai-ops skill uninstall \uC644\uB8CC");
|
|
2244
2190
|
return;
|
|
2245
2191
|
}
|
|
2246
2192
|
const removed = removeDirectories(basePath, installedSkill.installed_paths);
|
|
@@ -2258,8 +2204,8 @@ var skillUninstallCommand = async (skillId, opts) => {
|
|
|
2258
2204
|
removeSkillId: skillId
|
|
2259
2205
|
});
|
|
2260
2206
|
}
|
|
2261
|
-
|
|
2262
|
-
|
|
2207
|
+
p7.log.success(`\uC81C\uAC70 \uC644\uB8CC: ${removed.join(", ")}`);
|
|
2208
|
+
p7.outro("ai-ops skill uninstall \uC644\uB8CC");
|
|
2263
2209
|
};
|
|
2264
2210
|
|
|
2265
2211
|
// src/bin/index.ts
|