@sunasteriskrnd/takumi 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/index.js +191 -29
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19815,7 +19815,7 @@ var package_default;
|
|
|
19815
19815
|
var init_package = __esm(() => {
|
|
19816
19816
|
package_default = {
|
|
19817
19817
|
name: "@sunasteriskrnd/takumi",
|
|
19818
|
-
version: "0.
|
|
19818
|
+
version: "0.12.0",
|
|
19819
19819
|
description: "CLI tool for bootstrapping and managing Takumi projects",
|
|
19820
19820
|
type: "module",
|
|
19821
19821
|
repository: {
|
|
@@ -39263,7 +39263,7 @@ async function installSkillsDependencies(skillsDir, options2 = {}) {
|
|
|
39263
39263
|
let effectiveSkillsDir = skillsDir;
|
|
39264
39264
|
if (!existsSync8(scriptPath)) {
|
|
39265
39265
|
const { homedir: homedir6 } = await import("node:os");
|
|
39266
|
-
const globalSkillsDir = join38(homedir6(), ".claude", "skills");
|
|
39266
|
+
const globalSkillsDir = process.env.TKM_GLOBAL_SKILLS_DIR ?? join38(homedir6(), ".claude", "skills");
|
|
39267
39267
|
const globalScriptPath = join38(globalSkillsDir, scriptName);
|
|
39268
39268
|
if (existsSync8(globalScriptPath)) {
|
|
39269
39269
|
logger.debug(`Local install script not found, using global: ${globalScriptPath}`);
|
|
@@ -51332,6 +51332,82 @@ var init_auth_command_help = __esm(() => {
|
|
|
51332
51332
|
};
|
|
51333
51333
|
});
|
|
51334
51334
|
|
|
51335
|
+
// src/domains/help/commands/artifact-command-help.ts
|
|
51336
|
+
var artifactCommandHelp;
|
|
51337
|
+
var init_artifact_command_help = __esm(() => {
|
|
51338
|
+
artifactCommandHelp = {
|
|
51339
|
+
name: "artifact",
|
|
51340
|
+
description: "Upload, download, and delete Takumi artifacts (upload|download|delete)",
|
|
51341
|
+
usage: "tkm artifact <upload <file|dir> | download <uuid|url> | delete <uuid|url>>",
|
|
51342
|
+
examples: [
|
|
51343
|
+
{
|
|
51344
|
+
command: "tkm artifact upload ./report.html --title 'Weekly Report'",
|
|
51345
|
+
description: "Upload a file (or directory) as a new artifact and print its share URL"
|
|
51346
|
+
},
|
|
51347
|
+
{
|
|
51348
|
+
command: "tkm artifact download <uuid|url> -o ./out --ver 3",
|
|
51349
|
+
description: "Download a specific version's files into a directory"
|
|
51350
|
+
},
|
|
51351
|
+
{
|
|
51352
|
+
command: "tkm artifact delete <uuid|url> --ver 2",
|
|
51353
|
+
description: "Delete ONLY version 2 (soft delete; other versions stay). A pasted URL with ?v=2 does the same"
|
|
51354
|
+
}
|
|
51355
|
+
],
|
|
51356
|
+
optionGroups: [
|
|
51357
|
+
{
|
|
51358
|
+
title: "Actions",
|
|
51359
|
+
options: [
|
|
51360
|
+
{
|
|
51361
|
+
flags: "upload <file|dir>",
|
|
51362
|
+
description: "Upload a file or directory as a new artifact (or new version with --id)"
|
|
51363
|
+
},
|
|
51364
|
+
{
|
|
51365
|
+
flags: "download <uuid|url>",
|
|
51366
|
+
description: "Download an artifact's files (latest or --ver <n>)"
|
|
51367
|
+
},
|
|
51368
|
+
{
|
|
51369
|
+
flags: "delete <uuid|url>",
|
|
51370
|
+
description: "Soft-delete the whole artifact, or one version with --ver <n>"
|
|
51371
|
+
}
|
|
51372
|
+
]
|
|
51373
|
+
},
|
|
51374
|
+
{
|
|
51375
|
+
title: "Options",
|
|
51376
|
+
options: [
|
|
51377
|
+
{
|
|
51378
|
+
flags: "--id <uuid|url>",
|
|
51379
|
+
description: "(upload) Existing artifact to overwrite with a new version"
|
|
51380
|
+
},
|
|
51381
|
+
{
|
|
51382
|
+
flags: "--title <title>",
|
|
51383
|
+
description: "(upload) Display title for the artifact (max 200 chars)"
|
|
51384
|
+
},
|
|
51385
|
+
{
|
|
51386
|
+
flags: "-m, --message <message>",
|
|
51387
|
+
description: "(upload) Short note describing this version's change (max 100 chars)"
|
|
51388
|
+
},
|
|
51389
|
+
{
|
|
51390
|
+
flags: "-o, --output <dir>",
|
|
51391
|
+
description: "(download) Output directory; default: slug(title) or uuid in CWD"
|
|
51392
|
+
},
|
|
51393
|
+
{
|
|
51394
|
+
flags: "--ver <n>",
|
|
51395
|
+
description: "(download) Version to download | (delete) version to delete. ?v=<n> in a pasted URL works too; --ver wins when both given"
|
|
51396
|
+
},
|
|
51397
|
+
{
|
|
51398
|
+
flags: "--force",
|
|
51399
|
+
description: "(download) Allow writing into a non-empty directory"
|
|
51400
|
+
},
|
|
51401
|
+
{
|
|
51402
|
+
flags: "-y, --yes",
|
|
51403
|
+
description: "(delete) Skip the confirmation prompt"
|
|
51404
|
+
}
|
|
51405
|
+
]
|
|
51406
|
+
}
|
|
51407
|
+
]
|
|
51408
|
+
};
|
|
51409
|
+
});
|
|
51410
|
+
|
|
51335
51411
|
// src/domains/help/commands/index.ts
|
|
51336
51412
|
var init_commands2 = __esm(() => {
|
|
51337
51413
|
init_init_command_help();
|
|
@@ -51341,6 +51417,7 @@ var init_commands2 = __esm(() => {
|
|
|
51341
51417
|
init_versions_command_help();
|
|
51342
51418
|
init_config_command_help();
|
|
51343
51419
|
init_auth_command_help();
|
|
51420
|
+
init_artifact_command_help();
|
|
51344
51421
|
init_common_options();
|
|
51345
51422
|
});
|
|
51346
51423
|
|
|
@@ -51359,7 +51436,8 @@ var init_help_commands = __esm(() => {
|
|
|
51359
51436
|
versions: versionsCommandHelp,
|
|
51360
51437
|
doctor: doctorCommandHelp,
|
|
51361
51438
|
uninstall: uninstallCommandHelp,
|
|
51362
|
-
auth: authCommandHelp
|
|
51439
|
+
auth: authCommandHelp,
|
|
51440
|
+
artifact: artifactCommandHelp
|
|
51363
51441
|
};
|
|
51364
51442
|
});
|
|
51365
51443
|
|
|
@@ -53547,6 +53625,27 @@ async function remove9(token, uuid) {
|
|
|
53547
53625
|
throw new ArtifactApiError(res.status, `Delete failed (HTTP ${res.status}): ${msg}`);
|
|
53548
53626
|
}
|
|
53549
53627
|
}
|
|
53628
|
+
async function removeVersion(token, uuid, version3) {
|
|
53629
|
+
const base = getServerUrl();
|
|
53630
|
+
const res = await fetch(`${base}/api/artifacts/${encodeURIComponent(uuid)}/versions/${encodeURIComponent(String(version3))}`, {
|
|
53631
|
+
method: "DELETE",
|
|
53632
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }
|
|
53633
|
+
});
|
|
53634
|
+
if (!res.ok) {
|
|
53635
|
+
const msg = await parseErrorMessage(res);
|
|
53636
|
+
throw new ArtifactApiError(res.status, `Delete version failed (HTTP ${res.status}): ${msg}`);
|
|
53637
|
+
}
|
|
53638
|
+
try {
|
|
53639
|
+
return await res.json();
|
|
53640
|
+
} catch {
|
|
53641
|
+
return {
|
|
53642
|
+
ok: true,
|
|
53643
|
+
deleted_version: undefined,
|
|
53644
|
+
live_version: undefined,
|
|
53645
|
+
shared_version: undefined
|
|
53646
|
+
};
|
|
53647
|
+
}
|
|
53648
|
+
}
|
|
53550
53649
|
async function getManifest(token, uuid, version3) {
|
|
53551
53650
|
const base = getServerUrl();
|
|
53552
53651
|
const qs = version3 !== undefined ? `?v=${encodeURIComponent(String(version3))}` : "";
|
|
@@ -53680,6 +53779,17 @@ function parseArtifactRef(input) {
|
|
|
53680
53779
|
const candidate = m2?.[1] ?? "";
|
|
53681
53780
|
return UUID_V4_RE.test(candidate) ? candidate.toLowerCase() : null;
|
|
53682
53781
|
}
|
|
53782
|
+
function extractVersionFromRef(ref) {
|
|
53783
|
+
try {
|
|
53784
|
+
const url = new URL(ref.trim());
|
|
53785
|
+
const v2 = url.searchParams.get("v");
|
|
53786
|
+
if (v2 !== null) {
|
|
53787
|
+
const n = Number.parseInt(v2, 10);
|
|
53788
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
53789
|
+
}
|
|
53790
|
+
} catch {}
|
|
53791
|
+
return;
|
|
53792
|
+
}
|
|
53683
53793
|
function warnIfHostMismatch(input) {
|
|
53684
53794
|
let inputUrl;
|
|
53685
53795
|
try {
|
|
@@ -53710,6 +53820,11 @@ async function artifactDelete(ref, opts) {
|
|
|
53710
53820
|
const token = await getToken(opts);
|
|
53711
53821
|
if (!token)
|
|
53712
53822
|
return;
|
|
53823
|
+
const version3 = opts.version !== undefined ? opts.version : extractVersionFromRef(ref);
|
|
53824
|
+
if (version3 !== undefined) {
|
|
53825
|
+
await deleteVersion(uuid, version3, token, opts);
|
|
53826
|
+
return;
|
|
53827
|
+
}
|
|
53713
53828
|
if (!opts.yes) {
|
|
53714
53829
|
const confirmed = await se({
|
|
53715
53830
|
message: `Delete artifact ${uuid}? This cannot be undone.`,
|
|
@@ -53730,6 +53845,36 @@ async function artifactDelete(ref, opts) {
|
|
|
53730
53845
|
await removeEntry(uuid);
|
|
53731
53846
|
console.log(`Deleted artifact ${uuid}.`);
|
|
53732
53847
|
}
|
|
53848
|
+
async function deleteVersion(uuid, version3, token, opts) {
|
|
53849
|
+
if (!opts.yes) {
|
|
53850
|
+
const confirmed = await se({
|
|
53851
|
+
message: `Delete version ${version3} of artifact ${uuid}? This cannot be undone.`,
|
|
53852
|
+
initialValue: false
|
|
53853
|
+
});
|
|
53854
|
+
if (lD(confirmed) || !confirmed) {
|
|
53855
|
+
console.log("Cancelled.");
|
|
53856
|
+
return;
|
|
53857
|
+
}
|
|
53858
|
+
}
|
|
53859
|
+
try {
|
|
53860
|
+
const result = await removeVersion(token, uuid, version3);
|
|
53861
|
+
if (result.live_version !== undefined) {
|
|
53862
|
+
console.log(`Deleted version ${version3} of artifact ${uuid}. Live version is now ${result.live_version}.`);
|
|
53863
|
+
} else {
|
|
53864
|
+
console.log(`Deleted version ${version3} of artifact ${uuid}.`);
|
|
53865
|
+
}
|
|
53866
|
+
} catch (err) {
|
|
53867
|
+
if (err instanceof ArtifactApiError && isCannotDeleteLastVersion(err)) {
|
|
53868
|
+
console.error(`Error: cannot delete version ${version3} — it is the last remaining version. ` + `Delete the whole artifact instead: tkm artifact delete ${uuid}`);
|
|
53869
|
+
} else {
|
|
53870
|
+
printApiError(err);
|
|
53871
|
+
}
|
|
53872
|
+
process.exitCode = 1;
|
|
53873
|
+
}
|
|
53874
|
+
}
|
|
53875
|
+
function isCannotDeleteLastVersion(err) {
|
|
53876
|
+
return err.status === 409 && err.message.includes("cannot_delete_last_version");
|
|
53877
|
+
}
|
|
53733
53878
|
|
|
53734
53879
|
// src/commands/artifact/download-command.ts
|
|
53735
53880
|
import { promises as fs11 } from "node:fs";
|
|
@@ -53797,6 +53942,11 @@ var EXT_TO_MIME = {
|
|
|
53797
53942
|
html: "text/html",
|
|
53798
53943
|
htm: "text/html",
|
|
53799
53944
|
md: "text/markdown",
|
|
53945
|
+
mmd: "text/vnd.mermaid",
|
|
53946
|
+
yaml: "application/yaml",
|
|
53947
|
+
yml: "application/yaml",
|
|
53948
|
+
csv: "text/csv",
|
|
53949
|
+
tsv: "text/tab-separated-values",
|
|
53800
53950
|
txt: "text/plain",
|
|
53801
53951
|
css: "text/css",
|
|
53802
53952
|
js: "text/javascript",
|
|
@@ -53905,17 +54055,6 @@ function deriveSlug(title, uuid) {
|
|
|
53905
54055
|
const slug = (title ?? "").trim().replace(/[/\\:*?"<>|.]/g, " ").split("").map((c2) => c2.charCodeAt(0) < 32 ? " " : c2).join("").replace(/\s+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "").slice(0, 80);
|
|
53906
54056
|
return slug || uuid;
|
|
53907
54057
|
}
|
|
53908
|
-
function extractVersionFromRef(ref) {
|
|
53909
|
-
try {
|
|
53910
|
-
const url = new URL(ref.trim());
|
|
53911
|
-
const v2 = url.searchParams.get("v");
|
|
53912
|
-
if (v2 !== null) {
|
|
53913
|
-
const n = Number.parseInt(v2, 10);
|
|
53914
|
-
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
53915
|
-
}
|
|
53916
|
-
} catch {}
|
|
53917
|
-
return;
|
|
53918
|
-
}
|
|
53919
54058
|
async function artifactDownload(ref, opts) {
|
|
53920
54059
|
const uuid = parseArtifactRef(ref);
|
|
53921
54060
|
if (!uuid) {
|
|
@@ -54005,9 +54144,12 @@ import { promises as fs13 } from "node:fs";
|
|
|
54005
54144
|
import { basename as basename12, extname as extname5, resolve as resolve16 } from "node:path";
|
|
54006
54145
|
|
|
54007
54146
|
// src/domains/artifact/folder-walk.ts
|
|
54147
|
+
var import_ignore3 = __toESM(require_ignore(), 1);
|
|
54008
54148
|
import { promises as fs12 } from "node:fs";
|
|
54009
54149
|
import { join as join72, relative as relative14 } from "node:path";
|
|
54010
54150
|
var MAX_FILE_BYTES = 20 * 1024 * 1024;
|
|
54151
|
+
var IGNORE_FILES = [".gitignore", ".tkmignore"];
|
|
54152
|
+
var HARD_IGNORES = [".git", ".gitignore", ".tkmignore"];
|
|
54011
54153
|
|
|
54012
54154
|
class FolderLimitError extends Error {
|
|
54013
54155
|
constructor(message) {
|
|
@@ -54015,9 +54157,20 @@ class FolderLimitError extends Error {
|
|
|
54015
54157
|
this.name = "FolderLimitError";
|
|
54016
54158
|
}
|
|
54017
54159
|
}
|
|
54160
|
+
async function buildIgnoreMatcher(rootDir) {
|
|
54161
|
+
const ig = import_ignore3.default();
|
|
54162
|
+
for (const file of IGNORE_FILES) {
|
|
54163
|
+
try {
|
|
54164
|
+
ig.add(await fs12.readFile(join72(rootDir, file), "utf8"));
|
|
54165
|
+
} catch {}
|
|
54166
|
+
}
|
|
54167
|
+
ig.add(HARD_IGNORES);
|
|
54168
|
+
return ig;
|
|
54169
|
+
}
|
|
54018
54170
|
async function walkFolder(rootDir) {
|
|
54171
|
+
const ig = await buildIgnoreMatcher(rootDir);
|
|
54019
54172
|
const entries = [];
|
|
54020
|
-
await walk(rootDir, rootDir, entries);
|
|
54173
|
+
await walk(rootDir, rootDir, ig, entries);
|
|
54021
54174
|
entries.sort((a3, b3) => a3.relPath.localeCompare(b3.relPath));
|
|
54022
54175
|
const oversized = entries.find((e2) => e2.size > MAX_FILE_BYTES);
|
|
54023
54176
|
if (oversized) {
|
|
@@ -54026,7 +54179,7 @@ async function walkFolder(rootDir) {
|
|
|
54026
54179
|
}
|
|
54027
54180
|
return entries;
|
|
54028
54181
|
}
|
|
54029
|
-
async function walk(rootDir, dir, out) {
|
|
54182
|
+
async function walk(rootDir, dir, ig, out) {
|
|
54030
54183
|
let dirents;
|
|
54031
54184
|
try {
|
|
54032
54185
|
dirents = await fs12.readdir(dir, { withFileTypes: true });
|
|
@@ -54038,11 +54191,15 @@ async function walk(rootDir, dir, out) {
|
|
|
54038
54191
|
continue;
|
|
54039
54192
|
const name = String(dirent.name);
|
|
54040
54193
|
const absPath = join72(dir, name);
|
|
54194
|
+
const relPath = relative14(rootDir, absPath).split("\\").join("/");
|
|
54041
54195
|
if (dirent.isDirectory()) {
|
|
54042
|
-
|
|
54196
|
+
if (ig.ignores(`${relPath}/`))
|
|
54197
|
+
continue;
|
|
54198
|
+
await walk(rootDir, absPath, ig, out);
|
|
54043
54199
|
} else if (dirent.isFile()) {
|
|
54200
|
+
if (ig.ignores(relPath))
|
|
54201
|
+
continue;
|
|
54044
54202
|
const stat8 = await fs12.stat(absPath);
|
|
54045
|
-
const relPath = relative14(rootDir, absPath).split("\\").join("/");
|
|
54046
54203
|
out.push({ absPath, relPath, size: stat8.size });
|
|
54047
54204
|
}
|
|
54048
54205
|
}
|
|
@@ -54306,16 +54463,16 @@ async function artifactCommand(action, target, opts) {
|
|
|
54306
54463
|
break;
|
|
54307
54464
|
case "download":
|
|
54308
54465
|
if (!target)
|
|
54309
|
-
return usageError("tkm artifact download <uuid|url> [-o <dir>] [
|
|
54466
|
+
return usageError("tkm artifact download <uuid|url> [-o <dir>] [--ver <n>] [--force]");
|
|
54310
54467
|
await artifactDownload(target, opts);
|
|
54311
54468
|
break;
|
|
54312
54469
|
case "delete":
|
|
54313
54470
|
if (!target)
|
|
54314
|
-
return usageError("tkm artifact delete <uuid|url>");
|
|
54471
|
+
return usageError("tkm artifact delete <uuid|url> [--ver <n>]");
|
|
54315
54472
|
await artifactDelete(target, opts);
|
|
54316
54473
|
break;
|
|
54317
54474
|
case undefined:
|
|
54318
|
-
usageError("tkm artifact <upload <file> | download <uuid|url> | delete <uuid|url
|
|
54475
|
+
usageError("tkm artifact <upload <file> | download <uuid|url> | delete <uuid|url> [--ver <n>]>");
|
|
54319
54476
|
break;
|
|
54320
54477
|
default:
|
|
54321
54478
|
console.error(`Unknown artifact action: ${action}. Available: upload, download, delete`);
|
|
@@ -60842,7 +60999,7 @@ function detectBroadGlob(pattern, pathHint) {
|
|
|
60842
60999
|
}
|
|
60843
61000
|
|
|
60844
61001
|
// src/domains/hooks/handlers/guard-breadth-scout/check-ignore.ts
|
|
60845
|
-
var
|
|
61002
|
+
var import_ignore4 = __toESM(require_ignore(), 1);
|
|
60846
61003
|
import { existsSync as existsSync44, readFileSync as readFileSync13 } from "node:fs";
|
|
60847
61004
|
import { dirname as dirname24, join as join93 } from "node:path";
|
|
60848
61005
|
var BUILTIN_HEAVY_DIR_LINES = [
|
|
@@ -60903,7 +61060,7 @@ function cleanLines(lines) {
|
|
|
60903
61060
|
}
|
|
60904
61061
|
function buildIgnoreConfig(lines, sourceLabel) {
|
|
60905
61062
|
const cleaned = cleanLines(lines);
|
|
60906
|
-
const ig =
|
|
61063
|
+
const ig = import_ignore4.default().add(cleaned);
|
|
60907
61064
|
const patterns = cleaned.filter((line) => !line.startsWith("!"));
|
|
60908
61065
|
return { ig, patterns, sourceLabel };
|
|
60909
61066
|
}
|
|
@@ -60943,7 +61100,7 @@ function findMatchingIgnoreRule(candidatePath, config) {
|
|
|
60943
61100
|
let matched = null;
|
|
60944
61101
|
for (const pattern of config.patterns) {
|
|
60945
61102
|
try {
|
|
60946
|
-
if (
|
|
61103
|
+
if (import_ignore4.default().add(pattern).ignores(rel))
|
|
60947
61104
|
matched = pattern;
|
|
60948
61105
|
} catch {}
|
|
60949
61106
|
}
|
|
@@ -68150,7 +68307,7 @@ function registerTempDir(dir) {
|
|
|
68150
68307
|
|
|
68151
68308
|
// src/domains/installation/download-manager.ts
|
|
68152
68309
|
init_types2();
|
|
68153
|
-
var
|
|
68310
|
+
var import_ignore5 = __toESM(require_ignore(), 1);
|
|
68154
68311
|
|
|
68155
68312
|
// src/domains/installation/download/file-downloader.ts
|
|
68156
68313
|
init_logger();
|
|
@@ -72045,11 +72202,11 @@ class DownloadManager {
|
|
|
72045
72202
|
ig;
|
|
72046
72203
|
userExcludePatterns = [];
|
|
72047
72204
|
constructor() {
|
|
72048
|
-
this.ig =
|
|
72205
|
+
this.ig = import_ignore5.default().add(EXCLUDE_PATTERNS);
|
|
72049
72206
|
}
|
|
72050
72207
|
setExcludePatterns(patterns) {
|
|
72051
72208
|
this.userExcludePatterns = patterns;
|
|
72052
|
-
this.ig =
|
|
72209
|
+
this.ig = import_ignore5.default().add([...EXCLUDE_PATTERNS, ...this.userExcludePatterns]);
|
|
72053
72210
|
if (patterns.length > 0) {
|
|
72054
72211
|
logger.info(`Added ${patterns.length} custom exclude pattern(s)`);
|
|
72055
72212
|
patterns.forEach((p2) => logger.debug(` - ${p2}`));
|
|
@@ -77653,8 +77810,13 @@ function registerCommands(cli) {
|
|
|
77653
77810
|
cli.command("api [action] [service] [path]", "Interact with Takumi API and proxy services").option("--method <method>", "HTTP method for proxy requests (default: GET)").option("--body <json>", "Request body as JSON string (proxy only)").option("--query <json>", "Query params as JSON string (proxy only)").option("--key <key>", "API key to use (setup only)").option("--force", "Force re-setup even if key exists (setup only)").option("--json", "Output raw JSON instead of formatted display").option("--locale <locale>", "Locale for vidcap summary/caption (default: en)").option("--max-results <n>", "Max results for vidcap search").option("--second <s>", "Timestamp in seconds for vidcap screenshot").option("--order <order>", "Sort order for vidcap comments (time/relevance)").option("--format <fmt>", "Summary format for reviewweb (bullet/paragraph)").option("--max-length <n>", "Max summary length for reviewweb").option("--instructions <text>", "Extraction instructions for reviewweb extract").option("--template <json>", "JSON template for reviewweb extract").option("--type <type>", "Link type filter for reviewweb links (web/image/file/all)").option("--country <code>", "Country code for reviewweb SEO commands").action(async (action, service, path12, options2) => {
|
|
77654
77811
|
await apiCommand(action, service, path12, options2);
|
|
77655
77812
|
});
|
|
77656
|
-
cli.command("artifact [action] [target]", "Manage Takumi artifacts (upload <file> | download <uuid|url> | delete <uuid|url>)").option("--id <uuid|url>", "Existing artifact (UUID or viewer URL) to overwrite on upload").option("--title <title>", "Display title for the artifact (max 200 chars)").option("-m, --message <message>", "Short note describing this version's change (max 100 chars)").option("-o, --output <dir>", "(download) Output directory; default: slug(title) or uuid in CWD").option("
|
|
77657
|
-
const version3 = opts.
|
|
77813
|
+
cli.command("artifact [action] [target]", "Manage Takumi artifacts (upload <file> | download <uuid|url> | delete <uuid|url>)").option("--id <uuid|url>", "Existing artifact (UUID or viewer URL) to overwrite on upload").option("--title <title>", "Display title for the artifact (max 200 chars)").option("-m, --message <message>", "Short note describing this version's change (max 100 chars)").option("-o, --output <dir>", "(download) Output directory; default: slug(title) or uuid in CWD").option("--ver <n>", "Version number (download: download it; delete: delete only that version)").option("--force", "(download) Allow writing into a non-empty directory").option("-y, --yes", "Skip delete confirmation prompt").action(async (action, target, opts) => {
|
|
77814
|
+
const version3 = opts.ver !== undefined ? Number.parseInt(String(opts.ver), 10) : undefined;
|
|
77815
|
+
if (version3 !== undefined && (!Number.isInteger(version3) || version3 < 1)) {
|
|
77816
|
+
console.error(`Invalid version: ${opts.ver}. Use a positive integer, e.g. --ver 2`);
|
|
77817
|
+
process.exitCode = 1;
|
|
77818
|
+
return;
|
|
77819
|
+
}
|
|
77658
77820
|
await artifactCommand(action, target, { ...opts, version: version3 });
|
|
77659
77821
|
});
|
|
77660
77822
|
cli.command("auth [action]", "Sign in/out, refresh, and check Takumi session (login|logout|refresh|status)").option("--json", "Machine-readable JSON output (status, refresh)").option("-f, --force", "Force a token refresh even when the current token is still valid (refresh only)").action(async (action, options2 = {}) => {
|