xiaotime 0.2.1 → 0.4.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/__tests__/approval_menu.test.d.ts +15 -0
- package/dist/__tests__/approval_menu.test.d.ts.map +1 -0
- package/dist/__tests__/approval_menu.test.js +107 -0
- package/dist/__tests__/approval_menu.test.js.map +1 -0
- package/dist/__tests__/legacy_compat.test.d.ts +2 -0
- package/dist/__tests__/legacy_compat.test.d.ts.map +1 -0
- package/dist/__tests__/legacy_compat.test.js +36 -0
- package/dist/__tests__/legacy_compat.test.js.map +1 -0
- package/dist/__tests__/server_tool_render.test.d.ts +17 -0
- package/dist/__tests__/server_tool_render.test.d.ts.map +1 -0
- package/dist/__tests__/server_tool_render.test.js +74 -0
- package/dist/__tests__/server_tool_render.test.js.map +1 -0
- package/dist/__tests__/settings.test.d.ts +16 -0
- package/dist/__tests__/settings.test.d.ts.map +1 -0
- package/dist/__tests__/settings.test.js +289 -0
- package/dist/__tests__/settings.test.js.map +1 -0
- package/dist/__tests__/tool_result_client.test.d.ts +20 -0
- package/dist/__tests__/tool_result_client.test.d.ts.map +1 -0
- package/dist/__tests__/tool_result_client.test.js +142 -0
- package/dist/__tests__/tool_result_client.test.js.map +1 -0
- package/dist/__tests__/tools.test.d.ts +17 -0
- package/dist/__tests__/tools.test.d.ts.map +1 -0
- package/dist/__tests__/tools.test.js +381 -0
- package/dist/__tests__/tools.test.js.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -1
- package/dist/config.js.map +1 -1
- package/dist/display.d.ts +19 -0
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +23 -0
- package/dist/display.js.map +1 -1
- package/dist/settings.d.ts +109 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +332 -0
- package/dist/settings.js.map +1 -0
- package/dist/tool_result_client.d.ts +72 -0
- package/dist/tool_result_client.d.ts.map +1 -0
- package/dist/tool_result_client.js +123 -0
- package/dist/tool_result_client.js.map +1 -0
- package/dist/tools.d.ts +11 -3
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +96 -33
- package/dist/tools.js.map +1 -1
- package/dist/ui_state.d.ts +134 -0
- package/dist/ui_state.d.ts.map +1 -0
- package/dist/ui_state.js +460 -0
- package/dist/ui_state.js.map +1 -0
- package/dist/ws.d.ts +15 -0
- package/dist/ws.d.ts.map +1 -1
- package/dist/ws.js +180 -75
- package/dist/ws.js.map +1 -1
- package/package.json +6 -3
package/dist/ws.js
CHANGED
|
@@ -1,67 +1,129 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* WebSocket connection and main message loop.
|
|
4
|
+
*
|
|
5
|
+
* SPRINT-CLI-STATE-MACHINE-1 (#6163 / closes #6127) — drives the
|
|
6
|
+
* SessionUI state machine from incoming WS events so the user gets
|
|
7
|
+
* a spinner while the model is generating / a tool is running, and
|
|
8
|
+
* approval prompts don't race the main rl on keystrokes.
|
|
9
|
+
*
|
|
10
|
+
* SPRINT-TERMINAL-CLIENT-OWNED-DISPATCH-1 (#6565) PR3 — tool_result
|
|
11
|
+
* delivery moved off the WebSocket: results POST to
|
|
12
|
+
* /terminal/sessions/{id}/tool_results via the new REST endpoint.
|
|
13
|
+
* The WS now carries only inbound (server→client) `tool_call`
|
|
14
|
+
* events as informational triggers. Tool calls drain serially
|
|
15
|
+
* through a local queue so concurrent menus can't corrupt
|
|
16
|
+
* SessionUI state — the pre-#6565 `inFlightToolUseId` reject-on-
|
|
17
|
+
* overlap guard is gone (it caused the wedge observed in the
|
|
18
|
+
* #6509 PR1 canary).
|
|
4
19
|
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
20
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
21
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
22
|
};
|
|
41
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
24
|
exports.runSession = runSession;
|
|
43
25
|
const ws_1 = __importDefault(require("ws"));
|
|
44
|
-
const readline = __importStar(require("readline"));
|
|
45
26
|
const config_js_1 = require("./config.js");
|
|
46
27
|
const auth_js_1 = require("./auth.js");
|
|
47
28
|
const tools_js_1 = require("./tools.js");
|
|
29
|
+
const tool_result_client_js_1 = require("./tool_result_client.js");
|
|
48
30
|
const display_js_1 = require("./display.js");
|
|
31
|
+
const ui_state_js_1 = require("./ui_state.js");
|
|
32
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
49
33
|
async function runSession(sessionId) {
|
|
50
34
|
const wsUrl = `${config_js_1.WS_URL}/terminal/sessions/${sessionId}/stream`;
|
|
51
35
|
return new Promise((resolve, reject) => {
|
|
52
36
|
const ws = new ws_1.default(wsUrl);
|
|
53
37
|
let connected = false;
|
|
54
|
-
|
|
55
|
-
let
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
38
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
39
|
+
let firstTokenThisTurn = true;
|
|
40
|
+
// #6565 PR3 — serial drain queue. The server may emit multiple
|
|
41
|
+
// tool_call events back-to-back (one per tool_use block in the
|
|
42
|
+
// model's batch). Executing concurrently would corrupt
|
|
43
|
+
// SessionUI state (two menus rendering on top of each other);
|
|
44
|
+
// queueing + draining one-at-a-time gives clean approval flows
|
|
45
|
+
// while still parallelizable across the server (server emits
|
|
46
|
+
// all N then awaits the resume signal — order of completion
|
|
47
|
+
// doesn't matter to the server, only that all N land via POST).
|
|
48
|
+
const toolCallQueue = [];
|
|
49
|
+
let drainRunning = false;
|
|
50
|
+
async function drainToolCallQueue() {
|
|
51
|
+
if (drainRunning)
|
|
52
|
+
return;
|
|
53
|
+
drainRunning = true;
|
|
54
|
+
try {
|
|
55
|
+
while (toolCallQueue.length > 0) {
|
|
56
|
+
const tc = toolCallQueue.shift();
|
|
57
|
+
ui.setState("running_tool");
|
|
58
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
59
|
+
tool_use_id: tc.tool_use_id,
|
|
60
|
+
name: tc.name,
|
|
61
|
+
input: tc.input,
|
|
62
|
+
}, ui);
|
|
63
|
+
let postFailed = false;
|
|
64
|
+
try {
|
|
65
|
+
await (0, tool_result_client_js_1.postToolResults)(sessionId, [
|
|
66
|
+
{
|
|
67
|
+
tool_use_id: result.tool_use_id,
|
|
68
|
+
content: result.content,
|
|
69
|
+
is_error: result.is_error,
|
|
70
|
+
},
|
|
71
|
+
]);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
// POST exhausted retries (transient 5xx / network) OR
|
|
75
|
+
// 4xx (durable rejection, e.g. unknown_tool_use_id from
|
|
76
|
+
// a server restart that lost the pending row). Tool
|
|
77
|
+
// result is lost from the server's perspective; the
|
|
78
|
+
// pending row stays as `pending` until PR5's expiry
|
|
79
|
+
// sweep. PR4's WS-reconnect replay path will re-emit
|
|
80
|
+
// the tool_call on next session connect for a retry.
|
|
81
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
82
|
+
process.stderr.write(chalk_1.default.yellow(` (tool_result POST failed: ${msg})\n`));
|
|
83
|
+
postFailed = true;
|
|
84
|
+
}
|
|
85
|
+
// #6573 CR-r1: on POST failure, the server's resume signal
|
|
86
|
+
// won't fire (server never learns this tool completed).
|
|
87
|
+
// The CLI would sit silently with no further events from
|
|
88
|
+
// the server, looking wedged. Bounce the user back to the
|
|
89
|
+
// prompt with a clear cue + a fresh idle state so they can
|
|
90
|
+
// type `xiaotime dev --session <id>` (resume) or pick a
|
|
91
|
+
// different recovery action. The unfinished pending rows
|
|
92
|
+
// stay durable in the DB for PR4's reconnect replay.
|
|
93
|
+
if (postFailed) {
|
|
94
|
+
ui.setState("idle");
|
|
95
|
+
process.stderr.write(chalk_1.default.yellow(" (session paused — POST failed; reconnect with " +
|
|
96
|
+
"`xiaotime dev --session " +
|
|
97
|
+
sessionId +
|
|
98
|
+
"` to retry pending tool calls)\n"));
|
|
99
|
+
// #6573 CR-r1: a POST failure means the server never got
|
|
100
|
+
// the resume signal — its dispatch state is inconsistent.
|
|
101
|
+
// Close the socket rather than returning to the prompt:
|
|
102
|
+
// the clean recovery is a fresh session, not a retry on a
|
|
103
|
+
// half-dispatched one. ws.close() fires the on("close")
|
|
104
|
+
// handler (rl teardown + resolve), so the user genuinely
|
|
105
|
+
// re-runs `xiaotime dev --session <id>`. Pending rows stay
|
|
106
|
+
// durable in the DB for PR4's reconnect replay; draining
|
|
107
|
+
// stops here because the loop is abandoned with the session.
|
|
108
|
+
ws.close();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Don't transition state back to "generating" here — the
|
|
112
|
+
// model may already be streaming on the next turn (the
|
|
113
|
+
// server's resume happens as soon as all batch results
|
|
114
|
+
// land via POST). The next text_delta clears the spinner
|
|
115
|
+
// via onFirstToken.
|
|
116
|
+
firstTokenThisTurn = true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
drainRunning = false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
62
123
|
ws.on("open", () => {
|
|
63
|
-
// Auth
|
|
64
|
-
|
|
124
|
+
// Auth — #6565 PR5: `version` lets the server reject pre-0.4.0
|
|
125
|
+
// clients that would wedge on the old WS tool_result path.
|
|
126
|
+
ws.send(JSON.stringify({ type: "auth", token: (0, auth_js_1.getToken)(), version: config_js_1.CLI_VERSION }));
|
|
65
127
|
// Connect with cwd
|
|
66
128
|
ws.send(JSON.stringify({ type: "connect", cwd: process.cwd() }));
|
|
67
129
|
});
|
|
@@ -72,51 +134,85 @@ async function runSession(sessionId) {
|
|
|
72
134
|
connected = true;
|
|
73
135
|
(0, tools_js_1.setSessionCwd)(process.cwd());
|
|
74
136
|
(0, display_js_1.printWelcome)(msg.session_id, msg.session_name, msg.resumed, msg.message_count);
|
|
75
|
-
|
|
137
|
+
// #6565 PR4b — if the server is replaying tool calls left
|
|
138
|
+
// pending by a prior session (restart / crash mid-approval),
|
|
139
|
+
// defer the prompt loop. The server emits those `tool_call`
|
|
140
|
+
// events next; they drain through the queue, the CLI POSTs
|
|
141
|
+
// results, the server resumes the turn, and that turn's
|
|
142
|
+
// `message_stop` starts the prompt loop. Starting it here
|
|
143
|
+
// would race the replayed approval menus against the prompt.
|
|
144
|
+
if ((msg.pending_tool_calls ?? 0) > 0) {
|
|
145
|
+
process.stderr.write(chalk_1.default.cyan(` (resuming ${msg.pending_tool_calls} pending tool ` +
|
|
146
|
+
`call(s) from a prior session)\n`));
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
startUserPromptLoop();
|
|
150
|
+
}
|
|
76
151
|
break;
|
|
77
152
|
case "text_delta":
|
|
153
|
+
if (firstTokenThisTurn) {
|
|
154
|
+
ui.onFirstToken();
|
|
155
|
+
firstTokenThisTurn = false;
|
|
156
|
+
}
|
|
78
157
|
(0, display_js_1.printTextDelta)(msg.content);
|
|
79
158
|
break;
|
|
80
|
-
case "tool_call":
|
|
81
|
-
|
|
82
|
-
|
|
159
|
+
case "tool_call": {
|
|
160
|
+
// #6565 PR3 — informational event now. Server has already
|
|
161
|
+
// persisted the pending row + is awaiting our POST to
|
|
162
|
+
// /terminal/sessions/{id}/tool_results. Queue the call
|
|
163
|
+
// for serial draining (one menu rendering at a time);
|
|
164
|
+
// POST the result after each drain iteration. The
|
|
165
|
+
// pre-#6565 inFlightToolUseId reject-on-overlap guard is
|
|
166
|
+
// gone — concurrent dispatch is now safe by construction
|
|
167
|
+
// via the drain serialization.
|
|
168
|
+
toolCallQueue.push({
|
|
83
169
|
tool_use_id: msg.tool_use_id,
|
|
84
170
|
name: msg.name,
|
|
85
171
|
input: msg.input,
|
|
86
|
-
}).then((result) => {
|
|
87
|
-
waitingForToolResult = false;
|
|
88
|
-
ws.send(JSON.stringify({
|
|
89
|
-
type: "tool_result",
|
|
90
|
-
tool_use_id: result.tool_use_id,
|
|
91
|
-
content: result.content,
|
|
92
|
-
is_error: result.is_error,
|
|
93
|
-
}));
|
|
94
172
|
});
|
|
173
|
+
// Fire-and-forget — drainToolCallQueue is idempotent on
|
|
174
|
+
// concurrent invocation (the drainRunning guard inside).
|
|
175
|
+
drainToolCallQueue();
|
|
95
176
|
break;
|
|
177
|
+
}
|
|
96
178
|
case "message_stop":
|
|
179
|
+
ui.setState("idle");
|
|
97
180
|
(0, display_js_1.printTurnEnd)(msg.cost_usd || 0);
|
|
98
|
-
|
|
181
|
+
startUserPromptLoop();
|
|
99
182
|
break;
|
|
100
183
|
case "error":
|
|
184
|
+
ui.setState("idle");
|
|
101
185
|
(0, display_js_1.printError)(msg.message);
|
|
102
186
|
if (!connected) {
|
|
103
187
|
ws.close();
|
|
104
188
|
reject(new Error(msg.message));
|
|
105
189
|
}
|
|
106
190
|
else {
|
|
107
|
-
|
|
191
|
+
startUserPromptLoop();
|
|
108
192
|
}
|
|
109
193
|
break;
|
|
194
|
+
case "server_tool_call":
|
|
195
|
+
// #6509 PR3 — visibility line for the 15 server-side tools
|
|
196
|
+
// in terminal_orchestrator/main.py SERVER_TOOLS. Clear the
|
|
197
|
+
// spinner first so the [server:<name>] line doesn't get
|
|
198
|
+
// overwritten by the spinner's next frame, and pin
|
|
199
|
+
// firstTokenThisTurn=false so a subsequent text_delta
|
|
200
|
+
// doesn't double-clear (onFirstToken is idempotent but
|
|
201
|
+
// the bookkeeping flag should reflect reality).
|
|
202
|
+
ui.onFirstToken();
|
|
203
|
+
firstTokenThisTurn = false;
|
|
204
|
+
(0, display_js_1.printServerToolCall)(msg.name, msg.input_summary || "");
|
|
205
|
+
break;
|
|
110
206
|
case "pong":
|
|
111
207
|
break;
|
|
112
208
|
}
|
|
113
209
|
});
|
|
114
210
|
ws.on("close", () => {
|
|
115
|
-
|
|
211
|
+
ui.getRl().close();
|
|
116
212
|
resolve();
|
|
117
213
|
});
|
|
118
214
|
ws.on("error", (err) => {
|
|
119
|
-
|
|
215
|
+
ui.getRl().close();
|
|
120
216
|
reject(err);
|
|
121
217
|
});
|
|
122
218
|
// ── Ping keepalive ────────────────────────────────────────────
|
|
@@ -126,24 +222,33 @@ async function runSession(sessionId) {
|
|
|
126
222
|
}
|
|
127
223
|
}, 30000);
|
|
128
224
|
ws.on("close", () => clearInterval(pingInterval));
|
|
129
|
-
// ── User input
|
|
130
|
-
function
|
|
131
|
-
if (!connected
|
|
225
|
+
// ── User input loop ────────────────────────────────────────────
|
|
226
|
+
async function startUserPromptLoop() {
|
|
227
|
+
if (!connected)
|
|
132
228
|
return;
|
|
133
229
|
(0, display_js_1.printPrompt)();
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
230
|
+
const text = await ui.promptLine();
|
|
231
|
+
if (!text) {
|
|
232
|
+
startUserPromptLoop();
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (ws.readyState === ws_1.default.OPEN) {
|
|
236
|
+
// Mark generating BEFORE sending the message — gives the user
|
|
237
|
+
// an immediate spinner while we wait for the first token. The
|
|
238
|
+
// server may take 1-3s before the first text_delta lands;
|
|
239
|
+
// pre-#6163 this was a silent wait that looked like a hang.
|
|
240
|
+
ui.setState("generating");
|
|
241
|
+
firstTokenThisTurn = true;
|
|
242
|
+
ws.send(JSON.stringify({ type: "message", content: text }));
|
|
243
|
+
}
|
|
144
244
|
}
|
|
145
|
-
// Ctrl+C
|
|
146
|
-
rl
|
|
245
|
+
// Ctrl+C — registered via onRlClose (not getRl().on) so the listener
|
|
246
|
+
// survives the rl close-and-recreate cycle in promptApprovalMenu
|
|
247
|
+
// (SPRINT-CLI-APPROVAL-MENU-1 / #6509 PR1). The intra-menu close is
|
|
248
|
+
// suppressed inside promptApprovalMenu via removeAllListeners before
|
|
249
|
+
// calling rl.close(), so this listener only fires for genuine
|
|
250
|
+
// user-initiated Ctrl+C at the main prompt.
|
|
251
|
+
ui.onRlClose(() => {
|
|
147
252
|
console.log("\nSession paused. Resume with: xiaotime dev --session " + sessionId);
|
|
148
253
|
ws.close();
|
|
149
254
|
});
|
package/dist/ws.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws.js","sourceRoot":"","sources":["../src/ws.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"ws.js","sourceRoot":"","sources":["../src/ws.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xiaotime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Xiaotime Developer — persistent-memory AI coding assistant",
|
|
5
5
|
"bin": {
|
|
6
6
|
"xiaotime": "./dist/index.js"
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"dev": "ts-node src/index.ts",
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"test:watch": "vitest",
|
|
15
17
|
"prepublishOnly": "npm run build"
|
|
16
18
|
},
|
|
17
19
|
"dependencies": {
|
|
@@ -23,9 +25,10 @@
|
|
|
23
25
|
"@types/ws": "^8.5.12",
|
|
24
26
|
"@types/node": "^22.0.0",
|
|
25
27
|
"typescript": "^5.7.0",
|
|
26
|
-
"ts-node": "^10.9.2"
|
|
28
|
+
"ts-node": "^10.9.2",
|
|
29
|
+
"vitest": "^4.1.7"
|
|
27
30
|
},
|
|
28
31
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
32
|
+
"node": ">=20.19.0"
|
|
30
33
|
}
|
|
31
34
|
}
|