@ai-agent-forge/plugin-multi-agent 0.88.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 +3 -0
- package/dist/child-facade.d.ts +44 -0
- package/dist/child-facade.d.ts.map +1 -0
- package/dist/child-facade.js +56 -0
- package/dist/child-facade.js.map +1 -0
- package/dist/dependency-wiring.d.ts +48 -0
- package/dist/dependency-wiring.d.ts.map +1 -0
- package/dist/dependency-wiring.js +56 -0
- package/dist/dependency-wiring.js.map +1 -0
- package/dist/domain-recovery.d.ts +60 -0
- package/dist/domain-recovery.d.ts.map +1 -0
- package/dist/domain-recovery.js +94 -0
- package/dist/domain-recovery.js.map +1 -0
- package/dist/first-roles.d.ts +30 -0
- package/dist/first-roles.d.ts.map +1 -0
- package/dist/first-roles.js +83 -0
- package/dist/first-roles.js.map +1 -0
- package/dist/goal-plugin.d.ts +38 -0
- package/dist/goal-plugin.d.ts.map +1 -0
- package/dist/goal-plugin.js +132 -0
- package/dist/goal-plugin.js.map +1 -0
- package/dist/identity.d.ts +29 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +22 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/plan-plugin.d.ts +56 -0
- package/dist/plan-plugin.d.ts.map +1 -0
- package/dist/plan-plugin.js +169 -0
- package/dist/plan-plugin.js.map +1 -0
- package/dist/policy-manifest.d.ts +53 -0
- package/dist/policy-manifest.d.ts.map +1 -0
- package/dist/policy-manifest.js +66 -0
- package/dist/policy-manifest.js.map +1 -0
- package/dist/role-assembly.d.ts +47 -0
- package/dist/role-assembly.d.ts.map +1 -0
- package/dist/role-assembly.js +31 -0
- package/dist/role-assembly.js.map +1 -0
- package/dist/role-catalog.d.ts +43 -0
- package/dist/role-catalog.d.ts.map +1 -0
- package/dist/role-catalog.js +132 -0
- package/dist/role-catalog.js.map +1 -0
- package/dist/role-orchestrator.d.ts +123 -0
- package/dist/role-orchestrator.d.ts.map +1 -0
- package/dist/role-orchestrator.js +228 -0
- package/dist/role-orchestrator.js.map +1 -0
- package/dist/role-runner.d.ts +99 -0
- package/dist/role-runner.d.ts.map +1 -0
- package/dist/role-runner.js +100 -0
- package/dist/role-runner.js.map +1 -0
- package/dist/root-facade.d.ts +36 -0
- package/dist/root-facade.d.ts.map +1 -0
- package/dist/root-facade.js +58 -0
- package/dist/root-facade.js.map +1 -0
- package/dist/skill-discovery-wiring.d.ts +58 -0
- package/dist/skill-discovery-wiring.d.ts.map +1 -0
- package/dist/skill-discovery-wiring.js +80 -0
- package/dist/skill-discovery-wiring.js.map +1 -0
- package/dist/state-store.d.ts +62 -0
- package/dist/state-store.d.ts.map +1 -0
- package/dist/state-store.js +158 -0
- package/dist/state-store.js.map +1 -0
- package/dist/todo-plugin.d.ts +47 -0
- package/dist/todo-plugin.d.ts.map +1 -0
- package/dist/todo-plugin.js +147 -0
- package/dist/todo-plugin.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a
|
|
3
|
+
* transition store.
|
|
4
|
+
*
|
|
5
|
+
* Status graph: null → draft → active → achieved, and draft/active → archived.
|
|
6
|
+
* `achieve` requires at least one evidence reference. The plugin holds NO
|
|
7
|
+
* shadow state: every read derives status, revision, title, and evidence from
|
|
8
|
+
* the transition history, so recovery is exactly a store replay.
|
|
9
|
+
*/
|
|
10
|
+
import type { TransitionEvidenceRefV1, TransitionStoreV1 } from "./state-store.ts";
|
|
11
|
+
export type GoalStatusV1 = "draft" | "active" | "achieved" | "archived";
|
|
12
|
+
export interface GoalV1 {
|
|
13
|
+
readonly goalId: string;
|
|
14
|
+
readonly owner: string;
|
|
15
|
+
readonly title: string;
|
|
16
|
+
readonly status: GoalStatusV1;
|
|
17
|
+
readonly evidence: readonly TransitionEvidenceRefV1[];
|
|
18
|
+
readonly revision: number;
|
|
19
|
+
}
|
|
20
|
+
export interface GoalPluginV1 {
|
|
21
|
+
createGoal(input: {
|
|
22
|
+
readonly goalId: string;
|
|
23
|
+
readonly owner: string;
|
|
24
|
+
readonly title: string;
|
|
25
|
+
}): GoalV1;
|
|
26
|
+
activate(goalId: string, owner: string, options?: {
|
|
27
|
+
readonly operationId?: string;
|
|
28
|
+
}): GoalV1;
|
|
29
|
+
achieve(goalId: string, owner: string, evidence: readonly TransitionEvidenceRefV1[], options?: {
|
|
30
|
+
readonly operationId?: string;
|
|
31
|
+
}): GoalV1;
|
|
32
|
+
archive(goalId: string, owner: string): GoalV1;
|
|
33
|
+
get(goalId: string, owner: string): GoalV1 | undefined;
|
|
34
|
+
}
|
|
35
|
+
export declare function createGoalPlugin(options: {
|
|
36
|
+
readonly transitions: TransitionStoreV1;
|
|
37
|
+
}): GoalPluginV1;
|
|
38
|
+
//# sourceMappingURL=goal-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-plugin.d.ts","sourceRoot":"","sources":["../src/goal-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;AAExE,MAAM,WAAW,MAAM;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACvG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC7F,OAAO,CACN,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,uBAAuB,EAAE,EAC5C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACzC,MAAM,CAAC;IACV,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,GAAG,YAAY,CA8InG","sourcesContent":["/**\n * Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a\n * transition store.\n *\n * Status graph: null → draft → active → achieved, and draft/active → archived.\n * `achieve` requires at least one evidence reference. The plugin holds NO\n * shadow state: every read derives status, revision, title, and evidence from\n * the transition history, so recovery is exactly a store replay.\n */\n\nimport { t } from \"@agent-forge/host/i18n\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type GoalStatusV1 = \"draft\" | \"active\" | \"achieved\" | \"archived\";\n\nexport interface GoalV1 {\n\treadonly goalId: string;\n\treadonly owner: string;\n\treadonly title: string;\n\treadonly status: GoalStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface GoalPluginV1 {\n\tcreateGoal(input: { readonly goalId: string; readonly owner: string; readonly title: string }): GoalV1;\n\tactivate(goalId: string, owner: string, options?: { readonly operationId?: string }): GoalV1;\n\tachieve(\n\t\tgoalId: string,\n\t\towner: string,\n\t\tevidence: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): GoalV1;\n\tarchive(goalId: string, owner: string): GoalV1;\n\tget(goalId: string, owner: string): GoalV1 | undefined;\n}\n\nexport function createGoalPlugin(options: { readonly transitions: TransitionStoreV1 }): GoalPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst goalHistory = (goalId: string, owner: string) =>\n\t\ttransitions.history(goalId).filter((record) => record.domain === \"goal\" && record.owner === owner);\n\n\tconst current = (goalId: string, owner: string): { status: GoalStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\tif (state === undefined || goalHistory(goalId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as GoalStatusV1, revision: state.revision };\n\t};\n\n\tconst titleOf = (goalId: string, owner: string): string => {\n\t\tfor (const record of goalHistory(goalId, owner)) {\n\t\t\tif (record.fromStatus !== null) continue;\n\t\t\tconst payload = record.payload;\n\t\t\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\t\t\tconst title = (payload as Record<string, unknown>).title;\n\t\t\t\tif (typeof title === \"string\") return title;\n\t\t\t}\n\t\t}\n\t\treturn goalId;\n\t};\n\n\tconst goalGet = (goalId: string, owner: string): GoalV1 | undefined => {\n\t\tconst state = current(goalId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = goalHistory(goalId, owner);\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\ttoStatus: GoalStatusV1,\n\t\toperationId?: string,\n\t): GoalV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = goalHistory(goalId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? goalGet(goalId, owner) : undefined;\n\t};\n\n\tconst transitionGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\tfromStatus: GoalStatusV1 | null,\n\t\ttoStatus: GoalStatusV1,\n\t\tgoalOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: { readonly title: string };\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): GoalV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"goal\",\n\t\t\tentityId: goalId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: goalOptions.operationId ?? `${toStatus}:${goalId}`,\n\t\t\tevidence: goalOptions.evidence,\n\t\t\tpayload: goalOptions.payload,\n\t\t});\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state?.status as GoalStatusV1,\n\t\t\tevidence: goalOptions.evidence ?? [],\n\t\t\t// v8 ignore next -- transition 刚写入 currentStatus,必可读到 revision\n\t\t\trevision: state?.revision ?? 0,\n\t\t};\n\t};\n\n\treturn {\n\t\tcreateGoal({ goalId, owner, title }) {\n\t\t\tif (title.trim().length === 0) throw new Error(t(\"Goal title must be a non-empty string\"));\n\t\t\treturn transitionGoal(goalId, owner, null, \"draft\", {\n\t\t\t\tpayload: { title },\n\t\t\t\toperationId: `create:${goalId}`,\n\t\t\t});\n\t\t},\n\t\tactivate(goalId, owner, activateOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"active\", activateOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"draft\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be in draft status to activate (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, \"draft\", \"active\", { operationId: activateOptions?.operationId });\n\t\t},\n\t\tachieve(goalId, owner, evidence, achieveOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"achieved\", achieveOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be active to achieve (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (evidence.length === 0) throw new Error(t(\"Achieving a goal requires at least one evidence reference\"));\n\t\t\treturn transitionGoal(goalId, owner, \"active\", \"achieved\", {\n\t\t\t\tevidence,\n\t\t\t\toperationId: achieveOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tarchive(goalId, owner) {\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (!existing || existing.status === \"achieved\" || existing.status === \"archived\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} cannot be archived from status {status}\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, existing.status, \"archived\", {});\n\t\t},\n\t\tget(goalId, owner) {\n\t\t\treturn goalGet(goalId, owner);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a
|
|
3
|
+
* transition store.
|
|
4
|
+
*
|
|
5
|
+
* Status graph: null → draft → active → achieved, and draft/active → archived.
|
|
6
|
+
* `achieve` requires at least one evidence reference. The plugin holds NO
|
|
7
|
+
* shadow state: every read derives status, revision, title, and evidence from
|
|
8
|
+
* the transition history, so recovery is exactly a store replay.
|
|
9
|
+
*/
|
|
10
|
+
import { t } from "@agent-forge/host/i18n";
|
|
11
|
+
export function createGoalPlugin(options) {
|
|
12
|
+
const transitions = options.transitions;
|
|
13
|
+
const goalHistory = (goalId, owner) => transitions.history(goalId).filter((record) => record.domain === "goal" && record.owner === owner);
|
|
14
|
+
const current = (goalId, owner) => {
|
|
15
|
+
const state = transitions.currentStatus("goal", goalId);
|
|
16
|
+
if (state === undefined || goalHistory(goalId, owner).length === 0)
|
|
17
|
+
return undefined;
|
|
18
|
+
return { status: state.status, revision: state.revision };
|
|
19
|
+
};
|
|
20
|
+
const titleOf = (goalId, owner) => {
|
|
21
|
+
for (const record of goalHistory(goalId, owner)) {
|
|
22
|
+
if (record.fromStatus !== null)
|
|
23
|
+
continue;
|
|
24
|
+
const payload = record.payload;
|
|
25
|
+
if (payload !== null && typeof payload === "object" && !Array.isArray(payload)) {
|
|
26
|
+
const title = payload.title;
|
|
27
|
+
if (typeof title === "string")
|
|
28
|
+
return title;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return goalId;
|
|
32
|
+
};
|
|
33
|
+
const goalGet = (goalId, owner) => {
|
|
34
|
+
const state = current(goalId, owner);
|
|
35
|
+
if (!state)
|
|
36
|
+
return undefined;
|
|
37
|
+
const history = goalHistory(goalId, owner);
|
|
38
|
+
const lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];
|
|
39
|
+
return {
|
|
40
|
+
goalId,
|
|
41
|
+
owner,
|
|
42
|
+
title: titleOf(goalId, owner),
|
|
43
|
+
status: state.status,
|
|
44
|
+
evidence: lastEvidence,
|
|
45
|
+
revision: state.revision,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */
|
|
49
|
+
const replayedGoal = (goalId, owner, toStatus, operationId) => {
|
|
50
|
+
if (!operationId)
|
|
51
|
+
return undefined;
|
|
52
|
+
const applied = goalHistory(goalId, owner).some((record) => record.toStatus === toStatus && record.operationId === operationId);
|
|
53
|
+
return applied ? goalGet(goalId, owner) : undefined;
|
|
54
|
+
};
|
|
55
|
+
const transitionGoal = (goalId, owner, fromStatus, toStatus, goalOptions) => {
|
|
56
|
+
transitions.transition({
|
|
57
|
+
domain: "goal",
|
|
58
|
+
entityId: goalId,
|
|
59
|
+
owner,
|
|
60
|
+
fromStatus,
|
|
61
|
+
toStatus,
|
|
62
|
+
operationId: goalOptions.operationId ?? `${toStatus}:${goalId}`,
|
|
63
|
+
evidence: goalOptions.evidence,
|
|
64
|
+
payload: goalOptions.payload,
|
|
65
|
+
});
|
|
66
|
+
const state = transitions.currentStatus("goal", goalId);
|
|
67
|
+
return {
|
|
68
|
+
goalId,
|
|
69
|
+
owner,
|
|
70
|
+
title: titleOf(goalId, owner),
|
|
71
|
+
status: state?.status,
|
|
72
|
+
evidence: goalOptions.evidence ?? [],
|
|
73
|
+
// v8 ignore next -- transition 刚写入 currentStatus,必可读到 revision
|
|
74
|
+
revision: state?.revision ?? 0,
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
createGoal({ goalId, owner, title }) {
|
|
79
|
+
if (title.trim().length === 0)
|
|
80
|
+
throw new Error(t("Goal title must be a non-empty string"));
|
|
81
|
+
return transitionGoal(goalId, owner, null, "draft", {
|
|
82
|
+
payload: { title },
|
|
83
|
+
operationId: `create:${goalId}`,
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
activate(goalId, owner, activateOptions) {
|
|
87
|
+
const replayed = replayedGoal(goalId, owner, "active", activateOptions?.operationId);
|
|
88
|
+
if (replayed)
|
|
89
|
+
return replayed;
|
|
90
|
+
const existing = current(goalId, owner);
|
|
91
|
+
if (existing?.status !== "draft") {
|
|
92
|
+
throw new Error(t("Goal {goalId} must be in draft status to activate (current: {status})", {
|
|
93
|
+
goalId,
|
|
94
|
+
status: existing?.status ?? "missing",
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
return transitionGoal(goalId, owner, "draft", "active", { operationId: activateOptions?.operationId });
|
|
98
|
+
},
|
|
99
|
+
achieve(goalId, owner, evidence, achieveOptions) {
|
|
100
|
+
const replayed = replayedGoal(goalId, owner, "achieved", achieveOptions?.operationId);
|
|
101
|
+
if (replayed)
|
|
102
|
+
return replayed;
|
|
103
|
+
const existing = current(goalId, owner);
|
|
104
|
+
if (existing?.status !== "active") {
|
|
105
|
+
throw new Error(t("Goal {goalId} must be active to achieve (current: {status})", {
|
|
106
|
+
goalId,
|
|
107
|
+
status: existing?.status ?? "missing",
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
if (evidence.length === 0)
|
|
111
|
+
throw new Error(t("Achieving a goal requires at least one evidence reference"));
|
|
112
|
+
return transitionGoal(goalId, owner, "active", "achieved", {
|
|
113
|
+
evidence,
|
|
114
|
+
operationId: achieveOptions?.operationId,
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
archive(goalId, owner) {
|
|
118
|
+
const existing = current(goalId, owner);
|
|
119
|
+
if (!existing || existing.status === "achieved" || existing.status === "archived") {
|
|
120
|
+
throw new Error(t("Goal {goalId} cannot be archived from status {status}", {
|
|
121
|
+
goalId,
|
|
122
|
+
status: existing?.status ?? "missing",
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
return transitionGoal(goalId, owner, existing.status, "archived", {});
|
|
126
|
+
},
|
|
127
|
+
get(goalId, owner) {
|
|
128
|
+
return goalGet(goalId, owner);
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=goal-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-plugin.js","sourceRoot":"","sources":["../src/goal-plugin.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Goal plugin (2.3b) — Goal schema, evidence, and recovery on top of the 2.3a\n * transition store.\n *\n * Status graph: null → draft → active → achieved, and draft/active → archived.\n * `achieve` requires at least one evidence reference. The plugin holds NO\n * shadow state: every read derives status, revision, title, and evidence from\n * the transition history, so recovery is exactly a store replay.\n */\n\nimport { t } from \"@agent-forge/host/i18n\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type GoalStatusV1 = \"draft\" | \"active\" | \"achieved\" | \"archived\";\n\nexport interface GoalV1 {\n\treadonly goalId: string;\n\treadonly owner: string;\n\treadonly title: string;\n\treadonly status: GoalStatusV1;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revision: number;\n}\n\nexport interface GoalPluginV1 {\n\tcreateGoal(input: { readonly goalId: string; readonly owner: string; readonly title: string }): GoalV1;\n\tactivate(goalId: string, owner: string, options?: { readonly operationId?: string }): GoalV1;\n\tachieve(\n\t\tgoalId: string,\n\t\towner: string,\n\t\tevidence: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly operationId?: string },\n\t): GoalV1;\n\tarchive(goalId: string, owner: string): GoalV1;\n\tget(goalId: string, owner: string): GoalV1 | undefined;\n}\n\nexport function createGoalPlugin(options: { readonly transitions: TransitionStoreV1 }): GoalPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst goalHistory = (goalId: string, owner: string) =>\n\t\ttransitions.history(goalId).filter((record) => record.domain === \"goal\" && record.owner === owner);\n\n\tconst current = (goalId: string, owner: string): { status: GoalStatusV1; revision: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\tif (state === undefined || goalHistory(goalId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as GoalStatusV1, revision: state.revision };\n\t};\n\n\tconst titleOf = (goalId: string, owner: string): string => {\n\t\tfor (const record of goalHistory(goalId, owner)) {\n\t\t\tif (record.fromStatus !== null) continue;\n\t\t\tconst payload = record.payload;\n\t\t\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\t\t\tconst title = (payload as Record<string, unknown>).title;\n\t\t\t\tif (typeof title === \"string\") return title;\n\t\t\t}\n\t\t}\n\t\treturn goalId;\n\t};\n\n\tconst goalGet = (goalId: string, owner: string): GoalV1 | undefined => {\n\t\tconst state = current(goalId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = goalHistory(goalId, owner);\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state.status,\n\t\t\tevidence: lastEvidence,\n\t\t\trevision: state.revision,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\ttoStatus: GoalStatusV1,\n\t\toperationId?: string,\n\t): GoalV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = goalHistory(goalId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? goalGet(goalId, owner) : undefined;\n\t};\n\n\tconst transitionGoal = (\n\t\tgoalId: string,\n\t\towner: string,\n\t\tfromStatus: GoalStatusV1 | null,\n\t\ttoStatus: GoalStatusV1,\n\t\tgoalOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: { readonly title: string };\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): GoalV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"goal\",\n\t\t\tentityId: goalId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: goalOptions.operationId ?? `${toStatus}:${goalId}`,\n\t\t\tevidence: goalOptions.evidence,\n\t\t\tpayload: goalOptions.payload,\n\t\t});\n\t\tconst state = transitions.currentStatus(\"goal\", goalId);\n\t\treturn {\n\t\t\tgoalId,\n\t\t\towner,\n\t\t\ttitle: titleOf(goalId, owner),\n\t\t\tstatus: state?.status as GoalStatusV1,\n\t\t\tevidence: goalOptions.evidence ?? [],\n\t\t\t// v8 ignore next -- transition 刚写入 currentStatus,必可读到 revision\n\t\t\trevision: state?.revision ?? 0,\n\t\t};\n\t};\n\n\treturn {\n\t\tcreateGoal({ goalId, owner, title }) {\n\t\t\tif (title.trim().length === 0) throw new Error(t(\"Goal title must be a non-empty string\"));\n\t\t\treturn transitionGoal(goalId, owner, null, \"draft\", {\n\t\t\t\tpayload: { title },\n\t\t\t\toperationId: `create:${goalId}`,\n\t\t\t});\n\t\t},\n\t\tactivate(goalId, owner, activateOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"active\", activateOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"draft\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be in draft status to activate (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, \"draft\", \"active\", { operationId: activateOptions?.operationId });\n\t\t},\n\t\tachieve(goalId, owner, evidence, achieveOptions) {\n\t\t\tconst replayed = replayedGoal(goalId, owner, \"achieved\", achieveOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (existing?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} must be active to achieve (current: {status})\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (evidence.length === 0) throw new Error(t(\"Achieving a goal requires at least one evidence reference\"));\n\t\t\treturn transitionGoal(goalId, owner, \"active\", \"achieved\", {\n\t\t\t\tevidence,\n\t\t\t\toperationId: achieveOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tarchive(goalId, owner) {\n\t\t\tconst existing = current(goalId, owner);\n\t\t\tif (!existing || existing.status === \"achieved\" || existing.status === \"archived\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Goal {goalId} cannot be archived from status {status}\", {\n\t\t\t\t\t\tgoalId,\n\t\t\t\t\t\tstatus: existing?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionGoal(goalId, owner, existing.status, \"archived\", {});\n\t\t},\n\t\tget(goalId, owner) {\n\t\t\treturn goalGet(goalId, owner);\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile identity slice (2.0a) — package-local support for the multi-agent
|
|
3
|
+
* slices: the resolved-plugin-manifest shape consumed by dependency wiring
|
|
4
|
+
* (2.5a) and discovery wiring (4.4), plus the FNV-1a key-order-stable digest
|
|
5
|
+
* used by the default policy manifest (2.7e).
|
|
6
|
+
*
|
|
7
|
+
* Migrated verbatim from the host's `src/profile/identity.ts`
|
|
8
|
+
* (`buildProfileIdentityV1` / `ProfileIdentityV1` / `profileIdentitiesCompatible`
|
|
9
|
+
* stay host-owned). `JsonValue` now comes from `@agent-forge/plugin-sdk`
|
|
10
|
+
* because `@agent-forge/ai` is outside this package's supply list (D-082).
|
|
11
|
+
*/
|
|
12
|
+
import type { JsonValue } from "@agent-forge/plugin-sdk";
|
|
13
|
+
/** One resolved plugin manifest entry of a Profile. */
|
|
14
|
+
export interface ResolvedPluginManifestV1 {
|
|
15
|
+
readonly pluginId: string;
|
|
16
|
+
readonly pluginVersion: string;
|
|
17
|
+
readonly manifestPath?: string;
|
|
18
|
+
readonly capabilityRefs: readonly {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly version: number;
|
|
21
|
+
}[];
|
|
22
|
+
readonly selectedAdapter?: {
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly version: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** FNV-1a 64-bit digest over the key-order-stable JSON serialization. */
|
|
28
|
+
export declare function stableJsonDigest(value: JsonValue): string;
|
|
29
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,uDAAuD;AACvD,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtF,QAAQ,CAAC,eAAe,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E;AAaD,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAQzD","sourcesContent":["/**\n * Profile identity slice (2.0a) — package-local support for the multi-agent\n * slices: the resolved-plugin-manifest shape consumed by dependency wiring\n * (2.5a) and discovery wiring (4.4), plus the FNV-1a key-order-stable digest\n * used by the default policy manifest (2.7e).\n *\n * Migrated verbatim from the host's `src/profile/identity.ts`\n * (`buildProfileIdentityV1` / `ProfileIdentityV1` / `profileIdentitiesCompatible`\n * stay host-owned). `JsonValue` now comes from `@agent-forge/plugin-sdk`\n * because `@agent-forge/ai` is outside this package's supply list (D-082).\n */\nimport type { JsonValue } from \"@agent-forge/plugin-sdk\";\n\n/** One resolved plugin manifest entry of a Profile. */\nexport interface ResolvedPluginManifestV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestPath?: string;\n\treadonly capabilityRefs: readonly { readonly id: string; readonly version: number }[];\n\treadonly selectedAdapter?: { readonly id: string; readonly version: string };\n}\n\nfunction stableStringify(value: JsonValue): string {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"number\" || typeof value === \"string\") {\n\t\treturn JSON.stringify(value);\n\t}\n\tif (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(\",\")}]`;\n\tconst entries = Object.keys(value)\n\t\t.sort()\n\t\t.map((key) => `${JSON.stringify(key)}:${stableStringify((value as Record<string, JsonValue>)[key])}`);\n\treturn `{${entries.join(\",\")}}`;\n}\n\n/** FNV-1a 64-bit digest over the key-order-stable JSON serialization. */\nexport function stableJsonDigest(value: JsonValue): string {\n\tconst serialized = stableStringify(value);\n\tlet digest = 14695981039346656037n;\n\tfor (const byte of new TextEncoder().encode(serialized)) {\n\t\tdigest ^= BigInt(byte);\n\t\tdigest = BigInt.asUintN(64, digest * 1099511628211n);\n\t}\n\treturn digest.toString(16).padStart(16, \"0\");\n}\n"]}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function stableStringify(value) {
|
|
2
|
+
if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
|
|
3
|
+
return JSON.stringify(value);
|
|
4
|
+
}
|
|
5
|
+
if (Array.isArray(value))
|
|
6
|
+
return `[${value.map((item) => stableStringify(item)).join(",")}]`;
|
|
7
|
+
const entries = Object.keys(value)
|
|
8
|
+
.sort()
|
|
9
|
+
.map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`);
|
|
10
|
+
return `{${entries.join(",")}}`;
|
|
11
|
+
}
|
|
12
|
+
/** FNV-1a 64-bit digest over the key-order-stable JSON serialization. */
|
|
13
|
+
export function stableJsonDigest(value) {
|
|
14
|
+
const serialized = stableStringify(value);
|
|
15
|
+
let digest = 14695981039346656037n;
|
|
16
|
+
for (const byte of new TextEncoder().encode(serialized)) {
|
|
17
|
+
digest ^= BigInt(byte);
|
|
18
|
+
digest = BigInt.asUintN(64, digest * 1099511628211n);
|
|
19
|
+
}
|
|
20
|
+
return digest.toString(16).padStart(16, "0");
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAsBA,SAAS,eAAe,CAAC,KAAgB,EAAU;IAClD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5G,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7F,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;SAChC,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,eAAe,CAAE,KAAmC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IACvG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAAA,CAChC;AAED,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,KAAgB,EAAU;IAC1D,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,MAAM,GAAG,qBAAqB,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAAA,CAC7C","sourcesContent":["/**\n * Profile identity slice (2.0a) — package-local support for the multi-agent\n * slices: the resolved-plugin-manifest shape consumed by dependency wiring\n * (2.5a) and discovery wiring (4.4), plus the FNV-1a key-order-stable digest\n * used by the default policy manifest (2.7e).\n *\n * Migrated verbatim from the host's `src/profile/identity.ts`\n * (`buildProfileIdentityV1` / `ProfileIdentityV1` / `profileIdentitiesCompatible`\n * stay host-owned). `JsonValue` now comes from `@agent-forge/plugin-sdk`\n * because `@agent-forge/ai` is outside this package's supply list (D-082).\n */\nimport type { JsonValue } from \"@agent-forge/plugin-sdk\";\n\n/** One resolved plugin manifest entry of a Profile. */\nexport interface ResolvedPluginManifestV1 {\n\treadonly pluginId: string;\n\treadonly pluginVersion: string;\n\treadonly manifestPath?: string;\n\treadonly capabilityRefs: readonly { readonly id: string; readonly version: number }[];\n\treadonly selectedAdapter?: { readonly id: string; readonly version: string };\n}\n\nfunction stableStringify(value: JsonValue): string {\n\tif (value === null || typeof value === \"boolean\" || typeof value === \"number\" || typeof value === \"string\") {\n\t\treturn JSON.stringify(value);\n\t}\n\tif (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(\",\")}]`;\n\tconst entries = Object.keys(value)\n\t\t.sort()\n\t\t.map((key) => `${JSON.stringify(key)}:${stableStringify((value as Record<string, JsonValue>)[key])}`);\n\treturn `{${entries.join(\",\")}}`;\n}\n\n/** FNV-1a 64-bit digest over the key-order-stable JSON serialization. */\nexport function stableJsonDigest(value: JsonValue): string {\n\tconst serialized = stableStringify(value);\n\tlet digest = 14695981039346656037n;\n\tfor (const byte of new TextEncoder().encode(serialized)) {\n\t\tdigest ^= BigInt(byte);\n\t\tdigest = BigInt.asUintN(64, digest * 1099511628211n);\n\t}\n\treturn digest.toString(16).padStart(16, \"0\");\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-agent plugin public face: re-exports the migrated orchestration slices
|
|
3
|
+
* under the same symbol names the host's `src/profile/*` modules used to
|
|
4
|
+
* export (the host `src/index.ts` blocks, D-082 批 4), so SDK users import
|
|
5
|
+
* them from the plugin package directly.
|
|
6
|
+
*/
|
|
7
|
+
export { type ChildAgentFacadeV1, type ChildAgentResultRefV1, type ChildAgentTurnV1, createChildAgentFacade, } from "./child-facade.ts";
|
|
8
|
+
export { type AvailableCapabilityV1, type MissingDependencyV1, type PluginWiringResultV1, type ProfileDependencyWiringV1, wireProfileDependencies, } from "./dependency-wiring.ts";
|
|
9
|
+
export { buildRestartReport, type DomainRestartRecordV1, type DomainRestartReportV1, type PlanBranchRecoveryEntryV1, type PlanBranchRecoveryReportV1, recoverPlansForBranch, } from "./domain-recovery.ts";
|
|
10
|
+
export { createFirstBatchRoleSlices, FIRST_BATCH_ROLES, type FirstBatchRoleV1 } from "./first-roles.ts";
|
|
11
|
+
export { createGoalPlugin, type GoalPluginV1, type GoalStatusV1, type GoalV1, } from "./goal-plugin.ts";
|
|
12
|
+
export { type ResolvedPluginManifestV1, stableJsonDigest } from "./identity.ts";
|
|
13
|
+
export { createPlanPlugin, type PlanPluginV1, type PlanStatusV1, type PlanStepV1, type PlanV1, } from "./plan-plugin.ts";
|
|
14
|
+
export { createPolicyManifestBuilder, type PolicyChangeRecordV1, type PolicyDeclarationV1, type PolicyKindV1, type PolicyManifestBuilderV1, type PolicyManifestV1, } from "./policy-manifest.ts";
|
|
15
|
+
export { assembleRoles, type MountedRoleSummaryV1, type RegisteredRoleMetaV1, type RoleAssemblyDiagnosticsV1, type RoleAssemblyV1, } from "./role-assembly.ts";
|
|
16
|
+
export { createRoleCatalog, type RoleCapabilityDependencyV1, type RoleCatalogV1, type RoleIOSchemaRefV1, type RoleMetadataV1, type RoleWritableScopeV1, validateRoleMetadataV1, } from "./role-catalog.ts";
|
|
17
|
+
export { createRoleOrchestrator, DEFAULT_ROLE_AGGREGATION_LIMIT_BYTES, type RoleCompletionCheckV1, type RoleCompletionEvaluatorV1, type RoleOrchestrationEntryV1, type RoleOrchestrationResultV1, type RoleOrchestrationStatusV1, type RoleOrchestratorOptionsV1, type RoleOrchestratorRunRequestV1, type RoleOrchestratorV1, } from "./role-orchestrator.ts";
|
|
18
|
+
export { createRoleRunner, type RoleCapabilityCheckV1, type RoleMissingCapabilityV1, type RoleRunCallbackV1, type RoleRunnerInputV1, type RoleRunnerOptionsV1, type RoleRunnerResultV1, type RoleRunnerV1, type RoleRunResolverV1, runFirstBatchRole, } from "./role-runner.ts";
|
|
19
|
+
export { createRootAgentFacade, type RootAgentFacadeTurnResultV1, type RootAgentFacadeV1, } from "./root-facade.ts";
|
|
20
|
+
export { createSkillDiscoveryWiring, type DiscoveredItemV1, type DiscoverySourceKindV1, type DiscoveryVersionConflictV1, type DiscoveryWiringV1, } from "./skill-discovery-wiring.ts";
|
|
21
|
+
export { createTransitionStore, type TransitionEvidenceRefV1, type TransitionInputV1, type TransitionRecordV1, type TransitionResultV1, type TransitionStoreV1, } from "./state-store.ts";
|
|
22
|
+
export { createTodoPlugin, type TodoPluginV1, type TodoStatusV1, type TodoV1, } from "./todo-plugin.ts";
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACN,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,uBAAuB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACN,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAExG,OAAO,EACN,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,MAAM,GACX,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,KAAK,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,EACN,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,MAAM,GACX,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACN,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,GACnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACN,iBAAiB,EACjB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,sBAAsB,EACtB,oCAAoC,EACpC,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACN,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,qBAAqB,EACrB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,0BAA0B,EAC1B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,iBAAiB,GACtB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACN,qBAAqB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACN,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,MAAM,GACX,MAAM,kBAAkB,CAAC","sourcesContent":["/**\n * Multi-agent plugin public face: re-exports the migrated orchestration slices\n * under the same symbol names the host's `src/profile/*` modules used to\n * export (the host `src/index.ts` blocks, D-082 批 4), so SDK users import\n * them from the plugin package directly.\n */\n\n// Child agent lifecycle adapter (2.2b)\nexport {\n\ttype ChildAgentFacadeV1,\n\ttype ChildAgentResultRefV1,\n\ttype ChildAgentTurnV1,\n\tcreateChildAgentFacade,\n} from \"./child-facade.ts\";\n// Profile dependency wiring (2.5a): pre-session capability resolution\nexport {\n\ttype AvailableCapabilityV1,\n\ttype MissingDependencyV1,\n\ttype PluginWiringResultV1,\n\ttype ProfileDependencyWiringV1,\n\twireProfileDependencies,\n} from \"./dependency-wiring.ts\";\n// Domain recovery (5.2a/5.2b): branch-scoped plan recovery and restart replay\nexport {\n\tbuildRestartReport,\n\ttype DomainRestartRecordV1,\n\ttype DomainRestartReportV1,\n\ttype PlanBranchRecoveryEntryV1,\n\ttype PlanBranchRecoveryReportV1,\n\trecoverPlansForBranch,\n} from \"./domain-recovery.ts\";\n// First-batch role vertical slices (2.2c)\nexport { createFirstBatchRoleSlices, FIRST_BATCH_ROLES, type FirstBatchRoleV1 } from \"./first-roles.ts\";\n// Goal plugin (2.3b): Goal schema, evidence, and recovery over the transition store\nexport {\n\tcreateGoalPlugin,\n\ttype GoalPluginV1,\n\ttype GoalStatusV1,\n\ttype GoalV1,\n} from \"./goal-plugin.ts\";\n// Profile identity slice (2.0a): the manifest shape + stable digest consumed by\n// the wiring and policy surfaces above (the rest of the host identity module\n// stays host-owned).\nexport { type ResolvedPluginManifestV1, stableJsonDigest } from \"./identity.ts\";\n// Plan plugin (2.3c): branch/revision-bound plan semantics over the transition store\nexport {\n\tcreatePlanPlugin,\n\ttype PlanPluginV1,\n\ttype PlanStatusV1,\n\ttype PlanStepV1,\n\ttype PlanV1,\n} from \"./plan-plugin.ts\";\n// Policy manifest (2.7e): declarative policies with external selection\nexport {\n\tcreatePolicyManifestBuilder,\n\ttype PolicyChangeRecordV1,\n\ttype PolicyDeclarationV1,\n\ttype PolicyKindV1,\n\ttype PolicyManifestBuilderV1,\n\ttype PolicyManifestV1,\n} from \"./policy-manifest.ts\";\n// Role assembly (2.2d): catalog + runner binding mount with dependency diagnostics\nexport {\n\tassembleRoles,\n\ttype MountedRoleSummaryV1,\n\ttype RegisteredRoleMetaV1,\n\ttype RoleAssemblyDiagnosticsV1,\n\ttype RoleAssemblyV1,\n} from \"./role-assembly.ts\";\n// Role metadata catalog (2.2a)\nexport {\n\tcreateRoleCatalog,\n\ttype RoleCapabilityDependencyV1,\n\ttype RoleCatalogV1,\n\ttype RoleIOSchemaRefV1,\n\ttype RoleMetadataV1,\n\ttype RoleWritableScopeV1,\n\tvalidateRoleMetadataV1,\n} from \"./role-catalog.ts\";\n// Role orchestrator (2.2e): root-side concurrent orchestration with bounded aggregation\nexport {\n\tcreateRoleOrchestrator,\n\tDEFAULT_ROLE_AGGREGATION_LIMIT_BYTES,\n\ttype RoleCompletionCheckV1,\n\ttype RoleCompletionEvaluatorV1,\n\ttype RoleOrchestrationEntryV1,\n\ttype RoleOrchestrationResultV1,\n\ttype RoleOrchestrationStatusV1,\n\ttype RoleOrchestratorOptionsV1,\n\ttype RoleOrchestratorRunRequestV1,\n\ttype RoleOrchestratorV1,\n} from \"./role-orchestrator.ts\";\n// Role runner binding (2.2d): RoleMetadataV1 → child AgentDefinition\nexport {\n\tcreateRoleRunner,\n\ttype RoleCapabilityCheckV1,\n\ttype RoleMissingCapabilityV1,\n\ttype RoleRunCallbackV1,\n\ttype RoleRunnerInputV1,\n\ttype RoleRunnerOptionsV1,\n\ttype RoleRunnerResultV1,\n\ttype RoleRunnerV1,\n\ttype RoleRunResolverV1,\n\trunFirstBatchRole,\n} from \"./role-runner.ts\";\n// Root-agent-controller facade adapter (2.1a)\nexport {\n\tcreateRootAgentFacade,\n\ttype RootAgentFacadeTurnResultV1,\n\ttype RootAgentFacadeV1,\n} from \"./root-facade.ts\";\n// Skill/MCP discovery wiring (4.4): pre-session capability conflicts and wiring\nexport {\n\tcreateSkillDiscoveryWiring,\n\ttype DiscoveredItemV1,\n\ttype DiscoverySourceKindV1,\n\ttype DiscoveryVersionConflictV1,\n\ttype DiscoveryWiringV1,\n} from \"./skill-discovery-wiring.ts\";\n// Generic transition store (2.3a): Goal/Plan/Todo contract base\nexport {\n\tcreateTransitionStore,\n\ttype TransitionEvidenceRefV1,\n\ttype TransitionInputV1,\n\ttype TransitionRecordV1,\n\ttype TransitionResultV1,\n\ttype TransitionStoreV1,\n} from \"./state-store.ts\";\n// Todo plugin (2.3d): content lifecycle with cancel/restart over the transition store\nexport {\n\tcreateTodoPlugin,\n\ttype TodoPluginV1,\n\ttype TodoStatusV1,\n\ttype TodoV1,\n} from \"./todo-plugin.ts\";\n"]}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-agent plugin public face: re-exports the migrated orchestration slices
|
|
3
|
+
* under the same symbol names the host's `src/profile/*` modules used to
|
|
4
|
+
* export (the host `src/index.ts` blocks, D-082 批 4), so SDK users import
|
|
5
|
+
* them from the plugin package directly.
|
|
6
|
+
*/
|
|
7
|
+
// Child agent lifecycle adapter (2.2b)
|
|
8
|
+
export { createChildAgentFacade, } from "./child-facade.js";
|
|
9
|
+
// Profile dependency wiring (2.5a): pre-session capability resolution
|
|
10
|
+
export { wireProfileDependencies, } from "./dependency-wiring.js";
|
|
11
|
+
// Domain recovery (5.2a/5.2b): branch-scoped plan recovery and restart replay
|
|
12
|
+
export { buildRestartReport, recoverPlansForBranch, } from "./domain-recovery.js";
|
|
13
|
+
// First-batch role vertical slices (2.2c)
|
|
14
|
+
export { createFirstBatchRoleSlices, FIRST_BATCH_ROLES } from "./first-roles.js";
|
|
15
|
+
// Goal plugin (2.3b): Goal schema, evidence, and recovery over the transition store
|
|
16
|
+
export { createGoalPlugin, } from "./goal-plugin.js";
|
|
17
|
+
// Profile identity slice (2.0a): the manifest shape + stable digest consumed by
|
|
18
|
+
// the wiring and policy surfaces above (the rest of the host identity module
|
|
19
|
+
// stays host-owned).
|
|
20
|
+
export { stableJsonDigest } from "./identity.js";
|
|
21
|
+
// Plan plugin (2.3c): branch/revision-bound plan semantics over the transition store
|
|
22
|
+
export { createPlanPlugin, } from "./plan-plugin.js";
|
|
23
|
+
// Policy manifest (2.7e): declarative policies with external selection
|
|
24
|
+
export { createPolicyManifestBuilder, } from "./policy-manifest.js";
|
|
25
|
+
// Role assembly (2.2d): catalog + runner binding mount with dependency diagnostics
|
|
26
|
+
export { assembleRoles, } from "./role-assembly.js";
|
|
27
|
+
// Role metadata catalog (2.2a)
|
|
28
|
+
export { createRoleCatalog, validateRoleMetadataV1, } from "./role-catalog.js";
|
|
29
|
+
// Role orchestrator (2.2e): root-side concurrent orchestration with bounded aggregation
|
|
30
|
+
export { createRoleOrchestrator, DEFAULT_ROLE_AGGREGATION_LIMIT_BYTES, } from "./role-orchestrator.js";
|
|
31
|
+
// Role runner binding (2.2d): RoleMetadataV1 → child AgentDefinition
|
|
32
|
+
export { createRoleRunner, runFirstBatchRole, } from "./role-runner.js";
|
|
33
|
+
// Root-agent-controller facade adapter (2.1a)
|
|
34
|
+
export { createRootAgentFacade, } from "./root-facade.js";
|
|
35
|
+
// Skill/MCP discovery wiring (4.4): pre-session capability conflicts and wiring
|
|
36
|
+
export { createSkillDiscoveryWiring, } from "./skill-discovery-wiring.js";
|
|
37
|
+
// Generic transition store (2.3a): Goal/Plan/Todo contract base
|
|
38
|
+
export { createTransitionStore, } from "./state-store.js";
|
|
39
|
+
// Todo plugin (2.3d): content lifecycle with cancel/restart over the transition store
|
|
40
|
+
export { createTodoPlugin, } from "./todo-plugin.js";
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,uCAAuC;AACvC,OAAO,EAIN,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,sEAAsE;AACtE,OAAO,EAKN,uBAAuB,GACvB,MAAM,wBAAwB,CAAC;AAChC,8EAA8E;AAC9E,OAAO,EACN,kBAAkB,EAKlB,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,0CAA0C;AAC1C,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAyB,MAAM,kBAAkB,CAAC;AACxG,oFAAoF;AACpF,OAAO,EACN,gBAAgB,GAIhB,MAAM,kBAAkB,CAAC;AAC1B,gFAAgF;AAChF,6EAA6E;AAC7E,qBAAqB;AACrB,OAAO,EAAiC,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAChF,qFAAqF;AACrF,OAAO,EACN,gBAAgB,GAKhB,MAAM,kBAAkB,CAAC;AAC1B,uEAAuE;AACvE,OAAO,EACN,2BAA2B,GAM3B,MAAM,sBAAsB,CAAC;AAC9B,mFAAmF;AACnF,OAAO,EACN,aAAa,GAKb,MAAM,oBAAoB,CAAC;AAC5B,+BAA+B;AAC/B,OAAO,EACN,iBAAiB,EAMjB,sBAAsB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,wFAAwF;AACxF,OAAO,EACN,sBAAsB,EACtB,oCAAoC,GASpC,MAAM,wBAAwB,CAAC;AAChC,uEAAqE;AACrE,OAAO,EACN,gBAAgB,EAShB,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,8CAA8C;AAC9C,OAAO,EACN,qBAAqB,GAGrB,MAAM,kBAAkB,CAAC;AAC1B,gFAAgF;AAChF,OAAO,EACN,0BAA0B,GAK1B,MAAM,6BAA6B,CAAC;AACrC,gEAAgE;AAChE,OAAO,EACN,qBAAqB,GAMrB,MAAM,kBAAkB,CAAC;AAC1B,sFAAsF;AACtF,OAAO,EACN,gBAAgB,GAIhB,MAAM,kBAAkB,CAAC","sourcesContent":["/**\n * Multi-agent plugin public face: re-exports the migrated orchestration slices\n * under the same symbol names the host's `src/profile/*` modules used to\n * export (the host `src/index.ts` blocks, D-082 批 4), so SDK users import\n * them from the plugin package directly.\n */\n\n// Child agent lifecycle adapter (2.2b)\nexport {\n\ttype ChildAgentFacadeV1,\n\ttype ChildAgentResultRefV1,\n\ttype ChildAgentTurnV1,\n\tcreateChildAgentFacade,\n} from \"./child-facade.ts\";\n// Profile dependency wiring (2.5a): pre-session capability resolution\nexport {\n\ttype AvailableCapabilityV1,\n\ttype MissingDependencyV1,\n\ttype PluginWiringResultV1,\n\ttype ProfileDependencyWiringV1,\n\twireProfileDependencies,\n} from \"./dependency-wiring.ts\";\n// Domain recovery (5.2a/5.2b): branch-scoped plan recovery and restart replay\nexport {\n\tbuildRestartReport,\n\ttype DomainRestartRecordV1,\n\ttype DomainRestartReportV1,\n\ttype PlanBranchRecoveryEntryV1,\n\ttype PlanBranchRecoveryReportV1,\n\trecoverPlansForBranch,\n} from \"./domain-recovery.ts\";\n// First-batch role vertical slices (2.2c)\nexport { createFirstBatchRoleSlices, FIRST_BATCH_ROLES, type FirstBatchRoleV1 } from \"./first-roles.ts\";\n// Goal plugin (2.3b): Goal schema, evidence, and recovery over the transition store\nexport {\n\tcreateGoalPlugin,\n\ttype GoalPluginV1,\n\ttype GoalStatusV1,\n\ttype GoalV1,\n} from \"./goal-plugin.ts\";\n// Profile identity slice (2.0a): the manifest shape + stable digest consumed by\n// the wiring and policy surfaces above (the rest of the host identity module\n// stays host-owned).\nexport { type ResolvedPluginManifestV1, stableJsonDigest } from \"./identity.ts\";\n// Plan plugin (2.3c): branch/revision-bound plan semantics over the transition store\nexport {\n\tcreatePlanPlugin,\n\ttype PlanPluginV1,\n\ttype PlanStatusV1,\n\ttype PlanStepV1,\n\ttype PlanV1,\n} from \"./plan-plugin.ts\";\n// Policy manifest (2.7e): declarative policies with external selection\nexport {\n\tcreatePolicyManifestBuilder,\n\ttype PolicyChangeRecordV1,\n\ttype PolicyDeclarationV1,\n\ttype PolicyKindV1,\n\ttype PolicyManifestBuilderV1,\n\ttype PolicyManifestV1,\n} from \"./policy-manifest.ts\";\n// Role assembly (2.2d): catalog + runner binding mount with dependency diagnostics\nexport {\n\tassembleRoles,\n\ttype MountedRoleSummaryV1,\n\ttype RegisteredRoleMetaV1,\n\ttype RoleAssemblyDiagnosticsV1,\n\ttype RoleAssemblyV1,\n} from \"./role-assembly.ts\";\n// Role metadata catalog (2.2a)\nexport {\n\tcreateRoleCatalog,\n\ttype RoleCapabilityDependencyV1,\n\ttype RoleCatalogV1,\n\ttype RoleIOSchemaRefV1,\n\ttype RoleMetadataV1,\n\ttype RoleWritableScopeV1,\n\tvalidateRoleMetadataV1,\n} from \"./role-catalog.ts\";\n// Role orchestrator (2.2e): root-side concurrent orchestration with bounded aggregation\nexport {\n\tcreateRoleOrchestrator,\n\tDEFAULT_ROLE_AGGREGATION_LIMIT_BYTES,\n\ttype RoleCompletionCheckV1,\n\ttype RoleCompletionEvaluatorV1,\n\ttype RoleOrchestrationEntryV1,\n\ttype RoleOrchestrationResultV1,\n\ttype RoleOrchestrationStatusV1,\n\ttype RoleOrchestratorOptionsV1,\n\ttype RoleOrchestratorRunRequestV1,\n\ttype RoleOrchestratorV1,\n} from \"./role-orchestrator.ts\";\n// Role runner binding (2.2d): RoleMetadataV1 → child AgentDefinition\nexport {\n\tcreateRoleRunner,\n\ttype RoleCapabilityCheckV1,\n\ttype RoleMissingCapabilityV1,\n\ttype RoleRunCallbackV1,\n\ttype RoleRunnerInputV1,\n\ttype RoleRunnerOptionsV1,\n\ttype RoleRunnerResultV1,\n\ttype RoleRunnerV1,\n\ttype RoleRunResolverV1,\n\trunFirstBatchRole,\n} from \"./role-runner.ts\";\n// Root-agent-controller facade adapter (2.1a)\nexport {\n\tcreateRootAgentFacade,\n\ttype RootAgentFacadeTurnResultV1,\n\ttype RootAgentFacadeV1,\n} from \"./root-facade.ts\";\n// Skill/MCP discovery wiring (4.4): pre-session capability conflicts and wiring\nexport {\n\tcreateSkillDiscoveryWiring,\n\ttype DiscoveredItemV1,\n\ttype DiscoverySourceKindV1,\n\ttype DiscoveryVersionConflictV1,\n\ttype DiscoveryWiringV1,\n} from \"./skill-discovery-wiring.ts\";\n// Generic transition store (2.3a): Goal/Plan/Todo contract base\nexport {\n\tcreateTransitionStore,\n\ttype TransitionEvidenceRefV1,\n\ttype TransitionInputV1,\n\ttype TransitionRecordV1,\n\ttype TransitionResultV1,\n\ttype TransitionStoreV1,\n} from \"./state-store.ts\";\n// Todo plugin (2.3d): content lifecycle with cancel/restart over the transition store\nexport {\n\tcreateTodoPlugin,\n\ttype TodoPluginV1,\n\ttype TodoStatusV1,\n\ttype TodoV1,\n} from \"./todo-plugin.ts\";\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan plugin (2.3c) — Plan semantics bound to a branch/revision over the
|
|
3
|
+
* 2.3a transition store.
|
|
4
|
+
*
|
|
5
|
+
* Status graph: null → draft → active → completed, and draft/active →
|
|
6
|
+
* discarded. A plan is created with its step list and bound to a code branch;
|
|
7
|
+
* while active, `linkRevision` records plan progress against concrete
|
|
8
|
+
* revisions, and `complete` requires evidence plus the final revision. The
|
|
9
|
+
* plugin holds NO shadow state: status, revision, steps, branch, and the
|
|
10
|
+
* latest linked revision are all derived from the transition history, so
|
|
11
|
+
* recovery is exactly a store replay.
|
|
12
|
+
*/
|
|
13
|
+
import type { TransitionEvidenceRefV1, TransitionStoreV1 } from "./state-store.ts";
|
|
14
|
+
export type PlanStatusV1 = "draft" | "active" | "completed" | "discarded";
|
|
15
|
+
export interface PlanStepV1 {
|
|
16
|
+
readonly stepId: string;
|
|
17
|
+
readonly title: string;
|
|
18
|
+
}
|
|
19
|
+
export interface PlanV1 {
|
|
20
|
+
readonly planId: string;
|
|
21
|
+
readonly owner: string;
|
|
22
|
+
readonly title: string;
|
|
23
|
+
readonly branch: string;
|
|
24
|
+
readonly steps: readonly PlanStepV1[];
|
|
25
|
+
readonly status: PlanStatusV1;
|
|
26
|
+
/** The latest revision explicitly linked while active (undefined before the first link). */
|
|
27
|
+
readonly revision?: number;
|
|
28
|
+
readonly evidence: readonly TransitionEvidenceRefV1[];
|
|
29
|
+
readonly revisionNo: number;
|
|
30
|
+
}
|
|
31
|
+
export interface PlanPluginV1 {
|
|
32
|
+
createPlan(input: {
|
|
33
|
+
readonly planId: string;
|
|
34
|
+
readonly owner: string;
|
|
35
|
+
readonly title: string;
|
|
36
|
+
readonly branch: string;
|
|
37
|
+
readonly steps: readonly PlanStepV1[];
|
|
38
|
+
}): PlanV1;
|
|
39
|
+
activate(planId: string, owner: string, options?: {
|
|
40
|
+
readonly operationId?: string;
|
|
41
|
+
}): PlanV1;
|
|
42
|
+
/** Records plan progress against a concrete revision of the bound branch. */
|
|
43
|
+
linkRevision(planId: string, owner: string, revision: number, options?: {
|
|
44
|
+
readonly operationId?: string;
|
|
45
|
+
}): PlanV1;
|
|
46
|
+
complete(planId: string, owner: string, evidence: readonly TransitionEvidenceRefV1[], options?: {
|
|
47
|
+
readonly atRevision?: number;
|
|
48
|
+
readonly operationId?: string;
|
|
49
|
+
}): PlanV1;
|
|
50
|
+
discard(planId: string, owner: string): PlanV1;
|
|
51
|
+
get(planId: string, owner: string): PlanV1 | undefined;
|
|
52
|
+
}
|
|
53
|
+
export declare function createPlanPlugin(options: {
|
|
54
|
+
readonly transitions: TransitionStoreV1;
|
|
55
|
+
}): PlanPluginV1;
|
|
56
|
+
//# sourceMappingURL=plan-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-plugin.d.ts","sourceRoot":"","sources":["../src/plan-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;AAE1E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,MAAM;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC5B,UAAU,CAAC,KAAK,EAAE;QACjB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;KACtC,GAAG,MAAM,CAAC;IACX,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IAC7F,6EAA6E;IAC7E,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;IACnH,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,SAAS,uBAAuB,EAAE,EAC5C,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GACvE,MAAM,CAAC;IACV,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAiBD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAA;CAAE,GAAG,YAAY,CAyKnG","sourcesContent":["/**\n * Plan plugin (2.3c) — Plan semantics bound to a branch/revision over the\n * 2.3a transition store.\n *\n * Status graph: null → draft → active → completed, and draft/active →\n * discarded. A plan is created with its step list and bound to a code branch;\n * while active, `linkRevision` records plan progress against concrete\n * revisions, and `complete` requires evidence plus the final revision. The\n * plugin holds NO shadow state: status, revision, steps, branch, and the\n * latest linked revision are all derived from the transition history, so\n * recovery is exactly a store replay.\n */\n\nimport { t } from \"@agent-forge/host/i18n\";\nimport type { JsonValue } from \"@agent-forge/plugin-sdk\";\nimport type { TransitionEvidenceRefV1, TransitionStoreV1 } from \"./state-store.ts\";\n\nexport type PlanStatusV1 = \"draft\" | \"active\" | \"completed\" | \"discarded\";\n\nexport interface PlanStepV1 {\n\treadonly stepId: string;\n\treadonly title: string;\n}\n\nexport interface PlanV1 {\n\treadonly planId: string;\n\treadonly owner: string;\n\treadonly title: string;\n\treadonly branch: string;\n\treadonly steps: readonly PlanStepV1[];\n\treadonly status: PlanStatusV1;\n\t/** The latest revision explicitly linked while active (undefined before the first link). */\n\treadonly revision?: number;\n\treadonly evidence: readonly TransitionEvidenceRefV1[];\n\treadonly revisionNo: number;\n}\n\nexport interface PlanPluginV1 {\n\tcreatePlan(input: {\n\t\treadonly planId: string;\n\t\treadonly owner: string;\n\t\treadonly title: string;\n\t\treadonly branch: string;\n\t\treadonly steps: readonly PlanStepV1[];\n\t}): PlanV1;\n\tactivate(planId: string, owner: string, options?: { readonly operationId?: string }): PlanV1;\n\t/** Records plan progress against a concrete revision of the bound branch. */\n\tlinkRevision(planId: string, owner: string, revision: number, options?: { readonly operationId?: string }): PlanV1;\n\tcomplete(\n\t\tplanId: string,\n\t\towner: string,\n\t\tevidence: readonly TransitionEvidenceRefV1[],\n\t\toptions?: { readonly atRevision?: number; readonly operationId?: string },\n\t): PlanV1;\n\tdiscard(planId: string, owner: string): PlanV1;\n\tget(planId: string, owner: string): PlanV1 | undefined;\n}\n\ninterface PlanPayloadV1 {\n\treadonly title: string;\n\treadonly branch: string;\n\treadonly steps: readonly PlanStepV1[];\n\treadonly linkedRevision?: number;\n}\n\nfunction planPayloadOf(record: { readonly payload?: unknown }): Partial<PlanPayloadV1> | undefined {\n\tconst payload = record.payload;\n\tif (payload !== null && typeof payload === \"object\" && !Array.isArray(payload)) {\n\t\treturn payload as Partial<PlanPayloadV1>;\n\t}\n\treturn undefined;\n}\n\nexport function createPlanPlugin(options: { readonly transitions: TransitionStoreV1 }): PlanPluginV1 {\n\tconst transitions = options.transitions;\n\n\tconst planHistory = (planId: string, owner: string) =>\n\t\ttransitions.history(planId).filter((record) => record.domain === \"plan\" && record.owner === owner);\n\n\tconst current = (planId: string, owner: string): { status: PlanStatusV1; revisionNo: number } | undefined => {\n\t\tconst state = transitions.currentStatus(\"plan\", planId);\n\t\tif (state === undefined || planHistory(planId, owner).length === 0) return undefined;\n\t\treturn { status: state.status as PlanStatusV1, revisionNo: state.revision };\n\t};\n\n\tconst planGet = (planId: string, owner: string): PlanV1 | undefined => {\n\t\tconst state = current(planId, owner);\n\t\tif (!state) return undefined;\n\t\tconst history = planHistory(planId, owner);\n\t\t// v8 ignore next -- 因果校验保证每条 plan 历史都以 fromStatus=null 的创建记录开始\n\t\tconst createPayload = planPayloadOf(history.find((record) => record.fromStatus === null) ?? {});\n\t\tconst lastLinked = [...history]\n\t\t\t.reverse()\n\t\t\t.map((record) => planPayloadOf(record)?.linkedRevision)\n\t\t\t.find((revision): revision is number => typeof revision === \"number\");\n\t\tconst lastEvidence = [...history].reverse().find((record) => record.evidence.length > 0)?.evidence ?? [];\n\t\treturn {\n\t\t\tplanId,\n\t\t\towner,\n\t\t\ttitle: createPayload?.title ?? planId,\n\t\t\tbranch: createPayload?.branch ?? \"\",\n\t\t\tsteps: createPayload?.steps ?? [],\n\t\t\tstatus: state.status,\n\t\t\t...(lastLinked === undefined ? {} : { revision: lastLinked }),\n\t\t\tevidence: lastEvidence,\n\t\t\trevisionNo: state.revisionNo,\n\t\t};\n\t};\n\n\t/** A retried transition with an already-applied operationId returns the existing state instead of conflicting. */\n\tconst replayedPlan = (\n\t\tplanId: string,\n\t\towner: string,\n\t\ttoStatus: PlanStatusV1,\n\t\toperationId?: string,\n\t): PlanV1 | undefined => {\n\t\tif (!operationId) return undefined;\n\t\tconst applied = planHistory(planId, owner).some(\n\t\t\t(record) => record.toStatus === toStatus && record.operationId === operationId,\n\t\t);\n\t\treturn applied ? planGet(planId, owner) : undefined;\n\t};\n\n\tconst transitionPlan = (\n\t\tplanId: string,\n\t\towner: string,\n\t\tfromStatus: PlanStatusV1 | null,\n\t\ttoStatus: PlanStatusV1,\n\t\tplanOptions: {\n\t\t\treadonly evidence?: readonly TransitionEvidenceRefV1[];\n\t\t\treadonly payload?: PlanPayloadV1;\n\t\t\treadonly operationId?: string;\n\t\t},\n\t): PlanV1 => {\n\t\ttransitions.transition({\n\t\t\tdomain: \"plan\",\n\t\t\tentityId: planId,\n\t\t\towner,\n\t\t\tfromStatus,\n\t\t\ttoStatus,\n\t\t\toperationId: planOptions.operationId ?? `${toStatus}:${planId}`,\n\t\t\tevidence: planOptions.evidence,\n\t\t\tpayload: planOptions.payload as JsonValue | undefined,\n\t\t});\n\t\treturn planGet(planId, owner)!;\n\t};\n\n\treturn {\n\t\tcreatePlan({ planId, owner, title, branch, steps }) {\n\t\t\tif (title.trim().length === 0) throw new Error(t(\"Plan title must be a non-empty string\"));\n\t\t\tif (branch.trim().length === 0) throw new Error(t(\"Plan branch must be a non-empty string\"));\n\t\t\tif (steps.length === 0) throw new Error(t(\"Plan requires at least one step\"));\n\t\t\tconst stepIds = new Set<string>();\n\t\t\tfor (const step of steps) {\n\t\t\t\tif (typeof step.stepId !== \"string\" || step.stepId.trim().length === 0) {\n\t\t\t\t\tthrow new Error(t(\"Plan stepId must be a non-empty string\"));\n\t\t\t\t}\n\t\t\t\tif (typeof step.title !== \"string\" || step.title.trim().length === 0) {\n\t\t\t\t\tthrow new Error(t(\"Plan step title must be a non-empty string\"));\n\t\t\t\t}\n\t\t\t\tif (stepIds.has(step.stepId))\n\t\t\t\t\tthrow new Error(t(\"Duplicate plan stepId: {stepId}\", { stepId: step.stepId }));\n\t\t\t\tstepIds.add(step.stepId);\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, null, \"draft\", {\n\t\t\t\tpayload: { title, branch, steps: [...steps] },\n\t\t\t\toperationId: `create:${planId}`,\n\t\t\t});\n\t\t},\n\t\tactivate(planId, owner, activateOptions) {\n\t\t\tconst replayed = replayedPlan(planId, owner, \"active\", activateOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (plan?.status !== \"draft\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} must be in draft status to activate (current: {status})\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, \"draft\", \"active\", { operationId: activateOptions?.operationId });\n\t\t},\n\t\tlinkRevision(planId, owner, revision, linkOptions) {\n\t\t\tconst replayed = replayedPlan(planId, owner, \"active\", linkOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (plan?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} must be active to link a revision (current: {status})\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (!Number.isSafeInteger(revision) || revision < 1) {\n\t\t\t\tthrow new Error(t(\"Plan revision must be a positive safe integer, got {revision}\", { revision }));\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, \"active\", \"active\", {\n\t\t\t\tpayload: { title: plan.title, branch: plan.branch, steps: plan.steps, linkedRevision: revision },\n\t\t\t\toperationId: linkOptions?.operationId ?? `link:${planId}:${revision}`,\n\t\t\t});\n\t\t},\n\t\tcomplete(planId, owner, evidence, completeOptions) {\n\t\t\tconst replayed = replayedPlan(planId, owner, \"completed\", completeOptions?.operationId);\n\t\t\tif (replayed) return replayed;\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (plan?.status !== \"active\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} must be active to complete (current: {status})\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (evidence.length === 0) throw new Error(t(\"Completing a plan requires at least one evidence reference\"));\n\t\t\tconst target = completeOptions?.atRevision ?? plan.revision;\n\t\t\tif (typeof target !== \"number\") {\n\t\t\t\tthrow new Error(t(\"Plan {planId} requires atRevision or a linked revision to complete\", { planId }));\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, \"active\", \"completed\", {\n\t\t\t\tevidence,\n\t\t\t\tpayload: { title: plan.title, branch: plan.branch, steps: plan.steps, linkedRevision: target },\n\t\t\t\toperationId: completeOptions?.operationId,\n\t\t\t});\n\t\t},\n\t\tdiscard(planId, owner) {\n\t\t\tconst plan = planGet(planId, owner);\n\t\t\tif (!plan || plan.status === \"completed\" || plan.status === \"discarded\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\tt(\"Plan {planId} cannot be discarded from status {status}\", {\n\t\t\t\t\t\tplanId,\n\t\t\t\t\t\tstatus: plan?.status ?? \"missing\",\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn transitionPlan(planId, owner, plan.status, \"discarded\", {});\n\t\t},\n\t\tget(planId, owner) {\n\t\t\treturn planGet(planId, owner);\n\t\t},\n\t};\n}\n"]}
|