@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,506 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Meta-tools round-trip integration tests
|
|
3
|
-
*
|
|
4
|
-
* Tests the full lifecycle of the 6 meta-tools (search, learn_tool, learn_skill,
|
|
5
|
-
* create_tool, create_skill, use_skill) using mock IMemoria instances to verify
|
|
6
|
-
* that executors correctly call the Memoria API and that data flows through
|
|
7
|
-
* the system as expected.
|
|
8
|
-
*
|
|
9
|
-
* All tests use vi.fn() mocks to isolate the executor logic from real storage.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
13
|
-
import { mkdtempSync, rmSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { tmpdir, homedir } from "node:os";
|
|
16
|
-
import {
|
|
17
|
-
executeLearnTool,
|
|
18
|
-
executeLearnSkill,
|
|
19
|
-
executeCreateTool,
|
|
20
|
-
executeCreateSkill,
|
|
21
|
-
executeUseSkill,
|
|
22
|
-
executeSearchKnowledge,
|
|
23
|
-
} from "../../src/executors/learning-meta.js";
|
|
24
|
-
import { ToolRegistry } from "../../src/registry/registry.js";
|
|
25
|
-
import type { ToolContext } from "../../src/types.js";
|
|
26
|
-
|
|
27
|
-
// ===========================================================================
|
|
28
|
-
// Shared Helpers
|
|
29
|
-
// ===========================================================================
|
|
30
|
-
|
|
31
|
-
/** Create a mock IMemoria with all methods needed by meta-tool executors */
|
|
32
|
-
function createMockMemoria() {
|
|
33
|
-
return {
|
|
34
|
-
remember: vi.fn().mockResolvedValue({ id: "mem-001" }),
|
|
35
|
-
recall: vi.fn().mockResolvedValue({ memories: [] }),
|
|
36
|
-
recallTools: vi.fn().mockResolvedValue([]),
|
|
37
|
-
rememberTool: vi.fn().mockResolvedValue("tool-id-001"),
|
|
38
|
-
rememberSkill: vi.fn().mockResolvedValue("skill-id-001"),
|
|
39
|
-
recallSkills: vi.fn().mockResolvedValue([]),
|
|
40
|
-
getSkill: vi.fn().mockResolvedValue(null),
|
|
41
|
-
recordSkillExecution: vi.fn().mockResolvedValue({
|
|
42
|
-
id: "exec-001",
|
|
43
|
-
skillId: "skill-id-001",
|
|
44
|
-
success: true,
|
|
45
|
-
timestamp: new Date(),
|
|
46
|
-
}),
|
|
47
|
-
deleteMemory: vi.fn().mockResolvedValue(true),
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Create a ToolContext with the given workingDir and memoria mock */
|
|
52
|
-
function createContext(
|
|
53
|
-
workDir: string,
|
|
54
|
-
memoria: ReturnType<typeof createMockMemoria>,
|
|
55
|
-
): ToolContext {
|
|
56
|
-
return {
|
|
57
|
-
workingDir: workDir,
|
|
58
|
-
env: {},
|
|
59
|
-
confirm: vi.fn().mockResolvedValue(true),
|
|
60
|
-
memoria: memoria as any,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ===========================================================================
|
|
65
|
-
// Tests
|
|
66
|
-
// ===========================================================================
|
|
67
|
-
|
|
68
|
-
describe("Meta-tools round-trip integration", () => {
|
|
69
|
-
let workDir: string;
|
|
70
|
-
|
|
71
|
-
beforeEach(() => {
|
|
72
|
-
workDir = mkdtempSync(join(tmpdir(), "meta-tools-rt-"));
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// -----------------------------------------------------------------------
|
|
76
|
-
// 1. learn_tool -> discoverFromMemoria round-trip
|
|
77
|
-
// -----------------------------------------------------------------------
|
|
78
|
-
describe("learn_tool -> discoverFromMemoria round-trip", () => {
|
|
79
|
-
it("should learn a CLI tool via --help and store it in Memoria, then discover it in a fresh registry", async () => {
|
|
80
|
-
const mockMemoria = createMockMemoria();
|
|
81
|
-
mockMemoria.rememberTool.mockResolvedValue("learned-tool-id-42");
|
|
82
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
83
|
-
|
|
84
|
-
// Step 1: Learn a tool from its --help output (use "git" which reliably supports --help)
|
|
85
|
-
const result = await executeLearnTool({ command: "git" }, ctx);
|
|
86
|
-
|
|
87
|
-
expect(result.success).toBe(true);
|
|
88
|
-
expect((result.data as any).toolId).toBe("learned-tool-id-42");
|
|
89
|
-
expect((result.data as any).name).toBe("git");
|
|
90
|
-
|
|
91
|
-
// Verify rememberTool was called with correct shape
|
|
92
|
-
expect(mockMemoria.rememberTool).toHaveBeenCalledTimes(1);
|
|
93
|
-
const storedTool = mockMemoria.rememberTool.mock.calls[0][0];
|
|
94
|
-
expect(storedTool.name).toBe("git");
|
|
95
|
-
expect(storedTool.description).toBeDefined();
|
|
96
|
-
expect(storedTool.source).toEqual({
|
|
97
|
-
type: "external",
|
|
98
|
-
ref: "cli:git",
|
|
99
|
-
format: "markdown",
|
|
100
|
-
});
|
|
101
|
-
expect(storedTool.category).toBe("shell");
|
|
102
|
-
expect(storedTool.riskLevel).toBe("moderate");
|
|
103
|
-
expect(storedTool.parameters).toBeDefined();
|
|
104
|
-
expect(storedTool.responseTemplate).toContain("git");
|
|
105
|
-
expect(storedTool.knowledge).toBeDefined();
|
|
106
|
-
expect(storedTool.tags).toEqual(expect.arrayContaining(["cli", "learned"]));
|
|
107
|
-
expect(storedTool.confidence).toBe(0.7);
|
|
108
|
-
expect(storedTool.importance).toBe(0.6);
|
|
109
|
-
|
|
110
|
-
// Step 2: Verify a fresh ToolRegistry's discoverFromMemoria would find it.
|
|
111
|
-
// Set up recallTools to return the tool that was just "stored".
|
|
112
|
-
const discoveryMemoria = {
|
|
113
|
-
recallTools: vi.fn().mockResolvedValue([
|
|
114
|
-
{
|
|
115
|
-
id: "learned-tool-id-42",
|
|
116
|
-
name: storedTool.name,
|
|
117
|
-
description: storedTool.description,
|
|
118
|
-
category: storedTool.category,
|
|
119
|
-
parameters: storedTool.parameters,
|
|
120
|
-
riskLevel: storedTool.riskLevel,
|
|
121
|
-
responseTemplate: storedTool.responseTemplate,
|
|
122
|
-
},
|
|
123
|
-
]),
|
|
124
|
-
rememberTool: vi.fn().mockResolvedValue("unused"),
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const registry = new ToolRegistry();
|
|
128
|
-
const count = await registry.discoverFromMemoria(discoveryMemoria as any);
|
|
129
|
-
|
|
130
|
-
expect(count).toBe(1);
|
|
131
|
-
const discovered = registry.get("git");
|
|
132
|
-
expect(discovered).toBeDefined();
|
|
133
|
-
expect(discovered!.name).toBe("git");
|
|
134
|
-
expect(discovered!.category).toBe("shell");
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// -----------------------------------------------------------------------
|
|
139
|
-
// 2. create_skill -> recall round-trip
|
|
140
|
-
// -----------------------------------------------------------------------
|
|
141
|
-
describe("create_skill -> recall round-trip", () => {
|
|
142
|
-
it("should create a skill and verify rememberSkill was called, then verify recallSkills would return it", async () => {
|
|
143
|
-
const mockMemoria = createMockMemoria();
|
|
144
|
-
mockMemoria.rememberSkill.mockResolvedValue("skill-deploy-001");
|
|
145
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
146
|
-
|
|
147
|
-
// Step 1: Create a skill
|
|
148
|
-
const result = await executeCreateSkill(
|
|
149
|
-
{
|
|
150
|
-
name: "deploy-pipeline",
|
|
151
|
-
description: "Standard deploy procedure for production",
|
|
152
|
-
content:
|
|
153
|
-
"1. Run tests\n2. Build artifacts\n3. Push to staging\n4. Smoke test\n5. Promote to prod",
|
|
154
|
-
tags: ["deploy", "production"],
|
|
155
|
-
toolIds: ["bash-tool", "test-runner"],
|
|
156
|
-
},
|
|
157
|
-
ctx,
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
expect(result.success).toBe(true);
|
|
161
|
-
expect((result.data as any).skillId).toBe("skill-deploy-001");
|
|
162
|
-
expect((result.data as any).name).toBe("deploy-pipeline");
|
|
163
|
-
|
|
164
|
-
// Verify rememberSkill was called with correct shape
|
|
165
|
-
expect(mockMemoria.rememberSkill).toHaveBeenCalledTimes(1);
|
|
166
|
-
const storedSkill = mockMemoria.rememberSkill.mock.calls[0][0];
|
|
167
|
-
expect(storedSkill.name).toBe("deploy-pipeline");
|
|
168
|
-
expect(storedSkill.description).toBe("Standard deploy procedure for production");
|
|
169
|
-
expect(storedSkill.content).toContain("Run tests");
|
|
170
|
-
expect(storedSkill.source).toEqual({ type: "user", ref: "create_skill" });
|
|
171
|
-
expect(storedSkill.tags).toEqual(["deploy", "production"]);
|
|
172
|
-
expect(storedSkill.toolIds).toEqual(["bash-tool", "test-runner"]);
|
|
173
|
-
expect(storedSkill.importance).toBe(0.75);
|
|
174
|
-
expect(storedSkill.confidence).toBe(0.8);
|
|
175
|
-
|
|
176
|
-
// Step 2: Verify recallSkills({ query: name }) would return it
|
|
177
|
-
mockMemoria.recallSkills.mockResolvedValue([
|
|
178
|
-
{
|
|
179
|
-
id: "skill-deploy-001",
|
|
180
|
-
name: "deploy-pipeline",
|
|
181
|
-
description: "Standard deploy procedure for production",
|
|
182
|
-
content: storedSkill.content,
|
|
183
|
-
toolIds: ["bash-tool", "test-runner"],
|
|
184
|
-
triggers: [],
|
|
185
|
-
tags: ["deploy", "production"],
|
|
186
|
-
source: { type: "user", ref: "create_skill" },
|
|
187
|
-
executionCount: 0,
|
|
188
|
-
successCount: 0,
|
|
189
|
-
lastExecuted: null,
|
|
190
|
-
averageDurationMs: null,
|
|
191
|
-
confidence: 0.8,
|
|
192
|
-
importance: 0.75,
|
|
193
|
-
createdAt: new Date(),
|
|
194
|
-
updatedAt: new Date(),
|
|
195
|
-
accessedAt: new Date(),
|
|
196
|
-
accessCount: 0,
|
|
197
|
-
},
|
|
198
|
-
]);
|
|
199
|
-
|
|
200
|
-
const recalled = await mockMemoria.recallSkills({ query: "deploy-pipeline" });
|
|
201
|
-
expect(recalled).toHaveLength(1);
|
|
202
|
-
expect(recalled[0].name).toBe("deploy-pipeline");
|
|
203
|
-
expect(recalled[0].id).toBe("skill-deploy-001");
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// -----------------------------------------------------------------------
|
|
208
|
-
// 3. use_skill -> recordSkillExecution tracking
|
|
209
|
-
// -----------------------------------------------------------------------
|
|
210
|
-
describe("use_skill -> recordSkillExecution tracking", () => {
|
|
211
|
-
it("should look up a skill via getSkill and then record execution via recordSkillExecution", async () => {
|
|
212
|
-
const mockMemoria = createMockMemoria();
|
|
213
|
-
|
|
214
|
-
// Set up getSkill to return a known skill
|
|
215
|
-
const fakeSkill = {
|
|
216
|
-
id: "skill-lint-007",
|
|
217
|
-
name: "lint-check",
|
|
218
|
-
description: "Run all linters",
|
|
219
|
-
content: "eslint . && prettier --check .",
|
|
220
|
-
toolIds: ["bash"],
|
|
221
|
-
triggers: [],
|
|
222
|
-
tags: ["lint"],
|
|
223
|
-
source: { type: "user" as const, ref: "create_skill" },
|
|
224
|
-
executionCount: 3,
|
|
225
|
-
successCount: 2,
|
|
226
|
-
lastExecuted: new Date("2026-02-15"),
|
|
227
|
-
averageDurationMs: 500,
|
|
228
|
-
confidence: 0.85,
|
|
229
|
-
importance: 0.7,
|
|
230
|
-
createdAt: new Date(),
|
|
231
|
-
updatedAt: new Date(),
|
|
232
|
-
accessedAt: new Date(),
|
|
233
|
-
accessCount: 3,
|
|
234
|
-
};
|
|
235
|
-
mockMemoria.getSkill.mockResolvedValue(fakeSkill);
|
|
236
|
-
mockMemoria.recordSkillExecution.mockResolvedValue({
|
|
237
|
-
id: "exec-lint-001",
|
|
238
|
-
skillId: "skill-lint-007",
|
|
239
|
-
success: true,
|
|
240
|
-
durationMs: 320,
|
|
241
|
-
timestamp: new Date(),
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
245
|
-
|
|
246
|
-
// Execute use_skill
|
|
247
|
-
const result = await executeUseSkill(
|
|
248
|
-
{
|
|
249
|
-
name: "lint-check",
|
|
250
|
-
success: true,
|
|
251
|
-
durationMs: 320,
|
|
252
|
-
notes: "All checks passed",
|
|
253
|
-
},
|
|
254
|
-
ctx,
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
expect(result.success).toBe(true);
|
|
258
|
-
expect(result.message).toContain("lint-check");
|
|
259
|
-
|
|
260
|
-
// Verify getSkill was called with the skill name
|
|
261
|
-
expect(mockMemoria.getSkill).toHaveBeenCalledTimes(1);
|
|
262
|
-
expect(mockMemoria.getSkill).toHaveBeenCalledWith("lint-check");
|
|
263
|
-
|
|
264
|
-
// Verify recordSkillExecution was called with the skill's ID
|
|
265
|
-
expect(mockMemoria.recordSkillExecution).toHaveBeenCalledTimes(1);
|
|
266
|
-
expect(mockMemoria.recordSkillExecution).toHaveBeenCalledWith({
|
|
267
|
-
skillId: "skill-lint-007",
|
|
268
|
-
success: true,
|
|
269
|
-
durationMs: 320,
|
|
270
|
-
notes: "All checks passed",
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
// Verify the returned data contains the skill
|
|
274
|
-
expect((result.data as any).skill).toEqual(fakeSkill);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
it("should return failure when skill is not found", async () => {
|
|
278
|
-
const mockMemoria = createMockMemoria();
|
|
279
|
-
mockMemoria.getSkill.mockResolvedValue(null);
|
|
280
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
281
|
-
|
|
282
|
-
const result = await executeUseSkill({ name: "nonexistent-skill" }, ctx);
|
|
283
|
-
|
|
284
|
-
expect(result.success).toBe(false);
|
|
285
|
-
expect(result.message).toContain("not found");
|
|
286
|
-
expect(mockMemoria.recordSkillExecution).not.toHaveBeenCalled();
|
|
287
|
-
});
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
// -----------------------------------------------------------------------
|
|
291
|
-
// 4. learn_skill (file) -> search round-trip
|
|
292
|
-
// -----------------------------------------------------------------------
|
|
293
|
-
describe("learn_skill (file) -> search round-trip", () => {
|
|
294
|
-
it("should read a SKILL.md file, parse frontmatter, and store it via rememberSkill", async () => {
|
|
295
|
-
const mockMemoria = createMockMemoria();
|
|
296
|
-
mockMemoria.rememberSkill.mockResolvedValue("skill-file-001");
|
|
297
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
298
|
-
|
|
299
|
-
// Create a SKILL.md file with frontmatter
|
|
300
|
-
const skillDir = join(workDir, "skills", "code-review");
|
|
301
|
-
mkdirSync(skillDir, { recursive: true });
|
|
302
|
-
const skillPath = join(skillDir, "SKILL.md");
|
|
303
|
-
writeFileSync(
|
|
304
|
-
skillPath,
|
|
305
|
-
[
|
|
306
|
-
"---",
|
|
307
|
-
"name: code-review-checklist",
|
|
308
|
-
"description: Systematic code review procedure",
|
|
309
|
-
"---",
|
|
310
|
-
"## Code Review Checklist",
|
|
311
|
-
"",
|
|
312
|
-
"1. Check for security vulnerabilities",
|
|
313
|
-
"2. Verify error handling completeness",
|
|
314
|
-
"3. Review test coverage",
|
|
315
|
-
"4. Check naming conventions",
|
|
316
|
-
].join("\n"),
|
|
317
|
-
"utf-8",
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
// Execute learn_skill with file path
|
|
321
|
-
const result = await executeLearnSkill(
|
|
322
|
-
{
|
|
323
|
-
path: "skills/code-review/SKILL.md",
|
|
324
|
-
tags: ["review", "quality"],
|
|
325
|
-
},
|
|
326
|
-
ctx,
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
expect(result.success).toBe(true);
|
|
330
|
-
expect((result.data as any).skillId).toBe("skill-file-001");
|
|
331
|
-
expect((result.data as any).name).toBe("code-review-checklist");
|
|
332
|
-
|
|
333
|
-
// Verify rememberSkill was called with parsed frontmatter
|
|
334
|
-
expect(mockMemoria.rememberSkill).toHaveBeenCalledTimes(1);
|
|
335
|
-
const stored = mockMemoria.rememberSkill.mock.calls[0][0];
|
|
336
|
-
expect(stored.name).toBe("code-review-checklist");
|
|
337
|
-
expect(stored.description).toBe("Systematic code review procedure");
|
|
338
|
-
expect(stored.content).toContain("Check for security vulnerabilities");
|
|
339
|
-
expect(stored.content).toContain("Review test coverage");
|
|
340
|
-
expect(stored.source).toEqual({
|
|
341
|
-
type: "file",
|
|
342
|
-
path: skillPath,
|
|
343
|
-
format: "skill-file",
|
|
344
|
-
});
|
|
345
|
-
expect(stored.tags).toEqual(["review", "quality"]);
|
|
346
|
-
expect(stored.toolIds).toEqual([]);
|
|
347
|
-
expect(stored.importance).toBe(0.65);
|
|
348
|
-
expect(stored.confidence).toBe(0.7);
|
|
349
|
-
});
|
|
350
|
-
|
|
351
|
-
it("should fall back to directory name when frontmatter has no name", async () => {
|
|
352
|
-
const mockMemoria = createMockMemoria();
|
|
353
|
-
mockMemoria.rememberSkill.mockResolvedValue("skill-fallback-001");
|
|
354
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
355
|
-
|
|
356
|
-
// Create a SKILL.md without a name in frontmatter
|
|
357
|
-
const skillDir = join(workDir, "skills", "my-custom-skill");
|
|
358
|
-
mkdirSync(skillDir, { recursive: true });
|
|
359
|
-
writeFileSync(
|
|
360
|
-
join(skillDir, "SKILL.md"),
|
|
361
|
-
[
|
|
362
|
-
"---",
|
|
363
|
-
"description: A skill without explicit name",
|
|
364
|
-
"---",
|
|
365
|
-
"Do the thing step by step",
|
|
366
|
-
].join("\n"),
|
|
367
|
-
"utf-8",
|
|
368
|
-
);
|
|
369
|
-
|
|
370
|
-
const result = await executeLearnSkill({ path: "skills/my-custom-skill/SKILL.md" }, ctx);
|
|
371
|
-
|
|
372
|
-
expect(result.success).toBe(true);
|
|
373
|
-
const stored = mockMemoria.rememberSkill.mock.calls[0][0];
|
|
374
|
-
// Should fall back to directory name
|
|
375
|
-
expect(stored.name).toBe("my-custom-skill");
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
// -----------------------------------------------------------------------
|
|
380
|
-
// 5. create_tool upsert
|
|
381
|
-
// -----------------------------------------------------------------------
|
|
382
|
-
describe("create_tool upsert", () => {
|
|
383
|
-
it("should call rememberTool twice when creating a tool with the same name but different script (upsert)", async () => {
|
|
384
|
-
const mockMemoria = createMockMemoria();
|
|
385
|
-
mockMemoria.rememberTool.mockResolvedValueOnce("tool-v1").mockResolvedValueOnce("tool-v2");
|
|
386
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
387
|
-
|
|
388
|
-
// First creation
|
|
389
|
-
const result1 = await executeCreateTool(
|
|
390
|
-
{
|
|
391
|
-
name: "formatter",
|
|
392
|
-
description: "Format source code",
|
|
393
|
-
script: "prettier --write .",
|
|
394
|
-
tags: ["format"],
|
|
395
|
-
},
|
|
396
|
-
ctx,
|
|
397
|
-
);
|
|
398
|
-
|
|
399
|
-
expect(result1.success).toBe(true);
|
|
400
|
-
expect((result1.data as any).toolId).toBe("tool-v1");
|
|
401
|
-
|
|
402
|
-
// Second creation with same name but different script (upsert)
|
|
403
|
-
const result2 = await executeCreateTool(
|
|
404
|
-
{
|
|
405
|
-
name: "formatter",
|
|
406
|
-
description: "Format source code v2",
|
|
407
|
-
script: "biome format --write .",
|
|
408
|
-
tags: ["format", "v2"],
|
|
409
|
-
},
|
|
410
|
-
ctx,
|
|
411
|
-
);
|
|
412
|
-
|
|
413
|
-
expect(result2.success).toBe(true);
|
|
414
|
-
expect((result2.data as any).toolId).toBe("tool-v2");
|
|
415
|
-
|
|
416
|
-
// Verify rememberTool was called twice (upsert behavior -- second call overwrites)
|
|
417
|
-
expect(mockMemoria.rememberTool).toHaveBeenCalledTimes(2);
|
|
418
|
-
|
|
419
|
-
// Verify first call had the original script details
|
|
420
|
-
const firstCall = mockMemoria.rememberTool.mock.calls[0][0];
|
|
421
|
-
expect(firstCall.name).toBe("formatter");
|
|
422
|
-
expect(firstCall.description).toBe("Format source code");
|
|
423
|
-
expect(firstCall.tags).toEqual(expect.arrayContaining(["format", "created"]));
|
|
424
|
-
|
|
425
|
-
// Verify second call had the updated script details
|
|
426
|
-
const secondCall = mockMemoria.rememberTool.mock.calls[1][0];
|
|
427
|
-
expect(secondCall.name).toBe("formatter");
|
|
428
|
-
expect(secondCall.description).toBe("Format source code v2");
|
|
429
|
-
expect(secondCall.tags).toEqual(expect.arrayContaining(["format", "v2", "created"]));
|
|
430
|
-
|
|
431
|
-
// Verify the script file on disk was overwritten
|
|
432
|
-
// (both calls write to ~/.aria/tools/formatter.sh)
|
|
433
|
-
const { readFileSync } = await import("node:fs");
|
|
434
|
-
const scriptContent = readFileSync(join(homedir(), ".aria", "tools", "formatter.sh"), "utf-8");
|
|
435
|
-
expect(scriptContent).toContain("biome format --write .");
|
|
436
|
-
expect(scriptContent).not.toContain("prettier --write .");
|
|
437
|
-
});
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
// -----------------------------------------------------------------------
|
|
441
|
-
// 6. search (executeSearchKnowledge) — recallTools + recallSkills merge
|
|
442
|
-
// -----------------------------------------------------------------------
|
|
443
|
-
describe("executeSearchKnowledge — recallTools + recallSkills merge", () => {
|
|
444
|
-
it("should call both recallTools and recallSkills and merge results", async () => {
|
|
445
|
-
const mockMemoria = createMockMemoria();
|
|
446
|
-
mockMemoria.recallTools.mockResolvedValue([
|
|
447
|
-
{
|
|
448
|
-
id: "tool-grep-001",
|
|
449
|
-
name: "grep-helper",
|
|
450
|
-
description: "Smart grep wrapper",
|
|
451
|
-
category: "shell",
|
|
452
|
-
parameters: [],
|
|
453
|
-
riskLevel: "low",
|
|
454
|
-
},
|
|
455
|
-
]);
|
|
456
|
-
mockMemoria.recallSkills.mockResolvedValue([
|
|
457
|
-
{
|
|
458
|
-
id: "skill-review-001",
|
|
459
|
-
name: "code-review",
|
|
460
|
-
description: "Systematic code review procedure",
|
|
461
|
-
content: "1. Check errors 2. Check tests",
|
|
462
|
-
toolIds: [],
|
|
463
|
-
triggers: [],
|
|
464
|
-
tags: ["review"],
|
|
465
|
-
source: { type: "user", ref: "create_skill" },
|
|
466
|
-
executionCount: 5,
|
|
467
|
-
successCount: 4,
|
|
468
|
-
lastExecuted: null,
|
|
469
|
-
averageDurationMs: null,
|
|
470
|
-
confidence: 0.8,
|
|
471
|
-
importance: 0.7,
|
|
472
|
-
createdAt: new Date(),
|
|
473
|
-
updatedAt: new Date(),
|
|
474
|
-
accessedAt: new Date(),
|
|
475
|
-
accessCount: 3,
|
|
476
|
-
},
|
|
477
|
-
]);
|
|
478
|
-
const ctx = createContext(workDir, mockMemoria);
|
|
479
|
-
|
|
480
|
-
const result = await executeSearchKnowledge(
|
|
481
|
-
{ query: "code review grep", sources: ["memoria"] },
|
|
482
|
-
ctx,
|
|
483
|
-
);
|
|
484
|
-
|
|
485
|
-
expect(result.success).toBe(true);
|
|
486
|
-
|
|
487
|
-
// Verify both recall methods were called
|
|
488
|
-
expect(mockMemoria.recallTools).toHaveBeenCalledWith(
|
|
489
|
-
expect.objectContaining({ query: "code review grep" }),
|
|
490
|
-
);
|
|
491
|
-
expect(mockMemoria.recallSkills).toHaveBeenCalledWith(
|
|
492
|
-
expect.objectContaining({ query: "code review grep" }),
|
|
493
|
-
);
|
|
494
|
-
|
|
495
|
-
// Verify merged results contain both tool and skill
|
|
496
|
-
const data = result.data as { results: Array<Record<string, unknown>> };
|
|
497
|
-
expect(data.results).toHaveLength(2);
|
|
498
|
-
expect(data.results).toEqual(
|
|
499
|
-
expect.arrayContaining([
|
|
500
|
-
expect.objectContaining({ kind: "tool", name: "grep-helper" }),
|
|
501
|
-
expect.objectContaining({ kind: "skill", name: "code-review" }),
|
|
502
|
-
]),
|
|
503
|
-
);
|
|
504
|
-
});
|
|
505
|
-
});
|
|
506
|
-
});
|