@opentil/cli 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +620 -0
- package/package.json +44 -0
- package/templates/claude-md-section.md +5 -0
- package/templates/cursor-rule.md +4 -0
- package/templates/hooks.json +26 -0
- package/templates/skill/SKILL.md +635 -0
- package/templates/skill/references/api.md +465 -0
- package/templates/skill/references/auto-detection.md +145 -0
- package/templates/skill/references/local-drafts.md +142 -0
- package/templates/skill/references/management.md +779 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Local Drafts & Sync Protocol
|
|
2
|
+
|
|
3
|
+
When the API is unavailable or no token is configured, TIL entries are saved locally. This document covers the full local draft lifecycle.
|
|
4
|
+
|
|
5
|
+
## Directory Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
~/.til/
|
|
9
|
+
drafts/
|
|
10
|
+
20260210-143022-go-interfaces.md
|
|
11
|
+
20260210-150415-postgresql-gin-index.md
|
|
12
|
+
20260211-091200-css-has-selector.md
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
All platforms use `~/.til/drafts/`. Create the directory if it does not exist.
|
|
16
|
+
|
|
17
|
+
## File Format
|
|
18
|
+
|
|
19
|
+
Filename: `YYYYMMDD-HHMMSS-<slug>.md`
|
|
20
|
+
|
|
21
|
+
The slug is derived from the title (lowercase, hyphens, no special chars, max 50 chars).
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
---
|
|
25
|
+
title: "Go interfaces are satisfied implicitly"
|
|
26
|
+
tags: [go, interfaces]
|
|
27
|
+
lang: en
|
|
28
|
+
summary: "Go types implement interfaces implicitly by implementing their methods, with no explicit declaration needed."
|
|
29
|
+
source: human
|
|
30
|
+
agent_name: Claude Code
|
|
31
|
+
agent_model: Claude Opus 4.6
|
|
32
|
+
profile: personal
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
In Go, a type implements an interface by implementing its methods.
|
|
36
|
+
There is no explicit `implements` keyword...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Frontmatter Fields
|
|
40
|
+
|
|
41
|
+
| Field | Type | Description |
|
|
42
|
+
|-------|------|-------------|
|
|
43
|
+
| `title` | string | Entry title |
|
|
44
|
+
| `tags` | array | Tag list |
|
|
45
|
+
| `lang` | string | Language code |
|
|
46
|
+
| `summary` | string | AI-generated summary for listing pages (max 500 chars) |
|
|
47
|
+
| `source` | string | `human` (from `/til`) or `agent` (from auto-detection) |
|
|
48
|
+
| `agent_name` | string | Agent display name, e.g. `Claude Code` (optional) |
|
|
49
|
+
| `agent_model` | string | Human-readable model name, e.g. `Claude Opus 4.6` (optional) |
|
|
50
|
+
| `profile` | string | Active profile name at save time (optional). Used during sync to determine which account's token to use. Omitted when no profiles are configured. |
|
|
51
|
+
|
|
52
|
+
The `source`, `agent_name`, and `agent_model` fields preserve attribution so that when syncing to the API, the correct headers and tags can be applied.
|
|
53
|
+
|
|
54
|
+
The `profile` field ensures drafts are synced to the correct account in multi-profile setups.
|
|
55
|
+
|
|
56
|
+
## Sync Protocol
|
|
57
|
+
|
|
58
|
+
When a successful API call is made (201 response), check for pending local drafts:
|
|
59
|
+
|
|
60
|
+
### Step 1: Detect Pending Drafts
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
List files in ~/.til/drafts/ matching *.md
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If no files exist, skip sync entirely.
|
|
67
|
+
|
|
68
|
+
### Step 2: Offer to Sync
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Found 3 local drafts from before. Sync them to OpenTIL?
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Wait for user confirmation. If the user declines, do not ask again this session.
|
|
75
|
+
|
|
76
|
+
### Step 3: Sync Each Draft
|
|
77
|
+
|
|
78
|
+
For each `.md` file in `~/.til/drafts/`:
|
|
79
|
+
|
|
80
|
+
1. Parse the frontmatter (title, tags, lang, source, agent_name, agent_model, profile)
|
|
81
|
+
2. **Resolve token for this draft** (profile matching):
|
|
82
|
+
- If `$OPENTIL_TOKEN` is set → always use it (env var overrides all profiles)
|
|
83
|
+
- If `profile` field is present → look up that profile's token in `~/.til/credentials`
|
|
84
|
+
- Profile found → use its token
|
|
85
|
+
- Profile not found → skip this draft, report: `Skipped: profile "work" not found (/til auth list)`
|
|
86
|
+
- If `profile` field is absent (old drafts) → use the current active profile's token
|
|
87
|
+
3. Read the content body (everything after the second `---`)
|
|
88
|
+
4. POST to API (using the resolved token):
|
|
89
|
+
- Set `published: false`
|
|
90
|
+
- Set `X-OpenTIL-Source` header based on `source` field
|
|
91
|
+
- Set `X-OpenTIL-Agent` header from `agent_name` field (if present)
|
|
92
|
+
- Set `X-OpenTIL-Model` header from `agent_model` field (if present)
|
|
93
|
+
- Add `agent-assisted` tag if `source` is `agent`
|
|
94
|
+
5. On 201 success: delete the local file
|
|
95
|
+
6. On failure: keep the local file, record the error
|
|
96
|
+
|
|
97
|
+
### Step 4: Report Results
|
|
98
|
+
|
|
99
|
+
**All succeeded:**
|
|
100
|
+
```
|
|
101
|
+
Synced 3 local drafts to OpenTIL
|
|
102
|
+
|
|
103
|
+
+ Go defer runs in LIFO order
|
|
104
|
+
+ PostgreSQL JSONB indexes support GIN operators
|
|
105
|
+
+ CSS :has() selector enables parent selection
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Partial failure:**
|
|
109
|
+
```
|
|
110
|
+
Synced 2 of 3 local drafts
|
|
111
|
+
|
|
112
|
+
+ Go defer runs in LIFO order
|
|
113
|
+
+ PostgreSQL JSONB indexes support GIN operators
|
|
114
|
+
x CSS :has() selector enables parent selection (validation error)
|
|
115
|
+
Kept at: ~/.til/drafts/20260210-143022-css-has-selector.md
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## First-Run Guide Template
|
|
119
|
+
|
|
120
|
+
On the first local save in a session (when no token is found):
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
TIL captured
|
|
124
|
+
|
|
125
|
+
Title: Go interfaces are satisfied implicitly
|
|
126
|
+
Tags: go, interfaces
|
|
127
|
+
File: ~/.til/drafts/20260210-143022-go-interfaces.md
|
|
128
|
+
|
|
129
|
+
Sync to OpenTIL? Run: /til auth
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
On subsequent local saves in the same session, use the short form:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
TIL captured
|
|
136
|
+
|
|
137
|
+
Title: Go interfaces are satisfied implicitly
|
|
138
|
+
Tags: go, interfaces
|
|
139
|
+
File: ~/.til/drafts/20260210-143022-go-interfaces.md
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Track "first save shown" as session state. Reset on each new session.
|