@anthusai/papyrus 5.42.1 → 5.43.0-next.10

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 (83) hide show
  1. package/amplify/data/schema.js +2 -0
  2. package/amplify/data/schema.ts +2 -0
  3. package/amplify/functions/category-action/handler.ts +2 -1
  4. package/amplify/functions/monitoring-view/schema.js +22 -0
  5. package/amplify/functions/monitoring-view/schema.ts +22 -0
  6. package/amplify/functions/monitoring-view/wire.js +1 -0
  7. package/amplify/functions/monitoring-view/wire.ts +1 -0
  8. package/amplify/functions/procedure-action/handler.ts +2 -10
  9. package/amplify/functions/proposal-actions/handler.py +137 -0
  10. package/amplify/{plugins/reader-steering/function → functions/proposal-actions}/proposals.py +20 -3
  11. package/amplify/functions/proposal-actions/resource.js +15 -0
  12. package/amplify/functions/proposal-actions/resource.ts +22 -0
  13. package/amplify/functions/proposal-actions/schema.js +106 -0
  14. package/amplify/functions/proposal-actions/schema.ts +108 -0
  15. package/amplify/functions/proposal-actions/wire.js +10 -0
  16. package/amplify/functions/proposal-actions/wire.ts +13 -0
  17. package/amplify/plugins/reader-steering/function/handler.py +13 -72
  18. package/amplify/plugins/reader-steering/function/moderation.py +19 -0
  19. package/amplify/plugins/reader-steering/papyrus.plugin.js +5 -5
  20. package/amplify/plugins/reader-steering/papyrus.plugin.ts +5 -5
  21. package/amplify/plugins/reader-steering/schema.js +0 -95
  22. package/amplify/plugins/reader-steering/schema.ts +0 -95
  23. package/amplify/site-backend.js +4 -0
  24. package/amplify/site-backend.ts +4 -0
  25. package/app/.well-known/papyrus-cli.json/route.ts +9 -0
  26. package/app/globals.css +31 -35
  27. package/app/tailwind.css +2 -0
  28. package/bin/papyrus-infra.mjs +21 -1
  29. package/components/dev-sandbox-editor-sign-in.tsx +2 -2
  30. package/components/monitoring-overview-view.tsx +140 -23
  31. package/components/monitoring-panel.tsx +96 -6
  32. package/components/news-desk-client-provider.tsx +8 -2
  33. package/components/news-desk-taxonomy-client.ts +2 -1
  34. package/components/newsroom-mobile-navigation.tsx +23 -0
  35. package/components/newsroom-ops-overview.tsx +6 -1
  36. package/components/newsroom-ops-shell.tsx +8 -10
  37. package/components/newsroom-organizer.css +1 -0
  38. package/components/newsroom-references-view.tsx +139 -257
  39. package/components/notification-center.tsx +345 -63
  40. package/components/papyrus-console-frame.tsx +66 -0
  41. package/components/papyrus-console-shell.tsx +14 -42
  42. package/components/papyrus-private-chat-panel.tsx +50 -16
  43. package/components/proposals-panel.tsx +107 -0
  44. package/components/proposals-view.tsx +95 -0
  45. package/components/reference-review-card.tsx +400 -0
  46. package/components/topic-steering-workspace.tsx +13 -2
  47. package/components/use-console-visibility.ts +47 -0
  48. package/infra/amplify-app-shell.js +18 -2
  49. package/infra/amplify-app-shell.ts +18 -2
  50. package/infra/chat-stack.js +222 -0
  51. package/infra/chat-stack.ts +250 -0
  52. package/infra/chat.test.js +142 -0
  53. package/infra/chat.test.ts +151 -0
  54. package/infra/index.js +1 -0
  55. package/infra/site-config.js +58 -1
  56. package/infra/site-config.ts +78 -1
  57. package/lib/cli-login-discovery.ts +78 -0
  58. package/lib/monitoring-client.ts +39 -3
  59. package/lib/monitoring-overview-fixture.ts +2 -2
  60. package/lib/monitoring-overview.ts +47 -3
  61. package/lib/monitoring-paging.ts +58 -0
  62. package/lib/newsroom-chat-client.ts +30 -0
  63. package/lib/newsroom-chat-identity.ts +40 -0
  64. package/lib/newsroom-organizer-nav.ts +1 -0
  65. package/lib/papyrus-hosted-chat.ts +62 -80
  66. package/lib/papyrus-private-chat-client.ts +7 -4
  67. package/lib/proposals-admin.ts +115 -0
  68. package/lib/proposals-client.ts +29 -0
  69. package/lib/prospectus-session.ts +2 -0
  70. package/lib/prospectus-sign-in-routes.ts +19 -2
  71. package/lib/prospectus-site-identity.ts +7 -0
  72. package/lib/reader-subject.ts +3 -2
  73. package/lib/relevance-decisions.ts +9 -0
  74. package/lib/review-client.ts +38 -1
  75. package/lib/review-drafts.ts +231 -0
  76. package/lib/review-fixture.ts +36 -2
  77. package/lib/review-requests.ts +66 -24
  78. package/lib/staff-groups.ts +23 -0
  79. package/lib/staging-gate.ts +2 -2
  80. package/package.json +16 -1
  81. package/routes.manifest.json +12 -1
  82. package/src/sync.mjs +11 -2
  83. package/src/with-papyrus.mjs +1 -1
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Who counts as newsroom staff. `admin` has every editor right: a site owner who is in `admin` but not `editor` can do
3
+ * everything an editor can. Every editor check in the browser and in the Lambdas reads this one list.
4
+ */
5
+ export const STAFF_GROUPS = ["editor", "admin"] as const;
6
+
7
+ /** True when any group is `editor` or `admin`. */
8
+ export function hasEditorRights(groups: Iterable<unknown> | null | undefined): boolean {
9
+ if (!groups) return false;
10
+ for (const group of groups) {
11
+ if (typeof group === "string" && (STAFF_GROUPS as readonly string[]).includes(group.trim().toLowerCase())) return true;
12
+ }
13
+ return false;
14
+ }
15
+
16
+ /**
17
+ * Cognito groups from a `cognito:groups` claim, which arrives as an array, a JSON array, a bracketed list
18
+ * (`[admin Google_123]`), or a comma or space separated string depending on who forwarded it.
19
+ */
20
+ export function claimGroups(value: unknown): string[] {
21
+ const raw = Array.isArray(value) ? value.map((entry) => String(entry)) : typeof value === "string" ? value.split(/[\s,]+/) : [];
22
+ return raw.map((entry) => entry.trim().replace(/^["'[\](){}]+|["'[\](){}]+$/g, "")).filter(Boolean);
23
+ }
@@ -1,10 +1,10 @@
1
1
  import type { NextRequest, NextResponse } from "next/server";
2
2
  import { fetchAuthSession } from "aws-amplify/auth/server";
3
3
  import { getAmplifyServerRuntime } from "./amplify-server-runtime";
4
+ import { hasEditorRights } from "./staff-groups";
4
5
 
5
6
  export type StagingAccess = "anonymous" | "forbidden" | "ok";
6
7
 
7
- const STAGING_ALLOWED_GROUPS = ["editor", "admin"];
8
8
 
9
9
  export function groupsFromIdTokenPayload(payload: Record<string, unknown> | undefined): string[] {
10
10
  const raw = payload?.["cognito:groups"];
@@ -15,7 +15,7 @@ export function groupsFromIdTokenPayload(payload: Record<string, unknown> | unde
15
15
 
16
16
  export function accessForGroups(groups: string[] | null): StagingAccess {
17
17
  if (groups === null) return "anonymous";
18
- return groups.some((group) => STAGING_ALLOWED_GROUPS.includes(group)) ? "ok" : "forbidden";
18
+ return hasEditorRights(groups) ? "ok" : "forbidden";
19
19
  }
20
20
 
21
21
  export async function getStagingAccess(request: NextRequest, response: NextResponse): Promise<StagingAccess> {
package/package.json CHANGED
@@ -106,6 +106,7 @@
106
106
  "./components/newsroom-client-shell": "./components/newsroom-client-shell.tsx",
107
107
  "./components/newsroom-curation-bootstrap": "./components/newsroom-curation-bootstrap.tsx",
108
108
  "./components/newsroom-curation-provider": "./components/newsroom-curation-provider.tsx",
109
+ "./components/newsroom-mobile-navigation": "./components/newsroom-mobile-navigation.tsx",
109
110
  "./components/newsroom-ops-overview": "./components/newsroom-ops-overview.tsx",
110
111
  "./components/newsroom-ops-shell": "./components/newsroom-ops-shell.tsx",
111
112
  "./components/newsroom-overview-skeleton": "./components/newsroom-overview-skeleton.tsx",
@@ -118,6 +119,7 @@
118
119
  "./components/newsroom-topics-view": "./components/newsroom-topics-view.tsx",
119
120
  "./components/notification-center": "./components/notification-center.tsx",
120
121
  "./components/papyrus-console-conversation": "./components/papyrus-console-conversation.tsx",
122
+ "./components/papyrus-console-frame": "./components/papyrus-console-frame.tsx",
121
123
  "./components/papyrus-console-shell": "./components/papyrus-console-shell.tsx",
122
124
  "./components/papyrus-private-chat-panel": "./components/papyrus-private-chat-panel.tsx",
123
125
  "./components/pictogram-figure": "./components/pictogram-figure.tsx",
@@ -125,6 +127,8 @@
125
127
  "./components/presentation-header": "./components/presentation-header.tsx",
126
128
  "./components/presentation-rhythm-hrule": "./components/presentation-rhythm-hrule.tsx",
127
129
  "./components/priming-proof-page": "./components/priming-proof-page.tsx",
130
+ "./components/proposals-panel": "./components/proposals-panel.tsx",
131
+ "./components/proposals-view": "./components/proposals-view.tsx",
128
132
  "./components/prospectus-account-chooser": "./components/prospectus-account-chooser.tsx",
129
133
  "./components/publication-cyclotron-panel": "./components/publication-cyclotron-panel.tsx",
130
134
  "./components/reader-auth-control": "./components/reader-auth-control.tsx",
@@ -139,6 +143,7 @@
139
143
  "./components/reference-live-agreement": "./components/reference-live-agreement.tsx",
140
144
  "./components/reference-priming": "./components/reference-priming.tsx",
141
145
  "./components/reference-relevance-review": "./components/reference-relevance-review.tsx",
146
+ "./components/reference-review-card": "./components/reference-review-card.tsx",
142
147
  "./components/reference-section-suggestion": "./components/reference-section-suggestion.tsx",
143
148
  "./components/reference-source-preview": "./components/reference-source-preview.tsx",
144
149
  "./components/settings-page": "./components/settings-page.tsx",
@@ -167,6 +172,7 @@
167
172
  "./components/ui/tooltip": "./components/ui/tooltip.tsx",
168
173
  "./components/use-blog-header-obstacles": "./components/use-blog-header-obstacles.ts",
169
174
  "./components/use-brand-fonts-ready": "./components/use-brand-fonts-ready.ts",
175
+ "./components/use-console-visibility": "./components/use-console-visibility.ts",
170
176
  "./components/use-editorial-checks": "./components/use-editorial-checks.ts",
171
177
  "./components/use-near-viewport": "./components/use-near-viewport.ts",
172
178
  "./components/use-paged-content-item-versions": "./components/use-paged-content-item-versions.ts",
@@ -194,6 +200,7 @@
194
200
  "./lib/category-dashboard": "./lib/category-dashboard.ts",
195
201
  "./lib/category-repository": "./lib/category-repository.ts",
196
202
  "./lib/chrome-text": "./lib/chrome-text.ts",
203
+ "./lib/cli-login-discovery": "./lib/cli-login-discovery.ts",
197
204
  "./lib/console-chat-client": "./lib/console-chat-client.ts",
198
205
  "./lib/console-web-context": "./lib/console-web-context.ts",
199
206
  "./lib/content-actions-client": "./lib/content-actions-client.ts",
@@ -245,6 +252,7 @@
245
252
  "./lib/monitoring-client": "./lib/monitoring-client.ts",
246
253
  "./lib/monitoring-overview-fixture": "./lib/monitoring-overview-fixture.ts",
247
254
  "./lib/monitoring-overview": "./lib/monitoring-overview.ts",
255
+ "./lib/monitoring-paging": "./lib/monitoring-paging.ts",
248
256
  "./lib/news-desk-session": "./lib/news-desk-session.ts",
249
257
  "./lib/newsletter-api": "./lib/newsletter-api.ts",
250
258
  "./lib/newsletter-client": "./lib/newsletter-client.ts",
@@ -257,6 +265,8 @@
257
265
  "./lib/newsroom-board": "./lib/newsroom-board.ts",
258
266
  "./lib/newsroom-card-layout": "./lib/newsroom-card-layout.ts",
259
267
  "./lib/newsroom-category-drilldown": "./lib/newsroom-category-drilldown.ts",
268
+ "./lib/newsroom-chat-client": "./lib/newsroom-chat-client.ts",
269
+ "./lib/newsroom-chat-identity": "./lib/newsroom-chat-identity.ts",
260
270
  "./lib/newsroom-demo-articles": "./lib/newsroom-demo-articles.ts",
261
271
  "./lib/newsroom-demo-dashboard": "./lib/newsroom-demo-dashboard.ts",
262
272
  "./lib/newsroom-demo-profile": "./lib/newsroom-demo-profile.ts",
@@ -283,6 +293,8 @@
283
293
  "./lib/presentation-footer": "./lib/presentation-footer.ts",
284
294
  "./lib/pretext-layout": "./lib/pretext-layout.ts",
285
295
  "./lib/priming-proof-report": "./lib/priming-proof-report.ts",
296
+ "./lib/proposals-admin": "./lib/proposals-admin.ts",
297
+ "./lib/proposals-client": "./lib/proposals-client.ts",
286
298
  "./lib/prospectus-account-client": "./lib/prospectus-account-client.ts",
287
299
  "./lib/prospectus-publication-access": "./lib/prospectus-publication-access.ts",
288
300
  "./lib/prospectus-session": "./lib/prospectus-session.ts",
@@ -315,6 +327,7 @@
315
327
  "./lib/revalidate-prewarm": "./lib/revalidate-prewarm.ts",
316
328
  "./lib/revalidate-secret": "./lib/revalidate-secret.ts",
317
329
  "./lib/review-client": "./lib/review-client.ts",
330
+ "./lib/review-drafts": "./lib/review-drafts.ts",
318
331
  "./lib/review-fixture": "./lib/review-fixture.ts",
319
332
  "./lib/review-requests": "./lib/review-requests.ts",
320
333
  "./lib/robots-policy": "./lib/robots-policy.ts",
@@ -331,6 +344,7 @@
331
344
  "./lib/site-renderer": "./lib/site-renderer.ts",
332
345
  "./lib/site-section-suggestions": "./lib/site-section-suggestions.ts",
333
346
  "./lib/site-stack": "./lib/site-stack.ts",
347
+ "./lib/staff-groups": "./lib/staff-groups.ts",
334
348
  "./lib/staging-gate": "./lib/staging-gate.ts",
335
349
  "./lib/staging-gated-path": "./lib/staging-gated-path.ts",
336
350
  "./lib/staging-preview-object": "./lib/staging-preview-object.ts",
@@ -356,6 +370,7 @@
356
370
  "./renderers/pretext/rhythm-blog-presentation": "./renderers/pretext/rhythm-blog-presentation.tsx",
357
371
  "./renderers/pretext/rhythm-shell-style": "./renderers/pretext/rhythm-shell-style.ts",
358
372
  "./app/%5F_preview/[[...path]]/route": "./app/%5F_preview/[[...path]]/route.ts",
373
+ "./app/.well-known/papyrus-cli.json/route": "./app/.well-known/papyrus-cli.json/route.ts",
359
374
  "./app/[year]/[month]/[day]/[articleSlug]/page": "./app/[year]/[month]/[day]/[articleSlug]/page.tsx",
360
375
  "./app/[year]/[month]/[day]/page": "./app/[year]/[month]/[day]/page.tsx",
361
376
  "./app/[year]/[month]/[day]/page/[pageNumber]/page": "./app/[year]/[month]/[day]/page/[pageNumber]/page.tsx",
@@ -456,7 +471,7 @@
456
471
  "optional": true
457
472
  }
458
473
  },
459
- "version": "5.42.1",
474
+ "version": "5.43.0-next.10",
460
475
  "dependencies": {
461
476
  "@aws-amplify/adapter-nextjs": "^1.7.3",
462
477
  "@aws-crypto/sha256-js": "5.2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.42.1",
2
+ "version": "5.43.0-next.10",
3
3
  "routes": [
4
4
  {
5
5
  "file": "app/%5F_preview/[[...path]]/route.ts",
@@ -11,6 +11,17 @@
11
11
  "dynamic": "\"force-dynamic\""
12
12
  }
13
13
  },
14
+ {
15
+ "file": "app/.well-known/papyrus-cli.json/route.ts",
16
+ "hasDefault": false,
17
+ "exports": [
18
+ "GET"
19
+ ],
20
+ "config": {
21
+ "dynamic": "\"force-dynamic\"",
22
+ "runtime": "\"nodejs\""
23
+ }
24
+ },
14
25
  {
15
26
  "file": "app/[year]/[month]/[day]/[articleSlug]/page.tsx",
16
27
  "reader": true,
package/src/sync.mjs CHANGED
@@ -37,6 +37,15 @@ function shimFor(route) {
37
37
  return lines.join("\n") + "\n";
38
38
  }
39
39
 
40
+ /** Anchored .gitignore line for a literal path; escapes gitignore metacharacters (Next dynamic routes use [ ]). */
41
+ export function gitignoreEntry(rel) {
42
+ const escaped = rel
43
+ .replace(/[\\[\]*?]/g, "\\$&")
44
+ .replace(/^[#!]/, "\\$&")
45
+ .replace(/ +$/, (m) => m.replace(/ /g, "\\ "));
46
+ return "/" + escaped;
47
+ }
48
+
40
49
  export function middlewareShim(manifest) {
41
50
  const matcher = manifest.middleware.matcher ?? '["/((?!_next/static|_next/image|favicon.ico|icon).*)"]';
42
51
  return [
@@ -101,9 +110,9 @@ export function sync({ root = process.cwd(), log = console.log, manifest: manife
101
110
  // Keep generated shims out of git.
102
111
  const giFile = path.join(root, ".gitignore");
103
112
  const gi = fs.existsSync(giFile) ? fs.readFileSync(giFile, "utf8") : "";
104
- const block = [GITIGNORE_BEGIN, ...generated.map((g) => "/" + g), "/.papyrus/", GITIGNORE_END].join("\n");
113
+ const block = [GITIGNORE_BEGIN, ...generated.map(gitignoreEntry), "/.papyrus/", GITIGNORE_END].join("\n");
105
114
  const re = new RegExp(`${GITIGNORE_BEGIN.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s\\S]*?${GITIGNORE_END}`);
106
- fs.writeFileSync(giFile, re.test(gi) ? gi.replace(re, block) : `${gi}${gi.endsWith("\n") || !gi ? "" : "\n"}${block}\n`);
115
+ fs.writeFileSync(giFile, re.test(gi) ? gi.replace(re, () => block) : `${gi}${gi.endsWith("\n") || !gi ? "" : "\n"}${block}\n`);
107
116
 
108
117
  log(`papyrus-app sync: ${generated.length} shim(s) written, ${skipped.length} site-owned file(s) kept (${PKG}@${manifest.version})${readerBasePath ? `, reader mounted at ${readerBasePath}` : ""}`);
109
118
  for (const rel of skipped) log(` site-owned: ${rel}`);
@@ -50,7 +50,7 @@ export function staticGenerationSettings() {
50
50
  };
51
51
  }
52
52
 
53
- export const DEFAULT_TRANSPILE_PACKAGES = ["@anthusai/papyrus", "cyclotron", "chatticus"];
53
+ export const DEFAULT_TRANSPILE_PACKAGES = ["@anthusai/papyrus", "cyclotron", "chatticus", "lucide-react"];
54
54
 
55
55
  export function mergeTranspilePackages(existing = []) {
56
56
  return [...new Set([...existing, ...DEFAULT_TRANSPILE_PACKAGES])];