mobileclaude-agent 0.1.2 → 0.1.4

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.
@@ -67,6 +67,16 @@ export async function parseAndUpsertSession(filePath, startedFromMobile) {
67
67
  console.error(`Session indexer upsert error for ${basename(filePath)}:`, error.message);
68
68
  }
69
69
  }
70
+ function extractUserText(content) {
71
+ if (typeof content === 'string')
72
+ return content;
73
+ if (Array.isArray(content)) {
74
+ const textBlock = content.find((b) => b !== null && typeof b === 'object' && b.type === 'text');
75
+ if (textBlock)
76
+ return String(textBlock.text ?? '');
77
+ }
78
+ return '';
79
+ }
70
80
  export function parseJSONLSession(raw) {
71
81
  const lines = raw.split('\n').filter((l) => l.trim().length > 0);
72
82
  const entries = [];
@@ -78,10 +88,28 @@ export function parseJSONLSession(raw) {
78
88
  }
79
89
  if (entries.length === 0)
80
90
  return null;
81
- const userEntries = entries.filter((e) => e.type === 'user' &&
82
- e.message !== null &&
83
- typeof e.message === 'object' &&
84
- typeof e.message.content === 'string');
91
+ // Claude Code user messages can have content as a plain string OR as an array of
92
+ // content blocks (e.g. [{"type":"text","text":"..."}] or tool_result arrays).
93
+ // We only want entries where the user actually typed a prompt (text content).
94
+ const userEntries = entries.filter((e) => {
95
+ if (e.type !== 'user')
96
+ return false;
97
+ const msg = e.message;
98
+ if (!msg || typeof msg !== 'object')
99
+ return false;
100
+ const content = msg.content;
101
+ if (typeof content === 'string')
102
+ return content.trim().length > 0;
103
+ if (Array.isArray(content)) {
104
+ // Accept if any block is a non-empty text block (skip pure tool_result arrays)
105
+ return content.some((b) => b !== null &&
106
+ typeof b === 'object' &&
107
+ b.type === 'text' &&
108
+ typeof b.text === 'string' &&
109
+ b.text.trim().length > 0);
110
+ }
111
+ return false;
112
+ });
85
113
  if (userEntries.length === 0)
86
114
  return null;
87
115
  const assistantEntries = entries.filter((e) => e.type === 'assistant');
@@ -94,8 +122,8 @@ export function parseJSONLSession(raw) {
94
122
  const projectName = projectPath
95
123
  ? basename(dirname(projectPath + '/x')) || basename(projectPath)
96
124
  : null;
97
- const firstPromptFull = String(firstEntry.message.content ?? '');
98
- const lastPromptFull = String(lastEntry.message.content ?? '');
125
+ const firstPromptFull = extractUserText(firstEntry.message.content);
126
+ const lastPromptFull = extractUserText(lastEntry.message.content);
99
127
  let model = null;
100
128
  if (assistantEntries.length > 0) {
101
129
  const msg = assistantEntries[0].message;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobileclaude-agent",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Desktop agent for MobileIDE — controls Claude Code from your iPhone via Supabase",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",