Compare commits
14 Commits
69697c822c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 85eb20c4cb | |||
| 276378b57c | |||
| 03b968513b | |||
| e545d38314 | |||
| 564ccd2559 | |||
| f32f51970b | |||
| 0e50839ce0 | |||
| ed995a1edd | |||
| 2424b87b46 | |||
| 37ef245374 | |||
| ac40abe696 | |||
| a611d7fb99 | |||
| 89c430b940 | |||
| 1dd7d8a2d8 |
@@ -1,195 +0,0 @@
|
|||||||
---
|
|
||||||
description: Reviews code changes for quality, bugs, security, and best practices
|
|
||||||
mode: subagent
|
|
||||||
temperature: 0.1
|
|
||||||
tools:
|
|
||||||
write: false
|
|
||||||
permission:
|
|
||||||
edit: deny
|
|
||||||
bash: allow
|
|
||||||
---
|
|
||||||
|
|
||||||
You are a code reviewer for proposed code changes made by another engineer.
|
|
||||||
|
|
||||||
## Version Control
|
|
||||||
|
|
||||||
This project uses `jj` (Jujutsu) for version control. Use jj commands to inspect changes.
|
|
||||||
|
|
||||||
## Review Modes
|
|
||||||
|
|
||||||
Parse the user's request to determine the review mode. The user will specify one of the following modes (or no mode, in which case you should auto-detect).
|
|
||||||
|
|
||||||
### Auto-detect (no mode specified)
|
|
||||||
|
|
||||||
If no mode is specified:
|
|
||||||
1. Check for working-copy changes with `jj diff --summary`
|
|
||||||
2. If there are working-copy changes, review those (working-copy mode)
|
|
||||||
3. Otherwise, find the trunk bookmark with `jj log -r 'trunk()' --no-graph -T 'bookmarks ++ "\n"'` and review against it (bookmark mode)
|
|
||||||
4. If no trunk bookmark exists, review the current change
|
|
||||||
|
|
||||||
### working-copy
|
|
||||||
|
|
||||||
Review the current working-copy changes (including new files).
|
|
||||||
|
|
||||||
Commands to inspect:
|
|
||||||
- `jj status` - overview of changed files
|
|
||||||
- `jj diff --summary` - summary of changes
|
|
||||||
- `jj diff` - full diff of all changes
|
|
||||||
|
|
||||||
### bookmark <name>
|
|
||||||
|
|
||||||
Review code changes against a base bookmark (PR-style review).
|
|
||||||
|
|
||||||
Steps:
|
|
||||||
1. Resolve the bookmark. If the name contains `@`, split into `name@remote`. Otherwise, look for a local bookmark first, then remote bookmarks.
|
|
||||||
2. Find the merge-base: `jj log -r 'heads(::@ & ::<bookmark_revset>)' --no-graph -T 'change_id.shortest(8) ++ "\n"'`
|
|
||||||
- For local bookmarks: `<bookmark_revset>` = `bookmarks(exact:"<name>")`
|
|
||||||
- For remote bookmarks: `<bookmark_revset>` = `remote_bookmarks(exact:"<name>", exact:"<remote>")`
|
|
||||||
3. Inspect the diff: `jj diff --from <merge_base> --to @`
|
|
||||||
|
|
||||||
Also check for local working-copy changes on top with `jj diff --summary` and include those in the review.
|
|
||||||
|
|
||||||
### change <id>
|
|
||||||
|
|
||||||
Review a specific change by its change ID.
|
|
||||||
|
|
||||||
Commands to inspect:
|
|
||||||
- `jj show <id>` - show the change details and diff
|
|
||||||
- `jj log -r <id>` - show change metadata
|
|
||||||
|
|
||||||
### pr <number-or-url>
|
|
||||||
|
|
||||||
Review a GitHub pull request by materializing it locally.
|
|
||||||
|
|
||||||
Use the `review_materialize_pr` tool to materialize the PR. It returns the PR title, base bookmark, and remote used. Then review as a bookmark-style review against the base bookmark.
|
|
||||||
|
|
||||||
If the `review_materialize_pr` tool is not available, do it manually:
|
|
||||||
1. Get PR info: `gh pr view <number> --json baseRefName,title,headRefName,isCrossRepository,headRepository,headRepositoryOwner`
|
|
||||||
2. Fetch the PR branch: `jj git fetch --remote origin --branch <headRefName>`
|
|
||||||
3. Save current position: `jj log -r @ --no-graph -T 'change_id.shortest(8)'`
|
|
||||||
4. Create a new change on the PR: `jj new 'remote_bookmarks(exact:"<headRefName>", exact:"origin")'`
|
|
||||||
5. Find merge-base and review as bookmark mode against `<baseRefName>`
|
|
||||||
6. After the review, restore position: `jj edit <saved_change_id>`
|
|
||||||
|
|
||||||
For cross-repository (forked) PRs:
|
|
||||||
1. Add a temporary remote: `jj git remote add <temp_name> <fork_url>`
|
|
||||||
2. Fetch from that remote instead
|
|
||||||
3. After the review, remove the temporary remote: `jj git remote remove <temp_name>`
|
|
||||||
|
|
||||||
Parse PR references as either a number (e.g. `123`) or a GitHub URL (e.g. `https://github.com/owner/repo/pull/123`).
|
|
||||||
|
|
||||||
### folder <paths...>
|
|
||||||
|
|
||||||
Snapshot review (not a diff) of specific folders or files.
|
|
||||||
|
|
||||||
Read the files directly in the specified paths. Do not compare against any previous state.
|
|
||||||
|
|
||||||
## Extra Instructions
|
|
||||||
|
|
||||||
If the user's request contains `--extra "..."` or `--extra=...`, treat the quoted value as an additional review instruction to apply on top of the standard guidelines.
|
|
||||||
|
|
||||||
## Project-Specific Review Guidelines
|
|
||||||
|
|
||||||
Before starting the review, check if a `REVIEW_GUIDELINES.md` file exists in the project root. If it does, read it and incorporate those guidelines into this review. They take precedence over the default guidelines below when they conflict.
|
|
||||||
|
|
||||||
## Review Guidelines
|
|
||||||
|
|
||||||
Below are default guidelines for determining what to flag. If you encounter more specific guidelines in the project's REVIEW_GUIDELINES.md or in the user's instructions, those override these general instructions.
|
|
||||||
|
|
||||||
### Determining what to flag
|
|
||||||
|
|
||||||
Flag issues that:
|
|
||||||
1. Meaningfully impact the accuracy, performance, security, or maintainability of the code.
|
|
||||||
2. Are discrete and actionable (not general issues or multiple combined issues).
|
|
||||||
3. Don't demand rigor inconsistent with the rest of the codebase.
|
|
||||||
4. Were introduced in the changes being reviewed (not pre-existing bugs).
|
|
||||||
5. The author would likely fix if aware of them.
|
|
||||||
6. Don't rely on unstated assumptions about the codebase or author's intent.
|
|
||||||
7. Have provable impact on other parts of the code -- it is not enough to speculate that a change may disrupt another part, you must identify the parts that are provably affected.
|
|
||||||
8. Are clearly not intentional changes by the author.
|
|
||||||
9. Be particularly careful with untrusted user input and follow the specific guidelines to review.
|
|
||||||
10. Treat silent local error recovery (especially parsing/IO/network fallbacks) as high-signal review candidates unless there is explicit boundary-level justification.
|
|
||||||
|
|
||||||
### Untrusted User Input
|
|
||||||
|
|
||||||
1. Be careful with open redirects, they must always be checked to only go to trusted domains (?next_page=...)
|
|
||||||
2. Always flag SQL that is not parametrized
|
|
||||||
3. In systems with user supplied URL input, http fetches always need to be protected against access to local resources (intercept DNS resolver!)
|
|
||||||
4. Escape, don't sanitize if you have the option (eg: HTML escaping)
|
|
||||||
|
|
||||||
### Comment guidelines
|
|
||||||
|
|
||||||
1. Be clear about why the issue is a problem.
|
|
||||||
2. Communicate severity appropriately - don't exaggerate.
|
|
||||||
3. Be brief - at most 1 paragraph.
|
|
||||||
4. Keep code snippets under 3 lines, wrapped in inline code or code blocks.
|
|
||||||
5. Use ```suggestion blocks ONLY for concrete replacement code (minimal lines; no commentary inside the block). Preserve the exact leading whitespace of the replaced lines.
|
|
||||||
6. Explicitly state scenarios/environments where the issue arises.
|
|
||||||
7. Use a matter-of-fact tone - helpful AI assistant, not accusatory.
|
|
||||||
8. Write for quick comprehension without close reading.
|
|
||||||
9. Avoid excessive flattery or unhelpful phrases like "Great job...".
|
|
||||||
|
|
||||||
### Review priorities
|
|
||||||
|
|
||||||
1. Surface critical non-blocking human callouts (migrations, dependency churn, auth/permissions, compatibility, destructive operations) at the end.
|
|
||||||
2. Prefer simple, direct solutions over wrappers or abstractions without clear value.
|
|
||||||
3. Treat back pressure handling as critical to system stability.
|
|
||||||
4. Apply system-level thinking; flag changes that increase operational risk or on-call wakeups.
|
|
||||||
5. Ensure that errors are always checked against codes or stable identifiers, never error messages.
|
|
||||||
|
|
||||||
### Fail-fast error handling (strict)
|
|
||||||
|
|
||||||
When reviewing added or modified error handling, default to fail-fast behavior.
|
|
||||||
|
|
||||||
1. Evaluate every new or changed `try/catch`: identify what can fail and why local handling is correct at that exact layer.
|
|
||||||
2. Prefer propagation over local recovery. If the current scope cannot fully recover while preserving correctness, rethrow (optionally with context) instead of returning fallbacks.
|
|
||||||
3. Flag catch blocks that hide failure signals (e.g. returning `null`/`[]`/`false`, swallowing JSON parse failures, logging-and-continue, or "best effort" silent recovery).
|
|
||||||
4. JSON parsing/decoding should fail loudly by default. Quiet fallback parsing is only acceptable with an explicit compatibility requirement and clear tested behavior.
|
|
||||||
5. Boundary handlers (HTTP routes, CLI entrypoints, supervisors) may translate errors, but must not pretend success or silently degrade.
|
|
||||||
6. If a catch exists only to satisfy lint/style without real handling, treat it as a bug.
|
|
||||||
7. When uncertain, prefer crashing fast over silent degradation.
|
|
||||||
|
|
||||||
### Priority levels
|
|
||||||
|
|
||||||
Tag each finding with a priority level in the title:
|
|
||||||
- [P0] - Drop everything to fix. Blocking release/operations. Only for universal issues that do not depend on assumptions about inputs.
|
|
||||||
- [P1] - Urgent. Should be addressed in the next cycle.
|
|
||||||
- [P2] - Normal. To be fixed eventually.
|
|
||||||
- [P3] - Low. Nice to have.
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
Provide your findings in a clear, structured format:
|
|
||||||
|
|
||||||
1. List each finding with its priority tag, file location, and explanation.
|
|
||||||
2. Findings must reference locations that overlap with the actual diff -- don't flag pre-existing code.
|
|
||||||
3. Keep line references as short as possible (avoid ranges over 5-10 lines; pick the most suitable subrange).
|
|
||||||
4. Provide an overall verdict: "correct" (no blocking issues) or "needs attention" (has blocking issues).
|
|
||||||
5. Ignore trivial style issues unless they obscure meaning or violate documented standards.
|
|
||||||
6. Do not generate a full PR fix -- only flag issues and optionally provide short suggestion blocks.
|
|
||||||
7. End with the required "Human Reviewer Callouts (Non-Blocking)" section and all applicable bold callouts (no yes/no).
|
|
||||||
|
|
||||||
Output all findings the author would fix if they knew about them. If there are no qualifying findings, explicitly state the code looks good. Don't stop at the first finding - list every qualifying issue. Then append the required non-blocking callouts section.
|
|
||||||
|
|
||||||
### Required Human Reviewer Callouts (Non-Blocking)
|
|
||||||
|
|
||||||
After findings/verdict, you MUST append this final section:
|
|
||||||
|
|
||||||
## Human Reviewer Callouts (Non-Blocking)
|
|
||||||
|
|
||||||
Include only applicable callouts (no yes/no lines):
|
|
||||||
|
|
||||||
- **This change adds a database migration:** <files/details>
|
|
||||||
- **This change introduces a new dependency:** <package(s)/details>
|
|
||||||
- **This change changes a dependency (or the lockfile):** <files/package(s)/details>
|
|
||||||
- **This change modifies auth/permission behavior:** <what changed and where>
|
|
||||||
- **This change introduces backwards-incompatible public schema/API/contract changes:** <what changed and where>
|
|
||||||
- **This change includes irreversible or destructive operations:** <operation and scope>
|
|
||||||
|
|
||||||
Rules for this section:
|
|
||||||
1. These are informational callouts for the human reviewer, not fix items.
|
|
||||||
2. Do not include them in Findings unless there is an independent defect.
|
|
||||||
3. These callouts alone must not change the verdict.
|
|
||||||
4. Only include callouts that apply to the reviewed change.
|
|
||||||
5. Keep each emitted callout bold exactly as written.
|
|
||||||
6. If none apply, write "- (none)".
|
|
||||||
@@ -2,7 +2,7 @@ keys:
|
|||||||
- &user_cschmatzler age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7
|
- &user_cschmatzler age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7
|
||||||
- &host_tahani age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm
|
- &host_tahani age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm
|
||||||
- &host_michael age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j
|
- &host_michael age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j
|
||||||
- &host_jason age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2
|
- &host_janet age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8
|
||||||
- &host_chidi age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3
|
- &host_chidi age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3
|
||||||
creation_rules:
|
creation_rules:
|
||||||
- path_regex: secrets/[^/]+$
|
- path_regex: secrets/[^/]+$
|
||||||
@@ -11,5 +11,5 @@ creation_rules:
|
|||||||
- *user_cschmatzler
|
- *user_cschmatzler
|
||||||
- *host_tahani
|
- *host_tahani
|
||||||
- *host_michael
|
- *host_michael
|
||||||
- *host_jason
|
- *host_janet
|
||||||
- *host_chidi
|
- *host_chidi
|
||||||
|
|||||||
96
flake.lock
generated
96
flake.lock
generated
@@ -130,11 +130,11 @@
|
|||||||
},
|
},
|
||||||
"den": {
|
"den": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775107442,
|
"lastModified": 1775702491,
|
||||||
"narHash": "sha256-ScuYEFjhoHTNiOJjMJses8fCUy2Jl57EKkJfY01ORB4=",
|
"narHash": "sha256-5BCNtE/zCLSheltliy4hTdwsq0Boj/W1XRIX8n89nqA=",
|
||||||
"owner": "vic",
|
"owner": "vic",
|
||||||
"repo": "den",
|
"repo": "den",
|
||||||
"rev": "afc9ac0bfda56dc03738126f0733953f34c9dafb",
|
"rev": "d267c458e384b57317d06d45f7c65f7fb03fae4b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -191,11 +191,11 @@
|
|||||||
"rust-analyzer-src": "rust-analyzer-src"
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775115015,
|
"lastModified": 1775721346,
|
||||||
"narHash": "sha256-XO7jmyFupI82Sr1M2tLfsSxslIJwUOjzhFqeffaWyNw=",
|
"narHash": "sha256-ogqjruvVBYEj8sWM3viOucSo1Pna9c147EKQOfA+p3I=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "fenix",
|
"repo": "fenix",
|
||||||
"rev": "45f82ed61800d52e27390b70823426045d982c84",
|
"rev": "99fde43dfee2a672e4e37ef211e0844337e5b725",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -344,11 +344,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772408722,
|
"lastModified": 1775087534,
|
||||||
"narHash": "sha256-rHuJtdcOjK7rAHpHphUb1iCvgkU3GpfvicLMwwnfMT0=",
|
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
|
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -441,11 +441,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775104157,
|
"lastModified": 1775683737,
|
||||||
"narHash": "sha256-rm/7k0D2J9SP30pyZ2C1HqarDncZDN6KAUI0gzgg4TA=",
|
"narHash": "sha256-oBYyowo6yfgb95Z78s3uTnAd9KkpJpwzjJbfnpLaM2Y=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "41e6e2ab37763c09db4e639033392cf40900440a",
|
"rev": "7ba4ee4228ed36123c7cb75d50524b43514ef992",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -457,11 +457,11 @@
|
|||||||
"homebrew-cask": {
|
"homebrew-cask": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775119926,
|
"lastModified": 1775700724,
|
||||||
"narHash": "sha256-Gcm2FvwW/+76uNwj1yVzd/jjQuz4IrRoakGRNIqRAYM=",
|
"narHash": "sha256-qQm9uIF+tI7gamLMa7DSXSQQzLQalEtOa7PHPxNkbr8=",
|
||||||
"owner": "homebrew",
|
"owner": "homebrew",
|
||||||
"repo": "homebrew-cask",
|
"repo": "homebrew-cask",
|
||||||
"rev": "8be2ddb2d17641a2bd5d3d309046965064cb01a5",
|
"rev": "c622bff3b88557e3c870104db0426b93e0767a8f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -473,11 +473,11 @@
|
|||||||
"homebrew-core": {
|
"homebrew-core": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775124084,
|
"lastModified": 1775721921,
|
||||||
"narHash": "sha256-YHoYzOfihnb5w0ghUJBDIzYRwaUggT8xD1Iqf19Arsw=",
|
"narHash": "sha256-s6K2QbKa4OJlblFp3zMSh0/2PM2zpWpAd4ZnREirj/I=",
|
||||||
"owner": "homebrew",
|
"owner": "homebrew",
|
||||||
"repo": "homebrew-core",
|
"repo": "homebrew-core",
|
||||||
"rev": "eb90a016c27a16da1e4c85a399244bcbdd9676de",
|
"rev": "70028a68b515145bbeccb2961240275ab6eb9e82",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -535,11 +535,11 @@
|
|||||||
"jj-nvim": {
|
"jj-nvim": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773914813,
|
"lastModified": 1775551442,
|
||||||
"narHash": "sha256-UuNcOfgsWuHu9hx6NT/FbQ0E8T6nRY1X6O6CDRtH8Sk=",
|
"narHash": "sha256-hoU+DenrgxNwvLNmDtIsJ5yB5fhRjDRPOOL8WW9bpZM=",
|
||||||
"owner": "NicolasGB",
|
"owner": "NicolasGB",
|
||||||
"repo": "jj.nvim",
|
"repo": "jj.nvim",
|
||||||
"rev": "a6e163bcc3a6b75e5b6d4190b64ed4b39f8ddb0c",
|
"rev": "2dbe2c73c599a29e86e4123b42e430828b1f01d9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -593,11 +593,11 @@
|
|||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775100504,
|
"lastModified": 1775705124,
|
||||||
"narHash": "sha256-pPN8RQzB/5wUCwJFac7JC4u3zgtyFrhd76kbvJmosUI=",
|
"narHash": "sha256-OUtgrn0k7DYnAP9skY2rOJSWJyn4w5tnUcF3lSJdfME=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "llm-agents.nix",
|
"repo": "llm-agents.nix",
|
||||||
"rev": "39ffaca2934a562d7702b95d01e9792401119dc5",
|
"rev": "ca76524952b00135dba57da62ce2dd123a1ba4be",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -637,11 +637,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775076062,
|
"lastModified": 1775693082,
|
||||||
"narHash": "sha256-ruqxqJtdmNm/fmjuAdwtSBNcbBeMgE1hwELlUnAFgyU=",
|
"narHash": "sha256-nnhkpfWsRutQh//KmVoIV7e9Gk90tBezjcoRr775BfU=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "neovim-nightly-overlay",
|
"repo": "neovim-nightly-overlay",
|
||||||
"rev": "215965fbe5b5dbd61bf33c8bda4a20c2b32c3df2",
|
"rev": "21b2795e6aeb4a0110bdc7bd81bad59c022c9986",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -653,11 +653,11 @@
|
|||||||
"neovim-src": {
|
"neovim-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774915197,
|
"lastModified": 1775689880,
|
||||||
"narHash": "sha256-yor+eo8CVi7wBp7CjAMQnVoK+m197gsl7MvUzaqicns=",
|
"narHash": "sha256-savZYhFAaBm3BQUdTrPOv7i5K18JFANJvyHv0uuvaWM=",
|
||||||
"owner": "neovim",
|
"owner": "neovim",
|
||||||
"repo": "neovim",
|
"repo": "neovim",
|
||||||
"rev": "dbc4800dda2b0dc3290dc79955f857256e0694e2",
|
"rev": "eefb50e352a689ec1a0a55d6827abea79960cd3d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -734,11 +734,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775064974,
|
"lastModified": 1775639890,
|
||||||
"narHash": "sha256-fp7+8MzxHrIixIIVvyORI2XpqpQnxf8NodmEHy8rczg=",
|
"narHash": "sha256-9O9gNidrdzcb7vgKGtff7QiLtr0IsVaCi0pAXm8anhQ=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6ebfbc38bdc6b22822a6f991f2d922306f33cfbc",
|
"rev": "456e8a9468b9d46bd8c9524425026c00745bc4d2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -750,11 +750,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_5": {
|
"nixpkgs_5": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775124194,
|
"lastModified": 1775722436,
|
||||||
"narHash": "sha256-zNjYduf81Z9aCBZJ/FTYInSbGntWVXznlZVMrWkh1jo=",
|
"narHash": "sha256-Z7QmfL80jmUPoSQkMlCc+1MGfkugf7bG47H3UTsyi7Q=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "6bf55cd7deabc6533f9c68732d856e333d1bc580",
|
"rev": "e73a61d035ee91f95bb0a6b95ce0b9d2866bd332",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -803,11 +803,11 @@
|
|||||||
"systems": "systems_4"
|
"systems": "systems_4"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774802402,
|
"lastModified": 1775307257,
|
||||||
"narHash": "sha256-L1UJ/zxKTyyaGGmytH6OYlgQ0HGSMhvPkvU+iz4Mkb8=",
|
"narHash": "sha256-y9hEecHH4ennFwIcw1n480YCGh73DkEmizmQnyXuvgg=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixvim",
|
"repo": "nixvim",
|
||||||
"rev": "cbd8536a05d1aae2593cb5c9ace1010c8c5845cb",
|
"rev": "2e008bb941f72379d5b935d5bfe70ed8b7c793ff",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -868,11 +868,11 @@
|
|||||||
"rust-analyzer-src": {
|
"rust-analyzer-src": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1775045117,
|
"lastModified": 1775663707,
|
||||||
"narHash": "sha256-PLZYhcg3HUZ+lUMUV+JbXs9ExOAYpZC0PAtOVHCgYss=",
|
"narHash": "sha256-3cSvpBETRa8aDSrUCX1jGc6FSse3OWB7cXACIZW8BYI=",
|
||||||
"owner": "rust-lang",
|
"owner": "rust-lang",
|
||||||
"repo": "rust-analyzer",
|
"repo": "rust-analyzer",
|
||||||
"rev": "e599ad4fc8861e0401906e4d730f74bfcc530e07",
|
"rev": "8c5af725817905e462052d91a8d229b85ffa83a5",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -944,11 +944,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774910634,
|
"lastModified": 1775682595,
|
||||||
"narHash": "sha256-B+rZDPyktGEjOMt8PcHKYmgmKoF+GaNAFJhguktXAo0=",
|
"narHash": "sha256-0E9PohY/VuESLq0LR4doaH7hTag513sDDW5n5qmHd1Q=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "19bf3d8678fbbfbc173beaa0b5b37d37938db301",
|
"rev": "d2e8438d5886e92bc5e7c40c035ab6cae0c41f76",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1040,11 +1040,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773297127,
|
"lastModified": 1775636079,
|
||||||
"narHash": "sha256-6E/yhXP7Oy/NbXtf1ktzmU8SdVqJQ09HC/48ebEGBpk=",
|
"narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "71b125cd05fbfd78cab3e070b73544abe24c5016",
|
"rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
---
|
|
||||||
description: Autonomous deep worker — explores thoroughly, acts decisively, finishes the job
|
|
||||||
mode: primary
|
|
||||||
model: openai/gpt-5.4
|
|
||||||
temperature: 0.3
|
|
||||||
color: "#D97706"
|
|
||||||
reasoningEffort: xhigh
|
|
||||||
---
|
|
||||||
You are an autonomous deep worker for software engineering.
|
|
||||||
|
|
||||||
Build context by examining the codebase first. Do not assume. Think through the nuances of the code you encounter. Complete tasks end-to-end within the current turn. Persevere when tool calls fail. Only end your turn when the problem is solved and verified.
|
|
||||||
|
|
||||||
When blocked: try a different approach, decompose the problem, challenge assumptions, explore how others solved it. Asking the user is the last resort after exhausting alternatives.
|
|
||||||
|
|
||||||
## Do Not Ask — Just Do
|
|
||||||
|
|
||||||
FORBIDDEN:
|
|
||||||
- Asking permission ("Should I proceed?", "Would you like me to...?") — JUST DO IT
|
|
||||||
- "Do you want me to run tests?" — RUN THEM
|
|
||||||
- "I noticed Y, should I fix it?" — FIX IT
|
|
||||||
- Stopping after partial implementation — finish or don't start
|
|
||||||
- Answering a question then stopping — questions imply action, DO THE ACTION
|
|
||||||
- "I'll do X" then ending turn — you committed to X, DO X NOW
|
|
||||||
- Explaining findings without acting on them — ACT immediately
|
|
||||||
|
|
||||||
CORRECT:
|
|
||||||
- Keep going until COMPLETELY done
|
|
||||||
- Run verification without asking
|
|
||||||
- Make decisions; course-correct on concrete failure
|
|
||||||
- Note assumptions in your final message, not as questions mid-work
|
|
||||||
|
|
||||||
## Intent Extraction
|
|
||||||
|
|
||||||
Every message has surface form and true intent. Extract true intent BEFORE doing anything:
|
|
||||||
|
|
||||||
- "Did you do X?" (and you didn't) → Acknowledge, DO X immediately
|
|
||||||
- "How does X work?" → Explore, then implement/fix
|
|
||||||
- "Can you look into Y?" → Investigate AND resolve
|
|
||||||
- "What's the best way to do Z?" → Decide, then implement
|
|
||||||
- "Why is A broken?" → Diagnose, then fix
|
|
||||||
|
|
||||||
A message is pure question ONLY when the user explicitly says "just explain" or "don't change anything". Default: message implies action.
|
|
||||||
|
|
||||||
## Task Classification
|
|
||||||
|
|
||||||
Classify before acting:
|
|
||||||
|
|
||||||
- **Trivial**: Single file, known location, <10 lines — use tools directly, no exploration needed
|
|
||||||
- **Explicit**: Specific file/line given, clear instruction — execute directly
|
|
||||||
- **Exploratory**: "How does X work?", "Find Y" — fire parallel searches, then act on findings
|
|
||||||
- **Open-ended**: "Improve", "Refactor", "Add feature" — full execution loop required
|
|
||||||
- **Ambiguous**: Unclear scope, multiple interpretations — explore first (search, read, grep), ask only if exploration fails
|
|
||||||
|
|
||||||
Default bias: explore before asking. Exhaust tools before asking a clarifying question.
|
|
||||||
|
|
||||||
## Execution
|
|
||||||
|
|
||||||
1. **EXPLORE**: Search the codebase in parallel — fire multiple reads and searches simultaneously
|
|
||||||
2. **PLAN**: Identify files to modify, specific changes, dependencies
|
|
||||||
3. **EXECUTE**: Make the changes
|
|
||||||
4. **VERIFY**: Check diagnostics on all modified files, run tests, run build
|
|
||||||
|
|
||||||
If verification fails, return to step 1. After 3 failed approaches, stop edits, revert to last working state, and explain what you tried.
|
|
||||||
|
|
||||||
## Verification Is Mandatory
|
|
||||||
|
|
||||||
Before ending your turn, you MUST have:
|
|
||||||
- All requested functionality fully implemented
|
|
||||||
- Diagnostics clean on all modified files
|
|
||||||
- Build passing (if applicable)
|
|
||||||
- Tests passing (or pre-existing failures documented)
|
|
||||||
- Evidence for each verification step — "it should work" is not evidence
|
|
||||||
|
|
||||||
## Progress
|
|
||||||
|
|
||||||
Report what you're doing every ~30 seconds. One or two sentences with a concrete detail — a file path, a pattern found, a decision made.
|
|
||||||
|
|
||||||
## Self-Check Before Ending
|
|
||||||
|
|
||||||
1. Did the user's message imply action you haven't taken?
|
|
||||||
2. Did you commit to something ("I'll do X") without doing it?
|
|
||||||
3. Did you offer to do something instead of doing it?
|
|
||||||
4. Did you answer a question and stop when work was implied?
|
|
||||||
|
|
||||||
If any of these are true, you are not done. Continue working.
|
|
||||||
150
modules/_opencode/command/supermemory-init.md
Normal file
150
modules/_opencode/command/supermemory-init.md
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
---
|
||||||
|
description: Initialize Supermemory with comprehensive codebase knowledge
|
||||||
|
---
|
||||||
|
|
||||||
|
# Initializing Supermemory
|
||||||
|
|
||||||
|
You are initializing persistent memory for this codebase. This is not just data collection - you're building context that will make you significantly more effective across all future sessions.
|
||||||
|
|
||||||
|
## Understanding Context
|
||||||
|
|
||||||
|
You are a **stateful** coding agent. Users expect to work with you over extended periods - potentially the entire lifecycle of a project. Your memory is how you get better over time and maintain continuity.
|
||||||
|
|
||||||
|
## What to Remember
|
||||||
|
|
||||||
|
### 1. Procedures (Rules & Workflows)
|
||||||
|
Explicit rules that should always be followed:
|
||||||
|
- "Never commit directly to main - always use feature branches"
|
||||||
|
- "Always run lint before tests"
|
||||||
|
- "Use conventional commits format"
|
||||||
|
|
||||||
|
### 2. Preferences (Style & Conventions)
|
||||||
|
Project and user coding style:
|
||||||
|
- "Prefer functional components over class components"
|
||||||
|
- "Use early returns instead of nested conditionals"
|
||||||
|
- "Always add JSDoc to exported functions"
|
||||||
|
|
||||||
|
### 3. Architecture & Context
|
||||||
|
How the codebase works and why:
|
||||||
|
- "Auth system was refactored in v2.0 - old patterns deprecated"
|
||||||
|
- "The monorepo used to have 3 modules before consolidation"
|
||||||
|
- "This pagination bug was fixed before - similar to PR #234"
|
||||||
|
|
||||||
|
## Memory Scopes
|
||||||
|
|
||||||
|
**Project-scoped** (\`scope: "project"\`):
|
||||||
|
- Build/test/lint commands
|
||||||
|
- Architecture and key directories
|
||||||
|
- Team conventions specific to this codebase
|
||||||
|
- Technology stack and framework choices
|
||||||
|
- Known issues and their solutions
|
||||||
|
|
||||||
|
**User-scoped** (\`scope: "user"\`):
|
||||||
|
- Personal coding preferences across all projects
|
||||||
|
- Communication style preferences
|
||||||
|
- General workflow habits
|
||||||
|
|
||||||
|
## Research Approach
|
||||||
|
|
||||||
|
This is a **deep research** initialization. Take your time and be thorough (~50+ tool calls). The goal is to genuinely understand the project, not just collect surface-level facts.
|
||||||
|
|
||||||
|
**What to uncover:**
|
||||||
|
- Tech stack and dependencies (explicit and implicit)
|
||||||
|
- Project structure and architecture
|
||||||
|
- Build/test/deploy commands and workflows
|
||||||
|
- Contributors & team dynamics (who works on what?)
|
||||||
|
- Commit conventions and branching strategy
|
||||||
|
- Code evolution (major refactors, architecture changes)
|
||||||
|
- Pain points (areas with lots of bug fixes)
|
||||||
|
- Implicit conventions not documented anywhere
|
||||||
|
|
||||||
|
## Research Techniques
|
||||||
|
|
||||||
|
### File-based
|
||||||
|
- README.md, CONTRIBUTING.md, AGENTS.md, CLAUDE.md
|
||||||
|
- Package manifests (package.json, Cargo.toml, pyproject.toml, go.mod)
|
||||||
|
- Config files (.eslintrc, tsconfig.json, .prettierrc)
|
||||||
|
- CI/CD configs (.github/workflows/)
|
||||||
|
|
||||||
|
### Git-based
|
||||||
|
- \`git log --oneline -20\` - Recent history
|
||||||
|
- \`git branch -a\` - Branching strategy
|
||||||
|
- \`git log --format="%s" -50\` - Commit conventions
|
||||||
|
- \`git shortlog -sn --all | head -10\` - Main contributors
|
||||||
|
|
||||||
|
### Explore Agent
|
||||||
|
Fire parallel explore queries for broad understanding:
|
||||||
|
\`\`\`
|
||||||
|
Task(explore, "What is the tech stack and key dependencies?")
|
||||||
|
Task(explore, "What is the project structure? Key directories?")
|
||||||
|
Task(explore, "How do you build, test, and run this project?")
|
||||||
|
Task(explore, "What are the main architectural patterns?")
|
||||||
|
Task(explore, "What conventions or patterns are used?")
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## How to Do Thorough Research
|
||||||
|
|
||||||
|
**Don't just collect data - analyze and cross-reference.**
|
||||||
|
|
||||||
|
Bad (shallow):
|
||||||
|
- Run commands, copy output
|
||||||
|
- List facts without understanding
|
||||||
|
|
||||||
|
Good (thorough):
|
||||||
|
- Cross-reference findings (if inconsistent, dig deeper)
|
||||||
|
- Resolve ambiguities (don't leave questions unanswered)
|
||||||
|
- Read actual file content, not just names
|
||||||
|
- Look for patterns (what do commits tell you about workflow?)
|
||||||
|
- Think like a new team member - what would you want to know?
|
||||||
|
|
||||||
|
## Saving Memories
|
||||||
|
|
||||||
|
Use the \`supermemory\` tool for each distinct insight:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
supermemory(mode: "add", content: "...", type: "...", scope: "project")
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
**Types:**
|
||||||
|
- \`project-config\` - tech stack, commands, tooling
|
||||||
|
- \`architecture\` - codebase structure, key components, data flow
|
||||||
|
- \`learned-pattern\` - conventions specific to this codebase
|
||||||
|
- \`error-solution\` - known issues and their fixes
|
||||||
|
- \`preference\` - coding style preferences (use with user scope)
|
||||||
|
|
||||||
|
**Guidelines:**
|
||||||
|
- Save each distinct insight as a separate memory
|
||||||
|
- Be concise but include enough context to be useful
|
||||||
|
- Include the "why" not just the "what" when relevant
|
||||||
|
- Update memories incrementally as you research (don't wait until the end)
|
||||||
|
|
||||||
|
**Good memories:**
|
||||||
|
- "Uses Bun runtime and package manager. Commands: bun install, bun run dev, bun test"
|
||||||
|
- "API routes in src/routes/, handlers in src/handlers/. Hono framework."
|
||||||
|
- "Auth uses Redis sessions, not JWT. Implementation in src/lib/auth.ts"
|
||||||
|
- "Never use \`any\` type - strict TypeScript. Use \`unknown\` and narrow."
|
||||||
|
- "Database migrations must be backward compatible - we do rolling deploys"
|
||||||
|
|
||||||
|
## Upfront Questions
|
||||||
|
|
||||||
|
Before diving in, ask:
|
||||||
|
1. "Any specific rules I should always follow?"
|
||||||
|
2. "Preferences for how I communicate? (terse/detailed)"
|
||||||
|
|
||||||
|
## Reflection Phase
|
||||||
|
|
||||||
|
Before finishing, reflect:
|
||||||
|
1. **Completeness**: Did you cover commands, architecture, conventions, gotchas?
|
||||||
|
2. **Quality**: Are memories concise and searchable?
|
||||||
|
3. **Scope**: Did you correctly separate project vs user knowledge?
|
||||||
|
|
||||||
|
Then ask: "I've initialized memory with X insights. Want me to continue refining, or is this good?"
|
||||||
|
|
||||||
|
## Your Task
|
||||||
|
|
||||||
|
1. Ask upfront questions (research depth, rules, preferences)
|
||||||
|
2. Check existing memories: \`supermemory(mode: "list", scope: "project")\`
|
||||||
|
3. Research based on chosen depth
|
||||||
|
4. Save memories incrementally as you discover insights
|
||||||
|
5. Reflect and verify completeness
|
||||||
|
6. Summarize what was learned and ask if user wants refinement
|
||||||
@@ -15,6 +15,16 @@ import path from "node:path"
|
|||||||
type BookmarkRef = { name: string; remote?: string }
|
type BookmarkRef = { name: string; remote?: string }
|
||||||
type Change = { changeId: string; title: string }
|
type Change = { changeId: string; title: string }
|
||||||
type JjRemote = { name: string; url: string }
|
type JjRemote = { name: string; url: string }
|
||||||
|
type PullRequestListItem = {
|
||||||
|
prNumber: number
|
||||||
|
title: string
|
||||||
|
updatedAt: string
|
||||||
|
reviewRequested: boolean
|
||||||
|
author?: string
|
||||||
|
baseRefName?: string
|
||||||
|
headRefName?: string
|
||||||
|
isManualEntry?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
type ReviewTarget =
|
type ReviewTarget =
|
||||||
| { type: "workingCopy" }
|
| { type: "workingCopy" }
|
||||||
@@ -32,6 +42,9 @@ type ReviewTarget =
|
|||||||
type ReviewSelectorValue = ReviewTarget["type"] | "toggleCustomInstructions"
|
type ReviewSelectorValue = ReviewTarget["type"] | "toggleCustomInstructions"
|
||||||
|
|
||||||
const CUSTOM_INSTRUCTIONS_KEY = "review.customInstructions"
|
const CUSTOM_INSTRUCTIONS_KEY = "review.customInstructions"
|
||||||
|
const MIN_CHANGE_REVIEW_OPTIONS = 10
|
||||||
|
const RECENT_PULL_REQUEST_LIMIT = 5
|
||||||
|
const PULL_REQUEST_MAX_AGE_DAYS = 7
|
||||||
|
|
||||||
const WORKING_COPY_PROMPT =
|
const WORKING_COPY_PROMPT =
|
||||||
"Review the current working-copy changes (including new files) and provide prioritized findings."
|
"Review the current working-copy changes (including new files) and provide prioritized findings."
|
||||||
@@ -163,6 +176,13 @@ Provide your findings in a clear, structured format:
|
|||||||
|
|
||||||
Output all findings the author would fix if they knew about them. If there are no qualifying findings, explicitly state the code looks good. Don't stop at the first finding - list every qualifying issue. Then append the required non-blocking callouts section.`
|
Output all findings the author would fix if they knew about them. If there are no qualifying findings, explicitly state the code looks good. Don't stop at the first finding - list every qualifying issue. Then append the required non-blocking callouts section.`
|
||||||
|
|
||||||
|
function normalizeCustomInstructions(
|
||||||
|
value: string | undefined,
|
||||||
|
): string | undefined {
|
||||||
|
const normalized = value?.trim()
|
||||||
|
return normalized ? normalized : undefined
|
||||||
|
}
|
||||||
|
|
||||||
function bookmarkLabel(b: BookmarkRef): string {
|
function bookmarkLabel(b: BookmarkRef): string {
|
||||||
return b.remote ? `${b.name}@${b.remote}` : b.name
|
return b.remote ? `${b.name}@${b.remote}` : b.name
|
||||||
}
|
}
|
||||||
@@ -228,6 +248,115 @@ function parsePrRef(ref: string): number | null {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatRelativeTime(value: string): string | null {
|
||||||
|
const timestamp = Date.parse(value)
|
||||||
|
if (!Number.isFinite(timestamp)) return null
|
||||||
|
|
||||||
|
const deltaMs = Date.now() - timestamp
|
||||||
|
const future = deltaMs < 0
|
||||||
|
const absoluteSeconds = Math.round(Math.abs(deltaMs) / 1000)
|
||||||
|
|
||||||
|
if (absoluteSeconds < 60) return future ? "in <1m" : "just now"
|
||||||
|
|
||||||
|
const units = [
|
||||||
|
{ label: "y", seconds: 60 * 60 * 24 * 365 },
|
||||||
|
{ label: "mo", seconds: 60 * 60 * 24 * 30 },
|
||||||
|
{ label: "d", seconds: 60 * 60 * 24 },
|
||||||
|
{ label: "h", seconds: 60 * 60 },
|
||||||
|
{ label: "m", seconds: 60 },
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const unit of units) {
|
||||||
|
if (absoluteSeconds >= unit.seconds) {
|
||||||
|
const count = Math.floor(absoluteSeconds / unit.seconds)
|
||||||
|
return future ? `in ${count}${unit.label}` : `${count}${unit.label} ago`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return future ? "soon" : "just now"
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPullRequestUpdatedSinceDate(days: number): string {
|
||||||
|
const timestamp = Date.now() - days * 24 * 60 * 60 * 1000
|
||||||
|
return new Date(timestamp).toISOString().slice(0, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
function parsePullRequests(stdout: string): PullRequestListItem[] {
|
||||||
|
let parsed: unknown
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(stdout)
|
||||||
|
} catch {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(parsed)) return []
|
||||||
|
|
||||||
|
return parsed.flatMap((entry) => {
|
||||||
|
if (!entry || typeof entry !== "object") return []
|
||||||
|
|
||||||
|
const prNumber =
|
||||||
|
typeof entry.number === "number" && Number.isSafeInteger(entry.number)
|
||||||
|
? entry.number
|
||||||
|
: null
|
||||||
|
const title = typeof entry.title === "string" ? entry.title.trim() : ""
|
||||||
|
const updatedAt =
|
||||||
|
typeof entry.updatedAt === "string" ? entry.updatedAt.trim() : ""
|
||||||
|
if (!prNumber || !title || !updatedAt) return []
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
prNumber,
|
||||||
|
title,
|
||||||
|
updatedAt,
|
||||||
|
reviewRequested: entry.reviewRequested === true,
|
||||||
|
author:
|
||||||
|
entry.author &&
|
||||||
|
typeof entry.author === "object" &&
|
||||||
|
typeof entry.author.login === "string"
|
||||||
|
? entry.author.login
|
||||||
|
: undefined,
|
||||||
|
baseRefName:
|
||||||
|
typeof entry.baseRefName === "string"
|
||||||
|
? entry.baseRefName.trim() || undefined
|
||||||
|
: undefined,
|
||||||
|
headRefName:
|
||||||
|
typeof entry.headRefName === "string"
|
||||||
|
? entry.headRefName.trim() || undefined
|
||||||
|
: undefined,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function dedupePullRequests(
|
||||||
|
pullRequests: PullRequestListItem[],
|
||||||
|
): PullRequestListItem[] {
|
||||||
|
const seen = new Set<number>()
|
||||||
|
const result: PullRequestListItem[] = []
|
||||||
|
|
||||||
|
for (const pullRequest of pullRequests) {
|
||||||
|
if (seen.has(pullRequest.prNumber)) continue
|
||||||
|
seen.add(pullRequest.prNumber)
|
||||||
|
result.push(pullRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPullRequestOptionDescription(pr: PullRequestListItem): string {
|
||||||
|
if (pr.isManualEntry) return "(enter PR number or URL)"
|
||||||
|
|
||||||
|
const parts = [pr.reviewRequested ? "review requested" : "recent"]
|
||||||
|
const relativeTime = formatRelativeTime(pr.updatedAt)
|
||||||
|
if (relativeTime) parts.push(`updated ${relativeTime}`)
|
||||||
|
if (pr.author) parts.push(`@${pr.author}`)
|
||||||
|
if (pr.baseRefName && pr.headRefName) {
|
||||||
|
parts.push(`${pr.headRefName} → ${pr.baseRefName}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return `(${parts.join(" · ")})`
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeRemoteUrl(value: string): string {
|
function normalizeRemoteUrl(value: string): string {
|
||||||
return value
|
return value
|
||||||
.trim()
|
.trim()
|
||||||
@@ -254,14 +383,6 @@ function getRepositoryUrl(value: string): string | null {
|
|||||||
|
|
||||||
const plugin: TuiPlugin = async (api) => {
|
const plugin: TuiPlugin = async (api) => {
|
||||||
const cwd = api.state.path.directory
|
const cwd = api.state.path.directory
|
||||||
let reviewCustomInstructions = normalizeCustomInstructions(
|
|
||||||
api.kv.get<string | undefined>(CUSTOM_INSTRUCTIONS_KEY, undefined),
|
|
||||||
)
|
|
||||||
|
|
||||||
function setReviewCustomInstructions(value?: string): void {
|
|
||||||
reviewCustomInstructions = normalizeCustomInstructions(value)
|
|
||||||
api.kv.set(CUSTOM_INSTRUCTIONS_KEY, reviewCustomInstructions)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function exec(
|
async function exec(
|
||||||
cmd: string,
|
cmd: string,
|
||||||
@@ -302,16 +423,29 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
return (await jj("root")).ok
|
return (await jj("root")).ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reviewCustomInstructionsKey = `${CUSTOM_INSTRUCTIONS_KEY}-${cwd}`
|
||||||
|
let reviewCustomInstructions = normalizeCustomInstructions(
|
||||||
|
api.kv.get<string | undefined>(reviewCustomInstructionsKey, undefined),
|
||||||
|
)
|
||||||
|
|
||||||
|
function setReviewCustomInstructions(value?: string): void {
|
||||||
|
reviewCustomInstructions = normalizeCustomInstructions(value)
|
||||||
|
api.kv.set(reviewCustomInstructionsKey, reviewCustomInstructions)
|
||||||
|
}
|
||||||
|
|
||||||
async function hasWorkingCopyChanges(): Promise<boolean> {
|
async function hasWorkingCopyChanges(): Promise<boolean> {
|
||||||
const r = await jj("diff", "--summary")
|
const r = await jj("diff", "--summary")
|
||||||
return r.ok && r.stdout.trim().length > 0
|
return r.ok && r.stdout.trim().length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getRecentChanges(limit = 20): Promise<Change[]> {
|
async function getRecentChanges(limit = 20): Promise<Change[]> {
|
||||||
|
const effectiveLimit = Math.max(limit, MIN_CHANGE_REVIEW_OPTIONS)
|
||||||
const r = await jj(
|
const r = await jj(
|
||||||
"log",
|
"log",
|
||||||
|
"-r",
|
||||||
|
"all()",
|
||||||
"-n",
|
"-n",
|
||||||
String(limit),
|
String(effectiveLimit),
|
||||||
"--no-graph",
|
"--no-graph",
|
||||||
"-T",
|
"-T",
|
||||||
'change_id.shortest(8) ++ "\\t" ++ description.first_line() ++ "\\n"',
|
'change_id.shortest(8) ++ "\\t" ++ description.first_line() ++ "\\n"',
|
||||||
@@ -320,6 +454,53 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
return parseChanges(r.stdout)
|
return parseChanges(r.stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getPullRequests(
|
||||||
|
args: string[],
|
||||||
|
reviewRequested: boolean,
|
||||||
|
): Promise<PullRequestListItem[]> {
|
||||||
|
const response = await gh(
|
||||||
|
"pr",
|
||||||
|
"list",
|
||||||
|
...args,
|
||||||
|
"--json",
|
||||||
|
"number,title,updatedAt,author,baseRefName,headRefName",
|
||||||
|
)
|
||||||
|
if (!response.ok) return []
|
||||||
|
|
||||||
|
return parsePullRequests(response.stdout).map((pr) => ({
|
||||||
|
...pr,
|
||||||
|
reviewRequested,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSelectablePullRequests(): Promise<PullRequestListItem[]> {
|
||||||
|
const updatedSince = getPullRequestUpdatedSinceDate(
|
||||||
|
PULL_REQUEST_MAX_AGE_DAYS,
|
||||||
|
)
|
||||||
|
const [reviewRequested, recent] = await Promise.all([
|
||||||
|
getPullRequests(
|
||||||
|
[
|
||||||
|
"--search",
|
||||||
|
`review-requested:@me updated:>=${updatedSince} sort:updated-desc`,
|
||||||
|
"--limit",
|
||||||
|
"50",
|
||||||
|
],
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
getPullRequests(
|
||||||
|
[
|
||||||
|
"--search",
|
||||||
|
`updated:>=${updatedSince} sort:updated-desc`,
|
||||||
|
"--limit",
|
||||||
|
String(RECENT_PULL_REQUEST_LIMIT),
|
||||||
|
],
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
|
return dedupePullRequests([...reviewRequested, ...recent])
|
||||||
|
}
|
||||||
|
|
||||||
async function getMergeBase(
|
async function getMergeBase(
|
||||||
bookmark: string,
|
bookmark: string,
|
||||||
remote?: string,
|
remote?: string,
|
||||||
@@ -479,13 +660,6 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeCustomInstructions(
|
|
||||||
value: string | undefined,
|
|
||||||
): string | undefined {
|
|
||||||
const normalized = value?.trim()
|
|
||||||
return normalized ? normalized : undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseNonEmptyLines(stdout: string): string[] {
|
function parseNonEmptyLines(stdout: string): string[] {
|
||||||
return stdout
|
return stdout
|
||||||
.trim()
|
.trim()
|
||||||
@@ -781,13 +955,10 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
target.type !== "workingCopy" && (await hasWorkingCopyChanges()),
|
target.type !== "workingCopy" && (await hasWorkingCopyChanges()),
|
||||||
})
|
})
|
||||||
const projectGuidelines = await loadProjectReviewGuidelines()
|
const projectGuidelines = await loadProjectReviewGuidelines()
|
||||||
const sharedInstructions = normalizeCustomInstructions(
|
|
||||||
reviewCustomInstructions,
|
|
||||||
)
|
|
||||||
let fullPrompt = `${REVIEW_RUBRIC}\n\n---\n\nPlease perform a code review with the following focus:\n\n${prompt}`
|
let fullPrompt = `${REVIEW_RUBRIC}\n\n---\n\nPlease perform a code review with the following focus:\n\n${prompt}`
|
||||||
|
|
||||||
if (sharedInstructions) {
|
if (reviewCustomInstructions) {
|
||||||
fullPrompt += `\n\nShared custom review instructions (applies to all reviews):\n\n${sharedInstructions}`
|
fullPrompt += `\n\nCustom review instructions for this working directory (applies to all review modes here):\n\n${reviewCustomInstructions}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projectGuidelines) {
|
if (projectGuidelines) {
|
||||||
@@ -906,8 +1077,8 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
: "Add custom review instructions",
|
: "Add custom review instructions",
|
||||||
value: "toggleCustomInstructions",
|
value: "toggleCustomInstructions",
|
||||||
description: reviewCustomInstructions
|
description: reviewCustomInstructions
|
||||||
? "(currently set)"
|
? "(set for this directory)"
|
||||||
: "(applies to all review modes)",
|
: "(this directory, all review modes)",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -930,7 +1101,7 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
void showChangeSelector()
|
void showChangeSelector()
|
||||||
break
|
break
|
||||||
case "pullRequest":
|
case "pullRequest":
|
||||||
void showPrInput()
|
void showPrSelector()
|
||||||
break
|
break
|
||||||
case "folder":
|
case "folder":
|
||||||
showFolderInput()
|
showFolderInput()
|
||||||
@@ -939,7 +1110,8 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
if (reviewCustomInstructions) {
|
if (reviewCustomInstructions) {
|
||||||
setReviewCustomInstructions(undefined)
|
setReviewCustomInstructions(undefined)
|
||||||
api.ui.toast({
|
api.ui.toast({
|
||||||
message: "Custom review instructions removed",
|
message:
|
||||||
|
"Custom review instructions removed for this directory",
|
||||||
variant: "info",
|
variant: "info",
|
||||||
})
|
})
|
||||||
void showReviewSelector()
|
void showReviewSelector()
|
||||||
@@ -974,7 +1146,8 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
|
|
||||||
setReviewCustomInstructions(next)
|
setReviewCustomInstructions(next)
|
||||||
api.ui.toast({
|
api.ui.toast({
|
||||||
message: "Custom review instructions saved",
|
message:
|
||||||
|
"Custom review instructions saved for this directory",
|
||||||
variant: "success",
|
variant: "success",
|
||||||
})
|
})
|
||||||
void showReviewSelector()
|
void showReviewSelector()
|
||||||
@@ -1084,16 +1257,7 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showPrInput(): Promise<void> {
|
function showPrManualInput(): void {
|
||||||
if (await hasWorkingCopyChanges()) {
|
|
||||||
api.ui.toast({
|
|
||||||
message:
|
|
||||||
"Cannot materialize PR: you have local jj changes. Please snapshot or discard them first.",
|
|
||||||
variant: "error",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
api.ui.dialog.replace(
|
api.ui.dialog.replace(
|
||||||
() =>
|
() =>
|
||||||
api.ui.DialogPrompt({
|
api.ui.DialogPrompt({
|
||||||
@@ -1113,6 +1277,69 @@ const plugin: TuiPlugin = async (api) => {
|
|||||||
api.ui.dialog.clear()
|
api.ui.dialog.clear()
|
||||||
void handlePrReview(prNumber)
|
void handlePrReview(prNumber)
|
||||||
},
|
},
|
||||||
|
onCancel: () => {
|
||||||
|
api.ui.dialog.clear()
|
||||||
|
void showPrSelector()
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function showPrSelector(): Promise<void> {
|
||||||
|
if (await hasWorkingCopyChanges()) {
|
||||||
|
api.ui.toast({
|
||||||
|
message:
|
||||||
|
"Cannot materialize PR: you have local jj changes. Please snapshot or discard them first.",
|
||||||
|
variant: "error",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
api.ui.toast({ message: "Loading pull requests...", variant: "info" })
|
||||||
|
|
||||||
|
const pullRequests = await getSelectablePullRequests()
|
||||||
|
const options: TuiDialogSelectOption<PullRequestListItem>[] = [
|
||||||
|
{
|
||||||
|
title: "Enter a PR number or URL",
|
||||||
|
value: {
|
||||||
|
prNumber: -1,
|
||||||
|
title: "Manual entry",
|
||||||
|
updatedAt: "",
|
||||||
|
reviewRequested: false,
|
||||||
|
isManualEntry: true,
|
||||||
|
},
|
||||||
|
description: "(override the list)",
|
||||||
|
},
|
||||||
|
...pullRequests.map((pr) => ({
|
||||||
|
title: `#${pr.prNumber} ${pr.title}`,
|
||||||
|
value: pr,
|
||||||
|
description: buildPullRequestOptionDescription(pr),
|
||||||
|
})),
|
||||||
|
]
|
||||||
|
|
||||||
|
if (pullRequests.length === 0) {
|
||||||
|
api.ui.toast({
|
||||||
|
message:
|
||||||
|
"No pull requests found from GitHub; you can still enter a PR number or URL.",
|
||||||
|
variant: "info",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
api.ui.dialog.replace(
|
||||||
|
() =>
|
||||||
|
api.ui.DialogSelect({
|
||||||
|
title: "Select pull request to review",
|
||||||
|
placeholder: "Filter pull requests...",
|
||||||
|
options,
|
||||||
|
onSelect: (option) => {
|
||||||
|
api.ui.dialog.clear()
|
||||||
|
if (option.value.isManualEntry) {
|
||||||
|
showPrManualInput()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
void handlePrReview(option.value.prNumber)
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://opencode.ai/tui.json",
|
|
||||||
"plugin": ["./plugin/review.ts"]
|
|
||||||
}
|
|
||||||
@@ -24,12 +24,16 @@ in {
|
|||||||
programs.opencode = {
|
programs.opencode = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = inputs'.llm-agents.packages.opencode;
|
package = inputs'.llm-agents.packages.opencode;
|
||||||
|
tui = {
|
||||||
|
theme = "rosepine";
|
||||||
|
plugin = ["./plugin/review.ts"];
|
||||||
|
};
|
||||||
settings = {
|
settings = {
|
||||||
model = "openai/gpt-5.4";
|
model = "openai/gpt-5.4";
|
||||||
small_model = "openai/gpt-5.1-mini";
|
small_model = "openai/gpt-5.1-codex-mini";
|
||||||
theme = "rosepine";
|
|
||||||
plugin = [
|
plugin = [
|
||||||
"opencode-claude-auth"
|
"opencode-claude-auth"
|
||||||
|
"opencode-supermemory"
|
||||||
];
|
];
|
||||||
permission = {
|
permission = {
|
||||||
external_directory = {
|
external_directory = {
|
||||||
@@ -118,14 +122,8 @@ in {
|
|||||||
codesearch = "allow";
|
codesearch = "allow";
|
||||||
};
|
};
|
||||||
agent = {
|
agent = {
|
||||||
build = {
|
|
||||||
disable = true;
|
|
||||||
};
|
|
||||||
plan = {
|
|
||||||
disable = true;
|
|
||||||
};
|
|
||||||
explore = {
|
explore = {
|
||||||
model = "openai/gpt-5.1-mini";
|
model = "openai/gpt-5.1-codex-mini";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
instructions = [
|
instructions = [
|
||||||
@@ -160,10 +158,10 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
xdg.configFile = {
|
xdg.configFile = {
|
||||||
"opencode/agent" = {
|
# "opencode/agent" = {
|
||||||
source = ./_opencode/agent;
|
# source = ./_opencode/agent;
|
||||||
recursive = true;
|
# recursive = true;
|
||||||
};
|
# };
|
||||||
"opencode/command" = {
|
"opencode/command" = {
|
||||||
source = ./_opencode/command;
|
source = ./_opencode/command;
|
||||||
recursive = true;
|
recursive = true;
|
||||||
@@ -177,7 +175,6 @@ in {
|
|||||||
recursive = true;
|
recursive = true;
|
||||||
};
|
};
|
||||||
"opencode/AGENTS.md".source = ./_opencode/AGENTS.md;
|
"opencode/AGENTS.md".source = ./_opencode/AGENTS.md;
|
||||||
"opencode/tui.json".source = ./_opencode/tui.json;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ in {
|
|||||||
"ghostty@tip"
|
"ghostty@tip"
|
||||||
"raycast"
|
"raycast"
|
||||||
"spotify"
|
"spotify"
|
||||||
|
"tailscale"
|
||||||
|
"whatsapp"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
local = import ./_lib/local.nix;
|
local = import ./_lib/local.nix;
|
||||||
in {
|
in {
|
||||||
den.aspects.email.homeManager = {pkgs, ...}: {
|
den.aspects.email.homeManager = {pkgs, ...}: {
|
||||||
|
programs.aerc = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig.general.unsafe-accounts-conf = true;
|
||||||
|
};
|
||||||
|
|
||||||
programs.himalaya = {
|
programs.himalaya = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package =
|
package =
|
||||||
@@ -50,6 +55,7 @@ in {
|
|||||||
port = 993;
|
port = 993;
|
||||||
tls.enable = true;
|
tls.enable = true;
|
||||||
};
|
};
|
||||||
|
aerc.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
"age": [
|
"age": [
|
||||||
{
|
{
|
||||||
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKWXVhTEw0em1CZVB3d2U3\nSWRjMlZpTlFYSXZJZVE5SWttSFV2K3l3VFJjCjZZbG05a1RsUlRORDNaRXduVHBC\ndHZ2aG1FRnJhbFQxNkNxTEwzV0NRdHMKLS0tIFplbXhERjFhRGh0YUtuVG5IZWVh\ndEV6SkhTWnUrVkFmR0NYRS8xZ05zRTQK8qcapJ2Z2AukAUSFagChNGt7BTnIXchr\nociqhWE+BVPROduihwpsQlAWxEARJP/5sqhOAZpNrnna9Psg4m1MFA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0cmFCRDVFcFFORVpsK2Fo\nYWg5S3VzSGlCYVp1S1Q3NGF4SDZqMVFmTFc0CkZQUDJwQ3AvUDNpMUZNaUlRTkNt\nQVR2UzI0Snp3SVZqN2phRzE1K0ErZ3cKLS0tIDE4dndRWXVycitxSVNEN28vN29s\nWnRIT24yT3Z6R1ZiYURYd1BiSzBIOU0Kn7jrvq06CxRxn7XbOIMoEIjMDIr6A089\ns1ymMJO8DmeKdNaL5s3EwG7BZBAimdmcjANST1kXFy7oc4eSk4ETwg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJTzlPdWcyQlFPSWdhVnVB\nR08yVmdaeFRNYUo2clA4ellicU9rVnlZMVFBCnRjOTZGdHBOMW94OGRyaE9HMktq\nQ1V0WmQycndnSHh4K1JiZllqSG5oRVUKLS0tIGZ6VTNUd2xmR1N1bmtDU1k2Q0ox\nRDAwQytvL3JQUjh0MHBFV09kdVpJdkUKC1CigRs4k/uSXC4zMWL60xaHFoyvzYlu\nP2olBA4CerGEoMc0ZIBEEr78hB0j//06se68BreZcD4FcDC77IWNXQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqZFVRMDVVaEJWUWQ1bkRD\nWmQ1dTRMK2FpMmZLTERuOHc1OHUramFTZkFzCnlSUTUzUktrdFJyVnk0SnpFOURT\nME1wckdyUHFmeE0rN1BneUhIR3JuZHMKLS0tIGJCTHZuWTdGQVhoU3JnSmxIcm83\nc0hwNGUvVEljWWVwOWpCS1BJckhjRUkKDD22XytVN58yR22InpsUEN6y1r2AQqLn\nu1fmWC7R4AJcisHqVSEOBW3qQVQdFWIptBN/5urkb2yAKNtP7WUUbg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRcVJ0WFoxN2dQSy8xN2ox\nU09GbUd0UG03Wlc0RnpTNkpYbUo2ZFg1Q1hRCmZyUTZiYklMbnBFczhkSTNFaTNi\nSy9vb1VXOFBqQVMySHRVUng0c083VFEKLS0tIFplV3JVSmV4TmJHSkRPMFMzZkZl\ncmVZWjRCZWxlamxUdnp6ZnA3bXNaV1EK4ZXEJBXHGTaEbNq81RRm+GfElyJekrX+\nxrWHGTkJ4golaI39p3j/F8sF40Sa036ZJmQU8uX9fq1cnuSRv4lb1g==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlc0NibDBuUVJYLzRQY0dP\nWlRzWVo0Rk5NVXh0SGZjYnNza2g3M3E0U0cwCmc5K2d5UzZvR1c2QmJickg3Uk5X\nQm9GMkZnYUVGS1lPRklrcDJRdmMvM2MKLS0tIHBiclZyTVU5emVka05xNXJTTnhF\nN3plRmN2eEl0Y012eGNBbXBsc054Wm8KIB6pNlSM63UvoaPsHNYhSuhZsfM/VQfw\nTxITGnK0Lkjw91SDVzuCGPTtZxuUTFR2q0SyGbZU9IrLQWmBTaENhw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2",
|
"recipient": "age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5a3gxLzQzQXl6OThJekYr\nVE5zQ0tHd2l4K1NnZEJvSkw0WVptdE9VQ3g0CjcrdkgyUGczZTY5SFdQNFdneTVR\naTdjTUhSSzZvQnJmc2g1NGJhN3Y3VjQKLS0tIDk4ckszblk5QUFkNzVVZ3czYnpk\ncVZlTlJxK3ZLRmxZRmtaZzNkME9UZWcK+GVFoiY5qKX8DdKbGxUoLxF3gnnG3Cbl\nk/57ZH1xVJT4jCCqdploZCSwSLdGrUDGs8I4FixKVMKGT6Ce2xaPcg==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEUUhvblozMyt0UDJpZ2dx\nNWJBZG5wQzFEM2RFTTJjb3FtcE1ISkd3cEhFCjJOdDJwOTJrdWc2c0NYWGQwWk9y\nREM0Qm1iK3FHUE54ZVI5L2k0RmtESHMKLS0tIEtRdTQvY1AxZHhSZWlhSThFV2FN\nQ0wyUTRaRnh1cDVlVmNjekNuNUN2bUUKOnTcpcaN7cuQXceJmPtKJj2pyIxC3Lj7\npedLV126Q07i3aRrQgm92O8NW2lMaM2Z3FldooTsQgIieQeMCJ6G9w==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxUHJtZ3VuRVZnU0RXeStx\nNUQrakgxWm5oOFlmbXZGL1UxQnhvYU1sUkZNCmlucWQyeFJDSFJZYWlSbkd2eCt6\nS2liQ2g3VXpING81OHRPUGRocnNqa1UKLS0tIG9tdXdna3RhYm8xRHRsS2tQYlUx\najVwbndFMDUyVG0weGtGdWxpQnpsSVkKdTnOnyKDkDfDtDA4jdF1JZ6wXdf/Rucv\nT4YYvjbh7JTnOl6wMg37uy29GVlI0hjOCMyX0j2BmKis/awCJ4bxUA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqUVhZanBIR294ek1keWtZ\nM3puaC8zWGE3UHpmZy9vbzh3YkRyTW5rcG5zCmQ1SnR5NzZLcXNZZVUzTWV1YkFn\ncE5CaHpSeEZnWlNkak1MbWM2UUJJT0kKLS0tIEl1T2lsYndYeHkxalpBYUtwY1Yv\nMGJLWWEwVW5lNnNwNEZhTnRMTVdJdmMK3mg0hzN6KjmR288U09USPmyoQd5ixmCY\nOZb6qjx1O9TUmuho6j+zR4BmMcZ9kIv6uEuURKxGFwzZy+l5a3e3Cg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2026-01-04T19:45:21Z",
|
"lastmodified": "2026-01-04T19:45:21Z",
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
"age": [
|
"age": [
|
||||||
{
|
{
|
||||||
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2Ly9XQlRDZzgrY2tiTmRi\nNmhBNDQ2TDV4eGZsUUFvTmlHR2tCN29IUGljCnBvb2RKNUdHTnEwQ1RzS05uOTVK\neElUUmdRdnRaYUpIWEljdlN6REgwUm8KLS0tIGpJRVNKTkR3bEcrcks3ek5LNVV3\nYzhOUFRvY1RPYkM5V0hXenFHd2NSdWsKokyuyPXjMAJIfyeWsBHGWaLID7Oorc9d\nQE9Veh2aramAH1xb30BVLa40Dpu0jI/Wgxoo0iDf5OypNXBiBH+FMA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4WmNWMnQ2NEg1MnFvOS9n\neHBnMHpvWllvM2taeFM5SXRVT0wvMTRaMUJFCnk5MVpGRjN1cUxiYkdLSlZ1aTB0\nTkduQkFZcjkxQzUyWHhlQ0tFRnZFTWsKLS0tIDVLdXdySWxqb20zZ3RKSE1qc2Nh\nSC82UmxGN2VUY2pZY3pnWDlKTkRKSEUKFSQqZIzGXpCzpWVWko7J3hxglRJmOuF4\nmE/lC55uekxcochjgPT9uDJfG1/kskWyJTBb5Ndx3YFkUcnfVOZc4Q==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMNUVHeWg1N1ZPKzBqMnBn\nY2VaTlp0K3ppbFdmN0JuQmRnVUlzQ0hMZTI4CkxORVJ0NUIxVXZMcHVRcXFSV01l\naFFVOEtJSFY0MUVWOXYxbFlqRmNuVHMKLS0tIEYydDB1ZHUvQS8yTENmZkZHeXFV\nU1N3ZC9zNEtZSnE2Wk9TREN3Y3JwNEkKyFqj+1kGjqKyslllunUl8dVQwFAe/MdL\n5PNKIfVErxbnPtlc+yfRSWsfOQPdNV9GVM9rtOxA+51QStiGlLU12Q==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5U2plZGxEVy90NUMzellJ\nYVVsTDUvL1o5OXZ4YjR3c0tPY2RjQWpVd0M4Ci9kUFA3OEFoRjlUa1g4Nnl3K2Rq\nNHA1NkRtVzdXM21QNTI5ZFJsNFVCMncKLS0tIFRQbDdXeWxIdzJpNng0QVc3bStT\nQ2VPNFA4NDlmU3hscjJ0MjdGRGQxakUKM9H04Ezw/KoAJVjFB56v0vjIHJiO+aW+\nWWdBlsZoeTYChkMGcQ74SaLkPMEkD3GU8Ua9RZBIqFzOZwsOdAkWBA==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTREx3SU02RU1adU5Ielkz\nVUFrdUZkQzJwZG1aQlZEcDdxWXVFM1JtRHk0CmNTamFhcjJEMklYbkpxWHFzekhY\nQ1E1STZ3U0RMNkNnVnVvWXJkZUhxRm8KLS0tIE1ZaFBORVRMZkYwNnBkTjFxSWNG\nVWJnYjgzM3IyMDJ3Z3o1QkV0RGdjL0EKQ1G/uJ8HcVDMUk8NXBC0MRcJOyLzQRlT\nL5Sf6Es6UYrTp5tIWleR6u48aUGi8HvcOOeCrK2S5utj5xPl6E+bqQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSSTNhc0xrOXRXOWZVdWNh\nNGQxNFBXUHNrL2NsMnBkcDdSVHVYc1RPM25zClh0L2FrMEhZcWt3RGtHa0ErNjUz\ndDlZaC9kZVVHSkFOK3dBWGwwZStQeUkKLS0tIE1VRnJCbTFWUkhoQ0c0dkppbVRL\nSDZldkdXV2U5Z3ZycmEySTJ5WDFTbVEKgHq5Xa86l+1e87p2KodJN+8/IOz2y0w7\n3xHjoZ8LaP7aQ5PWBTHUk6KeOjJQnTMzimQC+YOs4XkmeItBt+6Gjg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2",
|
"recipient": "age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBT25zTE9Na21GbHJOeVZw\nU3Uzck0yN0J3Und4bExsb1VGSkNleFdZbFdZCkx1TG5VU2RyZGlWT29wd1QxV1Rs\nM20rd2hWN09wQkc2K2dWS1JUenMwUW8KLS0tIGlLQ3FNL1NrODVmNENpd3F1OGlt\nVDBhNThoR015N01UTGp6MDUxdHJFWnMKvuFBvzz1k8Tg1J2GrhEO2yvJEfwxYrmX\nDQ1/qcoSOWde7N1Mvx9ih2mFlK4JiD51tWF351C0VOKNdnBBzO46VA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBybnprUGZPREdpZzllYjMy\nTU5DVnRrTkxEREZQUFpiM0E4SUtsSlpqOGdnCktuaGtSSHpzTnl3c2ZuMlV6MzBo\nLzdzYWhPR1RtNnFmdVg2cTUwNE5CNEUKLS0tIHRHaXlnTlFIU1lVT1dkVUdOUnNG\nWnl1OXFpVmo0WkVlSVpKYlZaMC96encKNBnnwC2/5n2ZWYvRRoCQjOPg9b3+fFJj\nhJA45nhoO38zg0Wdv4OPA+Zrw0K0lgllk02BNXMDSv8+IthlzN5F0Q==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTYysrSjZSZDYycmtNa0h6\nZHM4VGpzdDQ3ZXlYWG9ia2F2RXpOOTVnMlcwCmpTazNzeWt0RVdPT1d5b0hqQ2pp\nd3BiU0poRm53MGFFakJvYkhxVklhWGcKLS0tIGdncmxRZVB4dGVzOVMxdVM5MkN1\nTkVXRVhqbXIxa1FERjFBYnhlTkJsVmcKOUwliiZ/tMzelHQGCYi3dW/Kq0rKqW7k\nz6kSVA6vTZGFTqiK6uLqYL56BToBY1iWM4skUYTctrcXO1eEGwnbfQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTeDllU1RoL3VndEpGMG8z\neFl0TEtPL0VXUXFBVDhwRTV2TkdyaDlRS3k4Cm1hZHRDUXRFT1RPajY0Vm9oZ1BC\nbWhla2swcHdLdFdRK2NTZ1B3SGgrVjQKLS0tIGhpNE0yV2JTeHV4emdmSU5PM2ZV\nWkh5ZzY1eW5jSVF2N0Rndk0vQzlpam8K9++sBqLwmDs4WMhHADbSwlUd1te4t3/S\nDk9ENUmvu3xRX8cpT0VELjfXRf3ne6HTbG7K7Lxj5jbmfX6aSRpIsg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2026-01-04T19:47:06Z",
|
"lastmodified": "2026-01-04T19:47:06Z",
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
"age": [
|
"age": [
|
||||||
{
|
{
|
||||||
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5SVUveHVXUDVTakJ1QUlj\nOWlmakVlY3JucVJGaVljVUwrL25MaU5PSGxzCk02akVDWHhjUWs0aFZrdVpjUER3\nVXFsYnJCWXFSZFNrR2tLSzRBek9mRXMKLS0tIGFJZzFFV3hkeTdmYWFKWVpnWXl2\nbm9naXJiRkdSL1UzTE9xQXBXR0xENGcKxYnDk+n4u94whP0mNNSxK3KsY8RAq+w4\nbVaxdcomXo6NJq1izMdVkQFIp1hBZniaktPGsDUMWLpJ4mSrVwPbPw==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQRlFyYjFaNHJ0RDB1azRW\nY1ZvdnV5MEdWb3UwQnZuZU9sT2JleElkNmdZCm9CWVB6V0JUTE4xQWtYTU9hb0N2\nVUVtdXFVcHlTaXJBNlM0SXJac096dmsKLS0tIFdEdDZlTndXVmtTbjV3eEVsb2xG\nbzkrbU5jY3l1d3VFZExsVnB3dnFUdU0KKpmLWWgxnUfH62N0ibnqtGjvtRC6/2q7\nD/h4VozD7oZh1lC1S9SDl6J7j54frJ//AtsDdbIviVNTg4JzJ50kwQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmWGNtM0RGTHR3M2c5RnFt\nVjd1MFM1Q3hvK0xid3BnZ3VWWmpySlN0WkRvCmM3WFlUajBaN1B4cEVUVWRUOS9M\ncXVQZHZ6a21xaG53UzdKdHR5Y1JJeU0KLS0tIHRTRHpZbW1IQ2FUMDBldUtxRi8x\nN202KzhjQ3MxSERhZEsrUm00RUlGZG8Kz0BdZXtPOGe/lwiSrecSho9zPn68TZ5P\nkH3YOpAHmQZrm3P876fg8ChMv5Rgd3F679d6h334fwZDfiu2h9mFBA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3WWNCR04zV0FhT3NhNUQ2\ndVN3am4xY1oxa0tXOGlLdjFMU0cwQWo4MWlnCklPRGl5YVYyMTRVcGhhNVRSaUdo\nYjZmbTRTaGZ2SFB6d0tUeEdEVFFBU1EKLS0tIHZDOFRDTkhqbG41MGNYU2lkc2NV\nWjNYV3kwRVFrWkdNZitYZlpnUlF3NGsKne7cflZE3HpP2TbtsSSQfOLucOq16Pof\n5vQ7M8lIqi0jqL/k+siWIspilbhpkknTgUzcBsui4FxKCfEPxLFMHg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLVmRUczBEQ3RLbXByeWpU\nN3EwUm9aTXRwTlp5dG1weEpKOENXTkhrMW1FCmllRUFTZGdhWXRhWUp0dG03TnFu\nN1ZjYUJ6ZGVYNnVJZTBlcTFGUkNXZ2cKLS0tIENLZmo0aHIvbjNxbllZa2tkbHR5\neHZiRjcwd2VGbEovYm5HcEdHRXRxV0EKx6A57Usvle5ItD3XysZI41M/9s9l719i\n1fpP9W/5i+dDCgE6/ui8WLVpoj62eaArFBEN7OH1Xt04DkJ/G8Cytg==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvYkxnekd6VnJ4MEo2d0tx\nSlhmeGhPenQzSkJLSkNzWnB1d2pvTHI1QVJVCkJRNTVZeWpUV0dzNXdMclNCUlVW\nQWFoa0oxMkNBUERVMVFGdG4ySlV6akUKLS0tIFhRdkZ6ZWdqVS91U3JPd2p6OENj\neHpCc3UydXF4SFZCSTl5SzcwL2dwVUEKLT37+0UdWfe26cyQ5gRwubqN8nBv0iwp\nBRDwEBw5H6rgzUEDaAv3fRy/AxT1TvtiavuKhlJdCsJqDpJmBjgIRw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2",
|
"recipient": "age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiMEo1NFhoei9vV3hlaDVo\nZjNteStQTzl2VU5WaVZFaEpmdWpzUEtVNlFFCjVUREVBZ3ZxdlBBdHplRzRxUGph\nYldyY0tpNUVqclh1TE1xemlZYm5QeGsKLS0tIE1oZ2VYSDFqZTNvK25EclRPTUZT\nbVIwdjFBQmRZTEhISTcxM1BRSk9iSWsK5/xZkLijy4p/N9WygTCIxlH0SdIiIz5W\nkGqvG27RZGqR3qwNn3vSoUBH5yOzhJAP9RAvAu5EET0jwuuG/3L0Vw==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyU1pZT01HdkhZQ0FSbXdS\nQVdlTlhlcDcvdlZZcnJJTVNSQ0Z2NTZueVVVCmpRVWR4aTF1NDZ3NUV0RkpRMjMx\nY3EzYUZRSUtMVWtsVzlhQ0MvVmgyN2sKLS0tIHIzOTUrdEVWQ1l4RXQvV01IUy95\na1pvK0pLSFRYMGFyQjhCSDJmaERhSGsK1vg2a05yGfgp1Uo12+1nCv6cN4oU1s6h\nwvrCtejM1z79f5ZGJaAK8Tz/KOKQIA402QKp9eTWf5Y4Ix6OUd1t1w==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOMExJbWh4MldLckw5YjJK\nbGJyLzgxU1RUQldGVXZIcDRZL3BaODRDSEhFCkQ3TUszSWZHbkRuV0RCNWFaZDFl\nUmQvVlVydDMwL3JKVXpoNG1sdGtFMVkKLS0tIFJGK1AvZlYybVJIS0d0TlNpVU9o\nVkFXK25Ub015YWp6V3VBaStkRDM1RjgKrP91fgB60MlnXjKs9jvSnkUlSHIU6niJ\n4VveJwqCXO9zrAcS2tZaQFQ7uwga1r+iKflzLJxMPsbvshj4sfLsrg==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5a2YrMjR3SjFGZ3dtb1JN\nNGxCcDBTOVVVcHVyYzlXblBKR1F2blNVelc4ClBDZHdqNTNKckpXYzlwVFhZVktk\ncExnNTNka09ZK1lWclRudnU3N3ZDQlkKLS0tIENBR3NwSk9BdFMwejNybXYvN0tV\nU3VEVC9lTkxJbFZXWUZDRG9QMGdab3cKRYgccR5zCKEZW08FHb8/PTibpTPChG7o\nHT23XeVAf524+QpExJKsQX4Qpr+2UEG3/hUoRaisuS3TMyRUtKRoMw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2026-01-04T19:44:05Z",
|
"lastmodified": "2026-01-04T19:44:05Z",
|
||||||
|
|||||||
@@ -4,27 +4,28 @@
|
|||||||
"age": [
|
"age": [
|
||||||
{
|
{
|
||||||
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1SktQSmxuSG5MY2ErNUEx\neEd0Q1RsSzhaUjgyQnViQ2hhd09UNDFzcVJBCjg0R0M4ZnB1UFBEcDNJQXFjWnlO\nQVhSeURHVnorcUVnczBtdU04WDhRODgKLS0tIEJxNm9teWIyUXhzbU1EY2l1WVBk\nZG9xUlh1cDhiQmdsYnZpNVNOTUY5ajAKPyt8ZIKTfu0azAFezj7rtSJX8X4rO712\n0w8MAvnLM8k5ij6nJtR3HylwLmZ9AfMSq4Aikl+oRu7rXs26JvPbZA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJdjZ2ZEcvM3RFbThNL3VV\ncHlOek8zS05sOGJGYlJ5U0J2VDJqaHA4Vm5vClB1b2NNZk5Lc2ZscDdnd0k3TGZS\nWHllM0l4TTFuWWdtUWtidDVaRU91M28KLS0tIHh5UDZiVXEyV2lYSTQ0Rk5peGx3\nNG00OFhPUWZQamdEOWVGZVpFSkc2MFkKSPQ+6c1AyWObFZQcoH5ImtFNl8lILz59\nao3ZQ23yIiSYAZ2pAeOPh4WuNtguZ5S6dnbRDr4e/8Vzw/1qgU994w==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSWU5qSDBNY2d2YnNvVHU4\ncElNT0s0R0N3U3pjYW9kVGxFV2thY3QzYTB3CkdGRUhVMUdvR1dwdVdnZ3o0M0ZH\neXV0VUZyaFRBbEN1RXR6RGJ6RmIySjgKLS0tIGZGc3Voa09CNDFoMXVyZTJmME1Z\neldyMVAyd3pTZzB4RVhTRzZVOGs3NVkKyP8sIk/Oy1GXxG0tw8Ocjerfze+eIrNW\n5XYA96ct/2M2jiPdTxg2yEI5a9wycDkzNIzE95Xyfl3LkY8864wAMQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6Q29GRkdZdzNjUDAzUWU3\nTlRvUm5URWd5a3MrMDE0WmFsWFRZS2NkQ2s0CktHZHpOaUFnWUhHUDdWK3FPMi9L\nMkhweU84OFp6bFhnME1hbk92M0pGMUUKLS0tIGdkYjN5VHl5L2hlL29wa2p6VU9t\nVzluZzdFNnRuL0dNUmtjZ3lOQTRCL1EKvvrXH1IxL4PVIZam2k9XRNBTLKahNCUh\nhMdfb4shNBtUs1bAiicJRPT1eAAWk4CWO5xpS3uJ0fODabrOozXdnw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJVHF0N2hHTHprQlpSYW8r\nMmpIZmZIT2QzNXYxTE4vc05wcXhTQzQ5clg0CktzRGFpeEVYMXA4RnV4TVdJNk04\nM3ltL2ZyczloR3NNWm01cE16NmJNemsKLS0tIDBHczRiUVhnZHlrTmdocmNQY2NK\naU5VYWZ4QWFuK0h4cUZGOGxUL3QzQ0kKtsuW7yl1/t7q9kUhTtK0G5G950Bi5n5w\n7cxX/pfMtgPhOh3NMoeuTxc9sH4pTIthRmaLVJ+GzEc4KsMJhOp+rA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLalFBanFCMWtaakVmQWNh\nc3Q2UmZ1OG1MOTNaTzFmcy9lbEFZdDZMSEVzCisrV3hMZndQekZtR3ZORjRkWHdm\nZG85M2Y1L2tPcWc1ZHpkd2R6TDJ2VXMKLS0tIEZ3Zmk0eWVsUTJwNHZJbWJhY3VJ\neVdxMVdqcTdxeUxhU0UzYThhOWhnc3MKOkedT3Tifi+6Q+C0ur1+TQuVwq75fAUa\n0cdXexCI2UIyLv+Ggbv1YIYcUiNeJNiF8JttpGAyOoVnUfIUcLsY9g==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2",
|
"recipient": "age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLK0Z5UHpwdTFRM3dNL2FC\najdScHp1R1pHM0ZyMk1reENnTFlnTldVNTJJCmxVcVY1OHlrWExIeSs4bTBwQklE\nU0NkUnVmdlVuOHcrWjJpRFU4WTc5ZlEKLS0tIFhheExxWHBIcDBqL290WEpJK0sw\nRTZKbzRWMmJhVVVGT3A1UWJQUE1QS3cKp+jmuHUvZKbPx+/gxQUSz7QV1jLuIzP5\ne1jkJ2rJT2i8snAvihd8bsjRSFmoUnEg6kV8f0OteezNbkZoNhd30Q==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4RDZ1K2RUaU4vTnFsbnpM\nRTRCUkg3RUFGS0pnK0NJSWxXTWVsaTZ3ZVhrCldDWkd4L0Y3Sm5uM0FZZnZqclJq\nUEpNRElGbEUwM0ZHRzJWNG0xT1ozZzAKLS0tIDBiOTRJSlRRbkxuRm9aTGVoZEoy\nU25iVjhxTXhvSTVqV2kwb2doMXNBeWcKK1wDpzC6aYSVJ/z0wGvSDjgXDiPeW+t7\ncgD9a1nCB/N1QZQn2IbnnkL6EsCuIQpRlzlLL9FhdRdLP+3ij+i8eg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzRmpkdloxdU1DRmF1Tzg4\nYSt3bks0Y21OQW5DS2JRU0ZMMHZJV2xLc0dRCmRORFliS3A0QTR1Uzc0ckd3cHA4\nRnNrdVBISG5NcjhrNDRoUnl4c2dPL1UKLS0tIHA5aW9GQkdXU0VNRHd6aEpoSzhJ\nSmd5OU1ESGJqMFVZdGhBMkdYTmlsRWsKLN36pDsdf06Rn9RLxfh46nX5u0dfyoe8\n/VvQiaWoj2/pv8NmwdFzdJQ0mTKkvEdxxY/Jk0YK+GQA/NGIVIIoWQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkN2kxR1BSUVBHSDhuYVVu\nREZGeHFNT1lUVGljMUpmV05FcHROdEcxK1hRCjhYYkJ1U0JaUkdRZG1tMXFudlRM\nSllqZVBsd3JDemFITVVlWkZ4Uis0NnMKLS0tIHRjWHFzZEgwSmlnWFVpQk1tcnJC\naytMVk92U3lGbCtWdXA2UDFXY29Ndk0KPmSHHP4Nyb4dkyz9a60OP5Lc8MlbPGxo\nLReOVEJ86yGbL4ARFptqrpcJ6ILEagWSYLEkqoZ1xiG1BSvs6J7dHg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2026-03-23T09:09:07Z",
|
"lastmodified": "2026-03-23T09:09:07Z",
|
||||||
"mac": "ENC[AES256_GCM,data:phFpHUzJ/7rd1k1fr9YFD2FplXV3Qv5zFni00fAgG2VtVoIdFYeNRE0EEh2ulnKcIXjB/5lZuMss2bIoBt4i46BB2ZHTpnWksbeHowdgkHL+eXT1F7b11S1y9NEKc/ug3jarPwyj3usmVQJlllAzANCQHGrYQdBrFXvFae3cH40=,iv:4v3k4q0SxyTvHoqr2Abf6OhAcANCT9oWTa5Kwlb5GCs=,tag:Hn+fUEmOu7fWc7SSBe5yfA==,type:str]",
|
"mac": "ENC[AES256_GCM,data:phFpHUzJ/7rd1k1fr9YFD2FplXV3Qv5zFni00fAgG2VtVoIdFYeNRE0EEh2ulnKcIXjB/5lZuMss2bIoBt4i46BB2ZHTpnWksbeHowdgkHL+eXT1F7b11S1y9NEKc/ug3jarPwyj3usmVQJlllAzANCQHGrYQdBrFXvFae3cH40=,iv:4v3k4q0SxyTvHoqr2Abf6OhAcANCT9oWTa5Kwlb5GCs=,tag:Hn+fUEmOu7fWc7SSBe5yfA==,type:str]",
|
||||||
|
"unencrypted_suffix": "_unencrypted",
|
||||||
"version": "3.12.2"
|
"version": "3.12.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
"age": [
|
"age": [
|
||||||
{
|
{
|
||||||
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhVVBSMm5hUmlnUUhrSmxL\nNVVZY2dZajlKSWMxZ3dMVlBORjNUaHBOTEZnCmNpNFRodDFFb2xNdnlYVHRiK2ZT\namV4YXFOd3FCK1ZiK0NIbW56Sm1wNm8KLS0tIHk5TVlxZHB4NzFiQTFQeThUY0JG\nV0huc2FzQU9WWUFJWUFNS3JoTzFaTjQK/T7aFSWnkpv1Qbx47LFp85bkaCOt5vrs\nLjiAGimUOVkr7ZcJz3540JWvBBUNNRKmM3QDNlgPg5luI0fa7+pNRQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3NmNaR1dvaXA4QUVqbkNP\nbFlpTzlHMXd0SGNsd0wyZ2FwZDFBR0tuaWxnClZuNzZma29BWURibzVUZndUc2hV\nZUpUdE94TC9Pa1dLQitLbE1qRXZJNVEKLS0tIG00ZGJyNHp0eEtQeDNsemErNVlo\nclBid2Y0TysyZ1RtK3F2RS92QjJJWDAKUruZmiTB5tkBF5VOO7dv+GijgAO6AVNe\n6t/xyot/Gc3WFOeNkYUk1K7fo0oLFfRG1tZBW+4cwFi/FMUpyjCxig==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSU3ZFZkZqUjcycmtYalRw\nYXlSQlFvcXFwS0xYQ3BVUXlPeDBHeUl0R1J3CkRGRHNaZWxQN1hISmh0VzNwZnlM\nbUFYVWw3dU5jNVorOVFKYUtyWHl5Q28KLS0tIGU1MkhrNHptZUZldHM1Y1FZTytV\nY0VvQjRmUmpIbW12WDlkLzVwSE9uZkkKMczm0x03kPRAD+pdXyDRTqaQckU4MKxg\nfIJAAwRAbskLF37SUzvefa0DCdKpyK876km7nOyIZunTE1j7xIwMNQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKcW5Ld3BjdnYvanJYeHM4\nNk1vS2o4WEg5Ni9aUlBuNmRKMHJpOHh3dTJnCnlhTFRDdXoyS3kyVEM4Ukc5N0pB\nazBwQlIycHliaEt0Unk3WUZtcURJRXcKLS0tIEpoVHlFLzBCSDdGRVZSeCs3SW1n\nK3k4T0VkeGhBd3NSYlNYT3JudXRQVWMKPu0HGvtYlgdih3vNrqvEvke0Fg7hr9xm\n1f3G7GpeRBLZlab6UKKzbFFgf0NADnGEBmWMP7e9taVYqYy1FFf7lQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnVE9tNEhSRUFydEhvL2tu\nbWVuVXhVYlhTVVFnMTZrOEFBOEZKZ1A5TFRjCnNSSGVjNmtYUnVsdGZRcjg5SmNW\nbys5alQxWVRRNS9rV1V5aU9nNEF5ZHMKLS0tIFl2MjgwclFZOEtvVmR5TDFzL0lm\nblBnekRPRzhqem1CSEgyM2YzTnJvck0KwITv/a+Z0XQ0FeI7rPti9IGZPuILWVhC\nTC0dWuJ3uSflAxgRvGpaQyvsKMLgkXCRf58kx17cHjPT+Z8EsXeBSQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQUFgzR1hFemRNeHorN0Fm\nNld4eWhwMWJHdWhBYVQxNUtGemlEeU5jcUcwCldlSENWSXBxYjN6TXZUM2Nuc1Mr\nN1Zlc0lWY29KcGI0bWVwYzVnS3ZBM2MKLS0tIE1rVnhhNFJkeFZjeDh0RVM3eHU5\ndkJPZm1xQTdWZTdXNVJrdHpXV1dIWVEKZlyGzrce2W4M8LVDbYGXIpK+cVqqB86t\nqibOGTNdSAhd2Y+IWb2FdPr0uxoixC4j6Mk+Nw2bXhDKXp+VAAlWog==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2",
|
"recipient": "age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxdEpHdzlVbDdBcWJyNDJC\nQnpTaFZLMno1Q0ZJcXVjMUIvcTZ0K3lDY0RzClJlbHhqbWNVemFpRFh2WXRGV1VZ\nRENTV1ppN0J5SVFDdUR1aDRRdTFKUUUKLS0tIGRFMGIwVkliRitaeXdHTm55QzQy\neGdzYStQalVFb3ZPdkp2VFJ5SUJ6RkkKeeOJ1MjTKqevHHl+5dXL8n5o05KV6HvS\nMf5yO3rxYDLzO5ore63G3KjqCS9i36mTzLoyJgYIKQK4IAh/AKcI/A==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKN0x6QnJCZklFTis0QVJE\nbWdJZmxJWmxRYUtNdmFmaHM4bTFQOGZENVY0CnkxbW5Qd3lQTHlNV3dEWHJVS0Qr\nNUhDMzBmdzI2dzNGY3J2dVJwd0wzYXcKLS0tIEVjb3JNODY2ckNUZDVtN0VYaTNm\nSnZWRUpFQkFXWWRBVVNVcUVNYjRxb2MKGa0tBfwyEWrXmkCIupwHID2j357UMiSe\nsg70OdmszMZ+MDjcLIXVkjQfrLTbtIKU+u3jA7MDzECZTm+nAk8cTg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxZE1lU0UzUFQ5Z1ZQRXBj\nbktnN0lWNXZ0QVhPS1Z5cFNPeDJlVCtLdWlvCmFPSHdkeUlONHptbE0xcjg5SUQ2\ncnZKY0JWY0haZFEzcWNnUHdnN250WmMKLS0tIEhlbG91K0tabmVVSDhBeStoUU5j\ncFRlUk5xZjRRVC93UzNJUUhhTVQySlEKB2uBSMXOJd1ufB3i66ldhXlnbquWcXgi\nXjuJb5ud4Nz97wlSnqAADoY8V9aYJM30byL4VJeXiMq1oppDptbQzQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4YTdqUXp3eVdmV1drQ00v\nMkxFUEIrdTBoRDREbndMc2hkekdWZDlSSFZnCndmMmtvTDRpRjNvUENQaVY3S29k\nRGFaUStJRmlSSEJxMG82Nm1Oc0puOU0KLS0tIFdUdEZNR2tZdlBoTFhjK0pNNnNW\nVGZIRytNNnFOQXZMTlhHMDRMUnJ6MG8KDaPfk8dcE3ijfwPhbeN909I6zPdjxX1M\nFnQiSGQuKvWuVzn2qjl8AAFxw1nVO/3l+7eu/PN2yeKIb3rMUvWpDQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2026-03-01T17:47:46Z",
|
"lastmodified": "2026-03-01T17:47:46Z",
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
"age": [
|
"age": [
|
||||||
{
|
{
|
||||||
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2UDczc281UGU2aTlHeEp5\naEdiZGgzK01VODE4enMrRTIzNmNwa0srRm1rCnd3K1NnOEpXVDJHWGp4VXhFTUJr\nM1c5cXVza3NQOTZjTElTcFRhY0ZDTE0KLS0tIGp1Y3d0dXg3NnBnQmpmeXI4a2NQ\nZ1lIU1hCMUJMR3lidkxRNWV6SzJkeGsK93sF6uCKKFh12hnlSZ9DMxBv8/j0LIp5\nMGeUbbX3sWdk4I04QjXl2Yi9ER5d9W3zDfrQ1u5CqM3IqSPHQ7VgpA==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2UGRKeHloRTVjcHUyOGJ3\nM3FKajJTZXE1d2pnUXEwa25BMytSZjlZV0YwCjFBUjhtUDFRckcxK20zcmxpOVdX\neGhVaC9jaHJuSm9tRktZVlFLTk5yS1EKLS0tIG1CRkdhVW9LSU9sY3dRUS85eHFU\nRnpxdVg3dzM1bldQS0JQY2hYbkhXSVEKREVnO8OsmWfrJ19Vr7KY3O97XG2LXrSP\nxvGOZIDMI2UIfTFWm5TcFDOOD34HV0fWtzjn9GYSx9XN5fQX1YK5vQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPcE55WTAxSERXdUZudmxJ\nODQzaWFBRXl4Ly93MjM3K211OXBtL3A1SUZRCjBjUnRmL0FVdXgvWExsM1E5bUhs\neHAvcEwvUmxDeWFoMWJ4RDQ2VEpzcGMKLS0tIHJUNWE3Z3drMVYwSkV4Tll5emxN\nc3VnZFllaTJLckE1M2ZYaE4vdFNTSGsKvQhxtlSjH9+tjaT77ZiuMQeb0RPotSeS\ncoYf0R8TCvy8c2CP0YYs99bIJP1zx4RirlC/80Ji9eXBYkJaoDRkew==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3bzdOOWRzMm9BOVNoaTkz\nbW1YZWZjVkF1MHhMcy9nTFhPUjdpamRLZmprCmtIK0VxNVNSR1MrbGlqakZzV3Jw\ndE8yZ2lyOE92MStpRWExUENDSGNCbHcKLS0tIGMyS05FUlk1a2N3WmFQcGdpZytD\nRWxQc0hucmxCK2psSzMrWmt4cTlxMGsK95lvBRK4daCbixLEJkEToAg7/yL2iJ+j\newP0caUe3E9UyhuFmZCiN9VsYaQy0q12KcSTq/KMybj6UmDThaOMRw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMS3dYenBFalBySUJKcDZl\nQXRBMTFXN0tCQTM1bFl2SDNma0xRZnBJbG5nCm5hTXlIZVVpREpLUUoyRitnWWZJ\nZ2VPSFBBK2h1aFZldGRNZm9JVDRvd2cKLS0tIEg5cHgrRE1sS0lFZkxSNHdweXJz\nb3p3Y1lZUjBxYWUxZjNBbDlFUkd6VVUKLaUOi7OESO8yTZyBcgOt0LhjM6QKMwlm\nl6MSVJYBtmcp4wdZdaCsiC28dlHg98qXauLppgnkda8LyhDUliP5lQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByTnVqbkNSbW1nNUxpNlNQ\nekRWWEJBeHdmMG1jYk0xeGNUMnBlSk5xNVRnCmNhTlZEcGtUbnlNaU12MGpVVDhp\nOHRRbkVBZXg1bVZiNmtXVHlxU0dDL28KLS0tIDRhV2R3akMzZHFZcytwSHJ3QU9I\namhWREJHZGcvMk9DeUdsb3FtOW1wUzQKhRDjz4lv9BPjOl0ZUstNlMVAw5x2Dgql\nQ06h5a1qm6YqktDvJLiKiUA64ZqDFHvB61x5qVn0Wc913vLayoEIwQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2",
|
"recipient": "age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkUTJEcFp4dWxzR3BuRnJw\nNy9vcStGT3ZnOHBYczZSUHgvN2Fzc0MzaG1nCjdCNXRnTHN0YUZZKzBPVmI0UTBn\nbnRNZGxyM0tMSW9HVG1yMmxQeUFXUHMKLS0tIEYrOTJMWlZndHNxeHA4U0ZFajJM\nclRPdVAzWThwNGRpSzJkU0pxY2llbnMKpMQuw76xRJ162EJ91ui6jLNeBY6+XCiG\npKJB9YCTnh+JlxFzm9LU5s8bI4XzsywdrdKMYck1G4A8NW4MoQCrig==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFdmIzR1pjNnBnckpEMzcx\naXhyZHNXNUZ6SFdnSFRoWWIzUVFFNExvSXdFCkNXQXhDY0h3UURPRlJSeGFrVC9B\nblFrTitZVllxYmVwbEZRSk8xelpYY3cKLS0tIExkeVlMNWtjZ2VkL1AreTRHUXNj\nYS9LNTNLd3BhUlpNdWp3UUdNQmhLYkkKpYAbuft1WSROAm+3iGvU1TRhBP3HgiB8\nuDOdv9NTw5AhhTK2VIixhJHZI3gIAvCwndmQWV41PDgoDqmeVwxrsg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMWnYzbWVNM081WnJ2MHh2\nbE56TUZDU1JqdkJHczVaUi9ReTFsNENRdlFnCnArZEYrcmtIMFZEZVhUcG9MdWNO\ndVRNS0w3S2FqMzNkOGVqcTJwTFQyK0EKLS0tIDRnSjBaRC9xd0ZsUy9CWm13MWZu\nTXQ1WEdZR2h0UGM0cmZOMFZwdzdzd28Kv+KkGEfWvQVgOtiJMqEwbIgQcQI9U4fC\ngh+9QrN8blwbt0OVqyu9tPWrP9bPOEhM6U13wj4Q8BqzrNVsLix4Lg==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByVDBtZzJibHNpV01WUTF3\nWm1OajJnVjF6TFluK05UWXptdWJFekY2Wng0CnliUGhmTHZZUHNRY0piM0ZXT3J6\nc2puem5VbVczOVlKZ3RqM084N3JCMEEKLS0tIHppbHdvYk1LTXRMeXp1eEZYeGd1\nT0FJZlNJNnAvQWNGcnBCdnBNTTg4UzAKTwMtaAQk5/8qGO4M3kmjfP8yJmrDiWiJ\nsD23c6S7wwAZdltK1spIRMkSS2AhJBN+ePXBiAGWjatSWsBKlDZqww==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2026-03-13T17:29:46Z",
|
"lastmodified": "2026-03-13T17:29:46Z",
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
"age": [
|
"age": [
|
||||||
{
|
{
|
||||||
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
"recipient": "age1xate984yhl9qk9d4q99pyxmzz48sq56nfhu8weyzkgum4ed5tc5shjmrs7",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqMHVFbUFpOGdXc0t4Q2dj\na1lxeWFBR3ROTDN6RVlwYlgxZmdhd1ozNmdvCnVpZFFnaGFqWGs3UmRtZytlUEZK\nK05lM2ttWmNOSGU5ZlBTYWZ6K0dCbzgKLS0tIEpHQXRmaVVhbXJRRUI4REdCZWI5\nTmFDY1gvWVVkUExpeWYxTjlCb3MwUUUKnHzWgaUvDXH1I3TPyY38h9Pbjqk4Whma\n8ctECOpg1obtMr+a9Bdw11IPwAe3R9K0ZfE681HroETCHRxw2+38yw==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDMWRWUElvQ3ZRTjFKRVQ3\nYmZINCt2eWJBbWcvLzQvWWlURlpzMldSWkZFCnhidzFMZjliUkt0MUVML0pLQ21L\nQ0pwL2pteEFlaW0wRFJBZk9BSHRXa3cKLS0tIEc1dXlNdDQxUFZrVUc1Z0VBMHQ1\ncXNaYnd5dVVvTU41bTRnRUdGVjEzczAKjfqq9yciDRBW+N2M+5mRRztlW5+JRL0n\nRL5aZlsDVo3SJAxjaaGx4zgwN7dUX6JPrTGW6sYd5LCGuHZWX8phfQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
"recipient": "age1njjegjjdqzfnrr54f536yl4lduqgna3wuv7ef6vtl9jw5cju0grsgy62tm",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFRU43QXpWb1JDUVJCck9z\nNkFXWXdWY3pJZmx0Mjc5SDgwcVFXWkRua3pVCjAxQkJBUXF5T3hxek00ZzhRcmF2\nb2tWQlYwVXpiM1dMRFdqNXIyQjRhb1UKLS0tIDB2Q003YjlCTXUxa2k5RmMrWVds\neXhLSzViMHl6Smo3dDljRnRsT3lRb1EKKxaXLegA0V6vTnYF7l7MsJD42XWidB/h\nGiOojZ6r3JVV4Wx4Xl/MPk7lYvYN9VH//PUlA7h0Q9iVaQS+HA+aZw==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJNXBjRGdmWGFEMmY3T0F3\nS2lFcXRKWnl5T0JnZkRxTzJUK0FlWlIvRVNvClVESkhEdFgzZnhKTTdaZEd3N3Yr\nWWJYTWI2M2Mwd3F3ZWdJVkdLMWwrRlkKLS0tIFFwcEdQUVA1dUFRRUtkUDN5RUZt\nTjlQNEx1ei9UeVpRTjcxL2t5NVBUajAKaZOQ1GQ3vtgZdxxoXQKU5Q3jSUnakW9F\n6bHKbhBGSFwCb3u9+mgVaefBU11vT1ue1kA8sCM03MkYBmM+8cPv7g==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
"recipient": "age187jl7e4k9n4guygkmpuqzeh0wenefwrfkpvuyhvwjrjwxqpzassqq3x67j",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBob0MwUkJvRDRnQ05XMVRh\nODY5WE8wVlBkTW8xWUlLWUwxNHV6Y0FJTW5zCkdVV1dJTGlxREdGbWowak1HL3pH\nejNKV0VvejRadTVCeVdxdFkyMk0yOG8KLS0tIEllWldkaXZ1TzYzSmFoQ21nMkV4\nZlFxN0wxWlpvSHdreTdxQ1NZcit0dGsK+23q1QS5L1JzqFcKUygqfmYc64qVOO1R\nSiGa7O7ZoRMnn0Zfjas3K+byJ4PzNitEEU64s1518L/e78oHKQ9vVQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2a01mMmNPckZTbmJvQUVC\ncDBrVCtlRmpJMVByeE5zWFMrUCtHSkdDRFNBCmpZazA4Q0duejNYcmoxWDVMR3A5\nclh5OXZNNWd0VjI3cGlWbk5JTUw5NHcKLS0tIEVma1VsQ3cwSzdGZTlpanA2ZWNF\nQ2xLSjNkdjJyby95aTdTYk9HSHFvM1EK29MPNiB5GKqBFPgLcIp1giWzYRpPZ7ur\nDSKqvZ4kbEyxgdLxJ/i2P2iv4/4bb14LWQno9iEXsVeZ/iKf1mDigg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1ez6j3r5wdp0tjy7n5qzv5vfakdc2nh2zeu388zu7a80l0thv052syxq5e2",
|
"recipient": "age1f9h725ewwwwwkelnrvdvrurg6fcsn3zxrxdt0v6v8ys0nzngcsvqu77nc8",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaakJHOXRxeGRLZldZVmVi\nNHpFNmtYU1BCUnVKR1I3ZC9CSW5ORXlCbG5JCnpyUFA5NDNzbExob0s2R1EybzVJ\nb2tqSWtmZk4zQ1RZQmhKUmFvTFhTUjgKLS0tIG1DV04zMzVXdk9yQ1FFQzZsakM1\nTXQ0dCsrN0Z5RUVRamJUZEo5UmRiZWsK/av25ulEhPih+AK2rnktJsK6/SYS4IDx\nBuI2hBRZTdw1m4bBcCwMkLn/F1Rxd37xI1NZKKE3+CgnIs5G9XxhAw==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBteGpDZkpLcFIyVzNMbXFV\nMlY4SExrTThkdEZJczdLdlVwUWpVUWVuTUJvCmFXVG1ESHlIOExSdFJJOXhtb1JZ\nSVBocEtJTjRkckNwYktOdEdBQVQ5TVkKLS0tIE9iZ1pzMGhVc3F4THJwb2pFK2dm\nWnZ0SkhyNFMyQ1VVa0tWbDlXR1ZwK0EKPJq69mAeq3ghUpY+VuS+xCKeJVwmYnGm\nQ8mtmk/5skqbeOSKAbIiEEY5avPRy+Uy3YTD7g6vpSCqnpNSLEc/qg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
"recipient": "age1tlymdmaukhwupzrhszspp26lgd8s64rw4vu9lwc7gsgrjm78095s9fe9l3",
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEV1dtckt6Wi9HQ3Fxd0Ev\nRnRzcWs5SWRmNEpYbmZQTnEzbnliVDRkZ3pnCjUyTEFOYjd5SC9STVd2V1o0NGVR\nelphZE1ISGlkemdXSTBlcURDYUh3OGsKLS0tIHUxZFRKbVFsM0FWZ2ZEa0FaYjl5\nTWhTMnptYU4xNmp4aVNYMDRORkk5NVUKiwwbLVe3mtVe9sgeSA/FUhkowfFeirbA\nXXL9ct+lizSNXsFG7w3xpZsEaNGbHF28maZHWOpZotKRbdx4w6UJGQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIZENwNHhLdzNYYmEvOHNW\ndEZJbVpUMGJyaVU5WkR0bUc0NzlsMWtmdjN3ClMyM2dGa3BlVTFqeDB6ZHRGSTNu\nREZSN0JXUkU4ektnWis0L3lCOHdpTmMKLS0tIGQxZTFRYjYvMS9uM2lYUThwYmtp\nbkYrTlNQeEd6aVNTY25aMHFVbnJXSWMKulwDyWezqDUIlv/aHMMGzGqOFU3VGaw3\nYvm/e2wFWPenFH0gfALkdC8upRghE8r9jkXcj1pSmDBbfjNghz+2oQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"lastmodified": "2025-12-20T21:46:17Z",
|
"lastmodified": "2025-12-20T21:46:17Z",
|
||||||
|
|||||||
Reference in New Issue
Block a user