fc7c2a1b9b481da4b43aa6ae2fbde0c3132bdd1a
21
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fc7c2a1b9b |
feat(login): /login opens the provider picker with green connected badges
/login previously fired the resolved method's flow immediately — there was no way to see providers or their status. It now lands on the provider picker; already-connected providers show a green 'connected' badge in the key column. Shell: initialize() probes stored credentials once (primary session flag, auth.json oauth/<provider> scopes, resolved platform keys env>auth.json> config) and stamps _meta.connected on each advertised method (connected_method_ids + stamp_connected_meta, pure and unit-tested). Display state only — never an authorization input. TUI: - PendingMenuItem::connected() reads the badge from method meta; the picker renders it green (accent_success), replacing the shortcut hint. - New Action::OpenLoginPicker: /login shows the picker; mid-session it stashes the view like dispatch_login, and starts no flow by itself. - Mid-session picker: last row reads 'Cancel' and dispatches CancelLogin (clicking it must not exit the app); Esc also returns to the session. - After a successful login, the just-authenticated method is stamped connected in the TUI's advertised-methods copy (auth_in_flight_method → AuthComplete), so a later /login shows the badge without re-initialize. Verified: kigi-shell 5256 + kigi-tui 6870 tests green, clippy clean. |
||
|
|
c2d1067f0d |
fix(tui): login picker scrolls in a capped viewport; the moon never clips
Root cause (issues: unscrollable list + half-blocked moon): the stacked welcome layout gave the menu one Length row per item. With ~30 advertised providers the vertical layout overflowed and the constraint solver squeezed every Length — clipping the logo — while rows past the fold were silently unreachable. - WelcomeLayout::compute_inner caps the menu to the rows genuinely left over after logo/prompt/version, so the chrome never gets squeezed. - render_menu is now a minimal-scroll viewport: it scrolls only when the selection exits it (stable under hover — no re-centering feedback loop), draws the picker-style scrollbar, and returns index-aligned hit rects (zero Rect for off-screen rows) plus the offset, which AppView feeds back next frame. - Mouse wheel moves the login-picker selection (clamped, not wrapping). Test: pending_menu_scrolls_and_never_clips_the_moon renders the full method list at 40 rows and asserts the whole moon (10 braille rows), the version badge, and that selecting Quit scrolls it into view. Verified: kigi-tui 6864 tests green, clippy clean. |
||
|
|
422e241e13 |
feat(providers): add ChatGPT/Codex subscription OAuth (PKCE + account-id, hardcoded catalog)
29th platform `openai-codex` (uses_oauth, Responses wire). PKCE-localhost login at auth.openai.com (client app_EMoamEEZ73f0CkXaXp7hrann, redirect localhost:1455/auth/ callback, form token exchange, fresh-random state) reusing the claude-pro-max flow; OAuthFlow::PkceLocalhost gained a redirect_path and OAuthConfig an authorize_extra (empty elsewhere, so claude/xai/copilot authorize URLs stay byte-identical). Codex-specific: the access token is a JWT carrying chatgpt_account_id, which becomes the `chatgpt-account-id` inference header. It is derived STATELESSLY from whichever bearer rides each request (so a rotated token needs no persisted field), and BOTH login and refresh fail fast when the claim is absent — gated on the explicit OAuthConfig.requires_chatgpt_account_id fact, never inferred from the token-body encoding (a plain form endpoint is the OAuth norm and must not inherit this). Inference rides the existing Responses wire at chatgpt.com/backend-api/codex → /responses, with codex headers (chatgpt-account-id, originator, OpenAI-Beta responses=experimental, codex UA) gated on SamplerConfig.openai_codex so API-key `openai` stays byte-identical; store:false was already the global Responses default. Catalog is HARDCODED (no live endpoint exists for this backend; read from the official Codex CLI's model cache): gpt-5.6-sol/terra/luna + gpt-5.5, ctx 272000, each with its real reasoning levels (low..ultra — ReasoningEffort gained Ultra). Excluded: gpt-5.3-codex-spark (supported_in_api=false), gpt-5.4/-mini and codex-auto-review (hidden) — they would list but fail at inference. The fetch short-circuits before any HTTP; Kigi never shells out to the codex CLI or reads ~/.codex. Security review fixes: redact any `account-id` header from request logs (it was reaching debug logs), strict 3-segment JWT check (fail closed), refresh no longer fails open on a missing claim. Inherits leak-safe pooled routing (scope oauth/openai-codex) — never the Kimi token. Full gate green (234 suites, 0 warnings). |
||
|
|
8179438278 |
feat(providers): add GitHub Copilot subscription OAuth (device flow + copilot-token re-mint)
28th platform `github-copilot` (uses_oauth, ChatCompletions wire). Two-stage auth: RFC-8628 GitHub device flow (client Iv1.b507a08c87ecfe98, scope read:user, errors in a 200 body) mints the DURABLE github token; a GET api.github.com/copilot_internal/ v2/token exchange re-mints the SHORT-LIVED copilot token. Persisted as key=copilot token, refresh_token=github token, expires_at=copilot expiry; the "refresh" is a copilot-token re-mint (not a refresh_token grant), dispatched via OAuthTokenBody::GithubCopilotExchange in the generic refresher. VS Code editor-identity headers on /models + /chat/completions, gated on SamplerConfig.github_copilot / PlatformId::sends_copilot_editor_headers() so every other ChatCompletions provider stays byte-identical. Live /models filtered (parse_github_copilot_listing) to the openai-completions-served models: keep iff model_picker_enabled && policy.state!="disabled" && tool_calls!=false AND not a claude-4.x/5.x (messages) or gpt-5/oswe/mai- (responses-only) id — those need per-model wire routing (documented debt), excluded rather than mis-routed. Inherits the leak-safe pooled routing (scope oauth/github-copilot); its bearer/ refresh/api_key never touch the Kimi token (regression test added). Fail-fast on an out-of-range copilot expires_at (would otherwise silently 401 mid-session). Adversarial security review: GO, no CRITICAL/HIGH. Known limitation: Pi's per-model policy-enablement POST is not ported (documented in AGENTS.md). |
||
|
|
5a9183b08b |
feat(providers): add Claude Pro/Max subscription OAuth (PKCE-localhost)
27th registry variant, 2nd subscription-OAuth provider. Log in with a Claude
Pro/Max subscription via PKCE authorization-code + S256 (loopback callback on
127.0.0.1:53692, with a manual code-paste fallback), then use it against
api.anthropic.com — reusing the existing Anthropic Messages wire + Anthropic
listing + the multi-provider OAuth foundation (
|
||
|
|
010f6c3be3 |
feat(providers): add Z.AI coding plan (global + China)
Providers 17-18 (20th & 21st registry variants), sourced authoritatively
from Pi (earendil-works/pi), the open-source agent whose provider list is
being mirrored. Pi's zai.ts / zai-coding-cn.ts use plain openAICompletionsApi
(NO special thinking dialect — overturns the matrix's 'thinking:{type} → new
dialect' concern), so Kigi maps them to Passthrough. Global: api.z.ai/api/
coding/paas/v4, ZAI_API_KEY, models.dev zai-coding-plan. China (Zhipu
BigModel): open.bigmodel.cn/api/coding/paas/v4, ZAI_CODING_CN_API_KEY,
models.dev zhipuai-coding-plan. Both Bearer + OpenAI listing + ChatCompletions
+ restrict_to_enriched; /models is auth-gated → validator.
id-match is PROVEN (not just assumed like Qwen): Pi's static model ids
[glm-4.5-air, glm-4.7, glm-5-turbo, glm-5.1, glm-5.2, glm-5v-turbo] are
byte-identical to the models.dev zai-coding-plan keys, all tool_call=true, so
restrict keeps every model with no silent-empty risk. Review found no defects.
GLM thinking is not lost (reasoning_content is parsed regardless of dialect).
Tests: e2e proves enrichment-supplied context + non-vacuous restrict (a
non-enriched wire model is dropped) + Passthrough; both variants' validation
tests hit /models and assert the per-variant console host (z.ai vs
open.bigmodel.cn). Registry at 21; picker 22 rows.
Also fixes the welcome login-picker test for the now-taller menu (renders at
a taller viewport to verify content coverage) and logs the real menu-overflow
UX debt: the picker clips rows past the fold with no scroll (q/l shortcuts
still work; only shown when unauthenticated) — deferred to its own cycle.
|
||
|
|
c5ddaec71e |
Add per-provider auth.json keys; make auth methods registry-generic (P0b)
Platform API keys now live in auth.json under the platform-id scope (the per-provider auth.json key contract), resolved env > auth.json > legacy [platforms.*] config.toml (read-only fallback). The TUI login picker, paste box, auth-method advertising, and authenticate handler are all registry-generic: a new PlatformSpec row appears in the login UI and authenticates with zero UI changes. Spec rows gained vendor/console_host/ login_label display fields (moonshot strings byte-identical, pinned by tests). Adversarial review caught that auth.json keys were validated at login but never stamped onto catalog entries (completions would 401; restart lost eager auth). Fixed red-green: resolve_model_list/resolve_model_catalog now take a resolved PlatformApiKeys snapshot consumed by the credential- stamping layer (auth.json beats stale config.toml, matching the login validator), with production callers resolving fresh per catalog build. Also from review: the new auth.json writer takes the manager's cross- process flock (bounded retry — an unlocked RMW racing a token refresh could revert a rotated refresh token); the oauth-401 wiremock test is hermetic (KIGI_SHARE_DIR tempdir; it could read a dev's real auth.json and hit live moonshot); cli_models resolves real keys; auth.json is read once per registry sweep; caller-less lock_config_writes deleted; catalog resolvers tightened to pub(crate); stale config.toml doc comments and the no-credentials error copy updated. |
||
|
|
1579558b56 |
Add /graph G2: resumable budget, GraphUpdated status chip, PTY + turn-level coverage
BudgetLimited is now a resumable state: a budget trip demotes in-flight
nodes to Ready (a resource stop, not a verdict — no forever-Running node is
ever persisted) and '/graph resume --budget <tokens>' re-arms the graph with
fresh headroom (new budget = spent-so-far + extra). The tripped node's
partial burn is charged into tokens_spent_nodes at BOTH cascade sites before
the demotion clears current_node, so the top-up arithmetic never runs on an
under-counted ledger. Any input starting with 'resume' resolves to a resume
(case-insensitive; malformed top-ups surface the usage hint) and setup_graph
refuses to replace any non-Complete graph — a typo can no longer silently
destroy a resumable graph. An explicit --budget on a merely-paused graph is
rejected loudly instead of silently discarded; all trip-time messages now
advertise the top-up.
The pager gains a graph status chip: a new GraphUpdated wire variant
(extensions/notification.rs, old pagers degrade via #[serde(other)]) is
emitted from the single persist_graph_state chokepoint — every transition is
both a checkpoint and a badge tick — with a 'cleared' sentinel on /graph
clear and a one-shot re-emit after session restore (the replayed updates log
otherwise shows the pre-shutdown Active state that from_snapshot just
demoted in memory). TUI side: GraphDisplayState, session-notification arm,
and a goal-idiom chip with node progress, clamped current-node title, and
budget-aware spend. Pre-session command availability now advertises /graph
from the flags (it was fail-closed to the in-session path only, so the
welcome-screen slash menu never showed it).
Coverage: GraphUpdated wire round-trip + minimal-payload + unknown-tag
tests; PTY scenarios graph_slash_presession{,_disabled}.yaml (both run
green against the real pager binary); handle_prompt-level e2e for terminal
slash outcomes (/graph status|resume|pause, /goal refusals while the graph
owns the engine); budget top-up e2e driving a BudgetLimited diamond back to
Complete. Not shimmed: pre-G2 persisted snapshots with budget-Failed nodes
(the KIGI_GRAPH flag has never shipped enabled, so none exist).
kigi-shell 4927 and kigi-tui 6610 lib tests green; workspace clippy clean.
|
||
|
|
54c9177ce2 |
Texture the welcome moon with lunar maria
Small scattered mare spots: dark holes on the sunlit disc, faint gray patches on the dark limb. |
||
|
|
10d0c0816f |
Excise the Changelog feature
Kigi never publishes CDN changelogs, so the entire inherited feature
was dead weight: the welcome-menu Changelog row, the hero-box info
slot (bullets + clickable CTA), /release-notes with its /changelog
alias, and the ChangelogManager CDN-fetch/disk-cache pipeline
(Effect::FetchChangelog, TaskResult::ChangelogFetched, startup and
post-login fetch kickoffs, AppView cache fields, mouse hover/click
handling). Welcome menu is now [Import] / New worktree / Resume
session / Quit; the hero box keeps title + version + subtitle and its
layout math simplifies to 3 + menu rows (verified equivalent by the
surviving boundary tests). Action::ShowReleaseNotes and the DocViewer
modal stay — /docs uses them. builtin.rs keeps deleting stale
CHANGELOG.{json,md} caches written by kigi ≤ 0.1.0.
kigi-shell-base drops its reqwest 'blocking' feature (only the deleted
module used it). -1206 lines net.
Gates: fmt clean, workspace check/clippy --all-targets 0/0, kigi-tui
lib 6609 / shell-base 56 / shell util:: 258 all passing, welcome pty
e2e (3 tests incl. braille logo) passing.
|
||
|
|
82ebcc38b7 |
Turn status: moon-phase spinner for Waiting for response
The active-turn spinner next to "Waiting for response…" now cycles the moon phases 🌑🌒🌓🌔🌕🌖🌗🌘 — the official kimi-cli's lunation animation (rich's `moon` spinner) — matching the welcome-screen moon logo. New glyphs::moon_spinner_frames() with the same legacy-ConHost ASCII fallback as every other spinner set; emoji frames are 2 columns and the status row already measures the rendered frame, so layout adapts. The ambient "Starting session…" row and other spinners stay braille. Verified: kigi-tui lib 6621 + pager-render 963 tests green; real-binary PTY e2e waiting_for_model_label_shows_before_first_token passes with the new spinner rendering in a live vt. |
||
|
|
0dc98a34a6 |
/feedback opens the Kigi GitHub issues page
Feedback about an unofficial community build belongs on its own issue tracker, not Moonshot's feedback endpoint — and this mirrors the official kimi-cli, whose /feedback opens its repo's issues page (ISSUE_URL in ui/shell/slash.py). /feedback now returns Action::OpenUrl(https://github.com/ZacharyZhang-NY/Kigi-CLI/issues), the same battle-tested browser path /docs web uses. The now-dead TUI text-feedback pipeline is excised: PromptInputMode:: Feedback (~ prefix composer mode), Action::{EnterFeedbackMode, SendFeedback}, Effect::SendFeedback (the kigi/feedback ACP POST), TaskResult::{FeedbackComplete,FeedbackFailed}, and their dispatchers. The shell-side kigi/feedback ACP extension stays: it is protocol surface for editor embeddings, OAuth-gated, and shared with kigi/btw. Gates: workspace check/clippy --all-targets 0/0, fmt, kigi-tui lib 6621 passed / 0 failed. |
||
|
|
3952c28f16 |
Login picker: offer all three platforms like the official CLI
The unauthenticated welcome screen previously offered only 'Login with
Kimi Code'. It now lists every interactive platform the shell
advertises, matching the official kimi-cli picker:
Kimi Code (OAuth)
Moonshot Open Platform (API key · moonshot.cn)
Moonshot Open Platform (API key · moonshot.ai)
Quit
- Shell: new ACP auth methods moonshot-cn / moonshot-ai (advertised
after kimi-code; the BYOK first-position invariant holds).
authenticate(moonshot-*) reloads keys from env>config, fails with an
actionable message when none is configured, validates the key against
GET {base}/models (401 → 'invalid API key' naming the console), then
swaps the fresh config in, triggers the model sync, and reports
auth_mode api_key so the pager treats it like other API-key logins.
Never session-based; keys never logged.
- Config: save_platform_api_key persists [platforms.<id>].api_key via an
atomic mode-preserving write under the config lock; refuses OAuth
platforms, blank keys, and unparseable files.
- TUI: the Pending welcome renders the picker rows from the advertised
methods (arrows/Enter/mouse; 'l' keeps selecting the OAuth row).
Choosing a Moonshot row opens a masked paste box ('Paste your Moonshot
API key (from platform.moonshot.cn)'); Esc returns to the picker,
Enter persists the key and authenticates in one sequential effect;
failures return to the picker with the error line, success lands on
the normal welcome. Startup eager-auth is unchanged: a key already in
the environment authenticates exactly as before, and single-method
shells keep the historical auto-device-flow.
Gates: workspace check/clippy 0/0; shell 4870 + tui 6620 lib tests
green; headless probe advertises [kimi-code, moonshot-cn, moonshot-ai]
for a fresh user and xai.api_key-first with a key configured.
|
||
|
|
6f31415ed6 |
§9 acceptance: grep-zero sweep — every internal x.ai/grok identifier renamed
The PRD's first acceptance gate now holds: grep -RinE '\bx\.ai\b|grok' crates/ --include='*.rs' → 0 matches (exempt: NOTICE and third-party license archives, README provenance, and the required 'Based on Grok Build Open Source' attribution, now sourced from version_attribution.txt). Wire-visible renames (both sides in this repo, changed in lockstep): - Auth method id 'grok.com' → 'kimi-code' (AuthMethodKind::KimiCode). - Every x.ai/* and _x.ai/* ACP ext method and meta key → kigi/* / _kigi/* (~200 names; grokShell → kigiShell). Session-file replay keeps a read-side alias for the legacy '_x.ai/session/update' method so existing updates.jsonl histories load; writes emit only the new name (both directions test-pinned). - Agent types grok-build* → kigi* with a documented legacy-prefix alias at resolution time so persisted sessions keep resolving. - ToolNamespace/BuiltinAgentName GrokBuild* → Kigi* (wire snake_case kigi/kigi_concise/kigi_hashline; schema regenerated); grok_build implementation dirs renamed to kigi*. - x-grok-* headers → x-kigi-*, __GROK_* sentinels → __KIGI_*, themes grokday/groknight → kigiday/kiginight (old persisted values fall back to the default theme), web_fetch allowlist xAI hosts → kimi.com + moonshot platforms, changelog CDN → this repo, grok-build changelog archives deleted. - BYOK default endpoint removed: [endpoints] api_base_url is now truly optional with NO default — consumers fail fast with the flag name when unset (no silent x.ai egress). Mock harnesses inject it explicitly. - System-prompt identity fixed: 'released by xAI' → 'an unofficial community CLI for Kimi' (template + regenerated encrypted form). Also repaired pre-existing grok-era test debt found by the sweep: the stale trace_classify default-model pin, the grok-pager UA label test, pty-harness stale-binary reuse and non-hermetic moonshot routing (a PTY test could previously reach the real api.moonshot.cn), and the outdated oauth fixture scope key. Gates: §9 grep 0; fmt clean; workspace check/clippy 0/0 (-D warnings); FULL cargo test --workspace: 234 suites, 21,961 passed, 0 failed; deny advisories ok. |
||
|
|
5e4e24db99 |
M2 audit: excise managed connectors and xAI media-gen tools
Managed connectors (grok.com MCP admin) removed root-and-branch: - The managed-MCP fetch/injection pipeline is gone, including the whole kigi-shell-session-support crate (managed-config fetch client, gateway tool catalog + dispatch, header injection, refresh task), reactive managed re-auth, mcp_doctor's grok.com-source discovery, and the [managed_mcps] config surface. - TUI: the 'Managed by grok.com' section, connectors URL/deep-link, Action::OpenManagedConnectors, and session_team_id are gone. Local MCP management (list/toggle/add/remove/auth/tools) is fully intact. - Kept as LOCAL policy: managed-settings.json MCP allow/deny enforcement, the multi-source local MCP merge, folder-trust gating. PluginOrigin Project/User labels kept (they tag locally discovered plugin dirs). imagine/media-gen tools (xAI image/video generation) removed: - image_gen, image_edit, video_gen, image_to_video, reference_to_video implementations, registrations, ToolKind/ToolInput/Output variants (serde-safe), config plumbing end to end, ZDR video machinery, /imagine + /imagine-video commands and guidance text, the bundled imagine skill (added to legacy cleanup so user installs delete it), and the media-gen render path. - Kept: image INPUT (paste/attach, [Image #N] meta, pdf/image fetch, clipboard wrap), generic media-ref rendering, and the generic tool 401-retry machinery (tests renamed, assertions unweakened). - deploy_app stays: it is a permanently-disabled local stub deploying nowhere. 121 files changed, 8 deleted. Gates: workspace check/clippy 0/0, fmt, deny ok; suites green (tools 2554, shell 4862, tui 6608, workspace 1042). Remaining grok.com strings live only in the auth-method ids and changelog archives (§9/M3 sweep). |
||
|
|
74b210535e |
F5: web search/fetch on the Kimi services (kimi-cli parity)
web_search now speaks the Kimi search service (kimi-cli tools/web/search.py,
wire-verified against api.kimi.com):
- POST {coding_base}/search with {text_query, limit 1-20 (default 5),
enable_page_crawling, timeout_seconds: 30}, OAuth bearer +
X-Msh-Tool-Call-Id; results render in kimi-cli's Title/Date/URL/Summary
schema with result URLs as citations.
- The old implementation called the xAI Responses API with a search model;
that client is fully replaced and the entire model-based config surface
is excised root-and-branch: web_search_model config keys/env/CLI plumbing,
resolve_web_search_sampling_config, toolset web_search SamplerConfig,
RemoteSettings.web_search_model, default_web_search_model.
- Enablement is now purely structural: the service exists only on the Kimi
Code subscription channel, so OAuth sessions get Enabled and API-key-only
sessions get Disabled (tool absent) — per PRD F5.
web_fetch gains the Kimi fetch service as its primary path (kimi-cli
tools/web/fetch.py): POST {coding_base}/fetch with {url}, Accept:
text/markdown, OAuth bearer + X-Msh-Tool-Call-Id; the 200 body is the
extracted markdown (still overflow-budgeted). Any service failure falls
back to the existing local pipeline (SSRF guards, cache, extraction).
The tool gate defaults ON now (kimi-cli always offers FetchURL) and the
egress User-Agent no longer claims grok-agent/x.ai.
Verified end-to-end against the scripted mock service: a headless session
drove web_search (limit/crawling/call-id observed on the wire) then
web_fetch (Accept + call-id observed) to completion.
|
||
|
|
0e3d43128e |
Replace the Grok braille logo with a procedurally generated moon
The welcome logo (hero box, stacked layout, and minimal's welcome card) is now a braille moon that waxes and wanes through a full 8s lunation, echoing the Kimi CLI's moon-phase spinner. The disc is rasterized into the 2x4 braille dot grid at render time — round at any size, no art assets — with the terminator at x = cos(2*pi*p)*sqrt(1-y^2) and a faint outline ring so the silhouette survives new moon. The full moon grows to 20x10 cells (from the 14x7 slashed-circle art) and the small tier to 10x5; the old logo*.txt assets are deleted. Geometry is unit-tested (wax/wane monotonicity, quarter-phase symmetry, right-limb-first waxing, silhouette at new moon, round raster). |
||
|
|
5406fb7d68 |
Rebrand remaining user-visible Grok strings to Kigi/Kimi
The welcome hero subtitle still read "Thanks for trying Grok Build"; theme display names, the NO_COLOR/COLORTERM diagnostics notes, the permission notification title, the self-update restart hints, and the clipboard-wrap protocol marker all still said Grok. Canonical theme keys (groknight/grokday) are unchanged — only display strings move. |
||
|
|
ea0ce9d15f |
F3: Kimi inference pipeline + full grok cloud-surface excision
Sampler / inference (PRD F3):
- kimi_compat.rs: single adaptation point for the Kimi chat/completions
dialect (thinking-field mapping, model_id stripping, empty-content
tool-call message fix, stream_options.include_usage), with kimi-cli
source citations
- Rate-limit handling reworked for Kimi/Moonshot semantics; UA kigi/{version}
- /models replaces the xAI models-v2 endpoint everywhere; idle model
refresh carries X-Msh-* device headers only (X-XAI-Token-Auth and
x-grok-client-mode/CLIENT_MODE_HEADER machinery deleted)
Cloud-surface excision (PRD §5, zero-egress):
- remote/ conversations lane, cli-chat-proxy-types crate, prod/ dir,
share command, credit bar: deleted (single local session lane;
paginate() replaces merge_and_paginate)
- Subscription/tier gate stack deleted end-to-end: AppView
gate/tier/team/ZDR fields, app/subscription.rs watch loop,
dispatch/billing.rs paywall + SuperGrok upsell, free-usage-exhausted
chain, tier-restricted commands, GateInfo, RemoteSettings gate fields,
SettingsUpdateNotification gate fields
- /privacy + coding-data-sharing setting deleted (backed by a dead xAI
RPC; Kigi is zero-egress — nothing to share or retain remotely)
Auth UX correctness (user-reported):
- Device-flow fixtures now mirror the live Kimi payload shape
(https://www.kimi.com/code/authorize_device?user_code=..., verified
against auth.kimi.com); the fabricated auth.kimi.com/device?code=...
URLs are gone
- open_browser_detached is a no-op under cfg(test): unit tests drove
wiremock fixture URLs into the real browser (root cause of the
"garbage mock link" ABCD-1234 tabs)
- Welcome/pager-minimal rebrand: Grok Build -> Kigi, grok.com ->
kimi.com, "Sign in to Grok" -> "Sign in to Kimi"
|
||
|
|
fe1f885bb3 |
M1/F2+F4: platform registry, Moonshot API-key channel, dynamic model sync
F2 — fixed three-platform registry in kigi-models: kimi-code (subscription, OAuth bearer, base kigi_env::coding_api_base_url()), moonshot-cn (https://api.moonshot.cn/v1), moonshot-ai (https://api.moonshot.ai/v1) with kimi-k model-prefix filtering. Moonshot API keys via KIGI_MOONSHOT_CN_API_KEY / KIGI_MOONSHOT_AI_API_KEY (+ KIGI_MOONSHOT_API_KEY shared fallback) or ~/.kigi/config.toml; values redacted from logs/display. F4 — model catalog now syncs from GET {base}/models (Bearer auth, wire shape per official kimi-cli: id/context_length/supports_reasoning/ supports_image_in/supports_video_in/display_name) with the official capability-derivation rules (thinking / always_thinking-in-name / kimi-k2 implicit set). Managed keys {platform_id}/{model_id}; default model = first list entry; default thinking iff capabilities contain thinking/always_thinking. Sync failure → last cache; no cache → built-in fallback table seeded from ids sourced in official kimi-cli (kimi-for-coding, kimi-k2-turbo-preview, kimi-k2-thinking-turbo). 401 during sync forces one token refresh and retries. Model resolution priority preserved: CLI > env > config > server > fallback. Grok model artifacts (grok-4*/grok-build catalog, tier gating remnants) removed from non-test code. All first-party endpoints re-verified live: device_authorization mints real codes; /models on all three platforms answers with real API auth errors when unauthenticated. Gates: check/clippy --all-targets 0/0, fmt clean, deny ok, kigi-shell lib 5136 green, kigi-tui lib 6819 green, kigi-models 8. |
||
|
|
d6c20fc13f |
M0: compilable skeleton — Kigi 0.1.0 fork surgery
Hard fork of xai-org/grok-build (Apache-2.0) re-targeted as Kigi, an
unofficial Kimi Code CLI community build.
Rename & identity
- 72 xai-*/xai-grok-* crates -> kigi-* (explicit: xai-grok-pager-bin ->
kigi-bin [binary `kigi`], xai-grok-pager -> kigi-tui; rest mechanical);
ptyctl, ptyctl-cli, third_party/ unchanged; proto package
xai.grok.tools.v1 -> kigi.tools.v1
- Config home ~/.kigi (KIGI_SHARE_DIR override), env prefix GROK_* ->
KIGI_*, `kigi --version` carries the unofficial-community-build notice
- clap identity, help text, startup banner, prompt templates rebranded
(templates re-encrypted)
Deletions (PRD removal list #5/#6/#7/#9/#10)
- voice input (xai-grok-voice) and all TUI wiring
- telemetry: Mixpanel client, external OTel stream, Sentry, OTLP layers,
trace/GCS/S3 upload queues (kigi-file-utils halved), workspace upload
module & dc_log, heap-profile uploader, auth-diagnostics uploader,
session-analytics halves of feedback; local zero-egress observability
preserved in new kigi-log crate (unified log, --debug firehose,
subsystem file logs, opt-in instrumentation)
- announcements (crate, remote-settings fields, TUI surfaces)
- plugin marketplace (crate, sources/browse/CTA/extensions-modal tab);
direct plugin install/uninstall/update via kigi-agent git_install kept
- relay/gateway/assets endpoints and features (agent relay, headless
relay transport, gateway bridge, LeaderEnvUrls); leader IPC socket now
~/.kigi/leader.sock + KIGI_LEADER_SOCKET, no ws-url derivation
- functional types rehomed instead of deleted: PermissionMode ->
kigi-config-types, McpInitStrategy -> kigi-mcp, PrCreationSource ->
session signals, TerminalDiagnostics -> kigi-pager-render, agent_id ->
shell util
Endpoints
- kigi-env rewritten: single production KigiEndpoints {coding_api_base_url
https://api.kimi.com/coding/v1 (KIGI_CODE_BASE_URL), oauth_host
https://auth.kimi.com (KIGI_OAUTH_HOST), update_base_url (GitHub
Releases API), upgrade_page_url}; GrokBuildEnvironment enum deleted
Toolchain & workspace hygiene
- Rust 1.97.0 pinned; edition 2024; full cargo update; git2 hoisted to
workspace at 0.21 (Option->Result API migration), quick-xml 0.41
- Root Cargo.toml hand-maintained (PRD §8.1): version 0.1.0 inherited by
all members, members sorted, unused deps pruned
- cargo-deny advisories gate (deny.toml with documented transitive
exceptions); CI workflow (check/clippy/fmt/deny/test, macOS+Linux)
- cross-crate test seams re-gated behind `test-support` cargo feature;
insta snapshot baselines renamed to the kigi_tui prefix
- clippy --workspace --all-targets: zero warnings; fmt clean
Fixes surfaced by the port
- updater probe/installer divergence (bin/kigi vs bin/grok symlink set)
- idle model-metadata refresh dead under KIGI_CODE_BASE_URL override
(new is_effective_coding_endpoint_url, loopback+override aware)
- macOS symlinked-TMPDIR fixture canonicalization (foreign_sessions,
fast-worktree); RSS measurement tests serialized via serial_test
Docs & legal (Apache §4)
- NOTICE added (upstream attribution + change statement); THIRD-PARTY
notices sustained; kigi-tools ported-code notices extended; README,
CONTRIBUTING, SECURITY, AGENTS.md rewritten
Out of scope for M0 (tracked): Kimi auth/inference (M1), search/fetch,
command parity, config import (M2), Computer Hub excision & final
brand-token sweep (M2), distribution & self-update rewrite (M3).
|