@mastra/factory 0.26.0-alpha.0 → 0.26.0-alpha.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.
- package/README.md +158 -57
- package/dist/auth.d.ts.map +1 -1
- package/dist/boards/card-facts.d.ts +5 -0
- package/dist/boards/card-facts.d.ts.map +1 -0
- package/dist/boards/card-facts.js +19 -0
- package/dist/boards/card-facts.js.map +1 -0
- package/dist/boards/define-board.d.ts +109 -13
- package/dist/boards/define-board.d.ts.map +1 -1
- package/dist/boards/define-board.js +163 -21
- package/dist/boards/define-board.js.map +1 -1
- package/dist/boards/index.d.ts +4 -3
- package/dist/boards/index.d.ts.map +1 -1
- package/dist/boards/index.js +3 -2
- package/dist/boards/index.js.map +1 -1
- package/dist/boards/legacy-plan-role.d.ts +14 -0
- package/dist/boards/legacy-plan-role.d.ts.map +1 -0
- package/dist/boards/legacy-plan-role.js +32 -0
- package/dist/boards/legacy-plan-role.js.map +1 -0
- package/dist/boards/phase-automation.d.ts +13 -0
- package/dist/boards/phase-automation.d.ts.map +1 -0
- package/dist/boards/phase-automation.js +25 -0
- package/dist/boards/phase-automation.js.map +1 -0
- package/dist/boards/phase-runner.d.ts +13 -0
- package/dist/boards/phase-runner.d.ts.map +1 -0
- package/dist/boards/phase-runner.js +44 -0
- package/dist/boards/phase-runner.js.map +1 -0
- package/dist/boards/relocate.d.ts.map +1 -1
- package/dist/boards/relocate.js +2 -0
- package/dist/boards/relocate.js.map +1 -1
- package/dist/boards/review.d.ts +1 -1
- package/dist/boards/review.d.ts.map +1 -1
- package/dist/boards/review.js +18 -18
- package/dist/boards/review.js.map +1 -1
- package/dist/boards/semantics.d.ts.map +1 -1
- package/dist/boards/semantics.js +11 -7
- package/dist/boards/semantics.js.map +1 -1
- package/dist/boards/transition-policy.d.ts +10 -10
- package/dist/boards/work-tool-rules.d.ts +3 -3
- package/dist/boards/work-tool-rules.d.ts.map +1 -1
- package/dist/boards/work-tool-rules.js +1 -1
- package/dist/boards/work-tool-rules.js.map +1 -1
- package/dist/boards/work.d.ts +3 -3
- package/dist/boards/work.d.ts.map +1 -1
- package/dist/boards/work.js +31 -29
- package/dist/boards/work.js.map +1 -1
- package/dist/environment/build-runner.d.ts +4 -4
- package/dist/environment/build-runner.d.ts.map +1 -1
- package/dist/environment/build-workflow.d.ts +6 -6
- package/dist/environment/build-workflow.js +1 -1
- package/dist/environment/build.d.ts +1 -1
- package/dist/environment/build.d.ts.map +1 -1
- package/dist/factory.d.ts +8 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +6 -0
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/integrations/github/app-identity.d.ts.map +1 -1
- package/dist/integrations/github/default-rules.d.ts +71 -71
- package/dist/integrations/github/default-rules.d.ts.map +1 -1
- package/dist/integrations/github/integration.d.ts.map +1 -1
- package/dist/integrations/github/reconcile-worker.d.ts.map +1 -1
- package/dist/integrations/github/rules.d.ts.map +1 -1
- package/dist/integrations/github/sandbox.d.ts.map +1 -1
- package/dist/integrations/gitlab/api.d.ts.map +1 -1
- package/dist/integrations/gitlab/default-rules.d.ts +38 -38
- package/dist/integrations/gitlab/default-rules.d.ts.map +1 -1
- package/dist/integrations/gitlab/integration.d.ts.map +1 -1
- package/dist/integrations/gitlab/rules.d.ts.map +1 -1
- package/dist/integrations/incidentio/api.d.ts.map +1 -1
- package/dist/integrations/incidentio/default-rules.d.ts +3 -3
- package/dist/integrations/incidentio/default-rules.d.ts.map +1 -1
- package/dist/integrations/incidentio/integration.d.ts.map +1 -1
- package/dist/integrations/incidentio/rules.d.ts.map +1 -1
- package/dist/integrations/issue-reconcile-worker.d.ts.map +1 -1
- package/dist/integrations/jira/api.d.ts +1 -1
- package/dist/integrations/jira/api.d.ts.map +1 -1
- package/dist/integrations/jira/default-rules.d.ts +3 -3
- package/dist/integrations/jira/default-rules.d.ts.map +1 -1
- package/dist/integrations/jira/integration.d.ts.map +1 -1
- package/dist/integrations/jira/rules.d.ts.map +1 -1
- package/dist/integrations/linear/default-rules.d.ts +8 -8
- package/dist/integrations/linear/default-rules.d.ts.map +1 -1
- package/dist/integrations/linear/integration.d.ts.map +1 -1
- package/dist/integrations/linear/rules.d.ts.map +1 -1
- package/dist/integrations/platform/api-client.d.ts.map +1 -1
- package/dist/integrations/platform/github/event-worker.d.ts.map +1 -1
- package/dist/integrations/platform/github/integration.d.ts.map +1 -1
- package/dist/integrations/platform/gitlab/event-worker.d.ts.map +1 -1
- package/dist/integrations/platform/gitlab/integration.d.ts.map +1 -1
- package/dist/integrations/platform/incidentio/integration.d.ts.map +1 -1
- package/dist/integrations/platform/jira/integration.d.ts.map +1 -1
- package/dist/integrations/platform/linear/event-worker.d.ts.map +1 -1
- package/dist/integrations/platform/linear/integration.d.ts.map +1 -1
- package/dist/integrations/slack/channel-reply-processor.d.ts.map +1 -1
- package/dist/integrations/slack/channel-session-link-processor.d.ts.map +1 -1
- package/dist/integrations/slack/feed-publisher.d.ts.map +1 -1
- package/dist/integrations/slack/integration.d.ts.map +1 -1
- package/dist/integrations/slack/reply-reminder-processor.d.ts.map +1 -1
- package/dist/integrations/slack/reply-tool.d.ts.map +1 -1
- package/dist/integrations/slack/slack.d.ts.map +1 -1
- package/dist/integrations/workos/integration.d.ts.map +1 -1
- package/dist/mcp/events.d.ts +3 -3
- package/dist/mcp/routes.js +1 -1
- package/dist/routes/attention-activity.d.ts +1 -1
- package/dist/routes/attention-activity.d.ts.map +1 -1
- package/dist/routes/attention-parked.d.ts +1 -1
- package/dist/routes/attention-parked.d.ts.map +1 -1
- package/dist/routes/attention-providers.d.ts +1 -1
- package/dist/routes/attention-providers.d.ts.map +1 -1
- package/dist/routes/automation-runs.d.ts.map +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/contracts.d.ts +159 -136
- package/dist/routes/contracts.d.ts.map +1 -1
- package/dist/routes/contracts.js +23 -0
- package/dist/routes/contracts.js.map +1 -1
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +24 -0
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/intake.d.ts.map +1 -1
- package/dist/routes/knowledge.d.ts.map +1 -1
- package/dist/routes/oauth.d.ts.map +1 -1
- package/dist/routes/projects.d.ts.map +1 -1
- package/dist/routes/route.d.ts.map +1 -1
- package/dist/routes/skills.d.ts +3 -0
- package/dist/routes/skills.d.ts.map +1 -1
- package/dist/routes/skills.js +1 -1
- package/dist/routes/skills.js.map +1 -1
- package/dist/routes/surface.d.ts +3 -0
- package/dist/routes/surface.d.ts.map +1 -1
- package/dist/routes/surface.js +23 -22
- package/dist/routes/surface.js.map +1 -1
- package/dist/routes/telemetry.d.ts.map +1 -1
- package/dist/routes/tenant-credentials.d.ts.map +1 -1
- package/dist/routes/work-items.d.ts.map +1 -1
- package/dist/routes/work-items.js +19 -3
- package/dist/routes/work-items.js.map +1 -1
- package/dist/rules/decision-applicability.d.ts.map +1 -1
- package/dist/rules/decision-applicability.js +3 -1
- package/dist/rules/decision-applicability.js.map +1 -1
- package/dist/rules/dispatch-errors.d.ts.map +1 -1
- package/dist/rules/dispatcher.d.ts.map +1 -1
- package/dist/rules/dispatcher.js +17 -3
- package/dist/rules/dispatcher.js.map +1 -1
- package/dist/rules/processor.d.ts.map +1 -1
- package/dist/rules/processor.js +4 -2
- package/dist/rules/processor.js.map +1 -1
- package/dist/rules/rule-group.d.ts +29 -0
- package/dist/rules/rule-group.d.ts.map +1 -0
- package/dist/rules/rule-group.js +141 -0
- package/dist/rules/rule-group.js.map +1 -0
- package/dist/rules/start-coordinator.d.ts.map +1 -1
- package/dist/rules/terminal-cleanup.d.ts.map +1 -1
- package/dist/rules/tools.d.ts +1 -1
- package/dist/rules/tools.d.ts.map +1 -1
- package/dist/rules/transition-service.d.ts.map +1 -1
- package/dist/rules/transition-service.js +5 -3
- package/dist/rules/transition-service.js.map +1 -1
- package/dist/rules/types.d.ts +25 -14
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/types.js.map +1 -1
- package/dist/rules/validation.d.ts +2 -0
- package/dist/rules/validation.d.ts.map +1 -1
- package/dist/rules/validation.js +6 -3
- package/dist/rules/validation.js.map +1 -1
- package/dist/sandbox/callback-factory-sandbox.d.ts.map +1 -1
- package/dist/sandbox/local-factory-sandbox.d.ts.map +1 -1
- package/dist/sandbox/session-retirement.d.ts.map +1 -1
- package/dist/session/environment-state-processor.d.ts.map +1 -1
- package/dist/session/factory-session.d.ts.map +1 -1
- package/dist/session/live-sessions.d.ts.map +1 -1
- package/dist/session/reply-credential-processor.d.ts.map +1 -1
- package/dist/session/run-audit.d.ts +1 -1
- package/dist/session/run-audit.d.ts.map +1 -1
- package/dist/skills/app-skills.d.ts +11 -0
- package/dist/skills/app-skills.d.ts.map +1 -0
- package/dist/skills/app-skills.js +37 -0
- package/dist/skills/app-skills.js.map +1 -0
- package/dist/skills/catalog.d.ts +9 -3
- package/dist/skills/catalog.d.ts.map +1 -1
- package/dist/skills/catalog.js +35 -19
- package/dist/skills/catalog.js.map +1 -1
- package/dist/skills/service.d.ts.map +1 -1
- package/dist/spa-static.d.ts.map +1 -1
- package/dist/storage/domains/audit/actions.d.ts +6 -6
- package/dist/storage/domains/audit/actions.d.ts.map +1 -1
- package/dist/storage/domains/audit/actors.d.ts +1 -1
- package/dist/storage/domains/audit/actors.d.ts.map +1 -1
- package/dist/storage/domains/audit/base.d.ts.map +1 -1
- package/dist/storage/domains/audit/domain.d.ts.map +1 -1
- package/dist/storage/domains/channel-identity/base.d.ts.map +1 -1
- package/dist/storage/domains/comments/base.d.ts.map +1 -1
- package/dist/storage/domains/comments/domain.d.ts.map +1 -1
- package/dist/storage/domains/comments/feed-context.d.ts.map +1 -1
- package/dist/storage/domains/credentials/base.d.ts.map +1 -1
- package/dist/storage/domains/custom-providers/base.d.ts.map +1 -1
- package/dist/storage/domains/filesystem/base.d.ts.map +1 -1
- package/dist/storage/domains/intake/base.d.ts.map +1 -1
- package/dist/storage/domains/integrations/base.d.ts.map +1 -1
- package/dist/storage/domains/memory-settings/base.d.ts.map +1 -1
- package/dist/storage/domains/model-defaults/base.d.ts.map +1 -1
- package/dist/storage/domains/projects/base.d.ts +1 -1
- package/dist/storage/domains/projects/base.d.ts.map +1 -1
- package/dist/storage/domains/queue-health/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/base.d.ts.map +1 -1
- package/dist/storage/domains/source-control/inmemory.d.ts +5 -5
- package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
- package/dist/storage/domains/work-items/base.d.ts +1 -1
- package/dist/storage/domains/work-items/base.d.ts.map +1 -1
- package/dist/storage/domains/work-items/board-version.d.ts.map +1 -1
- package/dist/telemetry-types.d.ts +1 -1
- package/dist/telemetry-types.d.ts.map +1 -1
- package/dist/timing.d.ts.map +1 -1
- package/dist/tools/session-tools.d.ts.map +1 -1
- package/dist/tools/session-tools.js +3 -1
- package/dist/tools/session-tools.js.map +1 -1
- package/dist/tools/sessions-state-processor.d.ts.map +1 -1
- package/dist/tools/work-item-tools.js +1 -1
- package/dist/workspace.d.ts +13 -6
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +66 -14
- package/dist/workspace.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-board.d.ts","sourceRoot":"","sources":["../../src/boards/define-board.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define-board.d.ts","sourceRoot":"","sources":["../../src/boards/define-board.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { cardRuleGroupSchema, evaluateRuleGroup } from "../rules/rule-group.js";
|
|
2
|
+
import { FACTORY_GITHUB_EVENTS, FACTORY_GITLAB_EVENTS, FACTORY_INCIDENTIO_EVENTS, FACTORY_JIRA_EVENTS, FACTORY_LINEAR_EVENTS, FACTORY_RULE_SOURCES } from "../rules/types.js";
|
|
3
|
+
import { IDENTIFIER_RE, SKILL_NAME_RE, isBoardIdentifier } from "../rules/validation.js";
|
|
4
|
+
import { addInstructions, startSkill } from "./phase-runner.js";
|
|
5
|
+
import { CODE_AGENT_ID } from "@mastra/code-sdk/constants";
|
|
3
6
|
// src/boards/define-board.ts
|
|
4
7
|
const BOARD_EVENT_NAMES = {
|
|
5
8
|
github: FACTORY_GITHUB_EVENTS,
|
|
@@ -8,6 +11,10 @@ const BOARD_EVENT_NAMES = {
|
|
|
8
11
|
jira: FACTORY_JIRA_EVENTS,
|
|
9
12
|
incidentio: FACTORY_INCIDENTIO_EVENTS
|
|
10
13
|
};
|
|
14
|
+
/** The agent Factory runs every phase with. */
|
|
15
|
+
const FACTORY_AGENT_ID = CODE_AGENT_ID;
|
|
16
|
+
/** The session context a working phase runs in when it names none. */
|
|
17
|
+
const DEFAULT_PHASE_CONTEXT = "work";
|
|
11
18
|
var BoardDefinitionError = class extends Error {
|
|
12
19
|
name = "BoardDefinitionError";
|
|
13
20
|
};
|
|
@@ -19,12 +26,88 @@ const PHASE_KINDS = /* @__PURE__ */ new Set([
|
|
|
19
26
|
function validateBoardIdentifier(value, label) {
|
|
20
27
|
if (!isBoardIdentifier(value)) throw new BoardDefinitionError(`${label} must be a valid board identifier.`);
|
|
21
28
|
}
|
|
29
|
+
const MAX_NAME_LENGTH = 128;
|
|
30
|
+
const MAX_DESCRIPTION_LENGTH = 2e3;
|
|
31
|
+
const MAX_INSTRUCTIONS_LENGTH = 1e3;
|
|
32
|
+
const RUNNER_KEYS = /* @__PURE__ */ new Set([
|
|
33
|
+
"agentId",
|
|
34
|
+
"skill",
|
|
35
|
+
"context",
|
|
36
|
+
"instructions"
|
|
37
|
+
]);
|
|
38
|
+
const EXIT_TOOL_KEYS = /* @__PURE__ */ new Set([
|
|
39
|
+
"id",
|
|
40
|
+
"autoApprove",
|
|
41
|
+
"autoApproveWhen"
|
|
42
|
+
]);
|
|
43
|
+
const WORKING_ONLY_FIELDS = [
|
|
44
|
+
"runner",
|
|
45
|
+
"autoStart",
|
|
46
|
+
"autoStartWhen",
|
|
47
|
+
"exitTool"
|
|
48
|
+
];
|
|
49
|
+
const MOVE_TOOL = "factory_transition_work_item";
|
|
50
|
+
/** `name`, falling back to the deprecated `title`; both may be set only to the same text. */
|
|
51
|
+
function resolveName(name, title, label) {
|
|
52
|
+
if (name !== void 0 && title !== void 0 && name !== title) throw new BoardDefinitionError(`${label} sets both name and title; drop the deprecated title.`);
|
|
53
|
+
const value = name ?? title;
|
|
54
|
+
if (typeof value !== "string" || value.trim().length === 0 || value.length > MAX_NAME_LENGTH) throw new BoardDefinitionError(`${label} must declare a name.`);
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function optionalText(value, label, max) {
|
|
58
|
+
if (value === void 0) return void 0;
|
|
59
|
+
if (typeof value !== "string" || value.trim().length === 0 || value.length > max) throw new BoardDefinitionError(`${label} must be non-empty text of at most ${max} characters.`);
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
function ruleGroup(value, label) {
|
|
63
|
+
if (value === void 0) return void 0;
|
|
64
|
+
const parsed = cardRuleGroupSchema.safeParse(value);
|
|
65
|
+
if (!parsed.success) throw new BoardDefinitionError(`${label} is not a valid condition: ${parsed.error.issues[0]?.message}`);
|
|
66
|
+
return parsed.data;
|
|
67
|
+
}
|
|
68
|
+
function isContext(value) {
|
|
69
|
+
return typeof value === "string" && value.length > 0 && value.length <= 32 && IDENTIFIER_RE.test(value);
|
|
70
|
+
}
|
|
71
|
+
function resolveRunner(phaseId, phase) {
|
|
72
|
+
const runner = phase.runner ?? {};
|
|
73
|
+
if (!isPlainObject(runner) || Object.keys(runner).some((key) => !RUNNER_KEYS.has(key))) throw new BoardDefinitionError(`Phase "${phaseId}" runner may only set agentId, skill, context and instructions.`);
|
|
74
|
+
const role = phase.role;
|
|
75
|
+
if (role !== void 0 && runner.context !== void 0 && role !== runner.context) throw new BoardDefinitionError(`Phase "${phaseId}" sets both role and runner.context; drop the deprecated role.`);
|
|
76
|
+
const context = runner.context ?? role ?? "work";
|
|
77
|
+
if (!isContext(context)) throw new BoardDefinitionError(`Working phase "${phaseId}" must declare a valid context.`);
|
|
78
|
+
const agentId = runner.agentId ?? FACTORY_AGENT_ID;
|
|
79
|
+
if (agentId !== FACTORY_AGENT_ID) throw new BoardDefinitionError(`Phase "${phaseId}" names unknown agent "${String(agentId)}"; Factory runs "${FACTORY_AGENT_ID}".`);
|
|
80
|
+
const skill = runner.skill;
|
|
81
|
+
if (skill !== void 0 && (typeof skill !== "string" || skill.length > 128 || !SKILL_NAME_RE.test(skill))) throw new BoardDefinitionError(`Phase "${phaseId}" runner.skill must be a skill name.`);
|
|
82
|
+
const instructions = optionalText(runner.instructions, `Phase "${phaseId}" runner.instructions`, MAX_INSTRUCTIONS_LENGTH);
|
|
83
|
+
return Object.freeze({
|
|
84
|
+
agentId,
|
|
85
|
+
context,
|
|
86
|
+
...skill !== void 0 ? { skill } : {},
|
|
87
|
+
...instructions !== void 0 ? { instructions } : {}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function resolveExitTool(phaseId, value) {
|
|
91
|
+
if (value === void 0) return void 0;
|
|
92
|
+
const declared = typeof value === "string" ? { id: value } : value;
|
|
93
|
+
if (!isPlainObject(declared) || Object.keys(declared).some((key) => !EXIT_TOOL_KEYS.has(key))) throw new BoardDefinitionError(`Phase "${phaseId}" exitTool must be a tool name or { id, autoApprove, autoApproveWhen }.`);
|
|
94
|
+
const { id, autoApprove = false } = declared;
|
|
95
|
+
if (typeof id !== "string" || id.length === 0 || id.length > 128 || !IDENTIFIER_RE.test(id)) throw new BoardDefinitionError(`Phase "${phaseId}" exitTool has an invalid tool name.`);
|
|
96
|
+
if (id === MOVE_TOOL) throw new BoardDefinitionError(`Phase "${phaseId}" cannot end with ${MOVE_TOOL}: that tool already moves the card.`);
|
|
97
|
+
if (typeof autoApprove !== "boolean") throw new BoardDefinitionError(`Phase "${phaseId}" exitTool.autoApprove must be a boolean.`);
|
|
98
|
+
const autoApproveWhen = ruleGroup(declared.autoApproveWhen, `Phase "${phaseId}" exitTool.autoApproveWhen`);
|
|
99
|
+
if (autoApproveWhen && !autoApprove) throw new BoardDefinitionError(`Phase "${phaseId}" exitTool.autoApproveWhen needs autoApprove.`);
|
|
100
|
+
return Object.freeze({
|
|
101
|
+
id,
|
|
102
|
+
autoApprove,
|
|
103
|
+
...autoApproveWhen ? { autoApproveWhen } : {}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
22
106
|
function validatePhaseSemantics(phaseId, phase) {
|
|
23
107
|
if (!PHASE_KINDS.has(phase.kind)) throw new BoardDefinitionError(`Phase "${phaseId}" must declare kind 'resting', 'working', or 'terminal'.`);
|
|
24
|
-
if (phase.kind === "working")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
} else if (phase.role !== void 0) throw new BoardDefinitionError(`Phase "${phaseId}" is ${phase.kind} and cannot declare a role.`);
|
|
108
|
+
if (phase.kind === "working") return;
|
|
109
|
+
if (phase.role !== void 0) throw new BoardDefinitionError(`Phase "${phaseId}" is ${phase.kind} and cannot declare a role.`);
|
|
110
|
+
for (const field of WORKING_ONLY_FIELDS) if (phase[field] !== void 0) throw new BoardDefinitionError(`Phase "${phaseId}" is ${phase.kind} and cannot declare ${field}.`);
|
|
28
111
|
}
|
|
29
112
|
function isPlainObject(value) {
|
|
30
113
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
@@ -77,8 +160,36 @@ function validateEventRules(events) {
|
|
|
77
160
|
}
|
|
78
161
|
return Object.freeze(frozen);
|
|
79
162
|
}
|
|
163
|
+
/** The phase's `onEnter` handlers, with its runner's skill for other sources and its instructions on every run. */
|
|
164
|
+
function phaseEnterHandlers(declared, runner) {
|
|
165
|
+
const handlers = { ...declared };
|
|
166
|
+
if (runner.skill) for (const source of FACTORY_RULE_SOURCES) handlers[source] ??= startSkill(runner.skill, runner.context);
|
|
167
|
+
if (runner.instructions) for (const source of Object.keys(handlers)) handlers[source] = addInstructions(handlers[source], runner.instructions);
|
|
168
|
+
return Object.keys(handlers).length > 0 ? handlers : void 0;
|
|
169
|
+
}
|
|
170
|
+
const warnedBoards = /* @__PURE__ */ new Set();
|
|
171
|
+
/** Deprecated fields a board declaration still uses; `defineBoard()` maps each to its replacement. */
|
|
172
|
+
function deprecatedFields(config) {
|
|
173
|
+
const found = [];
|
|
174
|
+
if (config.title !== void 0) found.push("title → name");
|
|
175
|
+
for (const [phaseId, phase] of Object.entries(config.phases)) {
|
|
176
|
+
if (phase.title !== void 0) found.push(`phases.${phaseId}.title → name`);
|
|
177
|
+
if (phase.next !== void 0) found.push(`phases.${phaseId}.next → nextPhases`);
|
|
178
|
+
if (phase.role !== void 0) found.push(`phases.${phaseId}.role → runner.context`);
|
|
179
|
+
}
|
|
180
|
+
return found;
|
|
181
|
+
}
|
|
182
|
+
function warnDeprecatedFields(config) {
|
|
183
|
+
if (warnedBoards.has(config.id)) return;
|
|
184
|
+
const found = deprecatedFields(config);
|
|
185
|
+
if (found.length === 0) return;
|
|
186
|
+
warnedBoards.add(config.id);
|
|
187
|
+
console.warn(`[Mastra Factory] Board "${config.id}" uses deprecated fields: ${found.join(", ")}. They still work but will be removed in a future release.`);
|
|
188
|
+
}
|
|
80
189
|
function defineBoard(config) {
|
|
81
190
|
validateBoardIdentifier(config.id, "Board id");
|
|
191
|
+
const boardName = resolveName(config.name, config.title, `Board "${config.id}"`);
|
|
192
|
+
const boardDescription = optionalText(config.description, `Board "${config.id}" description`, MAX_DESCRIPTION_LENGTH);
|
|
82
193
|
if (config.transitionPolicy !== void 0 && typeof config.transitionPolicy !== "function") throw new BoardDefinitionError("Board transitionPolicy must be a function.");
|
|
83
194
|
const tools = validateToolRules(config.tools);
|
|
84
195
|
const events = validateEventRules(config.events);
|
|
@@ -90,9 +201,11 @@ function defineBoard(config) {
|
|
|
90
201
|
validatePhaseSemantics(phaseId, phase);
|
|
91
202
|
}
|
|
92
203
|
if (config.phases[config.initialPhase].kind !== "resting") throw new BoardDefinitionError(`Initial phase "${config.initialPhase}" must be a resting phase.`);
|
|
204
|
+
warnDeprecatedFields(config);
|
|
93
205
|
const sourceClosed = validateSourceClosed(config.sourceClosed, config.phases);
|
|
94
206
|
const transitions = Object.fromEntries(Object.entries(config.phases).map(([phaseId, phase]) => {
|
|
95
207
|
if (phase.next !== void 0 && phase.outcomes) throw new BoardDefinitionError(`Phase "${phaseId}" cannot define both next and outcomes.`);
|
|
208
|
+
if (phase.nextPhases !== void 0 && !Array.isArray(phase.nextPhases)) throw new BoardDefinitionError(`Phase "${phaseId}" nextPhases must be a list of phases.`);
|
|
96
209
|
const targets = phase.next !== void 0 ? [Object.freeze({
|
|
97
210
|
outcome: null,
|
|
98
211
|
to: phase.next
|
|
@@ -100,19 +213,41 @@ function defineBoard(config) {
|
|
|
100
213
|
outcome,
|
|
101
214
|
to
|
|
102
215
|
}));
|
|
216
|
+
for (const to of phase.nextPhases ?? []) if (!targets.some((target) => target.to === to)) targets.push(Object.freeze({
|
|
217
|
+
outcome: null,
|
|
218
|
+
to
|
|
219
|
+
}));
|
|
103
220
|
for (const { to } of targets) if (!phaseIds.has(to)) throw new BoardDefinitionError(`Phase "${phaseId}" targets undefined phase "${to}".`);
|
|
104
221
|
return [phaseId, Object.freeze(targets)];
|
|
105
222
|
}));
|
|
106
|
-
const phases = Object.freeze(Object.fromEntries(Object.entries(config.phases).map(([phaseId, phase]) =>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
223
|
+
const phases = Object.freeze(Object.fromEntries(Object.entries(config.phases).map(([phaseId, phase]) => {
|
|
224
|
+
const label = `Phase "${phaseId}"`;
|
|
225
|
+
const nextPhases = Object.freeze([.../* @__PURE__ */ new Set([...phase.nextPhases ?? [], ...transitions[phaseId].map(({ to }) => to)])]);
|
|
226
|
+
const runner = phase.kind === "working" ? resolveRunner(phaseId, phase) : void 0;
|
|
227
|
+
const working = phase.kind === "working" ? phase : void 0;
|
|
228
|
+
if (working?.autoStart !== void 0 && typeof working.autoStart !== "boolean") throw new BoardDefinitionError(`${label} autoStart must be a boolean.`);
|
|
229
|
+
const autoStartWhen = ruleGroup(working?.autoStartWhen, `${label} autoStartWhen`);
|
|
230
|
+
if (autoStartWhen && working?.autoStart !== true) throw new BoardDefinitionError(`${label} autoStartWhen needs autoStart.`);
|
|
231
|
+
const exitTool = resolveExitTool(phaseId, working?.exitTool);
|
|
232
|
+
if (exitTool && nextPhases.length === 0) throw new BoardDefinitionError(`${label} exit tool needs a next phase to move the card to.`);
|
|
233
|
+
const onEnter = runner ? phaseEnterHandlers(phase.onEnter, runner) : phase.onEnter;
|
|
234
|
+
const name = resolveName(phase.name, phase.title, label);
|
|
235
|
+
const description = optionalText(phase.description, `${label} description`, MAX_DESCRIPTION_LENGTH);
|
|
236
|
+
return [phaseId, Object.freeze({
|
|
237
|
+
name,
|
|
238
|
+
...description !== void 0 ? { description } : {},
|
|
239
|
+
kind: phase.kind,
|
|
240
|
+
nextPhases,
|
|
241
|
+
...phase.outcomes ? { outcomes: Object.freeze({ ...phase.outcomes }) } : {},
|
|
242
|
+
...runner ? { runner } : {},
|
|
243
|
+
...working?.autoStart ? { autoStart: true } : {},
|
|
244
|
+
...autoStartWhen ? { autoStartWhen } : {},
|
|
245
|
+
...exitTool ? { exitTool } : {},
|
|
246
|
+
...onEnter ? { onEnter: Object.freeze({ ...onEnter }) } : {},
|
|
247
|
+
...phase.onExit ? { onExit: Object.freeze({ ...phase.onExit }) } : {}
|
|
248
|
+
})];
|
|
249
|
+
})));
|
|
250
|
+
const rules = Object.freeze(Object.fromEntries(Object.entries(phases).flatMap(([phaseId, phase]) => {
|
|
116
251
|
const sources = /* @__PURE__ */ new Set([...Object.keys(phase.onEnter ?? {}), ...Object.keys(phase.onExit ?? {})]);
|
|
117
252
|
if (sources.size === 0) return [];
|
|
118
253
|
return [[phaseId, Object.freeze(Object.fromEntries([...sources].map((source) => [source, Object.freeze({
|
|
@@ -126,12 +261,13 @@ function defineBoard(config) {
|
|
|
126
261
|
for (const [phaseId, phase] of Object.entries(phases)) {
|
|
127
262
|
kinds.set(phaseId, phase.kind);
|
|
128
263
|
if (phase.kind !== "working") continue;
|
|
129
|
-
roles.set(phaseId, phase.
|
|
130
|
-
if (!phaseByRole.has(phase.
|
|
264
|
+
roles.set(phaseId, phase.runner.context);
|
|
265
|
+
if (!phaseByRole.has(phase.runner.context)) phaseByRole.set(phase.runner.context, phaseId);
|
|
131
266
|
}
|
|
132
267
|
return Object.freeze({
|
|
133
268
|
id: config.id,
|
|
134
|
-
|
|
269
|
+
name: boardName,
|
|
270
|
+
...boardDescription !== void 0 ? { description: boardDescription } : {},
|
|
135
271
|
initialPhase: config.initialPhase,
|
|
136
272
|
phases,
|
|
137
273
|
transitions: Object.freeze(transitions),
|
|
@@ -147,9 +283,15 @@ function defineBoard(config) {
|
|
|
147
283
|
isWorking: (phase) => kinds.get(phase) === "working",
|
|
148
284
|
isTerminal: (phase) => kinds.get(phase) === "terminal",
|
|
149
285
|
roleForPhase: (phase) => roles.get(phase),
|
|
150
|
-
phaseForRole: (role) => phaseByRole.get(role)
|
|
286
|
+
phaseForRole: (role) => phaseByRole.get(role),
|
|
287
|
+
startsAutomatically: (phase, facts) => {
|
|
288
|
+
const definition = phases[phase];
|
|
289
|
+
if (definition?.kind !== "working" || definition.autoStart !== true) return false;
|
|
290
|
+
if (!definition.autoStartWhen) return true;
|
|
291
|
+
return facts !== void 0 && evaluateRuleGroup(definition.autoStartWhen, facts);
|
|
292
|
+
}
|
|
151
293
|
});
|
|
152
294
|
}
|
|
153
|
-
export { BoardDefinitionError, defineBoard };
|
|
295
|
+
export { BoardDefinitionError, DEFAULT_PHASE_CONTEXT, FACTORY_AGENT_ID, defineBoard };
|
|
154
296
|
|
|
155
297
|
//# sourceMappingURL=define-board.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-board.js","names":[],"sources":["../../src/boards/define-board.ts"],"sourcesContent":["import {\n FACTORY_GITHUB_EVENTS,\n FACTORY_GITLAB_EVENTS,\n FACTORY_INCIDENTIO_EVENTS,\n FACTORY_JIRA_EVENTS,\n FACTORY_LINEAR_EVENTS,\n} from '../rules/types.js';\nimport type {\n FactoryGithubEventName,\n FactoryGithubRuleContext,\n FactoryGitLabEventName,\n FactoryGitLabRuleContext,\n FactoryIncidentioEventName,\n FactoryIncidentioRuleContext,\n FactoryJiraEventName,\n FactoryJiraRuleContext,\n FactoryLinearEventName,\n FactoryLinearRuleContext,\n FactoryRuleHandler,\n FactoryRuleSource,\n FactoryStageRuleContext,\n FactoryToolResultRuleContext,\n} from '../rules/types.js';\nimport { IDENTIFIER_RE, isBoardIdentifier, MAX_ROLE_LENGTH, MAX_TOOL_NAME_LENGTH } from '../rules/validation.js';\nimport type { BoardTransitionPolicy } from './transition-policy.js';\n\ntype BoardPhaseHandlers = Partial<Record<FactoryRuleSource, FactoryRuleHandler<FactoryStageRuleContext>>>;\ntype ReadonlyBoardPhaseHandlers = Readonly<BoardPhaseHandlers>;\n\n/** Runs when an agent seated on this board completes the named tool. */\nexport type BoardToolResultRuleHandler = FactoryRuleHandler<FactoryToolResultRuleContext>;\nexport type BoardToolRule = { readonly onResult: BoardToolResultRuleHandler };\nexport type BoardToolRules = Readonly<Record<string, BoardToolRule>>;\n\n/**\n * A board's handler for one integration event. `null` switches the integration default off\n * for cards on this board only.\n */\ntype BoardEventHandlerMap<EventName extends string, Context> = Readonly<\n Partial<Record<EventName, FactoryRuleHandler<Context> | null>>\n>;\n\n/**\n * How cards on this board react to integration events, keyed by integration then event.\n * Consulted for events bound to a card on this board, after any handler the deployment set\n * explicitly on the integration and before the integration default.\n */\nexport interface BoardEventRules {\n readonly github?: BoardEventHandlerMap<FactoryGithubEventName, FactoryGithubRuleContext>;\n readonly gitlab?: BoardEventHandlerMap<FactoryGitLabEventName, FactoryGitLabRuleContext>;\n readonly linear?: BoardEventHandlerMap<FactoryLinearEventName, FactoryLinearRuleContext>;\n readonly jira?: BoardEventHandlerMap<FactoryJiraEventName, FactoryJiraRuleContext>;\n readonly incidentio?: BoardEventHandlerMap<FactoryIncidentioEventName, FactoryIncidentioRuleContext>;\n}\nexport type BoardEventIntegration = keyof BoardEventRules;\n\nconst BOARD_EVENT_NAMES: Readonly<Record<BoardEventIntegration, readonly string[]>> = {\n github: FACTORY_GITHUB_EVENTS,\n gitlab: FACTORY_GITLAB_EVENTS,\n linear: FACTORY_LINEAR_EVENTS,\n jira: FACTORY_JIRA_EVENTS,\n incidentio: FACTORY_INCIDENTIO_EVENTS,\n};\n\ntype ReadonlyFactoryBoardRules = Readonly<\n Record<\n string,\n Readonly<\n Partial<\n Record<\n FactoryRuleSource,\n Readonly<{\n onEnter?: FactoryRuleHandler<FactoryStageRuleContext>;\n onExit?: FactoryRuleHandler<FactoryStageRuleContext>;\n }>\n >\n >\n >\n >\n>;\n\n/**\n * What a phase means to the runtime.\n * - `resting`: nobody is seated; a card waits for a person or an event.\n * - `working`: an agent in `role` carries the card; a person's move in arms autonomy.\n * - `terminal`: the card is finished; sessions stop and held resources are released.\n */\nexport type BoardPhaseKind = 'resting' | 'working' | 'terminal';\n\ntype BoardPhaseBase<PhaseId extends string> = {\n readonly title: string;\n readonly next?: PhaseId;\n readonly outcomes?: Readonly<Record<string, PhaseId>>;\n readonly onEnter?: ReadonlyBoardPhaseHandlers;\n readonly onExit?: ReadonlyBoardPhaseHandlers;\n};\n\nexport type BoardPhaseDefinition<PhaseId extends string> =\n | (BoardPhaseBase<PhaseId> & { readonly kind: 'resting'; readonly role?: never })\n | (BoardPhaseBase<PhaseId> & { readonly kind: 'working'; readonly role: string })\n | (BoardPhaseBase<PhaseId> & { readonly kind: 'terminal'; readonly role?: never });\n\nexport interface BoardTransition<PhaseId extends string> {\n readonly outcome: string | null;\n readonly to: PhaseId;\n}\n\n/**\n * Terminal phases a card moves to when its tracked source (issue or follow-up) closes.\n * `completed` is used when the source was completed, `canceled` when it was canceled or not planned.\n */\nexport type BoardSourceClosed<PhaseId extends string> = Readonly<{ completed: PhaseId; canceled: PhaseId }>;\n\nexport interface BoardDefinition<BoardId extends string, PhaseId extends string> {\n readonly id: BoardId;\n readonly title: string;\n readonly initialPhase: PhaseId;\n readonly phases: Readonly<Record<PhaseId, BoardPhaseDefinition<PhaseId>>>;\n readonly transitions: Readonly<Record<PhaseId, readonly BoardTransition<PhaseId>[]>>;\n readonly rules: ReadonlyFactoryBoardRules;\n /** Tool-result rules keyed by tool name; empty when the board declares none. */\n readonly tools: BoardToolRules;\n /** Integration event handlers for cards on this board; empty when the board declares none. */\n readonly events: BoardEventRules;\n readonly transitionPolicy?: BoardTransitionPolicy;\n /** Where source-closed rules move a card; absent when the board opts out of auto-closing. */\n readonly sourceClosed?: BoardSourceClosed<PhaseId>;\n allowsTransition(from: PhaseId, to: PhaseId): boolean;\n /** Declared kind of a phase, or undefined when the board has no such phase. */\n phaseKind(phase: string): BoardPhaseKind | undefined;\n isWorking(phase: string): boolean;\n isTerminal(phase: string): boolean;\n /** Role seated in a working phase; undefined for resting/terminal/unknown phases. */\n roleForPhase(phase: string): string | undefined;\n /** First working phase, in declaration order, carried by `role`. */\n phaseForRole(role: string): PhaseId | undefined;\n}\n\ntype BoardConfig<BoardId extends string, Phases extends Record<string, BoardPhaseDefinition<keyof Phases & string>>> = {\n id: BoardId;\n title: string;\n initialPhase: keyof Phases & string;\n phases: Phases;\n tools?: Record<string, BoardToolRule>;\n events?: BoardEventRules;\n transitionPolicy?: BoardTransitionPolicy;\n sourceClosed?: { completed: keyof Phases & string; canceled: keyof Phases & string };\n};\n\nexport class BoardDefinitionError extends Error {\n override name = 'BoardDefinitionError';\n}\n\nconst PHASE_KINDS: ReadonlySet<string> = new Set<BoardPhaseKind>(['resting', 'working', 'terminal']);\n\nfunction validateBoardIdentifier(value: unknown, label: string): void {\n if (!isBoardIdentifier(value)) {\n throw new BoardDefinitionError(`${label} must be a valid board identifier.`);\n }\n}\n\nfunction validatePhaseSemantics(phaseId: string, phase: BoardPhaseDefinition<string>): void {\n if (!PHASE_KINDS.has(phase.kind as string)) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" must declare kind 'resting', 'working', or 'terminal'.`);\n }\n if (phase.kind === 'working') {\n const role: unknown = phase.role;\n if (typeof role !== 'string' || role.length === 0 || role.length > MAX_ROLE_LENGTH || !IDENTIFIER_RE.test(role)) {\n throw new BoardDefinitionError(`Working phase \"${phaseId}\" must declare a valid role.`);\n }\n } else if ((phase as { role?: unknown }).role !== undefined) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" is ${phase.kind} and cannot declare a role.`);\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction validateToolRules(tools: unknown): BoardToolRules {\n if (tools === undefined) return Object.freeze({});\n if (!isPlainObject(tools)) throw new BoardDefinitionError('Board tools must be a plain object.');\n const frozen: Record<string, BoardToolRule> = {};\n for (const [toolName, leaf] of Object.entries(tools)) {\n if (toolName.length === 0 || toolName.length > MAX_TOOL_NAME_LENGTH || !IDENTIFIER_RE.test(toolName)) {\n throw new BoardDefinitionError(`Tool rule \"${toolName}\" has an invalid tool name.`);\n }\n if (!isPlainObject(leaf) || Object.keys(leaf).some(key => key !== 'onResult')) {\n throw new BoardDefinitionError(`Tool rule \"${toolName}\" must be an object with only onResult.`);\n }\n if (typeof leaf.onResult !== 'function') {\n throw new BoardDefinitionError(`Tool rule \"${toolName}\" must declare an onResult function.`);\n }\n frozen[toolName] = Object.freeze({ onResult: leaf.onResult as BoardToolResultRuleHandler });\n }\n return Object.freeze(frozen);\n}\n\nfunction validateSourceClosed(\n sourceClosed: unknown,\n phases: Readonly<Record<string, BoardPhaseDefinition<string>>>,\n): BoardSourceClosed<string> | undefined {\n if (sourceClosed === undefined) return undefined;\n if (!isPlainObject(sourceClosed)) throw new BoardDefinitionError('Board sourceClosed must be a plain object.');\n const keys = Object.keys(sourceClosed);\n if (keys.length !== 2 || !keys.includes('completed') || !keys.includes('canceled')) {\n throw new BoardDefinitionError('Board sourceClosed must declare exactly completed and canceled.');\n }\n for (const key of ['completed', 'canceled'] as const) {\n const phase = sourceClosed[key];\n if (typeof phase !== 'string' || !Object.hasOwn(phases, phase) || phases[phase]!.kind !== 'terminal') {\n throw new BoardDefinitionError(`Board sourceClosed.${key} \"${String(phase)}\" must name a terminal phase.`);\n }\n }\n return Object.freeze({ completed: sourceClosed.completed as string, canceled: sourceClosed.canceled as string });\n}\n\nfunction validateEventRules(events: unknown): BoardEventRules {\n if (events === undefined) return Object.freeze({});\n if (!isPlainObject(events)) throw new BoardDefinitionError('Board events must be a plain object.');\n const frozen: Record<string, Readonly<Record<string, unknown>>> = {};\n for (const [integration, handlers] of Object.entries(events)) {\n const known = Object.hasOwn(BOARD_EVENT_NAMES, integration)\n ? BOARD_EVENT_NAMES[integration as BoardEventIntegration]\n : undefined;\n if (!known) throw new BoardDefinitionError(`Board events name unknown integration \"${integration}\".`);\n if (handlers === undefined) continue;\n if (!isPlainObject(handlers)) {\n throw new BoardDefinitionError(`Board events for \"${integration}\" must be a plain object.`);\n }\n const entries: Record<string, unknown> = {};\n for (const [event, handler] of Object.entries(handlers)) {\n if (!known.includes(event)) {\n throw new BoardDefinitionError(`Board events for \"${integration}\" name unknown event \"${event}\".`);\n }\n if (handler === undefined) continue;\n if (handler !== null && typeof handler !== 'function') {\n throw new BoardDefinitionError(`Board event handler \"${integration}.${event}\" must be a function or null.`);\n }\n entries[event] = handler;\n }\n frozen[integration] = Object.freeze(entries);\n }\n return Object.freeze(frozen) as BoardEventRules;\n}\n\nexport function defineBoard<\n const BoardId extends string,\n const Phases extends Record<string, BoardPhaseDefinition<keyof Phases & string>>,\n>(config: BoardConfig<BoardId, Phases>): BoardDefinition<BoardId, keyof Phases & string> {\n type PhaseId = keyof Phases & string;\n validateBoardIdentifier(config.id, 'Board id');\n if (config.transitionPolicy !== undefined && typeof config.transitionPolicy !== 'function') {\n throw new BoardDefinitionError('Board transitionPolicy must be a function.');\n }\n const tools = validateToolRules(config.tools);\n const events = validateEventRules(config.events);\n const phaseIds = new Set(Object.keys(config.phases));\n if (phaseIds.size === 0) throw new BoardDefinitionError('A board must define at least one phase.');\n if (!phaseIds.has(config.initialPhase)) {\n throw new BoardDefinitionError(`Initial phase \"${config.initialPhase}\" is not defined.`);\n }\n for (const [phaseId, phase] of Object.entries(config.phases)) {\n validateBoardIdentifier(phaseId, 'Phase id');\n validatePhaseSemantics(phaseId, phase);\n }\n if (config.phases[config.initialPhase]!.kind !== 'resting') {\n throw new BoardDefinitionError(`Initial phase \"${config.initialPhase}\" must be a resting phase.`);\n }\n const sourceClosed = validateSourceClosed(config.sourceClosed, config.phases) as\n | BoardSourceClosed<PhaseId>\n | undefined;\n\n const transitions = Object.fromEntries(\n Object.entries(config.phases).map(([phaseId, phase]) => {\n if (phase.next !== undefined && phase.outcomes) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" cannot define both next and outcomes.`);\n }\n const targets: BoardTransition<string>[] =\n phase.next !== undefined\n ? [Object.freeze({ outcome: null, to: phase.next })]\n : Object.entries(phase.outcomes ?? {}).map(([outcome, to]) => Object.freeze({ outcome, to }));\n for (const { to } of targets) {\n if (!phaseIds.has(to)) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" targets undefined phase \"${to}\".`);\n }\n }\n return [phaseId, Object.freeze(targets)];\n }),\n ) as Record<PhaseId, readonly BoardTransition<PhaseId>[]>;\n\n const phases = Object.freeze(\n Object.fromEntries(\n Object.entries(config.phases).map(([phaseId, phase]) => [\n phaseId,\n Object.freeze({\n title: phase.title,\n kind: phase.kind,\n ...(phase.kind === 'working' ? { role: phase.role } : {}),\n ...(phase.next !== undefined ? { next: phase.next } : {}),\n ...(phase.outcomes ? { outcomes: Object.freeze({ ...phase.outcomes }) } : {}),\n ...(phase.onEnter ? { onEnter: Object.freeze({ ...phase.onEnter }) } : {}),\n ...(phase.onExit ? { onExit: Object.freeze({ ...phase.onExit }) } : {}),\n }),\n ]),\n ),\n ) as Readonly<Record<PhaseId, BoardPhaseDefinition<PhaseId>>>;\n const rules = Object.freeze(\n Object.fromEntries(\n Object.entries(config.phases).flatMap(([phaseId, phase]) => {\n const sources = new Set([...Object.keys(phase.onEnter ?? {}), ...Object.keys(phase.onExit ?? {})]);\n if (sources.size === 0) return [];\n return [\n [\n phaseId,\n Object.freeze(\n Object.fromEntries(\n [...sources].map(source => [\n source,\n Object.freeze({\n ...(phase.onEnter?.[source as FactoryRuleSource]\n ? { onEnter: phase.onEnter[source as FactoryRuleSource] }\n : {}),\n ...(phase.onExit?.[source as FactoryRuleSource]\n ? { onExit: phase.onExit[source as FactoryRuleSource] }\n : {}),\n }),\n ]),\n ),\n ),\n ],\n ];\n }),\n ),\n ) as ReadonlyFactoryBoardRules;\n\n const kinds = new Map<string, BoardPhaseKind>();\n const roles = new Map<string, string>();\n const phaseByRole = new Map<string, PhaseId>();\n for (const [phaseId, phase] of Object.entries(phases) as [PhaseId, BoardPhaseDefinition<PhaseId>][]) {\n kinds.set(phaseId, phase.kind);\n if (phase.kind !== 'working') continue;\n roles.set(phaseId, phase.role);\n if (!phaseByRole.has(phase.role)) phaseByRole.set(phase.role, phaseId);\n }\n\n return Object.freeze({\n id: config.id,\n title: config.title,\n initialPhase: config.initialPhase,\n phases,\n transitions: Object.freeze(transitions),\n rules: Object.freeze(rules),\n tools,\n events,\n ...(config.transitionPolicy ? { transitionPolicy: config.transitionPolicy } : {}),\n ...(sourceClosed ? { sourceClosed } : {}),\n allowsTransition(from: PhaseId, to: PhaseId) {\n return from === to || transitions[from]?.some(transition => transition.to === to) === true;\n },\n phaseKind: (phase: string) => kinds.get(phase),\n isWorking: (phase: string) => kinds.get(phase) === 'working',\n isTerminal: (phase: string) => kinds.get(phase) === 'terminal',\n roleForPhase: (phase: string) => roles.get(phase),\n phaseForRole: (role: string) => phaseByRole.get(role),\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"define-board.js","names":[],"sources":["../../src/boards/define-board.ts"],"sourcesContent":["import { CODE_AGENT_ID } from '@mastra/code-sdk/constants';\nimport { cardRuleGroupSchema, evaluateRuleGroup } from '../rules/rule-group.js';\nimport type { RuleFacts, RuleGroup } from '../rules/rule-group.js';\nimport {\n FACTORY_GITHUB_EVENTS,\n FACTORY_RULE_SOURCES,\n FACTORY_GITLAB_EVENTS,\n FACTORY_INCIDENTIO_EVENTS,\n FACTORY_JIRA_EVENTS,\n FACTORY_LINEAR_EVENTS,\n} from '../rules/types.js';\nimport type {\n FactoryGithubEventName,\n FactoryGithubRuleContext,\n FactoryGitLabEventName,\n FactoryGitLabRuleContext,\n FactoryIncidentioEventName,\n FactoryIncidentioRuleContext,\n FactoryJiraEventName,\n FactoryJiraRuleContext,\n FactoryLinearEventName,\n FactoryLinearRuleContext,\n FactoryRuleHandler,\n FactoryRuleSource,\n FactoryStageRuleContext,\n FactoryToolResultRuleContext,\n} from '../rules/types.js';\nimport {\n IDENTIFIER_RE,\n isBoardIdentifier,\n MAX_ROLE_LENGTH,\n MAX_SKILL_NAME_LENGTH,\n MAX_TOOL_NAME_LENGTH,\n SKILL_NAME_RE,\n} from '../rules/validation.js';\nimport { addInstructions, startSkill } from './phase-runner.js';\nimport type { BoardTransitionPolicy } from './transition-policy.js';\n\ntype BoardPhaseHandlers = Partial<Record<FactoryRuleSource, FactoryRuleHandler<FactoryStageRuleContext>>>;\ntype ReadonlyBoardPhaseHandlers = Readonly<BoardPhaseHandlers>;\n\n/** Runs when an agent seated on this board completes the named tool. */\nexport type BoardToolResultRuleHandler = FactoryRuleHandler<FactoryToolResultRuleContext>;\nexport type BoardToolRule = { readonly onResult: BoardToolResultRuleHandler };\nexport type BoardToolRules = Readonly<Record<string, BoardToolRule>>;\n\n/**\n * A board's handler for one integration event. `null` switches the integration default off\n * for cards on this board only.\n */\ntype BoardEventHandlerMap<EventName extends string, Context> = Readonly<\n Partial<Record<EventName, FactoryRuleHandler<Context> | null>>\n>;\n\n/**\n * How cards on this board react to integration events, keyed by integration then event.\n * Consulted for events bound to a card on this board, after any handler the deployment set\n * explicitly on the integration and before the integration default.\n */\nexport interface BoardEventRules {\n readonly github?: BoardEventHandlerMap<FactoryGithubEventName, FactoryGithubRuleContext>;\n readonly gitlab?: BoardEventHandlerMap<FactoryGitLabEventName, FactoryGitLabRuleContext>;\n readonly linear?: BoardEventHandlerMap<FactoryLinearEventName, FactoryLinearRuleContext>;\n readonly jira?: BoardEventHandlerMap<FactoryJiraEventName, FactoryJiraRuleContext>;\n readonly incidentio?: BoardEventHandlerMap<FactoryIncidentioEventName, FactoryIncidentioRuleContext>;\n}\nexport type BoardEventIntegration = keyof BoardEventRules;\n\nconst BOARD_EVENT_NAMES: Readonly<Record<BoardEventIntegration, readonly string[]>> = {\n github: FACTORY_GITHUB_EVENTS,\n gitlab: FACTORY_GITLAB_EVENTS,\n linear: FACTORY_LINEAR_EVENTS,\n jira: FACTORY_JIRA_EVENTS,\n incidentio: FACTORY_INCIDENTIO_EVENTS,\n};\n\ntype ReadonlyFactoryBoardRules = Readonly<\n Record<\n string,\n Readonly<\n Partial<\n Record<\n FactoryRuleSource,\n Readonly<{\n onEnter?: FactoryRuleHandler<FactoryStageRuleContext>;\n onExit?: FactoryRuleHandler<FactoryStageRuleContext>;\n }>\n >\n >\n >\n >\n>;\n\n/**\n * What a phase means to the runtime.\n * - `resting`: nobody is seated; a card waits for a person or an event.\n * - `working`: an agent in the phase's context carries the card; a person's move in arms autonomy.\n * - `terminal`: the card is finished; sessions stop and held resources are released.\n */\nexport type BoardPhaseKind = 'resting' | 'working' | 'terminal';\n\n/** The agent Factory runs every phase with. */\nexport const FACTORY_AGENT_ID = CODE_AGENT_ID;\n\n/** The session context a working phase runs in when it names none. */\nexport const DEFAULT_PHASE_CONTEXT = 'work';\n\n/** Who runs a working phase, and with what. */\nexport interface BoardPhaseRunner {\n /** Must be `code-agent`, the agent Factory runs; omitted means that agent. */\n readonly agentId?: string;\n /** Skill started when a card enters the phase from a source with no `onEnter` handler. */\n readonly skill?: string;\n /**\n * The session the phase runs in. Phases naming the same context share one session per card;\n * a different context gets its own. Defaults to `work`.\n */\n readonly context?: string;\n /** Appended to every run the phase starts. */\n readonly instructions?: string;\n}\n\n/**\n * The tool whose successful call ends a working phase. The agent then moves the card itself with\n * `factory_transition_work_item`, to one of the phase's `nextPhases`.\n */\nexport interface BoardPhaseExitTool {\n readonly id: string;\n /**\n * Answer the approval the tool waits for without a person. Factory sessions run other tools\n * without asking, so today this applies to `submit_plan`. Defaults to false.\n */\n readonly autoApprove?: boolean;\n /** With `autoApprove`, only cards this matches are approved without a person. */\n readonly autoApproveWhen?: RuleGroup;\n}\n\ntype BoardPhaseBase<PhaseId extends string> = {\n readonly name?: string;\n /** @deprecated Use `name`. */\n readonly title?: string;\n readonly description?: string;\n /** Phases a card may move to from here. */\n readonly nextPhases?: readonly PhaseId[];\n /** @deprecated List the phase in `nextPhases`. */\n readonly next?: PhaseId;\n /** Named moves rules can choose by outcome; each target is also an allowed next phase. */\n readonly outcomes?: Readonly<Record<string, PhaseId>>;\n readonly onEnter?: ReadonlyBoardPhaseHandlers;\n readonly onExit?: ReadonlyBoardPhaseHandlers;\n};\n\ntype WorkingPhaseFields = {\n readonly runner?: BoardPhaseRunner;\n /** @deprecated Use `runner.context`. */\n readonly role?: string;\n /** Runs start without anyone approving them, even with the project's auto-run off. */\n readonly autoStart?: boolean;\n /** With `autoStart`, only cards this matches start on their own. */\n readonly autoStartWhen?: RuleGroup;\n /** A bare tool name is shorthand for `{ id }`, with nothing approved on a person's behalf. */\n readonly exitTool?: string | BoardPhaseExitTool;\n};\n\ntype NonWorkingPhaseFields = {\n readonly runner?: never;\n readonly role?: never;\n readonly autoStart?: never;\n readonly autoStartWhen?: never;\n readonly exitTool?: never;\n};\n\n/** A phase as a board declares it. */\nexport type BoardPhaseDefinition<PhaseId extends string> =\n | (BoardPhaseBase<PhaseId> & NonWorkingPhaseFields & { readonly kind: 'resting' })\n | (BoardPhaseBase<PhaseId> & WorkingPhaseFields & { readonly kind: 'working' })\n | (BoardPhaseBase<PhaseId> & NonWorkingPhaseFields & { readonly kind: 'terminal' });\n\ntype ResolvedPhaseBase<PhaseId extends string> = {\n readonly name: string;\n readonly description?: string;\n /** Every phase a card may move to from here, including outcome targets. */\n readonly nextPhases: readonly PhaseId[];\n readonly outcomes?: Readonly<Record<string, PhaseId>>;\n readonly onEnter?: ReadonlyBoardPhaseHandlers;\n readonly onExit?: ReadonlyBoardPhaseHandlers;\n};\n\n/**\n * A phase as the board resolved it: deprecated fields are replaced by their new names, so\n * only the new structure leaves `defineBoard()`, and a resolved phase can be declared again.\n */\nexport type BoardPhase<PhaseId extends string> =\n | (ResolvedPhaseBase<PhaseId> & { readonly kind: 'resting' })\n | (ResolvedPhaseBase<PhaseId> & {\n readonly kind: 'working';\n readonly runner: Readonly<BoardPhaseRunner & { agentId: string; context: string }>;\n readonly autoStart?: boolean;\n readonly autoStartWhen?: RuleGroup;\n readonly exitTool?: Readonly<{ id: string; autoApprove: boolean; autoApproveWhen?: RuleGroup }>;\n })\n | (ResolvedPhaseBase<PhaseId> & { readonly kind: 'terminal' });\n\ntype ResolvedRunner = Extract<BoardPhase<string>, { kind: 'working' }>['runner'];\ntype ResolvedExitTool = Extract<BoardPhase<string>, { kind: 'working' }>['exitTool'];\n\nexport interface BoardTransition<PhaseId extends string> {\n readonly outcome: string | null;\n readonly to: PhaseId;\n}\n\n/**\n * Terminal phases a card moves to when its tracked source (issue or follow-up) closes.\n * `completed` is used when the source was completed, `canceled` when it was canceled or not planned.\n */\nexport type BoardSourceClosed<PhaseId extends string> = Readonly<{ completed: PhaseId; canceled: PhaseId }>;\n\nexport interface BoardDefinition<BoardId extends string, PhaseId extends string> {\n readonly id: BoardId;\n readonly name: string;\n readonly description?: string;\n readonly initialPhase: PhaseId;\n readonly phases: Readonly<Record<PhaseId, BoardPhase<PhaseId>>>;\n readonly transitions: Readonly<Record<PhaseId, readonly BoardTransition<PhaseId>[]>>;\n readonly rules: ReadonlyFactoryBoardRules;\n /** Tool-result rules keyed by tool name; empty when the board declares none. */\n readonly tools: BoardToolRules;\n /** Integration event handlers for cards on this board; empty when the board declares none. */\n readonly events: BoardEventRules;\n readonly transitionPolicy?: BoardTransitionPolicy;\n /** Where source-closed rules move a card; absent when the board opts out of auto-closing. */\n readonly sourceClosed?: BoardSourceClosed<PhaseId>;\n allowsTransition(from: PhaseId, to: PhaseId): boolean;\n /** Declared kind of a phase, or undefined when the board has no such phase. */\n phaseKind(phase: string): BoardPhaseKind | undefined;\n isWorking(phase: string): boolean;\n isTerminal(phase: string): boolean;\n /** Session context of a working phase; undefined for resting/terminal/unknown phases. */\n roleForPhase(phase: string): string | undefined;\n /** First working phase, in declaration order, running in `role`'s context. */\n phaseForRole(role: string): PhaseId | undefined;\n /**\n * Whether the phase's runs start without anyone approving them, for a card with these facts\n * (`cardRuleFacts`). A phase with a start condition never starts on its own without facts.\n */\n startsAutomatically(phase: string, facts?: RuleFacts): boolean;\n}\n\ntype BoardConfig<BoardId extends string, Phases extends Record<string, BoardPhaseDefinition<keyof Phases & string>>> = {\n id: BoardId;\n name?: string;\n /** @deprecated Use `name`. */\n title?: string;\n description?: string;\n initialPhase: keyof Phases & string;\n phases: Phases;\n tools?: Record<string, BoardToolRule>;\n events?: BoardEventRules;\n transitionPolicy?: BoardTransitionPolicy;\n sourceClosed?: { completed: keyof Phases & string; canceled: keyof Phases & string };\n};\n\nexport class BoardDefinitionError extends Error {\n override name = 'BoardDefinitionError';\n}\n\nconst PHASE_KINDS: ReadonlySet<string> = new Set<BoardPhaseKind>(['resting', 'working', 'terminal']);\n\nfunction validateBoardIdentifier(value: unknown, label: string): void {\n if (!isBoardIdentifier(value)) {\n throw new BoardDefinitionError(`${label} must be a valid board identifier.`);\n }\n}\n\nconst MAX_NAME_LENGTH = 128;\nconst MAX_DESCRIPTION_LENGTH = 2_000;\nconst MAX_INSTRUCTIONS_LENGTH = 1_000;\nconst RUNNER_KEYS: ReadonlySet<string> = new Set(['agentId', 'skill', 'context', 'instructions']);\nconst EXIT_TOOL_KEYS: ReadonlySet<string> = new Set(['id', 'autoApprove', 'autoApproveWhen']);\nconst WORKING_ONLY_FIELDS = ['runner', 'autoStart', 'autoStartWhen', 'exitTool'] as const;\nconst MOVE_TOOL = 'factory_transition_work_item';\n\n/** `name`, falling back to the deprecated `title`; both may be set only to the same text. */\nfunction resolveName(name: unknown, title: unknown, label: string): string {\n if (name !== undefined && title !== undefined && name !== title) {\n throw new BoardDefinitionError(`${label} sets both name and title; drop the deprecated title.`);\n }\n const value = name ?? title;\n if (typeof value !== 'string' || value.trim().length === 0 || value.length > MAX_NAME_LENGTH) {\n throw new BoardDefinitionError(`${label} must declare a name.`);\n }\n return value;\n}\n\nfunction optionalText(value: unknown, label: string, max: number): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== 'string' || value.trim().length === 0 || value.length > max) {\n throw new BoardDefinitionError(`${label} must be non-empty text of at most ${max} characters.`);\n }\n return value;\n}\n\nfunction ruleGroup(value: unknown, label: string): RuleGroup | undefined {\n if (value === undefined) return undefined;\n const parsed = cardRuleGroupSchema.safeParse(value);\n if (!parsed.success) {\n throw new BoardDefinitionError(`${label} is not a valid condition: ${parsed.error.issues[0]?.message}`);\n }\n return parsed.data;\n}\n\nfunction isContext(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0 && value.length <= MAX_ROLE_LENGTH && IDENTIFIER_RE.test(value);\n}\n\nfunction resolveRunner(phaseId: string, phase: BoardPhaseDefinition<string>): ResolvedRunner {\n const runner: unknown = phase.runner ?? {};\n if (!isPlainObject(runner) || Object.keys(runner).some(key => !RUNNER_KEYS.has(key))) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" runner may only set agentId, skill, context and instructions.`);\n }\n const role: unknown = phase.role;\n if (role !== undefined && runner.context !== undefined && role !== runner.context) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" sets both role and runner.context; drop the deprecated role.`);\n }\n const context = runner.context ?? role ?? DEFAULT_PHASE_CONTEXT;\n if (!isContext(context)) throw new BoardDefinitionError(`Working phase \"${phaseId}\" must declare a valid context.`);\n const agentId = runner.agentId ?? FACTORY_AGENT_ID;\n if (agentId !== FACTORY_AGENT_ID) {\n throw new BoardDefinitionError(\n `Phase \"${phaseId}\" names unknown agent \"${String(agentId)}\"; Factory runs \"${FACTORY_AGENT_ID}\".`,\n );\n }\n const skill = runner.skill;\n if (\n skill !== undefined &&\n (typeof skill !== 'string' || skill.length > MAX_SKILL_NAME_LENGTH || !SKILL_NAME_RE.test(skill))\n ) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" runner.skill must be a skill name.`);\n }\n const instructions = optionalText(\n runner.instructions,\n `Phase \"${phaseId}\" runner.instructions`,\n MAX_INSTRUCTIONS_LENGTH,\n );\n return Object.freeze({\n agentId,\n context,\n ...(skill !== undefined ? { skill } : {}),\n ...(instructions !== undefined ? { instructions } : {}),\n });\n}\n\nfunction resolveExitTool(phaseId: string, value: unknown): ResolvedExitTool {\n if (value === undefined) return undefined;\n const declared = typeof value === 'string' ? { id: value } : value;\n if (!isPlainObject(declared) || Object.keys(declared).some(key => !EXIT_TOOL_KEYS.has(key))) {\n throw new BoardDefinitionError(\n `Phase \"${phaseId}\" exitTool must be a tool name or { id, autoApprove, autoApproveWhen }.`,\n );\n }\n const { id, autoApprove = false } = declared;\n if (typeof id !== 'string' || id.length === 0 || id.length > MAX_TOOL_NAME_LENGTH || !IDENTIFIER_RE.test(id)) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" exitTool has an invalid tool name.`);\n }\n if (id === MOVE_TOOL) {\n throw new BoardDefinitionError(\n `Phase \"${phaseId}\" cannot end with ${MOVE_TOOL}: that tool already moves the card.`,\n );\n }\n if (typeof autoApprove !== 'boolean') {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" exitTool.autoApprove must be a boolean.`);\n }\n const autoApproveWhen = ruleGroup(declared.autoApproveWhen, `Phase \"${phaseId}\" exitTool.autoApproveWhen`);\n if (autoApproveWhen && !autoApprove) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" exitTool.autoApproveWhen needs autoApprove.`);\n }\n return Object.freeze({ id, autoApprove, ...(autoApproveWhen ? { autoApproveWhen } : {}) });\n}\n\nfunction validatePhaseSemantics(phaseId: string, phase: BoardPhaseDefinition<string>): void {\n if (!PHASE_KINDS.has(phase.kind as string)) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" must declare kind 'resting', 'working', or 'terminal'.`);\n }\n if (phase.kind === 'working') return;\n if ((phase as { role?: unknown }).role !== undefined) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" is ${phase.kind} and cannot declare a role.`);\n }\n for (const field of WORKING_ONLY_FIELDS) {\n if ((phase as Record<string, unknown>)[field] !== undefined) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" is ${phase.kind} and cannot declare ${field}.`);\n }\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction validateToolRules(tools: unknown): BoardToolRules {\n if (tools === undefined) return Object.freeze({});\n if (!isPlainObject(tools)) throw new BoardDefinitionError('Board tools must be a plain object.');\n const frozen: Record<string, BoardToolRule> = {};\n for (const [toolName, leaf] of Object.entries(tools)) {\n if (toolName.length === 0 || toolName.length > MAX_TOOL_NAME_LENGTH || !IDENTIFIER_RE.test(toolName)) {\n throw new BoardDefinitionError(`Tool rule \"${toolName}\" has an invalid tool name.`);\n }\n if (!isPlainObject(leaf) || Object.keys(leaf).some(key => key !== 'onResult')) {\n throw new BoardDefinitionError(`Tool rule \"${toolName}\" must be an object with only onResult.`);\n }\n if (typeof leaf.onResult !== 'function') {\n throw new BoardDefinitionError(`Tool rule \"${toolName}\" must declare an onResult function.`);\n }\n frozen[toolName] = Object.freeze({ onResult: leaf.onResult as BoardToolResultRuleHandler });\n }\n return Object.freeze(frozen);\n}\n\nfunction validateSourceClosed(\n sourceClosed: unknown,\n phases: Readonly<Record<string, BoardPhaseDefinition<string>>>,\n): BoardSourceClosed<string> | undefined {\n if (sourceClosed === undefined) return undefined;\n if (!isPlainObject(sourceClosed)) throw new BoardDefinitionError('Board sourceClosed must be a plain object.');\n const keys = Object.keys(sourceClosed);\n if (keys.length !== 2 || !keys.includes('completed') || !keys.includes('canceled')) {\n throw new BoardDefinitionError('Board sourceClosed must declare exactly completed and canceled.');\n }\n for (const key of ['completed', 'canceled'] as const) {\n const phase = sourceClosed[key];\n if (typeof phase !== 'string' || !Object.hasOwn(phases, phase) || phases[phase]!.kind !== 'terminal') {\n throw new BoardDefinitionError(`Board sourceClosed.${key} \"${String(phase)}\" must name a terminal phase.`);\n }\n }\n return Object.freeze({ completed: sourceClosed.completed as string, canceled: sourceClosed.canceled as string });\n}\n\nfunction validateEventRules(events: unknown): BoardEventRules {\n if (events === undefined) return Object.freeze({});\n if (!isPlainObject(events)) throw new BoardDefinitionError('Board events must be a plain object.');\n const frozen: Record<string, Readonly<Record<string, unknown>>> = {};\n for (const [integration, handlers] of Object.entries(events)) {\n const known = Object.hasOwn(BOARD_EVENT_NAMES, integration)\n ? BOARD_EVENT_NAMES[integration as BoardEventIntegration]\n : undefined;\n if (!known) throw new BoardDefinitionError(`Board events name unknown integration \"${integration}\".`);\n if (handlers === undefined) continue;\n if (!isPlainObject(handlers)) {\n throw new BoardDefinitionError(`Board events for \"${integration}\" must be a plain object.`);\n }\n const entries: Record<string, unknown> = {};\n for (const [event, handler] of Object.entries(handlers)) {\n if (!known.includes(event)) {\n throw new BoardDefinitionError(`Board events for \"${integration}\" name unknown event \"${event}\".`);\n }\n if (handler === undefined) continue;\n if (handler !== null && typeof handler !== 'function') {\n throw new BoardDefinitionError(`Board event handler \"${integration}.${event}\" must be a function or null.`);\n }\n entries[event] = handler;\n }\n frozen[integration] = Object.freeze(entries);\n }\n return Object.freeze(frozen) as BoardEventRules;\n}\n\n/** The phase's `onEnter` handlers, with its runner's skill for other sources and its instructions on every run. */\nfunction phaseEnterHandlers(\n declared: ReadonlyBoardPhaseHandlers | undefined,\n runner: ResolvedRunner,\n): ReadonlyBoardPhaseHandlers | undefined {\n const handlers: BoardPhaseHandlers = { ...declared };\n if (runner.skill) {\n for (const source of FACTORY_RULE_SOURCES) handlers[source] ??= startSkill(runner.skill, runner.context);\n }\n if (runner.instructions) {\n for (const source of Object.keys(handlers) as FactoryRuleSource[]) {\n handlers[source] = addInstructions(handlers[source]!, runner.instructions);\n }\n }\n return Object.keys(handlers).length > 0 ? handlers : undefined;\n}\n\nconst warnedBoards = new Set<string>();\n\ntype DeclaredBoard = {\n readonly id: string;\n readonly name?: string;\n readonly title?: string;\n readonly phases: Readonly<Record<string, BoardPhaseDefinition<string>>>;\n};\n\n/** Deprecated fields a board declaration still uses; `defineBoard()` maps each to its replacement. */\nfunction deprecatedFields(config: DeclaredBoard): string[] {\n const found: string[] = [];\n if (config.title !== undefined) found.push('title → name');\n for (const [phaseId, phase] of Object.entries(config.phases)) {\n if (phase.title !== undefined) found.push(`phases.${phaseId}.title → name`);\n if (phase.next !== undefined) found.push(`phases.${phaseId}.next → nextPhases`);\n if (phase.role !== undefined) found.push(`phases.${phaseId}.role → runner.context`);\n }\n return found;\n}\n\nfunction warnDeprecatedFields(config: DeclaredBoard): void {\n if (warnedBoards.has(config.id)) return;\n const found = deprecatedFields(config);\n if (found.length === 0) return;\n warnedBoards.add(config.id);\n console.warn(\n `[Mastra Factory] Board \"${config.id}\" uses deprecated fields: ${found.join(', ')}. ` +\n 'They still work but will be removed in a future release.',\n );\n}\n\nexport function defineBoard<\n const BoardId extends string,\n const Phases extends Record<string, BoardPhaseDefinition<keyof Phases & string>>,\n>(config: BoardConfig<BoardId, Phases>): BoardDefinition<BoardId, keyof Phases & string> {\n type PhaseId = keyof Phases & string;\n validateBoardIdentifier(config.id, 'Board id');\n const boardName = resolveName(config.name, config.title, `Board \"${config.id}\"`);\n const boardDescription = optionalText(config.description, `Board \"${config.id}\" description`, MAX_DESCRIPTION_LENGTH);\n if (config.transitionPolicy !== undefined && typeof config.transitionPolicy !== 'function') {\n throw new BoardDefinitionError('Board transitionPolicy must be a function.');\n }\n const tools = validateToolRules(config.tools);\n const events = validateEventRules(config.events);\n const phaseIds = new Set(Object.keys(config.phases));\n if (phaseIds.size === 0) throw new BoardDefinitionError('A board must define at least one phase.');\n if (!phaseIds.has(config.initialPhase)) {\n throw new BoardDefinitionError(`Initial phase \"${config.initialPhase}\" is not defined.`);\n }\n for (const [phaseId, phase] of Object.entries(config.phases)) {\n validateBoardIdentifier(phaseId, 'Phase id');\n validatePhaseSemantics(phaseId, phase);\n }\n if (config.phases[config.initialPhase]!.kind !== 'resting') {\n throw new BoardDefinitionError(`Initial phase \"${config.initialPhase}\" must be a resting phase.`);\n }\n warnDeprecatedFields(config);\n const sourceClosed = validateSourceClosed(config.sourceClosed, config.phases) as\n | BoardSourceClosed<PhaseId>\n | undefined;\n\n const transitions = Object.fromEntries(\n Object.entries(config.phases).map(([phaseId, phase]) => {\n if (phase.next !== undefined && phase.outcomes) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" cannot define both next and outcomes.`);\n }\n if (phase.nextPhases !== undefined && !Array.isArray(phase.nextPhases)) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" nextPhases must be a list of phases.`);\n }\n const targets: BoardTransition<string>[] =\n phase.next !== undefined\n ? [Object.freeze({ outcome: null, to: phase.next })]\n : Object.entries(phase.outcomes ?? {}).map(([outcome, to]) => Object.freeze({ outcome, to }));\n for (const to of phase.nextPhases ?? []) {\n if (!targets.some(target => target.to === to)) targets.push(Object.freeze({ outcome: null, to }));\n }\n for (const { to } of targets) {\n if (!phaseIds.has(to)) {\n throw new BoardDefinitionError(`Phase \"${phaseId}\" targets undefined phase \"${to}\".`);\n }\n }\n return [phaseId, Object.freeze(targets)];\n }),\n ) as Record<PhaseId, readonly BoardTransition<PhaseId>[]>;\n\n const phases = Object.freeze(\n Object.fromEntries(\n Object.entries(config.phases).map(([phaseId, phase]) => {\n const label = `Phase \"${phaseId}\"`;\n const nextPhases = Object.freeze([\n ...new Set([...(phase.nextPhases ?? []), ...transitions[phaseId as PhaseId]!.map(({ to }) => to)]),\n ]);\n const runner = phase.kind === 'working' ? resolveRunner(phaseId, phase) : undefined;\n const working = phase.kind === 'working' ? phase : undefined;\n if (working?.autoStart !== undefined && typeof working.autoStart !== 'boolean') {\n throw new BoardDefinitionError(`${label} autoStart must be a boolean.`);\n }\n const autoStartWhen = ruleGroup(working?.autoStartWhen, `${label} autoStartWhen`);\n if (autoStartWhen && working?.autoStart !== true) {\n throw new BoardDefinitionError(`${label} autoStartWhen needs autoStart.`);\n }\n const exitTool = resolveExitTool(phaseId, working?.exitTool);\n if (exitTool && nextPhases.length === 0) {\n throw new BoardDefinitionError(`${label} exit tool needs a next phase to move the card to.`);\n }\n const onEnter = runner ? phaseEnterHandlers(phase.onEnter, runner) : phase.onEnter;\n const name = resolveName(phase.name, phase.title, label);\n const description = optionalText(phase.description, `${label} description`, MAX_DESCRIPTION_LENGTH);\n return [\n phaseId,\n Object.freeze({\n name,\n ...(description !== undefined ? { description } : {}),\n kind: phase.kind,\n nextPhases,\n ...(phase.outcomes ? { outcomes: Object.freeze({ ...phase.outcomes }) } : {}),\n ...(runner ? { runner } : {}),\n ...(working?.autoStart ? { autoStart: true } : {}),\n ...(autoStartWhen ? { autoStartWhen } : {}),\n ...(exitTool ? { exitTool } : {}),\n ...(onEnter ? { onEnter: Object.freeze({ ...onEnter }) } : {}),\n ...(phase.onExit ? { onExit: Object.freeze({ ...phase.onExit }) } : {}),\n }),\n ];\n }),\n ),\n ) as Readonly<Record<PhaseId, BoardPhase<PhaseId>>>;\n const rules = Object.freeze(\n Object.fromEntries(\n (Object.entries(phases) as [PhaseId, BoardPhase<PhaseId>][]).flatMap(([phaseId, phase]) => {\n const sources = new Set([...Object.keys(phase.onEnter ?? {}), ...Object.keys(phase.onExit ?? {})]);\n if (sources.size === 0) return [];\n return [\n [\n phaseId,\n Object.freeze(\n Object.fromEntries(\n [...sources].map(source => [\n source,\n Object.freeze({\n ...(phase.onEnter?.[source as FactoryRuleSource]\n ? { onEnter: phase.onEnter[source as FactoryRuleSource] }\n : {}),\n ...(phase.onExit?.[source as FactoryRuleSource]\n ? { onExit: phase.onExit[source as FactoryRuleSource] }\n : {}),\n }),\n ]),\n ),\n ),\n ],\n ];\n }),\n ),\n ) as ReadonlyFactoryBoardRules;\n\n const kinds = new Map<string, BoardPhaseKind>();\n const roles = new Map<string, string>();\n const phaseByRole = new Map<string, PhaseId>();\n for (const [phaseId, phase] of Object.entries(phases) as [PhaseId, BoardPhase<PhaseId>][]) {\n kinds.set(phaseId, phase.kind);\n if (phase.kind !== 'working') continue;\n roles.set(phaseId, phase.runner.context);\n if (!phaseByRole.has(phase.runner.context)) phaseByRole.set(phase.runner.context, phaseId);\n }\n\n return Object.freeze({\n id: config.id,\n name: boardName,\n ...(boardDescription !== undefined ? { description: boardDescription } : {}),\n initialPhase: config.initialPhase,\n phases,\n transitions: Object.freeze(transitions),\n rules: Object.freeze(rules),\n tools,\n events,\n ...(config.transitionPolicy ? { transitionPolicy: config.transitionPolicy } : {}),\n ...(sourceClosed ? { sourceClosed } : {}),\n allowsTransition(from: PhaseId, to: PhaseId) {\n return from === to || transitions[from]?.some(transition => transition.to === to) === true;\n },\n phaseKind: (phase: string) => kinds.get(phase),\n isWorking: (phase: string) => kinds.get(phase) === 'working',\n isTerminal: (phase: string) => kinds.get(phase) === 'terminal',\n roleForPhase: (phase: string) => roles.get(phase),\n phaseForRole: (role: string) => phaseByRole.get(role),\n startsAutomatically: (phase: string, facts?: RuleFacts) => {\n const definition = phases[phase as PhaseId] as BoardPhase<PhaseId> | undefined;\n if (definition?.kind !== 'working' || definition.autoStart !== true) return false;\n if (!definition.autoStartWhen) return true;\n return facts !== undefined && evaluateRuleGroup(definition.autoStartWhen, facts);\n },\n });\n}\n"],"mappings":"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"}
|
package/dist/boards/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { BoardDefinitionError, defineBoard } from './define-board.js';
|
|
2
|
-
export
|
|
1
|
+
export { BoardDefinitionError, DEFAULT_PHASE_CONTEXT, defineBoard, FACTORY_AGENT_ID } from './define-board.js';
|
|
2
|
+
export { cardRuleFacts } from './card-facts.js';
|
|
3
|
+
export type { BoardDefinition, BoardEventIntegration, BoardEventRules, BoardPhase, BoardPhaseDefinition, BoardPhaseExitTool, BoardPhaseKind, BoardPhaseRunner, BoardSourceClosed, BoardToolResultRuleHandler, BoardToolRule, BoardToolRules, BoardTransition, } from './define-board.js';
|
|
3
4
|
export { boardEventHandlers, boardForWorkItem, eventBoardId, isTerminalWorkItem, resolveBoardClosure, resolveBoardToolRule, rulePhaseContext, rulePhaseField, resolvePhaseSemantics, withBoardClosure, workItemPhaseSemantics, } from './semantics.js';
|
|
4
5
|
export type { PhaseSemantics } from './semantics.js';
|
|
5
6
|
export type { BoardTransitionPolicy, BoardTransitionPolicyContext, BoardTransitionPolicyResult, } from './transition-policy.js';
|
|
@@ -9,6 +10,6 @@ export { reviewBoard } from './review.js';
|
|
|
9
10
|
export type { ReviewBoardPhase } from './review.js';
|
|
10
11
|
export { workBoard } from './work.js';
|
|
11
12
|
export type { WorkBoardPhase } from './work.js';
|
|
12
|
-
export declare function builtInBoard(board: 'work' | 'review'): import("./define-board.js").BoardDefinition<"review", "
|
|
13
|
+
export declare function builtInBoard(board: 'work' | 'review'): import("./define-board.js").BoardDefinition<"review", "canceled" | "done" | "intake" | "review"> | import("./define-board.js").BoardDefinition<"work", "canceled" | "done" | "execute" | "intake" | "planning" | "review" | "triage">;
|
|
13
14
|
export declare function allowsBuiltInBoardTransition(board: 'work' | 'review', from: string, to: string): boolean;
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/boards/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/boards/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/G,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EACV,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAInE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIhD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,yOAEpD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAKxG"}
|
package/dist/boards/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { BoardDefinitionError, defineBoard } from "./define-board.js";
|
|
1
|
+
import { BoardDefinitionError, DEFAULT_PHASE_CONTEXT, FACTORY_AGENT_ID, defineBoard } from "./define-board.js";
|
|
2
|
+
import { cardRuleFacts } from "./card-facts.js";
|
|
2
3
|
import { boardEventHandlers, boardForWorkItem, eventBoardId, isTerminalWorkItem, resolveBoardClosure, resolveBoardToolRule, resolvePhaseSemantics, rulePhaseContext, rulePhaseField, withBoardClosure, workItemPhaseSemantics } from "./semantics.js";
|
|
3
4
|
import { isReviewBoardPhase, reviewBoard } from "./review.js";
|
|
4
5
|
import { isWorkBoardPhase, workBoard } from "./work.js";
|
|
@@ -15,6 +16,6 @@ function allowsBuiltInBoardTransition(board, from, to) {
|
|
|
15
16
|
if (board === "work") return isWorkBoardPhase(from) && isWorkBoardPhase(to) && workBoard.allowsTransition(from, to);
|
|
16
17
|
return isReviewBoardPhase(from) && isReviewBoardPhase(to) && reviewBoard.allowsTransition(from, to);
|
|
17
18
|
}
|
|
18
|
-
export { BoardDefinitionError, allowsBuiltInBoardTransition, boardEventHandlers, boardForWorkItem, builtInBoard, createBoardRegistry, defaultBoards, defineBoard, eventBoardId, isTerminalWorkItem, resolveBoardClosure, resolveBoardToolRule, resolvePhaseSemantics, reviewBoard, rulePhaseContext, rulePhaseField, withBoardClosure, workBoard, workItemPhaseSemantics };
|
|
19
|
+
export { BoardDefinitionError, DEFAULT_PHASE_CONTEXT, FACTORY_AGENT_ID, allowsBuiltInBoardTransition, boardEventHandlers, boardForWorkItem, builtInBoard, cardRuleFacts, createBoardRegistry, defaultBoards, defineBoard, eventBoardId, isTerminalWorkItem, resolveBoardClosure, resolveBoardToolRule, resolvePhaseSemantics, reviewBoard, rulePhaseContext, rulePhaseField, withBoardClosure, workBoard, workItemPhaseSemantics };
|
|
19
20
|
|
|
20
21
|
//# sourceMappingURL=index.js.map
|
package/dist/boards/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/boards/index.ts"],"sourcesContent":["export { BoardDefinitionError, defineBoard } from './define-board.js';\nexport type {\n BoardDefinition,\n BoardEventIntegration,\n BoardEventRules,\n BoardPhaseDefinition,\n BoardPhaseKind,\n BoardSourceClosed,\n BoardToolResultRuleHandler,\n BoardToolRule,\n BoardToolRules,\n BoardTransition,\n} from './define-board.js';\nexport {\n boardEventHandlers,\n boardForWorkItem,\n eventBoardId,\n isTerminalWorkItem,\n resolveBoardClosure,\n resolveBoardToolRule,\n rulePhaseContext,\n rulePhaseField,\n resolvePhaseSemantics,\n withBoardClosure,\n workItemPhaseSemantics,\n} from './semantics.js';\nexport type { PhaseSemantics } from './semantics.js';\nexport type {\n BoardTransitionPolicy,\n BoardTransitionPolicyContext,\n BoardTransitionPolicyResult,\n} from './transition-policy.js';\nexport { createBoardRegistry, defaultBoards } from './registry.js';\nexport type { BoardRegistry, InstalledBoard } from './registry.js';\nimport { isReviewBoardPhase, reviewBoard } from './review.js';\nimport { isWorkBoardPhase, workBoard } from './work.js';\n\nexport { reviewBoard } from './review.js';\nexport type { ReviewBoardPhase } from './review.js';\nexport { workBoard } from './work.js';\nexport type { WorkBoardPhase } from './work.js';\n\nconst builtInBoards = { work: workBoard, review: reviewBoard } as const;\n\nexport function builtInBoard(board: 'work' | 'review') {\n return builtInBoards[board];\n}\n\nexport function allowsBuiltInBoardTransition(board: 'work' | 'review', from: string, to: string): boolean {\n if (board === 'work') {\n return isWorkBoardPhase(from) && isWorkBoardPhase(to) && workBoard.allowsTransition(from, to);\n }\n return isReviewBoardPhase(from) && isReviewBoardPhase(to) && reviewBoard.allowsTransition(from, to);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/boards/index.ts"],"sourcesContent":["export { BoardDefinitionError, DEFAULT_PHASE_CONTEXT, defineBoard, FACTORY_AGENT_ID } from './define-board.js';\nexport { cardRuleFacts } from './card-facts.js';\nexport type {\n BoardDefinition,\n BoardEventIntegration,\n BoardEventRules,\n BoardPhase,\n BoardPhaseDefinition,\n BoardPhaseExitTool,\n BoardPhaseKind,\n BoardPhaseRunner,\n BoardSourceClosed,\n BoardToolResultRuleHandler,\n BoardToolRule,\n BoardToolRules,\n BoardTransition,\n} from './define-board.js';\nexport {\n boardEventHandlers,\n boardForWorkItem,\n eventBoardId,\n isTerminalWorkItem,\n resolveBoardClosure,\n resolveBoardToolRule,\n rulePhaseContext,\n rulePhaseField,\n resolvePhaseSemantics,\n withBoardClosure,\n workItemPhaseSemantics,\n} from './semantics.js';\nexport type { PhaseSemantics } from './semantics.js';\nexport type {\n BoardTransitionPolicy,\n BoardTransitionPolicyContext,\n BoardTransitionPolicyResult,\n} from './transition-policy.js';\nexport { createBoardRegistry, defaultBoards } from './registry.js';\nexport type { BoardRegistry, InstalledBoard } from './registry.js';\nimport { isReviewBoardPhase, reviewBoard } from './review.js';\nimport { isWorkBoardPhase, workBoard } from './work.js';\n\nexport { reviewBoard } from './review.js';\nexport type { ReviewBoardPhase } from './review.js';\nexport { workBoard } from './work.js';\nexport type { WorkBoardPhase } from './work.js';\n\nconst builtInBoards = { work: workBoard, review: reviewBoard } as const;\n\nexport function builtInBoard(board: 'work' | 'review') {\n return builtInBoards[board];\n}\n\nexport function allowsBuiltInBoardTransition(board: 'work' | 'review', from: string, to: string): boolean {\n if (board === 'work') {\n return isWorkBoardPhase(from) && isWorkBoardPhase(to) && workBoard.allowsTransition(from, to);\n }\n return isReviewBoardPhase(from) && isReviewBoardPhase(to) && reviewBoard.allowsTransition(from, to);\n}\n"],"mappings":";;;;;;;AA8CA,MAAM,gBAAgB;CAAE,MAAM;CAAW,QAAQ;AAAY;AAE7D,SAAgB,aAAa,OAA0B;CACrD,OAAO,cAAc;AACvB;AAEA,SAAgB,6BAA6B,OAA0B,MAAc,IAAqB;CACxG,IAAI,UAAU,QACZ,OAAO,iBAAiB,IAAI,KAAK,iBAAiB,EAAE,KAAK,UAAU,iBAAiB,MAAM,EAAE;CAE9F,OAAO,mBAAmB,IAAI,KAAK,mBAAmB,EAAE,KAAK,YAAY,iBAAiB,MAAM,EAAE;AACpG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The built-in Work lane a role's run belongs to: `plan` plans, `work` builds. Undefined on other boards. */
|
|
2
|
+
export declare function workLaneForRole(board: unknown, role: string): string | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* Whether a built-in Work stage carries a run decided for `role`. Planning,
|
|
5
|
+
* Building and Review share the `work` context, so the skill tells them apart:
|
|
6
|
+
* Planning carries `factory-plan` runs (and runs for the old `plan` role),
|
|
7
|
+
* Building and Review the other `work` runs. Undefined on other boards.
|
|
8
|
+
*/
|
|
9
|
+
export declare function workStageCarries(board: unknown, stage: string, role: string, skillName: unknown): boolean | undefined;
|
|
10
|
+
/** The session key a Work build falls back to when the card has no `work` session yet. */
|
|
11
|
+
export declare function legacyPlanRoleFor(boardId: string, role: string): string | undefined;
|
|
12
|
+
/** Whether a Work card in Planning still holds its planner under the old `plan` key. */
|
|
13
|
+
export declare function holdsLegacyPlanner(boardId: string, stage: string, sessions: Record<string, unknown>): boolean;
|
|
14
|
+
//# sourceMappingURL=legacy-plan-role.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-plan-role.d.ts","sourceRoot":"","sources":["../../src/boards/legacy-plan-role.ts"],"names":[],"mappings":"AAiBA,8GAA8G;AAC9G,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEhF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAMrH;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnF;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAE7G"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { factoryLaneForRole } from "../rules/types.js";
|
|
2
|
+
import { workBoard } from "./work.js";
|
|
3
|
+
// src/boards/legacy-plan-role.ts
|
|
4
|
+
const LEGACY_PLAN_ROLE = "plan";
|
|
5
|
+
/** The built-in Work lane a role's run belongs to: `plan` plans, `work` builds. Undefined on other boards. */
|
|
6
|
+
function workLaneForRole(board, role) {
|
|
7
|
+
return board === workBoard ? factoryLaneForRole(role) : void 0;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Whether a built-in Work stage carries a run decided for `role`. Planning,
|
|
11
|
+
* Building and Review share the `work` context, so the skill tells them apart:
|
|
12
|
+
* Planning carries `factory-plan` runs (and runs for the old `plan` role),
|
|
13
|
+
* Building and Review the other `work` runs. Undefined on other boards.
|
|
14
|
+
*/
|
|
15
|
+
function workStageCarries(board, stage, role, skillName) {
|
|
16
|
+
if (board !== workBoard) return void 0;
|
|
17
|
+
if (role === LEGACY_PLAN_ROLE) return stage === "planning";
|
|
18
|
+
if (role !== "work") return workBoard.roleForPhase(stage) === role;
|
|
19
|
+
if (workBoard.roleForPhase(stage) !== "work") return false;
|
|
20
|
+
return stage === "planning" === (skillName === "factory-plan");
|
|
21
|
+
}
|
|
22
|
+
/** The session key a Work build falls back to when the card has no `work` session yet. */
|
|
23
|
+
function legacyPlanRoleFor(boardId, role) {
|
|
24
|
+
return boardId === "work" && role === "work" ? LEGACY_PLAN_ROLE : void 0;
|
|
25
|
+
}
|
|
26
|
+
/** Whether a Work card in Planning still holds its planner under the old `plan` key. */
|
|
27
|
+
function holdsLegacyPlanner(boardId, stage, sessions) {
|
|
28
|
+
return boardId === "work" && stage === "planning" && sessions[LEGACY_PLAN_ROLE] !== void 0;
|
|
29
|
+
}
|
|
30
|
+
export { holdsLegacyPlanner, legacyPlanRoleFor, workLaneForRole, workStageCarries };
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=legacy-plan-role.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-plan-role.js","names":[],"sources":["../../src/boards/legacy-plan-role.ts"],"sourcesContent":["import { factoryLaneForRole } from '../rules/types.js';\nimport { workBoard } from './work.js';\n\n/*\n * Compatibility for the Work board's old `plan` role. Planning moved into the\n * `work` context, so Work's lanes no longer follow from its contexts alone, and\n * cards planned before the move hold their planner under `plan`. Delete these\n * once no card holds a `plan` session and no queued decision names `plan`.\n */\n\nconst LEGACY_PLAN_ROLE = 'plan';\n\n/*\n * Only the built-in Work board gets these rules. A board installed as `work` in\n * place of it is matched by its own contexts, like any other board.\n */\n\n/** The built-in Work lane a role's run belongs to: `plan` plans, `work` builds. Undefined on other boards. */\nexport function workLaneForRole(board: unknown, role: string): string | undefined {\n return board === workBoard ? factoryLaneForRole(role) : undefined;\n}\n\n/**\n * Whether a built-in Work stage carries a run decided for `role`. Planning,\n * Building and Review share the `work` context, so the skill tells them apart:\n * Planning carries `factory-plan` runs (and runs for the old `plan` role),\n * Building and Review the other `work` runs. Undefined on other boards.\n */\nexport function workStageCarries(board: unknown, stage: string, role: string, skillName: unknown): boolean | undefined {\n if (board !== workBoard) return undefined;\n if (role === LEGACY_PLAN_ROLE) return stage === 'planning';\n if (role !== 'work') return workBoard.roleForPhase(stage) === role;\n if (workBoard.roleForPhase(stage) !== 'work') return false;\n return (stage === 'planning') === (skillName === 'factory-plan');\n}\n\n/** The session key a Work build falls back to when the card has no `work` session yet. */\nexport function legacyPlanRoleFor(boardId: string, role: string): string | undefined {\n return boardId === 'work' && role === 'work' ? LEGACY_PLAN_ROLE : undefined;\n}\n\n/** Whether a Work card in Planning still holds its planner under the old `plan` key. */\nexport function holdsLegacyPlanner(boardId: string, stage: string, sessions: Record<string, unknown>): boolean {\n return boardId === 'work' && stage === 'planning' && sessions[LEGACY_PLAN_ROLE] !== undefined;\n}\n"],"mappings":";;;AAUA,MAAM,mBAAmB;;AAQzB,SAAgB,gBAAgB,OAAgB,MAAkC;CAChF,OAAO,UAAU,YAAY,mBAAmB,IAAI,IAAI,KAAA;AAC1D;;;;;;;AAQA,SAAgB,iBAAiB,OAAgB,OAAe,MAAc,WAAyC;CACrH,IAAI,UAAU,WAAW,OAAO,KAAA;CAChC,IAAI,SAAS,kBAAkB,OAAO,UAAU;CAChD,IAAI,SAAS,QAAQ,OAAO,UAAU,aAAa,KAAK,MAAM;CAC9D,IAAI,UAAU,aAAa,KAAK,MAAM,QAAQ,OAAO;CACrD,OAAQ,UAAU,gBAAiB,cAAc;AACnD;;AAGA,SAAgB,kBAAkB,SAAiB,MAAkC;CACnF,OAAO,YAAY,UAAU,SAAS,SAAS,mBAAmB,KAAA;AACpE;;AAGA,SAAgB,mBAAmB,SAAiB,OAAe,UAA4C;CAC7G,OAAO,YAAY,UAAU,UAAU,cAAc,SAAS,sBAAsB,KAAA;AACtF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FactoryCommitDecision } from '../rules/types.js';
|
|
2
|
+
import type { WorkItemRow } from '../storage/domains/work-items/base.js';
|
|
3
|
+
import type { BoardRegistry } from './registry.js';
|
|
4
|
+
type Card = Pick<WorkItemRow, 'board' | 'externalSource' | 'stages' | 'title' | 'metadata'>;
|
|
5
|
+
/**
|
|
6
|
+
* Whether the decision starts the run of a phase that starts on its own for this card
|
|
7
|
+
* (`autoStart`, and `autoStartWhen` when set), so it needs nobody's approval.
|
|
8
|
+
*/
|
|
9
|
+
export declare function startsInAutoPhase(boards: BoardRegistry, item: Card, decision: FactoryCommitDecision): boolean;
|
|
10
|
+
/** The exit tool of the card's phase when it is approved without a person for this card. */
|
|
11
|
+
export declare function autoApprovedExitTool(boards: BoardRegistry, item: Card): string | undefined;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=phase-automation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phase-automation.d.ts","sourceRoot":"","sources":["../../src/boards/phase-automation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,KAAK,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,gBAAgB,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC,CAAC;AAE5F;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAQ7G;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAK1F"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { evaluateRuleGroup } from "../rules/rule-group.js";
|
|
2
|
+
import { cardRuleFacts } from "./card-facts.js";
|
|
3
|
+
import { boardForWorkItem } from "./semantics.js";
|
|
4
|
+
// src/boards/phase-automation.ts
|
|
5
|
+
/**
|
|
6
|
+
* Whether the decision starts the run of a phase that starts on its own for this card
|
|
7
|
+
* (`autoStart`, and `autoStartWhen` when set), so it needs nobody's approval.
|
|
8
|
+
*/
|
|
9
|
+
function startsInAutoPhase(boards, item, decision) {
|
|
10
|
+
if (decision.type === "transition") return boards.get(decision.board)?.startsAutomatically(decision.stage, cardRuleFacts(item)) === true;
|
|
11
|
+
if (decision.type !== "invokeSkill" || item.stages.length !== 1) return false;
|
|
12
|
+
const board = boards.get(boardForWorkItem(item));
|
|
13
|
+
const stage = item.stages[0];
|
|
14
|
+
return board?.roleForPhase(stage) === decision.role && board.startsAutomatically(stage, cardRuleFacts(item));
|
|
15
|
+
}
|
|
16
|
+
/** The exit tool of the card's phase when it is approved without a person for this card. */
|
|
17
|
+
function autoApprovedExitTool(boards, item) {
|
|
18
|
+
if (item.stages.length !== 1) return void 0;
|
|
19
|
+
const phase = boards.get(boardForWorkItem(item))?.phases[item.stages[0]];
|
|
20
|
+
if (phase?.kind !== "working" || !phase.exitTool?.autoApprove) return void 0;
|
|
21
|
+
return evaluateRuleGroup(phase.exitTool.autoApproveWhen, cardRuleFacts(item)) ? phase.exitTool.id : void 0;
|
|
22
|
+
}
|
|
23
|
+
export { autoApprovedExitTool, startsInAutoPhase };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=phase-automation.js.map
|