@really-knows-ai/foundry 3.2.2 → 3.2.4

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.
@@ -36,8 +36,18 @@ import { createSnapshotTools } from './foundry-tools/snapshot-tools.js';
36
36
  import { createAttestationTools } from './foundry-tools/attestation-tools.js';
37
37
  import { createRefreshAgentsTool } from './foundry-tools/refresh-agents-tool.js';
38
38
 
39
+ function findPackageRoot(startDir) {
40
+ let dir = startDir;
41
+ const root = path.parse(dir).root;
42
+ while (dir !== root) {
43
+ if (existsSync(path.join(dir, 'package.json'))) return dir;
44
+ dir = path.dirname(dir);
45
+ }
46
+ return startDir;
47
+ }
48
+
39
49
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
40
- const packageRoot = path.resolve(__dirname, '../..');
50
+ const packageRoot = findPackageRoot(__dirname);
41
51
  const allSkillsDir = path.join(packageRoot, 'skills');
42
52
 
43
53
  // Module-level flag shared between config and message-transform hooks.
@@ -149,10 +159,12 @@ function resolveOpt(opts, key, fallback) {
149
159
  return (opts && opts[key] !== undefined) ? opts[key] : fallback;
150
160
  }
151
161
 
162
+ const STARTUP_MSG_MAX_MS = 3000;
163
+
152
164
  async function retryUntilReady(fn, opts) {
153
165
  const sleep = resolveOpt(opts, 'sleep', defaultSleep);
154
166
  const now = resolveOpt(opts, 'now', Date.now);
155
- const maxMs = resolveOpt(opts, 'maxMs', 30000);
167
+ const maxMs = resolveOpt(opts, 'maxMs', STARTUP_MSG_MAX_MS);
156
168
  const deadline = now() + maxMs;
157
169
  while (now() < deadline) {
158
170
  try {
@@ -230,7 +242,8 @@ export const FoundryPlugin = async ({ directory, client }) => {
230
242
  }
231
243
 
232
244
  restartNeeded = runPluginBootstrap(directory, packageRoot);
233
- await showStartupMessage(restartNeeded, directory, client);
245
+ // Fire-and-forget: don't block startup. messages.transform is the fallback.
246
+ showStartupMessage(restartNeeded, directory, client);
234
247
  },
235
248
 
236
249
  'experimental.chat.messages.transform': async (_input, output) => {
package/dist/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.2.4] - 2026-05-14
4
+
5
+ ### Fixed
6
+
7
+ - **Bootstrap error in cached npm installs.** The `packageRoot` was resolved
8
+ from `__dirname` using a hardcoded relative path (`../..`) that only worked
9
+ in the source tree. In the dist tree (`dist/.opencode/plugins/`), the same
10
+ path resolved to `dist/` instead of the package root, causing
11
+ `ENOENT: package.json` errors. The resolution now walks up from `__dirname`
12
+ until it finds `package.json`.
13
+
14
+ ## [3.2.3] - 2026-05-14
15
+
16
+ ### Fixed
17
+
18
+ - **Config hook blocked startup waiting for TUI client.** `showStartupMessage`
19
+ was awaited in the config hook, and its `retryUntilReady` loop could block
20
+ opencode startup for up to 30 seconds if the TUI client wasn't immediately
21
+ available. The call is now fire-and-forget: the config hook returns
22
+ immediately, and the message either shows within the 3-second retry window
23
+ or falls back to the `messages.transform` hook.
24
+
3
25
  ## [3.2.2] - 2026-05-14
4
26
 
5
27
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@really-knows-ai/foundry",
3
- "version": "3.2.2",
3
+ "version": "3.2.4",
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",