virtualmatter 0.4.1 → 0.5.0
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 +9 -7
- package/dist/agentfiles.js +47 -18
- package/dist/agents-md.generated.js +6 -0
- package/dist/index.js +7 -6
- package/dist/pull.js +2 -1
- package/dist/resolve.js +1 -1
- package/dist/urls.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ One command. It signs you in on first use (device code, approved in your
|
|
|
21
21
|
browser), creates the world, and mirrors its files into `./my-world`:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npx virtualmatter
|
|
24
|
+
npx virtualmatter make "My world"
|
|
25
25
|
cd my-world
|
|
26
26
|
npx virtualmatter sync
|
|
27
27
|
```
|
|
@@ -64,15 +64,17 @@ cannot be steered after its first turn.
|
|
|
64
64
|
|
|
65
65
|
## Hook up a coding agent (MCP)
|
|
66
66
|
|
|
67
|
-
A folder
|
|
68
|
-
Code), `.cursor/mcp.json` (Cursor),
|
|
69
|
-
|
|
70
|
-
and
|
|
67
|
+
A folder made by `make` or `pull` already carries `.mcp.json` (Claude
|
|
68
|
+
Code), `.cursor/mcp.json` (Cursor), `.codex/config.toml` (Codex, which loads
|
|
69
|
+
it once you trust the folder), `AGENTS.md` (Codex, Cursor, and most agents),
|
|
70
|
+
and a `CLAUDE.md` that imports it - open the folder in your agent and it finds
|
|
71
|
+
the MCP server and the project briefing on its own.
|
|
71
72
|
|
|
72
73
|
To register the server by hand, from anywhere:
|
|
73
74
|
|
|
74
75
|
```bash
|
|
75
76
|
claude mcp add virtualmatter -- npx -y virtualmatter mcp
|
|
77
|
+
codex mcp add virtualmatter -- npx -y virtualmatter mcp
|
|
76
78
|
```
|
|
77
79
|
|
|
78
80
|
It works before a world is selected: `list_projects`, `create_project`, and
|
|
@@ -87,7 +89,7 @@ deploying it.
|
|
|
87
89
|
|
|
88
90
|
| Command | What it does |
|
|
89
91
|
| --- | --- |
|
|
90
|
-
| `
|
|
92
|
+
| `make <name> [dir]` (`create`) | Make a world (region defaults to the nearest; `--region`, `--track`, `--description`, `--no-pull`, `--open`, `--json`) and mirror it into `./<slug>`. |
|
|
91
93
|
| `list` (`ls`, `projects`) | Your worlds with framing ids and edit/play URLs (`--json`). |
|
|
92
94
|
| `pull [target] [dir]` | Mirror a world's file tree. `target` is any Virtual Matter link or a framing id; omitted, it uses this folder's world or your only one. |
|
|
93
95
|
| `sync [dir]` | Watch + two-way sync with the live session. Ctrl-C to stop. |
|
|
@@ -109,7 +111,7 @@ deploying it.
|
|
|
109
111
|
folder, so a newer build never overwrites the one you are running.
|
|
110
112
|
- Sync skips `Uploads/`, `Screenshots/`, `Agent Logs/`, dotfiles, the
|
|
111
113
|
harness files the CLI writes (`AGENTS.md`, `CLAUDE.md`, `.mcp.json`,
|
|
112
|
-
`.cursor/`, `.virtualmatter.json`), and the SDK's in-session tooling at the
|
|
114
|
+
`.cursor/`, `.codex/`, `.virtualmatter.json`), and the SDK's in-session tooling at the
|
|
113
115
|
Montage root (`atomo`, `vm_auth.py`, the agent-log hooks) - those only work
|
|
114
116
|
inside a running session.
|
|
115
117
|
- The pulled `AGENTS.md` is the platform guide followed by the world's own
|
package/dist/agentfiles.js
CHANGED
|
@@ -2,27 +2,16 @@
|
|
|
2
2
|
* The files that make a pulled folder self-describing to whichever harness
|
|
3
3
|
* opens it: AGENTS.md (Codex, Cursor, and most others read it), CLAUDE.md
|
|
4
4
|
* (Claude Code reads this one and imports AGENTS.md through it), and the
|
|
5
|
-
* MCP registrations Claude Code (`.mcp.json`)
|
|
6
|
-
* discover on their own. Existing files are
|
|
7
|
-
* own notes win - except AGENTS.md, which the
|
|
5
|
+
* MCP registrations Claude Code (`.mcp.json`), Cursor (`.cursor/mcp.json`)
|
|
6
|
+
* and Codex (`.codex/config.toml`) discover on their own. Existing files are
|
|
7
|
+
* never overwritten - a maker's own notes win - except AGENTS.md, which the
|
|
8
|
+
* CLI owns; the Codex config gets our server appended if it lacks one.
|
|
8
9
|
*/
|
|
9
10
|
import fs from "node:fs";
|
|
10
11
|
import path from "node:path";
|
|
12
|
+
import { parse as parseToml } from "smol-toml";
|
|
13
|
+
import { AGENTS_MD_FALLBACK } from "./agents-md.generated.js";
|
|
11
14
|
import { apiBase } from "./config.js";
|
|
12
|
-
export const AGENTS_MD_STUB = `# Working with Virtual Matter
|
|
13
|
-
|
|
14
|
-
This folder is a live mirror of a Virtual Matter world's Montage files.
|
|
15
|
-
|
|
16
|
-
- \`npx virtualmatter sync\` keeps it in sync with the running session.
|
|
17
|
-
- \`npx virtualmatter agent-logs setup\` enables automatic local conversation logs.
|
|
18
|
-
- \`npx virtualmatter run-lua --code "..."\` executes Lua in the engine.
|
|
19
|
-
- \`npx virtualmatter errors\` shows recent engine errors.
|
|
20
|
-
- \`npx virtualmatter screenshot -o shot.png\` captures the current view.
|
|
21
|
-
- \`npx virtualmatter open\` opens this world in the native desktop client.
|
|
22
|
-
- Lua scripts under this tree hot-reload in the engine when saved.
|
|
23
|
-
|
|
24
|
-
Do not edit \`.virtualmatter.json\` - it is sync bookkeeping.
|
|
25
|
-
`;
|
|
26
15
|
export async function fetchAgentsMd(fetchFn = fetch) {
|
|
27
16
|
try {
|
|
28
17
|
const res = await fetchFn(`${apiBase()}/AGENTS.md`);
|
|
@@ -35,7 +24,7 @@ export async function fetchAgentsMd(fetchFn = fetch) {
|
|
|
35
24
|
catch {
|
|
36
25
|
/* fall through to the stub */
|
|
37
26
|
}
|
|
38
|
-
return
|
|
27
|
+
return AGENTS_MD_FALLBACK;
|
|
39
28
|
}
|
|
40
29
|
const CLAUDE_MD = `@AGENTS.md
|
|
41
30
|
|
|
@@ -50,6 +39,35 @@ function mcpServerConfig() {
|
|
|
50
39
|
args: ["-y", "virtualmatter", "mcp"],
|
|
51
40
|
};
|
|
52
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* The folder's `.codex/config.toml` with our MCP server in it, or null to
|
|
44
|
+
* leave the file as it is. Codex has no `.mcp.json`: it reads MCP servers from
|
|
45
|
+
* `.codex/config.toml`, and loads a project's copy only once the maker trusts
|
|
46
|
+
* the folder. `agent-logs setup` writes `[features]` into the same file, so
|
|
47
|
+
* our table is appended rather than the file rewritten (a maker's comments
|
|
48
|
+
* survive). An existing `virtualmatter` entry is never replaced, and a file
|
|
49
|
+
* that does not parse - or would not parse with our table added, e.g. an
|
|
50
|
+
* inline `mcp_servers = { ... }` - is left alone.
|
|
51
|
+
*/
|
|
52
|
+
export function codexConfigWithServer(existing) {
|
|
53
|
+
const { command, args } = mcpServerConfig();
|
|
54
|
+
const table = "[mcp_servers.virtualmatter]\n" +
|
|
55
|
+
`command = ${JSON.stringify(command)}\n` +
|
|
56
|
+
`args = ${JSON.stringify(args)}\n`;
|
|
57
|
+
if (existing === null || existing.trim() === "")
|
|
58
|
+
return table;
|
|
59
|
+
try {
|
|
60
|
+
const servers = (parseToml(existing).mcp_servers ?? {});
|
|
61
|
+
if (servers.virtualmatter !== undefined)
|
|
62
|
+
return null;
|
|
63
|
+
const next = `${existing.replace(/\n*$/, "\n")}\n${table}`;
|
|
64
|
+
parseToml(next);
|
|
65
|
+
return next;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
53
71
|
/**
|
|
54
72
|
* The SDK's own AGENTS.md ships inside every Montage tree. It is written for
|
|
55
73
|
* the in-session agent that drives the engine through `atomo`, which only
|
|
@@ -111,5 +129,16 @@ export function writeAgentFiles(dir, agentsMd) {
|
|
|
111
129
|
const mcp = JSON.stringify({ mcpServers: { virtualmatter: mcpServerConfig() } }, null, 2) + "\n";
|
|
112
130
|
put(".mcp.json", mcp, false);
|
|
113
131
|
put(path.join(".cursor", "mcp.json"), mcp, false);
|
|
132
|
+
const codexRel = path.join(".codex", "config.toml");
|
|
133
|
+
const codexAbs = path.join(dir, codexRel);
|
|
134
|
+
const codex = codexConfigWithServer(fs.existsSync(codexAbs) ? fs.readFileSync(codexAbs, "utf8") : null);
|
|
135
|
+
if (codex === null) {
|
|
136
|
+
kept.push(codexRel);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
fs.mkdirSync(path.dirname(codexAbs), { recursive: true });
|
|
140
|
+
fs.writeFileSync(codexAbs, codex);
|
|
141
|
+
written.push(codexRel);
|
|
142
|
+
}
|
|
114
143
|
return { written, kept };
|
|
115
144
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Generated by frontend/scripts/sync-cli-agents-md.mjs - do not edit.
|
|
2
|
+
// The same bytes https://make.virtualmatter.ai/AGENTS.md serves, built from
|
|
3
|
+
// frontend/content/agent-briefing.md and AGENTS.source.md. The CLI writes
|
|
4
|
+
// this into a world folder only when it cannot fetch the live copy. After
|
|
5
|
+
// changing either source, run: node frontend/scripts/sync-cli-agents-md.mjs
|
|
6
|
+
export const AGENTS_MD_FALLBACK = "# AGENTS.md - working with a Virtual Matter project\n\nThis file tells a coding agent how to think about a Virtual Matter project. The\n`virtualmatter` CLI drops a copy into every local project mirror it creates\n(`virtualmatter pull`); the canonical copy lives at\nhttps://make.virtualmatter.ai/AGENTS.md.\n\n## The mental model\n\n- The world itself runs on Virtual Matter servers, not on the maker's machine. There is\n one authoritative server simulation per world session, and any number of connected\n clients (browser WASM or the native client).\n- The project's content is SDK Lua scripts plus assets (voxel data, prefabs, images,\n sounds) under a `Montage/` tree. Virtual Matter can publish that tree to a GitHub repo\n in the maker's account for versioning and remixing; pushing to that repo does not feed\n back into the running world today - live edits happen in the session.\n- Changes hot-reload. Saving a `.lua` file in the live session's Montage tree re-runs\n the module and its `Start()` on a fresh instance inside the running world - no restart,\n no build step.\n- Prefabs are reusable scene-graph snippets: JSON files with a `.prefab` extension in the\n Montage folder, instantiated at runtime via `Server:InsertPrefab(asset)`.\n- There is no local runtime - the world cannot run on the maker's machine. The\n `virtualmatter` CLI (npm) is how you reach it from a local harness, and it needs no\n setup: the first command that needs an account signs you in with a device code.\n `npx virtualmatter make \"My world\"` makes a world and mirrors its Montage tree\n into `./my-world`; `npx virtualmatter pull <any Virtual Matter link>` mirrors an\n existing one (/edit, /play, /g, /p, /projects links all work, with or without a\n readable slug); `npx virtualmatter list` shows your worlds; `npx virtualmatter sync`\n live-pushes saves into the running session (which hot-reloads them);\n `npx virtualmatter run-lua` / `errors` / `screenshot` drive the engine;\n `npx virtualmatter open` downloads the native desktop client on first use, signs it\n in with your account, and opens the world in it; and `npx virtualmatter mcp` serves\n all of it over MCP. A mirrored folder carries `.mcp.json` and `.cursor/mcp.json`\n (so Claude Code and Cursor register the MCP server on their own), this file, and a\n `CLAUDE.md` that imports it. Folders from virtualmatter 0.5.0 on also carry\n `.codex/config.toml`, which Codex loads once you trust the folder; with an older\n CLI, or if Codex does not list the server, register it once with\n `codex mcp add virtualmatter -- npx -y virtualmatter mcp`. In Claude Code outside a\n mirrored folder, use `claude mcp add virtualmatter -- npx -y virtualmatter mcp`. The\n server works before a world\n is selected (`list_projects`, `create_project`, `select_project`), then exposes\n `list_files`, `read_file`, `write_file`, `run_lua`, `get_engine_errors`,\n `capture_screenshot`, `open_native_client`, and `world_info`.\n- Work through the CLI, not the website. Do not open make.virtualmatter.ai in a browser\n and do not prompt the built-in agent there: it spends Virtual Matter's platform credits\n instead of your own subscription, an anonymous browser session cannot be steered after\n its first turn, and you cannot read engine errors from a rendered page. The CLI does\n everything that agent does, from your own harness.\n- Seeing your work: `virtualmatter screenshot` shoots a default overview of the world\n origin, `--target <object>` frames one object by name or id, and `--at x,y,z --rot\n yaw,pitch,roll` places the camera exactly. Y is up and -Z is forward, and the\n rotation really is yaw first: yaw 0 faces -Z, pitch -90 looks straight down, pitch 0\n is the horizon. The MCP `capture_screenshot`\n tool takes the same arguments. Verify a change with a screenshot plus `errors` rather\n than assuming a write worked.\n- The mirrored folder's AGENTS.md is this guide followed by the engine SDK's own agent guide\n (the AGENTS.md that lives in every Montage tree and inside the desktop client's\n Data/Sdk/Montage/). The engine guide assumes an in-session agent driving the engine\n through `atomo`; the merged file maps each `atomo` step to the CLI or MCP equivalent, and\n the `Skills/*.md` references it points at are in the folder. The SDK's own tooling\n (`atomo`, `vm_auth.py`, the agent-log hooks) is not mirrored: it only works inside a\n session. Sandboxed agents need network access for every CLI command.\n\n## Reference\n\nThe same facts as terse lists, for quick lookup.\n\n### Project model\n- A project (\"montage\") is one voxel world hosted with Virtual Matter.\n- A project has framings: \"make\" framings (editing sessions) and \"play\"\n framings (public play sessions). A framing is a running session slot\n on a voxel host.\n- Project content = SDK Lua scripts + assets under a Montage/ tree.\n Edits made in the live session hot-reload into the running world.\n The tree can be published to a maker-owned GitHub repo.\n\n### URL shapes (make.virtualmatter.ai)\n- /new builder for people: create a world from a prompt\n (also at https://virtualmatter.ai/); coding agents\n use npx virtualmatter make instead\n- /edit/<framing-id> maker session: live world + agent chat\n (also /edit/<slug>-<framing-id>; the CLI accepts both)\n- /play/<framing-id> play session for a specific framing\n- /g/<id> share URL resolver: 302s to a live session\n\n### APIs (unauthenticated)\n- GET https://make.virtualmatter.ai/api/v1/public/native-clients\n JSON: { iteration, clients: [{ platform, kind, url, filename,\n file_size, branch, commit, match }] } - per-platform native client\n installers (kind \"download\") or store links (kind \"store\", iOS).\n\n### CLI + MCP (npm package \"virtualmatter\", Node >= 20)\n- npx virtualmatter make \"<name>\" make a world, mirror it into ./<slug>\n- npx virtualmatter pull <link> mirror an existing world (any link shape)\n- npx virtualmatter list your worlds with framing ids + URLs\n- npx virtualmatter sync live-push saves into the running world\n- npx virtualmatter open open the world in the native client\n- npx virtualmatter mcp stdio MCP server (list_projects,\n create_project, select_project, list_files, read_file, write_file,\n run_lua, get_engine_errors, capture_screenshot, open_native_client,\n world_info)\n- Sign-in happens on first use (device code); no separate login step.\n- A mirrored folder carries .mcp.json, .cursor/mcp.json, AGENTS.md and\n CLAUDE.md, so Claude Code and Cursor register the server on their own.\n- Codex: folders from 0.5.0 on carry .codex/config.toml, loaded once the\n folder is trusted; otherwise register the server once:\n codex mcp add virtualmatter -- npx -y virtualmatter mcp\n\n## SDK Lua cheat sheet\n\nThe scripting language is Lua 5.4, sandboxed: `os`, `io`, `require`, `package`,\n`dofile`, `loadfile`, `loadstring` are nil. `math`, `string`, `table`, `coroutine`\nremain. No `os.time` - use `Time.time` (sim time), `Time.frame`, or\n`AE:GetDebugTime()` (wall clock).\n\n### Script shape\n\nEvery persistent behavior is a `.lua` file in the Montage tree returning a `self` table:\n\n```lua\nlocal self = {}\nfunction self:Start() end\nfunction self:Update(deltaTime) end\nreturn self\n```\n\nAttach to an object with `obj:AddScript(\"My Folder/Example.lua\", sync)` - the path is\nrelative to the Montage root; `sync = true` replicates the script to clients.\n`obj:FindScript(\"Example\")` returns the live instance.\n\n### Server / client split\n\nThe same script runs on the server and (when synced) on every client. Branch with\n`self.onServer` / `self.onClient`:\n\n```lua\nfunction self:Update(dt)\n if self.onClient then return end -- voxel edits are server-only\n -- authoritative logic here\nend\n```\n\nNothing replicates automatically: set `syncToClients = true` on the script or\nVoxelData component, and use `util:makeNetworkedTable(self, { hp = 100 })` for\nproperties that should sync (server writes, clients read, deltas only).\n`obj.pos` / `obj.rot` do not auto-sync - replicate them yourself.\n\n### RPC\n\n```lua\nself:RPC(\"serverDoSomething\", pos, dir) -- on a client: goes to the server\nfunction self:serverDoSomething(pos, dir, clientID) -- clientID auto-appended\n assert(self.onServer)\nend\n```\n\nOn the server, `self:RPC(...)` fans out to all clients. Reliable, FIFO per direction.\nRequires `self.component.syncToClients = true`.\n\n### Scene and objects (server)\n\n```lua\nlocal ob = Scene:CreateObject(\"Name\")\nob.save = true\nob:AddScript(\"Path/Script.lua\")\nScene:GetObjectByName(\"Name\")\nScene:CloneObject(ob) -- prefer over rebuilding\nob.active = false -- prefer over destroy\nob:AddTag(\"Enemy\"); FindObjectsWithTag(\"Enemy\") -- tags are runtime-only state\n```\n\n### Voxel editing (server only, async)\n\n```lua\nVox:Add(Sphere(pos, 2)):Color(1, 0, 0):Run()\nVox:Add(Box(Vec3(0, -1, 0), Vec3(20, 2, 20))):ForceStatic():Run()\n```\n\nShapes: `Box(center, fullSize)`, `Sphere(center, r)`, `Capsule(p1, p2, r)`,\n`Cylinder(p1, p2, r1[, r2])`. `Run()` is async - chain `:OnFinished(fn)` before\n`:Run()` to read post-commit state. Big edits stall the frame for every client;\nkeep in-game edits small and infrequent.\n\n### Input (event-driven, client input reaches the server)\n\n```lua\nself.component.syncToClients = true\nevents.keyDown.addListener(self, function(key, from) self.keys[key] = true end)\nevents.keyUp.addListener(self, function(key, from) self.keys[key] = false end)\n```\n\nPlayer-driven movement must be client-predicted - never gate the player's own\nfeedback on the server round-trip.\n\n### Physics\n\n```lua\nlocal rb = obj:AddComponent(\"RigidBody\")\nrb:AddImpulse(Vec3(0, 50, 0), obj.pos)\nrb.velocity; rb.mass; rb.gravityScale\n```\n\n### Time and diagnostics\n\n```lua\nTime.dt; Time.time; Time.frame; Time.timeScale\nAE:GetLogValue(\"Raycasts\") -- engine counters, e.g. raycasts this frame\nAE:GetAssets() -- list all assets (APIs take Assets, not paths)\n```\n\n### UI (client-side HUD)\n\nBuild screen UI with the MUI builder: `UI:AddPanel|AddButton|AddLabel|AddSlider|...`\nchained with `:Set{...}`; flexbox-like row-wrap layout.\n\n## Conventions\n\n- Coordinates: Y is up, -Z is forward, X is right.\n- Script files are named in capital case with spaces (`Character Controller.lua`).\n- Check whether a script is already attached before adding it - duplicates run twice.\n- The server is for authority (world edits, spawns, state); clients are for feel\n (prediction, FX, UI).\n\n## Embed or build a world for an existing website\n\nFor a shared project link, fetch `/api/v1/public/embed?target=<encoded-link>`\nand follow `/embed-guide.md`. Use the returned canonical player URL, not the\nmaker's external website URL. Keep the existing website and its design.\n\nFor account discovery or prompt-based creation, connect the hosted MCP at\n`https://make.virtualmatter.ai/api/v1/mcp` using OAuth. Users can sign up in\nthe connection flow. Tools: `list_projects`, `get_embed`, `create_project`\n(with a prompt and stable request_id), `get_build_status`. VM's agent builds\nusing VM credits. Review and share the private world before embedding.\nThe local CLI exposes `embed`, `build --prompt --request-id`, and `build-status`.\n\n## Local conversation history\n\nAfter pulling a project, run `virtualmatter agent-logs setup` once to enable\nfuture chat history capture for local harnesses. It adds Codex, Claude Code,\nCursor, and (when installed) Hermes hooks without replacing existing hooks.\nKeep `virtualmatter sync` or `virtualmatter agent-logs watch` running for retry\nand delayed transcript capture. Follow each harness's normal hook review and\nrestart flow. Use `agent-logs status` to inspect pending uploads and\n`agent-logs disable` to stop capture.\n\nOther harnesses can send portable public event JSONL with\n`virtualmatter agent-logs upload <file> --harness <name> --session <id>`, or use\nMCP `upload_agent_logs`. Supply stable event IDs for retries; omit private\nreasoning, system/developer prompts, credentials, and binary media.\n";
|
package/dist/index.js
CHANGED
|
@@ -157,7 +157,7 @@ program
|
|
|
157
157
|
return;
|
|
158
158
|
}
|
|
159
159
|
if (projects.length === 0) {
|
|
160
|
-
console.log('No worlds yet.
|
|
160
|
+
console.log('No worlds yet. Make one: npx virtualmatter make "My world"');
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
163
|
console.log(formatProjectList(projects));
|
|
@@ -165,11 +165,12 @@ program
|
|
|
165
165
|
console.log("Pull one: npx virtualmatter pull <framing id or URL>");
|
|
166
166
|
}));
|
|
167
167
|
program
|
|
168
|
-
.command("
|
|
169
|
-
// `make`
|
|
170
|
-
//
|
|
171
|
-
.
|
|
172
|
-
.
|
|
168
|
+
.command("make")
|
|
169
|
+
// `make` is the product's own verb: the builder lives at
|
|
170
|
+
// make.virtualmatter.ai and its main button says Make. `create` stays as an
|
|
171
|
+
// alias so instructions written before 0.4.1 keep working.
|
|
172
|
+
.alias("create")
|
|
173
|
+
.description("Make a new world and mirror its files into a local folder (alias: create)")
|
|
173
174
|
.argument("<name>", "the world's name")
|
|
174
175
|
.argument("[dir]", "destination folder (default: ./<name-as-slug>)")
|
|
175
176
|
.option("--region <region>", "NA, EU, or AS (default: nearest)")
|
package/dist/pull.js
CHANGED
|
@@ -6,7 +6,8 @@ import { composeAgentsMd, fetchAgentsMd, writeAgentFiles } from "./agentfiles.js
|
|
|
6
6
|
import { FilesClient } from "./files.js";
|
|
7
7
|
import { isIgnoredPath } from "./ignore.js";
|
|
8
8
|
import { saveState } from "./state.js";
|
|
9
|
-
export {
|
|
9
|
+
export { fetchAgentsMd } from "./agentfiles.js";
|
|
10
|
+
export { AGENTS_MD_FALLBACK } from "./agents-md.generated.js";
|
|
10
11
|
/** Download workers per pull. The tree is ~1000 small files; sequential
|
|
11
12
|
* GETs left the command silent for minutes. Eight in flight keeps a
|
|
12
13
|
* single origin comfortable while cutting wall clock roughly 6-8x. */
|
package/dist/resolve.js
CHANGED
|
@@ -39,7 +39,7 @@ export async function resolveImplicitTarget(dir, fetchFn = fetch) {
|
|
|
39
39
|
if (projects.length === 1)
|
|
40
40
|
return { framingId: projects[0].make_framing_id, project: projects[0] };
|
|
41
41
|
if (projects.length === 0) {
|
|
42
|
-
throw new Error('You have no projects yet.
|
|
42
|
+
throw new Error('You have no projects yet. Make one with `npx virtualmatter make "My world"`.');
|
|
43
43
|
}
|
|
44
44
|
throw new NeedsChoiceError(projects);
|
|
45
45
|
}
|
package/dist/urls.js
CHANGED
|
@@ -110,7 +110,7 @@ export function parseTarget(input) {
|
|
|
110
110
|
if (first === "new" || parts.length === 0) {
|
|
111
111
|
return {
|
|
112
112
|
kind: "invalid",
|
|
113
|
-
reason: "That link is the home page, not a world. Run `npx virtualmatter
|
|
113
|
+
reason: "That link is the home page, not a world. Run `npx virtualmatter make \"My world\"` to start one, or `npx virtualmatter list` to see yours.",
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
116
|
return { kind: "invalid", reason: `Unrecognized Virtual Matter URL path: ${url.pathname}` };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "virtualmatter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI + MCP server for building with Virtual Matter - list and create worlds, sync their files, run Lua, capture screenshots, open the native client, and wire coding agents into a live session.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|