chore(dsh): 跟上游插件改名 dsh-events,并删掉一条会随机变红的联机验收 (#980)
* rename: 上游插件改名 dsh-jsonl -> dsh-events,同步 vendor 与常量 插件仓库改了名。`jsonl` 说的是输出格式,不是它给你什么——目标用户是想把 dsh 接进 GUI / 编辑器 / CI 的人,他们脑子里的词是「事件」,不是「JSON Lines」。而且别家都不这么 叫(Claude Code 是 --output-format stream-json,Codex 是 --json,OpenCode 是 --format json),有人来找这个能力时搜的是 "dsh json output"。 趁 npm 还没发布、还没对外宣传时改,代价只有改几个文件。旧 URL 有 GitHub 重定向兜底, 但留着迟早会成为断链。 跟着改的:vendor 文件名、同步脚本名、两个常量、环境变量名、模块文档与注释里的链接。 vendor 文件是用改名后的脚本重新生成的,不是手改——review 时加进来的来源与 MIT 许可头 原样保留。 * test(dsh): 删掉一条红绿取决于模型心情的联机验收 `tmp_is_writable_by_design_and_we_cannot_narrow_it` 想把「$TMPDIR 可写且收不掉」这个 dsh 既有行为钉成契约。但验证它必然要让模型去写文件,而 dsh 有**两道松紧不同的围栏**: bash(seatbelt 子进程沙箱) 工作目录 + /tmp + $TMPDIR write / edit(进程内 fs 围栏) 只有工作目录 prompt 里写了「用 bash 执行」,模型照做就绿,改用 write 就红。实测两种都出现过:一次 文件真落下去(bash),一次模型回 DONE 但文件根本没建(write)。这条测试的红绿反映的是 模型当次的选择,不是被测系统的行为——正是它上面那条注释批评过的毛病,我自己又犯了一遍。 那张「两道围栏」的表挪进模块文档,并写明为什么不做成测试。留下的 `sandbox_blocks_writes_outside_the_workspace` 打的是家目录,两道围栏都挡,不受工具选择 影响,那条才作数。
This commit is contained in:
1 parent
b7ac91f0e6
commit
aa0acf8827
3 files changed
+64
-85
No files matched your search
@@ -13,19 +13,19 @@
|
||||
//!
|
||||
//! dsh 是插件栈(cordis)架构,profile 由一层层 patch 叠成,`--patch <file>` 就是官方
|
||||
//! 留给外部叠自己那层的入口。我们用它挂上 [`TAP_PLUGIN_JS`]——那是
|
||||
//! [dsh-jsonl](https://github.com/bigsongeth/dsh-jsonl) 的带来源与 MIT 许可头副本:一个订阅
|
||||
//! [dsh-events](https://github.com/bigsongeth/dsh-events) 的带来源与 MIT 许可头副本:一个订阅
|
||||
//! `session/event` 的插件,把事件按有版本的公开 schema 打成 NDJSON 到 **stderr**,
|
||||
//! stdout 的「只打最终文本」契约原样不动。
|
||||
//!
|
||||
//! # 上游耦合都收在那个 JS 里
|
||||
//!
|
||||
//! dsh 目前是 `0.1.0-rc.6`,事件形状还会变,而上游不收 PR,跟随成本由我们自己背。
|
||||
//! 所以耦合点被压缩到那一个 JS 文件里:它把 dsh 的内部事件翻译成 dsh-jsonl 的公开 schema
|
||||
//! 所以耦合点被压缩到那一个 JS 文件里:它把 dsh 的内部事件翻译成 dsh-events 的公开 schema
|
||||
//! (`text.delta` / `tool.call` / `turn.end` …),Rust 侧只认那个 schema。上游改字段时改
|
||||
//! JS 即可,Rust 的解析和单测都不用动。
|
||||
//!
|
||||
//! 那个 JS 的源头在 dsh-jsonl 仓库,本仓库存的是带版本标记的副本,用
|
||||
//! `scripts/vendor-dsh-jsonl.sh` 同步——**跨仓库没有自动同步**,见 [`TAP_PLUGIN_JS`]。
|
||||
//! 那个 JS 的源头在 dsh-events 仓库,本仓库存的是带版本标记的副本,用
|
||||
//! `scripts/vendor-dsh-events.sh` 同步——**跨仓库没有自动同步**,见 [`TAP_PLUGIN_JS`]。
|
||||
//!
|
||||
//! 而且 tap 是**纯增益**:它挂不上或者解析不出来,最终结果照样从 stdout 拿得到,
|
||||
//! 只是少了逐字流和工具展示。护栏不依赖它(见下)。
|
||||
@@ -35,14 +35,24 @@
|
||||
//! dsh 没有逐命令 deny 清单,沙箱经 `DSH_PERMISSION_MODE` 环境变量注入。OpenLess 只开放
|
||||
//! `read-only` / `workspace-write` 两档;遗留权限值统一 fail-closed 到只读。
|
||||
//!
|
||||
//! **要说准它到底挡什么**:`workspace-write` 下的可写根被 dsh 写死成
|
||||
//! `[工作目录, "/tmp", $TMPDIR]`(见 `@deepseek-ai/dsh-sandbox` 的 `writableRoots`),
|
||||
//! 且**没有配置项能收掉那两个临时目录**——Codex 那边有 `-c sandbox_workspace_write.
|
||||
//! exclude_*` 可以收紧,dsh 没有对应物。家目录与系统路径确实挡得住(实测报
|
||||
//! **要说准它到底挡什么**——dsh 有**两道松紧不同的围栏**(实测 0.1.0-rc.6):
|
||||
//!
|
||||
//! | 工具 | 可写范围 |
|
||||
//! |---|---|
|
||||
//! | `bash`(seatbelt 子进程沙箱) | 工作目录 + `/tmp` + `$TMPDIR` |
|
||||
//! | `write` / `edit`(进程内 fs 围栏) | 只有工作目录 |
|
||||
//!
|
||||
//! 那三个可写根被 dsh 写死在 `@deepseek-ai/dsh-sandbox` 的 `writableRoots` 里,
|
||||
//! **没有配置项能收掉那两个临时目录**——Codex 那边有 `-c sandbox_workspace_write.
|
||||
//! exclude_*` 可以收紧,dsh 没有对应物。家目录与系统路径两道围栏都挡得住(实测报
|
||||
//! `sandbox: file access denied under workspace-write mode`)。
|
||||
//!
|
||||
//! 所以对用户的措辞只能是「撞到限制会如实报错」,不能说成「写入限制在工作目录内」。
|
||||
//! 见 `live::tmp_is_writable_by_design_and_we_cannot_narrow_it`。
|
||||
//!
|
||||
//! 上面那张表**没有做成测试**,是有意的:验证它必然要让模型去写文件,而结果取决于模型
|
||||
//! 当次挑了 `bash` 还是 `write`——那种测试的红绿反映的是模型的心情,不是被测系统的行为。
|
||||
//! `live::sandbox_blocks_writes_outside_the_workspace` 打的是家目录,两道围栏都挡,
|
||||
//! 不受工具选择影响,那条才作数。
|
||||
//!
|
||||
//! # prompt 不进 argv
|
||||
//!
|
||||
@@ -70,23 +80,23 @@ use super::{CodingAgentError, CodingAgentPermissionMode};
|
||||
/// 但 `headless-startup` 仍要求 argv 上有个非空任务(空的话它会走 usage error 直接退出)。
|
||||
pub const ARGV_TASK_PLACEHOLDER: &str = "openless-task";
|
||||
|
||||
/// 内嵌的 dsh-jsonl 插件版本。必须与 `vendor/dsh-jsonl.js` 头部的标记一致——
|
||||
/// 内嵌的 dsh-events 插件版本。必须与 `vendor/dsh-events.js` 头部的标记一致——
|
||||
/// 下面的单测盯着这一点,防止有人直接改了 vendor 目录却没走同步流程。
|
||||
pub const VENDORED_DSH_JSONL_VERSION: &str = "0.1.0";
|
||||
pub const VENDORED_DSH_EVENTS_VERSION: &str = "0.1.0";
|
||||
|
||||
/// 我们能解析的 dsh-jsonl schema 大版本。插件报的对不上只记警告,不中止——
|
||||
/// 我们能解析的 dsh-events schema 大版本。插件报的对不上只记警告,不中止——
|
||||
/// 最终结果始终从 stdout 拿得到,流式展示只是锦上添花。
|
||||
pub const SUPPORTED_DSH_JSONL_SCHEMA: u64 = 1;
|
||||
pub const SUPPORTED_DSH_EVENTS_SCHEMA: u64 = 1;
|
||||
|
||||
/// 挂给 dsh 的输出插件,逐字内嵌自 [dsh-jsonl](https://github.com/bigsongeth/dsh-jsonl)。
|
||||
/// 挂给 dsh 的输出插件,逐字内嵌自 [dsh-events](https://github.com/bigsongeth/dsh-events)。
|
||||
///
|
||||
/// **不要在这里改它。** 源头在那个仓库,这里只是一份带版本标记的副本,用
|
||||
/// `scripts/vendor-dsh-jsonl.sh <checkout>` 同步。之所以内嵌而不是让 App 去依赖 npm 包:
|
||||
/// `scripts/vendor-dsh-events.sh <checkout>` 同步。之所以内嵌而不是让 App 去依赖 npm 包:
|
||||
/// 用户装机即用,不需要网络、不需要 `npm i`,也不会碰用户自己的 dsh profile 配置。
|
||||
///
|
||||
/// 跨仓库没有任何自动同步。忘了同步的后果是 OpenLess 停在旧版插件(照常工作),不是崩;
|
||||
/// 真的对不上时 `live::tap_plugin_delivers_streaming_and_tool_events` 会红。
|
||||
const TAP_PLUGIN_JS: &str = include_str!("vendor/dsh-jsonl.js");
|
||||
const TAP_PLUGIN_JS: &str = include_str!("vendor/dsh-events.js");
|
||||
|
||||
/// 权限模式 → `DSH_PERMISSION_MODE` 取值。
|
||||
///
|
||||
@@ -110,9 +120,9 @@ fn configure_dsh_environment(
|
||||
) {
|
||||
cmd.env("DSH_PERMISSION_MODE", dsh_permission_mode(permission_mode))
|
||||
// stdout 必须只保留 dsh 的最终文本;不允许继承用户环境把 JSONL 改到 stdout/文件。
|
||||
.env("DSH_JSONL_OUT", "stderr")
|
||||
.env("DSH_EVENTS_OUT", "stderr")
|
||||
// 原始事件可能包含不必要的内部数据,OpenLess 只消费公开 schema。
|
||||
.env_remove("DSH_JSONL_RAW");
|
||||
.env_remove("DSH_EVENTS_RAW");
|
||||
}
|
||||
|
||||
/// 构造 `dsh` 的命令行参数(不含可执行文件本身,也不含 prompt——prompt 走 patch 文件)。
|
||||
@@ -141,7 +151,7 @@ pub fn build_dsh_patch_yaml(plugin_js_path: &Path, prompt: &str) -> Result<Strin
|
||||
Ok(format!(
|
||||
r#"# Generated by OpenLess. Applied as the last patch layer for one headless run.
|
||||
- insert:
|
||||
- id: dsh-jsonl
|
||||
- id: dsh-events
|
||||
name: {quoted_path}
|
||||
- id: headless-runner
|
||||
config:
|
||||
@@ -161,7 +171,7 @@ fn dsh_task_for_request(req: &CodingAgentRequest) -> String {
|
||||
req.prompt.clone()
|
||||
}
|
||||
|
||||
/// 解析一行 dsh-jsonl 输出的 NDJSON(schema v1,见插件仓库的 SCHEMA.md)。
|
||||
/// 解析一行 dsh-events 输出的 NDJSON(schema v1,见插件仓库的 SCHEMA.md)。
|
||||
///
|
||||
/// 只认我们用得上的几种;**其余一律忽略**——这是 schema 的兼容性约定:消费者必须忽略
|
||||
/// 自己不认识的 type 和字段,上游加新事件才不会把我们打挂。
|
||||
@@ -299,7 +309,7 @@ impl TapWorkspace {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let _ = std::fs::set_permissions(&dir, std::fs::Permissions::from_mode(0o700));
|
||||
}
|
||||
let js_path = dir.join("dsh-jsonl.mjs");
|
||||
let js_path = dir.join("dsh-events.mjs");
|
||||
std::fs::write(&js_path, TAP_PLUGIN_JS).map_err(|e| format!("写 tap 插件失败: {e}"))?;
|
||||
let patch_path = dir.join("openless.patch.yml");
|
||||
std::fs::write(&patch_path, build_dsh_patch_yaml(&js_path, prompt)?)
|
||||
@@ -407,11 +417,11 @@ pub async fn run_dsh_agent(
|
||||
let _ = sink.send(protocol_state.observe(ev));
|
||||
} else if let Some(schema) = parse_dsh_schema_version(&l) {
|
||||
saw_tap = true;
|
||||
if schema != SUPPORTED_DSH_JSONL_SCHEMA {
|
||||
if schema != SUPPORTED_DSH_EVENTS_SCHEMA {
|
||||
// 插件 schema 大版本变了 = 破坏性变更。任务照跑(结果仍从
|
||||
// stdout 拿),但流式/工具展示可能不完整,留个声明性日志。
|
||||
log::warn!(
|
||||
"[dsh] 插件 schema v{schema} 与本版支持的 v{SUPPORTED_DSH_JSONL_SCHEMA} 不一致,本轮流式展示可能不完整"
|
||||
"[dsh] 插件 schema v{schema} 与本版支持的 v{SUPPORTED_DSH_EVENTS_SCHEMA} 不一致,本轮流式展示可能不完整"
|
||||
);
|
||||
}
|
||||
} else if l.trim_start().starts_with("{\"v\":") {
|
||||
@@ -536,12 +546,12 @@ mod tests {
|
||||
// 逐字比对而不是 contains:YAML 全靠缩进,缩进丢了 dsh 直接 `failed to parse`,
|
||||
// 而 contains 完全看不出来(这就是当初漏掉的那个 bug)。
|
||||
let yaml =
|
||||
build_dsh_patch_yaml(Path::new("/tmp/x/dsh-jsonl.mjs"), "读一下 a.txt").unwrap();
|
||||
build_dsh_patch_yaml(Path::new("/tmp/x/dsh-events.mjs"), "读一下 a.txt").unwrap();
|
||||
let expected = concat!(
|
||||
"# Generated by OpenLess. Applied as the last patch layer for one headless run.\n",
|
||||
"- insert:\n",
|
||||
" - id: dsh-jsonl\n",
|
||||
" name: \"/tmp/x/dsh-jsonl.mjs\"\n",
|
||||
" - id: dsh-events\n",
|
||||
" name: \"/tmp/x/dsh-events.mjs\"\n",
|
||||
"- id: headless-runner\n",
|
||||
" config:\n",
|
||||
" task: \"读一下 a.txt\"\n",
|
||||
@@ -602,19 +612,19 @@ mod tests {
|
||||
"DSH_PERMISSION_MODE".into(),
|
||||
Some("workspace-write".into())
|
||||
)));
|
||||
assert!(envs.contains(&("DSH_JSONL_OUT".into(), Some("stderr".into()))));
|
||||
assert!(envs.contains(&("DSH_JSONL_RAW".into(), None)));
|
||||
assert!(envs.contains(&("DSH_EVENTS_OUT".into(), Some("stderr".into()))));
|
||||
assert!(envs.contains(&("DSH_EVENTS_RAW".into(), None)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vendored_plugin_version_matches_the_constant() {
|
||||
// 防的是「有人直接改了 vendor/dsh-jsonl.js 却没走 scripts/vendor-dsh-jsonl.sh」。
|
||||
// 防的是「有人直接改了 vendor/dsh-events.js 却没走 scripts/vendor-dsh-events.sh」。
|
||||
// 跨仓库没有自动同步,这条是唯一能当场发现副本被手改的地方。
|
||||
let marker = format!("dsh-jsonl v{VENDORED_DSH_JSONL_VERSION}");
|
||||
let marker = format!("dsh-events v{VENDORED_DSH_EVENTS_VERSION}");
|
||||
assert!(
|
||||
TAP_PLUGIN_JS.lines().next().unwrap_or("").contains(&marker),
|
||||
"vendor/dsh-jsonl.js 首行的版本标记与 VENDORED_DSH_JSONL_VERSION 对不上;\
|
||||
跑 scripts/vendor-dsh-jsonl.sh 重新同步,并把常量改成一致"
|
||||
"vendor/dsh-events.js 首行的版本标记与 VENDORED_DSH_EVENTS_VERSION 对不上;\
|
||||
跑 scripts/vendor-dsh-events.sh 重新同步,并把常量改成一致"
|
||||
);
|
||||
assert!(
|
||||
TAP_PLUGIN_JS.contains("do not edit here"),
|
||||
@@ -650,7 +660,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parses_delta_and_tool_and_guard() {
|
||||
// 形状取自 dsh-jsonl schema v1(真实抓取的样本)。
|
||||
// 形状取自 dsh-events schema v1(真实抓取的样本)。
|
||||
assert_eq!(
|
||||
parse_dsh_tap_line(
|
||||
"s1",
|
||||
@@ -681,7 +691,7 @@ mod tests {
|
||||
parse_dsh_schema_version(
|
||||
r#"{"v":1,"seq":0,"ts":null,"type":"session.start","sessionId":"s","cwd":"/tmp","schema":1}"#
|
||||
),
|
||||
Some(SUPPORTED_DSH_JSONL_SCHEMA)
|
||||
Some(SUPPORTED_DSH_EVENTS_SCHEMA)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -769,7 +779,7 @@ mod tests {
|
||||
let ws = TapWorkspace::create("跑个测试").unwrap();
|
||||
assert!(ws.patch_path.exists(), "patch 文件应已落盘");
|
||||
assert!(
|
||||
ws.dir.join("dsh-jsonl.mjs").exists(),
|
||||
ws.dir.join("dsh-events.mjs").exists(),
|
||||
"tap 插件应已落盘"
|
||||
);
|
||||
let yaml = std::fs::read_to_string(&ws.patch_path).unwrap();
|
||||
@@ -882,37 +892,6 @@ mod live {
|
||||
assert!(!escaped, "沙箱失效:家目录下的文件被创建了 {}", victim.display());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore = "打真实 dsh CLI:要花钱、要网络"]
|
||||
async fn tmp_is_writable_by_design_and_we_cannot_narrow_it() {
|
||||
// 这条不是在测我们的代码,是把 **dsh 的既有行为钉成契约**:workspace-write 下
|
||||
// `/tmp` 与 `$TMPDIR` 可写,而且写死在 dsh 里、没有配置项能收掉(Codex 那边有
|
||||
// `-c sandbox_workspace_write.exclude_*`,dsh 没有对应物)。
|
||||
//
|
||||
// 所以我们对用户的说法只能是「撞到限制会如实报错」,不能说成「写入限制在工作目录内」。
|
||||
// 哪天 dsh 收紧了这条会红——那是好消息,届时删掉本测试并更新文档。
|
||||
let dir = fixture_dir();
|
||||
let target =
|
||||
std::env::temp_dir().join(format!("openless-dsh-tmp-{}.txt", uuid::Uuid::new_v4()));
|
||||
let c = run(
|
||||
&format!(
|
||||
"用 bash 执行:echo ok > {} 。做完只回答 DONE 或 BLOCKED。",
|
||||
target.display()
|
||||
),
|
||||
&dir,
|
||||
CodingAgentPermissionMode::AcceptEdits,
|
||||
)
|
||||
.await;
|
||||
println!("[dsh] 写 $TMPDIR 结果 completed={:?}", c.completed);
|
||||
let wrote = target.exists();
|
||||
let _ = std::fs::remove_file(&target);
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
assert!(
|
||||
wrote,
|
||||
"dsh 似乎已把 $TMPDIR 移出可写根——好事,请更新 dsh.rs 的护栏说明并删掉本测试"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[ignore = "打真实 dsh CLI:要花钱、要网络"]
|
||||
async fn prompt_starting_with_a_dash_is_not_parsed_as_a_flag() {
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
// Vendored from github.com/bigsongeth/dsh-jsonl v0.1.0 — do not edit here.
|
||||
// Run scripts/vendor-dsh-jsonl.sh <path-to-checkout> to update, then bump
|
||||
// VENDORED_DSH_JSONL_VERSION in dsh.rs to match.
|
||||
// Vendored from github.com/bigsongeth/dsh-events v0.1.0 — do not edit here.
|
||||
// Run scripts/vendor-dsh-events.sh <path-to-checkout> to update, then bump
|
||||
// VENDORED_DSH_EVENTS_VERSION in dsh.rs to match.
|
||||
//
|
||||
// MIT License
|
||||
//
|
||||
@@ -24,7 +24,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
// dsh-jsonl — structured event output for `dsh --profile headless`.
|
||||
// dsh-events — structured event output for `dsh --profile headless`.
|
||||
//
|
||||
// `dsh --profile headless "<task>"` prints one line: the final assistant message.
|
||||
// Everything that happened on the way — file reads, commands, streaming text,
|
||||
@@ -43,18 +43,18 @@ import { appendFileSync } from 'node:fs'
|
||||
export const SCHEMA_VERSION = 1
|
||||
|
||||
/** Stable Cordis plugin name. */
|
||||
export const name = 'dsh-jsonl'
|
||||
export const name = 'dsh-events'
|
||||
|
||||
/**
|
||||
* Where the NDJSON goes.
|
||||
*
|
||||
* Default is stderr, not stdout: stdout carries dsh's own final-message line,
|
||||
* which is its existing contract with every current consumer. Taking it over
|
||||
* would silently break them. Set DSH_JSONL_OUT=<file> to write to a file
|
||||
* instead, or DSH_JSONL_OUT=stdout if you genuinely want them interleaved.
|
||||
* would silently break them. Set DSH_EVENTS_OUT=<file> to write to a file
|
||||
* instead, or DSH_EVENTS_OUT=stdout if you genuinely want them interleaved.
|
||||
*/
|
||||
function makeWriter() {
|
||||
const target = process.env.DSH_JSONL_OUT
|
||||
const target = process.env.DSH_EVENTS_OUT
|
||||
if (!target || target === 'stderr') return line => process.stderr.write(line + '\n')
|
||||
if (target === 'stdout') return line => process.stdout.write(line + '\n')
|
||||
return line => appendFileSync(target, line + '\n')
|
||||
@@ -104,7 +104,7 @@ export function apply(ctx) {
|
||||
if (Object.keys(guard).length > 0) emit('guard', { seq: guardSeq }, guard)
|
||||
}
|
||||
|
||||
const raw = process.env.DSH_JSONL_RAW === '1'
|
||||
const raw = process.env.DSH_EVENTS_RAW === '1'
|
||||
|
||||
// `session.start` is emitted lazily on the first event, not at mount time:
|
||||
// the session identity does not exist yet when the plugin is applied.
|
||||
+10
-10
@@ -1,33 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copy the dsh-jsonl plugin into OpenLess.
|
||||
# Copy the dsh-events plugin into OpenLess.
|
||||
#
|
||||
# The plugin's source of truth is github.com/bigsongeth/dsh-jsonl. OpenLess
|
||||
# The plugin's source of truth is github.com/bigsongeth/dsh-events. OpenLess
|
||||
# embeds the source with its provenance and MIT license (via include_str!) so
|
||||
# the app needs no npm install and no network at runtime. Nothing syncs the two automatically —
|
||||
# run this after the upstream plugin changes, then run the dsh live acceptance
|
||||
# (see coding_agent::dsh::live) to confirm the Rust parser still agrees with it.
|
||||
#
|
||||
# scripts/vendor-dsh-jsonl.sh ~/Personal/dsh-jsonl
|
||||
# scripts/vendor-dsh-events.sh ~/Personal/dsh-events
|
||||
set -euo pipefail
|
||||
|
||||
SRC="${1:-}"
|
||||
if [[ -z "$SRC" || ! -f "$SRC/index.js" || ! -f "$SRC/package.json" || ! -f "$SRC/LICENSE" ]]; then
|
||||
echo "usage: $0 <path-to-dsh-jsonl-checkout>" >&2
|
||||
echo "usage: $0 <path-to-dsh-events-checkout>" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
VERSION=$(node -p "require('$SRC/package.json').version")
|
||||
DEST="$(cd "$(dirname "$0")/.." && pwd)/app/src-tauri/src/coding_agent/vendor/dsh-jsonl.js"
|
||||
DEST="$(cd "$(dirname "$0")/.." && pwd)/app/src-tauri/src/coding_agent/vendor/dsh-events.js"
|
||||
|
||||
{
|
||||
echo "// Vendored from github.com/bigsongeth/dsh-jsonl v${VERSION} — do not edit here."
|
||||
echo "// Run scripts/vendor-dsh-jsonl.sh <path-to-checkout> to update, then bump"
|
||||
echo "// VENDORED_DSH_JSONL_VERSION in dsh.rs to match."
|
||||
echo "// Vendored from github.com/bigsongeth/dsh-events v${VERSION} — do not edit here."
|
||||
echo "// Run scripts/vendor-dsh-events.sh <path-to-checkout> to update, then bump"
|
||||
echo "// VENDORED_DSH_EVENTS_VERSION in dsh.rs to match."
|
||||
echo "//"
|
||||
awk '{ print (length($0) ? "// " $0 : "//") }' "$SRC/LICENSE"
|
||||
echo "//"
|
||||
cat "$SRC/index.js"
|
||||
} > "$DEST"
|
||||
|
||||
echo "vendored dsh-jsonl v${VERSION} -> ${DEST}"
|
||||
echo "next: set VENDORED_DSH_JSONL_VERSION = \"${VERSION}\" in coding_agent/dsh.rs"
|
||||
echo "vendored dsh-events v${VERSION} -> ${DEST}"
|
||||
echo "next: set VENDORED_DSH_EVENTS_VERSION = \"${VERSION}\" in coding_agent/dsh.rs"
|
||||
Reference in new issue
Block a user