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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST POST client tests.
|
|
3
|
+
*
|
|
4
|
+
* SPRINT-TERMINAL-CLIENT-OWNED-DISPATCH-1 (#6565) PR3.
|
|
5
|
+
*
|
|
6
|
+
* Verifies the contract between the CLI's drain queue (in ws.ts)
|
|
7
|
+
* and the server's POST /tool_results endpoint (added in PR1,
|
|
8
|
+
* consumed by PR2's dispatch refactor):
|
|
9
|
+
*
|
|
10
|
+
* - Happy path: 200 OK returns parsed body (completed,
|
|
11
|
+
* all_completed, resume_signaled).
|
|
12
|
+
* - Retry policy: 5xx + network errors retry with exponential
|
|
13
|
+
* backoff (100ms → 200ms → 400ms, 3 attempts total).
|
|
14
|
+
* - 4xx is durable — throws immediately, no retry.
|
|
15
|
+
* - Auth header (x-api-key with the cli_token) on every attempt.
|
|
16
|
+
* - Request body shape matches the server's PostToolResultsRequest
|
|
17
|
+
* Pydantic model.
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=tool_result_client.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool_result_client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/tool_result_client.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* REST POST client tests.
|
|
4
|
+
*
|
|
5
|
+
* SPRINT-TERMINAL-CLIENT-OWNED-DISPATCH-1 (#6565) PR3.
|
|
6
|
+
*
|
|
7
|
+
* Verifies the contract between the CLI's drain queue (in ws.ts)
|
|
8
|
+
* and the server's POST /tool_results endpoint (added in PR1,
|
|
9
|
+
* consumed by PR2's dispatch refactor):
|
|
10
|
+
*
|
|
11
|
+
* - Happy path: 200 OK returns parsed body (completed,
|
|
12
|
+
* all_completed, resume_signaled).
|
|
13
|
+
* - Retry policy: 5xx + network errors retry with exponential
|
|
14
|
+
* backoff (100ms → 200ms → 400ms, 3 attempts total).
|
|
15
|
+
* - 4xx is durable — throws immediately, no retry.
|
|
16
|
+
* - Auth header (x-api-key with the cli_token) on every attempt.
|
|
17
|
+
* - Request body shape matches the server's PostToolResultsRequest
|
|
18
|
+
* Pydantic model.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
const vitest_1 = require("vitest");
|
|
22
|
+
const tool_result_client_js_1 = require("../tool_result_client.js");
|
|
23
|
+
// Mock the auth module so we don't read a real token from
|
|
24
|
+
// ~/.xiaotime/cli_token.json during tests.
|
|
25
|
+
vitest_1.vi.mock("../auth.js", () => ({
|
|
26
|
+
getToken: () => "fake-cli-token-for-tests",
|
|
27
|
+
}));
|
|
28
|
+
// Mock the config so the URL is deterministic.
|
|
29
|
+
vitest_1.vi.mock("../config.js", () => ({
|
|
30
|
+
ORCHESTRATOR_URL: "https://terminal.xiaotime.test",
|
|
31
|
+
}));
|
|
32
|
+
let fetchMock;
|
|
33
|
+
let origFetch;
|
|
34
|
+
(0, vitest_1.beforeEach)(() => {
|
|
35
|
+
fetchMock = vitest_1.vi.fn();
|
|
36
|
+
origFetch = globalThis.fetch;
|
|
37
|
+
globalThis.fetch = fetchMock;
|
|
38
|
+
});
|
|
39
|
+
(0, vitest_1.afterEach)(() => {
|
|
40
|
+
globalThis.fetch = origFetch;
|
|
41
|
+
vitest_1.vi.restoreAllMocks();
|
|
42
|
+
});
|
|
43
|
+
function _okResponse(body) {
|
|
44
|
+
return new Response(JSON.stringify(body), {
|
|
45
|
+
status: 200,
|
|
46
|
+
headers: { "content-type": "application/json" },
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function _errorResponse(status, body) {
|
|
50
|
+
return new Response(body, { status });
|
|
51
|
+
}
|
|
52
|
+
(0, vitest_1.describe)("postToolResults happy path", () => {
|
|
53
|
+
(0, vitest_1.test)("posts to correct URL with auth header + JSON body", async () => {
|
|
54
|
+
fetchMock.mockResolvedValue(_okResponse({ completed: ["toolu_a"], all_completed: true, resume_signaled: true }));
|
|
55
|
+
const result = await (0, tool_result_client_js_1.postToolResults)("session-abc", [
|
|
56
|
+
{ tool_use_id: "toolu_a", content: "ok", is_error: false },
|
|
57
|
+
]);
|
|
58
|
+
(0, vitest_1.expect)(result).toEqual({
|
|
59
|
+
completed: ["toolu_a"],
|
|
60
|
+
all_completed: true,
|
|
61
|
+
resume_signaled: true,
|
|
62
|
+
});
|
|
63
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(1);
|
|
64
|
+
const [url, init] = fetchMock.mock.calls[0];
|
|
65
|
+
(0, vitest_1.expect)(url).toBe("https://terminal.xiaotime.test/terminal/sessions/session-abc/tool_results");
|
|
66
|
+
(0, vitest_1.expect)(init.method).toBe("POST");
|
|
67
|
+
(0, vitest_1.expect)(init.headers["x-api-key"]).toBe("fake-cli-token-for-tests");
|
|
68
|
+
(0, vitest_1.expect)(init.headers["Content-Type"]).toBe("application/json");
|
|
69
|
+
const body = JSON.parse(init.body);
|
|
70
|
+
(0, vitest_1.expect)(body).toEqual({
|
|
71
|
+
results: [{ tool_use_id: "toolu_a", content: "ok", is_error: false }],
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
(0, vitest_1.test)("supports multi-result batches", async () => {
|
|
75
|
+
fetchMock.mockResolvedValue(_okResponse({
|
|
76
|
+
completed: ["toolu_a", "toolu_b"],
|
|
77
|
+
all_completed: false,
|
|
78
|
+
resume_signaled: false,
|
|
79
|
+
}));
|
|
80
|
+
await (0, tool_result_client_js_1.postToolResults)("sess", [
|
|
81
|
+
{ tool_use_id: "toolu_a", content: "1", is_error: false },
|
|
82
|
+
{ tool_use_id: "toolu_b", content: "2", is_error: true },
|
|
83
|
+
]);
|
|
84
|
+
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
85
|
+
(0, vitest_1.expect)(body.results).toHaveLength(2);
|
|
86
|
+
(0, vitest_1.expect)(body.results[1].is_error).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
(0, vitest_1.describe)("postToolResults retry behavior", () => {
|
|
90
|
+
(0, vitest_1.test)("4xx error throws immediately without retrying", async () => {
|
|
91
|
+
// Use mockImplementation (fresh Response per call) instead of
|
|
92
|
+
// mockResolvedValue (single Response instance) — the latter's
|
|
93
|
+
// body stream gets consumed on the first .text() read and
|
|
94
|
+
// subsequent reads fail with "Body is unusable".
|
|
95
|
+
fetchMock.mockImplementation(() => Promise.resolve(_errorResponse(400, "unknown_tool_use_id")));
|
|
96
|
+
await (0, vitest_1.expect)((0, tool_result_client_js_1.postToolResults)("sess", [
|
|
97
|
+
{ tool_use_id: "toolu_a", content: "x", is_error: false },
|
|
98
|
+
])).rejects.toThrow(/rejected \(400\)/);
|
|
99
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(1);
|
|
100
|
+
});
|
|
101
|
+
(0, vitest_1.test)("4xx error includes server body in the thrown message", async () => {
|
|
102
|
+
fetchMock.mockImplementation(() => Promise.resolve(_errorResponse(400, '{"code":"unknown_tool_use_id","unknown":["toolu_x"]}')));
|
|
103
|
+
await (0, vitest_1.expect)((0, tool_result_client_js_1.postToolResults)("sess", [
|
|
104
|
+
{ tool_use_id: "toolu_x", content: "x", is_error: false },
|
|
105
|
+
])).rejects.toThrow(/unknown_tool_use_id/);
|
|
106
|
+
});
|
|
107
|
+
(0, vitest_1.test)("5xx error retries up to 3 attempts then throws", async () => {
|
|
108
|
+
fetchMock.mockImplementation(() => Promise.resolve(_errorResponse(503, "service unavailable")));
|
|
109
|
+
await (0, vitest_1.expect)((0, tool_result_client_js_1.postToolResults)("sess", [
|
|
110
|
+
{ tool_use_id: "toolu_a", content: "x", is_error: false },
|
|
111
|
+
])).rejects.toThrow(/503/);
|
|
112
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(3);
|
|
113
|
+
});
|
|
114
|
+
(0, vitest_1.test)("5xx then success on retry → returns success", async () => {
|
|
115
|
+
fetchMock
|
|
116
|
+
.mockResolvedValueOnce(_errorResponse(500, "internal"))
|
|
117
|
+
.mockResolvedValueOnce(_okResponse({ completed: ["a"], all_completed: true, resume_signaled: true }));
|
|
118
|
+
const result = await (0, tool_result_client_js_1.postToolResults)("sess", [
|
|
119
|
+
{ tool_use_id: "a", content: "x", is_error: false },
|
|
120
|
+
]);
|
|
121
|
+
(0, vitest_1.expect)(result.all_completed).toBe(true);
|
|
122
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(2);
|
|
123
|
+
});
|
|
124
|
+
(0, vitest_1.test)("network error retries up to 3 attempts then throws", async () => {
|
|
125
|
+
fetchMock.mockRejectedValue(new Error("ECONNRESET"));
|
|
126
|
+
await (0, vitest_1.expect)((0, tool_result_client_js_1.postToolResults)("sess", [
|
|
127
|
+
{ tool_use_id: "a", content: "x", is_error: false },
|
|
128
|
+
])).rejects.toThrow(/ECONNRESET/);
|
|
129
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(3);
|
|
130
|
+
});
|
|
131
|
+
(0, vitest_1.test)("network error then success on retry → returns success", async () => {
|
|
132
|
+
fetchMock
|
|
133
|
+
.mockRejectedValueOnce(new Error("ECONNRESET"))
|
|
134
|
+
.mockResolvedValueOnce(_okResponse({ completed: ["a"], all_completed: false, resume_signaled: false }));
|
|
135
|
+
const result = await (0, tool_result_client_js_1.postToolResults)("sess", [
|
|
136
|
+
{ tool_use_id: "a", content: "x", is_error: false },
|
|
137
|
+
]);
|
|
138
|
+
(0, vitest_1.expect)(result.completed).toEqual(["a"]);
|
|
139
|
+
(0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(2);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=tool_result_client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool_result_client.test.js","sourceRoot":"","sources":["../../src/__tests__/tool_result_client.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-execution surface tests.
|
|
3
|
+
*
|
|
4
|
+
* SPRINT-CLI-APPROVAL-MENU-1 (#6509):
|
|
5
|
+
* - PR1: ISC-6509-006 (read-only tools never prompt)
|
|
6
|
+
* + write_file approval integration (#6532 CR-r1)
|
|
7
|
+
* - PR2: ISC-6509-004 (allowlist match skips promptApprovalMenu +
|
|
8
|
+
* auto-approved suffix)
|
|
9
|
+
* + option-2 selection writes the derived pattern to
|
|
10
|
+
* ~/.xiaotime/settings.json
|
|
11
|
+
*
|
|
12
|
+
* Tests redirect XIAOTIME_SETTINGS_PATH to a per-test tmpdir so
|
|
13
|
+
* the user's real ~/.xiaotime/settings.json is never read or
|
|
14
|
+
* written.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=tools.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/tools.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tool-execution surface tests.
|
|
4
|
+
*
|
|
5
|
+
* SPRINT-CLI-APPROVAL-MENU-1 (#6509):
|
|
6
|
+
* - PR1: ISC-6509-006 (read-only tools never prompt)
|
|
7
|
+
* + write_file approval integration (#6532 CR-r1)
|
|
8
|
+
* - PR2: ISC-6509-004 (allowlist match skips promptApprovalMenu +
|
|
9
|
+
* auto-approved suffix)
|
|
10
|
+
* + option-2 selection writes the derived pattern to
|
|
11
|
+
* ~/.xiaotime/settings.json
|
|
12
|
+
*
|
|
13
|
+
* Tests redirect XIAOTIME_SETTINGS_PATH to a per-test tmpdir so
|
|
14
|
+
* the user's real ~/.xiaotime/settings.json is never read or
|
|
15
|
+
* written.
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
const vitest_1 = require("vitest");
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const os = __importStar(require("os"));
|
|
55
|
+
const tools_js_1 = require("../tools.js");
|
|
56
|
+
const ui_state_js_1 = require("../ui_state.js");
|
|
57
|
+
const settings_js_1 = require("../settings.js");
|
|
58
|
+
let tmpDir;
|
|
59
|
+
let settingsPath;
|
|
60
|
+
let origSettingsEnv;
|
|
61
|
+
(0, vitest_1.beforeEach)(() => {
|
|
62
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "xiaotime-tools-test-"));
|
|
63
|
+
(0, tools_js_1.setSessionCwd)(tmpDir);
|
|
64
|
+
// Redirect allowlist to a tmpfile so we never read or write the
|
|
65
|
+
// user's real ~/.xiaotime/settings.json.
|
|
66
|
+
settingsPath = path.join(tmpDir, ".xiaotime-test-settings.json");
|
|
67
|
+
origSettingsEnv = process.env.XIAOTIME_SETTINGS_PATH;
|
|
68
|
+
process.env.XIAOTIME_SETTINGS_PATH = settingsPath;
|
|
69
|
+
vitest_1.vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
|
70
|
+
vitest_1.vi.spyOn(console, "log").mockImplementation(() => { });
|
|
71
|
+
vitest_1.vi.spyOn(console, "error").mockImplementation(() => { });
|
|
72
|
+
});
|
|
73
|
+
(0, vitest_1.afterEach)(() => {
|
|
74
|
+
if (origSettingsEnv === undefined) {
|
|
75
|
+
delete process.env.XIAOTIME_SETTINGS_PATH;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
process.env.XIAOTIME_SETTINGS_PATH = origSettingsEnv;
|
|
79
|
+
}
|
|
80
|
+
vitest_1.vi.restoreAllMocks();
|
|
81
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
82
|
+
});
|
|
83
|
+
(0, vitest_1.describe)("read-only tools never prompt (ISC-6509-006)", () => {
|
|
84
|
+
(0, vitest_1.test)("read_file does not call promptApprovalMenu", async () => {
|
|
85
|
+
const filePath = path.join(tmpDir, "sample.txt");
|
|
86
|
+
fs.writeFileSync(filePath, "line one\nline two\nline three\n");
|
|
87
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
88
|
+
const spy = vitest_1.vi.spyOn(ui, "promptApprovalMenu");
|
|
89
|
+
try {
|
|
90
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
91
|
+
tool_use_id: "test-1",
|
|
92
|
+
name: "read_file",
|
|
93
|
+
input: { path: filePath },
|
|
94
|
+
}, ui);
|
|
95
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
96
|
+
(0, vitest_1.expect)(result.content).toContain("line one");
|
|
97
|
+
(0, vitest_1.expect)(spy).not.toHaveBeenCalled();
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
ui.getRl().close();
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
(0, vitest_1.test)("list_directory does not call promptApprovalMenu", async () => {
|
|
104
|
+
fs.writeFileSync(path.join(tmpDir, "a.txt"), "a");
|
|
105
|
+
fs.writeFileSync(path.join(tmpDir, "b.txt"), "b");
|
|
106
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
107
|
+
const spy = vitest_1.vi.spyOn(ui, "promptApprovalMenu");
|
|
108
|
+
try {
|
|
109
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
110
|
+
tool_use_id: "test-2",
|
|
111
|
+
name: "list_directory",
|
|
112
|
+
input: { path: tmpDir },
|
|
113
|
+
}, ui);
|
|
114
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
115
|
+
(0, vitest_1.expect)(result.content).toContain("a.txt");
|
|
116
|
+
(0, vitest_1.expect)(result.content).toContain("b.txt");
|
|
117
|
+
(0, vitest_1.expect)(spy).not.toHaveBeenCalled();
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
ui.getRl().close();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
(0, vitest_1.describe)("write_file approval integration (#6532 CR-r1)", () => {
|
|
125
|
+
(0, vitest_1.test)("rejection returns 'Rejected by user: <reason>' and does NOT write", async () => {
|
|
126
|
+
const target = path.join(tmpDir, "should-not-exist.txt");
|
|
127
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
128
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
129
|
+
approved: false,
|
|
130
|
+
rejectReason: "I don't want this written",
|
|
131
|
+
});
|
|
132
|
+
try {
|
|
133
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
134
|
+
tool_use_id: "t-reject-1",
|
|
135
|
+
name: "write_file",
|
|
136
|
+
input: { path: target, content: "should never land" },
|
|
137
|
+
}, ui);
|
|
138
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
139
|
+
(0, vitest_1.expect)(result.content).toBe("Rejected by user: I don't want this written");
|
|
140
|
+
(0, vitest_1.expect)(fs.existsSync(target)).toBe(false);
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
ui.getRl().close();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
(0, vitest_1.test)("rejection with empty reason returns 'Rejected by user.'", async () => {
|
|
147
|
+
const target = path.join(tmpDir, "empty-reason.txt");
|
|
148
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
149
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
150
|
+
approved: false,
|
|
151
|
+
rejectReason: "",
|
|
152
|
+
});
|
|
153
|
+
try {
|
|
154
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
155
|
+
tool_use_id: "t-reject-2",
|
|
156
|
+
name: "write_file",
|
|
157
|
+
input: { path: target, content: "x" },
|
|
158
|
+
}, ui);
|
|
159
|
+
(0, vitest_1.expect)(result.content).toBe("Rejected by user.");
|
|
160
|
+
(0, vitest_1.expect)(fs.existsSync(target)).toBe(false);
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
ui.getRl().close();
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
(0, vitest_1.test)("approval writes the file and returns 'File written: <path>'", async () => {
|
|
167
|
+
const target = path.join(tmpDir, "approved.txt");
|
|
168
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
169
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
170
|
+
approved: true,
|
|
171
|
+
allowlistRequested: false,
|
|
172
|
+
});
|
|
173
|
+
try {
|
|
174
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
175
|
+
tool_use_id: "t-approve-1",
|
|
176
|
+
name: "write_file",
|
|
177
|
+
input: { path: target, content: "content here" },
|
|
178
|
+
}, ui);
|
|
179
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
180
|
+
(0, vitest_1.expect)(result.content).toBe(`File written: ${target}`);
|
|
181
|
+
(0, vitest_1.expect)(fs.readFileSync(target, "utf-8")).toBe("content here");
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
ui.getRl().close();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
(0, vitest_1.describe)("allowlist persistence on option-2 selection (ISC-6509-003)", () => {
|
|
189
|
+
(0, vitest_1.test)("write_file: allowlistRequested=true persists derived pattern", async () => {
|
|
190
|
+
const target = path.join(tmpDir, "nested", "deep", "approved.txt");
|
|
191
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
192
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
193
|
+
approved: true,
|
|
194
|
+
allowlistRequested: true,
|
|
195
|
+
});
|
|
196
|
+
try {
|
|
197
|
+
await (0, tools_js_1.executeTool)({
|
|
198
|
+
tool_use_id: "t-allowlist-1",
|
|
199
|
+
name: "write_file",
|
|
200
|
+
input: { path: target, content: "x" },
|
|
201
|
+
}, ui);
|
|
202
|
+
const loaded = (0, settings_js_1.loadAllowlist)();
|
|
203
|
+
(0, vitest_1.expect)(loaded).toHaveLength(1);
|
|
204
|
+
(0, vitest_1.expect)(loaded[0]).toMatchObject({
|
|
205
|
+
tool: "write_file",
|
|
206
|
+
pattern: `${path.dirname(target)}/**`,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
ui.getRl().close();
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
(0, vitest_1.test)("shell_command: allowlistRequested=true persists 'echo hello' for 'echo hello world'", async () => {
|
|
214
|
+
// Real `echo` command — benign, no side effects, exits 0
|
|
215
|
+
// immediately. Avoids needing to mock child_process.execSync
|
|
216
|
+
// (which is hard to redefine on an ESM module namespace).
|
|
217
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
218
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
219
|
+
approved: true,
|
|
220
|
+
allowlistRequested: true,
|
|
221
|
+
});
|
|
222
|
+
try {
|
|
223
|
+
await (0, tools_js_1.executeTool)({
|
|
224
|
+
tool_use_id: "t-allowlist-2",
|
|
225
|
+
name: "shell_command",
|
|
226
|
+
input: { command: "echo hello world" },
|
|
227
|
+
}, ui);
|
|
228
|
+
const loaded = (0, settings_js_1.loadAllowlist)();
|
|
229
|
+
(0, vitest_1.expect)(loaded).toHaveLength(1);
|
|
230
|
+
(0, vitest_1.expect)(loaded[0]).toMatchObject({
|
|
231
|
+
tool: "shell_command",
|
|
232
|
+
pattern: "echo hello",
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
ui.getRl().close();
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
(0, vitest_1.test)("appendAllowlist failure does NOT abort the tool run (#6538 CR-r1)", async () => {
|
|
240
|
+
// Force the settings file to be unwritable by pointing
|
|
241
|
+
// XIAOTIME_SETTINGS_PATH at a non-existent directory under a
|
|
242
|
+
// read-only parent. The tool was already approved; persist
|
|
243
|
+
// failure should log to stderr and let the tool execute.
|
|
244
|
+
const readOnlyDir = path.join(tmpDir, "read-only");
|
|
245
|
+
fs.mkdirSync(readOnlyDir);
|
|
246
|
+
fs.chmodSync(readOnlyDir, 0o400); // r--
|
|
247
|
+
process.env.XIAOTIME_SETTINGS_PATH = path.join(readOnlyDir, "child", "settings.json");
|
|
248
|
+
const stderrSpy = vitest_1.vi
|
|
249
|
+
.spyOn(process.stderr, "write")
|
|
250
|
+
.mockImplementation(() => true);
|
|
251
|
+
const target = path.join(tmpDir, "still-written.txt");
|
|
252
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
253
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
254
|
+
approved: true,
|
|
255
|
+
allowlistRequested: true,
|
|
256
|
+
});
|
|
257
|
+
try {
|
|
258
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
259
|
+
tool_use_id: "t-persist-fail",
|
|
260
|
+
name: "write_file",
|
|
261
|
+
input: { path: target, content: "should still land" },
|
|
262
|
+
}, ui);
|
|
263
|
+
// Tool ran despite persist failure.
|
|
264
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
265
|
+
(0, vitest_1.expect)(fs.readFileSync(target, "utf-8")).toBe("should still land");
|
|
266
|
+
// Stderr received the failure warning.
|
|
267
|
+
const stderrCalls = stderrSpy.mock.calls
|
|
268
|
+
.map((c) => String(c[0]))
|
|
269
|
+
.join("");
|
|
270
|
+
(0, vitest_1.expect)(stderrCalls).toContain("failed to persist allowlist");
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
ui.getRl().close();
|
|
274
|
+
// Restore mode so cleanup can rm -rf.
|
|
275
|
+
fs.chmodSync(readOnlyDir, 0o700);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
(0, vitest_1.test)("allowlistRequested=false does NOT persist", async () => {
|
|
279
|
+
const target = path.join(tmpDir, "no-persist.txt");
|
|
280
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
281
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
282
|
+
approved: true,
|
|
283
|
+
allowlistRequested: false,
|
|
284
|
+
});
|
|
285
|
+
try {
|
|
286
|
+
await (0, tools_js_1.executeTool)({
|
|
287
|
+
tool_use_id: "t-no-persist",
|
|
288
|
+
name: "write_file",
|
|
289
|
+
input: { path: target, content: "x" },
|
|
290
|
+
}, ui);
|
|
291
|
+
(0, vitest_1.expect)((0, settings_js_1.loadAllowlist)()).toEqual([]);
|
|
292
|
+
(0, vitest_1.expect)(fs.existsSync(settingsPath)).toBe(false);
|
|
293
|
+
}
|
|
294
|
+
finally {
|
|
295
|
+
ui.getRl().close();
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
(0, vitest_1.describe)("allowlist match skips promptApprovalMenu (ISC-6509-004)", () => {
|
|
300
|
+
(0, vitest_1.test)("write_file: matching dir glob skips menu + writes file", async () => {
|
|
301
|
+
// Pre-seed the allowlist with a write_file dir-glob entry.
|
|
302
|
+
(0, settings_js_1.appendAllowlist)({
|
|
303
|
+
tool: "write_file",
|
|
304
|
+
pattern: `${tmpDir}/**`,
|
|
305
|
+
});
|
|
306
|
+
const target = path.join(tmpDir, "auto-approved.txt");
|
|
307
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
308
|
+
const spy = vitest_1.vi.spyOn(ui, "promptApprovalMenu");
|
|
309
|
+
try {
|
|
310
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
311
|
+
tool_use_id: "t-skip-1",
|
|
312
|
+
name: "write_file",
|
|
313
|
+
input: { path: target, content: "via allowlist" },
|
|
314
|
+
}, ui);
|
|
315
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
316
|
+
(0, vitest_1.expect)(result.content).toBe(`File written: ${target}`);
|
|
317
|
+
(0, vitest_1.expect)(fs.readFileSync(target, "utf-8")).toBe("via allowlist");
|
|
318
|
+
(0, vitest_1.expect)(spy).not.toHaveBeenCalled();
|
|
319
|
+
}
|
|
320
|
+
finally {
|
|
321
|
+
ui.getRl().close();
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
(0, vitest_1.test)("shell_command: matching derived pattern skips menu + runs", async () => {
|
|
325
|
+
(0, settings_js_1.appendAllowlist)({
|
|
326
|
+
tool: "shell_command",
|
|
327
|
+
pattern: "echo hello",
|
|
328
|
+
});
|
|
329
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
330
|
+
const spy = vitest_1.vi.spyOn(ui, "promptApprovalMenu");
|
|
331
|
+
try {
|
|
332
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
333
|
+
tool_use_id: "t-skip-2",
|
|
334
|
+
name: "shell_command",
|
|
335
|
+
input: { command: "echo hello world" },
|
|
336
|
+
}, ui);
|
|
337
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
338
|
+
(0, vitest_1.expect)(result.content).toBe("hello world\n");
|
|
339
|
+
(0, vitest_1.expect)(spy).not.toHaveBeenCalled();
|
|
340
|
+
}
|
|
341
|
+
finally {
|
|
342
|
+
ui.getRl().close();
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
// NOTE: git_commit auto-approve happy-path is covered by the
|
|
346
|
+
// PR-body manual walkthrough (requires a real git repo with staged
|
|
347
|
+
// changes; setting that up in a vitest fixture is heavier than the
|
|
348
|
+
// marginal coverage gain). The skip-menu invariant is exercised
|
|
349
|
+
// here via shell_command + write_file; git_commit shares the
|
|
350
|
+
// _gateApproval helper one switch case over.
|
|
351
|
+
(0, vitest_1.test)("non-matching allowlist entry → menu IS called", async () => {
|
|
352
|
+
// Allowlist has a write_file entry for a DIFFERENT dir; shouldn't
|
|
353
|
+
// authorize a write to tmpDir.
|
|
354
|
+
(0, settings_js_1.appendAllowlist)({
|
|
355
|
+
tool: "write_file",
|
|
356
|
+
pattern: "/some/other/**",
|
|
357
|
+
});
|
|
358
|
+
const target = path.join(tmpDir, "needs-prompt.txt");
|
|
359
|
+
const ui = new ui_state_js_1.SessionUI();
|
|
360
|
+
vitest_1.vi.spyOn(ui, "promptApprovalMenu").mockResolvedValue({
|
|
361
|
+
approved: true,
|
|
362
|
+
allowlistRequested: false,
|
|
363
|
+
});
|
|
364
|
+
try {
|
|
365
|
+
const result = await (0, tools_js_1.executeTool)({
|
|
366
|
+
tool_use_id: "t-skip-4",
|
|
367
|
+
name: "write_file",
|
|
368
|
+
input: { path: target, content: "x" },
|
|
369
|
+
}, ui);
|
|
370
|
+
(0, vitest_1.expect)(result.is_error).toBe(false);
|
|
371
|
+
(0, vitest_1.expect)(fs.readFileSync(target, "utf-8")).toBe("x");
|
|
372
|
+
// The mocked promptApprovalMenu WAS called, confirming the
|
|
373
|
+
// non-matching allowlist didn't authorize.
|
|
374
|
+
(0, vitest_1.expect)(ui.promptApprovalMenu).toHaveBeenCalledTimes(1);
|
|
375
|
+
}
|
|
376
|
+
finally {
|
|
377
|
+
ui.getRl().close();
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
//# sourceMappingURL=tools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../src/__tests__/tools.test.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -22,4 +22,11 @@
|
|
|
22
22
|
export declare const ORCHESTRATOR_URL: string;
|
|
23
23
|
export declare const AUTH_URL: string;
|
|
24
24
|
export declare const WS_URL: string;
|
|
25
|
+
/**
|
|
26
|
+
* The CLI's own version, sent in the WebSocket auth handshake so the
|
|
27
|
+
* server can reject pre-0.4.0 clients (#6565 PR5 — the client-owned
|
|
28
|
+
* dispatch cutover). MUST stay in sync with `version` in package.json;
|
|
29
|
+
* the drift-guard test in `__tests__/legacy_compat.test.ts` enforces it.
|
|
30
|
+
*/
|
|
31
|
+
export declare const CLI_VERSION = "0.4.0";
|
|
25
32
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,eAAO,MAAM,gBAAgB,QAC4C,CAAC;AAK1E,eAAO,MAAM,QAAQ,QACuC,CAAC;AAQ7D,eAAO,MAAM,MAAM,QAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,eAAO,MAAM,gBAAgB,QAC4C,CAAC;AAK1E,eAAO,MAAM,QAAQ,QACuC,CAAC;AAQ7D,eAAO,MAAM,MAAM,QAA4B,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,UAAU,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* got 404. Restored in 0.2.1 (#6097 PR2 follow-up).
|
|
22
22
|
*/
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.WS_URL = exports.AUTH_URL = exports.ORCHESTRATOR_URL = void 0;
|
|
24
|
+
exports.CLI_VERSION = exports.WS_URL = exports.AUTH_URL = exports.ORCHESTRATOR_URL = void 0;
|
|
25
25
|
// Terminal orchestrator — handles dev sessions (WebSocket + REST).
|
|
26
26
|
exports.ORCHESTRATOR_URL = process.env.XIAOTIME_ORCHESTRATOR_URL || "https://terminal.xiaotime.ai";
|
|
27
27
|
// Main orchestrator — handles the OAuth login flow (init + token poll).
|
|
@@ -34,4 +34,11 @@ function toWsUrl(url) {
|
|
|
34
34
|
return parsed.toString().replace(/\/$/, "");
|
|
35
35
|
}
|
|
36
36
|
exports.WS_URL = toWsUrl(exports.ORCHESTRATOR_URL);
|
|
37
|
+
/**
|
|
38
|
+
* The CLI's own version, sent in the WebSocket auth handshake so the
|
|
39
|
+
* server can reject pre-0.4.0 clients (#6565 PR5 — the client-owned
|
|
40
|
+
* dispatch cutover). MUST stay in sync with `version` in package.json;
|
|
41
|
+
* the drift-guard test in `__tests__/legacy_compat.test.ts` enforces it.
|
|
42
|
+
*/
|
|
43
|
+
exports.CLI_VERSION = "0.4.0";
|
|
37
44
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAEH,mEAAmE;AACtD,QAAA,gBAAgB,GAC3B,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,8BAA8B,CAAC;AAE1E,wEAAwE;AACxE,6EAA6E;AAC7E,4BAA4B;AACf,QAAA,QAAQ,GACnB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,yBAAyB,CAAC;AAE7D,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAChE,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAEY,QAAA,MAAM,GAAG,OAAO,CAAC,wBAAgB,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAEH,mEAAmE;AACtD,QAAA,gBAAgB,GAC3B,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,8BAA8B,CAAC;AAE1E,wEAAwE;AACxE,6EAA6E;AAC7E,4BAA4B;AACf,QAAA,QAAQ,GACnB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,yBAAyB,CAAC;AAE7D,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAChE,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAEY,QAAA,MAAM,GAAG,OAAO,CAAC,wBAAgB,CAAC,CAAC;AAEhD;;;;;GAKG;AACU,QAAA,WAAW,GAAG,OAAO,CAAC"}
|