@spool-lab/core 0.4.12 → 0.5.0
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/README.md +2 -2
- package/dist/db/db.d.ts +10 -2
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +119 -10
- package/dist/db/db.js.map +1 -1
- package/dist/db/queries.d.ts +5 -5
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +32 -14
- package/dist/db/queries.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/observability/exporter-file.d.ts +30 -0
- package/dist/observability/exporter-file.d.ts.map +1 -0
- package/dist/observability/exporter-file.js +125 -0
- package/dist/observability/exporter-file.js.map +1 -0
- package/dist/observability/exporter-pretty.d.ts +27 -0
- package/dist/observability/exporter-pretty.d.ts.map +1 -0
- package/dist/observability/exporter-pretty.js +84 -0
- package/dist/observability/exporter-pretty.js.map +1 -0
- package/dist/observability/index.d.ts +2 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +2 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/layer.d.ts +29 -0
- package/dist/observability/layer.d.ts.map +1 -0
- package/dist/observability/layer.js +45 -0
- package/dist/observability/layer.js.map +1 -0
- package/dist/parsers/opencode.d.ts +23 -0
- package/dist/parsers/opencode.d.ts.map +1 -0
- package/dist/parsers/opencode.js +358 -0
- package/dist/parsers/opencode.js.map +1 -0
- package/dist/projects/sessions.d.ts +29 -1
- package/dist/projects/sessions.d.ts.map +1 -1
- package/dist/projects/sessions.js +115 -11
- package/dist/projects/sessions.js.map +1 -1
- package/dist/security/index.d.ts +14 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +7 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/maintenance.d.ts +15 -0
- package/dist/security/maintenance.d.ts.map +1 -0
- package/dist/security/maintenance.js +68 -0
- package/dist/security/maintenance.js.map +1 -0
- package/dist/security/profile.d.ts +47 -0
- package/dist/security/profile.d.ts.map +1 -0
- package/dist/security/profile.js +131 -0
- package/dist/security/profile.js.map +1 -0
- package/dist/security/purge.d.ts +68 -0
- package/dist/security/purge.d.ts.map +1 -0
- package/dist/security/purge.js +193 -0
- package/dist/security/purge.js.map +1 -0
- package/dist/security/repo.d.ts +190 -0
- package/dist/security/repo.d.ts.map +1 -0
- package/dist/security/repo.js +594 -0
- package/dist/security/repo.js.map +1 -0
- package/dist/security/scan.d.ts +50 -0
- package/dist/security/scan.d.ts.map +1 -0
- package/dist/security/scan.js +122 -0
- package/dist/security/scan.js.map +1 -0
- package/dist/security/types.d.ts +146 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +10 -0
- package/dist/security/types.js.map +1 -0
- package/dist/security/worker.d.ts +69 -0
- package/dist/security/worker.d.ts.map +1 -0
- package/dist/security/worker.js +228 -0
- package/dist/security/worker.js.map +1 -0
- package/dist/sync/source-paths.d.ts +1 -0
- package/dist/sync/source-paths.d.ts.map +1 -1
- package/dist/sync/source-paths.js +48 -6
- package/dist/sync/source-paths.js.map +1 -1
- package/dist/sync/syncer.d.ts +9 -1
- package/dist/sync/syncer.d.ts.map +1 -1
- package/dist/sync/syncer.js +128 -16
- package/dist/sync/syncer.js.map +1 -1
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +8 -2
- package/dist/sync/watcher.js.map +1 -1
- package/dist/types.d.ts +15 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/util/resolve-bin.d.ts +34 -0
- package/dist/util/resolve-bin.d.ts.map +1 -1
- package/dist/util/resolve-bin.js +175 -20
- package/dist/util/resolve-bin.js.map +1 -1
- package/package.json +11 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter-file.d.ts","sourceRoot":"","sources":["../../src/observability/exporter-file.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAI/E,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED,MAAM,WAAW,+BAA+B;IAC9C,2DAA2D;IAC3D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CAC1B;AAMD,qBAAa,wBAAyB,YAAW,YAAY;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAMhC,OAAO,CAAC,UAAU,CAAsB;gBAE5B,IAAI,EAAE,+BAA+B;IAOjD,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAcnF,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IACzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAE3B,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,cAAc;CAevB;AA8DD;qDACqD;AACrD,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync, readdirSync, rmSync, statSync, } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { SpanStatusCode } from '@opentelemetry/api';
|
|
4
|
+
const FILE_PREFIX = 'spool-';
|
|
5
|
+
const FILE_SUFFIX = '.jsonl';
|
|
6
|
+
const DEFAULT_MAX_TOTAL_BYTES = 50 * 1024 * 1024;
|
|
7
|
+
export class RotatingFileSpanExporter {
|
|
8
|
+
dir;
|
|
9
|
+
maxTotalBytes;
|
|
10
|
+
now;
|
|
11
|
+
// Running estimate of bytes on disk across all log files. Maintained
|
|
12
|
+
// incrementally on each append so the happy path doesn't pay for a
|
|
13
|
+
// full readdir+stat sweep per span (SimpleSpanProcessor calls
|
|
14
|
+
// export() once per finished span — so this runs in the scan hot
|
|
15
|
+
// path). Seeded from disk on first export.
|
|
16
|
+
totalBytes = null;
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
this.dir = opts.dir;
|
|
19
|
+
this.maxTotalBytes = opts.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES;
|
|
20
|
+
this.now = opts.now ?? (() => new Date());
|
|
21
|
+
mkdirSync(this.dir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
export(spans, resultCallback) {
|
|
24
|
+
try {
|
|
25
|
+
const path = this.todayPath();
|
|
26
|
+
const payload = spans.map(spanToJsonLine).join('');
|
|
27
|
+
if (payload.length > 0)
|
|
28
|
+
appendFileSync(path, payload);
|
|
29
|
+
if (this.totalBytes === null)
|
|
30
|
+
this.totalBytes = readDirTotal(this.dir);
|
|
31
|
+
else
|
|
32
|
+
this.totalBytes += payload.length;
|
|
33
|
+
if (this.totalBytes > this.maxTotalBytes)
|
|
34
|
+
this.enforceSizeCap();
|
|
35
|
+
resultCallback({ code: 0 });
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
resultCallback({ code: 1, error: err instanceof Error ? err : new Error(String(err)) });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
shutdown() { return Promise.resolve(); }
|
|
42
|
+
forceFlush() { return Promise.resolve(); }
|
|
43
|
+
todayPath() {
|
|
44
|
+
const d = this.now();
|
|
45
|
+
const yyyy = d.getFullYear();
|
|
46
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0');
|
|
47
|
+
const dd = String(d.getDate()).padStart(2, '0');
|
|
48
|
+
return join(this.dir, `${FILE_PREFIX}${yyyy}-${mm}-${dd}${FILE_SUFFIX}`);
|
|
49
|
+
}
|
|
50
|
+
enforceSizeCap() {
|
|
51
|
+
const entries = listEntries(this.dir);
|
|
52
|
+
let total = entries.reduce((a, e) => a + e.size, 0);
|
|
53
|
+
if (total <= this.maxTotalBytes) {
|
|
54
|
+
this.totalBytes = total;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
entries.sort((a, b) => a.mtimeMs - b.mtimeMs);
|
|
58
|
+
for (const e of entries) {
|
|
59
|
+
if (total <= this.maxTotalBytes)
|
|
60
|
+
break;
|
|
61
|
+
try {
|
|
62
|
+
rmSync(e.path, { force: true });
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
total -= e.size;
|
|
68
|
+
}
|
|
69
|
+
this.totalBytes = total;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function spanToJsonLine(span) {
|
|
73
|
+
const rec = {
|
|
74
|
+
ts: hrTimeToIso(span.endTime),
|
|
75
|
+
name: span.name,
|
|
76
|
+
durationMs: hrTimeToMs(span.duration),
|
|
77
|
+
traceId: span.spanContext().traceId,
|
|
78
|
+
spanId: span.spanContext().spanId,
|
|
79
|
+
parentSpanId: span.parentSpanContext?.spanId ?? null,
|
|
80
|
+
status: span.status.code === SpanStatusCode.OK ? 'ok'
|
|
81
|
+
: span.status.code === SpanStatusCode.ERROR ? 'error'
|
|
82
|
+
: 'unset',
|
|
83
|
+
...(span.status.message ? { statusMessage: span.status.message } : {}),
|
|
84
|
+
attributes: { ...span.attributes },
|
|
85
|
+
};
|
|
86
|
+
return JSON.stringify(rec) + '\n';
|
|
87
|
+
}
|
|
88
|
+
function hrTimeToIso(hr) {
|
|
89
|
+
const ms = hr[0] * 1000 + Math.floor(hr[1] / 1_000_000);
|
|
90
|
+
return new Date(ms).toISOString();
|
|
91
|
+
}
|
|
92
|
+
function hrTimeToMs(hr) {
|
|
93
|
+
return hr[0] * 1000 + hr[1] / 1_000_000;
|
|
94
|
+
}
|
|
95
|
+
function listEntries(dir) {
|
|
96
|
+
let names;
|
|
97
|
+
try {
|
|
98
|
+
names = readdirSync(dir);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
return names
|
|
104
|
+
.filter((name) => name.startsWith(FILE_PREFIX) && name.endsWith(FILE_SUFFIX))
|
|
105
|
+
.map((name) => {
|
|
106
|
+
const path = join(dir, name);
|
|
107
|
+
try {
|
|
108
|
+
const st = statSync(path);
|
|
109
|
+
return { path, size: st.size, mtimeMs: st.mtimeMs };
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
.filter((e) => e !== null);
|
|
116
|
+
}
|
|
117
|
+
function readDirTotal(dir) {
|
|
118
|
+
return listEntries(dir).reduce((a, e) => a + e.size, 0);
|
|
119
|
+
}
|
|
120
|
+
/** Test-only utility — exported for fixtures that need to enumerate
|
|
121
|
+
* rotated files. Not part of the public surface. */
|
|
122
|
+
export function listLogFiles(dir) {
|
|
123
|
+
return listEntries(dir).map((e) => e.path.split('/').pop() ?? '').sort();
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=exporter-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter-file.js","sourceRoot":"","sources":["../../src/observability/exporter-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
2
|
+
interface ExportResult {
|
|
3
|
+
code: number;
|
|
4
|
+
error?: Error;
|
|
5
|
+
}
|
|
6
|
+
export interface PrettyConsoleSpanExporterOptions {
|
|
7
|
+
/** Where to write each line. Defaults to process.stdout. */
|
|
8
|
+
readonly sink?: (line: string) => void;
|
|
9
|
+
/** Force colors off (e.g. when stdout isn't a TTY). */
|
|
10
|
+
readonly noColor?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** Span exporter that prints one line per finished span to the console.
|
|
13
|
+
* Format: `HH:MM:SS.mmm [span.name] (Nms) k1=v1 k2=v2`.
|
|
14
|
+
* Designed for the dev loop — file-backed structured output lives in
|
|
15
|
+
* the file exporter. */
|
|
16
|
+
export declare class PrettyConsoleSpanExporter implements SpanExporter {
|
|
17
|
+
private readonly sink;
|
|
18
|
+
private readonly color;
|
|
19
|
+
constructor(opts?: PrettyConsoleSpanExporterOptions);
|
|
20
|
+
export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void;
|
|
21
|
+
shutdown(): Promise<void>;
|
|
22
|
+
forceFlush(): Promise<void>;
|
|
23
|
+
private format;
|
|
24
|
+
private tint;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=exporter-pretty.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter-pretty.d.ts","sourceRoot":"","sources":["../../src/observability/exporter-pretty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAM/E,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAcD,MAAM,WAAW,gCAAgC;IAC/C,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC,uDAAuD;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;;yBAGyB;AACzB,qBAAa,yBAA0B,YAAW,YAAY;IAC5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,IAAI,GAAE,gCAAqC;IAKvD,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAKnF,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IACzB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAE3B,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,IAAI;CAGb"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { SpanStatusCode } from '@opentelemetry/api';
|
|
2
|
+
const ANSI = {
|
|
3
|
+
reset: '\x1b[0m',
|
|
4
|
+
dim: '\x1b[2m',
|
|
5
|
+
red: '\x1b[31m',
|
|
6
|
+
green: '\x1b[32m',
|
|
7
|
+
yellow: '\x1b[33m',
|
|
8
|
+
blue: '\x1b[34m',
|
|
9
|
+
magenta: '\x1b[35m',
|
|
10
|
+
cyan: '\x1b[36m',
|
|
11
|
+
gray: '\x1b[90m',
|
|
12
|
+
};
|
|
13
|
+
/** Span exporter that prints one line per finished span to the console.
|
|
14
|
+
* Format: `HH:MM:SS.mmm [span.name] (Nms) k1=v1 k2=v2`.
|
|
15
|
+
* Designed for the dev loop — file-backed structured output lives in
|
|
16
|
+
* the file exporter. */
|
|
17
|
+
export class PrettyConsoleSpanExporter {
|
|
18
|
+
sink;
|
|
19
|
+
color;
|
|
20
|
+
constructor(opts = {}) {
|
|
21
|
+
this.sink = opts.sink ?? ((line) => process.stdout.write(line + '\n'));
|
|
22
|
+
this.color = opts.noColor ? false : process.stdout.isTTY === true;
|
|
23
|
+
}
|
|
24
|
+
export(spans, resultCallback) {
|
|
25
|
+
for (const span of spans)
|
|
26
|
+
this.sink(this.format(span));
|
|
27
|
+
resultCallback({ code: 0 });
|
|
28
|
+
}
|
|
29
|
+
shutdown() { return Promise.resolve(); }
|
|
30
|
+
forceFlush() { return Promise.resolve(); }
|
|
31
|
+
format(span) {
|
|
32
|
+
const ts = formatTimestamp(span.endTime);
|
|
33
|
+
const durMs = hrTimeToMs(span.duration);
|
|
34
|
+
const isError = span.status.code === SpanStatusCode.ERROR;
|
|
35
|
+
const name = isError ? this.tint(span.name, ANSI.red) : this.tint(span.name, ANSI.cyan);
|
|
36
|
+
const dur = this.tint(`(${formatDuration(durMs)})`, ANSI.gray);
|
|
37
|
+
const attrs = formatAttributes(span.attributes);
|
|
38
|
+
const attrsTinted = attrs ? ' ' + this.tint(attrs, ANSI.yellow) : '';
|
|
39
|
+
const statusSuffix = isError && span.status.message
|
|
40
|
+
? ' ' + this.tint(`error: ${span.status.message}`, ANSI.red)
|
|
41
|
+
: '';
|
|
42
|
+
return `${this.tint(ts, ANSI.dim)} [${name}] ${dur}${attrsTinted}${statusSuffix}`;
|
|
43
|
+
}
|
|
44
|
+
tint(s, code) {
|
|
45
|
+
return this.color ? `${code}${s}${ANSI.reset}` : s;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function pad2(n) { return n < 10 ? `0${n}` : `${n}`; }
|
|
49
|
+
function pad3(n) { return n < 10 ? `00${n}` : n < 100 ? `0${n}` : `${n}`; }
|
|
50
|
+
function formatTimestamp(hr) {
|
|
51
|
+
const ms = hr[0] * 1000 + Math.floor(hr[1] / 1_000_000);
|
|
52
|
+
const d = new Date(ms);
|
|
53
|
+
return `${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}.${pad3(d.getMilliseconds())}`;
|
|
54
|
+
}
|
|
55
|
+
function hrTimeToMs(hr) {
|
|
56
|
+
return hr[0] * 1000 + hr[1] / 1_000_000;
|
|
57
|
+
}
|
|
58
|
+
function formatDuration(ms) {
|
|
59
|
+
if (ms < 1)
|
|
60
|
+
return `${ms.toFixed(2)}ms`;
|
|
61
|
+
if (ms < 1000)
|
|
62
|
+
return `${ms.toFixed(1)}ms`;
|
|
63
|
+
return `${(ms / 1000).toFixed(2)}s`;
|
|
64
|
+
}
|
|
65
|
+
function formatAttributes(attrs) {
|
|
66
|
+
const entries = Object.entries(attrs);
|
|
67
|
+
if (entries.length === 0)
|
|
68
|
+
return '';
|
|
69
|
+
return entries
|
|
70
|
+
.map(([k, v]) => `${k}=${formatValue(v)}`)
|
|
71
|
+
.join(' ');
|
|
72
|
+
}
|
|
73
|
+
function formatValue(v) {
|
|
74
|
+
if (v == null)
|
|
75
|
+
return String(v);
|
|
76
|
+
if (typeof v === 'string')
|
|
77
|
+
return v.length > 60 ? `${v.slice(0, 57)}…` : v;
|
|
78
|
+
if (typeof v === 'number' || typeof v === 'boolean')
|
|
79
|
+
return String(v);
|
|
80
|
+
if (Array.isArray(v))
|
|
81
|
+
return `[${v.length}]`;
|
|
82
|
+
return JSON.stringify(v).slice(0, 60);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=exporter-pretty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter-pretty.js","sourceRoot":"","sources":["../../src/observability/exporter-pretty.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GAGzB,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type SpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
2
|
+
import { Effect, Layer, ManagedRuntime } from 'effect';
|
|
3
|
+
export type ObservabilityEnv = 'dev' | 'prod' | 'test';
|
|
4
|
+
interface CommonConfig {
|
|
5
|
+
readonly serviceName: string;
|
|
6
|
+
readonly serviceVersion?: string;
|
|
7
|
+
}
|
|
8
|
+
export type ObservabilityConfig = (CommonConfig & {
|
|
9
|
+
readonly env: 'dev';
|
|
10
|
+
}) | (CommonConfig & {
|
|
11
|
+
readonly env: 'prod';
|
|
12
|
+
readonly logsDir: string;
|
|
13
|
+
}) | (CommonConfig & {
|
|
14
|
+
readonly env: 'test';
|
|
15
|
+
readonly testExporter?: SpanExporter;
|
|
16
|
+
});
|
|
17
|
+
/** Effect Layer that wires `Effect.withSpan` to either a pretty console
|
|
18
|
+
* exporter (dev), a rotating jsonl file exporter (prod), or the
|
|
19
|
+
* supplied test exporter / noop (test). */
|
|
20
|
+
export declare function observabilityLayer(config: ObservabilityConfig): Layer.Layer<never>;
|
|
21
|
+
/** Build a ManagedRuntime carrying the observability layer + a typed
|
|
22
|
+
* promise runner. Lets main / scan-worker / sync-worker share the
|
|
23
|
+
* same env-detection + cast pattern instead of each rolling its own. */
|
|
24
|
+
export declare function makeObservabilityRuntime(config: ObservabilityConfig): {
|
|
25
|
+
readonly runtime: ManagedRuntime.ManagedRuntime<never, never>;
|
|
26
|
+
readonly run: <A, E>(eff: Effect.Effect<A, E>) => Promise<A>;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=layer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer.d.ts","sourceRoot":"","sources":["../../src/observability/layer.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAItD,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;AAEtD,UAAU,YAAY;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,MAAM,MAAM,mBAAmB,GAC3B,CAAC,YAAY,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAA;CAAE,CAAC,GACxC,CAAC,YAAY,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GACnE,CAAC,YAAY,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAA;CAAE,CAAC,CAAA;AAEnF;;4CAE4C;AAC5C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAQlF;AAqBD;;yEAEyE;AACzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,mBAAmB,GAAG;IACrE,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAC7D,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CAC7D,CAOA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { NodeSdk } from '@effect/opentelemetry';
|
|
2
|
+
import { SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base';
|
|
3
|
+
import { ManagedRuntime } from 'effect';
|
|
4
|
+
import { PrettyConsoleSpanExporter } from './exporter-pretty.js';
|
|
5
|
+
import { RotatingFileSpanExporter } from './exporter-file.js';
|
|
6
|
+
/** Effect Layer that wires `Effect.withSpan` to either a pretty console
|
|
7
|
+
* exporter (dev), a rotating jsonl file exporter (prod), or the
|
|
8
|
+
* supplied test exporter / noop (test). */
|
|
9
|
+
export function observabilityLayer(config) {
|
|
10
|
+
return NodeSdk.layer(() => ({
|
|
11
|
+
resource: {
|
|
12
|
+
serviceName: config.serviceName,
|
|
13
|
+
...(config.serviceVersion ? { serviceVersion: config.serviceVersion } : {}),
|
|
14
|
+
},
|
|
15
|
+
spanProcessor: makeProcessor(config),
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
function makeProcessor(config) {
|
|
19
|
+
switch (config.env) {
|
|
20
|
+
case 'test':
|
|
21
|
+
return new SimpleSpanProcessor(config.testExporter ?? noopExporter);
|
|
22
|
+
case 'dev':
|
|
23
|
+
return new SimpleSpanProcessor(new PrettyConsoleSpanExporter());
|
|
24
|
+
case 'prod':
|
|
25
|
+
// SimpleSpanProcessor on purpose: BatchSpanProcessor batches for
|
|
26
|
+
// network export, but our prod sink is a local file. Per-span
|
|
27
|
+
// writes keep logs current for live `tail -f` debugging.
|
|
28
|
+
return new SimpleSpanProcessor(new RotatingFileSpanExporter({ dir: config.logsDir }));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const noopExporter = {
|
|
32
|
+
export: (_spans, cb) => cb({ code: 0 }),
|
|
33
|
+
shutdown: () => Promise.resolve(),
|
|
34
|
+
};
|
|
35
|
+
/** Build a ManagedRuntime carrying the observability layer + a typed
|
|
36
|
+
* promise runner. Lets main / scan-worker / sync-worker share the
|
|
37
|
+
* same env-detection + cast pattern instead of each rolling its own. */
|
|
38
|
+
export function makeObservabilityRuntime(config) {
|
|
39
|
+
const runtime = ManagedRuntime.make(observabilityLayer(config));
|
|
40
|
+
return {
|
|
41
|
+
runtime,
|
|
42
|
+
run: (eff) => runtime.runPromise(eff),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=layer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer.js","sourceRoot":"","sources":["../../src/observability/layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,OAAO,EACL,mBAAmB,GAGpB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAiB,cAAc,EAAE,MAAM,QAAQ,CAAA;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAc7D;;4CAE4C;AAC5C,MAAM,UAAU,kBAAkB,CAAC,MAA2B;IAC5D,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1B,QAAQ,EAAE;YACR,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E;QACD,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC;KACrC,CAAC,CAAC,CAAA;AACL,CAAC;AAED,SAAS,aAAa,CAAC,MAA2B;IAChD,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,YAAY,IAAI,YAAY,CAAC,CAAA;QACrE,KAAK,KAAK;YACR,OAAO,IAAI,mBAAmB,CAAC,IAAI,yBAAyB,EAAE,CAAC,CAAA;QACjE,KAAK,MAAM;YACT,iEAAiE;YACjE,8DAA8D;YAC9D,yDAAyD;YACzD,OAAO,IAAI,mBAAmB,CAAC,IAAI,wBAAwB,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACzF,CAAC;AACH,CAAC;AAED,MAAM,YAAY,GAAiB;IACjC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACvC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;CAClC,CAAA;AAED;;yEAEyE;AACzE,MAAM,UAAU,wBAAwB,CAAC,MAA2B;IAIlE,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/D,OAAO;QACL,OAAO;QACP,GAAG,EAAE,CAAO,GAAwB,EAAE,EAAE,CACtC,OAAO,CAAC,UAAU,CAAC,GAA8B,CAAC;KACrD,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ParseSessionResult, ParsedSession } from '../types.js';
|
|
2
|
+
export declare const OPENCODE_INDEX_VERSION = "opencode-v3-session-model-json";
|
|
3
|
+
export declare const OPENCODE_DB_NAME = "opencode.db";
|
|
4
|
+
export declare function makeOpenCodeSessionFilePath(dbPath: string, sessionId: string): string;
|
|
5
|
+
export declare function parseOpenCodeSessionFilePath(filePath: string): {
|
|
6
|
+
dbPath: string;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
} | null;
|
|
9
|
+
export declare function isOpenCodeDatabaseFile(filePath: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Map an OpenCode DB sidecar path (`opencode.db-wal` / `-shm` / `-journal`) back
|
|
12
|
+
* to the main `opencode.db`. Non-sidecar paths are returned unchanged. The watcher
|
|
13
|
+
* uses this so WAL-mode writes — which land in `-wal` and leave the main file's
|
|
14
|
+
* mtime stale until checkpoint — still schedule a re-index of the database.
|
|
15
|
+
*/
|
|
16
|
+
export declare function normalizeOpenCodeWatchPath(filePath: string): string;
|
|
17
|
+
export declare function listOpenCodeSessionFilePaths(dbPath: string): string[];
|
|
18
|
+
export declare function getOpenCodeSessionIndexedMtime(filePath: string): string;
|
|
19
|
+
export declare function loadOpenCodeSession(filePath: string): ParseSessionResult;
|
|
20
|
+
export declare function parseOpenCodeSession(filePath: string): ParsedSession | null;
|
|
21
|
+
export declare function openCodeDbPathFromSessionPath(filePath: string): string;
|
|
22
|
+
export declare function openCodeDbDisplayPath(filePath: string): string;
|
|
23
|
+
//# sourceMappingURL=opencode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../src/parsers/opencode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAiB,aAAa,EAAE,MAAM,aAAa,CAAA;AAGnF,eAAO,MAAM,sBAAsB,mCAAmC,CAAA;AACtE,eAAO,MAAM,gBAAgB,gBAAgB,CAAA;AA4D7C,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO3G;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAQnE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BrE;AAED,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgCvE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAqExE;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAO3E;AAsLD,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D"}
|