@yagni-app/code-staging 1.0.5-staging.1241.1 → 1.0.6-staging.1244.1
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 +30 -6
- package/dist/doctor.d.ts +8 -3
- package/dist/doctor.js +38 -11
- package/dist/otel.d.ts +36 -7
- package/dist/otel.js +90 -12
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -179,11 +179,16 @@ children and subagents — emits a per-prompt span tree: interaction → LLM
|
|
|
179
179
|
request → tool calls, following the OTel GenAI semantic conventions. Nothing is
|
|
180
180
|
exported unless you configure an endpoint.
|
|
181
181
|
|
|
182
|
-
Enable it one of
|
|
183
|
-
|
|
184
|
-
- `OTEL_EXPORTER_OTLP_ENDPOINT
|
|
185
|
-
|
|
186
|
-
|
|
182
|
+
Enable it one of four ways (first match wins):
|
|
183
|
+
|
|
184
|
+
- `OTEL_EXPORTER_OTLP_ENDPOINT=…` in the environment (a personal override —
|
|
185
|
+
handy for pointing one session at a scratch collector), or
|
|
186
|
+
- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=…` in the environment — the per-signal
|
|
187
|
+
form Claude Code setups use (e.g.
|
|
188
|
+
`OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://otlp.datadoghq.com/v1/traces`
|
|
189
|
+
with `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf`); the launcher
|
|
190
|
+
bridges it to the generic var pi-otel reads, so a Claude Code OTel env
|
|
191
|
+
lights up YAGNI Code traces with no extra config, or
|
|
187
192
|
- **workspace settings** (the zero-setup path): a workspace admin sets the
|
|
188
193
|
endpoint, protocol, and any collector headers (e.g. a Datadog API key) once
|
|
189
194
|
in the web app under Settings → YAGNI Code → Trace export. Every session in
|
|
@@ -197,7 +202,26 @@ Enable it one of three ways (first match wins):
|
|
|
197
202
|
Standard OTel env vars are honored (`OTEL_EXPORTER_OTLP_PROTOCOL`,
|
|
198
203
|
`OTEL_EXPORTER_OTLP_HEADERS`, `OTEL_SERVICE_NAME` — defaults to `yagni-code`),
|
|
199
204
|
and `PI_OTEL_DISABLED=1` is the kill switch. `yagni doctor` shows the current
|
|
200
|
-
export state
|
|
205
|
+
export state and probes the endpoint live (unreachable → a warning with a
|
|
206
|
+
hint, never an exit-code flip).
|
|
207
|
+
|
|
208
|
+
Two recipes for common collectors:
|
|
209
|
+
|
|
210
|
+
- **Datadog, direct SaaS (no agent):** endpoint
|
|
211
|
+
`https://otlp.datadoghq.com/v1/traces` (US1; other sites have their own
|
|
212
|
+
host — `otlp.us3.datadoghq.com`, `otlp.us5.datadoghq.com`,
|
|
213
|
+
`otlp.datadoghq.eu`, `otlp.ap1.datadoghq.com`), protocol `http/protobuf`
|
|
214
|
+
(Datadog's direct trace intake does not accept gRPC), header
|
|
215
|
+
`dd-api-key=<your Datadog API key>`. Use the full path, not `/v1/` — the
|
|
216
|
+
endpoint is passed through verbatim, no path is appended for you.
|
|
217
|
+
- **Datadog Agent:** endpoint `http://<agent-host>:4317`, protocol `grpc`, no
|
|
218
|
+
key (the agent forwards with its own). OTLP ingest ships in the agent but
|
|
219
|
+
is off by default — enable it with
|
|
220
|
+
`otlp_config.receiver.protocols.grpc.endpoint: 0.0.0.0:4317` in
|
|
221
|
+
`datadog.yaml`.
|
|
222
|
+
- **Grafana Cloud:** endpoint `https://otlp-gateway-prod-…-0.grafana.net:443/otlp`,
|
|
223
|
+
protocol `http/protobuf`, header `authorization=<the raw MTgx… value>` (the
|
|
224
|
+
`Basic ` scheme is added for you).
|
|
201
225
|
|
|
202
226
|
Two things are enforced and not configurable:
|
|
203
227
|
|
package/dist/doctor.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* Advisory checks (loose perms, missing `gh`) never flip the exit code.
|
|
14
14
|
*/
|
|
15
15
|
import { type TokenExpiryStatus } from "./launch.js";
|
|
16
|
-
import { type OtelLaunchConfig } from "./otel.js";
|
|
16
|
+
import { probeOtelEndpoint, type OtelLaunchConfig } from "./otel.js";
|
|
17
17
|
import { type Profile } from "./profiles.js";
|
|
18
18
|
export type CheckStatus = "ok" | "warn" | "fail";
|
|
19
19
|
export interface CheckResult {
|
|
@@ -63,10 +63,15 @@ export declare function checkCliUpdate(probe: {
|
|
|
63
63
|
export declare function checkGh(onPath: boolean): CheckResult;
|
|
64
64
|
/**
|
|
65
65
|
* Advisory OTel-export line: says whether sessions will stream traces to an
|
|
66
|
-
* OTLP collector,
|
|
66
|
+
* OTLP collector, from which config source, and — when a collector is
|
|
67
|
+
* configured — whether the endpoint answers TCP right now (scheme-default
|
|
68
|
+
* ports included: https with no port probes 443). Never flips the exit code —
|
|
67
69
|
* most machines have no collector, and that is the healthy default.
|
|
68
70
|
*/
|
|
69
|
-
export declare function checkOtelExport(config: OtelLaunchConfig | undefined
|
|
71
|
+
export declare function checkOtelExport(config: OtelLaunchConfig | undefined, deps?: {
|
|
72
|
+
probeEndpoint?: typeof probeOtelEndpoint;
|
|
73
|
+
probeTimeoutMs?: number;
|
|
74
|
+
}): Promise<CheckResult>;
|
|
70
75
|
/** Config-only MCP snapshot (no connections — health checks live in `mcp list`/`get`). */
|
|
71
76
|
export interface McpProbe {
|
|
72
77
|
/** YAGNI_CODE_MCP_DISABLED kill-switch is active. */
|
package/dist/doctor.js
CHANGED
|
@@ -17,7 +17,7 @@ import { delimiter, join } from "node:path";
|
|
|
17
17
|
import { credentialsDir } from "./credentials.js";
|
|
18
18
|
import { currentCliVersion, fetchLatestVersion, isNewerVersion } from "./upgrade.js";
|
|
19
19
|
import { classifyTokenExpiry } from "./launch.js";
|
|
20
|
-
import { resolveOtelLaunchWithWorkspace } from "./otel.js";
|
|
20
|
+
import { probeOtelEndpoint, resolveOtelLaunchWithWorkspace, } from "./otel.js";
|
|
21
21
|
import { resolveExtensionPath, resolvePiCliPath, resolvePiPackageDir } from "./paths.js";
|
|
22
22
|
import { readActiveProfile } from "./profiles.js";
|
|
23
23
|
import { resolveMcpConfigPath } from "./mcpCommand.js";
|
|
@@ -202,10 +202,12 @@ export function checkGh(onPath) {
|
|
|
202
202
|
}
|
|
203
203
|
/**
|
|
204
204
|
* Advisory OTel-export line: says whether sessions will stream traces to an
|
|
205
|
-
* OTLP collector,
|
|
205
|
+
* OTLP collector, from which config source, and — when a collector is
|
|
206
|
+
* configured — whether the endpoint answers TCP right now (scheme-default
|
|
207
|
+
* ports included: https with no port probes 443). Never flips the exit code —
|
|
206
208
|
* most machines have no collector, and that is the healthy default.
|
|
207
209
|
*/
|
|
208
|
-
export function checkOtelExport(config) {
|
|
210
|
+
export async function checkOtelExport(config, deps = {}) {
|
|
209
211
|
if (!config) {
|
|
210
212
|
return {
|
|
211
213
|
name: "otel export (optional)",
|
|
@@ -215,16 +217,41 @@ export function checkOtelExport(config) {
|
|
|
215
217
|
};
|
|
216
218
|
}
|
|
217
219
|
const source = config.source === "env"
|
|
218
|
-
? "OTEL_EXPORTER_OTLP_ENDPOINT"
|
|
220
|
+
? (config.envVar ?? "OTEL_EXPORTER_OTLP_ENDPOINT")
|
|
219
221
|
: config.source === "workspace"
|
|
220
222
|
? "workspace settings"
|
|
221
223
|
: ".pi/settings.json";
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
const base = `on → ${config.endpoint} (${source}, metadata-only)`;
|
|
225
|
+
const doProbe = deps.probeEndpoint ?? probeOtelEndpoint;
|
|
226
|
+
try {
|
|
227
|
+
const reachable = await doProbe(config.endpoint, deps.probeTimeoutMs ?? 1_000);
|
|
228
|
+
return reachable
|
|
229
|
+
? {
|
|
230
|
+
name: "otel export (optional)",
|
|
231
|
+
status: "ok",
|
|
232
|
+
detail: `${base}, TCP reachable`,
|
|
233
|
+
required: false,
|
|
234
|
+
}
|
|
235
|
+
: {
|
|
236
|
+
name: "otel export (optional)",
|
|
237
|
+
status: "warn",
|
|
238
|
+
detail: `${base}, endpoint not reachable`,
|
|
239
|
+
hint: "the collector is down, unreachable from this machine, or the URL is wrong — traces will not export until it answers",
|
|
240
|
+
required: false,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
// The probe itself errored (not "endpoint down" — the check could not
|
|
245
|
+
// run). Distinct from a verified-healthy line so nobody reads an
|
|
246
|
+
// unverified config as checked-and-good.
|
|
247
|
+
return {
|
|
248
|
+
name: "otel export (optional)",
|
|
249
|
+
status: "warn",
|
|
250
|
+
detail: `${base}, reachability probe failed`,
|
|
251
|
+
hint: "the reachability check could not run (network error) — export is configured but unverified; traces may still export normally",
|
|
252
|
+
required: false,
|
|
253
|
+
};
|
|
254
|
+
}
|
|
228
255
|
}
|
|
229
256
|
/**
|
|
230
257
|
* Advisory (never required) MCP line: reports config health without connecting
|
|
@@ -489,7 +516,7 @@ export async function gatherChecks(deps = {}) {
|
|
|
489
516
|
checks.push(checkStateDir(probeStateDir()));
|
|
490
517
|
checks.push(checkGh(ghOnPath()));
|
|
491
518
|
checks.push(checkMcpConfig(await probeMcp()));
|
|
492
|
-
checks.push(checkOtelExport(await resolveOtelLaunchWithWorkspace({
|
|
519
|
+
checks.push(await checkOtelExport(await resolveOtelLaunchWithWorkspace({
|
|
493
520
|
env: process.env,
|
|
494
521
|
cwd: process.cwd(),
|
|
495
522
|
creds: profile.token ? { baseUrl: profile.baseUrl, token: profile.token } : null,
|
package/dist/otel.d.ts
CHANGED
|
@@ -43,13 +43,23 @@ export interface OtelLaunchConfig {
|
|
|
43
43
|
extensionPath: string;
|
|
44
44
|
/**
|
|
45
45
|
* Where the enablement signal came from. "workspace" additionally carries
|
|
46
|
-
* protocol/headers/serviceName, delivered as env to the session
|
|
47
|
-
*
|
|
46
|
+
* protocol/headers/serviceName, delivered as env to the session; "env" may
|
|
47
|
+
* carry a protocol when the endpoint arrived via the per-signal
|
|
48
|
+
* `OTEL_EXPORTER_OTLP_TRACES_(ENDPOINT|PROTOCOL)` bridge (pi-otel reads only
|
|
49
|
+
* the generic var, so the child env translates); "project-settings" leaves
|
|
50
|
+
* those to whatever the user/repo already configured.
|
|
48
51
|
*/
|
|
49
52
|
source: "env" | "workspace" | "project-settings";
|
|
53
|
+
/**
|
|
54
|
+
* The env var the endpoint actually came from — the generic
|
|
55
|
+
* `OTEL_EXPORTER_OTLP_ENDPOINT` or the per-signal
|
|
56
|
+
* `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`. Doctor surfaces it so a user who set
|
|
57
|
+
* the per-signal var sees their own var named, not the generic one.
|
|
58
|
+
*/
|
|
59
|
+
envVar?: "OTEL_EXPORTER_OTLP_ENDPOINT" | "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
|
|
50
60
|
/** The configured OTLP endpoint (for doctor display; env for workspace source). */
|
|
51
61
|
endpoint: string;
|
|
52
|
-
/**
|
|
62
|
+
/** OTLP protocol: workspace config, or a per-signal env bridge. */
|
|
53
63
|
protocol?: string;
|
|
54
64
|
/** Workspace-configured collector headers (workspace source only; carries secrets). */
|
|
55
65
|
headers?: Record<string, string>;
|
|
@@ -72,6 +82,15 @@ export interface WorkspaceOtelConfig {
|
|
|
72
82
|
* Decide whether this launch exports OTel traces, and with which pi-otel entry.
|
|
73
83
|
* Returns undefined when export stays off: no endpoint configured anywhere,
|
|
74
84
|
* `PI_OTEL_DISABLED` set, or the pi-otel package unresolvable (never fatal).
|
|
85
|
+
*
|
|
86
|
+
* Env sources, in precedence order: the generic `OTEL_EXPORTER_OTLP_ENDPOINT`,
|
|
87
|
+
* then the per-signal `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`. pi-otel only reads
|
|
88
|
+
* the generic var, so the per-signal one (the standard OTel env shape, and
|
|
89
|
+
* what Claude Code setups configure — e.g. Updater's) is bridged: the traces
|
|
90
|
+
* endpoint becomes the generic one, and a per-signal TRACES_PROTOCOL carries
|
|
91
|
+
* over the same way. Logs/metrics per-signal vars are deliberately NOT read:
|
|
92
|
+
* sessions export traces only, and pi-otel's metrics/logs signals are opt-in
|
|
93
|
+
* elsewhere.
|
|
75
94
|
*/
|
|
76
95
|
export declare function resolveOtelLaunch(opts: {
|
|
77
96
|
env: NodeJS.ProcessEnv;
|
|
@@ -80,13 +99,21 @@ export declare function resolveOtelLaunch(opts: {
|
|
|
80
99
|
resolveExtension?: () => string;
|
|
81
100
|
readFile?: typeof readFileSync;
|
|
82
101
|
}): OtelLaunchConfig | undefined;
|
|
83
|
-
/**
|
|
84
|
-
* Absolute path to pi-otel's extension entry (its package main IS the pi
|
|
102
|
+
/** Absolute path to pi-otel's extension entry (its package main IS the pi
|
|
85
103
|
* extension entry, `dist/index.js`). Resolved ESM-native like `paths.ts` does
|
|
86
104
|
* for pi itself. Throws when the package is missing — callers treat that as
|
|
87
105
|
* "export off", not an error.
|
|
88
106
|
*/
|
|
89
107
|
export declare function resolveOtelExtensionPath(): string;
|
|
108
|
+
/**
|
|
109
|
+
* TCP reachability probe for an OTLP endpoint URL, with scheme-default ports:
|
|
110
|
+
* WHATWG `URL` strips `:443`/`:80` as defaults, so an https endpoint with no
|
|
111
|
+
* port probes 443 (the agentless SaaS shape). Returns false on any parse or
|
|
112
|
+
* connect failure — reachability is advisory, never fatal. Mirrors the probe
|
|
113
|
+
* inside (patched) pi-otel but lives here so `doctor` can use it without
|
|
114
|
+
* importing the extension's SDK graph.
|
|
115
|
+
*/
|
|
116
|
+
export declare function probeOtelEndpoint(endpoint: string, timeoutMs?: number): Promise<boolean>;
|
|
90
117
|
/**
|
|
91
118
|
* The env keys an OTel-exporting child must carry. `PI_OTEL_CAPTURE_CONTENT`
|
|
92
119
|
* is pinned unconditionally (policy 2 above); the service name only fills in
|
|
@@ -125,10 +152,12 @@ export declare function fetchWorkspaceOtel(creds: {
|
|
|
125
152
|
token: string;
|
|
126
153
|
}, profileName: string, deps?: WorkspaceOtelFetchDeps): Promise<WorkspaceOtelConfig | null>;
|
|
127
154
|
/**
|
|
128
|
-
* Full launch-time resolution, all
|
|
155
|
+
* Full launch-time resolution, all four sources in precedence order:
|
|
129
156
|
*
|
|
130
157
|
* 1. `PI_OTEL_DISABLED` — personal kill switch, beats everything.
|
|
131
|
-
* 2. env `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
158
|
+
* 2. env `OTEL_EXPORTER_OTLP_ENDPOINT` / `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
|
|
159
|
+
* — the user's own setup, untouched (generic wins
|
|
160
|
+
* over per-signal).
|
|
132
161
|
* 3. workspace config — admin-set in the web app, fetched/cached.
|
|
133
162
|
* 4. repo `.pi/settings.json` — committed per-repo config.
|
|
134
163
|
*
|
package/dist/otel.js
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* missing package or unreadable settings file resolves to "disabled".
|
|
30
30
|
*/
|
|
31
31
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
32
|
+
import { createConnection } from "node:net";
|
|
32
33
|
import { join } from "node:path";
|
|
33
34
|
import { fileURLToPath } from "node:url";
|
|
34
35
|
import { credentialsDir } from "./credentials.js";
|
|
@@ -71,16 +72,25 @@ function envDisabled(env) {
|
|
|
71
72
|
* Decide whether this launch exports OTel traces, and with which pi-otel entry.
|
|
72
73
|
* Returns undefined when export stays off: no endpoint configured anywhere,
|
|
73
74
|
* `PI_OTEL_DISABLED` set, or the pi-otel package unresolvable (never fatal).
|
|
75
|
+
*
|
|
76
|
+
* Env sources, in precedence order: the generic `OTEL_EXPORTER_OTLP_ENDPOINT`,
|
|
77
|
+
* then the per-signal `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`. pi-otel only reads
|
|
78
|
+
* the generic var, so the per-signal one (the standard OTel env shape, and
|
|
79
|
+
* what Claude Code setups configure — e.g. Updater's) is bridged: the traces
|
|
80
|
+
* endpoint becomes the generic one, and a per-signal TRACES_PROTOCOL carries
|
|
81
|
+
* over the same way. Logs/metrics per-signal vars are deliberately NOT read:
|
|
82
|
+
* sessions export traces only, and pi-otel's metrics/logs signals are opt-in
|
|
83
|
+
* elsewhere.
|
|
74
84
|
*/
|
|
75
85
|
export function resolveOtelLaunch(opts) {
|
|
76
86
|
const { env, cwd } = opts;
|
|
77
87
|
if (envDisabled(env))
|
|
78
88
|
return undefined;
|
|
79
89
|
const envEndpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim();
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (!envEndpoint && !settingsEndpoint)
|
|
90
|
+
const tracesEndpoint = env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?.trim();
|
|
91
|
+
const usingPerSignal = !envEndpoint && !!tracesEndpoint;
|
|
92
|
+
const settingsEndpoint = envEndpoint || tracesEndpoint ? undefined : projectOtelEndpoint(cwd, opts.readFile ?? readFileSync);
|
|
93
|
+
if (!envEndpoint && !tracesEndpoint && !settingsEndpoint)
|
|
84
94
|
return undefined;
|
|
85
95
|
let extensionPath;
|
|
86
96
|
try {
|
|
@@ -89,12 +99,28 @@ export function resolveOtelLaunch(opts) {
|
|
|
89
99
|
catch {
|
|
90
100
|
return undefined;
|
|
91
101
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
102
|
+
if (envEndpoint) {
|
|
103
|
+
return {
|
|
104
|
+
extensionPath,
|
|
105
|
+
source: "env",
|
|
106
|
+
envVar: "OTEL_EXPORTER_OTLP_ENDPOINT",
|
|
107
|
+
endpoint: envEndpoint,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (usingPerSignal) {
|
|
111
|
+
return {
|
|
112
|
+
extensionPath,
|
|
113
|
+
source: "env",
|
|
114
|
+
envVar: "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
|
115
|
+
endpoint: tracesEndpoint,
|
|
116
|
+
...(env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL?.trim()
|
|
117
|
+
? { protocol: env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL.trim() }
|
|
118
|
+
: {}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return { extensionPath, source: "project-settings", endpoint: settingsEndpoint };
|
|
95
122
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Absolute path to pi-otel's extension entry (its package main IS the pi
|
|
123
|
+
/** Absolute path to pi-otel's extension entry (its package main IS the pi
|
|
98
124
|
* extension entry, `dist/index.js`). Resolved ESM-native like `paths.ts` does
|
|
99
125
|
* for pi itself. Throws when the package is missing — callers treat that as
|
|
100
126
|
* "export off", not an error.
|
|
@@ -106,6 +132,45 @@ export function resolveOtelExtensionPath() {
|
|
|
106
132
|
}
|
|
107
133
|
return path;
|
|
108
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* TCP reachability probe for an OTLP endpoint URL, with scheme-default ports:
|
|
137
|
+
* WHATWG `URL` strips `:443`/`:80` as defaults, so an https endpoint with no
|
|
138
|
+
* port probes 443 (the agentless SaaS shape). Returns false on any parse or
|
|
139
|
+
* connect failure — reachability is advisory, never fatal. Mirrors the probe
|
|
140
|
+
* inside (patched) pi-otel but lives here so `doctor` can use it without
|
|
141
|
+
* importing the extension's SDK graph.
|
|
142
|
+
*/
|
|
143
|
+
export async function probeOtelEndpoint(endpoint, timeoutMs = 1_000) {
|
|
144
|
+
let host;
|
|
145
|
+
let port;
|
|
146
|
+
try {
|
|
147
|
+
const u = new URL(endpoint);
|
|
148
|
+
host = u.hostname;
|
|
149
|
+
port = u.port
|
|
150
|
+
? Number(u.port)
|
|
151
|
+
: u.protocol === "https:"
|
|
152
|
+
? 443
|
|
153
|
+
: u.protocol === "http:"
|
|
154
|
+
? 80
|
|
155
|
+
: null;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
if (!host || !port)
|
|
161
|
+
return false;
|
|
162
|
+
return new Promise((resolve) => {
|
|
163
|
+
const sock = createConnection({ host, port });
|
|
164
|
+
const done = (ok) => {
|
|
165
|
+
sock.destroy();
|
|
166
|
+
resolve(ok);
|
|
167
|
+
};
|
|
168
|
+
sock.setTimeout(timeoutMs);
|
|
169
|
+
sock.once("connect", () => done(true));
|
|
170
|
+
sock.once("timeout", () => done(false));
|
|
171
|
+
sock.once("error", () => done(false));
|
|
172
|
+
});
|
|
173
|
+
}
|
|
109
174
|
/**
|
|
110
175
|
* The env keys an OTel-exporting child must carry. `PI_OTEL_CAPTURE_CONTENT`
|
|
111
176
|
* is pinned unconditionally (policy 2 above); the service name only fills in
|
|
@@ -135,6 +200,17 @@ export function otelChildEnv(config, baseEnv) {
|
|
|
135
200
|
workspace.OTEL_SERVICE_NAME = config.serviceName;
|
|
136
201
|
}
|
|
137
202
|
}
|
|
203
|
+
else if (config.source === "env" && config.protocol) {
|
|
204
|
+
// The per-signal bridge: the endpoint came from
|
|
205
|
+
// OTEL_EXPORTER_OTLP_TRACES_ENDPOINT (+ TRACES_PROTOCOL), which pi-otel
|
|
206
|
+
// does not read — deliver them as the generic vars the extension resolves.
|
|
207
|
+
if (!baseEnv.OTEL_EXPORTER_OTLP_ENDPOINT) {
|
|
208
|
+
workspace.OTEL_EXPORTER_OTLP_ENDPOINT = config.endpoint;
|
|
209
|
+
}
|
|
210
|
+
if (!baseEnv.OTEL_EXPORTER_OTLP_PROTOCOL) {
|
|
211
|
+
workspace.OTEL_EXPORTER_OTLP_PROTOCOL = config.protocol;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
138
214
|
return {
|
|
139
215
|
...workspace,
|
|
140
216
|
[OTEL_EXTENSION_PATH_ENV]: config.extensionPath,
|
|
@@ -235,10 +311,12 @@ function readWorkspaceOtelCache(cachePath) {
|
|
|
235
311
|
}
|
|
236
312
|
}
|
|
237
313
|
/**
|
|
238
|
-
* Full launch-time resolution, all
|
|
314
|
+
* Full launch-time resolution, all four sources in precedence order:
|
|
239
315
|
*
|
|
240
316
|
* 1. `PI_OTEL_DISABLED` — personal kill switch, beats everything.
|
|
241
|
-
* 2. env `OTEL_EXPORTER_OTLP_ENDPOINT`
|
|
317
|
+
* 2. env `OTEL_EXPORTER_OTLP_ENDPOINT` / `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`
|
|
318
|
+
* — the user's own setup, untouched (generic wins
|
|
319
|
+
* over per-signal).
|
|
242
320
|
* 3. workspace config — admin-set in the web app, fetched/cached.
|
|
243
321
|
* 4. repo `.pi/settings.json` — committed per-repo config.
|
|
244
322
|
*
|
|
@@ -249,7 +327,7 @@ export async function resolveOtelLaunchWithWorkspace(opts) {
|
|
|
249
327
|
if (envDisabled(env))
|
|
250
328
|
return undefined;
|
|
251
329
|
// Source 2: the user's own env config short-circuits — no fetch needed.
|
|
252
|
-
if (env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim()) {
|
|
330
|
+
if (env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim() || env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?.trim()) {
|
|
253
331
|
return resolveOtelLaunch({
|
|
254
332
|
env,
|
|
255
333
|
cwd,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yagni-app/code-staging",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6-staging.1244.1",
|
|
4
4
|
"description": "YAGNI Code: a terminal coding agent that already knows your company. One YAGNI login routes the model and grounds the agent in your team's context.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "YAGNI, Inc. <jack@yagni.app> (https://yagni.app)",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"turndown": "^7.2.4",
|
|
43
43
|
"typebox": "^1.3.15"
|
|
44
44
|
},
|
|
45
|
-
"yagniSourceSha": "
|
|
45
|
+
"yagniSourceSha": "09cd57add6ba5c3028cc4f971459d5c7f9d4da97"
|
|
46
46
|
}
|