Skip to content

feat(blocks): add text2speech/translate/videoSensing block factories - #153

Closed
nakasyou wants to merge 1 commit into
mainfrom
codex/resolve-issue-151
Closed

feat(blocks): add text2speech/translate/videoSensing block factories#153
nakasyou wants to merge 1 commit into
mainfrom
codex/resolve-issue-151

Conversation

@nakasyou

Copy link
Copy Markdown
Member

Motivation

  • Provide built-in block factories for several Scratch default extensions so Hikkaku can emit the corresponding extension opcodes and be used by higher-level tools and tests.
  • Improve test coverage and documentation generation for these extension-like blocks.

Description

  • Add packages/hikkaku/src/blocks/text2speech.ts, translate.ts, and videosensing.ts providing block factories for text2speech_*, translate_*, and videoSensing_* opcodes respectively.
  • Add focused unit tests text2speech.test.ts, translate.test.ts, and videosensing.test.ts that assert the expected opcodes are emitted when blocks are composed.
  • Export the new modules from packages/hikkaku/src/blocks/index.ts so they are available from the public blocks entrypoint.
  • Use type-friendly signatures (PrimitiveSource<HikkakuString> / PrimitiveSource<HikkakuNumber>) to satisfy existing HikkakuType constraints and avoid unconnected value-block test errors.

Testing

  • Ran bun fmt to apply formatting and fixes (successful).
  • Ran bun run typecheck && bun run test in packages/hikkaku, and all tests passed (50 tests across 27 files).
  • Ran bun ref:build to update reference docs (successful); note that a full repo-level bun typecheck previously failed in this environment because moon is not installed when building packages/moonscratch, which is environment-specific and unrelated to these package changes.

Codex Task

…locks

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 27, 2026 13:17
@codecov

codecov Bot commented Apr 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #153      +/-   ##
==========================================
+ Coverage   80.72%   80.80%   +0.08%     
==========================================
  Files          50       53       +3     
  Lines        4083     4101      +18     
  Branches      590      590              
==========================================
+ Hits         3296     3314      +18     
  Misses        549      549              
  Partials      238      238              
Flag Coverage Δ
tests 80.80% <100.00%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/hikkaku/src/blocks/text2speech.ts 100.00% <100.00%> (ø)
packages/hikkaku/src/blocks/translate.ts 100.00% <100.00%> (ø)
packages/hikkaku/src/blocks/videosensing.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@nakasyou

Copy link
Copy Markdown
Member Author

@Kicky1618 review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class block factory helpers for several Scratch “default extension” opcodes (Text to Speech, Translate, Video Sensing) so hikkaku/blocks can emit those blocks directly and so they’re covered by unit tests and docs generation.

Changes:

  • Added new block factory modules: text2speech, translate, videosensing
  • Added unit tests asserting the expected extension opcodes are emitted
  • Re-exported the new modules from the public blocks entrypoint

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/hikkaku/src/blocks/videosensing.ts Implements Video Sensing block factories (including a hat-like block).
packages/hikkaku/src/blocks/videosensing.test.ts Verifies Video Sensing opcodes appear in composed block output.
packages/hikkaku/src/blocks/translate.ts Implements Translate reporter block factories.
packages/hikkaku/src/blocks/translate.test.ts Verifies Translate opcodes appear in composed block output.
packages/hikkaku/src/blocks/text2speech.ts Implements Text to Speech statement block factories.
packages/hikkaku/src/blocks/text2speech.test.ts Verifies Text to Speech opcodes appear in composed block output.
packages/hikkaku/src/blocks/index.ts Exposes the new modules via the public hikkaku/blocks entrypoint.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6 to +15
export const translate = (
words: PrimitiveSource<HikkakuString>,
language: PrimitiveSource<HikkakuString>,
) => {
return valueBlock<HikkakuString>('translate_getTranslate', {
inputs: {
WORDS: fromPrimitiveSource(InputType.String, words, 'hello'),
LANGUAGE: fromPrimitiveSource(InputType.String, language, 'ja'),
},
})

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

translate_getTranslate’s LANGUAGE argument is typically a dropdown/menu in Scratch, but here it’s represented as a plain string input. Elsewhere, dropdowns are modeled as fields or menuInput with a shadow menu block (e.g. sensing_keypressed). Consider aligning with that approach so generated SB3 retains expected menu/shadow structure and callers get clearer intent.

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +16
export const translate = (
words: PrimitiveSource<HikkakuString>,
language: PrimitiveSource<HikkakuString>,
) => {
return valueBlock<HikkakuString>('translate_getTranslate', {
inputs: {
WORDS: fromPrimitiveSource(InputType.String, words, 'hello'),
LANGUAGE: fromPrimitiveSource(InputType.String, language, 'ja'),
},
})
}

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new module’s public exports are missing JSDoc comments, while most existing block factories in this directory include structured JSDoc used for reference docs/examples (see blocks/looks.ts, blocks/music.ts, etc.). Adding doc comments here would keep the generated docs consistent with the rest of the blocks API.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +22
export const whenMotionGreaterThan = (
reference: PrimitiveSource<HikkakuNumber>,
) => {
return block('videoSensing_whenMotionGreaterThan', {
inputs: {
REFERENCE: fromPrimitiveSource(InputType.Number, reference, 10),
},
})
}

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new module adds public block factories but does not include the JSDoc-style documentation used throughout packages/hikkaku/src/blocks (inputs/outputs + @example). Since the PR mentions documentation generation, consider adding JSDoc for these exports to match the rest of the blocks API.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +21
export const whenMotionGreaterThan = (
reference: PrimitiveSource<HikkakuNumber>,
) => {
return block('videoSensing_whenMotionGreaterThan', {
inputs: {
REFERENCE: fromPrimitiveSource(InputType.Number, reference, 10),
},
})

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

videoSensing_whenMotionGreaterThan is a hat block in Scratch, but this factory creates it as a normal statement (no topLevel: true and no stack attachment). This can lead to invalid scripts (hat blocks chained under another block) and prevents the block from being used like other hat helpers (e.g. whenFlagClicked). Consider adding topLevel: true and an optional stack?: () => void parameter using attachStack (as done in blocks/events.ts).

Copilot uses AI. Check for mistakes.
Comment on lines +25 to +31
attribute: PrimitiveSource<HikkakuString>,
subject: PrimitiveSource<HikkakuString>,
) => {
return valueBlock<HikkakuNumber>('videoSensing_videoOn', {
inputs: {
ATTRIBUTE: fromPrimitiveSource(InputType.String, attribute, 'motion'),
SUBJECT: fromPrimitiveSource(InputType.String, subject, 'this sprite'),

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These dropdown-like parameters (ATTRIBUTE, SUBJECT) are currently encoded as plain string inputs via fromPrimitiveSource. Elsewhere in this codebase, menu/dropdown inputs are typically modeled with menuInput(...) + a shadow menu reporter block (see sensing.getKeyPressed / menuOfKeyOptions) or as fields when the value is a true field. Encoding this as a primitive string input may lose the expected menu shadow block / UI semantics in generated SB3. Consider switching to a menu helper (or fields) consistent with other dropdowns.

Suggested change
attribute: PrimitiveSource<HikkakuString>,
subject: PrimitiveSource<HikkakuString>,
) => {
return valueBlock<HikkakuNumber>('videoSensing_videoOn', {
inputs: {
ATTRIBUTE: fromPrimitiveSource(InputType.String, attribute, 'motion'),
SUBJECT: fromPrimitiveSource(InputType.String, subject, 'this sprite'),
attribute: VideoSensingAttribute,
subject: VideoSensingSubject,
) => {
return valueBlock<HikkakuNumber>('videoSensing_videoOn', {
fields: {
ATTRIBUTE: [attribute, null],
SUBJECT: [subject, null],

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +39
export const videoToggle = (state: PrimitiveSource<HikkakuString>) => {
return block('videoSensing_videoToggle', {
inputs: {
VIDEO_STATE: fromPrimitiveSource(InputType.String, state, 'on'),

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VIDEO_STATE is a dropdown in Scratch, but it is currently represented as a generic string input. To match other dropdown/menu patterns in this repo (and Scratch’s SB3 structure), consider modeling this as fields: { VIDEO_STATE: [...] } or via menuInput + a shadow menu reporter block, rather than fromPrimitiveSource(InputType.String, ...).

Suggested change
export const videoToggle = (state: PrimitiveSource<HikkakuString>) => {
return block('videoSensing_videoToggle', {
inputs: {
VIDEO_STATE: fromPrimitiveSource(InputType.String, state, 'on'),
export const videoToggle = (state: VideoState) => {
return block('videoSensing_videoToggle', {
fields: {
VIDEO_STATE: [state, null],

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +19
export const speakAndWait = (words: PrimitiveSource<HikkakuString>) => {
return block('text2speech_speakAndWait', {
inputs: {
WORDS: fromPrimitiveSource(InputType.String, words, 'hello'),
},
})

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exported block factories in this new module are missing the JSDoc pattern used across packages/hikkaku/src/blocks (description, inputs/outputs, @example, etc.), which is likely important for the reference doc generation mentioned in the PR description. Consider adding doc comments for the public exports (similar to music.ts / looks.ts) so generated docs remain consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +27
export const setVoice = (voice: PrimitiveSource<HikkakuString>) => {
return block('text2speech_setVoice', {
inputs: {
VOICE: fromPrimitiveSource(InputType.String, voice, 'ALTO'),
},
})

Copilot AI Apr 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextToSpeechVoice is declared, but setVoice accepts PrimitiveSource<HikkakuString> and encodes VOICE as a generic string input. If this block is meant to reflect Scratch’s voice dropdown, consider using the TextToSpeechVoice type in the API (and encoding as a dropdown via fields or menuInput + a shadow menu block) so callers get type safety and the generated SB3 better matches Scratch semantics.

Copilot uses AI. Check for mistakes.
@nakasyou nakasyou closed this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants