@cerebriline/core 4.100.245 → 4.100.247

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 (126) hide show
  1. package/assets/prompt-templates/claude.md +2 -0
  2. package/assets/prompt-templates/deepseek.md +1 -0
  3. package/assets/prompt-templates/default.md +2 -1
  4. package/assets/prompt-templates/kimi-k3.md +1 -0
  5. package/assets/prompt-templates/kimi.md +1 -0
  6. package/assets/prompt-templates/minimax.md +2 -0
  7. package/assets/prompt-templates/nemotron.md +1 -0
  8. package/assets/skills/browser-automation/SKILL.md +113 -0
  9. package/dist/ClineCore.d.ts +9 -0
  10. package/dist/account/index.d.ts +1 -0
  11. package/dist/account/telemetry.d.ts +22 -0
  12. package/dist/cloud/api.d.ts +122 -0
  13. package/dist/cloud/controller.d.ts +172 -0
  14. package/dist/cloud/index.d.ts +9 -0
  15. package/dist/cloud/index.js +21 -0
  16. package/dist/cloud/models.d.ts +9 -0
  17. package/dist/cloud/repositories.d.ts +21 -0
  18. package/dist/cloud/snapshots.d.ts +22 -0
  19. package/dist/cloud/state.d.ts +13 -0
  20. package/dist/cloud/types.d.ts +84 -0
  21. package/dist/cron/events/cron-event-ingress.d.ts +4 -2
  22. package/dist/cron/runner/cron-runner.d.ts +5 -2
  23. package/dist/cron/service/cron-service.d.ts +2 -1
  24. package/dist/cron/service/schedule-service.d.ts +2 -1
  25. package/dist/cron/store/sqlite-cron-store.d.ts +7 -1
  26. package/dist/extensions/composio/composio-meta-tools.d.ts +39 -0
  27. package/dist/extensions/composio/composio-tools-extension.d.ts +13 -0
  28. package/dist/extensions/context/agentic-compaction.d.ts +1 -1
  29. package/dist/extensions/context/cap-thoughts.d.ts +39 -0
  30. package/dist/extensions/context/capped-thinking.d.ts +5 -0
  31. package/dist/extensions/context/compaction-shared.d.ts +76 -1
  32. package/dist/extensions/context/compaction.d.ts +81 -3
  33. package/dist/extensions/mcp/client.d.ts +1 -1
  34. package/dist/extensions/tools/code-search.d.ts +16 -0
  35. package/dist/extensions/tools/definitions.d.ts +5 -5
  36. package/dist/extensions/tools/executors/bash.d.ts +26 -0
  37. package/dist/extensions/tools/executors/index.d.ts +1 -1
  38. package/dist/extensions/tools/index.d.ts +1 -1
  39. package/dist/extensions/tools/library-tools.d.ts +14 -0
  40. package/dist/extensions/tools/schemas.d.ts +2 -11
  41. package/dist/extensions/tools/task-progress.d.ts +37 -0
  42. package/dist/extensions/tools/team/index.d.ts +1 -0
  43. package/dist/extensions/tools/team/multi-agent.d.ts +48 -0
  44. package/dist/extensions/tools/team/persistence-policy.d.ts +56 -0
  45. package/dist/extensions/tools/team/runtime.d.ts +1 -1
  46. package/dist/extensions/tools/team/sanitize-team-name.d.ts +5 -0
  47. package/dist/extensions/tools/team/team-tools.d.ts +1 -1
  48. package/dist/extensions/tools/types.d.ts +9 -1
  49. package/dist/extensions/tools/web-scrape-tool.d.ts +49 -0
  50. package/dist/extensions/tools/web-site-crawl.d.ts +96 -0
  51. package/dist/hooks/checkpoint-hooks.d.ts +23 -1
  52. package/dist/hooks/hook-file-hooks.d.ts +27 -0
  53. package/dist/hooks/subprocess-runner.d.ts +23 -0
  54. package/dist/hooks/subprocess.d.ts +10 -0
  55. package/dist/hub/client/index.d.ts +29 -3
  56. package/dist/hub/client/session-client.d.ts +0 -3
  57. package/dist/hub/daemon/bind-diagnostics.d.ts +16 -0
  58. package/dist/hub/daemon/entry.js +701 -652
  59. package/dist/hub/daemon/index.d.ts +17 -8
  60. package/dist/hub/discovery/index.d.ts +1 -0
  61. package/dist/hub/index.js +690 -642
  62. package/dist/hub/runtime-host/hub-runtime-host.d.ts +4 -2
  63. package/dist/hub/server/handlers/session-handlers.d.ts +6 -1
  64. package/dist/index.d.ts +24 -12
  65. package/dist/index.js +1137 -1062
  66. package/dist/remote/remote-environments.d.ts +155 -0
  67. package/dist/remote/remote-helper-entry.d.ts +1 -0
  68. package/dist/remote/remote-helper-entry.js +5 -0
  69. package/dist/remote/remote-helper.d.ts +29 -0
  70. package/dist/remote/remote-helper.js +4 -0
  71. package/dist/remote/shell-path.d.ts +88 -0
  72. package/dist/runtime/host/local-runtime-host.d.ts +4 -2
  73. package/dist/runtime/host/runtime-host.d.ts +13 -1
  74. package/dist/runtime/orchestration/oauth-refresh-lock.d.ts +6 -0
  75. package/dist/runtime/orchestration/session-runtime-orchestrator.d.ts +7 -0
  76. package/dist/runtime/orchestration/team-persistence-writer.d.ts +65 -0
  77. package/dist/runtime/safety/rules.d.ts +11 -0
  78. package/dist/runtime/turn-queue/pending-prompt-service.d.ts +1 -0
  79. package/dist/services/agent-events.d.ts +1 -0
  80. package/dist/services/cloud-handoff/git-preflight.d.ts +24 -0
  81. package/dist/services/cloud-handoff/index.d.ts +4 -0
  82. package/dist/services/cloud-handoff/metadata.d.ts +7 -0
  83. package/dist/services/cloud-handoff/transcript.d.ts +5 -0
  84. package/dist/services/cloud-handoff/types.d.ts +35 -0
  85. package/dist/services/feature-flags/FeatureFlagsService.d.ts +2 -0
  86. package/dist/services/feature-flags/cline-account-feature-flags.d.ts +5 -0
  87. package/dist/services/llms/cline-recommended-models.d.ts +1 -0
  88. package/dist/services/llms/handler-factory.d.ts +12 -0
  89. package/dist/services/llms/provider-defaults.d.ts +1 -1
  90. package/dist/services/llms/provider-settings.d.ts +19 -17
  91. package/dist/services/local-runtime-bootstrap.d.ts +7 -0
  92. package/dist/services/mcp-install.d.ts +9 -0
  93. package/dist/services/plugin-commands.d.ts +28 -0
  94. package/dist/services/providers/local-provider-registry.d.ts +8 -3
  95. package/dist/services/providers/local-provider-service.d.ts +20 -10
  96. package/dist/services/providers/model-source.d.ts +6 -1
  97. package/dist/services/providers/provider-config-fields.d.ts +11 -0
  98. package/dist/services/retrieval/code-index.d.ts +2 -0
  99. package/dist/services/retrieval/firecrawl.d.ts +15 -0
  100. package/dist/services/retrieval/web-mirror.d.ts +101 -0
  101. package/dist/services/session-import/claude-code.d.ts +1 -1
  102. package/dist/services/session-import/paths.d.ts +9 -0
  103. package/dist/services/storage/file-team-store.d.ts +10 -4
  104. package/dist/services/storage/sqlite-team-store.d.ts +48 -5
  105. package/dist/services/storage/team-store.d.ts +1 -0
  106. package/dist/services/telemetry/core-events.d.ts +97 -5
  107. package/dist/services/telemetry/index.d.ts +1 -0
  108. package/dist/services/telemetry/index.js +1 -1
  109. package/dist/services/telemetry/scoped-telemetry.d.ts +31 -0
  110. package/dist/services/workspace/workspace-manifest.d.ts +34 -0
  111. package/dist/services/workspace/workspace-telemetry.d.ts +5 -0
  112. package/dist/session/fork-metadata.d.ts +7 -0
  113. package/dist/session/models/session-compaction.d.ts +8 -1
  114. package/dist/session/services/message-builder.d.ts +8 -1
  115. package/dist/session/services/persistence-service.d.ts +4 -1
  116. package/dist/session/services/tool-result-cache.d.ts +30 -0
  117. package/dist/session/session-versioning-service.d.ts +8 -0
  118. package/dist/session/stores/session-manifest-store.d.ts +2 -4
  119. package/dist/session/team/team-session-coordinator.d.ts +3 -1
  120. package/dist/tasks/task-tool.d.ts +2 -2
  121. package/dist/types/provider-settings.d.ts +11 -0
  122. package/dist/types/session.d.ts +2 -0
  123. package/dist/types/storage.d.ts +22 -1
  124. package/package.json +16 -4
  125. package/dist/cron/runner/resource-limiter.d.ts +0 -8
  126. package/dist/services/storage/team-events-retention.d.ts +0 -25
@@ -21,6 +21,11 @@ export interface ScrapedPage {
21
21
  sha256: string;
22
22
  /** The links on the page, when they were asked for. */
23
23
  links?: string[];
24
+ /**
25
+ * The whole page as the browser held it after its scripts ran, when it
26
+ * was asked for: every tag, nothing cleaned out.
27
+ */
28
+ rawHtml?: string;
24
29
  }
25
30
  export interface ScrapeFailure {
26
31
  url: string;
@@ -34,6 +39,15 @@ export interface CrawlOptions {
34
39
  /** Only paths matching these (regular expressions), when given. */
35
40
  includePaths?: readonly string[];
36
41
  excludePaths?: readonly string[];
42
+ /**
43
+ * Follow links anywhere on the site. Without it a crawl stays below the
44
+ * address it starts from: from `/docs/intro` it never reaches `/docs/api`.
45
+ */
46
+ entireDomain?: boolean;
47
+ /** Also give each page's links, to tell what a crawl left unread. */
48
+ links?: boolean;
49
+ /** Also give each page whole, as rendered (`ScrapedPage.rawHtml`). */
50
+ rawHtml?: boolean;
37
51
  signal?: AbortSignal;
38
52
  fetch?: typeof fetch;
39
53
  /** How long to wait for the crawl. @default 20 minutes */
@@ -62,6 +76,7 @@ export declare function htmlToMarkdown(html: string): Promise<string>;
62
76
  /** Read one page. */
63
77
  export declare function scrapePage(endpoint: ScrapeEndpoint, url: string, options?: RequestOptions & {
64
78
  links?: boolean;
79
+ rawHtml?: boolean;
65
80
  }): Promise<ScrapedPage>;
66
81
  /** Read a page and the pages it links to, as deep and as many as `options` allow. */
67
82
  export declare function crawlSite(endpoint: ScrapeEndpoint, url: string, options: CrawlOptions): Promise<CrawlResult>;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * A site's pages and the files they need, saved as they are.
3
+ *
4
+ * The scraping endpoint reads pages in a browser and gives back their content;
5
+ * it does not give back a stylesheet, a script, a picture or a font. Those are
6
+ * fetched here, straight from the site, by the machine this runs on.
7
+ *
8
+ * Nothing is rewritten. A page is saved as the site served it, byte for byte,
9
+ * and beside it as the browser held it once its scripts had run -- on a site
10
+ * built by JavaScript the first is a shell of a few lines and the second is
11
+ * the page. Links inside them still point where they pointed.
12
+ */
13
+ export interface MirrorPage {
14
+ url: string;
15
+ /** The page as rendered, when the scraper gave it. */
16
+ rawHtml?: string;
17
+ }
18
+ export interface MirrorLimits {
19
+ /** Files fetched besides the pages, at most. @default 2000 */
20
+ maxAssets?: number;
21
+ /** One file's size, at most. @default 25 MB */
22
+ maxAssetBytes?: number;
23
+ /** Everything fetched, at most. @default 300 MB */
24
+ maxTotalBytes?: number;
25
+ /** How many requests run at once. @default 6 */
26
+ concurrency?: number;
27
+ /** How long one request may take. @default 30 s */
28
+ timeoutMs?: number;
29
+ }
30
+ export interface MirrorOptions extends MirrorLimits {
31
+ /** The folder everything is written under. */
32
+ root: string;
33
+ fetch?: typeof fetch;
34
+ signal?: AbortSignal;
35
+ onProgress?: (done: number, known: number) => void;
36
+ /**
37
+ * The file already saved for an address, from an earlier crawl into the
38
+ * same folder: it is not fetched again.
39
+ */
40
+ have?: (url: string) => string | undefined;
41
+ /** Files to fetch besides those the pages name: what an earlier crawl left. */
42
+ also?: readonly string[];
43
+ }
44
+ export interface MirroredPage {
45
+ url: string;
46
+ /** As the site served it; absent when the direct request failed. */
47
+ served?: string;
48
+ /** As the browser rendered it; absent when the scraper gave none. */
49
+ rendered?: string;
50
+ /** Why there is no `served`. */
51
+ problem?: string;
52
+ }
53
+ export interface MirrorReport {
54
+ pages: MirroredPage[];
55
+ /** Files saved besides the pages, by their path under the folder. */
56
+ assets: {
57
+ url: string;
58
+ file: string;
59
+ bytes: number;
60
+ }[];
61
+ failed: {
62
+ url: string;
63
+ reason: string;
64
+ }[];
65
+ /** Files left out because a limit was reached. */
66
+ skipped: number;
67
+ /** Their addresses, for a later crawl to fetch. */
68
+ left: string[];
69
+ /** How many of them the limit of files stopped, and how many the total size. */
70
+ leftForCount: number;
71
+ leftForSize: number;
72
+ /** Files over the size one file may have; they are in `failed` too. */
73
+ tooLarge: number;
74
+ /** Files an earlier crawl had already saved. */
75
+ reused: number;
76
+ bytes: number;
77
+ }
78
+ /**
79
+ * Where a page or a file of a site goes under the folder: its host, then its
80
+ * path as the site has it. A page always ends in `.html`; a path ending in `/`
81
+ * is that folder's `index.html`. A page's query is part of its name, since two
82
+ * queries are two pages; a file's is not, since it is nearly always a cache
83
+ * stamp on one file.
84
+ */
85
+ export declare function mirrorPath(url: string, kind: "page" | "asset", contentType?: string): string | undefined;
86
+ /** `X.html` as `X.rendered.html`. */
87
+ export declare function renderedPath(served: string): string;
88
+ /** The files a stylesheet needs: what it imports, and every `url(...)`. */
89
+ export declare function cssLinks(css: string, base: string): string[];
90
+ /**
91
+ * The files a page needs to look and behave as it does: stylesheets, scripts,
92
+ * pictures, fonts, icons, media. Not the pages it links to.
93
+ */
94
+ export declare function assetLinks(html: string, pageUrl: string): string[];
95
+ /**
96
+ * Save `pages` and every file they need under `options.root`.
97
+ *
98
+ * Never throws for a page or a file that could not be had: each is in the
99
+ * report with its reason. Throws only when the run is aborted.
100
+ */
101
+ export declare function mirrorSite(pages: readonly MirrorPage[], options: MirrorOptions): Promise<MirrorReport>;
@@ -1,6 +1,6 @@
1
1
  import { type ConvertedImportedSession, type ImportableSessionSummary, type SessionImportAdapter } from "./types";
2
2
  export interface ClaudeCodeAdapterOptions {
3
- /** Defaults to ~/.claude/projects */
3
+ /** Defaults to $CLAUDE_CONFIG_DIR/projects or ~/.claude/projects */
4
4
  projectsDir?: string;
5
5
  }
6
6
  export declare class ClaudeCodeImportAdapter implements SessionImportAdapter {
@@ -0,0 +1,9 @@
1
+ export interface SessionImportPathEnvironment {
2
+ platform: NodeJS.Platform;
3
+ homeDir: string;
4
+ env: Readonly<Record<string, string | undefined>>;
5
+ joinPath: (...paths: string[]) => string;
6
+ }
7
+ export declare function claudeCodeProjectsDir(environment?: SessionImportPathEnvironment): string;
8
+ export declare function codexHomeDir(environment?: SessionImportPathEnvironment): string;
9
+ export declare function opencodeDataDir(environment?: SessionImportPathEnvironment): string;
@@ -1,8 +1,7 @@
1
1
  import type { TeamRuntimeState, TeamTeammateSpec } from "@cerebriline/shared";
2
2
  import type { TeamEvent } from "../../extensions/tools/team";
3
- import type { TeamStore } from "../../types/storage";
4
- import { type TeamEventsRetention } from "./team-events-retention";
5
- export interface FileTeamStoreOptions extends TeamEventsRetention {
3
+ import type { TeamPersistenceBatch, TeamStore } from "../../types/storage";
4
+ export interface FileTeamStoreOptions {
6
5
  teamDir?: string;
7
6
  }
8
7
  export interface TeamRuntimeLoadResult {
@@ -12,7 +11,6 @@ export interface TeamRuntimeLoadResult {
12
11
  }
13
12
  export declare class FileTeamStore implements TeamStore {
14
13
  private readonly teamDirPath;
15
- private readonly eventsPrune;
16
14
  constructor(options?: FileTeamStoreOptions);
17
15
  /** Nothing is held open between calls; present so both stores close alike. */
18
16
  close(): void;
@@ -22,6 +20,14 @@ export declare class FileTeamStore implements TeamStore {
22
20
  readHistory(teamName: string, limit?: number): unknown[];
23
21
  loadRuntime(teamName: string): TeamRuntimeLoadResult;
24
22
  handleTeamEvent(teamName: string, event: TeamEvent): void;
23
+ /**
24
+ * The file store cannot apply deltas, so it rewrites `state.json` once per
25
+ * batch. Batching plus compacted run results keep that file small.
26
+ */
27
+ persistBatch(teamName: string, batch: TeamPersistenceBatch): void;
28
+ private appendHistory;
29
+ /** Keep the newest `retentionPerTeam` lines once the file grows too big. */
30
+ private compactHistoryIfNeeded;
25
31
  persistRuntime(teamName: string, state: TeamRuntimeState, teammates: TeamTeammateSpec[]): void;
26
32
  markInProgressRunsInterrupted(teamName: string, reason: string): string[];
27
33
  private ensureTeamDir;
@@ -1,8 +1,7 @@
1
1
  import { type TeamRuntimeState, type TeamTeammateSpec } from "@cerebriline/shared";
2
2
  import type { TeamEvent } from "../../extensions/tools/team";
3
- import type { TeamStore } from "../../types/storage";
4
- import { type TeamEventsRetention } from "./team-events-retention";
5
- export interface SqliteTeamStoreOptions extends TeamEventsRetention {
3
+ import type { TeamPersistenceBatch, TeamStore } from "../../types/storage";
4
+ export interface SqliteTeamStoreOptions {
6
5
  teamDir?: string;
7
6
  }
8
7
  export interface TeamRuntimeLoadResult {
@@ -10,11 +9,20 @@ export interface TeamRuntimeLoadResult {
10
9
  teammates: TeamTeammateSpec[];
11
10
  interruptedRunIds: string[];
12
11
  }
12
+ /** Durable event rows kept per team (history tool reads newest-first). */
13
+ export declare const TEAM_EVENT_RETENTION_PER_TEAM = 2000;
14
+ /** Event rows older than this are pruned regardless of count. */
15
+ export declare const TEAM_EVENT_RETENTION_MS: number;
16
+ export interface SqliteTeamStoreTuning {
17
+ eventRetentionPerTeam?: number;
18
+ eventRetentionMs?: number;
19
+ }
13
20
  export declare class SqliteTeamStore implements TeamStore {
14
21
  private readonly teamDirPath;
15
22
  private db;
16
- private readonly eventsPrune;
17
- constructor(options?: SqliteTeamStoreOptions);
23
+ private readonly retentionPerTeam;
24
+ private readonly retentionMs;
25
+ constructor(options?: SqliteTeamStoreOptions & SqliteTeamStoreTuning);
18
26
  init(): void;
19
27
  /**
20
28
  * Releases the database handle. The next call reopens it, so a store that
@@ -26,17 +34,52 @@ export declare class SqliteTeamStore implements TeamStore {
26
34
  private dbPath;
27
35
  private getRawDb;
28
36
  private ensureSchema;
37
+ /**
38
+ * Moves any non-empty `state_json` into entity rows, then clears it.
39
+ * v2+ builds only ever write `''`, so a non-empty value was written by an
40
+ * older build (e.g. after an image rollback). Runs on every open, not just
41
+ * the v2 migration, so those writes are recovered after re-upgrading.
42
+ * Caller owns the transaction.
43
+ */
44
+ private importLegacySnapshots;
45
+ /**
46
+ * v2 migration (one-time, transactional):
47
+ * - adds `data_json` to entity tables and new members/mailbox/mission-log
48
+ * tables, so state is rebuilt from rows instead of `state_json`;
49
+ * - moves each existing snapshot into rows, compacting run results;
50
+ * - deletes telemetry events and strips transcripts from retained ones;
51
+ * - clears `state_json` (the column stays for downgrade-safe schema).
52
+ * Run `vacuum()` afterwards to give the space back to the OS.
53
+ */
54
+ private migrateToV2;
29
55
  private run;
30
56
  private queryOne;
31
57
  private queryAll;
32
58
  /** Runs `work` in a single SQLite transaction (rollback on any error). */
33
59
  private withTransaction;
34
60
  listTeamNames(): string[];
61
+ /** Rebuild state from per-entity rows. Cost is O(live entities). */
35
62
  readState(teamName: string): TeamRuntimeState | undefined;
36
63
  readHistory(teamName: string, limit?: number): unknown[];
37
64
  loadRuntime(teamName: string): TeamRuntimeLoadResult;
38
65
  appendTeamEvent(teamName: string, eventType: string, payload: unknown, correlationId?: string): void;
66
+ /**
67
+ * Incremental write: appends events and upserts only changed entities in
68
+ * one transaction. Cost is O(changes in batch), independent of history.
69
+ */
70
+ persistBatch(teamName: string, batch: TeamPersistenceBatch): void;
71
+ /** Full rewrite, expressed as a reset delta (no `state_json` blob). */
39
72
  persistRuntime(teamName: string, state: TeamRuntimeState, teammates: TeamTeammateSpec[]): void;
73
+ private writeTeammates;
74
+ private writeDelta;
75
+ /** Cap `team_events` per team by count and by age. */
76
+ private pruneTeamEvents;
77
+ /**
78
+ * Return free pages to the OS after the v2 migration or heavy pruning.
79
+ * VACUUM rewrites the whole file, so it is explicit, not automatic.
80
+ */
81
+ vacuum(): void;
40
82
  markInProgressRunsInterrupted(teamName: string, reason: string): string[];
83
+ /** Legacy single-event path: telemetry is dropped, payloads compacted. */
41
84
  handleTeamEvent(teamName: string, event: TeamEvent): void;
42
85
  }
@@ -10,6 +10,7 @@ export declare function createLocalTeamStore(options?: SqliteTeamStoreOptions):
10
10
  readHistory(teamName: string, limit?: number): unknown[];
11
11
  loadRuntime(teamName: string): ReturnType<FileTeamStore["loadRuntime"]>;
12
12
  handleTeamEvent: FileTeamStore["handleTeamEvent"];
13
+ persistBatch: FileTeamStore["persistBatch"];
13
14
  persistRuntime: FileTeamStore["persistRuntime"];
14
15
  markInProgressRunsInterrupted: FileTeamStore["markInProgressRunsInterrupted"];
15
16
  close(): void;
@@ -14,12 +14,17 @@ export interface TelemetryAgentIdentityProperties {
14
14
  teamAgentId?: string;
15
15
  }
16
16
  export declare const CORE_TELEMETRY_EVENTS: {
17
+ readonly SCHEDULE: {
18
+ readonly RUN_STARTED: "schedule.run_started";
19
+ readonly RUN_FINISHED: "schedule.run_finished";
20
+ };
17
21
  readonly CLIENT: {
18
22
  readonly EXTENSION_ACTIVATED: "user.extension_activated";
19
23
  };
20
24
  readonly SESSION: {
21
25
  readonly STARTED: "session.started";
22
26
  readonly ENDED: "session.ended";
27
+ readonly ERROR_RECORDED: "session.error_recorded";
23
28
  };
24
29
  readonly AGENT: {
25
30
  readonly UNEXPECTED_REASONING_TOKENS: "agent.reasoning.unexpected_tokens";
@@ -38,6 +43,7 @@ export declare const CORE_TELEMETRY_EVENTS: {
38
43
  readonly CREATED: "task.created";
39
44
  readonly RESTARTED: "task.restarted";
40
45
  readonly COMPLETED: "task.completed";
46
+ readonly GIT_SNAPSHOT: "task.git_snapshot";
41
47
  readonly CONVERSATION_TURN: "task.conversation_turn";
42
48
  readonly TOKEN_USAGE: "task.tokens";
43
49
  readonly MODE_SWITCH: "task.mode";
@@ -50,6 +56,7 @@ export declare const CORE_TELEMETRY_EVENTS: {
50
56
  readonly PROVIDER_STREAM_STARTED: "task.provider_stream_started";
51
57
  readonly FIRST_CHUNK_RECEIVED: "task.first_chunk_received";
52
58
  readonly PROVIDER_STREAM_FAILED: "task.provider_stream_failed";
59
+ readonly MAX_TOKENS_RECOVERY: "task.max_tokens_recovery";
53
60
  readonly CANCELLED: "task.cancelled";
54
61
  readonly MENTION_USED: "task.mention_used";
55
62
  readonly MENTION_FAILED: "task.mention_failed";
@@ -64,6 +71,7 @@ export declare const CORE_TELEMETRY_EVENTS: {
64
71
  };
65
72
  readonly HOOKS: {
66
73
  readonly DISCOVERY_COMPLETED: "hooks.discovery_completed";
74
+ readonly DETACHED_RUNTIME: "hooks.detached_runtime";
67
75
  };
68
76
  readonly WORKSPACE: {
69
77
  readonly INITIALIZED: "workspace.initialized";
@@ -96,6 +104,46 @@ export interface RunCommandsTimeoutTelemetryProperties {
96
104
  tool_call_id?: string;
97
105
  }
98
106
  export { captureAgentUnexpectedReasoningTokens, captureTaskLifecycleEvent, type CaptureAgentUnexpectedReasoningTokensInput, type CaptureTaskLifecycleEventInput, };
107
+ export interface GitSnapshotProperties {
108
+ schema_version: 1;
109
+ /** Actual Core session ID; ulid duplicates it for existing export consumers. */
110
+ sessionId: string;
111
+ ulid: string;
112
+ providerId: string;
113
+ workspace_id: string;
114
+ /** VS Code workspace-folder count at observation start, not Git repo count; 0 with no folders, even outside Git. */
115
+ workspace_root_count: number;
116
+ observation_window_id: string;
117
+ observation_sequence: number;
118
+ /** ISO observation-start time, after the model response. Git reads are not atomic. */
119
+ observed_at: string;
120
+ /** Background observation triggered by this response; tools may execute during the read. */
121
+ boundary: "model_call";
122
+ runId?: string;
123
+ iteration?: number;
124
+ agentId?: string;
125
+ /** Surfaced response's backend ID, when available; never synthesized or inherited from an earlier request. */
126
+ request_id?: string;
127
+ request_id_status: "present" | "missing";
128
+ git: {
129
+ /** partial: status hit its timeout/output cap but separate reads recovered HEAD and/or branch. */
130
+ state: "ok" | "unborn" | "non_git" | "unavailable" | "partial";
131
+ head_sha?: string;
132
+ branch?: string;
133
+ /** Any staged/unstaged/untracked changes. All four flags are absent for partial/non_git/unavailable, not false. */
134
+ dirty?: boolean;
135
+ /** Index changes, including unmerged entries; does not imply commit readiness. */
136
+ staged?: boolean;
137
+ /** Worktree changes, including unmerged entries. */
138
+ unstaged?: boolean;
139
+ /** Non-ignored untracked files. */
140
+ untracked?: boolean;
141
+ remote_url?: string;
142
+ remote_state?: "ok" | "none" | "unsupported" | "unavailable";
143
+ };
144
+ }
145
+ /** Ordinary telemetry: use a consent-aware service, never captureRequired. */
146
+ export declare function captureGitSnapshot(telemetry: ITelemetryService | undefined, properties: GitSnapshotProperties): void;
99
147
  export interface WorkspaceInitializedProperties {
100
148
  root_count: number;
101
149
  vcs_types: ReadonlyArray<string>;
@@ -181,15 +229,23 @@ export declare function identifyAccount(telemetry: ITelemetryService | undefined
181
229
  organizationName?: string;
182
230
  memberId?: string;
183
231
  }): void;
232
+ /**
233
+ * Restore anonymous process identity after an account signs out.
234
+ *
235
+ * Account properties are explicitly set to undefined so they replace values
236
+ * previously merged into a long-lived telemetry service. Implementations
237
+ * remove undefined attributes before export.
238
+ */
239
+ export declare function clearAccountTelemetryIdentity(telemetry: ITelemetryService | undefined, anonymousDistinctId?: string): void;
184
240
  export declare function captureTaskCreated(telemetry: ITelemetryService | undefined, properties: {
185
241
  ulid: string;
186
- apiProvider?: string;
187
- openAiCompatibleDomain?: string;
242
+ provider?: string;
243
+ model?: string;
188
244
  } & Partial<TelemetryAgentIdentityProperties>): void;
189
245
  export declare function captureTaskRestarted(telemetry: ITelemetryService | undefined, properties: {
190
246
  ulid: string;
191
- apiProvider?: string;
192
- openAiCompatibleDomain?: string;
247
+ provider?: string;
248
+ model?: string;
193
249
  } & Partial<TelemetryAgentIdentityProperties>): void;
194
250
  /**
195
251
  * Distinguishes the trigger that produced a `task.completed` telemetry event.
@@ -206,7 +262,7 @@ export type TaskCompletedSource = "submit_and_exit" | "shutdown";
206
262
  export declare function captureTaskCompleted(telemetry: ITelemetryService | undefined, properties: {
207
263
  ulid: string;
208
264
  provider?: string;
209
- modelId?: string;
265
+ model?: string;
210
266
  mode?: string;
211
267
  durationMs?: number;
212
268
  source?: TaskCompletedSource;
@@ -222,11 +278,14 @@ export declare function captureTokenUsage(telemetry: ITelemetryService | undefin
222
278
  ulid: string;
223
279
  /** Uncached input tokens only — disjoint from the cache buckets. */
224
280
  tokensIn: number;
281
+ /** Non-reasoning output tokens only — reasoningTokenCount is disjoint from this. */
225
282
  tokensOut: number;
226
283
  cacheWriteTokens?: number;
227
284
  cacheReadTokens?: number;
228
285
  /** This request's cost delta, not a running total. */
229
286
  totalCost?: number;
287
+ /** Reasoning/thinking tokens for this request, reported separately since they're no longer folded into tokensOut. */
288
+ reasoningTokenCount?: number;
230
289
  provider?: string;
231
290
  model: string;
232
291
  } & Partial<TelemetryAgentIdentityProperties>): void;
@@ -316,6 +375,20 @@ export declare function captureSubagentExecution(telemetry: ITelemetryService |
316
375
  errorMessage?: string;
317
376
  type?: "agent" | "team";
318
377
  } & Partial<TelemetryAgentIdentityProperties>): void;
378
+ /**
379
+ * Records how long a fire-and-forget hook ran. Detached hooks are never
380
+ * awaited, so their runtime is otherwise invisible — this is the evidence for
381
+ * whether any of them could safely be made blocking. `exited: false` marks a
382
+ * censored observation: the hook was still running when the observation
383
+ * window closed, so treat `durationMs` as a lower bound and count these
384
+ * separately rather than averaging them in.
385
+ */
386
+ export declare function captureDetachedHookRuntime(telemetry: ITelemetryService | undefined, event: {
387
+ hookName: string;
388
+ durationMs: number;
389
+ exitCode: number | null;
390
+ exited: boolean;
391
+ }): void;
319
392
  export declare function captureHookDiscovery(telemetry: ITelemetryService | undefined, hookName: string, globalCount: number, workspaceCount: number): void;
320
393
  /**
321
394
  * Identifies which compaction implementation produced a
@@ -394,3 +467,22 @@ export interface CaptureCompactionBudgetEmergencyProperties {
394
467
  modelId?: string;
395
468
  }
396
469
  export declare function captureCompactionBudgetEmergency(telemetry: ITelemetryService | undefined, properties: CaptureCompactionBudgetEmergencyProperties & Partial<TelemetryAgentIdentityProperties>): void;
470
+ /** A terminal failure was recorded as a display-only transcript entry. */
471
+ export declare function captureSessionErrorRecorded(telemetry: ITelemetryService | undefined, details: {
472
+ sessionId?: string;
473
+ provider: string;
474
+ model: string;
475
+ source: "result" | "thrown";
476
+ }): void;
477
+ /** Bounded scheduler diagnostics; never include prompts, paths, or raw errors. */
478
+ export declare function captureScheduleRun(telemetry: ITelemetryService | undefined, input: {
479
+ triggerKind: "one_off" | "schedule" | "event" | "manual" | "retry";
480
+ attemptCount: number;
481
+ startDelayMs: number;
482
+ } & ({
483
+ phase: "started";
484
+ } | {
485
+ phase: "finished";
486
+ outcome: "success" | "failed" | "timeout" | "superseded" | "cancelled";
487
+ durationMs: number;
488
+ })): void;
@@ -2,3 +2,4 @@ export { resolveCoreDeviceId, resolveCoreDistinctId } from "./distinct-id";
2
2
  export type { ITelemetryAdapter, TelemetryArray, TelemetryMetadata, TelemetryObject, TelemetryPrimitive, TelemetryProperties, TelemetryValue, } from "./ITelemetryAdapter";
3
3
  export { OpenTelemetryAdapter, type OpenTelemetryAdapterOptions, } from "./OpenTelemetryAdapter";
4
4
  export { type ConfiguredTelemetryHandle, type CreateOpenTelemetryTelemetryServiceOptions, createConfiguredTelemetryHandle, createConfiguredTelemetryService, createOpenTelemetryTelemetryService, OpenTelemetryProvider, type OpenTelemetryProviderOptions, } from "./OpenTelemetryProvider";
5
+ export { type ClientTelemetryContext, createClientScopedTelemetryService, createScopedTelemetryService, resolveClientTelemetryProperties, } from "./scoped-telemetry";
@@ -1 +1 @@
1
- import{existsSync as N,mkdirSync as G,readFileSync as v,writeFileSync as u}from"node:fs";import{resolve as b}from"node:path";import{resolveSessionDataDir as S}from"@cerebriline/shared/storage";import{nanoid as g}from"nanoid";import*as c from"node-machine-id";var m="machine-id",C,w=!1;function B(){if(!w)C=h(),w=!0;return C??q()}function X(f){let P=f?.trim();if(P)return P;let A=h();if(A)return A;return q()}function d(){let f=c;return f.machineIdSync??f.default?.machineIdSync}function h(){try{let f=d();if(!f)return;return f().trim()||void 0}catch{return}}function q(){let f=S(),P=b(f,m);try{if(N(P)){let O=v(P,"utf8").trim();if(O.length>0)return O}}catch{}let A=`cl-${g()}`;try{G(f,{recursive:!0}),u(P,A,"utf8")}catch{}return A}class Y{name;metadata;meter;logger;enabled;distinctId;commonProperties;counters=new Map;histograms=new Map;gauges=new Map;gaugeValues=new Map;meterProvider;loggerProvider;constructor(f){this.name=f.name??"OpenTelemetryAdapter",this.metadata={...f.metadata},this.meterProvider=f.meterProvider,this.loggerProvider=f.loggerProvider,this.meter=f.meterProvider?.getMeter("cline")??null,this.logger=f.loggerProvider?.getLogger("cline")??null,this.enabled=f.enabled??!0,this.distinctId=f.distinctId,this.commonProperties=f.commonProperties?{...f.commonProperties}:{}}emit(f,P){if(!this.isEnabled())return;this.emitLog(f,P,!1)}emitRequired(f,P){this.emitLog(f,P,!0)}recordCounter(f,P,A,O,j=!1){if(!this.meter||!j&&!this.isEnabled())return;let H=this.counters.get(f);if(!H)H=this.meter.createCounter(f,O?{description:O}:void 0),this.counters.set(f,H);H.add(P,this.flattenProperties(this.buildAttributes(A)))}recordHistogram(f,P,A,O,j=!1){if(!this.meter||!j&&!this.isEnabled())return;let H=this.histograms.get(f);if(!H)H=this.meter.createHistogram(f,O?{description:O}:void 0),this.histograms.set(f,H);H.record(P,this.flattenProperties(this.buildAttributes(A)))}recordGauge(f,P,A,O,j=!1){if(!this.meter||!j&&!this.isEnabled())return;let H=this.buildAttributes(A),J=JSON.stringify(H),K=this.gaugeValues.get(f);if(P===null){if(K){if(K.delete(J),K.size===0)this.gaugeValues.delete(f),this.gauges.delete(f)}return}let T=K;if(!T)T=new Map,this.gaugeValues.set(f,T);if(!this.gauges.has(f)){let W=this.meter.createObservableGauge(f,O?{description:O}:void 0);W.addCallback((R)=>{for(let M of this.snapshotGaugeSeries(f))R.observe(M.value,this.flattenProperties(M.attributes))}),this.gauges.set(f,W)}T.set(J,{value:P,attributes:H})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}setDistinctId(f){this.distinctId=f}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}async flush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.()])}emitLog(f,P,A){if(!this.logger)return;let O=this.flattenProperties(this.buildAttributes(P,A));this.logger.emit({severityText:"INFO",body:f,attributes:O})}buildAttributes(f,P=!1){return{...this.commonProperties,...this.metadata,...f,...this.distinctId?{distinct_id:this.distinctId}:{},...P?{_required:!0}:{}}}snapshotGaugeSeries(f){let P=this.gaugeValues.get(f);if(!P)return[];return Array.from(P.values(),(A)=>({value:A.value,attributes:A.attributes?{...A.attributes}:void 0}))}flattenProperties(f,P="",A=new WeakSet,O=0){if(!f)return{};let j={},H=100,J=10;for(let[K,T]of Object.entries(f)){if(K==="__proto__"||K==="constructor"||K==="prototype")continue;let W=P?`${P}.${K}`:K;if(T===null||T===void 0){j[W]=String(T);continue}if(Array.isArray(T)){let R=T.length>H?T.slice(0,H):T;try{j[W]=JSON.stringify(R)}catch{j[W]="[UnserializableArray]"}if(T.length>H)j[`${W}_truncated`]=!0,j[`${W}_original_length`]=T.length;continue}if(typeof T==="object"){if(T instanceof Date){j[W]=T.toISOString();continue}if(T instanceof Error){j[W]=T.message;continue}if(A.has(T)){j[W]="[Circular]";continue}if(O>=J){j[W]="[MaxDepthExceeded]";continue}A.add(T),Object.assign(j,this.flattenProperties(T,W,A,O+1));continue}if(r(T)){j[W]=T;continue}try{j[W]=JSON.stringify(T)}catch{j[W]=String(T)}}return j}}function r(f){return typeof f==="string"||typeof f==="number"||typeof f==="boolean"}import{metrics as Of,trace as jf}from"@opentelemetry/api";import{logs as Hf}from"@opentelemetry/api-logs";import{OTLPLogExporter as Tf}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPMetricExporter as $f}from"@opentelemetry/exporter-metrics-otlp-http";import{OTLPTraceExporter as Jf}from"@opentelemetry/exporter-trace-otlp-http";import{resourceFromAttributes as Wf}from"@opentelemetry/resources";import{BatchLogRecordProcessor as Kf,ConsoleLogRecordExporter as Xf,LoggerProvider as Yf}from"@opentelemetry/sdk-logs";import{ConsoleMetricExporter as Zf,MeterProvider as Qf,PeriodicExportingMetricReader as y}from"@opentelemetry/sdk-metrics";import{BatchSpanProcessor as Rf,ConsoleSpanExporter as Bf,SimpleSpanProcessor as Ff}from"@opentelemetry/sdk-trace-base";import{NodeTracerProvider as Vf}from"@opentelemetry/sdk-trace-node";import{ATTR_SERVICE_NAME as Uf,ATTR_SERVICE_VERSION as _f}from"@opentelemetry/semantic-conventions";import{mkdirSync as rf,readFileSync as l,statSync as n,writeFileSync as lf}from"node:fs";import{CONFIGURABLE_MODEL_TOOL_NAMES as p}from"@cerebriline/shared";import{resolveGlobalSettingsPath as a}from"@cerebriline/shared/storage";import{z as $}from"zod";import{AGENT_UNEXPECTED_REASONING_TOKENS_EVENT as zf,captureAgentUnexpectedReasoningTokens as xf,captureTaskLifecycleEvent as Nf,SDK_ERROR_TELEMETRY_EVENT as Gf,TASK_CANCELLED_EVENT as vf,TASK_FIRST_CHUNK_RECEIVED_EVENT as uf,TASK_PROVIDER_REQUEST_STARTED_EVENT as bf,TASK_PROVIDER_STREAM_FAILED_EVENT as Sf,TASK_PROVIDER_STREAM_STARTED_EVENT as gf}from"@cerebriline/shared";var F=$.preprocess((f)=>Array.isArray(f)?f.filter((P)=>typeof P==="string").map((P)=>P.trim()).filter(Boolean):void 0,$.array($.string()).optional()).transform((f)=>{if(!f)return;let P=[...new Set(f)].sort((A,O)=>A.localeCompare(O));return P.length>0?P:void 0}),i=$.enum(["basic","agentic"]).catch("agentic"),s=$.partialRecord($.enum(p),$.object({enabled:$.boolean()}).strip()).optional(),o=$.record($.string(),$.object({enabled:$.boolean()}).strip()).optional().catch(void 0),t=$.enum(["plan","act"]),E=$.object({telemetryOptOut:$.boolean().default(!1).catch(!1),autoUpdateEnabled:$.boolean().default(!0).catch(!0),compactionStrategy:i.optional(),compactionEnabled:$.boolean().optional().catch(void 0),planActMode:t.optional().catch(void 0),toolAutoApprove:$.boolean().optional().catch(void 0),tuiTheme:$.string().optional().catch(void 0),disabledTools:F.optional(),tools:s,disabledPlugins:F.optional(),disabledAgentPlugins:F.optional(),bundledSkills:o}).strip().transform((f)=>{let P={autoUpdateEnabled:f.autoUpdateEnabled,telemetryOptOut:f.telemetryOptOut};if(f.compactionStrategy)P.compactionStrategy=f.compactionStrategy;if(f.compactionEnabled!==void 0)P.compactionEnabled=f.compactionEnabled;if(f.planActMode)P.planActMode=f.planActMode;if(f.toolAutoApprove!==void 0)P.toolAutoApprove=f.toolAutoApprove;if(f.tuiTheme?.trim())P.tuiTheme=f.tuiTheme.trim();if(f.disabledTools?.length)P.disabledTools=f.disabledTools;if(f.tools&&Object.keys(f.tools).length>0)P.tools=f.tools;if(f.disabledPlugins?.length)P.disabledPlugins=f.disabledPlugins;if(f.disabledAgentPlugins?.length)P.disabledAgentPlugins=f.disabledAgentPlugins;if(f.bundledSkills&&Object.keys(f.bundledSkills).length>0)P.bundledSkills=f.bundledSkills;return P});function Z(){return E.parse({})}var V;function e(f){if(f.disabledTools)Object.freeze(f.disabledTools);if(f.tools){for(let P of Object.values(f.tools))Object.freeze(P);Object.freeze(f.tools)}if(f.disabledPlugins)Object.freeze(f.disabledPlugins);if(f.disabledAgentPlugins)Object.freeze(f.disabledAgentPlugins);return Object.freeze(f)}function ff(f){let P;try{P=l(f,"utf8")}catch{return Z()}try{let A=E.safeParse(JSON.parse(P));return A.success?A.data:Z()}catch{return Z()}}function Pf(){let f=a(),P=n(f,{throwIfNoEntry:!1}),A=P?.mtimeMs??0,O=P?.size??0,j=V;if(j&&j.path===f&&j.mtimeMs===A&&j.size===O)return j;let H=e(P?ff(f):Z());return V={path:f,mtimeMs:A,size:O,value:H},V}function Af(){return Pf().value}function I(){return Af().telemetryOptOut}class U{name;logger;enabled;constructor(f={}){this.name=f.name??"TelemetryLoggerSink",this.logger=f.logger,this.enabled=f.enabled??!0}emit(f,P){if(!this.isEnabled())return;this.logger?.log("telemetry.event",{telemetrySink:this.name,event:f,properties:P})}emitRequired(f,P){this.logger?.log("telemetry.required_event",{telemetrySink:this.name,severity:"warn",event:f,properties:P})}recordCounter(f,P,A,O,j){if(!j&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"counter",name:f,value:P,attributes:A,description:O,required:j===!0})}recordHistogram(f,P,A,O,j){if(!j&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"histogram",name:f,value:P,attributes:A,description:O,required:j===!0})}recordGauge(f,P,A,O,j){if(!j&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"gauge",name:f,value:P,attributes:A,description:O,required:j===!0})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}async flush(){}async dispose(){}}class Q{adapters;metadata;distinctId;deviceId;commonProperties;constructor(f={}){if(this.adapters=[...f.adapters??[]],f.logger)this.adapters.push(new U({logger:f.logger}));this.metadata={...f.metadata??{}},this.distinctId=f.distinctId,this.deviceId=f.deviceId??B(),this.commonProperties={...f.commonProperties??{}}}addAdapter(f){this.adapters.push(f)}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return this.adapters.some((f)=>f.isEnabled())}capture(f){let P=this.buildAttributes(f.properties);for(let A of this.adapters)A.emit(f.event,P)}captureRequired(f,P){let A=this.buildAttributes(P);for(let O of this.adapters)O.emitRequired(f,A)}recordCounter(f,P,A,O,j=!1){let H=this.buildAttributes(A);for(let J of this.adapters)J.recordCounter(f,P,H,O,j)}recordHistogram(f,P,A,O,j=!1){let H=this.buildAttributes(A);for(let J of this.adapters)J.recordHistogram(f,P,H,O,j)}recordGauge(f,P,A,O,j=!1){let H=this.buildAttributes(A);for(let J of this.adapters)J.recordGauge(f,P,H,O,j)}async flush(){await Promise.all(this.adapters.map((f)=>f.flush()))}async dispose(){await Promise.all(this.adapters.map((f)=>f.dispose()))}buildAttributes(f){return{...this.commonProperties,...f,...this.metadata,...this.distinctId?{distinct_id:this.distinctId}:{},device_id:this.deviceId}}}class D{distinctId;metadata;commonProperties;constructor(f={}){this.distinctId=f.distinctId,this.metadata={...f.metadata??{}},this.commonProperties={...f.commonProperties??{}}}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return!1}capture(f){this.resolveProperties(f.properties)}captureRequired(f,P){this.resolveProperties(P)}recordCounter(){}recordHistogram(){}recordGauge(){}async flush(){}async dispose(){}resolveProperties(f){return{...this.commonProperties,...f,...this.metadata,...this.distinctId?{distinct_id:this.distinctId}:{}}}}class L{meterProvider;loggerProvider;tracerProvider;options;constructor(f={}){this.options=f;let P=Wf({[Uf]:f.serviceName??"cline",...f.serviceVersion?{[_f]:f.serviceVersion}:{}});if(this.meterProvider=this.createMeterProvider(P),this.loggerProvider=this.createLoggerProvider(P),this.tracerProvider=this.createTracerProvider(P),this.meterProvider)Of.setGlobalMeterProvider(this.meterProvider);if(this.loggerProvider)Hf.setGlobalLoggerProvider(this.loggerProvider);if(this.tracerProvider)this.tracerProvider.register()}getTracer(f="cline",P){return jf.getTracer(f,P??this.options.serviceVersion)}createAdapter(f){return new Y({...f,meterProvider:this.meterProvider,loggerProvider:this.loggerProvider})}createTelemetryService(f){let P=this.createAdapter({name:f.name,enabled:this.options.enabled,metadata:f.metadata});return new Q({...f,adapters:[P],distinctId:X(f.distinctId)})}async forceFlush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.(),this.tracerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.(),this.tracerProvider?.shutdown?.()])}createMeterProvider(f){let P=_(this.options.metricsExporter);if(P.length===0)return null;let A=Math.max(1000,this.options.metricExportIntervalMs??this.options.metricExportInterval??60000),O=Math.min(30000,Math.floor(A*0.8)),j=P.map((H)=>Cf(H,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json",interval:A,timeout:O})).filter((H)=>H!==null);if(j.length===0)return null;return new Qf({resource:f,readers:j})}createTracerProvider(f){let P=_(this.options.tracesExporter);if(P.length===0)return null;let A=this.options.otlpTracesEndpoint??this.options.otlpEndpoint,O=this.options.otlpTracesHeaders??this.options.otlpHeaders,j=[];for(let H of P){let J=Mf(H,{endpoint:A,headers:O,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(J)j.push(J)}if(j.length===0)return null;return new Vf({resource:f,spanProcessors:j})}createLoggerProvider(f){let P=_(this.options.logsExporter);if(P.length===0)return null;let A=P.map((O)=>{let j=kf(O,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(!j)return null;return new Kf(j,{maxQueueSize:this.options.logMaxQueueSize??2048,maxExportBatchSize:this.options.logBatchSize??512,scheduledDelayMillis:this.options.logBatchTimeoutMs??this.options.logBatchTimeout??5000})}).filter((O)=>O!==null);if(A.length===0)return null;return new Yf({resource:f,processors:A})}}function z(f){let P=new L(f),A=P.createTelemetryService(f),O=()=>{A.captureRequired("telemetry.provider_created",{provider:"opentelemetry",enabled:f.enabled??!0,logsExporter:Array.isArray(f.logsExporter)?f.logsExporter.join(","):f.logsExporter,metricsExporter:Array.isArray(f.metricsExporter)?f.metricsExporter.join(","):f.metricsExporter,tracesExporter:Array.isArray(f.tracesExporter)?f.tracesExporter.join(","):f.tracesExporter,otlpProtocol:f.otlpProtocol,hasOtlpEndpoint:Boolean(f.otlpEndpoint),serviceName:f.serviceName,serviceVersion:f.serviceVersion})};if(!f.deferProviderCreatedEvent)O();return{provider:P,telemetry:A,emitProviderCreated:O}}function x(f){if(I())return{telemetry:new D(f)};if(f.enabled!==!0)return{telemetry:new Q({...f,distinctId:X(f.distinctId)})};return z(f)}function Lf(f){let{telemetry:P,provider:A,emitProviderCreated:O}=x(f);return{telemetry:P,provider:A,flush:async()=>{let J=A;if(J&&typeof J.forceFlush==="function")try{await J.forceFlush()}catch{}},dispose:async()=>{await Promise.allSettled([P.dispose(),A?.dispose()])},...f.deferProviderCreatedEvent&&O?{emitProviderCreated:O}:{}}}function _(f){if(!f)return[];return(Array.isArray(f)?f:f.split(",")).map((A)=>A.trim()).filter((A)=>A==="console"||A==="otlp")}function kf(f,P){if(f==="console")return new Xf;if(!P.endpoint)return null;let A=k(P.endpoint,"/v1/logs");return new Tf({url:A,headers:P.headers})}function Mf(f,P){if(f==="console")return new Ff(new Bf);if(!P.endpoint)return null;let A=k(P.endpoint,"/v1/traces");return new Rf(new Jf({url:A,headers:P.headers}))}function Cf(f,P){if(f==="console")return new y({exporter:new Zf,exportIntervalMillis:P.interval,exportTimeoutMillis:P.timeout});if(!P.endpoint)return null;let A=k(P.endpoint,"/v1/metrics");return new y({exporter:new $f({url:A,headers:P.headers}),exportIntervalMillis:P.interval,exportTimeoutMillis:P.timeout})}function k(f,P){let A=new URL(f),O=A.pathname.endsWith("/")?A.pathname.slice(0,-1):A.pathname;return A.pathname=O.endsWith(P)?O:`${O}${P}`,A.toString()}export{X as resolveCoreDistinctId,B as resolveCoreDeviceId,z as createOpenTelemetryTelemetryService,x as createConfiguredTelemetryService,Lf as createConfiguredTelemetryHandle,L as OpenTelemetryProvider,Y as OpenTelemetryAdapter};
1
+ import{existsSync as g,mkdirSync as u,readFileSync as c,writeFileSync as m}from"node:fs";import{resolve as d}from"node:path";import{resolveSessionDataDir as l}from"@cerebriline/shared/storage";import{nanoid as p}from"nanoid";import*as r from"node-machine-id";var a="machine-id",q,h=!1;function R(){if(!h)q=E(),h=!0;return q??z()}function Y(f){let j=f?.trim();if(j)return j;let $=E();if($)return $;return z()}function n(){let f=r;return f.machineIdSync??f.default?.machineIdSync}function E(){try{let f=n();if(!f)return;return f().trim()||void 0}catch{return}}function z(){let f=l(),j=d(f,a);try{if(g(j)){let A=c(j,"utf8").trim();if(A.length>0)return A}}catch{}let $=`cl-${p()}`;try{u(f,{recursive:!0}),m(j,$,"utf8")}catch{}return $}class B{name;metadata;meter;logger;enabled;distinctId;commonProperties;counters=new Map;histograms=new Map;gauges=new Map;gaugeValues=new Map;meterProvider;loggerProvider;constructor(f){this.name=f.name??"OpenTelemetryAdapter",this.metadata={...f.metadata},this.meterProvider=f.meterProvider,this.loggerProvider=f.loggerProvider,this.meter=f.meterProvider?.getMeter("cline")??null,this.logger=f.loggerProvider?.getLogger("cline")??null,this.enabled=f.enabled??!0,this.distinctId=f.distinctId,this.commonProperties=f.commonProperties?{...f.commonProperties}:{}}emit(f,j){if(!this.isEnabled())return;this.emitLog(f,j,!1)}emitRequired(f,j){this.emitLog(f,j,!0)}recordCounter(f,j,$,A,J=!1){if(!this.meter||!J&&!this.isEnabled())return;let W=this.counters.get(f);if(!W)W=this.meter.createCounter(f,A?{description:A}:void 0),this.counters.set(f,W);W.add(j,this.flattenProperties(this.buildAttributes($)))}recordHistogram(f,j,$,A,J=!1){if(!this.meter||!J&&!this.isEnabled())return;let W=this.histograms.get(f);if(!W)W=this.meter.createHistogram(f,A?{description:A}:void 0),this.histograms.set(f,W);W.record(j,this.flattenProperties(this.buildAttributes($)))}recordGauge(f,j,$,A,J=!1){if(!this.meter||!J&&!this.isEnabled())return;let W=this.buildAttributes($),H=JSON.stringify(W),X=this.gaugeValues.get(f);if(j===null){if(X){if(X.delete(H),X.size===0)this.gaugeValues.delete(f),this.gauges.delete(f)}return}let O=X;if(!O)O=new Map,this.gaugeValues.set(f,O);if(!this.gauges.has(f)){let Z=this.meter.createObservableGauge(f,A?{description:A}:void 0);Z.addCallback((Q)=>{for(let w of this.snapshotGaugeSeries(f))Q.observe(w.value,this.flattenProperties(w.attributes))}),this.gauges.set(f,Z)}O.set(H,{value:j,attributes:W})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}setDistinctId(f){this.distinctId=f}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}async flush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.()])}emitLog(f,j,$){if(!this.logger)return;let A=this.flattenProperties(this.buildAttributes(j,$));this.logger.emit({severityText:"INFO",body:f,attributes:A})}buildAttributes(f,j=!1){return{...this.commonProperties,...this.metadata,...f,...this.distinctId?{distinct_id:this.distinctId}:{},...j?{_required:!0}:{}}}snapshotGaugeSeries(f){let j=this.gaugeValues.get(f);if(!j)return[];return Array.from(j.values(),($)=>({value:$.value,attributes:$.attributes?{...$.attributes}:void 0}))}flattenProperties(f,j="",$=new WeakSet,A=0){if(!f)return{};let J={},W=100,H=10;for(let[X,O]of Object.entries(f)){if(X==="__proto__"||X==="constructor"||X==="prototype")continue;let Z=j?`${j}.${X}`:X;if(O===null||O===void 0){J[Z]=String(O);continue}if(Array.isArray(O)){let Q=O.length>W?O.slice(0,W):O;try{J[Z]=JSON.stringify(Q)}catch{J[Z]="[UnserializableArray]"}if(O.length>W)J[`${Z}_truncated`]=!0,J[`${Z}_original_length`]=O.length;continue}if(typeof O==="object"){if(O instanceof Date){J[Z]=O.toISOString();continue}if(O instanceof Error){J[Z]=O.message;continue}if($.has(O)){J[Z]="[Circular]";continue}if(A>=H){J[Z]="[MaxDepthExceeded]";continue}$.add(O),Object.assign(J,this.flattenProperties(O,Z,$,A+1));continue}if(s(O)){J[Z]=O;continue}try{J[Z]=JSON.stringify(O)}catch{J[Z]=String(O)}}return J}}function s(f){return typeof f==="string"||typeof f==="number"||typeof f==="boolean"}import{LangfuseAttributesSpanProcessor as Xf}from"@cerebriline/llms";import{markOtlpTraceRelayProvider as Zf}from"@cerebriline/shared";import{metrics as Kf,trace as Pf}from"@opentelemetry/api";import{logs as Qf}from"@opentelemetry/api-logs";import{OTLPLogExporter as Tf}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPMetricExporter as Yf}from"@opentelemetry/exporter-metrics-otlp-http";import{OTLPTraceExporter as Bf}from"@opentelemetry/exporter-trace-otlp-http";import{resourceFromAttributes as Ff}from"@opentelemetry/resources";import{BatchLogRecordProcessor as Vf,ConsoleLogRecordExporter as Rf,LoggerProvider as Uf}from"@opentelemetry/sdk-logs";import{ConsoleMetricExporter as Lf,MeterProvider as kf,PeriodicExportingMetricReader as G}from"@opentelemetry/sdk-metrics";import{BatchSpanProcessor as Cf,ConsoleSpanExporter as _f,SimpleSpanProcessor as Mf}from"@opentelemetry/sdk-trace-base";import{NodeTracerProvider as wf}from"@opentelemetry/sdk-trace-node";import{ATTR_SERVICE_NAME as qf,ATTR_SERVICE_VERSION as hf}from"@opentelemetry/semantic-conventions";import{mkdirSync as f0,readFileSync as i,statSync as o,writeFileSync as j0}from"node:fs";import{CONFIGURABLE_MODEL_TOOL_NAMES as t}from"@cerebriline/shared";import{resolveGlobalSettingsPath as e}from"@cerebriline/shared/storage";import{z as K}from"zod";import{AGENT_UNEXPECTED_REASONING_TOKENS_EVENT as uf,captureAgentUnexpectedReasoningTokens as cf,captureTaskLifecycleEvent as mf,SDK_ERROR_TELEMETRY_EVENT as df,TASK_CANCELLED_EVENT as lf,TASK_FIRST_CHUNK_RECEIVED_EVENT as pf,TASK_MAX_TOKENS_RECOVERY_EVENT as rf,TASK_PROVIDER_REQUEST_STARTED_EVENT as af,TASK_PROVIDER_STREAM_FAILED_EVENT as nf,TASK_PROVIDER_STREAM_STARTED_EVENT as sf}from"@cerebriline/shared";var U=K.preprocess((f)=>Array.isArray(f)?f.filter((j)=>typeof j==="string").map((j)=>j.trim()).filter(Boolean):void 0,K.array(K.string()).optional()).transform((f)=>{if(!f)return;let j=[...new Set(f)].sort(($,A)=>$.localeCompare(A));return j.length>0?j:void 0}),ff=K.enum(["basic","agentic"]).catch("agentic"),jf=K.partialRecord(K.enum(t),K.object({enabled:K.boolean()}).strip()).optional(),$f=K.record(K.string(),K.object({enabled:K.boolean()}).strip()).optional().catch(void 0),Af=K.enum(["plan","act"]),D=K.object({telemetryOptOut:K.boolean().default(!1).catch(!1),autoUpdateEnabled:K.boolean().default(!0).catch(!0),compactionStrategy:ff.optional(),compactionEnabled:K.boolean().optional().catch(void 0),planActMode:Af.optional().catch(void 0),toolAutoApprove:K.boolean().optional().catch(void 0),tuiTheme:K.string().optional().catch(void 0),disabledTools:U.optional(),tools:jf,disabledPlugins:U.optional(),disabledAgentPlugins:U.optional(),bundledSkills:$f}).strip().transform((f)=>{let j={autoUpdateEnabled:f.autoUpdateEnabled,telemetryOptOut:f.telemetryOptOut};if(f.compactionStrategy)j.compactionStrategy=f.compactionStrategy;if(f.compactionEnabled!==void 0)j.compactionEnabled=f.compactionEnabled;if(f.planActMode)j.planActMode=f.planActMode;if(f.toolAutoApprove!==void 0)j.toolAutoApprove=f.toolAutoApprove;if(f.tuiTheme?.trim())j.tuiTheme=f.tuiTheme.trim();if(f.disabledTools?.length)j.disabledTools=f.disabledTools;if(f.tools&&Object.keys(f.tools).length>0)j.tools=f.tools;if(f.disabledPlugins?.length)j.disabledPlugins=f.disabledPlugins;if(f.disabledAgentPlugins?.length)j.disabledAgentPlugins=f.disabledAgentPlugins;if(f.bundledSkills&&Object.keys(f.bundledSkills).length>0)j.bundledSkills=f.bundledSkills;return j});function F(){return D.parse({})}var L;function Jf(f){if(f.disabledTools)Object.freeze(f.disabledTools);if(f.tools){for(let j of Object.values(f.tools))Object.freeze(j);Object.freeze(f.tools)}if(f.disabledPlugins)Object.freeze(f.disabledPlugins);if(f.disabledAgentPlugins)Object.freeze(f.disabledAgentPlugins);return Object.freeze(f)}function Hf(f){let j;try{j=i(f,"utf8")}catch{return{value:F(),loadFailed:!0}}try{let $=D.safeParse(JSON.parse(j));return $.success?{value:$.data,loadFailed:!1}:{value:F(),loadFailed:!0}}catch{return{value:F(),loadFailed:!0}}}function Wf(){let f=e(),j=o(f,{throwIfNoEntry:!1}),$=j?.mtimeMs??0,A=j?.size??0,J=L;if(J&&J.path===f&&J.mtimeMs===$&&J.size===A)return J;let W=j?Hf(f):{value:F(),loadFailed:!1},H=Jf(W.value);return L={path:f,mtimeMs:$,size:A,value:H,loadFailed:W.loadFailed},L}function Of(){return Wf().value}function I(){return Of().telemetryOptOut}class k{name;logger;enabled;constructor(f={}){this.name=f.name??"TelemetryLoggerSink",this.logger=f.logger,this.enabled=f.enabled??!0}emit(f,j){if(!this.isEnabled())return;this.logger?.log("telemetry.event",{telemetrySink:this.name,event:f,properties:j})}emitRequired(f,j){this.logger?.log("telemetry.required_event",{telemetrySink:this.name,severity:"warn",event:f,properties:j})}recordCounter(f,j,$,A,J){if(!J&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"counter",name:f,value:j,attributes:$,description:A,required:J===!0})}recordHistogram(f,j,$,A,J){if(!J&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"histogram",name:f,value:j,attributes:$,description:A,required:J===!0})}recordGauge(f,j,$,A,J){if(!J&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"gauge",name:f,value:j,attributes:$,description:A,required:J===!0})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}async flush(){}async dispose(){}}class V{adapters;metadata;distinctId;deviceId;commonProperties;constructor(f={}){if(this.adapters=[...f.adapters??[]],f.logger)this.adapters.push(new k({logger:f.logger}));this.metadata={...f.metadata??{}},this.distinctId=f.distinctId,this.deviceId=f.deviceId??R(),this.commonProperties={...f.commonProperties??{}}}addAdapter(f){this.adapters.push(f)}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return this.adapters.some((f)=>f.isEnabled())}capture(f){let j=this.buildAttributes(f.properties);for(let $ of this.adapters)$.emit(f.event,j)}captureRequired(f,j){let $=this.buildAttributes(j);for(let A of this.adapters)A.emitRequired(f,$)}recordCounter(f,j,$,A,J=!1){let W=this.buildAttributes($);for(let H of this.adapters)H.recordCounter(f,j,W,A,J)}recordHistogram(f,j,$,A,J=!1){let W=this.buildAttributes($);for(let H of this.adapters)H.recordHistogram(f,j,W,A,J)}recordGauge(f,j,$,A,J=!1){let W=this.buildAttributes($);for(let H of this.adapters)H.recordGauge(f,j,W,A,J)}async flush(){await Promise.all(this.adapters.map((f)=>f.flush()))}async dispose(){await Promise.all(this.adapters.map((f)=>f.dispose()))}buildAttributes(f){let j=typeof f?.distinct_id==="string"&&f.distinct_id.trim()?f.distinct_id.trim():this.distinctId,$={...this.commonProperties,...this.metadata,...f,...j?{distinct_id:j}:{},device_id:this.deviceId};return Object.fromEntries(Object.entries($).filter(([,A])=>A!==void 0))}}class x{distinctId;metadata;commonProperties;constructor(f={}){this.distinctId=f.distinctId,this.metadata={...f.metadata??{}},this.commonProperties={...f.commonProperties??{}}}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return!1}capture(f){this.resolveProperties(f.properties)}captureRequired(f,j){this.resolveProperties(j)}recordCounter(){}recordHistogram(){}recordGauge(){}async flush(){}async dispose(){}resolveProperties(f){let j=typeof f?.distinct_id==="string"&&f.distinct_id.trim()?f.distinct_id.trim():this.distinctId,$={...this.commonProperties,...this.metadata,...f,...j?{distinct_id:j}:{}};return Object.fromEntries(Object.entries($).filter(([,A])=>A!==void 0))}}class _{meterProvider;loggerProvider;tracerProvider;options;constructor(f={}){this.options=f;let j=Ff({[qf]:f.serviceName??"cline",...f.serviceVersion?{[hf]:f.serviceVersion}:{}});if(this.meterProvider=this.createMeterProvider(j),this.loggerProvider=this.createLoggerProvider(j),this.tracerProvider=this.createTracerProvider(j),this.meterProvider)Kf.setGlobalMeterProvider(this.meterProvider);if(this.loggerProvider)Qf.setGlobalLoggerProvider(this.loggerProvider);if(this.tracerProvider)this.tracerProvider.register()}getTracer(f="cline",j){return Pf.getTracer(f,j??this.options.serviceVersion)}createAdapter(f){return new B({...f,meterProvider:this.meterProvider,loggerProvider:this.loggerProvider})}createTelemetryService(f){let j=this.createAdapter({name:f.name,enabled:this.options.enabled,metadata:f.metadata});return new V({...f,adapters:[j],distinctId:Y(f.distinctId)})}async forceFlush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.(),this.tracerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.(),this.tracerProvider?.shutdown?.()])}createMeterProvider(f){let j=C(this.options.metricsExporter);if(j.length===0)return null;let $=Math.max(1000,this.options.metricExportIntervalMs??this.options.metricExportInterval??60000),A=Math.min(30000,Math.floor($*0.8)),J=j.map((W)=>If(W,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json",interval:$,timeout:A})).filter((W)=>W!==null);if(J.length===0)return null;return new kf({resource:f,readers:J})}createTracerProvider(f){let j=C(this.options.tracesExporter);if(j.length===0)return null;let $=this.options.otlpTracesEndpoint??this.options.otlpEndpoint,A=this.options.otlpTracesHeaders??this.options.otlpHeaders,J=[],W=!1;for(let X of j){let O=Df(X,{endpoint:$,headers:A,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(O){if(J.push(O),X!=="console")W=!0}}if(J.length===0)return null;let H=new wf({resource:f,spanProcessors:W?[new Xf,...J]:J});if(W)Zf(H);return H}createLoggerProvider(f){let j=C(this.options.logsExporter);if(j.length===0)return null;let $=j.map((A)=>{let J=zf(A,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(!J)return null;return new Vf(J,{maxQueueSize:this.options.logMaxQueueSize??2048,maxExportBatchSize:this.options.logBatchSize??512,scheduledDelayMillis:this.options.logBatchTimeoutMs??this.options.logBatchTimeout??5000})}).filter((A)=>A!==null);if($.length===0)return null;return new Uf({resource:f,processors:$})}}function N(f){let j=new _(f),$=j.createTelemetryService(f),A=()=>{$.captureRequired("telemetry.provider_created",{provider:"opentelemetry",enabled:f.enabled??!0,logsExporter:Array.isArray(f.logsExporter)?f.logsExporter.join(","):f.logsExporter,metricsExporter:Array.isArray(f.metricsExporter)?f.metricsExporter.join(","):f.metricsExporter,tracesExporter:Array.isArray(f.tracesExporter)?f.tracesExporter.join(","):f.tracesExporter,otlpProtocol:f.otlpProtocol,hasOtlpEndpoint:Boolean(f.otlpEndpoint),serviceName:f.serviceName,serviceVersion:f.serviceVersion})};if(!f.deferProviderCreatedEvent)A();return{provider:j,telemetry:$,emitProviderCreated:A}}function y(f){if(I())return{telemetry:new x(f)};if(f.enabled!==!0)return{telemetry:new V({...f,distinctId:Y(f.distinctId)})};return N(f)}function Ef(f){let{telemetry:j,provider:$,emitProviderCreated:A}=y(f);return{telemetry:j,provider:$,flush:async()=>{let H=$;if(H&&typeof H.forceFlush==="function")try{await H.forceFlush()}catch{}},dispose:async()=>{await Promise.allSettled([j.dispose(),$?.dispose()])},...f.deferProviderCreatedEvent&&A?{emitProviderCreated:A}:{}}}function C(f){if(!f)return[];return(Array.isArray(f)?f:f.split(",")).map(($)=>$.trim()).filter(($)=>$==="console"||$==="otlp")}function zf(f,j){if(f==="console")return new Rf;if(!j.endpoint)return null;let $=M(j.endpoint,"/v1/logs");return new Tf({url:$,headers:j.headers})}function Df(f,j){if(f==="console")return new Mf(new _f);if(!j.endpoint)return null;let $=M(j.endpoint,"/v1/traces");return new Cf(new Bf({url:$,headers:j.headers}))}function If(f,j){if(f==="console")return new G({exporter:new Lf,exportIntervalMillis:j.interval,exportTimeoutMillis:j.timeout});if(!j.endpoint)return null;let $=M(j.endpoint,"/v1/metrics");return new G({exporter:new Yf({url:$,headers:j.headers}),exportIntervalMillis:j.interval,exportTimeoutMillis:j.timeout})}function M(f,j){let $=new URL(f),A=$.pathname.endsWith("/")?$.pathname.slice(0,-1):$.pathname;return $.pathname=A.endsWith(j)?A:`${A}${j}`,$.toString()}import{SESSION_STATUS_VALUES as D0}from"@cerebriline/shared";var T={CORE:"core",CLI:"cli",SUBAGENT:"subagent",DESKTOP:"desktop",KANBAN:"kanban",API:"api",WEB:"web",VSCODE:"vscode",ENTERPRISE:"enterprise",IDE:"ide",JETBRAINS:"jetbrains",NEOVIM:"neovim",UNKNOWN:"unknown"};function b(f){let j=[f?.name,f?.platform].filter(($)=>typeof $==="string").join(" ").toLowerCase();if(!j)return;if(j.includes("vscode")||j.includes("visual studio code"))return T.VSCODE;if(j.includes("jetbrains")||j.includes("webstorm")||j.includes("intellij")||j.includes("pycharm")||j.includes("goland")||j.includes("clion")||j.includes("rider")||j.includes("android studio"))return T.JETBRAINS;if(j.includes("neovim"))return T.NEOVIM;if(j.includes("kanban"))return T.KANBAN;if(j.includes("desktop"))return T.DESKTOP;if(j.includes("cline-platform"))return T.WEB;if(j.includes("cline-cli")||j.includes("cline-acp"))return T.CLI;if(j.includes("cline-sdk")||j.includes("cline-core"))return T.CORE;return}function P(f){let j=f?.trim();return j?j:void 0}function S(f){let j=f.client,$=b(j)??P(f.source),A=P(j.version),J=P(j.platform)??P(j.name),W=P(j.platformVersion)??A,H={cline_type:$,extension_version:A,platform:J,platform_version:W};if(f.user?.accountId===void 0)return H;let X=typeof f.user.accountId==="string"?P(f.user.accountId):void 0;return{...H,distinct_id:X??P(f.user.distinctId),user_id:X,account_id:X,account_email:X?P(f.user.email):void 0,organization_id:X?P(f.user.organizationId):void 0}}function v(f,j){let $={},A={},J,W=(H)=>({...j,...A,...$,...H,...J?{distinct_id:J}:{}});return{setDistinctId(H){J=P(H)},setMetadata(H){$={...H}},updateMetadata(H){$={...$,...H}},setCommonProperties(H){A={...H}},updateCommonProperties(H){A={...A,...H}},isEnabled:()=>f.isEnabled(),capture:(H)=>f.capture({event:H.event,properties:W(H.properties)}),captureRequired:(H,X)=>f.captureRequired(H,W(X)),recordCounter:(H,X,O,Z,Q)=>f.recordCounter(H,X,W(O),Z,Q),recordHistogram:(H,X,O,Z,Q)=>f.recordHistogram(H,X,W(O),Z,Q),recordGauge:(H,X,O,Z,Q)=>f.recordGauge(H,X,W(O),Z,Q),flush:()=>f.flush(),dispose:async()=>{}}}function Gf(f,j){return v(f,S(j))}export{Y as resolveCoreDistinctId,R as resolveCoreDeviceId,S as resolveClientTelemetryProperties,v as createScopedTelemetryService,N as createOpenTelemetryTelemetryService,y as createConfiguredTelemetryService,Ef as createConfiguredTelemetryHandle,Gf as createClientScopedTelemetryService,_ as OpenTelemetryProvider,B as OpenTelemetryAdapter};
@@ -0,0 +1,31 @@
1
+ import type { ClientContext, ITelemetryService, TelemetryProperties, UserContext } from "@cerebriline/shared";
2
+ /**
3
+ * Client identity that can safely cross a runtime boundary and be attached to
4
+ * telemetry emitted by the process that actually executes a session.
5
+ */
6
+ export interface ClientTelemetryContext {
7
+ client: ClientContext;
8
+ source?: string;
9
+ user?: UserContext;
10
+ }
11
+ /**
12
+ * Converts the shared client context into the established cross-surface
13
+ * analytics dimensions. Event-specific fields still take precedence.
14
+ */
15
+ export declare function resolveClientTelemetryProperties(context: ClientTelemetryContext): TelemetryProperties;
16
+ /**
17
+ * A non-owning view over a host telemetry service. It adds immutable
18
+ * per-session properties without mutating the host singleton, which is
19
+ * essential for a Hub process that can execute sessions from several clients
20
+ * concurrently.
21
+ *
22
+ * The returned view never disposes the parent. The process that created the
23
+ * parent telemetry service remains responsible for its lifecycle.
24
+ */
25
+ export declare function createScopedTelemetryService(parent: ITelemetryService, properties: TelemetryProperties): ITelemetryService;
26
+ /**
27
+ * Scopes a host telemetry singleton to one runtime client. This is the
28
+ * reusable bridge used by Hub-hosted sessions; local clients that already
29
+ * provide their own telemetry service do not need it.
30
+ */
31
+ export declare function createClientScopedTelemetryService(parent: ITelemetryService, context: ClientTelemetryContext): ITelemetryService;
@@ -1,4 +1,38 @@
1
1
  import type { WorkspaceInfo } from "@cerebriline/shared";
2
+ export type GitCommand = (args: readonly string[], options: {
3
+ cwd: string;
4
+ signal?: AbortSignal;
5
+ }) => Promise<{
6
+ stdout: string;
7
+ stderr?: string;
8
+ }>;
9
+ export declare function gitCommandErrorMessage(error: unknown): string;
10
+ export declare function gitCommandExitCode(error: unknown): number | undefined;
11
+ /**
12
+ * Shared Git queries, without metadata fallback or cloud-handoff policy.
13
+ * Display branches retain simple-git's detached/unborn semantics; symbolic
14
+ * branches are strict and preserve Git exit codes for callers that require one.
15
+ * Commands are lazy so metadata reads never collect status or contact a remote.
16
+ * Structured display queries use simple-git; raw queries use the injectable
17
+ * runner to retain exit codes, timeouts, and cancellation for strict checks.
18
+ */
19
+ export declare function createWorkspaceGitReader(input: {
20
+ cwd: string;
21
+ git?: GitCommand;
22
+ signal?: AbortSignal;
23
+ }): {
24
+ isInsideWorkTree(): Promise<boolean>;
25
+ remotes: () => import("simple-git").Response<import("simple-git").RemoteWithRefs[]>;
26
+ displayBranch: () => Promise<string>;
27
+ symbolicBranch: () => Promise<string>;
28
+ headSha: () => Promise<string>;
29
+ workspacePrefix: () => Promise<string>;
30
+ worktreeStatus: () => Promise<string>;
31
+ branchRemote: (branch: string) => Promise<string>;
32
+ branchMergeRef: (branch: string) => Promise<string>;
33
+ remoteUrl: (remote: string) => Promise<string>;
34
+ remoteRefs: (remote: string, ref: string) => Promise<string>;
35
+ };
2
36
  export interface WorkspaceInfoDiagnostics {
3
37
  info: WorkspaceInfo;
4
38
  vcsType: "git" | "none";
@@ -2,6 +2,11 @@ import type { ITelemetryService, WorkspaceInfo } from "@cerebriline/shared";
2
2
  export interface WorkspaceLifecycleTelemetryInput {
3
3
  telemetry?: ITelemetryService;
4
4
  rootPath: string;
5
+ /**
6
+ * Optional client identity used for de-duplication in a shared runtime
7
+ * process. The same workspace still emits once per client surface.
8
+ */
9
+ dedupeScope?: string;
5
10
  workspaceInfo?: WorkspaceInfo;
6
11
  rootCount?: number;
7
12
  vcsType?: "git" | "none";