openalmanac 0.2.2 → 0.2.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.
- package/dist/server.js +2 -0
- package/dist/tools/articles.js +86 -5
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -16,6 +16,8 @@ export function createServer() {
|
|
|
16
16
|
"Before writing or editing any article, read https://www.openalmanac.org/ai-patterns-to-avoid.md " +
|
|
17
17
|
"— it covers AI writing patterns that erode trust (inflated significance, promotional language, " +
|
|
18
18
|
"formulaic conclusions, etc.). Every sentence should contain a specific fact the reader didn't know.\n\n" +
|
|
19
|
+
"After creating an article, always share the exact URL from the push response with the user. " +
|
|
20
|
+
"This URL includes a celebration page for the newly created article.\n\n" +
|
|
19
21
|
"When working with tool results, write down any important information you might need later " +
|
|
20
22
|
"in your response, as the original tool result may be cleared later.",
|
|
21
23
|
});
|
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
|
+
- label: Born
|
|
24
|
+
value: January 1, 1990
|
|
25
|
+
- label: 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
|
+
- label: "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
|
+
- label: 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({
|
|
@@ -107,7 +188,7 @@ export function registerArticleTools(server) {
|
|
|
107
188
|
contentType: "text/markdown",
|
|
108
189
|
});
|
|
109
190
|
const data = (await resp.json());
|
|
110
|
-
const articleUrl = `https://www.openalmanac.org/
|
|
191
|
+
const articleUrl = `https://www.openalmanac.org/article/${slug}?celebrate=true`;
|
|
111
192
|
return `Pushed successfully.\n${articleUrl}\n${JSON.stringify(data, null, 2)}`;
|
|
112
193
|
},
|
|
113
194
|
});
|