@anraktech/sync 0.11.0 → 0.12.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/cli.js +158 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1184,12 +1184,152 @@ function startAIAgent(ctx) {
|
|
|
1184
1184
|
console.log(row(`${chalk2.dim("Status")} ${statusLine}`));
|
|
1185
1185
|
}
|
|
1186
1186
|
console.log(empty);
|
|
1187
|
-
console.log(row(chalk2.dim("Type naturally
|
|
1188
|
-
console.log(row(chalk2.dim(
|
|
1187
|
+
console.log(row(chalk2.dim("Type naturally, or use / commands.")));
|
|
1188
|
+
console.log(row(chalk2.dim("Type /help to see all commands.")));
|
|
1189
1189
|
console.log(empty);
|
|
1190
1190
|
console.log(bot);
|
|
1191
1191
|
console.log("");
|
|
1192
1192
|
const PROMPT = `${chalk2.bold.blue("\u276F")} `;
|
|
1193
|
+
const slashCommands = {
|
|
1194
|
+
help: {
|
|
1195
|
+
description: "Show all commands",
|
|
1196
|
+
handler: () => {
|
|
1197
|
+
const W2 = Math.min(process.stdout.columns || 60, 60);
|
|
1198
|
+
console.log("");
|
|
1199
|
+
console.log(chalk2.bold(" Commands"));
|
|
1200
|
+
console.log(chalk2.dim(" " + "\u2500".repeat(W2 - 4)));
|
|
1201
|
+
for (const [cmd, { description }] of Object.entries(slashCommands)) {
|
|
1202
|
+
const label = chalk2.cyan(`/${cmd}`);
|
|
1203
|
+
const dots = chalk2.dim(".".repeat(Math.max(2, 18 - cmd.length)));
|
|
1204
|
+
console.log(` ${label} ${dots} ${chalk2.dim(description)}`);
|
|
1205
|
+
}
|
|
1206
|
+
console.log("");
|
|
1207
|
+
console.log(chalk2.dim(" Or just type naturally \u2014 the AI understands plain English."));
|
|
1208
|
+
}
|
|
1209
|
+
},
|
|
1210
|
+
cases: {
|
|
1211
|
+
description: "List your legal cases",
|
|
1212
|
+
handler: async () => {
|
|
1213
|
+
try {
|
|
1214
|
+
await ctx.refreshCases();
|
|
1215
|
+
const cases = ctx.getCases();
|
|
1216
|
+
if (cases.length === 0) {
|
|
1217
|
+
console.log(chalk2.dim(" No cases found."));
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
console.log("");
|
|
1221
|
+
console.log(chalk2.bold(` ${cases.length} case${cases.length !== 1 ? "s" : ""}`));
|
|
1222
|
+
console.log(chalk2.dim(" " + "\u2500".repeat(40)));
|
|
1223
|
+
for (const c of cases) {
|
|
1224
|
+
const docs = c.documents?.length ?? 0;
|
|
1225
|
+
console.log(` ${chalk2.cyan(c.caseNumber)} ${c.caseName} ${chalk2.dim(`${docs} docs`)}`);
|
|
1226
|
+
}
|
|
1227
|
+
} catch (err) {
|
|
1228
|
+
console.log(chalk2.red(` Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
},
|
|
1232
|
+
status: {
|
|
1233
|
+
description: "Show sync status",
|
|
1234
|
+
handler: () => {
|
|
1235
|
+
const s = getStats();
|
|
1236
|
+
const q = queueSize();
|
|
1237
|
+
console.log("");
|
|
1238
|
+
console.log(chalk2.bold(" Sync Status"));
|
|
1239
|
+
console.log(chalk2.dim(" " + "\u2500".repeat(30)));
|
|
1240
|
+
console.log(` ${chalk2.dim("Files tracked")} ${s.totalFiles}`);
|
|
1241
|
+
console.log(` ${chalk2.dim("Synced")} ${chalk2.green(s.synced)}`);
|
|
1242
|
+
console.log(` ${chalk2.dim("Pending")} ${chalk2.yellow(s.pending)}`);
|
|
1243
|
+
console.log(` ${chalk2.dim("Errors")} ${s.errors > 0 ? chalk2.red(s.errors) : s.errors}`);
|
|
1244
|
+
console.log(` ${chalk2.dim("Queue")} ${q}`);
|
|
1245
|
+
console.log(` ${chalk2.dim("Mapped folders")} ${s.mappedFolders}`);
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
folder: {
|
|
1249
|
+
description: "Show watch folder path",
|
|
1250
|
+
handler: () => {
|
|
1251
|
+
console.log(` ${chalk2.dim("Watch folder")} ${ctx.config.watchFolder}`);
|
|
1252
|
+
console.log(` ${chalk2.dim("Config dir")} ${getConfigDir()}`);
|
|
1253
|
+
}
|
|
1254
|
+
},
|
|
1255
|
+
mappings: {
|
|
1256
|
+
description: "Show folder \u2192 case mappings",
|
|
1257
|
+
handler: () => {
|
|
1258
|
+
const mappings = getAllMappings();
|
|
1259
|
+
const entries = Object.entries(mappings);
|
|
1260
|
+
if (entries.length === 0) {
|
|
1261
|
+
console.log(chalk2.dim(" No mappings yet. Sync a folder to create one."));
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
console.log("");
|
|
1265
|
+
console.log(chalk2.bold(` ${entries.length} mapping${entries.length !== 1 ? "s" : ""}`));
|
|
1266
|
+
console.log(chalk2.dim(" " + "\u2500".repeat(40)));
|
|
1267
|
+
for (const [folder, m] of entries) {
|
|
1268
|
+
console.log(` ${chalk2.cyan(folder)} \u2192 ${m.caseNumber} ${chalk2.dim(`(${m.caseName})`)}`);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
},
|
|
1272
|
+
login: {
|
|
1273
|
+
description: "Re-authenticate with AnrakLegal",
|
|
1274
|
+
handler: async () => {
|
|
1275
|
+
try {
|
|
1276
|
+
log.info("Opening browser for login...");
|
|
1277
|
+
const tokens = await browserLogin(ctx.config.apiUrl);
|
|
1278
|
+
ctx.config.accessToken = tokens.accessToken;
|
|
1279
|
+
ctx.config.refreshToken = tokens.refreshToken;
|
|
1280
|
+
saveConfig(ctx.config);
|
|
1281
|
+
log.success("Logged in successfully");
|
|
1282
|
+
} catch (err) {
|
|
1283
|
+
console.log(chalk2.red(` Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
logout: {
|
|
1288
|
+
description: "Clear stored credentials",
|
|
1289
|
+
handler: () => {
|
|
1290
|
+
ctx.config.accessToken = "";
|
|
1291
|
+
ctx.config.refreshToken = "";
|
|
1292
|
+
saveConfig(ctx.config);
|
|
1293
|
+
log.success("Logged out. Run /login to re-authenticate.");
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
1296
|
+
sync: {
|
|
1297
|
+
description: "Re-scan watch folder and sync",
|
|
1298
|
+
handler: async () => {
|
|
1299
|
+
try {
|
|
1300
|
+
await ctx.triggerScan();
|
|
1301
|
+
const s = getStats();
|
|
1302
|
+
if (s.pending === 0) {
|
|
1303
|
+
log.success("Everything up to date");
|
|
1304
|
+
} else {
|
|
1305
|
+
log.info(`${s.pending} file${s.pending !== 1 ? "s" : ""} pending sync`);
|
|
1306
|
+
}
|
|
1307
|
+
} catch (err) {
|
|
1308
|
+
console.log(chalk2.red(` Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1312
|
+
clear: {
|
|
1313
|
+
description: "Clear conversation history",
|
|
1314
|
+
handler: () => {
|
|
1315
|
+
history.length = 1;
|
|
1316
|
+
console.log(chalk2.dim(" Conversation cleared."));
|
|
1317
|
+
}
|
|
1318
|
+
},
|
|
1319
|
+
reset: {
|
|
1320
|
+
description: "Clear sync cache (re-uploads on next sync)",
|
|
1321
|
+
handler: () => {
|
|
1322
|
+
resetCache();
|
|
1323
|
+
log.success("Cache cleared. Run /sync to re-sync.");
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1326
|
+
quit: {
|
|
1327
|
+
description: "Exit AnrakLegal Sync",
|
|
1328
|
+
handler: () => {
|
|
1329
|
+
process.emit("SIGINT");
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1193
1333
|
async function promptLoop() {
|
|
1194
1334
|
while (true) {
|
|
1195
1335
|
let input;
|
|
@@ -1200,15 +1340,26 @@ function startAIAgent(ctx) {
|
|
|
1200
1340
|
}
|
|
1201
1341
|
const trimmed = input.trim();
|
|
1202
1342
|
if (!trimmed) continue;
|
|
1343
|
+
if (trimmed.startsWith("/")) {
|
|
1344
|
+
const cmd = trimmed.slice(1).toLowerCase().split(/\s+/)[0];
|
|
1345
|
+
if (slashCommands[cmd]) {
|
|
1346
|
+
await slashCommands[cmd].handler();
|
|
1347
|
+
console.log("");
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
const matches = Object.keys(slashCommands).filter((k) => k.startsWith(cmd));
|
|
1351
|
+
if (matches.length > 0) {
|
|
1352
|
+
console.log(chalk2.dim(` Did you mean: ${matches.map((m) => chalk2.cyan(`/${m}`)).join(", ")}?`));
|
|
1353
|
+
} else {
|
|
1354
|
+
console.log(chalk2.dim(` Unknown command. Type ${chalk2.cyan("/help")} for available commands.`));
|
|
1355
|
+
}
|
|
1356
|
+
console.log("");
|
|
1357
|
+
continue;
|
|
1358
|
+
}
|
|
1203
1359
|
if (/^(quit|exit|q)$/i.test(trimmed)) {
|
|
1204
1360
|
process.emit("SIGINT");
|
|
1205
1361
|
return;
|
|
1206
1362
|
}
|
|
1207
|
-
if (/^(clear|reset|new)$/i.test(trimmed)) {
|
|
1208
|
-
history.length = 1;
|
|
1209
|
-
console.log(chalk2.dim(" Conversation cleared.\n"));
|
|
1210
|
-
continue;
|
|
1211
|
-
}
|
|
1212
1363
|
history.push({ role: "user", content: trimmed });
|
|
1213
1364
|
while (history.length > 21) {
|
|
1214
1365
|
history.splice(1, 1);
|