@aria-cli/tools 1.0.9 → 1.0.11
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/package.json +9 -5
- package/src/__tests__/web-fetch-download.test.ts +0 -433
- package/src/__tests__/web-tools.test.ts +0 -619
- package/src/ask-user-interaction.ts +0 -33
- package/src/cache/web-cache.ts +0 -110
- package/src/definitions/arion.ts +0 -118
- package/src/definitions/browser/browser.ts +0 -502
- package/src/definitions/browser/index.ts +0 -5
- package/src/definitions/browser/pw-downloads.ts +0 -142
- package/src/definitions/browser/pw-interactions.ts +0 -282
- package/src/definitions/browser/pw-responses.ts +0 -98
- package/src/definitions/browser/pw-session.ts +0 -405
- package/src/definitions/browser/pw-shared.ts +0 -85
- package/src/definitions/browser/pw-snapshot.ts +0 -383
- package/src/definitions/browser/pw-state.ts +0 -101
- package/src/definitions/browser/types.ts +0 -203
- package/src/definitions/code-intelligence.ts +0 -526
- package/src/definitions/core.ts +0 -118
- package/src/definitions/delegation.ts +0 -567
- package/src/definitions/deploy.ts +0 -73
- package/src/definitions/filesystem.ts +0 -217
- package/src/definitions/frg.ts +0 -67
- package/src/definitions/index.ts +0 -28
- package/src/definitions/memory.ts +0 -150
- package/src/definitions/messaging.ts +0 -734
- package/src/definitions/meta.ts +0 -392
- package/src/definitions/network.ts +0 -179
- package/src/definitions/outlook.ts +0 -318
- package/src/definitions/patch/apply-patch.ts +0 -235
- package/src/definitions/patch/fuzzy-match.ts +0 -217
- package/src/definitions/patch/index.ts +0 -1
- package/src/definitions/patch/patch-parser.ts +0 -297
- package/src/definitions/patch/sandbox-paths.ts +0 -129
- package/src/definitions/process/index.ts +0 -5
- package/src/definitions/process/process-registry.ts +0 -303
- package/src/definitions/process/process.ts +0 -456
- package/src/definitions/process/pty-keys.ts +0 -298
- package/src/definitions/process/session-slug.ts +0 -147
- package/src/definitions/quip.ts +0 -225
- package/src/definitions/search.ts +0 -67
- package/src/definitions/session-history.ts +0 -79
- package/src/definitions/shell.ts +0 -202
- package/src/definitions/slack.ts +0 -211
- package/src/definitions/web.ts +0 -119
- package/src/executors/apply-patch.ts +0 -1035
- package/src/executors/arion.ts +0 -199
- package/src/executors/code-intelligence.ts +0 -1179
- package/src/executors/deploy.ts +0 -1066
- package/src/executors/filesystem.ts +0 -1428
- package/src/executors/frg-freshness.ts +0 -743
- package/src/executors/frg.ts +0 -394
- package/src/executors/index.ts +0 -280
- package/src/executors/learning-meta.ts +0 -1367
- package/src/executors/lsp-client.ts +0 -355
- package/src/executors/memory.ts +0 -978
- package/src/executors/meta.ts +0 -293
- package/src/executors/process-registry.ts +0 -570
- package/src/executors/pty-session-store.ts +0 -43
- package/src/executors/pty.ts +0 -342
- package/src/executors/restart.ts +0 -133
- package/src/executors/search-freshness.ts +0 -249
- package/src/executors/search-types.ts +0 -98
- package/src/executors/search.ts +0 -89
- package/src/executors/self-diagnose.ts +0 -552
- package/src/executors/session-history.ts +0 -435
- package/src/executors/shell-safety.ts +0 -519
- package/src/executors/shell.ts +0 -1243
- package/src/executors/utils.ts +0 -40
- package/src/executors/web.ts +0 -786
- package/src/extraction/content-extraction.ts +0 -281
- package/src/extraction/index.ts +0 -5
- package/src/headless-control-contract.ts +0 -1149
- package/src/index.ts +0 -788
- package/src/local-control-http-auth.ts +0 -2
- package/src/mcp/client.ts +0 -218
- package/src/mcp/connection.ts +0 -568
- package/src/mcp/index.ts +0 -11
- package/src/mcp/jsonrpc.ts +0 -195
- package/src/mcp/types.ts +0 -199
- package/src/network-control-adapter.ts +0 -88
- package/src/network-runtime/address-types.ts +0 -218
- package/src/network-runtime/db-owner-fencing.ts +0 -91
- package/src/network-runtime/delivery-receipts.ts +0 -372
- package/src/network-runtime/direct-endpoint-authority.ts +0 -35
- package/src/network-runtime/index.ts +0 -316
- package/src/network-runtime/local-control-contract.ts +0 -784
- package/src/network-runtime/node-store-contract.ts +0 -46
- package/src/network-runtime/pair-route-contract.ts +0 -97
- package/src/network-runtime/peer-capabilities.ts +0 -48
- package/src/network-runtime/peer-principal-ref.ts +0 -20
- package/src/network-runtime/peer-state-machine.ts +0 -160
- package/src/network-runtime/protocol-schemas.ts +0 -265
- package/src/network-runtime/runtime-bootstrap-contract.ts +0 -83
- package/src/outlook/desktop-session.ts +0 -409
- package/src/policy.ts +0 -171
- package/src/providers/brave.ts +0 -80
- package/src/providers/duckduckgo.ts +0 -199
- package/src/providers/exa.ts +0 -85
- package/src/providers/firecrawl.ts +0 -77
- package/src/providers/index.ts +0 -8
- package/src/providers/jina.ts +0 -70
- package/src/providers/router.ts +0 -121
- package/src/providers/search-provider.ts +0 -74
- package/src/providers/tavily.ts +0 -74
- package/src/quip/desktop-session.ts +0 -435
- package/src/registry/index.ts +0 -1
- package/src/registry/registry.ts +0 -905
- package/src/runtime-socket-local-control-client.ts +0 -632
- package/src/security/dns-normalization.ts +0 -34
- package/src/security/dns-pinning.ts +0 -138
- package/src/security/external-content.ts +0 -129
- package/src/security/ssrf.ts +0 -207
- package/src/slack/desktop-session.ts +0 -493
- package/src/tool-factory.ts +0 -91
- package/src/types.ts +0 -1341
- package/src/utils/retry.ts +0 -163
- package/src/utils/safe-parse-json.ts +0 -176
- package/src/utils/url.ts +0 -20
- package/tests/benchmarks/registry.bench.ts +0 -57
- package/tests/cache/web-cache.test.ts +0 -147
- package/tests/critical-integration.test.ts +0 -1465
- package/tests/definitions/apply-patch.test.ts +0 -586
- package/tests/definitions/browser.test.ts +0 -495
- package/tests/definitions/delegation-pause-resume.test.ts +0 -758
- package/tests/definitions/execution.test.ts +0 -671
- package/tests/definitions/messaging-inbox-scope.test.ts +0 -229
- package/tests/definitions/messaging.test.ts +0 -1468
- package/tests/definitions/outlook.test.ts +0 -30
- package/tests/definitions/process.test.ts +0 -469
- package/tests/definitions/slack.test.ts +0 -28
- package/tests/definitions/tool-inventory.test.ts +0 -218
- package/tests/e2e/delegation-quest-orchestration.e2e.test.ts +0 -433
- package/tests/e2e/memory-tool-discovery-contract.e2e.test.ts +0 -81
- package/tests/executors/apply-patch.test.ts +0 -538
- package/tests/executors/arion.test.ts +0 -309
- package/tests/executors/conversation-primitives.test.ts +0 -250
- package/tests/executors/deploy.test.ts +0 -746
- package/tests/executors/filesystem-tools.test.ts +0 -357
- package/tests/executors/filesystem.test.ts +0 -959
- package/tests/executors/frg-freshness.test.ts +0 -136
- package/tests/executors/frg-merge.test.ts +0 -70
- package/tests/executors/frg-session-content.test.ts +0 -40
- package/tests/executors/frg.test.ts +0 -56
- package/tests/executors/memory-bugfixes.test.ts +0 -257
- package/tests/executors/memory-real-memoria.integration.test.ts +0 -316
- package/tests/executors/memory.test.ts +0 -853
- package/tests/executors/meta-tools.test.ts +0 -411
- package/tests/executors/meta.test.ts +0 -683
- package/tests/executors/path-containment.test.ts +0 -51
- package/tests/executors/process-registry.test.ts +0 -505
- package/tests/executors/pty.test.ts +0 -664
- package/tests/executors/quest-security.test.ts +0 -249
- package/tests/executors/read-file-media.test.ts +0 -230
- package/tests/executors/recall-knowledge-schema.test.ts +0 -209
- package/tests/executors/recall-tags.test.ts +0 -278
- package/tests/executors/remember-null-safety.contract.test.ts +0 -41
- package/tests/executors/restart.test.ts +0 -67
- package/tests/executors/search-unified.test.ts +0 -381
- package/tests/executors/session-history.test.ts +0 -340
- package/tests/executors/session-transcript.test.ts +0 -561
- package/tests/executors/shell-abort.test.ts +0 -416
- package/tests/executors/shell-env-blocklist.test.ts +0 -648
- package/tests/executors/shell-env-process.test.ts +0 -245
- package/tests/executors/shell-process-registry.test.ts +0 -334
- package/tests/executors/shell-tools.test.ts +0 -393
- package/tests/executors/shell.test.ts +0 -690
- package/tests/executors/web-abort-vs-timeout.test.ts +0 -213
- package/tests/executors/web-integration.test.ts +0 -633
- package/tests/executors/web-symlink.test.ts +0 -18
- package/tests/executors/web.test.ts +0 -1400
- package/tests/executors/write-stdin.test.ts +0 -145
- package/tests/extraction/content-extraction.test.ts +0 -153
- package/tests/guards/tools-default-test-lane.integration.test.ts +0 -21
- package/tests/guards/tools-package-test-commands.e2e.test.ts +0 -43
- package/tests/guards/tools-test-lane-manifest.contract.test.ts +0 -76
- package/tests/guards/tools-vitest-workspace-alias.contract.test.ts +0 -63
- package/tests/helpers/async-waits.ts +0 -53
- package/tests/integration/headless-control-contract.integration.test.ts +0 -153
- package/tests/integration/memory-tool-schema-parity.integration.test.ts +0 -67
- package/tests/integration/meta-tools-round-trip.integration.test.ts +0 -506
- package/tests/integration/quest-round-trip.test.ts +0 -303
- package/tests/integration/registry-executor-flow.test.ts +0 -85
- package/tests/integration.test.ts +0 -177
- package/tests/loading-tier.test.ts +0 -126
- package/tests/mcp/client-reconnect.test.ts +0 -267
- package/tests/mcp/connection.test.ts +0 -846
- package/tests/mcp/injectable-logger.test.ts +0 -83
- package/tests/mcp/jsonrpc.test.ts +0 -109
- package/tests/mcp/lifecycle.test.ts +0 -879
- package/tests/network-runtime/address-types.contract.test.ts +0 -143
- package/tests/network-runtime/continuity-bind-schema.contract.test.ts +0 -203
- package/tests/network-runtime/local-control-contract.test.ts +0 -869
- package/tests/network-runtime/local-control-invite-token.contract.test.ts +0 -146
- package/tests/network-runtime/node-store-contract.test.ts +0 -11
- package/tests/network-runtime/pair-protocol-nodeid.contract.test.ts +0 -15
- package/tests/network-runtime/peer-state-machine.contract.test.ts +0 -148
- package/tests/network-runtime/protocol-schemas.contract.test.ts +0 -512
- package/tests/network-runtime/relay-pending-nodeid.contract.test.ts +0 -62
- package/tests/network-runtime/runtime-bootstrap-contract.test.ts +0 -227
- package/tests/network-runtime/runtime-socket-local-control-client.test.ts +0 -621
- package/tests/network-runtime/wait-for-message-script.test.ts +0 -288
- package/tests/parallel.test.ts +0 -71
- package/tests/policy.test.ts +0 -184
- package/tests/print-default-test-lane.ts +0 -14
- package/tests/print-test-lane-manifest.ts +0 -22
- package/tests/providers/brave.test.ts +0 -159
- package/tests/providers/duckduckgo.test.ts +0 -207
- package/tests/providers/exa.test.ts +0 -175
- package/tests/providers/firecrawl.test.ts +0 -168
- package/tests/providers/jina.test.ts +0 -144
- package/tests/providers/router.test.ts +0 -328
- package/tests/providers/tavily.test.ts +0 -165
- package/tests/registry/discovery.test.ts +0 -154
- package/tests/registry/injectable-logger.test.ts +0 -230
- package/tests/registry/input-validation.test.ts +0 -361
- package/tests/registry/interface-completeness.test.ts +0 -85
- package/tests/registry/mcp-integration.test.ts +0 -103
- package/tests/registry/mcp-read-only-hint.test.ts +0 -60
- package/tests/registry/memoria-discovery.test.ts +0 -390
- package/tests/registry/nested-validation.test.ts +0 -283
- package/tests/registry/pseudo-tool-filtering.test.ts +0 -258
- package/tests/registry/registration-lifecycle.test.ts +0 -133
- package/tests/registry-validation.test.ts +0 -424
- package/tests/registry.test.ts +0 -460
- package/tests/security/dns-pinning.test.ts +0 -162
- package/tests/security/external-content.test.ts +0 -144
- package/tests/security/ssrf.test.ts +0 -118
- package/tests/shell-safety-integration.test.ts +0 -32
- package/tests/shell-safety.test.ts +0 -365
- package/tests/slack/desktop-session.test.ts +0 -50
- package/tests/test-lane-manifest.ts +0 -440
- package/tests/test-utils.ts +0 -27
- package/tests/tool-factory.test.ts +0 -188
- package/tests/utils/retry.test.ts +0 -231
- package/tests/utils/url.test.ts +0 -63
- package/tsconfig.cjs.json +0 -24
- package/tsconfig.json +0 -12
- package/vitest.config.ts +0 -55
- package/vitest.e2e.config.ts +0 -24
- package/vitest.integration.config.ts +0 -24
- package/vitest.native.config.ts +0 -24
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { executeSessionHistory } from "../../src/executors/session-history.js";
|
|
3
|
-
import type {
|
|
4
|
-
ToolContext,
|
|
5
|
-
SessionHistoryRef,
|
|
6
|
-
SessionSummaryRef,
|
|
7
|
-
SessionContextRef,
|
|
8
|
-
} from "../../src/types.js";
|
|
9
|
-
|
|
10
|
-
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
11
|
-
|
|
12
|
-
function makeSummary(overrides: Partial<SessionSummaryRef> = {}): SessionSummaryRef {
|
|
13
|
-
return {
|
|
14
|
-
id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
|
|
15
|
-
createdAt: new Date("2026-03-01T10:00:00Z"),
|
|
16
|
-
updatedAt: new Date("2026-03-01T11:00:00Z"),
|
|
17
|
-
title: "Test session",
|
|
18
|
-
arion: "aria",
|
|
19
|
-
model: "claude-4-sonnet",
|
|
20
|
-
messageCount: 10,
|
|
21
|
-
preview: "Hello, how can I help?",
|
|
22
|
-
...overrides,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function makeSessionContext(overrides: Partial<SessionContextRef> = {}): SessionContextRef {
|
|
27
|
-
return {
|
|
28
|
-
id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
|
|
29
|
-
arion: "aria",
|
|
30
|
-
model: "claude-4-sonnet",
|
|
31
|
-
messages: [
|
|
32
|
-
{
|
|
33
|
-
id: 1,
|
|
34
|
-
role: "user",
|
|
35
|
-
content: "Hello",
|
|
36
|
-
createdAt: new Date("2026-03-01T10:00:00Z"),
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
id: 2,
|
|
40
|
-
role: "assistant",
|
|
41
|
-
content: "Hi! How can I help?",
|
|
42
|
-
createdAt: new Date("2026-03-01T10:00:01Z"),
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
...overrides,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function mockSessionHistory(overrides: Partial<SessionHistoryRef> = {}): SessionHistoryRef {
|
|
50
|
-
return {
|
|
51
|
-
listSessions: vi.fn().mockReturnValue([makeSummary()]),
|
|
52
|
-
searchSessionsFts: vi.fn().mockReturnValue([makeSummary()]),
|
|
53
|
-
getSession: vi.fn().mockReturnValue(makeSessionContext()),
|
|
54
|
-
getIncompleteSessions: vi.fn().mockReturnValue([]),
|
|
55
|
-
deleteSession: vi.fn(),
|
|
56
|
-
markCompleted: vi.fn(),
|
|
57
|
-
setSessionTitle: vi.fn(),
|
|
58
|
-
findSessionByPrefix: vi.fn().mockReturnValue("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"),
|
|
59
|
-
getSessionCount: vi.fn().mockReturnValue(42),
|
|
60
|
-
getRunMetrics: vi.fn().mockReturnValue([]),
|
|
61
|
-
...overrides,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function makeCtx(sessionHistory?: SessionHistoryRef, currentSessionId?: string): ToolContext {
|
|
66
|
-
return {
|
|
67
|
-
workingDir: "/tmp",
|
|
68
|
-
env: {},
|
|
69
|
-
confirm: vi.fn().mockResolvedValue(true),
|
|
70
|
-
sessionHistory,
|
|
71
|
-
currentSessionId,
|
|
72
|
-
} as unknown as ToolContext;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ── Tests ────────────────────────────────────────────────────────────────────
|
|
76
|
-
|
|
77
|
-
describe("executeSessionHistory", () => {
|
|
78
|
-
let sh: SessionHistoryRef;
|
|
79
|
-
let ctx: ToolContext;
|
|
80
|
-
|
|
81
|
-
beforeEach(() => {
|
|
82
|
-
sh = mockSessionHistory();
|
|
83
|
-
ctx = makeCtx(sh, "current-session-id-1234");
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// ── Missing prerequisites ──
|
|
87
|
-
|
|
88
|
-
it("fails when action is missing", async () => {
|
|
89
|
-
const result = await executeSessionHistory({} as any, ctx);
|
|
90
|
-
expect(result.success).toBe(false);
|
|
91
|
-
expect(result.message).toContain("action is required");
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("falls back to dynamic import when sessionHistory is not in context", async () => {
|
|
95
|
-
const ctxNoHistory = makeCtx(undefined);
|
|
96
|
-
const result = await executeSessionHistory({ action: "list" }, ctxNoHistory);
|
|
97
|
-
// In the monorepo, the fallback dynamic import of @aria/cli succeeds,
|
|
98
|
-
// so the tool works even without ctx.sessionHistory. It either succeeds
|
|
99
|
-
// (with real data from the DB) or fails with "not available" in isolated
|
|
100
|
-
// environments where @aria/cli can't be located.
|
|
101
|
-
expect(typeof result.success).toBe("boolean");
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("fails on unknown action", async () => {
|
|
105
|
-
const result = await executeSessionHistory({ action: "foobar" as any }, ctx);
|
|
106
|
-
expect(result.success).toBe(false);
|
|
107
|
-
expect(result.message).toContain("Unknown action");
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it("respects abort signal", async () => {
|
|
111
|
-
const controller = new AbortController();
|
|
112
|
-
controller.abort();
|
|
113
|
-
const ctxAborted = { ...ctx, abortSignal: controller.signal } as ToolContext;
|
|
114
|
-
const result = await executeSessionHistory({ action: "list" }, ctxAborted);
|
|
115
|
-
expect(result.success).toBe(false);
|
|
116
|
-
expect(result.message).toContain("cancelled");
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// ── list ──
|
|
120
|
-
|
|
121
|
-
describe("list", () => {
|
|
122
|
-
it("lists sessions", async () => {
|
|
123
|
-
const result = await executeSessionHistory({ action: "list" }, ctx);
|
|
124
|
-
expect(result.success).toBe(true);
|
|
125
|
-
expect(sh.listSessions).toHaveBeenCalledWith(20, 0);
|
|
126
|
-
expect(result.data).toHaveProperty("sessions");
|
|
127
|
-
const data = result.data as any;
|
|
128
|
-
expect(data.sessions).toHaveLength(1);
|
|
129
|
-
expect(data.sessions[0].id).toBe("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it("passes limit and offset", async () => {
|
|
133
|
-
await executeSessionHistory({ action: "list", limit: 5, offset: 10 }, ctx);
|
|
134
|
-
expect(sh.listSessions).toHaveBeenCalledWith(5, 10);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("returns empty message when no sessions", async () => {
|
|
138
|
-
(sh.listSessions as any).mockReturnValue([]);
|
|
139
|
-
const result = await executeSessionHistory({ action: "list" }, ctx);
|
|
140
|
-
expect(result.success).toBe(true);
|
|
141
|
-
expect(result.message).toContain("No sessions found");
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// ── search ──
|
|
146
|
-
|
|
147
|
-
describe("search", () => {
|
|
148
|
-
it("searches sessions by query", async () => {
|
|
149
|
-
const result = await executeSessionHistory({ action: "search", query: "deployment" }, ctx);
|
|
150
|
-
expect(result.success).toBe(true);
|
|
151
|
-
expect(sh.searchSessionsFts).toHaveBeenCalledWith("deployment", 20, 0);
|
|
152
|
-
const data = result.data as any;
|
|
153
|
-
expect(data.sessions).toHaveLength(1);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it("fails without query", async () => {
|
|
157
|
-
const result = await executeSessionHistory({ action: "search" }, ctx);
|
|
158
|
-
expect(result.success).toBe(false);
|
|
159
|
-
expect(result.message).toContain("query is required");
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("fails with empty query", async () => {
|
|
163
|
-
const result = await executeSessionHistory({ action: "search", query: " " }, ctx);
|
|
164
|
-
expect(result.success).toBe(false);
|
|
165
|
-
expect(result.message).toContain("query is required");
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
it("returns empty message when no results", async () => {
|
|
169
|
-
(sh.searchSessionsFts as any).mockReturnValue([]);
|
|
170
|
-
const result = await executeSessionHistory({ action: "search", query: "nonexistent" }, ctx);
|
|
171
|
-
expect(result.success).toBe(true);
|
|
172
|
-
expect(result.message).toContain("No sessions found matching");
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// ── get ──
|
|
177
|
-
|
|
178
|
-
describe("get", () => {
|
|
179
|
-
it("gets a session by ID", async () => {
|
|
180
|
-
const result = await executeSessionHistory(
|
|
181
|
-
{ action: "get", sessionId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" },
|
|
182
|
-
ctx,
|
|
183
|
-
);
|
|
184
|
-
expect(result.success).toBe(true);
|
|
185
|
-
const data = result.data as any;
|
|
186
|
-
expect(data.id).toBe("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
|
|
187
|
-
expect(data.messages).toHaveLength(2);
|
|
188
|
-
expect(data.messages[0].role).toBe("user");
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it("gets a session by prefix", async () => {
|
|
192
|
-
const result = await executeSessionHistory({ action: "get", sessionId: "aaaaaaaa-bb" }, ctx);
|
|
193
|
-
expect(result.success).toBe(true);
|
|
194
|
-
expect(sh.findSessionByPrefix).toHaveBeenCalledWith("aaaaaaaa-bb");
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it("fails without sessionId", async () => {
|
|
198
|
-
const result = await executeSessionHistory({ action: "get" }, ctx);
|
|
199
|
-
expect(result.success).toBe(false);
|
|
200
|
-
expect(result.message).toContain("sessionId is required");
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it("fails when session not found", async () => {
|
|
204
|
-
(sh.findSessionByPrefix as any).mockReturnValue(null);
|
|
205
|
-
const result = await executeSessionHistory({ action: "get", sessionId: "deadbeef" }, ctx);
|
|
206
|
-
expect(result.success).toBe(false);
|
|
207
|
-
expect(result.message).toContain("not found");
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
it("respects messageLimit", async () => {
|
|
211
|
-
const longSession = makeSessionContext({
|
|
212
|
-
messages: Array.from({ length: 100 }, (_, i) => ({
|
|
213
|
-
id: i,
|
|
214
|
-
role: "user" as const,
|
|
215
|
-
content: `Message ${i}`,
|
|
216
|
-
createdAt: new Date(),
|
|
217
|
-
})),
|
|
218
|
-
});
|
|
219
|
-
(sh.getSession as any).mockReturnValue(longSession);
|
|
220
|
-
|
|
221
|
-
const result = await executeSessionHistory(
|
|
222
|
-
{ action: "get", sessionId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", messageLimit: 10 },
|
|
223
|
-
ctx,
|
|
224
|
-
);
|
|
225
|
-
expect(result.success).toBe(true);
|
|
226
|
-
const data = result.data as any;
|
|
227
|
-
expect(data.messages).toHaveLength(10);
|
|
228
|
-
// Should be the LAST 10 messages
|
|
229
|
-
expect(data.messages[0].content).toBe("Message 90");
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
it("truncates long message content", async () => {
|
|
233
|
-
const longContent = "x".repeat(5000);
|
|
234
|
-
const session = makeSessionContext({
|
|
235
|
-
messages: [{ id: 1, role: "user", content: longContent, createdAt: new Date() }],
|
|
236
|
-
});
|
|
237
|
-
(sh.getSession as any).mockReturnValue(session);
|
|
238
|
-
|
|
239
|
-
const result = await executeSessionHistory(
|
|
240
|
-
{ action: "get", sessionId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" },
|
|
241
|
-
ctx,
|
|
242
|
-
);
|
|
243
|
-
const data = result.data as any;
|
|
244
|
-
expect(data.messages[0].content.length).toBeLessThan(longContent.length);
|
|
245
|
-
expect(data.messages[0].content).toMatch(/\.\.\.$/);
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// ── current ──
|
|
250
|
-
|
|
251
|
-
describe("current", () => {
|
|
252
|
-
it("returns current session info", async () => {
|
|
253
|
-
const result = await executeSessionHistory({ action: "current" }, ctx);
|
|
254
|
-
expect(result.success).toBe(true);
|
|
255
|
-
const data = result.data as any;
|
|
256
|
-
expect(data.sessionId).toBe("current-session-id-1234");
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it("fails without current session", async () => {
|
|
260
|
-
const ctxNoCurrent = makeCtx(sh, undefined);
|
|
261
|
-
const result = await executeSessionHistory({ action: "current" }, ctxNoCurrent);
|
|
262
|
-
expect(result.success).toBe(false);
|
|
263
|
-
expect(result.message).toContain("No current session");
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
// ── stats ──
|
|
268
|
-
|
|
269
|
-
describe("stats", () => {
|
|
270
|
-
it("returns session statistics", async () => {
|
|
271
|
-
(sh.getIncompleteSessions as any).mockReturnValue([makeSummary(), makeSummary()]);
|
|
272
|
-
const result = await executeSessionHistory({ action: "stats" }, ctx);
|
|
273
|
-
expect(result.success).toBe(true);
|
|
274
|
-
const data = result.data as any;
|
|
275
|
-
expect(data.totalSessions).toBe(42);
|
|
276
|
-
expect(data.incompleteSessions).toBe(2);
|
|
277
|
-
});
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// ── delete ──
|
|
281
|
-
|
|
282
|
-
describe("delete", () => {
|
|
283
|
-
it("deletes a session", async () => {
|
|
284
|
-
const result = await executeSessionHistory(
|
|
285
|
-
{ action: "delete", sessionId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" },
|
|
286
|
-
ctx,
|
|
287
|
-
);
|
|
288
|
-
expect(result.success).toBe(true);
|
|
289
|
-
expect(sh.deleteSession).toHaveBeenCalledWith("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it("fails without sessionId", async () => {
|
|
293
|
-
const result = await executeSessionHistory({ action: "delete" }, ctx);
|
|
294
|
-
expect(result.success).toBe(false);
|
|
295
|
-
expect(result.message).toContain("sessionId is required");
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
it("fails when session not found", async () => {
|
|
299
|
-
(sh.findSessionByPrefix as any).mockReturnValue(null);
|
|
300
|
-
const result = await executeSessionHistory({ action: "delete", sessionId: "deadbeef" }, ctx);
|
|
301
|
-
expect(result.success).toBe(false);
|
|
302
|
-
expect(result.message).toContain("not found");
|
|
303
|
-
});
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
// ── set_title ──
|
|
307
|
-
|
|
308
|
-
describe("set_title", () => {
|
|
309
|
-
it("sets session title", async () => {
|
|
310
|
-
const result = await executeSessionHistory(
|
|
311
|
-
{
|
|
312
|
-
action: "set_title",
|
|
313
|
-
sessionId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
|
|
314
|
-
title: "New Title",
|
|
315
|
-
},
|
|
316
|
-
ctx,
|
|
317
|
-
);
|
|
318
|
-
expect(result.success).toBe(true);
|
|
319
|
-
expect(sh.setSessionTitle).toHaveBeenCalledWith(
|
|
320
|
-
"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
|
|
321
|
-
"New Title",
|
|
322
|
-
);
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
it("fails without sessionId", async () => {
|
|
326
|
-
const result = await executeSessionHistory({ action: "set_title", title: "New Title" }, ctx);
|
|
327
|
-
expect(result.success).toBe(false);
|
|
328
|
-
expect(result.message).toContain("sessionId is required");
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
it("fails without title", async () => {
|
|
332
|
-
const result = await executeSessionHistory(
|
|
333
|
-
{ action: "set_title", sessionId: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" },
|
|
334
|
-
ctx,
|
|
335
|
-
);
|
|
336
|
-
expect(result.success).toBe(false);
|
|
337
|
-
expect(result.message).toContain("title is required");
|
|
338
|
-
});
|
|
339
|
-
});
|
|
340
|
-
});
|