role-os 1.0.0 → 1.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.2
4
+
5
+ ### Fixed
6
+ - Fix double-nested `.claude/.claude/` directory created by `roleos init` — `starter-pack/.claude/workflows/full-treatment.md` moved to `starter-pack/workflows/`
7
+ - Read VERSION from `package.json` at runtime instead of hardcoded constant — prevents version drift between CLI and package metadata
8
+
9
+ ### Added
10
+ - `roleos init --force` — update canonical scaffolded files while always protecting user-filled `context/` files
11
+ - 4 regression tests: no double-nesting, correct workflow placement, version sync, --force context protection
12
+
3
13
  ## 1.0.0
4
14
 
5
15
  ### Added
package/bin/roleos.mjs CHANGED
@@ -1,12 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { readFileSync } from "node:fs";
4
+ import { join, dirname } from "node:path";
5
+ import { fileURLToPath } from "node:url";
3
6
  import { initCommand } from "../src/init.mjs";
4
7
  import { packetCommand } from "../src/packet.mjs";
5
8
  import { routeCommand } from "../src/route.mjs";
6
9
  import { reviewCommand } from "../src/review.mjs";
7
10
  import { statusCommand } from "../src/status.mjs";
8
11
 
9
- const VERSION = "1.0.0";
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ const VERSION = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8")).version;
10
14
 
11
15
  function printHelp() {
12
16
  console.log(`
@@ -14,6 +18,7 @@ roleos v${VERSION} — Role OS bootstrap CLI
14
18
 
15
19
  Usage:
16
20
  roleos init Scaffold Role OS into .claude/
21
+ roleos init --force Update canonical files (protects context/)
17
22
  roleos packet new <type> Create a new packet (feature|integration|identity)
18
23
  roleos route <packet-file> Recommend the smallest valid chain
19
24
  roleos review <packet-file> <verdict> Record a review verdict
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "role-os",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Role OS — a repo-native operating layer where specialized roles execute work through contracts, handoffs, review, and escalation",
5
5
  "type": "module",
6
6
  "bin": {
package/src/fs-utils.mjs CHANGED
@@ -3,11 +3,14 @@ import { join, dirname, relative } from "node:path";
3
3
 
4
4
  /**
5
5
  * Recursively copy a directory, skipping files that already exist at the target.
6
- * Returns { created: string[], skipped: string[] } with relative paths.
6
+ * With force=true, overwrites existing files (except those matching protectedPaths).
7
+ * Returns { created: string[], skipped: string[], updated: string[] } with relative paths.
7
8
  */
8
- export function copyDirSafe(srcDir, destDir, baseDir = destDir) {
9
+ export function copyDirSafe(srcDir, destDir, { baseDir, force = false, protectedPaths = [] } = {}) {
10
+ const root = baseDir || destDir;
9
11
  const created = [];
10
12
  const skipped = [];
13
+ const updated = [];
11
14
 
12
15
  if (!existsSync(srcDir)) {
13
16
  throw new Error(`Source directory does not exist: ${srcDir}`);
@@ -18,15 +21,23 @@ export function copyDirSafe(srcDir, destDir, baseDir = destDir) {
18
21
  for (const entry of entries) {
19
22
  const srcPath = join(srcDir, entry.name);
20
23
  const destPath = join(destDir, entry.name);
21
- const relPath = relative(baseDir, destPath);
24
+ const relPath = relative(root, destPath);
22
25
 
23
26
  if (entry.isDirectory()) {
24
- const sub = copyDirSafe(srcPath, destPath, baseDir);
27
+ const sub = copyDirSafe(srcPath, destPath, { baseDir: root, force, protectedPaths });
25
28
  created.push(...sub.created);
26
29
  skipped.push(...sub.skipped);
30
+ updated.push(...sub.updated);
27
31
  } else {
28
32
  if (existsSync(destPath)) {
29
- skipped.push(relPath);
33
+ const normalizedRel = relPath.replace(/\\/g, "/");
34
+ if (force && !protectedPaths.some(p => normalizedRel.startsWith(p))) {
35
+ mkdirSync(dirname(destPath), { recursive: true });
36
+ copyFileSync(srcPath, destPath);
37
+ updated.push(relPath);
38
+ } else {
39
+ skipped.push(relPath);
40
+ }
30
41
  } else {
31
42
  mkdirSync(dirname(destPath), { recursive: true });
32
43
  copyFileSync(srcPath, destPath);
@@ -35,7 +46,7 @@ export function copyDirSafe(srcDir, destDir, baseDir = destDir) {
35
46
  }
36
47
  }
37
48
 
38
- return { created, skipped };
49
+ return { created, skipped, updated };
39
50
  }
40
51
 
41
52
  /**
package/src/init.mjs CHANGED
@@ -5,13 +5,23 @@ import { copyDirSafe } from "./fs-utils.mjs";
5
5
  const __dirname = dirname(fileURLToPath(import.meta.url));
6
6
  const STARTER_PACK_DIR = join(__dirname, "..", "starter-pack");
7
7
 
8
+ // Paths that --force must never overwrite (user-filled content)
9
+ const PROTECTED_PATHS = [
10
+ "context/",
11
+ ];
12
+
8
13
  export async function initCommand(args) {
9
- const targetDir = args[0] || ".";
14
+ const force = args.includes("--force");
15
+ const positional = args.filter(a => !a.startsWith("--"));
16
+ const targetDir = positional[0] || ".";
10
17
  const claudeDir = join(targetDir, ".claude");
11
18
 
12
- console.log("roleos init — scaffolding Role OS into .claude/\n");
19
+ console.log(`roleos init${force ? " --force" : ""} — scaffolding Role OS into .claude/\n`);
13
20
 
14
- const { created, skipped } = copyDirSafe(STARTER_PACK_DIR, claudeDir);
21
+ const { created, skipped, updated } = copyDirSafe(STARTER_PACK_DIR, claudeDir, {
22
+ force,
23
+ protectedPaths: PROTECTED_PATHS,
24
+ });
15
25
 
16
26
  if (created.length > 0) {
17
27
  console.log(`Created (${created.length}):`);
@@ -20,6 +30,13 @@ export async function initCommand(args) {
20
30
  }
21
31
  }
22
32
 
33
+ if (updated.length > 0) {
34
+ console.log(`\nUpdated (${updated.length}):`);
35
+ for (const f of updated) {
36
+ console.log(` ~ ${f}`);
37
+ }
38
+ }
39
+
23
40
  if (skipped.length > 0) {
24
41
  console.log(`\nSkipped (${skipped.length} — already exist):`);
25
42
  for (const f of skipped) {
@@ -27,8 +44,11 @@ export async function initCommand(args) {
27
44
  }
28
45
  }
29
46
 
30
- if (created.length === 0 && skipped.length > 0) {
47
+ if (created.length === 0 && updated.length === 0 && skipped.length > 0) {
31
48
  console.log("\nRole OS is already scaffolded. No files were overwritten.");
49
+ if (!force) {
50
+ console.log("Use --force to update canonical files (context/ files are always protected).");
51
+ }
32
52
  } else {
33
53
  console.log(`\nDone. Fill the context/ files for your project, then run:`);
34
54
  console.log(` roleos packet new feature`);
@@ -0,0 +1,176 @@
1
+ # Full Treatment
2
+
3
+ Every tool repo gets the full treatment before it's "whole." This is the complete 7-phase protocol — not a pointer to an external file.
4
+
5
+ ## Gate: Shipcheck runs first
6
+
7
+ Full treatment does not start until shipcheck passes. Shipcheck is the 31-item quality gate (hard gates A-D block release).
8
+
9
+ Order: `npx @mcptoolshop/shipcheck audit` → exits 0 → then full treatment.
10
+
11
+ No v1.0.0 bump without passing hard gates A-D.
12
+
13
+ ## Phase 1 — Pre-flight + finalize README + hand off translations
14
+
15
+ a) Clone repo, verify Pages source is "GitHub Actions", enable if not. Check for existing site/ and pages.yml.
16
+ b) Note whether root package.json has "private": true (controls npm badge/link decisions).
17
+ c) Push logo to brand repo: `mcp-tool-shop-org/brand/logos/<slug>/readme.png`, run `brand manifest`, commit+push. Min 530x530px.
18
+ d) Update README: brand logo URL (`https://raw.githubusercontent.com/mcp-tool-shop-org/brand/main/logos/<slug>/readme.png`), width="400", centered.
19
+ e) Badges (after logo, centered): CI status, Codecov coverage, MIT license, Landing Page. Only if published: npm/PyPI version badges.
20
+ f) If logo contains product name, remove redundant `<h1>`.
21
+ g) Update footer: `Built by <a href="https://mcp-tool-shop.github.io/">MCP Tool Shop</a>`
22
+ h) README is now final — hand the user the translation command(s).
23
+
24
+ Translation command (user runs in PowerShell, NOT Claude):
25
+ ```
26
+ node F:/AI/polyglot-mcp/scripts/translate-all.mjs F:/AI/<repo>/README.md
27
+ ```
28
+ Monorepos: chain with semicolons. Large monorepos: batch into groups of 5-7.
29
+
30
+ WARNING: NEVER run translations from Claude — wastes Claude points. User runs locally (TranslateGemma 12B, Ollama, zero API cost, ~2-4 min/README).
31
+
32
+ ### Role owners
33
+ - **Repo Researcher** — verify repo state, Pages config, package.json
34
+ - **Brand Guardian** — verify logo, README identity, footer
35
+ - **Repo Translator** — hand off and verify translations
36
+
37
+ ## Phase 2 — Scaffold landing page (while translations run)
38
+
39
+ a) `npx @mcptoolshop/site-theme init` from repo root
40
+ b) Add to .gitignore: site/.astro/, site/dist/, site/node_modules/, .polyglot-cache.json
41
+ c) `cd site && npm install`
42
+ d) Verify site/astro.config.mjs base matches `/<repo-name>/` (case-sensitive)
43
+ e) Write site/src/site-config.ts (typed as SiteConfig). Description from root package.json.
44
+ f) pages.yml does NOT count toward "max 2 workflow files" rule
45
+
46
+ ### Role owners
47
+ - **Docs Architect** — site-theme init, site-config.ts
48
+ - **Frontend Developer** — landing page content and build
49
+ - **Brand Guardian** — verify brand alignment
50
+
51
+ ## Phase 3 — Handbook (Starlight docs)
52
+
53
+ a) `cd <repo>/site && npm install @astrojs/starlight`
54
+ b) Replace astro.config.mjs (social must be array, disable404Route: true)
55
+ c) Create content.config.ts in site/src/:
56
+ ```ts
57
+ import { defineCollection } from 'astro:content';
58
+ import { docsLoader } from '@astrojs/starlight/loaders';
59
+ import { docsSchema } from '@astrojs/starlight/schema';
60
+ export const collections = { docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }) };
61
+ ```
62
+ d) Create starlight-custom.css (derive accent from global.css):
63
+
64
+ | Accent | --sl-color-accent-low | --sl-color-accent | --sl-color-accent-high |
65
+ |--------|----------------------|-------------------|------------------------|
66
+ | emerald (default) | #022c22 | #34d399 | #6ee7b7 |
67
+ | amber | #451a03 | #d97706 | #fbbf24 |
68
+ | blue | #1e1b4b | #3b82f6 | #93c5fd |
69
+ | rose | #4c0519 | #f43f5e | #fb7185 |
70
+ | violet | #2e1065 | #8b5cf6 | #a78bfa |
71
+ | cyan | #083344 | #06b6d4 | #67e8f9 |
72
+ | pink | #500724 | #ec4899 | #f9a8d4 |
73
+
74
+ Dark background vars: `--sl-color-bg: #09090b`, `--sl-color-hairline: #27272a`, etc.
75
+
76
+ e) Create handbook pages in site/src/content/docs/handbook/ (min 3: index, getting-started, reference)
77
+
78
+ | Source | File | Order |
79
+ |--------|------|-------|
80
+ | Welcome | index.md | 0 |
81
+ | Install/Quick Start | getting-started.md | 1 |
82
+ | Usage | usage.md | 2 |
83
+ | Config/Options | configuration.md | 3 |
84
+ | API/Commands | reference.md | 4 |
85
+ | Architecture | architecture.md | 5 |
86
+ | Security | security.md | 6 |
87
+
88
+ Minimum 3 pages. Rich repos get 5-7. Expand README content — don't just copy-paste.
89
+
90
+ f) Update landing page CTA in site-config.ts: `secondaryCta: { href: 'handbook/', label: 'Read the Handbook' }`
91
+ g) Build and verify: `cd site && npm run build` — check dist/index.html + dist/handbook/
92
+
93
+ ### Role owners
94
+ - **Docs Architect** — Starlight setup, page structure, content
95
+ - **Repo Translator** — docs translation if applicable
96
+
97
+ ## Phase 4 — Repo metadata + coverage
98
+
99
+ a) Set GitHub metadata:
100
+ ```
101
+ gh repo edit mcp-tool-shop-org/<repo> --description "<from package.json>" --homepage "https://mcp-tool-shop-org.github.io/<repo-name>/"
102
+ gh repo edit mcp-tool-shop-org/<repo> --add-topic <tags>
103
+ ```
104
+ b) Code coverage: add coverage dep, coverage CI step (one matrix entry), codecov upload, badge in README
105
+ c) Verify site builds, .gitignore complete, logo renders at brand URL
106
+ d) Review README for typos, broken links, stale content
107
+
108
+ ### Role owners
109
+ - **Metadata Curator** — GitHub metadata, badges, manifest
110
+ - **Coverage Auditor** — test coverage assessment, CI integration
111
+
112
+ ## Phase 5 — Repo Knowledge DB entry
113
+
114
+ Every treated repo gets a proper entry in the repo-knowledge database. This is NOT optional.
115
+
116
+ a) Sync the repo if not already in the DB:
117
+ ```
118
+ rk sync --owners mcp-tool-shop-org
119
+ ```
120
+
121
+ b) Add required notes using MCP tools or CLI:
122
+ - **thesis** — what the repo is and why it exists (1-2 sentences)
123
+ - **architecture** — how it's built, key components, data flow
124
+ - At least one **relationship** mapped (depends_on, related_to, shares_domain_with, etc.)
125
+
126
+ c) Add recommended notes where applicable:
127
+ - **convention** — important patterns/rules specific to this repo
128
+ - **next_step** — what should happen next
129
+ - **warning** or **drift_risk** — known issues or things that could break
130
+ - **command** — key commands to build/test/deploy
131
+
132
+ d) Verify the entry:
133
+ ```
134
+ rk show <slug>
135
+ ```
136
+ Confirm: thesis present, architecture present, relationships mapped, tech detected, docs indexed.
137
+
138
+ ### Role owners
139
+ - **Repo Researcher** — thesis, architecture, relationships
140
+ - **Metadata Curator** — verify entry completeness
141
+
142
+ ## Phase 6 — Commit and deploy
143
+
144
+ Stage explicitly: `git add site/ .github/workflows/pages.yml .gitignore README.md README.*.md`
145
+ WARNING: Use `README.*.md` glob — NEVER hand-type individual filenames.
146
+ Never `git add .` — translated READMEs may have CRLF drift on Windows.
147
+ Push to main. Verify landing page + handbook render.
148
+
149
+ ### Role owners
150
+ - **Release Engineer** — staging, version, tag, push
151
+
152
+ ## Phase 7 — Post-deploy verification
153
+
154
+ - Landing page renders at `https://mcp-tool-shop-org.github.io/<repo-name>/`
155
+ - Handbook renders at `.../handbook/`
156
+ - Pagefind search works in handbook
157
+ - Translations are complete (check ja for degenerate output)
158
+ - Coverage badge shows real data
159
+ - `rk show <slug>` returns complete knowledge entry
160
+ - Repo-knowledge DB has thesis, architecture, and relationships
161
+
162
+ ### Role owners
163
+ - **Deployment Verifier** — landing page, handbook, package, badges, translations
164
+
165
+ ### Final gate
166
+ - **Critic Reviewer** — accept or reject treatment completeness
167
+
168
+ ## Do NOT
169
+
170
+ - Copy or modify theme components locally
171
+ - Add extra Astro pages beyond index.astro unless requested
172
+ - Skip the init CLI and scaffold manually
173
+ - Add npm badges for private/unpublished repos
174
+ - Skip the repo-knowledge DB entry — it's part of the treatment now
175
+ - Run translations from Claude
176
+ - Reference "memory/" paths without absolute paths — protocols must be self-contained
@@ -1,74 +0,0 @@
1
- # Full Treatment
2
-
3
- Role OS does not own or redefine the full treatment protocol. The canonical protocol lives in Claude project memory (`memory/full-treatment.md`) and is a 7-phase polish + publish playbook.
4
-
5
- ## Canonical source
6
-
7
- The full treatment is defined in Claude project memory as a 7-phase protocol:
8
-
9
- 1. Pre-flight + finalize README + hand off translations
10
- 2. Scaffold landing page (Astro site-theme)
11
- 3. Handbook (Starlight docs)
12
- 4. Repo metadata + coverage
13
- 5. Repo Knowledge DB entry
14
- 6. Commit and deploy
15
- 7. Post-deploy verification
16
-
17
- Read `memory/full-treatment.md` and `memory/handbook-playbook.md` before starting.
18
-
19
- ## Gate: Shipcheck runs first
20
-
21
- Full treatment does not start until shipcheck passes. Shipcheck is the 31-item quality gate (hard gates A-D block release). The canonical shipcheck reference lives in Claude project memory (`memory/shipcheck.md`).
22
-
23
- Order: `npx @mcptoolshop/shipcheck audit` → exits 0 → then full treatment.
24
-
25
- No v1.0.0 bump without passing hard gates A-D.
26
-
27
- ## Role chain per phase
28
-
29
- Each treatment phase maps to specific roles:
30
-
31
- ### Phase 1 — Pre-flight + README + translations
32
- - **Repo Researcher** — verify repo state, Pages config, package.json
33
- - **Brand Guardian** — verify logo, README identity, footer
34
- - **Repo Translator** — hand off and verify translations
35
-
36
- ### Phase 2 — Scaffold landing page
37
- - **Docs Architect** — site-theme init, site-config.ts
38
- - **Frontend Developer** — landing page content and build
39
- - **Brand Guardian** — verify brand alignment
40
-
41
- ### Phase 3 — Handbook (Starlight docs)
42
- - **Docs Architect** — Starlight setup, page structure, content
43
- - **Repo Translator** — docs translation if applicable
44
-
45
- ### Phase 4 — Repo metadata + coverage
46
- - **Metadata Curator** — GitHub metadata, badges, manifest
47
- - **Coverage Auditor** — test coverage assessment, CI integration
48
-
49
- ### Phase 5 — Repo Knowledge DB entry
50
- - **Repo Researcher** — thesis, architecture, relationships
51
- - **Metadata Curator** — verify entry completeness
52
-
53
- ### Phase 6 — Commit and deploy
54
- - **Release Engineer** — staging, version, tag, push
55
-
56
- ### Phase 7 — Post-deploy verification
57
- - **Deployment Verifier** — landing page, handbook, package, badges, translations
58
-
59
- ### Final gate
60
- - **Critic Reviewer** — accept or reject treatment completeness
61
-
62
- ## What Role OS adds
63
-
64
- - Explicit role ownership for each treatment phase
65
- - Structured handoffs between phases
66
- - Review gate on treatment completeness
67
- - Routing and escalation law
68
-
69
- ## What Role OS does not own
70
-
71
- - The treatment protocol itself
72
- - The shipcheck gate
73
- - Claude project memory
74
- - Treatment history and repo facts (those live in Claude project memory)