pantheon-opencode 1.5.2 → 1.6.0-beta.2

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 (75) hide show
  1. package/.pantheon/code-mode/README.md +4 -2
  2. package/.pantheon/code-mode/checkpoint_session.py +138 -102
  3. package/.pantheon/code-mode/compress-inline.py +102 -57
  4. package/.pantheon/code-mode/manifest.json +2 -8
  5. package/CHANGELOG.md +59 -0
  6. package/README.md +115 -55
  7. package/README.pt-BR.md +86 -43
  8. package/commands/pantheon-optimize.md +2 -2
  9. package/package.json +13 -1
  10. package/plugin.json +1 -1
  11. package/pyproject.toml +8 -15
  12. package/scripts/build-agents-md.mjs +2 -2
  13. package/scripts/check-plugin-v2-coverage.mjs +213 -0
  14. package/scripts/ci-validate-yaml.py +7 -5
  15. package/scripts/code_mode_server.py +116 -24
  16. package/scripts/doctor.mjs +85 -28
  17. package/scripts/install/cli-ui.mjs +1 -1
  18. package/scripts/install/config-migration.mjs +124 -3
  19. package/scripts/install/health-check.mjs +6 -19
  20. package/scripts/install/interactive.mjs +6 -6
  21. package/scripts/install/migrate.mjs +1 -1
  22. package/scripts/install/opencode.mjs +43 -10
  23. package/scripts/mcp_persistence_server.py +390 -76
  24. package/scripts/memory_mcp_server.py +370 -196
  25. package/scripts/postinstall.mjs +0 -7
  26. package/scripts/probe-context-rehydrate.mjs +28 -11
  27. package/scripts/prune.mjs +2 -2
  28. package/scripts/test-opencode-v2-sandbox.sh +1759 -0
  29. package/scripts/validate-routing.mjs +40 -0
  30. package/skills-lock.json +9 -10
  31. package/src/agents/aphrodite.md +0 -1
  32. package/src/agents/apollo.md +0 -1
  33. package/src/agents/athena.md +0 -1
  34. package/src/agents/demeter.md +0 -1
  35. package/src/agents/gaia.md +0 -1
  36. package/src/agents/hephaestus.md +0 -1
  37. package/src/agents/hermes.md +0 -1
  38. package/src/agents/iris.md +0 -1
  39. package/src/agents/mnemosyne.md +15 -17
  40. package/src/agents/nyx.md +0 -1
  41. package/src/agents/prometheus.md +0 -1
  42. package/src/agents/talos.md +0 -1
  43. package/src/agents/themis.md +0 -1
  44. package/src/agents/zeus.md +1 -3
  45. package/src/mcp/code_mode_server.py +116 -24
  46. package/src/mcp/mcp_codemap_module.py +559 -129
  47. package/src/mcp/mcp_persistence_server.py +390 -76
  48. package/src/mcp/memory_mcp_server.py +371 -248
  49. package/src/mcp/pantheon_vision_server.py +136 -24
  50. package/src/mcp/requirements-mcp.txt +5 -3
  51. package/src/mcp/requirements-vision.txt +2 -0
  52. package/src/pantheon/model-command.ts +18 -7
  53. package/src/pantheon/presets.d.mts +0 -8
  54. package/src/pantheon/presets.mjs +0 -29
  55. package/src/pantheon/todo-enforcer.ts +1 -1
  56. package/src/pantheon/vision.ts +1 -1
  57. package/src/plugin-v2.ts +134 -104
  58. package/src/plugins/tui/dist/tui.js +1 -1
  59. package/src/plugins/tui/package-lock.json +23 -23
  60. package/src/plugins/tui/package.json +12 -12
  61. package/src/routing.yml +0 -16
  62. package/src/skills/README.md +31 -36
  63. package/src/skills/auto-continue/SKILL.md +27 -77
  64. package/.pantheon/code-mode/eval-llm-judge.py +0 -255
  65. package/.pantheon/code-mode/eval-monte-carlo.py +0 -368
  66. package/.pantheon/code-mode/eval-run.py +0 -197
  67. package/.pantheon/code-mode/eval-static.py +0 -321
  68. package/.pantheon/code-mode/session-end-save.py +0 -186
  69. package/.pantheon/code-mode/session-end-save.sh +0 -18
  70. package/scripts/recover-zenodo-deposition.mjs +0 -146
  71. package/scripts/test-opencode-v1-v2-sandbox.sh +0 -862
  72. package/scripts/validate-zenodo-release.mjs +0 -154
  73. package/scripts/zenodo-artifact.mjs +0 -94
  74. package/scripts/zenodo-release-state.mjs +0 -53
  75. package/src/skills/orchestration-workflow/SKILL.md +0 -311
@@ -5,13 +5,6 @@
5
5
  * Runs after `npm install` completes. Validates environment and prints
6
6
  * setup instructions. Does NOT install Pantheon platform components.
7
7
  */
8
- import { existsSync } from 'node:fs'
9
- import { join } from 'node:path'
10
- import { fileURLToPath } from 'node:url'
11
-
12
- const __dirname = fileURLToPath(new URL('.', import.meta.url))
13
- const _ROOT = join(__dirname, '..')
14
-
15
8
  const REQUIRED_NODE_MAJOR = 18
16
9
  const nodeMajor = parseInt(process.versions.node.split('.')[0], 10)
17
10
 
@@ -113,8 +113,10 @@ async def main():
113
113
 
114
114
  os.environ.pop("PANTHEON_COMPACTION", None)
115
115
  os.environ.pop("PANTHEON_SESSION_END_SUMMARY", None)
116
- blocks = await call("context_rehydrate", {"slug": slug})
117
- summary = await call("context_session_summary", {"slug": slug})
116
+ blocks = await call("context_rehydrate", {"slug": slug,
117
+ "session_id": session_id})
118
+ summary = await call("context_session_summary", {"slug": slug,
119
+ "session_id": session_id})
118
120
  if not isinstance(blocks, list) or not blocks:
119
121
  raise AssertionError("context_rehydrate returned a null/empty payload")
120
122
  if not isinstance(summary, str) or not summary:
@@ -126,18 +128,25 @@ async def main():
126
128
  checks.append("context_rehydrate non-null payload: PASS")
127
129
  checks.append("context_session_summary non-null payload: PASS")
128
130
 
129
- missing_blocks = await call("context_rehydrate", {"slug": "probe-absent"})
130
- missing_summary = await call("context_session_summary", {"slug": "probe-absent"})
131
+ missing_blocks = await call("context_rehydrate", {"slug": "probe-absent",
132
+ "session_id": session_id})
133
+ missing_summary = await call("context_session_summary", {"slug": "probe-absent",
134
+ "session_id": session_id})
131
135
  if missing_blocks is not None or missing_summary is not None:
132
136
  raise AssertionError("absent checkpoint must return null payloads")
133
137
  checks.append("absence returns null: PASS")
134
138
 
135
139
  expired_slug = "context-expired-probe"
136
140
  await call("context_save", {"slug": expired_slug, "key": "phase:1",
137
- "content": json.dumps(checkpoint), "ttl": -1,
141
+ "content": json.dumps(checkpoint), "ttl": 1,
138
142
  "session_id": session_id})
139
- expired_blocks = await call("context_rehydrate", {"slug": expired_slug})
140
- expired_summary = await call("context_session_summary", {"slug": expired_slug})
143
+ # Use the public TTL contract (positive seconds) and let the entry expire;
144
+ # negative TTLs are rejected by validation and must not be special-cased.
145
+ await asyncio.sleep(1.2)
146
+ expired_blocks = await call("context_rehydrate", {"slug": expired_slug,
147
+ "session_id": session_id})
148
+ expired_summary = await call("context_session_summary", {"slug": expired_slug,
149
+ "session_id": session_id})
141
150
  if expired_blocks is not None or expired_summary is not None:
142
151
  raise AssertionError("expired checkpoint must return null payloads")
143
152
  checks.append("expiration returns null: PASS")
@@ -145,19 +154,23 @@ async def main():
145
154
  invalid_slug = "context-invalid-probe"
146
155
  await call("context_save", {"slug": invalid_slug, "key": "phase:1",
147
156
  "content": "not-json", "session_id": session_id})
148
- invalid_blocks = await call("context_rehydrate", {"slug": invalid_slug})
149
- invalid_summary = await call("context_session_summary", {"slug": invalid_slug})
157
+ invalid_blocks = await call("context_rehydrate", {"slug": invalid_slug,
158
+ "session_id": session_id})
159
+ invalid_summary = await call("context_session_summary", {"slug": invalid_slug,
160
+ "session_id": session_id})
150
161
  if invalid_blocks is not None or invalid_summary is not None:
151
162
  raise AssertionError("invalid checkpoint must return null payloads")
152
163
  checks.append("invalid payload returns null: PASS")
153
164
 
154
165
  os.environ["PANTHEON_COMPACTION"] = "off"
155
- switched_blocks = await call("context_rehydrate", {"slug": slug})
166
+ switched_blocks = await call("context_rehydrate", {"slug": slug,
167
+ "session_id": session_id})
156
168
  if switched_blocks is not None:
157
169
  raise AssertionError("PANTHEON_COMPACTION=off must return null")
158
170
  os.environ.pop("PANTHEON_COMPACTION", None)
159
171
  os.environ["PANTHEON_SESSION_END_SUMMARY"] = "off"
160
- switched_summary = await call("context_session_summary", {"slug": slug})
172
+ switched_summary = await call("context_session_summary", {"slug": slug,
173
+ "session_id": session_id})
161
174
  if switched_summary is not None:
162
175
  raise AssertionError("PANTHEON_SESSION_END_SUMMARY=off must return null")
163
176
  checks.append("kill-switches return null: PASS")
@@ -207,6 +220,10 @@ async function main() {
207
220
  emit('AMBIENTAL', 'persistence probe timed out after 30s')
208
221
  return
209
222
  }
223
+ if (/IncompleteFieldDefinitionWarning|pydantic_settings/i.test(child.stderr)) {
224
+ emit('FAIL', 'persistence probe emitted an incomplete pydantic_settings field warning')
225
+ return
226
+ }
210
227
  if (child.status !== 0) {
211
228
  const detail = `${child.stderr || child.stdout || 'persistence probe failed'}`.trim()
212
229
  if (
package/scripts/prune.mjs CHANGED
@@ -164,7 +164,7 @@ export function configHasDeadPaths(configPath) {
164
164
  return true // unparseable config in a legacy dir counts as dead
165
165
  }
166
166
 
167
- const check = (value, where) => {
167
+ const check = (value, _where) => {
168
168
  if (typeof value !== 'string' || value === '') return
169
169
  if (value.startsWith('file://')) return
170
170
  if (!value.startsWith('/')) return true // relative path in a config
@@ -202,7 +202,7 @@ export function findLegacyDirs(configDir) {
202
202
  add(
203
203
  'legacy-dir',
204
204
  dir,
205
- `dead config(s): ${deadConfigs.map((c) => c.replace(dir + '/', '')).join(', ')}`,
205
+ `dead config(s): ${deadConfigs.map((c) => c.replace(`${dir}/`, '')).join(', ')}`,
206
206
  'list',
207
207
  )
208
208
  }