@lovelybunch/core 1.0.66 → 1.0.68
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/logging/index.d.ts +30 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +33 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/jsonl-writer.d.ts +76 -0
- package/dist/logging/jsonl-writer.d.ts.map +1 -0
- package/dist/logging/jsonl-writer.js +252 -0
- package/dist/logging/jsonl-writer.js.map +1 -0
- package/dist/logging/kinds.d.ts +224 -0
- package/dist/logging/kinds.d.ts.map +1 -0
- package/dist/logging/kinds.js +207 -0
- package/dist/logging/kinds.js.map +1 -0
- package/dist/logging/logger.d.ts +42 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +85 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/redact.d.ts +30 -0
- package/dist/logging/redact.d.ts.map +1 -0
- package/dist/logging/redact.js +145 -0
- package/dist/logging/redact.js.map +1 -0
- package/dist/logging/types.d.ts +74 -0
- package/dist/logging/types.d.ts.map +1 -0
- package/dist/logging/types.js +6 -0
- package/dist/logging/types.js.map +1 -0
- package/package.json +6 -2
- package/dist/workflow-templates.d.ts +0 -6
- package/dist/workflow-templates.d.ts.map +0 -1
- package/dist/workflow-templates.js +0 -61
- package/dist/workflow-templates.js.map +0 -1
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event kind taxonomy for Coconut activity logging
|
|
3
|
+
* @module logging/kinds
|
|
4
|
+
*
|
|
5
|
+
* Event kinds follow a hierarchical naming convention:
|
|
6
|
+
* {entity}.{action}.{qualifier}
|
|
7
|
+
*
|
|
8
|
+
* Examples:
|
|
9
|
+
* - proposal.create
|
|
10
|
+
* - agent.session.start
|
|
11
|
+
* - code.commit
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Proposal-related events
|
|
15
|
+
*/
|
|
16
|
+
export const ProposalKinds = {
|
|
17
|
+
CREATE: "proposal.create",
|
|
18
|
+
UPDATE: "proposal.update",
|
|
19
|
+
RUN_START: "proposal.run.start",
|
|
20
|
+
RUN_END: "proposal.run.end",
|
|
21
|
+
STATUS_CHANGE: "proposal.status.change",
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Agent and session events
|
|
25
|
+
*/
|
|
26
|
+
export const AgentKinds = {
|
|
27
|
+
SESSION_START: "agent.session.start",
|
|
28
|
+
SESSION_STDOUT: "agent.session.stdout",
|
|
29
|
+
SESSION_END: "agent.session.end",
|
|
30
|
+
SESSION_ERROR: "agent.session.error",
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Code and git-related events
|
|
34
|
+
*/
|
|
35
|
+
export const CodeKinds = {
|
|
36
|
+
EDIT: "code.edit",
|
|
37
|
+
COMMIT: "code.commit",
|
|
38
|
+
BRANCH_CREATE: "code.branch.create",
|
|
39
|
+
WORKTREE_ADD: "code.worktree.add",
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Knowledge base events
|
|
43
|
+
*/
|
|
44
|
+
export const KnowledgeKinds = {
|
|
45
|
+
CREATE: "knowledge.create",
|
|
46
|
+
UPDATE: "knowledge.update",
|
|
47
|
+
DELETE: "knowledge.delete",
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Job scheduling and execution events
|
|
51
|
+
*/
|
|
52
|
+
export const JobKinds = {
|
|
53
|
+
SCHEDULE: "job.schedule",
|
|
54
|
+
RUN_START: "job.run.start",
|
|
55
|
+
RUN_END: "job.run.end",
|
|
56
|
+
RUN_ERROR: "job.run.error",
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Resource management events
|
|
60
|
+
*/
|
|
61
|
+
export const ResourceKinds = {
|
|
62
|
+
UPLOAD: "resource.upload",
|
|
63
|
+
DELETE: "resource.delete",
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Authentication events (when auth is enabled)
|
|
67
|
+
*/
|
|
68
|
+
export const AuthKinds = {
|
|
69
|
+
LOGIN: "auth.login",
|
|
70
|
+
LOGOUT: "auth.logout",
|
|
71
|
+
API_KEY_USE: "auth.api.key.use",
|
|
72
|
+
API_KEY_CREATE: "auth.api.key.create",
|
|
73
|
+
API_KEY_DELETE: "auth.api.key.delete",
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* All event kinds in a single object
|
|
77
|
+
*/
|
|
78
|
+
export const EventKinds = {
|
|
79
|
+
...ProposalKinds,
|
|
80
|
+
...AgentKinds,
|
|
81
|
+
...CodeKinds,
|
|
82
|
+
...KnowledgeKinds,
|
|
83
|
+
...JobKinds,
|
|
84
|
+
...ResourceKinds,
|
|
85
|
+
...AuthKinds,
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Helper to validate if a string is a known event kind
|
|
89
|
+
*/
|
|
90
|
+
export function isValidEventKind(kind) {
|
|
91
|
+
return Object.values(EventKinds).includes(kind);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Registry of event kinds with metadata
|
|
95
|
+
* Useful for documentation and validation
|
|
96
|
+
*/
|
|
97
|
+
export const EventKindRegistry = {
|
|
98
|
+
[ProposalKinds.CREATE]: {
|
|
99
|
+
description: "A new change proposal was created",
|
|
100
|
+
tags: ["proposal"],
|
|
101
|
+
},
|
|
102
|
+
[ProposalKinds.UPDATE]: {
|
|
103
|
+
description: "A change proposal was updated",
|
|
104
|
+
tags: ["proposal"],
|
|
105
|
+
},
|
|
106
|
+
[ProposalKinds.RUN_START]: {
|
|
107
|
+
description: "Implementation of a proposal started",
|
|
108
|
+
tags: ["proposal", "execution"],
|
|
109
|
+
},
|
|
110
|
+
[ProposalKinds.RUN_END]: {
|
|
111
|
+
description: "Implementation of a proposal completed",
|
|
112
|
+
tags: ["proposal", "execution"],
|
|
113
|
+
},
|
|
114
|
+
[ProposalKinds.STATUS_CHANGE]: {
|
|
115
|
+
description: "Proposal status changed",
|
|
116
|
+
tags: ["proposal"],
|
|
117
|
+
},
|
|
118
|
+
[AgentKinds.SESSION_START]: {
|
|
119
|
+
description: "Agent session started",
|
|
120
|
+
tags: ["agent", "session"],
|
|
121
|
+
},
|
|
122
|
+
[AgentKinds.SESSION_STDOUT]: {
|
|
123
|
+
description: "Agent session output",
|
|
124
|
+
tags: ["agent", "session"],
|
|
125
|
+
},
|
|
126
|
+
[AgentKinds.SESSION_END]: {
|
|
127
|
+
description: "Agent session ended",
|
|
128
|
+
tags: ["agent", "session"],
|
|
129
|
+
},
|
|
130
|
+
[AgentKinds.SESSION_ERROR]: {
|
|
131
|
+
description: "Agent session encountered an error",
|
|
132
|
+
tags: ["agent", "session", "error"],
|
|
133
|
+
},
|
|
134
|
+
[CodeKinds.EDIT]: {
|
|
135
|
+
description: "Code was edited",
|
|
136
|
+
tags: ["code"],
|
|
137
|
+
},
|
|
138
|
+
[CodeKinds.COMMIT]: {
|
|
139
|
+
description: "Git commit was created",
|
|
140
|
+
tags: ["code", "git"],
|
|
141
|
+
},
|
|
142
|
+
[CodeKinds.BRANCH_CREATE]: {
|
|
143
|
+
description: "Git branch was created",
|
|
144
|
+
tags: ["code", "git"],
|
|
145
|
+
},
|
|
146
|
+
[CodeKinds.WORKTREE_ADD]: {
|
|
147
|
+
description: "Git worktree was added",
|
|
148
|
+
tags: ["code", "git"],
|
|
149
|
+
},
|
|
150
|
+
[KnowledgeKinds.CREATE]: {
|
|
151
|
+
description: "Knowledge base entry created",
|
|
152
|
+
tags: ["knowledge"],
|
|
153
|
+
},
|
|
154
|
+
[KnowledgeKinds.UPDATE]: {
|
|
155
|
+
description: "Knowledge base entry updated",
|
|
156
|
+
tags: ["knowledge"],
|
|
157
|
+
},
|
|
158
|
+
[KnowledgeKinds.DELETE]: {
|
|
159
|
+
description: "Knowledge base entry deleted",
|
|
160
|
+
tags: ["knowledge"],
|
|
161
|
+
},
|
|
162
|
+
[JobKinds.SCHEDULE]: {
|
|
163
|
+
description: "Job was scheduled",
|
|
164
|
+
tags: ["job"],
|
|
165
|
+
},
|
|
166
|
+
[JobKinds.RUN_START]: {
|
|
167
|
+
description: "Job run started",
|
|
168
|
+
tags: ["job", "execution"],
|
|
169
|
+
},
|
|
170
|
+
[JobKinds.RUN_END]: {
|
|
171
|
+
description: "Job run completed",
|
|
172
|
+
tags: ["job", "execution"],
|
|
173
|
+
},
|
|
174
|
+
[JobKinds.RUN_ERROR]: {
|
|
175
|
+
description: "Job run failed with error",
|
|
176
|
+
tags: ["job", "execution", "error"],
|
|
177
|
+
},
|
|
178
|
+
[ResourceKinds.UPLOAD]: {
|
|
179
|
+
description: "Resource was uploaded",
|
|
180
|
+
tags: ["resource"],
|
|
181
|
+
},
|
|
182
|
+
[ResourceKinds.DELETE]: {
|
|
183
|
+
description: "Resource was deleted",
|
|
184
|
+
tags: ["resource"],
|
|
185
|
+
},
|
|
186
|
+
[AuthKinds.LOGIN]: {
|
|
187
|
+
description: "User logged in",
|
|
188
|
+
tags: ["auth"],
|
|
189
|
+
},
|
|
190
|
+
[AuthKinds.LOGOUT]: {
|
|
191
|
+
description: "User logged out",
|
|
192
|
+
tags: ["auth"],
|
|
193
|
+
},
|
|
194
|
+
[AuthKinds.API_KEY_USE]: {
|
|
195
|
+
description: "API key was used for authentication",
|
|
196
|
+
tags: ["auth", "api"],
|
|
197
|
+
},
|
|
198
|
+
[AuthKinds.API_KEY_CREATE]: {
|
|
199
|
+
description: "API key was created",
|
|
200
|
+
tags: ["auth", "api"],
|
|
201
|
+
},
|
|
202
|
+
[AuthKinds.API_KEY_DELETE]: {
|
|
203
|
+
description: "API key was deleted",
|
|
204
|
+
tags: ["auth", "api"],
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=kinds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kinds.js","sourceRoot":"","sources":["../../src/logging/kinds.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger facade for Coconut activity logging
|
|
3
|
+
* @module logging/logger
|
|
4
|
+
*/
|
|
5
|
+
import type { Logger, LoggerOptions } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* Get or create the global logger instance
|
|
8
|
+
*
|
|
9
|
+
* This function returns a singleton logger that can be used throughout the application.
|
|
10
|
+
* The logger automatically fills in system fields (v, seq, ts, coconut) and applies
|
|
11
|
+
* redaction to scrub sensitive data.
|
|
12
|
+
*
|
|
13
|
+
* @param opts - Logger configuration options (only used on first call)
|
|
14
|
+
* @returns Logger instance
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { getLogger } from "@lovelybunch/core/logging/logger";
|
|
19
|
+
*
|
|
20
|
+
* const logger = getLogger();
|
|
21
|
+
* logger.log({
|
|
22
|
+
* kind: "proposal.create",
|
|
23
|
+
* actor: "human:sarah@company.com",
|
|
24
|
+
* subject: "proposal:cp-123",
|
|
25
|
+
* tags: ["proposal"],
|
|
26
|
+
* payload: { intent: "Add dark mode" }
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function getLogger(opts?: Partial<LoggerOptions>): Logger;
|
|
31
|
+
/**
|
|
32
|
+
* Reset the singleton logger (primarily for testing)
|
|
33
|
+
*/
|
|
34
|
+
export declare function resetLogger(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Check if a logger instance exists
|
|
37
|
+
*/
|
|
38
|
+
export declare function hasLogger(): boolean;
|
|
39
|
+
export type { LogEventBase, Logger, LoggerOptions, LogLevel } from "./types";
|
|
40
|
+
export { EventKinds } from "./kinds.js";
|
|
41
|
+
export { defaultRedactor, createRedactor, noRedactor } from "./redact.js";
|
|
42
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logging/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAgB,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAOnE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,MAAM,CAwC/D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAKlC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAGD,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger facade for Coconut activity logging
|
|
3
|
+
* @module logging/logger
|
|
4
|
+
*/
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { JsonlWriter } from "./jsonl-writer.js";
|
|
7
|
+
import { defaultRedactor } from "./redact.js";
|
|
8
|
+
/**
|
|
9
|
+
* Singleton logger instance
|
|
10
|
+
*/
|
|
11
|
+
let singleton = null;
|
|
12
|
+
/**
|
|
13
|
+
* Get or create the global logger instance
|
|
14
|
+
*
|
|
15
|
+
* This function returns a singleton logger that can be used throughout the application.
|
|
16
|
+
* The logger automatically fills in system fields (v, seq, ts, coconut) and applies
|
|
17
|
+
* redaction to scrub sensitive data.
|
|
18
|
+
*
|
|
19
|
+
* @param opts - Logger configuration options (only used on first call)
|
|
20
|
+
* @returns Logger instance
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { getLogger } from "@lovelybunch/core/logging/logger";
|
|
25
|
+
*
|
|
26
|
+
* const logger = getLogger();
|
|
27
|
+
* logger.log({
|
|
28
|
+
* kind: "proposal.create",
|
|
29
|
+
* actor: "human:sarah@company.com",
|
|
30
|
+
* subject: "proposal:cp-123",
|
|
31
|
+
* tags: ["proposal"],
|
|
32
|
+
* payload: { intent: "Add dark mode" }
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function getLogger(opts) {
|
|
37
|
+
if (singleton) {
|
|
38
|
+
return singleton;
|
|
39
|
+
}
|
|
40
|
+
// Resolve configuration with defaults
|
|
41
|
+
const coconutId = opts?.coconutId ?? process.env.COCONUT_ID ?? "unknown.coconut";
|
|
42
|
+
const logsDir = opts?.logsDir ?? path.resolve(".nut/logs");
|
|
43
|
+
const rotateBytes = opts?.rotateBytes ?? 128 * 1024 * 1024; // 128MB default
|
|
44
|
+
const redactor = opts?.redactor ?? defaultRedactor;
|
|
45
|
+
// Create the JSONL writer
|
|
46
|
+
const writer = new JsonlWriter(logsDir, coconutId, rotateBytes);
|
|
47
|
+
// Create and cache the logger instance
|
|
48
|
+
singleton = {
|
|
49
|
+
log(event) {
|
|
50
|
+
// Apply redaction to the event
|
|
51
|
+
const sanitized = redactor(event);
|
|
52
|
+
// Auto-fill system fields and enqueue
|
|
53
|
+
writer.nextEvent(sanitized);
|
|
54
|
+
},
|
|
55
|
+
async flush() {
|
|
56
|
+
return writer.flush();
|
|
57
|
+
},
|
|
58
|
+
getSeq() {
|
|
59
|
+
return writer.getSeq();
|
|
60
|
+
},
|
|
61
|
+
async close() {
|
|
62
|
+
await writer.close();
|
|
63
|
+
singleton = null;
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
return singleton;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Reset the singleton logger (primarily for testing)
|
|
70
|
+
*/
|
|
71
|
+
export function resetLogger() {
|
|
72
|
+
if (singleton) {
|
|
73
|
+
void singleton.close();
|
|
74
|
+
}
|
|
75
|
+
singleton = null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check if a logger instance exists
|
|
79
|
+
*/
|
|
80
|
+
export function hasLogger() {
|
|
81
|
+
return singleton !== null;
|
|
82
|
+
}
|
|
83
|
+
export { EventKinds } from "./kinds.js";
|
|
84
|
+
export { defaultRedactor, createRedactor, noRedactor } from "./redact.js";
|
|
85
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/logging/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C;;GAEG;AACH,IAAI,SAAS,GAAkB,IAAI,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,SAAS,CAAC,IAA6B;IACrD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,sCAAsC;IACtC,MAAM,SAAS,GACb,IAAI,EAAE,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,iBAAiB,CAAC;IACjE,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,gBAAgB;IAC5E,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,eAAe,CAAC;IAEnD,0BAA0B;IAC1B,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAEhE,uCAAuC;IACvC,SAAS,GAAG;QACV,GAAG,CAAC,KAAmB;YACrB,+BAA+B;YAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAElC,sCAAsC;YACtC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC9B,CAAC;QAED,KAAK,CAAC,KAAK;YACT,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QAED,MAAM;YACJ,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,CAAC;QAED,KAAK,CAAC,KAAK;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACrB,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;KACF,CAAC;IAEF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,SAAS,KAAK,IAAI,CAAC;AAC5B,CAAC;AAID,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payload redaction utilities for scrubbing sensitive data from log events
|
|
3
|
+
* @module logging/redact
|
|
4
|
+
*/
|
|
5
|
+
import type { LogEventBase } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* Default redactor function that scrubs sensitive data from log events
|
|
8
|
+
*
|
|
9
|
+
* This function:
|
|
10
|
+
* - Removes sensitive fields from the payload
|
|
11
|
+
* - Redacts known patterns (API keys, tokens, etc.)
|
|
12
|
+
* - Preserves the overall structure of the event
|
|
13
|
+
*
|
|
14
|
+
* @param event - The log event to redact
|
|
15
|
+
* @returns A new event with sensitive data removed
|
|
16
|
+
*/
|
|
17
|
+
export declare function defaultRedactor(event: LogEventBase): LogEventBase;
|
|
18
|
+
/**
|
|
19
|
+
* Create a custom redactor that combines the default redactor with additional rules
|
|
20
|
+
*
|
|
21
|
+
* @param additionalRedactor - Custom redaction function to apply after default redaction
|
|
22
|
+
* @returns Combined redactor function
|
|
23
|
+
*/
|
|
24
|
+
export declare function createRedactor(additionalRedactor?: (event: LogEventBase) => LogEventBase): (event: LogEventBase) => LogEventBase;
|
|
25
|
+
/**
|
|
26
|
+
* No-op redactor that returns the event unchanged
|
|
27
|
+
* Useful for testing or when redaction is not needed
|
|
28
|
+
*/
|
|
29
|
+
export declare function noRedactor(event: LogEventBase): LogEventBase;
|
|
30
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/logging/redact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAsG5C;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAqBjE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,YAAY,GACzD,CAAC,KAAK,EAAE,YAAY,KAAK,YAAY,CASvC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CAE5D"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payload redaction utilities for scrubbing sensitive data from log events
|
|
3
|
+
* @module logging/redact
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* List of field names that commonly contain sensitive data
|
|
7
|
+
*/
|
|
8
|
+
const SENSITIVE_FIELD_NAMES = [
|
|
9
|
+
"password",
|
|
10
|
+
"passwordHash",
|
|
11
|
+
"secret",
|
|
12
|
+
"apiKey",
|
|
13
|
+
"api_key",
|
|
14
|
+
"token",
|
|
15
|
+
"accessToken",
|
|
16
|
+
"access_token",
|
|
17
|
+
"refreshToken",
|
|
18
|
+
"refresh_token",
|
|
19
|
+
"clientSecret",
|
|
20
|
+
"client_secret",
|
|
21
|
+
"privateKey",
|
|
22
|
+
"private_key",
|
|
23
|
+
"authorization",
|
|
24
|
+
"cookie",
|
|
25
|
+
"sessionSecret",
|
|
26
|
+
"session_secret",
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Regular expressions to detect sensitive data patterns
|
|
30
|
+
*/
|
|
31
|
+
const SENSITIVE_PATTERNS = [
|
|
32
|
+
/sk-[a-zA-Z0-9]{20,}/g, // OpenAI API keys
|
|
33
|
+
/sk_live_[a-zA-Z0-9]{20,}/g, // Stripe live keys
|
|
34
|
+
/sk_test_[a-zA-Z0-9]{20,}/g, // Stripe test keys
|
|
35
|
+
/ghp_[a-zA-Z0-9]{36}/g, // GitHub personal access tokens
|
|
36
|
+
/gho_[a-zA-Z0-9]{36}/g, // GitHub OAuth tokens
|
|
37
|
+
/Bearer\s+[a-zA-Z0-9\-._~+/]+=*/g, // Bearer tokens
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Placeholder text for redacted content
|
|
41
|
+
*/
|
|
42
|
+
const REDACTED = "[REDACTED]";
|
|
43
|
+
/**
|
|
44
|
+
* Check if a field name is sensitive
|
|
45
|
+
*/
|
|
46
|
+
function isSensitiveFieldName(fieldName) {
|
|
47
|
+
const lowerField = fieldName.toLowerCase();
|
|
48
|
+
return SENSITIVE_FIELD_NAMES.some((sensitive) => lowerField.includes(sensitive.toLowerCase()));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Recursively redact sensitive fields from an object
|
|
52
|
+
*/
|
|
53
|
+
function redactObject(obj, depth = 0) {
|
|
54
|
+
// Prevent infinite recursion
|
|
55
|
+
if (depth > 10) {
|
|
56
|
+
return obj;
|
|
57
|
+
}
|
|
58
|
+
if (obj === null || obj === undefined) {
|
|
59
|
+
return obj;
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(obj)) {
|
|
62
|
+
return obj.map((item) => redactObject(item, depth + 1));
|
|
63
|
+
}
|
|
64
|
+
if (typeof obj === "object") {
|
|
65
|
+
const result = {};
|
|
66
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
67
|
+
if (isSensitiveFieldName(key)) {
|
|
68
|
+
result[key] = REDACTED;
|
|
69
|
+
}
|
|
70
|
+
else if (typeof value === "string") {
|
|
71
|
+
result[key] = redactString(value);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
result[key] = redactObject(value, depth + 1);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
if (typeof obj === "string") {
|
|
80
|
+
return redactString(obj);
|
|
81
|
+
}
|
|
82
|
+
return obj;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Redact sensitive patterns from a string
|
|
86
|
+
*/
|
|
87
|
+
function redactString(str) {
|
|
88
|
+
let result = str;
|
|
89
|
+
for (const pattern of SENSITIVE_PATTERNS) {
|
|
90
|
+
result = result.replace(pattern, REDACTED);
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Default redactor function that scrubs sensitive data from log events
|
|
96
|
+
*
|
|
97
|
+
* This function:
|
|
98
|
+
* - Removes sensitive fields from the payload
|
|
99
|
+
* - Redacts known patterns (API keys, tokens, etc.)
|
|
100
|
+
* - Preserves the overall structure of the event
|
|
101
|
+
*
|
|
102
|
+
* @param event - The log event to redact
|
|
103
|
+
* @returns A new event with sensitive data removed
|
|
104
|
+
*/
|
|
105
|
+
export function defaultRedactor(event) {
|
|
106
|
+
const redacted = {
|
|
107
|
+
...event,
|
|
108
|
+
};
|
|
109
|
+
// Redact the payload if present
|
|
110
|
+
if (event.payload) {
|
|
111
|
+
redacted.payload = redactObject(event.payload);
|
|
112
|
+
}
|
|
113
|
+
// Redact actor field if it looks like an email with sensitive content
|
|
114
|
+
if (event.actor && typeof event.actor === "string") {
|
|
115
|
+
redacted.actor = redactString(event.actor);
|
|
116
|
+
}
|
|
117
|
+
// Redact subject field if needed
|
|
118
|
+
if (event.subject && typeof event.subject === "string") {
|
|
119
|
+
redacted.subject = redactString(event.subject);
|
|
120
|
+
}
|
|
121
|
+
return redacted;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Create a custom redactor that combines the default redactor with additional rules
|
|
125
|
+
*
|
|
126
|
+
* @param additionalRedactor - Custom redaction function to apply after default redaction
|
|
127
|
+
* @returns Combined redactor function
|
|
128
|
+
*/
|
|
129
|
+
export function createRedactor(additionalRedactor) {
|
|
130
|
+
if (!additionalRedactor) {
|
|
131
|
+
return defaultRedactor;
|
|
132
|
+
}
|
|
133
|
+
return (event) => {
|
|
134
|
+
const defaultRedacted = defaultRedactor(event);
|
|
135
|
+
return additionalRedactor(defaultRedacted);
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* No-op redactor that returns the event unchanged
|
|
140
|
+
* Useful for testing or when redaction is not needed
|
|
141
|
+
*/
|
|
142
|
+
export function noRedactor(event) {
|
|
143
|
+
return event;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/logging/redact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core logging types for Coconut activity logging system
|
|
3
|
+
* @module logging/types
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Log level enumeration
|
|
7
|
+
*/
|
|
8
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
9
|
+
/**
|
|
10
|
+
* Base event structure for logging
|
|
11
|
+
* All events share these common fields, with additional payload data specific to the event type
|
|
12
|
+
*/
|
|
13
|
+
export interface LogEventBase {
|
|
14
|
+
/** Optional tenant identifier for multi-tenant deployments */
|
|
15
|
+
tenant?: string;
|
|
16
|
+
/** Event kind/type from the taxonomy (e.g., "proposal.create", "agent.session.start") */
|
|
17
|
+
kind: string;
|
|
18
|
+
/** Actor performing the action (e.g., "human:email@example.com", "agent:coder") */
|
|
19
|
+
actor?: string;
|
|
20
|
+
/** Subject entity this event is about (e.g., "proposal:cp-123", "session:abc123") */
|
|
21
|
+
subject?: string;
|
|
22
|
+
/** Correlation ID for tracing related events across operations */
|
|
23
|
+
trace?: string;
|
|
24
|
+
/** Optional parent trace hop for nested operations */
|
|
25
|
+
parent?: string;
|
|
26
|
+
/** Event severity level */
|
|
27
|
+
level?: LogLevel;
|
|
28
|
+
/** Queryable tags for filtering and categorization */
|
|
29
|
+
tags?: string[];
|
|
30
|
+
/** Event-specific payload data */
|
|
31
|
+
payload?: unknown;
|
|
32
|
+
/** Override timestamp (primarily for backfilling historical data) */
|
|
33
|
+
ts?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Complete event structure with system-filled fields
|
|
37
|
+
*/
|
|
38
|
+
export interface LogEvent extends Omit<LogEventBase, 'ts'> {
|
|
39
|
+
/** Schema version for the event format */
|
|
40
|
+
v: number;
|
|
41
|
+
/** Monotonic sequence number within this Coconut instance */
|
|
42
|
+
seq: number;
|
|
43
|
+
/** ISO 8601 timestamp (required in final event) */
|
|
44
|
+
ts: string;
|
|
45
|
+
/** Stable Coconut instance identifier */
|
|
46
|
+
coconut: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Configuration options for the logger
|
|
50
|
+
*/
|
|
51
|
+
export interface LoggerOptions {
|
|
52
|
+
/** Unique identifier for this Coconut instance */
|
|
53
|
+
coconutId: string;
|
|
54
|
+
/** Directory where log files are stored (default: ".nut/logs") */
|
|
55
|
+
logsDir?: string;
|
|
56
|
+
/** File size threshold for rotation in bytes (default: 128MB) */
|
|
57
|
+
rotateBytes?: number;
|
|
58
|
+
/** Optional redaction function to scrub sensitive data from payloads */
|
|
59
|
+
redactor?: (event: LogEventBase) => LogEventBase;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Logger interface for emitting events
|
|
63
|
+
*/
|
|
64
|
+
export interface Logger {
|
|
65
|
+
/** Enqueue an event for writing (non-blocking) */
|
|
66
|
+
log(event: LogEventBase): void;
|
|
67
|
+
/** Flush pending events to disk (best-effort fsync) */
|
|
68
|
+
flush(): Promise<void>;
|
|
69
|
+
/** Get the last assigned sequence number */
|
|
70
|
+
getSeq(): number;
|
|
71
|
+
/** Close the logger and cleanup resources */
|
|
72
|
+
close(): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/logging/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IAEb,mFAAmF;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,QAAQ,CAAC;IAEjB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,qEAAqE;IACrE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,QAAS,SAAQ,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC;IACxD,0CAA0C;IAC1C,CAAC,EAAE,MAAM,CAAC;IAEV,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;IAEZ,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IAEX,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAElB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,YAAY,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,kDAAkD;IAClD,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAE/B,uDAAuD;IACvD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,4CAA4C;IAC5C,MAAM,IAAI,MAAM,CAAC;IAEjB,6CAA6C;IAC7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/logging/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovelybunch/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.68",
|
|
4
4
|
"description": "Core Coconut functionality",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./logging": {
|
|
14
|
+
"types": "./dist/logging/index.d.ts",
|
|
15
|
+
"import": "./dist/logging/index.js"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"files": [
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
"test": "vitest run"
|
|
32
36
|
},
|
|
33
37
|
"dependencies": {
|
|
34
|
-
"@lovelybunch/types": "^1.0.
|
|
38
|
+
"@lovelybunch/types": "^1.0.68",
|
|
35
39
|
"gray-matter": "^4.0.3",
|
|
36
40
|
"fuse.js": "^7.0.0",
|
|
37
41
|
"nanoid": "^5.0.6"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-templates.d.ts","sourceRoot":"","sources":["../src/workflow-templates.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAyDpD,CAAC"}
|