feat(#2170): split docs/ into its own meta-flake input
This commit is contained in:
parent
9b607e2857
commit
b5acd60cf5
5 changed files with 148 additions and 18 deletions
35
flake.nix
35
flake.nix
|
|
@ -37,15 +37,17 @@
|
||||||
# each real source is a named, explicitly-filtered derivation used
|
# each real source is a named, explicitly-filtered derivation used
|
||||||
# as `src`, rather than an inline filter at the use site.
|
# as `src`, rather than an inline filter at the use site.
|
||||||
#
|
#
|
||||||
# Dropped: scripts/, root-level *.md (README/CLAUDE/TODO/…).
|
# Dropped: scripts/, docs/, root-level *.md (README/CLAUDE/TODO/…).
|
||||||
# Kept (build needs them): .nix, .rs, Cargo.*, branding/, docs/,
|
# Kept (build needs them): .nix, .rs, Cargo.*, branding/,
|
||||||
# frontend/, prompts/, flake.lock. docs/ MUST stay in: the
|
# frontend/, prompts/, flake.lock. docs/ is deliberately dropped:
|
||||||
# reference-docs derivation (nix/reference-docs.nix, shipped into
|
# it is shipped to agent containers as its OWN narrow
|
||||||
# every agent container via claude --add-dir) builds from ../docs,
|
# meta-flake input (`hyperhiveDocsSource`, below), threaded through
|
||||||
# so a flake source without it can't evaluate — container rebuilds
|
# hive-c0re → the meta flake → `hyperhive.docs.source`. Keeping docs/
|
||||||
# from the meta flake die with "path …/docs does not exist". The
|
# out of THIS source means a doc edit only re-hashes the docs input
|
||||||
# rebuild-avoidance for doc edits is gone by design: containers now
|
# (a cheap re-link), not the whole flake source (which would rebuild
|
||||||
# genuinely depend on the docs tree.
|
# every agent container). The old `nix/reference-docs.nix` build from
|
||||||
|
# `../docs` stays only for standalone `nix build .#reference-docs`
|
||||||
|
# from a full checkout — the meta path never evaluates it.
|
||||||
hyperhiveFlakeSource = lib.cleanSourceWith {
|
hyperhiveFlakeSource = lib.cleanSourceWith {
|
||||||
name = "hyperhive-flake-source";
|
name = "hyperhive-flake-source";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
|
|
@ -56,8 +58,20 @@
|
||||||
rel = lib.removePrefix (toString ./. + "/") (toString path);
|
rel = lib.removePrefix (toString ./. + "/") (toString path);
|
||||||
in
|
in
|
||||||
!(lib.hasPrefix "scripts/" rel || rel == "scripts")
|
!(lib.hasPrefix "scripts/" rel || rel == "scripts")
|
||||||
|
&& !(lib.hasPrefix "docs/" rel || rel == "docs")
|
||||||
&& !(type == "regular" && !lib.hasInfix "/" rel && lib.hasSuffix ".md" rel);
|
&& !(type == "regular" && !lib.hasInfix "/" rel && lib.hasSuffix ".md" rel);
|
||||||
};
|
};
|
||||||
|
# The repo `docs/` tree as a standalone narrow source. Its
|
||||||
|
# store path moves ONLY on doc edits, decoupled from
|
||||||
|
# `hyperhiveFlakeSource`. hive-c0re threads this to the meta flake as
|
||||||
|
# the `hyperhive-docs` input (same pattern as `hyperhiveFlake`); the
|
||||||
|
# harness resolves `$HIVE_DOCS_DIR` from it via `hyperhive.docs.source`.
|
||||||
|
# Evaluated here on the host where docs/ exists — it cannot be derived
|
||||||
|
# from inside the docs-stripped `hyperhiveFlakeSource`.
|
||||||
|
hyperhiveDocsSource = lib.cleanSourceWith {
|
||||||
|
name = "hyperhive-docs-source";
|
||||||
|
src = ./docs;
|
||||||
|
};
|
||||||
treefmt-config = {
|
treefmt-config = {
|
||||||
projectRootFile = "flake.nix";
|
projectRootFile = "flake.nix";
|
||||||
programs = {
|
programs = {
|
||||||
|
|
@ -285,6 +299,9 @@
|
||||||
hyperhiveFrontend = system: self.packages.${system}.frontend;
|
hyperhiveFrontend = system: self.packages.${system}.frontend;
|
||||||
hyperhiveAssets = system: self.packages.${system}.assets;
|
hyperhiveAssets = system: self.packages.${system}.assets;
|
||||||
hyperhiveFlake = "${hyperhiveFlakeSource}";
|
hyperhiveFlake = "${hyperhiveFlakeSource}";
|
||||||
|
# Narrow docs/ source, threaded as its own meta-flake input so
|
||||||
|
# doc edits don't re-hash the whole flake source.
|
||||||
|
hyperhiveDocs = "${hyperhiveDocsSource}";
|
||||||
# Per-container toplevels — wired into `system.extraDependencies`
|
# Per-container toplevels — wired into `system.extraDependencies`
|
||||||
# when `services.hyperhive.c0re.preBuildAgentTemplates` is on so the
|
# when `services.hyperhive.c0re.preBuildAgentTemplates` is on so the
|
||||||
# host system closure pre-fetches the heavy build inputs.
|
# host system closure pre-fetches the heavy build inputs.
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,11 @@ pub struct Coordinator {
|
||||||
/// URL of the hyperhive flake (no fragment). Inlined into per-agent
|
/// URL of the hyperhive flake (no fragment). Inlined into per-agent
|
||||||
/// `flake.nix` files as `inputs.hyperhive.url`.
|
/// `flake.nix` files as `inputs.hyperhive.url`.
|
||||||
pub hyperhive_flake: String,
|
pub hyperhive_flake: String,
|
||||||
|
/// URL of the narrow `docs/` source (no fragment). Inlined into the
|
||||||
|
/// meta `flake.nix` as `inputs.hyperhive-docs.url` and threaded to
|
||||||
|
/// each agent as `hyperhive.docs.source`. Its own store path
|
||||||
|
/// so doc edits don't re-hash `hyperhive_flake`.
|
||||||
|
pub hyperhive_docs_flake: String,
|
||||||
/// Store-path URL of the nixpkgs to wire into the meta flake as
|
/// Store-path URL of the nixpkgs to wire into the meta flake as
|
||||||
/// `inputs.nixpkgs.url`. Populated by `--nixpkgs-flake` (set by the
|
/// `inputs.nixpkgs.url`. Populated by `--nixpkgs-flake` (set by the
|
||||||
/// NixOS module to `"path:${pkgs.path}"` so the meta flake always
|
/// NixOS module to `"path:${pkgs.path}"` so the meta flake always
|
||||||
|
|
@ -197,6 +202,11 @@ pub struct Coordinator {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct HiveEnv {
|
pub struct HiveEnv {
|
||||||
pub hyperhive_flake: String,
|
pub hyperhive_flake: String,
|
||||||
|
/// Store-path URL of the narrow `docs/` source, wired into the meta
|
||||||
|
/// flake as `inputs.hyperhive-docs.url` and threaded to each agent as
|
||||||
|
/// `hyperhive.docs.source`. Separate from `hyperhive_flake`
|
||||||
|
/// so a doc edit only re-locks this input, not the whole source.
|
||||||
|
pub hyperhive_docs_flake: String,
|
||||||
pub nixpkgs_flake: String,
|
pub nixpkgs_flake: String,
|
||||||
pub dashboard_port: u16,
|
pub dashboard_port: u16,
|
||||||
pub operator_pronouns: String,
|
pub operator_pronouns: String,
|
||||||
|
|
@ -211,6 +221,7 @@ impl Default for HiveEnv {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
hyperhive_flake: "/etc/hyperhive".to_string(),
|
hyperhive_flake: "/etc/hyperhive".to_string(),
|
||||||
|
hyperhive_docs_flake: String::new(),
|
||||||
nixpkgs_flake: String::new(),
|
nixpkgs_flake: String::new(),
|
||||||
dashboard_port: 7000,
|
dashboard_port: 7000,
|
||||||
operator_pronouns: "she/her".to_string(),
|
operator_pronouns: "she/her".to_string(),
|
||||||
|
|
@ -425,6 +436,7 @@ impl Coordinator {
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let HiveEnv {
|
let HiveEnv {
|
||||||
hyperhive_flake,
|
hyperhive_flake,
|
||||||
|
hyperhive_docs_flake,
|
||||||
nixpkgs_flake,
|
nixpkgs_flake,
|
||||||
dashboard_port,
|
dashboard_port,
|
||||||
operator_pronouns,
|
operator_pronouns,
|
||||||
|
|
@ -467,6 +479,7 @@ impl Coordinator {
|
||||||
build_logs,
|
build_logs,
|
||||||
audit_log,
|
audit_log,
|
||||||
hyperhive_flake,
|
hyperhive_flake,
|
||||||
|
hyperhive_docs_flake,
|
||||||
nixpkgs_flake,
|
nixpkgs_flake,
|
||||||
dashboard_port,
|
dashboard_port,
|
||||||
operator_pronouns,
|
operator_pronouns,
|
||||||
|
|
@ -496,6 +509,7 @@ impl Coordinator {
|
||||||
pub fn hive_env(&self) -> HiveEnv {
|
pub fn hive_env(&self) -> HiveEnv {
|
||||||
HiveEnv {
|
HiveEnv {
|
||||||
hyperhive_flake: self.hyperhive_flake.clone(),
|
hyperhive_flake: self.hyperhive_flake.clone(),
|
||||||
|
hyperhive_docs_flake: self.hyperhive_docs_flake.clone(),
|
||||||
nixpkgs_flake: self.nixpkgs_flake.clone(),
|
nixpkgs_flake: self.nixpkgs_flake.clone(),
|
||||||
dashboard_port: self.dashboard_port,
|
dashboard_port: self.dashboard_port,
|
||||||
operator_pronouns: self.operator_pronouns.clone(),
|
operator_pronouns: self.operator_pronouns.clone(),
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ pub async fn sync_agents(hive: &HiveEnv, agents: &[AgentSpec]) -> Result<()> {
|
||||||
|
|
||||||
let new_flake = render_flake(
|
let new_flake = render_flake(
|
||||||
&hive.hyperhive_flake,
|
&hive.hyperhive_flake,
|
||||||
|
&hive.hyperhive_docs_flake,
|
||||||
&hive.nixpkgs_flake,
|
&hive.nixpkgs_flake,
|
||||||
hive.dashboard_port,
|
hive.dashboard_port,
|
||||||
&hive.operator_pronouns,
|
&hive.operator_pronouns,
|
||||||
|
|
@ -561,6 +562,7 @@ pub async fn bulk_commit_topology(
|
||||||
|
|
||||||
fn render_flake(
|
fn render_flake(
|
||||||
hyperhive_flake: &str,
|
hyperhive_flake: &str,
|
||||||
|
docs_flake: &str,
|
||||||
nixpkgs_flake: &str,
|
nixpkgs_flake: &str,
|
||||||
dashboard_port: u16,
|
dashboard_port: u16,
|
||||||
operator_pronouns: &str,
|
operator_pronouns: &str,
|
||||||
|
|
@ -569,6 +571,7 @@ fn render_flake(
|
||||||
) -> String {
|
) -> String {
|
||||||
render_flake_with_lookup(
|
render_flake_with_lookup(
|
||||||
hyperhive_flake,
|
hyperhive_flake,
|
||||||
|
docs_flake,
|
||||||
nixpkgs_flake,
|
nixpkgs_flake,
|
||||||
dashboard_port,
|
dashboard_port,
|
||||||
operator_pronouns,
|
operator_pronouns,
|
||||||
|
|
@ -844,6 +847,7 @@ fn agent_canonical_inputs(name: &str) -> Vec<&'static str> {
|
||||||
)]
|
)]
|
||||||
fn render_flake_with_lookup<F>(
|
fn render_flake_with_lookup<F>(
|
||||||
hyperhive_flake: &str,
|
hyperhive_flake: &str,
|
||||||
|
docs_flake: &str,
|
||||||
nixpkgs_flake: &str,
|
nixpkgs_flake: &str,
|
||||||
dashboard_port: u16,
|
dashboard_port: u16,
|
||||||
operator_pronouns: &str,
|
operator_pronouns: &str,
|
||||||
|
|
@ -882,6 +886,17 @@ where
|
||||||
let _ = writeln!(out, " hyperhive.url = \"{hyperhive_flake}\";");
|
let _ = writeln!(out, " hyperhive.url = \"{hyperhive_flake}\";");
|
||||||
out.push_str(" hyperhive.inputs.nixpkgs.follows = \"nixpkgs\";\n");
|
out.push_str(" hyperhive.inputs.nixpkgs.follows = \"nixpkgs\";\n");
|
||||||
}
|
}
|
||||||
|
// Narrow `docs/` source as its own input so a doc edit only
|
||||||
|
// re-locks THIS input instead of re-hashing the whole `hyperhive`
|
||||||
|
// source. Threaded to each agent below as `hyperhive.docs.source`.
|
||||||
|
// Empty = hive-c0re not built with the option wired up (legacy);
|
||||||
|
// agents then keep the harness-base default (`pkgs.hyperhive-docs`).
|
||||||
|
if !docs_flake.is_empty() {
|
||||||
|
// `flake = false`: the docs/ tree is a plain source (no flake.nix),
|
||||||
|
// so nix must treat it as raw source, not evaluate it as a flake.
|
||||||
|
let _ = writeln!(out, " hyperhive-docs.url = \"{docs_flake}\";");
|
||||||
|
out.push_str(" hyperhive-docs.flake = false;\n");
|
||||||
|
}
|
||||||
for spec in agents {
|
for spec in agents {
|
||||||
let _ = writeln!(
|
let _ = writeln!(
|
||||||
out,
|
out,
|
||||||
|
|
@ -930,6 +945,14 @@ where
|
||||||
{
|
{
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
|
// Point the in-container docs dir (`$HIVE_DOCS_DIR`) at the narrow
|
||||||
|
// `hyperhive-docs` input instead of the harness-base default
|
||||||
|
// (`pkgs.hyperhive-docs`, built from the now-docs-stripped source).
|
||||||
|
// `inputs."hyperhive-docs"` is reachable via the outputs `@inputs`
|
||||||
|
// capture. Emitted only when the input exists (docs_flake non-empty).
|
||||||
|
if !docs_flake.is_empty() {
|
||||||
|
out.push_str(" hyperhive.docs.source = inputs.\"hyperhive-docs\".outPath;\n");
|
||||||
|
}
|
||||||
// CA trust: embed every hive-trusted CA so each agent validates them at
|
// CA trust: embed every hive-trusted CA so each agent validates them at
|
||||||
// build time. The list is the hive's own self-signed CA (when active)
|
// build time. The list is the hive's own self-signed CA (when active)
|
||||||
// plus every peer-hive root CA (`swarm.peers.<d>.caCert`) — a peer CA is
|
// plus every peer-hive root CA (`swarm.peers.<d>.caCert`) — a peer CA is
|
||||||
|
|
@ -1274,6 +1297,7 @@ mod tests {
|
||||||
fn render_flake_uses_explicit_nixpkgs_url_when_provided() {
|
fn render_flake_uses_explicit_nixpkgs_url_when_provided() {
|
||||||
let out = render_flake(
|
let out = render_flake(
|
||||||
"github:example/hyperhive",
|
"github:example/hyperhive",
|
||||||
|
"path:/nix/store/bbbb-hyperhive-docs-source",
|
||||||
"path:/nix/store/aaaa-nixpkgs-source",
|
"path:/nix/store/aaaa-nixpkgs-source",
|
||||||
8000,
|
8000,
|
||||||
"she/her",
|
"she/her",
|
||||||
|
|
@ -1294,6 +1318,39 @@ mod tests {
|
||||||
!out.contains("nixpkgs.follows = \"hyperhive"),
|
!out.contains("nixpkgs.follows = \"hyperhive"),
|
||||||
"old-style follows must not appear when flake args are set:\n{out}"
|
"old-style follows must not appear when flake args are set:\n{out}"
|
||||||
);
|
);
|
||||||
|
// the narrow docs source is its own non-flake input, and each
|
||||||
|
// agent's docs dir resolves from it rather than pkgs.hyperhive-docs.
|
||||||
|
assert!(
|
||||||
|
out.contains("hyperhive-docs.url = \"path:/nix/store/bbbb-hyperhive-docs-source\""),
|
||||||
|
"expected hyperhive-docs input url:\n{out}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
out.contains("hyperhive-docs.flake = false;"),
|
||||||
|
"docs source is not a flake, must be flake = false:\n{out}"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
out.contains("hyperhive.docs.source = inputs.\"hyperhive-docs\".outPath;"),
|
||||||
|
"expected per-agent docs source wired to the input:\n{out}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn render_flake_omits_docs_input_when_docs_flake_empty() {
|
||||||
|
// Legacy / not-wired-up: empty docs_flake emits no docs input and
|
||||||
|
// leaves each agent on the harness-base default (pkgs.hyperhive-docs).
|
||||||
|
let out = render_flake(
|
||||||
|
"github:example/hyperhive",
|
||||||
|
"",
|
||||||
|
"path:/nix/store/aaaa-nixpkgs-source",
|
||||||
|
8000,
|
||||||
|
"she/her",
|
||||||
|
&std::collections::HashMap::new(),
|
||||||
|
&[sample_spec("alice", false, 9001)],
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!out.contains("hyperhive-docs"),
|
||||||
|
"no docs input/source when docs_flake is empty:\n{out}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -1302,6 +1359,7 @@ mod tests {
|
||||||
// for any code path that can't inject pkgs.path).
|
// for any code path that can't inject pkgs.path).
|
||||||
let out = render_flake(
|
let out = render_flake(
|
||||||
"github:example/hyperhive",
|
"github:example/hyperhive",
|
||||||
|
"path:/nix/store/bbbb-hyperhive-docs-source",
|
||||||
"",
|
"",
|
||||||
8000,
|
8000,
|
||||||
"she/her",
|
"she/her",
|
||||||
|
|
@ -1330,6 +1388,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
let out = render_flake_with_lookup(
|
let out = render_flake_with_lookup(
|
||||||
"github:example/hyperhive",
|
"github:example/hyperhive",
|
||||||
|
"path:/nix/store/bbbb-hyperhive-docs-source",
|
||||||
"path:/nix/store/aaaa-nixpkgs-source",
|
"path:/nix/store/aaaa-nixpkgs-source",
|
||||||
8000,
|
8000,
|
||||||
"she/her",
|
"she/her",
|
||||||
|
|
@ -1361,6 +1420,7 @@ mod tests {
|
||||||
fn render_flake_skips_canonical_follows_when_lookup_returns_empty() {
|
fn render_flake_skips_canonical_follows_when_lookup_returns_empty() {
|
||||||
let out = render_flake_with_lookup(
|
let out = render_flake_with_lookup(
|
||||||
"github:example/hyperhive",
|
"github:example/hyperhive",
|
||||||
|
"path:/nix/store/bbbb-hyperhive-docs-source",
|
||||||
"path:/nix/store/aaaa-nixpkgs-source",
|
"path:/nix/store/aaaa-nixpkgs-source",
|
||||||
8000,
|
8000,
|
||||||
"she/her",
|
"she/her",
|
||||||
|
|
@ -1394,6 +1454,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
let out = render_flake(
|
let out = render_flake(
|
||||||
"github:example/hyperhive",
|
"github:example/hyperhive",
|
||||||
|
"path:/nix/store/bbbb-hyperhive-docs-source",
|
||||||
"path:/nix/store/aaaa-nixpkgs-source",
|
"path:/nix/store/aaaa-nixpkgs-source",
|
||||||
8000,
|
8000,
|
||||||
"she/her",
|
"she/her",
|
||||||
|
|
@ -1441,6 +1502,7 @@ mod tests {
|
||||||
let render = || {
|
let render = || {
|
||||||
render_flake(
|
render_flake(
|
||||||
"github:example/hyperhive",
|
"github:example/hyperhive",
|
||||||
|
"path:/nix/store/bbbb-hyperhive-docs-source",
|
||||||
"path:/nix/store/aaaa-nixpkgs-source",
|
"path:/nix/store/aaaa-nixpkgs-source",
|
||||||
8000,
|
8000,
|
||||||
"she/her",
|
"she/her",
|
||||||
|
|
@ -1522,6 +1584,7 @@ mod tests {
|
||||||
let render = || {
|
let render = || {
|
||||||
render_flake(
|
render_flake(
|
||||||
"github:example/hyperhive",
|
"github:example/hyperhive",
|
||||||
|
"path:/nix/store/bbbb-hyperhive-docs-source",
|
||||||
"path:/nix/store/aaaa-nixpkgs-source",
|
"path:/nix/store/aaaa-nixpkgs-source",
|
||||||
8000,
|
8000,
|
||||||
"she/her",
|
"she/her",
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
hyperhiveFrontend,
|
hyperhiveFrontend,
|
||||||
hyperhiveAssets,
|
hyperhiveAssets,
|
||||||
hyperhiveFlake,
|
hyperhiveFlake,
|
||||||
|
hyperhiveDocs,
|
||||||
agentBaseToplevel,
|
agentBaseToplevel,
|
||||||
managerToplevel,
|
managerToplevel,
|
||||||
}:
|
}:
|
||||||
|
|
@ -39,6 +40,7 @@ let
|
||||||
serveConfig = pkgs.writeText "hive-c0re-serve.json" (
|
serveConfig = pkgs.writeText "hive-c0re-serve.json" (
|
||||||
builtins.toJSON {
|
builtins.toJSON {
|
||||||
hyperhive_flake = cfg.hyperhiveFlake;
|
hyperhive_flake = cfg.hyperhiveFlake;
|
||||||
|
hyperhive_docs_flake = cfg.hyperhiveDocs;
|
||||||
nixpkgs_flake = cfg.nixpkgsFlake;
|
nixpkgs_flake = cfg.nixpkgsFlake;
|
||||||
dashboard_port = cfg.dashboardPort;
|
dashboard_port = cfg.dashboardPort;
|
||||||
operator_pronouns = cfg.operatorPronouns;
|
operator_pronouns = cfg.operatorPronouns;
|
||||||
|
|
@ -558,6 +560,19 @@ in
|
||||||
only override if you want agents tracking a different ref.
|
only override if you want agents tracking a different ref.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
hyperhiveDocs = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = hyperhiveDocs;
|
||||||
|
defaultText = lib.literalMD "the docs/ tree's own store path";
|
||||||
|
description = ''
|
||||||
|
URL of the narrow `docs/` source (no fragment). Inlined into the
|
||||||
|
generated meta `flake.nix` at `inputs.hyperhive-docs.url` and
|
||||||
|
threaded to each agent as `hyperhive.docs.source`, from which the
|
||||||
|
harness resolves `$HIVE_DOCS_DIR`. Its own store path — separate
|
||||||
|
from `hyperhiveFlake` — so a doc edit only re-locks this input
|
||||||
|
instead of rebuilding every agent container.
|
||||||
|
'';
|
||||||
|
};
|
||||||
nixpkgsFlake = lib.mkOption {
|
nixpkgsFlake = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
default = "path:${pkgs.path}";
|
default = "path:${pkgs.path}";
|
||||||
|
|
|
||||||
|
|
@ -100,19 +100,21 @@ let
|
||||||
iconPng = pkgs.runCommand "hive-agent-icon.png" { nativeBuildInputs = [ pkgs.librsvg ]; } ''
|
iconPng = pkgs.runCommand "hive-agent-icon.png" { nativeBuildInputs = [ pkgs.librsvg ]; } ''
|
||||||
rsvg-convert -f png -w 512 -h 512 ${config.hyperhive.icon} -o $out
|
rsvg-convert -f png -w 512 -h 512 ${config.hyperhive.icon} -o $out
|
||||||
'';
|
'';
|
||||||
# hyperhive.docs.enable: the reference-docs tree (`pkgs.hyperhive-docs`,
|
# hyperhive.docs.enable: the reference-docs tree (from
|
||||||
# the repo `docs/` verbatim) with a generic `CLAUDE.md` pointer dropped
|
# `config.hyperhive.docs.source` — the narrow `hyperhive-docs` meta-flake
|
||||||
# at the root. The harness passes this dir to claude via `--add-dir`;
|
# input in a hive deployment, or `pkgs.hyperhive-docs` for standalone
|
||||||
# paired with `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1` claude
|
# builds) with a generic `CLAUDE.md` pointer dropped at the root. The
|
||||||
# loads `<dir>/CLAUDE.md` ADDITIVELY (alongside, never replacing, the
|
# harness passes this dir to claude via `--add-dir`; paired with
|
||||||
# agent's own `~/.claude/CLAUDE.md`). The pointer prose lives in
|
# `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1` claude loads
|
||||||
|
# `<dir>/CLAUDE.md` ADDITIVELY (alongside, never replacing, the agent's
|
||||||
|
# own `~/.claude/CLAUDE.md`). The pointer prose lives in
|
||||||
# `hive-ag3nt/prompts/docs-pointer.md` (prompts belong in prompts/, not
|
# `hive-ag3nt/prompts/docs-pointer.md` (prompts belong in prompts/, not
|
||||||
# nix/) and is shipped via `hyperhive-assets`. `hyperhive-docs` itself
|
# nix/) and is shipped via `hyperhive-assets`. The docs source itself
|
||||||
# stays pure (no CLAUDE.md) so the website can reuse the same tree.
|
# stays pure (no CLAUDE.md) so the website can reuse the same tree.
|
||||||
# Lazy: only forced when `hyperhive.docs.enable` references it below.
|
# Lazy: only forced when `hyperhive.docs.enable` references it below.
|
||||||
agentDocs = pkgs.runCommand "hyperhive-agent-docs" { } ''
|
agentDocs = pkgs.runCommand "hyperhive-agent-docs" { } ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp -r ${pkgs.hyperhive-docs}/. $out/
|
cp -r ${config.hyperhive.docs.source}/. $out/
|
||||||
chmod -R u+w $out
|
chmod -R u+w $out
|
||||||
cp ${pkgs.hyperhive-assets}/share/hyperhive/prompts/docs-pointer.md $out/CLAUDE.md
|
cp ${pkgs.hyperhive-assets}/share/hyperhive/prompts/docs-pointer.md $out/CLAUDE.md
|
||||||
'';
|
'';
|
||||||
|
|
@ -269,6 +271,22 @@ in
|
||||||
elsewhere; any agent can flip it from its `agent.nix`.
|
elsewhere; any agent can flip it from its `agent.nix`.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
options.hyperhive.docs.source = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = pkgs.hyperhive-docs;
|
||||||
|
defaultText = lib.literalMD "`pkgs.hyperhive-docs` (built from `../docs`)";
|
||||||
|
description = ''
|
||||||
|
Store path of the reference-docs tree exposed at `$HIVE_DOCS_DIR`
|
||||||
|
when `hyperhive.docs.enable` is set. Defaults to the overlay's
|
||||||
|
`pkgs.hyperhive-docs` (the `nix/reference-docs.nix` build from
|
||||||
|
`../docs`) so a standalone container build from a full checkout
|
||||||
|
works unchanged. The generated meta flake overrides this with the
|
||||||
|
narrow `hyperhive-docs` flake input so a doc edit only
|
||||||
|
re-locks that input instead of rebuilding the container from a
|
||||||
|
re-hashed `hyperhive` source.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
options.hyperhive.allowedBashPatterns = lib.mkOption {
|
options.hyperhive.allowedBashPatterns = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
|
@ -1408,7 +1426,10 @@ in
|
||||||
# `--add-dir` so the docs are readable; with
|
# `--add-dir` so the docs are readable; with
|
||||||
# `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1` claude also loads
|
# `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1` claude also loads
|
||||||
# the pointer additively, telling the agent the docs exist without
|
# the pointer additively, telling the agent the docs exist without
|
||||||
# clobbering its own memory. See hive-ag3nt::turn.
|
# clobbering its own memory. See hive-ag3nt::turn. The docs tree
|
||||||
|
# itself comes from `hyperhive.docs.source` (the narrow
|
||||||
|
# `hyperhive-docs` meta-flake input, or `pkgs.hyperhive-docs` for
|
||||||
|
# standalone builds) via `agentDocs`.
|
||||||
HIVE_DOCS_DIR = "${agentDocs}";
|
HIVE_DOCS_DIR = "${agentDocs}";
|
||||||
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD = "1";
|
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD = "1";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue