@anthusai/papyrus 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/amplify/plugins/editorial-checks/function/handler.py +11 -0
  2. package/amplify/plugins/editorial-checks/function/requirements.txt +1 -0
  3. package/amplify/plugins/editorial-checks/function/resource.js +43 -0
  4. package/amplify/plugins/editorial-checks/function/resource.ts +60 -0
  5. package/amplify/plugins/editorial-checks/papyrus.plugin.js +50 -0
  6. package/amplify/plugins/editorial-checks/papyrus.plugin.ts +63 -0
  7. package/amplify/plugins/editorial-checks/schema.js +94 -0
  8. package/amplify/plugins/editorial-checks/schema.ts +96 -0
  9. package/amplify/plugins/registry.js +2 -0
  10. package/amplify/plugins/registry.ts +2 -0
  11. package/components/editorial-checks-admin-panel.tsx +337 -0
  12. package/components/editorial-finding-card.tsx +162 -0
  13. package/components/editorial-findings-panel.tsx +91 -0
  14. package/components/editorial-preview-popover.tsx +103 -0
  15. package/components/markus-body-editor.tsx +213 -0
  16. package/components/markus-ir-preview.tsx +147 -6
  17. package/components/newsroom-article-editor.tsx +138 -11
  18. package/components/newsroom-board-view.tsx +2 -6
  19. package/components/newsroom-ops-shell.tsx +7 -3
  20. package/components/newsroom-organizer.css +57 -61
  21. package/components/newsroom-theme-fonts/broadsheet-green.css +10 -0
  22. package/components/newsroom-theme-fonts/broadsheet-green.tsx +6 -0
  23. package/components/newsroom-theme-fonts/newspaper-gothic.css +9 -0
  24. package/components/newsroom-theme-fonts/newspaper-gothic.tsx +6 -0
  25. package/components/newsroom-theme-fonts/night-desk.css +10 -0
  26. package/components/newsroom-theme-fonts/night-desk.tsx +6 -0
  27. package/components/newsroom-theme-fonts/refined-newsprint.css +11 -0
  28. package/components/newsroom-theme-fonts/refined-newsprint.tsx +6 -0
  29. package/components/newsroom-theme.css +39 -0
  30. package/components/newsroom-theme.tsx +33 -0
  31. package/components/topic-steering-workspace.tsx +19 -1
  32. package/components/use-editorial-checks.ts +131 -0
  33. package/lib/editorial-checks-backend.ts +16 -0
  34. package/lib/editorial-checks-client.ts +194 -0
  35. package/lib/editorial-checks-demo.ts +147 -0
  36. package/lib/editorial-checks-settings.ts +24 -0
  37. package/lib/editorial-checks.ts +178 -0
  38. package/lib/editorial-preview.ts +228 -0
  39. package/lib/site-brand.ts +17 -0
  40. package/package.json +34 -2
  41. package/routes.manifest.json +1 -1
  42. package/components/newsroom-fonts/playfair-display-700.ttf +0 -0
  43. package/components/newsroom-fonts/playfair-display-900.ttf +0 -0
  44. package/components/newsroom-fonts/playfair-display-OFL.txt +0 -93
  45. package/components/newsroom-fonts/plus-jakarta-sans-400.ttf +0 -0
  46. package/components/newsroom-fonts/plus-jakarta-sans-600.ttf +0 -0
  47. package/components/newsroom-fonts/plus-jakarta-sans-OFL.txt +0 -93
  48. package/components/newsroom-newsprint-board.css +0 -7
@@ -0,0 +1,11 @@
1
+ """The editorial-checks plugin's function: routes its GraphQL fields to papyrus_content.editorial_checks."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from papyrus_content.editorial_checks import GraphQLEditorialStore, Services, handle
8
+
9
+
10
+ def handler(event: dict[str, Any], _context: Any = None) -> dict[str, Any]:
11
+ return handle(event["info"]["fieldName"], event.get("arguments") or {}, Services(store=GraphQLEditorialStore()))
@@ -0,0 +1 @@
1
+ limatus[jev]>=0.31,<0.32
@@ -0,0 +1,43 @@
1
+ import { defineFunction } from "@aws-amplify/backend";
2
+ import { Duration } from "aws-cdk-lib";
3
+ import { Architecture, Function, Runtime } from "aws-cdk-lib/aws-lambda";
4
+ import { execFileSync } from "node:child_process";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { pythonLambdaCode } from "../../../functions/shared/python-bundle.js";
8
+ const functionDirectory = path.dirname(fileURLToPath(import.meta.url));
9
+ /** AppSync gives a resolver 30 seconds; Limatus's classifier deadline (settings, default 20 s) keeps a check inside this. */
10
+ export const EDITORIAL_CHECKS_TIMEOUT_SECONDS = 28;
11
+ /** Limatus with the Jev classifier lane; papyrus_content.editorial_checks does the work. */
12
+ export const editorialChecksRequirements = ["limatus[jev]>=0.31,<0.32"];
13
+ function installRequirements(outputDir) {
14
+ execFileSync("python3", [
15
+ "-m", "pip", "install", "-r", path.join(functionDirectory, "requirements.txt"), "-t", outputDir, "--no-cache-dir",
16
+ "--platform", "manylinux2014_aarch64", "--implementation", "cp", "--python-version", "3.12",
17
+ "--only-binary=:all:", "--ignore-requires-python",
18
+ ], { stdio: "inherit" });
19
+ }
20
+ export const editorialChecks = defineFunction((scope) => new Function(scope, "papyrus-editorial-checks", {
21
+ runtime: Runtime.PYTHON_3_12,
22
+ architecture: Architecture.ARM_64,
23
+ handler: "handler.handler",
24
+ timeout: Duration.seconds(EDITORIAL_CHECKS_TIMEOUT_SECONDS),
25
+ memorySize: 1024,
26
+ code: pythonLambdaCode({
27
+ functionDir: "../plugins/editorial-checks/function",
28
+ modules: ["papyrus_content"],
29
+ requirements: editorialChecksRequirements,
30
+ noDeps: true,
31
+ checkoutExtras: installRequirements,
32
+ }, [
33
+ "bash",
34
+ "-c",
35
+ [
36
+ "set -euo pipefail",
37
+ "mkdir -p /asset-output/papyrus_content",
38
+ "cp amplify/plugins/editorial-checks/function/handler.py /asset-output/handler.py",
39
+ "cp -R src/papyrus_content/. /asset-output/papyrus_content/",
40
+ "python3 -m pip install -r amplify/plugins/editorial-checks/function/requirements.txt -t /asset-output --no-cache-dir",
41
+ ].join(" && "),
42
+ ]),
43
+ }), { resourceGroupName: "data" });
@@ -0,0 +1,60 @@
1
+ import { defineFunction } from "@aws-amplify/backend";
2
+ import { Duration } from "aws-cdk-lib";
3
+ import { Architecture, Function, Runtime } from "aws-cdk-lib/aws-lambda";
4
+ import type { Construct } from "constructs";
5
+ import { execFileSync } from "node:child_process";
6
+ import path from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { pythonLambdaCode } from "../../../functions/shared/python-bundle";
9
+
10
+ const functionDirectory = path.dirname(fileURLToPath(import.meta.url));
11
+
12
+ /** AppSync gives a resolver 30 seconds; Limatus's classifier deadline (settings, default 20 s) keeps a check inside this. */
13
+ export const EDITORIAL_CHECKS_TIMEOUT_SECONDS = 28;
14
+
15
+ /** Limatus with the Jev classifier lane; papyrus_content.editorial_checks does the work. */
16
+ export const editorialChecksRequirements = ["limatus[jev]>=0.31,<0.32"];
17
+
18
+ function installRequirements(outputDir: string): void {
19
+ execFileSync(
20
+ "python3",
21
+ [
22
+ "-m", "pip", "install", "-r", path.join(functionDirectory, "requirements.txt"), "-t", outputDir, "--no-cache-dir",
23
+ "--platform", "manylinux2014_aarch64", "--implementation", "cp", "--python-version", "3.12",
24
+ "--only-binary=:all:", "--ignore-requires-python",
25
+ ],
26
+ { stdio: "inherit" },
27
+ );
28
+ }
29
+
30
+ export const editorialChecks = defineFunction(
31
+ (scope: Construct) =>
32
+ new Function(scope, "papyrus-editorial-checks", {
33
+ runtime: Runtime.PYTHON_3_12,
34
+ architecture: Architecture.ARM_64,
35
+ handler: "handler.handler",
36
+ timeout: Duration.seconds(EDITORIAL_CHECKS_TIMEOUT_SECONDS),
37
+ memorySize: 1024,
38
+ code: pythonLambdaCode(
39
+ {
40
+ functionDir: "../plugins/editorial-checks/function",
41
+ modules: ["papyrus_content"],
42
+ requirements: editorialChecksRequirements,
43
+ noDeps: true,
44
+ checkoutExtras: installRequirements,
45
+ },
46
+ [
47
+ "bash",
48
+ "-c",
49
+ [
50
+ "set -euo pipefail",
51
+ "mkdir -p /asset-output/papyrus_content",
52
+ "cp amplify/plugins/editorial-checks/function/handler.py /asset-output/handler.py",
53
+ "cp -R src/papyrus_content/. /asset-output/papyrus_content/",
54
+ "python3 -m pip install -r amplify/plugins/editorial-checks/function/requirements.txt -t /asset-output --no-cache-dir",
55
+ ].join(" && "),
56
+ ],
57
+ ),
58
+ }),
59
+ { resourceGroupName: "data" },
60
+ );
@@ -0,0 +1,50 @@
1
+ import { secret } from "@aws-amplify/backend";
2
+ import { Stack } from "aws-cdk-lib";
3
+ import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
4
+ import { editorialChecks } from "./function/resource.js";
5
+ import { editorialChecksSchemaDefinitions } from "./schema.js";
6
+ export const EDITORIAL_CHECKS_QUERIES = ["checkEditorial", "suggestEditorialRewrite", "draftEditorialQuestions", "tryEditorialPolicy"];
7
+ export const EDITORIAL_CHECKS_MUTATIONS = ["importEditorialStarterPack", "recalibrateEditorialPolicies"];
8
+ /** The model operations the function performs with its own role. */
9
+ export const EDITORIAL_CHECKS_FUNCTION_FIELDS = [
10
+ "Query/fields/listEditorialPolicies",
11
+ "Query/fields/getEditorialCheckSettings",
12
+ "Query/fields/listEditorialFeedbacks",
13
+ "Mutation/fields/createEditorialPolicy",
14
+ "Mutation/fields/updateEditorialPolicy",
15
+ ];
16
+ export const editorialChecksManifest = {
17
+ name: "editorial-checks",
18
+ contract: 1,
19
+ models: ["EditorialPolicy", "EditorialCheckSettings", "EditorialFeedback"],
20
+ mutations: [...EDITORIAL_CHECKS_QUERIES, ...EDITORIAL_CHECKS_MUTATIONS],
21
+ guest: { mutations: [] },
22
+ newsroomPanels: [{ id: "editorial-checks", label: "Editorial checks" }],
23
+ staticAssets: [],
24
+ };
25
+ export function resolveEditorialChecksConfig(request) {
26
+ const raw = typeof request === "string" ? { name: request } : request;
27
+ const unknown = Object.keys(raw).filter((key) => key !== "name");
28
+ if (unknown.length > 0)
29
+ throw new Error(`Unknown editorial-checks plugin settings: ${unknown.join(", ")} (runtime settings are edited in the newsroom)`);
30
+ return {};
31
+ }
32
+ export const editorialChecksPlugin = {
33
+ manifest: editorialChecksManifest,
34
+ resolveConfig: resolveEditorialChecksConfig,
35
+ functions: () => ({ editorialChecks }),
36
+ schemaDefinitions: editorialChecksSchemaDefinitions,
37
+ publicSettings: () => ({ contract: editorialChecksManifest.contract }),
38
+ wire(backend, _config, context) {
39
+ const lambda = backend.editorialChecks.resources.lambda;
40
+ const stack = Stack.of(lambda);
41
+ lambda.addEnvironment("PAPYRUS_GRAPHQL_ENDPOINT", context.graphqlEndpoint);
42
+ backend.editorialChecks.addEnvironment("TYPESAFE_API_KEY", secret("TYPESAFE_API_KEY"));
43
+ backend.editorialChecks.addEnvironment("OPENAI_API_KEY", secret("OPENAI_API_KEY"));
44
+ lambda.addToRolePolicy(new PolicyStatement({
45
+ effect: Effect.ALLOW,
46
+ actions: ["appsync:GraphQL"],
47
+ resources: EDITORIAL_CHECKS_FUNCTION_FIELDS.map((field) => `arn:aws:appsync:${stack.region}:${stack.account}:apis/${context.graphqlApiId}/types/${field}`),
48
+ }));
49
+ },
50
+ };
@@ -0,0 +1,63 @@
1
+ import { secret } from "@aws-amplify/backend";
2
+ import { Stack } from "aws-cdk-lib";
3
+ import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
4
+ import type { Function as LambdaFunction } from "aws-cdk-lib/aws-lambda";
5
+ import type { PapyrusPlugin, PluginManifest, PluginRequest, PluginWiringContext } from "../types";
6
+ import { editorialChecks } from "./function/resource";
7
+ import { editorialChecksSchemaDefinitions } from "./schema";
8
+
9
+ /** Runtime settings (lanes, models, deadline) live in EditorialCheckSettings, edited in the newsroom; enabling the plugin takes no options. */
10
+ export type EditorialChecksPluginConfig = Record<string, never>;
11
+
12
+ export const EDITORIAL_CHECKS_QUERIES = ["checkEditorial", "suggestEditorialRewrite", "draftEditorialQuestions", "tryEditorialPolicy"];
13
+ export const EDITORIAL_CHECKS_MUTATIONS = ["importEditorialStarterPack", "recalibrateEditorialPolicies"];
14
+
15
+ /** The model operations the function performs with its own role. */
16
+ export const EDITORIAL_CHECKS_FUNCTION_FIELDS = [
17
+ "Query/fields/listEditorialPolicies",
18
+ "Query/fields/getEditorialCheckSettings",
19
+ "Query/fields/listEditorialFeedbacks",
20
+ "Mutation/fields/createEditorialPolicy",
21
+ "Mutation/fields/updateEditorialPolicy",
22
+ ];
23
+
24
+ export const editorialChecksManifest: PluginManifest = {
25
+ name: "editorial-checks",
26
+ contract: 1,
27
+ models: ["EditorialPolicy", "EditorialCheckSettings", "EditorialFeedback"],
28
+ mutations: [...EDITORIAL_CHECKS_QUERIES, ...EDITORIAL_CHECKS_MUTATIONS],
29
+ guest: { mutations: [] },
30
+ newsroomPanels: [{ id: "editorial-checks", label: "Editorial checks" }],
31
+ staticAssets: [],
32
+ };
33
+
34
+ export function resolveEditorialChecksConfig(request: PluginRequest): EditorialChecksPluginConfig {
35
+ const raw = typeof request === "string" ? { name: request } : request;
36
+ const unknown = Object.keys(raw).filter((key) => key !== "name");
37
+ if (unknown.length > 0) throw new Error(`Unknown editorial-checks plugin settings: ${unknown.join(", ")} (runtime settings are edited in the newsroom)`);
38
+ return {};
39
+ }
40
+
41
+ export const editorialChecksPlugin: PapyrusPlugin<EditorialChecksPluginConfig, { editorialChecks: typeof editorialChecks }> = {
42
+ manifest: editorialChecksManifest,
43
+ resolveConfig: resolveEditorialChecksConfig,
44
+ functions: () => ({ editorialChecks }),
45
+ schemaDefinitions: editorialChecksSchemaDefinitions,
46
+ publicSettings: () => ({ contract: editorialChecksManifest.contract }),
47
+ wire(backend, _config, context: PluginWiringContext) {
48
+ const lambda = backend.editorialChecks.resources.lambda as LambdaFunction;
49
+ const stack = Stack.of(lambda);
50
+ lambda.addEnvironment("PAPYRUS_GRAPHQL_ENDPOINT", context.graphqlEndpoint);
51
+ backend.editorialChecks.addEnvironment("TYPESAFE_API_KEY", secret("TYPESAFE_API_KEY"));
52
+ backend.editorialChecks.addEnvironment("OPENAI_API_KEY", secret("OPENAI_API_KEY"));
53
+ lambda.addToRolePolicy(
54
+ new PolicyStatement({
55
+ effect: Effect.ALLOW,
56
+ actions: ["appsync:GraphQL"],
57
+ resources: EDITORIAL_CHECKS_FUNCTION_FIELDS.map(
58
+ (field) => `arn:aws:appsync:${stack.region}:${stack.account}:apis/${context.graphqlApiId}/types/${field}`,
59
+ ),
60
+ }),
61
+ );
62
+ },
63
+ };
@@ -0,0 +1,94 @@
1
+ import { a } from "@aws-amplify/backend";
2
+ import { editorialChecks } from "./function/resource.js";
3
+ const editors = ["editor", "admin"];
4
+ /**
5
+ * Policies, settings and editors' decisions live in Papyrus; Limatus checks
6
+ * content against them. Editors read policies and record decisions; admins
7
+ * manage policies and settings. Only the function (IAM) calls Limatus.
8
+ */
9
+ export function editorialChecksSchemaDefinitions() {
10
+ return {
11
+ EditorialPolicy: a
12
+ .model({
13
+ id: a.id().required(),
14
+ policyKey: a.string().required(),
15
+ scope: a.string().required(),
16
+ version: a.integer().required(),
17
+ title: a.string().required(),
18
+ guidance: a.string().required(),
19
+ severity: a.string().required(),
20
+ enabled: a.boolean().required(),
21
+ detectors: a.json().required(),
22
+ examples: a.json(),
23
+ rewriteGuidance: a.string(),
24
+ source: a.string().required(),
25
+ })
26
+ .disableOperations(["subscriptions"])
27
+ .authorization((allow) => [allow.group("editor").to(["read"]), allow.group("admin")]),
28
+ EditorialCheckSettings: a
29
+ .model({
30
+ id: a.id().required(),
31
+ settings: a.json().required(),
32
+ })
33
+ .disableOperations(["subscriptions"])
34
+ .authorization((allow) => [allow.group("editor").to(["read"]), allow.group("admin")]),
35
+ EditorialFeedback: a
36
+ .model({
37
+ id: a.id().required(),
38
+ itemId: a.string().required(),
39
+ findingId: a.string().required(),
40
+ policyId: a.string().required(),
41
+ detectorId: a.string().required(),
42
+ lane: a.string().required(),
43
+ probability: a.float(),
44
+ decision: a.string().required(),
45
+ reason: a.string(),
46
+ text: a.string(),
47
+ })
48
+ .disableOperations(["subscriptions"])
49
+ .secondaryIndexes((index) => [index("itemId").queryField("listEditorialFeedbackByItem")])
50
+ .authorization((allow) => [allow.group("editor").to(["create", "read"]), allow.group("admin")]),
51
+ checkEditorial: a
52
+ .query()
53
+ .arguments({ body: a.string().required(), format: a.string(), section: a.string() })
54
+ .returns(a.json())
55
+ .authorization((allow) => [allow.groups(editors)])
56
+ .handler(a.handler.function(editorialChecks)),
57
+ suggestEditorialRewrite: a
58
+ .query()
59
+ .arguments({
60
+ body: a.string().required(),
61
+ format: a.string(),
62
+ section: a.string(),
63
+ finding: a.json(),
64
+ selection: a.json(),
65
+ note: a.string(),
66
+ })
67
+ .returns(a.json())
68
+ .authorization((allow) => [allow.groups(editors)])
69
+ .handler(a.handler.function(editorialChecks)),
70
+ draftEditorialQuestions: a
71
+ .query()
72
+ .arguments({ title: a.string().required(), guidance: a.string().required(), examples: a.json() })
73
+ .returns(a.json())
74
+ .authorization((allow) => [allow.group("admin")])
75
+ .handler(a.handler.function(editorialChecks)),
76
+ tryEditorialPolicy: a
77
+ .query()
78
+ .arguments({ policy: a.json().required(), text: a.string().required(), format: a.string() })
79
+ .returns(a.json())
80
+ .authorization((allow) => [allow.group("admin")])
81
+ .handler(a.handler.function(editorialChecks)),
82
+ importEditorialStarterPack: a
83
+ .mutation()
84
+ .arguments({ name: a.string().required() })
85
+ .returns(a.json())
86
+ .authorization((allow) => [allow.group("admin")])
87
+ .handler(a.handler.function(editorialChecks)),
88
+ recalibrateEditorialPolicies: a
89
+ .mutation()
90
+ .returns(a.json())
91
+ .authorization((allow) => [allow.group("admin")])
92
+ .handler(a.handler.function(editorialChecks)),
93
+ };
94
+ }
@@ -0,0 +1,96 @@
1
+ import { a } from "@aws-amplify/backend";
2
+ import { editorialChecks } from "./function/resource";
3
+
4
+ const editors = ["editor", "admin"];
5
+
6
+ /**
7
+ * Policies, settings and editors' decisions live in Papyrus; Limatus checks
8
+ * content against them. Editors read policies and record decisions; admins
9
+ * manage policies and settings. Only the function (IAM) calls Limatus.
10
+ */
11
+ export function editorialChecksSchemaDefinitions() {
12
+ return {
13
+ EditorialPolicy: a
14
+ .model({
15
+ id: a.id().required(),
16
+ policyKey: a.string().required(),
17
+ scope: a.string().required(),
18
+ version: a.integer().required(),
19
+ title: a.string().required(),
20
+ guidance: a.string().required(),
21
+ severity: a.string().required(),
22
+ enabled: a.boolean().required(),
23
+ detectors: a.json().required(),
24
+ examples: a.json(),
25
+ rewriteGuidance: a.string(),
26
+ source: a.string().required(),
27
+ })
28
+ .disableOperations(["subscriptions"])
29
+ .authorization((allow) => [allow.group("editor").to(["read"]), allow.group("admin")]),
30
+ EditorialCheckSettings: a
31
+ .model({
32
+ id: a.id().required(),
33
+ settings: a.json().required(),
34
+ })
35
+ .disableOperations(["subscriptions"])
36
+ .authorization((allow) => [allow.group("editor").to(["read"]), allow.group("admin")]),
37
+ EditorialFeedback: a
38
+ .model({
39
+ id: a.id().required(),
40
+ itemId: a.string().required(),
41
+ findingId: a.string().required(),
42
+ policyId: a.string().required(),
43
+ detectorId: a.string().required(),
44
+ lane: a.string().required(),
45
+ probability: a.float(),
46
+ decision: a.string().required(),
47
+ reason: a.string(),
48
+ text: a.string(),
49
+ })
50
+ .disableOperations(["subscriptions"])
51
+ .secondaryIndexes((index) => [index("itemId").queryField("listEditorialFeedbackByItem")])
52
+ .authorization((allow) => [allow.group("editor").to(["create", "read"]), allow.group("admin")]),
53
+ checkEditorial: a
54
+ .query()
55
+ .arguments({ body: a.string().required(), format: a.string(), section: a.string() })
56
+ .returns(a.json())
57
+ .authorization((allow) => [allow.groups(editors)])
58
+ .handler(a.handler.function(editorialChecks)),
59
+ suggestEditorialRewrite: a
60
+ .query()
61
+ .arguments({
62
+ body: a.string().required(),
63
+ format: a.string(),
64
+ section: a.string(),
65
+ finding: a.json(),
66
+ selection: a.json(),
67
+ note: a.string(),
68
+ })
69
+ .returns(a.json())
70
+ .authorization((allow) => [allow.groups(editors)])
71
+ .handler(a.handler.function(editorialChecks)),
72
+ draftEditorialQuestions: a
73
+ .query()
74
+ .arguments({ title: a.string().required(), guidance: a.string().required(), examples: a.json() })
75
+ .returns(a.json())
76
+ .authorization((allow) => [allow.group("admin")])
77
+ .handler(a.handler.function(editorialChecks)),
78
+ tryEditorialPolicy: a
79
+ .query()
80
+ .arguments({ policy: a.json().required(), text: a.string().required(), format: a.string() })
81
+ .returns(a.json())
82
+ .authorization((allow) => [allow.group("admin")])
83
+ .handler(a.handler.function(editorialChecks)),
84
+ importEditorialStarterPack: a
85
+ .mutation()
86
+ .arguments({ name: a.string().required() })
87
+ .returns(a.json())
88
+ .authorization((allow) => [allow.group("admin")])
89
+ .handler(a.handler.function(editorialChecks)),
90
+ recalibrateEditorialPolicies: a
91
+ .mutation()
92
+ .returns(a.json())
93
+ .authorization((allow) => [allow.group("admin")])
94
+ .handler(a.handler.function(editorialChecks)),
95
+ };
96
+ }
@@ -1,6 +1,8 @@
1
+ import { editorialChecksPlugin } from "./editorial-checks/papyrus.plugin.js";
1
2
  import { signupPlugin } from "./signup/papyrus.plugin.js";
2
3
  /** Plugins are packaged with Papyrus and pinned by its version: there is no registry to fetch from. */
3
4
  export const KNOWN_PLUGINS = {
5
+ "editorial-checks": editorialChecksPlugin,
4
6
  signup: signupPlugin,
5
7
  };
6
8
  export function resolvePlugins(requests) {
@@ -1,8 +1,10 @@
1
1
  import type { PapyrusPlugin, PluginRequest } from "./types";
2
+ import { editorialChecksPlugin } from "./editorial-checks/papyrus.plugin";
2
3
  import { signupPlugin } from "./signup/papyrus.plugin";
3
4
 
4
5
  /** Plugins are packaged with Papyrus and pinned by its version: there is no registry to fetch from. */
5
6
  export const KNOWN_PLUGINS: Record<string, PapyrusPlugin<any, any>> = {
7
+ "editorial-checks": editorialChecksPlugin,
6
8
  signup: signupPlugin,
7
9
  };
8
10