diffwiki 0.17.2 → 0.17.3-rc.202610201004.ae57be7
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 +66 -12
- package/package.json +2 -2
- package/templates/collection-index-template.md +1 -1
- package/templates/dream-learning-template.md +30 -0
- package/templates/external-source-extract-template.md +29 -0
- package/templates/history-template.md +29 -0
- package/templates/session-transcript-template.md +12 -12
package/dist/bin.js
CHANGED
|
@@ -7,6 +7,7 @@ import { ensureHome } from "diffwiki-core";
|
|
|
7
7
|
import { spawn as spawn4 } from "child_process";
|
|
8
8
|
import path5 from "path";
|
|
9
9
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
10
|
+
import { readFile } from "fs/promises";
|
|
10
11
|
import { Command, Option } from "commander";
|
|
11
12
|
import {
|
|
12
13
|
addExternalCollection,
|
|
@@ -14,6 +15,13 @@ import {
|
|
|
14
15
|
collectionGitStatus,
|
|
15
16
|
createArticle,
|
|
16
17
|
createCollection,
|
|
18
|
+
createMetaRecord,
|
|
19
|
+
initMeta,
|
|
20
|
+
reindexMeta,
|
|
21
|
+
findCollection,
|
|
22
|
+
parseFrontmatter,
|
|
23
|
+
CollectionNotFoundError,
|
|
24
|
+
DiffwikiError as DiffwikiError2,
|
|
17
25
|
doctor,
|
|
18
26
|
getConfigValue,
|
|
19
27
|
initRepoWiki,
|
|
@@ -38,10 +46,9 @@ import {
|
|
|
38
46
|
resolveCwdCollection,
|
|
39
47
|
resolveEditorCommand,
|
|
40
48
|
resolveEditTarget,
|
|
41
|
-
setArticleMeta,
|
|
42
49
|
setConfigValue,
|
|
43
50
|
setTags,
|
|
44
|
-
|
|
51
|
+
updateArticle
|
|
45
52
|
} from "diffwiki-core";
|
|
46
53
|
|
|
47
54
|
// src/version.ts
|
|
@@ -359,15 +366,18 @@ async function createArticleAction(target, opts) {
|
|
|
359
366
|
async function updateArticleAction(target, opts) {
|
|
360
367
|
const tagList = splitTags(opts.tag);
|
|
361
368
|
const hasMeta = opts.audience !== void 0 || opts.status !== void 0;
|
|
362
|
-
if (opts.body === void 0 && tagList.length === 0 && !hasMeta) {
|
|
363
|
-
console.error("Nothing to update \u2014 pass -b/--body, -t/--tag, --audience, and/or --status.");
|
|
369
|
+
if (opts.title === void 0 && opts.body === void 0 && tagList.length === 0 && !hasMeta) {
|
|
370
|
+
console.error("Nothing to update \u2014 pass --title, -b/--body, -t/--tag, --audience, and/or --status.");
|
|
364
371
|
process.exitCode = 1;
|
|
365
372
|
return;
|
|
366
373
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
374
|
+
const article = await updateArticle(target, {
|
|
375
|
+
title: opts.title,
|
|
376
|
+
body: opts.body,
|
|
377
|
+
...tagList.length ? { tags: tagList } : {},
|
|
378
|
+
audience: opts.audience,
|
|
379
|
+
status: opts.status
|
|
380
|
+
});
|
|
371
381
|
console.log(`Updated ${article.path}`);
|
|
372
382
|
}
|
|
373
383
|
async function removeArticleAction(target) {
|
|
@@ -524,9 +534,9 @@ async function templatesInitAction() {
|
|
|
524
534
|
if (seeded.length === 0 && skipped.length === 0) console.log(" (no bundled templates found)");
|
|
525
535
|
}
|
|
526
536
|
async function templatesListAction(opts) {
|
|
527
|
-
const infos = await listTemplates(bundledTemplatesDir());
|
|
537
|
+
const infos = await listTemplates(bundledTemplatesDir(), opts.category);
|
|
528
538
|
if (infos.length === 0) {
|
|
529
|
-
console.log("No
|
|
539
|
+
console.log("No templates found.");
|
|
530
540
|
return;
|
|
531
541
|
}
|
|
532
542
|
if (opts.json) {
|
|
@@ -538,6 +548,38 @@ async function templatesListAction(opts) {
|
|
|
538
548
|
console.log(`${t.shape} ${t.purpose}${budget}`);
|
|
539
549
|
}
|
|
540
550
|
}
|
|
551
|
+
function reportMeta(result, opts) {
|
|
552
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
553
|
+
else {
|
|
554
|
+
console.log(`Metadata: ${result.created.length} mirrors created, ${result.kept.length} kept.`);
|
|
555
|
+
for (const file of result.index_paths) console.log(file);
|
|
556
|
+
}
|
|
557
|
+
for (const warning of result.warnings) console.error(`! ${warning}`);
|
|
558
|
+
for (const error of result.errors) console.error(`\u2716 ${error}`);
|
|
559
|
+
if (result.errors.length) process.exitCode = 1;
|
|
560
|
+
}
|
|
561
|
+
async function metaInitAction(name, opts) {
|
|
562
|
+
const entries = name ? [await findCollection(name)] : await listCollections2();
|
|
563
|
+
if (entries.some((entry) => !entry)) throw new CollectionNotFoundError(name);
|
|
564
|
+
reportMeta(await initMeta(entries.filter((entry) => entry !== void 0)), opts);
|
|
565
|
+
}
|
|
566
|
+
async function metaNewAction(target, opts) {
|
|
567
|
+
const colon = target.indexOf(":");
|
|
568
|
+
const name = colon < 0 ? target : target.slice(0, colon);
|
|
569
|
+
const articlePath = colon < 0 ? void 0 : target.slice(colon + 1);
|
|
570
|
+
const entry = await findCollection(name);
|
|
571
|
+
if (!entry) throw new CollectionNotFoundError(name);
|
|
572
|
+
const template = (await listTemplates(bundledTemplatesDir(), "meta")).find((item) => item.shape === opts.template);
|
|
573
|
+
if (!template) throw new DiffwikiError2(`Metadata template ${opts.template} not found. Run: diffwiki templates init`);
|
|
574
|
+
try {
|
|
575
|
+
const { body } = parseFrontmatter(await readFile(template.path, "utf8"));
|
|
576
|
+
const record = await createMetaRecord(entry, articlePath, opts.template, body.replace(/<!--[\s\S]*?-->/g, ""));
|
|
577
|
+
console.log(opts.json ? JSON.stringify(record, null, 2) : record.path);
|
|
578
|
+
} catch (err) {
|
|
579
|
+
if (err instanceof DiffwikiError2) throw err;
|
|
580
|
+
throw new DiffwikiError2(`Cannot capture ${target}: ${String(err)}`);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
541
583
|
var parseNames = (csv) => csv.split(",").map((s) => s.trim()).filter(Boolean);
|
|
542
584
|
async function warnUnknownCollections(names) {
|
|
543
585
|
const known = new Set((await listCollections2()).map((c) => c.name));
|
|
@@ -702,7 +744,7 @@ function createProgram() {
|
|
|
702
744
|
"deprecated"
|
|
703
745
|
])
|
|
704
746
|
).action(withErrors((target, opts) => createArticleAction(target, opts)));
|
|
705
|
-
article.command("update").description("Update an article's body, tags, audience, and/or status").argument("<target>", '"collection:slug"').option("-b, --body <markdown>", "replace the article body").option("-t, --tag <tag>", "replace all tags (repeatable, comma-separated)", collect, []).addOption(new Option("--audience <audience>", "set visibility").choices(["public", "private", "system"])).addOption(new Option("--status <status>", "set publish status").choices(["draft", "published", "deprecated"])).action(withErrors((target, opts) => updateArticleAction(target, opts)));
|
|
747
|
+
article.command("update").description("Update an article's display title, body, tags, audience, and/or status").argument("<target>", '"collection:slug"').option("--title <title>", "set the display title without renaming the file").option("-b, --body <markdown>", "replace the article body").option("-t, --tag <tag>", "replace all tags (repeatable, comma-separated)", collect, []).addOption(new Option("--audience <audience>", "set visibility").choices(["public", "private", "system"])).addOption(new Option("--status <status>", "set publish status").choices(["draft", "published", "deprecated"])).action(withErrors((target, opts) => updateArticleAction(target, opts)));
|
|
706
748
|
article.command("remove").description("Delete an article").argument("<target>", '"collection:slug"').action(withErrors((target) => removeArticleAction(target)));
|
|
707
749
|
article.command("edit").description("Open an article in your editor \u2014 GUI not required").argument("<target>", '"collection:slug"').option("--editor <cmd>", "editor command (overrides config `editor`, $VISUAL, $EDITOR)").action(withErrors((target, opts) => editAction(target, opts.editor)));
|
|
708
750
|
const tags = program.command("tags").description("Manage an article's tags");
|
|
@@ -745,9 +787,21 @@ function createProgram() {
|
|
|
745
787
|
context.command("set").description("Replace the recall-context collections").argument("<names>", "comma-separated collection names").action(withErrors((names) => contextSetAction(names)));
|
|
746
788
|
context.command("add").description("Add collections to the recall context").argument("<names>", "comma-separated collection names").action(withErrors((names) => contextAddAction(names)));
|
|
747
789
|
context.command("remove").description("Remove collections from the recall context").argument("<names>", "comma-separated collection names").action(withErrors((names) => contextRemoveAction(names)));
|
|
790
|
+
const meta = program.command("meta").description("Capture raw sources beside collection and article paths");
|
|
791
|
+
meta.command("init").description("Create missing source manifests for existing articles").argument("[collection]", "limit to one registered collection").option("--json", "output paths and diagnostics as JSON").action(withErrors(metaInitAction));
|
|
792
|
+
meta.command("new").description("Create a source-record template for a collection or exact article filename").argument("<target>", "collection or collection:relative-file.md").addOption(
|
|
793
|
+
new Option("--template <kind>", "source template").choices(["history", "external-source-extract", "dream-learning"]).makeOptionMandatory()
|
|
794
|
+
).option("--json", "output the record and index paths as JSON").action(withErrors(metaNewAction));
|
|
795
|
+
meta.command("reindex").description("Refresh generated source listings from current metadata files").argument("[collection]", "limit to one metadata collection").option("--json", "output paths and diagnostics as JSON").action(
|
|
796
|
+
withErrors(
|
|
797
|
+
async (name, opts) => reportMeta(await reindexMeta(name), opts)
|
|
798
|
+
)
|
|
799
|
+
);
|
|
748
800
|
const templates = program.command("templates").description("Manage authoring templates (~/.diffwiki/templates)");
|
|
749
801
|
templates.command("init").description("Seed ~/.diffwiki/templates from the bundled templates (never overwrites your own)").action(withErrors(templatesInitAction));
|
|
750
|
-
templates.command("list").description("List templates with their shape + purpose (read from each template\u2019s frontmatter)").
|
|
802
|
+
templates.command("list").description("List templates with their shape + purpose (read from each template\u2019s frontmatter)").addOption(
|
|
803
|
+
new Option("--category <category>", "template category").choices(["article", "meta", "all"]).default("article")
|
|
804
|
+
).option("--json", "output as JSON").action(withErrors((opts) => templatesListAction(opts)));
|
|
751
805
|
const config = program.command("config").description("Read and write diffwiki config");
|
|
752
806
|
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)));
|
|
753
807
|
config.command("get").description("Read a config value").argument("<key>", "config key").action(withErrors((key) => configGetAction(key)));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "diffwiki",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.3-rc.202610201004.ae57be7",
|
|
4
4
|
"description": "diffwiki command-line interface",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@logtape/logtape": "^2.2.4",
|
|
19
19
|
"@logtape/file": "^2.2.4",
|
|
20
20
|
"commander": "^13.0.0",
|
|
21
|
-
"diffwiki-core": "0.17.
|
|
21
|
+
"diffwiki-core": "0.17.3-rc.202610201004.ae57be7"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^22.0.0"
|
|
@@ -18,7 +18,7 @@ Authoring rules:
|
|
|
18
18
|
- No prose paragraphs, no examples, no code blocks
|
|
19
19
|
- Keep descriptions to a single clause — enough to distinguish siblings
|
|
20
20
|
- 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.
|
|
21
|
-
- Use concise descriptive titles in article frontmatter
|
|
21
|
+
- Use concise descriptive titles in article frontmatter. An index.md filename must not become the display title "index" or a path ending in /index.
|
|
22
22
|
- Tag the collection topic and add collection-index tag
|
|
23
23
|
- Default to public audience and published status for index files
|
|
24
24
|
-->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: dream-learning
|
|
3
|
+
category: meta
|
|
4
|
+
purpose: Keep one dream change inspectable through its raw evidence and observed result.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Run
|
|
8
|
+
|
|
9
|
+
- Tool: dw-dream
|
|
10
|
+
- Run / original event time: unknown
|
|
11
|
+
|
|
12
|
+
## Raw user requests
|
|
13
|
+
|
|
14
|
+
Not captured. Quote the request and include its session/message location. Do not infer preferences.
|
|
15
|
+
|
|
16
|
+
## Raw session/tool outputs
|
|
17
|
+
|
|
18
|
+
Not captured. Include speaker, command, output, exit status, and source locations. Label assistant text as generated and unverified.
|
|
19
|
+
|
|
20
|
+
## Source snippets
|
|
21
|
+
|
|
22
|
+
Not captured. Preserve the relevant original code or document excerpts and their locations.
|
|
23
|
+
|
|
24
|
+
## Source record links
|
|
25
|
+
|
|
26
|
+
None captured. Link preserved primary evidence from every affected page.
|
|
27
|
+
|
|
28
|
+
## Change and result
|
|
29
|
+
|
|
30
|
+
Not captured. Include affected paths, the exact patch or action, and the observed result. Record partial failures plainly.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: external-source-extract
|
|
3
|
+
category: meta
|
|
4
|
+
purpose: Store retrieved documentation, web page, or paper excerpts with their origin.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Source
|
|
8
|
+
|
|
9
|
+
- Requested URL: unknown
|
|
10
|
+
- Resolved URL: unknown
|
|
11
|
+
- Title / author / publisher: unknown
|
|
12
|
+
- Published date / document version: unknown
|
|
13
|
+
- Retrieved at (UTC): unknown
|
|
14
|
+
- Heading / page / line locator: unknown
|
|
15
|
+
|
|
16
|
+
## Exact excerpt
|
|
17
|
+
|
|
18
|
+
Not captured. Quote the retrieved text with enough context. Do not substitute a summary.
|
|
19
|
+
|
|
20
|
+
## Capture details
|
|
21
|
+
|
|
22
|
+
- Format / extraction method: unknown
|
|
23
|
+
- Coverage / omitted sections / truncation: unknown
|
|
24
|
+
- Retrieval failure or redactions: unknown
|
|
25
|
+
- Original attachment path / checksum, if retained: unknown
|
|
26
|
+
|
|
27
|
+
## Source record links
|
|
28
|
+
|
|
29
|
+
None captured. Link related records without replacing their original text.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
shape: history
|
|
3
|
+
category: meta
|
|
4
|
+
purpose: Preserve original user requests, session outputs, and source code.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Raw user requests
|
|
8
|
+
|
|
9
|
+
Not captured. Include exact quotations, speaker, original time, and session/message location when known.
|
|
10
|
+
|
|
11
|
+
## Stated rationale
|
|
12
|
+
|
|
13
|
+
Not captured. Quote the user's explanation. Do not infer a reason.
|
|
14
|
+
|
|
15
|
+
## Raw session/tool outputs
|
|
16
|
+
|
|
17
|
+
Not captured. Include the command, output, exit status, and source location. Label assistant text as generated and unverified.
|
|
18
|
+
|
|
19
|
+
## Source snippets
|
|
20
|
+
|
|
21
|
+
Not captured. Preserve code and whitespace. Include repository, file, symbol/lines, commit when known, and local changes.
|
|
22
|
+
|
|
23
|
+
## Source record links
|
|
24
|
+
|
|
25
|
+
None captured. Link any shared collection evidence or earlier records.
|
|
26
|
+
|
|
27
|
+
## Change and result
|
|
28
|
+
|
|
29
|
+
Not captured. Name affected files and the observed result. Keep capture time separate from the original event time.
|
|
@@ -2,25 +2,25 @@
|
|
|
2
2
|
shape: session-transcript
|
|
3
3
|
purpose: dw-learn capture into the hidden transcripts collection (not linted).
|
|
4
4
|
---
|
|
5
|
-
<!-- SESSION TRANSCRIPT.
|
|
5
|
+
<!-- SESSION TRANSCRIPT. Capture original inputs and outputs available in the session.
|
|
6
6
|
Goes into the hidden `transcripts` collection with `--audience system`; NOT linted
|
|
7
|
-
as a knowledge entry.
|
|
7
|
+
as a knowledge entry. Do not invent dialogue, causes, preferences, or lessons.
|
|
8
8
|
Title (passed to the CLI) is "<project>/<date>-<short-id>"; tags are
|
|
9
9
|
[transcript, <tool>, <project>]. Do not write frontmatter — the CLI owns it. -->
|
|
10
10
|
|
|
11
11
|
**Tool:** <claude-code|codex|opencode|goose|pi> · **Project:** <repo-or-path> · **Date:** <YYYY-MM-DD> · **Session:** <id-if-known>
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
- <
|
|
13
|
+
## Raw user requests
|
|
14
|
+
- <exact quotation, original time, session/message location>
|
|
15
15
|
|
|
16
|
-
##
|
|
17
|
-
- <
|
|
16
|
+
## Raw session outputs
|
|
17
|
+
- <speaker/role, exact output, source message location; label assistant text generated/unverified>
|
|
18
18
|
|
|
19
|
-
##
|
|
20
|
-
- <
|
|
19
|
+
## Commands and results
|
|
20
|
+
- <command, exact relevant stdout/stderr, exit status, original event time>
|
|
21
21
|
|
|
22
|
-
##
|
|
23
|
-
- <
|
|
22
|
+
## Source snippets
|
|
23
|
+
- <original code/document excerpt, repository, file/lines, commit/version, local changes>
|
|
24
24
|
|
|
25
|
-
##
|
|
26
|
-
- <
|
|
25
|
+
## Source locations and gaps
|
|
26
|
+
- <source record or attachment links; omitted/redacted/unavailable material>
|