@namzu/sdk 57.0.0 → 58.0.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 +62 -0
- package/dist/agents/QueryAgent.d.ts.map +1 -1
- package/dist/agents/QueryAgent.js +3 -0
- package/dist/agents/QueryAgent.js.map +1 -1
- package/dist/agents/file-definitions.d.ts +35 -4
- package/dist/agents/file-definitions.d.ts.map +1 -1
- package/dist/agents/file-definitions.js +98 -8
- package/dist/agents/file-definitions.js.map +1 -1
- package/dist/authorization/protected-paths.d.ts +9 -0
- package/dist/authorization/protected-paths.d.ts.map +1 -1
- package/dist/authorization/protected-paths.js +29 -3
- package/dist/authorization/protected-paths.js.map +1 -1
- package/dist/compaction/index.d.ts +1 -0
- package/dist/compaction/index.d.ts.map +1 -1
- package/dist/compaction/index.js.map +1 -1
- package/dist/compaction/manual.d.ts +7 -0
- package/dist/compaction/manual.d.ts.map +1 -1
- package/dist/compaction/manual.js +31 -12
- package/dist/compaction/manual.js.map +1 -1
- package/dist/compaction/model-summary.d.ts +101 -0
- package/dist/compaction/model-summary.d.ts.map +1 -0
- package/dist/compaction/model-summary.js +333 -0
- package/dist/compaction/model-summary.js.map +1 -0
- package/dist/compaction/verifier.d.ts +6 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +3 -3
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/config/runtime.d.ts +62 -0
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/runtime.js +16 -0
- package/dist/config/runtime.js.map +1 -1
- package/dist/connector/mcp/client.d.ts +8 -0
- package/dist/connector/mcp/client.d.ts.map +1 -1
- package/dist/connector/mcp/client.js +75 -2
- package/dist/connector/mcp/client.js.map +1 -1
- package/dist/constants/mcp/index.d.ts +2 -0
- package/dist/constants/mcp/index.d.ts.map +1 -1
- package/dist/constants/mcp/index.js +2 -0
- package/dist/constants/mcp/index.js.map +1 -1
- package/dist/constants/plugin/index.d.ts +2 -0
- package/dist/constants/plugin/index.d.ts.map +1 -1
- package/dist/constants/plugin/index.js +2 -0
- package/dist/constants/plugin/index.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +1 -1
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +25 -4
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +2 -1
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/persona/assembler.d.ts.map +1 -1
- package/dist/persona/assembler.js +2 -2
- package/dist/persona/assembler.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/lifecycle.d.ts +8 -1
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +9 -2
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/shell-hook-http.d.ts +39 -0
- package/dist/plugin/shell-hook-http.d.ts.map +1 -0
- package/dist/plugin/shell-hook-http.js +163 -0
- package/dist/plugin/shell-hook-http.js.map +1 -0
- package/dist/plugin/shell-hook.d.ts +93 -11
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +223 -39
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
- package/dist/prompt/coding-agent-doctrine.js +2 -1
- package/dist/prompt/coding-agent-doctrine.js.map +1 -1
- package/dist/public-runtime.d.ts +3 -2
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +2 -2
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +1 -0
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +2 -0
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +1 -1
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/query/executor.d.ts +4 -0
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +47 -9
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts +8 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +29 -1
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +6 -2
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +18 -8
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-breaker.js +33 -9
- package/dist/runtime/query/iteration/phases/compaction-breaker.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +52 -5
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +5 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +70 -3
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/path-escalation.d.ts +2 -0
- package/dist/runtime/query/path-escalation.d.ts.map +1 -1
- package/dist/runtime/query/path-escalation.js +7 -4
- package/dist/runtime/query/path-escalation.js.map +1 -1
- package/dist/runtime/query/plugin-hooks.js +2 -2
- package/dist/runtime/query/plugin-hooks.js.map +1 -1
- package/dist/runtime/query/prepare-turn.d.ts +2 -0
- package/dist/runtime/query/prepare-turn.d.ts.map +1 -1
- package/dist/runtime/query/prepare-turn.js +25 -0
- package/dist/runtime/query/prepare-turn.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +3 -2
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +32 -13
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/scheduler/local.js +1 -1
- package/dist/scheduler/local.js.map +1 -1
- package/dist/session/retention/archive.js +1 -1
- package/dist/session/retention/archive.js.map +1 -1
- package/dist/session/workspace/driver.d.ts +6 -0
- package/dist/session/workspace/driver.d.ts.map +1 -1
- package/dist/session/workspace/git-worktree.d.ts.map +1 -1
- package/dist/session/workspace/git-worktree.js +28 -0
- package/dist/session/workspace/git-worktree.js.map +1 -1
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/loader.d.ts +7 -0
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +53 -0
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/registry.d.ts +1 -1
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +2 -1
- package/dist/skills/registry.js.map +1 -1
- package/dist/tools/builtins/bash-cwd.d.ts +52 -0
- package/dist/tools/builtins/bash-cwd.d.ts.map +1 -0
- package/dist/tools/builtins/bash-cwd.js +127 -0
- package/dist/tools/builtins/bash-cwd.js.map +1 -0
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +41 -6
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/bounded-file-read.d.ts +10 -0
- package/dist/tools/builtins/bounded-file-read.d.ts.map +1 -0
- package/dist/tools/builtins/bounded-file-read.js +67 -0
- package/dist/tools/builtins/bounded-file-read.js.map +1 -0
- package/dist/tools/builtins/grep.d.ts +6 -1
- package/dist/tools/builtins/grep.d.ts.map +1 -1
- package/dist/tools/builtins/grep.js +187 -24
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/read-file.d.ts +1 -0
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +113 -28
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/read-media.d.ts +68 -0
- package/dist/tools/builtins/read-media.d.ts.map +1 -0
- package/dist/tools/builtins/read-media.js +397 -0
- package/dist/tools/builtins/read-media.js.map +1 -0
- package/dist/tools/builtins/search-tools.js +1 -1
- package/dist/tools/builtins/search-tools.js.map +1 -1
- package/dist/tools/builtins/skill.d.ts +4 -2
- package/dist/tools/builtins/skill.d.ts.map +1 -1
- package/dist/tools/builtins/skill.js +61 -2
- package/dist/tools/builtins/skill.js.map +1 -1
- package/dist/tools/builtins/sleep-guard.d.ts +15 -0
- package/dist/tools/builtins/sleep-guard.d.ts.map +1 -0
- package/dist/tools/builtins/sleep-guard.js +33 -0
- package/dist/tools/builtins/sleep-guard.js.map +1 -0
- package/dist/tools/builtins/view-image.d.ts +23 -1
- package/dist/tools/builtins/view-image.d.ts.map +1 -1
- package/dist/tools/builtins/view-image.js +66 -58
- package/dist/tools/builtins/view-image.js.map +1 -1
- package/dist/tools/file-read-tracker.d.ts.map +1 -1
- package/dist/tools/file-read-tracker.js +31 -0
- package/dist/tools/file-read-tracker.js.map +1 -1
- package/dist/toolsets/manager.js +3 -3
- package/dist/toolsets/manager.js.map +1 -1
- package/dist/types/agent/base.d.ts +8 -0
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/query.d.ts +2 -0
- package/dist/types/agent/query.d.ts.map +1 -1
- package/dist/types/agent/scheduler.d.ts +8 -0
- package/dist/types/agent/scheduler.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +6 -2
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/agent/task.js.map +1 -1
- package/dist/types/connector/mcp.d.ts +46 -0
- package/dist/types/connector/mcp.d.ts.map +1 -1
- package/dist/types/hitl/index.d.ts +1 -1
- package/dist/types/plugin/index.d.ts +74 -7
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js +12 -1
- package/dist/types/plugin/index.js.map +1 -1
- package/dist/types/session/sub-session.d.ts +6 -2
- package/dist/types/session/sub-session.d.ts.map +1 -1
- package/dist/types/skills/index.d.ts +36 -0
- package/dist/types/skills/index.d.ts.map +1 -1
- package/dist/types/skills/index.js +9 -0
- package/dist/types/skills/index.js.map +1 -1
- package/dist/types/tool/index.d.ts +37 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/workspace/ref.d.ts +2 -0
- package/dist/types/workspace/ref.d.ts.map +1 -1
- package/dist/utils/frontmatter.d.ts +12 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +6 -0
- package/dist/utils/frontmatter.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/QueryAgent.ts +3 -0
- package/src/agents/file-definitions.ts +126 -6
- package/src/authorization/protected-paths.ts +30 -2
- package/src/compaction/index.ts +1 -0
- package/src/compaction/manual.ts +68 -30
- package/src/compaction/model-summary.ts +412 -0
- package/src/compaction/verifier.ts +3 -3
- package/src/config/runtime.ts +16 -0
- package/src/connector/mcp/client.ts +87 -1
- package/src/constants/mcp/index.ts +3 -0
- package/src/constants/plugin/index.ts +2 -0
- package/src/manager/agent/lifecycle.ts +24 -5
- package/src/manager/session/turn-recorder.ts +2 -1
- package/src/persona/assembler.ts +2 -2
- package/src/plugin/index.ts +5 -0
- package/src/plugin/lifecycle.ts +16 -2
- package/src/plugin/shell-hook-http.ts +181 -0
- package/src/plugin/shell-hook.ts +386 -89
- package/src/prompt/coding-agent-doctrine.ts +2 -1
- package/src/public-runtime.ts +6 -0
- package/src/public-tools.ts +2 -0
- package/src/public-types.ts +5 -0
- package/src/runtime/query/executor.ts +54 -10
- package/src/runtime/query/index.ts +44 -0
- package/src/runtime/query/iteration/index.ts +11 -3
- package/src/runtime/query/iteration/phases/compaction-breaker.ts +38 -9
- package/src/runtime/query/iteration/phases/compaction.ts +67 -5
- package/src/runtime/query/iteration/phases/context.ts +6 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +74 -3
- package/src/runtime/query/path-escalation.ts +11 -5
- package/src/runtime/query/plugin-hooks.ts +2 -2
- package/src/runtime/query/prepare-turn.ts +33 -0
- package/src/runtime/query/review-policy.ts +45 -16
- package/src/scheduler/local.ts +1 -1
- package/src/session/retention/archive.ts +1 -1
- package/src/session/workspace/driver.ts +6 -0
- package/src/session/workspace/git-worktree.ts +31 -0
- package/src/skills/index.ts +6 -1
- package/src/skills/loader.ts +54 -0
- package/src/skills/registry.ts +7 -6
- package/src/tools/builtins/bash-cwd.ts +156 -0
- package/src/tools/builtins/bash.ts +79 -34
- package/src/tools/builtins/bounded-file-read.ts +80 -0
- package/src/tools/builtins/grep.ts +198 -28
- package/src/tools/builtins/read-file.ts +151 -30
- package/src/tools/builtins/read-media.ts +483 -0
- package/src/tools/builtins/search-tools.ts +1 -1
- package/src/tools/builtins/skill.ts +91 -2
- package/src/tools/builtins/sleep-guard.ts +31 -0
- package/src/tools/builtins/view-image.ts +74 -62
- package/src/tools/file-read-tracker.ts +30 -0
- package/src/toolsets/manager.ts +3 -3
- package/src/types/agent/base.ts +9 -0
- package/src/types/agent/query.ts +2 -0
- package/src/types/agent/scheduler.ts +9 -0
- package/src/types/agent/task.ts +6 -2
- package/src/types/connector/mcp.ts +48 -0
- package/src/types/hitl/index.ts +1 -1
- package/src/types/plugin/index.ts +102 -16
- package/src/types/session/sub-session.ts +6 -2
- package/src/types/skills/index.ts +48 -0
- package/src/types/tool/index.ts +38 -0
- package/src/types/workspace/ref.ts +2 -0
- package/src/utils/frontmatter.ts +21 -0
|
@@ -14,13 +14,20 @@
|
|
|
14
14
|
* name: reviewer
|
|
15
15
|
* description: Reviews a diff for correctness and convention drift.
|
|
16
16
|
* tools: read, grep, glob # optional allowlist, intersected with the parent's set
|
|
17
|
-
*
|
|
17
|
+
* disallowedTools: bash # optional; removed from whatever the rest allows
|
|
18
|
+
* model: claude-sonnet-4-5 # optional override; `inherit` keeps the session's
|
|
19
|
+
* effort: high # optional reasoning effort
|
|
20
|
+
* maxTurns: 20 # optional cap on the agent's own turns
|
|
21
|
+
* background: true # optional; runs in the background unless the call says otherwise
|
|
22
|
+
* isolation: worktree # optional; its own Git checkout
|
|
23
|
+
* skills: release-notes # optional; skills loaded into its prompt
|
|
18
24
|
* readOnly: true # optional; keeps only read-only tools
|
|
25
|
+
* permissionMode: plan # optional; a mode name the host lists
|
|
19
26
|
* ---
|
|
20
27
|
* You review changes for this repository. Cite file:line for every finding …
|
|
21
28
|
* ```
|
|
22
29
|
*
|
|
23
|
-
* `tools`
|
|
30
|
+
* `tools`, `disallowedTools` and `skills` are each one comma-separated line: this kernel's frontmatter reader
|
|
24
31
|
* refuses block lists and flow sequences by design, so there is no other
|
|
25
32
|
* form to accept.
|
|
26
33
|
*
|
|
@@ -36,6 +43,7 @@
|
|
|
36
43
|
import { readFile, readdir, stat } from 'node:fs/promises'
|
|
37
44
|
import { join } from 'node:path'
|
|
38
45
|
|
|
46
|
+
import type { ReasoningEffort } from '../types/provider/chat.js'
|
|
39
47
|
import { parseFrontmatter } from '../utils/frontmatter.js'
|
|
40
48
|
import { SCOPE_ATTRIBUTE } from '../utils/log/types.js'
|
|
41
49
|
import { type Logger, resolveLogger } from '../utils/logger.js'
|
|
@@ -52,6 +60,17 @@ export const DEFAULT_RESERVED_AGENT_NAMES: ReadonlySet<string> = new Set([
|
|
|
52
60
|
'explore',
|
|
53
61
|
])
|
|
54
62
|
|
|
63
|
+
const EFFORT_LEVELS: ReadonlySet<string> = new Set<ReasoningEffort>([
|
|
64
|
+
'none',
|
|
65
|
+
'minimal',
|
|
66
|
+
'low',
|
|
67
|
+
'medium',
|
|
68
|
+
'high',
|
|
69
|
+
'xhigh',
|
|
70
|
+
'max',
|
|
71
|
+
'ultra',
|
|
72
|
+
])
|
|
73
|
+
|
|
55
74
|
const NAME_PATTERN = /^[a-z][a-z0-9-]{0,63}$/
|
|
56
75
|
|
|
57
76
|
export interface AgentFileDefinition {
|
|
@@ -61,7 +80,25 @@ export interface AgentFileDefinition {
|
|
|
61
80
|
readonly prompt: string
|
|
62
81
|
/** Tool names the agent may use; absent means the parent's working set. */
|
|
63
82
|
readonly tools?: readonly string[]
|
|
83
|
+
/** Tool names removed from the roster whatever else allows them. */
|
|
84
|
+
readonly disallowedTools?: readonly string[]
|
|
85
|
+
/** Absent means the session's model; `model: inherit` in a file is the same thing. */
|
|
64
86
|
readonly model?: string
|
|
87
|
+
/** Reasoning effort the agent runs with, when its model supports it. */
|
|
88
|
+
readonly effort?: ReasoningEffort
|
|
89
|
+
/** The most turns the agent takes before it stops; a positive whole number. */
|
|
90
|
+
readonly maxTurns?: number
|
|
91
|
+
/** The agent runs in the background when the call does not say. */
|
|
92
|
+
readonly background?: boolean
|
|
93
|
+
/** `worktree`: the agent works in its own Git checkout. */
|
|
94
|
+
readonly isolation?: 'worktree'
|
|
95
|
+
/** Skills whose instructions are loaded into the agent's prompt. */
|
|
96
|
+
readonly skills?: readonly string[]
|
|
97
|
+
/**
|
|
98
|
+
* The permission mode the file asks for, as the word the host accepts. The
|
|
99
|
+
* host decides what it may do with it; the kernel only keeps it.
|
|
100
|
+
*/
|
|
101
|
+
readonly permissionMode?: string
|
|
65
102
|
readonly readOnly: boolean
|
|
66
103
|
readonly path: string
|
|
67
104
|
/** The host's label for the root this file came from (`user`, `project`, …). */
|
|
@@ -87,6 +124,11 @@ export interface DiscoveredAgentDefinitions {
|
|
|
87
124
|
export interface DiscoverAgentDefinitionsOptions {
|
|
88
125
|
/** Names refused in a file. Defaults to `DEFAULT_RESERVED_AGENT_NAMES`. */
|
|
89
126
|
readonly reserved?: ReadonlySet<string>
|
|
127
|
+
/**
|
|
128
|
+
* The words a `permissionMode:` line may use. A file naming any other word
|
|
129
|
+
* is reported and skipped. Absent: any non-empty word is kept.
|
|
130
|
+
*/
|
|
131
|
+
readonly permissionModes?: ReadonlySet<string>
|
|
90
132
|
readonly log?: Logger
|
|
91
133
|
}
|
|
92
134
|
|
|
@@ -114,7 +156,12 @@ export async function discoverAgentDefinitions(
|
|
|
114
156
|
continue
|
|
115
157
|
}
|
|
116
158
|
for (const file of files) {
|
|
117
|
-
const found = await parseAgentFile(
|
|
159
|
+
const found = await parseAgentFile(
|
|
160
|
+
join(root.dir, file),
|
|
161
|
+
root.source,
|
|
162
|
+
options.reserved,
|
|
163
|
+
options.permissionModes,
|
|
164
|
+
)
|
|
118
165
|
if ('reason' in found) skipped.push(found)
|
|
119
166
|
else byName.set(found.name, found)
|
|
120
167
|
}
|
|
@@ -126,6 +173,7 @@ export async function parseAgentFile(
|
|
|
126
173
|
path: string,
|
|
127
174
|
source: string,
|
|
128
175
|
reserved: ReadonlySet<string> = DEFAULT_RESERVED_AGENT_NAMES,
|
|
176
|
+
permissionModes?: ReadonlySet<string>,
|
|
129
177
|
): Promise<AgentFileDefinition | SkippedAgentFile> {
|
|
130
178
|
let raw: string
|
|
131
179
|
try {
|
|
@@ -139,7 +187,7 @@ export async function parseAgentFile(
|
|
|
139
187
|
reason: `could not be read: ${error instanceof Error ? error.message : String(error)}`,
|
|
140
188
|
}
|
|
141
189
|
}
|
|
142
|
-
return parseAgentMarkdown(raw, path, source, reserved)
|
|
190
|
+
return parseAgentMarkdown(raw, path, source, reserved, permissionModes)
|
|
143
191
|
}
|
|
144
192
|
|
|
145
193
|
/** Pure: the file's text to a definition, or the reason it is refused. */
|
|
@@ -148,6 +196,7 @@ export function parseAgentMarkdown(
|
|
|
148
196
|
path: string,
|
|
149
197
|
source: string,
|
|
150
198
|
reserved: ReadonlySet<string> = DEFAULT_RESERVED_AGENT_NAMES,
|
|
199
|
+
permissionModes?: ReadonlySet<string>,
|
|
151
200
|
): AgentFileDefinition | SkippedAgentFile {
|
|
152
201
|
if (!raw.trimStart().startsWith('---')) {
|
|
153
202
|
return { path, reason: 'has no frontmatter; an agent file starts with `---` and a `name:`' }
|
|
@@ -184,10 +233,74 @@ export function parseAgentMarkdown(
|
|
|
184
233
|
}
|
|
185
234
|
tools = list
|
|
186
235
|
}
|
|
187
|
-
const
|
|
188
|
-
|
|
236
|
+
const listed = (key: 'disallowedTools' | 'skills') => {
|
|
237
|
+
const value = values[key]
|
|
238
|
+
if (value === undefined) return { ok: true as const, list: undefined }
|
|
239
|
+
const list = stringList(value)
|
|
240
|
+
if (list === undefined || list.length === 0) {
|
|
241
|
+
return { ok: false as const, reason: `\`${key}:\` must be a non-empty, comma-separated list` }
|
|
242
|
+
}
|
|
243
|
+
return { ok: true as const, list }
|
|
244
|
+
}
|
|
245
|
+
const denied = listed('disallowedTools')
|
|
246
|
+
if (!denied.ok) return { path, reason: denied.reason }
|
|
247
|
+
const preloaded = listed('skills')
|
|
248
|
+
if (!preloaded.ok) return { path, reason: preloaded.reason }
|
|
249
|
+
|
|
250
|
+
const modelText = scalar(values.model)
|
|
251
|
+
if (values.model !== undefined && (modelText === undefined || modelText.trim().length === 0)) {
|
|
189
252
|
return { path, reason: '`model:` must be a model name' }
|
|
190
253
|
}
|
|
254
|
+
// `inherit` is the same as no line: the session's own model.
|
|
255
|
+
const model = modelText?.trim().toLowerCase() === 'inherit' ? undefined : modelText
|
|
256
|
+
let effort: ReasoningEffort | undefined
|
|
257
|
+
if (values.effort !== undefined) {
|
|
258
|
+
const level = scalar(values.effort)?.trim().toLowerCase()
|
|
259
|
+
if (level === undefined || !EFFORT_LEVELS.has(level)) {
|
|
260
|
+
return {
|
|
261
|
+
path,
|
|
262
|
+
reason: `\`effort:\` must be one of ${[...EFFORT_LEVELS].join(', ')}`,
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
effort = level as ReasoningEffort
|
|
266
|
+
}
|
|
267
|
+
let maxTurns: number | undefined
|
|
268
|
+
if (values.maxTurns !== undefined) {
|
|
269
|
+
const text = scalar(values.maxTurns)?.trim()
|
|
270
|
+
if (text === undefined || !/^[1-9][0-9]{0,8}$/.test(text)) {
|
|
271
|
+
return { path, reason: '`maxTurns:` must be a positive whole number' }
|
|
272
|
+
}
|
|
273
|
+
maxTurns = Number(text)
|
|
274
|
+
}
|
|
275
|
+
let background: boolean | undefined
|
|
276
|
+
if (values.background !== undefined) {
|
|
277
|
+
const flag = scalar(values.background)
|
|
278
|
+
if (flag !== 'true' && flag !== 'false') {
|
|
279
|
+
return { path, reason: '`background:` must be true or false' }
|
|
280
|
+
}
|
|
281
|
+
background = flag === 'true'
|
|
282
|
+
}
|
|
283
|
+
let isolation: 'worktree' | undefined
|
|
284
|
+
if (values.isolation !== undefined) {
|
|
285
|
+
if (scalar(values.isolation)?.trim() !== 'worktree') {
|
|
286
|
+
return { path, reason: '`isolation:` must be worktree' }
|
|
287
|
+
}
|
|
288
|
+
isolation = 'worktree'
|
|
289
|
+
}
|
|
290
|
+
let permissionMode: string | undefined
|
|
291
|
+
if (values.permissionMode !== undefined) {
|
|
292
|
+
const word = scalar(values.permissionMode)?.trim()
|
|
293
|
+
if (word === undefined || word.length === 0) {
|
|
294
|
+
return { path, reason: '`permissionMode:` must be a mode name' }
|
|
295
|
+
}
|
|
296
|
+
if (permissionModes && !permissionModes.has(word)) {
|
|
297
|
+
return {
|
|
298
|
+
path,
|
|
299
|
+
reason: `\`permissionMode: ${word}\` is not one of ${[...permissionModes].join(', ')}`,
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
permissionMode = word
|
|
303
|
+
}
|
|
191
304
|
let readOnly = false
|
|
192
305
|
if (values.readOnly !== undefined) {
|
|
193
306
|
const flag = scalar(values.readOnly)
|
|
@@ -211,7 +324,14 @@ export function parseAgentMarkdown(
|
|
|
211
324
|
description: description.trim(),
|
|
212
325
|
prompt,
|
|
213
326
|
...(tools ? { tools } : {}),
|
|
327
|
+
...(denied.list ? { disallowedTools: denied.list } : {}),
|
|
214
328
|
...(model ? { model: model.trim() } : {}),
|
|
329
|
+
...(effort ? { effort } : {}),
|
|
330
|
+
...(maxTurns !== undefined ? { maxTurns } : {}),
|
|
331
|
+
...(background !== undefined ? { background } : {}),
|
|
332
|
+
...(isolation ? { isolation } : {}),
|
|
333
|
+
...(preloaded.list ? { skills: preloaded.list } : {}),
|
|
334
|
+
...(permissionMode ? { permissionMode } : {}),
|
|
215
335
|
readOnly,
|
|
216
336
|
path,
|
|
217
337
|
source,
|
|
@@ -79,11 +79,29 @@ export const PROTECTED_FILE_NAMES: readonly string[] = [
|
|
|
79
79
|
'pyrightconfig.json',
|
|
80
80
|
]
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Folders under the project directory that hold what a person or the model
|
|
84
|
+
* authors on purpose (skills, agent definitions, commands) and the checkouts
|
|
85
|
+
* of delegated work. Writing there is the point of the folder, so the project
|
|
86
|
+
* directory is not protected on their account. Only the first project
|
|
87
|
+
* directory in a path can be excused: a second one deeper down, or any other
|
|
88
|
+
* protected name below, still protects the path.
|
|
89
|
+
*/
|
|
90
|
+
export const PROJECT_DIRECTORY_AUTHORED_FOLDERS: readonly string[] = [
|
|
91
|
+
'skills',
|
|
92
|
+
'agents',
|
|
93
|
+
'commands',
|
|
94
|
+
'worktrees',
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
const PROJECT_DIRECTORY = '.namzu'
|
|
98
|
+
|
|
82
99
|
/** Lower case, with the two letters that fold into ASCII on some file systems. */
|
|
83
100
|
function fold(name: string): string {
|
|
84
101
|
return name.toLowerCase().replace(/ı/g, 'i').replace(/ſ/g, 's')
|
|
85
102
|
}
|
|
86
103
|
|
|
104
|
+
const AUTHORED = new Set(PROJECT_DIRECTORY_AUTHORED_FOLDERS.map(fold))
|
|
87
105
|
const DIRECTORIES = new Set(PROTECTED_DIRECTORIES.map(fold))
|
|
88
106
|
const FILE_NAMES = new Set(PROTECTED_FILE_NAMES.map(fold))
|
|
89
107
|
const NESTED = PROTECTED_NESTED_DIRECTORIES.map((sequence) => sequence.map(fold))
|
|
@@ -95,8 +113,18 @@ const NESTED = PROTECTED_NESTED_DIRECTORIES.map((sequence) => sequence.map(fold)
|
|
|
95
113
|
*/
|
|
96
114
|
export function isProtectedPath(path: string): boolean {
|
|
97
115
|
const segments = path.split(/[\\/]+/).map(fold)
|
|
98
|
-
|
|
99
|
-
|
|
116
|
+
let excused = false
|
|
117
|
+
for (let index = 0; index < segments.length; index += 1) {
|
|
118
|
+
const segment = segments[index] as string
|
|
119
|
+
if (!DIRECTORIES.has(segment)) continue
|
|
120
|
+
if (segment === PROJECT_DIRECTORY && !excused) {
|
|
121
|
+
const next = segments[index + 1]
|
|
122
|
+
if (next !== undefined && AUTHORED.has(next)) {
|
|
123
|
+
excused = true
|
|
124
|
+
continue
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return true
|
|
100
128
|
}
|
|
101
129
|
for (const sequence of NESTED) {
|
|
102
130
|
for (let start = 0; start + sequence.length <= segments.length; start += 1) {
|
package/src/compaction/index.ts
CHANGED
|
@@ -41,6 +41,7 @@ export {
|
|
|
41
41
|
} from './extractor.js'
|
|
42
42
|
|
|
43
43
|
export { buildVerifiedSummary } from './verifier.js'
|
|
44
|
+
export type { CompactionSummaryRoute, CompactionSummaryRouter } from './model-summary.js'
|
|
44
45
|
export type { CompactionVerificationOptions } from './verifier.js'
|
|
45
46
|
|
|
46
47
|
export {
|
package/src/compaction/manual.ts
CHANGED
|
@@ -16,6 +16,11 @@ import {
|
|
|
16
16
|
extractFromUserMessage,
|
|
17
17
|
} from './extractor.js'
|
|
18
18
|
import { WorkingStateManager } from './manager.js'
|
|
19
|
+
import {
|
|
20
|
+
type CompactionSummaryRouter,
|
|
21
|
+
replaceableSummaries,
|
|
22
|
+
summarizeWithModel,
|
|
23
|
+
} from './model-summary.js'
|
|
19
24
|
import { planCompaction } from './plan.js'
|
|
20
25
|
import { recordRestorable, renderRestoredContext } from './restore.js'
|
|
21
26
|
import { findRetainedIndices } from './retention.js'
|
|
@@ -72,6 +77,33 @@ export interface CompactNowInput extends CompactionVerificationOptions {
|
|
|
72
77
|
readonly recoveryNote?: string
|
|
73
78
|
/** Text the host wants carried across, such as where its plan file is; added to the restored context. */
|
|
74
79
|
readonly restoreNote?: string
|
|
80
|
+
/**
|
|
81
|
+
* Names the model that writes the summary. Its tokens come back in
|
|
82
|
+
* {@link CompactionResult.usage}. Absent, or when its call fails, the
|
|
83
|
+
* summary is built from the extracted state as before.
|
|
84
|
+
*/
|
|
85
|
+
readonly summaryRoute?: CompactionSummaryRouter
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** The model-written summary of `span` for a host-triggered pass, if one can be had. */
|
|
89
|
+
async function modelWrittenBody(
|
|
90
|
+
input: CompactNowInput,
|
|
91
|
+
manager: WorkingStateManager,
|
|
92
|
+
span: readonly Message[],
|
|
93
|
+
earlier: readonly Message[],
|
|
94
|
+
onUsage: (usage: TokenUsage) => void,
|
|
95
|
+
): Promise<string | undefined> {
|
|
96
|
+
return summarizeWithModel({
|
|
97
|
+
manager,
|
|
98
|
+
olderMessages: span,
|
|
99
|
+
previousSummaries: replaceableSummaries(earlier),
|
|
100
|
+
config: input.config,
|
|
101
|
+
resolveRoute: input.summaryRoute,
|
|
102
|
+
onUsage,
|
|
103
|
+
signal: input.signal,
|
|
104
|
+
streamIdleTimeoutMs: input.streamIdleTimeoutMs,
|
|
105
|
+
instructions: input.instructions,
|
|
106
|
+
})
|
|
75
107
|
}
|
|
76
108
|
|
|
77
109
|
async function publishManualCompaction(
|
|
@@ -230,21 +262,24 @@ export async function compactNow(input: CompactNowInput): Promise<CompactionResu
|
|
|
230
262
|
const manager = new WorkingStateManager(input.config)
|
|
231
263
|
populateWorkingState(manager, plan.olderMessages, input.config)
|
|
232
264
|
let usage: TokenUsage = { ...EMPTY_TOKEN_USAGE }
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
input.
|
|
238
|
-
(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
265
|
+
const onUsage = (reported: TokenUsage) => {
|
|
266
|
+
usage = accumulateTokenUsage(usage, reported)
|
|
267
|
+
}
|
|
268
|
+
const body =
|
|
269
|
+
(await modelWrittenBody(input, manager, plan.olderMessages, plan.systemMessages, onUsage)) ??
|
|
270
|
+
(await buildVerifiedSummary(
|
|
271
|
+
manager,
|
|
272
|
+
[...plan.olderMessages],
|
|
273
|
+
input.provider,
|
|
274
|
+
input.config,
|
|
275
|
+
onUsage,
|
|
276
|
+
input.model ?? '',
|
|
277
|
+
{
|
|
278
|
+
signal: input.signal,
|
|
279
|
+
streamIdleTimeoutMs: input.streamIdleTimeoutMs,
|
|
280
|
+
instructions: input.instructions,
|
|
281
|
+
},
|
|
282
|
+
))
|
|
248
283
|
|
|
249
284
|
const { messages, summary } = splice(
|
|
250
285
|
preservedSystem,
|
|
@@ -322,21 +357,24 @@ export async function compactRegion(input: CompactRegionInput): Promise<Compacti
|
|
|
322
357
|
const manager = new WorkingStateManager(input.config)
|
|
323
358
|
populateWorkingState(manager, messages.slice(start, end), input.config)
|
|
324
359
|
let usage: TokenUsage = { ...EMPTY_TOKEN_USAGE }
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
input.
|
|
330
|
-
(
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
360
|
+
const onUsage = (reported: TokenUsage) => {
|
|
361
|
+
usage = accumulateTokenUsage(usage, reported)
|
|
362
|
+
}
|
|
363
|
+
const body =
|
|
364
|
+
(await modelWrittenBody(input, manager, messages.slice(start, end), [], onUsage)) ??
|
|
365
|
+
(await buildVerifiedSummary(
|
|
366
|
+
manager,
|
|
367
|
+
messages.slice(start, end),
|
|
368
|
+
input.provider,
|
|
369
|
+
input.config,
|
|
370
|
+
onUsage,
|
|
371
|
+
input.model ?? '',
|
|
372
|
+
{
|
|
373
|
+
signal: input.signal,
|
|
374
|
+
streamIdleTimeoutMs: input.streamIdleTimeoutMs,
|
|
375
|
+
instructions: input.instructions,
|
|
376
|
+
},
|
|
377
|
+
))
|
|
340
378
|
|
|
341
379
|
// Same cross-run ownership as compactNow: a selected region has been
|
|
342
380
|
// replaced outside a turn, so its only surviving account is pinned.
|