@crowdedkingdoms/crowdy-dsh 0.2.0-dev.1 → 0.2.0-dev.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/THIRD_PARTY_NOTICES.md +226 -0
- package/dist/dsh-web/BUILD.json +3 -3
- package/dist/dsh-web/preview/vfs-image.tar.gz +0 -0
- package/lib/attachments/crowdy-attachment-store.js +200 -0
- package/lib/attachments/crowdy-attachment-store.js.map +1 -0
- package/lib/bridge/client.js +161 -0
- package/lib/bridge/client.js.map +1 -0
- package/lib/bridge/index.js +155 -0
- package/lib/bridge/index.js.map +1 -0
- package/lib/bridge/protocol.js +30 -0
- package/lib/bridge/protocol.js.map +1 -0
- package/lib/crowdy/client.js +247 -0
- package/lib/crowdy/client.js.map +1 -0
- package/lib/crowdy/config.js +95 -0
- package/lib/crowdy/config.js.map +1 -0
- package/lib/crowdy/github-layout.js +97 -0
- package/lib/crowdy/github-layout.js.map +1 -0
- package/lib/crowdy/paths.js +145 -0
- package/lib/crowdy/paths.js.map +1 -0
- package/lib/crowdy/project-store.js +223 -0
- package/lib/crowdy/project-store.js.map +1 -0
- package/lib/fs/crowdy-file-system.js +621 -0
- package/lib/fs/crowdy-file-system.js.map +1 -0
- package/lib/fs/scratch-store.js +61 -0
- package/lib/fs/scratch-store.js.map +1 -0
- package/lib/index.js +15 -0
- package/lib/index.js.map +1 -0
- package/lib/persist/index.js +199 -0
- package/lib/persist/index.js.map +1 -0
- package/lib/scripts/probe.js +59 -0
- package/lib/scripts/probe.js.map +1 -0
- package/lib/sdk-index/catalog.js +237 -0
- package/lib/sdk-index/catalog.js.map +1 -0
- package/lib/sdk-index/index.js +10 -0
- package/lib/sdk-index/index.js.map +1 -0
- package/lib/sdk-index/parse-sdk.js +131 -0
- package/lib/sdk-index/parse-sdk.js.map +1 -0
- package/lib/sdk-index/plugin.js +90 -0
- package/lib/sdk-index/plugin.js.map +1 -0
- package/lib/sdk-index/snapshot.js +215 -0
- package/lib/sdk-index/snapshot.js.map +1 -0
- package/lib/search/glob-match.js +114 -0
- package/lib/search/glob-match.js.map +1 -0
- package/lib/search/search-tools.js +414 -0
- package/lib/search/search-tools.js.map +1 -0
- package/lib/tools/index.js +344 -0
- package/lib/tools/index.js.map +1 -0
- package/lib/types/attachments/crowdy-attachment-store.d.ts +45 -0
- package/lib/types/attachments/crowdy-attachment-store.d.ts.map +1 -0
- package/lib/types/attachments/crowdy-attachment-store.test.d.ts.map +1 -0
- package/lib/types/bridge/client.d.ts +57 -0
- package/lib/types/bridge/client.d.ts.map +1 -0
- package/lib/types/bridge/client.test.d.ts.map +1 -0
- package/lib/types/bridge/index.d.ts +66 -0
- package/lib/types/bridge/index.d.ts.map +1 -0
- package/lib/types/bridge/protocol.d.ts +242 -0
- package/lib/types/bridge/protocol.d.ts.map +1 -0
- package/lib/types/crowdy/client.d.ts +126 -0
- package/lib/types/crowdy/client.d.ts.map +1 -0
- package/lib/types/crowdy/client.test.d.ts.map +1 -0
- package/lib/types/crowdy/config.d.ts +60 -0
- package/lib/types/crowdy/config.d.ts.map +1 -0
- package/lib/types/crowdy/github-layout.d.ts +36 -0
- package/lib/types/crowdy/github-layout.d.ts.map +1 -0
- package/lib/types/crowdy/paths.d.ts +89 -0
- package/lib/types/crowdy/paths.d.ts.map +1 -0
- package/lib/types/crowdy/project-store.d.ts +84 -0
- package/lib/types/crowdy/project-store.d.ts.map +1 -0
- package/lib/types/crowdy/project-store.test.d.ts.map +1 -0
- package/lib/types/fs/crowdy-file-system.d.ts +173 -0
- package/lib/types/fs/crowdy-file-system.d.ts.map +1 -0
- package/lib/types/fs/crowdy-file-system.test.d.ts.map +1 -0
- package/lib/types/fs/scratch-store.d.ts +31 -0
- package/lib/types/fs/scratch-store.d.ts.map +1 -0
- package/lib/types/index.d.ts +19 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/persist/index.d.ts +85 -0
- package/lib/types/persist/index.d.ts.map +1 -0
- package/lib/types/scripts/probe.d.ts +9 -0
- package/lib/types/scripts/probe.d.ts.map +1 -0
- package/lib/types/sdk-index/catalog.d.ts +39 -0
- package/lib/types/sdk-index/catalog.d.ts.map +1 -0
- package/lib/types/sdk-index/catalog.test.d.ts.map +1 -0
- package/lib/types/sdk-index/index.d.ts +13 -0
- package/lib/types/sdk-index/index.d.ts.map +1 -0
- package/lib/types/sdk-index/parse-sdk.d.ts +25 -0
- package/lib/types/sdk-index/parse-sdk.d.ts.map +1 -0
- package/lib/types/sdk-index/plugin.d.ts +26 -0
- package/lib/types/sdk-index/plugin.d.ts.map +1 -0
- package/lib/types/sdk-index/snapshot.d.ts +11 -0
- package/lib/types/sdk-index/snapshot.d.ts.map +1 -0
- package/lib/types/search/glob-match.d.ts +31 -0
- package/lib/types/search/glob-match.d.ts.map +1 -0
- package/lib/types/search/glob-match.test.d.ts.map +1 -0
- package/lib/types/search/search-tools.d.ts +81 -0
- package/lib/types/search/search-tools.d.ts.map +1 -0
- package/lib/types/search/search-tools.test.d.ts.map +1 -0
- package/lib/types/tools/index.d.ts +27 -0
- package/lib/types/tools/index.d.ts.map +1 -0
- package/lib/types/vendor/crowdyjs-sdk.d.ts +17 -0
- package/lib/types/vendor/crowdyjs-sdk.d.ts.map +1 -0
- package/lib/vendor/crowdyjs-sdk.js +18338 -0
- package/lib/vendor/crowdyjs-sdk.js.map +1 -0
- package/lib/vendor/crowdyjs-sdk.version.json +5 -0
- package/package.json +151 -38
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory files beside the project trees: screenshots under `captures/`,
|
|
3
|
+
* game observations / client logs / diagnostics under `context/`.
|
|
4
|
+
*
|
|
5
|
+
* These are not project files and never reach the game API. They exist so the
|
|
6
|
+
* stock `read` / `read_image` tools can open what the Studio page shared,
|
|
7
|
+
* through the same paths the model already knows.
|
|
8
|
+
*
|
|
9
|
+
* @module @crowdedkingdoms/crowdy-dsh/fs/scratch-store
|
|
10
|
+
*/
|
|
11
|
+
const MAX_FILES_PER_DIR = 40;
|
|
12
|
+
export class ScratchStore {
|
|
13
|
+
dirs = new Map();
|
|
14
|
+
counter = 0;
|
|
15
|
+
putText(dir, name, text) {
|
|
16
|
+
const bytes = new TextEncoder().encode(text);
|
|
17
|
+
return this.put(dir, name, bytes, text);
|
|
18
|
+
}
|
|
19
|
+
putBytes(dir, name, bytes) {
|
|
20
|
+
return this.put(dir, name, bytes, undefined);
|
|
21
|
+
}
|
|
22
|
+
get(dir, name) {
|
|
23
|
+
return this.dirs.get(dir)?.get(name);
|
|
24
|
+
}
|
|
25
|
+
list(dir) {
|
|
26
|
+
const files = this.dirs.get(dir);
|
|
27
|
+
if (!files)
|
|
28
|
+
return [];
|
|
29
|
+
return [...files.entries()]
|
|
30
|
+
.map(([name, file]) => ({ name, file }))
|
|
31
|
+
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
32
|
+
}
|
|
33
|
+
put(dir, name, bytes, text) {
|
|
34
|
+
let files = this.dirs.get(dir);
|
|
35
|
+
if (!files) {
|
|
36
|
+
files = new Map();
|
|
37
|
+
this.dirs.set(dir, files);
|
|
38
|
+
}
|
|
39
|
+
// Keep the bag bounded: drop the oldest entries first.
|
|
40
|
+
while (files.size >= MAX_FILES_PER_DIR && !files.has(name)) {
|
|
41
|
+
let oldest;
|
|
42
|
+
for (const entry of files) {
|
|
43
|
+
if (!oldest || entry[1].updatedAt < oldest[1].updatedAt)
|
|
44
|
+
oldest = entry;
|
|
45
|
+
}
|
|
46
|
+
if (!oldest)
|
|
47
|
+
break;
|
|
48
|
+
files.delete(oldest[0]);
|
|
49
|
+
}
|
|
50
|
+
this.counter += 1;
|
|
51
|
+
const file = {
|
|
52
|
+
bytes,
|
|
53
|
+
version: `scratch:${this.counter}`,
|
|
54
|
+
updatedAt: Date.now(),
|
|
55
|
+
...(text === undefined ? {} : { text }),
|
|
56
|
+
};
|
|
57
|
+
files.set(name, file);
|
|
58
|
+
return file;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=scratch-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scratch-store.js","sourceRoot":"","sources":["../../src/fs/scratch-store.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package entry: the Cordis plugin DSH mounts as `ctx.fs`, plus the sibling
|
|
3
|
+
* plugins a Crowdy composition inserts (search, SDK index, page bridge, tools,
|
|
4
|
+
* in-memory attachments). Each plugin is also reachable as a subpath export so
|
|
5
|
+
* a `cordis.patch.yml` row can name it directly.
|
|
6
|
+
*
|
|
7
|
+
* @module @crowdedkingdoms/crowdy-dsh
|
|
8
|
+
*/
|
|
9
|
+
export { CrowdyFileSystem, default, versionOf } from './fs/crowdy-file-system.js';
|
|
10
|
+
export { ScratchStore } from './fs/scratch-store.js';
|
|
11
|
+
export { CrowdyApiError, CrowdyStudioClient } from './crowdy/client.js';
|
|
12
|
+
export { loadCrowdyConfig, describeMissing, CROWDY_CONFIG_FILENAME } from './crowdy/config.js';
|
|
13
|
+
export { GitHubProjectStore, StudioProjectStore, selectProjectStore, isSourcePath, } from './crowdy/project-store.js';
|
|
14
|
+
export { CrowdyAttachmentStore, imageDimensions } from './attachments/crowdy-attachment-store.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAQvE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAE9F,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,GACb,MAAM,2BAA2B,CAAA;AAGlC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAA"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session persistence for the browser worker: mirror the harness home's
|
|
3
|
+
* durable state (session logs, projection caches, user settings) from the
|
|
4
|
+
* in-memory VFS into the origin-private file system, so a reload or a later
|
|
5
|
+
* visit restores the player's sessions.
|
|
6
|
+
*
|
|
7
|
+
* The page half (`web/crowdy-boot.ts`) reads the same OPFS directory before the
|
|
8
|
+
* worker boots and feeds it back as a pre-boot overlay, so nothing here needs
|
|
9
|
+
* to run before the tree is up. In Node (the developer cockpit) OPFS does not
|
|
10
|
+
* exist and the plugin is inert: the real disk already persists `$DSH_HOME`.
|
|
11
|
+
*
|
|
12
|
+
* @module @crowdedkingdoms/crowdy-dsh/persist
|
|
13
|
+
*/
|
|
14
|
+
import z from '@deepseek-ai/schemastery';
|
|
15
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
16
|
+
import { join, relative } from 'node:path';
|
|
17
|
+
/** Cordis plugin name used by loader diagnostics. */
|
|
18
|
+
export const name = 'crowdy-persist';
|
|
19
|
+
export const Config = z.object({
|
|
20
|
+
scope: z.string(),
|
|
21
|
+
intervalMs: z.number().default(3_000),
|
|
22
|
+
maxBytes: z.number().default(48 * 1024 * 1024),
|
|
23
|
+
});
|
|
24
|
+
/** Home-relative trees worth keeping across reloads. */
|
|
25
|
+
export const PERSISTED_HOME_TREES = ['sessions', 'storages'];
|
|
26
|
+
/** Home-relative single files worth keeping across reloads. */
|
|
27
|
+
export const PERSISTED_HOME_FILES = ['settings.yaml'];
|
|
28
|
+
/** Root directory name inside OPFS; scopes hang under it. */
|
|
29
|
+
export const OPFS_ROOT = 'crowdy-dsh';
|
|
30
|
+
function opfsRoot() {
|
|
31
|
+
const storage = globalThis.navigator?.storage;
|
|
32
|
+
if (!storage || typeof storage.getDirectory !== 'function')
|
|
33
|
+
return undefined;
|
|
34
|
+
return storage.getDirectory();
|
|
35
|
+
}
|
|
36
|
+
async function ensureDirectory(root, segments) {
|
|
37
|
+
let current = root;
|
|
38
|
+
for (const segment of segments)
|
|
39
|
+
current = await current.getDirectoryHandle(segment, { create: true });
|
|
40
|
+
return current;
|
|
41
|
+
}
|
|
42
|
+
/** Resolve the scope from row config, then `crowdy.json`, then a fixed default. */
|
|
43
|
+
export function resolveScope(config, home) {
|
|
44
|
+
if (config.scope)
|
|
45
|
+
return config.scope;
|
|
46
|
+
if (home) {
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(readFileSync(join(home, 'crowdy.json'), 'utf8'));
|
|
49
|
+
if (typeof parsed.persistScope === 'string' && parsed.persistScope)
|
|
50
|
+
return parsed.persistScope;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// No page config: fall through to the default scope.
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return 'default';
|
|
57
|
+
}
|
|
58
|
+
function listFiles(root, directory, out) {
|
|
59
|
+
let entries;
|
|
60
|
+
try {
|
|
61
|
+
entries = readdirSync(directory);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
for (const entry of entries) {
|
|
67
|
+
const path = join(directory, entry);
|
|
68
|
+
let info;
|
|
69
|
+
try {
|
|
70
|
+
info = statSync(path);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (info.isDirectory())
|
|
76
|
+
listFiles(root, path, out);
|
|
77
|
+
else if (info.isFile())
|
|
78
|
+
out.set(relative(root, path), { mtime: info.mtimeMs, size: info.size });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Snapshot of every persisted file under the home, keyed by home-relative path. */
|
|
82
|
+
export function snapshotHome(home) {
|
|
83
|
+
const out = new Map();
|
|
84
|
+
for (const tree of PERSISTED_HOME_TREES)
|
|
85
|
+
listFiles(home, join(home, tree), out);
|
|
86
|
+
for (const file of PERSISTED_HOME_FILES) {
|
|
87
|
+
try {
|
|
88
|
+
const info = statSync(join(home, file));
|
|
89
|
+
if (info.isFile())
|
|
90
|
+
out.set(file, { mtime: info.mtimeMs, size: info.size });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// absent
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
export class HomeMirror {
|
|
99
|
+
home;
|
|
100
|
+
scopeDir;
|
|
101
|
+
maxBytes;
|
|
102
|
+
warn;
|
|
103
|
+
seen = new Map();
|
|
104
|
+
running = false;
|
|
105
|
+
constructor(home, scopeDir, maxBytes, warn) {
|
|
106
|
+
this.home = home;
|
|
107
|
+
this.scopeDir = scopeDir;
|
|
108
|
+
this.maxBytes = maxBytes;
|
|
109
|
+
this.warn = warn;
|
|
110
|
+
}
|
|
111
|
+
/** Copy every file whose mtime moved since the last sweep. */
|
|
112
|
+
async sweep() {
|
|
113
|
+
if (this.running)
|
|
114
|
+
return 0;
|
|
115
|
+
this.running = true;
|
|
116
|
+
try {
|
|
117
|
+
const snapshot = snapshotHome(this.home);
|
|
118
|
+
const scope = await this.scopeDir;
|
|
119
|
+
let copied = 0;
|
|
120
|
+
let total = 0;
|
|
121
|
+
for (const [path, info] of snapshot) {
|
|
122
|
+
total += info.size;
|
|
123
|
+
if (this.seen.get(path) === info.mtime)
|
|
124
|
+
continue;
|
|
125
|
+
const bytes = readFileSync(join(this.home, path));
|
|
126
|
+
const segments = path.split('/');
|
|
127
|
+
const leaf = segments.pop();
|
|
128
|
+
const directory = await ensureDirectory(scope, segments);
|
|
129
|
+
const handle = await directory.getFileHandle(leaf, { create: true });
|
|
130
|
+
const writable = await handle.createWritable();
|
|
131
|
+
await writable.write(new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength));
|
|
132
|
+
await writable.close();
|
|
133
|
+
this.seen.set(path, info.mtime);
|
|
134
|
+
copied += 1;
|
|
135
|
+
}
|
|
136
|
+
if (total > this.maxBytes)
|
|
137
|
+
await this.trim(snapshot, total);
|
|
138
|
+
return copied;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
this.warn(`session mirror sweep failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
142
|
+
return 0;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
this.running = false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** Drop the oldest session directories from the mirror until under budget. */
|
|
149
|
+
async trim(snapshot, total) {
|
|
150
|
+
const sessions = new Map();
|
|
151
|
+
for (const [path, info] of snapshot) {
|
|
152
|
+
if (!path.startsWith('sessions/'))
|
|
153
|
+
continue;
|
|
154
|
+
const key = path.split('/').slice(0, 3).join('/');
|
|
155
|
+
const current = sessions.get(key) ?? { mtime: 0, size: 0 };
|
|
156
|
+
sessions.set(key, { mtime: Math.max(current.mtime, info.mtime), size: current.size + info.size });
|
|
157
|
+
}
|
|
158
|
+
const oldestFirst = [...sessions.entries()].sort((a, b) => a[1].mtime - b[1].mtime);
|
|
159
|
+
const scope = await this.scopeDir;
|
|
160
|
+
for (const [key, info] of oldestFirst) {
|
|
161
|
+
if (total <= this.maxBytes)
|
|
162
|
+
break;
|
|
163
|
+
const segments = key.split('/');
|
|
164
|
+
const leaf = segments.pop();
|
|
165
|
+
try {
|
|
166
|
+
const directory = await ensureDirectory(scope, segments);
|
|
167
|
+
await directory.removeEntry(leaf, { recursive: true });
|
|
168
|
+
total -= info.size;
|
|
169
|
+
for (const path of [...this.seen.keys()])
|
|
170
|
+
if (path.startsWith(`${key}/`))
|
|
171
|
+
this.seen.delete(path);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
this.warn(`session mirror trim failed for ${key}: ${error instanceof Error ? error.message : String(error)}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
export function apply(ctx, config = {}) {
|
|
180
|
+
const root = opfsRoot();
|
|
181
|
+
const home = process.env.DSH_HOME;
|
|
182
|
+
if (!root || !home) {
|
|
183
|
+
// Node cockpit or a browser without OPFS: the disk (or nothing) persists.
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const scope = resolveScope(config, home);
|
|
187
|
+
const scopeDir = root.then((directory) => ensureDirectory(directory, [OPFS_ROOT, ...scope.split('/').filter(Boolean)]));
|
|
188
|
+
const mirror = new HomeMirror(home, scopeDir, config.maxBytes ?? 48 * 1024 * 1024, (message) => {
|
|
189
|
+
console.warn(`crowdy-persist: ${message}`);
|
|
190
|
+
});
|
|
191
|
+
const interval = setInterval(() => {
|
|
192
|
+
void mirror.sweep();
|
|
193
|
+
}, config.intervalMs ?? 3_000);
|
|
194
|
+
ctx.effect(() => () => {
|
|
195
|
+
clearInterval(interval);
|
|
196
|
+
}, 'crowdy session mirror');
|
|
197
|
+
void mirror.sweep();
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/persist/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connectivity probe: proves the cockpit's credentials and project id reach a
|
|
3
|
+
* real Crowdy Studio project before the harness is booted against it.
|
|
4
|
+
*
|
|
5
|
+
* With `--write` it also performs a guarded round-trip write, which is the
|
|
6
|
+
* end-to-end check that the agent's edits will actually land.
|
|
7
|
+
*/
|
|
8
|
+
import { CrowdyStudioClient } from '../crowdy/client.js';
|
|
9
|
+
import { describeMissing, loadCrowdyConfig } from '../crowdy/config.js';
|
|
10
|
+
import { selectProjectStore } from '../crowdy/project-store.js';
|
|
11
|
+
async function main() {
|
|
12
|
+
const boot = loadCrowdyConfig();
|
|
13
|
+
const missing = describeMissing(boot);
|
|
14
|
+
if (missing) {
|
|
15
|
+
console.error(`${missing} See .env.example.`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const client = new CrowdyStudioClient({
|
|
19
|
+
endpoint: boot.graphqlUrl,
|
|
20
|
+
appId: boot.appId,
|
|
21
|
+
appToken: boot.appToken,
|
|
22
|
+
email: boot.email,
|
|
23
|
+
password: boot.password,
|
|
24
|
+
});
|
|
25
|
+
const projectId = boot.projectId;
|
|
26
|
+
const selection = await selectProjectStore(client, projectId, {
|
|
27
|
+
githubFirst: boot.githubFirst ?? true,
|
|
28
|
+
warn: (message) => console.warn(` warn: ${message}`),
|
|
29
|
+
});
|
|
30
|
+
console.log(`store: ${selection.store.kind} — ${selection.reason}`);
|
|
31
|
+
const snapshot = await selection.store.load();
|
|
32
|
+
console.log(` ${snapshot.label}: ${snapshot.files.length} file(s)`);
|
|
33
|
+
const project = await client.loadProject(projectId);
|
|
34
|
+
console.log(`project ${project.name} (${project.projectId})`);
|
|
35
|
+
console.log(` revision ${project.revision}, ${project.files.length} file(s)`);
|
|
36
|
+
for (const file of project.files) {
|
|
37
|
+
console.log(` ${file.target.toLowerCase().padEnd(6)} ${file.path.padEnd(28)} ` +
|
|
38
|
+
`${Buffer.byteLength(file.content, 'utf8')} bytes rev ${file.revision}`);
|
|
39
|
+
}
|
|
40
|
+
if (!process.argv.includes('--write'))
|
|
41
|
+
return;
|
|
42
|
+
// Round-trip a marker through the same mutation the filesystem backend uses.
|
|
43
|
+
const path = 'src/cockpit_probe.rs';
|
|
44
|
+
const content = `// cockpit probe ${new Date().toISOString()}\n`;
|
|
45
|
+
const updated = await client.saveFiles({
|
|
46
|
+
projectId,
|
|
47
|
+
expectedRevision: project.revision,
|
|
48
|
+
upserts: [{ target: 'SERVER', path, content }],
|
|
49
|
+
});
|
|
50
|
+
console.log(`\nwrote server/${path}; revision ${project.revision} -> ${updated.revision}`);
|
|
51
|
+
const reverted = await client.saveFiles({
|
|
52
|
+
projectId,
|
|
53
|
+
expectedRevision: updated.revision,
|
|
54
|
+
deletes: [{ target: 'SERVER', path }],
|
|
55
|
+
});
|
|
56
|
+
console.log(`removed the probe file; revision ${updated.revision} -> ${reverted.revision}`);
|
|
57
|
+
}
|
|
58
|
+
await main();
|
|
59
|
+
//# sourceMappingURL=probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probe.js","sourceRoot":"","sources":["../../src/scripts/probe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Closed-world `crowdy-compute-sdk` catalog: lookup, aliases, and the
|
|
3
|
+
* system-prompt section the agent reads instead of guessing names.
|
|
4
|
+
*/
|
|
5
|
+
import { qualifiedName } from './parse-sdk.js';
|
|
6
|
+
/**
|
|
7
|
+
* Invented names the agent has already reached for. Values are catalog
|
|
8
|
+
* function names (unqualified). Keep this list curated; the parser cannot
|
|
9
|
+
* know what the model will hallucinate.
|
|
10
|
+
*/
|
|
11
|
+
export const SDK_ALIASES = {
|
|
12
|
+
emit: ['emit_event', 'emit_channel', 'emit_spatial'],
|
|
13
|
+
spawn: ['voxel_set'],
|
|
14
|
+
'crowdy::spawn': ['voxel_set'],
|
|
15
|
+
host_place_block: ['voxel_set'],
|
|
16
|
+
place_block: ['voxel_set'],
|
|
17
|
+
set_block: ['voxel_set'],
|
|
18
|
+
};
|
|
19
|
+
const FORBIDDEN_CRATES = ['glam'];
|
|
20
|
+
/** Harness tool, not a WASM host function. Looking it up in the SDK is the miss. */
|
|
21
|
+
export const GAME_CONTEXT_LOOKUP_NOTE = 'game_context is the Harness tool, not a crowdy::api function and not a host_call name. ' +
|
|
22
|
+
'Call the `game_context` tool to read the live current chunk and block catalog. ' +
|
|
23
|
+
'Place blocks with crowdy::api::voxel_set using that chunk (SERVER only). ' +
|
|
24
|
+
'A disco ball is SERVER voxel_set of dirt/sand/stone in a sphere near the TOP of the claimed chunk; shine and mock rays are CLIENT mesh_asset_spawn disco_rig, not wool/gold. ' +
|
|
25
|
+
'Do not write crowdy::host_call("game_context") or crowdy::api::game_context.';
|
|
26
|
+
export const PLUGIN_HOST_LOOKUP_NOTE = 'Disco look and held meshes are CLIENT host_call, not crowdy::api. ' +
|
|
27
|
+
'Appearance: crowdy::host_call("grid_skin_set", json!({ "remap": { "1": { "all": "mod_slot_00" }, "2": { "all": "mod_slot_00", "emission": 10 }, "3": { "all": "mod_slot_00" }, "6": { "all": "mod_slot_00", "emission": 8 } }, "paint": [{ "slot": 0, "fill": "#1a1a1a", "speckle": "#ffe066", "speckleCount": 28, "seed": 0 }] })). ' +
|
|
28
|
+
'Shimmer: CLIENT on_tick re-calls grid_skin_set with the same remap and a cycling paint.seed (and fill/speckle). Keep emission stable. ' +
|
|
29
|
+
'A disco ball in the sky is SERVER crowdy::api::voxel_set of dirt/sand/stone (ids 2,6,3) radius-3 near local y 12–14 of the current claimed chunk. Keep the floor. Do not voxel_set wool/gold. ' +
|
|
30
|
+
'Shine + mock rays: CLIENT mesh_asset_register { id:"disco", kind:"primitive", primitive:{ shape:"disco_rig" } } then mesh_asset_spawn { id:"disco", pose:{ x, y, z, yaw } } at the ball. on_tick re-spawns the same id with cycling pose.yaw. Not ray-traced lights and not voxel_set columns. Keep grid_skin_set shimmer on the floor. ' +
|
|
31
|
+
'Uploaded glTF: call Harness tool mesh_artifacts, then CLIENT mesh_asset_register { id, kind:"gltf", artifactHash } and mesh_asset_spawn. Never embed bytes. ' +
|
|
32
|
+
'Bow: crowdy::host_call("mesh_asset_register", json!({ "id": "bow", "kind": "primitive", "primitive": { "shape": "bow_placeholder" } })) then mesh_asset_attach { "id": "bow", "anchor": "hand" }. ' +
|
|
33
|
+
'CLIENT cannot voxel_set in Blocks with Friends.';
|
|
34
|
+
const PLUGIN_HOST_LOOKUPS = new Set([
|
|
35
|
+
'grid_skin_set',
|
|
36
|
+
'grid_skin_clear',
|
|
37
|
+
'mesh_asset_register',
|
|
38
|
+
'mesh_asset_attach',
|
|
39
|
+
'mesh_asset_spawn',
|
|
40
|
+
'mesh_asset_clear',
|
|
41
|
+
'mechanics_emit',
|
|
42
|
+
'disco',
|
|
43
|
+
'disco_skin',
|
|
44
|
+
'disco_ball',
|
|
45
|
+
'disco_ray',
|
|
46
|
+
'disco_rig',
|
|
47
|
+
'rays',
|
|
48
|
+
'shimmer',
|
|
49
|
+
'restyle',
|
|
50
|
+
'skin',
|
|
51
|
+
'gltf',
|
|
52
|
+
'artifactHash',
|
|
53
|
+
'mesh_artifacts',
|
|
54
|
+
'bow',
|
|
55
|
+
'bow_placeholder',
|
|
56
|
+
]);
|
|
57
|
+
export function isPluginHostLookup(raw, query = '') {
|
|
58
|
+
const normalized = query || raw;
|
|
59
|
+
if (PLUGIN_HOST_LOOKUPS.has(normalized))
|
|
60
|
+
return true;
|
|
61
|
+
return /host_call\s*\(\s*["'](?:grid_skin_set|mesh_asset_register|mesh_asset_attach|mesh_asset_spawn|mechanics_emit)["']/i.test(raw);
|
|
62
|
+
}
|
|
63
|
+
export function isHarnessGameContextLookup(raw, query = '') {
|
|
64
|
+
const normalized = query || raw;
|
|
65
|
+
if (normalized === 'game_context')
|
|
66
|
+
return true;
|
|
67
|
+
return /host_call\s*\(\s*["']game_context["']/i.test(raw);
|
|
68
|
+
}
|
|
69
|
+
function normalizeQuery(raw) {
|
|
70
|
+
return raw
|
|
71
|
+
.trim()
|
|
72
|
+
.replace(/^:+/u, '')
|
|
73
|
+
.replace(/^(?:crowdy::api::|crowdy::)/u, '')
|
|
74
|
+
.replace(/\(.*$/u, '')
|
|
75
|
+
.trim();
|
|
76
|
+
}
|
|
77
|
+
function byName(catalog, name) {
|
|
78
|
+
return catalog.find((entry) => entry.name === name);
|
|
79
|
+
}
|
|
80
|
+
/** Dice coefficient on character bigrams — enough for `emit` vs `emit_event`. */
|
|
81
|
+
export function nameSimilarity(a, b) {
|
|
82
|
+
if (a === b)
|
|
83
|
+
return 1;
|
|
84
|
+
if (a.length < 2 || b.length < 2)
|
|
85
|
+
return a.includes(b) || b.includes(a) ? 0.4 : 0;
|
|
86
|
+
const grams = (value) => {
|
|
87
|
+
const out = [];
|
|
88
|
+
for (let i = 0; i < value.length - 1; i += 1)
|
|
89
|
+
out.push(value.slice(i, i + 2));
|
|
90
|
+
return out;
|
|
91
|
+
};
|
|
92
|
+
const left = grams(a);
|
|
93
|
+
const right = new Map();
|
|
94
|
+
for (const g of grams(b))
|
|
95
|
+
right.set(g, (right.get(g) ?? 0) + 1);
|
|
96
|
+
let hits = 0;
|
|
97
|
+
for (const g of left) {
|
|
98
|
+
const n = right.get(g) ?? 0;
|
|
99
|
+
if (n > 0) {
|
|
100
|
+
hits += 1;
|
|
101
|
+
right.set(g, n - 1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return (2 * hits) / (left.length + grams(b).length);
|
|
105
|
+
}
|
|
106
|
+
export function nearestEntries(catalog, query, limit = 3) {
|
|
107
|
+
return [...catalog]
|
|
108
|
+
.map((entry) => ({ entry, score: nameSimilarity(query, entry.name) }))
|
|
109
|
+
.filter((row) => row.score > 0)
|
|
110
|
+
.sort((a, b) => b.score - a.score || a.entry.name.localeCompare(b.entry.name))
|
|
111
|
+
.slice(0, limit)
|
|
112
|
+
.map((row) => row.entry);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Resolve a rustc / agent name against the catalog. Exact hits win;
|
|
116
|
+
* then curated aliases; then nearest real names. Never invents a function.
|
|
117
|
+
*/
|
|
118
|
+
export function lookupSdkName(catalog, raw) {
|
|
119
|
+
const query = normalizeQuery(raw);
|
|
120
|
+
if (!query) {
|
|
121
|
+
return {
|
|
122
|
+
found: false,
|
|
123
|
+
query: raw,
|
|
124
|
+
nearest: [],
|
|
125
|
+
note: 'empty name — pass the identifier rustc could not find',
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (FORBIDDEN_CRATES.includes(query)) {
|
|
129
|
+
return {
|
|
130
|
+
found: false,
|
|
131
|
+
query,
|
|
132
|
+
nearest: [],
|
|
133
|
+
note: 'glam is forbidden in Crowdy Studio crates. Do not add it to Cargo.toml. ' +
|
|
134
|
+
'Use only functions in this catalog.',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (isHarnessGameContextLookup(raw, query)) {
|
|
138
|
+
const voxel = byName(catalog, 'voxel_set');
|
|
139
|
+
return {
|
|
140
|
+
found: false,
|
|
141
|
+
query,
|
|
142
|
+
nearest: voxel ? [voxel] : [],
|
|
143
|
+
note: GAME_CONTEXT_LOOKUP_NOTE,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (isPluginHostLookup(raw, query)) {
|
|
147
|
+
return {
|
|
148
|
+
found: false,
|
|
149
|
+
query,
|
|
150
|
+
nearest: [],
|
|
151
|
+
note: PLUGIN_HOST_LOOKUP_NOTE,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const exact = byName(catalog, query);
|
|
155
|
+
if (exact) {
|
|
156
|
+
return {
|
|
157
|
+
found: true,
|
|
158
|
+
query,
|
|
159
|
+
match: exact,
|
|
160
|
+
nearest: [],
|
|
161
|
+
note: `${qualifiedName(exact)} is in the catalog.`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const aliasTargets = SDK_ALIASES[query] ?? SDK_ALIASES[raw.trim()];
|
|
165
|
+
if (aliasTargets) {
|
|
166
|
+
const mapped = aliasTargets
|
|
167
|
+
.map((name) => byName(catalog, name))
|
|
168
|
+
.filter((entry) => entry !== undefined);
|
|
169
|
+
return {
|
|
170
|
+
found: false,
|
|
171
|
+
query,
|
|
172
|
+
viaAlias: query,
|
|
173
|
+
nearest: mapped,
|
|
174
|
+
note: `${query} is not a crowdy-compute-sdk function. Use ` +
|
|
175
|
+
`${mapped.map(qualifiedName).join(' / ') || 'a listed function'} instead.`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const nearest = nearestEntries(catalog, query);
|
|
179
|
+
return {
|
|
180
|
+
found: false,
|
|
181
|
+
query,
|
|
182
|
+
nearest,
|
|
183
|
+
note: `${query} is not in the catalog. Do not invent crowdy::api::${query}. ` +
|
|
184
|
+
(nearest.length > 0
|
|
185
|
+
? `Nearest real functions: ${nearest.map(qualifiedName).join(', ')}.`
|
|
186
|
+
: 'Remove the call and leave a TODO if no listed function matches.'),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
export function formatLookup(hit) {
|
|
190
|
+
const lines = [hit.note];
|
|
191
|
+
const show = hit.match ? [hit.match] : hit.nearest;
|
|
192
|
+
for (const entry of show) {
|
|
193
|
+
lines.push('');
|
|
194
|
+
lines.push(qualifiedName(entry));
|
|
195
|
+
lines.push(` ${entry.signature}`);
|
|
196
|
+
if (entry.doc)
|
|
197
|
+
lines.push(` ${entry.doc}`);
|
|
198
|
+
}
|
|
199
|
+
return lines.join('\n');
|
|
200
|
+
}
|
|
201
|
+
const RULES = [
|
|
202
|
+
'Closed-world SDK. Only the functions below exist on `crowdy` / `crowdy::api`.',
|
|
203
|
+
'Do not invent names (`crowdy::api::emit`, `crowdy::spawn`, `host_place_block`).',
|
|
204
|
+
'If rustc says cannot find function X, call `sdk_lookup` with X before editing.',
|
|
205
|
+
'If no listed function matches the intent, remove the call and leave a TODO — do not guess.',
|
|
206
|
+
'Do not add crates. glam is forbidden. Cargo.toml may only declare allowlisted crates (crowdy-compute-sdk, game-kit-*, serde, serde_json, rand).',
|
|
207
|
+
'World block writes: crowdy::api::voxel_set((cx,cy,cz), (vx,vy,vz), block_i32, None) on SERVER only. Always match the Result (`out_of_grid`, `permission_denied`, `bad_args`); never `let _ = voxel_set(...)`. CLIENT cannot voxel_set in Blocks with Friends.',
|
|
208
|
+
'Call the Harness tool `game_context` (not a WASM API, not host_call) before writing. Stay inside grid bounds.',
|
|
209
|
+
'Claimed-grid disco look is CLIENT crowdy::host_call("grid_skin_set", json!({ "remap": { "1": { "all": "mod_slot_00" }, "2": { "all": "mod_slot_00", "emission": 10 }, "3": { "all": "mod_slot_00" }, "6": { "all": "mod_slot_00", "emission": 8 } }, "paint": [{ "slot": 0, "fill": "#1a1a1a", "speckle": "#ffe066", "speckleCount": 28, "seed": 0 }] })). Do not SERVER voxel_set wool, gold, or glowstone as a skin. A disco ball in the sky is SERVER voxel_set of dirt/sand/stone (ids 2,6,3) radius-3 near the TOP of the current claimed chunk (local y 12–14), keep the floor — the CLIENT skin restyles those blocks. CLIENT on_tick may re-call grid_skin_set with cycling paint.seed for shimmer; keep remap/emission stable.',
|
|
210
|
+
'Disco shine + mock rays: CLIENT mesh_asset_register primitive disco_rig then mesh_asset_spawn at the ball with pose.yaw. on_tick re-spawns the same id with cycling yaw so beams spin. Not ray-traced lights. Not voxel_set columns.',
|
|
211
|
+
'Placeholder bow is CLIENT host_call mesh_asset_register primitive bow_placeholder then mesh_asset_attach anchor hand. Not a mini-block. Not voxel_set.',
|
|
212
|
+
'Uploaded glTF meshes: call Harness tool mesh_artifacts, then CLIENT mesh_asset_register kind gltf with artifactHash from that list, then mesh_asset_spawn. Never embed GLB bytes in host_call or Studio files.',
|
|
213
|
+
'Studio Invoke payload is UTF-8 JSON `{export, params, callerUserId, gridId}`. Parse `params` (chunk / chunk_x/y/z). Never treat the first 24 bytes as coordinates.',
|
|
214
|
+
'emit_spatial uuid_hex must be exactly 64 hex characters. emit_event is denied for player modules — use emit_spatial or emit_channel.',
|
|
215
|
+
].join(' ');
|
|
216
|
+
/** System-prompt section: rules plus the full function index. */
|
|
217
|
+
export function formatSdkPrompt(catalog) {
|
|
218
|
+
const crate = catalog.filter((e) => e.module === 'crate');
|
|
219
|
+
const api = catalog.filter((e) => e.module === 'api');
|
|
220
|
+
const block = (title, rows) => {
|
|
221
|
+
const body = rows
|
|
222
|
+
.map((entry) => {
|
|
223
|
+
const doc = entry.doc ? ` — ${entry.doc}` : '';
|
|
224
|
+
return `- ${qualifiedName(entry)} :: ${entry.signature}${doc}`;
|
|
225
|
+
})
|
|
226
|
+
.join('\n');
|
|
227
|
+
return `${title}\n${body}`;
|
|
228
|
+
};
|
|
229
|
+
return [
|
|
230
|
+
RULES,
|
|
231
|
+
'',
|
|
232
|
+
block('Crate-root helpers (`use crowdy_compute_sdk as crowdy`):', crate),
|
|
233
|
+
'',
|
|
234
|
+
block('Host API (`crowdy::api::*`):', api),
|
|
235
|
+
].join('\n');
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/sdk-index/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Closed-world crowdy-compute-sdk index plugin.
|
|
3
|
+
*
|
|
4
|
+
* @module @crowdy/dsh-cockpit/sdk-index
|
|
5
|
+
*/
|
|
6
|
+
export { apply, Config, inject, name } from './plugin.js';
|
|
7
|
+
export { formatLookup, formatSdkPrompt, GAME_CONTEXT_LOOKUP_NOTE, isHarnessGameContextLookup, lookupSdkName, nearestEntries, nameSimilarity, SDK_ALIASES, } from './catalog.js';
|
|
8
|
+
export { parseCrowdyComputeSdk, qualifiedName } from './parse-sdk.js';
|
|
9
|
+
export { SDK_SNAPSHOT, SDK_SNAPSHOT_VERSION } from './snapshot.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sdk-index/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAEzD,OAAO,EACL,YAAY,EACZ,eAAe,EACf,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,cAAc,EACd,WAAW,GACZ,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAErE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA"}
|