@sema-agent/core 5.0.1 → 5.1.0
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/CHANGELOG.md +34 -0
- package/dist/agents/roster-store.d.ts +9 -2
- package/dist/agents/roster-store.js +26 -5
- package/dist/agents/subagent.js +8 -3
- package/dist/bin/sema-tb.d.ts +1 -2
- package/dist/bin/sema-tb.js +13 -25
- package/dist/brain/anthropic.js +2 -3
- package/dist/brain/degrading.d.ts +2 -8
- package/dist/brain/degrading.js +3 -3
- package/dist/brain/terminal-cause.js +2 -8
- package/dist/core/hooks.js +4 -4
- package/dist/core/lsp.js +2 -3
- package/dist/core/mcp.d.ts +1 -1
- package/dist/core/mcp.js +2 -1
- package/dist/core/memory-engine/engine.js +2 -2
- package/dist/core/memory-engine/file-backend.js +3 -1
- package/dist/core/memory-engine/layout.d.ts +3 -0
- package/dist/core/memory-engine/layout.js +51 -0
- package/dist/core/memory.d.ts +0 -1
- package/dist/core/memory.js +1 -1
- package/dist/core/permission-rules.js +8 -7
- package/dist/core/protocol-table.d.ts +14 -0
- package/dist/core/protocol-table.js +23 -0
- package/dist/core/runner/active-skill-scope.js +7 -7
- package/dist/core/runner/prepare-memory.js +4 -1
- package/dist/core/runner/prepare-task.js +17 -16
- package/dist/core/runner/runtask.js +9 -3
- package/dist/core/runner/session-rule-policy.js +1 -1
- package/dist/core/runner/synthetic-tools.js +2 -2
- package/dist/core/runner/tool-disclosure.d.ts +0 -1
- package/dist/core/runner/tool-disclosure.js +0 -2
- package/dist/core/runner/turn-attachments.js +2 -1
- package/dist/core/sensitive-path-policy.js +2 -2
- package/dist/core/tool-policy.d.ts +0 -3
- package/dist/core/tool-policy.js +29 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/orchestration/run-spec.js +1 -1
- package/dist/orchestration/run-workflow-tool.js +2 -2
- package/dist/orchestration/workflow-script-store.d.ts +1 -1
- package/dist/orchestration/workflow-script-store.js +1 -1
- package/dist/prompt-assembly/assemble.js +0 -1
- package/dist/prompt-assembly/tool-catalog.d.ts +2 -1
- package/dist/prompts/default.d.ts +0 -2
- package/dist/prompts/default.js +1 -5
- package/dist/stores/cc/mailbox-store.d.ts +4 -0
- package/dist/stores/cc/mailbox-store.js +16 -2
- package/dist/stores/file/session-policy-store.d.ts +10 -1
- package/dist/stores/file/session-policy-store.js +20 -4
- package/dist/tools/fs/fs-search-tools.js +1 -2
- package/dist/tools/fs/fs-shared.d.ts +0 -1
- package/dist/tools/fs/fs-shared.js +0 -1
- package/dist/tools/todo.js +1 -1
- package/package.json +1 -1
|
@@ -4,5 +4,9 @@ export interface CcFileMailboxStoreOptions {
|
|
|
4
4
|
teamDir: string;
|
|
5
5
|
agentNameOf?: (handle: string) => string | undefined;
|
|
6
6
|
now?: () => number;
|
|
7
|
+
onCorruptRead?: (info: {
|
|
8
|
+
path: string;
|
|
9
|
+
reason: string;
|
|
10
|
+
}) => void;
|
|
7
11
|
}
|
|
8
12
|
export declare function createCcFileMailboxStore(opts: CcFileMailboxStoreOptions): MailboxStore;
|
|
@@ -27,19 +27,33 @@ export function createCcFileMailboxStore(opts) {
|
|
|
27
27
|
const name = opts.agentNameOf?.(handle) ?? handle;
|
|
28
28
|
return join(inboxDir, `${sanitizeCcAgentName(name)}.json`);
|
|
29
29
|
};
|
|
30
|
+
const discloseCorrupt = (path, reason) => {
|
|
31
|
+
try {
|
|
32
|
+
opts.onCorruptRead?.({ path, reason });
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
}
|
|
36
|
+
};
|
|
30
37
|
const loadBox = (path) => {
|
|
31
38
|
let raw;
|
|
32
39
|
try {
|
|
33
40
|
raw = readFileSync(path, "utf8");
|
|
34
41
|
}
|
|
35
|
-
catch {
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err.code !== "ENOENT")
|
|
44
|
+
discloseCorrupt(path, `read failed (non-ENOENT): ${err.message}`);
|
|
36
45
|
return [];
|
|
37
46
|
}
|
|
38
47
|
try {
|
|
39
48
|
const parsed = JSON.parse(raw);
|
|
40
|
-
|
|
49
|
+
if (!Array.isArray(parsed)) {
|
|
50
|
+
discloseCorrupt(path, "inbox document is not an array");
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
return parsed;
|
|
41
54
|
}
|
|
42
55
|
catch {
|
|
56
|
+
discloseCorrupt(path, "unparseable inbox JSON (torn write?)");
|
|
43
57
|
return [];
|
|
44
58
|
}
|
|
45
59
|
};
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { type PutRulesOptions, type SessionPermissionRules, type SessionPolicyStore, type SessionRulesRecord, type StoredSessionRules } from "../../core/session-policy-store.js";
|
|
2
2
|
export declare class FileSessionPolicyStore implements SessionPolicyStore {
|
|
3
3
|
private readonly dir;
|
|
4
|
-
|
|
4
|
+
private readonly onCorruptRead;
|
|
5
|
+
constructor(root: string, opts?: {
|
|
6
|
+
onCorruptRead?: (info: {
|
|
7
|
+
sessionId: string;
|
|
8
|
+
principal?: string;
|
|
9
|
+
path: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
}) => void;
|
|
12
|
+
});
|
|
13
|
+
private discloseCorrupt;
|
|
5
14
|
private pathFor;
|
|
6
15
|
private read;
|
|
7
16
|
getRules(sessionId: string, principal?: string): Promise<StoredSessionRules | null>;
|
|
@@ -4,9 +4,18 @@ import { loosenReasons, normalizeRules, stripRev, SessionPolicyError, } from "..
|
|
|
4
4
|
import { atomicWriteFile, ensureDir, sanitizeScope } from "./fs-atomic.js";
|
|
5
5
|
export class FileSessionPolicyStore {
|
|
6
6
|
dir;
|
|
7
|
-
|
|
7
|
+
onCorruptRead;
|
|
8
|
+
constructor(root, opts) {
|
|
8
9
|
this.dir = join(root, "session-policy");
|
|
9
10
|
ensureDir(this.dir);
|
|
11
|
+
this.onCorruptRead = opts?.onCorruptRead;
|
|
12
|
+
}
|
|
13
|
+
discloseCorrupt(sessionId, principal, reason) {
|
|
14
|
+
try {
|
|
15
|
+
this.onCorruptRead?.({ sessionId, ...(principal !== undefined ? { principal } : {}), path: this.pathFor(sessionId, principal), reason });
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
}
|
|
10
19
|
}
|
|
11
20
|
pathFor(sessionId, principal) {
|
|
12
21
|
const composite = JSON.stringify([sessionId, principal ?? null]);
|
|
@@ -24,20 +33,27 @@ export class FileSessionPolicyStore {
|
|
|
24
33
|
}
|
|
25
34
|
try {
|
|
26
35
|
const parsed = JSON.parse(raw);
|
|
27
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed))
|
|
36
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
37
|
+
this.discloseCorrupt(sessionId, principal, "not a JSON object");
|
|
28
38
|
return null;
|
|
39
|
+
}
|
|
29
40
|
const r = parsed;
|
|
30
|
-
if (r.rev !== undefined && (typeof r.rev !== "number" || !Number.isFinite(r.rev)))
|
|
41
|
+
if (r.rev !== undefined && (typeof r.rev !== "number" || !Number.isFinite(r.rev))) {
|
|
42
|
+
this.discloseCorrupt(sessionId, principal, "non-numeric rev");
|
|
31
43
|
return null;
|
|
44
|
+
}
|
|
32
45
|
const strArr = (x) => x === undefined || (Array.isArray(x) && x.every((e) => typeof e === "string"));
|
|
33
|
-
if (!strArr(r.toolAllow) || !strArr(r.toolDeny) || !strArr(r.commandAllow) || !strArr(r.commandDeny) || !strArr(r.allowDirs))
|
|
46
|
+
if (!strArr(r.toolAllow) || !strArr(r.toolDeny) || !strArr(r.commandAllow) || !strArr(r.commandDeny) || !strArr(r.allowDirs)) {
|
|
47
|
+
this.discloseCorrupt(sessionId, principal, "malformed rule field");
|
|
34
48
|
return null;
|
|
49
|
+
}
|
|
35
50
|
const { __sid: _sid, __principal: _principal, ...clean } = r;
|
|
36
51
|
void _sid;
|
|
37
52
|
void _principal;
|
|
38
53
|
return clean;
|
|
39
54
|
}
|
|
40
55
|
catch {
|
|
56
|
+
this.discloseCorrupt(sessionId, principal, "unparseable JSON (torn/zero-byte write?)");
|
|
41
57
|
return null;
|
|
42
58
|
}
|
|
43
59
|
}
|
|
@@ -37,7 +37,6 @@ export function createGrepTool(env, rootCanonical, additionalRoots) {
|
|
|
37
37
|
description: 'Limit output to first N lines/entries, equivalent to "| head -N". Works across all output modes: content (limits output lines), files_with_matches (limits file paths), count (limits count entries). Defaults to 250 when unspecified. Pass 0 for unlimited (use sparingly — large result sets waste context).',
|
|
38
38
|
})),
|
|
39
39
|
offset: Type.Optional(Type.Number({ description: "Skip the first N output lines (pagination partner of head_limit)." })),
|
|
40
|
-
max_results: Type.Optional(Type.Number({ description: "Deprecated alias for head_limit." })),
|
|
41
40
|
}),
|
|
42
41
|
effect: "read",
|
|
43
42
|
execute: async (args, ctx) => {
|
|
@@ -69,7 +68,7 @@ export function createGrepTool(env, rootCanonical, additionalRoots) {
|
|
|
69
68
|
const grepRun = await runGrepDetailed(env, rootCanonical, {
|
|
70
69
|
...a,
|
|
71
70
|
path: scoped,
|
|
72
|
-
head_limit: a.head_limit
|
|
71
|
+
head_limit: a.head_limit,
|
|
73
72
|
context: a.context ?? a["-C"],
|
|
74
73
|
context_after: a.context_after ?? a["-A"],
|
|
75
74
|
context_before: a.context_before ?? a["-B"],
|
|
@@ -43,7 +43,6 @@ export declare function bashTimeoutCapsSec(caps: {
|
|
|
43
43
|
export declare function bashMaxOutputChars(): number;
|
|
44
44
|
export declare const FILE_PATH_PARAMS: {
|
|
45
45
|
file_path: Type.TOptional<Type.TString>;
|
|
46
|
-
path: Type.TOptional<Type.TString>;
|
|
47
46
|
};
|
|
48
47
|
export declare function clipShellOutput(s: string): string;
|
|
49
48
|
export declare function writeShellOverflowFile(env: ExecutionEnv, stdout: string, stderr: string): Promise<string | undefined>;
|
|
@@ -77,7 +77,6 @@ export function bashMaxOutputChars() {
|
|
|
77
77
|
}
|
|
78
78
|
export const FILE_PATH_PARAMS = {
|
|
79
79
|
file_path: Type.Optional(Type.String({ description: "File path (within the configured root)." })),
|
|
80
|
-
path: Type.Optional(Type.String({ description: "Deprecated alias for `file_path` (back-compat; prefer file_path)." })),
|
|
81
80
|
};
|
|
82
81
|
export function clipShellOutput(s) {
|
|
83
82
|
return clipWithFilePointer(s, bashMaxOutputChars());
|
package/dist/tools/todo.js
CHANGED
|
@@ -76,7 +76,7 @@ export function createTodoWriteTool() {
|
|
|
76
76
|
todos: Type.Array(Type.Object({
|
|
77
77
|
content: Type.String({ description: "The task, in imperative form (e.g. \"Run the tests\")." }),
|
|
78
78
|
status: Type.Union([Type.Literal("pending"), Type.Literal("in_progress"), Type.Literal("completed")]),
|
|
79
|
-
activeForm: Type.
|
|
79
|
+
activeForm: Type.String({ minLength: 1, description: "Present-continuous form shown while in progress (e.g. \"Running the tests\")." }),
|
|
80
80
|
})),
|
|
81
81
|
}),
|
|
82
82
|
effect: "idempotent",
|