@hmcs/sdk 1.0.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.
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # @hmcs/sdk
2
+
3
+ TypeScript SDK for building mods and extensions for [Desktop Homunculus](https://github.com/not-elm/desktop_homunculus).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @hmcs/sdk@https://github.com/desktop-homunculus/typescript-sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { Vrm } from "@hmcs/sdk";
15
+ // Spawn a VRM character
16
+ const vrm = await Vrm.spawn("my-mod:avatar");
17
+ ```
18
+
19
+ ## Function Style
20
+
21
+ For SDK source code under `src/`, use the following style:
22
+
23
+ - Use `function` / `async function` declarations for top-level public API functions and reusable top-level helpers.
24
+ - Use arrow functions for inline callbacks (for example, array methods and event listeners).
25
+
26
+ This keeps API boundaries explicit while preserving readability in callback-heavy code.
27
+
28
+ ## License
29
+
30
+ MIT
package/dist/app.cjs ADDED
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ var host = require('./host.cjs');
4
+
5
+ /**
6
+ * Provides access to the application API.
7
+ */
8
+ exports.app = void 0;
9
+ (function (app) {
10
+ /**
11
+ * Exits the application without any problems.
12
+ */
13
+ async function exit() {
14
+ await host.host.post(host.host.createUrl("app/exit"));
15
+ }
16
+ app.exit = exit;
17
+ /**
18
+ * Checks if the Desktop Homunculus server is running and healthy.
19
+ *
20
+ * Returns `true` if the server responds with a successful health check,
21
+ * `false` if the server is unreachable or unhealthy.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const alive = await app.health();
26
+ * if (!alive) {
27
+ * console.error("Homunculus server is not running");
28
+ * }
29
+ * ```
30
+ */
31
+ async function health() {
32
+ try {
33
+ const response = await fetch(host.host.createUrl("app/health"));
34
+ return response.ok;
35
+ }
36
+ catch {
37
+ return false;
38
+ }
39
+ }
40
+ app.health = health;
41
+ /**
42
+ * Returns metadata about the running Desktop Homunculus instance.
43
+ *
44
+ * Provides the engine version, platform info, compiled features,
45
+ * and loaded mods in a single request. Useful for startup checks,
46
+ * feature detection, and status displays.
47
+ *
48
+ * @returns Application info including version, platform, features, and mods
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const info = await app.info();
53
+ * console.log(`Engine v${info.version} on ${info.platform.os}/${info.platform.arch}`);
54
+ * console.log(`Features: ${info.features.join(", ")}`);
55
+ * console.log(`${info.mods.length} mods loaded`);
56
+ * ```
57
+ */
58
+ async function info() {
59
+ const response = await host.host.get(host.host.createUrl("app/info"));
60
+ return await response.json();
61
+ }
62
+ app.info = info;
63
+ })(exports.app || (exports.app = {}));
package/dist/app.js ADDED
@@ -0,0 +1,63 @@
1
+ import { host } from './host.js';
2
+
3
+ /**
4
+ * Provides access to the application API.
5
+ */
6
+ var app;
7
+ (function (app) {
8
+ /**
9
+ * Exits the application without any problems.
10
+ */
11
+ async function exit() {
12
+ await host.post(host.createUrl("app/exit"));
13
+ }
14
+ app.exit = exit;
15
+ /**
16
+ * Checks if the Desktop Homunculus server is running and healthy.
17
+ *
18
+ * Returns `true` if the server responds with a successful health check,
19
+ * `false` if the server is unreachable or unhealthy.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const alive = await app.health();
24
+ * if (!alive) {
25
+ * console.error("Homunculus server is not running");
26
+ * }
27
+ * ```
28
+ */
29
+ async function health() {
30
+ try {
31
+ const response = await fetch(host.createUrl("app/health"));
32
+ return response.ok;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ app.health = health;
39
+ /**
40
+ * Returns metadata about the running Desktop Homunculus instance.
41
+ *
42
+ * Provides the engine version, platform info, compiled features,
43
+ * and loaded mods in a single request. Useful for startup checks,
44
+ * feature detection, and status displays.
45
+ *
46
+ * @returns Application info including version, platform, features, and mods
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const info = await app.info();
51
+ * console.log(`Engine v${info.version} on ${info.platform.os}/${info.platform.arch}`);
52
+ * console.log(`Features: ${info.features.join(", ")}`);
53
+ * console.log(`${info.mods.length} mods loaded`);
54
+ * ```
55
+ */
56
+ async function info() {
57
+ const response = await host.get(host.createUrl("app/info"));
58
+ return await response.json();
59
+ }
60
+ app.info = info;
61
+ })(app || (app = {}));
62
+
63
+ export { app };
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ var host = require('./host.cjs');
4
+
5
+ /**
6
+ * Assets API namespace for querying available mod assets.
7
+ *
8
+ * Provides access to the asset registry, which contains all assets declared
9
+ * by installed mods. Assets are referenced by their globally unique ID using
10
+ * the format `"mod-name:asset-name"` (e.g., `"elmer:idle"`, `"my-mod:click"`).
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // List all available assets
15
+ * const all = await assets.list();
16
+ *
17
+ * // Filter by type
18
+ * const vrms = await assets.list({ type: "vrm" });
19
+ *
20
+ * // Filter by mod
21
+ * const elmerAssets = await assets.list({ mod: "elmer" });
22
+ * ```
23
+ */
24
+ exports.assets = void 0;
25
+ (function (assets) {
26
+ /**
27
+ * Lists available assets, optionally filtered by type and/or mod.
28
+ *
29
+ * @param filter - Optional filter criteria
30
+ * @returns Array of matching asset info objects
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // Get all assets
35
+ * const all = await assets.list();
36
+ *
37
+ * // Get only VRM models
38
+ * const vrms = await assets.list({ type: "vrm" });
39
+ *
40
+ * // Get assets from a specific mod
41
+ * const modAssets = await assets.list({ mod: "elmer" });
42
+ *
43
+ * // Combine filters
44
+ * const sounds = await assets.list({ type: "sound", mod: "my-mod" });
45
+ * ```
46
+ */
47
+ async function list(filter) {
48
+ const response = await host.host.get(host.host.createUrl("assets", filter));
49
+ return await response.json();
50
+ }
51
+ assets.list = list;
52
+ })(exports.assets || (exports.assets = {}));
package/dist/assets.js ADDED
@@ -0,0 +1,52 @@
1
+ import { host } from './host.js';
2
+
3
+ /**
4
+ * Assets API namespace for querying available mod assets.
5
+ *
6
+ * Provides access to the asset registry, which contains all assets declared
7
+ * by installed mods. Assets are referenced by their globally unique ID using
8
+ * the format `"mod-name:asset-name"` (e.g., `"elmer:idle"`, `"my-mod:click"`).
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // List all available assets
13
+ * const all = await assets.list();
14
+ *
15
+ * // Filter by type
16
+ * const vrms = await assets.list({ type: "vrm" });
17
+ *
18
+ * // Filter by mod
19
+ * const elmerAssets = await assets.list({ mod: "elmer" });
20
+ * ```
21
+ */
22
+ var assets;
23
+ (function (assets) {
24
+ /**
25
+ * Lists available assets, optionally filtered by type and/or mod.
26
+ *
27
+ * @param filter - Optional filter criteria
28
+ * @returns Array of matching asset info objects
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Get all assets
33
+ * const all = await assets.list();
34
+ *
35
+ * // Get only VRM models
36
+ * const vrms = await assets.list({ type: "vrm" });
37
+ *
38
+ * // Get assets from a specific mod
39
+ * const modAssets = await assets.list({ mod: "elmer" });
40
+ *
41
+ * // Combine filters
42
+ * const sounds = await assets.list({ type: "sound", mod: "my-mod" });
43
+ * ```
44
+ */
45
+ async function list(filter) {
46
+ const response = await host.get(host.createUrl("assets", filter));
47
+ return await response.json();
48
+ }
49
+ assets.list = list;
50
+ })(assets || (assets = {}));
51
+
52
+ export { assets };
package/dist/audio.cjs ADDED
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ var host = require('./host.cjs');
4
+
5
+ /**
6
+ * Audio API namespace for playing sound effects and background music.
7
+ *
8
+ * Provides functionality for one-shot sound effects ({@link audio.se}) and
9
+ * looping background music with transport controls ({@link audio.bgm}).
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Play a sound effect
14
+ * await audio.se.play("click");
15
+ *
16
+ * // Play background music with fade-in
17
+ * await audio.bgm.play("heme", {
18
+ * volume: 0.8,
19
+ * fadeIn: { durationSecs: 2.0 }
20
+ * });
21
+ *
22
+ * // Stop BGM with fade-out
23
+ * await audio.bgm.stop({ fadeOut: { durationSecs: 1.5 } });
24
+ * ```
25
+ */
26
+ exports.audio = void 0;
27
+ (function (audio) {
28
+ (function (se) {
29
+ /**
30
+ * Plays a one-shot sound effect.
31
+ *
32
+ * @param asset - The asset ID of the sound effect (e.g., `"click"`)
33
+ * @param options - Optional playback configuration
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * await audio.se.play("click");
38
+ *
39
+ * await audio.se.play("coin", {
40
+ * volume: 0.7,
41
+ * speed: 1.5,
42
+ * panning: 0.3
43
+ * });
44
+ * ```
45
+ */
46
+ async function play(asset, options) {
47
+ await host.host.post(host.host.createUrl("audio/se"), { asset, ...options });
48
+ }
49
+ se.play = play;
50
+ })(audio.se || (audio.se = {}));
51
+ (function (bgm) {
52
+ /**
53
+ * Plays background music, replacing any currently playing BGM.
54
+ *
55
+ * @param asset - The asset ID of the music track (e.g., `"theme"`)
56
+ * @param options - Optional playback configuration
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * // Simple playback (loops by default)
61
+ * await audio.bgm.play("my-mod:battle");
62
+ *
63
+ * // With options
64
+ * await audio.bgm.play("my-mod:intro", {
65
+ * loop: false,
66
+ * volume: 0.6,
67
+ * fadeIn: { durationSecs: 3.0, easing: "easeIn" }
68
+ * });
69
+ * ```
70
+ */
71
+ async function play(asset, options) {
72
+ await host.host.post(host.host.createUrl("audio/bgm"), { asset, ...options });
73
+ }
74
+ bgm.play = play;
75
+ /**
76
+ * Stops the currently playing BGM.
77
+ *
78
+ * @param options - Optional stop configuration (e.g., fade-out)
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // Immediate stop
83
+ * await audio.bgm.stop();
84
+ *
85
+ * // Fade out over 2 seconds
86
+ * await audio.bgm.stop({
87
+ * fadeOut: { durationSecs: 2.0, easing: "easeOut" }
88
+ * });
89
+ * ```
90
+ */
91
+ async function stop(options) {
92
+ await host.host.post(host.host.createUrl("audio/bgm/stop"), { ...options });
93
+ }
94
+ bgm.stop = stop;
95
+ /**
96
+ * Pauses the currently playing BGM.
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * await audio.bgm.pause();
101
+ * ```
102
+ */
103
+ async function pause() {
104
+ await host.host.post(host.host.createUrl("audio/bgm/pause"), {});
105
+ }
106
+ bgm.pause = pause;
107
+ /**
108
+ * Resumes paused BGM playback.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * await audio.bgm.resume();
113
+ * ```
114
+ */
115
+ async function resume() {
116
+ await host.host.post(host.host.createUrl("audio/bgm/resume"), {});
117
+ }
118
+ bgm.resume = resume;
119
+ /**
120
+ * Updates playback parameters of the currently playing BGM.
121
+ *
122
+ * @param options - The parameters to update
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * // Fade volume to 0.3 over 1 second
127
+ * await audio.bgm.update({
128
+ * volume: 0.3,
129
+ * tween: { durationSecs: 1.0, easing: "easeInOut" }
130
+ * });
131
+ *
132
+ * // Change speed immediately
133
+ * await audio.bgm.update({ speed: 0.8 });
134
+ * ```
135
+ */
136
+ async function update(options) {
137
+ await host.host.patch(host.host.createUrl("audio/bgm"), options);
138
+ }
139
+ bgm.update = update;
140
+ /**
141
+ * Gets the current BGM playback status.
142
+ *
143
+ * @returns The current BGM status including asset, state, volume, and speed
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * const status = await audio.bgm.status();
148
+ * if (status.state === "playing") {
149
+ * console.log(`Now playing: ${status.asset} at volume ${status.volume}`);
150
+ * }
151
+ * ```
152
+ */
153
+ async function status() {
154
+ const response = await host.host.get(host.host.createUrl("audio/bgm"));
155
+ return await response.json();
156
+ }
157
+ bgm.status = status;
158
+ })(audio.bgm || (audio.bgm = {}));
159
+ })(exports.audio || (exports.audio = {}));
package/dist/audio.js ADDED
@@ -0,0 +1,159 @@
1
+ import { host } from './host.js';
2
+
3
+ /**
4
+ * Audio API namespace for playing sound effects and background music.
5
+ *
6
+ * Provides functionality for one-shot sound effects ({@link audio.se}) and
7
+ * looping background music with transport controls ({@link audio.bgm}).
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // Play a sound effect
12
+ * await audio.se.play("click");
13
+ *
14
+ * // Play background music with fade-in
15
+ * await audio.bgm.play("heme", {
16
+ * volume: 0.8,
17
+ * fadeIn: { durationSecs: 2.0 }
18
+ * });
19
+ *
20
+ * // Stop BGM with fade-out
21
+ * await audio.bgm.stop({ fadeOut: { durationSecs: 1.5 } });
22
+ * ```
23
+ */
24
+ var audio;
25
+ (function (audio) {
26
+ (function (se) {
27
+ /**
28
+ * Plays a one-shot sound effect.
29
+ *
30
+ * @param asset - The asset ID of the sound effect (e.g., `"click"`)
31
+ * @param options - Optional playback configuration
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * await audio.se.play("click");
36
+ *
37
+ * await audio.se.play("coin", {
38
+ * volume: 0.7,
39
+ * speed: 1.5,
40
+ * panning: 0.3
41
+ * });
42
+ * ```
43
+ */
44
+ async function play(asset, options) {
45
+ await host.post(host.createUrl("audio/se"), { asset, ...options });
46
+ }
47
+ se.play = play;
48
+ })(audio.se || (audio.se = {}));
49
+ (function (bgm) {
50
+ /**
51
+ * Plays background music, replacing any currently playing BGM.
52
+ *
53
+ * @param asset - The asset ID of the music track (e.g., `"theme"`)
54
+ * @param options - Optional playback configuration
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // Simple playback (loops by default)
59
+ * await audio.bgm.play("my-mod:battle");
60
+ *
61
+ * // With options
62
+ * await audio.bgm.play("my-mod:intro", {
63
+ * loop: false,
64
+ * volume: 0.6,
65
+ * fadeIn: { durationSecs: 3.0, easing: "easeIn" }
66
+ * });
67
+ * ```
68
+ */
69
+ async function play(asset, options) {
70
+ await host.post(host.createUrl("audio/bgm"), { asset, ...options });
71
+ }
72
+ bgm.play = play;
73
+ /**
74
+ * Stops the currently playing BGM.
75
+ *
76
+ * @param options - Optional stop configuration (e.g., fade-out)
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * // Immediate stop
81
+ * await audio.bgm.stop();
82
+ *
83
+ * // Fade out over 2 seconds
84
+ * await audio.bgm.stop({
85
+ * fadeOut: { durationSecs: 2.0, easing: "easeOut" }
86
+ * });
87
+ * ```
88
+ */
89
+ async function stop(options) {
90
+ await host.post(host.createUrl("audio/bgm/stop"), { ...options });
91
+ }
92
+ bgm.stop = stop;
93
+ /**
94
+ * Pauses the currently playing BGM.
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * await audio.bgm.pause();
99
+ * ```
100
+ */
101
+ async function pause() {
102
+ await host.post(host.createUrl("audio/bgm/pause"), {});
103
+ }
104
+ bgm.pause = pause;
105
+ /**
106
+ * Resumes paused BGM playback.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * await audio.bgm.resume();
111
+ * ```
112
+ */
113
+ async function resume() {
114
+ await host.post(host.createUrl("audio/bgm/resume"), {});
115
+ }
116
+ bgm.resume = resume;
117
+ /**
118
+ * Updates playback parameters of the currently playing BGM.
119
+ *
120
+ * @param options - The parameters to update
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * // Fade volume to 0.3 over 1 second
125
+ * await audio.bgm.update({
126
+ * volume: 0.3,
127
+ * tween: { durationSecs: 1.0, easing: "easeInOut" }
128
+ * });
129
+ *
130
+ * // Change speed immediately
131
+ * await audio.bgm.update({ speed: 0.8 });
132
+ * ```
133
+ */
134
+ async function update(options) {
135
+ await host.patch(host.createUrl("audio/bgm"), options);
136
+ }
137
+ bgm.update = update;
138
+ /**
139
+ * Gets the current BGM playback status.
140
+ *
141
+ * @returns The current BGM status including asset, state, volume, and speed
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const status = await audio.bgm.status();
146
+ * if (status.state === "playing") {
147
+ * console.log(`Now playing: ${status.asset} at volume ${status.volume}`);
148
+ * }
149
+ * ```
150
+ */
151
+ async function status() {
152
+ const response = await host.get(host.createUrl("audio/bgm"));
153
+ return await response.json();
154
+ }
155
+ bgm.status = status;
156
+ })(audio.bgm || (audio.bgm = {}));
157
+ })(audio || (audio = {}));
158
+
159
+ export { audio };