feat: add Stack-chan WASM build support#402
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds WASM build tooling and manifests, many WASM-target stub modules (drivers, services, TTS, hardware shims), and a WASM startup branch that evaluates Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Main as Main
participant Trace as Trace
participant DefaultMod as DefaultMod
participant Robot as Robot
Main->>Trace: log("main start")
Main->>Trace: log("install button bridge")
Main->>Trace: log("wifi stage")
Main->>DefaultMod: call onLaunch()
DefaultMod-->>Main: true
Main->>Trace: log("shouldRobotCreate = true")
Main->>Robot: createRobot()
Robot-->>Main: robotInstance
Main->>Trace: log("calling onRobotCreated")
Main->>DefaultMod: call onRobotCreated(robotInstance)
DefaultMod-->>Main: (done)
Main->>Trace: log("onRobotCreated completed")
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52e849fa60
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| async getRotation(): Promise<null> { | ||
| return null |
There was a problem hiding this comment.
Return
Maybe shape from WASM getRotation
Robot.updatePose assumes driver.getRotation() returns an object with a success field and immediately dereferences result.success. In the WASM path, this stub returns null, so the default WASM config (driver.type: "none" in manifest_wasm.json) will hit a runtime error as soon as pose updates run. This prevents normal simulator behavior and should return a valid Maybe<Rotation> object like the non-WASM NoneDriver implementation.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@firmware/stackchan/drivers/wasm/driver-stub.ts`:
- Around line 6-8: WasmDriver.getRotation() currently returns ZERO_ROTATION
directly which violates the driver result contract expected by callers to check
result.success; change getRotation to return a result object wrapping the
rotation, e.g. { success: true, rotation: ZERO_ROTATION } (or { success: false,
error: ... } on failure) so call sites that inspect result.success continue to
work; update the getRotation implementation and any related tests to return the
standardized result shape and reference ZERO_ROTATION inside that result.
In `@firmware/stackchan/drivers/wasm/dynamixel-driver.ts`:
- Around line 4-5: DynamixelDriver.getRotation currently returns null which
breaks callers expecting a Maybe object; change the function signature from
Promise<null> to Promise<Maybe<number>> (or the appropriate Maybe<T> for
rotation) and update the implementation to always return a Maybe shaped object
(e.g., { success: false } on error or { success: true, value: rotation } on
success) so callers can safely read result.success; ensure any internal paths
that previously returned null now return the correct Maybe form.
In `@firmware/stackchan/drivers/wasm/none-driver.ts`:
- Around line 4-5: getRotation currently returns null which breaks callers
expecting a Maybe-shaped object; change the implementation of getRotation to
return a Maybe-shaped object (e.g., an object containing the expected success
flag and value fields rather than null) so callers can safely read
result.success and result.value; update the returned Promise from getRotation to
resolve to that object shape (keeping the async signature) and ensure it matches
the project's Maybe type contract used elsewhere.
In `@firmware/stackchan/drivers/wasm/rs30x-driver.ts`:
- Around line 4-5: RS30XDriver.getRotation currently returns Promise<null>,
which breaks callers expecting a success-tagged result; update the method
signature and implementation in RS30XDriver.getRotation to return the expected
result shape (e.g., an object with a success boolean and either a rotation value
or an error message), ensure the Promise resolves to that object instead of
null, and adjust any internal logic to produce success: true with the rotation
data on success or success: false with an error on failure so downstream code
can reliably inspect the success tag.
In `@firmware/stackchan/drivers/wasm/scservo-driver.ts`:
- Around line 4-6: The getRotation() implementation currently returns null;
change it to return the zero-rotation object used by the existing WASM driver
baseline (not null). Update the method signature from Promise<null> to the
correct Rotation type (matching the other WASM driver code) and return the
zero-value rotation object (the same shape/fields the rest of the code expects)
so downstream callers no longer need null guards; adjust any imports/types if
necessary to reference the Rotation type and ensure the returned object matches
its shape.
In `@firmware/stackchan/drivers/wasm/sg90-driver.ts`:
- Around line 4-6: The getRotation method on PWMServoDriver currently returns
Promise<null> which violates the driver contract; change the signature to return
the correct rotation-shaped type (e.g., Promise<Rotation> or Promise<number> to
match other drivers) and return a real rotation value instead of null: implement
PWMServoDriver.getRotation to read the servo's current state (from an existing
field such as this.rotation/this.currentAngle or by converting pulse width /
calling the internal read method like getPulseWidth()/readPWMPosition()) and
return a Rotation-shaped object (or numeric angle) wrapped in a resolved Promise
so the method matches other driver implementations.
In `@firmware/stackchan/main.ts`:
- Around line 175-181: The onLaunch and onRobotCreated hooks are called
synchronously but may return Promises, so await their results to preserve
StackchanMod hook semantics and allow async errors to flow; change the call site
to await onLaunch() when computing shouldRobotCreate (e.g., const
shouldRobotCreate = await onLaunch?.() ?? true) and await
onRobotCreated?.(robot, globalEnv.device) after createRobot() (or make the
surrounding function async) so both hook results are handled correctly and any
thrown/rejected errors are propagated.
In `@firmware/stackchan/manifest_wasm.json`:
- Around line 15-19: The modules["*"] array in manifest_wasm.json is
mis-formatted for Biome; reformat the value of modules["*"] to match the
repository's JSON formatting style (one string per line, properly indented, with
commas placed/omitted as in the rest of the file) so the file passes the Biome
formatter; update the array entries for "./touch", "./robot", and "./main"
accordingly and run the Biome formatter (or commit the exact formatting used
elsewhere in the file) before pushing.
In `@firmware/stackchan/speeches/wasm/tts-stub.ts`:
- Around line 2-3: The constructor and stream method in this WASM TTS stub use
untyped parameters; change their signatures to match the explicit types used in
the other WASM TTS implementations (e.g., tts-voicevox.ts, tts-elevenlabs.ts,
tts-remote.ts, tts-openai.ts, tts-local.ts). Specifically, update
constructor(_options) to constructor(options: /* same options type used by the
other WASM TTS classes */) and update async stream(_text, _volume) to async
stream(text: string, volume?: number): /* same return type as other WASM TTS
stream methods */ so the parameter names, types, and return type match the rest
of the implementations.
In `@firmware/stackchan/wasm/microphone.ts`:
- Line 3: Restore the original optional parameter on the microphone API by
changing the record function signature back to record(durationMilliSec?:
number): Promise<ArrayBuffer> (i.e., accept an optional durationMilliSec
parameter), keep existing internal WASM logic unchanged but consume or ignore
durationMilliSec as appropriate (e.g., pass it into the WASM call or use it to
set a timeout/default), and ensure callers remain compatible with non-WASM code
paths; update the record method declaration in microphone.ts accordingly so
TypeScript call-sites don’t break.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7a752a29-2d01-41ed-998e-8b788a080ea3
📒 Files selected for processing (24)
firmware/package.jsonfirmware/stackchan/default-mods/wasm/on-launch.tsfirmware/stackchan/drivers/wasm/driver-stub.tsfirmware/stackchan/drivers/wasm/dynamixel-driver.tsfirmware/stackchan/drivers/wasm/none-driver.tsfirmware/stackchan/drivers/wasm/rs30x-driver.tsfirmware/stackchan/drivers/wasm/scservo-driver.tsfirmware/stackchan/drivers/wasm/sg90-driver.tsfirmware/stackchan/main.tsfirmware/stackchan/manifest_wasm.jsonfirmware/stackchan/renderers-piu/manifest_wasm_renderer_piu.jsonfirmware/stackchan/services/wasm/network-service.tsfirmware/stackchan/services/wasm/preference-server.tsfirmware/stackchan/speeches/wasm/tts-elevenlabs.tsfirmware/stackchan/speeches/wasm/tts-local.tsfirmware/stackchan/speeches/wasm/tts-openai.tsfirmware/stackchan/speeches/wasm/tts-remote.tsfirmware/stackchan/speeches/wasm/tts-stub.tsfirmware/stackchan/speeches/wasm/tts-voicevox-web.tsfirmware/stackchan/speeches/wasm/tts-voicevox.tsfirmware/stackchan/utilities/manifest_wasm_utility.jsonfirmware/stackchan/wasm/led.tsfirmware/stackchan/wasm/microphone.tsfirmware/stackchan/wasm/tone.ts
| async getRotation() { | ||
| return ZERO_ROTATION | ||
| } |
There was a problem hiding this comment.
Align WasmDriver.getRotation() with the driver result contract.
At Line 7, returning a plain rotation object (without success) is unsafe for existing call sites that branch on result.success.
Proposed fix
class WasmDriver {
constructor(_options) {}
async applyRotation(_rotation, _time) {}
async getRotation() {
- return ZERO_ROTATION
+ return {
+ success: true,
+ value: { ...ZERO_ROTATION },
+ }
}
async setTorque(_torque) {}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getRotation() { | |
| return ZERO_ROTATION | |
| } | |
| async getRotation() { | |
| return { | |
| success: true, | |
| value: { ...ZERO_ROTATION }, | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/drivers/wasm/driver-stub.ts` around lines 6 - 8,
WasmDriver.getRotation() currently returns ZERO_ROTATION directly which violates
the driver result contract expected by callers to check result.success; change
getRotation to return a result object wrapping the rotation, e.g. { success:
true, rotation: ZERO_ROTATION } (or { success: false, error: ... } on failure)
so call sites that inspect result.success continue to work; update the
getRotation implementation and any related tests to return the standardized
result shape and reference ZERO_ROTATION inside that result.
| async getRotation(): Promise<null> { | ||
| return null |
There was a problem hiding this comment.
DynamixelDriver.getRotation() should return a Maybe object, not null.
At Line 4, the null return can trigger runtime exceptions where result.success is accessed.
Proposed fix
export class DynamixelDriver {
constructor(_options?: unknown) {}
async applyRotation(_rotation: unknown, _time?: number): Promise<void> {}
- async getRotation(): Promise<null> {
- return null
+ async getRotation(): Promise<{ success: false }> {
+ return { success: false }
}
async setTorque(_torque: boolean): Promise<void> {}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getRotation(): Promise<null> { | |
| return null | |
| async getRotation(): Promise<{ success: false }> { | |
| return { success: false } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/drivers/wasm/dynamixel-driver.ts` around lines 4 - 5,
DynamixelDriver.getRotation currently returns null which breaks callers
expecting a Maybe object; change the function signature from Promise<null> to
Promise<Maybe<number>> (or the appropriate Maybe<T> for rotation) and update the
implementation to always return a Maybe shaped object (e.g., { success: false }
on error or { success: true, value: rotation } on success) so callers can safely
read result.success; ensure any internal paths that previously returned null now
return the correct Maybe form.
| async getRotation(): Promise<null> { | ||
| return null |
There was a problem hiding this comment.
Return a Maybe-shaped object instead of null from getRotation().
At Line 4, returning null breaks callers that read result.success, causing runtime failures in the robot update path.
Proposed fix
export class NoneDriver {
constructor(_options?: unknown) {}
async applyRotation(_rotation: unknown, _time?: number): Promise<void> {}
- async getRotation(): Promise<null> {
- return null
+ async getRotation(): Promise<{ success: false }> {
+ return { success: false }
}
async setTorque(_torque: boolean): Promise<void> {}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getRotation(): Promise<null> { | |
| return null | |
| export class NoneDriver { | |
| constructor(_options?: unknown) {} | |
| async applyRotation(_rotation: unknown, _time?: number): Promise<void> {} | |
| async getRotation(): Promise<{ success: false }> { | |
| return { success: false } | |
| } | |
| async setTorque(_torque: boolean): Promise<void> {} | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/drivers/wasm/none-driver.ts` around lines 4 - 5,
getRotation currently returns null which breaks callers expecting a Maybe-shaped
object; change the implementation of getRotation to return a Maybe-shaped object
(e.g., an object containing the expected success flag and value fields rather
than null) so callers can safely read result.success and result.value; update
the returned Promise from getRotation to resolve to that object shape (keeping
the async signature) and ensure it matches the project's Maybe type contract
used elsewhere.
| async getRotation(): Promise<null> { | ||
| return null |
There was a problem hiding this comment.
RS30XDriver.getRotation() should not return null.
At Line 4, Promise<null> is incompatible with the runtime expectation of a success-tagged result object and can crash downstream logic.
Proposed fix
export class RS30XDriver {
constructor(_options?: unknown) {}
async applyRotation(_rotation: unknown, _time?: number): Promise<void> {}
- async getRotation(): Promise<null> {
- return null
+ async getRotation(): Promise<{ success: false }> {
+ return { success: false }
}
async setTorque(_torque: boolean): Promise<void> {}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getRotation(): Promise<null> { | |
| return null | |
| async getRotation(): Promise<{ success: false }> { | |
| return { success: false } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/drivers/wasm/rs30x-driver.ts` around lines 4 - 5,
RS30XDriver.getRotation currently returns Promise<null>, which breaks callers
expecting a success-tagged result; update the method signature and
implementation in RS30XDriver.getRotation to return the expected result shape
(e.g., an object with a success boolean and either a rotation value or an error
message), ensure the Promise resolves to that object instead of null, and adjust
any internal logic to produce success: true with the rotation data on success or
success: false with an error on failure so downstream code can reliably inspect
the success tag.
| async getRotation(): Promise<null> { | ||
| return null | ||
| } |
There was a problem hiding this comment.
getRotation() should not return null in this WASM driver.
Line 4 diverges from the existing WASM driver baseline (zero rotation object), and null increases downstream runtime guard burden.
Suggested fix
+const ZERO_ROTATION = { y: 0, p: 0, r: 0 } as const
+
export class SCServoDriver {
constructor(_options?: unknown) {}
async applyRotation(_rotation: unknown, _time?: number): Promise<void> {}
- async getRotation(): Promise<null> {
- return null
+ async getRotation(): Promise<typeof ZERO_ROTATION> {
+ return ZERO_ROTATION
}
async setTorque(_torque: boolean): Promise<void> {}
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/drivers/wasm/scservo-driver.ts` around lines 4 - 6, The
getRotation() implementation currently returns null; change it to return the
zero-rotation object used by the existing WASM driver baseline (not null).
Update the method signature from Promise<null> to the correct Rotation type
(matching the other WASM driver code) and return the zero-value rotation object
(the same shape/fields the rest of the code expects) so downstream callers no
longer need null guards; adjust any imports/types if necessary to reference the
Rotation type and ensure the returned object matches its shape.
| async getRotation(): Promise<null> { | ||
| return null | ||
| } |
There was a problem hiding this comment.
PWMServoDriver.getRotation() should return a rotation-shaped value, not null.
Line 4 is contract-inconsistent with the other driver implementations/stubs and can cause downstream runtime errors.
Suggested fix
+const ZERO_ROTATION = { y: 0, p: 0, r: 0 } as const
+
export class PWMServoDriver {
constructor(_options?: unknown) {}
async applyRotation(_rotation: unknown, _time?: number): Promise<void> {}
- async getRotation(): Promise<null> {
- return null
+ async getRotation(): Promise<typeof ZERO_ROTATION> {
+ return ZERO_ROTATION
}
async setTorque(_torque: boolean): Promise<void> {}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async getRotation(): Promise<null> { | |
| return null | |
| } | |
| const ZERO_ROTATION = { y: 0, p: 0, r: 0 } as const | |
| export class PWMServoDriver { | |
| constructor(_options?: unknown) {} | |
| async applyRotation(_rotation: unknown, _time?: number): Promise<void> {} | |
| async getRotation(): Promise<typeof ZERO_ROTATION> { | |
| return ZERO_ROTATION | |
| } | |
| async setTorque(_torque: boolean): Promise<void> {} | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/drivers/wasm/sg90-driver.ts` around lines 4 - 6, The
getRotation method on PWMServoDriver currently returns Promise<null> which
violates the driver contract; change the signature to return the correct
rotation-shaped type (e.g., Promise<Rotation> or Promise<number> to match other
drivers) and return a real rotation value instead of null: implement
PWMServoDriver.getRotation to read the servo's current state (from an existing
field such as this.rotation/this.currentAngle or by converting pulse width /
calling the internal read method like getPulseWidth()/readPWMPosition()) and
return a Rotation-shaped object (or numeric angle) wrapped in a resolved Promise
so the method matches other driver implementations.
| const shouldRobotCreate = onLaunch?.() ?? true | ||
| trace(`[main] onLaunch shouldRobotCreate=${shouldRobotCreate}\n`) | ||
| if (shouldRobotCreate) { | ||
| const robot = createRobot() | ||
| trace('[main] robot created\n') | ||
| onRobotCreated?.(robot, globalEnv.device) | ||
| trace('[main] onRobotCreated complete\n') |
There was a problem hiding this comment.
Await WASM hook calls to preserve StackchanMod hook semantics.
At Line 175 and Line 180, hooks are called synchronously. If either hook returns a Promise, shouldRobotCreate is mis-evaluated and async errors bypass this flow.
Proposed fix
if (config.wasm) {
trace('[main] WASM synchronous launch path\n')
const { onRobotCreated, onLaunch } = defaultMod
- const shouldRobotCreate = onLaunch?.() ?? true
+ const shouldRobotCreate = await (onLaunch?.() ?? true)
trace(`[main] onLaunch shouldRobotCreate=${shouldRobotCreate}\n`)
if (shouldRobotCreate) {
const robot = createRobot()
trace('[main] robot created\n')
- onRobotCreated?.(robot, globalEnv.device)
+ await onRobotCreated?.(robot, globalEnv.device)
trace('[main] onRobotCreated complete\n')
}
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const shouldRobotCreate = onLaunch?.() ?? true | |
| trace(`[main] onLaunch shouldRobotCreate=${shouldRobotCreate}\n`) | |
| if (shouldRobotCreate) { | |
| const robot = createRobot() | |
| trace('[main] robot created\n') | |
| onRobotCreated?.(robot, globalEnv.device) | |
| trace('[main] onRobotCreated complete\n') | |
| const shouldRobotCreate = await (onLaunch?.() ?? true) | |
| trace(`[main] onLaunch shouldRobotCreate=${shouldRobotCreate}\n`) | |
| if (shouldRobotCreate) { | |
| const robot = createRobot() | |
| trace('[main] robot created\n') | |
| await onRobotCreated?.(robot, globalEnv.device) | |
| trace('[main] onRobotCreated complete\n') |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/main.ts` around lines 175 - 181, The onLaunch and
onRobotCreated hooks are called synchronously but may return Promises, so await
their results to preserve StackchanMod hook semantics and allow async errors to
flow; change the call site to await onLaunch() when computing shouldRobotCreate
(e.g., const shouldRobotCreate = await onLaunch?.() ?? true) and await
onRobotCreated?.(robot, globalEnv.device) after createRobot() (or make the
surrounding function async) so both hook results are handled correctly and any
thrown/rejected errors are propagated.
| "*": [ | ||
| "./touch", | ||
| "./robot", | ||
| "./main" | ||
| ], |
There was a problem hiding this comment.
Fix Biome formatting for modules["*"] to unblock CI.
Line 15-Line 19 currently violates the formatter expectation reported by the pipeline.
Proposed fix
- "*": [
- "./touch",
- "./robot",
- "./main"
- ],
+ "*": ["./touch", "./robot", "./main"],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "*": [ | |
| "./touch", | |
| "./robot", | |
| "./main" | |
| ], | |
| "*": ["./touch", "./robot", "./main"], |
🧰 Tools
🪛 GitHub Actions: Build Stack-chan Firmware
[error] 13-19: Biome format failed for stackchan/manifest_wasm.json. Formatter would have changed "modules" entry for "" from a multi-line array to a single-line array: "": ["./touch", "./robot", "./main"].
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/manifest_wasm.json` around lines 15 - 19, The modules["*"]
array in manifest_wasm.json is mis-formatted for Biome; reformat the value of
modules["*"] to match the repository's JSON formatting style (one string per
line, properly indented, with commas placed/omitted as in the rest of the file)
so the file passes the Biome formatter; update the array entries for "./touch",
"./robot", and "./main" accordingly and run the Biome formatter (or commit the
exact formatting used elsewhere in the file) before pushing.
| constructor(_options) {} | ||
| async stream(_text, _volume) {} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether strict/noImplicitAny is enabled and confirm current untyped params.
fd -a 'tsconfig*.json' firmware --exec sh -c 'echo "=== $1 ==="; sed -n "1,220p" "$1"' sh {}
rg -n --no-heading 'constructor\(_options\)|stream\(_text, _volume\)' firmware/stackchan/speeches/wasm/tts-stub.tsRepository: stack-chan/stack-chan
Length of output: 4389
🏁 Script executed:
# Find other WASM TTS stub or similar files to check parameter typing patterns
fd -type f 'tts.*\.ts' firmware/stackchan/speeches/wasm/ | head -20
rg -l 'class TTS|export class.*TTS' firmware/stackchan/speeches/ -A 3 | head -20Repository: stack-chan/stack-chan
Length of output: 855
🏁 Script executed:
# Check parameter signatures in the WASM TTS files
for file in firmware/stackchan/speeches/wasm/tts-{stub,voicevox,elevenlabs,remote,openai,local}.ts; do
if [ -f "$file" ]; then
echo "=== $file ==="
rg -A 1 'constructor|stream.*\(' "$file" | head -20
fi
doneRepository: stack-chan/stack-chan
Length of output: 986
Match parameter types with other WASM TTS implementations in this PR.
At Line 2 and Line 3, the untyped parameters are inconsistent with all other WASM TTS implementations (tts-voicevox.ts, tts-elevenlabs.ts, tts-remote.ts, tts-openai.ts, tts-local.ts), which use explicit types.
💡 Proposed fix
export class TTS {
- constructor(_options) {}
- async stream(_text, _volume) {}
+ constructor(_options?: unknown) {}
+ async stream(_text: string, _volume?: number): Promise<void> {}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| constructor(_options) {} | |
| async stream(_text, _volume) {} | |
| export class TTS { | |
| constructor(_options?: unknown) {} | |
| async stream(_text: string, _volume?: number): Promise<void> {} | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/speeches/wasm/tts-stub.ts` around lines 2 - 3, The
constructor and stream method in this WASM TTS stub use untyped parameters;
change their signatures to match the explicit types used in the other WASM TTS
implementations (e.g., tts-voicevox.ts, tts-elevenlabs.ts, tts-remote.ts,
tts-openai.ts, tts-local.ts). Specifically, update constructor(_options) to
constructor(options: /* same options type used by the other WASM TTS classes */)
and update async stream(_text, _volume) to async stream(text: string, volume?:
number): /* same return type as other WASM TTS stream methods */ so the
parameter names, types, and return type match the rest of the implementations.
| @@ -0,0 +1,7 @@ | |||
| export default class Microphone { | |||
| constructor(_options?: unknown) {} | |||
| async record(): Promise<ArrayBuffer> { | |||
There was a problem hiding this comment.
Preserve record(durationMilliSec?) API compatibility.
Line 3 drops the optional duration parameter used by the non-WASM microphone API. This can cause TS call-site mismatch in shared code paths.
Suggested fix
- async record(): Promise<ArrayBuffer> {
+ async record(_durationMilliSec = 3000): Promise<ArrayBuffer> {
return new ArrayBuffer(0)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async record(): Promise<ArrayBuffer> { | |
| async record(_durationMilliSec = 3000): Promise<ArrayBuffer> { | |
| return new ArrayBuffer(0) | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@firmware/stackchan/wasm/microphone.ts` at line 3, Restore the original
optional parameter on the microphone API by changing the record function
signature back to record(durationMilliSec?: number): Promise<ArrayBuffer> (i.e.,
accept an optional durationMilliSec parameter), keep existing internal WASM
logic unchanged but consume or ignore durationMilliSec as appropriate (e.g.,
pass it into the WASM call or use it to set a timeout/default), and ensure
callers remain compatible with non-WASM code paths; update the record method
declaration in microphone.ts accordingly so TypeScript call-sites don’t break.
Summary
Verification
/.local/share/moddable + emsdk 3.1.2 + FONTBM=/.local/bin/fontbm npm run build:wasmStacked follow-up will wire these artifacts into the deployed web page.
Do not merge yet; stacked CI deploy PR will target this branch.
Summary by CodeRabbit
New Features
Chores
Stability