@tappify/extension-sdk 2.1.0-beta.2 → 2.1.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 (137) hide show
  1. package/README.md +18 -54
  2. package/dist/{chunk-6HETNZJY.cjs → chunk-2DBSVKAU.cjs} +1 -1
  3. package/dist/{chunk-6HETNZJY.cjs.map → chunk-2DBSVKAU.cjs.map} +1 -1
  4. package/dist/{chunk-O357OJXL.cjs → chunk-3YWVYA42.cjs} +18 -14
  5. package/dist/chunk-3YWVYA42.cjs.map +1 -0
  6. package/dist/{chunk-GAUZYBXE.cjs → chunk-5AAPD5WV.cjs} +11 -11
  7. package/dist/chunk-5AAPD5WV.cjs.map +1 -0
  8. package/dist/{chunk-SGEYDV3K.mjs → chunk-BDCX6LRQ.mjs} +3 -3
  9. package/dist/chunk-BDCX6LRQ.mjs.map +1 -0
  10. package/dist/{chunk-KZ5NGFUP.mjs → chunk-C3YNVHBP.mjs} +7 -20
  11. package/dist/chunk-C3YNVHBP.mjs.map +1 -0
  12. package/dist/{chunk-QXD7WVKK.mjs → chunk-CSTYBKZC.mjs} +1 -1
  13. package/dist/chunk-CSTYBKZC.mjs.map +1 -0
  14. package/dist/{chunk-SWG7CNTZ.mjs → chunk-CTSZ5D7S.mjs} +5 -9
  15. package/dist/chunk-CTSZ5D7S.mjs.map +1 -0
  16. package/dist/chunk-EW54H7CR.cjs +722 -0
  17. package/dist/chunk-EW54H7CR.cjs.map +1 -0
  18. package/dist/chunk-EX3NFXDK.mjs +722 -0
  19. package/dist/chunk-EX3NFXDK.mjs.map +1 -0
  20. package/dist/{chunk-A74HCO6T.cjs → chunk-G7XZSN2Q.cjs} +18 -31
  21. package/dist/chunk-G7XZSN2Q.cjs.map +1 -0
  22. package/dist/{chunk-RBIQT75L.mjs → chunk-GG3IX52W.mjs} +2 -2
  23. package/dist/{chunk-SLGOHIBL.mjs → chunk-IGK2AP6J.mjs} +17 -13
  24. package/dist/chunk-IGK2AP6J.mjs.map +1 -0
  25. package/dist/{chunk-VV7ELNRW.cjs → chunk-JMUK3K47.cjs} +3 -3
  26. package/dist/{chunk-VV7ELNRW.cjs.map → chunk-JMUK3K47.cjs.map} +1 -1
  27. package/dist/{chunk-SGCYEEXD.mjs → chunk-MNDVYPEP.mjs} +2 -9
  28. package/dist/chunk-MNDVYPEP.mjs.map +1 -0
  29. package/dist/{chunk-BPCGXXMD.cjs → chunk-NFUPPCX4.cjs} +18 -22
  30. package/dist/chunk-NFUPPCX4.cjs.map +1 -0
  31. package/dist/{chunk-PRCZMOLD.cjs → chunk-OPPYEA7F.cjs} +3 -3
  32. package/dist/{chunk-PRCZMOLD.cjs.map → chunk-OPPYEA7F.cjs.map} +1 -1
  33. package/dist/{chunk-7YKH4LZN.cjs → chunk-PYJMJF44.cjs} +2 -9
  34. package/dist/chunk-PYJMJF44.cjs.map +1 -0
  35. package/dist/{chunk-QA5AL3VZ.mjs → chunk-QHM7XNRK.mjs} +2 -2
  36. package/dist/{chunk-QA5AL3VZ.mjs.map → chunk-QHM7XNRK.mjs.map} +1 -1
  37. package/dist/codegen.cjs.map +1 -1
  38. package/dist/codegen.d.cts +7 -43
  39. package/dist/codegen.d.ts +7 -43
  40. package/dist/codegen.mjs.map +1 -1
  41. package/dist/{constants-Bh759FUI.d.cts → constants-DJ_KgZpN.d.cts} +8 -44
  42. package/dist/{constants-Bh759FUI.d.ts → constants-DJ_KgZpN.d.ts} +8 -44
  43. package/dist/{context-mr8R5CNt.d.ts → context-Dt6xh_5t.d.cts} +4 -5
  44. package/dist/{context-DI0EJCRD.d.cts → context-Ml7k_V14.d.ts} +4 -5
  45. package/dist/{errors-Cqh0wrqt.d.ts → errors-COsBh7kd.d.cts} +2 -3
  46. package/dist/{errors-Cqh0wrqt.d.cts → errors-COsBh7kd.d.ts} +2 -3
  47. package/dist/handler-CZIlZ5vu.d.ts +227 -0
  48. package/dist/handler-kU9Jf36K.d.cts +227 -0
  49. package/dist/host.cjs +4 -4
  50. package/dist/host.d.cts +4 -4
  51. package/dist/host.d.ts +4 -4
  52. package/dist/host.mjs +3 -3
  53. package/dist/index.cjs +34 -5
  54. package/dist/index.cjs.map +1 -1
  55. package/dist/index.d.cts +627 -69
  56. package/dist/index.d.ts +627 -69
  57. package/dist/index.mjs +33 -4
  58. package/dist/manifest.cjs +24 -136
  59. package/dist/manifest.cjs.map +1 -1
  60. package/dist/manifest.d.cts +12 -97
  61. package/dist/manifest.d.ts +12 -97
  62. package/dist/manifest.mjs +10 -122
  63. package/dist/manifest.mjs.map +1 -1
  64. package/dist/server.cjs +66 -14
  65. package/dist/server.cjs.map +1 -1
  66. package/dist/server.d.cts +6 -6
  67. package/dist/server.d.ts +6 -6
  68. package/dist/server.mjs +61 -9
  69. package/dist/server.mjs.map +1 -1
  70. package/dist/styles.css +367 -0
  71. package/dist/testing/index.cjs +13 -72
  72. package/dist/testing/index.cjs.map +1 -1
  73. package/dist/testing/index.d.cts +10 -29
  74. package/dist/testing/index.d.ts +10 -29
  75. package/dist/testing/index.mjs +13 -72
  76. package/dist/testing/index.mjs.map +1 -1
  77. package/dist/testing/jest.cjs +5 -5
  78. package/dist/testing/jest.mjs +2 -2
  79. package/dist/testing/vitest.cjs +5 -5
  80. package/dist/testing/vitest.cjs.map +1 -1
  81. package/dist/testing/vitest.d.cts +0 -10
  82. package/dist/testing/vitest.d.ts +0 -10
  83. package/dist/testing/vitest.mjs +2 -2
  84. package/dist/testing/vitest.mjs.map +1 -1
  85. package/dist/{types-uGHrRaOj.d.ts → types-DDAGLpov.d.ts} +3 -4
  86. package/dist/{types-BdDaLnqs.d.cts → types-DrpQSv_2.d.cts} +3 -4
  87. package/dist/vite-preview.cjs +125 -294
  88. package/dist/vite-preview.cjs.map +1 -1
  89. package/dist/vite-preview.d.cts +24 -6
  90. package/dist/vite-preview.d.ts +24 -6
  91. package/dist/vite-preview.mjs +118 -287
  92. package/dist/vite-preview.mjs.map +1 -1
  93. package/dist/vite.cjs +24 -137
  94. package/dist/vite.cjs.map +1 -1
  95. package/dist/vite.d.cts +7 -43
  96. package/dist/vite.d.ts +7 -43
  97. package/dist/vite.mjs +18 -131
  98. package/dist/vite.mjs.map +1 -1
  99. package/package.json +2 -12
  100. package/schema/extension-v2.json +121 -440
  101. package/dist/chunk-2CY5HVY7.mjs +0 -59
  102. package/dist/chunk-2CY5HVY7.mjs.map +0 -1
  103. package/dist/chunk-7YKH4LZN.cjs.map +0 -1
  104. package/dist/chunk-A74HCO6T.cjs.map +0 -1
  105. package/dist/chunk-BPCGXXMD.cjs.map +0 -1
  106. package/dist/chunk-EB5XWQAU.cjs +0 -132
  107. package/dist/chunk-EB5XWQAU.cjs.map +0 -1
  108. package/dist/chunk-GAUZYBXE.cjs.map +0 -1
  109. package/dist/chunk-KZ5NGFUP.mjs.map +0 -1
  110. package/dist/chunk-O357OJXL.cjs.map +0 -1
  111. package/dist/chunk-ONJMPO3P.cjs +0 -59
  112. package/dist/chunk-ONJMPO3P.cjs.map +0 -1
  113. package/dist/chunk-QJMZRV7A.mjs +0 -132
  114. package/dist/chunk-QJMZRV7A.mjs.map +0 -1
  115. package/dist/chunk-QXD7WVKK.mjs.map +0 -1
  116. package/dist/chunk-SGCYEEXD.mjs.map +0 -1
  117. package/dist/chunk-SGEYDV3K.mjs.map +0 -1
  118. package/dist/chunk-SLGOHIBL.mjs.map +0 -1
  119. package/dist/chunk-SWG7CNTZ.mjs.map +0 -1
  120. package/dist/client-BO3kavn0.d.ts +0 -25
  121. package/dist/client-DE-vMgdO.d.cts +0 -25
  122. package/dist/ui/styles.css +0 -740
  123. package/dist/ui.cjs +0 -1018
  124. package/dist/ui.cjs.map +0 -1
  125. package/dist/ui.d.cts +0 -231
  126. package/dist/ui.d.ts +0 -231
  127. package/dist/ui.mjs +0 -1018
  128. package/dist/ui.mjs.map +0 -1
  129. package/dist/vite-preview-bootstrap.cjs +0 -66
  130. package/dist/vite-preview-bootstrap.cjs.map +0 -1
  131. package/dist/vite-preview-bootstrap.d.cts +0 -15
  132. package/dist/vite-preview-bootstrap.d.ts +0 -15
  133. package/dist/vite-preview-bootstrap.mjs +0 -66
  134. package/dist/vite-preview-bootstrap.mjs.map +0 -1
  135. package/dist/work-events-BlOVpK0k.d.ts +0 -547
  136. package/dist/work-events-D97EoqvS.d.cts +0 -547
  137. /package/dist/{chunk-RBIQT75L.mjs.map → chunk-GG3IX52W.mjs.map} +0 -0
package/dist/vite.d.cts CHANGED
@@ -30,12 +30,6 @@ declare const SCOPES: readonly [{
30
30
  readonly description: "Review text, ratings and replies";
31
31
  readonly requiresSecurityReview: false;
32
32
  readonly requiresJustification: false;
33
- }, {
34
- readonly key: "review.threads:read";
35
- readonly label: "Read Review threads";
36
- readonly description: "Review threads, comments, screenshot descriptors, build context and safe device context";
37
- readonly requiresSecurityReview: false;
38
- readonly requiresJustification: false;
39
33
  }, {
40
34
  readonly key: "crashes:read";
41
35
  readonly label: "Read crash data";
@@ -99,7 +93,7 @@ declare const SCOPES: readonly [{
99
93
  }, {
100
94
  readonly key: "work:sync";
101
95
  readonly label: "Sync work items";
102
- readonly description: "Sync comments and status on created work items";
96
+ readonly description: "Two-way comments and status on created work items";
103
97
  readonly requiresSecurityReview: false;
104
98
  readonly requiresJustification: true;
105
99
  }, {
@@ -263,7 +257,6 @@ interface CredentialField {
263
257
  options?: string[];
264
258
  help?: string;
265
259
  }
266
- type OAuthTokenRequestEncoding = 'form' | 'json';
267
260
  interface ConnectorAuth {
268
261
  method: 'none' | 'api_key' | 'oauth';
269
262
  fields?: CredentialField[];
@@ -271,8 +264,6 @@ interface ConnectorAuth {
271
264
  authorizationUrl: string;
272
265
  tokenUrl: string;
273
266
  scopes: string[];
274
- /** The token request body encoding. When omitted, uses form encoding. */
275
- tokenRequestEncoding?: OAuthTokenRequestEncoding;
276
267
  };
277
268
  }
278
269
  interface DimensionDeclaration {
@@ -354,53 +345,26 @@ interface AiContribution {
354
345
  prompts?: PromptDeclaration[];
355
346
  context?: ContextDeclaration[];
356
347
  }
357
- type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
358
- type WorkAuth = {
359
- method: 'oauth';
360
- provider: string;
361
- scopes: string[];
362
- } | {
363
- method: 'api_key';
364
- fields: CredentialField[];
365
- };
366
348
  interface WorkContribution {
367
349
  kind: 'tracker' | 'docs' | 'chat';
368
- creates: ('issue' | 'page' | 'message')[];
369
- identity: 'install' | 'user';
370
- comments: 'two-way' | 'none' | {
371
- direction: WorkDirection;
372
- supportsEdits: false;
373
- supportsDeletes: false;
374
- };
375
- status?: {
376
- direction: WorkDirection;
377
- webhook?: string;
378
- map?: Record<'open' | 'in_progress' | 'done', string[]>;
379
- };
380
- attachments: ('image' | 'link')[];
381
- auth: WorkAuth;
382
- /** @deprecated resolved dynamically by describe_container */
383
- container?: {
350
+ container: {
384
351
  label: string;
385
352
  list: string;
386
353
  };
387
- /** @deprecated resolved dynamically by describe_container */
388
- fields?: {
354
+ creates: ('issue' | 'page' | 'message')[];
355
+ fields: {
389
356
  priority?: string[];
390
357
  labels?: boolean;
391
358
  assignee?: boolean;
392
359
  required: string[];
393
360
  };
394
- }
395
- /** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
396
- interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
397
- container: NonNullable<WorkContribution['container']>;
398
- fields: NonNullable<WorkContribution['fields']>;
361
+ attachments: ('image' | 'link')[];
399
362
  comments: 'two-way' | 'none';
400
363
  status?: {
401
364
  webhook: string;
402
365
  map: Record<'open' | 'in_progress' | 'done', string[]>;
403
366
  };
367
+ identity: 'user' | 'install';
404
368
  }
405
369
  interface ExtensionListing {
406
370
  longDescription?: string;
@@ -433,7 +397,7 @@ interface ExtensionManifest {
433
397
  connector?: ConnectorContribution;
434
398
  webhooks?: WebhookContribution[];
435
399
  ai?: AiContribution;
436
- work?: WorkContribution | LegacyWorkContribution;
400
+ work?: WorkContribution;
437
401
  };
438
402
  server?: {
439
403
  baseUrl: string;
package/dist/vite.d.ts CHANGED
@@ -30,12 +30,6 @@ declare const SCOPES: readonly [{
30
30
  readonly description: "Review text, ratings and replies";
31
31
  readonly requiresSecurityReview: false;
32
32
  readonly requiresJustification: false;
33
- }, {
34
- readonly key: "review.threads:read";
35
- readonly label: "Read Review threads";
36
- readonly description: "Review threads, comments, screenshot descriptors, build context and safe device context";
37
- readonly requiresSecurityReview: false;
38
- readonly requiresJustification: false;
39
33
  }, {
40
34
  readonly key: "crashes:read";
41
35
  readonly label: "Read crash data";
@@ -99,7 +93,7 @@ declare const SCOPES: readonly [{
99
93
  }, {
100
94
  readonly key: "work:sync";
101
95
  readonly label: "Sync work items";
102
- readonly description: "Sync comments and status on created work items";
96
+ readonly description: "Two-way comments and status on created work items";
103
97
  readonly requiresSecurityReview: false;
104
98
  readonly requiresJustification: true;
105
99
  }, {
@@ -263,7 +257,6 @@ interface CredentialField {
263
257
  options?: string[];
264
258
  help?: string;
265
259
  }
266
- type OAuthTokenRequestEncoding = 'form' | 'json';
267
260
  interface ConnectorAuth {
268
261
  method: 'none' | 'api_key' | 'oauth';
269
262
  fields?: CredentialField[];
@@ -271,8 +264,6 @@ interface ConnectorAuth {
271
264
  authorizationUrl: string;
272
265
  tokenUrl: string;
273
266
  scopes: string[];
274
- /** The token request body encoding. When omitted, uses form encoding. */
275
- tokenRequestEncoding?: OAuthTokenRequestEncoding;
276
267
  };
277
268
  }
278
269
  interface DimensionDeclaration {
@@ -354,53 +345,26 @@ interface AiContribution {
354
345
  prompts?: PromptDeclaration[];
355
346
  context?: ContextDeclaration[];
356
347
  }
357
- type WorkDirection = 'none' | 'to_provider' | 'from_provider' | 'two-way';
358
- type WorkAuth = {
359
- method: 'oauth';
360
- provider: string;
361
- scopes: string[];
362
- } | {
363
- method: 'api_key';
364
- fields: CredentialField[];
365
- };
366
348
  interface WorkContribution {
367
349
  kind: 'tracker' | 'docs' | 'chat';
368
- creates: ('issue' | 'page' | 'message')[];
369
- identity: 'install' | 'user';
370
- comments: 'two-way' | 'none' | {
371
- direction: WorkDirection;
372
- supportsEdits: false;
373
- supportsDeletes: false;
374
- };
375
- status?: {
376
- direction: WorkDirection;
377
- webhook?: string;
378
- map?: Record<'open' | 'in_progress' | 'done', string[]>;
379
- };
380
- attachments: ('image' | 'link')[];
381
- auth: WorkAuth;
382
- /** @deprecated resolved dynamically by describe_container */
383
- container?: {
350
+ container: {
384
351
  label: string;
385
352
  list: string;
386
353
  };
387
- /** @deprecated resolved dynamically by describe_container */
388
- fields?: {
354
+ creates: ('issue' | 'page' | 'message')[];
355
+ fields: {
389
356
  priority?: string[];
390
357
  labels?: boolean;
391
358
  assignee?: boolean;
392
359
  required: string[];
393
360
  };
394
- }
395
- /** @deprecated Migrate to WorkContribution during the SDK v2 compatibility window. */
396
- interface LegacyWorkContribution extends Omit<WorkContribution, 'auth' | 'container' | 'fields' | 'comments' | 'status'> {
397
- container: NonNullable<WorkContribution['container']>;
398
- fields: NonNullable<WorkContribution['fields']>;
361
+ attachments: ('image' | 'link')[];
399
362
  comments: 'two-way' | 'none';
400
363
  status?: {
401
364
  webhook: string;
402
365
  map: Record<'open' | 'in_progress' | 'done', string[]>;
403
366
  };
367
+ identity: 'user' | 'install';
404
368
  }
405
369
  interface ExtensionListing {
406
370
  longDescription?: string;
@@ -433,7 +397,7 @@ interface ExtensionManifest {
433
397
  connector?: ConnectorContribution;
434
398
  webhooks?: WebhookContribution[];
435
399
  ai?: AiContribution;
436
- work?: WorkContribution | LegacyWorkContribution;
400
+ work?: WorkContribution;
437
401
  };
438
402
  server?: {
439
403
  baseUrl: string;
package/dist/vite.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/vite/plugin.ts
2
2
  import { federation } from "@module-federation/vite";
3
3
  import { readFileSync as readFileSync2 } from "fs";
4
- import { resolve as resolve3, sep as sep2 } from "path";
4
+ import { resolve as resolve2, sep as sep2 } from "path";
5
5
 
6
6
  // src/client/errors.ts
7
7
  var TAP_ERROR_CODES = [
@@ -143,13 +143,6 @@ var SCOPES = [
143
143
  requiresSecurityReview: false,
144
144
  requiresJustification: false
145
145
  },
146
- {
147
- key: "review.threads:read",
148
- label: "Read Review threads",
149
- description: "Review threads, comments, screenshot descriptors, build context and safe device context",
150
- requiresSecurityReview: false,
151
- requiresJustification: false
152
- },
153
146
  {
154
147
  key: "crashes:read",
155
148
  label: "Read crash data",
@@ -223,7 +216,7 @@ var SCOPES = [
223
216
  {
224
217
  key: "work:sync",
225
218
  label: "Sync work items",
226
- description: "Sync comments and status on created work items",
219
+ description: "Two-way comments and status on created work items",
227
220
  requiresSecurityReview: false,
228
221
  requiresJustification: true
229
222
  },
@@ -527,10 +520,7 @@ var connectorContribution = z.object({
527
520
  ),
528
521
  scopes: z.array(z.string()).describe(
529
522
  "The scopes asked of the outside service. These are that service's scopes, not Tappify's."
530
- ),
531
- tokenRequestEncoding: z.enum(["form", "json"]).describe(
532
- "The request body encoding for authorization-code and refresh token exchanges. When omitted, uses form encoding (application/x-www-form-urlencoded); json uses application/json."
533
- ).optional()
523
+ )
534
524
  }).strict().describe('The endpoints, for `method: "oauth"`.').optional()
535
525
  }).strict().describe("How owners authenticate this connector.").optional(),
536
526
  sync: z.enum(["5m", "15m", "1h", "6h", "24h"]).describe("How often Tappify asks your server to sync.").optional(),
@@ -674,7 +664,7 @@ var aiContribution = z.object({
674
664
  ).optional()
675
665
  }).strict();
676
666
  var statusNames = (stage) => z.array(z.string()).describe(`Your own status names that mean ${stage}.`);
677
- var legacyWorkContribution = z.object({
667
+ var workContribution = z.object({
678
668
  kind: z.enum(["tracker", "docs", "chat"]).describe("What kind of destination this is."),
679
669
  container: z.object({
680
670
  label: z.string().min(1).max(60).describe(
@@ -709,55 +699,6 @@ var legacyWorkContribution = z.object({
709
699
  "Whether items are created as the owner who asked (`user`) or as the install itself."
710
700
  )
711
701
  }).strict();
712
- var workDirection = z.enum([
713
- "none",
714
- "to_provider",
715
- "from_provider",
716
- "two-way"
717
- ]);
718
- var workAuth = z.discriminatedUnion("method", [
719
- z.object({
720
- method: z.literal("oauth"),
721
- provider: z.string().min(1).describe("The OAuth provider identifier."),
722
- scopes: z.array(z.string()).describe("The scopes requested from the provider.")
723
- }).strict(),
724
- z.object({
725
- method: z.literal("api_key"),
726
- fields: z.array(credentialField).max(20)
727
- }).strict()
728
- ]);
729
- var currentWorkContribution = legacyWorkContribution.extend({
730
- container: legacyWorkContribution.shape.container.describe(
731
- "Deprecated. Resolve containers dynamically with describe_container."
732
- ).optional(),
733
- fields: legacyWorkContribution.shape.fields.describe("Deprecated. Resolve fields dynamically with describe_container.").optional(),
734
- comments: z.union([
735
- z.enum(["two-way", "none"]).describe("Deprecated. Declare a comments capability object."),
736
- z.object({
737
- direction: workDirection,
738
- supportsEdits: z.literal(false),
739
- supportsDeletes: z.literal(false)
740
- }).strict()
741
- ]),
742
- status: z.object({
743
- direction: workDirection,
744
- webhook: z.string().regex(DOMAIN_EVENT).optional(),
745
- map: z.object({
746
- open: statusNames("not started"),
747
- in_progress: statusNames("under way"),
748
- done: statusNames("finished")
749
- }).strict().describe(
750
- "Deprecated. Resolve statuses dynamically with describe_container."
751
- ).optional()
752
- }).strict().optional(),
753
- auth: workAuth.describe("How owners authenticate the work destination.")
754
- });
755
- var workContribution = z.union([
756
- currentWorkContribution,
757
- legacyWorkContribution.describe(
758
- "Deprecated SDK v2 work declaration. Migrate to work capabilities and auth."
759
- )
760
- ]);
761
702
  var listing = z.object({
762
703
  longDescription: z.string().min(1).max(5e3).describe("The body of your listing page, in markdown.").optional(),
763
704
  screenshots: z.array(z.string().min(1)).min(1, "A listing shows 1 to 6 screenshots.").max(6, "A listing shows 1 to 6 screenshots.").describe(
@@ -849,7 +790,7 @@ var manifestObject = z.object({
849
790
  "What this extension offers the assistant: tools, mentions, actions, knowledge, skills, prompts and context providers."
850
791
  ).optional(),
851
792
  work: workContribution.describe(
852
- "The work destination this extension creates issues, pages or messages in. Needs `review.threads:read` and `work:create`; active comment or status sync also needs `work:sync`."
793
+ "The work destination this extension creates issues, pages or messages in. Needs the `work:create` and `work:sync` scopes."
853
794
  ).optional()
854
795
  }).strict().describe(
855
796
  "What this extension adds to the host. At most 20 UI contributions in total, and a page, tab, widget, row action, marker or settings panel needs the `ui:render` scope."
@@ -1070,36 +1011,16 @@ var manifestSchema = manifestObject.superRefine((manifest, ctx) => {
1070
1011
  }
1071
1012
  }
1072
1013
  if (contributes.work) {
1073
- const work = contributes.work;
1074
- const legacy = isLegacyWork(work);
1075
- if (!legacy || !granted.has("reviews:read")) {
1076
- requireScope(
1077
- "review.threads:read",
1078
- ["scopes"],
1079
- "the work destination reads Review threads."
1080
- );
1081
- }
1082
1014
  requireScope(
1083
1015
  "work:create",
1084
1016
  ["scopes"],
1085
1017
  "the work destination creates items."
1086
1018
  );
1087
- const comments = typeof work.comments === "string" ? work.comments : work.comments.direction;
1088
- const status = work.status ? "direction" in work.status ? work.status.direction : "from_provider" : "none";
1089
- if (comments !== "none" || status !== "none") {
1090
- requireScope(
1091
- "work:sync",
1092
- ["scopes"],
1093
- "the work destination syncs comments or status."
1094
- );
1095
- }
1096
- if (work.identity === "user") {
1097
- ctx.addIssue({
1098
- code: "custom",
1099
- path: ["contributes", "work", "identity"],
1100
- message: 'Per-user work identity is not supported. Set identity to "install".'
1101
- });
1102
- }
1019
+ requireScope(
1020
+ "work:sync",
1021
+ ["scopes"],
1022
+ "the work destination syncs comments and status."
1023
+ );
1103
1024
  }
1104
1025
  const needsServer = contributes.connector !== void 0 || (contributes.webhooks?.length ?? 0) > 0 || ai !== void 0 || contributes.work !== void 0 || manifest.server?.procedures !== void 0;
1105
1026
  if (needsServer && !manifest.server?.baseUrl) {
@@ -1174,14 +1095,8 @@ function validateManifest(value) {
1174
1095
  }));
1175
1096
  return { ok: false, issues };
1176
1097
  }
1177
- function isLegacyWork(work) {
1178
- return !("auth" in work);
1179
- }
1180
1098
 
1181
1099
  // src/vite/preview/plugin.ts
1182
- import { randomUUID } from "crypto";
1183
- import { isAbsolute, relative, resolve } from "path";
1184
- import { normalizePath } from "vite";
1185
1100
  var PREVIEW_CLIENT_ID = "virtual:tappify-preview/client";
1186
1101
  var PREVIEW_MANIFEST_ID = "virtual:tappify-preview/manifest";
1187
1102
  var PREVIEW_REMOTE_ID = "virtual:tappify-preview/remote";
@@ -1232,13 +1147,11 @@ function previewDocument(manifest, remote) {
1232
1147
  }
1233
1148
  if (!remote.ok)
1234
1149
  return messageDocument("Preview remote was refused", [remote.message]);
1235
- const icon = manifest.manifest.icon.replace(/^\.\//, "");
1236
1150
  return `<!doctype html>
1237
1151
  <html lang="en">
1238
1152
  <head>
1239
1153
  <meta charset="UTF-8" />
1240
1154
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
1241
- <link rel="icon" href="/${escapeHtml(icon)}" />
1242
1155
  <title>${escapeHtml(manifest.manifest.name)} \xB7 Tappify local preview</title>
1243
1156
  </head>
1244
1157
  <body>
@@ -1248,37 +1161,11 @@ function previewDocument(manifest, remote) {
1248
1161
  </html>`;
1249
1162
  }
1250
1163
  var moduleSource = (value) => `export default ${JSON.stringify(value)};`;
1251
- function optimizedReactUrl(root, cacheDir, cacheGeneration) {
1252
- const depsCacheDir = normalizePath(resolve(cacheDir, "deps"));
1253
- const relativeCacheDir = normalizePath(relative(root, depsCacheDir));
1254
- const prefix = isAbsolute(relativeCacheDir) || relativeCacheDir.startsWith("../") ? `/@fs/${depsCacheDir.replace(/^\/+/, "")}` : `/${relativeCacheDir}`;
1255
- return `${prefix}/react.js?tappify=${encodeURIComponent(cacheGeneration)}`;
1256
- }
1257
1164
  function createPreviewPlugins(options) {
1258
1165
  const remote = previewRemote(options.remote, options.port);
1259
- const cacheGeneration = randomUUID();
1260
- let reactUrl = optimizedReactUrl(
1261
- resolve(options.manifestFile, ".."),
1262
- resolve(options.manifestFile, "../node_modules/.vite"),
1263
- cacheGeneration
1264
- );
1265
1166
  const preview = {
1266
1167
  name: "tappify:preview",
1267
1168
  apply: "serve",
1268
- config() {
1269
- return {
1270
- optimizeDeps: {
1271
- exclude: ["@tappify/extension-sdk/vite/preview/bootstrap"]
1272
- }
1273
- };
1274
- },
1275
- configResolved(config) {
1276
- reactUrl = optimizedReactUrl(
1277
- config.root,
1278
- config.cacheDir,
1279
- cacheGeneration
1280
- );
1281
- },
1282
1169
  resolveId(id) {
1283
1170
  if (VIRTUAL_IDS.has(id)) return `\0${id}`;
1284
1171
  if (id.startsWith("\0") && VIRTUAL_IDS.has(id.slice(1))) return id;
@@ -1291,11 +1178,11 @@ function createPreviewPlugins(options) {
1291
1178
  if (id === `\0${PREVIEW_REMOTE_ID}`) return moduleSource(remote);
1292
1179
  if (id !== `\0${PREVIEW_CLIENT_ID}`) return null;
1293
1180
  return [
1294
- `import { startLocalPreview } from '@tappify/extension-sdk/vite/preview/bootstrap';`,
1181
+ `import { mountLocalPreview } from '@tappify/extension-sdk/vite/preview';`,
1295
1182
  `import manifest from '${PREVIEW_MANIFEST_ID}';`,
1296
1183
  `import remote from '${PREVIEW_REMOTE_ID}';`,
1297
1184
  `const mount = document.getElementById('tappify-preview-root');`,
1298
- `if (mount && manifest.ok && remote.ok) void startLocalPreview({ manifest: manifest.manifest, remote: remote.url, reactUrl: ${JSON.stringify(reactUrl)}, mount });`
1185
+ `if (mount && manifest.ok && remote.ok) mountLocalPreview({ manifest: manifest.manifest, remote: remote.url, mount });`
1299
1186
  ].join("\n");
1300
1187
  },
1301
1188
  configureServer(server) {
@@ -1343,7 +1230,7 @@ function createPreviewPlugins(options) {
1343
1230
 
1344
1231
  // src/vite/styles.ts
1345
1232
  import { existsSync, readFileSync } from "fs";
1346
- import { dirname, extname, resolve as resolve2, sep } from "path";
1233
+ import { dirname, extname, resolve, sep } from "path";
1347
1234
  var IMPORT_PATTERN = /(?:^|\n)\s*(?:import|export)(?:[^'"]*?from\s*)?\s*['"]([^'"]+)['"]/g;
1348
1235
  var IMPORT_SPECIFIER_PATTERN = /((?:^|\n)\s*(?:import|export)(?:[^'"]*?from\s*)?\s*['"])([^'"]+)(['"])/g;
1349
1236
  var BLOCK_COMMENT_PATTERN = /\/\*[\s\S]*?\*\//g;
@@ -1356,14 +1243,14 @@ function isPlainStylesheet(specifier) {
1356
1243
  return specifier.endsWith(".css") && !specifier.endsWith(".module.css");
1357
1244
  }
1358
1245
  function resolveSource(specifier, importer) {
1359
- const base = resolve2(dirname(importer), specifier);
1246
+ const base = resolve(dirname(importer), specifier);
1360
1247
  if (extname(base) !== "" && existsSync(base)) return base;
1361
1248
  for (const extension of SOURCE_EXTENSIONS) {
1362
1249
  const candidate = `${base}${extension}`;
1363
1250
  if (existsSync(candidate)) return candidate;
1364
1251
  }
1365
1252
  for (const extension of SOURCE_EXTENSIONS) {
1366
- const candidate = resolve2(base, `index${extension}`);
1253
+ const candidate = resolve(base, `index${extension}`);
1367
1254
  if (existsSync(candidate)) return candidate;
1368
1255
  }
1369
1256
  return null;
@@ -1385,7 +1272,7 @@ function collectEntryStyles(entryAbsolutePath, root) {
1385
1272
  while (match !== null) {
1386
1273
  const specifier = match[1];
1387
1274
  if (specifier.endsWith(".css")) {
1388
- const value = specifier.startsWith(".") ? resolve2(dirname(file), specifier) : specifier;
1275
+ const value = specifier.startsWith(".") ? resolve(dirname(file), specifier) : specifier;
1389
1276
  if (!seenStyles.has(value)) {
1390
1277
  seenStyles.add(value);
1391
1278
  styles.push(value);
@@ -1418,7 +1305,7 @@ var DEFAULT_PORT = 5273;
1418
1305
  var SOURCE_FILE = /\.(?:[cm]?[jt]sx?)$/;
1419
1306
  var federationOptionsByPlugins = /* @__PURE__ */ new WeakMap();
1420
1307
  function manifestFile(options) {
1421
- return options.manifestPath ?? resolve3(options.root ?? process.cwd(), "tappify.extension.json");
1308
+ return options.manifestPath ?? resolve2(options.root ?? process.cwd(), "tappify.extension.json");
1422
1309
  }
1423
1310
  function loadManifest(options) {
1424
1311
  let raw;
@@ -1458,7 +1345,7 @@ function tappifyExtension(options = {}) {
1458
1345
  const exposes = {};
1459
1346
  for (const contribution of contributions) {
1460
1347
  const key = contribution.expose.slice("./".length);
1461
- entryByKey.set(key, resolve3(root, contribution.entry));
1348
+ entryByKey.set(key, resolve2(root, contribution.entry));
1462
1349
  exposes[contribution.expose] = `${VIRTUAL_PREFIX}${key}`;
1463
1350
  }
1464
1351
  const singleton = { singleton: true, requiredVersion: false };