@lobu/core 3.0.13 → 3.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/fixtures/mock-redis.d.ts +3 -0
- package/dist/__tests__/fixtures/mock-redis.d.ts.map +1 -1
- package/dist/__tests__/fixtures/mock-redis.js +12 -0
- package/dist/__tests__/fixtures/mock-redis.js.map +1 -1
- package/dist/__tests__/secret-refs.test.d.ts +2 -0
- package/dist/__tests__/secret-refs.test.d.ts.map +1 -0
- package/dist/__tests__/secret-refs.test.js +29 -0
- package/dist/__tests__/secret-refs.test.js.map +1 -0
- package/dist/agent-store.d.ts +33 -6
- package/dist/agent-store.d.ts.map +1 -1
- package/dist/agent-store.js.map +1 -1
- package/dist/api-types.d.ts +1 -5
- package/dist/api-types.d.ts.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/integration-types.d.ts +9 -1
- package/dist/integration-types.d.ts.map +1 -1
- package/dist/lobu-toml-schema.d.ts +168 -0
- package/dist/lobu-toml-schema.d.ts.map +1 -0
- package/dist/lobu-toml-schema.js +108 -0
- package/dist/lobu-toml-schema.js.map +1 -0
- package/dist/secret-refs.d.ts +11 -0
- package/dist/secret-refs.d.ts.map +1 -0
- package/dist/secret-refs.js +31 -0
- package/dist/secret-refs.js.map +1 -0
- package/dist/types.d.ts +29 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -3
- package/dist/types.js.map +1 -1
- package/package.json +14 -4
- package/src/__tests__/encryption.test.ts +0 -103
- package/src/__tests__/fixtures/factories.ts +0 -76
- package/src/__tests__/fixtures/index.ts +0 -9
- package/src/__tests__/fixtures/mock-fetch.ts +0 -32
- package/src/__tests__/fixtures/mock-queue.ts +0 -50
- package/src/__tests__/fixtures/mock-redis.ts +0 -300
- package/src/__tests__/retry.test.ts +0 -134
- package/src/__tests__/sanitize.test.ts +0 -158
- package/src/agent-policy.ts +0 -207
- package/src/agent-store.ts +0 -220
- package/src/api-types.ts +0 -256
- package/src/command-registry.ts +0 -73
- package/src/constants.ts +0 -60
- package/src/errors.ts +0 -220
- package/src/index.ts +0 -131
- package/src/integration-types.ts +0 -26
- package/src/logger.ts +0 -248
- package/src/modules.ts +0 -184
- package/src/otel.ts +0 -307
- package/src/plugin-types.ts +0 -46
- package/src/provider-config-types.ts +0 -54
- package/src/redis/base-store.ts +0 -200
- package/src/sentry.ts +0 -56
- package/src/trace.ts +0 -32
- package/src/types.ts +0 -440
- package/src/utils/encryption.ts +0 -78
- package/src/utils/env.ts +0 -50
- package/src/utils/json.ts +0 -37
- package/src/utils/lock.ts +0 -75
- package/src/utils/mcp-tool-instructions.ts +0 -5
- package/src/utils/retry.ts +0 -91
- package/src/utils/sanitize.ts +0 -127
- package/src/worker/auth.ts +0 -100
- package/src/worker/transport.ts +0 -107
- package/tsconfig.json +0 -20
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical zod schema for `lobu.toml`.
|
|
4
|
+
*
|
|
5
|
+
* This is the single source of truth for both the CLI (validation on disk)
|
|
6
|
+
* and the gateway (runtime loading). Uses zod@4.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.lobuConfigSchema = void 0;
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
// ── Provider ────────────────────────────────────────────────────────────────
|
|
12
|
+
const providerSchema = zod_1.z
|
|
13
|
+
.object({
|
|
14
|
+
id: zod_1.z.string(),
|
|
15
|
+
model: zod_1.z.string().optional(),
|
|
16
|
+
/** API key — literal value or `$ENV_VAR` reference. */
|
|
17
|
+
key: zod_1.z.string().optional(),
|
|
18
|
+
/** First-class durable secret reference. */
|
|
19
|
+
secret_ref: zod_1.z.string().optional(),
|
|
20
|
+
})
|
|
21
|
+
.refine((p) => !(p.key && p.secret_ref), {
|
|
22
|
+
message: "provider must set at most one of `key` or `secret_ref`",
|
|
23
|
+
});
|
|
24
|
+
// ── Connection ──────────────────────────────────────────────────────────────
|
|
25
|
+
const connectionSchema = zod_1.z.object({
|
|
26
|
+
type: zod_1.z.string(),
|
|
27
|
+
/** Platform-specific config (e.g. `{ botToken: "$BOT_TOKEN" }`). */
|
|
28
|
+
config: zod_1.z.record(zod_1.z.string(), zod_1.z.string()),
|
|
29
|
+
});
|
|
30
|
+
// ── MCP Server ──────────────────────────────────────────────────────────────
|
|
31
|
+
const mcpOAuthSchema = zod_1.z.object({
|
|
32
|
+
auth_url: zod_1.z.string(),
|
|
33
|
+
token_url: zod_1.z.string(),
|
|
34
|
+
client_id: zod_1.z.string().optional(),
|
|
35
|
+
client_secret: zod_1.z.string().optional(),
|
|
36
|
+
scopes: zod_1.z.array(zod_1.z.string()).optional(),
|
|
37
|
+
token_endpoint_auth_method: zod_1.z.string().optional(),
|
|
38
|
+
});
|
|
39
|
+
const mcpServerSchema = zod_1.z.object({
|
|
40
|
+
url: zod_1.z.string().optional(),
|
|
41
|
+
command: zod_1.z.string().optional(),
|
|
42
|
+
args: zod_1.z.array(zod_1.z.string()).optional(),
|
|
43
|
+
env: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
44
|
+
headers: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
|
|
45
|
+
oauth: mcpOAuthSchema.optional(),
|
|
46
|
+
});
|
|
47
|
+
// ── Skills ──────────────────────────────────────────────────────────────────
|
|
48
|
+
const skillsSchema = zod_1.z.object({
|
|
49
|
+
enabled: zod_1.z.array(zod_1.z.string()).default([]),
|
|
50
|
+
mcp: zod_1.z.record(zod_1.z.string(), mcpServerSchema).optional(),
|
|
51
|
+
});
|
|
52
|
+
// ── Network ─────────────────────────────────────────────────────────────────
|
|
53
|
+
const networkSchema = zod_1.z.object({
|
|
54
|
+
allowed: zod_1.z.array(zod_1.z.string()).optional(),
|
|
55
|
+
denied: zod_1.z.array(zod_1.z.string()).optional(),
|
|
56
|
+
});
|
|
57
|
+
// ── Tools ───────────────────────────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* Accepted `pre_approved` entry formats:
|
|
60
|
+
* /mcp/<id>/tools/<name>
|
|
61
|
+
* /mcp/<id>/tools/*
|
|
62
|
+
* Anything else will fail validation — typos like "gmail" silently produced
|
|
63
|
+
* a no-op grant previously.
|
|
64
|
+
*/
|
|
65
|
+
const MCP_TOOL_PATTERN = /^\/mcp\/[a-zA-Z0-9_-]+\/tools\/([a-zA-Z0-9_-]+|\*)$/;
|
|
66
|
+
const mcpToolPatternSchema = zod_1.z
|
|
67
|
+
.string()
|
|
68
|
+
.refine((value) => MCP_TOOL_PATTERN.test(value), {
|
|
69
|
+
message: 'pre_approved entries must match "/mcp/<mcp-id>/tools/<tool-name>" or "/mcp/<mcp-id>/tools/*"',
|
|
70
|
+
});
|
|
71
|
+
const toolsSchema = zod_1.z.object({
|
|
72
|
+
/**
|
|
73
|
+
* Operator override: MCP tool grant patterns that bypass the in-thread
|
|
74
|
+
* approval card. Synced to the grant store at deployment time. See
|
|
75
|
+
* {@link AgentSettings.preApprovedTools} for the runtime shape.
|
|
76
|
+
*/
|
|
77
|
+
pre_approved: zod_1.z.array(mcpToolPatternSchema).optional(),
|
|
78
|
+
/**
|
|
79
|
+
* Worker-side tool visibility filter. Patterns follow Claude Code's
|
|
80
|
+
* permission format: `Read`, `Bash(git:*)`, `mcp__github__*`, `*`.
|
|
81
|
+
*/
|
|
82
|
+
allowed: zod_1.z.array(zod_1.z.string()).optional(),
|
|
83
|
+
denied: zod_1.z.array(zod_1.z.string()).optional(),
|
|
84
|
+
/** If true, ONLY `allowed` tools are permitted (ignores worker defaults). */
|
|
85
|
+
strict: zod_1.z.boolean().optional(),
|
|
86
|
+
});
|
|
87
|
+
// ── Worker ──────────────────────────────────────────────────────────────────
|
|
88
|
+
const workerSchema = zod_1.z.object({
|
|
89
|
+
nix_packages: zod_1.z.array(zod_1.z.string()).optional(),
|
|
90
|
+
});
|
|
91
|
+
// ── Agent ───────────────────────────────────────────────────────────────────
|
|
92
|
+
const agentEntrySchema = zod_1.z.object({
|
|
93
|
+
name: zod_1.z.string(),
|
|
94
|
+
description: zod_1.z.string().optional(),
|
|
95
|
+
/** Path to agent content directory (IDENTITY.md, SOUL.md, USER.md, skills/). */
|
|
96
|
+
dir: zod_1.z.string(),
|
|
97
|
+
providers: zod_1.z.array(providerSchema).default([]),
|
|
98
|
+
connections: zod_1.z.array(connectionSchema).default([]),
|
|
99
|
+
skills: skillsSchema.default({ enabled: [] }),
|
|
100
|
+
network: networkSchema.optional(),
|
|
101
|
+
tools: toolsSchema.optional(),
|
|
102
|
+
worker: workerSchema.optional(),
|
|
103
|
+
});
|
|
104
|
+
// ── Top Level ───────────────────────────────────────────────────────────────
|
|
105
|
+
exports.lobuConfigSchema = zod_1.z.object({
|
|
106
|
+
agents: zod_1.z.record(zod_1.z.string().regex(/^[a-z0-9][a-z0-9-]*$/), agentEntrySchema),
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=lobu-toml-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lobu-toml-schema.js","sourceRoot":"","sources":["../src/lobu-toml-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type SecretRef = string;
|
|
2
|
+
export interface ParsedSecretRef {
|
|
3
|
+
raw: SecretRef;
|
|
4
|
+
scheme: string;
|
|
5
|
+
path: string;
|
|
6
|
+
fragment?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function parseSecretRef(value: string): ParsedSecretRef | null;
|
|
9
|
+
export declare function isSecretRef(value: unknown): value is SecretRef;
|
|
10
|
+
export declare function createBuiltinSecretRef(name: string): SecretRef;
|
|
11
|
+
//# sourceMappingURL=secret-refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-refs.d.ts","sourceRoot":"","sources":["../src/secret-refs.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAiBpE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAE9D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSecretRef = parseSecretRef;
|
|
4
|
+
exports.isSecretRef = isSecretRef;
|
|
5
|
+
exports.createBuiltinSecretRef = createBuiltinSecretRef;
|
|
6
|
+
const SECRET_REF_RE = /^([a-z][a-z0-9+.-]*):\/\/(.+)$/i;
|
|
7
|
+
function parseSecretRef(value) {
|
|
8
|
+
const match = value.match(SECRET_REF_RE);
|
|
9
|
+
if (!match)
|
|
10
|
+
return null;
|
|
11
|
+
const scheme = match[1]?.toLowerCase();
|
|
12
|
+
const remainder = match[2];
|
|
13
|
+
if (!scheme || !remainder)
|
|
14
|
+
return null;
|
|
15
|
+
const [path, fragment] = remainder.split("#", 2);
|
|
16
|
+
if (!path)
|
|
17
|
+
return null;
|
|
18
|
+
return {
|
|
19
|
+
raw: value,
|
|
20
|
+
scheme,
|
|
21
|
+
path,
|
|
22
|
+
...(fragment ? { fragment } : {}),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function isSecretRef(value) {
|
|
26
|
+
return typeof value === "string" && parseSecretRef(value) !== null;
|
|
27
|
+
}
|
|
28
|
+
function createBuiltinSecretRef(name) {
|
|
29
|
+
return `secret://${name}`;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=secret-refs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-refs.js","sourceRoot":"","sources":["../src/secret-refs.ts"],"names":[],"mappings":";;AAWA,wCAiBC;AAED,kCAEC;AAED,wDAEC;AA3BD,MAAM,aAAa,GAAG,iCAAiC,CAAC;AAExD,SAAgB,cAAc,CAAC,KAAa;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,OAAO;QACL,GAAG,EAAE,KAAK;QACV,MAAM;QACN,IAAI;QACJ,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,SAAgB,WAAW,CAAC,KAAc;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,cAAc,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AACrE,CAAC;AAED,SAAgB,sBAAsB,CAAC,IAAY;IACjD,OAAO,YAAY,IAAI,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
import type { SecretRef } from "./secret-refs";
|
|
2
|
+
export type ModelSelectionMode = "auto" | "pinned";
|
|
3
|
+
/**
|
|
4
|
+
* Model selection state for an agent.
|
|
5
|
+
* `auto` lets the worker pick a default from installed providers;
|
|
6
|
+
* `pinned` forces a specific model reference (e.g. "openai/gpt-5").
|
|
7
|
+
*/
|
|
8
|
+
export interface ModelSelectionState {
|
|
9
|
+
mode: ModelSelectionMode;
|
|
10
|
+
pinnedModel?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Per-provider preferred model for auto mode, keyed by provider id. */
|
|
13
|
+
export type ProviderModelPreferences = Record<string, string>;
|
|
1
14
|
/**
|
|
2
15
|
* Represents a provider installed for a specific agent.
|
|
3
16
|
* Stored in AgentSettings.installedProviders as an ordered array (index 0 = primary).
|
|
@@ -25,22 +38,37 @@ export interface CliBackendConfig {
|
|
|
25
38
|
/**
|
|
26
39
|
* Unified authentication profile for any model provider.
|
|
27
40
|
* Stored in AgentSettings.authProfiles as an ordered array (index 0 = primary).
|
|
41
|
+
*
|
|
42
|
+
* **Invariant:** at any point in time, a profile has **exactly one** credential
|
|
43
|
+
* source set — either `credentialRef` (persisted profiles resolved through the
|
|
44
|
+
* secret store) or `credential` (in-memory runtime profiles for SDK-embedded
|
|
45
|
+
* use). The same rule applies to `metadata.refreshToken` / `refreshTokenRef`.
|
|
46
|
+
* The persistence layer is responsible for never writing plaintext credentials
|
|
47
|
+
* into the stored JSON.
|
|
28
48
|
*/
|
|
29
49
|
export interface AuthProfile {
|
|
30
50
|
id: string;
|
|
31
51
|
provider: string;
|
|
32
52
|
model: string;
|
|
33
|
-
credential
|
|
53
|
+
/** Runtime-only resolved credential value. Never persisted. */
|
|
54
|
+
credential?: string;
|
|
55
|
+
/** Durable secret reference for the credential. */
|
|
56
|
+
credentialRef?: SecretRef;
|
|
34
57
|
label: string;
|
|
35
58
|
authType: "oauth" | "device-code" | "api-key";
|
|
36
59
|
metadata?: {
|
|
37
60
|
email?: string;
|
|
38
61
|
expiresAt?: number;
|
|
62
|
+
/** Runtime-only resolved refresh token value. Never persisted. */
|
|
39
63
|
refreshToken?: string;
|
|
64
|
+
/** Durable secret reference for the refresh token. */
|
|
65
|
+
refreshTokenRef?: SecretRef;
|
|
40
66
|
accountId?: string;
|
|
41
67
|
};
|
|
42
68
|
createdAt: number;
|
|
43
69
|
}
|
|
70
|
+
/** True if the profile has any credential source (resolved or ref). */
|
|
71
|
+
export declare function hasCredentialSource(profile: AuthProfile): boolean;
|
|
44
72
|
export interface SessionContext {
|
|
45
73
|
platform: string;
|
|
46
74
|
channelId: string;
|
|
@@ -124,18 +152,11 @@ export interface SkillConfig {
|
|
|
124
152
|
mcpServers?: SkillMcpServer[];
|
|
125
153
|
/** System packages declared by the skill (nix) */
|
|
126
154
|
nixPackages?: string[];
|
|
127
|
-
/** Network domains the skill needs access to (legacy flat list) */
|
|
128
|
-
permissions?: string[];
|
|
129
155
|
/** Network access policy declared by the skill */
|
|
130
156
|
networkConfig?: {
|
|
131
157
|
allowedDomains?: string[];
|
|
132
158
|
deniedDomains?: string[];
|
|
133
159
|
};
|
|
134
|
-
/** Tool permission policy declared by the skill */
|
|
135
|
-
toolPermissions?: {
|
|
136
|
-
allow?: string[];
|
|
137
|
-
deny?: string[];
|
|
138
|
-
};
|
|
139
160
|
/** AI providers the skill requires */
|
|
140
161
|
providers?: string[];
|
|
141
162
|
/** Preferred model for this skill (e.g., "anthropic/claude-opus-4") */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// ============================================================================
|
|
3
|
-
// Provider Catalog Types
|
|
4
|
-
// ============================================================================
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasCredentialSource = hasCredentialSource;
|
|
4
|
+
/** True if the profile has any credential source (resolved or ref). */
|
|
5
|
+
function hasCredentialSource(profile) {
|
|
6
|
+
return Boolean(profile.credential || profile.credentialRef);
|
|
7
|
+
}
|
|
6
8
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;AAyFA,kDAEC;AAHD,uEAAuE;AACvE,SAAgB,mBAAmB,CAAC,OAAoB;IACtD,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;AAC9D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobu/core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.19",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Core types and utilities for Lobu agent platform",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/lobu-ai/lobu.git",
|
|
9
|
+
"directory": "packages/core"
|
|
10
|
+
},
|
|
6
11
|
"main": "dist/index.js",
|
|
7
12
|
"types": "dist/index.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
8
16
|
"exports": {
|
|
9
17
|
".": {
|
|
10
18
|
"types": "./dist/index.d.ts",
|
|
11
|
-
"bun": "./src/index.ts",
|
|
12
19
|
"import": "./dist/index.js",
|
|
13
20
|
"require": "./dist/index.js"
|
|
14
21
|
},
|
|
15
22
|
"./testing": {
|
|
16
|
-
"
|
|
23
|
+
"types": "./dist/__tests__/fixtures/index.d.ts",
|
|
24
|
+
"import": "./dist/__tests__/fixtures/index.js",
|
|
25
|
+
"require": "./dist/__tests__/fixtures/index.js"
|
|
17
26
|
}
|
|
18
27
|
},
|
|
19
28
|
"scripts": {
|
|
@@ -30,7 +39,8 @@
|
|
|
30
39
|
"@opentelemetry/semantic-conventions": "^1.28.0",
|
|
31
40
|
"@sentry/node": "^10.23.0",
|
|
32
41
|
"ioredis": "^5.4.1",
|
|
33
|
-
"winston": "^3.17.0"
|
|
42
|
+
"winston": "^3.17.0",
|
|
43
|
+
"zod": "^4.1.12"
|
|
34
44
|
},
|
|
35
45
|
"devDependencies": {
|
|
36
46
|
"@types/bun": "1.2.11",
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
-
import { decrypt, encrypt } from "../utils/encryption";
|
|
3
|
-
|
|
4
|
-
describe("encryption", () => {
|
|
5
|
-
let originalKey: string | undefined;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
originalKey = process.env.ENCRYPTION_KEY;
|
|
9
|
-
// 32-byte hex key
|
|
10
|
-
process.env.ENCRYPTION_KEY =
|
|
11
|
-
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
afterEach(() => {
|
|
15
|
-
if (originalKey !== undefined) {
|
|
16
|
-
process.env.ENCRYPTION_KEY = originalKey;
|
|
17
|
-
} else {
|
|
18
|
-
delete process.env.ENCRYPTION_KEY;
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("encrypt/decrypt round-trip preserves plaintext", () => {
|
|
23
|
-
const plaintext = "hello world";
|
|
24
|
-
const encrypted = encrypt(plaintext);
|
|
25
|
-
expect(decrypt(encrypted)).toBe(plaintext);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test("encrypt/decrypt works with empty string", () => {
|
|
29
|
-
const encrypted = encrypt("");
|
|
30
|
-
expect(decrypt(encrypted)).toBe("");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("encrypt/decrypt works with unicode", () => {
|
|
34
|
-
const text = "こんにちは 🌍 émojis";
|
|
35
|
-
expect(decrypt(encrypt(text))).toBe(text);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("encrypt/decrypt works with long text", () => {
|
|
39
|
-
const text = "x".repeat(10_000);
|
|
40
|
-
expect(decrypt(encrypt(text))).toBe(text);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test("each encryption produces different ciphertext (random IV)", () => {
|
|
44
|
-
const plaintext = "same input";
|
|
45
|
-
const a = encrypt(plaintext);
|
|
46
|
-
const b = encrypt(plaintext);
|
|
47
|
-
expect(a).not.toBe(b);
|
|
48
|
-
// Both should still decrypt to the same value
|
|
49
|
-
expect(decrypt(a)).toBe(plaintext);
|
|
50
|
-
expect(decrypt(b)).toBe(plaintext);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test("encrypted format is iv:tag:ciphertext (3 hex parts)", () => {
|
|
54
|
-
const encrypted = encrypt("test");
|
|
55
|
-
const parts = encrypted.split(":");
|
|
56
|
-
expect(parts).toHaveLength(3);
|
|
57
|
-
// Each part should be valid hex
|
|
58
|
-
for (const part of parts) {
|
|
59
|
-
expect(part).toMatch(/^[0-9a-f]+$/);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test("decrypt throws on invalid format (wrong number of parts)", () => {
|
|
64
|
-
expect(() => decrypt("only-one-part")).toThrow("Invalid encrypted format");
|
|
65
|
-
expect(() => decrypt("a:b")).toThrow("Invalid encrypted format");
|
|
66
|
-
expect(() => decrypt("a:b:c:d")).toThrow("Invalid encrypted format");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test("decrypt throws on tampered ciphertext", () => {
|
|
70
|
-
const encrypted = encrypt("secret");
|
|
71
|
-
const parts = encrypted.split(":");
|
|
72
|
-
// Tamper with the ciphertext
|
|
73
|
-
parts[2] = "ff".repeat(parts[2]!.length / 2);
|
|
74
|
-
expect(() => decrypt(parts.join(":"))).toThrow();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test("throws when ENCRYPTION_KEY is missing", () => {
|
|
78
|
-
delete process.env.ENCRYPTION_KEY;
|
|
79
|
-
expect(() => encrypt("test")).toThrow(
|
|
80
|
-
"ENCRYPTION_KEY environment variable is required"
|
|
81
|
-
);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test("throws when ENCRYPTION_KEY has wrong length", () => {
|
|
85
|
-
process.env.ENCRYPTION_KEY = "too-short";
|
|
86
|
-
expect(() => encrypt("test")).toThrow("base64 or hex encoded 32-byte key");
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
test("accepts base64-encoded 32-byte key", () => {
|
|
90
|
-
// 32 bytes → 44 chars in base64
|
|
91
|
-
process.env.ENCRYPTION_KEY = Buffer.alloc(32, 7).toString("base64");
|
|
92
|
-
const encrypted = encrypt("base64 key test");
|
|
93
|
-
expect(decrypt(encrypted)).toBe("base64 key test");
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test("rejects utf8 32-byte key (only base64 and hex accepted)", () => {
|
|
97
|
-
process.env.ENCRYPTION_KEY = "abcdefghijklmnopqrstuvwxyz012345";
|
|
98
|
-
// 32 ASCII chars = 32 bytes in utf8, but utf8 keys are no longer accepted
|
|
99
|
-
expect(() => encrypt("utf8 key test")).toThrow(
|
|
100
|
-
"base64 or hex encoded 32-byte key"
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared factory functions for test data.
|
|
3
|
-
*
|
|
4
|
-
* All factories accept a partial override object so tests only specify
|
|
5
|
-
* the fields they care about while getting sensible defaults for the rest.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { InstructionContext } from "../../types";
|
|
9
|
-
|
|
10
|
-
// Re-export WorkerConfig shape (worker package owns the interface).
|
|
11
|
-
// We duplicate a minimal version here to avoid a circular dependency.
|
|
12
|
-
export interface TestWorkerConfig {
|
|
13
|
-
sessionKey: string;
|
|
14
|
-
userId: string;
|
|
15
|
-
agentId: string;
|
|
16
|
-
channelId: string;
|
|
17
|
-
conversationId: string;
|
|
18
|
-
userPrompt: string;
|
|
19
|
-
responseChannel: string;
|
|
20
|
-
responseId: string;
|
|
21
|
-
platform: string;
|
|
22
|
-
agentOptions: string;
|
|
23
|
-
teamId?: string;
|
|
24
|
-
workspace: { baseDirectory: string };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function createWorkerConfig(
|
|
28
|
-
overrides: Partial<TestWorkerConfig> = {}
|
|
29
|
-
): TestWorkerConfig {
|
|
30
|
-
return {
|
|
31
|
-
sessionKey: "test-session-key",
|
|
32
|
-
userId: "U1234567890",
|
|
33
|
-
agentId: "agent-test",
|
|
34
|
-
channelId: "C1234567890",
|
|
35
|
-
conversationId: "1234567890.123456",
|
|
36
|
-
userPrompt: Buffer.from("Test user prompt").toString("base64"),
|
|
37
|
-
responseChannel: "C1234567890",
|
|
38
|
-
responseId: "1234567890.123457",
|
|
39
|
-
platform: "slack",
|
|
40
|
-
agentOptions: JSON.stringify({
|
|
41
|
-
model: "claude-sonnet-4-20250514",
|
|
42
|
-
max_tokens: 8192,
|
|
43
|
-
}),
|
|
44
|
-
teamId: "T1234567890",
|
|
45
|
-
workspace: { baseDirectory: "/tmp/test-workspace" },
|
|
46
|
-
...overrides,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function createInstructionContext(
|
|
51
|
-
overrides: Partial<InstructionContext> = {}
|
|
52
|
-
): InstructionContext {
|
|
53
|
-
return {
|
|
54
|
-
userId: "U1234567890",
|
|
55
|
-
agentId: "agent-test",
|
|
56
|
-
sessionKey: "test-session-key",
|
|
57
|
-
workingDirectory: "/tmp/test-workspace/test-thread",
|
|
58
|
-
availableProjects: [],
|
|
59
|
-
...overrides,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function createMockJob(overrides: Record<string, any> = {}): {
|
|
64
|
-
id: string;
|
|
65
|
-
data: Record<string, any>;
|
|
66
|
-
} {
|
|
67
|
-
return {
|
|
68
|
-
id: `job-${Date.now()}-${Math.random().toString(36).substring(7)}`,
|
|
69
|
-
data: {
|
|
70
|
-
sessionKey: "test-session-key",
|
|
71
|
-
userId: "U123",
|
|
72
|
-
prompt: "test prompt",
|
|
73
|
-
...overrides,
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
createInstructionContext,
|
|
3
|
-
createMockJob,
|
|
4
|
-
createWorkerConfig,
|
|
5
|
-
type TestWorkerConfig,
|
|
6
|
-
} from "./factories";
|
|
7
|
-
export { mockFetch } from "./mock-fetch";
|
|
8
|
-
export { MockMessageQueue } from "./mock-queue";
|
|
9
|
-
export { MockRedisClient } from "./mock-redis";
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified fetch mock for testing.
|
|
3
|
-
* Replaces TestHelpers.mockFetch from worker setup.ts.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Install a mock global.fetch that returns pre-configured responses.
|
|
8
|
-
* Returns a cleanup function that restores the original fetch.
|
|
9
|
-
*
|
|
10
|
-
* @param responses - Map of URL → response body (JSON-serialisable).
|
|
11
|
-
* Unmatched URLs return `{ success: true }`.
|
|
12
|
-
*/
|
|
13
|
-
export function mockFetch(responses: Record<string, any> = {}): () => void {
|
|
14
|
-
const originalFetch = globalThis.fetch;
|
|
15
|
-
|
|
16
|
-
globalThis.fetch = (async (
|
|
17
|
-
url: string | URL | Request,
|
|
18
|
-
_options?: RequestInit
|
|
19
|
-
) => {
|
|
20
|
-
const urlString = url instanceof Request ? url.url : url.toString();
|
|
21
|
-
|
|
22
|
-
const body = responses[urlString] ?? { success: true };
|
|
23
|
-
return new Response(JSON.stringify(body), {
|
|
24
|
-
status: 200,
|
|
25
|
-
headers: { "Content-Type": "application/json" },
|
|
26
|
-
});
|
|
27
|
-
}) as typeof fetch;
|
|
28
|
-
|
|
29
|
-
return () => {
|
|
30
|
-
globalThis.fetch = originalFetch;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified mock message queue for testing.
|
|
3
|
-
* Replaces MockMessageQueue from gateway setup.ts.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { MockRedisClient } from "./mock-redis";
|
|
7
|
-
|
|
8
|
-
export class MockMessageQueue {
|
|
9
|
-
private queues = new Map<string, any[]>();
|
|
10
|
-
private workers = new Map<string, (job: any) => Promise<void>>();
|
|
11
|
-
private redisClient = new MockRedisClient();
|
|
12
|
-
|
|
13
|
-
async createQueue(queueName: string): Promise<void> {
|
|
14
|
-
if (!this.queues.has(queueName)) {
|
|
15
|
-
this.queues.set(queueName, []);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async work(
|
|
20
|
-
queueName: string,
|
|
21
|
-
handler: (job: any) => Promise<void>,
|
|
22
|
-
_options?: { startPaused?: boolean }
|
|
23
|
-
): Promise<void> {
|
|
24
|
-
this.workers.set(queueName, handler);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async addJob(queueName: string, job: any): Promise<void> {
|
|
28
|
-
const queue = this.queues.get(queueName);
|
|
29
|
-
if (!queue) throw new Error(`Queue ${queueName} does not exist`);
|
|
30
|
-
queue.push(job);
|
|
31
|
-
|
|
32
|
-
const handler = this.workers.get(queueName);
|
|
33
|
-
if (handler) await handler(job);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
getRedisClient(): MockRedisClient {
|
|
37
|
-
return this.redisClient;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// --- Test helpers ---
|
|
41
|
-
|
|
42
|
-
getQueue(queueName: string): any[] | undefined {
|
|
43
|
-
return this.queues.get(queueName);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
clearQueues(): void {
|
|
47
|
-
this.queues.clear();
|
|
48
|
-
this.workers.clear();
|
|
49
|
-
}
|
|
50
|
-
}
|