@easytwin/devkit 0.1.2 → 0.1.4

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/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
- /** 配置文件名(项目根)。 */
1
+ /** 用户项目内工具目录(凭据 / 场景快照 / types)。 */
2
+ declare const EASYTWIN_DIR = ".easytwin";
3
+ /** 配置文件名(落在 `.easytwin/` 下,D29)。 */
2
4
  declare const CONFIG_FILE_NAME = "easytwin.config.json";
5
+ /** scene pull 缺省目录(相对 `.easytwin/`)。 */
6
+ declare const EASYTWIN_SCENES_DIRNAME = "scenes";
3
7
  /**
4
8
  * 官方缺省域名(正式环境)。该常量是全仓唯一收口点,只允许写在这里。
5
9
  */
@@ -7,20 +11,19 @@ declare const DEFAULT_BASE_URL = "http://saas-twin.k8s.dtstack.cn/";
7
11
  /** 官方测试环境域名。 */
8
12
  declare const TEST_BASE_URL = "http://172.16.125.3:10100/";
9
13
  /**
10
- * 当前测试 OP 网关缺省头(与编辑器 curl 一致)。配置/环境变量可覆盖。
11
- * 免网关接口到位后删除(D13)。
12
- */
13
- declare const TEST_OP_ACCOUNT_ID = "25";
14
- declare const TEST_OP_USER_ID = "25";
15
- declare const TEST_SPACE_ID = "54";
16
- /**
17
- * 官方 OSS(twin runtime baseOSSUrl)。系统资产由此拼出:
18
- * `{ossUrl}/easytwin/system/libs/webp-wasm.wasm`、
14
+ * 官方测试 OSS。twin runtime baseOSSUrl 缺省用此桶(D11)
15
+ * 系统资产由此拼出:`{ossUrl}/easytwin/system/libs/webp-wasm.wasm`、
19
16
  * `{ossUrl}/easytwin/system/libs/draco/`、
20
17
  * `{ossUrl}/easytwin/system/components/custom/{type}/{version}/script.js`。
21
18
  * 不得用 API baseUrl 代替:场景/上传走 API,系统库与组件脚本走 OSS。
22
19
  */
20
+ declare const TEST_OSS_URL = "https://dt-easyv-test.oss-cn-hangzhou.aliyuncs.com/";
21
+ /** 官方正式 OSS。runtime 类型在 env=prod 时用此桶(D31);资产根缺省仍为测试桶。 */
22
+ declare const PROD_OSS_URL = "https://dt-easyv-prod.oss-cn-hangzhou.aliyuncs.com/";
23
+ /** 资产根缺省 = 测试 OSS(D11)。 */
23
24
  declare const DEFAULT_OSS_URL = "https://dt-easyv-test.oss-cn-hangzhou.aliyuncs.com/";
25
+ /** runtime 类型声明相对 OSS 根的路径(D31)。 */
26
+ declare const RUNTIME_TYPES_RELPATH = "easytwin/system/libs/runtime/types/index.d.ts";
24
27
  /** 服务环境,决定缺省 baseUrl。 */
25
28
  type EasyTwinEnv = "prod" | "test";
26
29
  /** 本地测试模式哨兵凭据:appId 与 appSecret 均为该值时,场景/上传走本地 mock,不发网络请求(见 AGENTS.md 4.4)。 */
@@ -37,10 +40,6 @@ interface EasyTwinConfig {
37
40
  baseUrl?: string;
38
41
  /** twin runtime 资产根(baseOSSUrl);缺省官方 OSS,可覆盖为 CDN/自建存储。 */
39
42
  ossUrl?: string;
40
- /** 过渡期 OP 网关头;免网关接口到位后删除(D13)。 */
41
- opAccountId?: string;
42
- opUserId?: string;
43
- spaceId?: string;
44
43
  /**
45
44
  * 关联场景摘要,由 scene list / 场景树刷新写入(D17)。
46
45
  * 不含场景 JSON 本体;下次 list 全量覆盖。
@@ -66,15 +65,30 @@ interface ResolvedConfig {
66
65
  /** 本地测试模式:appId/appSecret 均为 "test" 时启用,scene/upload/pull 走本地 mock 不发请求。 */
67
66
  mock: boolean;
68
67
  source: "file" | "env";
69
- /** 过渡期 OP 网关头;env=test 时缺省 25/25/54。免网关接口到位后删除(D13)。 */
70
- opAccountId?: string;
71
- opUserId?: string;
72
- spaceId?: string;
73
68
  }
74
69
  declare class ConfigError extends Error {
75
70
  constructor(message: string);
76
71
  }
77
72
  declare function configFilePath(cwd: string): string;
73
+ /** 拼接 OSS 根与相对路径,两端斜杠归一。 */
74
+ declare function joinOssPath(ossUrl: string, relPath: string): string;
75
+ /**
76
+ * `@easytwin/runtime` 类型 `index.d.ts` 的 OSS 地址(D31)。
77
+ * 显式 ossUrl 优先;否则 `env=prod` 用正式桶,其余(含缺省)用测试桶。
78
+ */
79
+ declare function resolveRuntimeTypesUrl(options?: {
80
+ env?: EasyTwinEnv;
81
+ ossUrl?: string;
82
+ }): string;
83
+ /**
84
+ * 按工作区配置 / 环境变量解析类型 URL。无配置文件时仍可拉缺省测试桶。
85
+ * 只把文件或环境变量里显式给出的 ossUrl 当作覆盖,不把 DEFAULT_OSS_URL 当成显式值。
86
+ */
87
+ declare function resolveRuntimeTypesUrlForCwd(cwd: string, env?: NodeJS.ProcessEnv): Promise<string>;
88
+ /** D29 之前项目根的旧配置路径。 */
89
+ declare function legacyConfigFilePath(cwd: string): string;
90
+ /** `easytwin scene pull` 缺省输出:`.easytwin/scenes/<id>.scene.json`。 */
91
+ declare function defaultSceneOutPath(cwd: string, id: string): string;
78
92
  declare function parseConfig(raw: string): EasyTwinConfig;
79
93
  declare function validateConfigShape(value: unknown): EasyTwinConfig;
80
94
  declare function readConfigFile(cwd: string): Promise<EasyTwinConfig>;
@@ -83,12 +97,15 @@ declare function resolveConfig(file: EasyTwinConfig, env?: NodeJS.ProcessEnv): R
83
97
  declare function loadConfig(cwd: string, env?: NodeJS.ProcessEnv): Promise<ResolvedConfig>;
84
98
  declare function writeConfigFile(cwd: string, config: EasyTwinConfig): Promise<string>;
85
99
  declare const GITIGNORE_FILE_NAME = ".gitignore";
86
- declare const GITIGNORE_ENTRY = "easytwin.config.json";
100
+ /** 凭据文件 gitignore 条目(相对项目根)。 */
101
+ declare const GITIGNORE_ENTRY = ".easytwin/easytwin.config.json";
102
+ /** init 写入 .gitignore 的条目:凭据 + 场景快照目录。不忽略整个 `.easytwin/`,以便 types 可入库。 */
103
+ declare const GITIGNORE_ENTRIES: readonly [".easytwin/easytwin.config.json", ".easytwin/scenes/"];
87
104
  interface GitignoreResult {
88
105
  created: boolean;
89
106
  added: boolean;
90
107
  }
91
- /** 把配置文件名追加进 .gitignore(无则创建),幂等:已存在条目时不重复追加。 */
108
+ /** 把凭据与场景快照路径追加进 .gitignore(无则创建),幂等:已存在条目时不重复追加。 */
92
109
  declare function appendGitignore(cwd: string): Promise<GitignoreResult>;
93
110
  interface InitResult {
94
111
  configFile: string;
@@ -100,25 +117,21 @@ declare function initConfig(input: EasyTwinConfig, cwd: string): Promise<InitRes
100
117
  declare function writeConfigScenes(cwd: string, scenes: ConfigScene[]): Promise<void>;
101
118
 
102
119
  /**
103
- * 认证与路径以内部 swagger 为准(标签:SDK 应用场景 / SDK 应用代码 / SDK Runtime)。
104
- * 全仓唯一认证头注入点:`x-app-secret` = App Secret。
105
- * 过渡期另注入 OP 网关头 op-account-id / op-user-id / space-id(D13,免网关接口到位后删除)。
106
- * 场景/代码路径参数名为 applicationId;DevKit 传入配置里的 App ID。
120
+ * 认证与路径以内部 swagger 为准(标签:SDK 应用场景 / 分享相关 / SDK 应用代码)。
121
+ * 全仓唯一认证头注入点:`x-app-id` = App ID,`x-app-secret` = App Secret(D20)
122
+ * share 代码与场景列表接口无路径参数(D21 / D22);上传不请求仍走 OP 网关的 workspace-config(D24)。
107
123
  */
124
+ declare const APP_ID_HEADER = "x-app-id";
108
125
  declare const AUTH_HEADER = "x-app-secret";
109
- /** 过渡期 OP 网关头;免网关接口到位后删除(D13)。 */
110
- declare const OP_ACCOUNT_ID_HEADER = "op-account-id";
111
- declare const OP_USER_ID_HEADER = "op-user-id";
112
- declare const SPACE_ID_HEADER = "space-id";
113
126
  declare const ENDPOINTS: {
114
- /** GET 已关联场景列表。 */
115
- readonly linkedScenes: (applicationId: string) => string;
116
- /** GET 工作区全部代码文件。 */
117
- readonly workspaceCode: (applicationId: string) => string;
118
- /** GET 工作区文件约束。 */
127
+ /** POST 已关联场景列表(分享路径,空 body)。 */
128
+ readonly linkedScenes: () => string;
129
+ /** POST 拉取工作区全部代码文件(分享路径,空 body)。 */
130
+ readonly workspaceCodePull: () => string;
131
+ /** POST 一次推送 create/update/delete(分享路径)。 */
132
+ readonly workspaceCodePush: () => string;
133
+ /** GET 工作区文件约束(仍带 applicationId,走 OP 网关;上传不调用,拉取失败则降级)。 */
119
134
  readonly workspaceConfig: (applicationId: string) => string;
120
- /** POST 新建 / PATCH 批量更新 / DELETE 批量删除。 */
121
- readonly workspaceCodeFiles: (applicationId: string) => string;
122
135
  };
123
136
  declare class EasyTwinApiError extends Error {
124
137
  readonly status: number;
@@ -135,14 +148,11 @@ declare class EasyTwinClient {
135
148
  readonly baseUrl: string;
136
149
  /** twin runtime / 场景快照资产根(baseOSSUrl)。 */
137
150
  readonly ossUrl: string;
138
- /** 接入凭证 App ID;同时作为场景/代码 API applicationId 路径参数。 */
151
+ /** 接入凭证 App ID;写入 `x-app-id`,workspace-config 路径仍可用。 */
139
152
  readonly appId: string;
140
153
  /** 本地测试模式:true 时 scene/upload/pull 走本地 mock,不发网络请求(见 config.ts)。 */
141
154
  readonly mock: boolean;
142
155
  private readonly appSecret;
143
- private readonly opAccountId?;
144
- private readonly opUserId?;
145
- private readonly spaceId?;
146
156
  constructor(config: ResolvedConfig);
147
157
  /** 全仓唯一认证头注入点。 */
148
158
  private authHeaders;
@@ -224,6 +234,7 @@ declare function listScenes(client: EasyTwinClient, options?: {
224
234
  }): Promise<SceneSummary[]>;
225
235
  declare function pullScene(client: EasyTwinClient, id: string, options?: {
226
236
  exampleFile?: string;
237
+ cwd?: string;
227
238
  }): Promise<SceneDetail>;
228
239
  declare function saveSceneJson(scene: SceneDetail, out: string): Promise<string>;
229
240
  /** 场景对象树节点:由场景 JSON 的 objs/hierarchy 按 parentObjId 组装(侧边栏场景结构树等复用)。 */
@@ -240,6 +251,37 @@ interface SceneTreeNode {
240
251
  * scene 可为已解析对象或 JSON 字符串。
241
252
  */
242
253
  declare function parseSceneStructure(scene: unknown): SceneTreeNode[];
254
+ /** inspect 默认最多打印的节点数(D30)。 */
255
+ declare const INSPECT_NODE_LIMIT = 200;
256
+ interface InspectSceneFilter {
257
+ name?: string;
258
+ type?: string;
259
+ }
260
+ interface InspectSceneOptions extends InspectSceneFilter {
261
+ cwd: string;
262
+ id: string;
263
+ limit?: number;
264
+ }
265
+ interface InspectSceneResult {
266
+ file: string;
267
+ roots: SceneTreeNode[];
268
+ text: string;
269
+ printed: number;
270
+ total: number;
271
+ truncated: boolean;
272
+ }
273
+ declare function nodeMatchesInspect(node: SceneTreeNode, filter: InspectSceneFilter): boolean;
274
+ /** 无过滤原样返回;有过滤时保留匹配节点与祖先,丢掉未匹配旁支与未匹配子孙。 */
275
+ declare function filterSceneTree(roots: SceneTreeNode[], filter?: InspectSceneFilter): SceneTreeNode[];
276
+ declare function countSceneTreeNodes(roots: SceneTreeNode[]): number;
277
+ declare function formatSceneTree(roots: SceneTreeNode[], limit?: number): {
278
+ text: string;
279
+ printed: number;
280
+ total: number;
281
+ truncated: boolean;
282
+ };
283
+ /** 只读本地 `.easytwin/scenes/<id>.scene.json`,打印对象树。不拉网、不读凭据。 */
284
+ declare function inspectScene(options: InspectSceneOptions): Promise<InspectSceneResult>;
243
285
 
244
286
  interface UploadProgress {
245
287
  phase: "collect" | "upload";
@@ -251,20 +293,58 @@ interface UploadProgress {
251
293
  }
252
294
  interface UploadOptions {
253
295
  onProgress?: (progress: UploadProgress) => void;
254
- /** 自定义忽略规则,默认只跳过 .git。 */
296
+ /** 额外忽略规则;默认已跳过插件产物与相关文件(D23)。 */
255
297
  ignore?: (relPath: string) => boolean;
256
298
  }
299
+ interface CollectedFile {
300
+ relPath: string;
301
+ absPath: string;
302
+ size: number;
303
+ }
257
304
  interface UploadResult {
258
305
  fileCount: number;
259
306
  byteCount: number;
307
+ created: number;
308
+ updated: number;
309
+ deleted: number;
310
+ unchanged: number;
260
311
  /** 本地测试模式(dry-run)时置 true:未真正上传。 */
261
312
  mock?: boolean;
262
313
  }
263
- interface CollectedFile {
264
- relPath: string;
265
- absPath: string;
266
- size: number;
314
+ interface UploadCreate {
315
+ file: CollectedFile;
316
+ content: string;
317
+ }
318
+ interface UploadUpdate {
319
+ file: CollectedFile;
320
+ id: string;
321
+ content: string;
322
+ }
323
+ interface UploadDelete {
324
+ id: string;
325
+ filePath: string;
267
326
  }
327
+ /** 对照远端文件,本地区分新增 / 更新 / 删除(D21,一次 push)。 */
328
+ interface WorkspaceUploadPlan {
329
+ creates: UploadCreate[];
330
+ updates: UploadUpdate[];
331
+ deletes: UploadDelete[];
332
+ unchanged: CollectedFile[];
333
+ }
334
+ /** 上传/拉取共同跳过:插件产物、agent 目录、构建产物与凭据。 */
335
+ declare const WORKSPACE_IGNORED_DIRS: Set<string>;
336
+ declare const WORKSPACE_IGNORED_FILES: Set<string>;
337
+ /** 与 push 服务端一致的工作区代码扩展名(D25)。 */
338
+ declare const WORKSPACE_CODE_EXTENSIONS: readonly [".ts", ".tsx", ".js", ".json"];
339
+ /** 工作区本地预览测试文件:不参与 pull/upload(D27)。 */
340
+ declare function isWorkspaceSpecFile(relPath: string): boolean;
341
+ /**
342
+ * 插件产物、凭据、构建目录与场景快照。
343
+ * 不含 `*.spec.ts`(预览测试扫描需要读这些文件)。
344
+ */
345
+ declare function isIgnoredWorkspacePath(relPath: string): boolean;
346
+ /** 跳过插件产物/凭据/场景快照,以及本地预览测试文件 `*.spec.ts`(D23 / D26 / D27)。 */
347
+ declare function defaultWorkspaceIgnore(relPath: string): boolean;
268
348
  /** swagger `SdkApplicationWorkspaceCodeConfigVo`。 */
269
349
  interface WorkspaceCodeConfig {
270
350
  allowedFileExtensions: string[];
@@ -286,12 +366,25 @@ declare function buildMultipartBody(boundary: string, fields: Record<string, str
286
366
  declare function normalizePath(relPath: string): string;
287
367
  declare function normalizeWorkspaceConfig(data: unknown): WorkspaceCodeConfig;
288
368
  declare function normalizeWorkspaceFiles(data: unknown): WorkspaceCodeFile[];
369
+ /** 是否为可同步的工作区代码文件(`.ts` / `.tsx` / `.js` / `.json`)。 */
370
+ declare function isWorkspaceCodeFile(relPath: string): boolean;
289
371
  /** 目录深度:根文件为 0,`src/a.ts` 为 1,`src/utils/a.ts` 为 2。 */
290
372
  declare function directoryDepth(relPath: string): number;
291
373
  declare function assertUploadable(files: CollectedFile[], config: WorkspaceCodeConfig): void;
292
374
  /**
293
- * 全量覆盖上传目录:对照工作区代码文件(GET/POST/PATCH/DELETE)使远端与本地一致。
294
- * 本地测试模式(mock)时退化为 dry-run。
375
+ * 对照远端工作区文件,把本地文件分成新增 / 更新 / 删除 / 未变。
376
+ * 不做本地清单:每次上传以本次 GET 的远端列表为准。
377
+ */
378
+ declare function planWorkspaceUpload(local: {
379
+ file: CollectedFile;
380
+ content: string;
381
+ }[], remote: WorkspaceCodeFile[]): WorkspaceUploadPlan;
382
+ declare function formatUploadResult(result: UploadResult): string;
383
+ /** swagger `PushSdkApplicationWorkspaceCodeDto`:字段均可选,有变更才带上。 */
384
+ declare function buildWorkspacePushBody(plan: WorkspaceUploadPlan): Record<string, unknown> | null;
385
+ /**
386
+ * 全量对齐上传目录:对照远端工作区,本地 diff 后一次 push(create/update/delete)。
387
+ * 不请求仍走 OP 网关的 workspace-config(D24);只收集 `.ts`/`.tsx`/`.js`/`.json`(D25)。本地测试模式(mock)时退化为 dry-run。
295
388
  */
296
389
  declare function uploadDirectory(client: EasyTwinClient, dir: string, options?: UploadOptions): Promise<UploadResult>;
297
390
 
@@ -348,10 +441,73 @@ declare function formatWorkspacePullResult(result: WorkspacePullResult): string;
348
441
  declare function workspacePullHasConflicts(plan: WorkspacePullPlan): boolean;
349
442
  declare function workspacePullPendingWrites(plan: WorkspacePullPlan, force?: boolean): string[];
350
443
 
444
+ /** 用户代码固定入口(相对工作区根)。 */
445
+ declare const USER_ENTRY = "src/main.ts";
446
+ /** CLI 缺省输出路径(相对工作区根)。 */
447
+ declare const DEFAULT_BUNDLE_OUT = "dist/main.js";
448
+ /** 白名单允许的裸模块。 */
449
+ declare const RUNTIME_MODULE = "@easytwin/runtime";
450
+ declare const APPS_MODULE = "@easytwin/apps";
451
+ declare class BundleError extends Error {
452
+ constructor(message: string);
453
+ }
454
+ interface BundleUserCodeOptions {
455
+ cwd: string;
456
+ /** 缺省不落盘,只返回产物字符串(插件内存编译);CLI 传入绝对/相对路径。 */
457
+ outFile?: string;
458
+ }
459
+ interface BundleWorkspaceModuleOptions extends BundleUserCodeOptions {
460
+ /** 相对 cwd 的入口文件(posix 或当前平台分隔符均可)。 */
461
+ entry: string;
462
+ /** 入口缺失时的报错文案;缺省按路径拼一条。 */
463
+ missingEntryMessage?: string;
464
+ }
465
+ interface BundleResult {
466
+ code: string;
467
+ warnings: string[];
468
+ }
469
+ /** 打包工作区任意入口。产物标准 ESM + inline sourcemap;仅允许 @easytwin/runtime 与 @easytwin/apps。 */
470
+ declare function bundleWorkspaceModule(options: BundleWorkspaceModuleOptions): Promise<BundleResult>;
471
+ /** 打包工作区 src/main.ts。产物标准 ESM + inline sourcemap;仅允许 @easytwin/runtime 与 @easytwin/apps。 */
472
+ declare function bundleUserCode(options: BundleUserCodeOptions): Promise<BundleResult>;
473
+ /** 若工作区尚未同步 runtime 类型,返回提示文案;已同步则返回 undefined。 */
474
+ declare function typesMissingHint(cwd: string): Promise<string | undefined>;
475
+ interface SourceMapJson {
476
+ sources?: string[];
477
+ mappings?: string;
478
+ }
479
+ declare function extractInlineSourceMap(code: string): SourceMapJson | undefined;
480
+ /**
481
+ * 把 bundled JS 的 stack(blob: 行号)映射回 TS 源码行号。
482
+ * 映射失败时原样返回。
483
+ */
484
+ declare function remapErrorStack(stack: string, bundledCode: string): string;
485
+
486
+ interface WorkspaceTestCase {
487
+ /** `${file}:${name}`,文件内唯一。 */
488
+ id: string;
489
+ /** 相对工作区根的 posix 路径。 */
490
+ file: string;
491
+ name: string;
492
+ /** 除 ctx 外还有参数时,预览显示输入框。 */
493
+ hasInput: boolean;
494
+ /** 第二个参数名,作输入框占位。 */
495
+ inputName?: string;
496
+ }
497
+ /** 从 spec 源码解析命名导出的函数(跳过 default / type / class / 再导出)。 */
498
+ declare function parseExportedTestFunctions(source: string): Omit<WorkspaceTestCase, "id" | "file">[];
499
+ declare function workspaceTestId(file: string, name: string): string;
500
+ /** 扫描工作区 `*.spec.ts` 的命名导出函数。跳过插件产物目录,不跳过 spec 本身。 */
501
+ declare function listWorkspaceTests(cwd: string): Promise<WorkspaceTestCase[]>;
502
+ declare function bundleWorkspaceTestFile(options: {
503
+ cwd: string;
504
+ file: string;
505
+ }): Promise<BundleResult>;
506
+
351
507
  type SyncTarget = "cursor" | "claude" | "codex" | "qoder";
352
508
  type SyncTargetArg = SyncTarget | "all";
353
- /** 六件套清单(5.1),顺序即输出顺序。 */
354
- declare const SKILL_NAMES: readonly ["easytwin-render", "easytwin-core", "easytwin-develop", "easytwin-bootstrap", "easytwin-scene", "easytwin-upload"];
509
+ /** 七件套清单(5.1),顺序即输出顺序。 */
510
+ declare const SKILL_NAMES: readonly ["easytwin-render", "easytwin-core", "easytwin-develop", "easytwin-bootstrap", "easytwin-scene", "easytwin-upload", "easytwin-test"];
355
511
  type SyncAction = "created" | "updated" | "unchanged";
356
512
  interface SyncEntrySummary {
357
513
  name: string;
@@ -368,8 +524,15 @@ interface SyncOptions {
368
524
  version?: string;
369
525
  /** skills 源目录;缺省按 devkit 包内 skills/ 解析(CLI)。插件 bundle 场景显式传入插件内目录。 */
370
526
  sourceDir?: string;
371
- /** runtime index.d.ts 源文件;缺省按包内 src/lib 或 dist/runtime-types 解析。插件必须显式传入。 */
527
+ /**
528
+ * 覆盖 runtime 类型源文件(跳过 OSS)。单测 / 离线用;
529
+ * 缺省按配置 env 从官方 OSS 拉 `easytwin/system/libs/runtime/types/index.d.ts`(D31)。
530
+ */
372
531
  typesSourceFile?: string;
532
+ /** 拉取类型用的 fetch;缺省 global fetch。单测注入。 */
533
+ fetch?: typeof fetch;
534
+ /** 解析类型 URL 时覆盖 process.env。 */
535
+ env?: NodeJS.ProcessEnv;
373
536
  }
374
537
  declare const CODEX_MARKER_BEGIN = "<!-- EASYTWIN-SKILLS:BEGIN -->";
375
538
  declare const CODEX_MARKER_END = "<!-- EASYTWIN-SKILLS:END -->";
@@ -381,11 +544,14 @@ declare const TSCONFIG_PATHS_HINT = "\u5DF2\u6709 tsconfig.json,\u672A\u6539\u52
381
544
  declare const APPS_TYPES_FILE = "apps.d.ts";
382
545
  declare const APPS_DTS = "import type { RuntimeEngine, RuntimeScene, SceneManager } from \"@easytwin/runtime\";\n\nexport type TwinAppContext = {\n app: {\n id: string;\n mode: \"preview\" | \"publish\";\n };\n engine: RuntimeEngine;\n container: HTMLElement;\n runtimeScene: RuntimeScene | null;\n scene: RuntimeScene[\"sceneObject\"] | null;\n camera: RuntimeScene[\"camera\"][\"main\"] | null;\n sceneManager: {\n currentSceneId: string;\n runtime: SceneManager | null;\n loadScene(sceneId: string): Promise<void>;\n };\n logger: {\n log(...args: unknown[]): void;\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n };\n assets: {\n text(path: string): Promise<string>;\n json<T = unknown>(path: string): Promise<T>;\n };\n cleanup(fn: () => void | Promise<void>): void;\n sceneCleanup(fn: () => void | Promise<void>): void;\n};\n\nexport declare abstract class TwinApp {\n init?(ctx: TwinAppContext): void | Promise<void>;\n onUpdate?(ctx: TwinAppContext, delta: number, elapsed: number): void;\n onBeforeSceneUnload?(ctx: TwinAppContext): void | Promise<void>;\n onSceneLoaded?(ctx: TwinAppContext): void | Promise<void>;\n onDispose?(ctx: TwinAppContext): void | Promise<void>;\n onError?(ctx: TwinAppContext, error: unknown): boolean | void;\n}\n\nexport declare function defineApp<T>(app: T): T;\n";
383
546
  declare function buildRuntimeTypesContent(sourceDts: string): string;
547
+ declare class SkillsError extends Error {
548
+ constructor(message: string);
549
+ }
384
550
  declare function normalizeTargets(target?: SyncTargetArg | SyncTarget[]): SyncTarget[];
385
551
  /** skills 源目录默认解析:CLI 下为 devkit 包内 skills/。插件 bundle 到 CJS 后 import.meta.url 为空,
386
552
  * 必须通过 SyncOptions.sourceDir / detectSkillsStatus 的 sourceDir 显式传入(见 esbuild.config.mjs 注释)。 */
387
553
  declare function resolveSkillsSourceDir(): string;
388
- /** runtime 类型声明源:开发态 src/lib/index.d.ts,发布态 dist/runtime-types/index.d.ts。 */
554
+ /** 开发态/单测:包内 src/lib/index.d.ts。正式 sync 默认走 OSS,不经过此函数。 */
389
555
  declare function resolveRuntimeTypesSourceFile(): string;
390
556
  declare function readDevkitVersion(skillsDir?: string): Promise<string>;
391
557
  interface TypesSyncSummary {
@@ -411,40 +577,6 @@ interface SkillsStatus {
411
577
  /** 供插件"缺失/过期时提示一次"使用:检测各目标当前同步状态。 */
412
578
  declare function detectSkillsStatus(cwd: string, sourceDir?: string): Promise<SkillsStatus>;
413
579
 
414
- /** 用户代码固定入口(相对工作区根)。 */
415
- declare const USER_ENTRY = "src/main.ts";
416
- /** CLI 缺省输出路径(相对工作区根)。 */
417
- declare const DEFAULT_BUNDLE_OUT = "dist/main.js";
418
- /** 白名单允许的裸模块。 */
419
- declare const RUNTIME_MODULE = "@easytwin/runtime";
420
- declare const APPS_MODULE = "@easytwin/apps";
421
- declare class BundleError extends Error {
422
- constructor(message: string);
423
- }
424
- interface BundleUserCodeOptions {
425
- cwd: string;
426
- /** 缺省不落盘,只返回产物字符串(插件内存编译);CLI 传入绝对/相对路径。 */
427
- outFile?: string;
428
- }
429
- interface BundleResult {
430
- code: string;
431
- warnings: string[];
432
- }
433
- /** 打包工作区 src/main.ts。产物标准 ESM + inline sourcemap;仅允许 @easytwin/runtime 与 @easytwin/apps。 */
434
- declare function bundleUserCode(options: BundleUserCodeOptions): Promise<BundleResult>;
435
- /** 若工作区尚未同步 runtime 类型,返回提示文案;已同步则返回 undefined。 */
436
- declare function typesMissingHint(cwd: string): Promise<string | undefined>;
437
- interface SourceMapJson {
438
- sources?: string[];
439
- mappings?: string;
440
- }
441
- declare function extractInlineSourceMap(code: string): SourceMapJson | undefined;
442
- /**
443
- * 把 bundled JS 的 stack(blob: 行号)映射回 TS 源码行号。
444
- * 映射失败时原样返回。
445
- */
446
- declare function remapErrorStack(stack: string, bundledCode: string): string;
447
-
448
580
  /** 在线 TwinApp 编译 stub 露出的 `@easytwin/runtime` 导出名。本地整包 external,超出此集合只 warning。 */
449
581
  declare const PORTABLE_RUNTIME_EXPORTS: readonly ["THREE", "RuntimeEngine", "SceneManager", "LoadSceneMode", "convertObjToComponentJson"];
450
582
  type PortableRuntimeExport = (typeof PORTABLE_RUNTIME_EXPORTS)[number];
@@ -566,6 +698,9 @@ declare class TwinAppPreviewHost {
566
698
  private readonly onEngineTick;
567
699
  constructor(options: TwinAppPreviewHostOptions);
568
700
  getEngine(): TwinAppEngine | null;
701
+ /** 给 spec 调用:场景字段取当前引擎主场景(不要求已 Run TwinApp)。 */
702
+ getTestContext(): TwinAppContext;
703
+ invokeTest(fn: (ctx: TwinAppContext, input?: string) => unknown, input?: string): Promise<unknown>;
569
704
  boot(): Promise<void>;
570
705
  run(code: string): Promise<void>;
571
706
  dispose(): Promise<void>;
@@ -583,4 +718,40 @@ declare class TwinAppPreviewHost {
583
718
  private getContext;
584
719
  }
585
720
 
586
- export { APPS_DTS, APPS_MODULE, APPS_TYPES_FILE, AUTH_HEADER, BundleError, type BundleResult, type BundleUserCodeOptions, CODEX_MARKER_BEGIN, CODEX_MARKER_END, CONFIG_FILE_NAME, type CollectedFile, ConfigError, type ConfigScene, DEFAULT_BASE_URL, DEFAULT_BUNDLE_OUT, DEFAULT_ENTRY_PATH, DEFAULT_MAIN_TS, DEFAULT_OSS_URL, EASYTWIN_TYPES_DIR, ENDPOINTS, EXAMPLE_SCENE_FILE, EasyTwinApiError, EasyTwinClient, type EasyTwinConfig, type EasyTwinEnv, GITIGNORE_ENTRY, GITIGNORE_FILE_NAME, type GitignoreResult, type InitResult, LOCAL_LOAD_SCENE_ERROR, type LinkedScene, META_FILE_NAME, MINIMAL_TSCONFIG, MISSING_TICK_ERROR, MOCK_APP_ID, MOCK_APP_SECRET, MOCK_SCENE_NAME, OP_ACCOUNT_ID_HEADER, OP_USER_ID_HEADER, PORTABLE_RUNTIME_EXPORTS, type PortableRuntimeExport, RUNTIME_MODULE, type RequestOptions, type ResolvedConfig, SKILL_NAMES, SPACE_ID_HEADER, type SceneDetail, type SceneSummary, type SceneTreeNode, type SkillsStatus, type SkillsTargetStatus, type SyncAction, type SyncEntrySummary, type SyncOptions, type SyncSkillsResult, type SyncSummary, type SyncTarget, type SyncTargetArg, TEST_BASE_URL, TEST_OP_ACCOUNT_ID, TEST_OP_USER_ID, TEST_SPACE_ID, TSCONFIG_PATHS_HINT, TwinApp, type TwinAppContext, type TwinAppEngine, TwinAppPreviewHost, type TwinAppPreviewHostOptions, type TwinAppRuntimeModule, type TwinAppRuntimeScene, type TwinAppSceneManager, type TwinAppTickListener, type TypesSyncSummary, USER_ENTRY, type UploadOptions, type UploadProgress, type UploadResult, type WorkspaceChangeKind, type WorkspaceCodeConfig, type WorkspaceCodeFile, type WorkspaceFileChange, type WorkspacePullApplyResult, type WorkspacePullOptions, type WorkspacePullPlan, type WorkspacePullResult, appendGitignore, applyWorkspacePull, assertUploadable, buildMultipartBody, buildRuntimeTypesContent, bundleUserCode, collectFiles, configFilePath, createAppInstance, defaultPullIgnore, defineApp, deriveExampleSceneId, detectSkillsStatus, directoryDepth, exampleSceneSummary, extractInlineSourceMap, extractSceneArray, formatWorkspacePullPlan, formatWorkspacePullResult, initConfig, isMockCredentials, isSafeRelPath, listScenes, loadConfig, loadExampleScene, normalizeLinkedScenes, normalizePath, normalizeSceneList, normalizeTargets, normalizeWorkspaceConfig, normalizeWorkspaceFiles, parseConfig, parseSceneStructure, planWorkspacePull, portableRuntimeWarning, pullScene, pullWorkspace, readConfigFile, readDevkitVersion, remapErrorStack, resolveConfig, resolveExampleScenePath, resolveRuntimeTypesSourceFile, resolveSkillsSourceDir, resolveSnapshotUrl, resolveWorkspaceAssetPath, saveSceneJson, syncSkills, toConfigScenes, typesMissingHint, uploadDirectory, validateConfigShape, workspacePullHasConflicts, workspacePullPendingWrites, writeConfigFile, writeConfigScenes };
721
+ type PreviewHostKind = "vscode" | "http";
722
+ /**
723
+ * 纯函数:构造场景预览页 HTML(插件 webview 与 CLI localhost HTTP 共用,D28)。
724
+ * 单栏三维场景页:module script 动态 import twin runtime,
725
+ * 用场景数据经 convertObjToComponentJson + RuntimeEngine.create + loadScene 真实渲染。
726
+ * baseOSSUrl 必须是 ossUrl(缺省官方 OSS),不是 API baseUrl。
727
+ * host=vscode 且页面为 HTTPS 时,HTTP 资源经扩展宿主代理,规避 mixed content。
728
+ * host=http(CLI preview)时直连 API 与 OSS,走同源 `/api/*` 做 bundle/tests/assets。
729
+ * 底部 Run 走 TwinAppPreviewHost(D14):import map 注入 @easytwin/runtime 与 @easytwin/apps。
730
+ * 工作区 *.spec.ts 命名导出在 Run 栏上方列出(D27)。
731
+ */
732
+ declare function escapeHtml(text: string): string;
733
+ /**
734
+ * 把 JSON 文本安全嵌入 `<script type="application/json">`。
735
+ * script 元素的内容是 raw text,HTML 实体不会解码,因此不能使用 escapeHtml;
736
+ * 只需把 `<`/`>` 与 U+2028/U+2029 转成 JSON 字面转义。
737
+ */
738
+ declare function escapeJsonForScript(json: string): string;
739
+ /** 纯状态页:预览加载中 / 加载失败时的兜底内容,避免空白 webview。 */
740
+ declare function buildStatusHtml(message: string): string;
741
+ declare function buildPreviewHtml(options: {
742
+ baseUrl: string;
743
+ ossUrl: string;
744
+ sceneJson: string;
745
+ mock?: boolean;
746
+ runtimeUri: string;
747
+ appsUri?: string;
748
+ hostUri?: string;
749
+ appId?: string;
750
+ /** vscode=webview postMessage+混合内容代理;http=CLI 同源 /api/*。缺省 vscode。 */
751
+ host?: PreviewHostKind;
752
+ /** VSCode webview.cspSource;缺省回退 runtimeUri 的 origin(单测用)。 */
753
+ cspSource?: string;
754
+ tests?: WorkspaceTestCase[];
755
+ }): string;
756
+
757
+ export { APPS_DTS, APPS_MODULE, APPS_TYPES_FILE, APP_ID_HEADER, AUTH_HEADER, BundleError, type BundleResult, type BundleUserCodeOptions, type BundleWorkspaceModuleOptions, CODEX_MARKER_BEGIN, CODEX_MARKER_END, CONFIG_FILE_NAME, type CollectedFile, ConfigError, type ConfigScene, DEFAULT_BASE_URL, DEFAULT_BUNDLE_OUT, DEFAULT_ENTRY_PATH, DEFAULT_MAIN_TS, DEFAULT_OSS_URL, EASYTWIN_DIR, EASYTWIN_SCENES_DIRNAME, EASYTWIN_TYPES_DIR, ENDPOINTS, EXAMPLE_SCENE_FILE, EasyTwinApiError, EasyTwinClient, type EasyTwinConfig, type EasyTwinEnv, GITIGNORE_ENTRIES, GITIGNORE_ENTRY, GITIGNORE_FILE_NAME, type GitignoreResult, INSPECT_NODE_LIMIT, type InitResult, type InspectSceneFilter, type InspectSceneOptions, type InspectSceneResult, LOCAL_LOAD_SCENE_ERROR, type LinkedScene, META_FILE_NAME, MINIMAL_TSCONFIG, MISSING_TICK_ERROR, MOCK_APP_ID, MOCK_APP_SECRET, MOCK_SCENE_NAME, PORTABLE_RUNTIME_EXPORTS, PROD_OSS_URL, type PortableRuntimeExport, type PreviewHostKind, RUNTIME_MODULE, RUNTIME_TYPES_RELPATH, type RequestOptions, type ResolvedConfig, SKILL_NAMES, type SceneDetail, type SceneSummary, type SceneTreeNode, SkillsError, type SkillsStatus, type SkillsTargetStatus, type SyncAction, type SyncEntrySummary, type SyncOptions, type SyncSkillsResult, type SyncSummary, type SyncTarget, type SyncTargetArg, TEST_BASE_URL, TEST_OSS_URL, TSCONFIG_PATHS_HINT, TwinApp, type TwinAppContext, type TwinAppEngine, TwinAppPreviewHost, type TwinAppPreviewHostOptions, type TwinAppRuntimeModule, type TwinAppRuntimeScene, type TwinAppSceneManager, type TwinAppTickListener, type TypesSyncSummary, USER_ENTRY, type UploadCreate, type UploadDelete, type UploadOptions, type UploadProgress, type UploadResult, type UploadUpdate, WORKSPACE_CODE_EXTENSIONS, WORKSPACE_IGNORED_DIRS, WORKSPACE_IGNORED_FILES, type WorkspaceChangeKind, type WorkspaceCodeConfig, type WorkspaceCodeFile, type WorkspaceFileChange, type WorkspacePullApplyResult, type WorkspacePullOptions, type WorkspacePullPlan, type WorkspacePullResult, type WorkspaceTestCase, type WorkspaceUploadPlan, appendGitignore, applyWorkspacePull, assertUploadable, buildMultipartBody, buildPreviewHtml, buildRuntimeTypesContent, buildStatusHtml, buildWorkspacePushBody, bundleUserCode, bundleWorkspaceModule, bundleWorkspaceTestFile, collectFiles, configFilePath, countSceneTreeNodes, createAppInstance, defaultPullIgnore, defaultSceneOutPath, defaultWorkspaceIgnore, defineApp, deriveExampleSceneId, detectSkillsStatus, directoryDepth, escapeHtml, escapeJsonForScript, exampleSceneSummary, extractInlineSourceMap, extractSceneArray, filterSceneTree, formatSceneTree, formatUploadResult, formatWorkspacePullPlan, formatWorkspacePullResult, initConfig, inspectScene, isIgnoredWorkspacePath, isMockCredentials, isSafeRelPath, isWorkspaceCodeFile, isWorkspaceSpecFile, joinOssPath, legacyConfigFilePath, listScenes, listWorkspaceTests, loadConfig, loadExampleScene, nodeMatchesInspect, normalizeLinkedScenes, normalizePath, normalizeSceneList, normalizeTargets, normalizeWorkspaceConfig, normalizeWorkspaceFiles, parseConfig, parseExportedTestFunctions, parseSceneStructure, planWorkspacePull, planWorkspaceUpload, portableRuntimeWarning, pullScene, pullWorkspace, readConfigFile, readDevkitVersion, remapErrorStack, resolveConfig, resolveExampleScenePath, resolveRuntimeTypesSourceFile, resolveRuntimeTypesUrl, resolveRuntimeTypesUrlForCwd, resolveSkillsSourceDir, resolveSnapshotUrl, resolveWorkspaceAssetPath, saveSceneJson, syncSkills, toConfigScenes, typesMissingHint, uploadDirectory, validateConfigShape, workspacePullHasConflicts, workspacePullPendingWrites, workspaceTestId, writeConfigFile, writeConfigScenes };