cogpit-memory 0.4.0 → 0.4.2

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.
@@ -78,6 +78,8 @@ export interface AgentCapabilities {
78
78
  readonly imageInput: boolean;
79
79
  /** A message can be delivered into an already-running turn. */
80
80
  readonly midTurnSteering: boolean;
81
+ /** Shared informational input can join active work at the provider's next opportunity. */
82
+ readonly activeNotifications: boolean;
81
83
  /** The whole session can be shut down from the composer. */
82
84
  readonly stopSession: boolean;
83
85
  /** Maximum-effort orchestration mode, pinned to the top effort level. */
@@ -214,6 +216,8 @@ export interface AgentCli {
214
216
  /** Environment variable overriding that directory, if the CLI has one. */
215
217
  readonly homeEnvVar: string | null;
216
218
  readonly sdkHomeEnvVar?: string;
219
+ /** The native session ID this CLI supplies to its shell commands. */
220
+ readonly sessionIdEnvVar?: string;
217
221
  /**
218
222
  * Path inside the home whose existence proves the CLI has been used. Empty
219
223
  * when the home directory itself is the evidence.
@@ -41,6 +41,18 @@ export interface AgentFormat {
41
41
  metadataFromLines(lines: readonly string[]): AgentSessionMetadata;
42
42
  /** Status derived from raw records. */
43
43
  status(records: readonly RawRecord[]): SessionStatusInfo;
44
+ /**
45
+ * True for a raw line the CLI writes for its own bookkeeping that no reader
46
+ * of the transcript uses. The server drops these before paging or streaming,
47
+ * so they never take a page's byte budget or line floor.
48
+ */
49
+ isNoiseLine(line: string): boolean;
50
+ /**
51
+ * The transcript's first line as a page of it carries it, when a reader of
52
+ * one page needs facts about the rest of the file. `lastLines` reads the
53
+ * file's last complete lines.
54
+ */
55
+ pageHeaderLine?(firstLine: string, lastLines: () => Promise<readonly string[]>): Promise<string>;
44
56
  /**
45
57
  * The first record of a transcript, rewritten for a branch cut at
46
58
  * `branchedAt`: it now names `sessionId` and records the session and turn
@@ -75,6 +87,8 @@ export declare function formatForText(jsonlText: string): AgentFormat;
75
87
  export declare function formatForRecords(records: readonly {
76
88
  type?: unknown;
77
89
  }[]): AgentFormat;
90
+ /** `isNoiseLine` for a scan that reads lines before it knows which agent wrote them. */
91
+ export declare function isAnyAgentNoiseLine(line: string): boolean;
78
92
  /**
79
93
  * Boundary indexes for raw JSONL lines rather than parsed records.
80
94
  *
@@ -0,0 +1,10 @@
1
+ import type { Turn } from "./types";
2
+ /**
3
+ * Records on each async question the reader's first prompt after it.
4
+ *
5
+ * Nothing links a reply to its question, so that prompt answers every question
6
+ * still open when it arrives. A pure recompute over the list handed in, so the
7
+ * page stitcher re-runs it across a join and gets what a single parse would
8
+ * have produced. Turns whose answers did not change come back by reference.
9
+ */
10
+ export declare function linkAsyncAnswers(turns: readonly Turn[]): Turn[];
@@ -0,0 +1,4 @@
1
+ export declare const CREW_CHAT_DELIVERY_RE: RegExp;
2
+ export declare const TASK_WAKEUP_START_RE: RegExp;
3
+ /** Whether a prompt came from the reader rather than a crew, a child task or another agent. */
4
+ export declare function isReaderPrompt(text: string): boolean;
@@ -0,0 +1,16 @@
1
+ import type { BackgroundAgent, SessionStatusInfo } from "./types";
2
+ /** A launched background agent, placed by the transcript records that started and ended it. */
3
+ export interface AgentLaunch {
4
+ agent: Omit<BackgroundAgent, "done">;
5
+ /** Index of the record that launched it */
6
+ launchedAt: number;
7
+ /** Index of the record that completed, failed or stopped it; absent while it runs */
8
+ endedAt?: number;
9
+ }
10
+ /**
11
+ * The awaiting-agents status for a session's background agents, or null when
12
+ * none is still running. The batch is every agent launched since the last
13
+ * moment no agent was running, so agents that already finished in this wait
14
+ * still count toward its progress.
15
+ */
16
+ export declare function awaitingAgentsStatus(launches: readonly AgentLaunch[], pendingQueue?: number): SessionStatusInfo | null;
@@ -9,6 +9,16 @@ import type { ParseSessionOptions, ParsedSession, RawRecord, SessionStatusInfo }
9
9
  * registry exists to remove.
10
10
  */
11
11
  export declare function isClaudeSessionText(): boolean;
12
+ /**
13
+ * True for the `api-request`, `api-request-blob` and `api-request-shape`
14
+ * records Claude Code 2.1.300+ logs for every API call. Nothing reads them,
15
+ * and they can be most of a transcript's bytes.
16
+ *
17
+ * Inside a JSON string every quote is escaped, so `"type":"api-request` can
18
+ * only be a key and its value; with no `{` before it but the line's own, it is
19
+ * the top-level key, wherever the writer put it.
20
+ */
21
+ export declare function isClaudeNoiseLine(line: string): boolean;
12
22
  export interface ClaudeMetadata {
13
23
  sessionId: string;
14
24
  version: string;
@@ -32,6 +32,31 @@ interface CodexMetadata {
32
32
  * `source.subagent.thread_spawn`.
33
33
  */
34
34
  export declare function codexParentId(payload: Record<string, unknown>): string | null;
35
+ /**
36
+ * A rollout's first line as a page of it carries it: a sub-agent's
37
+ * `session_meta` gains the ordinal of the rollout's last record, so a page
38
+ * holding only copied history still knows its history boundary is real.
39
+ */
40
+ export declare function codexPageHeaderLine(firstLine: string, lastLines: () => Promise<readonly string[]>): Promise<string>;
41
+ /**
42
+ * The prompt a record carries, or "" for any other record, including the
43
+ * AGENTS.md, environment and other context Codex injects as user messages.
44
+ */
45
+ export declare function codexPromptText(record: {
46
+ type?: unknown;
47
+ payload?: unknown;
48
+ }): string;
49
+ /**
50
+ * Reads each prompt in a rollout once, fed its records in order.
51
+ *
52
+ * Codex 0.15x+ writes a prompt only as a `response_item` user message. Older
53
+ * CLIs follow that record with an `event_msg` `user_message` echo of it, which
54
+ * this skips.
55
+ */
56
+ export declare function createCodexPromptReader(): (record: {
57
+ type?: unknown;
58
+ payload?: unknown;
59
+ }) => string;
35
60
  export declare function isCodexSessionText(jsonlText: string): boolean;
36
61
  /** True when already-parsed raw records came from this CLI. */
37
62
  export declare function isCodexRawRecords(records: readonly {
@@ -0,0 +1,22 @@
1
+ export declare function isCompressedTranscript(filePath: string): boolean;
2
+ /** The name a transcript has uncompressed. */
3
+ export declare function uncompressedTranscriptName(fileName: string): string;
4
+ /**
5
+ * Whether a directory entry is a transcript this runtime can read, given its
6
+ * siblings: mid-compression both forms exist, and the plain one is current.
7
+ */
8
+ export declare function isListableTranscript(name: string, siblings: ReadonlySet<string>): boolean;
9
+ export declare function readTranscriptTextSync(filePath: string): string;
10
+ export declare function readTranscriptText(filePath: string): Promise<string>;
11
+ /** The subset of a `FileHandle` transcript readers use. */
12
+ export interface TranscriptHandle {
13
+ read(buffer: Buffer, offset: number, length: number, position: number): Promise<{
14
+ bytesRead: number;
15
+ }>;
16
+ stat(): Promise<{
17
+ size: number;
18
+ mtimeMs: number;
19
+ }>;
20
+ close(): Promise<void>;
21
+ }
22
+ export declare function openTranscript(filePath: string): Promise<TranscriptHandle>;
@@ -19,6 +19,19 @@ export interface SessionStatusInfo {
19
19
  pendingAgents?: number;
20
20
  /** Short descriptions of the pending background agents, oldest first */
21
21
  pendingAgentDescriptions?: string[];
22
+ /** Agents launched since the oldest one still running, in launch order (status awaiting_agents) */
23
+ backgroundAgents?: BackgroundAgent[];
24
+ }
25
+ /** A background agent launched by the session. */
26
+ export interface BackgroundAgent {
27
+ /** What the agent was asked to do; empty when the launch carried no description */
28
+ description: string;
29
+ /** When the agent was launched (ISO), if the transcript records it */
30
+ startedAt?: string;
31
+ /** The launching tool call, which keys the agent's live progress summaries */
32
+ toolUseId?: string;
33
+ /** Finished, failed or stopped */
34
+ done: boolean;
22
35
  }
23
36
  /** A raw transcript record, before any agent-specific interpretation. */
24
37
  export type RawRecord = {
@@ -202,6 +215,15 @@ export interface AgentProgressData {
202
215
  };
203
216
  prompt: string;
204
217
  agentId: string;
218
+ /**
219
+ * Written by Cogpit's subagent watcher. The Agent call that launched this
220
+ * agent, when that differs from the record's `parentToolUseID` — a nested
221
+ * agent's records are filed under the main-thread call it descends from.
222
+ */
223
+ toolUseId?: string;
224
+ /** The subagent that launched this one (the CLI's `parent_task_id`). */
225
+ parentAgentId?: string;
226
+ subagentType?: string;
205
227
  }
206
228
  export type HookEventName = "PreToolUse" | "PostToolUse" | "PostToolUseFailure" | "UserPromptSubmit" | "SessionStart" | "SessionEnd" | "Stop" | "StopFailure" | "SubagentStop" | "PreCompact" | "PostCompact" | "PreModelSwitch" | "PostModelSwitch" | "PermissionDenied" | "TaskCreated" | "WorktreeCreate" | "CwdChanged" | "FileChanged" | "Elicitation" | "ElicitationResult" | "Notification";
207
229
  export interface HookProgressData {
@@ -271,9 +293,14 @@ export interface SystemMessage extends BaseMessage {
271
293
  isMeta?: boolean;
272
294
  content?: string;
273
295
  compactMetadata?: CompactionMeta;
296
+ /** On a `local_command` record answering `/context`. */
297
+ contextUsage?: LocalCommandContextUsage;
298
+ /** On a `local_command` record answering `/usage`. */
299
+ usageReport?: LocalCommandUsageReport;
274
300
  }
275
301
  export interface CompactionMeta {
276
- trigger: "auto" | "manual";
302
+ /** "idle" (Claude Code 2.1.290+) compacts while the session waits for the user. */
303
+ trigger: "auto" | "manual" | "idle";
277
304
  preTokens: number;
278
305
  postTokens?: number;
279
306
  }
@@ -384,6 +411,8 @@ export interface ToolCall {
384
411
  * answered here.
385
412
  */
386
413
  asyncQuestion?: boolean;
414
+ /** The reader's reply to an async question, once the transcript holds one. */
415
+ asyncAnswer?: string;
387
416
  /** Set by parser when a PostToolUse hook replaced this tool's output */
388
417
  outputReplacedByHook?: boolean;
389
418
  /** Total duration of PostToolUse hooks attached to this call, summed in ms */
@@ -393,6 +422,8 @@ export interface SubAgentMessage {
393
422
  agentId: string;
394
423
  /** The Task/Agent tool_use id this agent belongs to (streaming overlay key) */
395
424
  parentToolUseId?: string;
425
+ /** The subagent that launched this one; absent when the main thread did. */
426
+ parentAgentId?: string;
396
427
  agentName: string | null;
397
428
  subagentType: string | null;
398
429
  type: "user" | "assistant";
@@ -403,6 +434,8 @@ export interface SubAgentMessage {
403
434
  timestamp: string;
404
435
  tokenUsage: TokenUsage | null;
405
436
  model: string | null;
437
+ /** Reasoning effort the agent ran at, when its spawn recorded one. */
438
+ effort?: string;
406
439
  isBackground: boolean;
407
440
  /** Summary fields from toolUseResult (new format, v2.1.63+) */
408
441
  prompt?: string;
@@ -494,13 +527,98 @@ export type TurnContentBlock = {
494
527
  * Output of a slash command that ran locally and answered the user directly
495
528
  * (`/usage`, `/context`, `/recap`), recorded as a `local_command` system
496
529
  * record. `content` is the raw record text, `<local-command-stdout>` tags
497
- * included, left for the renderers like `task_notification`.
530
+ * included, left for the renderers like `task_notification`. Newer CLIs
531
+ * record a structured twin of `/context` and `/usage` beside the text.
498
532
  */
499
533
  | {
500
534
  kind: "local_command";
501
535
  content: string;
502
536
  timestamp?: string;
537
+ contextUsage?: LocalCommandContextUsage;
538
+ usageReport?: LocalCommandUsageReport;
503
539
  };
540
+ /** One `/context` category row. Classify on `kind`, never on the display name. */
541
+ export interface ContextUsageCategory {
542
+ name: string;
543
+ tokens: number;
544
+ /** `deferred` rows sit outside the window and stay out of the usage math. */
545
+ kind: "used" | "free" | "buffer" | "deferred";
546
+ }
547
+ /** The structured twin of a `/context` reply, as the CLI records it. */
548
+ export interface LocalCommandContextUsage {
549
+ model: string;
550
+ total_tokens: number;
551
+ /** The window usage is measured against. */
552
+ raw_max_tokens: number;
553
+ percentage: number;
554
+ over_limit?: {
555
+ tokens_over: number;
556
+ kind: "hard_limit" | "compaction_window";
557
+ };
558
+ categories: ContextUsageCategory[];
559
+ mcp_tools?: {
560
+ name: string;
561
+ server_name: string;
562
+ tokens: number;
563
+ }[];
564
+ memory_files?: {
565
+ path: string;
566
+ type: string;
567
+ tokens: number;
568
+ }[];
569
+ agents?: {
570
+ agent_type: string;
571
+ source: string;
572
+ tokens: number;
573
+ }[];
574
+ skills?: {
575
+ name: string;
576
+ source: string;
577
+ plugin_name?: string;
578
+ tokens: number;
579
+ }[];
580
+ }
581
+ /** One plan meter of a `/usage` reply, rendered in the server's order and grading. */
582
+ export interface UsageLimitRow {
583
+ /** The meter kind, e.g. `session`, `weekly_all`, `weekly_scoped`. */
584
+ kind: string;
585
+ group: string;
586
+ percent: number;
587
+ resets_at: string | null;
588
+ scope?: {
589
+ model?: {
590
+ display_name: string;
591
+ } | null;
592
+ surface?: {
593
+ display_name: string;
594
+ } | null;
595
+ } | null;
596
+ /** e.g. `normal`, `warning`, `critical`. */
597
+ severity: string;
598
+ is_active: boolean;
599
+ }
600
+ /** The structured twin of a `/usage` reply, as the CLI records it. */
601
+ export interface LocalCommandUsageReport {
602
+ session: {
603
+ total_cost_usd: number;
604
+ total_api_duration_ms: number;
605
+ total_duration_ms: number;
606
+ total_lines_added: number;
607
+ total_lines_removed: number;
608
+ };
609
+ /** Null when the plan's usage could not be fetched (no plan, API key). */
610
+ rate_limits: {
611
+ limits: UsageLimitRow[] | null;
612
+ /** Amounts are in minor units of `currency`. */
613
+ extra_usage?: {
614
+ is_enabled: boolean;
615
+ monthly_limit: number | null;
616
+ used_credits: number | null;
617
+ utilization: number | null;
618
+ currency?: string | null;
619
+ } | null;
620
+ } | null;
621
+ }
504
622
  export interface Turn {
505
623
  id: string;
506
624
  userMessage: UserContent | null;
@@ -540,6 +658,13 @@ export interface Turn {
540
658
  * must be stitched onto the previous turn once the older page arrives.
541
659
  */
542
660
  isFragment?: boolean;
661
+ /**
662
+ * Set when the parse window opened on this turn's prompt record, with no turn
663
+ * context before it. An older CLI's echo of a prompt steered into the previous
664
+ * page's last turn looks exactly like this, so the page stitcher may fold it
665
+ * back into that steer.
666
+ */
667
+ opensOnPrompt?: boolean;
543
668
  }
544
669
  export interface SessionStats {
545
670
  totalInputTokens: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogpit-memory",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "CLI tool for Claude Code, Codex, and GitHub Copilot CLI session introspection",
5
5
  "license": "MIT",
6
6
  "repository": {