From 0d2cf83169a82e3fe11649146362cb354645abdf Mon Sep 17 00:00:00 2001 From: "jinli.yl" Date: Wed, 26 Aug 2026 22:11:53 +0800 Subject: [PATCH] refactor(packaging): reorganize published packages --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- .github/workflows/_build-python-packages.yml | 41 +--- .github/workflows/ci-docs.yml | 8 +- .github/workflows/ci-packages.yml | 8 - .github/workflows/ci-python-quality.yml | 2 +- .github/workflows/ci-python-tests.yml | 2 +- .github/workflows/ci-reme-studio.yml | 77 +++++++ .github/workflows/ci-typescript.yml | 8 +- .github/workflows/ci-website.yml | 50 ----- .github/workflows/ci-windows.yml | 22 +- .github/workflows/deploy-docs.yml | 4 +- .github/workflows/release-python.yml | 20 +- .github/workflows/release-reme-studio.yml | 141 ++++++++++++ .github/workflows/release-typescript.yml | 14 +- .gitignore | 5 +- AGENTS.md | 14 +- README.md | 10 +- README_ZH.md | 10 +- docs/en/contributing.md | 4 +- docs/en/framework.md | 4 +- docs/en/quick_start.md | 4 +- docs/zh/agent_integration_plan.md | 6 +- docs/zh/contributing.md | 4 +- docs/zh/framework.md | 4 +- docs/zh/quick_start.md | 4 +- github-pages/README.md | 4 +- github-pages/scripts/generate-content.mjs | 9 +- integrations/README.md | 2 +- packages/reme_ai_studio/.gitignore | 1 - packages/reme_ai_studio/README.md | 203 ------------------ plugins/daily_paper/README.md | 2 +- plugins/daily_paper/README_ZH.md | 2 +- pyproject.toml | 6 +- reme/utils/web_static.py | 6 +- {website => reme_studio}/.env.example | 0 {website => reme_studio}/.gitignore | 0 {website => reme_studio}/.openai/hosting.json | 0 {website => reme_studio}/.prettierignore | 1 + reme_studio/LICENSE | 201 +++++++++++++++++ {website => reme_studio}/README.md | 16 +- {website => reme_studio}/README_ZH.md | 16 +- {website => reme_studio}/app/api-endpoint.ts | 0 {website => reme_studio}/app/api.ts | 0 {website => reme_studio}/app/chat-stream.ts | 0 {website => reme_studio}/app/chatgpt-auth.ts | 0 .../app/files-workspace/FilePreview.tsx | 0 .../app/files-workspace/FilesNavigator.tsx | 0 .../app/files-workspace/MemoryGraphView.tsx | 0 .../app/files-workspace/TabbedEditor.tsx | 0 .../files-workspace.module.css | 0 .../app/files-workspace/get-language.ts | 0 .../app/files-workspace/markdown.ts | 0 .../files-workspace/memory-graph.module.css | 0 .../app/files-workspace/memory-graph.ts | 0 .../app/files-workspace/panel-resize.ts | 0 {website => reme_studio}/app/globals.css | 0 {website => reme_studio}/app/i18n.ts | 0 {website => reme_studio}/app/layout.tsx | 0 {website => reme_studio}/app/markdown-save.ts | 0 {website => reme_studio}/app/monaco-setup.ts | 0 {website => reme_studio}/app/page.tsx | 0 .../app/settings-center.tsx | 0 {website => reme_studio}/app/store.ts | 0 {website => reme_studio}/app/tab-close.ts | 0 {website => reme_studio}/app/theme.ts | 0 {website => reme_studio}/app/types.ts | 0 .../app/workspace-drag.ts | 0 .../app/workspace-files.ts | 0 .../app/workspace-persistence.ts | 0 {website => reme_studio}/app/workspace.tsx | 0 {website => reme_studio}/cloudflare-env.d.ts | 0 {website => reme_studio}/db/index.ts | 0 {website => reme_studio}/db/schema.ts | 0 {website => reme_studio}/drizzle.config.ts | 0 .../drizzle/meta/_journal.json | 0 {website => reme_studio}/eslint.config.mjs | 9 +- .../examples/d1/app/api/notes/route.ts | 0 .../examples/d1/db/schema.ts | 0 {website => reme_studio}/index.html | 0 {website => reme_studio}/next-env.d.ts | 0 {website => reme_studio}/next.config.ts | 0 {website => reme_studio}/package-lock.json | 151 +++++++++++-- {website => reme_studio}/package.json | 48 +++-- {website => reme_studio}/postcss.config.mjs | 0 {website => reme_studio}/public/favicon.svg | 0 {website => reme_studio}/public/file.svg | 0 {website => reme_studio}/public/globe.svg | 0 {website => reme_studio}/public/og.jpg | Bin {website => reme_studio}/public/window.svg | 0 .../pyproject.toml | 10 +- .../src/reme_studio}/__init__.py | 0 .../src/reme_studio}/static/.gitignore | 0 {website => reme_studio}/static/main.tsx | 0 .../static/next-dynamic.tsx | 0 .../tests/api-endpoint.test.mjs | 0 .../tests/chat-stream.test.mjs | 0 .../tests/files-workspace.test.mjs | 0 {website => reme_studio}/tests/i18n.test.mjs | 0 .../tests/markdown-save.test.mjs | 0 .../tests/memory-graph.test.mjs | 0 .../tests/rendered-html.test.mjs | 0 .../tests/static-build.test.mjs | 0 .../tests/tab-close.test.mjs | 0 .../tests/workspace-drag.test.mjs | 0 .../tests/workspace-files.test.mjs | 0 .../tests/workspace-persistence.test.mjs | 0 .../tooling}/sites-vite-plugin.ts | 0 {website => reme_studio}/tsconfig.json | 0 {website => reme_studio}/vite.config.ts | 2 +- .../vite.static.config.ts | 0 {website => reme_studio}/worker/index.ts | 0 scripts/bump_version.py | 152 +++---------- scripts/package_studio.py | 46 +--- tests/unit/test_http_web_workspace.py | 4 +- tests/unit/test_package_versions.py | 156 ++++---------- .../typescript => typescript}/.prettierignore | 0 {packages/typescript => typescript}/README.md | 2 +- .../typescript => typescript}/README_ZH.md | 2 +- .../dsh/cordis.patch.yml | 0 .../eslint.config.mjs | 0 .../openclaw.plugin.json | 0 .../package-lock.json | 4 +- .../typescript => typescript}/package.json | 4 +- .../scripts/build-client.mjs | 0 .../scripts/test-package.mjs | 0 .../src/core/client.ts | 0 .../src/core/context.ts | 0 .../src/core/guidance.ts | 0 .../src/core/scheduling.ts | 0 .../src/core/types.ts | 0 .../src/dsh/client/frontmatter.ts | 0 .../src/dsh/client/index.tsx | 0 .../src/dsh/client/status-page.tsx | 0 .../src/dsh/client/styles.ts | 0 .../src/dsh/config.ts | 0 .../src/dsh/guidance.ts | 0 .../src/dsh/index.ts | 0 .../src/dsh/messages.ts | 0 .../src/dsh/runtime-status.ts | 0 .../src/dsh/runtime.ts | 0 .../src/dsh/scheduler.ts | 0 .../src/dsh/status-gateway.ts | 0 .../src/dsh/tools.ts | 0 .../src/dsh/types.ts | 0 .../typescript => typescript}/src/index.ts | 0 .../src/openclaw/config.ts | 0 .../src/openclaw/index.ts | 0 .../src/openclaw/messages.ts | 0 .../src/openclaw/runtime.ts | 0 .../src/openclaw/tools.ts | 0 .../tests/bundle.test.mjs | 0 .../tests/client.test.mjs | 0 .../tests/config.test.mjs | 0 .../tests/context.test.mjs | 0 .../tests/dsh-index.test.mjs | 0 .../tests/dsh-tools.test.mjs | 0 .../tests/frontmatter.test.mjs | 0 .../tests/messages.test.mjs | 0 .../tests/openclaw.test.mjs | 0 .../tests/runtime.test.mjs | 0 .../tests/scheduler.test.mjs | 0 .../typescript => typescript}/tsconfig.json | 0 162 files changed, 798 insertions(+), 729 deletions(-) create mode 100644 .github/workflows/ci-reme-studio.yml delete mode 100644 .github/workflows/ci-website.yml create mode 100644 .github/workflows/release-reme-studio.yml delete mode 100644 packages/reme_ai_studio/.gitignore delete mode 100644 packages/reme_ai_studio/README.md rename {website => reme_studio}/.env.example (100%) rename {website => reme_studio}/.gitignore (100%) rename {website => reme_studio}/.openai/hosting.json (100%) rename {website => reme_studio}/.prettierignore (87%) create mode 100644 reme_studio/LICENSE rename {website => reme_studio}/README.md (88%) rename {website => reme_studio}/README_ZH.md (88%) rename {website => reme_studio}/app/api-endpoint.ts (100%) rename {website => reme_studio}/app/api.ts (100%) rename {website => reme_studio}/app/chat-stream.ts (100%) rename {website => reme_studio}/app/chatgpt-auth.ts (100%) rename {website => reme_studio}/app/files-workspace/FilePreview.tsx (100%) rename {website => reme_studio}/app/files-workspace/FilesNavigator.tsx (100%) rename {website => reme_studio}/app/files-workspace/MemoryGraphView.tsx (100%) rename {website => reme_studio}/app/files-workspace/TabbedEditor.tsx (100%) rename {website => reme_studio}/app/files-workspace/files-workspace.module.css (100%) rename {website => reme_studio}/app/files-workspace/get-language.ts (100%) rename {website => reme_studio}/app/files-workspace/markdown.ts (100%) rename {website => reme_studio}/app/files-workspace/memory-graph.module.css (100%) rename {website => reme_studio}/app/files-workspace/memory-graph.ts (100%) rename {website => reme_studio}/app/files-workspace/panel-resize.ts (100%) rename {website => reme_studio}/app/globals.css (100%) rename {website => reme_studio}/app/i18n.ts (100%) rename {website => reme_studio}/app/layout.tsx (100%) rename {website => reme_studio}/app/markdown-save.ts (100%) rename {website => reme_studio}/app/monaco-setup.ts (100%) rename {website => reme_studio}/app/page.tsx (100%) rename {website => reme_studio}/app/settings-center.tsx (100%) rename {website => reme_studio}/app/store.ts (100%) rename {website => reme_studio}/app/tab-close.ts (100%) rename {website => reme_studio}/app/theme.ts (100%) rename {website => reme_studio}/app/types.ts (100%) rename {website => reme_studio}/app/workspace-drag.ts (100%) rename {website => reme_studio}/app/workspace-files.ts (100%) rename {website => reme_studio}/app/workspace-persistence.ts (100%) rename {website => reme_studio}/app/workspace.tsx (100%) rename {website => reme_studio}/cloudflare-env.d.ts (100%) rename {website => reme_studio}/db/index.ts (100%) rename {website => reme_studio}/db/schema.ts (100%) rename {website => reme_studio}/drizzle.config.ts (100%) rename {website => reme_studio}/drizzle/meta/_journal.json (100%) rename {website => reme_studio}/eslint.config.mjs (86%) rename {website => reme_studio}/examples/d1/app/api/notes/route.ts (100%) rename {website => reme_studio}/examples/d1/db/schema.ts (100%) rename {website => reme_studio}/index.html (100%) rename {website => reme_studio}/next-env.d.ts (100%) rename {website => reme_studio}/next.config.ts (100%) rename {website => reme_studio}/package-lock.json (99%) rename {website => reme_studio}/package.json (78%) rename {website => reme_studio}/postcss.config.mjs (100%) rename {website => reme_studio}/public/favicon.svg (100%) rename {website => reme_studio}/public/file.svg (100%) rename {website => reme_studio}/public/globe.svg (100%) rename {website => reme_studio}/public/og.jpg (100%) rename {website => reme_studio}/public/window.svg (100%) rename {packages/reme_ai_studio => reme_studio}/pyproject.toml (73%) rename {packages/reme_ai_studio/src/reme_ai_studio => reme_studio/src/reme_studio}/__init__.py (100%) rename {packages/reme_ai_studio/src/reme_ai_studio => reme_studio/src/reme_studio}/static/.gitignore (100%) rename {website => reme_studio}/static/main.tsx (100%) rename {website => reme_studio}/static/next-dynamic.tsx (100%) rename {website => reme_studio}/tests/api-endpoint.test.mjs (100%) rename {website => reme_studio}/tests/chat-stream.test.mjs (100%) rename {website => reme_studio}/tests/files-workspace.test.mjs (100%) rename {website => reme_studio}/tests/i18n.test.mjs (100%) rename {website => reme_studio}/tests/markdown-save.test.mjs (100%) rename {website => reme_studio}/tests/memory-graph.test.mjs (100%) rename {website => reme_studio}/tests/rendered-html.test.mjs (100%) rename {website => reme_studio}/tests/static-build.test.mjs (100%) rename {website => reme_studio}/tests/tab-close.test.mjs (100%) rename {website => reme_studio}/tests/workspace-drag.test.mjs (100%) rename {website => reme_studio}/tests/workspace-files.test.mjs (100%) rename {website => reme_studio}/tests/workspace-persistence.test.mjs (100%) rename {website/build => reme_studio/tooling}/sites-vite-plugin.ts (100%) rename {website => reme_studio}/tsconfig.json (100%) rename {website => reme_studio}/vite.config.ts (96%) rename {website => reme_studio}/vite.static.config.ts (100%) rename {website => reme_studio}/worker/index.ts (100%) rename {packages/typescript => typescript}/.prettierignore (100%) rename {packages/typescript => typescript}/README.md (99%) rename {packages/typescript => typescript}/README_ZH.md (99%) rename {packages/typescript => typescript}/dsh/cordis.patch.yml (100%) rename {packages/typescript => typescript}/eslint.config.mjs (100%) rename {packages/typescript => typescript}/openclaw.plugin.json (100%) rename {packages/typescript => typescript}/package-lock.json (99%) rename {packages/typescript => typescript}/package.json (98%) rename {packages/typescript => typescript}/scripts/build-client.mjs (100%) rename {packages/typescript => typescript}/scripts/test-package.mjs (100%) rename {packages/typescript => typescript}/src/core/client.ts (100%) rename {packages/typescript => typescript}/src/core/context.ts (100%) rename {packages/typescript => typescript}/src/core/guidance.ts (100%) rename {packages/typescript => typescript}/src/core/scheduling.ts (100%) rename {packages/typescript => typescript}/src/core/types.ts (100%) rename {packages/typescript => typescript}/src/dsh/client/frontmatter.ts (100%) rename {packages/typescript => typescript}/src/dsh/client/index.tsx (100%) rename {packages/typescript => typescript}/src/dsh/client/status-page.tsx (100%) rename {packages/typescript => typescript}/src/dsh/client/styles.ts (100%) rename {packages/typescript => typescript}/src/dsh/config.ts (100%) rename {packages/typescript => typescript}/src/dsh/guidance.ts (100%) rename {packages/typescript => typescript}/src/dsh/index.ts (100%) rename {packages/typescript => typescript}/src/dsh/messages.ts (100%) rename {packages/typescript => typescript}/src/dsh/runtime-status.ts (100%) rename {packages/typescript => typescript}/src/dsh/runtime.ts (100%) rename {packages/typescript => typescript}/src/dsh/scheduler.ts (100%) rename {packages/typescript => typescript}/src/dsh/status-gateway.ts (100%) rename {packages/typescript => typescript}/src/dsh/tools.ts (100%) rename {packages/typescript => typescript}/src/dsh/types.ts (100%) rename {packages/typescript => typescript}/src/index.ts (100%) rename {packages/typescript => typescript}/src/openclaw/config.ts (100%) rename {packages/typescript => typescript}/src/openclaw/index.ts (100%) rename {packages/typescript => typescript}/src/openclaw/messages.ts (100%) rename {packages/typescript => typescript}/src/openclaw/runtime.ts (100%) rename {packages/typescript => typescript}/src/openclaw/tools.ts (100%) rename {packages/typescript => typescript}/tests/bundle.test.mjs (100%) rename {packages/typescript => typescript}/tests/client.test.mjs (100%) rename {packages/typescript => typescript}/tests/config.test.mjs (100%) rename {packages/typescript => typescript}/tests/context.test.mjs (100%) rename {packages/typescript => typescript}/tests/dsh-index.test.mjs (100%) rename {packages/typescript => typescript}/tests/dsh-tools.test.mjs (100%) rename {packages/typescript => typescript}/tests/frontmatter.test.mjs (100%) rename {packages/typescript => typescript}/tests/messages.test.mjs (100%) rename {packages/typescript => typescript}/tests/openclaw.test.mjs (100%) rename {packages/typescript => typescript}/tests/runtime.test.mjs (100%) rename {packages/typescript => typescript}/tests/scheduler.test.mjs (100%) rename {packages/typescript => typescript}/tsconfig.json (100%) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index aa3e4af2..f2d55fe2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -21,7 +21,7 @@ - [ ] Focused tests pass - [ ] Unit tests pass, or omitted tests are explained below - [ ] `pre-commit run --all-files` passes, or omitted checks are explained below -- [ ] Frontend checks were run when `website/` changed +- [ ] Frontend checks were run when `reme_studio/` changed ## Checklist diff --git a/.github/workflows/_build-python-packages.yml b/.github/workflows/_build-python-packages.yml index 21a91dad..74cc1c80 100644 --- a/.github/workflows/_build-python-packages.yml +++ b/.github/workflows/_build-python-packages.yml @@ -25,13 +25,6 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Set up Node - uses: actions/setup-node@v6 - with: - node-version: '22.13' - cache: npm - cache-dependency-path: website/package-lock.json - - name: Set up Python uses: actions/setup-python@v6 with: @@ -55,45 +48,21 @@ jobs: - name: Run package tests run: PYTHONPATH=. python -m pytest tests/unit/test_package_versions.py -q - - name: Build Studio static workspace - working-directory: website - run: | - npm ci - npm run build:static - - name: Build and check distributions run: | - python scripts/package_studio.py - mkdir -p dist/reme dist/studio + mkdir -p dist/reme python -m build --outdir dist/reme - python -m build packages/reme_ai_studio --outdir dist/studio - python -m twine check dist/reme/* dist/studio/* + python -m twine check dist/reme/* - name: Verify distributions and isolated installation run: | REME_WHEEL="$(pwd)/$(ls dist/reme/reme_ai-[0-9]*.whl)" - STUDIO_WHEEL="$(pwd)/$(ls dist/studio/reme_ai_studio-*.whl)" - STUDIO_SDIST="$(pwd)/$(ls dist/studio/reme_ai_studio-*.tar.gz)" python -m zipfile -l "${REME_WHEEL}" | (! grep 'reme/web/') - python -m zipfile -l "${STUDIO_WHEEL}" | grep 'reme_ai_studio/static/index.html' - python -m zipfile -l "${STUDIO_WHEEL}" | grep 'dist-info/licenses/LICENSE' - python -m tarfile -l "${STUDIO_SDIST}" | grep '/LICENSE' + python -m zipfile -l "${REME_WHEEL}" | (! grep 'reme_studio/') python -m venv "${RUNNER_TEMP}/reme-package-smoke" - "${RUNNER_TEMP}/reme-package-smoke/bin/python" -m pip install \ - --find-links "$(pwd)/dist/studio" "${REME_WHEEL}[core]" + "${RUNNER_TEMP}/reme-package-smoke/bin/python" -m pip install "${REME_WHEEL}" cd "${RUNNER_TEMP}" - "${RUNNER_TEMP}/reme-package-smoke/bin/python" -c \ - "import reme; from reme_ai_studio import static_dir; assert (static_dir() / 'index.html').is_file()" - "${RUNNER_TEMP}/reme-package-smoke/bin/python" -c \ - "from reme.utils import resolve_web_static_dir; assert (resolve_web_static_dir() / 'index.html').is_file()" - - - name: Upload ReMe Studio distributions - if: inputs.upload_artifacts - uses: actions/upload-artifact@v4 - with: - name: reme-studio-distributions - path: dist/studio/ - if-no-files-found: error + "${RUNNER_TEMP}/reme-package-smoke/bin/python" -c "import reme" - name: Upload ReMe distributions if: inputs.upload_artifacts diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index 5650d860..7f3b460f 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -11,8 +11,8 @@ on: - 'README_ZH.md' - 'docs/**' - 'github-pages/**' - - 'website/README*.md' - - 'website/public/og.jpg' + - 'reme_studio/README*.md' + - 'reme_studio/public/og.jpg' - 'plugins/*/README*.md' - 'benchmark/*/README*.md' - 'skills/reme_memory/SKILL.md' @@ -26,8 +26,8 @@ on: - 'README_ZH.md' - 'docs/**' - 'github-pages/**' - - 'website/README*.md' - - 'website/public/og.jpg' + - 'reme_studio/README*.md' + - 'reme_studio/public/og.jpg' - 'plugins/*/README*.md' - 'benchmark/*/README*.md' - 'skills/reme_memory/SKILL.md' diff --git a/.github/workflows/ci-packages.yml b/.github/workflows/ci-packages.yml index ea34f701..d851cbcb 100644 --- a/.github/workflows/ci-packages.yml +++ b/.github/workflows/ci-packages.yml @@ -7,14 +7,10 @@ on: - '.github/workflows/ci-packages.yml' - '.github/workflows/_build-python-packages.yml' - '.github/workflows/release-python.yml' - - 'packages/reme_ai_studio/**' - 'pyproject.toml' - 'reme/__init__.py' - 'reme/utils/web_static.py' - 'scripts/bump_version.py' - - 'scripts/package_studio.py' - - 'tests/unit/test_package_versions.py' - - 'website/**' - 'LICENSE' pull_request: branches: [main, master, dev, develop] @@ -22,14 +18,10 @@ on: - '.github/workflows/ci-packages.yml' - '.github/workflows/_build-python-packages.yml' - '.github/workflows/release-python.yml' - - 'packages/reme_ai_studio/**' - 'pyproject.toml' - 'reme/__init__.py' - 'reme/utils/web_static.py' - 'scripts/bump_version.py' - - 'scripts/package_studio.py' - - 'tests/unit/test_package_versions.py' - - 'website/**' - 'LICENSE' workflow_dispatch: diff --git a/.github/workflows/ci-python-quality.yml b/.github/workflows/ci-python-quality.yml index 1630faf2..3098a26e 100644 --- a/.github/workflows/ci-python-quality.yml +++ b/.github/workflows/ci-python-quality.yml @@ -31,7 +31,7 @@ jobs: - name: Install run: | - pip install -q -e packages/reme_ai_studio -e ".[dev,core]" + pip install -q -e reme_studio -e ".[dev,core]" pip install -q --no-deps -e plugins/auto-fin -e plugins/daily_paper - name: Pre-commit starts diff --git a/.github/workflows/ci-python-tests.yml b/.github/workflows/ci-python-tests.yml index 67bc8ad1..6d97009d 100644 --- a/.github/workflows/ci-python-tests.yml +++ b/.github/workflows/ci-python-tests.yml @@ -35,7 +35,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools wheel - pip install -e packages/reme_ai_studio -e ".[dev,core]" + pip install -e reme_studio -e ".[dev,core]" pip install --no-deps -e plugins/auto-fin pip install -e plugins/daily_paper pip install coverage diff --git a/.github/workflows/ci-reme-studio.yml b/.github/workflows/ci-reme-studio.yml new file mode 100644 index 00000000..d1c2b8ba --- /dev/null +++ b/.github/workflows/ci-reme-studio.yml @@ -0,0 +1,77 @@ +name: CI / ReMe Studio + +on: + push: + paths: + - "reme_studio/**" + - ".github/workflows/ci-reme-studio.yml" + - ".github/workflows/release-reme-studio.yml" + - "scripts/package_studio.py" + - "tests/unit/test_package_versions.py" + - "pyproject.toml" + - "LICENSE" + pull_request: + paths: + - "reme_studio/**" + - ".github/workflows/ci-reme-studio.yml" + - ".github/workflows/release-reme-studio.yml" + - "scripts/package_studio.py" + - "tests/unit/test_package_versions.py" + - "pyproject.toml" + - "LICENSE" + + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + studio: + name: Studio checks + runs-on: ubuntu-latest + defaults: + run: + working-directory: reme_studio + + steps: + - uses: actions/checkout@v6 + + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: "22" + cache: npm + cache-dependency-path: reme_studio/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Run format check + run: npm run format:check + + - name: Run lint + run: npm run lint + + - name: Run tests + run: npm test + + - name: Verify npm package + run: npm pack --dry-run + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.11" + + - name: Build and verify Python package + working-directory: . + run: | + python -m pip install build packaging pytest twine + PYTHONPATH=. python -m pytest tests/unit/test_package_versions.py -q + python scripts/package_studio.py + python -m build reme_studio --outdir dist/studio + python -m twine check dist/studio/* diff --git a/.github/workflows/ci-typescript.yml b/.github/workflows/ci-typescript.yml index 9193b6a3..a457fbfa 100644 --- a/.github/workflows/ci-typescript.yml +++ b/.github/workflows/ci-typescript.yml @@ -6,13 +6,13 @@ on: paths: - '.github/workflows/ci-typescript.yml' - '.github/workflows/release-typescript.yml' - - 'packages/typescript/**' + - 'typescript/**' pull_request: branches: [main, master, dev, develop] paths: - '.github/workflows/ci-typescript.yml' - '.github/workflows/release-typescript.yml' - - 'packages/typescript/**' + - 'typescript/**' workflow_dispatch: concurrency: @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest defaults: run: - working-directory: packages/typescript + working-directory: typescript steps: - uses: actions/checkout@v6 @@ -37,7 +37,7 @@ jobs: with: node-version: '22.22.3' cache: npm - cache-dependency-path: packages/typescript/package-lock.json + cache-dependency-path: typescript/package-lock.json - run: npm ci - run: npm run format:check diff --git a/.github/workflows/ci-website.yml b/.github/workflows/ci-website.yml deleted file mode 100644 index 957adaf0..00000000 --- a/.github/workflows/ci-website.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: CI / Website - -on: - push: - paths: - - "website/**" - - ".github/workflows/ci-website.yml" - pull_request: - paths: - - "website/**" - - ".github/workflows/ci-website.yml" - - workflow_dispatch: - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - website: - name: Website checks - runs-on: ubuntu-latest - defaults: - run: - working-directory: website - - steps: - - uses: actions/checkout@v6 - - - name: Setup Node - uses: actions/setup-node@v6 - with: - node-version: "22" - cache: npm - cache-dependency-path: website/package-lock.json - - - name: Install dependencies - run: npm ci - - - name: Run format check - run: npm run format:check - - - name: Run lint - run: npm run lint - - - name: Run tests - run: npm test diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml index 6c7b6986..84cad3ca 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -26,13 +26,6 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Set up Node - uses: actions/setup-node@v6 - with: - node-version: '22' - cache: npm - cache-dependency-path: website/package-lock.json - - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: @@ -42,20 +35,7 @@ jobs: - name: Install package run: | python -m pip install --upgrade pip setuptools wheel - pip install -e packages/reme_ai_studio -e ".[dev,core]" - - - name: Build Studio static workspace - working-directory: website - run: | - npm ci - npm run build:static - - - name: Verify editable source installation serves Studio - shell: pwsh - run: | - Push-Location $env:RUNNER_TEMP - python -c "from reme.utils import resolve_web_static_dir; assert (resolve_web_static_dir() / 'index.html').is_file()" - Pop-Location + pip install -e reme_studio -e ".[dev,core]" - name: Run version job run: reme start config=tests/fixtures/config/version-smoke.yaml job=version diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 859030b5..33d49baf 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -8,8 +8,8 @@ on: - "docs/**" - "README.md" - "README_ZH.md" - - "website/README*.md" - - "website/public/og.jpg" + - "reme_studio/README*.md" + - "reme_studio/public/og.jpg" - "plugins/*/README*.md" - "benchmark/*/README*.md" - "skills/reme_memory/SKILL.md" diff --git a/.github/workflows/release-python.yml b/.github/workflows/release-python.yml index 6380b3e9..b9144d31 100644 --- a/.github/workflows/release-python.yml +++ b/.github/workflows/release-python.yml @@ -21,26 +21,8 @@ jobs: expected_version: ${{ github.event_name == 'release' && github.event.release.tag_name || inputs.version }} upload_artifacts: true - publish-studio: - needs: build - runs-on: ubuntu-latest - steps: - - name: Download ReMe Studio distributions - uses: actions/download-artifact@v4 - with: - name: reme-studio-distributions - path: dist/studio - - - name: Publish ReMe Studio - uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} - packages-dir: dist/studio - skip-existing: true - publish-reme: - needs: publish-studio + needs: build runs-on: ubuntu-latest steps: - name: Download ReMe distributions diff --git a/.github/workflows/release-reme-studio.yml b/.github/workflows/release-reme-studio.yml new file mode 100644 index 00000000..091a764b --- /dev/null +++ b/.github/workflows/release-reme-studio.yml @@ -0,0 +1,141 @@ +# Release checklist: +# 1. Update reme_studio/pyproject.toml, package.json, and package-lock.json to the same Studio version. +# 2. Configure PyPI and npm publishing credentials for this workflow. +# 3. Run this workflow manually with the exact Studio version. + +name: Release / ReMe Studio + +run-name: Publish ReMe Studio ${{ inputs.version }} (${{ inputs.npm_tag }}) + +on: + workflow_dispatch: + inputs: + version: + description: Version from the Studio Python and npm manifests + required: true + type: string + npm_tag: + description: npm distribution tag + required: true + default: latest + type: choice + options: + - next + - latest + +permissions: + contents: read + +concurrency: + group: publish-reme-studio + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ inputs.version }} + NPM_TAG: ${{ inputs.npm_tag }} + + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-node@v6 + with: + node-version: "22.13" + cache: npm + cache-dependency-path: reme_studio/package-lock.json + + - uses: actions/setup-python@v6 + with: + python-version: "3.11" + + - name: Validate Studio package names and version + run: | + python - <<'PY' + import json + import os + import tomllib + from pathlib import Path + + studio = Path("reme_studio") + python_manifest = tomllib.loads((studio / "pyproject.toml").read_text(encoding="utf-8"))["project"] + npm_manifest = json.loads((studio / "package.json").read_text(encoding="utf-8")) + expected = os.environ["RELEASE_VERSION"].removeprefix("v") + if python_manifest["name"] != "reme_studio": + raise SystemExit(f"Unexpected Python package name: {python_manifest['name']}") + if npm_manifest["name"] != "@agentscope-ai/reme_studio": + raise SystemExit(f"Unexpected npm package name: {npm_manifest['name']}") + if python_manifest["version"] != expected or npm_manifest["version"] != expected: + raise SystemExit( + f"Studio manifests are {python_manifest['version']} and {npm_manifest['version']}; " + f"workflow input is {expected}", + ) + prerelease = "-" in expected + if prerelease != (os.environ["NPM_TAG"] == "next"): + raise SystemExit("Prereleases must use next; stable releases must use latest") + PY + + - name: Install dependencies and run checks + working-directory: reme_studio + run: | + npm ci + npm run format:check + npm run lint + npm test + + - name: Build Studio distributions + run: | + python -m pip install build twine + mkdir -p dist/studio-python dist/studio-npm + npm pack ./reme_studio --pack-destination dist/studio-npm + python scripts/package_studio.py + python -m build reme_studio --outdir dist/studio-python + python -m twine check dist/studio-python/* + + - uses: actions/upload-artifact@v4 + with: + name: reme-studio-${{ inputs.version }} + path: | + dist/studio-python/* + dist/studio-npm/* + if-no-files-found: error + + publish-python: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + name: reme-studio-${{ inputs.version }} + path: dist + + - name: Publish ReMe Studio to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + packages-dir: dist/studio-python + skip-existing: true + + publish-npm: + needs: build + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/setup-node@v6 + with: + node-version: "24" + registry-url: https://registry.npmjs.org + + - uses: actions/download-artifact@v4 + with: + name: reme-studio-${{ inputs.version }} + path: dist + + - name: Publish ReMe Studio to npm + env: + NPM_TAG: ${{ inputs.npm_tag }} + run: npm publish dist/studio-npm/*.tgz --access public --tag "${NPM_TAG}" --provenance diff --git a/.github/workflows/release-typescript.yml b/.github/workflows/release-typescript.yml index 6a3a0222..fae68860 100644 --- a/.github/workflows/release-typescript.yml +++ b/.github/workflows/release-typescript.yml @@ -1,5 +1,5 @@ # Release checklist: -# 1. Update packages/typescript/package.json and package-lock.json to the release version and merge them. +# 1. Update typescript/package.json and package-lock.json to the release version and merge them. # 2. Configure npm Trusted Publishing for agentscope-ai/ReMe and this workflow file. # 3. Run this workflow manually with the exact package version (an optional v prefix is accepted). # 4. Configure ClawHub Trusted Publishing or CLAWHUB_TOKEN before enabling ClawHub publication. @@ -13,7 +13,7 @@ on: workflow_dispatch: inputs: version: - description: Version from packages/typescript/package.json (for example, 0.1.0) + description: Version from typescript/package.json (for example, 0.1.0) required: true type: string npm_tag: @@ -56,7 +56,7 @@ jobs: - name: Validate package name and release version id: validate - working-directory: packages/typescript + working-directory: typescript run: | node --input-type=module <<'JS' import { appendFileSync, readFileSync } from 'node:fs'; @@ -81,11 +81,11 @@ jobs: JS - name: Install dependencies - working-directory: packages/typescript + working-directory: typescript run: npm ci - name: Type-check and test - working-directory: packages/typescript + working-directory: typescript run: | npm run format:check npm run lint @@ -95,7 +95,7 @@ jobs: npx --yes clawhub@0.23.3 package validate . --json - name: Pack npm tarball - working-directory: packages/typescript + working-directory: typescript run: | mkdir -p "${RUNNER_TEMP}/reme-typescript-package" npm pack --pack-destination "${RUNNER_TEMP}/reme-typescript-package" @@ -158,7 +158,7 @@ jobs: source_repo: ${{ github.repository }} source_commit: ${{ github.sha }} source_ref: ${{ github.ref }} - source_path: packages/typescript + source_path: typescript package_artifact_name: agentscope-ai-reme-${{ inputs.version }} wait_for_publication: true secrets: diff --git a/.gitignore b/.gitignore index 350817dc..da160dc1 100644 --- a/.gitignore +++ b/.gitignore @@ -32,10 +32,7 @@ build/ dist/ node_modules/ *.egg-info/ - -# Website build integration source (not generated output) -!website/build/ -!website/build/** +typescript/reports/ # Logs / temporary files *.log diff --git a/AGENTS.md b/AGENTS.md index 8e0aa211..169e2b4f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -52,7 +52,10 @@ and concise documentation together. accounting, and wikilink handling. - `tests/unit/`: primary fast, isolated validation suite. - `tests/integration/`: service/model tests that may need credentials or external processes. -- `website/`: ReMe Workspace frontend source; its static build can be served by the HTTP service. +- `reme_studio/`: ReMe Studio frontend source plus the independently published `reme_studio` Python package and + `@agentscope-ai/reme_studio` npm static distribution. +- `typescript/`: the independently published `@agentscope-ai/reme` package, including the shared TypeScript client and + DeepSeek Harness and OpenClaw adapters. - `plugins/`: installable ReMe extensions, such as Auto Fin. - `integrations/`: adapters that connect ReMe to external agent hosts, such as Claude Code, DSH, and Hermes Agent. - `skills/`: standalone skills; `reme_memory` calls ReMe, while other skills may use separate tools or direct-file @@ -65,7 +68,7 @@ and concise documentation together. ReMe requires Python 3.11 or newer. Install the editable development environment with: ```bash -pip install -e packages/reme_ai_studio -e ".[dev,core]" +pip install -e reme_studio -e ".[dev,core]" ``` Before changing behavior, inspect the adjacent implementation, schema, built-in config, and focused tests. Follow @@ -185,7 +188,7 @@ pre-commit run --all-files ``` Black and Flake8 use a 120-character line limit and Python 3.11 formatting; Pylint is also run by pre-commit. If -`website/` changes, use its Node 22.13+ scripts and run the proportionate checks from that directory, such as +`reme_studio/` changes, use its Node 22.13+ scripts and run the proportionate checks from that directory, such as `npm run format:check`, `npm run lint`, or `npm test`. Integration tests may contact real model providers, services, or agent subprocesses and can require credentials. Do not @@ -197,13 +200,14 @@ environment has been supplied or authorized. Mock network, model, and subprocess - Preserve unrelated user changes in a dirty working tree. - Make the smallest coherent change and avoid unrelated cleanup or broad refactors. - Do not edit generated output when the source can be changed instead. The publish workflow builds - `website/dist-static` and copies it into `reme/web`; change `website/` source for frontend work. + `reme_studio/dist-static` and stages it under `reme_studio/src/reme_studio/static`; change `reme_studio/` source for + frontend work. - Do not silently change CLI flags, configuration keys, workspace layouts, serialized schemas, endpoint shapes, streaming termination, or service interfaces. Preserve compatibility where practical and document intentional migrations. - Do not introduce dependencies without a concrete repository-level need. - Do not commit `.env` files, credentials, runtime memory, logs, indexes, caches, benchmark outputs, or generated - website distributions. + Studio distributions. - State which validations passed and which relevant checks were not run in the final handoff. If a requirement is ambiguous, infer intent from nearby code, schemas, defaults, and tests. Ask the user only when the diff --git a/README.md b/README.md index 29b206b1..02d0e8fb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- ReMe Logo + ReMe Logo

@@ -79,8 +79,8 @@ Install from source: ```bash git clone https://github.com/agentscope-ai/ReMe.git cd ReMe -pip install -e packages/reme_ai_studio -e ".[core]" -cd website +pip install -e reme_studio -e ".[core]" +cd reme_studio npm ci npm run build:static cd .. @@ -181,8 +181,8 @@ lifecycle according to the capabilities of each runtime. | Agent | Recommended path | Available after integration | | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| **DeepSeek Harness** | Install [`@agentscope-ai/reme`](packages/typescript/README.md#deepseek-harness) with `dsh plugin --profile web add @agentscope-ai/reme`. | Long-term memory guidance, the `reme_search` tool, and automatic capture of completed main-agent turns. | -| **OpenClaw** | Install [`@agentscope-ai/reme`](packages/typescript/README.md#openclaw) with `openclaw plugins install @agentscope-ai/reme`. | Native memory tools, recall before user-triggered runs, and automatic turn capture. | +| **DeepSeek Harness** | Install [`@agentscope-ai/reme`](typescript/README.md#deepseek-harness) with `dsh plugin --profile web add @agentscope-ai/reme`. | Long-term memory guidance, the `reme_search` tool, and automatic capture of completed main-agent turns. | +| **OpenClaw** | Install [`@agentscope-ai/reme`](typescript/README.md#openclaw) with `openclaw plugins install @agentscope-ai/reme`. | Native memory tools, recall before user-triggered runs, and automatic turn capture. | | **QwenPaw** | Embed ReMe in-process through its Python API. | Reuse the host lifecycle and model config while keeping memory local and file-based. | | **Claude Code** | Start the streamable HTTP MCP service and install [the ReMe plugin](integrations/claude_code/reme). | MCP recall tools, the `reme-memory` skill, and a Stop hook that records sessions automatically. | | **Hermes** | Start the HTTP service and install [the ReMe provider](integrations/hermes_agent). | Recall before model calls and asynchronous `auto_memory` after each completed turn. | diff --git a/README_ZH.md b/README_ZH.md index c9218c4e..775fbbc8 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -1,5 +1,5 @@

- ReMe Logo + ReMe Logo

@@ -78,8 +78,8 @@ pip install "reme-ai[core]" ```bash git clone https://github.com/agentscope-ai/ReMe.git cd ReMe -pip install -e packages/reme_ai_studio -e ".[core]" -cd website +pip install -e reme_studio -e ".[core]" +cd reme_studio npm ci npm run build:static cd .. @@ -179,8 +179,8 @@ runtime 的能力,将记忆指引、召回和捕获接入 Agent 生命周期 | Agent | 推荐接入方式 | 接入后能力 | | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | -| **DeepSeek Harness** | 使用 `dsh plugin --profile web add @agentscope-ai/reme` 安装 [`@agentscope-ai/reme`](packages/typescript/README_ZH.md#deepseek-harness)。 | 长期记忆指引、`reme_search` 工具,以及自动捕获已完成的主 Agent 对话。 | -| **OpenClaw** | 使用 `openclaw plugins install @agentscope-ai/reme` 安装 [`@agentscope-ai/reme`](packages/typescript/README_ZH.md#openclaw)。 | 原生记忆工具、用户触发运行前召回和自动对话捕获。 | +| **DeepSeek Harness** | 使用 `dsh plugin --profile web add @agentscope-ai/reme` 安装 [`@agentscope-ai/reme`](typescript/README_ZH.md#deepseek-harness)。 | 长期记忆指引、`reme_search` 工具,以及自动捕获已完成的主 Agent 对话。 | +| **OpenClaw** | 使用 `openclaw plugins install @agentscope-ai/reme` 安装 [`@agentscope-ai/reme`](typescript/README_ZH.md#openclaw)。 | 原生记忆工具、用户触发运行前召回和自动对话捕获。 | | **QwenPaw** | 通过 Python API 在进程内嵌入 ReMe。 | 复用宿主生命周期和模型配置,同时保持记忆本地、文件化。 | | **Claude Code** | 启动 streamable HTTP MCP service,并安装 [ReMe 插件](integrations/claude_code/reme)。 | MCP 召回工具、`reme-memory` skill,以及自动记录会话的 Stop hook。 | | **Hermes** | 启动 HTTP service,并安装 [ReMe provider](integrations/hermes_agent)。 | 模型调用前召回,每轮对话完成后异步执行 `auto_memory`。 | diff --git a/docs/en/contributing.md b/docs/en/contributing.md index e9fe9c3e..ad962169 100644 --- a/docs/en/contributing.md +++ b/docs/en/contributing.md @@ -39,8 +39,8 @@ The project requires Python 3.11 or later. A virtual environment is recommended: ```bash python -m venv .venv source .venv/bin/activate -pip install -e packages/reme_ai_studio -e ".[dev,full]" -cd website +pip install -e reme_studio -e ".[dev,full]" +cd reme_studio npm ci npm run build:static cd .. diff --git a/docs/en/framework.md b/docs/en/framework.md index 547a13b8..d001dcee 100644 --- a/docs/en/framework.md +++ b/docs/en/framework.md @@ -174,8 +174,8 @@ HTTP service behavior: After registering Job endpoints, the HTTP service can also mount the ReMe Studio single-page application. The default is `service.web_enabled=true`. Builds are resolved from `service.web_static_dir`, `REME_WEB_STATIC_DIR`, the optional -`reme-ai-studio` package installed by the `web` and `core` extras, and source-tree locations such as -`website/dist-static`. If no `index.html` is found, only the frontend is skipped and the Job API remains available. The +`reme_studio` package installed by the `web` and `core` extras, and source-tree locations such as +`reme_studio/dist-static`. If no `index.html` is found, only the frontend is skipped and the Job API remains available. The Studio `GET` fallback does not replace existing `POST /` routes. MCP service behavior: diff --git a/docs/en/quick_start.md b/docs/en/quick_start.md index bd73f91a..0d890c73 100644 --- a/docs/en/quick_start.md +++ b/docs/en/quick_start.md @@ -15,8 +15,8 @@ Install from source: ```bash git clone https://github.com/agentscope-ai/ReMe.git cd ReMe -pip install -e packages/reme_ai_studio -e ".[core]" -cd website +pip install -e reme_studio -e ".[core]" +cd reme_studio npm ci npm run build:static cd .. diff --git a/docs/zh/agent_integration_plan.md b/docs/zh/agent_integration_plan.md index 035b1d00..25e654a2 100644 --- a/docs/zh/agent_integration_plan.md +++ b/docs/zh/agent_integration_plan.md @@ -21,7 +21,7 @@ integrations/ codex/reme/ claude_code/reme/ # 已有,增量升级 hermes_agent/ # 已有,增量升级 -packages/typescript/ # @agentscope-ai/reme:共享客户端 + DSH/OpenClaw 适配器 +typescript/ # @agentscope-ai/reme:共享客户端 + DSH/OpenClaw 适配器 skills/ reme_memory/ # 通用、无 hook 时的降级入口 ``` @@ -301,7 +301,7 @@ integrations/codex/reme/ 当前目录: ```text -packages/typescript/ +typescript/ package.json dsh/cordis.patch.yml src/core/ @@ -336,7 +336,7 @@ dsh plugin --profile web add @agentscope-ai/reme 当前 OpenClaw 入口与 DSH 入口从同一包发布: ```text -packages/typescript/ +typescript/ openclaw.plugin.json package.json src/openclaw/index.ts diff --git a/docs/zh/contributing.md b/docs/zh/contributing.md index 14271abf..2b5c65e0 100644 --- a/docs/zh/contributing.md +++ b/docs/zh/contributing.md @@ -37,8 +37,8 @@ ReMe 的核心代码位于: ```bash python -m venv .venv source .venv/bin/activate -pip install -e packages/reme_ai_studio -e ".[dev,full]" -cd website +pip install -e reme_studio -e ".[dev,full]" +cd reme_studio npm ci npm run build:static cd .. diff --git a/docs/zh/framework.md b/docs/zh/framework.md index 171e1558..b28613cf 100644 --- a/docs/zh/framework.md +++ b/docs/zh/framework.md @@ -168,8 +168,8 @@ HTTP service 行为: | `enable_serve: false` | 不注册 endpoint | HTTP service 还可以在所有 Job endpoint 注册完成后挂载 ReMe Studio 单页应用。默认 `service.web_enabled=true`;构建产物按 -`service.web_static_dir`、`REME_WEB_STATIC_DIR`、由 `web` 或 `core` extra 安装的可选 `reme-ai-studio` 包,以及源码树 -`website/dist-static` 等候选位置解析。找不到 `index.html` 时只跳过前端,Job API 仍然可用。Studio 的 `GET` fallback 不会覆盖 +`service.web_static_dir`、`REME_WEB_STATIC_DIR`、由 `web` 或 `core` extra 安装的可选 `reme_studio` 包,以及源码树 +`reme_studio/dist-static` 等候选位置解析。找不到 `index.html` 时只跳过前端,Job API 仍然可用。Studio 的 `GET` fallback 不会覆盖 已有的 `POST /`。 MCP service 行为: diff --git a/docs/zh/quick_start.md b/docs/zh/quick_start.md index b3059866..6267e2d9 100644 --- a/docs/zh/quick_start.md +++ b/docs/zh/quick_start.md @@ -15,8 +15,8 @@ pip install "reme-ai[core]" ```bash git clone https://github.com/agentscope-ai/ReMe.git cd ReMe -pip install -e packages/reme_ai_studio -e ".[core]" -cd website +pip install -e reme_studio -e ".[core]" +cd reme_studio npm ci npm run build:static cd .. diff --git a/github-pages/README.md b/github-pages/README.md index 1f4b318e..8e62b95b 100644 --- a/github-pages/README.md +++ b/github-pages/README.md @@ -2,7 +2,7 @@ This directory contains the standalone Vite documentation site published at . The GitHub Pages fallback is . It does not depend on the ReMe Studio application in -`website/`. +`reme_studio/`. ## Requirements @@ -50,7 +50,7 @@ The build script reads the canonical repository files directly. Do not edit gene - `README.md` and `README_ZH.md`: project introductions - `docs/en/` and `docs/zh/`: English and Chinese guides - `docs/figure/`: documentation images -- `website/README.md` and `website/README_ZH.md`: ReMe Studio guide +- `reme_studio/README.md` and `reme_studio/README_ZH.md`: ReMe Studio guide - `plugins/*/README*.md`: plugin and research workflow guides - `benchmark/{beam,longmemeval,pibench,toolmemory}/README*.md`: benchmark guides and results - `skills/reme_memory/SKILL.md`: ReMe Memory skill guide diff --git a/github-pages/scripts/generate-content.mjs b/github-pages/scripts/generate-content.mjs index de8a17d4..337ab033 100644 --- a/github-pages/scripts/generate-content.mjs +++ b/github-pages/scripts/generate-content.mjs @@ -57,7 +57,7 @@ const localizedTitles = { const productDocuments = [ { slug: "studio", - source: "website", + source: "reme_studio", titles: { zh: "ReMe 工作台", en: "ReMe Studio" }, descriptions: { zh: "浏览、编辑和搜索本地记忆,并探索记忆图谱。", @@ -230,8 +230,11 @@ for (const product of productDocuments) { await cp(path.join(repoDir, product.source, filename), path.join(outputDir, product.source, filename)); } } -await mkdir(path.join(outputDir, "website", "public"), { recursive: true }); -await cp(path.join(repoDir, "website", "public", "og.jpg"), path.join(outputDir, "website", "public", "og.jpg")); +await mkdir(path.join(outputDir, "reme_studio", "public"), { recursive: true }); +await cp( + path.join(repoDir, "reme_studio", "public", "og.jpg"), + path.join(outputDir, "reme_studio", "public", "og.jpg"), +); await mkdir(path.join(outputDir, "skills", "reme_memory"), { recursive: true }); await cp( path.join(repoDir, "skills", "reme_memory", "SKILL.md"), diff --git a/integrations/README.md b/integrations/README.md index 2c5800bd..853bb54f 100644 --- a/integrations/README.md +++ b/integrations/README.md @@ -5,6 +5,6 @@ plugin API, hooks, MCP configuration, or client interface, but it does not exten `reme.plugins` entry-point group. The shared TypeScript client and the DeepSeek Harness and OpenClaw adapters live in -[`../packages/typescript`](../packages/typescript/README.md). +[`../typescript`](../typescript/README.md). Installable extensions of ReMe itself belong in [`../plugins`](../plugins/README.md). diff --git a/packages/reme_ai_studio/.gitignore b/packages/reme_ai_studio/.gitignore deleted file mode 100644 index 9dc7e3d4..00000000 --- a/packages/reme_ai_studio/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/LICENSE diff --git a/packages/reme_ai_studio/README.md b/packages/reme_ai_studio/README.md deleted file mode 100644 index bda397ca..00000000 --- a/packages/reme_ai_studio/README.md +++ /dev/null @@ -1,203 +0,0 @@ -# ReMe Studio - -English | [简体中文](#简体中文) - -ReMe Studio is the local web workspace for ReMe. It lets you browse and edit user-owned workspace files, explore memory -links, and chat with the ReMe Agent without moving durable memory into a separate application database. Search indexes, -graphs, and other derived metadata remain rebuildable from the source files. - -![ReMe Studio workspace](https://raw.githubusercontent.com/agentscope-ai/ReMe/main/website/public/og.jpg) - -## Installation - -Install Studio together with ReMe's optional integrations: - -```bash -pip install "reme-ai[core]" -``` - -For Studio without the other optional integrations, use `pip install "reme-ai[web]"`. The base `reme-ai` package is -headless and does not include the frontend assets. - -## Features - -- **Workspace browsing**: browse the full workspace or focus on journal and knowledge files through dedicated views. The - navigator refreshes as files change on disk. -- **Markdown editing and preview**: open multiple files in tabs, render Markdown front matter and GitHub Flavored - Markdown, edit with Monaco, save with optimistic modification-time checks, and download files locally. -- **Memory graph**: inspect indexed wikilinks under the `wiki`, `personal`, and - `procedure` knowledge roots, follow inbound and outbound links, and open the corresponding Markdown source. -- **Agent chat**: stream conversations with the read-only workspace Agent, see tool calls and token usage, and drag - workspace files into the conversation as references. -- **Service management**: inspect service and component memory usage, review the effective redacted configuration and - version, and rebuild derived indexes without modifying source memory files. -- **Personalization**: switch between English and Chinese, and use light, dark, or system appearance. - -## Requirements - -- Python 3.11 or newer with ReMe installed. -- A running ReMe HTTP service. Agent chat additionally requires a working Agent and model configuration. -- Node.js 22.13 or newer is required only when developing or building Studio from source. - -See the [repository README](https://github.com/agentscope-ai/ReMe#readme) for ReMe installation and backend configuration. - -## Development - -Start ReMe from the repository root, then run the frontend in another terminal: - -```bash -# Terminal 1, from the repository root -reme start - -# Terminal 2 -cd website -npm install -npm run dev -``` - -Open . The frontend connects to -`http://127.0.0.1:2333` by default. Override it when needed: - -```bash -NEXT_PUBLIC_REME_API_URL=http://127.0.0.1:8000 npm run dev -``` - -## ReMe-hosted static build - -ReMe can serve Studio from the same FastAPI process as its HTTP API. Build the static variant and restart ReMe: - -```bash -cd website -npm ci -npm run build:static -cd .. -reme start -``` - -Open . The static build uses same-origin requests by default. For standalone static development, -run `npm run dev:static` and set -`VITE_REME_API_URL` to the running ReMe service URL when necessary. - -The regular `npm run build` command remains the vinext/Sites deployment build; -`npm run build:static` creates `dist-static/` exclusively for FastAPI and Python package distribution. - -## Configuration - -The workspace hides dotfiles and dot-directories. It displays only Markdown and text files by default. Configure the -allowed extensions as a comma-separated list in `.env.local`: - -```bash -NEXT_PUBLIC_REME_WORKSPACE_EXTENSIONS=md,txt,mdx -``` - -The memory graph requires an index built by ReMe. Rebuilding the index from the Studio settings regenerates derived data -from workspace files and does not modify the source memory. - -## Checks - -```bash -npm run format:check -npm run lint -npm run build -npm run build:static -npm test -``` - ---- - -# 简体中文 - -[English](#reme-studio) | 简体中文 - -ReMe Studio 是 ReMe 的本地 Web 工作区。你可以在这里浏览和编辑自己拥有的工作区文件、探索记忆之间的联系,并与 ReMe Agent -对话,而无需将持久记忆迁移到独立的应用数据库中。搜索索引、图谱和其他派生元数据均可根据源文件重建。 - -![ReMe Studio 工作区](https://raw.githubusercontent.com/agentscope-ai/ReMe/main/website/public/og.jpg) - -## 安装 - -安装 Studio 和 ReMe 的可选集成功能: - -```bash -pip install "reme-ai[core]" -``` - -如果只需要 Studio,不需要其他可选集成,可以使用 `pip install "reme-ai[web]"`。基础 `reme-ai` 包以无界面模式分发, -不包含前端资源。 - -## 功能 - -- **浏览工作区**:浏览完整工作区,或通过独立视图聚焦日记和知识文件;磁盘中的文件发生变化后,导航器会自动刷新。 -- **Markdown 编辑与预览**:在多个标签页中打开文件,渲染 Markdown front matter 和 GitHub Flavored Markdown,使用 Monaco - 编辑器编辑,通过修改时间检查安全保存,并可将文件下载到本地。 -- **记忆图谱**:查看知识库 `wiki`、`personal` 和 `procedure` 目录中已索引的 wikilink,检查入链和出链,并从图谱打开对应的 - Markdown 源文件。 -- **Agent 对话**:与只读工作区 Agent 进行流式对话,查看工具调用和 token 用量,还可将工作区文件拖入对话作为引用。 -- **服务管理**:查看服务及组件的内存使用情况、当前生效的脱敏配置和版本,并在不修改记忆源文件的情况下重建派生索引。 -- **个性化设置**:切换中英文界面,并使用浅色、深色或跟随系统的外观。 - -## 环境要求 - -- Python 3.11 或更高版本,并已安装 ReMe。 -- 正在运行的 ReMe HTTP 服务。Agent 对话还需要可用的 Agent 和模型配置。 -- 只有从源码开发或构建 Studio 时才需要 Node.js 22.13 或更高版本。 - -ReMe 的安装和后端配置请参阅[仓库中文 README](https://github.com/agentscope-ai/ReMe/blob/main/README_ZH.md)。 - -## 本地开发 - -先在仓库根目录启动 ReMe,然后在另一个终端运行前端: - -```bash -# 终端 1:仓库根目录 -reme start - -# 终端 2 -cd website -npm install -npm run dev -``` - -打开 。前端默认连接 `http://127.0.0.1:2333`,需要时可覆盖该地址: - -```bash -NEXT_PUBLIC_REME_API_URL=http://127.0.0.1:8000 npm run dev -``` - -## 由 ReMe 托管的静态构建 - -ReMe 可以通过提供 HTTP API 的同一个 FastAPI 进程托管 Studio。构建静态版本并重启 ReMe: - -```bash -cd website -npm ci -npm run build:static -cd .. -reme start -``` - -打开 。静态构建默认使用同源请求。进行独立的静态开发时,运行 -`npm run dev:static`;如有需要,将 `VITE_REME_API_URL` 设置为正在运行的 ReMe 服务地址。 - -常规的 `npm run build` 命令仍用于 vinext/Sites 部署构建;`npm run build:static` 仅为 FastAPI 和 Python 包分发生成 -`dist-static/`。 - -## 配置 - -工作区会隐藏点文件和点目录,并且默认只显示 Markdown 和文本文件。可以在 `.env.local` 中通过逗号分隔的列表配置允许显示的扩展名: - -```bash -NEXT_PUBLIC_REME_WORKSPACE_EXTENSIONS=md,txt,mdx -``` - -记忆图谱依赖 ReMe 构建的索引。在 Studio 设置中重建索引时,只会根据工作区文件重新生成派生数据,不会修改记忆源文件。 - -## 检查 - -```bash -npm run format:check -npm run lint -npm run build -npm run build:static -npm test -``` diff --git a/plugins/daily_paper/README.md b/plugins/daily_paper/README.md index 315c3c60..85c67f08 100644 --- a/plugins/daily_paper/README.md +++ b/plugins/daily_paper/README.md @@ -275,6 +275,6 @@ curl -s http://127.0.0.1:2333/daily_paper \ The focused unit tests mock Hugging Face, arXiv, AgentScope, and DingTalk boundaries and do not call real services: ```bash -python -m pip install -e packages/reme_ai_studio -e ".[dev,core]" -e plugins/daily_paper +python -m pip install -e reme_studio -e ".[dev,core]" -e plugins/daily_paper python -m pytest plugins/daily_paper -v ``` diff --git a/plugins/daily_paper/README_ZH.md b/plugins/daily_paper/README_ZH.md index 7744add9..b9b80f13 100644 --- a/plugins/daily_paper/README_ZH.md +++ b/plugins/daily_paper/README_ZH.md @@ -261,6 +261,6 @@ curl -s http://127.0.0.1:2333/daily_paper \ 单元测试会 mock Hugging Face、arXiv、AgentScope 和 DingTalk 边界,不访问真实服务: ```bash -python -m pip install -e packages/reme_ai_studio -e ".[dev,core]" -e plugins/daily_paper +python -m pip install -e reme_studio -e ".[dev,core]" -e plugins/daily_paper python -m pytest plugins/daily_paper -v ``` diff --git a/pyproject.toml b/pyproject.toml index 4dd483ab..ff04e9cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ dependencies = [ [project.optional-dependencies] web = [ - "reme-ai-studio==0.4.1.8", + "reme_studio", ] core = [ "agentscope[model-ollama]==2.0.6", @@ -57,7 +57,7 @@ core = [ "neo4j>=6.2.0", "networkx>=3.4.2", "polars>=1.43.0", - "reme-ai-studio==0.4.1.8", + "reme_studio", ] dev = [ "packaging>=24.2", @@ -79,7 +79,7 @@ Repository = "https://github.com/agentscope-ai/ReMe" reme = "reme.reme:main" [tool.setuptools] -packages = { find = { where = ["."], include = ["reme*"] } } +packages = { find = { where = ["."], include = ["reme", "reme.*"], exclude = ["reme_studio*"] } } include-package-data = true [tool.setuptools.package-data] diff --git a/reme/utils/web_static.py b/reme/utils/web_static.py index aa58f4b4..87a0b4b9 100644 --- a/reme/utils/web_static.py +++ b/reme/utils/web_static.py @@ -11,7 +11,7 @@ REME_WEB_STATIC_DIR = "REME_WEB_STATIC_DIR" def _packaged_studio_dir() -> Path | None: """Return the static directory supplied by the optional Studio package.""" try: - from reme_ai_studio import static_dir + from reme_studio import static_dir except ImportError: return None return static_dir() @@ -36,8 +36,8 @@ def resolve_web_static_dir(configured_dir: str | None = None) -> Path | None: fallback_candidates = [ _packaged_studio_dir(), package_dir / "web", - repository_dir / "website" / "dist-static", - cwd / "website" / "dist-static", + repository_dir / "reme_studio" / "dist-static", + cwd / "reme_studio" / "dist-static", cwd / "web_dist", ] for candidate in fallback_candidates: diff --git a/website/.env.example b/reme_studio/.env.example similarity index 100% rename from website/.env.example rename to reme_studio/.env.example diff --git a/website/.gitignore b/reme_studio/.gitignore similarity index 100% rename from website/.gitignore rename to reme_studio/.gitignore diff --git a/website/.openai/hosting.json b/reme_studio/.openai/hosting.json similarity index 100% rename from website/.openai/hosting.json rename to reme_studio/.openai/hosting.json diff --git a/website/.prettierignore b/reme_studio/.prettierignore similarity index 87% rename from website/.prettierignore rename to reme_studio/.prettierignore index 10f02850..8d887880 100644 --- a/website/.prettierignore +++ b/reme_studio/.prettierignore @@ -4,6 +4,7 @@ dist/ dist-static/ out/ +src/reme_studio/static/ # Dependencies node_modules/ diff --git a/reme_studio/LICENSE b/reme_studio/LICENSE new file mode 100644 index 00000000..65c2c5cf --- /dev/null +++ b/reme_studio/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2025 Alibaba Group + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/website/README.md b/reme_studio/README.md similarity index 88% rename from website/README.md rename to reme_studio/README.md index d8fda46f..ab6a7379 100644 --- a/website/README.md +++ b/reme_studio/README.md @@ -1,12 +1,12 @@ # ReMe Studio -English | [简体中文](./README_ZH.md) +English | [简体中文](https://github.com/agentscope-ai/ReMe/blob/main/reme_studio/README_ZH.md) ReMe Studio is the local web workspace for ReMe. It lets you browse and edit user-owned workspace files, explore memory links, and chat with the ReMe Agent without moving durable memory into a separate application database. Search indexes, graphs, and other derived metadata remain rebuildable from the source files. -![ReMe Studio workspace](./public/og.jpg) +![ReMe Studio workspace](https://raw.githubusercontent.com/agentscope-ai/ReMe/main/reme_studio/public/og.jpg) ## Installation @@ -19,6 +19,14 @@ pip install "reme-ai[core]" For Studio without the other optional integrations, use `pip install "reme-ai[web]"`. The base `reme-ai` package is headless and does not include the frontend assets. +The same prebuilt static workspace is available for Node.js applications: + +```bash +npm install @agentscope-ai/reme_studio +``` + +Its static entry point is installed at `@agentscope-ai/reme_studio/dist-static/index.html`. + ## Features - **Workspace browsing**: browse the full workspace or focus on journal and knowledge files through dedicated views. The @@ -50,7 +58,7 @@ Start ReMe from the repository root, then run the frontend in another terminal: reme start # Terminal 2 -cd website +cd reme_studio npm install npm run dev ``` @@ -67,7 +75,7 @@ NEXT_PUBLIC_REME_API_URL=http://127.0.0.1:8000 npm run dev ReMe can serve Studio from the same FastAPI process as its HTTP API. Build the static variant and restart ReMe: ```bash -cd website +cd reme_studio npm ci npm run build:static cd .. diff --git a/website/README_ZH.md b/reme_studio/README_ZH.md similarity index 88% rename from website/README_ZH.md rename to reme_studio/README_ZH.md index c6f813ee..d75b2b5f 100644 --- a/website/README_ZH.md +++ b/reme_studio/README_ZH.md @@ -1,11 +1,11 @@ # ReMe Studio -[English](./README.md) | 简体中文 +[English](https://github.com/agentscope-ai/ReMe/blob/main/reme_studio/README.md) | 简体中文 ReMe Studio 是 ReMe 的本地 Web 工作区。你可以在这里浏览和编辑自己拥有的工作区文件、探索记忆之间的联系,并与 ReMe Agent 对话,而无需将持久记忆迁移到独立的应用数据库中。搜索索引、图谱和其他派生元数据均可根据源文件重建。 -![ReMe Studio 工作区](./public/og.jpg) +![ReMe Studio 工作区](https://raw.githubusercontent.com/agentscope-ai/ReMe/main/reme_studio/public/og.jpg) ## 安装 @@ -18,6 +18,14 @@ pip install "reme-ai[core]" 如果只需要 Studio,不需要其他可选集成,可以使用 `pip install "reme-ai[web]"`。基础 `reme-ai` 包以无界面模式分发, 不包含前端资源。 +Node.js 应用也可以安装同一份预构建静态工作区: + +```bash +npm install @agentscope-ai/reme_studio +``` + +静态入口安装在 `@agentscope-ai/reme_studio/dist-static/index.html`。 + ## 功能 - **浏览工作区**:浏览完整工作区,或通过独立视图聚焦日记和知识文件;磁盘中的文件发生变化后,导航器会自动刷新。 @@ -46,7 +54,7 @@ ReMe 的安装和后端配置请参阅[仓库中文 README](../README_ZH.md)。 reme start # 终端 2 -cd website +cd reme_studio npm install npm run dev ``` @@ -62,7 +70,7 @@ NEXT_PUBLIC_REME_API_URL=http://127.0.0.1:8000 npm run dev ReMe 可以通过提供 HTTP API 的同一个 FastAPI 进程托管 Studio。构建静态版本并重启 ReMe: ```bash -cd website +cd reme_studio npm ci npm run build:static cd .. diff --git a/website/app/api-endpoint.ts b/reme_studio/app/api-endpoint.ts similarity index 100% rename from website/app/api-endpoint.ts rename to reme_studio/app/api-endpoint.ts diff --git a/website/app/api.ts b/reme_studio/app/api.ts similarity index 100% rename from website/app/api.ts rename to reme_studio/app/api.ts diff --git a/website/app/chat-stream.ts b/reme_studio/app/chat-stream.ts similarity index 100% rename from website/app/chat-stream.ts rename to reme_studio/app/chat-stream.ts diff --git a/website/app/chatgpt-auth.ts b/reme_studio/app/chatgpt-auth.ts similarity index 100% rename from website/app/chatgpt-auth.ts rename to reme_studio/app/chatgpt-auth.ts diff --git a/website/app/files-workspace/FilePreview.tsx b/reme_studio/app/files-workspace/FilePreview.tsx similarity index 100% rename from website/app/files-workspace/FilePreview.tsx rename to reme_studio/app/files-workspace/FilePreview.tsx diff --git a/website/app/files-workspace/FilesNavigator.tsx b/reme_studio/app/files-workspace/FilesNavigator.tsx similarity index 100% rename from website/app/files-workspace/FilesNavigator.tsx rename to reme_studio/app/files-workspace/FilesNavigator.tsx diff --git a/website/app/files-workspace/MemoryGraphView.tsx b/reme_studio/app/files-workspace/MemoryGraphView.tsx similarity index 100% rename from website/app/files-workspace/MemoryGraphView.tsx rename to reme_studio/app/files-workspace/MemoryGraphView.tsx diff --git a/website/app/files-workspace/TabbedEditor.tsx b/reme_studio/app/files-workspace/TabbedEditor.tsx similarity index 100% rename from website/app/files-workspace/TabbedEditor.tsx rename to reme_studio/app/files-workspace/TabbedEditor.tsx diff --git a/website/app/files-workspace/files-workspace.module.css b/reme_studio/app/files-workspace/files-workspace.module.css similarity index 100% rename from website/app/files-workspace/files-workspace.module.css rename to reme_studio/app/files-workspace/files-workspace.module.css diff --git a/website/app/files-workspace/get-language.ts b/reme_studio/app/files-workspace/get-language.ts similarity index 100% rename from website/app/files-workspace/get-language.ts rename to reme_studio/app/files-workspace/get-language.ts diff --git a/website/app/files-workspace/markdown.ts b/reme_studio/app/files-workspace/markdown.ts similarity index 100% rename from website/app/files-workspace/markdown.ts rename to reme_studio/app/files-workspace/markdown.ts diff --git a/website/app/files-workspace/memory-graph.module.css b/reme_studio/app/files-workspace/memory-graph.module.css similarity index 100% rename from website/app/files-workspace/memory-graph.module.css rename to reme_studio/app/files-workspace/memory-graph.module.css diff --git a/website/app/files-workspace/memory-graph.ts b/reme_studio/app/files-workspace/memory-graph.ts similarity index 100% rename from website/app/files-workspace/memory-graph.ts rename to reme_studio/app/files-workspace/memory-graph.ts diff --git a/website/app/files-workspace/panel-resize.ts b/reme_studio/app/files-workspace/panel-resize.ts similarity index 100% rename from website/app/files-workspace/panel-resize.ts rename to reme_studio/app/files-workspace/panel-resize.ts diff --git a/website/app/globals.css b/reme_studio/app/globals.css similarity index 100% rename from website/app/globals.css rename to reme_studio/app/globals.css diff --git a/website/app/i18n.ts b/reme_studio/app/i18n.ts similarity index 100% rename from website/app/i18n.ts rename to reme_studio/app/i18n.ts diff --git a/website/app/layout.tsx b/reme_studio/app/layout.tsx similarity index 100% rename from website/app/layout.tsx rename to reme_studio/app/layout.tsx diff --git a/website/app/markdown-save.ts b/reme_studio/app/markdown-save.ts similarity index 100% rename from website/app/markdown-save.ts rename to reme_studio/app/markdown-save.ts diff --git a/website/app/monaco-setup.ts b/reme_studio/app/monaco-setup.ts similarity index 100% rename from website/app/monaco-setup.ts rename to reme_studio/app/monaco-setup.ts diff --git a/website/app/page.tsx b/reme_studio/app/page.tsx similarity index 100% rename from website/app/page.tsx rename to reme_studio/app/page.tsx diff --git a/website/app/settings-center.tsx b/reme_studio/app/settings-center.tsx similarity index 100% rename from website/app/settings-center.tsx rename to reme_studio/app/settings-center.tsx diff --git a/website/app/store.ts b/reme_studio/app/store.ts similarity index 100% rename from website/app/store.ts rename to reme_studio/app/store.ts diff --git a/website/app/tab-close.ts b/reme_studio/app/tab-close.ts similarity index 100% rename from website/app/tab-close.ts rename to reme_studio/app/tab-close.ts diff --git a/website/app/theme.ts b/reme_studio/app/theme.ts similarity index 100% rename from website/app/theme.ts rename to reme_studio/app/theme.ts diff --git a/website/app/types.ts b/reme_studio/app/types.ts similarity index 100% rename from website/app/types.ts rename to reme_studio/app/types.ts diff --git a/website/app/workspace-drag.ts b/reme_studio/app/workspace-drag.ts similarity index 100% rename from website/app/workspace-drag.ts rename to reme_studio/app/workspace-drag.ts diff --git a/website/app/workspace-files.ts b/reme_studio/app/workspace-files.ts similarity index 100% rename from website/app/workspace-files.ts rename to reme_studio/app/workspace-files.ts diff --git a/website/app/workspace-persistence.ts b/reme_studio/app/workspace-persistence.ts similarity index 100% rename from website/app/workspace-persistence.ts rename to reme_studio/app/workspace-persistence.ts diff --git a/website/app/workspace.tsx b/reme_studio/app/workspace.tsx similarity index 100% rename from website/app/workspace.tsx rename to reme_studio/app/workspace.tsx diff --git a/website/cloudflare-env.d.ts b/reme_studio/cloudflare-env.d.ts similarity index 100% rename from website/cloudflare-env.d.ts rename to reme_studio/cloudflare-env.d.ts diff --git a/website/db/index.ts b/reme_studio/db/index.ts similarity index 100% rename from website/db/index.ts rename to reme_studio/db/index.ts diff --git a/website/db/schema.ts b/reme_studio/db/schema.ts similarity index 100% rename from website/db/schema.ts rename to reme_studio/db/schema.ts diff --git a/website/drizzle.config.ts b/reme_studio/drizzle.config.ts similarity index 100% rename from website/drizzle.config.ts rename to reme_studio/drizzle.config.ts diff --git a/website/drizzle/meta/_journal.json b/reme_studio/drizzle/meta/_journal.json similarity index 100% rename from website/drizzle/meta/_journal.json rename to reme_studio/drizzle/meta/_journal.json diff --git a/website/eslint.config.mjs b/reme_studio/eslint.config.mjs similarity index 86% rename from website/eslint.config.mjs rename to reme_studio/eslint.config.mjs index 6d68103b..325fa94d 100644 --- a/website/eslint.config.mjs +++ b/reme_studio/eslint.config.mjs @@ -8,7 +8,14 @@ import globals from "globals"; import tseslint from "typescript-eslint"; const eslintConfig = defineConfig([ - globalIgnores([".next/**", "dist/**", "out/**", "build/**", "next-env.d.ts"]), + globalIgnores([ + ".next/**", + "dist/**", + "out/**", + "build/**", + "src/reme_studio/static/**", + "next-env.d.ts", + ]), eslint.configs.recommended, ...tseslint.configs.recommended, react.configs.flat.recommended, diff --git a/website/examples/d1/app/api/notes/route.ts b/reme_studio/examples/d1/app/api/notes/route.ts similarity index 100% rename from website/examples/d1/app/api/notes/route.ts rename to reme_studio/examples/d1/app/api/notes/route.ts diff --git a/website/examples/d1/db/schema.ts b/reme_studio/examples/d1/db/schema.ts similarity index 100% rename from website/examples/d1/db/schema.ts rename to reme_studio/examples/d1/db/schema.ts diff --git a/website/index.html b/reme_studio/index.html similarity index 100% rename from website/index.html rename to reme_studio/index.html diff --git a/website/next-env.d.ts b/reme_studio/next-env.d.ts similarity index 100% rename from website/next-env.d.ts rename to reme_studio/next-env.d.ts diff --git a/website/next.config.ts b/reme_studio/next.config.ts similarity index 100% rename from website/next.config.ts rename to reme_studio/next.config.ts diff --git a/website/package-lock.json b/reme_studio/package-lock.json similarity index 99% rename from website/package-lock.json rename to reme_studio/package-lock.json index 2282d041..69be3024 100644 --- a/website/package-lock.json +++ b/reme_studio/package-lock.json @@ -1,28 +1,19 @@ { - "name": "reme-studio", - "version": "0.1.0", + "name": "@agentscope-ai/reme_studio", + "version": "0.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "reme-studio", - "version": "0.1.0", - "dependencies": { - "@agentscope-ai/icons": "^1.0.67", - "@monaco-editor/react": "^4.7.0", - "drizzle-orm": "0.45.2", - "lucide-react": "^1.28.0", - "monaco-editor": "^0.55.1", - "react": "19.2.8", - "react-dom": "19.2.8", - "react-markdown": "^10.1.0", - "remark-gfm": "^4.0.1", - "zustand": "^5.0.14" - }, + "name": "@agentscope-ai/reme_studio", + "version": "0.1.1", + "license": "Apache-2.0", "devDependencies": { + "@agentscope-ai/icons": "^1.0.67", "@cloudflare/vite-plugin": "1.51.3", "@cloudflare/workers-types": "^5.20260804.1", "@eslint/js": "9.39.4", + "@monaco-editor/react": "^4.7.0", "@next/eslint-plugin-next": "16.2.6", "@tailwindcss/postcss": "4.2.1", "@types/node": "22.19.19", @@ -31,19 +22,27 @@ "@vitejs/plugin-react": "6.0.2", "@vitejs/plugin-rsc": "0.5.26", "drizzle-kit": "0.31.10", + "drizzle-orm": "0.45.2", "eslint": "9.39.4", "eslint-plugin-jsx-a11y": "6.10.2", "eslint-plugin-react": "7.37.5", "eslint-plugin-react-hooks": "7.1.1", "globals": "16.4.0", + "lucide-react": "^1.28.0", + "monaco-editor": "^0.55.1", "prettier": "3.0.0", + "react": "19.2.8", + "react-dom": "19.2.8", + "react-markdown": "^10.1.0", "react-server-dom-webpack": "19.2.8", + "remark-gfm": "^4.0.1", "tailwindcss": "4.2.1", "typescript": "5.9.3", "typescript-eslint": "8.59.3", "vinext": "1.0.0-beta.2", "vite": "8.2.1", - "wrangler": "4.121.0" + "wrangler": "4.121.0", + "zustand": "^5.0.14" }, "engines": { "node": ">=22.13.0" @@ -53,6 +52,7 @@ "version": "1.0.67", "resolved": "https://registry.npmjs.org/@agentscope-ai/icons/-/icons-1.0.67.tgz", "integrity": "sha512-tbly1taaZTHcu9IdmBOWK9ZLLNZ/j2suVKqUgwR0hcr+BAN0kNT08r5sFRvpRDALcdxJdwLNzMlIv0670XfA3g==", + "dev": true, "license": "ISC" }, "node_modules/@alloc/quick-lru": { @@ -445,7 +445,7 @@ "version": "5.20260812.1", "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-5.20260812.1.tgz", "integrity": "sha512-eG2aQdUWH8RYEubpBjUE98L2G57JYzGEcI8PgROTjt9YjunbEnPBHP4371Usj8v8pTWcXtbOmI+LRCXF4KhJgQ==", - "devOptional": true, + "dev": true, "license": "MIT OR Apache-2.0" }, "node_modules/@cspotcode/source-map-support": { @@ -2238,6 +2238,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz", "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==", + "dev": true, "license": "MIT", "dependencies": { "state-local": "^1.0.6" @@ -2247,6 +2248,7 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "dev": true, "license": "MIT", "dependencies": { "@monaco-editor/loader": "^1.5.0" @@ -2988,6 +2990,7 @@ "version": "4.1.13", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, "license": "MIT", "dependencies": { "@types/ms": "*" @@ -3021,12 +3024,14 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, "license": "MIT" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "*" @@ -3036,6 +3041,7 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "*" @@ -3052,6 +3058,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "*" @@ -3061,6 +3068,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, "license": "MIT" }, "node_modules/@types/node": { @@ -3077,6 +3085,7 @@ "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -3096,6 +3105,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, "license": "MIT", "optional": true }, @@ -3103,6 +3113,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { @@ -3404,6 +3415,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "dev": true, "license": "ISC" }, "node_modules/@unpic/core": { @@ -4053,6 +4065,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4256,6 +4269,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4283,6 +4297,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4293,6 +4308,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4303,6 +4319,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4313,6 +4330,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4354,6 +4372,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -4461,6 +4480,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -4528,6 +4548,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -4545,6 +4566,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "dev": true, "license": "MIT", "dependencies": { "character-entities": "^2.0.0" @@ -4601,6 +4623,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4620,6 +4643,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, "license": "MIT", "dependencies": { "dequal": "^2.0.0" @@ -4646,6 +4670,7 @@ "version": "3.4.13", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.13.tgz", "integrity": "sha512-2vmYIoqjze2d+kakP8S/nS5shfsl587kzwEjcGlTdiksUVgFHnFCsLYDVj/JNqJVOQZGSYBTmuycv0PodwmnMQ==", + "dev": true, "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -5155,6 +5180,7 @@ "version": "0.45.2", "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.2.tgz", "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", + "dev": true, "license": "Apache-2.0", "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", @@ -5826,6 +5852,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -5867,6 +5894,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, "license": "MIT" }, "node_modules/fast-deep-equal": { @@ -6350,6 +6378,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -6377,6 +6406,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dev": true, "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" @@ -6420,6 +6450,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -6480,6 +6511,7 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "dev": true, "license": "MIT" }, "node_modules/internal-slot": { @@ -6511,6 +6543,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -6521,6 +6554,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, "license": "MIT", "dependencies": { "is-alphabetical": "^2.0.0", @@ -6670,6 +6704,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -6739,6 +6774,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -6802,6 +6838,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -7491,6 +7528,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -7524,6 +7562,7 @@ "version": "1.28.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.28.0.tgz", "integrity": "sha512-fARAFJULsGuDDydjp6+6blekG/sBIM29TerzLjc9bQUKAcEfrSc4ZQKb25KRz4OMKd87cZTb5dgq0w/T6KufVg==", + "dev": true, "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -7543,6 +7582,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -7553,6 +7593,7 @@ "version": "14.0.0", "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "dev": true, "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -7575,6 +7616,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7591,6 +7633,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -7603,6 +7646,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7627,6 +7671,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", @@ -7646,6 +7691,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7663,6 +7709,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7680,6 +7727,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7695,6 +7743,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7712,6 +7761,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7728,6 +7778,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -7746,6 +7797,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -7770,6 +7822,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dev": true, "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -7788,6 +7841,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7802,6 +7856,7 @@ "version": "13.2.1", "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "dev": true, "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -7823,6 +7878,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -7844,6 +7900,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" @@ -7875,6 +7932,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -7910,6 +7968,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -7944,6 +8003,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, "license": "MIT", "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", @@ -7964,6 +8024,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", @@ -7980,6 +8041,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -8000,6 +8062,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -8018,6 +8081,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -8035,6 +8099,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" @@ -8048,6 +8113,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -8065,6 +8131,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8086,6 +8153,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8108,6 +8176,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8128,6 +8197,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8150,6 +8220,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8172,6 +8243,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8192,6 +8264,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8211,6 +8284,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8232,6 +8306,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8252,6 +8327,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8271,6 +8347,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8293,6 +8370,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8309,6 +8387,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8325,6 +8404,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8344,6 +8424,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8363,6 +8444,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8384,6 +8466,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8406,6 +8489,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8422,6 +8506,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, "funding": [ { "type": "GitHub Sponsors", @@ -8494,6 +8579,7 @@ "version": "0.55.1", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", + "dev": true, "license": "MIT", "dependencies": { "dompurify": "3.2.7", @@ -8504,6 +8590,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/nanoid": { @@ -8776,6 +8863,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", @@ -8795,6 +8883,7 @@ "version": "2.0.11", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, "license": "MIT" }, "node_modules/path-exists": { @@ -8946,6 +9035,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -8987,6 +9077,7 @@ "version": "19.2.8", "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8996,6 +9087,7 @@ "version": "19.2.8", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "dev": true, "license": "MIT", "dependencies": { "scheduler": "^0.27.0" @@ -9015,6 +9107,7 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -9106,6 +9199,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -9124,6 +9218,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -9140,6 +9235,7 @@ "version": "11.1.2", "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "dev": true, "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -9157,6 +9253,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dev": true, "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -9373,6 +9470,7 @@ "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, "license": "MIT" }, "node_modules/schema-utils": { @@ -9687,6 +9785,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -9710,6 +9809,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "dev": true, "license": "MIT" }, "node_modules/stop-iteration-iterator": { @@ -9850,6 +9950,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dev": true, "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", @@ -9897,6 +9998,7 @@ "version": "1.1.21", "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "dev": true, "license": "MIT", "dependencies": { "style-to-object": "1.0.14" @@ -9906,6 +10008,7 @@ "version": "1.0.14", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "dev": true, "license": "MIT", "dependencies": { "inline-style-parser": "0.2.7" @@ -10112,6 +10215,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -10122,6 +10226,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "dev": true, "license": "MIT", "funding": { "type": "github", @@ -10365,6 +10470,7 @@ "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -10384,6 +10490,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -10397,6 +10504,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -10410,6 +10518,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -10423,6 +10532,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -10438,6 +10548,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -10500,6 +10611,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -10514,6 +10626,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "dev": true, "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -11865,6 +11978,7 @@ "version": "5.0.14", "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.14.tgz", "integrity": "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==", + "dev": true, "license": "MIT", "engines": { "node": ">=12.20.0" @@ -11894,6 +12008,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, "license": "MIT", "funding": { "type": "github", diff --git a/website/package.json b/reme_studio/package.json similarity index 78% rename from website/package.json rename to reme_studio/package.json index 22fc53d8..c3749952 100644 --- a/website/package.json +++ b/reme_studio/package.json @@ -1,7 +1,22 @@ { - "name": "reme-studio", - "version": "0.1.0", - "private": true, + "name": "@agentscope-ai/reme_studio", + "version": "0.1.1", + "description": "ReMe Studio web workspace and static distribution", + "license": "Apache-2.0", + "files": [ + "dist-static", + "README.md", + "README_ZH.md", + "LICENSE" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/agentscope-ai/ReMe.git", + "directory": "reme_studio" + }, "engines": { "node": ">=22.13.0" }, @@ -15,21 +30,12 @@ "lint": "eslint . --ignore-pattern dist --ignore-pattern dist-static --ignore-pattern .next", "format": "tsc --noEmit && prettier --write .", "format:check": "tsc --noEmit && prettier --check .", - "db:generate": "drizzle-kit generate" - }, - "dependencies": { - "@agentscope-ai/icons": "^1.0.67", - "@monaco-editor/react": "^4.7.0", - "drizzle-orm": "0.45.2", - "lucide-react": "^1.28.0", - "monaco-editor": "^0.55.1", - "react": "19.2.8", - "react-dom": "19.2.8", - "react-markdown": "^10.1.0", - "remark-gfm": "^4.0.1", - "zustand": "^5.0.14" + "db:generate": "drizzle-kit generate", + "prepack": "npm run build:static" }, "devDependencies": { + "@agentscope-ai/icons": "^1.0.67", + "@monaco-editor/react": "^4.7.0", "@cloudflare/vite-plugin": "1.51.3", "@cloudflare/workers-types": "^5.20260804.1", "@eslint/js": "9.39.4", @@ -40,20 +46,28 @@ "@types/react-dom": "19.2.3", "@vitejs/plugin-react": "6.0.2", "@vitejs/plugin-rsc": "0.5.26", + "drizzle-orm": "0.45.2", "drizzle-kit": "0.31.10", "eslint": "9.39.4", "eslint-plugin-jsx-a11y": "6.10.2", "eslint-plugin-react": "7.37.5", "eslint-plugin-react-hooks": "7.1.1", "globals": "16.4.0", + "lucide-react": "^1.28.0", + "monaco-editor": "^0.55.1", "prettier": "3.0.0", + "react": "19.2.8", + "react-dom": "19.2.8", + "react-markdown": "^10.1.0", "react-server-dom-webpack": "19.2.8", + "remark-gfm": "^4.0.1", "tailwindcss": "4.2.1", "typescript": "5.9.3", "typescript-eslint": "8.59.3", "vinext": "1.0.0-beta.2", "vite": "8.2.1", - "wrangler": "4.121.0" + "wrangler": "4.121.0", + "zustand": "^5.0.14" }, "overrides": { "@esbuild-kit/core-utils": { diff --git a/website/postcss.config.mjs b/reme_studio/postcss.config.mjs similarity index 100% rename from website/postcss.config.mjs rename to reme_studio/postcss.config.mjs diff --git a/website/public/favicon.svg b/reme_studio/public/favicon.svg similarity index 100% rename from website/public/favicon.svg rename to reme_studio/public/favicon.svg diff --git a/website/public/file.svg b/reme_studio/public/file.svg similarity index 100% rename from website/public/file.svg rename to reme_studio/public/file.svg diff --git a/website/public/globe.svg b/reme_studio/public/globe.svg similarity index 100% rename from website/public/globe.svg rename to reme_studio/public/globe.svg diff --git a/website/public/og.jpg b/reme_studio/public/og.jpg similarity index 100% rename from website/public/og.jpg rename to reme_studio/public/og.jpg diff --git a/website/public/window.svg b/reme_studio/public/window.svg similarity index 100% rename from website/public/window.svg rename to reme_studio/public/window.svg diff --git a/packages/reme_ai_studio/pyproject.toml b/reme_studio/pyproject.toml similarity index 73% rename from packages/reme_ai_studio/pyproject.toml rename to reme_studio/pyproject.toml index 67878504..4b201305 100644 --- a/packages/reme_ai_studio/pyproject.toml +++ b/reme_studio/pyproject.toml @@ -1,6 +1,6 @@ [project] -name = "reme-ai-studio" -version = "0.4.1.8" +name = "reme_studio" +version = "0.1.1" description = "Optional ReMe Studio static frontend." readme = "README.md" license = "Apache-2.0" @@ -8,17 +8,17 @@ license-files = ["LICENSE"] requires-python = ">=3.11" [project.urls] -Homepage = "https://github.com/agentscope-ai/ReMe/tree/main/website" +Homepage = "https://github.com/agentscope-ai/ReMe/tree/main/reme_studio" Documentation = "https://reme.agentscope.io" Repository = "https://github.com/agentscope-ai/ReMe" [tool.setuptools] package-dir = { "" = "src" } -packages = ["reme_ai_studio"] +packages = ["reme_studio"] include-package-data = false [tool.setuptools.package-data] -"reme_ai_studio" = ["static/**"] +"reme_studio" = ["static/**"] [build-system] requires = ["setuptools>=77", "wheel"] diff --git a/packages/reme_ai_studio/src/reme_ai_studio/__init__.py b/reme_studio/src/reme_studio/__init__.py similarity index 100% rename from packages/reme_ai_studio/src/reme_ai_studio/__init__.py rename to reme_studio/src/reme_studio/__init__.py diff --git a/packages/reme_ai_studio/src/reme_ai_studio/static/.gitignore b/reme_studio/src/reme_studio/static/.gitignore similarity index 100% rename from packages/reme_ai_studio/src/reme_ai_studio/static/.gitignore rename to reme_studio/src/reme_studio/static/.gitignore diff --git a/website/static/main.tsx b/reme_studio/static/main.tsx similarity index 100% rename from website/static/main.tsx rename to reme_studio/static/main.tsx diff --git a/website/static/next-dynamic.tsx b/reme_studio/static/next-dynamic.tsx similarity index 100% rename from website/static/next-dynamic.tsx rename to reme_studio/static/next-dynamic.tsx diff --git a/website/tests/api-endpoint.test.mjs b/reme_studio/tests/api-endpoint.test.mjs similarity index 100% rename from website/tests/api-endpoint.test.mjs rename to reme_studio/tests/api-endpoint.test.mjs diff --git a/website/tests/chat-stream.test.mjs b/reme_studio/tests/chat-stream.test.mjs similarity index 100% rename from website/tests/chat-stream.test.mjs rename to reme_studio/tests/chat-stream.test.mjs diff --git a/website/tests/files-workspace.test.mjs b/reme_studio/tests/files-workspace.test.mjs similarity index 100% rename from website/tests/files-workspace.test.mjs rename to reme_studio/tests/files-workspace.test.mjs diff --git a/website/tests/i18n.test.mjs b/reme_studio/tests/i18n.test.mjs similarity index 100% rename from website/tests/i18n.test.mjs rename to reme_studio/tests/i18n.test.mjs diff --git a/website/tests/markdown-save.test.mjs b/reme_studio/tests/markdown-save.test.mjs similarity index 100% rename from website/tests/markdown-save.test.mjs rename to reme_studio/tests/markdown-save.test.mjs diff --git a/website/tests/memory-graph.test.mjs b/reme_studio/tests/memory-graph.test.mjs similarity index 100% rename from website/tests/memory-graph.test.mjs rename to reme_studio/tests/memory-graph.test.mjs diff --git a/website/tests/rendered-html.test.mjs b/reme_studio/tests/rendered-html.test.mjs similarity index 100% rename from website/tests/rendered-html.test.mjs rename to reme_studio/tests/rendered-html.test.mjs diff --git a/website/tests/static-build.test.mjs b/reme_studio/tests/static-build.test.mjs similarity index 100% rename from website/tests/static-build.test.mjs rename to reme_studio/tests/static-build.test.mjs diff --git a/website/tests/tab-close.test.mjs b/reme_studio/tests/tab-close.test.mjs similarity index 100% rename from website/tests/tab-close.test.mjs rename to reme_studio/tests/tab-close.test.mjs diff --git a/website/tests/workspace-drag.test.mjs b/reme_studio/tests/workspace-drag.test.mjs similarity index 100% rename from website/tests/workspace-drag.test.mjs rename to reme_studio/tests/workspace-drag.test.mjs diff --git a/website/tests/workspace-files.test.mjs b/reme_studio/tests/workspace-files.test.mjs similarity index 100% rename from website/tests/workspace-files.test.mjs rename to reme_studio/tests/workspace-files.test.mjs diff --git a/website/tests/workspace-persistence.test.mjs b/reme_studio/tests/workspace-persistence.test.mjs similarity index 100% rename from website/tests/workspace-persistence.test.mjs rename to reme_studio/tests/workspace-persistence.test.mjs diff --git a/website/build/sites-vite-plugin.ts b/reme_studio/tooling/sites-vite-plugin.ts similarity index 100% rename from website/build/sites-vite-plugin.ts rename to reme_studio/tooling/sites-vite-plugin.ts diff --git a/website/tsconfig.json b/reme_studio/tsconfig.json similarity index 100% rename from website/tsconfig.json rename to reme_studio/tsconfig.json diff --git a/website/vite.config.ts b/reme_studio/vite.config.ts similarity index 96% rename from website/vite.config.ts rename to reme_studio/vite.config.ts index ae08f936..cba8eb80 100644 --- a/website/vite.config.ts +++ b/reme_studio/vite.config.ts @@ -1,7 +1,7 @@ import vinext from "vinext"; import { defineConfig } from "vite"; import hostingConfig from "./.openai/hosting.json"; -import { sites } from "./build/sites-vite-plugin"; +import { sites } from "./tooling/sites-vite-plugin"; const SITE_CREATOR_PLACEHOLDER_DATABASE_ID = "00000000-0000-4000-8000-000000000000"; diff --git a/website/vite.static.config.ts b/reme_studio/vite.static.config.ts similarity index 100% rename from website/vite.static.config.ts rename to reme_studio/vite.static.config.ts diff --git a/website/worker/index.ts b/reme_studio/worker/index.ts similarity index 100% rename from website/worker/index.ts rename to reme_studio/worker/index.ts diff --git a/scripts/bump_version.py b/scripts/bump_version.py index 587ca90b..9a398774 100644 --- a/scripts/bump_version.py +++ b/scripts/bump_version.py @@ -1,4 +1,4 @@ -"""Validate or update the ReMe and ReMe Studio release version.""" +"""Validate or update the ReMe release version.""" from __future__ import annotations @@ -6,7 +6,6 @@ import argparse import os import re import tempfile -import tomllib from pathlib import Path from packaging.version import InvalidVersion, Version @@ -14,15 +13,10 @@ from packaging.version import InvalidVersion, Version REPOSITORY_DIR = Path(__file__).resolve().parents[1] _VERSION_PATTERN = re.compile(r'(?m)^__version__ = "(?P[^"]+)"$') -_STUDIO_VERSION_PATTERN = re.compile(r'(?m)^version = "(?P[^"]+)"$') -def _paths(repository: Path) -> tuple[Path, Path, Path]: - return ( - repository / "reme" / "__init__.py", - repository / "pyproject.toml", - repository / "packages" / "reme_ai_studio" / "pyproject.toml", - ) +def _version_file(repository: Path) -> Path: + return repository / "reme" / "__init__.py" def _canonical_version(value: str) -> str: @@ -38,40 +32,13 @@ def _canonical_version(value: str) -> str: return canonical -def _read_toml(source: Path) -> dict: - """Read one TOML file or identify the file that needs correction.""" - try: - return tomllib.loads(source.read_text(encoding="utf-8")) - except (OSError, UnicodeError, tomllib.TOMLDecodeError) as error: - raise ValueError(f"{source}: cannot read valid TOML ({error}). Fix this file and retry.") from error - - -def _required_table(config: dict, keys: tuple[str, ...], source: Path) -> dict: - """Return a required TOML table or explain where to add it.""" - value: object = config - for key in keys: - if not isinstance(value, dict) or key not in value: - table = ".".join(keys) - raise ValueError(f"{source}: missing or invalid [{table}] table. Add or fix this table and retry.") - value = value[key] - if not isinstance(value, dict): - table = ".".join(keys) - raise ValueError(f"{source}: [{table}] must be a TOML table. Fix this table and retry.") - return value - - -def _match_version(text: str, pattern: re.Pattern[str], source: Path) -> str: - matches = list(pattern.finditer(text)) +def _match_version(text: str, source: Path) -> str: + matches = list(_VERSION_PATTERN.finditer(text)) if len(matches) != 1: raise ValueError(f"Expected exactly one version declaration in {source}, found {len(matches)}.") return matches[0].group("version") -def _replace_version(text: str, pattern: re.Pattern[str], version: str, source: Path) -> str: - _match_version(text, pattern, source) - return pattern.sub(lambda match: match.group(0).replace(match.group("version"), version), text) - - def _write_atomic(path: Path, content: str) -> None: """Replace one text file without exposing a partially written file.""" temporary_name: str | None = None @@ -87,9 +54,9 @@ def _write_atomic(path: Path, content: str) -> None: def read_version(repository: Path = REPOSITORY_DIR) -> str: - """Read and validate the main distribution version.""" - version_file, _, _ = _paths(repository) - version = _match_version(version_file.read_text(encoding="utf-8"), _VERSION_PATTERN, version_file) + """Read and validate the ReMe distribution version.""" + version_file = _version_file(repository) + version = _match_version(version_file.read_text(encoding="utf-8"), version_file) try: return _canonical_version(version) except ValueError as error: @@ -97,108 +64,59 @@ def read_version(repository: Path = REPOSITORY_DIR) -> str: def check_versions(repository: Path = REPOSITORY_DIR, expected_version: str | None = None) -> str: - """Validate both distributions and their exact optional-dependency pins.""" - version_file, main_config_file, studio_config_file = _paths(repository) + """Validate the ReMe version and an optional release tag.""" version = read_version(repository) - main_config = _read_toml(main_config_file) - studio_config = _read_toml(studio_config_file) - dependency = f"reme-ai-studio=={version}" - optional_dependencies = _required_table(main_config, ("project", "optional-dependencies"), main_config_file) - studio_project = _required_table(studio_config, ("project",), studio_config_file) - problems: list[str] = [] - - studio_version = studio_project.get("version") - if studio_version != version: - problems.append(f"{studio_config_file}: project.version is {studio_version!r}; expected {version!r}") - if optional_dependencies.get("web") != [dependency]: - problems.append(f"{main_config_file}: web must be exactly [{dependency!r}]") - core_dependencies = optional_dependencies.get("core") - if not isinstance(core_dependencies, list) or core_dependencies.count(dependency) != 1: - problems.append(f"{main_config_file}: core must contain {dependency!r} exactly once") - - expected = None - if expected_version is not None: - expected = _canonical_version(expected_version.removeprefix("v")) - if version != expected: - problems.append(f"{version_file}: package version is {version!r}; release expects {expected!r}") - - if problems: - details = "\n".join(f"- {problem}" for problem in problems) - raise ValueError( - "Version metadata is inconsistent:\n" - f"{details}\n" - f"Fix the listed values, or run `python scripts/bump_version.py {expected or version}` " - "after restoring a consistent current version.", - ) + if expected_version is None: + return version + expected = _canonical_version(expected_version.removeprefix("v")) + if version != expected: + version_file = _version_file(repository) + raise ValueError(f"{version_file}: package version is {version!r}; release expects {expected!r}") return version def bump_version(version: str, repository: Path = REPOSITORY_DIR) -> str: - """Update every release version, rolling back if any write or validation fails.""" + """Update the ReMe version without coupling independently released packages.""" version = _canonical_version(version) - current_version = check_versions(repository) - version_file, main_config_file, studio_config_file = _paths(repository) - paths = (version_file, main_config_file, studio_config_file) - original = {path: path.read_text(encoding="utf-8") for path in paths} - current_dependency = f"reme-ai-studio=={current_version}" - - main_text = original[main_config_file] - if main_text.count(current_dependency) != 2: - raise ValueError(f"Expected exactly two {current_dependency!r} pins in {main_config_file}.") - updated = { - version_file: _replace_version(original[version_file], _VERSION_PATTERN, version, version_file), - main_config_file: main_text.replace(current_dependency, f"reme-ai-studio=={version}"), - studio_config_file: _replace_version( - original[studio_config_file], - _STUDIO_VERSION_PATTERN, - version, - studio_config_file, - ), - } - - written: list[Path] = [] + previous_version = read_version(repository) + version_file = _version_file(repository) + original = version_file.read_text(encoding="utf-8") + _match_version(original, version_file) + updated = _VERSION_PATTERN.sub( + lambda match: match.group(0).replace(match.group("version"), version), + original, + ) + _write_atomic(version_file, updated) try: - for path in paths: - _write_atomic(path, updated[path]) - written.append(path) check_versions(repository, version) except BaseException as error: - rollback_errors: list[str] = [] - for path in reversed(written): - try: - _write_atomic(path, original[path]) - except OSError as rollback_error: - rollback_errors.append(f"{path}: {rollback_error}") - if rollback_errors: - raise RuntimeError( - "Version update failed and rollback was incomplete. Restore these files from Git:\n- " - + "\n- ".join(rollback_errors), - ) from error - raise RuntimeError( - "Version update failed; all changed files were restored. Fix the error and retry.", - ) from error - return current_version + try: + _write_atomic(version_file, original) + except OSError as rollback_error: + raise RuntimeError(f"Version update failed and rollback was incomplete: {version_file}") from rollback_error + raise RuntimeError("Version update failed; the previous version was restored.") from error + return previous_version def main() -> None: """Run the version validation or update command.""" parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("version", nargs="?", help="New version for both distributions, for example 0.4.1.8") - parser.add_argument("--check", action="store_true", help="Validate versions without changing files") + parser.add_argument("version", nargs="?", help="New ReMe version, for example 0.4.1.8") + parser.add_argument("--check", action="store_true", help="Validate the version without changing files") parser.add_argument("--expected-version", help="Also require this release/tag version; a leading v is accepted") args = parser.parse_args() if args.check: if args.version: parser.error("version cannot be used with --check; use --expected-version") version = check_versions(expected_version=args.expected_version) - print(f"Release versions are consistent: {version}") + print(f"ReMe release version is valid: {version}") return if args.expected_version: parser.error("--expected-version requires --check") if not args.version: parser.error("provide a version to update, or use --check") previous_version = bump_version(args.version) - print(f"Updated ReMe and ReMe Studio from {previous_version} to {args.version}") + print(f"Updated ReMe from {previous_version} to {args.version}") if __name__ == "__main__": diff --git a/scripts/package_studio.py b/scripts/package_studio.py index 96396bc9..d8549e7b 100644 --- a/scripts/package_studio.py +++ b/scripts/package_studio.py @@ -1,48 +1,21 @@ -"""Prepare the optional ReMe Studio Python distribution.""" +"""Stage the ReMe Studio static build for its Python distribution.""" from __future__ import annotations -import argparse import shutil from pathlib import Path REPOSITORY_DIR = Path(__file__).resolve().parents[1] -WEBSITE_DIR = REPOSITORY_DIR / "website" -PACKAGE_DIR = REPOSITORY_DIR / "packages" / "reme_ai_studio" -STATIC_DIR = PACKAGE_DIR / "src" / "reme_ai_studio" / "static" +STUDIO_DIR = REPOSITORY_DIR / "reme_studio" +STATIC_DIR = STUDIO_DIR / "src" / "reme_studio" / "static" LICENSE_FILE = REPOSITORY_DIR / "LICENSE" STATIC_GITIGNORE = "*\n!.gitignore\n" -_RAW_WEBSITE_URL = "https://raw.githubusercontent.com/agentscope-ai/ReMe/main/website" -_REPOSITORY_URL = "https://github.com/agentscope-ai/ReMe" - -def build_readme() -> str: - """Compose the PyPI description from the English and Chinese Studio docs.""" - english = (WEBSITE_DIR / "README.md").read_text(encoding="utf-8") - chinese = (WEBSITE_DIR / "README_ZH.md").read_text(encoding="utf-8") - english = english.replace("English | [简体中文](./README_ZH.md)", "English | [简体中文](#简体中文)") - chinese = chinese.replace( - "# ReMe Studio\n\n[English](./README.md) | 简体中文", - "# 简体中文\n\n[English](#reme-studio) | 简体中文", - ) - for relative, absolute in { - "./public/og.jpg": f"{_RAW_WEBSITE_URL}/public/og.jpg", - "../README.md": f"{_REPOSITORY_URL}#readme", - "../README_ZH.md": f"{_REPOSITORY_URL}/blob/main/README_ZH.md", - }.items(): - english = english.replace(relative, absolute) - chinese = chinese.replace(relative, absolute) - return f"{english.rstrip()}\n\n---\n\n{chinese.rstrip()}\n" - - -def prepare_package(*, copy_static: bool = True) -> None: - """Generate package metadata files and optionally stage the static build.""" - (PACKAGE_DIR / "README.md").write_text(build_readme(), encoding="utf-8") - shutil.copyfile(LICENSE_FILE, PACKAGE_DIR / "LICENSE") - if not copy_static: - return - source = WEBSITE_DIR / "dist-static" +def prepare_package() -> None: + """Copy generated assets into the importable Python package.""" + shutil.copyfile(LICENSE_FILE, STUDIO_DIR / "LICENSE") + source = STUDIO_DIR / "dist-static" if not (source / "index.html").is_file(): raise FileNotFoundError(f"Studio static build is unavailable: {source}") try: @@ -55,10 +28,7 @@ def prepare_package(*, copy_static: bool = True) -> None: def main() -> None: """Run the package preparation command.""" - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("--readme-only", action="store_true", help="Generate only the PyPI README") - args = parser.parse_args() - prepare_package(copy_static=not args.readme_only) + prepare_package() if __name__ == "__main__": diff --git a/tests/unit/test_http_web_workspace.py b/tests/unit/test_http_web_workspace.py index 891f943a..709214e4 100644 --- a/tests/unit/test_http_web_workspace.py +++ b/tests/unit/test_http_web_workspace.py @@ -106,8 +106,8 @@ def test_static_dir_configuration_precedes_environment(monkeypatch, tmp_path: Pa def test_static_dir_uses_optional_studio_package(monkeypatch, tmp_path: Path) -> None: """Use static assets supplied by the separately installed Studio wheel.""" static_dir = _static_build(tmp_path / "studio") - studio = ModuleType("reme_ai_studio") + studio = ModuleType("reme_studio") studio.static_dir = lambda: static_dir # type: ignore[attr-defined] - monkeypatch.setitem(sys.modules, "reme_ai_studio", studio) + monkeypatch.setitem(sys.modules, "reme_studio", studio) assert resolve_web_static_dir() == static_dir.resolve() diff --git a/tests/unit/test_package_versions.py b/tests/unit/test_package_versions.py index 833509de..2b631d5a 100644 --- a/tests/unit/test_package_versions.py +++ b/tests/unit/test_package_versions.py @@ -1,6 +1,7 @@ -"""Keep the separately published distributions version-compatible.""" +"""Validate independently published package metadata and release helpers.""" import importlib.util +import json from pathlib import Path import tomllib from types import ModuleType @@ -25,72 +26,43 @@ bump_version = _load_script("bump_version") package_studio = _load_script("package_studio") -def test_studio_package_and_extra_versions_match_reme() -> None: - """Require one version bump to update both wheels and their exact pin.""" +def test_studio_packages_have_independent_identity() -> None: + """Keep both Studio distributions independent from the ReMe release version.""" main_config = tomllib.loads((REPOSITORY / "pyproject.toml").read_text(encoding="utf-8")) - studio_config = tomllib.loads( - (REPOSITORY / "packages" / "reme_ai_studio" / "pyproject.toml").read_text(encoding="utf-8"), - ) - version = bump_version.read_version(REPOSITORY) - expected_dependency = f"reme-ai-studio=={version}" + studio_config = tomllib.loads((REPOSITORY / "reme_studio" / "pyproject.toml").read_text(encoding="utf-8")) + npm_config = json.loads((REPOSITORY / "reme_studio" / "package.json").read_text(encoding="utf-8")) - assert studio_config["project"]["version"] == version - assert main_config["project"]["optional-dependencies"]["web"] == [expected_dependency] - assert expected_dependency in main_config["project"]["optional-dependencies"]["core"] + assert studio_config["project"]["name"] == "reme_studio" + assert npm_config["name"] == "@agentscope-ai/reme_studio" + assert studio_config["project"]["version"] == npm_config["version"] + assert main_config["project"]["optional-dependencies"]["web"] == ["reme_studio"] + assert main_config["project"]["optional-dependencies"]["core"].count("reme_studio") == 1 + assert main_config["tool"]["setuptools"]["packages"]["find"]["include"] == ["reme", "reme.*"] + assert "reme_studio*" in main_config["tool"]["setuptools"]["packages"]["find"]["exclude"] -def _write_version_fixture(repository: Path, *, studio_version: str = "1.2.3") -> None: +def _write_version_fixture(repository: Path) -> None: (repository / "reme").mkdir() - (repository / "packages" / "reme_ai_studio").mkdir(parents=True) (repository / "reme" / "__init__.py").write_text('__version__ = "1.2.3"\n', encoding="utf-8") - (repository / "pyproject.toml").write_text( - """[project] -name = "reme-ai" - -[project.optional-dependencies] -web = ["reme-ai-studio==1.2.3"] -core = ["example", "reme-ai-studio==1.2.3"] -""", - encoding="utf-8", - ) - (repository / "packages" / "reme_ai_studio" / "pyproject.toml").write_text( - f'[project]\nname = "reme-ai-studio"\nversion = "{studio_version}"\n', - encoding="utf-8", - ) -def test_bump_version_updates_both_packages_and_exact_pins(tmp_path: Path) -> None: - """Update the two package versions and both dependency declarations together.""" +def test_bump_version_updates_only_reme(tmp_path: Path) -> None: + """Do not couple an independent Studio release to the ReMe version helper.""" _write_version_fixture(tmp_path) + studio_config = tmp_path / "reme_studio" / "pyproject.toml" + studio_config.parent.mkdir() + studio_config.write_text('[project]\nname = "reme_studio"\nversion = "0.1.0"\n', encoding="utf-8") previous_version = bump_version.bump_version("1.2.4", tmp_path) assert previous_version == "1.2.3" assert (tmp_path / "reme" / "__init__.py").read_text(encoding="utf-8") == '__version__ = "1.2.4"\n' - assert (tmp_path / "pyproject.toml").read_text(encoding="utf-8").count("reme-ai-studio==1.2.4") == 2 - studio_config = tomllib.loads( - (tmp_path / "packages" / "reme_ai_studio" / "pyproject.toml").read_text(encoding="utf-8"), - ) - assert studio_config["project"]["version"] == "1.2.4" - - -def test_bump_version_rejects_inconsistent_sources_before_writing( - tmp_path: Path, -) -> None: - """Refuse to update any file if the current release metadata has drifted.""" - _write_version_fixture(tmp_path, studio_version="1.2.2") - version_file = tmp_path / "reme" / "__init__.py" - original_version_text = version_file.read_text(encoding="utf-8") - - with pytest.raises(ValueError, match=r"project.version is '1.2.2'; expected '1.2.3'"): - bump_version.bump_version("1.2.4", tmp_path) - - assert version_file.read_text(encoding="utf-8") == original_version_text + assert 'version = "0.1.0"' in studio_config.read_text(encoding="utf-8") @pytest.mark.parametrize("version", ["release", "1..2", "1.2.3_"]) def test_bump_version_rejects_invalid_pep440_versions(tmp_path: Path, version: str) -> None: - """Reject invalid release versions before changing any source file.""" + """Reject invalid release versions before changing the source file.""" _write_version_fixture(tmp_path) version_file = tmp_path / "reme" / "__init__.py" original_version_text = version_file.read_text(encoding="utf-8") @@ -119,67 +91,44 @@ def test_read_version_identifies_invalid_source_file(tmp_path: Path) -> None: bump_version.check_versions(tmp_path) -def test_check_versions_identifies_invalid_toml_file(tmp_path: Path) -> None: - """Point maintainers to malformed package metadata.""" +def test_bump_version_rolls_back_when_validation_fails(monkeypatch, tmp_path: Path) -> None: + """Restore the previous version if post-write validation fails.""" _write_version_fixture(tmp_path) - config_file = tmp_path / "pyproject.toml" - config_file.write_text("[project\n", encoding="utf-8") + version_file = tmp_path / "reme" / "__init__.py" + original = version_file.read_text(encoding="utf-8") - with pytest.raises(ValueError, match=rf"{config_file}.*cannot read valid TOML.*Fix this file"): - bump_version.check_versions(tmp_path) + def fail_validation(*_args, **_kwargs) -> None: + raise ValueError + monkeypatch.setattr(bump_version, "check_versions", fail_validation) -def test_check_versions_identifies_missing_table(tmp_path: Path) -> None: - """Explain which required TOML table must be restored.""" - _write_version_fixture(tmp_path) - config_file = tmp_path / "pyproject.toml" - config_file.write_text('[project]\nname = "reme-ai"\n', encoding="utf-8") - - with pytest.raises(ValueError, match=rf"{config_file}.*\[project.optional-dependencies\].*Add or fix"): - bump_version.check_versions(tmp_path) - - -def test_bump_version_rolls_back_when_a_write_fails(monkeypatch, tmp_path: Path) -> None: - """Restore earlier files when a later atomic replacement fails.""" - # pylint: disable=protected-access - _write_version_fixture(tmp_path) - paths = bump_version._paths(tmp_path) - original = {path: path.read_text(encoding="utf-8") for path in paths} - write_atomic = bump_version._write_atomic - attempts = 0 - - def fail_second_write(path: Path, content: str) -> None: - nonlocal attempts - attempts += 1 - if attempts == 2: - raise OSError("simulated write failure") - write_atomic(path, content) - - monkeypatch.setattr(bump_version, "_write_atomic", fail_second_write) - - with pytest.raises(RuntimeError, match="all changed files were restored"): + with pytest.raises(RuntimeError, match="previous version was restored"): bump_version.bump_version("1.2.4", tmp_path) - assert {path: path.read_text(encoding="utf-8") for path in paths} == original + assert version_file.read_text(encoding="utf-8") == original -def test_studio_readme_is_generated_from_website_docs() -> None: - """Keep the packaged PyPI description synchronized with the source docs.""" - packaged_readme = REPOSITORY / "packages" / "reme_ai_studio" / "README.md" - assert packaged_readme.read_text(encoding="utf-8") == package_studio.build_readme() +def _studio_package_fixture(monkeypatch, tmp_path: Path) -> tuple[Path, Path]: + studio_dir = tmp_path / "reme_studio" + source_dir = studio_dir / "dist-static" + source_dir.mkdir(parents=True) + (source_dir / "index.html").write_text("", encoding="utf-8") + static_dir = studio_dir / "src" / "reme_studio" / "static" + license_file = tmp_path / "LICENSE" + license_file.write_text("test license\n", encoding="utf-8") + monkeypatch.setattr(package_studio, "STUDIO_DIR", studio_dir) + monkeypatch.setattr(package_studio, "STATIC_DIR", static_dir) + monkeypatch.setattr(package_studio, "LICENSE_FILE", license_file) + return studio_dir, static_dir def test_studio_package_preparation_copies_license(monkeypatch, tmp_path: Path) -> None: """Include the repository license in the independently distributed Studio package.""" - package_dir = tmp_path / "reme_ai_studio" - package_dir.mkdir() - monkeypatch.setattr(package_studio, "PACKAGE_DIR", package_dir) + studio_dir, _ = _studio_package_fixture(monkeypatch, tmp_path) - package_studio.prepare_package(copy_static=False) + package_studio.prepare_package() - assert (package_dir / "LICENSE").read_text(encoding="utf-8") == (REPOSITORY / "LICENSE").read_text( - encoding="utf-8", - ) + assert (studio_dir / "LICENSE").read_text(encoding="utf-8") == "test license\n" def test_auto_fin_license_matches_repository() -> None: @@ -218,20 +167,7 @@ def test_daily_paper_declares_runtime_dependencies() -> None: def test_studio_package_preparation_preserves_static_gitignore(monkeypatch, tmp_path: Path) -> None: """Keep generated static assets ignored after staging the Studio build.""" - package_dir = tmp_path / "reme_ai_studio" - package_dir.mkdir() - website_dir = tmp_path / "website" - source_dir = website_dir / "dist-static" - source_dir.mkdir(parents=True) - (source_dir / "index.html").write_text("", encoding="utf-8") - static_dir = package_dir / "src" / "reme_ai_studio" / "static" - static_dir.mkdir(parents=True) - (static_dir / ".gitignore").write_text(package_studio.STATIC_GITIGNORE, encoding="utf-8") - - monkeypatch.setattr(package_studio, "PACKAGE_DIR", package_dir) - monkeypatch.setattr(package_studio, "WEBSITE_DIR", website_dir) - monkeypatch.setattr(package_studio, "STATIC_DIR", static_dir) - monkeypatch.setattr(package_studio, "build_readme", lambda: "# ReMe Studio\n") + _, static_dir = _studio_package_fixture(monkeypatch, tmp_path) package_studio.prepare_package() diff --git a/packages/typescript/.prettierignore b/typescript/.prettierignore similarity index 100% rename from packages/typescript/.prettierignore rename to typescript/.prettierignore diff --git a/packages/typescript/README.md b/typescript/README.md similarity index 99% rename from packages/typescript/README.md rename to typescript/README.md index 268c2069..b1ca5e9c 100644 --- a/packages/typescript/README.md +++ b/typescript/README.md @@ -122,7 +122,7 @@ Host code is available only through `@agentscope-ai/reme/dsh` and `@agentscope-a ## Development ```bash -cd packages/typescript +cd typescript npm ci npm run format:check npm run lint diff --git a/packages/typescript/README_ZH.md b/typescript/README_ZH.md similarity index 99% rename from packages/typescript/README_ZH.md rename to typescript/README_ZH.md index 90213c9a..4e5ec318 100644 --- a/packages/typescript/README_ZH.md +++ b/typescript/README_ZH.md @@ -56,7 +56,7 @@ import { ReMeClient, formatReMeContext } from "@agentscope-ai/reme"; ## 开发与发布检查 ```bash -cd packages/typescript +cd typescript npm ci npm run format:check npm run lint diff --git a/packages/typescript/dsh/cordis.patch.yml b/typescript/dsh/cordis.patch.yml similarity index 100% rename from packages/typescript/dsh/cordis.patch.yml rename to typescript/dsh/cordis.patch.yml diff --git a/packages/typescript/eslint.config.mjs b/typescript/eslint.config.mjs similarity index 100% rename from packages/typescript/eslint.config.mjs rename to typescript/eslint.config.mjs diff --git a/packages/typescript/openclaw.plugin.json b/typescript/openclaw.plugin.json similarity index 100% rename from packages/typescript/openclaw.plugin.json rename to typescript/openclaw.plugin.json diff --git a/packages/typescript/package-lock.json b/typescript/package-lock.json similarity index 99% rename from packages/typescript/package-lock.json rename to typescript/package-lock.json index 8aa267c6..8fca1497 100644 --- a/packages/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "@agentscope-ai/reme", - "version": "0.1.0", + "version": "0.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@agentscope-ai/reme", - "version": "0.1.0", + "version": "0.1.1", "license": "Apache-2.0", "dependencies": { "typebox": "1.3.19" diff --git a/packages/typescript/package.json b/typescript/package.json similarity index 98% rename from packages/typescript/package.json rename to typescript/package.json index 993e63ab..8c20d7c7 100644 --- a/packages/typescript/package.json +++ b/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@agentscope-ai/reme", - "version": "0.1.0", + "version": "0.1.1", "description": "ReMe client and memory integrations for TypeScript agents", "type": "module", "main": "./dist/index.js", @@ -139,7 +139,7 @@ "repository": { "type": "git", "url": "git+https://github.com/agentscope-ai/ReMe.git", - "directory": "packages/typescript" + "directory": "typescript" }, "keywords": [ "reme", diff --git a/packages/typescript/scripts/build-client.mjs b/typescript/scripts/build-client.mjs similarity index 100% rename from packages/typescript/scripts/build-client.mjs rename to typescript/scripts/build-client.mjs diff --git a/packages/typescript/scripts/test-package.mjs b/typescript/scripts/test-package.mjs similarity index 100% rename from packages/typescript/scripts/test-package.mjs rename to typescript/scripts/test-package.mjs diff --git a/packages/typescript/src/core/client.ts b/typescript/src/core/client.ts similarity index 100% rename from packages/typescript/src/core/client.ts rename to typescript/src/core/client.ts diff --git a/packages/typescript/src/core/context.ts b/typescript/src/core/context.ts similarity index 100% rename from packages/typescript/src/core/context.ts rename to typescript/src/core/context.ts diff --git a/packages/typescript/src/core/guidance.ts b/typescript/src/core/guidance.ts similarity index 100% rename from packages/typescript/src/core/guidance.ts rename to typescript/src/core/guidance.ts diff --git a/packages/typescript/src/core/scheduling.ts b/typescript/src/core/scheduling.ts similarity index 100% rename from packages/typescript/src/core/scheduling.ts rename to typescript/src/core/scheduling.ts diff --git a/packages/typescript/src/core/types.ts b/typescript/src/core/types.ts similarity index 100% rename from packages/typescript/src/core/types.ts rename to typescript/src/core/types.ts diff --git a/packages/typescript/src/dsh/client/frontmatter.ts b/typescript/src/dsh/client/frontmatter.ts similarity index 100% rename from packages/typescript/src/dsh/client/frontmatter.ts rename to typescript/src/dsh/client/frontmatter.ts diff --git a/packages/typescript/src/dsh/client/index.tsx b/typescript/src/dsh/client/index.tsx similarity index 100% rename from packages/typescript/src/dsh/client/index.tsx rename to typescript/src/dsh/client/index.tsx diff --git a/packages/typescript/src/dsh/client/status-page.tsx b/typescript/src/dsh/client/status-page.tsx similarity index 100% rename from packages/typescript/src/dsh/client/status-page.tsx rename to typescript/src/dsh/client/status-page.tsx diff --git a/packages/typescript/src/dsh/client/styles.ts b/typescript/src/dsh/client/styles.ts similarity index 100% rename from packages/typescript/src/dsh/client/styles.ts rename to typescript/src/dsh/client/styles.ts diff --git a/packages/typescript/src/dsh/config.ts b/typescript/src/dsh/config.ts similarity index 100% rename from packages/typescript/src/dsh/config.ts rename to typescript/src/dsh/config.ts diff --git a/packages/typescript/src/dsh/guidance.ts b/typescript/src/dsh/guidance.ts similarity index 100% rename from packages/typescript/src/dsh/guidance.ts rename to typescript/src/dsh/guidance.ts diff --git a/packages/typescript/src/dsh/index.ts b/typescript/src/dsh/index.ts similarity index 100% rename from packages/typescript/src/dsh/index.ts rename to typescript/src/dsh/index.ts diff --git a/packages/typescript/src/dsh/messages.ts b/typescript/src/dsh/messages.ts similarity index 100% rename from packages/typescript/src/dsh/messages.ts rename to typescript/src/dsh/messages.ts diff --git a/packages/typescript/src/dsh/runtime-status.ts b/typescript/src/dsh/runtime-status.ts similarity index 100% rename from packages/typescript/src/dsh/runtime-status.ts rename to typescript/src/dsh/runtime-status.ts diff --git a/packages/typescript/src/dsh/runtime.ts b/typescript/src/dsh/runtime.ts similarity index 100% rename from packages/typescript/src/dsh/runtime.ts rename to typescript/src/dsh/runtime.ts diff --git a/packages/typescript/src/dsh/scheduler.ts b/typescript/src/dsh/scheduler.ts similarity index 100% rename from packages/typescript/src/dsh/scheduler.ts rename to typescript/src/dsh/scheduler.ts diff --git a/packages/typescript/src/dsh/status-gateway.ts b/typescript/src/dsh/status-gateway.ts similarity index 100% rename from packages/typescript/src/dsh/status-gateway.ts rename to typescript/src/dsh/status-gateway.ts diff --git a/packages/typescript/src/dsh/tools.ts b/typescript/src/dsh/tools.ts similarity index 100% rename from packages/typescript/src/dsh/tools.ts rename to typescript/src/dsh/tools.ts diff --git a/packages/typescript/src/dsh/types.ts b/typescript/src/dsh/types.ts similarity index 100% rename from packages/typescript/src/dsh/types.ts rename to typescript/src/dsh/types.ts diff --git a/packages/typescript/src/index.ts b/typescript/src/index.ts similarity index 100% rename from packages/typescript/src/index.ts rename to typescript/src/index.ts diff --git a/packages/typescript/src/openclaw/config.ts b/typescript/src/openclaw/config.ts similarity index 100% rename from packages/typescript/src/openclaw/config.ts rename to typescript/src/openclaw/config.ts diff --git a/packages/typescript/src/openclaw/index.ts b/typescript/src/openclaw/index.ts similarity index 100% rename from packages/typescript/src/openclaw/index.ts rename to typescript/src/openclaw/index.ts diff --git a/packages/typescript/src/openclaw/messages.ts b/typescript/src/openclaw/messages.ts similarity index 100% rename from packages/typescript/src/openclaw/messages.ts rename to typescript/src/openclaw/messages.ts diff --git a/packages/typescript/src/openclaw/runtime.ts b/typescript/src/openclaw/runtime.ts similarity index 100% rename from packages/typescript/src/openclaw/runtime.ts rename to typescript/src/openclaw/runtime.ts diff --git a/packages/typescript/src/openclaw/tools.ts b/typescript/src/openclaw/tools.ts similarity index 100% rename from packages/typescript/src/openclaw/tools.ts rename to typescript/src/openclaw/tools.ts diff --git a/packages/typescript/tests/bundle.test.mjs b/typescript/tests/bundle.test.mjs similarity index 100% rename from packages/typescript/tests/bundle.test.mjs rename to typescript/tests/bundle.test.mjs diff --git a/packages/typescript/tests/client.test.mjs b/typescript/tests/client.test.mjs similarity index 100% rename from packages/typescript/tests/client.test.mjs rename to typescript/tests/client.test.mjs diff --git a/packages/typescript/tests/config.test.mjs b/typescript/tests/config.test.mjs similarity index 100% rename from packages/typescript/tests/config.test.mjs rename to typescript/tests/config.test.mjs diff --git a/packages/typescript/tests/context.test.mjs b/typescript/tests/context.test.mjs similarity index 100% rename from packages/typescript/tests/context.test.mjs rename to typescript/tests/context.test.mjs diff --git a/packages/typescript/tests/dsh-index.test.mjs b/typescript/tests/dsh-index.test.mjs similarity index 100% rename from packages/typescript/tests/dsh-index.test.mjs rename to typescript/tests/dsh-index.test.mjs diff --git a/packages/typescript/tests/dsh-tools.test.mjs b/typescript/tests/dsh-tools.test.mjs similarity index 100% rename from packages/typescript/tests/dsh-tools.test.mjs rename to typescript/tests/dsh-tools.test.mjs diff --git a/packages/typescript/tests/frontmatter.test.mjs b/typescript/tests/frontmatter.test.mjs similarity index 100% rename from packages/typescript/tests/frontmatter.test.mjs rename to typescript/tests/frontmatter.test.mjs diff --git a/packages/typescript/tests/messages.test.mjs b/typescript/tests/messages.test.mjs similarity index 100% rename from packages/typescript/tests/messages.test.mjs rename to typescript/tests/messages.test.mjs diff --git a/packages/typescript/tests/openclaw.test.mjs b/typescript/tests/openclaw.test.mjs similarity index 100% rename from packages/typescript/tests/openclaw.test.mjs rename to typescript/tests/openclaw.test.mjs diff --git a/packages/typescript/tests/runtime.test.mjs b/typescript/tests/runtime.test.mjs similarity index 100% rename from packages/typescript/tests/runtime.test.mjs rename to typescript/tests/runtime.test.mjs diff --git a/packages/typescript/tests/scheduler.test.mjs b/typescript/tests/scheduler.test.mjs similarity index 100% rename from packages/typescript/tests/scheduler.test.mjs rename to typescript/tests/scheduler.test.mjs diff --git a/packages/typescript/tsconfig.json b/typescript/tsconfig.json similarity index 100% rename from packages/typescript/tsconfig.json rename to typescript/tsconfig.json