Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ FROM node:22-alpine
# keeps the Glama-introspected surface reproducible. Bump on release.
ENV PNPM_HOME=/usr/local/share/pnpm
ENV PATH=$PNPM_HOME/bin:$PNPM_HOME:$PATH
RUN corepack enable && pnpm add -g robrain@2.4.8
RUN corepack enable && pnpm add -g robrain@2.4.9

# stdio MCP transport: the client speaks JSON-RPC over stdin/stdout.
ENTRYPOINT ["robrain", "mcp"]
48 changes: 45 additions & 3 deletions docs/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,58 @@ git push origin v2.3.8 && gh run watch

### 3. Publish npm

From repo root (release guard runs automatically in `prepublishOnly`):
Two packages ship to npm every release: **`@robrain/shared`** (consumed by the
cloud repo as a normal registry dependency) and **`robrain`** (the CLI).

> **One-time setup:** the `@robrain` scope is an npm **organization**, created on
> https://www.npmjs.com/org/create with the same account that owns the `robrain`
> CLI package (`npm owner ls robrain`). Orgs cannot be created from the CLI. Use
> the free *Unlimited public packages* plan. Verify with `npm org ls robrain`.
> Scoped packages default to restricted on publish, which a free org cannot
> host β€” hence `publishConfig.access: "public"` in `packages/shared/package.json`
> **and** `--access public` on the publish command.

Preflight β€” confirm the shared tarball has `dist/*` (no `*.test.js`, no
`*.map`), `schema.sql`, `README.md`, `LICENSE`, and `package.json`, and nothing
else:

```bash
pnpm --filter @robrain/shared exec npm pack --dry-run
```

Then from repo root:

```bash
pnpm publish:npm
# equivalent: pnpm --filter @robrain/sensing-mcp build && pnpm --filter @robrain/synthesis build && pnpm --filter robrain publish --access public --no-git-checks
# equivalent: pnpm --filter robrain build && node packages/cli/scripts/verify-release-artifacts.mjs && pnpm --filter @robrain/shared publish --access public --no-git-checks && pnpm --filter @robrain/sensing-mcp build && pnpm --filter @robrain/synthesis build && pnpm --filter robrain publish --access public --no-git-checks
```

With 2FA on the account, npm prompts for an OTP **per package** β€” two prompts.

**Why the guard runs up front.** `@robrain/shared` has no coupling to the Docker
image, so the GHCR golden rule does not gate it, and publishing it first means a
cloud repin never waits on a CLI publish failure. But the CLI's own
`prepublishOnly` guard runs *last* in the chain β€” if it failed there,
`@robrain/shared@X.Y.Z` would already be public with no matching CLI, and npm
blocks reusing a version for 24h after an unpublish. The only way out would be
bumping everything to X.Y.Z+1, leaving an orphan version the cloud could pin and
breaking the lockstep invariant. So `publish:npm` builds the CLI and runs
`verify-release-artifacts.mjs` standalone *before* the first publish. It runs
again in `prepublishOnly`; the second run is a cheap no-op re-check.
`ROBRAIN_SKIP_RELEASE_GUARD=1` still bypasses both.

**`prepack` cleans `dist/` first.** `tsc` never removes stale output, so the
tsconfig test exclusion alone would leave previously-compiled `*.test.js` in a
release machine's `dist/` and ship them. `prepack` is
`rm -rf dist && tsc --sourceMap false --declarationMap false` β€” the clean makes
the exclusion real, and dropping the maps avoids shipping `.js.map` /
`.d.ts.map` that point at a `../src` the tarball does not contain. Plain `build`
and `prepare` keep maps, so local dev and the git-pin path are unaffected.

Smoke:

```bash
npm view @robrain/shared version # β†’ X.Y.Z
npx robrain@X.Y.Z --version
npx robrain@X.Y.Z up # only if no conflicting stack already running (see below)
cd packages/cli && pnpm pack:verify
Expand Down Expand Up @@ -234,7 +276,7 @@ git tag vX.Y.Z β†’ push tag β†’ wait publish-perception-image.yml βœ“
↓
docker pull ghcr.io/.../robrain-perception:X.Y.Z (verify)
↓
pnpm publish:npm (release guard must pass)
pnpm publish:npm (@robrain/shared, then robrain β€” release guard must pass)
↓
mcp-publisher publish (login github only if 401)
↓
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "robrain-monorepo",
"version": "2.4.8",
"version": "2.4.9",
"description": "Institutional memory for AI coding agents \u2014 capture decisions, rejected alternatives, and rationale across sessions",
"license": "Apache-2.0",
"private": true,
Expand All @@ -23,7 +23,7 @@
"docker:down": "docker compose -f docker/docker-compose.yml --env-file .env down",
"docker:build": "pnpm prepare-env && docker compose -f docker/docker-compose.yml --env-file .env build perception",
"docker:up:build": "pnpm prepare-env && docker compose -f docker/docker-compose.yml --env-file .env up -d --build perception",
"publish:npm": "pnpm --filter @robrain/sensing-mcp build && pnpm --filter @robrain/synthesis build && pnpm --filter robrain publish --access public --no-git-checks"
"publish:npm": "pnpm --filter robrain build && node packages/cli/scripts/verify-release-artifacts.mjs && pnpm --filter @robrain/shared publish --access public --no-git-checks && pnpm --filter @robrain/sensing-mcp build && pnpm --filter @robrain/synthesis build && pnpm --filter robrain publish --access public --no-git-checks"
},
"devDependencies": {
"@types/node": "^20.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "robrain",
"version": "2.4.8",
"version": "2.4.9",
"type": "module",
"description": "RoBrain CLI for installation, setup, and memory workflows",
"author": "Rory Plans, Inc.",
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ export async function installCommand(opts: InstallOptions): Promise<void> {
// Display only (status) β€” the thin client never embeds locally.
...(provisioned.embeddingProvider ? { embeddingProvider: provisioned.embeddingProvider } : {}),
installedAt: new Date().toISOString(),
version: '2.4.8',
version: '2.4.9',
})

spinner.succeed('MCP servers configured')
Expand Down Expand Up @@ -526,7 +526,7 @@ async function installSelfHosted(opts: InstallOptions): Promise<void> {
...(perceptionKey ? { perceptionKey } : {}),
embeddingProvider: provider,
installedAt: new Date().toISOString(),
version: '2.4.8',
version: '2.4.9',
selfHosted: true,
})

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { upCommand, downCommand, DEFAULT_IMAGE_REPO } from './commands/up.js'
import { mcpCommand } from './commands/mcp.js'
import { installHermesPlugin, resolveHermesHome } from './lib/hermes-plugin.js'

const VERSION = '2.4.8'
const VERSION = '2.4.9'

program
.name('robrain')
Expand Down
2 changes: 1 addition & 1 deletion packages/eval/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@robrain/eval",
"version": "2.4.8",
"version": "2.4.9",
"private": true,
"type": "module",
"main": "./dist/run.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/perception-self-hosted/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@robrain/perception-self-hosted",
"version": "2.4.8",
"version": "2.4.9",
"private": true,
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/sensing-mcp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@robrain/sensing-mcp",
"version": "2.4.8",
"version": "2.4.9",
"type": "module",
"description": "RoBrain Sensing MCP server \u2014 passive decision capture for AI coding agents",
"license": "Apache-2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/sensing-mcp/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function resolveSessionId(raw: string | null | undefined): string {
export function buildServer(): McpServer {
const server = new McpServer({
name: 'sensing-mcp',
version: '2.4.8',
version: '2.4.9',
})

// ─────────────────────────────────────────────────────────────
Expand Down
17 changes: 17 additions & 0 deletions packages/shared/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/

Copyright 2026 Rory Plans, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
46 changes: 46 additions & 0 deletions packages/shared/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# @robrain/shared

Shared primitives for [RoBrain](https://github.com/adelinamart/robrain) β€”
database helpers, embedding and LLM providers, secret redaction, trust scoring,
and the canonical Postgres schema.

This package is published so RoBrain services can depend on a prebuilt tarball
instead of compiling the monorepo at install time. It is not a general-purpose
library: the API tracks RoBrain's needs and moves with the monorepo's lockstep
version.

## Install

```bash
npm install @robrain/shared
```

No runtime dependencies β€” everything here imports only Node built-ins. Database
helpers take a structural `PoolLike`, so bring your own `pg` (or compatible)
pool.

## Usage

```js
import { scoreMemoryTrust, redactSecrets, embed } from '@robrain/shared'
import { loadEnv } from '@robrain/shared/load-env'
```

The Postgres schema ships at the package root and can be resolved directly:

```js
import { createRequire } from 'node:module'
import { readFileSync } from 'node:fs'

const require = createRequire(import.meta.url)
const schema = readFileSync(require.resolve('@robrain/shared/schema.sql'), 'utf8')
```

## Links

- [Repository](https://github.com/adelinamart/robrain) (source lives in `packages/shared`)
- [Issues](https://github.com/adelinamart/robrain/issues)

## License

Apache-2.0 Β© Rory Plans, Inc.
33 changes: 28 additions & 5 deletions packages/shared/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
{
"name": "@robrain/shared",
"version": "2.4.8",
"private": true,
"version": "2.4.9",
"description": "Shared database, embedding, and trust primitives for RoBrain",
"author": "Rory Plans, Inc.",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git+https://github.com/adelinamart/robrain.git",
"directory": "packages/shared"
},
"homepage": "https://github.com/adelinamart/robrain#readme",
"bugs": {
"url": "https://github.com/adelinamart/robrain/issues"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
Expand All @@ -12,12 +23,24 @@
"./load-env": {
"import": "./dist/load-env.js",
"types": "./dist/load-env.d.ts"
}
},
"./schema.sql": "./schema.sql",
"./package.json": "./package.json"
},
"files": [
"dist",
"schema.sql",
"README.md",
"LICENSE"
],
"publishConfig": {
"access": "public"
},
"scripts": {
"prepare": "tsc",
"prepare": "rm -rf dist && tsc -p tsconfig.publish.json",
"prepack": "rm -rf dist && tsc -p tsconfig.publish.json",
"build": "tsc",
"typecheck": "tsc --noEmit",
"typecheck": "tsc -p tsconfig.typecheck.json --noEmit",
"test": "bun test src"
},
"devDependencies": {
Expand Down
6 changes: 5 additions & 1 deletion packages/shared/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src/**/*"]
"include": ["src/**/*"],
// Tests run from source via `bun test src`; keeping them out of the build
// keeps compiled tests out of dist/ and therefore out of the npm tarball.
// `tsconfig.typecheck.json` re-includes them for type checking.
"exclude": ["src/**/*.test.ts"]
}
12 changes: 12 additions & 0 deletions packages/shared/tsconfig.publish.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
// Build config for anything that produces a consumable artifact: the npm
// tarball (`prepack`) and git-path installs (`prepare`). Maps are off because
// `files` does not ship `src/`, so published `.js.map` / `.d.ts.map` would
// point at a `../src` that isn't in the tarball. Local dev uses `build`
// (plain tsconfig.json), which keeps maps.
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"declarationMap": false
}
}
8 changes: 8 additions & 0 deletions packages/shared/tsconfig.typecheck.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
// Type checking only: same options as the build, but tests included.
// The build config excludes `src/**/*.test.ts` so compiled tests stay out of
// dist/ (and the published tarball) β€” they still need to typecheck.
"extends": "./tsconfig.json",
"include": ["src/**/*"],
"exclude": []
}
2 changes: 1 addition & 1 deletion packages/synthesis/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@robrain/synthesis",
"version": "2.4.8",
"version": "2.4.9",
"private": true,
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion plugins/claude-code/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "robrain",
"version": "2.4.8",
"version": "2.4.9",
"description": "Institutional memory for AI coding agents: deterministic decision capture and pre-task warnings about previously REJECTED approaches, backed by your self-hosted RoBrain stack.",
"author": {
"name": "Rory Plans",
Expand Down
4 changes: 2 additions & 2 deletions server.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
"url": "https://github.com/adelinamart/robrain",
"source": "github"
},
"version": "2.4.8",
"version": "2.4.9",
"packages": [
{
"registryType": "npm",
"registryBaseUrl": "https://registry.npmjs.org",
"identifier": "robrain",
"version": "2.4.8",
"version": "2.4.9",
"transport": {
"type": "stdio"
},
Expand Down
Loading