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.
- package/.pantheon/code-mode/README.md +4 -2
- package/.pantheon/code-mode/checkpoint_session.py +138 -102
- package/.pantheon/code-mode/compress-inline.py +102 -57
- package/.pantheon/code-mode/manifest.json +2 -8
- package/CHANGELOG.md +59 -0
- package/README.md +115 -55
- package/README.pt-BR.md +86 -43
- package/commands/pantheon-optimize.md +2 -2
- package/package.json +13 -1
- package/plugin.json +1 -1
- package/pyproject.toml +8 -15
- package/scripts/build-agents-md.mjs +2 -2
- package/scripts/check-plugin-v2-coverage.mjs +213 -0
- package/scripts/ci-validate-yaml.py +7 -5
- package/scripts/code_mode_server.py +116 -24
- package/scripts/doctor.mjs +85 -28
- package/scripts/install/cli-ui.mjs +1 -1
- package/scripts/install/config-migration.mjs +124 -3
- package/scripts/install/health-check.mjs +6 -19
- package/scripts/install/interactive.mjs +6 -6
- package/scripts/install/migrate.mjs +1 -1
- package/scripts/install/opencode.mjs +43 -10
- package/scripts/mcp_persistence_server.py +390 -76
- package/scripts/memory_mcp_server.py +370 -196
- package/scripts/postinstall.mjs +0 -7
- package/scripts/probe-context-rehydrate.mjs +28 -11
- package/scripts/prune.mjs +2 -2
- package/scripts/test-opencode-v2-sandbox.sh +1759 -0
- package/scripts/validate-routing.mjs +40 -0
- package/skills-lock.json +9 -10
- package/src/agents/aphrodite.md +0 -1
- package/src/agents/apollo.md +0 -1
- package/src/agents/athena.md +0 -1
- package/src/agents/demeter.md +0 -1
- package/src/agents/gaia.md +0 -1
- package/src/agents/hephaestus.md +0 -1
- package/src/agents/hermes.md +0 -1
- package/src/agents/iris.md +0 -1
- package/src/agents/mnemosyne.md +15 -17
- package/src/agents/nyx.md +0 -1
- package/src/agents/prometheus.md +0 -1
- package/src/agents/talos.md +0 -1
- package/src/agents/themis.md +0 -1
- package/src/agents/zeus.md +1 -3
- package/src/mcp/code_mode_server.py +116 -24
- package/src/mcp/mcp_codemap_module.py +559 -129
- package/src/mcp/mcp_persistence_server.py +390 -76
- package/src/mcp/memory_mcp_server.py +371 -248
- package/src/mcp/pantheon_vision_server.py +136 -24
- package/src/mcp/requirements-mcp.txt +5 -3
- package/src/mcp/requirements-vision.txt +2 -0
- package/src/pantheon/model-command.ts +18 -7
- package/src/pantheon/presets.d.mts +0 -8
- package/src/pantheon/presets.mjs +0 -29
- package/src/pantheon/todo-enforcer.ts +1 -1
- package/src/pantheon/vision.ts +1 -1
- package/src/plugin-v2.ts +134 -104
- package/src/plugins/tui/dist/tui.js +1 -1
- package/src/plugins/tui/package-lock.json +23 -23
- package/src/plugins/tui/package.json +12 -12
- package/src/routing.yml +0 -16
- package/src/skills/README.md +31 -36
- package/src/skills/auto-continue/SKILL.md +27 -77
- package/.pantheon/code-mode/eval-llm-judge.py +0 -255
- package/.pantheon/code-mode/eval-monte-carlo.py +0 -368
- package/.pantheon/code-mode/eval-run.py +0 -197
- package/.pantheon/code-mode/eval-static.py +0 -321
- package/.pantheon/code-mode/session-end-save.py +0 -186
- package/.pantheon/code-mode/session-end-save.sh +0 -18
- package/scripts/recover-zenodo-deposition.mjs +0 -146
- package/scripts/test-opencode-v1-v2-sandbox.sh +0 -862
- package/scripts/validate-zenodo-release.mjs +0 -154
- package/scripts/zenodo-artifact.mjs +0 -94
- package/scripts/zenodo-release-state.mjs +0 -53
- package/src/skills/orchestration-workflow/SKILL.md +0 -311
package/scripts/postinstall.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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":
|
|
141
|
+
"content": json.dumps(checkpoint), "ttl": 1,
|
|
138
142
|
"session_id": session_id})
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
205
|
+
`dead config(s): ${deadConfigs.map((c) => c.replace(`${dir}/`, '')).join(', ')}`,
|
|
206
206
|
'list',
|
|
207
207
|
)
|
|
208
208
|
}
|