daybrain 0.3.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.
Files changed (51) hide show
  1. package/bin/daybrain.js +18 -0
  2. package/dist/aw.d.ts +30 -0
  3. package/dist/aw.d.ts.map +1 -0
  4. package/dist/aw.js +145 -0
  5. package/dist/aw.js.map +1 -0
  6. package/dist/baseline.d.ts +31 -0
  7. package/dist/baseline.d.ts.map +1 -0
  8. package/dist/baseline.js +130 -0
  9. package/dist/baseline.js.map +1 -0
  10. package/dist/config.d.ts +36 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +139 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/db.d.ts +72 -0
  15. package/dist/db.d.ts.map +1 -0
  16. package/dist/db.js +261 -0
  17. package/dist/db.js.map +1 -0
  18. package/dist/http.d.ts +5 -0
  19. package/dist/http.d.ts.map +1 -0
  20. package/dist/http.js +411 -0
  21. package/dist/http.js.map +1 -0
  22. package/dist/index.d.ts +16 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +908 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/insights.d.ts +68 -0
  27. package/dist/insights.d.ts.map +1 -0
  28. package/dist/insights.js +523 -0
  29. package/dist/insights.js.map +1 -0
  30. package/dist/onboard.d.ts +2 -0
  31. package/dist/onboard.d.ts.map +1 -0
  32. package/dist/onboard.js +121 -0
  33. package/dist/onboard.js.map +1 -0
  34. package/dist/scheduler.d.ts +8 -0
  35. package/dist/scheduler.d.ts.map +1 -0
  36. package/dist/scheduler.js +214 -0
  37. package/dist/scheduler.js.map +1 -0
  38. package/dist/screenpipe.d.ts +25 -0
  39. package/dist/screenpipe.d.ts.map +1 -0
  40. package/dist/screenpipe.js +71 -0
  41. package/dist/screenpipe.js.map +1 -0
  42. package/dist/transport.d.ts +12 -0
  43. package/dist/transport.d.ts.map +1 -0
  44. package/dist/transport.js +152 -0
  45. package/dist/transport.js.map +1 -0
  46. package/dist/watcher.d.ts +15 -0
  47. package/dist/watcher.d.ts.map +1 -0
  48. package/dist/watcher.js +173 -0
  49. package/dist/watcher.js.map +1 -0
  50. package/package.json +58 -0
  51. package/watcher.py +139 -0
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+
6
+ const distPath = path.join(__dirname, '..', 'dist', 'index.js');
7
+
8
+ if (!fs.existsSync(distPath)) {
9
+ console.error('daybrain is not built. Run: npm run build');
10
+ process.exit(1);
11
+ }
12
+
13
+ const { main } = require(distPath);
14
+
15
+ main().catch((err) => {
16
+ console.error('[opencontext] Fatal error:', err instanceof Error ? err.message : String(err));
17
+ process.exit(1);
18
+ });
package/dist/aw.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ export interface AWEvent {
2
+ timestamp: string;
3
+ duration: number;
4
+ data: Record<string, unknown>;
5
+ }
6
+ export interface AWQueryResult {
7
+ [bucketId: string]: AWEvent[];
8
+ }
9
+ export declare class ActivityWatchClient {
10
+ private baseUrl;
11
+ constructor(baseUrl?: string);
12
+ healthCheck(): Promise<{
13
+ ok: boolean;
14
+ version?: string;
15
+ error?: string;
16
+ }>;
17
+ getBuckets(): Promise<{
18
+ ok: boolean;
19
+ buckets: Record<string, string>;
20
+ error?: string;
21
+ }>;
22
+ query(timeperiods: string[], queryLines: string[]): Promise<AWQueryResult>;
23
+ getWindowEvents(period?: string): Promise<AWEvent[]>;
24
+ getBrowserEvents(period?: string): Promise<AWEvent[]>;
25
+ getAFKEvents(period?: string): Promise<AWEvent[]>;
26
+ fetchAndStore(periodStart: string, periodEnd: string): Promise<number>;
27
+ getWindowEventsByRange(periodStart: string, periodEnd: string): Promise<AWEvent[]>;
28
+ }
29
+ export declare function createAWClient(baseUrl?: string): ActivityWatchClient;
30
+ //# sourceMappingURL=aw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aw.d.ts","sourceRoot":"","sources":["../src/aw.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;CAC/B;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAItB,WAAW,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAWzE,UAAU,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAgBvF,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAiB1E,eAAe,CAAC,MAAM,GAAE,MAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAqB7D,gBAAgB,CAAC,MAAM,GAAE,MAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAqB9D,YAAY,CAAC,MAAM,GAAE,MAAgB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAqB1D,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBtE,sBAAsB,CAC1B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,EAAE,CAAC;CAoBtB;AAED,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAEpE"}
package/dist/aw.js ADDED
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActivityWatchClient = void 0;
4
+ exports.createAWClient = createAWClient;
5
+ const config_1 = require("./config");
6
+ const db_1 = require("./db");
7
+ class ActivityWatchClient {
8
+ baseUrl;
9
+ constructor(baseUrl) {
10
+ this.baseUrl = baseUrl || (0, config_1.getConfig)().activitywatch.baseUrl;
11
+ }
12
+ async healthCheck() {
13
+ try {
14
+ const res = await fetch(`${this.baseUrl}/api/0/info`, { signal: AbortSignal.timeout(3000) });
15
+ if (!res.ok)
16
+ return { ok: false, error: `HTTP ${res.status}` };
17
+ const json = await res.json();
18
+ return { ok: true, version: json.version || 'unknown' };
19
+ }
20
+ catch (err) {
21
+ return { ok: false, error: String(err) };
22
+ }
23
+ }
24
+ async getBuckets() {
25
+ try {
26
+ const res = await fetch(`${this.baseUrl}/api/0/buckets`, { signal: AbortSignal.timeout(5000) });
27
+ if (!res.ok)
28
+ return { ok: false, buckets: {}, error: `HTTP ${res.status}` };
29
+ const json = await res.json();
30
+ const buckets = {};
31
+ for (const [key, val] of Object.entries(json)) {
32
+ buckets[key] = val.type;
33
+ }
34
+ return { ok: true, buckets };
35
+ }
36
+ catch (err) {
37
+ console.error('[daybrain] AW getBuckets failed:', err instanceof Error ? err.message : String(err));
38
+ return { ok: false, buckets: {}, error: String(err) };
39
+ }
40
+ }
41
+ async query(timeperiods, queryLines) {
42
+ try {
43
+ const res = await fetch(`${this.baseUrl}/api/0/query/`, {
44
+ method: 'POST',
45
+ headers: { 'Content-Type': 'application/json' },
46
+ body: JSON.stringify({ timeperiods, query: queryLines }),
47
+ signal: AbortSignal.timeout(15000),
48
+ });
49
+ if (!res.ok) {
50
+ throw new Error(`Query failed: HTTP ${res.status}`);
51
+ }
52
+ return await res.json();
53
+ }
54
+ catch (err) {
55
+ throw new Error(`ActivityWatch query failed: ${err}`);
56
+ }
57
+ }
58
+ async getWindowEvents(period = 'today') {
59
+ const timeperiods = [period];
60
+ const queryLines = [
61
+ 'window_events = query_bucket("aw-watcher-window_*");',
62
+ `window_events = filter_period_intersect(window_events, "${period}");`,
63
+ 'window_events = sort_by_timestamp(window_events);',
64
+ 'RETURN = window_events;',
65
+ ];
66
+ const result = await this.query(timeperiods, queryLines);
67
+ const allEvents = [];
68
+ for (const events of Object.values(result)) {
69
+ if (Array.isArray(events)) {
70
+ allEvents.push(...events);
71
+ }
72
+ }
73
+ return allEvents.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
74
+ }
75
+ async getBrowserEvents(period = 'today') {
76
+ const timeperiods = [period];
77
+ const queryLines = [
78
+ 'browser_events = query_bucket("aw-watcher-web-*");',
79
+ `browser_events = filter_period_intersect(browser_events, "${period}");`,
80
+ 'browser_events = sort_by_timestamp(browser_events);',
81
+ 'RETURN = browser_events;',
82
+ ];
83
+ const result = await this.query(timeperiods, queryLines);
84
+ const allEvents = [];
85
+ for (const events of Object.values(result)) {
86
+ if (Array.isArray(events)) {
87
+ allEvents.push(...events);
88
+ }
89
+ }
90
+ return allEvents.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
91
+ }
92
+ async getAFKEvents(period = 'today') {
93
+ const timeperiods = [period];
94
+ const queryLines = [
95
+ 'afk_events = query_bucket("aw-watcher-afk_*");',
96
+ `afk_events = filter_period_intersect(afk_events, "${period}");`,
97
+ 'afk_events = sort_by_timestamp(afk_events);',
98
+ 'RETURN = afk_events;',
99
+ ];
100
+ const result = await this.query(timeperiods, queryLines);
101
+ const allEvents = [];
102
+ for (const events of Object.values(result)) {
103
+ if (Array.isArray(events)) {
104
+ allEvents.push(...events);
105
+ }
106
+ }
107
+ return allEvents.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
108
+ }
109
+ async fetchAndStore(periodStart, periodEnd) {
110
+ const windowEvents = await this.getWindowEventsByRange(periodStart, periodEnd);
111
+ const rawEvents = windowEvents.map((evt) => ({
112
+ source: 'activitywatch',
113
+ bucket_id: 'aw-watcher-window',
114
+ timestamp: evt.timestamp,
115
+ duration: evt.duration,
116
+ app: String(evt.data?.app || ''),
117
+ title: String(evt.data?.title || ''),
118
+ url: String(evt.data?.url || ''),
119
+ raw_data: JSON.stringify(evt.data),
120
+ }));
121
+ return (0, db_1.insertRawEvents)(rawEvents);
122
+ }
123
+ async getWindowEventsByRange(periodStart, periodEnd) {
124
+ const timeperiods = [`${periodStart}/${periodEnd}`];
125
+ const queryLines = [
126
+ 'window_events = query_bucket("aw-watcher-window_*");',
127
+ `window_events = filter_period_intersect(window_events, "${periodStart}/${periodEnd}");`,
128
+ 'window_events = sort_by_timestamp(window_events);',
129
+ 'RETURN = window_events;',
130
+ ];
131
+ const result = await this.query(timeperiods, queryLines);
132
+ const allEvents = [];
133
+ for (const events of Object.values(result)) {
134
+ if (Array.isArray(events)) {
135
+ allEvents.push(...events);
136
+ }
137
+ }
138
+ return allEvents.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
139
+ }
140
+ }
141
+ exports.ActivityWatchClient = ActivityWatchClient;
142
+ function createAWClient(baseUrl) {
143
+ return new ActivityWatchClient(baseUrl);
144
+ }
145
+ //# sourceMappingURL=aw.js.map
package/dist/aw.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aw.js","sourceRoot":"","sources":["../src/aw.ts"],"names":[],"mappings":";;;AAyKA,wCAEC;AA3KD,qCAAqC;AACrC,6BAAuC;AAYvC,MAAa,mBAAmB;IACtB,OAAO,CAAS;IAExB,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,IAAA,kBAAS,GAAE,CAAC,aAAa,CAAC,OAAO,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,aAAa,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7F,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/D,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAA6C,CAAC;YACzE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,gBAAgB,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChG,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5E,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAkD,CAAC;YAC9E,MAAM,OAAO,GAA2B,EAAE,CAAC;YAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1B,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACpG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,WAAqB,EAAE,UAAoB;QACrD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,eAAe,EAAE;gBACtD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;gBACxD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,MAAM,GAAG,CAAC,IAAI,EAAmB,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,SAAiB,OAAO;QAC5C,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG;YACjB,sDAAsD;YACtD,2DAA2D,MAAM,KAAK;YACtE,mDAAmD;YACnD,yBAAyB;SAC1B,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,MAAM,SAAS,GAAc,EAAE,CAAC;QAChC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC,IAAI,CACnB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAC5E,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,SAAiB,OAAO;QAC7C,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG;YACjB,oDAAoD;YACpD,6DAA6D,MAAM,KAAK;YACxE,qDAAqD;YACrD,0BAA0B;SAC3B,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,MAAM,SAAS,GAAc,EAAE,CAAC;QAChC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC,IAAI,CACnB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAC5E,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,SAAiB,OAAO;QACzC,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG;YACjB,gDAAgD;YAChD,qDAAqD,MAAM,KAAK;YAChE,6CAA6C;YAC7C,sBAAsB;SACvB,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,MAAM,SAAS,GAAc,EAAE,CAAC;QAChC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC,IAAI,CACnB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAC5E,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,WAAmB,EAAE,SAAiB;QACxD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAE/E,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,GAAY,EAAE,EAAE,CAAC,CAAC;YACpD,MAAM,EAAE,eAAwB;YAChC,SAAS,EAAE,mBAAmB;YAC9B,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;YAChC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACpC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;YAChC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;SACnC,CAAC,CAAC,CAAC;QAEJ,OAAO,IAAA,oBAAe,EAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,WAAmB,EACnB,SAAiB;QAEjB,MAAM,WAAW,GAAG,CAAC,GAAG,WAAW,IAAI,SAAS,EAAE,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG;YACjB,sDAAsD;YACtD,2DAA2D,WAAW,IAAI,SAAS,KAAK;YACxF,mDAAmD;YACnD,yBAAyB;SAC1B,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,MAAM,SAAS,GAAc,EAAE,CAAC;QAChC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC,IAAI,CACnB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAC5E,CAAC;IACJ,CAAC;CACF;AA1JD,kDA0JC;AAED,SAAgB,cAAc,CAAC,OAAgB;IAC7C,OAAO,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { AWEvent } from './aw';
2
+ export interface BaselineComparison {
3
+ today: {
4
+ totalMinutes: number;
5
+ topApps: {
6
+ app: string;
7
+ minutes: number;
8
+ }[];
9
+ switchCount: number;
10
+ insightCount: number;
11
+ };
12
+ average: {
13
+ totalMinutes: number;
14
+ days: number;
15
+ topApps: {
16
+ app: string;
17
+ minutes: number;
18
+ }[];
19
+ switchCount: number;
20
+ insightCount: number;
21
+ };
22
+ anomalies: BaselineAnomaly[];
23
+ }
24
+ export interface BaselineAnomaly {
25
+ type: 'time_drop' | 'time_spike' | 'app_change' | 'switch_spike' | 'new_app' | 'missing_app';
26
+ description: string;
27
+ detail: string;
28
+ severity: 'low' | 'medium' | 'high';
29
+ }
30
+ export declare function generateBaseline(todayEvents: AWEvent[], insightEngine: any, days?: number): BaselineComparison;
31
+ //# sourceMappingURL=baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC5C,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,EAAE;QACP,YAAY,EAAE,MAAM,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC5C,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,SAAS,EAAE,eAAe,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,YAAY,GAAG,cAAc,GAAG,SAAS,GAAG,aAAa,CAAC;IAC7F,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACrC;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,OAAO,EAAE,EACtB,aAAa,EAAE,GAAG,EAClB,IAAI,GAAE,MAAU,GACf,kBAAkB,CA4IpB"}
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateBaseline = generateBaseline;
4
+ const db_1 = require("./db");
5
+ function generateBaseline(todayEvents, insightEngine, days = 7) {
6
+ const todayResult = insightEngine.analyzeWindowEvents(todayEvents);
7
+ const summaries = (0, db_1.getRecentDailySummaries)(days);
8
+ const todayTotalMinutes = Math.round(todayResult.totalActiveTime / 60);
9
+ const todayApps = todayResult.appSummaries.slice(0, 10).map((a) => ({
10
+ app: a.app,
11
+ minutes: Math.round(a.totalDuration / 60),
12
+ }));
13
+ const todaySwitches = todayResult.contextSwitches.reduce((s, c) => s + c.count, 0);
14
+ const historicalSummaries = summaries.filter((s) => s.total_active_time > 0);
15
+ if (historicalSummaries.length === 0) {
16
+ return {
17
+ today: {
18
+ totalMinutes: todayTotalMinutes,
19
+ topApps: todayApps,
20
+ switchCount: todaySwitches,
21
+ insightCount: 0,
22
+ },
23
+ average: { totalMinutes: 0, days: 0, topApps: [], switchCount: 0, insightCount: 0 },
24
+ anomalies: [],
25
+ };
26
+ }
27
+ const avgMinutes = Math.round(historicalSummaries.reduce((s, d) => s + d.total_active_time, 0) /
28
+ 60 /
29
+ historicalSummaries.length);
30
+ const avgSwitches = Math.round(historicalSummaries.reduce((s, d) => s + d.switch_count, 0) /
31
+ historicalSummaries.length);
32
+ // Aggregate app usage across historical days
33
+ const historicalApps = new Map();
34
+ for (const summary of historicalSummaries) {
35
+ const apps = JSON.parse(summary.top_apps || '[]');
36
+ for (const app of apps) {
37
+ const existing = historicalApps.get(app.app) || { totalMinutes: 0, days: 0 };
38
+ existing.totalMinutes += app.minutes;
39
+ existing.days += 1;
40
+ historicalApps.set(app.app, existing);
41
+ }
42
+ }
43
+ const avgTopApps = Array.from(historicalApps.entries())
44
+ .map(([app, data]) => ({
45
+ app,
46
+ minutes: Math.round(data.totalMinutes / historicalSummaries.length),
47
+ }))
48
+ .sort((a, b) => b.minutes - a.minutes)
49
+ .slice(0, 10);
50
+ const anomalies = [];
51
+ // Total time anomaly
52
+ const timeRatio = avgMinutes > 0 ? todayTotalMinutes / avgMinutes : 1;
53
+ if (timeRatio < 0.5) {
54
+ anomalies.push({
55
+ type: 'time_drop',
56
+ description: `Significantly less active than usual`,
57
+ detail: `${todayTotalMinutes} min today vs ${avgMinutes} min average over ${historicalSummaries.length} days.`,
58
+ severity: todayTotalMinutes < avgMinutes * 0.25 ? 'high' : 'medium',
59
+ });
60
+ }
61
+ else if (timeRatio > 1.5) {
62
+ anomalies.push({
63
+ type: 'time_spike',
64
+ description: `Unusually high activity today`,
65
+ detail: `${todayTotalMinutes} min today vs ${avgMinutes} min average.`,
66
+ severity: 'low',
67
+ });
68
+ }
69
+ // Switch anomaly
70
+ if (avgSwitches > 0 && todaySwitches > avgSwitches * 1.5) {
71
+ anomalies.push({
72
+ type: 'switch_spike',
73
+ description: `Context switching is ${Math.round((todaySwitches / avgSwitches - 1) * 100)}% above your average`,
74
+ detail: `${todaySwitches} switches today vs ${avgSwitches} avg. Consider time-blocking.`,
75
+ severity: todaySwitches > avgSwitches * 2 ? 'high' : 'medium',
76
+ });
77
+ }
78
+ // App anomalies
79
+ for (const todayApp of todayApps) {
80
+ const avgApp = avgTopApps.find(a => a.app === todayApp.app);
81
+ if (!avgApp && todayApp.minutes > 15) {
82
+ anomalies.push({
83
+ type: 'new_app',
84
+ description: `Spent ${todayApp.minutes} min in ${todayApp.app} — not in your usual rotation`,
85
+ detail: `New app detected in today's workflow.`,
86
+ severity: 'low',
87
+ });
88
+ }
89
+ else if (avgApp) {
90
+ const ratio = todayApp.minutes / (avgApp.minutes || 1);
91
+ if (ratio > 2) {
92
+ anomalies.push({
93
+ type: 'app_change',
94
+ description: `${Math.round((ratio - 1) * 100)}% more time in ${todayApp.app} than usual`,
95
+ detail: `${todayApp.minutes} min today vs ${avgApp.minutes} min avg.`,
96
+ severity: ratio > 3 ? 'medium' : 'low',
97
+ });
98
+ }
99
+ else if (ratio < 0.3 && avgApp.minutes > 10) {
100
+ anomalies.push({
101
+ type: 'missing_app',
102
+ description: `Barely touched ${todayApp.app} today (${todayApp.minutes} min vs ${avgApp.minutes} min avg)`,
103
+ detail: `Usually spend ${avgApp.minutes} min/day here.`,
104
+ severity: 'medium',
105
+ });
106
+ }
107
+ }
108
+ }
109
+ return {
110
+ today: {
111
+ totalMinutes: todayTotalMinutes,
112
+ topApps: todayApps,
113
+ switchCount: todaySwitches,
114
+ insightCount: 0,
115
+ },
116
+ average: {
117
+ totalMinutes: avgMinutes,
118
+ days: historicalSummaries.length,
119
+ topApps: avgTopApps,
120
+ switchCount: avgSwitches,
121
+ insightCount: Math.round(historicalSummaries.reduce((s, d) => s + d.insight_count, 0) /
122
+ historicalSummaries.length),
123
+ },
124
+ anomalies: anomalies.sort((a, b) => {
125
+ const sev = { high: 3, medium: 2, low: 1 };
126
+ return (sev[b.severity] || 0) - (sev[a.severity] || 0);
127
+ }),
128
+ };
129
+ }
130
+ //# sourceMappingURL=baseline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.js","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface OpenContextConfig {
2
+ activitywatch: {
3
+ enabled: boolean;
4
+ baseUrl: string;
5
+ pollIntervalMinutes: number;
6
+ };
7
+ screenpipe: {
8
+ enabled: boolean;
9
+ baseUrl: string;
10
+ };
11
+ transports: {
12
+ slack: {
13
+ webhookUrl: string;
14
+ };
15
+ telegram: {
16
+ botToken: string;
17
+ chatId: string;
18
+ };
19
+ webhook: {
20
+ url: string;
21
+ headers: Record<string, string>;
22
+ };
23
+ };
24
+ insights: {
25
+ scheduleIntervalMinutes: number;
26
+ minConfidence: number;
27
+ maxInsightsPerRun: number;
28
+ };
29
+ dataDir: string;
30
+ }
31
+ export declare function loadConfig(): OpenContextConfig;
32
+ export declare function saveConfig(config: OpenContextConfig): void;
33
+ export declare function getConfig(): OpenContextConfig;
34
+ export declare function getDataDir(): string;
35
+ export declare function getConfigPath(): string;
36
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE;QACb,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE;QACV,KAAK,EAAE;YACL,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,QAAQ,EAAE;YACR,QAAQ,EAAE,MAAM,CAAC;YACjB,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;QACF,OAAO,EAAE;YACP,GAAG,EAAE,MAAM,CAAC;YACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACjC,CAAC;KACH,CAAC;IACF,QAAQ,EAAE;QACR,uBAAuB,EAAE,MAAM,CAAC;QAChC,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAmCD,wBAAgB,UAAU,IAAI,iBAAiB,CAwB9C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAK1D;AAED,wBAAgB,SAAS,IAAI,iBAAiB,CAG7C;AAED,wBAAgB,UAAU,IAAI,MAAM,CAYnC;AA2BD,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
package/dist/config.js ADDED
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadConfig = loadConfig;
37
+ exports.saveConfig = saveConfig;
38
+ exports.getConfig = getConfig;
39
+ exports.getDataDir = getDataDir;
40
+ exports.getConfigPath = getConfigPath;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const DEFAULT_CONFIG = {
45
+ activitywatch: {
46
+ enabled: true,
47
+ baseUrl: 'http://localhost:5600',
48
+ pollIntervalMinutes: 15,
49
+ },
50
+ screenpipe: {
51
+ enabled: false,
52
+ baseUrl: 'http://localhost:3030',
53
+ },
54
+ transports: {
55
+ slack: { webhookUrl: '' },
56
+ telegram: { botToken: '', chatId: '' },
57
+ webhook: { url: '', headers: {} },
58
+ },
59
+ insights: {
60
+ scheduleIntervalMinutes: 60,
61
+ minConfidence: 0.4,
62
+ maxInsightsPerRun: 10,
63
+ },
64
+ dataDir: path.join(os.homedir(), '.daybrain', 'data'),
65
+ };
66
+ let _config = null;
67
+ function configDir() {
68
+ return path.join(os.homedir(), '.daybrain');
69
+ }
70
+ function configPath() {
71
+ return path.join(configDir(), 'config.json');
72
+ }
73
+ function loadConfig() {
74
+ if (_config)
75
+ return _config;
76
+ const cfgPath = configPath();
77
+ if (!fs.existsSync(cfgPath)) {
78
+ fs.mkdirSync(configDir(), { recursive: true });
79
+ fs.writeFileSync(cfgPath, JSON.stringify(DEFAULT_CONFIG, null, 2), { mode: 0o600 });
80
+ fs.chmodSync(configDir(), 0o700);
81
+ fs.chmodSync(cfgPath, 0o600);
82
+ _config = structuredClone(DEFAULT_CONFIG);
83
+ return _config;
84
+ }
85
+ fs.chmodSync(cfgPath, 0o600);
86
+ try {
87
+ const raw = fs.readFileSync(cfgPath, 'utf-8');
88
+ const userConfig = JSON.parse(raw);
89
+ _config = deepMergeConfig(DEFAULT_CONFIG, userConfig);
90
+ }
91
+ catch {
92
+ _config = structuredClone(DEFAULT_CONFIG);
93
+ }
94
+ return _config;
95
+ }
96
+ function saveConfig(config) {
97
+ const cfgPath = configPath();
98
+ fs.mkdirSync(configDir(), { recursive: true });
99
+ fs.writeFileSync(cfgPath, JSON.stringify(config, null, 2));
100
+ _config = config;
101
+ }
102
+ function getConfig() {
103
+ if (!_config)
104
+ return loadConfig();
105
+ return structuredClone(_config);
106
+ }
107
+ function getDataDir() {
108
+ const cfg = getConfig();
109
+ let dir = cfg.dataDir.replace(/^~/, os.homedir());
110
+ dir = path.resolve(dir);
111
+ const home = os.homedir();
112
+ if (!dir.startsWith(home + path.sep) && dir !== home) {
113
+ throw new Error(`dataDir must be within home directory (${home}), got: ${dir}`);
114
+ }
115
+ fs.mkdirSync(dir, { recursive: true });
116
+ return dir;
117
+ }
118
+ function deepMergeConfig(base, override) {
119
+ const result = structuredClone(base);
120
+ for (const [key, val] of Object.entries(override)) {
121
+ if (val !== null && typeof val === 'object' && !Array.isArray(val)) {
122
+ const baseVal = result[key];
123
+ if (baseVal !== null && typeof baseVal === 'object' && !Array.isArray(baseVal)) {
124
+ result[key] = deepMergeConfig(baseVal, val);
125
+ }
126
+ else {
127
+ result[key] = val;
128
+ }
129
+ }
130
+ else if (val !== undefined) {
131
+ result[key] = val;
132
+ }
133
+ }
134
+ return result;
135
+ }
136
+ function getConfigPath() {
137
+ return configPath();
138
+ }
139
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/db.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ import Database from 'better-sqlite3';
2
+ export interface RawEvent {
3
+ source: 'activitywatch' | 'screenpipe' | 'native';
4
+ bucket_id: string;
5
+ timestamp: string;
6
+ duration: number;
7
+ app: string;
8
+ title: string;
9
+ url: string;
10
+ raw_data: string;
11
+ }
12
+ export interface StoredRawEvent extends RawEvent {
13
+ id: number;
14
+ created_at: string;
15
+ }
16
+ export interface Insight {
17
+ type: 'commitment' | 'avoidance' | 'pattern' | 'summary' | 'context_switch' | 'focus' | 'deadline';
18
+ period_start: string;
19
+ period_end: string;
20
+ title: string;
21
+ description: string;
22
+ confidence: number;
23
+ evidence: string;
24
+ action_text: string;
25
+ status?: string;
26
+ }
27
+ export interface StoredInsight extends Insight {
28
+ id: number;
29
+ status: string;
30
+ created_at: string;
31
+ pushed_to: string | null;
32
+ pushed_at: string | null;
33
+ }
34
+ export interface DailySummary {
35
+ date: string;
36
+ total_active_time: number;
37
+ top_apps: string;
38
+ switch_count: number;
39
+ insight_count: number;
40
+ raw_summary: string;
41
+ }
42
+ export interface StoredDailySummary extends DailySummary {
43
+ id: number;
44
+ created_at: string;
45
+ }
46
+ export declare function getDb(): Database.Database;
47
+ export declare function insertRawEvents(events: RawEvent[]): number;
48
+ export declare function getRawEvents(options: {
49
+ periodStart?: string;
50
+ periodEnd?: string;
51
+ source?: string;
52
+ app?: string;
53
+ limit?: number;
54
+ offset?: number;
55
+ }): StoredRawEvent[];
56
+ export declare function insertInsight(insight: Insight): StoredInsight | null;
57
+ export declare function insertInsights(insights: Insight[]): number;
58
+ export declare function getInsights(options: {
59
+ type?: string;
60
+ periodStart?: string;
61
+ periodEnd?: string;
62
+ minConfidence?: number;
63
+ limit?: number;
64
+ includePushed?: boolean;
65
+ }): StoredInsight[];
66
+ export declare function updateInsightStatus(id: number, status: string): void;
67
+ export declare function markInsightPushed(id: number, target: string): void;
68
+ export declare function upsertDailySummary(summary: DailySummary): void;
69
+ export declare function getDailySummary(date: string): StoredDailySummary | undefined;
70
+ export declare function getRecentDailySummaries(days: number): StoredDailySummary[];
71
+ export declare function closeDb(): void;
72
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}