diff --git a/AGENTS.md b/AGENTS.md index 1bac1cd..76a4b3c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,7 +11,8 @@ - `bun install`: install JS dependencies (Bun is the preferred runtime). - `./mill agent.compile` or `bun run build`: compile the Scala.js library. - `./mill agent.test`: run the MUnit test suite. -- `./mill examples.run`: run the default example; use `EXAMPLE=simple ./mill examples.run` for a specific example. +- `./mill examples.run`: run the default example. +- `./mill examples.simple.run`: run a specific example by submodule, e.g. `./mill examples.hook.run`. - `bun run run`: compile and execute the JS output for examples. - `./mill examples.list`: list available example entry points. @@ -34,5 +35,4 @@ motivation or linked issue, and the commands you ran (e.g. `./mill agent.test`). examples when public APIs or usage patterns change. ## Configuration & Runtime Notes -Runtime examples require `ANTHROPIC_API_KEY`. Prefer Bun for JS tasks (`bun run ...`) rather than -npm/node. +Runtime examples require `ANTHROPIC_API_KEY`. When running inside Claude Code, auth is typically handled automatically; setting `ANTHROPIC_API_KEY` remains an optional override. Prefer Bun for JS tasks (`bun run ...`) rather than npm/node. diff --git a/build.mill b/build.mill index 252cc60..c5f13bd 100644 --- a/build.mill +++ b/build.mill @@ -5,15 +5,208 @@ import mill.scalajslib.api.* import publish.* import mainargs.arg -// Main library module - sources in /src -object agent extends ScalaJSModule with PublishModule { +// --------------------------------------------------------------------------- +// BunModule — Use Bun as the Scala.js runtime +// --------------------------------------------------------------------------- +// Will be extracted to a separate mill-scalajs-bun plugin repo once validated. +// See: https://github.com/TJC-LP/scalagent/issues/26 + +trait BunModule extends ScalaJSModule { + + /** Path to the bun executable. */ + def bunExecutable: T[String] = Task { "bun" } + + /** Additional args passed to bun before the script path. */ + def bunArgs: T[Seq[String]] = Task { Seq.empty[String] } + + /** Additional environment variables for bun execution. */ + def bunEnv: T[Map[String, String]] = Task { Map.empty[String, String] } + + /** + * JSEnv config using NodeJs compat with Bun. + * Bun supports require('net') so the Scala.js test adapter's TCP com protocol works. + * sourceMap=false because Bun has native source map support. + */ + override def jsEnvConfig: T[JsEnvConfig] = Task { + JsEnvConfig.NodeJs( + executable = bunExecutable(), + args = bunArgs().toList, + env = bunEnv(), + sourceMap = false + ) + } + + /** Run the linked JS output with Bun directly, bypassing the JSEnv framework. */ + override def run(args: Task[Args] = Task.Anon(Args())): Command[Unit] = Task.Command { + finalMainClassOpt() match { + case Left(err) => Task.fail(err) + case Right(_) => + val linked = fastLinkJS() + val jsFile = linked.dest.path / linked.publicModules.head.jsFileName + val cmd = Seq(bunExecutable()) ++ bunArgs() ++ Seq(jsFile.toString) ++ args().value + os.proc(cmd).call( + stdin = os.Inherit, + stdout = os.Inherit, + stderr = os.Inherit, + env = bunEnv() + ) + () + } + } +} + +// --------------------------------------------------------------------------- +// BunNpmModule — Declare npm dependencies in build.mill +// --------------------------------------------------------------------------- + +trait BunNpmModule extends BunModule { outer => + + /** NPM dependencies: package name -> version spec. */ + def npmDeps: T[Map[String, String]] = Task { Map.empty[String, String] } + + /** NPM dev dependencies. */ + def npmDevDeps: T[Map[String, String]] = Task { Map.empty[String, String] } + + /** NPM peer dependencies. */ + def npmPeerDeps: T[Map[String, String]] = Task { Map.empty[String, String] } + + /** Whether to use ESM ("module" type) in package.json. */ + def npmModuleType: T[Boolean] = Task { true } + + /** Project root for bun.lock resolution and IDE tooling. */ + def npmProjectDir: T[os.Path] = Task { moduleDir } + + /** bun.lock file for reproducible installs. Declared as Source so Mill allows reading it. */ + def bunLockFile: T[PathRef] = Task.Source(moduleDir / "bun.lock") + + /** Generate package.json content from declared dependencies. */ + def packageJsonContent: T[ujson.Value] = Task { + val obj = ujson.Obj( + "private" -> true, + "dependencies" -> ujson.Obj.from( + npmDeps().toSeq.sortBy(_._1).map { case (k, v) => k -> ujson.Str(v) } + ), + "devDependencies" -> ujson.Obj.from( + npmDevDeps().toSeq.sortBy(_._1).map { case (k, v) => k -> ujson.Str(v) } + ) + ) + if (npmModuleType()) obj("type") = "module" + val peers = npmPeerDeps() + if (peers.nonEmpty) + obj("peerDependencies") = ujson.Obj.from( + peers.toSeq.sortBy(_._1).map { case (k, v) => k -> ujson.Str(v) } + ) + obj + } + + /** + * Generate package.json in Task.dest, copy bun.lock if present, and run + * bun install. Returns PathRef to the install directory (contains node_modules). + * Follows Mill convention: Tasks only write to Task.dest. + */ + def bunInstall: T[PathRef] = Task { + val dest = Task.dest + + // Generate package.json in Task.dest + val content = ujson.write(packageJsonContent(), indent = 2) + "\n" + os.write.over(dest / "package.json", content) + + // Copy bun.lock from project root if it exists (for reproducible installs) + val lockSrc = bunLockFile().path + if (os.exists(lockSrc)) os.copy.over(lockSrc, dest / "bun.lock") + + os.proc(bunExecutable(), "install") + .call(cwd = dest, stdout = os.Inherit, stderr = os.Inherit) + + PathRef(dest) + } + + /** Path to node_modules from bunInstall. */ + def nodeModulesPath: T[os.Path] = Task { bunInstall().path / "node_modules" } + + /** Check for outdated npm packages. */ + def bunOutdated() = Task.Command { + val dest = bunInstall().path + os.proc(bunExecutable(), "outdated") + .call(cwd = dest, stdout = os.Inherit, stderr = os.Inherit) + } + + /** Generate package.json to project root for IDE/TypeScript LSP compatibility. */ + def generatePackageJson() = Task.Command { + val dir = npmProjectDir() + val content = ujson.write(packageJsonContent(), indent = 2) + "\n" + os.write.over(dir / "package.json", content) + println(s"Generated package.json in $dir from build.mill declarations") + } + + /** Override run to ensure bun install happens first and NODE_PATH is set. */ + override def run(args: Task[Args] = Task.Anon(Args())): Command[Unit] = Task.Command { + finalMainClassOpt() match { + case Left(err) => Task.fail(err) + case Right(_) => + val nmPath = nodeModulesPath() + val linked = fastLinkJS() + val jsFile = linked.dest.path / linked.publicModules.head.jsFileName + val cmd = Seq(bunExecutable()) ++ bunArgs() ++ Seq(jsFile.toString) ++ args().value + os.proc(cmd).call( + stdin = os.Inherit, + stdout = os.Inherit, + stderr = os.Inherit, + env = bunEnv() ++ Map("NODE_PATH" -> nmPath.toString) + ) + () + } + } + + /** Test module that inherits npm deps from the parent. + * Tests use Node.js for the JSEnv test adapter — the adapter pipes JS to + * stdin and uses a TCP com protocol that requires Node.js's stdin behavior. + * Bun doesn't read from stdin without explicit flags, so Node is used here. + * The `run` task still uses Bun for all runtime execution. + */ + trait BunNpmTests extends ScalaJSTests with BunNpmModule { + override def npmDeps = outer.npmDeps + override def npmDevDeps = outer.npmDevDeps + override def npmPeerDeps = outer.npmPeerDeps + override def npmProjectDir = outer.npmProjectDir + + // Use Node.js for the test adapter's stdin/com protocol + override def jsEnvConfig: T[JsEnvConfig] = Task { + JsEnvConfig.NodeJs() + } + } +} + +// --------------------------------------------------------------------------- +// Main library module — sources in /src +// --------------------------------------------------------------------------- + +object agent extends ScalaJSModule with PublishModule with BunNpmModule { def scalaVersion = "3.7.4" def scalaJSVersion = "1.20.1" // Scala.js linker configuration override def moduleKind = ModuleKind.ESModule - // Dependencies + // NPM dependencies — single source of truth (replaces package.json) + override def npmDeps = Task { Map( + "@anthropic-ai/claude-agent-sdk" -> "^0.2.78", + "@a2a-js/sdk" -> "^0.3.12", + "zod" -> "^4.0.0" + )} + + override def npmDevDeps = Task { Map( + "@types/bun" -> "^1.3.5" + )} + + override def npmPeerDeps = Task { Map( + "typescript" -> "^5.9.3" + )} + + // Project root for bun.lock and IDE tooling + override def npmProjectDir = Task { build.moduleDir } + + // Scala/Maven dependencies def mvnDeps = Seq( mvn"dev.zio::zio::2.1.24", mvn"dev.zio::zio-streams::2.1.24", @@ -56,28 +249,27 @@ object agent extends ScalaJSModule with PublishModule { def artifactName = "scalagent" // Test module - object test extends ScalaJSTests with TestModule.Munit { + object test extends BunNpmTests with TestModule.Munit { def munitVersion = "1.1.0" } } +// --------------------------------------------------------------------------- // Example application module -// Run examples with: ./mill examples.run -// List examples with: ./mill examples.list -object examples extends ScalaJSModule { +// --------------------------------------------------------------------------- + +trait ExampleModule extends BunNpmModule { def scalaVersion = agent.scalaVersion def scalaJSVersion = agent.scalaJSVersion override def moduleKind = ModuleKind.ESModule override def moduleDeps = Seq(agent) - // Use Bun instead of Node.js for running examples - override def jsEnvConfig = Task { - JsEnvConfig.NodeJs( - executable = "bun", - args = Nil - ) - } + // Inherit npm deps from agent + override def npmDeps = agent.npmDeps + override def npmDevDeps = agent.npmDevDeps + override def npmPeerDeps = agent.npmPeerDeps + override def npmProjectDir = agent.npmProjectDir def mvnDeps = Seq( mvn"dev.zio::zio::2.1.24", @@ -88,67 +280,95 @@ object examples extends ScalaJSModule { override def moduleDir = build.moduleDir override def sources = Task.Sources(moduleDir / "examples") + def exampleMainClass: String + + override def mainClass = Task { Some(exampleMainClass) } +} + +object examples extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.MacroToolExample" + // Available examples - add new ones here - val exampleClasses = Map( - "simple" -> "com.tjclp.scalagent.examples.SimpleQuery", - "macro" -> "com.tjclp.scalagent.examples.MacroToolExample", - "custom" -> "com.tjclp.scalagent.examples.CustomToolExample", - "hook" -> "com.tjclp.scalagent.examples.HookExample", - "permission" -> "com.tjclp.scalagent.examples.PermissionExample", - "session" -> "com.tjclp.scalagent.examples.SessionExample", - // New examples for recent features - "structured" -> "com.tjclp.scalagent.examples.StructuredOutputExample", - "subagent" -> "com.tjclp.scalagent.examples.SubagentExample", - "plugin" -> "com.tjclp.scalagent.examples.PluginExample", - "prompt" -> "com.tjclp.scalagent.examples.SystemPromptExample", - "command" -> "com.tjclp.scalagent.examples.SlashCommandExample", - "a2a" -> "com.tjclp.scalagent.examples.A2AExample", - "agent-hooks" -> "com.tjclp.scalagent.examples.AgentHooksExample" + val exampleCommands = Map( + "simple" -> "examples.simple.run", + "macro" -> "examples.run", + "custom" -> "examples.custom.run", + "hook" -> "examples.hook.run", + "permission" -> "examples.permission.run", + "session" -> "examples.session.run", + "structured" -> "examples.structured.run", + "subagent" -> "examples.subagent.run", + "plugin" -> "examples.plugin.run", + "prompt" -> "examples.prompt.run", + "command" -> "examples.command.run", + "a2a" -> "examples.a2a.run", + "agent-hooks" -> "examples.agentHooks.run" ) + private val defaultExample = "macro" + // List available examples def list() = Task.Command { println("Available examples:") println("-------------------") - exampleClasses.toSeq.sortBy(_._1).foreach { case (name, cls) => - println(s" $name -> $cls") + exampleCommands.toSeq.sortBy(_._1).foreach { case (name, command) => + println(s" $name -> ./$command") } println() println("Run with:") - println(" EXAMPLE=simple ./mill examples.bun # run specific example") - println(" EXAMPLE=hook ./mill examples.bun # run hook example") - println(" ./mill examples.bun # runs 'macro' by default") + println(s" ./mill examples.run # runs '$defaultExample' by default") + println(" ./mill examples.simple.run # run simple example") + println(" ./mill examples.hook.run # run hook example") println() println("Or run the compiled JS directly:") println(" bun out/examples/fastLinkJS.dest/main.js") } - // Dynamic mainClass based on environment or default - // Task.Input ensures this is re-evaluated each run - override def mainClass = Task.Input { - val example = Task.env.get("EXAMPLE").getOrElse("macro") - val cls = exampleClasses.get(example) - if cls.isEmpty then println(s"Warning: Unknown example '$example', using 'macro'") - cls.orElse(Some(exampleClasses("macro"))) - } - - // Run a specific example by short name - // Usage: EXAMPLE=simple ./mill examples.run - // EXAMPLE=hook ./mill examples.run - // ./mill examples.run (runs macro by default) - // - // Or use runMain directly: - // ./mill examples.runMain com.tjclp.scalagent.examples.SimpleQuery - - // Custom bun runner that properly invokes the compiled JS - // Usage: EXAMPLE=hook ./mill examples.bun - def bun() = Task.Command { - val jsFile = fastLinkJS().dest.path / "main.js" - println(s"Running: bun $jsFile") - os.proc("bun", jsFile).call( - stdin = os.Inherit, - stdout = os.Inherit, - stderr = os.Inherit - ) + object simple extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.SimpleQuery" + } + + object custom extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.CustomToolExample" + } + + object hook extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.HookExample" + } + + object permission extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.PermissionExample" + } + + object session extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.SessionExample" + } + + object structured extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.StructuredOutputExample" + } + + object subagent extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.SubagentExample" + } + + object plugin extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.PluginExample" + } + + object prompt extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.SystemPromptExample" + } + + object command extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.SlashCommandExample" + } + + object a2a extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.A2AExample" + } + + object agentHooks extends ExampleModule { + def exampleMainClass = "com.tjclp.scalagent.examples.AgentHooksExample" } } diff --git a/examples/A2AExample.scala b/examples/A2AExample.scala index 2bd1a2b..f0653be 100644 --- a/examples/A2AExample.scala +++ b/examples/A2AExample.scala @@ -18,10 +18,10 @@ import com.tjclp.scalagent.* * Claude Writer (local) --> A2ATool --> A2A Client --> A2A Server --> Claude Researcher * ``` * - * Run with: mill examples.runMain com.tjclp.scalagent.examples.A2AExample + * Run with: ./mill examples.a2a.run * * Requires: - * - ANTHROPIC_API_KEY environment variable + * - ANTHROPIC_API_KEY environment variable when Claude Code auth is not already available * - @a2a-js/sdk npm package installed */ object A2AExample extends ZIOAppDefault: diff --git a/examples/AgentHooksExample.scala b/examples/AgentHooksExample.scala index a32549e..99f4f8d 100644 --- a/examples/AgentHooksExample.scala +++ b/examples/AgentHooksExample.scala @@ -14,9 +14,9 @@ import com.tjclp.scalagent.hooks.HookConfig * 4. Use the permissionMode field in AgentDefinition * 5. Use the fluent extension methods (withShellHook, withCallbackHook) * - * Run with: EXAMPLE=agent-hooks mill examples.run + * Run with: ./mill examples.agentHooks.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object AgentHooksExample extends ZIOAppDefault: diff --git a/examples/CustomToolExample.scala b/examples/CustomToolExample.scala index 4bf9d32..14b16a4 100644 --- a/examples/CustomToolExample.scala +++ b/examples/CustomToolExample.scala @@ -12,9 +12,9 @@ import com.tjclp.scalagent.* * 2. Create an in-process MCP server with those tools * 3. Use the custom tools in a Claude agent query * - * Run with: mill examples.runMain com.tjclp.scalagent.examples.CustomToolExample + * Run with: ./mill examples.custom.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object CustomToolExample extends ZIOAppDefault: diff --git a/examples/HookExample.scala b/examples/HookExample.scala index 6b89be0..31c8ef0 100644 --- a/examples/HookExample.scala +++ b/examples/HookExample.scala @@ -11,9 +11,9 @@ import com.tjclp.scalagent.* * 2. Block specific tools (e.g., Bash commands) * 3. Modify tool behavior based on custom logic * - * Run with: mill examples.runMain com.tjclp.scalagent.examples.HookExample + * Run with: ./mill examples.hook.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object HookExample extends ZIOAppDefault: diff --git a/examples/MacroToolExample.scala b/examples/MacroToolExample.scala index 269cb4a..6f3e388 100644 --- a/examples/MacroToolExample.scala +++ b/examples/MacroToolExample.scala @@ -16,9 +16,9 @@ import com.tjclp.scalagent.* * - Support for structured output with ToolResult.json() * - Support for multimodal output with ToolResult.multi * - * Run with: mill examples.runMain com.tjclp.scalagent.examples.MacroToolExample + * Run with: ./mill examples.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object MacroToolExample extends ZIOAppDefault: diff --git a/examples/PermissionExample.scala b/examples/PermissionExample.scala index 2559588..46df967 100644 --- a/examples/PermissionExample.scala +++ b/examples/PermissionExample.scala @@ -14,9 +14,9 @@ import com.tjclp.scalagent.permissions.{PermissionUpdate, PermissionUpdateDestin * 3. Use permission utilities for common patterns * 4. Programmatic permission updates with PermissionUpdateDestination * - * Run with: mill examples.runMain com.tjclp.scalagent.examples.PermissionExample + * Run with: ./mill examples.permission.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object PermissionExample extends ZIOAppDefault: diff --git a/examples/PluginExample.scala b/examples/PluginExample.scala index c1d9639..84eb460 100644 --- a/examples/PluginExample.scala +++ b/examples/PluginExample.scala @@ -11,9 +11,9 @@ import com.tjclp.scalagent.* * - Handle PluginError types (PathNotFound, NotADirectory, MissingManifest) * - Use convenience methods like withLocalPlugins() * - * Run with: EXAMPLE=plugin mill examples.run + * Run with: ./mill examples.plugin.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object PluginExample extends ZIOAppDefault: diff --git a/examples/SessionExample.scala b/examples/SessionExample.scala index 249a3d5..aed02ac 100644 --- a/examples/SessionExample.scala +++ b/examples/SessionExample.scala @@ -17,9 +17,9 @@ import com.tjclp.scalagent.* * - Proper resource cleanup with `session.close` * - Validated session UUIDs with `SessionUuid` * - * Run with: mill examples.runMain com.tjclp.scalagent.examples.SessionExample + * Run with: ./mill examples.session.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. * * @note * This uses the unstable V2 API from the TypeScript SDK. The API may change. diff --git a/examples/SimpleQuery.scala b/examples/SimpleQuery.scala index eb839cc..37a0dc4 100644 --- a/examples/SimpleQuery.scala +++ b/examples/SimpleQuery.scala @@ -11,9 +11,9 @@ import com.tjclp.scalagent.* * - Claude.query() for streaming responses * - Claude.conversation() for multi-turn chats * - * Run with: mill examples.run + * Run with: ./mill examples.simple.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object SimpleQuery extends ZIOAppDefault: diff --git a/examples/SlashCommandExample.scala b/examples/SlashCommandExample.scala index 63fdf08..d3fc28f 100644 --- a/examples/SlashCommandExample.scala +++ b/examples/SlashCommandExample.scala @@ -12,9 +12,9 @@ import com.tjclp.scalagent.* * - Use extension methods (withSlash, isBuiltin) * - Handle commands from SystemEvent.Init * - * Run with: EXAMPLE=command mill examples.run + * Run with: ./mill examples.command.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object SlashCommandExample extends ZIOAppDefault: diff --git a/examples/StructuredOutputExample.scala b/examples/StructuredOutputExample.scala index 705188a..30d9f95 100644 --- a/examples/StructuredOutputExample.scala +++ b/examples/StructuredOutputExample.scala @@ -12,9 +12,9 @@ import com.tjclp.scalagent.* * - Use StructuredOutput.derive[T] to generate JSON Schema * - Parse typed responses with parseAs[T] * - * Run with: EXAMPLE=structured mill examples.run + * Run with: ./mill examples.structured.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object StructuredOutputExample extends ZIOAppDefault: diff --git a/examples/SubagentExample.scala b/examples/SubagentExample.scala index 3062feb..a471711 100644 --- a/examples/SubagentExample.scala +++ b/examples/SubagentExample.scala @@ -11,9 +11,9 @@ import com.tjclp.scalagent.* * - Restrict agent tool access * - Set agent-specific models with AgentModel * - * Run with: EXAMPLE=subagent mill examples.run + * Run with: ./mill examples.subagent.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object SubagentExample extends ZIOAppDefault: diff --git a/examples/SystemPromptExample.scala b/examples/SystemPromptExample.scala index 67b3628..99fdd2f 100644 --- a/examples/SystemPromptExample.scala +++ b/examples/SystemPromptExample.scala @@ -11,9 +11,9 @@ import com.tjclp.scalagent.* * - Use SystemPromptConfig.claudeCode convenience value * - Append instructions to presets with claudeCodeWith() * - * Run with: EXAMPLE=prompt mill examples.run + * Run with: ./mill examples.prompt.run * - * Requires ANTHROPIC_API_KEY environment variable to be set. + * Requires ANTHROPIC_API_KEY environment variable to be set when Claude Code auth is not already available. */ object SystemPromptExample extends ZIOAppDefault: diff --git a/package.json b/package.json index 7b53f47..6bdc825 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,8 @@ { - "name": "scalagent", - "version": "0.4.2-SNAPSHOT", "private": true, - "type": "module", - "description": "Scalagent - Type-safe Scala.js wrapper for the Claude Agent SDK", "scripts": { - "build": "mill agent.compile", - "run": "mill examples.fastLinkJS && bun run out/examples/fastLinkJS.dest/main.js" + "build": "./mill agent.compile", + "run": "./mill examples.run" }, "dependencies": { "@a2a-js/sdk": "^0.3.12", @@ -16,7 +12,7 @@ "devDependencies": { "@types/bun": "^1.3.5" }, - "module": "index.ts", + "type": "module", "peerDependencies": { "typescript": "^5.9.3" }