chore: rename prompt setup→bootstrap, programmatic generation, bun→pnpm cleanup #81

Merged
xiaoju merged 2 commits from chore/80-bootstrap-cleanup into main 2026-06-06 14:34:38 +00:00
7 changed files with 207 additions and 73 deletions
+5 -5
View File
@@ -120,15 +120,15 @@ roles:
1. Use `git rev-parse --show-toplevel` to find the repo root (do NOT use repoPath from proposer — that's the analyzed repo)
2. `git fetch origin` to get latest refs
3. `git worktree add .worktrees/retrospect/<short-slug> -b retrospect/<short-slug> origin/main`
4. `cd .worktrees/retrospect/<short-slug> && bun install`
4. `cd .worktrees/retrospect/<short-slug> && pnpm install`
5. ALL subsequent work must happen inside the worktree directory.
Then apply changes:
6. Read the change plan from CAS: `uwf cas get <plan hash>`
7. Apply each edit from the plan to the workflow YAML
8. Update or add tests as specified in the plan
9. Run `bun run build` and `bun test` to verify
10. Run `bun run check` for lint
9. Run `pnpm run build` and `pnpm test` to verify
10. Run `pnpm run check` for lint
11. Commit with message: `improve: <workflow-name> — <brief summary>`
output: "List all files changed and provide a summary. Set $status to done (with branch/worktree), or failed (with reason)."
frontmatter:
@@ -157,8 +157,8 @@ roles:
2. Edits should be minimal — don't rewrite working procedures
3. New pitfall notes or instructions must be clear and actionable
4. Tests must be updated if assertions changed
5. `bun run build` and `bun test` must pass
6. `bunx biome check` must pass
5. `pnpm run build` and `pnpm test` must pass
6. `pnpm run check` must pass
IMPORTANT: `tea pr create` must run from the MAIN repo directory (not a worktree), because tea cannot detect the repo from worktree `.git` files.
output: "Explain your decision. Set $status to approved (with branch/worktree) or rejected (with comments)."
+6 -6
View File
@@ -50,7 +50,7 @@ roles:
2. `git fetch origin` to get latest refs
3. First time (no existing branch):
- `git worktree add .worktrees/fix/<issue-number>-<short-slug> -b fix/<issue-number>-<short-slug> origin/main`
- `cd .worktrees/fix/<issue-number>-<short-slug> && bun install`
- `cd .worktrees/fix/<issue-number>-<short-slug> && pnpm install`
4. If bounced back from reviewer or tester (branch already exists):
- cd into the existing worktree under `.worktrees/fix/<issue-number>-<short-slug>`
- `git fetch origin && git rebase origin/main`
@@ -61,8 +61,8 @@ roles:
7. If bounced back from reviewer or tester: read the previous role's feedback in your task prompt
8. Write tests first based on the spec
9. Implement the code to make tests pass
10. Ensure `bun run build` passes with no errors
11. Run `bun test` to verify all tests pass
10. Ensure `pnpm run build` passes with no errors
11. Run `pnpm test` to verify all tests pass
If you cannot complete the implementation (e.g. the issue is too complex, blocked by external factors,
or repeated attempts fail), set $status=failed with a reason.
@@ -95,8 +95,8 @@ roles:
Then perform code review:
Hard checks (must all pass):
3. `bun run build` — no build errors
4. `bunx biome check` — no lint violations
3. `pnpm run build` — no build errors
4. `pnpm run check` — no lint violations
5. TypeScript strict mode — no type errors
Soft checks (review against project conventions if CLAUDE.md / .cursor/rules exist):
@@ -129,7 +129,7 @@ roles:
procedure: |
The worktree path is provided in your task prompt. cd into it first.
1. Run `bun test` for automated test verification
1. Run `pnpm test` for automated test verification
2. Read the test spec from CAS: `uwf cas get <plan hash>` (find the hash from the planner step in the thread history)
3. Verify each scenario in the spec is covered and passing
4. Determine outcome:
-53
View File
@@ -1,53 +0,0 @@
# OCAS Skill Setup
You are being asked to install or update the OCAS (Object Content Addressable Store) skill
so that you know how to use the `ocas` CLI.
## Steps
1. **Check if OCAS CLI is installed:**
```bash
ocas --help
```
If not installed: `pnpm add -g @ocas/cli`
2. **Clean up old versions of the skill** (if any exist):
- Look for any existing OCAS/ocas skill files in your skill directories
(e.g. `~/.hermes/skills/ocas/SKILL.md` or similar paths).
- If a skill exists, read its `version` from the YAML frontmatter.
- If the version matches the current CLI version (`ocas --version`), you're done — no update needed.
- If the version is older, **delete the old skill file** before proceeding.
3. **Get the usage skill content:**
```bash
ocas prompt usage
```
4. **Create a SKILL.md file** in your skill directory (e.g. `~/.hermes/skills/ocas/SKILL.md`).
The output of `ocas prompt usage` is the skill body WITHOUT frontmatter.
You must prepend the following YAML frontmatter:
```yaml
---
name: ocas
description: "Use when storing, retrieving, or managing typed JSON data with OCAS (Object Content Addressable Store). Covers CLI usage, variable management, templates, rendering, and pipe composition."
version: <VERSION>
author: OCAS
license: MIT
metadata:
hermes:
tags: [cas, storage, cli, json, schema, content-addressing]
---
```
Replace `<VERSION>` with the installed CLI version (from `ocas --version`).
5. **Verify** the skill is loadable by your agent framework.
## Notes
- The skill content is bundled with the CLI and versioned with it — always use
`ocas prompt usage` to get the content matching your installed version.
- Do NOT hand-edit the skill body. If the CLI is updated, re-run `ocas prompt setup`
and follow the steps again.
- When upgrading, always delete the old skill first to avoid stale instructions.
+12 -8
View File
@@ -5,6 +5,8 @@ import { homedir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { cmdPromptBootstrap } from "./prompt-bootstrap.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
import type { Hash, ListEntry, ListOptions, Store, TagOp } from "@ocas/core";
@@ -1115,7 +1117,7 @@ Flags:
--epsilon <n> Cutoff threshold for render (default: 0.01)
--pipe, -p Read from stdin (put/hash: raw JSON payload; render: { type, value } envelope)
Agent: If you have not installed the ocas skill for this version (${pkg.version}), run \`ocas prompt setup\` and follow the instructions.`);
Agent: If you have not installed the ocas skill for this version (${pkg.version}), run \`ocas prompt bootstrap\` and follow the instructions.`);
}
// ---- Dispatch ----
@@ -1232,6 +1234,11 @@ switch (cmd) {
case "prompt": {
const [sub] = rest;
switch (sub) {
case "list": {
// biome-ignore lint/suspicious/noConsole: CLI user-facing output
console.log("usage\nbootstrap");
break;
}
case "usage": {
const content = readFileSync(
join(__dirname, "..", "prompts", "usage.md"),
@@ -1240,17 +1247,14 @@ switch (cmd) {
process.stdout.write(content);
break;
}
case "setup": {
const content = readFileSync(
join(__dirname, "..", "prompts", "setup.md"),
"utf-8",
);
process.stdout.write(content);
case "bootstrap": {
// biome-ignore lint/suspicious/noConsole: CLI user-facing output
console.log(cmdPromptBootstrap());
break;
}
default:
die(
`Unknown prompt subcommand: ${sub ?? "(none)"}. Available: usage, setup`,
`Unknown prompt subcommand: ${sub ?? "(none)"}. Available: list, usage, bootstrap`,
);
}
break;
+183
View File
@@ -0,0 +1,183 @@
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
// Walk up from __dirname to find the nearest @ocas/cli package.json
function _findCliVersion(): string {
let dir = dirname(fileURLToPath(import.meta.url));
for (let i = 0; i < 5; i++) {
const candidate = join(dir, "package.json");
try {
const pkg = JSON.parse(readFileSync(candidate, "utf-8")) as {
name?: string;
version?: string;
};
if (pkg.name === "@ocas/cli") {
return pkg.version ?? "0.0.0";
}
} catch {
// not found, keep walking
}
dir = dirname(dir);
}
return "0.0.0";
}
const CLI_VERSION = _findCliVersion();
export function cmdPromptBootstrap(): string {
return `# ocas Bootstrap
Set up or upgrade ocas (Object Content Addressable Store) — from zero to running your first command.
## Scenario A: Fresh Install
### Step 0 — Environment pre-flight check
Run ALL checks below BEFORE installing anything. If any check fails, fix it first — do NOT skip ahead.
\`\`\`bash
# 1. Node.js
node --version # need v20+
# FIX: install via nvm (https://github.com/nvm-sh/nvm) or your OS package manager
# 2. Package manager — pnpm (preferred) or npm
pnpm --version || npm --version
# FIX for pnpm: corepack enable pnpm (Node 20+)
# or: npm install -g pnpm
# If pnpm is not an option, npm works too — adjust install commands below
# 3. Global bin directory is in PATH
# For pnpm:
pnpm bin -g # prints the global bin directory
# For npm:
npm prefix -g # global prefix; bin is <prefix>/bin
# The directory printed above MUST be in your PATH.
# Test: echo \\$PATH | tr ':' '\\n'
# FIX: add the missing directory to your shell's startup file
# (e.g. ~/.bashrc, ~/.zshrc, ~/.profile, or fish config):
# export PATH="<global-bin-dir>:$PATH"
\`\`\`
**All checks must pass before continuing.** If you had to modify PATH, verify the change persists by opening a new shell or sourcing your shell config.
### Step 1 — Install @ocas/cli
\`\`\`bash
# Using pnpm (preferred)
pnpm add -g @ocas/cli
# Using npm
npm install -g @ocas/cli
\`\`\`
**After installing, verify that \`ocas\` is available in PATH:**
\`\`\`bash
ocas --version # should print ${CLI_VERSION}
\`\`\`
If the command is not found, the global bin directory is not in the current shell's PATH. **You must fix this before continuing:**
1. Find where the binary was installed:
\`\`\`bash
find ~/.local /usr/local -name ocas -type f 2>/dev/null
npm prefix -g # global prefix — bin is <prefix>/bin
\`\`\`
2. Add the directory to PATH permanently by appending to the user's shell config (e.g. \`~/.bashrc\`, \`~/.zshrc\`, \`~/.profile\`, or fish config):
\`\`\`bash
export PATH="<global-bin-dir>:$PATH"
\`\`\`
3. Source the updated config or open a new shell, then re-verify the command works.
### Step 2 — Verify version
\`\`\`bash
ocas --version # should print ${CLI_VERSION}
\`\`\`
### Step 3 — Install the ocas skill
Run the usage prompt and save it as a skill so your agent knows how to use ocas:
\`\`\`bash
ocas prompt usage
\`\`\`
The output is the skill body **without** frontmatter. Save it as a skill in your agent framework with the following YAML frontmatter prepended:
\`\`\`yaml
---
name: ocas
description: "Use when storing, retrieving, or managing typed JSON data with OCAS (Object Content Addressable Store). Covers CLI usage, variable management, templates, rendering, and pipe composition."
version: ${CLI_VERSION}
author: OCAS
license: MIT
metadata:
hermes:
tags: [cas, storage, cli, json, schema, content-addressing]
---
\`\`\`
Replace the \`version\` field with the installed CLI version (from \`ocas --version\`).
**⚠ After saving the skill, start a new session** so the agent loads the updated skill content. Skills saved in the current session are not active until the next session.
### Step 4 — End-to-end verify
\`\`\`bash
# Store a string value
ocas put @ocas/string '"hello world"'
# Get it back using the returned hash
ocas get <hash>
\`\`\`
If \`ocas get\` returns \`"hello world"\`, the setup is working.
## Scenario B: Upgrade from Previous Version
### Step 1 — Update to latest
\`\`\`bash
# Using pnpm
pnpm add -g @ocas/cli@latest
# Using npm
npm install -g @ocas/cli@latest
\`\`\`
### Step 2 — Verify version
\`\`\`bash
ocas --version # should print ${CLI_VERSION}
\`\`\`
### Step 3 — Regenerate skill
Skill content is bundled with the CLI — always regenerate after upgrading:
\`\`\`bash
ocas prompt usage # → update skill "ocas"
\`\`\`
Update the \`version\` field in the skill frontmatter to match the new CLI version.
**⚠ After updating the skill, start a new session** to load the new skill content.
### Step 4 — Verify
\`\`\`bash
ocas put @ocas/string '"upgrade test"'
ocas get <hash>
\`\`\`
## Available prompts
\`\`\`bash
ocas prompt list # list available prompt names
ocas prompt usage # CLI usage guide (skill body)
ocas prompt bootstrap # this guide
\`\`\`
`;
}
@@ -466,5 +466,5 @@ Flags:
--epsilon <n> Cutoff threshold for render (default: 0.01)
--pipe, -p Read from stdin (put/hash: raw JSON payload; render: { type, value } envelope)
Agent: If you have not installed the ocas skill for this version (0.3.1), run \`ocas prompt setup\` and follow the instructions."
Agent: If you have not installed the ocas skill for this version (0.3.1), run \`ocas prompt bootstrap\` and follow the instructions."
`;