pantheon-opencode 1.4.3 → 1.5.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/.pantheon/code-mode/README.md +93 -0
  2. package/.pantheon/code-mode/checkpoint-session.py +7 -0
  3. package/.pantheon/code-mode/checkpoint-session.sh +11 -0
  4. package/.pantheon/code-mode/checkpoint_session.py +481 -0
  5. package/.pantheon/code-mode/compress-inline.py +450 -0
  6. package/.pantheon/code-mode/eval-llm-judge.py +255 -0
  7. package/.pantheon/code-mode/eval-monte-carlo.py +368 -0
  8. package/.pantheon/code-mode/eval-run.py +197 -0
  9. package/.pantheon/code-mode/eval-static.py +321 -0
  10. package/.pantheon/code-mode/example-sync.sh +5 -0
  11. package/.pantheon/code-mode/manifest.json +21 -0
  12. package/.pantheon/code-mode/session-end-save.py +186 -0
  13. package/.pantheon/code-mode/session-end-save.sh +18 -0
  14. package/.pantheon/code-mode/test-allowed.sh +5 -0
  15. package/.pantheon/code-mode/test-auto-continue-checkpoint.sh +179 -0
  16. package/.pantheon/code-mode/test-env.sh +7 -0
  17. package/.pantheon/code-mode/test-prlimit.sh +9 -0
  18. package/.pantheon/code-mode/test-timeout.sh +6 -0
  19. package/CHANGELOG.md +1026 -0
  20. package/README.md +292 -1080
  21. package/README.pt-BR.md +308 -0
  22. package/bin/pantheon-init.mjs +207 -31
  23. package/opencode.json +1 -0
  24. package/package.json +34 -14
  25. package/plugin.json +15 -0
  26. package/pyproject.toml +65 -0
  27. package/scripts/_pantheon_paths.py +48 -7
  28. package/scripts/ci-validate-yaml.py +7 -2
  29. package/scripts/code_mode_server.py +451 -44
  30. package/scripts/cost.mjs +30 -14
  31. package/scripts/doctor.mjs +306 -129
  32. package/scripts/generate-preset-docs.mjs +127 -66
  33. package/scripts/generate-prompts.sh +2 -2
  34. package/scripts/install/cli-ui.mjs +23 -10
  35. package/scripts/install/config-migration.mjs +399 -0
  36. package/scripts/install/health-check.mjs +3 -3
  37. package/scripts/install/model-picker.mjs +72 -23
  38. package/scripts/install/opencode-version.mjs +47 -0
  39. package/scripts/install/opencode.mjs +396 -121
  40. package/scripts/install/plugin.mjs +89 -49
  41. package/scripts/install/shared.mjs +55 -159
  42. package/scripts/install/strings.mjs +129 -0
  43. package/scripts/install-mcp.mjs +45 -232
  44. package/scripts/manifest-inventory.mjs +410 -0
  45. package/scripts/mcp_persistence_server.py +798 -60
  46. package/scripts/mcp_resources_server.py +144 -40
  47. package/scripts/memory_mcp_server.py +2 -2
  48. package/scripts/package-evidence.mjs +242 -0
  49. package/scripts/probe-context-rehydrate.mjs +240 -0
  50. package/scripts/probe-pantheon-cost.mjs +313 -0
  51. package/scripts/recover-zenodo-deposition.mjs +146 -0
  52. package/scripts/release-beta-version.mjs +56 -60
  53. package/scripts/sync-artifacts.mjs +169 -0
  54. package/scripts/sync-tui.mjs +135 -42
  55. package/scripts/test-opencode-v1-v2-sandbox.sh +862 -0
  56. package/scripts/uninstall.mjs +298 -954
  57. package/scripts/validate-zenodo-release.mjs +154 -0
  58. package/scripts/validation-policy.mjs +7 -7
  59. package/scripts/version-check.mjs +113 -108
  60. package/scripts/versioning.mjs +230 -86
  61. package/scripts/zenodo-artifact.mjs +21 -0
  62. package/scripts/zenodo-release-state.mjs +53 -0
  63. package/src/agents/mnemosyne.md +1 -1
  64. package/src/agents/zeus.md +27 -16
  65. package/src/mcp/_pantheon_paths.py +48 -7
  66. package/src/mcp/code_mode_server.py +451 -44
  67. package/src/mcp/eval_store.py +1 -1
  68. package/src/mcp/mcp_persistence_server.py +798 -60
  69. package/src/mcp/mcp_resources_server.py +144 -40
  70. package/src/mcp/pantheon_vision_server.py +1 -1
  71. package/src/mcp/toon_codec.py +491 -0
  72. package/src/pantheon/auto-wake.ts +1 -5
  73. package/src/pantheon/background-job-board.ts +110 -2
  74. package/src/pantheon/compaction-handoff.ts +304 -0
  75. package/src/pantheon/cost-command.ts +356 -69
  76. package/src/pantheon/delegate-manager.ts +766 -0
  77. package/src/pantheon/delegation-classifier.ts +307 -0
  78. package/src/pantheon/delegation-enforce.ts +13 -12
  79. package/src/pantheon/delegation-finalize.ts +406 -0
  80. package/src/pantheon/delegation-notify.ts +212 -0
  81. package/src/pantheon/delegation-toast.ts +73 -0
  82. package/src/pantheon/delegation.ts +1337 -0
  83. package/src/pantheon/file-persistence-salvage.ts +64 -0
  84. package/src/pantheon/file-persistence.ts +194 -45
  85. package/src/pantheon/goal-loop.ts +2 -2
  86. package/src/pantheon/goal-store.ts +1 -1
  87. package/src/pantheon/hashline/tool.ts +2 -2
  88. package/src/pantheon/model-command.ts +2 -1
  89. package/src/pantheon/native-probe.ts +234 -0
  90. package/src/pantheon/native-task-status.ts +139 -0
  91. package/src/pantheon/permission-eval.ts +284 -0
  92. package/src/pantheon/provider-capabilities.ts +221 -0
  93. package/src/pantheon/provider-stream-tracker.ts +182 -0
  94. package/src/pantheon/shared-board.ts +37 -0
  95. package/src/pantheon/step-cap.ts +110 -0
  96. package/src/pantheon/task-result-guard.ts +107 -0
  97. package/src/pantheon/token-opt.ts +689 -0
  98. package/src/pantheon/tool-ceiling.ts +159 -0
  99. package/src/pantheon/toon-codec.ts +481 -0
  100. package/src/pantheon/tui-version-check.ts +1 -3
  101. package/src/pantheon/v2-bridge.ts +129 -0
  102. package/src/pantheon/v2-events.ts +148 -0
  103. package/src/pantheon/v2-hooks.ts +287 -0
  104. package/src/pantheon/v2-tool-definitions.ts +331 -0
  105. package/src/pantheon/zeus-delegate-with-retry.ts +406 -0
  106. package/src/plugin-v2/index.ts +21 -0
  107. package/src/plugin-v2.ts +824 -0
  108. package/src/plugin.ts +261 -51
  109. package/src/plugins/pantheon-hooks.ts +51 -0
  110. package/src/plugins/tui/dist/tui.d.ts +116 -24
  111. package/src/plugins/tui/dist/tui.d.ts.map +1 -1
  112. package/src/plugins/tui/dist/tui.js +416 -149
  113. package/src/plugins/tui/dist/tui.tsx +456 -87
  114. package/src/plugins/tui/package-lock.json +51 -51
  115. package/src/plugins/tui/package.json +7 -7
  116. package/src/plugins/tui/src/index.tsx +462 -95
  117. package/src/skills/README.md +0 -2
  118. package/src/pantheon/tool-context.ts +0 -41
package/package.json CHANGED
@@ -1,11 +1,17 @@
1
1
  {
2
2
  "name": "pantheon-opencode",
3
- "version": "1.4.3",
3
+ "version": "1.5.0-beta.10",
4
4
  "description": "Multi-agent orchestration for OpenCode — 14 specialized agents, TDD, Themis review gates.",
5
+ "type": "module",
5
6
  "publishConfig": {
6
7
  "access": "public",
7
8
  "registry": "https://registry.npmjs.org/"
8
9
  },
10
+ "exports": {
11
+ "./plugin": "./src/plugin.ts",
12
+ "./plugin-v2": "./src/plugin-v2.ts",
13
+ "./v2-bridge": "./src/pantheon/v2-bridge.ts"
14
+ },
9
15
  "scripts": {
10
16
  "postinstall": "node scripts/postinstall.mjs && node scripts/sync-tui.mjs",
11
17
  "prepare": "husky",
@@ -22,28 +28,37 @@
22
28
  "version:status": "node scripts/versioning.mjs status",
23
29
  "version:apply": "node scripts/versioning.mjs apply",
24
30
  "version:check": "node scripts/version-check.mjs",
25
- "release:dry-run": "node scripts/versioning.mjs status && node scripts/release-notes.mjs && npm pack --dry-run",
31
+ "release:dry-run": "node scripts/versioning.mjs status && node scripts/release-notes.mjs && node scripts/package-evidence.mjs",
32
+ "package:evidence": "node scripts/package-evidence.mjs",
33
+ "package:validate": "node scripts/validate-package.mjs",
26
34
  "publish:next": "npm publish --tag next --access public",
27
- "lint": "npx biome ci .",
28
- "typecheck": "npx tsc --noEmit",
35
+ "lint": "biome ci .",
36
+ "typecheck": "tsc --noEmit",
29
37
  "audit": "npm audit --audit-level=high",
30
38
  "secret-scan": "node scripts/secret-scan.mjs",
31
39
  "hooks:install": "pre-commit install",
32
40
  "hooks:update": "pre-commit autoupdate",
33
- "test:security": "npm run secret-scan && node tests/test_install_mcp_vision.mjs && node tests/test_doctor_layers.mjs",
41
+ "test:security": "npm run secret-scan",
34
42
  "test:node": "node --test tests/*.mjs tests/pantheon/*.mjs",
35
- "test:ts": "for f in tests/pantheon/*.test.ts; do npx tsx \"$f\" || exit 1; done",
36
- "test": "python3 -m pytest tests/ -q 2>&1; status=$?; if [ \"$status\" -eq 5 ]; then echo \"No tests found\"; fi; exit \"$status\"",
37
- "test:ci": "python3 -m pytest tests/ -q --tb=short 2>&1"
43
+ "test:ts": "for f in tests/pantheon/*.test.ts; do if [ \"$f\" = tests/pantheon/plugin-v2-contract.test.ts ]; then NODE_OPTIONS=--conditions=import tsx \"$f\"; else tsx \"$f\"; fi || exit 1; done",
44
+ "test:all": "npm run test:ci && npm run test:node && npm run test:ts",
45
+ "test": "npm run test:all",
46
+ "test:ci": "python3 -m pytest -q --tb=short 2>&1"
38
47
  },
39
48
  "bin": {
40
49
  "pantheon-opencode": "bin/pantheon-init.mjs"
41
50
  },
42
51
  "files": [
43
52
  "LICENSE",
53
+ "package-lock.json",
54
+ "plugin.json",
55
+ "pyproject.toml",
44
56
  "scripts/install/*.mjs",
45
57
  "scripts/*.py",
46
58
  "src/plugin.ts",
59
+ "src/plugin-v2.ts",
60
+ "src/plugin-v2",
61
+ "src/pantheon/v2-bridge.ts",
47
62
  "README.md",
48
63
  "src/mcp/*.txt",
49
64
  "commands/*.md",
@@ -54,6 +69,7 @@
54
69
  "!src/agents/README.md",
55
70
  "bin/*.mjs",
56
71
  "AGENTS.md",
72
+ "CHANGELOG.md",
57
73
  "opencode.json",
58
74
  "src/mcp/*.py",
59
75
  "src/instructions/*.instructions.md",
@@ -62,6 +78,7 @@
62
78
  "src/mcp/*.sh",
63
79
  "src/routing.yml",
64
80
  "src/pantheon/**",
81
+ ".pantheon/code-mode/**",
65
82
  "src/plugins/**",
66
83
  "scripts/hooks/**",
67
84
  "src/mcp/requirements*",
@@ -72,14 +89,17 @@
72
89
  "!**/*.pyc"
73
90
  ],
74
91
  "dependencies": {
75
- "js-yaml": "^4.3.0",
92
+ "@opencode-ai/plugin": "1.18.30",
93
+ "js-yaml": "^4.3.2",
76
94
  "zod": "4.1.8"
77
95
  },
78
96
  "devDependencies": {
79
- "@commitlint/cli": "^19.8.0",
80
- "@commitlint/config-conventional": "^19.8.0",
81
- "@opencode-ai/plugin": "1.18.11",
82
- "husky": "^9.1.7"
97
+ "@biomejs/biome": "2.5.13",
98
+ "@commitlint/cli": "21.2.2",
99
+ "@commitlint/config-conventional": "21.2.2",
100
+ "husky": "^9.1.7",
101
+ "tsx": "4.23.13",
102
+ "typescript": "6.0.3"
83
103
  },
84
104
  "repository": {
85
105
  "type": "git",
@@ -100,7 +120,7 @@
100
120
  "author": "ils15",
101
121
  "license": "MIT",
102
122
  "engines": {
103
- "node": ">=18"
123
+ "node": ">=22"
104
124
  },
105
125
  "preferGlobal": true
106
126
  }
package/plugin.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "pantheon",
3
+ "publisher": "ils15",
4
+ "version": "1.5.0-beta.10",
5
+ "displayName": "Pantheon",
6
+ "description": "Conductor-Delegate orchestration platform with 14 specialized agents, 21 skills, and OpenCode support.",
7
+ "agents": "./src/agents",
8
+ "skills": "./src/skills",
9
+ "instructions": "./src/instructions",
10
+ "prompts": "./prompts",
11
+ "repository": "https://github.com/ils15/pantheon-opencode",
12
+ "exports": {
13
+ ".": "./src/routing.yml"
14
+ }
15
+ }
package/pyproject.toml ADDED
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64"]
3
+ build-backend = "setuptools.backends._legacy:_Backend"
4
+
5
+ [project]
6
+ name = "pantheon"
7
+ version = "1.5.0-beta.10"
8
+ description = "Multi-agent orchestration framework"
9
+ requires-python = ">=3.11"
10
+ dependencies = []
11
+
12
+ [tool.pytest.ini_options]
13
+ # `tests/` holds the main suite; the two entries below are orphaned test
14
+ # modules that live next to the code they cover and are collected here so
15
+ # pytest (and therefore `npm test`) exercises them instead of letting them
16
+ # rot as dead code.
17
+ testpaths = [
18
+ "tests",
19
+ "scripts/vector_memory/test_memory.py",
20
+ "benchmarks/beta2/test_beta2.py",
21
+ ]
22
+ asyncio_mode = "auto"
23
+ addopts = "-v --tb=short"
24
+
25
+ [tool.ruff]
26
+ line-length = 88
27
+ target-version = "py311"
28
+
29
+ [tool.ruff.lint]
30
+ select = ["E", "F", "W", "I", "N", "UP", "B", "SIM", "PL", "RUF", "C901"]
31
+ ignore = ["E501"]
32
+
33
+ [tool.ruff.lint.per-file-ignores]
34
+ "__init__.py" = ["F401"]
35
+ # Legacy command-line scripts intentionally use hyphenated filenames.
36
+ "scripts/ci-validate-yaml.py" = ["N999"]
37
+ "scripts/scrub-secrets.py" = ["N999"]
38
+ # These modules defer optional/heavy imports until the corresponding command is used.
39
+ "scripts/vector_memory/*.py" = ["PLC0415"]
40
+ "tests/test_code_mode_args.py" = ["PLC0415"]
41
+ "tests/test_code_mode_sandbox.py" = ["PLC0415", "N806"]
42
+ "tests/test_code_mode_server.py" = ["PLC0415"]
43
+ "tests/test_eval_store.py" = ["PLC0415", "PLR2004"]
44
+ "tests/test_memory_mcp_server.py" = ["PLC0415", "PLR2004"]
45
+ # Existing public APIs and test fixtures are intentionally broad/simple; refactoring
46
+ # them would be behavior-affecting rather than a mechanical lint correction.
47
+ "scripts/code_mode_server.py" = ["PLR0913"]
48
+ "src/mcp/code_mode_server.py" = ["PLR0913"]
49
+ "scripts/mcp_persistence_server.py" = ["PLR0913"]
50
+ "src/mcp/mcp_persistence_server.py" = ["PLR0913"]
51
+ "scripts/memory_mcp_server.py" = ["C901"]
52
+ "scripts/vector_memory/index.py" = ["C901", "PLR0913", "PLR2004", "PLW0603", "PLW2901"]
53
+ "scripts/vector_memory/cli.py" = ["PLR2004"]
54
+ "scripts/vector_memory/query.py" = ["PLR0913"]
55
+ "src/mcp/eval_store.py" = ["PLR2004"]
56
+ "tests/test_code_mode_frontmatter.py" = ["PLR2004"]
57
+ "tests/test_eval_judge.py" = ["PLR2004"]
58
+ "tests/test_eval_static.py" = ["PLR2004"]
59
+ "tests/test_mcp_persistence_server.py" = ["PLR2004"]
60
+
61
+ [tool.mypy]
62
+ python_version = "3.11"
63
+ strict = true
64
+ ignore_missing_imports = true
65
+ disallow_untyped_defs = true
@@ -34,11 +34,11 @@ def pantheon_home() -> Path:
34
34
  """
35
35
  env = os.environ.get("PANTHEON_HOME")
36
36
  if env:
37
- return Path(env).expanduser().resolve()
37
+ return Path(env).expanduser().absolute()
38
38
 
39
39
  xdg = os.environ.get("XDG_CONFIG_HOME")
40
40
  if xdg:
41
- return Path(xdg).expanduser().resolve() / "opencode"
41
+ return Path(xdg).expanduser().absolute() / "opencode"
42
42
 
43
43
  return Path.home() / ".config" / "opencode"
44
44
 
@@ -48,7 +48,8 @@ def pantheon_project() -> Path | None:
48
48
 
49
49
  Resolution priority:
50
50
  1. $PANTHEON_PROJECT env var (explicit override)
51
- 2. Current working directory (set by MCP client's cwd in opencode.json)
51
+ 2. The validated logical ``$PWD`` supplied by the launcher
52
+ 3. Current working directory (set by MCP client's cwd in opencode.json)
52
53
 
53
54
  Returns:
54
55
  Absolute Path to the project root, or None if neither is available
@@ -56,10 +57,50 @@ def pantheon_project() -> Path | None:
56
57
  """
57
58
  env = os.environ.get("PANTHEON_PROJECT")
58
59
  if env:
59
- return Path(env).expanduser().resolve()
60
-
61
- cwd = os.getcwd()
60
+ return Path(env).expanduser().absolute()
61
+
62
+ logical_cwd = os.environ.get("PWD")
63
+ try:
64
+ cwd = os.getcwd()
65
+ except OSError:
66
+ cwd = ""
67
+ if logical_cwd and _is_valid_logical_cwd(logical_cwd, cwd):
68
+ return Path(logical_cwd).expanduser().absolute()
62
69
  if cwd:
63
- return Path(cwd).resolve()
70
+ return Path(cwd).absolute()
64
71
 
65
72
  return None
73
+
74
+
75
+ def _is_valid_logical_cwd(logical_cwd: str, physical_cwd: str) -> bool:
76
+ """Validate a launcher-provided logical cwd without resolving its result.
77
+
78
+ ``PWD`` is trusted only when it is an existing directory naming the same
79
+ inode as the process cwd. This preserves symlink spelling while rejecting
80
+ forged or stale environment values.
81
+ """
82
+ logical = Path(logical_cwd).expanduser()
83
+ if not logical.is_absolute() or not logical.is_dir():
84
+ return False
85
+ try:
86
+ return os.path.samefile(logical, physical_cwd)
87
+ except (OSError, ValueError):
88
+ return False
89
+
90
+
91
+ def has_symlink_component(path: Path) -> bool:
92
+ """Return whether any existing lexical component of ``path`` is a symlink.
93
+
94
+ The lexical path is intentionally inspected before ``resolve()`` so a
95
+ symlink cannot be hidden by resolving to an otherwise trusted directory.
96
+ Missing trailing components are allowed; this keeps normal project paths
97
+ usable while still checking every existing ancestor.
98
+ """
99
+ current = Path(path.anchor) if path.is_absolute() else Path.cwd()
100
+ for component in path.parts[1:] if path.is_absolute() else path.parts:
101
+ if component in {"", "."}:
102
+ continue
103
+ current /= component
104
+ if current.is_symlink():
105
+ return True
106
+ return False
@@ -1,12 +1,17 @@
1
1
  #!/usr/bin/env python3
2
2
  """Validate agent YAML frontmatter in CI."""
3
- import os, re, yaml, sys
3
+ import os
4
+ import re
5
+ import sys
6
+
7
+ import yaml
4
8
 
5
9
  errors = 0
6
10
  for f in sorted(os.listdir('src/agents')):
7
11
  if not f.endswith('.md'):
8
12
  continue
9
- content = open(f'src/agents/{f}').read()
13
+ with open(f"src/agents/{f}", encoding="utf-8") as agent_file:
14
+ content = agent_file.read()
10
15
  match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
11
16
  if match:
12
17
  try: