← Files Lauki SIP CalculatorARCHIVED FILE

src/core/types.ts

3.23 KB · Nov 5, 2026 · 01:00 UTC

↓ Download file

// Shared types for every plugin built from this template.
export type Json = null | boolean | number | string | Json[] | { [k: string]: Json }
export type JsonObject = { [k: string]: Json }

/** JSON Schema subset the runtime validates: type, enum, required, properties,
 * additionalProperties:false, minimum/maximum, minLength/maxLength, pattern, items, minItems/maxItems. */
export type Schema = {
  type?: 'object' | 'string' | 'number' | 'integer' | 'boolean' | 'array'
  description?: string
  enum?: (string | number)[]
  properties?: Record<string, Schema>
  required?: string[]
  additionalProperties?: boolean
  minimum?: number
  maximum?: number
  minLength?: number
  maxLength?: number
  pattern?: string
  format?: string
  items?: Schema
  minItems?: number
  maxItems?: number
  default?: Json
}

/** The generic card every widget renders. Tools return { card, ...data } as structuredContent. */
export type Card = {
  title: string
  subtitle?: string
  highlight?: { label: string; value: string }
  rows?: [string, string][]
  sections?: { heading: string; rows: [string, string][] }[]
  chips?: string[]
  table?: { columns: string[]; rows: string[][] }
  note?: string
  link?: { label: string; url: string }
}

export type ToolResult = { text: string; card?: Card; data?: JsonObject }

export type ToolDef = {
  name: string
  title: string
  /** Must start "Use this when..." and contain "Do not use for..." (enforced by tests). */
  description: string
  inputSchema: Schema
  /** Read-only lookups/calculators: readOnlyHint true, destructiveHint false, openWorldHint false. */
  annotations?: { readOnlyHint?: boolean; destructiveHint?: boolean; openWorldHint?: boolean; idempotentHint?: boolean }
  invoking?: string
  invoked?: string
  /** Render the shared card widget for this tool (default true). */
  widget?: boolean
  /** Sample arguments used by scripts/smoke.mjs and tests. At least one per tool. */
  samples: JsonObject[]
  /** env = the Worker bindings (KV/R2/vars from wrangler.toml); undefined in unit tests. Large datasets (IFSC, PIN) live in KV, not the bundle. */
  run: (args: any, env?: Record<string, any>) => ToolResult | Promise<ToolResult>
}

export type PluginConfig = {
  slug: string // kebab-case, also the worker name stem and repo name
  name: string // display name in the directory, no "Plugin"/"MCP" suffix
  version: string
  shortDescription: string // <= 120 chars, plugin.json extensions.com.openai.description
  longDescription: string // plugin.json description
  funnel: {
    origin: string // e.g. https://naksha.social
    campaign: string // utm_campaign, e.g. naksha_panchang
    label: string // default CTA label in the card
    path?: string // default landing path
  }
  privacy: {
    dataProcessed: string[] // what inputs are processed (in memory)
    thirdParties: string[] // outbound network calls at runtime; [] for pure compute
    attributions: string[] // data licences, e.g. GeoNames CC BY 4.0
    contact: string
    operator?: string // legal entity named on the brand policy, e.g. 'Upsurge Labs Pte. Ltd., Singapore'
    minAge?: number // default 13; brands with an 18+ service set 18
    fullPolicyUrl?: string // brand policy section that this app page belongs to
  }
  widgetDescription: string
  tools: ToolDef[]
}

SHA-256: c01502fe54204a788ec1ba3e88a3dfec25ba92bc9aaf913ba91c039a948dadf7