Skip to content
This repository was archived by the owner on Jul 30, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
31e0869
refactor(tui): clarify report information architecture
makoMakoGo Jul 16, 2026
1a336bb
ci: prepare source-first session navigation
makoMakoGo Jul 17, 2026
f55b64a
ci: validate source-first session navigation
makoMakoGo Jul 17, 2026
5a1235c
ci: capture session patch diagnostics
makoMakoGo Jul 17, 2026
457ebea
ci: normalize generated patch anchors
makoMakoGo Jul 17, 2026
79ccba4
ci: align session insertion anchor
makoMakoGo Jul 17, 2026
68dfacc
ci: align aggregation sort anchor
makoMakoGo Jul 17, 2026
00451e4
ci: make prepared patch whitespace-stable
makoMakoGo Jul 17, 2026
62dcab0
ci: capture format diagnostics
makoMakoGo Jul 17, 2026
1439712
ci: fix generated footer match arm
makoMakoGo Jul 17, 2026
ffb340e
ci: capture clippy and test diagnostics
makoMakoGo Jul 17, 2026
0c938cd
ci: apply focused session lint fixes
makoMakoGo Jul 17, 2026
93735a0
ci: inspect session navigation integration points
makoMakoGo Jul 17, 2026
c547fbf
ci: collect session navigation integration points
makoMakoGo Jul 17, 2026
83289b3
ci: validate source-first session navigation
makoMakoGo Jul 17, 2026
3c06d55
ci: run session navigation validation on branch push
makoMakoGo Jul 17, 2026
a8dfb17
ci: apply and validate session navigation implementation
makoMakoGo Jul 17, 2026
d1b5c57
ci: trigger session navigation validation
makoMakoGo Jul 17, 2026
242fc5d
ci: register session navigation validation
makoMakoGo Jul 17, 2026
e36c596
ci: trigger registered session validation
makoMakoGo Jul 17, 2026
970d78a
ci: make session validation self-reporting
makoMakoGo Jul 17, 2026
8a000df
ci: execute self-reporting session validation
makoMakoGo Jul 17, 2026
fc30b3c
ci: trigger base-defined session validation
makoMakoGo Jul 17, 2026
e2790e7
ci: validate source-first Sessions implementation
makoMakoGo Jul 17, 2026
8b6a9ce
ci: trigger Sessions validation on pull requests
makoMakoGo Jul 17, 2026
060e705
ci: capture Sessions patch conflicts
makoMakoGo Jul 17, 2026
7278638
ci: normalize Sessions patch metadata before validation
makoMakoGo Jul 17, 2026
4297c9c
ci: upload normalized Sessions patch diagnostics
makoMakoGo Jul 17, 2026
b73b739
ci: validate Sessions lint cleanup
makoMakoGo Jul 17, 2026
6bd31d0
ci: materialize source-first Sessions implementation
makoMakoGo Jul 17, 2026
d4c0f83
ci: finalize issue 153 into one clean PR commit
makoMakoGo Jul 17, 2026
a312c17
ci: finalize issue 153 after validation
makoMakoGo Jul 17, 2026
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
1,846 changes: 1,846 additions & 0 deletions .github/session-navigation-v2.patch

Large diffs are not rendered by default.

195 changes: 195 additions & 0 deletions .github/workflows/finalize-issue-153-v3.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
name: Finalize Issue 153 V3

on:
push:
branches:
- codex/issue-153-session-navigation

permissions:
contents: write

concurrency:
group: finalize-issue-153-v3
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always
FORMAL_BRANCH: codex/issue-153-tui-information-architecture
BASE_BRANCH: personal/local-clients

jobs:
finalize:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
ref: codex/issue-153-session-navigation
fetch-depth: 0

- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Materialize source-first Sessions implementation
run: |
if ! grep -q 'pub struct SessionUsage' crates/tokscale-core/src/usage_views.rs; then
for patch in .github/session-patches/*.patch; do
git apply --check "$patch"
git apply "$patch"
done
fi

- name: Apply focused cleanup
run: |
python3 <<'PY'
from pathlib import Path
import re

def replace_if_present(path: str, old: str, new: str) -> None:
file = Path(path)
text = file.read_text()
if old in text:
file.write_text(text.replace(old, new, 1))

replace_if_present(
"crates/tokscale-cli/src/tui/ui/issues.rs",
"Constraint::Length(health_height.min(area.height))",
"Constraint::Length(health_height)",
)
replace_if_present(
"crates/tokscale-cli/src/tui/data/mod.rs",
"aggregate_by_period, aggregate_by_weekday, build_period_usage, find_peak_hour,",
"aggregate_by_period, build_period_usage, find_peak_hour,",
)
replace_if_present(
"crates/tokscale-cli/src/tui/ui/hourly_profile.rs",
"#[cfg(test)]\nmod tests {\n use super::*;\n\n #[test]",
"#[cfg(test)]\nmod tests {\n #[test]",
)

app = Path("crates/tokscale-cli/src/tui/app.rs")
text = app.read_text()
tuple_pattern = re.compile(
r"let mut sources:\s*BTreeMap<\s*String,\s*"
r"\(BTreeSet<String>, usize, u32, u32, u64, f64, i64\),\s*>\s*"
r"=\s*BTreeMap::new\(\);"
)
replacement = (
"type SessionSourceAggregate = "
"(BTreeSet<String>, usize, u32, u32, u64, f64, i64);\n"
" let mut sources: BTreeMap<String, SessionSourceAggregate> = "
"BTreeMap::new();"
)
text = tuple_pattern.sub(replacement, text, count=1)
obsolete_test = re.compile(
r"\n #\[test\]\n"
r" fn issues_tab_key_scrolls_text_viewport_without_table_selection\(\) \{.*?"
r"\n \}\n",
flags=re.DOTALL,
)
text = obsolete_test.sub("\n", text, count=1)
app.write_text(text)

cache = Path("crates/tokscale-cli/src/tui/cache.rs")
text = cache.read_text()

def matching_brace(source: str, opening: int) -> int:
depth = 0
in_string = False
escaped = False
for index in range(opening, len(source)):
char = source[index]
if in_string:
if escaped:
escaped = False
elif char == "\\":
escaped = True
elif char == '"':
in_string = False
continue
if char == '"':
in_string = True
elif char == "{":
depth += 1
elif char == "}":
depth -= 1
if depth == 0:
return index
raise SystemExit("unterminated UsageData initializer")

insertions = []
for match in re.finditer(r"\bUsageData\s*\{", text):
before = text[max(0, match.start() - 100):match.start()]
if re.search(r"(?:impl|struct|enum|trait|fn)[^\n{]{0,100}$", before):
continue
opening = text.find("{", match.start())
closing = matching_brace(text, opening)
block = text[match.start():closing + 1]
if "sessions:" in block or "..Default" in block:
continue
agent_line = re.search(r"(?m)^(\s*)agents:\s*Vec::new\(\),\s*$", block)
if agent_line is None:
continue
absolute_end = match.start() + agent_line.end()
insertions.append((absolute_end, agent_line.group(1)))

if len(insertions) > 1:
raise SystemExit(f"ambiguous missing sessions fields: {len(insertions)}")
for position, indent in reversed(insertions):
text = text[:position] + f"\n{indent}sessions: Vec::new()," + text[position:]
cache.write_text(text)

themes = Path("crates/tokscale-cli/src/tui/themes.rs")
if themes.exists():
text = themes.read_text()
if text.count("metric_total_style(") == 1:
text = re.sub(
r"\n pub\(crate\) fn metric_total_style\(&self\) -> Style \{.*?\n \}\n",
"\n",
text,
count=1,
flags=re.DOTALL,
)
themes.write_text(text)
PY

- name: Remove temporary validation scaffolding
run: |
rm -rf .github/session-patches
rm -f \
.github/session-navigation-v2.patch \
.github/session-navigation-patch-source.yml \
.github/session-navigation-trigger \
.github/workflows/prepare-session-navigation.yml \
.github/workflows/session-navigation-diagnostics.yml \
.github/workflows/session-navigation-validation.yml \
.github/workflows/session-navigation-validation-v2.yml \
.github/workflows/session-navigation-materialize.yml \
.github/workflows/finalize-issue-153.yml \
.github/workflows/finalize-issue-153-v3.yml

- name: Format
run: cargo fmt --all

- name: Apply safe Clippy suggestions
run: |
cargo clippy --fix --workspace --all-targets --all-features \
--allow-dirty --allow-staged -- -W warnings || true
cargo fmt --all

- name: Strict Clippy
run: cargo clippy --workspace --all-targets --all-features -- -D warnings

- name: Full test suite
run: cargo test --workspace --all-targets --all-features

- name: Publish one semantic commit to the formal PR branch
run: |
git config user.name "OpenAI Codex"
git config user.email "codex@openai.com"
git fetch origin "$BASE_BRANCH" "$FORMAL_BRANCH"
git reset --soft "origin/$BASE_BRANCH"
git add -A
git commit -m "refactor(tui): reorganize overview stats and sessions"
git push --force-with-lease origin "HEAD:$FORMAL_BRANCH"
186 changes: 186 additions & 0 deletions .github/workflows/finalize-issue-153.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
name: Finalize Issue 153

on:
push:
branches:
- codex/issue-153-session-navigation

permissions:
contents: write

concurrency:
group: finalize-issue-153
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always
FORMAL_BRANCH: codex/issue-153-tui-information-architecture
BASE_BRANCH: personal/local-clients

jobs:
finalize:
if: github.actor != 'github-actions[bot]'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
ref: codex/issue-153-session-navigation
fetch-depth: 0

- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Materialize Sessions implementation when needed
run: |
if [ -d .github/session-patches ]; then
for patch in .github/session-patches/*.patch; do
git apply --check "$patch"
git apply "$patch"
done
fi

- name: Apply focused cleanup
run: |
python3 <<'PY'
from pathlib import Path
import re

issues = Path("crates/tokscale-cli/src/tui/ui/issues.rs")
text = issues.read_text().replace(
"Constraint::Length(health_height.min(area.height))",
"Constraint::Length(health_height)",
)
issues.write_text(text)

app = Path("crates/tokscale-cli/src/tui/app.rs")
text = app.read_text()
tuple_pattern = re.compile(
r"let mut sources:\s*BTreeMap<\s*String,\s*"
r"\(BTreeSet<String>, usize, u32, u32, u64, f64, i64\),\s*>\s*"
r"=\s*BTreeMap::new\(\);"
)
replacement = (
"type SessionSourceAggregate = "
"(BTreeSet<String>, usize, u32, u32, u64, f64, i64);\n"
" let mut sources: BTreeMap<String, SessionSourceAggregate> = "
"BTreeMap::new();"
)
text, replacements = tuple_pattern.subn(replacement, text, count=1)
if replacements == 0 and not any(
marker in text
for marker in ("SessionSourceAggregate", "SessionSourceAccumulator")
):
raise SystemExit("could not locate the session source accumulator")
app.write_text(text)

cache = Path("crates/tokscale-cli/src/tui/cache.rs")
text = cache.read_text()

def matching_brace(source: str, opening: int) -> int:
depth = 0
in_string = False
escaped = False
for index in range(opening, len(source)):
char = source[index]
if in_string:
if escaped:
escaped = False
elif char == "\\":
escaped = True
elif char == '"':
in_string = False
continue
if char == '"':
in_string = True
elif char == "{":
depth += 1
elif char == "}":
depth -= 1
if depth == 0:
return index
raise SystemExit("unterminated UsageData initializer")

insertions = []
for match in re.finditer(r"\bUsageData\s*\{", text):
before = text[max(0, match.start() - 100):match.start()]
if re.search(r"(?:impl|struct|enum|trait|fn)[^\n{]{0,100}$", before):
continue
opening = text.find("{", match.start())
closing = matching_brace(text, opening)
block = text[match.start():closing + 1]
if "sessions:" in block or "..Default" in block:
continue
agent_line = re.search(r"(?m)^(\s*)agents:\s*Vec::new\(\),\s*$", block)
if agent_line is None:
raise SystemExit("UsageData initializer without sessions has no simple agents field")
absolute_end = match.start() + agent_line.end()
insertions.append((absolute_end, agent_line.group(1)))

if len(insertions) > 1:
raise SystemExit(f"expected at most one missing sessions field, found {len(insertions)}")
for position, indent in reversed(insertions):
text = text[:position] + f"\n{indent}sessions: Vec::new()," + text[position:]
cache.write_text(text)
PY

- name: Remove validation scaffolding
run: |
rm -rf .github/session-patches
rm -f \
.github/workflows/session-navigation-validation.yml \
.github/workflows/session-navigation-validation-v2.yml \
.github/workflows/session-navigation-materialize.yml \
.github/workflows/finalize-issue-153.yml

- name: Format
run: cargo fmt --all

- name: Clippy
id: clippy
continue-on-error: true
run: |
set -o pipefail
cargo clippy --workspace --all-targets --all-features -- -D warnings 2>&1 |
tee issue-153-clippy.log

- uses: actions/upload-artifact@v4
if: always()
with:
name: issue-153-clippy-log
path: issue-153-clippy.log
if-no-files-found: warn

- name: Stop after Clippy failure
if: steps.clippy.outcome == 'failure'
run: exit 1

- name: Test
id: test
continue-on-error: true
run: |
set -o pipefail
cargo test --workspace --all-targets --all-features 2>&1 |
tee issue-153-test.log

- uses: actions/upload-artifact@v4
if: always()
with:
name: issue-153-test-log
path: issue-153-test.log
if-no-files-found: warn

- name: Stop after test failure
if: steps.test.outcome == 'failure'
run: exit 1

- name: Publish one clean semantic commit to PR branch
run: |
git config user.name "OpenAI Codex"
git config user.email "codex@openai.com"
git fetch origin "$BASE_BRANCH" "$FORMAL_BRANCH"
git merge-base --is-ancestor "origin/$BASE_BRANCH" HEAD
git reset --soft "origin/$BASE_BRANCH"
git add -A
git commit -m "refactor(tui): reorganize overview stats and sessions"
git push --force-with-lease origin "HEAD:$FORMAL_BRANCH"
Loading
Loading