@mediadatafusion/pi-workflow-suite 0.0.20 → 0.0.22
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 +18 -0
- package/README.md +51 -17
- package/VERSION +1 -1
- package/config/prompts/mission-repair.md +1 -0
- package/config/prompts/mission-run.md +1 -0
- package/extensions/workflow-modes.ts +1038 -188
- package/extensions/workflow-state.ts +20 -0
- package/extensions/workflow-subagent-policy.ts +236 -3
- package/package.json +1 -1
|
@@ -141,6 +141,25 @@ export interface StandardTodoState {
|
|
|
141
141
|
|
|
142
142
|
export type StandardClarificationStage = "drafting" | "awaiting_answer" | "answered";
|
|
143
143
|
export type WorkflowSubagentPhase = "Planning" | "Execution" | "Repair" | "Review" | "Validation";
|
|
144
|
+
export type WorkflowSubagentPolicyDecisionOutcome =
|
|
145
|
+
| "required"
|
|
146
|
+
| "exempt_trivial"
|
|
147
|
+
| "auto_delegate"
|
|
148
|
+
| "auto_skip_trivial"
|
|
149
|
+
| "auto_skip_no_useful_parallel_work"
|
|
150
|
+
| "unavailable";
|
|
151
|
+
|
|
152
|
+
export interface WorkflowSubagentPolicyDecision {
|
|
153
|
+
phase: WorkflowSubagentPhase;
|
|
154
|
+
policy: "off" | "auto" | "deep" | "maximum" | "forced";
|
|
155
|
+
outcome: WorkflowSubagentPolicyDecisionOutcome;
|
|
156
|
+
reason: string;
|
|
157
|
+
task?: string;
|
|
158
|
+
required?: number;
|
|
159
|
+
observed?: number;
|
|
160
|
+
background?: boolean;
|
|
161
|
+
createdAt: string;
|
|
162
|
+
}
|
|
144
163
|
|
|
145
164
|
export interface StandardSubagentPreflightRecord {
|
|
146
165
|
task?: string;
|
|
@@ -310,6 +329,7 @@ export interface WorkflowState {
|
|
|
310
329
|
standardClarifyingQuestions?: ClarificationQuestion[];
|
|
311
330
|
standardClarifyingAnswers?: ClarificationAnswer[];
|
|
312
331
|
standardSubagentPreflight?: Partial<Record<WorkflowSubagentPhase, StandardSubagentPreflightRecord>>;
|
|
332
|
+
subagentPolicyDecisions?: Partial<Record<WorkflowSubagentPhase, WorkflowSubagentPolicyDecision>>;
|
|
313
333
|
standardLastTodoDecision?: string;
|
|
314
334
|
standardLastTodoReason?: string;
|
|
315
335
|
lastCompletedPlanSummary?: CompletedPlanSummary;
|
|
@@ -14,6 +14,28 @@ import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
|
14
14
|
|
|
15
15
|
export type SubagentPhase = "Planning" | "Execution" | "Repair" | "Review" | "Validation";
|
|
16
16
|
export type SubagentPolicyValue = "off" | "auto" | "deep" | "maximum" | "forced";
|
|
17
|
+
export type SubagentPolicyDecisionOutcome =
|
|
18
|
+
| "required"
|
|
19
|
+
| "exempt_trivial"
|
|
20
|
+
| "allow_probe"
|
|
21
|
+
| "allow_mechanical"
|
|
22
|
+
| "allow_user_explicit_finalization"
|
|
23
|
+
| "auto_delegate"
|
|
24
|
+
| "auto_skip_trivial"
|
|
25
|
+
| "auto_skip_no_useful_parallel_work"
|
|
26
|
+
| "unavailable";
|
|
27
|
+
|
|
28
|
+
export interface SubagentPolicyDecision {
|
|
29
|
+
phase: SubagentPhase;
|
|
30
|
+
policy: SubagentPolicyValue;
|
|
31
|
+
outcome: SubagentPolicyDecisionOutcome;
|
|
32
|
+
reason: string;
|
|
33
|
+
task?: string;
|
|
34
|
+
required?: number;
|
|
35
|
+
observed?: number;
|
|
36
|
+
background?: boolean;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
}
|
|
17
39
|
|
|
18
40
|
export interface SubagentToolProfile {
|
|
19
41
|
name: string;
|
|
@@ -106,10 +128,218 @@ export function workerTargetForPolicy(policy: SubagentPolicyValue | undefined, w
|
|
|
106
128
|
return 0;
|
|
107
129
|
}
|
|
108
130
|
|
|
131
|
+
export function subagentPolicyRequiresRequiredEvidence(policy: SubagentPolicyValue | undefined): boolean {
|
|
132
|
+
return policy === "forced";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function subagentPolicyNeedsInternalDecision(policy: SubagentPolicyValue | undefined): boolean {
|
|
136
|
+
return policy === "auto" || policy === "deep" || policy === "maximum";
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function formatSubagentPolicyDecision(decision: SubagentPolicyDecision): string {
|
|
140
|
+
return [
|
|
141
|
+
`Policy decision: ${decision.outcome}`,
|
|
142
|
+
`Phase: ${decision.phase}`,
|
|
143
|
+
`Policy: ${decision.policy}`,
|
|
144
|
+
decision.required !== undefined ? `Required workers: ${decision.required}` : undefined,
|
|
145
|
+
decision.observed !== undefined ? `Observed workers: ${decision.observed}` : undefined,
|
|
146
|
+
decision.background !== undefined ? `Background: ${decision.background ? "yes" : "no"}` : undefined,
|
|
147
|
+
`Reason: ${decision.reason}`,
|
|
148
|
+
].filter((line): line is string => Boolean(line)).join("\n");
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export type ForcedSubagentActionTool =
|
|
152
|
+
| "read"
|
|
153
|
+
| "grep"
|
|
154
|
+
| "find"
|
|
155
|
+
| "ls"
|
|
156
|
+
| "bash"
|
|
157
|
+
| "edit"
|
|
158
|
+
| "write"
|
|
159
|
+
| "subagent"
|
|
160
|
+
| "workflow_progress"
|
|
161
|
+
| "workflow_execution_result"
|
|
162
|
+
| "workflow_validation_result"
|
|
163
|
+
| "workflow_repair_result"
|
|
164
|
+
| "workflow_review_result"
|
|
165
|
+
| "mission_milestone_result"
|
|
166
|
+
| "standard_handoff_result"
|
|
167
|
+
| "standard_todo"
|
|
168
|
+
| string;
|
|
169
|
+
|
|
170
|
+
export interface ForcedSubagentActionInput {
|
|
171
|
+
phase: SubagentPhase;
|
|
172
|
+
policy: SubagentPolicyValue;
|
|
173
|
+
task?: string;
|
|
174
|
+
kind?: string;
|
|
175
|
+
toolName?: ForcedSubagentActionTool;
|
|
176
|
+
command?: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export interface ForcedSubagentActionDecision {
|
|
180
|
+
outcome: Extract<SubagentPolicyDecisionOutcome, "required" | "exempt_trivial" | "allow_probe" | "allow_mechanical" | "allow_user_explicit_finalization">;
|
|
181
|
+
reason: string;
|
|
182
|
+
allowBeforeEvidence: boolean;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface AdvisorySubagentActionDecision {
|
|
186
|
+
outcome: SubagentPolicyDecisionOutcome;
|
|
187
|
+
reason: string;
|
|
188
|
+
allowBeforeEvidence: boolean;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const WORK_MUTATION_RE = /\b(?:edit|write|modify|change|implement|add|remove|delete|refactor|migrate|apply|create files?|update files?|repair|fix)\b/i;
|
|
192
|
+
const EVIDENCE_WORK_RE = /\b(?:validate|validation|verify|test|lint|build|typecheck|quality review|review)\b/i;
|
|
193
|
+
const FINALIZATION_WORK_RE = /\b(?:commit|push|sync(?:\s+to)?\s+live|install(?:\s+to)?\s+live)\b/i;
|
|
194
|
+
const TRIVIAL_REQUEST_RE = /^(?:hi|hello|hey|thanks|thank you|ok|okay|yes|no|help|status)$/i;
|
|
195
|
+
const SMALL_LOOKUP_RE = /\b(?:what|where|when|who|which|explain|summari[sz]e)\b/i;
|
|
196
|
+
const SIMPLE_READ_RE = /\b(?:status|list|show|summari[sz]e|inspect|scan|read.?only|docs? only|no code|do not edit|without editing)\b/i;
|
|
197
|
+
const COMPLEX_CONTEXT_RE = /\b(?:codebase|architecture|multi-file|implementation|workflow|release|runtime|regression)\b/i;
|
|
198
|
+
const SAFE_PROBE_COMMAND_RE = /^(?:pwd|date|whoami|id|hostname|uname\b.*|git\s+(?:status|diff|log|show|branch|rev-parse|ls-files|describe|remote)\b.*|(?:node|npm|pnpm|yarn|bun|python3?|pip3?|cargo|go|rustc|tsc)\s+(?:--version|-v|-V)\b.*)$/i;
|
|
199
|
+
const EXACT_USER_FINALIZATION_COMMAND_RE = /^(?:git\s+add\b.+|git\s+commit\b.+|git\s+push(?:\s+\S+){0,2}|scripts\/install-to-live\.sh|scripts\/verify-live\.sh)$/i;
|
|
200
|
+
|
|
201
|
+
function normalizedWords(text: string | undefined): string[] {
|
|
202
|
+
return (text ?? "").trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function forcedTrivialTaskReason(phase: SubagentPhase, task: string | undefined, kind?: string): string | undefined {
|
|
206
|
+
const text = task?.trim() ?? "";
|
|
207
|
+
if (!text) return "empty/no-op request";
|
|
208
|
+
const normalized = text.toLowerCase();
|
|
209
|
+
const words = normalizedWords(text);
|
|
210
|
+
if (TRIVIAL_REQUEST_RE.test(normalized)) return "trivial conversational/status request";
|
|
211
|
+
if (WORK_MUTATION_RE.test(normalized) || EVIDENCE_WORK_RE.test(normalized) || FINALIZATION_WORK_RE.test(normalized)) return undefined;
|
|
212
|
+
if (kind && kind !== "read_only") return undefined;
|
|
213
|
+
if (SIMPLE_READ_RE.test(normalized) && words.length <= 14) return `trivial ${phase.toLowerCase()} read-only/status request`;
|
|
214
|
+
if (normalized.length <= 80 && SMALL_LOOKUP_RE.test(normalized) && !COMPLEX_CONTEXT_RE.test(normalized)) return `small ${phase.toLowerCase()} lookup/explanation request`;
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function commandWithoutTimeout(command: string | undefined): string {
|
|
219
|
+
return (command ?? "").trim().replace(/^timeout\s+\d+[smhd]?\s+/, "").trim();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function forcedSubagentActionDecision(input: ForcedSubagentActionInput): ForcedSubagentActionDecision {
|
|
223
|
+
const toolName = input.toolName;
|
|
224
|
+
if (!subagentPolicyRequiresRequiredEvidence(input.policy)) {
|
|
225
|
+
return { outcome: "allow_mechanical", reason: "sub-agent policy is not forced", allowBeforeEvidence: true };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!toolName) {
|
|
229
|
+
const reason = forcedTrivialTaskReason(input.phase, input.task, input.kind);
|
|
230
|
+
if (reason) return { outcome: "exempt_trivial", reason, allowBeforeEvidence: true };
|
|
231
|
+
return { outcome: "required", reason: "non-trivial phase requires forced sub-agent evidence", allowBeforeEvidence: false };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (toolName === "subagent") {
|
|
235
|
+
return { outcome: "allow_mechanical", reason: "visible sub-agent call is the required evidence path", allowBeforeEvidence: true };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (toolName === "workflow_progress") {
|
|
239
|
+
return { outcome: "allow_mechanical", reason: "workflow_progress only marks the current execution step active", allowBeforeEvidence: true };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (toolName === "standard_todo") {
|
|
243
|
+
return { outcome: "allow_mechanical", reason: "standard_todo only initializes or updates required Standard Mode task tracking", allowBeforeEvidence: true };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (toolName === "read" || toolName === "grep" || toolName === "find" || toolName === "ls") {
|
|
247
|
+
return { outcome: "allow_probe", reason: "local read/search/list probe can run before forced worker evidence", allowBeforeEvidence: true };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (
|
|
251
|
+
toolName === "workflow_execution_result"
|
|
252
|
+
|| toolName === "workflow_validation_result"
|
|
253
|
+
|| toolName === "workflow_repair_result"
|
|
254
|
+
|| toolName === "workflow_review_result"
|
|
255
|
+
|| toolName === "mission_milestone_result"
|
|
256
|
+
) {
|
|
257
|
+
return { outcome: "required", reason: "typed phase handoff requires forced sub-agent evidence", allowBeforeEvidence: false };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (toolName === "edit" || toolName === "write") {
|
|
261
|
+
return { outcome: "required", reason: "file mutation requires forced sub-agent evidence", allowBeforeEvidence: false };
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (toolName === "bash") {
|
|
265
|
+
const command = commandWithoutTimeout(input.command);
|
|
266
|
+
if (SAFE_PROBE_COMMAND_RE.test(command)) {
|
|
267
|
+
return { outcome: "allow_probe", reason: "safe shell probe can run before forced worker evidence", allowBeforeEvidence: true };
|
|
268
|
+
}
|
|
269
|
+
const task = input.task?.toLowerCase() ?? "";
|
|
270
|
+
if (FINALIZATION_WORK_RE.test(task) && EXACT_USER_FINALIZATION_COMMAND_RE.test(command)) {
|
|
271
|
+
return { outcome: "allow_user_explicit_finalization", reason: "exact user-requested finalization command is not useful worker fanout", allowBeforeEvidence: true };
|
|
272
|
+
}
|
|
273
|
+
return { outcome: "required", reason: "shell command is meaningful work and requires forced sub-agent evidence", allowBeforeEvidence: false };
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const phaseReason = forcedTrivialTaskReason(input.phase, input.task, input.kind);
|
|
277
|
+
if (phaseReason) return { outcome: "exempt_trivial", reason: phaseReason, allowBeforeEvidence: true };
|
|
278
|
+
return { outcome: "required", reason: "tool use requires forced sub-agent evidence", allowBeforeEvidence: false };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export function advisorySubagentPolicyDecision(phase: SubagentPhase, policy: SubagentPolicyValue, task?: string, kind?: string): { outcome: Extract<SubagentPolicyDecisionOutcome, "auto_delegate" | "auto_skip_trivial" | "auto_skip_no_useful_parallel_work">; reason: string } {
|
|
282
|
+
const trivialReason = forcedTrivialTaskReason(phase, task, kind);
|
|
283
|
+
if (trivialReason) return { outcome: "auto_skip_trivial", reason: trivialReason };
|
|
284
|
+
if (policy === "auto") return { outcome: "auto_delegate", reason: `auto policy must actively consider worker delegation for non-trivial ${phase.toLowerCase()} work` };
|
|
285
|
+
return { outcome: "auto_delegate", reason: `${policy} policy expects worker delegation for non-trivial ${phase.toLowerCase()} work` };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export function advisorySubagentActionDecision(input: ForcedSubagentActionInput): AdvisorySubagentActionDecision {
|
|
289
|
+
const toolName = input.toolName;
|
|
290
|
+
if (!subagentPolicyNeedsInternalDecision(input.policy)) {
|
|
291
|
+
return { outcome: "allow_mechanical", reason: "sub-agent policy does not require advisory consideration", allowBeforeEvidence: true };
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!toolName) {
|
|
295
|
+
const reason = forcedTrivialTaskReason(input.phase, input.task, input.kind);
|
|
296
|
+
if (reason) return { outcome: "auto_skip_trivial", reason, allowBeforeEvidence: true };
|
|
297
|
+
return { outcome: "auto_delegate", reason: `non-trivial ${input.phase.toLowerCase()} work must actively consider sub-agent delegation`, allowBeforeEvidence: false };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (toolName === "subagent") {
|
|
301
|
+
return { outcome: "auto_delegate", reason: "visible parent sub-agent call satisfies advisory consideration", allowBeforeEvidence: true };
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (toolName === "workflow_progress") {
|
|
305
|
+
return { outcome: "allow_mechanical", reason: "workflow_progress only marks workflow bookkeeping", allowBeforeEvidence: true };
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (toolName === "standard_todo") {
|
|
309
|
+
return { outcome: "allow_mechanical", reason: "standard_todo only initializes or updates required Standard Mode task tracking", allowBeforeEvidence: true };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (
|
|
313
|
+
toolName === "workflow_execution_result"
|
|
314
|
+
|| toolName === "workflow_validation_result"
|
|
315
|
+
|| toolName === "workflow_repair_result"
|
|
316
|
+
|| toolName === "workflow_review_result"
|
|
317
|
+
|| toolName === "mission_milestone_result"
|
|
318
|
+
|| toolName === "standard_handoff_result"
|
|
319
|
+
) {
|
|
320
|
+
return { outcome: "allow_user_explicit_finalization", reason: "typed phase handoff is finalization; advisory sub-agent consideration must happen before substantive work", allowBeforeEvidence: true };
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (toolName === "bash") {
|
|
324
|
+
const command = commandWithoutTimeout(input.command);
|
|
325
|
+
if (SAFE_PROBE_COMMAND_RE.test(command)) {
|
|
326
|
+
return { outcome: "allow_probe", reason: "safe shell probe can run before advisory worker evidence", allowBeforeEvidence: true };
|
|
327
|
+
}
|
|
328
|
+
const task = input.task?.toLowerCase() ?? "";
|
|
329
|
+
if (FINALIZATION_WORK_RE.test(task) && EXACT_USER_FINALIZATION_COMMAND_RE.test(command)) {
|
|
330
|
+
return { outcome: "allow_user_explicit_finalization", reason: "exact user-requested finalization command is not useful worker fanout", allowBeforeEvidence: true };
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const trivialReason = forcedTrivialTaskReason(input.phase, input.task, input.kind);
|
|
335
|
+
if (trivialReason) return { outcome: "auto_skip_trivial", reason: trivialReason, allowBeforeEvidence: true };
|
|
336
|
+
return { outcome: "auto_delegate", reason: `non-trivial ${input.phase.toLowerCase()} ${toolName} use must actively consider sub-agent delegation`, allowBeforeEvidence: false };
|
|
337
|
+
}
|
|
338
|
+
|
|
109
339
|
export function activeWorkerTargetLabel(policy: SubagentPolicyValue | undefined, workers: { deep: number; maximum: number }): string {
|
|
110
340
|
const effectivePolicy = policy ?? "auto";
|
|
111
341
|
if (effectivePolicy === "off") return "off (sub-agents disabled for this phase)";
|
|
112
|
-
if (effectivePolicy === "auto") return
|
|
342
|
+
if (effectivePolicy === "auto") return `actively considered; prefer up to ${Math.max(1, workers.deep)} target worker${Math.max(1, workers.deep) === 1 ? "" : "s"} for non-trivial work`;
|
|
113
343
|
if (effectivePolicy === "deep") return `${workers.deep} target worker${workers.deep === 1 ? "" : "s"} (deep policy; expected for non-trivial work)`;
|
|
114
344
|
if (effectivePolicy === "maximum") return `${workers.maximum} target worker${workers.maximum === 1 ? "" : "s"} (maximum policy; skip only if trivial/unavailable)`;
|
|
115
345
|
return `${Math.max(1, workers.maximum)} required worker${Math.max(1, workers.maximum) === 1 ? "" : "s"} (forced policy; hard requirement)`;
|
|
@@ -136,14 +366,14 @@ export function repairPolicySource(settings: WorkflowSettings): "configured/defa
|
|
|
136
366
|
}
|
|
137
367
|
|
|
138
368
|
export function forcedSubagentUnavailableReason(settings: WorkflowSettings, phase: SubagentPhase, cwd: string, policy = phasePolicy(settings, phase), workers = workerCount(settings, phase)): string | undefined {
|
|
139
|
-
if (policy
|
|
369
|
+
if (!subagentPolicyRequiresRequiredEvidence(policy)) return undefined;
|
|
140
370
|
if (settings.subagents.enabled === false) return "subagents.enabled=false";
|
|
141
371
|
if (!phaseAutoUseAllowed(settings, phase)) return `subagents.autoUseDuring${phase}=false`;
|
|
142
372
|
if (!phaseParallelAllowed(settings, phase)) return `subagents.allowParallel${phase}=false`;
|
|
143
373
|
if (phase !== "Execution" && settings.subagents.allowParallelReadOnly === false) return "subagents.allowParallelReadOnly=false";
|
|
144
374
|
const subagentInstalled = existsSync(USER_SUBAGENT_EXTENSION_FILE) || existsSync(PACKAGE_SUBAGENT_EXTENSION_FILE);
|
|
145
375
|
if (!subagentInstalled) return `the subagent extension is not installed at ${USER_SUBAGENT_EXTENSION_FILE} or bundled at ${PACKAGE_SUBAGENT_EXTENSION_FILE}`;
|
|
146
|
-
const target = workerTargetForPolicy(
|
|
376
|
+
const target = workerTargetForPolicy(policy, workers);
|
|
147
377
|
if (target > 8) return `required worker target ${target} exceeds subagent maximum of 8`;
|
|
148
378
|
return undefined;
|
|
149
379
|
}
|
|
@@ -164,6 +394,9 @@ export function hasRequiredSubagentPreflight(preflightBlock?: string): boolean {
|
|
|
164
394
|
|
|
165
395
|
export function requiredSubagentPreflightSection(preflightBlock?: string): string {
|
|
166
396
|
if (!preflightBlock?.trim()) return "";
|
|
397
|
+
if (/^Policy decision:\s*exempt_trivial\b/im.test(preflightBlock)) {
|
|
398
|
+
return `\n\n## Required Sub-Agent Policy Decision\n${preflightBlock.trim()}\n\nWorkflow Suite internally classified this forced-policy request as deterministic trivial/read-only or no-op work. Do not call the visible subagent tool solely for policy compliance, and do not print policy deliberation to the user.`;
|
|
399
|
+
}
|
|
167
400
|
return `\n\n## Required Sub-Agent Preflight\n${preflightBlock.trim()}\n\nThe workflow already ran the required forced-policy sub-agents for this phase. Use these findings as input. Do not rerun required workers just to satisfy policy; call more sub-agents only if additional targeted work is genuinely useful.`;
|
|
168
401
|
}
|
|
169
402
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mediadatafusion/pi-workflow-suite",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "Multi-agent workflow suite for Pi with Idle, Standard, Plan, Mission, approval gates, reviewer/validator roles, sub-agents, model routing, web search/fetch, browser checks, diagrams, compaction, presets, settings, themes, widgets, and Repo Lock.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|