pantheon-opencode 1.6.0-beta.1 → 1.6.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 (120) hide show
  1. package/AGENTS.global.md +182 -0
  2. package/AGENTS.md +10 -891
  3. package/CHANGELOG.md +326 -0
  4. package/README.md +496 -32
  5. package/README.pt-BR.md +285 -20
  6. package/bin/pantheon-init.mjs +26 -3
  7. package/commands/pantheon-audit.md +7 -1
  8. package/commands/pantheon-consolidate.md +1 -1
  9. package/commands/pantheon-deepwork.md +14 -3
  10. package/commands/pantheon-focus.md +17 -0
  11. package/commands/pantheon-vision.md +61 -12
  12. package/package.json +21 -14
  13. package/plugin.json +2 -2
  14. package/pyproject.toml +8 -6
  15. package/scripts/build-agents-md.mjs +374 -56
  16. package/scripts/changelog-merge.mjs +161 -0
  17. package/scripts/{code_mode_server.py → code_mode.py} +3 -3
  18. package/scripts/cost.mjs +244 -41
  19. package/scripts/doctor.mjs +151 -1
  20. package/scripts/install/agents-md.mjs +4 -4
  21. package/scripts/install/config-migration.mjs +317 -4
  22. package/scripts/install/health-check.mjs +21 -19
  23. package/scripts/install/interactive.mjs +1 -1
  24. package/scripts/install/opencode-version.mjs +246 -4
  25. package/scripts/install/opencode.mjs +627 -179
  26. package/scripts/install/plugin.mjs +43 -9
  27. package/scripts/install/shared.mjs +120 -12
  28. package/scripts/install/vision-prompt.mjs +161 -0
  29. package/scripts/install-mcp.mjs +28 -9
  30. package/scripts/{mcp_persistence_server.py → mcp_persistence.py} +2 -2
  31. package/{src/mcp/mcp_resources_server.py → scripts/mcp_resources.py} +2 -2
  32. package/scripts/{memory_mcp_server.py → memory_mcp.py} +2 -2
  33. package/scripts/probe-context-rehydrate.mjs +8 -2
  34. package/scripts/probe-pantheon-cost.mjs +71 -15
  35. package/scripts/run-node-tests.mjs +189 -0
  36. package/scripts/sync-artifacts.mjs +26 -13
  37. package/scripts/sync-tui.mjs +24 -3
  38. package/scripts/test-opencode-v2-sandbox.sh +180 -26
  39. package/scripts/validate-routing.mjs +3 -3
  40. package/scripts/validate-sandbox-install.mjs +138 -0
  41. package/scripts/versioning.mjs +13 -1
  42. package/scripts/vision-status.mjs +682 -0
  43. package/skills-lock.json +8 -8
  44. package/src/agents/aphrodite.md +20 -37
  45. package/src/agents/apollo.md +7 -3
  46. package/src/agents/athena.md +63 -35
  47. package/src/agents/demeter.md +8 -28
  48. package/src/agents/gaia.md +1 -1
  49. package/src/agents/hephaestus.md +10 -21
  50. package/src/agents/hermes.md +15 -38
  51. package/src/agents/iris.md +1 -1
  52. package/src/agents/mnemosyne.md +18 -54
  53. package/src/agents/nyx.md +1 -1
  54. package/src/agents/prometheus.md +16 -20
  55. package/src/agents/talos.md +10 -2
  56. package/src/agents/themis.md +5 -5
  57. package/src/agents/zeus.md +99 -129
  58. package/src/instructions/agent-return-format.instructions.md +18 -3
  59. package/src/instructions/backend-standards.instructions.md +2 -0
  60. package/src/instructions/frontend-standards.instructions.md +3 -1
  61. package/src/instructions/memory-protocol.instructions.md +11 -110
  62. package/src/instructions/zeus-anti-stall.instructions.md +14 -61
  63. package/src/instructions/zeus-communication-rules.instructions.md +0 -1
  64. package/src/instructions/zeus-council-synthesis.instructions.md +32 -260
  65. package/src/instructions/zeus-memory-operations.instructions.md +26 -0
  66. package/src/instructions/zeus-timeout-retry.instructions.md +40 -87
  67. package/src/mcp/{code_mode_server.py → code_mode.py} +3 -3
  68. package/src/mcp/eval_store.py +2 -2
  69. package/src/mcp/{mcp_persistence_server.py → mcp_persistence.py} +2 -2
  70. package/{scripts/mcp_resources_server.py → src/mcp/mcp_resources.py} +2 -2
  71. package/src/mcp/{memory_mcp_server.py → memory_mcp.py} +2 -2
  72. package/src/mcp/{pantheon_vision_server.py → pantheon_vision.py} +286 -42
  73. package/src/mcp/requirements-mcp.txt +6 -4
  74. package/src/mcp/requirements-vision.txt +2 -2
  75. package/src/pantheon/cost-command.ts +399 -101
  76. package/src/pantheon/delegation-enforce.ts +10 -1
  77. package/src/pantheon/presets.d.mts +0 -8
  78. package/src/pantheon/presets.mjs +5 -32
  79. package/src/pantheon/v2-bounded-read.ts +640 -0
  80. package/src/pantheon/v2-delegation-enforce.ts +214 -0
  81. package/src/pantheon/v2-execute-after.ts +186 -0
  82. package/src/pantheon/v2-tools.ts +429 -0
  83. package/src/pantheon/v2-unsupported.d.mts +11 -0
  84. package/src/pantheon/v2-unsupported.mjs +90 -0
  85. package/src/pantheon/v2-vision.ts +622 -0
  86. package/src/pantheon/vision-local.ts +531 -0
  87. package/src/pantheon/vision.ts +1160 -115
  88. package/src/plugin-v2.ts +1145 -219
  89. package/src/plugin.ts +12 -9
  90. package/src/plugins/tui/dist/server.d.ts +1 -2
  91. package/src/plugins/tui/dist/server.d.ts.map +1 -1
  92. package/src/plugins/tui/dist/tui-v2.d.ts +154 -0
  93. package/src/plugins/tui/dist/tui-v2.d.ts.map +1 -0
  94. package/src/plugins/tui/dist/tui-v2.js +659 -0
  95. package/src/plugins/tui/dist/tui-v2.js.map +1 -0
  96. package/src/plugins/tui/dist/tui.d.ts +85 -82
  97. package/src/plugins/tui/dist/tui.d.ts.map +1 -1
  98. package/src/plugins/tui/dist/tui.js +72 -59
  99. package/src/plugins/tui/index-v2.ts +6 -0
  100. package/src/plugins/tui/package-lock.json +5516 -1353
  101. package/src/plugins/tui/package.json +22 -12
  102. package/src/plugins/tui/src/index-v2.tsx +734 -0
  103. package/src/plugins/tui/src/index.tsx +106 -85
  104. package/src/plugins/tui/src/opencode-v2.d.ts +13 -0
  105. package/src/plugins/tui/tsconfig.build.json +5 -0
  106. package/src/plugins/tui/tsconfig.typecheck.json +5 -0
  107. package/src/plugins/tui/tsdown.config.ts +22 -2
  108. package/src/plugins/tui/tui-v2.ts +2 -0
  109. package/src/plugins/tui/tui.ts +3 -0
  110. package/src/routing.yml +11 -21
  111. package/src/skills/README.md +3 -3
  112. package/src/skills/agent-coordination/SKILL.md +7 -2
  113. package/src/skills/artifact-management/SKILL.md +12 -5
  114. package/src/skills/auto-continue/SKILL.md +39 -30
  115. package/src/skills/code-review-checklist/SKILL.md +5 -5
  116. package/src/skills/context-compression/SKILL.md +26 -879
  117. package/src/skills/session-goal/SKILL.md +14 -5
  118. package/src/skills/spec-driven-development/SKILL.md +3 -1
  119. package/src/skills/tdd-with-agents/SKILL.md +18 -10
  120. package/opencode.json +0 -58
@@ -5,9 +5,9 @@
5
5
  /**
6
6
  * pantheon-tui — Pantheon TUI plugin for opencode.
7
7
  *
8
- * Bundled entry: `tsdown` emits `dist/tui.js`, and the package `exports`
9
- * (`./tui` → ./dist/tui.js, `./server` → ./dist/server.js) is the ONLY load
10
- * path — no raw TSX copy is shipped. Because the bundle inlines relative
8
+ * V1 bundle: `tsdown` emits `dist/tui.js`, re-exported by root `tui.ts`.
9
+ * OpenCode V2 uses the separate `src/index-v2.tsx` entry and native CLI plugin
10
+ * API. No raw TSX implementation is shipped. Because the bundle inlines relative
11
11
  * imports, this entry may be split into modules without breaking the loader.
12
12
  *
13
13
  * Slots:
@@ -53,16 +53,7 @@ import { homedir } from 'node:os'
53
53
  import { dirname, join } from 'node:path'
54
54
  import { fileURLToPath } from 'node:url'
55
55
  import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from '@opencode-ai/plugin/tui'
56
- import {
57
- createEffect,
58
- createMemo,
59
- createResource,
60
- createSignal,
61
- For,
62
- onCleanup,
63
- onMount,
64
- Show,
65
- } from 'solid-js'
56
+ import { createMemo, createResource, createSignal, For, onCleanup, onMount, Show } from 'solid-js'
66
57
 
67
58
  // ─── Double-load guard (mirrors src/pantheon/plugin-once.ts) ───────────────
68
59
  // Opencode merges global + project plugin paths, so this module can load twice
@@ -919,9 +910,9 @@ async function setupUsageBar(api: TuiPluginApi) {
919
910
  * (filterDelegationsToSession) drops every non-focused report — the panel
920
911
  * lists only the focused session.
921
912
  *
922
- * 3. REFRESH — session.created/updated/deleted/status events and
923
- * message.part.updated/removed (via liveStore.version bumps) re-fetch
924
- * children; a 1s safety poll (oh-my-opencode-slim pattern) re-fetches
913
+ * 3. REFRESH — session.created/updated/deleted/status events and live-store
914
+ * subscription notifications re-fetch children; a 1s safety poll
915
+ * (oh-my-opencode-slim pattern) re-fetches
925
916
  * children + re-reads the md so the panel updates EVEN without events.
926
917
  *
927
918
  * 4. DIAGNOSTICS — every re-fetch logs
@@ -947,8 +938,8 @@ async function setupUsageBar(api: TuiPluginApi) {
947
938
  * panel renders EMPTY — zero rows, zero errors.
948
939
  *
949
940
  * The live tool-part lifecycle helpers below remain (tested, exported) but
950
- * are no longer the source of truth: they feed a version signal that merely
951
- * re-triggers the children fetch. Everything is fail-open: a missing
941
+ * are no longer the source of truth: they update the shared live store, whose
942
+ * subscribers re-trigger the children fetch. Everything is fail-open: a missing
952
943
  * children API or directory yields [], and any unreadable input is skipped —
953
944
  * never crash. */
954
945
 
@@ -2631,18 +2622,88 @@ function DelegationRow(props: {
2631
2622
 
2632
2623
  /* ─── Main Sidebar View ──────────────────────────────────── */
2633
2624
 
2634
- /** Plugin-level live delegation store shared with the event subscriptions
2635
- * in `tui()`: the map of live entries + a version signal bumped on every
2636
- * mutation. The View subscribes to the version (in an effect) to refresh the
2637
- * durable child list and also reads the map as an optimistic live source. */
2625
+ /** Plugin-level live delegation store shared by event subscriptions and View.
2626
+ * Mutations notify subscribers so the View can refresh its durable child
2627
+ * list while also reading the map as an optimistic live source. */
2638
2628
  export type LiveDelegationStore = {
2639
2629
  map: Map<string, LiveDelegationEntry>
2640
- /** Reactive version getter — View reads it inside an effect to re-fetch. */
2641
- version: () => number
2642
- /** Bump the version after a live mutation. */
2630
+ /** Subscribe to invalidations consumed by the sidebar's refresh path. */
2631
+ subscribe: (listener: () => void) => () => void
2632
+ /** Notify sidebar subscribers after a live mutation. */
2643
2633
  bump: () => void
2644
2634
  }
2645
2635
 
2636
+ /** Create the observable live store shared by task events and the sidebar. */
2637
+ export function createLiveDelegationStore(): LiveDelegationStore {
2638
+ const listeners = new Set<() => void>()
2639
+ return {
2640
+ map: new Map<string, LiveDelegationEntry>(),
2641
+ subscribe(listener) {
2642
+ listeners.add(listener)
2643
+ return () => listeners.delete(listener)
2644
+ },
2645
+ bump() {
2646
+ for (const listener of listeners) listener()
2647
+ },
2648
+ }
2649
+ }
2650
+
2651
+ /** Register the live task-part events that invalidate the sidebar store. */
2652
+ export function registerLiveDelegationEvents(
2653
+ api: TuiPluginApi,
2654
+ liveStore: LiveDelegationStore,
2655
+ ): () => void {
2656
+ const unsubLive: (() => void)[] = []
2657
+
2658
+ try {
2659
+ unsubLive.push(
2660
+ api.event.on('message.part.updated', (event: unknown) => {
2661
+ // SDK v2 shape: properties.part (v1 drift: properties.info.part).
2662
+ const props = ((event as { properties?: unknown } | null)?.properties ?? {}) as {
2663
+ part?: unknown
2664
+ info?: { part?: unknown }
2665
+ }
2666
+ const part = (props.part ?? props.info?.part) as DelegationToolPart | undefined
2667
+ if (part === undefined) return
2668
+ // beta.6: track the live tool call per child session (panel's
2669
+ // activity line). Fire-and-forget — display-only state.
2670
+ const sample = extractToolActivity(part as Parameters<typeof extractToolActivity>[0])
2671
+ if (sample !== null)
2672
+ trackToolActivity(latestToolActivity, sample.sessionID, sample.activity)
2673
+ if (reduceDelegationToolPart(liveStore.map, part)) liveStore.bump()
2674
+ }),
2675
+ )
2676
+ } catch {
2677
+ /* events API unavailable — children API + 1s poll cover the panel */
2678
+ }
2679
+
2680
+ try {
2681
+ unsubLive.push(
2682
+ api.event.on('message.part.removed', (event: unknown) => {
2683
+ // SDK v2 shape: properties.partID (v1 drift: properties.part.id).
2684
+ const props = ((event as { properties?: unknown } | null)?.properties ?? {}) as {
2685
+ partID?: string
2686
+ part?: { id?: string }
2687
+ }
2688
+ const partID = props.partID ?? props.part?.id
2689
+ if (partID !== undefined && removeDelegationEntry(liveStore.map, partID)) liveStore.bump()
2690
+ }),
2691
+ )
2692
+ } catch {
2693
+ /* events API unavailable — children API + 1s poll cover the panel */
2694
+ }
2695
+
2696
+ return () => {
2697
+ for (const unsub of unsubLive) {
2698
+ try {
2699
+ unsub()
2700
+ } catch {
2701
+ /* ignore */
2702
+ }
2703
+ }
2704
+ }
2705
+ }
2706
+
2646
2707
  function View(props: {
2647
2708
  api: TuiPluginApi
2648
2709
  sessionID: string | undefined
@@ -2758,7 +2819,7 @@ function View(props: {
2758
2819
  // means the event bus isn't delivering, and the 1s poll is what keeps
2759
2820
  // the panel honest.
2760
2821
  let eventRefreshCount = 0
2761
- // In-flight guard: overlap between the poll, events and the version effect
2822
+ // In-flight guard: overlap between the poll, events and store subscribers
2762
2823
  // collapses into one fetch — no duplicate work, no duplicate entries.
2763
2824
  let delegationsInflight: Promise<void> | null = null
2764
2825
  const refreshDelegations = () => {
@@ -2910,14 +2971,17 @@ function View(props: {
2910
2971
  /* events API not available — the 1s poll still covers it */
2911
2972
  }
2912
2973
 
2913
- // message.part.updated/removed → liveStore.version() bumps (tui()):
2914
- // subscribe here so the panel ALSO re-fetches children when tool-part
2915
- // events DO arrive and the updated live row is rendered immediately.
2916
- createEffect(() => {
2917
- props.liveStore.version() // subscribe to live mutations
2918
- eventRefreshCount += 1
2919
- void refreshDelegations()
2920
- })
2974
+ // Task-part events invalidate the same store the panel reads, refreshing
2975
+ // children when those events arrive and making optimistic live rows visible.
2976
+ cleanup.push(
2977
+ props.liveStore.subscribe(() => {
2978
+ eventRefreshCount += 1
2979
+ void refreshDelegations()
2980
+ }),
2981
+ )
2982
+ // Fetch the initial state; future updates use the store subscription above.
2983
+ eventRefreshCount += 1
2984
+ void refreshDelegations()
2921
2985
 
2922
2986
  // Safety poll (OMO-slim pattern): 1s re-fetch children + md + tick the
2923
2987
  // elapsed counter. Guarantees the panel updates even with zero events.
@@ -2935,8 +2999,8 @@ function View(props: {
2935
2999
  // compacting, so after a compaction/attach the live map would start
2936
3000
  // empty even though the session still holds the delegation tool parts.
2937
3001
  // Re-seed the live map from the session's existing parts (in message
2938
- // order) right after the subscriptions are registered — the version
2939
- // bump re-triggers the children fetch. Fail-open: if the SDK access is
3002
+ // order) right after the subscriptions are registered — the store
3003
+ // notification re-triggers the children fetch. Fail-open: if the SDK access is
2940
3004
  // unavailable we skip — the children API + the 1s poll keep the panel
2941
3005
  // working.
2942
3006
  try {
@@ -3072,61 +3136,18 @@ const tui: TuiPlugin = (api, _options, _meta) => {
3072
3136
  // Vendored feature (MIT): AI subscription usage gauges.
3073
3137
  void setupUsageBar(api) // async init — never blocks sidebar registration
3074
3138
 
3075
- // ── Live delegation store (tool-part tracker, kept as a REFRESH
3076
- // TRIGGER) ──
3139
+ // ── Live delegation store (tool-part tracker + sidebar invalidation) ──
3077
3140
  // The Delegations panel's PRIMARY source is `api.client.session.children`
3078
3141
  // (delegations-sidebar pattern) — `message.part.updated` may not fire for
3079
3142
  // the native task tool on runtime 1.18.13 (the "(0)" symptom). The
3080
- // tool-part lifecycle below still tracks `task` parts and bumps a version
3081
- // signal the View subscribes to: when part events DO arrive, the panel
3143
+ // tool-part lifecycle below still tracks `task` parts and invalidates the
3144
+ // store subscription consumed by the View: when part events DO arrive, the panel
3082
3145
  // re-fetches children. Fail-open: if the events API is unavailable nothing
3083
3146
  // subscribes and the 1s safety poll keeps the panel working (never crash).
3084
- const [liveVersion, setLiveVersion] = createSignal(0)
3085
- const liveStore: LiveDelegationStore = {
3086
- map: new Map<string, LiveDelegationEntry>(),
3087
- version: liveVersion,
3088
- bump: () => setLiveVersion((v) => v + 1),
3089
- }
3090
- const unsubLive: (() => void)[] = []
3091
-
3092
- try {
3093
- unsubLive.push(
3094
- api.event.on('message.part.updated', (event: any) => {
3095
- // SDK v2 shape: properties.part (v1 drift: properties.info.part).
3096
- const props = (event?.properties ?? {}) as { part?: unknown; info?: { part?: unknown } }
3097
- const part = (props.part ?? props.info?.part) as DelegationToolPart | undefined
3098
- if (part === undefined) return
3099
- // beta.6: track the live tool call per child session (panel's
3100
- // activity line). Fire-and-forget — display-only state.
3101
- const sample = extractToolActivity(part as any)
3102
- if (sample !== null)
3103
- trackToolActivity(latestToolActivity, sample.sessionID, sample.activity)
3104
- if (reduceDelegationToolPart(liveStore.map, part)) liveStore.bump()
3105
- }),
3106
- )
3107
- } catch {
3108
- /* events API unavailable — children API + 1s poll cover the panel */
3109
- }
3110
- try {
3111
- unsubLive.push(
3112
- api.event.on('message.part.removed', (event: any) => {
3113
- // SDK v2 shape: properties.partID (v1 drift: properties.part.id).
3114
- const props = (event?.properties ?? {}) as { partID?: string; part?: { id?: string } }
3115
- const partID = props.partID ?? props.part?.id
3116
- if (partID !== undefined && removeDelegationEntry(liveStore.map, partID)) liveStore.bump()
3117
- }),
3118
- )
3119
- } catch {
3120
- /* events API unavailable — children API + 1s poll cover the panel */
3121
- }
3147
+ const liveStore = createLiveDelegationStore()
3148
+ const unsubscribeLive = registerLiveDelegationEvents(api, liveStore)
3122
3149
  api.lifecycle.onDispose(() => {
3123
- for (const unsub of unsubLive) {
3124
- try {
3125
- unsub()
3126
- } catch {
3127
- /* ignore */
3128
- }
3129
- }
3150
+ unsubscribeLive()
3130
3151
  liveStore.map.clear()
3131
3152
  })
3132
3153
 
@@ -0,0 +1,13 @@
1
+ declare module '@opencode/plugin/tui' {
2
+ export const Plugin: {
3
+ define<T>(plugin: T): T
4
+ }
5
+ }
6
+
7
+ declare module '@opencode/plugin' {
8
+ export const Plugin: {
9
+ define<T>(plugin: T): T
10
+ }
11
+ }
12
+
13
+ declare const __PANTHEON_VERSION__: string
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "../../../tsconfig.json",
3
+ "include": ["src"],
4
+ "exclude": ["node_modules", "dist"]
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "//": "Typecheck gate for the V2 TUI entry only. `tsc --noEmit` at the package root was a no-op: with no tsconfig in this directory tsc walked up to the repo tsconfig.json, which excludes src/plugins/tui entirely — so nothing here was checked. tsdown bundles without type-checking, which is how an invalid event name (session.updated, absent from the OpenCode V2 event union) shipped in the V2 rewrite. This config points tsc at the V2 entry plus its ambient declarations so a type error in src/index-v2.tsx fails `npm run typecheck`. The V1 entry (src/index.tsx) is intentionally NOT included: it carries pre-existing type errors out of scope for the V2 gate. Keep this file strict JSON — the repo pre-commit `check-json` hook rejects comments.",
3
+ "extends": "./tsconfig.build.json",
4
+ "include": ["src/index-v2.tsx", "src/opencode-v2.d.ts"]
5
+ }
@@ -1,4 +1,5 @@
1
1
  import { readFileSync } from 'node:fs'
2
+ import { appendFile, readdir, readFile } from 'node:fs/promises'
2
3
  import { join } from 'node:path'
3
4
  import { fileURLToPath } from 'node:url'
4
5
  import solid from 'rolldown-plugin-solid'
@@ -9,13 +10,31 @@ const pkg = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8')) as
9
10
  version: string
10
11
  }
11
12
 
13
+ async function ensureDistArtifactsEndWithNewline(): Promise<void> {
14
+ const dist = join(__dirname, 'dist')
15
+ const entries = await readdir(dist, { withFileTypes: true })
16
+
17
+ await Promise.all(
18
+ entries
19
+ .filter((entry) => entry.isFile())
20
+ .map(async ({ name }) => {
21
+ const path = join(dist, name)
22
+ const contents = await readFile(path, 'utf8')
23
+ if (!contents.endsWith('\n')) await appendFile(path, '\n')
24
+ }),
25
+ )
26
+ }
27
+
12
28
  export default defineConfig({
13
- entry: { tui: 'src/index.tsx', server: 'src/server.ts' },
29
+ entry: { tui: 'src/index.tsx', 'tui-v2': 'src/index-v2.tsx', server: 'src/server.ts' },
14
30
  format: ['esm'],
15
31
  platform: 'node',
16
32
  outDir: 'dist',
17
33
  clean: true,
18
34
  outExtensions: () => ({ js: '.js' }),
35
+ dts: {
36
+ tsconfig: join(__dirname, 'tsconfig.build.json'),
37
+ },
19
38
  define: {
20
39
  __PANTHEON_VERSION__: JSON.stringify(pkg.version),
21
40
  },
@@ -28,6 +47,7 @@ export default defineConfig({
28
47
  }),
29
48
  ],
30
49
  deps: {
31
- neverBundle: [/^@opencode-ai\//, /^@opentui\//, /^solid-js/],
50
+ neverBundle: [/^@opencode-ai\//, /^@opencode\//, /^@opentui\//, /^solid-js/],
32
51
  },
52
+ onSuccess: ensureDistArtifactsEndWithNewline,
33
53
  })
@@ -0,0 +1,2 @@
1
+ // OpenCode V2's CLI loader resolves this root-level TUI entrypoint.
2
+ export { default } from './dist/tui-v2.js'
@@ -0,0 +1,3 @@
1
+ // OpenCode V1 compatibility entrypoint. The V2 installer copies tui-v2.ts as
2
+ // the installed root tui.ts instead.
3
+ export { default } from './dist/tui.js'
package/src/routing.yml CHANGED
@@ -3,7 +3,7 @@ presets:
3
3
  go-free:
4
4
  description: "Free-tier lineup via OpenCode Zen 2026: big-pickle orchestrator, nemotron-3-super-free planner, qwen3.6-plus-free reviewer, deepseek-v4-flash-free implementers, mimo-v2.5-free scouts. Only -free suffix models; quota, availability and pricing depend on Zen account. 2026 pricing verified."
5
5
  vision:
6
- model: opencode/mimo-v2.5-free
6
+ model: opencode/mimo-v2.6-flash-free
7
7
  reasoning_effort: low
8
8
  providers:
9
9
  opencode:
@@ -99,7 +99,6 @@ presets:
99
99
  agents:
100
100
  zeus:
101
101
  role: Central orchestrator
102
- max_steps: 40 # R4: step budget — at max_steps the agent is forced to summarize-and-stop. Tracker is permanent-per-process (no reset wiring).
103
102
  reasoning_effort: medium
104
103
  user_invocable: true
105
104
  can_delegate: true
@@ -137,7 +136,6 @@ agents:
137
136
  - incremental-implementation
138
137
  athena:
139
138
  role: Strategic planner
140
- max_steps: 15 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
141
139
  reasoning_effort: high
142
140
  user_invocable: true
143
141
  can_delegate: true
@@ -157,7 +155,6 @@ agents:
157
155
  - memory-bank
158
156
  apollo:
159
157
  role: Investigation scout
160
- max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
161
158
  reasoning_effort: low
162
159
  user_invocable: false
163
160
  can_delegate: false
@@ -175,7 +172,6 @@ agents:
175
172
  - auto-continue
176
173
  hermes:
177
174
  role: Backend specialist
178
- max_steps: 60 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
179
175
  reasoning_effort: medium
180
176
  user_invocable: true
181
177
  can_delegate: true
@@ -198,7 +194,6 @@ agents:
198
194
  - incremental-implementation
199
195
  aphrodite:
200
196
  role: Frontend specialist
201
- max_steps: 60 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
202
197
  reasoning_effort: medium
203
198
  user_invocable: true
204
199
  can_delegate: false
@@ -219,7 +214,6 @@ agents:
219
214
  - file-prompts
220
215
  demeter:
221
216
  role: Database specialist
222
- max_steps: 50 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
223
217
  reasoning_effort: medium
224
218
  user_invocable: true
225
219
  can_delegate: false
@@ -239,7 +233,6 @@ agents:
239
233
  - incremental-implementation
240
234
  themis:
241
235
  role: Quality gate
242
- max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
243
236
  reasoning_effort: high
244
237
  user_invocable: true
245
238
  can_delegate: false
@@ -261,7 +254,6 @@ agents:
261
254
  - context-compression
262
255
  prometheus:
263
256
  role: Infrastructure specialist
264
- max_steps: 30 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
265
257
  reasoning_effort: medium
266
258
  user_invocable: true
267
259
  can_delegate: false
@@ -280,7 +272,6 @@ agents:
280
272
  - incremental-implementation
281
273
  hephaestus:
282
274
  role: AI pipelines
283
- max_steps: 50 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
284
275
  reasoning_effort: medium
285
276
  user_invocable: true
286
277
  can_delegate: false
@@ -299,7 +290,6 @@ agents:
299
290
  - auto-continue
300
291
  nyx:
301
292
  role: Observability
302
- max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
303
293
  reasoning_effort: low
304
294
  user_invocable: true
305
295
  can_delegate: false
@@ -318,7 +308,6 @@ agents:
318
308
  - auto-continue
319
309
  gaia:
320
310
  role: Remote sensing domain specialist
321
- max_steps: 25 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
322
311
  reasoning_effort: low
323
312
  user_invocable: false
324
313
  can_delegate: false
@@ -333,7 +322,6 @@ agents:
333
322
  - auto-continue
334
323
  iris:
335
324
  role: GitHub operations
336
- max_steps: 20 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
337
325
  reasoning_effort: low
338
326
  user_invocable: true
339
327
  can_delegate: false
@@ -351,7 +339,6 @@ agents:
351
339
  - artifact-management
352
340
  mnemosyne:
353
341
  role: Memory bank
354
- max_steps: 20 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
355
342
  reasoning_effort: low
356
343
  user_invocable: true
357
344
  can_delegate: false
@@ -375,7 +362,6 @@ agents:
375
362
  - session-goal
376
363
  talos:
377
364
  role: Hotfix agent
378
- max_steps: 15 # R4: step budget — at max_steps the agent is forced to summarize-and-stop
379
365
  reasoning_effort: low
380
366
  user_invocable: true
381
367
  can_delegate: false
@@ -473,6 +459,8 @@ handoffs:
473
459
  (priority-aware, budget-allocated), archive IMPL/REVIEW to 02-progress-log.md,
474
460
  update _xref/index.md cross-references.'
475
461
 
462
+ # Canonical explicit fallback map for Zeus timeout/retry policy. Evaluate
463
+ # left-to-right; an absent agent entry means escalate (never guess a fallback).
476
464
  fallback_chains:
477
465
  apollo:
478
466
  - athena
@@ -529,11 +517,10 @@ background_job_board:
529
517
  background_delegation:
530
518
  timeout_ms: 900000 # 15 min
531
519
  poll_ms: 250
532
- max_compaction_items: 10
533
520
  prune_ttl_ms: 86400000 # 24h
534
521
  read_only_agents: [apollo, gaia]
535
522
  session_max: 3
536
- retry_count: 1
523
+ retry_count: 1 # one retry after an initial transient failure; no retry loops
537
524
  # ── O5: permission.task — glob rules for which subagents an agent may
538
525
  # invoke (last matching rule wins; deny removes the agent from the delegate
539
526
  # tool description entirely — prevents circular delegation at the
@@ -566,7 +553,10 @@ hashline:
566
553
  full_auto:
567
554
  enabled: false # opt-in: goal continuations are OFF by default
568
555
  max_continuations: 25 # hard cap on goal continuations per session
569
- # Wave 3 (PR #46): full-auto goal loop. One active goal per session
570
- # (pending → in_progress → done); while active, idle sessions are
571
- # continued automatically toward the objective. Documentation mirror —
572
- # the plugin resolves behavior in code (GOAL_LOOP_DEFAULTS).
556
+ # Full-auto only continues a task/scope explicitly authorized by the user.
557
+ # It never authorizes auth/security gates, risky data/schema or destructive
558
+ # operations, global config, broad permissions, production deploy, push, or merge.
559
+ # Low-risk execution is proportional: no forced plan/discovery/council/artifact
560
+ # for a bounded fix; use focused verification. Documentation mirror — runtime
561
+ # behavior is implemented in the plugin (GOAL_LOOP_DEFAULTS).
562
+ # Wave 3 (PR #46): one active goal per session (pending → in_progress → done).
@@ -23,8 +23,8 @@ There are **20 skills** divided into **5 domains**.
23
23
  - Used by: Zeus, Apollo, Hephaestus, Nyx, Gaia
24
24
 
25
25
  4. **context-compression** — `context-compression/SKILL.md`
26
- - Level 2 — Pantheon-native context compression with priority scoring, semantic summarization, budget allocation, and cross-references.
27
- - Used by: Zeus, Mnemosyne, Themis
26
+ - Native compaction guidance and explicit checkpoint rules; no automatic compression MCP calls.
27
+ - Used by: Zeus, Mnemosyne
28
28
 
29
29
  5. **memory-bank** — `memory-bank/SKILL.md`
30
30
  - Memory bank rules, structure, and optimization — complete guide to Pantheon memory management.
@@ -124,7 +124,7 @@ The `SKILL.md` file contains YAML frontmatter with `name`, `description`, and pl
124
124
  | 1 | agent-coordination | Orchestration & Workflow | Zeus |
125
125
  | 2 | artifact-management | Orchestration & Workflow | Zeus, Mnemosyne, Iris |
126
126
  | 3 | auto-continue | Orchestration & Workflow | Zeus, Apollo, Hephaestus, Nyx, Gaia |
127
- | 4 | context-compression | Orchestration & Workflow | Zeus, Mnemosyne, Themis |
127
+ | 4 | context-compression | Orchestration & Workflow | Zeus, Mnemosyne |
128
128
  | 5 | memory-bank | Orchestration & Workflow | Mnemosyne, Athena |
129
129
  | 6 | session-goal | Orchestration & Workflow | Zeus, Mnemosyne |
130
130
  | 7 | clonedeps | Development Tools | Hermes, Hephaestus |
@@ -34,8 +34,8 @@ Route tasks to optimized agents based on category instead of specifying agents m
34
34
 
35
35
  ```
36
36
  1. User describes feature
37
- 2. @athena creates PLAN with phases and agents
38
- 3. User approves PLAN (GATE 1)
37
+ 2. @athena returns the complete PLAN to Zeus (no approval prompt from the child session)
38
+ 3. Zeus displays the full PLAN in the main conversation, then asks the user to approve it (GATE 1)
39
39
  4. Zeus dispatches agents to phases (parallel when possible)
40
40
  5. Each agent: TDD cycle → writes IMPL artifact
41
41
  6. @themis reviews all phases (GATE 2)
@@ -67,6 +67,11 @@ All phase outputs go to `.pantheon/memory-bank/.tmp/`. See `skill: artifact-mana
67
67
 
68
68
  ## Safety Gates
69
69
 
70
+ For every requested plan, Gate 1 is not satisfied by a child-agent approval
71
+ question or a link to a hidden artifact: the complete plan must be visible in
72
+ the main conversation before Zeus asks for approval. If the user requests
73
+ changes, Zeus presents the complete revised plan and repeats Gate 1.
74
+
70
75
  | Gate | When | Why |
71
76
  |------|------|-----|
72
77
  | **GATE 1** | After PLAN | User confirms scope |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: artifact-management
3
- description: "Structured artifact trail for feature implementations — plans, implementations, reviews, and decisions."
3
+ description: "Structured artifacts for planned, multi-phase, or materially risky implementation work."
4
4
  context: fork
5
5
  globs: []
6
6
  alwaysApply: false
@@ -8,7 +8,7 @@ alwaysApply: false
8
8
 
9
9
  # Artifact Management
10
10
 
11
- Structured artifact trail system for documenting feature implementations. Defines what, where, and how agents produce phase outputs.
11
+ Structured artifact trail for planned, multi-phase, or materially risky implementation work. Artifacts are not a prerequisite for simple fixes or read-only investigation.
12
12
 
13
13
  ---
14
14
 
@@ -55,6 +55,13 @@ All ephemeral artifacts live in `.pantheon/memory-bank/.tmp/` — gitignored and
55
55
 
56
56
  > **Zeus does NOT generate artifacts.** He orchestrates agents that generate them.
57
57
 
58
+ ## Proportional Use
59
+
60
+ - Create PLAN/IMPL/REVIEW artifacts for planned multi-phase work or when risk, auditability, or an explicit request needs a durable phase trail.
61
+ - A bounded, reversible fix should be investigated only as far as needed, implemented, verified with focused checks, and returned as a concise summary. Do not create PLAN, IMPL, or REVIEW artifacts for it.
62
+ - Read-only lookup or trivial discovery needs no DISC artifact; use one only when findings are broad enough to be reused or drive a material decision.
63
+ - The absence of an artifact never waives Themis review or human approval for auth/security, data/schema/migrations, production-impacting work, or sensitive actions.
64
+
58
65
  ---
59
66
 
60
67
  ## Templates
@@ -103,9 +110,9 @@ All ephemeral artifacts live in `.pantheon/memory-bank/.tmp/` — gitignored and
103
110
 
104
111
  ## Human Pause Points
105
112
 
106
- 1. **After PLAN** → user reads `.tmp/PLAN-<feature>.md` and approves
107
- 2. **After REVIEW** → user reads `.tmp/REVIEW-<feature>.md` and validates focus items
108
- 3. **Before git commit** → user executes manually
113
+ 1. **After a required PLAN** → pause only when a material scope/risk decision needs approval.
114
+ 2. **After required REVIEW** → preserve auth/security/data/schema and other sensitive approval gates.
115
+ 3. **Before commit/push/merge/deploy or destructive/global action** → require explicit human approval.
109
116
 
110
117
  ---
111
118