open-azdo 0.1.0 → 0.1.2

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 CHANGED
@@ -19,7 +19,7 @@ The CLI consumes the Azure Pipeline checkout workspace directly and uses the bui
19
19
  Use Bun 1.3.10 or newer.
20
20
 
21
21
  ```bash
22
- bunx open-azdo review --model "openai/gpt-5.4"
22
+ bun x open-azdo review --model "openai/gpt-5.4"
23
23
  ```
24
24
 
25
25
  Required inputs:
@@ -56,6 +56,7 @@ Exit behavior:
56
56
  ## Azure Pipelines
57
57
 
58
58
  The canonical example is in [examples/azure-pipelines.review.yml](/home/ponbac/dev/open-azdo/examples/azure-pipelines.review.yml).
59
+ For first-time rollout or debugging, use [examples/azure-pipelines.review.debug.yml](/home/ponbac/dev/open-azdo/examples/azure-pipelines.review.debug.yml).
59
60
 
60
61
  Key requirements:
61
62
 
@@ -90,7 +91,7 @@ steps:
90
91
  tar -xzf opencode.tar.gz -C opencode-bin
91
92
  export PATH="$PWD/opencode-bin:$PATH"
92
93
 
93
- bunx open-azdo review --model "$(OpenCodeModel)"
94
+ bun x open-azdo review --model "$(OpenCodeModel)"
94
95
  displayName: Review Pull Request
95
96
  env:
96
97
  SYSTEM_ACCESSTOKEN: $(System.AccessToken)
package/dist/open-azdo.js CHANGED
@@ -1674,6 +1674,7 @@ var keys = (self) => Object.keys(self);
1674
1674
  var Array3 = globalThis.Array;
1675
1675
  var allocate = (n) => new Array3(n);
1676
1676
  var fromIterable2 = (collection) => Array3.isArray(collection) ? collection : Array3.from(collection);
1677
+ var ensure = (self) => Array3.isArray(self) ? self : [self];
1677
1678
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
1678
1679
  var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable2(self).concat(fromIterable2(that)));
1679
1680
  var isArray = Array3.isArray;
@@ -4687,6 +4688,18 @@ var formatLogSpan = (self, now) => {
4687
4688
  const label = formatLabel(self[0]);
4688
4689
  return `${label}=${now - self[1]}ms`;
4689
4690
  };
4691
+ var structuredMessage = (u) => {
4692
+ switch (typeof u) {
4693
+ case "bigint":
4694
+ case "function":
4695
+ case "symbol": {
4696
+ return String(u);
4697
+ }
4698
+ default: {
4699
+ return toJson(u);
4700
+ }
4701
+ }
4702
+ };
4690
4703
  var logWithLevel = (level) => (...message) => {
4691
4704
  let cause = undefined;
4692
4705
  for (let i = 0, len = message.length;i < len; i++) {
@@ -25751,10 +25764,10 @@ var toCodecEnsureArray = /* @__PURE__ */ toCodec((ast) => {
25751
25764
  }
25752
25765
  const out = onSerializerEnsureArray(ast);
25753
25766
  if (isArrays(out)) {
25754
- const ensure = new Union([out, decodeTo(string2, out, new Transformation(split(), passthrough2()))], "anyOf", {
25767
+ const ensure2 = new Union([out, decodeTo(string2, out, new Transformation(split(), passthrough2()))], "anyOf", {
25755
25768
  [SERIALIZER_ENSURE_ARRAY]: true
25756
25769
  });
25757
- return isOptional(ast) ? optionalKey(ensure) : ensure;
25770
+ return isOptional(ast) ? optionalKey(ensure2) : ensure2;
25758
25771
  }
25759
25772
  return out;
25760
25773
  });
@@ -28099,13 +28112,82 @@ var splitByWhitespaces = (template, rawTemplate) => {
28099
28112
  };
28100
28113
  var concatTokens = (prevTokens, nextTokens, isSeparated) => isSeparated || prevTokens.length === 0 || nextTokens.length === 0 ? [...prevTokens, ...nextTokens] : [...prevTokens.slice(0, -1), `${prevTokens.at(-1)}${nextTokens.at(0)}`, ...nextTokens.slice(1)];
28101
28114
 
28115
+ // src/logging.ts
28116
+ var REDACTED = "<redacted>";
28117
+ var DEFAULT_PREVIEW_LENGTH = 400;
28118
+ var sanitizeForLog = (value3) => {
28119
+ if (exports_Redacted.isRedacted(value3)) {
28120
+ return REDACTED;
28121
+ }
28122
+ if (value3 instanceof Error) {
28123
+ return {
28124
+ name: value3.name,
28125
+ message: value3.message
28126
+ };
28127
+ }
28128
+ if (Array.isArray(value3)) {
28129
+ return value3.map(sanitizeForLog);
28130
+ }
28131
+ if (value3 && typeof value3 === "object") {
28132
+ return Object.fromEntries(Object.entries(value3).map(([key, nested]) => [
28133
+ key,
28134
+ key.toLowerCase().includes("token") || key.toLowerCase().includes("secret") ? REDACTED : sanitizeForLog(nested)
28135
+ ]));
28136
+ }
28137
+ return value3;
28138
+ };
28139
+ var truncateForLog = (value3, maxLength = DEFAULT_PREVIEW_LENGTH) => {
28140
+ if (value3.length <= maxLength) {
28141
+ return value3;
28142
+ }
28143
+ return `${value3.slice(0, maxLength)}... [truncated ${value3.length - maxLength} chars]`;
28144
+ };
28145
+ var withSanitizedAnnotations = (effect2, fields) => {
28146
+ if (!fields || Object.keys(fields).length === 0) {
28147
+ return effect2;
28148
+ }
28149
+ return effect2.pipe(exports_Effect.annotateLogs(sanitizeForLog(fields)));
28150
+ };
28151
+ var withLogAnnotations = (fields) => (effect2) => {
28152
+ if (!fields || Object.keys(fields).length === 0) {
28153
+ return effect2;
28154
+ }
28155
+ return effect2.pipe(exports_Effect.annotateLogs(sanitizeForLog(fields)));
28156
+ };
28157
+ var logInfo2 = (message, fields) => withSanitizedAnnotations(exports_Effect.logInfo(message), fields);
28158
+ var logError2 = (message, fields) => withSanitizedAnnotations(exports_Effect.logError(message), fields);
28159
+
28102
28160
  // src/process.ts
28103
28161
  var DEFAULT_TIMEOUT_MS = 30000;
28104
28162
  var DEFAULT_MAX_OUTPUT_BYTES = 1e6;
28105
- var commandLabel = (input) => [input.command, ...input.args].join(" ");
28163
+ var summarizeArg = (arg) => {
28164
+ if (arg.includes(`
28165
+ `) || arg.length > 160) {
28166
+ return `[${arg.length} chars omitted]`;
28167
+ }
28168
+ return truncateForLog(arg, 160);
28169
+ };
28170
+ var summarizeArgs = (args2) => args2.map(summarizeArg);
28171
+ var commandLabel = (input) => [input.command, ...summarizeArgs(input.args)].join(" ");
28172
+ var commandLogFields = (input, timeoutMs, maxOutputBytes) => ({
28173
+ operation: input.operation,
28174
+ command: input.command,
28175
+ args: summarizeArgs(input.args),
28176
+ cwd: input.cwd ?? "",
28177
+ timeoutMs,
28178
+ maxOutputBytes,
28179
+ allowNonZeroExit: input.allowNonZeroExit ?? false,
28180
+ stdinBytes: input.stdin?.length ?? 0
28181
+ });
28182
+ var commandResultLogFields = (input, timeoutMs, maxOutputBytes, result3) => ({
28183
+ ...commandLogFields(input, timeoutMs, maxOutputBytes),
28184
+ exitCode: result3.exitCode,
28185
+ stdoutBytes: result3.stdout.length,
28186
+ stderrBytes: result3.stderr.length
28187
+ });
28106
28188
  var toCommandExecutionError = (input, detail, stderr = "", exitCode = -1) => new CommandExecutionError({
28107
28189
  operation: input.operation,
28108
- command: [input.command, ...input.args],
28190
+ command: [input.command, ...summarizeArgs(input.args)],
28109
28191
  cwd: input.cwd ?? "",
28110
28192
  detail,
28111
28193
  stderr,
@@ -28133,6 +28215,7 @@ class ProcessRunner extends Service()("open-azdo/ProcessRunner") {
28133
28215
  const timeoutMs = input.timeoutMs ?? DEFAULT_TIMEOUT_MS;
28134
28216
  const maxOutputBytes = input.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
28135
28217
  const encodedStdin = input.stdin === undefined ? "ignore" : fromIterable8([new TextEncoder().encode(input.stdin)]);
28218
+ yield* logInfo2("Starting command.", commandLogFields(input, timeoutMs, maxOutputBytes));
28136
28219
  const command = make28(input.command, [...input.args], {
28137
28220
  ...input.cwd ? { cwd: input.cwd } : {},
28138
28221
  ...input.env ? { env: input.env, extendEnv: false } : {},
@@ -28148,7 +28231,7 @@ class ProcessRunner extends Service()("open-azdo/ProcessRunner") {
28148
28231
  handle.exitCode.pipe(exports_Effect.map((value3) => Number(value3)), exports_Effect.mapError(() => toCommandExecutionError(input, `Failed to read exit code for ${commandLabel(input)}.`)))
28149
28232
  ], { concurrency: "unbounded" });
28150
28233
  if (exitCode !== 0 && !input.allowNonZeroExit) {
28151
- return yield* toCommandExecutionError(input, stderr.trim().length > 0 ? `${commandLabel(input)} failed: ${stderr.trim()}` : `${commandLabel(input)} failed.`, stderr, exitCode);
28234
+ return yield* toCommandExecutionError(input, stderr.trim().length > 0 ? `${commandLabel(input)} failed: ${truncateForLog(stderr.trim())}` : `${commandLabel(input)} failed.`, stderr, exitCode);
28152
28235
  }
28153
28236
  return {
28154
28237
  exitCode,
@@ -28158,7 +28241,12 @@ class ProcessRunner extends Service()("open-azdo/ProcessRunner") {
28158
28241
  }).pipe(exports_Effect.scoped, exports_Effect.timeoutOption(timeoutMs), exports_Effect.flatMap((maybeResult) => exports_Option.match(maybeResult, {
28159
28242
  onNone: () => exports_Effect.fail(toCommandExecutionError(input, `${commandLabel(input)} timed out after ${timeoutMs}ms.`)),
28160
28243
  onSome: exports_Effect.succeed
28161
- })));
28244
+ })), exports_Effect.tap((result3) => logInfo2("Command completed.", commandResultLogFields(input, timeoutMs, maxOutputBytes, result3))), exports_Effect.tapError((error) => logError2("Command failed.", {
28245
+ ...commandLogFields(input, timeoutMs, maxOutputBytes),
28246
+ detail: error.detail,
28247
+ exitCode: error.exitCode,
28248
+ stderrPreview: truncateForLog(error.stderr || error.detail)
28249
+ })), exports_Effect.withLogSpan(input.operation));
28162
28250
  });
28163
28251
  return ProcessRunner.of({
28164
28252
  execute
@@ -28342,46 +28430,6 @@ var runGit = exports_Effect.fn("git.runGit")(function* (cwd, args2, allowFailure
28342
28430
  return yield* git.runGit(cwd, args2, allowFailure);
28343
28431
  });
28344
28432
 
28345
- // src/logging.ts
28346
- var REDACTED = "<redacted>";
28347
- var sanitizeForLog = (value3) => {
28348
- if (exports_Redacted.isRedacted(value3)) {
28349
- return REDACTED;
28350
- }
28351
- if (value3 instanceof Error) {
28352
- return {
28353
- name: value3.name,
28354
- message: value3.message
28355
- };
28356
- }
28357
- if (Array.isArray(value3)) {
28358
- return value3.map(sanitizeForLog);
28359
- }
28360
- if (value3 && typeof value3 === "object") {
28361
- return Object.fromEntries(Object.entries(value3).map(([key, nested]) => [
28362
- key,
28363
- key.toLowerCase().includes("token") || key.toLowerCase().includes("secret") ? REDACTED : sanitizeForLog(nested)
28364
- ]));
28365
- }
28366
- return value3;
28367
- };
28368
- var renderLogLine = (level, message, fields) => {
28369
- const sanitizedFields = sanitizeForLog(fields ?? {});
28370
- return JSON.stringify({
28371
- level,
28372
- message,
28373
- ...sanitizedFields
28374
- });
28375
- };
28376
- var writeLogLine = exports_Effect.fn("logging.writeLogLine")(function* (streamName, line) {
28377
- const stdio = yield* Stdio2;
28378
- const sink = streamName === "stdout" ? stdio.stdout() : stdio.stderr();
28379
- yield* make24(`${line}
28380
- `).pipe(run2(sink));
28381
- });
28382
- var writeInfoLog = (message, fields) => writeLogLine("stdout", renderLogLine("info", message, fields));
28383
- var writeErrorLog = (message, fields) => writeLogLine("stderr", renderLogLine("error", message, fields));
28384
-
28385
28433
  // src/opencode.ts
28386
28434
  var buildOpenCodeConfig = (agentName) => ({
28387
28435
  $schema: "https://opencode.ai/config.json",
@@ -28473,6 +28521,12 @@ class OpenCodeService extends Service()("open-azdo/OpenCodeService") {
28473
28521
  const runtimeInput = yield* RuntimeInput;
28474
28522
  const run3 = exports_Effect.fn("OpenCodeService.run")(function* (config, prompt) {
28475
28523
  return yield* exports_Effect.gen(function* () {
28524
+ yield* logInfo2("Preparing OpenCode execution.", {
28525
+ agent: config.agent,
28526
+ model: config.model,
28527
+ workspace: config.workspace,
28528
+ promptChars: prompt.length
28529
+ });
28476
28530
  const tempDir = yield* fileSystem.makeTempDirectoryScoped({
28477
28531
  prefix: "open-azdo-opencode-"
28478
28532
  }).pipe(exports_Effect.mapError((error) => new OpenCodeOutputError({
@@ -28488,6 +28542,11 @@ class OpenCodeService extends Service()("open-azdo/OpenCodeService") {
28488
28542
  message: "Failed to write temporary OpenCode configuration.",
28489
28543
  output: String(error)
28490
28544
  })));
28545
+ yield* logInfo2("Prepared temporary OpenCode files.", {
28546
+ tempDir,
28547
+ configPath,
28548
+ promptPath
28549
+ });
28491
28550
  const result3 = yield* runner.execute({
28492
28551
  operation: "OpenCodeService.run",
28493
28552
  command: "opencode",
@@ -28504,20 +28563,34 @@ class OpenCodeService extends Service()("open-azdo/OpenCodeService") {
28504
28563
  stderr: error.stderr,
28505
28564
  exitCode: error.exitCode
28506
28565
  })));
28566
+ yield* logInfo2("OpenCode process exited.", {
28567
+ exitCode: result3.exitCode,
28568
+ stdoutBytes: result3.stdout.length,
28569
+ stderrBytes: result3.stderr.length
28570
+ });
28507
28571
  if (result3.exitCode !== 0) {
28572
+ yield* logError2("OpenCode exited with a non-zero status.", {
28573
+ exitCode: result3.exitCode,
28574
+ stderrPreview: truncateForLog(result3.stderr)
28575
+ });
28508
28576
  return yield* new OpenCodeInvocationError({
28509
28577
  message: "OpenCode exited with a non-zero status.",
28510
28578
  stderr: result3.stderr,
28511
28579
  exitCode: result3.exitCode
28512
28580
  });
28513
28581
  }
28514
- return yield* exports_Effect.try({
28582
+ const response = yield* exports_Effect.try({
28515
28583
  try: () => extractFinalResponse(result3.stdout),
28516
28584
  catch: (error) => error instanceof OpenCodeOutputError ? error : new OpenCodeOutputError({
28517
28585
  message: "OpenCode did not return a valid final response.",
28518
28586
  output: String(error)
28519
28587
  })
28520
28588
  });
28589
+ yield* logInfo2("Extracted final OpenCode response.", {
28590
+ responseChars: response.length,
28591
+ responsePreview: truncateForLog(response)
28592
+ });
28593
+ return response;
28521
28594
  }).pipe(exports_Effect.scoped);
28522
28595
  });
28523
28596
  return OpenCodeService.of({
@@ -28592,58 +28665,88 @@ var writeStdout = exports_Effect.fn("cli.writeStdout")(function* (text) {
28592
28665
  const stdio = yield* Stdio2;
28593
28666
  yield* make24(text).pipe(run2(stdio.stdout()));
28594
28667
  });
28668
+ var reviewLogFields = (config) => ({
28669
+ command: config.command,
28670
+ model: config.model,
28671
+ workspace: config.workspace,
28672
+ organization: config.organization,
28673
+ project: config.project,
28674
+ repositoryId: config.repositoryId,
28675
+ pullRequestId: config.pullRequestId,
28676
+ collectionUrl: config.collectionUrl,
28677
+ agent: config.agent,
28678
+ dryRun: config.dryRun,
28679
+ json: config.json
28680
+ });
28595
28681
  var runReviewWithConfig = exports_Effect.fn("cli.runReviewWithConfig")(function* (config) {
28596
- const azureContext = createAzureContext(config);
28597
- yield* writeInfoLog("Resolved review configuration.", {
28598
- command: config.command,
28599
- model: config.model,
28600
- workspace: config.workspace,
28601
- organization: config.organization,
28602
- project: config.project,
28603
- repositoryId: config.repositoryId,
28604
- pullRequestId: config.pullRequestId,
28605
- collectionUrl: config.collectionUrl,
28606
- agent: config.agent,
28607
- dryRun: config.dryRun,
28608
- json: config.json,
28609
- systemAccessToken: config.systemAccessToken
28610
- });
28611
- const [metadata, gitDiff] = yield* exports_Effect.all([
28612
- getPullRequestMetadata(azureContext, config.systemAccessToken),
28613
- resolveGitDiff(config)
28614
- ]);
28615
- const reviewContext = yield* buildReviewContext(config.workspace, metadata, gitDiff);
28616
- const prompt = yield* buildReviewPrompt(config, reviewContext);
28617
- const rawResult = yield* runOpenCode(config, prompt);
28618
- const decodedJson = yield* exports_Effect.try({
28619
- try: () => parseJsonString(rawResult),
28620
- catch: () => ({ summary: rawResult, verdict: "concerns", findings: [], unmappedNotes: [] })
28621
- });
28622
- const reviewResult = yield* decodeReviewResult(decodedJson, gitDiff.changedLinesByFile);
28623
- const publishResult = yield* publishReview(config, reviewResult);
28624
- if (config.json) {
28625
- yield* writeStdout(`${stringifyJson2({
28626
- status: "ok",
28682
+ return yield* exports_Effect.gen(function* () {
28683
+ const azureContext = createAzureContext(config);
28684
+ yield* logInfo2("Resolved review configuration.");
28685
+ yield* logInfo2("Loading pull request metadata and git diff.");
28686
+ const [metadata, gitDiff] = yield* exports_Effect.all([
28687
+ getPullRequestMetadata(azureContext, config.systemAccessToken),
28688
+ resolveGitDiff(config)
28689
+ ]);
28690
+ yield* logInfo2("Loaded review inputs.", {
28691
+ pullRequestTitle: metadata.title,
28692
+ changedFiles: gitDiff.changedFiles.length,
28693
+ diffBytes: gitDiff.diffText.length,
28694
+ baseRef: gitDiff.baseRef,
28695
+ headRef: gitDiff.headRef
28696
+ });
28697
+ const reviewContext = yield* buildReviewContext(config.workspace, metadata, gitDiff);
28698
+ yield* logInfo2("Built review context.", {
28699
+ changedFiles: reviewContext.changedFiles.length
28700
+ });
28701
+ const prompt = yield* buildReviewPrompt(config, reviewContext);
28702
+ yield* logInfo2("Built review prompt.", {
28703
+ promptChars: prompt.length
28704
+ });
28705
+ const rawResult = yield* runOpenCode(config, prompt);
28706
+ yield* logInfo2("Received OpenCode response.", {
28707
+ responseChars: rawResult.length
28708
+ });
28709
+ const decodedJson = yield* exports_Effect.try({
28710
+ try: () => parseJsonString(rawResult),
28711
+ catch: () => ({ summary: rawResult, verdict: "concerns", findings: [], unmappedNotes: [] })
28712
+ });
28713
+ const reviewResult = yield* decodeReviewResult(decodedJson, gitDiff.changedLinesByFile);
28714
+ yield* logInfo2("Decoded review result.", {
28627
28715
  verdict: reviewResult.verdict,
28628
28716
  findings: reviewResult.findings.length,
28629
28717
  inlineFindings: reviewResult.inlineFindings.length,
28630
- unmappedNotes: reviewResult.unmappedNotes.length,
28631
- dryRun: config.dryRun,
28632
- actions: publishResult.actions.length
28633
- })}
28718
+ summaryOnlyFindings: reviewResult.summaryOnlyFindings.length,
28719
+ unmappedNotes: reviewResult.unmappedNotes.length
28720
+ });
28721
+ const publishResult = yield* publishReview(config, reviewResult);
28722
+ yield* logInfo2("Published review result.", {
28723
+ actions: publishResult.actions.length,
28724
+ dryRun: config.dryRun
28725
+ });
28726
+ if (config.json) {
28727
+ yield* writeStdout(`${stringifyJson2({
28728
+ status: "ok",
28729
+ verdict: reviewResult.verdict,
28730
+ findings: reviewResult.findings.length,
28731
+ inlineFindings: reviewResult.inlineFindings.length,
28732
+ unmappedNotes: reviewResult.unmappedNotes.length,
28733
+ dryRun: config.dryRun,
28734
+ actions: publishResult.actions.length
28735
+ })}
28634
28736
  `);
28635
- } else if (config.dryRun) {
28636
- yield* writeStdout(`${buildSummaryComment(reviewResult)}
28737
+ } else if (config.dryRun) {
28738
+ yield* writeStdout(`${buildSummaryComment(reviewResult)}
28637
28739
  `);
28638
- } else {
28639
- yield* writeStdout(`Posted review verdict ${reviewResult.verdict} with ${reviewResult.findings.length} findings.
28740
+ } else {
28741
+ yield* writeStdout(`Posted review verdict ${reviewResult.verdict} with ${reviewResult.findings.length} findings.
28640
28742
  `);
28641
- }
28642
- return 0;
28743
+ }
28744
+ return 0;
28745
+ }).pipe(withLogAnnotations(reviewLogFields(config)));
28643
28746
  });
28644
28747
  var runCli = exports_Effect.fn("cli.runCli")(function* () {
28645
28748
  const config = yield* ReviewConfigValue;
28646
- return yield* runReviewWithConfig(config);
28749
+ return yield* runReviewWithConfig(config).pipe(exports_Effect.withLogSpan("open-azdo.review"));
28647
28750
  });
28648
28751
  var runCliWithExitHandling = exports_Effect.fn("cli.runCliWithExitHandling")(function* () {
28649
28752
  const exit3 = yield* exports_Effect.exit(runCli());
@@ -28657,7 +28760,7 @@ var runCliWithExitHandling = exports_Effect.fn("cli.runCliWithExitHandling")(fun
28657
28760
  if (exports_Exit.isSuccess(configExit)) {
28658
28761
  yield* publishFailureSummary(configExit.value, failureReason).pipe(exports_Effect.ignore);
28659
28762
  }
28660
- yield* writeErrorLog("open-azdo failed.", {
28763
+ yield* logError2("open-azdo failed.", {
28661
28764
  cause: failureReason
28662
28765
  });
28663
28766
  return 1;
@@ -29762,6 +29865,53 @@ var layer9 = layer8;
29762
29865
 
29763
29866
  // node_modules/@effect/platform-bun/dist/BunServices.js
29764
29867
  var layer10 = /* @__PURE__ */ layer.pipe(/* @__PURE__ */ provideMerge(/* @__PURE__ */ mergeAll2(layer3, layer5, layer7, layer9)));
29868
+ // node_modules/effect/dist/Logger.js
29869
+ var CurrentLoggers2 = CurrentLoggers;
29870
+ var map14 = /* @__PURE__ */ dual(2, (self, f) => loggerMake((options) => f(self.log(options))));
29871
+ var withConsoleLog = (self) => loggerMake((options) => {
29872
+ const console2 = options.fiber.getRef(ConsoleRef);
29873
+ return console2.log(self.log(options));
29874
+ });
29875
+ var formatFiberId = (fiberId3) => `#${fiberId3}`;
29876
+ var formatStructured = /* @__PURE__ */ loggerMake(({
29877
+ cause,
29878
+ date: date2,
29879
+ fiber: fiber3,
29880
+ logLevel,
29881
+ message
29882
+ }) => {
29883
+ const annotationsObj = {};
29884
+ const spansObj = {};
29885
+ const annotations2 = fiber3.getRef(CurrentLogAnnotations);
29886
+ for (const [key, value3] of Object.entries(annotations2)) {
29887
+ annotationsObj[key] = structuredMessage(value3);
29888
+ }
29889
+ const now2 = date2.getTime();
29890
+ const spans = fiber3.getRef(CurrentLogSpans);
29891
+ for (const [label, timestamp] of spans) {
29892
+ spansObj[label] = now2 - timestamp;
29893
+ }
29894
+ const messageArr = ensure(message);
29895
+ return {
29896
+ message: messageArr.length === 1 ? structuredMessage(messageArr[0]) : messageArr.map(structuredMessage),
29897
+ level: logLevel.toUpperCase(),
29898
+ timestamp: date2.toISOString(),
29899
+ cause: cause.reasons.length > 0 ? causePretty(cause) : undefined,
29900
+ annotations: annotationsObj,
29901
+ spans: spansObj,
29902
+ fiberId: formatFiberId(fiber3.id)
29903
+ };
29904
+ });
29905
+ var formatJson2 = /* @__PURE__ */ map14(formatStructured, formatJson);
29906
+ var consoleJson = /* @__PURE__ */ withConsoleLog(formatJson2);
29907
+ var layer11 = (loggers, options) => effect(CurrentLoggers2, withFiber(fnUntraced(function* (fiber3) {
29908
+ const currentLoggers = new Set(options?.mergeWithExisting === true ? fiber3.getRef(CurrentLoggers) : []);
29909
+ for (const logger of loggers) {
29910
+ currentLoggers.add(isEffect(logger) ? yield* logger : logger);
29911
+ }
29912
+ return currentLoggers;
29913
+ })));
29914
+
29765
29915
  // src/runtime.ts
29766
29916
  var makeAppLayer = (argv, env) => {
29767
29917
  const inputLayer = succeed5(RuntimeInput, {
@@ -29775,7 +29925,8 @@ var makeAppLayer = (argv, env) => {
29775
29925
  const gitLayer = GitService.layer.pipe(provide2(mergeAll2(processLayer, exports_BunServices.layer)));
29776
29926
  const openCodeLayer = OpenCodeService.layer.pipe(provide2(mergeAll2(processLayer, bunRuntimeLayer)));
29777
29927
  const azureDevOpsLayer = AzureDevOpsService.layer.pipe(provide2(fetchLayer));
29778
- return mergeAll2(bunRuntimeLayer, fetchLayer, configLayer, processLayer, gitLayer, openCodeLayer, azureDevOpsLayer);
29928
+ const loggerLayer = layer11([consoleJson]);
29929
+ return mergeAll2(bunRuntimeLayer, fetchLayer, configLayer, processLayer, gitLayer, openCodeLayer, azureDevOpsLayer, loggerLayer);
29779
29930
  };
29780
29931
 
29781
29932
  // src/main.ts
@@ -29784,4 +29935,4 @@ var main = async (argv, env) => await exports_Effect.runPromise(runCliWithExitHa
29784
29935
  // bin/open-azdo.ts
29785
29936
  process.exitCode = await main(process.argv.slice(2), process.env);
29786
29937
 
29787
- //# debugId=72684AFC268FCFAF64756E2164756E21
29938
+ //# debugId=3D47738376EA848764756E2164756E21