diff --git a/.github/workflows/CI-build.yml b/.github/workflows/CI-build.yml
index cc19d429bd..79661d1c3c 100644
--- a/.github/workflows/CI-build.yml
+++ b/.github/workflows/CI-build.yml
@@ -7,9 +7,9 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- node-version: [18.x]
+ node-version: [24.x]
env:
- NODE_OPTIONS: '--max_old_space_size=4096'
+ NODE_OPTIONS: "--max_old_space_size=4096"
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -18,8 +18,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- cache: 'npm'
- cache-dependency-path: '**/package-lock.json'
+ cache: "npm"
+ cache-dependency-path: "**/package-lock.json"
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/CI-e2e.yml b/.github/workflows/CI-e2e.yml
index 25d4d5f7ab..314a9fd493 100644
--- a/.github/workflows/CI-e2e.yml
+++ b/.github/workflows/CI-e2e.yml
@@ -8,10 +8,10 @@ jobs:
strategy:
fail-fast: false
matrix:
- node-version: [18.x]
+ node-version: [24.x]
test: [1, 2, 3, 4, 5]
env:
- NODE_OPTIONS: '--max_old_space_size=4096'
+ NODE_OPTIONS: "--max_old_space_size=4096"
steps:
- name: Checkout code
uses: actions/checkout@v4
@@ -20,8 +20,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- cache: 'npm'
- cache-dependency-path: '**/package-lock.json'
+ cache: "npm"
+ cache-dependency-path: "**/package-lock.json"
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 5468e8ad01..ac5f2ee4bf 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -7,13 +7,13 @@ on:
- main
env:
- NODE_VERSION: 18.x
+ NODE_VERSION: 24.x
jobs:
deploy:
runs-on: ubuntu-latest
env:
- NODE_OPTIONS: '--max_old_space_size=4096'
+ NODE_OPTIONS: "--max_old_space_size=4096"
steps:
- name: Generate Github Token for CI Bot
uses: actions/create-github-app-token@v1
@@ -31,8 +31,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- cache: 'npm'
- cache-dependency-path: '**/package-lock.json'
+ cache: "npm"
+ cache-dependency-path: "**/package-lock.json"
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/i18n-update-pull.yml b/.github/workflows/i18n-update-pull.yml
index 2e78760639..0a5c9a74d2 100644
--- a/.github/workflows/i18n-update-pull.yml
+++ b/.github/workflows/i18n-update-pull.yml
@@ -7,7 +7,7 @@ on:
env:
LOKALISE_PROJECT_ID: ${{ vars.LOKALISE_PROJECT_ID }}
LOKALISE_API_TOKEN: ${{ secrets.LOKALISE_API_TOKEN }}
- NODE_VERSION: 18.x
+ NODE_VERSION: 24.x
CI: true
jobs:
@@ -91,8 +91,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- cache: 'npm'
- cache-dependency-path: '**/package-lock.json'
+ cache: "npm"
+ cache-dependency-path: "**/package-lock.json"
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/i18n-update-push.yml b/.github/workflows/i18n-update-push.yml
index fcbf516740..4d9488b08a 100644
--- a/.github/workflows/i18n-update-push.yml
+++ b/.github/workflows/i18n-update-push.yml
@@ -7,7 +7,7 @@ on:
env:
LOKALISE_PROJECT_ID: ${{ vars.LOKALISE_PROJECT_ID }}
LOKALISE_API_TOKEN: ${{ secrets.LOKALISE_API_TOKEN }}
- NODE_VERSION: 18.x
+ NODE_VERSION: 24.x
CI: true
jobs:
@@ -91,8 +91,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- cache: 'npm'
- cache-dependency-path: '**/package-lock.json'
+ cache: "npm"
+ cache-dependency-path: "**/package-lock.json"
- name: Install dependencies
run: npm ci
@@ -136,7 +136,7 @@ jobs:
| **New Branch for i18n** | [\`${process.env.NEW_BRANCH}\`](${branchURL}) |
| **Last Commit SHA** | ${process.env.LAST_COMMIT_SHA} |
- Maintainers can comment \`.i18n-update-pull\` after translation is done to trigger the i18n pull workflow and pull the changes back to Github.
+ Maintainers can comment \`.i18n-update-pull\` after translation is done to trigger the i18n pull workflow and pull the changes back to Github.
`;
github.rest.issues.createComment({
diff --git a/.github/workflows/i18n-update-scheduled.yml b/.github/workflows/i18n-update-scheduled.yml
index be2b5ac395..81dab6d82f 100644
--- a/.github/workflows/i18n-update-scheduled.yml
+++ b/.github/workflows/i18n-update-scheduled.yml
@@ -5,7 +5,7 @@ name: i18n-update-scheduled
on:
schedule:
- - cron: '0 0 * * 0'
+ - cron: "0 0 * * 0"
push:
branches:
- develop
@@ -16,7 +16,7 @@ env:
LOKALISE_API_TOKEN: ${{ secrets.LOKALISE_API_TOKEN }}
BRANCH: i18n/develop
LOKALISE_BRANCH: master
- NODE_VERSION: 18.x
+ NODE_VERSION: 24.x
CI: true
jobs:
@@ -55,8 +55,8 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- cache: 'npm'
- cache-dependency-path: '**/package-lock.json'
+ cache: "npm"
+ cache-dependency-path: "**/package-lock.json"
- name: Install dependencies
run: npm ci
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 8020c62898..aa44a5df7d 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -6,15 +6,19 @@ on:
- develop
types: [closed]
+permissions:
+ id-token: write # Required for OIDC
+ contents: write
+
env:
- NODE_VERSION: 18.x
+ NODE_VERSION: 24.x
jobs:
release:
runs-on: ubuntu-latest
if: github.event.pull_request.merged && startsWith(github.head_ref, 'releases/')
env:
- NODE_OPTIONS: '--max_old_space_size=4096'
+ NODE_OPTIONS: "--max_old_space_size=4096"
steps:
- name: Generate Github Token for CI Bot
uses: actions/create-github-app-token@v1
@@ -36,8 +40,12 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- cache: 'npm'
- cache-dependency-path: '**/package-lock.json'
+ cache: "npm"
+ cache-dependency-path: "**/package-lock.json"
+
+ # Ensure npm 11.5.1 or later is installed (for OIDC)
+ - name: Update npm
+ run: npm install -g npm@11.6.4
- name: Install dependencies
run: npm ci
@@ -91,12 +99,8 @@ jobs:
- name: Publish SDK to NPM
if: startsWith(github.head_ref, 'releases/sdk-v')
- run: |
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
- npm publish --access=public
working-directory: ./build/sdk
- env:
- NPM_TOKEN: ${{secrets.NPM_TOKEN}}
+ run: npm publish --access=public
- name: Create pull request to main (App)
if: startsWith(github.head_ref, 'releases/v')
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b010805b70..0ca7bdbe58 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. See [standa
---
+## [sdk-v0.13.0](https://github.com/live-codes/livecodes/compare/v47...sdk-v0.13.0) (2026-02-08)
+
+### Highlights for this release
+
+- Add `minizinc` to `Language` (Minizinc language support).
+- Add `bn`, `nl`, `id` and `tr` to `AppLanguage` (Bengali, Dutch, Indonesian and Turkish translations).
+- Remove `enableAI` config option (see [#937](https://github.com/live-codes/livecodes/pull/937))
+
+---
+
## [v47](https://github.com/live-codes/livecodes/compare/v46...v47) (2025-10-04)
### Highlights for this release
diff --git a/README.md b/README.md
index dc44433982..4d0cb49cc9 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ A [feature-rich](https://livecodes.io/docs/features/), open-source, **client-sid
[](https://www.npmjs.com/package/livecodes)
[](https://www.npmjs.com/package/livecodes)
[](https://www.jsdelivr.com/package/npm/livecodes)
-[](https://livecodes.io/docs/languages/)
+[](https://livecodes.io/docs/languages/)
[](https://livecodes.io/docs/)
[](https://livecodes.io/docs/llms.txt)
[](https://livecodes.io/docs/llms-full.txt)
@@ -110,7 +110,6 @@ Add this code to your page:
- [Dev Tools](https://livecodes.io/docs/features/tools-pane) ([console](https://livecodes.io/docs/features/console), [compiled code viewer](https://livecodes.io/docs/features/compiled-code), [test runner](https://livecodes.io/docs/features/tests))
- [Code formatting](https://livecodes.io/docs/features/code-format)
- [Intellisense](https://livecodes.io/docs/features/intellisense)
-- [AI Code Assistant 🪄](https://livecodes.io/docs/features/ai)
- [Lite mode](https://livecodes.io/docs/features/lite)
- [Read-only mode](https://livecodes.io/docs/features/read-only)
- [Broadcast](https://livecodes.io/docs/features/broadcast)
@@ -119,7 +118,7 @@ Add this code to your page:
- [Client-side!](https://livecodes.io/docs/why#client-side)
- Very [configurable](https://livecodes.io/docs/configuration/)
- Developer-friendly build-free environment
-- Powerful [SDK](https://livecodes.io/docs/sdk/) (available for [vanilla JavaScript, TypeScript](https://livecodes.io/docs/sdk/js-ts), [React](https://livecodes.io/docs/sdk/react), [Vue](https://livecodes.io/docs/sdk/vue) and [Svelte](https://livecodes.io/docs/sdk/svelte))
+- Powerful [SDK](https://livecodes.io/docs/sdk/) (available for [vanilla JavaScript, TypeScript](https://livecodes.io/docs/sdk/js-ts), [React](https://livecodes.io/docs/sdk/react), [Vue](https://livecodes.io/docs/sdk/vue), [Svelte](https://livecodes.io/docs/sdk/svelte) and [Solid](https://livecodes.io/docs/sdk/solid))
- Comprehensive [Documentations](https://livecodes.io/docs/)
- Focused on [privacy and security](https://livecodes.io/docs/features/security)
- Free and [Open-Source](https://livecodes.io/docs/license)
@@ -130,7 +129,7 @@ For details check the [full list of features](https://livecodes.io/docs/features
The Software Development Kit (SDK) provides an easy, yet powerful, interface to embed and communicate with LiveCodes playgrounds.
-The SDK is provided as a light-weight ([less than 5kb gzipped](https://bundlephobia.com/package/livecodes)), zero-dependencies [npm package](https://livecodes.io/docs/sdk/#npm-package), that is also available from [CDNs](https://livecodes.io/docs/sdk/#cdn). It can be used to create playgrounds with a wide variety of [configurations](https://livecodes.io/docs/configuration/configuration-object.md) and [embed options](https://livecodes.io/docs/sdk/js-ts.md#embed-options). In addition, [SDK methods](https://livecodes.io/docs/sdk/js-ts.md#sdk-methods) allow programmatic communication and control of the playgrounds during runtime.
+The SDK is provided as a light-weight ([less than 5kb gzipped](https://bundlephobia.com/package/livecodes)), zero-dependencies [npm package](https://livecodes.io/docs/sdk/#npm-package), that is also available from [CDNs](https://livecodes.io/docs/sdk/#cdn). It can be used to create playgrounds with a wide variety of [configurations](https://livecodes.io/docs/configuration/configuration-object) and [embed options](https://livecodes.io/docs/sdk/js-ts#embed-options). In addition, [SDK methods](https://livecodes.io/docs/sdk/js-ts#sdk-methods) allow programmatic communication and control of the playgrounds during runtime.
### Installation
@@ -156,7 +155,7 @@ createPlayground('#container', {
});
```
-The [JavaScript SDK](https://livecodes.io/docs/sdk/js-ts.md) is framework/library agnostic. However, wrapper components are also provided for popular libraries (currently [React](https://livecodes.io/docs/sdk/react.md) and [Vue](https://livecodes.io/docs/sdk/vue.md)). The SDK can be used in [Svelte](https://livecodes.io/docs/sdk/svelte.md) directly without wrappers. [TypeScript support](https://livecodes.io/docs/sdk/js-ts.md#typescript-types) provides type-safety and a great developer experience.
+The [JavaScript SDK](https://livecodes.io/docs/sdk/js-ts) is framework/library agnostic. However, wrapper components are also provided for popular libraries (currently [React](https://livecodes.io/docs/sdk/react) and [Vue](https://livecodes.io/docs/sdk/vue)). The SDK can be used in [Svelte](https://livecodes.io/docs/sdk/svelte) and [Solid](https://livecodes.io/docs/sdk/solid) directly without wrappers. [TypeScript support](https://livecodes.io/docs/sdk/js-ts#typescript-types) provides type-safety and a great developer experience.
React SDK example: ([open in LiveCodes](https://livecodes.io/?x=code/N4IgLglmA2CmIC4QBkIDdYGED2ATWAzgAQBKsAhgMZhEDKAIgNJH4C22IANCPgZQE4QADpGwA7RCC4gAFhVySAPK1hhyRSjPL8CqgLwAdEAFUAKgDEAtAA4jRAPQA+A2OWr1Y8isMg0EWADuQtj8YHaU4mCwYmA+ARC4YDJ6+H6UsJbxiTKcRBBiUBDk0JZ8xbB6AIwAdAAMdk7SMmCs0ACCYGA6ktDkYgDmPtHhvQQEPkbSav0EiADaALrcVJAYAKK4UCGSfIIi0qzaANYArkKIoL0DJ+T98EjNrdIRMdFgkiAAvtwEYACecAuICu-Rud0klDGz0ibw+3xAu2E7wQlz6oNu9xAACsCAAPaGvGKSCCsYKhIioDA4XhEABm-GwrCIAHJoOhYBFePZ+BRqMyANwGfguIUuF6-DTiWkQfpEPREYCisREIiHfinIQIBVKlUqkFg2Ba5lqo64bABMTMzg63UvKIxI0AYiIAAlYNBoNgiAB1ELQXAAQitNu+Ss+guFYnFNAACr0-v0GScxLg5UQABQASjljiIikpWDwhElYmlg2ALzLnyIfkCPh5BBO0DCIAcjgjLlguLJNHwtPITdj8cT2GTuA7EnhvwBhDkqlmCEWPwESIXS5AkIIMYbqg+3CEDPSYxCa6WG5Ov0ZtFUkAGC+A8JJPfv8P+QkIF1fhDA9+BaINkhvoQK77NwdqwkgXzcBgOgQOIkgAMwIVM2DYNAv7ROQABGcAKEgxTQNIKzshC4gEGh8A-GoYAXhCnq6AonyfEAA))
@@ -270,11 +269,6 @@ LiveCodes uses services that are generously provided by:
-
-
-
-
-
@@ -310,11 +304,6 @@ LiveCodes uses services that are generously provided by:
-
-
-
-
-
diff --git a/docs/docs/configuration/configuration-object.mdx b/docs/docs/configuration/configuration-object.mdx
index fbd5982f6b..eae8a94115 100644
--- a/docs/docs/configuration/configuration-object.mdx
+++ b/docs/docs/configuration/configuration-object.mdx
@@ -451,7 +451,7 @@ Sets result page [zoom level](../features/result.mdx#result-page-zoom).
## User Settings
These are properties that define the [user settings](./../features/user-settings.mdx), including [editor settings](../features/editor-settings.mdx).
-
+{/*
### `enableAI`
Type: [`boolean`](../api/interfaces/Config.md#enableai)
@@ -459,6 +459,7 @@ Type: [`boolean`](../api/interfaces/Config.md#enableai)
Default: `false`
If `true`, [AI code assistant](../features/ai.mdx) is enabled.
+ */}
### `autoupdate`
diff --git a/docs/docs/credits.mdx b/docs/docs/credits.mdx
index e7ea48b5d8..4d6dc624ac 100644
--- a/docs/docs/credits.mdx
+++ b/docs/docs/credits.mdx
@@ -50,15 +50,6 @@ LiveCodes uses services that are generously provided by:
>
-
-
-
-
-
-
-
-
-
-
-
-## Examples:
-
-JavaScript:
-
-
-
-
-
-
-Python:
-
-
-
-
-
-
-## Instructions
-
-The AI code assistant can be enabled from:
-
-### UI
-
-The [editor settings](./editor-settings.mdx) screen (Settings menu → Editor Settings → Enable AI Code Assistant).
-
-import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx';
-
-
-
-
-
-**Note**
-
-When set from the UI, this configuration is saved locally to [user settings](./user-settings.mdx) and is remembered across sessions.
-
-### Configuration
-
-Alternatively, this can be enabled (_only for the current session_) using the [`enableAI`](../configuration/configuration-object.mdx#enableai) property in the [configuration object](../configuration/configuration-object.mdx). This can be used to enable the AI code assistant in [embedded playgrounds](./embeds.mdx).
-
-Example:
-
-```js
-import { createPlayground } from 'livecodes';
-
-createPlayground('#container', {
- config: {
- // highlight-next-line
- enableAI: true,
- },
-});
-```
-
-Also this can be enabled using [query params](../configuration/query-params.mdx) (e.g. https://livecodes.io/?enableAI).
-
-## Usage
-
-On typing, the code completion suggestions will be shown in dimmed color. Press Tab to accept, or Esc to cancel.
-
-On mobile, tap on the suggestion to accept it, or continue typing to reject.
-
-:::caution Note
-
-Please note that when using Windsurf AI assistant, your code is sent to Windsurf servers for code completion. However, your code is not used for training their model. Check Windsurf [FAQ](https://windsurf.com/faq#will-windsurf-regurgitate-private-code) and [privacy policy](https://windsurf.com/privacy-policy) for more details.
-
-:::
diff --git a/docs/docs/features/command-menu.mdx b/docs/docs/features/command-menu.mdx
index e69cbdf2b4..46194b7aad 100644
--- a/docs/docs/features/command-menu.mdx
+++ b/docs/docs/features/command-menu.mdx
@@ -7,7 +7,7 @@ It can be triggered from the keyboard by pressing Ctrl + K

The available commands cover a wide range of functionality, like showing and hiding UI elements (e.g. different editors, the [result page](./result.mdx), [console](./console.mdx), [compiled code viewer](./compiled-code.mdx), and [tests](./tests.mdx)), changing [languages](../languages), loading [starter templates](./templates.mdx), opening different screens (e.g. new project, opening saved projects, [import](./import.mdx), [embeds](./embeds.mdx), [deploy](./deploy.mdx), [share](./share.mdx) and more).
-In addition many commands can be executed from the command menu, such as running code, formatting code, changing settings (e.g. autorun, autosave, [AI code assistant](./ai.mdx), changing [themes](./themes.mdx), [editor settings](./editor-settings.mdx), and more).
+In addition many commands can be executed from the command menu, such as running code, formatting code, changing settings (e.g. autorun, autosave, changing [themes](./themes.mdx), [editor settings](./editor-settings.mdx), and more).

diff --git a/docs/docs/features/editor-settings.mdx b/docs/docs/features/editor-settings.mdx
index 66a2cf936d..ced2203dfd 100644
--- a/docs/docs/features/editor-settings.mdx
+++ b/docs/docs/features/editor-settings.mdx
@@ -17,10 +17,11 @@ import RunInLiveCodes from '../../src/components/RunInLiveCodes.tsx';
A preview code editor is displayed to preview the settings in real time.
The settings selected in the `Editor Settings` screen are saved locally to [user settings](./user-settings.mdx) and are used subsequently. These include:
-
+{/*
### Enable AI Code Assistant
Enables the [AI code assistant](./ai.mdx). (Free and no account required)
+ */}
### Code Editor
diff --git a/docs/docs/features/index.mdx b/docs/docs/features/index.mdx
index a51c2bea1a..7d3e02020f 100644
--- a/docs/docs/features/index.mdx
+++ b/docs/docs/features/index.mdx
@@ -20,10 +20,6 @@ In this page, a quick overview of the important features are presented. A more d
The default code editor is the powerful editor that powers [VS Code](https://code.visualstudio.com/), featuring code-completion, go-to-definition, multi-cursor support and other powerful features you got used to. The editor is very [customizable](./editor-settings.mdx). It supports [keyboard shortcuts](./keyboard-shortcuts.mdx), [code formatting](./code-format.mdx), [Emmet abbreviations](./editor-settings.mdx#emmet) and even [Vim and Emacs bindings](./editor-settings.mdx#editor-modes).
-## AI Code Assistant
-
-LiveCodes supports AI-powered code completion, totally for **free**, using [Windsurf](https://windsurf.com/). No account or tokens required. Enable from [editor settings](./ai.mdx#ui) and enjoy the magic!
-
## Mobile-friendly
The responsive layout allows working on devices with different screen sizes. On mobile, a lighter-weight touch-friendly code editor (CodeMirror 6) is used, so that you can experiment your ideas on the go.
diff --git a/docs/docs/languages/astro.mdx b/docs/docs/languages/astro.mdx
index 396b6c8ce5..e52955b126 100644
--- a/docs/docs/languages/astro.mdx
+++ b/docs/docs/languages/astro.mdx
@@ -1,3 +1,107 @@
# Astro
-TODO...
+Astro is a modern static site builder focused on delivering fast, content-driven websites. It uses a “zero JavaScript by default” approach and supports multiple frameworks like React, Vue, and Svelte through an islands architecture.
+
+## Usage
+
+There are **two primary modes** for building and rendering Astro pages:
+
+### Static (Default)
+
+In this mode, pages are fully pre-rendered at build time.
+All data must be available during the build process and can be supplied through **frontmatter**, **data fetching functions**, or **integrations**.
+
+**Example:** Provide data to a page using frontmatter.
+
+```astro
+---
+const name = "LiveCodes";
+---
+
Hello {name}!
+```
+
+---
+
+### Dynamic
+
+To enable runtime rendering, configure the page as a server-rendered route or use an Astro server adapter (e.g., Node, Deno, or Vercel).
+
+In this mode, values can be provided dynamically during request handling.
+
+**Example:** Create a server-side API endpoint:
+
+```js
+export async function GET() {
+ return new Response(JSON.stringify({ name: 'LiveCodes' }), {
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+```
+
+Then fetch and render it dynamically in Astro:
+
+```astro
+---
+const res = await fetch('https://jsonplaceholder.typicode.com/users/1');
+const data = await res.json();
+---
+Hello {data.name}!
+```
+
+---
+
+## Language Info
+
+### Name
+
+`astro`
+
+### Extension
+
+`astro`
+
+## Editor
+
+`markup`
+
+## Compiler
+
+Astro compiler
+
+### Version
+
+`@astrojs/compiler`: `v2.2.8`
+
+## Code Formatting
+
+Using [Prettier](https://prettier.io/).
+
+---
+
+## Example Usage
+
+### Static Example
+
+```astro
+---
+const message = "Hello from Astro!";
+---
+{message}
+```
+
+### Dynamic Example
+
+```astro
+---
+const res = await fetch('https://api.example.com/data');
+const data = await res.json();
+---
+{data.title}
+```
+
+## Links
+
+- [Astro Documentation](https://docs.astro.build)
+- [Astro Starter Template](https://livecodes.io/?template=astro)
+
+
diff --git a/docs/docs/languages/bbcode.mdx b/docs/docs/languages/bbcode.mdx
index be0493685e..893ca690f6 100644
--- a/docs/docs/languages/bbcode.mdx
+++ b/docs/docs/languages/bbcode.mdx
@@ -22,7 +22,7 @@
### Version
-`BBob`: v3.0.2
+`BBob`: v4.3.1
## Example Usage
diff --git a/docs/docs/languages/javascript.mdx b/docs/docs/languages/javascript.mdx
index 7f6c373412..a6dcb2c0b0 100644
--- a/docs/docs/languages/javascript.mdx
+++ b/docs/docs/languages/javascript.mdx
@@ -1,3 +1,78 @@
# JavaScript
-TODO...
+LiveCodes runs [JavaScript](https://developer.mozilla.org/docs/Web/JavaScript) (JS) in the browser.
+Accordingly, it has access to the DOM and other Web APIs, but it does not have access to Node.js APIs such as the file system or process information.
+
+## Demo
+
+import LiveCodes from '../../src/components/LiveCodes.tsx';
+
+
+
+## Usage
+
+The JavaScript code is added as-is without any transformations to the [result page](../features/result.mdx) inside a `
+`.trimStart(),
+ },
+ style: {
+ language: 'css',
+ content: `
+* {
+ box-sizing: border-box;
+}
+
+.container {
+ text-align: center;
+ font: 1em sans-serif;
+ max-width: 900px;
+ margin: 1em auto;
+ padding: 0 2em;
+}
+
+.logo {
+ width: 100px;
+}
+
+.label {
+ display: block;
+ text-align: left;
+ margin: 0.5em 0;
+ font-weight: bold;
+}
+
+#button {
+ display: block;
+ margin: 1em auto;
+ width: 10em;
+ height: 2em;
+ background-color: #1491EB;
+ border: 0;
+ border-radius: 3px;
+ color: #fff;
+ font-size: 1em;
+ cursor: pointer;
+}
+
+#button:hover {
+ background-color: #1180cf;
+}
+
+#button:disabled {
+ background-color: #6a9bbe;
+}
+
+.solver {
+ display: flex;
+ gap: 1em;
+}
+
+#data {
+ height: 9em;
+ resize: vertical;
+}
+
+#data, #output {
+ background-color: #fafafa;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ color: #3d3d3d;
+ margin: 1em auto;
+ padding: 0.8em;
+ text-align: left;
+ width: 100%;
+}
+
+#output.error {
+ color: red;
+}
+`.trimStart(),
+ },
+ script: {
+ language: 'minizinc',
+ content: String.raw`
+% from https://docs.minizinc.dev/en/stable/part_2_tutorial.html
+% Baking cakes for the school fete (with data file)
+
+int: flour; % no. grams of flour available
+int: banana; % no. of bananas available
+int: sugar; % no. grams of sugar available
+int: butter; % no. grams of butter available
+int: cocoa; % no. grams of cocoa available
+
+constraint assert(flour >= 0,
+ "Invalid datafile: " ++ "Amount of flour should be non-negative");
+constraint assert(banana >= 0,
+ "Invalid datafile: " ++ "Amount of banana should be non-negative");
+constraint assert(sugar >= 0,
+ "Invalid datafile: " ++ "Amount of sugar should be non-negative");
+constraint assert(butter >= 0,
+ "Invalid datafile: " ++ "Amount of butter should be non-negative");
+constraint assert(cocoa >= 0,
+ "Invalid datafile: " ++ "Amount of cocoa should be non-negative");
+
+var 0..100: b; % no. of banana cakes
+var 0..100: c; % no. of chocolate cakes
+
+% flour
+constraint 250 * b + 200 * c <= flour;
+% bananas
+constraint 2 * b <= banana;
+% sugar
+constraint 75 * b + 150 * c <= sugar;
+% butter
+constraint 100 * b + 150 * c <= butter;
+% cocoa
+constraint 75 * c <= cocoa;
+
+% maximize our profit
+solve maximize 400 * b + 450 * c;
+
+output [
+ "no. of banana cakes = \(b)\n",
+ "no. of chocolate cakes = \(c)\n"];
+`.trimStart(),
+ },
+};
diff --git a/src/livecodes/templates/starter/perl-starter.ts b/src/livecodes/templates/starter/perl-starter.ts
index 78a1228797..b8f6a7f63a 100644
--- a/src/livecodes/templates/starter/perl-starter.ts
+++ b/src/livecodes/templates/starter/perl-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const perlStarter: Template = {
name: 'perl',
+ aliases: ['pl'],
title: window.deps.translateString('templates.starter.perl', 'Perl Starter'),
thumbnail: 'assets/templates/perl.svg',
activeEditor: 'script',
diff --git a/src/livecodes/templates/starter/phaser-starter.ts b/src/livecodes/templates/starter/phaser-starter.ts
index bdbc1b9c11..affb495079 100644
--- a/src/livecodes/templates/starter/phaser-starter.ts
+++ b/src/livecodes/templates/starter/phaser-starter.ts
@@ -2,7 +2,7 @@ import type { Template } from '../../models';
export const phaserStarter: Template = {
name: 'phaser',
- title: 'Phaser Starter',
+ title: window.deps.translateString('templates.starter.phaser', 'Phaser Starter'),
thumbnail: 'assets/templates/phaser.png',
activeEditor: 'script',
markup: {
diff --git a/src/livecodes/templates/starter/postgresql-starter.ts b/src/livecodes/templates/starter/postgresql-starter.ts
index b78d1604d7..f7d8f2bfbc 100644
--- a/src/livecodes/templates/starter/postgresql-starter.ts
+++ b/src/livecodes/templates/starter/postgresql-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const postgresqlStarter: Template = {
name: 'postgresql',
+ aliases: ['pg', 'postgres', 'pgsql'],
title: window.deps.translateString('templates.starter.postgresql', 'PostgreSQL Starter'),
thumbnail: 'assets/templates/postgresql.svg',
activeEditor: 'script',
diff --git a/src/livecodes/templates/starter/python-starter.ts b/src/livecodes/templates/starter/python-starter.ts
index b2f2eb5f12..559d1eeb11 100644
--- a/src/livecodes/templates/starter/python-starter.ts
+++ b/src/livecodes/templates/starter/python-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const pythonStarter: Template = {
name: 'python',
+ aliases: ['py'],
title: window.deps.translateString('templates.starter.python', 'Python Starter'),
thumbnail: 'assets/templates/python.svg',
activeEditor: 'script',
diff --git a/src/livecodes/templates/starter/python-wasm-starter.ts b/src/livecodes/templates/starter/python-wasm-starter.ts
index d0e43caefb..37cb97752f 100644
--- a/src/livecodes/templates/starter/python-wasm-starter.ts
+++ b/src/livecodes/templates/starter/python-wasm-starter.ts
@@ -2,8 +2,8 @@ import type { Template } from '../../models';
export const pythonWasmStarter: Template = {
name: 'python-wasm',
- aliases: ['pyodide'],
- title: 'Python (Wasm) Starter',
+ aliases: ['pyodide', 'py-wasm'],
+ title: window.deps.translateString('templates.starter.python-wasm', 'Python (Wasm) Starter'),
thumbnail: 'assets/templates/python.svg',
activeEditor: 'script',
markup: {
diff --git a/src/livecodes/templates/starter/r-starter.ts b/src/livecodes/templates/starter/r-starter.ts
index 8af8afa04f..719eb2d0af 100644
--- a/src/livecodes/templates/starter/r-starter.ts
+++ b/src/livecodes/templates/starter/r-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const rStarter: Template = {
name: 'r',
+ aliases: ['r-lang', 'rlang'],
title: window.deps.translateString('templates.starter.r', 'R Starter'),
thumbnail: 'assets/templates/r.svg',
activeEditor: 'script',
diff --git a/src/livecodes/templates/starter/ruby-starter.ts b/src/livecodes/templates/starter/ruby-starter.ts
index 72bfb7f8c2..32d79fb897 100644
--- a/src/livecodes/templates/starter/ruby-starter.ts
+++ b/src/livecodes/templates/starter/ruby-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const rubyStarter: Template = {
name: 'ruby',
+ aliases: ['rb'],
title: window.deps.translateString('templates.starter.ruby', 'Ruby Starter'),
thumbnail: 'assets/templates/ruby.svg',
activeEditor: 'script',
diff --git a/src/livecodes/templates/starter/ruby-wasm-starter.ts b/src/livecodes/templates/starter/ruby-wasm-starter.ts
index 2f55751c06..3290ca0e17 100644
--- a/src/livecodes/templates/starter/ruby-wasm-starter.ts
+++ b/src/livecodes/templates/starter/ruby-wasm-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const rubyWasmStarter: Template = {
name: 'ruby-wasm',
+ aliases: ['rb-wasm'],
title: window.deps.translateString('templates.starter.ruby-wasm', 'Ruby (Wasm) Starter'),
thumbnail: 'assets/templates/ruby.svg',
activeEditor: 'script',
diff --git a/src/livecodes/templates/starter/tailwindcss-starter.ts b/src/livecodes/templates/starter/tailwindcss-starter.ts
index 20a768aab4..d0e504702e 100644
--- a/src/livecodes/templates/starter/tailwindcss-starter.ts
+++ b/src/livecodes/templates/starter/tailwindcss-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const tailwindcssStarter: Template = {
name: 'tailwindcss',
+ aliases: ['tw', 'tailwind'],
title: window.deps.translateString('templates.starter.tailwindcss', 'Tailwind CSS Starter'),
thumbnail: 'assets/templates/tailwindcss.svg',
activeEditor: 'markup',
diff --git a/src/livecodes/templates/starter/typescript-starter.ts b/src/livecodes/templates/starter/typescript-starter.ts
index eaee81797c..ade3a890e8 100644
--- a/src/livecodes/templates/starter/typescript-starter.ts
+++ b/src/livecodes/templates/starter/typescript-starter.ts
@@ -2,6 +2,7 @@ import type { Template } from '../../models';
export const typescriptStarter: Template = {
name: 'typescript',
+ aliases: ['ts'],
title: window.deps.translateString('templates.starter.typescript', 'TypeScript Starter'),
thumbnail: 'assets/templates/typescript.svg',
activeEditor: 'script',
diff --git a/src/livecodes/utils/utils.ts b/src/livecodes/utils/utils.ts
index 5ae0cc8929..06497ef7e3 100644
--- a/src/livecodes/utils/utils.ts
+++ b/src/livecodes/utils/utils.ts
@@ -685,6 +685,14 @@ export const addProp = /* @__PURE__ */ (
addProp(obj[first] as Record, rest.join('.'), value);
};
+export const onLoad = /* @__PURE__ */ (fn: (...args: any[]) => any) => {
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
+ fn();
+ } else {
+ window.addEventListener('load', fn, { once: true });
+ }
+};
+
export const predefinedValues = {
APP_VERSION: process.env.VERSION || '',
SDK_VERSION: process.env.SDK_VERSION || '',
diff --git a/src/livecodes/vendors.ts b/src/livecodes/vendors.ts
index ee5c78a39b..2c940244b9 100644
--- a/src/livecodes/vendors.ts
+++ b/src/livecodes/vendors.ts
@@ -3,7 +3,7 @@ import { modulesService } from './services/modules';
const { getUrl, getModuleUrl } = modulesService;
export const vendorsBaseUrl = // 'http://127.0.0.1:8081/';
- /* @__PURE__ */ getUrl('@live-codes/browser-compilers@0.22.3/dist/');
+ /* @__PURE__ */ getUrl('@live-codes/browser-compilers@0.22.6/dist/');
export const acornUrl = /* @__PURE__ */ getUrl('acorn@8.12.1/dist/acorn.js');
@@ -29,6 +29,11 @@ export const autoCompleteUrl = /* @__PURE__ */ getUrl(
export const babelUrl = /* @__PURE__ */ getUrl('@babel/standalone@7.26.4/babel.js');
+export const bbobHtmlUrl = /* @__PURE__ */ getUrl('@bbob/html@4.3.1/dist/index.min.js');
+export const bbobPresetHtmlUrl = /* @__PURE__ */ getUrl(
+ '@bbob/preset-html5@4.3.1/dist/index.min.js',
+);
+
export const biwaschemeUrl = /* @__PURE__ */ getUrl('biwascheme@0.8.0/release/biwascheme.js');
export const blocklyCdnBaseUrl = /* @__PURE__ */ getUrl('blockly@11.1.1/');
@@ -85,7 +90,7 @@ export const codeiumProviderUrl = /* @__PURE__ */ getUrl(
'@live-codes/monaco-codeium-provider@0.2.2/dist/index.js',
);
-export const codeMirrorBaseUrl = /* @__PURE__ */ getUrl('@live-codes/codemirror@0.3.2/build/');
+export const codeMirrorBaseUrl = /* @__PURE__ */ getUrl('@live-codes/codemirror@0.3.4/build/');
export const coffeeScriptUrl = /* @__PURE__ */ getUrl(
'coffeescript@2.7.0/lib/coffeescript-browser-compiler-legacy/coffeescript.js',
@@ -293,9 +298,11 @@ export const mermaidCdnUrl = /* @__PURE__ */ getUrl('mermaid@10.2.2/dist/mermaid
export const metaPngUrl = /* @__PURE__ */ getUrl('meta-png@1.0.6/dist/meta-png.umd.js');
+export const minizincUrl = /* @__PURE__ */ getUrl('minizinc@4.4.4/dist/minizinc.mjs');
+
export const mjmlUrl = /* @__PURE__ */ getUrl('mjml-browser@4.15.3/lib/index.js');
-export const monacoBaseUrl = /* @__PURE__ */ getUrl('@live-codes/monaco-editor@0.3.0/');
+export const monacoBaseUrl = /* @__PURE__ */ getUrl('@live-codes/monaco-editor@0.3.1/');
export const monacoEmacsUrl = /* @__PURE__ */ getUrl('monaco-emacs@0.3.0/dist/monaco-emacs.js');
@@ -337,6 +344,10 @@ export const postcssImportUrlUrl = /* @__PURE__ */ getUrl(
export const prettierBaseUrl = /* @__PURE__ */ getUrl('prettier@3.3.2/');
+export const prettierMinizincUrl = /* @__PURE__ */ getUrl(
+ '@live-codes/prettier-plugin-minizinc@0.2.0/dist/standalone.js',
+);
+
export const prettierPhpUrl = /* @__PURE__ */ getUrl('@prettier/plugin-php@0.22.2/standalone.js');
export const prismBaseUrl = /* @__PURE__ */ getUrl('prismjs@1.29.0/components/');
@@ -354,7 +365,7 @@ export const prismThemesLaserWaveUrl = /* @__PURE__ */ getUrl(
);
export const pyodideBaseUrl = /* @__PURE__ */ getUrl(
- 'https://cdn.jsdelivr.net/pyodide/v0.28.3/full/',
+ 'https://cdn.jsdelivr.net/pyodide/v0.29.0/full/',
);
export const qrcodeUrl = /* @__PURE__ */ getUrl('easyqrcodejs@4.6.1/dist/easy.qrcode.min.js');
@@ -391,10 +402,10 @@ export const resetCssUrl = /* @__PURE__ */ getUrl('reset-css@5.0.1/reset.css');
export const riotBaseUrl = /* @__PURE__ */ getUrl('riot@9.2.2/');
-export const rubyWasmBaseUrl = /* @__PURE__ */ getUrl('@ruby/3.3-wasm-wasi@2.6.2/dist/');
+export const rubyWasmBaseUrl = /* @__PURE__ */ getUrl('@ruby/3.4-wasm-wasi@2.7.2/dist/');
export const rubyWasmScriptUrl = /* @__PURE__ */ getUrl(
- '@ruby/wasm-wasi@2.6.2/dist/browser.umd.js',
+ '@ruby/wasm-wasi@2.7.2/dist/browser.umd.js',
);
export const snackbarUrl = /* @__PURE__ */ getUrl('@snackbar/core@1.7.0/dist/snackbar.css');
@@ -413,7 +424,7 @@ export const stencilUrl = /* @__PURE__ */ getUrl('@stencil/core@3.2.2/compiler/s
export const stylisUrl = /* @__PURE__ */ getUrl('stylis@4.3.2/dist/umd/stylis.js');
-export const svelteBaseUrl = /* @__PURE__ */ getUrl('svelte@5.12.0/');
+export const svelteBaseUrl = /* @__PURE__ */ getUrl('svelte@5.39.12/');
export const svgbobWasmCdnUrl = /* @__PURE__ */ getUrl('svgbob-wasm@0.4.1-a0/svgbob_wasm_bg.wasm');
@@ -437,9 +448,7 @@ export const tesseractUrl = /* @__PURE__ */ getUrl('tesseract.js@6.0.1/dist/tess
export const twigUrl = /* @__PURE__ */ getUrl('twig@1.17.1/twig.min.js');
-export const typescriptUrl = /* @__PURE__ */ getUrl(`typescript@5.6.2/lib/typescript.js`);
-
-export const typescriptVfsUrl = /* @__PURE__ */ getUrl('@typescript/vfs@1.5.3/dist/vfs.esm.js');
+export const typescriptUrl = /* @__PURE__ */ getUrl(`typescript@5.9.3/lib/typescript.js`);
export const uniterUrl = /* @__PURE__ */ getUrl('uniter@2.18.0/dist/uniter.js');
diff --git a/src/sdk/models.ts b/src/sdk/models.ts
index adebd1a1ae..7195f0f6dd 100644
--- a/src/sdk/models.ts
+++ b/src/sdk/models.ts
@@ -811,11 +811,11 @@ export interface EditorConfig {
*/
editorMode: 'vim' | 'emacs' | undefined;
- /**
- * If `true`, [AI code assistant](https://livecodes.io/docs/features/ai) is enabled.
- * @default false
- */
- enableAI: boolean;
+ // /**
+ // * If `true`, [AI code assistant](https://livecodes.io/docs/features/ai) is enabled.
+ // * @default false
+ // */
+ // enableAI: boolean;
}
export interface FormatterConfig {
@@ -933,6 +933,7 @@ export type Language =
| 'postcss'
| 'javascript'
| 'js'
+ | 'mjs'
| 'json'
| 'babel'
| 'es'
@@ -940,6 +941,7 @@ export type Language =
| 'typescript'
| 'flow'
| 'ts'
+ | 'mts'
| 'jsx'
| 'tsx'
| 'react'
@@ -1085,6 +1087,9 @@ export type Language =
| 'postgresql.sql'
| 'prolog.pl'
| 'prolog'
+ | 'minizinc'
+ | 'mzn'
+ | 'dzn'
| 'blockly'
| 'blockly.xml'
| 'xml'
@@ -1254,7 +1259,8 @@ export type ParserName =
| 'less'
| 'php'
| 'pug'
- | 'java';
+ | 'java'
+ | 'minizinc';
export interface Parser {
name: ParserName;
@@ -1355,6 +1361,7 @@ export interface Compiler {
| 'text/commonlisp'
| 'text/tcl'
| 'text/prolog'
+ | 'text/minizinc'
| 'text/go-wasm'
| 'application/json'
| 'application/lua'
@@ -1374,7 +1381,7 @@ export interface Compilers {
export type Template = Pick &
Partial & {
name: TemplateName;
- aliases?: TemplateName[];
+ aliases?: TemplateAlias[];
thumbnail: string;
tools?: Config['tools'];
autotest?: Config['autotest'];
@@ -1418,7 +1425,6 @@ export type TemplateName =
| 'reason'
| 'ocaml'
| 'python'
- | 'pyodide'
| 'python-wasm'
| 'r'
| 'ruby'
@@ -1428,7 +1434,6 @@ export type TemplateName =
| 'php'
| 'php-wasm'
| 'cpp'
- | 'clang'
| 'cpp-wasm'
| 'java'
| 'csharp-wasm'
@@ -1449,9 +1454,43 @@ export type TemplateName =
| 'sql'
| 'postgresql'
| 'prolog'
+ | 'minizinc'
| 'blockly'
| 'diagrams';
+export type TemplateAlias =
+ | 'js'
+ | 'ts'
+ | 'ng'
+ | 'bs'
+ | 'tailwind'
+ | 'tw'
+ | 'coffee'
+ | 'ls'
+ | 'py'
+ | 'pyodide'
+ | 'py-wasm'
+ | 'r-lang'
+ | 'rlang'
+ | 'rb'
+ | 'rb-wasm'
+ | 'golang'
+ | 'golang-wasm'
+ | 'c++'
+ | 'clang'
+ | 'c++-wasm'
+ | 'c#-wasm'
+ | 'cs-wasm'
+ | 'pl'
+ | 'lisp'
+ | 'cljs'
+ | 'md'
+ | 'as'
+ | 'postgres'
+ | 'pg'
+ | 'pgsql'
+ | 'mzn';
+
export interface Tool {
name: 'console' | 'compiled' | 'tests';
title: string;
@@ -1786,15 +1825,19 @@ export interface BlocklyContent {
export type AppLanguage =
| 'auto'
| 'ar'
+ | 'bn'
| 'de'
| 'en'
| 'es'
| 'fa'
| 'fr'
| 'hi'
+ | 'id'
| 'it'
| 'ja'
+ | 'nl'
| 'pt'
+ | 'tr'
| 'ru'
| 'ur'
| 'zh-CN';
diff --git a/src/sdk/package.sdk.json b/src/sdk/package.sdk.json
index 54d5841863..0a1923c7a0 100644
--- a/src/sdk/package.sdk.json
+++ b/src/sdk/package.sdk.json
@@ -1,6 +1,6 @@
{
"name": "livecodes",
- "version": "0.12.0",
+ "version": "0.13.0",
"description": "A Code Playground That Just Works!",
"author": "Hatem Hosny",
"license": "MIT",
diff --git a/storybook/stories/EmbedOptions/template.stories.ts b/storybook/stories/EmbedOptions/template.stories.ts
index 757ea3a4fa..1402812bc5 100644
--- a/storybook/stories/EmbedOptions/template.stories.ts
+++ b/storybook/stories/EmbedOptions/template.stories.ts
@@ -42,13 +42,13 @@ ReScript.storyName = 'ReScript';
export const Reason = livecodesStory({ template: 'reason' });
export const Ocaml = livecodesStory({ template: 'ocaml' });
export const Python = livecodesStory({ template: 'python' });
-export const PythonPyodide = livecodesStory({ template: 'pyodide' });
+export const PythonPyodide = livecodesStory({ template: 'python-wasm' });
export const R = livecodesStory({ template: 'r' });
export const Ruby = livecodesStory({ template: 'ruby' });
export const Go = livecodesStory({ template: 'go' });
export const PHP = livecodesStory({ template: 'php' });
export const Cpp = livecodesStory({ template: 'cpp' });
-export const CppClang = livecodesStory({ template: 'clang' });
+export const CppClang = livecodesStory({ template: 'cpp-wasm' });
export const Perl = livecodesStory({ template: 'perl' });
export const Lua = livecodesStory({ template: 'lua' });
export const Teal = livecodesStory({ template: 'teal' });
diff --git a/vendor-licenses.md b/vendor-licenses.md
index a22b29a64e..ac70c65302 100644
--- a/vendor-licenses.md
+++ b/vendor-licenses.md
@@ -148,6 +148,8 @@ mhsdesign/jit-browser-tailwindcss: [MIT License](https://github.com/mhsdesign/ji
MDX: [MIT License](https://github.com/mdx-js/mdx/blob/7fd1d9a4272754951e70dbaecff07a0ae402e13e/license)
+minizinc-js: [MPL-2.0 License](https://github.com/MiniZinc/minizinc-js/blob/3f7c34f0549195e5a66cf0f2d6f34cb5bce867f4/LICENSE)
+
MJML: [MIT License](https://github.com/mjmlio/mjml/blob/988819de3375867c09585d28f555166b97415200/LICENSE.md)
Monaco-editor: [MIT License](https://github.com/microsoft/monaco-editor/blob/f849d3f2653d1097652a7d9e1d01d242cc225da8/LICENSE.md)