@backcap/cli 0.1.5 → 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.
- package/dist/index.cjs +66 -26
- package/dist/index.mjs +66 -26
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -246,28 +246,54 @@ const init = citty.defineCommand({
|
|
|
246
246
|
name: "init",
|
|
247
247
|
description: "Initialize a Backcap project in the current directory"
|
|
248
248
|
},
|
|
249
|
-
|
|
249
|
+
args: {
|
|
250
|
+
yes: {
|
|
251
|
+
type: "boolean",
|
|
252
|
+
alias: "y",
|
|
253
|
+
default: false,
|
|
254
|
+
description: "Skip all prompts (non-interactive mode)"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
async run({ args }) {
|
|
250
258
|
const cwd = process.cwd();
|
|
251
259
|
intro();
|
|
252
260
|
const frameworkResult = await detectFramework(cwd);
|
|
253
|
-
let framework
|
|
261
|
+
let framework;
|
|
262
|
+
if (frameworkResult.isOk()) {
|
|
263
|
+
framework = frameworkResult.unwrap();
|
|
264
|
+
} else if (args.yes) {
|
|
265
|
+
fail("Cannot detect framework. Run without --yes or create backcap.json manually.");
|
|
266
|
+
return;
|
|
267
|
+
} else {
|
|
268
|
+
framework = await promptFramework();
|
|
269
|
+
}
|
|
254
270
|
if (frameworkResult.isOk()) {
|
|
255
271
|
log.info(`Detected framework: ${framework}`);
|
|
256
272
|
}
|
|
257
273
|
const pmResult = await detectPackageManager(cwd);
|
|
258
|
-
let pm
|
|
274
|
+
let pm;
|
|
275
|
+
if (pmResult.isOk()) {
|
|
276
|
+
pm = pmResult.unwrap();
|
|
277
|
+
} else if (args.yes) {
|
|
278
|
+
fail("Cannot detect package manager. Run without --yes or create backcap.json manually.");
|
|
279
|
+
return;
|
|
280
|
+
} else {
|
|
281
|
+
pm = await promptPackageManager();
|
|
282
|
+
}
|
|
259
283
|
if (pmResult.isOk()) {
|
|
260
284
|
log.info(`Detected package manager: ${pm}`);
|
|
261
285
|
}
|
|
262
286
|
if (await configExists(cwd)) {
|
|
263
287
|
const existingResult = await loadConfig(cwd);
|
|
264
288
|
if (existingResult.isOk()) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
289
|
+
if (!args.yes) {
|
|
290
|
+
const shouldOverwrite = await promptOverwriteConfirm(
|
|
291
|
+
existingResult.unwrap()
|
|
292
|
+
);
|
|
293
|
+
if (!shouldOverwrite) {
|
|
294
|
+
outro("Kept existing backcap.json unchanged.");
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
271
297
|
}
|
|
272
298
|
}
|
|
273
299
|
}
|
|
@@ -968,6 +994,12 @@ const add = citty.defineCommand({
|
|
|
968
994
|
type: "positional",
|
|
969
995
|
required: true,
|
|
970
996
|
description: "Capability or bridge name to install"
|
|
997
|
+
},
|
|
998
|
+
yes: {
|
|
999
|
+
type: "boolean",
|
|
1000
|
+
alias: "y",
|
|
1001
|
+
default: false,
|
|
1002
|
+
description: "Skip all prompts (non-interactive mode)"
|
|
971
1003
|
}
|
|
972
1004
|
},
|
|
973
1005
|
async run({ args }) {
|
|
@@ -1011,7 +1043,7 @@ const add = citty.defineCommand({
|
|
|
1011
1043
|
const itemVersion = item.version;
|
|
1012
1044
|
const itemType = item.type;
|
|
1013
1045
|
if (itemType === "bridge" || fetchedFromBridges) {
|
|
1014
|
-
await installBridge(cwd, config, item, itemVersion);
|
|
1046
|
+
await installBridge(cwd, config, item, itemVersion, args.yes);
|
|
1015
1047
|
return;
|
|
1016
1048
|
}
|
|
1017
1049
|
const capabilityName = itemName;
|
|
@@ -1019,10 +1051,14 @@ const add = citty.defineCommand({
|
|
|
1019
1051
|
const availableAdapters = await detectAdapters(cwd, capabilityName);
|
|
1020
1052
|
let selectedAdapters = [];
|
|
1021
1053
|
if (availableAdapters.length > 0) {
|
|
1022
|
-
|
|
1023
|
-
availableAdapters.
|
|
1024
|
-
|
|
1025
|
-
|
|
1054
|
+
if (args.yes) {
|
|
1055
|
+
selectedAdapters = availableAdapters.filter((a) => a.detected).map((a) => a.name);
|
|
1056
|
+
} else {
|
|
1057
|
+
selectedAdapters = await promptAdapterSelection(
|
|
1058
|
+
availableAdapters.map((a) => ({ name: a.name, category: a.category })),
|
|
1059
|
+
availableAdapters.filter((a) => a.detected).map((a) => a.name)
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1026
1062
|
}
|
|
1027
1063
|
const files = item.files;
|
|
1028
1064
|
const filesToWrite = files.filter((f) => typeof f.content === "string");
|
|
@@ -1061,7 +1097,7 @@ ${err.suggestion}`);
|
|
|
1061
1097
|
break;
|
|
1062
1098
|
}
|
|
1063
1099
|
renderConflictSummary(report);
|
|
1064
|
-
const action = await promptConflictResolution();
|
|
1100
|
+
const action = args.yes ? "compare_and_continue" : await promptConflictResolution();
|
|
1065
1101
|
if (action === "abort") {
|
|
1066
1102
|
outro("Installation cancelled. No files were written.");
|
|
1067
1103
|
return;
|
|
@@ -1105,10 +1141,12 @@ ${err.suggestion}`);
|
|
|
1105
1141
|
resolved = true;
|
|
1106
1142
|
}
|
|
1107
1143
|
if (!useSelectiveInstall) {
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1144
|
+
if (!args.yes) {
|
|
1145
|
+
const confirmed = await promptInstallConfirm(capabilityName);
|
|
1146
|
+
if (!confirmed) {
|
|
1147
|
+
outro("Installation cancelled.");
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1112
1150
|
}
|
|
1113
1151
|
await writeCapabilityFiles(filesToWrite, { capabilityRoot: capRoot, markers });
|
|
1114
1152
|
log.success(`Capability files written to ${capRoot}`);
|
|
@@ -1163,7 +1201,7 @@ ${err.suggestion}`);
|
|
|
1163
1201
|
skillFiles: capSkillFiles,
|
|
1164
1202
|
coreSkillFiles,
|
|
1165
1203
|
templateValues: markers,
|
|
1166
|
-
onConflict: promptSkillConflict
|
|
1204
|
+
onConflict: args.yes ? async () => "overwrite" : promptSkillConflict
|
|
1167
1205
|
});
|
|
1168
1206
|
log.success(`Skill installed to ${skillsPath}/backcap-${capabilityName}/`);
|
|
1169
1207
|
}
|
|
@@ -1196,7 +1234,7 @@ ${err.suggestion}`);
|
|
|
1196
1234
|
}
|
|
1197
1235
|
}
|
|
1198
1236
|
});
|
|
1199
|
-
async function installBridge(cwd, config, item, itemVersion) {
|
|
1237
|
+
async function installBridge(cwd, config, item, itemVersion, yes = false) {
|
|
1200
1238
|
const bridgeName = item.name;
|
|
1201
1239
|
const version = itemVersion ?? "0.1.0";
|
|
1202
1240
|
const installedBridgeNames = new Set(config.installed.bridges.map((b) => b.name));
|
|
@@ -1238,7 +1276,7 @@ ${err.suggestion}`);
|
|
|
1238
1276
|
}
|
|
1239
1277
|
if (report.hasConflicts) {
|
|
1240
1278
|
renderConflictSummary(report);
|
|
1241
|
-
const action = await promptConflictResolution();
|
|
1279
|
+
const action = yes ? "compare_and_continue" : await promptConflictResolution();
|
|
1242
1280
|
if (action === "abort") {
|
|
1243
1281
|
outro("Installation cancelled. No files were written.");
|
|
1244
1282
|
return;
|
|
@@ -1259,10 +1297,12 @@ ${err.suggestion}`);
|
|
|
1259
1297
|
}
|
|
1260
1298
|
throw err;
|
|
1261
1299
|
}
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1300
|
+
if (!yes) {
|
|
1301
|
+
const confirmed = await promptInstallConfirm(bridgeName);
|
|
1302
|
+
if (!confirmed) {
|
|
1303
|
+
outro("Installation cancelled.");
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1266
1306
|
}
|
|
1267
1307
|
await writeCapabilityFiles(filesToWrite, { capabilityRoot: bridgeRoot, markers });
|
|
1268
1308
|
log.success(`Bridge files written to ${bridgeRoot}`);
|
package/dist/index.mjs
CHANGED
|
@@ -229,28 +229,54 @@ const init = defineCommand({
|
|
|
229
229
|
name: "init",
|
|
230
230
|
description: "Initialize a Backcap project in the current directory"
|
|
231
231
|
},
|
|
232
|
-
|
|
232
|
+
args: {
|
|
233
|
+
yes: {
|
|
234
|
+
type: "boolean",
|
|
235
|
+
alias: "y",
|
|
236
|
+
default: false,
|
|
237
|
+
description: "Skip all prompts (non-interactive mode)"
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
async run({ args }) {
|
|
233
241
|
const cwd = process.cwd();
|
|
234
242
|
intro();
|
|
235
243
|
const frameworkResult = await detectFramework(cwd);
|
|
236
|
-
let framework
|
|
244
|
+
let framework;
|
|
245
|
+
if (frameworkResult.isOk()) {
|
|
246
|
+
framework = frameworkResult.unwrap();
|
|
247
|
+
} else if (args.yes) {
|
|
248
|
+
fail("Cannot detect framework. Run without --yes or create backcap.json manually.");
|
|
249
|
+
return;
|
|
250
|
+
} else {
|
|
251
|
+
framework = await promptFramework();
|
|
252
|
+
}
|
|
237
253
|
if (frameworkResult.isOk()) {
|
|
238
254
|
log.info(`Detected framework: ${framework}`);
|
|
239
255
|
}
|
|
240
256
|
const pmResult = await detectPackageManager(cwd);
|
|
241
|
-
let pm
|
|
257
|
+
let pm;
|
|
258
|
+
if (pmResult.isOk()) {
|
|
259
|
+
pm = pmResult.unwrap();
|
|
260
|
+
} else if (args.yes) {
|
|
261
|
+
fail("Cannot detect package manager. Run without --yes or create backcap.json manually.");
|
|
262
|
+
return;
|
|
263
|
+
} else {
|
|
264
|
+
pm = await promptPackageManager();
|
|
265
|
+
}
|
|
242
266
|
if (pmResult.isOk()) {
|
|
243
267
|
log.info(`Detected package manager: ${pm}`);
|
|
244
268
|
}
|
|
245
269
|
if (await configExists(cwd)) {
|
|
246
270
|
const existingResult = await loadConfig(cwd);
|
|
247
271
|
if (existingResult.isOk()) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
272
|
+
if (!args.yes) {
|
|
273
|
+
const shouldOverwrite = await promptOverwriteConfirm(
|
|
274
|
+
existingResult.unwrap()
|
|
275
|
+
);
|
|
276
|
+
if (!shouldOverwrite) {
|
|
277
|
+
outro("Kept existing backcap.json unchanged.");
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
254
280
|
}
|
|
255
281
|
}
|
|
256
282
|
}
|
|
@@ -951,6 +977,12 @@ const add = defineCommand({
|
|
|
951
977
|
type: "positional",
|
|
952
978
|
required: true,
|
|
953
979
|
description: "Capability or bridge name to install"
|
|
980
|
+
},
|
|
981
|
+
yes: {
|
|
982
|
+
type: "boolean",
|
|
983
|
+
alias: "y",
|
|
984
|
+
default: false,
|
|
985
|
+
description: "Skip all prompts (non-interactive mode)"
|
|
954
986
|
}
|
|
955
987
|
},
|
|
956
988
|
async run({ args }) {
|
|
@@ -994,7 +1026,7 @@ const add = defineCommand({
|
|
|
994
1026
|
const itemVersion = item.version;
|
|
995
1027
|
const itemType = item.type;
|
|
996
1028
|
if (itemType === "bridge" || fetchedFromBridges) {
|
|
997
|
-
await installBridge(cwd, config, item, itemVersion);
|
|
1029
|
+
await installBridge(cwd, config, item, itemVersion, args.yes);
|
|
998
1030
|
return;
|
|
999
1031
|
}
|
|
1000
1032
|
const capabilityName = itemName;
|
|
@@ -1002,10 +1034,14 @@ const add = defineCommand({
|
|
|
1002
1034
|
const availableAdapters = await detectAdapters(cwd, capabilityName);
|
|
1003
1035
|
let selectedAdapters = [];
|
|
1004
1036
|
if (availableAdapters.length > 0) {
|
|
1005
|
-
|
|
1006
|
-
availableAdapters.
|
|
1007
|
-
|
|
1008
|
-
|
|
1037
|
+
if (args.yes) {
|
|
1038
|
+
selectedAdapters = availableAdapters.filter((a) => a.detected).map((a) => a.name);
|
|
1039
|
+
} else {
|
|
1040
|
+
selectedAdapters = await promptAdapterSelection(
|
|
1041
|
+
availableAdapters.map((a) => ({ name: a.name, category: a.category })),
|
|
1042
|
+
availableAdapters.filter((a) => a.detected).map((a) => a.name)
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1009
1045
|
}
|
|
1010
1046
|
const files = item.files;
|
|
1011
1047
|
const filesToWrite = files.filter((f) => typeof f.content === "string");
|
|
@@ -1044,7 +1080,7 @@ ${err.suggestion}`);
|
|
|
1044
1080
|
break;
|
|
1045
1081
|
}
|
|
1046
1082
|
renderConflictSummary(report);
|
|
1047
|
-
const action = await promptConflictResolution();
|
|
1083
|
+
const action = args.yes ? "compare_and_continue" : await promptConflictResolution();
|
|
1048
1084
|
if (action === "abort") {
|
|
1049
1085
|
outro("Installation cancelled. No files were written.");
|
|
1050
1086
|
return;
|
|
@@ -1088,10 +1124,12 @@ ${err.suggestion}`);
|
|
|
1088
1124
|
resolved = true;
|
|
1089
1125
|
}
|
|
1090
1126
|
if (!useSelectiveInstall) {
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1127
|
+
if (!args.yes) {
|
|
1128
|
+
const confirmed = await promptInstallConfirm(capabilityName);
|
|
1129
|
+
if (!confirmed) {
|
|
1130
|
+
outro("Installation cancelled.");
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1095
1133
|
}
|
|
1096
1134
|
await writeCapabilityFiles(filesToWrite, { capabilityRoot: capRoot, markers });
|
|
1097
1135
|
log.success(`Capability files written to ${capRoot}`);
|
|
@@ -1146,7 +1184,7 @@ ${err.suggestion}`);
|
|
|
1146
1184
|
skillFiles: capSkillFiles,
|
|
1147
1185
|
coreSkillFiles,
|
|
1148
1186
|
templateValues: markers,
|
|
1149
|
-
onConflict: promptSkillConflict
|
|
1187
|
+
onConflict: args.yes ? async () => "overwrite" : promptSkillConflict
|
|
1150
1188
|
});
|
|
1151
1189
|
log.success(`Skill installed to ${skillsPath}/backcap-${capabilityName}/`);
|
|
1152
1190
|
}
|
|
@@ -1179,7 +1217,7 @@ ${err.suggestion}`);
|
|
|
1179
1217
|
}
|
|
1180
1218
|
}
|
|
1181
1219
|
});
|
|
1182
|
-
async function installBridge(cwd, config, item, itemVersion) {
|
|
1220
|
+
async function installBridge(cwd, config, item, itemVersion, yes = false) {
|
|
1183
1221
|
const bridgeName = item.name;
|
|
1184
1222
|
const version = itemVersion ?? "0.1.0";
|
|
1185
1223
|
const installedBridgeNames = new Set(config.installed.bridges.map((b) => b.name));
|
|
@@ -1221,7 +1259,7 @@ ${err.suggestion}`);
|
|
|
1221
1259
|
}
|
|
1222
1260
|
if (report.hasConflicts) {
|
|
1223
1261
|
renderConflictSummary(report);
|
|
1224
|
-
const action = await promptConflictResolution();
|
|
1262
|
+
const action = yes ? "compare_and_continue" : await promptConflictResolution();
|
|
1225
1263
|
if (action === "abort") {
|
|
1226
1264
|
outro("Installation cancelled. No files were written.");
|
|
1227
1265
|
return;
|
|
@@ -1242,10 +1280,12 @@ ${err.suggestion}`);
|
|
|
1242
1280
|
}
|
|
1243
1281
|
throw err;
|
|
1244
1282
|
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1283
|
+
if (!yes) {
|
|
1284
|
+
const confirmed = await promptInstallConfirm(bridgeName);
|
|
1285
|
+
if (!confirmed) {
|
|
1286
|
+
outro("Installation cancelled.");
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1249
1289
|
}
|
|
1250
1290
|
await writeCapabilityFiles(filesToWrite, { capabilityRoot: bridgeRoot, markers });
|
|
1251
1291
|
log.success(`Bridge files written to ${bridgeRoot}`);
|