@yagni-app/code 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -27
- package/dist/claudeCompat.d.ts +59 -0
- package/dist/claudeCompat.js +109 -2
- package/dist/claudePlugins.d.ts +45 -3
- package/dist/claudePlugins.js +129 -19
- package/dist/cli.js +28 -4
- package/dist/doctor.d.ts +42 -4
- package/dist/doctor.js +150 -15
- package/dist/extension/condensedTools.d.ts +12 -1
- package/dist/extension/condensedTools.js +17 -9
- package/dist/extension/index.d.ts +18 -5
- package/dist/extension/index.js +319 -72
- package/dist/extension/mcp/approval.d.ts +45 -0
- package/dist/extension/mcp/approval.js +164 -0
- package/dist/extension/mcp/auth.d.ts +124 -0
- package/dist/extension/mcp/auth.js +560 -0
- package/dist/extension/mcp/authStore.d.ts +61 -0
- package/dist/extension/mcp/authStore.js +105 -0
- package/dist/extension/mcp/callbackPage.d.ts +31 -0
- package/dist/extension/mcp/callbackPage.js +222 -0
- package/dist/extension/mcp/cliConfig.d.ts +12 -0
- package/dist/extension/mcp/cliConfig.js +12 -0
- package/dist/extension/mcp/config.d.ts +153 -0
- package/dist/extension/mcp/config.js +381 -0
- package/dist/extension/mcp/log.d.ts +28 -0
- package/dist/extension/mcp/log.js +82 -0
- package/dist/extension/mcp/manager.d.ts +100 -0
- package/dist/extension/mcp/manager.js +273 -0
- package/dist/extension/mcp/names.d.ts +25 -0
- package/dist/extension/mcp/names.js +40 -0
- package/dist/extension/mcp/panel.d.ts +33 -0
- package/dist/extension/mcp/panel.js +268 -0
- package/dist/extension/mcp/prompts.d.ts +23 -0
- package/dist/extension/mcp/prompts.js +93 -0
- package/dist/extension/mcp/startup.d.ts +55 -0
- package/dist/extension/mcp/startup.js +152 -0
- package/dist/extension/mcp/tools.d.ts +31 -0
- package/dist/extension/mcp/tools.js +117 -0
- package/dist/extension/mcp/transports.d.ts +17 -0
- package/dist/extension/mcp/transports.js +44 -0
- package/dist/extension/permission/gate.d.ts +104 -2
- package/dist/extension/permission/gate.js +387 -31
- package/dist/extension/permission/guardian.d.ts +24 -5
- package/dist/extension/permission/guardian.js +162 -24
- package/dist/extension/permissionRules/bashFileArgs.d.ts +39 -0
- package/dist/extension/permissionRules/bashFileArgs.js +236 -0
- package/dist/extension/permissionRules/engine.d.ts +50 -0
- package/dist/extension/permissionRules/engine.js +238 -0
- package/dist/extension/permissionRules/loadConfig.d.ts +53 -0
- package/dist/extension/permissionRules/loadConfig.js +90 -0
- package/dist/extension/permissionRules/parser.d.ts +38 -0
- package/dist/extension/permissionRules/parser.js +136 -0
- package/dist/extension/permissionRules/pathRules.d.ts +58 -0
- package/dist/extension/permissionRules/pathRules.js +120 -0
- package/dist/extension/permissionRules/shellRules.d.ts +52 -0
- package/dist/extension/permissionRules/shellRules.js +221 -0
- package/dist/extension/pipeline/invocation.d.ts +3 -6
- package/dist/extension/pipeline/invocation.js +3 -6
- package/dist/extension/pipeline/personas.js +5 -0
- package/dist/extension/pipeline/runner.d.ts +0 -1
- package/dist/extension/pipeline/runner.js +6 -14
- package/dist/extension/plugins/inventory.d.ts +88 -0
- package/dist/extension/plugins/inventory.js +144 -0
- package/dist/extension/plugins/panel.d.ts +45 -0
- package/dist/extension/plugins/panel.js +293 -0
- package/dist/extension/sandbox/bash.d.ts +99 -0
- package/dist/extension/sandbox/bash.js +190 -0
- package/dist/extension/sandbox/config.d.ts +114 -0
- package/dist/extension/sandbox/config.js +366 -0
- package/dist/extension/sandbox/manager.d.ts +98 -0
- package/dist/extension/sandbox/manager.js +216 -0
- package/dist/extension/sandbox/panel.d.ts +111 -0
- package/dist/extension/sandbox/panel.js +342 -0
- package/dist/extension/sandbox/session.d.ts +85 -0
- package/dist/extension/sandbox/session.js +775 -0
- package/dist/extension/telemetry/attrs.d.ts +96 -0
- package/dist/extension/telemetry/attrs.js +149 -0
- package/dist/extension/telemetry/config.d.ts +99 -0
- package/dist/extension/telemetry/config.js +193 -0
- package/dist/extension/telemetry/index.d.ts +7 -0
- package/dist/extension/telemetry/index.js +7 -0
- package/dist/extension/telemetry/probe.d.ts +29 -0
- package/dist/extension/telemetry/probe.js +122 -0
- package/dist/extension/telemetry/register.d.ts +40 -0
- package/dist/extension/telemetry/register.js +192 -0
- package/dist/extension/telemetry/sdk.d.ts +63 -0
- package/dist/extension/telemetry/sdk.js +207 -0
- package/dist/extension/telemetry/tracker.d.ts +131 -0
- package/dist/extension/telemetry/tracker.js +551 -0
- package/dist/extension/vendor/IGNORE-LICENSE-MIT +21 -0
- package/dist/extension/vendor/ignore.d.ts +86 -0
- package/dist/extension/vendor/ignore.js +788 -0
- package/dist/goHeadless.d.ts +1 -1
- package/dist/goHeadless.js +2 -2
- package/dist/launch.d.ts +4 -3
- package/dist/launch.js +7 -4
- package/dist/mcpCommand.d.ts +122 -0
- package/dist/mcpCommand.js +787 -0
- package/dist/otel.d.ts +69 -63
- package/dist/otel.js +154 -119
- package/dist/paths.d.ts +13 -0
- package/dist/paths.js +18 -0
- package/dist/pluginCommand.d.ts +43 -0
- package/dist/pluginCommand.js +499 -0
- package/dist/pluginStore.d.ts +170 -0
- package/dist/pluginStore.js +554 -0
- package/dist/upgrade.d.ts +11 -2
- package/dist/upgrade.js +48 -8
- package/package.json +20 -3
- package/dist/extension/mcpTools.d.ts +0 -57
- package/dist/extension/mcpTools.js +0 -132
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute, metric, and event names.
|
|
3
|
+
*
|
|
4
|
+
* Two vocabularies ride on every signal on purpose:
|
|
5
|
+
*
|
|
6
|
+
* - Claude Code's telemetry shape (`session.id`, `input_tokens`,
|
|
7
|
+
* `tool_name`, the `<prefix>.token.usage` counter, the `api_request`
|
|
8
|
+
* event …) so a team's existing Claude Code dashboards swap to YAGNI Code
|
|
9
|
+
* by changing the prefix from `claude_code` to `yagni_code`;
|
|
10
|
+
* - the OpenTelemetry GenAI semantic conventions (`gen_ai.*`) on the LLM
|
|
11
|
+
* and tool spans, which is what vendor LLM-observability products
|
|
12
|
+
* (Datadog LLM Observability, Grafana's GenAI views) key on.
|
|
13
|
+
*
|
|
14
|
+
* Names are literal strings rather than semconv-package imports: the set is
|
|
15
|
+
* small, stable, and part of our documented customer contract.
|
|
16
|
+
*/
|
|
17
|
+
export declare const PREFIX = "yagni_code";
|
|
18
|
+
export declare const ATTR_SESSION_ID = "session.id";
|
|
19
|
+
export declare const ATTR_APP_VERSION = "app.version";
|
|
20
|
+
export declare const ATTR_APP_ENTRYPOINT = "app.entrypoint";
|
|
21
|
+
export declare const ATTR_ORGANIZATION_ID = "organization.id";
|
|
22
|
+
export declare const ATTR_USER_EMAIL = "user.email";
|
|
23
|
+
export declare const ATTR_TERMINAL_TYPE = "terminal.type";
|
|
24
|
+
export declare const ATTR_GEN_AI_OPERATION_NAME = "gen_ai.operation.name";
|
|
25
|
+
export declare const ATTR_GEN_AI_PROVIDER_NAME = "gen_ai.provider.name";
|
|
26
|
+
export declare const ATTR_GEN_AI_SYSTEM = "gen_ai.system";
|
|
27
|
+
export declare const ATTR_GEN_AI_REQUEST_MODEL = "gen_ai.request.model";
|
|
28
|
+
export declare const ATTR_GEN_AI_RESPONSE_MODEL = "gen_ai.response.model";
|
|
29
|
+
export declare const ATTR_GEN_AI_RESPONSE_ID = "gen_ai.response.id";
|
|
30
|
+
export declare const ATTR_GEN_AI_FINISH_REASONS = "gen_ai.response.finish_reasons";
|
|
31
|
+
/**
|
|
32
|
+
* Token usage. The semconv registry says `gen_ai.usage.input_tokens` "SHOULD
|
|
33
|
+
* include all types of input tokens, including cached tokens", and defines the
|
|
34
|
+
* cache counters as subsets of it. pi reports the Anthropic way (non-cached
|
|
35
|
+
* input, cache read, cache write as three disjoint numbers), so the tracker
|
|
36
|
+
* adds them up for the `gen_ai.*` layer. Consumers such as Datadog LLM
|
|
37
|
+
* Observability divide cache_read by input_tokens; feeding them the disjoint
|
|
38
|
+
* number produced cache ratios in the tens of thousands of percent.
|
|
39
|
+
*
|
|
40
|
+
* The flat Claude Code attributes (`input_tokens`, `cache_read_tokens`, …) and
|
|
41
|
+
* the `<prefix>.token.usage` metric deliberately keep Claude Code's disjoint
|
|
42
|
+
* semantics so cross-harness comparisons stay apples to apples.
|
|
43
|
+
*/
|
|
44
|
+
export declare const ATTR_GEN_AI_INPUT_TOKENS = "gen_ai.usage.input_tokens";
|
|
45
|
+
export declare const ATTR_GEN_AI_OUTPUT_TOKENS = "gen_ai.usage.output_tokens";
|
|
46
|
+
export declare const ATTR_GEN_AI_TOTAL_TOKENS = "gen_ai.usage.total_tokens";
|
|
47
|
+
export declare const ATTR_GEN_AI_CACHE_READ_TOKENS = "gen_ai.usage.cache_read.input_tokens";
|
|
48
|
+
export declare const ATTR_GEN_AI_CACHE_WRITE_TOKENS = "gen_ai.usage.cache_write.input_tokens";
|
|
49
|
+
/** Pre-semconv spellings emitted through 1.0.x; kept for one release so
|
|
50
|
+
* dashboards keyed on them keep working. */
|
|
51
|
+
export declare const ATTR_GEN_AI_CACHE_READ_TOKENS_LEGACY = "gen_ai.usage.cache_read_input_tokens";
|
|
52
|
+
export declare const ATTR_GEN_AI_CACHE_CREATION_TOKENS_LEGACY = "gen_ai.usage.cache_creation_input_tokens";
|
|
53
|
+
/** The one cost attribute Datadog's OTLP ingestion documents. Carries the
|
|
54
|
+
* same sell-rate figure as the flat `cost_usd`, so the vendor Cost view
|
|
55
|
+
* populates for the opaque tier id, which no vendor price table knows.
|
|
56
|
+
* Unit is NANODOLLARS (integer), not dollars: Datadog copies the value
|
|
57
|
+
* unscaled into its nanodollar cost metric. */
|
|
58
|
+
export declare const ATTR_GEN_AI_COST_ESTIMATED_TOTAL = "gen_ai.cost.estimated_total";
|
|
59
|
+
export declare const ATTR_GEN_AI_CONVERSATION_ID = "gen_ai.conversation.id";
|
|
60
|
+
export declare const ATTR_GEN_AI_AGENT_NAME = "gen_ai.agent.name";
|
|
61
|
+
export declare const ATTR_GEN_AI_TOOL_NAME = "gen_ai.tool.name";
|
|
62
|
+
export declare const ATTR_GEN_AI_TOOL_CALL_ID = "gen_ai.tool.call.id";
|
|
63
|
+
export declare const ATTR_GEN_AI_TOOL_TYPE = "gen_ai.tool.type";
|
|
64
|
+
export declare const ATTR_ERROR_TYPE = "error.type";
|
|
65
|
+
export declare const ATTR_HTTP_STATUS_CODE = "http.response.status_code";
|
|
66
|
+
/** The provider name every span carries. The backing model is never exposed:
|
|
67
|
+
* `gen_ai.request.model` is the opaque YAGNI tier id. */
|
|
68
|
+
export declare const GEN_AI_PROVIDER = "yagni";
|
|
69
|
+
export declare const SPAN_INTERACTION = "yagni_code.interaction";
|
|
70
|
+
export declare const SPAN_TURN = "yagni_code.turn";
|
|
71
|
+
export declare const SPAN_LLM_REQUEST = "yagni_code.llm_request";
|
|
72
|
+
export declare const SPAN_TOOL = "yagni_code.tool";
|
|
73
|
+
export declare const METRIC_SESSION_COUNT = "yagni_code.session.count";
|
|
74
|
+
export declare const METRIC_LINES_OF_CODE = "yagni_code.lines_of_code.count";
|
|
75
|
+
export declare const METRIC_PULL_REQUEST_COUNT = "yagni_code.pull_request.count";
|
|
76
|
+
export declare const METRIC_COMMIT_COUNT = "yagni_code.commit.count";
|
|
77
|
+
export declare const METRIC_COST_USAGE = "yagni_code.cost.usage";
|
|
78
|
+
export declare const METRIC_TOKEN_USAGE = "yagni_code.token.usage";
|
|
79
|
+
export declare const METRIC_CODE_EDIT_DECISION = "yagni_code.code_edit_tool.decision";
|
|
80
|
+
export declare const METRIC_ACTIVE_TIME = "yagni_code.active_time.total";
|
|
81
|
+
export declare const EVENT_USER_PROMPT = "user_prompt";
|
|
82
|
+
export declare const EVENT_ASSISTANT_RESPONSE = "assistant_response";
|
|
83
|
+
export declare const EVENT_TOOL_RESULT = "tool_result";
|
|
84
|
+
export declare const EVENT_API_REQUEST = "api_request";
|
|
85
|
+
export declare const EVENT_API_ERROR = "api_error";
|
|
86
|
+
export declare const EVENT_TOOL_DECISION = "tool_decision";
|
|
87
|
+
export declare const EVENT_PERMISSION_MODE_CHANGED = "permission_mode_changed";
|
|
88
|
+
/** Claude Code token-type values on `<prefix>.token.usage`. */
|
|
89
|
+
export type TokenType = "input" | "output" | "cacheRead" | "cacheCreation";
|
|
90
|
+
/** Claude Code decision sources on tool_decision / code_edit_tool.decision. */
|
|
91
|
+
export type DecisionSource = "config" | "hook" | "user_permanent" | "user_temporary" | "user_abort" | "user_reject";
|
|
92
|
+
export type Decision = "accept" | "reject";
|
|
93
|
+
export declare function clampString(s: string, max?: number): string;
|
|
94
|
+
/** Language label from a file path's extension (Claude Code's `language` attr). */
|
|
95
|
+
export declare function languageFromPath(path: string | undefined): string | undefined;
|
|
96
|
+
//# sourceMappingURL=attrs.d.ts.map
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute, metric, and event names.
|
|
3
|
+
*
|
|
4
|
+
* Two vocabularies ride on every signal on purpose:
|
|
5
|
+
*
|
|
6
|
+
* - Claude Code's telemetry shape (`session.id`, `input_tokens`,
|
|
7
|
+
* `tool_name`, the `<prefix>.token.usage` counter, the `api_request`
|
|
8
|
+
* event …) so a team's existing Claude Code dashboards swap to YAGNI Code
|
|
9
|
+
* by changing the prefix from `claude_code` to `yagni_code`;
|
|
10
|
+
* - the OpenTelemetry GenAI semantic conventions (`gen_ai.*`) on the LLM
|
|
11
|
+
* and tool spans, which is what vendor LLM-observability products
|
|
12
|
+
* (Datadog LLM Observability, Grafana's GenAI views) key on.
|
|
13
|
+
*
|
|
14
|
+
* Names are literal strings rather than semconv-package imports: the set is
|
|
15
|
+
* small, stable, and part of our documented customer contract.
|
|
16
|
+
*/
|
|
17
|
+
export const PREFIX = "yagni_code";
|
|
18
|
+
// ── Resource / standard attributes ──────────────────────────────────────────
|
|
19
|
+
export const ATTR_SESSION_ID = "session.id";
|
|
20
|
+
export const ATTR_APP_VERSION = "app.version";
|
|
21
|
+
export const ATTR_APP_ENTRYPOINT = "app.entrypoint";
|
|
22
|
+
export const ATTR_ORGANIZATION_ID = "organization.id";
|
|
23
|
+
export const ATTR_USER_EMAIL = "user.email";
|
|
24
|
+
export const ATTR_TERMINAL_TYPE = "terminal.type";
|
|
25
|
+
// ── GenAI semantic conventions ──────────────────────────────────────────────
|
|
26
|
+
export const ATTR_GEN_AI_OPERATION_NAME = "gen_ai.operation.name";
|
|
27
|
+
export const ATTR_GEN_AI_PROVIDER_NAME = "gen_ai.provider.name";
|
|
28
|
+
export const ATTR_GEN_AI_SYSTEM = "gen_ai.system";
|
|
29
|
+
export const ATTR_GEN_AI_REQUEST_MODEL = "gen_ai.request.model";
|
|
30
|
+
export const ATTR_GEN_AI_RESPONSE_MODEL = "gen_ai.response.model";
|
|
31
|
+
export const ATTR_GEN_AI_RESPONSE_ID = "gen_ai.response.id";
|
|
32
|
+
export const ATTR_GEN_AI_FINISH_REASONS = "gen_ai.response.finish_reasons";
|
|
33
|
+
/**
|
|
34
|
+
* Token usage. The semconv registry says `gen_ai.usage.input_tokens` "SHOULD
|
|
35
|
+
* include all types of input tokens, including cached tokens", and defines the
|
|
36
|
+
* cache counters as subsets of it. pi reports the Anthropic way (non-cached
|
|
37
|
+
* input, cache read, cache write as three disjoint numbers), so the tracker
|
|
38
|
+
* adds them up for the `gen_ai.*` layer. Consumers such as Datadog LLM
|
|
39
|
+
* Observability divide cache_read by input_tokens; feeding them the disjoint
|
|
40
|
+
* number produced cache ratios in the tens of thousands of percent.
|
|
41
|
+
*
|
|
42
|
+
* The flat Claude Code attributes (`input_tokens`, `cache_read_tokens`, …) and
|
|
43
|
+
* the `<prefix>.token.usage` metric deliberately keep Claude Code's disjoint
|
|
44
|
+
* semantics so cross-harness comparisons stay apples to apples.
|
|
45
|
+
*/
|
|
46
|
+
export const ATTR_GEN_AI_INPUT_TOKENS = "gen_ai.usage.input_tokens";
|
|
47
|
+
export const ATTR_GEN_AI_OUTPUT_TOKENS = "gen_ai.usage.output_tokens";
|
|
48
|
+
export const ATTR_GEN_AI_TOTAL_TOKENS = "gen_ai.usage.total_tokens";
|
|
49
|
+
export const ATTR_GEN_AI_CACHE_READ_TOKENS = "gen_ai.usage.cache_read.input_tokens";
|
|
50
|
+
export const ATTR_GEN_AI_CACHE_WRITE_TOKENS = "gen_ai.usage.cache_write.input_tokens";
|
|
51
|
+
/** Pre-semconv spellings emitted through 1.0.x; kept for one release so
|
|
52
|
+
* dashboards keyed on them keep working. */
|
|
53
|
+
export const ATTR_GEN_AI_CACHE_READ_TOKENS_LEGACY = "gen_ai.usage.cache_read_input_tokens";
|
|
54
|
+
export const ATTR_GEN_AI_CACHE_CREATION_TOKENS_LEGACY = "gen_ai.usage.cache_creation_input_tokens";
|
|
55
|
+
/** The one cost attribute Datadog's OTLP ingestion documents. Carries the
|
|
56
|
+
* same sell-rate figure as the flat `cost_usd`, so the vendor Cost view
|
|
57
|
+
* populates for the opaque tier id, which no vendor price table knows.
|
|
58
|
+
* Unit is NANODOLLARS (integer), not dollars: Datadog copies the value
|
|
59
|
+
* unscaled into its nanodollar cost metric. */
|
|
60
|
+
export const ATTR_GEN_AI_COST_ESTIMATED_TOTAL = "gen_ai.cost.estimated_total";
|
|
61
|
+
export const ATTR_GEN_AI_CONVERSATION_ID = "gen_ai.conversation.id";
|
|
62
|
+
export const ATTR_GEN_AI_AGENT_NAME = "gen_ai.agent.name";
|
|
63
|
+
export const ATTR_GEN_AI_TOOL_NAME = "gen_ai.tool.name";
|
|
64
|
+
export const ATTR_GEN_AI_TOOL_CALL_ID = "gen_ai.tool.call.id";
|
|
65
|
+
export const ATTR_GEN_AI_TOOL_TYPE = "gen_ai.tool.type";
|
|
66
|
+
export const ATTR_ERROR_TYPE = "error.type";
|
|
67
|
+
export const ATTR_HTTP_STATUS_CODE = "http.response.status_code";
|
|
68
|
+
/** The provider name every span carries. The backing model is never exposed:
|
|
69
|
+
* `gen_ai.request.model` is the opaque YAGNI tier id. */
|
|
70
|
+
export const GEN_AI_PROVIDER = "yagni";
|
|
71
|
+
// ── Span names (Claude Code's beta trace tree, prefixed) ────────────────────
|
|
72
|
+
export const SPAN_INTERACTION = `${PREFIX}.interaction`;
|
|
73
|
+
export const SPAN_TURN = `${PREFIX}.turn`;
|
|
74
|
+
export const SPAN_LLM_REQUEST = `${PREFIX}.llm_request`;
|
|
75
|
+
export const SPAN_TOOL = `${PREFIX}.tool`;
|
|
76
|
+
// ── Metric names (Claude Code's eight counters, prefixed) ───────────────────
|
|
77
|
+
export const METRIC_SESSION_COUNT = `${PREFIX}.session.count`;
|
|
78
|
+
export const METRIC_LINES_OF_CODE = `${PREFIX}.lines_of_code.count`;
|
|
79
|
+
export const METRIC_PULL_REQUEST_COUNT = `${PREFIX}.pull_request.count`;
|
|
80
|
+
export const METRIC_COMMIT_COUNT = `${PREFIX}.commit.count`;
|
|
81
|
+
export const METRIC_COST_USAGE = `${PREFIX}.cost.usage`;
|
|
82
|
+
export const METRIC_TOKEN_USAGE = `${PREFIX}.token.usage`;
|
|
83
|
+
export const METRIC_CODE_EDIT_DECISION = `${PREFIX}.code_edit_tool.decision`;
|
|
84
|
+
export const METRIC_ACTIVE_TIME = `${PREFIX}.active_time.total`;
|
|
85
|
+
// ── Event names (Claude Code's log events, prefixed in the body) ────────────
|
|
86
|
+
export const EVENT_USER_PROMPT = "user_prompt";
|
|
87
|
+
export const EVENT_ASSISTANT_RESPONSE = "assistant_response";
|
|
88
|
+
export const EVENT_TOOL_RESULT = "tool_result";
|
|
89
|
+
export const EVENT_API_REQUEST = "api_request";
|
|
90
|
+
export const EVENT_API_ERROR = "api_error";
|
|
91
|
+
export const EVENT_TOOL_DECISION = "tool_decision";
|
|
92
|
+
export const EVENT_PERMISSION_MODE_CHANGED = "permission_mode_changed";
|
|
93
|
+
/** Cap on any string attribute (Claude Code's 60 KB content limit). */
|
|
94
|
+
const MAX_ATTR_BYTES = 60 * 1024;
|
|
95
|
+
export function clampString(s, max = MAX_ATTR_BYTES) {
|
|
96
|
+
if (Buffer.byteLength(s, "utf8") <= max)
|
|
97
|
+
return s;
|
|
98
|
+
let end = max;
|
|
99
|
+
while (end > 0 && Buffer.byteLength(s.slice(0, end), "utf8") > max - 16)
|
|
100
|
+
end -= 64;
|
|
101
|
+
return `${s.slice(0, Math.max(0, end))}…[truncated]`;
|
|
102
|
+
}
|
|
103
|
+
/** Language label from a file path's extension (Claude Code's `language` attr). */
|
|
104
|
+
export function languageFromPath(path) {
|
|
105
|
+
if (!path)
|
|
106
|
+
return undefined;
|
|
107
|
+
const m = /\.([A-Za-z0-9]+)$/.exec(path);
|
|
108
|
+
if (!m)
|
|
109
|
+
return undefined;
|
|
110
|
+
const ext = m[1].toLowerCase();
|
|
111
|
+
const map = {
|
|
112
|
+
ts: "typescript",
|
|
113
|
+
tsx: "typescript",
|
|
114
|
+
mts: "typescript",
|
|
115
|
+
cts: "typescript",
|
|
116
|
+
js: "javascript",
|
|
117
|
+
jsx: "javascript",
|
|
118
|
+
mjs: "javascript",
|
|
119
|
+
cjs: "javascript",
|
|
120
|
+
py: "python",
|
|
121
|
+
rb: "ruby",
|
|
122
|
+
go: "go",
|
|
123
|
+
rs: "rust",
|
|
124
|
+
java: "java",
|
|
125
|
+
kt: "kotlin",
|
|
126
|
+
swift: "swift",
|
|
127
|
+
c: "c",
|
|
128
|
+
h: "c",
|
|
129
|
+
cc: "cpp",
|
|
130
|
+
cpp: "cpp",
|
|
131
|
+
hpp: "cpp",
|
|
132
|
+
cs: "csharp",
|
|
133
|
+
php: "php",
|
|
134
|
+
sh: "shell",
|
|
135
|
+
bash: "shell",
|
|
136
|
+
zsh: "shell",
|
|
137
|
+
sql: "sql",
|
|
138
|
+
md: "markdown",
|
|
139
|
+
json: "json",
|
|
140
|
+
yaml: "yaml",
|
|
141
|
+
yml: "yaml",
|
|
142
|
+
toml: "toml",
|
|
143
|
+
html: "html",
|
|
144
|
+
css: "css",
|
|
145
|
+
scss: "scss",
|
|
146
|
+
};
|
|
147
|
+
return map[ext] ?? ext;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=attrs.js.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry export configuration, resolved from the standard OpenTelemetry
|
|
3
|
+
* environment contract (the same variables Claude Code reads), so a machine
|
|
4
|
+
* or workspace already configured for Claude Code lights up YAGNI Code with
|
|
5
|
+
* no translation.
|
|
6
|
+
*
|
|
7
|
+
* Pure: reads an env record, never the network or disk. The launcher decides
|
|
8
|
+
* WHETHER a session exports (see the CLI's otel.ts: env, workspace settings,
|
|
9
|
+
* or a repo's committed config) and sets `YAGNI_OTEL_EXPORT=1` plus the OTLP
|
|
10
|
+
* variables in the child env; this module turns that env into per-signal
|
|
11
|
+
* exporter settings.
|
|
12
|
+
*
|
|
13
|
+
* Endpoint rules follow the OTLP exporter spec:
|
|
14
|
+
* - a per-signal endpoint (`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, …) is used
|
|
15
|
+
* verbatim;
|
|
16
|
+
* - the generic `OTEL_EXPORTER_OTLP_ENDPOINT` is a BASE: http transports
|
|
17
|
+
* append `/v1/<signal>`, gRPC uses it as-is;
|
|
18
|
+
* - nothing configured falls back to the local-collector defaults.
|
|
19
|
+
*
|
|
20
|
+
* Content policy is enforced here, not configurable: prompt and response
|
|
21
|
+
* text never export. `OTEL_LOG_USER_PROMPTS` and `OTEL_LOG_TOOL_DETAILS` are
|
|
22
|
+
* deliberately NOT honored — session content leaving the machine is a
|
|
23
|
+
* contract change, not an env knob.
|
|
24
|
+
*/
|
|
25
|
+
export type OtlpProtocol = "grpc" | "http/protobuf" | "http/json";
|
|
26
|
+
export type Signal = "traces" | "metrics" | "logs";
|
|
27
|
+
export declare const SIGNALS: readonly Signal[];
|
|
28
|
+
export interface SignalConfig {
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
protocol: OtlpProtocol;
|
|
31
|
+
/** The fully resolved URL this signal exports to. */
|
|
32
|
+
url: string;
|
|
33
|
+
headers: Record<string, string>;
|
|
34
|
+
/** Batch / periodic export interval in ms. */
|
|
35
|
+
exportIntervalMs: number;
|
|
36
|
+
}
|
|
37
|
+
export interface TelemetryIdentity {
|
|
38
|
+
/** Bound workspace id (YAGNI_WORKSPACE_ID) → `organization.id`. */
|
|
39
|
+
organizationId?: string;
|
|
40
|
+
/** The signed-in user's email when the launcher forwards it → `user.email`. */
|
|
41
|
+
userEmail?: string;
|
|
42
|
+
/** Shipping CLI version (YAGNI_CODE_VERSION) → `app.version`. */
|
|
43
|
+
appVersion?: string;
|
|
44
|
+
/** Detected terminal (TERM_PROGRAM / TMUX) → `terminal.type`. */
|
|
45
|
+
terminalType?: string;
|
|
46
|
+
/** `cli` for an interactive launch, `sdk-cli` for a headless /go run. */
|
|
47
|
+
entrypoint: "cli" | "sdk-cli";
|
|
48
|
+
}
|
|
49
|
+
export interface TelemetryConfig {
|
|
50
|
+
enabled: boolean;
|
|
51
|
+
serviceName: string;
|
|
52
|
+
serviceVersion?: string;
|
|
53
|
+
/** OTEL_RESOURCE_ATTRIBUTES, decoded. Applied to the resource and (by
|
|
54
|
+
* default) to every metric and event. */
|
|
55
|
+
resourceAttributes: Record<string, string>;
|
|
56
|
+
traces: SignalConfig;
|
|
57
|
+
metrics: SignalConfig;
|
|
58
|
+
logs: SignalConfig;
|
|
59
|
+
metricsTemporality: "delta" | "cumulative";
|
|
60
|
+
/** Cardinality controls (Claude Code parity). */
|
|
61
|
+
includeSessionId: boolean;
|
|
62
|
+
includeVersion: boolean;
|
|
63
|
+
includeAccountId: boolean;
|
|
64
|
+
includeResourceAttributes: boolean;
|
|
65
|
+
includeEntrypoint: boolean;
|
|
66
|
+
identity: TelemetryIdentity;
|
|
67
|
+
}
|
|
68
|
+
export declare const DEFAULT_SERVICE_NAME = "yagni-code";
|
|
69
|
+
type Env = Record<string, string | undefined>;
|
|
70
|
+
export declare function normalizeProtocol(p: string | undefined): OtlpProtocol | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* Parse a `k=v,k2=v2` list (OTEL_EXPORTER_OTLP_HEADERS / OTEL_RESOURCE_ATTRIBUTES).
|
|
73
|
+
* Values may be percent-encoded per the W3C baggage rules the spec references;
|
|
74
|
+
* a malformed escape keeps the raw value. Splits on the FIRST `=` only so a
|
|
75
|
+
* base64 value's trailing `==` survives.
|
|
76
|
+
*/
|
|
77
|
+
export declare function parseKvList(s: string | undefined): Record<string, string>;
|
|
78
|
+
/**
|
|
79
|
+
* Reduce an endpoint that carries a signal path to its base
|
|
80
|
+
* (`https://otlp.datadoghq.com/v1/traces` → `https://otlp.datadoghq.com`).
|
|
81
|
+
* Pre-parity workspace configs stored the full trace URL; treating it as a
|
|
82
|
+
* base keeps them exporting all three signals without an admin re-save.
|
|
83
|
+
*/
|
|
84
|
+
export declare function stripSignalPath(endpoint: string): string;
|
|
85
|
+
/**
|
|
86
|
+
* Resolve one signal's URL from the env, per the OTLP exporter spec.
|
|
87
|
+
* Exported for the launcher's doctor so its report names the exact URL a
|
|
88
|
+
* session will post to.
|
|
89
|
+
*/
|
|
90
|
+
export declare function resolveSignalUrl(env: Env, signal: Signal, protocol: OtlpProtocol): string;
|
|
91
|
+
/** Personal kill switch, beats every other source (both spellings accepted). */
|
|
92
|
+
export declare function telemetryDisabled(env: Env): boolean;
|
|
93
|
+
/** The launcher's "this session exports" gate. */
|
|
94
|
+
export declare const OTEL_EXPORT_ENV = "YAGNI_OTEL_EXPORT";
|
|
95
|
+
export declare function resolveTelemetryConfig(env?: Env): TelemetryConfig;
|
|
96
|
+
/** Signals this config will actually export (for doctor / status lines). */
|
|
97
|
+
export declare function enabledSignals(config: TelemetryConfig): Signal[];
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry export configuration, resolved from the standard OpenTelemetry
|
|
3
|
+
* environment contract (the same variables Claude Code reads), so a machine
|
|
4
|
+
* or workspace already configured for Claude Code lights up YAGNI Code with
|
|
5
|
+
* no translation.
|
|
6
|
+
*
|
|
7
|
+
* Pure: reads an env record, never the network or disk. The launcher decides
|
|
8
|
+
* WHETHER a session exports (see the CLI's otel.ts: env, workspace settings,
|
|
9
|
+
* or a repo's committed config) and sets `YAGNI_OTEL_EXPORT=1` plus the OTLP
|
|
10
|
+
* variables in the child env; this module turns that env into per-signal
|
|
11
|
+
* exporter settings.
|
|
12
|
+
*
|
|
13
|
+
* Endpoint rules follow the OTLP exporter spec:
|
|
14
|
+
* - a per-signal endpoint (`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, …) is used
|
|
15
|
+
* verbatim;
|
|
16
|
+
* - the generic `OTEL_EXPORTER_OTLP_ENDPOINT` is a BASE: http transports
|
|
17
|
+
* append `/v1/<signal>`, gRPC uses it as-is;
|
|
18
|
+
* - nothing configured falls back to the local-collector defaults.
|
|
19
|
+
*
|
|
20
|
+
* Content policy is enforced here, not configurable: prompt and response
|
|
21
|
+
* text never export. `OTEL_LOG_USER_PROMPTS` and `OTEL_LOG_TOOL_DETAILS` are
|
|
22
|
+
* deliberately NOT honored — session content leaving the machine is a
|
|
23
|
+
* contract change, not an env knob.
|
|
24
|
+
*/
|
|
25
|
+
export const SIGNALS = ["traces", "metrics", "logs"];
|
|
26
|
+
export const DEFAULT_SERVICE_NAME = "yagni-code";
|
|
27
|
+
const DEFAULT_GRPC_ENDPOINT = "http://localhost:4317";
|
|
28
|
+
const DEFAULT_HTTP_ENDPOINT = "http://localhost:4318";
|
|
29
|
+
const DEFAULT_INTERVALS_MS = { traces: 5_000, metrics: 60_000, logs: 5_000 };
|
|
30
|
+
const SIGNAL_ENV = { traces: "TRACES", metrics: "METRICS", logs: "LOGS" };
|
|
31
|
+
function envTrue(v) {
|
|
32
|
+
return v === "1" || v === "true";
|
|
33
|
+
}
|
|
34
|
+
function envBool(v, fallback) {
|
|
35
|
+
if (v === undefined || v.trim() === "")
|
|
36
|
+
return fallback;
|
|
37
|
+
const s = v.trim().toLowerCase();
|
|
38
|
+
if (s === "1" || s === "true" || s === "yes")
|
|
39
|
+
return true;
|
|
40
|
+
if (s === "0" || s === "false" || s === "no")
|
|
41
|
+
return false;
|
|
42
|
+
return fallback;
|
|
43
|
+
}
|
|
44
|
+
export function normalizeProtocol(p) {
|
|
45
|
+
if (!p)
|
|
46
|
+
return undefined;
|
|
47
|
+
const v = p.trim().toLowerCase();
|
|
48
|
+
if (v === "grpc")
|
|
49
|
+
return "grpc";
|
|
50
|
+
if (v === "http/protobuf" || v === "http-protobuf" || v === "http")
|
|
51
|
+
return "http/protobuf";
|
|
52
|
+
if (v === "http/json")
|
|
53
|
+
return "http/json";
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse a `k=v,k2=v2` list (OTEL_EXPORTER_OTLP_HEADERS / OTEL_RESOURCE_ATTRIBUTES).
|
|
58
|
+
* Values may be percent-encoded per the W3C baggage rules the spec references;
|
|
59
|
+
* a malformed escape keeps the raw value. Splits on the FIRST `=` only so a
|
|
60
|
+
* base64 value's trailing `==` survives.
|
|
61
|
+
*/
|
|
62
|
+
export function parseKvList(s) {
|
|
63
|
+
const out = {};
|
|
64
|
+
if (!s)
|
|
65
|
+
return out;
|
|
66
|
+
for (const pair of s.split(",")) {
|
|
67
|
+
const eq = pair.indexOf("=");
|
|
68
|
+
if (eq <= 0)
|
|
69
|
+
continue;
|
|
70
|
+
const k = pair.slice(0, eq).trim();
|
|
71
|
+
if (!k)
|
|
72
|
+
continue;
|
|
73
|
+
const raw = pair.slice(eq + 1).trim();
|
|
74
|
+
let v = raw;
|
|
75
|
+
try {
|
|
76
|
+
v = decodeURIComponent(raw);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
v = raw;
|
|
80
|
+
}
|
|
81
|
+
out[k] = v;
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
/** Trailing `/v1/<signal>` on a URL — the shape older workspace configs stored. */
|
|
86
|
+
const SIGNAL_PATH_RE = /\/v1\/(traces|metrics|logs)\/?$/i;
|
|
87
|
+
/**
|
|
88
|
+
* Reduce an endpoint that carries a signal path to its base
|
|
89
|
+
* (`https://otlp.datadoghq.com/v1/traces` → `https://otlp.datadoghq.com`).
|
|
90
|
+
* Pre-parity workspace configs stored the full trace URL; treating it as a
|
|
91
|
+
* base keeps them exporting all three signals without an admin re-save.
|
|
92
|
+
*/
|
|
93
|
+
export function stripSignalPath(endpoint) {
|
|
94
|
+
return endpoint.replace(SIGNAL_PATH_RE, "").replace(/\/+$/, "");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve one signal's URL from the env, per the OTLP exporter spec.
|
|
98
|
+
* Exported for the launcher's doctor so its report names the exact URL a
|
|
99
|
+
* session will post to.
|
|
100
|
+
*/
|
|
101
|
+
export function resolveSignalUrl(env, signal, protocol) {
|
|
102
|
+
const specific = env[`OTEL_EXPORTER_OTLP_${SIGNAL_ENV[signal]}_ENDPOINT`]?.trim();
|
|
103
|
+
if (specific)
|
|
104
|
+
return specific;
|
|
105
|
+
const generic = env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim();
|
|
106
|
+
if (protocol === "grpc")
|
|
107
|
+
return generic || DEFAULT_GRPC_ENDPOINT;
|
|
108
|
+
const base = stripSignalPath(generic || DEFAULT_HTTP_ENDPOINT);
|
|
109
|
+
return `${base}/v1/${signal}`;
|
|
110
|
+
}
|
|
111
|
+
/** Whether any per-signal endpoint variable is set. */
|
|
112
|
+
function anyPerSignalEndpoint(env) {
|
|
113
|
+
return SIGNALS.some((s) => Boolean(env[`OTEL_EXPORTER_OTLP_${SIGNAL_ENV[s]}_ENDPOINT`]?.trim()));
|
|
114
|
+
}
|
|
115
|
+
function resolveSignal(env, signal) {
|
|
116
|
+
const tag = SIGNAL_ENV[signal];
|
|
117
|
+
const protocol = normalizeProtocol(env[`OTEL_EXPORTER_OTLP_${tag}_PROTOCOL`]) ??
|
|
118
|
+
normalizeProtocol(env.OTEL_EXPORTER_OTLP_PROTOCOL) ??
|
|
119
|
+
"grpc";
|
|
120
|
+
const exporterSetting = env[`OTEL_${tag}_EXPORTER`]?.trim().toLowerCase();
|
|
121
|
+
// Claude Code gates each signal on OTEL_<SIGNAL>_EXPORTER; absent means on
|
|
122
|
+
// here (the launcher already decided this session exports), "none" turns
|
|
123
|
+
// one signal off.
|
|
124
|
+
const switchedOn = exporterSetting === undefined || exporterSetting === "" ? true : exporterSetting !== "none";
|
|
125
|
+
// A per-signal-only env (e.g. just OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, no
|
|
126
|
+
// generic endpoint) means the user configured exactly those signals: the
|
|
127
|
+
// others must not fall back to the localhost defaults and spray
|
|
128
|
+
// ECONNREFUSED at a collector nobody runs.
|
|
129
|
+
const hasOwnEndpoint = Boolean(env[`OTEL_EXPORTER_OTLP_${tag}_ENDPOINT`]?.trim());
|
|
130
|
+
const hasGenericEndpoint = Boolean(env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim());
|
|
131
|
+
const orphaned = !hasOwnEndpoint && !hasGenericEndpoint && anyPerSignalEndpoint(env);
|
|
132
|
+
const enabled = switchedOn && !orphaned;
|
|
133
|
+
const headers = {
|
|
134
|
+
...parseKvList(env.OTEL_EXPORTER_OTLP_HEADERS),
|
|
135
|
+
...parseKvList(env[`OTEL_EXPORTER_OTLP_${tag}_HEADERS`]),
|
|
136
|
+
};
|
|
137
|
+
const intervalRaw = Number(signal === "metrics"
|
|
138
|
+
? env.OTEL_METRIC_EXPORT_INTERVAL
|
|
139
|
+
: signal === "logs"
|
|
140
|
+
? env.OTEL_LOGS_EXPORT_INTERVAL
|
|
141
|
+
: env.OTEL_TRACES_EXPORT_INTERVAL);
|
|
142
|
+
const exportIntervalMs = Number.isFinite(intervalRaw) && intervalRaw > 0 ? intervalRaw : DEFAULT_INTERVALS_MS[signal];
|
|
143
|
+
return { enabled, protocol, url: resolveSignalUrl(env, signal, protocol), headers, exportIntervalMs };
|
|
144
|
+
}
|
|
145
|
+
function detectTerminal(env) {
|
|
146
|
+
if (env.TMUX)
|
|
147
|
+
return "tmux";
|
|
148
|
+
const tp = env.TERM_PROGRAM?.trim();
|
|
149
|
+
if (tp)
|
|
150
|
+
return tp;
|
|
151
|
+
return undefined;
|
|
152
|
+
}
|
|
153
|
+
/** Personal kill switch, beats every other source (both spellings accepted). */
|
|
154
|
+
export function telemetryDisabled(env) {
|
|
155
|
+
return envTrue(env.PI_OTEL_DISABLED) || envTrue(env.YAGNI_OTEL_DISABLED);
|
|
156
|
+
}
|
|
157
|
+
/** The launcher's "this session exports" gate. */
|
|
158
|
+
export const OTEL_EXPORT_ENV = "YAGNI_OTEL_EXPORT";
|
|
159
|
+
export function resolveTelemetryConfig(env = process.env) {
|
|
160
|
+
const enabled = envTrue(env[OTEL_EXPORT_ENV]) && !telemetryDisabled(env);
|
|
161
|
+
const temporality = env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE?.trim().toLowerCase();
|
|
162
|
+
const appVersion = env.YAGNI_CODE_VERSION?.trim() || undefined;
|
|
163
|
+
const organizationId = env.YAGNI_WORKSPACE_ID?.trim() || undefined;
|
|
164
|
+
const userEmail = env.YAGNI_USER_EMAIL?.trim() || undefined;
|
|
165
|
+
const terminalType = detectTerminal(env);
|
|
166
|
+
return {
|
|
167
|
+
enabled,
|
|
168
|
+
serviceName: env.OTEL_SERVICE_NAME?.trim() || DEFAULT_SERVICE_NAME,
|
|
169
|
+
...(appVersion ? { serviceVersion: appVersion } : {}),
|
|
170
|
+
resourceAttributes: parseKvList(env.OTEL_RESOURCE_ATTRIBUTES),
|
|
171
|
+
traces: resolveSignal(env, "traces"),
|
|
172
|
+
metrics: resolveSignal(env, "metrics"),
|
|
173
|
+
logs: resolveSignal(env, "logs"),
|
|
174
|
+
metricsTemporality: temporality === "cumulative" ? "cumulative" : "delta",
|
|
175
|
+
includeSessionId: envBool(env.OTEL_METRICS_INCLUDE_SESSION_ID, true),
|
|
176
|
+
includeVersion: envBool(env.OTEL_METRICS_INCLUDE_VERSION, false),
|
|
177
|
+
includeAccountId: envBool(env.OTEL_METRICS_INCLUDE_ACCOUNT_UUID, true),
|
|
178
|
+
includeResourceAttributes: envBool(env.OTEL_METRICS_INCLUDE_RESOURCE_ATTRIBUTES, true),
|
|
179
|
+
includeEntrypoint: envBool(env.OTEL_METRICS_INCLUDE_ENTRYPOINT, false),
|
|
180
|
+
identity: {
|
|
181
|
+
...(organizationId ? { organizationId } : {}),
|
|
182
|
+
...(userEmail ? { userEmail } : {}),
|
|
183
|
+
...(appVersion ? { appVersion } : {}),
|
|
184
|
+
...(terminalType ? { terminalType } : {}),
|
|
185
|
+
entrypoint: env.YAGNI_GO_HEADLESS === "1" ? "sdk-cli" : "cli",
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
/** Signals this config will actually export (for doctor / status lines). */
|
|
190
|
+
export function enabledSignals(config) {
|
|
191
|
+
return SIGNALS.filter((s) => config[s].enabled);
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { DEFAULT_SERVICE_NAME, OTEL_EXPORT_ENV, SIGNALS, enabledSignals, normalizeProtocol, parseKvList, resolveSignalUrl, resolveTelemetryConfig, stripSignalPath, telemetryDisabled, type OtlpProtocol, type Signal, type SignalConfig, type TelemetryConfig, type TelemetryIdentity, } from "./config.js";
|
|
2
|
+
export { PREFIX, type Decision, type DecisionSource } from "./attrs.js";
|
|
3
|
+
export { registerTelemetry, type RegisterTelemetryDeps, type TelemetryHandle } from "./register.js";
|
|
4
|
+
export { SessionTelemetry, countContentLines, countPatchLines, type ToolDecisionInput } from "./tracker.js";
|
|
5
|
+
export { createTelemetrySdk, type TelemetrySdk, type TelemetrySdkOptions } from "./sdk.js";
|
|
6
|
+
export { probeTelemetryExport, type SignalProbeResult, type TelemetryProbeReport } from "./probe.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { DEFAULT_SERVICE_NAME, OTEL_EXPORT_ENV, SIGNALS, enabledSignals, normalizeProtocol, parseKvList, resolveSignalUrl, resolveTelemetryConfig, stripSignalPath, telemetryDisabled, } from "./config.js";
|
|
2
|
+
export { PREFIX } from "./attrs.js";
|
|
3
|
+
export { registerTelemetry } from "./register.js";
|
|
4
|
+
export { SessionTelemetry, countContentLines, countPatchLines } from "./tracker.js";
|
|
5
|
+
export { createTelemetrySdk } from "./sdk.js";
|
|
6
|
+
export { probeTelemetryExport } from "./probe.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Doctor probe: send one real record per enabled signal and report the
|
|
3
|
+
* exporter's verdict. This is what `yagni doctor` runs, so its "otel export"
|
|
4
|
+
* line means "the collector ACCEPTED a span/metric/log with these headers",
|
|
5
|
+
* not "port 443 answered" — a wrong API key (403), a wrong path (404), or a
|
|
6
|
+
* protocol mismatch all show up as the real status.
|
|
7
|
+
*
|
|
8
|
+
* The probe records are tiny and clearly named (`yagni_code.doctor.probe`)
|
|
9
|
+
* so a customer can find them in their backend as proof the pipe works.
|
|
10
|
+
*/
|
|
11
|
+
import { type Signal, type TelemetryConfig } from "./config.js";
|
|
12
|
+
export interface SignalProbeResult {
|
|
13
|
+
signal: Signal;
|
|
14
|
+
url: string;
|
|
15
|
+
protocol: string;
|
|
16
|
+
ok: boolean;
|
|
17
|
+
/** One-line failure reason (status code, connection error) when !ok. */
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface TelemetryProbeReport {
|
|
21
|
+
config: TelemetryConfig;
|
|
22
|
+
results: SignalProbeResult[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run the probe against a config resolved from `env` (the launcher passes the
|
|
26
|
+
* exact child env a session would get). Never throws.
|
|
27
|
+
*/
|
|
28
|
+
export declare function probeTelemetryExport(env: NodeJS.ProcessEnv): Promise<TelemetryProbeReport>;
|
|
29
|
+
//# sourceMappingURL=probe.d.ts.map
|