Compare commits
16 Commits
4bc5df11c4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e827a10680 | |||
| b8cb8908e7 | |||
| e8b2dfda36 | |||
| 42016cda27 | |||
| 2c5e64039a | |||
| 7e7b884cc6 | |||
| af91bad87b | |||
| 7d89dac788 | |||
| 824232aaa7 | |||
| f6d8485817 | |||
| 1f3f0f468b | |||
| 3d3213d61b | |||
| eba219c8e1 | |||
| 3ddbedc2cc | |||
| 24079b7694 | |||
| f27894bb2f |
48
.agents/skills/caveman/README.md
Normal file
48
.agents/skills/caveman/README.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# caveman
|
||||||
|
|
||||||
|
Talk like smart caveman. Same brain, fewer tokens.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
Compress every model response to caveman-style prose. Drops articles, filler, pleasantries, and hedging. Keeps every technical detail, code block, error string, and symbol exact. Cuts 65% of output tokens (measured) with full accuracy preserved. Mode persists for the whole session until changed or stopped.
|
||||||
|
|
||||||
|
Six intensity levels:
|
||||||
|
|
||||||
|
| Level | What change |
|
||||||
|
|-------|-------------|
|
||||||
|
| `lite` | Drop filler/hedging. Sentences stay full. Professional but tight. |
|
||||||
|
| `full` | Default. Drop articles, fragments OK, short synonyms. |
|
||||||
|
| `ultra` | Bare fragments. Abbreviations (DB, auth, fn). Arrows for causality. |
|
||||||
|
| `wenyan-lite` | Classical Chinese register, light compression. |
|
||||||
|
| `wenyan-full` | Maximum 文言文. 80-90% character reduction. |
|
||||||
|
| `wenyan-ultra` | Extreme classical compression. |
|
||||||
|
|
||||||
|
Auto-clarity rule: caveman drops to normal prose for security warnings, irreversible-action confirmations, multi-step sequences where fragment ambiguity risks misread, and when user repeats a question. Resumes after the clear part.
|
||||||
|
|
||||||
|
## How to invoke
|
||||||
|
|
||||||
|
```
|
||||||
|
/caveman # full mode (default)
|
||||||
|
/caveman lite # lighter compression
|
||||||
|
/caveman ultra # extreme compression
|
||||||
|
/caveman wenyan # classical Chinese
|
||||||
|
stop caveman # back to normal prose
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example output
|
||||||
|
|
||||||
|
Question: "Why does my React component re-render?"
|
||||||
|
|
||||||
|
Normal prose:
|
||||||
|
> Your component re-renders because you create a new object reference each render. Wrapping it in `useMemo` will fix the issue.
|
||||||
|
|
||||||
|
Caveman (full):
|
||||||
|
> New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`.
|
||||||
|
|
||||||
|
Caveman (ultra):
|
||||||
|
> Inline obj prop → new ref → re-render. `useMemo`.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
- [`SKILL.md`](./SKILL.md) — full LLM-facing instructions
|
||||||
|
- [Caveman README](../../README.md) — repo overview, install, benchmarks
|
||||||
88
.agents/skills/caveman/SKILL.md
Normal file
88
.agents/skills/caveman/SKILL.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
name: caveman
|
||||||
|
description: >
|
||||||
|
Ultra-compressed communication mode. Cuts output tokens 65% (measured) by speaking like caveman
|
||||||
|
while keeping full technical accuracy. Supports intensity levels: lite, full (default), ultra,
|
||||||
|
wenyan-lite, wenyan-full, wenyan-ultra.
|
||||||
|
Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens",
|
||||||
|
"be brief", or invokes /caveman. Also auto-triggers when token efficiency is requested.
|
||||||
|
---
|
||||||
|
|
||||||
|
Respond terse like smart caveman. All technical substance stay. Only fluff die.
|
||||||
|
|
||||||
|
## Persistence
|
||||||
|
|
||||||
|
ACTIVE EVERY RESPONSE. No revert after many turns. No filler drift. Still active if unsure. Off only: "stop caveman" / "normal mode".
|
||||||
|
|
||||||
|
Default: **full**. Switch: `/caveman lite|full|ultra|wenyan-lite|wenyan-full|wenyan-ultra|off`.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
Drop: articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries (sure/certainly/of course/happy to), hedging. Fragments OK. Short synonyms (big not extensive, fix not "implement a solution for"). No tool-call narration, no decorative tables/emoji, no dumping long raw error logs unless asked — quote shortest decisive line. Standard well-known tech acronyms OK (DB/API/HTTP); never invent new abbreviations (cfg/impl/req/res/fn) — tokenizer split them same as full word: zero token saved, reader still decode. Full word cheaper AND clearer. No causal arrows (→) either — own token, save nothing. Technical terms exact. Code blocks unchanged. Errors quoted exact.
|
||||||
|
|
||||||
|
Never drop not/never/no/only/except — flip meaning worse than any token saved. Numbers, units exact.
|
||||||
|
|
||||||
|
Tool calls: fire direct. No preamble, plan, or progress note before or between calls. After result: next call direct or final answer — never announce next call. Text before call only to clarify, warn security/irreversible, or resolve ambiguity.
|
||||||
|
|
||||||
|
Preserve user's dominant language exactly — reply in the language user writes, never switch regardless of example text or multilingual context elsewhere. Compress the style, not the language. Every emitted line in that language — openings, pre-tool status lines, all — not just final reply. ALWAYS keep technical terms, code, API names, CLI commands, commit-type keywords (feat/fix/...), and exact error strings verbatim — unless user explicitly ask for translation.
|
||||||
|
|
||||||
|
'Drop articles' = article languages only. Where small markers carry case/role (particles, postpositions), keep them — grammar, not filler; compress politeness/filler instead.
|
||||||
|
|
||||||
|
No self-reference. Never name or announce the style. No "caveman mode on", "me caveman think", no third-person caveman tags. Output caveman-only — never normal answer plus "Caveman:" recap. Exception: user explicitly ask what the mode is.
|
||||||
|
|
||||||
|
Pattern: `[thing] [action] [reason]. [next step].`
|
||||||
|
|
||||||
|
Not: "Sure! I'd be happy to help you with that. The issue you're experiencing is likely caused by..."
|
||||||
|
Yes: "Bug in auth middleware. Token expiry check use `<` not `<=`. Fix:"
|
||||||
|
|
||||||
|
## Intensity
|
||||||
|
|
||||||
|
| Level | What change |
|
||||||
|
|-------|------------|
|
||||||
|
| **lite** | No filler/hedging. Keep articles + full sentences. Professional but tight |
|
||||||
|
| **full** | Drop articles, fragments OK, short synonyms. Classic caveman. No tool-call narration, no decorative tables/emoji, no long raw error-log dumps unless asked. Standard acronyms OK; no invented abbreviations |
|
||||||
|
| **ultra** | Strip conjunctions when cause-then-effect stay unambiguous. One word when one word enough. State each fact once. NO prose abbreviations (cfg/impl/req/res/fn/auth), NO arrows (X → Y) — measured zero token saving under tokenizer, cost decode clarity. Code symbols, function names, API names, error strings: never touch |
|
||||||
|
| **wenyan-lite** | Semi-classical. Drop filler/hedging but keep grammar structure, classical register |
|
||||||
|
| **wenyan-full** | Maximum classical terseness. Fully 文言文. 80-90% character reduction — chars, not tokens. Classical sentence patterns, verbs precede objects, subjects often omitted, classical particles (之/乃/為/其) |
|
||||||
|
| **wenyan-ultra** | Extreme abbreviation while keeping classical Chinese feel. Maximum compression, ultra terse |
|
||||||
|
|
||||||
|
Example — "Why React component re-render?"
|
||||||
|
- lite: "Your component re-renders because you create a new object reference each render. Wrap it in `useMemo`."
|
||||||
|
- full: "New object ref each render. Inline object prop = new ref = re-render. Wrap in `useMemo`."
|
||||||
|
- ultra: "Inline obj prop, new ref, re-render. `useMemo`."
|
||||||
|
- wenyan-lite: "組件頻重繪,以每繪新生對象參照故。以 useMemo 包之。"
|
||||||
|
- wenyan-full: "每繪新生對象參照,故重繪;以 useMemo 包之則免。"
|
||||||
|
- wenyan-ultra: "新參照則重繪。useMemo 包之。"
|
||||||
|
|
||||||
|
Example — "Explain database connection pooling."
|
||||||
|
- lite: "Connection pooling reuses open connections instead of creating new ones per request. Avoids repeated handshake overhead."
|
||||||
|
- full: "Pool reuse open DB connections. No new connection per request. Skip handshake overhead."
|
||||||
|
- ultra: "Pool reuse open DB connections. No per-request handshake."
|
||||||
|
- wenyan-full: "池蓄已開之連,不逐請而新開,省握手之費。"
|
||||||
|
- wenyan-ultra: "池蓄連,免逐請新開,省握手。"
|
||||||
|
|
||||||
|
Classical chars = wenyan modes only. Never swap a word to a classical char to shrink at non-wenyan levels.
|
||||||
|
|
||||||
|
## Auto-Clarity
|
||||||
|
|
||||||
|
Drop caveman when:
|
||||||
|
- Security warnings
|
||||||
|
- Irreversible action confirmations
|
||||||
|
- Multi-step sequences where fragment order or omitted conjunctions risk misread
|
||||||
|
- Compression itself creates technical ambiguity (e.g., `"migrate table drop column backup first"` — order unclear without articles/conjunctions)
|
||||||
|
- User asks to clarify or repeats question
|
||||||
|
|
||||||
|
Resume caveman after clear part done.
|
||||||
|
|
||||||
|
Example shows FORMAT only — write warning in session language, not example's.
|
||||||
|
|
||||||
|
Example — destructive op:
|
||||||
|
> **Warning:** This will permanently delete all rows in the `users` table and cannot be undone.
|
||||||
|
> ```sql
|
||||||
|
> DROP TABLE users;
|
||||||
|
> ```
|
||||||
|
> Caveman resume. Verify backup exist first.
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
Persisted outside chat: write normal prose — code, comments, commits, docs, issue/PR/MR text, memory files, third-party messages (/caveman-compress exempt). "stop caveman" or "normal mode": revert. Level persist until changed or session end.
|
||||||
67
.agents/skills/karpathy-guidelines/SKILL.md
Normal file
67
.agents/skills/karpathy-guidelines/SKILL.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
name: karpathy-guidelines
|
||||||
|
description: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.
|
||||||
|
license: MIT
|
||||||
|
---
|
||||||
|
|
||||||
|
# Karpathy Guidelines
|
||||||
|
|
||||||
|
Behavioral guidelines to reduce common LLM coding mistakes, derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls.
|
||||||
|
|
||||||
|
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
|
||||||
|
|
||||||
|
## 1. Think Before Coding
|
||||||
|
|
||||||
|
**Don't assume. Don't hide confusion. Surface tradeoffs.**
|
||||||
|
|
||||||
|
Before implementing:
|
||||||
|
- State your assumptions explicitly. If uncertain, ask.
|
||||||
|
- If multiple interpretations exist, present them - don't pick silently.
|
||||||
|
- If a simpler approach exists, say so. Push back when warranted.
|
||||||
|
- If something is unclear, stop. Name what's confusing. Ask.
|
||||||
|
|
||||||
|
## 2. Simplicity First
|
||||||
|
|
||||||
|
**Minimum code that solves the problem. Nothing speculative.**
|
||||||
|
|
||||||
|
- No features beyond what was asked.
|
||||||
|
- No abstractions for single-use code.
|
||||||
|
- No "flexibility" or "configurability" that wasn't requested.
|
||||||
|
- No error handling for impossible scenarios.
|
||||||
|
- If you write 200 lines and it could be 50, rewrite it.
|
||||||
|
|
||||||
|
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
|
||||||
|
|
||||||
|
## 3. Surgical Changes
|
||||||
|
|
||||||
|
**Touch only what you must. Clean up only your own mess.**
|
||||||
|
|
||||||
|
When editing existing code:
|
||||||
|
- Don't "improve" adjacent code, comments, or formatting.
|
||||||
|
- Don't refactor things that aren't broken.
|
||||||
|
- Match existing style, even if you'd do it differently.
|
||||||
|
- If you notice unrelated dead code, mention it - don't delete it.
|
||||||
|
|
||||||
|
When your changes create orphans:
|
||||||
|
- Remove imports/variables/functions that YOUR changes made unused.
|
||||||
|
- Don't remove pre-existing dead code unless asked.
|
||||||
|
|
||||||
|
The test: Every changed line should trace directly to the user's request.
|
||||||
|
|
||||||
|
## 4. Goal-Driven Execution
|
||||||
|
|
||||||
|
**Define success criteria. Loop until verified.**
|
||||||
|
|
||||||
|
Transform tasks into verifiable goals:
|
||||||
|
- "Add validation" → "Write tests for invalid inputs, then make them pass"
|
||||||
|
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
|
||||||
|
- "Refactor X" → "Ensure tests pass before and after"
|
||||||
|
|
||||||
|
For multi-step tasks, state a brief plan:
|
||||||
|
```
|
||||||
|
1. [Step] → verify: [check]
|
||||||
|
2. [Step] → verify: [check]
|
||||||
|
3. [Step] → verify: [check]
|
||||||
|
```
|
||||||
|
|
||||||
|
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
{"_type":"issue","id":"nix-overlay-6y6","title":"Add Loop corporate messenger package","description":"Add Loop - Corporate messenger for your team. Distributed as x86-64 binary from https://artifacts.wilix.dev/repository/loop-files/loop-6.0.3/loop-desktop-6.0.3-linux-x64.tar.gz","status":"closed","priority":2,"issue_type":"feature","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-29T16:41:37Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-29T16:51:32Z","started_at":"2026-05-29T16:42:02Z","closed_at":"2026-05-29T16:51:32Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-dv3","title":"Fix Config screen crash on F2","description":"F2 opens ConfigScreen then Textual raises InvalidSelectValueError because _refresh_aggregator_dropdown assigns Select.BLANK, resolved as False, instead of clearing selection.\\n\\nAcceptance: Config screen opens with saved consensus configuration; regression covers no selected aggregator; targeted tests pass.","status":"in_progress","priority":1,"issue_type":"bug","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-20T11:34:03Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-20T11:34:07Z","started_at":"2026-08-20T11:34:07Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-cdt","title":"radar-1.6.1","description":"update package radar to v1.6.1","status":"closed","priority":2,"issue_type":"task","owner":"alex@millerson.name","created_at":"2026-05-17T12:41:54Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-17T13:03:38Z","closed_at":"2026-05-17T13:03:38Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-a9m","title":"Fix haivemind startup after MainScreen mount","description":"Restore deferred engine startup while preserving MainScreen widget lookup fix.","status":"closed","priority":1,"issue_type":"bug","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-20T11:20:36Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-20T11:21:43Z","started_at":"2026-08-20T11:20:43Z","closed_at":"2026-08-20T11:21:43Z","close_reason":"Restored engine startup after MainScreen mount and verified package build.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-27z","title":"freebuff","description":"В данный nixos overlay репозиторй необходимо добавить новый пакет https://www.npmjs.com/package/freebuff .\nИспользуй mcp: nixos, karpathy-guidelines и Sequential Thinking для планирования шаг за шагом задачи. Управление тасками используй beads. Разбей задачу на подзадачи, используя beads с указанием parent task.\n\nRequired Skills\ncaveman,karpathy-guidelines,nix,nix-flakes","status":"closed","priority":2,"issue_type":"feature","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-11T16:11:44Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T17:03:53Z","started_at":"2026-05-11T16:17:34Z","closed_at":"2026-05-11T17:03:53Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-q00","title":"Add haivemind package","description":"Package https://github.com/dev-boz/haivemind in the Nix overlay, document it, validate the build, and complete repository workflow.","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-08T16:32:37Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-08T16:36:41Z","started_at":"2026-08-08T16:33:00Z","closed_at":"2026-08-08T16:36:41Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-qlc.5","title":"Update package metadata and updateScript","description":"Remove binaryNativeCode sourceProvenance, update meta, adjust updateScript for source build","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-11T13:51:22Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T15:01:06Z","started_at":"2026-05-11T14:59:33Z","closed_at":"2026-05-11T15:01:06Z","close_reason":"Closed","dependencies":[{"issue_id":"nix-overlay-qlc.5","depends_on_id":"nix-overlay-qlc","type":"parent-child","created_at":"2026-05-11T16:51:21Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-67e","title":"Add traycer package","description":"Add new package for traycer from https://github.com/traycerai/traycer. Steps: research repo build system, create packages/traycer/, stage with git add, test nix build, update README.","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-07T08:59:25Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-07T09:22:07Z","started_at":"2026-08-07T09:00:29Z","closed_at":"2026-08-07T09:22:07Z","close_reason":"Traycer package added, built, pushed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-qlc.4","title":"Test build and verify functionality","description":"Build radar from source and verify it runs correctly","status":"closed","priority":2,"issue_type":"task","owner":"alex@millerson.name","created_at":"2026-05-11T13:51:11Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T14:59:55Z","closed_at":"2026-05-11T14:59:55Z","close_reason":"Closed","dependencies":[{"issue_id":"nix-overlay-qlc.4","depends_on_id":"nix-overlay-qlc","type":"parent-child","created_at":"2026-05-11T16:51:10Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-2gf","title":"Update all packages to latest versions","description":"## Why\\nUser request: update every package in the overlay to its latest upstream version.\\n\\n## What\\nBump version + src hash (and cargoHash for Rust) in each packages/\u003cname\u003e/package.nix, update README table if needed, verify builds.\\n\\n## Acceptance\\n- Every package builds with nix build .#\u003cname\u003e\\n- README reflects new versions\\n- Changes committed and pushed","notes":"All packages updated and built successfully. Commit 1f3f0f468bdd on local main. PUSH BLOCKED: git.millerson.name:22002 and DoltHub unreachable from this network (SSH connect timeout). Re-run git push + bd dolt push when network is back, then close.","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-07T07:22:50Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-07T13:17:34Z","started_at":"2026-08-07T07:22:55Z","closed_at":"2026-08-07T13:17:34Z","close_reason":"All packages updated to latest versions, verified building, pushed to origin","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-qlc.3","title":"Handle go:embed frontend assets","description":"Ensure frontend assets are copied to internal/static/dist before Go build so go:embed works correctly","status":"closed","priority":2,"issue_type":"task","owner":"alex@millerson.name","created_at":"2026-05-11T13:51:02Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T14:59:55Z","closed_at":"2026-05-11T14:59:55Z","close_reason":"Closed","dependencies":[{"issue_id":"nix-overlay-qlc.3","depends_on_id":"nix-overlay-qlc","type":"parent-child","created_at":"2026-05-11T16:51:02Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-9xs","title":"Update all packages to latest versions","description":"Update every package in packages/ to its latest upstream version, refresh source hashes and cargoHashes, verify builds, update README.","status":"in_progress","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-07T05:45:16Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-07T05:45:22Z","started_at":"2026-08-07T05:45:22Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-qlc.2","title":"Configure npm dependencies for frontend build","description":"Set up npmDependencies hash for the Vite/React frontend build within buildGoModule","status":"closed","priority":2,"issue_type":"task","owner":"alex@millerson.name","created_at":"2026-05-11T13:50:53Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T14:59:55Z","closed_at":"2026-05-11T14:59:55Z","close_reason":"Closed","dependencies":[{"issue_id":"nix-overlay-qlc.2","depends_on_id":"nix-overlay-qlc","type":"parent-child","created_at":"2026-05-11T16:50:52Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-f8c","title":"Add nftablesbuilder package","description":"Package NftablesBuilder (github.com/AiseBouma/NftablesBuilder) web interface to manage nftables. Upstream source is incomplete (missing settings crate, no GUI build tooling, no Cargo.lock) so: patch in authored settings crate (schema from release artifacts), build Rust workspace from pinned commit, reuse built GUI assets from hash-pinned release tarball.","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-07T04:58:22Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-07T05:38:40Z","started_at":"2026-08-07T04:58:25Z","closed_at":"2026-08-07T05:38:40Z","close_reason":"Package added, builds green, committed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-qlc.1","title":"Update radar default.nix to use buildGoModule","description":"Change package.nix from stdenv.mkDerivation with fetchurl to buildGoModule pattern","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-11T13:50:42Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T14:59:55Z","started_at":"2026-05-11T13:51:49Z","closed_at":"2026-05-11T14:59:55Z","close_reason":"Closed","dependencies":[{"issue_id":"nix-overlay-qlc.1","depends_on_id":"nix-overlay-qlc","type":"parent-child","created_at":"2026-05-11T16:50:41Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-bjd","title":"Add nftables-analyzer CLI package","description":"Add python3Packages.buildPythonApplication derivation for reinaldosaraiva/nftables-analyzer (CLI only). Pin to main commit 5fc78d0c9ce173e3baa80a5655bcadb1b2f78493 (no tags upstream). sourceRoot=source/backend, hatchling build system. Category: Networking. Frontend excluded - upstream repo missing frontend/src/lib modules.","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-07T04:48:07Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-07T04:50:25Z","started_at":"2026-08-07T04:48:10Z","closed_at":"2026-08-07T04:50:25Z","close_reason":"Package added, built, smoke-tested, committed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-qlc","title":"Rebuild radar package from source instead of prebuilt binary","description":"Current radar package uses prebuilt binary from GitHub releases. Need to rebuild from source using nix native tooling (buildGoModule + npm for frontend). Build pipeline: 1) npm run build for frontend, 2) copy assets to internal/static/dist, 3) CGO_ENABLED=0 go build with embedded assets.","status":"closed","priority":2,"issue_type":"task","owner":"alex@millerson.name","created_at":"2026-05-11T13:50:27Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T15:01:06Z","closed_at":"2026-05-11T15:01:06Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
{"_type":"issue","id":"nix-overlay-vhq","title":"Note missing Dolt remote in AGENTS.md","description":"## Why\\nAgents running bd dolt push see 'No remote is configured - skipping' and may mistake it for a failure (blocking session close). Document that this is expected: no Dolt remote is set up, beads state is versioned locally in .beads/ and committed via git.\\n\\n## What\\nAdd a short note in the Beads Issue Tracker / Session Completion section of AGENTS.md.\\n\\n## Acceptance\\n- AGENTS.md explains the expected bd dolt push output and that git push is the actual sync mechanism","status":"closed","priority":3,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-08-07T13:18:33Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-08-07T13:19:26Z","started_at":"2026-08-07T13:18:51Z","closed_at":"2026-08-07T13:19:26Z","close_reason":"AGENTS.md updated and pushed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||||
{"_type":"issue","id":"nix-overlay-y8r","title":"nix-overlay-2lr-3 · Approach 3: ручной npm cache + buildGoModule [parent:nix-overlay-2lr]","notes":"BLOCKED: fetchNpmDeps v2 не загружает workspace-scoped пакеты (@vitejs/plugin-react ENOTCACHED) даже с makeCacheWritable=true. Все 3 подхода заблокированы одним ограничением — fetchNpmDeps v2 не поддерживает npm workspaces корректно, вопреки release notes.","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-11T09:38:34Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T11:14:40Z","started_at":"2026-05-11T10:23:41Z","closed_at":"2026-05-11T11:14:40Z","dependencies":[{"issue_id":"nix-overlay-y8r","depends_on_id":"nix-overlay-2lr","type":"parent-child","created_at":"2026-05-11T12:42:18Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
|
||||||
{"_type":"issue","id":"nix-overlay-dcx","title":"nix-overlay-2lr-2 · Approach 2: bun2nix генерация пакетов [parent:nix-overlay-2lr]","notes":"Skipping bun2nix — требует staging branch, неочевидная поддержка npm lockfiles. Проще перейти к Approach 3 (ручной stdenv.mkDerivation с nodejs/npm).","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-11T09:38:06Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T10:23:18Z","started_at":"2026-05-11T10:21:04Z","closed_at":"2026-05-11T10:23:18Z","dependencies":[{"issue_id":"nix-overlay-dcx","depends_on_id":"nix-overlay-2lr","type":"parent-child","created_at":"2026-05-11T12:42:12Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
|
||||||
{"_type":"issue","id":"nix-overlay-3ik","title":"nix-overlay-2lr-1 · Approach 1: buildNpmPackage + buildGoModule с npmDepsFetcherVersion=2 [parent:nix-overlay-2lr]","notes":"fetchNpmDeps v2 не resolves workspace-scoped packages (@vitejs/plugin-react ENOTCACHED). Approach blocked — same issue as previous attempt. Moving to Approach 2 (bun2nix).","status":"closed","priority":2,"issue_type":"task","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-11T09:37:43Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T10:20:38Z","started_at":"2026-05-11T09:39:05Z","closed_at":"2026-05-11T10:20:38Z","dependencies":[{"issue_id":"nix-overlay-3ik","depends_on_id":"nix-overlay-2lr","type":"parent-child","created_at":"2026-05-11T12:41:54Z","created_by":"Alexander Miroshnichenko","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
|
|
||||||
{"_type":"issue","id":"nix-overlay-2lr","title":"radar","description":"Используй karpathy-guidelines и Sequential Thinking для планирования шаг за шагом добавления нового пакета https://github.com/skyhook-io/radar.git в данный NIXOS overlay-репозиторий. Разбей задачу на подзадачи, используя beads. В написании кода используй mcp: nixos, refContext и context7.\n\n\n\n## Required Skills\ncaveman,karpathy-guidelines,nix,nix-flakes","notes":"Все 3 подхода провалены. fetchNpmDeps v2 НЕ работает с npm workspaces вопреки release notes - ENOTCACHED для workspace-scoped пакетов (@vitejs/plugin-react). Ручной сбор node_modules без npm ci слишком сложен (требует reimplement fetchNpmDeps). Текущее решение: pre-built binary из GitHub Releases. Нужно дождаться исправления fetchNpmDeps v2 в nixpkgs или upstream поддержки standalone lockfile для web/.","status":"closed","priority":2,"issue_type":"feature","assignee":"Alexander Miroshnichenko","owner":"alex@millerson.name","created_at":"2026-05-10T19:28:56Z","created_by":"Alexander Miroshnichenko","updated_at":"2026-05-11T11:24:40Z","started_at":"2026-05-10T19:30:31Z","closed_at":"2026-05-11T11:24:40Z","dependency_count":0,"dependent_count":0,"comment_count":0}
|
|
||||||
|
|||||||
@@ -414,6 +414,11 @@ bd remember # Save persistent knowledge (use instead of MEMORY.md file
|
|||||||
git push
|
git push
|
||||||
git status # MUST show "up to date with origin"
|
git status # MUST show "up to date with origin"
|
||||||
```
|
```
|
||||||
|
Note: no Dolt remote is configured for this workspace, so `bd dolt push`
|
||||||
|
prints `No remote is configured — skipping.` and exits. That is expected,
|
||||||
|
NOT a failure. Beads state is versioned locally in `.beads/` and synced to
|
||||||
|
the shared repository via `git push` — the `git status` check above is the
|
||||||
|
real completion gate.
|
||||||
5. **Clean up** - Clear stashes, prune remote branches
|
5. **Clean up** - Clear stashes, prune remote branches
|
||||||
6. **Verify** - All changes committed AND pushed
|
6. **Verify** - All changes committed AND pushed
|
||||||
7. **Hand off** - Provide context for next session
|
7. **Hand off** - Provide context for next session
|
||||||
|
|||||||
35
README.md
35
README.md
@@ -12,14 +12,18 @@ A custom Nix overlay and flake providing additional packages not found in upstre
|
|||||||
|
|
||||||
| Package | Description | Category |
|
| Package | Description | Category |
|
||||||
|---------|-------------|----------|
|
|---------|-------------|----------|
|
||||||
|
| `awg-tool` | CLI for AmneziaWG self-hosting — generates 1.0/1.5/2.0/3.0 obfuscation parameters, exports .conf and vpn:// configs, installs servers over SSH | Networking |
|
||||||
| `aionui` | Free, open-source, Cowork app with AI Agents | AI Coding Agents |
|
| `aionui` | Free, open-source, Cowork app with AI Agents | AI Coding Agents |
|
||||||
| `container-use` | Containerized environments for coding agents | AI Coding Agents |
|
| `container-use` | Containerized environments for coding agents | AI Coding Agents |
|
||||||
| `desloppify` | Multi-language codebase health scanner and technical debt tracker for AI agents | AI Coding Agents |
|
| `desloppify` | Multi-language codebase health scanner and technical debt tracker for AI agents | AI Coding Agents |
|
||||||
| `ds4` | DeepSeek 4 Flash and PRO local inference engine for ROCm (Strix Halo) | AI Inference |
|
| `ds4` | DeepSeek 4 Flash and PRO local inference engine for ROCm (Strix Halo) | AI Inference |
|
||||||
| `freebuff` | The world's strongest free coding agent | AI Coding Agents |
|
| `freebuff` | The world's strongest free coding agent | AI Coding Agents |
|
||||||
| `graphify` | Turn any folder of code, docs, papers, images, or videos into a queryable knowledge graph | AI Coding Agents |
|
| `graphify` | Turn any folder of code, docs, papers, images, or videos into a queryable knowledge graph | AI Coding Agents |
|
||||||
|
| `haivemind` | Multi-model AI consensus, aggregation, and fusion runner for popular AI CLIs | AI Coding Agents |
|
||||||
| `hipengine` | ROCm-native local LLM inference engine with torch-free runtime for AMD RDNA GPUs | AI Inference |
|
| `hipengine` | ROCm-native local LLM inference engine with torch-free runtime for AMD RDNA GPUs | AI Inference |
|
||||||
| `mcp-gateway` | Universal Model Context Protocol gateway that sits between AI client and MCP tools/servers | MCP Servers |
|
| `mcp-gateway` | Universal Model Context Protocol gateway that sits between AI client and MCP tools/servers | MCP Servers |
|
||||||
|
| `nftables-analyzer` | Analyze nftables firewall rules and evaluate traffic queries | Networking |
|
||||||
|
| `nftablesbuilder` | Web interface to manage nftables rules with drag-and-drop rule creation | Networking |
|
||||||
| `skillsmcp` | MCP server that exposes Agent Skills to AI agents via the Model Context Protocol | MCP Servers |
|
| `skillsmcp` | MCP server that exposes Agent Skills to AI agents via the Model Context Protocol | MCP Servers |
|
||||||
| `kubernetes-mcp-server` | Model Context Protocol (MCP) server for Kubernetes and OpenShift | MCP Servers |
|
| `kubernetes-mcp-server` | Model Context Protocol (MCP) server for Kubernetes and OpenShift | MCP Servers |
|
||||||
| `loop` | Corporate messenger for your team | Communication |
|
| `loop` | Corporate messenger for your team | Communication |
|
||||||
@@ -27,6 +31,7 @@ A custom Nix overlay and flake providing additional packages not found in upstre
|
|||||||
| `omniroute` | Unified AI router with 160+ providers, auto fallback, MCP/A2A, OpenAI-compatible APIs | AI LLM Gateway |
|
| `omniroute` | Unified AI router with 160+ providers, auto fallback, MCP/A2A, OpenAI-compatible APIs | AI LLM Gateway |
|
||||||
| `relay-free-llm` | RESTful API to route user prompts to various AI model providers with automatic failover and intent-based routing | AI LLM Gateway |
|
| `relay-free-llm` | RESTful API to route user prompts to various AI model providers with automatic failover and intent-based routing | AI LLM Gateway |
|
||||||
| `stakpak` | DevOps AI agent that generates infrastructure code, debugs Kubernetes, configures CI/CD, and automates deployments | AI Agents |
|
| `stakpak` | DevOps AI agent that generates infrastructure code, debugs Kubernetes, configures CI/CD, and automates deployments | AI Agents |
|
||||||
|
| `traycer` | Open-source AI orchestration app for agentic coding | AI Coding Agents |
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -82,6 +87,31 @@ nix run git+https://git.millerson.name/alex/millerson-overlay.nix.git#mcp-gatewa
|
|||||||
nix profile install git+https://git.millerson.name/alex/millerson-overlay.nix.git#mcp-gateway
|
nix profile install git+https://git.millerson.name/alex/millerson-overlay.nix.git#mcp-gateway
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### nftablesbuilder Runtime Notes
|
||||||
|
|
||||||
|
`nftablesbuilder` is a web interface for managing nftables. It consists of a
|
||||||
|
root-launcher (`nftablesbuilder`) that spawns the unprivileged `webserver`
|
||||||
|
binary and pipes encrypted commands between it and the `nft` binary.
|
||||||
|
|
||||||
|
Before running it you must:
|
||||||
|
|
||||||
|
1. Copy the settings template to `/etc/nftablesbuilder` (the only fixed path):
|
||||||
|
```bash
|
||||||
|
nix build .#nftablesbuilder
|
||||||
|
cp result/share/nftablesbuilder/settings.example /etc/nftablesbuilder
|
||||||
|
```
|
||||||
|
Adjust paths inside (html, webserver, nft, savepath, TLS files).
|
||||||
|
2. Create a TLS key/certificate pair at the paths referenced by
|
||||||
|
`tlskey`/`tlscert` (e.g. `openssl req -x509 -newkey rsa:2048 -nodes ...`).
|
||||||
|
3. Run the launcher as root (it needs to write `/etc/nftables.conf` and run
|
||||||
|
`nft`); the web interface listens on `https://<server>:1969`.
|
||||||
|
|
||||||
|
Note: upstream publishes the GUI only as a prebuilt tarball on
|
||||||
|
nftablesbuilder.eu (served with a self-signed certificate, hence the
|
||||||
|
`curlOpts = "-k"` in the derivation); the source repository is missing the
|
||||||
|
`settings` crate, which this overlay patches in.
|
||||||
|
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
@@ -112,6 +142,7 @@ nix-overlay/
|
|||||||
│ ├── default.nix # Binary-cache-friendly overlay
|
│ ├── default.nix # Binary-cache-friendly overlay
|
||||||
│ └── shared-nixpkgs.nix # Dependency-sharing overlay
|
│ └── shared-nixpkgs.nix # Dependency-sharing overlay
|
||||||
├── packages/ # Package definitions
|
├── packages/ # Package definitions
|
||||||
|
│ ├── awg-tool/ # AmneziaWG parameter generation and SSH deployment CLI
|
||||||
│ ├── aionui/ # AionUi - AI Cowork desktop app
|
│ ├── aionui/ # AionUi - AI Cowork desktop app
|
||||||
│ ├── container-use/ # Containerized environments for coding agents
|
│ ├── container-use/ # Containerized environments for coding agents
|
||||||
│ ├── default/ # Meta-package listing all packages
|
│ ├── default/ # Meta-package listing all packages
|
||||||
@@ -120,6 +151,7 @@ nix-overlay/
|
|||||||
│ ├── flake-inputs/ # Utility for caching flake inputs
|
│ ├── flake-inputs/ # Utility for caching flake inputs
|
||||||
│ ├── freebuff/ # Free coding agent (Codebuff)
|
│ ├── freebuff/ # Free coding agent (Codebuff)
|
||||||
│ ├── graphify/ # Knowledge graph generator for code folders
|
│ ├── graphify/ # Knowledge graph generator for code folders
|
||||||
|
│ ├── haivemind/ # Multi-model AI consensus runner
|
||||||
│ ├── hipengine/ # ROCm-native LLM inference engine for AMD GPUs
|
│ ├── hipengine/ # ROCm-native LLM inference engine for AMD GPUs
|
||||||
│ ├── kubernetes-mcp-server/ # MCP server for Kubernetes and OpenShift
|
│ ├── kubernetes-mcp-server/ # MCP server for Kubernetes and OpenShift
|
||||||
│ ├── loop/ # Corporate messenger for your team
|
│ ├── loop/ # Corporate messenger for your team
|
||||||
@@ -128,7 +160,8 @@ nix-overlay/
|
|||||||
│ ├── radar/ # Kubernetes UI (topology, timeline, Helm, GitOps)
|
│ ├── radar/ # Kubernetes UI (topology, timeline, Helm, GitOps)
|
||||||
│ ├── relay-free-llm/ # AI model provider routing gateway
|
│ ├── relay-free-llm/ # AI model provider routing gateway
|
||||||
│ ├── skillsmcp/ # MCP server for Agent Skills
|
│ ├── skillsmcp/ # MCP server for Agent Skills
|
||||||
│ └── stakpak/ # DevOps AI agent for infrastructure automation
|
│ ├── stakpak/ # DevOps AI agent for infrastructure automation
|
||||||
|
│ └── traycer/ # AI orchestration desktop app (agentic coding)
|
||||||
└── README.md
|
└── README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
17
flake.lock
generated
17
flake.lock
generated
@@ -89,12 +89,29 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-latest": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785967620,
|
||||||
|
"narHash": "sha256-IItrdb7Puk05RqOBWZYFC5X6Wl1sJmCfh5MWVHw5iMM=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "b7c2ada94fe99c15b0dbcf4d11fd7850b957a436",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"blueprint": "blueprint",
|
"blueprint": "blueprint",
|
||||||
"bun2nix": "bun2nix",
|
"bun2nix": "bun2nix",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
|
"nixpkgs-latest": "nixpkgs-latest",
|
||||||
"systems": "systems",
|
"systems": "systems",
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
# Newer nixpkgs whose toolchains are required by some packages:
|
||||||
|
# rustc >= 1.95 (mcp-gateway >= 3.4.0), go >= 1.26.3 (kubernetes-mcp-server >= 0.0.66).
|
||||||
|
nixpkgs-latest.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
systems.url = "github:nix-systems/default";
|
systems.url = "github:nix-systems/default";
|
||||||
blueprint = {
|
blueprint = {
|
||||||
url = "github:numtide/blueprint";
|
url = "github:numtide/blueprint";
|
||||||
|
|||||||
@@ -15,13 +15,13 @@
|
|||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "2.1.4";
|
version = "2.1.50";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "iOfficeAI";
|
owner = "iOfficeAI";
|
||||||
repo = "AionUi";
|
repo = "AionUi";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-A7dKGEuo5n+M7D9fJR3TN95q1P7En/ulsTO+ev6SAUY=";
|
hash = "sha256-NsKygGMRN5pQXyKaehVW/sC2tyd4KmrYmiQrr5ZGeNY=";
|
||||||
};
|
};
|
||||||
|
|
||||||
# FOD 1: All dependencies (dev + prod) for the build phase.
|
# FOD 1: All dependencies (dev + prod) for the build phase.
|
||||||
@@ -34,7 +34,7 @@ let
|
|||||||
];
|
];
|
||||||
outputHashAlgo = "sha256";
|
outputHashAlgo = "sha256";
|
||||||
outputHashMode = "recursive";
|
outputHashMode = "recursive";
|
||||||
outputHash = "sha256-Fuj55vxDgpx5A4iwnU/5IZKPfaYMH3DeZ1yauuZHn8g=";
|
outputHash = "sha256-EeDapBXeiU/70N92ka1dmrKUMEDN65FON8VPVPsBfro=";
|
||||||
dontPatchShebangs = true;
|
dontPatchShebangs = true;
|
||||||
dontFixup = true;
|
dontFixup = true;
|
||||||
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||||
@@ -63,7 +63,7 @@ let
|
|||||||
];
|
];
|
||||||
outputHashAlgo = "sha256";
|
outputHashAlgo = "sha256";
|
||||||
outputHashMode = "recursive";
|
outputHashMode = "recursive";
|
||||||
outputHash = "sha256-eCQ9ObhttZ10CehRRvl4IaOKkdK9m1TQJuhLmhiMkBY=";
|
outputHash = "sha256-L2UV+OsHfoQTsc1s+tBrJZtnoiCcB2mlnsAHbplTggc=";
|
||||||
dontPatchShebangs = true;
|
dontPatchShebangs = true;
|
||||||
dontFixup = true;
|
dontFixup = true;
|
||||||
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
|
||||||
|
|||||||
5
packages/awg-tool/default.nix
Normal file
5
packages/awg-tool/default.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.callPackage ./package.nix { }
|
||||||
51
packages/awg-tool/package.nix
Normal file
51
packages/awg-tool/package.nix
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
rustPlatform,
|
||||||
|
fetchFromGitHub,
|
||||||
|
cmake,
|
||||||
|
perl,
|
||||||
|
}:
|
||||||
|
|
||||||
|
rustPlatform.buildRustPackage rec {
|
||||||
|
pname = "awg-tool";
|
||||||
|
version = "0.2.2";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "Vadim-Khristenko";
|
||||||
|
repo = "awg-containers-and-tools";
|
||||||
|
rev = "v${version}";
|
||||||
|
hash = "sha256-z4LG+z60uqsfkRyt7Dc8Fc5GMfpiF7G0N9PXnzTUJms=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# awg-core builds ssh2 with vendored-openssl, which compiles libssh2
|
||||||
|
# (via cmake) and OpenSSL (via perl Configure) from source.
|
||||||
|
nativeBuildInputs = [
|
||||||
|
cmake
|
||||||
|
perl
|
||||||
|
];
|
||||||
|
|
||||||
|
cargoHash = "sha256-Nb5tmwvhzKAldHai7yxtYapjbZmai0ujBX9c6nRGZk0=";
|
||||||
|
|
||||||
|
# Upstream tests exercise Docker/SSH targets; unit tests are already
|
||||||
|
# covered by the upstream CI before a release is cut.
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
category = "Networking";
|
||||||
|
updateScript = [
|
||||||
|
"nix-update"
|
||||||
|
"--flake"
|
||||||
|
".#awg-tool"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "CLI for AmneziaWG self-hosting — generates 1.0/1.5/2.0/3.0 obfuscation parameters, exports .conf and vpn:// configs, installs servers over SSH";
|
||||||
|
homepage = "https://github.com/Vadim-Khristenko/awg-containers-and-tools";
|
||||||
|
changelog = "https://github.com/Vadim-Khristenko/awg-containers-and-tools/releases/tag/v${version}";
|
||||||
|
license = licenses.mit;
|
||||||
|
sourceProvenance = with sourceTypes; [ fromSource ];
|
||||||
|
mainProgram = "awg-tool";
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
python3Packages.buildPythonApplication rec {
|
python3Packages.buildPythonApplication rec {
|
||||||
pname = "desloppify";
|
pname = "desloppify";
|
||||||
version = "0.9.15";
|
version = "1.0";
|
||||||
pyproject = true;
|
pyproject = true;
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "peteromallet";
|
owner = "peteromallet";
|
||||||
repo = "desloppify";
|
repo = "desloppify";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-KVCt9loGSzsOaYSLNzpyUCi/TpCDQ4b6BxEydQTRNcA=";
|
hash = "sha256-USFofGy0SUZV0oeh5x5KAWeFReD45GxlyYqpmc23NFM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
build-system = with python3Packages; [
|
build-system = with python3Packages; [
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
|
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation {
|
||||||
pname = "ds4";
|
pname = "ds4";
|
||||||
version = "0-unstable-2026-06-17";
|
version = "0-unstable-2026-08-05";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "antirez";
|
owner = "antirez";
|
||||||
repo = "ds4";
|
repo = "ds4";
|
||||||
rev = "80ebbc396aee40eedc1d829222f3362d10fa4c6c";
|
rev = "b0309611041655f4e45671cfd9c9886aff161406";
|
||||||
hash = "sha256-Ieuc72GHZs20ModQfnvI5Me31n4Pj+WFYtsuqaKJceo=";
|
hash = "sha256-yBPQqX8oI9fElGiXfz72iWwIS8ZQpK4Bl9TWLZSa6JU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "0.0.85";
|
version = "0.0.142";
|
||||||
|
|
||||||
freebuffSrc = fetchurl {
|
freebuffSrc = fetchurl {
|
||||||
url = "https://registry.npmjs.org/freebuff/-/freebuff-${version}.tgz";
|
url = "https://registry.npmjs.org/freebuff/-/freebuff-${version}.tgz";
|
||||||
hash = "sha256-1x593yLMkoFIO5O+k5NKeEpi729VhINQlW1xFbYGnXM=";
|
hash = "sha256-8DSNy/wJqLzp7mu2xsPBlMv69aBMIBNVva3SAaV13Tw=";
|
||||||
};
|
};
|
||||||
|
|
||||||
pkgTar = fetchurl {
|
pkgTar = fetchurl {
|
||||||
@@ -47,15 +47,15 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
binarySrc = fetchurl {
|
binarySrc = fetchurl {
|
||||||
url = "https://codebuff.com/api/releases/download/${version}/freebuff-linux-x64.tar.gz";
|
url = "https://github.com/CodebuffAI/codebuff-community/releases/download/freebuff-v${version}/freebuff-linux-x64.tar.gz";
|
||||||
hash = "sha256-WRTEXqKDww4ZPAnDLAAkAd0jxl+z6+dRbcQORmN7QfM=";
|
hash = "sha256-SuV5djfrvRZZ59p+dUyiux+OmEMOxscuIU5/YDGWHYI=";
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "freebuff";
|
pname = "freebuff";
|
||||||
version = "0.0.85";
|
version = "0.0.142";
|
||||||
|
|
||||||
src = freebuffSrc;
|
src = freebuffSrc;
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
python3Packages.buildPythonApplication rec {
|
python3Packages.buildPythonApplication rec {
|
||||||
pname = "graphify";
|
pname = "graphify";
|
||||||
version = "0.7.10";
|
version = "0.9.35";
|
||||||
pyproject = true;
|
pyproject = true;
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "safishamsi";
|
owner = "safishamsi";
|
||||||
repo = "graphify";
|
repo = "graphify";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-sSlmYPDwY43ro+kd5uQyvE9cEPNAMXUd5TIEPcaoioc=";
|
hash = "sha256-HESowqiR5c6WaeiNj1WDSYBzrrcpZQwqaKwQxroePD8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
build-system = with python3Packages; [
|
build-system = with python3Packages; [
|
||||||
@@ -34,28 +34,34 @@ python3Packages.buildPythonApplication rec {
|
|||||||
tree-sitter-sql
|
tree-sitter-sql
|
||||||
];
|
];
|
||||||
|
|
||||||
# Remove unavailable tree-sitter grammars from pyproject.toml
|
# Remove unavailable tree-sitter grammars from pyproject.toml.
|
||||||
|
# Since 0.9.35 upstream pins versions ("tree-sitter-X>=v,<v"), and GNU sed
|
||||||
|
# mishandles `"` inside bracket expressions, match the name followed by
|
||||||
|
# either `>` (versioned) or `"` (bare) via alternation. This also avoids
|
||||||
|
# prefix collisions (e.g. tree-sitter-c vs tree-sitter-c-sharp).
|
||||||
postPatch = ''
|
postPatch = ''
|
||||||
sed -i \
|
sed -i \
|
||||||
-e '/"tree-sitter-typescript"/d' \
|
-e '/tree-sitter-typescript>\|tree-sitter-typescript"/d' \
|
||||||
-e '/"tree-sitter-go"/d' \
|
-e '/tree-sitter-go>\|tree-sitter-go"/d' \
|
||||||
-e '/"tree-sitter-java"/d' \
|
-e '/tree-sitter-java>\|tree-sitter-java"/d' \
|
||||||
-e '/"tree-sitter-groovy"/d' \
|
-e '/tree-sitter-groovy>\|tree-sitter-groovy"/d' \
|
||||||
-e '/"tree-sitter-c"/d' \
|
-e '/tree-sitter-c>\|tree-sitter-c"/d' \
|
||||||
-e '/"tree-sitter-cpp"/d' \
|
-e '/tree-sitter-cpp>\|tree-sitter-cpp"/d' \
|
||||||
-e '/"tree-sitter-ruby"/d' \
|
-e '/tree-sitter-ruby>\|tree-sitter-ruby"/d' \
|
||||||
-e '/"tree-sitter-kotlin"/d' \
|
-e '/tree-sitter-kotlin>\|tree-sitter-kotlin"/d' \
|
||||||
-e '/"tree-sitter-scala"/d' \
|
-e '/tree-sitter-scala>\|tree-sitter-scala"/d' \
|
||||||
-e '/"tree-sitter-php"/d' \
|
-e '/tree-sitter-php>\|tree-sitter-php"/d' \
|
||||||
-e '/"tree-sitter-swift"/d' \
|
-e '/tree-sitter-swift>\|tree-sitter-swift"/d' \
|
||||||
-e '/"tree-sitter-lua"/d' \
|
-e '/tree-sitter-lua>\|tree-sitter-lua"/d' \
|
||||||
-e '/"tree-sitter-zig"/d' \
|
-e '/tree-sitter-zig>\|tree-sitter-zig"/d' \
|
||||||
-e '/"tree-sitter-powershell"/d' \
|
-e '/tree-sitter-powershell>\|tree-sitter-powershell"/d' \
|
||||||
-e '/"tree-sitter-elixir"/d' \
|
-e '/tree-sitter-elixir>\|tree-sitter-elixir"/d' \
|
||||||
-e '/"tree-sitter-objc"/d' \
|
-e '/tree-sitter-objc>\|tree-sitter-objc"/d' \
|
||||||
-e '/"tree-sitter-julia"/d' \
|
-e '/tree-sitter-julia>\|tree-sitter-julia"/d' \
|
||||||
-e '/"tree-sitter-verilog"/d' \
|
-e '/tree-sitter-verilog>\|tree-sitter-verilog"/d' \
|
||||||
-e '/"tree-sitter-fortran"/d' \
|
-e '/tree-sitter-fortran>\|tree-sitter-fortran"/d' \
|
||||||
|
-e '/tree-sitter-bash>\|tree-sitter-bash"/d' \
|
||||||
|
-e '/tree-sitter-json>\|tree-sitter-json"/d' \
|
||||||
pyproject.toml
|
pyproject.toml
|
||||||
'';
|
'';
|
||||||
|
|
||||||
@@ -74,9 +80,9 @@ python3Packages.buildPythonApplication rec {
|
|||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "AI coding assistant skill - turn any folder of code, docs, papers, images, or videos into a queryable knowledge graph";
|
description = "AI coding assistant skill - turn any folder of code, docs, papers, images, or videos into a queryable knowledge graph";
|
||||||
homepage = "https://github.com/safishamsi/graphify";
|
homepage = "https://github.com/Graphify-Labs/graphify";
|
||||||
changelog = "https://github.com/safishamsi/graphify/releases/tag/v${version}";
|
changelog = "https://github.com/Graphify-Labs/graphify/releases/tag/v${version}";
|
||||||
license = lib.licenses.mit;
|
license = lib.licenses.asl20;
|
||||||
mainProgram = "graphify";
|
mainProgram = "graphify";
|
||||||
platforms = lib.platforms.all;
|
platforms = lib.platforms.all;
|
||||||
};
|
};
|
||||||
|
|||||||
1
packages/haivemind/default.nix
Normal file
1
packages/haivemind/default.nix
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{ pkgs, ... }: pkgs.callPackage ./package.nix { }
|
||||||
459
packages/haivemind/fix-chat-log-race.patch
Normal file
459
packages/haivemind/fix-chat-log-race.patch
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
--- a/haivemind_tui.py
|
||||||
|
+++ b/haivemind_tui.py
|
||||||
|
@@ -1197,0 +1198,8 @@
|
||||||
|
+ def on_mount(self) -> None:
|
||||||
|
+ app = self.app
|
||||||
|
+ if (
|
||||||
|
+ getattr(app, "_prompt", None) is not None
|
||||||
|
+ and getattr(app, "_config", None) is not None
|
||||||
|
+ ):
|
||||||
|
+ app.start_run(app._prompt, app._config)
|
||||||
|
+
|
||||||
|
@@ -1220,13 +1220,13 @@
|
||||||
|
self._engine: HaivemindEngine | None = None
|
||||||
|
self._run_started = False
|
||||||
|
self._run_start_time: float = 0.0
|
||||||
|
+ self._main_screen = None
|
||||||
|
|
||||||
|
def on_mount(self) -> None:
|
||||||
|
- self.push_screen(MainScreen())
|
||||||
|
+ self._main_screen = MainScreen()
|
||||||
|
+ self.push_screen(self._main_screen)
|
||||||
|
self.set_interval(0.15, self._tick_spinner)
|
||||||
|
- if self._prompt is not None and self._config is not None:
|
||||||
|
- self.start_run(self._prompt, self._config)
|
||||||
|
- else:
|
||||||
|
+ if self._prompt is None or self._config is None:
|
||||||
|
self.push_screen(ConfigScreen())
|
||||||
|
|
||||||
|
def start_run(self, prompt: str, config: HaivemindConfig) -> None:
|
||||||
|
@@ -1303,7 +1303,7 @@
|
||||||
|
def _tick_spinner(self) -> None:
|
||||||
|
_advance_spinner()
|
||||||
|
try:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
if "streaming" in hbar._model_status.values():
|
||||||
|
hbar._refresh()
|
||||||
|
except NoMatches:
|
||||||
|
@@ -1315,20 +1315,20 @@
|
||||||
|
def _on_probe_start(self) -> None:
|
||||||
|
import time as _time
|
||||||
|
self._run_start_time = _time.time()
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
chat.add_summary("[bold yellow]Probing models...[/]")
|
||||||
|
if self._config is not None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_models(self._config.models)
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.consensus_info = "probing"
|
||||||
|
header.progress_pct = 0.0
|
||||||
|
|
||||||
|
@on(ProbeResult)
|
||||||
|
def _on_probe_result(self, event: ProbeResult) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "done" if event.ok else "failed")
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
if event.ok:
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
chat.add_summary(f"[{color}][probe] ok: {event.model}[/]")
|
||||||
|
@@ -1339,44 +1339,44 @@
|
||||||
|
|
||||||
|
@on(ProbeDone)
|
||||||
|
def _on_probe_done(self, event: ProbeDone) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
chat.add_summary(
|
||||||
|
f"[bold yellow]Probe complete:[/] {len(event.healthy)} healthy, "
|
||||||
|
f"{len(event.failures)} failed"
|
||||||
|
)
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.consensus_info = ""
|
||||||
|
if event.healthy:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_models(event.healthy)
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.update_layout(event.healthy, hbar._model_colors)
|
||||||
|
|
||||||
|
@on(RoundStart)
|
||||||
|
def _on_round_start(self, event: RoundStart) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
chat.add_summary(f"\n[bold cyan]\u2500\u2500 Round {event.round_idx}/{event.total} \u2500\u2500[/]")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.round_info = f"hAIvemind \u2502 Round {event.round_idx}/{event.total}"
|
||||||
|
header.consensus_info = ""
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.clear_all()
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@on(ModelStart)
|
||||||
|
def _on_model_start(self, event: ModelStart) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "streaming")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
total = len(hbar._model_status) if hbar._model_status else 0
|
||||||
|
done_count = sum(
|
||||||
|
1 for s in hbar._model_status.values() if s in ("streaming", "done")
|
||||||
|
)
|
||||||
|
header.model_info = f"Models: {done_count}/{total}"
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
active = [
|
||||||
|
m for m, s in hbar._model_status.items() if s != "dropped"
|
||||||
|
]
|
||||||
|
@@ -1386,27 +1386,27 @@
|
||||||
|
|
||||||
|
@on(ModelStream)
|
||||||
|
def _on_model_stream(self, event: ModelStream) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
t = event.fragment.strip()
|
||||||
|
if t:
|
||||||
|
chat.add_summary(f"[{color}][{event.model}][/] {t}")
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.stream_to_model(event.model, event.fragment)
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@on(ModelDone)
|
||||||
|
def _on_model_done(self, event: ModelDone) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
ar = event.agent_round
|
||||||
|
if ar.error and ar.error not in ("stderr",):
|
||||||
|
hbar.set_status(event.model, "failed")
|
||||||
|
else:
|
||||||
|
hbar.set_status(event.model, "done")
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
if ar.has_valid_draft:
|
||||||
|
chat.add_summary(
|
||||||
|
@@ -1419,14 +1419,14 @@
|
||||||
|
|
||||||
|
@on(ModelDropped)
|
||||||
|
def _on_model_dropped(self, event: ModelDropped) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "dropped")
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
chat.add_summary(
|
||||||
|
f"[red]\u26a0 {event.model} dropped:[/] {event.reason}"
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
remaining = [
|
||||||
|
m for m, s in hbar._model_status.items() if s != "dropped"
|
||||||
|
]
|
||||||
|
@@ -1436,7 +1436,7 @@
|
||||||
|
|
||||||
|
@on(RoundDone)
|
||||||
|
def _on_round_done(self, event: RoundDone) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
dur = event.record.get("duration_s", 0)
|
||||||
|
chat.add_summary(
|
||||||
|
f"[dim]\u2500\u2500 end round {event.round_idx} ({dur}s) \u2500\u2500[/]"
|
||||||
|
@@ -1446,15 +1446,15 @@
|
||||||
|
best_sim = _compute_best_similarity(drafts)
|
||||||
|
threshold = self._config.threshold if self._config else 0.75
|
||||||
|
pct = min(1.0, best_sim / threshold) if threshold > 0 else 0.0
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.progress_pct = pct
|
||||||
|
header.consensus_info = f"sim: {best_sim:.2f}"
|
||||||
|
|
||||||
|
@on(Consensus)
|
||||||
|
def _on_consensus(self, event: Consensus) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
total_models = len(hbar._model_status) if hbar._model_status else 0
|
||||||
|
import time as _time
|
||||||
|
elapsed = (
|
||||||
|
@@ -1493,9 +1493,9 @@
|
||||||
|
|
||||||
|
@on(Fallback)
|
||||||
|
def _on_fallback(self, event: Fallback) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
total_models = len(hbar._model_status) if hbar._model_status else 0
|
||||||
|
header.consensus_info = "fallback"
|
||||||
|
header.progress_pct = 0.0
|
||||||
|
@@ -1518,30 +1518,30 @@
|
||||||
|
|
||||||
|
@on(EngineError)
|
||||||
|
def _on_engine_error(self, event: EngineError) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
chat.add_summary(f"[red]Error:[/] {event.message}")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.consensus_info = "error"
|
||||||
|
|
||||||
|
@on(EngineLog)
|
||||||
|
def _on_engine_log(self, event: EngineLog) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
chat.add_summary(event.message)
|
||||||
|
|
||||||
|
@on(MoaRefStart)
|
||||||
|
def _on_moa_ref_start(self, event: MoaRefStart) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "streaming")
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
chat.add_summary(f"[{color}]\U0001f4e1 [ref] {event.model} analyzing...[/]")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.round_info = "hAIvemind \u2502 MoA \u2502 References"
|
||||||
|
|
||||||
|
@on(MoaRefDone)
|
||||||
|
def _on_moa_ref_done(self, event: MoaRefDone) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
if event.err and not event.raw.strip():
|
||||||
|
hbar.set_status(event.model, "failed")
|
||||||
|
@@ -1552,32 +1552,32 @@
|
||||||
|
|
||||||
|
@on(MoaRefStream)
|
||||||
|
def _on_moa_ref_stream(self, event: MoaRefStream) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
t = event.fragment.strip()
|
||||||
|
if t:
|
||||||
|
chat.add_summary(f"[{color}][ref:{event.model}][/] {t}")
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.stream_to_model(event.model, event.fragment)
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@on(MoaAggStart)
|
||||||
|
def _on_moa_agg_start(self, event: MoaAggStart) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "streaming")
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
chat.add_summary(f"\n[bold {color}]\U0001f9e0 [aggregator] {event.model} synthesizing...[/]")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.round_info = "hAIvemind \u2502 MoA \u2502 Aggregating"
|
||||||
|
|
||||||
|
@on(MoaAggDone)
|
||||||
|
def _on_moa_agg_done(self, event: MoaAggDone) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
if event.raw.strip():
|
||||||
|
hbar.set_status(event.model, "done")
|
||||||
|
@@ -1588,14 +1588,14 @@
|
||||||
|
|
||||||
|
@on(MoaAggStream)
|
||||||
|
def _on_moa_agg_stream(self, event: MoaAggStream) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
t = event.fragment.strip()
|
||||||
|
if t:
|
||||||
|
chat.add_summary(f"[{color}][agg:{event.model}][/] {t}")
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.stream_to_model(event.model, event.fragment)
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
@@ -1604,18 +1604,18 @@
|
||||||
|
|
||||||
|
@on(FusionPanelStart)
|
||||||
|
def _on_fusion_panel_start(self, event: FusionPanelStart) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "streaming")
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
chat.add_summary(f"[{color}]\U0001f52c [panel] {event.model} analyzing...[/]")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.round_info = "hAIvemind \u2502 Fusion \u2502 Panel"
|
||||||
|
|
||||||
|
@on(FusionPanelDone)
|
||||||
|
def _on_fusion_panel_done(self, event: FusionPanelDone) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
if event.err and not event.raw.strip():
|
||||||
|
hbar.set_status(event.model, "failed")
|
||||||
|
@@ -1626,32 +1626,32 @@
|
||||||
|
|
||||||
|
@on(FusionPanelStream)
|
||||||
|
def _on_fusion_panel_stream(self, event: FusionPanelStream) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
t = event.fragment.strip()
|
||||||
|
if t:
|
||||||
|
chat.add_summary(f"[{color}][panel:{event.model}][/] {t}")
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.stream_to_model(event.model, event.fragment)
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@on(FusionJudgeStart)
|
||||||
|
def _on_fusion_judge_start(self, event: FusionJudgeStart) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "streaming")
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
chat.add_summary(f"\n[bold {color}]\u2696\ufe0f [judge] {event.model} analyzing...[/]")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.round_info = "hAIvemind \u2502 Fusion \u2502 Judging"
|
||||||
|
|
||||||
|
@on(FusionJudgeDone)
|
||||||
|
def _on_fusion_judge_done(self, event: FusionJudgeDone) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
if event.raw.strip():
|
||||||
|
hbar.set_status(event.model, "done")
|
||||||
|
@@ -1662,32 +1662,32 @@
|
||||||
|
|
||||||
|
@on(FusionJudgeStream)
|
||||||
|
def _on_fusion_judge_stream(self, event: FusionJudgeStream) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
t = event.fragment.strip()
|
||||||
|
if t:
|
||||||
|
chat.add_summary(f"[{color}][judge:{event.model}][/] {t}")
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.stream_to_model(event.model, event.fragment)
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@on(FusionSynthStart)
|
||||||
|
def _on_fusion_synth_start(self, event: FusionSynthStart) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
hbar.set_status(event.model, "streaming")
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
chat.add_summary(f"\n[bold {color}]\u270d\ufe0f [synth] {event.model} writing final answer...[/]")
|
||||||
|
- header = self.query_one("#header-bar", HeaderBar)
|
||||||
|
+ header = self._main_screen.query_one("#header-bar", HeaderBar)
|
||||||
|
header.round_info = "hAIvemind \u2502 Fusion \u2502 Synthesizing"
|
||||||
|
|
||||||
|
@on(FusionSynthDone)
|
||||||
|
def _on_fusion_synth_done(self, event: FusionSynthDone) -> None:
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
if event.raw.strip():
|
||||||
|
hbar.set_status(event.model, "done")
|
||||||
|
@@ -1698,14 +1698,14 @@
|
||||||
|
|
||||||
|
@on(FusionSynthStream)
|
||||||
|
def _on_fusion_synth_stream(self, event: FusionSynthStream) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
- hbar = self.query_one("#health-bar", ModelHealthBar)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
+ hbar = self._main_screen.query_one("#health-bar", ModelHealthBar)
|
||||||
|
color = hbar.model_color(event.model)
|
||||||
|
t = event.fragment.strip()
|
||||||
|
if t:
|
||||||
|
chat.add_summary(f"[{color}][synth:{event.model}][/] {t}")
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.stream_to_model(event.model, event.fragment)
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
@@ -1720,7 +1720,7 @@
|
||||||
|
|
||||||
|
def action_toggle_theatre(self) -> None:
|
||||||
|
try:
|
||||||
|
- tc = self.query_one("#theatre-container")
|
||||||
|
+ tc = self._main_screen.query_one("#theatre-container")
|
||||||
|
if tc.has_class("visible"):
|
||||||
|
tc.remove_class("visible")
|
||||||
|
else:
|
||||||
|
@@ -1734,13 +1734,13 @@
|
||||||
|
|
||||||
|
def action_clear_theatre(self) -> None:
|
||||||
|
try:
|
||||||
|
- theatre = self.query_one("#theatre-container", TheatrePanel)
|
||||||
|
+ theatre = self._main_screen.query_one("#theatre-container", TheatrePanel)
|
||||||
|
theatre.clear_all()
|
||||||
|
except NoMatches:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def action_show_artifacts(self) -> None:
|
||||||
|
- chat = self.query_one("#chat-log", ChatLog)
|
||||||
|
+ chat = self._main_screen.query_one("#chat-log", ChatLog)
|
||||||
|
if self._engine and self._engine.run_dir:
|
||||||
|
chat.add_summary(f"[bold]Artifacts:[/] {self._engine.run_dir}")
|
||||||
|
else:
|
||||||
62
packages/haivemind/package.nix
Normal file
62
packages/haivemind/package.nix
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
python3Packages,
|
||||||
|
}:
|
||||||
|
|
||||||
|
python3Packages.buildPythonApplication rec {
|
||||||
|
pname = "haivemind";
|
||||||
|
version = "0.1.0";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "dev-boz";
|
||||||
|
repo = "haivemind";
|
||||||
|
rev = "ce4a0437d41f57638b71a17e2ff3af524d5a1b6e";
|
||||||
|
hash = "sha256-x7NM2wHwi11i07jHTL9NgYJkzzlP+tOmJy027itRtWs=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = with python3Packages; [
|
||||||
|
setuptools
|
||||||
|
];
|
||||||
|
|
||||||
|
dependencies = with python3Packages; [
|
||||||
|
textual
|
||||||
|
];
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
./fix-chat-log-race.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace haivemind_tui.py \
|
||||||
|
--replace-fail "sel.value = Select.BLANK" "sel.clear()" \
|
||||||
|
--replace-fail "v is Select.BLANK" "v is Select.NULL"
|
||||||
|
'';
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
pythonImportsCheck = [
|
||||||
|
"haivemind"
|
||||||
|
"haivemind_tui"
|
||||||
|
"haivemind_curses"
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
category = "AI Coding Agents";
|
||||||
|
updateScript = [
|
||||||
|
"nix-update"
|
||||||
|
"--flake"
|
||||||
|
".#haivemind"
|
||||||
|
"--version=branch=main"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Multi-model AI consensus, aggregation, and fusion runner for popular AI CLIs";
|
||||||
|
homepage = "https://github.com/dev-boz/haivemind";
|
||||||
|
changelog = "https://github.com/dev-boz/haivemind/commits/main";
|
||||||
|
license = licenses.mit;
|
||||||
|
mainProgram = "haivemind";
|
||||||
|
platforms = platforms.all;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
python3Packages.buildPythonApplication rec {
|
python3Packages.buildPythonApplication rec {
|
||||||
pname = "hipengine";
|
pname = "hipengine";
|
||||||
version = "0.2.2";
|
version = "0.3.0";
|
||||||
pyproject = true;
|
pyproject = true;
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "shisa-ai";
|
owner = "shisa-ai";
|
||||||
repo = "hipEngine";
|
repo = "hipEngine";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-ljgXDQfUTx64i1+yAKFE13GkcE9AE+1YICfSScQ9nuA=";
|
hash = "sha256-lnYsXTxke5LLMbHOt6i2FM8IrnHCimC/va1fJL5G4PQ=";
|
||||||
};
|
};
|
||||||
|
|
||||||
build-system = with python3Packages; [
|
build-system = with python3Packages; [
|
||||||
@@ -47,6 +47,8 @@ python3Packages.buildPythonApplication rec {
|
|||||||
changelog = "https://github.com/shisa-ai/hipEngine/releases/tag/v${version}";
|
changelog = "https://github.com/shisa-ai/hipEngine/releases/tag/v${version}";
|
||||||
license = lib.licenses.agpl3Plus;
|
license = lib.licenses.agpl3Plus;
|
||||||
platforms = lib.platforms.linux;
|
platforms = lib.platforms.linux;
|
||||||
mainProgram = "hipengine-server";
|
# Upstream replaced the hipengine-server console script with
|
||||||
|
# a top-level `hipengine` command (e.g. `hipengine serve`).
|
||||||
|
mainProgram = "hipengine";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,11 @@
|
|||||||
{ pkgs, ... }: pkgs.callPackage ./package.nix { }
|
{
|
||||||
|
pkgs,
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
# kubernetes-mcp-server >= 0.0.66 requires go >= 1.26.3, which the flake's
|
||||||
|
# pinned nixpkgs does not provide yet. Build with the newer nixpkgs-latest input.
|
||||||
|
let
|
||||||
|
latestPkgs = inputs.nixpkgs-latest.legacyPackages.${pkgs.stdenv.hostPlatform.system};
|
||||||
|
in
|
||||||
|
latestPkgs.callPackage ./package.nix { }
|
||||||
|
|||||||
@@ -6,16 +6,16 @@
|
|||||||
|
|
||||||
buildGoModule rec {
|
buildGoModule rec {
|
||||||
pname = "kubernetes-mcp-server";
|
pname = "kubernetes-mcp-server";
|
||||||
version = "0.0.62";
|
version = "0.0.66";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "containers";
|
owner = "containers";
|
||||||
repo = "kubernetes-mcp-server";
|
repo = "kubernetes-mcp-server";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-m4oM8KMcDmXwIGaFw+VdnW22kLjt2SaD7qZV4kgTiu8=";
|
hash = "sha256-vnJxSCfnpvOZJXQpKrCAW4QKt5R2PJDYQevA7O1uXZg=";
|
||||||
};
|
};
|
||||||
|
|
||||||
vendorHash = "sha256-JNeYn/IfzQ2VLDbHgrkserh3wrXYOWXBczBn2DUO6NM=";
|
vendorHash = "sha256-gbqoT4X+wVOEktHm7jaAH9vHrUBrYgR8OjyFz1ljP6k=";
|
||||||
|
|
||||||
env.CGO_ENABLED = 0;
|
env.CGO_ENABLED = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
|
inputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
pkgs.callPackage ./package.nix { }
|
# mcp-gateway >= 3.4.0 requires rustc >= 1.95, which the flake's pinned
|
||||||
|
# nixpkgs does not provide yet. Build with the newer nixpkgs-latest input.
|
||||||
|
let
|
||||||
|
latestPkgs = inputs.nixpkgs-latest.legacyPackages.${pkgs.stdenv.hostPlatform.system};
|
||||||
|
in
|
||||||
|
latestPkgs.callPackage ./package.nix { }
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage rec {
|
||||||
pname = "mcp-gateway";
|
pname = "mcp-gateway";
|
||||||
version = "2.11.0";
|
version = "3.4.0";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "MikkoParkkola";
|
owner = "MikkoParkkola";
|
||||||
repo = "mcp-gateway";
|
repo = "mcp-gateway";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-7IALz7hOnCeKtiEm8b3M7v5oy4hw173viyhNeqQIhTI=";
|
hash = "sha256-shn2cv463SnegamsMu6NmfylnNaFzGJLoL2H7QhETY8=";
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoHash = "sha256-B5HRETFryzLqQhdIqRFj0apZS0wMggW2MHE2VsbB22Y=";
|
cargoHash = "sha256-XuOYuYapb2l7RHQIgLDfcDPtSdMDpEgti8Ud5ssuGC8=";
|
||||||
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
nativeBuildInputs = [ pkg-config ];
|
||||||
|
|
||||||
|
|||||||
5
packages/nftables-analyzer/default.nix
Normal file
5
packages/nftables-analyzer/default.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.callPackage ./package.nix { }
|
||||||
54
packages/nftables-analyzer/package.nix
Normal file
54
packages/nftables-analyzer/package.nix
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
python3Packages,
|
||||||
|
fetchFromGitHub,
|
||||||
|
}:
|
||||||
|
|
||||||
|
python3Packages.buildPythonApplication rec {
|
||||||
|
pname = "nftables-analyzer";
|
||||||
|
version = "0.1.0-unstable-2025-11-27";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "reinaldosaraiva";
|
||||||
|
repo = "nftables-analyzer";
|
||||||
|
rev = "5fc78d0c9ce173e3baa80a5655bcadb1b2f78493";
|
||||||
|
hash = "sha256-PlEIArUPSSOtVrdUEamZBr1YQnm+GJpl5Xxgk0tHrdw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
sourceRoot = "source/backend";
|
||||||
|
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
build-system = with python3Packages; [
|
||||||
|
hatchling
|
||||||
|
];
|
||||||
|
|
||||||
|
dependencies = with python3Packages; [
|
||||||
|
typer
|
||||||
|
rich
|
||||||
|
pydantic
|
||||||
|
fastapi
|
||||||
|
uvicorn
|
||||||
|
python-multipart
|
||||||
|
];
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
pythonImportsCheck = [ "nftables_analyzer" ];
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
category = "Networking";
|
||||||
|
updateScript = [
|
||||||
|
"nix-update"
|
||||||
|
"--flake"
|
||||||
|
".#nftables-analyzer"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Analyze nftables firewall rules and evaluate traffic queries";
|
||||||
|
homepage = "https://github.com/reinaldosaraiva/nftables-analyzer";
|
||||||
|
license = licenses.mit;
|
||||||
|
mainProgram = "nftables-analyzer";
|
||||||
|
platforms = platforms.all;
|
||||||
|
};
|
||||||
|
}
|
||||||
2273
packages/nftablesbuilder/Cargo.lock
generated
Normal file
2273
packages/nftablesbuilder/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
packages/nftablesbuilder/default.nix
Normal file
5
packages/nftablesbuilder/default.nix
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
pkgs.callPackage ./package.nix { }
|
||||||
69
packages/nftablesbuilder/package.nix
Normal file
69
packages/nftablesbuilder/package.nix
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
rustPlatform,
|
||||||
|
fetchFromGitHub,
|
||||||
|
fetchurl,
|
||||||
|
pkg-config,
|
||||||
|
openssl,
|
||||||
|
}:
|
||||||
|
|
||||||
|
rustPlatform.buildRustPackage rec {
|
||||||
|
pname = "nftablesbuilder";
|
||||||
|
# Pinned to a commit rather than a release tag because upstream
|
||||||
|
# publishes releases only as tarballs on nftablesbuilder.eu.
|
||||||
|
version = "0.1.0-unstable-2026-01-27";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "AiseBouma";
|
||||||
|
repo = "NftablesBuilder";
|
||||||
|
rev = "f414e921c2857556cdb4d602ed832a32a6951d25";
|
||||||
|
hash = "sha256-5qwyVXLrUxOk7poVdUyi/yJUq1CYMffruvAO0ONO+cI=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Upstream source is incomplete: both crates depend on a `settings`
|
||||||
|
# crate (path = "../settings") that was never committed, and the GUI
|
||||||
|
# has no build tooling (raw TSX, no package.json). This patch adds
|
||||||
|
# the missing settings crate (schema recovered from the official
|
||||||
|
# release artifacts) plus a workspace Cargo.toml.
|
||||||
|
patches = [ ./settings-workspace.patch ];
|
||||||
|
|
||||||
|
cargoLock.lockFile = ./Cargo.lock;
|
||||||
|
|
||||||
|
# Prebuilt GUI from the official release tarball, since the GUI cannot
|
||||||
|
# be built from source. Upstream serves releases with a self-signed
|
||||||
|
# TLS certificate, hence curlOpts = "-k"; the hash still pins content.
|
||||||
|
guiSrc = fetchurl {
|
||||||
|
url = "https://nftablesbuilder.eu/releases/latest/nftablesbuilder.tar.gz";
|
||||||
|
sha256 = "sha256-vHyuKVH4OtXEisWeDo+b3gHg3TzdXUSfMbaNpfQOrns=";
|
||||||
|
curlOpts = "-k";
|
||||||
|
};
|
||||||
|
|
||||||
|
nativeBuildInputs = [ pkg-config ];
|
||||||
|
buildInputs = [ openssl ];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
binDir=$(dirname "$(find target -type f -name nftablesbuilder -path '*/release/*' | head -1)")
|
||||||
|
install -Dm755 $binDir/nftablesbuilder $out/bin/nftablesbuilder
|
||||||
|
install -Dm755 $binDir/webserver $out/libexec/nftablesbuilder/webserver
|
||||||
|
|
||||||
|
mkdir -p $out/share/nftablesbuilder
|
||||||
|
tar -xzf $guiSrc -C $out/share/nftablesbuilder --strip-components=4 nftablesbuilder/root/opt/nftablesbuilder/html
|
||||||
|
install -Dm644 ${./settings.example} $out/share/nftablesbuilder/settings.example
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
category = "Networking";
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Web interface to manage nftables rules";
|
||||||
|
homepage = "https://github.com/AiseBouma/NftablesBuilder";
|
||||||
|
license = licenses.mit;
|
||||||
|
mainProgram = "nftablesbuilder";
|
||||||
|
platforms = platforms.linux;
|
||||||
|
};
|
||||||
|
}
|
||||||
2350
packages/nftablesbuilder/settings-workspace.patch
Normal file
2350
packages/nftablesbuilder/settings-workspace.patch
Normal file
File diff suppressed because it is too large
Load Diff
17
packages/nftablesbuilder/settings.example
Normal file
17
packages/nftablesbuilder/settings.example
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[connection]
|
||||||
|
port = 1969
|
||||||
|
|
||||||
|
[paths]
|
||||||
|
savepath = "/var/lib/nftablesbuilder"
|
||||||
|
htmlpath = "/run/current-system/sw/share/nftablesbuilder/html"
|
||||||
|
|
||||||
|
[files]
|
||||||
|
nft = "/run/current-system/sw/bin/nft"
|
||||||
|
test = "/tmp/nftables.conf"
|
||||||
|
conf = "/etc/nftables.conf"
|
||||||
|
webserver = "/run/current-system/sw/libexec/nftablesbuilder/webserver"
|
||||||
|
tlskey = "/var/lib/nftablesbuilder/nftables.key"
|
||||||
|
tlscert = "/var/lib/nftablesbuilder/nftables.crt"
|
||||||
|
|
||||||
|
[commands]
|
||||||
|
reload = "systemctl reload nftables"
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "3.8.28";
|
version = "3.8.49";
|
||||||
npmTarball = fetchurl {
|
npmTarball = fetchurl {
|
||||||
url = "https://registry.npmjs.org/omniroute/-/omniroute-${version}.tgz";
|
url = "https://registry.npmjs.org/omniroute/-/omniroute-${version}.tgz";
|
||||||
hash = "sha256-/le4p5DSX5T7/srNuxVBLepzUPw8BgIVio+h0JnbfyY=";
|
hash = "sha256-fcGsAxOdv1ZSwt24eHJu97lyRATKBw8rYeFvGTRhxYs=";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
|
||||||
@@ -23,12 +23,12 @@ buildNpmPackage (finalAttrs: {
|
|||||||
owner = "diegosouzapw";
|
owner = "diegosouzapw";
|
||||||
repo = "OmniRoute";
|
repo = "OmniRoute";
|
||||||
rev = "v${finalAttrs.version}";
|
rev = "v${finalAttrs.version}";
|
||||||
hash = "sha256-BRvpbhhLTYj2rKw+nZloaXkpu3ySs5sWZo9425xvAPs=";
|
hash = "sha256-nRLziV4NWPoa0ev57DV7jmAvLpL/1MP1EMZO2/drrTU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
nodejs = nodejs_22;
|
nodejs = nodejs_22;
|
||||||
|
|
||||||
npmDepsHash = "sha256-Q1KLR3NkeFBB+tQzBazy+XWyIfpG8Magv+rdeqISNxw=";
|
npmDepsHash = "sha256-R0u93MLUUWC8xFgq4S0Aj/7wg4pygTKwxP/eWkWMgCw=";
|
||||||
|
|
||||||
# Skip Next.js build (requires network for Google Fonts).
|
# Skip Next.js build (requires network for Google Fonts).
|
||||||
# Pre-built dist/ is copied from the npm tarball in preConfigure.
|
# Pre-built dist/ is copied from the npm tarball in preConfigure.
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
version = "1.6.1";
|
version = "1.9.1";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "skyhook-io";
|
owner = "skyhook-io";
|
||||||
repo = "radar";
|
repo = "radar";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-vctvMD7sca7HgEM1ufnUClhc04ucnvl3Zx4jTfaAzyE=";
|
hash = "sha256-VZLzmxW86yMtYILhmKswkj57KD4Z+8ILwHKiO53YMWE=";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Build the frontend as a separate derivation.
|
# Build the frontend as a separate derivation.
|
||||||
@@ -23,34 +23,10 @@ let
|
|||||||
inherit version src;
|
inherit version src;
|
||||||
sourceRoot = "source";
|
sourceRoot = "source";
|
||||||
|
|
||||||
postPatch = ''
|
# Upstream lockfile ships complete resolved/integrity fields for all
|
||||||
# Fix missing resolved URLs for packages under web/node_modules/
|
# packages since v1.9.x, so no lockfile patching is needed anymore.
|
||||||
# WARNING: This sed is version-specific — if upstream bumps a
|
|
||||||
# transitive dep version, the patterns silently fail and the
|
|
||||||
# build breaks. Update resolved/integrity values when bumping radar.
|
|
||||||
# that are actually external npm packages (not workspace links).
|
|
||||||
# Insert "resolved" and "integrity" after the "version" field
|
|
||||||
# for each affected package using sed.
|
|
||||||
sed -i \
|
|
||||||
-e '/"web\/node_modules\/@vitejs\/plugin-react"/,/^[[:space:]]*}/{
|
|
||||||
/"version"/a\
|
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz",\
|
|
||||||
"integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==",
|
|
||||||
}' \
|
|
||||||
-e '/"web\/node_modules\/@rolldown\/pluginutils"/,/^[[:space:]]*}/{
|
|
||||||
/"version"/a\
|
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz",\
|
|
||||||
"integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==",
|
|
||||||
}' \
|
|
||||||
-e '/"web\/node_modules\/@types\/diff"/,/^[[:space:]]*}/{
|
|
||||||
/"version"/a\
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/diff/-/diff-8.0.0.tgz",\
|
|
||||||
"integrity": "sha512-o7jqJM04gfaYrdCecCVMbZhNdG6T1MHg/oQoRFdERLV+4d+V7FijhiEAbFu0Usww84Yijk9yH58U4Jk4HbtzZw==",
|
|
||||||
}' \
|
|
||||||
package-lock.json
|
|
||||||
'';
|
|
||||||
|
|
||||||
npmDepsHash = "sha256-6t0Q3Xzrk1w8zC00H721o/OzHxNhAfCH7EdRXrKQsAg=";
|
npmDepsHash = "sha256-9xS5ChQ1xBix/n9N8vyBsHlHYmYXsibTK5J+X6mRgM4=";
|
||||||
npmDepsFetcherVersion = 2;
|
npmDepsFetcherVersion = 2;
|
||||||
makeCacheWritable = true;
|
makeCacheWritable = true;
|
||||||
|
|
||||||
@@ -78,7 +54,7 @@ buildGoModule {
|
|||||||
pname = "radar";
|
pname = "radar";
|
||||||
inherit version src;
|
inherit version src;
|
||||||
|
|
||||||
vendorHash = "sha256-vhp0dNPKTOg2NUVD5QoLuTnCumdwzDypvh/rUEhGbL4=";
|
vendorHash = "sha256-d26tlh+Twv9GFX6NmR25Q9OpP/pUL2T4grdncQHYSg4=";
|
||||||
|
|
||||||
# Copy pre-built frontend assets before Go compilation for go:embed
|
# Copy pre-built frontend assets before Go compilation for go:embed
|
||||||
preBuild = ''
|
preBuild = ''
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
let
|
let
|
||||||
cerebras-cloud-sdk = python3Packages.buildPythonPackage rec {
|
cerebras-cloud-sdk = python3Packages.buildPythonPackage rec {
|
||||||
pname = "cerebras-cloud-sdk";
|
pname = "cerebras-cloud-sdk";
|
||||||
version = "1.67.0";
|
version = "1.91.0";
|
||||||
pyproject = true;
|
pyproject = true;
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://files.pythonhosted.org/packages/92/12/c201f07582068141e88f9a523ab02fdc97de58f2f7c0df775c6c52b9d8dd/cerebras_cloud_sdk-1.67.0.tar.gz";
|
url = "https://files.pythonhosted.org/packages/0c/98/767ab62618be157b5fb21bce980ad5c8ebe155e32aff38521e511054e5c3/cerebras_cloud_sdk-1.91.0.tar.gz";
|
||||||
hash = "sha256-Ou1vhsbHqD7p1M+wiirOoInOvyr1uK7RFu95mVpPSBM=";
|
hash = "sha256-b0GT/sCIkR/+gpzlaCUQ+GEgzTUyyvToVAvzO1n9t+s=";
|
||||||
};
|
};
|
||||||
|
|
||||||
build-system = with python3Packages; [
|
build-system = with python3Packages; [
|
||||||
@@ -65,8 +65,8 @@ python3Packages.buildPythonApplication {
|
|||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "msmarkgu";
|
owner = "msmarkgu";
|
||||||
repo = "RelayFreeLLM";
|
repo = "RelayFreeLLM";
|
||||||
rev = "fea9e1642dbbc5c0980885f41b21aa04a30090a2";
|
rev = "96e6c48a552755bf250c3155b14176916c69d8d8";
|
||||||
hash = "sha256-ZLAVhJFrVFjqAz0f4qOi2REBDccIc8g2H9b7dcqcYRU=";
|
hash = "sha256-SNux6hVOij+2kYFH/gUQQj8QLfxGzjcdakkZ48AIWPU=";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ makeWrapper ];
|
nativeBuildInputs = [ makeWrapper ];
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage rec {
|
||||||
pname = "stakpak";
|
pname = "stakpak";
|
||||||
version = "0.3.86";
|
version = "0.3.88";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "stakpak";
|
owner = "stakpak";
|
||||||
repo = "agent";
|
repo = "agent";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
hash = "sha256-k8fOgwn1Sh3Yg62ROzfKJym8AGewpZ3/2e3tHNRL7/0=";
|
hash = "sha256-rTqRxfAFQChA5fjW5VVxGThH0X7OodF1SdviMd3dK78=";
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoHash = "sha256-aa1YjyShoSNv9sC18gIx/kuAbxrNAsCE+2if8Rm2uiw=";
|
cargoHash = "sha256-jf0PqcoNtfdcDNayPNVNeWNaa0acuUJeb3CYLKN6VeA=";
|
||||||
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
nativeBuildInputs = [ pkg-config ];
|
||||||
|
|
||||||
|
|||||||
1
packages/traycer/default.nix
Normal file
1
packages/traycer/default.nix
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{ pkgs, ... }: pkgs.callPackage ./package.nix { }
|
||||||
56
packages/traycer/package.nix
Normal file
56
packages/traycer/package.nix
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
appimageTools,
|
||||||
|
fetchurl,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
version = "1.1.10";
|
||||||
|
src = fetchurl {
|
||||||
|
url = "https://github.com/traycerai/traycer/releases/download/desktop-v${version}/traycer-desktop-linux-x86_64.AppImage";
|
||||||
|
hash = "sha256-+aSlqX1RCpbKuV0j7xEBMQDAq/IzpvCC5XZ/psQJcjY=";
|
||||||
|
};
|
||||||
|
appimageContents = appimageTools.extractType2 {
|
||||||
|
pname = "traycer";
|
||||||
|
inherit version src;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
appimageTools.wrapType2 {
|
||||||
|
pname = "traycer";
|
||||||
|
inherit version src;
|
||||||
|
|
||||||
|
extraPkgs = pkgsWith: [
|
||||||
|
pkgsWith.gtk3
|
||||||
|
pkgsWith.glib
|
||||||
|
];
|
||||||
|
|
||||||
|
extraInstallCommands = ''
|
||||||
|
mkdir -p $out/share/applications
|
||||||
|
install -m 444 ${appimageContents}/traycer-desktop.desktop $out/share/applications/traycer.desktop
|
||||||
|
substituteInPlace $out/share/applications/traycer.desktop \
|
||||||
|
--replace-fail 'Exec=AppRun --no-sandbox %U' 'Exec=traycer --no-sandbox %U'
|
||||||
|
|
||||||
|
mkdir -p $out/share/icons/hicolor
|
||||||
|
cp -r ${appimageContents}/usr/share/icons/hicolor/* $out/share/icons/hicolor/
|
||||||
|
'';
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
category = "AI Coding Agents";
|
||||||
|
updateScript = [
|
||||||
|
"nix-update"
|
||||||
|
"--flake"
|
||||||
|
".#traycer"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Open-source AI orchestration app for agentic coding";
|
||||||
|
homepage = "https://github.com/traycerai/traycer";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = [ ];
|
||||||
|
platforms = [ "x86_64-linux" ];
|
||||||
|
mainProgram = "traycer";
|
||||||
|
sourceProvenance = [ lib.sourceTypes.binaryNativeCode ];
|
||||||
|
};
|
||||||
|
}
|
||||||
11
skills-lock.json
Normal file
11
skills-lock.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"skills": {
|
||||||
|
"karpathy-guidelines": {
|
||||||
|
"source": "szkocot/andrej-karpathy-skills",
|
||||||
|
"sourceType": "github",
|
||||||
|
"skillPath": "skills/karpathy-guidelines/SKILL.md",
|
||||||
|
"computedHash": "41e8ca055bbde13d240776a14a076a59614057200340c243130a76ba4e64cac8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user