Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
900da7a
Move springboard dev to single-port ModuleRunner
Feb 25, 2026
24883d9
Add midi_files_module to @jamtools/core package exports
Feb 26, 2026
4e02efa
Refactor io_module to use separate .browser.ts and .node.ts files
Feb 26, 2026
e0366d8
Use package.json export conditions for platform-specific io_dependencies
Feb 27, 2026
5786193
Fix ES module import reassignment in io_module for Vite dev mode
Feb 27, 2026
48723f5
Fix @tonejs/midi import to use default import with type import
Feb 27, 2026
51fe57e
Fix dev plugin stream and module-graph typings
Mar 22, 2026
c6b22d8
Add e2e dev-route HMR test for registerServerModule
Mar 22, 2026
ac6c546
docs: clarify registerServerModule contract
Mar 25, 2026
76d916a
apps/vite-test: add start script and configurable port
Mar 25, 2026
b2a694f
Committed the two requested files as `apps/vite-test: add start scrip…
Mar 25, 2026
1543cb5
apps/vite-test: add debug log for module load
Mar 25, 2026
2335c8e
fix: use single-port dev server in vite plugin
Mar 25, 2026
b3b9628
fix: install vite dev middleware before spa fallback
Mar 25, 2026
6a8c1c4
refactor: remove unused vite plugin modules
Mar 25, 2026
c44e8be
Committed the deletions as `refactor: remove unused vite plugin modul…
Mar 25, 2026
98cb178
refactor: store generated vite files in node_modules
Mar 25, 2026
8fb45c6
edit scripts
Mar 25, 2026
1616cba
fix: serve dev web entry through vite transform
Mar 25, 2026
b7b6ea0
fix: stop forcing localhost npm registry in ci
May 12, 2026
94e21c4
Merge branch 'preview-pr-70-vk-8100-fix-vite-dev-nod' into vk/e1e4-co…
Jun 6, 2026
6db3543
Improve Springboard agent docs
Jun 6, 2026
32c43a1
Fix springboard reset preserving registered modules
Jun 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
registry=http://localhost:4873/

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove localhost registry override from repo config

Committing a root .npmrc with registry=http://localhost:4873/ forces all package installs/publishes in this repo to use a local Verdaccio instance. In normal developer/CI environments where Verdaccio is not running, dependency resolution will fail outright, making the repository unusable without extra local setup.

Useful? React with 👍 / 👎.

//localhost:4873/:_authToken=fake

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove hardcoded localhost registry from root npmrc

This root .npmrc forces registry=http://localhost:4873/ for the entire repo, which makes installs and publishes depend on a locally running Verdaccio instance. In CI or any developer environment without that service, package resolution will fail against localhost and standard dependency workflows break by default.

Useful? React with 👍 / 👎.

16 changes: 16 additions & 0 deletions packages/jamtools/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@
"types": "./dist/modules/midi_files/midi_file_parser/midi_file_parser.d.ts",
"import": "./dist/modules/midi_files/midi_file_parser/midi_file_parser.js"
},
"./modules/midi_files/midi_files_module": {
"types": "./dist/modules/midi_files/midi_files_module.d.ts",
"import": "./dist/modules/midi_files/midi_files_module.js"
},
"./modules/io/io_dependencies": {
"types": "./dist/modules/io/io_dependencies_types.d.ts",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Export io_dependencies types from declaration with value

The ./modules/io/io_dependencies export maps types to io_dependencies_types.d.ts, which defines only type aliases and does not declare the createIoDependencies value export that the runtime files provide. TypeScript consumers importing createIoDependencies from this subpath will get missing-export type errors even though the JS export exists.

Useful? React with 👍 / 👎.

"node": {
"import": "./dist/modules/io/io_dependencies.node.js"
},
"browser": {
"import": "./dist/modules/io/io_dependencies.browser.js"
},
"default": {
"import": "./dist/modules/io/io_dependencies.js"
}
},
"./modules/macro_module/registered_macro_types": {
"types": "./dist/modules/macro_module/registered_macro_types.d.ts",
"import": "./dist/modules/macro_module/registered_macro_types.js"
Expand Down
12 changes: 12 additions & 0 deletions packages/jamtools/core/src/modules/io/io_dependencies.browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {BrowserQwertyService} from '@jamtools/core/services/browser/browser_qwerty_service';
import {BrowserMidiService} from '@jamtools/core/services/browser/browser_midi_service';
import type {IoDeps} from './io_dependencies_types';

export const createIoDependencies = async (): Promise<IoDeps> => {
const qwerty = new BrowserQwertyService(document);
const midi = new BrowserMidiService();
return {
qwerty,
midi,
};
};
21 changes: 21 additions & 0 deletions packages/jamtools/core/src/modules/io/io_dependencies.node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {NodeQwertyService} from '@jamtools/core/services/node/node_qwerty_service';
import {NodeMidiService} from '@jamtools/core/services/node/node_midi_service';
import {MockMidiService} from '@jamtools/core/test/services/mock_midi_service';
import {MockQwertyService} from '@jamtools/core/test/services/mock_qwerty_service';
import type {IoDeps} from './io_dependencies_types';

export const createIoDependencies = async (): Promise<IoDeps> => {
if (process.env.DISABLE_IO === 'true') {
return {
qwerty: new MockQwertyService(),
midi: new MockMidiService(),
};
}

const qwerty = new NodeQwertyService();
const midi = new NodeMidiService();
return {
qwerty,
midi,
};
};
11 changes: 11 additions & 0 deletions packages/jamtools/core/src/modules/io/io_dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {MockMidiService} from '@jamtools/core/test/services/mock_midi_service';
import {MockQwertyService} from '@jamtools/core/test/services/mock_qwerty_service';
import type {IoDeps} from './io_dependencies_types';

// Default implementation for testing
export const createIoDependencies = async (): Promise<IoDeps> => {
return {
qwerty: new MockQwertyService(),
midi: new MockMidiService(),
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {MidiService, QwertyService} from '@jamtools/core/types/io_types';

export type IoDeps = {
midi: MidiService;
qwerty: QwertyService;
}

export type CreateIoDependencies = () => Promise<IoDeps>;
60 changes: 9 additions & 51 deletions packages/jamtools/core/src/modules/io/io_module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,18 @@ import springboard from 'springboard';
import {StateSupervisor} from 'springboard/services/states/shared_state_service';
import {ModuleAPI} from 'springboard/engine/module_api';
import {MidiEvent} from '@jamtools/core/modules/macro_module/macro_module_types';
import {MockMidiService} from '@jamtools/core/test/services/mock_midi_service';
import {MockQwertyService} from '@jamtools/core/test/services/mock_qwerty_service';

import {MidiService, QwertyService} from '@jamtools/core/types/io_types';
import type {IoDeps, CreateIoDependencies} from './io_dependencies_types';
import {createIoDependencies as defaultCreateIoDependencies} from './io_dependencies';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore platform-specific IO dependency loading

IoModule now imports createIoDependencies from ./io_dependencies, but that file is the test fallback that always returns MockQwertyService/MockMidiService. Because this is a relative import, Node/browser conditional exports are not applied, so production builds will never instantiate the real browser/node IO services unless tests manually override the creator.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Because this is a relative import, Node/browser conditional exports are not applied

@codex Are you sure this is true?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Route IO dependency import through package exports

Because io_module.tsx imports ./io_dependencies via a relative specifier, the resolver never consults the package.json conditional exports you added for ./modules/io/io_dependencies. As a result, browser and node runtimes both load io_dependencies.ts (the mock implementation) instead of the .browser/.node variants, so real MIDI/QWERTY services are never initialized unless tests manually override the creator.

Useful? React with 👍 / 👎.


type IoDeps = {
midi: MidiService;
qwerty: QwertyService;
}

let createIoDependencies = async (): Promise<IoDeps> => {
return {
qwerty: new MockQwertyService(),
midi: new MockMidiService(),
};
};

// @platform "browser"
createIoDependencies = async () => {
const {BrowserQwertyService} = await import('@jamtools/core/services/browser/browser_qwerty_service');
const {BrowserMidiService} = await import('@jamtools/core/services/browser/browser_midi_service');

const qwerty = new BrowserQwertyService(document);
const midi = new BrowserMidiService();
return {
qwerty,
midi,
};
};
// @platform end

// @platform "node"
createIoDependencies = async () => {
if (process.env.DISABLE_IO === 'true') {
return {
qwerty: new MockQwertyService(),
midi: new MockMidiService(),
};
}

const {NodeQwertyService} = await import('@jamtools/core/services/node/node_qwerty_service');
const {NodeMidiService} = await import('@jamtools/core/services/node/node_midi_service');

const qwerty = new NodeQwertyService();
const midi = new NodeMidiService();
return {
qwerty,
midi,
};
// Wrapper object to allow mutation for testing
const ioDepsConfig = {
createIoDependencies: defaultCreateIoDependencies
};
// @platform end

export const setIoDependencyCreator = (func: typeof createIoDependencies) => {
createIoDependencies = func;
export const setIoDependencyCreator = (func: CreateIoDependencies) => {
// This is used for testing to override the platform-specific implementation
ioDepsConfig.createIoDependencies = func;
};

type IoState = {
Expand Down Expand Up @@ -120,7 +78,7 @@ export class IoModule implements Module<IoState> {
};

initialize = async (moduleAPI: ModuleAPI) => {
this.ioDeps = await createIoDependencies();
this.ioDeps = await ioDepsConfig.createIoDependencies();

this.qwertyInputSubject = this.ioDeps.qwerty.onInputEvent;
this.midiInputSubject = this.ioDeps.midi.onInputEvent;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import midi from 'midi-file';

import {Midi} from '@tonejs/midi';
import tonejs from '@tonejs/midi';
import type {Midi} from '@tonejs/midi';
const {Midi: MidiClass} = tonejs;

type SustainedNote = {
midiNumber: number;
Expand All @@ -19,7 +21,7 @@ export type ParsedMidiFile = {

export class MidiFileParser {
parseWithTonejsMidiBuffer = (input: Buffer) => {
const parsed = new Midi(input);
const parsed = new MidiClass(input);
return this.parseWithTonejsMidiData(parsed);
};

Expand Down
4 changes: 4 additions & 0 deletions packages/springboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
"types": "./dist/platforms/browser/services/browser_kvstore_service.d.ts",
"import": "./dist/platforms/browser/services/browser_kvstore_service.js"
},
"./platforms/browser/services/browser_session_kvstore_service": {
"types": "./dist/platforms/browser/services/browser_session_kvstore_service.d.ts",
"import": "./dist/platforms/browser/services/browser_session_kvstore_service.js"
},
"./platforms/cloudflare-workers/entrypoints/cloudflare_entrypoint": {
"types": "./dist/platforms/cloudflare-workers/entrypoints/cloudflare_entrypoint.d.ts",
"import": "./dist/platforms/cloudflare-workers/entrypoints/cloudflare_entrypoint.js"
Expand Down
2 changes: 1 addition & 1 deletion packages/springboard/vite-plugin/src/plugins/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export function springboardDev(options: NormalizedOptions): Plugin {

// Check if the changed file is within the project root (excludes node_modules, etc.)
// and is not a generated file (excludes .springboard/, dist/, etc.)
const isUserCode = isNodePlatformActive &&
const isUserCode = hasNode &&
file.startsWith(options.root) &&
!file.includes(path.sep + 'node_modules' + path.sep) &&
!file.includes(path.sep + '.springboard' + path.sep) &&
Expand Down
1 change: 1 addition & 0 deletions scripts/run-all-folders.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ publish_package() {
environment="npm"
else
export NPM_CONFIG_REGISTRY="http://localhost:4873"
# export NPM_CONFIG_REGISTRY="http://10.0.1.1:4873"
environment="local Verdaccio"
fi

Expand Down
4 changes: 2 additions & 2 deletions verdaccio/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
verdaccio:
image: verdaccio/verdaccio
container_name: 'verdaccio'
network_mode: 'host'
# network_mode: 'host'
# networks:
# - verdaccio-network
environment:
Expand All @@ -17,4 +17,4 @@ services:
- './plugins:/verdaccio/plugins'
# networks:
# verdaccio-network:
# external: true
# external: true
19 changes: 19 additions & 0 deletions verdaccio/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# export BASE_PATH="/var/lib/docker/volumes/dowo0cwkww0swc0kg0wgw44k_vibe-kanban-worktrees/_data/e1e4-copy-jamtools-fe/springboard/verdaccio"
# VERDACCIO_CONFIG_PATH="$BASE_PATH/config" \
# VERDACCIO_STORAGE_PATH="$BASE_PATH/storage" \
# VERDACCIO_PLUGINS_PATH="$BASE_PATH/plugins" \
# docker compose up

echo "registry=http://localhost:4873/" >> ../.npmrc
echo "//localhost:4873/:_authToken=fake" >> ../.npmrc

npx verdaccio --config ./config/config.yaml

# curl -L -o $HOME/bin/jq https://github.com/jqlang/jq/releases/latest/download/jq-linux64
# chmod +x "$HOME/bin/jq"
# export PATH=$PATH:$HOME/bin

# export npm_config__authToken=fake
# export npm_config_registry=http://localhost:4873/
# ./scripts/run-all-folders.sh 0.0.1-dev-jamapp-3

Loading