@khorsheed/dsh-game 0.0.0-stage → 0.1.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.en.md +53 -0
  3. package/README.i18n.yaml +6 -0
  4. package/README.md +52 -2
  5. package/cordis.patch.yml +23 -0
  6. package/lib/client.js +30348 -0
  7. package/lib/index.js +4154 -0
  8. package/lib/typert.host.d.ts +3 -0
  9. package/lib/typert.host.js +3769 -0
  10. package/lib/typert.remote-client.d.ts +101 -0
  11. package/lib/typert.remote-client.js +2082 -0
  12. package/lib/types/agent.d.ts +20 -0
  13. package/lib/types/agent.js +42 -0
  14. package/lib/types/checks.d.ts +44 -0
  15. package/lib/types/checks.js +267 -0
  16. package/lib/types/client/DesignView.d.ts +22 -0
  17. package/lib/types/client/DesignView.js +134 -0
  18. package/lib/types/client/ElementsView.d.ts +21 -0
  19. package/lib/types/client/ElementsView.js +187 -0
  20. package/lib/types/client/GameTab.d.ts +14 -0
  21. package/lib/types/client/GameTab.js +256 -0
  22. package/lib/types/client/PlayFrame.d.ts +54 -0
  23. package/lib/types/client/PlayFrame.js +129 -0
  24. package/lib/types/client/PlayView.d.ts +19 -0
  25. package/lib/types/client/PlayView.js +161 -0
  26. package/lib/types/client/Preview3D.d.ts +50 -0
  27. package/lib/types/client/Preview3D.js +176 -0
  28. package/lib/types/client/ProjectSwitcher.d.ts +20 -0
  29. package/lib/types/client/ProjectSwitcher.js +75 -0
  30. package/lib/types/client/Recipe3DEditor.d.ts +19 -0
  31. package/lib/types/client/Recipe3DEditor.js +44 -0
  32. package/lib/types/client/StyleGallery.d.ts +18 -0
  33. package/lib/types/client/StyleGallery.js +27 -0
  34. package/lib/types/client/TurnCard.d.ts +62 -0
  35. package/lib/types/client/TurnCard.js +100 -0
  36. package/lib/types/client/VersionsView.d.ts +17 -0
  37. package/lib/types/client/VersionsView.js +68 -0
  38. package/lib/types/client/chat-node.d.ts +42 -0
  39. package/lib/types/client/chat-node.js +77 -0
  40. package/lib/types/client/contract.d.ts +125 -0
  41. package/lib/types/client/contract.js +6 -0
  42. package/lib/types/client/definition.d.ts +22 -0
  43. package/lib/types/client/definition.js +28 -0
  44. package/lib/types/client/index.d.ts +21 -0
  45. package/lib/types/client/index.js +229 -0
  46. package/lib/types/client/locales.d.ts +376 -0
  47. package/lib/types/client/locales.js +727 -0
  48. package/lib/types/client/looks.d.ts +36 -0
  49. package/lib/types/client/looks.js +105 -0
  50. package/lib/types/client/markdown.d.ts +11 -0
  51. package/lib/types/client/markdown.js +52 -0
  52. package/lib/types/client/preset-visibility.d.ts +94 -0
  53. package/lib/types/client/preset-visibility.js +115 -0
  54. package/lib/types/client/preview-entry.d.ts +24 -0
  55. package/lib/types/client/preview-entry.js +107 -0
  56. package/lib/types/client/refs.d.ts +36 -0
  57. package/lib/types/client/refs.js +44 -0
  58. package/lib/types/client/style-samples.d.ts +5 -0
  59. package/lib/types/client/style-samples.js +196 -0
  60. package/lib/types/fsutil.d.ts +26 -0
  61. package/lib/types/fsutil.js +104 -0
  62. package/lib/types/hooks.d.ts +83 -0
  63. package/lib/types/hooks.js +108 -0
  64. package/lib/types/index.d.ts +30 -0
  65. package/lib/types/index.js +22 -0
  66. package/lib/types/kits/canvas2d.d.ts +6 -0
  67. package/lib/types/kits/canvas2d.js +60 -0
  68. package/lib/types/kits/ids.d.ts +11 -0
  69. package/lib/types/kits/ids.js +6 -0
  70. package/lib/types/kits/index.d.ts +26 -0
  71. package/lib/types/kits/index.js +28 -0
  72. package/lib/types/kits/three3d.d.ts +12 -0
  73. package/lib/types/kits/three3d.js +188 -0
  74. package/lib/types/kits/types.d.ts +52 -0
  75. package/lib/types/kits/types.js +6 -0
  76. package/lib/types/look3d.d.ts +20 -0
  77. package/lib/types/look3d.js +175 -0
  78. package/lib/types/panel-session.d.ts +21 -0
  79. package/lib/types/panel-session.js +16 -0
  80. package/lib/types/project.d.ts +132 -0
  81. package/lib/types/project.js +494 -0
  82. package/lib/types/remote.d.ts +182 -0
  83. package/lib/types/remote.js +256 -0
  84. package/lib/types/skills.d.ts +13 -0
  85. package/lib/types/skills.js +140 -0
  86. package/lib/types/store.d.ts +325 -0
  87. package/lib/types/store.js +1285 -0
  88. package/lib/types/tools.d.ts +12 -0
  89. package/lib/types/tools.js +301 -0
  90. package/lib/types/trash.d.ts +5 -0
  91. package/lib/types/trash.js +64 -0
  92. package/lib/types/types.d.ts +522 -0
  93. package/lib/types/types.js +85 -0
  94. package/lib/types/vfs.d.ts +92 -0
  95. package/lib/types/vfs.js +217 -0
  96. package/locale/en.json +6 -0
  97. package/locale/zh.json +6 -0
  98. package/package.json +132 -3
  99. package/runtime/dsh3d.js +1279 -0
@@ -0,0 +1,325 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { Session } from '@deepseek-ai/dsh-session';
3
+ import { type BrowserChecker } from './checks.ts';
4
+ import { type TrashMover } from './trash.ts';
5
+ import { type CreateRequest } from './project.ts';
6
+ import { type BundleFile, type CommitResult, type VersionSource, type WorkingChanges, type DeleteProjectResult, type CheckRecord, type GameResult, type PlayBundle, type ProjectCard, type ProjectRow, type ProjectView, type TurnReport, type SessionGameState, type VersionDiff, type VersionRecord } from './types.ts';
7
+ /** Plugin config; every key optional. */
8
+ export interface GameConfig {
9
+ /** Registry root override (default `$DSH_HOME/state/game`). */
10
+ stateRoot?: string;
11
+ /** Chrome executable for the checks (default: `CHROME_PATH`, then common install paths). */
12
+ chromePath?: string;
13
+ }
14
+ /**
15
+ * Resolve the registry root: explicit value, then `$DSH_HOME/state/game`,
16
+ * then `<cwd>/.dsh-game` (the canvas precedent).
17
+ */
18
+ export declare function resolveGameStateRoot(configured: string | undefined): string;
19
+ /** A project's state when a turn started, for the turn report. */
20
+ export interface TurnBaseline {
21
+ readonly at: number;
22
+ readonly projectId: string;
23
+ readonly files: ReadonlyMap<string, string>;
24
+ readonly elements: ReadonlyMap<string, {
25
+ name: string;
26
+ json: string;
27
+ look: string;
28
+ fields: Record<string, string>;
29
+ }>;
30
+ readonly params: Readonly<Record<string, number>>;
31
+ readonly current: number | undefined;
32
+ readonly candidate: number | undefined;
33
+ }
34
+ /** The writer the store creates the first files with (specs swap in plain node). */
35
+ export type FenceWriter = (path: string, content: string, session: Session) => Promise<void>;
36
+ /** One end-of-turn evaluation's outcome, as the hook acts on it. */
37
+ export type TurnCheckOutcome = {
38
+ readonly kind: 'skip';
39
+ } | {
40
+ readonly kind: 'pass';
41
+ readonly record: CheckRecord;
42
+ readonly deployed: VersionRecord | null;
43
+ readonly candidate: VersionRecord | null;
44
+ } | {
45
+ readonly kind: 'fail';
46
+ readonly record: CheckRecord;
47
+ };
48
+ /** The game service core. */
49
+ export declare class GameService {
50
+ private readonly ctx;
51
+ static inject: string[];
52
+ readonly stateRoot: string;
53
+ private readonly sandboxPolicy;
54
+ private readonly checker;
55
+ /** Serializes registry read-modify-write cycles. */
56
+ private registryLock;
57
+ private readonly listeners;
58
+ /**
59
+ * @param ctx - host context (the mounted `ctx.fs`; `sandboxPolicy` probed).
60
+ * @param config - plugin config.
61
+ * @param deps - seams the specs replace.
62
+ */
63
+ constructor(ctx: Context, config?: GameConfig, deps?: {
64
+ checker?: BrowserChecker;
65
+ writer?: FenceWriter;
66
+ trash?: TrashMover;
67
+ });
68
+ /** Where a deleted project folder goes (the system trash; specs swap a fake). */
69
+ private readonly trash;
70
+ /** Release the checker's browser. */
71
+ dispose(): Promise<void>;
72
+ /** Subscribe to project changes (the Remote face forwards nothing yet; specs and hooks use it). */
73
+ subscribe(listener: (projectId: string) => void): () => void;
74
+ private notify;
75
+ /** Default fenced write: the mounted fs, stamped with the caller's policy. */
76
+ private writeFenced;
77
+ /** Whether the session may have the plugin write into its workspace. */
78
+ private writable;
79
+ private registryPath;
80
+ private readRegistry;
81
+ /** Read-modify-write the registry under the lock. */
82
+ private updateRegistry;
83
+ /** Every registered project, most recently updated first. */
84
+ listProjects(): Promise<ProjectRow[]>;
85
+ /** Element files parsed per id, for turn diffs. */
86
+ private elementIndex;
87
+ /** Snapshot the bound project when a turn starts (undefined when unbound). */
88
+ turnBaseline(sessionId: string): Promise<TurnBaseline | undefined>;
89
+ private turnsPath;
90
+ /**
91
+ * Compare the project with its turn-start snapshot and store what the turn
92
+ * changed. Nothing is stored for a turn that changed nothing.
93
+ */
94
+ recordTurn(sessionId: string, turn: number, base: TurnBaseline): Promise<TurnReport | undefined>;
95
+ /** A stored turn report. */
96
+ turnReport(sessionId: string, turn: number): Promise<TurnReport | null>;
97
+ /** Every project as a switcher card (manifest summary, live version, last screenshot), most recent first. */
98
+ projectCards(): Promise<ProjectCard[]>;
99
+ /** The project a session is bound to, if any. */
100
+ boundProject(sessionId: string): Promise<ProjectRow | undefined>;
101
+ /** Bind a session to a project (or unbind with null). */
102
+ bind(sessionId: string, projectId: string | null): Promise<GameResult>;
103
+ private touch;
104
+ /**
105
+ * Register an existing folder that holds a `game.json` (a project copied
106
+ * in, or one whose registry row was lost).
107
+ */
108
+ adopt(root: string): Promise<GameResult<{
109
+ readonly ok: true;
110
+ readonly project: ProjectRow;
111
+ }>>;
112
+ /**
113
+ * Delete a project from the panel. `trash` takes it out of the plugin
114
+ * (registry row and every session binding) AND moves its folder to the
115
+ * system trash — complete, yet recoverable; `forget` only takes it out of
116
+ * the plugin and leaves the folder (re-adopt with `game_open path`).
117
+ *
118
+ * Guards, checked before anything changes: the folder must still hold the
119
+ * project's own `game.json` (never trash an arbitrary directory a registry
120
+ * row happens to point at), must not be the calling session's workspace
121
+ * itself, and a read-only session may do neither. A failed move changes
122
+ * nothing, so the panel can offer `forget` instead.
123
+ */
124
+ deleteProject(projectId: string, mode: 'trash' | 'forget', session: Session | undefined): Promise<DeleteProjectResult>;
125
+ /**
126
+ * Create a project in the session's workspace behind the light gate, and
127
+ * bind the session to it.
128
+ * @param request - the gate's inputs.
129
+ * @param session - the calling session (its workspace and fence).
130
+ * @returns the new row, the gate's missing items, or a failure.
131
+ */
132
+ create(request: CreateRequest, session: Session): Promise<{
133
+ ok: true;
134
+ project: ProjectRow;
135
+ } | {
136
+ ok: false;
137
+ missing: readonly string[];
138
+ } | {
139
+ ok: false;
140
+ error: string;
141
+ }>;
142
+ private row;
143
+ /**
144
+ * Everything the panel and `game_read` show about one project.
145
+ * @param projectId - registry id.
146
+ * @returns the view, or undefined for an unknown id.
147
+ */
148
+ view(projectId: string): Promise<ProjectView | undefined>;
149
+ /** Elements the waiting candidate changed or added against the live version (null without both). */
150
+ private candidateDiff;
151
+ /** The tab's state for one session. */
152
+ sessionState(sessionId: string): Promise<SessionGameState>;
153
+ /**
154
+ * One build file as it is in the working folder now (a model the user just
155
+ * exported, say), for a panel preview ahead of any version. Build files only,
156
+ * inside the project, 8 MB at most.
157
+ */
158
+ workingFile(projectId: string, path: string): Promise<GameResult<{
159
+ readonly ok: true;
160
+ readonly file: BundleFile;
161
+ }>>;
162
+ /** The files of a deployed (or candidate) version, for the play area. */
163
+ bundle(projectId: string, which?: 'current' | 'candidate'): Promise<GameResult<{
164
+ readonly ok: true;
165
+ readonly bundle: PlayBundle;
166
+ }>>;
167
+ /** One specific version's files. */
168
+ versionBundle(projectId: string, version: number): Promise<GameResult<{
169
+ readonly ok: true;
170
+ readonly bundle: PlayBundle;
171
+ }>>;
172
+ /** The kit a snapshot was built for: its own `game.json`'s runtime. */
173
+ private snapshotKit;
174
+ /** The kit a project runs on now (its working `game.json`). */
175
+ private kitFor;
176
+ /** The build and test files as they are on disk now, plus their fingerprint. */
177
+ private snapshot;
178
+ /**
179
+ * The end-of-turn evaluation for a bound session: skip when nothing
180
+ * playable changed since the last check, else run the checks, persist the
181
+ * record, and on a pass deploy (auto-confirm) or leave a candidate.
182
+ * @param session - the session whose turn is closing.
183
+ * @param attempt - which automatic fix round this is (0 = the turn's own work).
184
+ * @param cap - the fix-round cap (a failure at the cap is recorded as given up).
185
+ * @returns what the hook should do.
186
+ */
187
+ checkTurn(session: Session, attempt: number, cap: number, by?: VersionSource): Promise<TurnCheckOutcome>;
188
+ /**
189
+ * 提交为新版本: the user commits the panel edits sitting in the working
190
+ * files. Runs the same checks as the end of a turn (no fix cap — nothing
191
+ * is steered); a pass cuts the version, whose note lists the edits.
192
+ */
193
+ commit(projectId: string, session: Session | undefined): Promise<GameResult<CommitResult>>;
194
+ private checkRow;
195
+ private nextVersion;
196
+ private copyVersion;
197
+ /** Keep the newest versions plus whatever current/candidate point at. */
198
+ private prune;
199
+ /** Promote the candidate to current (the user's 确认 when auto-confirm is off). */
200
+ confirm(projectId: string, session: Session | undefined): Promise<GameResult<{
201
+ readonly ok: true;
202
+ readonly version: number;
203
+ }>>;
204
+ /**
205
+ * Turn auto-confirm on or off in `game.json` (the panel's switch). The
206
+ * manifest is the project's own file, so this goes through node behind the
207
+ * same writable check.
208
+ */
209
+ setAutoConfirm(projectId: string, on: boolean, session: Session | undefined): Promise<GameResult>;
210
+ /** Throw the candidate away (the user's 退回); the model hears about it on the next send. */
211
+ reject(projectId: string, reason: string, session: Session | undefined): Promise<GameResult>;
212
+ /** Put an older version back into the play area. */
213
+ rollback(projectId: string, version: number, session: Session | undefined): Promise<GameResult>;
214
+ /** Files that differ between two versions' snapshots. */
215
+ diff(projectId: string, from: number, to: number): Promise<GameResult<{
216
+ readonly ok: true;
217
+ readonly diff: VersionDiff;
218
+ }>>;
219
+ private userLayer;
220
+ private saveUserLayer;
221
+ /** Add (or replace by key) one pending change; `text: ''` removes it. */
222
+ private addPending;
223
+ /** Sessions whose agent turn is running now (the turn hooks keep it). */
224
+ private readonly activeTurns;
225
+ /** The turn hooks report a bound session's turn starting and ending. */
226
+ setTurnActive(sessionId: string, active: boolean): void;
227
+ /**
228
+ * What the working files hold that the play area does not: build files
229
+ * added, changed or removed against the waiting candidate (else the live
230
+ * version), whoever wrote them — the panel, the agent, a CLI member, the
231
+ * user's own editor. Modification times pick the suspects; only those are
232
+ * compared byte for byte, so an unchanged project costs a stat walk.
233
+ */
234
+ changes(projectId: string): Promise<GameResult<WorkingChanges & {
235
+ readonly ok: true;
236
+ }>>;
237
+ /** Add (or replace by key) one uncommitted panel edit. */
238
+ private addEdit;
239
+ /** The agent has read the pending list (`game_read`): it is no longer news. */
240
+ clearPending(projectId: string): Promise<void>;
241
+ /** Drop one pending change by key (the dock's ×). */
242
+ dropPending(projectId: string, key: string, session: Session | undefined): Promise<GameResult>;
243
+ /**
244
+ * The user sent a message carrying the panel's change list (it starts
245
+ * with {@link PANEL_CHANGES_MARK}): drop exactly the changes it lists.
246
+ * Changes made after the list was written stay pending.
247
+ * @param sessionId - the sending session.
248
+ * @param text - the user message's text.
249
+ * @returns how many changes were cleared.
250
+ */
251
+ clearSent(sessionId: string, text: string): Promise<number>;
252
+ /** The manifest of a project, or undefined. */
253
+ private manifestOf;
254
+ /** Set one slider value (user layer; the play frame gets it live from the panel). */
255
+ setParam(projectId: string, key: string, value: number, session: Session | undefined): Promise<GameResult>;
256
+ /** 定稿: write the slider values into game.json as the new defaults. */
257
+ finalizeParams(projectId: string, session: Session | undefined): Promise<GameResult>;
258
+ /** 还原: drop every slider override. */
259
+ resetParams(projectId: string, session: Session | undefined): Promise<GameResult>;
260
+ /**
261
+ * Edit one element in the working files — its look, or scalar fields
262
+ * (`lore`, the 设定 text, included). The play area keeps its version until
263
+ * the user commits (`commit`); the edit is listed as uncommitted, and as
264
+ * pending for the agent.
265
+ */
266
+ editElement(projectId: string, elementId: string, patch: {
267
+ look?: unknown;
268
+ fields?: Record<string, string | number | boolean | null>;
269
+ }, session: Session | undefined, note?: string): Promise<GameResult<{
270
+ readonly ok: true;
271
+ readonly element: Record<string, unknown>;
272
+ }>>;
273
+ /** Write one design chapter (the user's direct edit). */
274
+ writeChapter(projectId: string, chapterId: string, text: string, session: Session | undefined): Promise<GameResult>;
275
+ /** Edit the one-pager in game.json (pitch, element types, pillars) — the user's direct edit. */
276
+ setOnePager(projectId: string, patch: {
277
+ pitch?: string;
278
+ elementTypes?: string;
279
+ pillars?: string;
280
+ }, session: Session | undefined): Promise<GameResult>;
281
+ /** Ask for a restyle: the next passing version becomes a candidate. The panel puts the request into the composer. */
282
+ requestRestyle(projectId: string, styleId: string, session: Session | undefined): Promise<GameResult>;
283
+ private proposals;
284
+ /**
285
+ * Store up to 3 appearance variants for an element (the `game_propose`
286
+ * tool); the user picks one in the panel.
287
+ */
288
+ proposeLooks(sessionId: string, elementId: string, request: string, variants: readonly {
289
+ label?: string;
290
+ note?: string;
291
+ look: unknown;
292
+ }[]): Promise<{
293
+ ok: true;
294
+ count: number;
295
+ name: string;
296
+ } | {
297
+ ok: false;
298
+ error: string;
299
+ }>;
300
+ /** The user picks a variant: it replaces the element's look at once; the others stay in the history. */
301
+ pickProposal(projectId: string, elementId: string, at: string, index: number, session: Session | undefined): Promise<GameResult>;
302
+ private readVersions;
303
+ private updateVersions;
304
+ private appendVersion;
305
+ /** The 版本 view's rows, newest first: only versions whose snapshot still exists. */
306
+ private versionRows;
307
+ /** The last check's screenshot (webp, base64), if any. */
308
+ checkShot(projectId: string, version?: number): Promise<GameResult<{
309
+ readonly ok: true;
310
+ readonly webp: string;
311
+ }>>;
312
+ /** Append one line to the project's playtest log (`.game/playtest-log.jsonl`). */
313
+ private log;
314
+ /** Record what the panel saw during one play session (errors, length). */
315
+ logPlay(projectId: string, entry: {
316
+ version: number;
317
+ seconds: number;
318
+ errors: readonly string[];
319
+ }, session: Session | undefined): Promise<GameResult>;
320
+ /** The playtest log, newest first (last 60). */
321
+ private logEntries;
322
+ /** The generated 试玩记录 chapter, newest first. */
323
+ private playtestText;
324
+ }
325
+ //# sourceMappingURL=store.d.ts.map