openalmanac 0.2.4 → 0.2.6
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/auth.d.ts +7 -0
- package/dist/auth.js +19 -0
- package/dist/tools/articles.js +34 -23
- package/package.json +1 -1
package/dist/auth.d.ts
CHANGED
|
@@ -6,6 +6,13 @@ export declare function getApiKey(): string | null;
|
|
|
6
6
|
export declare function requireApiKey(): string;
|
|
7
7
|
export declare function saveApiKey(key: string): void;
|
|
8
8
|
export declare function removeApiKey(): boolean;
|
|
9
|
+
export type AuthStatus = {
|
|
10
|
+
loggedIn: true;
|
|
11
|
+
name: string;
|
|
12
|
+
} | {
|
|
13
|
+
loggedIn: false;
|
|
14
|
+
};
|
|
15
|
+
export declare function getAuthStatus(): Promise<AuthStatus>;
|
|
9
16
|
export declare function buildAuthHeaders(): Record<string, string>;
|
|
10
17
|
export declare function request(method: string, path: string, options?: {
|
|
11
18
|
auth?: boolean;
|
package/dist/auth.js
CHANGED
|
@@ -37,6 +37,25 @@ export function removeApiKey() {
|
|
|
37
37
|
}
|
|
38
38
|
return false;
|
|
39
39
|
}
|
|
40
|
+
export async function getAuthStatus() {
|
|
41
|
+
const key = getApiKey();
|
|
42
|
+
if (!key)
|
|
43
|
+
return { loggedIn: false };
|
|
44
|
+
try {
|
|
45
|
+
const resp = await fetch(`${API_BASE}/api/agents/me`, {
|
|
46
|
+
headers: { Authorization: `Bearer ${key}` },
|
|
47
|
+
signal: AbortSignal.timeout(10_000),
|
|
48
|
+
});
|
|
49
|
+
if (resp.ok) {
|
|
50
|
+
const data = (await resp.json());
|
|
51
|
+
return { loggedIn: true, name: data.name ?? "unknown" };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Key invalid or network error
|
|
56
|
+
}
|
|
57
|
+
return { loggedIn: false };
|
|
58
|
+
}
|
|
40
59
|
export function buildAuthHeaders() {
|
|
41
60
|
return { Authorization: `Bearer ${requireApiKey()}` };
|
|
42
61
|
}
|
package/dist/tools/articles.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, existsSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { stringify as yamlStringify } from "yaml";
|
|
5
|
-
import { request, ARTICLES_DIR } from "../auth.js";
|
|
5
|
+
import { request, ARTICLES_DIR, getAuthStatus } from "../auth.js";
|
|
6
6
|
import { validateArticle, parseFrontmatter } from "../validate.js";
|
|
7
7
|
const SLUG_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
8
8
|
const WRITING_GUIDE = `
|
|
@@ -15,48 +15,55 @@ title: Article Title
|
|
|
15
15
|
sources:
|
|
16
16
|
- url: https://example.com
|
|
17
17
|
title: Source Title
|
|
18
|
+
accessed_date: "2025-01-15"
|
|
18
19
|
infobox:
|
|
19
20
|
header:
|
|
20
21
|
image_url: https://... # optional hero image
|
|
21
22
|
subtitle: Short tagline
|
|
22
23
|
details:
|
|
23
|
-
-
|
|
24
|
+
- key: Born
|
|
24
25
|
value: January 1, 1990
|
|
25
|
-
-
|
|
26
|
+
- key: Occupation
|
|
26
27
|
value: Scientist
|
|
27
28
|
links:
|
|
28
|
-
-
|
|
29
|
-
url: https://...
|
|
29
|
+
- https://example.com
|
|
30
30
|
sections:
|
|
31
31
|
- type: timeline # chronological events
|
|
32
32
|
title: Career Timeline
|
|
33
33
|
items:
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
- primary: "Started company"
|
|
35
|
+
period: "2010"
|
|
36
|
+
location: "San Francisco"
|
|
37
|
+
- type: list # key figures, works, features
|
|
37
38
|
title: Known For
|
|
38
39
|
items:
|
|
39
|
-
-
|
|
40
|
-
-
|
|
40
|
+
- title: First achievement
|
|
41
|
+
- title: Second achievement
|
|
42
|
+
subtitle: Additional detail
|
|
41
43
|
- type: tags # inline tags/chips
|
|
42
44
|
title: Genres
|
|
43
45
|
items:
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
+
- Rock
|
|
47
|
+
- Jazz
|
|
46
48
|
- type: grid # image grid
|
|
47
49
|
title: Gallery
|
|
48
50
|
items:
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
- type: table #
|
|
51
|
+
- title: Caption
|
|
52
|
+
image_url: https://...
|
|
53
|
+
- type: table # structured comparison
|
|
52
54
|
title: Statistics
|
|
53
55
|
items:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
headers:
|
|
57
|
+
- Name
|
|
58
|
+
- Value
|
|
59
|
+
rows:
|
|
60
|
+
- cells:
|
|
61
|
+
- Height
|
|
62
|
+
- "6'2\\""
|
|
56
63
|
- type: key_value # simple key-value pairs
|
|
57
64
|
title: Quick Facts
|
|
58
65
|
items:
|
|
59
|
-
-
|
|
66
|
+
- key: Population
|
|
60
67
|
value: "1.4 billion"
|
|
61
68
|
---
|
|
62
69
|
|
|
@@ -189,18 +196,22 @@ export function registerArticleTools(server) {
|
|
|
189
196
|
});
|
|
190
197
|
const data = (await resp.json());
|
|
191
198
|
const articleUrl = `https://www.openalmanac.org/article/${slug}?celebrate=true`;
|
|
192
|
-
return `Pushed successfully.\n${articleUrl}\n${JSON.stringify(data, null, 2)}`;
|
|
199
|
+
return `Pushed successfully.\n\nArticle URL (share this exact link with the user): ${articleUrl}\n\n${JSON.stringify(data, null, 2)}`;
|
|
193
200
|
},
|
|
194
201
|
});
|
|
195
202
|
server.addTool({
|
|
196
203
|
name: "status",
|
|
197
|
-
description: "
|
|
198
|
-
"Shows filename, title, file size, and last modified time.
|
|
204
|
+
description: "Show login status and list all article files in your local working directory (~/.openalmanac/articles/). " +
|
|
205
|
+
"Shows auth state, filename, title, file size, and last modified time.",
|
|
199
206
|
async execute() {
|
|
200
207
|
ensureArticlesDir();
|
|
208
|
+
const auth = await getAuthStatus();
|
|
209
|
+
const authLine = auth.loggedIn
|
|
210
|
+
? `Logged in as ${auth.name}.`
|
|
211
|
+
: "Not logged in. Use login to authenticate.";
|
|
201
212
|
const files = readdirSync(ARTICLES_DIR).filter((f) => f.endsWith(".md"));
|
|
202
213
|
if (files.length === 0) {
|
|
203
|
-
return
|
|
214
|
+
return `${authLine}\n\nLocal articles (0 files in ${ARTICLES_DIR}):\n (none — use pull or new to get started)`;
|
|
204
215
|
}
|
|
205
216
|
const rows = [];
|
|
206
217
|
for (const file of files) {
|
|
@@ -215,7 +226,7 @@ export function registerArticleTools(server) {
|
|
|
215
226
|
const modified = stat.mtime.toISOString().slice(0, 16).replace("T", " ");
|
|
216
227
|
rows.push(` ${file} — "${title}" (${size}, modified ${modified})`);
|
|
217
228
|
}
|
|
218
|
-
return `${files.length}
|
|
229
|
+
return `${authLine}\n\nLocal articles (${files.length} file(s) in ${ARTICLES_DIR}):\n${rows.join("\n")}`;
|
|
219
230
|
},
|
|
220
231
|
});
|
|
221
232
|
}
|