Commit Graph

117 Commits

Author SHA1 Message Date
YeonGyu-Kim 607e9c3cec docs(omo-codex): batch 60 (4 files) 2026-05-30 19:12:10 +09:00
YeonGyu-Kim f9bbe0517b fix(team-mode): fix lifecycle-test-fixture ask type + update bun.lock 2026-05-26 18:51:25 +09:00
YeonGyu-Kim 5f1fb0c52a fix(team-mode): make lead close teams on its own initiative
The lead currently leaves teams alive after the task list drains because
none of the prompt surfaces tell it WHEN to close or HOW. omx-style
'self-closing' behavior was missing for four reasons (diagnosed via
prompt-engineering A/B/C: wrong / misframed / missing):

1. builtin team-mode skill 'Lifecycle' (B+C): 'phase ends / shape
   outgrown' is qualitative, so the model maps it to 'wait for user'.
   Step 6 jumped to team_delete without the request/approve pair the
   tool contract requires. Replaced with a 'Closure Contract' (a
   computable predicate over team_task_list + team_status) and an
   explicit 'Closure Sequence' (request -> approve -> delete, with
   force=true reserved for unrecoverable paths only).

2. TEAM_MESSAGE keyword injection (C): spent 100%% of its one-shot
   budget on routing ('do not substitute delegate_task'), 0%% on
   closure. Added the same closure rule in compressed form. Kept the
   'NEVER substitute with delegate_task' literal that
   keyword-detector/index.test.ts depends on.

3. team-mode-status-injector body (C): the only per-session injection
   for team mode had no closure obligation. Replaced the optional
   'load the team-mode skill ... otherwise use the team_* tools'
   sentence with a 'Closure invariant' clause that ties the check to
   every team_task_update.

4. member-guidance Wrap-up (A+B): step 3 said 'so the lead can decide
   whether to request shutdown', but team_shutdown_request is
   lead-only - members cannot initiate it. Step ordering also placed
   the completion message before team_task_update, so the lead's
   closable check would see stale data. Reordered to
   task_update -> check task_list for new work -> if nothing left,
   send a single 'closure-ready' message and idle. Test assertion
   updated to match the new accurate contract.

Also: stripped Korean alternation from TEAM_PATTERN per directive
('절대로 코드 내에 한국어 적지 마라'). Pattern is now
/\\bteam[\\s_-]?mode\\b/i. Removed 4 Korean test cases
(2 positive triggers + 2 false-positive guards) that the pattern no
longer needs to defend, and updated the keyword-detector AGENTS.md
row.

Net: -71 lines across prompt surfaces. The Closure Contract is the
only addition; everything else tightened.

Tests: 428/428 pass across src/features/team-mode/,
src/features/builtin-skills/, src/hooks/keyword-detector/,
src/hooks/team-mode-status-injector/, src/hooks/team-mailbox-injector/,
src/hooks/team-tool-gating/, src/hooks/team-session-events/.
LSP: no errors introduced (one pre-existing error in
keyword-detector/index.test.ts confirmed pre-existing on dev).
2026-05-24 15:21:24 +09:00
YeonGyu-Kim bc0da0fad3 test: fix prometheus-prompt syntax + sync display name casing to lowercase
- prometheus-prompt.test.ts: close missing }) on the OpenSpec expanded
  commands describe block (introduced by d66b6bcbf, parse error).
- agent-sort-shim/agent-config-integration/continuation-injection/
  unstable-agent-babysitter/subagent-resolver/sync-executor/
  resolve-caller-team-lead tests: expect 'Sisyphus - ultraworker'
  (lowercase) to match production after cd39f8858, which lowercased the
  display name to dodge a TUI ZWSP rendering glitch. Legacy uppercase
  inputs that exercise the normalization path are preserved.
- sync-executor.ts + resolve-caller-team-lead.ts: route legacy display
  name inputs through normalizeAgentForPrompt so prompt agent names and
  caller team lead lookups produce the canonical lowercase form.
2026-05-22 00:07:46 +09:00
YeonGyu-Kim 6dcb2afd41 Merge pull request #3838 from NICxKMS/fix/team-mode-windows-atomic-write
fix(team-mode): sync atomic writes through writable handle
2026-05-21 00:46:24 +09:00
YeonGyu-Kim e824115a2f Merge pull request #4063 from PeterPonyu/fix/3963-server-url-port-zero
fix(team-mode): surface port-0 fallback and silent layout skip (#3963)
2026-05-21 00:42:20 +09:00
YeonGyu-Kim cb124f75a5 Merge pull request #4065 from PeterPonyu/fix/3987-team-create-hard-reject-validation
fix(team-mode): reject team_create from hard-reject agents (#3987)
2026-05-21 00:42:04 +09:00
YeonGyu-Kim a1f03c8461 Merge pull request #4066 from PeterPonyu/fix/2887-filter-terminal-probe-replies
fix(tmux-subagent): drain terminal probe replies during delegated pane startup (#2887)
2026-05-21 00:41:57 +09:00
YeonGyu-Kim 4611856176 Merge pull request #4172 from MoerAI/fix/team-mode-base-dir-chmod-eperm 2026-05-20 18:59:59 +09:00
YeonGyu-Kim da5aa7f32e test(team-mode): allow reclaimed reservations to stay readable
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-20 13:05:57 +09:00
YeonGyu-Kim f79da77fe0 test(team-mode): decouple resume history fixture from session routing
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-20 13:00:48 +09:00
YeonGyu-Kim af42f0ac70 test(team-mode): stabilize resume stale reservation history check
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-20 12:52:00 +09:00
YeonGyu-Kim 655dffbc2a fix(team-mode): release reservation on ambiguous failure, commit on success-path mark failure
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-20 12:30:02 +09:00
YeonGyu-Kim 7adb833609 test(team-mode): add red tests for ambiguous delivery loss (BUG-A + BUG-B)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-20 12:28:40 +09:00
YeonGyu-Kim 6df148f0f6 fix(team-mode): close peer message delivery races 2026-05-20 11:42:38 +09:00
YeonGyu-Kim b2918fd4db fix(team-mode): close peer message delivery races 2026-05-19 19:18:13 +09:00
YeonGyu-Kim bcea4a9d28 fix(prompt-gate): harden sync and team prompt dispatch 2026-05-19 19:18:13 +09:00
YeonGyu-Kim 1492bffd20 fix(prompt-gate): harden internal prompt dispatch 2026-05-19 19:18:13 +09:00
YeonGyu-Kim 7db3a7f933 fix(team-mode): preserve live delivery holds after ambiguous prompt failure 2026-05-19 13:49:01 +09:00
MoerAI 688d7395e0 fix(team-mode): swallow EPERM/ENOTSUP/EINVAL from chmod on base dir to keep init alive (fixes #4023)
ensureBaseDirs unconditionally called chmod(baseDir, 0o700) on every startup
and on every team_create. On filesystems where the OS rejects chmod for the
directory (network mounts, SIP-protected locations, non-owner cases on macOS
shared by multiple GUI users), the call raises EPERM and the entire team-mode
init aborts:

  [team-mode] init failed: EPERM: operation not permitted, chmod '/Users/<u>/.omo'

Wrap chmod through a small safeChmod helper that converts EPERM, ENOTSUP, and
EINVAL into a single warning log and continues. mkdir already creates new
directories with mode 0o700, and the existing post-creation stat-guard remains
in place for the case where the directory pre-exists with a different mode and
chmod is permitted, so the security envelope on supported filesystems is
unchanged. All other error codes (ENOENT, EACCES, etc.) still propagate.

Regression test mocks node:fs/promises.chmod to throw EPERM and asserts that
ensureBaseDirs completes successfully and emits exactly the documented warning.
2026-05-19 10:19:46 +09:00
YeonGyu-Kim f925d13049 chore(deps): update root dependencies
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-18 20:55:17 +09:00
ririnto 19aaf5d329 fix(prompts): point planning guidance at plan subagent 2026-05-18 00:54:01 +09:00
YeonGyu-Kim fee515c5ac refactor(prompt-callers): migrate team and call_omo_agent dispatch
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-17 16:48:06 +09:00
Nikhil Kumar 75ba70803d fix(team-mode): sync atomic writes through writable handle 2026-05-17 12:20:58 +05:30
YeonGyu-Kim 36e373cdbb feat(workspace): point planning guardrails at omo 2026-05-16 17:41:35 +09:00
YeonGyu-Kim cf7bf9d02d fix(team-mode): accept legacy inline specs 2026-05-16 15:43:08 +09:00
ZeyuFu e25f3ca736 fix(tmux-subagent): drain terminal probe replies during delegated pane startup (#2887)
When oh-my-opencode created a delegated tmux pane, terminal
capability/color probe replies emitted by tmux or the freshly
attaching opencode session could end up in the caller pane's
input buffer instead of being consumed by the delegated pane,
appearing as literal text in the main OpenCode chat (e.g.
"414/21212a2/...").

Root cause: buildSplitArgs in team-layout-tmux/layout.ts called
split-window without the -d (detached/don't-switch-focus) flag.
Without -d, tmux briefly grants focus to the new pane during
creation; the outer terminal then sends DA1/DA2 and OSC color
probe replies into what it believes is the active pane, but the
focus handoff races and those bytes land in the caller pane's
stdin buffer instead.

Fix: add -d to every split-window call in buildSplitArgs, matching
the same flag already used in pane-spawn.ts for inline subagent
panes. This keeps the caller pane focused throughout the delegated
pane lifecycle so probe replies are consumed by the correct target.

Existing tests pass; one new test asserts -d is present on every
split-window call to guard this invariant.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 01:41:25 -04:00
ZeyuFu 4c36005467 fix(team-mode): reject team_create from hard-reject agents (#3987)
When a hard-reject agent (e.g. prometheus) called team_create with an
explicit `lead` in the spec, the eligibility check that runs in the
no-lead branch of shouldReuseCallerLeadSession was bypassed. The
caller session was never registered in the team, the spawned lead
ran as a detached child, and replies routed to the spawned lead
never reached the caller — the caller became an orphan that could
send but never receive.

Move the caller eligibility guard to the top of team_create.execute
so it runs unconditionally before any team-run state mutates. Throw
an actionable error naming the agent and explaining hard-reject
agents cannot lead teams regardless of an explicit `lead` in the
spec.
2026-05-16 01:40:13 -04:00
ZeyuFu ced95c4bfa fix(team-mode): surface port-0 fallback and silent layout skip (#3963)
When ctx.serverUrl had a port string of "0", TmuxSessionManager
silently replaced it with the localhost:4096 fallback and
createTeamLayout subsequently skipped pane creation without any
user-visible signal. The two-step silent failure made team_mode
tmux_visualization look broken in default TUI mode.

Surface the failure path:

- TmuxSessionManager now retains ctx.serverUrl on the instance and
  exposes it via getCtxServerUrl(), and emits a structured warning
  log on the port-0 fallback branch naming both the discarded URL
  and the fallback it landed on.
- createTeamLayout's "opencode server not reachable" log is
  upgraded to a structured warning including ctxServerUrl and a
  hint to launch with --port N + OPENCODE_PORT=N.

No behavior change to the fallback resolution itself - only the
silence. Existing port-0 fallback tests still pass; two new tests
assert the warning fires on port 0 and is absent for real ports.
2026-05-16 01:23:25 -04:00
YeonGyu-Kim e8de8b79a8 fix(team-mode): skip pending mailbox reinjection 2026-05-15 23:15:46 +09:00
YeonGyu-Kim 196f6512ae fix(team-mode): defer live mailbox acks 2026-05-15 22:49:10 +09:00
YeonGyu-Kim a02686e729 test(ci): remove suite-order mock coupling 2026-05-15 18:21:04 +09:00
YeonGyu-Kim 462b55efc7 Merge pull request #4040 from code-yeongyu/cleanup/typescript-ai-slop-20260515
Refactor TypeScript cleanup patterns
2026-05-15 16:42:10 +09:00
YeonGyu-Kim a9886ccbb7 refactor(plugin): remove metadata assertions
Guard optional plugin metadata and pane identifiers before passing them to cleanup and warning paths.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-15 16:31:13 +09:00
YeonGyu-Kim d8f52aae7f test: run suite without split runner 2026-05-15 16:26:57 +09:00
YeonGyu-Kim 9f6d0d2281 docs(agents-md): refresh hierarchical knowledge base for v4.1.2
- Bump root AGENTS.md header: 2026-05-14 → 2026-05-15, commit 5ffbe0e2453a740636, release v4.1.1 → v4.1.2
- Update file counts: 2034 (1337+697) → 2041 (1340+701), LOC ~292k → ~294k
- Fix STRUCTURE: openclaw lives at src/openclaw/ (not src/features/); list more accurate feature modules in the parenthetical
- Clarify interactive_bash gate: tmux binary on PATH via isInteractiveBashEnabled() (not 'tmux enabled')
- Fix docs/reference/features.md hook counts: Tool Guard 14→16, Total base 52→54, total with team-mode 59→61
- Bump 'Generated' date on all 43 subdir AGENTS.md files to 2026-05-15
- Preserve promptAsync injection cautions verbatim (per request)
2026-05-15 13:48:11 +09:00
YeonGyu-Kim c2aa180e7e fix(prompt-gate): pin duplicate prompt dispatches
Keep prompt reservations briefly after successful dispatch so rapid idle/message/error transitions cannot inject the same follow-up twice.

Route all production session prompt calls through the shared gate, restore skipped background resume state, release holds after abort/recovery paths, and preserve Ralph/ULW loop state when a dispatch is deferred.

Add regression coverage for session routing, static prompt route auditing, team-mode live messaging, model suggestion retries, call-omo-agent reuse, background parent wakes, runtime fallback, compaction recovery, Atlas, and Ralph/ULW loops.
2026-05-15 13:19:10 +09:00
YeonGyu-Kim f1a62a9cd1 fix(team-mode): gate member wake prompts 2026-05-15 12:55:56 +09:00
YeonGyu-Kim 1e7a7600a2 docs(agents-md): regenerate hierarchical AGENTS.md knowledge base for v4.1.1
Refresh all AGENTS.md files to reflect codebase state at 5ffbe0e24 (was cd31d2a1a, 197 commits behind).

Key drift corrections across 45 modified + 1 new file:

Root AGENTS.md:
- TS file counts: 1967 -> 2034 in src/ (1337 source + 697 test)
- LOC: 278k -> 292k
- Barrel index.ts: 120 -> 122
- Hook tier composition: 52/59 -> 54/61 (base/with team-mode)
- Tool Guard hooks: 14 -> 16 (add fsync-skip-warning, bash-file-read-guard)
- Add boulder feature, agent-ordering schema, .agents/ directory, v4.1.1 release tag
- Add generated/ directory entry

src/AGENTS.md:
- Subsystem inventory: agents 96->102, hooks 570->581, tools 306->314,
  features 389->400, shared 258->278, cli 150->158, plugin 55->56
- LOC totals refreshed for every subsystem
- Schema files: 32 -> 30

src/hooks/AGENTS.md:
- Tier 2 (Tool Guard): 14 -> 16 hooks, add fsyncSkipWarning row
- Total: 52 base / 59 team-mode -> 54 base / 61 team-mode
- zauc-mocks count: 7 -> 5

src/features/AGENTS.md:
- background-agent: 47 -> 57 files, mention archive fallback
- opencode-skill-loader: 33 -> 30
- tmux-subagent: 34 -> 32

src/plugin/AGENTS.md:
- Tool Guard composer count: 14 -> 16
- Aggregator total: 43 -> 45

src/cli/AGENTS.md:
- Add new boulder subcommand (BoulderState inspector)
- Command count: 6 -> 7

NEW: src/features/boulder-state/AGENTS.md
- Document the new Boulder work tracking feature
- Schema v2 with BoulderState/BoulderWorkState/TaskSessionState
- Lifecycle, storage, integration points with atlas/ralph-loop hooks

All other AGENTS.md files: Generated date 2026-05-08 -> 2026-05-14.
2026-05-14 12:57:46 +09:00
YeonGyu-Kim d5fbada13d test: make unsafe test coercion explicit
Move test coercion out of a hidden global and require each test to import the helper so review tools and runtime scripts can see the unsafe boundary.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-12 15:51:31 +09:00
YeonGyu-Kim 11b3638493 test(features): remove unsafe test assertions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-12 15:41:17 +09:00
YeonGyu-Kim 0aafe20a85 refactor: route raw Bun.file/write/hash/which/spawn through runtime shims
Eliminates 19 unguarded `Bun.*` runtime call sites in the plugin bundle
that crashed with `ReferenceError: Bun is not defined` under Electron.

Per-tool-call hot paths (executed on every Read/Edit):
- src/tools/hashline-edit/hash-computation.ts: Bun.hash.xxHash32 → bunHashXxh32
- src/tools/hashline-edit/hashline-edit-executor.ts: 8 sites via bunFile/bunWrite
- src/hooks/hashline-read-enhancer/hook.ts: Bun.file → bunFile
- src/hooks/hashline-edit-diff-enhancer/hook.ts: 2 sites via bunFile

Plugin-load paths:
- src/hooks/claude-code-hooks/config.ts and config-loader.ts: Bun.file → bunFile
- src/features/claude-code-mcp-loader/loader.ts: Bun.file → bunFile
- src/features/claude-code-plugin-loader/mcp-server-loader.ts: Bun.file → bunFile
- src/features/team-mode/deps.ts: Bun.spawn → spawn shim
- src/hooks/session-notification-utils.ts: Bun.which → bunWhich, also drops
  the bare `declare const Bun` ambient declaration
- src/shared/binary-downloader.ts: Bun.write → bunWrite

Pure mechanical API swaps. No control-flow or signature changes.
2026-05-12 12:46:50 +09:00
YeonGyu-Kim 59209f0659 fix(team-mode): track session-created team runs 2026-05-11 12:37:20 +09:00
YeonGyu-Kim d801c88888 fix(team-mode): preserve member context on retry 2026-05-10 13:11:52 +09:00
YeonGyu-Kim c69d6bd964 fix(team-mode): tolerate EPERM during fsync in atomicWrite and acquireLock
Replaces direct fileHandle.sync() calls in acquireLock and atomicWrite
with tolerantFsync. Users on iCloud Drive / OneDrive / Desktop sync
folders were hitting 'EPERM: operation not permitted, fsync' during
team_create, which propagated up and aborted the entire team_create
flow even though the actual write+rename had succeeded.

Reported on Discord (omo 4.0.0, opencode desktop 1.14.41, project on
synced Desktop). atomicity is preserved by the temp-file rename; only
the durability hint is now best-effort on filesystems that disallow
fsync.
2026-05-08 14:09:16 +09:00
YeonGyu-Kim 2dfa6336f5 fix(metis): switch primary model to claude-sonnet-4-6 + correct AGENTS.md inaccuracies
Source code change:
- src/shared/model-requirements.ts: prepend claude-sonnet-4-6 to metis fallback
  chain so Sonnet becomes the default. Opus 4.7 max remains as the immediate
  fallback for callers who want extra reasoning.
- src/shared/model-requirements.test.ts: update assertion to expect Sonnet
  primary + Opus secondary.

AGENTS.md accuracy fixes (verified against source):
- Agent modes: Sisyphus/Hephaestus are 'primary' (not 'all'); Sisyphus-Junior
  is 'subagent' (not 'all'). Confirmed via 'const MODE: AgentMode = ...' in
  each agent file. Also clarified Prometheus has no agentSources factory and
  is built via buildPrometheusAgentConfig.
- Sisyphus fallback chain: corrected order to kimi-k2.6 → k2p5 → kimi-k2.5
  → gpt-5.5 medium → glm-5 → big-pickle (was missing kimi-k2.5).
- Librarian/Explore: added missing minimax-m2.7 step between -highspeed and
  claude-haiku-4-5.
- Metis chain: removed fictitious gemini-3.1-pro entry.
- Sisyphus-Junior chain: spelled out the actual fallback (was 'user-configurable').
- Temperatures: Sisyphus/Hephaestus do not set explicit temperature (model
  default); Sisyphus-Junior is 0.1 via SISYPHUS_JUNIOR_DEFAULTS.
- Quick category default: gpt-5.4-mini (not gpt-5.4-mini-fast).

Team-mode corrections:
- Eligibility registry has 3 verdicts: eligible (sisyphus, atlas, sisyphus-junior),
  conditional (hephaestus — needs D-36 teammate permission), hard-reject
  (oracle, librarian, explore, multimodal-looker, metis, momus, prometheus).
- Schema has 11 fields, not 4: added max_messages_per_run, max_wall_clock_minutes,
  max_member_turns, base_dir, message_payload_max_bytes, recipient_unread_max_bytes,
  mailbox_poll_interval_ms.
- Hooks: 'team-session-events' is 4 sub-handlers in src/plugin/event.ts
  (team-idle-wake-hint, team-lead-orphan-handler, team-member-error-handler,
  team-member-status-handler), not a single Continuation-tier hook.
- Tier counts now show base + team-mode: ToolGuard 14/15, Transform 5/7.
- Total: 52 base hooks, 59 with team-mode.

Doc cascade for the Metis change:
- docs/guide/orchestration.md, agent-model-matching.md, installation.md
- docs/reference/configuration.md, features.md
2026-05-08 13:06:34 +09:00
YeonGyu-Kim 838b5ae216 docs(agents): refresh hierarchical AGENTS.md with team-mode coverage
Update root + 43 directory-level AGENTS.md files to reflect current state:
- Root AGENTS.md rewritten with accurate counts (1967 TS files, 1304 source +
  663 test, 278k LOC, 120 barrel index.ts), 7-step init flow, 5-tier hook
  composition, and full Team Mode section (12 team_* tools, eligibility,
  storage layout, config gate)
- src/AGENTS.md adds team-mode init step, current per-subdir file/LOC table
- src/tools/AGENTS.md documents conditional gates (team-mode +12, task
  system +4, hashline +1, interactive_bash +1, look_at +1) with always-on
  baseline of 20
- src/hooks/AGENTS.md splits into 5 tiers + 4 conditional team-mode hooks
- src/features/team-mode/AGENTS.md surfaces 12 tools, eligible agents,
  spawn-race-safe invariants, and integration points
- src/features/builtin-skills/AGENTS.md tracks 10 skills incl. team-mode
- src/agents/AGENTS.md, src/plugin/AGENTS.md, src/config/AGENTS.md updated
  for team-mode awareness, accurate counts, and current schema field list
- All other AGENTS.md files refreshed to 2026-05-08 generation date
2026-05-08 12:08:42 +09:00
YeonGyu-Kim ee938aa097 fix full-suite isolation regressions 2026-05-07 18:36:03 +09:00
YeonGyu-Kim 89c959955a fix(team-mode): gate tmux layout cleanup by config
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 17:36:03 +09:00
YeonGyu-Kim b4791c85ca fix(team-mode): keep tmux visualization in caller window
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 17:36:03 +09:00