til

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

til

TIL

Capture and manage "Today I Learned" entries on OpenTIL -- from drafting to publishing, all within the CLI.
在OpenTIL上捕获和管理「今日所学(Today I Learned)」条目——从起草到发布,全程在CLI内完成。

Setup

设置

  1. Go to https://opentil.ai/dashboard/settings/tokens and create a Personal Access Token with
    read:entries
    ,
    write:entries
    , and
    delete:entries
    scopes
  2. Copy the token (starts with
    til_
    )
  3. Set the environment variable:
bash
export OPENTIL_TOKEN="til_xxx"
  1. 访问https://opentil.ai/dashboard/settings/tokens,创建一个拥有`read:entries`、`write:entries`和`delete:entries`权限的个人访问令牌
  2. 复制该令牌(以
    til_
    开头)
  3. 设置环境变量:
bash
export OPENTIL_TOKEN="til_xxx"

Token Resolution

令牌解析顺序

Token resolution order:
  1. $OPENTIL_TOKEN
    environment variable
  2. ~/.til/credentials
    file (created by
    /til auth
    )
If neither is set, entries are saved locally to
~/.til/drafts/
.
令牌解析优先级:
  1. $OPENTIL_TOKEN
    环境变量
  2. ~/.til/credentials
    文件(由
    /til auth
    命令创建)
如果两者都未设置,条目将本地保存到
~/.til/drafts/
目录。

Subcommand Routing

子命令路由

The first word after
/til
determines the action. Reserved words route to management subcommands; anything else is treated as content to capture.
InvocationAction
/til list [drafts|published|all]
List entries (default: drafts)
/til publish [<id> | last]
Publish an entry
/til unpublish <id>
Unpublish (revert to draft)
/til edit <id> [instructions]
AI-assisted edit
/til search <keyword>
Search entries by title
/til delete <id>
Delete entry (with confirmation)
/til status
Show site status and connection info
/til sync
Sync local drafts to OpenTIL
/til tags
List site tags with usage counts
/til categories
List site categories
/til batch <topics>
Batch-capture multiple TIL entries
/til auth
Connect OpenTIL account (browser auth)
/til <anything else>
Capture content as a new TIL
/til
Extract insights from conversation (multi-candidate)
Reserved words:
list
,
publish
,
unpublish
,
edit
,
search
,
delete
,
status
,
sync
,
tags
,
categories
,
batch
,
auth
.
/til
后的第一个单词决定执行的操作。保留字会路由到管理子命令;其他任何内容都将被视为要捕获的条目内容。
调用方式操作
/til list [drafts|published|all]
列出条目(默认:草稿)
/til publish [<id> | last]
发布条目
/til unpublish <id>
取消发布(恢复为草稿)
/til edit <id> [instructions]
AI辅助编辑
/til search <keyword>
按标题搜索条目
/til delete <id>
删除条目(需确认)
/til status
显示站点状态和连接信息
/til sync
将本地草稿同步到OpenTIL
/til tags
列出站点标签及使用次数
/til categories
列出站点分类
/til batch <topics>
批量捕获多个TIL条目
/til auth
连接OpenTIL账户(浏览器认证)
/til <其他内容>
将内容捕获为新的TIL条目
/til
从对话中提取见解(多候选)
保留字:
list
,
publish
,
unpublish
,
edit
,
search
,
delete
,
status
,
sync
,
tags
,
categories
,
batch
,
auth

Reference Loading

参考文件加载规则

⚠️ DO NOT read reference files unless specified below. SKILL.md contains enough inline context for most operations.
⚠️ 除非以下情况指定,否则请勿读取参考文件。SKILL.md包含了大多数操作所需的内联上下文。

On subcommand dispatch (load before execution):

子命令执行前加载:

SubcommandReferences to load
/til <content>
none
/til
(extract from conversation)
none
/til list|status|tags|categories
references/management.md
/til publish|unpublish|edit|search|delete|batch
references/management.md
/til sync
references/management.md, references/local-drafts.md
/til auth
references/management.md, references/api.md
子命令需加载的参考文件
/til <content>
/til
(从对话提取)
/til list|status|tags|categories
references/management.md
/til publish|unpublish|edit|search|delete|batch
references/management.md
/til sync
references/management.md, references/local-drafts.md
/til auth
references/management.md, references/api.md

On-demand (load only when the situation arises):

按需加载(仅在特定场景触发时加载):

TriggerReference to load
API returns non-2xx after inline error handling is insufficientreferences/api.md
Auto-detection context (proactive TIL suggestion)references/auto-detection.md
No token found (first-run local fallback)references/local-drafts.md
触发条件需加载的参考文件
内联错误处理后API仍返回非2xx状态码references/api.md
自动检测上下文(主动建议TIL)references/auto-detection.md
未找到令牌(首次运行本地 fallback)references/local-drafts.md

API Quick Reference

API快速参考

Create and publish an entry:
bash
curl -X POST "https://opentil.ai/api/v1/entries" \
  -H "Authorization: Bearer $OPENTIL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entry": {
      "title": "Go interfaces are satisfied implicitly",
      "content": "In Go, a type implements an interface...",
      "tag_names": ["go", "interfaces"],
      "published": true,
      "lang": "en"
    }
  }'
Key create parameters:
FieldTypeRequiredDescription
content
stringyesMarkdown body (max 100,000 chars)
title
stringnoEntry title (max 200 chars). Auto-generates slug.
tag_names
arrayno1-3 lowercase tags, e.g.
["go", "concurrency"]
published
booleanno
false
for draft (default),
true
to publish immediately
lang
stringnoLanguage code:
en
,
zh-CN
,
zh-TW
,
ja
,
ko
, etc.
slug
stringnoCustom URL slug. Auto-generated from title if omitted.
visibility
stringno
public
(default),
unlisted
, or
private
Management endpoints:
EndpointMethodDescription
/entries?status=draft&q=keyword
GETList/search entries
/entries/:id
GETGet a single entry
/entries/:id
PATCHUpdate entry fields
/entries/:id
DELETEPermanently delete entry
/entries/:id/publish
POSTPublish a draft
/entries/:id/unpublish
POSTRevert to draft
/site
GETSite info (username, entry counts, etc.)
/tags?sort=popular
GETList tags with usage counts
/categories
GETList categories with entry counts
Full parameter list, response format, and error handling: see references/api.md
创建并发布条目:
bash
curl -X POST "https://opentil.ai/api/v1/entries" \
  -H "Authorization: Bearer $OPENTIL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entry": {
      "title": "Go interfaces are satisfied implicitly",
      "content": "In Go, a type implements an interface...",
      "tag_names": ["go", "interfaces"],
      "published": true,
      "lang": "en"
    }
  }'
创建条目关键参数:
字段类型是否必填描述
content
stringMarkdown正文(最大100,000字符)
title
string条目标题(最大200字符),自动生成URL别名
tag_names
array1-3个小写标签,例如
["go", "concurrency"]
published
boolean
false
为草稿(默认),
true
为立即发布
lang
string语言代码:
en
,
zh-CN
,
zh-TW
,
ja
,
ko
slug
string自定义URL别名,若省略则从标题自动生成
visibility
string
public
(默认)、
unlisted
private
管理端点:
端点请求方法描述
/entries?status=draft&q=keyword
GET列出/搜索条目
/entries/:id
GET获取单个条目详情
/entries/:id
PATCH更新条目字段
/entries/:id
DELETE永久删除条目
/entries/:id/publish
POST发布草稿
/entries/:id/unpublish
POST恢复为草稿
/site
GET站点信息(用户名、条目数量等)
/tags?sort=popular
GET列出标签及使用次数
/categories
GET列出分类及条目数量
完整参数列表、响应格式和错误处理:请查看references/api.md

Execution Flow

执行流程

Every
/til
invocation follows this flow:
  1. Generate -- craft the TIL entry (title, body, tags, lang)
  2. Check token -- resolve token (env var →
    ~/.til/credentials
    )
    • Found -> POST to API with
      published: true
      -> show published URL
    • Not found -> save to
      ~/.til/drafts/
      -> show first-run setup guide
  3. Never lose content -- the entry is always persisted somewhere
  4. On API failure -> save locally as draft (fallback unchanged)
每次
/til
调用都遵循以下流程:
  1. 生成——制作TIL条目(标题、正文、标签、语言)
  2. 检查令牌——解析令牌(环境变量 →
    ~/.til/credentials
    • 找到令牌 → 携带
      published: true
      参数POST到API → 显示发布后的URL
    • 未找到令牌 → 保存到
      ~/.til/drafts/
      → 显示首次运行设置指南
  3. 永不丢失内容——条目始终会被持久化到某个位置
  4. API调用失败时 → 本地保存为草稿(fallback逻辑不变)

/til <content>
-- Explicit Capture

/til <content>
—— 显式捕获

The user's input is raw material -- a seed, not the final entry. Generate a complete TIL from it:
  • Short input (a sentence or phrase) -> expand into a full entry with context and examples
  • Long input (a paragraph or more) -> refine and structure, but preserve the user's intent
Steps:
  1. Treat the user's input as a seed -- craft a complete title + body from it
  2. Generate a concise title (5-15 words) in the same language as the content
  3. Write a self-contained Markdown body (see Content Guidelines below)
  4. Infer 1-3 lowercase tags from technical domain (e.g.
    rails
    ,
    postgresql
    ,
    go
    )
  5. Detect language -> set
    lang
    (
    en
    ,
    zh-CN
    ,
    zh-TW
    ,
    ja
    ,
    ko
    ,
    es
    ,
    fr
    ,
    de
    ,
    pt-BR
    ,
    pt
    ,
    ru
    ,
    ar
    ,
    bs
    ,
    da
    ,
    nb
    ,
    pl
    ,
    th
    ,
    tr
    ,
    it
    )
  6. Follow Execution Flow above (check token -> POST or save locally)
No confirmation needed -- the user explicitly asked to capture. Execute directly.
用户输入是原始素材——是种子而非最终条目。需要基于输入生成完整的TIL条目:
  • 短输入(一句话或短语)→ 扩展为包含上下文和示例的完整条目
  • 长输入(一段或多段内容)→ 优化结构,但保留用户原意
步骤:
  1. 将用户输入视为种子,生成完整的标题+正文
  2. 生成简洁标题(5-15个单词),语言与输入内容一致
  3. 撰写独立完整的Markdown正文(请遵循下方内容规范)
  4. 从技术领域推断1-3个小写标签(例如
    rails
    ,
    postgresql
    ,
    go
  5. 检测语言 → 设置
    lang
    参数(
    en
    ,
    zh-CN
    ,
    zh-TW
    ,
    ja
    ,
    ko
    ,
    es
    ,
    fr
    ,
    de
    ,
    pt-BR
    ,
    pt
    ,
    ru
    ,
    ar
    ,
    bs
    ,
    da
    ,
    nb
    ,
    pl
    ,
    th
    ,
    tr
    ,
    it
  6. 遵循上述执行流程(检查令牌 → POST或本地保存)
无需确认——用户已明确要求捕获,直接执行。

/til
-- Extract from Conversation

/til
—— 从对话提取

When
/til
is used without arguments, analyze the current conversation for learnable insights.
Steps:
  1. Scan the conversation for knowledge worth preserving -- surprising facts, useful techniques, debugging breakthroughs, "aha" moments
  2. Identify all TIL-worthy insights (not just one), up to 5
  3. Branch based on count:
0 insights:
No clear TIL insights found in this conversation.
1 insight: Generate the full draft (title, body, tags), show it, ask for confirmation. On confirmation -> follow Execution Flow.
2+ insights: Show a numbered list (max 5), let the user choose:
Found 3 TIL-worthy insights:

  1. Go interfaces are satisfied implicitly
  2. PostgreSQL JSONB arrays don't support GIN @>
  3. CSS :has() enables parent selection

Which to capture? (1/2/3/all/none)
  • Single number -> generate draft for that insight, show confirmation, proceed
  • Comma-separated list (e.g.
    1,3
    ) -> generate drafts for selected, show all for confirmation, POST sequentially
  • all
    -> generate drafts for each, show all for confirmation, POST sequentially
  • none
    -> cancel
  1. For each selected insight, generate a standalone TIL entry following Content Guidelines
  2. Show the generated entry to the user and ask for confirmation before proceeding
  3. On confirmation -> follow Execution Flow above (check token -> POST or save locally)
/til
不带参数使用时,分析当前对话以提取值得记录的见解。
步骤:
  1. 扫描对话,寻找值得保存的知识——意外发现的事实、实用技巧、调试突破、「恍然大悟」的时刻
  2. 识别所有适合作为TIL的见解(不止一个),最多5个
  3. 根据数量分支处理:
0个见解:
在本次对话中未发现明确的TIL见解。
1个见解: 生成完整草稿(标题、正文、标签),展示给用户并请求确认。确认后 → 遵循执行流程。
2个及以上见解: 显示编号列表(最多5个),让用户选择:
发现3个适合作为TIL的见解:

  1. Go接口为隐式实现
  2. PostgreSQL JSONB数组不支持GIN @>操作符
  3. CSS :has()支持父元素选择

要捕获哪一个?(1/2/3/all/none)
  • 单个数字 → 生成对应见解的草稿,展示确认后继续
  • 逗号分隔列表(如
    1,3
    )→ 为选中的见解生成草稿,全部展示确认后依次POST
  • all
    → 为每个见解生成草稿,全部展示确认后依次POST
  • none
    → 取消操作
  1. 为每个选中的见解生成符合内容规范的独立TIL条目
  2. 在执行前,必须向用户展示生成的条目并请求确认
  3. 确认后 → 遵循上述执行流程(检查令牌 → POST或本地保存)

Auto-Detection

自动检测

When working alongside a user, proactively detect moments worth capturing as TIL entries.
在与用户协作时,主动检测适合捕获为TIL条目的时刻。

When to Suggest

建议时机

Suggest when the conversation produces a genuine "aha" moment — something surprising, non-obvious, or worth remembering. Examples:
  • Debugging uncovered a non-obvious root cause
  • A language/framework behavior contradicted common assumptions
  • Refactoring revealed a clearly superior pattern
  • Performance optimization yielded measurable improvement
  • An obscure but useful tool flag or API parameter was discovered
  • Two technologies interacting produced unexpected behavior
Do NOT suggest for: standard tool usage, documented behavior, typo-caused bugs, or widely known best practices.
当对话产生真正的「恍然大悟」时刻时提出建议——例如意外的事实、实用技巧、非显而易见的内容或值得记住的知识点。示例:
  • 调试发现了非显而易见的根本原因
  • 语言/框架的行为与普遍认知不符
  • 重构发现了更优的模式
  • 性能优化取得了可衡量的提升
  • 发现了一个小众但实用的工具参数或API
  • 两种技术交互产生了意外行为
请勿为以下场景提出建议:标准工具使用、文档已有说明、打字错误导致的bug、广为人知的最佳实践。

Rate Limiting

频率限制

  1. Once per session — after suggesting once (accepted or declined), never suggest again
  2. Natural pauses only — suggest at resolution points or task boundaries, never mid-problem-solving
  3. Respect rejection — if declined, move on without persuasion
  1. 每会话一次——无论用户接受或拒绝建议,在同一会话中不再提出第二次
  2. 仅在自然停顿点——在问题解决或任务边界时提出,不要在问题解决过程中打断
  3. 尊重拒绝——如果用户拒绝,无需劝说,继续当前任务

Suggestion Format

建议格式

Append at the end of your normal response. Never interrupt workflow.
Template:
💡 TIL: [concise title of the insight]
   Tags: [tag1, tag2] · Capture? (yes/no)
Example (at the end of a debugging response):
...so the fix is to close the channel before the goroutine exits.

💡 TIL: Unclosed Go channels in goroutines cause silent memory leaks
   Tags: go, concurrency · Capture? (yes/no)
附加在正常回复末尾,绝不打断工作流程。
模板:
💡 TIL: [见解的简洁标题]
   标签: [tag1, tag2] · 是否捕获?(是/否)
示例(在调试回复末尾):
...所以修复方法是在goroutine退出前关闭通道。

💡 TIL: 未关闭的Go通道会导致静默内存泄漏
   标签: go, concurrency · 是否捕获?(是/否)

Capture Flow

捕获流程

Auto-detected TILs bypass the extract flow. The suggestion itself is the candidate.
  1. User replies
    yes
    /
    y
    /
    ok
    /
    sure
    → agent generates full entry (title, body, tags, lang) from the suggested insight → follows Execution Flow (POST or save locally)
  2. User replies
    no
    / ignores / continues other topic → move on, do not ask again
Non-affirmative responses (continuing the conversation about something else) are treated as implicit decline.
Detailed trigger examples, state machine, and anti-patterns: see references/auto-detection.md
自动检测到的TIL跳过提取流程,建议本身即为候选条目。
  1. 用户回复
    /
    y
    /
    好的
    /
    确定
    → 代理根据建议的见解生成完整条目(标题、正文、标签、语言)→ 遵循执行流程(POST或本地保存)
  2. 用户回复
    /忽略/继续其他话题 → 继续当前任务,不再询问
非肯定回复(继续讨论其他内容)视为隐含拒绝。
详细的触发示例、状态机和反模式:请查看references/auto-detection.md

Management Subcommands

管理子命令

Management subcommands require a token. There is no local fallback -- management operations need the API.
管理子命令需要令牌,无本地fallback——管理操作依赖API。

/til list [drafts|published|all]

/til list [drafts|published|all]

List entries. Default filter:
drafts
.
  • API:
    GET /entries?status=<filter>&per_page=10
  • Display as a compact table with short IDs (last 8 chars, prefixed with
    ...
    )
  • Show pagination info at the bottom
列出条目,默认筛选条件:
drafts
(草稿)。
  • API调用:
    GET /entries?status=<filter>&per_page=10
  • 以紧凑表格展示,显示短ID(最后8个字符,前缀为
    ...
  • 底部显示分页信息

/til publish [<id> | last]

/til publish [<id> | last]

Publish a draft entry.
  • last
    resolves to the most recently created entry in this session (tracked via
    last_created_entry_id
    set on every successful POST)
  • Fetch the entry first, show title/tags, ask for confirmation
  • On success, display the published URL
  • If already published, show informational message (not an error)
发布草稿条目。
  • last
    指代本次会话中最近创建的条目(通过每次成功POST后设置的
    last_created_entry_id
    跟踪)
  • 先获取条目详情,显示标题/标签,请求确认
  • 成功后显示发布URL
  • 如果条目已发布,显示提示信息(非错误)

/til unpublish <id>

/til unpublish <id>

Revert a published entry to draft.
  • Fetch the entry first, confirm before unpublishing
  • If already a draft, show informational message
将已发布条目恢复为草稿。
  • 先获取条目详情,确认后再执行取消发布
  • 如果条目已是草稿,显示提示信息

/til edit <id> [instructions]

/til edit <id> [instructions]

AI-assisted editing of an existing entry.
  • Fetch the full entry via
    GET /entries/:id
  • Apply changes based on instructions (or ask what to change if none given)
  • Show a diff preview of proposed changes
  • On confirmation,
    PATCH /entries/:id
    with only the changed fields
AI辅助编辑现有条目。
  • 通过
    GET /entries/:id
    获取完整条目
  • 根据指令修改内容(若未提供指令则询问修改需求)
  • 显示修改预览差异
  • 确认后,仅将修改的字段通过
    PATCH /entries/:id
    提交

/til search <keyword>

/til search <keyword>

Search entries by title.
  • API:
    GET /entries?q=<keyword>&per_page=10
  • Same compact table format as
    list
按标题搜索条目。
  • API调用:
    GET /entries?q=<keyword>&per_page=10
  • list
    命令使用相同的紧凑表格格式

/til delete <id>

/til delete <id>

Permanently delete an entry.
  • Fetch the entry, show title and status
  • Double-confirm: "This cannot be undone. Type 'delete' to confirm."
  • On confirmation,
    DELETE /entries/:id
永久删除条目。
  • 获取条目详情,显示标题和状态
  • 二次确认:「此操作不可撤销。请输入'delete'确认。」
  • 确认后执行
    DELETE /entries/:id

/til status

/til status

Show site status and connection info. Works without a token (degraded display).
  • With token:
    GET /site
    -> show username, entry breakdown (total/published/drafts), token status, local draft count, dashboard link
  • Without token: show "not connected", local draft count, setup link
显示站点状态和连接信息。无需令牌即可使用(功能受限展示)。
  • 已配置令牌:调用
    GET /site
    → 显示用户名、条目统计(总数/已发布/草稿)、令牌状态、本地草稿数量、仪表盘链接
  • 未配置令牌:显示「未连接」、本地草稿数量、设置链接

/til sync

/til sync

Explicitly sync local drafts from
~/.til/drafts/
to OpenTIL. Requires token.
  • List pending drafts, POST each one, delete local file on success
  • Show summary with success/failure per draft
~/.til/drafts/
中的本地草稿显式同步到OpenTIL,需要令牌。
  • 列出待同步草稿,逐个POST到API,成功后删除本地文件
  • 显示同步总结,包含每个草稿的成功/失败状态

/til tags

/til tags

List site tags sorted by usage count (top 20). Requires token.
  • API:
    GET /tags?sort=popular&per_page=20&with_entries=true
  • Show as compact table with tag name and entry count
按使用次数排序列出站点标签(前20个),需要令牌。
  • API调用:
    GET /tags?sort=popular&per_page=20&with_entries=true
  • 以紧凑表格展示标签名称和条目数量

/til categories

/til categories

List site categories. Requires token.
  • API:
    GET /categories
  • Show as compact table with name, entry count, and description
列出站点分类,需要令牌。
  • API调用:
    GET /categories
  • 以紧凑表格展示分类名称、条目数量和描述

/til batch <topics>

/til batch <topics>

Batch-capture multiple TIL entries in one invocation. Requires explicit topic list.
  • User lists topics separated by newlines, semicolons, or markdown list items (
    -
    /
    1.
    )
  • Generate a draft for each -> show all drafts for confirmation -> POST sequentially
  • On partial failure, show per-entry success/failure (same format as
    /til sync
    )
一次调用批量捕获多个TIL条目,需要明确的主题列表。
  • 用户通过换行、分号或Markdown列表项(
    -
    /
    1.
    )分隔主题
  • 为每个主题生成草稿 → 展示所有草稿请求确认 → 依次POST
  • 部分失败时,显示每个条目的成功/失败状态(与
    /til sync
    格式相同)

ID Resolution

ID解析规则

  • In listings, show IDs in short form:
    ...
    + last 8 characters
  • Accept both short and full IDs as input
  • Resolve short IDs by suffix match against the current listing
  • If ambiguous (multiple matches), ask for clarification
  • 在列表中,以短格式显示ID:
    ...
    + 最后8个字符
  • 接受短ID和完整ID作为输入
  • 通过后缀匹配当前列表解析短ID
  • 若存在歧义(多个匹配项),请用户澄清

Session State

会话状态

Track
last_created_entry_id
-- set on every successful
POST /entries
(201). Used by
/til publish last
. Not persisted across sessions.
Detailed subcommand flows, display formats, and error handling: see references/management.md
跟踪
last_created_entry_id
——每次成功执行
POST /entries
后设置。供
/til publish last
命令使用,跨会话不持久化。
详细的子命令流程、展示格式和错误处理:请查看references/management.md

Agent Identity

代理身份标识

Three layers of attribution signal distinguish human-initiated from agent-initiated TILs.
三层归因标识区分人工发起和代理发起的TIL条目。

Layer 1: HTTP Headers

第一层:HTTP请求头

Include these headers on every API call:
X-OpenTIL-Source: human | agent
X-OpenTIL-Agent: <your agent display name>
X-OpenTIL-Model: <human-readable model name>
  • Source:
    /til <content>
    and
    /til
    ->
    human
    ; Auto-detected ->
    agent
  • Agent: use your tool's display name (e.g.
    Claude Code
    ,
    Cursor
    ,
    GitHub Copilot
    ). Do not use a slug.
  • Model: use a human-readable model name (e.g.
    Claude Opus 4.6
    ,
    GPT-4o
    ,
    Gemini 2.5 Pro
    ). Do not use a model ID.
  • Agent and Model are optional -- omit them if you are unsure.
每次API调用都需包含以下请求头:
X-OpenTIL-Source: human | agent
X-OpenTIL-Agent: <你的代理显示名称>
X-OpenTIL-Model: <易读的模型名称>
  • Source:
    /til <content>
    /til
    human
    ;自动检测的条目 →
    agent
  • Agent:使用工具的显示名称(例如
    Claude Code
    ,
    Cursor
    ,
    GitHub Copilot
    ),请勿使用短名称
  • Model:使用易读的模型名称(例如
    Claude Opus 4.6
    ,
    GPT-4o
    ,
    Gemini 2.5 Pro
    ),请勿使用模型ID
  • Agent和Model为可选字段——若不确定可省略

Layer 2: Tag Convention

第二层:标签约定

  • Auto-detected TILs: automatically add
    agent-assisted
    to the tag list
  • /til <content>
    and
    /til
    : do not add the tag (unless the Agent substantially rewrote the content)
  • 自动检测的TIL条目:自动添加
    agent-assisted
    标签
  • /til <content>
    /til
    :请勿添加该标签(除非代理对内容进行了大幅改写)

Layer 3: Attribution Rendering (Backend)

第三层:归因展示(后端处理)

Agent-initiated TILs are visually marked on OpenTIL automatically based on the
source
field. No content modification needed -- the backend renders attribution in the display layer.
  • Public page: shows
    ✨ via {agent_name}
    , or
    ✨ AI
    when agent_name is absent
  • Tooltip (hover): shows
    {agent_name} · {model}
    when both are present
  • Dashboard: shows ✨ badge + agent_name, or "Agent" when agent_name is absent
Do NOT append any footer or attribution text to the content body.
代理发起的TIL条目会在OpenTIL上自动标记,基于
source
字段。无需修改内容——后端会在展示层处理归因。
  • 公开页面:显示
    ✨ via {agent_name}
    ,若未提供agent_name则显示
    ✨ AI
  • 悬停提示:若同时提供agent_name和model,显示
    {agent_name} · {model}
  • 仪表盘:显示✨徽章+agent_name,若未提供则显示「Agent」
请勿在内容末尾添加任何页脚或归因文本。

Summary

总结

Dimension
/til <content>
/til
Auto-detected
TriggerUser explicitUser commandAgent proactive
Confirmations0 (direct publish)1 (review before publish)1 (suggest → capture)
Source header
human
human
agent
Agent headerYesYesYes
Model headerYesYesYes
agent-assisted
tag
NoNoYes
AttributionAutomatic (backend)Automatic (backend)Automatic (backend)
维度
/til <content>
/til
自动检测
触发方式用户显式调用用户命令代理主动建议
确认次数0(直接发布)1(发布前审核)1(建议→捕获)
Source头
human
human
agent
Agent头
Model头
agent-assisted
标签
归因方式自动(后端)自动(后端)自动(后端)

Content Guidelines

内容规范

Every TIL entry must follow these rules:
  • Self-contained: The reader must understand the entry without any conversation context. Never write "as we discussed", "the above error", "this project's config", etc.
  • Desensitized: Remove project names, company details, colleague names, internal URLs, and proprietary business logic. Generalize specifics: "our User model" -> "a model", "the production server" -> "a production environment", "the Acme payment service" -> "a payment gateway".
  • Universally valuable: Write to StackOverflow-answer standards. A stranger searching for this topic should find the entry immediately useful. Content only useful to the author belongs in private notes, not TIL.
  • Factual tone: State facts, show examples, explain why. Avoid first-person narrative ("I was debugging...", "I discovered..."). Exception: brief situational context is fine ("When upgrading Rails from 7.2 to 8.0...").
  • One insight per entry: Each TIL teaches exactly ONE thing. If there are multiple insights, create separate entries.
  • Concrete examples: Include code snippets, commands, or specific data whenever relevant. Avoid vague descriptions.
  • Title: 5-15 words. Descriptive, same language as content. No "TIL:" prefix.
  • Content: Use the most efficient format for the knowledge — tables for comparisons, code blocks for examples, lists for enumerations, math (
    $inline$
    /
    $$display$$
    ) for formulas with fractions/subscripts/superscripts/greek letters, Mermaid diagrams (
    ```mermaid
    ) for flows/states/sequences that text cannot clearly express. Simple expressions like
    O(n)
    stay as inline code; use math only when notation complexity warrants it. Only use prose when explaining causation or context. Never pad content; if one sentence suffices, don't write a paragraph.
  • Tags: 1-3 lowercase tags from the technical domain (
    go
    ,
    rails
    ,
    postgresql
    ,
    css
    ,
    linux
    ). No generic tags like
    programming
    or
    til
    .
  • Lang: Detect from content. Chinese ->
    zh-CN
    , Traditional Chinese ->
    zh-TW
    , English ->
    en
    , Japanese ->
    ja
    , Korean ->
    ko
    .
  • Category: Do not auto-infer
    category_name
    -- only include it if the user explicitly specifies a category/topic.
所有TIL条目必须遵循以下规则:
  • 独立完整:读者无需对话上下文即可理解条目内容。请勿使用「如我们讨论的」「上述错误」「本项目配置」等表述。
  • 脱敏处理:移除项目名称、公司细节、同事姓名、内部URL和专有业务逻辑。将具体信息泛化:「我们的User模型」→「某个模型」,「生产服务器」→「生产环境」,「Acme支付服务」→「支付网关」。
  • 通用价值:内容需达到StackOverflow回答的标准。陌生用户搜索相关主题时,应能立即从中获得帮助。仅对作者有用的内容应存为私人笔记,而非TIL。
  • 客观语气:陈述事实、展示示例、解释原因。避免第一人称叙事(「我在调试...」「我发现...」)。例外:简短的场景上下文是允许的(「在将Rails从7.2升级到8.0时...」)。
  • 单条见解:每个TIL仅讲解一个知识点。若有多个见解,请创建独立条目。
  • 具体示例:相关时需包含代码片段、命令或具体数据。避免模糊描述。
  • 标题:5-15个单词,描述性强,语言与内容一致。请勿添加「TIL:」前缀。
  • 内容格式:选择最适合知识呈现的格式——对比用表格,示例用代码块,枚举用列表,复杂公式用KaTeX数学公式(
    $inline$
    /
    $$display$$
    ),流程/状态/序列用Mermaid图(
    ```mermaid
    )。简单表达式如
    O(n)
    保持内联代码格式;仅当符号复杂度需要时才使用数学公式。仅在解释因果关系或上下文时使用 prose。绝不凑字数——一句话能说明的,不要写一段。
  • 标签:1-3个技术领域的小写标签(
    go
    ,
    rails
    ,
    postgresql
    ,
    css
    ,
    linux
    )。请勿使用
    programming
    til
    等通用标签。
  • 语言:根据内容自动检测。简体中文→
    zh-CN
    ,繁体中文→
    zh-TW
    ,英文→
    en
    ,日文→
    ja
    ,韩文→
    ko
  • 分类:请勿自动推断
    category_name
    ——仅当用户明确指定分类/主题时才添加。

Result Messages

结果消息

API Success (token configured, 201)

API调用成功(已配置令牌,返回201)

Published to OpenTIL

  Title:  Go interfaces are satisfied implicitly
  Tags:   go, interfaces
  URL:    https://opentil.ai/@username/go-interfaces-are-satisfied-implicitly
Extract the
url
field from the API response for the URL.
已发布到OpenTIL

  标题:  Go接口为隐式实现
  标签:   go, interfaces
  URL:    https://opentil.ai/@username/go-interfaces-are-satisfied-implicitly
从API响应中提取
url
字段作为展示的URL。

Sync Local Drafts

同步本地草稿

After the first successful API call, check
~/.til/drafts/
for pending files. If any exist, offer to sync:
Draft saved to OpenTIL

  Title:  Go interfaces are satisfied implicitly
  Tags:   go, interfaces
  Review: https://opentil.ai/@username/go-interfaces-are-satisfied-implicitly

Found 3 local drafts from before. Sync them to OpenTIL?
On confirmation, POST each draft to the API. Delete the local file after each successful sync. Keep files that fail. Show summary:
Synced 3 local drafts to OpenTIL

  + Go defer runs in LIFO order
  + PostgreSQL JSONB indexes support GIN operators
  + CSS :has() selector enables parent selection
If the user declines, keep the local files and do not ask again in this session.
首次API调用成功后,检查
~/.til/drafts/
目录是否有待处理文件。若存在,询问是否同步:
草稿已保存到OpenTIL

  标题:  Go接口为隐式实现
  标签:   go, interfaces
  查看: https://opentil.ai/@username/go-interfaces-are-satisfied-implicitly

发现3个之前的本地草稿。是否同步到OpenTIL?
用户确认后,将每个草稿POST到API。成功同步后删除本地文件,失败的文件保留。显示总结:
已将3个本地草稿同步到OpenTIL

  + Go defer按后进先出顺序执行
  + PostgreSQL JSONB索引支持GIN操作符
  + CSS :has()选择器支持父元素选择
若用户拒绝,保留本地文件,本会话不再询问。

First Run (no token)

首次运行(无令牌)

Save the draft locally, then show a concise setup hint. This is NOT an error -- the user successfully captured a TIL.
TIL captured

  Title:  Go interfaces are satisfied implicitly
  Tags:   go, interfaces
  File:   ~/.til/drafts/20260210-143022-go-interfaces.md

Sync to OpenTIL? Run: /til auth
Only show the setup hint on the first local save in this session. On subsequent saves, use the short form:
TIL captured

  Title:  Go interfaces are satisfied implicitly
  Tags:   go, interfaces
  File:   ~/.til/drafts/20260210-143022-go-interfaces.md
将草稿本地保存,然后显示简洁的设置提示。这不是错误——用户已成功捕获TIL条目。
已捕获TIL条目

  标题:  Go接口为隐式实现
  标签:   go, interfaces
  文件:   ~/.til/drafts/20260210-143022-go-interfaces.md

是否同步到OpenTIL?请运行:/til auth
仅在本会话的第一次本地保存时显示设置提示。后续保存使用简化格式:
已捕获TIL条目

  标题:  Go接口为隐式实现
  标签:   go, interfaces
  文件:   ~/.til/drafts/20260210-143022-go-interfaces.md

Error Handling

错误处理

On ANY API failure, always save the draft locally first. Never let user content be lost.
422 -- Validation error: Analyze the error response, fix the issue (e.g. truncate title to 200 chars, correct lang code), and retry. Only save locally if the retry also fails.
401 -- Token invalid or expired:
TIL captured (saved locally -- token expired)

  File: ~/.til/drafts/20260210-143022-go-interfaces.md

Token expired. Run /til auth to reconnect.
Network failure or 5xx:
TIL captured (saved locally -- API unavailable)

  File: ~/.til/drafts/20260210-143022-go-interfaces.md
Full error codes, 422 auto-fix logic, and rate limit details: see references/api.md
任何API调用失败时,必须先将草稿本地保存。绝不能丢失用户内容。
422——验证错误: 分析错误响应,修复问题(例如将标题截断到200字符、修正语言代码),并重试。仅当重试失败时才本地保存。
401——令牌无效或过期:
已捕获TIL条目(本地保存——令牌已过期)

  文件: ~/.til/drafts/20260210-143022-go-interfaces.md

令牌已过期。请运行/til auth重新连接。
网络故障或5xx错误:
已捕获TIL条目(本地保存——API不可用)

  文件: ~/.til/drafts/20260210-143022-go-interfaces.md
完整的错误码、422自动修复逻辑和速率限制详情:请查看references/api.md

Local Draft Fallback

本地草稿Fallback

When the API is unavailable or no token is configured, drafts are saved locally to
~/.til/drafts/
.
File format:
YYYYMMDD-HHMMSS-<slug>.md
markdown
---
title: "Go interfaces are satisfied implicitly"
tags: [go, interfaces]
lang: en
---

In Go, a type implements an interface...
Full directory structure, metadata fields, and sync protocol: see references/local-drafts.md
当API不可用或未配置令牌时,草稿会本地保存到
~/.til/drafts/
目录。
文件格式:
YYYYMMDD-HHMMSS-<slug>.md
markdown
---
title: "Go interfaces are satisfied implicitly"
tags: [go, interfaces]
lang: en
---

In Go, a type implements an interface...
完整的目录结构、元数据字段和同步协议:请查看references/local-drafts.md

Notes

注意事项

  • Entries are published immediately by default (
    published: true
    ) -- use
    /til unpublish <id>
    to revert to draft
  • The API auto-generates a URL slug from the title
  • Tags are created automatically if they don't exist on the site
  • Content is rendered to HTML server-side (GFM Markdown with syntax highlighting, KaTeX math, and Mermaid diagrams)
  • Management subcommands (
    list
    ,
    publish
    ,
    edit
    ,
    search
    ,
    delete
    ,
    tags
    ,
    categories
    ,
    sync
    ,
    batch
    ) require a token -- no local fallback. Exception:
    status
    and
    auth
    work without a token.
  • Scope errors map to specific scopes:
    list
    /
    search
    /
    tags
    /
    categories
    need
    read:entries
    ,
    publish
    /
    unpublish
    /
    edit
    /
    sync
    /
    batch
    need
    write:entries
    ,
    delete
    needs
    delete:entries
    .
    status
    uses
    read:entries
    when available but works without a token.
  • 默认情况下条目会立即发布(
    published: true
    )——使用
    /til unpublish <id>
    恢复为草稿
  • API会根据标题自动生成URL别名
  • 若站点不存在对应标签,会自动创建
  • 内容在服务端渲染为HTML(支持GFM Markdown、语法高亮、KaTeX数学公式和Mermaid图)
  • 管理子命令(
    list
    ,
    publish
    ,
    edit
    ,
    search
    ,
    delete
    ,
    tags
    ,
    categories
    ,
    sync
    ,
    batch
    )需要令牌——无本地fallback。例外:
    status
    auth
    无需令牌即可使用。
  • 权限错误对应具体权限:
    list
    /
    search
    /
    tags
    /
    categories
    需要
    read:entries
    权限,
    publish
    /
    unpublish
    /
    edit
    /
    sync
    /
    batch
    需要
    write:entries
    权限,
    delete
    需要
    delete:entries
    权限。
    status
    在有权限时使用
    read:entries
    ,但无令牌时也可使用。