chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
import type { KetchGetConsentParams, KetchGetConsentResponse } from '@/tools/ketch/types'
import { CONSENT_PURPOSE_OUTPUT_PROPERTIES } from '@/tools/ketch/types'
import type { ToolConfig } from '@/tools/types'
export const getConsentTool: ToolConfig<KetchGetConsentParams, KetchGetConsentResponse> = {
id: 'ketch_get_consent',
name: 'Ketch Get Consent',
description:
'Retrieve consent status for a data subject. Returns the current consent preferences for each configured purpose.',
version: '1.0.0',
params: {
organizationCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Ketch organization code',
},
propertyCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Digital property code defined in Ketch',
},
environmentCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Environment code defined in Ketch (e.g., "production")',
},
jurisdictionCode: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Jurisdiction code (e.g., "gdpr", "ccpa")',
},
identities: {
type: 'json',
required: true,
visibility: 'user-or-llm',
description: 'Identity map (e.g., {"email": "user@example.com"})',
},
purposes: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description: 'Optional purposes to filter the consent query',
},
},
request: {
url: (params) =>
`https://global.ketchcdn.com/web/v2/consent/${encodeURIComponent(params.organizationCode.trim())}/get`,
method: 'POST',
headers: () => ({
Accept: 'application/json',
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
organizationCode: params.organizationCode.trim(),
propertyCode: params.propertyCode,
environmentCode: params.environmentCode,
identities: params.identities,
}
if (params.jurisdictionCode) body.jurisdictionCode = params.jurisdictionCode
if (params.purposes) body.purposes = params.purposes
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
let errorMessage = `Request failed with status ${response.status}`
try {
const data = await response.json()
errorMessage = data.message ?? data.error ?? errorMessage
} catch {
// No JSON body in error response
}
return {
success: false,
output: {
error: errorMessage,
purposes: {},
vendors: null,
},
}
}
const data = await response.json()
return {
success: true,
output: {
purposes: data.purposes ?? {},
vendors: data.vendors ?? null,
},
}
},
outputs: {
purposes: {
type: 'object',
description: 'Map of purpose codes to consent status and legal basis',
properties: CONSENT_PURPOSE_OUTPUT_PROPERTIES,
},
vendors: {
type: 'object',
description: 'Map of vendor consent statuses',
optional: true,
},
},
}
+101
View File
@@ -0,0 +1,101 @@
import type {
KetchGetSubscriptionsParams,
KetchGetSubscriptionsResponse,
} from '@/tools/ketch/types'
import type { ToolConfig } from '@/tools/types'
export const getSubscriptionsTool: ToolConfig<
KetchGetSubscriptionsParams,
KetchGetSubscriptionsResponse
> = {
id: 'ketch_get_subscriptions',
name: 'Ketch Get Subscriptions',
description:
'Retrieve subscription preferences for a data subject. Returns the current subscription topic and control statuses.',
version: '1.0.0',
params: {
organizationCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Ketch organization code',
},
propertyCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Digital property code defined in Ketch',
},
environmentCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Environment code defined in Ketch (e.g., "production")',
},
identities: {
type: 'json',
required: true,
visibility: 'user-or-llm',
description: 'Identity map (e.g., {"email": "user@example.com"})',
},
},
request: {
url: (params) =>
`https://global.ketchcdn.com/web/v2/subscriptions/${encodeURIComponent(params.organizationCode.trim())}/get`,
method: 'POST',
headers: () => ({
Accept: 'application/json',
'Content-Type': 'application/json',
}),
body: (params) => ({
organizationCode: params.organizationCode.trim(),
propertyCode: params.propertyCode,
environmentCode: params.environmentCode,
identities: params.identities,
}),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
let errorMessage = `Request failed with status ${response.status}`
try {
const data = await response.json()
errorMessage = data.message ?? data.error ?? errorMessage
} catch {
// No JSON body in error response
}
return {
success: false,
output: {
error: errorMessage,
topics: {},
controls: {},
},
}
}
const data = await response.json()
return {
success: true,
output: {
topics: data.topics ?? {},
controls: data.controls ?? {},
},
}
},
outputs: {
topics: {
type: 'object',
description:
'Map of topic codes to contact method settings (e.g., {"newsletter": {"email": {"status": "granted"}}})',
},
controls: {
type: 'object',
description:
'Map of control codes to settings (e.g., {"global_unsubscribe": {"status": "denied"}})',
},
},
}
+11
View File
@@ -0,0 +1,11 @@
import { getConsentTool } from '@/tools/ketch/get_consent'
import { getSubscriptionsTool } from '@/tools/ketch/get_subscriptions'
import { invokeRightTool } from '@/tools/ketch/invoke_right'
import { setConsentTool } from '@/tools/ketch/set_consent'
import { setSubscriptionsTool } from '@/tools/ketch/set_subscriptions'
export const ketchGetConsentTool = getConsentTool
export const ketchSetConsentTool = setConsentTool
export const ketchInvokeRightTool = invokeRightTool
export const ketchGetSubscriptionsTool = getSubscriptionsTool
export const ketchSetSubscriptionsTool = setSubscriptionsTool
+123
View File
@@ -0,0 +1,123 @@
import type { KetchInvokeRightParams, KetchInvokeRightResponse } from '@/tools/ketch/types'
import type { ToolConfig } from '@/tools/types'
export const invokeRightTool: ToolConfig<KetchInvokeRightParams, KetchInvokeRightResponse> = {
id: 'ketch_invoke_right',
name: 'Ketch Invoke Right',
description:
'Submit a data subject rights request (e.g., access, delete, correct, restrict processing). Initiates a privacy rights workflow in Ketch.',
version: '1.0.0',
params: {
organizationCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Ketch organization code',
},
propertyCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Digital property code defined in Ketch',
},
environmentCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Environment code defined in Ketch (e.g., "production")',
},
jurisdictionCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Jurisdiction code (e.g., "gdpr", "ccpa")',
},
rightCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'Privacy right code to invoke (e.g., "access", "delete", "correct", "restrict_processing")',
},
identities: {
type: 'json',
required: true,
visibility: 'user-or-llm',
description: 'Identity map (e.g., {"email": "user@example.com"})',
},
userData: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description:
'Optional data subject information (e.g., {"email": "user@example.com", "firstName": "John", "lastName": "Doe"})',
},
},
request: {
url: (params) =>
`https://global.ketchcdn.com/web/v2/rights/${encodeURIComponent(params.organizationCode.trim())}/invoke`,
method: 'POST',
headers: () => ({
Accept: 'application/json',
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
organizationCode: params.organizationCode.trim(),
propertyCode: params.propertyCode,
environmentCode: params.environmentCode,
jurisdictionCode: params.jurisdictionCode,
rightCode: params.rightCode,
identities: params.identities,
}
if (params.userData) body.user = params.userData
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
let errorMessage = `Request failed with status ${response.status}`
try {
const data = await response.json()
errorMessage = data.message ?? data.error ?? errorMessage
} catch {
// No JSON body in error response
}
return {
success: false,
output: {
success: false,
message: errorMessage,
},
}
}
let message: string | null = null
try {
const data = await response.json()
message = data.message ?? null
} catch {
// 204 No Content - no body to parse
}
return {
success: true,
output: {
success: true,
message,
},
}
},
outputs: {
success: { type: 'boolean', description: 'Whether the rights request was submitted' },
message: {
type: 'string',
description: 'Response message from Ketch',
optional: true,
},
},
}
+123
View File
@@ -0,0 +1,123 @@
import type { KetchSetConsentParams, KetchSetConsentResponse } from '@/tools/ketch/types'
import { CONSENT_PURPOSE_OUTPUT_PROPERTIES } from '@/tools/ketch/types'
import type { ToolConfig } from '@/tools/types'
export const setConsentTool: ToolConfig<KetchSetConsentParams, KetchSetConsentResponse> = {
id: 'ketch_set_consent',
name: 'Ketch Set Consent',
description:
'Update consent preferences for a data subject. Sets the consent status for specified purposes with the appropriate legal basis.',
version: '1.0.0',
params: {
organizationCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Ketch organization code',
},
propertyCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Digital property code defined in Ketch',
},
environmentCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Environment code defined in Ketch (e.g., "production")',
},
jurisdictionCode: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Jurisdiction code (e.g., "gdpr", "ccpa")',
},
identities: {
type: 'json',
required: true,
visibility: 'user-or-llm',
description: 'Identity map (e.g., {"email": "user@example.com"})',
},
purposes: {
type: 'json',
required: true,
visibility: 'user-or-llm',
description:
'Map of purpose codes to consent settings (e.g., {"analytics": {"allowed": "granted", "legalBasisCode": "consent_optin"}})',
},
collectedAt: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'UNIX timestamp when consent was collected (defaults to current time)',
},
},
request: {
url: (params) =>
`https://global.ketchcdn.com/web/v2/consent/${encodeURIComponent(params.organizationCode.trim())}/update`,
method: 'POST',
headers: () => ({
Accept: 'application/json',
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
organizationCode: params.organizationCode.trim(),
propertyCode: params.propertyCode,
environmentCode: params.environmentCode,
identities: params.identities,
purposes: params.purposes,
collectedAt: params.collectedAt ?? Math.floor(Date.now() / 1000),
}
if (params.jurisdictionCode) body.jurisdictionCode = params.jurisdictionCode
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
let errorMessage = `Request failed with status ${response.status}`
try {
const data = await response.json()
errorMessage = data.message ?? data.error ?? errorMessage
} catch {
// No JSON body in error response
}
return {
success: false,
output: {
error: errorMessage,
purposes: {},
},
}
}
if (response.status === 204) {
return {
success: true,
output: {
purposes: {},
},
}
}
const data = await response.json()
return {
success: true,
output: {
purposes: data.purposes ?? {},
},
}
},
outputs: {
purposes: {
type: 'object',
description: 'Updated consent status map of purpose codes to consent settings',
properties: CONSENT_PURPOSE_OUTPUT_PROPERTIES,
},
},
}
+111
View File
@@ -0,0 +1,111 @@
import type {
KetchSetSubscriptionsParams,
KetchSetSubscriptionsResponse,
} from '@/tools/ketch/types'
import type { ToolConfig } from '@/tools/types'
export const setSubscriptionsTool: ToolConfig<
KetchSetSubscriptionsParams,
KetchSetSubscriptionsResponse
> = {
id: 'ketch_set_subscriptions',
name: 'Ketch Set Subscriptions',
description:
'Update subscription preferences for a data subject. Sets topic and control statuses for email, SMS, and other contact methods.',
version: '1.0.0',
params: {
organizationCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Ketch organization code',
},
propertyCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Digital property code defined in Ketch',
},
environmentCode: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Environment code defined in Ketch (e.g., "production")',
},
identities: {
type: 'json',
required: true,
visibility: 'user-or-llm',
description: 'Identity map (e.g., {"email": "user@example.com"})',
},
topics: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description:
'Map of topic codes to contact method settings (e.g., {"newsletter": {"email": {"status": "granted"}, "sms": {"status": "denied"}}})',
},
controls: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description:
'Map of control codes to settings (e.g., {"global_unsubscribe": {"status": "denied"}})',
},
},
request: {
url: (params) =>
`https://global.ketchcdn.com/web/v2/subscriptions/${encodeURIComponent(params.organizationCode.trim())}/update`,
method: 'POST',
headers: () => ({
Accept: 'application/json',
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
organizationCode: params.organizationCode.trim(),
propertyCode: params.propertyCode,
environmentCode: params.environmentCode,
identities: params.identities,
}
if (params.topics) body.topics = params.topics
if (params.controls) body.controls = params.controls
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
let errorMessage = `Request failed with status ${response.status}`
try {
const data = await response.json()
errorMessage = data.message ?? data.error ?? errorMessage
} catch {
// No JSON body in error response
}
return {
success: false,
output: {
error: errorMessage,
success: false,
},
}
}
return {
success: true,
output: {
success: true,
},
}
},
outputs: {
success: {
type: 'boolean',
description: 'Whether the subscription preferences were updated',
},
},
}
+117
View File
@@ -0,0 +1,117 @@
import type { OutputProperty, ToolResponse } from '@/tools/types'
/**
* Shared output property definitions for Ketch API responses.
* Based on Ketch Web API: https://github.com/ketch-sdk/ketch-web-api
* Types reference: https://github.com/ketch-sdk/ketch-types
*/
export const CONSENT_PURPOSE_OUTPUT_PROPERTIES = {
allowed: {
type: 'string',
description: 'Consent status for the purpose: "granted" or "denied"',
},
legalBasisCode: {
type: 'string',
description:
'Legal basis code (e.g., "consent_optin", "consent_optout", "disclosure", "other")',
optional: true,
},
} as const satisfies Record<string, OutputProperty>
export interface KetchGetConsentParams {
organizationCode: string
propertyCode: string
environmentCode: string
jurisdictionCode?: string
identities: Record<string, string>
purposes?: Record<string, Record<string, unknown>>
}
export interface KetchGetConsentResponse extends ToolResponse {
output: {
purposes: Record<string, { allowed: string; legalBasisCode?: string }>
vendors: Record<string, string> | null
}
}
export interface KetchSetConsentParams {
organizationCode: string
propertyCode: string
environmentCode: string
jurisdictionCode?: string
identities: Record<string, string>
purposes: Record<string, { allowed: string; legalBasisCode?: string }>
collectedAt?: number
}
export interface KetchSetConsentResponse extends ToolResponse {
output: {
purposes: Record<string, { allowed: string; legalBasisCode?: string }>
}
}
export interface KetchInvokeRightParams {
organizationCode: string
propertyCode: string
environmentCode: string
jurisdictionCode: string
rightCode: string
identities: Record<string, string>
userData?: {
email?: string
firstName?: string
lastName?: string
}
}
export interface KetchInvokeRightResponse extends ToolResponse {
output: {
success: boolean
message: string | null
}
}
interface SubscriptionControlSetting {
status: string
}
interface SubscriptionTopicContactMethodSetting {
status: string
}
export interface KetchGetSubscriptionsParams {
organizationCode: string
propertyCode: string
environmentCode: string
identities: Record<string, string>
}
export interface KetchGetSubscriptionsResponse extends ToolResponse {
output: {
topics: Record<string, Record<string, SubscriptionTopicContactMethodSetting>>
controls: Record<string, SubscriptionControlSetting>
}
}
export interface KetchSetSubscriptionsParams {
organizationCode: string
propertyCode: string
environmentCode: string
identities: Record<string, string>
topics?: Record<string, Record<string, SubscriptionTopicContactMethodSetting>>
controls?: Record<string, SubscriptionControlSetting>
}
export interface KetchSetSubscriptionsResponse extends ToolResponse {
output: {
success: boolean
}
}
export type KetchResponse =
| KetchGetConsentResponse
| KetchSetConsentResponse
| KetchInvokeRightResponse
| KetchGetSubscriptionsResponse
| KetchSetSubscriptionsResponse