anywhere-ai 0.0.32 → 0.0.34

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 CHANGED
@@ -17,13 +17,13 @@ var STATUS_PATH = path.join(ANYWHERE_DIR, "status.json");
17
17
  var args = process.argv.slice(2);
18
18
  var command = args.find((a) => !a.startsWith("-"));
19
19
  if (args.includes("--version") || args.includes("-v")) {
20
- console.log(`anywhere-ai v${"0.0.32"}`);
20
+ console.log(`anywhere-ai v${"0.0.34"}`);
21
21
  process.exit(0);
22
22
  }
23
23
  if (args.includes("--help") || args.includes("-h") || command === "help") {
24
- console.log(`anywhere-ai v${"0.0.32"} \u2014 Mobile coding agent
24
+ console.log(`anywhere-ai v${"0.0.34"} \u2014 Mobile coding agent
25
25
 
26
- Usage: anywhere-ai [command] [options]
26
+ Usage: npx anywhere-ai [command] [options]
27
27
 
28
28
  Commands:
29
29
  status Show server status and connection info
@@ -112,7 +112,7 @@ if (command === "regenerate-token") {
112
112
  try {
113
113
  await fs.access(CONFIG_PATH);
114
114
  } catch {
115
- console.error("No config found. Run `anywhere-ai` first to set up.");
115
+ console.error("No config found. Run `npx anywhere-ai` first to set up.");
116
116
  process.exit(1);
117
117
  }
118
118
  const config2 = JSON.parse(await fs.readFile(CONFIG_PATH, "utf-8"));
@@ -124,16 +124,16 @@ if (command === "regenerate-token") {
124
124
  var isDaemon = !args.includes("--foreground");
125
125
  var existingPid = getDaemonPid();
126
126
  if (existingPid) {
127
- console.log(`Server already running (PID ${existingPid}). Use 'anywhere-ai stop' first.`);
127
+ console.log(`Server already running (PID ${existingPid}). Use 'npx anywhere-ai stop' first.`);
128
128
  process.exit(1);
129
129
  }
130
130
  async function checkForUpdate() {
131
131
  try {
132
132
  const res = await fetch("https://registry.npmjs.org/anywhere-ai/latest", { signal: AbortSignal.timeout(3e3) });
133
133
  const data = await res.json();
134
- if (data.version && data.version !== "0.0.32") {
134
+ if (data.version && data.version !== "0.0.34") {
135
135
  console.log(`
136
- Update available: v${"0.0.32"} \u2192 v${data.version}`);
136
+ Update available: v${"0.0.34"} \u2192 v${data.version}`);
137
137
  console.log(` Run: npx anywhere-ai@latest
138
138
  `);
139
139
  }
@@ -429,8 +429,8 @@ if (isDaemon) {
429
429
  });
430
430
  console.log(" Server will keep running after terminal closes.");
431
431
  console.log(" Use --foreground to disable this behavior.");
432
- console.log(` Status: anywhere-ai status`);
433
- console.log(` Stop: anywhere-ai stop`);
432
+ console.log(` Status: npx anywhere-ai status`);
433
+ console.log(` Stop: npx anywhere-ai stop`);
434
434
  console.log();
435
435
  }
436
436
  function cleanup() {
package/dist/server.js CHANGED
@@ -700,78 +700,94 @@ chats.get("/:id", async (c) => {
700
700
  const sessionId = c.req.param("id");
701
701
  if (!sessionId || /[\/\\]/.test(sessionId))
702
702
  return c.json({ error: "Invalid session id" }, 400);
703
+ const limit = Math.min(Math.max(parseInt(c.req.query("limit") || "30", 10) || 30, 1), 500);
704
+ const offset = Math.max(parseInt(c.req.query("offset") || "0", 10) || 0, 0);
703
705
  try {
704
706
  const file = await findSessionFile(sessionId);
705
707
  if (!file) return c.json({ error: "Chat not found" }, 404);
706
708
  const fileStat = await stat2(file);
707
709
  const cached = chatDetailCache.get(sessionId);
708
- if (cached && cached.mtimeMs === fileStat.mtimeMs) {
709
- return c.json(cached.response);
710
- }
711
- const content = await readFile2(file, "utf-8");
712
- const lines = content.split("\n").filter(Boolean);
713
- const parsed = lines.map((line) => JSON.parse(line));
710
+ let allMessages;
714
711
  let model;
715
712
  let permissionMode;
716
713
  let cwd;
717
- for (const obj of parsed) {
718
- if (obj.type === "user" && obj.cwd && !cwd) cwd = obj.cwd;
719
- }
720
- for (const obj of [...parsed].reverse()) {
721
- if (!model && obj.type === "assistant") model = obj.message?.model;
722
- if (!permissionMode && obj.type === "user" && !obj.isMeta)
723
- permissionMode = obj.permissionMode;
724
- if (model && permissionMode) break;
725
- }
726
- const messages = parsed.filter(
727
- (obj) => obj.type === "user" && !obj.isMeta || obj.type === "assistant"
728
- ).flatMap((obj) => {
729
- const content2 = obj.message.content;
730
- if (typeof content2 === "string") {
731
- return [
732
- {
733
- role: obj.message.role,
734
- type: "text",
735
- text: content2.trim(),
736
- timestamp: obj.timestamp
737
- }
738
- ];
714
+ let chatName;
715
+ if (cached && cached.mtimeMs === fileStat.mtimeMs) {
716
+ allMessages = cached.response.messages;
717
+ model = cached.response.model;
718
+ permissionMode = cached.response.permissionMode;
719
+ cwd = cached.response.cwd;
720
+ chatName = cached.response.chatName;
721
+ } else {
722
+ const content = await readFile2(file, "utf-8");
723
+ const lines = content.split("\n").filter(Boolean);
724
+ const parsed = lines.map((line) => JSON.parse(line));
725
+ for (const obj of parsed) {
726
+ if (obj.type === "user" && obj.cwd && !cwd) cwd = obj.cwd;
739
727
  }
740
- return content2.filter(
741
- (b) => ["text", "tool_use", "tool_result"].includes(b.type)
742
- ).map((b) => {
743
- if (b.type === "text") {
744
- return {
745
- role: obj.message.role,
746
- type: "text",
747
- text: b.text.trim(),
748
- timestamp: obj.timestamp
749
- };
750
- }
751
- if (b.type === "tool_use") {
752
- return {
753
- role: obj.message.role,
754
- type: "tool_use",
755
- name: b.name,
756
- input: b.input,
757
- timestamp: obj.timestamp
758
- };
759
- }
760
- if (b.type === "tool_result") {
761
- const resultText = Array.isArray(b.content) ? b.content.filter((r) => r.type === "text").map((r) => r.text).join("") : b.content ?? "";
762
- return {
763
- role: obj.message.role,
764
- type: "tool_result",
765
- text: resultText.trim(),
766
- timestamp: obj.timestamp
767
- };
728
+ for (const obj of [...parsed].reverse()) {
729
+ if (!model && obj.type === "assistant") model = obj.message?.model;
730
+ if (!permissionMode && obj.type === "user" && !obj.isMeta)
731
+ permissionMode = obj.permissionMode;
732
+ if (model && permissionMode) break;
733
+ }
734
+ allMessages = parsed.filter(
735
+ (obj) => obj.type === "user" && !obj.isMeta || obj.type === "assistant"
736
+ ).flatMap((obj) => {
737
+ const content2 = obj.message.content;
738
+ if (typeof content2 === "string") {
739
+ return [
740
+ {
741
+ role: obj.message.role,
742
+ type: "text",
743
+ text: content2.trim(),
744
+ timestamp: obj.timestamp
745
+ }
746
+ ];
768
747
  }
769
- }).filter(Boolean);
770
- });
771
- const chatName = await getChatName(sessionId);
772
- const response = { messages, model, permissionMode, cwd, chatName: chatName || "" };
773
- chatDetailCache.set(sessionId, { mtimeMs: fileStat.mtimeMs, response });
774
- return c.json(response);
748
+ return content2.filter(
749
+ (b) => ["text", "tool_use", "tool_result"].includes(b.type)
750
+ ).map((b) => {
751
+ if (b.type === "text") {
752
+ return {
753
+ role: obj.message.role,
754
+ type: "text",
755
+ text: b.text.trim(),
756
+ timestamp: obj.timestamp
757
+ };
758
+ }
759
+ if (b.type === "tool_use") {
760
+ return {
761
+ role: obj.message.role,
762
+ type: "tool_use",
763
+ name: b.name,
764
+ input: b.input,
765
+ timestamp: obj.timestamp
766
+ };
767
+ }
768
+ if (b.type === "tool_result") {
769
+ const resultText = Array.isArray(b.content) ? b.content.filter((r) => r.type === "text").map((r) => r.text).join("") : b.content ?? "";
770
+ return {
771
+ role: obj.message.role,
772
+ type: "tool_result",
773
+ text: resultText.trim(),
774
+ timestamp: obj.timestamp
775
+ };
776
+ }
777
+ }).filter(Boolean);
778
+ });
779
+ chatName = await getChatName(sessionId) || "";
780
+ chatDetailCache.set(sessionId, {
781
+ mtimeMs: fileStat.mtimeMs,
782
+ response: { messages: allMessages, model, permissionMode, cwd, chatName }
783
+ });
784
+ }
785
+ const total = allMessages.length;
786
+ const start = Math.max(total - offset - limit, 0);
787
+ const end = Math.max(total - offset, 0);
788
+ const messages = allMessages.slice(start, end);
789
+ const hasMore = start > 0;
790
+ return c.json({ messages, model, permissionMode, cwd, chatName, total, hasMore });
775
791
  } catch {
776
792
  return c.json({ error: "Chat not found" }, 404);
777
793
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anywhere-ai",
3
- "version": "0.0.32",
3
+ "version": "0.0.34",
4
4
  "type": "module",
5
5
  "description": "Code on any repo from your phone",
6
6
  "bin": {