@hasna/logs 0.1.0 → 0.2.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/dashboard/README.md +73 -0
- package/dashboard/bun.lock +526 -0
- package/dashboard/eslint.config.js +23 -0
- package/dashboard/index.html +13 -0
- package/dashboard/package.json +32 -0
- package/dashboard/public/favicon.svg +1 -0
- package/dashboard/public/icons.svg +24 -0
- package/dashboard/src/App.css +184 -0
- package/dashboard/src/App.tsx +49 -0
- package/dashboard/src/api.ts +33 -0
- package/dashboard/src/assets/hero.png +0 -0
- package/dashboard/src/assets/react.svg +1 -0
- package/dashboard/src/assets/vite.svg +1 -0
- package/dashboard/src/index.css +111 -0
- package/dashboard/src/main.tsx +10 -0
- package/dashboard/src/pages/Alerts.tsx +69 -0
- package/dashboard/src/pages/Issues.tsx +50 -0
- package/dashboard/src/pages/Perf.tsx +75 -0
- package/dashboard/src/pages/Projects.tsx +67 -0
- package/dashboard/src/pages/Summary.tsx +67 -0
- package/dashboard/src/pages/Tail.tsx +65 -0
- package/dashboard/tsconfig.app.json +28 -0
- package/dashboard/tsconfig.json +7 -0
- package/dashboard/tsconfig.node.json +26 -0
- package/dashboard/vite.config.ts +14 -0
- package/dist/cli/index.js +80 -9
- package/dist/mcp/index.js +63 -35
- package/dist/server/index.js +281 -6
- package/package.json +3 -1
- package/sdk/package.json +3 -2
- package/sdk/src/index.ts +1 -1
- package/sdk/src/types.ts +56 -0
- package/src/cli/index.ts +70 -4
- package/src/lib/session-context.ts +28 -0
- package/src/mcp/index.ts +10 -0
- package/src/server/index.ts +4 -1
package/dist/mcp/index.js
CHANGED
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
deleteAlertRule,
|
|
8
8
|
getDb,
|
|
9
9
|
getLatestSnapshot,
|
|
10
|
-
getLogContext,
|
|
11
10
|
getPerfTrend,
|
|
12
11
|
ingestLog,
|
|
13
12
|
listAlertRules,
|
|
@@ -15,15 +14,18 @@ import {
|
|
|
15
14
|
listPages,
|
|
16
15
|
listProjects,
|
|
17
16
|
scoreLabel,
|
|
18
|
-
searchLogs,
|
|
19
17
|
summarizeLogs,
|
|
20
|
-
tailLogs,
|
|
21
18
|
updateIssueStatus
|
|
22
|
-
} from "../index-
|
|
19
|
+
} from "../index-77ss2sf4.js";
|
|
23
20
|
import {
|
|
24
21
|
createJob,
|
|
25
22
|
listJobs
|
|
26
23
|
} from "../jobs-124e878j.js";
|
|
24
|
+
import {
|
|
25
|
+
getLogContext,
|
|
26
|
+
searchLogs,
|
|
27
|
+
tailLogs
|
|
28
|
+
} from "../query-0qv7fvzt.js";
|
|
27
29
|
import {
|
|
28
30
|
getHealth
|
|
29
31
|
} from "../health-f2qrebqc.js";
|
|
@@ -10332,7 +10334,7 @@ __export(exports_core2, {
|
|
|
10332
10334
|
safeDecode: () => safeDecode,
|
|
10333
10335
|
registry: () => registry,
|
|
10334
10336
|
regexes: () => exports_regexes,
|
|
10335
|
-
process: () =>
|
|
10337
|
+
process: () => process2,
|
|
10336
10338
|
prettifyError: () => prettifyError,
|
|
10337
10339
|
parseAsync: () => parseAsync,
|
|
10338
10340
|
parse: () => parse,
|
|
@@ -20796,7 +20798,7 @@ function initializeContext(params) {
|
|
|
20796
20798
|
external: params?.external ?? undefined
|
|
20797
20799
|
};
|
|
20798
20800
|
}
|
|
20799
|
-
function
|
|
20801
|
+
function process2(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
20800
20802
|
var _a2;
|
|
20801
20803
|
const def = schema._zod.def;
|
|
20802
20804
|
const seen = ctx.seen.get(schema);
|
|
@@ -20833,7 +20835,7 @@ function process(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
|
20833
20835
|
if (parent) {
|
|
20834
20836
|
if (!result.ref)
|
|
20835
20837
|
result.ref = parent;
|
|
20836
|
-
|
|
20838
|
+
process2(parent, ctx, params);
|
|
20837
20839
|
ctx.seen.get(parent).isParent = true;
|
|
20838
20840
|
}
|
|
20839
20841
|
}
|
|
@@ -21109,14 +21111,14 @@ function isTransforming(_schema, _ctx) {
|
|
|
21109
21111
|
}
|
|
21110
21112
|
var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
|
|
21111
21113
|
const ctx = initializeContext({ ...params, processors });
|
|
21112
|
-
|
|
21114
|
+
process2(schema, ctx);
|
|
21113
21115
|
extractDefs(ctx, schema);
|
|
21114
21116
|
return finalize(ctx, schema);
|
|
21115
21117
|
};
|
|
21116
21118
|
var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
|
|
21117
21119
|
const { libraryOptions, target } = params ?? {};
|
|
21118
21120
|
const ctx = initializeContext({ ...libraryOptions ?? {}, target, io, processors });
|
|
21119
|
-
|
|
21121
|
+
process2(schema, ctx);
|
|
21120
21122
|
extractDefs(ctx, schema);
|
|
21121
21123
|
return finalize(ctx, schema);
|
|
21122
21124
|
};
|
|
@@ -21367,7 +21369,7 @@ var arrayProcessor = (schema, ctx, _json, params) => {
|
|
|
21367
21369
|
if (typeof maximum === "number")
|
|
21368
21370
|
json.maxItems = maximum;
|
|
21369
21371
|
json.type = "array";
|
|
21370
|
-
json.items =
|
|
21372
|
+
json.items = process2(def.element, ctx, { ...params, path: [...params.path, "items"] });
|
|
21371
21373
|
};
|
|
21372
21374
|
var objectProcessor = (schema, ctx, _json, params) => {
|
|
21373
21375
|
const json = _json;
|
|
@@ -21376,7 +21378,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
21376
21378
|
json.properties = {};
|
|
21377
21379
|
const shape = def.shape;
|
|
21378
21380
|
for (const key in shape) {
|
|
21379
|
-
json.properties[key] =
|
|
21381
|
+
json.properties[key] = process2(shape[key], ctx, {
|
|
21380
21382
|
...params,
|
|
21381
21383
|
path: [...params.path, "properties", key]
|
|
21382
21384
|
});
|
|
@@ -21399,7 +21401,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
21399
21401
|
if (ctx.io === "output")
|
|
21400
21402
|
json.additionalProperties = false;
|
|
21401
21403
|
} else if (def.catchall) {
|
|
21402
|
-
json.additionalProperties =
|
|
21404
|
+
json.additionalProperties = process2(def.catchall, ctx, {
|
|
21403
21405
|
...params,
|
|
21404
21406
|
path: [...params.path, "additionalProperties"]
|
|
21405
21407
|
});
|
|
@@ -21408,7 +21410,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
21408
21410
|
var unionProcessor = (schema, ctx, json, params) => {
|
|
21409
21411
|
const def = schema._zod.def;
|
|
21410
21412
|
const isExclusive = def.inclusive === false;
|
|
21411
|
-
const options = def.options.map((x, i) =>
|
|
21413
|
+
const options = def.options.map((x, i) => process2(x, ctx, {
|
|
21412
21414
|
...params,
|
|
21413
21415
|
path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
|
|
21414
21416
|
}));
|
|
@@ -21420,11 +21422,11 @@ var unionProcessor = (schema, ctx, json, params) => {
|
|
|
21420
21422
|
};
|
|
21421
21423
|
var intersectionProcessor = (schema, ctx, json, params) => {
|
|
21422
21424
|
const def = schema._zod.def;
|
|
21423
|
-
const a =
|
|
21425
|
+
const a = process2(def.left, ctx, {
|
|
21424
21426
|
...params,
|
|
21425
21427
|
path: [...params.path, "allOf", 0]
|
|
21426
21428
|
});
|
|
21427
|
-
const b =
|
|
21429
|
+
const b = process2(def.right, ctx, {
|
|
21428
21430
|
...params,
|
|
21429
21431
|
path: [...params.path, "allOf", 1]
|
|
21430
21432
|
});
|
|
@@ -21441,11 +21443,11 @@ var tupleProcessor = (schema, ctx, _json, params) => {
|
|
|
21441
21443
|
json.type = "array";
|
|
21442
21444
|
const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
21443
21445
|
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
21444
|
-
const prefixItems = def.items.map((x, i) =>
|
|
21446
|
+
const prefixItems = def.items.map((x, i) => process2(x, ctx, {
|
|
21445
21447
|
...params,
|
|
21446
21448
|
path: [...params.path, prefixPath, i]
|
|
21447
21449
|
}));
|
|
21448
|
-
const rest = def.rest ?
|
|
21450
|
+
const rest = def.rest ? process2(def.rest, ctx, {
|
|
21449
21451
|
...params,
|
|
21450
21452
|
path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
|
|
21451
21453
|
}) : null;
|
|
@@ -21485,7 +21487,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
21485
21487
|
const keyBag = keyType._zod.bag;
|
|
21486
21488
|
const patterns = keyBag?.patterns;
|
|
21487
21489
|
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
21488
|
-
const valueSchema =
|
|
21490
|
+
const valueSchema = process2(def.valueType, ctx, {
|
|
21489
21491
|
...params,
|
|
21490
21492
|
path: [...params.path, "patternProperties", "*"]
|
|
21491
21493
|
});
|
|
@@ -21495,12 +21497,12 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
21495
21497
|
}
|
|
21496
21498
|
} else {
|
|
21497
21499
|
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
|
|
21498
|
-
json.propertyNames =
|
|
21500
|
+
json.propertyNames = process2(def.keyType, ctx, {
|
|
21499
21501
|
...params,
|
|
21500
21502
|
path: [...params.path, "propertyNames"]
|
|
21501
21503
|
});
|
|
21502
21504
|
}
|
|
21503
|
-
json.additionalProperties =
|
|
21505
|
+
json.additionalProperties = process2(def.valueType, ctx, {
|
|
21504
21506
|
...params,
|
|
21505
21507
|
path: [...params.path, "additionalProperties"]
|
|
21506
21508
|
});
|
|
@@ -21515,7 +21517,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
21515
21517
|
};
|
|
21516
21518
|
var nullableProcessor = (schema, ctx, json, params) => {
|
|
21517
21519
|
const def = schema._zod.def;
|
|
21518
|
-
const inner =
|
|
21520
|
+
const inner = process2(def.innerType, ctx, params);
|
|
21519
21521
|
const seen = ctx.seen.get(schema);
|
|
21520
21522
|
if (ctx.target === "openapi-3.0") {
|
|
21521
21523
|
seen.ref = def.innerType;
|
|
@@ -21526,20 +21528,20 @@ var nullableProcessor = (schema, ctx, json, params) => {
|
|
|
21526
21528
|
};
|
|
21527
21529
|
var nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
21528
21530
|
const def = schema._zod.def;
|
|
21529
|
-
|
|
21531
|
+
process2(def.innerType, ctx, params);
|
|
21530
21532
|
const seen = ctx.seen.get(schema);
|
|
21531
21533
|
seen.ref = def.innerType;
|
|
21532
21534
|
};
|
|
21533
21535
|
var defaultProcessor = (schema, ctx, json, params) => {
|
|
21534
21536
|
const def = schema._zod.def;
|
|
21535
|
-
|
|
21537
|
+
process2(def.innerType, ctx, params);
|
|
21536
21538
|
const seen = ctx.seen.get(schema);
|
|
21537
21539
|
seen.ref = def.innerType;
|
|
21538
21540
|
json.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
21539
21541
|
};
|
|
21540
21542
|
var prefaultProcessor = (schema, ctx, json, params) => {
|
|
21541
21543
|
const def = schema._zod.def;
|
|
21542
|
-
|
|
21544
|
+
process2(def.innerType, ctx, params);
|
|
21543
21545
|
const seen = ctx.seen.get(schema);
|
|
21544
21546
|
seen.ref = def.innerType;
|
|
21545
21547
|
if (ctx.io === "input")
|
|
@@ -21547,7 +21549,7 @@ var prefaultProcessor = (schema, ctx, json, params) => {
|
|
|
21547
21549
|
};
|
|
21548
21550
|
var catchProcessor = (schema, ctx, json, params) => {
|
|
21549
21551
|
const def = schema._zod.def;
|
|
21550
|
-
|
|
21552
|
+
process2(def.innerType, ctx, params);
|
|
21551
21553
|
const seen = ctx.seen.get(schema);
|
|
21552
21554
|
seen.ref = def.innerType;
|
|
21553
21555
|
let catchValue;
|
|
@@ -21561,32 +21563,32 @@ var catchProcessor = (schema, ctx, json, params) => {
|
|
|
21561
21563
|
var pipeProcessor = (schema, ctx, _json, params) => {
|
|
21562
21564
|
const def = schema._zod.def;
|
|
21563
21565
|
const innerType = ctx.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out;
|
|
21564
|
-
|
|
21566
|
+
process2(innerType, ctx, params);
|
|
21565
21567
|
const seen = ctx.seen.get(schema);
|
|
21566
21568
|
seen.ref = innerType;
|
|
21567
21569
|
};
|
|
21568
21570
|
var readonlyProcessor = (schema, ctx, json, params) => {
|
|
21569
21571
|
const def = schema._zod.def;
|
|
21570
|
-
|
|
21572
|
+
process2(def.innerType, ctx, params);
|
|
21571
21573
|
const seen = ctx.seen.get(schema);
|
|
21572
21574
|
seen.ref = def.innerType;
|
|
21573
21575
|
json.readOnly = true;
|
|
21574
21576
|
};
|
|
21575
21577
|
var promiseProcessor = (schema, ctx, _json, params) => {
|
|
21576
21578
|
const def = schema._zod.def;
|
|
21577
|
-
|
|
21579
|
+
process2(def.innerType, ctx, params);
|
|
21578
21580
|
const seen = ctx.seen.get(schema);
|
|
21579
21581
|
seen.ref = def.innerType;
|
|
21580
21582
|
};
|
|
21581
21583
|
var optionalProcessor = (schema, ctx, _json, params) => {
|
|
21582
21584
|
const def = schema._zod.def;
|
|
21583
|
-
|
|
21585
|
+
process2(def.innerType, ctx, params);
|
|
21584
21586
|
const seen = ctx.seen.get(schema);
|
|
21585
21587
|
seen.ref = def.innerType;
|
|
21586
21588
|
};
|
|
21587
21589
|
var lazyProcessor = (schema, ctx, _json, params) => {
|
|
21588
21590
|
const innerType = schema._zod.innerType;
|
|
21589
|
-
|
|
21591
|
+
process2(innerType, ctx, params);
|
|
21590
21592
|
const seen = ctx.seen.get(schema);
|
|
21591
21593
|
seen.ref = innerType;
|
|
21592
21594
|
};
|
|
@@ -21638,7 +21640,7 @@ function toJSONSchema(input, params) {
|
|
|
21638
21640
|
const defs = {};
|
|
21639
21641
|
for (const entry of registry2._idmap.entries()) {
|
|
21640
21642
|
const [_, schema] = entry;
|
|
21641
|
-
|
|
21643
|
+
process2(schema, ctx2);
|
|
21642
21644
|
}
|
|
21643
21645
|
const schemas = {};
|
|
21644
21646
|
const external = {
|
|
@@ -21661,7 +21663,7 @@ function toJSONSchema(input, params) {
|
|
|
21661
21663
|
return { schemas };
|
|
21662
21664
|
}
|
|
21663
21665
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
21664
|
-
|
|
21666
|
+
process2(input, ctx);
|
|
21665
21667
|
extractDefs(ctx, input);
|
|
21666
21668
|
return finalize(ctx, input);
|
|
21667
21669
|
}
|
|
@@ -21707,7 +21709,7 @@ class JSONSchemaGenerator {
|
|
|
21707
21709
|
});
|
|
21708
21710
|
}
|
|
21709
21711
|
process(schema, _params = { path: [], schemaPath: [] }) {
|
|
21710
|
-
return
|
|
21712
|
+
return process2(schema, this.ctx, _params);
|
|
21711
21713
|
}
|
|
21712
21714
|
emit(schema, _params) {
|
|
21713
21715
|
if (_params) {
|
|
@@ -28288,7 +28290,7 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
28288
28290
|
};
|
|
28289
28291
|
|
|
28290
28292
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
28291
|
-
import
|
|
28293
|
+
import process3 from "process";
|
|
28292
28294
|
|
|
28293
28295
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
28294
28296
|
class ReadBuffer {
|
|
@@ -28322,7 +28324,7 @@ function serializeMessage(message) {
|
|
|
28322
28324
|
|
|
28323
28325
|
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
28324
28326
|
class StdioServerTransport {
|
|
28325
|
-
constructor(_stdin =
|
|
28327
|
+
constructor(_stdin = process3.stdin, _stdout = process3.stdout) {
|
|
28326
28328
|
this._stdin = _stdin;
|
|
28327
28329
|
this._stdout = _stdout;
|
|
28328
28330
|
this._readBuffer = new ReadBuffer;
|
|
@@ -28495,6 +28497,24 @@ function compare(db, projectId, aSince, aUntil, bSince, bUntil) {
|
|
|
28495
28497
|
};
|
|
28496
28498
|
}
|
|
28497
28499
|
|
|
28500
|
+
// src/lib/session-context.ts
|
|
28501
|
+
async function getSessionContext(db, sessionId) {
|
|
28502
|
+
const logs = db.prepare("SELECT * FROM logs WHERE session_id = $s ORDER BY timestamp ASC").all({ $s: sessionId });
|
|
28503
|
+
const sessionsUrl = process.env.SESSIONS_URL;
|
|
28504
|
+
if (!sessionsUrl) {
|
|
28505
|
+
return { session_id: sessionId, logs };
|
|
28506
|
+
}
|
|
28507
|
+
try {
|
|
28508
|
+
const res = await fetch(`${sessionsUrl.replace(/\/$/, "")}/api/sessions/${sessionId}`);
|
|
28509
|
+
if (!res.ok)
|
|
28510
|
+
return { session_id: sessionId, logs };
|
|
28511
|
+
const session = await res.json();
|
|
28512
|
+
return { session_id: sessionId, logs, session };
|
|
28513
|
+
} catch (err) {
|
|
28514
|
+
return { session_id: sessionId, logs, error: String(err) };
|
|
28515
|
+
}
|
|
28516
|
+
}
|
|
28517
|
+
|
|
28498
28518
|
// src/mcp/index.ts
|
|
28499
28519
|
var db = getDb();
|
|
28500
28520
|
var server = new McpServer({ name: "logs", version: "0.1.0" });
|
|
@@ -28524,6 +28544,7 @@ var TOOLS = {
|
|
|
28524
28544
|
create_alert_rule: "Create alert rule (project_id, name, level, threshold_count, window_seconds, webhook_url?)",
|
|
28525
28545
|
list_alert_rules: "List alert rules (project_id?)",
|
|
28526
28546
|
delete_alert_rule: "Delete alert rule (id)",
|
|
28547
|
+
log_session_context: "Logs + session metadata for a session_id (requires SESSIONS_URL env)",
|
|
28527
28548
|
get_health: "Server health + DB stats",
|
|
28528
28549
|
search_tools: "Search tools by keyword (query)",
|
|
28529
28550
|
describe_tools: "List all tools"
|
|
@@ -28678,6 +28699,13 @@ server.tool("delete_alert_rule", { id: exports_external.string() }, ({ id }) =>
|
|
|
28678
28699
|
deleteAlertRule(db, id);
|
|
28679
28700
|
return { content: [{ type: "text", text: "deleted" }] };
|
|
28680
28701
|
});
|
|
28702
|
+
server.tool("log_session_context", {
|
|
28703
|
+
session_id: exports_external.string(),
|
|
28704
|
+
brief: exports_external.boolean().optional()
|
|
28705
|
+
}, async ({ session_id, brief }) => {
|
|
28706
|
+
const ctx = await getSessionContext(db, session_id);
|
|
28707
|
+
return { content: [{ type: "text", text: JSON.stringify({ ...ctx, logs: applyBrief(ctx.logs, brief !== false) }) }] };
|
|
28708
|
+
});
|
|
28681
28709
|
server.tool("get_health", {}, () => ({
|
|
28682
28710
|
content: [{ type: "text", text: JSON.stringify(getHealth(db)) }]
|
|
28683
28711
|
}));
|
package/dist/server/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
setPageAuth,
|
|
7
7
|
setRetentionPolicy,
|
|
8
8
|
startScheduler
|
|
9
|
-
} from "../index-
|
|
9
|
+
} from "../index-2p6ynjet.js";
|
|
10
10
|
import {
|
|
11
11
|
createAlertRule,
|
|
12
12
|
createPage,
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
getDb,
|
|
16
16
|
getIssue,
|
|
17
17
|
getLatestSnapshot,
|
|
18
|
-
getLogContext,
|
|
19
18
|
getPerfTrend,
|
|
20
19
|
getProject,
|
|
21
20
|
ingestBatch,
|
|
@@ -24,19 +23,22 @@ import {
|
|
|
24
23
|
listIssues,
|
|
25
24
|
listPages,
|
|
26
25
|
listProjects,
|
|
27
|
-
searchLogs,
|
|
28
26
|
summarizeLogs,
|
|
29
|
-
tailLogs,
|
|
30
27
|
updateAlertRule,
|
|
31
28
|
updateIssueStatus,
|
|
32
29
|
updateProject
|
|
33
|
-
} from "../index-
|
|
30
|
+
} from "../index-77ss2sf4.js";
|
|
34
31
|
import {
|
|
35
32
|
createJob,
|
|
36
33
|
deleteJob,
|
|
37
34
|
listJobs,
|
|
38
35
|
updateJob
|
|
39
36
|
} from "../jobs-124e878j.js";
|
|
37
|
+
import {
|
|
38
|
+
getLogContext,
|
|
39
|
+
searchLogs,
|
|
40
|
+
tailLogs
|
|
41
|
+
} from "../query-0qv7fvzt.js";
|
|
40
42
|
import {
|
|
41
43
|
exportToCsv,
|
|
42
44
|
exportToJson
|
|
@@ -1669,6 +1671,277 @@ var cors = (options) => {
|
|
|
1669
1671
|
};
|
|
1670
1672
|
};
|
|
1671
1673
|
|
|
1674
|
+
// node_modules/hono/dist/adapter/bun/serve-static.js
|
|
1675
|
+
import { stat } from "fs/promises";
|
|
1676
|
+
import { join } from "path";
|
|
1677
|
+
|
|
1678
|
+
// node_modules/hono/dist/utils/compress.js
|
|
1679
|
+
var COMPRESSIBLE_CONTENT_TYPE_REGEX = /^\s*(?:text\/(?!event-stream(?:[;\s]|$))[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
|
|
1680
|
+
|
|
1681
|
+
// node_modules/hono/dist/utils/mime.js
|
|
1682
|
+
var getMimeType = (filename, mimes = baseMimes) => {
|
|
1683
|
+
const regexp = /\.([a-zA-Z0-9]+?)$/;
|
|
1684
|
+
const match2 = filename.match(regexp);
|
|
1685
|
+
if (!match2) {
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
let mimeType = mimes[match2[1].toLowerCase()];
|
|
1689
|
+
if (mimeType && mimeType.startsWith("text")) {
|
|
1690
|
+
mimeType += "; charset=utf-8";
|
|
1691
|
+
}
|
|
1692
|
+
return mimeType;
|
|
1693
|
+
};
|
|
1694
|
+
var _baseMimes = {
|
|
1695
|
+
aac: "audio/aac",
|
|
1696
|
+
avi: "video/x-msvideo",
|
|
1697
|
+
avif: "image/avif",
|
|
1698
|
+
av1: "video/av1",
|
|
1699
|
+
bin: "application/octet-stream",
|
|
1700
|
+
bmp: "image/bmp",
|
|
1701
|
+
css: "text/css",
|
|
1702
|
+
csv: "text/csv",
|
|
1703
|
+
eot: "application/vnd.ms-fontobject",
|
|
1704
|
+
epub: "application/epub+zip",
|
|
1705
|
+
gif: "image/gif",
|
|
1706
|
+
gz: "application/gzip",
|
|
1707
|
+
htm: "text/html",
|
|
1708
|
+
html: "text/html",
|
|
1709
|
+
ico: "image/x-icon",
|
|
1710
|
+
ics: "text/calendar",
|
|
1711
|
+
jpeg: "image/jpeg",
|
|
1712
|
+
jpg: "image/jpeg",
|
|
1713
|
+
js: "text/javascript",
|
|
1714
|
+
json: "application/json",
|
|
1715
|
+
jsonld: "application/ld+json",
|
|
1716
|
+
map: "application/json",
|
|
1717
|
+
mid: "audio/x-midi",
|
|
1718
|
+
midi: "audio/x-midi",
|
|
1719
|
+
mjs: "text/javascript",
|
|
1720
|
+
mp3: "audio/mpeg",
|
|
1721
|
+
mp4: "video/mp4",
|
|
1722
|
+
mpeg: "video/mpeg",
|
|
1723
|
+
oga: "audio/ogg",
|
|
1724
|
+
ogv: "video/ogg",
|
|
1725
|
+
ogx: "application/ogg",
|
|
1726
|
+
opus: "audio/opus",
|
|
1727
|
+
otf: "font/otf",
|
|
1728
|
+
pdf: "application/pdf",
|
|
1729
|
+
png: "image/png",
|
|
1730
|
+
rtf: "application/rtf",
|
|
1731
|
+
svg: "image/svg+xml",
|
|
1732
|
+
tif: "image/tiff",
|
|
1733
|
+
tiff: "image/tiff",
|
|
1734
|
+
ts: "video/mp2t",
|
|
1735
|
+
ttf: "font/ttf",
|
|
1736
|
+
txt: "text/plain",
|
|
1737
|
+
wasm: "application/wasm",
|
|
1738
|
+
webm: "video/webm",
|
|
1739
|
+
weba: "audio/webm",
|
|
1740
|
+
webmanifest: "application/manifest+json",
|
|
1741
|
+
webp: "image/webp",
|
|
1742
|
+
woff: "font/woff",
|
|
1743
|
+
woff2: "font/woff2",
|
|
1744
|
+
xhtml: "application/xhtml+xml",
|
|
1745
|
+
xml: "application/xml",
|
|
1746
|
+
zip: "application/zip",
|
|
1747
|
+
"3gp": "video/3gpp",
|
|
1748
|
+
"3g2": "video/3gpp2",
|
|
1749
|
+
gltf: "model/gltf+json",
|
|
1750
|
+
glb: "model/gltf-binary"
|
|
1751
|
+
};
|
|
1752
|
+
var baseMimes = _baseMimes;
|
|
1753
|
+
|
|
1754
|
+
// node_modules/hono/dist/middleware/serve-static/path.js
|
|
1755
|
+
var defaultJoin = (...paths) => {
|
|
1756
|
+
let result = paths.filter((p) => p !== "").join("/");
|
|
1757
|
+
result = result.replace(/(?<=\/)\/+/g, "");
|
|
1758
|
+
const segments = result.split("/");
|
|
1759
|
+
const resolved = [];
|
|
1760
|
+
for (const segment of segments) {
|
|
1761
|
+
if (segment === ".." && resolved.length > 0 && resolved.at(-1) !== "..") {
|
|
1762
|
+
resolved.pop();
|
|
1763
|
+
} else if (segment !== ".") {
|
|
1764
|
+
resolved.push(segment);
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
return resolved.join("/") || ".";
|
|
1768
|
+
};
|
|
1769
|
+
|
|
1770
|
+
// node_modules/hono/dist/middleware/serve-static/index.js
|
|
1771
|
+
var ENCODINGS = {
|
|
1772
|
+
br: ".br",
|
|
1773
|
+
zstd: ".zst",
|
|
1774
|
+
gzip: ".gz"
|
|
1775
|
+
};
|
|
1776
|
+
var ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
|
|
1777
|
+
var DEFAULT_DOCUMENT = "index.html";
|
|
1778
|
+
var serveStatic = (options) => {
|
|
1779
|
+
const root = options.root ?? "./";
|
|
1780
|
+
const optionPath = options.path;
|
|
1781
|
+
const join = options.join ?? defaultJoin;
|
|
1782
|
+
return async (c, next) => {
|
|
1783
|
+
if (c.finalized) {
|
|
1784
|
+
return next();
|
|
1785
|
+
}
|
|
1786
|
+
let filename;
|
|
1787
|
+
if (options.path) {
|
|
1788
|
+
filename = options.path;
|
|
1789
|
+
} else {
|
|
1790
|
+
try {
|
|
1791
|
+
filename = tryDecodeURI(c.req.path);
|
|
1792
|
+
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
1793
|
+
throw new Error;
|
|
1794
|
+
}
|
|
1795
|
+
} catch {
|
|
1796
|
+
await options.onNotFound?.(c.req.path, c);
|
|
1797
|
+
return next();
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
let path = join(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
|
|
1801
|
+
if (options.isDir && await options.isDir(path)) {
|
|
1802
|
+
path = join(path, DEFAULT_DOCUMENT);
|
|
1803
|
+
}
|
|
1804
|
+
const getContent = options.getContent;
|
|
1805
|
+
let content = await getContent(path, c);
|
|
1806
|
+
if (content instanceof Response) {
|
|
1807
|
+
return c.newResponse(content.body, content);
|
|
1808
|
+
}
|
|
1809
|
+
if (content) {
|
|
1810
|
+
const mimeType = options.mimes && getMimeType(path, options.mimes) || getMimeType(path);
|
|
1811
|
+
c.header("Content-Type", mimeType || "application/octet-stream");
|
|
1812
|
+
if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
|
|
1813
|
+
const acceptEncodingSet = new Set(c.req.header("Accept-Encoding")?.split(",").map((encoding) => encoding.trim()));
|
|
1814
|
+
for (const encoding of ENCODINGS_ORDERED_KEYS) {
|
|
1815
|
+
if (!acceptEncodingSet.has(encoding)) {
|
|
1816
|
+
continue;
|
|
1817
|
+
}
|
|
1818
|
+
const compressedContent = await getContent(path + ENCODINGS[encoding], c);
|
|
1819
|
+
if (compressedContent) {
|
|
1820
|
+
content = compressedContent;
|
|
1821
|
+
c.header("Content-Encoding", encoding);
|
|
1822
|
+
c.header("Vary", "Accept-Encoding", { append: true });
|
|
1823
|
+
break;
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
await options.onFound?.(path, c);
|
|
1828
|
+
return c.body(content);
|
|
1829
|
+
}
|
|
1830
|
+
await options.onNotFound?.(path, c);
|
|
1831
|
+
await next();
|
|
1832
|
+
return;
|
|
1833
|
+
};
|
|
1834
|
+
};
|
|
1835
|
+
|
|
1836
|
+
// node_modules/hono/dist/adapter/bun/serve-static.js
|
|
1837
|
+
var serveStatic2 = (options) => {
|
|
1838
|
+
return async function serveStatic2(c, next) {
|
|
1839
|
+
const getContent = async (path) => {
|
|
1840
|
+
const file = Bun.file(path);
|
|
1841
|
+
return await file.exists() ? file : null;
|
|
1842
|
+
};
|
|
1843
|
+
const isDir = async (path) => {
|
|
1844
|
+
let isDir2;
|
|
1845
|
+
try {
|
|
1846
|
+
const stats = await stat(path);
|
|
1847
|
+
isDir2 = stats.isDirectory();
|
|
1848
|
+
} catch {}
|
|
1849
|
+
return isDir2;
|
|
1850
|
+
};
|
|
1851
|
+
return serveStatic({
|
|
1852
|
+
...options,
|
|
1853
|
+
getContent,
|
|
1854
|
+
join,
|
|
1855
|
+
isDir
|
|
1856
|
+
})(c, next);
|
|
1857
|
+
};
|
|
1858
|
+
};
|
|
1859
|
+
|
|
1860
|
+
// node_modules/hono/dist/helper/ssg/middleware.js
|
|
1861
|
+
var X_HONO_DISABLE_SSG_HEADER_KEY = "x-hono-disable-ssg";
|
|
1862
|
+
var SSG_DISABLED_RESPONSE = (() => {
|
|
1863
|
+
try {
|
|
1864
|
+
return new Response("SSG is disabled", {
|
|
1865
|
+
status: 404,
|
|
1866
|
+
headers: { [X_HONO_DISABLE_SSG_HEADER_KEY]: "true" }
|
|
1867
|
+
});
|
|
1868
|
+
} catch {
|
|
1869
|
+
return null;
|
|
1870
|
+
}
|
|
1871
|
+
})();
|
|
1872
|
+
// node_modules/hono/dist/adapter/bun/ssg.js
|
|
1873
|
+
var { write } = Bun;
|
|
1874
|
+
|
|
1875
|
+
// node_modules/hono/dist/helper/websocket/index.js
|
|
1876
|
+
var WSContext = class {
|
|
1877
|
+
#init;
|
|
1878
|
+
constructor(init) {
|
|
1879
|
+
this.#init = init;
|
|
1880
|
+
this.raw = init.raw;
|
|
1881
|
+
this.url = init.url ? new URL(init.url) : null;
|
|
1882
|
+
this.protocol = init.protocol ?? null;
|
|
1883
|
+
}
|
|
1884
|
+
send(source, options) {
|
|
1885
|
+
this.#init.send(source, options ?? {});
|
|
1886
|
+
}
|
|
1887
|
+
raw;
|
|
1888
|
+
binaryType = "arraybuffer";
|
|
1889
|
+
get readyState() {
|
|
1890
|
+
return this.#init.readyState;
|
|
1891
|
+
}
|
|
1892
|
+
url;
|
|
1893
|
+
protocol;
|
|
1894
|
+
close(code, reason) {
|
|
1895
|
+
this.#init.close(code, reason);
|
|
1896
|
+
}
|
|
1897
|
+
};
|
|
1898
|
+
var defineWebSocketHelper = (handler) => {
|
|
1899
|
+
return (...args) => {
|
|
1900
|
+
if (typeof args[0] === "function") {
|
|
1901
|
+
const [createEvents, options] = args;
|
|
1902
|
+
return async function upgradeWebSocket(c, next) {
|
|
1903
|
+
const events = await createEvents(c);
|
|
1904
|
+
const result = await handler(c, events, options);
|
|
1905
|
+
if (result) {
|
|
1906
|
+
return result;
|
|
1907
|
+
}
|
|
1908
|
+
await next();
|
|
1909
|
+
};
|
|
1910
|
+
} else {
|
|
1911
|
+
const [c, events, options] = args;
|
|
1912
|
+
return (async () => {
|
|
1913
|
+
const upgraded = await handler(c, events, options);
|
|
1914
|
+
if (!upgraded) {
|
|
1915
|
+
throw new Error("Failed to upgrade WebSocket");
|
|
1916
|
+
}
|
|
1917
|
+
return upgraded;
|
|
1918
|
+
})();
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1921
|
+
};
|
|
1922
|
+
|
|
1923
|
+
// node_modules/hono/dist/adapter/bun/server.js
|
|
1924
|
+
var getBunServer = (c) => ("server" in c.env) ? c.env.server : c.env;
|
|
1925
|
+
|
|
1926
|
+
// node_modules/hono/dist/adapter/bun/websocket.js
|
|
1927
|
+
var upgradeWebSocket = defineWebSocketHelper((c, events) => {
|
|
1928
|
+
const server = getBunServer(c);
|
|
1929
|
+
if (!server) {
|
|
1930
|
+
throw new TypeError("env has to include the 2nd argument of fetch.");
|
|
1931
|
+
}
|
|
1932
|
+
const upgradeResult = server.upgrade(c.req.raw, {
|
|
1933
|
+
data: {
|
|
1934
|
+
events,
|
|
1935
|
+
url: new URL(c.req.url),
|
|
1936
|
+
protocol: c.req.url
|
|
1937
|
+
}
|
|
1938
|
+
});
|
|
1939
|
+
if (upgradeResult) {
|
|
1940
|
+
return new Response(null);
|
|
1941
|
+
}
|
|
1942
|
+
return;
|
|
1943
|
+
});
|
|
1944
|
+
|
|
1672
1945
|
// src/lib/browser-script.ts
|
|
1673
1946
|
function getBrowserScript(serverUrl) {
|
|
1674
1947
|
return `(function(){
|
|
@@ -2160,7 +2433,9 @@ app.route("/api/alerts", alertsRoutes(db));
|
|
|
2160
2433
|
app.route("/api/issues", issuesRoutes(db));
|
|
2161
2434
|
app.route("/api/perf", perfRoutes(db));
|
|
2162
2435
|
app.get("/health", (c) => c.json(getHealth(db)));
|
|
2163
|
-
app.get("/", (c) => c.
|
|
2436
|
+
app.get("/dashboard", (c) => c.redirect("/dashboard/"));
|
|
2437
|
+
app.use("/dashboard/*", serveStatic2({ root: "./dashboard/dist", rewriteRequestPath: (p) => p.replace(/^\/dashboard/, "") }));
|
|
2438
|
+
app.get("/", (c) => c.json({ service: "@hasna/logs", port: PORT, status: "ok", dashboard: `http://localhost:${PORT}/dashboard/` }));
|
|
2164
2439
|
startScheduler(db);
|
|
2165
2440
|
console.log(`@hasna/logs server running on http://localhost:${PORT}`);
|
|
2166
2441
|
var server_default = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/logs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Log aggregation + browser script + headless page scanner + performance monitoring for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "bun build src/cli/index.ts src/mcp/index.ts src/server/index.ts --outdir dist --target bun --splitting --external playwright --external playwright-core --external electron --external chromium-bidi --external lighthouse",
|
|
15
|
+
"build:dashboard": "cd dashboard && bun run build",
|
|
16
|
+
"build:all": "bun run build:dashboard && bun run build",
|
|
15
17
|
"dev": "bun run src/server/index.ts",
|
|
16
18
|
"test": "bun test",
|
|
17
19
|
"test:coverage": "bun test --coverage",
|
package/sdk/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/logs-sdk",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "Zero-dependency fetch client for @hasna/logs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Zero-dependency fetch client for @hasna/logs — push logs, query, browse issues, perf snapshots",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"build": "bun build src/index.ts --outdir dist --target browser"
|
|
18
18
|
},
|
|
19
|
+
"keywords": ["logs", "monitoring", "sdk", "ai-agents"],
|
|
19
20
|
"author": "Andrei Hasna <andrei@hasna.com>",
|
|
20
21
|
"license": "MIT"
|
|
21
22
|
}
|