drafted 1.24.2 → 1.24.4

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.
Files changed (46) hide show
  1. package/README.md +15 -34
  2. package/cli/drafted.mjs +1 -1
  3. package/mcp/chunked-write.mjs +178 -0
  4. package/mcp/server.mjs +189 -12
  5. package/package.json +21 -27
  6. package/skills/import-website-to-drafted.md +329 -0
  7. package/agent-instructions/global.md +0 -3
  8. package/cli/google-setup.sh +0 -186
  9. package/cli/mail-watch.mjs +0 -237
  10. package/cli/open-url.mjs +0 -17
  11. package/cli/repo-scan.mjs +0 -240
  12. package/cli/skill-setup-trust.mjs +0 -17
  13. package/install-mcp.sh +0 -1440
  14. package/mcp/active-project-store.mjs +0 -81
  15. package/mcp/gates.mjs +0 -206
  16. package/mcp/gws-status.mjs +0 -31
  17. package/mcp/repo-address.mjs +0 -215
  18. package/mcp/test-file-path-text.mjs +0 -58
  19. package/mcp/test-org-guards.mjs +0 -234
  20. package/mcp/test-project-index.mjs +0 -88
  21. package/mcp/test-search-terms.mjs +0 -79
  22. package/mcp/test-skill-paths.mjs +0 -29
  23. package/mcp/widgets/canvas-overview.html +0 -229
  24. package/mcp/widgets/frame-preview.html +0 -162
  25. package/plugin/commands/create-project.md +0 -20
  26. package/plugin/commands/create-skill.md +0 -18
  27. package/plugin/commands/extract.md +0 -16
  28. package/plugin/commands/improve-project-harness.md +0 -16
  29. package/plugin/commands/improve-skill.md +0 -14
  30. package/plugin/commands/improve-wiki.md +0 -14
  31. package/plugin/commands/ingest.md +0 -20
  32. package/plugin/commands/onboard-drafted.md +0 -18
  33. package/plugin/skills/drafted/SKILL.md +0 -102
  34. package/server/lib/umami.mjs +0 -164
  35. package/src/shared/anchor-scope.mjs +0 -98
  36. package/src/shared/excalidraw.mjs +0 -94
  37. package/src/shared/folder-path.mjs +0 -176
  38. package/src/shared/gate-budget.mjs +0 -30
  39. package/src/shared/minion-presets.mjs +0 -67
  40. package/src/shared/okf-log.mjs +0 -62
  41. package/src/shared/record-conformance.mjs +0 -167
  42. package/src/shared/root-route.mjs +0 -45
  43. package/src/shared/task-id.mjs +0 -54
  44. package/src/shared/test-excalidraw-merge.mjs +0 -52
  45. package/src/shared/wiki-excalidraw.mjs +0 -90
  46. /package/{src/shared → shared}/constants.mjs +0 -0
@@ -1,229 +0,0 @@
1
- <style>
2
- :root {
3
- --bg: #fafafa;
4
- --card: #fff;
5
- --border: #e5e7eb;
6
- --muted: #6b7280;
7
- --text: #1a1a2e;
8
- --accent: #533afd;
9
- --accent-light: #ede9fe;
10
- }
11
- * { box-sizing: border-box; margin: 0; padding: 0; }
12
- html, body { height: 100%; }
13
- body {
14
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
15
- background: var(--bg);
16
- color: var(--text);
17
- padding: 16px 18px;
18
- }
19
- .header {
20
- display: flex;
21
- justify-content: space-between;
22
- align-items: baseline;
23
- margin-bottom: 14px;
24
- }
25
- .header .title { font-size: 14px; font-weight: 600; }
26
- .header .meta { font-size: 12px; color: var(--muted); }
27
- .header a {
28
- color: var(--accent);
29
- text-decoration: none;
30
- font-weight: 500;
31
- font-size: 12px;
32
- margin-left: 12px;
33
- }
34
- .header a:hover { text-decoration: underline; }
35
-
36
- .layer {
37
- background: var(--card);
38
- border: 1px solid var(--border);
39
- border-radius: 10px;
40
- padding: 12px 14px;
41
- margin-bottom: 10px;
42
- }
43
- .layer h3 {
44
- font-size: 12px;
45
- font-weight: 600;
46
- color: var(--muted);
47
- text-transform: uppercase;
48
- letter-spacing: 0.04em;
49
- margin-bottom: 8px;
50
- display: flex;
51
- justify-content: space-between;
52
- }
53
- .layer h3 .count {
54
- background: var(--accent-light);
55
- color: var(--accent);
56
- padding: 1px 8px;
57
- border-radius: 999px;
58
- font-size: 10px;
59
- }
60
- .frames {
61
- display: flex;
62
- flex-wrap: wrap;
63
- gap: 6px;
64
- }
65
- .frame {
66
- background: var(--bg);
67
- border: 1px solid var(--border);
68
- border-radius: 6px;
69
- padding: 6px 10px;
70
- font-size: 12px;
71
- color: var(--text);
72
- text-decoration: none;
73
- display: inline-flex;
74
- align-items: center;
75
- gap: 6px;
76
- transition: border-color 0.15s, color 0.15s;
77
- }
78
- .frame:hover {
79
- border-color: var(--accent);
80
- color: var(--accent);
81
- }
82
- .frame .lane {
83
- color: var(--muted);
84
- font-size: 11px;
85
- }
86
- .empty {
87
- text-align: center;
88
- color: var(--muted);
89
- font-size: 13px;
90
- padding: 32px;
91
- }
92
- .project {
93
- background: var(--card);
94
- border: 1px solid var(--border);
95
- border-radius: 10px;
96
- padding: 12px 14px;
97
- margin-bottom: 8px;
98
- display: flex;
99
- justify-content: space-between;
100
- align-items: center;
101
- text-decoration: none;
102
- color: inherit;
103
- transition: border-color 0.15s;
104
- }
105
- .project:hover { border-color: var(--accent); }
106
- .project .name { font-weight: 500; font-size: 14px; }
107
- .project .desc { font-size: 12px; color: var(--muted); margin-top: 2px; }
108
- .project .badge {
109
- font-size: 11px;
110
- background: var(--accent-light);
111
- color: var(--accent);
112
- padding: 2px 8px;
113
- border-radius: 999px;
114
- }
115
- </style>
116
-
117
- <div class="header">
118
- <div>
119
- <div class="title" id="title">Loading…</div>
120
- <div class="meta" id="subtitle"></div>
121
- </div>
122
- <a id="open" href="#" target="_blank" rel="noopener" hidden>Open in canvas →</a>
123
- </div>
124
- <div id="root"></div>
125
-
126
- <script>
127
- function escapeHtml(s) {
128
- return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
129
- }
130
-
131
- // Derive the Drafted server origin from payload URLs (frameUrl, canvasUrl) so the
132
- // widget deep-links correctly on local installs and hosted servers alike — never
133
- // hardcode https://drafted.live (breaks localhost/self-hosted deployments).
134
- function serverOrigin(sc) {
135
- const candidates = [
136
- sc.canvasUrl, sc.serverUrl,
137
- ...(Array.isArray(sc.projects) ? sc.projects.map(p => p.canvasUrl).filter(Boolean) : []),
138
- ...(Array.isArray(sc.projects) ? sc.projects.map(p => p.frameUrl).filter(Boolean) : []),
139
- ...(Array.isArray(sc.entries) ? sc.entries.map(e => e.frameUrl).filter(Boolean) : []),
140
- ];
141
- for (const u of candidates) {
142
- try { return new URL(u).origin; } catch { /* keep looking */ }
143
- }
144
- return 'https://drafted.live';
145
- }
146
-
147
- function renderProjects(projects, activeId, origin) {
148
- if (!projects?.length) return '<div class="empty">No projects yet. Use project(action="create") to start one.</div>';
149
- return projects.slice(0, 30).map(p => {
150
- const isActive = p.id === activeId;
151
- const url = p.slug ? `${origin}/project/${escapeHtml(p.slug)}` : '#';
152
- return `
153
- <a class="project" href="${url}" target="_blank" rel="noopener">
154
- <div>
155
- <div class="name">${escapeHtml(p.name || p.slug || 'Untitled')}</div>
156
- ${p.description ? `<div class="desc">${escapeHtml(p.description)}</div>` : ''}
157
- </div>
158
- ${isActive ? '<span class="badge">active</span>' : ''}
159
- </a>
160
- `;
161
- }).join('');
162
- }
163
-
164
- function renderLayers(byLayer) {
165
- if (!byLayer || !Object.keys(byLayer).length) return '<div class="empty">No frames in this view.</div>';
166
- return Object.entries(byLayer).map(([layer, frames]) => `
167
- <div class="layer">
168
- <h3>${escapeHtml(layer)} <span class="count">${frames.length}</span></h3>
169
- <div class="frames">
170
- ${frames.slice(0, 24).map(f => `
171
- <a class="frame" href="${escapeHtml(f.frameUrl || '#')}" target="_blank" rel="noopener">
172
- <span>${escapeHtml(f.label || f.filename || f.path || '?')}</span>
173
- ${f.lane && f.lane !== 'default' ? `<span class="lane">${escapeHtml(f.lane)}</span>` : ''}
174
- </a>
175
- `).join('')}
176
- </div>
177
- </div>
178
- `).join('');
179
- }
180
-
181
- function render(payload) {
182
- const sc = payload?.structuredContent || {};
183
- const root = document.getElementById('root');
184
-
185
- // project(action="list") shape
186
- if (Array.isArray(sc.projects)) {
187
- document.getElementById('title').textContent = `${sc.projects.length} project${sc.projects.length === 1 ? '' : 's'}`;
188
- document.getElementById('subtitle').textContent = sc.activeProject ? 'One active' : 'None active — use project(action="open") to switch';
189
- root.innerHTML = renderProjects(sc.projects, sc.activeProject, serverOrigin(sc));
190
- return;
191
- }
192
-
193
- // ls shape
194
- if (sc.byLayer || sc.entries) {
195
- const byLayer = sc.byLayer || groupByLayer(sc.entries || []);
196
- const total = Object.values(byLayer).reduce((sum, arr) => sum + arr.length, 0);
197
- document.getElementById('title').textContent = sc.project || 'Project canvas';
198
- document.getElementById('subtitle').textContent = `${total} frame${total === 1 ? '' : 's'} · ${Object.keys(byLayer).length} layer${Object.keys(byLayer).length === 1 ? '' : 's'}`;
199
- if (sc.canvasUrl) {
200
- const link = document.getElementById('open');
201
- link.href = sc.canvasUrl;
202
- link.hidden = false;
203
- }
204
- root.innerHTML = renderLayers(byLayer);
205
- return;
206
- }
207
-
208
- root.innerHTML = '<div class="empty">No data to display.</div>';
209
- }
210
-
211
- function groupByLayer(entries) {
212
- const out = {};
213
- for (const e of entries) {
214
- const layer = e.layer || 'unsorted';
215
- (out[layer] ??= []).push(e);
216
- }
217
- return out;
218
- }
219
-
220
- window.addEventListener('message', (event) => {
221
- const msg = event.data;
222
- if (!msg || typeof msg !== 'object') return;
223
- if (msg.method === 'ui/notifications/tool-result' && msg.params?.result) {
224
- render(msg.params.result);
225
- }
226
- });
227
-
228
- if (window.openai?.toolResult) render(window.openai.toolResult);
229
- </script>
@@ -1,162 +0,0 @@
1
- <style>
2
- :root {
3
- --bg: #fafafa;
4
- --card: #fff;
5
- --border: #e5e7eb;
6
- --muted: #6b7280;
7
- --text: #1a1a2e;
8
- --accent: #533afd;
9
- }
10
- * { box-sizing: border-box; margin: 0; padding: 0; }
11
- html, body { height: 100%; }
12
- body {
13
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
14
- background: var(--bg);
15
- color: var(--text);
16
- display: flex;
17
- flex-direction: column;
18
- }
19
- .header {
20
- display: flex;
21
- justify-content: space-between;
22
- align-items: center;
23
- padding: 10px 14px;
24
- border-bottom: 1px solid var(--border);
25
- background: var(--card);
26
- font-size: 13px;
27
- }
28
- .header .path {
29
- font-family: 'SF Mono', 'Menlo', monospace;
30
- color: var(--muted);
31
- font-size: 12px;
32
- }
33
- .header .meta {
34
- color: var(--muted);
35
- font-size: 11px;
36
- }
37
- .header a {
38
- color: var(--accent);
39
- text-decoration: none;
40
- font-weight: 500;
41
- margin-left: 12px;
42
- }
43
- .header a:hover { text-decoration: underline; }
44
- .stage {
45
- flex: 1;
46
- overflow: auto;
47
- background: var(--card);
48
- }
49
- iframe {
50
- width: 100%;
51
- min-height: 480px;
52
- border: 0;
53
- display: block;
54
- }
55
- img.preview {
56
- max-width: 100%;
57
- height: auto;
58
- display: block;
59
- margin: 0 auto;
60
- }
61
- .empty {
62
- padding: 40px;
63
- text-align: center;
64
- color: var(--muted);
65
- font-size: 13px;
66
- }
67
- .markdown-body {
68
- padding: 24px 32px;
69
- max-width: 760px;
70
- margin: 0 auto;
71
- line-height: 1.6;
72
- }
73
- .markdown-body pre {
74
- background: #f3f4f6;
75
- padding: 12px 16px;
76
- border-radius: 6px;
77
- overflow-x: auto;
78
- font-size: 13px;
79
- }
80
- </style>
81
-
82
- <div class="header">
83
- <span class="path" id="path">Loading frame…</span>
84
- <span>
85
- <span class="meta" id="meta"></span>
86
- <a id="open" href="#" target="_blank" rel="noopener" hidden>Open in canvas →</a>
87
- </span>
88
- </div>
89
- <div class="stage" id="stage">
90
- <div class="empty">Waiting for frame data…</div>
91
- </div>
92
-
93
- <script>
94
- function escapeHtml(s) {
95
- return String(s).replace(/[&<>"']/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
96
- }
97
-
98
- function render(payload) {
99
- const sc = payload?.structuredContent || {};
100
- const meta = payload?._meta || {};
101
- const path = sc.path || sc.frameId || sc.id || 'Frame';
102
- const sizeBits = [];
103
- if (sc.width && sc.height) sizeBits.push(`${sc.width}×${sc.height}`);
104
- if (sc.contentType) sizeBits.push(sc.contentType.split('/').pop());
105
- if (sc.layer) sizeBits.push(sc.layer);
106
-
107
- document.getElementById('path').textContent = path;
108
- document.getElementById('meta').textContent = sizeBits.join(' · ');
109
- const openLink = document.getElementById('open');
110
- if (sc.frameUrl) {
111
- openLink.href = sc.frameUrl;
112
- openLink.hidden = false;
113
- }
114
-
115
- const stage = document.getElementById('stage');
116
- stage.innerHTML = '';
117
-
118
- // Image (PNG screenshot, asset)
119
- if (sc.imageUrl || meta.imageUrl) {
120
- const img = document.createElement('img');
121
- img.className = 'preview';
122
- img.src = sc.imageUrl || meta.imageUrl;
123
- img.alt = path;
124
- stage.appendChild(img);
125
- return;
126
- }
127
-
128
- // HTML frame — render in sandboxed srcdoc iframe
129
- const html = meta.frameHtml || sc.content;
130
- const ctype = (sc.contentType || '').toLowerCase();
131
- if (html) {
132
- if (ctype.includes('markdown') || path.toLowerCase().endsWith('.md')) {
133
- // Render markdown as preformatted text — keeps it readable without a parser dep
134
- const div = document.createElement('div');
135
- div.className = 'markdown-body';
136
- div.innerHTML = '<pre>' + escapeHtml(html) + '</pre>';
137
- stage.appendChild(div);
138
- } else {
139
- const iframe = document.createElement('iframe');
140
- iframe.setAttribute('sandbox', 'allow-same-origin');
141
- iframe.srcdoc = html;
142
- if (sc.height && Number(sc.height) > 480) iframe.style.minHeight = sc.height + 'px';
143
- stage.appendChild(iframe);
144
- }
145
- return;
146
- }
147
-
148
- stage.innerHTML = '<div class="empty">No content to preview. The tool result did not include frame HTML.</div>';
149
- }
150
-
151
- // MCP Apps bridge: listen for ui/notifications/tool-result
152
- window.addEventListener('message', (event) => {
153
- const msg = event.data;
154
- if (!msg || typeof msg !== 'object') return;
155
- if (msg.method === 'ui/notifications/tool-result' && msg.params?.result) {
156
- render(msg.params.result);
157
- }
158
- });
159
-
160
- // Some hosts send the initial payload synchronously — try reading it now too
161
- if (window.openai?.toolResult) render(window.openai.toolResult);
162
- </script>
@@ -1,20 +0,0 @@
1
- ---
2
- description: Start a new project — or a reusable template — with proper search of knowledge and skills first
3
- argument-hint: <project name and what you want to do>
4
- ---
5
-
6
- Spin up a project on the surface, or generalize one into a reusable template. Goal: $ARGUMENTS
7
-
8
- First ask: **a new project, or a reusable template?** (This command does both.)
9
-
10
- Search before creating (also satisfies the gates):
11
- 1. `fs(search, path="/o/<org>/wiki", query="<terms>")` for relevant knowledge. [G1]
12
- 2. `fs(search, path="/o/<org>/skills", query="<topic>")` for procedures that should be attached. [G2/G3]
13
-
14
- Then:
15
- - Create the project — a project is a folder: `fs(mkdir, path="/o/<org>/projects/<name>")`. It starts with **no layers**; you define them by writing into them.
16
- - `fs(write, path="/o/<org>/projects/<name>/<layer>/<lane>/brief.md", content=...)` a real brief at the earliest layer (goal, audience, constraints — 6-12 lines, not a placeholder). The layer + lane auto-create.
17
- - Attach the relevant skills you found; anchor any that agents must read before they write.
18
- - `fs(ls, path="/o/<org>/projects/<name>")` to confirm the structure, and hand the user the `projectUrl` from the response.
19
-
20
- For a **template**: build the layer structure + anchored guidance, then note how to fork it next time. Don't speculatively fill downstream frames — wait for direction.
@@ -1,18 +0,0 @@
1
- ---
2
- description: Capture a repeatable procedure as an org skill — with proper knowledge and prior-art search
3
- argument-hint: <what the procedure is for>
4
- ---
5
-
6
- Turn a repeatable way of working into a Drafted skill so every future agent in the org follows it. Procedure: $ARGUMENTS
7
-
8
- Do the searches first (they also satisfy the gates):
9
- 1. `fs(search, path="/o/<org>/wiki", query="<terms>")` for relevant org knowledge the procedure should reference. [G1]
10
- 2. `fs(search, path="/o/<org>/skills", query="<topic>")` for prior art — an existing skill to improve instead of duplicating. [G2 — also enforced on writing a new skill.] If a close match exists, prefer `/drafted:improve-skill`.
11
-
12
- Then define a PROPER procedure, not a vague note:
13
- - a clear trigger ("when to use this"),
14
- - ordered, concrete steps,
15
- - success criteria / what "done right" looks like,
16
- - written in the second person so any agent can follow it directly. Keep it sharp (~40 lines).
17
-
18
- Show the draft to the user with a proposed `name` (Title Case), one-line `description`, `tags` (3-5), and `triggerPatterns`. After approval, write it with `fs(write, path="/o/<org>/skills/<slug>", content=...)` — the slug is derived from the name. Confirm with the slug and note it will auto-surface on matching tasks.
@@ -1,16 +0,0 @@
1
- ---
2
- description: Deposit what this session produced into the harness — knowledge, a skill, and/or a template
3
- argument-hint: <optional: what to capture>
4
- ---
5
-
6
- Session-end deposit. Harvest what's durable from this conversation back into the harness so the next session starts smarter. Focus: $ARGUMENTS
7
-
8
- Review the session, then **present the user options for which store(s) to deposit into** — don't auto-decide. Offer any that apply:
9
-
10
- - **Knowledge → wiki** — durable facts, decisions, or findings worth keeping. Search first (`fs(search, path="/o/<org>/wiki", ...)`) to avoid fragmenting, then `fs(write, path="/o/<org>/wiki/<path>", ...)`.
11
- - **Procedure → skill** — a repeatable way of working that emerged. Follow `/drafted:create-skill`.
12
- - **Template → surface** — a reusable project structure that emerged. Build it as a project via `fs(mkdir, ...)` + frames.
13
-
14
- Show the user the candidate deposits per store, let them pick which to keep, then write the chosen ones with their approval. Confirm what landed where.
15
-
16
- One command, all three stores — because at session end the human shouldn't have to remember which store is which.
@@ -1,16 +0,0 @@
1
- ---
2
- description: Turn corrections you made in a project into enforced gates (anchors, attached skills, layer rules)
3
- argument-hint: <optional: the correction to enforce>
4
- ---
5
-
6
- When the user had to correct the work in this project, codify the correction so future work is compelled to comply. This is the nurture → enforce bridge. Correction: $ARGUMENTS
7
-
8
- 1. Identify the recurring correction(s) or standing rule from this session.
9
- 2. Choose the right Drafted-side gate per correction (each counts toward the project's context budget):
10
- - **Project anchor** — a brief, constraint, or style guide that must be in context project-wide: `fs(write, path="/o/<org>/projects/<project>/<layer>/<lane>/<file>", content=...)` it, then anchor it so it is listed as suggested reading (not enforced). [G5]
11
- - **Attached skill** — a procedure that must be loaded before work: `/drafted:create-skill` (or `fs(search, path="/o/<org>/skills", ...)` for an existing one), then ask the user to anchor it to the project (Skills view > Anchoring, effect Enforce; an agent cannot do this itself, and attaching a skill alone does not gate). Writes in that scope are then refused until the skill is read. [G4]
12
- - **Layer rule** — a standing instruction for one stage: set that layer's rules (an AGENTS.md in the layer) so they are surfaced when work happens there. [G6]
13
- 3. Propose which mechanism for each correction, confirm with the user, then apply.
14
- 4. Confirm what is now enforced — only an anchored skill gates writes; a project anchor and a layer rule do not.
15
-
16
- Keep within the project's context budget — if a deposit would exceed it, tighten existing gates instead of piling on.
@@ -1,14 +0,0 @@
1
- ---
2
- description: Fix a skill you noticed is inefficient, wrong, or missing a step
3
- argument-hint: <which skill, and what's off>
4
- ---
5
-
6
- Improve an existing org skill when it underperformed in practice. Skill / issue: $ARGUMENTS
7
-
8
- 1. `fs(search, path="/o/<org>/skills", query="<slug>")` then `fs(read, path="/o/<org>/skills/<slug>")` the skill in question — read it fully.
9
- 2. Pinpoint the inefficiency: a missing step, a wrong instruction, an ambiguous trigger, or a step that wastes effort.
10
- 3. Propose the specific edit to the user — show before/after of the changed steps.
11
- 4. After approval, `fs(write, path="/o/<org>/skills/<slug>", content=<updated>)` — writing an existing skill updates it (the version bumps automatically). If it was archived, writing restores it.
12
- 5. Confirm what changed so the next agent benefits.
13
-
14
- Skills are the org's stable processes — every fix compounds across everyone who uses them.
@@ -1,14 +0,0 @@
1
- ---
2
- description: Fix the wiki — reconcile stale, wrong, fragmented, or contradictory knowledge
3
- argument-hint: <what's wrong, or the topic to clean up>
4
- ---
5
-
6
- Improve the org wiki when knowledge has drifted. Issue/topic: $ARGUMENTS
7
-
8
- 1. `fs(search, path="/o/<org>/wiki", query="<terms>")` (3-5 paraphrased queries) and `fs(read, path="/o/<org>/wiki/<path>")` the affected pages — don't trust titles, open them.
9
- 2. Diagnose: duplicate pages, a stale fact, a contradiction, or knowledge fragmented across pages.
10
- 3. Propose the fix to the user: consolidate duplicates, correct the fact, reconcile the contradiction, or re-link fragments.
11
- 4. Apply with `fs(write, path="/o/<org>/wiki/<path>", content=<updated>)` (hashline `edit` for surgical changes) or `fs(mv, path="/o/<org>/wiki/<from>", to="/o/<org>/wiki/<to>")` (which rewrites inbound links). Check what links to a page before moving or archiving it.
12
- 5. Never hard-delete — `fs(rm, path="/o/<org>/wiki/<path>")` moves a page to the archive folder.
13
-
14
- Leave the wiki more coherent than you found it — fewer, sharper, better-linked pages.
@@ -1,20 +0,0 @@
1
- ---
2
- description: Bring knowledge into the wiki — from a research output, existing documents, or by interrogating you
3
- argument-hint: <optional: what to ingest, or a source>
4
- ---
5
-
6
- Feed durable knowledge into the org wiki. Source/intent: $ARGUMENTS
7
-
8
- First decide WHAT to ingest. If it's obvious from the conversation (a research run just finished, or the user named a source), use that. Otherwise ask which of these three modes fits:
9
-
10
- 1. **A research producible** — the output of a research run (a provider-native `/deep-research` or similar). Structure it into wiki pages.
11
- 2. **Existing documents** — the user points at local / remote / connected folders. Scour them (spawn sub-agents if there are many) for relevant material, shortlist, confirm, then ingest the right ones. Folder scour needs file access (desktop / Cowork); on web, use connected sources.
12
- 3. **Interrogate the user** (grill-me) — when the knowledge is in their head. Interview relentlessly, walking ONE branch of the decision tree at a time and proposing your recommended answer at each step, until you reach shared understanding. Then structure what you captured.
13
-
14
- Then deposit:
15
- - `fs(search, path="/o/<org>/wiki", query="<terms>")` first (3-5 paraphrased queries) so you don't fragment existing pages.
16
- - Propose the page set to the user before writing.
17
- - Write with `fs(write, path="/o/<org>/wiki/<path>", content=...)` per page. Cross-link related pages.
18
- - Confirm what landed where, with the page links.
19
-
20
- The wiki is the org's durable knowledge — write for the next agent and teammate, not just this session.
@@ -1,18 +0,0 @@
1
- ---
2
- description: First-run setup — orient to Drafted and bootstrap the harness (wiki, skills, first project)
3
- argument-hint: <optional: what you want to start working on>
4
- ---
5
-
6
- Onboard the user to Drafted — a producibles harness that compounds across three primitives: knowledge (the wiki), procedures (skills), and the project surface. Goal/context: $ARGUMENTS
7
-
8
- This is the over-arching prime command: orient, then seed all three stores so every later session starts smart.
9
-
10
- 1. **Orient** — in 3-4 lines explain the loop: you *prime* from the harness (the system makes you search the wiki, and refuses a write until you have read the skills anchored to where you are working), you *build*, then you *compound* (deposit what you learned). The more it's used, the less searching and the more stable the work. Drafted is navigated like a filesystem — one `fs` tool, three roots: `/wiki`, `/skills`, `/projects`.
11
- 2. **Name the org** — the org is an address, not a cursor: address wiki/skills with `org=...` on the call, and projects self-derive their org from the path. Never rely on an "active" org: a project-less create by a multi-org user is refused rather than guessed.
12
- 3. **Find the work (ask first).** Make your first question permission, offering three scopes, narrowest first: (a) "tell me what you're working on this week" (nothing is read), (b) one folder they point you to, (c) recent files plus their inbox, Drive and calendar. Option (c) needs `gws` signed in; check it as the `drafted` skill's *Source material from Google* section describes, and if it isn't, offer `! drafted google-setup`. Say plainly what stays on their machine (everything you read) and what reaches Drafted (only what they pick). Read headers before bodies. Then write one frame, **Your work, mapped**: the 3-7 strongest candidates for a Drafted project, each with why it fits (many artifacts, several people, a recurring process, a decision to make), its source links, and the project it would become. Let the user pick.
13
- 4. **Seed knowledge** — run the `/drafted:ingest` flow: help the user point at existing business materials (folders, docs, past research, the sources behind the candidate they picked) or interrogate them for tacit knowledge, and land durable pages in the wiki.
14
- 5. **Seed procedures** — from those materials and the conversation, surface 1-3 candidate SOPs. For the most valuable, run the `/drafted:create-skill` flow.
15
- 6. **Seed the surface** — run the `/drafted:create-project` flow for the candidate the user picked, or their immediate piece of work (or a reusable template).
16
- 7. Close by showing what now exists (wiki pages, skills, project) and restate the one-line loop: prime → build → compound.
17
-
18
- Keep it guided and conversational — one step at a time, confirming before each deposit. Don't dump everything at once.