@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.
- package/assets/prompt-templates/claude.md +2 -0
- package/assets/prompt-templates/deepseek.md +1 -0
- package/assets/prompt-templates/default.md +2 -1
- package/assets/prompt-templates/kimi-k3.md +1 -0
- package/assets/prompt-templates/kimi.md +1 -0
- package/assets/prompt-templates/minimax.md +2 -0
- package/assets/prompt-templates/nemotron.md +1 -0
- package/assets/skills/browser-automation/SKILL.md +113 -0
- package/dist/ClineCore.d.ts +9 -0
- package/dist/account/index.d.ts +1 -0
- package/dist/account/telemetry.d.ts +22 -0
- package/dist/cloud/api.d.ts +122 -0
- package/dist/cloud/controller.d.ts +172 -0
- package/dist/cloud/index.d.ts +9 -0
- package/dist/cloud/index.js +21 -0
- package/dist/cloud/models.d.ts +9 -0
- package/dist/cloud/repositories.d.ts +21 -0
- package/dist/cloud/snapshots.d.ts +22 -0
- package/dist/cloud/state.d.ts +13 -0
- package/dist/cloud/types.d.ts +84 -0
- package/dist/cron/events/cron-event-ingress.d.ts +4 -2
- package/dist/cron/runner/cron-runner.d.ts +5 -2
- package/dist/cron/service/cron-service.d.ts +2 -1
- package/dist/cron/service/schedule-service.d.ts +2 -1
- package/dist/cron/store/sqlite-cron-store.d.ts +7 -1
- package/dist/extensions/composio/composio-meta-tools.d.ts +39 -0
- package/dist/extensions/composio/composio-tools-extension.d.ts +13 -0
- package/dist/extensions/context/agentic-compaction.d.ts +1 -1
- package/dist/extensions/context/cap-thoughts.d.ts +39 -0
- package/dist/extensions/context/capped-thinking.d.ts +5 -0
- package/dist/extensions/context/compaction-shared.d.ts +76 -1
- package/dist/extensions/context/compaction.d.ts +81 -3
- package/dist/extensions/mcp/client.d.ts +1 -1
- package/dist/extensions/tools/code-search.d.ts +16 -0
- package/dist/extensions/tools/definitions.d.ts +5 -5
- package/dist/extensions/tools/executors/bash.d.ts +26 -0
- package/dist/extensions/tools/executors/index.d.ts +1 -1
- package/dist/extensions/tools/index.d.ts +1 -1
- package/dist/extensions/tools/library-tools.d.ts +14 -0
- package/dist/extensions/tools/schemas.d.ts +2 -11
- package/dist/extensions/tools/task-progress.d.ts +37 -0
- package/dist/extensions/tools/team/index.d.ts +1 -0
- package/dist/extensions/tools/team/multi-agent.d.ts +48 -0
- package/dist/extensions/tools/team/persistence-policy.d.ts +56 -0
- package/dist/extensions/tools/team/runtime.d.ts +1 -1
- package/dist/extensions/tools/team/sanitize-team-name.d.ts +5 -0
- package/dist/extensions/tools/team/team-tools.d.ts +1 -1
- package/dist/extensions/tools/types.d.ts +9 -1
- package/dist/extensions/tools/web-scrape-tool.d.ts +49 -0
- package/dist/extensions/tools/web-site-crawl.d.ts +96 -0
- package/dist/hooks/checkpoint-hooks.d.ts +23 -1
- package/dist/hooks/hook-file-hooks.d.ts +27 -0
- package/dist/hooks/subprocess-runner.d.ts +23 -0
- package/dist/hooks/subprocess.d.ts +10 -0
- package/dist/hub/client/index.d.ts +29 -3
- package/dist/hub/client/session-client.d.ts +0 -3
- package/dist/hub/daemon/bind-diagnostics.d.ts +16 -0
- package/dist/hub/daemon/entry.js +701 -652
- package/dist/hub/daemon/index.d.ts +17 -8
- package/dist/hub/discovery/index.d.ts +1 -0
- package/dist/hub/index.js +690 -642
- package/dist/hub/runtime-host/hub-runtime-host.d.ts +4 -2
- package/dist/hub/server/handlers/session-handlers.d.ts +6 -1
- package/dist/index.d.ts +24 -12
- package/dist/index.js +1137 -1062
- package/dist/remote/remote-environments.d.ts +155 -0
- package/dist/remote/remote-helper-entry.d.ts +1 -0
- package/dist/remote/remote-helper-entry.js +5 -0
- package/dist/remote/remote-helper.d.ts +29 -0
- package/dist/remote/remote-helper.js +4 -0
- package/dist/remote/shell-path.d.ts +88 -0
- package/dist/runtime/host/local-runtime-host.d.ts +4 -2
- package/dist/runtime/host/runtime-host.d.ts +13 -1
- package/dist/runtime/orchestration/oauth-refresh-lock.d.ts +6 -0
- package/dist/runtime/orchestration/session-runtime-orchestrator.d.ts +7 -0
- package/dist/runtime/orchestration/team-persistence-writer.d.ts +65 -0
- package/dist/runtime/safety/rules.d.ts +11 -0
- package/dist/runtime/turn-queue/pending-prompt-service.d.ts +1 -0
- package/dist/services/agent-events.d.ts +1 -0
- package/dist/services/cloud-handoff/git-preflight.d.ts +24 -0
- package/dist/services/cloud-handoff/index.d.ts +4 -0
- package/dist/services/cloud-handoff/metadata.d.ts +7 -0
- package/dist/services/cloud-handoff/transcript.d.ts +5 -0
- package/dist/services/cloud-handoff/types.d.ts +35 -0
- package/dist/services/feature-flags/FeatureFlagsService.d.ts +2 -0
- package/dist/services/feature-flags/cline-account-feature-flags.d.ts +5 -0
- package/dist/services/llms/cline-recommended-models.d.ts +1 -0
- package/dist/services/llms/handler-factory.d.ts +12 -0
- package/dist/services/llms/provider-defaults.d.ts +1 -1
- package/dist/services/llms/provider-settings.d.ts +19 -17
- package/dist/services/local-runtime-bootstrap.d.ts +7 -0
- package/dist/services/mcp-install.d.ts +9 -0
- package/dist/services/plugin-commands.d.ts +28 -0
- package/dist/services/providers/local-provider-registry.d.ts +8 -3
- package/dist/services/providers/local-provider-service.d.ts +20 -10
- package/dist/services/providers/model-source.d.ts +6 -1
- package/dist/services/providers/provider-config-fields.d.ts +11 -0
- package/dist/services/retrieval/code-index.d.ts +2 -0
- package/dist/services/retrieval/firecrawl.d.ts +15 -0
- package/dist/services/retrieval/web-mirror.d.ts +101 -0
- package/dist/services/session-import/claude-code.d.ts +1 -1
- package/dist/services/session-import/paths.d.ts +9 -0
- package/dist/services/storage/file-team-store.d.ts +10 -4
- package/dist/services/storage/sqlite-team-store.d.ts +48 -5
- package/dist/services/storage/team-store.d.ts +1 -0
- package/dist/services/telemetry/core-events.d.ts +97 -5
- package/dist/services/telemetry/index.d.ts +1 -0
- package/dist/services/telemetry/index.js +1 -1
- package/dist/services/telemetry/scoped-telemetry.d.ts +31 -0
- package/dist/services/workspace/workspace-manifest.d.ts +34 -0
- package/dist/services/workspace/workspace-telemetry.d.ts +5 -0
- package/dist/session/fork-metadata.d.ts +7 -0
- package/dist/session/models/session-compaction.d.ts +8 -1
- package/dist/session/services/message-builder.d.ts +8 -1
- package/dist/session/services/persistence-service.d.ts +4 -1
- package/dist/session/services/tool-result-cache.d.ts +30 -0
- package/dist/session/session-versioning-service.d.ts +8 -0
- package/dist/session/stores/session-manifest-store.d.ts +2 -4
- package/dist/session/team/team-session-coordinator.d.ts +3 -1
- package/dist/tasks/task-tool.d.ts +2 -2
- package/dist/types/provider-settings.d.ts +11 -0
- package/dist/types/session.d.ts +2 -0
- package/dist/types/storage.d.ts +22 -1
- package/package.json +16 -4
- package/dist/cron/runner/resource-limiter.d.ts +0 -8
- 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
|
-
|
|
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
|
-
|
|
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
|
|
17
|
-
|
|
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
|
-
|
|
187
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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";
|