@danypops/papyrus 0.55.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +14 -1
- package/src/artifact/artifact-relationship-view.ts +1 -1
- package/src/artifact/artifact-scope-store.ts +32 -26
- package/src/artifact/in-memory-artifact-scope-store.ts +82 -43
- package/src/artifact/index.ts +3 -0
- package/src/artifact/sqlite-artifact-scope-store.ts +105 -56
- package/src/cli/docs-command.ts +71 -0
- package/src/cli/gates-command.ts +1 -1
- package/src/cli/note-command.ts +1 -1
- package/src/cli/playbooks-command.ts +71 -0
- package/src/cli/rules-command.ts +71 -0
- package/src/cli/scope-groups-command.ts +197 -0
- package/src/cli/task-command.ts +1 -1
- package/src/cli.ts +7 -0
- package/src/constants.ts +10 -2
- package/src/db.ts +117 -7
- package/src/{stores → discussion}/discussion-round-store.ts +1 -1
- package/src/discussion/discussion-service.ts +2 -2
- package/src/discussion/index.ts +1 -0
- package/src/{stores → discussion}/sqlite-discussion-round-store.ts +2 -2
- package/src/display-graph/graph-renderer.ts +5 -0
- package/src/docs/docs-service.ts +55 -20
- package/src/domain-service-shared.ts +90 -2
- package/src/{domain → gate}/gate-execution.ts +1 -1
- package/src/{stores → gate}/gate-runner.ts +1 -1
- package/src/{stores → gate}/sqlite-gate-runner.ts +3 -3
- package/src/graph-projection/graph-projection-service.ts +2 -2
- package/src/{stores → graph-projection}/graph-projection-store.ts +1 -1
- package/src/{stores → graph-projection}/sqlite-graph-projection-store.ts +2 -2
- package/src/handlers/discuss.ts +1 -1
- package/src/handlers/docs.ts +57 -2
- package/src/handlers/playbooks.ts +49 -8
- package/src/handlers/projects.ts +1 -1
- package/src/handlers/registry.ts +10 -5
- package/src/handlers/rules.ts +66 -2
- package/src/handlers/scope-groups.ts +100 -0
- package/src/handlers/task-classifiers.ts +1 -1
- package/src/handlers/tasks.ts +4 -4
- package/src/index.ts +9 -9
- package/src/log/log-service.ts +2 -2
- package/src/{stores → log}/log-store.ts +1 -1
- package/src/{stores → log}/sqlite-log-store.ts +2 -2
- package/src/modules/docs.ts +21 -1
- package/src/modules/graph-projection.ts +2 -2
- package/src/modules/logs.ts +1 -1
- package/src/modules/notes.ts +1 -1
- package/src/modules/playbooks.ts +24 -3
- package/src/modules/projects.ts +3 -3
- package/src/modules/rules.ts +21 -1
- package/src/modules/scope-groups.ts +92 -0
- package/src/modules/tasks.ts +3 -3
- package/src/note/index.ts +1 -0
- package/src/{stores → note}/note-event-store.ts +1 -1
- package/src/note/note-service.ts +2 -2
- package/src/{stores → note}/sqlite-note-event-store.ts +2 -2
- package/src/ops.ts +1 -1
- package/src/playbook/index.ts +2 -0
- package/src/playbook/playbook-definition.ts +2 -2
- package/src/playbook/playbook-execution.ts +1 -1
- package/src/playbook/playbook-service.ts +61 -26
- package/src/playbook/workflow-execution.ts +8 -8
- package/src/{stores → project-registry}/in-memory-project-registry-store.ts +2 -2
- package/src/{ports → project-registry}/project-registry-store.ts +1 -1
- package/src/{stores → project-registry}/sqlite-project-registry-store.ts +3 -3
- package/src/rules/rules-service.ts +56 -24
- package/src/scope-group/delete-scope-group.ts +17 -0
- package/src/scope-group/in-memory-scope-group-store.ts +173 -0
- package/src/scope-group/scope-group-store.ts +28 -0
- package/src/scope-group/scope-group.ts +79 -0
- package/src/scope-group/sqlite-scope-group-store.ts +223 -0
- package/src/service.ts +46 -21
- package/src/session-identity/session-identity-service.ts +2 -2
- package/src/{stores → session-identity}/sqlite-session-identity-store.ts +1 -1
- package/src/task/index.ts +13 -0
- package/src/task/task-context.ts +1 -1
- package/src/task/task-edges.ts +2 -2
- package/src/task/task-focus-coordinator.ts +3 -3
- package/src/task/task-graph-view.ts +1 -1
- package/src/task/task-lease-coordinator.ts +2 -2
- package/src/task/task-mutation-coordinator.ts +1 -1
- package/src/task/task-project-scope.ts +5 -5
- package/src/task/task-relationship-view.ts +1 -1
- package/src/task/task-service.ts +24 -24
- package/src/{stores → task-create-request}/sqlite-task-create-request-store.ts +1 -1
- package/src/{stores → task-event}/sqlite-task-event-store.ts +2 -2
- package/src/{stores → task-event}/task-event-store.ts +1 -1
- package/src/{stores → task-focus}/sqlite-task-focus-store.ts +1 -1
- package/src/{stores → task-lease}/sqlite-task-lease-store.ts +2 -2
- package/src/{stores → task-lease}/task-lease-store.ts +1 -1
- package/src/{stores → task-mutation-request}/sqlite-task-mutation-request-store.ts +5 -1
- package/src/{stores → task-scope}/sqlite-task-scope-store.ts +3 -3
- package/src/{stores → task-scope}/task-scope-store.ts +3 -3
- package/src/{domain → task-scope}/task-scope.ts +1 -1
- package/src/stores/graph-renderer.ts +0 -5
- /package/src/{domain → discussion}/discussion.ts +0 -0
- /package/src/{domain → display-graph}/display-graph.ts +0 -0
- /package/src/{domain → gate}/gate.ts +0 -0
- /package/src/{domain → graph-projection}/graph-projection.ts +0 -0
- /package/src/{domain → log}/log-entry.ts +0 -0
- /package/src/{domain → note}/note-event.ts +0 -0
- /package/src/{domain → playbook}/blueprint-definition.ts +0 -0
- /package/src/{domain → project-registry}/project-registry.ts +0 -0
- /package/src/{stores → session-identity}/session-identity-store.ts +0 -0
- /package/src/{domain → session-identity}/session-identity.ts +0 -0
- /package/src/{domain → task}/checklist.ts +0 -0
- /package/src/{stores → task-create-request}/task-create-request-store.ts +0 -0
- /package/src/{domain → task-event}/task-event.ts +0 -0
- /package/src/{stores → task-focus}/task-focus-store.ts +0 -0
- /package/src/{domain → task-lease}/task-lease.ts +0 -0
- /package/src/{stores → task-mutation-request}/task-mutation-request-store.ts +0 -0
package/src/modules/rules.ts
CHANGED
|
@@ -15,24 +15,29 @@ import { type Artifact, summarizeArtifact } from "../artifact/artifact.ts";
|
|
|
15
15
|
import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
16
16
|
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
17
17
|
import type { OperationDefinition } from "../module-registry.ts";
|
|
18
|
-
import type { ProjectRegistryStore } from "../
|
|
18
|
+
import type { ProjectRegistryStore } from "../project-registry/project-registry-store.ts";
|
|
19
19
|
import {
|
|
20
|
+
addRuleGroup,
|
|
20
21
|
addRuleProject,
|
|
21
22
|
assignRuleProject,
|
|
22
23
|
createRule,
|
|
23
24
|
gateTaskWithRule,
|
|
24
25
|
listRules,
|
|
25
26
|
previewRule,
|
|
27
|
+
removeRuleGroup,
|
|
26
28
|
removeRuleProject,
|
|
29
|
+
replaceRuleGroups,
|
|
27
30
|
replaceRuleProjects,
|
|
28
31
|
ruleCombinedLength,
|
|
29
32
|
ruleCombinedLengthWarning,
|
|
30
33
|
ruleScope,
|
|
31
34
|
setRuleGlobal,
|
|
35
|
+
setRuleNone,
|
|
32
36
|
showRule,
|
|
33
37
|
transitionRule,
|
|
34
38
|
updateRule,
|
|
35
39
|
} from "../rules/rules-service.ts";
|
|
40
|
+
import type { ScopeGroupStore } from "../scope-group/scope-group-store.ts";
|
|
36
41
|
import { type OperationInput, optionalBoolean, optionalNumber, optionalString, string } from "./operation-input.ts";
|
|
37
42
|
|
|
38
43
|
const MODULE_ID = "rules";
|
|
@@ -79,9 +84,13 @@ export const RULES_OPERATION_NAMES = [
|
|
|
79
84
|
"rules.assign_project",
|
|
80
85
|
"rules.scope",
|
|
81
86
|
"rules.set_global",
|
|
87
|
+
"rules.set_none",
|
|
82
88
|
"rules.add_project",
|
|
83
89
|
"rules.remove_project",
|
|
84
90
|
"rules.replace_projects",
|
|
91
|
+
"rules.add_group",
|
|
92
|
+
"rules.remove_group",
|
|
93
|
+
"rules.replace_groups",
|
|
85
94
|
"rules.update",
|
|
86
95
|
] as const;
|
|
87
96
|
|
|
@@ -89,6 +98,7 @@ export function rulesOperations(
|
|
|
89
98
|
artifacts: ArtifactStore,
|
|
90
99
|
scopes: ArtifactScopeStore,
|
|
91
100
|
registry: ProjectRegistryStore,
|
|
101
|
+
scopeGroups: ScopeGroupStore,
|
|
92
102
|
): OperationDefinition[] {
|
|
93
103
|
const define = <Input, Output>(name: string, execute: (input: Input) => Output): OperationDefinition<Input, Output> => ({
|
|
94
104
|
name,
|
|
@@ -144,6 +154,16 @@ export function rulesOperations(
|
|
|
144
154
|
),
|
|
145
155
|
define("rules.scope", (input: OperationInput) => ruleScope(artifacts, scopes, string(input, "id"))),
|
|
146
156
|
define("rules.set_global", (input: OperationInput) => setRuleGlobal(artifacts, scopes, string(input, "id"))),
|
|
157
|
+
define("rules.set_none", (input: OperationInput) => setRuleNone(artifacts, scopes, string(input, "id"))),
|
|
158
|
+
define("rules.add_group", (input: OperationInput) =>
|
|
159
|
+
addRuleGroup(artifacts, scopes, scopeGroups, string(input, "id"), string(input, "group")),
|
|
160
|
+
),
|
|
161
|
+
define("rules.remove_group", (input: OperationInput) =>
|
|
162
|
+
removeRuleGroup(artifacts, scopes, scopeGroups, string(input, "id"), string(input, "group")),
|
|
163
|
+
),
|
|
164
|
+
define("rules.replace_groups", (input: OperationInput) =>
|
|
165
|
+
replaceRuleGroups(artifacts, scopes, scopeGroups, string(input, "id"), (input.groups as string[] | undefined) ?? []),
|
|
166
|
+
),
|
|
147
167
|
define("rules.add_project", (input: OperationInput) =>
|
|
148
168
|
addRuleProject(artifacts, scopes, registry, string(input, "id"), string(input, "project")),
|
|
149
169
|
),
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* modules/scope-groups.ts — named, reusable, possibly-nested scope member collections as their
|
|
3
|
+
* own Papyrus-native registered module. A scope group's own members (added/removed here) are
|
|
4
|
+
* referenced by Docs/Rules/Playbooks' own explicit scope (docs/rules/playbooks.add_group etc.,
|
|
5
|
+
* see ../artifact/artifact-scope-store.ts) -- "explicit scope can include nested scopes".
|
|
6
|
+
* Mirrors modules/projects.ts's own shape (list/resolve/register) for the catalog half, plus
|
|
7
|
+
* real membership management and a real delete (deleteScopeGroup, unlike ProjectRegistryStore
|
|
8
|
+
* which has no delete path at all -- see papyrus task 1716b34b).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
12
|
+
import { SCOPE_GROUP_LIST_MAX_RESULTS } from "../constants.ts";
|
|
13
|
+
import type { OperationDefinition } from "../module-registry.ts";
|
|
14
|
+
import { resolveProjectReference } from "../project-registry/project-registry.ts";
|
|
15
|
+
import type { ProjectRegistryStore } from "../project-registry/project-registry-store.ts";
|
|
16
|
+
import { deleteScopeGroup } from "../scope-group/delete-scope-group.ts";
|
|
17
|
+
import { resolveScopeGroupReference, type ScopeMemberRef } from "../scope-group/scope-group.ts";
|
|
18
|
+
import type { ScopeGroupStore } from "../scope-group/scope-group-store.ts";
|
|
19
|
+
import { type OperationInput, optionalNumber, optionalString, optionalStringArray, string } from "./operation-input.ts";
|
|
20
|
+
|
|
21
|
+
const MODULE_ID = "scope_groups";
|
|
22
|
+
|
|
23
|
+
export const SCOPE_GROUPS_OPERATION_NAMES = [
|
|
24
|
+
"scope_groups.list",
|
|
25
|
+
"scope_groups.resolve",
|
|
26
|
+
"scope_groups.register",
|
|
27
|
+
"scope_groups.show",
|
|
28
|
+
"scope_groups.add_member",
|
|
29
|
+
"scope_groups.remove_member",
|
|
30
|
+
"scope_groups.delete",
|
|
31
|
+
] as const;
|
|
32
|
+
|
|
33
|
+
function resolveMember(
|
|
34
|
+
registry: ProjectRegistryStore,
|
|
35
|
+
scopeGroups: ScopeGroupStore,
|
|
36
|
+
memberType: string,
|
|
37
|
+
memberReference: string,
|
|
38
|
+
): ScopeMemberRef {
|
|
39
|
+
if (memberType === "project") return { type: "project", id: resolveProjectReference(registry, memberReference).id };
|
|
40
|
+
if (memberType === "group") return { type: "group", id: resolveScopeGroupReference(scopeGroups, memberReference).id };
|
|
41
|
+
throw new Error('member_type must be "project" or "group"');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function scopeGroupsOperations(
|
|
45
|
+
scopeGroups: ScopeGroupStore,
|
|
46
|
+
registry: ProjectRegistryStore,
|
|
47
|
+
artifactScopes: ArtifactScopeStore,
|
|
48
|
+
): OperationDefinition[] {
|
|
49
|
+
const define = <Input, Output>(name: string, execute: (input: Input) => Output): OperationDefinition<Input, Output> => ({
|
|
50
|
+
name,
|
|
51
|
+
moduleId: MODULE_ID,
|
|
52
|
+
execute,
|
|
53
|
+
});
|
|
54
|
+
return [
|
|
55
|
+
define("scope_groups.list", (input: OperationInput) => {
|
|
56
|
+
const limit = optionalNumber(input, "limit") ?? 20;
|
|
57
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > SCOPE_GROUP_LIST_MAX_RESULTS) {
|
|
58
|
+
throw new Error(`scope group list limit must be between 1 and ${SCOPE_GROUP_LIST_MAX_RESULTS}`);
|
|
59
|
+
}
|
|
60
|
+
return scopeGroups.groups(optionalString(input, "query"), limit);
|
|
61
|
+
}),
|
|
62
|
+
define("scope_groups.resolve", (input: OperationInput) => resolveScopeGroupReference(scopeGroups, string(input, "reference"))),
|
|
63
|
+
define("scope_groups.register", (input: OperationInput) =>
|
|
64
|
+
scopeGroups.registerGroup({
|
|
65
|
+
name: optionalString(input, "name"),
|
|
66
|
+
aliases: optionalStringArray(input, "aliases"),
|
|
67
|
+
existingId: optionalString(input, "existing_id"),
|
|
68
|
+
}),
|
|
69
|
+
),
|
|
70
|
+
define("scope_groups.show", (input: OperationInput) => {
|
|
71
|
+
const group = resolveScopeGroupReference(scopeGroups, string(input, "group"));
|
|
72
|
+
return { group, members: scopeGroups.members(group.id) };
|
|
73
|
+
}),
|
|
74
|
+
define("scope_groups.add_member", (input: OperationInput) => {
|
|
75
|
+
const group = resolveScopeGroupReference(scopeGroups, string(input, "group"));
|
|
76
|
+
const member = resolveMember(registry, scopeGroups, string(input, "member_type"), string(input, "member_reference"));
|
|
77
|
+
scopeGroups.addMember(group.id, member);
|
|
78
|
+
return { group, members: scopeGroups.members(group.id) };
|
|
79
|
+
}),
|
|
80
|
+
define("scope_groups.remove_member", (input: OperationInput) => {
|
|
81
|
+
const group = resolveScopeGroupReference(scopeGroups, string(input, "group"));
|
|
82
|
+
const member = resolveMember(registry, scopeGroups, string(input, "member_type"), string(input, "member_reference"));
|
|
83
|
+
scopeGroups.removeMember(group.id, member);
|
|
84
|
+
return { group, members: scopeGroups.members(group.id) };
|
|
85
|
+
}),
|
|
86
|
+
define("scope_groups.delete", (input: OperationInput) => {
|
|
87
|
+
const group = resolveScopeGroupReference(scopeGroups, string(input, "group"));
|
|
88
|
+
deleteScopeGroup(scopeGroups, artifactScopes, group.id);
|
|
89
|
+
return { deleted: true, id: group.id };
|
|
90
|
+
}),
|
|
91
|
+
];
|
|
92
|
+
}
|
package/src/modules/tasks.ts
CHANGED
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
|
|
22
22
|
import { summarizeArtifact } from "../artifact/artifact.ts";
|
|
23
23
|
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
24
|
-
import type { Checklist } from "../domain/checklist.ts";
|
|
25
|
-
import type { TaskEventContext, TaskEventDirection, TaskEventFeedQuery } from "../domain/task-event.ts";
|
|
26
|
-
import type { TaskViewMode } from "../domain/task-scope.ts";
|
|
27
24
|
import type { OperationDefinition } from "../module-registry.ts";
|
|
28
25
|
import type { SessionIdentity } from "../session-identity/session-identity-service.ts";
|
|
26
|
+
import type { Checklist } from "../task/checklist.ts";
|
|
29
27
|
import { taskContext } from "../task/task-context.ts";
|
|
30
28
|
import { projectTaskExecution } from "../task/task-execution.ts";
|
|
31
29
|
import type { TaskMutationRequestContext, TaskStatus, Tasks } from "../task/task-service.ts";
|
|
30
|
+
import type { TaskEventContext, TaskEventDirection, TaskEventFeedQuery } from "../task-event/task-event.ts";
|
|
31
|
+
import type { TaskViewMode } from "../task-scope/task-scope.ts";
|
|
32
32
|
import { type OperationInput, optionalBoolean, optionalNumber, optionalString, optionalStringArray, string } from "./operation-input.ts";
|
|
33
33
|
|
|
34
34
|
const MODULE_ID = "tasks";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { NOTE_DISPOSITIONS } from "./note-service.ts";
|
package/src/note/note-service.ts
CHANGED
|
@@ -10,8 +10,8 @@ import {
|
|
|
10
10
|
NOTE_TITLE_MAX_CHARACTERS,
|
|
11
11
|
TASK_PROJECT_ROOT_MAX_LENGTH,
|
|
12
12
|
} from "../constants.ts";
|
|
13
|
-
import type { AppendNoteEvent, NoteEventType, NoteHistoryPage, NoteHistoryQuery } from "
|
|
14
|
-
import { InMemoryNoteEventStore, type NoteEventStore } from "
|
|
13
|
+
import type { AppendNoteEvent, NoteEventType, NoteHistoryPage, NoteHistoryQuery } from "./note-event.ts";
|
|
14
|
+
import { InMemoryNoteEventStore, type NoteEventStore } from "./note-event-store.ts";
|
|
15
15
|
|
|
16
16
|
export const NOTE_SUBTYPE = "note";
|
|
17
17
|
export const NOTE_DISPOSITIONS = ["completed", "duplicate", "declined", "superseded"] as const;
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
type NoteHistoryQuery,
|
|
8
8
|
normalizeNoteHistoryQuery,
|
|
9
9
|
validateNoteEvent,
|
|
10
|
-
} from "../
|
|
11
|
-
import type { NoteEventStore } from "
|
|
10
|
+
} from "../note/note-event.ts";
|
|
11
|
+
import type { NoteEventStore } from "../note/note-event-store.ts";
|
|
12
12
|
|
|
13
13
|
interface NoteEventRow {
|
|
14
14
|
id: number;
|
package/src/ops.ts
CHANGED
|
@@ -481,7 +481,7 @@ export function purgeDueArtifacts(db: Db, now: () => string = () => new Date().t
|
|
|
481
481
|
db.prepare("DELETE FROM task_scopes WHERE task_id = ?").run(id);
|
|
482
482
|
db.prepare("DELETE FROM task_views WHERE root_task_id = ?").run(id);
|
|
483
483
|
db.prepare("DELETE FROM graph_projection_identities WHERE artifact_id = ?").run(id);
|
|
484
|
-
db.prepare("DELETE FROM
|
|
484
|
+
db.prepare("DELETE FROM artifact_scope_members WHERE artifact_id = ?").run(id);
|
|
485
485
|
db.prepare("DELETE FROM artifact_scopes WHERE artifact_id = ?").run(id);
|
|
486
486
|
db.prepare("DELETE FROM task_events WHERE task_id = ?").run(id);
|
|
487
487
|
db.prepare("DELETE FROM note_events WHERE note_id = ?").run(id);
|
|
@@ -33,8 +33,8 @@ import type {
|
|
|
33
33
|
DocBlueprint,
|
|
34
34
|
RuleBlueprint,
|
|
35
35
|
TaskBlueprint,
|
|
36
|
-
} from "
|
|
37
|
-
import { validateBlueprintDefinition } from "
|
|
36
|
+
} from "./blueprint-definition.ts";
|
|
37
|
+
import { validateBlueprintDefinition } from "./blueprint-definition.ts";
|
|
38
38
|
import type { PlaybookArgument, PlaybookStep } from "./playbook-service.ts";
|
|
39
39
|
|
|
40
40
|
/** A non-composing edge touching a playbook node, to be mirrored onto that node's generated root task once real task ids exist -- e.g. a Rule `gates` this playbook, or this playbook `references`/`documents` a Doc. Direction is preserved exactly: `from`/`to` name whichever side is NOT the playbook, and `ownerIsFrom` says which side the playbook (now the generated root task) occupies. */
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
12
12
|
import { requireAtomicArtifactStore } from "../artifact/atomic-artifact-store.ts";
|
|
13
|
-
import type { BlueprintArgumentValue } from "../domain/blueprint-definition.ts";
|
|
14
13
|
import type { TaskExecutionPlan } from "../task/task-execution.ts";
|
|
14
|
+
import type { BlueprintArgumentValue } from "./blueprint-definition.ts";
|
|
15
15
|
import { compilePlaybookDefinition } from "./playbook-definition.ts";
|
|
16
16
|
import {
|
|
17
17
|
applyPlaybookExternalLinks,
|
|
@@ -28,7 +28,6 @@ import type { ArtifactEventContext } from "../artifact/artifact-event.ts";
|
|
|
28
28
|
import type { ArtifactScope, ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
29
29
|
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
30
30
|
import {
|
|
31
|
-
ARTIFACT_SCOPE_MAX_PROJECTS_PER_ARTIFACT,
|
|
32
31
|
ARTIFACT_TITLE_MAX_LENGTH,
|
|
33
32
|
PLAYBOOK_ARGUMENT_DESCRIPTION_MAX_LENGTH,
|
|
34
33
|
PLAYBOOK_ARGUMENT_MAX_COUNT,
|
|
@@ -39,26 +38,33 @@ import {
|
|
|
39
38
|
SKILL_MAX_ENUM_VALUES,
|
|
40
39
|
} from "../constants.ts";
|
|
41
40
|
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
type BlueprintInputType,
|
|
45
|
-
validateArgumentValue,
|
|
46
|
-
} from "../domain/blueprint-definition.ts";
|
|
47
|
-
import { resolveProjectReference } from "../domain/project-registry.ts";
|
|
48
|
-
import { normalizeProjectRoot } from "../domain/task-scope.ts";
|
|
49
|
-
import {
|
|
41
|
+
addArtifactScopeGroup,
|
|
42
|
+
addArtifactScopeProject,
|
|
50
43
|
assertBodyBounds,
|
|
51
44
|
assertLabelsBounds,
|
|
52
45
|
assertTitleBounds,
|
|
53
46
|
assignArtifactProject,
|
|
54
47
|
type ListFilter,
|
|
55
48
|
listScoped,
|
|
49
|
+
removeArtifactScopeGroup,
|
|
50
|
+
removeArtifactScopeProject,
|
|
51
|
+
replaceArtifactScopeGroups,
|
|
52
|
+
replaceArtifactScopeProjects,
|
|
56
53
|
requireKind,
|
|
57
54
|
runTransition,
|
|
55
|
+
setArtifactScopeNone,
|
|
58
56
|
type TransitionTable,
|
|
59
57
|
type UpdateContentInput,
|
|
60
58
|
} from "../domain-service-shared.ts";
|
|
61
|
-
import type { ProjectRegistryStore } from "../
|
|
59
|
+
import type { ProjectRegistryStore } from "../project-registry/project-registry-store.ts";
|
|
60
|
+
import type { ScopeGroupStore } from "../scope-group/scope-group-store.ts";
|
|
61
|
+
import { normalizeProjectRoot } from "../task-scope/task-scope.ts";
|
|
62
|
+
import {
|
|
63
|
+
BLUEPRINT_INPUT_TYPES,
|
|
64
|
+
type BlueprintArgumentValue,
|
|
65
|
+
type BlueprintInputType,
|
|
66
|
+
validateArgumentValue,
|
|
67
|
+
} from "./blueprint-definition.ts";
|
|
62
68
|
|
|
63
69
|
export interface PlaybookArgument {
|
|
64
70
|
name: string;
|
|
@@ -280,11 +286,7 @@ export function createPlaybook(
|
|
|
280
286
|
context,
|
|
281
287
|
);
|
|
282
288
|
if (input.projectReferences !== undefined && input.projectReferences.length > 0) {
|
|
283
|
-
|
|
284
|
-
throw new Error(`projectReferences may include at most ${ARTIFACT_SCOPE_MAX_PROJECTS_PER_ARTIFACT} entries`);
|
|
285
|
-
}
|
|
286
|
-
const ids = input.projectReferences.map((reference) => resolveProjectReference(registry!, reference).id);
|
|
287
|
-
scopes.replaceProjects(playbook.id, ids, "explicit");
|
|
289
|
+
replaceArtifactScopeProjects(scopes, registry!, playbook.id, input.projectReferences);
|
|
288
290
|
} else {
|
|
289
291
|
scopes.assign(playbook.id, projectRoot, projectRoot === undefined ? "unscoped" : "explicit");
|
|
290
292
|
}
|
|
@@ -320,7 +322,13 @@ export function playbookScope(artifacts: ArtifactStore, scopes: ArtifactScopeSto
|
|
|
320
322
|
|
|
321
323
|
export function setPlaybookGlobal(artifacts: ArtifactStore, scopes: ArtifactScopeStore, id: string): ArtifactScope {
|
|
322
324
|
requireKind(artifacts, id, "playbook");
|
|
323
|
-
return scopes.
|
|
325
|
+
return scopes.setAll(id, "explicit");
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Fully hides this Playbook -- never applicable, never injected via before_agent_start, regardless of project. */
|
|
329
|
+
export function setPlaybookNone(artifacts: ArtifactStore, scopes: ArtifactScopeStore, id: string): ArtifactScope {
|
|
330
|
+
requireKind(artifacts, id, "playbook");
|
|
331
|
+
return setArtifactScopeNone(scopes, id);
|
|
324
332
|
}
|
|
325
333
|
|
|
326
334
|
export function replacePlaybookProjects(
|
|
@@ -331,12 +339,7 @@ export function replacePlaybookProjects(
|
|
|
331
339
|
projectReferences: readonly string[],
|
|
332
340
|
): ArtifactScope {
|
|
333
341
|
requireKind(artifacts, id, "playbook");
|
|
334
|
-
|
|
335
|
-
if (projectReferences.length > ARTIFACT_SCOPE_MAX_PROJECTS_PER_ARTIFACT) {
|
|
336
|
-
throw new Error(`projectReferences may include at most ${ARTIFACT_SCOPE_MAX_PROJECTS_PER_ARTIFACT} entries`);
|
|
337
|
-
}
|
|
338
|
-
const ids = projectReferences.map((reference) => resolveProjectReference(registry, reference).id);
|
|
339
|
-
return scopes.replaceProjects(id, ids, "explicit");
|
|
342
|
+
return replaceArtifactScopeProjects(scopes, registry, id, projectReferences);
|
|
340
343
|
}
|
|
341
344
|
|
|
342
345
|
export function addPlaybookProject(
|
|
@@ -347,8 +350,7 @@ export function addPlaybookProject(
|
|
|
347
350
|
projectReference: string,
|
|
348
351
|
): ArtifactScope {
|
|
349
352
|
requireKind(artifacts, id, "playbook");
|
|
350
|
-
|
|
351
|
-
return scopes.addProject(id, project.id, "explicit");
|
|
353
|
+
return addArtifactScopeProject(scopes, registry, id, projectReference);
|
|
352
354
|
}
|
|
353
355
|
|
|
354
356
|
export function removePlaybookProject(
|
|
@@ -359,8 +361,41 @@ export function removePlaybookProject(
|
|
|
359
361
|
projectReference: string,
|
|
360
362
|
): ArtifactScope {
|
|
361
363
|
requireKind(artifacts, id, "playbook");
|
|
362
|
-
|
|
363
|
-
|
|
364
|
+
return removeArtifactScopeProject(scopes, registry, id, projectReference);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Scope-group ('nested scope') siblings of replacePlaybookProjects/addPlaybookProject/removePlaybookProject. */
|
|
368
|
+
export function replacePlaybookGroups(
|
|
369
|
+
artifacts: ArtifactStore,
|
|
370
|
+
scopes: ArtifactScopeStore,
|
|
371
|
+
scopeGroups: ScopeGroupStore,
|
|
372
|
+
id: string,
|
|
373
|
+
groupReferences: readonly string[],
|
|
374
|
+
): ArtifactScope {
|
|
375
|
+
requireKind(artifacts, id, "playbook");
|
|
376
|
+
return replaceArtifactScopeGroups(scopes, scopeGroups, id, groupReferences);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export function addPlaybookGroup(
|
|
380
|
+
artifacts: ArtifactStore,
|
|
381
|
+
scopes: ArtifactScopeStore,
|
|
382
|
+
scopeGroups: ScopeGroupStore,
|
|
383
|
+
id: string,
|
|
384
|
+
groupReference: string,
|
|
385
|
+
): ArtifactScope {
|
|
386
|
+
requireKind(artifacts, id, "playbook");
|
|
387
|
+
return addArtifactScopeGroup(scopes, scopeGroups, id, groupReference);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export function removePlaybookGroup(
|
|
391
|
+
artifacts: ArtifactStore,
|
|
392
|
+
scopes: ArtifactScopeStore,
|
|
393
|
+
scopeGroups: ScopeGroupStore,
|
|
394
|
+
id: string,
|
|
395
|
+
groupReference: string,
|
|
396
|
+
): ArtifactScope {
|
|
397
|
+
requireKind(artifacts, id, "playbook");
|
|
398
|
+
return removeArtifactScopeGroup(scopes, scopeGroups, id, groupReference);
|
|
364
399
|
}
|
|
365
400
|
|
|
366
401
|
export function showPlaybook(artifacts: ArtifactStore, id: string): Artifact {
|
|
@@ -9,20 +9,20 @@ import {
|
|
|
9
9
|
SKILL_WORKFLOW_MAX_NESTING_DEPTH,
|
|
10
10
|
TASK_EXECUTION_MAX_EDGES,
|
|
11
11
|
} from "../constants.ts";
|
|
12
|
+
import { validateChecklist } from "../task/checklist.ts";
|
|
13
|
+
import { projectTaskExecution, TaskExecutionBoundExceededError, type TaskExecutionPlan } from "../task/task-execution.ts";
|
|
14
|
+
import type { TaskGraph, TaskNode, TaskStatus } from "../task/task-service.ts";
|
|
15
|
+
import type { TaskEventContext } from "../task-event/task-event.ts";
|
|
16
|
+
import type { TaskEventStore } from "../task-event/task-event-store.ts";
|
|
17
|
+
import { normalizeProjectRoot } from "../task-scope/task-scope.ts";
|
|
18
|
+
import type { TaskScopeStore } from "../task-scope/task-scope-store.ts";
|
|
12
19
|
import {
|
|
13
20
|
type BlueprintArgumentValue,
|
|
14
21
|
type BlueprintDefinition,
|
|
15
22
|
type CallBlueprint,
|
|
16
23
|
resolveBlueprintArguments,
|
|
17
24
|
validateBlueprintDefinition,
|
|
18
|
-
} from "
|
|
19
|
-
import { validateChecklist } from "../domain/checklist.ts";
|
|
20
|
-
import type { TaskEventContext } from "../domain/task-event.ts";
|
|
21
|
-
import { normalizeProjectRoot } from "../domain/task-scope.ts";
|
|
22
|
-
import type { TaskEventStore } from "../stores/task-event-store.ts";
|
|
23
|
-
import type { TaskScopeStore } from "../stores/task-scope-store.ts";
|
|
24
|
-
import { projectTaskExecution, TaskExecutionBoundExceededError, type TaskExecutionPlan } from "../task/task-execution.ts";
|
|
25
|
-
import type { TaskGraph, TaskNode, TaskStatus } from "../task/task-service.ts";
|
|
25
|
+
} from "./blueprint-definition.ts";
|
|
26
26
|
import { compilePlaybookDefinition, type PlaybookExternalLink } from "./playbook-definition.ts";
|
|
27
27
|
|
|
28
28
|
const RUN_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { basename } from "node:path";
|
|
3
3
|
import { TASK_PROJECT_ALIAS_MAX_COUNT } from "../constants.ts";
|
|
4
|
-
import type { Project, RegisterProjectInput } from "../
|
|
5
|
-
import type { ProjectRegistryStore } from "../
|
|
4
|
+
import type { Project, RegisterProjectInput } from "../project-registry/project-registry.ts";
|
|
5
|
+
import type { ProjectRegistryStore } from "../project-registry/project-registry-store.ts";
|
|
6
6
|
|
|
7
7
|
export function uniqueAliases(values: readonly string[], name: string): string[] {
|
|
8
8
|
const seen = new Set([name.trim().toLowerCase()]);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Project, RegisterProjectInput } from "../
|
|
1
|
+
import type { Project, RegisterProjectInput } from "../project-registry/project-registry.ts";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Kind-neutral project identity, shared by Task scope and every non-Task artifact scope
|
|
@@ -2,9 +2,9 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { basename } from "node:path";
|
|
3
3
|
import type { Db } from "../db.ts";
|
|
4
4
|
import { inTransaction } from "../db.ts";
|
|
5
|
-
import
|
|
6
|
-
import type {
|
|
7
|
-
import {
|
|
5
|
+
import { uniqueAliases } from "../project-registry/in-memory-project-registry-store.ts";
|
|
6
|
+
import type { Project, RegisterProjectInput } from "../project-registry/project-registry.ts";
|
|
7
|
+
import type { ProjectRegistryStore } from "../project-registry/project-registry-store.ts";
|
|
8
8
|
|
|
9
9
|
interface ProjectRow {
|
|
10
10
|
id: string;
|
|
@@ -10,26 +10,29 @@ import { requireLocallyOwnedContent } from "../artifact/artifact.ts";
|
|
|
10
10
|
import type { ArtifactEventContext } from "../artifact/artifact-event.ts";
|
|
11
11
|
import type { ArtifactScope, ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
12
12
|
import type { ArtifactStore } from "../artifact/artifact-store.ts";
|
|
13
|
+
import { RULE_TEXT_HARD_LIMIT_CHARACTERS, RULE_TEXT_SOFT_TARGET_CHARACTERS } from "../constants.ts";
|
|
13
14
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
RULE_TEXT_SOFT_TARGET_CHARACTERS,
|
|
17
|
-
} from "../constants.ts";
|
|
18
|
-
import { resolveProjectReference } from "../domain/project-registry.ts";
|
|
19
|
-
import { normalizeProjectRoot } from "../domain/task-scope.ts";
|
|
20
|
-
import {
|
|
15
|
+
addArtifactScopeGroup,
|
|
16
|
+
addArtifactScopeProject,
|
|
21
17
|
assertLabelsBounds,
|
|
22
18
|
assertTitleBounds,
|
|
23
19
|
assignArtifactProject,
|
|
24
20
|
type ListFilter,
|
|
25
21
|
listScoped,
|
|
22
|
+
removeArtifactScopeGroup,
|
|
23
|
+
removeArtifactScopeProject,
|
|
24
|
+
replaceArtifactScopeGroups,
|
|
25
|
+
replaceArtifactScopeProjects,
|
|
26
26
|
requireContentUpdateFields,
|
|
27
27
|
requireKind,
|
|
28
28
|
runTransition,
|
|
29
|
+
setArtifactScopeNone,
|
|
29
30
|
type TransitionTable,
|
|
30
31
|
type UpdateContentInput,
|
|
31
32
|
} from "../domain-service-shared.ts";
|
|
32
|
-
import type { ProjectRegistryStore } from "../
|
|
33
|
+
import type { ProjectRegistryStore } from "../project-registry/project-registry-store.ts";
|
|
34
|
+
import type { ScopeGroupStore } from "../scope-group/scope-group-store.ts";
|
|
35
|
+
import { normalizeProjectRoot } from "../task-scope/task-scope.ts";
|
|
33
36
|
|
|
34
37
|
export interface CreateRuleInput {
|
|
35
38
|
title: string;
|
|
@@ -156,11 +159,7 @@ export function createRule(
|
|
|
156
159
|
context,
|
|
157
160
|
);
|
|
158
161
|
if (input.projectReferences !== undefined && input.projectReferences.length > 0) {
|
|
159
|
-
|
|
160
|
-
throw new Error(`projectReferences may include at most ${ARTIFACT_SCOPE_MAX_PROJECTS_PER_ARTIFACT} entries`);
|
|
161
|
-
}
|
|
162
|
-
const ids = input.projectReferences.map((reference) => resolveProjectReference(registry!, reference).id);
|
|
163
|
-
scopes.replaceProjects(rule.id, ids, "explicit");
|
|
162
|
+
replaceArtifactScopeProjects(scopes, registry!, rule.id, input.projectReferences);
|
|
164
163
|
} else {
|
|
165
164
|
scopes.assign(rule.id, projectRoot, projectRoot === undefined ? "unscoped" : "explicit");
|
|
166
165
|
}
|
|
@@ -195,7 +194,13 @@ export function ruleScope(artifacts: ArtifactStore, scopes: ArtifactScopeStore,
|
|
|
195
194
|
|
|
196
195
|
export function setRuleGlobal(artifacts: ArtifactStore, scopes: ArtifactScopeStore, id: string): ArtifactScope {
|
|
197
196
|
requireKind(artifacts, id, "rule");
|
|
198
|
-
return scopes.
|
|
197
|
+
return scopes.setAll(id, "explicit");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Fully hides this Rule -- never applicable, never injected, regardless of project. */
|
|
201
|
+
export function setRuleNone(artifacts: ArtifactStore, scopes: ArtifactScopeStore, id: string): ArtifactScope {
|
|
202
|
+
requireKind(artifacts, id, "rule");
|
|
203
|
+
return setArtifactScopeNone(scopes, id);
|
|
199
204
|
}
|
|
200
205
|
|
|
201
206
|
export function replaceRuleProjects(
|
|
@@ -206,12 +211,7 @@ export function replaceRuleProjects(
|
|
|
206
211
|
projectReferences: readonly string[],
|
|
207
212
|
): ArtifactScope {
|
|
208
213
|
requireKind(artifacts, id, "rule");
|
|
209
|
-
|
|
210
|
-
if (projectReferences.length > ARTIFACT_SCOPE_MAX_PROJECTS_PER_ARTIFACT) {
|
|
211
|
-
throw new Error(`projectReferences may include at most ${ARTIFACT_SCOPE_MAX_PROJECTS_PER_ARTIFACT} entries`);
|
|
212
|
-
}
|
|
213
|
-
const ids = projectReferences.map((reference) => resolveProjectReference(registry, reference).id);
|
|
214
|
-
return scopes.replaceProjects(id, ids, "explicit");
|
|
214
|
+
return replaceArtifactScopeProjects(scopes, registry, id, projectReferences);
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
export function addRuleProject(
|
|
@@ -222,8 +222,7 @@ export function addRuleProject(
|
|
|
222
222
|
projectReference: string,
|
|
223
223
|
): ArtifactScope {
|
|
224
224
|
requireKind(artifacts, id, "rule");
|
|
225
|
-
|
|
226
|
-
return scopes.addProject(id, project.id, "explicit");
|
|
225
|
+
return addArtifactScopeProject(scopes, registry, id, projectReference);
|
|
227
226
|
}
|
|
228
227
|
|
|
229
228
|
export function removeRuleProject(
|
|
@@ -234,8 +233,41 @@ export function removeRuleProject(
|
|
|
234
233
|
projectReference: string,
|
|
235
234
|
): ArtifactScope {
|
|
236
235
|
requireKind(artifacts, id, "rule");
|
|
237
|
-
|
|
238
|
-
|
|
236
|
+
return removeArtifactScopeProject(scopes, registry, id, projectReference);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Scope-group ('nested scope') siblings of replaceRuleProjects/addRuleProject/removeRuleProject. */
|
|
240
|
+
export function replaceRuleGroups(
|
|
241
|
+
artifacts: ArtifactStore,
|
|
242
|
+
scopes: ArtifactScopeStore,
|
|
243
|
+
scopeGroups: ScopeGroupStore,
|
|
244
|
+
id: string,
|
|
245
|
+
groupReferences: readonly string[],
|
|
246
|
+
): ArtifactScope {
|
|
247
|
+
requireKind(artifacts, id, "rule");
|
|
248
|
+
return replaceArtifactScopeGroups(scopes, scopeGroups, id, groupReferences);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function addRuleGroup(
|
|
252
|
+
artifacts: ArtifactStore,
|
|
253
|
+
scopes: ArtifactScopeStore,
|
|
254
|
+
scopeGroups: ScopeGroupStore,
|
|
255
|
+
id: string,
|
|
256
|
+
groupReference: string,
|
|
257
|
+
): ArtifactScope {
|
|
258
|
+
requireKind(artifacts, id, "rule");
|
|
259
|
+
return addArtifactScopeGroup(scopes, scopeGroups, id, groupReference);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function removeRuleGroup(
|
|
263
|
+
artifacts: ArtifactStore,
|
|
264
|
+
scopes: ArtifactScopeStore,
|
|
265
|
+
scopeGroups: ScopeGroupStore,
|
|
266
|
+
id: string,
|
|
267
|
+
groupReference: string,
|
|
268
|
+
): ArtifactScope {
|
|
269
|
+
requireKind(artifacts, id, "rule");
|
|
270
|
+
return removeArtifactScopeGroup(scopes, scopeGroups, id, groupReference);
|
|
239
271
|
}
|
|
240
272
|
|
|
241
273
|
/** The extra.scope run-gating check alone -- a Rule with no extra.scope always passes this; one with a skill-run/playbook-run scope passes only while its run owns activeTaskId. Both a workflow-definition target's own run scope ("skill-run", written by workflow-execution.ts's runWorkflowSteps for that target kind) and a Playbook's own run scope ("playbook-run", same call for a Playbook target) are recognized -- confirmed live that only "skill-run" was ever checked here, silently breaking Playbook-run-scoped rule injection since Playbook gained its own doc/rule structured steps. */
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ArtifactScopeStore } from "../artifact/artifact-scope-store.ts";
|
|
2
|
+
import { ScopeGroupInUseError } from "./scope-group.ts";
|
|
3
|
+
import type { ScopeGroupStore } from "./scope-group-store.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The one real cross-store check a plain ScopeGroupStore.delete() cannot make on its own: whether
|
|
7
|
+
* any Doc/Rule/Playbook's own explicit scope still references this group. ScopeGroupStore.delete()
|
|
8
|
+
* itself only checks the self-consistency case (another group's own membership) -- deliberately,
|
|
9
|
+
* so the store's own port stays kind-agnostic and never depends on ArtifactScopeStore. This
|
|
10
|
+
* orchestration function is the one real caller that holds both.
|
|
11
|
+
*/
|
|
12
|
+
export function deleteScopeGroup(scopeGroups: ScopeGroupStore, artifactScopes: ArtifactScopeStore, groupId: string): void {
|
|
13
|
+
if (artifactScopes.referencesGroup(groupId)) {
|
|
14
|
+
throw new ScopeGroupInUseError(`scope group "${groupId}" is still referenced by at least one artifact's explicit scope`);
|
|
15
|
+
}
|
|
16
|
+
scopeGroups.delete(groupId);
|
|
17
|
+
}
|