diff --git a/AGENTS.md b/AGENTS.md index c84943f85..a6ef27a93 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -54,100 +54,14 @@ signet secret list About Your User --- -- Name: Nicholai -- Pronouns: he/him -- Timezone: America/Denver -- Role: dev, AI researcher, artist +Add information about yourself here so your agent knows who you are. + +- Name: +- Preferences: Projects --- -See USER.md for the full project list. +List your active projects here. -## Operational Settings - -- **Proactivity:** proactive - suggest things you notice, don't wait to be asked -- **External actions:** always ask before anything public-facing (emails, messages, deployments, posts) -- **Error handling:** own it briefly, fix it, move on. no groveling. -- **Parallel work:** use judgment based on complexity - -## Memory - -- **Remember:** aggressive - log patterns, preferences, project details, anything useful -- **Forgetting:** ask before removing anything - -## Hard Rules - -- Never delete production database without backup -- Never auto-deploy nicholai's website - he prefers manual control -- Do not delegate UI work to subagents - implement yourself -- Signet agent profile lives at `~/.agents/` (not `~/.signet/`) -- Always ask before external/public-facing actions - - -## Memory Context (auto-synced) - - - -Current Context - -Active maintenance of the `signetai` monorepo and OpenMarketUI ecosystem, with a specific focus on contributing high-value fixes to the OpenClaw project and engaging its community by positioning Signet as a complementary utility rather than a competitor. - -Active Projects - -OpenMarketUI (Core) - Location: `/home/nicholai/signet/signetai` - Status: Main branch active, codebase audit completed. - Details: A multi-component system including the trading pipeline, UI components, and Astro-based static site generator. Currently using TypeScript, Biome for linting (no config file), and Bun/Turbo for build orchestration. - Next Steps: Continue monitoring PRs and ensuring consistent naming conventions throughout the codebase. - -Predictive Memory Scorer (R&D) - Location: Rust implementation, architecture docs in `docs/wip/predictive-memory-scorer.md` - Status: Architecture defined; ACAN reference available in `references/acan/`. - Details: Experimental component utilizing 8 delegated agents for real-time preference processing. - Next Steps: Implementation and integration testing. - -OpenMarketUI Website - Location: `/web/` (Astro) - Status: Active build and deployment pipeline. - Details: Published as an npm package named `openmarketui-web` and deployed via Cloudflare Pages. - -OpenClaw Ecosystem Engagement - Status: Bugfixing and Community Outreach. - Details: Currently fixing specific issues in the OpenClaw codebase and drafting forum content to share Signet features. - Next Steps: Complete the secret provider timeout bugfix; finalize and post the OpenClaw discussion thread emphasizing problem-solving over feature comparison. - -Recent Work - -OpenClaw Bugfix: Mistral Tool Call Sanitization - Action: Fixed a logic error in `src/agents/transcript-policy.ts:120`. - Issue: The condition `sanitizeToolCallIds: !isOpenAi && sanitizeToolCallIds` incorrectly short-circuited sanitization for Mistral models when used via an OpenAI-compatible provider. - Resolution: Added regression tests and committed the fix. PR created for review. - -OpenClaw Outreach Strategy - Action: Drafted content for OpenClaw discussions. - Decision: Shifted the narrative away from comparing Signet to ChatGPT/Claude Code. Instead, focused on Signet being a practical solution to specific pain points identified in OpenClaw discussions (#842 memory issues, #9676 secrets concerns). - -OpenClaw Bugfix: Exec Secret Provider Timeout - Action: Identified hardcoded timeout in `src/secrets/resolve.ts:544`. - Issue: The timeout was fixed at 2000ms, ignoring user-configured `timeoutMs` values. - Status: Identified root cause; fix implementation in progress. - -Technical Notes - - Environment: Operating system is Arch Linux running Hyprland window manager. - Storage: User state and secrets are stored in `~/.agents/`. The memory database uses SQLite located within this directory. - Secrets Management: Mandatory workflow uses `secret_list` MCP to discover secrets and `secret_exec` MCP to execute commands securely. - TypeScript Configuration: Strict mode enforced. No usage of `any` types allowed; must use `unknown` with narrowing. Null checks must be explicit. - Git: Commit messages must follow Conventional Commits format. - UI Workflow: For any frontend/UI work involving images or complex layouts, always use the original image references and do not delegate the task to sub-agents. - Session Handling: The session compacting hook is active but limited in scope. - -Rules & Warnings - - Security First: Never delete production data without creating a backup first. - Secrets: Always utilize the `secret_list` and `secret_exec` MCP tools for any operations involving secrets. - Code Quality: Enforce strict TypeScript rules: `any` is forbidden; use `unknown` with type narrowing; explicit null checks preferred. - UI Guidelines: Never delegate UI-related coding to sub-agents. Ensure original image references are preserved in all renders. - Maintenance: Update `MEMORY.md` in the local database at least once per session to track progress and context. - +- diff --git a/agent.yaml b/agent.yaml index f2135efc8..0ce0a8266 100644 --- a/agent.yaml +++ b/agent.yaml @@ -2,16 +2,15 @@ version: 1 schema: signet/v1 agent: name: Mr Claude - description: the exceptionally helpful, capable, thoughtful, and friendly - assistant to Nicholai - created: 2026-02-23T11:25:00.507Z - updated: 2026-02-23T11:25:00.507Z + description: The exceptionally kind, helpful and thoughtful agent. + created: "2026-03-03T12:17:50.888Z" + updated: "2026-03-03T12:17:50.888Z" harnesses: - claude-code - opencode - openclaw install: - primary_package_manager: npm + primary_package_manager: bun source: fallback memory: database: memory/memories.db @@ -19,25 +18,22 @@ memory: decay_rate: 0.95 pipelineV2: enabled: true - extractionProvider: claude-code - extractionModel: haiku - maintenanceMode: execute - allowUpdateDelete: true - graphEnabled: true - autonomousEnabled: true + extraction: + provider: claude-code + model: haiku + graph: + enabled: true reranker: enabled: true - topN: 20 - timeoutMs: 2000 - rerankerEnabled: true + autonomous: + enabled: true + allowUpdateDelete: true + maintenanceMode: execute search: alpha: 0.7 top_k: 20 min_score: 0.3 - rehearsal_enabled: true - rehearsal_weight: 0.1 - rehearsal_half_life_days: 30 embedding: - provider: ollama - model: nomic-embed-text + provider: native + model: nomic-embed-text-v1.5 dimensions: 768 diff --git a/memory/memories.db b/memory/memories.db index f894e1cdb..47726d9d6 100644 Binary files a/memory/memories.db and b/memory/memories.db differ diff --git a/scripts/generate-harness-configs.py b/scripts/generate-harness-configs.py index fa093cba9..0dda9a4df 100755 --- a/scripts/generate-harness-configs.py +++ b/scripts/generate-harness-configs.py @@ -1,94 +1,101 @@ #!/usr/bin/env python3 """ -Generate harness-specific config files from AGENTS.md +Generate harness-specific config files from identity files -Source of truth: ~/.agents/AGENTS.md +Source of truth: ~/.agents/ (AGENTS.md, SOUL.md, IDENTITY.md, USER.md, MEMORY.md) Generates: - ~/.claude/CLAUDE.md (Claude Code) - ~/.config/opencode/AGENTS.md (OpenCode) -Run manually or via systemd timer after AGENTS.md changes. +Run manually or via systemd timer after identity file changes. """ import sys from pathlib import Path from datetime import datetime -AGENTS_MD = Path.home() / ".agents/AGENTS.md" +AGENTS_DIR = Path.home() / ".agents" +AGENTS_MD = AGENTS_DIR / "AGENTS.md" + +# Additional identity files to compose (in order) +IDENTITY_FILES = ["SOUL.md", "IDENTITY.md", "USER.md", "MEMORY.md"] TARGETS = { "claude-code": Path.home() / ".claude/CLAUDE.md", "opencode": Path.home() / ".config/opencode/AGENTS.md", } -HEADER = """# Auto-generated from ~/.agents/AGENTS.md +HEADER = """# Auto-generated from ~/.agents/ identity files # Source: {source} # Generated: {timestamp} # DO NOT EDIT - changes will be overwritten -# Edit ~/.agents/AGENTS.md instead +# Edit the source files in ~/.agents/ instead """ -def generate_config(source_content: str, harness: str) -> str: - """Generate harness-specific config from AGENTS.md content.""" - +def read_identity_extras() -> str: + """Read and compose additional identity files with section headers.""" + parts = [] + for name in IDENTITY_FILES: + path = AGENTS_DIR / name + if not path.exists(): + continue + content = path.read_text().strip() + if not content: + continue + header = name.replace(".md", "") + parts.append(f"\n## {header}\n\n{content}") + return "\n".join(parts) + + +def generate_config(source_content: str, extras: str, harness: str) -> str: + """Generate harness-specific config from identity file content.""" + header = HEADER.format( - source=AGENTS_MD, + source=AGENTS_DIR, timestamp=datetime.now().isoformat() ) - - # For now, configs are identical - but this allows harness-specific - # transformations in the future (e.g., removing sections, adding - # harness-specific instructions) - - if harness == "claude-code": - # Claude Code uses CLAUDE.md - return header + source_content - - elif harness == "opencode": - # OpenCode uses AGENTS.md - return header + source_content - - else: - return header + source_content + + return header + source_content + extras def main(): if not AGENTS_MD.exists(): print(f"ERROR: Source file not found: {AGENTS_MD}") sys.exit(1) - + source_content = AGENTS_MD.read_text() - source_hash = hash(source_content) - - print(f"Source: {AGENTS_MD}") - print(f"Content length: {len(source_content)} chars") + extras = read_identity_extras() + + print(f"Source: {AGENTS_DIR}") + print(f"AGENTS.md: {len(source_content)} chars") + print(f"Identity extras: {len(extras)} chars") print() - + for harness, target_path in TARGETS.items(): # Ensure parent directory exists target_path.parent.mkdir(parents=True, exist_ok=True) - + # Remove symlink if it exists if target_path.is_symlink(): target_path.unlink() print(f" Removed symlink: {target_path}") - + # Generate config - config_content = generate_config(source_content, harness) - + config_content = generate_config(source_content, extras, harness) + # Check if content changed if target_path.exists(): existing_content = target_path.read_text() if existing_content == config_content: print(f" {harness}: unchanged") continue - + # Write new config target_path.write_text(config_content) print(f" {harness}: generated → {target_path}") - + print() print("Done.")