@bastani/atomic 0.8.17-0 → 0.8.18-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 +16 -0
- package/dist/builtin/intercom/CHANGELOG.md +5 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +5 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +5 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/CHANGELOG.md +5 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +25 -0
- package/dist/builtin/workflows/README.md +62 -3
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +555 -537
- package/dist/builtin/workflows/builtin/goal.ts +5 -0
- package/dist/builtin/workflows/builtin/open-claude-design.ts +3 -3
- package/dist/builtin/workflows/builtin/ralph.ts +737 -713
- package/dist/builtin/workflows/builtin/shared-prompts.ts +11 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/discovery.ts +61 -22
- package/dist/builtin/workflows/src/extension/index.ts +2 -0
- package/dist/builtin/workflows/src/extension/runtime.ts +4 -0
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +4 -0
- package/dist/builtin/workflows/src/runs/foreground/executor.ts +96 -6
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +2 -0
- package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +7 -0
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +214 -1
- package/dist/builtin/workflows/src/sdk-surface.ts +2 -0
- package/dist/builtin/workflows/src/shared/types.ts +32 -3
- package/dist/builtin/workflows/src/workflows/define-workflow.ts +18 -1
- package/dist/core/agent-session-services.d.ts +2 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +16 -5
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +40 -28
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/sdk.d.ts +9 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +2 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/system-prompt.d.ts +2 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +22 -13
- package/dist/core/system-prompt.js.map +1 -1
- package/docs/quickstart.md +13 -5
- package/docs/sdk.md +20 -5
- package/docs/workflows.md +44 -17
- package/examples/sdk/05-tools.ts +22 -1
- package/examples/sdk/README.md +7 -3
- package/package.json +1 -1
|
@@ -71,6 +71,24 @@ interface GitResult {
|
|
|
71
71
|
stdout: string;
|
|
72
72
|
stderr: string;
|
|
73
73
|
status: number | null;
|
|
74
|
+
error?: Error;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface GitWorktreeSetupOptions {
|
|
78
|
+
gitWorktreeDir: string;
|
|
79
|
+
baseBranch?: string;
|
|
80
|
+
cwd: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface GitWorktreeSetupResult {
|
|
84
|
+
/** Root checkout path that was requested/created/reused. */
|
|
85
|
+
worktreeRoot: string;
|
|
86
|
+
/** Effective workflow cwd, preserving the caller's repo-relative subdirectory inside the worktree. */
|
|
87
|
+
cwd: string;
|
|
88
|
+
/** Invoking checkout root reported by Git. */
|
|
89
|
+
repositoryRoot: string;
|
|
90
|
+
/** Whether this call created a new linked worktree. Existing roots are reused as-is. */
|
|
91
|
+
created: boolean;
|
|
74
92
|
}
|
|
75
93
|
|
|
76
94
|
interface RepoState {
|
|
@@ -80,13 +98,26 @@ interface RepoState {
|
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
const DEFAULT_WORKTREE_SETUP_HOOK_TIMEOUT_MS = 30000;
|
|
101
|
+
const DISABLED_GIT_HOOKS_PATH = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
83
102
|
|
|
84
103
|
function runGit(cwd: string, args: string[]): GitResult {
|
|
85
|
-
const result = spawnSync("git", [
|
|
104
|
+
const result = spawnSync("git", [
|
|
105
|
+
"-c",
|
|
106
|
+
`core.hooksPath=${DISABLED_GIT_HOOKS_PATH}`,
|
|
107
|
+
"-c",
|
|
108
|
+
"core.fsmonitor=false",
|
|
109
|
+
...args,
|
|
110
|
+
], {
|
|
111
|
+
cwd,
|
|
112
|
+
encoding: "utf-8",
|
|
113
|
+
env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" },
|
|
114
|
+
timeout: 5000,
|
|
115
|
+
});
|
|
86
116
|
return {
|
|
87
117
|
stdout: result.stdout ?? "",
|
|
88
118
|
stderr: result.stderr ?? "",
|
|
89
119
|
status: result.status,
|
|
120
|
+
...(result.error === undefined ? {} : { error: result.error }),
|
|
90
121
|
};
|
|
91
122
|
}
|
|
92
123
|
|
|
@@ -100,6 +131,188 @@ function runGitChecked(cwd: string, args: string[]): string {
|
|
|
100
131
|
return result.stdout;
|
|
101
132
|
}
|
|
102
133
|
|
|
134
|
+
function gitFailureMessage(result: GitResult): string {
|
|
135
|
+
if (result.error !== undefined) return result.error.message;
|
|
136
|
+
return result.stderr.trim() || result.stdout.trim() || `git exited with status ${result.status}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function quoteShellArg(value: string): string {
|
|
140
|
+
if (process.platform === "win32") return `"${value.replace(/"/g, "\"\"")}"`;
|
|
141
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function worktreeRecoveryCommand(repositoryRoot: string, worktreeDir: string): string {
|
|
145
|
+
return `git -C ${quoteShellArg(repositoryRoot)} worktree remove --force ${quoteShellArg(worktreeDir)}`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function hasGrandparent(value: string): boolean {
|
|
149
|
+
const parent = path.dirname(value);
|
|
150
|
+
if (parent === value) return false;
|
|
151
|
+
const grandparent = path.dirname(parent);
|
|
152
|
+
return grandparent !== parent;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function pathAncestors(value: string): string[] {
|
|
156
|
+
const ancestors: string[] = [];
|
|
157
|
+
let current = value;
|
|
158
|
+
while (true) {
|
|
159
|
+
ancestors.push(current);
|
|
160
|
+
const parent = path.dirname(current);
|
|
161
|
+
if (parent === current) return ancestors;
|
|
162
|
+
current = parent;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function shouldPreserveLogicalPath(logicalPath: string): boolean {
|
|
167
|
+
return pathAncestors(logicalPath).some((ancestor) => {
|
|
168
|
+
try {
|
|
169
|
+
return fs.lstatSync(ancestor).isSymbolicLink() && hasGrandparent(ancestor);
|
|
170
|
+
} catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function canonicalizePreservingSymlinks(value: string): string {
|
|
177
|
+
const logicalPath = path.resolve(value);
|
|
178
|
+
const preserveLogicalPath = shouldPreserveLogicalPath(logicalPath);
|
|
179
|
+
try {
|
|
180
|
+
const canonical = fs.realpathSync.native(logicalPath);
|
|
181
|
+
return preserveLogicalPath && canonical !== logicalPath ? logicalPath : canonical;
|
|
182
|
+
} catch {
|
|
183
|
+
return logicalPath;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function resolveGitWorktreePath(value: string, repoRoot: string): string {
|
|
188
|
+
const trimmed = value.trim();
|
|
189
|
+
if (!trimmed) throw new Error("gitWorktreeDir cannot be empty");
|
|
190
|
+
if (trimmed.includes("\0")) {
|
|
191
|
+
throw new Error("gitWorktreeDir contains an unusable null byte; provide a valid path or omit gitWorktreeDir.");
|
|
192
|
+
}
|
|
193
|
+
return canonicalizePreservingSymlinks(path.isAbsolute(trimmed) ? trimmed : path.resolve(repoRoot, trimmed));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function comparableRealPath(value: string): string {
|
|
197
|
+
const realpath = fs.realpathSync.native(value).replace(/\\/g, "/");
|
|
198
|
+
return process.platform === "win32" ? realpath.toLowerCase() : realpath;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function gitPathFromOutput(value: string, cwd: string): string | undefined {
|
|
202
|
+
const trimmed = value.trim();
|
|
203
|
+
if (!trimmed) return undefined;
|
|
204
|
+
return path.isAbsolute(trimmed) ? path.resolve(trimmed) : path.resolve(cwd, trimmed);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function pathExistsSync(value: string): boolean {
|
|
208
|
+
try {
|
|
209
|
+
fs.statSync(value);
|
|
210
|
+
return true;
|
|
211
|
+
} catch (error) {
|
|
212
|
+
const code = error && typeof error === "object" && "code" in error ? (error as { code?: unknown }).code : undefined;
|
|
213
|
+
if (code === "ENOENT" || code === "ENOTDIR") return false;
|
|
214
|
+
throw error;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function repositoryRootForGitWorktree(cwd: string): string {
|
|
219
|
+
const result = runGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
220
|
+
if (result.status !== 0) {
|
|
221
|
+
throw new Error(`gitWorktreeDir requires the workflow to be invoked from inside a Git repository. Start from a Git checkout or omit gitWorktreeDir. Git reported: ${gitFailureMessage(result)}`);
|
|
222
|
+
}
|
|
223
|
+
return result.stdout.trim();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function gitTopLevel(cwd: string): string | undefined {
|
|
227
|
+
const result = runGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
228
|
+
if (result.status !== 0) return undefined;
|
|
229
|
+
return gitPathFromOutput(result.stdout, cwd);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function gitCommonDirForWorktree(cwd: string): string {
|
|
233
|
+
const result = runGit(cwd, ["rev-parse", "--git-common-dir"]);
|
|
234
|
+
if (result.status !== 0) throw new Error(gitFailureMessage(result));
|
|
235
|
+
const gitPath = gitPathFromOutput(result.stdout, cwd);
|
|
236
|
+
if (gitPath === undefined) throw new Error("git rev-parse --git-common-dir returned an empty path");
|
|
237
|
+
return gitPath;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function dirnameForEachRelativeComponent(base: string, relativePath: string): string | undefined {
|
|
241
|
+
if (relativePath === "") return base;
|
|
242
|
+
let current = base;
|
|
243
|
+
for (const component of relativePath.split(/[\\/]+/).filter(Boolean)) {
|
|
244
|
+
if (component === ".") continue;
|
|
245
|
+
if (component === "..") return undefined;
|
|
246
|
+
current = path.dirname(current);
|
|
247
|
+
}
|
|
248
|
+
return current;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function cwdWithinGitRepository(cwd: string, repoRoot: string): { relativeCwd: string; logicalRepoRoot: string } {
|
|
252
|
+
const sourceCwd = fs.realpathSync.native(cwd);
|
|
253
|
+
const sourceRepoRoot = fs.realpathSync.native(repoRoot);
|
|
254
|
+
const relativeCwd = path.relative(sourceRepoRoot, sourceCwd);
|
|
255
|
+
const safeRelativeCwd = relativeCwd === "" || relativeCwd.startsWith("..") || path.isAbsolute(relativeCwd) ? "" : relativeCwd;
|
|
256
|
+
const logicalCwd = canonicalizePreservingSymlinks(cwd);
|
|
257
|
+
return {
|
|
258
|
+
relativeCwd: safeRelativeCwd,
|
|
259
|
+
logicalRepoRoot: dirnameForEachRelativeComponent(logicalCwd, safeRelativeCwd) ?? repoRoot,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function workspaceCwdForGitWorktreeRoot(worktreeRoot: string, relativeCwd: string): string {
|
|
264
|
+
return relativeCwd === "" ? worktreeRoot : path.join(worktreeRoot, relativeCwd);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function validateExistingGitWorktreeRoot(worktreeRoot: string, repoRoot: string): void {
|
|
268
|
+
const topLevel = gitTopLevel(worktreeRoot);
|
|
269
|
+
if (topLevel === undefined) {
|
|
270
|
+
throw new Error(`gitWorktreeDir already exists but is not a Git worktree: ${worktreeRoot}`);
|
|
271
|
+
}
|
|
272
|
+
if (comparableRealPath(worktreeRoot) !== comparableRealPath(topLevel)) {
|
|
273
|
+
throw new Error(`gitWorktreeDir already exists but is not a Git worktree root: ${worktreeRoot}. Git top-level checkout is ${topLevel}`);
|
|
274
|
+
}
|
|
275
|
+
if (comparableRealPath(gitCommonDirForWorktree(repoRoot)) !== comparableRealPath(gitCommonDirForWorktree(topLevel))) {
|
|
276
|
+
throw new Error(`gitWorktreeDir already exists but does not belong to the invoking Git repository: ${worktreeRoot}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function setupGitWorktree(options: GitWorktreeSetupOptions): GitWorktreeSetupResult {
|
|
281
|
+
const repoRoot = repositoryRootForGitWorktree(options.cwd);
|
|
282
|
+
const { relativeCwd, logicalRepoRoot } = cwdWithinGitRepository(options.cwd, repoRoot);
|
|
283
|
+
const worktreeRoot = resolveGitWorktreePath(options.gitWorktreeDir, logicalRepoRoot);
|
|
284
|
+
if (pathExistsSync(worktreeRoot)) {
|
|
285
|
+
validateExistingGitWorktreeRoot(worktreeRoot, repoRoot);
|
|
286
|
+
return {
|
|
287
|
+
worktreeRoot,
|
|
288
|
+
cwd: workspaceCwdForGitWorktreeRoot(worktreeRoot, relativeCwd),
|
|
289
|
+
repositoryRoot: repoRoot,
|
|
290
|
+
created: false,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
try {
|
|
295
|
+
fs.mkdirSync(path.dirname(worktreeRoot), { recursive: true });
|
|
296
|
+
} catch (error) {
|
|
297
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
298
|
+
throw new Error(`Failed to create parent directory for requested gitWorktreeDir ${worktreeRoot}: ${message}`);
|
|
299
|
+
}
|
|
300
|
+
const baseRef = options.baseBranch?.trim() || "HEAD";
|
|
301
|
+
const result = runGit(repoRoot, ["worktree", "add", "--detach", worktreeRoot, baseRef]);
|
|
302
|
+
if (result.status !== 0) {
|
|
303
|
+
throw new Error([
|
|
304
|
+
`Failed to create git worktree at requested gitWorktreeDir ${worktreeRoot} from ${baseRef}. Git reported: ${gitFailureMessage(result)}`,
|
|
305
|
+
`If another process just created this same-repository worktree, rerun the workflow to resume it. If this is an orphaned worktree from an interrupted run, recover or remove it with: ${worktreeRecoveryCommand(repoRoot, worktreeRoot)}`,
|
|
306
|
+
].join("\n"));
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
worktreeRoot,
|
|
310
|
+
cwd: workspaceCwdForGitWorktreeRoot(worktreeRoot, relativeCwd),
|
|
311
|
+
repositoryRoot: repoRoot,
|
|
312
|
+
created: true,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
103
316
|
function resolveRepoState(cwd: string): RepoState {
|
|
104
317
|
const cwdRelative = resolveRepoCwdRelative(cwd);
|
|
105
318
|
const toplevel = runGitChecked(cwd, ["rev-parse", "--show-toplevel"]).trim();
|
|
@@ -18,6 +18,8 @@ export type { RunOpts, RunResult, ResolvedInputs } from "./runs/foreground/execu
|
|
|
18
18
|
export type { AgentSessionAdapter, StageAdapters } from "./runs/foreground/stage-runner.js";
|
|
19
19
|
export { GraphFrontierTracker } from "./runs/shared/graph-inference.js";
|
|
20
20
|
export type { StageNode } from "./runs/shared/graph-inference.js";
|
|
21
|
+
export { setupGitWorktree } from "./runs/shared/worktree.js";
|
|
22
|
+
export type { GitWorktreeSetupOptions, GitWorktreeSetupResult } from "./runs/shared/worktree.js";
|
|
21
23
|
export { createStore, store } from "./shared/store.js";
|
|
22
24
|
export type { RunStatus, StageStatus, ToolEvent, StageSnapshot, RunSnapshot, StoreSnapshot, WorkflowNotice, NoticeLevel, WorkflowOverlayAdapter, PromptKind, PendingPrompt } from "./shared/store-types.js";
|
|
23
25
|
|
|
@@ -140,13 +140,17 @@ export interface StageMcpOptions {
|
|
|
140
140
|
/**
|
|
141
141
|
* Options accepted by WorkflowRunContext.stage(name, options?).
|
|
142
142
|
* All pi SDK createAgentSession options are forwarded to the stage session;
|
|
143
|
-
* `mcp`
|
|
143
|
+
* workflow-owned options such as `mcp` and `gitWorktreeDir` are stripped before SDK session creation.
|
|
144
144
|
*/
|
|
145
145
|
export interface StageOptions extends Omit<CreateAgentSessionOptions, "model">, WorkflowModelFallbackFields {
|
|
146
146
|
/** Model id or pi SDK model object used as the primary stage model. */
|
|
147
147
|
model?: WorkflowModelValue;
|
|
148
148
|
/** Per-stage MCP server gating. No-op when no WorkflowMcpPort is configured. */
|
|
149
149
|
mcp?: StageMcpOptions;
|
|
150
|
+
/** Reusable Git worktree root. Defaults this stage cwd to the corresponding worktree cwd unless cwd is explicitly provided. */
|
|
151
|
+
gitWorktreeDir?: string;
|
|
152
|
+
/** Git ref used when creating gitWorktreeDir. Defaults to HEAD. */
|
|
153
|
+
baseBranch?: string;
|
|
150
154
|
/**
|
|
151
155
|
* Override the session log directory for this stage.
|
|
152
156
|
* Converted to a pi SessionManager before createAgentSession() is called.
|
|
@@ -271,8 +275,12 @@ export interface WorkflowSharedTaskDefaults extends StageOptions {
|
|
|
271
275
|
outputMode?: WorkflowOutputMode;
|
|
272
276
|
/** Files the task should read before responding; relative paths resolve via chainDir for chains, otherwise cwd. */
|
|
273
277
|
reads?: readonly string[] | false;
|
|
274
|
-
/** Workflow-owned isolation flag; not forwarded to createAgentSession(). */
|
|
278
|
+
/** Workflow-owned temporary isolation flag; not forwarded to createAgentSession(). */
|
|
275
279
|
worktree?: boolean;
|
|
280
|
+
/** Reusable Git worktree root. Defaults cwd to the corresponding worktree cwd unless cwd is explicitly provided. */
|
|
281
|
+
gitWorktreeDir?: string;
|
|
282
|
+
/** Git ref used when creating gitWorktreeDir. Defaults to HEAD. */
|
|
283
|
+
baseBranch?: string;
|
|
276
284
|
/** Default output truncation limits for steps that do not set one. */
|
|
277
285
|
maxOutput?: WorkflowMaxOutput;
|
|
278
286
|
/** Whether to include debug artifacts such as sessions and worktree diffs. */
|
|
@@ -400,8 +408,12 @@ export interface WorkflowTaskSessionFields {
|
|
|
400
408
|
output?: string | false;
|
|
401
409
|
outputMode?: WorkflowOutputMode;
|
|
402
410
|
reads?: readonly string[] | false;
|
|
403
|
-
/** Workflow-owned isolation flag; not forwarded to createAgentSession(). */
|
|
411
|
+
/** Workflow-owned temporary isolation flag; not forwarded to createAgentSession(). */
|
|
404
412
|
worktree?: boolean;
|
|
413
|
+
/** Reusable Git worktree root. Defaults cwd to the corresponding worktree cwd unless cwd is explicitly provided. */
|
|
414
|
+
gitWorktreeDir?: string;
|
|
415
|
+
/** Git ref used when creating gitWorktreeDir. Defaults to HEAD. */
|
|
416
|
+
baseBranch?: string;
|
|
405
417
|
maxOutput?: WorkflowMaxOutput;
|
|
406
418
|
/** Whether to include debug artifacts such as sessions and worktree diffs. */
|
|
407
419
|
artifacts?: boolean;
|
|
@@ -421,6 +433,8 @@ export interface WorkflowParallelChainStep {
|
|
|
421
433
|
readonly concurrency?: number;
|
|
422
434
|
readonly failFast?: boolean;
|
|
423
435
|
readonly worktree?: boolean;
|
|
436
|
+
readonly gitWorktreeDir?: string;
|
|
437
|
+
readonly baseBranch?: string;
|
|
424
438
|
}
|
|
425
439
|
|
|
426
440
|
export type WorkflowChainStep = WorkflowDirectTaskItem | WorkflowParallelChainStep;
|
|
@@ -438,6 +452,8 @@ export interface WorkflowDirectOptions extends StageOptions {
|
|
|
438
452
|
output?: string | false;
|
|
439
453
|
outputMode?: WorkflowOutputMode;
|
|
440
454
|
worktree?: boolean;
|
|
455
|
+
gitWorktreeDir?: string;
|
|
456
|
+
baseBranch?: string;
|
|
441
457
|
maxOutput?: WorkflowMaxOutput;
|
|
442
458
|
artifacts?: boolean;
|
|
443
459
|
}
|
|
@@ -505,6 +521,8 @@ export interface StageContext {
|
|
|
505
521
|
export interface WorkflowRunContext<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
506
522
|
/** Typed inputs provided by the caller, validated against the input schema. */
|
|
507
523
|
readonly inputs: TInputs;
|
|
524
|
+
/** Invocation working directory for workflow-owned artifacts. Defaults to the host process cwd when omitted. */
|
|
525
|
+
readonly cwd?: string;
|
|
508
526
|
/**
|
|
509
527
|
* Create and register a named stage synchronously. Stage work starts when
|
|
510
528
|
* a stage method such as prompt() or complete() is awaited; the executor
|
|
@@ -571,6 +589,15 @@ export type WorkflowRunFn<TInputs extends Record<string, unknown> = Record<strin
|
|
|
571
589
|
// Compiled workflow definition
|
|
572
590
|
// ---------------------------------------------------------------------------
|
|
573
591
|
|
|
592
|
+
export interface WorkflowWorktreeInputBinding {
|
|
593
|
+
readonly gitWorktreeDir: string;
|
|
594
|
+
readonly baseBranch?: string;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
export interface WorkflowInputBindings {
|
|
598
|
+
readonly worktree?: WorkflowWorktreeInputBinding;
|
|
599
|
+
}
|
|
600
|
+
|
|
574
601
|
export interface WorkflowDefinition<TInputs extends Record<string, unknown> = Record<string, unknown>> {
|
|
575
602
|
/** Sentinel consumed by the registry loader to validate the export. */
|
|
576
603
|
readonly __piWorkflow: true;
|
|
@@ -579,5 +606,7 @@ export interface WorkflowDefinition<TInputs extends Record<string, unknown> = Re
|
|
|
579
606
|
readonly normalizedName: string;
|
|
580
607
|
readonly description: string;
|
|
581
608
|
readonly inputs: Readonly<Record<string, WorkflowInputSchema>>;
|
|
609
|
+
/** Optional input-to-runtime defaults declared by the workflow builder. */
|
|
610
|
+
readonly inputBindings?: WorkflowInputBindings;
|
|
582
611
|
readonly run: WorkflowRunFn<TInputs>;
|
|
583
612
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* cross-ref: v0.x packages/atomic-sdk/src/define-workflow.ts
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type { WorkflowDefinition, WorkflowInputSchema, WorkflowRunFn } from "../shared/types.js";
|
|
11
|
+
import type { WorkflowDefinition, WorkflowInputBindings, WorkflowInputSchema, WorkflowRunFn, WorkflowWorktreeInputBinding } from "../shared/types.js";
|
|
12
12
|
import { normalizeWorkflowName } from "./identity.js";
|
|
13
13
|
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
@@ -19,6 +19,7 @@ interface BuilderState<TInputs extends Record<string, unknown>> {
|
|
|
19
19
|
readonly name: string;
|
|
20
20
|
readonly description: string;
|
|
21
21
|
readonly inputs: Readonly<Record<string, WorkflowInputSchema>>;
|
|
22
|
+
readonly inputBindings: WorkflowInputBindings;
|
|
22
23
|
readonly runFn: WorkflowRunFn<TInputs> | undefined;
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -45,6 +46,8 @@ export interface WorkflowBuilder<TInputs extends Record<string, unknown> = Recor
|
|
|
45
46
|
key: K,
|
|
46
47
|
schema: WorkflowInputSchema,
|
|
47
48
|
): WorkflowBuilder<TInputs & Record<K, unknown>>;
|
|
49
|
+
/** Bind workflow inputs to reusable git worktree runtime defaults. */
|
|
50
|
+
worktreeFromInputs(binding: WorkflowWorktreeInputBinding): WorkflowBuilder<TInputs>;
|
|
48
51
|
/** Seal the run function. Returns a builder on which .compile() is available. */
|
|
49
52
|
run(fn: WorkflowRunFn<TInputs>): CompletedWorkflowBuilder<TInputs>;
|
|
50
53
|
}
|
|
@@ -59,6 +62,7 @@ export interface CompletedWorkflowBuilder<TInputs extends Record<string, unknown
|
|
|
59
62
|
key: K,
|
|
60
63
|
schema: WorkflowInputSchema,
|
|
61
64
|
): CompletedWorkflowBuilder<TInputs & Record<K, unknown>>;
|
|
65
|
+
worktreeFromInputs(binding: WorkflowWorktreeInputBinding): CompletedWorkflowBuilder<TInputs>;
|
|
62
66
|
run(fn: WorkflowRunFn<TInputs>): CompletedWorkflowBuilder<TInputs>;
|
|
63
67
|
/** Freeze and return the completed WorkflowDefinition. */
|
|
64
68
|
compile(): WorkflowDefinition<TInputs>;
|
|
@@ -83,6 +87,16 @@ function makeBuilder<TInputs extends Record<string, unknown>>(
|
|
|
83
87
|
} as BuilderState<TInputs & Record<K, unknown>>);
|
|
84
88
|
},
|
|
85
89
|
|
|
90
|
+
worktreeFromInputs(binding: WorkflowWorktreeInputBinding) {
|
|
91
|
+
return makeBuilder<TInputs>({
|
|
92
|
+
...state,
|
|
93
|
+
inputBindings: {
|
|
94
|
+
...state.inputBindings,
|
|
95
|
+
worktree: { ...binding },
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
|
|
86
100
|
run(fn: WorkflowRunFn<TInputs>) {
|
|
87
101
|
return makeBuilder<TInputs>({ ...state, runFn: fn });
|
|
88
102
|
},
|
|
@@ -98,6 +112,7 @@ function makeBuilder<TInputs extends Record<string, unknown>>(
|
|
|
98
112
|
|
|
99
113
|
// Deep-freeze inputs map first, then the top-level definition.
|
|
100
114
|
const frozenInputs = Object.freeze({ ...state.inputs });
|
|
115
|
+
const inputBindings = Object.freeze({ ...state.inputBindings });
|
|
101
116
|
|
|
102
117
|
const definition: WorkflowDefinition<TInputs> = {
|
|
103
118
|
__piWorkflow: true,
|
|
@@ -105,6 +120,7 @@ function makeBuilder<TInputs extends Record<string, unknown>>(
|
|
|
105
120
|
normalizedName,
|
|
106
121
|
description: state.description,
|
|
107
122
|
inputs: frozenInputs,
|
|
123
|
+
...(Object.keys(inputBindings).length > 0 ? { inputBindings } : {}),
|
|
108
124
|
run: state.runFn,
|
|
109
125
|
};
|
|
110
126
|
|
|
@@ -143,6 +159,7 @@ export function defineWorkflow(name: string): WorkflowBuilder {
|
|
|
143
159
|
name,
|
|
144
160
|
description: "",
|
|
145
161
|
inputs: {},
|
|
162
|
+
inputBindings: {},
|
|
146
163
|
runFn: undefined,
|
|
147
164
|
};
|
|
148
165
|
|
|
@@ -50,7 +50,8 @@ export interface CreateAgentSessionFromServicesOptions {
|
|
|
50
50
|
model: Model<Api>;
|
|
51
51
|
thinkingLevel?: ThinkingLevel;
|
|
52
52
|
}>;
|
|
53
|
-
tools?:
|
|
53
|
+
tools?: CreateAgentSessionOptions["tools"];
|
|
54
|
+
excludeTools?: CreateAgentSessionOptions["excludeTools"];
|
|
54
55
|
noTools?: CreateAgentSessionOptions["noTools"];
|
|
55
56
|
customTools?: ToolDefinition[];
|
|
56
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-services.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAyB,KAAK,4BAA4B,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrH,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,wBAAwB,EAAsB,MAAM,UAAU,CAAC;AAC7G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC7C,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iCAAiC;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IACpD,qBAAqB,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,KAAK,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC;CACnG;AAED;;;;;GAKG;AACH,MAAM,WAAW,qCAAqC;IACrD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC3E,KAAK,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"agent-session-services.d.ts","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAyB,KAAK,4BAA4B,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrH,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,wBAAwB,EAAsB,MAAM,UAAU,CAAC;AAC7G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,6BAA6B;IAC7C,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iCAAiC;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC;IACpD,qBAAqB,CAAC,EAAE,IAAI,CAAC,4BAA4B,EAAE,KAAK,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC;CACnG;AAED;;;;;GAKG;AACH,MAAM,WAAW,qCAAqC;IACrD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,aAAa,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC3E,KAAK,CAAC,EAAE,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,yBAAyB,CAAC,cAAc,CAAC,CAAC;IACzD,OAAO,CAAC,EAAE,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC/C,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,6BAA6B,EAAE,CAAC;CAC7C;AAkDD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC/C,OAAO,EAAE,iCAAiC,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAuC/B;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CACnD,OAAO,EAAE,qCAAqC,GAC5C,OAAO,CAAC,wBAAwB,CAAC,CAkBnC","sourcesContent":["import { join } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport type { SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { DefaultResourceLoader, type DefaultResourceLoaderOptions, type ResourceLoader } from \"./resource-loader.ts\";\nimport { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession } from \"./sdk.ts\";\nimport type { SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\n/**\n * Non-fatal issues collected while creating services or sessions.\n *\n * Runtime creation returns diagnostics to the caller instead of printing or\n * exiting. The app layer decides whether warnings should be shown and whether\n * errors should abort startup.\n */\nexport interface AgentSessionRuntimeDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\n/**\n * Inputs for creating cwd-bound runtime services.\n *\n * These services are recreated whenever the effective session cwd changes.\n * CLI-provided resource paths should be resolved to absolute paths before they\n * reach this function, so later cwd switches do not reinterpret them.\n */\nexport interface CreateAgentSessionServicesOptions {\n\tcwd: string;\n\tagentDir?: string;\n\tauthStorage?: AuthStorage;\n\tsettingsManager?: SettingsManager;\n\tmodelRegistry?: ModelRegistry;\n\textensionFlagValues?: Map<string, boolean | string>;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n}\n\n/**\n * Inputs for creating an AgentSession from already-created services.\n *\n * Use this after services exist and any cwd-bound model/tool/session options\n * have been resolved against those services.\n */\nexport interface CreateAgentSessionFromServicesOptions {\n\tservices: AgentSessionServices;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n\tmodel?: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: CreateAgentSessionOptions[\"tools\"];\n\texcludeTools?: CreateAgentSessionOptions[\"excludeTools\"];\n\tnoTools?: CreateAgentSessionOptions[\"noTools\"];\n\tcustomTools?: ToolDefinition[];\n}\n\n/**\n * Coherent cwd-bound runtime services for one effective session cwd.\n *\n * This is infrastructure only. The AgentSession itself is created separately so\n * session options can be resolved against these services first.\n */\nexport interface AgentSessionServices {\n\tcwd: string;\n\tagentDir: string;\n\tauthStorage: AuthStorage;\n\tsettingsManager: SettingsManager;\n\tmodelRegistry: ModelRegistry;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\nfunction applyExtensionFlagValues(\n\tresourceLoader: ResourceLoader,\n\textensionFlagValues: Map<string, boolean | string> | undefined,\n): AgentSessionRuntimeDiagnostic[] {\n\tif (!extensionFlagValues) {\n\t\treturn [];\n\t}\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tconst registeredFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const extension of extensionsResult.extensions) {\n\t\tfor (const [name, flag] of extension.flags) {\n\t\t\tregisteredFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\tconst unknownFlags: string[] = [];\n\tfor (const [name, value] of extensionFlagValues) {\n\t\tconst flag = registeredFlags.get(name);\n\t\tif (!flag) {\n\t\t\tunknownFlags.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (flag.type === \"boolean\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === \"string\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Extension flag \"--${name}\" requires a value`,\n\t\t});\n\t}\n\n\tif (unknownFlags.length > 0) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Unknown option${unknownFlags.length === 1 ? \"\" : \"s\"}: ${unknownFlags.map((name) => `--${name}`).join(\", \")}`,\n\t\t});\n\t}\n\n\treturn diagnostics;\n}\n\n/**\n * Create cwd-bound runtime services.\n *\n * Returns services plus diagnostics. It does not create an AgentSession.\n */\nexport async function createAgentSessionServices(\n\toptions: CreateAgentSessionServicesOptions,\n): Promise<AgentSessionServices> {\n\tconst cwd = resolvePath(options.cwd);\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getAgentDir();\n\tconst authStorage = options.authStorage ?? AuthStorage.create(join(agentDir, \"auth.json\"));\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, join(agentDir, \"models.json\"));\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\t...(options.resourceLoaderOptions ?? {}),\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t});\n\tawait resourceLoader.reload();\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tfor (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {\n\t\ttry {\n\t\t\tmodelRegistry.registerProvider(name, config);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: `Extension \"${extensionPath}\" error: ${message}`,\n\t\t\t});\n\t\t}\n\t}\n\textensionsResult.runtime.pendingProviderRegistrations = [];\n\tdiagnostics.push(...applyExtensionFlagValues(resourceLoader, options.extensionFlagValues));\n\n\treturn {\n\t\tcwd,\n\t\tagentDir,\n\t\tauthStorage,\n\t\tsettingsManager,\n\t\tmodelRegistry,\n\t\tresourceLoader,\n\t\tdiagnostics,\n\t};\n}\n\n/**\n * Create an AgentSession from previously created services.\n *\n * This keeps session creation separate from service creation so callers can\n * resolve model, thinking, tools, and other session inputs against the target\n * cwd before constructing the session.\n */\nexport async function createAgentSessionFromServices(\n\toptions: CreateAgentSessionFromServicesOptions,\n): Promise<CreateAgentSessionResult> {\n\treturn createAgentSession({\n\t\tcwd: options.services.cwd,\n\t\tagentDir: options.services.agentDir,\n\t\tauthStorage: options.services.authStorage,\n\t\tsettingsManager: options.services.settingsManager,\n\t\tmodelRegistry: options.services.modelRegistry,\n\t\tresourceLoader: options.services.resourceLoader,\n\t\tsessionManager: options.sessionManager,\n\t\tmodel: options.model,\n\t\tthinkingLevel: options.thinkingLevel,\n\t\tscopedModels: options.scopedModels,\n\t\ttools: options.tools,\n\t\texcludeTools: options.excludeTools,\n\t\tnoTools: options.noTools,\n\t\tcustomTools: options.customTools,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n}\n"]}
|
|
@@ -110,6 +110,7 @@ export async function createAgentSessionFromServices(options) {
|
|
|
110
110
|
thinkingLevel: options.thinkingLevel,
|
|
111
111
|
scopedModels: options.scopedModels,
|
|
112
112
|
tools: options.tools,
|
|
113
|
+
excludeTools: options.excludeTools,
|
|
113
114
|
noTools: options.noTools,
|
|
114
115
|
customTools: options.customTools,
|
|
115
116
|
sessionStartEvent: options.sessionStartEvent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-session-services.js","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport type { SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { DefaultResourceLoader, type DefaultResourceLoaderOptions, type ResourceLoader } from \"./resource-loader.ts\";\nimport { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession } from \"./sdk.ts\";\nimport type { SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\n/**\n * Non-fatal issues collected while creating services or sessions.\n *\n * Runtime creation returns diagnostics to the caller instead of printing or\n * exiting. The app layer decides whether warnings should be shown and whether\n * errors should abort startup.\n */\nexport interface AgentSessionRuntimeDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\n/**\n * Inputs for creating cwd-bound runtime services.\n *\n * These services are recreated whenever the effective session cwd changes.\n * CLI-provided resource paths should be resolved to absolute paths before they\n * reach this function, so later cwd switches do not reinterpret them.\n */\nexport interface CreateAgentSessionServicesOptions {\n\tcwd: string;\n\tagentDir?: string;\n\tauthStorage?: AuthStorage;\n\tsettingsManager?: SettingsManager;\n\tmodelRegistry?: ModelRegistry;\n\textensionFlagValues?: Map<string, boolean | string>;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n}\n\n/**\n * Inputs for creating an AgentSession from already-created services.\n *\n * Use this after services exist and any cwd-bound model/tool/session options\n * have been resolved against those services.\n */\nexport interface CreateAgentSessionFromServicesOptions {\n\tservices: AgentSessionServices;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n\tmodel?: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: string[];\n\tnoTools?: CreateAgentSessionOptions[\"noTools\"];\n\tcustomTools?: ToolDefinition[];\n}\n\n/**\n * Coherent cwd-bound runtime services for one effective session cwd.\n *\n * This is infrastructure only. The AgentSession itself is created separately so\n * session options can be resolved against these services first.\n */\nexport interface AgentSessionServices {\n\tcwd: string;\n\tagentDir: string;\n\tauthStorage: AuthStorage;\n\tsettingsManager: SettingsManager;\n\tmodelRegistry: ModelRegistry;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\nfunction applyExtensionFlagValues(\n\tresourceLoader: ResourceLoader,\n\textensionFlagValues: Map<string, boolean | string> | undefined,\n): AgentSessionRuntimeDiagnostic[] {\n\tif (!extensionFlagValues) {\n\t\treturn [];\n\t}\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tconst registeredFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const extension of extensionsResult.extensions) {\n\t\tfor (const [name, flag] of extension.flags) {\n\t\t\tregisteredFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\tconst unknownFlags: string[] = [];\n\tfor (const [name, value] of extensionFlagValues) {\n\t\tconst flag = registeredFlags.get(name);\n\t\tif (!flag) {\n\t\t\tunknownFlags.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (flag.type === \"boolean\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === \"string\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Extension flag \"--${name}\" requires a value`,\n\t\t});\n\t}\n\n\tif (unknownFlags.length > 0) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Unknown option${unknownFlags.length === 1 ? \"\" : \"s\"}: ${unknownFlags.map((name) => `--${name}`).join(\", \")}`,\n\t\t});\n\t}\n\n\treturn diagnostics;\n}\n\n/**\n * Create cwd-bound runtime services.\n *\n * Returns services plus diagnostics. It does not create an AgentSession.\n */\nexport async function createAgentSessionServices(\n\toptions: CreateAgentSessionServicesOptions,\n): Promise<AgentSessionServices> {\n\tconst cwd = resolvePath(options.cwd);\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getAgentDir();\n\tconst authStorage = options.authStorage ?? AuthStorage.create(join(agentDir, \"auth.json\"));\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, join(agentDir, \"models.json\"));\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\t...(options.resourceLoaderOptions ?? {}),\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t});\n\tawait resourceLoader.reload();\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tfor (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {\n\t\ttry {\n\t\t\tmodelRegistry.registerProvider(name, config);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: `Extension \"${extensionPath}\" error: ${message}`,\n\t\t\t});\n\t\t}\n\t}\n\textensionsResult.runtime.pendingProviderRegistrations = [];\n\tdiagnostics.push(...applyExtensionFlagValues(resourceLoader, options.extensionFlagValues));\n\n\treturn {\n\t\tcwd,\n\t\tagentDir,\n\t\tauthStorage,\n\t\tsettingsManager,\n\t\tmodelRegistry,\n\t\tresourceLoader,\n\t\tdiagnostics,\n\t};\n}\n\n/**\n * Create an AgentSession from previously created services.\n *\n * This keeps session creation separate from service creation so callers can\n * resolve model, thinking, tools, and other session inputs against the target\n * cwd before constructing the session.\n */\nexport async function createAgentSessionFromServices(\n\toptions: CreateAgentSessionFromServicesOptions,\n): Promise<CreateAgentSessionResult> {\n\treturn createAgentSession({\n\t\tcwd: options.services.cwd,\n\t\tagentDir: options.services.agentDir,\n\t\tauthStorage: options.services.authStorage,\n\t\tsettingsManager: options.services.settingsManager,\n\t\tmodelRegistry: options.services.modelRegistry,\n\t\tresourceLoader: options.services.resourceLoader,\n\t\tsessionManager: options.sessionManager,\n\t\tmodel: options.model,\n\t\tthinkingLevel: options.thinkingLevel,\n\t\tscopedModels: options.scopedModels,\n\t\ttools: options.tools,\n\t\tnoTools: options.noTools,\n\t\tcustomTools: options.customTools,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-session-services.js","sourceRoot":"","sources":["../../src/core/agent-session-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport type { SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { DefaultResourceLoader, type DefaultResourceLoaderOptions, type ResourceLoader } from \"./resource-loader.ts\";\nimport { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession } from \"./sdk.ts\";\nimport type { SessionManager } from \"./session-manager.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\n\n/**\n * Non-fatal issues collected while creating services or sessions.\n *\n * Runtime creation returns diagnostics to the caller instead of printing or\n * exiting. The app layer decides whether warnings should be shown and whether\n * errors should abort startup.\n */\nexport interface AgentSessionRuntimeDiagnostic {\n\ttype: \"info\" | \"warning\" | \"error\";\n\tmessage: string;\n}\n\n/**\n * Inputs for creating cwd-bound runtime services.\n *\n * These services are recreated whenever the effective session cwd changes.\n * CLI-provided resource paths should be resolved to absolute paths before they\n * reach this function, so later cwd switches do not reinterpret them.\n */\nexport interface CreateAgentSessionServicesOptions {\n\tcwd: string;\n\tagentDir?: string;\n\tauthStorage?: AuthStorage;\n\tsettingsManager?: SettingsManager;\n\tmodelRegistry?: ModelRegistry;\n\textensionFlagValues?: Map<string, boolean | string>;\n\tresourceLoaderOptions?: Omit<DefaultResourceLoaderOptions, \"cwd\" | \"agentDir\" | \"settingsManager\">;\n}\n\n/**\n * Inputs for creating an AgentSession from already-created services.\n *\n * Use this after services exist and any cwd-bound model/tool/session options\n * have been resolved against those services.\n */\nexport interface CreateAgentSessionFromServicesOptions {\n\tservices: AgentSessionServices;\n\tsessionManager: SessionManager;\n\tsessionStartEvent?: SessionStartEvent;\n\tmodel?: Model<Api>;\n\tthinkingLevel?: ThinkingLevel;\n\tscopedModels?: Array<{ model: Model<Api>; thinkingLevel?: ThinkingLevel }>;\n\ttools?: CreateAgentSessionOptions[\"tools\"];\n\texcludeTools?: CreateAgentSessionOptions[\"excludeTools\"];\n\tnoTools?: CreateAgentSessionOptions[\"noTools\"];\n\tcustomTools?: ToolDefinition[];\n}\n\n/**\n * Coherent cwd-bound runtime services for one effective session cwd.\n *\n * This is infrastructure only. The AgentSession itself is created separately so\n * session options can be resolved against these services first.\n */\nexport interface AgentSessionServices {\n\tcwd: string;\n\tagentDir: string;\n\tauthStorage: AuthStorage;\n\tsettingsManager: SettingsManager;\n\tmodelRegistry: ModelRegistry;\n\tresourceLoader: ResourceLoader;\n\tdiagnostics: AgentSessionRuntimeDiagnostic[];\n}\n\nfunction applyExtensionFlagValues(\n\tresourceLoader: ResourceLoader,\n\textensionFlagValues: Map<string, boolean | string> | undefined,\n): AgentSessionRuntimeDiagnostic[] {\n\tif (!extensionFlagValues) {\n\t\treturn [];\n\t}\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tconst registeredFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const extension of extensionsResult.extensions) {\n\t\tfor (const [name, flag] of extension.flags) {\n\t\t\tregisteredFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\tconst unknownFlags: string[] = [];\n\tfor (const [name, value] of extensionFlagValues) {\n\t\tconst flag = registeredFlags.get(name);\n\t\tif (!flag) {\n\t\t\tunknownFlags.push(name);\n\t\t\tcontinue;\n\t\t}\n\t\tif (flag.type === \"boolean\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, true);\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === \"string\") {\n\t\t\textensionsResult.runtime.flagValues.set(name, value);\n\t\t\tcontinue;\n\t\t}\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Extension flag \"--${name}\" requires a value`,\n\t\t});\n\t}\n\n\tif (unknownFlags.length > 0) {\n\t\tdiagnostics.push({\n\t\t\ttype: \"error\",\n\t\t\tmessage: `Unknown option${unknownFlags.length === 1 ? \"\" : \"s\"}: ${unknownFlags.map((name) => `--${name}`).join(\", \")}`,\n\t\t});\n\t}\n\n\treturn diagnostics;\n}\n\n/**\n * Create cwd-bound runtime services.\n *\n * Returns services plus diagnostics. It does not create an AgentSession.\n */\nexport async function createAgentSessionServices(\n\toptions: CreateAgentSessionServicesOptions,\n): Promise<AgentSessionServices> {\n\tconst cwd = resolvePath(options.cwd);\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getAgentDir();\n\tconst authStorage = options.authStorage ?? AuthStorage.create(join(agentDir, \"auth.json\"));\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, join(agentDir, \"models.json\"));\n\tconst resourceLoader = new DefaultResourceLoader({\n\t\t...(options.resourceLoaderOptions ?? {}),\n\t\tcwd,\n\t\tagentDir,\n\t\tsettingsManager,\n\t});\n\tawait resourceLoader.reload();\n\n\tconst diagnostics: AgentSessionRuntimeDiagnostic[] = [];\n\tconst extensionsResult = resourceLoader.getExtensions();\n\tfor (const { name, config, extensionPath } of extensionsResult.runtime.pendingProviderRegistrations) {\n\t\ttry {\n\t\t\tmodelRegistry.registerProvider(name, config);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tdiagnostics.push({\n\t\t\t\ttype: \"error\",\n\t\t\t\tmessage: `Extension \"${extensionPath}\" error: ${message}`,\n\t\t\t});\n\t\t}\n\t}\n\textensionsResult.runtime.pendingProviderRegistrations = [];\n\tdiagnostics.push(...applyExtensionFlagValues(resourceLoader, options.extensionFlagValues));\n\n\treturn {\n\t\tcwd,\n\t\tagentDir,\n\t\tauthStorage,\n\t\tsettingsManager,\n\t\tmodelRegistry,\n\t\tresourceLoader,\n\t\tdiagnostics,\n\t};\n}\n\n/**\n * Create an AgentSession from previously created services.\n *\n * This keeps session creation separate from service creation so callers can\n * resolve model, thinking, tools, and other session inputs against the target\n * cwd before constructing the session.\n */\nexport async function createAgentSessionFromServices(\n\toptions: CreateAgentSessionFromServicesOptions,\n): Promise<CreateAgentSessionResult> {\n\treturn createAgentSession({\n\t\tcwd: options.services.cwd,\n\t\tagentDir: options.services.agentDir,\n\t\tauthStorage: options.services.authStorage,\n\t\tsettingsManager: options.services.settingsManager,\n\t\tmodelRegistry: options.services.modelRegistry,\n\t\tresourceLoader: options.services.resourceLoader,\n\t\tsessionManager: options.sessionManager,\n\t\tmodel: options.model,\n\t\tthinkingLevel: options.thinkingLevel,\n\t\tscopedModels: options.scopedModels,\n\t\ttools: options.tools,\n\t\texcludeTools: options.excludeTools,\n\t\tnoTools: options.noTools,\n\t\tcustomTools: options.customTools,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t});\n}\n"]}
|
|
@@ -96,6 +96,8 @@ export interface AgentSessionConfig {
|
|
|
96
96
|
initialActiveToolNames?: string[];
|
|
97
97
|
/** Optional allowlist of tool names. When provided, only these tool names are exposed. */
|
|
98
98
|
allowedToolNames?: string[];
|
|
99
|
+
/** Optional blocklist of tool names. Matching names are omitted from the final exposed registry. */
|
|
100
|
+
excludedToolNames?: string[];
|
|
99
101
|
/**
|
|
100
102
|
* Override base tools (useful for custom runtimes).
|
|
101
103
|
*
|
|
@@ -188,6 +190,7 @@ export declare class AgentSession {
|
|
|
188
190
|
private _extensionRunnerRef?;
|
|
189
191
|
private _initialActiveToolNames?;
|
|
190
192
|
private _allowedToolNames?;
|
|
193
|
+
private _excludedToolNames?;
|
|
191
194
|
private _baseToolsOverride?;
|
|
192
195
|
private _sessionStartEvent;
|
|
193
196
|
private _extensionUIContext?;
|