Author SHA1 Message Date
m3ta-chiron ef421306dd chore: flake update 2026-08-01 11:06:19 +02:00
m3ta-chiron 58fecf72df feat: migrate host Hyprland overrides to Lua 2026-08-01 10:53:09 +02:00
m3ta-chiron 4b65a6c3b1 chore: flake update 2026-07-30 14:31:49 +02:00
m3ta-chiron 43ce336675 +qmd 2026-07-30 06:46:23 +02:00
m3ta-chiron 673a1908d2 chore: flake update 2026-07-25 14:54:22 +02:00
m3ta-chiron e761d91ab5 chore: update + fix pnpm upstream bug 2026-07-10 15:19:44 +02:00
m3ta-chiron 4d1c4a859b chore: flake update 2026-07-07 19:49:53 +02:00
m3ta-chiron 08c0773472 chore: update 2026-07-05 18:42:20 +02:00
m3ta-chiron 02773fcc0b flake update 2026-07-03 08:28:30 +02:00
m3ta-chiron 8041f5306e hermes rollback because of matrix gateway problem 2026-06-27 12:01:52 +02:00
m3ta-chiron 4ba56269ff flake update 2026-06-27 10:45:32 +02:00
m3ta-chiron 99c8ff04cd merge flake.lock 2026-06-27 10:37:25 +02:00
m3ta-chiron 1df2d9576e chore: some updates 2026-06-27 10:27:35 +02:00
m3ta-chiron 2fac7fd6d9 flake update 2026-06-21 21:24:46 +02:00
m3ta-chiron cccc0d6a05 fix: vibetyper hyprland setting 2026-06-20 10:59:39 +02:00
m3ta-chiron 3397514743 chore: vibetyper rec indicator agent-skills update 2026-06-20 08:47:23 +02:00
m3ta-chiron 89a1584f6f chore: vibetyper update 2026-06-16 19:42:58 +02:00
m3ta-chiron 45ac13141c update agent-lib 2026-06-13 14:22:20 +02:00
m3ta-chiron 879bdb3005 refactor: consume agent-lib through m3ta-home 2026-06-13 09:25:40 +02:00
m3ta-chiron c692ca1c63 fix: nix eval warnings 2026-06-11 17:42:43 +02:00
m3ta-chiron 2a1dbe540a fix: ksnip crash 2026-06-11 09:29:20 +02:00
m3ta-chiron 93216125d6 Merge branch 'master' of code.m3ta.dev:m3tam3re/nixos-config 2026-06-11 08:53:30 +02:00
m3ta-chiron 690475af84 flake update 2026-06-11 07:50:09 +02:00
m3ta-chiron 80c49a6727 chore: pin m3-atlas ghost to version 6 2026-06-09 18:40:25 +02:00
m3ta-chiron 8b495c6bc9 fix: lock m3ta-home git input 2026-06-07 11:11:06 +02:00
m3ta-chiron 9bceb1c6d0 fix: make inputs self-contained 2026-06-06 13:15:27 +02:00
m3ta-chiron a5d321805b merge into master 2026-06-06 08:02:37 +02:00
m3ta-chiron 651b808f15 +agents-lib in m3ta-home 2026-05-31 14:37:46 +02:00
26 changed files with 1233 additions and 802 deletions
@@ -0,0 +1,5 @@
{
"nixosConfigDir": "/home/m3tam3re/p/NIX/nixos-config",
"m3taHomeDir": "/home/m3tam3re/p/NIX/m3ta-home",
"specPath": "/home/m3tam3re/p/NIX/nixos-config/.a5c/inputs/fix-eval-warnings-spec.md"
}
+10
View File
@@ -0,0 +1,10 @@
Fix the following Nix/Home Manager evaluation warnings except for the gc/nh conflict warning:
- `evaluation warning: 'system' has been renamed to/replaced by 'stdenv.hostPlatform.system'`
- `evaluation warning: m3tam3re profile: programs.ssh.matchBlocks defined in /nix/store/...-users/m3tam3re/identities/private.nix is deprecated. Use programs.ssh.settings.`
Do not fix or change the warning:
- `evaluation warning: programs.nh.clean.enable and nix.gc.automatic are both enabled. Please use one or the other to avoid conflict.`
The private identity source file is in `/home/m3tam3re/p/NIX/m3ta-home/users/m3tam3re/identities/private.nix`.
+301
View File
@@ -0,0 +1,301 @@
/**
* @process local/fix-nix-eval-warnings
* @description Fix Nix/Home Manager evaluation warnings except the nh/gc conflict warning.
* @skill systematic-debugging methodologies/superpowers/systematic-debugging.js
* @skill verification-before-completion methodologies/superpowers/verification-before-completion.js
* @skill root-cause-diagnosis methodologies/shared/root-cause-diagnosis.js
*/
import { defineTask } from '@a5c-ai/babysitter-sdk';
const q = (value) => `'${String(value).replace(/'/g, `'\\''`)}'`;
export async function process(inputs, ctx) {
const nixosConfigDir = inputs.nixosConfigDir || '/home/m3tam3re/p/NIX/nixos-config';
const m3taHomeDir = inputs.m3taHomeDir || '/home/m3tam3re/p/NIX/m3ta-home';
const specPath = inputs.specPath || `${nixosConfigDir}/.a5c/inputs/fix-eval-warnings-spec.md`;
const spec = await ctx.task(readSpecTask, { specPath });
const inspection = await ctx.task(inspectWarningSourcesTask, {
nixosConfigDir,
m3taHomeDir,
});
const implementation = await ctx.task(implementFixesTask, {
nixosConfigDir,
m3taHomeDir,
spec: spec.stdout,
inspection: inspection.stdout,
});
const formatting = await ctx.task(formatChangedNixTask, {
m3taHomeDir,
});
const verification = await ctx.task(verifyWarningsTask, {
nixosConfigDir,
m3taHomeDir,
});
const artifacts = await ctx.task(collectArtifactsTask, {
nixosConfigDir,
m3taHomeDir,
verifyStdout: verification.stdout || '',
verifyStderr: verification.stderr || '',
});
const acceptance = await ctx.task(acceptanceReviewTask, {
spec: spec.stdout,
artifacts: artifacts.stdout,
});
if (!acceptance.accepted) {
await ctx.breakpoint({
title: 'Warning fix acceptance review failed',
question: `Acceptance review did not approve the changes: ${acceptance.reason}`,
context: {
runId: ctx.runId,
files: [
{ path: `${m3taHomeDir}/users/m3tam3re/identities/private.nix`, format: 'nix', label: 'Private SSH identity' },
{ path: `${m3taHomeDir}/profiles/sets/coding/agents/agents.nix`, format: 'nix', label: 'Agent packages' },
{ path: `${m3taHomeDir}/profiles/contexts/desktop/default.nix`, format: 'nix', label: 'Desktop packages' },
],
},
});
}
return {
success: acceptance.accepted,
summary: implementation.summary,
changedFiles: implementation.changedFiles,
verification: {
formatting: formatting.stdout,
warnings: verification.stdout,
review: acceptance,
},
};
}
export const readSpecTask = defineTask('read-spec', (args, taskCtx) => ({
kind: 'shell',
title: 'Read warning-fix spec',
shell: {
command: `cat ${q(args.specPath)}`,
expectedExitCode: 0,
timeout: 10000,
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/output.json`,
},
labels: ['spec', 'shell'],
}));
export const inspectWarningSourcesTask = defineTask('inspect-warning-sources', (args, taskCtx) => ({
kind: 'shell',
title: 'Inspect current warning sources',
shell: {
command: [
'set -euo pipefail',
`echo '== nixos-config status =='`,
`cd ${q(args.nixosConfigDir)} && git status --short`,
`echo`,
`echo '== m3ta-home status =='`,
`cd ${q(args.m3taHomeDir)} && git status --short`,
`echo`,
`echo '== active pkgs.system-style package selectors =='`,
`grep -RIn --include='*.nix' -E 'packages[.]\\$\\{pkgs[.]system\\}|packages[.]\\$\\{prev[.]system\\}|packages[.]\\$\\{final[.]system\\}' ${q(args.nixosConfigDir)} ${q(args.m3taHomeDir)} || true`,
`echo`,
`echo '== SSH matchBlocks in m3ta-home identities =='`,
`grep -RIn --include='*.nix' 'matchBlocks' ${q(`${args.m3taHomeDir}/users/m3tam3re/identities`)} || true`,
].join('\n'),
expectedExitCode: 0,
timeout: 30000,
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/output.json`,
},
labels: ['diagnosis', 'shell'],
}));
export const implementFixesTask = defineTask('implement-warning-fixes', (args, taskCtx) => ({
kind: 'agent',
title: 'Implement requested warning fixes',
agent: {
name: 'worker',
prompt: {
role: 'Nix/Home Manager maintenance engineer',
task: 'Edit the repositories to remove the requested evaluation warnings, excluding the nh/gc warning by request.',
context: {
nixosConfigDir: args.nixosConfigDir,
m3taHomeDir: args.m3taHomeDir,
specVerbatim: args.spec,
inspectionStdout: args.inspection,
},
instructions: [
'Execute the task fully; do not just provide a plan.',
'Do not invoke the babysit skill or create another babysitter run.',
'Read every file before editing it.',
'Preserve unrelated existing user changes, especially any dirty files in nixos-config such as flake.nix or flake.lock.',
'Fix active uses of pkgs.system/prev.system/final.system that trigger the Nixpkgs deprecation warning by using stdenv.hostPlatform.system through the appropriate package set.',
'Migrate /home/m3tam3re/p/NIX/m3ta-home/users/m3tam3re/identities/private.nix from programs.ssh.matchBlocks to programs.ssh.settings.',
'For programs.ssh.settings, use OpenSSH directive names such as HostName, User, Port, and IdentityFile; do not keep legacy camelCase option names under settings.',
'Do not change programs.nh.clean.enable or nix.gc.automatic; the user explicitly excluded that warning.',
'Keep the change minimal and focused on the warnings in the spec.',
'Run a quick static check of the edited files if practical, but leave deterministic verification to the process quality gate.',
],
outputFormat: 'JSON with summary, changedFiles, and verificationNotes.',
},
outputSchema: {
type: 'object',
required: ['summary', 'changedFiles', 'verificationNotes'],
properties: {
summary: { type: 'string' },
changedFiles: { type: 'array', items: { type: 'string' } },
verificationNotes: { type: 'array', items: { type: 'string' } },
},
},
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/output.json`,
},
labels: ['implementation', 'agent', 'nix'],
}));
export const formatChangedNixTask = defineTask('format-changed-nix', (args, taskCtx) => ({
kind: 'shell',
title: 'Format changed Nix files',
shell: {
command: [
'set -euo pipefail',
`cd ${q(args.m3taHomeDir)}`,
`if command -v alejandra >/dev/null 2>&1; then`,
` alejandra users/m3tam3re/identities/private.nix profiles/sets/coding/agents/agents.nix profiles/contexts/desktop/default.nix`,
`else`,
` nix run nixpkgs#alejandra -- users/m3tam3re/identities/private.nix profiles/sets/coding/agents/agents.nix profiles/contexts/desktop/default.nix`,
`fi`,
].join('\n'),
expectedExitCode: 0,
timeout: 120000,
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/output.json`,
},
labels: ['format', 'shell'],
}));
export const verifyWarningsTask = defineTask('verify-warning-removal', (args, taskCtx) => ({
kind: 'shell',
title: 'Verify requested warnings are gone',
shell: {
command: [
'set -euo pipefail',
`echo '== static checks =='`,
`! grep -RIn --include='*.nix' -E 'packages[.]\\$\\{pkgs[.]system\\}|packages[.]\\$\\{prev[.]system\\}|packages[.]\\$\\{final[.]system\\}' ${q(`${args.m3taHomeDir}/profiles`)} || { echo 'Found deprecated package system selector' >&2; exit 1; }`,
`! grep -n 'matchBlocks' ${q(`${args.m3taHomeDir}/users/m3tam3re/identities/private.nix`)} || { echo 'private.nix still uses matchBlocks' >&2; exit 1; }`,
`grep -n 'settings = {' ${q(`${args.m3taHomeDir}/users/m3tam3re/identities/private.nix`)}`,
`echo`,
`echo '== nix eval m3-ares =='`,
`cd ${q(args.nixosConfigDir)}`,
`eval_stdout=$(mktemp)`,
`eval_stderr=$(mktemp)`,
`set +e`,
`nix eval .#nixosConfigurations.m3-ares.config.system.build.toplevel.drvPath --show-trace >"$eval_stdout" 2>"$eval_stderr"`,
`status=$?`,
`set -e`,
`cat "$eval_stdout"`,
`cat "$eval_stderr" >&2`,
`if [ "$status" -ne 0 ]; then exit "$status"; fi`,
`if grep -F "'system' has been renamed" "$eval_stderr"; then echo 'Deprecated system warning still present' >&2; exit 1; fi`,
`if grep -F 'programs.ssh.matchBlocks' "$eval_stderr"; then echo 'Deprecated SSH matchBlocks warning still present' >&2; exit 1; fi`,
`if grep -F 'programs.nh.clean.enable and nix.gc.automatic' "$eval_stderr" >/dev/null; then echo 'Allowed nh/gc warning remains by request.'; fi`,
].join('\n'),
expectedExitCode: 0,
timeout: 300000,
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/output.json`,
},
labels: ['verification', 'shell', 'nix'],
}));
export const collectArtifactsTask = defineTask('collect-artifacts', (args, taskCtx) => ({
kind: 'shell',
title: 'Collect diffs and verification output',
shell: {
command: [
'set -euo pipefail',
`echo '== m3ta-home diff =='`,
`cd ${q(args.m3taHomeDir)} && git diff -- users/m3tam3re/identities/private.nix profiles/sets/coding/agents/agents.nix profiles/contexts/desktop/default.nix`,
`echo`,
`echo '== nixos-config diff (should not include warning fix unless needed) =='`,
`cd ${q(args.nixosConfigDir)} && git diff -- overlays/default.nix flake.nix flake.lock || true`,
`echo`,
`echo '== verification stdout =='`,
`cat <<'VERIFY_STDOUT'`,
args.verifyStdout || '',
`VERIFY_STDOUT`,
`echo`,
`echo '== verification stderr =='`,
`cat <<'VERIFY_STDERR'`,
args.verifyStderr || '',
`VERIFY_STDERR`,
].join('\n'),
expectedExitCode: 0,
timeout: 30000,
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/output.json`,
},
labels: ['artifacts', 'shell'],
}));
export const acceptanceReviewTask = defineTask('acceptance-review', (args, taskCtx) => ({
kind: 'agent',
title: 'Review changes against requested warning fixes',
agent: {
name: 'reviewer',
prompt: {
role: 'Acceptance reviewer for a Nix/Home Manager warning fix',
task: 'Compare SPEC to ARTIFACTS directly and decide whether the requested warnings were fixed without touching the excluded nh/gc warning.',
instructions: [
'Ignore any narrative in your context about how ARTIFACTS were built.',
'Do not ask for additional changes unless they are required by the SPEC.',
'Accept if the system deprecation warning and private SSH matchBlocks warning are addressed, and the nh/gc conflict remains untouched.',
'',
'SPEC (verbatim):',
'---',
args.spec,
'---',
'',
'ARTIFACTS (verbatim):',
'---',
args.artifacts,
'---',
'',
'Compare SPEC to ARTIFACTS directly. Ignore any narrative in your context about how ARTIFACTS were built.',
],
outputFormat: 'JSON with accepted boolean, reason string, and checkedCriteria array.',
},
outputSchema: {
type: 'object',
required: ['accepted', 'reason', 'checkedCriteria'],
properties: {
accepted: { type: 'boolean' },
reason: { type: 'string' },
checkedCriteria: { type: 'array', items: { type: 'string' } },
},
},
},
io: {
inputJsonPath: `tasks/${taskCtx.effectId}/input.json`,
outputJsonPath: `tasks/${taskCtx.effectId}/output.json`,
},
labels: ['acceptance', 'agent', 'review'],
}));
+160 -51
View File
@@ -533,6 +533,17 @@
},
"path": "skills/changelog"
},
"crunch-jobs": {
"entry": "skills/crunch-jobs/SKILL.md",
"licenseFiles": [],
"metadata": {
"description": "Use when: (1) The user asks to be reminded at a specific time, (2) Schedule recurring notifications, (3) Set up AI-powered scheduled jobs (summarize, review, report), (4) Run custom pipeline scripts on a schedule with voice output. Triggers: remind me, erinnere mich, schedule, cron, daily, weekly, täglich, jeden Montag, crunch, talk at, notify me at, voice reminder.",
"name": "crunch-jobs",
"requires": [],
"tags": []
},
"path": "skills/crunch-jobs"
},
"doc-translator": {
"entry": "skills/doc-translator/SKILL.md",
"licenseFiles": [],
@@ -555,6 +566,17 @@
},
"path": "skills/excalidraw"
},
"m3ta-brain": {
"entry": "skills/m3ta-brain/SKILL.md",
"licenseFiles": [],
"metadata": {
"description": "Shared Obsidian vault for human-agent collaboration. Use when: (1) Loading project context at session start (auto-recall), (2) Writing session summaries, decisions, project updates, or learning notes, (3) Searching for past decisions or project state, (4) Running nightly/weekly digest passes, (5) Creating or updating person profiles, (6) Any reference to 'the vault', 'shared brain', 'our context', 'what did we decide'. Triggers: m3ta-brain, shared brain, vault, session summary, decision note, project update, memory candidate, brain vault, auto-recall, digest, nightly pass.",
"name": "m3ta-brain",
"requires": [],
"tags": []
},
"path": "skills/m3ta-brain"
},
"mem0-memory": {
"entry": "skills/mem0-memory/SKILL.md",
"licenseFiles": [],
@@ -643,6 +665,17 @@
},
"path": "skills/reflection"
},
"shared-brain-vault": {
"entry": "skills/shared-brain-vault/SKILL.md",
"licenseFiles": [],
"metadata": {
"description": "Build and maintain a Git-synced Obsidian vault as shared working memory between user and AI agents. Use when: (1) Writing session summaries or project updates, (2) Recording decisions or learnings, (3) Adding people/profiles to the vault, (4) Populating or restructuring the vault, (5) Setting up multi-agent vault access, (6) Answering 'what did we decide' or 'where do we stand on X'. Triggers: 'shared brain', 'm3ta-brain', 'session summary', 'vault update', 'decision note', 'project status', 'what did we decide'.",
"name": "shared-brain-vault",
"requires": [],
"tags": []
},
"path": "skills/shared-brain-vault"
},
"skill-creator": {
"entry": "skills/skill-creator/SKILL.md",
"licenseFiles": [],
@@ -665,6 +698,17 @@
},
"path": "skills/systematic-debugging"
},
"voice-notify": {
"entry": "skills/voice-notify/SKILL.md",
"licenseFiles": [],
"metadata": {
"description": "Use when: (1) A long-running task (build, test, migration, cruncher job) completes, (2) The user asks to be notified audibly, (3) An agent finishes delegated work and should announce results, (4) Important errors or completions need immediate attention. Triggers: talk, voice, notify, audio, abbrechen, notify me, let me know when done, cruncher, job complete.",
"name": "voice-notify",
"requires": [],
"tags": []
},
"path": "skills/voice-notify"
},
"xlsx": {
"entry": "skills/xlsx/SKILL.md",
"licenseFiles": [],
@@ -679,9 +723,9 @@
},
"tools": {}
},
"narHash": "sha256:640f5c15e9124526564a5438952c3231d9fa3cbab6a4e6b1cecdf4cd280c7847",
"narHash": "sha256:c119e6197eb556c9c00a13a88d2e8f42d740c724262b2b0e2ac6fb05456fe621",
"ref": null,
"rev": "920c00313ae242bd93275c30131b9ab1e52ee2fb",
"rev": "83284d752d2ac325d4bf3ab7b38acad1c2fffe3a",
"root": ".",
"type": "git",
"url": "https://code.m3ta.dev/m3tam3re/AGENTS",
@@ -726,18 +770,44 @@
"agents": {},
"prompts": {},
"skills": {
"caveman": {
"entry": "skills/productivity/caveman/SKILL.md",
"ask-matt": {
"entry": "skills/engineering/ask-matt/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": ">",
"name": "caveman",
"description": "Ask which skill or flow fits your situation. A router over the user-invoked skills in this repo.",
"name": "ask-matt",
"requires": [],
"tags": []
},
"path": "skills/productivity/caveman"
"path": "skills/engineering/ask-matt"
},
"codebase-design": {
"entry": "skills/engineering/codebase-design/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.",
"name": "codebase-design",
"requires": [],
"tags": []
},
"path": "skills/engineering/codebase-design"
},
"decision-mapping": {
"entry": "skills/in-progress/decision-mapping/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Turn a loose idea into a sequenced map of investigation tickets, then drive them to resolution one at a time.",
"name": "decision-mapping",
"requires": [],
"tags": []
},
"path": "skills/in-progress/decision-mapping"
},
"design-an-interface": {
"entry": "skills/deprecated/design-an-interface/SKILL.md",
@@ -752,18 +822,31 @@
},
"path": "skills/deprecated/design-an-interface"
},
"diagnose": {
"entry": "skills/engineering/diagnose/SKILL.md",
"diagnosing-bugs": {
"entry": "skills/engineering/diagnosing-bugs/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says \"diagnose this\" / \"debug this\", reports a bug, says something is broken/throwing/failing, or describes a performance regression.",
"name": "diagnose",
"description": "Diagnosis loop for hard bugs and performance regressions. Use when the user says \"diagnose\"/\"debug this\", or reports something broken/throwing/failing/slow.",
"name": "diagnosing-bugs",
"requires": [],
"tags": []
},
"path": "skills/engineering/diagnose"
"path": "skills/engineering/diagnosing-bugs"
},
"domain-modeling": {
"entry": "skills/engineering/domain-modeling/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model.",
"name": "domain-modeling",
"requires": [],
"tags": []
},
"path": "skills/engineering/domain-modeling"
},
"edit-article": {
"entry": "skills/personal/edit-article/SKILL.md",
@@ -797,7 +880,7 @@
"LICENSE"
],
"metadata": {
"description": "Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions \"grill me\".",
"description": "A relentless interview to sharpen a plan or design.",
"name": "grill-me",
"requires": [],
"tags": []
@@ -810,13 +893,26 @@
"LICENSE"
],
"metadata": {
"description": "Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.",
"description": "A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.",
"name": "grill-with-docs",
"requires": [],
"tags": []
},
"path": "skills/engineering/grill-with-docs"
},
"grilling": {
"entry": "skills/productivity/grilling/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Interview the user relentlessly about a plan or design. Use when the user wants to stress-test a plan before building, or uses any 'grill' trigger phrases.",
"name": "grilling",
"requires": [],
"tags": []
},
"path": "skills/productivity/grilling"
},
"handoff": {
"entry": "skills/productivity/handoff/SKILL.md",
"licenseFiles": [
@@ -830,13 +926,26 @@
},
"path": "skills/productivity/handoff"
},
"implement": {
"entry": "skills/engineering/implement/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Implement a piece of work based on a PRD or set of issues.",
"name": "implement",
"requires": [],
"tags": []
},
"path": "skills/engineering/implement"
},
"improve-codebase-architecture": {
"entry": "skills/engineering/improve-codebase-architecture/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Find deepening opportunities in a codebase, informed by the domain language in CONTEXT.md and the decisions in docs/adr/. Use when the user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more testable and AI-navigable.",
"description": "Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.",
"name": "improve-codebase-architecture",
"requires": [],
"tags": []
@@ -875,7 +984,7 @@
"LICENSE"
],
"metadata": {
"description": "Build a throwaway prototype to flesh out a design before committing to it. Routes between two branches — a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route. Use when the user wants to prototype, sanity-check a data model or state machine, mock up a UI, explore design options, or says \"prototype this\", \"let me play with it\", \"try a few designs\".",
"description": "Build a throwaway prototype to flesh out a design — a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route.",
"name": "prototype",
"requires": [],
"tags": []
@@ -908,6 +1017,19 @@
},
"path": "skills/deprecated/request-refactor-plan"
},
"resolving-merge-conflicts": {
"entry": "skills/engineering/resolving-merge-conflicts/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Use when you need to resolve an in-progress git merge/rebase conflict.",
"name": "resolving-merge-conflicts",
"requires": [],
"tags": []
},
"path": "skills/engineering/resolving-merge-conflicts"
},
"review": {
"entry": "skills/in-progress/review/SKILL.md",
"licenseFiles": [
@@ -940,7 +1062,7 @@
"LICENSE"
],
"metadata": {
"description": "Sets up an `## Agent skills` block in AGENTS.md/CLAUDE.md and `docs/agents/` so the engineering skills know this repo's issue tracker (GitHub or local markdown), triage label vocabulary, and domain doc layout. Run before first use of `to-issues`, `to-prd`, `triage`, `diagnose`, `tdd`, `improve-codebase-architecture`, or `zoom-out` — or if those skills appear to be missing context about the issue tracker, triage labels, or domain docs.",
"description": "Configure this repo for the engineering skills — set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.",
"name": "setup-matt-pocock-skills",
"requires": [],
"tags": []
@@ -966,7 +1088,7 @@
"LICENSE"
],
"metadata": {
"description": "Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions \"red-green-refactor\", wants integration tests, or asks for test-first development.",
"description": "Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions \"red-green-refactor\", or wants integration tests.",
"name": "tdd",
"requires": [],
"tags": []
@@ -974,7 +1096,7 @@
"path": "skills/engineering/tdd"
},
"teach": {
"entry": "skills/in-progress/teach/SKILL.md",
"entry": "skills/productivity/teach/SKILL.md",
"licenseFiles": [
"LICENSE"
],
@@ -984,7 +1106,7 @@
"requires": [],
"tags": []
},
"path": "skills/in-progress/teach"
"path": "skills/productivity/teach"
},
"to-issues": {
"entry": "skills/engineering/to-issues/SKILL.md",
@@ -992,7 +1114,7 @@
"LICENSE"
],
"metadata": {
"description": "Break a plan, spec, or PRD into independently-grabbable issues on the project issue tracker using tracer-bullet vertical slices. Use when user wants to convert a plan into issues, create implementation tickets, or break down work into issues.",
"description": "Break a plan, spec, or PRD into independently-grabbable issues on the project issue tracker using tracer-bullet vertical slices.",
"name": "to-issues",
"requires": [],
"tags": []
@@ -1005,7 +1127,7 @@
"LICENSE"
],
"metadata": {
"description": "Turn the current conversation context into a PRD and publish it to the project issue tracker. Use when user wants to create a PRD from the current context.",
"description": "Turn the current conversation into a PRD and publish it to the project issue tracker — no interview, just synthesis of what you've already discussed.",
"name": "to-prd",
"requires": [],
"tags": []
@@ -1018,7 +1140,7 @@
"LICENSE"
],
"metadata": {
"description": "Triage issues through a state machine driven by triage roles. Use when user wants to create an issue, triage issues, review incoming bugs or feature requests, prepare issues for an AFK agent, or manage issue workflow.",
"description": "Move issues and external PRs through a state machine of triage roles — categorise, verify, grill if needed, and write agent-ready briefs.",
"name": "triage",
"requires": [],
"tags": []
@@ -1038,19 +1160,6 @@
},
"path": "skills/deprecated/ubiquitous-language"
},
"write-a-skill": {
"entry": "skills/productivity/write-a-skill/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill.",
"name": "write-a-skill",
"requires": [],
"tags": []
},
"path": "skills/productivity/write-a-skill"
},
"writing-beats": {
"entry": "skills/in-progress/writing-beats/SKILL.md",
"licenseFiles": [
@@ -1077,6 +1186,19 @@
},
"path": "skills/in-progress/writing-fragments"
},
"writing-great-skills": {
"entry": "skills/productivity/writing-great-skills/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Reference for writing and editing skills well — the vocabulary and principles that make a skill predictable.",
"name": "writing-great-skills",
"requires": [],
"tags": []
},
"path": "skills/productivity/writing-great-skills"
},
"writing-shape": {
"entry": "skills/in-progress/writing-shape/SKILL.md",
"licenseFiles": [
@@ -1089,26 +1211,13 @@
"tags": []
},
"path": "skills/in-progress/writing-shape"
},
"zoom-out": {
"entry": "skills/engineering/zoom-out/SKILL.md",
"licenseFiles": [
"LICENSE"
],
"metadata": {
"description": "Tell the agent to zoom out and give broader context or a higher-level perspective. Use when you're unfamiliar with a section of code or need to understand how it fits into the bigger picture.",
"name": "zoom-out",
"requires": [],
"tags": []
},
"path": "skills/engineering/zoom-out"
}
},
"tools": {}
},
"narHash": "sha256:e61c575015dca998709776014f52317e29b49aca42659b635dbc69fb60a7f9e1",
"narHash": "sha256:8ee1b06b32fb908c62f89275138af4028c1a2d0827987209a0fffab89cf7595f",
"ref": null,
"rev": "e3b90b5238f38cdea5996e16861dcae28ef52eda",
"rev": "6eeb81b5fcfeeb5bd531dd47ab2f9f2bbea27461",
"root": ".",
"type": "git",
"url": "https://github.com/mattpocock/skills",
Generated
+408 -308
View File
File diff suppressed because it is too large Load Diff
+9 -17
View File
@@ -17,15 +17,18 @@
};
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.11";
nixpkgs-45570c2.url = "github:nixos/nixpkgs/45570c299dc2b63c8c574c4cd77f0b92f7e2766e";
nixpkgs-locked.url = "github:nixos/nixpkgs/2744d988fa116fc6d46cdfa3d1c936d0abd7d121";
nixpkgs-9e58ed7.url = "github:nixos/nixpkgs/9e58ed7ba759d81c98f033b7f5eba21ca68f53b0";
# nixpkgs-45570c2.url = "github:nixos/nixpkgs/45570c299dc2b63c8c574c4cd77f0b92f7e2766e";
# nixpkgs-locked.url = "github:nixos/nixpkgs/2744d988fa116fc6d46cdfa3d1c936d0abd7d121";
# nixpkgs-9e58ed7.url = "github:nixos/nixpkgs/9e58ed7ba759d81c98f033b7f5eba21ca68f53b0";
nixpkgs-master.url = "github:nixos/nixpkgs/master";
m3ta-nixpkgs.url = "git+ssh://gitea@code.m3ta.dev/m3tam3re/nixpkgs";
m3ta-nixpkgs = {
url = "git+ssh://gitea@code.m3ta.dev/m3tam3re/nixpkgs";
# url = "path:/home/m3tam3re/p/NIX/nixpkgs";
};
llm-agents.url = "github:numtide/llm-agents.nix";
#
nur = {
url = "github:nix-community/NUR";
inputs.nixpkgs.follows = "nixpkgs";
@@ -48,17 +51,7 @@
inputs.nixpkgs.follows = "nixpkgs";
};
agent-lib = {
url = "git+ssh://gitea@code.m3ta.dev/m3tam3re/agent-lib";
inputs.nixpkgs.follows = "nixpkgs";
};
hermes-agent.url = "github:NousResearch/hermes-agent/v2026.5.29.2";
rustfs = {
url = "github:rustfs/rustfs-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
hermes-agent.url = "github:NousResearch/hermes-agent/v2026.7.20";
};
outputs = {
@@ -111,7 +104,6 @@
inputs.disko.nixosModules.disko
agenix.nixosModules.default
m3ta-nixpkgs.nixosModules.default
inputs.rustfs.nixosModules.rustfs
];
};
m3-kratos = nixpkgs.lib.nixosSystem {
+5 -8
View File
@@ -34,12 +34,12 @@
#outputs.overlays.additions
#outputs.overlays.modifications
outputs.overlays.stable-packages
outputs.overlays.locked-packages
outputs.overlays.pinned-packages
# outputs.overlays.locked-packages
# outputs.overlays.pinned-packages
outputs.overlays.master-packages
inputs.m3ta-nixpkgs.overlays.default
inputs.m3ta-nixpkgs.overlays.modifications
# inputs.m3ta-nixpkgs.overlays.modifications
(outputs.lib.mkLlmAgentsOverlay system)
# You can also add overlays exported from other flakes:
# neovim-nightly-overlay.overlays.default
@@ -68,11 +68,8 @@
"m3tam3re"
]; # Set users that are allowed to use the flake command
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
# Garbage collection is handled by programs.nh.clean on each host.
# Keep nix.gc.automatic disabled to avoid dueling GC timers.
optimise.automatic = true;
registry =
(lib.mapAttrs (_: flake: {inherit flake;}))
+92 -20
View File
@@ -7,7 +7,20 @@
lib,
...
}:
with lib; {
with lib; let
lua = lib.generators.mkLuaInline;
startupCommand = command: {
_args = [
"hyprland.start"
(lua ''
function()
hl.exec_cmd(${builtins.toJSON command})
end
'')
];
};
in {
config = mkMerge [
# ── XDG / MIME defaults ──
{
@@ -41,28 +54,87 @@ with lib; {
wayland.windowManager.hyprland = {
enable = true;
settings = {
exec-once = ["tuxedo-backlight"];
on = [
(startupCommand "tuxedo-backlight")
];
monitor = [
"eDP-1,preferred,0x0,1.25"
"HDMI-A-1,1920x1080@120,2560x0,1"
{
output = "eDP-1";
mode = "preferred";
position = "0x0";
scale = 1.25;
}
{
output = "HDMI-A-1";
mode = "1920x1080@120";
position = "2560x0";
scale = 1;
}
];
workspace = [
"1, monitor:eDP-1, default:true"
"2, monitor:eDP-1"
"3, monitor:eDP-1"
"4, monitor:HDMI-A-1"
"5, monitor:HDMI-A-1,border:false,rounding:false"
"6, monitor:HDMI-A-1"
workspace_rule = [
{
workspace = "1";
monitor = "eDP-1";
default = true;
}
{
workspace = "2";
monitor = "eDP-1";
}
{
workspace = "3";
monitor = "eDP-1";
}
{
workspace = "4";
monitor = "HDMI-A-1";
}
{
workspace = "5";
monitor = "HDMI-A-1";
no_border = true;
no_rounding = true;
}
{
workspace = "6";
monitor = "HDMI-A-1";
}
];
windowrule = [
"match:class dev.zed.Zed, workspace 1"
"match:class Msty, workspace 1"
"match:class ^(com.obsproject.Studio)$, workspace 2"
"match:class ^(brave-browser)$, workspace 4, opacity 1.0"
"match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
"match:class ^steam_app_\\d+$, fullscreen on"
"match:class ^steam_app_\\d+$, workspace 5"
"match:class ^steam_app_\\d+$, idle_inhibit focus"
window_rule = [
{
match.class = "dev.zed.Zed";
workspace = "1";
}
{
match.class = "Msty";
workspace = "1";
}
{
match.class = "^(com.obsproject.Studio)$";
workspace = "2";
}
{
match.class = "^(brave-browser)$";
workspace = "4";
opacity = "1.0";
}
{
match.class = "^(vivaldi-stable)$";
workspace = "4";
opacity = "1.0";
}
{
match.class = "^steam_app_\\d+$";
fullscreen = true;
}
{
match.class = "^steam_app_\\d+$";
workspace = "5";
}
{
match.class = "^steam_app_\\d+$";
idle_inhibit = "focus";
}
];
};
};
+1 -2
View File
@@ -2,7 +2,6 @@
imports = [
./containers
./greetd.nix
./hermes-agent.nix
./netbird.nix
#./n8n.nix
./mem0.nix
@@ -30,7 +29,7 @@
gvfs.enable = true;
trezord.enable = true;
gnome.gnome-keyring.enable = true;
qdrant.enable = true;
# qdrant.enable = true;
# qdrant = {
# enable = true;
# settings = {
-195
View File
@@ -1,195 +0,0 @@
{config, ...}: let
# Default ElevenLabs voice: Bella (German-capable female)
elevenlabsVoiceId = "hpp4J3VqNfWAUOO0d1Us";
in {
services.hermes-agent = {
enable = true;
addToSystemPackages = true;
# Secrets via agenix
environmentFiles = [config.age.secrets."hermes-env".path];
# Non-secret environment variables
environment = {
GLM_BASE_URL = "https://api.z.ai/api/coding/paas/v4/";
};
settings = {
# ── Model ──────────────────────────────────────────────────────────
model = {
default = "gpt-5.5";
provider = "openai-codex";
};
fallback_providers = [
{
provider = "zai";
model = "glm-5.1";
}
{
provider = "minimax";
model = "MiniMax-M2.7";
}
];
credential_pool_strategies = {
zai = "fill_first";
};
toolsets = ["all"];
# ── Agent ──────────────────────────────────────────────────────────
agent = {
max_turns = 90;
gateway_timeout = 1800;
tool_use_enforcement = "auto";
};
# ── Terminal ───────────────────────────────────────────────────────
terminal = {
backend = "ssh";
modal_mode = "auto";
cwd = ".";
timeout = 180;
persistent_shell = true;
};
# ── Browser ────────────────────────────────────────────────────────
browser = {
inactivity_timeout = 120;
command_timeout = 30;
cloud_provider = "local";
};
# ── Checkpoints / Compression ──────────────────────────────────────
checkpoints = {
enabled = true;
max_snapshots = 50;
};
file_read_max_chars = 100000;
compression = {
enabled = true;
threshold = 0.5;
target_ratio = 0.2;
protect_last_n = 20;
};
# ── Display ────────────────────────────────────────────────────────
display = {
compact = false;
personality = "kawaii";
resume_display = "full";
busy_input_mode = "interrupt";
inline_diffs = true;
skin = "default";
tool_progress = "all";
};
# ── TTS / STT / Voice ──────────────────────────────────────────────
tts = {
provider = "elevenlabs";
elevenlabs = {
voice_id = elevenlabsVoiceId;
model_id = "eleven_multilingual_v2";
};
};
stt = {
enabled = true;
provider = "local";
local = {model = "base";};
};
voice = {
record_key = "ctrl+b";
max_recording_seconds = 120;
silence_threshold = 200;
silence_duration = 3.0;
};
# ── Memory ─────────────────────────────────────────────────────────
memory = {
memory_enabled = true;
user_profile_enabled = true;
memory_char_limit = 2200;
user_char_limit = 1375;
};
# ── Delegation ─────────────────────────────────────────────────────
delegation = {
max_iterations = 50;
};
# ── Discord ────────────────────────────────────────────────────────
discord = {
require_mention = true;
auto_thread = true;
reactions = true;
};
# ── Approvals / Security ───────────────────────────────────────────
approvals = {
mode = "manual";
timeout = 60;
};
security = {
redact_secrets = true;
tirith_enabled = true;
tirith_fail_open = true;
};
# ── Cron / Session ─────────────────────────────────────────────────
cron = {wrap_response = true;};
session_reset = {
mode = "both";
idle_minutes = 1440;
at_hour = 4;
};
# ── Web ────────────────────────────────────────────────────────────
web = {backend = "exa";};
# ── Platform Toolsets ──────────────────────────────────────────────
platform_toolsets = {
cli = [
"browser"
"clarify"
"code_execution"
"cronjob"
"delegation"
"file"
"image_gen"
"memory"
"session_search"
"skills"
"terminal"
"todo"
"tts"
"vision"
"web"
];
telegram = [
"browser"
"clarify"
"code_execution"
"cronjob"
"delegation"
"file"
"image_gen"
"memory"
"session_search"
"skills"
"terminal"
"todo"
"tts"
"vision"
"web"
];
};
};
};
}
+1 -2
View File
@@ -18,8 +18,7 @@
kestra-env = {file = ../../secrets/kestra-env.age;};
littlelink-m3tam3re = {file = ../../secrets/littlelink-m3tam3re.age;};
minio-root-cred = {file = ../../secrets/minio-root-cred.age;};
rustfs-access-key = {file = ../../secrets/rustfs-access-key.age;};
rustfs-secret-key = {file = ../../secrets/rustfs-secret-key.age;};
rustfs-env = {file = ../../secrets/rustfs-env.age;};
n8n-env = {file = ../../secrets/n8n-env.age;};
netbird-auth-secret = {
file = ../../secrets/netbird-auth-secret.age;
+1 -1
View File
@@ -1,6 +1,6 @@
{config, ...}: {
virtualisation.oci-containers.containers."ghost" = {
image = "docker.io/ghost:latest";
image = "docker.io/ghost:6-alpine";
environmentFiles = [config.age.secrets.ghost-env.path];
ports = ["127.0.0.1:3002:2368"];
volumes = ["ghost_data:/var/lib/ghost/content"];
+10 -13
View File
@@ -6,21 +6,18 @@
}: {
services.rustfs = {
enable = true;
package = inputs.rustfs.packages.${pkgs.stdenv.hostPlatform.system}.default;
environmentFile = config.age.secrets.rustfs-env.path;
settings = {
# Reuse existing MinIO data directory
RUSTFS_VOLUMES = "/var/storage/s3";
# Reuse existing MinIO data directory
volumes = "/var/storage/s3";
# Keep same ports as MinIO to avoid changing Traefik and client configs
RUSTFS_ADDRESS = ":3008";
RUSTFS_CONSOLE_ENABLE = "true";
RUSTFS_CONSOLE_ADDRESS = ":3007";
# Keep same ports as MinIO to avoid changing Traefik and client configs
address = ":3008";
consoleEnable = true;
consoleAddress = ":3007";
# Credentials via agenix
accessKeyFile = config.age.secrets.rustfs-access-key.path;
secretKeyFile = config.age.secrets.rustfs-secret-key.path;
logLevel = "info";
RUST_LOG = "info";
};
};
# Traefik configuration — same routes as before
+34 -53
View File
@@ -8,44 +8,34 @@
# Edge TTS: Seraphina — friendly, multilingual German female voice (free, no API key)
edgeVoice = "de-DE-SeraphinaMultilingualNeural";
agentLock = builtins.fromJSON (builtins.readFile ../../../agent-sources.lock.json);
agentSkillSelections = {
m3ta-agents.exclude = [];
anthropic.exclude = ["pdf" "skill-creator" "xlsx"];
basecamp.exclude = [];
kestra.exclude = [];
mattpocock.exclude = ["grill-me" "caveman"];
superpowers.exclude = ["brainstorming" "systematic-debugging"];
vercel.exclude = [];
agentSkillExclusions = {
m3ta-agents = [];
anthropic = ["pdf" "skill-creator" "xlsx"];
basecamp = [];
kestra = [];
mattpocock = ["grill-me" "caveman"];
superpowers = ["brainstorming" "systematic-debugging"];
vercel = [];
};
sourceRoot = source:
builtins.fetchGit {
inherit (source) url rev;
};
agentLibSourceSelections =
lib.mapAttrs (_sourceName: exclude: {
skills = {
all = true;
inherit exclude;
};
})
agentSkillExclusions;
selectedSkillNames = sourceName: let
source = agentLock.sources.${sourceName};
excluded = agentSkillSelections.${sourceName}.exclude;
in
lib.subtractLists excluded (builtins.attrNames source.items.skills);
copySkill = sourceName: skillName: let
source = agentLock.sources.${sourceName};
item = source.items.skills.${skillName};
in ''
cp -R ${sourceRoot source}/${source.root}/${item.path} $out/${skillName}
'';
copySourceSkills = sourceName:
lib.concatMapStringsSep "\n" (copySkill sourceName) (selectedSkillNames sourceName);
# Build skills from the agent-lib lockfile instead of the legacy AGENTS flake.
hermesSkills = pkgs.runCommand "hermes-agent-lib-skills" {} ''
mkdir -p $out
${lib.concatMapStringsSep "\n" copySourceSkills (builtins.attrNames agentSkillSelections)}
'';
# Deterministic store renderer consumed directly by Hermes. m3ta-home
# re-exports the focused helper so nixos-config does not need a direct
# agent-lib flake input.
hermesSkills = inputs.m3ta-home.lib.mkHermesSkillsDir {
system = pkgs.stdenv.hostPlatform.system;
name = "hermes-agent-lib-skills";
lockFile = ../../../agent-sources.lock.json;
sources = agentLibSourceSelections;
};
in {
virtualisation.docker.enable = true;
@@ -63,18 +53,7 @@ in {
''}"
];
systemd.services.copy-hermes-skills = {
description = "Copy agent skills to hermes home directory";
wantedBy = ["hermes-agent.service"];
before = ["hermes-agent.service"];
serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true;
script = ''
mkdir -p /var/lib/hermes/.agents
cp -rT ${hermesSkills} /var/lib/hermes/.agents/skills
chown -R hermes:hermes /var/lib/hermes/.agents
'';
};
systemd.services.hermes-agent.restartTriggers = [hermesSkills];
services.hermes-agent = {
enable = true;
@@ -92,6 +71,7 @@ in {
];
extraPackages = with pkgs; [
basecamp
docker
git
curl
@@ -99,6 +79,7 @@ in {
tea
nix
python3Minimal
qmd
uv
zellij
];
@@ -142,18 +123,18 @@ in {
settings = {
# ── Model ──────────────────────────────────────────────────────────
model = {
default = "gpt-5.5";
provider = "openai-codex";
default = "glm-5.2";
provider = "zai";
};
fallback_providers = [
{
provider = "zai";
model = "glm-5.1";
provider = "openai-codex";
model = "gpt-5.5";
}
{
provider = "minimax";
model = "MiniMax-M2.7";
model = "MiniMax-M3";
}
];
@@ -175,7 +156,7 @@ in {
skills = {
external_dirs = [
"/var/lib/hermes/.agents/skills"
hermesSkills
];
};
+5 -2
View File
@@ -1,7 +1,11 @@
# Edit this configuration file to define what should be installed on
# your system. Help is available in the configuration.nix(5) man page, on
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
{pkgs, ...}: {
{
config,
pkgs,
...
}: {
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
@@ -15,7 +19,6 @@
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.initrd.kernelModules = ["amdgpu"];
boot.kernelPackages = pkgs.linuxPackages_7_0;
services.xserver.videoDrivers = ["amdgpu"];
security.polkit.enable = true;
security.pam.services.gdm.enableGnomeKeyring = true;
+91 -18
View File
@@ -4,17 +4,25 @@
# m3ta-home via the profile mapping in hosts/common/users/m3tam3re.nix.
{
config,
inputs,
lib,
...
}:
with lib; {
with lib; let
mkEnvVar = name: value: {
_args = [
name
value
];
};
in {
imports = [
];
config = mkMerge [
# ── XDG / MIME defaults ──
{
qt.platformTheme.name = mkForce "qtct";
xdg = {
enable = true;
configFile."mimeapps.list".force = true;
@@ -46,24 +54,89 @@ with lib; {
enable = true;
settings = {
monitor = [
"DP-1,2560x1440@144,0x0,1"
"DP-2,2560x1440@144,2560x0,1"
{
output = "DP-1";
mode = "2560x1440@144";
position = "0x0";
scale = 1;
}
{
output = "DP-2";
mode = "2560x1440@144";
position = "2560x0";
scale = 1;
}
];
workspace = [
"1, monitor:DP-1, default:true"
"2, monitor:DP-1"
"3, monitor:DP-1"
"4, monitor:DP-2"
"5, monitor:DP-2"
"6, monitor:DP-2"
"7, monitor:DP-2"
workspace_rule = [
{
workspace = "1";
monitor = "DP-1";
default = true;
}
{
workspace = "2";
monitor = "DP-1";
}
{
workspace = "3";
monitor = "DP-1";
}
{
workspace = "4";
monitor = "DP-2";
}
{
workspace = "5";
monitor = "DP-2";
}
{
workspace = "6";
monitor = "DP-2";
}
{
workspace = "7";
monitor = "DP-2";
}
];
windowrule = [
"match:class dev.zed.Zed, workspace 1"
"match:class ^(com.obsproject.Studio)$, workspace 2"
"match:class ^(brave-browser)$, workspace 4, opacity 1.0"
"match:class ^(vivaldi-stable)$, workspace 4, opacity 1.0"
"match:class ^steam_app_\\d+$, idle_inhibit focus"
# m3ta-home sets QT_QPA_PLATFORMTHEME to gtk3 globally for Hyprland.
# ksnip crashes with duplicate GDK type registration under that Qt GTK
# platform theme, so use qtct for Qt apps on this host instead.
"env" = mkForce [
(mkEnvVar "XCURSOR_SIZE" "32")
(mkEnvVar "HYPRCURSOR_THEME" "Bibata-Modern-Ice")
(mkEnvVar "WLR_NO_HARDWARE_CURSORS" "1")
(mkEnvVar "XDG_CURRENT_DESKTOP" "Hyprland")
(mkEnvVar "XDG_SESSION_TYPE" "wayland")
(mkEnvVar "XDG_SESSION_DESKTOP" "Hyprland")
(mkEnvVar "XKB_DEFAULT_LAYOUT" "de")
(mkEnvVar "NIXOS_OZONE_WL" "1")
(mkEnvVar "QT_QPA_PLATFORM" "wayland;xcb")
(mkEnvVar "QT_QPA_PLATFORMTHEME" "qt5ct")
(mkEnvVar "QT_QPA_PLATFORMTHEME_QT6" "qt6ct")
];
window_rule = [
{
match.class = "dev.zed.Zed";
workspace = "1";
}
{
match.class = "^(com.obsproject.Studio)$";
workspace = "2";
}
{
match.class = "^(brave-browser)$";
workspace = "4";
opacity = "1.0";
}
{
match.class = "^(vivaldi-stable)$";
workspace = "4";
opacity = "1.0";
}
{
match.class = "^steam_app_\\d+$";
idle_inhibit = "focus";
}
];
};
};
+1
View File
@@ -19,6 +19,7 @@
dedicatedServer.openFirewall = true;
gamescopeSession.enable = true;
};
programs.localsend.enable = true;
programs.obs-studio = {
enable = true;
enableVirtualCamera = true;
+4 -4
View File
@@ -1,9 +1,9 @@
{pkgs, ...}: {
imports = [
./containers
./greetd.nix
# ./greetd.nix
./mem0.nix
# ./n8n.nix
./n8n.nix
./netbird.nix
./postgres.nix
./sound.nix
@@ -20,7 +20,7 @@
gvfs.enable = true;
trezord.enable = true;
gnome.gnome-keyring.enable = true;
qdrant.enable = true;
# qdrant.enable = true;
avahi = {
enable = true;
nssmdns4 = true;
@@ -30,6 +30,6 @@
userServices = true;
};
};
# displayManager.gdm.enable = true;
displayManager.gdm.enable = true;
};
}
+1 -1
View File
@@ -1,6 +1,6 @@
{lib, ...}: {
services.n8n = {
enable = false;
enable = true;
openFirewall = true;
environment = {
N8N_SECURE_COOKIE = "false";
+45 -19
View File
@@ -25,12 +25,12 @@
# });
};
temp-packages = final: _prev: {
temp = import inputs.nixpkgs-9e9486b {
system = final.stdenv.hostPlatform.system;
config.allowUnfree = true;
};
};
# temp-packages = final: _prev: {
# temp = import inputs.nixpkgs-9e9486b {
# system = final.stdenv.hostPlatform.system;
# config.allowUnfree = true;
# };
# };
stable-packages = final: _prev: {
stable = import inputs.nixpkgs-stable {
@@ -39,19 +39,19 @@
};
};
pinned-packages = final: _prev: {
pinned = import inputs.nixpkgs-9472de4 {
system = final.stdenv.hostPlatform.system;
config.allowUnfree = true;
};
};
# pinned-packages = final: _prev: {
# pinned = import inputs.nixpkgs-9472de4 {
# system = final.stdenv.hostPlatform.system;
# config.allowUnfree = true;
# };
# };
locked-packages = final: _prev: {
locked = import inputs.nixpkgs-locked {
system = final.stdenv.hostPlatform.system;
config.allowUnfree = true;
};
};
# locked-packages = final: _prev: {
# locked = import inputs.nixpkgs-locked {
# system = final.stdenv.hostPlatform.system;
# config.allowUnfree = true;
# };
# };
master-packages = final: _prev: {
master = import inputs.nixpkgs-master {
@@ -63,6 +63,32 @@
# Factory: not a proper overlay itself — takes system to avoid the infinite
# recursion that occurs when accessing final/prev.system while the fixed-point
# is still being computed. Exposed via outputs.lib, not outputs.overlays.
#
# Filters out the 16 internal helpers (marked `passthru.hideFromDocs = true`
# upstream) that would otherwise clobber nixpkgs attributes. Most critically
# this excludes `buildNpmPackage` — llm-agents' buildNpmPackage is a guarded
# re-export whose `__functor`/`override` interaction with makeOverridable
# breaks any package (e.g. nixpkgs' webcord) that calls
# `buildNpmPackage.override { nodejs = ...; }`. See numtide/llm-agents.nix
# commit 40490259 and the wrapper at packages/buildNpmPackage/package.nix.
mkLlmAgentsOverlay = system: _final: _prev:
inputs.llm-agents.packages.${system} or {};
builtins.removeAttrs (inputs.llm-agents.packages.${system} or {}) [
# Internal helpers from packages/* marked hideFromDocs upstream:
"antigravity"
"auto-claude"
"buildNpmPackage" # ← the culprit; breaks webcord's `buildNpmPackage.override { nodejs = ...; }`
"bun2nix"
"darwinOpenptyHook"
"default" # fzf launcher; collides with nothing in nixpkgs but kept out for hygiene
"dolt" # collides with nixpkgs.dolt (Dolt database); not used in this config
"flake-inputs"
"forge"
"formatelf"
"formatter" # collides conceptually with pkgs.formatter; not used here
"go-bin"
"unpinCargoMsrvHook"
"unpinGoModVersionHook"
"versionCheckHomeHook"
"wrapBuddy"
];
}
+1 -2
View File
@@ -23,8 +23,7 @@ in {
"secrets/kestra-config.age".publicKeys = systems ++ users;
"secrets/kestra-env.age".publicKeys = systems ++ users;
"secrets/minio-root-cred.age".publicKeys = systems ++ users;
"secrets/rustfs-access-key.age".publicKeys = systems ++ users;
"secrets/rustfs-secret-key.age".publicKeys = systems ++ users;
"secrets/rustfs-env.age".publicKeys = systems ++ users;
"secrets/n8n-env.age".publicKeys = systems ++ users;
"secrets/netbird-auth-secret.age".publicKeys = systems ++ users;
"secrets/netbird-db-password.age".publicKeys = systems ++ users;
+22 -23
View File
@@ -1,26 +1,25 @@
age-encryption.org/v1
-> ssh-ed25519 4NLKrw 2TwbZwX9SwWg4SVC0A2ICmyRjSfO+xtfBcBOK1lh3T4
DSf4DrOAvW7L49lh6cq5IqrMM7gqXv2+67rR3ttn+CE
-> ssh-ed25519 5kwcsA K1hqFOAxq2T+oLp3bQjLYpXtlQVkA7RHCM/8ETMGbwU
xIE4xz50LB5vbDTTLKVcx9vC2iXIsRLThHYYxGjcJyY
-> ssh-ed25519 9d4YIQ bXYb62OM/N+EXpMOZZ6zEbpfaH10Vz62PuUdGODXolw
j64kKzOn8CmSnykEuWnXHZ0nfqwOfOxX4FPR4GSouR0
-> ssh-ed25519 3Bcr1w C4alN6ud7q0K4I7NHuBgC77D6zeTfZVGjNS3EKpvL00
NpjOsg3eJ5LvX0lV7NYuVHLeqeYylHdmw60H+KeG1GY
-> ssh-ed25519 c4NQlA In5wsg4+LTIEbP75B83GMXPCItSPGwKWUW8QO+QjXyY
oK1kikhr4RMq6QMv9kjNjiKrf5srlGh7hGbU2qns2rM
-> ssh-ed25519 4NLKrw 42tBp6EbDJpC7EBt0++QxmF3N9rQJ/AP+7A/S174rCs
bRzpQku0GLEBvANvCdeH3L4Kf06k6w2C4FfZCOp2QWI
-> ssh-ed25519 5kwcsA YAYkQzsxfbHwrCPMW2eqLS9mRuuxr+EjHKl7MV3DDEo
dN3TitETbdPbXzBtIDBglienhY4oDsFGgfe0VYdsP1o
-> ssh-ed25519 9d4YIQ 2vTWMSuLrgpgaTWeu0ARoUOukLBKupCfMdqJhLvTqwA
Lzk2Uo2U3tUJiq29on/a5zYfuUjgOZvCHhZYuFGSDG4
-> ssh-ed25519 3Bcr1w x689Z0/TsOLLk1JNPXg2jj6y5ucaH37zRt46d/Z1l2w
Bkzg3umkDYFBemmgev/M5LUFuobFugXe0u85mLmsDSo
-> ssh-ed25519 c4NQlA 5Dn6e8bILaYl9FVt+ZwuZ6rOC0k0Kg1+KOSP4JakyWI
AT6LeCo+P7RjgNhRex04kJ/7NHD2DAWRqs33uOJ7e5E
-> ssh-rsa DQlE7w
tcP4yPgGWqHYeE1gw/KD6cswik+9WU2s2f7hg5mK78085sQ7npXRsBVAz2OCRn07
foeAAmnY4YmKriBh421JOVNBDOXHR5dfaIKY9b663L+rYj99ic0rfW26C+dqKitF
SnvveL3Zf16nqg6duSVA7LIcIFgkIlA+RXnHPVho+P4GwEH7W8nCf/4kUquuhB7B
F4Hx1qOknmGyNBJBFi27D04ZDDk/ZVxioYsO6P6TUu7MuaGmQCoVKREDl5RRh4zO
XD8/TFDRsJLqqcbCKIlU+6CN1+L0r4FN4K0UaTjwPNzGvn5EEjBKw9RpOhdvI28I
WlAQ+w6gdQiz9Ju4e5p7Doz2MbNb6894DimawHjzl968Xy5ifX2XA+FBdcW5hU9A
u+7VXKZmbfMyvRA7lmKRoi4SurJAyQd6iXBrVKfTwFc53V/tJi48bsKcE3yXxHH+
lKGuZFNGDDkqCruycjvz94WaIHy3fv5hhmBdgwoCZK1VGSLAnwdm1rG4B9m3t/K8
M9pUnzZDa1v6X5UbQOE6HILaGU36VkQtnfXaJJdxJSRQ/sE9R3ZQoLjRZAw+UhUf
09JwLkS55477xaar3bpvvOxeP4MrtTHLJ7593eEkFT3i45FfVmxutq6EYckZrCJB
WjrCG7Cbvc20o6s54PYiF4Xk8AuPxt+SElRxBtcOK+SPba84f+WWHqrBA1YRzTDK
fsM15eKWsJgzaz5y36grv4xSj4KbWMFtmEt5V5BEW32+zXBU5CPhonO59TxEQgh4
hI2+gNmAzKQja7xbuxCyr3jcXWJz7IuXcrklr+2ZjF1wx3BDll1z+vxSX0C88MCc
OLKDfnUiDa6BlgUfLK90dLIia8v0oIPXs4OWRfYs7SC/Z3QOPpSO62Ky9dKYRrod
PHvCgxX28QvROE4TekL9PV81AfAbMVJrnkRiybg6id8CscldtDmgaKqoaIoJlAuF
g5/LGd+FPfmlv2iNfGUn2Glhui8SkrBK1MzGJpeQw+l4CXLH33yQzHX0m6TdQBzr
-> ssh-ed25519 CSMyhg FNYYdEIJYcxkjMuM5lnIs9gIilvgD44uazZE8CjNeho
QHeghlsOOlYNMwhMHT4o7DeuyxGP/3wyqm94HUHjn44
--- zRG6aCTS+X18VpeN+tz38kaUoilk1kN5KrWTWYZ6pV4
ræX _qÔÁ’Ð껿H#p¯f™”}(žA(ã|»?ë0ªyJk¥SD‡\Jm&uõà &Ô9€ýÄ5Ù+çÊ…!v%Y˜ù~ãÁ$û“šZÇÓ° j„z–Â\ßá1,Vf˜
£’æ1zª»#Ó
-> ssh-ed25519 CSMyhg 5YHqBNbkkUFVhDEfOM4P2tAxT2t1rDn5KItUcjUs4DY
oWEKUGiIVkRQvEkY33PpOUcoqsmacgHAaX58H6sRpP4
--- KH+IYh4+bS3JMeEmFYakwIceMxOrlEZj0Fqt3VMgFRk
96¨ºà·ènÅϬuk!ß±1ÝNItŽNŸ8EçwĹ]3µ”S*¡õ«0>!ý9zc‡(”2OI.^jC”&$ºÚ\ÛËWtÇÃNÿ#Õ€Å3¾ÜøÞÌÏcMuÈAߢ•<¾)¬´¼a¥rdí'pÄggPä5’ÆõOQòNfà”×1AZ|1v\š4F›‡Ò 6;„T<l£
Binary file not shown.
-31
View File
@@ -1,31 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDROTEtydyBnRjhF
SHhTS2YrOHF1OWM1Zm04elkzVWpST0hhN0RhOWZBZGpBYmNTVnk4Cm9SMm5NcWdV
Rnh0TVpqTlFSaGtaMnBrSGorUEhDd1RibWs1VUt5RGtqaVEKLT4gc3NoLWVkMjU1
MTkgNWt3Y3NBIFV5OWhMU204L25nR3ZLOWl1a1ppZkUvcTNJTDhlNmE3eXpJMjRL
NWdsWDQKNGhVYUhwRWRndjFYVEVIT3N2WE1WVncyV1Q1Q1BoNkhraVU5Q2s4UmtB
OAotPiBzc2gtZWQyNTUxOSA5ZDRZSVEgVkRwdGtHVTlTMUVMOFZrdUNHZHc5UWo3
WWtRaXJPY0p2QWZOUEtjWDVCYwpYQmh3ejdLOWdmM3dZbWJuRU1EYlRYZ2tJL3VY
OURUKzhRY2dtcVRQZnBnCi0+IHNzaC1lZDI1NTE5IDNCY3IxdyAyOFI4YllyWlox
V09BbERmRm4yd1Y5dlh0UGphK05DMGpsWXJQTmwrVlRVCjdqNE4yVHFKWFV3NXlr
bm40M1BpNGNNNDdJOXMyak5EUWdMa0hrb3lJY3cKLT4gc3NoLWVkMjU1MTkgYzRO
UWxBICsxb3poQit6VGRtWmZXUWUxMmRGWUN6RGVOeUxEZjdvZldTTE5XSFpDRVkK
bFNWLzFpazJLM0Q2R0NKU2FaS25ldEQ1RUZQM2RpektaT1NhRnJtS0JFcwotPiBz
c2gtcnNhIERRbEU3dwpFMVdKYnhiTWF4MCtJMFNHVGtOZGNBdlVDYWRRR252dVd6
NW1vNFRtbENLbHB2cHo1aE43M3RiZGh1QkVQVzBECjlvRnhYbjlpWWFFTEFFc1cw
NjFVSENsVWJHdWdGV3ZEY2tOcXkvUm9SSFE4VWw5eHVUSnV6SmxCRU9TNUdpRjMK
aGNhdHcvay85N0ZQNksydEhkcXNkc0h6dkRMRXlzUCtNNGM1V2tXb28wQ05valBH
TUdJa3V1bEdYRUZveFNwbwpIbWRnZmtQMDREd08rRkx3OERwRVZZNVlnSXlNNlFH
SkFoQWVEN1NzL0lqeVkvZllPdUkvbWZkU2NxNjQyYTIvCnJ4QmZ1SlpGNkp3UXFD
SUdFMFY5RWVadTd5QmM1U2tIZ3dLQ2ZZKzF0WTE3K09aN3FYWUVBYkErVlNpblNU
QzgKNENEZStFeitaYmE5Q1MyQ0lWSFlZb2hJdlBVNkhUUjBFWkxsWmZqdHNYb3Fk
VVJMMzg2V2xWdnNCNndGSWdpbAoyUHZ1WXR5UG04ZmZOdVluU2J6VUhKZ0xMZ0lS
R3YrY3RIRHJCby8yVWxIMWpGNWlJK1h4eXdRUXExT3pleWc3CnRmQVl1Yk1IUUFJ
blNoUGxVUUlVOG9FSE5CMDVidmZhSWJmWTFsY0lFcWpZU213cmcxNzFvb29XaklC
MnhpSkwKCi0+IHNzaC1lZDI1NTE5IENTTXloZyBOMDNYdGlvL3Y5QUp2YlNlUDZu
RXFyTkFWbFFsN1oweEErSS9Ccmh0WmwwClpzTWw1aXNqVXdaTVFrTTJ6Y0FWbVpR
TXk4cTNUUElkeGF1VUZ0U3RWcEEKLT4gTyUkcSZASGstZ3JlYXNlCnYwSGdsbE5h
d2JLOAotLS0gcjB3WU1rNDhBY1VxalpBNVJRSTJFZ0NhWEZlSW15UHphMnRHTjBj
aGptRQpiZ/2f41GnSHdg+EXeRwxHOHc/RNfEwlKhEB/Weq8tQ2Xf/jJ21WiWsTIm
g7Sq9EO6JyYMTJ/qlccpytfkU/qkouyR+z3prQcP7NWTcg==
-----END AGE ENCRYPTED FILE-----
+26
View File
@@ -0,0 +1,26 @@
age-encryption.org/v1
-> ssh-ed25519 4NLKrw 4yocYUNwOH2fkSzRbkhJ1DN58fiFHKGQlQY8ljkgykM
68DuFPNFjyD2+avOMlOlRQm3bs43Bk84MIXygS35MtE
-> ssh-ed25519 5kwcsA cC38K7vS4JlkGtSEPn7D6x2m9H08XK4vuhWysJcFNG0
kKbUBKEfUUkhmnr3g5/Bz8chDouySQf3Mk/+LyNNQls
-> ssh-ed25519 9d4YIQ w3u2BX/R0lVgy35DoFtxUM6f/nYkcNVeAoPDNDSX5yU
XOo2/yrO2r2mn2FTcR+dviKVClU94Pi8Wri17emUsoI
-> ssh-ed25519 3Bcr1w 8ncD6gl8tHVOYO83VW4dXI3XVUNXdfbFoZutCGGykxw
r7k0ltk9XK5q9+gyLwqzaajYbTRgsj3rALJTCnQ0Lyg
-> ssh-ed25519 c4NQlA A8WnqWlC8ljCaQVMa6wJIfe4uA3OQ/q9vJRAF56ovVE
xwh0RE9S+z5Rf+PCW0L/flKy506HRel0dVJJVzyO1M8
-> ssh-rsa DQlE7w
f5iiDuIUPzKToC7cCUtQUQzkxKPkYsDuHHM+9BHsQmwSOT91Z0J1F4udOlEqUcuE
kUMCbHvhFEQnzfKruEH3+tRnW1YWtqTzhgvW1MvY/gv8PihekM+TSjB/mxwYSC88
yp3NhNxxonBdIjTUcgYBGijWQjPVCuggZcseqyy+h37rQCUNG6whacU7Q+ELbtTW
ssfofJrKU7l8uBpNuM3ULMK4ZzM9IurZQyqt43n++y21G1hCKVkf7g6q0IQ94SL1
y6yGyx2JGNnFO8e57vggmAtyFMMv+660plF0bg1pyQfFdmKHrPXmVHFURdQixhrg
dZhcOq1WZIjNE/SALmZj8NkNxCIjne0oIE94RNq1lj7sRFolbyaYTjfa3lnmsjsl
0s7y3QR1igJozNc0InR6koal1/WzykfXDqNwxFNyknfaGT75ZtsXJ8PC2mLbqxvC
YKYHOBledBfLASMFHeJjXx1b+X1X1DzllY51Z2p1c4BeWxuheNCd2zPiCLfzPk0w
-> ssh-ed25519 CSMyhg /KgSvWyP3WRBq8uKV8VacXZEeGna+HmH3f+4lrJKnBc
PlGjwoekR9PhGTxvxbl81BKkVl4z2JqCH+L68qfoyow
--- CeX80TFkreEFbDMeAGswnT0Y+CVfI9kTdosSCj49Hlk
T½"±–q<E/gíÑ|`.#®8Z2F­ÇD1îËÀ•õ¢+:~Úæ
Í)ü.;/TwzƒHtË ¥agX0ˆß;½ÖOiè)sÑ઒‹„FéõU>aÍê„™çú=ëäG–-séÌA¢“
-32
View File
@@ -1,32 +0,0 @@
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHNzaC1lZDI1NTE5IDROTEtydyBQd3FZ
dUFYOFhoUGdBejZKYjRnVmNvYU85LzdJS1lVZFNRS3pTeS9hT0c4Cndwc3pHdStQ
N1QvU0NSbGJhNEJCOE83eThhSFBrbDJPU0tDbmhIM3lwcjQKLT4gc3NoLWVkMjU1
MTkgNWt3Y3NBIHdaS3UvRUdFb3pITmZGdTNEaUtXdnlUMWFuNk5ZcFV0VVIwNllN
S2c5Rm8KV0x3Z2NjcUdLWmFEUExDT2EwbjFhQ2Y2TXNoaUc1d052RnJmM3VOSDVr
VQotPiBzc2gtZWQyNTUxOSA5ZDRZSVEgOG1URGlNekltV0YyQ2Y2NFdPL2tSWDlG
UnNLc2wrSllNWFd6aU9LWGN3YwpXUEthT3NNVHZJMUJndiswUVNFNWZjZnBDS3ZH
dXBJV1FSNEpPRGxQd0JrCi0+IHNzaC1lZDI1NTE5IDNCY3IxdyAvSTlFMitYZFVQ
ZER6ZDI5OEorTE5TRTdlcllPSmpkUjU5SkV2N0xQY1JBCmJPNFN5NEovdHBVVDRl
T0czS0g2dEgyTXhIMmtJVFRONDQ3enpLbFhJT3MKLT4gc3NoLWVkMjU1MTkgYzRO
UWxBIDBUV2RYajBTMkZ4WnV4ZUVCeHFZay9vRGR2dkcxaXBPOWxsZ05IZm1KVDAK
am56blp1ajlzc0NSYjY5NFdGNlNzQ0NNQzZPeVRtWTc1Z0lEYzc2TGNFMAotPiBz
c2gtcnNhIERRbEU3dwpOMGowMWFoRzhsTGp0U0RqeHUyckZvQU9EVkQxUXE1b0U0
N2hPU2NZY2huNm5kREg5SExCZGYzaTUwdWs4MjlsCjhONjVOWnZDZjFRU2k2K2Uz
dnVmWVd5MCt6bFk4UVU3UEdsWXZMOHlZMktzWWR4SFJ6Vzh4dDFpYWNYRVQ2UmsK
aW5iODV0WDYyQWN4K1ROZUVjdE40MGlxZDlXdnZVRVZBc04zdVRaOE9RTUJPUWxa
YnJjZEg3OGcxNHVEVkR0MgpGUWh6NHV4WTcxUEZwUU52QkdsOE5hZy9XWFpjQUFP
bDZzUjd3ZXFTTmpDN3ViZ0dpL3BOTFpBL3k2aUs3Qm9HCkVDeXZ2M0dQcWJwaXdm
N2E1R2pjcWY2V1dYaEFNMVc3MG9ndDRLd0tVdkxHSUxwL2REazE2Unc1Z3JjUHJh
NDgKamVqZjdkU0hCTVhqcjRsL1NtYkxxd3BId0lsRTRRUTNrZ05mcE1ZRkFSUlBW
VVdkd2VSNzJMQVJEM2QyVkMzSQoxRGVOOUtzdGVOMTBLVk8zN2xjT3lvYm0vSXpQ
VElTaS84SUxIekVybGYxV0ttZldVWHhyVVEvdzRFK3RibVFGCjV3bzltRjFTb0pu
bGJQaTJ1Mlgxd0hNN2VvS0p3eDd4WHNkaTkwV3MwWTdLWUxnNzJjLzBBZzZsck5h
Zk1UUDcKCi0+IHNzaC1lZDI1NTE5IENTTXloZyByQ1cwWm50UTY1bkp2NWZFeFVU
T0htZDFWUUFsdlBSOVVNY3RTZnNwdjE0CjBySlExb1dnTGJKZy9MT25Oa2hZdDJZ
Um9PZWlpOVA5bTBRM2wvVHJJaG8KLT4gWS1ncmVhc2UgWydtCnF4dzJjR2luMHBS
S2p3bUE2bVl2R2FaQ2hRK3greGMKLS0tIDhSdFFGaGlGRVV2VFZKcTNWYnNtbUQr
blprSjUyMjJwQkhBbVBCTmVhQ0kKUITtRYOYPDGGQlKrEp/JVUP8jTcptZxVaVcd
AmxviaG76EuXQeK/VgrGKoi+bZwHbpCbXBT2H8DBuSPgXdG3aQDQn2QgZylMnhmM
wzU=
-----END AGE ENCRYPTED FILE-----