Skip to content

feat(jcode): add support for Jcode - #718

Merged
junhoyeo merged 2 commits into
junhoyeo:mainfrom
yousiki:main
Jun 17, 2026
Merged

feat(jcode): add support for Jcode#718
junhoyeo merged 2 commits into
junhoyeo:mainfrom
yousiki:main

Conversation

@yousiki

@yousiki yousiki commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add Jcode as a first-class local client with JCODE_HOME support and ~/.jcode/sessions/session_*.json discovery.
  • Parse Jcode session snapshots plus matching session_*.journal.jsonl sidecars without spoofing another client identity.
  • Wire Jcode through core aggregation, cache fingerprinting, CLI filters, TUI/frontend display metadata, README docs, and validation tests.

Validation

  • env -u TOKSCALE_EXTRA_DIRS -u CODEX_HOME -u XDG_DATA_HOME -u OPENCODE_DB -u OPENCODE_DISABLE_CHANNEL_DB HOME="$tmp_home" cargo +stable-aarch64-apple-darwin test -p tokscale-core -p tokscale-cli
  • git diff --check upstream/main...HEAD
  • Local Codex read-only review: no blocker/high findings; PR-ready yes.

Summary by cubic

Add first-class Jcode support that parses session_*.json snapshots and merges session_*.journal.jsonl sidecars with accurate token buckets, plus CLI/TUI/frontend integration and source-cache fingerprinting (schema 19, auto invalidation). Journal parsing is hardened with fallback timestamps and safe read behavior for stability.

  • New Features

    • Discover jcode sessions at ~/.jcode/sessions/session_*.json with JCODE_HOME override; parse snapshots + journals, map token_usage to input/output/cache-read/cache-write/reasoning, dedupe by message IDs; integrated with aggregation, pricing, and per-client filtering (--client jcode; legacy --jcode hidden).
    • TUI/frontend: display name, hotkey j, color, logo asset, and types; docs updated.
    • Cache fingerprinting for snapshot+journal pairs; message cache schema bumped to 19 (auto invalidation); tests added for scanner, parser, CLI output, pricing, dedupe, and frontend submit validation.
  • Bug Fixes

    • Use journal file modified time when entries lack timestamps and skip unreadable lines without aborting parsing.

Written for commit 34630f0. Summary will update on new commits.

Review in cubic

@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
tokscale Ignored Ignored Preview Jun 17, 2026 5:45am

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 21 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/tokscale-core/src/sessions/jcode.rs Outdated
Comment thread crates/tokscale-core/src/sessions/jcode.rs
@junhoyeo
junhoyeo merged commit 0ce3d73 into junhoyeo:main Jun 17, 2026
16 checks passed
junhoyeo added a commit that referenced this pull request Jun 22, 2026
…746)

* docs: sync EN/ja/ko/zh-cn for unreleased clients + breaking flag removal

Pre-v3.2.0 documentation sync for the unreleased range (v3.1.3..main):

- #465: replace the now-false legacy per-client flag notices in ja/ko/zh-cn
  (they claimed the removed flags still work) with a v3.2.0 breaking-change
  migration note; add the same note to README.md (which had none).
- #728: document the MiniMax Token Plan subscription source (distinct from the
  MINIMAX_API_KEY row) in all locales; port the entire Subscription Usage
  section into ja/ko/zh-cn (was English-only).
- #718: add the Jcode table row + detail section to the locales missing them.
- #726: document the TOKSCALE_FM_DEBUG env var in all locales.
- #633: add the missing task-attributed report bullet to README.ja Key Features.
- drift: add Junie to the frontend Source-filtering list (all locales).
- #710: fix the MiMo Code repo link (XiaomiMiMo/MiMo -> XiaomiMiMo/MiMo-Code).
- #717: disclose Command Code token usage is estimated (~4 chars/token).

Confidence: medium
Scope-risk: narrow
Directive: ja/ko/zh-cn translations of the ported Subscription Usage section are machine-generated and should get a native-speaker review pass
Not-tested: #713 Antigravity CLI detail section was not added — no English source section exists to port from

* fix(report): feed real session content to the summarizer (#633)

extract_content_for_session unconditionally returned metadata_only_content()
(first_user_message hardcoded None), so the report summarizer never saw any
conversation content and the four real per-client extractors were dead code.

Add content_extractor::extract_session_content, which dispatches to the correct
per-client extractor (opencode/claude/codex/gemini) and falls back to
metadata-only — never erroring or panicking — for unknown clients, missing
candidates, or unreadable/unparseable files. report.rs builds a SessionPathIndex
once (session_id -> transcript file, plus opencode DBs) and threads it through
run_summarizer so each payload carries the real first user message.

Confidence: high
Scope-risk: moderate
Rejected: thread file paths through core's scanner/WikiEntry | too invasive; indexed at the report layer instead
Not-tested: end-to-end opencode/codex/gemini extraction in report.rs (core dispatcher covers claude + all fallback paths; per-client extractors are pre-existing)

* docs: name the breaking release v4.0.0 (was v3.2.0)

The per-client flag removal (#465) is a breaking change, so the next release is v4.0.0, not v3.2.0. Update the migration notes in all four README locales and the main.rs doc comment accordingly.

* fix(report): real Codex/Gemini extraction + (client,session_id) index keying

Addresses automated review feedback on the #633 report-summarizer-content
fix (PR #746). The summarizer still surfaced (none) for normal Codex/Gemini
sessions and could mis-route cross-client session_id collisions.

- content_extractor: parse the current on-disk Codex format (event_msg with
  payload.type == "user_message", text in payload.message) and skip
  harness-injected context blocks (<environment_context>/<system-reminder>/
  <user_instructions>), mirroring sessions::codex.
- content_extractor: Gemini extractor now handles chat-recording JSON
  (messages[].type == "user" / content) and falls back to scanning
  line-delimited JSONL; empty/whitespace user text is treated as not-found.
- extract_session_content: an empty/whitespace first_user_message no longer
  counts as success, so scanning continues to a later candidate with real text.
- report: SessionPathIndex is keyed by (client, session_id) to prevent
  cross-client collisions, and Gemini files are keyed by their in-file
  sessionId (via gemini_session_id_for_file) rather than the filename stem,
  since the wiki entry's session_id is derived from inside the file.
- Added fixture-based regression tests for all of the above.

Constraint: wiki session_id for Gemini comes from the in-file sessionId, not the path stem
Rejected: match any leading '<' for Codex injected blocks | drops legit prompts starting with markup
Confidence: high
Scope-risk: narrow
pinion05 added a commit to pinion05/tokscale that referenced this pull request Jun 23, 2026
* feat(jcode): add support for Jcode

* fix(jcode): handle journal fallback timestamps and read errors
t1000040 pushed a commit to tmobi-internal/tokscale that referenced this pull request Jun 30, 2026
* feat(jcode): add support for Jcode

* fix(jcode): handle journal fallback timestamps and read errors
t1000040 pushed a commit to tmobi-internal/tokscale that referenced this pull request Jun 30, 2026
…unhoyeo#746)

* docs: sync EN/ja/ko/zh-cn for unreleased clients + breaking flag removal

Pre-v3.2.0 documentation sync for the unreleased range (v3.1.3..main):

- junhoyeo#465: replace the now-false legacy per-client flag notices in ja/ko/zh-cn
  (they claimed the removed flags still work) with a v3.2.0 breaking-change
  migration note; add the same note to README.md (which had none).
- junhoyeo#728: document the MiniMax Token Plan subscription source (distinct from the
  MINIMAX_API_KEY row) in all locales; port the entire Subscription Usage
  section into ja/ko/zh-cn (was English-only).
- junhoyeo#718: add the Jcode table row + detail section to the locales missing them.
- junhoyeo#726: document the TOKSCALE_FM_DEBUG env var in all locales.
- junhoyeo#633: add the missing task-attributed report bullet to README.ja Key Features.
- drift: add Junie to the frontend Source-filtering list (all locales).
- junhoyeo#710: fix the MiMo Code repo link (XiaomiMiMo/MiMo -> XiaomiMiMo/MiMo-Code).
- junhoyeo#717: disclose Command Code token usage is estimated (~4 chars/token).

Confidence: medium
Scope-risk: narrow
Directive: ja/ko/zh-cn translations of the ported Subscription Usage section are machine-generated and should get a native-speaker review pass
Not-tested: junhoyeo#713 Antigravity CLI detail section was not added — no English source section exists to port from

* fix(report): feed real session content to the summarizer (junhoyeo#633)

extract_content_for_session unconditionally returned metadata_only_content()
(first_user_message hardcoded None), so the report summarizer never saw any
conversation content and the four real per-client extractors were dead code.

Add content_extractor::extract_session_content, which dispatches to the correct
per-client extractor (opencode/claude/codex/gemini) and falls back to
metadata-only — never erroring or panicking — for unknown clients, missing
candidates, or unreadable/unparseable files. report.rs builds a SessionPathIndex
once (session_id -> transcript file, plus opencode DBs) and threads it through
run_summarizer so each payload carries the real first user message.

Confidence: high
Scope-risk: moderate
Rejected: thread file paths through core's scanner/WikiEntry | too invasive; indexed at the report layer instead
Not-tested: end-to-end opencode/codex/gemini extraction in report.rs (core dispatcher covers claude + all fallback paths; per-client extractors are pre-existing)

* docs: name the breaking release v4.0.0 (was v3.2.0)

The per-client flag removal (junhoyeo#465) is a breaking change, so the next release is v4.0.0, not v3.2.0. Update the migration notes in all four README locales and the main.rs doc comment accordingly.

* fix(report): real Codex/Gemini extraction + (client,session_id) index keying

Addresses automated review feedback on the junhoyeo#633 report-summarizer-content
fix (PR junhoyeo#746). The summarizer still surfaced (none) for normal Codex/Gemini
sessions and could mis-route cross-client session_id collisions.

- content_extractor: parse the current on-disk Codex format (event_msg with
  payload.type == "user_message", text in payload.message) and skip
  harness-injected context blocks (<environment_context>/<system-reminder>/
  <user_instructions>), mirroring sessions::codex.
- content_extractor: Gemini extractor now handles chat-recording JSON
  (messages[].type == "user" / content) and falls back to scanning
  line-delimited JSONL; empty/whitespace user text is treated as not-found.
- extract_session_content: an empty/whitespace first_user_message no longer
  counts as success, so scanning continues to a later candidate with real text.
- report: SessionPathIndex is keyed by (client, session_id) to prevent
  cross-client collisions, and Gemini files are keyed by their in-file
  sessionId (via gemini_session_id_for_file) rather than the filename stem,
  since the wiki entry's session_id is derived from inside the file.
- Added fixture-based regression tests for all of the above.

Constraint: wiki session_id for Gemini comes from the in-file sessionId, not the path stem
Rejected: match any leading '<' for Codex injected blocks | drops legit prompts starting with markup
Confidence: high
Scope-risk: narrow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants