@punkcode/cli 0.1.7 → 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.
Files changed (2) hide show
  1. package/dist/cli.js +74 -5
  2. 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";
@@ -149,10 +179,18 @@ function runClaude(options, callbacks) {
149
179
  case "system": {
150
180
  const sys = message;
151
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
+ }
152
190
  callbacks.onSessionCreated({
153
191
  sessionId: sys.session_id ?? "",
154
192
  tools: sys.tools ?? [],
155
- slashCommands: (sys.slash_commands ?? []).map((cmd) => ({ name: cmd, description: "" })),
193
+ slashCommands,
156
194
  skills: sys.skills ?? [],
157
195
  mcpServers: sys.mcp_servers ?? [],
158
196
  model: sys.model ?? "",
@@ -219,14 +257,18 @@ function getOrCreateDeviceId() {
219
257
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", "utf-8");
220
258
  return id;
221
259
  }
222
- function collectDeviceInfo(deviceId, customName) {
260
+ function collectDeviceInfo(deviceId, customName, customTags) {
223
261
  if (customName) {
224
262
  saveConfigField("deviceName", customName);
225
263
  }
264
+ if (customTags && customTags.length > 0) {
265
+ saveConfigField("tags", customTags);
266
+ }
226
267
  const cpus = os.cpus();
227
268
  return {
228
269
  deviceId,
229
270
  name: customName || getDeviceName(),
271
+ tags: customTags && customTags.length > 0 ? customTags : getTags(),
230
272
  platform: process.platform,
231
273
  arch: process.arch,
232
274
  username: os.userInfo().username,
@@ -255,6 +297,14 @@ function getDeviceName() {
255
297
  }
256
298
  return os.hostname();
257
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
+ }
258
308
  function saveConfigField(key, value) {
259
309
  fs.mkdirSync(PUNK_DIR, { recursive: true });
260
310
  let config = {};
@@ -889,7 +939,7 @@ async function connect(server, options) {
889
939
  const activeSessions = /* @__PURE__ */ new Map();
890
940
  socket.on("connect", () => {
891
941
  logger.info("Connected");
892
- const deviceInfo = collectDeviceInfo(deviceId, options.name);
942
+ const deviceInfo = collectDeviceInfo(deviceId, options.name, options.tag);
893
943
  socket.emit("register", deviceInfo, (response) => {
894
944
  if (response.success) {
895
945
  logger.info({ deviceId }, "Registered");
@@ -916,6 +966,11 @@ async function connect(server, options) {
916
966
  handleGetContext(socket, msg);
917
967
  }
918
968
  });
969
+ socket.on("get-session-info", (msg) => {
970
+ if (msg.type === "get-session-info") {
971
+ handleGetSessionInfo(socket, msg);
972
+ }
973
+ });
919
974
  socket.on("cancel", (msg) => {
920
975
  handleCancel(msg.id, activeSessions);
921
976
  });
@@ -937,7 +992,7 @@ async function connect(server, options) {
937
992
  });
938
993
  socket.on("reconnect", (attemptNumber) => {
939
994
  logger.info({ attemptNumber }, "Reconnected");
940
- socket.emit("register", collectDeviceInfo(deviceId, options.name));
995
+ socket.emit("register", collectDeviceInfo(deviceId, options.name, options.tag));
941
996
  });
942
997
  socket.on("connect_error", (err) => {
943
998
  logger.error({ err }, "Connection error");
@@ -1054,6 +1109,20 @@ async function handleLoadSession(socket, msg) {
1054
1109
  log2.warn("Session not found");
1055
1110
  }
1056
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
+ }
1057
1126
  async function handleGetContext(socket, msg) {
1058
1127
  const { id, sessionId, cwd } = msg;
1059
1128
  const log2 = createChildLogger({ sessionId });
@@ -1141,7 +1210,7 @@ function logout() {
1141
1210
 
1142
1211
  // src/commands/index.ts
1143
1212
  function registerCommands(program2) {
1144
- 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);
1145
1214
  program2.command("login").description("Log in with your email and password").action(login);
1146
1215
  program2.command("logout").description("Log out and clear stored credentials").action(logout);
1147
1216
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@punkcode/cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Control Claude Code from your phone",
5
5
  "type": "module",
6
6
  "bin": {