@superblocksteam/shared 0.9567.3 → 0.9568.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/socket/protocol.d.ts +13 -1
- package/dist/socket/protocol.d.ts.map +1 -1
- package/dist/socket/protocol.js.map +1 -1
- package/dist/types/ai/index.d.ts +43 -1
- package/dist/types/ai/index.d.ts.map +1 -1
- package/dist/types/ai/index.js +1 -1
- package/dist/types/ai/index.js.map +1 -1
- package/dist/types/ai/quota-paywall.d.ts +8 -1
- package/dist/types/ai/quota-paywall.d.ts.map +1 -1
- package/dist/types/ai/quota-paywall.js +46 -15
- package/dist/types/ai/quota-paywall.js.map +1 -1
- package/dist/types/billing/billing.d.ts +5 -0
- package/dist/types/billing/billing.d.ts.map +1 -1
- package/dist/types/billing/billing.js +3 -0
- package/dist/types/billing/billing.js.map +1 -1
- package/dist/types/fact/fact.d.ts +17 -0
- package/dist/types/fact/fact.d.ts.map +1 -1
- package/dist/types/rbac/index.d.ts +5 -0
- package/dist/types/rbac/index.d.ts.map +1 -1
- package/dist/types/rbac/index.js +5 -0
- package/dist/types/rbac/index.js.map +1 -1
- package/dist/utils/attachment-upload.d.ts +122 -0
- package/dist/utils/attachment-upload.d.ts.map +1 -0
- package/dist/utils/attachment-upload.js +356 -0
- package/dist/utils/attachment-upload.js.map +1 -0
- package/dist/utils/attachment-upload.test.d.ts +2 -0
- package/dist/utils/attachment-upload.test.d.ts.map +1 -0
- package/dist/utils/attachment-upload.test.js +126 -0
- package/dist/utils/attachment-upload.test.js.map +1 -0
- package/dist/utils/github-workflow.d.ts +6 -0
- package/dist/utils/github-workflow.d.ts.map +1 -0
- package/dist/utils/github-workflow.js +72 -0
- package/dist/utils/github-workflow.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist-esm/index.d.ts +1 -0
- package/dist-esm/index.d.ts.map +1 -1
- package/dist-esm/index.js +1 -0
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/socket/protocol.d.ts +13 -1
- package/dist-esm/socket/protocol.d.ts.map +1 -1
- package/dist-esm/socket/protocol.js.map +1 -1
- package/dist-esm/types/ai/index.d.ts +43 -1
- package/dist-esm/types/ai/index.d.ts.map +1 -1
- package/dist-esm/types/ai/index.js +1 -1
- package/dist-esm/types/ai/index.js.map +1 -1
- package/dist-esm/types/ai/quota-paywall.d.ts +8 -1
- package/dist-esm/types/ai/quota-paywall.d.ts.map +1 -1
- package/dist-esm/types/ai/quota-paywall.js +45 -14
- package/dist-esm/types/ai/quota-paywall.js.map +1 -1
- package/dist-esm/types/billing/billing.d.ts +5 -0
- package/dist-esm/types/billing/billing.d.ts.map +1 -1
- package/dist-esm/types/billing/billing.js +3 -0
- package/dist-esm/types/billing/billing.js.map +1 -1
- package/dist-esm/types/fact/fact.d.ts +17 -0
- package/dist-esm/types/fact/fact.d.ts.map +1 -1
- package/dist-esm/types/rbac/index.d.ts +5 -0
- package/dist-esm/types/rbac/index.d.ts.map +1 -1
- package/dist-esm/types/rbac/index.js +5 -0
- package/dist-esm/types/rbac/index.js.map +1 -1
- package/dist-esm/utils/attachment-upload.d.ts +122 -0
- package/dist-esm/utils/attachment-upload.d.ts.map +1 -0
- package/dist-esm/utils/attachment-upload.js +345 -0
- package/dist-esm/utils/attachment-upload.js.map +1 -0
- package/dist-esm/utils/attachment-upload.test.d.ts +2 -0
- package/dist-esm/utils/attachment-upload.test.d.ts.map +1 -0
- package/dist-esm/utils/attachment-upload.test.js +124 -0
- package/dist-esm/utils/attachment-upload.test.js.map +1 -0
- package/dist-esm/utils/github-workflow.d.ts +6 -0
- package/dist-esm/utils/github-workflow.d.ts.map +1 -0
- package/dist-esm/utils/github-workflow.js +65 -0
- package/dist-esm/utils/github-workflow.js.map +1 -0
- package/dist-esm/utils/index.d.ts +1 -0
- package/dist-esm/utils/index.d.ts.map +1 -1
- package/dist-esm/utils/index.js +1 -0
- package/dist-esm/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/socket/protocol.ts +21 -1
- package/src/types/ai/index.ts +47 -1
- package/src/types/ai/quota-paywall.ts +53 -15
- package/src/types/billing/billing.ts +5 -0
- package/src/types/fact/fact.ts +18 -0
- package/src/types/rbac/index.ts +5 -0
- package/src/utils/attachment-upload.test.ts +153 -0
- package/src/utils/attachment-upload.ts +546 -0
- package/src/utils/github-workflow.ts +68 -0
- package/src/utils/index.ts +1 -0
- package/dist/types/ai/credit-pricing.d.ts +0 -47
- package/dist/types/ai/credit-pricing.d.ts.map +0 -1
- package/dist/types/ai/credit-pricing.js +0 -66
- package/dist/types/ai/credit-pricing.js.map +0 -1
- package/dist-esm/types/ai/credit-pricing.d.ts +0 -47
- package/dist-esm/types/ai/credit-pricing.d.ts.map +0 -1
- package/dist-esm/types/ai/credit-pricing.js +0 -61
- package/dist-esm/types/ai/credit-pricing.js.map +0 -1
- package/src/types/ai/credit-pricing.ts +0 -87
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const DEFAULT_SUPERBLOCKS_DOMAIN = "app.superblocks.com";
|
|
2
|
+
export declare function isGitHubRemoteUrl(remoteUrl: string): boolean;
|
|
3
|
+
export declare function buildGithubSuperblocksSyncWorkflow(domain?: string): string;
|
|
4
|
+
export declare function getSuperblocksDomainFromBaseUrl(superblocksBaseUrl: string): string;
|
|
5
|
+
export declare function buildGithubSuperblocksSyncWorkflowFromBaseUrl(superblocksBaseUrl: string): string;
|
|
6
|
+
//# sourceMappingURL=github-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-workflow.d.ts","sourceRoot":"","sources":["../../src/utils/github-workflow.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,wBAAwB,CAAC;AAEhE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,kCAAkC,CAAC,MAAM,GAAE,MAAmC,GAAG,MAAM,CA4CtG;AAED,wBAAgB,+BAA+B,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAWlF;AAED,wBAAgB,6CAA6C,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAEhG"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const DEFAULT_SUPERBLOCKS_DOMAIN = 'app.superblocks.com';
|
|
2
|
+
export function isGitHubRemoteUrl(remoteUrl) {
|
|
3
|
+
return /(^git@github\.com:)|(^https?:\/\/github\.com\/)|(^ssh:\/\/git@github\.com\/)/.test(remoteUrl.trim());
|
|
4
|
+
}
|
|
5
|
+
export function buildGithubSuperblocksSyncWorkflow(domain = DEFAULT_SUPERBLOCKS_DOMAIN) {
|
|
6
|
+
return `name: Sync changes to Superblocks
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
superblocks-sync:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
name: Sync to Superblocks
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
packages: read
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
|
|
28
|
+
# Optional: needed only if the CLI version is private in GitHub Packages.
|
|
29
|
+
- name: Setup npm credentials
|
|
30
|
+
env:
|
|
31
|
+
NPM_AUTH_TOKEN: \${{ secrets.NPM_AUTH_TOKEN }}
|
|
32
|
+
run: |
|
|
33
|
+
if [ -n "$NPM_AUTH_TOKEN" ]; then
|
|
34
|
+
echo "@superblocksteam:registry=https://npm.pkg.github.com" >> .npmrc
|
|
35
|
+
echo "always-auth=true" >> .npmrc
|
|
36
|
+
echo "//npm.pkg.github.com/:_authToken=$NPM_AUTH_TOKEN" >> .npmrc
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
- name: Sync
|
|
40
|
+
uses: superblocksteam/sync-action@v1
|
|
41
|
+
env:
|
|
42
|
+
NPM_CONFIG_USERCONFIG: \${{ github.workspace }}/.npmrc
|
|
43
|
+
with:
|
|
44
|
+
token: \${{ secrets.SUPERBLOCKS_TOKEN }}
|
|
45
|
+
domain: ${domain}
|
|
46
|
+
path: .
|
|
47
|
+
sha: \${{ github.sha }}
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
export function getSuperblocksDomainFromBaseUrl(superblocksBaseUrl) {
|
|
51
|
+
const trimmed = superblocksBaseUrl.trim();
|
|
52
|
+
if (!trimmed) {
|
|
53
|
+
return DEFAULT_SUPERBLOCKS_DOMAIN;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
return new URL(trimmed).host || DEFAULT_SUPERBLOCKS_DOMAIN;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return DEFAULT_SUPERBLOCKS_DOMAIN;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export function buildGithubSuperblocksSyncWorkflowFromBaseUrl(superblocksBaseUrl) {
|
|
63
|
+
return buildGithubSuperblocksSyncWorkflow(getSuperblocksDomainFromBaseUrl(superblocksBaseUrl));
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=github-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-workflow.js","sourceRoot":"","sources":["../../src/utils/github-workflow.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,qBAAqB,CAAC;AAEhE,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,OAAO,8EAA8E,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AAC/G,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,SAAiB,0BAA0B;IAC5F,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAuCW,MAAM;;;CAGzB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,kBAA0B;IACxE,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,0BAA0B,CAAC;IACpC,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,0BAA0B,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,0BAA0B,CAAC;IACpC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,6CAA6C,CAAC,kBAA0B;IACtF,OAAO,kCAAkC,CAAC,+BAA+B,CAAC,kBAAkB,CAAC,CAAC,CAAC;AACjG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AAEvC,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AAEvC,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
package/dist-esm/utils/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AAEvC,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AAEvC,OAAO,MAAM,MAAM,2BAA2B,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './observability/index.js';
|
|
|
8
8
|
export * from './constants.js';
|
|
9
9
|
export * from './pageMigrations/index.js';
|
|
10
10
|
export * from './utils/appDSL.js';
|
|
11
|
+
export * from './utils/github-workflow.js';
|
|
11
12
|
export * from './pages/index.js';
|
|
12
13
|
export * from './utils/page.js';
|
|
13
14
|
export * from './utils/response-dto.js';
|
package/src/socket/protocol.ts
CHANGED
|
@@ -2,7 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
import { DirectoryEntry, PutManyRequestPayload, PutManyResponsePayload } from '../dbfs/types.js';
|
|
4
4
|
import { ApiToSign, ApiToVerify, AppToSign, AppToVerify, ApplicationSignatureTreeSigned, Signature } from '../signing/constants.js';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AiChatMessageDto,
|
|
7
|
+
AiChatMessagePayload,
|
|
8
|
+
AiWorkflowEvent,
|
|
9
|
+
AiResolveAttachmentLeasesRequest,
|
|
10
|
+
AiResolveAttachmentLeasesResponse,
|
|
11
|
+
FactCreate,
|
|
12
|
+
FactDto,
|
|
13
|
+
FactListQuery,
|
|
14
|
+
ListFactsResponse
|
|
15
|
+
} from '../types/index.js';
|
|
6
16
|
import {
|
|
7
17
|
ApplicationConfiguration,
|
|
8
18
|
ApplicationPageClonePayload,
|
|
@@ -134,9 +144,15 @@ export interface ServerMethods {
|
|
|
134
144
|
submit: ServerMethodSchema<AiWorkflowEvent, void>;
|
|
135
145
|
};
|
|
136
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* Resolve attachment leases and return fresh signed URLs.
|
|
149
|
+
* Called by ai-service to refresh attachment leases before sending to LLM.
|
|
150
|
+
*/
|
|
151
|
+
resolveAttachmentLeases: ServerMethodSchema<AiResolveAttachmentLeasesRequest, AiResolveAttachmentLeasesResponse>;
|
|
137
152
|
};
|
|
138
153
|
fact: {
|
|
139
154
|
list: ServerMethodSchema<FactListQuery, ListFactsResponse>;
|
|
155
|
+
create: ServerMethodSchema<FactCreate, FactDto>;
|
|
140
156
|
};
|
|
141
157
|
};
|
|
142
158
|
v2: {
|
|
@@ -225,6 +241,10 @@ export interface ServerMethods {
|
|
|
225
241
|
lock: {
|
|
226
242
|
acquire: ServerMethodSchema<{ applicationId: string; branchName: string; sessionType: string }, GetAppBranchLockResponseBody>;
|
|
227
243
|
release: ServerMethodSchema<{ applicationId: string; branchName: string; lockId: string }, void>;
|
|
244
|
+
transfer: ServerMethodSchema<
|
|
245
|
+
{ applicationId: string; fromBranchName: string; toBranchName: string; lockId: string },
|
|
246
|
+
GetAppBranchLockResponseBody
|
|
247
|
+
>;
|
|
228
248
|
grab: ServerMethodSchema<{ applicationId: string; branchName: string; lockId: string }, GetAppBranchLockResponseBody>;
|
|
229
249
|
inspect: ServerMethodSchema<{ applicationId: string; branchName: string }, LockInfo>;
|
|
230
250
|
forceTake: ServerMethodSchema<{ applicationId: string; branchName: string; sessionType: string }, GetAppBranchLockResponseBody>;
|
package/src/types/ai/index.ts
CHANGED
|
@@ -8,12 +8,59 @@ export type AiChatMessageDto = {
|
|
|
8
8
|
authorName?: string | null;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Attachment reference for lease resolution.
|
|
13
|
+
*/
|
|
14
|
+
export interface AiAttachmentLeaseReference {
|
|
15
|
+
/** Stable URL of the attachment */
|
|
16
|
+
url: string;
|
|
17
|
+
/** Media/MIME type */
|
|
18
|
+
mediaType: string;
|
|
19
|
+
/** Original filename */
|
|
20
|
+
fileName: string;
|
|
21
|
+
/** Optional storage key in object storage */
|
|
22
|
+
storageKey?: string;
|
|
23
|
+
/** Scope of the attachment: org-wide or app-specific */
|
|
24
|
+
scopeType?: 'org' | 'app';
|
|
25
|
+
/** Application ID if scopeType is "app" */
|
|
26
|
+
applicationId?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Resolved attachment with fresh signed URL.
|
|
31
|
+
*/
|
|
32
|
+
export interface AiResolvedAttachment {
|
|
33
|
+
url: string;
|
|
34
|
+
signedUrl: string;
|
|
35
|
+
expiresAt: string;
|
|
36
|
+
mimeType: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Request to resolve attachment leases via RPC.
|
|
41
|
+
*/
|
|
42
|
+
export interface AiResolveAttachmentLeasesRequest {
|
|
43
|
+
attachments: AiAttachmentLeaseReference[];
|
|
44
|
+
/** Scoped token for Bucketeer access (issued client-side). */
|
|
45
|
+
scopedToken: string;
|
|
46
|
+
/** Base URL of the Superblocks server, used to derive Bucketeer URL. */
|
|
47
|
+
superblocksBaseUrl: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Response with resolved attachment leases.
|
|
52
|
+
*/
|
|
53
|
+
export interface AiResolveAttachmentLeasesResponse {
|
|
54
|
+
attachments: AiResolvedAttachment[];
|
|
55
|
+
}
|
|
56
|
+
|
|
11
57
|
/**
|
|
12
58
|
* System event trigger types for AI operations without prompt_id
|
|
13
59
|
*/
|
|
14
60
|
export enum AiSystemTriggerType {
|
|
15
61
|
APP_NAME = 'app_name',
|
|
16
62
|
COMMIT_MESSAGE = 'commit_message',
|
|
63
|
+
DASHBOARD_CHAT = 'dashboard_chat',
|
|
17
64
|
FACT_METADATA = 'fact_metadata'
|
|
18
65
|
}
|
|
19
66
|
|
|
@@ -46,5 +93,4 @@ export interface AiWorkflowEvent {
|
|
|
46
93
|
attributes: AiWorkflowAttributes;
|
|
47
94
|
}
|
|
48
95
|
|
|
49
|
-
export * from './credit-pricing.js';
|
|
50
96
|
export * from './quota-paywall.js';
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
export type AiQuotaPaywallReason = 'token_limit_exceeded' | 'trial_expired';
|
|
1
|
+
export type AiQuotaPaywallReason = 'credit_limit_exceeded' | 'no_seat_assigned' | 'token_limit_exceeded' | 'trial_expired';
|
|
2
2
|
|
|
3
3
|
export const getAiQuotaPaywallReasonFromMessage = (message: string): AiQuotaPaywallReason | undefined => {
|
|
4
4
|
const normalizedMessage = message.toLowerCase();
|
|
5
5
|
|
|
6
|
+
if (
|
|
7
|
+
normalizedMessage.includes('no_seat_assigned') ||
|
|
8
|
+
normalizedMessage.includes("doesn't have an ai builder license assigned") ||
|
|
9
|
+
normalizedMessage.includes("doesn't have an ai builder seat assigned") ||
|
|
10
|
+
normalizedMessage.includes('does not have an ai builder license assigned') ||
|
|
11
|
+
normalizedMessage.includes('does not have an ai builder seat assigned') ||
|
|
12
|
+
normalizedMessage.includes('no builder seat assigned')
|
|
13
|
+
) {
|
|
14
|
+
return 'no_seat_assigned';
|
|
15
|
+
}
|
|
16
|
+
|
|
6
17
|
if (
|
|
7
18
|
normalizedMessage.includes('trial_expired') ||
|
|
8
19
|
normalizedMessage.includes('ai trial period has ended') ||
|
|
@@ -11,7 +22,15 @@ export const getAiQuotaPaywallReasonFromMessage = (message: string): AiQuotaPayw
|
|
|
11
22
|
return 'trial_expired';
|
|
12
23
|
}
|
|
13
24
|
|
|
14
|
-
if (normalizedMessage.includes('token_limit_exceeded')
|
|
25
|
+
if (normalizedMessage.includes('token_limit_exceeded')) {
|
|
26
|
+
return 'token_limit_exceeded';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (normalizedMessage.includes('credit_limit_exceeded') || normalizedMessage.includes('organization has reached its ai usage limit')) {
|
|
30
|
+
return 'credit_limit_exceeded';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (normalizedMessage.includes('ai usage limit')) {
|
|
15
34
|
return 'token_limit_exceeded';
|
|
16
35
|
}
|
|
17
36
|
|
|
@@ -22,11 +41,22 @@ export const AI_QUOTA_PAYWALL_STRIPE_CHECKOUT_URL = 'https://buy.stripe.com/7sYe
|
|
|
22
41
|
|
|
23
42
|
export const AI_QUOTA_PAYWALL_CONTACT_SALES_EMAIL = 'sales@superblockshq.com';
|
|
24
43
|
|
|
44
|
+
// TODO: Revisit this mailto template once backend enforcement is in place.
|
|
45
|
+
// Surface the specific reason (buy a seat vs. increase org credits) so the
|
|
46
|
+
// email to the admin is actionable rather than generic.
|
|
25
47
|
export const AI_QUOTA_PAYWALL_CONTACT_SALES_MAILTO = 'mailto:sales@superblockshq.com?subject=Enterprise%20inquiry';
|
|
26
48
|
|
|
27
49
|
export const AI_QUOTA_PAYWALL_REASON_CONFIG: Record<AiQuotaPaywallReason, { title: string; subtitle: string }> = {
|
|
50
|
+
credit_limit_exceeded: {
|
|
51
|
+
title: 'Your organization has reached its AI usage limit',
|
|
52
|
+
subtitle: 'Ask your admin to purchase additional AI credits to continue using Clark AI.'
|
|
53
|
+
},
|
|
54
|
+
no_seat_assigned: {
|
|
55
|
+
title: "You don't have an AI Builder license",
|
|
56
|
+
subtitle: 'Ask your admin to assign a license so you can continue building with Clark AI.'
|
|
57
|
+
},
|
|
28
58
|
token_limit_exceeded: {
|
|
29
|
-
title: 'Your
|
|
59
|
+
title: 'Your organization has reached its AI usage limit',
|
|
30
60
|
subtitle: 'Upgrade your plan to continue using Clark AI and other AI-powered features.'
|
|
31
61
|
},
|
|
32
62
|
trial_expired: {
|
|
@@ -35,28 +65,36 @@ export const AI_QUOTA_PAYWALL_REASON_CONFIG: Record<AiQuotaPaywallReason, { titl
|
|
|
35
65
|
}
|
|
36
66
|
};
|
|
37
67
|
|
|
68
|
+
export const AI_QUOTA_PAYWALL_PRICE_PER_SEAT_ANNUAL = 80;
|
|
69
|
+
export const AI_QUOTA_PAYWALL_PRICE_PER_SEAT_MONTHLY = 100;
|
|
70
|
+
export const AI_QUOTA_PAYWALL_CREDITS_PER_SEAT = 80;
|
|
71
|
+
export const AI_QUOTA_PAYWALL_APPS_PER_SEAT = 1;
|
|
72
|
+
export const AI_QUOTA_PAYWALL_MIN_SEATS = 1;
|
|
73
|
+
export const AI_QUOTA_PAYWALL_MAX_SEATS = 100;
|
|
74
|
+
|
|
38
75
|
export const AI_QUOTA_PAYWALL_TEAMS_FEATURES = [
|
|
39
|
-
'
|
|
76
|
+
'80 AI Credits per AI Builder / month',
|
|
77
|
+
'Org-level credit top-ups, shared across team',
|
|
40
78
|
'Clark AI agent for app building',
|
|
41
79
|
'Clark User Memory',
|
|
42
80
|
'AI Credit Packs add-on available'
|
|
43
81
|
];
|
|
44
82
|
|
|
45
83
|
export const AI_QUOTA_PAYWALL_ENTERPRISE_FEATURES = [
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
'
|
|
49
|
-
'
|
|
84
|
+
'Clark Integration and Organization memory',
|
|
85
|
+
'Source Control via GitHub, GitLab, BitBucket, Azure DevOps',
|
|
86
|
+
'Secrets Management',
|
|
87
|
+
'Embedded Applications',
|
|
88
|
+
'Custom app hosting'
|
|
50
89
|
];
|
|
51
90
|
|
|
52
|
-
export const AI_QUOTA_PAYWALL_TEAMS_PLATFORM_FEATURES = ['Staging and production environments', '
|
|
91
|
+
export const AI_QUOTA_PAYWALL_TEAMS_PLATFORM_FEATURES = ['Staging and production environments', '1 hosted app included'];
|
|
53
92
|
|
|
54
93
|
export const AI_QUOTA_PAYWALL_ENTERPRISE_PLATFORM_FEATURES = [
|
|
55
|
-
'
|
|
56
|
-
'Custom app hosting with volume pricing',
|
|
94
|
+
'Deploy in your VPC (Hybrid or Cloud Prem)',
|
|
57
95
|
'SSO / SAML / OIDC',
|
|
58
|
-
'
|
|
59
|
-
'Audit Logs'
|
|
60
|
-
'Dedicated support',
|
|
61
|
-
'99.9% SLA'
|
|
96
|
+
'Role-based access control (RBAC)',
|
|
97
|
+
'Audit Logs & Observability'
|
|
62
98
|
];
|
|
99
|
+
|
|
100
|
+
export const AI_QUOTA_PAYWALL_ENTERPRISE_SUPPORT_FEATURES = ['Dedicated account team', 'Enterprise Uptime and SLAs'];
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export enum BillingPlan {
|
|
2
2
|
TRIAL = 'TRIAL',
|
|
3
|
+
/** @deprecated Legacy v1 plan — no longer issued to new organizations. */
|
|
3
4
|
FREE = 'FREE',
|
|
5
|
+
/** @deprecated Legacy v1 plan — no longer issued to new organizations. */
|
|
4
6
|
STARTER = 'STARTER',
|
|
7
|
+
/** @deprecated Legacy v1 plan — no longer issued to new organizations. */
|
|
5
8
|
PRO = 'PRO',
|
|
6
9
|
ENTERPRISE = 'ENTERPRISE',
|
|
7
10
|
TEAMS = 'TEAMS',
|
|
@@ -13,4 +16,6 @@ export type Billing = {
|
|
|
13
16
|
isExpired: boolean;
|
|
14
17
|
expiryDate: Date;
|
|
15
18
|
daysLeft: number;
|
|
19
|
+
billingInterval?: 'annual' | 'monthly' | null;
|
|
20
|
+
interval?: 'annual' | 'monthly' | null;
|
|
16
21
|
};
|
package/src/types/fact/fact.ts
CHANGED
|
@@ -54,3 +54,21 @@ export type FactListQuery = {
|
|
|
54
54
|
export interface ListFactsResponse {
|
|
55
55
|
facts: FactDto[];
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* FactCreate for Socket RPC protocol.
|
|
60
|
+
*
|
|
61
|
+
* NOTE: This type is intentionally duplicated from @superblocksteam/schemas to avoid
|
|
62
|
+
* a circular dependency. The schemas package cannot depend on shared, and the socket
|
|
63
|
+
* protocol in shared needs this type. Keep in sync with packages/schemas/src/schemas/FactCreate.ts.
|
|
64
|
+
*/
|
|
65
|
+
export type FactCreate = {
|
|
66
|
+
name: string;
|
|
67
|
+
description: string;
|
|
68
|
+
content: string;
|
|
69
|
+
metadata?: Record<string, unknown>;
|
|
70
|
+
entityScope: FactEntityScope;
|
|
71
|
+
entityId: string;
|
|
72
|
+
accessType?: FactAccessType;
|
|
73
|
+
createdSource?: FactCreatedSource;
|
|
74
|
+
};
|
package/src/types/rbac/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export enum PermissionedEntities {
|
|
|
39
39
|
APPLICATION_V2 = 'application_v2',
|
|
40
40
|
API_V3 = 'api_v3',
|
|
41
41
|
API = 'api',
|
|
42
|
+
ORGANIZATION = 'organization',
|
|
42
43
|
/**
|
|
43
44
|
* @deprecated The Datasource entity is being deprecated in favor of the Integration entity.
|
|
44
45
|
*/
|
|
@@ -135,6 +136,7 @@ export enum ResourceTypeEnum {
|
|
|
135
136
|
APPLICATIONS = 'apps',
|
|
136
137
|
APPLICATIONS_APIS = 'apps.apis',
|
|
137
138
|
APPLICATIONS_PAGES = 'apps.pages',
|
|
139
|
+
BILLING = 'billing',
|
|
138
140
|
FOLDERS = 'folders',
|
|
139
141
|
GROUPS = 'groups',
|
|
140
142
|
GROUPS_MEMBERS = 'groups.members',
|
|
@@ -187,6 +189,9 @@ export const ActionTypeByResourceType = {
|
|
|
187
189
|
READ: ActionTypeEnum.READ,
|
|
188
190
|
MANAGE: ActionTypeEnum.MANAGE
|
|
189
191
|
},
|
|
192
|
+
BILLING: {
|
|
193
|
+
MANAGE: ActionTypeEnum.MANAGE
|
|
194
|
+
},
|
|
190
195
|
WORKFLOWS: {
|
|
191
196
|
DEPLOY: ActionTypeEnum.DEPLOY,
|
|
192
197
|
DELETE: ActionTypeEnum.DELETE,
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
buildAttachmentUploadMetadata,
|
|
4
|
+
buildAttachmentUploadFormData,
|
|
5
|
+
createUploadedAttachmentFromServer,
|
|
6
|
+
normalizeAttachmentMimeType,
|
|
7
|
+
toAttachmentUploadDescriptor
|
|
8
|
+
} from './attachment-upload.js';
|
|
9
|
+
|
|
10
|
+
describe('toAttachmentUploadDescriptor', () => {
|
|
11
|
+
test('preserves explicit names for non-File uploads', () => {
|
|
12
|
+
const descriptor = toAttachmentUploadDescriptor({
|
|
13
|
+
data: 'data:image/webp;base64,Zm9v',
|
|
14
|
+
mimeType: 'image/webp',
|
|
15
|
+
name: 'capture.webp'
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
expect(descriptor).toMatchObject({
|
|
19
|
+
fileName: 'capture.webp',
|
|
20
|
+
mimeType: 'image/webp'
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('falls back to mime-derived filenames for unnamed non-File uploads', () => {
|
|
25
|
+
const descriptor = toAttachmentUploadDescriptor({
|
|
26
|
+
data: 'data:application/pdf;base64,Zm9v',
|
|
27
|
+
mimeType: 'application/pdf'
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
expect(descriptor).toMatchObject({
|
|
31
|
+
fileName: 'attachment.pdf',
|
|
32
|
+
mimeType: 'application/pdf'
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('normalizes browser ts mime types from filename when they are not text-like', () => {
|
|
37
|
+
const descriptor = toAttachmentUploadDescriptor(new File(['const answer = 42;'], 'main.ts', { type: 'video/mp2t' }));
|
|
38
|
+
|
|
39
|
+
expect(descriptor).toMatchObject({
|
|
40
|
+
fileName: 'main.ts',
|
|
41
|
+
mimeType: 'text/plain'
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('buildAttachmentUploadFormData', () => {
|
|
47
|
+
test('appends the normalized filename to form data', () => {
|
|
48
|
+
const descriptor = toAttachmentUploadDescriptor({
|
|
49
|
+
data: 'data:image/webp;base64,Zm9v',
|
|
50
|
+
mimeType: 'image/webp',
|
|
51
|
+
name: 'capture.webp'
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
expect(descriptor).not.toBeNull();
|
|
55
|
+
|
|
56
|
+
const formData = buildAttachmentUploadFormData({
|
|
57
|
+
descriptor: descriptor!,
|
|
58
|
+
prefix: 'captured-screenshot'
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const uploadedFile = formData.get('file');
|
|
62
|
+
expect(uploadedFile).toBeInstanceOf(File);
|
|
63
|
+
expect((uploadedFile as File).name).toBe('capture.webp');
|
|
64
|
+
expect(formData.get('prefix')).toBe('captured-screenshot');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('appends serialized metadata when provided', () => {
|
|
68
|
+
const descriptor = toAttachmentUploadDescriptor({
|
|
69
|
+
data: 'data:text/plain;base64,Zm9v',
|
|
70
|
+
mimeType: 'text/plain',
|
|
71
|
+
name: 'notes.txt'
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
expect(descriptor).not.toBeNull();
|
|
75
|
+
|
|
76
|
+
const formData = buildAttachmentUploadFormData({
|
|
77
|
+
descriptor: descriptor!,
|
|
78
|
+
prefix: 'message-attachment',
|
|
79
|
+
metadata: buildAttachmentUploadMetadata({
|
|
80
|
+
label: 'Error screenshot',
|
|
81
|
+
insight: 'Shows a missing submit button'
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(formData.get('metadata')).toBe(
|
|
86
|
+
JSON.stringify({
|
|
87
|
+
label: 'Error screenshot',
|
|
88
|
+
insight: 'Shows a missing submit button'
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('createUploadedAttachmentFromServer', () => {
|
|
95
|
+
test('falls back to the original mime type when the server omits one', () => {
|
|
96
|
+
const uploadedAttachment = createUploadedAttachmentFromServer({
|
|
97
|
+
response: {
|
|
98
|
+
attachmentId: '123',
|
|
99
|
+
fileName: '',
|
|
100
|
+
contentUrl: '/api/v1/files/content/123',
|
|
101
|
+
mimeType: null,
|
|
102
|
+
purpose: 'attachment',
|
|
103
|
+
scopeType: 'app',
|
|
104
|
+
signedUrl: 'https://signed.example/123',
|
|
105
|
+
signedUrlExpiresAt: '2026-03-06T00:00:00.000Z',
|
|
106
|
+
storageKey: 'message-attachment/123'
|
|
107
|
+
},
|
|
108
|
+
fallbackFileName: 'spec.pdf',
|
|
109
|
+
fallbackMimeType: 'application/pdf',
|
|
110
|
+
label: 'Spec',
|
|
111
|
+
insight: 'Reference doc'
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
expect(uploadedAttachment).toEqual({
|
|
115
|
+
type: 'uploaded',
|
|
116
|
+
url: '/api/v1/files/content/123',
|
|
117
|
+
signedUrl: 'https://signed.example/123',
|
|
118
|
+
mediaType: 'application/pdf',
|
|
119
|
+
fileName: 'spec.pdf',
|
|
120
|
+
label: 'Spec',
|
|
121
|
+
insight: 'Reference doc',
|
|
122
|
+
storageKey: 'message-attachment/123',
|
|
123
|
+
signedUrlExpiresAt: '2026-03-06T00:00:00.000Z',
|
|
124
|
+
scopeType: 'app',
|
|
125
|
+
applicationId: undefined
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe('buildAttachmentUploadMetadata', () => {
|
|
131
|
+
test('normalizes non-empty label and insight fields', () => {
|
|
132
|
+
expect(
|
|
133
|
+
buildAttachmentUploadMetadata({
|
|
134
|
+
label: 'Error screenshot',
|
|
135
|
+
insight: 'Shows a missing submit button'
|
|
136
|
+
})
|
|
137
|
+
).toEqual({
|
|
138
|
+
label: 'Error screenshot',
|
|
139
|
+
insight: 'Shows a missing submit button'
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe('normalizeAttachmentMimeType', () => {
|
|
145
|
+
test('prefers text-safe mime types for text-like filenames', () => {
|
|
146
|
+
expect(
|
|
147
|
+
normalizeAttachmentMimeType({
|
|
148
|
+
fileName: 'component.tsx',
|
|
149
|
+
mimeType: 'video/mp2t'
|
|
150
|
+
})
|
|
151
|
+
).toBe('text/plain');
|
|
152
|
+
});
|
|
153
|
+
});
|