clay-server 4.0.0-beta.2 → 4.0.0-beta.21
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/lib/background-task-timing.js +105 -0
- package/lib/capsule-display-floor.js +51 -0
- package/lib/capsule-frame-server.js +255 -0
- package/lib/capsule-mate-turn.js +105 -0
- package/lib/capsule-pig-logic.js +300 -0
- package/lib/capsule-server-runtimes.js +39 -0
- package/lib/capsules/pig/display.js +198 -0
- package/lib/capsules/pig/manifest.json +9 -0
- package/lib/capsules/pig/ui.json +84 -0
- package/lib/config.js +25 -1
- package/lib/daemon-projects.js +13 -8
- package/lib/daemon.js +127 -14
- package/lib/git-cli.js +95 -1
- package/lib/knowledge-import.js +436 -0
- package/lib/knowledge-record-store.js +188 -0
- package/lib/knowledge-search.js +240 -0
- package/lib/mate-knowledge-mcp-server.js +151 -0
- package/lib/mate-knowledge-migration.js +283 -0
- package/lib/mate-knowledge-service.js +488 -0
- package/lib/mate-knowledge-sync.js +482 -0
- package/lib/migrate-single-user.js +2 -0
- package/lib/notes-lifecycle.js +149 -0
- package/lib/notes.js +60 -3
- package/lib/os-users.js +3 -1
- package/lib/project-capsule-catalog.js +9 -1
- package/lib/project-capsule-turn.js +96 -0
- package/lib/project-connection.js +14 -1
- package/lib/project-http.js +15 -1
- package/lib/project-knowledge.js +22 -0
- package/lib/project-log-context.js +172 -0
- package/lib/project-log-feedback-delivery.js +118 -0
- package/lib/project-logs-comments.js +137 -0
- package/lib/project-logs-context-state.js +42 -0
- package/lib/project-logs-mcp-server.js +328 -0
- package/lib/project-logs-query.js +185 -0
- package/lib/project-logs-root.js +75 -0
- package/lib/project-logs-schema.js +259 -0
- package/lib/project-logs-service.js +463 -0
- package/lib/project-logs-snapshot.js +205 -0
- package/lib/project-logs-store.js +495 -0
- package/lib/project-logs-versioning.js +132 -0
- package/lib/project-logs.js +400 -0
- package/lib/project-mate-interaction.js +14 -0
- package/lib/project-mate-knowledge.js +110 -0
- package/lib/project-memory.js +22 -0
- package/lib/project-message-delivery.js +70 -0
- package/lib/project-pair-lifecycle.js +460 -0
- package/lib/project-session-handoff.js +1 -1
- package/lib/project-session-notes.js +64 -13
- package/lib/project-session-pair.js +159 -146
- package/lib/project-session-spawn.js +1 -1
- package/lib/project-sessions.js +58 -13
- package/lib/project-user-message.js +53 -4
- package/lib/project-vendor-login.js +20 -3
- package/lib/project-worker-permission.js +430 -0
- package/lib/project-worker-proposal.js +208 -62
- package/lib/project.js +178 -6
- package/lib/public/app.js +58 -35
- package/lib/public/css/admin.css +2 -2
- package/lib/public/css/capsule-ui.css +38 -0
- package/lib/public/css/command-palette.css +19 -9
- package/lib/public/css/git-placard.css +154 -0
- package/lib/public/css/home-hub.css +4 -0
- package/lib/public/css/home-session-actions.css +66 -0
- package/lib/public/css/home-sidebar.css +66 -0
- package/lib/public/css/input.css +163 -28
- package/lib/public/css/mobile-nav.css +80 -0
- package/lib/public/css/notifications-center.css +67 -0
- package/lib/public/css/pane.css +52 -0
- package/lib/public/css/project-logs.css +198 -0
- package/lib/public/css/scheduler.css +1 -1
- package/lib/public/css/session-actions.css +16 -101
- package/lib/public/css/sidebar.css +103 -0
- package/lib/public/css/sticky-notes.css +237 -229
- package/lib/public/css/worker-proposal.css +34 -1
- package/lib/public/index.html +45 -11
- package/lib/public/modules/admin.js +8 -8
- package/lib/public/modules/app-connection.js +109 -4
- package/lib/public/modules/app-home-hub.js +19 -7
- package/lib/public/modules/app-message-cards.js +2 -1
- package/lib/public/modules/app-messages.js +84 -7
- package/lib/public/modules/app-misc.js +2 -14
- package/lib/public/modules/app-notifications.js +11 -7
- package/lib/public/modules/app-panels.js +46 -4
- package/lib/public/modules/app-projects.js +13 -8
- package/lib/public/modules/app-rendering.js +1 -0
- package/lib/public/modules/background-tasks-ui.js +139 -16
- package/lib/public/modules/capsule-preference.js +44 -0
- package/lib/public/modules/chat-bubble-renderer.js +1 -1
- package/lib/public/modules/clay-log-links.js +70 -0
- package/lib/public/modules/command-palette.js +52 -15
- package/lib/public/modules/context-sources.js +0 -3
- package/lib/public/modules/git-agent-sessions.js +85 -0
- package/lib/public/modules/git-panel.js +111 -84
- package/lib/public/modules/git-placard.js +161 -0
- package/lib/public/modules/home-chat-empty-state.js +39 -0
- package/lib/public/modules/home-chat-identity.js +9 -0
- package/lib/public/modules/home-conversations-sheet.js +102 -48
- package/lib/public/modules/home-mate-chat.js +15 -35
- package/lib/public/modules/home-session-actions.js +6 -0
- package/lib/public/modules/home-sidebar-chat-list.js +101 -41
- package/lib/public/modules/home-sidebar.js +7 -0
- package/lib/public/modules/home-tool-frame.js +182 -0
- package/lib/public/modules/home-tools.js +138 -1
- package/lib/public/modules/input.js +38 -7
- package/lib/public/modules/markdown.js +2 -0
- package/lib/public/modules/mate-sidebar.js +0 -8
- package/lib/public/modules/message-delivery.js +97 -0
- package/lib/public/modules/paste-modal.js +84 -0
- package/lib/public/modules/project-logs-render.js +405 -0
- package/lib/public/modules/project-logs.js +461 -0
- package/lib/public/modules/project-removal-target.js +26 -0
- package/lib/public/modules/scheduler.js +17 -3
- package/lib/public/modules/session-actions.js +29 -105
- package/lib/public/modules/session-hierarchy.js +54 -0
- package/lib/public/modules/sidebar-mobile.js +40 -15
- package/lib/public/modules/sidebar-session-hierarchy.js +214 -0
- package/lib/public/modules/sidebar-sessions.js +77 -11
- package/lib/public/modules/sidebar.js +17 -5
- package/lib/public/modules/split-group-helpers.js +8 -0
- package/lib/public/modules/split-view.js +5 -2
- package/lib/public/modules/sticky-note-markdown.js +5 -0
- package/lib/public/modules/sticky-notes-browser.js +326 -0
- package/lib/public/modules/sticky-notes-card.js +360 -0
- package/lib/public/modules/sticky-notes-editor.js +291 -0
- package/lib/public/modules/sticky-notes-shared.js +90 -0
- package/lib/public/modules/sticky-notes.js +170 -946
- package/lib/public/modules/tool-palette-order.js +143 -0
- package/lib/public/modules/tool-palette-overlays.js +159 -0
- package/lib/public/modules/tool-palette.js +21 -188
- package/lib/public/modules/tools.js +21 -1
- package/lib/public/modules/update-snooze.js +169 -0
- package/lib/public/modules/user-settings.js +4 -0
- package/lib/public/modules/worker-pane-lock.js +176 -0
- package/lib/public/modules/worker-proposal-state.js +16 -0
- package/lib/public/modules/worker-proposal.js +49 -12
- package/lib/public/style.css +3 -1
- package/lib/sdk-bridge.js +132 -46
- package/lib/sdk-message-processor.js +60 -14
- package/lib/server-experimental-settings.js +49 -0
- package/lib/server-global-ws.js +11 -0
- package/lib/server-home-chat-events.js +31 -1
- package/lib/server-home-chat.js +27 -4
- package/lib/server-home-clay-entry.js +1 -1
- package/lib/server-home-clay-session-links.js +34 -5
- package/lib/server-settings.js +5 -0
- package/lib/server-tools.js +127 -9
- package/lib/server.js +124 -18
- package/lib/session-driver-eligibility.js +38 -0
- package/lib/session-driver-orchestration.js +31 -0
- package/lib/session-hygiene.js +3 -0
- package/lib/session-notes-mcp-server.js +25 -5
- package/lib/session-pair-factory.js +247 -0
- package/lib/session-pair-mcp-server.js +46 -8
- package/lib/session-pair-prompts.js +79 -0
- package/lib/session-pair-turn-control.js +153 -0
- package/lib/session-provenance.js +119 -0
- package/lib/session-spawn-mcp-server.js +1 -1
- package/lib/session-split-groups.js +4 -1
- package/lib/session-title-policy.js +60 -0
- package/lib/session-visibility.js +39 -0
- package/lib/sessions.js +61 -11
- package/lib/tools-registry.js +89 -10
- package/lib/update-snooze.js +437 -0
- package/lib/users-experimental-preferences.js +30 -0
- package/lib/users-permissions.js +2 -2
- package/lib/users.js +22 -16
- package/lib/workspace-query-access.js +102 -0
- package/lib/workspace-query-service.js +24 -17
- package/lib/worktree.js +25 -38
- package/lib/ws-schema.js +38 -7
- package/lib/yoke/adapters/claude-worker.js +16 -6
- package/lib/yoke/adapters/claude.js +81 -4
- package/lib/yoke/adapters/codex.js +63 -15
- package/lib/yoke/codex-background-tasks.js +8 -2
- package/lib/yoke/vendor-registry.js +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
var sessionSearch = require("./session-search");
|
|
2
2
|
var builtinMates = require("./builtin-mates");
|
|
3
|
+
var workspaceQueryAccess = require("./workspace-query-access");
|
|
3
4
|
var crypto = require("crypto");
|
|
4
5
|
|
|
5
6
|
var MAX_PAGE = 50;
|
|
@@ -100,7 +101,13 @@ function attachWorkspaceQueryService(ctx) {
|
|
|
100
101
|
var getProjects = ctx.getProjects;
|
|
101
102
|
var isMultiUser = ctx.isMultiUser;
|
|
102
103
|
var resolveMate = ctx.resolveMate;
|
|
103
|
-
|
|
104
|
+
// Ownership and access both come from here, never from getStatus().
|
|
105
|
+
var projectAccess = workspaceQueryAccess.attachWorkspaceQueryAccess({
|
|
106
|
+
isMultiUser: isMultiUser,
|
|
107
|
+
resolveMate: resolveMate,
|
|
108
|
+
onGetProjectAccess: ctx.onGetProjectAccess,
|
|
109
|
+
canAccessProject: ctx.canAccessProject,
|
|
110
|
+
});
|
|
104
111
|
|
|
105
112
|
function authoritativeMate(source) {
|
|
106
113
|
if (!source || source.isMate !== true || !source.mateId || typeof resolveMate !== "function") return null;
|
|
@@ -164,12 +171,6 @@ function attachWorkspaceQueryService(ctx) {
|
|
|
164
171
|
});
|
|
165
172
|
}
|
|
166
173
|
|
|
167
|
-
function ownsProject(principal, status) {
|
|
168
|
-
if (!status || status.isWorktree) return false;
|
|
169
|
-
if (isMultiUser()) return !!principal.userId && status.projectOwnerId === principal.userId;
|
|
170
|
-
return !status.projectOwnerId || (!!principal.singleUserOwnerId && status.projectOwnerId === principal.singleUserOwnerId);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
174
|
function ownsSession(principal, session) {
|
|
174
175
|
if (!session || session.hidden) return false;
|
|
175
176
|
if (isMultiUser()) return !!principal.userId && session.ownerId === principal.userId;
|
|
@@ -180,12 +181,12 @@ function attachWorkspaceQueryService(ctx) {
|
|
|
180
181
|
var projects = [];
|
|
181
182
|
getProjects().forEach(function (project, slug) {
|
|
182
183
|
var status = project.getStatus();
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
184
|
+
if (!status || status.isWorktree) return;
|
|
185
|
+
// Authorized here rather than at bind time, so an already-created tool
|
|
186
|
+
// handler loses a project the moment its access record changes.
|
|
187
|
+
var verdict = projectAccess.evaluate(principal, status);
|
|
188
|
+
if (!verdict.accessible) return;
|
|
189
|
+
var projectOwned = verdict.owned;
|
|
189
190
|
var manager = project.getSessionManager ? project.getSessionManager() : project.sm;
|
|
190
191
|
if (!manager || !manager.sessions) return;
|
|
191
192
|
var sessions = [];
|
|
@@ -305,14 +306,20 @@ function attachWorkspaceQueryService(ctx) {
|
|
|
305
306
|
function searchHistory(principal, projectSlug, args) {
|
|
306
307
|
var query = cleanText(args && args.query || "", 500);
|
|
307
308
|
if (!query) throw new Error("A search query is required.");
|
|
308
|
-
|
|
309
|
+
// One authorization snapshot for the whole call. Resolving hits back to
|
|
310
|
+
// their project through findProject() would re-authorize every project once
|
|
311
|
+
// per hit, so the visible set is captured once and indexed.
|
|
312
|
+
var visible;
|
|
309
313
|
if (projectSlug) {
|
|
310
314
|
var project = findProject(principal, projectSlug);
|
|
311
315
|
if (!project) throw new Error("Project not found in the owned workspace.");
|
|
312
|
-
|
|
316
|
+
visible = [project];
|
|
313
317
|
} else {
|
|
314
|
-
|
|
318
|
+
visible = collect(principal);
|
|
315
319
|
}
|
|
320
|
+
var bySlug = {};
|
|
321
|
+
for (var v = 0; v < visible.length; v++) bySlug[visible[v].projectSlug] = visible[v];
|
|
322
|
+
var projects = visible.map(sanitizedProject);
|
|
316
323
|
var max = Math.min(100, decodeCursor(args && args.cursor) + parseLimit(args && args.limit, 20) + 20);
|
|
317
324
|
var ranked = sessionSearch.searchPalette(projects, query, { maxResults: max });
|
|
318
325
|
var offset = decodeCursor(args && args.cursor);
|
|
@@ -321,7 +328,7 @@ function attachWorkspaceQueryService(ctx) {
|
|
|
321
328
|
var results = [];
|
|
322
329
|
for (var i = 0; i < selected.length; i++) {
|
|
323
330
|
var hit = selected[i];
|
|
324
|
-
var projectForHit =
|
|
331
|
+
var projectForHit = bySlug[hit.projectSlug] || null;
|
|
325
332
|
var session = projectForHit ? findSession(projectForHit, String(hit.sessionId)) : null;
|
|
326
333
|
if (!session) continue;
|
|
327
334
|
results.push({
|
package/lib/worktree.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var { execFileSync } = require("child_process");
|
|
2
1
|
var fs = require("fs");
|
|
3
2
|
var path = require("path");
|
|
3
|
+
var { runGitSync } = require("./git-cli");
|
|
4
4
|
|
|
5
5
|
// Parse `git worktree list --porcelain` output into structured objects
|
|
6
6
|
function parseWorktreeOutput(output) {
|
|
@@ -28,14 +28,10 @@ function parseWorktreeOutput(output) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// Check if a given path is itself a worktree (not the main working tree)
|
|
31
|
-
function isWorktree(projectPath) {
|
|
31
|
+
function isWorktree(projectPath, osUserInfo) {
|
|
32
32
|
try {
|
|
33
|
-
var gitDir =
|
|
34
|
-
|
|
35
|
-
}).trim();
|
|
36
|
-
var commonDir = execFileSync("git", ["rev-parse", "--git-common-dir"], {
|
|
37
|
-
cwd: projectPath, encoding: "utf8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"],
|
|
38
|
-
}).trim();
|
|
33
|
+
var gitDir = runGitSync(projectPath, ["rev-parse", "--git-dir"], null, osUserInfo).trim();
|
|
34
|
+
var commonDir = runGitSync(projectPath, ["rev-parse", "--git-common-dir"], null, osUserInfo).trim();
|
|
39
35
|
var absGit = path.resolve(projectPath, gitDir);
|
|
40
36
|
var absCommon = path.resolve(projectPath, commonDir);
|
|
41
37
|
return absGit !== absCommon;
|
|
@@ -49,18 +45,21 @@ function isPathInside(parentPath, candidatePath) {
|
|
|
49
45
|
return relative !== "" && relative !== ".." && relative.indexOf(".." + path.sep) !== 0 && !path.isAbsolute(relative);
|
|
50
46
|
}
|
|
51
47
|
|
|
48
|
+
function worktreePath(projectPath, dirName) {
|
|
49
|
+
if (typeof dirName !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(dirName)) return null;
|
|
50
|
+
var resolvedParent = path.resolve(projectPath);
|
|
51
|
+
var resolvedWorktree = path.resolve(resolvedParent, dirName);
|
|
52
|
+
return isPathInside(resolvedParent, resolvedWorktree) ? resolvedWorktree : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
52
55
|
// Scan worktrees for a given project path
|
|
53
56
|
// Returns array of { path, branch, bare, detached, external }
|
|
54
57
|
// external = true when Git registered the worktree outside the main project folder
|
|
55
|
-
function scanWorktrees(projectPath) {
|
|
58
|
+
function scanWorktrees(projectPath, osUserInfo) {
|
|
56
59
|
var resolvedParent = path.resolve(projectPath);
|
|
60
|
+
try { resolvedParent = fs.realpathSync(resolvedParent); } catch (e) {}
|
|
57
61
|
try {
|
|
58
|
-
var output =
|
|
59
|
-
cwd: resolvedParent,
|
|
60
|
-
encoding: "utf8",
|
|
61
|
-
timeout: 5000,
|
|
62
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
63
|
-
});
|
|
62
|
+
var output = runGitSync(resolvedParent, ["worktree", "list", "--porcelain"], null, osUserInfo);
|
|
64
63
|
var all = parseWorktreeOutput(output);
|
|
65
64
|
// Filter out bare worktrees and the main worktree itself
|
|
66
65
|
var results = [];
|
|
@@ -68,10 +67,11 @@ function scanWorktrees(projectPath) {
|
|
|
68
67
|
var wt = all[i];
|
|
69
68
|
if (wt.bare) continue;
|
|
70
69
|
var resolvedWt = path.resolve(wt.path);
|
|
71
|
-
if (resolvedWt === resolvedParent) continue;
|
|
72
70
|
// Git retains removed worktrees until `git worktree prune` runs. Do not
|
|
73
71
|
// register those stale paths as Clay projects.
|
|
74
72
|
if (!fs.existsSync(resolvedWt)) continue;
|
|
73
|
+
try { resolvedWt = fs.realpathSync(resolvedWt); } catch (e) {}
|
|
74
|
+
if (resolvedWt === resolvedParent) continue;
|
|
75
75
|
wt.external = !isPathInside(resolvedParent, resolvedWt);
|
|
76
76
|
wt.dirName = path.basename(wt.path);
|
|
77
77
|
results.push(wt);
|
|
@@ -84,28 +84,19 @@ function scanWorktrees(projectPath) {
|
|
|
84
84
|
|
|
85
85
|
// Create a new worktree inside the parent project directory
|
|
86
86
|
// Returns { ok, path, error }
|
|
87
|
-
function createWorktree(projectPath, branchName, dirName, baseBranch) {
|
|
87
|
+
function createWorktree(projectPath, branchName, dirName, baseBranch, osUserInfo) {
|
|
88
88
|
var resolvedParent = path.resolve(projectPath);
|
|
89
|
-
var wtPath =
|
|
89
|
+
var wtPath = worktreePath(resolvedParent, dirName || branchName);
|
|
90
|
+
if (!wtPath) return { ok: false, error: "Invalid worktree directory name" };
|
|
90
91
|
var base = baseBranch || "main";
|
|
91
92
|
// Try creating with -b (new branch)
|
|
92
93
|
try {
|
|
93
|
-
|
|
94
|
-
cwd: resolvedParent,
|
|
95
|
-
encoding: "utf8",
|
|
96
|
-
timeout: 15000,
|
|
97
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
98
|
-
});
|
|
94
|
+
runGitSync(resolvedParent, ["worktree", "add", wtPath, "-b", branchName, base], { timeout: 15000 }, osUserInfo);
|
|
99
95
|
return { ok: true, path: wtPath };
|
|
100
96
|
} catch (e) {
|
|
101
97
|
// Branch may already exist, try without -b
|
|
102
98
|
try {
|
|
103
|
-
|
|
104
|
-
cwd: resolvedParent,
|
|
105
|
-
encoding: "utf8",
|
|
106
|
-
timeout: 15000,
|
|
107
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
108
|
-
});
|
|
99
|
+
runGitSync(resolvedParent, ["worktree", "add", wtPath, branchName], { timeout: 15000 }, osUserInfo);
|
|
109
100
|
return { ok: true, path: wtPath };
|
|
110
101
|
} catch (e2) {
|
|
111
102
|
return { ok: false, error: e2.message || "Failed to create worktree" };
|
|
@@ -115,17 +106,13 @@ function createWorktree(projectPath, branchName, dirName, baseBranch) {
|
|
|
115
106
|
|
|
116
107
|
// Remove a worktree
|
|
117
108
|
// Returns { ok, error }
|
|
118
|
-
function removeWorktree(projectPath, worktreeDirName) {
|
|
109
|
+
function removeWorktree(projectPath, worktreeDirName, osUserInfo) {
|
|
119
110
|
var resolvedParent = path.resolve(projectPath);
|
|
120
|
-
var wtPath =
|
|
111
|
+
var wtPath = worktreePath(resolvedParent, worktreeDirName);
|
|
112
|
+
if (!wtPath) return { ok: false, error: "Invalid worktree directory name" };
|
|
121
113
|
// Try normal remove first
|
|
122
114
|
try {
|
|
123
|
-
|
|
124
|
-
cwd: resolvedParent,
|
|
125
|
-
encoding: "utf8",
|
|
126
|
-
timeout: 15000,
|
|
127
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
128
|
-
});
|
|
115
|
+
runGitSync(resolvedParent, ["worktree", "remove", wtPath], { timeout: 15000 }, osUserInfo);
|
|
129
116
|
return { ok: true };
|
|
130
117
|
} catch (e) {
|
|
131
118
|
var errMsg = (e.stderr || e.message || "").toString();
|
package/lib/ws-schema.js
CHANGED
|
@@ -40,10 +40,12 @@ var schema = {
|
|
|
40
40
|
"split_group_set_pair": { direction: "c2s", handler: "lib/session-split-groups.js", description: "Assign Driver/Worker roles on a split group (driverId null clears them)" },
|
|
41
41
|
"pair_session_options": { direction: "c2s", handler: "lib/project-session-pair.js", description: "Request vendors/models for the pair-session dialog (response reuses the same type)" },
|
|
42
42
|
"pair_session_create": { direction: "c2s", handler: "lib/project-session-pair.js", description: "Create a Driver/Split Worker session pair as a split group" },
|
|
43
|
-
"worker_proposal_response": { direction: "c2s", handler: "lib/project-worker-proposal.js", description: "Accept or decline
|
|
43
|
+
"worker_proposal_response": { direction: "c2s", handler: "lib/project-worker-proposal.js", description: "Accept or decline an exact Driver Split Worker configuration with the selected runtime" },
|
|
44
44
|
"project_assignment_response": { direction: "c2s", handler: "lib/workspace-assignment-service.js", description: "Approve or cancel an exact-session cross-project assignment proposal" },
|
|
45
45
|
"home_clay_session_resolve": { direction: "c2s", handler: "lib/server-home-chat.js", description: "Resolve an opaque Mate session reference through the exact bound source session" },
|
|
46
46
|
"home_clay_session_target": { direction: "s2c", handler: "lib/public/modules/command-palette.js", description: "Return an owner-validated navigation target for a rendered Mate session reference" },
|
|
47
|
+
"home_clay_log_resolve": { direction: "c2s", handler: "lib/server-home-chat.js", description: "Resolve an opaque Project Log reference through the exact bound Clay session" },
|
|
48
|
+
"home_clay_log_target": { direction: "s2c", handler: "lib/public/modules/command-palette.js", description: "Return an owner-validated project target for a rendered Log reference" },
|
|
47
49
|
|
|
48
50
|
"session_list": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Full list of sessions for the sidebar" },
|
|
49
51
|
"session_switched": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Confirmation that active session changed" },
|
|
@@ -62,8 +64,8 @@ var schema = {
|
|
|
62
64
|
"split_groups": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Full persistent split-group list for the current user" },
|
|
63
65
|
"split_group_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Result of a split-group mutation" },
|
|
64
66
|
"pair_session_created": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Result of pair_session_create; carries the new group" },
|
|
65
|
-
"worker_proposal": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "
|
|
66
|
-
"worker_proposal_update": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Worker
|
|
67
|
+
"worker_proposal": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Recorded Split Worker creation/replacement runtime card with Driver rationale" },
|
|
68
|
+
"worker_proposal_update": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Worker card lifecycle and manual/auto decision audit update" },
|
|
67
69
|
"project_assignment_proposal": { direction: "s2c", handler: "lib/public/modules/app-message-router.js", description: "Approval card for a new owner-bound project assignment" },
|
|
68
70
|
"project_assignment_status": { direction: "s2c", handler: "lib/public/modules/app-message-router.js", description: "Durable project assignment lifecycle update" },
|
|
69
71
|
"project_assignment_error": { direction: "s2c", handler: "lib/public/modules/app-message-router.js", description: "Rejected or stale project assignment response" },
|
|
@@ -81,7 +83,8 @@ var schema = {
|
|
|
81
83
|
// -----------------------------------------------------------------------
|
|
82
84
|
// Chat / streaming
|
|
83
85
|
// -----------------------------------------------------------------------
|
|
84
|
-
"message": { direction: "c2s", handler: "lib/project-user-message.js", description: "Send
|
|
86
|
+
"message": { direction: "c2s", handler: "lib/project-user-message.js", description: "Send an idempotent user chat message; message_ack confirms persistence" },
|
|
87
|
+
"message_ack": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Confirm that an idempotent user chat message was persisted" },
|
|
85
88
|
"user_message": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Echo of the user message in the timeline" },
|
|
86
89
|
"delta": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Incremental text delta from the assistant" },
|
|
87
90
|
"result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Final assistant result text" },
|
|
@@ -247,9 +250,11 @@ var schema = {
|
|
|
247
250
|
"set_update_channel": { direction: "c2s", handler: "lib/project-sessions.js", description: "Set the update channel (stable/beta)" },
|
|
248
251
|
"check_update": { direction: "c2s", handler: "lib/project-sessions.js", description: "Check if an update is available" },
|
|
249
252
|
"update_now": { direction: "c2s", handler: "lib/project-sessions.js", description: "Start the update process" },
|
|
253
|
+
"update_snooze": { direction: "c2s", handler: "lib/project-sessions.js", description: "Snooze the current update notification for an allowlisted duration" },
|
|
254
|
+
"update_snoozed": { direction: "s2c", handler: "lib/public/modules/update-snooze.js", description: "Result of an update snooze, fanned out to every device of that user" },
|
|
250
255
|
"update_available": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "A new version is available" },
|
|
251
256
|
"up_to_date": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Server is already on the latest version" },
|
|
252
|
-
"update_started": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Update download/install has started" },
|
|
257
|
+
"update_started": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Update download/install has started; the version field is included only for admin-grade recipients" },
|
|
253
258
|
|
|
254
259
|
// -----------------------------------------------------------------------
|
|
255
260
|
// What's New
|
|
@@ -396,12 +401,31 @@ var schema = {
|
|
|
396
401
|
"note_written": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Agent created or updated a sticky note" },
|
|
397
402
|
"note_update": { direction: "c2s", handler: "lib/project-user-message.js", description: "Update a sticky note" },
|
|
398
403
|
"note_updated": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Sticky note was updated" },
|
|
399
|
-
"
|
|
400
|
-
"
|
|
404
|
+
"note_close": { direction: "c2s", handler: "lib/project-user-message.js", description: "Close a sticky note (reversible; never deletes)" },
|
|
405
|
+
"note_reopen": { direction: "c2s", handler: "lib/project-user-message.js", description: "Reopen a closed sticky note" },
|
|
406
|
+
"note_delete": { direction: "c2s", handler: "lib/project-user-message.js", description: "Retired: older clients still send this; handled as a non-destructive close" },
|
|
407
|
+
"note_deleted": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Retired: never sent. Closing broadcasts note_updated instead" },
|
|
401
408
|
"note_list_request": { direction: "c2s", handler: "lib/project-user-message.js", description: "Request the full notes list" },
|
|
402
409
|
"note_bring_front": { direction: "c2s", handler: "lib/project-user-message.js", description: "Bring a note to front (update z-order)" },
|
|
403
410
|
"notes_list": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Full list of sticky notes" },
|
|
404
411
|
|
|
412
|
+
// -----------------------------------------------------------------------
|
|
413
|
+
// Project Logs
|
|
414
|
+
// -----------------------------------------------------------------------
|
|
415
|
+
"project_logs_list": { direction: "c2s", handler: "lib/project-logs.js", description: "List or search this project's logs (project scope is bound server-side)" },
|
|
416
|
+
"project_log_read": { direction: "c2s", handler: "lib/project-logs.js", description: "Read one project log entry by opaque ref" },
|
|
417
|
+
"project_log_comment": { direction: "c2s", handler: "lib/project-logs.js", description: "Append an attributed comment to a project log entry (append-only; author comes from the connection)" },
|
|
418
|
+
"project_log_delete": { direction: "c2s", handler: "lib/project-logs.js", description: "Delete a project log entry (project owner only; scope and identity are bound server-side)" },
|
|
419
|
+
"project_log_create": { direction: "c2s", handler: "lib/project-logs.js", description: "Retired. Canonical entries are written only by project agent sessions; this is always refused" },
|
|
420
|
+
"project_log_update": { direction: "c2s", handler: "lib/project-logs.js", description: "Retired. Canonical revisions are written only by project agent sessions; this is always refused" },
|
|
421
|
+
"project_logs_state": { direction: "s2c", handler: "lib/public/modules/project-logs.js", description: "Correlated project log index for a list or search request" },
|
|
422
|
+
"project_log_entry": { direction: "s2c", handler: "lib/public/modules/project-logs.js", description: "Correlated full project log entry" },
|
|
423
|
+
"project_log_commented": { direction: "s2c", handler: "lib/public/modules/project-logs.js", description: "Correlated project log entry after a comment was appended" },
|
|
424
|
+
"project_log_comment_reviewed": { direction: "s2c", handler: "lib/public/modules/project-logs.js", description: "A Project Driver resolved a log comment; carries identifiers and action only" },
|
|
425
|
+
"project_log_deleted": { direction: "s2c", handler: "lib/public/modules/project-logs.js", description: "Confirm that the project owner deleted a project log entry" },
|
|
426
|
+
"project_log_updated": { direction: "s2c", handler: "lib/public/modules/project-logs.js", description: "A project log entry was created, revised, or deleted (bounded ledger metadata only)" },
|
|
427
|
+
"project_logs_error": { direction: "s2c", handler: "lib/public/modules/project-logs.js", description: "Correlated project log request failure" },
|
|
428
|
+
|
|
405
429
|
// -----------------------------------------------------------------------
|
|
406
430
|
// Browser extension
|
|
407
431
|
// -----------------------------------------------------------------------
|
|
@@ -471,6 +495,8 @@ var schema = {
|
|
|
471
495
|
"tool_llm_op": { direction: "c2s", handler: "lib/server-tools.js", description: "Run a permission-gated vendor-neutral capsule LLM completion" },
|
|
472
496
|
"tool_llm_config_get": { direction: "c2s", handler: "lib/server-tools.js", description: "Get the concrete configured provider and model used by Capsule LLM calls" },
|
|
473
497
|
"tool_control_response": { direction: "c2s", handler: "lib/server-tools.js", description: "Resolve a mate tool-control request with browser runtime state or an error" },
|
|
498
|
+
"tool_server_control": { direction: "c2s", handler: "lib/server-tools.js", description: "Human snapshot or action against a server-runtime Capsule, through the same Logic a Mate calls" },
|
|
499
|
+
"tool_frame_url": { direction: "c2s", handler: "lib/server-tools.js", description: "Mint a one-time separate-origin URL for a Capsule's sandboxed rich Display frame" },
|
|
474
500
|
"tools_state": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Full installed tool definitions" },
|
|
475
501
|
"tool_installed": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "An installed tool changed" },
|
|
476
502
|
"tool_source_state": { direction: "s2c", handler: "lib/public/modules/home-capsule-source.js", description: "Correlated authored Capsule source or read error" },
|
|
@@ -480,6 +506,10 @@ var schema = {
|
|
|
480
506
|
"tool_llm_result": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Result of a capsule LLM completion" },
|
|
481
507
|
"tool_llm_config_state": { direction: "s2c", handler: "lib/public/modules/tool-llm-status.js", description: "Concrete provider and model state for Capsule LLM calls" },
|
|
482
508
|
"tool_control_request": { direction: "s2c", handler: "lib/public/modules/home-tools.js", description: "Ask the connected home client to snapshot or drive a sandboxed tool" },
|
|
509
|
+
"tool_server_state": { direction: "s2c", handler: "lib/public/modules/home-tools.js", description: "Correlated server-runtime Capsule state for the human who requested it, or the refusal that blocked it" },
|
|
510
|
+
"tool_server_event": { direction: "s2c", handler: "lib/public/modules/home-tools.js", description: "Ordered causal act event {seq, actor, action, previous, next} pushed to the user's Displays whenever server-runtime Capsule Logic changes state" },
|
|
511
|
+
"tool_frame_url_state": { direction: "s2c", handler: "lib/public/modules/home-tool-frame.js", description: "Correlated one-time rich Display frame URL, or the refusal that blocked it" },
|
|
512
|
+
"capsule_game_session": { direction: "s2c", handler: "lib/public/modules/home-tools.js", description: "A Capsule game session opened or advanced for this user; an explicit game start navigates the home board into it" },
|
|
483
513
|
"tools_error": { direction: "s2c", handler: "lib/public/modules/app-messages.js", description: "Tool registry, runtime, or storage error" },
|
|
484
514
|
|
|
485
515
|
// -----------------------------------------------------------------------
|
|
@@ -632,6 +662,7 @@ var schema = {
|
|
|
632
662
|
"home_mate_session_identity": { direction: "s2c", handler: "lib/public/modules/app-message-router.js", description: "Promote an active Home session from its local reference to its durable runtime identity" },
|
|
633
663
|
"home_mate_sessions_state": { direction: "s2c", handler: "lib/public/modules/home-mate-chat.js", description: "Owned visible Mate conversations with sanitized runtime identity, model, status, and timestamps" },
|
|
634
664
|
"home_mate_delta": { direction: "s2c", handler: "lib/public/modules/home-mate-chat.js", description: "Selected mate's streaming assistant text delta" },
|
|
665
|
+
"home_mate_segment": { direction: "s2c", handler: "lib/public/modules/home-mate-chat.js", description: "A tool call ended the mate's current spoken burst; the client seals the streamed bubble and later text starts a fresh one" },
|
|
635
666
|
"home_mate_done": { direction: "s2c", handler: "lib/public/modules/home-mate-chat.js", description: "Selected mate's turn finished" },
|
|
636
667
|
"home_debate_proposal": { direction: "s2c", handler: "lib/public/modules/app-message-router.js", description: "Session-bound debate proposal for the active Home transcript" },
|
|
637
668
|
"home_debate_proposal_resolved": { direction: "s2c", handler: "lib/public/modules/app-message-router.js", description: "Server-confirmed result for a Home debate proposal" },
|
|
@@ -424,22 +424,32 @@ async function handleQueryStart(msg) {
|
|
|
424
424
|
function perf(label) { console.log("[PERF] sdk-worker: " + label + " +" + (Date.now() - t0) + "ms (local +" + (Date.now() - localT0) + "ms)"); }
|
|
425
425
|
perf("handleQueryStart entered");
|
|
426
426
|
|
|
427
|
+
// Socket messages keep arriving while the SDK import awaits. Accept input
|
|
428
|
+
// and cancellation synchronously, before yielding to the next IPC message.
|
|
429
|
+
messageQueue = createMessageQueue();
|
|
430
|
+
abortController = new AbortController();
|
|
431
|
+
if (msg.prompt) messageQueue.push(msg.prompt);
|
|
432
|
+
|
|
427
433
|
var sdk;
|
|
428
434
|
try {
|
|
429
435
|
perf("loading SDK");
|
|
430
436
|
sdk = await getSDK();
|
|
431
437
|
perf("SDK loaded");
|
|
432
438
|
} catch (e) {
|
|
439
|
+
messageQueue.end();
|
|
440
|
+
messageQueue = null;
|
|
441
|
+
abortController = null;
|
|
442
|
+
sdkModule = null;
|
|
433
443
|
sendToDaemon({ type: "query_error", error: "Failed to load SDK: " + (e.message || e), exitCode: null, stderr: null });
|
|
434
444
|
return;
|
|
435
445
|
}
|
|
436
446
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
447
|
+
if (abortController.signal.aborted) {
|
|
448
|
+
messageQueue.end();
|
|
449
|
+
messageQueue = null;
|
|
450
|
+
abortController = null;
|
|
451
|
+
sendToDaemon({ type: "query_done" });
|
|
452
|
+
return;
|
|
443
453
|
}
|
|
444
454
|
|
|
445
455
|
// Build query options (callbacks are local, everything else from daemon)
|
|
@@ -20,6 +20,49 @@ var claudeUserInput = require("../claude-user-input");
|
|
|
20
20
|
// emitted. Keep in sync with the client's generic user-dialog renderer.
|
|
21
21
|
var SUPPORTED_DIALOG_KINDS = ["refusal_fallback_prompt"];
|
|
22
22
|
|
|
23
|
+
// Clay renders a per-task Stop control in the composer's background-tasks bar
|
|
24
|
+
// (public/modules/background-tasks-ui.js), wired through project-sessions.js
|
|
25
|
+
// `stop_task` -> adapter.stopTask -> rawQuery.stopTask (worker path: the
|
|
26
|
+
// stop_task message in claude-worker.js). Declaring that affordance makes an
|
|
27
|
+
// interrupt spare running background tasks so Stop only aborts the current
|
|
28
|
+
// turn. The CLI fails CLOSED on absence: without this, every interrupt would
|
|
29
|
+
// also kill background tasks, since a consumer with no per-task control could
|
|
30
|
+
// not otherwise stop a runaway one.
|
|
31
|
+
//
|
|
32
|
+
// Declared identically on the in-process and OS-user worker paths. The CLI
|
|
33
|
+
// takes first-attached-client-wins on multi-client sessions, so the two paths
|
|
34
|
+
// must not disagree, or which one connected first would decide whether Stop
|
|
35
|
+
// kills background work.
|
|
36
|
+
var PER_TASK_STOP_AFFORDANCE = true;
|
|
37
|
+
|
|
38
|
+
// --- System prompt recording (SDK `snapshot`) ---
|
|
39
|
+
// Records the conversation's system prompt once and replays it verbatim on
|
|
40
|
+
// every later request and resume, which keeps the prompt-cache prefix and
|
|
41
|
+
// extended-thinking context stable across CLI upgrades and flag changes.
|
|
42
|
+
//
|
|
43
|
+
// OFF for Clay's persistent sessions, deliberately. getSessionSystemPrompt
|
|
44
|
+
// (project.js) recomposes the append from live state every time the query is
|
|
45
|
+
// rebuilt - sticky notes, pair/Driver role, and the Mate Capsule catalog - and
|
|
46
|
+
// three call sites exist purely to force that re-render mid-conversation
|
|
47
|
+
// (project-capsule-catalog.js refreshSessions, project.js pair regrouping,
|
|
48
|
+
// sdk-bridge refreshEnvironmentRuntime). Because Clay resumes those
|
|
49
|
+
// conversations, a recorded prompt would pin the first render and silently
|
|
50
|
+
// swallow every later update until compaction.
|
|
51
|
+
//
|
|
52
|
+
// Callers whose prompt is fixed for the life of the conversation opt in with
|
|
53
|
+
// queryOpts.systemPromptSnapshot. A bare string prompt cannot be recorded, so
|
|
54
|
+
// it is promoted to the custom form the SDK requires.
|
|
55
|
+
function applySystemPromptSnapshot(systemPrompt, enabled) {
|
|
56
|
+
if (!enabled || !systemPrompt) return systemPrompt;
|
|
57
|
+
if (typeof systemPrompt === "string" || Array.isArray(systemPrompt)) {
|
|
58
|
+
return { type: "custom", prompt: systemPrompt, snapshot: true };
|
|
59
|
+
}
|
|
60
|
+
if (typeof systemPrompt === "object") {
|
|
61
|
+
return Object.assign({}, systemPrompt, { snapshot: true });
|
|
62
|
+
}
|
|
63
|
+
return systemPrompt;
|
|
64
|
+
}
|
|
65
|
+
|
|
23
66
|
function getSharedSkillPlugins(homeDir, existingPlugins) {
|
|
24
67
|
var plugins = Array.isArray(existingPlugins) ? existingPlugins.slice() : [];
|
|
25
68
|
var bridgePath = skillDiscovery.ensureClaudeCodexPlugin(homeDir ? { homeDir: homeDir } : null);
|
|
@@ -45,10 +88,16 @@ function buildWorkerQueryOptions(queryOpts, claudeOpts, workerCwd) {
|
|
|
45
88
|
if (claudeOpts.permissionMode) queryOptions.permissionMode = claudeOpts.permissionMode;
|
|
46
89
|
if (claudeOpts.allowDangerouslySkipPermissions) queryOptions.allowDangerouslySkipPermissions = true;
|
|
47
90
|
if (claudeOpts.settings) queryOptions.settings = claudeOpts.settings;
|
|
48
|
-
if (queryOpts.appendSystemPrompt)
|
|
91
|
+
if (queryOpts.appendSystemPrompt) {
|
|
92
|
+
queryOptions.systemPrompt = applySystemPromptSnapshot(
|
|
93
|
+
{ type: "preset", preset: "claude_code", append: queryOpts.appendSystemPrompt },
|
|
94
|
+
queryOpts.systemPromptSnapshot
|
|
95
|
+
);
|
|
96
|
+
}
|
|
49
97
|
queryOptions.plugins = queryOpts.skipSkills ? (claudeOpts.plugins || []) : getSharedSkillPlugins(claudeOpts.originalHome, claudeOpts.plugins);
|
|
50
98
|
if (queryOpts.toolServerDescriptors) queryOptions.mcpServerDescriptors = queryOpts.toolServerDescriptors;
|
|
51
99
|
if (queryOpts.onUserDialog) queryOptions.supportedDialogKinds = SUPPORTED_DIALOG_KINDS;
|
|
100
|
+
queryOptions.perTaskStopAffordance = PER_TASK_STOP_AFFORDANCE;
|
|
52
101
|
if (queryOpts.model) queryOptions.model = queryOpts.model;
|
|
53
102
|
if (queryOpts.effort) queryOptions.effort = queryOpts.effort;
|
|
54
103
|
if (queryOpts.resumeSessionId) queryOptions.resume = queryOpts.resumeSessionId;
|
|
@@ -211,6 +260,18 @@ function flattenEvent(raw) {
|
|
|
211
260
|
base.status = raw.status;
|
|
212
261
|
return base;
|
|
213
262
|
}
|
|
263
|
+
// API retry notices are transient transport state, not conversation
|
|
264
|
+
// errors. Preserve the structured counters so the host can bound overload
|
|
265
|
+
// churn without recording one red error row per SDK retry.
|
|
266
|
+
if (raw.subtype === "api_retry") {
|
|
267
|
+
base.yokeType = "api_retry";
|
|
268
|
+
base.attempt = raw.attempt || 0;
|
|
269
|
+
base.maxRetries = raw.max_retries || 0;
|
|
270
|
+
base.retryDelayMs = raw.retry_delay_ms || 0;
|
|
271
|
+
base.error = raw.error || "unknown";
|
|
272
|
+
base.errorStatus = raw.error_status == null ? null : raw.error_status;
|
|
273
|
+
return base;
|
|
274
|
+
}
|
|
214
275
|
if (raw.subtype === "task_started") {
|
|
215
276
|
base.yokeType = "task_started";
|
|
216
277
|
base.parentToolId = raw.tool_use_id;
|
|
@@ -400,11 +461,21 @@ function normalizeBackgroundTasks(tasks) {
|
|
|
400
461
|
var nativeType = task && task.task_type;
|
|
401
462
|
var taskType = nativeType === "local_bash" ? "shell"
|
|
402
463
|
: nativeType === "local_agent" ? "agent" : "other";
|
|
403
|
-
|
|
464
|
+
var normalized = {
|
|
404
465
|
task_id: task && task.task_id,
|
|
405
466
|
task_type: taskType,
|
|
406
467
|
description: (task && task.description) || "",
|
|
468
|
+
// Housekeeping the CLI does not surface as user work (skip_transcript
|
|
469
|
+
// tasks, auto-started live-update watchers). Clay keeps these out of its
|
|
470
|
+
// activity indicators and lists them as a subdued secondary group.
|
|
471
|
+
// Normalized to a boolean so consumers never have to test for absence.
|
|
472
|
+
ambient: !!(task && task.ambient),
|
|
407
473
|
};
|
|
474
|
+
// The SDK does not report a start time today. Forward one if a future
|
|
475
|
+
// version adds it; otherwise the session stamps first-seen time.
|
|
476
|
+
var startedAt = task && (task.started_at || task.startedAt || task.created_at);
|
|
477
|
+
if (startedAt) normalized.started_at = startedAt;
|
|
478
|
+
return normalized;
|
|
408
479
|
});
|
|
409
480
|
}
|
|
410
481
|
|
|
@@ -1449,12 +1520,17 @@ function createClaudeAdapter(opts) {
|
|
|
1449
1520
|
if (_claudeBinaryPath) sdkOptions.pathToClaudeCodeExecutable = _claudeBinaryPath;
|
|
1450
1521
|
|
|
1451
1522
|
// YOKE standard options -> SDK options
|
|
1452
|
-
if (queryOpts.systemPrompt)
|
|
1523
|
+
if (queryOpts.systemPrompt) {
|
|
1524
|
+
sdkOptions.systemPrompt = applySystemPromptSnapshot(queryOpts.systemPrompt, queryOpts.systemPromptSnapshot);
|
|
1525
|
+
}
|
|
1453
1526
|
// Additive variant: keep the full Claude Code system prompt and append.
|
|
1454
1527
|
// A plain-string systemPrompt REPLACES the whole prompt, so pair
|
|
1455
1528
|
// presets and other add-ons must come through here instead.
|
|
1456
1529
|
if (!queryOpts.systemPrompt && queryOpts.appendSystemPrompt) {
|
|
1457
|
-
sdkOptions.systemPrompt =
|
|
1530
|
+
sdkOptions.systemPrompt = applySystemPromptSnapshot(
|
|
1531
|
+
{ type: "preset", preset: "claude_code", append: queryOpts.appendSystemPrompt },
|
|
1532
|
+
queryOpts.systemPromptSnapshot
|
|
1533
|
+
);
|
|
1458
1534
|
}
|
|
1459
1535
|
if (queryOpts.model) sdkOptions.model = queryOpts.model;
|
|
1460
1536
|
if (queryOpts.effort) sdkOptions.effort = queryOpts.effort;
|
|
@@ -1470,6 +1546,7 @@ function createClaudeAdapter(opts) {
|
|
|
1470
1546
|
sdkOptions.onUserDialog = queryOpts.onUserDialog;
|
|
1471
1547
|
sdkOptions.supportedDialogKinds = SUPPORTED_DIALOG_KINDS;
|
|
1472
1548
|
}
|
|
1549
|
+
sdkOptions.perTaskStopAffordance = PER_TASK_STOP_AFFORDANCE;
|
|
1473
1550
|
if (queryOpts.resumeSessionId) sdkOptions.resume = queryOpts.resumeSessionId;
|
|
1474
1551
|
if (queryOpts.persistSession === false) sdkOptions.persistSession = false;
|
|
1475
1552
|
|