chron-mcp 0.1.12 → 0.1.13

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.
@@ -1,35 +0,0 @@
1
- import type { Db } from '../db/index';
2
- export declare function logMessage(db: Db): (args: {
3
- session_id: string;
4
- role: "user" | "assistant";
5
- content: string;
6
- }) => Promise<{
7
- content: {
8
- type: "text";
9
- text: string;
10
- }[];
11
- isError: boolean;
12
- } | {
13
- content: {
14
- type: "text";
15
- text: string;
16
- }[];
17
- isError?: undefined;
18
- }>;
19
- export declare function logExchange(db: Db): (args: {
20
- session_id: string;
21
- user_content: string;
22
- assistant_content: string;
23
- }) => Promise<{
24
- content: {
25
- type: "text";
26
- text: string;
27
- }[];
28
- isError: boolean;
29
- } | {
30
- content: {
31
- type: "text";
32
- text: string;
33
- }[];
34
- isError?: undefined;
35
- }>;
@@ -1,95 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.logMessage = logMessage;
4
- exports.logExchange = logExchange;
5
- const drizzle_orm_1 = require("drizzle-orm");
6
- const uuid_1 = require("uuid");
7
- const schema_1 = require("../db/schema");
8
- const time_1 = require("../utils/time");
9
- const hash_1 = require("../utils/hash");
10
- function logMessage(db) {
11
- return async (args) => {
12
- const existing = await db.select({ id: schema_1.sessions.id }).from(schema_1.sessions).where((0, drizzle_orm_1.eq)(schema_1.sessions.id, args.session_id)).limit(1);
13
- if (existing.length === 0) {
14
- return { content: [{ type: 'text', text: `Session not found: ${args.session_id}` }], isError: true };
15
- }
16
- const last = await db.select({ content_hash: schema_1.messages.content_hash })
17
- .from(schema_1.messages)
18
- .where((0, drizzle_orm_1.eq)(schema_1.messages.session_id, args.session_id))
19
- .orderBy((0, drizzle_orm_1.desc)(schema_1.messages.created_at), (0, drizzle_orm_1.desc)((0, drizzle_orm_1.sql) `rowid`))
20
- .limit(1);
21
- const now = (0, time_1.localISOString)();
22
- const id = (0, uuid_1.v4)();
23
- const prevHash = last[0]?.content_hash ?? null;
24
- const contentHash = (0, hash_1.computeContentHash)(args.session_id, args.role, args.content, now, prevHash);
25
- await db.insert(schema_1.messages).values({
26
- id,
27
- session_id: args.session_id,
28
- role: args.role,
29
- content: args.content,
30
- created_at: now,
31
- prev_hash: prevHash,
32
- content_hash: contentHash,
33
- });
34
- await db.update(schema_1.sessions)
35
- .set({ updated_at: now })
36
- .where((0, drizzle_orm_1.eq)(schema_1.sessions.id, args.session_id));
37
- return {
38
- content: [{ type: 'text', text: JSON.stringify({ message_id: id, created_at: now, content_hash: contentHash }) }],
39
- };
40
- };
41
- }
42
- function logExchange(db) {
43
- return async (args) => {
44
- const existing = await db.select({ id: schema_1.sessions.id }).from(schema_1.sessions).where((0, drizzle_orm_1.eq)(schema_1.sessions.id, args.session_id)).limit(1);
45
- if (existing.length === 0) {
46
- return { content: [{ type: 'text', text: `Session not found: ${args.session_id}` }], isError: true };
47
- }
48
- const last = await db.select({ content_hash: schema_1.messages.content_hash })
49
- .from(schema_1.messages)
50
- .where((0, drizzle_orm_1.eq)(schema_1.messages.session_id, args.session_id))
51
- .orderBy((0, drizzle_orm_1.desc)(schema_1.messages.created_at), (0, drizzle_orm_1.desc)((0, drizzle_orm_1.sql) `rowid`))
52
- .limit(1);
53
- const userNow = (0, time_1.localISOString)();
54
- const userId = (0, uuid_1.v4)();
55
- const assistantNow = (0, time_1.localISOString)();
56
- const assistantId = (0, uuid_1.v4)();
57
- const prevHash = last[0]?.content_hash ?? null;
58
- const userHash = (0, hash_1.computeContentHash)(args.session_id, 'user', args.user_content, userNow, prevHash);
59
- const assistantHash = (0, hash_1.computeContentHash)(args.session_id, 'assistant', args.assistant_content, assistantNow, userHash);
60
- await db.insert(schema_1.messages).values({
61
- id: userId,
62
- session_id: args.session_id,
63
- role: 'user',
64
- content: args.user_content,
65
- created_at: userNow,
66
- prev_hash: prevHash,
67
- content_hash: userHash,
68
- });
69
- await db.insert(schema_1.messages).values({
70
- id: assistantId,
71
- session_id: args.session_id,
72
- role: 'assistant',
73
- content: args.assistant_content,
74
- created_at: assistantNow,
75
- prev_hash: userHash,
76
- content_hash: assistantHash,
77
- });
78
- await db.update(schema_1.sessions)
79
- .set({ updated_at: assistantNow })
80
- .where((0, drizzle_orm_1.eq)(schema_1.sessions.id, args.session_id));
81
- return {
82
- content: [{
83
- type: 'text',
84
- text: JSON.stringify({
85
- user_message_id: userId,
86
- user_created_at: userNow,
87
- user_content_hash: userHash,
88
- assistant_message_id: assistantId,
89
- assistant_created_at: assistantNow,
90
- assistant_content_hash: assistantHash,
91
- }),
92
- }],
93
- };
94
- };
95
- }
@@ -1,27 +0,0 @@
1
- import type { Db } from '../db/index';
2
- export declare function startSession(db: Db): (args: {
3
- title: string;
4
- ai_tool?: string;
5
- }) => Promise<{
6
- content: {
7
- type: "text";
8
- text: string;
9
- }[];
10
- }>;
11
- export declare function listSessions(db: Db): (args: {
12
- limit?: number;
13
- }) => Promise<{
14
- content: {
15
- type: "text";
16
- text: string;
17
- }[];
18
- }>;
19
- export declare function getSessionHistory(db: Db): (args: {
20
- session_id: string;
21
- limit?: number;
22
- }) => Promise<{
23
- content: {
24
- type: "text";
25
- text: string;
26
- }[];
27
- }>;
@@ -1,93 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.startSession = startSession;
4
- exports.listSessions = listSessions;
5
- exports.getSessionHistory = getSessionHistory;
6
- const drizzle_orm_1 = require("drizzle-orm");
7
- const uuid_1 = require("uuid");
8
- const schema_1 = require("../db/schema");
9
- const time_1 = require("../utils/time");
10
- function startSession(db) {
11
- return async (args) => {
12
- const id = (0, uuid_1.v4)();
13
- const now = (0, time_1.localISOString)();
14
- try {
15
- await db.insert(schema_1.sessions).values({
16
- id,
17
- title: args.title,
18
- ai_tool: args.ai_tool ?? null,
19
- created_at: now,
20
- updated_at: now,
21
- });
22
- return {
23
- content: [{
24
- type: 'text',
25
- text: JSON.stringify({ session_id: id, created: true, message_count: 0, ai_tool: args.ai_tool ?? null }),
26
- }],
27
- };
28
- }
29
- catch (e) {
30
- const isUnique = e?.message?.includes('UNIQUE constraint failed') ||
31
- e?.code === 'SQLITE_CONSTRAINT_UNIQUE' ||
32
- e?.cause?.message?.includes('UNIQUE constraint failed') ||
33
- e?.cause?.extendedCode === 'SQLITE_CONSTRAINT_UNIQUE';
34
- if (!isUnique)
35
- throw e;
36
- const existing = await db.select().from(schema_1.sessions).where((0, drizzle_orm_1.eq)(schema_1.sessions.title, args.title)).limit(1);
37
- const session = existing[0];
38
- const [countRow] = await db.select({ count: (0, drizzle_orm_1.sql) `count(*)` }).from(schema_1.messages).where((0, drizzle_orm_1.eq)(schema_1.messages.session_id, session.id));
39
- await db.update(schema_1.sessions).set({ updated_at: now }).where((0, drizzle_orm_1.eq)(schema_1.sessions.id, session.id));
40
- return {
41
- content: [{
42
- type: 'text',
43
- text: JSON.stringify({ session_id: session.id, created: false, message_count: countRow?.count ?? 0, ai_tool: session.ai_tool }),
44
- }],
45
- };
46
- }
47
- };
48
- }
49
- function listSessions(db) {
50
- return async (args) => {
51
- const rows = await db.select({
52
- id: schema_1.sessions.id,
53
- title: schema_1.sessions.title,
54
- ai_tool: schema_1.sessions.ai_tool,
55
- created_at: schema_1.sessions.created_at,
56
- updated_at: schema_1.sessions.updated_at,
57
- message_count: (0, drizzle_orm_1.sql) `count(${schema_1.messages.id})`,
58
- })
59
- .from(schema_1.sessions)
60
- .leftJoin(schema_1.messages, (0, drizzle_orm_1.eq)(schema_1.messages.session_id, schema_1.sessions.id))
61
- .groupBy(schema_1.sessions.id)
62
- .orderBy((0, drizzle_orm_1.desc)(schema_1.sessions.updated_at));
63
- const limited = args.limit != null ? rows.slice(0, args.limit) : rows;
64
- return {
65
- content: [{
66
- type: 'text',
67
- text: JSON.stringify({ sessions: limited, total: rows.length }),
68
- }],
69
- };
70
- };
71
- }
72
- function getSessionHistory(db) {
73
- return async (args) => {
74
- const [countRow] = await db.select({ count: (0, drizzle_orm_1.sql) `count(*)` })
75
- .from(schema_1.messages)
76
- .where((0, drizzle_orm_1.eq)(schema_1.messages.session_id, args.session_id));
77
- const total = countRow?.count ?? 0;
78
- const baseQuery = db.select().from(schema_1.messages)
79
- .where((0, drizzle_orm_1.eq)(schema_1.messages.session_id, args.session_id))
80
- .orderBy((0, drizzle_orm_1.desc)(schema_1.messages.created_at), (0, drizzle_orm_1.desc)((0, drizzle_orm_1.sql) `rowid`));
81
- const rows = await (args.limit != null ? baseQuery.limit(args.limit) : baseQuery);
82
- const limited = rows.reverse();
83
- return {
84
- content: [{
85
- type: 'text',
86
- text: JSON.stringify({
87
- messages: limited.map(m => ({ role: m.role, content: m.content, created_at: m.created_at })),
88
- total,
89
- }),
90
- }],
91
- };
92
- };
93
- }
@@ -1,9 +0,0 @@
1
- import type { Db } from '../db/index';
2
- export declare function verifySession(db: Db): (args: {
3
- session_id: string;
4
- }) => Promise<{
5
- content: {
6
- type: "text";
7
- text: string;
8
- }[];
9
- }>;
@@ -1,49 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verifySession = verifySession;
4
- const drizzle_orm_1 = require("drizzle-orm");
5
- const schema_1 = require("../db/schema");
6
- const hash_1 = require("../utils/hash");
7
- function verifySession(db) {
8
- return async (args) => {
9
- const rows = await db.select().from(schema_1.messages)
10
- .where((0, drizzle_orm_1.eq)(schema_1.messages.session_id, args.session_id))
11
- .orderBy((0, drizzle_orm_1.asc)(schema_1.messages.created_at), (0, drizzle_orm_1.asc)((0, drizzle_orm_1.sql) `rowid`));
12
- const chained = rows.filter(r => r.content_hash !== null);
13
- if (chained.length === 0) {
14
- return {
15
- content: [{
16
- type: 'text',
17
- text: JSON.stringify({ valid: true, messages: rows.length, chained: 0, note: 'No chained messages — pre-dates hash chaining' }),
18
- }],
19
- };
20
- }
21
- for (let i = 0; i < chained.length; i++) {
22
- const row = chained[i];
23
- const expectedPrev = i === 0 ? null : chained[i - 1].content_hash;
24
- if (row.prev_hash !== expectedPrev) {
25
- return {
26
- content: [{
27
- type: 'text',
28
- text: JSON.stringify({ valid: false, first_break: row.id, reason: 'prev_hash mismatch' }),
29
- }],
30
- };
31
- }
32
- const expected = (0, hash_1.computeContentHash)(row.session_id, row.role, row.content, row.created_at, row.prev_hash);
33
- if (row.content_hash !== expected) {
34
- return {
35
- content: [{
36
- type: 'text',
37
- text: JSON.stringify({ valid: false, first_break: row.id, reason: 'content_hash mismatch — row was tampered' }),
38
- }],
39
- };
40
- }
41
- }
42
- return {
43
- content: [{
44
- type: 'text',
45
- text: JSON.stringify({ valid: true, messages: rows.length, chained: chained.length }),
46
- }],
47
- };
48
- };
49
- }
@@ -1 +0,0 @@
1
- export declare function computeContentHash(sessionId: string, role: string, content: string, createdAt: string, prevHash: string | null): string;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.computeContentHash = computeContentHash;
4
- const crypto_1 = require("crypto");
5
- function computeContentHash(sessionId, role, content, createdAt, prevHash) {
6
- return (0, crypto_1.createHash)('sha256')
7
- .update(`${sessionId}|${role}|${content}|${createdAt}|${prevHash ?? ''}`)
8
- .digest('hex');
9
- }
@@ -1 +0,0 @@
1
- export declare function localISOString(): string;
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.localISOString = localISOString;
4
- function localISOString() {
5
- const d = new Date();
6
- const offsetMin = -d.getTimezoneOffset(); // positive for UTC+, negative for UTC-
7
- const sign = offsetMin >= 0 ? '+' : '-';
8
- const absMin = Math.abs(offsetMin);
9
- const hh = String(Math.floor(absMin / 60)).padStart(2, '0');
10
- const mm = String(absMin % 60).padStart(2, '0');
11
- const year = d.getFullYear();
12
- const month = String(d.getMonth() + 1).padStart(2, '0');
13
- const day = String(d.getDate()).padStart(2, '0');
14
- const hours = String(d.getHours()).padStart(2, '0');
15
- const minutes = String(d.getMinutes()).padStart(2, '0');
16
- const seconds = String(d.getSeconds()).padStart(2, '0');
17
- const ms = String(d.getMilliseconds()).padStart(3, '0');
18
- return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${ms}${sign}${hh}:${mm}`;
19
- }