@volcengine/tls-observer-cursor 0.0.4

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/LICENCE ADDED
@@ -0,0 +1,13 @@
1
+ # Copyright 2023 Beijing Volcano Engine Technology Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # TLS Observer for Cursor
2
+
3
+ 采集 Cursor 本地 hooks 和 `agent-transcripts/*.jsonl`,转换为 GenAI Trace,并通过 Volcengine TLS Producer 写入 Trace Topic。
4
+
5
+ ## 数据源
6
+
7
+ - Cursor 原生 hooks:`beforeSubmitPrompt`、`preToolUse`、`postToolUse`、`postToolUseFailure`、`stop`、`sessionEnd`、`subagentStart`、`subagentStop`、`preCompact`。主 `tool.call` 链路只使用 Cursor generic tool hooks。
8
+ - Cursor transcript:`~/.cursor/projects/<workspace>/agent-transcripts/<conversation-id>/<conversation-id>.jsonl`。
9
+
10
+ ## Span
11
+
12
+ - `agent.turn`:一个用户 turn 的根 span。
13
+ - `llm.request`:从 assistant transcript entry 还原的模型请求。
14
+ - `tool.call`:从 `tool_use` block 与 tool hook observation 还原的工具调用,挂在产出该 `tool_use` 的 `llm.request` 下。
15
+ - `agent.subagent` / `agent.compact`:Cursor subagent 和 compact hook 事件。
16
+
17
+ 所有 span 都包含 `tls.app.type=cursor`。Cursor 专属字段使用 `cursor.*` attribute,例如 `cursor.version`、`cursor.workspace.roots`、`cursor.transcript_path`。
18
+
19
+ ## 本地接入
20
+
21
+ 构建:
22
+
23
+ ```bash
24
+ pnpm --dir packages/cursor build
25
+ ```
26
+
27
+ 准备 env:
28
+
29
+ ```bash
30
+ cat > ~/.cursor/tls-observer-cursor.env <<'EOF'
31
+ CURSOR_TLS_ENDPOINT=https://tls-cn-beijing.volces.com
32
+ CURSOR_TLS_REGION=cn-beijing
33
+ CURSOR_TLS_TRACE_TOPIC_ID=<trace-topic-id>
34
+ CURSOR_TLS_API_KEY=<api-key>
35
+ CURSOR_TLS_CAPTURE_CONTENT=1
36
+ EOF
37
+ ```
38
+
39
+ 在 Cursor hooks 中引用构建产物。用户级示例:
40
+
41
+ ```json
42
+ {
43
+ "version": 1,
44
+ "hooks": {
45
+ "beforeSubmitPrompt": [
46
+ {
47
+ "command": "node \"/Users/bytedance/TLSProjects/storage-tls-observer/packages/cursor/dist/index.js\""
48
+ }
49
+ ],
50
+ "stop": [
51
+ {
52
+ "command": "node \"/Users/bytedance/TLSProjects/storage-tls-observer/packages/cursor/dist/index.js\"",
53
+ "timeout": 120
54
+ }
55
+ ]
56
+ }
57
+ }
58
+ ```
59
+
60
+ 完整 hook 模板见 `hooks/hooks.json`。
61
+
62
+ ## 配置
63
+
64
+ | 环境变量 | 说明 |
65
+ | --- | --- |
66
+ | `CURSOR_TLS_EXPORT` | 设为 `0` 可关闭上报 |
67
+ | `CURSOR_TLS_CAPTURE_CONTENT` | 设为 `0` 时不写 prompt/response/tool body |
68
+ | `CURSOR_TLS_DEBUG_ARTIFACTS` | 设为 `1` 输出本地 trace/OTLP 调试文件 |
69
+ | `CURSOR_TLS_DATA_ROOT` | 默认 `~/.cursor/plugins/data/tls-observer-cursor` |
70
+ | `CURSOR_TLS_ENDPOINT` / `CURSOR_TLS_OTEL_ENDPOINT` | TLS endpoint |
71
+ | `CURSOR_TLS_REGION` | TLS region |
72
+ | `CURSOR_TLS_TRACE_TOPIC_ID` | Trace Topic ID |
73
+ | `CURSOR_TLS_API_KEY` | TLS API key |
74
+ | `CURSOR_TLS_AK` / `CURSOR_TLS_SK` | AK/SK 鉴权 |
75
+
76
+ 最近一次发送结果:
77
+
78
+ ```bash
79
+ cat ~/.cursor/plugins/data/tls-observer-cursor/logs/send/latest.send-log.json
80
+ ```
@@ -0,0 +1,26 @@
1
+ export interface Config {
2
+ enabled: boolean;
3
+ dataRoot: string;
4
+ stateFilePath: string;
5
+ sendLogsDir: string;
6
+ artifactsDir: string;
7
+ diagnosticLogMaxBytes: number;
8
+ captureContent: boolean;
9
+ debugArtifacts: boolean;
10
+ serviceName: string;
11
+ serviceInstanceId: string;
12
+ tlsEndpoint?: string;
13
+ otelEndpoint?: string;
14
+ region?: string;
15
+ traceTopicId?: string;
16
+ apiKey?: string;
17
+ ak?: string;
18
+ sk?: string;
19
+ authMode: 'header' | 'resource';
20
+ exportTimeoutMs: number;
21
+ exportTimeoutRetries: number;
22
+ transcriptLookbehindBytes: number;
23
+ }
24
+ export declare function loadEnvFile(filePath?: string): boolean;
25
+ export declare function loadConfig(): Config;
26
+ export declare function localIdentityMetadata(): Record<string, unknown>;
@@ -0,0 +1,10 @@
1
+ import type { Config } from './config';
2
+ import { closeTraceLogProducers } from './tls-producer';
3
+ import type { ExportResult, TraceModel, TraceSpan } from './types';
4
+ export declare const SCHEMA_FIELD_ORDER: string[];
5
+ export declare function buildOtlpPayload(trace: TraceModel, config: Config): Record<string, unknown>;
6
+ export declare function exportTraceToTls(trace: TraceModel, config: Config): Promise<ExportResult>;
7
+ export { closeTraceLogProducers };
8
+ export declare function buildSchemaAlignedRecord(trace: TraceModel, span: TraceSpan, observedTimeUnixMs?: number): Record<string, unknown>;
9
+ export declare function buildSchemaAlignedRecords(trace: TraceModel, observedTimeUnixMs?: number): Array<Record<string, unknown>>;
10
+ export declare function exportSummary(trace: TraceModel, result: ExportResult): Record<string, unknown>;
@@ -0,0 +1,3 @@
1
+ import type { Config } from '../config';
2
+ import type { CompactHookInput } from '../types';
3
+ export declare function handlePreCompact(input: CompactHookInput, config: Config): Promise<void>;
@@ -0,0 +1,3 @@
1
+ import type { Config } from '../config';
2
+ import type { HookInput } from '../types';
3
+ export declare function dispatchHook(input: HookInput, config: Config): Promise<void>;
@@ -0,0 +1,6 @@
1
+ export { dispatchHook } from './dispatch';
2
+ export { handlePreCompact } from './compact';
3
+ export { handleSessionEnd, handleStop } from './stop';
4
+ export { handleSubagentStart, handleSubagentStop } from './subagent-stop';
5
+ export { handlePostToolUse, handlePreToolUse } from './tool-use';
6
+ export { handleUserPromptSubmit } from './user-prompt-submit';
@@ -0,0 +1,4 @@
1
+ import type { Config } from '../config';
2
+ import type { StopHookInput } from '../types';
3
+ export declare function handleStop(input: StopHookInput, config: Config): Promise<void>;
4
+ export declare function handleSessionEnd(input: StopHookInput, config: Config): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import type { Config } from '../config';
2
+ import type { SubagentHookInput } from '../types';
3
+ export declare function handleSubagentStart(input: SubagentHookInput, config: Config): Promise<void>;
4
+ export declare function handleSubagentStop(input: SubagentHookInput, config: Config): Promise<void>;
@@ -0,0 +1,4 @@
1
+ import type { Config } from '../config';
2
+ import type { ToolHookInput } from '../types';
3
+ export declare function handlePreToolUse(input: ToolHookInput, config: Config): Promise<void>;
4
+ export declare function handlePostToolUse(input: ToolHookInput, config: Config): Promise<void>;
@@ -0,0 +1,34 @@
1
+ import type { Config } from '../config';
2
+ import type { HookInput, SessionState, StopHookInput, TraceModel } from '../types';
3
+ export declare function expandHome(filePath: string | undefined): string | undefined;
4
+ export declare function sessionIdForInput(input: HookInput, transcriptPath?: string): string | undefined;
5
+ export declare function writeSendLog(config: Config, record: Record<string, unknown>): Promise<void>;
6
+ export declare function exportTraceAndLog(options: {
7
+ config: Config;
8
+ trace: TraceModel;
9
+ hookEventName: string;
10
+ }): Promise<void>;
11
+ export declare function exportTranscriptTurns(options: {
12
+ input: StopHookInput;
13
+ config: Config;
14
+ transcriptPath: string;
15
+ afterLine: number;
16
+ afterOffset?: number;
17
+ session: SessionState;
18
+ hookEventName: string;
19
+ turnEndTimeMs?: number;
20
+ source?: string;
21
+ traceSeedSuffix?: string;
22
+ extraAttributes?: Record<string, unknown>;
23
+ turnIndexBase?: number;
24
+ synthesizeFinalAssistant?: boolean;
25
+ }): Promise<{
26
+ lastLine: number;
27
+ lastOffset: number;
28
+ tracedTurns: number;
29
+ }>;
30
+ export declare function exportPendingSubagents(options: {
31
+ input: StopHookInput;
32
+ config: Config;
33
+ session: SessionState;
34
+ }): Promise<number>;
@@ -0,0 +1,3 @@
1
+ import type { Config } from '../config';
2
+ import type { UserPromptSubmitHookInput } from '../types';
3
+ export declare function handleUserPromptSubmit(input: UserPromptSubmitHookInput, config: Config): Promise<void>;
@@ -0,0 +1 @@
1
+ export {};