openalmanac 0.4.0 → 0.4.2
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/cli.js +1 -1
- package/dist/instructions.d.ts +1 -0
- package/dist/instructions.js +150 -0
- package/dist/onboarding-copy.d.ts +1 -1
- package/dist/onboarding-copy.js +6 -6
- package/dist/openalmanac_mcp-0.3.1-py3-none-any.whl +0 -0
- package/dist/openalmanac_mcp-0.3.1.tar.gz +0 -0
- package/dist/openalmanac_mcp-0.3.2-py3-none-any.whl +0 -0
- package/dist/openalmanac_mcp-0.3.2.tar.gz +0 -0
- package/dist/server.js +3 -149
- package/dist/setup/clients.d.ts +10 -0
- package/dist/setup/clients.js +291 -0
- package/dist/setup/config-files.d.ts +43 -0
- package/dist/setup/config-files.js +257 -0
- package/dist/setup/index.d.ts +2 -0
- package/dist/setup/index.js +55 -0
- package/dist/setup/permissions.d.ts +3 -0
- package/dist/setup/permissions.js +52 -0
- package/dist/{setup.d.ts → setup/reddit.d.ts} +0 -1
- package/dist/setup/reddit.js +69 -0
- package/dist/setup/tui.d.ts +7 -0
- package/dist/setup/tui.js +517 -0
- package/dist/setup/types.d.ts +43 -0
- package/dist/setup/types.js +1 -0
- package/dist/tool-registry.js +1 -1
- package/dist/tools/{pages.js → pages/index.js} +8 -164
- package/dist/tools/pages/publish-format.d.ts +48 -0
- package/dist/tools/pages/publish-format.js +92 -0
- package/dist/tools/pages/workspace.d.ts +7 -0
- package/dist/tools/pages/workspace.js +14 -0
- package/dist/tools/pages/writing-guide.d.ts +1 -0
- package/dist/tools/pages/writing-guide.js +56 -0
- package/package.json +1 -1
- package/dist/setup.js +0 -1216
- package/dist/validate.d.ts +0 -971
- package/dist/validate.js +0 -154
- /package/dist/tools/{pages.d.ts → pages/index.d.ts} +0 -0
package/dist/validate.js
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { parse as parseYaml } from "yaml";
|
|
2
|
-
import { z, ZodError } from "zod";
|
|
3
|
-
// ── Primitives ──────────────────────────────────────────────────
|
|
4
|
-
const sourceKeyRe = /^[a-z0-9]+-[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
5
|
-
// Match pydantic's `date` coercion: a bare YYYY-MM-DD date, OR any ISO-8601
|
|
6
|
-
// datetime prefix — pydantic accepts "2026-04-17T00:00:00Z" as a date. yaml
|
|
7
|
-
// may deserialize either as a `Date` object or a string.
|
|
8
|
-
const isoDateLikeRe = /^\d{4}-\d{2}-\d{2}([T ].*)?$/;
|
|
9
|
-
const accessedDateSchema = z.union([
|
|
10
|
-
z.date(),
|
|
11
|
-
z.string().regex(isoDateLikeRe, "Must be YYYY-MM-DD (optionally with an ISO time suffix)"),
|
|
12
|
-
]);
|
|
13
|
-
// ── Source — mirrors backend/src/schemas/source_schemas.py ──────
|
|
14
|
-
export const sourceSchema = z.object({
|
|
15
|
-
key: z
|
|
16
|
-
.string()
|
|
17
|
-
.min(3)
|
|
18
|
-
.regex(sourceKeyRe, "Must be kebab-case with at least one hyphen (e.g. 'nytimes-climate-report')"),
|
|
19
|
-
url: z
|
|
20
|
-
.string()
|
|
21
|
-
.min(1)
|
|
22
|
-
.regex(/^https?:\/\//, "Must start with http:// or https://"),
|
|
23
|
-
title: z.string().min(1).max(500),
|
|
24
|
-
accessed_date: accessedDateSchema,
|
|
25
|
-
}).strict();
|
|
26
|
-
// ── Infobox — mirrors backend/src/schemas/infobox_schemas.py ────
|
|
27
|
-
const keyValueItemSchema = z.object({
|
|
28
|
-
key: z.string(),
|
|
29
|
-
value: z.string(),
|
|
30
|
-
}).strict();
|
|
31
|
-
const headerBlockSchema = z.object({
|
|
32
|
-
image_url: z.string().nullable().optional(),
|
|
33
|
-
subtitle: z.string().nullable().optional(),
|
|
34
|
-
details: z.array(keyValueItemSchema).default([]),
|
|
35
|
-
// STRICTLY list[str] — no {url, label} objects. For labeled links use a
|
|
36
|
-
// `list` section with ListItem.link.
|
|
37
|
-
links: z.array(z.string()).default([]),
|
|
38
|
-
}).strict();
|
|
39
|
-
// Matches `default_factory=HeaderBlock` on the pydantic model. A factory
|
|
40
|
-
// (not a literal) so each default produces a fresh object — preventing
|
|
41
|
-
// shared-reference aliasing if a caller mutates the default.
|
|
42
|
-
const emptyHeader = () => ({ details: [], links: [] });
|
|
43
|
-
const timelineItemSchema = z.object({
|
|
44
|
-
primary: z.string(),
|
|
45
|
-
secondary: z.string().nullable().optional(),
|
|
46
|
-
period: z.string().nullable().optional(),
|
|
47
|
-
location: z.string().nullable().optional(),
|
|
48
|
-
description: z.array(z.string()).nullable().optional(),
|
|
49
|
-
link: z.string().nullable().optional(),
|
|
50
|
-
}).strict();
|
|
51
|
-
const listItemSchema = z.object({
|
|
52
|
-
title: z.string(),
|
|
53
|
-
subtitle: z.string().nullable().optional(),
|
|
54
|
-
year: z.string().nullable().optional(),
|
|
55
|
-
description: z.array(z.string()).nullable().optional(),
|
|
56
|
-
link: z.string().nullable().optional(),
|
|
57
|
-
}).strict();
|
|
58
|
-
const gridItemSchema = z.object({
|
|
59
|
-
title: z.string(),
|
|
60
|
-
image_url: z.string().nullable().optional(),
|
|
61
|
-
year: z.string().nullable().optional(),
|
|
62
|
-
description: z.string().nullable().optional(),
|
|
63
|
-
link: z.string().nullable().optional(),
|
|
64
|
-
type: z.string().nullable().optional(),
|
|
65
|
-
}).strict();
|
|
66
|
-
const tableRowSchema = z.object({
|
|
67
|
-
cells: z.array(z.string()),
|
|
68
|
-
}).strict();
|
|
69
|
-
const tableDataSchema = z.object({
|
|
70
|
-
headers: z.array(z.string()).min(1, "Table headers must be non-empty"),
|
|
71
|
-
rows: z.array(tableRowSchema),
|
|
72
|
-
}).strict();
|
|
73
|
-
const timelineSectionSchema = z.object({
|
|
74
|
-
type: z.literal("timeline"),
|
|
75
|
-
title: z.string(),
|
|
76
|
-
items: z.array(timelineItemSchema),
|
|
77
|
-
}).strict();
|
|
78
|
-
const listSectionSchema = z.object({
|
|
79
|
-
type: z.literal("list"),
|
|
80
|
-
title: z.string(),
|
|
81
|
-
items: z.array(listItemSchema),
|
|
82
|
-
}).strict();
|
|
83
|
-
const tagsSectionSchema = z.object({
|
|
84
|
-
type: z.literal("tags"),
|
|
85
|
-
title: z.string(),
|
|
86
|
-
items: z.array(z.string()),
|
|
87
|
-
}).strict();
|
|
88
|
-
const gridSectionSchema = z.object({
|
|
89
|
-
type: z.literal("grid"),
|
|
90
|
-
title: z.string(),
|
|
91
|
-
items: z.array(gridItemSchema),
|
|
92
|
-
}).strict();
|
|
93
|
-
const tableSectionSchema = z.object({
|
|
94
|
-
type: z.literal("table"),
|
|
95
|
-
title: z.string(),
|
|
96
|
-
items: tableDataSchema,
|
|
97
|
-
}).strict();
|
|
98
|
-
const keyValueSectionSchema = z.object({
|
|
99
|
-
type: z.literal("key_value"),
|
|
100
|
-
title: z.string(),
|
|
101
|
-
items: z.array(keyValueItemSchema),
|
|
102
|
-
}).strict();
|
|
103
|
-
const sectionSchema = z.discriminatedUnion("type", [
|
|
104
|
-
timelineSectionSchema,
|
|
105
|
-
listSectionSchema,
|
|
106
|
-
tagsSectionSchema,
|
|
107
|
-
gridSectionSchema,
|
|
108
|
-
tableSectionSchema,
|
|
109
|
-
keyValueSectionSchema,
|
|
110
|
-
]);
|
|
111
|
-
export const infoboxSchema = z.object({
|
|
112
|
-
header: headerBlockSchema.default(emptyHeader),
|
|
113
|
-
sections: z.array(sectionSchema).default([]),
|
|
114
|
-
}).strict();
|
|
115
|
-
// ── Frontmatter — mirrors backend PagePublishFrontmatter ────────
|
|
116
|
-
export const pagePublishFrontmatterSchema = z.object({
|
|
117
|
-
title: z.string().min(1).max(500),
|
|
118
|
-
topics: z.array(z.string()).default([]),
|
|
119
|
-
sources: z.array(sourceSchema).default([]),
|
|
120
|
-
infobox: infoboxSchema.nullable().optional(),
|
|
121
|
-
// Informational round-trip field — `_serialize_page` embeds the wiki slug
|
|
122
|
-
// in downloaded frontmatter so agents know what they're editing. Backend
|
|
123
|
-
// ignores it at publish (wiki is taken from the URL param).
|
|
124
|
-
wiki: z.string().nullable().optional(),
|
|
125
|
-
edit_summary: z.string().nullable().optional(),
|
|
126
|
-
change_title: z.string().nullable().optional(),
|
|
127
|
-
change_description: z.string().nullable().optional(),
|
|
128
|
-
}).strict();
|
|
129
|
-
// ── Public surface ──────────────────────────────────────────────
|
|
130
|
-
export function parseFrontmatter(raw) {
|
|
131
|
-
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
132
|
-
if (!match) {
|
|
133
|
-
return { frontmatter: {}, content: raw };
|
|
134
|
-
}
|
|
135
|
-
const frontmatter = parseYaml(match[1]);
|
|
136
|
-
return { frontmatter, content: match[2] };
|
|
137
|
-
}
|
|
138
|
-
function zodIssueToError(issue) {
|
|
139
|
-
const path = issue.path.length === 0 ? "(root)" : issue.path.join(".");
|
|
140
|
-
return { field: path, message: issue.message };
|
|
141
|
-
}
|
|
142
|
-
export function validateArticle(raw) {
|
|
143
|
-
const { frontmatter } = parseFrontmatter(raw);
|
|
144
|
-
try {
|
|
145
|
-
pagePublishFrontmatterSchema.parse(frontmatter);
|
|
146
|
-
return [];
|
|
147
|
-
}
|
|
148
|
-
catch (err) {
|
|
149
|
-
if (err instanceof ZodError) {
|
|
150
|
-
return err.issues.map(zodIssueToError);
|
|
151
|
-
}
|
|
152
|
-
return [{ field: "(root)", message: String(err) }];
|
|
153
|
-
}
|
|
154
|
-
}
|
|
File without changes
|