@forumone/throughline-publishing 0.0.1 → 0.2.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 (96) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +2 -42
  4. package/dist/checks/alt-text.d.ts +11 -0
  5. package/dist/checks/alt-text.d.ts.map +1 -0
  6. package/dist/checks/alt-text.js +53 -0
  7. package/dist/checks/alt-text.js.map +1 -0
  8. package/dist/checks/heading-hierarchy.d.ts +11 -0
  9. package/dist/checks/heading-hierarchy.d.ts.map +1 -0
  10. package/dist/checks/heading-hierarchy.js +32 -0
  11. package/dist/checks/heading-hierarchy.js.map +1 -0
  12. package/dist/checks/index.d.ts +6 -0
  13. package/dist/checks/index.d.ts.map +1 -0
  14. package/dist/checks/index.js +13 -0
  15. package/dist/checks/index.js.map +1 -0
  16. package/dist/checks/link-labels.d.ts +9 -0
  17. package/dist/checks/link-labels.d.ts.map +1 -0
  18. package/dist/checks/link-labels.js +44 -0
  19. package/dist/checks/link-labels.js.map +1 -0
  20. package/dist/hooks/block-status-writes.d.ts +12 -0
  21. package/dist/hooks/block-status-writes.d.ts.map +1 -0
  22. package/dist/hooks/block-status-writes.js +36 -0
  23. package/dist/hooks/block-status-writes.js.map +1 -0
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +2 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/options.d.ts +65 -0
  29. package/dist/options.d.ts.map +1 -0
  30. package/dist/options.js +57 -0
  31. package/dist/options.js.map +1 -0
  32. package/dist/pipeline/index.d.ts +15 -0
  33. package/dist/pipeline/index.d.ts.map +1 -0
  34. package/dist/pipeline/index.js +62 -0
  35. package/dist/pipeline/index.js.map +1 -0
  36. package/dist/pipeline/steps/accessibility.d.ts +9 -0
  37. package/dist/pipeline/steps/accessibility.d.ts.map +1 -0
  38. package/dist/pipeline/steps/accessibility.js +32 -0
  39. package/dist/pipeline/steps/accessibility.js.map +1 -0
  40. package/dist/pipeline/steps/approval.d.ts +11 -0
  41. package/dist/pipeline/steps/approval.d.ts.map +1 -0
  42. package/dist/pipeline/steps/approval.js +33 -0
  43. package/dist/pipeline/steps/approval.js.map +1 -0
  44. package/dist/pipeline/steps/composition.d.ts +14 -0
  45. package/dist/pipeline/steps/composition.d.ts.map +1 -0
  46. package/dist/pipeline/steps/composition.js +63 -0
  47. package/dist/pipeline/steps/composition.js.map +1 -0
  48. package/dist/pipeline/steps/embargo.d.ts +12 -0
  49. package/dist/pipeline/steps/embargo.d.ts.map +1 -0
  50. package/dist/pipeline/steps/embargo.js +41 -0
  51. package/dist/pipeline/steps/embargo.js.map +1 -0
  52. package/dist/pipeline/steps/execute.d.ts +12 -0
  53. package/dist/pipeline/steps/execute.d.ts.map +1 -0
  54. package/dist/pipeline/steps/execute.js +38 -0
  55. package/dist/pipeline/steps/execute.js.map +1 -0
  56. package/dist/pipeline/steps/exist.d.ts +9 -0
  57. package/dist/pipeline/steps/exist.d.ts.map +1 -0
  58. package/dist/pipeline/steps/exist.js +31 -0
  59. package/dist/pipeline/steps/exist.js.map +1 -0
  60. package/dist/pipeline/steps/required-fields.d.ts +9 -0
  61. package/dist/pipeline/steps/required-fields.d.ts.map +1 -0
  62. package/dist/pipeline/steps/required-fields.js +63 -0
  63. package/dist/pipeline/steps/required-fields.js.map +1 -0
  64. package/dist/pipeline/types.d.ts +45 -0
  65. package/dist/pipeline/types.d.ts.map +1 -0
  66. package/dist/pipeline/types.js +2 -0
  67. package/dist/pipeline/types.js.map +1 -0
  68. package/dist/plugin.d.ts +4 -0
  69. package/dist/plugin.d.ts.map +1 -0
  70. package/dist/plugin.js +87 -0
  71. package/dist/plugin.js.map +1 -0
  72. package/dist/tools/get-publish-status.d.ts +9 -0
  73. package/dist/tools/get-publish-status.d.ts.map +1 -0
  74. package/dist/tools/get-publish-status.js +55 -0
  75. package/dist/tools/get-publish-status.js.map +1 -0
  76. package/dist/tools/index.d.ts +6 -0
  77. package/dist/tools/index.d.ts.map +1 -0
  78. package/dist/tools/index.js +6 -0
  79. package/dist/tools/index.js.map +1 -0
  80. package/dist/tools/publish.d.ts +11 -0
  81. package/dist/tools/publish.d.ts.map +1 -0
  82. package/dist/tools/publish.js +71 -0
  83. package/dist/tools/publish.js.map +1 -0
  84. package/dist/tools/rollback.d.ts +11 -0
  85. package/dist/tools/rollback.d.ts.map +1 -0
  86. package/dist/tools/rollback.js +78 -0
  87. package/dist/tools/rollback.js.map +1 -0
  88. package/dist/tools/schedule-publish.d.ts +11 -0
  89. package/dist/tools/schedule-publish.d.ts.map +1 -0
  90. package/dist/tools/schedule-publish.js +94 -0
  91. package/dist/tools/schedule-publish.js.map +1 -0
  92. package/dist/tools/unpublish.d.ts +11 -0
  93. package/dist/tools/unpublish.d.ts.map +1 -0
  94. package/dist/tools/unpublish.js +61 -0
  95. package/dist/tools/unpublish.js.map +1 -0
  96. package/package.json +66 -7
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ import { withMeta } from '@forumone/throughline-core';
3
+ import { resolveCollection } from '../options.js';
4
+ import { runPreflightPipeline } from '../pipeline/index.js';
5
+ export function createGetPublishStatusTool(deps) {
6
+ const inputSchema = withMeta({
7
+ collection: z.string(),
8
+ id: z.string(),
9
+ });
10
+ return {
11
+ name: 'get_publish_status',
12
+ description: "Returns the current publishability of a document without actually publishing. Reports current status, whether unpublished changes exist, the last publish timestamp, and a preflight result indicating whether `publish` would currently succeed. Read-only; no audit record is written.",
13
+ inputSchema,
14
+ handler: async (input, ctx) => {
15
+ const collection = resolveCollection(deps.options, input.collection);
16
+ const document = (await deps.payload.findByID({
17
+ collection: collection.slug,
18
+ id: input.id,
19
+ draft: true,
20
+ }));
21
+ const preflight = await runPreflightPipeline({
22
+ payload: deps.payload,
23
+ inngest: deps.options.inngest,
24
+ options: deps.options,
25
+ collection,
26
+ document,
27
+ documentId: input.id,
28
+ actor: { user: ctx.user, apiKeyName: ctx.apiKeyName },
29
+ });
30
+ const updatedAt = document['updatedAt'];
31
+ const publishedAt = document[collection.publishedAtField];
32
+ const hasUnpublishedChanges = typeof updatedAt === 'string' &&
33
+ typeof publishedAt === 'string' &&
34
+ Date.parse(updatedAt) > Date.parse(publishedAt);
35
+ return {
36
+ currentStatus: document['_status'] ?? 'draft',
37
+ hasUnpublishedChanges,
38
+ lastPublished: typeof publishedAt === 'string' ? publishedAt : null,
39
+ wouldPublish: {
40
+ canPublish: preflight.success,
41
+ ...(preflight.success
42
+ ? {}
43
+ : {
44
+ blockedAt: preflight.failedAt,
45
+ code: preflight.code,
46
+ reason: preflight.reason,
47
+ suggestion: preflight.suggestion,
48
+ issues: preflight.issues ?? [],
49
+ }),
50
+ },
51
+ };
52
+ },
53
+ };
54
+ }
55
+ //# sourceMappingURL=get-publish-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-publish-status.js","sourceRoot":"","sources":["../../src/tools/get-publish-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAErD,OAAO,EAAgC,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAO3D,MAAM,UAAU,0BAA0B,CAAC,IAA8B;IACvE,MAAM,WAAW,GAAG,QAAQ,CAAC;QAC3B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;QACtB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;KACf,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EACT,0RAA0R;QAC5R,WAAW;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;YACpE,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAC5C,UAAU,EAAE,UAAU,CAAC,IAAI;gBAC3B,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,KAAK,EAAE,IAAI;aACZ,CAAC,CAA4B,CAAA;YAE9B,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC;gBAC3C,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;gBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,UAAU;gBACV,QAAQ;gBACR,UAAU,EAAE,KAAK,CAAC,EAAE;gBACpB,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE;aACtD,CAAC,CAAA;YAEF,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;YACvC,MAAM,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;YACzD,MAAM,qBAAqB,GACzB,OAAO,SAAS,KAAK,QAAQ;gBAC7B,OAAO,WAAW,KAAK,QAAQ;gBAC/B,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAEjD,OAAO;gBACL,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO;gBAC7C,qBAAqB;gBACrB,aAAa,EAAE,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;gBACnE,YAAY,EAAE;oBACZ,UAAU,EAAE,SAAS,CAAC,OAAO;oBAC7B,GAAG,CAAC,SAAS,CAAC,OAAO;wBACnB,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC;4BACE,SAAS,EAAE,SAAS,CAAC,QAAQ;4BAC7B,IAAI,EAAE,SAAS,CAAC,IAAI;4BACpB,MAAM,EAAE,SAAS,CAAC,MAAM;4BACxB,UAAU,EAAE,SAAS,CAAC,UAAU;4BAChC,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,EAAE;yBAC/B,CAAC;iBACP;aACF,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { createPublishTool, type PublishToolDeps } from './publish.js';
2
+ export { createUnpublishTool, type UnpublishToolDeps } from './unpublish.js';
3
+ export { createSchedulePublishTool, type SchedulePublishToolDeps, } from './schedule-publish.js';
4
+ export { createGetPublishStatusTool, type GetPublishStatusToolDeps, } from './get-publish-status.js';
5
+ export { createRollbackTool, type RollbackToolDeps } from './rollback.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AACtE,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,OAAO,EACL,yBAAyB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,0BAA0B,EAC1B,KAAK,wBAAwB,GAC9B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA"}
@@ -0,0 +1,6 @@
1
+ export { createPublishTool } from './publish.js';
2
+ export { createUnpublishTool } from './unpublish.js';
3
+ export { createSchedulePublishTool, } from './schedule-publish.js';
4
+ export { createGetPublishStatusTool, } from './get-publish-status.js';
5
+ export { createRollbackTool } from './rollback.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAwB,MAAM,cAAc,CAAA;AACtE,OAAO,EAAE,mBAAmB,EAA0B,MAAM,gBAAgB,CAAA;AAC5E,OAAO,EACL,yBAAyB,GAE1B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,0BAA0B,GAE3B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,kBAAkB,EAAyB,MAAM,eAAe,CAAA"}
@@ -0,0 +1,11 @@
1
+ import type { Payload } from 'payload';
2
+ import { type AuditWriter } from '@forumone/throughline-core';
3
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
4
+ import { type PublishingPluginOptions } from '../options.js';
5
+ export interface PublishToolDeps {
6
+ payload: Payload;
7
+ options: PublishingPluginOptions;
8
+ auditWriter: AuditWriter;
9
+ }
10
+ export declare function createPublishTool(deps: PublishToolDeps): McpToolDefinition;
11
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/tools/publish.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,4BAA4B,CAAA;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAC9E,OAAO,EAAE,KAAK,uBAAuB,EAAqB,MAAM,eAAe,CAAA;AAG/E,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,uBAAuB,CAAA;IAChC,WAAW,EAAE,WAAW,CAAA;CACzB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CAkE1E"}
@@ -0,0 +1,71 @@
1
+ import { z } from 'zod';
2
+ import { withMeta } from '@forumone/throughline-core';
3
+ import { resolveCollection } from '../options.js';
4
+ import { runPublishPipeline } from '../pipeline/index.js';
5
+ export function createPublishTool(deps) {
6
+ const inputSchema = withMeta({
7
+ collection: z.string().describe('The collection slug (e.g. "pages")'),
8
+ id: z.string().describe('The document ID'),
9
+ });
10
+ return {
11
+ name: 'publish',
12
+ description: "Publishes a draft document. Runs the full publish pipeline: composition, accessibility, required-field, embargo, and approval checks. Returns success with the publish timestamp, or a specific failedAt step with reason / suggestion when something blocks the publish.",
13
+ inputSchema,
14
+ handler: async (input, ctx) => {
15
+ const collection = resolveCollection(deps.options, input.collection);
16
+ const document = (await deps.payload.findByID({
17
+ collection: collection.slug,
18
+ id: input.id,
19
+ draft: true,
20
+ }));
21
+ const result = await runPublishPipeline({
22
+ payload: deps.payload,
23
+ inngest: deps.options.inngest,
24
+ options: deps.options,
25
+ collection,
26
+ document,
27
+ documentId: input.id,
28
+ actor: { user: ctx.user, apiKeyName: ctx.apiKeyName },
29
+ ...(input._meta ? { meta: input._meta } : {}),
30
+ });
31
+ await deps.auditWriter({
32
+ actor: {
33
+ type: ctx.user ? 'user' : 'system',
34
+ userId: ctx.user?.id,
35
+ userName: ctx.user?.name,
36
+ apiKeyName: ctx.apiKeyName,
37
+ },
38
+ action: 'publishing.publish',
39
+ mcpServer: 'publishing',
40
+ mcpTool: 'publish',
41
+ targetCollection: input.collection,
42
+ targetId: input.id,
43
+ targetTitle: stringField(document, 'title') ?? input.id,
44
+ prompt: input._meta?.userPrompt,
45
+ reasoning: input._meta?.reasoning,
46
+ changesSummary: input._meta?.changesSummary,
47
+ success: result.success,
48
+ errorMessage: result.success ? undefined : result.reason,
49
+ });
50
+ if (result.success) {
51
+ return {
52
+ published: true,
53
+ publishedAt: result.publishedAt,
54
+ };
55
+ }
56
+ return {
57
+ published: false,
58
+ failedAt: result.failedAt,
59
+ reason: result.reason,
60
+ code: result.code,
61
+ issues: result.issues,
62
+ suggestion: result.suggestion,
63
+ };
64
+ },
65
+ };
66
+ }
67
+ function stringField(doc, name) {
68
+ const value = doc[name];
69
+ return typeof value === 'string' ? value : undefined;
70
+ }
71
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/tools/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAoB,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAEvE,OAAO,EAAgC,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAQzD,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,MAAM,WAAW,GAAG,QAAQ,CAAC;QAC3B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;QACrE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;KAC3C,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,SAAS;QACf,WAAW,EACT,2QAA2Q;QAC7Q,WAAW;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;YACpE,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAC5C,UAAU,EAAE,UAAU,CAAC,IAAI;gBAC3B,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,KAAK,EAAE,IAAI;aACZ,CAAC,CAA4B,CAAA;YAE9B,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;gBACtC,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;gBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,UAAU;gBACV,QAAQ;gBACR,UAAU,EAAE,KAAK,CAAC,EAAE;gBACpB,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE;gBACrD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9C,CAAC,CAAA;YAEF,MAAM,IAAI,CAAC,WAAW,CAAC;gBACrB,KAAK,EAAE;oBACL,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;oBAClC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE;oBACpB,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI;oBACxB,UAAU,EAAE,GAAG,CAAC,UAAU;iBAC3B;gBACD,MAAM,EAAE,oBAAoB;gBAC5B,SAAS,EAAE,YAAY;gBACvB,OAAO,EAAE,SAAS;gBAClB,gBAAgB,EAAE,KAAK,CAAC,UAAU;gBAClC,QAAQ,EAAE,KAAK,CAAC,EAAE;gBAClB,WAAW,EAAE,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE;gBACvD,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,UAAU;gBAC/B,SAAS,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS;gBACjC,cAAc,EAAE,KAAK,CAAC,KAAK,EAAE,cAAc;gBAC3C,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM;aACzD,CAAC,CAAA;YAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO;oBACL,SAAS,EAAE,IAAI;oBACf,WAAW,EAAE,MAAM,CAAC,WAAW;iBAChC,CAAA;YACH,CAAC;YACD,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAA4B,EAAE,IAAY;IAC7D,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;IACvB,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AACtD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Payload } from 'payload';
2
+ import { type AuditWriter } from '@forumone/throughline-core';
3
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
4
+ import { type PublishingPluginOptions } from '../options.js';
5
+ export interface RollbackToolDeps {
6
+ payload: Payload;
7
+ options: PublishingPluginOptions;
8
+ auditWriter: AuditWriter;
9
+ }
10
+ export declare function createRollbackTool(deps: RollbackToolDeps): McpToolDefinition;
11
+ //# sourceMappingURL=rollback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/tools/rollback.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,4BAA4B,CAAA;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAC9E,OAAO,EAAE,KAAK,uBAAuB,EAAqB,MAAM,eAAe,CAAA;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,uBAAuB,CAAA;IAChC,WAAW,EAAE,WAAW,CAAA;CACzB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,iBAAiB,CAiF5E"}
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod';
2
+ import { withMeta } from '@forumone/throughline-core';
3
+ import { resolveCollection } from '../options.js';
4
+ export function createRollbackTool(deps) {
5
+ const inputSchema = withMeta({
6
+ collection: z.string(),
7
+ id: z.string().describe('The document ID'),
8
+ versionId: z.string().describe('The version ID to roll the document back to'),
9
+ });
10
+ return {
11
+ name: 'rollback',
12
+ description: "Rolls a document back to a prior version from Payload's version history. The restored content lands as a fresh draft; call `publish` afterwards if you want it live again. Audits the rollback under publishing.rollback.",
13
+ inputSchema,
14
+ handler: async (input, ctx) => {
15
+ const collection = resolveCollection(deps.options, input.collection);
16
+ // Confirm the version belongs to this document before restoring.
17
+ const versions = await deps.payload.findVersions({
18
+ collection: collection.slug,
19
+ where: {
20
+ and: [{ id: { equals: input.versionId } }, { parent: { equals: input.id } }],
21
+ },
22
+ limit: 1,
23
+ });
24
+ if (!versions.docs[0]) {
25
+ await deps.auditWriter({
26
+ actor: { type: ctx.user ? 'user' : 'system', userId: ctx.user?.id, apiKeyName: ctx.apiKeyName },
27
+ action: 'publishing.rollback',
28
+ mcpServer: 'publishing',
29
+ mcpTool: 'rollback',
30
+ targetCollection: input.collection,
31
+ targetId: input.id,
32
+ success: false,
33
+ errorMessage: 'Version not found for the supplied document',
34
+ });
35
+ return {
36
+ restored: false,
37
+ reason: `Version "${input.versionId}" not found for document "${input.id}" in "${input.collection}"`,
38
+ };
39
+ }
40
+ await deps.payload.restoreVersion({
41
+ collection: collection.slug,
42
+ id: input.versionId,
43
+ });
44
+ await deps.options.inngest.send({
45
+ name: 'content/page.rolled_back',
46
+ data: {
47
+ collection: collection.slug,
48
+ id: input.id,
49
+ rolledBackBy: ctx.user?.id ?? 'system',
50
+ toVersionId: input.versionId,
51
+ },
52
+ });
53
+ await deps.auditWriter({
54
+ actor: {
55
+ type: ctx.user ? 'user' : 'system',
56
+ userId: ctx.user?.id,
57
+ userName: ctx.user?.name,
58
+ apiKeyName: ctx.apiKeyName,
59
+ },
60
+ action: 'publishing.rollback',
61
+ mcpServer: 'publishing',
62
+ mcpTool: 'rollback',
63
+ targetCollection: input.collection,
64
+ targetId: input.id,
65
+ prompt: input._meta?.userPrompt,
66
+ reasoning: input._meta?.reasoning,
67
+ changesSummary: `Rolled back to version ${input.versionId}`,
68
+ success: true,
69
+ });
70
+ return {
71
+ restored: true,
72
+ toVersionId: input.versionId,
73
+ note: 'The restored content is a draft. Call `publish` to make it live.',
74
+ };
75
+ },
76
+ };
77
+ }
78
+ //# sourceMappingURL=rollback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollback.js","sourceRoot":"","sources":["../../src/tools/rollback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Payload } from 'payload';
2
+ import { type AuditWriter } from '@forumone/throughline-core';
3
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
4
+ import { type PublishingPluginOptions } from '../options.js';
5
+ export interface SchedulePublishToolDeps {
6
+ payload: Payload;
7
+ options: PublishingPluginOptions;
8
+ auditWriter: AuditWriter;
9
+ }
10
+ export declare function createSchedulePublishTool(deps: SchedulePublishToolDeps): McpToolDefinition;
11
+ //# sourceMappingURL=schedule-publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-publish.d.ts","sourceRoot":"","sources":["../../src/tools/schedule-publish.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,4BAA4B,CAAA;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAC9E,OAAO,EAAE,KAAK,uBAAuB,EAAqB,MAAM,eAAe,CAAA;AAG/E,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,uBAAuB,CAAA;IAChC,WAAW,EAAE,WAAW,CAAA;CACzB;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,uBAAuB,GAAG,iBAAiB,CAiG1F"}
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod';
2
+ import { withMeta } from '@forumone/throughline-core';
3
+ import { resolveCollection } from '../options.js';
4
+ import { runPreflightPipeline } from '../pipeline/index.js';
5
+ export function createSchedulePublishTool(deps) {
6
+ const inputSchema = withMeta({
7
+ collection: z.string(),
8
+ id: z.string(),
9
+ publishAt: z
10
+ .string()
11
+ .datetime()
12
+ .describe('ISO 8601 timestamp at which the document should be published'),
13
+ });
14
+ return {
15
+ name: 'schedule_publish',
16
+ description: "Schedules a future publish. Validates the document would currently pass the preflight pipeline (composition, accessibility, required fields, embargo, approval), then stores `scheduledPublishAt` on the document. The framework's workflow runner picks up the schedule and executes the full publish pipeline at that time.",
17
+ inputSchema,
18
+ handler: async (input, ctx) => {
19
+ const collection = resolveCollection(deps.options, input.collection);
20
+ const publishAtMs = Date.parse(input.publishAt);
21
+ if (publishAtMs <= Date.now()) {
22
+ return {
23
+ scheduled: false,
24
+ reason: 'publishAt must be in the future',
25
+ };
26
+ }
27
+ const document = (await deps.payload.findByID({
28
+ collection: collection.slug,
29
+ id: input.id,
30
+ draft: true,
31
+ }));
32
+ const preflight = await runPreflightPipeline({
33
+ payload: deps.payload,
34
+ inngest: deps.options.inngest,
35
+ options: deps.options,
36
+ collection,
37
+ document,
38
+ documentId: input.id,
39
+ actor: { user: ctx.user, apiKeyName: ctx.apiKeyName },
40
+ ...(input._meta ? { meta: input._meta } : {}),
41
+ });
42
+ if (!preflight.success) {
43
+ await deps.auditWriter({
44
+ actor: { type: ctx.user ? 'user' : 'system', userId: ctx.user?.id, apiKeyName: ctx.apiKeyName },
45
+ action: 'publishing.schedule',
46
+ mcpServer: 'publishing',
47
+ mcpTool: 'schedule_publish',
48
+ targetCollection: input.collection,
49
+ targetId: input.id,
50
+ prompt: input._meta?.userPrompt,
51
+ success: false,
52
+ errorMessage: preflight.reason,
53
+ });
54
+ return {
55
+ scheduled: false,
56
+ failedAt: preflight.failedAt,
57
+ reason: preflight.reason,
58
+ code: preflight.code,
59
+ issues: preflight.issues,
60
+ suggestion: preflight.suggestion,
61
+ };
62
+ }
63
+ await deps.payload.update({
64
+ collection: collection.slug,
65
+ id: input.id,
66
+ data: { [collection.scheduledPublishField]: input.publishAt },
67
+ context: { bypassPublishingServer: false },
68
+ });
69
+ await deps.options.inngest.send({
70
+ name: 'content/page.scheduled',
71
+ data: {
72
+ collection: collection.slug,
73
+ id: input.id,
74
+ scheduledFor: input.publishAt,
75
+ },
76
+ });
77
+ await deps.auditWriter({
78
+ actor: { type: ctx.user ? 'user' : 'system', userId: ctx.user?.id, apiKeyName: ctx.apiKeyName },
79
+ action: 'publishing.schedule',
80
+ mcpServer: 'publishing',
81
+ mcpTool: 'schedule_publish',
82
+ targetCollection: input.collection,
83
+ targetId: input.id,
84
+ targetTitle: typeof document['title'] === 'string' ? document['title'] : input.id,
85
+ prompt: input._meta?.userPrompt,
86
+ reasoning: input._meta?.reasoning,
87
+ changesSummary: `Scheduled publish for ${input.publishAt}`,
88
+ success: true,
89
+ });
90
+ return { scheduled: true, scheduledFor: input.publishAt };
91
+ },
92
+ };
93
+ }
94
+ //# sourceMappingURL=schedule-publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-publish.js","sourceRoot":"","sources":["../../src/tools/schedule-publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Payload } from 'payload';
2
+ import { type AuditWriter } from '@forumone/throughline-core';
3
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
4
+ import { type PublishingPluginOptions } from '../options.js';
5
+ export interface UnpublishToolDeps {
6
+ payload: Payload;
7
+ options: PublishingPluginOptions;
8
+ auditWriter: AuditWriter;
9
+ }
10
+ export declare function createUnpublishTool(deps: UnpublishToolDeps): McpToolDefinition;
11
+ //# sourceMappingURL=unpublish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unpublish.d.ts","sourceRoot":"","sources":["../../src/tools/unpublish.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,4BAA4B,CAAA;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAC9E,OAAO,EAAE,KAAK,uBAAuB,EAAqB,MAAM,eAAe,CAAA;AAE/E,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,uBAAuB,CAAA;IAChC,WAAW,EAAE,WAAW,CAAA;CACzB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,iBAAiB,CA+D9E"}
@@ -0,0 +1,61 @@
1
+ import { z } from 'zod';
2
+ import { withMeta } from '@forumone/throughline-core';
3
+ import { resolveCollection } from '../options.js';
4
+ export function createUnpublishTool(deps) {
5
+ const inputSchema = withMeta({
6
+ collection: z.string(),
7
+ id: z.string(),
8
+ });
9
+ return {
10
+ name: 'unpublish',
11
+ description: 'Unpublishes a published document by reverting it to draft. Use when content needs to be removed from the public site without deleting it. Fires content/page.unpublished so revalidation and integrations can react.',
12
+ inputSchema,
13
+ handler: async (input, ctx) => {
14
+ const collection = resolveCollection(deps.options, input.collection);
15
+ const document = (await deps.payload.findByID({
16
+ collection: collection.slug,
17
+ id: input.id,
18
+ draft: true,
19
+ }));
20
+ if (document['_status'] !== 'published') {
21
+ return { unpublished: false, reason: 'Document is not currently published' };
22
+ }
23
+ await deps.payload.update({
24
+ collection: collection.slug,
25
+ id: input.id,
26
+ data: { _status: 'draft' },
27
+ context: { bypassPublishingServer: true },
28
+ });
29
+ const slug = document[collection.slugField];
30
+ await deps.options.inngest.send({
31
+ name: 'content/page.unpublished',
32
+ data: {
33
+ collection: collection.slug,
34
+ id: input.id,
35
+ slug: typeof slug === 'string' ? slug : input.id,
36
+ unpublishedBy: ctx.user?.id ?? 'system',
37
+ },
38
+ });
39
+ await deps.auditWriter({
40
+ actor: {
41
+ type: ctx.user ? 'user' : 'system',
42
+ userId: ctx.user?.id,
43
+ userName: ctx.user?.name,
44
+ apiKeyName: ctx.apiKeyName,
45
+ },
46
+ action: 'publishing.unpublish',
47
+ mcpServer: 'publishing',
48
+ mcpTool: 'unpublish',
49
+ targetCollection: input.collection,
50
+ targetId: input.id,
51
+ targetTitle: typeof document['title'] === 'string' ? document['title'] : input.id,
52
+ prompt: input._meta?.userPrompt,
53
+ reasoning: input._meta?.reasoning,
54
+ changesSummary: input._meta?.changesSummary,
55
+ success: true,
56
+ });
57
+ return { unpublished: true };
58
+ },
59
+ };
60
+ }
61
+ //# sourceMappingURL=unpublish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unpublish.js","sourceRoot":"","sources":["../../src/tools/unpublish.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,69 @@
1
1
  {
2
2
  "name": "@forumone/throughline-publishing",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @forumone/throughline-publishing",
3
+ "version": "0.2.0",
4
+ "description": "Policy-gated publishing server for Throughline. Wraps Payload's update operation with composition, accessibility, required-field, embargo, and approval gating.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./checks": {
14
+ "types": "./dist/checks/index.d.ts",
15
+ "default": "./dist/checks/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "CHANGELOG.md"
22
+ ],
5
23
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
10
- }
24
+ "throughline",
25
+ "payload",
26
+ "mcp",
27
+ "publishing"
28
+ ],
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/forumone/throughline.git",
33
+ "directory": "packages/publishing"
34
+ },
35
+ "homepage": "https://github.com/forumone/throughline/tree/main/packages/publishing#readme",
36
+ "bugs": {
37
+ "url": "https://github.com/forumone/throughline/issues"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "peerDependencies": {
43
+ "payload": "^3.0.0",
44
+ "inngest": "^4.0.0"
45
+ },
46
+ "dependencies": {
47
+ "zod": "^3.23.0",
48
+ "@forumone/throughline-core": "0.2.0",
49
+ "@forumone/throughline-plugin-contract": "0.0.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^20.17.0",
53
+ "eslint": "^9.15.0",
54
+ "inngest": "^4.2.0",
55
+ "payload": "^3.83.0",
56
+ "typescript": "^5.6.0",
57
+ "vitest": "^2.1.0",
58
+ "@forumone/throughline-eslint-config": "0.0.0",
59
+ "@forumone/throughline-tsconfig": "0.0.0"
60
+ },
61
+ "scripts": {
62
+ "build": "tsc -b",
63
+ "dev": "tsc -b -w",
64
+ "clean": "rm -rf dist .turbo *.tsbuildinfo",
65
+ "typecheck": "tsc --noEmit",
66
+ "lint": "eslint src",
67
+ "test": "vitest run"
68
+ }
69
+ }