@runtypelabs/cli 2.19.4 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +187 -89
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48784,6 +48784,65 @@ import chalk17 from "chalk";
|
|
|
48784
48784
|
import React14 from "react";
|
|
48785
48785
|
import { render as render14 } from "ink";
|
|
48786
48786
|
import { useState as useState15, useEffect as useEffect16 } from "react";
|
|
48787
|
+
|
|
48788
|
+
// src/lib/terminal-image.ts
|
|
48789
|
+
var ESC = "\x1B";
|
|
48790
|
+
var BEL = "\x07";
|
|
48791
|
+
var ST = `${ESC}\\`;
|
|
48792
|
+
function detectImageProtocol(env = process.env, isTTY2 = process.stdout.isTTY === true) {
|
|
48793
|
+
if (!isTTY2) return null;
|
|
48794
|
+
if (env.TERM === "xterm-kitty" || env.KITTY_WINDOW_ID || env.TERM_PROGRAM === "ghostty") {
|
|
48795
|
+
return "kitty";
|
|
48796
|
+
}
|
|
48797
|
+
if (env.TERM_PROGRAM === "iTerm.app" || env.TERM_PROGRAM === "WezTerm" || env.LC_TERMINAL === "iTerm2") {
|
|
48798
|
+
return "iterm2";
|
|
48799
|
+
}
|
|
48800
|
+
return null;
|
|
48801
|
+
}
|
|
48802
|
+
function parseImageDataUri(value) {
|
|
48803
|
+
if (typeof value !== "string" || !value.startsWith("data:")) return null;
|
|
48804
|
+
const match = value.match(/^data:([^;,]+)(?:;[^,]*)?;base64,(.+)$/s);
|
|
48805
|
+
if (!match || !match[1] || !match[2]) return null;
|
|
48806
|
+
return { mimeType: match[1], base64: match[2] };
|
|
48807
|
+
}
|
|
48808
|
+
function base64DecodedByteLength(base643) {
|
|
48809
|
+
const len = base643.length;
|
|
48810
|
+
if (len === 0) return 0;
|
|
48811
|
+
let padding = 0;
|
|
48812
|
+
if (base643.endsWith("==")) padding = 2;
|
|
48813
|
+
else if (base643.endsWith("=")) padding = 1;
|
|
48814
|
+
return Math.floor(len * 3 / 4) - padding;
|
|
48815
|
+
}
|
|
48816
|
+
function kittyImageSequence(base643) {
|
|
48817
|
+
const CHUNK = 4096;
|
|
48818
|
+
if (base643.length <= CHUNK) {
|
|
48819
|
+
return `${ESC}_Ga=T,f=100,m=0;${base643}${ST}`;
|
|
48820
|
+
}
|
|
48821
|
+
let out = "";
|
|
48822
|
+
for (let i = 0; i < base643.length; i += CHUNK) {
|
|
48823
|
+
const piece = base643.slice(i, i + CHUNK);
|
|
48824
|
+
const more = i + CHUNK < base643.length ? 1 : 0;
|
|
48825
|
+
out += i === 0 ? `${ESC}_Ga=T,f=100,m=${more};${piece}${ST}` : `${ESC}_Gm=${more};${piece}${ST}`;
|
|
48826
|
+
}
|
|
48827
|
+
return out;
|
|
48828
|
+
}
|
|
48829
|
+
function encodeInlineImage(opts) {
|
|
48830
|
+
const { base64: base643, mimeType, protocol } = opts;
|
|
48831
|
+
if (!base643) return null;
|
|
48832
|
+
if (protocol === "iterm2") {
|
|
48833
|
+
const sizeBytes = base64DecodedByteLength(base643);
|
|
48834
|
+
return `${ESC}]1337;File=inline=1;size=${sizeBytes};width=auto;height=auto;preserveAspectRatio=1:${base643}${BEL}`;
|
|
48835
|
+
}
|
|
48836
|
+
if (mimeType !== "image/png") return null;
|
|
48837
|
+
return kittyImageSequence(base643);
|
|
48838
|
+
}
|
|
48839
|
+
function renderInlineImage(value, protocol) {
|
|
48840
|
+
const parsed = parseImageDataUri(value);
|
|
48841
|
+
if (!parsed) return null;
|
|
48842
|
+
return encodeInlineImage({ base64: parsed.base64, mimeType: parsed.mimeType, protocol });
|
|
48843
|
+
}
|
|
48844
|
+
|
|
48845
|
+
// src/commands/conversations.ts
|
|
48787
48846
|
function renderMessageContent(content) {
|
|
48788
48847
|
if (typeof content === "string") return content;
|
|
48789
48848
|
if (!Array.isArray(content)) return content == null ? "" : String(content);
|
|
@@ -48805,6 +48864,64 @@ function renderMessageContent(content) {
|
|
|
48805
48864
|
}
|
|
48806
48865
|
}).filter((s) => s.length > 0).join(" ");
|
|
48807
48866
|
}
|
|
48867
|
+
function writeMessageWithImages(msg, rolePrefix, protocol) {
|
|
48868
|
+
const out = process.stdout;
|
|
48869
|
+
const content = msg.content;
|
|
48870
|
+
if (!Array.isArray(content)) {
|
|
48871
|
+
out.write(`${rolePrefix}${renderMessageContent(content)}
|
|
48872
|
+
`);
|
|
48873
|
+
return;
|
|
48874
|
+
}
|
|
48875
|
+
const inline = [];
|
|
48876
|
+
const images = [];
|
|
48877
|
+
for (const part of content) {
|
|
48878
|
+
if (part && typeof part === "object" && part.type === "image") {
|
|
48879
|
+
const image = part.image;
|
|
48880
|
+
const seq = typeof image === "string" ? renderInlineImage(image, protocol) : null;
|
|
48881
|
+
if (seq) {
|
|
48882
|
+
images.push(seq);
|
|
48883
|
+
continue;
|
|
48884
|
+
}
|
|
48885
|
+
}
|
|
48886
|
+
inline.push(renderMessageContent([part]));
|
|
48887
|
+
}
|
|
48888
|
+
out.write(`${rolePrefix}${inline.filter((s) => s.length > 0).join(" ")}
|
|
48889
|
+
`);
|
|
48890
|
+
for (const seq of images) {
|
|
48891
|
+
out.write(`${seq}
|
|
48892
|
+
`);
|
|
48893
|
+
}
|
|
48894
|
+
}
|
|
48895
|
+
function printConversationDetail(data, imageProtocol) {
|
|
48896
|
+
printDetail("Conversation", [
|
|
48897
|
+
{ label: "ID", value: data.id },
|
|
48898
|
+
{ label: "Title", value: data.title },
|
|
48899
|
+
{ label: "Model", value: data.modelId },
|
|
48900
|
+
{ label: "System prompt", value: data.systemPrompt },
|
|
48901
|
+
{ label: "Owner", value: data.ownerId },
|
|
48902
|
+
{ label: "Source", value: data.source },
|
|
48903
|
+
{ label: "Created", value: data.createdAt },
|
|
48904
|
+
{ label: "Updated", value: data.updatedAt }
|
|
48905
|
+
]);
|
|
48906
|
+
const messages = data.messages ?? [];
|
|
48907
|
+
console.log(chalk17.cyan(`
|
|
48908
|
+
Messages (${messages.length}):`));
|
|
48909
|
+
if (messages.length === 0) {
|
|
48910
|
+
console.log(chalk17.gray(" No messages"));
|
|
48911
|
+
return;
|
|
48912
|
+
}
|
|
48913
|
+
for (const msg of messages) {
|
|
48914
|
+
const roleColor = msg.role === "user" ? chalk17.blue : msg.role === "assistant" ? chalk17.green : chalk17.gray;
|
|
48915
|
+
if (imageProtocol) {
|
|
48916
|
+
writeMessageWithImages(msg, ` ${roleColor(msg.role)}: `, imageProtocol);
|
|
48917
|
+
} else {
|
|
48918
|
+
console.log(` ${roleColor(msg.role)}: ${renderMessageContent(msg.content)}`);
|
|
48919
|
+
}
|
|
48920
|
+
if (msg.createdAt) {
|
|
48921
|
+
console.log(chalk17.dim(` ${msg.createdAt}`));
|
|
48922
|
+
}
|
|
48923
|
+
}
|
|
48924
|
+
}
|
|
48808
48925
|
var conversationsCommand = new Command15("conversations").description("Manage conversations");
|
|
48809
48926
|
conversationsCommand.command("list").description("List your conversations").option("--limit <n>", "Limit results (defaults to the API page size)").option("--cursor <cursor>", "Pagination cursor for the next page").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
|
|
48810
48927
|
const apiKey = await ensureAuth();
|
|
@@ -48882,99 +48999,80 @@ conversationsCommand.command("list").description("List your conversations").opti
|
|
|
48882
48999
|
const { waitUntilExit } = render14(React14.createElement(App));
|
|
48883
49000
|
await waitUntilExit();
|
|
48884
49001
|
});
|
|
48885
|
-
conversationsCommand.command("get <id>").description("Get conversation details including its messages").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").
|
|
48886
|
-
|
|
48887
|
-
|
|
48888
|
-
|
|
48889
|
-
|
|
48890
|
-
|
|
48891
|
-
|
|
48892
|
-
|
|
48893
|
-
|
|
48894
|
-
|
|
48895
|
-
|
|
48896
|
-
|
|
48897
|
-
|
|
48898
|
-
{ label: "Title", value: data.title },
|
|
48899
|
-
{ label: "Model", value: data.modelId },
|
|
48900
|
-
{ label: "System prompt", value: data.systemPrompt },
|
|
48901
|
-
{ label: "Owner", value: data.ownerId },
|
|
48902
|
-
{ label: "Source", value: data.source },
|
|
48903
|
-
{ label: "Created", value: data.createdAt },
|
|
48904
|
-
{ label: "Updated", value: data.updatedAt }
|
|
48905
|
-
]);
|
|
48906
|
-
const messages = data.messages ?? [];
|
|
48907
|
-
console.log(chalk17.cyan(`
|
|
48908
|
-
Messages (${messages.length}):`));
|
|
48909
|
-
if (messages.length === 0) {
|
|
48910
|
-
console.log(chalk17.gray(" No messages"));
|
|
48911
|
-
} else {
|
|
48912
|
-
for (const msg of messages) {
|
|
48913
|
-
const roleColor = msg.role === "user" ? chalk17.blue : msg.role === "assistant" ? chalk17.green : chalk17.gray;
|
|
48914
|
-
console.log(` ${roleColor(msg.role)}: ${renderMessageContent(msg.content)}`);
|
|
48915
|
-
if (msg.createdAt) {
|
|
48916
|
-
console.log(chalk17.dim(` ${msg.createdAt}`));
|
|
48917
|
-
}
|
|
49002
|
+
conversationsCommand.command("get <id>").description("Get conversation details including its messages").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").option("--no-images", "Disable inline image rendering even in supported terminals").action(
|
|
49003
|
+
async (id, options) => {
|
|
49004
|
+
const apiKey = await ensureAuth();
|
|
49005
|
+
if (!apiKey) return;
|
|
49006
|
+
const client = createCliClient(apiKey);
|
|
49007
|
+
const interactive = isTTY(options) && !options.json;
|
|
49008
|
+
const imageProtocol = interactive && options.images !== false ? detectImageProtocol() : null;
|
|
49009
|
+
if (!interactive || imageProtocol) {
|
|
49010
|
+
try {
|
|
49011
|
+
const data = await client.get(`/conversations/${id}`);
|
|
49012
|
+
if (options.json) {
|
|
49013
|
+
printJson(data);
|
|
49014
|
+
return;
|
|
48918
49015
|
}
|
|
49016
|
+
printConversationDetail(data, imageProtocol);
|
|
49017
|
+
} catch (error51) {
|
|
49018
|
+
const message = error51 instanceof Error ? error51.message : "Unknown error";
|
|
49019
|
+
console.error(chalk17.red(`Failed to fetch conversation: ${message}`));
|
|
49020
|
+
process.exit(1);
|
|
48919
49021
|
}
|
|
48920
|
-
|
|
48921
|
-
const message = error51 instanceof Error ? error51.message : "Unknown error";
|
|
48922
|
-
console.error(chalk17.red(`Failed to fetch conversation: ${message}`));
|
|
48923
|
-
process.exit(1);
|
|
49022
|
+
return;
|
|
48924
49023
|
}
|
|
48925
|
-
|
|
49024
|
+
const App = () => {
|
|
49025
|
+
const [loading, setLoading] = useState15(true);
|
|
49026
|
+
const [success2, setSuccess] = useState15(null);
|
|
49027
|
+
const [error51, setError] = useState15(null);
|
|
49028
|
+
const [resultNode, setResultNode] = useState15(void 0);
|
|
49029
|
+
useEffect16(() => {
|
|
49030
|
+
const run2 = async () => {
|
|
49031
|
+
try {
|
|
49032
|
+
const data = await client.get(`/conversations/${id}`);
|
|
49033
|
+
const messages = data.messages ?? [];
|
|
49034
|
+
const messageSummary = messages.length === 0 ? "No messages" : messages.map((m2) => `${m2.role}: ${renderMessageContent(m2.content)}`).join("\n");
|
|
49035
|
+
setResultNode(
|
|
49036
|
+
React14.createElement(EntityCard, {
|
|
49037
|
+
fields: [
|
|
49038
|
+
{ label: "ID", value: data.id, color: "green" },
|
|
49039
|
+
{ label: "Title", value: data.title },
|
|
49040
|
+
{ label: "Model", value: data.modelId },
|
|
49041
|
+
{ label: "System prompt", value: data.systemPrompt },
|
|
49042
|
+
{ label: "Owner", value: data.ownerId },
|
|
49043
|
+
{ label: "Source", value: data.source, color: "gray" },
|
|
49044
|
+
{ label: "Created", value: data.createdAt },
|
|
49045
|
+
{ label: "Updated", value: data.updatedAt },
|
|
49046
|
+
{
|
|
49047
|
+
label: `Messages (${messages.length})`,
|
|
49048
|
+
value: messageSummary
|
|
49049
|
+
}
|
|
49050
|
+
]
|
|
49051
|
+
})
|
|
49052
|
+
);
|
|
49053
|
+
setSuccess(true);
|
|
49054
|
+
setLoading(false);
|
|
49055
|
+
} catch (err) {
|
|
49056
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
49057
|
+
setSuccess(false);
|
|
49058
|
+
setLoading(false);
|
|
49059
|
+
}
|
|
49060
|
+
};
|
|
49061
|
+
run2();
|
|
49062
|
+
}, []);
|
|
49063
|
+
return React14.createElement(MutationResult, {
|
|
49064
|
+
loading,
|
|
49065
|
+
loadingLabel: "Fetching conversation...",
|
|
49066
|
+
success: success2,
|
|
49067
|
+
successMessage: "Conversation",
|
|
49068
|
+
error: error51,
|
|
49069
|
+
result: resultNode
|
|
49070
|
+
});
|
|
49071
|
+
};
|
|
49072
|
+
const { waitUntilExit } = render14(React14.createElement(App));
|
|
49073
|
+
await waitUntilExit();
|
|
48926
49074
|
}
|
|
48927
|
-
|
|
48928
|
-
const [loading, setLoading] = useState15(true);
|
|
48929
|
-
const [success2, setSuccess] = useState15(null);
|
|
48930
|
-
const [error51, setError] = useState15(null);
|
|
48931
|
-
const [resultNode, setResultNode] = useState15(void 0);
|
|
48932
|
-
useEffect16(() => {
|
|
48933
|
-
const run2 = async () => {
|
|
48934
|
-
try {
|
|
48935
|
-
const data = await client.get(`/conversations/${id}`);
|
|
48936
|
-
const messages = data.messages ?? [];
|
|
48937
|
-
const messageSummary = messages.length === 0 ? "No messages" : messages.map((m2) => `${m2.role}: ${renderMessageContent(m2.content)}`).join("\n");
|
|
48938
|
-
setResultNode(
|
|
48939
|
-
React14.createElement(EntityCard, {
|
|
48940
|
-
fields: [
|
|
48941
|
-
{ label: "ID", value: data.id, color: "green" },
|
|
48942
|
-
{ label: "Title", value: data.title },
|
|
48943
|
-
{ label: "Model", value: data.modelId },
|
|
48944
|
-
{ label: "System prompt", value: data.systemPrompt },
|
|
48945
|
-
{ label: "Owner", value: data.ownerId },
|
|
48946
|
-
{ label: "Source", value: data.source, color: "gray" },
|
|
48947
|
-
{ label: "Created", value: data.createdAt },
|
|
48948
|
-
{ label: "Updated", value: data.updatedAt },
|
|
48949
|
-
{
|
|
48950
|
-
label: `Messages (${messages.length})`,
|
|
48951
|
-
value: messageSummary
|
|
48952
|
-
}
|
|
48953
|
-
]
|
|
48954
|
-
})
|
|
48955
|
-
);
|
|
48956
|
-
setSuccess(true);
|
|
48957
|
-
setLoading(false);
|
|
48958
|
-
} catch (err) {
|
|
48959
|
-
setError(err instanceof Error ? err : new Error(String(err)));
|
|
48960
|
-
setSuccess(false);
|
|
48961
|
-
setLoading(false);
|
|
48962
|
-
}
|
|
48963
|
-
};
|
|
48964
|
-
run2();
|
|
48965
|
-
}, []);
|
|
48966
|
-
return React14.createElement(MutationResult, {
|
|
48967
|
-
loading,
|
|
48968
|
-
loadingLabel: "Fetching conversation...",
|
|
48969
|
-
success: success2,
|
|
48970
|
-
successMessage: "Conversation",
|
|
48971
|
-
error: error51,
|
|
48972
|
-
result: resultNode
|
|
48973
|
-
});
|
|
48974
|
-
};
|
|
48975
|
-
const { waitUntilExit } = render14(React14.createElement(App));
|
|
48976
|
-
await waitUntilExit();
|
|
48977
|
-
});
|
|
49075
|
+
);
|
|
48978
49076
|
conversationsCommand.command("delete <id>").description("Delete a conversation").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").option("--yes", "Skip confirmation").action(async (id, options) => {
|
|
48979
49077
|
const apiKey = await ensureAuth();
|
|
48980
49078
|
if (!apiKey) return;
|