world-building-framework 0.2.2 → 0.2.3

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/README.md CHANGED
@@ -26,7 +26,7 @@ npm install
26
26
  - `.gitignore`
27
27
  - `AGENTS.md`
28
28
  - a GitHub Pages workflow
29
- - Obsidian settings that hide tooling folders
29
+ - Obsidian settings that keep `node_modules/` out of Obsidian's search and graph (Settings → Files and links → Excluded files)
30
30
 
31
31
  Then put it on GitHub:
32
32
 
@@ -83,7 +83,8 @@ export async function runInit(options = {}) {
83
83
  outcome.skipped.push(".gitignore");
84
84
  }
85
85
  }
86
- // Obsidian: hide tooling folders, so it doesn't list package READMEs.
86
+ // Obsidian: "Excluded files" (userIgnoreFilters), so package READMEs under node_modules
87
+ // don't show up in search and the graph view. Obsidian skips dot-folders like .wbf on its own.
87
88
  if (!exists(".obsidian/app.json")) {
88
89
  await writeRepoFile(dir, ".obsidian/app.json", JSON.stringify({ userIgnoreFilters: ["node_modules/", ".wbf/"] }, null, 2) + "\n");
89
90
  outcome.created.push(".obsidian/app.json");
package/dist/cli/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
3
  import { Command } from "commander";
4
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
5
5
  import { createMcpServer } from "../mcp/server.js";
6
6
  import { runSchema } from "./commands/schema.js";
7
7
  import { runInit } from "./commands/init.js";
@@ -1,4 +1,4 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1
+ import { McpServer } from "@modelcontextprotocol/server";
2
2
  /**
3
3
  * What every agent connecting to the server is told up front: the
4
4
  * world-vault skill's rules (skills/world-vault/SKILL.md), in terms of this
@@ -1,6 +1,6 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { McpServer } from "@modelcontextprotocol/server";
4
4
  import { z } from "zod";
5
5
  import { readVaultFile } from "../core/vault/index.js";
6
6
  import { runSchema } from "../cli/commands/schema.js";
@@ -79,17 +79,17 @@ export function createMcpServer(options) {
79
79
  server.registerTool("search", {
80
80
  title: "Search the world",
81
81
  description: "Keyword search over titles, aliases and text. Each result has the file's id (the UUID you link with), title and score, and for entities entityType and tags.",
82
- inputSchema: {
82
+ inputSchema: z.object({
83
83
  query: z.string().min(1).describe("Search terms"),
84
84
  tags: z.array(z.string()).optional().describe("Only files carrying all of these tags"),
85
85
  limit: z.number().int().positive().optional().describe("Maximum number of results"),
86
- },
86
+ }),
87
87
  annotations: readOnly,
88
88
  }, ({ query, tags, limit }) => run(async () => ({ result: await runSearch(vault, query, { tags, limit }) })));
89
89
  server.registerTool("read", {
90
90
  title: "Read a file",
91
91
  description: "One file's id, frontmatter and body. Call it before update, which needs the file's complete new content.",
92
- inputSchema: { id: z.string().describe("The file's UUID") },
92
+ inputSchema: z.object({ id: z.string().describe("The file's UUID") }),
93
93
  annotations: readOnly,
94
94
  }, ({ id }) => run(async () => {
95
95
  const file = await readVaultFile(resolveVaultDir(vault), id);
@@ -98,11 +98,11 @@ export function createMcpServer(options) {
98
98
  server.registerTool("validate", {
99
99
  title: "Validate",
100
100
  description: "Checks without writing anything. With frontmatter (and body): a candidate file, exactly as create would check it. With id: one existing file. With neither: the whole world.",
101
- inputSchema: {
101
+ inputSchema: z.object({
102
102
  id: z.string().optional().describe("Check one existing file"),
103
103
  frontmatter: fileInput.frontmatter.optional(),
104
104
  body: fileInput.body,
105
- },
105
+ }),
106
106
  annotations: readOnly,
107
107
  }, ({ id, frontmatter, body }) => run(async () => {
108
108
  const candidate = frontmatter ? { frontmatter, body } : undefined;
@@ -113,7 +113,7 @@ export function createMcpServer(options) {
113
113
  server.registerTool("create", {
114
114
  title: "Create a file",
115
115
  description: "Creates a new entity or event file under a new UUID, after the same checks as validate; on any error nothing is written. Returns the new id. Show the user the content and get their go-ahead first.",
116
- inputSchema: fileInput,
116
+ inputSchema: z.object(fileInput),
117
117
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
118
118
  }, ({ frontmatter, body }) => run(async () => {
119
119
  const outcome = await runCreate(vault, { frontmatter, body });
@@ -122,7 +122,7 @@ export function createMcpServer(options) {
122
122
  server.registerTool("update", {
123
123
  title: "Correct a file",
124
124
  description: "Replaces an existing file's whole content, for corrections only; a change in the story is a new version (create with supersedes and causedBy). Call read first and send the complete content: fields you leave out are removed. type can't change. A changed title is also rewritten in other files' links. Show the user the change and get their go-ahead first.",
125
- inputSchema: { id: z.string().describe("The file's UUID"), ...fileInput },
125
+ inputSchema: z.object({ id: z.string().describe("The file's UUID"), ...fileInput }),
126
126
  annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
127
127
  }, ({ id, frontmatter, body }) => run(async () => {
128
128
  const outcome = await runUpdate(vault, id, { frontmatter, body });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "world-building-framework",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Build, search and publish fictional worlds from a vault of Markdown files: the wbf CLI and its core engine.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  "prepublishOnly": "npm run typecheck && npm test"
33
33
  },
34
34
  "dependencies": {
35
- "@modelcontextprotocol/sdk": "^1.32.2",
35
+ "@modelcontextprotocol/server": "^2.4.0",
36
36
  "better-sqlite3": "^13.0.3",
37
37
  "commander": "^15.0.0",
38
38
  "gray-matter": "^4.0.3",
@@ -40,6 +40,7 @@
40
40
  "zod": "^4.6.7"
41
41
  },
42
42
  "devDependencies": {
43
+ "@modelcontextprotocol/client": "^2.4.0",
43
44
  "@types/better-sqlite3": "^9.6.0",
44
45
  "@types/node": "^22.20.1",
45
46
  "glob": "^13.0.6",
@@ -21,25 +21,30 @@ jobs:
21
21
  build:
22
22
  runs-on: ubuntu-latest
23
23
  steps:
24
- - uses: actions/checkout@v4
24
+ - uses: actions/checkout@v7
25
+ with:
26
+ # Nothing here pushes, so the git token isn't kept around.
27
+ persist-credentials: false
25
28
 
26
- - uses: actions/setup-node@v4
29
+ # No npm cache: setup-node advises against caching in workflows with
30
+ # Pages and id-token permissions (cache poisoning), and the install is small.
31
+ - uses: actions/setup-node@v7
27
32
  with:
28
33
  node-version: 22
29
- cache: npm
34
+ package-manager-cache: false
30
35
 
31
36
  - name: Install the framework (version pinned in package.json)
32
37
  run: npm ci
33
38
 
34
39
  # Runs before publish so its base_url output (the Pages site's real
35
40
  # address) can be handed to Quartz.
36
- - uses: actions/configure-pages@v5
41
+ - uses: actions/configure-pages@v6
37
42
  id: pages
38
43
 
39
44
  - name: Publish every build variant
40
45
  run: npx wbf publish --output ./site --base-url "${{ steps.pages.outputs.base_url }}"
41
46
 
42
- - uses: actions/upload-pages-artifact@v3
47
+ - uses: actions/upload-pages-artifact@v5
43
48
  with:
44
49
  path: ./site
45
50
 
@@ -50,5 +55,5 @@ jobs:
50
55
  name: github-pages
51
56
  url: ${{ steps.deployment.outputs.page_url }}
52
57
  steps:
53
- - uses: actions/deploy-pages@v4
58
+ - uses: actions/deploy-pages@v5
54
59
  id: deployment