一键导入
basil-development
Develop and test Basil web applications with HTTP handlers, routing, sessions, authentication, databases, and interactive components (Parts).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Develop and test Basil web applications with HTTP handlers, routing, sessions, authentication, databases, and interactive components (Parts).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Build and run a Basil server against a scratch site to observe changes at the real HTTP surface.
Run the project Definition of Done for the current unit of work and integrate it — build, test, verify, docs/changelog, commit, rebase, merge to main, push, and remove the worktree. Use when a piece of work is finished and should land on main. Merge model is direct-to-main (no PR).
How to write Parsley code for tests, examples and documentation.
| name | basil-development |
| description | Develop and test Basil web applications with HTTP handlers, routing, sessions, authentication, databases, and interactive components (Parts). |
Use when:
Use this skill when you need to:
Basil is a web framework for Parsley (the language):
Basil provides HTTP server, routing, sessions, auth, database, interactive components (Parts), and asset bundling.
# Initialize project
./basil --init myapp && cd myapp
# Run dev server (auto-reload, detailed errors, dev tools at /__dev/log)
./basil --dev
# Test
curl http://localhost:8080/
Parsley files that handle HTTP requests.
// site/index.pars
<html>
<body>
<h1>"Welcome!"</h1>
<p>`Search: {@params.q ?? 'none'}`</p>
</body>
</html>
server:
port: 8080
site:
path: ./site # Filesystem routing: site/about.pars → /about
database:
path: ./data.db # Database
session:
secret: "your-32-char-secret" # Required for sessions
.part files with functions that return HTML. Update without page reload.
// parts/counter.part
export default = fn(props) {
let count = props.count ?? 0
<div>
<p>`Count: {count}`</p>
<button part-click="increment" part-count={count + 1}>"++"</button>
</div>
}
export increment = fn(props) {
default(props) // Re-render with new count
}
Usage:
<Part src={@~/parts/counter.part} count={0}/>
Important: Parts need routes in basil.yaml:
routes:
- path: /parts/counter.part
handler: ./parts/counter.part
let {request, response, method} = import @basil/http
let {redirect} = import @std/api
@params // URL/form params: {id: "123"}
method // "GET", "POST", etc.
request.body // Request body (JSON auto-parsed)
request.path // "/api/users/123"
response.status = 404
redirect("/dashboard") // Returns redirect response
let {session, user} = import @basil/auth
// Sessions
session.set("cart", ["item1", "item2"])
let cart = session.get("cart", [])
session.flash("success", "Saved!") // Show-once message
// Current user (null if not logged in)
if (user) {
user.email
user.role // "admin", "user", etc.
}
@params // URL/form parameters
@DB // Server database (configured in basil.yaml)
@now // Current datetime
@env.HOME // Environment variables
// Use @DB magic variable for database access
let id = 123
let user = @DB <=?=> `SELECT * FROM users WHERE id = {id}` // One row
let users = @DB <=??=> "SELECT * FROM users" // All rows
let name = "Alice"
let result = @DB <=!=> `INSERT INTO users (name) VALUES ('{name}')` // Mutation
// See docs/basil/reference.md for complete database API
let users = @DB <=??=> "SELECT * FROM users ORDER BY name"
<html>
<body>
<ul>
for (user in users) {
<li>user.name</li>
}
</ul>
</body>
</html>
let {method} = import @basil/http
if (method == "GET") {
let users = @DB <=??=> "SELECT id, name FROM users"
{users: users}
} else if (method == "POST") {
let result = @DB <=!=> `INSERT INTO users (name) VALUES ('{@params.name}')`
let id = @DB.lastInsertId()
{id: id}
}
let {method, request} = import @basil/http
let {session} = import @basil/auth
let {redirect} = import @std/api
if (method == "POST") {
let form = request.form
// Process form...
session.flash("success", "Saved!")
redirect("/")
} else {
<form method="POST">
<input name="email" required/>
<button>"Submit"</button>
</form>
}
# GET
curl http://localhost:8080/
# With query params
curl "http://localhost:8080/search?q=test"
# POST form
curl -X POST http://localhost:8080/contact -d "name=Alice&email=alice@example.com"
# JSON API
curl http://localhost:8080/api/users -H "Content-Type: application/json" -d '{"name":"Alice"}'
# With cookies
curl -c cookies.txt http://localhost:8080/login -d "user=admin&pass=secret"
curl -b cookies.txt http://localhost:8080/dashboard
routes:security.allow_write in config./basil --init myapp # Create project
./basil --dev # Run dev server
./basil --dev --port 3000 # Custom port
server:
port: 8080
site:
path: ./site # Filesystem routing
database:
path: ./data.db # Database
session:
secret: "32-char-secret"
auth:
enabled: true
protected_paths: ["/admin"]
let {method, request, response} = import @basil/http
let {session, user} = import @basil/auth
let {redirect, notFound} = import @std/api
For comprehensive guides, see:
docs/basil/reference.md - Full language reference with all operators and builtinsdocs/parsley/CHEATSHEET.md and docs/parsley/reference.md./basil --dev for auto-reload and detailed errorshttp://localhost:8080/__dev/log for debugging./pars before using in handlers{data, error} pattern for error handling