Add terminal client, memory, model fallback, version and install improvements
- codecraft: full-screen terminal client (ratatui) – local tools and files, models via the CodeCraft server gateway or own providers (standalone with a guided setup), slash commands, @files, permission dialogs, resume, update - Static Linux CLI builds (x86_64/aarch64, cargo-zigbuild) served by the server: /cli/install.sh and /cli/download/<target> - Project memory (remember tool, .codecraft/memory.md) and personal memory - Model fallback when a host is unreachable or a budget is used up - Version/commit in UI and health, daily release check, "What's new" dialog - PWA: install button, maskable icon, manifest id and screenshots - Case-insensitive detection of connection errors for retries Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa1f8cf016
commit
6dffcb501a
52 files changed
+6477
-765
No files matched your search
@@ -97,6 +97,45 @@ impl Tool for CraftPhase {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Project memory: lasting facts about the project in .codecraft/memory.md.
|
||||
pub struct Remember;
|
||||
|
||||
#[async_trait]
|
||||
impl Tool for Remember {
|
||||
fn name(&self) -> &str {
|
||||
"remember"
|
||||
}
|
||||
fn description(&self) -> String {
|
||||
"Save a lasting insight about this project (build/test commands, conventions, pitfalls, decisions) to \
|
||||
.codecraft/memory.md – it is loaded into every future session in this project. Keep entries short; \
|
||||
never store secrets or temporary state."
|
||||
.into()
|
||||
}
|
||||
fn schema(&self) -> Value {
|
||||
json!({"type": "object", "properties": {"note": {"type": "string"}}, "required": ["note"]})
|
||||
}
|
||||
fn is_edit(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn title(&self, input: &Value) -> String {
|
||||
input["note"].as_str().unwrap_or("").chars().take(80).collect()
|
||||
}
|
||||
async fn run(&self, input: Value, ctx: &ToolCtx) -> Result<ToolOutput> {
|
||||
let note = arg_str(&input, "note")?.trim().replace('\n', " ");
|
||||
let path = ctx.resolve(".codecraft/memory.md")?;
|
||||
std::fs::create_dir_all(path.parent().unwrap())?;
|
||||
let mut text = std::fs::read_to_string(&path).unwrap_or_else(|_| "# Project memory\n\nLearned facts about this project (maintained by CodeCraft; edit freely).\n\n".into());
|
||||
if !text.ends_with('\n') {
|
||||
text.push('\n');
|
||||
}
|
||||
text.push_str(&format!("- {note}\n"));
|
||||
std::fs::write(&path, &text)?;
|
||||
Ok(ToolOutput::text(format!("Saved to .codecraft/memory.md: {note}")).with_meta(json!({"memory": note})))
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Switch the session's working directory (only on the user's request).
|
||||
pub struct ChangeDirectory;
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@ pub fn builtin_tools() -> Vec<Arc<dyn Tool>> {
|
||||
Arc::new(web::WebSearch),
|
||||
Arc::new(agent::CraftPhase),
|
||||
Arc::new(agent::ChangeDirectory),
|
||||
Arc::new(agent::Remember),
|
||||
Arc::new(cad::OpenScad),
|
||||
Arc::new(crate::jobs::Schedule),
|
||||
Arc::new(crate::lsp::Diagnostics),
|
||||
|
||||
Reference in new issue
Block a user