Skip to content

@uriva/safeapp

0.2.2
Skill

Description

Build, deploy, and manage agent-native applications, dashboards, and internal tools on SafeApp..

Pending
tank install -g @uriva/safeapp

SafeApp Platform Skill

SafeApp (https://app.safescript.cc) is an agent-native, file-free, and git-free application platform where policy derives placement. Applications are collections of discrete Safescript functions stored in an entity store and manipulated via REST API (/api/v1/apps).

In SafeApp, the database IS the state — there is no double mechanism.

Canonical platform spec: https://app.safescript.cc/llms.txt. Safescript spec: https://safescript.cc/llms.txt.


âš¡ Quickstart for Agents (Build a Live Database App in 3 Steps)

Step 1: Create App

POST https://app.safescript.cc/api/v1/apps
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "id": "my-crm",
  "name": "My CRM",
  "title": "Lead Management Dashboard"
}

Returns { "ok": true, "previewUrl": "/preview/my-crm/main" }.

Step 2: Push Real Data Directly (Data REST API)

Push data directly into the app's provisioned database via standard HTTP without boilerplate code:

POST https://app.safescript.cc/api/v1/apps/my-crm/data/leads
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "items": [
    { "company": "Wix", "contactName": "Dana", "status": "New", "phone": "050-1234567" },
    { "company": "Amdocs", "contactName": "Michal", "status": "Contacted", "phone": "052-7654321" }
  ]
}

Query data anytime with GET https://app.safescript.cc/api/v1/apps/my-crm/data/leads.

Step 3: Define UI (render Only)

No initialState() needed. The UI queries the database directly with dbQuery:

POST https://app.safescript.cc/api/v1/apps/my-crm/functions
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "updates": {
    "render": "(): { tag: string } => {
      leads = dbQuery({ namespace: \"leads\" }).items
      return {
        tag: \"card\",
        title: \"Leads Dashboard\",
        children: [
          { tag: \"table\", props: { columns: [\"company\", \"contactName\", \"status\", \"phone\"], rows: leads } }
        ]
      }
    }"
  },
  "summary": "Display leads from database in a table"
}

Live SSR & client SPA immediately available at https://app.safescript.cc/preview/my-crm/main!


1. Authentication & Setup (Zero Setup / No Email Required)

Base URL: https://app.safescript.cc Authentication Header: Authorization: Bearer <TOKEN> or x-safeapp-token: <TOKEN>.

Instant Guest Admin Token

Agents can obtain a master admin session instantly without human email interaction:

POST https://app.safescript.cc/api/v1/auth/guest
Content-Type: application/json
{}

Response: { "ok": true, "token": "sa_guest_...", "account": { "id": "guest-...", "isGuest": true } }

Use this bearer token for all subsequent platform API calls.


2. Application Lifecycle & Function Updates (Zero Files on Disk)

A. Scaffold Application

POST https://app.safescript.cc/api/v1/apps
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "id": "my-dashboard",
  "name": "My Dashboard",
  "title": "Business Operations Dashboard",
  "isPrivate": false
}
  • Set "isPrivate": true for internal tools or CRMs to activate the Turnkey Hosted Login Page, preventing any data leak to unauthenticated visitors without needing custom login Safescript code.

B. Deploy & Delete Functions

Deploy discrete named Safescript functions directly (or delete unused functions by setting their value to null or passing "deleteFunctions": ["oldFn"]):

POST https://app.safescript.cc/api/v1/apps/:appId/functions
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "updates": {
    "render": "(): { tag: string } => { return { tag: \"card\", title: \"Leads\", children: [...] } }",
    "obsoleteHelper": null
  },
  "summary": "Implement realtime leads dashboard"
}

The application contract:

  1. render() (or render(state)): Required. Returns a View ADT tree.
  2. update(state, action, payload): Optional. Handles dispatched user actions and mutates data via dbTransact.
  3. initialState(): Optional. Transient UI state (e.g. tabs or search input). If omitted, defaults to {}.

3. Real Database & Data Management

Every SafeApp automatically allocates a dedicated, isolated realtime relational database instance (InstantDB).

A. Direct Data REST API (Agent Access)

Push or query records directly over HTTP:

  • POST /api/v1/apps/:appId/data/:namespace with { "items": [ ... ] } or [ ... ]
  • GET /api/v1/apps/:appId/data/:namespace with optional query filters ?status=New

B. In Safescript Application Code

  • Query real records (dbQuery):
    items = dbQuery({ namespace: "leads", where: { status: "Active" } }).items
    
  • Insert / Update real records (dbTransact):
    result = dbTransact({
      namespace: "leads",
      id: leadId,
      patch: { name: "ACME Corp", status: "Active", value: 15000 }
    })
    

B. Seed Real Data from the Agent via Server Run

Agents can seed or query database records directly by executing any server function:

POST https://app.safescript.cc/api/v1/apps/:appId/branches/:branch/run
Authorization: Bearer <adminToken>
Content-Type: application/json

{
  "functionName": "seedInitialData",
  "args": { "count": 10 }
}

C. Database Rules & Schema Inspection

  • Inspect / Update Rules:
    • GET /api/v1/apps/:appId/resources/database/rules
    • POST /api/v1/apps/:appId/resources/database/rules with { "rules": { "leads": { "allow": { "view": "true", "create": "auth.id != null" } } } }
  • Inspect / Update Schema:
    • GET /api/v1/apps/:appId/resources/database/schema
    • POST /api/v1/apps/:appId/resources/database/schema with { "schema": { "leads": { "name": "string", "status": "string" } } }

4. Built-in Semantic UI Component Primitives

SafeApp provides pre-styled, dark-mode semantic component primitives out of the box. No CSS boilerplate required:

  • Card (tag: "card"): Container with title and subtitle: { tag: "card", title: "Active Pipeline", subtitle: "Q3 High Value Deals", children: [ ... ] }
  • Table (tag: "table"): Declarative data table accepting columns and rows directly: { tag: "table", props: { columns: ["Name", "Status", "Value"], rows: state.leads } } Rows can be objects matching column names or arrays of cells.
  • Badge (tag: "badge"): Status badge supporting variants (success, warning, danger, info, neutral): { tag: "badge", attrs: { variant: "success" }, text: "Active" }
  • Stat Metric (tag: "stat"): Metric block: { tag: "stat", label: "Monthly Revenue", value: "$45,200" }
  • Raw HTML (tag: "raw_html" or { html: "..." }): Embed raw HTML directly: { tag: "raw_html", html: "<div class='chart-container'>...</div>" }
  • Event Bindings (on: { click, change, input, submit } or onclick="fnName(...)"): Bind UI events directly to named Safescript functions (client or server RPC) or update(state, action, payload):
    • on: { click: "selectLead" } with attrs: { "data-payload": lead.id } (or inline onclick="selectLead('lead-1')").
    • on: { change: "setFilter" } on <select> or on: { input: "setSearch" } on <input> (preserves focus across re-renders).
    • on: { submit: "createLead" } on <form> (automatically serializes all <input name="..."> fields into a payload object).

5. Previews, Authentication & Merge

A. Preview URLs

  • Public/Private App Preview: https://app.safescript.cc/preview/:appId/:branch
  • Authenticated Preview: https://app.safescript.cc/preview/:appId/:branch?auth_token=<token>

B. Headless User Token Minting (For Agent Testing)

Mint an authenticated app end-user token without needing an email verification inbox:

POST https://app.safescript.cc/api/v1/apps/:appId/auth/token
Authorization: Bearer <adminToken>
Content-Type: application/json

{ "email": "[email protected]" }

Returns: { "ok": true, "token": "<userToken>", "user": { "id": "...", "email": "..." } }.

C. Self-Verification & Branch Merge

  • Run Unit Tests: POST https://app.safescript.cc/api/v1/apps/:appId/branches/:branch/test
  • Autonomous Policy-Gated Merge: POST https://app.safescript.cc/api/v1/apps/:appId/branches/:branch/merge Body: { "targetBranch": "main" } Merges automatically if all branch tests pass and no secret leaks or unallowlisted network sinks are introduced.

Command Palette

Search packages, docs, and navigate Tank