@really-knows-ai/foundry 3.2.1 → 3.2.3

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.
@@ -143,6 +143,44 @@ function runPluginBootstrap(worktree, pkgRoot) {
143
143
  }
144
144
  }
145
145
 
146
+ const defaultSleep = ms => new Promise(resolve => { setTimeout(resolve, ms); });
147
+
148
+ function resolveOpt(opts, key, fallback) {
149
+ return (opts && opts[key] !== undefined) ? opts[key] : fallback;
150
+ }
151
+
152
+ const STARTUP_MSG_MAX_MS = 3000;
153
+
154
+ async function retryUntilReady(fn, opts) {
155
+ const sleep = resolveOpt(opts, 'sleep', defaultSleep);
156
+ const now = resolveOpt(opts, 'now', Date.now);
157
+ const maxMs = resolveOpt(opts, 'maxMs', STARTUP_MSG_MAX_MS);
158
+ const deadline = now() + maxMs;
159
+ while (now() < deadline) {
160
+ try {
161
+ await fn();
162
+ return;
163
+ } catch {
164
+ await sleep(500);
165
+ }
166
+ }
167
+ }
168
+
169
+ async function showStartupMessage(needsRestart, directory, client, timerFns) {
170
+ if (!client) return;
171
+ if (needsRestart) {
172
+ await retryUntilReady(() => client.tui.appendPrompt({
173
+ body: { text: 'Foundry initialised. Restart OpenCode so the Foundry agent registers, then switch to it to author and run workflows.' },
174
+ }), timerFns);
175
+ return;
176
+ }
177
+ if (existsSync(path.join(directory, 'foundry'))) {
178
+ await retryUntilReady(() => client.tui.showToast({
179
+ body: { message: 'Foundry is active', variant: 'info' },
180
+ }), timerFns);
181
+ }
182
+ }
183
+
146
184
  export { buildCyclePromptExtras } from './foundry-tools/helpers.js';
147
185
 
148
186
  function buildTools(createTool, pending) {
@@ -179,7 +217,7 @@ function getFirstUserWithParts(output) {
179
217
  return firstUser;
180
218
  }
181
219
 
182
- export const FoundryPlugin = async ({ directory }) => {
220
+ export const FoundryPlugin = async ({ directory, client }) => {
183
221
  // Pending store is per-plugin-instance (shared across all tool invocations).
184
222
  const pending = createPendingStore();
185
223
 
@@ -194,6 +232,8 @@ export const FoundryPlugin = async ({ directory }) => {
194
232
  }
195
233
 
196
234
  restartNeeded = runPluginBootstrap(directory, packageRoot);
235
+ // Fire-and-forget: don't block startup. messages.transform is the fallback.
236
+ showStartupMessage(restartNeeded, directory, client);
197
237
  },
198
238
 
199
239
  'experimental.chat.messages.transform': async (_input, output) => {
package/dist/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.2.3] - 2026-05-14
4
+
5
+ ### Fixed
6
+
7
+ - **Config hook blocked startup waiting for TUI client.** `showStartupMessage`
8
+ was awaited in the config hook, and its `retryUntilReady` loop could block
9
+ opencode startup for up to 30 seconds if the TUI client wasn't immediately
10
+ available. The call is now fire-and-forget: the config hook returns
11
+ immediately, and the message either shows within the 3-second retry window
12
+ or falls back to the `messages.transform` hook.
13
+
14
+ ## [3.2.2] - 2026-05-14
15
+
16
+ ### Added
17
+
18
+ - **Immediate startup feedback via TUI.** Instead of waiting for the first
19
+ user prompt to inject the Foundry context message, the config hook now
20
+ shows feedback immediately. When a restart is needed, the message is
21
+ appended directly to the prompt bar via `client.tui.appendPrompt`. When
22
+ Foundry is already active, a non-intrusive toast notification confirms
23
+ readiness via `client.tui.showToast`. The `messages.transform` hook
24
+ remains as a fallback for AI context injection.
25
+ - **Injectable timer for startup retry logic.** `retryUntilReady` accepts
26
+ injectable `sleep`, `now`, and `maxMs` functions so tests can control
27
+ timing without real delays. `showStartupMessage` bails early when the
28
+ TUI client is unavailable to avoid hanging in environments without a
29
+ client.
30
+
3
31
  ## [3.2.1] - 2026-05-14
4
32
 
5
33
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@really-knows-ai/foundry",
3
- "version": "3.2.1",
3
+ "version": "3.2.3",
4
4
  "description": "A skill-driven framework for governed artefact generation with AI coding tools. Define your own artefact types, laws, and flows — Foundry handles the forge → quench → appraise pipeline with deterministic routing, quality gates, and iterative refinement.",
5
5
  "type": "module",
6
6
  "main": "dist/.opencode/plugins/foundry.js",