Skip to content

update#1

Merged
GoetschiM merged 1140 commits into
GoetschiM:mainfrom
spacedriveapp:main
Apr 28, 2026
Merged

update#1
GoetschiM merged 1140 commits into
GoetschiM:mainfrom
spacedriveapp:main

Conversation

@GoetschiM
Copy link
Copy Markdown
Owner

No description provided.

tomasmach and others added 30 commits March 19, 2026 18:48
Top-level /orchestrate route showing active OpenCode workers across all
agents as horizontally scrollable columns, each embedding a live
OpenCode session via Shadow DOM.

Backend: expose project_id, project_name, opencode_session_id, and
directory in the workers list API response (LEFT JOIN against projects
table, no new migrations needed — columns already exist).

Frontend:
- Extract OpenCodeEmbed into shared component with ref-counted portal
  CSS and stable mount lifecycle (no remount on directory discovery)
- New Orchestrate page with fan-out data fetching across all agents,
  project/agent grouping toggle, agent filter, live SSE state merge
- Sidebar icon (columns) linking to /orchestrate
- AgentWorkers imports shared OpenCodeEmbed instead of inline copy
…screen

feat: worker orchestration screen
fix: add provider prefix to zai-coding-plan default model
…ings

fix: skill install 500 error and chart dimension warnings
feat: Add Mattermost channel support
- Add "error sending request" to retriable error patterns to handle
  transient network failures (DNS, connection refused, etc.)
- Remove broken keepalive code that tried to clone non-Clone Browser
- Implement graceful browser shutdown in Drop to prevent Chrome core dumps
- Add comprehensive test suite (7 tests) for error classification
- Fix clippy warning about collapsible if statements

Fixes WebSocket connection errors when workers fail due to transient
API errors, preventing Chrome from being force-killed and dumping core.
fix: graceful browser shutdown and network error retries
Sanitize metadata URLs against javascript: scheme injection, guard
merge_json_object against non-object patches to preserve the metadata-
is-always-an-object invariant, align doc wording with deep-merge
semantics, and avoid redundant getGithubReferences computation in the
task detail dialog.
fix: preserve nested task metadata updates
- Include vendor directory in cargoSrc for imap-proto patch to fix builds
- Update frontend node_modules npm deps hash
- Add LD_LIBRARY_PATH for onnxruntime in spacebot-full
- Update flake.lock after rebase
- Add frontend-updater package for easy hash updates
- Add just commands for Nix workflow:
  - just update-frontend-hash: Updates frontend node_modules hash only
  - just update-flake: Updates all flake inputs (nixpkgs, crane, etc.)
- Document Nix workflow in AGENTS.md

Usage after updating interface deps:
  just update-frontend-hash

Usage to update all Nix dependencies:
  just update-flake

Fixes missing vendor directory causing imap-proto build failures and
updates npm dependency hashes for frontend builds.
justfile:
- Replace GNU-specific grep -oP with portable awk/sed
- Replace GNU-specific sed -i '' with POSIX-safe mktemp+mv pattern
- Works on both GNU/Linux and BSD/macOS

nix/default.nix:
- Replace fragile find ... | while read loops with find -exec
- Define replace_imap_proto function to avoid code duplication
- Properly handles paths with spaces/special characters
Change doCheck from false to true so tests actually run.
craneLib.cargoTest is specifically for running tests, so doCheck=false
was skipping all tests entirely, defeating the purpose of having a
test derivation with cargoTestExtraArgs for selective test skipping.
- Use specific version imap-proto-0.10.2 instead of wildcard pattern
- Use ${NIX_BUILD_TOP:-/build} instead of hardcoded /build path
- Makes the replacement safer and more robust
…ectors

- Use `set -euo pipefail` in update-frontend-hash recipe for full strict mode
- Switch bun/rollup/esbuild native package selectors from hostPlatform to
  buildPlatform so build-time binaries match the build machine

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make chromium conditional (Linux-only) in the default dev shell;
  fall back to system Chrome on macOS
- Fix error messages to say "build platform/CPU" instead of "host"
  since the checks inspect stdenv.buildPlatform
- Guard esbuild and rollup native package installs with package.json
  existence checks before reading versions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix imap-proto build issues and update Nix dependencies
- Add signal_http_url and signal_account credential fields
- Add E.164 phone number validation for Signal accounts
- Auto-populate dm_allowed_users with Signal account on instance creation
- Support both default and named Signal adapter instances
- Add unit tests for E.164 validation

Validation ensures phone numbers are in E.164 format (+ followed by 7+ digits)
parse_delivery_target splits at the first colon, so a delivery target
like 'signal:gvoice1:uuid:xxx' was parsed as adapter='signal' instead
of 'signal:gvoice1'. This caused cron jobs to fail with 'no messaging
adapter named signal' even when the named instance was registered.

Fix parse_delivery_target to delegate to parse_signal_target_parts for
Signal targets, which already correctly handles named instance prefixes.

fix(cron): guide LLM to use reply and fix Signal adapter resolution in non-Signal contexts

- Add minimal cron prompt guidance: use reply for primary output, only use
  send_message_to_another_channel for explicit multi-channel delivery
- Fix signal_adapter_available check to query messaging_manager instead of
  current_adapter, so Signal targets are advertised in cron/cross-platform contexts
- Fix named-instance upgrade: when current_adapter is not Signal (e.g. cron),
  look up registered Signal adapters and auto-resolve if exactly one exists

fix(cron): use delivery_target.adapter as source adapter for cron channels

When a cron job fires, set the synthetic InboundMessage's adapter field
to the job's delivery_target.adapter (e.g., signal:gvoice1) instead of None.

This ensures:
- The cron channel correctly identifies as being 'from' that messaging platform
- current_adapter() returns the named instance (e.g., signal:gvoice1)
- reply tool output routes to the correct destination
- send_message_to_another_channel can resolve bare 'signal:' prefixes to
the correct named instance using existing upgrade logic
…h available channels format

Problem:
The LLM was confusing the current Signal group with other groups when creating
cron jobs. The conversation context showed:
  Channel: Group Chat abc123 (signal)
While available channels showed:
  Group Chat abc123 (signal, id: signal:adapter:group:abc123)

This format mismatch caused the LLM to pick the wrong group ID from the
available channels list when asked about "this chat".

Solution:
Update the conversation context template to include the full channel ID in the
same format as available channels:
  Channel: Group Chat abc123 (signal, id: signal:adapter:group:abc123)

Changes:
- prompts/en/fragments/conversation_context.md.j2: Add conversation_id to template
- src/prompts/engine.rs: Add conversation_id parameter to render_conversation_context()
- src/agent/channel.rs: Pass conversation_id when building context
- src/api/channels.rs: Pass channel id when building context

Now the LLM can clearly correlate the current chat with the correct entry in
the available channels list, preventing group ID confusion.
- Add Signal to Platform type and PLATFORM_LABELS
- Add Signal credential form with http_url and account fields
- Add E.164 format validation in frontend
- Add Signal to available platforms list
- Add Signal icon mapping (using generic comment icon)
- Include placeholder documentation link

fix(messaging): resolve Signal adapter validation and consistency issues

Fixes several issues with Signal messaging adapter implementation:

**E.164 Phone Number Validation (issue #5)**
- Move is_valid_e164 to messaging::target module for reuse
- Add proper E.164 validation: first digit must be 1-9 (not 0)
- Enforce maximum 15 digits per E.164 standard
- Update normalize_signal_target to use shared validation
- Add test cases for +01234567 (invalid) and >15 digit numbers

**Validation Response Format (issue #2)**
- Replace StatusCode::BAD_REQUEST with MessagingInstanceActionResponse
- Return user-friendly validation failures for missing signal_http_url
- Return user-friendly validation failures for missing signal_account
- Applied to both default and named instance creation paths

**dm_allowed_users Cleanup (issue #3)**
- Remove old auto-added account from dm_allowed_users when account changes
- Prevent allowlist from growing indefinitely on account updates
- Only the new account remains in the authorized list

**Signal Platform Deletion Support (issue #4)**
- Add 'signal' to delete_messaging_instance supported platforms
- Add Signal-specific credential cleanup in delete handler
- Enables proper deletion of Signal instances via API

**Adapter Name Matching (issue #6)**
- Fix implicit Signal shorthand detection in send_message tool
- Change from starts_with('signal') to exact match or signal: prefix
- Prevents adapters like 'signal-alerts' from triggering Signal shorthand

Note: DOC_LINKS entry for signal docs (issue #1) retained as-is per request

fix(api): add Signal to messaging status endpoint

Add Signal instance detection to messaging_status function:
- Read [messaging.signal] section for default instance
- Read [[messaging.signal.instances]] for named instances
- Push instance status to instances array when configured
- Requires both http_url and account fields to be considered configured

This fixes the issue where Signal instances were not appearing in the web UI.

fix(signal): align validation rules and add toggle_platform support

Frontend validation (ChannelSettingCard.tsx):
- Update E.164 regex to /^\+[1-9]\d{5,13}$/ for true E.164 compliance
- Enforce 7-15 digits total (6-14 after '+'), first digit 1-9
- Update error message and help text to reflect correct range

Backend validation (target.rs):
- Change is_valid_e164 to require 6-14 digits after '+' (7-15 total)
- normalize_signal_target: Reuse is_valid_e164() for bare digit validation
- parse_signal_target_parts: Add empty segment checks to all match arms
  - Reject empty uuid, group_id, phone, instance, or single segments
  - Prevents invalid targets like 'uuid:' or 'signal:work:'

API state (state.rs):
- Add signal_permissions field to ApiState
- Add set_signal_permissions() method for hot-reload support

toggle_platform (messaging.rs):
- Add Signal case to toggle_platform for runtime adapter start/stop
- Support both default and named Signal instances
- Update existing ArcSwap pointee instead of creating new one when permissions exist

send_message_to_another_channel:
- parse_implicit_signal_shorthand: Use is_valid_e164() for strict validation
- Add specific error messages for each validation failure case
- Add early error for ambiguous Signal adapter selection when multiple
  named instances exist without a default, preventing broadcast() failure
- Fix adapter resolution to distinguish default 'signal' from named adapters

Tests (messaging.rs):
- Update E.164 tests for 6-14 digit range (7-15 total)
Introduce the foundation for elevating the task system from per-agent
scope to a single global instance-level database shared across all
agents.

Changes:
- New migration directory (migrations/global/) with the global tasks
  schema featuring globally unique task_number, owner_agent_id and
  assigned_agent_id columns, and ISO 8601 timestamp defaults
- New connect_global_tasks() function in db.rs for connecting to and
  migrating the instance-level tasks.db
- Initialize the global task pool during startup in main.rs alongside
  the existing secrets.redb instance-level store
- Design specification for the full task elevation roadmap
…t model

Replace agent-scoped task storage with a global model where tasks have
owner_agent_id (creator) and assigned_agent_id (executor) instead of a
single agent_id. Task numbers are now globally unique (no composite key).

TaskStore API changes:
- create() takes owner_agent_id + assigned_agent_id instead of agent_id
- list() takes TaskListFilter struct instead of positional agent_id param
- get_by_number() no longer requires agent_id (globally unique numbers)
- update() no longer requires agent_id; gains assigned_agent_id field
- delete() no longer requires agent_id
- claim_next_ready() filters by assigned_agent_id
- list_ready() filters by assigned_agent_id

All 24 consumer call sites updated across tools (task_create, task_list,
task_update, send_agent_message), API handlers, and cortex ready-task
loop. Cortex test fixtures updated to use global schema.

New tests: global_task_numbers_are_unique_across_agents,
list_filters_by_assigned_agent, claim_next_ready_scopes_by_assigned_agent,
reassign_task_via_update
Replace the per-agent task store map and cross-agent task_store_registry
with a single global TaskStore shared across all agents. This eliminates
the fragile cross-database write pattern where SendAgentMessageTool
looked up target agent stores from a registry.

Removed fields:
- AgentDeps.task_store_registry (lib.rs)
- ApiState.task_stores HashMap (api/state.rs)
- ApiState.task_store_registry (api/state.rs)

Added/changed:
- ApiState.task_store: ArcSwap<Option<Arc<TaskStore>>> (single global)
- ApiState.set_task_store() replaces set_task_stores()
- SendAgentMessageTool.task_store replaces task_store_registry
- initialize_agents() takes Arc<TaskStore> instead of registry
- All agents share the same global_task_store via AgentDeps

Cleanup:
- Removed task_store_registry population loop after agent init
- Removed per-agent TaskStore::new(db.sqlite) in agent init
- Removed per-agent task_stores map build for API state
- Simplified API task handlers from per-agent map lookup to single store
- Updated test fixtures (context_dump.rs, bulletin.rs)
jamiepine and others added 29 commits April 12, 2026 19:21
…iability

fix(memory): make cortex synthesis non-blocking
…ion-p2

feat(memory): expand working-memory event semantics
…eaming

feat: Interactive shell streaming with live output
…participant-roles

[codex] Preserve participant roles in knowledge synthesis
…mutex

[codex] Guard dirty knowledge synthesis
@GoetschiM GoetschiM merged commit fc8d019 into GoetschiM:main Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants