pantheon-opencode 1.5.2 → 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 (146) 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/AGENTS.global.md +182 -0
  6. package/AGENTS.md +10 -891
  7. package/CHANGELOG.md +343 -0
  8. package/README.md +577 -79
  9. package/README.pt-BR.md +345 -60
  10. package/bin/pantheon-init.mjs +26 -3
  11. package/commands/pantheon-audit.md +7 -1
  12. package/commands/pantheon-consolidate.md +1 -1
  13. package/commands/pantheon-deepwork.md +14 -3
  14. package/commands/pantheon-focus.md +17 -0
  15. package/commands/pantheon-optimize.md +2 -2
  16. package/commands/pantheon-vision.md +61 -12
  17. package/package.json +30 -11
  18. package/plugin.json +2 -2
  19. package/pyproject.toml +11 -16
  20. package/scripts/build-agents-md.mjs +376 -58
  21. package/scripts/changelog-merge.mjs +161 -0
  22. package/scripts/check-plugin-v2-coverage.mjs +213 -0
  23. package/scripts/ci-validate-yaml.py +7 -5
  24. package/scripts/{code_mode_server.py → code_mode.py} +119 -27
  25. package/scripts/cost.mjs +244 -41
  26. package/scripts/doctor.mjs +236 -29
  27. package/scripts/install/agents-md.mjs +4 -4
  28. package/scripts/install/cli-ui.mjs +1 -1
  29. package/scripts/install/config-migration.mjs +319 -6
  30. package/scripts/install/health-check.mjs +26 -37
  31. package/scripts/install/interactive.mjs +7 -7
  32. package/scripts/install/migrate.mjs +1 -1
  33. package/scripts/install/opencode-version.mjs +246 -4
  34. package/scripts/install/opencode.mjs +627 -179
  35. package/scripts/install/plugin.mjs +43 -9
  36. package/scripts/install/shared.mjs +120 -12
  37. package/scripts/install/vision-prompt.mjs +161 -0
  38. package/scripts/install-mcp.mjs +28 -9
  39. package/scripts/{mcp_persistence_server.py → mcp_persistence.py} +392 -78
  40. package/{src/mcp/mcp_resources_server.py → scripts/mcp_resources.py} +2 -2
  41. package/scripts/{memory_mcp_server.py → memory_mcp.py} +372 -198
  42. package/scripts/postinstall.mjs +0 -7
  43. package/scripts/probe-context-rehydrate.mjs +36 -13
  44. package/scripts/probe-pantheon-cost.mjs +71 -15
  45. package/scripts/prune.mjs +2 -2
  46. package/scripts/run-node-tests.mjs +189 -0
  47. package/scripts/sync-artifacts.mjs +26 -13
  48. package/scripts/sync-tui.mjs +24 -3
  49. package/scripts/test-opencode-v2-sandbox.sh +1913 -0
  50. package/scripts/validate-routing.mjs +43 -3
  51. package/scripts/validate-sandbox-install.mjs +138 -0
  52. package/scripts/versioning.mjs +13 -1
  53. package/scripts/vision-status.mjs +682 -0
  54. package/skills-lock.json +15 -16
  55. package/src/agents/aphrodite.md +20 -37
  56. package/src/agents/apollo.md +7 -3
  57. package/src/agents/athena.md +63 -35
  58. package/src/agents/demeter.md +8 -28
  59. package/src/agents/gaia.md +1 -1
  60. package/src/agents/hephaestus.md +10 -21
  61. package/src/agents/hermes.md +15 -38
  62. package/src/agents/iris.md +1 -1
  63. package/src/agents/mnemosyne.md +23 -60
  64. package/src/agents/nyx.md +1 -1
  65. package/src/agents/prometheus.md +16 -20
  66. package/src/agents/talos.md +10 -2
  67. package/src/agents/themis.md +5 -5
  68. package/src/agents/zeus.md +99 -130
  69. package/src/instructions/agent-return-format.instructions.md +18 -3
  70. package/src/instructions/backend-standards.instructions.md +2 -0
  71. package/src/instructions/frontend-standards.instructions.md +3 -1
  72. package/src/instructions/memory-protocol.instructions.md +11 -110
  73. package/src/instructions/zeus-anti-stall.instructions.md +14 -61
  74. package/src/instructions/zeus-communication-rules.instructions.md +0 -1
  75. package/src/instructions/zeus-council-synthesis.instructions.md +32 -260
  76. package/src/instructions/zeus-memory-operations.instructions.md +26 -0
  77. package/src/instructions/zeus-timeout-retry.instructions.md +40 -87
  78. package/src/mcp/{code_mode_server.py → code_mode.py} +119 -27
  79. package/src/mcp/eval_store.py +2 -2
  80. package/src/mcp/mcp_codemap_module.py +559 -129
  81. package/src/mcp/{mcp_persistence_server.py → mcp_persistence.py} +392 -78
  82. package/{scripts/mcp_resources_server.py → src/mcp/mcp_resources.py} +2 -2
  83. package/src/mcp/{memory_mcp_server.py → memory_mcp.py} +373 -250
  84. package/src/mcp/{pantheon_vision_server.py → pantheon_vision.py} +396 -40
  85. package/src/mcp/requirements-mcp.txt +10 -6
  86. package/src/mcp/requirements-vision.txt +4 -2
  87. package/src/pantheon/cost-command.ts +399 -101
  88. package/src/pantheon/delegation-enforce.ts +10 -1
  89. package/src/pantheon/model-command.ts +18 -7
  90. package/src/pantheon/presets.d.mts +0 -8
  91. package/src/pantheon/presets.mjs +5 -32
  92. package/src/pantheon/todo-enforcer.ts +1 -1
  93. package/src/pantheon/v2-bounded-read.ts +640 -0
  94. package/src/pantheon/v2-delegation-enforce.ts +214 -0
  95. package/src/pantheon/v2-execute-after.ts +186 -0
  96. package/src/pantheon/v2-tools.ts +429 -0
  97. package/src/pantheon/v2-unsupported.d.mts +11 -0
  98. package/src/pantheon/v2-unsupported.mjs +90 -0
  99. package/src/pantheon/v2-vision.ts +622 -0
  100. package/src/pantheon/vision-local.ts +531 -0
  101. package/src/pantheon/vision.ts +1161 -116
  102. package/src/plugin-v2.ts +1244 -288
  103. package/src/plugin.ts +12 -9
  104. package/src/plugins/tui/dist/server.d.ts +1 -2
  105. package/src/plugins/tui/dist/server.d.ts.map +1 -1
  106. package/src/plugins/tui/dist/tui-v2.d.ts +154 -0
  107. package/src/plugins/tui/dist/tui-v2.d.ts.map +1 -0
  108. package/src/plugins/tui/dist/tui-v2.js +659 -0
  109. package/src/plugins/tui/dist/tui-v2.js.map +1 -0
  110. package/src/plugins/tui/dist/tui.d.ts +85 -82
  111. package/src/plugins/tui/dist/tui.d.ts.map +1 -1
  112. package/src/plugins/tui/dist/tui.js +72 -59
  113. package/src/plugins/tui/index-v2.ts +6 -0
  114. package/src/plugins/tui/package-lock.json +5504 -1341
  115. package/src/plugins/tui/package.json +25 -15
  116. package/src/plugins/tui/src/index-v2.tsx +734 -0
  117. package/src/plugins/tui/src/index.tsx +106 -85
  118. package/src/plugins/tui/src/opencode-v2.d.ts +13 -0
  119. package/src/plugins/tui/tsconfig.build.json +5 -0
  120. package/src/plugins/tui/tsconfig.typecheck.json +5 -0
  121. package/src/plugins/tui/tsdown.config.ts +22 -2
  122. package/src/plugins/tui/tui-v2.ts +2 -0
  123. package/src/plugins/tui/tui.ts +3 -0
  124. package/src/routing.yml +11 -22
  125. package/src/skills/README.md +34 -39
  126. package/src/skills/agent-coordination/SKILL.md +7 -2
  127. package/src/skills/artifact-management/SKILL.md +12 -5
  128. package/src/skills/auto-continue/SKILL.md +54 -95
  129. package/src/skills/code-review-checklist/SKILL.md +5 -5
  130. package/src/skills/context-compression/SKILL.md +26 -879
  131. package/src/skills/session-goal/SKILL.md +14 -5
  132. package/src/skills/spec-driven-development/SKILL.md +3 -1
  133. package/src/skills/tdd-with-agents/SKILL.md +18 -10
  134. package/.pantheon/code-mode/eval-llm-judge.py +0 -255
  135. package/.pantheon/code-mode/eval-monte-carlo.py +0 -368
  136. package/.pantheon/code-mode/eval-run.py +0 -197
  137. package/.pantheon/code-mode/eval-static.py +0 -321
  138. package/.pantheon/code-mode/session-end-save.py +0 -186
  139. package/.pantheon/code-mode/session-end-save.sh +0 -18
  140. package/opencode.json +0 -58
  141. package/scripts/recover-zenodo-deposition.mjs +0 -146
  142. package/scripts/test-opencode-v1-v2-sandbox.sh +0 -862
  143. package/scripts/validate-zenodo-release.mjs +0 -154
  144. package/scripts/zenodo-artifact.mjs +0 -94
  145. package/scripts/zenodo-release-state.mjs +0 -53
  146. package/src/skills/orchestration-workflow/SKILL.md +0 -311
package/src/plugin.ts CHANGED
@@ -238,15 +238,18 @@ function adaptTodoEnforcerClient(client: PluginInput['client']): TodoEnforcerCli
238
238
 
239
239
  /**
240
240
  * Pantheon plugin for OpenCode. Pasted images are intercepted via the
241
- * `chat.message` hook (proven to fire in opencode 1.18.11). When a provider
242
- * key is available — env PANTHEON_OPENCODE_API_KEY / OPENCODE_API_KEY, or the
243
- * opencode auth store for `opencode auth login` users — the image is
244
- * described NATIVELY by the multimodal model via the opencode Zen
245
- * OpenAI-compatible endpoint, and replaced with the text description — no MCP
246
- * tool required. Without a key the legacy pattern applies: the image is
247
- * replaced with a text instruction telling the model to call a vision MCP tool
248
- * (default `pantheon_vision_vision_describe`). Either way the image never reaches
249
- * the main provider, so text-only models cannot fail with an `image_url` error.
241
+ * `chat.message` hook (proven to fire in opencode 1.18.11). Credentials follow
242
+ * the endpoint: a Zen endpoint (`opencode` / `opencode-go*`) may use the shared
243
+ * `PANTHEON_OPENCODE_API_KEY` / `OPENCODE_API_KEY` env keys and the legacy
244
+ * `opencode-go` / `opencode` auth-store entries, while a non-Zen endpoint uses
245
+ * ONLY its own auth-store entry (never the Zen env keys or legacy entries).
246
+ * When a credential is available the image is described NATIVELY by the
247
+ * multimodal model via the endpoint's OpenAI-compatible API, and replaced with
248
+ * the text description — no MCP tool required. Without a credential the legacy
249
+ * pattern applies: the image is replaced with a text instruction telling the
250
+ * model to call a vision MCP tool (default `pantheon_vision_vision_describe`).
251
+ * Either way the image never reaches the main provider, so text-only models
252
+ * cannot fail with an `image_url` error.
250
253
  *
251
254
  * The canonical `pantheon-vision` MCP owns the standalone describe/OCR/analyze
252
255
  * tools. The installed OpenCode plugin API exposes no stable pre-provider
@@ -11,7 +11,6 @@
11
11
  * This stub satisfies the loader contract; pantheon-tui is TUI-only and has
12
12
  * no background server work of its own.
13
13
  */
14
- declare function server(): {};
14
+ export default function server(): {};
15
15
  //#endregion
16
- export { server as default };
17
16
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","names":[],"sources":["../src/server.ts"],"mappings":";;;;;;;;;;;;;iBAYwB"}
1
+ {"version":3,"file":"server.d.ts","names":[],"sources":["../src/server.ts"],"mappings":";;;;;;;;;;;;;wBAYwB"}
@@ -0,0 +1,154 @@
1
+ import { Accessor } from "solid-js";
2
+ import { Context } from "@opencode/plugin/tui/context";
3
+ //#region src/index-v2.d.ts
4
+ /** Running delegations rendered before the "… +N more" line (V1 parity). */
5
+ export declare const DELEGATIONS_VISIBLE_CEILING = 8;
6
+ /** Sidebar body shown while the host has not published a session yet. */
7
+ export declare const SIDEBAR_WAITING_LABEL = "Aguardando sessão…";
8
+ /** One event name the host publishes on `data.on` — the OpenCode V2 union. */
9
+ export type SidebarDataEvent = Parameters<Context['data']['on']>[0];
10
+ /** V2 events that refresh the sidebar. V1 also listened to `session.updated`,
11
+ * but that name is absent from the OpenCode V2 event union (verified against
12
+ * `@opencode/client`'s `OpenCodeEvent`), so the valid events that carry the
13
+ * same state changes are used instead: `session.renamed` /
14
+ * `session.metadata.updated` / `session.moved` (the mutations `session.updated`
15
+ * used to stand for) and `session.idle` (a child finishing). `satisfies` keeps
16
+ * the literals while making a name outside the union a type error (surfaced by
17
+ * `tsc -p tsconfig.build.json`), and the sidebar test asserts the same names
18
+ * against the installed union at runtime. */
19
+ export declare const SIDEBAR_REFRESH_EVENTS: readonly ["session.created", "session.renamed", "session.metadata.updated", "session.moved", "session.idle", "session.status", "session.deleted"];
20
+ export type PresetInfo = {
21
+ name: string | null;
22
+ source: 'env' | 'file' | null;
23
+ };
24
+ /** Env leg of resolution: PANTHEON_MODEL_PRESET set and !== 'none' wins. */
25
+ export declare function presetFromEnv(env: Record<string, string | undefined>): PresetInfo;
26
+ /** Resolve the active preset for the sidebar: env > file > default. */
27
+ export declare function resolvePresetForTui(env: Record<string, string | undefined>, cwd: string): Promise<PresetInfo>;
28
+ /** `SessionInfo.id` is always a `ses…` handle. Guarded so a placeholder or a
29
+ * foreign id never reaches the status/navigate APIs. */
30
+ export declare function isValidSessionID(id: unknown): id is string;
31
+ export type DelegationState = 'running' | 'completed' | 'failed' | 'interrupted';
32
+ export type DelegationTone = 'warning' | 'error' | 'success';
33
+ /** Grace window for a child that has not started yet. V2's `session.status()`
34
+ * returns `idle` both for "created but not started" and for "finished", so an
35
+ * idle/unknown/absent child whose own last activity (`time.updated`, falling
36
+ * back to `time.created`) is this recent still reads as running — otherwise a
37
+ * just-spawned child renders a premature ✓. Trade-off (V1 parity: it had the
38
+ * same window for its absent statuses): a child that finished within the window
39
+ * and reports no `outcome` reads as running until the window closes, at which
40
+ * point it turns terminal and its completion toast fires. A child that reports
41
+ * a terminal `outcome` is never held back by the window. */
42
+ export declare const DELEGATION_CHILD_STATUS_GRACE_MS: number;
43
+ /** One delegated child job as the sidebar renders it. */
44
+ export type DelegationView = {
45
+ /** Child session id — also the click-through target. */
46
+ id: string;
47
+ /** Alias shown on the row: the child title, else agent, else short id. */
48
+ label: string;
49
+ state: DelegationState;
50
+ /** Epoch ms of the child's `time.created`. */
51
+ startedAt: number | null;
52
+ /** Epoch ms of the child's `time.updated`. */
53
+ updatedAt: number | null;
54
+ };
55
+ /** Map the host's live session status to a display state. V2 exposes only
56
+ * `"idle" | "running"` through the TUI context (the client union adds `retry`
57
+ * and `busy`); `error`/`failed` are handled defensively for host drift.
58
+ * `idle`, `retry` and unknown/absent statuses are terminal only once the
59
+ * child's own activity is older than the grace window — within it the child
60
+ * reads as running (see `DELEGATION_CHILD_STATUS_GRACE_MS`). An interruption is
61
+ * not part of this union: it arrives as a terminal `outcome`. Pure. */
62
+ export declare function delegationStateFromStatus(status: string | undefined, time?: {
63
+ created?: number;
64
+ updated?: number;
65
+ }, now?: number, graceMs?: number): DelegationState;
66
+ /** Map a V2 child `outcome` to a display state. `interrupted` (user abort,
67
+ * shutdown, superseded, inactivity) is distinct from both success and failure,
68
+ * so an aborted child never renders the ✓ of a completed one. Returns null for
69
+ * an absent/unrecognised outcome so the live status decides. Pure. */
70
+ export declare function delegationStateFromOutcome(outcome: unknown): DelegationState | null;
71
+ /** Build a delegation row from a child session + its live status. A terminal
72
+ * `outcome` wins when present (the only V2 primitive that surfaces a
73
+ * delegation failure/interruption once the status is back to idle); otherwise
74
+ * the live status decides, with the absent/idle grace window applied. Pure. */
75
+ export declare function toDelegationView(child: any, status: string | undefined, now?: number): DelegationView;
76
+ /** Whole-row tone: red = failed, green = terminal, yellow = in flight. The
77
+ * glyph stays a redundant channel so the state reads in monochrome. Pure. */
78
+ export declare function delegationStateTone(state: DelegationState): DelegationTone;
79
+ /** Spinner glyph for a frame counter (incremented every ~80ms while any job is
80
+ * running). Pure. */
81
+ export declare function spinnerFrame(frame: number): string;
82
+ /** Row marker (`<glyph> `): the animated spinner while running, ✓ when done,
83
+ * ⊘ when interrupted, ✕ on failure. Pure. */
84
+ export declare function delegationRowMarker(state: DelegationState, frame?: number): string;
85
+ /** Compact single-unit elapsed label: "12s"/"3m"/"1h"/"2d". Pure. */
86
+ export declare function fmtElapsed(ms: number): string;
87
+ /** Elapsed label for one row: a running job ticks `now - startedAt`; a terminal
88
+ * one is fixed at `updatedAt - startedAt` (em dash when a timestamp is
89
+ * missing). Pure. */
90
+ export declare function delegationElapsed(view: DelegationView, now: number): string;
91
+ /** Live rows first (a running job never falls behind the cap), then by most
92
+ * recent activity. Pure. */
93
+ export declare function orderDelegations(views: readonly DelegationView[]): DelegationView[];
94
+ /** Cap the panel: at most `maxVisible` rows, the remainder collapsing into the
95
+ * "… +N more" line. Pure. */
96
+ export declare function ceilingDelegations(views: readonly DelegationView[], maxVisible?: number): {
97
+ visible: DelegationView[];
98
+ hidden: number;
99
+ };
100
+ /** Session ids to eagerly sync at load (deduped, bounded). Pure. */
101
+ export declare function collectWarmupTargets(sessions: readonly any[], limit?: number): string[];
102
+ /** Body a sidebar instance renders when the host has not published a real
103
+ * session id yet. OpenCode V2 scopes the `sidebar.content` slot to a session
104
+ * (`SlotMap["sidebar.content"] = { sessionID: string }`), so before the first
105
+ * prompt the slot may not mount at all — see the `home.footer.status`
106
+ * contribution for the pre-prompt degradation. Pure. */
107
+ export declare function sidebarPlaceholder(sessionID: string | undefined): string | null;
108
+ /** Navigate to a session through the V2 router. Fail-open: an absent router or
109
+ * a removed session must never break the sidebar. Returns whether a valid
110
+ * navigation was dispatched. Pure. */
111
+ export declare function navigateToSession(router: {
112
+ navigate?: (destination: any) => void;
113
+ } | undefined, sessionID: string | undefined): boolean;
114
+ export type DelegationCompletion = {
115
+ id: string;
116
+ label: string;
117
+ state: DelegationState;
118
+ };
119
+ /** Diff two delegation observations: entries that were `running` and are no
120
+ * longer running count as completions, fired once per transition. Returns the
121
+ * next snapshot so callers can keep a single tracker. First observation never
122
+ * reports a completion (no toast spam on mount). Pure. */
123
+ export declare function detectDelegationCompletions(previous: ReadonlyMap<string, DelegationState>, current: ReadonlyArray<DelegationCompletion>): {
124
+ completed: DelegationCompletion[];
125
+ snapshot: Map<string, DelegationState>;
126
+ };
127
+ /** Reactive state the sidebar view renders. Accessors keep the view reactive
128
+ * while the model itself stays free of JSX, so its effects are exercisable
129
+ * without a TUI renderer. */
130
+ export type SidebarModel = {
131
+ activeSessionID: Accessor<string>;
132
+ session: Accessor<any>;
133
+ branch: Accessor<string | null>;
134
+ delegations: Accessor<DelegationView[]>;
135
+ ceiling: Accessor<{
136
+ visible: DelegationView[];
137
+ hidden: number;
138
+ }>;
139
+ hasRunning: Accessor<boolean>;
140
+ frame: Accessor<number>;
141
+ preset: Accessor<PresetInfo>;
142
+ };
143
+ /** Reactive wiring behind the sidebar: refresh subscription, warm syncs, the
144
+ * running-only spinner and the completion-toast effect. `context` stays loosely
145
+ * typed (the host API only exists at runtime) but the refresh event names are
146
+ * narrowed to the V2 union at the subscription site. */
147
+ export declare function createSidebarModel(context: any, sessionID: () => string | undefined): SidebarModel;
148
+ declare const plugin: {
149
+ id: string;
150
+ setup(context: Context): (() => void) | undefined;
151
+ };
152
+ //#endregion
153
+ export { plugin as default };
154
+ //# sourceMappingURL=tui-v2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-v2.d.ts","names":[],"sources":["../src/index-v2.tsx"],"mappings":";;;;qBAoBa;;qBAMA;;YAID,mBAAmB,WAAW;;;;;;;;;;qBAU7B;YAmBD;EAAe;EAAqB;;;wBAgChC,cAAc,KAAK,qCAAqC;;wBASlD,oBACpB,KAAK,oCACL,cACC,QAAQ;;;wBAUK,iBAAiB,cAAc;YAUnC;YACA;;;;;;;;;;qBAWC;;YAGD;;EAEV;;EAEA;EACA,OAAO;;EAEP;;EAEA;;;;;;;;;wBAUc,0BACd,4BACA;EAAS;EAAkB;GAC3B,cACA,mBACC;;;;;wBAoBa,2BAA2B,mBAAmB;;;;;wBAiB9C,iBACd,YACA,4BACA,eACC;;;wBA0Ba,oBAAoB,OAAO,kBAAkB;;;wBAQ7C,aAAa;;;wBAOb,oBAAoB,OAAO,iBAAiB;;wBAQ5C,WAAW;;;;wBAeX,kBAAkB,MAAM,gBAAgB;;;wBAWxC,iBAAiB,gBAAgB,mBAAmB;;;wBAWpD,mBACd,gBAAgB,kBAChB;EACG,SAAS;EAAkB;;;wBAOhB,qBACd,0BACA;;;;;;wBAkBc,mBAAmB;;;;wBASnB,kBACd;EAAU,YAAY;eACtB;YAaU;EAAyB;EAAY;EAAe,OAAO;;;;;;wBAMvD,4BACd,UAAU,oBAAoB,kBAC9B,SAAS,cAAc;EACpB,WAAW;EAAwB,UAAU,YAAY;;;;;YA6GlD;EACV,iBAAiB;EACjB,SAAS;EACT,QAAQ;EACR,aAAa,SAAS;EACtB,SAAS;IAAW,SAAS;IAAkB;;EAC/C,YAAY;EACZ,OAAO;EACP,QAAQ,SAAS;;;;;;wBAOH,mBACd,cACA,sCACC;cAgOG;;EAEW,MAAA,SAAA"}