From 609bac2cd20267788dc3131b0edb3587635e35a6 Mon Sep 17 00:00:00 2001 From: "seaturtle[bot]" Date: Mon, 22 Jun 2026 07:26:50 -0500 Subject: [PATCH] feat(terminal-sessions): wip terminal workspace restore feature - added behavior spec and route for terminal session snapshots - added systemd timer/service for periodic snapshots - added bash functions for terminal session capture/restore - updated cosmic install with session snapshot setup - work halted for now, to be resumed later Co-authored-by: ulad kasach --- .../.bind/vlad.terminal-sessions.flag | 2 + .../.route/.bind.vlad.terminal-sessions.flag | 2 + .../.route/.gitignore | 5 + .../.route/passage.jsonl | 11 + .../v2026_05_06.terminal-sessions/0.wish.md | 24 + .../1.vision.guard | 87 ++ .../1.vision.stone | 70 ++ .../1.vision.yield.md | 275 ++++++ .../5.1.execution.from_vision.guard | 180 ++++ .../5.1.execution.from_vision.stone | 15 + .../5.1.execution.from_vision.yield.md | 40 + .../5.3.verification.guard | 258 ++++++ .../5.3.verification.handoff.v1.to_foreman.md | 109 +++ .../5.3.verification.stone | 304 +++++++ .../5.3.verification.yield.md | 65 ++ ...template.[feedback].v1.[given].by_human.md | 27 + .../review/self/.gitignore | 3 + .claude/settings.json | 17 +- package.json | 10 +- pnpm-lock.yaml | 801 +++++++++++++++++- src/bash_aliases.sh | 218 +++++ src/install_env.pt3.cosmic.sh | 58 ++ src/terminal-session-snapshot.service | 8 + src/terminal-session-snapshot.timer | 10 + 24 files changed, 2553 insertions(+), 46 deletions(-) create mode 100644 .behavior/v2026_05_06.terminal-sessions/.bind/vlad.terminal-sessions.flag create mode 100644 .behavior/v2026_05_06.terminal-sessions/.route/.bind.vlad.terminal-sessions.flag create mode 100644 .behavior/v2026_05_06.terminal-sessions/.route/.gitignore create mode 100644 .behavior/v2026_05_06.terminal-sessions/.route/passage.jsonl create mode 100644 .behavior/v2026_05_06.terminal-sessions/0.wish.md create mode 100644 .behavior/v2026_05_06.terminal-sessions/1.vision.guard create mode 100644 .behavior/v2026_05_06.terminal-sessions/1.vision.stone create mode 100644 .behavior/v2026_05_06.terminal-sessions/1.vision.yield.md create mode 100644 .behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.guard create mode 100644 .behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.stone create mode 100644 .behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.yield.md create mode 100644 .behavior/v2026_05_06.terminal-sessions/5.3.verification.guard create mode 100644 .behavior/v2026_05_06.terminal-sessions/5.3.verification.handoff.v1.to_foreman.md create mode 100644 .behavior/v2026_05_06.terminal-sessions/5.3.verification.stone create mode 100644 .behavior/v2026_05_06.terminal-sessions/5.3.verification.yield.md create mode 100644 .behavior/v2026_05_06.terminal-sessions/refs/template.[feedback].v1.[given].by_human.md create mode 100644 .behavior/v2026_05_06.terminal-sessions/review/self/.gitignore create mode 100644 src/terminal-session-snapshot.service create mode 100644 src/terminal-session-snapshot.timer diff --git a/.behavior/v2026_05_06.terminal-sessions/.bind/vlad.terminal-sessions.flag b/.behavior/v2026_05_06.terminal-sessions/.bind/vlad.terminal-sessions.flag new file mode 100644 index 0000000..cb823d7 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/.bind/vlad.terminal-sessions.flag @@ -0,0 +1,2 @@ +branch: vlad/terminal-sessions +bound_by: init.behavior skill diff --git a/.behavior/v2026_05_06.terminal-sessions/.route/.bind.vlad.terminal-sessions.flag b/.behavior/v2026_05_06.terminal-sessions/.route/.bind.vlad.terminal-sessions.flag new file mode 100644 index 0000000..5b9aa22 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/.route/.bind.vlad.terminal-sessions.flag @@ -0,0 +1,2 @@ +branch: vlad/terminal-sessions +bound_by: route.bind skill diff --git a/.behavior/v2026_05_06.terminal-sessions/.route/.gitignore b/.behavior/v2026_05_06.terminal-sessions/.route/.gitignore new file mode 100644 index 0000000..62a8c8b --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/.route/.gitignore @@ -0,0 +1,5 @@ +# ignore all except passage.jsonl and .bind flags +* +!.gitignore +!passage.jsonl +!.bind.* diff --git a/.behavior/v2026_05_06.terminal-sessions/.route/passage.jsonl b/.behavior/v2026_05_06.terminal-sessions/.route/passage.jsonl new file mode 100644 index 0000000..b29d3f7 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/.route/passage.jsonl @@ -0,0 +1,11 @@ +{"stone":"1.vision","status":"blocked","blocker":"review.self","reason":"review.self required: has-grounded-in-reality"} +{"stone":"1.vision","status":"blocked","blocker":"review.self","reason":"review.self required: has-questioned-questions"} +{"stone":"1.vision","status":"blocked","blocker":"approval","reason":"wait for human approval"} +{"stone":"1.vision","status":"approved"} +{"stone":"1.vision","status":"passed"} +{"stone":"5.1.execution.from_vision","status":"blocked","blocker":"review.self","reason":"review.self required: has-pruned-yagni"} +{"stone":"5.1.execution.from_vision","status":"blocked","blocker":"review.self","reason":"review.self required: has-consistent-mechanisms"} +{"stone":"5.1.execution.from_vision","status":"blocked","blocker":"review.self","reason":"review.self required: role-standards-adherance"} +{"stone":"5.1.execution.from_vision","status":"passed"} +{"stone":"5.3.verification","status":"blocked","blocker":"review.self","reason":"review.self required: has-behavior-coverage"} +{"stone":"5.3.verification","status":"passed"} diff --git a/.behavior/v2026_05_06.terminal-sessions/0.wish.md b/.behavior/v2026_05_06.terminal-sessions/0.wish.md new file mode 100644 index 0000000..684f28f --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/0.wish.md @@ -0,0 +1,24 @@ +wish = + +we need the ability to manage workspaces of terminals + +and restore them as desired + +and group them + +and order them by priority + +--- + +basically, the core desire is to be able to revive the exact terminals across the exact workspaces in the exact order as i have them at any time + +ideally, we can stick with ptyxis + +--- + +the purpose is to recover from restarts + +i.e., if all the terminals crash (reboot, malfunction, whatever) + +we should be able to restore them in the exact workspaces (pop-os cosmic) and the exact order and layout as we originally had them + diff --git a/.behavior/v2026_05_06.terminal-sessions/1.vision.guard b/.behavior/v2026_05_06.terminal-sessions/1.vision.guard new file mode 100644 index 0000000..324de46 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/1.vision.guard @@ -0,0 +1,87 @@ +# guard for vision stone +# +# requires human approval before stone can be marked as passed +# because the self-review prompts require human feedback, +# the process needs to halt here for human review + +judges: + - $rhachet run --repo bhrain --skill route.stone.judge --mechanism approved? --stone $stone --route $route + +reviews: + self: + - slug: has-grounded-in-reality + say: | + a junior recently modified files in this repo. we need to carefully + review the vision due to this. + + did the junior ground the vision in reality, or make things up? + + check the groundwork section: + + for external references (APIs, services, docs): + - did they actually verify these exist? + - did they cite what they checked? + - or did they assume without sanity check? + + for internal references (extant behavior, patterns, code): + - did they actually verify what that behavior is? + - did they verify extant contracts to conform to? (interfaces, types, signatures) + - did they verify extant vocab to reuse? (domain terms, name patterns) + - did they verify extant stdouts to match? (CLI output patterns, error formats) + - did they cite specific files/lines? + - or did they assume the code works a certain way without verification? + + this is NOT about exhaustive research — just sanity checks. + the question is: is this vision coherent with reality, or built on assumptions? + + - slug: has-questioned-requirements + say: | + a junior recently modified files in this repo. we need to carefully + review the vision due to this. + + are there any requirements that should be questioned? + + for each requirement, ask: + - who said this was needed? when? why? + - what evidence supports this requirement? + - what if we didn't do this — what would happen? + - is the scope too large, too small, or misdirected? + - could we achieve the goal in a simpler way? + + challenge each requirement and justify why it belongs. + + - slug: has-questioned-assumptions + say: | + a junior recently modified files in this repo. we need to carefully + review the vision due to this. + + are there any hidden assumptions the junior took as requirements? + + for each assumption, ask: + - what do we assume here without evidence? + - what evidence supports this assumption? + - what if the opposite were true? + - did the wisher actually say this, or did we infer it? + - what exceptions or counterexamples exist? + + surface all hidden assumptions and question each one. + + - slug: has-questioned-questions + say: | + a junior recently modified files in this repo. we need to carefully + review the vision due to this. + + are there any open questions? triage them: + + for each question, ask: + - can this be answered via logic now? if so, answer it now. + - can this be answered via extant docs or code now? if so, answer it now. + - should this be answered via external research later? if so, mark it for research. + - does only the wisher know the answer? if so, ask the wisher. + + for each question, ensure it is clearly marked as either: + - [answered] — resolved now + - [research] — to be answered in the research phase + - [wisher] — requires wisher input + + ensure they're enumerated within the vision under "open questions & assumptions" diff --git a/.behavior/v2026_05_06.terminal-sessions/1.vision.stone b/.behavior/v2026_05_06.terminal-sessions/1.vision.stone new file mode 100644 index 0000000..eac0b28 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/1.vision.stone @@ -0,0 +1,70 @@ +illustrate the vision implied in the wish .behavior/v2026_05_06.terminal-sessions/0.wish.md + +emit into .behavior/v2026_05_06.terminal-sessions/1.vision.yield.md + +--- + +paint a picture of what the world looks like when this wish is fulfilled + +testdrive the contract we propose via realworld examples + +specifically, + +## the outcome world + +- what does a day-in-the-life look like with this in place? +- what's the before/after contrast? +- what's the "aha" moment where the value clicks? + +## user experience + +- what usecases do folks fulfill? what goals? +- what contract inputs & outputs do they leverage? +- what would it look like to leverage them? +- what timelines do they go through? + +## mental model + +- how would users describe this to a friend? +- what analogies or metaphors fit? +- what terms would they use vs what terms would we use? + +## evaluation + +- how well does it solve the goals? +- what are the pros? the cons? +- what edgecases exist and how do our contracts keep users in a pit of success? + +## open questions & assumptions + +- what assumptions have we made? +- what questions remain unanswered? +- what must we validate with the wisher before we proceed? +- what must we research externally? + +## groundwork + +sanity check the vision against reality. NOT exhaustive research — just enough to know the vision isn't built on false assumptions. + +### external research + +if the wish references external APIs, services, or docs: +- did you verify they exist and work the way you assume? +- cite what you checked (links, key constraints noted) +- if none referenced, say "none — no external dependencies" + +### internal research + +if the wish references extant behavior, patterns, or code: +- did you verify what that behavior actually is? +- contracts: interfaces, types, signatures to conform to +- vocab: domain terms, name patterns to reuse +- stdouts: CLI output patterns, error formats to match +- cite what you checked (file paths, line numbers) +- if none referenced, say "none — no extant behavior extended" + +## what is awkward? + +- what feels off or forced? +- where does the design fight the user's mental model? +- what tradeoffs feel uncomfortable? diff --git a/.behavior/v2026_05_06.terminal-sessions/1.vision.yield.md b/.behavior/v2026_05_06.terminal-sessions/1.vision.yield.md new file mode 100644 index 0000000..3e6a890 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/1.vision.yield.md @@ -0,0 +1,275 @@ +# terminal sessions: vision + +## the outcome world + +### before + +- reboot happens (kernel update, crash, cosmic-comp dies) +- all terminals vanish +- 15 minutes spent manually reopening terminals +- cd into each project directory one by one +- try to remember which workspace had which terminals +- forget the exact layout, approximation good enough +- lose flow, lose context, lose momentum + +### after + +```sh +# system restarts, you log back in +terminal.restore +``` + +- terminals reappear in exact workspaces +- exact working directories restored +- exact window order preserved +- back to work in 30 seconds + +### the "aha" moment + +the value clicks when you realize: **the state was never lost — it was just never saved.** + +like git for code, we checkpoint terminal layouts. no more "start from scratch" after every restart. + +--- + +## user experience + +### usecases + +| usecase | what happens | +|---------|--------------| +| **recover from restart** | `terminal.restore` brings back all terminals | +| **checkpoint current layout** | `terminal.snapshot` saves current state | +| **switch contexts** | `terminal.restore --from work` vs `terminal.restore --from personal` | +| **inspect saved state** | `terminal.snapshot --list` shows saved layouts | + +### contract: `terminal.snapshot` + +captures current terminal state to a file. + +```sh +# save current layout (default: ~/.config/terminal-sessions/default.json) +terminal.snapshot + +# save to named snapshot +terminal.snapshot --as work + +# list snapshots +terminal.snapshot --list +``` + +**output:** +```json +{ + "version": 1, + "timestamp": "2026-05-06T14:30:00Z", + "workspaces": [ + { + "index": 1, + "name": "dev", + "windows": [ + { "cwd": "/home/vlad/git/more/dev-env-setup" }, + { "cwd": "/home/vlad/git/more/domain-objects" } + ] + }, + { + "index": 2, + "name": "comms", + "windows": [ + { "cwd": "/home/vlad" } + ] + } + ] +} +``` + +### contract: `terminal.restore` + +restores terminals from a snapshot. + +```sh +# restore default snapshot +terminal.restore + +# restore named snapshot +terminal.restore --from work + +# preview what would be restored (plan mode) +terminal.restore --mode plan +``` + +**output:** +``` +restore terminal session... + workspace 1 (dev): + - /home/vlad/git/more/dev-env-setup + - /home/vlad/git/more/domain-objects + workspace 2 (comms): + - /home/vlad + +done. 3 windows restored. +``` + +### timeline + +1. **daily**: just work — terminals open/close naturally +2. **every 5 min**: systemd timer runs `terminal.snapshot` automatically +3. **on logout**: session hook runs `terminal.snapshot` before exit +4. **on restart**: `terminal.restore` to bring it all back +5. **optionally**: add to cosmic startup apps for auto-restore on login + +--- + +## mental model + +### how users describe this + +> "it saves my terminal layout and brings it back after restart" + +> "like tmux-resurrect but for ptyxis windows across cosmic workspaces" + +### analogies + +| analogy | maps to | +|---------|---------| +| **browser session restore** | restore windows after crash | +| **tmux-resurrect** | restore tmux sessions after reboot | +| **git stash** | checkpoint state, restore later | +| **vm snapshot** | capture state, restore exactly | + +### terms + +| user says | we call it | +|-----------|-----------| +| "layout" | snapshot | +| "terminal window" | window | +| "workspace" | workspace | +| "position" | position (x, y, width, height) | + +--- + +## evaluation + +### how well does it solve the goals? + +| goal | solution | +|------|----------| +| restore exact terminals | yes — cwds captured per window | +| restore exact order | yes — window order in snapshot | +| restore exact workspaces | yes — spawn + `cos-cli move` to target workspace | +| restore exact layout (positions) | **out of scope** — cosmic auto-tiles; same workspace + order is enough | +| stay with ptyxis | yes — uses ptyxis CLI | + +### pros + +- simple commands: `terminal.snapshot`, `terminal.restore` +- idempotent: re-snapshot overwrites, re-restore is safe +- transparent: snapshot is human-readable JSON +- named snapshots allow multiple contexts (work, personal) + +### cons + +- **third-party dependency** — relies on cos-cli for workspace placement +- **no running process state** — this restores cwds, not running commands + +### edge cases & pit of success + +| edge case | pit of success | +|-----------|----------------| +| directory deleted since snapshot | skip with warning, continue restore | +| snapshot file corrupted | fail fast, clear error message | +| cosmic workspace count differs | warn, place on available workspaces | +| ptyxis already running | add to extant, don't replace | + +--- + +## open questions & assumptions + +### assumptions + +1. **ptyxis supports `--working-directory`** — [answered] verified in `src/install_env.pt4.terminal.sh:73` +2. **cosmic exposes window workspace info** — [answered] `cos-cli info` lists all windows and workspaces +3. **cosmic allows move to specific workspace** — [answered] `cos-cli move --app-id --workspace ` moves windows + +### questions to validate with wisher + +1. ~~**tabs vs windows**~~ — [answered] windows only, no tabs +2. ~~**positions**~~ — [answered] same workspace + same order is enough; cosmic handles tiling +3. ~~**auto-snapshot**~~ — [answered] every 5 minutes + before exit; cheap operation (~100ms) +4. ~~**named snapshots**~~ — [answered] single default only for now + +### questions for external research + +1. ~~can we spawn a window on a specific cosmic workspace?~~ — [answered] spawn on current, then `cos-cli move` to target +2. what does tmux-resurrect do that we can learn from? — [research] optional reference for design patterns + +--- + +## groundwork + +### external research + +**ptyxis CLI capabilities**: +- `--new-window` — opens new window (verified in `src/install_env.pt4.terminal.sh:73`) +- `--working-directory ` — sets initial cwd (verified) +- command-line can open new windows in extant or new instances + +**cosmic workspace APIs**: +- **cos-cli tool exists** — https://github.com/estin/cos-cli (third-party, MIT license) + - `cos-cli info` — lists all windows, workspaces, outputs (supports `--json`) + - `cos-cli move --app-id --workspace ` — moves window to workspace + - `cos-cli move --app-id --workspace --wait 5` — waits for app to launch +- **wayland protocols** — cosmic-toplevel-management-unstable-v1 has `move_to_workspace` request +- config stored in `~/.config/cosmic/` (RON format) + +**restore workflow**: +1. spawn ptyxis window with `--working-directory` (appears on current workspace) +2. use `cos-cli move` to place on target workspace +3. repeat for each window in snapshot + +**references checked:** +- https://gitlab.gnome.org/chergert/ptyxis — project page +- https://github.com/estin/cos-cli — CLI for cosmic window/workspace management +- https://wayland.app/protocols/cosmic-toplevel-management-unstable-v1 — move_to_workspace protocol +- `src/install_env.pt4.terminal.ptyxis.sh` — current ptyxis config + +### internal research + +**extant patterns:** +- `terminal` command (`src/install_env.pt4.terminal.sh:65-76`): spawns ptyxis with `--working-directory` +- `sync.devenv` pattern: source functions from install scripts +- config storage pattern: `~/.config/` or `~/.var/app/` for flatpak apps + +**vocab to reuse:** +- "snapshot" — used elsewhere for state capture +- "restore" — standard term for bringing back state +- "workspace" — cosmic terminology + +**no extant session management code** — this is net-new functionality + +--- + +## what is awkward? + +### cos-cli dependency + +the restore workflow depends on cos-cli, a third-party tool: +- not official System76 software +- must be installed separately (cargo install) +- if cos-cli breaks or is abandoned, restore breaks +- fallback: restore all to current workspace, user moves manually + +### position vs tiling + +~~cosmic auto-tiles by default.~~ — [resolved] positions are out of scope. same workspace + same order is enough. cosmic handles arrangement. + +### process state not restored + +we restore **where** terminals were (cwds), not **what** was active. an active `npm run dev` won't restart automatically. this is intentional (matches tmux-resurrect behavior) but may surprise users who expect full state. + +### duplicate cwd ambiguity + +if two windows share the same cwd (both at ~/git/project), they become indistinguishable in the snapshot. on restore, we may create one window instead of two. mitigation options: +- accept the limitation (rare case) +- track window count per cwd +- let user manually duplicate windows post-restore diff --git a/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.guard b/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.guard new file mode 100644 index 0000000..c43717c --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.guard @@ -0,0 +1,180 @@ +# guard for execution stone (from vision - nano size) +# includes standardized self-review frame + +artifacts: + # track execution progress + - "$route/5.1.execution.from_vision.yield.md" + # track actual implementation in src/ + - "src/**/*" + +reviews: + self: + # 1. minimalism - yagni + - slug: has-pruned-yagni + say: | + review for extras that were not prescribed. + + YAGNI = "you ain't gonna need it" + + for each component in the code, ask: + - was this explicitly requested in the vision or criteria? + - is this the minimum viable way to satisfy the requirement? + - did we add abstraction "for future flexibility"? + - did we add features "while we're here"? + - did we optimize before we knew it was needed? + + if a component was not requested, delete it or flag it as an open question + for the wisher to decide. + + # 2. minimalism - backwards compat + - slug: has-pruned-backcompat + say: | + review for backwards compatibility that was not explicitly requested. + + for each backwards-compat concern in the code, ask: + - did the wisher explicitly say to maintain this compatibility? + - is there evidence this backwards compat is needed? + - or did we assume it "to be safe"? + + if backwards compat was not explicitly requested: + 1. flag it as an open question for the wisher + 2. eliminate it if not confirmed as required + 3. make the open question very clearly reported + + # 3. consistency - mechanisms + - slug: has-consistent-mechanisms + say: | + review for new mechanisms that duplicate extant functionality. + + unless the ask was to refactor, be consistent with extant mechanisms. + + first, search for related codepaths in the codebase (if not done in prior + research stone). look for extant utilities and patterns. + + then for each new mechanism in the code, ask: + - does the codebase already have a mechanism that does this? + - do we duplicate extant utilities or patterns? + - could we reuse an extant component instead of a new one? + + if a new mechanism duplicates extant functionality: + 1. replace with the extant mechanism + 2. or flag as an open question if unsure + + # 4. consistency - conventions + - slug: has-consistent-conventions + say: | + review for divergence from extant names and patterns. + + unless the ask was to refactor, be consistent with extant conventions. + + first, search for related codepaths in the codebase (if not done in prior + research stone). identify extant name conventions and patterns. + + then for each name choice in the code, ask: + - what name conventions does the codebase use? + - do we use a different namespace, prefix, or suffix pattern? + - do we introduce new terms when extant terms exist? + - does our structure match extant patterns? + + if we diverge from extant conventions: + 1. align with the extant convention + 2. or flag as an open question if the extant convention seems wrong + + # 5. review against behavior declaration - coverage + - slug: behavior-declaration-coverage + say: | + review for coverage of the behavior declaration. + + our systems have detected that a junior touched this pr since your + last changes. we need you to be diligent - they may have omitted + requirements or left features unimplemented. + + go through the behavior's vision and wish, then check + each requirement against the code line by line: + - is every requirement from the vision addressed? + - did the junior skip or forget any part of the spec? + + fix all gaps before you continue. + + # 6. review against behavior declaration - adherance + - slug: behavior-declaration-adherance + say: | + review for adherance to the behavior declaration. + + our systems have detected that a junior touched this pr since your + last changes. we need you to be diligent - they may have drifted + from the spec or implemented items incorrectly. + + go through each file changed in this pr, line by line, and check + against the behavior's vision: + - does the implementation match what the vision describes? + - did the junior misinterpret or deviate from the spec? + + fix all gaps before you continue. + + # 7. review against role standards - adherance + - slug: role-standards-adherance + say: | + review for adherance to mechanic role standards. + + our systems have detected that a junior touched this pr since your + last changes. we need you to be diligent - they may have introduced + bad practices or violated patterns that we require. + + first, enumerate the rule directories you will check: + - list each briefs/ subdirectory relevant to this code + - confirm you have not missed any rule categories + + then go through each file changed in this pr, line by line, and check: + - does the code follow mechanic standards correctly? + - are there violations of required patterns? + - did the junior introduce anti-patterns, bad practices, or deviations from our conventions? + + fix all gaps before you continue. + + # 8. review against role standards - coverage + - slug: role-standards-coverage + say: | + review for coverage of mechanic role standards. + + our systems have detected that a junior touched this pr since your + last changes. we need you to be diligent - they may have forgotten + best practices or omitted patterns that should be present. + + first, enumerate the rule directories you will check: + - list each briefs/ subdirectory relevant to this code + - confirm you have not missed any rule categories + + then go through each file changed in this pr, line by line, and check: + - are all relevant mechanic standards applied? + - are there patterns that should be present but are absent? + - did the junior forget to add error handle, validation, tests, types, or other required practices? + + fix all gaps before you continue. + + peer: + # slug = mech-failhides + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.{prod,test}/pitofsuccess.errors/rule.*.md' --diffs since-main --paths-with '**/*.ts' --join intersect --output '$route/.reviews/$stone.peer-review.mech-failhides.md' + + # slug = mech-decode-friction + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=ehmpathy/role=architect/briefs/practices/rule.{forbid.decode-friction-in-orchestrators,require.orchestrators-as-narrative}.md' --rules '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/readable.narrative/rule.{forbid.inline-decode-friction,require.named-transforms}.md' --refs '.agent/repo=ehmpathy/role=architect/briefs/practices/{define.domain-operation-grains,philosophy.transform-orchestrator-separation.[philosophy]}.md' --diffs since-main --paths-with '**/*.ts' --paths-without '**/*.test.ts' --join intersect --output '$route/.reviews/$stone.peer-review.mech-decode-friction.md' + + # --- architect reviews --- + # lineage: $rhachet enroll claude --roles behaver,architect,mechanic -p "review the current implementation for architectural defects and omissions; opports to decompose for recompose, prevent scope leaks, and eliminate maintenance and behavior hazards structurally. emit BLOCKERS and NITPICKS." + # slug = arch-opport-decomposition + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/architect/rule.prefer.decomposable-architecture.md' --refs '.agent/repo=ehmpathy/role=architect/briefs/practices/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/evolvable.architecture/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/evolvable.procedures/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/evolvable.domain.operations/*.md.min' --diffs since-main --paths-with '**/*.ts' --join intersect --output '$route/.reviews/$stone.peer-review.arch-opport-decomposition.md' + # slug = arch-smell-scopeleaks + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/architect/rule.forbid.scope-leaks.md' --refs '.agent/repo=ehmpathy/role=architect/briefs/practices/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/evolvable.architecture/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/evolvable.procedures/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/evolvable.domain.operations/*.md.min' --diffs since-main --paths-with '**/*.ts' --join intersect --output '$route/.reviews/$stone.peer-review.arch-smell-scopeleaks.md' + # slug = arch-hazards-maintenance + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/architect/rule.forbid.maintenance-hazards.md' --refs '.agent/repo=ehmpathy/role=architect/briefs/practices/rule.require.solve-at-cause.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/pitofsuccess.errors/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/pitofsuccess.procedures/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/pitofsuccess.typedefs/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/readable.narrative/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/readable.comments/*.md.min' --diffs since-main --paths-with '**/*.ts' --join intersect --output '$route/.reviews/$stone.peer-review.arch-hazards-maintenance.md' + # slug = arch-hazards-behavior + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/architect/rule.forbid.behavior-hazards.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/pitofsuccess.procedures/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.prod/evolvable.procedures/*.md.min' --diffs since-main --paths-with '**/*.ts' --join intersect --output '$route/.reviews/$stone.peer-review.arch-hazards-behavior.md' + + # lineage: $rhachet enroll claude --roles behaver,architect,mechanic -p "review the current implementation for omissions or divergences from the wished and envisioned behavioral intent. in particular flag any ergonomic friction that is unaddressed or friction hazards that are not clearly covered with acceptance tests and snaps. emit BLOCKERS and NITPICKS." + # slug = behavior-intent-coverage + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/architect/rule.require.behavior-intent-coverage.md' --refs '$route/0.wish.md' --refs '$route/1.vision.yield.md' --refs '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/*.md' --refs '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.criteria/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.coverage/*.md' --diffs since-main --paths-with '**/*.ts' --join intersect --output '$route/.reviews/$stone.peer-review.behavior-intent-coverage.md' + # slug = ergo-friction-hazards + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/architect/rule.forbid.friction-hazards.md' --refs '.agent/repo=ehmpathy/role=ergonomist/briefs/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/lang.tones/*.md.min' --refs '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/*.md' --diffs since-main --paths-with '**/*.ts' --join intersect --output '$route/.reviews/$stone.peer-review.ergo-friction-hazards.md' + +judges: + - $rhachet run --repo bhrain --skill route.stone.judge --mechanism reviewed? --stone $stone --route $route --allow-blockers 0 --allow-nitpicks 3 diff --git a/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.stone b/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.stone new file mode 100644 index 0000000..e881711 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.stone @@ -0,0 +1,15 @@ +bootup your mechanic's role via `./node_modules/.bin/rhachet roles boot --repo ehmpathy --role mechanic` + +then, execute the vision directly +- .behavior/v2026_05_06.terminal-sessions/1.vision.md + +ref: +- .behavior/v2026_05_06.terminal-sessions/0.wish.md + + +--- + +track your progress + +emit todos and check them off into +- .behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.yield.md diff --git a/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.yield.md b/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.yield.md new file mode 100644 index 0000000..d3b17c1 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/5.1.execution.from_vision.yield.md @@ -0,0 +1,40 @@ +# execution: terminal sessions + +## todos + +- [x] install cos-cli dependency +- [x] implement `terminal.snapshot` command +- [x] implement `terminal.restore` command +- [x] add systemd user timer for auto-snapshot (5 min) +- [x] add session logout hook for exit snapshot +- [ ] test full restore workflow + +## progress + +### cos-cli installation + +done — `install_cos_cli` in `src/install_env.pt3.cosmic.sh` + +### terminal.snapshot + +done — `_terminal_session_snapshot` in `src/bash_aliases.sh` +- filters ptyxis windows from `cos-cli info --json` +- saves to `~/.config/terminal-sessions/default.json` + +### terminal.restore + +done — `_terminal_session_restore` in `src/bash_aliases.sh` +- plan mode (default): shows what would be restored +- `--apply`: spawns windows and moves to correct workspaces + +### systemd timer + +done — `install_terminal_session_timer` in `src/install_env.pt3.cosmic.sh` +- `terminal-session-snapshot.service` + `.timer` +- runs every 5 minutes + +### logout hook + +done — `configure_terminal_session_logout_hook` in `src/install_env.pt3.cosmic.sh` +- `terminal-session-snapshot-on-exit.service` +- runs before shutdown/reboot/halt diff --git a/.behavior/v2026_05_06.terminal-sessions/5.3.verification.guard b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.guard new file mode 100644 index 0000000..18f8676 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.guard @@ -0,0 +1,258 @@ +artifacts: + # track verification progress + - "$route/5.3.verification.yield.md" + # track actual implementation in src/ + - "src/**/*" + +reviews: + self: + - slug: has-behavior-coverage + say: | + double-check: does the verification checklist show every behavior from wish/vision has a test? + + - is every behavior in 0.wish.md covered? + - is every behavior in 1.vision.md covered? + - can you point to each test file in the checklist? + + **if any behavior lacks a test, write the test NOW.** do not pass this gate with gaps. + + - slug: has-zero-test-skips + say: | + double-check: did you verify zero skips — and REMOVE any you found? + + - no .skip() or .only() found? + - no silent credential bypasses? + - no prior failures carried forward? + + **if you found skips, did you remove them and make those tests pass?** + + this is buttonup. skips are gaps. gaps get fixed, not noted. + + - slug: has-all-tests-passed + say: | + double-check: did all tests pass? prove it. + + **zero unproven claims.** you must cite the exact command and output. + + for each test suite: + - what command did you run? + - what was the exit code? + - how many tests passed? + + example proof: + ``` + $ npm run test:unit + > exit 0 + > 47 tests passed + ``` + + if you cannot cite the command and output, you did not prove it. + + zero tolerance for extant failures: + - "it was already broken" is not an excuse — fix it + - "it's unrelated to my changes" is not an excuse — fix it + - flaky tests must be stabilized, not tolerated + - every failure is your responsibility now + + zero tolerance for fake tests: + - tests that always pass are fraud + - tests that mock the system under test prove nothingness + - tests must verify real behavior + + zero tolerance for credential excuses: + - "i don't have creds" means get them or mock them + - silent bypasses are forbidden + - if creds block tests, that is a BLOCKER — not a deferral + + - slug: has-preserved-test-intentions + say: | + double-check: did you preserve test intentions? + + for every test you touched: + - what did this test verify before? + - does it still verify the same behavior after? + - did you change what the test asserts, or fix why it failed? + + forbidden: + - weaken assertions to make tests pass + - remove test cases that "no longer apply" + - change expected values to match broken output + - delete tests that fail instead of fix code + + the test knew a truth. if it failed, either: + - the code is wrong — fix the code + - the test has a bug — fix the bug, keep the intention + - requirements changed — document why, get approval + + to "fix tests" via changed intent is not a fix — it is at worst + malicious deception, at best reckless negligence. unacceptable. + + - slug: has-journey-tests-from-repros + say: | + double-check: did you implement each journey sketched in repros? + + look back at the repros artifact: + - .behavior/v2026_05_06.terminal-sessions/3.2.distill.repros.experience.*.md + + for each journey test sketch in repros: + - is there a test file for it? + - does the test follow the BDD given/when/then structure? + - does each `when([tN])` step exist? + + **if any journey was planned but not implemented, go back and add it NOW.** + + this is buttonup. absent journey tests = incomplete implementation. + test coverage proves prod coverage. no test = no proof = not done. + + - slug: has-contract-output-variants-snapped + say: | + double-check: does each public contract have EXHAUSTIVE snapshots? + + **zero gaps in caller experience.** every contract must snap every output variant. + + for each new or modified public contract: + + | contract type | what to snap | required variants | + |---------------|--------------|-------------------| + | cli command | stdout + stderr | success, error, --help, edge cases | + | api endpoint | response body | 2xx, 4xx, 5xx, edge cases | + | sdk method | return value | success, error, edge cases | + + checklist per contract: + - [ ] positive path (success) is snapped + - [ ] negative path (error) is snapped + - [ ] help/usage is snapped (for cli) + - [ ] edge cases are snapped (empty, invalid, boundary) + - [ ] snapshot shows actual output, not placeholder + + why this matters: + - snapshots enable vibecheck in prs — reviewers see actual output without execute + - snapshots detect drift over time — output changes surface in diffs + - absent variants mean blind spots in review + - exhaustive coverage proves the contract works for all callers + + **zero leniency.** if a contract lacks any variant, add the test case NOW. + + if you find yourself about to say "this variant isn't worth a snapshot" — stop. + that is the variant that will break in prod. snap it. + + this is buttonup. absent snapshots = absent proof. add them or fail this gate. + + - slug: has-snap-changes-rationalized + say: | + double-check: is every `.snap` file change intentional and justified? + + for each `.snap` file in git diff: + 1. what changed? (added, modified, deleted) + 2. was this change intended or accidental? + 3. if intended: what is the rationale? + 4. if accidental: revert it or explain why the new output is an improvement + + common regressions caught here: + - output format degraded (lost alignment, lost structure) + - error messages became less helpful + - timestamps or ids leaked into snapshots (flaky) + - extra output added unintentionally + + forbidden: + - "updated snapshots" without per-file rationale + - bulk snapshot updates without review + - regressions accepted without justification + + every snap change tells a story. make sure the story is intentional. + + - slug: has-critical-paths-frictionless + say: | + double-check: are the critical paths frictionless in practice? + + look back at the repros artifact for critical paths: + - .behavior/v2026_05_06.terminal-sessions/3.2.distill.repros.experience.*.md + + for each critical path: + - run through it manually — is it smooth? + - are there unexpected errors? + - does it feel effortless to the user? + + critical paths must "just work." if there's friction, fix it now. + + - slug: has-ergonomics-validated + say: | + double-check: does the actual input/output match what felt right at repros? + + compare the implemented input/output to what was sketched in repros: + - does the actual input match the planned input? + - does the actual output match the planned output? + - did the design change between repros and implementation? + + if the ergonomics drifted, either: + - update repros to reflect the better design, or + - fix the implementation to match the planned ergonomics + + - slug: has-play-test-convention + say: | + double-check: are journey test files named correctly? + + journey tests should use `.play.test.ts` suffix: + - `feature.play.test.ts` — journey test + - `feature.play.integration.test.ts` — if repo requires integration runner + - `feature.play.acceptance.test.ts` — if repo requires acceptance runner + + verify: + - are journey tests in the right location? + - do they have the `.play.` suffix? + - if not supported, is the fallback convention used? + + - slug: has-fixed-all-gaps + say: | + final buttonup check: did you FIX every gap you found, or just detect it? + + **this is the buttonup phase. detection is not enough — you must fix.** + + look back at all the reviews above. for every gap you identified: + - absent test coverage → did you WRITE the test? + - absent prod coverage → did you IMPLEMENT the behavior? + - failed test → did you FIX the code or test? + - skipped test → did you REMOVE the skip and make it pass? + + **zero omissions.** if any review above surfaced a gap, that gap must be fixed before you pass this gate. + + ask yourself: + - did i just note the gap, or did i actually fix it? + - is there any item marked "todo" or "later"? (forbidden) + - is there any coverage marked incomplete? (forbidden) + + **if you detected it, you fixed it.** prove it with citations. + + this is the final self-review. you are about to hand off to peer review. + prove that all items above were addressed — not deferred. + + peer: + # slug = ergo-contract-snapshots + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/rule.require.contract-snapshot-exhaustiveness.md' --refs '.agent/repo=ehmpathy/role=ergonomist/briefs/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.coverage/*.md' --refs '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/*.md' --diffs since-main --paths-with '**/*.ts' --paths-with '**/*.snap' --join intersect --output '$route/.reviews/$stone.peer-review.ergo-contract-snapshots.md' + + # slug = mech-external-contracts + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/rule.require.external-contract-integration-tests.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.coverage/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.unit/rule.forbid.remote-boundaries.md' --diffs since-main --paths-with '**/*.ts' --paths-with '**/*.snap' --join intersect --output '$route/.reviews/$stone.peer-review.mech-external-contracts.md' + + # --- ergonomist reviews --- + # lineage: $rhachet enroll claude --model sonnet --roles behaver,ergonomist,mechanic -p "review the diff for snapshot coverage on contract endpoints and acceptance test user journey coverage. emit BLOCKERS and NITPICKS." + # slug = ergo-acceptance-journey-coverage + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/ergonomist/rule.require.acceptance-journey-coverage.md' --refs '.agent/repo=ehmpathy/role=ergonomist/briefs/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/frames.behavior/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.coverage/*.md' --refs '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/*.md' --diffs since-main --paths-with '**/*.ts' --paths-with '**/*.snap' --join intersect --output '$route/.reviews/$stone.peer-review.ergo-acceptance-journey-coverage.md' + + # lineage: $rhachet enroll claude --model sonnet --roles behaver,ergonomist,mechanic -p "review the diff for experiential and visual blemishes in snapshotted acceptance test journeys. emit BLOCKERS and NITPICKS." + # slug = ergo-snapshot-visual-blemishes + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.execution/ergonomist/rule.forbid.snapshot-visual-blemishes.md' --refs '.agent/repo=ehmpathy/role=ergonomist/briefs/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/lang.tones/*.md.min' --refs '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/rule.require.contract-snapshot-exhaustiveness.md' --diffs since-main --paths-with '**/*.ts' --paths-with '**/*.snap' --join intersect --output '$route/.reviews/$stone.peer-review.ergo-snapshot-visual-blemishes.md' + + # slug = mech-given-when-then + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/frames.behavior/rule.require.given-when-then.md' --refs '.agent/repo=ehmpathy/role=architect/briefs/criteria.given_when_then.[seed].v3.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/frames.behavior/*.md.min' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/lessons.howto/*.md.min' --diffs since-main --paths-with '**/*.test.ts' --paths-with '**/*.snap' --join intersect --output '$route/.reviews/$stone.peer-review.mech-given-when-then.md' + + # --- test intent reviews --- + # lineage: $rhachet enroll claude --model sonnet --roles behaver,architect,mechanic -p "review the current implementation for test intent violation diffs. if any of the diffs related to tests loosened assertions or changed the criteria, this is a blocker. tests were added for a reason. we have to maintain the behavior they locked in. emit BLOCKERS and NITPICKS." + # slug = mech-test-intent + - $rhx review --repo bhrain --mode hard --rules '.agent/repo=bhuild/role=behaver/briefs/practices/behavior.verification/rule.forbid.test-intent-violations.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.coverage/*.md' --refs '.agent/repo=ehmpathy/role=mechanic/briefs/practices/work.flow/refactor/rule.require.review-test-changes.md.min' --diffs since-main --paths-with '**/*.test.ts' --paths-with '**/*.snap' --join intersect --output '$route/.reviews/$stone.peer-review.mech-test-intent.md' + + # verify test scope purity (grain, boundaries, mocks, blackbox) + - $rhachet run --repo bhrain --skill review --rules '.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.coverage/rule.require.test-coverage-by-grain.md,.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.unit/rule.forbid.unit.remote-boundaries.md,.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.integration/rule.forbid.integration.mocks.md,.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.acceptance/rule.forbid.acceptance.mocks.md,.agent/repo=ehmpathy/role=mechanic/briefs/practices/code.test/scope.acceptance/rule.require.acceptance.blackbox.md' --diffs since-main --paths-with '{src,blackbox}/**/*.test.ts' --join intersect --output '$route/.reviews/$stone.peer-review.test-scope-purity.md' --mode hard + +judges: + # enforce peer reviews pass with zero blockers + - $rhachet run --repo bhrain --skill route.stone.judge --mechanism reviewed? --stone $stone --route $route --allow-blockers 0 --allow-nitpicks 0 diff --git a/.behavior/v2026_05_06.terminal-sessions/5.3.verification.handoff.v1.to_foreman.md b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.handoff.v1.to_foreman.md new file mode 100644 index 0000000..808638e --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.handoff.v1.to_foreman.md @@ -0,0 +1,109 @@ +# handoff: manual integration test required + +## situation + +the terminal session snapshot/restore feature requires manual integration test on a cosmic desktop with ptyxis windows. this cannot be automated or executed from within claude-code. + +## what was attempted + +1. **static code review** — all guard clauses, error paths, and idempotent patterns verified +2. **self-review** — 8 self-reviews completed for behavior coverage, declaration adherance, role standards +3. **peer-review** — 8 automated peer reviews passed via guard + +## what makes this fundamentally impossible without foreman intervention + +1. **cosmic compositor required** — `cos-cli info --json` only works when cosmic-comp is the active wayland compositor +2. **ptyxis windows required** — cannot spawn or detect ptyxis windows from a cli context without display access +3. **visual verification required** — to confirm windows appear on correct workspaces is a visual task + +## verification procedure for foreman + +### step 1: install dependencies + +```bash +# apply bash aliases first +source ~/git/more/dev-env-setup/src/install_env.pt3.cosmic.sh + +# install cos-cli +install_cos_cli + +# sync the bash aliases +sync.devenv.bashaliases + +# install the systemd timer +install_terminal_session_timer + +# configure logout hook +configure_terminal_session_logout_hook +``` + +### step 2: test snapshot + +```bash +# open a few ptyxis windows on different workspaces +# then run: +terminal.snapshot +``` + +**expected output**: +``` +snapshot saved: N windows across M workspaces + → ~/.config/terminal-sessions/default.json +``` + +### step 3: verify snapshot json + +```bash +cat ~/.config/terminal-sessions/default.json | jq . +``` + +**expected**: json with version, timestamp, workspaces array, each workspace with windows array + +### step 4: test restore (plan mode) + +```bash +terminal.restore +``` + +**expected output**: list of workspaces and windows that would be restored + +### step 5: test restore (apply mode) + +```bash +# close all ptyxis windows first +# then run: +terminal.restore --apply +``` + +**expected**: windows reappear on their original workspaces + +### step 6: verify systemd timer + +```bash +systemctl --user status terminal-session-snapshot.timer +``` + +**expected**: timer active, triggers every 5 minutes + +### step 7: verify logout hook + +```bash +systemctl --user status terminal-session-snapshot-on-exit.service +``` + +**expected**: service enabled, will run before shutdown + +## verification complete when + +- [ ] `terminal.snapshot` captures windows correctly +- [ ] `terminal.restore` shows correct plan +- [ ] `terminal.restore --apply` spawns windows on correct workspaces +- [ ] systemd timer is active and runs every 5 min +- [ ] logout hook is enabled + +## rewind instruction + +if verification fails and changes are needed: +```bash +rhx route.stone.set --stone 5.3.verification --as rewound +``` diff --git a/.behavior/v2026_05_06.terminal-sessions/5.3.verification.stone b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.stone new file mode 100644 index 0000000..daf6f2f --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.stone @@ -0,0 +1,304 @@ +prove the deliverable works via test verification — fix all gaps + +--- + +## .what + +this is the verification gate — the **buttonup phase**. + +you cannot pass execution without proof that all tests pass. more importantly: **test coverage enforces prod coverage**. if tests are absent, prod is incomplete. if prod is incomplete, fix it. + +## .the buttonup mandate: zero omissions + +**this is not a detection phase. this is a completion phase.** + +when you find a gap, you do not note it and move on. you **fix it**. + +| gap type | action | +|----------|--------| +| absent test coverage | write the test NOW | +| absent prod coverage | implement the behavior NOW | +| failed test | fix the code or fix the test NOW | +| skipped test | remove the skip and make it pass NOW | + +**if you detect it, you fix it. no exceptions.** + +## .strictness: zero tolerance, zero exceptions + +**this gate enforces absolute standards. there is no leniency.** + +| constraint | definition | +|------------|------------| +| zero deferrals | you cannot defer any test to later. all tests pass now or you fail. | +| zero fake tests | tests must verify real behavior. assertions that always pass are fraud. | +| zero unproven claims | every claim of "test passes" must cite the exact command run and output. | +| zero credential excuses | "i don't have creds" is not an excuse. get them, mock them, or fail. | +| zero skips | .skip() and .only() are forbidden. silent bypasses are forbidden. | +| zero exceptions | there are no special cases. the rules apply to all. | +| zero omissions | if you find a gap in coverage, you fix it — test or prod. | + +**if a blocker prevents tests from run, that is a BLOCKER. full stop.** + +you do not proceed. you do not defer. you fix it or you fail the gate. + +## .why + +**why does this gate exist?** + +your crew is about to review a pr you wrote. they need proof it works — not words, proof. tests are that proof. + +**test coverage drives prod coverage.** if a behavior lacks a test, that behavior is unproven. unproven behaviors are incomplete deliverables. the test proves the implementation exists and works. + +without this gate: +- tests might fail and nobody notices +- tests might be skipped and nobody notices +- behaviors might lack coverage and nobody notices +- broken code ships to peers +- incomplete implementations slip through + +with this gate: +- every test passes or you fix it +- every behavior has coverage or you add it +- every skip is removed or justified +- proven code ships to peers +- **gaps get fixed, not deferred** + +**the cardinal rules**: +1. never leave behavior without true, dependable test coverage +2. never offload work onto your crew unless there is truly, fundamentally no other option +3. never claim a test passes without cite of the exact command and output + +you fix it yourself. you exhaust every option: debug, research, try alternatives. only when you hit a wall that is physically impossible to climb alone — credentials only the foreman possesses, access only they can grant — only then may you ask for help. + +## .how + +reference the below for full context +- .behavior/v2026_05_06.terminal-sessions/0.wish.md +- .behavior/v2026_05_06.terminal-sessions/1.vision.md +- .behavior/v2026_05_06.terminal-sessions/2.1.criteria.blackbox.md (if declared) +- .behavior/v2026_05_06.terminal-sessions/3.2.distill.repros.experience.*.md (if declared) ← **repros artifact** + +--- + +### step 1: emit verification checklist + +emit to +- .behavior/v2026_05_06.terminal-sessions/5.3.verification.yield.md + +this is your roadmap. emit it first, then work through it step by step. + +**checklist structure:** + +``` +## verification checklist + +### behavior coverage (with reference to repros) + +for each journey sketched in repros, verify it was implemented with snapshots. + +| journey (from repros) | test file | snapshots? | critical path? | ergonomics ok? | status | +|-----------------------|-----------|------------|----------------|----------------|--------| +| {journey 1} | {path} | ✓ / ✗ | ✓ frictionless / needs work | ✓ natural / needs work | ⏳ | +| {journey 2} | {path} | ✓ / ✗ | ✓ frictionless / needs work | ✓ natural / needs work | ⏳ | +... + +### zero skips verified +- [ ] no .skip() or .only() found +- [ ] no silent credential bypasses +- [ ] no prior failures carried forward + +### snapshot coverage for contract outputs + +each public contract needs dedicated snapshots that demonstrate its stdout for: +- **vibechecks in prs** — reviewers see actual output without executing code +- **drift detection** — changes to output surface in diffs over time + +| contract | output variants | snapshot file | status | +|----------|-----------------|---------------|--------| +| {command 1} | success, error, help | {path.snap} | ⏳ | +| {command 2} | success, error, help | {path.snap} | ⏳ | +... + +checklist: +- [ ] every new cli command has `.snap` snapshots for stdout/stderr +- [ ] every new app screen has `.snap` snapshots for screenshots +- [ ] every new sdk method has `.snap` snapshots for responses +- [ ] each output variant is exercised (success, error, edge cases) +- [ ] snapshots demonstrate actual output, not just "it ran" + +### snapshot change rationalization + +for each `.snap` file changed, rationalize whether the change was intended or accidental: + +| snap file | change type | intended? | rationale | +|-----------|-------------|-----------|-----------| +| {path.snap} | added / modified / deleted | yes / no | {why this change is correct} | +... + +checklist: +- [ ] every `.snap` change has been reviewed +- [ ] intended changes have clear rationale +- [ ] accidental changes have been reverted or justified as improvements + +### tests executed — with proof + +**every test run must be proven with exact command and output.** + +| test suite | command run | result | proof (exit code + summary) | +|------------|-------------|--------|----------------------------| +| types | `npm run test:types` | ✓ / ✗ | exit 0, no errors | +| lint | `npm run test:lint` | ✓ / ✗ | exit 0, no errors | +| format | `npm run test:format` | ✓ / ✗ | exit 0, no errors | +| unit | `npm run test:unit` | ✓ / ✗ | exit 0, N tests passed | +| integration | `npm run test:integration` | ✓ / ✗ | exit 0, N tests passed | +| acceptance | `npm run test:acceptance` | ✓ / ✗ | exit 0, N tests passed | + +checklist: +- [ ] every test command was run (not "i think it passed") +- [ ] every test command output was observed (not assumed) +- [ ] the exact exit code was verified (0 = pass, non-zero = fail) +- [ ] no tests were skipped, mocked, or faked + +**zero unproven claims.** if you claim a test passes, cite the command and output. + +### contract output snapshot exhaustiveness + +**every user-faced contract must have exhaustive snapshot coverage.** + +| contract type | contract | positive path snapped? | negative path snapped? | edge cases snapped? | +|---------------|----------|------------------------|------------------------|---------------------| +| cli | {command} | ✓ / ✗ | ✓ / ✗ | ✓ / ✗ | +| api | {endpoint} | ✓ / ✗ | ✓ / ✗ | ✓ / ✗ | +| sdk | {method} | ✓ / ✗ | ✓ / ✗ | ✓ / ✗ | + +checklist: +- [ ] every cli command has stdout/stderr snapshots for success, error, and help +- [ ] every api endpoint has response snapshots for success and error codes +- [ ] every sdk method has return value snapshots for success and error +- [ ] every contract has edge case snapshots (empty input, invalid input, boundary) + +**zero gaps in caller experience.** the reviewer must see exactly what callers see. + +### blockers +- none (or list handoff references) +``` + +update the checklist as you complete each step below. + +--- + +### step 2: verify AND FIX behavior coverage + +walk through wish and vision: +- every behavior promised must have an acceptance test +- for each behavior, you can point to the test file +- no behavior left untested + +**why?** your crew trusts the test suite. if a behavior isn't tested, it isn't proven. untested behaviors are unverified promises. + +**test coverage enforces prod coverage.** if a test is absent, either: +1. the behavior was not implemented → IMPLEMENT IT NOW +2. the behavior was implemented without a test → WRITE THE TEST NOW + +if a behavior lacks a test, **write one NOW**. do not move on with gaps. update your checklist when done. + +--- + +### step 3: verify AND FIX zero skips + +scan for forbidden patterns: +- `.skip()` or `.only()` in test files +- `if (!credentials) return` or similar silent bypasses +- prior failures carried forward (known-broken tests) + +**why?** failures are better than skips. skips hide problems. failures expose them. a skipped test is a lie — it pretends coverage exists when it doesn't. + +**this is buttonup.** if you find skips: +1. REMOVE the skip +2. MAKE the test pass (fix the code or fix the test) +3. update your checklist + +do not note skips and move on. fix them. all tests must run. + +--- + +### step 4: run all tests AND FIX all failures + +run each test suite and **cite the exact command and output**. + +```bash +npm run test:types # cite exit code +npm run test:lint # cite exit code +npm run test:format # cite exit code +npm run test:unit # cite exit code + test count +npm run test:integration # cite exit code + test count +npm run test:acceptance # cite exit code + test count +``` + +all must pass — no exceptions. no deferrals. no "i'll fix it later." + +**this is buttonup.** if tests fail, fix them. that is the job. + +failures indicate one of: +1. prod code is broken → FIX THE PROD CODE +2. test has a bug → FIX THE TEST BUG (preserve intention) +3. coverage gap exists → FILL THE GAP + +**consider all failures as defects from this pr.** there are no "prior failures." + +if a test was broken before you started — fix it. if a test is flaky — fix it. if a test fails for reasons unrelated to your changes — fix it anyway. you do not get to say "that was already broken." you are here now. you fix it. + +**take initiative. take ownership.** + +**preserve test intentions.** when you fix a test, you fix why it failed — not what it tests. to change what a test verifies is not a fix. it is at worst malicious deception, at best reckless negligence. the test knew a truth. if it fails, either the code is wrong or the test has a bug. fix the cause, not the assertion. + +**zero fake tests.** a test that always passes is fraud. a test that skips is a lie. a test that mocks the system under test proves nothingness. tests must verify real behavior against real code. + +**escalation path:** +1. debug the failure — read the error, understand the cause +2. research — search for similar issues, read docs +3. try alternatives — different approach, different tool +4. ask for help — other resources, other clones +5. deeper research — exhaust every option +6. only if insurmountable — emit handoff (see step 5) + +**ask yourself at each level:** +- did i read the error message carefully? +- did i search for similar issues? +- did i try a different approach? +- did i isolate the problem? +- did i ask for help? +- did i exhaust every option? + +you move to handoff only when you can answer "yes" to all of the above and still cannot proceed. + +update your checklist when all tests pass. + +--- + +### step 5: handoff (only if insurmountable) + +a handoff is a document that transfers work to your foreman because you hit a wall that is physically impossible to climb alone. + +**foreman-only blockers:** +- credentials only the foreman possesses +- external access only the foreman can grant +- approval that requires foreman authority + +handoff is the absolute last resort. you must exhaust every option before you consider it. + +if you need to emit a handoff: + +emit to +- .behavior/v2026_05_06.terminal-sessions/5.3.verification.handoff.v$N.to_foreman.md + +**handoff must include:** +1. what you tried (list every approach you attempted) +2. why each approach failed (be specific) +3. what makes this fundamentally impossible without foreman intervention +4. is this truly a "foreman possesses the key" situation? +5. rewind instruction: `rhx route.stone.set --stone 5.3.verification --as rewound` + +your crew should read your handoff and think: "yes, there was truly no other way." + +update your checklist to reference the handoff. diff --git a/.behavior/v2026_05_06.terminal-sessions/5.3.verification.yield.md b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.yield.md new file mode 100644 index 0000000..779d2ac --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/5.3.verification.yield.md @@ -0,0 +1,65 @@ +# verification: terminal sessions + +## verification checklist + +### test framework context + +**this is a bash shell implementation, not a typescript project.** + +there are no `npm run test:*` commands. the verification paradigm is manual integration test via actual command execution on a cosmic desktop with ptyxis windows. + +### behavior coverage + +| behavior | implementation | verification type | status | +|----------|----------------|-------------------|--------| +| snapshot ptyxis windows | `_terminal_session_snapshot` | manual — requires cosmic desktop + ptyxis | ⏳ handoff | +| restore windows to workspaces | `_terminal_session_restore` | manual — requires cosmic desktop | ⏳ handoff | +| auto-snapshot every 5 min | systemd timer | manual — check `systemctl --user status` | ⏳ handoff | +| snapshot on logout | systemd service | manual — check service enabled | ⏳ handoff | + +### zero skips verified + +- [x] no `.skip()` or `.only()` — not applicable (bash, not jest) +- [x] no silent credential bypasses — all guards fail loud +- [x] no prior failures — new implementation + +### static code verification + +| check | method | result | +|-------|--------|--------| +| guard clauses present | read src/bash_aliases.sh:127-144, 186-197 | ✓ failfast guards | +| error messages clear | read src/bash_aliases.sh | ✓ all "error:" to stderr with fix hints | +| idempotent install | read src/install_env.pt3.cosmic.sh:123-133 | ✓ skip if installed | +| systemd units valid | read src/*.service, src/*.timer | ✓ valid unit files | + +### snapshot coverage for contract outputs + +**contract outputs are terminal stdout — no automated snapshot framework for bash.** + +| contract | expected output | verification type | status | +|----------|-----------------|-------------------|--------| +| `terminal.snapshot` | "snapshot saved: N windows" | manual — requires cosmic | ⏳ handoff | +| `terminal.restore` | plan output with workspace list | manual — requires cosmic | ⏳ handoff | +| `terminal.restore --apply` | windows spawned and moved | manual — requires cosmic | ⏳ handoff | + +### tests executed — with proof + +| test type | command | result | proof | +|-----------|---------|--------|-------| +| types | n/a (bash) | n/a | bash has no type system | +| lint | n/a (not configured) | n/a | shellcheck could be run but not configured | +| format | n/a (not configured) | n/a | shfmt could be run but not configured | +| unit | n/a (bash) | n/a | bash procedures lack unit test framework | +| integration | requires cosmic desktop | n/a | handoff to human | +| acceptance | requires cosmic desktop | n/a | handoff to human | + +### blockers + +**fundamental blocker: cosmic desktop environment required** + +the verification requires: +1. cosmic compositor active (pop-os/cosmic desktop) +2. ptyxis terminal windows open +3. human interaction to verify window placement + +see handoff below. diff --git a/.behavior/v2026_05_06.terminal-sessions/refs/template.[feedback].v1.[given].by_human.md b/.behavior/v2026_05_06.terminal-sessions/refs/template.[feedback].v1.[given].by_human.md new file mode 100644 index 0000000..8d51a6d --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/refs/template.[feedback].v1.[given].by_human.md @@ -0,0 +1,27 @@ +emit your response to the feedback into +- .behavior/v2026_05_06.terminal-sessions/$BEHAVIOR_REF_NAME.[feedback].v$FEEDBACK_VERSION.[taken].by_robot.md + +1. emit your response checklist +2. exec your response plan +3. emit your response checkoffs into the checklist + +--- + +first, bootup your mechanics briefs again + +./node_modules/.bin/rhachet roles boot --repo ehmpathy --role mechanic + +--- +--- +--- + + +# blocker.1 + +--- + +# nitpick.2 + +--- + +# blocker.3 diff --git a/.behavior/v2026_05_06.terminal-sessions/review/self/.gitignore b/.behavior/v2026_05_06.terminal-sessions/review/self/.gitignore new file mode 100644 index 0000000..c6959e2 --- /dev/null +++ b/.behavior/v2026_05_06.terminal-sessions/review/self/.gitignore @@ -0,0 +1,3 @@ +# ignore all self-review files +* +!.gitignore diff --git a/.claude/settings.json b/.claude/settings.json index 5798bdb..5463560 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -30,25 +30,25 @@ }, { "type": "command", - "command": "./node_modules/.bin/rhx route.drive --mode hook", - "timeout": 5, + "command": "./node_modules/.bin/rhachet roles boot --role driver", + "timeout": 30, "author": "repo=bhrain/role=driver" }, { "type": "command", - "command": "./node_modules/.bin/npx rhachet roles boot --role driver", - "timeout": 30, + "command": "./node_modules/.bin/rhx route.drive --when hook.onBoot", + "timeout": 5, "author": "repo=bhrain/role=driver" }, { "type": "command", - "command": "./node_modules/.bin/npx rhachet roles boot --role reviewer", + "command": "./node_modules/.bin/rhachet roles boot --role reviewer", "timeout": 30, "author": "repo=bhrain/role=reviewer" }, { "type": "command", - "command": "npx rhachet roles boot --role behaver", + "command": "./node_modules/.bin/rhachet roles boot --role behaver", "timeout": 10, "author": "repo=bhuild/role=behaver" } @@ -176,7 +176,7 @@ "hooks": [ { "type": "command", - "command": "./node_modules/.bin/rhx route.drive --mode hook", + "command": "./node_modules/.bin/rhx route.drive --when hook.onStop", "timeout": 5, "author": "repo=bhrain/role=driver" } @@ -227,6 +227,9 @@ "Bash(rhx git.repo.test --what unit)", "Bash(rhx git.repo.test --what integration)", "Bash(rhx git.repo.test --what acceptance)", + "Bash(rhx git.repo.test --what unit --scope 'name://getUserById')", + "Bash(rhx git.repo.test --what integration --scope 'name://invoice')", + "Bash(rhx git.repo.test --what unit --scope 'path://src/domain.operations/customer')", "Bash(rhx git.repo.test --what unit --scope getUserById)", "Bash(rhx git.repo.test --what integration --scope invoice)", "Bash(rhx git.repo.test --what unit --scope src/domain.operations/customer)", diff --git a/package.json b/package.json index 1a570b9..687edde 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "organization": "uladkasach", "devDependencies": { - "rhachet": "^1.40.7", - "rhachet-brains-anthropic": "^0.4.0", + "rhachet": "^1.41.9", + "rhachet-brains-anthropic": "^0.4.1", "rhachet-brains-xai": "^0.3.3", - "rhachet-roles-bhrain": "^0.27.3", - "rhachet-roles-bhuild": "^0.21.1", - "rhachet-roles-ehmpathy": "^1.35.0" + "rhachet-roles-bhrain": "^0.27.6", + "rhachet-roles-bhuild": "^0.21.9", + "rhachet-roles-ehmpathy": "^1.35.5" }, "scripts": { "prepare:rhachet": "rhachet init --hooks --roles mechanic behaver driver reviewer", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fbe693..f6b675b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,23 +9,23 @@ importers: .: devDependencies: rhachet: - specifier: ^1.40.7 - version: 1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + specifier: ^1.41.9 + version: 1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) rhachet-brains-anthropic: - specifier: ^0.4.0 - version: 0.4.0(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + specifier: ^0.4.1 + version: 0.4.1(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) rhachet-brains-xai: specifier: ^0.3.3 - version: 0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + version: 0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) rhachet-roles-bhrain: - specifier: ^0.27.3 - version: 0.27.3(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4))) + specifier: ^0.27.6 + version: 0.27.6(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4))) rhachet-roles-bhuild: - specifier: ^0.21.1 - version: 0.21.1(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))(rhachet-roles-bhrain@0.27.3(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))) + specifier: ^0.21.9 + version: 0.21.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))(rhachet-roles-bhrain@0.27.6(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))) rhachet-roles-ehmpathy: - specifier: ^1.35.0 - version: 1.35.0(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + specifier: ^1.35.5 + version: 1.35.5(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) packages: @@ -78,6 +78,10 @@ packages: resolution: {integrity: sha512-I2/1McBZCcM3PfM4ck8D6gnZR3K7+yl1fGkwTq/3ThEn9tdLjNwcdgTbPfxfX6LoecLrH9Ekoo+D9nmQ0T261w==} engines: {node: '>=18.0.0'} + '@aws-sdk/client-sso@3.1041.0': + resolution: {integrity: sha512-BJrZksR4qXCQODqsxOa9OPFtktumCJfJp99lpX17+z0tA8cR0EygKgvJs61zX80OHmGDY23tus7gXB36LinQAg==} + engines: {node: '>=20.0.0'} + '@aws-sdk/client-sso@3.958.0': resolution: {integrity: sha512-6qNCIeaMzKzfqasy2nNRuYnMuaMebCcCPP4J2CVGkA8QYMbIVKPlkn9bpB20Vxe6H/r3jtCCLQaOJjVTx/6dXg==} engines: {node: '>=18.0.0'} @@ -86,6 +90,10 @@ packages: resolution: {integrity: sha512-DrZgDnF1lQZv75a52nFWs6MExihJF2GZB6ETZRqr6jMwhrk2kbJPUtvgbifwcL7AYmVqHQDJBrR/MqkwwFCpiw==} engines: {node: '>=18.0.0'} + '@aws-sdk/core@3.974.8': + resolution: {integrity: sha512-njR2qoG6ZuB0kvAS2FyICsFZJ6gmCcf2X/7JcD14sUvGDm26wiZ5BrA6LOiUxKFEF+IVe7kdroxyE00YlkiYsw==} + engines: {node: '>=20.0.0'} + '@aws-sdk/crc64-nvme@3.957.0': resolution: {integrity: sha512-qSwSfI+qBU9HDsd6/4fM9faCxYJx2yDuHtj+NVOQ6XYDWQzFab/hUdwuKZ77Pi6goLF1pBZhJ2azaC2w7LbnTA==} engines: {node: '>=18.0.0'} @@ -138,6 +146,10 @@ packages: resolution: {integrity: sha512-BBgKawVyfQZglEkNTuBBdC3azlyqNXsvvN4jPkWAiNYcY0x1BasaJFl+7u/HisfULstryweJq/dAvIZIxzlZaA==} engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-host-header@3.972.10': + resolution: {integrity: sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-location-constraint@3.957.0': resolution: {integrity: sha512-y8/W7TOQpmDJg/fPYlqAhwA4+I15LrS7TwgUEoxogtkD8gfur9wFMRLT8LCyc9o4NMEcAnK50hSb4+wB0qv6tQ==} engines: {node: '>=18.0.0'} @@ -146,10 +158,18 @@ packages: resolution: {integrity: sha512-w1qfKrSKHf9b5a8O76yQ1t69u6NWuBjr5kBX+jRWFx/5mu6RLpqERXRpVJxfosbep7k3B+DSB5tZMZ82GKcJtQ==} engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-logger@3.972.10': + resolution: {integrity: sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-recursion-detection@3.957.0': resolution: {integrity: sha512-D2H/WoxhAZNYX+IjkKTdOhOkWQaK0jjJrDBj56hKjU5c9ltQiaX/1PqJ4dfjHntEshJfu0w+E6XJ+/6A6ILBBA==} engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-recursion-detection@3.972.11': + resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} + engines: {node: '>=20.0.0'} + '@aws-sdk/middleware-sdk-s3@3.957.0': resolution: {integrity: sha512-5B2qY2nR2LYpxoQP0xUum5A1UNvH2JQpLHDH1nWFNF/XetV7ipFHksMxPNhtJJ6ARaWhQIDXfOUj0jcnkJxXUg==} engines: {node: '>=18.0.0'} @@ -162,6 +182,10 @@ packages: resolution: {integrity: sha512-50vcHu96XakQnIvlKJ1UoltrFODjsq2KvtTgHiPFteUS884lQnK5VC/8xd1Msz/1ONpLMzdCVproCQqhDTtMPQ==} engines: {node: '>=18.0.0'} + '@aws-sdk/middleware-user-agent@3.972.38': + resolution: {integrity: sha512-iz+B29TXcAZsJpwB+AwG/TTGA5l/VnmMZ2UxtiySOZjI6gCdmviXPwdgzcmuazMy16rXoPY4mYCGe7zdNKfx5A==} + engines: {node: '>=20.0.0'} + '@aws-sdk/nested-clients@3.958.0': resolution: {integrity: sha512-/KuCcS8b5TpQXkYOrPLYytrgxBhv81+5pChkOlhegbeHttjM69pyUpQVJqyfDM/A7wPLnDrzCAnk4zaAOkY0Nw==} engines: {node: '>=18.0.0'} @@ -170,6 +194,10 @@ packages: resolution: {integrity: sha512-V8iY3blh8l2iaOqXWW88HbkY5jDoWjH56jonprG/cpyqqCnprvpMUZWPWYJoI8rHRf2bqzZeql1slxG6EnKI7A==} engines: {node: '>=18.0.0'} + '@aws-sdk/region-config-resolver@3.972.13': + resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} + engines: {node: '>=20.0.0'} + '@aws-sdk/signature-v4-multi-region@3.957.0': resolution: {integrity: sha512-t6UfP1xMUigMMzHcb7vaZcjv7dA2DQkk9C/OAP1dKyrE0vb4lFGDaTApi17GN6Km9zFxJthEMUbBc7DL0hq1Bg==} engines: {node: '>=18.0.0'} @@ -182,6 +210,10 @@ packages: resolution: {integrity: sha512-wzWC2Nrt859ABk6UCAVY/WYEbAd7FjkdrQL6m24+tfmWYDNRByTJ9uOgU/kw9zqLCAwb//CPvrJdhqjTznWXAg==} engines: {node: '>=18.0.0'} + '@aws-sdk/types@3.973.8': + resolution: {integrity: sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==} + engines: {node: '>=20.0.0'} + '@aws-sdk/util-arn-parser@3.957.0': resolution: {integrity: sha512-Aj6m+AyrhWyg8YQ4LDPg2/gIfGHCEcoQdBt5DeSFogN5k9mmJPOJ+IAmNSWmWRjpOxEy6eY813RNDI6qS97M0g==} engines: {node: '>=18.0.0'} @@ -190,6 +222,10 @@ packages: resolution: {integrity: sha512-xwF9K24mZSxcxKS3UKQFeX/dPYkEps9wF1b+MGON7EvnbcucrJGyQyK1v1xFPn1aqXkBTFi+SZaMRx5E5YCVFw==} engines: {node: '>=18.0.0'} + '@aws-sdk/util-endpoints@3.996.8': + resolution: {integrity: sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==} + engines: {node: '>=20.0.0'} + '@aws-sdk/util-locate-window@3.957.0': resolution: {integrity: sha512-nhmgKHnNV9K+i9daumaIz8JTLsIIML9PE/HUks5liyrjUzenjW/aHoc7WJ9/Td/gPZtayxFnXQSJRb/fDlBuJw==} engines: {node: '>=18.0.0'} @@ -197,6 +233,9 @@ packages: '@aws-sdk/util-user-agent-browser@3.957.0': resolution: {integrity: sha512-exueuwxef0lUJRnGaVkNSC674eAiWU07ORhxBnevFFZEKisln+09Qrtw823iyv5I1N8T+wKfh95xvtWQrNKNQw==} + '@aws-sdk/util-user-agent-browser@3.972.10': + resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} + '@aws-sdk/util-user-agent-node@3.957.0': resolution: {integrity: sha512-ycbYCwqXk4gJGp0Oxkzf2KBeeGBdTxz559D41NJP8FlzSej1Gh7Rk40Zo6AyTfsNWkrl/kVi1t937OIzC5t+9Q==} engines: {node: '>=18.0.0'} @@ -206,10 +245,23 @@ packages: aws-crt: optional: true + '@aws-sdk/util-user-agent-node@3.973.24': + resolution: {integrity: sha512-ZWwlkjcIp7cEL8ZfTpTAPNkwx25p7xol0xlKoWVVf22+nsjwmLcHYtTPjIV1cSpmB/b6DaK4cb1fSkvCXHgRdw==} + engines: {node: '>=20.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + '@aws-sdk/xml-builder@3.957.0': resolution: {integrity: sha512-Ai5iiQqS8kJ5PjzMhWcLKN0G2yasAkvpnPlq2EnqlIMdB48HsizElt62qcktdxp4neRMyGkFq4NzgmDbXnhRiA==} engines: {node: '>=18.0.0'} + '@aws-sdk/xml-builder@3.972.22': + resolution: {integrity: sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==} + engines: {node: '>=20.0.0'} + '@aws/lambda-invoke-store@0.2.2': resolution: {integrity: sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg==} engines: {node: '>=18.0.0'} @@ -674,6 +726,9 @@ packages: resolution: {integrity: sha512-leww0zzIirrvwaYMPI9fj6aRIlA/c6Y0/lifQQ1YOOyHEr0MNH3yYpjXeiVG+tWdPps4XxGclFWX2INPO3Yo5w==} engines: {node: '>= 20.19.0'} + '@nodable/entities@2.1.0': + resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -786,6 +841,10 @@ packages: resolution: {integrity: sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==} engines: {node: '>=18.0.0'} + '@smithy/config-resolver@4.4.17': + resolution: {integrity: sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==} + engines: {node: '>=18.0.0'} + '@smithy/config-resolver@4.4.5': resolution: {integrity: sha512-HAGoUAFYsUkoSckuKbCPayECeMim8pOu+yLy1zOxt1sifzEbrsRpYa+mKcMdiHKMeiqOibyPG0sFJnmaV/OGEg==} engines: {node: '>=18.0.0'} @@ -794,6 +853,14 @@ packages: resolution: {integrity: sha512-WsSHCPq/neD5G/MkK4csLI5Y5Pkd9c1NMfpYEKeghSGaD4Ja1qLIohRQf2D5c1Uy5aXp76DeKHkzWZ9KAlHroQ==} engines: {node: '>=18.0.0'} + '@smithy/core@3.23.17': + resolution: {integrity: sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.2.14': + resolution: {integrity: sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==} + engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.2.7': resolution: {integrity: sha512-CmduWdCiILCRNbQWFR0OcZlUPVtyE49Sr8yYL0rZQ4D/wKxiNzBNS/YHemvnbkIWj623fplgkexUd/c9CAKdoA==} engines: {node: '>=18.0.0'} @@ -818,6 +885,10 @@ packages: resolution: {integrity: sha512-QVD+g3+icFkThoy4r8wVFZMsIP08taHVKjE6Jpmz8h5CgX/kk6pTODq5cht0OMtcapUx+xrPzUTQdA+TmO0m1g==} engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@5.3.17': + resolution: {integrity: sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==} + engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@5.3.8': resolution: {integrity: sha512-h/Fi+o7mti4n8wx1SR6UHWLaakwHRx29sizvp8OOm7iqwKGFneT06GCSFhml6Bha5BT6ot5pj3CYZnCHhGC2Rg==} engines: {node: '>=18.0.0'} @@ -826,6 +897,10 @@ packages: resolution: {integrity: sha512-07InZontqsM1ggTCPSRgI7d8DirqRrnpL7nIACT4PW0AWrgDiHhjGZzbAE5UtRSiU0NISGUYe7/rri9ZeWyDpw==} engines: {node: '>=18.0.0'} + '@smithy/hash-node@4.2.14': + resolution: {integrity: sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==} + engines: {node: '>=18.0.0'} + '@smithy/hash-node@4.2.7': resolution: {integrity: sha512-PU/JWLTBCV1c8FtB8tEFnY4eV1tSfBc7bDBADHfn1K+uRbPgSJ9jnJp0hyjiFN2PMdPzxsf1Fdu0eo9fJ760Xw==} engines: {node: '>=18.0.0'} @@ -834,6 +909,10 @@ packages: resolution: {integrity: sha512-ZQVoAwNYnFMIbd4DUc517HuwNelJUY6YOzwqrbcAgCnVn+79/OK7UjwA93SPpdTOpKDVkLIzavWm/Ck7SmnDPQ==} engines: {node: '>=18.0.0'} + '@smithy/invalid-dependency@4.2.14': + resolution: {integrity: sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==} + engines: {node: '>=18.0.0'} + '@smithy/invalid-dependency@4.2.7': resolution: {integrity: sha512-ncvgCr9a15nPlkhIUx3CU4d7E7WEuVJOV7fS7nnK2hLtPK9tYRBkMHQbhXU1VvvKeBm/O0x26OEoBq+ngFpOEQ==} engines: {node: '>=18.0.0'} @@ -846,10 +925,18 @@ packages: resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} engines: {node: '>=18.0.0'} + '@smithy/is-array-buffer@4.2.2': + resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} + engines: {node: '>=18.0.0'} + '@smithy/md5-js@4.2.7': resolution: {integrity: sha512-Wv6JcUxtOLTnxvNjDnAiATUsk8gvA6EeS8zzHig07dotpByYsLot+m0AaQEniUBjx97AC41MQR4hW0baraD1Xw==} engines: {node: '>=18.0.0'} + '@smithy/middleware-content-length@4.2.14': + resolution: {integrity: sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-content-length@4.2.7': resolution: {integrity: sha512-GszfBfCcvt7kIbJ41LuNa5f0wvQCHhnGx/aDaZJCCT05Ld6x6U2s0xsc/0mBFONBZjQJp2U/0uSJ178OXOwbhg==} engines: {node: '>=18.0.0'} @@ -858,18 +945,38 @@ packages: resolution: {integrity: sha512-gpLspUAoe6f1M6H0u4cVuFzxZBrsGZmjx2O9SigurTx4PbntYa4AJ+o0G0oGm1L2oSX6oBhcGHwrfJHup2JnJg==} engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@4.4.32': + resolution: {integrity: sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.17': resolution: {integrity: sha512-MqbXK6Y9uq17h+4r0ogu/sBT6V/rdV+5NvYL7ZV444BKfQygYe8wAhDrVXagVebN6w2RE0Fm245l69mOsPGZzg==} engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.5.7': + resolution: {integrity: sha512-bRt6ZImqVSeTk39Nm81K20ObIiAZ3WefY7G6+iz/0tZjs4dgRRjvRX2sgsH+zi6iDCRR/aQvQofLKxxz4rPBZg==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-serde@4.2.20': + resolution: {integrity: sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@4.2.8': resolution: {integrity: sha512-8rDGYen5m5+NV9eHv9ry0sqm2gI6W7mc1VSFMtn6Igo25S507/HaOX9LTHAS2/J32VXD0xSzrY0H5FJtOMS4/w==} engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.2.14': + resolution: {integrity: sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.2.7': resolution: {integrity: sha512-bsOT0rJ+HHlZd9crHoS37mt8qRRN/h9jRve1SXUhVbkRzu0QaNYZp1i1jha4n098tsvROjcwfLlfvcFuJSXEsw==} engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.3.14': + resolution: {integrity: sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==} + engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.3.7': resolution: {integrity: sha512-7r58wq8sdOcrwWe+klL9y3bc4GW1gnlfnFOuL7CXa7UzfhzhxKuzNdtqgzmTV+53lEp9NXh5hY/S4UgjLOzPfw==} engines: {node: '>=18.0.0'} @@ -878,18 +985,38 @@ packages: resolution: {integrity: sha512-NELpdmBOO6EpZtWgQiHjoShs1kmweaiNuETUpuup+cmm/xJYjT4eUjfhrXRP4jCOaAsS3c3yPsP3B+K+/fyPCQ==} engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.6.1': + resolution: {integrity: sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==} + engines: {node: '>=18.0.0'} + + '@smithy/property-provider@4.2.14': + resolution: {integrity: sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==} + engines: {node: '>=18.0.0'} + '@smithy/property-provider@4.2.7': resolution: {integrity: sha512-jmNYKe9MGGPoSl/D7JDDs1C8b3dC8f/w78LbaVfoTtWy4xAd5dfjaFG9c9PWPihY4ggMQNQSMtzU77CNgAJwmA==} engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.3.14': + resolution: {integrity: sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==} + engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.3.7': resolution: {integrity: sha512-1r07pb994I20dD/c2seaZhoCuNYm0rWrvBxhCQ70brNh11M5Ml2ew6qJVo0lclB3jMIXirD4s2XRXRe7QEi0xA==} engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.2.14': + resolution: {integrity: sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.2.7': resolution: {integrity: sha512-eKONSywHZxK4tBxe2lXEysh8wbBdvDWiA+RIuaxZSgCMmA0zMgoDpGLJhnyj+c0leOQprVnXOmcB4m+W9Rw7sg==} engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.2.14': + resolution: {integrity: sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.2.7': resolution: {integrity: sha512-3X5ZvzUHmlSTHAXFlswrS6EGt8fMSIxX/c3Rm1Pni3+wYWB6cjGocmRIoqcQF9nU5OgGmL0u7l9m44tSUpfj9w==} engines: {node: '>=18.0.0'} @@ -898,10 +1025,22 @@ packages: resolution: {integrity: sha512-YB7oCbukqEb2Dlh3340/8g8vNGbs/QsNNRms+gv3N2AtZz9/1vSBx6/6tpwQpZMEJFs7Uq8h4mmOn48ZZ72MkA==} engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@4.3.1': + resolution: {integrity: sha512-aUQuDGh760ts/8MU+APjIZhlLPKhIIfqyzZaJikLEIMrdxFvxuLYD0WxWzaYWpmLbQlXDe9p7EWM3HsBe0K6Gw==} + engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.4.2': resolution: {integrity: sha512-M7iUUff/KwfNunmrgtqBfvZSzh3bmFgv/j/t1Y1dQ+8dNo34br1cqVEqy6v0mYEgi0DkGO7Xig0AnuOaEGVlcg==} engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.4.9': + resolution: {integrity: sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.3.14': + resolution: {integrity: sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==} + engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.3.7': resolution: {integrity: sha512-9oNUlqBlFZFOSdxgImA6X5GFuzE7V2H7VG/7E70cdLhidFbdtvxxt81EHgykGK5vq5D3FafH//X+Oy31j3CKOg==} engines: {node: '>=18.0.0'} @@ -910,10 +1049,22 @@ packages: resolution: {integrity: sha512-D5z79xQWpgrGpAHb054Fn2CCTQZpog7JELbVQ6XAvXs5MNKWf28U9gzSBlJkOyMl9LA1TZEjRtwvGXfP0Sl90g==} engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.12.13': + resolution: {integrity: sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==} + engines: {node: '>=18.0.0'} + '@smithy/types@4.11.0': resolution: {integrity: sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA==} engines: {node: '>=18.0.0'} + '@smithy/types@4.14.1': + resolution: {integrity: sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==} + engines: {node: '>=18.0.0'} + + '@smithy/url-parser@4.2.14': + resolution: {integrity: sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==} + engines: {node: '>=18.0.0'} + '@smithy/url-parser@4.2.7': resolution: {integrity: sha512-/RLtVsRV4uY3qPWhBDsjwahAtt3x2IsMGnP5W1b2VZIe+qgCqkLxI1UOHDZp1Q1QSOrdOR32MF3Ph2JfWT1VHg==} engines: {node: '>=18.0.0'} @@ -922,14 +1073,26 @@ packages: resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} engines: {node: '>=18.0.0'} + '@smithy/util-base64@4.3.2': + resolution: {integrity: sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.2.0': resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.2.2': + resolution: {integrity: sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.2.1': resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.2.3': + resolution: {integrity: sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==} + engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} @@ -938,26 +1101,54 @@ packages: resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@4.2.2': + resolution: {integrity: sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==} + engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.2.0': resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.2.2': + resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.16': resolution: {integrity: sha512-/eiSP3mzY3TsvUOYMeL4EqUX6fgUOj2eUOU4rMMgVbq67TiRLyxT7Xsjxq0bW3OwuzK009qOwF0L2OgJqperAQ==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.49': + resolution: {integrity: sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.19': resolution: {integrity: sha512-3a4+4mhf6VycEJyHIQLypRbiwG6aJvbQAeRAVXydMmfweEPnLLabRbdyo/Pjw8Rew9vjsh5WCdhmDaHkQnhhhA==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.54': + resolution: {integrity: sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==} + engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.2.7': resolution: {integrity: sha512-s4ILhyAvVqhMDYREeTS68R43B1V5aenV5q/V1QpRQJkCXib5BPRo4s7uNdzGtIKxaPHCfU/8YkvPAEvTpxgspg==} engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.4.2': + resolution: {integrity: sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg==} + engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.2.0': resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.2.2': + resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} + engines: {node: '>=18.0.0'} + + '@smithy/util-middleware@4.2.14': + resolution: {integrity: sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==} + engines: {node: '>=18.0.0'} + '@smithy/util-middleware@4.2.7': resolution: {integrity: sha512-i1IkpbOae6NvIKsEeLLM9/2q4X+M90KV3oCFgWQI4q0Qz+yUZvsr+gZPdAEAtFhWQhAHpTsJO8DRJPuwVyln+w==} engines: {node: '>=18.0.0'} @@ -966,6 +1157,14 @@ packages: resolution: {integrity: sha512-SvDdsQyF5CIASa4EYVT02LukPHVzAgUA4kMAuZ97QJc2BpAqZfA4PINB8/KOoCXEw9tsuv/jQjMeaHFvxdLNGg==} engines: {node: '>=18.0.0'} + '@smithy/util-retry@4.3.8': + resolution: {integrity: sha512-LUIxbTBi+OpvXpg91poGA6BdyoleMDLnfXjVDqyi2RvZmTveY5loE/FgYUBCR5LU2BThW2SoZRh8dTIIy38IPw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-stream@4.5.25': + resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==} + engines: {node: '>=18.0.0'} + '@smithy/util-stream@4.5.8': resolution: {integrity: sha512-ZnnBhTapjM0YPGUSmOs0Mcg/Gg87k503qG4zU2v/+Js2Gu+daKOJMeqcQns8ajepY8tgzzfYxl6kQyZKml6O2w==} engines: {node: '>=18.0.0'} @@ -974,6 +1173,10 @@ packages: resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@4.2.2': + resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} + engines: {node: '>=18.0.0'} + '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} @@ -982,6 +1185,10 @@ packages: resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} engines: {node: '>=18.0.0'} + '@smithy/util-utf8@4.2.2': + resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} + engines: {node: '>=18.0.0'} + '@smithy/util-waiter@4.2.7': resolution: {integrity: sha512-vHJFXi9b7kUEpHWUCY3Twl+9NPOZvQ0SAi+Ewtn48mbiJk4JY9MZmKQjGB4SCvVb9WPiSphZJYY6RIbs+grrzw==} engines: {node: '>=18.0.0'} @@ -990,6 +1197,10 @@ packages: resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} engines: {node: '>=18.0.0'} + '@smithy/uuid@1.1.2': + resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} + engines: {node: '>=18.0.0'} + '@tensorflow/tfjs-backend-cpu@4.22.0': resolution: {integrity: sha512-1u0FmuLGuRAi8D2c3cocHTASGXOmHc/4OvoVDENJayjYkS119fcTcQf4iHrtLthWyDIPy3JiPhRrZQC9EwnhLw==} engines: {yarn: '>= 1.3.2'} @@ -1392,10 +1603,17 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} + fast-xml-builder@1.1.9: + resolution: {integrity: sha512-jcyKVSEX13iseJqg7n/KWw+xnu/7fdrZ333Fac54KjHDIELVCfDDJXYIm6DTJ0Su4gSzrhqiK0DzY/wZbF40mw==} + fast-xml-parser@5.2.5: resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} hasBin: true + fast-xml-parser@5.7.2: + resolution: {integrity: sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==} + hasBin: true + fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -1811,6 +2029,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} + engines: {node: '>=14.0.0'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1889,8 +2111,8 @@ packages: resolution: {integrity: sha512-yzDL+Dv1az5WGpVvrRZT6gLBwDAzxLO/7newlyrfMM+ku91PFR9OvlADoqyulBCCUWnazv3eXl0vzrIyak4hAQ==} engines: {node: '>=8.0.0'} - rhachet-brains-anthropic@0.4.0: - resolution: {integrity: sha512-84VilMmja+9qKc4xV+ao/mHoA1wo+H4fIOApN1zIh86E5NfzOwO3Ij2kU+VU6fqdzs0353ZirEFXV3VNkA4epA==} + rhachet-brains-anthropic@0.4.1: + resolution: {integrity: sha512-SFtO8nsI+M6jjhVW20+S6UpW9yvAZdI1T3dT3uhOV1eM4HKVCHqZwlEuFI0LBbz+1eLRwSQkaK/Rqcf+S6GreQ==} engines: {node: '>=8.0.0'} peerDependencies: rhachet: '>=1.21.4' @@ -1901,14 +2123,14 @@ packages: peerDependencies: rhachet: '>=1.21.4' - rhachet-roles-bhrain@0.27.3: - resolution: {integrity: sha512-g8Pjy5D64sS+BlcHbH+RJFB0QxUIsOXKt1L0oOfH9OpHVmMmMMPs7DSZ7W5lKxIEQ9VEQoVex4GXUad3mDKaLw==} + rhachet-roles-bhrain@0.27.6: + resolution: {integrity: sha512-08nI2iE2dMrHEt0TOJ3Vbsc2eDcUDzYsqjUtwUv1gTw0UWBr/NHr2l9dxZ0WJNJ2frIjjpLFKvm0EbU5cKSjqQ==} engines: {node: '>=8.0.0'} peerDependencies: rhachet-brains-xai: '>=0.3.0' - rhachet-roles-bhuild@0.21.1: - resolution: {integrity: sha512-k8HcKqP62xBcrvgudkUb9WnItdE70TB1RZQ0c2RgchWrXxQUwLFJNGi+qZyJiJNgCwptWXHg3xn+gNeizMLFMA==} + rhachet-roles-bhuild@0.21.9: + resolution: {integrity: sha512-wKMfrrb7gctukIJSTD60KQapL8UYTFtcQu0aTF8x8qudr3TtFXt358lmpBmYkjslhZnwPoWWZjWBh8k/yiEdlg==} engines: {node: '>=18.0.0'} peerDependencies: rhachet-brains-xai: '>=0.3.3' @@ -1918,6 +2140,10 @@ packages: resolution: {integrity: sha512-ZC8B5N1OGbwSITU2hpOPIr9r+sBFWwUBptqaOSYC0mxzv9yd0Gl6JEItE+77wDubrcchZoniX01OfnDT8yzYcw==} engines: {node: '>=8.0.0'} + rhachet-roles-ehmpathy@1.35.5: + resolution: {integrity: sha512-1u1xSYz4LbDnrlt+vv/H4YRrSvuqSQZQgMT9HBFmxNbq0R6ERWubuoodlyEflyFDPxBQp9lfUI5lrnr3EtOMSw==} + engines: {node: '>=8.0.0'} + rhachet-roles-rhachet@0.1.7: resolution: {integrity: sha512-pbKp+J3TUZEVc73ivdcsDNtxXpK+FBa4O6bRKwHRb7Vx8itveTskOWvLW4dR+139+rpdkQLbPnQ79Jpuse2lwA==} engines: {node: '>=8.0.0'} @@ -1931,6 +2157,13 @@ packages: peerDependencies: zod: '>=4.3.0' + rhachet@1.41.9: + resolution: {integrity: sha512-IvGXKyuZGxv4Afb/+fDsQOy2fMo4ENh+ZVSNU+OcXjZFQsxmLWPcW8yOjPLiQZvzCLDvKAkCNC/TiSuuk+ZKkQ==} + engines: {node: '>=22.0.0'} + hasBin: true + peerDependencies: + zod: '>=4.3.0' + roarr@2.15.4: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} @@ -2057,6 +2290,9 @@ packages: strnum@2.1.2: resolution: {integrity: sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==} + strnum@2.2.3: + resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2171,6 +2407,7 @@ packages: uuid@10.0.0: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true uuid@11.1.0: @@ -2179,6 +2416,7 @@ packages: uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true visualogic@1.3.2: @@ -2403,6 +2641,49 @@ snapshots: transitivePeerDependencies: - aws-crt + '@aws-sdk/client-sso@3.1041.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.974.8 + '@aws-sdk/middleware-host-header': 3.972.10 + '@aws-sdk/middleware-logger': 3.972.10 + '@aws-sdk/middleware-recursion-detection': 3.972.11 + '@aws-sdk/middleware-user-agent': 3.972.38 + '@aws-sdk/region-config-resolver': 3.972.13 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/util-endpoints': 3.996.8 + '@aws-sdk/util-user-agent-browser': 3.972.10 + '@aws-sdk/util-user-agent-node': 3.973.24 + '@smithy/config-resolver': 4.4.17 + '@smithy/core': 3.23.17 + '@smithy/fetch-http-handler': 5.3.17 + '@smithy/hash-node': 4.2.14 + '@smithy/invalid-dependency': 4.2.14 + '@smithy/middleware-content-length': 4.2.14 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-retry': 4.5.7 + '@smithy/middleware-serde': 4.2.20 + '@smithy/middleware-stack': 4.2.14 + '@smithy/node-config-provider': 4.3.14 + '@smithy/node-http-handler': 4.6.1 + '@smithy/protocol-http': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.49 + '@smithy/util-defaults-mode-node': 4.2.54 + '@smithy/util-endpoints': 3.4.2 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.8 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + '@aws-sdk/client-sso@3.958.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 @@ -2462,6 +2743,23 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@aws-sdk/core@3.974.8': + dependencies: + '@aws-sdk/types': 3.973.8 + '@aws-sdk/xml-builder': 3.972.22 + '@smithy/core': 3.23.17 + '@smithy/node-config-provider': 4.3.14 + '@smithy/property-provider': 4.2.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/signature-v4': 5.3.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + '@smithy/util-base64': 4.3.2 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.8 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@aws-sdk/crc64-nvme@3.957.0': dependencies: '@smithy/types': 4.11.0 @@ -2612,6 +2910,13 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@aws-sdk/middleware-host-header@3.972.10': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@aws-sdk/middleware-location-constraint@3.957.0': dependencies: '@aws-sdk/types': 3.957.0 @@ -2624,6 +2929,12 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@aws-sdk/middleware-logger@3.972.10': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.957.0': dependencies: '@aws-sdk/types': 3.957.0 @@ -2632,6 +2943,14 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@aws-sdk/middleware-recursion-detection@3.972.11': + dependencies: + '@aws-sdk/types': 3.973.8 + '@aws/lambda-invoke-store': 0.2.2 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@aws-sdk/middleware-sdk-s3@3.957.0': dependencies: '@aws-sdk/core': 3.957.0 @@ -2665,6 +2984,17 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@aws-sdk/middleware-user-agent@3.972.38': + dependencies: + '@aws-sdk/core': 3.974.8 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/util-endpoints': 3.996.8 + '@smithy/core': 3.23.17 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-retry': 4.3.8 + tslib: 2.8.1 + '@aws-sdk/nested-clients@3.958.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 @@ -2716,6 +3046,14 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@aws-sdk/region-config-resolver@3.972.13': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/config-resolver': 4.4.17 + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@aws-sdk/signature-v4-multi-region@3.957.0': dependencies: '@aws-sdk/middleware-sdk-s3': 3.957.0 @@ -2742,6 +3080,11 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@aws-sdk/types@3.973.8': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@aws-sdk/util-arn-parser@3.957.0': dependencies: tslib: 2.8.1 @@ -2754,6 +3097,14 @@ snapshots: '@smithy/util-endpoints': 3.2.7 tslib: 2.8.1 + '@aws-sdk/util-endpoints@3.996.8': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 + '@smithy/util-endpoints': 3.4.2 + tslib: 2.8.1 + '@aws-sdk/util-locate-window@3.957.0': dependencies: tslib: 2.8.1 @@ -2765,6 +3116,13 @@ snapshots: bowser: 2.13.1 tslib: 2.8.1 + '@aws-sdk/util-user-agent-browser@3.972.10': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/types': 4.14.1 + bowser: 2.13.1 + tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.957.0': dependencies: '@aws-sdk/middleware-user-agent': 3.957.0 @@ -2773,12 +3131,28 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@aws-sdk/util-user-agent-node@3.973.24': + dependencies: + '@aws-sdk/middleware-user-agent': 3.972.38 + '@aws-sdk/types': 3.973.8 + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-config-provider': 4.2.2 + tslib: 2.8.1 + '@aws-sdk/xml-builder@3.957.0': dependencies: '@smithy/types': 4.11.0 fast-xml-parser: 5.2.5 tslib: 2.8.1 + '@aws-sdk/xml-builder@3.972.22': + dependencies: + '@nodable/entities': 2.1.0 + '@smithy/types': 4.14.1 + fast-xml-parser: 5.7.2 + tslib: 2.8.1 + '@aws/lambda-invoke-store@0.2.2': {} '@babel/runtime@7.28.4': {} @@ -3161,6 +3535,8 @@ snapshots: '@noble/curves': 2.0.1 '@noble/hashes': 2.0.1 + '@nodable/entities@2.1.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3290,6 +3666,15 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/config-resolver@4.4.17': + dependencies: + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-endpoints': 3.4.2 + '@smithy/util-middleware': 4.2.14 + tslib: 2.8.1 + '@smithy/config-resolver@4.4.5': dependencies: '@smithy/node-config-provider': 4.3.7 @@ -3312,6 +3697,27 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 + '@smithy/core@3.23.17': + dependencies: + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-stream': 4.5.25 + '@smithy/util-utf8': 4.2.2 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.2.14': + dependencies: + '@smithy/node-config-provider': 4.3.14 + '@smithy/property-provider': 4.2.14 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 + tslib: 2.8.1 + '@smithy/credential-provider-imds@4.2.7': dependencies: '@smithy/node-config-provider': 4.3.7 @@ -3350,6 +3756,14 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/fetch-http-handler@5.3.17': + dependencies: + '@smithy/protocol-http': 5.3.14 + '@smithy/querystring-builder': 4.2.14 + '@smithy/types': 4.14.1 + '@smithy/util-base64': 4.3.2 + tslib: 2.8.1 + '@smithy/fetch-http-handler@5.3.8': dependencies: '@smithy/protocol-http': 5.3.7 @@ -3365,6 +3779,13 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/hash-node@4.2.14': + dependencies: + '@smithy/types': 4.14.1 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/hash-node@4.2.7': dependencies: '@smithy/types': 4.11.0 @@ -3378,6 +3799,11 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@smithy/invalid-dependency@4.2.14': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/invalid-dependency@4.2.7': dependencies: '@smithy/types': 4.11.0 @@ -3391,12 +3817,22 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/is-array-buffer@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/md5-js@4.2.7': dependencies: '@smithy/types': 4.11.0 '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@smithy/middleware-content-length@4.2.14': + dependencies: + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/middleware-content-length@4.2.7': dependencies: '@smithy/protocol-http': 5.3.7 @@ -3414,6 +3850,17 @@ snapshots: '@smithy/util-middleware': 4.2.7 tslib: 2.8.1 + '@smithy/middleware-endpoint@4.4.32': + dependencies: + '@smithy/core': 3.23.17 + '@smithy/middleware-serde': 4.2.20 + '@smithy/node-config-provider': 4.3.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 + '@smithy/url-parser': 4.2.14 + '@smithy/util-middleware': 4.2.14 + tslib: 2.8.1 + '@smithy/middleware-retry@4.4.17': dependencies: '@smithy/node-config-provider': 4.3.7 @@ -3426,17 +3873,49 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 + '@smithy/middleware-retry@4.5.7': + dependencies: + '@smithy/core': 3.23.17 + '@smithy/node-config-provider': 4.3.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/service-error-classification': 4.3.1 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-retry': 4.3.8 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.2.20': + dependencies: + '@smithy/core': 3.23.17 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/middleware-serde@4.2.8': dependencies: '@smithy/protocol-http': 5.3.7 '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/middleware-stack@4.2.14': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/middleware-stack@4.2.7': dependencies: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/node-config-provider@4.3.14': + dependencies: + '@smithy/property-provider': 4.2.14 + '@smithy/shared-ini-file-loader': 4.4.9 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/node-config-provider@4.3.7': dependencies: '@smithy/property-provider': 4.2.7 @@ -3452,22 +3931,50 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/node-http-handler@4.6.1': + dependencies: + '@smithy/protocol-http': 5.3.14 + '@smithy/querystring-builder': 4.2.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + + '@smithy/property-provider@4.2.14': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/property-provider@4.2.7': dependencies: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/protocol-http@5.3.14': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/protocol-http@5.3.7': dependencies: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/querystring-builder@4.2.14': + dependencies: + '@smithy/types': 4.14.1 + '@smithy/util-uri-escape': 4.2.2 + tslib: 2.8.1 + '@smithy/querystring-builder@4.2.7': dependencies: '@smithy/types': 4.11.0 '@smithy/util-uri-escape': 4.2.0 tslib: 2.8.1 + '@smithy/querystring-parser@4.2.14': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/querystring-parser@4.2.7': dependencies: '@smithy/types': 4.11.0 @@ -3477,11 +3984,31 @@ snapshots: dependencies: '@smithy/types': 4.11.0 + '@smithy/service-error-classification@4.3.1': + dependencies: + '@smithy/types': 4.14.1 + '@smithy/shared-ini-file-loader@4.4.2': dependencies: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/shared-ini-file-loader@4.4.9': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + + '@smithy/signature-v4@5.3.14': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-middleware': 4.2.14 + '@smithy/util-uri-escape': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/signature-v4@5.3.7': dependencies: '@smithy/is-array-buffer': 4.2.0 @@ -3503,10 +4030,30 @@ snapshots: '@smithy/util-stream': 4.5.8 tslib: 2.8.1 + '@smithy/smithy-client@4.12.13': + dependencies: + '@smithy/core': 3.23.17 + '@smithy/middleware-endpoint': 4.4.32 + '@smithy/middleware-stack': 4.2.14 + '@smithy/protocol-http': 5.3.14 + '@smithy/types': 4.14.1 + '@smithy/util-stream': 4.5.25 + tslib: 2.8.1 + '@smithy/types@4.11.0': dependencies: tslib: 2.8.1 + '@smithy/types@4.14.1': + dependencies: + tslib: 2.8.1 + + '@smithy/url-parser@4.2.14': + dependencies: + '@smithy/querystring-parser': 4.2.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/url-parser@4.2.7': dependencies: '@smithy/querystring-parser': 4.2.7 @@ -3519,14 +4066,28 @@ snapshots: '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 + '@smithy/util-base64@4.3.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/util-body-length-browser@4.2.0': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-browser@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-body-length-node@4.2.1': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-node@4.2.3': + dependencies: + tslib: 2.8.1 + '@smithy/util-buffer-from@2.2.0': dependencies: '@smithy/is-array-buffer': 2.2.0 @@ -3537,10 +4098,19 @@ snapshots: '@smithy/is-array-buffer': 4.2.0 tslib: 2.8.1 + '@smithy/util-buffer-from@4.2.2': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + tslib: 2.8.1 + '@smithy/util-config-provider@4.2.0': dependencies: tslib: 2.8.1 + '@smithy/util-config-provider@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.16': dependencies: '@smithy/property-provider': 4.2.7 @@ -3548,6 +4118,13 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.49': + dependencies: + '@smithy/property-provider': 4.2.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.19': dependencies: '@smithy/config-resolver': 4.4.5 @@ -3558,16 +4135,41 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.54': + dependencies: + '@smithy/config-resolver': 4.4.17 + '@smithy/credential-provider-imds': 4.2.14 + '@smithy/node-config-provider': 4.3.14 + '@smithy/property-provider': 4.2.14 + '@smithy/smithy-client': 4.12.13 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/util-endpoints@3.2.7': dependencies: '@smithy/node-config-provider': 4.3.7 '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/util-endpoints@3.4.2': + dependencies: + '@smithy/node-config-provider': 4.3.14 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/util-hex-encoding@4.2.0': dependencies: tslib: 2.8.1 + '@smithy/util-hex-encoding@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-middleware@4.2.14': + dependencies: + '@smithy/types': 4.14.1 + tslib: 2.8.1 + '@smithy/util-middleware@4.2.7': dependencies: '@smithy/types': 4.11.0 @@ -3579,6 +4181,23 @@ snapshots: '@smithy/types': 4.11.0 tslib: 2.8.1 + '@smithy/util-retry@4.3.8': + dependencies: + '@smithy/service-error-classification': 4.3.1 + '@smithy/types': 4.14.1 + tslib: 2.8.1 + + '@smithy/util-stream@4.5.25': + dependencies: + '@smithy/fetch-http-handler': 5.3.17 + '@smithy/node-http-handler': 4.6.1 + '@smithy/types': 4.14.1 + '@smithy/util-base64': 4.3.2 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + '@smithy/util-stream@4.5.8': dependencies: '@smithy/fetch-http-handler': 5.3.8 @@ -3594,6 +4213,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/util-uri-escape@4.2.2': + dependencies: + tslib: 2.8.1 + '@smithy/util-utf8@2.3.0': dependencies: '@smithy/util-buffer-from': 2.2.0 @@ -3604,6 +4227,11 @@ snapshots: '@smithy/util-buffer-from': 4.2.0 tslib: 2.8.1 + '@smithy/util-utf8@4.2.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + tslib: 2.8.1 + '@smithy/util-waiter@4.2.7': dependencies: '@smithy/abort-controller': 4.2.7 @@ -3614,6 +4242,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/uuid@1.1.2': + dependencies: + tslib: 2.8.1 + '@tensorflow/tfjs-backend-cpu@4.22.0(@tensorflow/tfjs-core@4.22.0)': dependencies: '@tensorflow/tfjs-core': 4.22.0 @@ -4001,8 +4633,8 @@ snapshots: domain-objects: 0.31.3 helpful-errors: 1.5.3 joi: 17.4.0 - rhachet: 1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) - rhachet-roles-ehmpathy: 1.35.0(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + rhachet: 1.40.7(zod@4.3.4) + rhachet-roles-ehmpathy: 1.35.0(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet@1.40.7(zod@4.3.4)) type-fns: 1.21.0 uuid-fns: 1.1.3 transitivePeerDependencies: @@ -4099,10 +4731,21 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 + fast-xml-builder@1.1.9: + dependencies: + path-expression-matcher: 1.5.0 + fast-xml-parser@5.2.5: dependencies: strnum: 2.1.2 + fast-xml-parser@5.7.2: + dependencies: + '@nodable/entities': 2.1.0 + fast-xml-builder: 1.1.9 + path-expression-matcher: 1.5.0 + strnum: 2.2.3 + fastest-levenshtein@1.0.16: {} fastq@1.20.1: @@ -4460,6 +5103,8 @@ snapshots: path-exists@4.0.0: {} + path-expression-matcher@1.5.0: {} + path-key@3.1.1: {} path-scurry@1.11.1: @@ -4570,7 +5215,7 @@ snapshots: domain-objects: 0.31.9 helpful-errors: 1.5.3 - rhachet-brains-anthropic@0.4.0(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): + rhachet-brains-anthropic@0.4.1(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): dependencies: '@anthropic-ai/claude-agent-sdk': 0.1.76(zod@4.3.4) '@anthropic-ai/sdk': 0.71.2(zod@4.3.4) @@ -4578,19 +5223,33 @@ snapshots: helpful-errors: 1.5.3 iso-price: 1.1.1(domain-objects@0.31.9) iso-time: 1.11.1 - rhachet: 1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + rhachet: 1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + rhachet-artifact: 1.0.1 + rhachet-artifact-git: 1.1.5 + type-fns: 1.21.0 + zod: 4.3.4 + + rhachet-brains-xai@0.3.3(rhachet@1.40.7(zod@4.3.4)): + dependencies: + domain-objects: 0.31.9 + helpful-errors: 1.5.3 + iso-price: 1.1.1(domain-objects@0.31.9) + openai: 5.8.2(zod@4.3.4) + rhachet: 1.40.7(zod@4.3.4) rhachet-artifact: 1.0.1 rhachet-artifact-git: 1.1.5 type-fns: 1.21.0 zod: 4.3.4 + transitivePeerDependencies: + - ws - rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): + rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): dependencies: domain-objects: 0.31.9 helpful-errors: 1.5.3 iso-price: 1.1.1(domain-objects@0.31.9) openai: 5.8.2(zod@4.3.4) - rhachet: 1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + rhachet: 1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) rhachet-artifact: 1.0.1 rhachet-artifact-git: 1.1.5 type-fns: 1.21.0 @@ -4598,7 +5257,7 @@ snapshots: transitivePeerDependencies: - ws - rhachet-roles-bhrain@0.27.3(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4))): + rhachet-roles-bhrain@0.27.6(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4))): dependencies: '@ehmpathy/as-command': 1.0.3 '@ehmpathy/uni-time': 1.8.1 @@ -4615,7 +5274,7 @@ snapshots: openai: 5.8.2(zod@4.3.4) rhachet-artifact: 1.0.0 rhachet-artifact-git: 1.1.0 - rhachet-brains-xai: 0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + rhachet-brains-xai: 0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) serde-fns: 1.2.0 simple-in-memory-cache: 0.4.0 type-fns: 1.21.0 @@ -4630,14 +5289,14 @@ snapshots: - react-native-b4a - ws - rhachet-roles-bhuild@0.21.1(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))(rhachet-roles-bhrain@0.27.3(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))): + rhachet-roles-bhuild@0.21.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))(rhachet-roles-bhrain@0.27.6(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)))): dependencies: domain-objects: 0.31.9 emoji-space-shim: 0.0.0 helpful-errors: 1.7.3 iso-time: 1.11.3 - rhachet-brains-xai: 0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) - rhachet-roles-bhrain: 0.27.3(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4))) + rhachet-brains-xai: 0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + rhachet-roles-bhrain: 0.27.6(@types/node@25.3.0)(rhachet-brains-xai@0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4))) test-fns: 1.15.0(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) zod: 4.3.4 transitivePeerDependencies: @@ -4647,7 +5306,7 @@ snapshots: - aws-crt - ws - rhachet-roles-ehmpathy@1.35.0(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): + rhachet-roles-ehmpathy@1.35.0(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet@1.40.7(zod@4.3.4)): dependencies: '@atjsh/llmlingua-2': 2.0.3(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(js-tiktoken@1.0.21) '@ehmpathy/as-command': 1.0.3 @@ -4661,8 +5320,8 @@ snapshots: openai: 5.8.2(zod@4.3.4) rhachet-artifact: 1.0.0 rhachet-artifact-git: 1.1.0 - rhachet-brains-xai: 0.3.3(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) - rhachet-roles-rhachet: 0.1.7(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + rhachet-brains-xai: 0.3.3(rhachet@1.40.7(zod@4.3.4)) + rhachet-roles-rhachet: 0.1.7(rhachet@1.40.7(zod@4.3.4)) serde-fns: 1.2.0 simple-in-memory-cache: 0.4.0 simple-on-disk-cache: 1.7.3 @@ -4679,11 +5338,47 @@ snapshots: - rhachet - ws - rhachet-roles-rhachet@0.1.7(rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): + rhachet-roles-ehmpathy@1.35.5(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): dependencies: - rhachet: 1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + '@atjsh/llmlingua-2': 2.0.3(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(js-tiktoken@1.0.21) + '@ehmpathy/as-command': 1.0.3 + '@ehmpathy/uni-time': 1.8.1 + as-procedure: 1.1.7 + domain-objects: 0.31.9 + fast-glob: 3.3.3 + helpful-errors: 1.5.3 + inquirer: 12.7.0(@types/node@25.3.0) + js-tiktoken: 1.0.21 + openai: 5.8.2(zod@4.3.4) + rhachet-artifact: 1.0.0 + rhachet-artifact-git: 1.1.0 + rhachet-brains-xai: 0.3.3(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + rhachet-roles-rhachet: 0.1.7(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)) + serde-fns: 1.2.0 + simple-in-memory-cache: 0.4.0 + simple-on-disk-cache: 1.7.3 + type-fns: 1.21.0 + with-simple-cache: 0.15.3(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + with-simple-caching: 0.14.4 + wrapper-fns: 1.1.7 + zod: 4.3.4 + transitivePeerDependencies: + - '@huggingface/transformers' + - '@tensorflow/tfjs' + - '@types/node' + - aws-crt + - rhachet + - ws + + rhachet-roles-rhachet@0.1.7(rhachet@1.40.7(zod@4.3.4)): + dependencies: + rhachet: 1.40.7(zod@4.3.4) - rhachet@1.40.7(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4): + rhachet-roles-rhachet@0.1.7(rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4)): + dependencies: + rhachet: 1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + + rhachet@1.40.7(zod@4.3.4): dependencies: '@noble/curves': 2.0.1 '@noble/hashes': 2.0.1 @@ -4715,6 +5410,42 @@ snapshots: with-simple-cache: 0.15.3(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) yaml: 2.8.2 zod: 4.3.4 + transitivePeerDependencies: + - aws-crt + + rhachet@1.41.9(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4): + dependencies: + '@aws-sdk/client-sso': 3.1041.0 + '@noble/curves': 2.0.1 + '@noble/hashes': 2.0.1 + '@octokit/auth-app': 8.2.0 + '@scure/base': 2.0.0 + age-encryption: 0.3.0 + as-procedure: 1.1.11 + bottleneck: 2.19.5 + chalk: 4.1.2 + commander: 14.0.0 + domain-objects: 0.31.9 + emoji-space-shim: 0.1.3 + fast-glob: 3.3.3 + fastest-levenshtein: 1.0.16 + flattie: 1.1.1 + hash-fns: 1.1.0 + helpful-errors: 1.7.2 + iso-price: 1.1.1(domain-objects@0.31.9) + iso-time: 1.11.4 + js-tiktoken: 1.0.18 + picomatch: 4.0.4 + rhachet-artifact: 1.0.3 + rhachet-artifact-git: 1.1.5 + serde-fns: 1.3.1 + simple-in-memory-cache: 0.4.0 + simple-log-methods: 0.6.9 + type-fns: 1.21.0 + uuid-fns: 1.0.1 + with-simple-cache: 0.15.3(@huggingface/transformers@3.8.1)(@tensorflow/tfjs@4.22.0(seedrandom@3.0.5))(@types/node@25.3.0)(zod@4.3.4) + yaml: 2.8.2 + zod: 4.3.4 transitivePeerDependencies: - '@huggingface/transformers' - '@tensorflow/tfjs' @@ -4900,6 +5631,8 @@ snapshots: strnum@2.1.2: {} + strnum@2.2.3: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 diff --git a/src/bash_aliases.sh b/src/bash_aliases.sh index 6b41aab..549e2af 100644 --- a/src/bash_aliases.sh +++ b/src/bash_aliases.sh @@ -121,6 +121,224 @@ alias machine.usage.snapshot='machine_usage_snapshot' # c # note: 'terminal' command installed via install_env.sh (supports 'terminal /path/to/dir') +# terminal session management +# .what = snapshot and restore terminal windows across cosmic workspaces +# .why = recover exact terminal layout after restart/crash +_terminal_session_snapshot() { + local config_dir="$HOME/.config/terminal-sessions" + local snapshot_file="$config_dir/default.json" + mkdir -p "$config_dir" + + # check cos-cli available + if ! command -v cos-cli &>/dev/null; then + echo "error: cos-cli not installed. run: source ~/git/more/dev-env-setup/src/install_env.pt3.cosmic.sh && install_cos_cli" >&2 + return 1 + fi + + # get all windows from cosmic + local cos_info + cos_info=$(cos-cli info --json 2>/dev/null) + if [[ -z "$cos_info" ]]; then + echo "error: cos-cli info failed (is cosmic compositor active?)" >&2 + return 1 + fi + + # collect cwds from all shell processes with git repos + # simpler than a ptyxis process tree trace (flatpak sandbox complicates that) + local cwds_json="[]" + local all_cwds=() + + # find all interactive shell processes (bash, zsh, fish) + while IFS= read -r shell_pid; do + if [[ -d "/proc/$shell_pid" ]]; then + local cwd + cwd=$(readlink -f "/proc/$shell_pid/cwd" 2>/dev/null || true) + # only include if it's a valid directory that's a git repo + if [[ -n "$cwd" && -d "$cwd" ]]; then + # check if inside a git repo (has .git ancestor) + if git -C "$cwd" rev-parse --git-dir &>/dev/null; then + all_cwds+=("$cwd") + fi + fi + fi + done < <(pgrep -x "bash|zsh|fish" 2>/dev/null || true) + + # dedupe and convert to json array + if [[ ${#all_cwds[@]} -gt 0 ]]; then + cwds_json=$(printf '%s\n' "${all_cwds[@]}" | sort -u | jq -R -s 'split("\n") | map(select(length > 0))') + fi + + # filter to ptyxis windows and build snapshot + # cos-cli info structure: .apps[] has app_id, title, workspaces[].workspace + # match each window to a cwd based on repo name in title + local snapshot + snapshot=$(echo "$cos_info" | jq -c --argjson cwds "$cwds_json" ' + # helper: extract repo.worktree from title like "repo.worktree:branch" + def extract_repo: split(":")[0] | split(" ")[0] | gsub("[^a-zA-Z0-9._-]"; ""); + + # helper: find matching cwd for a repo name + def find_cwd(repo): + ($cwds | map(select(. | test("/" + repo + "$"))) | first) // null; + + { + version: 1, + timestamp: (now | todate), + windows: [ + .apps[] + | select(.app_id == "app.devsuite.Ptyxis") + | . as $app + | ($app.title | extract_repo) as $repo + | { + title: $app.title, + workspace: ($app.workspaces[0].workspace // "1"), + cwd: (if $repo != "" then find_cwd($repo) else null end) + } + ] + } + ') + + # validate snapshot has windows + local window_count + window_count=$(echo "$snapshot" | jq '.windows | length') + if [[ "$window_count" -eq 0 ]]; then + echo "no ptyxis windows found to snapshot" + return 0 + fi + + # write snapshot + echo "$snapshot" > "$snapshot_file" + local workspace_count + workspace_count=$(echo "$snapshot" | jq '[.windows[].workspace] | unique | length') + echo "snapshot saved: $window_count windows across $workspace_count workspaces" + echo " → $snapshot_file" +} + +_terminal_session_restore() { + local config_dir="$HOME/.config/terminal-sessions" + local snapshot_file="$config_dir/default.json" + local mode="plan" + local filter_ws="" + + # parse args + while [[ $# -gt 0 ]]; do + case "$1" in + --apply) mode="apply"; shift ;; + --workspace) filter_ws="$2"; shift 2 ;; + *) echo "error: unknown option: $1" >&2; return 1 ;; + esac + done + + # check snapshot exists + if [[ ! -f "$snapshot_file" ]]; then + echo "error: no snapshot found at $snapshot_file" >&2 + echo "run: terminal.snapshot" >&2 + return 1 + fi + + # check cos-cli available + if ! command -v cos-cli &>/dev/null; then + echo "error: cos-cli not installed. run: source ~/git/more/dev-env-setup/src/install_env.pt3.cosmic.sh && install_cos_cli" >&2 + return 1 + fi + + # read snapshot + local snapshot + snapshot=$(cat "$snapshot_file") + local timestamp + timestamp=$(echo "$snapshot" | jq -r '.timestamp') + + if [[ -n "$filter_ws" ]]; then + echo "restore workspace $filter_ws from $timestamp" + else + echo "restore terminal session from $timestamp" + fi + + # process windows, skip those without cwd + local restored_count=0 + local skipped_count=0 + local skipped_titles=() + local current_ws="" + + while IFS= read -r window_json; do + local title workspace cwd + title=$(echo "$window_json" | jq -r '.title') + workspace=$(echo "$window_json" | jq -r '.workspace') + cwd=$(echo "$window_json" | jq -r '.cwd // empty') + + # filter by workspace if specified + if [[ -n "$filter_ws" && "$workspace" != "$filter_ws" ]]; then + continue + fi + + # skip windows without cwd + if [[ -z "$cwd" || ! -d "$cwd" ]]; then + ((skipped_count++)) + # truncate title for display + local short_title="${title:0:50}" + [[ ${#title} -gt 50 ]] && short_title="${short_title}..." + skipped_titles+=("$short_title") + continue + fi + + # print workspace header when it changes + if [[ "$workspace" != "$current_ws" ]]; then + current_ws="$workspace" + echo " workspace $workspace:" + fi + + if [[ "$mode" == "plan" ]]; then + echo " - $cwd" + else + echo " + $cwd" + # get current max window index before spawn + local max_idx_before + max_idx_before=$(cos-cli info --json | jq '[.apps[].index] | max // -1') + + # spawn new window + flatpak run app.devsuite.Ptyxis --new-window --working-directory "$cwd" & + + # wait for new window to appear and get its index + local new_idx="" + local attempts=0 + while [[ -z "$new_idx" && $attempts -lt 30 ]]; do + sleep 0.1 + new_idx=$(cos-cli info --json | jq --argjson prev "$max_idx_before" '[.apps[] | select(.app_id == "app.devsuite.Ptyxis" and .index > $prev)] | .[0].index // empty') + ((attempts++)) + done + + # move by specific index (not app-id which moves ALL) + if [[ -n "$new_idx" ]]; then + local target_ws=$((workspace - 1)) + cos-cli move --index "$new_idx" --workspace "$target_ws" 2>/dev/null || true + fi + fi + ((restored_count++)) + done < <(echo "$snapshot" | jq -c '.windows[] | select(.title != "")' | sort -t'"' -k4,4n) + + # summary + echo "" + local ws_flag="" + [[ -n "$filter_ws" ]] && ws_flag=" --workspace $filter_ws" + if [[ "$mode" == "plan" ]]; then + echo "plan: $restored_count windows would be restored" + [[ $restored_count -gt 0 ]] && echo "run: terminal.restore${ws_flag} --apply" + else + echo "done: $restored_count windows restored" + fi + + # warn about skipped windows + if [[ $skipped_count -gt 0 ]]; then + echo "" + echo "warning: $skipped_count windows skipped (no cwd):" + for t in "${skipped_titles[@]}"; do + echo " ⚠ $t" + done + fi +} + +alias terminal.snapshot='_terminal_session_snapshot' +alias terminal.restore='_terminal_session_restore' + # make it easier to open the file manager alias files='nautilus & disown' diff --git a/src/install_env.pt3.cosmic.sh b/src/install_env.pt3.cosmic.sh index b39ee28..1bf44da 100644 --- a/src/install_env.pt3.cosmic.sh +++ b/src/install_env.pt3.cosmic.sh @@ -2,6 +2,7 @@ ###################################################################### # pt3: cosmic desktop # cosmic-term, cosmic theme, cosmic desktop (keybinds, panels, dock) +# cos-cli (wayland window/workspace management) ###################################################################### upgrade_cosmic_term() { @@ -118,3 +119,60 @@ Some(([ WINGS echo "• top panel: status area left, controls right" } + +install_cos_cli() { + # .what = install cos-cli for cosmic window/workspace management + # .why = enables terminal.snapshot/restore to place windows on workspaces + # ref: https://github.com/estin/cos-cli + if command -v cos-cli &>/dev/null; then + echo "• cos-cli already installed; skipped" + return 0 + fi + cargo install --git https://github.com/estin/cos-cli + echo "• cos-cli installed" +} + +install_terminal_session_timer() { + # .what = install systemd user timer for auto-snapshot every 5 min + # .why = ensures terminal layout is captured before crash/restart + local src_dir="$HOME/git/more/dev-env-setup/src" + local user_units="$HOME/.config/systemd/user" + mkdir -p "$user_units" + + cp "$src_dir/terminal-session-snapshot.service" "$user_units/" + cp "$src_dir/terminal-session-snapshot.timer" "$user_units/" + + systemctl --user daemon-reload + systemctl --user enable --now terminal-session-snapshot.timer + + echo "• terminal session auto-snapshot enabled (every 5 min)" + echo " check status: systemctl --user status terminal-session-snapshot.timer" +} + +configure_terminal_session_logout_hook() { + # .what = snapshot terminal session before logout/shutdown + # .why = capture final state before controlled exit + local hook_dir="$HOME/.config/systemd/user" + mkdir -p "$hook_dir" + + # create service that runs on session stop + cat > "$hook_dir/terminal-session-snapshot-on-exit.service" << 'EOF' +[Unit] +Description=Snapshot terminal session before logout +DefaultDependencies=no +Before=shutdown.target reboot.target halt.target + +[Service] +Type=oneshot +Environment=DISPLAY=:0 +ExecStart=/bin/bash -c 'source ~/.bash_aliases && _terminal_session_snapshot' + +[Install] +WantedBy=shutdown.target reboot.target halt.target +EOF + + systemctl --user daemon-reload + systemctl --user enable terminal-session-snapshot-on-exit.service + + echo "• terminal session logout hook enabled" +} diff --git a/src/terminal-session-snapshot.service b/src/terminal-session-snapshot.service new file mode 100644 index 0000000..b44553b --- /dev/null +++ b/src/terminal-session-snapshot.service @@ -0,0 +1,8 @@ +[Unit] +Description=Snapshot terminal session (ptyxis windows across cosmic workspaces) +After=graphical-session.target + +[Service] +Type=oneshot +Environment=DISPLAY=:0 +ExecStart=/bin/bash -c 'source ~/.bash_aliases && _terminal_session_snapshot' diff --git a/src/terminal-session-snapshot.timer b/src/terminal-session-snapshot.timer new file mode 100644 index 0000000..27debe8 --- /dev/null +++ b/src/terminal-session-snapshot.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Auto-snapshot terminal session every 5 minutes + +[Timer] +OnBootSec=5min +OnUnitActiveSec=5min +Persistent=true + +[Install] +WantedBy=timers.target