Build for BASAL
One function. The graph gets smarter.
Write one function. BASAL compounds it into intelligence for everyone.
$ basal scaffold --lens team-health
✓ Created marketplace/team-health
✓ Tests pass
✓ Ready to runimport { define } from '@basal/sdk'
export default define({
id: 'team-health',
version: '0.1.0',
description: 'Who delivers, who slips',
lens: {
projections: [{
id: 'velocity',
name: 'Team Velocity',
parameters: {
days: { type: 'number', default: 7 },
},
run: async (ctx) => {
return await ctx.graph.read(`
MATCH (p:Person)-[:SUBJECT_OF]->(f:Fact)
WHERE f.lifecycleState = 'active'
RETURN p.name, count(f) AS facts
ORDER BY facts DESC
`)
},
}],
},
})→ basal lens run team-health
Person Facts
─────────────────────────
Sarah Chen 47
James Kumar 31
Priya Osei 28
Daniel Reeves 12 ⚠ declining
That's it. One function. The graph answers.
Start from a template
NOW Intelligence
Daily briefing — what changed, what's due, what needs attention.
Lens · View source →
FIBO Finance
Financial vocabulary — securities, portfolios, risk exposures.
Domain · View source →
Discourse Analysis
Detect commitments, objections, and proposals in meetings.
Refine · View source →
10 apps in the marketplace. Read the code, learn the patterns, build your own.
Browse all appsWhat do you want BASAL to do?
Query the graph
Read-only intelligence views. Cypher queries in, structured insight out.
Lens · Easy · ctx.graph.read()
Connect a source
Bring data from Slack, GitHub, Notion, or any API.
Connect · Medium · SourceAdapter
Teach a domain
Entity types, vocabulary, causal mechanisms for your field.
Domain · Hard · activationPolicy
Enrich extraction
Detect patterns, boost confidence, inject hints before extraction.
Refine · Hard · SignalAdapter
Run on schedule
Cron jobs that maintain and improve the graph. Governed writes.
Routine · Medium · ctx.graph.write()
Orchestrate agents
Multi-agent deliberation with phases, rosters, and outcomes.
Lens
Read-only. No side effects. Start here.
Every projection is automatically an MCP tool — external agents can query it.
basal scaffold --lens my-lensrun: async (ctx) => {
return await ctx.graph.read(`
MATCH (p:Person)-[:SUBJECT_OF]->(f:Fact)
WHERE f.type IN [
'CommitmentFulfilled',
'CommitmentSlipped'
]
AND f.lifecycleState = 'active'
RETURN p.name AS person,
f.type AS outcome,
count(*) AS count
ORDER BY count DESC
`)
}Connect
Fetch from external APIs, convert to BASAL's document format.
basal scaffold --connect my-sourceconnect: {
sources: [{
id: 'slack-sync',
sync: async (ctx) => {
// ctx.oauth, ctx.paginate built in
return { documents: [...] }
},
}],
converters: [{
id: 'slack-msg',
contentTypes: ['slack-message'],
convert: async (input) => {
return { markdown: '...', metadata: {} }
},
}],
}Refine
Detect patterns in extracted data. Boost confidence. Inject hints before extraction runs. Pair with a Domain pack.
basal scaffold --refine my-signalsrefine: {
signals: [{
id: 'commitment-detector',
detect: async (ctx) => {
const signals = []
for (const fact of ctx.extraction.facts) {
if (fact.evidenceSpan?.match(
/I('ll| will) (handle|take care)/i
)) {
signals.push({
type: 'CommittedTo',
entity: fact.subject,
Domain
Entity types, relationships, vocabulary, causal mechanisms. When BASAL speaks your domain's language, everything gets smarter.
basal scaffold --domain my-packdomain: {
standard: 'FIBO',
entityTypes: [
{ name: 'SecurityInstrument',
description: 'Tradeable financial asset' },
],
vocabulary: {
mappings: {
'equity': 'SecurityInstrument',
'bond': 'SecurityInstrument',
},
},
activationPolicy: {
scope: { sourceTypes: ['sec-filing'] },
weight: 0.8,
},
Routine
Cron jobs and event-driven functions. Governed writes — every mutation declares its class.
basal scaffold --routine my-routineroutine: {
functions: [{
id: 'stale-cleanup',
name: 'Stale Contact Cleanup',
trigger: { type: 'cron',
schedule: '0 3 * * 0' },
handler: async (ctx) => {
const stale = await ctx.graph.read(`
MATCH (p:Person)
WHERE p.lastSeenAt < datetime()
- duration('P90D')
RETURN p.uuid, p.name
`)
for (const row of stale.rows) {
Council
Multi-agent deliberation. Phases, rosters, outcomes. The richest SDK — and the hardest to get right.
basal scaffold --council my-protocolcouncil: {
protocols: [{
id: 'red-team',
name: 'Red Team Review',
phases: [
{ id: 'attack', name: 'Attack',
duration: '10m' },
{ id: 'defend', name: 'Defend',
duration: '10m' },
{ id: 'synthesis', name: 'Synthesis',
duration: '5m' },
],
}],
rosters: [{
id: 'diverse-team',
strategy:
The SDK
import { define, WriteClass } from '@basal/sdk'| What | How |
|---|---|
| Read the graph | ctx.graph.read(cypher) |
| Write with governance | ctx.graph.write(cypher, params, WriteClass.B) |
| Call LLMs | ctx.llm.chat(messages) |
| Emit telemetry | ctx.observe(metrics) |
| Test without infra | import { createTestGraph } from '@basal/sdk/testing' |