@really-knows-ai/foundry 3.2.1 → 3.2.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.
@@ -143,6 +143,42 @@ 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
+ async function retryUntilReady(fn, opts) {
153
+ const sleep = resolveOpt(opts, 'sleep', defaultSleep);
154
+ const now = resolveOpt(opts, 'now', Date.now);
155
+ const maxMs = resolveOpt(opts, 'maxMs', 30000);
156
+ const deadline = now() + maxMs;
157
+ while (now() < deadline) {
158
+ try {
159
+ await fn();
160
+ return;
161
+ } catch {
162
+ await sleep(500);
163
+ }
164
+ }
165
+ }
166
+
167
+ async function showStartupMessage(needsRestart, directory, client, timerFns) {
168
+ if (!client) return;
169
+ if (needsRestart) {
170
+ await retryUntilReady(() => client.tui.appendPrompt({
171
+ body: { text: 'Foundry initialised. Restart OpenCode so the Foundry agent registers, then switch to it to author and run workflows.' },
172
+ }), timerFns);
173
+ return;
174
+ }
175
+ if (existsSync(path.join(directory, 'foundry'))) {
176
+ await retryUntilReady(() => client.tui.showToast({
177
+ body: { message: 'Foundry is active', variant: 'info' },
178
+ }), timerFns);
179
+ }
180
+ }
181
+
146
182
  export { buildCyclePromptExtras } from './foundry-tools/helpers.js';
147
183
 
148
184
  function buildTools(createTool, pending) {
@@ -179,7 +215,7 @@ function getFirstUserWithParts(output) {
179
215
  return firstUser;
180
216
  }
181
217
 
182
- export const FoundryPlugin = async ({ directory }) => {
218
+ export const FoundryPlugin = async ({ directory, client }) => {
183
219
  // Pending store is per-plugin-instance (shared across all tool invocations).
184
220
  const pending = createPendingStore();
185
221
 
@@ -194,6 +230,7 @@ export const FoundryPlugin = async ({ directory }) => {
194
230
  }
195
231
 
196
232
  restartNeeded = runPluginBootstrap(directory, packageRoot);
233
+ await showStartupMessage(restartNeeded, directory, client);
197
234
  },
198
235
 
199
236
  'experimental.chat.messages.transform': async (_input, output) => {
package/dist/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.2.2] - 2026-05-14
4
+
5
+ ### Added
6
+
7
+ - **Immediate startup feedback via TUI.** Instead of waiting for the first
8
+ user prompt to inject the Foundry context message, the config hook now
9
+ shows feedback immediately. When a restart is needed, the message is
10
+ appended directly to the prompt bar via `client.tui.appendPrompt`. When
11
+ Foundry is already active, a non-intrusive toast notification confirms
12
+ readiness via `client.tui.showToast`. The `messages.transform` hook
13
+ remains as a fallback for AI context injection.
14
+ - **Injectable timer for startup retry logic.** `retryUntilReady` accepts
15
+ injectable `sleep`, `now`, and `maxMs` functions so tests can control
16
+ timing without real delays. `showStartupMessage` bails early when the
17
+ TUI client is unavailable to avoid hanging in environments without a
18
+ client.
19
+
3
20
  ## [3.2.1] - 2026-05-14
4
21
 
5
22
  ### 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.2",
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",