@iola_adm/iola-cli 0.1.86 → 0.1.88

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iola_adm/iola-cli",
3
- "version": "0.1.86",
3
+ "version": "0.1.88",
4
4
  "description": "CLI и AI-агент городского округа Йошкар-Ола.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/adm-iola/iola-cli#readme",
package/src/cli.js CHANGED
@@ -298,6 +298,8 @@ const SLASH_COMMANDS = [
298
298
  { command: "/quality", description: "качество данных" },
299
299
  { command: "/views", description: "saved views" },
300
300
  { command: "/config get", description: "конфигурация" },
301
+ { command: "/delete --yes", description: "удалить локальные данные iola-cli" },
302
+ { command: "/uninstall --yes", description: "алиас для /delete --yes" },
301
303
  { command: "/layers", description: "слои данных" },
302
304
  { command: "/data schools --limit 10", description: "данные слоя" },
303
305
  { command: "/schools --limit 10", description: "школы" },
@@ -389,6 +391,9 @@ const COMMANDS = new Map([
389
391
  ["alias", handleAlias],
390
392
  ["run", runNaturalLanguage],
391
393
  ["config", handleConfig],
394
+ ["uninstall", handleUninstall],
395
+ ["purge", handleUninstall],
396
+ ["delete", handleUninstall],
392
397
  ["banner", showBanner],
393
398
  ["agent", startAgent],
394
399
  ["chat", startAgent],
@@ -576,6 +581,8 @@ Usage:
576
581
  iola config set api.baseUrl URL
577
582
  iola config set api.mcpBaseUrl URL
578
583
  iola config reset
584
+ iola delete --yes
585
+ iola uninstall --yes
579
586
  iola update
580
587
  iola ask TEXT [--profile NAME] [--model MODEL] [--tools] [--files] [--plan] [--trace] [--reasoning fast|verify|vote] [--output FILE] [--schema json|table] [--events] [--no-history] [--bare] [--quiet] [--no-color] [--fail-on-empty]
581
588
  iola data LAYER [--limit 10] [--search TEXT] [--where FIELD=VALUE] [--columns a,b,c] [--format table|json|csv]
@@ -1256,6 +1263,9 @@ async function handleAgentLine(line, state) {
1256
1263
  sync: ["sync", args],
1257
1264
  diff: ["diff", args],
1258
1265
  config: ["config", args],
1266
+ delete: ["delete", args],
1267
+ uninstall: ["uninstall", args],
1268
+ purge: ["purge", args],
1259
1269
  layers: ["layers", args],
1260
1270
  data: ["data", args],
1261
1271
  schools: ["schools", args],
@@ -2116,6 +2126,79 @@ async function handleConfig(args) {
2116
2126
  throw new Error("Команды config: get, set, validate, schema, reset.");
2117
2127
  }
2118
2128
 
2129
+ async function handleUninstall(args = []) {
2130
+ const options = parseOptions(args);
2131
+ const targets = [
2132
+ {
2133
+ label: "user data",
2134
+ path: CONFIG_DIR,
2135
+ description: "config, secrets, SQLite-БД, модель IOLA, Python/browser runtime, cache, history",
2136
+ },
2137
+ ];
2138
+
2139
+ if (options.project) {
2140
+ targets.push({
2141
+ label: "project data",
2142
+ path: PROJECT_IOLA_DIR,
2143
+ description: "локальная папка .iola текущего проекта",
2144
+ });
2145
+ }
2146
+
2147
+ const safeTargets = targets.map((target) => ({
2148
+ ...target,
2149
+ path: path.resolve(target.path),
2150
+ }));
2151
+ const home = path.resolve(os.homedir());
2152
+ for (const target of safeTargets) {
2153
+ const isUserConfig = target.path === path.resolve(CONFIG_DIR) && target.path.startsWith(home);
2154
+ const isProjectConfig = target.path === path.resolve(PROJECT_IOLA_DIR) && target.path.startsWith(path.resolve(process.cwd()));
2155
+ if (!isUserConfig && !isProjectConfig) {
2156
+ throw new Error(`Небезопасный путь удаления: ${target.path}`);
2157
+ }
2158
+ }
2159
+
2160
+ if (options["dry-run"] || options.json) {
2161
+ const payload = {
2162
+ willDelete: safeTargets.map((target) => ({
2163
+ label: target.label,
2164
+ path: target.path,
2165
+ exists: existsSync(target.path),
2166
+ description: target.description,
2167
+ })),
2168
+ willKeep: ["Codex CLI", "Codex auth/config", "npm package files"],
2169
+ reinstall: "npm install -g @iola_adm/iola-cli@latest",
2170
+ };
2171
+ if (options.json) printJson(payload);
2172
+ else printKeyValue(Object.fromEntries(payload.willDelete.map((item) => [item.label, `${item.path} (${item.exists ? "exists" : "missing"})`])));
2173
+ return;
2174
+ }
2175
+
2176
+ if (!options.yes) {
2177
+ console.log("Будет удалено:");
2178
+ for (const target of safeTargets) {
2179
+ console.log(`- ${target.path}`);
2180
+ console.log(` ${target.description}`);
2181
+ }
2182
+ console.log("");
2183
+ console.log("Codex CLI и его настройки не удаляются.");
2184
+ const confirmed = await confirm("Удалить локальные данные iola-cli? [y/N] ");
2185
+ if (!confirmed) {
2186
+ console.log("Удаление отменено.");
2187
+ return;
2188
+ }
2189
+ }
2190
+
2191
+ for (const target of safeTargets) {
2192
+ await rm(target.path, { recursive: true, force: true });
2193
+ }
2194
+
2195
+ console.log("Локальные данные iola-cli удалены.");
2196
+ console.log("Codex CLI не тронут.");
2197
+ console.log("Для полной переустановки npm-пакета:");
2198
+ console.log(" npm uninstall -g @iola_adm/iola-cli");
2199
+ console.log(" npm install -g @iola_adm/iola-cli@latest");
2200
+ }
2201
+
2119
2202
  async function handleDb(args) {
2120
2203
  const [action = "status"] = args;
2121
2204
  const options = parseOptions(args);
@@ -7764,7 +7847,7 @@ function parseOptions(args) {
7764
7847
 
7765
7848
  for (let index = 0; index < args.length; index += 1) {
7766
7849
  const arg = args[index];
7767
- if (arg === "--json" || arg === "--yes" || arg === "--silent" || arg === "--events" || arg === "--stream-json" || arg === "--stdio" || arg === "--system" || arg === "--headed" || arg === "--headless" || arg === "--no-history" || arg === "--summary" || arg === "--all" || arg === "--full" || arg === "--unread" || arg === "--once" || arg === "--local" || arg === "--cache" || arg === "--tools" || arg === "--files" || arg === "--plan" || arg === "--trace" || arg === "--diff" || arg === "--stage" || arg === "--fts" || arg === "--bare" || arg === "--quiet" || arg === "--optional" || arg === "--no-color" || arg === "--fail-on-empty" || arg === "--debug" || arg === "--fix" || arg === "--append") {
7850
+ if (arg === "--json" || arg === "--yes" || arg === "--silent" || arg === "--events" || arg === "--stream-json" || arg === "--stdio" || arg === "--system" || arg === "--headed" || arg === "--headless" || arg === "--no-history" || arg === "--summary" || arg === "--all" || arg === "--full" || arg === "--unread" || arg === "--once" || arg === "--local" || arg === "--cache" || arg === "--tools" || arg === "--files" || arg === "--plan" || arg === "--trace" || arg === "--diff" || arg === "--stage" || arg === "--fts" || arg === "--bare" || arg === "--quiet" || arg === "--optional" || arg === "--project" || arg === "--dry-run" || arg === "--no-color" || arg === "--fail-on-empty" || arg === "--debug" || arg === "--fix" || arg === "--append") {
7768
7851
  result[arg.slice(2)] = true;
7769
7852
  } else if (arg === "--check" || arg === "--upgrade-node") {
7770
7853
  result.check = true;
@@ -48,6 +48,8 @@ assertIncludes(help, "iola ask", "help");
48
48
  const commands = await runCli(["commands"]);
49
49
  assertIncludes(commands, "iola browser status|install|open|text|html|screenshot|pdf|click|type|eval", "commands");
50
50
  assertIncludes(commands, "iola mcp list|status|install|remove|serve [--stdio]", "commands");
51
+ assertIncludes(commands, "iola delete --yes", "commands");
52
+ assertIncludes(commands, "iola uninstall --yes", "commands");
51
53
  assertNotIncludes(commands, "Госуслуг", "commands");
52
54
  assertNotIncludes(commands, "gosuslugi", "commands");
53
55
 
@@ -61,4 +63,14 @@ assertIncludes(skills, "open-data", "skills list");
61
63
  assertIncludes(skills, "reports", "skills list");
62
64
  assertNotIncludes(skills, "gosuslugi", "skills list");
63
65
 
66
+ const uninstallPlan = JSON.parse(await runCli(["uninstall", "--dry-run", "--json"]));
67
+ if (!Array.isArray(uninstallPlan.willDelete) || !uninstallPlan.willKeep.includes("Codex CLI")) {
68
+ throw new Error("uninstall dry-run should list delete targets and keep Codex CLI");
69
+ }
70
+
71
+ const deletePlan = JSON.parse(await runCli(["delete", "--dry-run", "--json"]));
72
+ if (!Array.isArray(deletePlan.willDelete) || !deletePlan.willKeep.includes("Codex CLI")) {
73
+ throw new Error("delete dry-run should list delete targets and keep Codex CLI");
74
+ }
75
+
64
76
  console.log("smoke tests passed");