universal-agent-memory 0.6.2 → 0.6.3

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.
Files changed (69) hide show
  1. package/dist/benchmarks/agents/naive-agent.d.ts +60 -0
  2. package/dist/benchmarks/agents/naive-agent.d.ts.map +1 -0
  3. package/dist/benchmarks/agents/naive-agent.js +144 -0
  4. package/dist/benchmarks/agents/naive-agent.js.map +1 -0
  5. package/dist/benchmarks/agents/uam-agent.d.ts +167 -0
  6. package/dist/benchmarks/agents/uam-agent.d.ts.map +1 -0
  7. package/dist/benchmarks/agents/uam-agent.js +386 -0
  8. package/dist/benchmarks/agents/uam-agent.js.map +1 -0
  9. package/dist/benchmarks/benchmark.d.ts +328 -0
  10. package/dist/benchmarks/benchmark.d.ts.map +1 -0
  11. package/dist/benchmarks/benchmark.js +104 -0
  12. package/dist/benchmarks/benchmark.js.map +1 -0
  13. package/dist/benchmarks/execution-verifier.d.ts +41 -0
  14. package/dist/benchmarks/execution-verifier.d.ts.map +1 -0
  15. package/dist/benchmarks/execution-verifier.js +301 -0
  16. package/dist/benchmarks/execution-verifier.js.map +1 -0
  17. package/dist/benchmarks/hierarchical-prompting.d.ts +37 -0
  18. package/dist/benchmarks/hierarchical-prompting.d.ts.map +1 -0
  19. package/dist/benchmarks/hierarchical-prompting.js +260 -0
  20. package/dist/benchmarks/hierarchical-prompting.js.map +1 -0
  21. package/dist/benchmarks/improved-benchmark.d.ts +88 -0
  22. package/dist/benchmarks/improved-benchmark.d.ts.map +1 -0
  23. package/dist/benchmarks/improved-benchmark.js +533 -0
  24. package/dist/benchmarks/improved-benchmark.js.map +1 -0
  25. package/dist/benchmarks/index.d.ts +10 -0
  26. package/dist/benchmarks/index.d.ts.map +1 -0
  27. package/dist/benchmarks/index.js +10 -0
  28. package/dist/benchmarks/index.js.map +1 -0
  29. package/dist/benchmarks/multi-turn-agent.d.ts +44 -0
  30. package/dist/benchmarks/multi-turn-agent.d.ts.map +1 -0
  31. package/dist/benchmarks/multi-turn-agent.js +235 -0
  32. package/dist/benchmarks/multi-turn-agent.js.map +1 -0
  33. package/dist/benchmarks/runner.d.ts +2 -0
  34. package/dist/benchmarks/runner.d.ts.map +1 -0
  35. package/dist/benchmarks/runner.js +2 -0
  36. package/dist/benchmarks/runner.js.map +1 -0
  37. package/dist/benchmarks/tasks.d.ts +19 -0
  38. package/dist/benchmarks/tasks.d.ts.map +1 -0
  39. package/dist/benchmarks/tasks.js +371 -0
  40. package/dist/benchmarks/tasks.js.map +1 -0
  41. package/dist/index.d.ts +5 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +4 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/memory/backends/qdrant-cloud.d.ts +1 -1
  46. package/dist/memory/backends/qdrant-cloud.d.ts.map +1 -1
  47. package/dist/memory/backends/qdrant-cloud.js +6 -4
  48. package/dist/memory/backends/qdrant-cloud.js.map +1 -1
  49. package/dist/memory/dynamic-retrieval.d.ts +26 -0
  50. package/dist/memory/dynamic-retrieval.d.ts.map +1 -0
  51. package/dist/memory/dynamic-retrieval.js +378 -0
  52. package/dist/memory/dynamic-retrieval.js.map +1 -0
  53. package/dist/memory/embeddings.d.ts +82 -0
  54. package/dist/memory/embeddings.d.ts.map +1 -0
  55. package/dist/memory/embeddings.js +297 -0
  56. package/dist/memory/embeddings.js.map +1 -0
  57. package/dist/memory/task-classifier.d.ts +33 -0
  58. package/dist/memory/task-classifier.d.ts.map +1 -0
  59. package/dist/memory/task-classifier.js +277 -0
  60. package/dist/memory/task-classifier.js.map +1 -0
  61. package/dist/utils/rate-limiter.d.ts +62 -0
  62. package/dist/utils/rate-limiter.d.ts.map +1 -0
  63. package/dist/utils/rate-limiter.js +150 -0
  64. package/dist/utils/rate-limiter.js.map +1 -0
  65. package/dist/utils/validate-json.d.ts +52 -0
  66. package/dist/utils/validate-json.d.ts.map +1 -0
  67. package/dist/utils/validate-json.js +99 -0
  68. package/dist/utils/validate-json.js.map +1 -0
  69. package/package.json +2 -1
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Configuration options for the RateLimiter.
3
+ */
4
+ export interface RateLimiterConfig {
5
+ maxRequests: number;
6
+ windowMs: number;
7
+ }
8
+ export declare class RateLimiter {
9
+ private static readonly configSchema;
10
+ private static readonly clientIdSchema;
11
+ private readonly maxRequests;
12
+ private readonly windowMs;
13
+ private readonly requests;
14
+ /**
15
+ * Creates a new RateLimiter instance.
16
+ *
17
+ * @param config - Configuration for request limits and window size
18
+ * @returns A configured RateLimiter instance
19
+ * @throws AppError when config is invalid
20
+ */
21
+ constructor(config: RateLimiterConfig);
22
+ /**
23
+ * Checks if a request from the given client is allowed and records it if so.
24
+ *
25
+ * @param clientId - Identifier for the calling client
26
+ * @returns True if the request is allowed; otherwise false
27
+ * @throws AppError when clientId is invalid
28
+ */
29
+ isAllowed(clientId: string): boolean;
30
+ /**
31
+ * Returns the remaining number of requests for a client in the current window.
32
+ *
33
+ * @param clientId - Identifier for the calling client
34
+ * @returns Remaining number of requests in the window
35
+ * @throws AppError when clientId is invalid
36
+ */
37
+ getRemainingRequests(clientId: string): number;
38
+ /**
39
+ * Resets rate limiting for a single client or all clients.
40
+ *
41
+ * @param clientId - Optional client identifier to reset; omit to reset all
42
+ * @returns Nothing
43
+ */
44
+ reset(clientId?: string): void;
45
+ /**
46
+ * Removes expired timestamps and deletes empty client entries.
47
+ *
48
+ * @param now - Current timestamp used as reference
49
+ * @param clientId - Optional client identifier to scope cleanup
50
+ * @returns Nothing
51
+ */
52
+ private cleanupExpiredEntries;
53
+ /**
54
+ * Ensures the client identifier is valid.
55
+ *
56
+ * @param clientId - Identifier to validate
57
+ * @returns Nothing
58
+ * @throws AppError when clientId is invalid
59
+ */
60
+ private ensureValidClientId;
61
+ }
62
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/utils/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AASD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAejC;IAEH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAKE;IAExC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAE7D;;;;;;OAMG;gBACS,MAAM,EAAE,iBAAiB;IAcrC;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAgBpC;;;;;;OAMG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAc9C;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAU9B;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAoC7B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;CAU5B"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * A sliding-window rate limiter that tracks requests per client.
3
+ */
4
+ import { z } from 'zod';
5
+ import { AppError } from './validate-json.js';
6
+ export class RateLimiter {
7
+ static configSchema = z.object({
8
+ maxRequests: z
9
+ .number({
10
+ required_error: 'maxRequests is required',
11
+ invalid_type_error: 'maxRequests must be a number',
12
+ })
13
+ .int('maxRequests must be an integer')
14
+ .positive('maxRequests must be greater than 0'),
15
+ windowMs: z
16
+ .number({
17
+ required_error: 'windowMs is required',
18
+ invalid_type_error: 'windowMs must be a number',
19
+ })
20
+ .int('windowMs must be an integer')
21
+ .positive('windowMs must be greater than 0'),
22
+ });
23
+ static clientIdSchema = z
24
+ .string({
25
+ required_error: 'clientId is required',
26
+ invalid_type_error: 'clientId must be a string',
27
+ })
28
+ .min(1, 'clientId must not be empty');
29
+ maxRequests;
30
+ windowMs;
31
+ requests = new Map();
32
+ /**
33
+ * Creates a new RateLimiter instance.
34
+ *
35
+ * @param config - Configuration for request limits and window size
36
+ * @returns A configured RateLimiter instance
37
+ * @throws AppError when config is invalid
38
+ */
39
+ constructor(config) {
40
+ const validation = RateLimiter.configSchema.safeParse(config);
41
+ if (!validation.success) {
42
+ throw new AppError('Invalid rate limiter configuration', 'INVALID_CONFIG', {
43
+ errors: validation.error.errors,
44
+ received: config,
45
+ });
46
+ }
47
+ this.maxRequests = validation.data.maxRequests;
48
+ this.windowMs = validation.data.windowMs;
49
+ }
50
+ /**
51
+ * Checks if a request from the given client is allowed and records it if so.
52
+ *
53
+ * @param clientId - Identifier for the calling client
54
+ * @returns True if the request is allowed; otherwise false
55
+ * @throws AppError when clientId is invalid
56
+ */
57
+ isAllowed(clientId) {
58
+ this.ensureValidClientId(clientId);
59
+ const now = Date.now();
60
+ this.cleanupExpiredEntries(now, clientId);
61
+ const timestamps = this.requests.get(clientId) ?? [];
62
+ if (timestamps.length < this.maxRequests) {
63
+ timestamps.push(now);
64
+ this.requests.set(clientId, timestamps);
65
+ return true;
66
+ }
67
+ return false;
68
+ }
69
+ /**
70
+ * Returns the remaining number of requests for a client in the current window.
71
+ *
72
+ * @param clientId - Identifier for the calling client
73
+ * @returns Remaining number of requests in the window
74
+ * @throws AppError when clientId is invalid
75
+ */
76
+ getRemainingRequests(clientId) {
77
+ this.ensureValidClientId(clientId);
78
+ const now = Date.now();
79
+ this.cleanupExpiredEntries(now, clientId);
80
+ const timestamps = this.requests.get(clientId);
81
+ if (!timestamps) {
82
+ return this.maxRequests;
83
+ }
84
+ return Math.max(0, this.maxRequests - timestamps.length);
85
+ }
86
+ /**
87
+ * Resets rate limiting for a single client or all clients.
88
+ *
89
+ * @param clientId - Optional client identifier to reset; omit to reset all
90
+ * @returns Nothing
91
+ */
92
+ reset(clientId) {
93
+ if (clientId) {
94
+ this.ensureValidClientId(clientId);
95
+ this.requests.delete(clientId);
96
+ return;
97
+ }
98
+ this.requests.clear();
99
+ }
100
+ /**
101
+ * Removes expired timestamps and deletes empty client entries.
102
+ *
103
+ * @param now - Current timestamp used as reference
104
+ * @param clientId - Optional client identifier to scope cleanup
105
+ * @returns Nothing
106
+ */
107
+ cleanupExpiredEntries(now, clientId) {
108
+ const cutoff = now - this.windowMs;
109
+ if (clientId) {
110
+ const timestamps = this.requests.get(clientId);
111
+ if (!timestamps) {
112
+ return;
113
+ }
114
+ const validTimestamps = timestamps.filter((timestamp) => timestamp > cutoff);
115
+ if (validTimestamps.length === 0) {
116
+ this.requests.delete(clientId);
117
+ }
118
+ else {
119
+ this.requests.set(clientId, validTimestamps);
120
+ }
121
+ return;
122
+ }
123
+ for (const [id, timestamps] of this.requests.entries()) {
124
+ const validTimestamps = timestamps.filter((timestamp) => timestamp > cutoff);
125
+ if (validTimestamps.length === 0) {
126
+ this.requests.delete(id);
127
+ }
128
+ else {
129
+ this.requests.set(id, validTimestamps);
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * Ensures the client identifier is valid.
135
+ *
136
+ * @param clientId - Identifier to validate
137
+ * @returns Nothing
138
+ * @throws AppError when clientId is invalid
139
+ */
140
+ ensureValidClientId(clientId) {
141
+ const validation = RateLimiter.clientIdSchema.safeParse(clientId);
142
+ if (!validation.success) {
143
+ throw new AppError('Invalid client identifier', 'INVALID_CLIENT_ID', {
144
+ errors: validation.error.errors,
145
+ received: clientId,
146
+ });
147
+ }
148
+ }
149
+ }
150
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/utils/rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Custom error class for application-level errors with detailed context.
3
+ * Extends the built-in Error class to provide additional metadata.
4
+ */
5
+ export declare class AppError extends Error {
6
+ /** Error code for programmatic handling */
7
+ readonly code: string;
8
+ /** Additional context about the error */
9
+ readonly context?: Record<string, unknown>;
10
+ /**
11
+ * Creates a new AppError instance.
12
+ *
13
+ * @param message - Human-readable error message
14
+ * @param code - Error code for programmatic handling
15
+ * @param context - Optional additional context
16
+ */
17
+ constructor(message: string, code: string, context?: Record<string, unknown>);
18
+ }
19
+ /**
20
+ * Validates that a string is valid JSON and parses it.
21
+ *
22
+ * Uses zod for runtime validation to ensure the input is a valid string
23
+ * before attempting to parse. The parsed result is then validated
24
+ * against a permissive schema that accepts any valid JSON value.
25
+ *
26
+ * @param input - The string to validate and parse as JSON
27
+ * @returns The parsed JSON value (object, array, string, number, boolean, or null)
28
+ * @throws AppError with code 'INVALID_INPUT' if input is not a string
29
+ * @throws AppError with code 'JSON_PARSE_ERROR' if the string is not valid JSON
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Parse a valid JSON object
34
+ * const obj = validateAndParseJSON('{"name": "test", "value": 42}');
35
+ * // Returns: { name: "test", value: 42 }
36
+ *
37
+ * // Parse a valid JSON array
38
+ * const arr = validateAndParseJSON('[1, 2, 3]');
39
+ * // Returns: [1, 2, 3]
40
+ *
41
+ * // Invalid JSON throws AppError
42
+ * try {
43
+ * validateAndParseJSON('{invalid}');
44
+ * } catch (error) {
45
+ * if (error instanceof AppError) {
46
+ * console.log(error.code); // 'JSON_PARSE_ERROR'
47
+ * }
48
+ * }
49
+ * ```
50
+ */
51
+ export declare function validateAndParseJSON(input: string): Promise<unknown>;
52
+ //# sourceMappingURL=validate-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-json.d.ts","sourceRoot":"","sources":["../../src/utils/validate-json.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE3C;;;;;;OAMG;gBAED,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAYpC;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiD1E"}
@@ -0,0 +1,99 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Custom error class for application-level errors with detailed context.
4
+ * Extends the built-in Error class to provide additional metadata.
5
+ */
6
+ export class AppError extends Error {
7
+ /** Error code for programmatic handling */
8
+ code;
9
+ /** Additional context about the error */
10
+ context;
11
+ /**
12
+ * Creates a new AppError instance.
13
+ *
14
+ * @param message - Human-readable error message
15
+ * @param code - Error code for programmatic handling
16
+ * @param context - Optional additional context
17
+ */
18
+ constructor(message, code, context) {
19
+ super(message);
20
+ this.name = 'AppError';
21
+ this.code = code;
22
+ this.context = context;
23
+ // Maintains proper stack trace for where error was thrown (V8 engines)
24
+ if (Error.captureStackTrace) {
25
+ Error.captureStackTrace(this, AppError);
26
+ }
27
+ }
28
+ }
29
+ /**
30
+ * Zod schema for validating that a value is valid JSON.
31
+ * Accepts any valid JSON value (object, array, string, number, boolean, null).
32
+ */
33
+ const jsonSchema = z.unknown();
34
+ /**
35
+ * Validates that a string is valid JSON and parses it.
36
+ *
37
+ * Uses zod for runtime validation to ensure the input is a valid string
38
+ * before attempting to parse. The parsed result is then validated
39
+ * against a permissive schema that accepts any valid JSON value.
40
+ *
41
+ * @param input - The string to validate and parse as JSON
42
+ * @returns The parsed JSON value (object, array, string, number, boolean, or null)
43
+ * @throws AppError with code 'INVALID_INPUT' if input is not a string
44
+ * @throws AppError with code 'JSON_PARSE_ERROR' if the string is not valid JSON
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * // Parse a valid JSON object
49
+ * const obj = validateAndParseJSON('{"name": "test", "value": 42}');
50
+ * // Returns: { name: "test", value: 42 }
51
+ *
52
+ * // Parse a valid JSON array
53
+ * const arr = validateAndParseJSON('[1, 2, 3]');
54
+ * // Returns: [1, 2, 3]
55
+ *
56
+ * // Invalid JSON throws AppError
57
+ * try {
58
+ * validateAndParseJSON('{invalid}');
59
+ * } catch (error) {
60
+ * if (error instanceof AppError) {
61
+ * console.log(error.code); // 'JSON_PARSE_ERROR'
62
+ * }
63
+ * }
64
+ * ```
65
+ */
66
+ export async function validateAndParseJSON(input) {
67
+ // Validate input is a string using zod
68
+ const stringSchema = z.string({
69
+ required_error: 'Input is required',
70
+ invalid_type_error: 'Input must be a string',
71
+ });
72
+ const validationResult = stringSchema.safeParse(input);
73
+ if (!validationResult.success) {
74
+ throw new AppError('Input must be a valid string', 'INVALID_INPUT', {
75
+ errors: validationResult.error.errors,
76
+ receivedType: typeof input,
77
+ });
78
+ }
79
+ // Attempt to parse the JSON string
80
+ let parsed;
81
+ try {
82
+ parsed = JSON.parse(validationResult.data);
83
+ }
84
+ catch (error) {
85
+ throw new AppError(`Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`, 'JSON_PARSE_ERROR', {
86
+ input: input.length > 100 ? `${input.substring(0, 100)}...` : input,
87
+ originalError: error instanceof Error ? error.message : String(error),
88
+ });
89
+ }
90
+ // Validate the parsed result with zod (accepts any valid JSON value)
91
+ const parseResult = jsonSchema.safeParse(parsed);
92
+ if (!parseResult.success) {
93
+ throw new AppError('Parsed value failed schema validation', 'SCHEMA_VALIDATION_ERROR', {
94
+ errors: parseResult.error.errors,
95
+ });
96
+ }
97
+ return parseResult.data;
98
+ }
99
+ //# sourceMappingURL=validate-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-json.js","sourceRoot":"","sources":["../../src/utils/validate-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjC,2CAA2C;IAClC,IAAI,CAAS;IACtB,yCAAyC;IAChC,OAAO,CAA2B;IAE3C;;;;;;OAMG;IACH,YACE,OAAe,EACf,IAAY,EACZ,OAAiC;QAEjC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,uEAAuE;QACvE,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAa;IACtD,uCAAuC;IACvC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;QAC5B,cAAc,EAAE,mBAAmB;QACnC,kBAAkB,EAAE,wBAAwB;KAC7C,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAEvD,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,QAAQ,CAChB,8BAA8B,EAC9B,eAAe,EACf;YACE,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAM;YACrC,YAAY,EAAE,OAAO,KAAK;SAC3B,CACF,CAAC;IACJ,CAAC;IAED,mCAAmC;IACnC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CAChB,yBAAyB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,EACnF,kBAAkB,EAClB;YACE,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;YACnE,aAAa,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SACtE,CACF,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAEjD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,QAAQ,CAChB,uCAAuC,EACvC,yBAAyB,EACzB;YACE,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM;SACjC,CACF,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC,IAAI,CAAC;AAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-agent-memory",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Universal AI agent memory system - CLAUDE.md templates, memory, worktrees for Claude Code, Factory.AI, VSCode, OpenCode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -78,6 +78,7 @@
78
78
  "eslint": "^8.56.0",
79
79
  "fake-indexeddb": "^6.0.0",
80
80
  "prettier": "^3.2.4",
81
+ "tsx": "^4.21.0",
81
82
  "typescript": "^5.3.3",
82
83
  "vitest": "^1.2.0"
83
84
  },