@cjhyy/code-shell-core 0.8.20 → 0.9.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/dist/automation/desktop-authority-client.d.ts +9 -0
- package/dist/automation/desktop-authority-client.js +47 -0
- package/dist/automation/scheduler.d.ts +8 -0
- package/dist/automation/scheduler.js +37 -1
- package/dist/automation/store.js +14 -1
- package/dist/capabilities/index.d.ts +1 -0
- package/dist/cli/agent-server-stdio.js +4 -1
- package/dist/engine/engine-workspace-authority.d.ts +50 -0
- package/dist/engine/engine-workspace-authority.js +167 -0
- package/dist/engine/engine.d.ts +7 -10
- package/dist/engine/engine.js +87 -101
- package/dist/engine/input-attachments.d.ts +1 -0
- package/dist/engine/input-attachments.js +6 -2
- package/dist/engine/run-environment.d.ts +8 -3
- package/dist/engine/run-environment.js +33 -8
- package/dist/engine/run-image-input.d.ts +1 -0
- package/dist/engine/run-image-input.js +1 -0
- package/dist/engine/run-session-open.d.ts +2 -1
- package/dist/engine/run-session-open.js +6 -0
- package/dist/engine/run-setup.d.ts +1 -0
- package/dist/engine/run-setup.js +2 -1
- package/dist/engine/run-tooling.d.ts +2 -0
- package/dist/engine/run-tooling.js +3 -0
- package/dist/engine/run-types.d.ts +2 -0
- package/dist/engine/run-workspace.d.ts +6 -1
- package/dist/engine/run-workspace.js +47 -0
- package/dist/engine/subagent-spawner.d.ts +1 -0
- package/dist/engine/subagent-spawner.js +1 -0
- package/dist/engine/types.d.ts +2 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.extension.d.ts +1 -1
- package/dist/index.internal.d.ts +2 -2
- package/dist/index.internal.js +1 -0
- package/dist/index.js +1 -1
- package/dist/plugins/pluginAutomationTemplates.d.ts +2 -0
- package/dist/plugins/pluginAutomationTemplates.js +4 -0
- package/dist/prompt/composer.d.ts +4 -1
- package/dist/prompt/composer.js +11 -3
- package/dist/protocol/background-result-wakeup.d.ts +18 -0
- package/dist/protocol/background-result-wakeup.js +101 -0
- package/dist/protocol/chat-session-manager.d.ts +42 -1
- package/dist/protocol/chat-session-manager.js +167 -4
- package/dist/protocol/chat-session.d.ts +9 -1
- package/dist/protocol/chat-session.js +20 -2
- package/dist/protocol/mobile-remote-types.d.ts +15 -0
- package/dist/protocol/server.d.ts +5 -6
- package/dist/protocol/server.js +62 -128
- package/dist/protocol/session-workspace-rpc.d.ts +23 -0
- package/dist/protocol/session-workspace-rpc.js +171 -0
- package/dist/protocol/types.d.ts +45 -1
- package/dist/protocol/types.js +4 -0
- package/dist/session/session-manager.d.ts +18 -0
- package/dist/session/session-manager.js +87 -0
- package/dist/settings/manager.d.ts +7 -0
- package/dist/settings/manager.js +64 -3
- package/dist/tool-system/builtin/agent-notifications.d.ts +8 -0
- package/dist/tool-system/builtin/agent-notifications.js +19 -0
- package/dist/tool-system/builtin/config.d.ts +11 -0
- package/dist/tool-system/builtin/config.js +55 -10
- package/dist/tool-system/builtin/cron.d.ts +11 -0
- package/dist/tool-system/builtin/cron.js +27 -2
- package/dist/tool-system/builtin/edit.js +5 -3
- package/dist/tool-system/builtin/view-image.js +8 -2
- package/dist/tool-system/builtin/write.js +5 -3
- package/dist/tool-system/context.d.ts +4 -1
- package/dist/tool-system/executor.js +1 -1
- package/dist/tool-system/path-policy.d.ts +11 -3
- package/dist/tool-system/path-policy.js +56 -36
- package/dist/types.d.ts +6 -0
- package/dist/workspace/canonical-key.d.ts +7 -0
- package/dist/workspace/canonical-key.js +39 -0
- package/dist/workspace/workspace-context.d.ts +35 -0
- package/dist/workspace/workspace-context.js +128 -0
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { isAbsolute, relative, sep } from "node:path";
|
|
3
|
+
import { canonicalKey, canonicalPath } from "./canonical-key.js";
|
|
4
|
+
export { canonicalKey, canonicalPath };
|
|
5
|
+
function requireIdentifier(value, label) {
|
|
6
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 512) {
|
|
7
|
+
throw new Error(`invalid WorkspaceContext ${label}`);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function containsPath(parent, child) {
|
|
12
|
+
if (parent === child)
|
|
13
|
+
return true;
|
|
14
|
+
const rel = relative(parent, child);
|
|
15
|
+
return rel !== "" && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
|
|
16
|
+
}
|
|
17
|
+
export function computeWorkspaceRootsDigest(roots) {
|
|
18
|
+
const keys = roots.map((root) => canonicalKey(root.path)).sort();
|
|
19
|
+
return createHash("sha256").update(keys.join("\0"), "utf8").digest("hex");
|
|
20
|
+
}
|
|
21
|
+
function validateRoots(roots, sessionMainRootId) {
|
|
22
|
+
if (roots.length === 0 || roots.length > 256) {
|
|
23
|
+
throw new Error("WorkspaceContext roots must contain between 1 and 256 entries");
|
|
24
|
+
}
|
|
25
|
+
const ids = new Set();
|
|
26
|
+
const normalized = roots.map((root, index) => {
|
|
27
|
+
if (!root || typeof root !== "object") {
|
|
28
|
+
throw new Error(`invalid WorkspaceContext root at index ${index}`);
|
|
29
|
+
}
|
|
30
|
+
const id = requireIdentifier(root.id, `roots[${index}].id`);
|
|
31
|
+
if (ids.has(id))
|
|
32
|
+
throw new Error(`duplicate root id: ${id}`);
|
|
33
|
+
ids.add(id);
|
|
34
|
+
if (typeof root.path !== "string" || root.path.length === 0 || root.path.length > 16_384) {
|
|
35
|
+
throw new Error(`invalid WorkspaceContext roots[${index}].path`);
|
|
36
|
+
}
|
|
37
|
+
if (!isAbsolute(root.path)) {
|
|
38
|
+
throw new Error(`WorkspaceContext root path must be absolute: ${root.path}`);
|
|
39
|
+
}
|
|
40
|
+
if (root.role !== "primary" && root.role !== "secondary") {
|
|
41
|
+
throw new Error(`invalid WorkspaceContext roots[${index}].role`);
|
|
42
|
+
}
|
|
43
|
+
return { id, path: root.path, role: root.role };
|
|
44
|
+
});
|
|
45
|
+
const primary = normalized.filter((root) => root.role === "primary");
|
|
46
|
+
if (primary.length !== 1 || primary[0]?.id !== sessionMainRootId) {
|
|
47
|
+
throw new Error("WorkspaceContext must have exactly one primary matching sessionMainRootId");
|
|
48
|
+
}
|
|
49
|
+
const keys = normalized.map((root) => canonicalKey(root.path));
|
|
50
|
+
for (let left = 0; left < keys.length; left += 1) {
|
|
51
|
+
for (let right = left + 1; right < keys.length; right += 1) {
|
|
52
|
+
if (containsPath(keys[left], keys[right]) || containsPath(keys[right], keys[left])) {
|
|
53
|
+
throw new Error(`WorkspaceContext roots overlap: ${normalized[left].path} and ${normalized[right].path}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return normalized;
|
|
58
|
+
}
|
|
59
|
+
export function createWorkspaceContext(input) {
|
|
60
|
+
const projectId = requireIdentifier(input.projectId, "projectId");
|
|
61
|
+
const sessionMainRootId = requireIdentifier(input.sessionMainRootId, "sessionMainRootId");
|
|
62
|
+
if (!Number.isSafeInteger(input.projectRevision) || input.projectRevision < 1) {
|
|
63
|
+
throw new Error("invalid WorkspaceContext projectRevision");
|
|
64
|
+
}
|
|
65
|
+
const roots = validateRoots(input.roots, sessionMainRootId);
|
|
66
|
+
return {
|
|
67
|
+
version: 1,
|
|
68
|
+
projectId,
|
|
69
|
+
projectRevision: input.projectRevision,
|
|
70
|
+
sessionMainRootId,
|
|
71
|
+
roots,
|
|
72
|
+
rootsDigest: computeWorkspaceRootsDigest(roots),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function validateWorkspaceContext(value) {
|
|
76
|
+
if (!value || typeof value !== "object")
|
|
77
|
+
throw new Error("invalid WorkspaceContext");
|
|
78
|
+
const candidate = value;
|
|
79
|
+
if (candidate.version !== 1)
|
|
80
|
+
throw new Error("invalid WorkspaceContext version");
|
|
81
|
+
const created = createWorkspaceContext({
|
|
82
|
+
projectId: candidate.projectId,
|
|
83
|
+
projectRevision: candidate.projectRevision,
|
|
84
|
+
sessionMainRootId: candidate.sessionMainRootId,
|
|
85
|
+
roots: candidate.roots,
|
|
86
|
+
});
|
|
87
|
+
if (candidate.rootsDigest !== created.rootsDigest) {
|
|
88
|
+
throw new Error("WorkspaceContext rootsDigest does not match roots");
|
|
89
|
+
}
|
|
90
|
+
return created;
|
|
91
|
+
}
|
|
92
|
+
/** Compatibility context for callers that only possess one cwd. It is never persisted as a binding. */
|
|
93
|
+
export function legacySingleRootWorkspace(cwd) {
|
|
94
|
+
const path = canonicalPath(cwd);
|
|
95
|
+
const keyDigest = createHash("sha256").update(canonicalKey(path), "utf8").digest("hex");
|
|
96
|
+
return createWorkspaceContext({
|
|
97
|
+
projectId: `legacy-${keyDigest}`,
|
|
98
|
+
projectRevision: 1,
|
|
99
|
+
sessionMainRootId: "legacy-root",
|
|
100
|
+
roots: [{ id: "legacy-root", path, role: "primary" }],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
export function workspacePrimaryRoot(context) {
|
|
104
|
+
return context.roots.find((root) => root.id === context.sessionMainRootId);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Rebase only the Session's primary runtime path while preserving the host's
|
|
108
|
+
* authoritative project/root identities and the mounted secondary roots.
|
|
109
|
+
*
|
|
110
|
+
* A worktree switch changes where the primary root executes; it does not mint
|
|
111
|
+
* a new project or root id. Rebuilding through createWorkspaceContext also
|
|
112
|
+
* recomputes rootsDigest and re-runs the overlap/absolute-path validation.
|
|
113
|
+
*/
|
|
114
|
+
export function rebaseWorkspacePrimaryRoot(context, primaryPath) {
|
|
115
|
+
return createWorkspaceContext({
|
|
116
|
+
projectId: context.projectId,
|
|
117
|
+
projectRevision: context.projectRevision,
|
|
118
|
+
sessionMainRootId: context.sessionMainRootId,
|
|
119
|
+
roots: context.roots.map((root) => root.id === context.sessionMainRootId ? { ...root, path: primaryPath } : root),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/** Paths present in the previous run-scoped root set but absent from the next one. */
|
|
123
|
+
export function removedWorkspaceRootPaths(previous, next) {
|
|
124
|
+
const nextKeys = new Set(next.roots.map((root) => canonicalKey(root.path)));
|
|
125
|
+
return previous.roots
|
|
126
|
+
.filter((root) => !nextKeys.has(canonicalKey(root.path)))
|
|
127
|
+
.map((root) => root.path);
|
|
128
|
+
}
|
package/package.json
CHANGED