style: treefmt main — fix CI formatting check
Full `nix flake check` (CI) runs the treefmt formatting derivation. While the hive-ci runner was offline (#1221), PRs merged without it, leaving 5 files unformatted: hive-ag3nt/src/web_ui.rs, hive-c0re/src/bin/hivectl.rs, hive-c0re/src/knowledge.rs, hive-c0re/src/matrix.rs, hive-forge/src/verbs/attachment_get.rs. `nix fmt` output, pure formatting.
This commit is contained in:
parent
c70823755b
commit
20c5039156
5 changed files with 62 additions and 44 deletions
|
|
@ -618,7 +618,11 @@ fn read_own_status() -> (Option<String>, Option<i64>) {
|
|||
.and_then(|d| i64::try_from(d.as_secs()).ok())
|
||||
})
|
||||
});
|
||||
if text.is_none() { (None, None) } else { (text, mtime) }
|
||||
if text.is_none() {
|
||||
(None, None)
|
||||
} else {
|
||||
(text, mtime)
|
||||
}
|
||||
}
|
||||
|
||||
async fn api_dashboard_state(State(state): State<AppState>) -> axum::Json<DashboardState> {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
//! dirs) and reuse the `forge` / `matrix` modules from the
|
||||
//! `hive-c0re` lib — single source of truth, no duplication.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::CommandExt as _;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
use clap::{Parser, Subcommand};
|
||||
|
|
@ -339,9 +339,7 @@ fn is_agent(name: &str) -> bool {
|
|||
/// fully interactive. Requires root and a running container.
|
||||
fn choom(name: &str, fresh: bool) -> Result<()> {
|
||||
if !is_agent(name) {
|
||||
bail!(
|
||||
"no such agent: '{name}' (no state dir under /var/lib/hyperhive/agents/)"
|
||||
);
|
||||
bail!("no such agent: '{name}' (no state dir under /var/lib/hyperhive/agents/)");
|
||||
}
|
||||
let container = hive_c0re::lifecycle::container_name(name);
|
||||
let claude = "/run/current-system/sw/bin/claude";
|
||||
|
|
|
|||
|
|
@ -152,7 +152,10 @@ pub async fn ensure_webhook(core_token: &str, dashboard_port: u16) -> Result<()>
|
|||
.context("build reqwest client for webhook setup")?;
|
||||
|
||||
// List existing hooks — skip creation if ours is already there.
|
||||
let list_url = format!("{}/api/v1/repos/{ORG}/{REPO}/hooks", crate::forge::FORGE_HTTP);
|
||||
let list_url = format!(
|
||||
"{}/api/v1/repos/{ORG}/{REPO}/hooks",
|
||||
crate::forge::FORGE_HTTP
|
||||
);
|
||||
let resp = client
|
||||
.get(&list_url)
|
||||
.header("Authorization", format!("token {core_token}"))
|
||||
|
|
@ -174,7 +177,10 @@ pub async fn ensure_webhook(core_token: &str, dashboard_port: u16) -> Result<()>
|
|||
}
|
||||
|
||||
// Create the webhook.
|
||||
let create_url = format!("{}/api/v1/repos/{ORG}/{REPO}/hooks", crate::forge::FORGE_HTTP);
|
||||
let create_url = format!(
|
||||
"{}/api/v1/repos/{ORG}/{REPO}/hooks",
|
||||
crate::forge::FORGE_HTTP
|
||||
);
|
||||
let body = serde_json::json!({
|
||||
"type": "forgejo",
|
||||
"config": {
|
||||
|
|
|
|||
|
|
@ -299,12 +299,9 @@ async fn auto_reset_password(client: &reqwest::Client, name: &str) -> anyhow::Re
|
|||
let server_name = discover_server_name(client)
|
||||
.await
|
||||
.context("matrix: discover_server_name for auto-recovery")?;
|
||||
let effective_password =
|
||||
reset_user_password(client, &admin_token, name, &server_name)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!("matrix: admin-room password reset for {name} (auto-recovery)")
|
||||
})?;
|
||||
let effective_password = reset_user_password(client, &admin_token, name, &server_name)
|
||||
.await
|
||||
.with_context(|| format!("matrix: admin-room password reset for {name} (auto-recovery)"))?;
|
||||
tracing::info!(%name, "matrix: auto-recovered password via admin-room reset");
|
||||
Ok(effective_password)
|
||||
}
|
||||
|
|
@ -345,9 +342,7 @@ async fn discover_admin_room_id(
|
|||
json["room_id"]
|
||||
.as_str()
|
||||
.map(|s| s.to_owned())
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!("matrix: admin room alias response missing room_id: {json}")
|
||||
})
|
||||
.ok_or_else(|| anyhow::anyhow!("matrix: admin room alias response missing room_id: {json}"))
|
||||
}
|
||||
|
||||
/// Extract the new password from a conduit/tuwunel admin-room reset reply.
|
||||
|
|
@ -411,7 +406,8 @@ mod extract_new_password_tests {
|
|||
#[test]
|
||||
fn password_with_symbols_inside_span() {
|
||||
// '@' mid-token is fine — only a leading "@…:…" user-id shape is rejected.
|
||||
let msg = "Successfully reset the password for user @atlas:pr1ma.darkest.space: `N3wP@ss-w0rd!`";
|
||||
let msg =
|
||||
"Successfully reset the password for user @atlas:pr1ma.darkest.space: `N3wP@ss-w0rd!`";
|
||||
assert_eq!(extract_new_password(msg).as_deref(), Some("N3wP@ss-w0rd!"));
|
||||
}
|
||||
|
||||
|
|
@ -467,9 +463,8 @@ async fn admin_room_send_and_poll<T>(
|
|||
) -> Result<T> {
|
||||
// Send the command; record the event_id so we can use it as an anchor.
|
||||
let txn_id = random_hex(8)?;
|
||||
let send_url = format!(
|
||||
"{MATRIX_HTTP}/_matrix/client/v3/rooms/{room_url}/send/m.room.message/{txn_id}"
|
||||
);
|
||||
let send_url =
|
||||
format!("{MATRIX_HTTP}/_matrix/client/v3/rooms/{room_url}/send/m.room.message/{txn_id}");
|
||||
let send_resp = client
|
||||
.put(&send_url)
|
||||
.bearer_auth(admin_token)
|
||||
|
|
@ -478,25 +473,24 @@ async fn admin_room_send_and_poll<T>(
|
|||
.await
|
||||
.context("matrix: PUT admin room message")?;
|
||||
if !send_resp.status().is_success() {
|
||||
let body = send_resp.json::<serde_json::Value>().await.unwrap_or_default();
|
||||
let body = send_resp
|
||||
.json::<serde_json::Value>()
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
anyhow::bail!("matrix: admin room send failed: {body}");
|
||||
}
|
||||
let send_json = send_resp
|
||||
.json::<serde_json::Value>()
|
||||
.await
|
||||
.unwrap_or_default();
|
||||
let our_event_id = send_json["event_id"]
|
||||
.as_str()
|
||||
.unwrap_or("")
|
||||
.to_owned();
|
||||
let our_event_id = send_json["event_id"].as_str().unwrap_or("").to_owned();
|
||||
|
||||
// Poll for bot response: fetch the 20 most recent events (newest-first)
|
||||
// on each tick. Walk the list until we hit our own command event_id;
|
||||
// everything *before* that marker arrived after our command.
|
||||
let own_user_id = format!("@{HIVE_ADMIN_LOCALPART}:{server_name}");
|
||||
let poll_url = format!(
|
||||
"{MATRIX_HTTP}/_matrix/client/v3/rooms/{room_url}/messages?dir=b&limit=20"
|
||||
);
|
||||
let poll_url =
|
||||
format!("{MATRIX_HTTP}/_matrix/client/v3/rooms/{room_url}/messages?dir=b&limit=20");
|
||||
for _ in 0..15_u8 {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||
let poll_json = client
|
||||
|
|
@ -562,15 +556,22 @@ async fn admin_room_reset_password(
|
|||
let room_id = discover_admin_room_id(client, admin_token, server_name).await?;
|
||||
let room_url = encode_room_id_for_url(&room_id);
|
||||
let command = format!("!admin users reset-password @{localpart}:{server_name}");
|
||||
admin_room_send_and_poll(client, admin_token, server_name, &room_url, &command, extract_new_password)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"matrix: admin room reset-password for @{localpart}:{server_name}: \
|
||||
admin_room_send_and_poll(
|
||||
client,
|
||||
admin_token,
|
||||
server_name,
|
||||
&room_url,
|
||||
&command,
|
||||
extract_new_password,
|
||||
)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"matrix: admin room reset-password for @{localpart}:{server_name}: \
|
||||
no password response received within 15 seconds. \
|
||||
Verify the admin room accepts '!admin users reset-password @user:server' commands."
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Ensure `name` has a matrix user + token file on the local
|
||||
|
|
@ -838,14 +839,21 @@ pub async fn promote_user_to_admin(
|
|||
let room_id = discover_admin_room_id(client, admin_token, server_name).await?;
|
||||
let room_url = encode_room_id_for_url(&room_id);
|
||||
let command = format!("!admin users make-user-admin @{localpart}:{server_name}");
|
||||
admin_room_send_and_poll(client, admin_token, server_name, &room_url, &command, |body| {
|
||||
let lower = body.to_ascii_lowercase();
|
||||
if lower.starts_with("done") || lower.contains("made") && lower.contains("admin") {
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
admin_room_send_and_poll(
|
||||
client,
|
||||
admin_token,
|
||||
server_name,
|
||||
&room_url,
|
||||
&command,
|
||||
|body| {
|
||||
let lower = body.to_ascii_lowercase();
|
||||
if lower.starts_with("done") || lower.contains("made") && lower.contains("admin") {
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
|
|
|
|||
|
|
@ -80,7 +80,9 @@ fn extract_uuid(input: &str) -> Result<String> {
|
|||
.rsplit('/')
|
||||
.next()
|
||||
.filter(|s| !s.is_empty())
|
||||
.ok_or_else(|| anyhow::anyhow!("hive-forge attachment-get: cannot extract UUID from {input:?}"))?
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!("hive-forge attachment-get: cannot extract UUID from {input:?}")
|
||||
})?
|
||||
} else {
|
||||
input
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue