@lumenflow/packs-sidekick 3.6.6
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/LICENSE +661 -0
- package/README.md +194 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +10 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest-schema.d.ts +48 -0
- package/dist/manifest-schema.d.ts.map +1 -0
- package/dist/manifest-schema.js +177 -0
- package/dist/manifest-schema.js.map +1 -0
- package/dist/manifest.d.ts +26 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +297 -0
- package/dist/manifest.js.map +1 -0
- package/dist/pack-registration.d.ts +14 -0
- package/dist/pack-registration.d.ts.map +1 -0
- package/dist/pack-registration.js +79 -0
- package/dist/pack-registration.js.map +1 -0
- package/dist/tool-impl/channel-tools.d.ts +3 -0
- package/dist/tool-impl/channel-tools.d.ts.map +1 -0
- package/dist/tool-impl/channel-tools.js +169 -0
- package/dist/tool-impl/channel-tools.js.map +1 -0
- package/dist/tool-impl/index.d.ts +2 -0
- package/dist/tool-impl/index.d.ts.map +1 -0
- package/dist/tool-impl/index.js +4 -0
- package/dist/tool-impl/index.js.map +1 -0
- package/dist/tool-impl/memory-tools.d.ts +3 -0
- package/dist/tool-impl/memory-tools.d.ts.map +1 -0
- package/dist/tool-impl/memory-tools.js +137 -0
- package/dist/tool-impl/memory-tools.js.map +1 -0
- package/dist/tool-impl/routine-tools.d.ts +3 -0
- package/dist/tool-impl/routine-tools.d.ts.map +1 -0
- package/dist/tool-impl/routine-tools.js +145 -0
- package/dist/tool-impl/routine-tools.js.map +1 -0
- package/dist/tool-impl/shared.d.ts +34 -0
- package/dist/tool-impl/shared.d.ts.map +1 -0
- package/dist/tool-impl/shared.js +89 -0
- package/dist/tool-impl/shared.js.map +1 -0
- package/dist/tool-impl/storage.d.ts +87 -0
- package/dist/tool-impl/storage.d.ts.map +1 -0
- package/dist/tool-impl/storage.js +191 -0
- package/dist/tool-impl/storage.js.map +1 -0
- package/dist/tool-impl/system-tools.d.ts +3 -0
- package/dist/tool-impl/system-tools.d.ts.map +1 -0
- package/dist/tool-impl/system-tools.js +116 -0
- package/dist/tool-impl/system-tools.js.map +1 -0
- package/dist/tool-impl/task-tools.d.ts +3 -0
- package/dist/tool-impl/task-tools.d.ts.map +1 -0
- package/dist/tool-impl/task-tools.js +215 -0
- package/dist/tool-impl/task-tools.js.map +1 -0
- package/dist/tools/channel-tools.d.ts +4 -0
- package/dist/tools/channel-tools.d.ts.map +1 -0
- package/dist/tools/channel-tools.js +41 -0
- package/dist/tools/channel-tools.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/memory-tools.d.ts +4 -0
- package/dist/tools/memory-tools.d.ts.map +1 -0
- package/dist/tools/memory-tools.js +41 -0
- package/dist/tools/memory-tools.js.map +1 -0
- package/dist/tools/routine-tools.d.ts +4 -0
- package/dist/tools/routine-tools.d.ts.map +1 -0
- package/dist/tools/routine-tools.js +41 -0
- package/dist/tools/routine-tools.js.map +1 -0
- package/dist/tools/system-tools.d.ts +4 -0
- package/dist/tools/system-tools.d.ts.map +1 -0
- package/dist/tools/system-tools.js +36 -0
- package/dist/tools/system-tools.js.map +1 -0
- package/dist/tools/task-tools.d.ts +5 -0
- package/dist/tools/task-tools.d.ts.map +1 -0
- package/dist/tools/task-tools.js +48 -0
- package/dist/tools/task-tools.js.map +1 -0
- package/dist/tools/types.d.ts +40 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +24 -0
- package/dist/tools/types.js.map +1 -0
- package/manifest.yaml +406 -0
- package/package.json +55 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { getStoragePort } from './storage.js';
|
|
4
|
+
import { asInteger, asNonEmptyString, asStringArray, buildAuditEvent, createId, failure, includesText, isDryRun, matchesTags, nowIso, success, toRecord, } from './shared.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Constants
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const TOOL_NAMES = {
|
|
9
|
+
STORE: 'memory:store',
|
|
10
|
+
RECALL: 'memory:recall',
|
|
11
|
+
FORGET: 'memory:forget',
|
|
12
|
+
};
|
|
13
|
+
const VALID_MEMORY_TYPES = ['fact', 'preference', 'note'];
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Helpers
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
function asMemoryType(value) {
|
|
18
|
+
return VALID_MEMORY_TYPES.includes(value) ? value : null;
|
|
19
|
+
}
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// memory:store
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
async function memoryStoreTool(input, context) {
|
|
24
|
+
const parsed = toRecord(input);
|
|
25
|
+
const type = asMemoryType(parsed.type);
|
|
26
|
+
const content = asNonEmptyString(parsed.content);
|
|
27
|
+
if (!type) {
|
|
28
|
+
return failure('INVALID_INPUT', 'type must be one of fact, preference, note.');
|
|
29
|
+
}
|
|
30
|
+
if (!content) {
|
|
31
|
+
return failure('INVALID_INPUT', 'content is required.');
|
|
32
|
+
}
|
|
33
|
+
const memory = {
|
|
34
|
+
id: createId('mem'),
|
|
35
|
+
type,
|
|
36
|
+
content,
|
|
37
|
+
tags: asStringArray(parsed.tags),
|
|
38
|
+
created_at: nowIso(),
|
|
39
|
+
updated_at: nowIso(),
|
|
40
|
+
};
|
|
41
|
+
if (isDryRun(parsed)) {
|
|
42
|
+
return success({
|
|
43
|
+
dry_run: true,
|
|
44
|
+
memory: memory,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
const storage = getStoragePort();
|
|
48
|
+
await storage.withLock(async () => {
|
|
49
|
+
const memories = await storage.readStore('memories');
|
|
50
|
+
memories.push(memory);
|
|
51
|
+
await storage.writeStore('memories', memories);
|
|
52
|
+
await storage.appendAudit(buildAuditEvent({
|
|
53
|
+
tool: TOOL_NAMES.STORE,
|
|
54
|
+
op: 'create',
|
|
55
|
+
context,
|
|
56
|
+
ids: [memory.id],
|
|
57
|
+
}));
|
|
58
|
+
});
|
|
59
|
+
return success({ memory: memory });
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// memory:recall
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
async function memoryRecallTool(input, _context) {
|
|
65
|
+
const parsed = toRecord(input);
|
|
66
|
+
const query = asNonEmptyString(parsed.query);
|
|
67
|
+
const type = asMemoryType(parsed.type);
|
|
68
|
+
const tags = asStringArray(parsed.tags);
|
|
69
|
+
const limit = asInteger(parsed.limit);
|
|
70
|
+
const storage = getStoragePort();
|
|
71
|
+
const memories = await storage.readStore('memories');
|
|
72
|
+
const filtered = memories.filter((memory) => {
|
|
73
|
+
if (type && memory.type !== type) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (!matchesTags(tags, memory.tags)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
if (!includesText(memory.content, query)) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
});
|
|
84
|
+
const sorted = filtered.toSorted((a, b) => Date.parse(b.updated_at) - Date.parse(a.updated_at));
|
|
85
|
+
const items = limit && limit > 0 ? sorted.slice(0, limit) : sorted;
|
|
86
|
+
return success({
|
|
87
|
+
items: items,
|
|
88
|
+
count: items.length,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// memory:forget
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
async function memoryForgetTool(input, context) {
|
|
95
|
+
const parsed = toRecord(input);
|
|
96
|
+
const id = asNonEmptyString(parsed.id);
|
|
97
|
+
if (!id) {
|
|
98
|
+
return failure('INVALID_INPUT', 'id is required.');
|
|
99
|
+
}
|
|
100
|
+
const storage = getStoragePort();
|
|
101
|
+
const memories = await storage.readStore('memories');
|
|
102
|
+
const exists = memories.some((memory) => memory.id === id);
|
|
103
|
+
if (!exists) {
|
|
104
|
+
return failure('NOT_FOUND', `memory ${id} was not found.`);
|
|
105
|
+
}
|
|
106
|
+
if (isDryRun(parsed)) {
|
|
107
|
+
return success({ dry_run: true, deleted_id: id });
|
|
108
|
+
}
|
|
109
|
+
await storage.withLock(async () => {
|
|
110
|
+
const latest = await storage.readStore('memories');
|
|
111
|
+
const remaining = latest.filter((memory) => memory.id !== id);
|
|
112
|
+
await storage.writeStore('memories', remaining);
|
|
113
|
+
await storage.appendAudit(buildAuditEvent({
|
|
114
|
+
tool: TOOL_NAMES.FORGET,
|
|
115
|
+
op: 'delete',
|
|
116
|
+
context,
|
|
117
|
+
ids: [id],
|
|
118
|
+
}));
|
|
119
|
+
});
|
|
120
|
+
return success({ deleted_id: id });
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Router (default export)
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
export default async function memoryTools(input, context) {
|
|
126
|
+
switch (context?.tool_name) {
|
|
127
|
+
case TOOL_NAMES.STORE:
|
|
128
|
+
return memoryStoreTool(input, context);
|
|
129
|
+
case TOOL_NAMES.RECALL:
|
|
130
|
+
return memoryRecallTool(input, context);
|
|
131
|
+
case TOOL_NAMES.FORGET:
|
|
132
|
+
return memoryForgetTool(input, context);
|
|
133
|
+
default:
|
|
134
|
+
return failure('UNKNOWN_TOOL', `Unknown memory tool: ${context?.tool_name ?? 'unknown'}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=memory-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-tools.js","sourceRoot":"","sources":["../../tool-impl/memory-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routine-tools.d.ts","sourceRoot":"","sources":["../../tool-impl/routine-tools.ts"],"names":[],"mappings":"AAIA,OAAO,EAUL,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAmKrB,wBAA8B,YAAY,CACxC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,UAAU,CAAC,CAWrB"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { getStoragePort } from './storage.js';
|
|
4
|
+
import { asInteger, asNonEmptyString, buildAuditEvent, createId, failure, isDryRun, nowIso, success, toRecord, } from './shared.js';
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Constants
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const TOOL_NAMES = {
|
|
9
|
+
CREATE: 'routine:create',
|
|
10
|
+
LIST: 'routine:list',
|
|
11
|
+
RUN: 'routine:run',
|
|
12
|
+
};
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Helpers
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
function normalizeSteps(value) {
|
|
17
|
+
if (!Array.isArray(value)) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const steps = [];
|
|
21
|
+
for (const candidate of value) {
|
|
22
|
+
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const record = candidate;
|
|
26
|
+
const tool = asNonEmptyString(record.tool);
|
|
27
|
+
if (!tool) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const input = record.input && typeof record.input === 'object' && !Array.isArray(record.input)
|
|
31
|
+
? record.input
|
|
32
|
+
: {};
|
|
33
|
+
steps.push({ tool, input });
|
|
34
|
+
}
|
|
35
|
+
return steps;
|
|
36
|
+
}
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// routine:create
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
async function routineCreateTool(input, context) {
|
|
41
|
+
const parsed = toRecord(input);
|
|
42
|
+
const name = asNonEmptyString(parsed.name);
|
|
43
|
+
const steps = normalizeSteps(parsed.steps);
|
|
44
|
+
if (!name) {
|
|
45
|
+
return failure('INVALID_INPUT', 'name is required.');
|
|
46
|
+
}
|
|
47
|
+
if (steps.length === 0) {
|
|
48
|
+
return failure('INVALID_INPUT', 'steps must include at least one tool step.');
|
|
49
|
+
}
|
|
50
|
+
const now = nowIso();
|
|
51
|
+
const routine = {
|
|
52
|
+
id: createId('routine'),
|
|
53
|
+
name,
|
|
54
|
+
steps,
|
|
55
|
+
created_at: now,
|
|
56
|
+
updated_at: now,
|
|
57
|
+
};
|
|
58
|
+
if (isDryRun(parsed)) {
|
|
59
|
+
return success({
|
|
60
|
+
dry_run: true,
|
|
61
|
+
routine: routine,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const storage = getStoragePort();
|
|
65
|
+
await storage.withLock(async () => {
|
|
66
|
+
const routines = await storage.readStore('routines');
|
|
67
|
+
routines.push(routine);
|
|
68
|
+
await storage.writeStore('routines', routines);
|
|
69
|
+
await storage.appendAudit(buildAuditEvent({
|
|
70
|
+
tool: TOOL_NAMES.CREATE,
|
|
71
|
+
op: 'create',
|
|
72
|
+
context,
|
|
73
|
+
ids: [routine.id],
|
|
74
|
+
}));
|
|
75
|
+
});
|
|
76
|
+
return success({ routine: routine });
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// routine:list
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
async function routineListTool(input, _context) {
|
|
82
|
+
const parsed = toRecord(input);
|
|
83
|
+
const limit = asInteger(parsed.limit);
|
|
84
|
+
const storage = getStoragePort();
|
|
85
|
+
const routines = await storage.readStore('routines');
|
|
86
|
+
const sorted = routines.toSorted((a, b) => Date.parse(b.updated_at) - Date.parse(a.updated_at));
|
|
87
|
+
const items = limit && limit > 0 ? sorted.slice(0, limit) : sorted;
|
|
88
|
+
return success({
|
|
89
|
+
items: items,
|
|
90
|
+
count: items.length,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
// routine:run (PLAN-ONLY -- does NOT execute tool steps)
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
async function routineRunTool(input, context) {
|
|
97
|
+
const parsed = toRecord(input);
|
|
98
|
+
const id = asNonEmptyString(parsed.id);
|
|
99
|
+
if (!id) {
|
|
100
|
+
return failure('INVALID_INPUT', 'id is required.');
|
|
101
|
+
}
|
|
102
|
+
const storage = getStoragePort();
|
|
103
|
+
const routines = await storage.readStore('routines');
|
|
104
|
+
const routine = routines.find((r) => r.id === id);
|
|
105
|
+
if (!routine) {
|
|
106
|
+
return failure('NOT_FOUND', `routine ${id} was not found.`);
|
|
107
|
+
}
|
|
108
|
+
await storage.appendAudit(buildAuditEvent({
|
|
109
|
+
tool: TOOL_NAMES.RUN,
|
|
110
|
+
op: 'execute',
|
|
111
|
+
context,
|
|
112
|
+
ids: [id],
|
|
113
|
+
details: { plan_only: true },
|
|
114
|
+
}));
|
|
115
|
+
return success({
|
|
116
|
+
routine_id: routine.id,
|
|
117
|
+
name: routine.name,
|
|
118
|
+
plan_only: true,
|
|
119
|
+
plan: routine.steps.map((step, index) => ({
|
|
120
|
+
index,
|
|
121
|
+
tool: step.tool,
|
|
122
|
+
input: step.input,
|
|
123
|
+
})),
|
|
124
|
+
governance: {
|
|
125
|
+
dispatch_required: true,
|
|
126
|
+
execution: 'No tool steps were executed by routine:run. This endpoint only returns a plan.',
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Router (default export)
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
export default async function routineTools(input, context) {
|
|
134
|
+
switch (context?.tool_name) {
|
|
135
|
+
case TOOL_NAMES.CREATE:
|
|
136
|
+
return routineCreateTool(input, context);
|
|
137
|
+
case TOOL_NAMES.LIST:
|
|
138
|
+
return routineListTool(input, context);
|
|
139
|
+
case TOOL_NAMES.RUN:
|
|
140
|
+
return routineRunTool(input, context);
|
|
141
|
+
default:
|
|
142
|
+
return failure('UNKNOWN_TOOL', `Unknown routine tool: ${context?.tool_name ?? 'unknown'}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=routine-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routine-tools.js","sourceRoot":"","sources":["../../tool-impl/routine-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AuditEvent } from './storage.js';
|
|
2
|
+
export interface ToolContextLike {
|
|
3
|
+
tool_name?: string;
|
|
4
|
+
receipt_id?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ToolOutput {
|
|
7
|
+
success: boolean;
|
|
8
|
+
data?: Record<string, unknown>;
|
|
9
|
+
error?: {
|
|
10
|
+
code: string;
|
|
11
|
+
message: string;
|
|
12
|
+
details?: Record<string, unknown>;
|
|
13
|
+
};
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export declare function toRecord(input: unknown): Record<string, unknown>;
|
|
17
|
+
export declare function asNonEmptyString(value: unknown): string | null;
|
|
18
|
+
export declare function asStringArray(value: unknown): string[];
|
|
19
|
+
export declare function asInteger(value: unknown): number | null;
|
|
20
|
+
export declare function isDryRun(input: Record<string, unknown>): boolean;
|
|
21
|
+
export declare function nowIso(): string;
|
|
22
|
+
export declare function createId(prefix: string): string;
|
|
23
|
+
export declare function failure(code: string, message: string, details?: Record<string, unknown>): ToolOutput;
|
|
24
|
+
export declare function success(data: Record<string, unknown>): ToolOutput;
|
|
25
|
+
export declare function matchesTags(requiredTags: string[], candidateTags: string[]): boolean;
|
|
26
|
+
export declare function includesText(haystack: string, needle: string | null): boolean;
|
|
27
|
+
export declare function buildAuditEvent(input: {
|
|
28
|
+
tool: string;
|
|
29
|
+
op: AuditEvent['op'];
|
|
30
|
+
context?: ToolContextLike;
|
|
31
|
+
ids?: string[];
|
|
32
|
+
details?: Record<string, unknown>;
|
|
33
|
+
}): AuditEvent;
|
|
34
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../tool-impl/shared.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKhE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAM9D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAYtD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CASvD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAEhE;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,UAAU,CASZ;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAKjE;AAED,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAMpF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAK7E;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,GAAG,UAAU,CAUb"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
import { randomBytes } from 'node:crypto';
|
|
4
|
+
export function toRecord(input) {
|
|
5
|
+
if (input && typeof input === 'object' && !Array.isArray(input)) {
|
|
6
|
+
return input;
|
|
7
|
+
}
|
|
8
|
+
return {};
|
|
9
|
+
}
|
|
10
|
+
export function asNonEmptyString(value) {
|
|
11
|
+
if (typeof value !== 'string') {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const trimmed = value.trim();
|
|
15
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
16
|
+
}
|
|
17
|
+
export function asStringArray(value) {
|
|
18
|
+
if (!Array.isArray(value)) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const items = [];
|
|
22
|
+
for (const entry of value) {
|
|
23
|
+
const normalized = asNonEmptyString(entry);
|
|
24
|
+
if (normalized) {
|
|
25
|
+
items.push(normalized);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return [...new Set(items)];
|
|
29
|
+
}
|
|
30
|
+
export function asInteger(value) {
|
|
31
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
32
|
+
return Math.trunc(value);
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === 'string') {
|
|
35
|
+
const parsed = Number.parseInt(value, 10);
|
|
36
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
export function isDryRun(input) {
|
|
41
|
+
return input.dry_run === true;
|
|
42
|
+
}
|
|
43
|
+
export function nowIso() {
|
|
44
|
+
return new Date().toISOString();
|
|
45
|
+
}
|
|
46
|
+
export function createId(prefix) {
|
|
47
|
+
return `${prefix}-${randomBytes(4).toString('hex')}`;
|
|
48
|
+
}
|
|
49
|
+
export function failure(code, message, details) {
|
|
50
|
+
return {
|
|
51
|
+
success: false,
|
|
52
|
+
error: {
|
|
53
|
+
code,
|
|
54
|
+
message,
|
|
55
|
+
...(details ? { details } : {}),
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function success(data) {
|
|
60
|
+
return {
|
|
61
|
+
success: true,
|
|
62
|
+
data,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export function matchesTags(requiredTags, candidateTags) {
|
|
66
|
+
if (requiredTags.length === 0) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
const candidateSet = new Set(candidateTags.map((tag) => tag.toLowerCase()));
|
|
70
|
+
return requiredTags.every((tag) => candidateSet.has(tag.toLowerCase()));
|
|
71
|
+
}
|
|
72
|
+
export function includesText(haystack, needle) {
|
|
73
|
+
if (!needle) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return haystack.toLowerCase().includes(needle.toLowerCase());
|
|
77
|
+
}
|
|
78
|
+
export function buildAuditEvent(input) {
|
|
79
|
+
return {
|
|
80
|
+
id: createId('evt'),
|
|
81
|
+
ts: nowIso(),
|
|
82
|
+
tool: input.tool,
|
|
83
|
+
op: input.op,
|
|
84
|
+
actor: input.context?.receipt_id,
|
|
85
|
+
ids: input.ids,
|
|
86
|
+
details: input.details,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../tool-impl/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export type TaskPriority = 'P0' | 'P1' | 'P2' | 'P3';
|
|
2
|
+
export type TaskStatus = 'pending' | 'done';
|
|
3
|
+
export type MemoryType = 'fact' | 'preference' | 'note';
|
|
4
|
+
export interface TaskRecord {
|
|
5
|
+
id: string;
|
|
6
|
+
title: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
priority: TaskPriority;
|
|
9
|
+
status: TaskStatus;
|
|
10
|
+
tags: string[];
|
|
11
|
+
due_at?: string;
|
|
12
|
+
note?: string;
|
|
13
|
+
created_at: string;
|
|
14
|
+
updated_at: string;
|
|
15
|
+
completed_at?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface MemoryRecord {
|
|
18
|
+
id: string;
|
|
19
|
+
type: MemoryType;
|
|
20
|
+
content: string;
|
|
21
|
+
tags: string[];
|
|
22
|
+
created_at: string;
|
|
23
|
+
updated_at: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ChannelRecord {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
created_at: string;
|
|
29
|
+
updated_at: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ChannelMessageRecord {
|
|
32
|
+
id: string;
|
|
33
|
+
channel_id: string;
|
|
34
|
+
sender: string;
|
|
35
|
+
content: string;
|
|
36
|
+
created_at: string;
|
|
37
|
+
}
|
|
38
|
+
export interface RoutineStepRecord {
|
|
39
|
+
tool: string;
|
|
40
|
+
input: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
export interface RoutineRecord {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
steps: RoutineStepRecord[];
|
|
46
|
+
created_at: string;
|
|
47
|
+
updated_at: string;
|
|
48
|
+
}
|
|
49
|
+
export interface SidekickStores {
|
|
50
|
+
tasks: TaskRecord[];
|
|
51
|
+
memories: MemoryRecord[];
|
|
52
|
+
channels: ChannelRecord[];
|
|
53
|
+
messages: ChannelMessageRecord[];
|
|
54
|
+
routines: RoutineRecord[];
|
|
55
|
+
}
|
|
56
|
+
export type StoreName = keyof SidekickStores;
|
|
57
|
+
export interface AuditEvent {
|
|
58
|
+
id: string;
|
|
59
|
+
ts: string;
|
|
60
|
+
tool: string;
|
|
61
|
+
op: 'create' | 'read' | 'update' | 'delete' | 'execute' | 'export';
|
|
62
|
+
actor?: string;
|
|
63
|
+
ids?: string[];
|
|
64
|
+
details?: Record<string, unknown>;
|
|
65
|
+
}
|
|
66
|
+
export interface StoragePort {
|
|
67
|
+
getRootDir(): string;
|
|
68
|
+
withLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
69
|
+
readStore<K extends StoreName>(store: K): Promise<SidekickStores[K]>;
|
|
70
|
+
writeStore<K extends StoreName>(store: K, data: SidekickStores[K]): Promise<void>;
|
|
71
|
+
appendAudit(event: AuditEvent): Promise<void>;
|
|
72
|
+
readAuditEvents(): Promise<AuditEvent[]>;
|
|
73
|
+
}
|
|
74
|
+
export declare class FsStoragePort implements StoragePort {
|
|
75
|
+
private readonly rootDir;
|
|
76
|
+
constructor(rootDir?: string);
|
|
77
|
+
getRootDir(): string;
|
|
78
|
+
withLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
79
|
+
readStore<K extends StoreName>(store: K): Promise<SidekickStores[K]>;
|
|
80
|
+
writeStore<K extends StoreName>(store: K, data: SidekickStores[K]): Promise<void>;
|
|
81
|
+
appendAudit(event: AuditEvent): Promise<void>;
|
|
82
|
+
readAuditEvents(): Promise<AuditEvent[]>;
|
|
83
|
+
}
|
|
84
|
+
export declare function setDefaultStoragePort(port: StoragePort): void;
|
|
85
|
+
export declare function getStoragePort(): StoragePort;
|
|
86
|
+
export declare function runWithStoragePort<T>(port: StoragePort, fn: () => Promise<T>): Promise<T>;
|
|
87
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../tool-impl/storage.ts"],"names":[],"mappings":"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"}
|