Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions changelog.d/unreleased/3681.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
category: fixed
issues:
- 3681
affected:
- src/CodeIndex/Mcp/BoundedJsonUtf8Stream.cs
- src/CodeIndex/Mcp/McpServer.cs
- src/CodeIndex/Mcp/AuditLogSink.cs
- tests/CodeIndex.Tests/McpServerTests.cs
---

## English

- **MCP JSON byte-limit streams are shared across response and audit-log serialization (#3681)** — bounded UTF-8 serialization now uses one helper with tests for unsupported stream operations and partial byte-limit capture.

## 日本語

- **MCP の JSON バイト制限 stream を response と audit-log serialization で共有しました (#3681)** — bounded UTF-8 serialization は 1 つの helper を使うようになり、未対応 stream 操作と byte limit 超過時の部分 capture をテストで固定しました。
24 changes: 24 additions & 0 deletions changelog.d/unreleased/3683.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
category: fixed
issues:
- 3683
affected:
- src/CodeIndex/Cli/CommandErrorWriter.cs
- src/CodeIndex/Cli/QueryCommandRunner.cs
- src/CodeIndex/Cli/ProgramRunner.cs
- src/CodeIndex/Cli/IndexCommandRunner.Parse.cs
- src/CodeIndex/Mcp/McpServer.cs
- src/CodeIndex/Database/DbDebug.cs
- src/CodeIndex/Diagnostics/BackgroundTaskObserver.cs
- src/CodeIndex/Indexer/Extensibility/ExtractorPluginRegistry.Diagnostics.cs
- tests/CodeIndex.Tests/HookCommandRunnerTests.cs
- tests/CodeIndex.Tests/DbDebugTests.cs
---

## English

- **Command-facing stderr diagnostics now use the shared CLI error writer (#3683)** — direct stderr writes are centralized behind `CommandErrorWriter`, with tests covering JSON-mode error isolation and redacted diagnostics.

## 日本語

- **コマンド向け stderr 診断が shared CLI error writer を使うようになりました (#3683)** — direct stderr write は `CommandErrorWriter` に集約し、JSON mode の error 分離と redacted diagnostic をテストで固定しました。
20 changes: 20 additions & 0 deletions changelog.d/unreleased/3689.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
category: fixed
issues:
- 3689
affected:
- src/CodeIndex/Indexer/Scanning/FileWriteProbe.cs
- src/CodeIndex/Indexer/Scanning/FileIndexer.cs
- src/CodeIndex/Cli/GitHelper.cs
- src/CodeIndex/Cli/PathCasing.cs
- src/CodeIndex/Cli/GlobalToolLog.cs
- tests/CodeIndex.Tests/FileIndexerTests.cs
---

## English

- **Filesystem write probes now share long-path-safe create/delete behavior (#3689)** — case-sensitivity probes and global log directory checks now use one helper, with tests that verify successful cleanup and failure reporting.

## 日本語

- **filesystem write probe が long-path-safe な作成・削除処理を共有するようになりました (#3689)** — case-sensitivity probe と global log directory check は 1 つの helper を使い、成功時 cleanup と失敗報告をテストで確認します。
25 changes: 25 additions & 0 deletions changelog.d/unreleased/3690.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
category: changed
issues:
- 3690
affected:
- src/CodeIndex/Cli/CdidxConfigFile.cs
- src/CodeIndex/Cli/ConsoleUi.cs
- src/CodeIndex/Cli/GlobalToolLog.cs
- src/CodeIndex/Cli/ProgramRunner.cs
- src/CodeIndex/Cli/SearchAuditRecipes.cs
- src/CodeIndex/Cli/UpdateChecker.cs
- src/CodeIndex/Database/DbReader.cs
- src/CodeIndex/Indexer/Scanning/FileIndexer.cs
- tests/CodeIndex.Tests/ConsoleUiTests.cs
- tests/CodeIndex.Tests/GlobalToolLogTests.cs
- tests/CodeIndex.Tests/ProgramRunnerTests.cs
---

## English

- **CLI environment variable reads now use scoped `CdidxEnvironment` overrides more consistently (#3690)** — config loading, console policy, logging, update checks, recipe discovery, fold diagnostics, and index file-size limits can be tested without mutating process-global environment variables.

## 日本語

- **CLI の環境変数読み取りが scoped な `CdidxEnvironment` override をより一貫して使うようになりました (#3690)** — config loading、console policy、logging、update check、recipe discovery、fold diagnostics、index file-size limit は process-global な環境変数を変更せずにテストできます。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/3715.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: fixed
issues:
- 3715
affected:
- src/CodeIndex/Cli/ExportImportCommandRunner.cs
- tests/CodeIndex.Tests/ExportImportCommandRunnerTests.cs
---

## English

- **Export manifests now report unknown-extension sample list limits explicitly (#3715)** — archives include sample count, limit, and truncation metadata while preserving existing unknown-extension fields for older import/export compatibility.

## 日本語

- **export manifest が unknown-extension sample list の制限を明示するようになりました (#3715)** — archive は sample count、limit、truncation metadata を含み、既存の unknown-extension field は古い import/export 互換性のため維持します。
2 changes: 1 addition & 1 deletion src/CodeIndex/Cli/ActiveWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,5 +247,5 @@ private static bool IsFullyQualifiedPath(string path)
};

private static void WriteLoadWarning(string source, string reason)
=> Console.Error.WriteLine($"[cdidx] Ignoring active workspace {source}: {ConsoleUi.FormatBoundedValue(reason)}. Hint: inspect or reset the active workspace configuration.");
=> CommandErrorWriter.WriteStderr($"[cdidx] Ignoring active workspace {source}: {ConsoleUi.FormatBoundedValue(reason)}. Hint: inspect or reset the active workspace configuration.");
}
4 changes: 2 additions & 2 deletions src/CodeIndex/Cli/CdidxConfigFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ internal sealed record LoadResult(string? Path, string? Error)
/// validation errors. No-op when `CDIDX_DISABLE_CONFIG_FILE=1` is set.
/// </summary>
internal static LoadResult Load(string startingDirectory)
=> Load(startingDirectory, Environment.GetEnvironmentVariable);
=> Load(startingDirectory, CdidxEnvironment.GetEnvironmentVariable);

internal static LoadResult Load(
string startingDirectory,
Expand Down Expand Up @@ -529,7 +529,7 @@ internal static int RunValidate(string[] args, JsonSerializerOptions jsonOptions
var result = Load(Environment.CurrentDirectory, name => name == DisableEnvVar ? null : Environment.GetEnvironmentVariable(name));
if (result.Failed)
{
Console.Error.WriteLine(result.Error);
CommandErrorWriter.WriteStderr(result.Error);
return CommandExitCodes.UsageError;
}

Expand Down
6 changes: 3 additions & 3 deletions src/CodeIndex/Cli/CodeIndexExceptionFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ public static void Write(CodeIndexException ex, string[] args, JsonSerializerOpt
// QueryCommandRunner / IndexCommandRunner already emit so downstream
// parsers do not need a second format.
// 既存の `Error [Exxx]: ...` 形に揃え、parser の差分を最小化する。
Console.Error.WriteLine($"Error [{ex.Code}]: {ex.Message}");
CommandErrorWriter.WriteStderr($"Error [{ex.Code}]: {ex.Message}");
if (!string.IsNullOrEmpty(ex.Path))
Console.Error.WriteLine($"Path: {ex.Path}");
CommandErrorWriter.WriteStderr($"Path: {ex.Path}");
if (!string.IsNullOrEmpty(ex.Hint))
Console.Error.WriteLine($"Hint: {ex.Hint}");
CommandErrorWriter.WriteStderr($"Hint: {ex.Hint}");
}

internal static bool HasJsonFlag(string[] args)
Expand Down
2 changes: 1 addition & 1 deletion src/CodeIndex/Cli/CommandErrorWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal static class CommandErrorWriter
internal static void WriteStdout(string message = "")
=> Console.WriteLine(message);

internal static void WriteStderr(string message = "")
internal static void WriteStderr(string? message = "")
=> Console.Error.WriteLine(message);

internal static void WriteWarning(string message)
Expand Down
56 changes: 28 additions & 28 deletions src/CodeIndex/Cli/ConsoleUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ internal static void TryWriteErrorLine(string? value = null)
try
{
if (value == null)
Console.Error.WriteLine();
CommandErrorWriter.WriteStderr();
else
Console.Error.WriteLine(value);
CommandErrorWriter.WriteStderr(value);
}
catch (ObjectDisposedException)
{
Expand Down Expand Up @@ -390,7 +390,7 @@ internal static bool ShouldUseProgressAnimation()
if (IsTruthyEnvironmentVariable(DisableProgressEnvironmentVariable))
return false;

var reducedMotion = Environment.GetEnvironmentVariable(PrefersReducedMotionEnvironmentVariable);
var reducedMotion = CdidxEnvironment.GetEnvironmentVariable(PrefersReducedMotionEnvironmentVariable);
return string.IsNullOrWhiteSpace(reducedMotion) || !IsTruthyEnvironmentValue(reducedMotion);
}

Expand Down Expand Up @@ -592,7 +592,7 @@ public static void PrintWarning(string message)
lock (TerminalLock)
{
ClearProgressLineCore();
Console.Error.WriteLine($" [WARN] {message}");
CommandErrorWriter.WriteStderr($" [WARN] {message}");
Console.Error.Flush();
Console.Out.Flush();
}
Expand Down Expand Up @@ -1401,7 +1401,7 @@ public static bool PrintCompletions(string shell)
}
catch (ArgumentOutOfRangeException)
{
Console.Error.WriteLine($"Unknown shell: {shell}. Supported: bash, zsh, fish, powershell");
CommandErrorWriter.WriteStderr($"Unknown shell: {shell}. Supported: bash, zsh, fish, powershell");
return false;
}
}
Expand Down Expand Up @@ -1941,7 +1941,7 @@ public static ColorPalette ResolveColorPalette()
if (_explicitPalette is { } explicitPalette)
return explicitPalette;

var envPalette = Environment.GetEnvironmentVariable("CDIDX_COLOR_PALETTE");
var envPalette = CdidxEnvironment.GetEnvironmentVariable("CDIDX_COLOR_PALETTE");
if (!string.IsNullOrWhiteSpace(envPalette) && TryParseColorPalette(envPalette, out var parsed))
return parsed;

Expand All @@ -1957,15 +1957,15 @@ public static ColorPalette ResolveColorPalette()
/// </summary>
internal static ColorPalette DetectColorPalette()
{
var colorTerm = Environment.GetEnvironmentVariable("COLORTERM");
var colorTerm = CdidxEnvironment.GetEnvironmentVariable("COLORTERM");
if (!string.IsNullOrEmpty(colorTerm))
{
var ct = colorTerm.Trim().ToLowerInvariant();
if (ct == "truecolor" || ct == "24bit")
return ColorPalette.Truecolor;
}

var term = Environment.GetEnvironmentVariable("TERM");
var term = CdidxEnvironment.GetEnvironmentVariable("TERM");
if (!string.IsNullOrEmpty(term))
{
var t = term.ToLowerInvariant();
Expand Down Expand Up @@ -2159,14 +2159,14 @@ public static bool ShouldUseColor()

private static bool HasTerminalEnvironmentHint()
{
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WT_SESSION")))
if (!string.IsNullOrEmpty(CdidxEnvironment.GetEnvironmentVariable("WT_SESSION")))
return true;
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WT_PROFILE_ID")))
if (!string.IsNullOrEmpty(CdidxEnvironment.GetEnvironmentVariable("WT_PROFILE_ID")))
return true;
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TERM_PROGRAM")))
if (!string.IsNullOrEmpty(CdidxEnvironment.GetEnvironmentVariable("TERM_PROGRAM")))
return true;

var term = Environment.GetEnvironmentVariable("TERM");
var term = CdidxEnvironment.GetEnvironmentVariable("TERM");
return !string.IsNullOrWhiteSpace(term)
&& !term.Equals("dumb", StringComparison.OrdinalIgnoreCase);
}
Expand All @@ -2176,7 +2176,7 @@ private static bool IsTerminalEnvironmentDisabled()

private static bool IsCiEnvironment()
{
var ci = Environment.GetEnvironmentVariable("CI");
var ci = CdidxEnvironment.GetEnvironmentVariable("CI");
return !string.IsNullOrEmpty(ci)
&& !ci.Equals("0", StringComparison.OrdinalIgnoreCase)
&& !ci.Equals("false", StringComparison.OrdinalIgnoreCase)
Expand Down Expand Up @@ -2227,17 +2227,17 @@ internal static void ResetTerminalCapabilityCacheForTests()

private static bool IsForceColorRequested()
{
var force = Environment.GetEnvironmentVariable("CLICOLOR_FORCE");
var force = CdidxEnvironment.GetEnvironmentVariable("CLICOLOR_FORCE");
return !string.IsNullOrEmpty(force) && force != "0";
}

private static bool IsNoColorRequested()
{
var noColor = Environment.GetEnvironmentVariable("NO_COLOR");
var noColor = CdidxEnvironment.GetEnvironmentVariable("NO_COLOR");
if (!string.IsNullOrEmpty(noColor))
return true;

var cliColor = Environment.GetEnvironmentVariable("CLICOLOR");
var cliColor = CdidxEnvironment.GetEnvironmentVariable("CLICOLOR");
return cliColor == "0";
}

Expand All @@ -2262,29 +2262,29 @@ private static bool IsAsciiOutputRequested()
if (_asciiOutputForced)
return true;

var ascii = Environment.GetEnvironmentVariable("CDIDX_ASCII");
var ascii = CdidxEnvironment.GetEnvironmentVariable("CDIDX_ASCII");
if (!string.IsNullOrEmpty(ascii) && ascii != "0")
return true;

var noUnicode = Environment.GetEnvironmentVariable("NO_UNICODE");
var noUnicode = CdidxEnvironment.GetEnvironmentVariable("NO_UNICODE");
if (!string.IsNullOrEmpty(noUnicode) && noUnicode != "0")
return true;

var atBridgeType = Environment.GetEnvironmentVariable("AT_BRIDGE_TYPE");
var atBridgeType = CdidxEnvironment.GetEnvironmentVariable("AT_BRIDGE_TYPE");
if (!string.IsNullOrEmpty(atBridgeType))
return true;

var accessibilityEnabled = Environment.GetEnvironmentVariable("ACCESSIBILITY_ENABLED");
var accessibilityEnabled = CdidxEnvironment.GetEnvironmentVariable("ACCESSIBILITY_ENABLED");
if (!string.IsNullOrEmpty(accessibilityEnabled) && accessibilityEnabled != "0")
return true;

return IsPosixLocale(Environment.GetEnvironmentVariable("LC_ALL"))
|| IsPosixLocale(Environment.GetEnvironmentVariable("LC_CTYPE"))
|| IsPosixLocale(Environment.GetEnvironmentVariable("LANG"));
return IsPosixLocale(CdidxEnvironment.GetEnvironmentVariable("LC_ALL"))
|| IsPosixLocale(CdidxEnvironment.GetEnvironmentVariable("LC_CTYPE"))
|| IsPosixLocale(CdidxEnvironment.GetEnvironmentVariable("LANG"));
}

private static bool IsTruthyEnvironmentVariable(string name)
=> IsTruthyEnvironmentValue(Environment.GetEnvironmentVariable(name));
=> IsTruthyEnvironmentValue(CdidxEnvironment.GetEnvironmentVariable(name));

private static bool IsTruthyEnvironmentValue(string? value)
{
Expand All @@ -2295,7 +2295,7 @@ private static bool IsTruthyEnvironmentValue(string? value)
}

private static bool IsDumbTerminal()
=> string.Equals(Environment.GetEnvironmentVariable("TERM"), "dumb", StringComparison.OrdinalIgnoreCase);
=> string.Equals(CdidxEnvironment.GetEnvironmentVariable("TERM"), "dumb", StringComparison.OrdinalIgnoreCase);

private static bool IsPosixLocale(string? locale)
=> locale != null
Expand All @@ -2310,7 +2310,7 @@ private static bool IsUnicodeLocale(string locale)
{
foreach (var name in names)
{
var value = Environment.GetEnvironmentVariable(name);
var value = CdidxEnvironment.GetEnvironmentVariable(name);
if (!string.IsNullOrEmpty(value))
return value;
}
Expand Down Expand Up @@ -2359,7 +2359,7 @@ private static int GetFallbackWindowWidth(Exception? exception)
if (_traceWidthDetectionFailures && !_widthDetectionTraceWritten)
{
var suffix = exception == null ? string.Empty : $" ({exception.GetType().Name}: {exception.Message})";
Console.Error.WriteLine($"cdidx: console width detection failed; using COLUMNS or 80 columns{suffix}");
CommandErrorWriter.WriteStderr($"cdidx: console width detection failed; using COLUMNS or 80 columns{suffix}");
_widthDetectionTraceWritten = true;
}

Expand All @@ -2368,7 +2368,7 @@ private static int GetFallbackWindowWidth(Exception? exception)

private static bool TryGetColumnsEnvironmentWidth(out int width)
{
var columns = Environment.GetEnvironmentVariable("COLUMNS");
var columns = CdidxEnvironment.GetEnvironmentVariable("COLUMNS");
if (int.TryParse(columns, NumberStyles.Integer, CultureInfo.InvariantCulture, out width) && width > 0)
return true;

Expand Down
8 changes: 4 additions & 4 deletions src/CodeIndex/Cli/DbCommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ private static int RunPrune(DbCommandOptions options, JsonSerializerOptions json
Console.WriteLine($" orphan symbols : {result.OrphanSymbols:N0}");
Console.WriteLine($" total : {result.Total:N0}");
foreach (var warning in result.Warnings)
Console.Error.WriteLine($"Warning [{warning.Code}]: {warning.Message}");
CommandErrorWriter.WriteStderr($"Warning [{warning.Code}]: {warning.Message}");
}

return CommandExitCodes.Success;
Expand Down Expand Up @@ -391,7 +391,7 @@ private static int RunListCheckpoints(DbCommandOptions options, JsonSerializerOp
}

foreach (var diagnostic in result.Diagnostics)
Console.Error.WriteLine($"Warning [{diagnostic.Code}]: {diagnostic.Message}");
CommandErrorWriter.WriteStderr($"Warning [{diagnostic.Code}]: {diagnostic.Message}");
}

return CommandExitCodes.Success;
Expand Down Expand Up @@ -962,7 +962,7 @@ private static string RestoreCheckpoint(string fullDbPath, string name, string c
}
catch (Exception rollbackEx) when (IsRecoverableRestoreException(rollbackEx))
{
Console.Error.WriteLine($"Warning: failed to roll back database restore from backup {ConsoleUi.FormatBoundedValue(backupPath)} ({CommandErrorWriter.FormatSanitizedException(rollbackEx)}).");
CommandErrorWriter.WriteStderr($"Warning: failed to roll back database restore from backup {ConsoleUi.FormatBoundedValue(backupPath)} ({CommandErrorWriter.FormatSanitizedException(rollbackEx)}).");
}

throw;
Expand Down Expand Up @@ -1070,7 +1070,7 @@ internal static void TryDeleteTemporaryDirectory(string path, string cleanupDesc
{
if (!TryValidateTemporaryDirectoryCleanupTarget(path, safeRoot, expectedNamePrefix, out var fullPath, out var validationFailure))
{
Console.Error.WriteLine($"Warning: skipped deleting {cleanupDescription} {ConsoleUi.FormatBoundedValue(path)} ({validationFailure}).");
CommandErrorWriter.WriteStderr($"Warning: skipped deleting {cleanupDescription} {ConsoleUi.FormatBoundedValue(path)} ({validationFailure}).");
return;
}

Expand Down
4 changes: 2 additions & 2 deletions src/CodeIndex/Cli/DiffCommandRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -840,9 +840,9 @@ private static int WriteCommandError(bool json, JsonSerializerOptions jsonOption
CliJsonSerializerContextFactory.Create(jsonOptions).CommandErrorJsonResult));
else
{
Console.Error.WriteLine($"Error [{errorCode ?? CommandErrorCodes.UsageError}]: {message}");
CommandErrorWriter.WriteStderr($"Error [{errorCode ?? CommandErrorCodes.UsageError}]: {message}");
if (!string.IsNullOrWhiteSpace(hint))
Console.Error.WriteLine($"Hint: {hint}");
CommandErrorWriter.WriteStderr($"Hint: {hint}");
}
return exitCode;
}
Expand Down
Loading
Loading