layerweave 0.0.0-stage → 0.7.9-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LayerWeave contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.en.md ADDED
@@ -0,0 +1,35 @@
1
+ # LayerWeave npm launcher
2
+
3
+ [简体中文](https://github.com/aceddad/LayerWeave/blob/v0.7.9b1/distribution/npm/README.md) | English
4
+
5
+ Start LayerWeave with one command on Windows x64. This package prepares the runtime and forwards arguments. All example, project, view, and MCP behavior lives in the same Python application used by uv.
6
+
7
+ ## Quick start
8
+
9
+ Run from your chosen working directory:
10
+
11
+ ```powershell
12
+ npx --yes layerweave@0.7.9-beta.1 demo
13
+ ```
14
+
15
+ This npm preview uses the next dist-tag and pins Python package `0.7.9b1`. It supports Windows x64 and Node.js 20+. Python and uv do not need to be installed beforehand.
16
+
17
+ ## Commands
18
+
19
+ - `demo`: prepare and open article reading in `./layerweave-demo/article-reading`.
20
+ - `demo --list`: list examples; other examples download on demand.
21
+ - `demo comic-creation --dir ./my-comic`: prepare another example at a chosen location.
22
+ - `view ./project.sqlite3` or `view ./my-comic`: open an existing database or launcher project.
23
+ - `new ./my-project --template subtitles`: create a project from a template.
24
+ - `help project_overview`: reuse the existing detailed tool help.
25
+ - `mcp --config ./mcp.json`: run MCP; the npm launcher requests the matching mcp extra.
26
+
27
+ Reopening preserves edits. The server runs in the foreground; Ctrl+C stops it without deleting project data. Use `--no-browser` to print the URL only, or `--port` to choose a port. Environment setup messages go to stderr, leaving MCP stdout for its protocol.
28
+
29
+ ## Runtime and maintenance
30
+
31
+ The launcher reuses uv >= 0.9 from PATH when available. Otherwise it downloads a pinned official uv archive, verifies SHA-256, and extracts it into the user's cache. uv prepares an independent Python 3.11 and application environment without changing PATH or shell configuration. First use needs internet access; later runs reuse caches.
32
+
33
+ The default cache is `%LOCALAPPDATA%/LayerWeave/cache`. LAYERWEAVE_CACHE_DIR changes its location; LAYERWEAVE_UV selects an existing executable; LAYERWEAVE_PYTHON_PACKAGE selects a local wheel or full Python requirement for unpublished-package testing. Custom sources should match the npm package's Python version and include the mcp extra when needed.
34
+
35
+ Run `npm test` to verify and `npm pack` to build. Only the launcher is shipped: no user data, install-time scripts, or duplicate Python implementation. Registry publication requires the maintainer's accounts and authorization.
package/README.md CHANGED
@@ -1,3 +1,35 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # LayerWeave npm 启动器
2
+
3
+ 简体中文 | [English](https://github.com/aceddad/LayerWeave/blob/v0.7.9b1/distribution/npm/README.en.md)
4
+
5
+ 在 Windows x64 上,以一条命令启动 LayerWeave。npm 包只准备运行环境并转交参数,案例、数据库、视图与 MCP 的业务逻辑全部来自同一份 Python 包。
6
+
7
+ ## 快速开始
8
+
9
+ 在自己的工作目录中执行:
10
+
11
+ ```powershell
12
+ npx --yes layerweave@0.7.9-beta.1 demo
13
+ ```
14
+
15
+ 本次 npm 预览版使用 next 通道,固定匹配 Python `0.7.9b1`。支持 Windows x64、Node.js 20+;不需要预先安装 Python 或 uv。
16
+
17
+ ## 命令
18
+
19
+ - `demo`:准备并打开文章解析,默认保存到 `./layerweave-demo/article-reading`。
20
+ - `demo --list`:列出全部案例;其他案例按需下载。
21
+ - `demo comic-creation --dir ./my-comic`:在指定目录体验漫画案例。
22
+ - `view ./project.sqlite3` 或 `view ./my-comic`:打开已有内容。
23
+ - `new ./my-project --template subtitles`:创建自己的模板项目。
24
+ - `help project_overview`:查看现有详细 help。
25
+ - `mcp --config ./mcp.json`:启动 MCP;启动器自动选用对应版本的 mcp extra。
26
+
27
+ 项目重复打开时保留修改。服务在前台运行,Ctrl+C 停止服务。`--no-browser` 只打印地址,`--port` 可指定端口。MCP 的 stdout 保留给协议,环境准备提示写到 stderr。
28
+
29
+ ## 环境与维护
30
+
31
+ 优先使用 PATH 中可用的 uv >= 0.9;没有时下载固定版本的官方 uv,核对 SHA-256 后解压到用户缓存。uv 自动准备独立的 Python 3.11 与 LayerWeave 环境,不修改 PATH 或 shell 配置。首次准备需要网络,后续可复用缓存。源码在 lib/launch.mjs,官方 uv 地址与校验值在 runtime.json。
32
+
33
+ 默认缓存为 `%LOCALAPPDATA%/LayerWeave/cache`。LAYERWEAVE_CACHE_DIR 可改缓存位置;LAYERWEAVE_UV 可指定已有 uv;LAYERWEAVE_PYTHON_PACKAGE 可指定本地 wheel 或完整 Python requirement,供未发布包验证。自定义来源时请使用与 npm 版本相符的 Python 包;需要 MCP 时提供含 mcp extra 的 requirement。
34
+
35
+ 构建 npm 包执行 `npm pack`;验证执行 `npm test`。包中没有项目数据库、用户素材、安装后脚本或另一份 Python 实现。发布需要维护者账号与授权,详见仓库发布说明。
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../lib/launch.mjs';
3
+
4
+ try {
5
+ process.exitCode = await main(process.argv.slice(2));
6
+ } catch (error) {
7
+ console.error(`LayerWeave: ${error.message}`);
8
+ process.exitCode = 1;
9
+ }
package/lib/launch.mjs ADDED
@@ -0,0 +1,132 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
3
+ import { createReadStream, createWriteStream } from 'node:fs';
4
+ import { access, mkdir, mkdtemp, readFile, rename, rm } from 'node:fs/promises';
5
+ import { homedir } from 'node:os';
6
+ import path from 'node:path';
7
+ import { Readable } from 'node:stream';
8
+ import { pipeline } from 'node:stream/promises';
9
+
10
+ const metadata = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
11
+ const runtime = JSON.parse(await readFile(new URL('../runtime.json', import.meta.url), 'utf8'));
12
+
13
+ export function cacheRoot(env = process.env) {
14
+ return path.resolve(env.LAYERWEAVE_CACHE_DIR || path.join(env.LOCALAPPDATA || path.join(homedir(), 'AppData', 'Local'), 'LayerWeave', 'cache'));
15
+ }
16
+
17
+ async function exists(file) {
18
+ try { await access(file); return true; } catch { return false; }
19
+ }
20
+
21
+ export async function download(url, output, sha256) {
22
+ if (process.platform === 'win32' && url.startsWith('https:')) {
23
+ // Use the Windows proxy and certificate settings; do not disable TLS checks.
24
+ const powershell = path.join(process.env.SystemRoot || 'C:\\Windows', 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe');
25
+ await new Promise((resolve, reject) => {
26
+ const child = spawn(powershell, ['-NoProfile', '-NonInteractive', '-Command',
27
+ "$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; [Console]::OutputEncoding=[Text.UTF8Encoding]::new(); Invoke-WebRequest -UseBasicParsing -TimeoutSec 120 -Uri $env:LAYERWEAVE_UV_URL -OutFile $env:LAYERWEAVE_UV_OUTPUT"],
28
+ { env: { ...process.env, LAYERWEAVE_UV_URL: url, LAYERWEAVE_UV_OUTPUT: output }, stdio: ['ignore', 'ignore', 'pipe'], windowsHide: true });
29
+ let error = '';
30
+ child.stderr.setEncoding('utf8');
31
+ child.stderr.on('data', chunk => { error += chunk; });
32
+ child.once('error', reject);
33
+ child.once('close', code => code === 0 ? resolve() : reject(new Error(`uv download failed: ${error.trim()}`)));
34
+ });
35
+ } else {
36
+ const response = await fetch(url, { signal: AbortSignal.timeout(120_000) });
37
+ if (!response.ok) throw new Error(`Download failed: HTTP ${response.status} (${url})`);
38
+ await pipeline(Readable.fromWeb(response.body), createWriteStream(output));
39
+ }
40
+ const hash = createHash('sha256');
41
+ for await (const chunk of createReadStream(output)) hash.update(chunk);
42
+ if (hash.digest('hex') !== sha256) throw new Error('uv archive checksum mismatch; retry the command.');
43
+ }
44
+
45
+ function usableUv(command) {
46
+ const result = spawnSync(command, ['--version'], { encoding: 'utf8', windowsHide: true, timeout: 10_000 });
47
+ const version = /^uv (\d+)\.(\d+)\./.exec(result.stdout || '');
48
+ return result.status === 0 && version && (Number(version[1]) > 0 || Number(version[2]) >= 9);
49
+ }
50
+
51
+ export async function prepareUv(env = process.env) {
52
+ if (env.LAYERWEAVE_UV) {
53
+ if (!usableUv(env.LAYERWEAVE_UV)) throw new Error('LAYERWEAVE_UV must point to uv >= 0.9.');
54
+ return env.LAYERWEAVE_UV;
55
+ }
56
+ if (usableUv('uv')) return 'uv';
57
+ const spec = runtime.targets[`${process.platform}-${process.arch}`];
58
+ if (!spec) throw new Error('This npm preview supports Windows x64. Use the Python/uv distribution on other platforms.');
59
+ const parent = path.join(cacheRoot(env), 'runtime');
60
+ const directory = path.join(parent, `uv-${runtime.version}`);
61
+ const executable = path.join(directory, 'uv.exe');
62
+ if (await exists(executable)) return executable;
63
+ await mkdir(parent, { recursive: true });
64
+ const staging = await mkdtemp(path.join(parent, '.uv-'));
65
+ try {
66
+ console.error(`LayerWeave: preparing uv ${runtime.version} in ${directory}`);
67
+ const archive = path.join(staging, 'uv.zip');
68
+ await download(spec.url, archive, spec.sha256);
69
+ const extracted = path.join(staging, 'unpacked');
70
+ const powershell = path.join(env.SystemRoot || 'C:\\Windows', 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe');
71
+ const result = spawnSync(powershell, ['-NoProfile', '-NonInteractive', '-Command',
72
+ "$ErrorActionPreference='Stop'; Expand-Archive -LiteralPath $env:LAYERWEAVE_UV_ARCHIVE -DestinationPath $env:LAYERWEAVE_UV_EXTRACT"],
73
+ { env: { ...env, LAYERWEAVE_UV_ARCHIVE: archive, LAYERWEAVE_UV_EXTRACT: extracted }, encoding: 'utf8', windowsHide: true });
74
+ if (result.status !== 0) throw new Error(`Cannot extract uv: ${result.stderr || result.error?.message}`);
75
+ if (!(await exists(path.join(extracted, 'uv.exe')))) throw new Error('Downloaded uv archive is missing uv.exe.');
76
+ try { await rename(extracted, directory); }
77
+ catch (error) { if (!(await exists(executable))) throw error; }
78
+ return executable;
79
+ } finally {
80
+ // Only remove the unique staging directory created by this invocation.
81
+ await rm(staging, { recursive: true, force: true });
82
+ }
83
+ }
84
+
85
+ export function commandArgs(argv, env = process.env) {
86
+ const extra = argv[0] === 'mcp' ? '[mcp]' : '';
87
+ const requirement = env.LAYERWEAVE_PYTHON_PACKAGE || `layerweave${extra}==${metadata.layerweave.pythonVersion}`;
88
+ return ['tool', 'run', '--no-config', '--managed-python', '--python', '3.11', '--from', requirement, 'layerweave', ...argv];
89
+ }
90
+
91
+ export function forward(command, args, env = process.env) {
92
+ return new Promise((resolve, reject) => {
93
+ const child = spawn(command, args, { env, stdio: 'inherit', windowsHide: true });
94
+ let stopping;
95
+ let timer;
96
+ const handlers = new Map();
97
+ const cleanup = () => {
98
+ clearTimeout(timer);
99
+ for (const [signal, handler] of handlers) process.removeListener(signal, handler);
100
+ };
101
+ for (const signal of ['SIGINT', 'SIGTERM']) {
102
+ const handler = () => {
103
+ if (stopping) return;
104
+ stopping = signal;
105
+ if (process.platform !== 'win32') child.kill(signal);
106
+ // Windows console Ctrl+C reaches uv and Python too. Allow their normal
107
+ // shutdown first; terminate only this child tree if it does not exit.
108
+ timer = setTimeout(() => {
109
+ if (process.platform === 'win32' && child.pid) {
110
+ spawn('taskkill', ['/PID', String(child.pid), '/T', '/F'], { stdio: 'ignore', windowsHide: true });
111
+ } else child.kill('SIGKILL');
112
+ }, 5000).unref();
113
+ };
114
+ handlers.set(signal, handler);
115
+ process.on(signal, handler);
116
+ }
117
+ child.once('error', error => { cleanup(); reject(error); });
118
+ child.once('close', (code, signal) => {
119
+ cleanup();
120
+ resolve(stopping === 'SIGINT' ? 130 : stopping === 'SIGTERM' ? 143 : code ?? (signal ? 1 : 0));
121
+ });
122
+ });
123
+ }
124
+
125
+ export async function main(argv) {
126
+ const uv = await prepareUv();
127
+ const root = cacheRoot();
128
+ const env = { ...process.env, PYTHONUTF8: '1',
129
+ UV_CACHE_DIR: process.env.UV_CACHE_DIR || path.join(root, 'uv'),
130
+ UV_PYTHON_INSTALL_DIR: process.env.UV_PYTHON_INSTALL_DIR || path.join(root, 'python') };
131
+ return forward(uv, commandArgs(argv), env);
132
+ }
package/package.json CHANGED
@@ -1,6 +1,15 @@
1
- {
2
- "name": "layerweave",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
1
+ {
2
+ "name": "layerweave",
3
+ "version": "0.7.9-beta.1",
4
+ "description": "One-command LayerWeave examples, projects and MCP with an automatically managed Python environment",
5
+ "type": "module",
6
+ "bin": {"layerweave": "bin/layerweave.mjs"},
7
+ "files": ["bin", "lib", "runtime.json", "README.md", "README.en.md", "LICENSE"],
8
+ "engines": {"node": ">=20"},
9
+ "os": ["win32"],
10
+ "cpu": ["x64"],
11
+ "scripts": {"test": "node --test test/*.test.mjs"},
12
+ "license": "MIT",
13
+ "repository": {"type": "git", "url": "git+https://github.com/aceddad/LayerWeave.git", "directory": "distribution/npm"},
14
+ "layerweave": {"pythonVersion": "0.7.9b1"}
15
+ }
package/runtime.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.13.4",
3
+ "targets": {
4
+ "win32-x64": {
5
+ "url": "https://github.com/astral-sh/uv/releases/download/0.13.4/uv-x86_64-pc-windows-msvc.zip",
6
+ "sha256": "ccec7508a07d9933d7cb1261880633efcf1f30d6e6eddab21823f1dae6f23225"
7
+ }
8
+ }
9
+ }