@sunasteriskrnd/takumi 1.0.0-dev.62 → 1.0.0-dev.63
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 +975 -438
- 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: "1.0.0-dev.
|
|
19818
|
+
version: "1.0.0-dev.63",
|
|
19819
19819
|
description: "CLI tool for bootstrapping and managing Takumi projects",
|
|
19820
19820
|
type: "module",
|
|
19821
19821
|
repository: {
|
|
@@ -20012,7 +20012,7 @@ function getLegacyManifestPath(providerRoot) {
|
|
|
20012
20012
|
return join4(providerRoot, LEGACY_MANIFEST_FILENAME);
|
|
20013
20013
|
}
|
|
20014
20014
|
function getCliVersion() {
|
|
20015
|
-
return "1.0.0-dev.
|
|
20015
|
+
return "1.0.0-dev.63"?.trim() || process.env.npm_package_version?.trim() || "unknown";
|
|
20016
20016
|
}
|
|
20017
20017
|
function getCliUserAgent() {
|
|
20018
20018
|
return `${TAKUMI_CLI_NPM_PACKAGE_NAME}/${getCliVersion()}`;
|
|
@@ -51580,14 +51580,127 @@ var init_artifact_action_help = __esm(() => {
|
|
|
51580
51580
|
};
|
|
51581
51581
|
});
|
|
51582
51582
|
|
|
51583
|
+
// src/domains/help/commands/artifact-comments-help.ts
|
|
51584
|
+
var artifactCommentsHelp;
|
|
51585
|
+
var init_artifact_comments_help = __esm(() => {
|
|
51586
|
+
artifactCommentsHelp = {
|
|
51587
|
+
name: "artifact comments",
|
|
51588
|
+
description: "Read and act on an artifact's review comments (list|reply|solve|reopen|delete)",
|
|
51589
|
+
usage: "tkm artifact comments <list|reply|solve|reopen|delete> <uuid|url> [id] [options]",
|
|
51590
|
+
examples: [
|
|
51591
|
+
{
|
|
51592
|
+
command: "tkm artifact comments list <uuid|url>",
|
|
51593
|
+
description: "List unresolved threads grouped by file (default --status open)"
|
|
51594
|
+
},
|
|
51595
|
+
{
|
|
51596
|
+
command: "tkm artifact comments list <uuid|url> --status all --json",
|
|
51597
|
+
description: "Every thread, resolved included, as machine-readable JSON"
|
|
51598
|
+
},
|
|
51599
|
+
{
|
|
51600
|
+
command: "tkm artifact comments reply <uuid|url> <comment-id> -m 'fixed in v4'",
|
|
51601
|
+
description: "Append a reply to the thread that comment belongs to"
|
|
51602
|
+
},
|
|
51603
|
+
{
|
|
51604
|
+
command: "tkm artifact comments solve <uuid|url> <thread-id>",
|
|
51605
|
+
description: "Mark a whole thread solved (reopen undoes it)"
|
|
51606
|
+
}
|
|
51607
|
+
],
|
|
51608
|
+
optionGroups: [
|
|
51609
|
+
{
|
|
51610
|
+
title: "Verbs",
|
|
51611
|
+
options: [
|
|
51612
|
+
{
|
|
51613
|
+
flags: "list <uuid|url>",
|
|
51614
|
+
description: "List threads with their comments; defaults to unresolved only"
|
|
51615
|
+
},
|
|
51616
|
+
{
|
|
51617
|
+
flags: "reply <uuid|url> <comment-id>",
|
|
51618
|
+
description: "Append a reply to the thread containing <comment-id>"
|
|
51619
|
+
},
|
|
51620
|
+
{
|
|
51621
|
+
flags: "solve <uuid|url> <thread-id>",
|
|
51622
|
+
description: "Mark the whole thread solved"
|
|
51623
|
+
},
|
|
51624
|
+
{
|
|
51625
|
+
flags: "reopen <uuid|url> <thread-id>",
|
|
51626
|
+
description: "Reopen a solved thread"
|
|
51627
|
+
},
|
|
51628
|
+
{
|
|
51629
|
+
flags: "delete <uuid|url> <comment-id>",
|
|
51630
|
+
description: "Delete one of your own comments. Deleting a thread's first comment removes the whole thread"
|
|
51631
|
+
}
|
|
51632
|
+
]
|
|
51633
|
+
},
|
|
51634
|
+
{
|
|
51635
|
+
title: "List options",
|
|
51636
|
+
options: [
|
|
51637
|
+
{
|
|
51638
|
+
flags: "--status <open|solved|all>",
|
|
51639
|
+
description: "Which threads to return (default: open)"
|
|
51640
|
+
},
|
|
51641
|
+
{
|
|
51642
|
+
flags: "--author <author>",
|
|
51643
|
+
description: "Keep threads with a comment by this user (name, email, or user id)"
|
|
51644
|
+
},
|
|
51645
|
+
{
|
|
51646
|
+
flags: "--limit <n>",
|
|
51647
|
+
description: "Threads per page, max 100 (default: 20)"
|
|
51648
|
+
},
|
|
51649
|
+
{
|
|
51650
|
+
flags: "--cursor <cursor>",
|
|
51651
|
+
description: "Fetch the next page, using next_cursor from the previous --json response"
|
|
51652
|
+
}
|
|
51653
|
+
]
|
|
51654
|
+
},
|
|
51655
|
+
{
|
|
51656
|
+
title: "Reply options",
|
|
51657
|
+
options: [
|
|
51658
|
+
{
|
|
51659
|
+
flags: "-m, --message <message>",
|
|
51660
|
+
description: "Comment body (max 4096 bytes). Mutually exclusive with --file"
|
|
51661
|
+
},
|
|
51662
|
+
{
|
|
51663
|
+
flags: "--file <path>",
|
|
51664
|
+
description: "Read the comment body from this file instead of --message"
|
|
51665
|
+
}
|
|
51666
|
+
]
|
|
51667
|
+
},
|
|
51668
|
+
{
|
|
51669
|
+
title: "Shared options",
|
|
51670
|
+
options: [
|
|
51671
|
+
{
|
|
51672
|
+
flags: "--json",
|
|
51673
|
+
description: "Machine-readable JSON output"
|
|
51674
|
+
},
|
|
51675
|
+
{
|
|
51676
|
+
flags: "--quiet",
|
|
51677
|
+
description: "Print only ids, one per line — thread ids for list, the acted-on id otherwise"
|
|
51678
|
+
},
|
|
51679
|
+
{
|
|
51680
|
+
flags: "-y, --yes",
|
|
51681
|
+
description: "(delete) Skip the confirmation prompt"
|
|
51682
|
+
}
|
|
51683
|
+
]
|
|
51684
|
+
}
|
|
51685
|
+
],
|
|
51686
|
+
sections: [
|
|
51687
|
+
{
|
|
51688
|
+
title: "Notes",
|
|
51689
|
+
content: "Threads are created in the artifact viewer, not from the CLI — a thread needs a pin position that only the rendered page can supply. Comments are printed to stdout and never written into a downloaded artifact folder, so a re-upload cannot push them back as artifact content."
|
|
51690
|
+
}
|
|
51691
|
+
]
|
|
51692
|
+
};
|
|
51693
|
+
});
|
|
51694
|
+
|
|
51583
51695
|
// src/domains/help/commands/artifact-command-help.ts
|
|
51584
51696
|
var artifactCommandHelp;
|
|
51585
51697
|
var init_artifact_command_help = __esm(() => {
|
|
51586
51698
|
init_artifact_action_help();
|
|
51699
|
+
init_artifact_comments_help();
|
|
51587
51700
|
artifactCommandHelp = {
|
|
51588
51701
|
name: "artifact",
|
|
51589
|
-
description: "List, search, upload, download, and delete Takumi artifacts
|
|
51590
|
-
usage: "tkm artifact <list | search <term> | upload <file|dir> | download <uuid|url> | delete <uuid|url
|
|
51702
|
+
description: "List, search, upload, download, and delete Takumi artifacts, and work with their review comments",
|
|
51703
|
+
usage: "tkm artifact <list | search <term> | upload <file|dir> | download <uuid|url> | delete <uuid|url> | comments <verb> <uuid|url> [id]>",
|
|
51591
51704
|
examples: [
|
|
51592
51705
|
{
|
|
51593
51706
|
command: "tkm artifact upload ./report.html --title 'Weekly Report'",
|
|
@@ -51625,6 +51738,10 @@ var init_artifact_command_help = __esm(() => {
|
|
|
51625
51738
|
{
|
|
51626
51739
|
flags: "delete <uuid|url>",
|
|
51627
51740
|
description: "Soft-delete the whole artifact, or one version with --ver <n>"
|
|
51741
|
+
},
|
|
51742
|
+
{
|
|
51743
|
+
flags: "comments <verb> <uuid|url> [id]",
|
|
51744
|
+
description: "Read and act on review comments (list|reply|solve|reopen|delete)"
|
|
51628
51745
|
}
|
|
51629
51746
|
]
|
|
51630
51747
|
}
|
|
@@ -51640,7 +51757,8 @@ var init_artifact_command_help = __esm(() => {
|
|
|
51640
51757
|
search: artifactSearchHelp,
|
|
51641
51758
|
upload: artifactUploadHelp,
|
|
51642
51759
|
download: artifactDownloadHelp,
|
|
51643
|
-
delete: artifactDeleteHelp
|
|
51760
|
+
delete: artifactDeleteHelp,
|
|
51761
|
+
comments: artifactCommentsHelp
|
|
51644
51762
|
}
|
|
51645
51763
|
};
|
|
51646
51764
|
});
|
|
@@ -51722,6 +51840,7 @@ var init_commands2 = __esm(() => {
|
|
|
51722
51840
|
init_config_command_help();
|
|
51723
51841
|
init_auth_command_help();
|
|
51724
51842
|
init_artifact_command_help();
|
|
51843
|
+
init_artifact_comments_help();
|
|
51725
51844
|
init_artifact_action_help();
|
|
51726
51845
|
init_mcp_command_help();
|
|
51727
51846
|
init_common_options();
|
|
@@ -53848,8 +53967,48 @@ function showApiHelp() {
|
|
|
53848
53967
|
console.log(" takumi api reviewweb seo-backlinks <domain> SEO backlinks");
|
|
53849
53968
|
console.log();
|
|
53850
53969
|
}
|
|
53851
|
-
// src/commands/artifact/
|
|
53852
|
-
|
|
53970
|
+
// src/commands/artifact/refs.ts
|
|
53971
|
+
init_auth_client();
|
|
53972
|
+
var UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
53973
|
+
function isArtifactUuid(id) {
|
|
53974
|
+
return UUID_V4_RE.test(id.trim());
|
|
53975
|
+
}
|
|
53976
|
+
function parseArtifactRef(input) {
|
|
53977
|
+
const s = input.trim();
|
|
53978
|
+
if (UUID_V4_RE.test(s))
|
|
53979
|
+
return s.toLowerCase();
|
|
53980
|
+
const m2 = s.match(/\/artifacts\/([^/?#]+)/i);
|
|
53981
|
+
const candidate = m2?.[1] ?? "";
|
|
53982
|
+
return UUID_V4_RE.test(candidate) ? candidate.toLowerCase() : null;
|
|
53983
|
+
}
|
|
53984
|
+
function extractVersionFromRef(ref) {
|
|
53985
|
+
try {
|
|
53986
|
+
const url = new URL(ref.trim());
|
|
53987
|
+
const v2 = url.searchParams.get("v");
|
|
53988
|
+
if (v2 !== null) {
|
|
53989
|
+
const n = Number.parseInt(v2, 10);
|
|
53990
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
53991
|
+
}
|
|
53992
|
+
} catch {}
|
|
53993
|
+
return;
|
|
53994
|
+
}
|
|
53995
|
+
function warnIfHostMismatch(input) {
|
|
53996
|
+
let inputUrl;
|
|
53997
|
+
try {
|
|
53998
|
+
inputUrl = new URL(input.trim());
|
|
53999
|
+
} catch {
|
|
54000
|
+
return;
|
|
54001
|
+
}
|
|
54002
|
+
let serverHost;
|
|
54003
|
+
try {
|
|
54004
|
+
serverHost = new URL(getServerUrl()).host;
|
|
54005
|
+
} catch {
|
|
54006
|
+
return;
|
|
54007
|
+
}
|
|
54008
|
+
if (inputUrl.host !== serverHost) {
|
|
54009
|
+
console.warn(`Warning: URL host "${inputUrl.host}" differs from the configured server "${serverHost}". ` + `Operating against ${serverHost} (set TAKUMI_SERVER_URL to target another environment).`);
|
|
54010
|
+
}
|
|
54011
|
+
}
|
|
53853
54012
|
|
|
53854
54013
|
// src/domains/artifact/artifact-client.ts
|
|
53855
54014
|
init_auth_client();
|
|
@@ -53866,7 +54025,7 @@ class ArtifactApiError extends Error {
|
|
|
53866
54025
|
async function parseErrorMessage(res) {
|
|
53867
54026
|
try {
|
|
53868
54027
|
const body = await res.json();
|
|
53869
|
-
return body.error ?? res.statusText;
|
|
54028
|
+
return body.error ?? body.message ?? res.statusText;
|
|
53870
54029
|
} catch {
|
|
53871
54030
|
return res.statusText;
|
|
53872
54031
|
}
|
|
@@ -54011,10 +54170,449 @@ async function listArtifacts(token, params = {}) {
|
|
|
54011
54170
|
return payload;
|
|
54012
54171
|
}
|
|
54013
54172
|
|
|
54173
|
+
// src/domains/artifact/comment-client.ts
|
|
54174
|
+
init_auth_client();
|
|
54175
|
+
class CommentsUnsupportedError extends Error {
|
|
54176
|
+
}
|
|
54177
|
+
var UNSUPPORTED_MESSAGE = "this Takumi server does not support artifact comments (needs a newer server version)";
|
|
54178
|
+
async function failFor(verb, res) {
|
|
54179
|
+
if (res.status === 404) {
|
|
54180
|
+
let body;
|
|
54181
|
+
try {
|
|
54182
|
+
body = await res.clone().json();
|
|
54183
|
+
} catch {
|
|
54184
|
+
body = undefined;
|
|
54185
|
+
}
|
|
54186
|
+
if (body?.error !== "not_found" && body?.message !== "not_found") {
|
|
54187
|
+
throw new CommentsUnsupportedError(UNSUPPORTED_MESSAGE);
|
|
54188
|
+
}
|
|
54189
|
+
}
|
|
54190
|
+
throw new ArtifactApiError(res.status, `${verb} failed (HTTP ${res.status}): ${await parseErrorMessage(res)}`);
|
|
54191
|
+
}
|
|
54192
|
+
async function parseJsonPayload(verb, res, url, isValid2) {
|
|
54193
|
+
let payload;
|
|
54194
|
+
try {
|
|
54195
|
+
payload = await res.json();
|
|
54196
|
+
} catch {
|
|
54197
|
+
throw new ArtifactApiError(res.status, `${verb} failed (HTTP ${res.status}): non-JSON response from ${url}`);
|
|
54198
|
+
}
|
|
54199
|
+
if (!isValid2(payload)) {
|
|
54200
|
+
throw new ArtifactApiError(res.status, `${verb} failed (HTTP ${res.status}): unexpected response shape from ${url}`);
|
|
54201
|
+
}
|
|
54202
|
+
return payload;
|
|
54203
|
+
}
|
|
54204
|
+
function hasId(value) {
|
|
54205
|
+
return typeof value?.id === "string";
|
|
54206
|
+
}
|
|
54207
|
+
async function listComments(token, uuid, params = {}) {
|
|
54208
|
+
const base = getServerUrl();
|
|
54209
|
+
const qs = new URLSearchParams;
|
|
54210
|
+
if (params.status !== undefined)
|
|
54211
|
+
qs.set("status", params.status);
|
|
54212
|
+
if (params.author !== undefined)
|
|
54213
|
+
qs.set("author", params.author);
|
|
54214
|
+
if (params.limit !== undefined)
|
|
54215
|
+
qs.set("limit", String(params.limit));
|
|
54216
|
+
if (params.cursor !== undefined)
|
|
54217
|
+
qs.set("cursor", params.cursor);
|
|
54218
|
+
const query = qs.toString();
|
|
54219
|
+
const url = `${base}/api/artifacts/${encodeURIComponent(uuid)}/comments${query ? `?${query}` : ""}`;
|
|
54220
|
+
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
|
|
54221
|
+
if (!res.ok)
|
|
54222
|
+
await failFor("List comments", res);
|
|
54223
|
+
const payload = await parseJsonPayload("List comments", res, url, (value) => Array.isArray(value?.threads));
|
|
54224
|
+
return { ...payload, next_cursor: payload.next_cursor ?? null };
|
|
54225
|
+
}
|
|
54226
|
+
async function replyToComment(token, uuid, commentId, body) {
|
|
54227
|
+
const base = getServerUrl();
|
|
54228
|
+
const url = `${base}/api/artifacts/${encodeURIComponent(uuid)}/comments/${encodeURIComponent(commentId)}/replies`;
|
|
54229
|
+
const res = await fetch(url, {
|
|
54230
|
+
method: "POST",
|
|
54231
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
54232
|
+
body: JSON.stringify({ body })
|
|
54233
|
+
});
|
|
54234
|
+
if (!res.ok)
|
|
54235
|
+
await failFor("Reply", res);
|
|
54236
|
+
return parseJsonPayload("Reply", res, url, hasId);
|
|
54237
|
+
}
|
|
54238
|
+
async function setThreadSolved(token, uuid, threadId, solved) {
|
|
54239
|
+
const base = getServerUrl();
|
|
54240
|
+
const verb = solved ? "Solve" : "Reopen";
|
|
54241
|
+
const url = `${base}/api/artifacts/${encodeURIComponent(uuid)}/comment-threads/${encodeURIComponent(threadId)}`;
|
|
54242
|
+
const res = await fetch(url, {
|
|
54243
|
+
method: "PATCH",
|
|
54244
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
54245
|
+
body: JSON.stringify({ solved })
|
|
54246
|
+
});
|
|
54247
|
+
if (!res.ok)
|
|
54248
|
+
await failFor(verb, res);
|
|
54249
|
+
return parseJsonPayload(verb, res, url, hasId);
|
|
54250
|
+
}
|
|
54251
|
+
async function deleteComment(token, uuid, commentId) {
|
|
54252
|
+
const base = getServerUrl();
|
|
54253
|
+
const res = await fetch(`${base}/api/artifacts/${encodeURIComponent(uuid)}/comments/${encodeURIComponent(commentId)}`, { method: "DELETE", headers: { Authorization: `Bearer ${token}` } });
|
|
54254
|
+
if (!res.ok)
|
|
54255
|
+
await failFor("Delete comment", res);
|
|
54256
|
+
const scope = res.headers.get("X-Deleted-Scope");
|
|
54257
|
+
return { scope: scope === "thread" ? "thread" : "comment" };
|
|
54258
|
+
}
|
|
54259
|
+
|
|
54260
|
+
// src/commands/artifact/comments/list-comments-command.ts
|
|
54261
|
+
init_logger();
|
|
54262
|
+
|
|
54263
|
+
// src/commands/artifact/command-helpers.ts
|
|
54264
|
+
init_auth_client();
|
|
54265
|
+
async function getToken(opts) {
|
|
54266
|
+
try {
|
|
54267
|
+
return await ensureAuthenticated({ ...opts._authOpts });
|
|
54268
|
+
} catch (err) {
|
|
54269
|
+
if (err instanceof NotLoggedInError) {
|
|
54270
|
+
console.error(`Error: ${err.message}`);
|
|
54271
|
+
process.exitCode = 1;
|
|
54272
|
+
return null;
|
|
54273
|
+
}
|
|
54274
|
+
throw err;
|
|
54275
|
+
}
|
|
54276
|
+
}
|
|
54277
|
+
function printApiError(err) {
|
|
54278
|
+
console.error(err instanceof ArtifactApiError ? err.message : `Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
54279
|
+
}
|
|
54280
|
+
|
|
54281
|
+
// src/commands/artifact/comments/comment-tree-render.ts
|
|
54282
|
+
init_output_sanitizer();
|
|
54283
|
+
|
|
54284
|
+
// src/shared/relative-time.ts
|
|
54285
|
+
function formatRelativeTime(iso, now = Date.now()) {
|
|
54286
|
+
const then = Date.parse(iso);
|
|
54287
|
+
if (Number.isNaN(then))
|
|
54288
|
+
return "—";
|
|
54289
|
+
const diffMs = Math.max(0, now - then);
|
|
54290
|
+
const diffSec = Math.floor(diffMs / 1000);
|
|
54291
|
+
if (diffSec < 60)
|
|
54292
|
+
return "just now";
|
|
54293
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
54294
|
+
if (diffMin < 60)
|
|
54295
|
+
return `${diffMin}m ago`;
|
|
54296
|
+
const diffHour = Math.floor(diffMin / 60);
|
|
54297
|
+
if (diffHour < 24)
|
|
54298
|
+
return `${diffHour}h ago`;
|
|
54299
|
+
const diffDay = Math.floor(diffHour / 24);
|
|
54300
|
+
if (diffDay < 30)
|
|
54301
|
+
return `${diffDay}d ago`;
|
|
54302
|
+
const diffMonth = Math.floor(diffDay / 30);
|
|
54303
|
+
if (diffMonth < 12)
|
|
54304
|
+
return `${diffMonth}mo ago`;
|
|
54305
|
+
const diffYear = Math.floor(diffMonth / 12);
|
|
54306
|
+
return `${diffYear}y ago`;
|
|
54307
|
+
}
|
|
54308
|
+
|
|
54309
|
+
// src/commands/artifact/comments/comment-tree-render.ts
|
|
54310
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
54311
|
+
var clean = sanitizeTerminalText;
|
|
54312
|
+
function statusTag(status) {
|
|
54313
|
+
return status === "solved" ? import_picocolors16.default.dim(import_picocolors16.default.green("[SOLVED]")) : import_picocolors16.default.yellow("[OPEN]");
|
|
54314
|
+
}
|
|
54315
|
+
function authorLine(comment, now) {
|
|
54316
|
+
const name = clean(comment.author_display_name ?? "").trim() || "unknown";
|
|
54317
|
+
const time = formatRelativeTime(comment.created_at, now);
|
|
54318
|
+
const edited = comment.edited_at ? " (edited)" : "";
|
|
54319
|
+
return `${name} · ${time}${edited}`;
|
|
54320
|
+
}
|
|
54321
|
+
function renderComment(comment, isLast, now) {
|
|
54322
|
+
const branch = isLast ? "└─" : "├─";
|
|
54323
|
+
const continuation = isLast ? " " : "│ ";
|
|
54324
|
+
const bodyLines = clean(comment.body ?? "").split(`
|
|
54325
|
+
`).map((line) => `${continuation}${line}`);
|
|
54326
|
+
return [`${branch} ${authorLine(comment, now)}`, ...bodyLines].join(`
|
|
54327
|
+
`);
|
|
54328
|
+
}
|
|
54329
|
+
function renderThread(thread, now) {
|
|
54330
|
+
const header = `Thread ${clean(thread.id)} ${statusTag(thread.status)}`;
|
|
54331
|
+
const comments = Array.isArray(thread.comments) ? thread.comments : [];
|
|
54332
|
+
const rows = comments.map((comment, idx) => renderComment(comment, idx === comments.length - 1, now));
|
|
54333
|
+
return [header, ...rows].join(`
|
|
54334
|
+
`);
|
|
54335
|
+
}
|
|
54336
|
+
function renderThreadGroups(threads, now) {
|
|
54337
|
+
const byFile = new Map;
|
|
54338
|
+
for (const thread of threads) {
|
|
54339
|
+
const bucket = byFile.get(thread.file_path);
|
|
54340
|
+
if (bucket)
|
|
54341
|
+
bucket.push(thread);
|
|
54342
|
+
else
|
|
54343
|
+
byFile.set(thread.file_path, [thread]);
|
|
54344
|
+
}
|
|
54345
|
+
const groups = [];
|
|
54346
|
+
for (const [file, bucket] of byFile) {
|
|
54347
|
+
groups.push(`${clean(file)}
|
|
54348
|
+
|
|
54349
|
+
${bucket.map((t) => renderThread(t, now)).join(`
|
|
54350
|
+
|
|
54351
|
+
`)}`);
|
|
54352
|
+
}
|
|
54353
|
+
return groups.join(`
|
|
54354
|
+
|
|
54355
|
+
`);
|
|
54356
|
+
}
|
|
54357
|
+
function renderQuietIds(threads) {
|
|
54358
|
+
return threads.map((t) => clean(t.id)).join(`
|
|
54359
|
+
`);
|
|
54360
|
+
}
|
|
54361
|
+
|
|
54362
|
+
// src/commands/artifact/comments/list-comments-command.ts
|
|
54363
|
+
var STATUS_VALUES = ["open", "solved", "all"];
|
|
54364
|
+
function isStatusValue(value) {
|
|
54365
|
+
return STATUS_VALUES.includes(value);
|
|
54366
|
+
}
|
|
54367
|
+
function emptyMessage(status, author) {
|
|
54368
|
+
if (status === "open" && !author)
|
|
54369
|
+
return "No open comments.";
|
|
54370
|
+
const parts = [`--status ${status}`];
|
|
54371
|
+
if (author)
|
|
54372
|
+
parts.push(`--author ${author}`);
|
|
54373
|
+
return `No comments found for ${parts.join(" ")}.`;
|
|
54374
|
+
}
|
|
54375
|
+
function footerLine(payload) {
|
|
54376
|
+
const base = `${payload.threads.length} threads`;
|
|
54377
|
+
return payload.next_cursor != null ? `${base} · use --cursor ${payload.next_cursor} for the next page` : base;
|
|
54378
|
+
}
|
|
54379
|
+
async function listCommentsCommand(uuid, opts) {
|
|
54380
|
+
const status = opts.status ?? "open";
|
|
54381
|
+
if (!isStatusValue(status)) {
|
|
54382
|
+
console.error(`Invalid --status: ${status}. Use one of: ${STATUS_VALUES.join(", ")}`);
|
|
54383
|
+
process.exitCode = 1;
|
|
54384
|
+
return;
|
|
54385
|
+
}
|
|
54386
|
+
const token = await getToken(opts);
|
|
54387
|
+
if (!token)
|
|
54388
|
+
return;
|
|
54389
|
+
let payload;
|
|
54390
|
+
try {
|
|
54391
|
+
payload = await listComments(token, uuid, {
|
|
54392
|
+
status,
|
|
54393
|
+
author: opts.author,
|
|
54394
|
+
limit: opts.limit,
|
|
54395
|
+
cursor: opts.cursor
|
|
54396
|
+
});
|
|
54397
|
+
} catch (err) {
|
|
54398
|
+
if (err instanceof CommentsUnsupportedError) {
|
|
54399
|
+
console.error(`Error: ${err.message}`);
|
|
54400
|
+
process.exitCode = 1;
|
|
54401
|
+
return;
|
|
54402
|
+
}
|
|
54403
|
+
if (err instanceof ArtifactApiError && err.status === 404) {
|
|
54404
|
+
console.error("Error: artifact not found, or you do not have comment access to it.");
|
|
54405
|
+
process.exitCode = 1;
|
|
54406
|
+
return;
|
|
54407
|
+
}
|
|
54408
|
+
printApiError(err);
|
|
54409
|
+
process.exitCode = 1;
|
|
54410
|
+
return;
|
|
54411
|
+
}
|
|
54412
|
+
if (opts.json) {
|
|
54413
|
+
process.stdout.write(`${JSON.stringify(payload)}
|
|
54414
|
+
`);
|
|
54415
|
+
return;
|
|
54416
|
+
}
|
|
54417
|
+
if (opts.quiet) {
|
|
54418
|
+
const ids = renderQuietIds(payload.threads);
|
|
54419
|
+
if (ids)
|
|
54420
|
+
process.stdout.write(`${ids}
|
|
54421
|
+
`);
|
|
54422
|
+
if (payload.next_cursor != null) {
|
|
54423
|
+
console.error(`Note: more threads remain — rerun with --cursor ${payload.next_cursor} for the next page.`);
|
|
54424
|
+
}
|
|
54425
|
+
return;
|
|
54426
|
+
}
|
|
54427
|
+
if (payload.threads.length === 0) {
|
|
54428
|
+
logger.info(opts.cursor ? "No further comments on this page." : emptyMessage(status, opts.author));
|
|
54429
|
+
return;
|
|
54430
|
+
}
|
|
54431
|
+
process.stdout.write(`${renderThreadGroups(payload.threads, Date.now())}
|
|
54432
|
+
|
|
54433
|
+
`);
|
|
54434
|
+
logger.info(footerLine(payload));
|
|
54435
|
+
}
|
|
54436
|
+
|
|
54437
|
+
// src/commands/artifact/comments/mutate-comments-command.ts
|
|
54438
|
+
import { promises as fs9 } from "node:fs";
|
|
54439
|
+
init_dist2();
|
|
54440
|
+
async function resolveReplyBody(opts) {
|
|
54441
|
+
if (opts.message !== undefined && opts.file !== undefined) {
|
|
54442
|
+
console.error("Use either --message or --file, not both.");
|
|
54443
|
+
process.exitCode = 1;
|
|
54444
|
+
return null;
|
|
54445
|
+
}
|
|
54446
|
+
if (opts.message === undefined && opts.file === undefined) {
|
|
54447
|
+
console.error("Usage: tkm artifact comments reply <ref> <commentId> (--message <text> | --file <path>)");
|
|
54448
|
+
process.exitCode = 1;
|
|
54449
|
+
return null;
|
|
54450
|
+
}
|
|
54451
|
+
if (Array.isArray(opts.message) || Array.isArray(opts.file)) {
|
|
54452
|
+
console.error("Pass --message (or --file) once, not repeated.");
|
|
54453
|
+
process.exitCode = 1;
|
|
54454
|
+
return null;
|
|
54455
|
+
}
|
|
54456
|
+
let raw;
|
|
54457
|
+
if (opts.file !== undefined) {
|
|
54458
|
+
const path6 = String(opts.file);
|
|
54459
|
+
try {
|
|
54460
|
+
raw = await fs9.readFile(path6, "utf8");
|
|
54461
|
+
} catch (err) {
|
|
54462
|
+
console.error(`Error: could not read --file "${path6}": ${err instanceof Error ? err.message : String(err)}`);
|
|
54463
|
+
process.exitCode = 1;
|
|
54464
|
+
return null;
|
|
54465
|
+
}
|
|
54466
|
+
} else {
|
|
54467
|
+
raw = String(opts.message);
|
|
54468
|
+
}
|
|
54469
|
+
const trimmed = raw.trim();
|
|
54470
|
+
if (trimmed.length === 0) {
|
|
54471
|
+
console.error("Error: comment body is empty.");
|
|
54472
|
+
process.exitCode = 1;
|
|
54473
|
+
return null;
|
|
54474
|
+
}
|
|
54475
|
+
return trimmed;
|
|
54476
|
+
}
|
|
54477
|
+
function emitResult(opts, json, id, human) {
|
|
54478
|
+
if (opts.json)
|
|
54479
|
+
process.stdout.write(`${JSON.stringify(json)}
|
|
54480
|
+
`);
|
|
54481
|
+
else if (opts.quiet)
|
|
54482
|
+
process.stdout.write(`${id}
|
|
54483
|
+
`);
|
|
54484
|
+
else
|
|
54485
|
+
console.log(human);
|
|
54486
|
+
}
|
|
54487
|
+
async function runReply(uuid, commentId, opts) {
|
|
54488
|
+
const body = await resolveReplyBody(opts);
|
|
54489
|
+
if (body === null)
|
|
54490
|
+
return;
|
|
54491
|
+
const token = await getToken(opts);
|
|
54492
|
+
if (!token)
|
|
54493
|
+
return;
|
|
54494
|
+
try {
|
|
54495
|
+
const comment = await replyToComment(token, uuid, commentId, body);
|
|
54496
|
+
const suffix = opts.file ? ` (${Buffer.byteLength(body, "utf8")} bytes from ${opts.file})` : "";
|
|
54497
|
+
emitResult(opts, comment, comment.id, `Replied to thread with comment ${comment.id}${suffix}.`);
|
|
54498
|
+
} catch (err) {
|
|
54499
|
+
printApiError(err);
|
|
54500
|
+
process.exitCode = 1;
|
|
54501
|
+
}
|
|
54502
|
+
}
|
|
54503
|
+
async function runSolveOrReopen(uuid, threadId, solved, opts) {
|
|
54504
|
+
const token = await getToken(opts);
|
|
54505
|
+
if (!token)
|
|
54506
|
+
return;
|
|
54507
|
+
try {
|
|
54508
|
+
const thread = await setThreadSolved(token, uuid, threadId, solved);
|
|
54509
|
+
const status = thread.status ?? (solved ? "solved" : "open");
|
|
54510
|
+
emitResult(opts, thread, thread.id, `Thread ${thread.id} marked ${status}.`);
|
|
54511
|
+
} catch (err) {
|
|
54512
|
+
printApiError(err);
|
|
54513
|
+
process.exitCode = 1;
|
|
54514
|
+
}
|
|
54515
|
+
}
|
|
54516
|
+
async function runDelete(uuid, commentId, opts) {
|
|
54517
|
+
const token = await getToken(opts);
|
|
54518
|
+
if (!token)
|
|
54519
|
+
return;
|
|
54520
|
+
if (!opts.yes) {
|
|
54521
|
+
const confirmed = await se({
|
|
54522
|
+
message: `Delete comment ${commentId}? This cannot be undone.`,
|
|
54523
|
+
initialValue: false
|
|
54524
|
+
});
|
|
54525
|
+
if (lD(confirmed) || !confirmed) {
|
|
54526
|
+
console.log("Cancelled.");
|
|
54527
|
+
return;
|
|
54528
|
+
}
|
|
54529
|
+
}
|
|
54530
|
+
try {
|
|
54531
|
+
const { scope } = await deleteComment(token, uuid, commentId);
|
|
54532
|
+
emitResult(opts, { id: commentId, deleted_scope: scope }, commentId, scope === "thread" ? "Deleted the root comment — the whole thread and its replies are gone." : `Deleted comment ${commentId}.`);
|
|
54533
|
+
} catch (err) {
|
|
54534
|
+
printApiError(err);
|
|
54535
|
+
process.exitCode = 1;
|
|
54536
|
+
}
|
|
54537
|
+
}
|
|
54538
|
+
async function mutateCommentsCommand(subverb, uuid, targetId, opts) {
|
|
54539
|
+
switch (subverb) {
|
|
54540
|
+
case "reply":
|
|
54541
|
+
await runReply(uuid, targetId, opts);
|
|
54542
|
+
break;
|
|
54543
|
+
case "solve":
|
|
54544
|
+
await runSolveOrReopen(uuid, targetId, true, opts);
|
|
54545
|
+
break;
|
|
54546
|
+
case "reopen":
|
|
54547
|
+
await runSolveOrReopen(uuid, targetId, false, opts);
|
|
54548
|
+
break;
|
|
54549
|
+
case "delete":
|
|
54550
|
+
await runDelete(uuid, targetId, opts);
|
|
54551
|
+
break;
|
|
54552
|
+
}
|
|
54553
|
+
}
|
|
54554
|
+
|
|
54555
|
+
// src/commands/artifact/comments/comments-command.ts
|
|
54556
|
+
var MUTATE_SUBVERBS = ["reply", "solve", "reopen", "delete"];
|
|
54557
|
+
function isMutateSubverb(value) {
|
|
54558
|
+
return MUTATE_SUBVERBS.includes(value);
|
|
54559
|
+
}
|
|
54560
|
+
function usageError(hint) {
|
|
54561
|
+
console.error(`Usage: ${hint}`);
|
|
54562
|
+
process.exitCode = 1;
|
|
54563
|
+
}
|
|
54564
|
+
function resolveRef(ref) {
|
|
54565
|
+
const uuid = parseArtifactRef(ref);
|
|
54566
|
+
if (!uuid) {
|
|
54567
|
+
console.error(`Invalid artifact id or URL: ${ref}`);
|
|
54568
|
+
process.exitCode = 1;
|
|
54569
|
+
return null;
|
|
54570
|
+
}
|
|
54571
|
+
warnIfHostMismatch(ref);
|
|
54572
|
+
return uuid;
|
|
54573
|
+
}
|
|
54574
|
+
async function commentsCommand(subverb, ref, targetId, opts) {
|
|
54575
|
+
if (subverb === undefined) {
|
|
54576
|
+
usageError("tkm artifact comments <list|reply|solve|reopen|delete> <ref> [id]");
|
|
54577
|
+
return;
|
|
54578
|
+
}
|
|
54579
|
+
if (subverb === "list") {
|
|
54580
|
+
if (!ref)
|
|
54581
|
+
return usageError("tkm artifact comments list <ref>");
|
|
54582
|
+
if (targetId) {
|
|
54583
|
+
return usageError("tkm artifact comments list <ref> (list takes no extra id)");
|
|
54584
|
+
}
|
|
54585
|
+
const uuid = resolveRef(ref);
|
|
54586
|
+
if (!uuid)
|
|
54587
|
+
return;
|
|
54588
|
+
await listCommentsCommand(uuid, opts);
|
|
54589
|
+
return;
|
|
54590
|
+
}
|
|
54591
|
+
if (isMutateSubverb(subverb)) {
|
|
54592
|
+
if (!ref || !targetId) {
|
|
54593
|
+
return usageError(`tkm artifact comments ${subverb} <ref> <id>`);
|
|
54594
|
+
}
|
|
54595
|
+
if (!isArtifactUuid(targetId)) {
|
|
54596
|
+
console.error(`Invalid comment/thread id: ${targetId}`);
|
|
54597
|
+
process.exitCode = 1;
|
|
54598
|
+
return;
|
|
54599
|
+
}
|
|
54600
|
+
const uuid = resolveRef(ref);
|
|
54601
|
+
if (!uuid)
|
|
54602
|
+
return;
|
|
54603
|
+
await mutateCommentsCommand(subverb, uuid, targetId.trim(), opts);
|
|
54604
|
+
return;
|
|
54605
|
+
}
|
|
54606
|
+
console.error(`Unknown comments subcommand: ${subverb}. Available: list, reply, solve, reopen, delete`);
|
|
54607
|
+
process.exitCode = 1;
|
|
54608
|
+
}
|
|
54609
|
+
// src/commands/artifact/delete-command.ts
|
|
54610
|
+
init_dist2();
|
|
54611
|
+
|
|
54014
54612
|
// src/domains/artifact/manifest-store.ts
|
|
54015
54613
|
init_logger();
|
|
54016
54614
|
init_paths2();
|
|
54017
|
-
import { promises as
|
|
54615
|
+
import { promises as fs10 } from "node:fs";
|
|
54018
54616
|
|
|
54019
54617
|
// src/domains/artifact/paths.ts
|
|
54020
54618
|
init_paths2();
|
|
@@ -54031,7 +54629,7 @@ function samePath(a3, b3) {
|
|
|
54031
54629
|
async function readManifest2() {
|
|
54032
54630
|
const path6 = getManifestPath2();
|
|
54033
54631
|
try {
|
|
54034
|
-
const raw = await
|
|
54632
|
+
const raw = await fs10.readFile(path6, "utf8");
|
|
54035
54633
|
const parsed = JSON.parse(raw);
|
|
54036
54634
|
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.entries)) {
|
|
54037
54635
|
logger.warning(`artifact-manifest: malformed manifest at ${path6}, using empty manifest`);
|
|
@@ -54049,17 +54647,17 @@ async function readManifest2() {
|
|
|
54049
54647
|
async function writeManifest2(manifest) {
|
|
54050
54648
|
const path6 = getManifestPath2();
|
|
54051
54649
|
const tmpPath = `${path6}.tmp`;
|
|
54052
|
-
await
|
|
54053
|
-
const fh = await
|
|
54650
|
+
await fs10.mkdir(getConfigDir(), { recursive: true, mode: 448 });
|
|
54651
|
+
const fh = await fs10.open(tmpPath, "w", 384);
|
|
54054
54652
|
try {
|
|
54055
54653
|
await fh.writeFile(JSON.stringify(manifest, null, 2), "utf8");
|
|
54056
54654
|
} finally {
|
|
54057
54655
|
await fh.close();
|
|
54058
54656
|
}
|
|
54059
54657
|
try {
|
|
54060
|
-
await
|
|
54658
|
+
await fs10.chmod(tmpPath, 384);
|
|
54061
54659
|
} catch {}
|
|
54062
|
-
await
|
|
54660
|
+
await fs10.rename(tmpPath, path6);
|
|
54063
54661
|
}
|
|
54064
54662
|
function lookupByPath(manifest, absPath) {
|
|
54065
54663
|
return manifest.entries.find((e2) => samePath(e2.localPath, absPath));
|
|
@@ -54081,64 +54679,6 @@ async function removeEntry(uuid) {
|
|
|
54081
54679
|
await writeManifest2(manifest);
|
|
54082
54680
|
}
|
|
54083
54681
|
|
|
54084
|
-
// src/commands/artifact/command-helpers.ts
|
|
54085
|
-
init_auth_client();
|
|
54086
|
-
async function getToken(opts) {
|
|
54087
|
-
try {
|
|
54088
|
-
return await ensureAuthenticated({ ...opts._authOpts });
|
|
54089
|
-
} catch (err) {
|
|
54090
|
-
if (err instanceof NotLoggedInError) {
|
|
54091
|
-
console.error(`Error: ${err.message}`);
|
|
54092
|
-
process.exitCode = 1;
|
|
54093
|
-
return null;
|
|
54094
|
-
}
|
|
54095
|
-
throw err;
|
|
54096
|
-
}
|
|
54097
|
-
}
|
|
54098
|
-
function printApiError(err) {
|
|
54099
|
-
console.error(err instanceof ArtifactApiError ? err.message : `Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
54100
|
-
}
|
|
54101
|
-
|
|
54102
|
-
// src/commands/artifact/refs.ts
|
|
54103
|
-
init_auth_client();
|
|
54104
|
-
var UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
54105
|
-
function parseArtifactRef(input) {
|
|
54106
|
-
const s = input.trim();
|
|
54107
|
-
if (UUID_V4_RE.test(s))
|
|
54108
|
-
return s.toLowerCase();
|
|
54109
|
-
const m2 = s.match(/\/artifacts\/([^/?#]+)/i);
|
|
54110
|
-
const candidate = m2?.[1] ?? "";
|
|
54111
|
-
return UUID_V4_RE.test(candidate) ? candidate.toLowerCase() : null;
|
|
54112
|
-
}
|
|
54113
|
-
function extractVersionFromRef(ref) {
|
|
54114
|
-
try {
|
|
54115
|
-
const url = new URL(ref.trim());
|
|
54116
|
-
const v2 = url.searchParams.get("v");
|
|
54117
|
-
if (v2 !== null) {
|
|
54118
|
-
const n = Number.parseInt(v2, 10);
|
|
54119
|
-
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
54120
|
-
}
|
|
54121
|
-
} catch {}
|
|
54122
|
-
return;
|
|
54123
|
-
}
|
|
54124
|
-
function warnIfHostMismatch(input) {
|
|
54125
|
-
let inputUrl;
|
|
54126
|
-
try {
|
|
54127
|
-
inputUrl = new URL(input.trim());
|
|
54128
|
-
} catch {
|
|
54129
|
-
return;
|
|
54130
|
-
}
|
|
54131
|
-
let serverHost;
|
|
54132
|
-
try {
|
|
54133
|
-
serverHost = new URL(getServerUrl()).host;
|
|
54134
|
-
} catch {
|
|
54135
|
-
return;
|
|
54136
|
-
}
|
|
54137
|
-
if (inputUrl.host !== serverHost) {
|
|
54138
|
-
console.warn(`Warning: URL host "${inputUrl.host}" differs from the configured server "${serverHost}". ` + `Operating against ${serverHost} (set TAKUMI_SERVER_URL to target another environment).`);
|
|
54139
|
-
}
|
|
54140
|
-
}
|
|
54141
|
-
|
|
54142
54682
|
// src/commands/artifact/delete-command.ts
|
|
54143
54683
|
async function artifactDelete(ref, opts) {
|
|
54144
54684
|
const uuid = parseArtifactRef(ref);
|
|
@@ -54208,11 +54748,11 @@ function isCannotDeleteLastVersion(err) {
|
|
|
54208
54748
|
}
|
|
54209
54749
|
|
|
54210
54750
|
// src/commands/artifact/download-command.ts
|
|
54211
|
-
import { promises as
|
|
54751
|
+
import { promises as fs12 } from "node:fs";
|
|
54212
54752
|
import { basename as basename11, resolve as resolve18 } from "node:path";
|
|
54213
54753
|
|
|
54214
54754
|
// src/domains/artifact/folder-download.ts
|
|
54215
|
-
import { promises as
|
|
54755
|
+
import { promises as fs11 } from "node:fs";
|
|
54216
54756
|
import { dirname as dirname19, isAbsolute as isAbsolute4, join as join76, normalize as normalize5 } from "node:path";
|
|
54217
54757
|
var CONCURRENCY = 6;
|
|
54218
54758
|
function sanitizeFilePath(filePath, destDir) {
|
|
@@ -54239,8 +54779,8 @@ async function downloadOne(task, destDir) {
|
|
|
54239
54779
|
throw new ArtifactApiError(res.status, `Download failed for "${task.file_path}" (HTTP ${res.status}): ${detail.slice(0, 200)}`);
|
|
54240
54780
|
}
|
|
54241
54781
|
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
54242
|
-
await
|
|
54243
|
-
await
|
|
54782
|
+
await fs11.mkdir(dirname19(absDestPath), { recursive: true });
|
|
54783
|
+
await fs11.writeFile(absDestPath, bytes);
|
|
54244
54784
|
return { file_path: task.file_path, size: bytes.byteLength };
|
|
54245
54785
|
}
|
|
54246
54786
|
async function parallelDownload(files, destDir) {
|
|
@@ -54408,14 +54948,14 @@ async function artifactDownload(ref, opts) {
|
|
|
54408
54948
|
}
|
|
54409
54949
|
const destDir = opts.output ? resolve18(opts.output) : resolve18(deriveSlug(manifestRes.title, uuid));
|
|
54410
54950
|
try {
|
|
54411
|
-
const stat7 = await
|
|
54951
|
+
const stat7 = await fs12.stat(destDir);
|
|
54412
54952
|
if (!stat7.isDirectory()) {
|
|
54413
54953
|
console.error(`Error: "${basename11(destDir)}" already exists and is not a directory. Choose another location with -o <dir>.`);
|
|
54414
54954
|
process.exitCode = 1;
|
|
54415
54955
|
return;
|
|
54416
54956
|
}
|
|
54417
54957
|
if (!opts.force) {
|
|
54418
|
-
const entries = await
|
|
54958
|
+
const entries = await fs12.readdir(destDir);
|
|
54419
54959
|
if (entries.length > 0) {
|
|
54420
54960
|
console.error(`Error: directory "${basename11(destDir)}" is not empty. Use --force to overwrite.`);
|
|
54421
54961
|
process.exitCode = 1;
|
|
@@ -54438,7 +54978,7 @@ async function artifactDownload(ref, opts) {
|
|
|
54438
54978
|
return;
|
|
54439
54979
|
}
|
|
54440
54980
|
try {
|
|
54441
|
-
await
|
|
54981
|
+
await fs12.mkdir(destDir, { recursive: true });
|
|
54442
54982
|
} catch (err) {
|
|
54443
54983
|
console.error(`Error: could not create directory "${destDir}": ${err instanceof Error ? err.message : String(err)}`);
|
|
54444
54984
|
process.exitCode = 1;
|
|
@@ -54470,41 +55010,16 @@ async function artifactDownload(ref, opts) {
|
|
|
54470
55010
|
}
|
|
54471
55011
|
|
|
54472
55012
|
// src/commands/artifact/list-command.ts
|
|
54473
|
-
var
|
|
55013
|
+
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
54474
55014
|
init_logger();
|
|
54475
55015
|
|
|
54476
|
-
// src/shared/relative-time.ts
|
|
54477
|
-
function formatRelativeTime(iso, now = Date.now()) {
|
|
54478
|
-
const then = Date.parse(iso);
|
|
54479
|
-
if (Number.isNaN(then))
|
|
54480
|
-
return "—";
|
|
54481
|
-
const diffMs = Math.max(0, now - then);
|
|
54482
|
-
const diffSec = Math.floor(diffMs / 1000);
|
|
54483
|
-
if (diffSec < 60)
|
|
54484
|
-
return "just now";
|
|
54485
|
-
const diffMin = Math.floor(diffSec / 60);
|
|
54486
|
-
if (diffMin < 60)
|
|
54487
|
-
return `${diffMin}m ago`;
|
|
54488
|
-
const diffHour = Math.floor(diffMin / 60);
|
|
54489
|
-
if (diffHour < 24)
|
|
54490
|
-
return `${diffHour}h ago`;
|
|
54491
|
-
const diffDay = Math.floor(diffHour / 24);
|
|
54492
|
-
if (diffDay < 30)
|
|
54493
|
-
return `${diffDay}d ago`;
|
|
54494
|
-
const diffMonth = Math.floor(diffDay / 30);
|
|
54495
|
-
if (diffMonth < 12)
|
|
54496
|
-
return `${diffMonth}mo ago`;
|
|
54497
|
-
const diffYear = Math.floor(diffMonth / 12);
|
|
54498
|
-
return `${diffYear}y ago`;
|
|
54499
|
-
}
|
|
54500
|
-
|
|
54501
55016
|
// src/shared/render-table.ts
|
|
54502
|
-
var
|
|
55017
|
+
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
54503
55018
|
function renderTable(header, rows) {
|
|
54504
55019
|
const lastCol = header.length - 1;
|
|
54505
55020
|
const widths = header.map((h2, col) => Math.max(h2.length, ...rows.map((r2) => r2[col]?.value.length ?? 0)));
|
|
54506
55021
|
const padPlain = (text, col) => col === lastCol ? text : text.padEnd(widths[col]);
|
|
54507
|
-
const headerLine =
|
|
55022
|
+
const headerLine = import_picocolors17.default.bold(header.map((h2, col) => padPlain(h2, col)).join(" ").trimEnd());
|
|
54508
55023
|
const rowLine = (cells) => cells.map((cell, col) => {
|
|
54509
55024
|
const padded = padPlain(cell.value, col);
|
|
54510
55025
|
return cell.paint ? cell.paint(padded) : padded;
|
|
@@ -54528,10 +55043,10 @@ function truncate(text, max) {
|
|
|
54528
55043
|
}
|
|
54529
55044
|
function paintVis(vis) {
|
|
54530
55045
|
if (vis === "shared")
|
|
54531
|
-
return
|
|
55046
|
+
return import_picocolors18.default.cyan;
|
|
54532
55047
|
if (vis === "org")
|
|
54533
|
-
return
|
|
54534
|
-
return
|
|
55048
|
+
return import_picocolors18.default.green;
|
|
55049
|
+
return import_picocolors18.default.dim;
|
|
54535
55050
|
}
|
|
54536
55051
|
function accessLabel(vis, viewerOrgName) {
|
|
54537
55052
|
if (vis === "private")
|
|
@@ -54543,10 +55058,10 @@ function accessLabel(vis, viewerOrgName) {
|
|
|
54543
55058
|
return vis;
|
|
54544
55059
|
}
|
|
54545
55060
|
function ownerCell(item) {
|
|
54546
|
-
return item.isOwner ? { value: "you", paint:
|
|
55061
|
+
return item.isOwner ? { value: "you", paint: import_picocolors18.default.dim } : { value: truncate(item.ownerName, OWNER_MAX) };
|
|
54547
55062
|
}
|
|
54548
55063
|
function threadsCell(item) {
|
|
54549
|
-
return item.openThreads !== null && item.openThreads > 0 ? { value: String(item.openThreads), paint:
|
|
55064
|
+
return item.openThreads !== null && item.openThreads > 0 ? { value: String(item.openThreads), paint: import_picocolors18.default.yellow } : { value: "—", paint: import_picocolors18.default.dim };
|
|
54550
55065
|
}
|
|
54551
55066
|
function buildRow(item, viewerOrgName, now) {
|
|
54552
55067
|
return [
|
|
@@ -54567,7 +55082,7 @@ function describeFilters(q3, access) {
|
|
|
54567
55082
|
parts.push(`--access ${access}`);
|
|
54568
55083
|
return parts.join(" ");
|
|
54569
55084
|
}
|
|
54570
|
-
function
|
|
55085
|
+
function footerLine2(payload) {
|
|
54571
55086
|
const { page, totalPages, totalFiltered, pageSize } = payload.pagination;
|
|
54572
55087
|
const start = (page - 1) * pageSize + 1;
|
|
54573
55088
|
const end = start + payload.artifacts.length - 1;
|
|
@@ -54622,17 +55137,17 @@ async function artifactList(term, opts) {
|
|
|
54622
55137
|
const rows = payload.artifacts.map((item) => buildRow(item, payload.viewerOrgName, now));
|
|
54623
55138
|
process.stdout.write(`${renderTable(header, rows)}
|
|
54624
55139
|
`);
|
|
54625
|
-
logger.info(
|
|
55140
|
+
logger.info(footerLine2(payload));
|
|
54626
55141
|
}
|
|
54627
55142
|
|
|
54628
55143
|
// src/commands/artifact/upload-command.ts
|
|
54629
55144
|
init_dist2();
|
|
54630
|
-
import { promises as
|
|
55145
|
+
import { promises as fs14 } from "node:fs";
|
|
54631
55146
|
import { basename as basename12, extname as extname6, resolve as resolve19 } from "node:path";
|
|
54632
55147
|
|
|
54633
55148
|
// src/domains/artifact/folder-walk.ts
|
|
54634
55149
|
var import_ignore4 = __toESM(require_ignore(), 1);
|
|
54635
|
-
import { promises as
|
|
55150
|
+
import { promises as fs13 } from "node:fs";
|
|
54636
55151
|
import { join as join77, relative as relative15 } from "node:path";
|
|
54637
55152
|
var MAX_FILE_BYTES = 20 * 1024 * 1024;
|
|
54638
55153
|
var IGNORE_FILES = [".gitignore", ".tkmignore"];
|
|
@@ -54649,7 +55164,7 @@ async function buildIgnoreMatcher(rootDir) {
|
|
|
54649
55164
|
const ig = import_ignore4.default();
|
|
54650
55165
|
for (const file of IGNORE_FILES) {
|
|
54651
55166
|
try {
|
|
54652
|
-
ig.add(await
|
|
55167
|
+
ig.add(await fs13.readFile(join77(rootDir, file), "utf8"));
|
|
54653
55168
|
} catch {}
|
|
54654
55169
|
}
|
|
54655
55170
|
ig.add(HARD_IGNORES);
|
|
@@ -54673,7 +55188,7 @@ async function walkFolder(rootDir, skipped) {
|
|
|
54673
55188
|
async function walk2(rootDir, dir, ig, out, skipped) {
|
|
54674
55189
|
let dirents;
|
|
54675
55190
|
try {
|
|
54676
|
-
dirents = await
|
|
55191
|
+
dirents = await fs13.readdir(dir, { withFileTypes: true });
|
|
54677
55192
|
} catch {
|
|
54678
55193
|
return;
|
|
54679
55194
|
}
|
|
@@ -54696,7 +55211,7 @@ async function walk2(rootDir, dir, ig, out, skipped) {
|
|
|
54696
55211
|
skipped.push(relPath);
|
|
54697
55212
|
continue;
|
|
54698
55213
|
}
|
|
54699
|
-
const stat7 = await
|
|
55214
|
+
const stat7 = await fs13.stat(absPath);
|
|
54700
55215
|
out.push({ absPath, relPath, size: stat7.size });
|
|
54701
55216
|
}
|
|
54702
55217
|
}
|
|
@@ -54743,7 +55258,7 @@ async function artifactUpload(filePath, opts) {
|
|
|
54743
55258
|
const absPath = resolve19(filePath);
|
|
54744
55259
|
let stat7;
|
|
54745
55260
|
try {
|
|
54746
|
-
stat7 = await
|
|
55261
|
+
stat7 = await fs14.stat(absPath);
|
|
54747
55262
|
} catch {
|
|
54748
55263
|
console.error(`Error: path not found: ${absPath}`);
|
|
54749
55264
|
process.exitCode = 1;
|
|
@@ -54953,43 +55468,65 @@ async function uploadFolder(absPath, displayPath, token, opts) {
|
|
|
54953
55468
|
}
|
|
54954
55469
|
|
|
54955
55470
|
// src/commands/artifact/artifact-command.ts
|
|
54956
|
-
function
|
|
55471
|
+
function usageError2(hint) {
|
|
54957
55472
|
console.error(`Usage: ${hint}`);
|
|
54958
55473
|
process.exitCode = 1;
|
|
54959
55474
|
}
|
|
54960
|
-
|
|
55475
|
+
var COMMENTS_ONLY_FLAGS = ["status", "author", "cursor", "quiet", "file"];
|
|
55476
|
+
async function artifactCommand(action, target, ...rest) {
|
|
55477
|
+
if (rest.length !== 1 && rest.length !== 3) {
|
|
55478
|
+
throw new TypeError(`artifactCommand: expected 3 or 5 arguments, received ${rest.length + 2}`);
|
|
55479
|
+
}
|
|
55480
|
+
const opts = rest[rest.length - 1];
|
|
55481
|
+
const arg3 = rest.length === 3 ? rest[0] : undefined;
|
|
55482
|
+
const arg4 = rest.length === 3 ? rest[1] : undefined;
|
|
55483
|
+
if (action !== undefined && action !== "comments") {
|
|
55484
|
+
if (arg3 !== undefined && arg3 !== null) {
|
|
55485
|
+
return usageError2(`tkm artifact ${action} — unexpected extra argument "${arg3}"`);
|
|
55486
|
+
}
|
|
55487
|
+
const stray = COMMENTS_ONLY_FLAGS.filter((flag) => opts[flag] !== undefined);
|
|
55488
|
+
if (stray.length > 0) {
|
|
55489
|
+
return usageError2(`tkm artifact ${action} — ${stray.map((f3) => `--${f3}`).join(", ")} ${stray.length === 1 ? "applies" : "apply"} only to \`artifact comments\``);
|
|
55490
|
+
}
|
|
55491
|
+
}
|
|
54961
55492
|
switch (action) {
|
|
54962
55493
|
case "list":
|
|
54963
55494
|
if (target) {
|
|
54964
|
-
return
|
|
55495
|
+
return usageError2(`tkm artifact search ${target} (list takes no search term)`);
|
|
54965
55496
|
}
|
|
54966
55497
|
await artifactList(undefined, opts);
|
|
54967
55498
|
break;
|
|
54968
55499
|
case "search":
|
|
54969
55500
|
if (!target)
|
|
54970
|
-
return
|
|
55501
|
+
return usageError2("tkm artifact search <term>");
|
|
54971
55502
|
await artifactList(target, opts);
|
|
54972
55503
|
break;
|
|
54973
55504
|
case "upload":
|
|
54974
55505
|
if (!target)
|
|
54975
|
-
return
|
|
55506
|
+
return usageError2("tkm artifact upload <file>");
|
|
54976
55507
|
await artifactUpload(target, opts);
|
|
54977
55508
|
break;
|
|
54978
55509
|
case "download":
|
|
54979
55510
|
if (!target)
|
|
54980
|
-
return
|
|
55511
|
+
return usageError2("tkm artifact download <uuid|url> [-o <dir>] [--ver <n>] [--force]");
|
|
54981
55512
|
await artifactDownload(target, opts);
|
|
54982
55513
|
break;
|
|
54983
55514
|
case "delete":
|
|
54984
55515
|
if (!target)
|
|
54985
|
-
return
|
|
55516
|
+
return usageError2("tkm artifact delete <uuid|url> [--ver <n>]");
|
|
54986
55517
|
await artifactDelete(target, opts);
|
|
54987
55518
|
break;
|
|
55519
|
+
case "comments":
|
|
55520
|
+
if (!target) {
|
|
55521
|
+
return usageError2("tkm artifact comments <list|reply|solve|reopen|delete> <ref> [id]");
|
|
55522
|
+
}
|
|
55523
|
+
await commentsCommand(target, arg3, arg4, opts);
|
|
55524
|
+
break;
|
|
54988
55525
|
case undefined:
|
|
54989
|
-
|
|
55526
|
+
usageError2("tkm artifact <list | search <term> | upload <file> | download <uuid|url> | delete <uuid|url> [--ver <n>] | comments <verb> <ref> [id]>");
|
|
54990
55527
|
break;
|
|
54991
55528
|
default:
|
|
54992
|
-
console.error(`Unknown artifact action: ${action}. Available: list, search, upload, download, delete`);
|
|
55529
|
+
console.error(`Unknown artifact action: ${action}. Available: list, search, upload, download, delete, comments`);
|
|
54993
55530
|
process.exitCode = 1;
|
|
54994
55531
|
}
|
|
54995
55532
|
}
|
|
@@ -55804,12 +56341,12 @@ function foldAnalytics(aggregates, now, range) {
|
|
|
55804
56341
|
}
|
|
55805
56342
|
|
|
55806
56343
|
// src/domains/sessions/adapters/claude.ts
|
|
55807
|
-
import * as
|
|
56344
|
+
import * as fs16 from "node:fs";
|
|
55808
56345
|
import * as os4 from "node:os";
|
|
55809
56346
|
import * as path6 from "node:path";
|
|
55810
56347
|
|
|
55811
56348
|
// src/domains/sessions/transcript-parser.ts
|
|
55812
|
-
import * as
|
|
56349
|
+
import * as fs15 from "node:fs";
|
|
55813
56350
|
|
|
55814
56351
|
// src/domains/sessions/types.ts
|
|
55815
56352
|
function emptyTokens() {
|
|
@@ -55838,13 +56375,13 @@ function isInterruptText(s) {
|
|
|
55838
56375
|
return /^\s*\[Request interrupted\b/.test(String(s || ""));
|
|
55839
56376
|
}
|
|
55840
56377
|
function readNew(transcriptPath, fromOffset) {
|
|
55841
|
-
if (!transcriptPath || !
|
|
56378
|
+
if (!transcriptPath || !fs15.existsSync(transcriptPath)) {
|
|
55842
56379
|
return { records: [], newOffset: fromOffset || 0 };
|
|
55843
56380
|
}
|
|
55844
56381
|
if (transcriptPath.endsWith(".zst")) {
|
|
55845
56382
|
return { records: [], newOffset: fromOffset || 0 };
|
|
55846
56383
|
}
|
|
55847
|
-
const st =
|
|
56384
|
+
const st = fs15.statSync(transcriptPath);
|
|
55848
56385
|
const start = fromOffset || 0;
|
|
55849
56386
|
if (st.size <= start) {
|
|
55850
56387
|
return { records: [], newOffset: st.size };
|
|
@@ -55855,10 +56392,10 @@ function readNew(transcriptPath, fromOffset) {
|
|
|
55855
56392
|
len = MAX_READ_BYTES;
|
|
55856
56393
|
truncated = true;
|
|
55857
56394
|
}
|
|
55858
|
-
const fd =
|
|
56395
|
+
const fd = fs15.openSync(transcriptPath, "r");
|
|
55859
56396
|
try {
|
|
55860
56397
|
const buf = Buffer.alloc(len);
|
|
55861
|
-
|
|
56398
|
+
fs15.readSync(fd, buf, 0, len, start);
|
|
55862
56399
|
const text = buf.toString("utf-8");
|
|
55863
56400
|
const lines = text.split(`
|
|
55864
56401
|
`).filter(Boolean);
|
|
@@ -55866,17 +56403,17 @@ function readNew(transcriptPath, fromOffset) {
|
|
|
55866
56403
|
const newOffset = truncated ? start + len : st.size;
|
|
55867
56404
|
return { records, newOffset };
|
|
55868
56405
|
} finally {
|
|
55869
|
-
|
|
56406
|
+
fs15.closeSync(fd);
|
|
55870
56407
|
}
|
|
55871
56408
|
}
|
|
55872
56409
|
function readNewCheckpointed(transcriptPath, fromOffset) {
|
|
55873
|
-
if (!transcriptPath || !
|
|
56410
|
+
if (!transcriptPath || !fs15.existsSync(transcriptPath)) {
|
|
55874
56411
|
return { records: [], newOffset: fromOffset || 0 };
|
|
55875
56412
|
}
|
|
55876
56413
|
if (transcriptPath.endsWith(".zst")) {
|
|
55877
56414
|
return { records: [], newOffset: fromOffset || 0 };
|
|
55878
56415
|
}
|
|
55879
|
-
const st =
|
|
56416
|
+
const st = fs15.statSync(transcriptPath);
|
|
55880
56417
|
const start = fromOffset || 0;
|
|
55881
56418
|
if (st.size <= start) {
|
|
55882
56419
|
return { records: [], newOffset: st.size };
|
|
@@ -55887,10 +56424,10 @@ function readNewCheckpointed(transcriptPath, fromOffset) {
|
|
|
55887
56424
|
len = MAX_READ_BYTES;
|
|
55888
56425
|
truncated = true;
|
|
55889
56426
|
}
|
|
55890
|
-
const fd =
|
|
56427
|
+
const fd = fs15.openSync(transcriptPath, "r");
|
|
55891
56428
|
try {
|
|
55892
56429
|
const buf = Buffer.alloc(len);
|
|
55893
|
-
|
|
56430
|
+
fs15.readSync(fd, buf, 0, len, start);
|
|
55894
56431
|
const lastNl = buf.lastIndexOf(10);
|
|
55895
56432
|
if (lastNl < 0) {
|
|
55896
56433
|
return { records: [], newOffset: truncated ? start + len : start };
|
|
@@ -55901,7 +56438,7 @@ function readNewCheckpointed(transcriptPath, fromOffset) {
|
|
|
55901
56438
|
const records = lines.map(safeJSON).filter((r2) => r2 !== null);
|
|
55902
56439
|
return { records, newOffset: start + lastNl + 1 };
|
|
55903
56440
|
} finally {
|
|
55904
|
-
|
|
56441
|
+
fs15.closeSync(fd);
|
|
55905
56442
|
}
|
|
55906
56443
|
}
|
|
55907
56444
|
function addTokens(a3, b3) {
|
|
@@ -55941,7 +56478,7 @@ function tokensOfCodex(rec) {
|
|
|
55941
56478
|
};
|
|
55942
56479
|
}
|
|
55943
56480
|
function peekFirstTimestamp(jsonlPath) {
|
|
55944
|
-
if (!
|
|
56481
|
+
if (!fs15.existsSync(jsonlPath))
|
|
55945
56482
|
return null;
|
|
55946
56483
|
const { records } = readNew(jsonlPath, 0);
|
|
55947
56484
|
for (const r2 of records) {
|
|
@@ -55952,7 +56489,7 @@ function peekFirstTimestamp(jsonlPath) {
|
|
|
55952
56489
|
return null;
|
|
55953
56490
|
}
|
|
55954
56491
|
function peekLastTimestamp(jsonlPath) {
|
|
55955
|
-
if (!
|
|
56492
|
+
if (!fs15.existsSync(jsonlPath))
|
|
55956
56493
|
return null;
|
|
55957
56494
|
const { records } = readNew(jsonlPath, 0);
|
|
55958
56495
|
for (let i = records.length - 1;i >= 0; i--) {
|
|
@@ -55965,7 +56502,7 @@ function peekLastTimestamp(jsonlPath) {
|
|
|
55965
56502
|
function sumClaudeAgentTokens(jsonlPath) {
|
|
55966
56503
|
const tot = emptyTokens();
|
|
55967
56504
|
let model = null;
|
|
55968
|
-
if (!
|
|
56505
|
+
if (!fs15.existsSync(jsonlPath))
|
|
55969
56506
|
return { tokens: tot, model };
|
|
55970
56507
|
const { records } = readNew(jsonlPath, 0);
|
|
55971
56508
|
for (const rec of records) {
|
|
@@ -55986,7 +56523,7 @@ function sumClaudeAgentTokens(jsonlPath) {
|
|
|
55986
56523
|
}
|
|
55987
56524
|
function sumCodexAgentTokens(jsonlPath) {
|
|
55988
56525
|
const tot = emptyTokens();
|
|
55989
|
-
if (!
|
|
56526
|
+
if (!fs15.existsSync(jsonlPath))
|
|
55990
56527
|
return tot;
|
|
55991
56528
|
const { records } = readNew(jsonlPath, 0);
|
|
55992
56529
|
for (const rec of records) {
|
|
@@ -56100,14 +56637,14 @@ function readSessionSummary(filePath) {
|
|
|
56100
56637
|
aiTitle: null
|
|
56101
56638
|
};
|
|
56102
56639
|
try {
|
|
56103
|
-
const st =
|
|
56640
|
+
const st = fs16.statSync(filePath);
|
|
56104
56641
|
const len = Math.min(st.size, 64 * 1024);
|
|
56105
56642
|
const buf = Buffer.alloc(len);
|
|
56106
|
-
const fd =
|
|
56643
|
+
const fd = fs16.openSync(filePath, "r");
|
|
56107
56644
|
try {
|
|
56108
|
-
|
|
56645
|
+
fs16.readSync(fd, buf, 0, len, 0);
|
|
56109
56646
|
} finally {
|
|
56110
|
-
|
|
56647
|
+
fs16.closeSync(fd);
|
|
56111
56648
|
}
|
|
56112
56649
|
const lines = buf.toString("utf-8").split(`
|
|
56113
56650
|
`);
|
|
@@ -56148,7 +56685,7 @@ async function listSessions(rootDir) {
|
|
|
56148
56685
|
const out = [];
|
|
56149
56686
|
let projects;
|
|
56150
56687
|
try {
|
|
56151
|
-
projects =
|
|
56688
|
+
projects = fs16.readdirSync(root);
|
|
56152
56689
|
} catch {
|
|
56153
56690
|
return out;
|
|
56154
56691
|
}
|
|
@@ -56156,7 +56693,7 @@ async function listSessions(rootDir) {
|
|
|
56156
56693
|
const projDir = path6.join(root, proj);
|
|
56157
56694
|
let entries;
|
|
56158
56695
|
try {
|
|
56159
|
-
entries =
|
|
56696
|
+
entries = fs16.readdirSync(projDir);
|
|
56160
56697
|
} catch {
|
|
56161
56698
|
continue;
|
|
56162
56699
|
}
|
|
@@ -56166,7 +56703,7 @@ async function listSessions(rootDir) {
|
|
|
56166
56703
|
const full = path6.join(projDir, entry);
|
|
56167
56704
|
let st;
|
|
56168
56705
|
try {
|
|
56169
|
-
st =
|
|
56706
|
+
st = fs16.statSync(full);
|
|
56170
56707
|
} catch {
|
|
56171
56708
|
continue;
|
|
56172
56709
|
}
|
|
@@ -56192,7 +56729,7 @@ function loadSubagentIndex(parentTranscriptPath, sessionId) {
|
|
|
56192
56729
|
const byAgentId = new Map;
|
|
56193
56730
|
let names;
|
|
56194
56731
|
try {
|
|
56195
|
-
names =
|
|
56732
|
+
names = fs16.readdirSync(subDir);
|
|
56196
56733
|
} catch {
|
|
56197
56734
|
return { byToolUseId, byAgentId };
|
|
56198
56735
|
}
|
|
@@ -56202,7 +56739,7 @@ function loadSubagentIndex(parentTranscriptPath, sessionId) {
|
|
|
56202
56739
|
const agentId = name.replace(/^agent-/, "").replace(/\.meta\.json$/, "");
|
|
56203
56740
|
let meta = {};
|
|
56204
56741
|
try {
|
|
56205
|
-
meta = JSON.parse(
|
|
56742
|
+
meta = JSON.parse(fs16.readFileSync(path6.join(subDir, name), "utf-8"));
|
|
56206
56743
|
} catch {}
|
|
56207
56744
|
const jsonlPath = path6.join(subDir, `agent-${agentId}.jsonl`);
|
|
56208
56745
|
const { tokens, model } = sumClaudeAgentTokens(jsonlPath);
|
|
@@ -56303,7 +56840,7 @@ function handleTaskUse(state, rec, toolUse, subIdx) {
|
|
|
56303
56840
|
turn.agentIds.push(agentId);
|
|
56304
56841
|
if (match.jsonlPath) {
|
|
56305
56842
|
try {
|
|
56306
|
-
state.agentOffsets[agentId] =
|
|
56843
|
+
state.agentOffsets[agentId] = fs16.statSync(match.jsonlPath).size;
|
|
56307
56844
|
} catch {
|
|
56308
56845
|
state.agentOffsets[agentId] = 0;
|
|
56309
56846
|
}
|
|
@@ -56364,7 +56901,7 @@ function lastNonStartupTurn(state) {
|
|
|
56364
56901
|
async function parse2(filePath) {
|
|
56365
56902
|
const sessionId = path6.basename(filePath, ".jsonl");
|
|
56366
56903
|
try {
|
|
56367
|
-
const st =
|
|
56904
|
+
const st = fs16.statSync(filePath);
|
|
56368
56905
|
if (st.size > MAX_PARSE_BYTES) {
|
|
56369
56906
|
const mb = (st.size / (1024 * 1024)).toFixed(0);
|
|
56370
56907
|
const cap = MAX_PARSE_BYTES / (1024 * 1024);
|
|
@@ -56559,7 +57096,7 @@ var claudeAdapter = {
|
|
|
56559
57096
|
};
|
|
56560
57097
|
|
|
56561
57098
|
// src/domains/sessions/adapters/codex.ts
|
|
56562
|
-
import * as
|
|
57099
|
+
import * as fs17 from "node:fs";
|
|
56563
57100
|
import * as os5 from "node:os";
|
|
56564
57101
|
import * as path7 from "node:path";
|
|
56565
57102
|
var CODEX_ROOT = path7.join(os5.homedir(), ".codex", "sessions");
|
|
@@ -56578,7 +57115,7 @@ function loadSkillCatalog(cwd2) {
|
|
|
56578
57115
|
for (const dir of skillDirs(cwd2)) {
|
|
56579
57116
|
let names;
|
|
56580
57117
|
try {
|
|
56581
|
-
names =
|
|
57118
|
+
names = fs17.readdirSync(dir);
|
|
56582
57119
|
} catch {
|
|
56583
57120
|
continue;
|
|
56584
57121
|
}
|
|
@@ -56588,13 +57125,13 @@ function loadSkillCatalog(cwd2) {
|
|
|
56588
57125
|
const entryPath = path7.join(dir, name);
|
|
56589
57126
|
let st;
|
|
56590
57127
|
try {
|
|
56591
|
-
st =
|
|
57128
|
+
st = fs17.statSync(entryPath);
|
|
56592
57129
|
} catch {
|
|
56593
57130
|
continue;
|
|
56594
57131
|
}
|
|
56595
57132
|
if (!st.isDirectory())
|
|
56596
57133
|
continue;
|
|
56597
|
-
if (!
|
|
57134
|
+
if (!fs17.existsSync(path7.join(entryPath, "SKILL.md")))
|
|
56598
57135
|
continue;
|
|
56599
57136
|
const key = normalizeName(name);
|
|
56600
57137
|
if (!key || seen.has(key))
|
|
@@ -56650,7 +57187,7 @@ function extractUuidFromName(filePath) {
|
|
|
56650
57187
|
function walkRolloutFiles(dir, depth, maxDepth, out) {
|
|
56651
57188
|
let entries;
|
|
56652
57189
|
try {
|
|
56653
|
-
entries =
|
|
57190
|
+
entries = fs17.readdirSync(dir, { withFileTypes: true });
|
|
56654
57191
|
} catch {
|
|
56655
57192
|
return;
|
|
56656
57193
|
}
|
|
@@ -56670,20 +57207,20 @@ function walkRolloutFiles(dir, depth, maxDepth, out) {
|
|
|
56670
57207
|
}
|
|
56671
57208
|
function collectRolloutFiles(root) {
|
|
56672
57209
|
const files = [];
|
|
56673
|
-
if (!
|
|
57210
|
+
if (!fs17.existsSync(root))
|
|
56674
57211
|
return files;
|
|
56675
57212
|
walkRolloutFiles(root, 0, 3, files);
|
|
56676
57213
|
return files;
|
|
56677
57214
|
}
|
|
56678
57215
|
function readFirstSessionMeta(filePath) {
|
|
56679
57216
|
try {
|
|
56680
|
-
const len = Math.min(
|
|
57217
|
+
const len = Math.min(fs17.statSync(filePath).size, 64 * 1024);
|
|
56681
57218
|
const buf = Buffer.alloc(len);
|
|
56682
|
-
const fd =
|
|
57219
|
+
const fd = fs17.openSync(filePath, "r");
|
|
56683
57220
|
try {
|
|
56684
|
-
|
|
57221
|
+
fs17.readSync(fd, buf, 0, len, 0);
|
|
56685
57222
|
} finally {
|
|
56686
|
-
|
|
57223
|
+
fs17.closeSync(fd);
|
|
56687
57224
|
}
|
|
56688
57225
|
const firstLine = buf.toString("utf-8").split(`
|
|
56689
57226
|
`)[0];
|
|
@@ -56697,13 +57234,13 @@ function readFirstSessionMeta(filePath) {
|
|
|
56697
57234
|
}
|
|
56698
57235
|
function readFirstUserPrompt(filePath) {
|
|
56699
57236
|
try {
|
|
56700
|
-
const len = Math.min(
|
|
57237
|
+
const len = Math.min(fs17.statSync(filePath).size, 128 * 1024);
|
|
56701
57238
|
const buf = Buffer.alloc(len);
|
|
56702
|
-
const fd =
|
|
57239
|
+
const fd = fs17.openSync(filePath, "r");
|
|
56703
57240
|
try {
|
|
56704
|
-
|
|
57241
|
+
fs17.readSync(fd, buf, 0, len, 0);
|
|
56705
57242
|
} finally {
|
|
56706
|
-
|
|
57243
|
+
fs17.closeSync(fd);
|
|
56707
57244
|
}
|
|
56708
57245
|
const lines = buf.toString("utf-8").split(`
|
|
56709
57246
|
`);
|
|
@@ -56722,13 +57259,13 @@ function readFirstUserPrompt(filePath) {
|
|
|
56722
57259
|
}
|
|
56723
57260
|
function readFirstChildModel(filePath) {
|
|
56724
57261
|
try {
|
|
56725
|
-
const len = Math.min(
|
|
57262
|
+
const len = Math.min(fs17.statSync(filePath).size, 64 * 1024);
|
|
56726
57263
|
const buf = Buffer.alloc(len);
|
|
56727
|
-
const fd =
|
|
57264
|
+
const fd = fs17.openSync(filePath, "r");
|
|
56728
57265
|
try {
|
|
56729
|
-
|
|
57266
|
+
fs17.readSync(fd, buf, 0, len, 0);
|
|
56730
57267
|
} finally {
|
|
56731
|
-
|
|
57268
|
+
fs17.closeSync(fd);
|
|
56732
57269
|
}
|
|
56733
57270
|
for (const line of buf.toString("utf-8").split(`
|
|
56734
57271
|
`)) {
|
|
@@ -56772,7 +57309,7 @@ async function listSessions2(rootDir) {
|
|
|
56772
57309
|
continue;
|
|
56773
57310
|
let st;
|
|
56774
57311
|
try {
|
|
56775
|
-
st =
|
|
57312
|
+
st = fs17.statSync(full);
|
|
56776
57313
|
} catch {
|
|
56777
57314
|
continue;
|
|
56778
57315
|
}
|
|
@@ -56841,7 +57378,7 @@ function attachSubagent(state, info, childIndex) {
|
|
|
56841
57378
|
startedAt: info.spawnedAt
|
|
56842
57379
|
});
|
|
56843
57380
|
const cached = childIndex.get(info.agentId);
|
|
56844
|
-
const childPath = cached &&
|
|
57381
|
+
const childPath = cached && fs17.existsSync(cached) ? cached : null;
|
|
56845
57382
|
const transcriptMissing = !childPath;
|
|
56846
57383
|
const description = info.nickname ? `${info.nickname}${transcriptMissing ? " (transcript missing)" : ""}` : transcriptMissing ? "(transcript missing)" : "";
|
|
56847
57384
|
let tokens = emptyTokens();
|
|
@@ -66374,7 +66911,7 @@ init_logger();
|
|
|
66374
66911
|
var import_proper_lockfile8 = __toESM(require_proper_lockfile(), 1);
|
|
66375
66912
|
|
|
66376
66913
|
// src/domains/sessions/store/db.ts
|
|
66377
|
-
import { promises as
|
|
66914
|
+
import { promises as fs18 } from "node:fs";
|
|
66378
66915
|
import { join as join81 } from "node:path";
|
|
66379
66916
|
init_logger();
|
|
66380
66917
|
init_paths2();
|
|
@@ -66477,7 +67014,7 @@ function getConsoleStorePath() {
|
|
|
66477
67014
|
}
|
|
66478
67015
|
async function chmodSafe2(path8, mode) {
|
|
66479
67016
|
try {
|
|
66480
|
-
await
|
|
67017
|
+
await fs18.chmod(path8, mode);
|
|
66481
67018
|
} catch (err) {
|
|
66482
67019
|
const code = err?.code;
|
|
66483
67020
|
if (code === "ENOENT")
|
|
@@ -66488,7 +67025,7 @@ async function chmodSafe2(path8, mode) {
|
|
|
66488
67025
|
async function openStore(dbPath = getConsoleStorePath()) {
|
|
66489
67026
|
const onDisk = dbPath !== ":memory:";
|
|
66490
67027
|
if (onDisk) {
|
|
66491
|
-
await
|
|
67028
|
+
await fs18.mkdir(getConsoleStoreDir(), { recursive: true, mode: 448 });
|
|
66492
67029
|
}
|
|
66493
67030
|
const db = new Kysely({ dialect: await createDialect(dbPath) });
|
|
66494
67031
|
try {
|
|
@@ -67984,7 +68521,7 @@ var PYTHON_INSTALLERS = [
|
|
|
67984
68521
|
// src/services/package-installer/dependencies/system-installer.ts
|
|
67985
68522
|
init_logger();
|
|
67986
68523
|
import { exec as exec3 } from "node:child_process";
|
|
67987
|
-
import * as
|
|
68524
|
+
import * as fs19 from "node:fs";
|
|
67988
68525
|
import { promisify as promisify9 } from "node:util";
|
|
67989
68526
|
var execAsync3 = promisify9(exec3);
|
|
67990
68527
|
async function detectOS() {
|
|
@@ -67999,8 +68536,8 @@ async function detectOS() {
|
|
|
67999
68536
|
}
|
|
68000
68537
|
} else if (platform5 === "linux") {
|
|
68001
68538
|
try {
|
|
68002
|
-
if (
|
|
68003
|
-
const content =
|
|
68539
|
+
if (fs19.existsSync("/etc/os-release")) {
|
|
68540
|
+
const content = fs19.readFileSync("/etc/os-release", "utf-8");
|
|
68004
68541
|
const idMatch = content.match(/^ID=(.+)$/m);
|
|
68005
68542
|
info.distro = idMatch?.[1]?.replace(/"/g, "");
|
|
68006
68543
|
}
|
|
@@ -69766,7 +70303,7 @@ import { spawnSync as spawnSync3 } from "node:child_process";
|
|
|
69766
70303
|
init_build_config();
|
|
69767
70304
|
init_logger();
|
|
69768
70305
|
import { execSync as execSync2 } from "node:child_process";
|
|
69769
|
-
import * as
|
|
70306
|
+
import * as fs20 from "node:fs";
|
|
69770
70307
|
import * as os6 from "node:os";
|
|
69771
70308
|
import * as path8 from "node:path";
|
|
69772
70309
|
var VALID_TAG_PATTERN = /^[a-zA-Z0-9._+\-]+$/;
|
|
@@ -69788,7 +70325,7 @@ Tags must contain only letters, numbers, dots, hyphens, underscores, and plus si
|
|
|
69788
70325
|
const { kit, tag, preferSsh = true, timeout = 60000 } = options2;
|
|
69789
70326
|
this.validateTag(tag);
|
|
69790
70327
|
try {
|
|
69791
|
-
await
|
|
70328
|
+
await fs20.promises.mkdir(this.tempBaseDir, { recursive: true });
|
|
69792
70329
|
} catch (error) {
|
|
69793
70330
|
const msg = error instanceof Error ? error.message : String(error);
|
|
69794
70331
|
throw new Error(`Failed to create temp directory: ${this.tempBaseDir}
|
|
@@ -69796,7 +70333,7 @@ Error: ${msg}
|
|
|
69796
70333
|
|
|
69797
70334
|
Check disk space and directory permissions.`);
|
|
69798
70335
|
}
|
|
69799
|
-
const tempDir = await
|
|
70336
|
+
const tempDir = await fs20.promises.mkdtemp(path8.join(this.tempBaseDir, `tkm-git-${kit.repo}-`));
|
|
69800
70337
|
const url = preferSsh ? `git@github.com:${kit.owner}/${kit.repo}.git` : `https://github.com/${kit.owner}/${kit.repo}.git`;
|
|
69801
70338
|
const method = preferSsh ? "ssh" : "https";
|
|
69802
70339
|
logger.verbose("Git clone", { url, tag, tempDir, method });
|
|
@@ -69813,8 +70350,8 @@ Check disk space and directory permissions.`);
|
|
|
69813
70350
|
const stderr = shallowError?.stderr || "";
|
|
69814
70351
|
if (stderr.includes("Could not find remote branch") || stderr.includes("fatal: Remote branch") || stderr.includes("warning: Could not find remote branch")) {
|
|
69815
70352
|
logger.debug(`Shallow clone failed for tag ${tag}, trying full clone...`);
|
|
69816
|
-
await
|
|
69817
|
-
await
|
|
70353
|
+
await fs20.promises.rm(tempDir, { recursive: true, force: true }).catch(() => {});
|
|
70354
|
+
await fs20.promises.mkdir(tempDir, { recursive: true });
|
|
69818
70355
|
execSync2(`git clone --no-checkout ${quotedUrl} ${quotedDir}`, {
|
|
69819
70356
|
stdio: ["pipe", "pipe", "pipe"],
|
|
69820
70357
|
timeout,
|
|
@@ -69830,7 +70367,7 @@ Check disk space and directory permissions.`);
|
|
|
69830
70367
|
}
|
|
69831
70368
|
}
|
|
69832
70369
|
const gitDir = path8.join(tempDir, ".git");
|
|
69833
|
-
await
|
|
70370
|
+
await fs20.promises.rm(gitDir, { recursive: true, force: true });
|
|
69834
70371
|
logger.debug(`Git clone successful: ${tempDir}`);
|
|
69835
70372
|
return {
|
|
69836
70373
|
cloneDir: tempDir,
|
|
@@ -69838,7 +70375,7 @@ Check disk space and directory permissions.`);
|
|
|
69838
70375
|
method
|
|
69839
70376
|
};
|
|
69840
70377
|
} catch (error) {
|
|
69841
|
-
await
|
|
70378
|
+
await fs20.promises.rm(tempDir, { recursive: true, force: true }).catch((err) => logger.debug(`Failed to cleanup temp dir ${tempDir}: ${err.message}`));
|
|
69842
70379
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
69843
70380
|
const stderr = error?.stderr || "";
|
|
69844
70381
|
const errorCode = error?.code;
|
|
@@ -69881,10 +70418,10 @@ Ensure you have access to the repository and your git credentials are configured
|
|
|
69881
70418
|
const sshDir = path8.join(homeDir, ".ssh");
|
|
69882
70419
|
const keyFiles = ["id_rsa", "id_ed25519", "id_ecdsa", "id_rsa.pub", "id_ed25519.pub"];
|
|
69883
70420
|
try {
|
|
69884
|
-
if (!
|
|
70421
|
+
if (!fs20.existsSync(sshDir))
|
|
69885
70422
|
return false;
|
|
69886
70423
|
for (const keyFile of keyFiles) {
|
|
69887
|
-
if (
|
|
70424
|
+
if (fs20.existsSync(path8.join(sshDir, keyFile))) {
|
|
69888
70425
|
return true;
|
|
69889
70426
|
}
|
|
69890
70427
|
}
|
|
@@ -70825,7 +71362,7 @@ class ReportGenerator {
|
|
|
70825
71362
|
}
|
|
70826
71363
|
// src/domains/health-checks/doctor-ui-renderer.ts
|
|
70827
71364
|
init_terminal_utils();
|
|
70828
|
-
var
|
|
71365
|
+
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
70829
71366
|
|
|
70830
71367
|
class DoctorUIRenderer {
|
|
70831
71368
|
symbols = getStatusSymbols();
|
|
@@ -70837,8 +71374,8 @@ class DoctorUIRenderer {
|
|
|
70837
71374
|
const groups = this.groupChecks(summary.checks);
|
|
70838
71375
|
for (const [groupName, checks] of groups) {
|
|
70839
71376
|
console.log("│");
|
|
70840
|
-
console.log(`│ ${
|
|
70841
|
-
console.log(`│ ${
|
|
71377
|
+
console.log(`│ ${import_picocolors19.default.bold(import_picocolors19.default.cyan(groupName.toUpperCase()))}`);
|
|
71378
|
+
console.log(`│ ${import_picocolors19.default.dim("─".repeat(50))}`);
|
|
70842
71379
|
const maxNameLen = Math.max(...checks.map((c2) => c2.name.length));
|
|
70843
71380
|
const maxMsgLen = Math.max(...checks.map((c2) => c2.message.length));
|
|
70844
71381
|
for (const check of checks) {
|
|
@@ -70850,55 +71387,55 @@ class DoctorUIRenderer {
|
|
|
70850
71387
|
}
|
|
70851
71388
|
renderCheck(check, maxNameLen, maxMsgLen) {
|
|
70852
71389
|
const symbol = this.getColoredSymbol(check.status);
|
|
70853
|
-
const name2 =
|
|
71390
|
+
const name2 = import_picocolors19.default.bold(check.name.padEnd(maxNameLen));
|
|
70854
71391
|
const paddedMsg = check.message.padEnd(maxMsgLen);
|
|
70855
71392
|
const value = this.colorizeValue(check.status, paddedMsg);
|
|
70856
71393
|
if (this.verbose && check.command) {
|
|
70857
|
-
console.log(`│ ${
|
|
71394
|
+
console.log(`│ ${import_picocolors19.default.dim(`Running: ${check.command}`)}`);
|
|
70858
71395
|
}
|
|
70859
71396
|
let line = `│ ${symbol} ${name2} ${value}`;
|
|
70860
71397
|
if (this.verbose && check.duration !== undefined) {
|
|
70861
|
-
line += ` ${
|
|
71398
|
+
line += ` ${import_picocolors19.default.dim(`(${check.duration}ms)`)}`;
|
|
70862
71399
|
}
|
|
70863
71400
|
if (check.details) {
|
|
70864
71401
|
const displayPath = this.verbose ? check.details : this.shortenPath(check.details);
|
|
70865
|
-
line += ` ${
|
|
71402
|
+
line += ` ${import_picocolors19.default.dim(displayPath)}`;
|
|
70866
71403
|
}
|
|
70867
71404
|
console.log(line);
|
|
70868
71405
|
if (this.verbose && check.status === "pass" && check.suggestion) {
|
|
70869
71406
|
const indent = " ".repeat(maxNameLen + 5);
|
|
70870
|
-
console.log(`│ ${indent}${
|
|
71407
|
+
console.log(`│ ${indent}${import_picocolors19.default.dim(`→ ${check.suggestion}`)}`);
|
|
70871
71408
|
}
|
|
70872
71409
|
if (check.status !== "pass" && check.suggestion) {
|
|
70873
71410
|
const indent = " ".repeat(maxNameLen + 5);
|
|
70874
|
-
console.log(`│ ${indent}${
|
|
71411
|
+
console.log(`│ ${indent}${import_picocolors19.default.dim(`→ ${check.suggestion}`)}`);
|
|
70875
71412
|
}
|
|
70876
71413
|
}
|
|
70877
71414
|
getColoredSymbol(status2) {
|
|
70878
71415
|
switch (status2) {
|
|
70879
71416
|
case "pass":
|
|
70880
|
-
return
|
|
71417
|
+
return import_picocolors19.default.green(this.symbols.pass);
|
|
70881
71418
|
case "warn":
|
|
70882
|
-
return
|
|
71419
|
+
return import_picocolors19.default.yellow(this.symbols.warn);
|
|
70883
71420
|
case "fail":
|
|
70884
|
-
return
|
|
71421
|
+
return import_picocolors19.default.red(this.symbols.fail);
|
|
70885
71422
|
default:
|
|
70886
|
-
return
|
|
71423
|
+
return import_picocolors19.default.blue(this.symbols.info);
|
|
70887
71424
|
}
|
|
70888
71425
|
}
|
|
70889
71426
|
renderHealingSummary(healSummary) {
|
|
70890
71427
|
console.log("│");
|
|
70891
|
-
console.log(`│ ${
|
|
70892
|
-
console.log(`│ ${
|
|
71428
|
+
console.log(`│ ${import_picocolors19.default.bold(import_picocolors19.default.cyan("AUTO-HEAL RESULTS"))}`);
|
|
71429
|
+
console.log(`│ ${import_picocolors19.default.dim("─".repeat(50))}`);
|
|
70893
71430
|
for (const fix of healSummary.fixes) {
|
|
70894
|
-
const symbol = fix.success ?
|
|
70895
|
-
console.log(`│ ${symbol} ${
|
|
71431
|
+
const symbol = fix.success ? import_picocolors19.default.green(this.symbols.pass) : import_picocolors19.default.red(this.symbols.fail);
|
|
71432
|
+
console.log(`│ ${symbol} ${import_picocolors19.default.bold(fix.checkName)} ${import_picocolors19.default.dim(fix.message)}`);
|
|
70896
71433
|
if (!fix.success && fix.error) {
|
|
70897
|
-
console.log(`│ ${
|
|
71434
|
+
console.log(`│ ${import_picocolors19.default.red(`Error: ${fix.error}`)}`);
|
|
70898
71435
|
}
|
|
70899
71436
|
}
|
|
70900
71437
|
console.log("│");
|
|
70901
|
-
console.log(`│ Fixed: ${
|
|
71438
|
+
console.log(`│ Fixed: ${import_picocolors19.default.green(String(healSummary.succeeded))}, Failed: ${import_picocolors19.default.red(String(healSummary.failed))}`);
|
|
70902
71439
|
}
|
|
70903
71440
|
groupChecks(checks) {
|
|
70904
71441
|
const groups = new Map;
|
|
@@ -70912,11 +71449,11 @@ class DoctorUIRenderer {
|
|
|
70912
71449
|
colorizeValue(status2, message) {
|
|
70913
71450
|
switch (status2) {
|
|
70914
71451
|
case "pass":
|
|
70915
|
-
return
|
|
71452
|
+
return import_picocolors19.default.green(message);
|
|
70916
71453
|
case "warn":
|
|
70917
|
-
return
|
|
71454
|
+
return import_picocolors19.default.yellow(message);
|
|
70918
71455
|
case "fail":
|
|
70919
|
-
return
|
|
71456
|
+
return import_picocolors19.default.red(message);
|
|
70920
71457
|
default:
|
|
70921
71458
|
return message;
|
|
70922
71459
|
}
|
|
@@ -70935,23 +71472,23 @@ class DoctorUIRenderer {
|
|
|
70935
71472
|
renderSummaryLine(summary) {
|
|
70936
71473
|
const parts = [];
|
|
70937
71474
|
if (summary.passed > 0) {
|
|
70938
|
-
parts.push(
|
|
71475
|
+
parts.push(import_picocolors19.default.green(`${summary.passed} ${this.symbols.pass}`));
|
|
70939
71476
|
}
|
|
70940
71477
|
if (summary.warnings > 0) {
|
|
70941
|
-
parts.push(
|
|
71478
|
+
parts.push(import_picocolors19.default.yellow(`${summary.warnings} ${this.symbols.warn}`));
|
|
70942
71479
|
}
|
|
70943
71480
|
if (summary.failed > 0) {
|
|
70944
|
-
parts.push(
|
|
71481
|
+
parts.push(import_picocolors19.default.red(`${summary.failed} ${this.symbols.fail}`));
|
|
70945
71482
|
}
|
|
70946
|
-
console.log(`│ ${
|
|
71483
|
+
console.log(`│ ${import_picocolors19.default.dim("─".repeat(50))}`);
|
|
70947
71484
|
console.log(`│ Summary: ${parts.join(" ")}`);
|
|
70948
71485
|
console.log("│");
|
|
70949
|
-
console.log(`│ ${
|
|
70950
|
-
console.log(`│ ${
|
|
70951
|
-
console.log(`│ ${
|
|
70952
|
-
console.log(`│ ${
|
|
70953
|
-
console.log(`│ ${
|
|
70954
|
-
console.log(`│ ${
|
|
71486
|
+
console.log(`│ ${import_picocolors19.default.dim("Quick Commands:")}`);
|
|
71487
|
+
console.log(`│ ${import_picocolors19.default.dim(" tkm init Install/update Takumi in project")}`);
|
|
71488
|
+
console.log(`│ ${import_picocolors19.default.dim(" tkm init -g Install/update Takumi globally")}`);
|
|
71489
|
+
console.log(`│ ${import_picocolors19.default.dim(" tkm update Update the CLI tool")}`);
|
|
71490
|
+
console.log(`│ ${import_picocolors19.default.dim(" tkm uninstall Remove Takumi from project/global")}`);
|
|
71491
|
+
console.log(`│ ${import_picocolors19.default.dim(" tkm --help Show all commands")}`);
|
|
70955
71492
|
}
|
|
70956
71493
|
}
|
|
70957
71494
|
// src/commands/doctor.ts
|
|
@@ -71351,7 +71888,7 @@ var conventionQualityGate = {
|
|
|
71351
71888
|
};
|
|
71352
71889
|
|
|
71353
71890
|
// src/domains/hooks/handlers/extension-skill/handler.ts
|
|
71354
|
-
import
|
|
71891
|
+
import fs21 from "node:fs";
|
|
71355
71892
|
import os7 from "node:os";
|
|
71356
71893
|
import path9 from "node:path";
|
|
71357
71894
|
var CONFIG_KEY2 = "skill-extension-loader";
|
|
@@ -71446,7 +71983,7 @@ function resolveLocalExtDir(skillDir, roots) {
|
|
|
71446
71983
|
const extDir = path9.resolve(skillsRoot, skillDir, "extensions");
|
|
71447
71984
|
if (extDir !== skillsRoot && !extDir.startsWith(skillsRoot + path9.sep))
|
|
71448
71985
|
continue;
|
|
71449
|
-
if (
|
|
71986
|
+
if (fs21.existsSync(extDir))
|
|
71450
71987
|
return extDir;
|
|
71451
71988
|
}
|
|
71452
71989
|
return null;
|
|
@@ -71462,14 +71999,14 @@ function resolveSharedExtDir(skillDir, sharedDirRaw, projectRoot) {
|
|
|
71462
71999
|
const cand = path9.resolve(sharedRoot, skillDir);
|
|
71463
72000
|
if (cand !== sharedRoot && !cand.startsWith(sharedRoot + path9.sep))
|
|
71464
72001
|
return null;
|
|
71465
|
-
return
|
|
72002
|
+
return fs21.existsSync(cand) ? cand : null;
|
|
71466
72003
|
}
|
|
71467
72004
|
function readExtensionsFromDir(extDir, skillDir, cwd2) {
|
|
71468
72005
|
const kept = [];
|
|
71469
72006
|
const skipped = [];
|
|
71470
72007
|
let entries;
|
|
71471
72008
|
try {
|
|
71472
|
-
entries =
|
|
72009
|
+
entries = fs21.readdirSync(extDir, { withFileTypes: true });
|
|
71473
72010
|
} catch {
|
|
71474
72011
|
return { kept, skipped };
|
|
71475
72012
|
}
|
|
@@ -71479,7 +72016,7 @@ function readExtensionsFromDir(extDir, skillDir, cwd2) {
|
|
|
71479
72016
|
const absPath = path9.join(extDir, entry.name);
|
|
71480
72017
|
let raw;
|
|
71481
72018
|
try {
|
|
71482
|
-
raw =
|
|
72019
|
+
raw = fs21.readFileSync(absPath, "utf8");
|
|
71483
72020
|
} catch {
|
|
71484
72021
|
skipped.push(entry.name);
|
|
71485
72022
|
continue;
|
|
@@ -72633,7 +73170,7 @@ function bucketTokens(records) {
|
|
|
72633
73170
|
|
|
72634
73171
|
// src/domains/hooks/telemetry/lib/session-lock.ts
|
|
72635
73172
|
var import_proper_lockfile9 = __toESM(require_proper_lockfile(), 1);
|
|
72636
|
-
import { promises as
|
|
73173
|
+
import { promises as fs22 } from "node:fs";
|
|
72637
73174
|
import { join as join100 } from "node:path";
|
|
72638
73175
|
var LOCK_RESOURCE = "summary.json";
|
|
72639
73176
|
var DEFAULT_TIMEOUT_MS3 = 2000;
|
|
@@ -72644,7 +73181,7 @@ async function withSummaryLock(sessionDir, fn, options2 = {}) {
|
|
|
72644
73181
|
const staleAfterMs = options2.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
|
|
72645
73182
|
const resource = join100(sessionDir, LOCK_RESOURCE);
|
|
72646
73183
|
try {
|
|
72647
|
-
await
|
|
73184
|
+
await fs22.mkdir(sessionDir, { recursive: true });
|
|
72648
73185
|
} catch {
|
|
72649
73186
|
return fn();
|
|
72650
73187
|
}
|
|
@@ -72674,7 +73211,7 @@ async function withSummaryLock(sessionDir, fn, options2 = {}) {
|
|
|
72674
73211
|
}
|
|
72675
73212
|
|
|
72676
73213
|
// src/domains/hooks/telemetry/lib/summary.ts
|
|
72677
|
-
import { promises as
|
|
73214
|
+
import { promises as fs23 } from "node:fs";
|
|
72678
73215
|
|
|
72679
73216
|
// src/domains/hooks/telemetry/lib/session-paths.ts
|
|
72680
73217
|
init_paths2();
|
|
@@ -72785,7 +73322,7 @@ function initialSummary(args) {
|
|
|
72785
73322
|
async function readSummary(sessionDir) {
|
|
72786
73323
|
let raw;
|
|
72787
73324
|
try {
|
|
72788
|
-
raw = await
|
|
73325
|
+
raw = await fs23.readFile(getSummaryFile(sessionDir), "utf8");
|
|
72789
73326
|
} catch {
|
|
72790
73327
|
return null;
|
|
72791
73328
|
}
|
|
@@ -72796,11 +73333,11 @@ async function readSummary(sessionDir) {
|
|
|
72796
73333
|
}
|
|
72797
73334
|
}
|
|
72798
73335
|
async function writeSummary(sessionDir, summary) {
|
|
72799
|
-
await
|
|
73336
|
+
await fs23.mkdir(sessionDir, { recursive: true });
|
|
72800
73337
|
const target = getSummaryFile(sessionDir);
|
|
72801
73338
|
const tmp = `${target}.tmp`;
|
|
72802
|
-
await
|
|
72803
|
-
await
|
|
73339
|
+
await fs23.writeFile(tmp, JSON.stringify(summary), "utf8");
|
|
73340
|
+
await fs23.rename(tmp, target);
|
|
72804
73341
|
}
|
|
72805
73342
|
function isPlainObject2(value) {
|
|
72806
73343
|
return typeof value === "object" && value !== null && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
@@ -73140,11 +73677,11 @@ function closeBusyInterval(summary, nowIso) {
|
|
|
73140
73677
|
}
|
|
73141
73678
|
|
|
73142
73679
|
// src/domains/hooks/telemetry/lib/session-meta.ts
|
|
73143
|
-
import { promises as
|
|
73680
|
+
import { promises as fs24 } from "node:fs";
|
|
73144
73681
|
async function readMeta(sessionDir) {
|
|
73145
73682
|
let raw;
|
|
73146
73683
|
try {
|
|
73147
|
-
raw = await
|
|
73684
|
+
raw = await fs24.readFile(getMetaFile(sessionDir), "utf8");
|
|
73148
73685
|
} catch {
|
|
73149
73686
|
return null;
|
|
73150
73687
|
}
|
|
@@ -73157,13 +73694,13 @@ async function readMeta(sessionDir) {
|
|
|
73157
73694
|
async function writeMetaIfAbsent(sessionDir, meta) {
|
|
73158
73695
|
const target = getMetaFile(sessionDir);
|
|
73159
73696
|
try {
|
|
73160
|
-
await
|
|
73697
|
+
await fs24.access(target);
|
|
73161
73698
|
return;
|
|
73162
73699
|
} catch {}
|
|
73163
|
-
await
|
|
73700
|
+
await fs24.mkdir(sessionDir, { recursive: true });
|
|
73164
73701
|
const tmp = `${target}.tmp`;
|
|
73165
|
-
await
|
|
73166
|
-
await
|
|
73702
|
+
await fs24.writeFile(tmp, JSON.stringify(meta), "utf8");
|
|
73703
|
+
await fs24.rename(tmp, target);
|
|
73167
73704
|
}
|
|
73168
73705
|
|
|
73169
73706
|
// src/domains/hooks/telemetry/lib/session-payload.ts
|
|
@@ -73202,12 +73739,12 @@ function buildSessionPayload(args) {
|
|
|
73202
73739
|
}
|
|
73203
73740
|
|
|
73204
73741
|
// src/domains/hooks/telemetry/lib/throttle.ts
|
|
73205
|
-
import { promises as
|
|
73742
|
+
import { promises as fs25 } from "node:fs";
|
|
73206
73743
|
var defaultNow = () => Date.now();
|
|
73207
73744
|
async function readLastPush(sessionDir) {
|
|
73208
73745
|
let raw;
|
|
73209
73746
|
try {
|
|
73210
|
-
raw = await
|
|
73747
|
+
raw = await fs25.readFile(getLastPushFile(sessionDir), "utf8");
|
|
73211
73748
|
} catch {
|
|
73212
73749
|
return null;
|
|
73213
73750
|
}
|
|
@@ -73215,11 +73752,11 @@ async function readLastPush(sessionDir) {
|
|
|
73215
73752
|
return Number.isFinite(parsed) ? parsed : null;
|
|
73216
73753
|
}
|
|
73217
73754
|
async function writeLastPush(sessionDir, ts) {
|
|
73218
|
-
await
|
|
73755
|
+
await fs25.mkdir(sessionDir, { recursive: true });
|
|
73219
73756
|
const target = getLastPushFile(sessionDir);
|
|
73220
73757
|
const tmp = `${target}.tmp`;
|
|
73221
|
-
await
|
|
73222
|
-
await
|
|
73758
|
+
await fs25.writeFile(tmp, String(ts), "utf8");
|
|
73759
|
+
await fs25.rename(tmp, target);
|
|
73223
73760
|
}
|
|
73224
73761
|
async function shouldFlush(args) {
|
|
73225
73762
|
const now = args.now ?? defaultNow;
|
|
@@ -73229,7 +73766,7 @@ async function shouldFlush(args) {
|
|
|
73229
73766
|
if (now() - last >= args.intervalMs)
|
|
73230
73767
|
return true;
|
|
73231
73768
|
try {
|
|
73232
|
-
const stat8 = await
|
|
73769
|
+
const stat8 = await fs25.stat(getEventsFile(args.sessionDir));
|
|
73233
73770
|
if (stat8.size >= args.sizeBytes)
|
|
73234
73771
|
return true;
|
|
73235
73772
|
} catch {}
|
|
@@ -73299,12 +73836,12 @@ async function runSessionEndFlush(data, ctx) {
|
|
|
73299
73836
|
...reason ? { session_end_reason: reason } : {},
|
|
73300
73837
|
session_end_raw: data
|
|
73301
73838
|
};
|
|
73302
|
-
const { promises:
|
|
73839
|
+
const { promises: fs26 } = await import("node:fs");
|
|
73303
73840
|
const { join: join106 } = await import("node:path");
|
|
73304
73841
|
const target = join106(sessionDir, "meta.json");
|
|
73305
73842
|
const tmp = `${target}.tmp`;
|
|
73306
|
-
await
|
|
73307
|
-
await
|
|
73843
|
+
await fs26.writeFile(tmp, JSON.stringify(updated), "utf8");
|
|
73844
|
+
await fs26.rename(tmp, target);
|
|
73308
73845
|
} else if (!existingMeta) {
|
|
73309
73846
|
await writeMetaIfAbsent(sessionDir, {
|
|
73310
73847
|
agent,
|
|
@@ -73376,7 +73913,7 @@ async function handleSessionEnd(agent, flags = {}) {
|
|
|
73376
73913
|
init_takumi_constants();
|
|
73377
73914
|
|
|
73378
73915
|
// src/domains/hooks/telemetry/lib/codex-tokens.ts
|
|
73379
|
-
import * as
|
|
73916
|
+
import * as fs26 from "node:fs";
|
|
73380
73917
|
function n(v2) {
|
|
73381
73918
|
return typeof v2 === "number" && Number.isFinite(v2) ? v2 : 0;
|
|
73382
73919
|
}
|
|
@@ -73400,7 +73937,7 @@ function codexTokensOf(rec) {
|
|
|
73400
73937
|
}
|
|
73401
73938
|
function sumCodexChildTokens(jsonlPath) {
|
|
73402
73939
|
const acc = { input: 0, output: 0, cache_read: 0, cache_write: 0 };
|
|
73403
|
-
if (!jsonlPath || !
|
|
73940
|
+
if (!jsonlPath || !fs26.existsSync(jsonlPath))
|
|
73404
73941
|
return acc;
|
|
73405
73942
|
const { records } = readNew(jsonlPath, 0);
|
|
73406
73943
|
for (const rec of records) {
|
|
@@ -73486,12 +74023,12 @@ async function applyCodexTranscriptDelta(args) {
|
|
|
73486
74023
|
}
|
|
73487
74024
|
|
|
73488
74025
|
// src/domains/hooks/lib/jsonl-append.ts
|
|
73489
|
-
import { promises as
|
|
74026
|
+
import { promises as fs27, appendFileSync as appendFileSync2, mkdirSync as mkdirSync5 } from "node:fs";
|
|
73490
74027
|
import { dirname as dirname28 } from "node:path";
|
|
73491
74028
|
async function appendJsonl(filePath, record) {
|
|
73492
74029
|
try {
|
|
73493
|
-
await
|
|
73494
|
-
await
|
|
74030
|
+
await fs27.mkdir(dirname28(filePath), { recursive: true });
|
|
74031
|
+
await fs27.appendFile(filePath, `${JSON.stringify(record)}
|
|
73495
74032
|
`, "utf8");
|
|
73496
74033
|
} catch {}
|
|
73497
74034
|
}
|
|
@@ -73788,15 +74325,15 @@ async function handleStop(agent, flags = {}) {
|
|
|
73788
74325
|
|
|
73789
74326
|
// src/domains/hooks/telemetry/otlp/observations-export.ts
|
|
73790
74327
|
init_paths2();
|
|
73791
|
-
import { promises as
|
|
74328
|
+
import { promises as fs31, openSync as openSync9 } from "node:fs";
|
|
73792
74329
|
import { join as join107 } from "node:path";
|
|
73793
74330
|
|
|
73794
74331
|
// src/domains/hooks/telemetry/lib/retention.ts
|
|
73795
|
-
import { promises as
|
|
74332
|
+
import { promises as fs28 } from "node:fs";
|
|
73796
74333
|
import { join as join106 } from "node:path";
|
|
73797
74334
|
async function pathExists25(path10) {
|
|
73798
74335
|
try {
|
|
73799
|
-
await
|
|
74336
|
+
await fs28.access(path10);
|
|
73800
74337
|
return true;
|
|
73801
74338
|
} catch {
|
|
73802
74339
|
return false;
|
|
@@ -73808,7 +74345,7 @@ async function hasUnexportedObservations(dir) {
|
|
|
73808
74345
|
async function decideDelete(dir, args) {
|
|
73809
74346
|
let mtimeMs = 0;
|
|
73810
74347
|
try {
|
|
73811
|
-
const stat8 = await
|
|
74348
|
+
const stat8 = await fs28.stat(dir);
|
|
73812
74349
|
if (!stat8.isDirectory())
|
|
73813
74350
|
return false;
|
|
73814
74351
|
mtimeMs = stat8.mtimeMs;
|
|
@@ -73827,7 +74364,7 @@ async function decideDelete(dir, args) {
|
|
|
73827
74364
|
}
|
|
73828
74365
|
async function listChildren(dir) {
|
|
73829
74366
|
try {
|
|
73830
|
-
const names = await
|
|
74367
|
+
const names = await fs28.readdir(dir);
|
|
73831
74368
|
return names.map((n2) => join106(dir, n2));
|
|
73832
74369
|
} catch {
|
|
73833
74370
|
return [];
|
|
@@ -73863,7 +74400,7 @@ async function sweepRetention(args) {
|
|
|
73863
74400
|
continue;
|
|
73864
74401
|
}
|
|
73865
74402
|
try {
|
|
73866
|
-
await
|
|
74403
|
+
await fs28.rm(dir, { recursive: true, force: true });
|
|
73867
74404
|
deleted.push(dir);
|
|
73868
74405
|
} catch {}
|
|
73869
74406
|
}
|
|
@@ -73871,10 +74408,10 @@ async function sweepRetention(args) {
|
|
|
73871
74408
|
}
|
|
73872
74409
|
|
|
73873
74410
|
// src/domains/hooks/telemetry/otlp/observations-export-state.ts
|
|
73874
|
-
import { promises as
|
|
74411
|
+
import { promises as fs29 } from "node:fs";
|
|
73875
74412
|
async function exists(path10) {
|
|
73876
74413
|
try {
|
|
73877
|
-
await
|
|
74414
|
+
await fs29.access(path10);
|
|
73878
74415
|
return true;
|
|
73879
74416
|
} catch {
|
|
73880
74417
|
return false;
|
|
@@ -73886,7 +74423,7 @@ async function stageObservationsForFlush(sessionDir) {
|
|
|
73886
74423
|
return flushing;
|
|
73887
74424
|
const live = getObservationsFile(sessionDir);
|
|
73888
74425
|
try {
|
|
73889
|
-
await
|
|
74426
|
+
await fs29.rename(live, flushing);
|
|
73890
74427
|
return flushing;
|
|
73891
74428
|
} catch {
|
|
73892
74429
|
return null;
|
|
@@ -73894,15 +74431,15 @@ async function stageObservationsForFlush(sessionDir) {
|
|
|
73894
74431
|
}
|
|
73895
74432
|
async function completeObservationsFlush(sessionDir, flushingPath, now) {
|
|
73896
74433
|
try {
|
|
73897
|
-
await
|
|
74434
|
+
await fs29.writeFile(getObservationsPushedFile(sessionDir), String(now), "utf8");
|
|
73898
74435
|
} catch {}
|
|
73899
74436
|
try {
|
|
73900
|
-
await
|
|
74437
|
+
await fs29.rm(flushingPath, { force: true });
|
|
73901
74438
|
} catch {}
|
|
73902
74439
|
}
|
|
73903
74440
|
async function readObsPushed(sessionDir) {
|
|
73904
74441
|
try {
|
|
73905
|
-
const raw = await
|
|
74442
|
+
const raw = await fs29.readFile(getObservationsPushedFile(sessionDir), "utf8");
|
|
73906
74443
|
const parsed = Number.parseInt(raw.trim(), 10);
|
|
73907
74444
|
return Number.isFinite(parsed) ? parsed : null;
|
|
73908
74445
|
} catch {
|
|
@@ -73917,7 +74454,7 @@ async function shouldFlushObservations(sessionDir, gate) {
|
|
|
73917
74454
|
return true;
|
|
73918
74455
|
let size = 0;
|
|
73919
74456
|
try {
|
|
73920
|
-
size = (await
|
|
74457
|
+
size = (await fs29.stat(getObservationsFile(sessionDir))).size;
|
|
73921
74458
|
} catch {
|
|
73922
74459
|
return false;
|
|
73923
74460
|
}
|
|
@@ -73944,7 +74481,7 @@ async function resolveOtlpConfig() {
|
|
|
73944
74481
|
|
|
73945
74482
|
// src/domains/hooks/telemetry/otlp/otlp-post.ts
|
|
73946
74483
|
import { spawn as spawn3 } from "node:child_process";
|
|
73947
|
-
import { promises as
|
|
74484
|
+
import { promises as fs30, openSync as openSync8 } from "node:fs";
|
|
73948
74485
|
|
|
73949
74486
|
// src/domains/hooks/telemetry/otlp/otlp-payload-builder.ts
|
|
73950
74487
|
import { createHash as createHash13 } from "node:crypto";
|
|
@@ -74129,7 +74666,7 @@ async function runOtlpPost(job, deps = {}) {
|
|
|
74129
74666
|
const now = deps.now ?? Date.now;
|
|
74130
74667
|
let content;
|
|
74131
74668
|
try {
|
|
74132
|
-
content = await
|
|
74669
|
+
content = await fs30.readFile(job.flushingPath, "utf8");
|
|
74133
74670
|
} catch {
|
|
74134
74671
|
return { ok: false, skipped: true, error: "no_flushing_file" };
|
|
74135
74672
|
}
|
|
@@ -74273,7 +74810,7 @@ function lockPath() {
|
|
|
74273
74810
|
async function acquireSweepLock(now) {
|
|
74274
74811
|
const path10 = lockPath();
|
|
74275
74812
|
try {
|
|
74276
|
-
await
|
|
74813
|
+
await fs31.mkdir(getConfigDir(), { recursive: true });
|
|
74277
74814
|
} catch {
|
|
74278
74815
|
return false;
|
|
74279
74816
|
}
|
|
@@ -74282,9 +74819,9 @@ async function acquireSweepLock(now) {
|
|
|
74282
74819
|
return true;
|
|
74283
74820
|
} catch {
|
|
74284
74821
|
try {
|
|
74285
|
-
const stat8 = await
|
|
74822
|
+
const stat8 = await fs31.stat(path10);
|
|
74286
74823
|
if (now - stat8.mtimeMs > STALE_LOCK_MS) {
|
|
74287
|
-
await
|
|
74824
|
+
await fs31.rm(path10, { force: true });
|
|
74288
74825
|
openSync9(path10, "wx");
|
|
74289
74826
|
return true;
|
|
74290
74827
|
}
|
|
@@ -74294,7 +74831,7 @@ async function acquireSweepLock(now) {
|
|
|
74294
74831
|
}
|
|
74295
74832
|
async function releaseSweepLock() {
|
|
74296
74833
|
try {
|
|
74297
|
-
await
|
|
74834
|
+
await fs31.rm(lockPath(), { force: true });
|
|
74298
74835
|
} catch {}
|
|
74299
74836
|
}
|
|
74300
74837
|
async function flushOrphanObservations(deps = {}) {
|
|
@@ -79615,7 +80152,7 @@ function releaseEntryToGitHubRelease(entry, kit) {
|
|
|
79615
80152
|
init_logger();
|
|
79616
80153
|
init_dist2();
|
|
79617
80154
|
init_release_filter();
|
|
79618
|
-
var
|
|
80155
|
+
var import_picocolors22 = __toESM(require_picocolors(), 1);
|
|
79619
80156
|
|
|
79620
80157
|
// src/domains/versioning/selection/version-filter.ts
|
|
79621
80158
|
var VERSION_PATTERN = /^v?\d+\.\d+\.\d+(-[a-zA-Z0-9.]+)?$/;
|
|
@@ -79633,36 +80170,36 @@ function normalizeVersionTag(version3) {
|
|
|
79633
80170
|
init_environment();
|
|
79634
80171
|
init_logger();
|
|
79635
80172
|
init_dist2();
|
|
79636
|
-
var
|
|
80173
|
+
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
79637
80174
|
|
|
79638
80175
|
// src/domains/versioning/version-display.ts
|
|
79639
|
-
var
|
|
80176
|
+
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
79640
80177
|
|
|
79641
80178
|
class VersionDisplayFormatter {
|
|
79642
80179
|
static createBadges(release) {
|
|
79643
80180
|
const badges = [];
|
|
79644
80181
|
if (release.isLatestStable) {
|
|
79645
|
-
badges.push(
|
|
80182
|
+
badges.push(import_picocolors20.default.bold(import_picocolors20.default.yellow("[latest]")));
|
|
79646
80183
|
}
|
|
79647
80184
|
if (release.prerelease || release.isLatestBeta) {
|
|
79648
80185
|
if (release.isLatestBeta) {
|
|
79649
|
-
badges.push(
|
|
80186
|
+
badges.push(import_picocolors20.default.bold(import_picocolors20.default.magenta("[beta]")));
|
|
79650
80187
|
} else {
|
|
79651
|
-
badges.push(
|
|
80188
|
+
badges.push(import_picocolors20.default.magenta("[prerelease]"));
|
|
79652
80189
|
}
|
|
79653
80190
|
} else if (!release.draft) {
|
|
79654
|
-
badges.push(
|
|
80191
|
+
badges.push(import_picocolors20.default.blue("[stable]"));
|
|
79655
80192
|
}
|
|
79656
80193
|
if (release.draft) {
|
|
79657
|
-
badges.push(
|
|
80194
|
+
badges.push(import_picocolors20.default.gray("[draft]"));
|
|
79658
80195
|
}
|
|
79659
80196
|
return badges.length > 0 ? ` ${badges.join(" ")}` : "";
|
|
79660
80197
|
}
|
|
79661
80198
|
static formatChoiceLabel(release) {
|
|
79662
|
-
const version3 =
|
|
80199
|
+
const version3 = import_picocolors20.default.green(release.displayVersion);
|
|
79663
80200
|
const badges = VersionDisplayFormatter.createBadges(release);
|
|
79664
80201
|
const name2 = release.name || "Release";
|
|
79665
|
-
return `${version3}${badges} ${
|
|
80202
|
+
return `${version3}${badges} ${import_picocolors20.default.dim(name2)}`;
|
|
79666
80203
|
}
|
|
79667
80204
|
static formatChoiceHint(release) {
|
|
79668
80205
|
const parts = [];
|
|
@@ -79684,7 +80221,7 @@ class VersionDisplayFormatter {
|
|
|
79684
80221
|
if (latestStable) {
|
|
79685
80222
|
options2.push({
|
|
79686
80223
|
value: latestStable.tag_name,
|
|
79687
|
-
label: `${
|
|
80224
|
+
label: `${import_picocolors20.default.bold(import_picocolors20.default.green("Latest Stable"))} (${latestStable.displayVersion})`,
|
|
79688
80225
|
hint: "recommended version",
|
|
79689
80226
|
isLatest: true,
|
|
79690
80227
|
isPrerelease: false
|
|
@@ -79694,7 +80231,7 @@ class VersionDisplayFormatter {
|
|
|
79694
80231
|
if (latestBeta) {
|
|
79695
80232
|
options2.push({
|
|
79696
80233
|
value: latestBeta.tag_name,
|
|
79697
|
-
label: `${
|
|
80234
|
+
label: `${import_picocolors20.default.bold(import_picocolors20.default.magenta("Latest Beta"))} (${latestBeta.displayVersion})`,
|
|
79698
80235
|
hint: "latest features, may be unstable",
|
|
79699
80236
|
isLatest: false,
|
|
79700
80237
|
isPrerelease: true
|
|
@@ -79705,7 +80242,7 @@ class VersionDisplayFormatter {
|
|
|
79705
80242
|
static createSeparator() {
|
|
79706
80243
|
return {
|
|
79707
80244
|
value: "separator",
|
|
79708
|
-
label:
|
|
80245
|
+
label: import_picocolors20.default.dim("─".repeat(50)),
|
|
79709
80246
|
hint: undefined,
|
|
79710
80247
|
isLatest: false,
|
|
79711
80248
|
isPrerelease: false
|
|
@@ -79714,7 +80251,7 @@ class VersionDisplayFormatter {
|
|
|
79714
80251
|
static createCancelOption() {
|
|
79715
80252
|
return {
|
|
79716
80253
|
value: "cancel",
|
|
79717
|
-
label:
|
|
80254
|
+
label: import_picocolors20.default.red("Cancel"),
|
|
79718
80255
|
hint: "exit version selection",
|
|
79719
80256
|
isLatest: false,
|
|
79720
80257
|
isPrerelease: false
|
|
@@ -79766,15 +80303,15 @@ class VersionDisplayFormatter {
|
|
|
79766
80303
|
return value !== "separator" && value !== "cancel" && value.trim().length > 0;
|
|
79767
80304
|
}
|
|
79768
80305
|
static formatError(message, suggestion) {
|
|
79769
|
-
let output2 =
|
|
80306
|
+
let output2 = import_picocolors20.default.red(`Error: ${message}`);
|
|
79770
80307
|
if (suggestion) {
|
|
79771
80308
|
output2 += `
|
|
79772
|
-
${
|
|
80309
|
+
${import_picocolors20.default.dim(suggestion)}`;
|
|
79773
80310
|
}
|
|
79774
80311
|
return output2;
|
|
79775
80312
|
}
|
|
79776
80313
|
static formatSuccess(version3, kitName) {
|
|
79777
|
-
return `${
|
|
80314
|
+
return `${import_picocolors20.default.green("✓")} Selected ${import_picocolors20.default.bold(version3)} for ${import_picocolors20.default.bold(kitName)}`;
|
|
79778
80315
|
}
|
|
79779
80316
|
}
|
|
79780
80317
|
|
|
@@ -79784,7 +80321,7 @@ async function handleNoReleases(kit, allowManualEntry) {
|
|
|
79784
80321
|
This could be due to:
|
|
79785
80322
|
• No releases published yet
|
|
79786
80323
|
• Network connectivity issues
|
|
79787
|
-
• Repository access permissions`,
|
|
80324
|
+
• Repository access permissions`, import_picocolors21.default.yellow("No Releases Available"));
|
|
79788
80325
|
if (!allowManualEntry) {
|
|
79789
80326
|
throw new Error(`No releases available for ${kit.name}`);
|
|
79790
80327
|
}
|
|
@@ -79844,34 +80381,34 @@ async function createVersionPrompt(kit, choices, _defaultIndex, allowManualEntry
|
|
|
79844
80381
|
if (latestStable) {
|
|
79845
80382
|
clackChoices.push({
|
|
79846
80383
|
value: latestStable.tag_name,
|
|
79847
|
-
label: `${
|
|
80384
|
+
label: `${import_picocolors21.default.bold(import_picocolors21.default.green("Latest Stable"))} (${latestStable.displayVersion})`,
|
|
79848
80385
|
hint: "recommended"
|
|
79849
80386
|
});
|
|
79850
80387
|
}
|
|
79851
80388
|
if (allowManualEntry) {
|
|
79852
80389
|
clackChoices.push({
|
|
79853
80390
|
value: "manual-entry",
|
|
79854
|
-
label:
|
|
80391
|
+
label: import_picocolors21.default.cyan("↳ Enter Version Manually"),
|
|
79855
80392
|
hint: "for older versions"
|
|
79856
80393
|
});
|
|
79857
80394
|
}
|
|
79858
80395
|
clackChoices.push({
|
|
79859
80396
|
value: "cancel",
|
|
79860
|
-
label:
|
|
80397
|
+
label: import_picocolors21.default.red("✕ Cancel")
|
|
79861
80398
|
});
|
|
79862
80399
|
const versionChoices = choices.filter((choice) => choice.value !== "separator" && choice.value !== "cancel");
|
|
79863
80400
|
for (const choice of versionChoices) {
|
|
79864
80401
|
const isCurrentlyInstalled = currentVersion && (choice.value === currentVersion || choice.value === `v${currentVersion}`);
|
|
79865
|
-
const installedMarker = isCurrentlyInstalled ?
|
|
80402
|
+
const installedMarker = isCurrentlyInstalled ? import_picocolors21.default.cyan(" (installed)") : "";
|
|
79866
80403
|
clackChoices.push({
|
|
79867
80404
|
value: choice.value,
|
|
79868
80405
|
label: `${choice.label}${installedMarker}`,
|
|
79869
80406
|
hint: choice.hint
|
|
79870
80407
|
});
|
|
79871
80408
|
}
|
|
79872
|
-
const currentVersionHint = currentVersion ?
|
|
80409
|
+
const currentVersionHint = currentVersion ? import_picocolors21.default.dim(` (current: ${currentVersion})`) : "";
|
|
79873
80410
|
const selected = await ie({
|
|
79874
|
-
message: `Select version for ${
|
|
80411
|
+
message: `Select version for ${import_picocolors21.default.bold(kit.name)}${currentVersionHint}:`,
|
|
79875
80412
|
options: clackChoices,
|
|
79876
80413
|
initialValue: latestStable?.tag_name
|
|
79877
80414
|
});
|
|
@@ -79896,15 +80433,15 @@ async function createVersionPrompt(kit, choices, _defaultIndex, allowManualEntry
|
|
|
79896
80433
|
async function handleSelectionError(error, kit, allowManualEntry, retryCallback) {
|
|
79897
80434
|
logger.error(`Version selection error: ${error.message}`);
|
|
79898
80435
|
if (error.message.includes("401") || error.message.includes("403")) {
|
|
79899
|
-
le(VersionDisplayFormatter.formatError("Authentication failed", "Please check your GitHub token with: tkm auth"),
|
|
80436
|
+
le(VersionDisplayFormatter.formatError("Authentication failed", "Please check your GitHub token with: tkm auth"), import_picocolors21.default.red("Authentication Error"));
|
|
79900
80437
|
} else if (error.message.includes("404")) {
|
|
79901
|
-
le(VersionDisplayFormatter.formatError("Repository access denied", "Make sure you have access to the repository"),
|
|
80438
|
+
le(VersionDisplayFormatter.formatError("Repository access denied", "Make sure you have access to the repository"), import_picocolors21.default.red("Access Error"));
|
|
79902
80439
|
} else if (error.message.includes("rate limit") || error.message.includes("403")) {
|
|
79903
|
-
le(VersionDisplayFormatter.formatError("GitHub API rate limit exceeded", "Please wait a moment and try again"),
|
|
80440
|
+
le(VersionDisplayFormatter.formatError("GitHub API rate limit exceeded", "Please wait a moment and try again"), import_picocolors21.default.yellow("Rate Limited"));
|
|
79904
80441
|
} else if (error.message.includes("network") || error.message.includes("ENOTFOUND")) {
|
|
79905
|
-
le(VersionDisplayFormatter.formatError("Network connection failed", "Please check your internet connection"),
|
|
80442
|
+
le(VersionDisplayFormatter.formatError("Network connection failed", "Please check your internet connection"), import_picocolors21.default.yellow("Network Error"));
|
|
79906
80443
|
} else {
|
|
79907
|
-
le(VersionDisplayFormatter.formatError(error.message || "Unknown error occurred", "Please try again or contact support"),
|
|
80444
|
+
le(VersionDisplayFormatter.formatError(error.message || "Unknown error occurred", "Please try again or contact support"), import_picocolors21.default.red("Error"));
|
|
79908
80445
|
}
|
|
79909
80446
|
if (isNonInteractive()) {
|
|
79910
80447
|
logger.warning("Non-interactive mode: version selection failed, cannot retry");
|
|
@@ -79966,7 +80503,7 @@ class VersionSelector {
|
|
|
79966
80503
|
} = options2;
|
|
79967
80504
|
try {
|
|
79968
80505
|
const loadingSpinner = de();
|
|
79969
|
-
loadingSpinner.start(`Fetching versions for ${
|
|
80506
|
+
loadingSpinner.start(`Fetching versions for ${import_picocolors22.default.bold(kit.name)}...`);
|
|
79970
80507
|
let releases;
|
|
79971
80508
|
if (useGh) {
|
|
79972
80509
|
releases = await this.githubClient.listReleasesWithCache(kit, {
|
|
@@ -80599,18 +81136,18 @@ async function dispatchInstallers(ctx, targetAgents2, lifecycle) {
|
|
|
80599
81136
|
init_logger();
|
|
80600
81137
|
// src/domains/installation/download-extractor.ts
|
|
80601
81138
|
init_auth_client();
|
|
80602
|
-
import * as
|
|
81139
|
+
import * as fs33 from "node:fs";
|
|
80603
81140
|
import * as path10 from "node:path";
|
|
80604
81141
|
|
|
80605
81142
|
// src/domains/github/auth-prompt.ts
|
|
80606
81143
|
init_dist2();
|
|
80607
81144
|
init_github_auth();
|
|
80608
|
-
var
|
|
81145
|
+
var import_picocolors23 = __toESM(require_picocolors(), 1);
|
|
80609
81146
|
async function promptForAuth() {
|
|
80610
81147
|
const hasGit = GitCloneManager.isGitInstalled();
|
|
80611
81148
|
const hasSshKeys = hasGit && GitCloneManager.hasSshKeys();
|
|
80612
81149
|
const hasGhCli = AuthManager.isGhCliInstalled();
|
|
80613
|
-
oe(
|
|
81150
|
+
oe(import_picocolors23.default.yellow("No GitHub authentication found"));
|
|
80614
81151
|
const options2 = [];
|
|
80615
81152
|
if (hasGit) {
|
|
80616
81153
|
const hint = hasSshKeys ? "SSH keys detected" : "Will use HTTPS";
|
|
@@ -80663,7 +81200,7 @@ async function promptForAuth() {
|
|
|
80663
81200
|
return { method: "cancel" };
|
|
80664
81201
|
}
|
|
80665
81202
|
if (typeof token === "string" && token.startsWith("github_pat_")) {
|
|
80666
|
-
le(
|
|
81203
|
+
le(import_picocolors23.default.yellow(`⚠️ Fine-grained PATs cannot access repos where you're a collaborator.
|
|
80667
81204
|
` + " If you encounter access issues, use a Classic PAT instead."));
|
|
80668
81205
|
}
|
|
80669
81206
|
return { method: "token", token };
|
|
@@ -80706,7 +81243,7 @@ import { join as join123 } from "node:path";
|
|
|
80706
81243
|
// src/shared/progress-bar.ts
|
|
80707
81244
|
init_output_manager();
|
|
80708
81245
|
init_terminal_utils();
|
|
80709
|
-
var
|
|
81246
|
+
var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
80710
81247
|
var BAR_CHARS = {
|
|
80711
81248
|
unicode: { filled: "█", empty: "░" },
|
|
80712
81249
|
ascii: { filled: "=", empty: "-" }
|
|
@@ -80764,7 +81301,7 @@ class ProgressBar {
|
|
|
80764
81301
|
this.clearLine();
|
|
80765
81302
|
if (message) {
|
|
80766
81303
|
const symbols = output.getSymbols();
|
|
80767
|
-
console.log(`${
|
|
81304
|
+
console.log(`${import_picocolors24.default.green(symbols.success)} ${message}`);
|
|
80768
81305
|
}
|
|
80769
81306
|
}
|
|
80770
81307
|
clearLine() {
|
|
@@ -83405,7 +83942,7 @@ var Vn = 512 * 1024;
|
|
|
83405
83942
|
var $n = pr | ur | dr | mr;
|
|
83406
83943
|
var lr = !fr && typeof ar == "number" ? ar | ur | dr | mr : null;
|
|
83407
83944
|
var cs = lr !== null ? () => lr : Kn ? (s3) => s3 < Vn ? $n : "w" : () => "w";
|
|
83408
|
-
var
|
|
83945
|
+
var fs32 = (s3, t, e2) => {
|
|
83409
83946
|
try {
|
|
83410
83947
|
return mi.lchownSync(s3, t, e2);
|
|
83411
83948
|
} catch (i) {
|
|
@@ -83454,7 +83991,7 @@ var ds = (s3, t, e2, i) => {
|
|
|
83454
83991
|
});
|
|
83455
83992
|
};
|
|
83456
83993
|
var qn = (s3, t, e2, i) => {
|
|
83457
|
-
t.isDirectory() && us(Ee.resolve(s3, t.name), e2, i),
|
|
83994
|
+
t.isDirectory() && us(Ee.resolve(s3, t.name), e2, i), fs32(Ee.resolve(s3, t.name), e2, i);
|
|
83458
83995
|
};
|
|
83459
83996
|
var us = (s3, t, e2) => {
|
|
83460
83997
|
let i;
|
|
@@ -83465,12 +84002,12 @@ var us = (s3, t, e2) => {
|
|
|
83465
84002
|
if (n2?.code === "ENOENT")
|
|
83466
84003
|
return;
|
|
83467
84004
|
if (n2?.code === "ENOTDIR" || n2?.code === "ENOTSUP")
|
|
83468
|
-
return
|
|
84005
|
+
return fs32(s3, t, e2);
|
|
83469
84006
|
throw n2;
|
|
83470
84007
|
}
|
|
83471
84008
|
for (let r2 of i)
|
|
83472
84009
|
qn(s3, r2, t, e2);
|
|
83473
|
-
return
|
|
84010
|
+
return fs32(s3, t, e2);
|
|
83474
84011
|
};
|
|
83475
84012
|
var we = class extends Error {
|
|
83476
84013
|
path;
|
|
@@ -84710,7 +85247,7 @@ function buildReleaseAllowlist(layout) {
|
|
|
84710
85247
|
async function ensureLayoutSourceDir(projectRoot, layout, strict) {
|
|
84711
85248
|
const sourceDir = path10.join(projectRoot, layout.sourceDir);
|
|
84712
85249
|
try {
|
|
84713
|
-
const stat11 = await
|
|
85250
|
+
const stat11 = await fs33.promises.stat(sourceDir);
|
|
84714
85251
|
if (!stat11.isDirectory()) {
|
|
84715
85252
|
throw new Error(`Expected source directory "${layout.sourceDir}" exists but is not a directory.`);
|
|
84716
85253
|
}
|
|
@@ -84735,8 +85272,8 @@ async function materializeRuntimeLayoutInPlace(projectRoot, layout) {
|
|
|
84735
85272
|
}
|
|
84736
85273
|
const sourceDir = path10.join(projectRoot, layout.sourceDir);
|
|
84737
85274
|
const runtimeDir = path10.join(projectRoot, layout.runtimeDir);
|
|
84738
|
-
await
|
|
84739
|
-
await
|
|
85275
|
+
await fs33.promises.rm(runtimeDir, { recursive: true, force: true });
|
|
85276
|
+
await fs33.promises.rename(sourceDir, runtimeDir);
|
|
84740
85277
|
}
|
|
84741
85278
|
async function stageLocalKitPathForRuntimeLayout(kitRoot, layout) {
|
|
84742
85279
|
const sourceDir = await ensureLayoutSourceDir(kitRoot, layout, false);
|
|
@@ -84746,20 +85283,20 @@ async function stageLocalKitPathForRuntimeLayout(kitRoot, layout) {
|
|
|
84746
85283
|
const downloadManager = new DownloadManager;
|
|
84747
85284
|
const tempDir = await downloadManager.createTempDir();
|
|
84748
85285
|
const extractDir = `${tempDir}/extracted`;
|
|
84749
|
-
await
|
|
84750
|
-
const entries = await
|
|
85286
|
+
await fs33.promises.mkdir(extractDir, { recursive: true });
|
|
85287
|
+
const entries = await fs33.promises.readdir(kitRoot);
|
|
84751
85288
|
const allowlist = buildReleaseAllowlist(layout);
|
|
84752
85289
|
for (const entry of entries) {
|
|
84753
85290
|
if (!allowlist.includes(entry) || entry === layout.sourceDir) {
|
|
84754
85291
|
continue;
|
|
84755
85292
|
}
|
|
84756
|
-
await
|
|
85293
|
+
await fs33.promises.cp(path10.join(kitRoot, entry), path10.join(extractDir, entry), {
|
|
84757
85294
|
recursive: true
|
|
84758
85295
|
});
|
|
84759
85296
|
}
|
|
84760
85297
|
const runtimeDir = path10.join(extractDir, layout.runtimeDir);
|
|
84761
|
-
await
|
|
84762
|
-
await
|
|
85298
|
+
await fs33.promises.mkdir(path10.dirname(runtimeDir), { recursive: true });
|
|
85299
|
+
await fs33.promises.cp(sourceDir, runtimeDir, { recursive: true });
|
|
84763
85300
|
logger.verbose("Staged local kit path with runtime layout", {
|
|
84764
85301
|
kitRoot,
|
|
84765
85302
|
extractDir,
|
|
@@ -84788,9 +85325,9 @@ function resolveRepoRootForKit(kitRoot) {
|
|
|
84788
85325
|
try {
|
|
84789
85326
|
const parent = path10.dirname(kitRoot);
|
|
84790
85327
|
const parentPackageJson = path10.join(parent, "package.json");
|
|
84791
|
-
if (!
|
|
85328
|
+
if (!fs33.existsSync(parentPackageJson))
|
|
84792
85329
|
return kitRoot;
|
|
84793
|
-
const pkg = JSON.parse(
|
|
85330
|
+
const pkg = JSON.parse(fs33.readFileSync(parentPackageJson, "utf-8"));
|
|
84794
85331
|
const kitCfg = pkg.takumi;
|
|
84795
85332
|
const sourceDir = kitCfg?.sourceDir;
|
|
84796
85333
|
if (typeof sourceDir === "string" && path10.resolve(parent, sourceDir) === path10.resolve(kitRoot)) {
|
|
@@ -84804,9 +85341,9 @@ async function stageMonorepoForInstallation(kitRoot) {
|
|
|
84804
85341
|
const tempDir = await downloadManager.createTempDir();
|
|
84805
85342
|
const extractDir = `${tempDir}/extracted`;
|
|
84806
85343
|
const claudeDir = path10.join(extractDir, ".claude");
|
|
84807
|
-
await
|
|
85344
|
+
await fs33.promises.mkdir(claudeDir, { recursive: true });
|
|
84808
85345
|
const repoRoot = resolveRepoRootForKit(kitRoot);
|
|
84809
|
-
const kitEntries = await
|
|
85346
|
+
const kitEntries = await fs33.promises.readdir(kitRoot);
|
|
84810
85347
|
const skipLegacyManifest = kitEntries.includes(MANIFEST_FILENAME) && kitEntries.includes(LEGACY_MANIFEST_FILENAME);
|
|
84811
85348
|
for (const entry of kitEntries) {
|
|
84812
85349
|
if (!MONOREPO_KIT_CONTENT.includes(entry))
|
|
@@ -84814,14 +85351,14 @@ async function stageMonorepoForInstallation(kitRoot) {
|
|
|
84814
85351
|
if (skipLegacyManifest && entry === LEGACY_MANIFEST_FILENAME)
|
|
84815
85352
|
continue;
|
|
84816
85353
|
const srcPath = path10.join(kitRoot, entry);
|
|
84817
|
-
await
|
|
85354
|
+
await fs33.promises.cp(srcPath, path10.join(claudeDir, entry), { recursive: true });
|
|
84818
85355
|
}
|
|
84819
|
-
const repoEntries = repoRoot === kitRoot ? kitEntries : await
|
|
85356
|
+
const repoEntries = repoRoot === kitRoot ? kitEntries : await fs33.promises.readdir(repoRoot);
|
|
84820
85357
|
for (const entry of repoEntries) {
|
|
84821
85358
|
if (!RELEASE_ROOT_ALLOWLIST.includes(entry))
|
|
84822
85359
|
continue;
|
|
84823
85360
|
const srcPath = path10.join(repoRoot, entry);
|
|
84824
|
-
await
|
|
85361
|
+
await fs33.promises.cp(srcPath, path10.join(extractDir, entry), { recursive: true });
|
|
84825
85362
|
}
|
|
84826
85363
|
logger.verbose("Staged monorepo for installation", {
|
|
84827
85364
|
kitRoot,
|
|
@@ -84835,13 +85372,13 @@ async function stageMonorepoForInstallation(kitRoot) {
|
|
|
84835
85372
|
async function normalizeFullRepoExtract(dir, strict) {
|
|
84836
85373
|
const layout = resolveKitLayout(dir);
|
|
84837
85374
|
await ensureLayoutSourceDir(dir, layout, strict);
|
|
84838
|
-
const entries = await
|
|
85375
|
+
const entries = await fs33.promises.readdir(dir);
|
|
84839
85376
|
const releaseAllowlist = buildReleaseAllowlist(layout);
|
|
84840
85377
|
let removedCount = 0;
|
|
84841
85378
|
for (const entry of entries) {
|
|
84842
85379
|
if (!releaseAllowlist.includes(entry)) {
|
|
84843
85380
|
const fullPath = path10.join(dir, entry);
|
|
84844
|
-
await
|
|
85381
|
+
await fs33.promises.rm(fullPath, { recursive: true, force: true });
|
|
84845
85382
|
removedCount++;
|
|
84846
85383
|
}
|
|
84847
85384
|
}
|
|
@@ -84956,7 +85493,7 @@ async function useLocalKitPath(kitPath, isMonorepo) {
|
|
|
84956
85493
|
output.section("Using local kit");
|
|
84957
85494
|
const absolutePath = path10.resolve(kitPath);
|
|
84958
85495
|
try {
|
|
84959
|
-
const stat11 = await
|
|
85496
|
+
const stat11 = await fs33.promises.stat(absolutePath);
|
|
84960
85497
|
if (!stat11.isDirectory()) {
|
|
84961
85498
|
throw new Error(`--kit-path must point to a directory, not a file.
|
|
84962
85499
|
|
|
@@ -84995,7 +85532,7 @@ Please verify the path exists and is accessible.`);
|
|
|
84995
85532
|
}
|
|
84996
85533
|
const claudeDir = path10.join(absolutePath, DEFAULT_KIT_LAYOUT.runtimeDir);
|
|
84997
85534
|
try {
|
|
84998
|
-
const stat11 = await
|
|
85535
|
+
const stat11 = await fs33.promises.stat(claudeDir);
|
|
84999
85536
|
if (!stat11.isDirectory()) {
|
|
85000
85537
|
logger.warning(`Warning: ${claudeDir} exists but is not a directory.
|
|
85001
85538
|
This may not be a valid Takumi installation.`);
|
|
@@ -85030,7 +85567,7 @@ async function extractLocalArchive(archivePath, exclude) {
|
|
|
85030
85567
|
const absolutePath = path10.resolve(archivePath);
|
|
85031
85568
|
validateArchiveFormat(absolutePath);
|
|
85032
85569
|
try {
|
|
85033
|
-
const stat11 = await
|
|
85570
|
+
const stat11 = await fs33.promises.stat(absolutePath);
|
|
85034
85571
|
if (!stat11.isFile()) {
|
|
85035
85572
|
throw new Error(`--archive must point to a file, not a directory.
|
|
85036
85573
|
|
|
@@ -85163,7 +85700,7 @@ async function downloadViaWorker(release, kit, isNonInteractive2) {
|
|
|
85163
85700
|
const tempDir = await downloadManager.createTempDir();
|
|
85164
85701
|
const archivePath = path10.join(tempDir, assetName);
|
|
85165
85702
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
85166
|
-
await
|
|
85703
|
+
await fs33.promises.writeFile(archivePath, buf);
|
|
85167
85704
|
const extractDir = `${tempDir}/extracted`;
|
|
85168
85705
|
logger.verbose("Extraction", { archivePath, extractDir });
|
|
85169
85706
|
await downloadManager.extractArchive(archivePath, extractDir);
|
|
@@ -86396,7 +86933,7 @@ function filterDeletionPaths(trackedFiles, deletions) {
|
|
|
86396
86933
|
}
|
|
86397
86934
|
// src/domains/sync/merge-ui.ts
|
|
86398
86935
|
init_dist2();
|
|
86399
|
-
var
|
|
86936
|
+
var import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
86400
86937
|
var HUNK_SEPARATOR_WIDTH = 50;
|
|
86401
86938
|
var EXTENDED_CONTEXT_LINES = 10;
|
|
86402
86939
|
var MAX_LINE_DISPLAY_LENGTH = 120;
|
|
@@ -86415,21 +86952,21 @@ class MergeUI {
|
|
|
86415
86952
|
static async promptHunk(hunk, hunkIndex, totalHunks, _filename) {
|
|
86416
86953
|
requireTTY();
|
|
86417
86954
|
const lineRange = `${hunk.oldStart}-${hunk.oldStart + hunk.oldLines - 1}`;
|
|
86418
|
-
console.log(
|
|
86955
|
+
console.log(import_picocolors25.default.cyan(`
|
|
86419
86956
|
Hunk ${hunkIndex + 1}/${totalHunks}: Lines ${lineRange}`));
|
|
86420
|
-
console.log(
|
|
86957
|
+
console.log(import_picocolors25.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
86421
86958
|
for (const line of hunk.lines) {
|
|
86422
86959
|
const displayLine = truncateLine(line);
|
|
86423
86960
|
const prefix = line[0];
|
|
86424
86961
|
if (prefix === "+") {
|
|
86425
|
-
console.log(
|
|
86962
|
+
console.log(import_picocolors25.default.green(displayLine));
|
|
86426
86963
|
} else if (prefix === "-") {
|
|
86427
|
-
console.log(
|
|
86964
|
+
console.log(import_picocolors25.default.red(displayLine));
|
|
86428
86965
|
} else {
|
|
86429
|
-
console.log(
|
|
86966
|
+
console.log(import_picocolors25.default.dim(displayLine));
|
|
86430
86967
|
}
|
|
86431
86968
|
}
|
|
86432
|
-
console.log(
|
|
86969
|
+
console.log(import_picocolors25.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
86433
86970
|
const action = await ie({
|
|
86434
86971
|
message: "Action?",
|
|
86435
86972
|
options: [
|
|
@@ -86449,21 +86986,21 @@ Hunk ${hunkIndex + 1}/${totalHunks}: Lines ${lineRange}`));
|
|
|
86449
86986
|
`);
|
|
86450
86987
|
const startLine = Math.max(0, hunk.oldStart - 1 - contextLines);
|
|
86451
86988
|
const endLine = Math.min(lines.length, hunk.oldStart + hunk.oldLines - 1 + contextLines);
|
|
86452
|
-
console.log(
|
|
86989
|
+
console.log(import_picocolors25.default.cyan(`
|
|
86453
86990
|
Extended context (lines ${startLine + 1}-${endLine}):`));
|
|
86454
|
-
console.log(
|
|
86991
|
+
console.log(import_picocolors25.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
86455
86992
|
for (let i = startLine;i < endLine; i++) {
|
|
86456
86993
|
const lineNum = String(i + 1).padStart(4, " ");
|
|
86457
86994
|
const isInHunk = i >= hunk.oldStart - 1 && i < hunk.oldStart - 1 + hunk.oldLines;
|
|
86458
|
-
const prefix = isInHunk ?
|
|
86459
|
-
console.log(`${
|
|
86995
|
+
const prefix = isInHunk ? import_picocolors25.default.yellow("*") : " ";
|
|
86996
|
+
console.log(`${import_picocolors25.default.dim(lineNum)} ${prefix} ${lines[i]}`);
|
|
86460
86997
|
}
|
|
86461
|
-
console.log(
|
|
86998
|
+
console.log(import_picocolors25.default.dim("─".repeat(HUNK_SEPARATOR_WIDTH)));
|
|
86462
86999
|
}
|
|
86463
87000
|
static async mergeFile(filename, currentContent, _newContent, hunks) {
|
|
86464
|
-
console.log(
|
|
87001
|
+
console.log(import_picocolors25.default.bold(`
|
|
86465
87002
|
━━━ ${filename} ━━━`));
|
|
86466
|
-
console.log(
|
|
87003
|
+
console.log(import_picocolors25.default.dim(`${hunks.length} change${hunks.length === 1 ? "" : "s"} to review
|
|
86467
87004
|
`));
|
|
86468
87005
|
const decisions = [];
|
|
86469
87006
|
for (let i = 0;i < hunks.length; i++) {
|
|
@@ -86486,19 +87023,19 @@ Extended context (lines ${startLine + 1}-${endLine}):`));
|
|
|
86486
87023
|
}
|
|
86487
87024
|
static displayMergeSummary(filename, applied, rejected) {
|
|
86488
87025
|
if (applied > 0 && rejected > 0) {
|
|
86489
|
-
console.log(
|
|
87026
|
+
console.log(import_picocolors25.default.dim(` ${filename}: `) + import_picocolors25.default.green(`${applied} applied`) + import_picocolors25.default.dim(", ") + import_picocolors25.default.yellow(`${rejected} rejected`));
|
|
86490
87027
|
} else if (applied > 0) {
|
|
86491
|
-
console.log(
|
|
87028
|
+
console.log(import_picocolors25.default.dim(` ${filename}: `) + import_picocolors25.default.green(`${applied} applied`));
|
|
86492
87029
|
} else {
|
|
86493
|
-
console.log(
|
|
87030
|
+
console.log(import_picocolors25.default.dim(` ${filename}: `) + import_picocolors25.default.yellow(`${rejected} rejected`));
|
|
86494
87031
|
}
|
|
86495
87032
|
}
|
|
86496
87033
|
static displaySkipped(filename) {
|
|
86497
|
-
console.log(
|
|
87034
|
+
console.log(import_picocolors25.default.dim(` ${filename}: `) + import_picocolors25.default.yellow("skipped"));
|
|
86498
87035
|
}
|
|
86499
87036
|
}
|
|
86500
87037
|
// src/domains/sync/notification-display.ts
|
|
86501
|
-
var
|
|
87038
|
+
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
86502
87039
|
import { stdout } from "node:process";
|
|
86503
87040
|
function createNotificationBox2(borderColor, boxWidth) {
|
|
86504
87041
|
const contentWidth = boxWidth - 2;
|
|
@@ -86522,19 +87059,19 @@ function displayConfigUpdateNotification(entries, isGlobal = false) {
|
|
|
86522
87059
|
const lines = entries.map(({ kit, currentVersion, latestVersion }) => {
|
|
86523
87060
|
const cur = currentVersion.replace(/^v/, "");
|
|
86524
87061
|
const latest = latestVersion.replace(/^v/, "");
|
|
86525
|
-
const text = `${
|
|
87062
|
+
const text = `${import_picocolors26.default.bold(kit)}: ${import_picocolors26.default.dim(cur)} ${import_picocolors26.default.white("→")} ${import_picocolors26.default.green(import_picocolors26.default.bold(latest))}`;
|
|
86526
87063
|
const visibleLen = kit.length + 2 + cur.length + 3 + latest.length;
|
|
86527
87064
|
return { text, visibleLen };
|
|
86528
87065
|
});
|
|
86529
87066
|
const updateCmd = isGlobal ? "tkm init -g --sync" : "tkm init --sync";
|
|
86530
|
-
const commandText = `Run: ${
|
|
87067
|
+
const commandText = `Run: ${import_picocolors26.default.cyan(import_picocolors26.default.bold(updateCmd))}`;
|
|
86531
87068
|
const commandLen = `Run: ${updateCmd}`.length;
|
|
86532
87069
|
const headerLabel = "\uD83D\uDCE6 Config Updates Available";
|
|
86533
|
-
const headerText =
|
|
87070
|
+
const headerText = import_picocolors26.default.bold(import_picocolors26.default.yellow(headerLabel));
|
|
86534
87071
|
const longestLine = Math.max(headerLabel.length, commandLen, ...lines.map((l2) => l2.visibleLen));
|
|
86535
87072
|
const terminalWidth = stdout.columns || 80;
|
|
86536
87073
|
const boxWidth = Math.min(Math.max(longestLine + 6, 52), terminalWidth - 4);
|
|
86537
|
-
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(
|
|
87074
|
+
const { topBorder, bottomBorder, emptyLine, padLine } = createNotificationBox2(import_picocolors26.default.cyan, boxWidth);
|
|
86538
87075
|
console.log("");
|
|
86539
87076
|
console.log(topBorder);
|
|
86540
87077
|
console.log(emptyLine);
|
|
@@ -86557,7 +87094,7 @@ init_manifest_reader();
|
|
|
86557
87094
|
init_logger();
|
|
86558
87095
|
init_path_resolver();
|
|
86559
87096
|
var import_fs_extra36 = __toESM(require_lib(), 1);
|
|
86560
|
-
var
|
|
87097
|
+
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
86561
87098
|
async function handleSync(ctx) {
|
|
86562
87099
|
if (!ctx.options.sync) {
|
|
86563
87100
|
return ctx;
|
|
@@ -86742,7 +87279,7 @@ async function executeSyncMerge(ctx) {
|
|
|
86742
87279
|
}
|
|
86743
87280
|
const backupDir = PathResolver.getBackupDir();
|
|
86744
87281
|
await createBackup(ctx.claudeDir, trackedFiles, backupDir);
|
|
86745
|
-
logger.success(`Backup created at ${
|
|
87282
|
+
logger.success(`Backup created at ${import_picocolors27.default.dim(backupDir)}`);
|
|
86746
87283
|
if (plan.autoUpdate.length > 0) {
|
|
86747
87284
|
logger.info(`Auto-updating ${plan.autoUpdate.length} file(s)...`);
|
|
86748
87285
|
let updateSuccess = 0;
|
|
@@ -86852,22 +87389,22 @@ async function executeSyncMerge(ctx) {
|
|
|
86852
87389
|
totalRejected += result.rejected;
|
|
86853
87390
|
}
|
|
86854
87391
|
console.log("");
|
|
86855
|
-
console.log(
|
|
86856
|
-
console.log(
|
|
87392
|
+
console.log(import_picocolors27.default.bold("Sync Summary:"));
|
|
87393
|
+
console.log(import_picocolors27.default.dim("─".repeat(40)));
|
|
86857
87394
|
if (plan.autoUpdate.length > 0) {
|
|
86858
|
-
console.log(
|
|
87395
|
+
console.log(import_picocolors27.default.green(` ✓ ${plan.autoUpdate.length} file(s) auto-updated`));
|
|
86859
87396
|
}
|
|
86860
87397
|
if (totalApplied > 0) {
|
|
86861
|
-
console.log(
|
|
87398
|
+
console.log(import_picocolors27.default.green(` ✓ ${totalApplied} hunk(s) applied`));
|
|
86862
87399
|
}
|
|
86863
87400
|
if (totalRejected > 0) {
|
|
86864
|
-
console.log(
|
|
87401
|
+
console.log(import_picocolors27.default.yellow(` ○ ${totalRejected} hunk(s) rejected`));
|
|
86865
87402
|
}
|
|
86866
87403
|
if (skippedFiles > 0) {
|
|
86867
|
-
console.log(
|
|
87404
|
+
console.log(import_picocolors27.default.yellow(` ○ ${skippedFiles} file(s) skipped`));
|
|
86868
87405
|
}
|
|
86869
87406
|
if (plan.skipped.length > 0) {
|
|
86870
|
-
console.log(
|
|
87407
|
+
console.log(import_picocolors27.default.dim(` ─ ${plan.skipped.length} user-owned file(s) unchanged`));
|
|
86871
87408
|
}
|
|
86872
87409
|
} else if (plan.needsReview.length > 0 && ctx.isNonInteractive) {
|
|
86873
87410
|
logger.error(`Cannot complete sync: ${plan.needsReview.length} file(s) require interactive review`);
|
|
@@ -86890,30 +87427,30 @@ Options:
|
|
|
86890
87427
|
}
|
|
86891
87428
|
function displaySyncPlan(plan) {
|
|
86892
87429
|
console.log("");
|
|
86893
|
-
console.log(
|
|
86894
|
-
console.log(
|
|
87430
|
+
console.log(import_picocolors27.default.bold("Sync Plan:"));
|
|
87431
|
+
console.log(import_picocolors27.default.dim("─".repeat(40)));
|
|
86895
87432
|
if (plan.autoUpdate.length > 0) {
|
|
86896
|
-
console.log(
|
|
87433
|
+
console.log(import_picocolors27.default.green(` ${plan.autoUpdate.length} file(s) will be auto-updated`));
|
|
86897
87434
|
for (const file of plan.autoUpdate.slice(0, 5)) {
|
|
86898
|
-
console.log(
|
|
87435
|
+
console.log(import_picocolors27.default.dim(` • ${file.path}`));
|
|
86899
87436
|
}
|
|
86900
87437
|
if (plan.autoUpdate.length > 5) {
|
|
86901
|
-
console.log(
|
|
87438
|
+
console.log(import_picocolors27.default.dim(` ... and ${plan.autoUpdate.length - 5} more`));
|
|
86902
87439
|
}
|
|
86903
87440
|
}
|
|
86904
87441
|
if (plan.needsReview.length > 0) {
|
|
86905
|
-
console.log(
|
|
87442
|
+
console.log(import_picocolors27.default.yellow(` ${plan.needsReview.length} file(s) need interactive review`));
|
|
86906
87443
|
for (const file of plan.needsReview.slice(0, 5)) {
|
|
86907
|
-
console.log(
|
|
87444
|
+
console.log(import_picocolors27.default.dim(` • ${file.path}`));
|
|
86908
87445
|
}
|
|
86909
87446
|
if (plan.needsReview.length > 5) {
|
|
86910
|
-
console.log(
|
|
87447
|
+
console.log(import_picocolors27.default.dim(` ... and ${plan.needsReview.length - 5} more`));
|
|
86911
87448
|
}
|
|
86912
87449
|
}
|
|
86913
87450
|
if (plan.skipped.length > 0) {
|
|
86914
|
-
console.log(
|
|
87451
|
+
console.log(import_picocolors27.default.dim(` ${plan.skipped.length} user-owned file(s) will be skipped`));
|
|
86915
87452
|
}
|
|
86916
|
-
console.log(
|
|
87453
|
+
console.log(import_picocolors27.default.dim("─".repeat(40)));
|
|
86917
87454
|
}
|
|
86918
87455
|
async function createBackup(claudeDir, files, backupDir) {
|
|
86919
87456
|
await mkdir28(backupDir, { recursive: true });
|
|
@@ -87869,7 +88406,7 @@ init_auth_client();
|
|
|
87869
88406
|
// src/domains/mcp/registry-cache.ts
|
|
87870
88407
|
init_logger();
|
|
87871
88408
|
init_paths2();
|
|
87872
|
-
import { promises as
|
|
88409
|
+
import { promises as fs34 } from "node:fs";
|
|
87873
88410
|
import { join as join139 } from "node:path";
|
|
87874
88411
|
function getCacheDir() {
|
|
87875
88412
|
return join139(getConfigDir(), "mcp");
|
|
@@ -87879,7 +88416,7 @@ function getCachePath2() {
|
|
|
87879
88416
|
}
|
|
87880
88417
|
async function readCachedRegistry() {
|
|
87881
88418
|
try {
|
|
87882
|
-
const raw = await
|
|
88419
|
+
const raw = await fs34.readFile(getCachePath2(), "utf8");
|
|
87883
88420
|
const parsed = JSON.parse(raw);
|
|
87884
88421
|
const result = McpRegistrySchema.safeParse({ services: parsed.services });
|
|
87885
88422
|
if (!result.success)
|
|
@@ -87897,9 +88434,9 @@ async function readCachedRegistry() {
|
|
|
87897
88434
|
}
|
|
87898
88435
|
async function writeCachedRegistry(registry) {
|
|
87899
88436
|
const dir = getCacheDir();
|
|
87900
|
-
await
|
|
88437
|
+
await fs34.mkdir(dir, { recursive: true, mode: 448 });
|
|
87901
88438
|
const body = { services: registry.services, cachedAt: Date.now() };
|
|
87902
|
-
await
|
|
88439
|
+
await fs34.writeFile(getCachePath2(), JSON.stringify(body, null, 2), {
|
|
87903
88440
|
mode: 384,
|
|
87904
88441
|
encoding: "utf8"
|
|
87905
88442
|
});
|
|
@@ -88598,9 +89135,9 @@ async function addCommand(service, options2 = {}) {
|
|
|
88598
89135
|
}
|
|
88599
89136
|
// src/commands/mcp/list-command.ts
|
|
88600
89137
|
init_logger();
|
|
88601
|
-
var
|
|
89138
|
+
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
88602
89139
|
function statusCell(configured) {
|
|
88603
|
-
return configured ? { value: "● configured", paint:
|
|
89140
|
+
return configured ? { value: "● configured", paint: import_picocolors28.default.green } : { value: "○ not set", paint: import_picocolors28.default.dim };
|
|
88604
89141
|
}
|
|
88605
89142
|
async function listCommand(options2 = {}, deps) {
|
|
88606
89143
|
let listed;
|
|
@@ -89443,7 +89980,7 @@ function buildPlanSummary(planFile) {
|
|
|
89443
89980
|
// src/commands/plan/plan-read-handlers.ts
|
|
89444
89981
|
init_logger();
|
|
89445
89982
|
init_output_manager();
|
|
89446
|
-
var
|
|
89983
|
+
var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
89447
89984
|
async function handleParse(target, options2) {
|
|
89448
89985
|
const planFile = resolvePlanFile(target);
|
|
89449
89986
|
if (!planFile) {
|
|
@@ -89466,7 +90003,7 @@ async function handleParse(target, options2) {
|
|
|
89466
90003
|
}
|
|
89467
90004
|
const title = typeof frontmatter.title === "string" ? frontmatter.title : basename22(dirname41(planFile));
|
|
89468
90005
|
console.log();
|
|
89469
|
-
console.log(
|
|
90006
|
+
console.log(import_picocolors29.default.bold(` Plan: ${title}`));
|
|
89470
90007
|
console.log(` File: ${planFile}`);
|
|
89471
90008
|
console.log(` Phases found: ${phases.length}`);
|
|
89472
90009
|
console.log();
|
|
@@ -89497,7 +90034,7 @@ async function handleValidate(target, options2) {
|
|
|
89497
90034
|
return;
|
|
89498
90035
|
}
|
|
89499
90036
|
console.log();
|
|
89500
|
-
console.log(
|
|
90037
|
+
console.log(import_picocolors29.default.bold(` Validating: ${planFile}`));
|
|
89501
90038
|
console.log();
|
|
89502
90039
|
if (result.issues.length === 0) {
|
|
89503
90040
|
console.log(` [OK] No issues found — ${result.phases.length} phases detected`);
|
|
@@ -89511,7 +90048,7 @@ async function handleValidate(target, options2) {
|
|
|
89511
90048
|
}
|
|
89512
90049
|
}
|
|
89513
90050
|
console.log();
|
|
89514
|
-
const validStr = result.valid ?
|
|
90051
|
+
const validStr = result.valid ? import_picocolors29.default.green("[OK] Valid") : import_picocolors29.default.red("[X] Invalid");
|
|
89515
90052
|
console.log(` ${validStr} — ${result.issues.filter((i) => i.severity === "error").length} errors, ${result.issues.filter((i) => i.severity === "warning").length} warnings`);
|
|
89516
90053
|
console.log();
|
|
89517
90054
|
if (!result.valid)
|
|
@@ -89538,14 +90075,14 @@ async function handleStatus(target, options2) {
|
|
|
89538
90075
|
return;
|
|
89539
90076
|
}
|
|
89540
90077
|
console.log();
|
|
89541
|
-
console.log(
|
|
90078
|
+
console.log(import_picocolors29.default.bold(` Plans in: ${plansDir}`));
|
|
89542
90079
|
console.log();
|
|
89543
90080
|
for (const pf of planFiles) {
|
|
89544
90081
|
try {
|
|
89545
90082
|
const s3 = buildPlanSummary(pf);
|
|
89546
90083
|
const bar = progressBar(s3.completed, s3.totalPhases);
|
|
89547
90084
|
const title2 = s3.title ?? basename22(dirname41(pf));
|
|
89548
|
-
console.log(` ${
|
|
90085
|
+
console.log(` ${import_picocolors29.default.bold(title2)}`);
|
|
89549
90086
|
console.log(` ${bar}`);
|
|
89550
90087
|
if (s3.inProgress > 0)
|
|
89551
90088
|
console.log(` [~] ${s3.inProgress} in progress`);
|
|
@@ -89577,7 +90114,7 @@ async function handleStatus(target, options2) {
|
|
|
89577
90114
|
}
|
|
89578
90115
|
const title = summary.title ?? basename22(dirname41(planFile));
|
|
89579
90116
|
console.log();
|
|
89580
|
-
console.log(
|
|
90117
|
+
console.log(import_picocolors29.default.bold(` ${title}`));
|
|
89581
90118
|
if (summary.status)
|
|
89582
90119
|
console.log(` Status: ${summary.status}`);
|
|
89583
90120
|
console.log();
|
|
@@ -89603,7 +90140,7 @@ async function handleKanban(target, _options) {
|
|
|
89603
90140
|
// src/commands/plan/plan-write-handlers.ts
|
|
89604
90141
|
import { basename as basename23, relative as relative22, resolve as resolve34 } from "node:path";
|
|
89605
90142
|
init_output_manager();
|
|
89606
|
-
var
|
|
90143
|
+
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
89607
90144
|
async function handleCreate(target, options2) {
|
|
89608
90145
|
if (!options2.title) {
|
|
89609
90146
|
output.error("[X] --title is required for create");
|
|
@@ -89650,7 +90187,7 @@ async function handleCreate(target, options2) {
|
|
|
89650
90187
|
return;
|
|
89651
90188
|
}
|
|
89652
90189
|
console.log();
|
|
89653
|
-
console.log(
|
|
90190
|
+
console.log(import_picocolors30.default.bold(` [OK] Plan created: ${options2.title}`));
|
|
89654
90191
|
console.log(` Directory: ${resolve34(dir)}`);
|
|
89655
90192
|
console.log(` Phases: ${result.phaseFiles.length}`);
|
|
89656
90193
|
for (const f4 of result.phaseFiles) {
|
|
@@ -90428,10 +90965,10 @@ function renderQuotas(data, s3) {
|
|
|
90428
90965
|
const allow = new Set(s3.windows.map((w4) => WINDOW_ALIASES[w4.toLowerCase()] ?? w4.toLowerCase()));
|
|
90429
90966
|
const parts = [];
|
|
90430
90967
|
for (const windowText of data.usageWindows) {
|
|
90431
|
-
const
|
|
90432
|
-
const match =
|
|
90968
|
+
const clean2 = sanitizeField(windowText);
|
|
90969
|
+
const match = clean2.match(/^(\w+)\s+(\d+)%(.*)$/);
|
|
90433
90970
|
if (!match) {
|
|
90434
|
-
parts.push(paint("dim",
|
|
90971
|
+
parts.push(paint("dim", clean2));
|
|
90435
90972
|
continue;
|
|
90436
90973
|
}
|
|
90437
90974
|
const [, label, pctStr, rest] = match;
|
|
@@ -90809,7 +91346,7 @@ init_manifest_writer();
|
|
|
90809
91346
|
init_logger();
|
|
90810
91347
|
init_safe_prompts();
|
|
90811
91348
|
init_types2();
|
|
90812
|
-
var
|
|
91349
|
+
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
90813
91350
|
|
|
90814
91351
|
// src/commands/uninstall/installation-detector.ts
|
|
90815
91352
|
init_paths();
|
|
@@ -90868,7 +91405,7 @@ init_ownership_checker();
|
|
|
90868
91405
|
init_logger();
|
|
90869
91406
|
init_safe_prompts();
|
|
90870
91407
|
init_takumi_constants();
|
|
90871
|
-
var
|
|
91408
|
+
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
90872
91409
|
import { existsSync as existsSync70, readdirSync as readdirSync14, rmSync as rmSync11 } from "node:fs";
|
|
90873
91410
|
import { dirname as dirname43, join as join147 } from "node:path";
|
|
90874
91411
|
function listPresentManifestNames(installPath) {
|
|
@@ -90973,27 +91510,27 @@ async function analyzeInstallation(installation, forceOverwrite, kit) {
|
|
|
90973
91510
|
}
|
|
90974
91511
|
function displayDryRunPreview(analysis, installationType) {
|
|
90975
91512
|
console.log("");
|
|
90976
|
-
log.info(
|
|
91513
|
+
log.info(import_picocolors31.default.bold(`DRY RUN - Preview for ${installationType} installation:`));
|
|
90977
91514
|
console.log("");
|
|
90978
91515
|
if (analysis.toDelete.length > 0) {
|
|
90979
|
-
console.log(
|
|
91516
|
+
console.log(import_picocolors31.default.red(import_picocolors31.default.bold(`Files to DELETE (${analysis.toDelete.length}):`)));
|
|
90980
91517
|
const showDelete = analysis.toDelete.slice(0, 10);
|
|
90981
91518
|
for (const item of showDelete) {
|
|
90982
|
-
console.log(` ${
|
|
91519
|
+
console.log(` ${import_picocolors31.default.red("✖")} ${item.path}`);
|
|
90983
91520
|
}
|
|
90984
91521
|
if (analysis.toDelete.length > 10) {
|
|
90985
|
-
console.log(
|
|
91522
|
+
console.log(import_picocolors31.default.gray(` ... and ${analysis.toDelete.length - 10} more`));
|
|
90986
91523
|
}
|
|
90987
91524
|
console.log("");
|
|
90988
91525
|
}
|
|
90989
91526
|
if (analysis.toPreserve.length > 0) {
|
|
90990
|
-
console.log(
|
|
91527
|
+
console.log(import_picocolors31.default.green(import_picocolors31.default.bold(`Files to PRESERVE (${analysis.toPreserve.length}):`)));
|
|
90991
91528
|
const showPreserve = analysis.toPreserve.slice(0, 10);
|
|
90992
91529
|
for (const item of showPreserve) {
|
|
90993
|
-
console.log(` ${
|
|
91530
|
+
console.log(` ${import_picocolors31.default.green("✓")} ${item.path} ${import_picocolors31.default.gray(`(${item.reason})`)}`);
|
|
90994
91531
|
}
|
|
90995
91532
|
if (analysis.toPreserve.length > 10) {
|
|
90996
|
-
console.log(
|
|
91533
|
+
console.log(import_picocolors31.default.gray(` ... and ${analysis.toPreserve.length - 10} more`));
|
|
90997
91534
|
}
|
|
90998
91535
|
console.log("");
|
|
90999
91536
|
}
|
|
@@ -91115,15 +91652,15 @@ function displayInstallations(installations, scope) {
|
|
|
91115
91652
|
const hasLegacy = installations.some((i) => !i.hasMetadata);
|
|
91116
91653
|
const lines = installations.map((i) => {
|
|
91117
91654
|
const typeLabel = i.type === "local" ? "Local " : "Global";
|
|
91118
|
-
const legacyTag = !i.hasMetadata ?
|
|
91655
|
+
const legacyTag = !i.hasMetadata ? import_picocolors32.default.yellow(" [legacy]") : "";
|
|
91119
91656
|
const components = formatComponentSummary(i);
|
|
91120
91657
|
return ` ${typeLabel}: ${i.path}${legacyTag}${components}`;
|
|
91121
91658
|
});
|
|
91122
91659
|
prompts.note(lines.join(`
|
|
91123
91660
|
`), `Detected Takumi installations (${scopeLabel})`);
|
|
91124
91661
|
if (hasLegacy) {
|
|
91125
|
-
log.warn(
|
|
91126
|
-
`) +
|
|
91662
|
+
log.warn(import_picocolors32.default.yellow(`[!] Legacy installation(s) detected without metadata.json.
|
|
91663
|
+
`) + import_picocolors32.default.yellow(" These files cannot be selectively removed. Full directory cleanup will be performed."));
|
|
91127
91664
|
}
|
|
91128
91665
|
log.warn("[!] This will permanently delete Takumi files from the above paths.");
|
|
91129
91666
|
}
|
|
@@ -91183,7 +91720,7 @@ async function uninstallCommand(options2) {
|
|
|
91183
91720
|
}
|
|
91184
91721
|
const isAtHome = isLocalSameAsGlobal();
|
|
91185
91722
|
if (validOptions.local && !validOptions.global && isAtHome) {
|
|
91186
|
-
log.warn(
|
|
91723
|
+
log.warn(import_picocolors32.default.yellow("Cannot use --local at HOME directory (local path equals global path)."));
|
|
91187
91724
|
log.info("Use -g/--global or run from a project directory.");
|
|
91188
91725
|
return;
|
|
91189
91726
|
}
|
|
@@ -91195,7 +91732,7 @@ async function uninstallCommand(options2) {
|
|
|
91195
91732
|
} else if (validOptions.global) {
|
|
91196
91733
|
scope = "global";
|
|
91197
91734
|
} else if (isAtHome) {
|
|
91198
|
-
log.info(
|
|
91735
|
+
log.info(import_picocolors32.default.cyan("Running at HOME directory - targeting global installation"));
|
|
91199
91736
|
scope = "global";
|
|
91200
91737
|
} else {
|
|
91201
91738
|
const promptedScope = await promptScope(allInstallations);
|
|
@@ -91217,10 +91754,10 @@ async function uninstallCommand(options2) {
|
|
|
91217
91754
|
}
|
|
91218
91755
|
displayInstallations(installations, scope);
|
|
91219
91756
|
if (validOptions.kit) {
|
|
91220
|
-
log.info(
|
|
91757
|
+
log.info(import_picocolors32.default.cyan(`Kit-scoped uninstall: ${validOptions.kit} kit only`));
|
|
91221
91758
|
}
|
|
91222
91759
|
if (validOptions.dryRun) {
|
|
91223
|
-
log.info(
|
|
91760
|
+
log.info(import_picocolors32.default.yellow("DRY RUN MODE - No files will be deleted"));
|
|
91224
91761
|
await removeInstallations(installations, {
|
|
91225
91762
|
dryRun: true,
|
|
91226
91763
|
forceOverwrite: validOptions.forceOverwrite,
|
|
@@ -91230,8 +91767,8 @@ async function uninstallCommand(options2) {
|
|
|
91230
91767
|
return;
|
|
91231
91768
|
}
|
|
91232
91769
|
if (validOptions.forceOverwrite) {
|
|
91233
|
-
log.warn(`${
|
|
91234
|
-
${
|
|
91770
|
+
log.warn(`${import_picocolors32.default.yellow(import_picocolors32.default.bold("FORCE MODE ENABLED"))}
|
|
91771
|
+
${import_picocolors32.default.yellow("User modifications will be permanently deleted!")}`);
|
|
91235
91772
|
}
|
|
91236
91773
|
if (!validOptions.yes) {
|
|
91237
91774
|
const kitLabel = validOptions.kit ? ` (${validOptions.kit} kit only)` : "";
|
|
@@ -91698,7 +92235,7 @@ init_github_client();
|
|
|
91698
92235
|
init_environment();
|
|
91699
92236
|
init_logger();
|
|
91700
92237
|
init_types2();
|
|
91701
|
-
var
|
|
92238
|
+
var import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
91702
92239
|
function formatRelativeTime2(dateString) {
|
|
91703
92240
|
if (!dateString)
|
|
91704
92241
|
return "Unknown";
|
|
@@ -91720,21 +92257,21 @@ function formatRelativeTime2(dateString) {
|
|
|
91720
92257
|
}
|
|
91721
92258
|
function displayKitReleases(kitName, releases) {
|
|
91722
92259
|
console.log(`
|
|
91723
|
-
${
|
|
92260
|
+
${import_picocolors33.default.bold(import_picocolors33.default.cyan(kitName))} - Available Versions:
|
|
91724
92261
|
`);
|
|
91725
92262
|
if (releases.length === 0) {
|
|
91726
|
-
console.log(
|
|
92263
|
+
console.log(import_picocolors33.default.dim(" No releases found"));
|
|
91727
92264
|
return;
|
|
91728
92265
|
}
|
|
91729
92266
|
for (const release of releases) {
|
|
91730
|
-
const version3 =
|
|
92267
|
+
const version3 = import_picocolors33.default.green(release.tag);
|
|
91731
92268
|
const publishedAt = formatRelativeTime2(release.publishedAt);
|
|
91732
|
-
const badge = release.prerelease ? ` ${
|
|
92269
|
+
const badge = release.prerelease ? ` ${import_picocolors33.default.yellow("[prerelease]")}` : "";
|
|
91733
92270
|
const versionPart = version3.padEnd(20);
|
|
91734
|
-
const timePart =
|
|
92271
|
+
const timePart = import_picocolors33.default.dim(publishedAt.padEnd(20));
|
|
91735
92272
|
console.log(` ${versionPart} ${timePart}${badge}`);
|
|
91736
92273
|
}
|
|
91737
|
-
console.log(
|
|
92274
|
+
console.log(import_picocolors33.default.dim(`
|
|
91738
92275
|
Showing ${releases.length} ${releases.length === 1 ? "release" : "releases"}`));
|
|
91739
92276
|
}
|
|
91740
92277
|
async function fetchReleasesForKit(kitType, options2) {
|
|
@@ -91798,8 +92335,8 @@ async function versionCommand(options2, deps) {
|
|
|
91798
92335
|
for (const result of results) {
|
|
91799
92336
|
if (result.error) {
|
|
91800
92337
|
console.log(`
|
|
91801
|
-
${
|
|
91802
|
-
console.log(
|
|
92338
|
+
${import_picocolors33.default.bold(import_picocolors33.default.cyan(result.kitConfig.name))} - ${import_picocolors33.default.red("Error")}`);
|
|
92339
|
+
console.log(import_picocolors33.default.dim(` ${result.error}`));
|
|
91803
92340
|
} else {
|
|
91804
92341
|
displayKitReleases(result.kitConfig.name, result.releases);
|
|
91805
92342
|
}
|
|
@@ -91951,7 +92488,7 @@ function registerCommands(cli) {
|
|
|
91951
92488
|
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, path11, options2) => {
|
|
91952
92489
|
await apiCommand(action, service, path11, options2);
|
|
91953
92490
|
});
|
|
91954
|
-
cli.command("artifact [action] [target]", "Manage Takumi artifacts (list | search <term> | 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>", "
|
|
92491
|
+
cli.command("artifact [action] [target] [arg3] [arg4]", "Manage Takumi artifacts (list | search <term> | upload <file> | download <uuid|url> | delete <uuid|url> | comments <verb> <ref> [id])").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>", "(upload) Version note, max 100 chars · (comments reply) Comment body").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").option("--access <level>", "(list) Filter by access level: private | restricted | organization").option("--page <n>", "(list) Page number, 1-based (default: 1)").option("--limit <n>", "(list) Rows per page · (comments list) Threads per page · max 100").option("--json", "Machine-readable JSON output (list/search/comments)").option("--status <status>", "(comments list) Filter by status: open | solved | all (default: open)").option("--author <author>", "(comments list) Filter by author name, email, or user id").option("--cursor <cursor>", "(comments list) Pagination cursor from a previous page").option("--quiet", "Print only ids, one per line (comments)").option("--file <path>", "(comments reply) Read the message body from this file").action(async (action, target, arg3, arg4, opts) => {
|
|
91955
92492
|
const version3 = parsePositiveIntFlag(opts.ver, "version", "--ver 2");
|
|
91956
92493
|
if (version3 === null)
|
|
91957
92494
|
return;
|
|
@@ -91961,7 +92498,7 @@ function registerCommands(cli) {
|
|
|
91961
92498
|
const limit = parsePositiveIntFlag(opts.limit, "limit", "--limit 25", ARTIFACT_LIST_LIMIT_MAX);
|
|
91962
92499
|
if (limit === null)
|
|
91963
92500
|
return;
|
|
91964
|
-
await artifactCommand(action, target, { ...opts, version: version3, page, limit });
|
|
92501
|
+
await artifactCommand(action, target, arg3, arg4, { ...opts, version: version3, page, limit });
|
|
91965
92502
|
});
|
|
91966
92503
|
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 = {}) => {
|
|
91967
92504
|
switch (action) {
|
|
@@ -92136,7 +92673,7 @@ function getPackageVersion3() {
|
|
|
92136
92673
|
|
|
92137
92674
|
// src/shared/logger.ts
|
|
92138
92675
|
init_output_manager();
|
|
92139
|
-
var
|
|
92676
|
+
var import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
92140
92677
|
import { createWriteStream as createWriteStream4 } from "node:fs";
|
|
92141
92678
|
|
|
92142
92679
|
class Logger2 {
|
|
@@ -92145,23 +92682,23 @@ class Logger2 {
|
|
|
92145
92682
|
exitHandlerRegistered = false;
|
|
92146
92683
|
info(message) {
|
|
92147
92684
|
const symbols = output.getSymbols();
|
|
92148
|
-
console.log(
|
|
92685
|
+
console.log(import_picocolors34.default.blue(symbols.info), message);
|
|
92149
92686
|
}
|
|
92150
92687
|
success(message) {
|
|
92151
92688
|
const symbols = output.getSymbols();
|
|
92152
|
-
console.log(
|
|
92689
|
+
console.log(import_picocolors34.default.green(symbols.success), message);
|
|
92153
92690
|
}
|
|
92154
92691
|
warning(message) {
|
|
92155
92692
|
const symbols = output.getSymbols();
|
|
92156
|
-
console.log(
|
|
92693
|
+
console.log(import_picocolors34.default.yellow(symbols.warning), message);
|
|
92157
92694
|
}
|
|
92158
92695
|
error(message) {
|
|
92159
92696
|
const symbols = output.getSymbols();
|
|
92160
|
-
console.error(
|
|
92697
|
+
console.error(import_picocolors34.default.red(symbols.error), message);
|
|
92161
92698
|
}
|
|
92162
92699
|
debug(message) {
|
|
92163
92700
|
if (process.env.DEBUG) {
|
|
92164
|
-
console.log(
|
|
92701
|
+
console.log(import_picocolors34.default.gray("[DEBUG]"), message);
|
|
92165
92702
|
}
|
|
92166
92703
|
}
|
|
92167
92704
|
verbose(message, context) {
|
|
@@ -92170,7 +92707,7 @@ class Logger2 {
|
|
|
92170
92707
|
const timestamp = this.getTimestamp();
|
|
92171
92708
|
const sanitizedMessage = this.sanitize(message);
|
|
92172
92709
|
const formattedContext = context ? this.formatContext(context) : "";
|
|
92173
|
-
const logLine = `${timestamp} ${
|
|
92710
|
+
const logLine = `${timestamp} ${import_picocolors34.default.gray("[VERBOSE]")} ${sanitizedMessage}${formattedContext}`;
|
|
92174
92711
|
console.error(logLine);
|
|
92175
92712
|
if (this.logFileStream) {
|
|
92176
92713
|
const plainLogLine = `${timestamp} [VERBOSE] ${sanitizedMessage}${formattedContext}`;
|
|
@@ -92273,7 +92810,7 @@ var logger3 = new Logger2;
|
|
|
92273
92810
|
|
|
92274
92811
|
// src/shared/output-manager.ts
|
|
92275
92812
|
init_terminal_utils();
|
|
92276
|
-
var
|
|
92813
|
+
var import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
92277
92814
|
var SYMBOLS2 = {
|
|
92278
92815
|
unicode: {
|
|
92279
92816
|
prompt: "◇",
|
|
@@ -92354,7 +92891,7 @@ class OutputManager2 {
|
|
|
92354
92891
|
if (this.config.quiet)
|
|
92355
92892
|
return;
|
|
92356
92893
|
const symbol = this.getSymbols().success;
|
|
92357
|
-
console.log(
|
|
92894
|
+
console.log(import_picocolors35.default.green(`${symbol} ${message}`));
|
|
92358
92895
|
}
|
|
92359
92896
|
error(message, data) {
|
|
92360
92897
|
if (this.config.json) {
|
|
@@ -92362,7 +92899,7 @@ class OutputManager2 {
|
|
|
92362
92899
|
return;
|
|
92363
92900
|
}
|
|
92364
92901
|
const symbol = this.getSymbols().error;
|
|
92365
|
-
console.error(
|
|
92902
|
+
console.error(import_picocolors35.default.red(`${symbol} ${message}`));
|
|
92366
92903
|
}
|
|
92367
92904
|
warning(message, data) {
|
|
92368
92905
|
if (this.config.json) {
|
|
@@ -92372,7 +92909,7 @@ class OutputManager2 {
|
|
|
92372
92909
|
if (this.config.quiet)
|
|
92373
92910
|
return;
|
|
92374
92911
|
const symbol = this.getSymbols().warning;
|
|
92375
|
-
console.log(
|
|
92912
|
+
console.log(import_picocolors35.default.yellow(`${symbol} ${message}`));
|
|
92376
92913
|
}
|
|
92377
92914
|
info(message, data) {
|
|
92378
92915
|
if (this.config.json) {
|
|
@@ -92382,7 +92919,7 @@ class OutputManager2 {
|
|
|
92382
92919
|
if (this.config.quiet)
|
|
92383
92920
|
return;
|
|
92384
92921
|
const symbol = this.getSymbols().info;
|
|
92385
|
-
console.log(
|
|
92922
|
+
console.log(import_picocolors35.default.blue(`${symbol} ${message}`));
|
|
92386
92923
|
}
|
|
92387
92924
|
verbose(message, data) {
|
|
92388
92925
|
if (!this.config.verbose)
|
|
@@ -92391,7 +92928,7 @@ class OutputManager2 {
|
|
|
92391
92928
|
this.addJsonEntry({ type: "info", message, data });
|
|
92392
92929
|
return;
|
|
92393
92930
|
}
|
|
92394
|
-
console.log(
|
|
92931
|
+
console.log(import_picocolors35.default.dim(` ${message}`));
|
|
92395
92932
|
}
|
|
92396
92933
|
indent(message) {
|
|
92397
92934
|
if (this.config.json)
|
|
@@ -92416,7 +92953,7 @@ class OutputManager2 {
|
|
|
92416
92953
|
return;
|
|
92417
92954
|
const symbols = this.getSymbols();
|
|
92418
92955
|
console.log();
|
|
92419
|
-
console.log(
|
|
92956
|
+
console.log(import_picocolors35.default.bold(import_picocolors35.default.cyan(`${symbols.line} ${title}`)));
|
|
92420
92957
|
}
|
|
92421
92958
|
addJsonEntry(entry) {
|
|
92422
92959
|
this.jsonBuffer.push({
|