合并 origin/master 并同步 SpacetimeDB 2.8.3 指导
Project CI / Repository checks (pull_request) Successful in 2m55s
Project CI / Frontend tests (pull_request) Successful in 3m2s
Project CI / Backend tests (pull_request) Successful in 5m54s
Project CI / Native shell tests (pull_request) Successful in 13m24s

合并 origin/master 的工具与文档迁移

删除已被统一 skill 替代的旧 SpacetimeDB skill

将统一 SpacetimeDB 指导更新到 2.8.3
This commit is contained in:
2026-08-27 14:16:40 +08:00
91 changed files with 253 additions and 1036 deletions
@@ -1286,7 +1286,6 @@ fn bridge_project_file_is_hidden_control_path(path: &str) -> bool {
part.eq_ignore_ascii_case(".agent")
|| part.eq_ignore_ascii_case(".git")
|| part.eq_ignore_ascii_case(".codex")
|| part.eq_ignore_ascii_case(".hermes")
|| part.eq_ignore_ascii_case("node_modules")
})
}
@@ -2312,7 +2311,7 @@ mod tests {
for path in [
".agent/manifest.json",
"tools/.codex/private.png",
"vendor/.hermes/private.png",
"vendor/.codex/private.png",
"game/node_modules/private.png",
] {
assert!(
@@ -612,9 +612,9 @@ fn validate_account_asset_import_string_array(
));
}
if should_skip_project_snapshot_path(text)
|| text.split('/').any(|part| {
part.eq_ignore_ascii_case(".codex") || part.eq_ignore_ascii_case(".hermes")
})
|| text
.split('/')
.any(|part| part.eq_ignore_ascii_case(".codex"))
|| reject_sensitive_project_file_read(text).is_err()
{
return Err(format!("工具参数 {field} 不得访问隐藏、构建或敏感控制路径"));
@@ -1288,7 +1288,7 @@ mod tests {
.is_err());
for local_path in [
"tools/.codex/hero.png",
"vendor/.hermes/hero.png",
"vendor/.codex/hero.png",
"game/node_modules/hero.png",
"secrets/hero.png",
] {
@@ -184,9 +184,9 @@ fn prompt_context_hidden_project_path(path: &str) -> bool {
// directories and sensitive file suffixes; a media extension alone must
// never make one of those paths visible to the model.
should_skip_project_snapshot_path(path)
|| path.split('/').any(|component| {
component.eq_ignore_ascii_case(".codex") || component.eq_ignore_ascii_case(".hermes")
})
|| path
.split('/')
.any(|component| component.eq_ignore_ascii_case(".codex"))
}
fn prompt_context_media_type(path: &str) -> Option<&'static str> {
@@ -470,9 +470,9 @@ fn runtime_asset_import_string_array(
|| text.contains("://")
|| has_parent
|| should_skip_project_snapshot_path(text)
|| text.split('/').any(|part| {
part.eq_ignore_ascii_case(".codex") || part.eq_ignore_ascii_case(".hermes")
})
|| text
.split('/')
.any(|part| part.eq_ignore_ascii_case(".codex"))
|| reject_sensitive_project_file_read(text).is_err()
{
return Err("localPaths 只能使用受控项目根内的项目相对图片路径".to_string());
@@ -774,7 +774,7 @@ mod asset_import_input_tests {
assert!(runtime_asset_import_string_array(&private, "localPaths", 100).is_err());
for protected in [
"tools/.codex/hero.png",
"vendor/.hermes/hero.png",
"vendor/.codex/hero.png",
"game/node_modules/hero.png",
"secrets/hero.png",
] {
@@ -759,7 +759,6 @@ fn project_command_argument_contains_sensitive_path(value: &str) -> bool {
| ".git"
| ".agents"
| ".codex"
| ".hermes"
| ".hg"
| ".svn"
| ".ssh"
@@ -2280,7 +2279,7 @@ mod tests {
async fn project_command_workspace_sandbox_blocks_host_controls_and_network() {
let dir = command_project("workspace-sandbox");
let root = dir.path();
for name in [".git", ".agents", ".codex", ".hermes"] {
for name in [".git", ".agents", ".codex"] {
fs::create_dir_all(root.join(name)).expect("create protected directory");
fs::write(root.join(name).join("marker"), name).expect("write protected marker");
}
@@ -2294,7 +2293,7 @@ mod tests {
printf WORKSPACE_OK > workspace-write.txt
test ! -r {outside:?}
! printf NO > {outside:?}
for control in .git .agents .codex .hermes; do
for control in .git .agents .codex; do
test -r "$control/marker"
! touch "$control/blocked-write"
done
@@ -2326,7 +2325,7 @@ raise SystemExit(code)'
fs::read_to_string(&outside).expect("outside sentinel"),
"HOST_SECRET"
);
for name in [".git", ".agents", ".codex", ".hermes"] {
for name in [".git", ".agents", ".codex"] {
assert!(!root.join(name).join("blocked-write").exists());
}
fs::remove_file(outside).ok();
@@ -181,7 +181,7 @@ mod linux {
use std::time::{Duration, Instant};
const TRUSTED_BWRAP_PATHS: [&str; 2] = ["/usr/bin/bwrap", "/bin/bwrap"];
const PROTECTED_READ_ONLY_NAMES: [&str; 4] = [".git", ".agents", ".codex", ".hermes"];
const PROTECTED_READ_ONLY_NAMES: [&str; 3] = [".git", ".agents", ".codex"];
const TOOLCHAIN_ENVIRONMENT_ROOTS: [&str; 4] =
["RUSTUP_HOME", "JAVA_HOME", "GOROOT", "DOTNET_ROOT"];
const FIXED_SYSTEM_READ_ONLY_PATHS: [&str; 8] = [
@@ -962,7 +962,6 @@ mod linux {
PathBuf::from("/workspace/project/.git"),
PathBuf::from("/workspace/project/.agents"),
PathBuf::from("/workspace/project/.codex"),
PathBuf::from("/workspace/project/.hermes"),
],
external_read_only: vec![ReadOnlyMount {
source: PathBuf::from("/opt/toolchain/bin/tool"),
@@ -995,7 +994,7 @@ mod linux {
&launch.arguments,
&["--bind", "/workspace/project", "/workspace/project"]
));
for path in [".git", ".agents", ".codex", ".hermes"] {
for path in [".git", ".agents", ".codex"] {
let path = format!("/workspace/project/{path}");
assert!(has_sequence(
&launch.arguments,
@@ -1162,7 +1161,7 @@ mod linux {
let outside = tree.0.join("outside-secret.txt");
std::fs::create_dir_all(&root).expect("create workspace");
std::fs::write(&outside, "OUTSIDE_SECRET").expect("write outside secret");
for name in [".agent", ".git", ".agents", ".codex", ".hermes"] {
for name in [".agent", ".git", ".agents", ".codex"] {
std::fs::create_dir_all(root.join(name)).expect("create control directory");
std::fs::write(root.join(name).join("marker"), name).expect("write control marker");
}
@@ -1175,7 +1174,7 @@ import subprocess
Path("workspace-write.txt").write_text("WORKSPACE_OK")
assert Path("workspace-write.txt").read_text() == "WORKSPACE_OK"
for control in [".git", ".agents", ".codex", ".hermes"]:
for control in [".git", ".agents", ".codex"]:
assert Path(control, "marker").read_text() == control
try:
Path(control, "blocked-write").write_text("NO")
@@ -1259,7 +1258,7 @@ print("SANDBOX_OK")
std::fs::read_to_string(&outside).expect("outside secret unchanged"),
"OUTSIDE_SECRET"
);
for name in [".git", ".agents", ".codex", ".hermes"] {
for name in [".git", ".agents", ".codex"] {
assert!(!root.join(name).join("blocked-write").exists());
}
}
@@ -1272,7 +1271,7 @@ print("SANDBOX_OK")
let tree = unique_temp_tree();
let root = tree.0.join("workspace-staged-gate");
std::fs::create_dir_all(&root).expect("create workspace");
for name in [".agent", ".git", ".agents", ".codex", ".hermes"] {
for name in [".agent", ".git", ".agents", ".codex"] {
std::fs::create_dir_all(root.join(name)).expect("create control directory");
}
let marker = root.join("committed-target-ran");
@@ -2802,7 +2802,6 @@ mod agent_asset_import_tests {
for (index, directory) in [
".git",
".codex",
".hermes",
"node_modules",
"target",
"dist",
@@ -3350,7 +3349,7 @@ fn reject_agent_local_image_source_path(normalized_path: &str) -> Result<(), Str
if should_skip_project_snapshot_path(normalized_path)
|| normalized_path
.split('/')
.any(|part| part.eq_ignore_ascii_case(".codex") || part.eq_ignore_ascii_case(".hermes"))
.any(|part| part.eq_ignore_ascii_case(".codex"))
{
return Err("本地图片导入不得访问隐藏、构建或工具控制目录".to_string());
}
@@ -189,7 +189,6 @@ function isVisibleProjectPath(localPath: string) {
'secrets',
'credentials',
'.codex',
'.hermes',
'node_modules',
'target',
'dist',