Commit graph

36 commits

Author SHA1 Message Date
Rasmus Widing
c142dbbc54
feat(cli): Add git repository safety check (#328)
* feat(cli): Add git repository safety check

Add validation to ensure CLI workflows only run from within a git
repository. If the user runs from a subdirectory, the CLI resolves
to the repo root. Running from a non-git directory produces a clear
error message with guidance.

- Add git.findRepoRoot() check before workflow commands
- Bypass check for version/help commands
- Add tests for git repo validation behavior

* docs: Update CLI documentation for git repository requirement

* fix(cli): Improve error handling and tests for git repo check

- Move git.findRepoRoot() inside try-catch block to ensure proper error
  handling and database cleanup on unexpected errors
- Add path existence validation before git check for clearer error messages
- Improve tests: test real git.findRepoRoot behavior instead of mocks
- Add tests for path validation and command categorization logic
2026-01-22 10:00:12 +02:00
Rasmus Widing
2c5cb65619
docs: Add CLI user guide and developer guide (#326)
* docs: Add CLI user guide and developer guide

- Add docs/cli-user-guide.md with command reference, flags, and examples
- Add docs/cli-developer-guide.md with architecture and ASCII flow diagrams
- Update README CLI section with proper setup order (install → auth → run)
- Link README to user guide, user guide to developer guide

* docs: Update CLI docs to reflect source-based usage

Binary distribution not yet available. Update all docs to use
`bun run cli` from cloned repo instead of `archon` binary.

* docs: Add bun link for global CLI availability

- Add step to run `bun link` from packages/cli for global `archon` command
- Update all examples to use `archon` instead of `bun run cli`
- Update Windows WSL2 section with bun link step
2026-01-22 09:03:12 +02:00
Rasmus Widing
0e57b2f788 fix: Update all repo URLs from raswonders to dynamous-community 2026-01-22 00:20:27 +02:00
Rasmus Widing
68e7db0466
feat: Phase 5 - CLI binary distribution (#325)
* docs: Add Phase 5 CLI binary distribution plan

- Create detailed implementation plan for binary distribution
- Add Phase 5.0: Bundle defaults for binary (depends on #322)
- Add Phase 5.1-5.7: Build scripts, GitHub Actions, curl install,
  Homebrew formula, Windows docs, version command, release guide
- Update research doc with Phase 6 (auto-update command)
- Renumber dashboard to Phase 7, workflow builder to Phase 8
- Mark Phases 1-4 as complete in research doc

* feat: Phase 5 - CLI binary distribution

Implement standalone binary distribution for Archon CLI:

- Bundle default commands and workflows into binaries at compile time
- Add build scripts for cross-platform compilation (macOS/Linux, ARM64/x64)
- Create GitHub Actions release workflow triggered on version tags
- Add curl install script with checksum verification
- Create Homebrew formula for macOS/Linux installation
- Update version command to show platform, build type, and database info
- Add developer release guide documentation
- Update README with CLI installation instructions

Binary compilation uses Bun's --compile flag to create standalone
executables that include the Bun runtime and all dependencies.
Default workflows and commands are imported as text at compile time
and embedded directly into the binary.

* fix: Pin Dockerfile to Bun 1.3.4 to match lockfile version

The Docker build was failing because oven/bun:1-slim resolved to 1.3.6
while the lockfile was created with 1.3.4, causing --frozen-lockfile to fail.

* docs: Clarify binary vs source builds for default commands/workflows

* fix: Address PR review issues for CLI binary distribution

Security fixes:
- install.sh: Require SKIP_CHECKSUM=true to bypass checksum verification
  instead of silently skipping (addresses security vulnerability)
- install.sh: Show actual error output when version check fails instead
  of falsely reporting success

Validation improvements:
- checksums.sh: Validate all 4 expected binaries exist before generating
  checksums to prevent releasing incomplete builds
- build-binaries.sh: Verify binary exists and has reasonable size (>1MB)
  after each build step
- update-homebrew.sh: Validate extracted checksums are non-empty and
  look like valid SHA256 hashes (64 hex chars)
- update-homebrew.sh: Fix sed patterns to use URL context for updating
  checksums on subsequent runs

Bug fixes:
- homebrew/archon.rb: Fix test to expect exit code 0 (success) instead
  of 1 for `archon version`
- loader.ts: Log error when bundled workflow fails to parse (indicates
  build-time corruption)

Test coverage:
- Add bundled-defaults.test.ts for isBinaryBuild() and content validation
- Add connection.test.ts for getDatabaseType() function
- Add binary build bundled workflow tests to loader.test.ts
- Add binary build bundled command tests to executor.test.ts

All 959 tests pass.
2026-01-21 23:51:51 +02:00
Rasmus Widing
090e5fd812
feat: Runtime loading of default commands/workflows (#324)
* feat: Runtime loading of default commands/workflows

Instead of copying default commands and workflows to target repos on
clone, load them at runtime from the app's bundled defaults directory.

Changes:
- Fix getAppArchonBasePath() to resolve to repo root (not packages/core)
- Add loadDefaultCommands and loadDefaultWorkflows config options
- Update workflow loader to search app defaults then repo (repo wins)
- Update command executor to search app defaults after repo paths
- Remove copyDefaultsToRepo() calls from /clone and GitHub adapter
- Fix lint-staged to not warn on ignored test files

Benefits:
- Defaults always up-to-date (no sync issues)
- Clean repos (no 24+ files copied per clone)
- User's local clone stays in sync with what Archon uses

Closes #322

* docs: Update documentation for runtime loading of defaults

- Update CLAUDE.md to explain runtime loading behavior
- Fix README.md example output and note about defaults
- Update docs/configuration.md with new config options
- Mark copyDefaults as deprecated in favor of loadDefaultCommands/loadDefaultWorkflows

* fix: Address PR review findings for runtime loading

- Fix silent error swallowing in loadConfig catch blocks (loader.ts, executor.ts)
  - Now logs warning with context before falling back to defaults
  - Users will know when their config has syntax errors

- Fix config merging bug in mergeRepoConfig
  - Now includes loadDefaultCommands and loadDefaultWorkflows in merge
  - Repo config opt-out now works correctly

- Add consistent empty file handling for app defaults
  - Returns explicit empty_file error instead of falling through

- Add debug logging for ENOENT cases
  - Helps troubleshoot when app defaults aren't found

- Add startup validation for app defaults paths
  - validateAppDefaultsPaths() checks and logs verification status
  - Called during server startup after logArchonPaths()

- Add comprehensive tests for app defaults command loading
  - Test loading from app defaults when not in repo
  - Test repo commands override app defaults
  - Test loadDefaultCommands: false opt-out
  - Test empty file handling
  - Test graceful handling of missing paths
  - Test config error fallback behavior

* fix: Use namespace imports for archonPaths to fix test mocking in CI

The loader.ts used destructured imports for getDefaultWorkflowsPath and
getWorkflowFolderSearchPaths, but the tests use spyOn which only works
with namespace imports (import * as). This caused the mocks to not work
in CI where tests run in parallel, causing 48 test failures.

* fix: Restore spyOn approach with namespace imports for loader tests

The key fix is that loader.ts uses namespace imports (import * as archonPaths)
which shares the same module instance with the test file. This allows spyOn
to work correctly without using mock.module() which pollutes other tests.

* fix: Use loadDefaultWorkflows: false to avoid app defaults in tests

Instead of mocking archon-paths (which pollutes other tests), we:
1. Only mock config-loader with loadDefaultWorkflows: false by default
2. This prevents app defaults from being loaded during tests
3. For multi-source loading tests, enable loadDefaultWorkflows: true
   and use spyOn to set the path to a temp directory

* fix: Use namespace imports and spyOn for all loader dependencies

Key changes:
1. loader.ts now uses namespace imports for both archonPaths and configLoader
2. loader.test.ts uses spyOn instead of mock.module
3. This avoids polluting other test files (archon-paths.test.ts, config-loader.test.ts)

The spyOn approach works because:
- Both loader.ts and loader.test.ts import the modules as namespaces
- They share the same module instance in Bun's module cache
- spyOn modifies the shared namespace object

* fix: Use namespace imports in executor.ts for test mocking

Change executor.ts to use namespace imports for archon-paths and
config-loader, matching the fix already applied to loader.ts.

The previous fix commits (491fa94, c3a68dd) only updated loader.ts
but missed executor.ts, which has the same pattern of tests using
spyOn() that requires namespace imports to work correctly.

Changes:
- import * as archonPaths from '../utils/archon-paths'
- import * as configLoader from '../config/config-loader'
- Update all usage sites to use namespace prefix

* refactor: Prefix app defaults with archon-* and simplify override logic

Changes:
- Rename all default workflow files to archon-*.yaml
- Rename all default command files to archon-*.md
- Update workflow name: fields to match filenames
- Update command references in workflows to use archon-* names
- Simplify loader.ts to use exact filename match for overrides (not workflow name)
- Remove path mocking from tests - use real app defaults instead
- Simplify tests to be more reliable in CI

Benefits:
- No accidental collisions with user workflows/commands
- Clear intent when users override (must use exact filename)
- Simpler deduplication logic (filename-based)
- More reliable tests (no spyOn issues in CI parallel execution)

* feat: Add deprecation warning for old defaults and update docs

- Add warning in loader.ts when old non-prefixed defaults found in repo
- Update CLAUDE.md with migration instructions for old repos
- Document the archon-* prefix naming convention
- Document exact filename match override behavior

* docs: Move migration docs to docs/migration-guide.md

- Revert CLAUDE.md changes (keep it focused on development)
- Create dedicated migration guide for version upgrades
- Document runtime loading defaults migration steps
- Add commands for full fresh start cleanup

* docs: Add getting started section after cleanup

* docs: Fix stale references to command loading behavior

- Update CLAUDE.md to say 'auto-detected' instead of 'loaded via /clone (auto)'
- Clarify in architecture.md that defaults are loaded at runtime, not copied
- Update GitHub webhook flow to say 'detect and register' instead of 'load commands'

* refactor: Use early return in validateAppDefaultsPaths for cleaner flow

* fix: Improve error handling for silent failure cases

- Add ENOENT check to empty catch block in loader.ts (critical)
- Distinguish between 'not found' and other errors in validateAppDefaultsPaths
- Add errorType to config load fallback logging in loader.ts and executor.ts
2026-01-21 23:08:23 +02:00
Rasmus Widing
7fc0e2e837 docs: Add guide for adding webhooks to additional GitHub repos 2026-01-21 14:23:53 +02:00
Rasmus Widing
3b6b7ab69f
feat: Phase 4 - Express to Hono migration (#318)
* feat: Phase 4 - Express to Hono migration

Replace Express with Hono in @archon/server for improved performance
and better Bun integration. This is a focused HTTP layer migration
that preserves all existing API functionality.

Changes:
- Replace express with hono dependency
- Migrate all endpoints to Hono context-based handlers
- Use Bun.serve() for native Bun server integration
- Update optional parameter syntax from Express 5 to Hono style
- Remove express.json()/express.raw() middleware (Hono handles natively)
- Change default port from 3000 to 3090
- Update log prefixes from [Express] to [Hono]
- Update CLAUDE.md documentation references

All endpoints verified working:
- GET /health, /health/db, /health/concurrency
- POST /test/message, GET /test/messages/:id
- DELETE /test/messages/:id?, PUT /test/mode
- POST /webhooks/github (signature verification)

* refactor: Simplify Hono endpoint handlers

- Remove unnecessary try/catch from /health/concurrency endpoint
  (getStats() is a simple sync operation that doesn't need error handling)
- Remove outer try/catch from /test/message endpoint
  (validation returns early, processing is fire-and-forget with its own error handler)
- Consolidate validation checks with clearer error messages
- Reduce nesting depth for improved readability

Total: 12 lines removed while maintaining identical functionality

* docs: Update port references from 3000 to 3090 after Hono migration

* fix: Improve error handling in Hono endpoints

- Add global app.onError() handler for consistent unhandled exception responses
- Add explicit JSON parsing error handling to /test/message endpoint (returns 400 instead of 500)
- Add explicit JSON parsing error handling to /test/mode endpoint (was completely unhandled)
- Fix CLAUDE.md worktree port example to use correct port (3637 with base 3090)
2026-01-21 13:23:34 +02:00
Rasmus Widing
a28e695aee
feat: Phase 3 - Database abstraction layer and CLI isolation (#314)
* feat: Phase 3 - Database abstraction layer and CLI isolation

Part A: Database Abstraction Layer
- Add IDatabase interface supporting PostgreSQL and SQLite
- Create PostgresAdapter wrapping pg Pool with same interface
- Create SqliteAdapter using bun:sqlite with auto-schema init
- Add SqlDialect helpers for database-specific SQL generation
- Update connection.ts with auto-detection (DATABASE_URL → Postgres, else SQLite)
- Update isolation-environments.ts to use dialect helpers
- CLI now works without DATABASE_URL (uses ~/.archon/archon.db)

Part B: CLI Isolation Integration
- Add --branch/-b flag to create/reuse worktrees for workflows
- Add --no-worktree flag to run on branch directly without isolation
- Add isolation list command to show all active worktrees
- Add isolation cleanup command to remove stale environments
- Auto-register codebase when using --branch from git repo

New git utilities:
- findRepoRoot: Find git repository root from any path
- getRemoteUrl: Get origin remote URL
- checkout: Checkout branch (creating if needed)

* docs: Update documentation for Phase 3 - SQLite support and CLI isolation

* fix: Address all PR review issues for database abstraction

Critical fixes:
- Use dialect helpers (now(), jsonMerge, jsonArrayContains) in all DB operations
- Replace hardcoded PostgreSQL NOW(), ::jsonb, and JSON operators
- Add rowCount validation to updateStatus() and updateMetadata()
- Improve PostgreSQL pool error logging with structured context

Important fixes:
- Add explicit null check in getDialect() instead of non-null assertion
- Add warning for unsupported UPDATE/DELETE RETURNING in SQLite
- Throw error in extractTableName() on parse failure instead of empty string
- Track codebaseLookupError to provide clearer errors when --branch fails
- Couple IDatabase with SqlDialect via readonly sql property

Code simplifications:
- Extract loadWorkflows() helper to DRY duplicate error handling
- Fix N+1 query in getCodebases() by including repository_url in JOIN
- Cache sql.toUpperCase() to avoid redundant calls

All changes verified with:
- Type-check passes
- All 1082 tests pass
- CLI commands tested with both SQLite and PostgreSQL

* docs: Add SQLite support to getting-started, configuration, and architecture guides

* refactor: Simplify Phase 3 code for clarity and maintainability

- sqlite.ts: Remove unused UPDATE branch from extractTableName, consolidate
  RETURNING clause handling into single condition
- isolation.ts: Extract CodebaseInfo interface to reduce type duplication
- workflow.ts: Extract actualBranchName variable for clearer intent
- isolation-environments.ts: Rename variables for semantic clarity
  (staleActivityThreshold/staleCreationThreshold vs nowMinusDays1/2)

* fix: Address all remaining PR review issues

- SQLite: Throw error for UPDATE/DELETE RETURNING instead of warning
- SQLite: Replace deprecated db.exec() with db.run()
- Worktree: Throw for fatal errors (permission denied, not a git repo)
- Types: Add import type for type-only imports in 4 db modules
- Codebases: Add null check validation to createCodebase return
- WorkflowRunOptions: Add JSDoc documenting constraint behavior
- QueryResult: Add comment noting fields should be treated as readonly
- Connection: Improve getDialect() error message with actionable details

* fix: Complete type safety improvements for Phase 3

- QueryResult: Make rows and rowCount readonly to prevent mutation
- WorkflowRunOptions: Use discriminated union to prevent invalid states
  (noWorktree can only be set when branchName is provided)
- Update all database functions to return readonly arrays
- Fix CLI call site to properly construct options object

* fix: Add getDialect mock to database tests

Tests were failing because they expected hardcoded PostgreSQL SQL
(NOW(), metadata || $1::jsonb) but the code now uses dialect helpers.

- Add mockPostgresDialect to test/mocks/database.ts
- Update all db test files to mock getDialect() returning PostgreSQL dialect
- Tests now properly verify the SQL generated by dialect helpers
2026-01-21 10:38:57 +02:00
Rasmus Widing
cf06128e14
feat: Add workflow status visibility (#233) (#256)
* Investigate issue #233: Workflow state management visibility

* feat: Add workflow status visibility to /status and /workflow status (#233)

Users had no visibility into running workflows - they could only see "already running"
errors when attempting to start new workflows. This made it impossible to know what
was running, how long it had been active, or whether it was stuck.

Changes:
- Add workflow info to /status command (name, step, duration, activity)
- Add /workflow status subcommand for detailed workflow state
- Show staleness warnings (>5 min) and stale indicators (>15 min)
- Update help text to document new command

Fixes #233

* Archive investigation for issue #233

* docs: Add /workflow status command to documentation

* refactor: Improve workflow status error handling and code quality

- Extract calculateWorkflowTiming() helper to eliminate code duplication
- Add try-catch around workflow DB queries for graceful degradation
- Define WORKFLOW_SLOW_THRESHOLD_MS and WORKFLOW_STALE_THRESHOLD_MS constants
- Handle invalid date data gracefully (shows "timing unavailable")
- Prevent negative durations with Math.max(0, ...)
- Remove unnecessary String() wrappers in template literals
- Add tests for database error handling and invalid date scenarios
- Add test for /workflow help text including status subcommand
2026-01-19 16:06:58 +02:00
Rasmus Widing
f25994248d
fix: Add Codex sandbox/network settings and progress logging (#290)
* fix: Add Codex sandbox/network settings and progress logging (#288)

The Codex provider was missing critical configuration options, causing it to:
- Run in read-only sandbox mode (couldn't write files)
- Have no network access (couldn't run gh commands)
- Show no progress during execution (appeared to hang)

This commit adds:
- sandboxMode: 'workspace-write' to allow file operations
- networkAccessEnabled: true to allow network calls (gh, curl)
- approvalPolicy: 'never' to auto-approve operations (like Claude's bypassPermissions)
- Progress logging for item.started and item.completed events

Applied to all three thread creation points:
- resumeThread (line 50-56)
- fallback startThread in catch block (line 63-69)
- new startThread (line 74-80)

Fixes #288

* fix: Address PR review feedback for Codex sandbox/network settings

- Remove stale README warning about Codex read-only mode (issue #288 is now fixed)
- Extract thread options to shared helper function (DRY violation fix)
- Add user notification when session resume fails (no longer silent fallback)
- Consolidate item.completed logging with context (command details included)
- Improve comments to be self-contained (remove unverified default claims)
- Strengthen test assertions for fallback path and progress logging
2026-01-19 14:56:07 +02:00
Rasmus Widing
d98d329d59 docs: Add Codex read-only limitation warning
Codex currently runs in read-only sandbox mode due to missing
sandboxMode and networkAccessEnabled settings in the client.

Until #288 is fixed, Codex can only analyze code but cannot
write files or make network calls.

References #288
2026-01-19 14:08:17 +02:00
Rasmus Widing
2a76165305
Fix stale workspace: sync before worktree creation (#287)
* Investigate issue #285: stale workspace causes outdated worktrees

Analyzed root cause and created implementation plan for fixing the
workspace sync issue where new worktrees are created from outdated code
after PRs are merged.

* Fix stale workspace: sync before worktree creation

When a PR is merged, subsequent worktrees were created from outdated
code because the workspace was never synced after the initial clone.

Changes:
- Add syncWorkspace() and getDefaultBranch() helpers in git.ts
- Call syncWorkspaceBeforeCreate() in WorktreeProvider before creating
  new worktrees
- Make sync non-fatal to handle offline/permission edge cases gracefully

The sync happens at the natural boundary of starting new work, ensuring
new issues/PRs always start from the latest code without disrupting
existing in-progress worktrees.

Fixes #285

* Address PR review feedback: data safety and test coverage

- Add uncommitted changes check in syncWorkspace() before git reset --hard
  to prevent accidental data loss (returns false if changes detected)
- Add logging to getDefaultBranch() fallback paths for better debugging
  when symbolic-ref fails and fallback to main/master is used
- Add integration tests verifying sync is called during worktree creation
- Add tests for sync failure scenarios (non-fatal behavior)
- Add test for checkout failure in syncWorkspace()
- Update worktree.ts to handle new boolean return from syncWorkspace()

* simplify: flatten getDefaultBranch fallback logic

Remove verbose logging in getDefaultBranch function. The fallback from
symbolic-ref to checking origin/main to defaulting to master is expected
behavior that doesn't need logging at the info level. Flatten nested
try-catch into sequential blocks for better readability.

* docs: document workspace sync behavior before worktree creation

* Address PR review feedback: error handling and test coverage

- Add logging to empty catch blocks in getDefaultBranch() (critical)
- Add operation context to syncWorkspace() error messages
- Differentiate error severity in syncWorkspaceBeforeCreate():
  - Permission errors and corruption logged at ERROR level
  - Network/timeout errors logged at WARN level
- Update syncWorkspace JSDoc with reset --hard warning
- Remove redundant inline comment before sync call
- Add tests for:
  - Non-standard branch names (develop, trunk)
  - Timeout parameter verification
  - Operation context in error messages
  - Sync skipped when adopting existing worktree
2026-01-19 13:07:56 +02:00
Rasmus Widing
3aff6e3309
feat: Config-based provider selection for workflows (#283)
* feat: Use config-based provider selection for workflows

- Workflow executor now uses config.assistant as fallback instead of
  hardcoded 'claude' when workflow doesn't specify provider
- Remove provider: claude from all default workflow files so they
  inherit from config
- Add assistant: codex to repo config for testing
- Add implementation plan for model validation feature (#281)

This allows users to switch default provider via config without
modifying workflow files. Workflows can still override by specifying
provider explicitly.

* feat: Add logging for resolved provider and model at workflow execution

Log which provider and model is being used at:
- Each workflow step execution
- Each loop workflow iteration

This helps debug config-based provider selection and verify the
correct provider/model combination is being used.

Related to #281

* docs: Document config-based workflow provider inheritance

* refactor: Hoist config loading outside of loops in workflow executor

- Load config once at workflow start instead of on each step/iteration
- Pass resolvedProvider and resolvedModel as parameters to internal functions
- Remove now-unused workflow parameter from executeStepInternal and executeParallelBlock
- Eliminates redundant filesystem reads during workflow execution

* fix: Add provider source tracking and enhanced error context

- Add source tracking to provider log messages (shows "from workflow
  definition" vs "from config") for easier debugging
- Wrap getAssistantClient calls with try-catch that provides actionable
  error messages pointing users to check their workflow YAML or
  .archon/config.yaml assistant setting

Addresses review feedback from PR #283
2026-01-19 11:08:02 +02:00
Rasmus Widing
62a06a834d
Fix: Show repo identifier instead of server filesystem path (#152) (#175)
* Investigate issue #152: GitHub UX - Show repo identifier instead of filesystem path

* Fix: Show repo identifier instead of server filesystem path (#152)

Commands were exposing server's internal filesystem paths (e.g.,
/Users/rasmus/.archon/workspaces/owner/repo) to users, which is a security
concern and provides no value. Users need to know what repo and branch they're
working in, not the server's internal directory structure.

Changes:
- Added formatRepoContext() helper to show "owner/repo @ branch" format
- Updated /status to display "Repository: owner/repo @ branch (worktree)"
- Updated /getcwd to show repo context instead of filesystem path
- Updated /setcwd response to show repo context with fallback to path
- Updated /clone response to remove "Path:" line entirely
- Updated tests to match new output format

Fixes #152

* Archive investigation for issue #152

* Simplify formatRepoContext by extracting getCurrentBranch helper

- Extract git branch lookup into standalone getCurrentBranch() function
- Remove mutable variables (branchName, isWorktree)
- Simplify control flow with early returns
- Reduce JSDoc verbosity (function signature is self-documenting)
- Comment now explains WHY git failures fallback to 'main'

All 84 tests pass. No functional changes.

* docs: Update command output examples to show repo identifier instead of filesystem paths

* Address PR review feedback: improve error handling and simplify code

- Fix duplicate "Repository:" label in /status - now shows "URL:" for repo URL
- Add error logging to getCurrentBranch() when git fails
- Handle detached HEAD state explicitly (shows "detached HEAD" not "HEAD")
- Add try-catch around DB call in formatRepoContext() with logging
- Remove unnecessary isolationDb parameter (uses already-imported module)
- Fix /setcwd fallback to show folder name only, not full filesystem path
- Update tests to match new output format

* Add warning log for orphaned isolation envs and improve test coverage

- Add console.warn() when isolation_env_id exists but DB record not found
- Document no-throw guarantees in getCurrentBranch() and formatRepoContext()
- Add tests for worktree branch lookup and orphaned isolation env fallback
2026-01-18 14:29:20 +02:00
Rasmus Widing
8c27f7759a docs: Update prerequisites to list Bun instead of Node.js
Fixes #247
2026-01-17 22:25:28 +02:00
DIY Smart Code
e1b4db97f3
fix: Auto-detect Claude auth when CLAUDE_USE_GLOBAL_AUTH not set (#236)
* fix: Auto-detect Claude auth when CLAUDE_USE_GLOBAL_AUTH not set

Previously, if CLAUDE_USE_GLOBAL_AUTH was not explicitly set, the code
defaulted to filtering out auth tokens. This broke backwards compatibility
for users who had explicit tokens in their .env files.

New behavior:
- CLAUDE_USE_GLOBAL_AUTH=true: Filter tokens, use global auth
- CLAUDE_USE_GLOBAL_AUTH=false: Use explicit tokens from env
- Not set: Auto-detect - if tokens exist in env, use them

This ensures existing deployments with tokens in .env continue to work
without requiring configuration changes.

* docs: Document auto-detect behavior for Claude authentication

Updated documentation to reflect the new three-way authentication behavior:
- CLAUDE_USE_GLOBAL_AUTH=true: Use global auth from claude /login
- CLAUDE_USE_GLOBAL_AUTH=false: Use explicit tokens from env
- Not set: Auto-detect (use tokens if present, otherwise global auth)

This ensures users understand the backwards-compatible auto-detect feature
that prevents breaking existing deployments with explicit tokens.

* fix: Add comprehensive logging for Claude auth detection

- Log confirmation for explicit CLAUDE_USE_GLOBAL_AUTH=true/false settings
- Log when auto-detect falls back to global auth (no tokens found)
- Warn about empty string token values (common misconfiguration)
- Warn about unrecognized boolean values (e.g., 'yes', '1')

This makes debugging auth issues straightforward by logging every path.

---------

Co-authored-by: Rasmus Widing <rasmus.widing@gmail.com>
2026-01-17 21:46:01 +02:00
Rasmus Widing
1d6768d184 docs: Add missing bun install to setup guide 2026-01-17 21:03:40 +02:00
DIY Smart Code
e6217ec561
Update README.md 2026-01-17 12:33:35 +01:00
Rasmus Widing
3d6c460589
feat: Auto-copy default commands/workflows on clone (#243)
* feat: Auto-copy default commands/workflows on clone

Automatically copy bundled default commands and workflows to newly cloned
repositories. The defaults are stored in `.archon/commands/defaults/` and
`.archon/workflows/defaults/` within the app repository.

These defaults serve dual purpose:
1. They're loaded and usable by this repo itself (recursive loading)
2. They get copied to target repos on `/clone` (flat, not nested)

Key changes:
- Move existing commands/workflows to defaults/ subdirectories
- Add getDefaultCommandsPath/getDefaultWorkflowsPath to archon-paths.ts
- Add defaults.copyDefaults config option (opt-out via config.yaml)
- Create defaults-copy.ts utility for copying files
- Update /clone handler to copy defaults before loading commands
- Update GitHub adapter to copy defaults for new codebases
- Add unit tests for defaults-copy.ts

To opt out: Set `defaults.copyDefaults: false` in target's .archon/config.yaml

Closes #241

* docs: Update documentation for default commands feature

* refactor: Simplify defaults-copy.ts by extracting common copy logic

- Extract duplicated code from copyDefaultCommands and copyDefaultWorkflows
  into a single generic copyFiles helper function
- Add directoryExists helper to replace try/catch for access checks
- Define CopyFilesOptions interface for cleaner parameter passing
- Reduce code from 156 to 137 lines while preserving all functionality

* fix: Improve error handling and test coverage for defaults copy

- Add commandsFailed/workflowsFailed to CopyDefaultsResult interface
- Make copyDefaultsToRepo non-fatal in both command-handler and github adapter
- Surface partial failures to users (warning messages)
- Handle mkdir and readdir errors gracefully
- Use specific ENOENT check instead of catching all errors
- Fix template literal number warnings with String()
- Add tests for mkdir failure, combined copy, and empty directory case

* style: Fix ESLint quote errors in defaults-copy.ts
2026-01-16 01:06:20 +02:00
Rasmus Widing
825a41fcb6
docs: Update README with accurate command reference and new features (#242)
- Reorganize Available Commands into logical categories matching /help output
- Add missing commands: /repo, /repo-remove, /reset-context, /init
- Add complete Worktree commands section (/worktree create/list/remove/cleanup/orphans)
- Add Workflow commands section (/workflow list/reload/cancel)
- Add Global Templates commands (/templates, /template-add, /template-delete)
- Add Workflows documentation in Advanced Configuration
- Update architecture diagram to show Workflow Executor
- Update database schema to include workflow_runs table (6 tables total)
- Update Key Design Patterns to mention workflow engine and worktree isolation
- Update example workflow to be accurate (no commands auto-loaded unless repo has them)
- Change example paths from .claude/commands to .archon/commands (primary location)
- Add note explaining commands are only auto-loaded if repo has .archon/commands/
2026-01-16 00:42:45 +02:00
Rasmus Widing
6558654d57
fix: Add CLAUDE_USE_GLOBAL_AUTH for SDK built-in authentication (#228)
* fix: Remove Claude credentials from .env.example

Claude Code uses global auth from `claude /login`, not project .env
files. Having tokens in .env.example caused Bun to auto-load them
in worktrees, overriding valid user credentials and causing auth failures.

- Comment out CLAUDE_CODE_OAUTH_TOKEN placeholder
- Comment out CLAUDE_API_KEY placeholder
- Add note explaining why these should not be set

* fix: Add CLAUDE_USE_GLOBAL_AUTH for SDK built-in authentication

Bun auto-loads .env files from the working directory, which caused
issues when worktrees contained CLAUDE_CODE_OAUTH_TOKEN - the invalid
token would override the user's valid global auth from `claude /login`.

Changes:
- Add CLAUDE_USE_GLOBAL_AUTH=true option to bypass credential check
- Update .env.example to use global auth by default (recommended)
- Remove explicit Claude tokens from .env.example template

This allows the Claude Code SDK to use its built-in OAuth authentication
instead of requiring explicit tokens in environment variables.

For Docker/VPS deployments, users can still set CLAUDE_CODE_OAUTH_TOKEN
or ANTHROPIC_API_KEY explicitly via environment variables at runtime.

Related: #227

* chore: Upgrade Claude Agent SDK to 0.2.7

Fixes hanging issue when running Claude Code in worktrees with
settingSources: ["project"]. The previous version (0.1.57/0.1.69)
would hang indefinitely when loading project settings.

* docs: Add CLAUDE_USE_GLOBAL_AUTH to documentation

Update CLAUDE.md and README.md to document the new recommended
authentication method using global auth from `claude /login`.

- CLAUDE.md: Updated Environment Variables section
- README.md: Restructured Claude Code section with 3 options

This addresses the documentation gaps identified in PR review.
2026-01-14 13:55:53 +02:00
Rasmus Widing
e2b53e7a65
feat: Add Ralph-style autonomous iteration loops to workflow engine (#168)
* Fix outdated command loading documentation

* feat: Add Ralph-style autonomous iteration loops to workflow engine

Enable workflows to iterate autonomously until a completion signal is
detected (e.g., `<promise>COMPLETE</promise>`) or max iterations reached.

Changes:
- Add LoopConfig type with until signal, max_iterations, fresh_context
- Extend WorkflowDefinition to support loop + prompt (mutually exclusive with steps)
- Add executeLoopWorkflow function with completion signal detection
- Update loader to parse and validate loop configuration
- Add ralph.yaml example workflow demonstrating PRD implementation pattern
- Add 22 new tests covering loop execution and parsing

Loop workflows allow developers to run long-running tasks (like PRD
implementation) without manual phase transitions, following the pattern
popularized by Geoffrey Huntley.

* Add test-loop workflow for Ralph loop testing

* feat: Update worktree config to copy .archon files

- Include all .archon files in worktree copy (not just .archon/ralph)
- Update ralph.yaml with dynamic path detection for feature directories
- Add PR creation step at completion
- Use {prd-dir} variable for flexible path handling

* feat: Add ralph-prd command for generating PRD files

Creates structured PRD files for Ralph autonomous loops:
- Outputs to .archon/ralph/{feature-slug}/ directory
- Generates prd.md (full context) and prd.json (story tracking)
- Feature-based naming to avoid conflicts between projects
- Guides user through requirements gathering phases

* feat: Add ralph-fresh workflow with fresh_context: true

Fresh context mode for Ralph loops where each iteration:
- Starts with a clean slate (no memory of previous iterations)
- Re-reads progress.txt, prd.json, prd.md to understand current state
- Relies on progress.txt "Codebase Patterns" section for learnings
- Better for long loops and avoiding context confusion

* refactor: Rename ralph workflows with explicit descriptions

- Rename ralph.yaml → ralph-stateful.yaml (persistent memory mode)
- Update ralph-fresh.yaml description for clarity
- Both workflows now require explicit invocation
- Clear INVOKE WITH / NOT FOR / HOW IT WORKS / TRADE-OFFS sections
- Neither is "default" - user must choose explicitly

* chore: Set max_iterations to 10 on ralph workflows

* fix: Address PR review feedback for loop workflow

- Wrap database metadata update in try-catch to prevent misleading errors
- Add dropped message tracking and user warning in loop workflow
- Make plain signal detection more restrictive (end of output or own line)
- Add context (line number, preview) to YAML parse errors
- Make max iterations error message actionable with suggestions
- Remove unnecessary type assertions after discriminated union refactor

* chore: Remove unrelated plan files from branch
2026-01-12 11:13:21 +02:00
Rasmus Widing
74591012e9
Fix: Copy git-ignored files to worktrees (#100) (#145)
* Fix: Copy git-ignored files to worktrees (#100)

Worktrees created via the orchestrator now copy git-ignored files (like
.env) based on configuration in .archon/config.yaml. This addresses the
issue where applications fail when running in worktrees due to missing
environment configuration.

Changes:
- Add copyFiles option to RepoConfig.worktree in config-types.ts
- Create worktree-copy.ts utility for parsing config and copying files
- Integrate file copying into WorktreeProvider.createWorktree()
- Add comprehensive tests for new functionality

Configuration example:
```yaml
worktree:
  copyFiles:
    - .env.example -> .env    # Copy and rename
    - .env                     # Copy as-is if exists
    - data/fixtures/           # Copy entire directory
```

Fixes #100

* Archive investigation for issue #100

* Fix: Add path traversal protection and improve error handling

- Add isPathWithinRoot() to block path traversal attacks (works on Unix/Windows)
- Add input validation to parseCopyFileEntry() for empty/invalid entries
- Improve error logging with structured data and error codes
- Separate config loading errors from file copy errors
- Use console.error for unexpected errors, console.log for expected skips
- Add 34 new tests for security, validation, and error handling
- 100% test coverage for worktree-copy.ts

* Add worktree copyFiles config for .env files

* Update bot mention from @remote-agent to @Archon

- Update default botMention in GitHubAdapter to 'Archon'
- Update all docs to use @Archon consistently
- Update test cases to use @Archon variations
- The default botName in config is 'Archon', so this aligns the adapter

* Docs: Add worktree app testing instructions to CLAUDE.md
2026-01-06 18:41:37 +02:00
Rasmus Widing
c20c9b3805 Update README for Archon paths and new migrations
- Update workspace references from /workspace to /.archon/workspaces
- Add migrations 006 and 007 to upgrade instructions
- Update database schema section (3 tables → 5 tables)
- Update troubleshooting paths
2025-12-17 22:20:31 +02:00
Rasmus Widing
3026a6445d
Add Archon distribution config and directory structure (#101)
* Add Archon distribution config and directory structure

- Create centralized path resolution in src/utils/archon-paths.ts
- Add YAML configuration system (src/config/) with layered loading
- Update Dockerfile and docker-compose for /.archon/ directory
- Add GHCR publish workflow for multi-arch Docker builds
- Create deploy/ directory with end-user docker-compose
- Add /init command to create .archon structure in repos
- Add docs/configuration.md reference guide
- Update README with Quick Start section
- Add bun run validate script
- Update tests for new path defaults (~/.archon/)

Directory structure:
- Local: ~/.archon/{workspaces,worktrees,config.yaml}
- Docker: /.archon/{workspaces,worktrees}
- Repo: .archon/{commands,workflows,config.yaml}

Legacy WORKSPACE_PATH and WORKTREE_BASE env vars still supported.

* Complete Archon distribution config implementation

- Wire up config system in src/index.ts (Task 3.5)
- Remove legacy WORKSPACE_PATH and WORKTREE_BASE support
- Add logConfig() function to config-loader.ts
- Update docker-compose.yml to use ARCHON_DOCKER env var
- Remove legacy env vars from .env.example
- Update all documentation to reference ARCHON_HOME
- Create scripts/validate-setup.sh for setup validation
- Add setup:check script to package.json
- Create docs/getting-started.md guide
- Create docs/archon-architecture.md technical docs
- Update tests to use ARCHON_HOME instead of legacy vars
- Fix validate.md command template for new paths

All plan phases now complete:
- Phase 1: Archon Directory Structure
- Phase 2: Docker Distribution
- Phase 3: YAML Configuration System
- Phase 4: Developer Experience
- Phase 5: Documentation
2025-12-17 21:45:41 +02:00
Rasmus Widing
c85622fbbb
Migrate from Node.js/npm/Jest to Bun runtime (#85)
* Migrate from Node.js/npm/Jest to Bun runtime

- Replace npm with bun for package management (bun.lock)
- Replace Jest with bun:test for testing
- Update tsconfig for Bun (ESNext module, bundler resolution)
- Update Dockerfile to use oven/bun:1-slim
- Update CI workflow to use oven-sh/setup-bun@v2
- Remove dynamic import hack from codex.ts (direct ESM imports)
- Fix test mocking for Bun (export execFileAsync, use spyOn)
- Update all documentation (CLAUDE.md, README.md, CONTRIBUTING.md)

All 395 tests pass, type-check passes, E2E validated with curl.

* ci: retrigger CI build

* fix: make execFileAsync a function for better Bun mockability

* fix: ensure execFileAsync returns string not Buffer

* fix: rename _execFileAsync to comply with naming convention

* fix: make mkdirAsync mockable for Bun tests

* fix: update engines to bun>=1.0.0 and add mkdirAsync mock

* fix: pin Bun to 1.3.4 in CI to fix mock.module test failures

Newer Bun versions have different mock.module() behavior that causes
cross-test module pollution, resulting in 71 test failures in CI while
tests pass locally. Pinning to 1.3.4 ensures consistent behavior.

* fix: run orchestrator tests last to avoid mock.module pollution

Bun's mock.module() pollutes the global module cache, causing tests to
fail when orchestrator.test.ts (which mocks command-handler and factory)
runs before those modules' own test files.

Fix by running tests in two batches:
1. All tests except orchestrator
2. Orchestrator tests last

This ensures orchestrator's mocks don't affect other test files.
2025-12-16 15:34:58 +02:00
Wirasm
45c7adbf2f
Add Slack platform adapter with Socket Mode support (#73)
- Add SlackAdapter using @slack/bolt with Socket Mode (no HTTP endpoints needed)
- Implement thread handling mirroring Discord pattern (channel:thread_ts conversation IDs)
- Add Slack URL normalization to strip <url> formatting from messages
- Add user whitelist authorization (SLACK_ALLOWED_USER_IDS)
- Support @mention activation in channels and direct DMs
- Add comprehensive setup guide and update README with Slack section
2025-12-05 21:34:42 +02:00
Cole Medin
9c58a2ecdf SQL, documentation, and Docker touch ups 2025-12-05 07:12:12 -06:00
Wirasm
1b6771ea2a
Fix WORKSPACE_PATH configuration to avoid nested repos (#37) (#54)
Updated documentation and configuration to recommend external paths
for WORKSPACE_PATH, preventing repo-inside-repo confusion when
working on this project's issues.

Changes:
- Updated .env.example default to /tmp/remote-agent-workspace
- Added detailed WORKSPACE_PATH guidance to README with warning section
- Updated cloud deployment docs with recommended external path
- Added startup warning when WORKSPACE_PATH is inside project directory

The warning helps developers avoid nested repository issues where
clones end up at paths like:
  /remote-coding-agent/workspace/remote-coding-agent

This caused path confusion, git worktree conflicts, and disk duplication.

Fixes #37

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 20:54:10 +02:00
Rasmus Widing
eda8be2ec2 Update README for new Docker Compose profile system
- Update startup commands to use --profile external-db or --profile with-db
- Add Option C for local development without Docker
- Update troubleshooting section with profile-aware commands
- Document app vs app-with-db service names
2025-11-28 10:26:29 +02:00
Cole Medin
b878bfba54 Adding git clone command to README 2025-11-15 08:36:33 -06:00
Cole Medin
923bae3258 Cloud Deployment Guide 2025-11-12 09:51:46 -06:00
Cole Medin
05a564a74b README Overhaul 2025-11-12 09:10:34 -06:00
Cole Medin
ca74774cac Codex Implementation 2025-11-11 23:06:29 -06:00
Cole Medin
7afa1bbb23 GitHub Adapter Implementation 2025-11-11 12:38:20 -06:00
Cole Medin
41415d7e7f feat: implement telegram + claude mvp with generic architecture
- Add generic IPlatformAdapter and IAssistantClient interfaces for extensibility
- Implement TelegramAdapter with streaming/batch modes
- Implement ClaudeClient with session persistence and resume capability
- Create TestAdapter for autonomous validation via HTTP endpoints
- Add PostgreSQL database with 3-table schema (conversations, codebases, sessions)
- Implement slash command system (/clone, /status, /getcwd, /setcwd, /reset, /help)
- Add Docker containerization with docker-compose (with-db profile for local PostgreSQL)
- Fix Claude Agent SDK spawn error (install bash, pass PATH environment variable)
- Fix workspace volume mount to use /workspace in container
- Add comprehensive documentation and health check endpoints

Architecture highlights:
- Platform-agnostic design allows adding Slack, GitHub, etc. via IPlatformAdapter
- AI-agnostic design allows adding Codex, etc. via IAssistantClient
- Orchestrator uses dependency injection with interface types
- Session persistence survives container restarts
- Working directory + codebase context determine Claude behavior

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 19:35:50 -06:00