@deepseek-ai/dsh-headless 0.0.1-rc.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,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, DeepSeek
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,6 @@
1
+ # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
+ # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
+ # after editing either side, bring the other along and re-record with:
4
+ # pnpm run verify-translation-pairing --write packages/bundle/headless/README.md
5
+ README.md: 31a4894dbb191d2244371ca7272339e96e253053
6
+ README.zh.md: 6e8d28f10071fbab175c4f14f1aaa9618b8f598a
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # `@deepseek-ai/dsh-headless`
2
+
3
+ English | [中文](README.zh.md)
4
+
5
+ The dsh one-shot bundle. [`cordis.patch.yml`](cordis.patch.yml) rides directly over [`dsh-base`](../base/README.md): it supplies the coding persona and tool mode, disables HMR, mounts Code Mode's worker as a core execution capability, and inserts this package's `headless-runner` plugin (config `{task}`, resolved from the injected `headlessStartup` provider). It mounts no Host, HTTP server, Web runtime, or browser plugin.
6
+
7
+ After the Loader settles, the runner reads the shared [`ctx.agentDefaultModel`](../../core/agent-default-model/README.md), creates one fresh persisted Agent through `ctx.agents`, submits the task as an ordinary user message, and waits for quiescence. It flushes the Session before folding the owned durable event interval, writes the last non-empty assistant text to stdout, and requests exit through the launcher-provided `ctx.headlessIo` host hook (final `turn/end` completed → 0, otherwise 1). A terminal `error` reason also writes its code and message to stderr; successful runs keep stderr empty. The process opens no listening port. The task text is this app's command line: the ordinary `headless-startup` provider ([`src/startup.ts`](src/startup.ts)) injects `ctx.cmdlineArgs` ([`dsh-cmdline`](../../boot/cmdline/README.md)), reads the positional argument of `dsh --profile headless "task"`, prints the app's `--help`, and provides `headlessStartup`; the runner injects that service and reads its task from lazy config. A missing or whitespace-only task is rejected before the runner activates.
8
+
9
+ ## Model Experience
10
+
11
+ None, as the runner submits the task as an ordinary user message; prompts and tools belong to the base and headless bundle rows.
12
+
13
+ #### KV Cache effect
14
+
15
+ None; the runner adds nothing to the request prefix.
16
+
17
+ ## Known Limitations and Deferred Work
18
+
19
+ - **One submitted task only** — the runner has no interactive follow-up surface; it waits through any work the Agent completes before returning to idle and prints the last non-empty assistant message in that interval.
20
+ - **`ctx.headlessIo` is launcher-owned** — booting the headless profile outside the `dsh` launcher fails loud at activation until the host provides the hook.
package/README.zh.md ADDED
@@ -0,0 +1,20 @@
1
+ # `@deepseek-ai/dsh-headless`
2
+
3
+ [English](README.md) | 中文
4
+
5
+ dsh 一次性任务组合包。[`cordis.patch.yml`](cordis.patch.yml) 直接叠加在 [`dsh-base`](../base/README.md) 之上:提供编码 persona 和工具模式、禁用 HMR(热模块替换)、将 Code Mode 的 worker 作为核心执行能力挂载,并插入本包的 `headless-runner` 插件(配置为 `{task}`,从注入的 `headlessStartup` 提供方解析)。它不挂载任何 Host、HTTP server、Web runtime 或浏览器插件。
6
+
7
+ Loader 结算后,runner 读取共享的 [`ctx.agentDefaultModel`](../../core/agent-default-model/README.md),通过 `ctx.agents` 创建一个全新的持久化 Agent(智能体),将任务作为普通用户消息提交,并等待完全停稳。它对 Session 执行 flush 后再汇总自身持有的持久化事件区间,将最后一条非空 assistant 文本写入 stdout,再经启动器提供的 `ctx.headlessIo` 宿主钩子请求退出(最终 `turn/end` 完成 → 0,否则为 1)。最终 reason 为 `error` 时,还会将持久化的 code 与 message 写入 stderr;成功运行时 stderr 保持为空。进程不会打开监听端口。任务文本就是这个应用的命令行:普通 `headless-startup` 提供方([`src/startup.ts`](src/startup.ts))注入 `ctx.cmdlineArgs`([`dsh-cmdline`](../../boot/cmdline/README.md)),读取 `dsh --profile headless "task"` 的位置参数、打印应用自己的 `--help`,并提供 `headlessStartup`;runner 注入该服务,再从惰性配置中读取任务。缺失或只有空白的任务会在 runner 激活前被拒绝。
8
+
9
+ ## 模型体验
10
+
11
+ 无影响,因为 runner 把任务作为普通用户消息提交;提示词与工具归 base 和 headless 组合包中的相应行所有。
12
+
13
+ #### KV Cache 影响
14
+
15
+ 无;runner 不向请求前缀添加任何内容。
16
+
17
+ ## 已知限制与延期工作
18
+
19
+ - **只提交一个任务**:runner 没有用于交互式后续输入的 surface;它会等待 Agent 在返回 idle 前完成的所有工作,并打印该区间内最后一条非空 assistant 消息。
20
+ - **`ctx.headlessIo` 由启动器持有**:在 `dsh` 启动器之外启动 headless profile 会在激活时明确报错,直到宿主提供该钩子。
@@ -0,0 +1,34 @@
1
+ # The dsh-headless bundle patch: one-shot task mode directly over dsh-base.
2
+ # It mounts no Host, HTTP server, Web runtime, or browser plugin. An ordinary
3
+ # provider plugin injects `cmdlineArgs`, parses the task positional
4
+ # (`dsh --profile headless "<task>"`) and this app's --help, then the direct
5
+ # driver creates an Agent through the core registry and prints its durable result.
6
+
7
+ - id: system-prompt
8
+ config:
9
+ persona: >-
10
+ You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.
11
+
12
+ # One-shot runs never watch or reload their composition.
13
+ - id: hmr
14
+ disabled: true
15
+
16
+ - id: tools
17
+ config:
18
+ # Keep the same temporary process-wide Code Mode opt-in as the Web surface.
19
+ mode: !!js process.env.DSH_TOOLS_MODE
20
+
21
+ - insert:
22
+ # Code Mode is a core execution capability, not a Web component.
23
+ - id: code-runtime
24
+ name: '@deepseek-ai/dsh-code-runtime-worker'
25
+
26
+ - id: headless-startup
27
+ name: '@deepseek-ai/dsh-headless/startup'
28
+
29
+ # Reads its task from the ordinary headlessStartup provider.
30
+ - id: headless-runner
31
+ name: '@deepseek-ai/dsh-headless'
32
+ inject: [headlessStartup]
33
+ config:
34
+ task: !!js ctx.headlessStartup.task
package/lib/index.js ADDED
@@ -0,0 +1,108 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import z from "@deepseek-ai/schemastery";
3
+ import { installModelSelection } from "@deepseek-ai/dsh-agent";
4
+ import { createUserMessage } from "@deepseek-ai/dsh-llm";
5
+ import { SessionId } from "@deepseek-ai/dsh-session";
6
+ //#region lib/types/index.js
7
+ /**
8
+ * @deepseek-ai/dsh-headless — one-shot direct Agent driver. The bundle patch
9
+ * rides over dsh-base without Host, HTTP, or browser plugins; this runner
10
+ * creates one Agent through the core registry, drives the task to quiescence,
11
+ * flushes its Session, prints the final assistant text, and exits.
12
+ *
13
+ * @module @deepseek-ai/dsh-headless
14
+ */
15
+ /** Stable Cordis plugin name. */
16
+ const name = "headless-runner";
17
+ /** Core services required before the one-shot turn can start. */
18
+ const inject = [
19
+ "agentDefaultModel",
20
+ "agents",
21
+ "sessions"
22
+ ];
23
+ const Config = z.object({ task: z.string().required() });
24
+ /** Aggregate the last assistant text and turn outcome in one owned interval. */
25
+ function summarize(events, firstSeq) {
26
+ let started = false;
27
+ let text = "";
28
+ let reason;
29
+ for (const event of events) {
30
+ if (event.seq < firstSeq) continue;
31
+ if (event.type === "turn/start") {
32
+ started = true;
33
+ continue;
34
+ }
35
+ if (!started) continue;
36
+ if (event.type === "assistant/message") {
37
+ const joined = event.data.message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
38
+ if (joined !== "") text = joined;
39
+ }
40
+ if (event.type === "turn/end") reason = event.data.reason;
41
+ }
42
+ return {
43
+ text,
44
+ reason
45
+ };
46
+ }
47
+ /** Report an unexpected direct-driver failure and request a failing exit. */
48
+ function fail(io, error) {
49
+ io.stderr.write(`dsh: ${error instanceof Error ? error.message : String(error)}\n`);
50
+ io.exit(1);
51
+ }
52
+ /**
53
+ * Run one task through a freshly created Agent and request process exit.
54
+ * @param ctx - plugin context carrying the Agent, default model, Session, and launcher IO services.
55
+ * @param task - one-shot task text.
56
+ * @param io - process-facing effects.
57
+ */
58
+ async function run(ctx, task, io) {
59
+ await ctx.get("loader")?.await();
60
+ const agents = ctx.get("agents");
61
+ const defaultModel = ctx.get("agentDefaultModel");
62
+ const sessions = ctx.get("sessions");
63
+ if (agents === void 0 || defaultModel === void 0 || sessions === void 0) return;
64
+ const selection = defaultModel.currentSelection();
65
+ const { agent } = await agents.create({
66
+ sessionId: SessionId(`session-${randomUUID()}`),
67
+ meta: { cwd: process.cwd() },
68
+ agentOptions: {
69
+ provider: selection.provider,
70
+ model: selection.model
71
+ },
72
+ setup: (agentCtx) => {
73
+ installModelSelection(agentCtx, {
74
+ current: selection,
75
+ assembled: void 0
76
+ });
77
+ }
78
+ });
79
+ await agent.whenIdle();
80
+ const firstSeq = agent.session.seq;
81
+ agent.followup(createUserMessage({
82
+ content: [{
83
+ type: "text",
84
+ text: task
85
+ }],
86
+ source: { kind: "user" }
87
+ }));
88
+ await agent.whenIdle();
89
+ await sessions.flush(agent.session);
90
+ const outcome = summarize(agent.session.events, firstSeq);
91
+ io.stdout.write(outcome.text + "\n");
92
+ if (outcome.reason?.kind === "error") io.stderr.write(`dsh: ${outcome.reason.error.code}: ${outcome.reason.error.message}\n`);
93
+ io.exit(outcome.reason?.kind === "completed" ? 0 : 1);
94
+ }
95
+ /**
96
+ * Mount the one-shot direct driver.
97
+ * @param ctx - plugin context carrying core services and the launcher-owned IO seam.
98
+ * @param config - validated task config.
99
+ */
100
+ function apply(ctx, config) {
101
+ const io = ctx.headlessIo;
102
+ if (io === void 0) throw new Error("headless-runner: the launcher must provide ctx.headlessIo before the tree mounts");
103
+ run(ctx, config.task, io).catch((error) => {
104
+ fail(io, error);
105
+ });
106
+ }
107
+ //#endregion
108
+ export { Config, apply, inject, name };
@@ -0,0 +1,25 @@
1
+ //#region lib/types/invariant.js
2
+ /**
3
+ * Package-owned invariant companion for `@deepseek-ai/dsh-headless`.
4
+ * @module @deepseek-ai/dsh-headless/invariant
5
+ */
6
+ const PACKAGE_NAME = "@deepseek-ai/dsh-headless";
7
+ /** Cordis companion plugin name. */
8
+ const name = "headless-invariant";
9
+ /** Service required before the companion can register. */
10
+ const inject = ["invariants"];
11
+ /**
12
+ * No runtime invariant: the runner is a one-shot driver over the API carrier
13
+ * whose observable contract (final text on stdout, exit code by turn-end
14
+ * reason) is process-level and owned by the launcher e2e; it registers
15
+ * nothing and holds no mutable relation to audit inside the tree.
16
+ */
17
+ const install = () => {};
18
+ /**
19
+ * Register this package's invariant companion.
20
+ * @param ctx - Cordis context carrying the invariant service.
21
+ * @returns the installed registration's disposer after setup succeeds.
22
+ */
23
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
24
+ //#endregion
25
+ export { apply, inject, name };
package/lib/startup.js ADDED
@@ -0,0 +1,46 @@
1
+ import { Command } from "commander";
2
+ import { parseCmdline } from "@deepseek-ai/dsh-cmdline";
3
+ //#region lib/types/startup.js
4
+ /**
5
+ * The one-shot app's command-line provider: it parses the task positional and
6
+ * `--help`, then publishes {@link HEADLESS_STARTUP_SERVICE}. The runner is an
7
+ * ordinary consumer whose lazy config waits for that service.
8
+ * @module @deepseek-ai/dsh-headless/startup
9
+ */
10
+ /** Stable Cordis plugin name. */
11
+ const name = "headless-startup";
12
+ /** Services required before the task can be resolved. */
13
+ const inject = ["cmdlineArgs"];
14
+ /** Service provided by this plugin and injected by the one-shot runner. */
15
+ const HEADLESS_STARTUP_SERVICE = "headlessStartup";
16
+ /**
17
+ * This app's command: the task positional, its description, and its help text.
18
+ * @returns a fresh program, so one process can parse more than once (tests).
19
+ */
20
+ function headlessCommand() {
21
+ return new Command().name("dsh --profile headless").description("Answer one task, print the final assistant message, and exit.").helpOption("-h, --help", "show this help").argument("[task...]", "the task text; multiple words are joined by spaces").addHelpText("after", `
22
+ Examples:
23
+ dsh --profile headless "run the tests" answer one task and exit
24
+ `);
25
+ }
26
+ /**
27
+ * Turn the parsed command line into the runner's task.
28
+ * @param program - the parsed headless command.
29
+ * @returns the runner's service value.
30
+ */
31
+ function planHeadlessStartup(program) {
32
+ const task = program.args.join(" ");
33
+ if (task.trim() === "") program.error("error: a task is required, for example: dsh --profile headless \"run the tests\"");
34
+ return { task };
35
+ }
36
+ /**
37
+ * Parse and provide the one-shot task as an ordinary Cordis service.
38
+ * @param ctx - plugin context carrying the command line.
39
+ * @returns nothing once the task is provided, or when the command requested exit.
40
+ */
41
+ function apply(ctx) {
42
+ const values = parseCmdline(ctx, headlessCommand(), planHeadlessStartup);
43
+ if (values !== void 0) ctx.provide(HEADLESS_STARTUP_SERVICE, values);
44
+ }
45
+ //#endregion
46
+ export { HEADLESS_STARTUP_SERVICE, apply, inject, name };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @deepseek-ai/dsh-headless — one-shot direct Agent driver. The bundle patch
3
+ * rides over dsh-base without Host, HTTP, or browser plugins; this runner
4
+ * creates one Agent through the core registry, drives the task to quiescence,
5
+ * flushes its Session, prints the final assistant text, and exits.
6
+ *
7
+ * @module @deepseek-ai/dsh-headless
8
+ */
9
+ import type { Context } from '@deepseek-ai/cordis';
10
+ import z from '@deepseek-ai/schemastery';
11
+ /** Stable Cordis plugin name. */
12
+ export declare const name = "headless-runner";
13
+ /** Core services required before the one-shot turn can start. */
14
+ export declare const inject: string[];
15
+ /** Plugin config: the task resolved from this app's injected provider service. */
16
+ export interface Config {
17
+ /** The prompt text for the single run. */
18
+ task: string;
19
+ }
20
+ export declare const Config: z<Config>;
21
+ /**
22
+ * Process-facing effects of one run, injectable for tests. The launcher owns
23
+ * bounded tree shutdown and wires `exit()` to it.
24
+ */
25
+ export interface HeadlessIo {
26
+ stdout: {
27
+ write(chunk: string): unknown;
28
+ };
29
+ stderr: {
30
+ write(chunk: string): unknown;
31
+ };
32
+ /** Request process exit with `code` after the tree disposes. */
33
+ exit(code: number): void;
34
+ }
35
+ declare module '@deepseek-ai/cordis' {
36
+ interface Context {
37
+ /** Process-facing effects provided before the headless tree mounts. */
38
+ headlessIo?: HeadlessIo;
39
+ }
40
+ }
41
+ /**
42
+ * Mount the one-shot direct driver.
43
+ * @param ctx - plugin context carrying core services and the launcher-owned IO seam.
44
+ * @param config - validated task config.
45
+ */
46
+ export declare function apply(ctx: Context, config: Config): void;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Package-owned invariant companion for `@deepseek-ai/dsh-headless`.
3
+ * @module @deepseek-ai/dsh-headless/invariant
4
+ */
5
+ import type { Context } from '@deepseek-ai/cordis';
6
+ /** Cordis companion plugin name. */
7
+ export declare const name = "headless-invariant";
8
+ /** Service required before the companion can register. */
9
+ export declare const inject: string[];
10
+ /**
11
+ * Register this package's invariant companion.
12
+ * @param ctx - Cordis context carrying the invariant service.
13
+ * @returns the installed registration's disposer after setup succeeds.
14
+ */
15
+ export declare const apply: (ctx: Context) => Promise<() => void>;
16
+ //# sourceMappingURL=invariant.d.ts.map
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The one-shot app's command-line provider: it parses the task positional and
3
+ * `--help`, then publishes {@link HEADLESS_STARTUP_SERVICE}. The runner is an
4
+ * ordinary consumer whose lazy config waits for that service.
5
+ * @module @deepseek-ai/dsh-headless/startup
6
+ */
7
+ import type { Context } from '@deepseek-ai/cordis';
8
+ /** Stable Cordis plugin name. */
9
+ export declare const name = "headless-startup";
10
+ /** Services required before the task can be resolved. */
11
+ export declare const inject: string[];
12
+ /** Service provided by this plugin and injected by the one-shot runner. */
13
+ export declare const HEADLESS_STARTUP_SERVICE = "headlessStartup";
14
+ /** What the runner row reads from {@link HEADLESS_STARTUP_SERVICE}. */
15
+ export interface HeadlessStartupValues {
16
+ /** The task text this invocation asked for. */
17
+ task: string;
18
+ }
19
+ /**
20
+ * Parse and provide the one-shot task as an ordinary Cordis service.
21
+ * @param ctx - plugin context carrying the command line.
22
+ * @returns nothing once the task is provided, or when the command requested exit.
23
+ */
24
+ export declare function apply(ctx: Context): void;
25
+ //# sourceMappingURL=startup.d.ts.map
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@deepseek-ai/dsh-headless",
3
+ "description": "The dsh one-shot bundle: a direct core Agent/Session runner over dsh-base with no Host, HTTP, or browser layer",
4
+ "version": "0.0.1-rc.1",
5
+ "publishConfig": {
6
+ "access": "restricted"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
11
+ "directory": "packages/bundle/headless"
12
+ },
13
+ "type": "module",
14
+ "main": "lib/index.js",
15
+ "types": "lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "default": "./lib/index.js"
20
+ },
21
+ "./startup": {
22
+ "types": "./lib/types/startup.d.ts",
23
+ "default": "./lib/startup.js"
24
+ },
25
+ "./invariant": {
26
+ "types": "./lib/types/invariant.d.ts",
27
+ "default": "./lib/invariant.js"
28
+ },
29
+ "./cordis.patch.yml": "./cordis.patch.yml",
30
+ "./src/*": "./src/*",
31
+ "./package.json": "./package.json"
32
+ },
33
+ "files": [
34
+ "lib/index.js",
35
+ "lib/invariant.js",
36
+ "lib/startup.js",
37
+ "cordis.patch.yml",
38
+ "lib/types/**/*.d.ts"
39
+ ],
40
+ "license": "BSD-3-Clause",
41
+ "dsh": {
42
+ "bundle": {
43
+ "patch": "./cordis.patch.yml"
44
+ }
45
+ },
46
+ "dependencies": {
47
+ "commander": "^15.0.0",
48
+ "@deepseek-ai/dsh-cmdline": "^0.0.1-rc.1",
49
+ "@deepseek-ai/schemastery": "^3.18.1-rc.1",
50
+ "@deepseek-ai/dsh-code-runtime-worker": "^0.0.1-rc.1"
51
+ },
52
+ "peerDependencies": {
53
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.1-rc.1",
54
+ "@deepseek-ai/dsh-agent": "^0.0.1-rc.1",
55
+ "@deepseek-ai/dsh-agent-default-model": "^0.0.1-rc.1",
56
+ "@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
57
+ "@deepseek-ai/dsh-llm": "^0.0.1-rc.1",
58
+ "@deepseek-ai/dsh-session": "^0.0.1-rc.1",
59
+ "@deepseek-ai/cordis": "^4.0.1-rc.1"
60
+ },
61
+ "devDependencies": {
62
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.1-rc.1",
63
+ "@deepseek-ai/dsh-agent-default-model": "^0.0.1-rc.1",
64
+ "@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
65
+ "@deepseek-ai/dsh-agent": "^0.0.1-rc.1",
66
+ "@deepseek-ai/dsh-llm": "^0.0.1-rc.1",
67
+ "@deepseek-ai/dsh-session": "^0.0.1-rc.1",
68
+ "@deepseek-ai/cordis": "^4.0.1-rc.1"
69
+ }
70
+ }