Skip to content

refactor(tui): simplify pipeline event rendering logic#6

Closed
unohee wants to merge 9 commits into
mainfrom
feature/int-1088-trace-collector
Closed

refactor(tui): simplify pipeline event rendering logic#6
unohee wants to merge 9 commits into
mainfrom
feature/int-1088-trace-collector

Conversation

@unohee

@unohee unohee commented Mar 5, 2026

Copy link
Copy Markdown
Owner

Summary

Refactor pipeline event rendering logic in Chat TUI for better code quality and maintainability.

Changes

  • Remove unused timestamp field from stage events
  • Simplify variable names for better readability
  • Replace conditional chains with status map object
  • Merge task info extraction into single loop
  • Reduce code complexity while maintaining functionality

Files Changed

  • src/support/chatTui.ts - Simplified pipeline event rendering (39 insertions, 76 deletions)

Related Issues

  • Linear: INT-1088

🤖 Generated with Claude Code

Heewon Oh and others added 9 commits March 4, 2026 01:04
에이전트 실행 추적을 위한 핵심 모듈 구현:
- Span/Trace 데이터 모델 정의 (trace_id, span_id, parent_span_id, status 등)
- TraceCollector 클래스: start/end trace, start/end span, recordError
- parent-child span 계층 구조 관리
- 22개 단위 테스트 전체 통과

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace claude-sonnet-4-20250514 (invalid) with claude-sonnet-4-5-20250929 across all configs

- Add detailed stderr logging in planner.ts for debugging Claude CLI failures

- Improve error handling in chat.ts to capture stderr output

- Add real-time stderr logging and structured error messages

This fixes 'Claude CLI exited with code 1' errors caused by invalid model ID.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add /api/pipeline endpoint to expose stage events from eventHub

- Redesign TUI Tasks tab to show pipeline stages in table format

- Display task ID, stage name, model, tokens, cost, and status

- Show 15 most recent pipeline events with status indicators (◐/●/✗)

Tasks tab now matches web dashboard's pipeline view for better visibility.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Claude CLI does not support --disable-hooks flag.

Removed to prevent 'unknown option' error.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add 1-minute TTL cache for inProgress, backlog, and myIssues queries

- Add clearLinearCache() to invalidate cache on mutations

- Clear cache after updateIssueState and createIssue

- Add cache logging for monitoring hit/miss rates

This addresses Linear rate limit (5000 req/hour) by caching frequently

accessed issue lists. Each heartbeat previously made 40+ API calls per

10 issues (N+1 query problem). Now only 1 call if cache is valid.

Note: src/linear/linear.ts exceeds 1000 lines (1081), refactoring needed.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implement token bucket rate limiter to prevent API abuse:

- Claude API: 20 req/min (conservative, adjustable by tier)

- Linear API: 80 req/min (4800/hour with 20% safety margin)

- GitHub API: 80 req/min (4800/hour with 20% safety margin)

Features:

- Token bucket algorithm with automatic refill

- Request queuing with configurable timeout (default 1-2min)

- Per-service metrics tracking (total, rejected, queued, current tokens)

- Graceful initialization/cleanup in service lifecycle

- HTTP API endpoint: GET /api/rate-limits for monitoring

Integration:

- Applied to all Linear API calls (issues, states, mutations)

- Ready for Claude CLI and GitHub API integration

Note: src/linear/linear.ts needs refactoring (1084 lines)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Problem:

- LanceDB append-only → 265 files accumulate (no deletion support)

- 5.7MB with 8.4KB avg file size → fragmentation

- cleanupExpired() only logs, doesn't delete

- Backup files (.corrupted, .bak) accumulate (+1.6MB waste)

Solution:

- Implement full compaction: read → filter → deduplicate → recreate

- Remove expired records (expiresAt < now)

- Remove decayed records (decay >= 0.7)

- Remove unimportant records (importance < 0.1)

- Deduplicate similar memories (cosine similarity >= 0.85)

- Clean up backup files

Scheduling:

- Daily at 2 AM (cron: 0 2 * * *)

- Auto-check if needed (>20% waste or >1000 records)

- Result: 265 files → ~50-100 files expected

New functions:

- compactMemoryTable(): Main compaction logic

- shouldCompact(): Heuristic check

- cleanupBackupFiles(): Remove .corrupted/.bak files

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Remove unused timestamp field from stage events
- Simplify variable names for better readability (event -> ev)
- Replace conditional chains with status map object
- Merge task info extraction into single loop
- Reduce code complexity while maintaining functionality

Refs: INT-1088

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@unohee unohee closed this Mar 5, 2026
@unohee unohee deleted the feature/int-1088-trace-collector branch March 5, 2026 08:43
unohee added a commit that referenced this pull request Apr 20, 2026
- longRunningMonitor: compile user-supplied completion patterns via
  `safeCompileRegex()` (length cap + try/catch) instead of `new RegExp()`
  directly, and reject malformed `checkCommand` on registration. The
  bash invocation is still intentional — dashboard operators need to
  compose shell probes — so it is annotated accordingly rather than
  rewritten.
- scheduler: invoke `claude` via spawn argv instead of
  `bash -c "cd $path && claude -p \"$(cat $file)\" ..."`. The child
  process already gets `cwd`, so the extra shell layer (and the
  metacharacter-sensitive string interpolation) is unnecessary.
- pairPipeline/longRunningMonitor: move tainted values out of the
  `console.*` first argument so they can never be interpreted as
  `util.format` specifiers.

Resolves CodeQL `js/regex-injection` (#6, #7), `js/command-line-injection`
(#9), and two `js/tainted-format-string` alerts (#22, #23).
unohee added a commit that referenced this pull request Apr 20, 2026
* ci: set minimal workflow permissions on CI pipeline

Adds a top-level `permissions: contents: read` to .github/workflows/ci.yml
so every job runs with the least-privileged GITHUB_TOKEN. Resolves
CodeQL `actions/missing-workflow-permissions` alerts 1-5.

* fix(web): strict CORS origin check and sanitized error responses

- Replace `origin.startsWith('http://tauri.localhost')`-style checks with
  URL-parsed hostname matching. Prefix comparison admitted hosts like
  `http://tauri.localhost.evil.com`; the new guard compares hostnames
  exactly and validates the Tailscale CGNAT range by octet.
- Stop sending raw `String(err)` in JSON responses. `safeErrorMessage()`
  returns only `err.message` (or a generic string), so stack traces and
  non-Error object details no longer leak to the dashboard client.

Resolves CodeQL `js/incomplete-url-substring-sanitization` (#20, #21)
and `js/stack-trace-exposure` (#10#19).

* fix(automation): harden regex, shell, and logging inputs

- longRunningMonitor: compile user-supplied completion patterns via
  `safeCompileRegex()` (length cap + try/catch) instead of `new RegExp()`
  directly, and reject malformed `checkCommand` on registration. The
  bash invocation is still intentional — dashboard operators need to
  compose shell probes — so it is annotated accordingly rather than
  rewritten.
- scheduler: invoke `claude` via spawn argv instead of
  `bash -c "cd $path && claude -p \"$(cat $file)\" ..."`. The child
  process already gets `cwd`, so the extra shell layer (and the
  metacharacter-sensitive string interpolation) is unnecessary.
- pairPipeline/longRunningMonitor: move tainted values out of the
  `console.*` first argument so they can never be interpreted as
  `util.format` specifiers.

Resolves CodeQL `js/regex-injection` (#6, #7), `js/command-line-injection`
(#9), and two `js/tainted-format-string` alerts (#22, #23).

* fix(knowledge): defend graph file paths and untaint log calls

- store.ts: resolve every `<STORE_DIR>/<slug>.json` path through
  `resolveGraphPath()` and reject anything that escapes STORE_DIR.
  `toProjectSlug()` already strips non-alnum chars, so this is
  defense-in-depth for callers that forget to sanitize.
- store.ts / index.ts: pass slugs and project paths as separate
  `console.*` arguments instead of interpolating them into the first
  argument, so `util.format` never sees tainted specifiers.

Resolves CodeQL `js/path-injection` (#28) and the remaining
`js/tainted-format-string` alerts (#24#27).

* fix(monitor): argv-only checkCommand and regex sanitizer

BREAKING CHANGE: LongRunningMonitor.checkCommand is now `string[]`
(argv) instead of a shell string. Pipes, redirects, and substitutions
no longer work out of the box — wrap shell logic in a script and call
the script via argv.

- Replace `execFile('bash', ['-c', command])` with
  `execFile(program, args, { shell: false })`. Shell metacharacters in
  argv elements are inert because no shell interprets them, which
  eliminates the underlying command-injection surface and resolves
  CodeQL alert `js/command-line-injection`.
- Validate every argv token against a control-character-free allowlist
  (`ARGV_SAFE`) and bound length at register time and inside
  `executeCheck`. Legacy persisted monitors with string checkCommand
  are skipped at load with a warning rather than crashing the service.
- Zod schema (`LongRunningMonitorConfigSchema.checkCommand`) and the
  `POST /api/monitors` handler now require a non-empty string array,
  with a clearer 400 error pointing at the new shape.
- Regex sanitizer: `safeCompileRegex()` additionally rejects any input
  containing control characters via an ALLOWED_REGEX_CHARS allowlist.
  This doubles as a CodeQL sanitizer for `js/regex-injection`.
- Refresh `config.example.yaml` monitor example to argv form with a
  note about shell semantics.

Resolves the two new alerts (#29 `js/regex-injection`,
#30 `js/command-line-injection`) flagged on PR #46.

* fix(monitor): constrain checkCommand program to an allowlist

Argv-only invocation alone still let `execFile` spawn any binary
reachable from `PATH`, which CodeQL correctly flags as a
command-injection sink. Gate the program before it reaches `execFile`:

- Bare names must be in ALLOWED_PROGRAMS (curl, wget, ssh, jq, grep,
  awk, sed, cat, tail, head, nvidia-smi, kubectl, docker, podman).
  Extending the list is a deliberate code change, not a config change.
- Absolute paths / `~/...` must resolve under a trusted prefix
  (`/usr/local/bin/`, `/usr/local/sbin/`, `/opt/`, `$HOME/bin/`,
  `$HOME/.local/bin/`, `$HOME/scripts/`, `$HOME/.openswarm/monitors/`).
- `..` is rejected outright to prevent traversal tricks against the
  prefix checks.
- Validation runs both inside `isValidArgv` and again at the call site
  in `executeCheck`, so the program value flowing into `execFile` is
  always vetted — this is what CodeQL needs to see as a sanitizer.

Resolves the remaining CodeQL alert #31 `js/command-line-injection`
on PR #46.
Link-Start pushed a commit to Link-Start/OpenSwarm-unohee that referenced this pull request Jul 3, 2026
Behavioral + deterministic guardrails against the systematic swarm
defects surfaced reviewing autonomous PRs unohee#201-207 (approve 3 /
request-changes 3 / reject 1).

Prompt rules (worker Rules + reviewer criteria, en + ko):
- unohee#1 on import/SDK failure, fix the env — never re-author a third-party
  package or spoof its __version__
- unohee#2 cite the counterparty's real producer/consumer code for cross-service
  contracts; no self-referential tests
- unohee#4 don't delete "verified" statements without counter-evidence; include a
  before/after distribution for score/gate/metric changes
- reviewer criteria: contract integrity, evidence & wiring, scope

Deterministic guards (pipelineGuards, non-blocking):
- deadModuleCheck (unohee#5): flag newly-added source modules nothing imports/calls
- reformatCheck (unohee#6): flag reformat-only files and oversized diffs
- getWorkingDiffDetail (gitTracker): per-file numstat + new/whitespace-only flags
- surface non-blocking guard warnings to the reviewer (previously log-only)

Wired via PipelineGuardsConfig (deadModuleCheck/reformatCheck) + config.example.

Out of scope, tracked as follow-up: canonical-package registry (unohee#1),
deterministic contract verification (unohee#2), orchestrator file-overlap
serialization + PR-overlap report (#3).
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.

1 participant