@teeras/afterhours 0.3.1 → 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 +15 -0
- package/dist/apprun.d.ts +8 -0
- package/dist/apprun.d.ts.map +1 -0
- package/dist/apprun.js +67 -0
- package/dist/apprun.js.map +1 -0
- package/dist/cli.js +42 -3
- package/dist/cli.js.map +1 -1
- package/dist/cloud.d.ts +47 -0
- package/dist/cloud.d.ts.map +1 -1
- package/dist/cloud.js +165 -0
- package/dist/cloud.js.map +1 -1
- package/dist/collect.d.ts.map +1 -1
- package/dist/collect.js +4 -1
- package/dist/collect.js.map +1 -1
- package/dist/detect.js +2 -2
- package/dist/detect.js.map +1 -1
- package/dist/hooks.d.ts +13 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +41 -21
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/macos/spool.d.ts +19 -0
- package/dist/macos/spool.d.ts.map +1 -0
- package/dist/macos/spool.js +117 -0
- package/dist/macos/spool.js.map +1 -0
- package/dist/macos/status.d.ts +32 -0
- package/dist/macos/status.d.ts.map +1 -0
- package/dist/macos/status.js +55 -0
- package/dist/macos/status.js.map +1 -0
- package/dist/privacy.d.ts.map +1 -1
- package/dist/privacy.js +2 -0
- package/dist/privacy.js.map +1 -1
- package/dist/runEventTypes.d.ts +2 -0
- package/dist/runEventTypes.d.ts.map +1 -0
- package/dist/runEventTypes.js +2 -0
- package/dist/runEventTypes.js.map +1 -0
- package/dist/runEvents.d.ts +59 -0
- package/dist/runEvents.d.ts.map +1 -0
- package/dist/runEvents.js +148 -0
- package/dist/runEvents.js.map +1 -0
- package/dist/sources/claude.js +2 -2
- package/dist/sources/claude.js.map +1 -1
- package/dist/sources/macosApps.d.ts +7 -0
- package/dist/sources/macosApps.d.ts.map +1 -0
- package/dist/sources/macosApps.js +122 -0
- package/dist/sources/macosApps.js.map +1 -0
- package/dist/types.d.ts +5 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/llms-install.md +8 -0
- package/package.json +1 -1
package/dist/hooks.d.ts
CHANGED
|
@@ -9,6 +9,19 @@ export interface ContentFreeHookEvent {
|
|
|
9
9
|
}
|
|
10
10
|
export type HookSourceId = "claude-code" | "codex";
|
|
11
11
|
export declare function hookJournalPath(home?: string): string;
|
|
12
|
+
export interface ParsedHookEvent {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
eventName: string;
|
|
15
|
+
model: string | null;
|
|
16
|
+
notificationType: string | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Reduce a raw agent hook payload to the four content-free fields the
|
|
20
|
+
* collector needs. Prompt, cwd, transcript path, messages, tool inputs, and
|
|
21
|
+
* model output are never read. Returns null when the payload is oversized,
|
|
22
|
+
* unparseable, or missing a usable session id / event name.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseHookInput(raw: string): ParsedHookEvent | null;
|
|
12
25
|
export declare function ingestClaudeHook(raw: string, episodeSecret: string, home?: string, now?: number): ContentFreeHookEvent | null;
|
|
13
26
|
export declare function ingestCodexHook(raw: string, episodeSecret: string, home?: string, now?: number): ContentFreeHookEvent | null;
|
|
14
27
|
export declare function readContentFreeHookEvents(home?: string, sinceMs?: number, untilMs?: number): ContentFreeHookEvent[];
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAClB,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,cAAc,GACd,sBAAsB,GACtB,cAAc,GACd,eAAe,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,CAAC,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC;AAMnD,wBAAgB,eAAe,CAAC,IAAI,SAAY,GAAG,MAAM,CAExD;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAClB,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,cAAc,GACd,sBAAsB,GACtB,cAAc,GACd,eAAe,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,CAAC,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC;AAMnD,wBAAgB,eAAe,CAAC,IAAI,SAAY,GAAG,MAAM,CAExD;AA+BD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAsBlE;AAkDD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,IAAI,SAAY,EAChB,GAAG,SAAa,GACf,oBAAoB,GAAG,IAAI,CAE7B;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,IAAI,SAAY,EAChB,GAAG,SAAa,GACf,oBAAoB,GAAG,IAAI,CAE7B;AAED,wBAAgB,yBAAyB,CACvC,IAAI,SAAY,EAChB,OAAO,SAAI,EACX,OAAO,SAAa,GACnB,oBAAoB,EAAE,CAmCxB;AAMD,wBAAgB,kBAAkB,CAAC,OAAO,SAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBhF;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,oDAAoD,CAAC;AAEzF,wBAAgB,iBAAiB,CAAC,OAAO,SAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAcrF;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAC/B,IAAI,SAAY,EAChB,GAAG,SAAa,EAChB,QAAQ,CAAC,EAAE,YAAY,GACtB,iBAAiB,CAenB"}
|
package/dist/hooks.js
CHANGED
|
@@ -13,8 +13,8 @@ function record(value) {
|
|
|
13
13
|
? value
|
|
14
14
|
: null;
|
|
15
15
|
}
|
|
16
|
-
function signal(
|
|
17
|
-
switch (
|
|
16
|
+
function signal(eventName, notificationType) {
|
|
17
|
+
switch (eventName) {
|
|
18
18
|
case "SessionStart":
|
|
19
19
|
return "session_started";
|
|
20
20
|
case "UserPromptSubmit":
|
|
@@ -28,15 +28,46 @@ function signal(input) {
|
|
|
28
28
|
case "SessionEnd":
|
|
29
29
|
return "session_ended";
|
|
30
30
|
case "Notification":
|
|
31
|
-
if (
|
|
31
|
+
if (notificationType === "permission_prompt")
|
|
32
32
|
return "permission_requested";
|
|
33
|
-
if (
|
|
33
|
+
if (notificationType === "idle_prompt")
|
|
34
34
|
return "human_needed";
|
|
35
35
|
return null;
|
|
36
36
|
default:
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Reduce a raw agent hook payload to the four content-free fields the
|
|
42
|
+
* collector needs. Prompt, cwd, transcript path, messages, tool inputs, and
|
|
43
|
+
* model output are never read. Returns null when the payload is oversized,
|
|
44
|
+
* unparseable, or missing a usable session id / event name.
|
|
45
|
+
*/
|
|
46
|
+
export function parseHookInput(raw) {
|
|
47
|
+
if (Buffer.byteLength(raw, "utf8") > MAX_HOOK_INPUT_BYTES)
|
|
48
|
+
return null;
|
|
49
|
+
let input;
|
|
50
|
+
try {
|
|
51
|
+
input = record(JSON.parse(raw));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const sessionId = typeof input?.session_id === "string" && input.session_id.length <= 200
|
|
57
|
+
? input.session_id
|
|
58
|
+
: null;
|
|
59
|
+
const eventName = typeof input?.hook_event_name === "string" ? input.hook_event_name : null;
|
|
60
|
+
if (!sessionId || !eventName)
|
|
61
|
+
return null;
|
|
62
|
+
return {
|
|
63
|
+
sessionId,
|
|
64
|
+
eventName,
|
|
65
|
+
model: typeof input?.model === "string" && /^[a-z0-9._-]{1,80}$/i.test(input.model)
|
|
66
|
+
? input.model
|
|
67
|
+
: null,
|
|
68
|
+
notificationType: typeof input?.notification_type === "string" ? input.notification_type : null,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
40
71
|
function compactJournal(path, now) {
|
|
41
72
|
try {
|
|
42
73
|
if (statSync(path).size <= MAX_JOURNAL_BYTES)
|
|
@@ -58,30 +89,19 @@ function compactJournal(path, now) {
|
|
|
58
89
|
* token), so journal events keep joining log-derived episodes across logins.
|
|
59
90
|
*/
|
|
60
91
|
function ingestAgentHook(raw, sourceId, episodeSecret, home = homedir(), now = Date.now()) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
let input;
|
|
64
|
-
try {
|
|
65
|
-
input = record(JSON.parse(raw));
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
92
|
+
const parsed = parseHookInput(raw);
|
|
93
|
+
if (!parsed)
|
|
68
94
|
return null;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
? input.session_id
|
|
72
|
-
: null;
|
|
73
|
-
const nextSignal = input ? signal(input) : null;
|
|
74
|
-
if (!sessionId || !nextSignal)
|
|
95
|
+
const nextSignal = signal(parsed.eventName, parsed.notificationType);
|
|
96
|
+
if (!nextSignal)
|
|
75
97
|
return null;
|
|
76
98
|
const event = {
|
|
77
99
|
schemaVersion: 1,
|
|
78
100
|
at: now,
|
|
79
101
|
sourceId,
|
|
80
|
-
episodeId: opaqueEpisodeId(episodeSecret, sourceId, sessionId),
|
|
102
|
+
episodeId: opaqueEpisodeId(episodeSecret, sourceId, parsed.sessionId),
|
|
81
103
|
signal: nextSignal,
|
|
82
|
-
modelFamily:
|
|
83
|
-
? input.model
|
|
84
|
-
: null,
|
|
104
|
+
modelFamily: parsed.model,
|
|
85
105
|
};
|
|
86
106
|
const path = hookJournalPath(home);
|
|
87
107
|
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,SAAS,EACT,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAsB3D,MAAM,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC;AACvC,MAAM,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAAC;AACtC,MAAM,oBAAoB,GAAG,EAAE,GAAG,UAAU,CAAC;AAE7C,MAAM,UAAU,eAAe,CAAC,IAAI,GAAG,OAAO,EAAE;IAC9C,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAC,KAAgC;QAClC,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export { collectAfterhours, SOURCES, type CollectOptions } from "./collect.js";
|
|
2
|
-
export { ConnectionExpiredError, credentialsPath, openVerificationUri, pollDeviceLogin, readCredentials, removeCredentials, startDeviceLogin, syncSnapshot, revokeDevice, teerasBaseUrl, writeCredentials, type CloudCredentials, type DeviceGrant, } from "./cloud.js";
|
|
2
|
+
export { ConnectionExpiredError, connectMachine, credentialsPath, openVerificationUri, pollDeviceLogin, postRunEnded, postRunStarted, readCredentials, removeCredentials, REPORT_FALLBACK_URL, REPORT_TIMEOUT_MS, reportMachine, reportUrl, RUN_EVENT_TIMEOUT_MS, startDeviceLogin, syncSnapshot, revokeDevice, teerasBaseUrl, writeCredentials, type CloudCredentials, type DeviceGrant, } from "./cloud.js";
|
|
3
|
+
export type { RunEnded, RunStarted } from "./runEventTypes.js";
|
|
3
4
|
export { DATA_BOUNDARY } from "./privacy.js";
|
|
4
|
-
export { claudeHookSettings, codexHookSettings, hookJournalPath, hookJournalReport, ingestClaudeHook, ingestCodexHook, readContentFreeHookEvents, type ContentFreeHookEvent, type HookJournalReport, type HookSignal, type HookSourceId, } from "./hooks.js";
|
|
5
|
+
export { claudeHookSettings, codexHookSettings, hookJournalPath, hookJournalReport, ingestClaudeHook, ingestCodexHook, parseHookInput, readContentFreeHookEvents, type ContentFreeHookEvent, type HookJournalReport, type HookSignal, type HookSourceId, type ParsedHookEvent, } from "./hooks.js";
|
|
5
6
|
export { ensureEpisodeSecret, episodeSecretPath } from "./secret.js";
|
|
6
7
|
export { detectCodingAgents } from "./detect.js";
|
|
7
8
|
export { reportFrom } from "./report.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,iBAAiB,GACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,cAAc,EACd,aAAa,EACb,KAAK,SAAS,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,aAAa,EACb,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { collectAfterhours, SOURCES } from "./collect.js";
|
|
2
|
-
export { ConnectionExpiredError, credentialsPath, openVerificationUri, pollDeviceLogin, readCredentials, removeCredentials, startDeviceLogin, syncSnapshot, revokeDevice, teerasBaseUrl, writeCredentials, } from "./cloud.js";
|
|
2
|
+
export { ConnectionExpiredError, connectMachine, credentialsPath, openVerificationUri, pollDeviceLogin, postRunEnded, postRunStarted, readCredentials, removeCredentials, REPORT_FALLBACK_URL, REPORT_TIMEOUT_MS, reportMachine, reportUrl, RUN_EVENT_TIMEOUT_MS, startDeviceLogin, syncSnapshot, revokeDevice, teerasBaseUrl, writeCredentials, } from "./cloud.js";
|
|
3
3
|
export { DATA_BOUNDARY } from "./privacy.js";
|
|
4
|
-
export { claudeHookSettings, codexHookSettings, hookJournalPath, hookJournalReport, ingestClaudeHook, ingestCodexHook, readContentFreeHookEvents, } from "./hooks.js";
|
|
4
|
+
export { claudeHookSettings, codexHookSettings, hookJournalPath, hookJournalReport, ingestClaudeHook, ingestCodexHook, parseHookInput, readContentFreeHookEvents, } from "./hooks.js";
|
|
5
5
|
export { ensureEpisodeSecret, episodeSecretPath } from "./secret.js";
|
|
6
6
|
export { detectCodingAgents } from "./detect.js";
|
|
7
7
|
export { reportFrom } from "./report.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,GAGjB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,GAGjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,yBAAyB,GAM1B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,GAGb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAqD,MAAM,UAAU,CAAC;AACrF,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,cAAc,EACd,aAAa,GAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAqB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** v1 spool contract with Teeras.app — any change bumps `v`. */
|
|
2
|
+
export interface SpoolRecord {
|
|
3
|
+
v: 1;
|
|
4
|
+
kind: "app_session";
|
|
5
|
+
app_id: string;
|
|
6
|
+
started_at: string;
|
|
7
|
+
ended_at: string;
|
|
8
|
+
local_date: string;
|
|
9
|
+
fg_seconds_by_hour: Record<string, number>;
|
|
10
|
+
}
|
|
11
|
+
export interface SpoolReadResult {
|
|
12
|
+
records: SpoolRecord[];
|
|
13
|
+
quarantinedLines: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function spoolDir(home: string): string;
|
|
16
|
+
export declare function readSpool(dir: string): SpoolReadResult;
|
|
17
|
+
/** Rewrite spool files dropping records fully synced (ended_at <= upToIso). */
|
|
18
|
+
export declare function compactSpool(dir: string, upToIso: string): number;
|
|
19
|
+
//# sourceMappingURL=spool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spool.d.ts","sourceRoot":"","sources":["../../src/macos/spool.ts"],"names":[],"mappings":"AAIA,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,CAAC,CAAC;IACL,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AA4BD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAsCtD;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA2BjE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { appendFileSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { isDirectory } from "../files.js";
|
|
4
|
+
export function spoolDir(home) {
|
|
5
|
+
return join(home, "Library", "Application Support", "Teeras", "spool");
|
|
6
|
+
}
|
|
7
|
+
function asSpoolRecord(value) {
|
|
8
|
+
if (typeof value !== "object" || value === null)
|
|
9
|
+
return null;
|
|
10
|
+
const row = value;
|
|
11
|
+
if (row.v !== 1 || row.kind !== "app_session")
|
|
12
|
+
return null;
|
|
13
|
+
if (typeof row.app_id !== "string" || row.app_id.length === 0)
|
|
14
|
+
return null;
|
|
15
|
+
for (const key of ["started_at", "ended_at"]) {
|
|
16
|
+
if (typeof row[key] !== "string" || Number.isNaN(Date.parse(row[key])))
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
// local_date drives bucket-key math downstream (toBuckets, compactSpool's
|
|
20
|
+
// watermark comparisons don't use it, but macosApps.ts's toBuckets does) —
|
|
21
|
+
// a non-YYYY-MM-DD value is a poison pill there, so quarantine it here.
|
|
22
|
+
if (typeof row.local_date !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(row.local_date))
|
|
23
|
+
return null;
|
|
24
|
+
const hours = row.fg_seconds_by_hour;
|
|
25
|
+
if (typeof hours !== "object" || hours === null)
|
|
26
|
+
return null;
|
|
27
|
+
for (const [hour, seconds] of Object.entries(hours)) {
|
|
28
|
+
const h = Number(hour);
|
|
29
|
+
if (!Number.isInteger(h) || h < 0 || h > 23)
|
|
30
|
+
return null;
|
|
31
|
+
if (typeof seconds !== "number" || seconds < 0 || seconds > 3600)
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return row;
|
|
35
|
+
}
|
|
36
|
+
function spoolFiles(dir) {
|
|
37
|
+
return readdirSync(dir).filter((name) => name.endsWith(".jsonl")).sort().map((name) => join(dir, name));
|
|
38
|
+
}
|
|
39
|
+
export function readSpool(dir) {
|
|
40
|
+
if (!isDirectory(dir))
|
|
41
|
+
return { records: [], quarantinedLines: 0 };
|
|
42
|
+
const records = [];
|
|
43
|
+
let quarantinedLines = 0;
|
|
44
|
+
for (const file of spoolFiles(dir)) {
|
|
45
|
+
const kept = [];
|
|
46
|
+
const bad = [];
|
|
47
|
+
// Line-by-line parsing with error signal required for quarantine:
|
|
48
|
+
// parseLines silently skips unparseable lines and loses the raw text,
|
|
49
|
+
// preventing the move-not-copy semantics (idempotent rewrite) needed here.
|
|
50
|
+
for (const line of readFileSync(file, "utf8").split("\n")) {
|
|
51
|
+
if (!line.trim())
|
|
52
|
+
continue;
|
|
53
|
+
let parsed = null;
|
|
54
|
+
try {
|
|
55
|
+
parsed = asSpoolRecord(JSON.parse(line));
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
parsed = null;
|
|
59
|
+
}
|
|
60
|
+
if (parsed) {
|
|
61
|
+
records.push(parsed);
|
|
62
|
+
kept.push(line);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
bad.push(line);
|
|
66
|
+
quarantinedLines += 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Only touch the file when there's actually something to quarantine — an
|
|
70
|
+
// unconditional rewrite is a truncate window that can clobber a concurrent
|
|
71
|
+
// Swift O_APPEND append to a file that had nothing wrong with it.
|
|
72
|
+
if (bad.length > 0) {
|
|
73
|
+
// Append bad lines to the quarantine file BEFORE rewriting the source: if
|
|
74
|
+
// the process dies between the two writes, the bad lines exist in both
|
|
75
|
+
// places (safe, re-quarantinable) rather than in neither (lost).
|
|
76
|
+
appendFileSync(`${file}.bad`, `${bad.join("\n")}\n`);
|
|
77
|
+
writeFileSync(file, kept.length > 0 ? `${kept.join("\n")}\n` : "");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { records, quarantinedLines };
|
|
81
|
+
}
|
|
82
|
+
/** Rewrite spool files dropping records fully synced (ended_at <= upToIso). */
|
|
83
|
+
export function compactSpool(dir, upToIso) {
|
|
84
|
+
if (!isDirectory(dir))
|
|
85
|
+
return 0;
|
|
86
|
+
const watermark = Date.parse(upToIso);
|
|
87
|
+
let dropped = 0;
|
|
88
|
+
for (const file of spoolFiles(dir)) {
|
|
89
|
+
const kept = [];
|
|
90
|
+
let droppedInFile = 0;
|
|
91
|
+
for (const line of readFileSync(file, "utf8").split("\n")) {
|
|
92
|
+
if (!line.trim())
|
|
93
|
+
continue;
|
|
94
|
+
let keep = true;
|
|
95
|
+
try {
|
|
96
|
+
const parsed = asSpoolRecord(JSON.parse(line));
|
|
97
|
+
if (parsed && Date.parse(parsed.ended_at) <= watermark)
|
|
98
|
+
keep = false;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Unparseable lines are readSpool's quarantine problem, not compaction's.
|
|
102
|
+
}
|
|
103
|
+
if (keep)
|
|
104
|
+
kept.push(line);
|
|
105
|
+
else
|
|
106
|
+
droppedInFile += 1;
|
|
107
|
+
}
|
|
108
|
+
// Same truncate-window guard as readSpool: nothing dropped means nothing
|
|
109
|
+
// to rewrite, so leave the file (and a concurrent appender) alone.
|
|
110
|
+
if (droppedInFile > 0) {
|
|
111
|
+
writeFileSync(file, kept.length > 0 ? `${kept.join("\n")}\n` : "");
|
|
112
|
+
}
|
|
113
|
+
dropped += droppedInFile;
|
|
114
|
+
}
|
|
115
|
+
return dropped;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=spool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spool.js","sourceRoot":"","sources":["../../src/macos/spool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AfterhoursSnapshot } from "../types.js";
|
|
2
|
+
export type SyncState = "ok" | "offline" | "signed_out" | "error";
|
|
3
|
+
export interface AppStatusLine {
|
|
4
|
+
lastActivityAt: string | null;
|
|
5
|
+
resolution: "minute" | "hour";
|
|
6
|
+
eveningsKept7d: number;
|
|
7
|
+
}
|
|
8
|
+
export interface AppStatusSource {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
configured: boolean;
|
|
12
|
+
fidelity: string;
|
|
13
|
+
sessions: number;
|
|
14
|
+
}
|
|
15
|
+
export interface AppStatus {
|
|
16
|
+
v: 1;
|
|
17
|
+
generatedAt: string;
|
|
18
|
+
sources: AppStatusSource[];
|
|
19
|
+
sync: {
|
|
20
|
+
state: SyncState;
|
|
21
|
+
lastAckAt: string | null;
|
|
22
|
+
pendingSessions: number;
|
|
23
|
+
};
|
|
24
|
+
line: AppStatusLine;
|
|
25
|
+
spool: {
|
|
26
|
+
quarantinedLines: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export declare function statusPath(home: string): string;
|
|
30
|
+
export declare function buildStatus(snapshot: AfterhoursSnapshot, sync: AppStatus["sync"], spool: AppStatus["spool"]): AppStatus;
|
|
31
|
+
export declare function writeStatus(home: string, status: AppStatus): void;
|
|
32
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/macos/status.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,CAAC;AAElE,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,EAAE,CAAC,CAAC;IACL,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,IAAI,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9E,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EACvB,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,GACxB,SAAS,CAwCX;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAMjE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { localDateOf } from "../activity.js";
|
|
4
|
+
export function statusPath(home) {
|
|
5
|
+
return join(home, "Library", "Application Support", "Teeras", "status.json");
|
|
6
|
+
}
|
|
7
|
+
export function buildStatus(snapshot, sync, spool) {
|
|
8
|
+
let lastActivityAt = null;
|
|
9
|
+
let resolution = "hour";
|
|
10
|
+
const eveningDatesWithActivity = new Set();
|
|
11
|
+
for (const source of snapshot.sources) {
|
|
12
|
+
for (const episode of source.episodes) {
|
|
13
|
+
if (lastActivityAt === null || episode.endedAt > lastActivityAt) {
|
|
14
|
+
lastActivityAt = episode.endedAt;
|
|
15
|
+
resolution = "minute";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
for (const bucket of source.buckets) {
|
|
19
|
+
const active = bucket.agentTurns + bucket.humanCheckIns + bucket.agentActiveMinutes + bucket.humanAttentionMinutes > 0;
|
|
20
|
+
if (!active)
|
|
21
|
+
continue;
|
|
22
|
+
if (lastActivityAt === null || bucket.hour > lastActivityAt) {
|
|
23
|
+
lastActivityAt = bucket.hour;
|
|
24
|
+
resolution = "hour";
|
|
25
|
+
}
|
|
26
|
+
if (bucket.localHour >= 21)
|
|
27
|
+
eveningDatesWithActivity.add(bucket.localDate);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Last 7 full local dates before the snapshot's `until` date.
|
|
31
|
+
const untilDate = localDateOf(Date.parse(snapshot.until));
|
|
32
|
+
let eveningsKept7d = 0;
|
|
33
|
+
const cursor = new Date(`${untilDate}T12:00:00Z`);
|
|
34
|
+
for (let i = 0; i < 7; i += 1) {
|
|
35
|
+
cursor.setUTCDate(cursor.getUTCDate() - 1);
|
|
36
|
+
if (!eveningDatesWithActivity.has(cursor.toISOString().slice(0, 10)))
|
|
37
|
+
eveningsKept7d += 1;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
v: 1,
|
|
41
|
+
generatedAt: snapshot.generatedAt,
|
|
42
|
+
sources: snapshot.sources.map((s) => ({ id: s.id, name: s.name, configured: s.configured, fidelity: s.fidelity, sessions: s.sessions })),
|
|
43
|
+
sync,
|
|
44
|
+
line: { lastActivityAt, resolution, eveningsKept7d },
|
|
45
|
+
spool,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function writeStatus(home, status) {
|
|
49
|
+
const path = statusPath(home);
|
|
50
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
51
|
+
const tmp = `${path}.tmp`;
|
|
52
|
+
writeFileSync(tmp, `${JSON.stringify(status, null, 2)}\n`);
|
|
53
|
+
renameSync(tmp, path);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/macos/status.ts"],"names":[],"mappings":"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"}
|
package/dist/privacy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAIxE;AAED,eAAO,MAAM,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAIxE;AAED,eAAO,MAAM,aAAa,EAAE,YAyB3B,CAAC"}
|
package/dist/privacy.js
CHANGED
|
@@ -27,6 +27,8 @@ export const DATA_BOUNDARY = {
|
|
|
27
27
|
"agent and model family",
|
|
28
28
|
"approval and lifecycle signals",
|
|
29
29
|
"reporting timezone",
|
|
30
|
+
"collector version",
|
|
31
|
+
"since 0.5.0, a per-turn real-time event (agent, model family, hour, opaque run id, minutes-active estimate; end: id and time) sent when a turn starts and ends",
|
|
30
32
|
],
|
|
31
33
|
neverRetained: [
|
|
32
34
|
"prompt text",
|
package/dist/privacy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"privacy.js","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGhC;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,OAAe,OAAO,EAAE;IAC9D,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC;IAC3D,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,yBAAyB;IAC/B,QAAQ,EAAE;QACR,mBAAmB;QACnB,qBAAqB;QACrB,aAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,kCAAkC;QAClC,wCAAwC;QACxC,wBAAwB;QACxB,gCAAgC;QAChC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"privacy.js","sourceRoot":"","sources":["../src/privacy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGhC;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,OAAe,OAAO,EAAE;IAC9D,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC;IAC3D,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAiB;IACzC,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,yBAAyB;IAC/B,QAAQ,EAAE;QACR,mBAAmB;QACnB,qBAAqB;QACrB,aAAa;QACb,gBAAgB;QAChB,gBAAgB;QAChB,kCAAkC;QAClC,wCAAwC;QACxC,wBAAwB;QACxB,gCAAgC;QAChC,oBAAoB;QACpB,mBAAmB;QACnB,gKAAgK;KACjK;IACD,aAAa,EAAE;QACb,aAAa;QACb,aAAa;QACb,cAAc;QACd,kBAAkB;QAClB,qBAAqB;QACrB,YAAY;KACb;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runEventTypes.d.ts","sourceRoot":"","sources":["../src/runEventTypes.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runEventTypes.js","sourceRoot":"","sources":["../src/runEventTypes.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type ParsedHookEvent } from "./hooks.js";
|
|
2
|
+
type Fetcher = typeof fetch;
|
|
3
|
+
/**
|
|
4
|
+
* Real-time run events for the forecast path. A "run" is one agent turn:
|
|
5
|
+
* UserPromptSubmit opens it, Stop closes it. Only opaque ids and timing leave
|
|
6
|
+
* this module — the parsed hook event already contains no text.
|
|
7
|
+
*/
|
|
8
|
+
export type OpenTurns = Record<string, number>;
|
|
9
|
+
export declare function openTurnsPath(home?: string): string;
|
|
10
|
+
export declare function readOpenTurns(home?: string, nowMs?: number): OpenTurns;
|
|
11
|
+
export declare function writeOpenTurns(turns: OpenTurns, home?: string, nowMs?: number): void;
|
|
12
|
+
export interface RunStarted {
|
|
13
|
+
kind: "started";
|
|
14
|
+
sourceId: string;
|
|
15
|
+
runKey: string;
|
|
16
|
+
modelFamily: string | null;
|
|
17
|
+
localStartHour: number;
|
|
18
|
+
tz: string;
|
|
19
|
+
startedAtMs: number;
|
|
20
|
+
}
|
|
21
|
+
export interface RunEnded {
|
|
22
|
+
kind: "ended";
|
|
23
|
+
sourceId: string;
|
|
24
|
+
runKey: string;
|
|
25
|
+
endedAt: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Derives the real-time run-forecast event (if any) from one parsed hook
|
|
29
|
+
* event, against the caller's on-disk open-turn state.
|
|
30
|
+
*
|
|
31
|
+
* A run is one agent turn: `UserPromptSubmit` opens it, `Stop` closes it.
|
|
32
|
+
* Claude Code fires `Stop` whenever the agent yields, so if a
|
|
33
|
+
* `UserPromptSubmit` arrives while a turn is still open, that open turn was
|
|
34
|
+
* interrupted (e.g. Esc) and no `Stop` for it will ever come. The new prompt
|
|
35
|
+
* **replaces** the open turn: `next[key]` is overwritten with the new start
|
|
36
|
+
* time and a `started` event is emitted for the new turn under a new
|
|
37
|
+
* `runKey`. No `ended` event is emitted for the stale turn — the server
|
|
38
|
+
* expires it after 6 h and excludes it from accuracy, and emitting one here
|
|
39
|
+
* would fold a bogus duration into the cohort.
|
|
40
|
+
*/
|
|
41
|
+
export declare function deriveRunEvent(event: ParsedHookEvent, sourceId: "claude-code" | "codex", secret: string, turns: OpenTurns, nowMs: number, tz?: string): {
|
|
42
|
+
event: RunStarted | RunEnded | null;
|
|
43
|
+
turns: OpenTurns;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* 10-minute buckets since local midnight that contain a human hook event
|
|
47
|
+
* (a `human_prompt` signal). 0 when the journal is missing or empty; null
|
|
48
|
+
* only if the timezone is invalid.
|
|
49
|
+
*/
|
|
50
|
+
export declare function humanActiveMinutesToday(home: string, nowMs: number, tz: string): number | null;
|
|
51
|
+
/**
|
|
52
|
+
* Full hook→cloud path for `trs hook`: parse, gate on a connected account,
|
|
53
|
+
* derive the run event against on-disk open-turn state, persist that state
|
|
54
|
+
* before ever touching the network, then fire the matching best-effort POST.
|
|
55
|
+
* Never throws — a broken hook body must never interrupt the agent.
|
|
56
|
+
*/
|
|
57
|
+
export declare function emitRunEventFromHook(raw: string, sourceId: "claude-code" | "codex", home?: string, fetcher?: Fetcher, nowMs?: number, tz?: string): Promise<"started" | "ended" | "none">;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=runEvents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runEvents.d.ts","sourceRoot":"","sources":["../src/runEvents.ts"],"names":[],"mappings":"AAKA,OAAO,EAA6C,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7F,KAAK,OAAO,GAAG,OAAO,KAAK,CAAC;AAE5B;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAG/C,wBAAgB,aAAa,CAAC,IAAI,SAAY,GAAG,MAAM,CAEtD;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAY,EAAE,KAAK,GAAE,MAAmB,GAAG,SAAS,CAarF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,SAAY,EAAE,KAAK,GAAE,MAAmB,GAAG,IAAI,CAQnG;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AASD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,aAAa,GAAG,OAAO,EACjC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EACb,EAAE,GAAE,MAAyD,GAC5D;IAAE,KAAK,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAqC3D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB9F;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,aAAa,GAAG,OAAO,EACjC,IAAI,GAAE,MAAkB,EACxB,OAAO,GAAE,OAAe,EACxB,KAAK,GAAE,MAAmB,EAC1B,EAAE,GAAE,MAAyD,GAC5D,OAAO,CAAC,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC,CAqBvC"}
|