@pickle-pee/runtime 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -0
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.js +10 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/kernel-session-adapter.d.ts +73 -0
- package/dist/adapters/kernel-session-adapter.js +10 -0
- package/dist/adapters/kernel-session-adapter.js.map +1 -0
- package/dist/adapters/pi-mono-event-bridge.d.ts +54 -0
- package/dist/adapters/pi-mono-event-bridge.js +159 -0
- package/dist/adapters/pi-mono-event-bridge.js.map +1 -0
- package/dist/adapters/pi-mono-session-adapter.d.ts +75 -0
- package/dist/adapters/pi-mono-session-adapter.js +490 -0
- package/dist/adapters/pi-mono-session-adapter.js.map +1 -0
- package/dist/create-app-runtime.d.ts +52 -0
- package/dist/create-app-runtime.js +163 -0
- package/dist/create-app-runtime.js.map +1 -0
- package/dist/domain/index.d.ts +1 -0
- package/dist/domain/index.js +5 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/events/event-bus.d.ts +23 -0
- package/dist/events/event-bus.js +85 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.js +6 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/runtime-event.d.ts +158 -0
- package/dist/events/runtime-event.js +13 -0
- package/dist/events/runtime-event.js.map +1 -0
- package/dist/governance/tool-governor.d.ts +63 -0
- package/dist/governance/tool-governor.js +639 -0
- package/dist/governance/tool-governor.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/planning/index.d.ts +6 -0
- package/dist/planning/index.js +16 -0
- package/dist/planning/index.js.map +1 -0
- package/dist/planning/plan-engine.d.ts +49 -0
- package/dist/planning/plan-engine.js +174 -0
- package/dist/planning/plan-engine.js.map +1 -0
- package/dist/planning/plan-events.d.ts +14 -0
- package/dist/planning/plan-events.js +94 -0
- package/dist/planning/plan-events.js.map +1 -0
- package/dist/planning/plan-orchestrator.d.ts +56 -0
- package/dist/planning/plan-orchestrator.js +167 -0
- package/dist/planning/plan-orchestrator.js.map +1 -0
- package/dist/planning/plan-types.d.ts +36 -0
- package/dist/planning/plan-types.js +9 -0
- package/dist/planning/plan-types.js.map +1 -0
- package/dist/runtime-context.d.ts +21 -0
- package/dist/runtime-context.js +37 -0
- package/dist/runtime-context.js.map +1 -0
- package/dist/services/event-normalizer.d.ts +22 -0
- package/dist/services/event-normalizer.js +162 -0
- package/dist/services/event-normalizer.js.map +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +7 -0
- package/dist/services/index.js.map +1 -0
- package/dist/session/session-events.d.ts +11 -0
- package/dist/session/session-events.js +52 -0
- package/dist/session/session-events.js.map +1 -0
- package/dist/session/session-facade.d.ts +88 -0
- package/dist/session/session-facade.js +439 -0
- package/dist/session/session-facade.js.map +1 -0
- package/dist/session/session-state.d.ts +14 -0
- package/dist/session/session-state.js +75 -0
- package/dist/session/session-state.js.map +1 -0
- package/dist/subagent/aggregation.d.ts +25 -0
- package/dist/subagent/aggregation.js +124 -0
- package/dist/subagent/aggregation.js.map +1 -0
- package/dist/subagent/index.d.ts +10 -0
- package/dist/subagent/index.js +29 -0
- package/dist/subagent/index.js.map +1 -0
- package/dist/subagent/path-scope.d.ts +24 -0
- package/dist/subagent/path-scope.js +86 -0
- package/dist/subagent/path-scope.js.map +1 -0
- package/dist/subagent/result-types.d.ts +61 -0
- package/dist/subagent/result-types.js +9 -0
- package/dist/subagent/result-types.js.map +1 -0
- package/dist/subagent/stop-condition.d.ts +34 -0
- package/dist/subagent/stop-condition.js +76 -0
- package/dist/subagent/stop-condition.js.map +1 -0
- package/dist/subagent/task-types.d.ts +48 -0
- package/dist/subagent/task-types.js +10 -0
- package/dist/subagent/task-types.js.map +1 -0
- package/dist/subagent/task-validator.d.ts +22 -0
- package/dist/subagent/task-validator.js +79 -0
- package/dist/subagent/task-validator.js.map +1 -0
- package/dist/subagent/verification.d.ts +22 -0
- package/dist/subagent/verification.js +55 -0
- package/dist/subagent/verification.js.map +1 -0
- package/dist/test/aggregation.test.d.ts +1 -0
- package/dist/test/aggregation.test.js +201 -0
- package/dist/test/aggregation.test.js.map +1 -0
- package/dist/test/create-app-runtime.test.d.ts +1 -0
- package/dist/test/create-app-runtime.test.js +286 -0
- package/dist/test/create-app-runtime.test.js.map +1 -0
- package/dist/test/event-bus.test.d.ts +1 -0
- package/dist/test/event-bus.test.js +81 -0
- package/dist/test/event-bus.test.js.map +1 -0
- package/dist/test/event-normalizer.test.d.ts +1 -0
- package/dist/test/event-normalizer.test.js +143 -0
- package/dist/test/event-normalizer.test.js.map +1 -0
- package/dist/test/path-scope.test.d.ts +1 -0
- package/dist/test/path-scope.test.js +71 -0
- package/dist/test/path-scope.test.js.map +1 -0
- package/dist/test/pi-mono-event-bridge.test.d.ts +1 -0
- package/dist/test/pi-mono-event-bridge.test.js +125 -0
- package/dist/test/pi-mono-event-bridge.test.js.map +1 -0
- package/dist/test/pi-mono-live.test.d.ts +1 -0
- package/dist/test/pi-mono-live.test.js +289 -0
- package/dist/test/pi-mono-live.test.js.map +1 -0
- package/dist/test/pi-mono-session-adapter.test.d.ts +1 -0
- package/dist/test/pi-mono-session-adapter.test.js +260 -0
- package/dist/test/pi-mono-session-adapter.test.js.map +1 -0
- package/dist/test/plan-engine.test.d.ts +1 -0
- package/dist/test/plan-engine.test.js +235 -0
- package/dist/test/plan-engine.test.js.map +1 -0
- package/dist/test/plan-events.test.d.ts +1 -0
- package/dist/test/plan-events.test.js +81 -0
- package/dist/test/plan-events.test.js.map +1 -0
- package/dist/test/plan-orchestrator.test.d.ts +1 -0
- package/dist/test/plan-orchestrator.test.js +324 -0
- package/dist/test/plan-orchestrator.test.js.map +1 -0
- package/dist/test/runtime-context.test.d.ts +1 -0
- package/dist/test/runtime-context.test.js +70 -0
- package/dist/test/runtime-context.test.js.map +1 -0
- package/dist/test/session-facade.test.d.ts +1 -0
- package/dist/test/session-facade.test.js +1011 -0
- package/dist/test/session-facade.test.js.map +1 -0
- package/dist/test/session-state.test.d.ts +1 -0
- package/dist/test/session-state.test.js +118 -0
- package/dist/test/session-state.test.js.map +1 -0
- package/dist/test/stop-condition.test.d.ts +1 -0
- package/dist/test/stop-condition.test.js +105 -0
- package/dist/test/stop-condition.test.js.map +1 -0
- package/dist/test/stubs/stub-kernel-session-adapter.d.ts +45 -0
- package/dist/test/stubs/stub-kernel-session-adapter.js +186 -0
- package/dist/test/stubs/stub-kernel-session-adapter.js.map +1 -0
- package/dist/test/task-validator.test.d.ts +1 -0
- package/dist/test/task-validator.test.js +97 -0
- package/dist/test/task-validator.test.js.map +1 -0
- package/dist/test/tool-governor.test.d.ts +1 -0
- package/dist/test/tool-governor.test.js +379 -0
- package/dist/test/tool-governor.test.js.map +1 -0
- package/dist/types/index.d.ts +77 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Main agent result aggregation and rework decision logic.
|
|
4
|
+
*
|
|
5
|
+
* Collects results from multiple subagent tasks, evaluates verification
|
|
6
|
+
* outcomes, and decides whether each task should be accepted, reworked,
|
|
7
|
+
* or abandoned.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.aggregateResults = aggregateResults;
|
|
11
|
+
exports.decideRework = decideRework;
|
|
12
|
+
const path_scope_js_1 = require("./path-scope.js");
|
|
13
|
+
const verification_js_1 = require("./verification.js");
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Aggregation
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/** Aggregate results from multiple completed subagent tasks. */
|
|
18
|
+
function aggregateResults(planId, results, reworkDecisionsInput) {
|
|
19
|
+
const allModifiedPaths = [];
|
|
20
|
+
const allRisks = [];
|
|
21
|
+
const reworkDecisions = reworkDecisionsInput ?? new Map();
|
|
22
|
+
let completedTasks = 0;
|
|
23
|
+
let failedTasks = 0;
|
|
24
|
+
for (const result of results) {
|
|
25
|
+
// Merge paths
|
|
26
|
+
allModifiedPaths.push(...result.modifiedPaths);
|
|
27
|
+
// Merge risks
|
|
28
|
+
allRisks.push(...result.risks);
|
|
29
|
+
// Count by final decision when available; otherwise fall back to raw status.
|
|
30
|
+
const finalDecision = reworkDecisions.get(result.taskId);
|
|
31
|
+
const accepted = finalDecision ? finalDecision.type === "accept" : result.status === "completed";
|
|
32
|
+
if (accepted) {
|
|
33
|
+
completedTasks++;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
failedTasks++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const tasksRequiringRework = [...reworkDecisions.values()].filter((d) => d.type === "rework").length;
|
|
40
|
+
return {
|
|
41
|
+
planId,
|
|
42
|
+
totalTasks: results.length,
|
|
43
|
+
completedTasks,
|
|
44
|
+
failedTasks,
|
|
45
|
+
tasksRequiringRework,
|
|
46
|
+
allModifiedPaths,
|
|
47
|
+
allRisks,
|
|
48
|
+
reworkDecisions,
|
|
49
|
+
completedAt: Date.now(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Rework decision
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Decide whether a task result needs rework, should be accepted, or abandoned.
|
|
57
|
+
*
|
|
58
|
+
* Decision matrix:
|
|
59
|
+
* completed + all verifications passed → accept
|
|
60
|
+
* completed + verification failures + rework → rework (focus: failed names)
|
|
61
|
+
* completed + verification failures + no rework → abandon
|
|
62
|
+
* boundary_violation → abandon
|
|
63
|
+
* failed + rework available → rework
|
|
64
|
+
* failed + no rework → abandon
|
|
65
|
+
* stop_condition_triggered + rework → rework
|
|
66
|
+
* stop_condition_triggered + no rework → abandon
|
|
67
|
+
*/
|
|
68
|
+
function decideRework(task, result, maxReworkAttempts, currentReworkCount) {
|
|
69
|
+
const canRework = currentReworkCount < maxReworkAttempts;
|
|
70
|
+
switch (result.status) {
|
|
71
|
+
case "completed": {
|
|
72
|
+
// Boundary check: verify all modified paths are within scope
|
|
73
|
+
const boundaryViolations = result.modifiedPaths.filter((p) => (0, path_scope_js_1.wouldViolateBoundary)(task.scope, p));
|
|
74
|
+
if (boundaryViolations.length > 0) {
|
|
75
|
+
if (canRework) {
|
|
76
|
+
return {
|
|
77
|
+
type: "rework",
|
|
78
|
+
reason: `Modified paths outside scope: ${boundaryViolations.join(", ")}`,
|
|
79
|
+
focusAreas: ["scope_compliance"],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
type: "abandon",
|
|
84
|
+
reason: `Boundary violation in modified paths (rework limit exceeded): ${boundaryViolations.join(", ")}`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const evaluation = (0, verification_js_1.evaluateVerifications)(task.verification, result.verifications);
|
|
88
|
+
if (evaluation.allPassed) {
|
|
89
|
+
return { type: "accept" };
|
|
90
|
+
}
|
|
91
|
+
if (canRework) {
|
|
92
|
+
return {
|
|
93
|
+
type: "rework",
|
|
94
|
+
reason: `Verification failures: ${evaluation.failedNames.join(", ")}`,
|
|
95
|
+
focusAreas: [...evaluation.failedNames],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return { type: "abandon", reason: "Rework limit exceeded — verification failures persist" };
|
|
99
|
+
}
|
|
100
|
+
case "boundary_violation":
|
|
101
|
+
return { type: "abandon", reason: "Boundary violation detected — subagent modified paths outside its scope" };
|
|
102
|
+
case "failed": {
|
|
103
|
+
if (canRework) {
|
|
104
|
+
return {
|
|
105
|
+
type: "rework",
|
|
106
|
+
reason: "Task execution failed",
|
|
107
|
+
focusAreas: [],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return { type: "abandon", reason: "Rework limit exceeded — task keeps failing" };
|
|
111
|
+
}
|
|
112
|
+
case "stop_condition_triggered": {
|
|
113
|
+
if (canRework) {
|
|
114
|
+
return {
|
|
115
|
+
type: "rework",
|
|
116
|
+
reason: "Stop condition was triggered",
|
|
117
|
+
focusAreas: [],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { type: "abandon", reason: "Rework limit exceeded — stop conditions keep triggering" };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=aggregation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregation.js","sourceRoot":"","sources":["../../src/subagent/aggregation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { aggregateResults, decideRework } from "./aggregation.js";
|
|
2
|
+
export { isPathAllowed, isPathForbidden, scopesOverlap, wouldViolateBoundary, } from "./path-scope.js";
|
|
3
|
+
export type { AggregationResult, ReworkDecision, SubagentResult, SubagentResultStatus, SubagentRuntimeSnapshot, TaskRisk, VerificationResult, } from "./result-types.js";
|
|
4
|
+
export type { StopConditionEvaluation, SubagentRuntimeState } from "./stop-condition.js";
|
|
5
|
+
export { createInitialRuntimeState, evaluateStopConditions, recordBoundaryViolation, recordError, recordModification, updateElapsedTime, } from "./stop-condition.js";
|
|
6
|
+
export type { PathScope, StopCondition, StopConditionType, SubagentTask, TaskInputs, Verification, VerificationType, } from "./task-types.js";
|
|
7
|
+
export type { ValidationResult } from "./task-validator.js";
|
|
8
|
+
export { hasConsistentScope, hasRequiredFields, validateTask } from "./task-validator.js";
|
|
9
|
+
export type { VerificationEvaluation } from "./verification.js";
|
|
10
|
+
export { evaluateVerifications, isVerificationTrustworthy } from "./verification.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// subagent/ — Subagent task contract, result delivery, validation, and aggregation.
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.isVerificationTrustworthy = exports.evaluateVerifications = exports.validateTask = exports.hasRequiredFields = exports.hasConsistentScope = exports.updateElapsedTime = exports.recordModification = exports.recordError = exports.recordBoundaryViolation = exports.evaluateStopConditions = exports.createInitialRuntimeState = exports.wouldViolateBoundary = exports.scopesOverlap = exports.isPathForbidden = exports.isPathAllowed = exports.decideRework = exports.aggregateResults = void 0;
|
|
5
|
+
// Aggregation
|
|
6
|
+
var aggregation_js_1 = require("./aggregation.js");
|
|
7
|
+
Object.defineProperty(exports, "aggregateResults", { enumerable: true, get: function () { return aggregation_js_1.aggregateResults; } });
|
|
8
|
+
Object.defineProperty(exports, "decideRework", { enumerable: true, get: function () { return aggregation_js_1.decideRework; } });
|
|
9
|
+
// Path scope
|
|
10
|
+
var path_scope_js_1 = require("./path-scope.js");
|
|
11
|
+
Object.defineProperty(exports, "isPathAllowed", { enumerable: true, get: function () { return path_scope_js_1.isPathAllowed; } });
|
|
12
|
+
Object.defineProperty(exports, "isPathForbidden", { enumerable: true, get: function () { return path_scope_js_1.isPathForbidden; } });
|
|
13
|
+
Object.defineProperty(exports, "scopesOverlap", { enumerable: true, get: function () { return path_scope_js_1.scopesOverlap; } });
|
|
14
|
+
Object.defineProperty(exports, "wouldViolateBoundary", { enumerable: true, get: function () { return path_scope_js_1.wouldViolateBoundary; } });
|
|
15
|
+
var stop_condition_js_1 = require("./stop-condition.js");
|
|
16
|
+
Object.defineProperty(exports, "createInitialRuntimeState", { enumerable: true, get: function () { return stop_condition_js_1.createInitialRuntimeState; } });
|
|
17
|
+
Object.defineProperty(exports, "evaluateStopConditions", { enumerable: true, get: function () { return stop_condition_js_1.evaluateStopConditions; } });
|
|
18
|
+
Object.defineProperty(exports, "recordBoundaryViolation", { enumerable: true, get: function () { return stop_condition_js_1.recordBoundaryViolation; } });
|
|
19
|
+
Object.defineProperty(exports, "recordError", { enumerable: true, get: function () { return stop_condition_js_1.recordError; } });
|
|
20
|
+
Object.defineProperty(exports, "recordModification", { enumerable: true, get: function () { return stop_condition_js_1.recordModification; } });
|
|
21
|
+
Object.defineProperty(exports, "updateElapsedTime", { enumerable: true, get: function () { return stop_condition_js_1.updateElapsedTime; } });
|
|
22
|
+
var task_validator_js_1 = require("./task-validator.js");
|
|
23
|
+
Object.defineProperty(exports, "hasConsistentScope", { enumerable: true, get: function () { return task_validator_js_1.hasConsistentScope; } });
|
|
24
|
+
Object.defineProperty(exports, "hasRequiredFields", { enumerable: true, get: function () { return task_validator_js_1.hasRequiredFields; } });
|
|
25
|
+
Object.defineProperty(exports, "validateTask", { enumerable: true, get: function () { return task_validator_js_1.validateTask; } });
|
|
26
|
+
var verification_js_1 = require("./verification.js");
|
|
27
|
+
Object.defineProperty(exports, "evaluateVerifications", { enumerable: true, get: function () { return verification_js_1.evaluateVerifications; } });
|
|
28
|
+
Object.defineProperty(exports, "isVerificationTrustworthy", { enumerable: true, get: function () { return verification_js_1.isVerificationTrustworthy; } });
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/subagent/index.ts"],"names":[],"mappings":";AAAA,oFAAoF;;;AAEpF,cAAc;AACd,mDAAkE;AAAzD,kHAAA,gBAAgB,OAAA;AAAE,8GAAA,YAAY,OAAA;AACvC,aAAa;AACb,iDAKyB;AAJxB,8GAAA,aAAa,OAAA;AACb,gHAAA,eAAe,OAAA;AACf,8GAAA,aAAa,OAAA;AACb,qHAAA,oBAAoB,OAAA;AAcrB,yDAO6B;AAN5B,8HAAA,yBAAyB,OAAA;AACzB,2HAAA,sBAAsB,OAAA;AACtB,4HAAA,uBAAuB,OAAA;AACvB,gHAAA,WAAW,OAAA;AACX,uHAAA,kBAAkB,OAAA;AAClB,sHAAA,iBAAiB,OAAA;AAclB,yDAA0F;AAAjF,uHAAA,kBAAkB,OAAA;AAAE,sHAAA,iBAAiB,OAAA;AAAE,iHAAA,YAAY,OAAA;AAG5D,qDAAqF;AAA5E,wHAAA,qBAAqB,OAAA;AAAE,4HAAA,yBAAyB,OAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path scope boundary checking.
|
|
3
|
+
*
|
|
4
|
+
* Uses normalize + prefix matching to determine whether a path falls within
|
|
5
|
+
* a subagent's allowed scope. Supports glob-style `/**` suffix to mean
|
|
6
|
+
* "this directory and everything below it".
|
|
7
|
+
*/
|
|
8
|
+
import type { PathScope } from "./task-types.js";
|
|
9
|
+
/** Check if a path is within the allowed scope of a task. */
|
|
10
|
+
export declare function isPathAllowed(scope: PathScope, filePath: string): boolean;
|
|
11
|
+
/** Check if a path is explicitly forbidden. */
|
|
12
|
+
export declare function isPathForbidden(scope: PathScope, filePath: string): boolean;
|
|
13
|
+
/** Check if a modification to a path would violate the task boundary. */
|
|
14
|
+
export declare function wouldViolateBoundary(scope: PathScope, filePath: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Check whether two path scopes share any allowed paths.
|
|
17
|
+
* Used to determine if two subagent tasks can safely run concurrently.
|
|
18
|
+
*/
|
|
19
|
+
export declare function scopesOverlap(a: PathScope, b: PathScope): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Check that allowedPaths and forbiddenPaths do not overlap.
|
|
22
|
+
* Returns true if the scope is consistent (no overlap).
|
|
23
|
+
*/
|
|
24
|
+
export declare function isScopeConsistent(scope: PathScope): boolean;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Path scope boundary checking.
|
|
4
|
+
*
|
|
5
|
+
* Uses normalize + prefix matching to determine whether a path falls within
|
|
6
|
+
* a subagent's allowed scope. Supports glob-style `/**` suffix to mean
|
|
7
|
+
* "this directory and everything below it".
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.isPathAllowed = isPathAllowed;
|
|
11
|
+
exports.isPathForbidden = isPathForbidden;
|
|
12
|
+
exports.wouldViolateBoundary = wouldViolateBoundary;
|
|
13
|
+
exports.scopesOverlap = scopesOverlap;
|
|
14
|
+
exports.isScopeConsistent = isScopeConsistent;
|
|
15
|
+
const node_path_1 = require("node:path");
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Internal: strip trailing /** for prefix matching
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Convert a scope pattern to a directory prefix for matching.
|
|
21
|
+
* `packages/app-runtime/**` → `packages/app-runtime`
|
|
22
|
+
* `packages/app-runtime` → `packages/app-runtime`
|
|
23
|
+
*/
|
|
24
|
+
function toPrefix(pattern) {
|
|
25
|
+
const norm = (0, node_path_1.normalize)(pattern);
|
|
26
|
+
if (norm.endsWith("/**") || norm.endsWith("/**")) {
|
|
27
|
+
return norm.slice(0, -3);
|
|
28
|
+
}
|
|
29
|
+
return norm;
|
|
30
|
+
}
|
|
31
|
+
/** Check if `filePath` is under or equal to `dirPrefix`. */
|
|
32
|
+
function isUnderPrefix(filePath, dirPrefix) {
|
|
33
|
+
return filePath === dirPrefix || filePath.startsWith(`${dirPrefix}/`);
|
|
34
|
+
}
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Single-path checks
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
/** Check if a path is within the allowed scope of a task. */
|
|
39
|
+
function isPathAllowed(scope, filePath) {
|
|
40
|
+
const normalized = (0, node_path_1.normalize)(filePath);
|
|
41
|
+
return scope.allowedPaths.some((allowed) => {
|
|
42
|
+
const prefix = toPrefix(allowed);
|
|
43
|
+
return isUnderPrefix(normalized, prefix);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/** Check if a path is explicitly forbidden. */
|
|
47
|
+
function isPathForbidden(scope, filePath) {
|
|
48
|
+
const normalized = (0, node_path_1.normalize)(filePath);
|
|
49
|
+
return scope.forbiddenPaths.some((forbidden) => {
|
|
50
|
+
const prefix = toPrefix(forbidden);
|
|
51
|
+
return isUnderPrefix(normalized, prefix);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/** Check if a modification to a path would violate the task boundary. */
|
|
55
|
+
function wouldViolateBoundary(scope, filePath) {
|
|
56
|
+
return !isPathAllowed(scope, filePath) || isPathForbidden(scope, filePath);
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Scope-pair checks
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
/**
|
|
62
|
+
* Check whether two path scopes share any allowed paths.
|
|
63
|
+
* Used to determine if two subagent tasks can safely run concurrently.
|
|
64
|
+
*/
|
|
65
|
+
function scopesOverlap(a, b) {
|
|
66
|
+
return a.allowedPaths.some((pathA) => b.allowedPaths.some((pathB) => {
|
|
67
|
+
const pA = toPrefix(pathA);
|
|
68
|
+
const pB = toPrefix(pathB);
|
|
69
|
+
return pA.startsWith(pB) || pB.startsWith(pA);
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// Internal
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
/**
|
|
76
|
+
* Check that allowedPaths and forbiddenPaths do not overlap.
|
|
77
|
+
* Returns true if the scope is consistent (no overlap).
|
|
78
|
+
*/
|
|
79
|
+
function isScopeConsistent(scope) {
|
|
80
|
+
return !scope.allowedPaths.some((allowed) => scope.forbiddenPaths.some((forbidden) => {
|
|
81
|
+
const pA = toPrefix(allowed);
|
|
82
|
+
const pF = toPrefix(forbidden);
|
|
83
|
+
return pA === pF || pA.startsWith(`${pF}/`) || pF.startsWith(`${pA}/`);
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=path-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-scope.js","sourceRoot":"","sources":["../../src/subagent/path-scope.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAgCH,sCAMC;AAGD,0CAMC;AAGD,oDAEC;AAUD,sCAQC;AAUD,8CAQC;AAtFD,yCAAsC;AAGtC,8EAA8E;AAC9E,mDAAmD;AACnD,8EAA8E;AAE9E;;;;GAIG;AACH,SAAS,QAAQ,CAAC,OAAe;IAChC,MAAM,IAAI,GAAG,IAAA,qBAAS,EAAC,OAAO,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,4DAA4D;AAC5D,SAAS,aAAa,CAAC,QAAgB,EAAE,SAAiB;IACzD,OAAO,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;AACvE,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,6DAA6D;AAC7D,SAAgB,aAAa,CAAC,KAAgB,EAAE,QAAgB;IAC/D,MAAM,UAAU,GAAG,IAAA,qBAAS,EAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjC,OAAO,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,+CAA+C;AAC/C,SAAgB,eAAe,CAAC,KAAgB,EAAE,QAAgB;IACjE,MAAM,UAAU,GAAG,IAAA,qBAAS,EAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAgB,oBAAoB,CAAC,KAAgB,EAAE,QAAgB;IACtE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC5E,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;GAGG;AACH,SAAgB,aAAa,CAAC,CAAY,EAAE,CAAY;IACvD,OAAO,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACpC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CACF,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,KAAgB;IACjD,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC3C,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;QACvC,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxE,CAAC,CAAC,CACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent result and aggregation types.
|
|
3
|
+
*
|
|
4
|
+
* Defines the structured schema for results delivered by subagents,
|
|
5
|
+
* rework decisions made by the reviewer, and aggregation of multi-task outcomes.
|
|
6
|
+
*/
|
|
7
|
+
/** Status of a completed subagent task. */
|
|
8
|
+
export type SubagentResultStatus = "completed" | "failed" | "boundary_violation" | "stop_condition_triggered";
|
|
9
|
+
/** Result of a single verification check. */
|
|
10
|
+
export interface VerificationResult {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly status: "passed" | "failed" | "error" | "skipped";
|
|
13
|
+
readonly output?: string;
|
|
14
|
+
readonly durationMs?: number;
|
|
15
|
+
}
|
|
16
|
+
/** Runtime counters reported by the subagent for stop-condition enforcement. */
|
|
17
|
+
export interface SubagentRuntimeSnapshot {
|
|
18
|
+
readonly elapsedMs?: number;
|
|
19
|
+
readonly errorCount?: number;
|
|
20
|
+
readonly boundaryViolations?: number;
|
|
21
|
+
}
|
|
22
|
+
/** A risk identified by the subagent or reviewer. */
|
|
23
|
+
export interface TaskRisk {
|
|
24
|
+
readonly severity: "low" | "medium" | "high";
|
|
25
|
+
readonly description: string;
|
|
26
|
+
readonly affectedPaths: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
/** The structured result delivered by a subagent upon task completion. */
|
|
29
|
+
export interface SubagentResult {
|
|
30
|
+
readonly taskId: string;
|
|
31
|
+
readonly status: SubagentResultStatus;
|
|
32
|
+
readonly modifiedPaths: readonly string[];
|
|
33
|
+
readonly verifications: readonly VerificationResult[];
|
|
34
|
+
readonly risks: readonly TaskRisk[];
|
|
35
|
+
readonly handoffNotes: readonly string[];
|
|
36
|
+
readonly runtime?: SubagentRuntimeSnapshot;
|
|
37
|
+
readonly completedAt: number;
|
|
38
|
+
}
|
|
39
|
+
/** The rework decision made by the reviewer / main agent. */
|
|
40
|
+
export type ReworkDecision = {
|
|
41
|
+
readonly type: "accept";
|
|
42
|
+
} | {
|
|
43
|
+
readonly type: "rework";
|
|
44
|
+
readonly reason: string;
|
|
45
|
+
readonly focusAreas: readonly string[];
|
|
46
|
+
} | {
|
|
47
|
+
readonly type: "abandon";
|
|
48
|
+
readonly reason: string;
|
|
49
|
+
};
|
|
50
|
+
/** The overall aggregation of multiple subagent task results. */
|
|
51
|
+
export interface AggregationResult {
|
|
52
|
+
readonly planId: string;
|
|
53
|
+
readonly totalTasks: number;
|
|
54
|
+
readonly completedTasks: number;
|
|
55
|
+
readonly failedTasks: number;
|
|
56
|
+
readonly tasksRequiringRework: number;
|
|
57
|
+
readonly allModifiedPaths: readonly string[];
|
|
58
|
+
readonly allRisks: readonly TaskRisk[];
|
|
59
|
+
readonly reworkDecisions: ReadonlyMap<string, ReworkDecision>;
|
|
60
|
+
readonly completedAt: number;
|
|
61
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Subagent result and aggregation types.
|
|
4
|
+
*
|
|
5
|
+
* Defines the structured schema for results delivered by subagents,
|
|
6
|
+
* rework decisions made by the reviewer, and aggregation of multi-task outcomes.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=result-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-types.js","sourceRoot":"","sources":["../../src/subagent/result-types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stop condition evaluation.
|
|
3
|
+
*
|
|
4
|
+
* Tracks runtime state for a subagent and evaluates whether any stop condition
|
|
5
|
+
* has been triggered. All state updates are immutable.
|
|
6
|
+
*/
|
|
7
|
+
import type { StopCondition } from "./task-types.js";
|
|
8
|
+
/** Runtime tracking state for evaluating stop conditions. */
|
|
9
|
+
export interface SubagentRuntimeState {
|
|
10
|
+
readonly modifiedPaths: readonly string[];
|
|
11
|
+
readonly elapsedMs: number;
|
|
12
|
+
readonly errorCount: number;
|
|
13
|
+
readonly boundaryViolations: number;
|
|
14
|
+
}
|
|
15
|
+
/** Result of evaluating stop conditions against current state. */
|
|
16
|
+
export interface StopConditionEvaluation {
|
|
17
|
+
readonly triggered: boolean;
|
|
18
|
+
readonly triggeredCondition?: StopCondition;
|
|
19
|
+
}
|
|
20
|
+
/** Create an initial runtime state with zero values. */
|
|
21
|
+
export declare function createInitialRuntimeState(): SubagentRuntimeState;
|
|
22
|
+
/** Record a file modification immutably. */
|
|
23
|
+
export declare function recordModification(state: SubagentRuntimeState, path: string): SubagentRuntimeState;
|
|
24
|
+
/** Record an error immutably. */
|
|
25
|
+
export declare function recordError(state: SubagentRuntimeState): SubagentRuntimeState;
|
|
26
|
+
/** Record a boundary violation immutably. */
|
|
27
|
+
export declare function recordBoundaryViolation(state: SubagentRuntimeState): SubagentRuntimeState;
|
|
28
|
+
/** Update elapsed time immutably. */
|
|
29
|
+
export declare function updateElapsedTime(state: SubagentRuntimeState, elapsedMs: number): SubagentRuntimeState;
|
|
30
|
+
/**
|
|
31
|
+
* Evaluate whether any stop condition has been triggered.
|
|
32
|
+
* Returns on the first triggered condition (first-match semantics).
|
|
33
|
+
*/
|
|
34
|
+
export declare function evaluateStopConditions(conditions: readonly StopCondition[], state: SubagentRuntimeState): StopConditionEvaluation;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Stop condition evaluation.
|
|
4
|
+
*
|
|
5
|
+
* Tracks runtime state for a subagent and evaluates whether any stop condition
|
|
6
|
+
* has been triggered. All state updates are immutable.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.createInitialRuntimeState = createInitialRuntimeState;
|
|
10
|
+
exports.recordModification = recordModification;
|
|
11
|
+
exports.recordError = recordError;
|
|
12
|
+
exports.recordBoundaryViolation = recordBoundaryViolation;
|
|
13
|
+
exports.updateElapsedTime = updateElapsedTime;
|
|
14
|
+
exports.evaluateStopConditions = evaluateStopConditions;
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Factory
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/** Create an initial runtime state with zero values. */
|
|
19
|
+
function createInitialRuntimeState() {
|
|
20
|
+
return { modifiedPaths: [], elapsedMs: 0, errorCount: 0, boundaryViolations: 0 };
|
|
21
|
+
}
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// State updaters — return new instances
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/** Record a file modification immutably. */
|
|
26
|
+
function recordModification(state, path) {
|
|
27
|
+
return { ...state, modifiedPaths: [...state.modifiedPaths, path] };
|
|
28
|
+
}
|
|
29
|
+
/** Record an error immutably. */
|
|
30
|
+
function recordError(state) {
|
|
31
|
+
return { ...state, errorCount: state.errorCount + 1 };
|
|
32
|
+
}
|
|
33
|
+
/** Record a boundary violation immutably. */
|
|
34
|
+
function recordBoundaryViolation(state) {
|
|
35
|
+
return { ...state, boundaryViolations: state.boundaryViolations + 1 };
|
|
36
|
+
}
|
|
37
|
+
/** Update elapsed time immutably. */
|
|
38
|
+
function updateElapsedTime(state, elapsedMs) {
|
|
39
|
+
return { ...state, elapsedMs };
|
|
40
|
+
}
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// Evaluation
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
/**
|
|
45
|
+
* Evaluate whether any stop condition has been triggered.
|
|
46
|
+
* Returns on the first triggered condition (first-match semantics).
|
|
47
|
+
*/
|
|
48
|
+
function evaluateStopConditions(conditions, state) {
|
|
49
|
+
for (const condition of conditions) {
|
|
50
|
+
if (isTriggered(condition, state)) {
|
|
51
|
+
return { triggered: true, triggeredCondition: condition };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return NOT_TRIGGERED;
|
|
55
|
+
}
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Internal
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
function isTriggered(condition, state) {
|
|
60
|
+
switch (condition.type) {
|
|
61
|
+
case "boundary_violation":
|
|
62
|
+
return state.boundaryViolations > 0;
|
|
63
|
+
case "max_duration_ms":
|
|
64
|
+
return typeof condition.value === "number" && state.elapsedMs >= condition.value;
|
|
65
|
+
case "max_file_count":
|
|
66
|
+
case "max_mutations":
|
|
67
|
+
return typeof condition.value === "number" && state.modifiedPaths.length >= condition.value;
|
|
68
|
+
case "error_threshold":
|
|
69
|
+
return typeof condition.value === "number" && state.errorCount >= condition.value;
|
|
70
|
+
case "custom":
|
|
71
|
+
// Reserved for P5+ — custom conditions require runtime hooks not yet available
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const NOT_TRIGGERED = Object.freeze({ triggered: false });
|
|
76
|
+
//# sourceMappingURL=stop-condition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-condition.js","sourceRoot":"","sources":["../../src/subagent/stop-condition.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA2BH,8DAEC;AAOD,gDAEC;AAGD,kCAEC;AAGD,0DAEC;AAGD,8CAEC;AAUD,wDAUC;AAnDD,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,wDAAwD;AACxD,SAAgB,yBAAyB;IACxC,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC;AAClF,CAAC;AAED,8EAA8E;AAC9E,wCAAwC;AACxC,8EAA8E;AAE9E,4CAA4C;AAC5C,SAAgB,kBAAkB,CAAC,KAA2B,EAAE,IAAY;IAC3E,OAAO,EAAE,GAAG,KAAK,EAAE,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,iCAAiC;AACjC,SAAgB,WAAW,CAAC,KAA2B;IACtD,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,6CAA6C;AAC7C,SAAgB,uBAAuB,CAAC,KAA2B;IAClE,OAAO,EAAE,GAAG,KAAK,EAAE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,GAAG,CAAC,EAAE,CAAC;AACvE,CAAC;AAED,qCAAqC;AACrC,SAAgB,iBAAiB,CAAC,KAA2B,EAAE,SAAiB;IAC/E,OAAO,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC;AAChC,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;GAGG;AACH,SAAgB,sBAAsB,CACrC,UAAoC,EACpC,KAA2B;IAE3B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE,CAAC;QAC3D,CAAC;IACF,CAAC;IACD,OAAO,aAAa,CAAC;AACtB,CAAC;AAED,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,SAAS,WAAW,CAAC,SAAwB,EAAE,KAA2B;IACzE,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,oBAAoB;YACxB,OAAO,KAAK,CAAC,kBAAkB,GAAG,CAAC,CAAC;QACrC,KAAK,iBAAiB;YACrB,OAAO,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,KAAK,CAAC;QAClF,KAAK,gBAAgB,CAAC;QACtB,KAAK,eAAe;YACnB,OAAO,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC;QAC7F,KAAK,iBAAiB;YACrB,OAAO,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC,KAAK,CAAC;QACnF,KAAK,QAAQ;YACZ,+EAA+E;YAC/E,OAAO,KAAK,CAAC;IACf,CAAC;AACF,CAAC;AAED,MAAM,aAAa,GAA4B,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent task contract types.
|
|
3
|
+
*
|
|
4
|
+
* Defines the structured schema for dispatching work to subagents.
|
|
5
|
+
* Every subagent task must specify scope, verification, and stop conditions —
|
|
6
|
+
* tasks missing these are considered unsafe and cannot be dispatched.
|
|
7
|
+
*/
|
|
8
|
+
/** Path scope boundaries for a subagent task. */
|
|
9
|
+
export interface PathScope {
|
|
10
|
+
/** Paths the subagent is allowed to read and modify. Must be non-empty. */
|
|
11
|
+
readonly allowedPaths: readonly string[];
|
|
12
|
+
/** Paths explicitly forbidden even if within allowedPaths. */
|
|
13
|
+
readonly forbiddenPaths: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
/** Input materials provided to a subagent. */
|
|
16
|
+
export interface TaskInputs {
|
|
17
|
+
readonly docs: readonly string[];
|
|
18
|
+
readonly files: readonly string[];
|
|
19
|
+
readonly assumptions: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
/** Verification type discriminator. */
|
|
22
|
+
export type VerificationType = "command" | "file_exists" | "no_errors" | "custom";
|
|
23
|
+
/** A single verification check for a subagent task. */
|
|
24
|
+
export interface Verification {
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly type: VerificationType;
|
|
27
|
+
readonly command?: string;
|
|
28
|
+
readonly expected?: string;
|
|
29
|
+
readonly description: string;
|
|
30
|
+
}
|
|
31
|
+
/** Stop condition type discriminator. */
|
|
32
|
+
export type StopConditionType = "boundary_violation" | "max_duration_ms" | "max_file_count" | "max_mutations" | "error_threshold" | "custom";
|
|
33
|
+
/** A condition under which the subagent must stop immediately. */
|
|
34
|
+
export interface StopCondition {
|
|
35
|
+
readonly type: StopConditionType;
|
|
36
|
+
readonly value?: number;
|
|
37
|
+
readonly description: string;
|
|
38
|
+
}
|
|
39
|
+
/** The complete subagent task contract — the input schema for dispatching work. */
|
|
40
|
+
export interface SubagentTask {
|
|
41
|
+
readonly taskId: string;
|
|
42
|
+
readonly goal: string;
|
|
43
|
+
readonly scope: PathScope;
|
|
44
|
+
readonly inputs: TaskInputs;
|
|
45
|
+
readonly deliverables: readonly string[];
|
|
46
|
+
readonly verification: readonly Verification[];
|
|
47
|
+
readonly stopConditions: readonly StopCondition[];
|
|
48
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Subagent task contract types.
|
|
4
|
+
*
|
|
5
|
+
* Defines the structured schema for dispatching work to subagents.
|
|
6
|
+
* Every subagent task must specify scope, verification, and stop conditions —
|
|
7
|
+
* tasks missing these are considered unsafe and cannot be dispatched.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=task-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-types.js","sourceRoot":"","sources":["../../src/subagent/task-types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task contract validation.
|
|
3
|
+
*
|
|
4
|
+
* Enforces the three mandatory rules from the subagent protocol:
|
|
5
|
+
* 1. No task without allowed_paths can be dispatched
|
|
6
|
+
* 2. No task without verification can be dispatched
|
|
7
|
+
* 3. No task without stop_conditions is considered safe
|
|
8
|
+
*
|
|
9
|
+
* Plus consistency checks: taskId/goal non-empty, no scope overlap.
|
|
10
|
+
*/
|
|
11
|
+
import type { PathScope, SubagentTask } from "./task-types.js";
|
|
12
|
+
/** Outcome of a validation check. */
|
|
13
|
+
export interface ValidationResult {
|
|
14
|
+
readonly valid: boolean;
|
|
15
|
+
readonly errors: readonly string[];
|
|
16
|
+
}
|
|
17
|
+
/** Validate that a task contract is complete and dispatchable. */
|
|
18
|
+
export declare function validateTask(task: SubagentTask): ValidationResult;
|
|
19
|
+
/** Check that allowedPaths and forbiddenPaths do not overlap. */
|
|
20
|
+
export declare function hasConsistentScope(scope: PathScope): ValidationResult;
|
|
21
|
+
/** Check required fields only (no scope consistency check). */
|
|
22
|
+
export declare function hasRequiredFields(task: SubagentTask): ValidationResult;
|