ReviewOS

also looking at this

stacks/uplink

docs: add an uplink-conventions skill

#41
Merged glennmichael123 wants to merge docs/uplink-conventions-skill into main
2 files +157 -0
9 days ago

Chris asked for the review feedback to be written as a skill rather than left in one agent's head, so it reaches the next agent too. Related: #40.

Why a skill and not just a note

Both corrections in the feedback are right, and the obvious form of each does nothing visible. That is the whole reason this is worth writing down.

config/uplink.ts is not loaded by @stacksjs/config. It does not scan the directory. It walks a hardcoded list of about 46 [key, filename] pairs, and uplink is not one of them, nor should it be, since that list is the framework's own surface.

grep -c uplink node_modules/@stacksjs/config/dist/overrides.js   # 0

So config.uplink is undefined, and if (config.uplink?.pollMs) reads as "not configured" rather than failing. Nothing throws, nothing logs.

The supported route is bunfig's loadConfig({ name: 'uplink', defaultConfig, checkEnv: true }), which is how stx loads its own config. Worth knowing before the migration: bunfig derives the variable name as name.toUpperCase() plus k.replace(/([A-Z])/g, '_$1').toUpperCase(), so pollMs becomes UPLINK_POLL_MS. All seventeen of Uplink's current UPLINK_* names are exactly what it generates, so the hand-rolled int() and str() readers can go without renaming anything in .env.example. Only UPLINK_MODEL, the legacy alias, and CLAUDE_CODE_OAUTH_TOKEN need hand-handling.

A declaration is not an injection. A name in server-auto-imports.d.ts only means tsc accepts it. The globals exist after injectGlobalAutoImports() runs, which happens at server boot in buddy serve and production-server.ts. Uplink's engine runs in a launchd service and in app/Commands/Uplink.ts, which do not necessarily take that path, so a bare CodexEngine(...) would typecheck and then throw ReferenceError. Same class of failure as stacksjs/stacks#2585, and AGENTS.md already documents the browser-side version of it.

The skill carries the working form of both, plus the verification that actually proves injection rather than declaration, since the first two steps pass even when it is broken.

The constraint underneath both

grep -rn "@stacksjs" app/Uplink/*.ts app/Desktop/*.ts returns one hit, and it is a comment. The downloadable Uplink.app is compiled framework-free, which is why a second config path exists at all. The skill opens with that, because every other decision follows from it.

Also in here

AGENTS.md gains a pointer to the skill. A skill nobody invokes is the same problem over again, and AGENTS.md is the one file every agent reads.

Verification

Every command the skill tells a reader to run was run against this checkout first, so it does not ship a broken one.

🤖 Generated with Claude Code

2 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.