@iola_adm/iola-cli 0.1.28 → 0.1.29
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/README.md +4 -0
- package/package.json +1 -1
- package/src/cli.js +217 -4
- package/wiki/Home.md +1 -0
- package/wiki//320/220/321/200/321/205/320/270/320/262/321/213-/320/270-/320/274/320/260/321/201/321/202/320/265/321/200-/320/275/320/260/321/201/321/202/321/200/320/276/320/271/320/272/320/270.md +42 -0
- package/wiki//320/232/320/276/320/274/320/260/320/275/320/264/321/213.md +4 -0
package/README.md
CHANGED
|
@@ -59,6 +59,7 @@ iola tasks list
|
|
|
59
59
|
iola artifacts list
|
|
60
60
|
iola trace last
|
|
61
61
|
iola changes list
|
|
62
|
+
iola archive doctor
|
|
62
63
|
iola index status
|
|
63
64
|
iola reports list
|
|
64
65
|
iola plugins list
|
|
@@ -92,6 +93,7 @@ iola version --check
|
|
|
92
93
|
- [Локальные файлы](https://github.com/adm-iola/iola-cli/wiki/Локальные-файлы)
|
|
93
94
|
- [Рабочая среда агента](https://github.com/adm-iola/iola-cli/wiki/Рабочая-среда-агента)
|
|
94
95
|
- [Расширения и локальные данные](https://github.com/adm-iola/iola-cli/wiki/Расширения-и-локальные-данные)
|
|
96
|
+
- [Архивы и мастер настройки](https://github.com/adm-iola/iola-cli/wiki/Архивы-и-мастер-настройки)
|
|
95
97
|
- [Daemon, RPC и cron](https://github.com/adm-iola/iola-cli/wiki/Daemon-RPC-и-cron)
|
|
96
98
|
- [Контекст и память](https://github.com/adm-iola/iola-cli/wiki/Контекст-и-память)
|
|
97
99
|
- [Команды](https://github.com/adm-iola/iola-cli/wiki/Команды)
|
|
@@ -109,6 +111,8 @@ iola version --check
|
|
|
109
111
|
- экспорт отчетов в Excel/Word-совместимые файлы;
|
|
110
112
|
- staged changes, импорт локальных CSV/JSON, индекс локальных документов, report packs, plugins и локальный MCP endpoint;
|
|
111
113
|
- чтение и индексирование `.docx`, `.xlsx`, `.pptx`, `.pdf`, `.md`, `.txt`, `.csv`, `.json`, `.html`;
|
|
114
|
+
- работа с архивами через 7-Zip: `.zip`, `.7z`, `.rar`, `.tar`, `.gz`, `.tgz`, `.bz2`, `.xz` и другие;
|
|
115
|
+
- расширенный `iola onboard` с установкой 7-Zip, Ollama, Codex CLI и настройкой выбранных компонентов.
|
|
112
116
|
- cron-задачи, локальный daemon и RPC для автоматизаций;
|
|
113
117
|
- контекстные файлы `IOLA.md` и `.iola/context.md`;
|
|
114
118
|
- интеграция с публичным MCP-сервером Йошкар-Олы.
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -244,6 +244,7 @@ const COMMANDS = new Map([
|
|
|
244
244
|
["skills", handleSkills],
|
|
245
245
|
["tools", handleTools],
|
|
246
246
|
["files", handleFiles],
|
|
247
|
+
["archive", handleArchive],
|
|
247
248
|
["changes", handleChanges],
|
|
248
249
|
["import", handleImport],
|
|
249
250
|
["index", handleIndex],
|
|
@@ -360,6 +361,7 @@ Usage:
|
|
|
360
361
|
iola skills list|show|paths|enable|disable
|
|
361
362
|
iola tools list|toolsets|enable|disable|profile
|
|
362
363
|
iola files status|mode|approvals|tree|read|search|write|patch
|
|
364
|
+
iola archive doctor|list|test|extract|create|index
|
|
363
365
|
iola changes list|show|apply|discard
|
|
364
366
|
iola import file|folder
|
|
365
367
|
iola index folder|status|search
|
|
@@ -618,6 +620,11 @@ async function handleAgentLine(line, state) {
|
|
|
618
620
|
return false;
|
|
619
621
|
}
|
|
620
622
|
|
|
623
|
+
if (command === "archive") {
|
|
624
|
+
await handleArchive(args);
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
|
|
621
628
|
if (command === "changes") {
|
|
622
629
|
await handleChanges(args);
|
|
623
630
|
return false;
|
|
@@ -791,6 +798,7 @@ async function handleAgentLine(line, state) {
|
|
|
791
798
|
context: ["context", args],
|
|
792
799
|
skills: ["skills", args],
|
|
793
800
|
files: ["files", args],
|
|
801
|
+
archive: ["archive", args],
|
|
794
802
|
changes: ["changes", args],
|
|
795
803
|
index: ["index", args],
|
|
796
804
|
reports: ["reports", args],
|
|
@@ -850,6 +858,7 @@ function printAgentHelp() {
|
|
|
850
858
|
/permissions
|
|
851
859
|
/tools
|
|
852
860
|
/files status
|
|
861
|
+
/archive doctor
|
|
853
862
|
/changes list
|
|
854
863
|
/index status
|
|
855
864
|
/reports list
|
|
@@ -1591,6 +1600,7 @@ async function handleWiki(args) {
|
|
|
1591
1600
|
["Локальные файлы", `${base}/Локальные-файлы`],
|
|
1592
1601
|
["Рабочая среда агента", `${base}/Рабочая-среда-агента`],
|
|
1593
1602
|
["Расширения и локальные данные", `${base}/Расширения-и-локальные-данные`],
|
|
1603
|
+
["Архивы и мастер настройки", `${base}/Архивы-и-мастер-настройки`],
|
|
1594
1604
|
["Daemon, RPC и cron", `${base}/Daemon-RPC-и-cron`],
|
|
1595
1605
|
["Контекст и память", `${base}/Контекст-и-память`],
|
|
1596
1606
|
["Команды", `${base}/Команды`],
|
|
@@ -1845,6 +1855,88 @@ async function handleFiles(args) {
|
|
|
1845
1855
|
throw new Error("Команды files: status, mode MODE, approvals POLICY, tree [PATH], read FILE, search TEXT, write FILE --text TEXT, patch FILE --search OLD --replace NEW.");
|
|
1846
1856
|
}
|
|
1847
1857
|
|
|
1858
|
+
async function handleArchive(args) {
|
|
1859
|
+
const [action = "doctor", target, ...rest] = args;
|
|
1860
|
+
const options = parseOptions(rest);
|
|
1861
|
+
if (action === "doctor") {
|
|
1862
|
+
const sevenZip = await ensureArchiveTool({ install: true });
|
|
1863
|
+
printKeyValue({ sevenZip, status: "ok", formats: "zip, 7z, rar, tar, gz, tgz, bz2, xz и др." });
|
|
1864
|
+
return;
|
|
1865
|
+
}
|
|
1866
|
+
if (action === "list") {
|
|
1867
|
+
if (!target) throw new Error("Пример: iola archive list docs.zip");
|
|
1868
|
+
const rows = await archiveList(target);
|
|
1869
|
+
printTable(rows, [["date", "Дата"], ["size", "Размер"], ["name", "Файл"]]);
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1872
|
+
if (action === "test") {
|
|
1873
|
+
if (!target) throw new Error("Пример: iola archive test docs.zip");
|
|
1874
|
+
await archiveRun(["t", target]);
|
|
1875
|
+
console.log("Архив проверен.");
|
|
1876
|
+
return;
|
|
1877
|
+
}
|
|
1878
|
+
if (action === "extract") {
|
|
1879
|
+
if (!target) throw new Error("Пример: iola archive extract docs.zip --output ./out");
|
|
1880
|
+
const outputDir = options.output || path.join(process.cwd(), path.basename(target, path.extname(target)));
|
|
1881
|
+
await archiveRun(["x", target, `-o${outputDir}`, "-y"]);
|
|
1882
|
+
console.log(`Архив распакован: ${outputDir}`);
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
1885
|
+
if (action === "create") {
|
|
1886
|
+
const outputFile = target;
|
|
1887
|
+
const inputPath = rest[0] || options.path || ".";
|
|
1888
|
+
if (!outputFile) throw new Error("Пример: iola archive create docs.zip ./docs");
|
|
1889
|
+
await archiveRun(["a", outputFile, inputPath]);
|
|
1890
|
+
console.log(`Архив создан: ${outputFile}`);
|
|
1891
|
+
return;
|
|
1892
|
+
}
|
|
1893
|
+
if (action === "index") {
|
|
1894
|
+
if (!target) throw new Error("Пример: iola archive index docs.zip");
|
|
1895
|
+
const tempDir = path.join(os.tmpdir(), `iola-archive-${Date.now()}`);
|
|
1896
|
+
const previous = await loadConfig();
|
|
1897
|
+
await mkdir(tempDir, { recursive: true });
|
|
1898
|
+
try {
|
|
1899
|
+
await archiveRun(["x", target, `-o${tempDir}`, "-y"]);
|
|
1900
|
+
await saveConfig({ files: { ...(previous.files || {}), workspaceRoot: tempDir, mode: "read-only" } });
|
|
1901
|
+
await setFilesMode("read-only", await loadConfig());
|
|
1902
|
+
const count = await indexFolder(".", { depth: options.depth || 8, limit: options.limit || 2000 });
|
|
1903
|
+
console.log(`Проиндексировано файлов из архива: ${count}`);
|
|
1904
|
+
} finally {
|
|
1905
|
+
await saveConfig({ files: previous.files, permissions: previous.permissions, toolsets: previous.toolsets }).catch(() => {});
|
|
1906
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
1907
|
+
}
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1910
|
+
throw new Error("Команды archive: doctor, list FILE, test FILE, extract FILE --output DIR, create OUT INPUT, index FILE.");
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
async function archiveRun(args) {
|
|
1914
|
+
const command = await ensureArchiveTool({ install: true });
|
|
1915
|
+
return runCommand(command, args, { inherit: true });
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
async function archiveList(target) {
|
|
1919
|
+
const command = await ensureArchiveTool({ install: true });
|
|
1920
|
+
const { stdout } = await runCommand(command, ["l", "-slt", target]);
|
|
1921
|
+
const rows = [];
|
|
1922
|
+
let current = {};
|
|
1923
|
+
for (const line of stdout.split(/\r?\n/)) {
|
|
1924
|
+
if (!line.trim()) {
|
|
1925
|
+
if (current.Path && current.Path !== target) rows.push({
|
|
1926
|
+
date: current.Modified || current.Created || "-",
|
|
1927
|
+
size: current.Size || "-",
|
|
1928
|
+
name: current.Path,
|
|
1929
|
+
});
|
|
1930
|
+
current = {};
|
|
1931
|
+
continue;
|
|
1932
|
+
}
|
|
1933
|
+
const [key, ...parts] = line.split(" = ");
|
|
1934
|
+
if (key && parts.length) current[key.trim()] = parts.join(" = ").trim();
|
|
1935
|
+
}
|
|
1936
|
+
if (current.Path && current.Path !== target) rows.push({ date: current.Modified || current.Created || "-", size: current.Size || "-", name: current.Path });
|
|
1937
|
+
return rows;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1848
1940
|
async function handleChanges(args) {
|
|
1849
1941
|
const [action = "list", id] = args;
|
|
1850
1942
|
if (action === "list" || action === "ls") {
|
|
@@ -1905,13 +1997,18 @@ async function handleIndex(args) {
|
|
|
1905
1997
|
console.log(`Проиндексировано документов: ${count}`);
|
|
1906
1998
|
return;
|
|
1907
1999
|
}
|
|
2000
|
+
if (action === "archive") {
|
|
2001
|
+
if (!target) throw new Error("Пример: iola index archive docs.zip");
|
|
2002
|
+
await handleArchive(["index", target, ...rest]);
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
1908
2005
|
if (action === "search") {
|
|
1909
2006
|
const query = [target, ...rest].filter(Boolean).join(" ");
|
|
1910
2007
|
if (!query) throw new Error('Пример: iola index search "школа 29"');
|
|
1911
2008
|
printTable(searchDocs(query, Number(options.limit || 20)), [["file", "Файл"], ["title", "Название"], ["snippet", "Фрагмент"]]);
|
|
1912
2009
|
return;
|
|
1913
2010
|
}
|
|
1914
|
-
throw new Error("Команды index: status, folder PATH, search TEXT.");
|
|
2011
|
+
throw new Error("Команды index: status, folder PATH, archive FILE, search TEXT.");
|
|
1915
2012
|
}
|
|
1916
2013
|
|
|
1917
2014
|
async function handleReports(args) {
|
|
@@ -5281,12 +5378,68 @@ async function onboard(args = []) {
|
|
|
5281
5378
|
initDatabase();
|
|
5282
5379
|
await handleConfig(["validate"]);
|
|
5283
5380
|
await doctor(["--summary"]);
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5381
|
+
await ensureArchiveTool({ install: true });
|
|
5382
|
+
|
|
5383
|
+
const components = options.yes ? ["workspace", "policy", "ollama", "openai", "openrouter", "codex", "codex-mcp", "index"] : await chooseOnboardComponents();
|
|
5384
|
+
if (components.includes("workspace")) await handleWorkspace(["init"]);
|
|
5385
|
+
if (components.includes("policy")) await handlePolicy(["use", "analyst"]);
|
|
5386
|
+
if (components.includes("ollama")) {
|
|
5387
|
+
await installOllamaIfMissing();
|
|
5388
|
+
await setupOllama(["--yes"]);
|
|
5389
|
+
}
|
|
5390
|
+
if (components.includes("openai")) {
|
|
5391
|
+
await aiSetup(["openai"]);
|
|
5392
|
+
if (process.stdin.isTTY) await setAiKey("openai");
|
|
5393
|
+
}
|
|
5394
|
+
if (components.includes("openrouter")) {
|
|
5395
|
+
await aiSetup(["openrouter"]);
|
|
5396
|
+
if (process.stdin.isTTY) await setAiKey("openrouter");
|
|
5397
|
+
}
|
|
5398
|
+
if (components.includes("codex")) {
|
|
5399
|
+
await installCodexIfMissing();
|
|
5400
|
+
await aiSetup(["codex"]);
|
|
5401
|
+
}
|
|
5402
|
+
if (components.includes("codex-mcp")) await setupClient(["codex"]);
|
|
5403
|
+
if (components.includes("index")) {
|
|
5404
|
+
await setFilesMode("read-only", await loadConfig());
|
|
5405
|
+
console.log("Индекс документов можно запустить командой: iola index folder ./docs");
|
|
5406
|
+
}
|
|
5287
5407
|
console.log("Onboard завершен.");
|
|
5288
5408
|
}
|
|
5289
5409
|
|
|
5410
|
+
async function chooseOnboardComponents() {
|
|
5411
|
+
if (!process.stdin.isTTY) return ["workspace", "policy"];
|
|
5412
|
+
console.log("");
|
|
5413
|
+
console.log("Выберите компоненты через запятую:");
|
|
5414
|
+
console.log("1. workspace и контекст");
|
|
5415
|
+
console.log("2. policy analyst");
|
|
5416
|
+
console.log("3. Ollama + локальная модель");
|
|
5417
|
+
console.log("4. OpenAI API");
|
|
5418
|
+
console.log("5. OpenRouter API");
|
|
5419
|
+
console.log("6. Codex CLI");
|
|
5420
|
+
console.log("7. MCP для Codex");
|
|
5421
|
+
console.log("8. Индекс локальных документов");
|
|
5422
|
+
console.log("");
|
|
5423
|
+
const rl = readline.createInterface({ input, output });
|
|
5424
|
+
try {
|
|
5425
|
+
const answer = (await rl.question("Компоненты [1,2,8]: ")).trim() || "1,2,8";
|
|
5426
|
+
const selected = new Set(answer.split(/[,\s]+/).filter(Boolean));
|
|
5427
|
+
const map = {
|
|
5428
|
+
1: "workspace",
|
|
5429
|
+
2: "policy",
|
|
5430
|
+
3: "ollama",
|
|
5431
|
+
4: "openai",
|
|
5432
|
+
5: "openrouter",
|
|
5433
|
+
6: "codex",
|
|
5434
|
+
7: "codex-mcp",
|
|
5435
|
+
8: "index",
|
|
5436
|
+
};
|
|
5437
|
+
return [...selected].map((item) => map[item] || item).filter(Boolean);
|
|
5438
|
+
} finally {
|
|
5439
|
+
rl.close();
|
|
5440
|
+
}
|
|
5441
|
+
}
|
|
5442
|
+
|
|
5290
5443
|
function parseOptions(args) {
|
|
5291
5444
|
const result = { _: [] };
|
|
5292
5445
|
|
|
@@ -5614,6 +5767,66 @@ async function getCommandVersion(command, args) {
|
|
|
5614
5767
|
}
|
|
5615
5768
|
}
|
|
5616
5769
|
|
|
5770
|
+
async function findCommand(candidates, versionArgs = ["--version"]) {
|
|
5771
|
+
for (const command of candidates) {
|
|
5772
|
+
const version = await getCommandVersion(command, versionArgs);
|
|
5773
|
+
if (version !== "не найден") return { command, version };
|
|
5774
|
+
}
|
|
5775
|
+
return null;
|
|
5776
|
+
}
|
|
5777
|
+
|
|
5778
|
+
async function ensureArchiveTool(options = {}) {
|
|
5779
|
+
const found = await findCommand(["7z", "7zz", "7za"], ["--help"]);
|
|
5780
|
+
if (found) return found.command;
|
|
5781
|
+
if (options.install === false) throw new Error("7-Zip не найден.");
|
|
5782
|
+
await installSevenZip();
|
|
5783
|
+
const installed = await findCommand(["7z", "7zz", "7za"], ["--help"]);
|
|
5784
|
+
if (!installed) throw new Error("7-Zip не найден после установки. Перезапустите терминал и проверьте: 7z");
|
|
5785
|
+
return installed.command;
|
|
5786
|
+
}
|
|
5787
|
+
|
|
5788
|
+
async function installSevenZip() {
|
|
5789
|
+
console.log("7-Zip не найден. Устанавливаю архиватор для работы со всеми типами архивов.");
|
|
5790
|
+
if (process.platform === "win32") {
|
|
5791
|
+
await runCommand("winget", ["install", "7zip.7zip", "--accept-package-agreements", "--accept-source-agreements"], { inherit: true });
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
if (process.platform === "darwin") {
|
|
5795
|
+
try {
|
|
5796
|
+
await runCommand("brew", ["install", "sevenzip"], { inherit: true });
|
|
5797
|
+
} catch {
|
|
5798
|
+
await runCommand("brew", ["install", "p7zip"], { inherit: true });
|
|
5799
|
+
}
|
|
5800
|
+
return;
|
|
5801
|
+
}
|
|
5802
|
+
try {
|
|
5803
|
+
await runCommand("sh", ["-c", "sudo apt-get update && sudo apt-get install -y p7zip-full p7zip-rar"], { inherit: true });
|
|
5804
|
+
} catch {
|
|
5805
|
+
await runCommand("sh", ["-c", "sudo apt-get update && sudo apt-get install -y 7zip"], { inherit: true });
|
|
5806
|
+
}
|
|
5807
|
+
}
|
|
5808
|
+
|
|
5809
|
+
async function installOllamaIfMissing() {
|
|
5810
|
+
if (await getOllamaVersion()) return;
|
|
5811
|
+
console.log("Ollama не найден. Устанавливаю Ollama.");
|
|
5812
|
+
if (process.platform === "win32") {
|
|
5813
|
+
await runCommand("winget", ["install", "Ollama.Ollama", "--accept-package-agreements", "--accept-source-agreements"], { inherit: true });
|
|
5814
|
+
return;
|
|
5815
|
+
}
|
|
5816
|
+
if (process.platform === "darwin") {
|
|
5817
|
+
await runCommand("brew", ["install", "--cask", "ollama"], { inherit: true });
|
|
5818
|
+
return;
|
|
5819
|
+
}
|
|
5820
|
+
await runCommand("sh", ["-c", "curl -fsSL https://ollama.com/install.sh | sh"], { inherit: true });
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5823
|
+
async function installCodexIfMissing() {
|
|
5824
|
+
const version = await getCommandVersion("codex", ["--version"]);
|
|
5825
|
+
if (version !== "не найден") return;
|
|
5826
|
+
console.log("Codex CLI не найден. Устанавливаю через npm.");
|
|
5827
|
+
await runCommand("npm", ["install", "-g", "@openai/codex"], { inherit: true });
|
|
5828
|
+
}
|
|
5829
|
+
|
|
5617
5830
|
async function probeEndpoint(url) {
|
|
5618
5831
|
try {
|
|
5619
5832
|
const response = await fetch(url, { headers: { accept: "application/json" } });
|
package/wiki/Home.md
CHANGED
|
@@ -32,6 +32,7 @@ iola ask "найди школу 29"
|
|
|
32
32
|
- [Локальные файлы](Локальные-файлы)
|
|
33
33
|
- [Рабочая среда агента](Рабочая-среда-агента)
|
|
34
34
|
- [Расширения и локальные данные](Расширения-и-локальные-данные)
|
|
35
|
+
- [Архивы и мастер настройки](Архивы-и-мастер-настройки)
|
|
35
36
|
- [Daemon, RPC и cron](Daemon-RPC-и-cron)
|
|
36
37
|
- [Контекст и память](Контекст-и-память)
|
|
37
38
|
- [Команды](Команды)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Архивы и мастер настройки
|
|
2
|
+
|
|
3
|
+
`iola-cli` использует 7-Zip как штатный архиватор. Если 7-Zip не найден, `iola archive doctor` и `iola onboard` устанавливают его автоматически.
|
|
4
|
+
|
|
5
|
+
Поддерживаемые форматы зависят от 7-Zip:
|
|
6
|
+
|
|
7
|
+
- `.zip`
|
|
8
|
+
- `.7z`
|
|
9
|
+
- `.rar`
|
|
10
|
+
- `.tar`
|
|
11
|
+
- `.gz`
|
|
12
|
+
- `.tgz`
|
|
13
|
+
- `.bz2`
|
|
14
|
+
- `.xz`
|
|
15
|
+
- другие форматы, которые поддерживает установленный 7-Zip
|
|
16
|
+
|
|
17
|
+
Команды:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
iola archive doctor
|
|
21
|
+
iola archive list docs.zip
|
|
22
|
+
iola archive test docs.zip
|
|
23
|
+
iola archive extract docs.zip --output ./out
|
|
24
|
+
iola archive create docs.zip ./docs
|
|
25
|
+
iola archive index docs.zip
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Индекс архива:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
iola index archive docs.zip
|
|
32
|
+
iola index search "контракт"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Мастер настройки:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
iola onboard
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Мастер проверяет Node/npm, SQLite, API, 7-Zip и предлагает подключить workspace, policy, Ollama, OpenAI, OpenRouter, Codex CLI, MCP и индекс локальных документов.
|
|
42
|
+
|
|
@@ -58,6 +58,10 @@ iola snapshot list
|
|
|
58
58
|
iola trace last
|
|
59
59
|
iola export education-contacts --format xlsx --output contacts.xlsx
|
|
60
60
|
iola changes list
|
|
61
|
+
iola archive doctor
|
|
62
|
+
iola archive list docs.zip
|
|
63
|
+
iola archive extract docs.zip --output ./out
|
|
64
|
+
iola index archive docs.zip
|
|
61
65
|
iola import file data.csv --dataset custom
|
|
62
66
|
iola index folder ./docs
|
|
63
67
|
iola reports list
|