@marcoscale98/pi-extensible-workflows 5.14.1-fork.1 → 5.19.1-fork.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/dist/src/agent-execution.js +114 -87
  3. package/dist/src/background-widget.d.ts +61 -0
  4. package/dist/src/background-widget.js +23 -16
  5. package/dist/src/decoders.js +28 -1
  6. package/dist/src/execution.d.ts +4 -2
  7. package/dist/src/execution.js +43 -2
  8. package/dist/src/host-delivery.js +1 -0
  9. package/dist/src/host-navigator.d.ts +18 -0
  10. package/dist/src/host-navigator.js +71 -13
  11. package/dist/src/host-recovery.d.ts +5 -2
  12. package/dist/src/host-recovery.js +3 -3
  13. package/dist/src/host-view.d.ts +21 -1
  14. package/dist/src/host-view.js +138 -47
  15. package/dist/src/host.d.ts +2 -2
  16. package/dist/src/host.js +246 -60
  17. package/dist/src/index.d.ts +3 -1
  18. package/dist/src/index.js +1346 -622
  19. package/dist/src/index.js.map +3 -3
  20. package/dist/src/paths.d.ts +2 -0
  21. package/dist/src/paths.js +2 -0
  22. package/dist/src/registry.js +3 -2
  23. package/dist/src/roles.d.ts +70 -0
  24. package/dist/src/roles.js +326 -0
  25. package/dist/src/script-tools.d.ts +27 -0
  26. package/dist/src/script-tools.js +87 -0
  27. package/dist/src/settings.d.ts +26 -0
  28. package/dist/src/settings.js +277 -0
  29. package/dist/src/trajectory.d.ts +39 -4
  30. package/dist/src/trajectory.js +82 -5
  31. package/dist/src/types.d.ts +30 -3
  32. package/dist/src/types.js +1 -1
  33. package/dist/src/utils.d.ts +21 -1
  34. package/dist/src/utils.js +40 -0
  35. package/dist/src/validation.d.ts +10 -17
  36. package/dist/src/validation.js +29 -458
  37. package/dist/starter/index.js +0 -2
  38. package/dist/starter/index.js.map +1 -1
  39. package/dist/starter/review-loop.d.ts +0 -13
  40. package/dist/starter/review-loop.js +0 -2
  41. package/dist/subagents/index.js +1344 -798
  42. package/dist/subagents/index.js.map +3 -3
  43. package/dist/subagents/src/contracts.d.ts +49 -29
  44. package/dist/subagents/src/contracts.js +18 -7
  45. package/dist/subagents/src/index.d.ts +1 -1
  46. package/dist/subagents/src/index.js +15 -7
  47. package/dist/subagents/src/manager.js +32 -13
  48. package/dist/subagents/src/navigator.js +396 -247
  49. package/dist/subagents/src/view.d.ts +24 -2
  50. package/dist/subagents/src/view.js +107 -80
  51. package/dist/trajectory/assets/index.html +370 -232
  52. package/dist/trajectory/assets/prism.min.js +13 -0
  53. package/dist/trajectory/index.js +445 -277
  54. package/dist/trajectory/index.js.map +3 -3
  55. package/dist/trajectory/src/assets/index.html +370 -232
  56. package/dist/trajectory/src/assets/prism.min.js +13 -0
  57. package/dist/trajectory/src/export.js +4 -2
  58. package/dist/trajectory/src/index.d.ts +2 -0
  59. package/dist/trajectory/src/index.js +151 -60
  60. package/dist/trajectory/src/server.js +138 -11
  61. package/dist/trajectory/src/server.js.map +2 -2
  62. package/package.json +7 -6
  63. package/skills/pi-extensible-workflows/SKILL.md +2 -0
  64. package/src/agent-execution.ts +110 -80
  65. package/src/background-widget.ts +26 -19
  66. package/src/decoders.ts +22 -1
  67. package/src/execution.ts +41 -4
  68. package/src/host-delivery.ts +1 -0
  69. package/src/host-navigator.ts +58 -14
  70. package/src/host-recovery.ts +8 -7
  71. package/src/host-view.ts +116 -42
  72. package/src/host.ts +223 -55
  73. package/src/index.ts +3 -1
  74. package/src/paths.ts +3 -0
  75. package/src/registry.ts +3 -2
  76. package/src/roles.ts +327 -0
  77. package/src/script-tools.ts +76 -0
  78. package/src/settings.ts +224 -0
  79. package/src/trajectory.ts +97 -9
  80. package/src/types.ts +12 -5
  81. package/src/utils.ts +36 -1
  82. package/src/validation.ts +30 -356
  83. package/starter/review-loop.ts +0 -2
  84. package/subagents/README.md +3 -3
  85. package/subagents/src/contracts.ts +22 -7
  86. package/subagents/src/index.ts +18 -7
  87. package/subagents/src/manager.ts +31 -13
  88. package/subagents/src/navigator.ts +336 -180
  89. package/subagents/src/view.ts +108 -76
  90. package/trajectory/src/assets/index.html +370 -232
  91. package/trajectory/src/assets/prism.min.js +13 -0
  92. package/trajectory/src/export.ts +4 -2
  93. package/trajectory/src/index.ts +124 -47
  94. package/trajectory/src/server.ts +114 -14
package/dist/src/utils.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { ERROR_CODES, LAUNCH_SNAPSHOT_IDENTITY_VERSION, THINKING_LEVELS, WorkflowError } from "./types.js";
2
3
  import { Minimatch } from "minimatch";
3
4
  export class SerialLane {
@@ -17,6 +18,17 @@ export function sanitizeDisplayText(value) { return value.replace(ANSI_ESCAPE_SE
17
18
  export { object as isObject };
18
19
  function isStringKey(key) { return typeof key === "string"; }
19
20
  function stringKeyValue(value, key) { return object(value) ? value[key] : undefined; }
21
+ function sortedJson(value) {
22
+ if (Array.isArray(value))
23
+ return value.map(sortedJson);
24
+ if (value === null || typeof value !== "object")
25
+ return value;
26
+ return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortedJson(value[key])]));
27
+ }
28
+ /** A short digest of a JSON value that ignores object key order. */
29
+ export function jsonDigest(value) {
30
+ return createHash("sha256").update(JSON.stringify(sortedJson(value))).digest("hex").slice(0, 16);
31
+ }
20
32
  export function jsonValue(value, seen = new Set()) {
21
33
  if (value === null || typeof value === "boolean" || typeof value === "string")
22
34
  return true;
@@ -178,6 +190,24 @@ export function resolveModelReference(value, aliases = {}, knownModels, settings
178
190
  };
179
191
  return resolveReference(value, []);
180
192
  }
193
+ /**
194
+ * Tools a session can reach, and so the ceiling for its agents: the declared tools plus the ones
195
+ * only codemode scripts call or tool_search loads, such as MCP tools with the default exposure.
196
+ * Agent sessions allow tools by name, so leaving these out would make them unreachable there.
197
+ */
198
+ export function reachableTools(pi) {
199
+ const undeclared = pi.getAllTools?.().filter(({ exposure }) => exposure === "codemode" || exposure === "deferred").map(({ name }) => name) ?? [];
200
+ return [...new Set([...pi.getActiveTools(), ...undeclared])];
201
+ }
202
+ /** Provider of the virtual models that expose workflow model aliases in `/model`. */
203
+ export const VIRTUAL_MODEL_PROVIDER = "workflow";
204
+ /** Child sessions do not load the workflow extension, so they receive the alias target instead of its virtual model. */
205
+ export function physicalModel(spec, aliases = {}, knownModels, settingsPath) {
206
+ if (spec.provider !== VIRTUAL_MODEL_PROVIDER || !modelAliasName(spec.model, aliases))
207
+ return spec;
208
+ const target = resolveModelReference(spec.model, aliases, knownModels, settingsPath);
209
+ return spec.thinking === undefined ? target : { ...target, thinking: spec.thinking };
210
+ }
181
211
  export function modelCapability(value, aliases, knownModels, settingsPath) {
182
212
  const parsed = typeof value === "string" ? resolveModelReference(value, aliases, knownModels, settingsPath) : value;
183
213
  return `${parsed.provider}/${parsed.model}`;
@@ -223,3 +253,13 @@ export function resourcePatternHasMagic(pattern) { return /[*?\x5b\x5d{}()]/.tes
223
253
  export function unmatchedResourcePatterns(patterns, resources) { return patterns.filter((pattern) => !resources.some((resource) => resourcePatternMatches(resource, pattern))); }
224
254
  export function createLaunchSnapshot(input) { return deepFreeze(structuredClone({ ...input, identityVersion: input.identityVersion ?? LAUNCH_SNAPSHOT_IDENTITY_VERSION })); }
225
255
  export function loadLaunchSnapshot(input) { return deepFreeze(structuredClone(input)); }
256
+ export function validateSchema(schema, at = "schema") {
257
+ if (!object(schema) || Object.getPrototypeOf(schema) !== Object.prototype || !jsonValue(schema))
258
+ fail("INVALID_SCHEMA", `${at} must be a plain JSON-compatible Schema object`);
259
+ if (typeof schema.type !== "string" && !Array.isArray(schema.type) && schema.$ref === undefined && schema.anyOf === undefined && schema.oneOf === undefined && schema.allOf === undefined && schema.const === undefined && schema.enum === undefined)
260
+ fail("INVALID_SCHEMA", `${at} has no JSON Schema shape`);
261
+ if (schema.required !== undefined && (!Array.isArray(schema.required) || schema.required.some((key) => typeof key !== "string")))
262
+ fail("INVALID_SCHEMA", `${at}.required must be an array of strings`);
263
+ if (schema.properties !== undefined && !object(schema.properties))
264
+ fail("INVALID_SCHEMA", `${at}.properties must be an object`);
265
+ }
@@ -1,24 +1,17 @@
1
- import type { AgentDefinition, AgentResourcePolicy, CheckpointInput, JsonSchema, JsonValue, PreflightCapabilities, PreflightResult, ShellOptions, StaticWorkflowCall, ValidatedWorkflowLaunch, WorkflowExtensionSettings, WorkflowMetadata, WorkflowRoleDirectoryRegistration, WorkflowSettings, WorkflowSettingsOverrides, WorkflowSettingsResolution, WorkflowValidationContext, WorkflowValidationParameters } from "./types.js";
1
+ import type { CheckpointInput, JsonValue, PreflightCapabilities, PreflightResult, ShellOptions, StaticWorkflowCall, ValidatedWorkflowLaunch, WorkflowMetadata, WorkflowValidationContext, WorkflowValidationParameters } from "./types.js";
2
2
  import type { WorkflowRegistryApi } from "./registry.js";
3
- export { workflowProjectSettingsPath } from "./paths.js";
4
- export declare const DEFAULT_SETTINGS: Readonly<WorkflowSettings>;
3
+ export { validateSchema } from "./utils.js";
4
+ export { loadAgentDefinitions, loadProjectAgentDefinitions, parseRoleMarkdown, workflowRoleDirectories } from "./roles.js";
5
+ export type { WorkflowRoleDirectoryInput } from "./roles.js";
6
+ export { DEFAULT_SETTINGS, loadCodemodeToolsSetting, loadSettings, loadSettingsOverrides, resolveAgentResourcePolicy, resolveWorkflowSettings, saveModelAliases, validateContextFileScopes, validateModelAliasAvailability, validateSelectorList, validateWorkflowExtensionSettings, workflowProjectSettingsPath, workflowSettingsPath, workflowToolExposure } from "./settings.js";
5
7
  export declare function validateCheckpoint(value: unknown): CheckpointInput;
6
- export declare function workflowSettingsPath(agentDir?: string): string;
7
- export declare function validateWorkflowExtensionSettings(value: unknown, settingsPath: string, errorCode?: "INVALID_SETTINGS" | "INVALID_METADATA", applyDefaults?: boolean): WorkflowExtensionSettings | undefined;
8
- export declare function loadSettings(path?: string): Readonly<WorkflowSettings>;
9
- export declare function loadSettingsOverrides(path: string): Readonly<WorkflowSettingsOverrides>;
10
- export declare function resolveWorkflowSettings(cwd: string, projectTrusted: boolean, globalSettingsPath?: string): WorkflowSettingsResolution;
11
- export declare function validateModelAliasAvailability(aliases: Readonly<Record<string, string>>, names: readonly string[], availableModels: ReadonlySet<string>, knownModels: ReadonlySet<string>, settingsPath?: string): void;
12
- export declare function resolveAgentResourcePolicy(cwd: string, projectTrusted: boolean, globalSettingsPath?: string): AgentResourcePolicy;
13
- export declare function saveModelAliases(path?: string, aliases?: Readonly<Record<string, string>>): void;
14
- export declare function parseRoleMarkdown(content: string, strict?: boolean, rolePath?: string): AgentDefinition;
15
- export declare function workflowRoleDirectories(agentDir?: string): readonly string[];
16
- export type WorkflowRoleDirectoryInput = string | WorkflowRoleDirectoryRegistration;
17
- export declare function loadProjectAgentDefinitions(cwd: string): Readonly<Record<string, AgentDefinition>>;
18
- export declare function loadAgentDefinitions(cwd: string, agentDir?: string, projectTrusted?: boolean, extensionRoleDirectories?: readonly WorkflowRoleDirectoryInput[]): Readonly<Record<string, AgentDefinition>>;
8
+ /**
9
+ * The `tools.<id>` members a workflow script names statically. Any other use of `tools`, such as a
10
+ * local declaration that shadows the global or passing it around, makes the set unknowable: undefined.
11
+ */
12
+ export declare function scriptToolReferences(script: string): string[] | undefined;
19
13
  export declare function instrumentWorkflow(script: string): string;
20
14
  export declare function workflowPrompt(template: string, values: Readonly<Record<string, JsonValue>>): string;
21
- export declare function validateSchema(schema: unknown, at?: string): asserts schema is JsonSchema;
22
15
  export declare function validateAgentOptions(value: unknown): Readonly<Record<string, JsonValue>>;
23
16
  export declare function validateShellOptions(value: unknown): ShellOptions;
24
17
  export declare function validateShellCommand(value: unknown): string;
@@ -1,17 +1,14 @@
1
- import { atomicWriteFile } from "./persistence.js";
2
- import { mkdirSync, readFileSync, readdirSync, statSync } from "node:fs";
3
- import { homedir } from "node:os";
4
- import { basename, dirname, extname, join, resolve } from "node:path";
5
- import { fileURLToPath } from "node:url";
1
+ import { readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
6
3
  import * as acorn from "acorn";
7
4
  import { Script } from "node:vm";
8
- import { getAgentDir, parseFrontmatter } from "@earendil-works/pi-coding-agent";
9
- import { registeredWorkflowRoleDirectoryRegistrations } from "./registry.js";
10
- import { annotateModelAliasError, assertModelThinking, deepFreeze, errorText, fail, isNodeError, jsonObject, jsonValue, mergeWorkflowExtensionSettings, modelAliasName, modelCapability, object, positiveInteger, resolveModelReference, resourcePatternHasMagic, unknownModel, validateModelAliases, validateResourcePattern, validWorkflowExtensionNamespace } from "./utils.js";
11
- import { WORKFLOW_CALL_KINDS, isContextFileScope } from "./types.js";
12
- import { canonicalPath, workflowProjectSettingsPath } from "./paths.js";
13
- export { workflowProjectSettingsPath } from "./paths.js";
14
- export const DEFAULT_SETTINGS = Object.freeze({ concurrency: 8, backgroundWidget: true });
5
+ import { assertModelThinking, validateSchema, deepFreeze, errorText, fail, jsonObject, jsonValue, mergeWorkflowExtensionSettings, modelAliasName, modelCapability, object, positiveInteger, resolveModelReference, resourcePatternHasMagic, unknownModel } from "./utils.js";
6
+ import { WORKFLOW_CALL_KINDS } from "./types.js";
7
+ export { validateSchema } from "./utils.js";
8
+ import { loadAgentDefinitions, loadProjectAgentDefinitions } from "./roles.js";
9
+ export { loadAgentDefinitions, loadProjectAgentDefinitions, parseRoleMarkdown, workflowRoleDirectories } from "./roles.js";
10
+ import { validateContextFileScopes, validateSelectorList } from "./settings.js";
11
+ export { DEFAULT_SETTINGS, loadCodemodeToolsSetting, loadSettings, loadSettingsOverrides, resolveAgentResourcePolicy, resolveWorkflowSettings, saveModelAliases, validateContextFileScopes, validateModelAliasAvailability, validateSelectorList, validateWorkflowExtensionSettings, workflowProjectSettingsPath, workflowSettingsPath, workflowToolExposure } from "./settings.js";
15
12
  export function validateCheckpoint(value) {
16
13
  if (!object(value) || Object.keys(value).some((key) => !["name", "prompt", "context"].includes(key)) || typeof value.name !== "string" || value.name.trim() === "" || typeof value.prompt !== "string" || !jsonValue(value.context))
17
14
  fail("INVALID_METADATA", "checkpoint requires only name, prompt, and JSON context");
@@ -21,442 +18,6 @@ export function validateCheckpoint(value) {
21
18
  fail("INVALID_METADATA", "checkpoint context exceeds 4096 UTF-8 bytes");
22
19
  return { name: value.name, prompt: value.prompt, context: value.context };
23
20
  }
24
- export function workflowSettingsPath(agentDir = getAgentDir()) { return join(agentDir, ROLE_DIRECTORY, "settings.json"); }
25
- function normalizedResourcePath(value, settingsPath) {
26
- if (value === "*")
27
- return value;
28
- let expanded = value === "~" ? homedir() : value.startsWith("~/") || value.startsWith("~\\") ? join(homedir(), value.slice(2)) : value;
29
- if (expanded.startsWith("file://"))
30
- expanded = fileURLToPath(expanded);
31
- const resolved = resolve(dirname(settingsPath), expanded);
32
- if (expanded === "**" || expanded.startsWith("**/") || expanded.startsWith("**\\"))
33
- return expanded;
34
- if (resourcePatternHasMagic(expanded)) {
35
- const magicIndex = resolved.search(/[*?\x5b\x5d{}()]/);
36
- const separatorIndex = Math.max(resolved.lastIndexOf("/", magicIndex), resolved.lastIndexOf("\\", magicIndex));
37
- const rootBoundary = separatorIndex === 0 || (separatorIndex === 2 && /^[A-Za-z]:[\\/]/.test(resolved));
38
- const prefix = rootBoundary ? resolved.slice(0, separatorIndex + 1) : separatorIndex >= 0 ? resolved.slice(0, separatorIndex) : resolved;
39
- const suffix = rootBoundary ? resolved.slice(separatorIndex + 1) : separatorIndex >= 0 ? resolved.slice(separatorIndex) : "";
40
- return `${canonicalPath(prefix)}${suffix}`;
41
- }
42
- return canonicalPath(resolved);
43
- }
44
- function validateSelectorList(value, path, kind, errorCode = "INVALID_SETTINGS", normalizeExtensions = true) {
45
- if (value === undefined)
46
- return undefined;
47
- if (!Array.isArray(value))
48
- fail(errorCode, `${path}.${kind} must be an array`);
49
- const normalized = [];
50
- for (const [index, entry] of value.entries()) {
51
- if (typeof entry !== "string" || !entry.trim())
52
- fail(errorCode, `${path}.${kind}[${String(index)}] must be a non-empty string`);
53
- let selector = entry.trim();
54
- if (kind === "extensions" && normalizeExtensions) {
55
- const negated = selector.startsWith("!");
56
- const body = negated ? selector.slice(1) : selector;
57
- if (!body)
58
- fail(errorCode, `${path}.${kind}[${String(index)}] must be a valid minimatch pattern: Empty minimatch pattern ${JSON.stringify(selector)}`);
59
- try {
60
- selector = `${negated ? "!" : ""}${normalizedResourcePath(body, path)}`;
61
- }
62
- catch (error) {
63
- fail(errorCode, `${path}.${kind}[${String(index)}] must be a valid path: ${errorText(error)}`);
64
- }
65
- }
66
- try {
67
- validateResourcePattern(selector);
68
- }
69
- catch (error) {
70
- fail(errorCode, `${path}.${kind}[${String(index)}] must be a valid minimatch pattern: ${errorText(error)}`);
71
- }
72
- normalized.push(selector);
73
- }
74
- return Object.freeze(normalized);
75
- }
76
- function validateWorktreePostCreateCommand(value, settingsPath) {
77
- if (value === undefined)
78
- return undefined;
79
- if (!Array.isArray(value) || value.length === 0)
80
- fail("INVALID_SETTINGS", `${settingsPath}.worktreePostCreateCommand must be a non-empty array`);
81
- return Object.freeze(value.map((entry, index) => {
82
- if (typeof entry !== "string" || !entry.trim())
83
- fail("INVALID_SETTINGS", `${settingsPath}.worktreePostCreateCommand[${String(index)}] must be a non-empty string`);
84
- return entry;
85
- }));
86
- }
87
- function selectorsFromSettings(settings) {
88
- return {
89
- ...(settings.skills === undefined ? {} : { skills: settings.skills }),
90
- ...(settings.extensions === undefined ? {} : { extensions: settings.extensions }),
91
- ...(settings.tools === undefined ? {} : { tools: settings.tools }),
92
- };
93
- }
94
- function selectorSet(value) { return { skills: [...(value?.skills ?? [])], extensions: [...(value?.extensions ?? [])], ...(value?.tools === undefined ? {} : { tools: [...value.tools] }) }; }
95
- function validateContextFileScopes(value, rolePath) {
96
- if (value === undefined)
97
- return undefined;
98
- if (!Array.isArray(value) || !value.every(isContextFileScope))
99
- fail("INVALID_METADATA", `${rolePath}.contextFiles must be an array containing only global, project, or cwd`);
100
- return [...value];
101
- }
102
- export function validateWorkflowExtensionSettings(value, settingsPath, errorCode = "INVALID_SETTINGS", applyDefaults = true) {
103
- if (value === undefined)
104
- return undefined;
105
- const base = `${settingsPath}.extensionSettings`;
106
- if (!object(value))
107
- fail(errorCode, `${base} must be an object`);
108
- const normalized = {};
109
- for (const [namespace, raw] of Object.entries(value)) {
110
- if (!validWorkflowExtensionNamespace(namespace))
111
- fail(errorCode, `${base} contains an invalid namespace: ${namespace}`);
112
- if (namespace === "herdr") {
113
- if (!object(raw))
114
- fail(errorCode, `${base}.herdr must be an object`);
115
- if (Object.keys(raw).some((key) => key !== "enableFullyInspectableMode"))
116
- fail(errorCode, `${base}.herdr contains an unsupported setting`);
117
- if (raw.enableFullyInspectableMode !== undefined && typeof raw.enableFullyInspectableMode !== "boolean")
118
- fail(errorCode, `${base}.herdr.enableFullyInspectableMode must be a boolean`);
119
- normalized.herdr = Object.freeze({ ...(raw.enableFullyInspectableMode === undefined ? {} : { enableFullyInspectableMode: raw.enableFullyInspectableMode }) });
120
- continue;
121
- }
122
- if (namespace === "trajectory") {
123
- if (!object(raw))
124
- fail(errorCode, `${base}.trajectory must be an object`);
125
- if (Object.keys(raw).some((key) => key !== "port" && key !== "themes"))
126
- fail(errorCode, `${base}.trajectory contains an unsupported setting`);
127
- if (raw.port !== undefined && (!positiveInteger(raw.port) || raw.port > 65535))
128
- fail(errorCode, `${base}.trajectory.port must be an integer from 1 to 65535`);
129
- if (raw.themes !== undefined && typeof raw.themes !== "boolean")
130
- fail(errorCode, `${base}.trajectory.themes must be a boolean`);
131
- normalized.trajectory = Object.freeze({ ...(raw.port === undefined ? {} : { port: raw.port }), ...(raw.themes === undefined ? (applyDefaults ? { themes: false } : {}) : { themes: raw.themes }) });
132
- continue;
133
- }
134
- if (!jsonValue(raw))
135
- fail(errorCode, `${base}.${namespace} must be JSON-compatible`);
136
- normalized[namespace] = structuredClone(raw);
137
- }
138
- return deepFreeze(normalized);
139
- }
140
- function positiveRetentionInteger(value) { return positiveInteger(value) && Number.isSafeInteger(value); }
141
- function validateRetention(value, settingsPath) {
142
- if (value === undefined)
143
- return undefined;
144
- const base = `${settingsPath}.retention`;
145
- if (!object(value))
146
- fail("INVALID_SETTINGS", `${base} must be an object`);
147
- const unknown = Object.keys(value).find((key) => key !== "olderThanDays" && key !== "maxTerminalRuns");
148
- if (unknown)
149
- fail("INVALID_SETTINGS", `Unknown retention setting at ${base}: ${unknown}`);
150
- if (value.olderThanDays !== undefined && !positiveRetentionInteger(value.olderThanDays))
151
- fail("INVALID_SETTINGS", `${base}.olderThanDays must be a positive integer`);
152
- if (value.maxTerminalRuns !== undefined && !positiveRetentionInteger(value.maxTerminalRuns))
153
- fail("INVALID_SETTINGS", `${base}.maxTerminalRuns must be a positive integer`);
154
- return Object.freeze({ ...(value.olderThanDays === undefined ? {} : { olderThanDays: value.olderThanDays }), ...(value.maxTerminalRuns === undefined ? {} : { maxTerminalRuns: value.maxTerminalRuns }) });
155
- }
156
- function parseSettings(path, partial) {
157
- let parsed;
158
- try {
159
- parsed = JSON.parse(readFileSync(path, "utf8"));
160
- }
161
- catch (error) {
162
- if (isNodeError(error, "ENOENT"))
163
- return partial ? Object.freeze({}) : DEFAULT_SETTINGS;
164
- fail("CONFIG_ERROR", `Invalid workflow settings JSON at ${path}: ${errorText(error)}`);
165
- }
166
- if (!object(parsed))
167
- fail("INVALID_SETTINGS", `Workflow settings at ${path} must be an object`);
168
- const allowed = new Set(["concurrency", "modelAliases", "skills", "extensions", "extensionSettings", "tools", "retention", "worktreePostCreateCommand", ...(partial ? [] : ["backgroundWidget"])]);
169
- const unknown = Object.keys(parsed).find((key) => !allowed.has(key));
170
- if (Object.prototype.hasOwnProperty.call(parsed, "disabledAgentResources"))
171
- fail("INVALID_SETTINGS", `disabledAgentResources is no longer supported; use skills, extensions, and tools selectors (settings: ${path})`);
172
- if (unknown)
173
- fail("INVALID_SETTINGS", `Unknown workflow setting at ${path}: ${unknown}`);
174
- const concurrency = parsed.concurrency === undefined ? (partial ? undefined : DEFAULT_SETTINGS.concurrency) : parsed.concurrency;
175
- if (concurrency !== undefined && (!positiveInteger(concurrency) || concurrency > 16))
176
- fail("INVALID_SETTINGS", `${path}.concurrency must be an integer from 1 to 16`);
177
- const backgroundWidget = parsed.backgroundWidget === undefined ? (partial ? undefined : DEFAULT_SETTINGS.backgroundWidget) : parsed.backgroundWidget;
178
- if (backgroundWidget !== undefined && typeof backgroundWidget !== "boolean")
179
- fail("INVALID_SETTINGS", `${path}.backgroundWidget must be a boolean`);
180
- const modelAliases = parsed.modelAliases === undefined ? undefined : validateModelAliases(parsed.modelAliases, path);
181
- const skills = validateSelectorList(parsed.skills, path, "skills");
182
- const tools = validateSelectorList(parsed.tools, path, "tools");
183
- const extensions = validateSelectorList(parsed.extensions, path, "extensions");
184
- const extensionSettings = parsed.extensionSettings === undefined ? undefined : validateWorkflowExtensionSettings(parsed.extensionSettings, path, "INVALID_SETTINGS", !partial);
185
- const retention = validateRetention(parsed.retention, path);
186
- const worktreePostCreateCommand = validateWorktreePostCreateCommand(parsed.worktreePostCreateCommand, path);
187
- return Object.freeze({
188
- ...(concurrency === undefined ? {} : { concurrency }), ...(backgroundWidget === undefined ? {} : { backgroundWidget }), ...(modelAliases === undefined ? {} : { modelAliases }),
189
- ...(skills === undefined ? {} : { skills }), ...(extensions === undefined ? {} : { extensions }),
190
- ...(extensionSettings === undefined ? {} : { extensionSettings }), ...(tools === undefined ? {} : { tools }), ...(retention === undefined ? {} : { retention }),
191
- ...(worktreePostCreateCommand === undefined ? {} : { worktreePostCreateCommand }),
192
- });
193
- }
194
- export function loadSettings(path = workflowSettingsPath()) { return parseSettings(path, false); }
195
- export function loadSettingsOverrides(path) { return parseSettings(path, true); }
196
- export function resolveWorkflowSettings(cwd, projectTrusted, globalSettingsPath = workflowSettingsPath()) {
197
- const projectSettingsPath = workflowProjectSettingsPath(cwd);
198
- const global = loadSettings(globalSettingsPath);
199
- const project = projectTrusted ? loadSettingsOverrides(projectSettingsPath) : Object.freeze({});
200
- const projectHas = (key) => Object.prototype.hasOwnProperty.call(project, key);
201
- const sourceFor = (key) => projectHas(key) ? projectSettingsPath : globalSettingsPath;
202
- const globalSelectors = selectorsFromSettings(global);
203
- const projectSelectors = selectorsFromSettings(project);
204
- const effectiveSelectors = selectorSet({
205
- skills: [...(globalSelectors.skills ?? []), ...(projectSelectors.skills ?? [])],
206
- extensions: [...(globalSelectors.extensions ?? []), ...(projectSelectors.extensions ?? [])],
207
- ...(globalSelectors.tools === undefined && projectSelectors.tools === undefined ? {} : { tools: [...(globalSelectors.tools ?? []), ...(projectSelectors.tools ?? [])] }),
208
- });
209
- const hasExtensionSelectors = global.extensions !== undefined || project.extensions !== undefined;
210
- const extensionSettings = projectHas("extensionSettings") ? project.extensionSettings : global.extensionSettings;
211
- const sources = {
212
- concurrency: projectHas("concurrency") ? projectSettingsPath : globalSettingsPath,
213
- modelAliases: projectHas("modelAliases") ? projectSettingsPath : globalSettingsPath,
214
- skills: sourceFor("skills"), extensions: sourceFor("extensions"), tools: sourceFor("tools"),
215
- ...(extensionSettings === undefined ? {} : { extensionSettings: projectHas("extensionSettings") ? projectSettingsPath : globalSettingsPath }),
216
- ...(project.retention === undefined && global.retention === undefined ? {} : { retention: project.retention === undefined ? globalSettingsPath : projectSettingsPath }),
217
- ...(projectHas("worktreePostCreateCommand") || global.worktreePostCreateCommand !== undefined ? { worktreePostCreateCommand: projectHas("worktreePostCreateCommand") ? projectSettingsPath : globalSettingsPath } : {}),
218
- };
219
- const effective = Object.freeze({
220
- concurrency: project.concurrency ?? global.concurrency,
221
- backgroundWidget: global.backgroundWidget ?? true,
222
- ...(projectHas("modelAliases") ? { modelAliases: project.modelAliases } : global.modelAliases === undefined ? {} : { modelAliases: global.modelAliases }),
223
- ...(effectiveSelectors.skills.length ? { skills: effectiveSelectors.skills } : global.skills !== undefined || project.skills !== undefined ? { skills: effectiveSelectors.skills } : {}),
224
- ...(hasExtensionSelectors ? { extensions: effectiveSelectors.extensions } : {}),
225
- ...(extensionSettings === undefined ? {} : { extensionSettings }),
226
- ...(effectiveSelectors.tools?.length ? { tools: effectiveSelectors.tools } : global.tools !== undefined || project.tools !== undefined ? { tools: effectiveSelectors.tools } : {}),
227
- ...((project.retention ?? global.retention) === undefined ? {} : { retention: project.retention ?? global.retention }),
228
- ...(projectHas("worktreePostCreateCommand") ? { worktreePostCreateCommand: project.worktreePostCreateCommand } : global.worktreePostCreateCommand === undefined ? {} : { worktreePostCreateCommand: global.worktreePostCreateCommand }),
229
- });
230
- return { globalSettingsPath, projectSettingsPath, projectTrusted, global, project, effective, sources };
231
- }
232
- export function validateModelAliasAvailability(aliases, names, availableModels, knownModels, settingsPath) {
233
- for (const name of names) {
234
- try {
235
- const target = modelCapability(name, aliases, knownModels, settingsPath);
236
- if (!availableModels.has(target))
237
- unknownModel(name, target, settingsPath);
238
- }
239
- catch (error) {
240
- throw annotateModelAliasError(error, name);
241
- }
242
- }
243
- }
244
- export function resolveAgentResourcePolicy(cwd, projectTrusted, globalSettingsPath = workflowSettingsPath()) {
245
- const resolved = resolveWorkflowSettings(cwd, projectTrusted, globalSettingsPath);
246
- const global = selectorSet(selectorsFromSettings(resolved.global));
247
- const project = selectorSet(selectorsFromSettings(resolved.project));
248
- const effective = selectorSet(selectorsFromSettings(resolved.effective));
249
- return { globalSettingsPath: resolved.globalSettingsPath, projectSettingsPath: resolved.projectSettingsPath, projectTrusted, global, project, effective, unmatchedSkills: [], unmatchedExtensions: [], unmatchedTools: [], selectorSources: { global: selectorsFromSettings(resolved.global), project: selectorsFromSettings(resolved.project) } };
250
- }
251
- export function saveModelAliases(path = workflowSettingsPath(), aliases = {}) {
252
- const normalized = validateModelAliases(aliases, path);
253
- let parsed = {};
254
- try {
255
- loadSettings(path);
256
- parsed = JSON.parse(readFileSync(path, "utf8"));
257
- }
258
- catch (error) {
259
- if (!isNodeError(error, "ENOENT"))
260
- throw error;
261
- }
262
- if (!object(parsed))
263
- fail("INVALID_SETTINGS", `Workflow settings at ${path} must be an object`);
264
- mkdirSync(dirname(path), { recursive: true });
265
- atomicWriteFile(path, `${JSON.stringify({ ...parsed, modelAliases: normalized }, null, 2)}\n`, true);
266
- }
267
- export function parseRoleMarkdown(content, strict = false, rolePath) {
268
- if (!strict) {
269
- if (!content.startsWith("---\n"))
270
- return { prompt: content };
271
- const end = content.indexOf("\n---", 4);
272
- if (end < 0)
273
- return { prompt: content };
274
- const meta = {};
275
- for (const line of content.slice(4, end).split("\n")) {
276
- const match = /^(model|tools|skills|extensions|description|overrideSystemPrompt|override_system_prompt|is_system_prompt|contextFiles|extensionSettings|disabledAgentResources|thinking)\s*:\s*(.+)$/.exec(line.trim());
277
- if (match?.[1] === "disabledAgentResources")
278
- fail("INVALID_METADATA", "disabledAgentResources is no longer supported; use skills, extensions, and tools selectors");
279
- if (match?.[1] === "thinking")
280
- fail("INVALID_METADATA", "Role thinking is not supported; put it on model as provider/model:thinking");
281
- if (match?.[1] && match[2])
282
- meta[match[1]] = match[2].trim();
283
- }
284
- const unquote = (v) => v.replace(/^['"]|['"]$/g, "");
285
- const parseList = (value) => value === undefined ? undefined : value.replace(/^\[|\]$/g, "").split(",").map((entry) => unquote(entry.trim())).filter(Boolean);
286
- const tools = parseList(meta.tools);
287
- const skills = parseList(meta.skills);
288
- const extensions = parseList(meta.extensions);
289
- let extensionSettings;
290
- if (meta.extensionSettings !== undefined) {
291
- try {
292
- extensionSettings = JSON.parse(meta.extensionSettings);
293
- }
294
- catch (error) {
295
- fail("INVALID_METADATA", `Invalid role extensionSettings: ${errorText(error)}`);
296
- }
297
- }
298
- const rolePathValue = rolePath ?? "<role>";
299
- const normalizedExtensionSettings = validateWorkflowExtensionSettings(extensionSettings, rolePathValue, "INVALID_METADATA", false);
300
- const definition = { prompt: content.slice(end + 4).replace(/^\n/, "") };
301
- if (meta.model) {
302
- const model = unquote(meta.model);
303
- assertModelThinking(model, "Role model");
304
- definition.model = model;
305
- }
306
- if (meta.description)
307
- definition.description = unquote(meta.description);
308
- if (tools)
309
- definition.tools = tools;
310
- if (skills)
311
- definition.skills = skills;
312
- if (extensions)
313
- definition.extensions = extensions;
314
- if (normalizedExtensionSettings !== undefined)
315
- definition.extensionSettings = normalizedExtensionSettings;
316
- const overrideSystemPrompt = meta.overrideSystemPrompt ?? meta.override_system_prompt ?? meta.is_system_prompt;
317
- const contextFiles = meta.contextFiles ? meta.contextFiles.replace(/^\[|\]$/g, "").split(",").map((scope) => unquote(scope.trim())).filter(Boolean) : undefined;
318
- const normalizedContextFiles = validateContextFileScopes(contextFiles, "role");
319
- if (overrideSystemPrompt)
320
- definition.overrideSystemPrompt = overrideSystemPrompt === "true";
321
- if (normalizedContextFiles)
322
- definition.contextFiles = normalizedContextFiles;
323
- return definition;
324
- }
325
- const normalized = content.replace(/\r\n?/g, "\n");
326
- if (normalized.startsWith("---\n") && normalized.indexOf("\n---", 3) < 0)
327
- fail("INVALID_METADATA", "Role frontmatter is missing its closing delimiter");
328
- let parsed;
329
- try {
330
- parsed = parseFrontmatter(content);
331
- }
332
- catch (error) {
333
- fail("INVALID_METADATA", `Invalid role frontmatter: ${errorText(error)}`);
334
- }
335
- if (!object(parsed.frontmatter))
336
- fail("INVALID_METADATA", "Role frontmatter must be an object");
337
- const { model, tools, skills, extensions, extensionSettings, description, contextFiles } = parsed.frontmatter;
338
- if (Object.prototype.hasOwnProperty.call(parsed.frontmatter, "disabledAgentResources"))
339
- fail("INVALID_METADATA", "disabledAgentResources is no longer supported; use skills, extensions, and tools selectors");
340
- if (Object.prototype.hasOwnProperty.call(parsed.frontmatter, "thinking"))
341
- fail("INVALID_METADATA", "Role thinking is not supported; put it on model as provider/model:thinking");
342
- const overrideSystemPrompt = parsed.frontmatter.overrideSystemPrompt ?? parsed.frontmatter.override_system_prompt ?? parsed.frontmatter.is_system_prompt;
343
- if (model !== undefined && (typeof model !== "string" || model.trim() === ""))
344
- fail("INVALID_METADATA", "Role model must be a non-empty string");
345
- if (description !== undefined && (typeof description !== "string" || description.trim() === "" || description.length > 1024 || /[\r\n]/.test(description)))
346
- fail("INVALID_METADATA", "Role description must be a non-empty single-line string of at most 1024 characters");
347
- if (overrideSystemPrompt !== undefined && typeof overrideSystemPrompt !== "boolean")
348
- fail("INVALID_METADATA", "Role overrideSystemPrompt must be a boolean");
349
- const normalizedContextFiles = validateContextFileScopes(contextFiles, rolePath ?? "<role>");
350
- const rolePathValue = rolePath ?? "<role>";
351
- const normalizedTools = validateSelectorList(tools, rolePathValue, "tools", "INVALID_METADATA");
352
- const normalizedSkills = validateSelectorList(skills, rolePathValue, "skills", "INVALID_METADATA");
353
- const normalizedExtensions = validateSelectorList(extensions, rolePathValue, "extensions", "INVALID_METADATA");
354
- const normalizedExtensionSettings = validateWorkflowExtensionSettings(extensionSettings, rolePathValue, "INVALID_METADATA", false);
355
- const normalizedDescription = typeof description === "string" ? description.trim() : undefined;
356
- const normalizedModel = typeof model === "string" ? model.trim() : undefined;
357
- if (normalizedModel !== undefined)
358
- assertModelThinking(normalizedModel, "Role model");
359
- const definition = { prompt: parsed.body };
360
- if (normalizedDescription !== undefined)
361
- definition.description = normalizedDescription;
362
- if (normalizedModel !== undefined)
363
- definition.model = normalizedModel;
364
- if (normalizedTools !== undefined)
365
- definition.tools = normalizedTools;
366
- if (normalizedSkills !== undefined)
367
- definition.skills = normalizedSkills;
368
- if (normalizedExtensions !== undefined)
369
- definition.extensions = normalizedExtensions;
370
- if (normalizedExtensionSettings !== undefined)
371
- definition.extensionSettings = normalizedExtensionSettings;
372
- if (typeof overrideSystemPrompt === "boolean")
373
- definition.overrideSystemPrompt = overrideSystemPrompt;
374
- if (normalizedContextFiles !== undefined)
375
- definition.contextFiles = normalizedContextFiles;
376
- return definition;
377
- }
378
- const ROLE_DIRECTORY = "pi-extensible-workflows";
379
- export function workflowRoleDirectories(agentDir = getAgentDir()) {
380
- return [join(agentDir, ROLE_DIRECTORY, "roles")];
381
- }
382
- function projectRoleDirectories(root) {
383
- return [join(root, ROLE_DIRECTORY, "roles")];
384
- }
385
- function roleDirectorySources(dirs) {
386
- const seen = new Set();
387
- return dirs.flatMap((value) => {
388
- const source = typeof value === "string" ? { path: value } : { path: value.path, extension: value.extension, ...(value.builtin === true ? { builtin: true } : {}) };
389
- if (seen.has(source.path))
390
- return [];
391
- seen.add(source.path);
392
- return [source];
393
- });
394
- }
395
- function roleDirectoryLabel(source, extension = true) {
396
- return source.extension ? `Extension "${source.extension.headline}" (${source.extension.version})` : extension ? "Registered workflow extension" : "Standard workflow";
397
- }
398
- function isRoleFile(dir, entry) {
399
- if (extname(entry.name) !== ".md")
400
- return false;
401
- if (entry.isFile())
402
- return true;
403
- if (!entry.isSymbolicLink())
404
- return false;
405
- try {
406
- return statSync(join(dir, entry.name)).isFile();
407
- }
408
- catch (error) {
409
- if (isNodeError(error, "ENOENT"))
410
- return false;
411
- throw error;
412
- }
413
- }
414
- function scanRoleFiles(dirs, extension) {
415
- const files = [];
416
- for (const source of roleDirectorySources(dirs)) {
417
- let entries;
418
- try {
419
- entries = readdirSync(source.path, { withFileTypes: true });
420
- }
421
- catch (error) {
422
- if (!extension && isNodeError(error, "ENOENT"))
423
- continue;
424
- fail("INVALID_METADATA", `${roleDirectoryLabel(source, extension)} role directory "${source.path}" could not be scanned: ${errorText(error)}`);
425
- }
426
- for (const entry of entries)
427
- if (isRoleFile(source.path, entry))
428
- files.push({ name: basename(entry.name, ".md"), path: join(source.path, entry.name), source });
429
- }
430
- return files.sort((left, right) => left.name.localeCompare(right.name) || left.path.localeCompare(right.path));
431
- }
432
- function readRoleDefinitions(dirs, extension = false) {
433
- const files = scanRoleFiles(dirs, extension);
434
- const starterFiles = files.filter(({ source }) => source.builtin === true);
435
- const regularFiles = files.filter(({ source }) => source.builtin !== true);
436
- if (extension) {
437
- const byName = new Map();
438
- for (const file of regularFiles)
439
- byName.set(file.name, [...(byName.get(file.name) ?? []), file]);
440
- for (const [name, matches] of byName)
441
- if (matches.length > 1)
442
- fail("INVALID_METADATA", `Duplicate extension role "${name}": ${matches.map(({ path, source }) => `${roleDirectoryLabel(source)} role directory "${source.path}" (${path})`).join("; ")}`);
443
- }
444
- const read = (roleFiles) => Object.fromEntries(roleFiles.map(({ name, path, source }) => {
445
- try {
446
- return [name, parseRoleMarkdown(readFileSync(path, "utf8"), true, path)];
447
- }
448
- catch (error) {
449
- if (extension)
450
- fail("INVALID_METADATA", `${roleDirectoryLabel(source)} role directory "${source.path}" contains invalid role "${name}" at "${path}": ${errorText(error)}`);
451
- throw error;
452
- }
453
- }));
454
- return extension ? { ...read(starterFiles), ...read(regularFiles) } : read(files);
455
- }
456
- export function loadProjectAgentDefinitions(cwd) { return readRoleDefinitions(projectRoleDirectories(join(cwd, ".pi"))); }
457
- export function loadAgentDefinitions(cwd, agentDir = getAgentDir(), projectTrusted = true, extensionRoleDirectories = registeredWorkflowRoleDirectoryRegistrations()) {
458
- return deepFreeze({ ...readRoleDefinitions(extensionRoleDirectories, true), ...readRoleDefinitions(workflowRoleDirectories(agentDir)), ...(projectTrusted ? readRoleDefinitions(projectRoleDirectories(join(cwd, ".pi"))) : {}) });
459
- }
460
21
  function validateRolePolicies(definitions, roles, availableModels, aliases = {}, knownModels = availableModels, settingsPath) {
461
22
  for (const role of roles) {
462
23
  const definition = definitions[role];
@@ -683,6 +244,26 @@ function callHasTrailingComma(source, call) {
683
244
  }
684
245
  return current?.type.label === ")" && previous?.type.label === ",";
685
246
  }
247
+ /**
248
+ * The `tools.<id>` members a workflow script names statically. Any other use of `tools`, such as a
249
+ * local declaration that shadows the global or passing it around, makes the set unknowable: undefined.
250
+ */
251
+ export function scriptToolReferences(script) {
252
+ const body = workflowBody(script);
253
+ if (!body.trim())
254
+ return [];
255
+ const names = new Set();
256
+ const opaque = (node, parent) => {
257
+ if (node.type === "Identifier" && node.name === "tools") {
258
+ if (parent?.type === "MemberExpression" && parent.object === node && !parent.computed && parent.property.type === "Identifier")
259
+ names.add(parent.property.name);
260
+ else if (!(parent?.type === "Property" && parent.key === node && !parent.computed && !parent.shorthand || parent?.type === "MemberExpression" && parent.property === node && !parent.computed))
261
+ return true;
262
+ }
263
+ return astChildren(node).some((child) => opaque(child, node));
264
+ };
265
+ return opaque(parseWorkflow(body)) ? undefined : [...names];
266
+ }
686
267
  export function instrumentWorkflow(script) {
687
268
  const body = workflowBody(script);
688
269
  if (!body.trim())
@@ -767,16 +348,6 @@ export function workflowPrompt(template, values) {
767
348
  return typeof value === "string" ? value : JSON.stringify(value, null, 2);
768
349
  });
769
350
  }
770
- export function validateSchema(schema, at = "schema") {
771
- if (!object(schema) || Object.getPrototypeOf(schema) !== Object.prototype || !jsonValue(schema))
772
- fail("INVALID_SCHEMA", `${at} must be a plain JSON-compatible Schema object`);
773
- if (typeof schema.type !== "string" && !Array.isArray(schema.type) && schema.$ref === undefined && schema.anyOf === undefined && schema.oneOf === undefined && schema.allOf === undefined && schema.const === undefined && schema.enum === undefined)
774
- fail("INVALID_SCHEMA", `${at} has no JSON Schema shape`);
775
- if (schema.required !== undefined && (!Array.isArray(schema.required) || schema.required.some((key) => typeof key !== "string")))
776
- fail("INVALID_SCHEMA", `${at}.required must be an array of strings`);
777
- if (schema.properties !== undefined && !object(schema.properties))
778
- fail("INVALID_SCHEMA", `${at}.properties must be an object`);
779
- }
780
351
  const AGENT_OPTION_KEYS = new Set(["label", "model", "tools", "skills", "extensions", "contextFiles", "role", "outputSchema", "retries", "timeoutMs"]);
781
352
  function validateAgentOption(key, value, aliases, knownModels, settingsPath) {
782
353
  switch (key) {
@@ -65,8 +65,6 @@ var reviewLoop = defineWorkflowFunction({
65
65
  { additionalProperties: false }
66
66
  )
67
67
  });
68
- var reviewLoopInputSchema = reviewLoop.input;
69
- var reviewLoopOutputSchema = reviewLoop.output;
70
68
 
71
69
  // starter/index.ts
72
70
  var extension = {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../starter/index.ts", "../../starter/review-loop.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": []
6
6
  }