@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,30 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { getCoreTool } from "../../src/definitions/core.js";
|
|
3
|
-
|
|
4
|
-
describe("Outlook tool definitions", () => {
|
|
5
|
-
it("registers the Outlook check, send, and reply tools in the core inventory", () => {
|
|
6
|
-
const checkOutlookMessages = getCoreTool("check_outlook_messages");
|
|
7
|
-
const sendOutlookMessage = getCoreTool("send_outlook_message");
|
|
8
|
-
const replyOutlookMessage = getCoreTool("reply_outlook_message");
|
|
9
|
-
|
|
10
|
-
expect(checkOutlookMessages).toBeDefined();
|
|
11
|
-
expect(sendOutlookMessage).toBeDefined();
|
|
12
|
-
expect(replyOutlookMessage).toBeDefined();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("marks Outlook reads as read-only and sends/replies as confirmation-gated writes", () => {
|
|
16
|
-
const checkOutlookMessages = getCoreTool("check_outlook_messages");
|
|
17
|
-
const sendOutlookMessage = getCoreTool("send_outlook_message");
|
|
18
|
-
const replyOutlookMessage = getCoreTool("reply_outlook_message");
|
|
19
|
-
|
|
20
|
-
expect(checkOutlookMessages?.category).toBe("messaging");
|
|
21
|
-
expect(checkOutlookMessages?.isReadOnly).toBe(true);
|
|
22
|
-
expect(checkOutlookMessages?.riskLevel).toBe("safe");
|
|
23
|
-
expect(sendOutlookMessage?.category).toBe("messaging");
|
|
24
|
-
expect(sendOutlookMessage?.requiresConfirmation).toBe(true);
|
|
25
|
-
expect(sendOutlookMessage?.riskLevel).toBe("dangerous");
|
|
26
|
-
expect(replyOutlookMessage?.category).toBe("messaging");
|
|
27
|
-
expect(replyOutlookMessage?.requiresConfirmation).toBe(true);
|
|
28
|
-
expect(replyOutlookMessage?.riskLevel).toBe("dangerous");
|
|
29
|
-
});
|
|
30
|
-
});
|
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @aria/tools - process tool unit tests
|
|
3
|
-
*
|
|
4
|
-
* Tests for session slugs, PTY key encoding, and process registry.
|
|
5
|
-
* No real child processes are spawned.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
9
|
-
import { createSessionSlug } from "../../src/definitions/process/session-slug.js";
|
|
10
|
-
import {
|
|
11
|
-
encodeKeySequence,
|
|
12
|
-
encodePaste,
|
|
13
|
-
BRACKETED_PASTE_START,
|
|
14
|
-
BRACKETED_PASTE_END,
|
|
15
|
-
} from "../../src/definitions/process/pty-keys.js";
|
|
16
|
-
import {
|
|
17
|
-
addSession,
|
|
18
|
-
getSession,
|
|
19
|
-
getFinishedSession,
|
|
20
|
-
appendOutput,
|
|
21
|
-
drainSession,
|
|
22
|
-
markExited,
|
|
23
|
-
markBackgrounded,
|
|
24
|
-
listRunningSessions,
|
|
25
|
-
listFinishedSessions,
|
|
26
|
-
resetProcessRegistryForTests,
|
|
27
|
-
tail,
|
|
28
|
-
trimWithCap,
|
|
29
|
-
type ProcessSession,
|
|
30
|
-
} from "../../src/definitions/process/process-registry.js";
|
|
31
|
-
|
|
32
|
-
// ── Session Slugs ────────────────────────────────────────────────────
|
|
33
|
-
|
|
34
|
-
describe("process", () => {
|
|
35
|
-
describe("session-slug", () => {
|
|
36
|
-
it("generates human-readable slugs", () => {
|
|
37
|
-
const slug = createSessionSlug();
|
|
38
|
-
|
|
39
|
-
// Format: adjective-noun (two words joined by hyphen)
|
|
40
|
-
expect(slug).toMatch(/^[a-z]+-[a-z]+/);
|
|
41
|
-
expect(slug.length).toBeGreaterThan(3);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("generates unique slugs on repeated calls", () => {
|
|
45
|
-
const slugs = new Set<string>();
|
|
46
|
-
// Generate many slugs; collisions are extremely unlikely
|
|
47
|
-
for (let i = 0; i < 50; i++) {
|
|
48
|
-
slugs.add(createSessionSlug());
|
|
49
|
-
}
|
|
50
|
-
// With 40+ adjectives * 50+ nouns = 2000+ combos, 50 should be mostly unique
|
|
51
|
-
expect(slugs.size).toBeGreaterThan(30);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it("avoids collisions with existing slugs", () => {
|
|
55
|
-
const taken = new Set<string>();
|
|
56
|
-
|
|
57
|
-
const slug1 = createSessionSlug((id) => taken.has(id));
|
|
58
|
-
taken.add(slug1);
|
|
59
|
-
|
|
60
|
-
const slug2 = createSessionSlug((id) => taken.has(id));
|
|
61
|
-
taken.add(slug2);
|
|
62
|
-
|
|
63
|
-
expect(slug1).not.toBe(slug2);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("appends numeric suffix when base is taken", () => {
|
|
67
|
-
// Force collision by marking all base slugs as taken for first attempt,
|
|
68
|
-
// but allow the -2 suffix variant
|
|
69
|
-
let callCount = 0;
|
|
70
|
-
const slug = createSessionSlug((id) => {
|
|
71
|
-
callCount++;
|
|
72
|
-
// First call (base slug): taken. Subsequent calls with suffixes: not taken.
|
|
73
|
-
if (!id.includes("-") || id.split("-").length <= 2) {
|
|
74
|
-
// Base slug (e.g., "calm-harbor") is taken
|
|
75
|
-
return true;
|
|
76
|
-
}
|
|
77
|
-
return false;
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Should have a numeric suffix since all 2-word bases are "taken"
|
|
81
|
-
expect(slug).toMatch(/\d/);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it("falls back to 3-word slugs when 2-word exhausted", () => {
|
|
85
|
-
// Mark ALL 2-word and their suffixed variants as taken
|
|
86
|
-
// to force 3-word generation
|
|
87
|
-
let attemptCount = 0;
|
|
88
|
-
const slug = createSessionSlug((id) => {
|
|
89
|
-
attemptCount++;
|
|
90
|
-
// If attempt count is very high, allow it (safety valve)
|
|
91
|
-
if (attemptCount > 200) return false;
|
|
92
|
-
// Count word segments (excluding numeric suffixes)
|
|
93
|
-
const parts = id.split("-");
|
|
94
|
-
const wordCount = parts.filter((p) => !/^\d+$/.test(p)).length;
|
|
95
|
-
return wordCount <= 2; // All 2-word variants are taken
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// The slug should exist and be non-empty
|
|
99
|
-
expect(slug).toBeTruthy();
|
|
100
|
-
expect(slug.length).toBeGreaterThan(0);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// ── PTY Keys ───────────────────────────────────────────────────────
|
|
105
|
-
|
|
106
|
-
describe("pty-keys", () => {
|
|
107
|
-
it("encodes Enter key", () => {
|
|
108
|
-
const result = encodeKeySequence({ keys: ["Enter"] });
|
|
109
|
-
expect(result.data).toBe("\r");
|
|
110
|
-
expect(result.warnings).toHaveLength(0);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("encodes Return key (alias for Enter)", () => {
|
|
114
|
-
const result = encodeKeySequence({ keys: ["Return"] });
|
|
115
|
-
expect(result.data).toBe("\r");
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("encodes Ctrl+C", () => {
|
|
119
|
-
const result = encodeKeySequence({ keys: ["C-c"] });
|
|
120
|
-
expect(result.data).toBe("\x03"); // ETX (End of Text)
|
|
121
|
-
expect(result.warnings).toHaveLength(0);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("encodes Ctrl+C with caret notation", () => {
|
|
125
|
-
const result = encodeKeySequence({ keys: ["^C"] });
|
|
126
|
-
expect(result.data).toBe("\x03");
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it("encodes arrow keys", () => {
|
|
130
|
-
const up = encodeKeySequence({ keys: ["Up"] });
|
|
131
|
-
expect(up.data).toBe("\x1b[A");
|
|
132
|
-
|
|
133
|
-
const down = encodeKeySequence({ keys: ["Down"] });
|
|
134
|
-
expect(down.data).toBe("\x1b[B");
|
|
135
|
-
|
|
136
|
-
const right = encodeKeySequence({ keys: ["Right"] });
|
|
137
|
-
expect(right.data).toBe("\x1b[C");
|
|
138
|
-
|
|
139
|
-
const left = encodeKeySequence({ keys: ["Left"] });
|
|
140
|
-
expect(left.data).toBe("\x1b[D");
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it("encodes Tab key", () => {
|
|
144
|
-
const result = encodeKeySequence({ keys: ["Tab"] });
|
|
145
|
-
expect(result.data).toBe("\t");
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("encodes Escape key", () => {
|
|
149
|
-
const result = encodeKeySequence({ keys: ["Escape"] });
|
|
150
|
-
expect(result.data).toBe("\x1b");
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it("encodes Backspace key", () => {
|
|
154
|
-
const result = encodeKeySequence({ keys: ["Backspace"] });
|
|
155
|
-
expect(result.data).toBe("\x7f");
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it("encodes function keys", () => {
|
|
159
|
-
const f1 = encodeKeySequence({ keys: ["F1"] });
|
|
160
|
-
expect(f1.data).toBe("\x1bOP");
|
|
161
|
-
|
|
162
|
-
const f5 = encodeKeySequence({ keys: ["F5"] });
|
|
163
|
-
expect(f5.data).toBe("\x1b[15~");
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it("encodes Space key", () => {
|
|
167
|
-
const result = encodeKeySequence({ keys: ["Space"] });
|
|
168
|
-
expect(result.data).toBe(" ");
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it("encodes Shift+Tab (back-tab)", () => {
|
|
172
|
-
const result = encodeKeySequence({ keys: ["S-Tab"] });
|
|
173
|
-
expect(result.data).toBe("\x1b[Z");
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it("handles literal text", () => {
|
|
177
|
-
const result = encodeKeySequence({ literal: "hello" });
|
|
178
|
-
expect(result.data).toBe("hello");
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it("handles hex byte encoding", () => {
|
|
182
|
-
const result = encodeKeySequence({ hex: ["0x0d"] });
|
|
183
|
-
expect(result.data).toBe("\r"); // 0x0d = carriage return
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it("rejects invalid hex bytes with warning", () => {
|
|
187
|
-
const result = encodeKeySequence({ hex: ["zz"] });
|
|
188
|
-
expect(result.data).toBe("");
|
|
189
|
-
expect(result.warnings).toHaveLength(1);
|
|
190
|
-
expect(result.warnings[0]).toContain("Invalid hex byte");
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it("handles unknown keys gracefully with warning", () => {
|
|
194
|
-
const result = encodeKeySequence({ keys: ["C-UnknownKey"] });
|
|
195
|
-
// Should produce warnings for unknown modified key
|
|
196
|
-
expect(result.warnings.length).toBeGreaterThanOrEqual(0);
|
|
197
|
-
// Should still produce some output (literal fallback)
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
it("encodes multiple keys in sequence", () => {
|
|
201
|
-
const result = encodeKeySequence({ keys: ["h", "i", "Enter"] });
|
|
202
|
-
expect(result.data).toBe("hi\r");
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it("combines literal and keys", () => {
|
|
206
|
-
const result = encodeKeySequence({
|
|
207
|
-
literal: "hello",
|
|
208
|
-
keys: ["Enter"],
|
|
209
|
-
});
|
|
210
|
-
expect(result.data).toBe("hello\r");
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it("encodes Alt modifier", () => {
|
|
214
|
-
const result = encodeKeySequence({ keys: ["M-x"] });
|
|
215
|
-
expect(result.data).toBe("\x1bx"); // ESC + x
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it("encodes Ctrl+A to Ctrl+Z", () => {
|
|
219
|
-
const ctrlA = encodeKeySequence({ keys: ["C-a"] });
|
|
220
|
-
expect(ctrlA.data).toBe("\x01");
|
|
221
|
-
|
|
222
|
-
const ctrlZ = encodeKeySequence({ keys: ["C-z"] });
|
|
223
|
-
expect(ctrlZ.data).toBe("\x1a");
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it("encodes modifiers on arrow keys", () => {
|
|
227
|
-
// Ctrl+Up
|
|
228
|
-
const result = encodeKeySequence({ keys: ["C-Up"] });
|
|
229
|
-
// Should be xterm modified sequence: ESC[1;5A (5 = ctrl modifier)
|
|
230
|
-
expect(result.data).toContain("\x1b[1;5A");
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it("encodePaste wraps with bracketed paste markers", () => {
|
|
234
|
-
const result = encodePaste("hello world");
|
|
235
|
-
expect(result.startsWith(BRACKETED_PASTE_START)).toBe(true);
|
|
236
|
-
expect(result.endsWith(BRACKETED_PASTE_END)).toBe(true);
|
|
237
|
-
expect(result).toContain("hello world");
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it("encodePaste without brackets returns raw text", () => {
|
|
241
|
-
const result = encodePaste("hello", false);
|
|
242
|
-
expect(result).toBe("hello");
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
// ── Process Registry ───────────────────────────────────────────────
|
|
247
|
-
|
|
248
|
-
describe("process-registry", () => {
|
|
249
|
-
beforeEach(() => {
|
|
250
|
-
resetProcessRegistryForTests();
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
afterEach(() => {
|
|
254
|
-
resetProcessRegistryForTests();
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
function createMockSession(overrides?: Partial<ProcessSession>): ProcessSession {
|
|
258
|
-
return {
|
|
259
|
-
id: "test-session",
|
|
260
|
-
command: "echo hello",
|
|
261
|
-
startedAt: Date.now(),
|
|
262
|
-
maxOutputChars: 200_000,
|
|
263
|
-
totalOutputChars: 0,
|
|
264
|
-
pendingStdout: [],
|
|
265
|
-
pendingStderr: [],
|
|
266
|
-
pendingStdoutChars: 0,
|
|
267
|
-
pendingStderrChars: 0,
|
|
268
|
-
aggregated: "",
|
|
269
|
-
tail: "",
|
|
270
|
-
exited: false,
|
|
271
|
-
truncated: false,
|
|
272
|
-
backgrounded: false,
|
|
273
|
-
...overrides,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
it("tracks spawned processes", () => {
|
|
278
|
-
const session = createMockSession({ id: "my-proc" });
|
|
279
|
-
addSession(session);
|
|
280
|
-
|
|
281
|
-
const found = getSession("my-proc");
|
|
282
|
-
expect(found).toBeDefined();
|
|
283
|
-
expect(found!.id).toBe("my-proc");
|
|
284
|
-
expect(found!.command).toBe("echo hello");
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
it("returns undefined for unknown session", () => {
|
|
288
|
-
expect(getSession("nonexistent")).toBeUndefined();
|
|
289
|
-
expect(getFinishedSession("nonexistent")).toBeUndefined();
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it("appends output to stdout", () => {
|
|
293
|
-
const session = createMockSession();
|
|
294
|
-
addSession(session);
|
|
295
|
-
|
|
296
|
-
appendOutput(session, "stdout", "line 1\n");
|
|
297
|
-
appendOutput(session, "stdout", "line 2\n");
|
|
298
|
-
|
|
299
|
-
const drained = drainSession(session);
|
|
300
|
-
expect(drained.stdout).toBe("line 1\nline 2\n");
|
|
301
|
-
expect(drained.stderr).toBe("");
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it("appends output to stderr", () => {
|
|
305
|
-
const session = createMockSession();
|
|
306
|
-
addSession(session);
|
|
307
|
-
|
|
308
|
-
appendOutput(session, "stderr", "error msg\n");
|
|
309
|
-
|
|
310
|
-
const drained = drainSession(session);
|
|
311
|
-
expect(drained.stdout).toBe("");
|
|
312
|
-
expect(drained.stderr).toBe("error msg\n");
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
it("drainSession clears pending buffers", () => {
|
|
316
|
-
const session = createMockSession();
|
|
317
|
-
addSession(session);
|
|
318
|
-
|
|
319
|
-
appendOutput(session, "stdout", "data");
|
|
320
|
-
const first = drainSession(session);
|
|
321
|
-
expect(first.stdout).toBe("data");
|
|
322
|
-
|
|
323
|
-
// Second drain should be empty
|
|
324
|
-
const second = drainSession(session);
|
|
325
|
-
expect(second.stdout).toBe("");
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
it("caps output at ring buffer limit", () => {
|
|
329
|
-
const session = createMockSession({
|
|
330
|
-
maxOutputChars: 100,
|
|
331
|
-
});
|
|
332
|
-
addSession(session);
|
|
333
|
-
|
|
334
|
-
// Write more than 100 chars
|
|
335
|
-
const bigChunk = "x".repeat(150);
|
|
336
|
-
appendOutput(session, "stdout", bigChunk);
|
|
337
|
-
|
|
338
|
-
expect(session.truncated).toBe(true);
|
|
339
|
-
expect(session.aggregated.length).toBeLessThanOrEqual(100);
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
it("marks finished processes", () => {
|
|
343
|
-
const session = createMockSession({
|
|
344
|
-
id: "finishing",
|
|
345
|
-
backgrounded: true,
|
|
346
|
-
});
|
|
347
|
-
addSession(session);
|
|
348
|
-
markBackgrounded(session);
|
|
349
|
-
|
|
350
|
-
appendOutput(session, "stdout", "done\n");
|
|
351
|
-
markExited(session, 0, null, "completed");
|
|
352
|
-
|
|
353
|
-
// Should be moved from running to finished
|
|
354
|
-
expect(getSession("finishing")).toBeUndefined();
|
|
355
|
-
|
|
356
|
-
const finished = getFinishedSession("finishing");
|
|
357
|
-
expect(finished).toBeDefined();
|
|
358
|
-
expect(finished!.status).toBe("completed");
|
|
359
|
-
expect(finished!.exitCode).toBe(0);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it("marks failed processes", () => {
|
|
363
|
-
const session = createMockSession({
|
|
364
|
-
id: "failing",
|
|
365
|
-
backgrounded: true,
|
|
366
|
-
});
|
|
367
|
-
addSession(session);
|
|
368
|
-
markBackgrounded(session);
|
|
369
|
-
|
|
370
|
-
markExited(session, 1, null, "failed");
|
|
371
|
-
|
|
372
|
-
const finished = getFinishedSession("failing");
|
|
373
|
-
expect(finished).toBeDefined();
|
|
374
|
-
expect(finished!.status).toBe("failed");
|
|
375
|
-
expect(finished!.exitCode).toBe(1);
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
it("marks killed processes", () => {
|
|
379
|
-
const session = createMockSession({
|
|
380
|
-
id: "killed",
|
|
381
|
-
backgrounded: true,
|
|
382
|
-
});
|
|
383
|
-
addSession(session);
|
|
384
|
-
markBackgrounded(session);
|
|
385
|
-
|
|
386
|
-
markExited(session, null, "SIGTERM", "killed");
|
|
387
|
-
|
|
388
|
-
const finished = getFinishedSession("killed");
|
|
389
|
-
expect(finished).toBeDefined();
|
|
390
|
-
expect(finished!.status).toBe("killed");
|
|
391
|
-
expect(finished!.exitSignal).toBe("SIGTERM");
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
it("lists running backgrounded sessions", () => {
|
|
395
|
-
const s1 = createMockSession({ id: "bg-1", backgrounded: true });
|
|
396
|
-
const s2 = createMockSession({ id: "bg-2", backgrounded: false });
|
|
397
|
-
const s3 = createMockSession({ id: "bg-3", backgrounded: true });
|
|
398
|
-
|
|
399
|
-
addSession(s1);
|
|
400
|
-
addSession(s2);
|
|
401
|
-
addSession(s3);
|
|
402
|
-
|
|
403
|
-
const running = listRunningSessions();
|
|
404
|
-
const ids = running.map((s) => s.id);
|
|
405
|
-
expect(ids).toContain("bg-1");
|
|
406
|
-
expect(ids).toContain("bg-3");
|
|
407
|
-
expect(ids).not.toContain("bg-2");
|
|
408
|
-
});
|
|
409
|
-
|
|
410
|
-
it("lists finished sessions", () => {
|
|
411
|
-
const session = createMockSession({ id: "done-1", backgrounded: true });
|
|
412
|
-
addSession(session);
|
|
413
|
-
markBackgrounded(session);
|
|
414
|
-
markExited(session, 0, null, "completed");
|
|
415
|
-
|
|
416
|
-
const finished = listFinishedSessions();
|
|
417
|
-
expect(finished).toHaveLength(1);
|
|
418
|
-
expect(finished[0]!.id).toBe("done-1");
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
it("non-backgrounded sessions are not preserved in finished", () => {
|
|
422
|
-
const session = createMockSession({ id: "fg-session", backgrounded: false });
|
|
423
|
-
addSession(session);
|
|
424
|
-
|
|
425
|
-
markExited(session, 0, null, "completed");
|
|
426
|
-
|
|
427
|
-
// Should not appear in finished since it was not backgrounded
|
|
428
|
-
expect(getFinishedSession("fg-session")).toBeUndefined();
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
it("tail utility caps output at max chars", () => {
|
|
432
|
-
expect(tail("hello world", 5)).toBe("world");
|
|
433
|
-
expect(tail("hi", 10)).toBe("hi");
|
|
434
|
-
expect(tail("", 5)).toBe("");
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
it("trimWithCap keeps last N characters", () => {
|
|
438
|
-
expect(trimWithCap("abcdef", 3)).toBe("def");
|
|
439
|
-
expect(trimWithCap("ab", 5)).toBe("ab");
|
|
440
|
-
});
|
|
441
|
-
|
|
442
|
-
it("tracks total output chars across appends", () => {
|
|
443
|
-
const session = createMockSession();
|
|
444
|
-
addSession(session);
|
|
445
|
-
|
|
446
|
-
appendOutput(session, "stdout", "12345");
|
|
447
|
-
appendOutput(session, "stderr", "67890");
|
|
448
|
-
|
|
449
|
-
expect(session.totalOutputChars).toBe(10);
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
it("resetProcessRegistryForTests clears all state", () => {
|
|
453
|
-
const s1 = createMockSession({ id: "s1" });
|
|
454
|
-
addSession(s1);
|
|
455
|
-
|
|
456
|
-
const s2 = createMockSession({ id: "s2", backgrounded: true });
|
|
457
|
-
addSession(s2);
|
|
458
|
-
markBackgrounded(s2);
|
|
459
|
-
markExited(s2, 0, null, "completed");
|
|
460
|
-
|
|
461
|
-
resetProcessRegistryForTests();
|
|
462
|
-
|
|
463
|
-
expect(getSession("s1")).toBeUndefined();
|
|
464
|
-
expect(getFinishedSession("s2")).toBeUndefined();
|
|
465
|
-
expect(listRunningSessions()).toHaveLength(0);
|
|
466
|
-
expect(listFinishedSessions()).toHaveLength(0);
|
|
467
|
-
});
|
|
468
|
-
});
|
|
469
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { getCoreTool } from "../../src/definitions/core.js";
|
|
3
|
-
|
|
4
|
-
describe("Slack tool definitions", () => {
|
|
5
|
-
it("registers the Slack read, write, and react tools in the core inventory", () => {
|
|
6
|
-
const checkSlackMessages = getCoreTool("check_slack_messages");
|
|
7
|
-
const sendSlackMessage = getCoreTool("send_slack_message");
|
|
8
|
-
const reactSlackMessage = getCoreTool("react_slack_message");
|
|
9
|
-
|
|
10
|
-
expect(checkSlackMessages).toBeDefined();
|
|
11
|
-
expect(sendSlackMessage).toBeDefined();
|
|
12
|
-
expect(reactSlackMessage).toBeDefined();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("marks Slack reads as read-only and Slack sends/reacts as confirmation-gated writes", () => {
|
|
16
|
-
const checkSlackMessages = getCoreTool("check_slack_messages");
|
|
17
|
-
const sendSlackMessage = getCoreTool("send_slack_message");
|
|
18
|
-
const reactSlackMessage = getCoreTool("react_slack_message");
|
|
19
|
-
|
|
20
|
-
expect(checkSlackMessages?.category).toBe("messaging");
|
|
21
|
-
expect(checkSlackMessages?.isReadOnly).toBe(true);
|
|
22
|
-
expect(sendSlackMessage?.category).toBe("messaging");
|
|
23
|
-
expect(sendSlackMessage?.requiresConfirmation).toBe(true);
|
|
24
|
-
expect(reactSlackMessage?.category).toBe("messaging");
|
|
25
|
-
expect(reactSlackMessage?.requiresConfirmation).toBe(true);
|
|
26
|
-
expect(reactSlackMessage?.isReadOnly).toBe(false);
|
|
27
|
-
});
|
|
28
|
-
});
|