feat(clients): add gajae-code (gjc) as a tracked client - #685
Merged
Conversation
- Register Gjc=26 in define_clients! (COUNT->27) with EnvVar root GJC_CODING_AGENT_DIR + fallback .gjc/agent, relative sessions (N2) - Add sessions/gjc.rs JSONL parser: assistant-only, A1 embedded usage.cost.total reuse, codebuff-style dedup keys, per-line skip - Wire pub mod gjc; add parser + clients unit tests, count 26->27
Empty file, header-only, malformed-line-between-valid, missing model/provider/usage, negative token clamp, negative/absent cost fallback, dedup-key replay collapse, unicode/encoded cwd.
- Cached cluster: gjc_outcomes via non-repricing parse_gjc_file + A1 Hermes guard (reprice only when cost<=0.0) + should_keep_deduped_message; never routes through load_or_parse_source/apply_pricing_to_messages. - Non-cached cluster: gjc_msgs dedup + counts.set(Gjc) + extend.
Proves A1 holds through the lib.rs Hermes guard: embedded usage.cost.total wins for a priceable model; absent-cost message is recomputed. The N1 gate \u2014 fails if cached cluster repriced.
- Add ClientId::Gjc to the generic-loop continue skip set (N3, load-bearing against env-set over-collection). - Dedicated discovery block resolving agent-sessions root in precedence: GJC_CODING_AGENT_DIR -> GJC_CONFIG_DIR/PI_CONFIG_DIR -> $XDG_DATA_HOME/gjc (flattened) -> ~/.gjc/agent/sessions, each gated on use_env_roots, pushing EVERY existence-gated root via push_unique_scan_task (N4, not first-match). WalkDir+*.jsonl covers depth-1 and depth-2. - Tests: depth1+depth2, home-fallback when env disabled, env override, multi-root dedup.
- ClientFilter::Gjc + as_filter_str/to_client_id/from_client_id arms, hidden legacy --gjc flag, enumerated lists, capitalize_client, and test_client_filter_gjc_round_trip (item f). - CLIENT_UI 27th literal (Gajae-Code, hotkey g), wrapped client_display_name, widgets red-claw brand color; data/mod test_client_all 26->27 + test_client_key hotkey g (item g). - provider_identity regression test for gjc provider passthrough (item h).
GJC_CONFIG_DIR/PI_CONFIG_DIR roots, XDG flattened redirect, multi-root push-all (N4), use_env_roots=false suppression, nonexistent root no-panic.
Real binary invocation: gjc fixture surfaces under --client gjc, empty-data is clean, and --client claude does not leak gjc rows.
- G8: cwd-header drives workspace key/label over dash-encoded slug; normalize_workspace_key/workspace_label_from_key contract. - G9a: depth-1 and depth-2 transcripts both discovered. - G9b: replayed session+message id deduped to one (defensive guard).
Supported-clients table (text-only name cell), multi-platform sentence, --client possible values, source filtering list, Windows path table, and per-client JSONL data-format subsection. Inserted before the synthetic meta-client entry; translations for zh-cn/ja/ko.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Replace the text-only name cell with the gjc logo image across all four READMEs.
Point to https://github.com/Yeachan-Heo/gajae-code in all four READMEs.
junhoyeo
approved these changes
Jun 8, 2026
junhoyeo
left a comment
Owner
There was a problem hiding this comment.
Thanks a lot! cc @Yeachan-Heo Congrats!
3 tasks
junhoyeo
added a commit
that referenced
this pull request
Jun 8, 2026
* fix(frontend): register gjc client in submission validation and display constants The clientRegistry vitest enumerates every define_clients! entry in crates/tokscale-core/src/clients.rs and asserts each one validates as a submission and has a display name, logo URL, and color. PR #685 added gjc to the Rust macro but the frontend constants were never updated, so the next push to main broke Frontend CI. Added gjc to: - SUPPORTED_CLIENT_TYPES in types.ts (drives the zod enum that validateSubmission uses) - SOURCE_DISPLAY_NAMES ("Gajae Code") - SOURCE_LOGOS ($GITHUB_CDN_BASE/client-gjc.png — the asset itself is pending in .github/assets/) - SOURCE_COLORS (#FF6B6B) Confidence: high Scope-risk: narrow Directive: When a new client is added to the Rust define_clients! macro, the same id must be added to the four frontend registries in the same PR. The vitest above is the gate. Not-tested: visual rendering of the gjc logo (asset not yet uploaded) * chore: apply cargo fmt across the workspace cargo fmt --check has been failing on main since #685 (Test & Coverage runs on 1492b96, b43dc5f, e644f96 all red). The drift came in over multiple PRs that touched scanner.rs, main.rs, sessions/gjc.rs and tests, where the formatter would have wrapped or reflowed slightly differently than the manually-written form. Ran cargo fmt --all once to bring the whole tree into agreement with rustfmt 1.8.0-stable. No behavioral change. Confidence: high Scope-risk: narrow Directive: Run cargo fmt --all locally before pushing any Rust change, or rely on the CI gate to catch it before merge — drift compounds silently across PRs otherwise. Not-tested: nothing — pure formatting
junhoyeo
added a commit
to chi2nagisa/tokscale
that referenced
this pull request
Jun 9, 2026
cargo fmt over the kimi-code changes from junhoyeo#682 plus the merged scanner.rs, and replace three .len() >= 1 assertions on the Gjc scan results (from junhoyeo#685 on main, only linted under --all-targets) with !is_empty() so cargo clippy --all-targets -- -D warnings passes.
junhoyeo
added a commit
that referenced
this pull request
Jun 9, 2026
* feat(kimi): support kimi-code alongside legacy kimi-cli
- Parse kimi-code wire.jsonl format (usage.record lines) from
~/.kimi-code/sessions/{workspace}/{session}/agents/{agent}/wire.jsonl
- Route parser selection via is_kimi_code_path() in lib.rs
- Scanner discovers both ~/.kimi/sessions (legacy) and ~/.kimi-code/sessions
- Usage query reads credentials from ~/.kimi-code first, fallback to ~/.kimi
- Respect KIMI_CODE_HOME environment variable for custom data directories
- Update README to reflect Kimi Code support
* fix(kimi): respect KIMI_CODE_HOME in parser routing and docs
- is_kimi_code_path() now checks KIMI_CODE_HOME env var in addition
to the literal .kimi-code path segment, fixing mis-routing for
custom installation directories.
- Add serial_test-guarded test for custom KIMI_CODE_HOME paths.
- Update README (EN/ZH/KO) to document the KIMI_CODE_HOME override.
* docs(readme.ja): add kimi-code data path and wire format
Mirror the kimi-code documentation added to README.md, README.ko.md,
and README.zh-cn.md in #682, which missed the Japanese translation:
client table row, cross-platform path table row, and the Kimi Code
wire.jsonl format section.
* fix(kimi): count only turn-scoped usage.record lines
kimi-code tags every usage.record with usageScope: "turn" for per-step
LLM calls made inside a user turn, and "session" for non-turn
bookkeeping such as context compaction rollups. Upstream's own tooling
(apps/vis context-projector) treats a missing usageScope as
session-scoped, so the parser now requires an explicit "turn" before
counting a record.
Constraint: all public kimi-code releases always write usageScope on usage.record lines
Rejected: counting records with a missing usageScope | upstream attributes them to the session scope, not a turn
Rejected: also counting session-scoped compaction usage | review verdict for #682 was to count turn-scoped usage only
Confidence: high
Scope-risk: narrow
Not-tested: real wire.jsonl files containing compaction-emitted session-scoped records
* style: rustfmt kimi additions and fix clippy len_zero in scanner tests
cargo fmt over the kimi-code changes from #682 plus the merged
scanner.rs, and replace three .len() >= 1 assertions on the Gjc scan
results (from #685 on main, only linted under --all-targets) with
!is_empty() so cargo clippy --all-targets -- -D warnings passes.
---------
Co-authored-by: Junho Yeo <i@junho.io>
t1000040
pushed a commit
to tmobi-internal/tokscale
that referenced
this pull request
Jun 30, 2026
* feat(kimi): support kimi-code alongside legacy kimi-cli
- Parse kimi-code wire.jsonl format (usage.record lines) from
~/.kimi-code/sessions/{workspace}/{session}/agents/{agent}/wire.jsonl
- Route parser selection via is_kimi_code_path() in lib.rs
- Scanner discovers both ~/.kimi/sessions (legacy) and ~/.kimi-code/sessions
- Usage query reads credentials from ~/.kimi-code first, fallback to ~/.kimi
- Respect KIMI_CODE_HOME environment variable for custom data directories
- Update README to reflect Kimi Code support
* fix(kimi): respect KIMI_CODE_HOME in parser routing and docs
- is_kimi_code_path() now checks KIMI_CODE_HOME env var in addition
to the literal .kimi-code path segment, fixing mis-routing for
custom installation directories.
- Add serial_test-guarded test for custom KIMI_CODE_HOME paths.
- Update README (EN/ZH/KO) to document the KIMI_CODE_HOME override.
* docs(readme.ja): add kimi-code data path and wire format
Mirror the kimi-code documentation added to README.md, README.ko.md,
and README.zh-cn.md in junhoyeo#682, which missed the Japanese translation:
client table row, cross-platform path table row, and the Kimi Code
wire.jsonl format section.
* fix(kimi): count only turn-scoped usage.record lines
kimi-code tags every usage.record with usageScope: "turn" for per-step
LLM calls made inside a user turn, and "session" for non-turn
bookkeeping such as context compaction rollups. Upstream's own tooling
(apps/vis context-projector) treats a missing usageScope as
session-scoped, so the parser now requires an explicit "turn" before
counting a record.
Constraint: all public kimi-code releases always write usageScope on usage.record lines
Rejected: counting records with a missing usageScope | upstream attributes them to the session scope, not a turn
Rejected: also counting session-scoped compaction usage | review verdict for junhoyeo#682 was to count turn-scoped usage only
Confidence: high
Scope-risk: narrow
Not-tested: real wire.jsonl files containing compaction-emitted session-scoped records
* style: rustfmt kimi additions and fix clippy len_zero in scanner tests
cargo fmt over the kimi-code changes from junhoyeo#682 plus the merged
scanner.rs, and replace three .len() >= 1 assertions on the Gjc scan
results (from junhoyeo#685 on main, only linted under --all-targets) with
!is_empty() so cargo clippy --all-targets -- -D warnings passes.
---------
Co-authored-by: Junho Yeo <i@junho.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds gajae-code (
gjc) as a tracked client so tokscale can report token usage and cost from gjc agent sessions.gjc stores JSONL session transcripts under
~/.gjc/agent/sessions/<project-slug>/*.jsonl(with depth-2 per-pass sub-agent children<slug>/<session>/N-*.jsonl). Each assistant message carries an authoritative per-messageusage.costobject in USD.What's included:
ClientId::Gjc = 26(COUNT→ 27), rooted atGJC_CODING_AGENT_DIRwith a~/.gjc/agentfallback andsessionsrelative path. Additive — no existing client index, ordering, or count changes.sessions/gjc.rs): assistant-only JSONL parsing; reuses the embeddedusage.cost.total(USD) verbatim when present, recomputing from tokens only when absent; codebuff-style message dedup (<session>:<message-id>with a deterministic fallback); per-line skip-on-error;sessionheader andservice_tier_changelines are ignored.if cost <= 0.0 { reprice }) so gjc's authoritative cost is preserved for priceable models and only recomputed when missing.GJC_CODING_AGENT_DIR→GJC_CONFIG_DIR/PI_CONFIG_DIR→$XDG_DATA_HOME/gjc/sessions(flattened, Linux/macOS) →~/.gjc/agent/sessions, gated on env-root strategy and pushing every existence-gated root (overlap collapses via dedup).WalkDircovers depth-1 and depth-2 transcripts.--client gjcfilter,Gajae-Codedisplay name across the TUI client list (hotkeyg), wrapped report, and brand color.--clientvalues, source filtering list, Windows path table, and a per-client data-format subsection.What was tested
All green on a full workspace build:
cargo build --workspacecargo clippy --workspace(clean)cargo test --package tokscale-core— 871 lib tests + 4 gjc integration testscargo test --package tokscale-core --test gjc— end-to-end cost-precedence (embedded cost preserved; absent cost recomputed), workspace-key from dash-encoded slug, recursive depth-1/depth-2 discovery, and message dedup across replayed filescargo test --package tokscale-cli— 590 bin + 118 integration tests, including a real-binary--client gjcend-to-end test, empty-data cleanliness, and filter isolationcargo test --package tokscale-core clients::tests::test_client_id_count(→ 27), plustest_client_all,test_client_key,test_client_filter_gjc_round_tripNotes
GJC_CODING_AGENT_DIR,GJC_CONFIG_DIR,PI_CONFIG_DIR, and the$XDG_DATA_HOME/gjcredirect (which flattens theagent/segment) on Linux/macOS;--homedisables all env-derived roots.Summary by cubic
Add
gjc(gajae-code) as a tracked client. Tokscale now parses gjc JSONL sessions, preserves embedded per‑message USD cost, and supports--client gjcin the CLI and TUI.New Features
ClientId::Gjcwith*.jsonlunderGJC_CODING_AGENT_DIR(fallback~/.gjc/agent/sessions).GJC_CODING_AGENT_DIR→GJC_CONFIG_DIR/PI_CONFIG_DIR→$XDG_DATA_HOME/gjc/sessions→ home; pushes all existing roots with cross-root dedup; walks depth‑1 and depth‑2 transcripts.usage.cost.total(USD) when present and reprices only when missing; per‑message dedup by<session>:<message-id>; skipsservice_tier_changeand bad lines.--client gjcfilter (legacy--gjchidden), display name “Gajae‑Code”, hotkeyg, and branded color.Docs
--clientvalues, source filtering lists, Windows path table, and a per‑client JSONL format section.https://github.com/Yeachan-Heo/gajae-codein all READMEs.Written for commit 1f2d0a8. Summary will update on new commits.