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
8 changes: 8 additions & 0 deletions DEVELOPER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ Do not add mutable static caches, shared `StringBuilder` instances, reused `Matc

`status --check` keeps the DB/worktree checksum comparison in `IndexFreshnessChecker`, but the user-facing age hint threshold is resolved in `QueryCommandRunner`: CLI `--stale-after <duration>` wins over `CDIDX_STALE_AFTER`, which wins over `.cdidxrc.json`'s `stale_after`, then the 24-hour default. Supported duration suffixes are `m`, `h`, and `d`. JSON output includes `stale_after_seconds` and `index_age_seconds` only for `--check`, so clients can confirm which threshold was applied without inferring it from text.

### Workspace version pinning

On startup, `cdidx` walks up from the current directory looking for `.cdidx-version`. The first non-empty line is treated as the required CLI version for that workspace. A mismatch prints a warning and continues by default; `--strict-version` or `CDIDX_STRICT_VERSION=1` turns the mismatch into exit code `64` (`EX_USAGE`). This check is advisory and does not rewrite the file. Use it to keep teams on the same binary when index contracts or query behavior differ between releases.

### Release freshness and upgrade checks

`cdidx --check-updates` and `cdidx status --check-updates` query the GitHub latest-release endpoint through `UpdateChecker`, using the same 24-hour cache and `CDIDX_DISABLE_UPDATE_CHECK=1` opt-out as the `--version` hint. `cdidx upgrade --check-only` reuses that check. `cdidx upgrade` is intentionally a thin wrapper around the signed release installer: it downloads `install.sh`, verifies the current binary directory is writable, sets `CDIDX_INSTALL_DIR` to that directory, and runs the installer for the latest release.

### Degradation reason codes

Readiness degradation reason codes are centralized in `DegradationReasonCodes`. Add new codes there with human text, a recommended action, and an alternative action before emitting them from readers, CLI, or MCP payloads.
Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,20 @@ file completion.
| Drift checks | `cdidx diff <db1> <db2>` compares schema, file, symbol, and reference deltas with stable exit codes: `0` identical, `1` drift, `2` schema mismatch, `3` unreadable DB. |
| Extensibility and feedback | Post-extraction hooks from `~/.config/cdidx/hooks/*.dll` or `CDIDX_HOOKS_DIR` can enrich symbols and references. `cdidx suggestions` lists, inspects, and exports local suggestion history, with fuzzy MCP suggestion deduplication controlled by CLI, env, or `.cdidxrc.json`. |
| Language coverage | 78 detected languages, with symbol and graph support where available. |
| Updates | `cdidx --version` checks GitHub releases at most once per day and appends a newer-release hint when one is available. Set `CDIDX_DISABLE_UPDATE_CHECK=1` to suppress the check. |
| Updates | `cdidx --version` checks GitHub releases at most once per day and appends a newer-release hint when one is available. Use `cdidx --check-updates` or `cdidx status --check-updates` for an explicit freshness check, and `cdidx upgrade` to reinstall the latest GitHub release via `install.sh`. Set `CDIDX_DISABLE_UPDATE_CHECK=1` to suppress checks. |

### Upgrade and uninstall

`cdidx upgrade --check-only` reports whether a newer GitHub release is available. `cdidx upgrade` downloads the current `install.sh`, refuses unwritable install directories, and reruns the installer with `CDIDX_INSTALL_DIR` pointed at the current binary directory.

Direct `install.sh` installs can be removed with:

```bash
bash ./install.sh --uninstall
bash ./install.sh --uninstall --purge-cache
```

The uninstaller removes files placed next to the `cdidx` binary and can optionally remove `~/.cache/cdidx`. It does not remove project `.cdidx/` directories, shell profile PATH edits, shell completion scripts, Homebrew installs, or .NET global-tool installs.

The documented `status --json` trust contract covers these fields:

Expand Down
17 changes: 17 additions & 0 deletions changelog.d/unreleased/1744.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
category: added
issues:
- 1744
affected:
- src/CodeIndex/Cli/ProgramRunner.cs
- src/CodeIndex/Cli/ConsoleUi.cs
- README.md
---

## English

- **Added `cdidx upgrade` for release self-upgrades (#1744)** — `upgrade` checks GitHub release freshness, supports `--check-only`, refuses unwritable install directories, and reruns the signed `install.sh` installer for the latest release.

## 日本語

- **リリース自己更新用の `cdidx upgrade` を追加しました (#1744)** — `upgrade` は GitHub release の鮮度を確認し、`--check-only` をサポートし、書き込み不能なインストール先を拒否したうえで最新リリース向けに署名済み `install.sh` を再実行します。
18 changes: 18 additions & 0 deletions changelog.d/unreleased/1748.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
category: added
issues:
- 1748
affected:
- src/CodeIndex/Cli/ProgramRunner.cs
- src/CodeIndex/Cli/QueryCommandRunner.cs
- src/CodeIndex/Cli/UpdateChecker.cs
- README.md
---

## English

- **Added explicit update checks (#1748)** — `cdidx --check-updates` and `cdidx status --check-updates` now use the cached GitHub latest-release check so operators can ask for version freshness without running an upgrade.

## 日本語

- **明示的な更新確認を追加しました (#1748)** — `cdidx --check-updates` と `cdidx status --check-updates` がキャッシュ付き GitHub latest-release 確認を使うようになり、upgrade せずにバージョン鮮度を確認できます。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/1750.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: added
issues:
- 1750
affected:
- install.sh
- README.md
---

## English

- **Added installer uninstall mode (#1750)** — `install.sh --uninstall` removes files installed next to the `cdidx` binary and `--purge-cache` can also remove the per-user cdidx cache, while documenting what remains manual.

## 日本語

- **インストーラーに uninstall モードを追加しました (#1750)** — `install.sh --uninstall` は `cdidx` バイナリ横に配置されたファイルを削除し、`--purge-cache` ではユーザー単位の cdidx キャッシュも削除できます。手動で残るものも明示します。
16 changes: 16 additions & 0 deletions changelog.d/unreleased/1752.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
category: added
issues:
- 1752
affected:
- src/CodeIndex/Cli/ProgramRunner.cs
- DEVELOPER_GUIDE.md
---

## English

- **Added workspace version pin warnings (#1752)** — `.cdidx-version` now warns when the running CLI version differs from the workspace pin, and `--strict-version` / `CDIDX_STRICT_VERSION=1` can turn the mismatch into exit code 64.

## 日本語

- **ワークスペースのバージョン固定警告を追加しました (#1752)** — `.cdidx-version` と実行中 CLI のバージョンが異なる場合に警告し、`--strict-version` / `CDIDX_STRICT_VERSION=1` で不一致を exit code 64 にできます。
68 changes: 68 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# bash ./install.sh --self-test-local-mirror [--self-test-allow-overwrite] [vX.Y.Z]
# bash ./install.sh --reinstall-real vX.Y.Z
# bash ./install.sh --doctor [vX.Y.Z]
# bash ./install.sh --uninstall [--purge-cache]
# HTTPS_PROXY=http://proxy.example:8080 bash ./install.sh --doctor
# CDIDX_GITHUB_BASE_URL=https://github.example.internal \
# CDIDX_GITHUB_API_BASE_URL=https://github.example.internal/api/v3 \
Expand Down Expand Up @@ -98,6 +99,7 @@ SELF_TEST_ALLOW_OVERWRITE=0
EXISTING_BIN=""
EXISTING_VERSION=""
EXPLICIT_VERSION_REQUESTED=0
PURGE_CACHE_ON_UNINSTALL=0

# --- Helpers / ヘルパー ---

Expand Down Expand Up @@ -1075,6 +1077,54 @@ check_path() {
esac
}

uninstall_cdidx() {
info "cdidx uninstaller"
acquire_install_lock

local removed=0
local path
for path in \
"${INSTALL_DIR}/${BINARY_NAME}" \
"${INSTALL_DIR}/version.json" \
"${INSTALL_DIR}/libe_sqlite3.so" \
"${INSTALL_DIR}/libe_sqlite3.dylib" \
"${INSTALL_DIR}/LICENSE" \
"${INSTALL_DIR}/COMMERCIAL_LICENSE.md" \
"${INSTALL_DIR}/INTEGRATION_POLICY.md" \
"${INSTALL_DIR}/TRADEMARKS.md" \
"${INSTALL_DIR}/MANIFEST.sha256"; do
if [ -e "$path" ]; then
rm -f "$path"
info "Removed ${path}"
removed=1
fi
done

if [ -d "${INSTALL_DIR}/LICENSES" ]; then
rm -rf "${INSTALL_DIR}/LICENSES"
info "Removed ${INSTALL_DIR}/LICENSES"
removed=1
fi

if [ "$PURGE_CACHE_ON_UNINSTALL" = "1" ]; then
local cache_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/cdidx"
if [ -d "$cache_dir" ]; then
rm -rf "$cache_dir"
info "Removed ${cache_dir}"
removed=1
fi
fi

if [ "$removed" = "0" ]; then
warn "No cdidx install files were found under ${INSTALL_DIR}."
fi

echo ""
info "Uninstall complete."
echo "Not removed: project-local .cdidx/ directories, shell profile PATH edits, shell completion scripts, or global-tool installs managed by dotnet/Homebrew."
echo "To remove cached update metadata too, rerun with --uninstall --purge-cache."
}

report_local_mirror_start_failure() {
local local_mirror_port="$1"
local local_mirror_log="$2"
Expand Down Expand Up @@ -1815,6 +1865,24 @@ if [ "${CDIDX_INSTALL_SH_LIB_ONLY:-0}" != "1" ]; then
shift
run_doctor "${1:-}"
;;
--uninstall)
shift
while [ $# -gt 0 ]; do
case "$1" in
--purge-cache)
PURGE_CACHE_ON_UNINSTALL=1
shift
;;
--*)
error "Unknown uninstall option: $1"
;;
*)
error "--uninstall does not accept a version argument."
;;
esac
done
uninstall_cdidx
;;
*)
main "$@"
;;
Expand Down
6 changes: 5 additions & 1 deletion src/CodeIndex/Cli/CliFlagSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ internal static class CliFlagSchema
[
"index", "backfill-fold", "optimize", "search", "definition", "references", "callers", "callees",
"symbols", "files", "find", "excerpt", "map", "inspect", "outline", "status", "validate-config",
"validate", "deps", "impact", "unused", "hotspots", "languages", "batch", "mcp", "completions", "db", "vacuum", "report", "license",
"validate", "deps", "impact", "unused", "hotspots", "languages", "batch", "mcp", "completions", "db", "vacuum", "report", "license", "upgrade",
];

// Commands that accept the `--` end-of-options marker so a user can pass a literal
Expand Down Expand Up @@ -245,6 +245,10 @@ private static IReadOnlyList<CliFlag> BuildAll()
new() { Name = "--stale-after", ValuePlaceholder = "<duration>", Description = "Status: freshness age threshold (e.g. 30m, 2h, 7d)", Commands = Set("status") },
new() { Name = "--explain", ValuePlaceholder = "<field>", Description = "Explain one status readiness field", Commands = Set("status") },
new() { Name = "--log-path", Description = "Print the active persistent log directory", Commands = Set("status") },
new() { Name = "--check-updates", Description = "Check whether a newer cdidx release is available", Commands = Set("status", "upgrade") },
new() { Name = "--check-only", Description = "Upgrade: only report whether an upgrade is available", Commands = Set("upgrade") },
new() { Name = "--channel", ValuePlaceholder = "<stable|beta>", Description = "Upgrade channel selector (reserved)", Commands = Set("upgrade") },
new() { Name = "--prerelease", Description = "Upgrade: include prerelease versions (reserved)", Commands = Set("upgrade") },
new() { Name = "--integrity-check", Description = "Run PRAGMA integrity_check on the database", Commands = Set("db") },
new() { Name = "--rebuild", Description = "Delete existing DB and rebuild from scratch", Commands = Set("index") },
new() { Name = "--optimize", Description = "Optimize the existing FTS5 table without scanning files", Commands = Set("index") },
Expand Down
6 changes: 4 additions & 2 deletions src/CodeIndex/Cli/ConsoleUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private static readonly (string Command, string Usage)[] CommandUsageLines =
("map", "cdidx map [--db <path>] [--json] [--verbose] [--limit <n>] [--lang <lang>] [--path <glob>] [--exclude-path <glob>] [--exclude-tests] [--bytes]"),
("inspect", "cdidx inspect <query>|--query <query>|-- <query> [--db <path>] [--json] [--verbose] [--limit <n>] [--lang <lang>] [--path <glob>] [--exclude-path <glob>] [--exclude-tests] [--body] [--max-line-width <n>] [--exact|--exact-name]"),
("outline", "cdidx outline <path> [--db <path>] [--json] [--verbose]"),
("status", "cdidx status [--db <path>] [--json] [--verbose] [--check[=workspace,fold,graph,issues,hotspot,csharp,sql,newer]] [--stale-after <duration>] [--explain <field>] [--log-path] [--config]"),
("status", "cdidx status [--db <path>] [--json] [--verbose] [--check[=workspace,fold,graph,issues,hotspot,csharp,sql,newer]] [--stale-after <duration>] [--explain <field>] [--log-path] [--config] [--check-updates]"),
("validate-config", "cdidx validate-config"),
("db", "cdidx db --integrity-check [--db <path>] [--json]"),
("diff", "cdidx diff <db1> <db2> [--json] [--summary-only] [--detailed] [--limit <n>]"),
Expand All @@ -96,6 +96,7 @@ private static readonly (string Command, string Usage)[] CommandUsageLines =
("mcp", "cdidx mcp [--db <path>]"),
("completions", "cdidx completions <shell>"),
("--completions", "cdidx --completions <shell>"),
("upgrade", "cdidx upgrade [--check-only]"),
("license", "cdidx license"),
];

Expand Down Expand Up @@ -660,6 +661,7 @@ void WriteHelpLine(string line = "")
Console.WriteLine(" inspect <query> Bundle definition, graph, and nearby symbol context");
Console.WriteLine(" outline <path> Show a file outline ordered by line, start column, kind, and name");
Console.WriteLine(" status Show database statistics; add --check for freshness, --config for effective config, --explain <field> for readiness, or --log-path for logs");
Console.WriteLine(" upgrade Check for and install the latest release via install.sh");
Console.WriteLine(" validate-config Validate .cdidx/config.json or .cdidxrc.json");
Console.WriteLine(" db --integrity-check Run SQLite `PRAGMA integrity_check` and report findings");
Console.WriteLine(" diff <db1> <db2> Compare two index databases; exit 0 identical, 1 drift, 2 schema mismatch, 3 unreadable");
Expand Down Expand Up @@ -1035,7 +1037,7 @@ private static int DamerauLevenshteinDistance(string s, string t)
[
"index", "backfill-fold", "optimize", "search", "definition", "references", "callers", "callees",
"symbols", "files", "find", "excerpt", "map", "inspect", "outline", "status", "validate-config",
"validate", "deps", "impact", "unused", "hotspots", "languages", "batch", "mcp", "completions", "db", "vacuum", "report", "license",
"validate", "deps", "impact", "unused", "hotspots", "languages", "batch", "mcp", "completions", "db", "vacuum", "report", "license", "upgrade",
];

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions src/CodeIndex/Cli/JsonOutputContracts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ internal sealed record VersionInfoJsonResult(
[JsonSerializable(typeof(SymbolHotspotJsonResult))]
[JsonSerializable(typeof(SymbolResult))]
[JsonSerializable(typeof(UnusedSymbolResult))]
[JsonSerializable(typeof(CodeIndex.Models.UpdateCheckResult))]
[JsonSerializable(typeof(VacuumResult))]
[JsonSerializable(typeof(VersionInfoJsonResult))]
internal partial class CliJsonSerializerContext : JsonSerializerContext;
Expand Down
Loading
Loading