openalmanac 0.2.3 → 0.2.5
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/tools/articles.js +85 -4
- package/package.json +1 -1
package/dist/tools/articles.js
CHANGED
|
@@ -5,6 +5,85 @@ import { stringify as yamlStringify } from "yaml";
|
|
|
5
5
|
import { request, ARTICLES_DIR } from "../auth.js";
|
|
6
6
|
import { validateArticle, parseFrontmatter } from "../validate.js";
|
|
7
7
|
const SLUG_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
8
|
+
const WRITING_GUIDE = `
|
|
9
|
+
## Article structure
|
|
10
|
+
|
|
11
|
+
\`\`\`yaml
|
|
12
|
+
---
|
|
13
|
+
article_id: the-slug
|
|
14
|
+
title: Article Title
|
|
15
|
+
sources:
|
|
16
|
+
- url: https://example.com
|
|
17
|
+
title: Source Title
|
|
18
|
+
infobox:
|
|
19
|
+
header:
|
|
20
|
+
image_url: https://... # optional hero image
|
|
21
|
+
subtitle: Short tagline
|
|
22
|
+
details:
|
|
23
|
+
- key: Born
|
|
24
|
+
value: January 1, 1990
|
|
25
|
+
- key: Occupation
|
|
26
|
+
value: Scientist
|
|
27
|
+
links:
|
|
28
|
+
- label: Official site
|
|
29
|
+
url: https://...
|
|
30
|
+
sections:
|
|
31
|
+
- type: timeline # chronological events
|
|
32
|
+
title: Career Timeline
|
|
33
|
+
items:
|
|
34
|
+
- primary: "2010"
|
|
35
|
+
value: Started company
|
|
36
|
+
- type: list # bullet list
|
|
37
|
+
title: Known For
|
|
38
|
+
items:
|
|
39
|
+
- value: First achievement
|
|
40
|
+
- value: Second achievement
|
|
41
|
+
- type: tags # inline tags/chips
|
|
42
|
+
title: Genres
|
|
43
|
+
items:
|
|
44
|
+
- value: Rock
|
|
45
|
+
- value: Jazz
|
|
46
|
+
- type: grid # image grid
|
|
47
|
+
title: Gallery
|
|
48
|
+
items:
|
|
49
|
+
- image_url: https://...
|
|
50
|
+
value: Caption
|
|
51
|
+
- type: table # rows with label+value
|
|
52
|
+
title: Statistics
|
|
53
|
+
items:
|
|
54
|
+
- label: Height
|
|
55
|
+
value: "6'2\\""
|
|
56
|
+
- type: key_value # simple key-value pairs
|
|
57
|
+
title: Quick Facts
|
|
58
|
+
items:
|
|
59
|
+
- key: Population
|
|
60
|
+
value: "1.4 billion"
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
Article body with [1] citation markers...
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
## Infobox
|
|
67
|
+
|
|
68
|
+
Include an infobox for any article about a person, place, organization, event, or concept. Pick the section types that fit — you don't need all six.
|
|
69
|
+
|
|
70
|
+
## Citations
|
|
71
|
+
|
|
72
|
+
- Mark claims with [N] after punctuation: "The population is 1.4 billion.[1]"
|
|
73
|
+
- Number sequentially starting at [1]
|
|
74
|
+
- Every source in the sources list must be referenced at least once in the body
|
|
75
|
+
- Every [N] marker must have a matching source
|
|
76
|
+
|
|
77
|
+
## Writing quality
|
|
78
|
+
|
|
79
|
+
- Every sentence should contain a specific fact the reader didn't know
|
|
80
|
+
- No filler phrases ("It is worth noting", "In today's world", "Throughout history")
|
|
81
|
+
- No promotional language ("revolutionary", "groundbreaking", "game-changing")
|
|
82
|
+
- No inflated significance ("one of the most important", "changed the world forever")
|
|
83
|
+
- No vague attribution ("many experts say", "it is widely regarded")
|
|
84
|
+
- No formulaic conclusions ("In conclusion", "continues to shape")
|
|
85
|
+
- Write like a concise encyclopedia, not a blog post
|
|
86
|
+
`.trim();
|
|
8
87
|
function ensureArticlesDir() {
|
|
9
88
|
mkdirSync(ARTICLES_DIR, { recursive: true });
|
|
10
89
|
}
|
|
@@ -27,7 +106,8 @@ export function registerArticleTools(server) {
|
|
|
27
106
|
server.addTool({
|
|
28
107
|
name: "pull",
|
|
29
108
|
description: "Download an article from OpenAlmanac to your local working directory (~/.openalmanac/articles/). " +
|
|
30
|
-
"The file is saved as {slug}.md with YAML frontmatter.
|
|
109
|
+
"The file is saved as {slug}.md with YAML frontmatter. Returns a writing guide covering article structure, infobox format, citations, and quality rules. " +
|
|
110
|
+
"Edit the file locally, then use push to publish changes.",
|
|
31
111
|
parameters: z.object({
|
|
32
112
|
slug: z.string().describe("Article slug (e.g. 'machine-learning')"),
|
|
33
113
|
}),
|
|
@@ -42,13 +122,14 @@ export function registerArticleTools(server) {
|
|
|
42
122
|
const { frontmatter, content } = parseFrontmatter(markdown);
|
|
43
123
|
const title = frontmatter.title || "(untitled)";
|
|
44
124
|
const wordCount = content.trim().split(/\s+/).filter(Boolean).length;
|
|
45
|
-
return `Pulled "${title}" to ${filePath}\n${wordCount} words, ${frontmatter.sources?.length ?? 0} sources.\
|
|
125
|
+
return `Pulled "${title}" to ${filePath}\n${wordCount} words, ${frontmatter.sources?.length ?? 0} sources.\n\n${WRITING_GUIDE}`;
|
|
46
126
|
},
|
|
47
127
|
});
|
|
48
128
|
server.addTool({
|
|
49
129
|
name: "new",
|
|
50
130
|
description: "Create a new article scaffold in your local working directory (~/.openalmanac/articles/). " +
|
|
51
|
-
"The file is created with YAML frontmatter and an empty body.
|
|
131
|
+
"The file is created with YAML frontmatter and an empty body. Returns a writing guide covering article structure, infobox format, citations, and quality rules. " +
|
|
132
|
+
"Edit the file to add content and sources, then use push to publish.",
|
|
52
133
|
parameters: z.object({
|
|
53
134
|
slug: z
|
|
54
135
|
.string()
|
|
@@ -67,7 +148,7 @@ export function registerArticleTools(server) {
|
|
|
67
148
|
const frontmatter = yamlStringify({ article_id: slug, title, sources: [] });
|
|
68
149
|
const scaffold = `---\n${frontmatter}---\n\n`;
|
|
69
150
|
writeFileSync(filePath, scaffold, "utf-8");
|
|
70
|
-
return `Created ${filePath}\
|
|
151
|
+
return `Created ${filePath}\n\n${WRITING_GUIDE}`;
|
|
71
152
|
},
|
|
72
153
|
});
|
|
73
154
|
server.addTool({
|