diff --git a/.gitignore b/.gitignore
index 691a887..04916c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,7 +26,6 @@ dist-ssr
.env
**/agent-eval-report*
-packages
pids
.file-manifest
.devcontainer/
diff --git a/packages/spark/README.md b/packages/spark/README.md
new file mode 100644
index 0000000..59c9629
--- /dev/null
+++ b/packages/spark/README.md
@@ -0,0 +1,115 @@
+# @github/spark
+
+Spark runtime and hooks for low-code React applications.
+
+## Overview
+
+The `@github/spark` package provides core functionality for Spark-powered applications:
+
+- **useKV Hook**: Persistent key-value storage with localStorage and Spark KV integration
+- **Spark Runtime**: Mock LLM service, KV storage, and user authentication APIs
+- **Vite Plugins**: Build-time integrations for Spark applications
+
+## Installation
+
+This package is designed to be used as a workspace dependency:
+
+```json
+{
+ "dependencies": {
+ "@github/spark": "workspace:*"
+ }
+}
+```
+
+## Usage
+
+### useKV Hook
+
+The `useKV` hook provides persistent state management:
+
+```typescript
+import { useKV } from '@github/spark/hooks'
+
+function MyComponent() {
+ const [count, setCount, deleteCount] = useKV('counter', 0)
+
+ return (
+
+
Count: {count}
+
+
+
+ )
+}
+```
+
+### Spark Runtime
+
+Initialize the Spark runtime in your application entry point:
+
+```typescript
+import '@github/spark/spark'
+```
+
+Access the runtime APIs:
+
+```typescript
+// KV Storage
+window.spark.kv.set('key', 'value')
+const value = window.spark.kv.get('key')
+
+// LLM Service
+const response = await window.spark.llm.chat([
+ { role: 'user', content: 'Hello!' }
+])
+
+// User Info
+const user = window.spark.user.getCurrentUser()
+```
+
+### Vite Plugins
+
+Add Spark plugins to your Vite configuration:
+
+```typescript
+import sparkPlugin from '@github/spark/spark-vite-plugin'
+import createIconImportProxy from '@github/spark/vitePhosphorIconProxyPlugin'
+
+export default defineConfig({
+ plugins: [
+ sparkPlugin(),
+ createIconImportProxy()
+ ]
+})
+```
+
+## API Reference
+
+### useKV(key: string, defaultValue: T)
+
+Returns: `[value: T, setValue: (value: T | ((prev: T) => T)) => void, deleteValue: () => void]`
+
+- `key`: Storage key
+- `defaultValue`: Default value if key doesn't exist
+- `value`: Current value
+- `setValue`: Update the value (supports functional updates)
+- `deleteValue`: Delete the value and reset to default
+
+### window.spark
+
+Global runtime object with the following APIs:
+
+- `kv.get(key)`: Get value from KV storage
+- `kv.set(key, value)`: Set value in KV storage
+- `kv.delete(key)`: Delete key from KV storage
+- `kv.clear()`: Clear all KV storage
+- `kv.keys()`: Get all keys
+- `llm.chat(messages)`: Chat with LLM
+- `llm.complete(prompt)`: Complete a prompt
+- `user.getCurrentUser()`: Get current user info
+- `user.isAuthenticated()`: Check if user is authenticated
+
+## License
+
+MIT
diff --git a/packages/spark/package.json b/packages/spark/package.json
new file mode 100644
index 0000000..95480ec
--- /dev/null
+++ b/packages/spark/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "@github/spark",
+ "version": "1.0.0",
+ "description": "Spark runtime and hooks for low-code React applications",
+ "type": "module",
+ "main": "./src/index.ts",
+ "types": "./src/types.d.ts",
+ "exports": {
+ ".": "./src/index.ts",
+ "./hooks": "./src/hooks/index.ts",
+ "./spark": "./src/spark.ts",
+ "./spark-vite-plugin": "./src/spark-vite-plugin.mjs",
+ "./vitePhosphorIconProxyPlugin": "./src/vitePhosphorIconProxyPlugin.mjs"
+ },
+ "files": [
+ "src"
+ ],
+ "scripts": {
+ "build": "tsc"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0 || ^19.0.0"
+ },
+ "devDependencies": {
+ "@types/react": "^19.0.0",
+ "typescript": "~5.7.2"
+ }
+}
diff --git a/packages/spark/src/hooks/index.ts b/packages/spark/src/hooks/index.ts
new file mode 100644
index 0000000..6f1f16b
--- /dev/null
+++ b/packages/spark/src/hooks/index.ts
@@ -0,0 +1,94 @@
+import { useState, useEffect, useCallback } from 'react'
+
+/**
+ * useKV Hook - Persistent key-value storage with localStorage and window.spark.kv integration
+ *
+ * This hook provides persistent state management that syncs with localStorage
+ * and integrates with the Spark KV storage system if available.
+ *
+ * @param key - Storage key
+ * @param defaultValue - Default value if key doesn't exist
+ * @returns Tuple of [value, setValue, deleteValue]
+ */
+export function useKV(
+ key: string,
+ defaultValue: T
+): [T, (value: T | ((prev: T) => T)) => void, () => void] {
+ // Initialize state from localStorage or default value
+ const [value, setValueInternal] = useState(() => {
+ try {
+ // Try to get from window.spark.kv first
+ if (typeof window !== 'undefined' && window.spark?.kv) {
+ const sparkValue = window.spark.kv.get(key)
+ if (sparkValue !== undefined) {
+ return sparkValue as T
+ }
+ }
+
+ // Fallback to localStorage
+ const item = localStorage.getItem(key)
+ return item ? JSON.parse(item) : defaultValue
+ } catch (error) {
+ console.error('Error reading from storage:', error)
+ return defaultValue
+ }
+ })
+
+ // Set value and sync to storage
+ const setValue = useCallback(
+ (newValue: T | ((prev: T) => T)) => {
+ try {
+ setValueInternal((prevValue) => {
+ const valueToStore =
+ typeof newValue === 'function'
+ ? (newValue as (prev: T) => T)(prevValue)
+ : newValue
+
+ // Store in localStorage
+ localStorage.setItem(key, JSON.stringify(valueToStore))
+
+ // Store in window.spark.kv if available
+ if (typeof window !== 'undefined' && window.spark?.kv) {
+ window.spark.kv.set(key, valueToStore)
+ }
+
+ return valueToStore
+ })
+ } catch (error) {
+ console.error('Error writing to storage:', error)
+ }
+ },
+ [key]
+ )
+
+ // Delete value from storage
+ const deleteValue = useCallback(() => {
+ try {
+ localStorage.removeItem(key)
+ if (typeof window !== 'undefined' && window.spark?.kv) {
+ window.spark.kv.delete(key)
+ }
+ setValueInternal(defaultValue)
+ } catch (error) {
+ console.error('Error deleting from storage:', error)
+ }
+ }, [key, defaultValue])
+
+ // Sync with localStorage changes from other tabs
+ useEffect(() => {
+ const handleStorageChange = (e: StorageEvent) => {
+ if (e.key === key && e.newValue !== null) {
+ try {
+ setValueInternal(JSON.parse(e.newValue))
+ } catch (error) {
+ console.error('Error parsing storage event:', error)
+ }
+ }
+ }
+
+ window.addEventListener('storage', handleStorageChange)
+ return () => window.removeEventListener('storage', handleStorageChange)
+ }, [key])
+
+ return [value, setValue, deleteValue]
+}
diff --git a/packages/spark/src/index.ts b/packages/spark/src/index.ts
new file mode 100644
index 0000000..84619c9
--- /dev/null
+++ b/packages/spark/src/index.ts
@@ -0,0 +1,11 @@
+/**
+ * @github/spark - Main Entry Point
+ *
+ * This is the main entry point for the Spark package.
+ * It re-exports all core functionality.
+ */
+
+export { sparkRuntime } from './spark-runtime'
+export { useKV } from './hooks/index'
+export { default as sparkPlugin } from './spark-vite-plugin.mjs'
+export { default as createIconImportProxy } from './vitePhosphorIconProxyPlugin.mjs'
diff --git a/packages/spark/src/spark-runtime.ts b/packages/spark/src/spark-runtime.ts
new file mode 100644
index 0000000..c9cad1e
--- /dev/null
+++ b/packages/spark/src/spark-runtime.ts
@@ -0,0 +1,72 @@
+/**
+ * Spark Runtime - Core runtime services for Spark applications
+ *
+ * This module provides mock implementations of Spark services including:
+ * - KV storage (key-value store)
+ * - LLM service (language model integration)
+ * - User authentication
+ */
+
+// Mock KV Storage
+const kvStorage = new Map()
+
+export const sparkRuntime = {
+ kv: {
+ get: (key: string) => {
+ try {
+ const value = kvStorage.get(key)
+ return value !== undefined ? value : localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key)!) : undefined
+ } catch (error) {
+ console.error('Error getting KV value:', error)
+ return undefined
+ }
+ },
+ set: (key: string, value: any) => {
+ try {
+ kvStorage.set(key, value)
+ localStorage.setItem(key, JSON.stringify(value))
+ } catch (error) {
+ console.error('Error setting KV value:', error)
+ }
+ },
+ delete: (key: string) => {
+ try {
+ kvStorage.delete(key)
+ localStorage.removeItem(key)
+ } catch (error) {
+ console.error('Error deleting KV value:', error)
+ }
+ },
+ clear: () => {
+ try {
+ kvStorage.clear()
+ } catch (error) {
+ console.error('Error clearing KV storage:', error)
+ }
+ },
+ keys: () => Array.from(kvStorage.keys())
+ },
+
+ llm: {
+ chat: async (messages: any[]) => {
+ console.log('Mock LLM chat called with messages:', messages)
+ return {
+ role: 'assistant',
+ content: 'This is a mock response from the Spark LLM service.'
+ }
+ },
+ complete: async (prompt: string) => {
+ console.log('Mock LLM complete called with prompt:', prompt)
+ return 'This is a mock completion from the Spark LLM service.'
+ }
+ },
+
+ user: {
+ getCurrentUser: () => ({
+ id: 'mock-user-id',
+ name: 'Mock User',
+ email: 'mock@example.com'
+ }),
+ isAuthenticated: () => true
+ }
+}
diff --git a/packages/spark/src/spark-vite-plugin.mjs b/packages/spark/src/spark-vite-plugin.mjs
new file mode 100644
index 0000000..f175370
--- /dev/null
+++ b/packages/spark/src/spark-vite-plugin.mjs
@@ -0,0 +1,21 @@
+/**
+ * Spark Vite Plugin
+ *
+ * This plugin integrates Spark functionality into the Vite build process.
+ * It handles initialization and configuration of Spark features.
+ */
+
+export default function sparkPlugin() {
+ return {
+ name: 'spark-vite-plugin',
+
+ configResolved(config) {
+ // Plugin configuration
+ },
+
+ transformIndexHtml(html) {
+ // Inject Spark initialization if needed
+ return html
+ }
+ }
+}
diff --git a/packages/spark/src/spark.ts b/packages/spark/src/spark.ts
new file mode 100644
index 0000000..893d801
--- /dev/null
+++ b/packages/spark/src/spark.ts
@@ -0,0 +1,22 @@
+/**
+ * Spark Initialization Module
+ *
+ * This module initializes the Spark runtime and makes it available globally
+ * via window.spark. It should be imported early in the application lifecycle.
+ */
+
+import { sparkRuntime } from './spark-runtime'
+
+// Declare global window.spark
+declare global {
+ interface Window {
+ spark: typeof sparkRuntime
+ }
+}
+
+// Initialize window.spark
+if (typeof window !== 'undefined') {
+ window.spark = sparkRuntime
+}
+
+export default sparkRuntime
diff --git a/packages/spark/src/types.d.ts b/packages/spark/src/types.d.ts
new file mode 100644
index 0000000..21dd62f
--- /dev/null
+++ b/packages/spark/src/types.d.ts
@@ -0,0 +1,29 @@
+/**
+ * TypeScript Type Definitions for Spark
+ *
+ * Global type declarations for window.spark and Spark APIs
+ */
+
+declare global {
+ interface Window {
+ spark: {
+ kv: {
+ get: (key: string) => any
+ set: (key: string, value: any) => void
+ delete: (key: string) => void
+ clear: () => void
+ keys: () => string[]
+ }
+ llm: {
+ chat: (messages: any[]) => Promise<{ role: string; content: string }>
+ complete: (prompt: string) => Promise
+ }
+ user: {
+ getCurrentUser: () => { id: string; name: string; email: string }
+ isAuthenticated: () => boolean
+ }
+ }
+ }
+}
+
+export {}
diff --git a/packages/spark/src/vitePhosphorIconProxyPlugin.mjs b/packages/spark/src/vitePhosphorIconProxyPlugin.mjs
new file mode 100644
index 0000000..3e4dee4
--- /dev/null
+++ b/packages/spark/src/vitePhosphorIconProxyPlugin.mjs
@@ -0,0 +1,24 @@
+/**
+ * Vite Phosphor Icon Proxy Plugin
+ *
+ * This plugin provides a proxy for Phosphor icon imports to improve
+ * build performance and bundle size.
+ */
+
+export default function createIconImportProxy() {
+ return {
+ name: 'vite-phosphor-icon-proxy',
+
+ resolveId(id) {
+ // Handle icon imports
+ if (id.includes('@phosphor-icons/react')) {
+ return null // Let Vite handle it normally
+ }
+ },
+
+ transform(code, id) {
+ // Transform icon imports if needed
+ return null
+ }
+ }
+}
diff --git a/packages/spark/tsconfig.json b/packages/spark/tsconfig.json
new file mode 100644
index 0000000..653d99d
--- /dev/null
+++ b/packages/spark/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "ESNext",
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true
+ },
+ "include": ["src"],
+ "exclude": ["node_modules"]
+}