@dxos/plugin-chess 0.9.0 → 0.9.1-staging.ee54ba693a
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/lib/neutral/{ChessArticle-JHI5OXYR.mjs → ChessArticle-MPRT54KQ.mjs} +4 -3
- package/dist/lib/neutral/ChessArticle-MPRT54KQ.mjs.map +7 -0
- package/dist/lib/neutral/{ChessCard-4TUTIFB6.mjs → ChessCard-VJ3I6MIB.mjs} +8 -3
- package/dist/lib/neutral/ChessCard-VJ3I6MIB.mjs.map +7 -0
- package/dist/lib/neutral/ChessPlugin.mjs +1 -1
- package/dist/lib/neutral/ChessPlugin.node.mjs +3 -3
- package/dist/lib/neutral/ChessPlugin.node.mjs.map +3 -3
- package/dist/lib/neutral/capabilities/index.mjs +3 -3
- package/dist/lib/neutral/capabilities/index.mjs.map +3 -3
- package/dist/lib/neutral/{chunk-YB6WZOZI.mjs → chunk-AMXVX7V2.mjs} +2 -2
- package/dist/lib/neutral/{chunk-OYWDKJ5B.mjs → chunk-DXIET5G2.mjs} +12 -12
- package/dist/lib/neutral/chunk-DXIET5G2.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-PJOAFP6S.mjs → chunk-EXZ3XFEG.mjs} +7 -7
- package/dist/lib/neutral/chunk-EXZ3XFEG.mjs.map +7 -0
- package/dist/lib/neutral/chunk-IKWULCKX.mjs +38 -0
- package/dist/lib/neutral/chunk-IKWULCKX.mjs.map +7 -0
- package/dist/lib/neutral/chunk-YZTKZ5F7.mjs +42 -0
- package/dist/lib/neutral/chunk-YZTKZ5F7.mjs.map +7 -0
- package/dist/lib/neutral/components/index.mjs +47 -46
- package/dist/lib/neutral/components/index.mjs.map +3 -3
- package/dist/lib/neutral/containers/index.mjs +2 -2
- package/dist/lib/neutral/index.mjs +5 -5
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/meta.mjs +1 -1
- package/dist/lib/neutral/{move-6NCMKKWD.mjs → move-UMDTQST4.mjs} +2 -2
- package/dist/lib/neutral/operations/index.mjs +1 -1
- package/dist/lib/neutral/{play-F5L5LFLW.mjs → play-7XTJZ4N6.mjs} +2 -2
- package/dist/lib/neutral/plugin.mjs +2 -2
- package/dist/lib/neutral/{print-GMSNKAS2.mjs → print-JR4VB3UX.mjs} +2 -2
- package/dist/lib/neutral/skill-definition-ZGQBUE4R.mjs +15 -0
- package/dist/lib/neutral/skill-definition-ZGQBUE4R.mjs.map +7 -0
- package/dist/lib/neutral/skills/index.mjs +8 -0
- package/dist/lib/neutral/testing.mjs +1 -1
- package/dist/lib/neutral/translations.mjs +1 -1
- package/dist/lib/neutral/translations.mjs.map +3 -3
- package/dist/lib/neutral/types/index.mjs +1 -1
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/capabilities/game-variant.d.ts +1 -2
- package/dist/types/src/capabilities/game-variant.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +2 -3
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
- package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
- package/dist/types/src/components/Chessboard/Chessboard.d.ts +1 -1
- package/dist/types/src/components/Chessboard/Chessboard.d.ts.map +1 -1
- package/dist/types/src/components/Chessboard/Chessboard.stories.d.ts +2 -2
- package/dist/types/src/components/Chessboard/Chessboard.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ChessArticle/ChessArticle.d.ts.map +1 -1
- package/dist/types/src/containers/ChessArticle/ChessArticle.stories.d.ts +2 -2
- package/dist/types/src/containers/ChessArticle/ChessArticle.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ChessCard/ChessCard.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +32 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/skills/chess-skill.d.ts +4 -0
- package/dist/types/src/skills/chess-skill.d.ts.map +1 -0
- package/dist/types/src/skills/index.d.ts +2 -0
- package/dist/types/src/skills/index.d.ts.map +1 -0
- package/dist/types/src/types/Chess.d.ts +8 -7
- package/dist/types/src/types/Chess.d.ts.map +1 -1
- package/dist/types/src/types/ChessOperation.d.ts +2 -8
- package/dist/types/src/types/ChessOperation.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +24 -0
- package/package.json +39 -38
- package/src/ChessPlugin.node.ts +2 -2
- package/src/ChessPlugin.test.ts +2 -2
- package/src/ChessPlugin.tsx +4 -4
- package/src/capabilities/index.ts +1 -7
- package/src/capabilities/skill-definition.ts +14 -0
- package/src/components/Chessboard/Chessboard.stories.tsx +2 -2
- package/src/components/Chessboard/Chessboard.tsx +47 -45
- package/src/components/Chessboard/Info.tsx +5 -3
- package/src/containers/ChessArticle/ChessArticle.stories.tsx +2 -2
- package/src/containers/ChessArticle/ChessArticle.tsx +5 -4
- package/src/containers/ChessCard/ChessCard.stories.tsx +1 -1
- package/src/containers/ChessCard/ChessCard.tsx +12 -5
- package/src/index.ts +1 -1
- package/src/meta.ts +3 -19
- package/src/{blueprints/chess-blueprint.ts → skills/chess-skill.ts} +11 -7
- package/src/skills/index.ts +5 -0
- package/src/translations.ts +1 -1
- package/src/types/Chess.ts +21 -22
- package/dist/lib/neutral/ChessArticle-JHI5OXYR.mjs.map +0 -7
- package/dist/lib/neutral/ChessCard-4TUTIFB6.mjs.map +0 -7
- package/dist/lib/neutral/blueprint-definition-4MOWVVWD.mjs +0 -15
- package/dist/lib/neutral/blueprint-definition-4MOWVVWD.mjs.map +0 -7
- package/dist/lib/neutral/blueprints/index.mjs +0 -8
- package/dist/lib/neutral/chunk-7XZ4CRDL.mjs +0 -32
- package/dist/lib/neutral/chunk-7XZ4CRDL.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OYWDKJ5B.mjs.map +0 -7
- package/dist/lib/neutral/chunk-PJOAFP6S.mjs.map +0 -7
- package/dist/lib/neutral/chunk-XWKNXG62.mjs +0 -34
- package/dist/lib/neutral/chunk-XWKNXG62.mjs.map +0 -7
- package/dist/types/src/blueprints/chess-blueprint.d.ts +0 -4
- package/dist/types/src/blueprints/chess-blueprint.d.ts.map +0 -1
- package/dist/types/src/blueprints/index.d.ts +0 -2
- package/dist/types/src/blueprints/index.d.ts.map +0 -1
- package/dist/types/src/capabilities/blueprint-definition.d.ts +0 -6
- package/dist/types/src/capabilities/blueprint-definition.d.ts.map +0 -1
- package/src/blueprints/index.ts +0 -5
- package/src/capabilities/blueprint-definition.ts +0 -19
- /package/dist/lib/neutral/{chunk-YB6WZOZI.mjs.map → chunk-AMXVX7V2.mjs.map} +0 -0
- /package/dist/lib/neutral/{move-6NCMKKWD.mjs.map → move-UMDTQST4.mjs.map} +0 -0
- /package/dist/lib/neutral/{play-F5L5LFLW.mjs.map → play-7XTJZ4N6.mjs.map} +0 -0
- /package/dist/lib/neutral/{print-GMSNKAS2.mjs.map → print-JR4VB3UX.mjs.map} +0 -0
- /package/dist/lib/neutral/{blueprints → skills}/index.mjs.map +0 -0
package/dx.config.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Config2 } from '@dxos/app-framework/config';
|
|
6
|
+
import { trim } from '@dxos/util';
|
|
7
|
+
|
|
8
|
+
export default Config2.make({
|
|
9
|
+
plugin: {
|
|
10
|
+
key: 'org.dxos.plugin.chess',
|
|
11
|
+
name: 'Chess',
|
|
12
|
+
author: 'DXOS',
|
|
13
|
+
description: trim`
|
|
14
|
+
Full-featured chess game supporting multiplayer matches with friends or practice sessions against AI opponents.
|
|
15
|
+
Track game history and analyze moves in real-time.
|
|
16
|
+
`,
|
|
17
|
+
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-chess',
|
|
18
|
+
icon: { key: 'ph--shield-chevron--regular', hue: 'amber' },
|
|
19
|
+
spec: 'PLUGIN.mdl',
|
|
20
|
+
tags: ['game'],
|
|
21
|
+
screenshots: [{ dark: 'https://dxos.network/plugin-details-chess-dark.png' }],
|
|
22
|
+
dependsOn: ['org.dxos.plugin.game'],
|
|
23
|
+
},
|
|
24
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/plugin-chess",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.1-staging.ee54ba693a",
|
|
4
4
|
"description": "Chess for new plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"sideEffects": true,
|
|
14
14
|
"type": "module",
|
|
15
15
|
"imports": {
|
|
16
|
-
"#
|
|
17
|
-
"source": "./src/
|
|
18
|
-
"types": "./dist/types/src/
|
|
19
|
-
"default": "./dist/lib/neutral/
|
|
16
|
+
"#skills": {
|
|
17
|
+
"source": "./src/skills/index.ts",
|
|
18
|
+
"types": "./dist/types/src/skills/index.d.ts",
|
|
19
|
+
"default": "./dist/lib/neutral/skills/index.mjs"
|
|
20
20
|
},
|
|
21
21
|
"#capabilities": {
|
|
22
22
|
"source": "./src/capabilities/index.ts",
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"default": "./dist/lib/neutral/index.mjs"
|
|
73
73
|
},
|
|
74
74
|
"./assets/PLUGIN.mdl": "./PLUGIN.mdl",
|
|
75
|
-
"./
|
|
76
|
-
"source": "./src/
|
|
77
|
-
"types": "./dist/types/src/
|
|
78
|
-
"default": "./dist/lib/neutral/
|
|
75
|
+
"./skills": {
|
|
76
|
+
"source": "./src/skills/index.ts",
|
|
77
|
+
"types": "./dist/types/src/skills/index.d.ts",
|
|
78
|
+
"default": "./dist/lib/neutral/skills/index.mjs"
|
|
79
79
|
},
|
|
80
80
|
"./plugin": {
|
|
81
81
|
"source": "./src/plugin.ts",
|
|
@@ -101,47 +101,48 @@
|
|
|
101
101
|
"types": "dist/types/src/index.d.ts",
|
|
102
102
|
"files": [
|
|
103
103
|
"dist",
|
|
104
|
+
"dx.config.ts",
|
|
104
105
|
"src",
|
|
105
106
|
"PLUGIN.mdl"
|
|
106
107
|
],
|
|
107
108
|
"dependencies": {
|
|
108
109
|
"@effect-atom/atom-react": "^0.5.0",
|
|
109
110
|
"chess.js": "^1.0.0",
|
|
110
|
-
"effect": "3.21.
|
|
111
|
-
"@dxos/
|
|
112
|
-
"@dxos/app-
|
|
113
|
-
"@dxos/
|
|
114
|
-
"@dxos/
|
|
115
|
-
"@dxos/echo-react": "0.9.
|
|
116
|
-
"@dxos/
|
|
117
|
-
"@dxos/
|
|
118
|
-
"@dxos/log": "0.9.
|
|
119
|
-
"@dxos/
|
|
120
|
-
"@dxos/plugin-client": "0.9.
|
|
121
|
-
"@dxos/plugin-game": "0.9.
|
|
122
|
-
"@dxos/react-ui-audio": "0.9.
|
|
123
|
-
"@dxos/react-
|
|
124
|
-
"@dxos/react-ui-
|
|
125
|
-
"@dxos/util": "0.9.
|
|
126
|
-
"@dxos/react-
|
|
111
|
+
"effect": "3.21.4",
|
|
112
|
+
"@dxos/app-framework": "0.9.1-staging.ee54ba693a",
|
|
113
|
+
"@dxos/app-toolkit": "0.9.1-staging.ee54ba693a",
|
|
114
|
+
"@dxos/async": "0.9.1-staging.ee54ba693a",
|
|
115
|
+
"@dxos/compute": "0.9.1-staging.ee54ba693a",
|
|
116
|
+
"@dxos/echo-react": "0.9.1-staging.ee54ba693a",
|
|
117
|
+
"@dxos/invariant": "0.9.1-staging.ee54ba693a",
|
|
118
|
+
"@dxos/echo": "0.9.1-staging.ee54ba693a",
|
|
119
|
+
"@dxos/log": "0.9.1-staging.ee54ba693a",
|
|
120
|
+
"@dxos/keys": "0.9.1-staging.ee54ba693a",
|
|
121
|
+
"@dxos/plugin-client": "0.9.1-staging.ee54ba693a",
|
|
122
|
+
"@dxos/plugin-game": "0.9.1-staging.ee54ba693a",
|
|
123
|
+
"@dxos/react-ui-audio": "0.9.1-staging.ee54ba693a",
|
|
124
|
+
"@dxos/react-ui-gameboard": "0.9.1-staging.ee54ba693a",
|
|
125
|
+
"@dxos/react-ui-mosaic": "0.9.1-staging.ee54ba693a",
|
|
126
|
+
"@dxos/util": "0.9.1-staging.ee54ba693a",
|
|
127
|
+
"@dxos/react-client": "0.9.1-staging.ee54ba693a"
|
|
127
128
|
},
|
|
128
129
|
"devDependencies": {
|
|
129
|
-
"@types/react": "~19.2.
|
|
130
|
+
"@types/react": "~19.2.17",
|
|
130
131
|
"@types/react-dom": "~19.2.3",
|
|
131
|
-
"react": "~19.2.
|
|
132
|
-
"react-dom": "~19.2.
|
|
132
|
+
"react": "~19.2.7",
|
|
133
|
+
"react-dom": "~19.2.7",
|
|
133
134
|
"vite": "^8.0.16",
|
|
134
|
-
"@dxos/plugin-testing": "0.9.
|
|
135
|
-
"@dxos/plugin-theme": "0.9.
|
|
136
|
-
"@dxos/
|
|
137
|
-
"@dxos/
|
|
138
|
-
"@dxos/
|
|
135
|
+
"@dxos/plugin-testing": "0.9.1-staging.ee54ba693a",
|
|
136
|
+
"@dxos/plugin-theme": "0.9.1-staging.ee54ba693a",
|
|
137
|
+
"@dxos/react-ui": "0.9.1-staging.ee54ba693a",
|
|
138
|
+
"@dxos/storybook-utils": "0.9.1-staging.ee54ba693a",
|
|
139
|
+
"@dxos/ui-theme": "0.9.1-staging.ee54ba693a"
|
|
139
140
|
},
|
|
140
141
|
"peerDependencies": {
|
|
141
|
-
"react": "~19.2.
|
|
142
|
-
"react-dom": "~19.2.
|
|
143
|
-
"@dxos/react-ui": "0.9.
|
|
144
|
-
"@dxos/ui-theme": "0.9.
|
|
142
|
+
"react": "~19.2.7",
|
|
143
|
+
"react-dom": "~19.2.7",
|
|
144
|
+
"@dxos/react-ui": "0.9.1-staging.ee54ba693a",
|
|
145
|
+
"@dxos/ui-theme": "0.9.1-staging.ee54ba693a"
|
|
145
146
|
},
|
|
146
147
|
"publishConfig": {
|
|
147
148
|
"access": "public"
|
package/src/ChessPlugin.node.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
6
|
import { AppPlugin } from '@dxos/app-toolkit';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { OperationHandler, SkillDefinition } from '#capabilities';
|
|
9
9
|
import { meta } from '#meta';
|
|
10
10
|
import { Chess } from '#types';
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ import { Chess } from '#types';
|
|
|
15
15
|
*/
|
|
16
16
|
export const ChessPlugin = Plugin.define(meta).pipe(
|
|
17
17
|
AppPlugin.addSchemaModule({ schema: [Chess.State] }),
|
|
18
|
-
AppPlugin.
|
|
18
|
+
AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
|
|
19
19
|
AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
|
|
20
20
|
Plugin.make,
|
|
21
21
|
);
|
package/src/ChessPlugin.test.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { ChessPlugin } from '#plugin';
|
|
|
15
15
|
import { meta } from './meta';
|
|
16
16
|
import { ChessOperation } from './types';
|
|
17
17
|
|
|
18
|
-
const moduleId = (name: string) => `${meta.
|
|
18
|
+
const moduleId = (name: string) => `${meta.profile.key}.module.${name}`;
|
|
19
19
|
|
|
20
20
|
describe('ChessPlugin', () => {
|
|
21
21
|
test('modules activate on the expected events', async ({ expect }) => {
|
|
@@ -28,7 +28,7 @@ describe('ChessPlugin', () => {
|
|
|
28
28
|
|
|
29
29
|
// SetupArtifactDefinition is fired by AssistantPlugin, which can't be included here due to a workspace cycle.
|
|
30
30
|
await harness.fire(AppActivationEvents.SetupArtifactDefinition);
|
|
31
|
-
expect(harness.manager.getActive()).toContain(moduleId('
|
|
31
|
+
expect(harness.manager.getActive()).toContain(moduleId('SkillDefinition'));
|
|
32
32
|
|
|
33
33
|
// Operation handlers are not loaded on startup — SetupProcessManager fires lazily when an operation is invoked.
|
|
34
34
|
await harness.fire(ActivationEvents.SetupProcessManager);
|
package/src/ChessPlugin.tsx
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
|
-
import {
|
|
6
|
+
import { AppActivationEvents, AppPlugin } from '@dxos/app-toolkit';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { GameVariant, OperationHandler, SkillDefinition } from '#capabilities';
|
|
9
9
|
import { meta } from '#meta';
|
|
10
10
|
import { translations } from '#translations';
|
|
11
11
|
import { Chess } from '#types';
|
|
@@ -19,10 +19,10 @@ export const ChessPlugin = Plugin.define(meta).pipe(
|
|
|
19
19
|
activatesOn: AppActivationEvents.SetupSchema,
|
|
20
20
|
activate: GameVariant,
|
|
21
21
|
}),
|
|
22
|
-
AppPlugin.
|
|
22
|
+
AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
|
|
23
23
|
AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
|
|
24
24
|
AppPlugin.addPluginAssetModule({
|
|
25
|
-
asset: { pluginId: meta.
|
|
25
|
+
asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
|
|
26
26
|
}),
|
|
27
27
|
AppPlugin.addSchemaModule({ schema: [Chess.State] }),
|
|
28
28
|
AppPlugin.addTranslationsModule({ translations }),
|
|
@@ -3,15 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Capability } from '@dxos/app-framework';
|
|
6
|
-
import { type AppCapabilities } from '@dxos/app-toolkit';
|
|
7
6
|
import type { OperationHandlerSet } from '@dxos/compute';
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
// wrapper needs an explicit annotation to keep the inferred type portable (TS2883).
|
|
11
|
-
export const BlueprintDefinition: Capability.LazyCapability<
|
|
12
|
-
void,
|
|
13
|
-
Capability.Capability<typeof AppCapabilities.BlueprintDefinition>[]
|
|
14
|
-
> = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
|
|
8
|
+
export const SkillDefinition = Capability.lazy('SkillDefinition', () => import('./skill-definition'));
|
|
15
9
|
export const GameVariant = Capability.lazy('GameVariant', () => import('./game-variant'));
|
|
16
10
|
export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
|
|
17
11
|
'OperationHandler',
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
|
|
7
|
+
import { Capability } from '@dxos/app-framework';
|
|
8
|
+
import { AppCapabilities } from '@dxos/app-toolkit';
|
|
9
|
+
|
|
10
|
+
import { ChessSkill } from '#skills';
|
|
11
|
+
|
|
12
|
+
const skillDefinition = () => Effect.succeed([Capability.contributes(AppCapabilities.SkillDefinition, ChessSkill)]);
|
|
13
|
+
|
|
14
|
+
export default skillDefinition;
|
|
@@ -20,11 +20,11 @@ const SAMPLE_PGN =
|
|
|
20
20
|
const PROMOTION_PGN =
|
|
21
21
|
'1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. c3 Nf6 5. d4 exd4 6. cxd4 Bb4+ 7. Nc3 d5 8. exd5 Nxd5 9. O-O Be6 10. Qb3 Na5 11. Qa4+ c6 12. Bxd5 Bxc3 13. Bxe6 fxe6 14. d5 Qg5 15. dxe6 Kf8 16. e7+ Kg8 *';
|
|
22
22
|
|
|
23
|
-
type
|
|
23
|
+
type StoryArgs = {
|
|
24
24
|
pgn?: string;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const DefaultStory = ({ pgn }:
|
|
27
|
+
const DefaultStory = ({ pgn }: StoryArgs) => {
|
|
28
28
|
const state = useMemo(() => Chess.make(pgn ? { pgn } : undefined), [pgn]);
|
|
29
29
|
const [orientation, setOrientation] = useState<Player>('white');
|
|
30
30
|
const [showInfo, setShowInfo] = useState(true);
|
|
@@ -11,10 +11,8 @@ import React, {
|
|
|
11
11
|
useEffect,
|
|
12
12
|
useImperativeHandle,
|
|
13
13
|
useMemo,
|
|
14
|
-
useRef,
|
|
15
14
|
} from 'react';
|
|
16
15
|
|
|
17
|
-
import { addEventListener } from '@dxos/async';
|
|
18
16
|
import { useObject } from '@dxos/echo-react';
|
|
19
17
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
20
18
|
import { useSoundEffect } from '@dxos/react-ui-audio';
|
|
@@ -25,7 +23,6 @@ import {
|
|
|
25
23
|
Chessboard as NaturalChessboard,
|
|
26
24
|
type ChessboardProps as NaturalChessboardProps,
|
|
27
25
|
getRawPgn,
|
|
28
|
-
useGameboardContext,
|
|
29
26
|
} from '@dxos/react-ui-gameboard';
|
|
30
27
|
|
|
31
28
|
import { type Chess } from '#types';
|
|
@@ -88,9 +85,48 @@ const Root = forwardRef<ChessboardController, RootProps>(({ state, children }, f
|
|
|
88
85
|
[model],
|
|
89
86
|
);
|
|
90
87
|
|
|
88
|
+
// Keyboard navigation — fires regardless of which descendant (Board or Info) has focus.
|
|
89
|
+
// Gated to elements marked data-chessboard-arrow-navigation to avoid intercepting toolbar controls.
|
|
90
|
+
const handleKeyDown = useCallback(
|
|
91
|
+
(ev: React.KeyboardEvent) => {
|
|
92
|
+
const target = ev.target instanceof HTMLElement ? ev.target : undefined;
|
|
93
|
+
if (!target?.closest('[data-chessboard-arrow-navigation]')) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const moveIndex = registry.get(model.moveIndex);
|
|
98
|
+
switch (ev.key) {
|
|
99
|
+
case 'ArrowUp':
|
|
100
|
+
ev.preventDefault();
|
|
101
|
+
model.setMoveIndex(0);
|
|
102
|
+
break;
|
|
103
|
+
case 'ArrowDown':
|
|
104
|
+
ev.preventDefault();
|
|
105
|
+
model.setMoveIndex(model.game.history().length);
|
|
106
|
+
break;
|
|
107
|
+
case 'ArrowLeft':
|
|
108
|
+
if (moveIndex > 0) {
|
|
109
|
+
ev.preventDefault();
|
|
110
|
+
model.setMoveIndex(moveIndex - 1);
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case 'ArrowRight':
|
|
114
|
+
if (moveIndex < model.game.history().length) {
|
|
115
|
+
ev.preventDefault();
|
|
116
|
+
model.setMoveIndex(moveIndex + 1);
|
|
117
|
+
}
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
[registry, model],
|
|
122
|
+
);
|
|
123
|
+
|
|
91
124
|
return (
|
|
92
125
|
<Gameboard.Root model={model} onDrop={handleDrop}>
|
|
93
|
-
{
|
|
126
|
+
{/* display:contents is layout-transparent; catches keydown bubbled from any focused descendant. */}
|
|
127
|
+
<div className='contents' onKeyDown={handleKeyDown}>
|
|
128
|
+
{children}
|
|
129
|
+
</div>
|
|
94
130
|
</Gameboard.Root>
|
|
95
131
|
);
|
|
96
132
|
});
|
|
@@ -119,45 +155,11 @@ const BOARD_NAME = 'Chessboard.Board';
|
|
|
119
155
|
|
|
120
156
|
type BoardProps = NaturalChessboardProps;
|
|
121
157
|
|
|
122
|
-
const Board = (props: BoardProps) =>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
128
|
-
useEffect(() => {
|
|
129
|
-
if (!ref.current) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Participate in keyboard navigation (set tabIndex={0})
|
|
134
|
-
ref.current.setAttribute('data-arrow-keys', 'all');
|
|
135
|
-
|
|
136
|
-
return addEventListener(ref.current, 'keydown', (ev) => {
|
|
137
|
-
const moveIndex = registry.get(model.moveIndex);
|
|
138
|
-
switch (ev.key) {
|
|
139
|
-
case 'ArrowUp':
|
|
140
|
-
model.setMoveIndex(0);
|
|
141
|
-
break;
|
|
142
|
-
case 'ArrowDown':
|
|
143
|
-
model.setMoveIndex(model.game.history().length);
|
|
144
|
-
break;
|
|
145
|
-
case 'ArrowLeft':
|
|
146
|
-
if (moveIndex > 0) {
|
|
147
|
-
model.setMoveIndex(moveIndex - 1);
|
|
148
|
-
}
|
|
149
|
-
break;
|
|
150
|
-
case 'ArrowRight':
|
|
151
|
-
if (moveIndex < model.game.history().length) {
|
|
152
|
-
model.setMoveIndex(moveIndex + 1);
|
|
153
|
-
}
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
}, [registry, model]);
|
|
158
|
-
|
|
159
|
-
return <NaturalChessboard {...props} ref={ref} />;
|
|
160
|
-
};
|
|
158
|
+
const Board = (props: BoardProps) => (
|
|
159
|
+
<div className='contents' data-chessboard-arrow-navigation>
|
|
160
|
+
<NaturalChessboard {...props} />
|
|
161
|
+
</div>
|
|
162
|
+
);
|
|
161
163
|
|
|
162
164
|
Board.displayName = BOARD_NAME;
|
|
163
165
|
|
|
@@ -173,8 +175,8 @@ export const Chessboard = {
|
|
|
173
175
|
};
|
|
174
176
|
|
|
175
177
|
export type {
|
|
176
|
-
RootProps as ChessboardRootProps,
|
|
177
|
-
ContentProps as ChessboardContentProps,
|
|
178
178
|
BoardProps as ChessboardBoardProps,
|
|
179
|
+
ContentProps as ChessboardContentProps,
|
|
179
180
|
InfoProps as ChessboardInfoProps,
|
|
181
|
+
RootProps as ChessboardRootProps,
|
|
180
182
|
};
|
|
@@ -24,7 +24,7 @@ export type InfoProps = ThemedClassName<
|
|
|
24
24
|
>;
|
|
25
25
|
|
|
26
26
|
export const Info = ({ classNames, orientation = 'white', onOrientationChange, onClose, ...props }: InfoProps) => {
|
|
27
|
-
const { t } = useTranslation(meta.
|
|
27
|
+
const { t } = useTranslation(meta.profile.key);
|
|
28
28
|
const { model } = useGameboardContext<ExtendedChessModel>(INFO_NAME);
|
|
29
29
|
|
|
30
30
|
return (
|
|
@@ -87,7 +87,7 @@ type HistoryProps = ThemedClassName<{
|
|
|
87
87
|
}>;
|
|
88
88
|
|
|
89
89
|
const History = ({ classNames, model, min, max, onSelect }: HistoryProps) => {
|
|
90
|
-
const { t } = useTranslation(meta.
|
|
90
|
+
const { t } = useTranslation(meta.profile.key);
|
|
91
91
|
const moveIndex = useAtomValue(model.moveIndex);
|
|
92
92
|
const label = model.game.isGameOver()
|
|
93
93
|
? model.game.isCheckmate()
|
|
@@ -131,7 +131,9 @@ const History = ({ classNames, model, min, max, onSelect }: HistoryProps) => {
|
|
|
131
131
|
return (
|
|
132
132
|
<div
|
|
133
133
|
ref={scrollerRef}
|
|
134
|
-
|
|
134
|
+
tabIndex={0}
|
|
135
|
+
data-chessboard-arrow-navigation
|
|
136
|
+
className={mx('overflow-y-auto outline-hidden focus-visible:ring-2 focus-visible:ring-primary-500', classNames)}
|
|
135
137
|
style={{
|
|
136
138
|
minHeight: min === undefined ? 'auto' : `${min * 24}px`,
|
|
137
139
|
maxHeight: max === undefined ? 'auto' : `${max * 24}px`,
|
|
@@ -15,11 +15,11 @@ import { Chess } from '#types';
|
|
|
15
15
|
|
|
16
16
|
import { ChessArticle } from './ChessArticle';
|
|
17
17
|
|
|
18
|
-
type
|
|
18
|
+
type StoryArgs = {
|
|
19
19
|
pgn?: string;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
const DefaultStory = ({ pgn }:
|
|
22
|
+
const DefaultStory = ({ pgn }: StoryArgs) => {
|
|
23
23
|
const { game, state } = useMemo(() => {
|
|
24
24
|
const state = Chess.make(pgn ? { pgn } : undefined);
|
|
25
25
|
const game = makeGame({ name: 'Story game', variant: state as Obj.Unknown });
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Chess as ChessJS } from 'chess.js';
|
|
6
6
|
import React, { useCallback, useRef, useState } from 'react';
|
|
7
7
|
|
|
8
|
+
import { AppSurface } from '@dxos/app-toolkit/ui';
|
|
8
9
|
import { Obj } from '@dxos/echo';
|
|
9
10
|
import { type GameVariantSurfaceProps } from '@dxos/plugin-game/types';
|
|
10
11
|
import { Panel, Toolbar, useTranslation } from '@dxos/react-ui';
|
|
@@ -18,7 +19,7 @@ import { Chess } from '#types';
|
|
|
18
19
|
export type ChessArticleProps = GameVariantSurfaceProps;
|
|
19
20
|
|
|
20
21
|
export const ChessArticle = ({ role, variant }: ChessArticleProps) => {
|
|
21
|
-
const { t } = useTranslation(meta.
|
|
22
|
+
const { t } = useTranslation(meta.profile.key);
|
|
22
23
|
const [orientation, setOrientation] = useState<Player>('white');
|
|
23
24
|
const [showInfo, setShowInfo] = useState(true);
|
|
24
25
|
const controller = useRef<ChessboardController>(null);
|
|
@@ -80,9 +81,9 @@ export const ChessArticle = ({ role, variant }: ChessArticleProps) => {
|
|
|
80
81
|
className={mx(
|
|
81
82
|
'grid h-full w-full',
|
|
82
83
|
showInfo && '@4xl:grid-cols-[1fr_320px] gap-8',
|
|
83
|
-
role ===
|
|
84
|
-
role ===
|
|
85
|
-
role ===
|
|
84
|
+
role === AppSurface.Article.role && 'p-4',
|
|
85
|
+
role === AppSurface.Section.role && 'aspect-square',
|
|
86
|
+
role === AppSurface.Section.role && showInfo && '@4xl:aspect-auto',
|
|
86
87
|
)}
|
|
87
88
|
>
|
|
88
89
|
<Chessboard.Content>
|
|
@@ -24,7 +24,7 @@ const CardStory = () => {
|
|
|
24
24
|
return { game, state };
|
|
25
25
|
}, []);
|
|
26
26
|
return (
|
|
27
|
-
<CardContainer role='popover' icon={pluginMeta.icon}>
|
|
27
|
+
<CardContainer role='popover' icon={pluginMeta.profile.icon?.key}>
|
|
28
28
|
<ChessCard role='card--content' game={game} variant={state} />
|
|
29
29
|
</CardContainer>
|
|
30
30
|
);
|
|
@@ -6,6 +6,7 @@ import React from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { Obj } from '@dxos/echo';
|
|
8
8
|
import { type GameVariantSurfaceProps } from '@dxos/plugin-game/types';
|
|
9
|
+
import { Card } from '@dxos/react-ui';
|
|
9
10
|
|
|
10
11
|
import { Chessboard } from '#components';
|
|
11
12
|
import { Chess } from '#types';
|
|
@@ -18,10 +19,16 @@ export const ChessCard = ({ variant }: ChessCardProps) => {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
return (
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
<Card.Body>
|
|
23
|
+
<Card.Section classNames='aspect-square'>
|
|
24
|
+
<Card.Row fullWidth>
|
|
25
|
+
<Chessboard.Root state={variant}>
|
|
26
|
+
<Chessboard.Content>
|
|
27
|
+
<Chessboard.Board />
|
|
28
|
+
</Chessboard.Content>
|
|
29
|
+
</Chessboard.Root>
|
|
30
|
+
</Card.Row>
|
|
31
|
+
</Card.Section>
|
|
32
|
+
</Card.Body>
|
|
26
33
|
);
|
|
27
34
|
};
|
package/src/index.ts
CHANGED
package/src/meta.ts
CHANGED
|
@@ -3,23 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { Plugin } from '@dxos/app-framework';
|
|
6
|
-
import { DXN } from '@dxos/keys';
|
|
7
|
-
import { meta as gameMeta } from '@dxos/plugin-game';
|
|
8
|
-
import { trim } from '@dxos/util';
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
author: 'DXOS',
|
|
14
|
-
description: trim`
|
|
15
|
-
Full-featured chess game supporting multiplayer matches with friends or practice sessions against AI opponents.
|
|
16
|
-
Track game history and analyze moves in real-time.
|
|
17
|
-
`,
|
|
18
|
-
icon: 'ph--shield-chevron--regular',
|
|
19
|
-
iconHue: 'amber',
|
|
20
|
-
source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-chess',
|
|
21
|
-
spec: 'PLUGIN.mdl',
|
|
22
|
-
screenshots: ['https://dxos.network/plugin-details-chess-dark.png'],
|
|
23
|
-
dependsOn: [gameMeta.id],
|
|
24
|
-
tags: ['game'],
|
|
25
|
-
});
|
|
7
|
+
import config from '../dx.config';
|
|
8
|
+
|
|
9
|
+
export const meta = Plugin.getMetaFromConfig(config);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Skill, Template } from '@dxos/compute';
|
|
6
6
|
import { trim } from '@dxos/util';
|
|
7
7
|
|
|
8
8
|
import { Chess, ChessOperation } from '#types';
|
|
@@ -10,23 +10,27 @@ import { Chess, ChessOperation } from '#types';
|
|
|
10
10
|
const operations = [ChessOperation.Move, ChessOperation.Play, ChessOperation.Print];
|
|
11
11
|
|
|
12
12
|
const make = () =>
|
|
13
|
-
|
|
14
|
-
key: Chess.
|
|
13
|
+
Skill.make({
|
|
14
|
+
key: Chess.SKILL_KEY,
|
|
15
15
|
name: 'Chess',
|
|
16
|
-
tools:
|
|
16
|
+
tools: Skill.toolDefinitions({ operations }),
|
|
17
17
|
instructions: Template.make({
|
|
18
18
|
source: trim`
|
|
19
19
|
You are an expert chess player.
|
|
20
20
|
To analyze a game you can access the "pgn" property by loading the context object that represents the current game.
|
|
21
21
|
You could suggest a good next move or offer to play a move.
|
|
22
22
|
Don't actually make a move unless you are asked to.
|
|
23
|
+
|
|
24
|
+
When setting a chess position, always set the "pgn" field (move list in standard PGN notation) on the org.dxos.type.chess.state object.
|
|
25
|
+
The "fen" field is not used by the UI for display — the board is driven exclusively from "pgn".
|
|
26
|
+
Setting "fen" alone or leaving "pgn" empty will result in the initial position being shown.
|
|
23
27
|
`,
|
|
24
28
|
}),
|
|
25
29
|
});
|
|
26
30
|
|
|
27
|
-
const
|
|
28
|
-
key: Chess.
|
|
31
|
+
const skill: Skill.Definition = {
|
|
32
|
+
key: Chess.SKILL_KEY,
|
|
29
33
|
make,
|
|
30
34
|
};
|
|
31
35
|
|
|
32
|
-
export default
|
|
36
|
+
export default skill;
|
package/src/translations.ts
CHANGED
|
@@ -21,7 +21,7 @@ export const translations = [
|
|
|
21
21
|
'rename-object.label': 'Rename chess game',
|
|
22
22
|
'delete-object.label': 'Delete chess game',
|
|
23
23
|
},
|
|
24
|
-
[meta.
|
|
24
|
+
[meta.profile.key]: {
|
|
25
25
|
'plugin.name': 'Chess',
|
|
26
26
|
'new-game.button': 'New game',
|
|
27
27
|
'delete-game.label': 'Delete',
|