Harbor as of 2026-10-05: the coordination hub for the Open Sea's decomp team
Messages, threads, acknowledgements, claims, bands, tasks, review items and stop flags for a team of AI agents; the chat page and board; host hooks and MCP server; autopilot; tools/watch.py. Put under version control after the weekend's changes so they have history and can be rolled back. Local only.
This commit is contained in:
commit
dbfd1720c5
43 files changed
+12440
No files matched your search
@@ -0,0 +1,155 @@
|
||||
"""Installer tests against a fake user home (HARBOR_INSTALL_HOME) - real host configs are never touched."""
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import tomllib
|
||||
import unittest
|
||||
|
||||
import yaml
|
||||
|
||||
from helpers import make_home, temp_dir
|
||||
from harbor import install
|
||||
|
||||
CODEX_CONFIG = '''model = "gpt"
|
||||
notify = ["x.exe", "turn-ended"]
|
||||
|
||||
[features]
|
||||
|
||||
[mcp_servers.node_repl]
|
||||
command = "node"
|
||||
|
||||
[tui.model_availability_nux]
|
||||
seen = true
|
||||
'''
|
||||
DSH_PATCH = '''# Your patch layer
|
||||
- id: ui-chat
|
||||
name: "@deepseek-ai/dsh-client-ui-chat"
|
||||
config:
|
||||
transcriptView: standard
|
||||
- id: tools
|
||||
config:
|
||||
mode: !!js process.env.DSH_TOOLS_MODE
|
||||
'''
|
||||
|
||||
|
||||
class Installer(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.dir = temp_dir()
|
||||
self.home = self.dir / "user"
|
||||
(self.home / ".codex").mkdir(parents=True)
|
||||
(self.home / ".codex" / "config.toml").write_text(CODEX_CONFIG, encoding="utf-8")
|
||||
(self.home / ".codex" / "AGENTS.md").write_text("# My rules\n\nBe brief.\n", encoding="utf-8")
|
||||
(self.home / ".config" / "opencode").mkdir(parents=True)
|
||||
(self.home / ".config" / "opencode" / "opencode.jsonc").write_text('{\n "$schema": "https://opencode.ai/config.json"\n}', encoding="utf-8")
|
||||
(self.home / ".dsh" / "profiles" / "desktop").mkdir(parents=True)
|
||||
(self.home / ".dsh" / "profiles" / "desktop" / "cordis.patch.yml").write_text(DSH_PATCH, encoding="utf-8")
|
||||
self.harbor_home = self.dir / "harbor-home"
|
||||
make_home(self.harbor_home)
|
||||
self.saved = {k: os.environ.get(k) for k in ("HARBOR_INSTALL_HOME", "HARBOR_HOME", "HARBOR_PROJECT", "APPDATA")}
|
||||
os.environ.update(HARBOR_INSTALL_HOME=str(self.home), HARBOR_HOME=str(self.harbor_home),
|
||||
APPDATA=str(self.dir / "appdata"))
|
||||
os.environ.pop("HARBOR_PROJECT", None)
|
||||
self.cwd = os.getcwd()
|
||||
os.chdir(self.dir) # resolve projects from the test folder, not from wherever the suite runs
|
||||
|
||||
def tearDown(self):
|
||||
os.chdir(self.cwd)
|
||||
for k, v in self.saved.items():
|
||||
if v is None:
|
||||
os.environ.pop(k, None)
|
||||
else:
|
||||
os.environ[k] = v
|
||||
shutil.rmtree(self.dir, ignore_errors=True)
|
||||
|
||||
def read(self, *parts):
|
||||
return (self.home.joinpath(*parts)).read_text(encoding="utf-8")
|
||||
|
||||
def test_codex_install_is_idempotent_and_reversible(self):
|
||||
install.install("codex", python="py -3.12")
|
||||
config = tomllib.loads(self.read(".codex", "config.toml"))
|
||||
server = config["mcp_servers"]["harbor"]
|
||||
self.assertEqual(server["env"]["HARBOR_AGENT"], "Codex")
|
||||
self.assertEqual(server["args"][-3:], ["--as", "Codex", "mcp"])
|
||||
self.assertEqual(config["mcp_servers"]["node_repl"]["command"], "node") # untouched
|
||||
self.assertTrue(config["tui"]["model_availability_nux"]["seen"])
|
||||
hooks = json.loads(self.read(".codex", "hooks.json"))["hooks"]
|
||||
self.assertEqual(sorted(hooks), ["PreToolUse", "SessionStart", "Stop", "UserPromptSubmit"])
|
||||
self.assertIn("hook pre-tool --host codex", hooks["PreToolUse"][0]["hooks"][0]["command"])
|
||||
self.assertIn("Be brief.", self.read(".codex", "AGENTS.md"))
|
||||
self.assertIn("you are **Codex**", self.read(".codex", "AGENTS.md"))
|
||||
once = self.read(".codex", "config.toml")
|
||||
report = install.install("codex", python="py -3.12")
|
||||
self.assertEqual(self.read(".codex", "config.toml"), once)
|
||||
self.assertTrue(all(line.startswith("unchanged") for line in report if line.startswith(("unchanged", "update", "create"))))
|
||||
install.install("codex", remove=True)
|
||||
self.assertEqual(self.read(".codex", "config.toml"), CODEX_CONFIG)
|
||||
self.assertEqual(self.read(".codex", "AGENTS.md"), "# My rules\n\nBe brief.\n")
|
||||
self.assertFalse((self.home / ".codex" / "hooks.json").exists())
|
||||
backups = list((self.harbor_home / "backups" / "integrations").rglob("config.toml"))
|
||||
self.assertTrue(backups)
|
||||
|
||||
def test_codex_keeps_other_hooks(self):
|
||||
(self.home / ".codex" / "hooks.json").write_text(json.dumps(
|
||||
{"hooks": {"Stop": [{"hooks": [{"type": "command", "command": "mine.exe"}]}]}}), encoding="utf-8")
|
||||
install.install("codex", python="py -3.12")
|
||||
stop = json.loads(self.read(".codex", "hooks.json"))["hooks"]["Stop"]
|
||||
self.assertEqual(len(stop), 2)
|
||||
install.install("codex", remove=True)
|
||||
self.assertEqual(json.loads(self.read(".codex", "hooks.json")),
|
||||
{"hooks": {"Stop": [{"hooks": [{"type": "command", "command": "mine.exe"}]}]}})
|
||||
|
||||
def test_opencode(self):
|
||||
install.install("opencode", python="py -3.12")
|
||||
config = json.loads(self.read(".config", "opencode", "opencode.jsonc"))
|
||||
self.assertEqual(config["$schema"], "https://opencode.ai/config.json")
|
||||
self.assertEqual(config["mcp"]["harbor"]["environment"], {"HARBOR_AGENT": "OpenCode", "HARBOR_HOST": "opencode"})
|
||||
plugin = self.read(".config", "opencode", "plugin", "harbor.js")
|
||||
self.assertIn('const AGENT = "OpenCode";', plugin)
|
||||
self.assertIn('const COMMAND = ["py", "-3.12", "-B",', plugin)
|
||||
self.assertIn("export const HarborPlugin", plugin)
|
||||
install.install("opencode", remove=True)
|
||||
self.assertEqual(json.loads(self.read(".config", "opencode", "opencode.jsonc")),
|
||||
{"$schema": "https://opencode.ai/config.json"})
|
||||
self.assertFalse((self.home / ".config" / "opencode" / "plugin" / "harbor.js").exists())
|
||||
|
||||
def test_deepseek(self):
|
||||
install.install("deepseek", python="py -3.12")
|
||||
patch = self.read(".dsh", "profiles", "desktop", "cordis.patch.yml")
|
||||
self.assertTrue(patch.startswith(DSH_PATCH.rstrip("\n")))
|
||||
rows = install._TolerantLoader.load(patch)
|
||||
inserted = rows[-1]["insert"]
|
||||
self.assertEqual([r["id"] for r in inserted], ["mcp-harbor", "hooks-harbor"])
|
||||
self.assertEqual(inserted[0]["config"]["env"], {"HARBOR_AGENT": "DeepSeek", "HARBOR_HOST": "deepseek"})
|
||||
hooks = json.loads((self.harbor_home / "integrations" / "deepseek" / "hooks.json").read_text(encoding="utf-8"))
|
||||
self.assertIn("--host deepseek", hooks["hooks"]["Stop"][0]["hooks"][0]["command"])
|
||||
install.install("deepseek", remove=True)
|
||||
self.assertEqual(self.read(".dsh", "profiles", "desktop", "cordis.patch.yml"), DSH_PATCH)
|
||||
|
||||
def test_kimi_plugin_is_bound_to_a_project(self):
|
||||
install.install("kimi", project="test", python="py -3.12", register=False)
|
||||
folder = self.harbor_home / "integrations" / "kimi" / "harbor-test"
|
||||
manifest = json.loads((folder / "kimi.plugin.json").read_text(encoding="utf-8"))
|
||||
self.assertEqual(manifest["mcpServers"]["harbor"]["env"], {"HARBOR_AGENT": "Kimi", "HARBOR_PROJECT": "test", "HARBOR_HOST": "kimi"})
|
||||
self.assertEqual([h["event"] for h in manifest["hooks"]], ["UserPromptSubmit", "PreToolUse", "Stop"])
|
||||
self.assertTrue(all("--project test" in h["command"] for h in manifest["hooks"]))
|
||||
self.assertTrue((folder / "skills" / "harbor-test" / "SKILL.md").exists())
|
||||
|
||||
def test_refusals(self):
|
||||
with self.assertRaises(install.InstallError):
|
||||
install.install("codex", agent="Nobody")
|
||||
(self.home / ".config" / "opencode" / "opencode.jsonc").write_text('{ // mine\n}', encoding="utf-8")
|
||||
with self.assertRaises(install.InstallError):
|
||||
install.install("opencode")
|
||||
(self.home / ".codex" / "config.toml").write_text(CODEX_CONFIG + "\n[mcp_servers.harbor]\ncommand='x'\n",
|
||||
encoding="utf-8")
|
||||
with self.assertRaises(install.InstallError):
|
||||
install.install("codex")
|
||||
|
||||
def test_dry_run_writes_nothing(self):
|
||||
report = install.install("deepseek", dry_run=True, python="py -3.12")
|
||||
self.assertTrue(any(line.startswith("update") for line in report))
|
||||
self.assertEqual(self.read(".dsh", "profiles", "desktop", "cordis.patch.yml"), DSH_PATCH)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user