@punkcode/cli 0.1.6 → 0.1.8
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/cli.js +94 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -33,6 +33,36 @@ async function* promptWithImages(text, images, sessionId) {
|
|
|
33
33
|
session_id: sessionId
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
+
async function getSessionInfo(sessionId, cwd) {
|
|
37
|
+
const q = query({
|
|
38
|
+
prompt: "",
|
|
39
|
+
options: {
|
|
40
|
+
resume: sessionId,
|
|
41
|
+
...cwd && { cwd }
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
try {
|
|
45
|
+
const [init, commands, mcpServers] = await Promise.all([
|
|
46
|
+
q.initializationResult(),
|
|
47
|
+
q.supportedCommands(),
|
|
48
|
+
q.mcpServerStatus()
|
|
49
|
+
]);
|
|
50
|
+
const cmdList = commands.length >= init.commands.length ? commands : init.commands;
|
|
51
|
+
return {
|
|
52
|
+
sessionId,
|
|
53
|
+
tools: [],
|
|
54
|
+
slashCommands: cmdList.map((c) => ({ name: c.name, description: c.description })),
|
|
55
|
+
skills: [],
|
|
56
|
+
mcpServers: mcpServers.map((s) => ({ name: s.name, status: s.status })),
|
|
57
|
+
model: init.models?.[0]?.value ?? "",
|
|
58
|
+
cwd: cwd ?? "",
|
|
59
|
+
claudeCodeVersion: "",
|
|
60
|
+
permissionMode: "default"
|
|
61
|
+
};
|
|
62
|
+
} finally {
|
|
63
|
+
q.close();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
36
66
|
function runClaude(options, callbacks) {
|
|
37
67
|
const opts = options.options || {};
|
|
38
68
|
const isBypass = opts.permissionMode === "bypassPermissions";
|
|
@@ -49,6 +79,7 @@ function runClaude(options, callbacks) {
|
|
|
49
79
|
...opts.allowedTools && { allowedTools: opts.allowedTools },
|
|
50
80
|
...opts.disallowedTools && { disallowedTools: opts.disallowedTools },
|
|
51
81
|
...opts.maxTurns && { maxTurns: opts.maxTurns },
|
|
82
|
+
systemPrompt: opts.systemPrompt ?? { type: "preset", preset: "claude_code" },
|
|
52
83
|
...options.cwd && { cwd: options.cwd },
|
|
53
84
|
...options.sessionId && { resume: options.sessionId },
|
|
54
85
|
maxThinkingTokens: 1e4,
|
|
@@ -148,10 +179,18 @@ function runClaude(options, callbacks) {
|
|
|
148
179
|
case "system": {
|
|
149
180
|
const sys = message;
|
|
150
181
|
if (sys.subtype === "init" && callbacks.onSessionCreated) {
|
|
182
|
+
let slashCommands = (sys.slash_commands ?? []).map((cmd) => ({ name: cmd, description: "" }));
|
|
183
|
+
try {
|
|
184
|
+
const cmds = await q.supportedCommands();
|
|
185
|
+
if (cmds.length > 0) {
|
|
186
|
+
slashCommands = cmds.map((c) => ({ name: c.name, description: c.description }));
|
|
187
|
+
}
|
|
188
|
+
} catch {
|
|
189
|
+
}
|
|
151
190
|
callbacks.onSessionCreated({
|
|
152
191
|
sessionId: sys.session_id ?? "",
|
|
153
192
|
tools: sys.tools ?? [],
|
|
154
|
-
slashCommands
|
|
193
|
+
slashCommands,
|
|
155
194
|
skills: sys.skills ?? [],
|
|
156
195
|
mcpServers: sys.mcp_servers ?? [],
|
|
157
196
|
model: sys.model ?? "",
|
|
@@ -218,14 +257,18 @@ function getOrCreateDeviceId() {
|
|
|
218
257
|
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
219
258
|
return id;
|
|
220
259
|
}
|
|
221
|
-
function collectDeviceInfo(deviceId, customName) {
|
|
260
|
+
function collectDeviceInfo(deviceId, customName, customTags) {
|
|
222
261
|
if (customName) {
|
|
223
262
|
saveConfigField("deviceName", customName);
|
|
224
263
|
}
|
|
264
|
+
if (customTags && customTags.length > 0) {
|
|
265
|
+
saveConfigField("tags", customTags);
|
|
266
|
+
}
|
|
225
267
|
const cpus = os.cpus();
|
|
226
268
|
return {
|
|
227
269
|
deviceId,
|
|
228
270
|
name: customName || getDeviceName(),
|
|
271
|
+
tags: customTags && customTags.length > 0 ? customTags : getTags(),
|
|
229
272
|
platform: process.platform,
|
|
230
273
|
arch: process.arch,
|
|
231
274
|
username: os.userInfo().username,
|
|
@@ -254,6 +297,14 @@ function getDeviceName() {
|
|
|
254
297
|
}
|
|
255
298
|
return os.hostname();
|
|
256
299
|
}
|
|
300
|
+
function getTags() {
|
|
301
|
+
try {
|
|
302
|
+
const config = JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
|
|
303
|
+
if (Array.isArray(config.tags)) return config.tags;
|
|
304
|
+
} catch {
|
|
305
|
+
}
|
|
306
|
+
return [];
|
|
307
|
+
}
|
|
257
308
|
function saveConfigField(key, value) {
|
|
258
309
|
fs.mkdirSync(PUNK_DIR, { recursive: true });
|
|
259
310
|
let config = {};
|
|
@@ -543,7 +594,7 @@ function parseSessionFile(content) {
|
|
|
543
594
|
}
|
|
544
595
|
if (entry.type === "system" && entry.subtype === "compact_boundary") {
|
|
545
596
|
messages.push({
|
|
546
|
-
role: "
|
|
597
|
+
role: "system",
|
|
547
598
|
content: [],
|
|
548
599
|
timestamp: entry.timestamp,
|
|
549
600
|
type: "system",
|
|
@@ -553,6 +604,24 @@ function parseSessionFile(content) {
|
|
|
553
604
|
});
|
|
554
605
|
continue;
|
|
555
606
|
}
|
|
607
|
+
if (entry.isCompactSummary && entry.message) {
|
|
608
|
+
const summaryContent = entry.message.content;
|
|
609
|
+
let summaryText = "";
|
|
610
|
+
if (typeof summaryContent === "string") {
|
|
611
|
+
summaryText = summaryContent;
|
|
612
|
+
} else if (Array.isArray(summaryContent)) {
|
|
613
|
+
summaryText = summaryContent.filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("\n");
|
|
614
|
+
}
|
|
615
|
+
if (summaryText) {
|
|
616
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
617
|
+
if (messages[i].subtype === "compact_boundary") {
|
|
618
|
+
messages[i].content = [{ type: "text", text: summaryText }];
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
556
625
|
if ((entry.type === "user" || entry.type === "assistant") && entry.message) {
|
|
557
626
|
const msgContent = entry.message.content;
|
|
558
627
|
messages.push({
|
|
@@ -870,7 +939,7 @@ async function connect(server, options) {
|
|
|
870
939
|
const activeSessions = /* @__PURE__ */ new Map();
|
|
871
940
|
socket.on("connect", () => {
|
|
872
941
|
logger.info("Connected");
|
|
873
|
-
const deviceInfo = collectDeviceInfo(deviceId, options.name);
|
|
942
|
+
const deviceInfo = collectDeviceInfo(deviceId, options.name, options.tag);
|
|
874
943
|
socket.emit("register", deviceInfo, (response) => {
|
|
875
944
|
if (response.success) {
|
|
876
945
|
logger.info({ deviceId }, "Registered");
|
|
@@ -897,6 +966,11 @@ async function connect(server, options) {
|
|
|
897
966
|
handleGetContext(socket, msg);
|
|
898
967
|
}
|
|
899
968
|
});
|
|
969
|
+
socket.on("get-session-info", (msg) => {
|
|
970
|
+
if (msg.type === "get-session-info") {
|
|
971
|
+
handleGetSessionInfo(socket, msg);
|
|
972
|
+
}
|
|
973
|
+
});
|
|
900
974
|
socket.on("cancel", (msg) => {
|
|
901
975
|
handleCancel(msg.id, activeSessions);
|
|
902
976
|
});
|
|
@@ -918,7 +992,7 @@ async function connect(server, options) {
|
|
|
918
992
|
});
|
|
919
993
|
socket.on("reconnect", (attemptNumber) => {
|
|
920
994
|
logger.info({ attemptNumber }, "Reconnected");
|
|
921
|
-
socket.emit("register", collectDeviceInfo(deviceId, options.name));
|
|
995
|
+
socket.emit("register", collectDeviceInfo(deviceId, options.name, options.tag));
|
|
922
996
|
});
|
|
923
997
|
socket.on("connect_error", (err) => {
|
|
924
998
|
logger.error({ err }, "Connection error");
|
|
@@ -1035,6 +1109,20 @@ async function handleLoadSession(socket, msg) {
|
|
|
1035
1109
|
log2.warn("Session not found");
|
|
1036
1110
|
}
|
|
1037
1111
|
}
|
|
1112
|
+
async function handleGetSessionInfo(socket, msg) {
|
|
1113
|
+
const { id, sessionId, cwd } = msg;
|
|
1114
|
+
const log2 = createChildLogger({ sessionId });
|
|
1115
|
+
log2.info("Getting session info...");
|
|
1116
|
+
try {
|
|
1117
|
+
const data = await getSessionInfo(sessionId, cwd);
|
|
1118
|
+
send(socket, "response", { type: "session_info", data, requestId: id });
|
|
1119
|
+
log2.info("Session info retrieved");
|
|
1120
|
+
} catch (err) {
|
|
1121
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1122
|
+
send(socket, "response", { type: "error", message, requestId: id });
|
|
1123
|
+
log2.error({ err }, "Session info error");
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1038
1126
|
async function handleGetContext(socket, msg) {
|
|
1039
1127
|
const { id, sessionId, cwd } = msg;
|
|
1040
1128
|
const log2 = createChildLogger({ sessionId });
|
|
@@ -1122,7 +1210,7 @@ function logout() {
|
|
|
1122
1210
|
|
|
1123
1211
|
// src/commands/index.ts
|
|
1124
1212
|
function registerCommands(program2) {
|
|
1125
|
-
program2.command("connect").argument("[server]", "Backend server URL", "https://api.punkcode.dev").description("Connect to backend server").option("-t, --token <token>", "Authentication token").option("-d, --device-id <deviceId>", "Device identifier (defaults to hostname)").option("-n, --name <name>", "Custom device display name").action(connect);
|
|
1213
|
+
program2.command("connect").argument("[server]", "Backend server URL", "https://api.punkcode.dev").description("Connect to backend server").option("-t, --token <token>", "Authentication token").option("-d, --device-id <deviceId>", "Device identifier (defaults to hostname)").option("-n, --name <name>", "Custom device display name").option("--tag <tag>", "Device tag (repeatable, e.g. --tag home --tag mac --tag docker)", (val, acc) => [...acc, val], []).action(connect);
|
|
1126
1214
|
program2.command("login").description("Log in with your email and password").action(login);
|
|
1127
1215
|
program2.command("logout").description("Log out and clear stored credentials").action(logout);
|
|
1128
1216
|
}
|