@steerable/agent-shell 0.8.1 → 0.8.2

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.
@@ -38,7 +38,7 @@ import { createJsonStore } from '../json-store.js';
38
38
  import { bindWorkspaceSkillRoots, listSkillRoots } from '../local-backend/skill-loader.js';
39
39
  import { collectPackExecWritableRoots } from '../local-backend/pack-turn-hooks.js';
40
40
  import { getChatAttachmentsDir } from '../attachments.js';
41
- import { ensureChatWorkspace } from '../project-home.js';
41
+ import { ensureChatWorkspace, ensureWritableRoots } from '../project-home.js';
42
42
  import { recordInsightTurn } from '../insights/record.js';
43
43
  import { llmService } from '../llm/index.js';
44
44
  import { isProductLlmLocked, resolveRuntimeLlmSettings } from '../host-tools-runtime.js';
@@ -323,12 +323,14 @@ export async function createHostRuntime(options) {
323
323
  ];
324
324
  },
325
325
  // 写:源文件夹、包声明的可写根,以及各自的子目录。附件目录保持只读。
326
+ // ensureWritableRoots 让这些名字先落成目录:Landlock/bwrap 在安装沙箱
327
+ // 规则时要 open 它们,声明了却还没建过的目录会让子进程起不来。
326
328
  resolveAdditionalWriteRoots: async (chatId) => {
327
329
  const project = await localBackendRouter.resolveChatProject(chatId);
328
- return [
330
+ return ensureWritableRoots([
329
331
  ...(project?.sourceFolders ?? []),
330
332
  ...collectPackExecWritableRoots(chatId),
331
- ];
333
+ ]);
332
334
  },
333
335
  approvalHandler: approvalBridge.handler,
334
336
  askUserHandler: askUserBridge.handler,
@@ -52,7 +52,7 @@ import { parseImageAttachments, processImageAttachments } from '../image-attachm
52
52
  import { chatAttachmentsDirPath, isValidChatAttachmentsKey } from '../attachments.js';
53
53
  import { canonicalFencePath, canonicalPathInside } from '../fence-path.js';
54
54
  import { listProjectRuleFiles, loadProjectRuleFiles } from '../project-rules.js';
55
- import { allocateProjectHome, chatWorkspacePath, ensureChatWorkspace, ensureProjectHome, expandUserPath, } from '../project-home.js';
55
+ import { allocateProjectHome, chatWorkspacePath, ensureChatWorkspace, ensureProjectHome, ensureWritableRoots, expandUserPath, } from '../project-home.js';
56
56
  import { registerLiveStream, getLiveStream, removeLiveStream } from './live-stream.js';
57
57
  import { compactHistory, forkHistory, rewindFrom } from './history-edit.js';
58
58
  import { copyForkDirectory, DEFAULT_FORK_WORKSPACE_MAX_BYTES, directorySizeBytes, forkPathRewriter, removeForkDirectory, } from './fork-copy.js';
@@ -3778,11 +3778,11 @@ export class LocalBackendRouter {
3778
3778
  // (项目根 + 包工作区),与沙箱是否启用无关——「完整权限」下根列表只是
3779
3779
  // 不再被强制,产物仍大概率落在这里;根之外的显式写由工具参数并集补。
3780
3780
  const turnStartedAtMs = Date.now();
3781
- const turnFileRoots = [
3781
+ const turnFileRoots = ensureWritableRoots([
3782
3782
  ...collectPackExecWritableRoots(chatId),
3783
3783
  workspaceRoot,
3784
3784
  ...(chatProject?.sourceFolders ?? []),
3785
- ];
3785
+ ]);
3786
3786
  try {
3787
3787
  const coreLoopOptions = {
3788
3788
  supervisor,
@@ -23,6 +23,18 @@ export declare function allocateProjectHome(projectName: string, options?: {
23
23
  exists?: (folderPath: string) => boolean;
24
24
  }): string;
25
25
  export declare function ensureProjectHome(folderPath: string): void;
26
+ /**
27
+ * 把一批可写根落成真实目录,返回原列表(便于链式使用)。
28
+ *
29
+ * Linux 的 Landlock 在安装规则时逐个 open 这些路径,bwrap 则要 bind mount
30
+ * 它们;声明了但还没建过的目录会让被沙箱的子进程直接起不来
31
+ * (`writable root … does not exist`)。这与 supervisor 启动时对
32
+ * `sandboxWritableRoots` 做的 mkdir 是同一个前置条件。
33
+ *
34
+ * 建不出来的根**留在列表里**:沙箱应当因此明确拒绝这次调用,而不是悄悄
35
+ * 少一份写权限继续跑。
36
+ */
37
+ export declare function ensureWritableRoots(roots: readonly string[]): string[];
26
38
  /** 无项目对话的工作区子目录名(与托管项目家目录并列,避免撞名)。 */
27
39
  export declare const CHAT_WORKSPACES_DIR = "conversations";
28
40
  /**
@@ -56,6 +56,30 @@ export function allocateProjectHome(projectName, options) {
56
56
  export function ensureProjectHome(folderPath) {
57
57
  fs.mkdirSync(folderPath, { recursive: true });
58
58
  }
59
+ /**
60
+ * 把一批可写根落成真实目录,返回原列表(便于链式使用)。
61
+ *
62
+ * Linux 的 Landlock 在安装规则时逐个 open 这些路径,bwrap 则要 bind mount
63
+ * 它们;声明了但还没建过的目录会让被沙箱的子进程直接起不来
64
+ * (`writable root … does not exist`)。这与 supervisor 启动时对
65
+ * `sandboxWritableRoots` 做的 mkdir 是同一个前置条件。
66
+ *
67
+ * 建不出来的根**留在列表里**:沙箱应当因此明确拒绝这次调用,而不是悄悄
68
+ * 少一份写权限继续跑。
69
+ */
70
+ export function ensureWritableRoots(roots) {
71
+ for (const root of new Set(roots)) {
72
+ if (typeof root !== 'string' || !root.trim())
73
+ continue;
74
+ try {
75
+ fs.mkdirSync(root, { recursive: true });
76
+ }
77
+ catch (err) {
78
+ console.warn(`[project-home] cannot create writable root ${root}: ${err.message}`);
79
+ }
80
+ }
81
+ return [...roots];
82
+ }
59
83
  /** 无项目对话的工作区子目录名(与托管项目家目录并列,避免撞名)。 */
60
84
  export const CHAT_WORKSPACES_DIR = 'conversations';
61
85
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steerable/agent-shell",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "Steerable framework — product-neutral Node HostRuntime and headless HTTP server shared by Tauri desktop and browser deployments; scenario packs extend it through @steerable/pack-sdk.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://steerableframework.com/",
@@ -53,9 +53,9 @@
53
53
  "jpeg-js": "^0.4.4",
54
54
  "node-pty": "^1.1.0",
55
55
  "pngjs": "^7.0.0",
56
- "@steerable/agent-harness": "0.8.1",
57
- "@steerable/agent-protocol": "0.8.1",
58
- "@steerable/pack-sdk": "0.8.1"
56
+ "@steerable/agent-harness": "0.8.2",
57
+ "@steerable/agent-protocol": "0.8.2",
58
+ "@steerable/pack-sdk": "0.8.2"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@types/better-sqlite3": "^7.6.13",