diffwiki 0.14.0 → 0.15.0-rc.202608040926.6b3b436
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/bin.js +107 -9
- package/package.json +4 -3
- package/templates/collection-index-template.md +43 -0
- package/templates/guide-template.md +68 -0
- package/templates/recipe-template.md +58 -0
- package/templates/recipe-with-steps-template.md +76 -0
- package/templates/reference-template.md +70 -0
- package/templates/session-transcript-template.md +26 -0
package/dist/bin.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { spawn as spawn4 } from "child_process";
|
|
5
|
+
import path4 from "path";
|
|
6
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5
7
|
import { Command, Option } from "commander";
|
|
6
8
|
import {
|
|
7
9
|
addExternalCollection,
|
|
@@ -23,7 +25,13 @@ import {
|
|
|
23
25
|
registerPlugin,
|
|
24
26
|
removeArticle,
|
|
25
27
|
removePlugin,
|
|
28
|
+
repairPlugins,
|
|
26
29
|
removeTags,
|
|
30
|
+
seedTemplates,
|
|
31
|
+
listTemplates,
|
|
32
|
+
readContextCollections,
|
|
33
|
+
setContextCollections,
|
|
34
|
+
resolveDefaultSearchMode,
|
|
27
35
|
resolveCwdCollection,
|
|
28
36
|
resolveEditorCommand,
|
|
29
37
|
resolveEditTarget,
|
|
@@ -350,7 +358,8 @@ async function tagsAction(fn, target, tags) {
|
|
|
350
358
|
console.log(`${article.path} \u2192 tags: ${article.tags.join(", ") || "(none)"}`);
|
|
351
359
|
}
|
|
352
360
|
async function indexAction(opts) {
|
|
353
|
-
const
|
|
361
|
+
const { engine } = await resolveDefaultSearchMode();
|
|
362
|
+
const provider = await loadSearchProvider(engine);
|
|
354
363
|
if (!provider) {
|
|
355
364
|
const installable = (await listSearchModes()).filter((m) => m.plugin !== "native");
|
|
356
365
|
console.log(
|
|
@@ -363,10 +372,16 @@ async function indexAction(opts) {
|
|
|
363
372
|
}
|
|
364
373
|
async function queryAction(term, opts) {
|
|
365
374
|
const names = opts.collection ? opts.collection.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
375
|
+
const expansions = [
|
|
376
|
+
...(opts.lex ?? []).map((query) => ({ type: "lex", query })),
|
|
377
|
+
...(opts.vec ?? []).map((query) => ({ type: "vec", query })),
|
|
378
|
+
...(opts.hyde ?? []).map((query) => ({ type: "hyde", query }))
|
|
379
|
+
];
|
|
366
380
|
const queryOpts = {
|
|
367
381
|
engine: opts.engine,
|
|
368
382
|
collection: names && names.length === 1 ? names[0] : names,
|
|
369
|
-
type: opts.type
|
|
383
|
+
type: opts.type,
|
|
384
|
+
...expansions.length > 0 ? { expansions } : {}
|
|
370
385
|
};
|
|
371
386
|
const outcome = await search(term, queryOpts);
|
|
372
387
|
const hits = outcome.hits;
|
|
@@ -456,7 +471,19 @@ async function configGetAction(key) {
|
|
|
456
471
|
const value = await getConfigValue(key);
|
|
457
472
|
console.log(value ?? "(unset)");
|
|
458
473
|
}
|
|
459
|
-
async function doctorAction() {
|
|
474
|
+
async function doctorAction(opts) {
|
|
475
|
+
if (opts.fix) {
|
|
476
|
+
console.log("Repairing plugins (installing missing tools)\u2026");
|
|
477
|
+
const repairs = await repairPlugins();
|
|
478
|
+
for (const r of repairs) {
|
|
479
|
+
for (const step of r.setup.steps) {
|
|
480
|
+
console.log(
|
|
481
|
+
`${icon(step.ok ? "ok" : "warn")} ${r.name} \xB7 ${step.step}${step.message ? ` \u2014 ${step.message}` : ""}`
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
console.log("");
|
|
486
|
+
}
|
|
460
487
|
const diagnostics = await doctor();
|
|
461
488
|
for (const d of diagnostics) {
|
|
462
489
|
console.log(`${icon(d.level)} ${d.message}`);
|
|
@@ -465,6 +492,69 @@ async function doctorAction() {
|
|
|
465
492
|
process.exitCode = 1;
|
|
466
493
|
}
|
|
467
494
|
}
|
|
495
|
+
function bundledTemplatesDir() {
|
|
496
|
+
return path4.resolve(path4.dirname(fileURLToPath4(import.meta.url)), "..", "templates");
|
|
497
|
+
}
|
|
498
|
+
async function templatesInitAction() {
|
|
499
|
+
const { seeded, skipped, dir } = await seedTemplates(bundledTemplatesDir());
|
|
500
|
+
console.log(`Templates \u2192 ${dir}`);
|
|
501
|
+
if (seeded.length > 0) console.log(` seeded: ${seeded.join(", ")}`);
|
|
502
|
+
if (skipped.length > 0) console.log(` kept existing (user overrides): ${skipped.join(", ")}`);
|
|
503
|
+
if (seeded.length === 0 && skipped.length === 0) console.log(" (no bundled templates found)");
|
|
504
|
+
}
|
|
505
|
+
async function templatesListAction(opts) {
|
|
506
|
+
const infos = await listTemplates(bundledTemplatesDir());
|
|
507
|
+
if (infos.length === 0) {
|
|
508
|
+
console.log("No bundled templates found.");
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
if (opts.json) {
|
|
512
|
+
console.log(JSON.stringify(infos, null, 2));
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
for (const t of infos) {
|
|
516
|
+
const budget = t.budget ? ` [${t.budget[0]}\u2013${t.budget[1]} tok]` : "";
|
|
517
|
+
console.log(`${t.shape} ${t.purpose}${budget}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
var parseNames = (csv) => csv.split(",").map((s) => s.trim()).filter(Boolean);
|
|
521
|
+
async function warnUnknownCollections(names) {
|
|
522
|
+
const known = new Set((await listCollections2()).map((c) => c.name));
|
|
523
|
+
const unknown = names.filter((n) => !known.has(n));
|
|
524
|
+
if (unknown.length > 0) {
|
|
525
|
+
console.error(`! not in your collections: ${unknown.join(", ")} (see: diffwiki collection list)`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function reportContext(collections, file) {
|
|
529
|
+
console.log(`context.collections = [${collections.join(", ")}] \u2192 ${file}`);
|
|
530
|
+
}
|
|
531
|
+
async function contextShowAction() {
|
|
532
|
+
const cols = await readContextCollections(process.cwd());
|
|
533
|
+
if (cols.length === 0) {
|
|
534
|
+
console.log("No recall context set. Set one: diffwiki context set <a,b,c>");
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
for (const c of cols) console.log(c);
|
|
538
|
+
}
|
|
539
|
+
async function contextSetAction(names) {
|
|
540
|
+
const cols = parseNames(names);
|
|
541
|
+
const file = await setContextCollections(process.cwd(), cols);
|
|
542
|
+
await warnUnknownCollections(cols);
|
|
543
|
+
reportContext(cols, file);
|
|
544
|
+
}
|
|
545
|
+
async function contextAddAction(names) {
|
|
546
|
+
const merged = await readContextCollections(process.cwd());
|
|
547
|
+
for (const n of parseNames(names)) if (!merged.includes(n)) merged.push(n);
|
|
548
|
+
const file = await setContextCollections(process.cwd(), merged);
|
|
549
|
+
await warnUnknownCollections(merged);
|
|
550
|
+
reportContext(merged, file);
|
|
551
|
+
}
|
|
552
|
+
async function contextRemoveAction(names) {
|
|
553
|
+
const drop = new Set(parseNames(names));
|
|
554
|
+
const kept = (await readContextCollections(process.cwd())).filter((c) => !drop.has(c));
|
|
555
|
+
const file = await setContextCollections(process.cwd(), kept);
|
|
556
|
+
reportContext(kept, file);
|
|
557
|
+
}
|
|
468
558
|
async function lintAction(opts) {
|
|
469
559
|
const result = await lintCollections(opts.collections);
|
|
470
560
|
for (const file of result.files) {
|
|
@@ -573,7 +663,7 @@ function createProgram() {
|
|
|
573
663
|
registerTagsSub("remove", "Remove from an article's tags", removeTags);
|
|
574
664
|
registerTagsSub("set", "Replace an article's tags", setTags);
|
|
575
665
|
const searchCmd = program.command("search").description("Search articles and manage the index");
|
|
576
|
-
searchCmd.command("query").alias("q").description("Search articles via the resolved search engine (native fallback if none)").option("--engine <name>", "search engine/plugin (default: config defaultSearch, else native)").option("-c, --collection <names>", "limit to a collection (comma-separated for a set)").option("-t, --type <type>", "search type (engine-defined, e.g. keyword|semantic|hybrid)").argument("[term]", "search term", "").action(
|
|
666
|
+
searchCmd.command("query").alias("q").description("Search articles via the resolved search engine (native fallback if none)").option("--engine <name>", "search engine/plugin (default: config defaultSearch, else native)").option("-c, --collection <names>", "limit to a collection (comma-separated for a set)").option("-t, --type <type>", "search type (engine-defined, e.g. keyword|semantic|hybrid)").option("--lex <query>", "BM25 keyword variant (repeatable)", collect, []).option("--vec <query>", "semantic variant \u2014 a natural-language question (repeatable)", collect, []).option("--hyde <query>", "hypothetical-answer passage variant (repeatable)", collect, []).argument("[term]", "search term (used as ranking intent when variants are given)", "").action(
|
|
577
667
|
withErrors(
|
|
578
668
|
(term, opts) => queryAction(term, opts)
|
|
579
669
|
)
|
|
@@ -600,10 +690,18 @@ function createProgram() {
|
|
|
600
690
|
ui.command("down").description("Stop the running diffwiki UI").action(withErrors(downAction));
|
|
601
691
|
ui.command("status").description("Show whether the diffwiki UI is running").action(withErrors(statusAction));
|
|
602
692
|
ui.command("open").description("Open the diffwiki UI in the browser (starting it if needed)").option("-p, --port <port>", "port to serve on", "4321").action(withErrors((opts) => openAction(opts)));
|
|
693
|
+
const context = program.command("context").description("Manage recall/search context (diffwiki.yaml \u2192 context.collections)");
|
|
694
|
+
context.command("show").description("Print the current recall-context collections").action(withErrors(contextShowAction));
|
|
695
|
+
context.command("set").description("Replace the recall-context collections").argument("<names>", "comma-separated collection names").action(withErrors((names) => contextSetAction(names)));
|
|
696
|
+
context.command("add").description("Add collections to the recall context").argument("<names>", "comma-separated collection names").action(withErrors((names) => contextAddAction(names)));
|
|
697
|
+
context.command("remove").description("Remove collections from the recall context").argument("<names>", "comma-separated collection names").action(withErrors((names) => contextRemoveAction(names)));
|
|
698
|
+
const templates = program.command("templates").description("Manage authoring templates (~/.diffwiki/templates)");
|
|
699
|
+
templates.command("init").description("Seed ~/.diffwiki/templates from the bundled templates (never overwrites your own)").action(withErrors(templatesInitAction));
|
|
700
|
+
templates.command("list").description("List templates with their shape + purpose (read from each template\u2019s frontmatter)").option("--json", "output as JSON").action(withErrors((opts) => templatesListAction(opts)));
|
|
603
701
|
const config = program.command("config").description("Read and write diffwiki config");
|
|
604
702
|
config.command("set").description("Set a config value (e.g. defaultCollection, or defaultSearch <engine[:type]>)").argument("<key>", "config key").argument("<value>", "config value").action(withErrors((key, value) => configSetAction(key, value)));
|
|
605
703
|
config.command("get").description("Read a config value").argument("<key>", "config key").action(withErrors((key) => configGetAction(key)));
|
|
606
|
-
program.command("doctor").description("Diagnose configuration issues").action(withErrors(doctorAction));
|
|
704
|
+
program.command("doctor").description("Diagnose configuration issues").option("--fix", "attempt to repair issues (re-provision plugins, auto-installing missing tools)").action(withErrors((opts) => doctorAction(opts)));
|
|
607
705
|
program.command("lint").description("Lint articles against the template shapes (frontmatter, budgets, references)").option("-c, --collections <scope>", "current | all | comma-separated names", "current").action(withErrors((opts) => lintAction(opts)));
|
|
608
706
|
return program;
|
|
609
707
|
}
|
|
@@ -611,14 +709,14 @@ function createProgram() {
|
|
|
611
709
|
// src/logging.ts
|
|
612
710
|
import { mkdirSync } from "fs";
|
|
613
711
|
import os from "os";
|
|
614
|
-
import
|
|
712
|
+
import path5 from "path";
|
|
615
713
|
import { configureSync, getConfig } from "@logtape/logtape";
|
|
616
714
|
import { getRotatingFileSink } from "@logtape/file";
|
|
617
715
|
import { resolveLogLevel } from "diffwiki-core";
|
|
618
716
|
var configured = false;
|
|
619
717
|
function diffwikiHome() {
|
|
620
718
|
const override = process.env.DIFFWIKI_HOME;
|
|
621
|
-
return override && override.length > 0 ? override :
|
|
719
|
+
return override && override.length > 0 ? override : path5.join(os.homedir(), ".diffwiki");
|
|
622
720
|
}
|
|
623
721
|
function resolveCliLevel(argv) {
|
|
624
722
|
if (argv.includes("-v") || argv.includes("--verbose")) return "debug";
|
|
@@ -635,9 +733,9 @@ function configureCliLogging(argv = process.argv) {
|
|
|
635
733
|
if (configured || getConfig() != null) return;
|
|
636
734
|
configured = true;
|
|
637
735
|
const level = resolveCliLevel(argv);
|
|
638
|
-
const logsDir =
|
|
736
|
+
const logsDir = path5.join(diffwikiHome(), "logs");
|
|
639
737
|
mkdirSync(logsDir, { recursive: true });
|
|
640
|
-
const logFile =
|
|
738
|
+
const logFile = path5.join(logsDir, "diffwiki.log");
|
|
641
739
|
const stderrSink = (record) => {
|
|
642
740
|
process.stderr.write(formatLine(record) + "\n");
|
|
643
741
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "diffwiki",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0-rc.202608040926.6b3b436",
|
|
4
4
|
"description": "diffwiki command-line interface",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"diffwiki": "./dist/bin.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
-
"dist"
|
|
11
|
+
"dist",
|
|
12
|
+
"templates"
|
|
12
13
|
],
|
|
13
14
|
"publishConfig": {
|
|
14
15
|
"access": "public"
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
"@logtape/logtape": "^2.2.4",
|
|
18
19
|
"@logtape/file": "^2.2.4",
|
|
19
20
|
"commander": "^13.0.0",
|
|
20
|
-
"diffwiki-core": "0.
|
|
21
|
+
"diffwiki-core": "0.15.0-rc.202608040926.6b3b436"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
24
|
"@types/node": "^22.0.0"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: collection-index
|
|
3
|
+
purpose: Groups and links a collection's articles — organises by topic, no prose narration.
|
|
4
|
+
budget: [100, 500]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
Use this shape for a collection's root index file. An index groups articles into topics, provides a one-line description for each, and links to them. It does not teach, demonstrate, or narrate.
|
|
9
|
+
|
|
10
|
+
Authoring rules:
|
|
11
|
+
- Adhere to the template structure
|
|
12
|
+
- One H2 per topic group; keep the group label short (2–4 words)
|
|
13
|
+
- One bullet per article: [Title](./slug.md) — one-line description
|
|
14
|
+
- No prose paragraphs, no examples, no code blocks, no References section
|
|
15
|
+
- Keep descriptions to a single clause — enough to distinguish siblings
|
|
16
|
+
- Do not copy over html comments or the template specific yaml frontmatter above this section. Write a diffwiki article yaml frontmatter as shown below this comment.
|
|
17
|
+
- Use concise descriptive titles in article frontmatter
|
|
18
|
+
- Tag the collection topic and add collection-index tag
|
|
19
|
+
- Default to public audience and published status for index files
|
|
20
|
+
-->
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
title: COLLECTION TITLE
|
|
25
|
+
tags:
|
|
26
|
+
|
|
27
|
+
- collection-index
|
|
28
|
+
- TAG1
|
|
29
|
+
- TAG2
|
|
30
|
+
audience: public
|
|
31
|
+
status: published
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## <Topic Group>
|
|
36
|
+
|
|
37
|
+
- [Article Title](./slug.md) — one-line description of what this article covers.
|
|
38
|
+
- [Article Title](./slug.md) — one-line description of what this article covers.
|
|
39
|
+
|
|
40
|
+
## <Second Topic Group>
|
|
41
|
+
|
|
42
|
+
- [Article Title](./slug.md) — one-line description of what this article covers.
|
|
43
|
+
- [Article Title](./slug.md) — one-line description of what this article covers.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: guide
|
|
3
|
+
purpose: Teaches the reasoning behind a topic — connects related patterns and explains why they work.
|
|
4
|
+
budget: [1500, 5000]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
Use this shape to teach. A guide explains the reasoning, trade-offs, and mental model behind a set of related patterns. It answers "why" and "how does this fit together" — not "what steps do I follow". If the reader needs a procedure, use recipe-with-steps. If they need a lookup, use reference.
|
|
9
|
+
|
|
10
|
+
Authoring rules:
|
|
11
|
+
- Adhere to the template structure
|
|
12
|
+
- One H2 per concept or insight; each section covers one idea
|
|
13
|
+
- State trade-offs and limits, not just the happy path
|
|
14
|
+
- Show, don't tell: replace prose explanations with Mermaid diagrams, tables, and code examples wherever possible. A sequence diagram beats three paragraphs of data-flow description. A comparison table beats a list of trade-offs.
|
|
15
|
+
- Soft-wrap prose
|
|
16
|
+
- Use inline references as needed for other wiki articles and external sources
|
|
17
|
+
- Do not copy over html comments or the template specific yaml frontmatter above this section. Write a diffwiki article yaml frontmatter as shown below this comment.
|
|
18
|
+
- Use concise descriptive titles in article frontmatter
|
|
19
|
+
- Tag programming languages, frameworks, topics of relevance to support vector embedding/search
|
|
20
|
+
- Default to public audience and draft status unless user specifies otherwise
|
|
21
|
+
-->
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
title: TITLE
|
|
26
|
+
tags:
|
|
27
|
+
|
|
28
|
+
- guide
|
|
29
|
+
- TAG1
|
|
30
|
+
- TAG2
|
|
31
|
+
- ...
|
|
32
|
+
audience: public
|
|
33
|
+
status: draft
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
One to three sentences. State the insight or principle this guide teaches and name the concrete systems or patterns it covers. State what the guide does not cover and link to the adjacent recipe or reference: see [<related>](./<related>.md).
|
|
38
|
+
|
|
39
|
+
## <The core concept — concrete noun, not "Overview">
|
|
40
|
+
|
|
41
|
+
State what this concept is and why it matters. Name the constraint or trade-off that makes it non-obvious.
|
|
42
|
+
|
|
43
|
+
```<lang>
|
|
44
|
+
<illustrative example — under ~40 lines>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Explain what the example demonstrates. Point to the part that carries the lesson.
|
|
48
|
+
|
|
49
|
+
## <Second concept or pattern>
|
|
50
|
+
|
|
51
|
+
State how this concept relates to the previous one. Describe the trade-off or decision point a reader faces between the two.
|
|
52
|
+
|
|
53
|
+
If the relationship needs a diagram:
|
|
54
|
+
|
|
55
|
+
```mermaid
|
|
56
|
+
graph LR
|
|
57
|
+
A[Concept A] --> B[Concept B]
|
|
58
|
+
B --> C[Outcome]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## <When this breaks / limits>
|
|
62
|
+
|
|
63
|
+
State the condition under which the pattern fails. One paragraph per failure mode. Link to the recipe that handles each case: see [<recipe>](../<collection>/<slug>.md).
|
|
64
|
+
|
|
65
|
+
## References
|
|
66
|
+
|
|
67
|
+
- [<Primary source>](<url>) — <one-line reason>
|
|
68
|
+
- [<Related recipe or guide>](../<collection>/<slug>.md) — <one-line reason>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: recipe
|
|
3
|
+
purpose: One contained pattern with a single canonical example.
|
|
4
|
+
budget: [50, 1000]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
Use this shape when the recipe is one contained pattern: intro + a single canonical example + notes. No ordered steps. If the recipe has ordered steps, use `recipe-with-steps-template.md` instead.
|
|
9
|
+
|
|
10
|
+
Authoring rules:
|
|
11
|
+
- Adhere to the template structure
|
|
12
|
+
- Soft-wrap prose
|
|
13
|
+
- Use inline references as needed for other wiki articles and external sources
|
|
14
|
+
- Do not copy over html comments or the template specific yaml frontmatter above this section. Write a diffwiki article yaml frontmatter as shown below this comment.
|
|
15
|
+
- Use concise descriptive titles in article frontmatter
|
|
16
|
+
- Tag programming languages, frameworks, topics of relevance to support vector embedding/search
|
|
17
|
+
- Default to public audience and draft status unless user specifies otherwise
|
|
18
|
+
-->
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
title: TITLE
|
|
23
|
+
tags:
|
|
24
|
+
|
|
25
|
+
- recipe
|
|
26
|
+
- TAG1
|
|
27
|
+
- TAG2
|
|
28
|
+
- ...
|
|
29
|
+
audience: public
|
|
30
|
+
status: draft
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
Write two to four sentences of intro prose. Describe what the recipe covers, utilizing concrete symbols and verbs a reader would search for. Mention adjacent phrasings when possible so vector search hits from alternative wording.
|
|
35
|
+
|
|
36
|
+
## Recipe
|
|
37
|
+
|
|
38
|
+
State the pattern in one sentence — what the code does and when to reach for it.
|
|
39
|
+
|
|
40
|
+
```<lang>
|
|
41
|
+
<code — the canonical example, under ~70 lines>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Follow-up notes only if the code isn't self-explanatory. Cover variations, edge cases, related recipes, etc.
|
|
45
|
+
|
|
46
|
+
## Troubleshooting
|
|
47
|
+
|
|
48
|
+
<!-- Optional. Include only if there are real, specific problems users hit. Skip if you'd otherwise write generic warnings. -->
|
|
49
|
+
|
|
50
|
+
- <Symptom> — <root cause> — <fix>.
|
|
51
|
+
- <Symptom> — <root cause> — <fix>.
|
|
52
|
+
|
|
53
|
+
## References
|
|
54
|
+
|
|
55
|
+
<!-- Do not omit even if references are also inline -->
|
|
56
|
+
|
|
57
|
+
- [<Name>](url) — <one-line reason (optional)>
|
|
58
|
+
- [<Related recipe>](../<collection>/<slug>.md) — <one-line reason (optional)>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: recipe-with-steps
|
|
3
|
+
purpose: An ordered sequence — do X, then Y, then Z.
|
|
4
|
+
budget: [100, 1500]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
Use this shape when the recipe is an ordered sequence — install X, then configure Y, then run Z. If there are no ordered steps, use `recipe-template.md` (simple) instead.
|
|
9
|
+
|
|
10
|
+
Authoring rules:
|
|
11
|
+
- Adhere to the template structure
|
|
12
|
+
- Number every step: `### Step 1 — <verb + object>`, and keep each step self-contained
|
|
13
|
+
- If the sequence grows past ~7 steps, split into two recipes
|
|
14
|
+
- Soft-wrap prose
|
|
15
|
+
- Use inline references as needed for other wiki articles and external sources
|
|
16
|
+
- Do not copy over html comments or the template specific yaml frontmatter above this section. Write a diffwiki article yaml frontmatter as shown below this comment.
|
|
17
|
+
- Use concise descriptive titles in article frontmatter
|
|
18
|
+
- Tag programming languages, frameworks, topics of relevance to support vector embedding/search
|
|
19
|
+
- Default to public audience and draft status unless user specifies otherwise
|
|
20
|
+
-->
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
title: TITLE
|
|
25
|
+
tags:
|
|
26
|
+
|
|
27
|
+
- recipe
|
|
28
|
+
- TAG1
|
|
29
|
+
- TAG2
|
|
30
|
+
- ...
|
|
31
|
+
audience: public
|
|
32
|
+
status: draft
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
Write two to four sentences of intro prose. State what the recipe accomplishes end-to-end, utilizing concrete tools and commands a reader would search for. Mention adjacent phrasings when possible so vector search hits from alternative wording.
|
|
37
|
+
|
|
38
|
+
## Recipe
|
|
39
|
+
|
|
40
|
+
One sentence framing the whole sequence — what state the reader is in when they start, and what state they're in when the last step succeeds.
|
|
41
|
+
|
|
42
|
+
### Step 1 — <verb + object>
|
|
43
|
+
|
|
44
|
+
One-sentence goal for the step.
|
|
45
|
+
|
|
46
|
+
```<lang>
|
|
47
|
+
<code — under ~70 lines>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Optional one-line verification (`<cmd> should print <result>`) or an inline link to the sub-topic.
|
|
51
|
+
|
|
52
|
+
### Step 2 — <verb + object>
|
|
53
|
+
|
|
54
|
+
One-sentence goal.
|
|
55
|
+
|
|
56
|
+
```<lang>
|
|
57
|
+
<code>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Step 3 — <verb + object>
|
|
61
|
+
|
|
62
|
+
<...>
|
|
63
|
+
|
|
64
|
+
## Troubleshooting
|
|
65
|
+
|
|
66
|
+
<!-- Optional. Only real, specific problems. Cross-link to steps by name so retrieval keeps the connection. -->
|
|
67
|
+
|
|
68
|
+
- <Symptom during step N> — <root cause> — <fix>.
|
|
69
|
+
- <Symptom during step N> — <root cause> — <fix>.
|
|
70
|
+
|
|
71
|
+
## References
|
|
72
|
+
|
|
73
|
+
<!-- Do not omit even if references are also inline -->
|
|
74
|
+
|
|
75
|
+
- [<Name>](url) — <one-line reason (optional)>
|
|
76
|
+
- [<Related recipe>](../<collection>/<slug>.md) — <one-line reason (optional)>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: reference
|
|
3
|
+
purpose: Authoritative description of commands, flags, config keys, types, or API endpoints — consult while working, not read linearly.
|
|
4
|
+
budget: [300, 2000]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
Use this shape for lookup tables: CLI flags, config keys, environment variables, type definitions, API endpoints, error codes. A reference entry describes one item — its name, type, default, and effect. It does not explain why, teach, or walk through steps.
|
|
9
|
+
|
|
10
|
+
Authoring rules:
|
|
11
|
+
- Adhere to the template structure
|
|
12
|
+
- Organize entries by the system's own structure (group flags by command, keys by section) — not by frequency of use
|
|
13
|
+
- One entry per item; keep descriptions to one sentence
|
|
14
|
+
- Mark required entries explicitly; note all defaults
|
|
15
|
+
- Add a minimal example only when the effect is not clear from the description alone
|
|
16
|
+
- Do not add prose narration between entries
|
|
17
|
+
- Soft-wrap prose in the intro and Notes sections only
|
|
18
|
+
- Do not copy over html comments or the template specific yaml frontmatter above this section. Write a diffwiki article yaml frontmatter as shown below this comment.
|
|
19
|
+
- Use concise descriptive titles in article frontmatter
|
|
20
|
+
- Tag the system, language, or framework this reference covers
|
|
21
|
+
- Default to public audience and draft status unless user specifies otherwise
|
|
22
|
+
-->
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
title: TITLE
|
|
27
|
+
tags:
|
|
28
|
+
|
|
29
|
+
- reference
|
|
30
|
+
- TAG1
|
|
31
|
+
- TAG2
|
|
32
|
+
- ...
|
|
33
|
+
audience: public
|
|
34
|
+
status: draft
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
One sentence: what system this page covers and the version or scope it applies to. Link to the upstream docs: [<System name>](<official-url>).
|
|
39
|
+
|
|
40
|
+
## <Command / Section / Group>
|
|
41
|
+
|
|
42
|
+
One sentence on what this command or group does.
|
|
43
|
+
|
|
44
|
+
| Flag / Key | Type | Default | Description |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| `<name>` | `<type>` | `<default>` | <one-sentence description> |
|
|
47
|
+
| `<name>` | `<type>` | — | **Required.** <one-sentence description> |
|
|
48
|
+
|
|
49
|
+
Minimal example where the flag combination is not obvious from the table:
|
|
50
|
+
|
|
51
|
+
```<lang>
|
|
52
|
+
<example>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## <Second command / section>
|
|
56
|
+
|
|
57
|
+
<same pattern>
|
|
58
|
+
|
|
59
|
+
## Notes
|
|
60
|
+
|
|
61
|
+
<!-- Optional. Warnings, known limits, version-specific behavior, or gotchas that apply across the whole reference — not to a single entry. -->
|
|
62
|
+
|
|
63
|
+
- <Warning or limit> — <what breaks and what to do instead>.
|
|
64
|
+
|
|
65
|
+
## References
|
|
66
|
+
|
|
67
|
+
<!-- Do not omit even if references are also inline -->
|
|
68
|
+
|
|
69
|
+
- [<Official docs>](<url>) — <one-line reason (optional)>
|
|
70
|
+
- [<Related recipe>](../<collection>/<slug>.md) — <one-line reason (optional)>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: session-transcript
|
|
3
|
+
purpose: dw-learn capture into the hidden transcripts collection (not linted).
|
|
4
|
+
---
|
|
5
|
+
<!-- SESSION TRANSCRIPT. The agent fills this by introspecting its own session.
|
|
6
|
+
Goes into the hidden `transcripts` collection with `--audience system`; NOT linted
|
|
7
|
+
as a knowledge entry. Terse and factual — raw material for dw-learn, not a doc.
|
|
8
|
+
Title (passed to the CLI) is "<project>/<date>-<short-id>"; tags are
|
|
9
|
+
[transcript, <tool>, <project>]. Do not write frontmatter — the CLI owns it. -->
|
|
10
|
+
|
|
11
|
+
**Tool:** <claude-code|codex|opencode|goose|pi> · **Project:** <repo-or-path> · **Date:** <YYYY-MM-DD> · **Session:** <id-if-known>
|
|
12
|
+
|
|
13
|
+
## Worked on
|
|
14
|
+
- <goal — what was attempted and the outcome>
|
|
15
|
+
|
|
16
|
+
## Issues & learnings
|
|
17
|
+
- <problem — root cause — how it was resolved (or that it's unresolved)>
|
|
18
|
+
|
|
19
|
+
## Decisions & patterns
|
|
20
|
+
- <architectural decision or reusable pattern observed — and why>
|
|
21
|
+
|
|
22
|
+
## Key tool actions
|
|
23
|
+
- <notable commands, files created/changed, workflows — the reproducible bits>
|
|
24
|
+
|
|
25
|
+
## Open threads
|
|
26
|
+
- <unfinished work, follow-ups, questions for next time>
|