@world-engines/create-project 0.1.0-alpha.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.
@@ -0,0 +1,2 @@
1
+ /** npm 生命周期脚本也必须能找到与 npm CLI 相同的 Node,不依赖系统安装。 */
2
+ export declare function npmChildEnvironment(nodeExecutable: string, inherited?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
@@ -0,0 +1,11 @@
1
+ import { delimiter, dirname, resolve } from "node:path";
2
+ /** npm 生命周期脚本也必须能找到与 npm CLI 相同的 Node,不依赖系统安装。 */
3
+ export function npmChildEnvironment(nodeExecutable, inherited = process.env) {
4
+ const environment = { ...inherited };
5
+ const pathKeys = Object.keys(environment).filter((key) => process.platform === "win32" ? key.toLowerCase() === "path" : key === "PATH");
6
+ const paths = pathKeys.map((key) => environment[key]).filter((value) => Boolean(value));
7
+ for (const key of pathKeys)
8
+ delete environment[key];
9
+ environment.PATH = [dirname(resolve(nodeExecutable)), ...paths].join(delimiter);
10
+ return environment;
11
+ }
@@ -0,0 +1,8 @@
1
+ export interface TemplateFile {
2
+ readonly path: string;
3
+ readonly content: string;
4
+ }
5
+ /** 独立作者工具链版本,不改变主站 workspace 的构建工具。 */
6
+ export declare const AUTHOR_PROJECT_VITE_VERSION = "6.4.3";
7
+ export declare const AUTHOR_PROJECT_WORKER_FORMAT = "es";
8
+ export declare const PROJECT_TEMPLATE_FILES: readonly TemplateFile[];
@@ -0,0 +1,128 @@
1
+ import { DEFAULT_CHAT_APP_V3 } from "./default-view/app-v3.js";
2
+ import { DEFAULT_CHAT_PLAYER_PANEL } from "./default-view/panel.js";
3
+ import { DEFAULT_CHAT_BRIDGE } from "./default-view/bridge.js";
4
+ import { DEFAULT_CHAT_VIEW_CONFIG } from "./default-view/config.js";
5
+ import { DEFAULT_CHAT_STYLES } from "./default-view/styles.js";
6
+ import { INTERACTION_DEMO_CONFIG, INTERACTION_DEMO_INSTALLER, INTERACTION_DEMO_README } from "./default-view/interaction-demo.js";
7
+ /** 独立作者工具链版本,不改变主站 workspace 的构建工具。 */
8
+ export const AUTHOR_PROJECT_VITE_VERSION = "6.4.3";
9
+ export const AUTHOR_PROJECT_WORKER_FORMAT = "es";
10
+ const ROOT_PACKAGE = {
11
+ name: "worldengine-local-author-project",
12
+ version: "0.0.0",
13
+ private: true,
14
+ scripts: {
15
+ dev: "worldengine gui",
16
+ build: "npm --prefix view run build",
17
+ typecheck: "npm --prefix view run typecheck",
18
+ test: "npm --prefix view run test",
19
+ "smoke:view": "npm --prefix view run smoke:chatplay",
20
+ doctor: "worldengine doctor",
21
+ snapshot: "worldengine snapshot",
22
+ "sync:status": "worldengine sync status",
23
+ gui: "worldengine gui",
24
+ "gui:check": "worldengine gui --check",
25
+ },
26
+ dependencies: {
27
+ "@world-engines/project-host": "0.1.0-alpha.0",
28
+ "@world-engines/authoring-bridge": "0.1.0-alpha.0",
29
+ "@world-engines/project-format": "0.1.0-alpha.0",
30
+ "@world-engines/agent-kit": "0.1.0-alpha.0",
31
+ },
32
+ overrides: {
33
+ dompurify: "3.4.13",
34
+ },
35
+ };
36
+ const VIEW_PACKAGE = {
37
+ name: "worldengine-local-view",
38
+ version: "0.0.0",
39
+ private: true,
40
+ type: "module",
41
+ scripts: {
42
+ dev: "vite --host 127.0.0.1",
43
+ build: "tsc --noEmit && vite build",
44
+ typecheck: "tsc --noEmit",
45
+ test: "vitest run --passWithNoTests",
46
+ "smoke:chatplay": "vitest run src/chatplay.smoke.test.ts",
47
+ },
48
+ dependencies: {
49
+ "@world-engines/view-sdk": "0.1.0-alpha.0",
50
+ react: "^18.3.1",
51
+ "react-dom": "^18.3.1",
52
+ three: "^0.180.0",
53
+ },
54
+ devDependencies: {
55
+ "@types/react": "^18.3.12",
56
+ "@types/react-dom": "^18.3.1",
57
+ "@types/three": "^0.180.0",
58
+ "@vitejs/plugin-react": "^4.3.3",
59
+ autoprefixer: "^10.4.20",
60
+ postcss: "^8.4.49",
61
+ tailwindcss: "^3.4.17",
62
+ typescript: "^5.6.3",
63
+ vite: AUTHOR_PROJECT_VITE_VERSION,
64
+ vitest: "^3.2.4",
65
+ },
66
+ };
67
+ export const PROJECT_TEMPLATE_FILES = [
68
+ { path: "package.json", content: `${JSON.stringify(ROOT_PACKAGE, null, 2)}\n` },
69
+ {
70
+ path: "view/package.json",
71
+ content: `${JSON.stringify(VIEW_PACKAGE, null, 2)}\n`,
72
+ },
73
+ {
74
+ path: "view/index.html",
75
+ content: '<!doctype html>\n<html><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width,initial-scale=1" /><title>WorldEngine View</title></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body></html>\n',
76
+ },
77
+ {
78
+ path: "view/tsconfig.json",
79
+ content: `${JSON.stringify({ compilerOptions: { target: "ES2022", useDefineForClassFields: true, lib: ["ES2022", "DOM", "DOM.Iterable"], allowJs: false, skipLibCheck: true, esModuleInterop: true, allowSyntheticDefaultImports: true, strict: true, forceConsistentCasingInFileNames: true, module: "ESNext", moduleResolution: "Bundler", resolveJsonModule: true, isolatedModules: true, noEmit: true, jsx: "react-jsx" }, include: ["src"], references: [] }, null, 2)}\n`,
80
+ },
81
+ {
82
+ path: "view/vite.config.ts",
83
+ content: 'import { chatPlay } from "@world-engines/view-sdk";\nimport react from "@vitejs/plugin-react";\nimport { defineConfig } from "vite";\nimport previewConfig from "./preview.config.json" with { type: "json" };\n\nexport default defineConfig({ plugins: [react(), chatPlay({ apiBase: "http://127.0.0.1:11450", authentication: { mode: "account_proxy" }, model: previewConfig.model })], worker: { format: "es" }, server: { host: "127.0.0.1" } });\n',
84
+ },
85
+ { path: "view/preview.config.json", content: '{\n "schema_version": 1,\n "model": "anthropic/claude-sonnet-4-6"\n}\n' },
86
+ {
87
+ path: "view/tailwind.config.ts",
88
+ content: 'import type { Config } from "tailwindcss";\n\nexport default { content: ["./index.html", "./src/**/*.{ts,tsx}"], theme: { extend: {} }, plugins: [] } satisfies Config;\n',
89
+ },
90
+ {
91
+ path: "view/postcss.config.js",
92
+ content: 'export default { plugins: { tailwindcss: {}, autoprefixer: {} } };\n',
93
+ },
94
+ {
95
+ path: "view/src/main.tsx",
96
+ content: 'import React from "react";\nimport ReactDOM from "react-dom/client";\nimport { App } from "./App";\nimport "./styles.css";\n\nReactDOM.createRoot(document.getElementById("root")!).render(<React.StrictMode><App /></React.StrictMode>);\n',
97
+ },
98
+ {
99
+ path: "view/src/chatplay.d.ts",
100
+ content: 'import type {} from "@world-engines/view-sdk";\n',
101
+ },
102
+ {
103
+ path: "view/src/chatplay.ts",
104
+ content: DEFAULT_CHAT_BRIDGE,
105
+ },
106
+ {
107
+ path: "view/src/view-config.ts",
108
+ content: DEFAULT_CHAT_VIEW_CONFIG,
109
+ },
110
+ {
111
+ path: "view/src/App.tsx",
112
+ content: DEFAULT_CHAT_APP_V3,
113
+ },
114
+ { path: "view/src/player-panel.tsx", content: DEFAULT_CHAT_PLAYER_PANEL },
115
+ {
116
+ path: "view/src/chatplay.smoke.test.ts",
117
+ content: 'import { describe, expect, test, vi } from "vitest";\nimport { applyMessageDeleted, applyMessagePage, emitConfiguredAction, loadMessages, messageIdFromEvent, resolvedThemeFromEvent, sendMessage, type ChatPlayConversationBridge } from "./chatplay";\n\nconst message = (id: string, ts: number) => ({ id, saveId: "s", role: "assistant" as const, text: id, ts });\ndescribe("ChatPlay conversation bridge", () => {\n test("ready 拒绝时不发请求,分页排序与发送服从正式 SDK", async () => {\n const bridge = { ready: Promise.reject(new Error("not ready")), listMessages: vi.fn(), sendUserMessage: vi.fn() } as unknown as ChatPlayConversationBridge;\n await expect(loadMessages(bridge)).rejects.toThrow("not ready"); await expect(sendMessage(bridge, "回复")).rejects.toThrow("not ready"); expect(bridge.listMessages).not.toHaveBeenCalled(); expect(bridge.sendUserMessage).not.toHaveBeenCalled();\n });\n test("删除 tombstone 和较晚旧页不会复活消息", () => {\n const initial = { request: 2, deletedIds: new Set<string>(), messages: [message("a", 1), message("b", 2)] }; const removed = applyMessageDeleted(initial, "b");\n expect(removed.messages).toMatchObject([{ id: "a" }]); expect(applyMessagePage(removed, 1, [message("b", 2)]).messages).toMatchObject([{ id: "a" }]); expect(applyMessagePage(removed, 3, [message("b", 2), message("c", 3)]).messages).toMatchObject([{ id: "a" }, { id: "c" }]); expect(messageIdFromEvent({ messageId: "b" })).toBe("b");\n });\n test("主题通知优先采用宿主 resolved,作者 action 只调用 manifest 声明事件", () => {\n const emit = vi.fn().mockReturnValue({ interactionId: "i", nonce: "n" }); const bridge = { events: { emit } } as unknown as ChatPlayConversationBridge;\n expect(resolvedThemeFromEvent({ resolved: "light" })).toBe("light"); expect(resolvedThemeFromEvent({ resolved: "system" })).toBeNull(); expect(emitConfiguredAction(bridge, "story.choose", { choice: "left" }, "i")).toEqual({ interactionId: "i", nonce: "n" }); expect(emit).toHaveBeenCalledWith("story.choose", { choice: "left" }, "i");\n });\n});\n',
118
+ },
119
+ {
120
+ path: "view/src/styles.css",
121
+ content: DEFAULT_CHAT_STYLES,
122
+ },
123
+ { path: "examples/interaction-demo/install.mjs", content: INTERACTION_DEMO_INSTALLER },
124
+ { path: "examples/interaction-demo/view-config.ts", content: INTERACTION_DEMO_CONFIG },
125
+ { path: "examples/interaction-demo/README.md", content: INTERACTION_DEMO_README },
126
+ { path: "scenario/README.md", content: "# Scenario Part\n\n`source.wes` 是唯一作者源;请通过 GUI、MCP 或 CLI Tool 修改。\n" },
127
+ { path: "docs/README.md", content: "# 默认玩家视图二开\n\n`view/src/App.tsx` 是聊天中心;`player-panel.tsx` 只在玩家打开功能后读取数据。所有调用先等待 `ChatPlay.ready`。\n\n| 玩家菜单 / 页面 | 公开 SDK | 使用时机 |\n| --- | --- | --- |\n| 对话 | `listMessages`、`sendUserMessage`、消息/流事件 | ready 后独立读取消息;事件只刷新消息 |\n| 标题、主题和语言 | `getScenarioMeta`、`getTheme`/`themeChanged`、`getLocale`/`localeChanged` | 标题读取不得阻断消息;主题读取与通知用版本保护同步外观 |\n| 剧情、资源、已解锁 | `getProgress`、`listAssets`/`getAssetUrl`、`getOwnedResources` | 玩家打开相应面板后才读取 |\n| 角色状态 | `customState.keys`/`customState.get`、配置过的 `getVariable`/`getUnlock` | 使用 canonical custom state,不调用旧 readonly load aliases |\n| 互动选择 | `events.emit` | 仅发 manifest 声明的 action;同步返回不是故事完成回执 |\n| 世界线 | `worldline.list`、`fork`、`activate` | mutation 后清空当前消息、丢弃跨线迟到页,再重读新世界线 |\n| 切换模型 | `openModelSettings()` | host/provider 明确支持时显示;仅玩家点击才请求,调用不携带模型或配置参数 |\n\n默认 `view-config.ts` 保持空白,避免空剧本读取不存在的变量、解锁或 action。若要获得可运行的 TMW interaction、保存变量和解锁读取范例,请先阅读 `examples/interaction-demo/README.md`;该示范只会写入一个新建、未编辑的专用项目。\n\n不要在 View 中调用未公开的宿主 RPC、MCP 或写入状态,也不要在玩家 UI 展示 runtime、bridge、权限或 provider 技术信息。\n" },
128
+ ];
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@world-engines/create-project",
3
+ "version": "0.1.0-alpha.0",
4
+ "license": "SEE LICENSE IN LICENSE",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-worldengine-project": "dist/cli.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "@world-engines/agent-kit": "0.1.0-alpha.0",
20
+ "@world-engines/project-format": "0.1.0-alpha.0"
21
+ },
22
+ "engines": {
23
+ "node": ">=24"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "worldengine_source_sha256": "0b89a822b9a94e277fdee6c4935202710bd2177944fef360ae9c9d4ae5457bb7",
29
+ "worldengine_source_identity_provenance": {
30
+ "schema": "worldengine-public-namespace-projection/v1",
31
+ "kind": "composite-source-identity; namespace projection; not-full-source-recompile",
32
+ "original_name": "@worldengine/create-project",
33
+ "original_archive_sha256": "0850b35ea051ab5c57c87bc90dec998dd9302df5846bd12222e1e019ead2fa5f",
34
+ "original_source_sha256": "8ac35a1932805fd26785b8383454f9a1a775834a356465cdfb9e990dcbf89da8",
35
+ "projected_name": "@world-engines/create-project",
36
+ "package_name_mapping": {
37
+ "@chat/blocks-editor": "@world-engines/blocks-editor",
38
+ "@chat/ladybug-bridge": "@world-engines/ladybug-bridge",
39
+ "@chat/monaco-host": "@world-engines/monaco-host",
40
+ "@chat/protocol-ts": "@world-engines/protocol-ts",
41
+ "@chat/scenario-author-source": "@world-engines/scenario-author-source",
42
+ "@chat/scenario-review-snapshot": "@world-engines/scenario-review-snapshot",
43
+ "@chat/tmw": "@world-engines/tmw",
44
+ "@chat/view-exposure": "@world-engines/view-exposure",
45
+ "@world-engines/chatplay-vite-plugin": "@world-engines/chatplay-vite-plugin",
46
+ "@worldengine/agent-kit": "@world-engines/agent-kit",
47
+ "@worldengine/authoring-bridge": "@world-engines/authoring-bridge",
48
+ "@worldengine/authoring-ui": "@world-engines/authoring-ui",
49
+ "@worldengine/create-project": "@world-engines/create-project",
50
+ "@worldengine/project-format": "@world-engines/project-format",
51
+ "@worldengine/project-host": "@world-engines/project-host",
52
+ "@worldengine/project-setup": "@world-engines/project-setup",
53
+ "@worldengine/spatial-authoring": "@world-engines/spatial-authoring",
54
+ "@worldengine/view-sdk": "@world-engines/view-sdk"
55
+ }
56
+ }
57
+ }