* Return boolean from exists method for credential check
* Add test for empty value handling in EnvVarStorage
Add test to verify exists() and load() consistency for empty values in EnvVarStorage.
Problem
- The Zoho CRM tool was refactored to an MCP-based architecture, making the old in-tree test suite obsolete
- The remaining tests under src were not executed by pytest. Testpaths only includes tools/tests, effectively making them dead code
- A proper MCP test suite already exists under tools/tests, providing coverage
Decision
- Removed the unused test directory under src/aden_tools/tools/zoho_crm_tool/tests
- Aligns project structure with existing tools, where tests are only located in tools/tests
- Avoids confusion and prevents future contributors from relying on outdated or non-executed tests
* fix(skills): restore module-level path constants for HIVE_HOME refactor
ae2aa30e replaced module-level USER_SKILLS_DIR / INSTALL_NOTICE_SENTINEL
in installer.py and _NOTICE_SENTINEL_PATH / _TRUSTED_REPOS_PATH in
trust.py with lazy helper functions, but left callers and tests still
referencing the original symbols. CI fails with ImportError /
AttributeError.
Restore them as module-level constants computed from HIVE_HOME so the
desktop-shell override still works, callers in cli.py keep importing
the same names, and existing test monkeypatches stay valid.
Refs #7148
* fix(colony): preserve task text in run_parallel_workers spawn data
run_parallel_workers stamps __template_task_id into spec['data'] before
calling spawn_batch. Once that mutation makes spec['data'] non-empty,
colony_runtime.spawn()'s ``input_data or {"task": task}`` fallback no
longer fires and the task description disappears from the worker's
first user message. Workers loop on empty responses and never emit
SUBAGENT_REPORT.
Hoist the ``setdefault("task")`` step out of the template-publish try
block so task text survives even if the template store fails
non-fatally. Inner loop only stamps __template_task_id.
Refs #7148
Accepts a multipart upload of `tar` / `tar.gz` (any compression
tarfile.open auto-detects) containing a single top-level directory and
unpacks it into HIVE_HOME/colonies/<name>. Lets a desktop client (or any
external tool) hand a colony spec to a remote runtime to run.
Form fields:
file (required) the archive blob
name (optional) override the colony name; defaults to
the archive's top-level dir
replace_existing (optional) "true" to overwrite; else 409 if the
target dir already exists
Safety:
- 50 MB upload cap (multipart reader streams + caps each part)
- Manual path-traversal validation per member (Python 3.11 compatible —
tarfile's safe `filter='data'` only landed in 3.12)
- Symlinks, hardlinks, device, fifo entries all rejected
- Colony name validated against the existing [a-z0-9_]+ pattern used by
routes_colony_workers + queen_lifecycle_tools
- Mode bits masked to 0o755 / 0o644 so a tampered tar can't ship
world-writable scripts
Tests cover happy path, name override, 409 / 201 around replace_existing,
path traversal, absolute paths, symlinks, multiple top-level dirs,
invalid colony name, missing file part, corrupt tar, non-multipart, and
uncompressed tar.
Future work (not in this PR): export endpoint, colony list/delete via
this same prefix, and an MCP tool wrapper so queens can move colonies
between hosts mid-conversation.