seshat-scribe 2.0.0 → 3.0.0
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/commands/check-due.d.ts +15 -0
- package/dist/commands/check-due.d.ts.map +1 -0
- package/dist/commands/check-due.js +53 -0
- package/dist/commands/check-due.js.map +1 -0
- package/dist/commands/generate.d.ts +3 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +82 -14
- package/dist/commands/generate.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -1
- package/dist/core/planner.d.ts +2 -2
- package/dist/core/sanity.d.ts +36 -1
- package/dist/core/sanity.d.ts.map +1 -1
- package/dist/core/sanity.js +78 -2
- package/dist/core/sanity.js.map +1 -1
- package/dist/core/scheduler.d.ts +45 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +136 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/index.js +25 -2
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check which content topics are due for generation
|
|
3
|
+
*/
|
|
4
|
+
export interface CheckDueOptions {
|
|
5
|
+
sanityProject: string;
|
|
6
|
+
sanityDataset: string;
|
|
7
|
+
json?: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Check which topics are due for generation based on their schedules
|
|
11
|
+
* @param options - Check-due command options
|
|
12
|
+
* @returns Array of topic IDs that are due for generation
|
|
13
|
+
*/
|
|
14
|
+
export declare function checkDueTopics(options: CheckDueOptions): Promise<string[]>;
|
|
15
|
+
//# sourceMappingURL=check-due.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-due.d.ts","sourceRoot":"","sources":["../../src/commands/check-due.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgDhF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check which content topics are due for generation
|
|
3
|
+
*/
|
|
4
|
+
import { createSanityClientFromConfig, fetchActiveTopics } from '../core/sanity.js';
|
|
5
|
+
import { isTopicDue } from '../core/scheduler.js';
|
|
6
|
+
/**
|
|
7
|
+
* Check which topics are due for generation based on their schedules
|
|
8
|
+
* @param options - Check-due command options
|
|
9
|
+
* @returns Array of topic IDs that are due for generation
|
|
10
|
+
*/
|
|
11
|
+
export async function checkDueTopics(options) {
|
|
12
|
+
const sanityConfig = {
|
|
13
|
+
projectId: options.sanityProject,
|
|
14
|
+
dataset: options.sanityDataset,
|
|
15
|
+
};
|
|
16
|
+
// Create read-only client
|
|
17
|
+
const client = createSanityClientFromConfig(sanityConfig, { readOnly: true });
|
|
18
|
+
// Fetch all active topics
|
|
19
|
+
const topics = await fetchActiveTopics(client);
|
|
20
|
+
if (!options.json) {
|
|
21
|
+
console.log(`\nFound ${topics.length} active topic${topics.length !== 1 ? 's' : ''}`);
|
|
22
|
+
}
|
|
23
|
+
// Check which topics are due
|
|
24
|
+
const dueTopics = [];
|
|
25
|
+
const now = new Date();
|
|
26
|
+
for (const topic of topics) {
|
|
27
|
+
const lastGenerated = topic.lastGeneratedAt ? new Date(topic.lastGeneratedAt) : null;
|
|
28
|
+
const isDue = isTopicDue(topic.cronSchedule, lastGenerated, now);
|
|
29
|
+
if (isDue) {
|
|
30
|
+
dueTopics.push(topic._id);
|
|
31
|
+
if (!options.json) {
|
|
32
|
+
console.log(` ✦ ${topic.name} (${topic._id})`);
|
|
33
|
+
if (lastGenerated) {
|
|
34
|
+
console.log(` Last generated: ${lastGenerated.toISOString()}`);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(` Never generated`);
|
|
38
|
+
}
|
|
39
|
+
console.log(` Schedule: ${topic.cronSchedule}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!options.json) {
|
|
44
|
+
if (dueTopics.length === 0) {
|
|
45
|
+
console.log(`\nNo topics are due for generation at this time.`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log(`\n${dueTopics.length} topic${dueTopics.length !== 1 ? 's' : ''} due for generation`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return dueTopics;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=check-due.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-due.js","sourceRoot":"","sources":["../../src/commands/check-due.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AASlD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAwB;IAC3D,MAAM,YAAY,GAA2B;QAC3C,SAAS,EAAE,OAAO,CAAC,aAAa;QAChC,OAAO,EAAE,OAAO,CAAC,aAAa;KAC/B,CAAC;IAEF,0BAA0B;IAC1B,MAAM,MAAM,GAAG,4BAA4B,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9E,0BAA0B;IAC1B,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAE/C,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,MAAM,gBAAgB,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,6BAA6B;IAC7B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,aAAa,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,YAAY,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QAEjE,IAAI,KAAK,EAAE,CAAC;YACV,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAE1B,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;gBAChD,IAAI,aAAa,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,uBAAuB,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBACpE,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;gBACrC,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,MAAM,SAAS,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2O3E"}
|
|
@@ -6,32 +6,60 @@ import { scanRepository } from '../core/analyzer.js';
|
|
|
6
6
|
import { planBlogPost } from '../core/planner.js';
|
|
7
7
|
import { writePortableTextContent } from '../core/portable-writer.js';
|
|
8
8
|
import { generateImage } from '../core/artist.js';
|
|
9
|
-
import { uploadToSanity } from '../core/sanity.js';
|
|
9
|
+
import { uploadToSanity, createSanityClientFromConfig, updateTopicAfterGeneration, updateTopicError } from '../core/sanity.js';
|
|
10
|
+
import { calculateNextRun } from '../core/scheduler.js';
|
|
10
11
|
import { gold, cyan, error, info, scrollWritten } from '../lib/output.js';
|
|
11
12
|
import { resetUsage, formatUsageSummary } from '../lib/usage.js';
|
|
13
|
+
import { loadTopicFromSanity } from '../config.js';
|
|
12
14
|
/**
|
|
13
15
|
* Main command: Generate a new blog post with image and upload to Sanity
|
|
14
16
|
*/
|
|
15
17
|
export async function generate(options = {}) {
|
|
16
|
-
|
|
17
|
-
// Load configuration
|
|
18
|
+
// Load configuration - either from Sanity topic or file (deprecated)
|
|
18
19
|
let config;
|
|
20
|
+
let topicId;
|
|
19
21
|
try {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
if (options.topicId) {
|
|
23
|
+
// Load from Sanity topic (primary method)
|
|
24
|
+
if (!options.sanityProject || !options.sanityDataset) {
|
|
25
|
+
error('--sanity-project and --sanity-dataset are required when using --topic-id');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const sanityConfig = {
|
|
29
|
+
projectId: options.sanityProject,
|
|
30
|
+
dataset: options.sanityDataset,
|
|
31
|
+
};
|
|
32
|
+
topicId = options.topicId;
|
|
33
|
+
config = await loadTopicFromSanity(sanityConfig, topicId);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Load from file (deprecated)
|
|
37
|
+
const configPath = path.join(process.cwd(), 'seshat.config.json');
|
|
38
|
+
const { loadConfig } = await import('../config.js');
|
|
39
|
+
config = await loadConfig(configPath);
|
|
40
|
+
// Override topic if provided via CLI
|
|
41
|
+
if (options.topic) {
|
|
42
|
+
config = { ...config, topic: options.topic };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
22
45
|
}
|
|
23
46
|
catch (err) {
|
|
24
|
-
error('Could not load
|
|
25
|
-
|
|
47
|
+
error('Could not load configuration');
|
|
48
|
+
if (options.topicId) {
|
|
49
|
+
info('Check that the topic ID exists in Sanity and is active');
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
info('Run: seshat init');
|
|
53
|
+
}
|
|
54
|
+
console.error(err instanceof Error ? err.message : 'Unknown error');
|
|
26
55
|
process.exit(1);
|
|
27
56
|
}
|
|
28
|
-
// Override topic if provided via CLI
|
|
29
|
-
if (options.topic) {
|
|
30
|
-
config = { ...config, topic: options.topic };
|
|
31
|
-
}
|
|
32
57
|
console.log('');
|
|
33
58
|
console.log(gold.bold('⟡ Seshat awakens...'));
|
|
34
|
-
if (
|
|
59
|
+
if (topicId) {
|
|
60
|
+
info(`Topic ID: ${topicId}`);
|
|
61
|
+
}
|
|
62
|
+
else if (options.topic) {
|
|
35
63
|
info(`Topic override: ${options.topic}`);
|
|
36
64
|
}
|
|
37
65
|
console.log('');
|
|
@@ -112,6 +140,7 @@ export async function generate(options = {}) {
|
|
|
112
140
|
text: cyan('Inscribing the scroll...'),
|
|
113
141
|
color: 'cyan',
|
|
114
142
|
}).start();
|
|
143
|
+
let result;
|
|
115
144
|
try {
|
|
116
145
|
if (options.dryRun) {
|
|
117
146
|
saveSpinner.info('Dry run: skipping Sanity upload');
|
|
@@ -125,9 +154,33 @@ export async function generate(options = {}) {
|
|
|
125
154
|
console.log('');
|
|
126
155
|
}
|
|
127
156
|
else {
|
|
128
|
-
|
|
157
|
+
result = await uploadToSanity(config, plan, portableTextBody, imagePath, postDate);
|
|
129
158
|
saveSpinner.succeed(`Uploaded to Sanity: ${result.documentId}`);
|
|
130
159
|
info(` View in studio: /studio/intent/edit/id=${result.documentId};type=post`);
|
|
160
|
+
// Update topic document if this was generated from a Sanity topic
|
|
161
|
+
if (topicId && options.sanityProject && options.sanityDataset) {
|
|
162
|
+
const updateSpinner = ora({
|
|
163
|
+
text: cyan('Updating topic...'),
|
|
164
|
+
color: 'cyan',
|
|
165
|
+
}).start();
|
|
166
|
+
try {
|
|
167
|
+
const sanityConfig = {
|
|
168
|
+
projectId: options.sanityProject,
|
|
169
|
+
dataset: options.sanityDataset,
|
|
170
|
+
};
|
|
171
|
+
const client = createSanityClientFromConfig(sanityConfig);
|
|
172
|
+
// Calculate next run time
|
|
173
|
+
const nextRun = calculateNextRun(config.schedule || '0 9 * * *');
|
|
174
|
+
// Update topic document
|
|
175
|
+
await updateTopicAfterGeneration(client, topicId, result.documentId, nextRun);
|
|
176
|
+
updateSpinner.succeed(`Topic updated (next run: ${nextRun.toISOString()})`);
|
|
177
|
+
}
|
|
178
|
+
catch (updateErr) {
|
|
179
|
+
updateSpinner.fail('Failed to update topic');
|
|
180
|
+
console.warn(updateErr instanceof Error ? updateErr.message : 'Unknown error');
|
|
181
|
+
// Don't exit - the post was created successfully
|
|
182
|
+
}
|
|
183
|
+
}
|
|
131
184
|
}
|
|
132
185
|
// Clean up temporary image
|
|
133
186
|
if (imagePath) {
|
|
@@ -141,7 +194,22 @@ export async function generate(options = {}) {
|
|
|
141
194
|
}
|
|
142
195
|
catch (err) {
|
|
143
196
|
saveSpinner.fail('Failed to upload to Sanity');
|
|
144
|
-
|
|
197
|
+
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
198
|
+
error(errorMessage);
|
|
199
|
+
// Update topic with error if applicable
|
|
200
|
+
if (topicId && options.sanityProject && options.sanityDataset) {
|
|
201
|
+
try {
|
|
202
|
+
const sanityConfig = {
|
|
203
|
+
projectId: options.sanityProject,
|
|
204
|
+
dataset: options.sanityDataset,
|
|
205
|
+
};
|
|
206
|
+
const client = createSanityClientFromConfig(sanityConfig);
|
|
207
|
+
await updateTopicError(client, topicId, errorMessage);
|
|
208
|
+
}
|
|
209
|
+
catch (updateErr) {
|
|
210
|
+
// Ignore errors updating error status
|
|
211
|
+
}
|
|
212
|
+
}
|
|
145
213
|
// Clean up temporary image on error
|
|
146
214
|
if (imagePath) {
|
|
147
215
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,GAAG,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,OAAO,EAAE,cAAc,EAA0B,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,4BAA4B,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/H,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAUnD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,UAA2B,EAAE;IAC1D,qEAAqE;IACrE,IAAI,MAAoB,CAAC;IACzB,IAAI,OAA2B,CAAC;IAEhC,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,0CAA0C;YAC1C,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;gBACrD,KAAK,CAAC,0EAA0E,CAAC,CAAC;gBAClF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,YAAY,GAA2B;gBAC3C,SAAS,EAAE,OAAO,CAAC,aAAa;gBAChC,OAAO,EAAE,OAAO,CAAC,aAAa;aAC/B,CAAC;YAEF,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YAC1B,MAAM,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,8BAA8B;YAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;YAClE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YACpD,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;YAEtC,qCAAqC;YACrC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClB,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,8BAA8B,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,wDAAwD,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC9C,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,aAAa,OAAO,EAAE,CAAC,CAAC;IAC/B,CAAC;SAAM,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,mBAAmB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,UAAU,EAAE,CAAC;IAEb,+CAA+C;IAC/C,MAAM,cAAc,GAAG,GAAG,CAAC;QACzB,IAAI,EAAE,IAAI,CAAC,yBAAyB,CAAC;QACrC,KAAK,EAAE,MAAM;KACd,CAAC,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,OAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;QACvC,cAAc,CAAC,OAAO,CACpB,SAAS,OAAO,CAAC,UAAU,iBAAiB,OAAO,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAClF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,cAAc,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACjD,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,MAAM,WAAW,GAAG,GAAG,CAAC;QACtB,IAAI,EAAE,IAAI,CAAC,4BAA4B,CAAC;QACxC,KAAK,EAAE,MAAM;KACd,CAAC,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,IAAc,CAAC;IACnB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3C,WAAW,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAC3C,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;IAE5B,0CAA0C;IAC1C,MAAM,qBAAqB,GAAG,MAAM,CAAC,UAAU,EAAE,qBAAqB,IAAI,IAAI,CAAC;IAC/E,IAAI,SAAS,GAAkB,IAAI,CAAC;IAEpC,IAAI,qBAAqB,EAAE,CAAC;QAC1B,MAAM,YAAY,GAAG,GAAG,CAAC;YACvB,IAAI,EAAE,IAAI,CAAC,uBAAuB,CAAC;YACnC,KAAK,EAAE,MAAM;SACd,CAAC,CAAC,KAAK,EAAE,CAAC;QAEX,IAAI,CAAC;YACH,2CAA2C;YAC3C,MAAM,OAAO,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC;YAE5B,SAAS,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACtE,YAAY,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC5C,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,qDAAqD,CAAC,CAAC;IAC9D,CAAC;IAED,sCAAsC;IACtC,MAAM,YAAY,GAAG,GAAG,CAAC;QACvB,IAAI,EAAE,IAAI,CAAC,sBAAsB,CAAC;QAClC,KAAK,EAAE,MAAM;KACd,CAAC,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,gBAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,gBAAgB,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChE,YAAY,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC7C,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,MAAM,WAAW,GAAG,GAAG,CAAC;QACtB,IAAI,EAAE,IAAI,CAAC,0BAA0B,CAAC;QACtC,KAAK,EAAE,MAAM;KACd,CAAC,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,MAAwD,CAAC;IAE7D,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,WAAW,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,WAAW,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YACnF,WAAW,CAAC,OAAO,CAAC,uBAAuB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YAChE,IAAI,CAAC,4CAA4C,MAAM,CAAC,UAAU,YAAY,CAAC,CAAC;YAEhF,kEAAkE;YAClE,IAAI,OAAO,IAAI,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;gBAC9D,MAAM,aAAa,GAAG,GAAG,CAAC;oBACxB,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC;oBAC/B,KAAK,EAAE,MAAM;iBACd,CAAC,CAAC,KAAK,EAAE,CAAC;gBAEX,IAAI,CAAC;oBACH,MAAM,YAAY,GAA2B;wBAC3C,SAAS,EAAE,OAAO,CAAC,aAAa;wBAChC,OAAO,EAAE,OAAO,CAAC,aAAa;qBAC/B,CAAC;oBACF,MAAM,MAAM,GAAG,4BAA4B,CAAC,YAAY,CAAC,CAAC;oBAE1D,0BAA0B;oBAC1B,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,QAAQ,IAAI,WAAW,CAAC,CAAC;oBAEjE,wBAAwB;oBACxB,MAAM,0BAA0B,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBAE9E,aAAa,CAAC,OAAO,CAAC,4BAA4B,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBAC9E,CAAC;gBAAC,OAAO,SAAS,EAAE,CAAC;oBACnB,aAAa,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;oBAC7C,OAAO,CAAC,IAAI,CAAC,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;oBAC/E,iDAAiD;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,UAAU,EAAE,CAAC;gBACpB,wBAAwB;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC/C,MAAM,YAAY,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC1E,KAAK,CAAC,YAAY,CAAC,CAAC;QAEpB,wCAAwC;QACxC,IAAI,OAAO,IAAI,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YAC9D,IAAI,CAAC;gBACH,MAAM,YAAY,GAA2B;oBAC3C,SAAS,EAAE,OAAO,CAAC,aAAa;oBAChC,OAAO,EAAE,OAAO,CAAC,aAAa;iBAC/B,CAAC;gBACF,MAAM,MAAM,GAAG,4BAA4B,CAAC,YAAY,CAAC,CAAC;gBAC1D,MAAM,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;YACxD,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,sCAAsC;YACxC,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,UAAU,EAAE,CAAC;gBACpB,wBAAwB;YAC1B,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,gBAAgB;IAChB,MAAM,UAAU,GAAG,kBAAkB,EAAE,CAAC;IACxC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,CAAC;IACH,CAAC;IAED,WAAW;IACX,aAAa,EAAE,CAAC;AAClB,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import type { SanityConnectionConfig } from './types.js';
|
|
2
3
|
/**
|
|
3
4
|
* Content generation options schema
|
|
4
5
|
*/
|
|
@@ -137,6 +138,16 @@ export type SeshatConfig = z.infer<typeof SeshatConfigSchema>;
|
|
|
137
138
|
export declare const DEFAULT_IMAGE_FORMAT: "png";
|
|
138
139
|
/**
|
|
139
140
|
* Load and validate configuration from file
|
|
141
|
+
* @deprecated Use loadTopicFromSanity instead for Sanity-native configuration
|
|
140
142
|
*/
|
|
141
143
|
export declare function loadConfig(configPath: string): Promise<SeshatConfig>;
|
|
144
|
+
/**
|
|
145
|
+
* Load configuration from a Sanity contentTopic document
|
|
146
|
+
* This is the primary configuration method for Seshat
|
|
147
|
+
*
|
|
148
|
+
* @param sanityConfig - Sanity connection configuration
|
|
149
|
+
* @param topicId - Content topic document ID
|
|
150
|
+
* @returns SeshatConfig transformed from the topic document
|
|
151
|
+
*/
|
|
152
|
+
export declare function loadTopicFromSanity(sanityConfig: SanityConnectionConfig, topicId: string): Promise<SeshatConfig>;
|
|
142
153
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;EAMjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;EAM7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAG,KAAc,CAAC;AAEnD
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,sBAAsB,EAAwB,MAAM,YAAY,CAAC;AAE/E;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;EAMjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;EAM7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAG,KAAc,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAY1E;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,sBAAsB,EACpC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC,CA4BvB"}
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { createSanityClientFromConfig, fetchContentTopic } from './core/sanity.js';
|
|
2
3
|
/**
|
|
3
4
|
* Content generation options schema
|
|
4
5
|
*/
|
|
@@ -39,6 +40,7 @@ export const SeshatConfigSchema = z.object({
|
|
|
39
40
|
export const DEFAULT_IMAGE_FORMAT = 'png';
|
|
40
41
|
/**
|
|
41
42
|
* Load and validate configuration from file
|
|
43
|
+
* @deprecated Use loadTopicFromSanity instead for Sanity-native configuration
|
|
42
44
|
*/
|
|
43
45
|
export async function loadConfig(configPath) {
|
|
44
46
|
const fs = await import('fs/promises');
|
|
@@ -51,4 +53,37 @@ export async function loadConfig(configPath) {
|
|
|
51
53
|
}
|
|
52
54
|
return config;
|
|
53
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Load configuration from a Sanity contentTopic document
|
|
58
|
+
* This is the primary configuration method for Seshat
|
|
59
|
+
*
|
|
60
|
+
* @param sanityConfig - Sanity connection configuration
|
|
61
|
+
* @param topicId - Content topic document ID
|
|
62
|
+
* @returns SeshatConfig transformed from the topic document
|
|
63
|
+
*/
|
|
64
|
+
export async function loadTopicFromSanity(sanityConfig, topicId) {
|
|
65
|
+
// Create read-only client
|
|
66
|
+
const client = createSanityClientFromConfig(sanityConfig, { readOnly: true });
|
|
67
|
+
// Fetch the topic document
|
|
68
|
+
const topic = await fetchContentTopic(client, topicId);
|
|
69
|
+
// Check if topic is active
|
|
70
|
+
if (!topic.active) {
|
|
71
|
+
throw new Error(`Content topic "${topic.name}" (${topicId}) is not active`);
|
|
72
|
+
}
|
|
73
|
+
// Transform ContentTopicDocument to SeshatConfig
|
|
74
|
+
const config = {
|
|
75
|
+
topic: topic.topic,
|
|
76
|
+
tone: topic.tone,
|
|
77
|
+
schedule: topic.cronSchedule,
|
|
78
|
+
imageFormat: topic.sanityOverride?.imageFormat || DEFAULT_IMAGE_FORMAT,
|
|
79
|
+
generation: topic.generation,
|
|
80
|
+
sanity: {
|
|
81
|
+
projectId: sanityConfig.projectId,
|
|
82
|
+
dataset: sanityConfig.dataset,
|
|
83
|
+
apiVersion: sanityConfig.apiVersion || '2024-01-01',
|
|
84
|
+
documentType: topic.sanityOverride?.documentType || 'post',
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
return config;
|
|
88
|
+
}
|
|
54
89
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/core/planner.d.ts
CHANGED
|
@@ -11,15 +11,15 @@ export declare const BlogPlanSchema: z.ZodObject<{
|
|
|
11
11
|
tags: z.ZodArray<z.ZodString, "many">;
|
|
12
12
|
imagePrompt: z.ZodString;
|
|
13
13
|
}, "strip", z.ZodTypeAny, {
|
|
14
|
-
description: string;
|
|
15
14
|
title: string;
|
|
16
15
|
slug: string;
|
|
16
|
+
description: string;
|
|
17
17
|
tags: string[];
|
|
18
18
|
imagePrompt: string;
|
|
19
19
|
}, {
|
|
20
|
-
description: string;
|
|
21
20
|
title: string;
|
|
22
21
|
slug: string;
|
|
22
|
+
description: string;
|
|
23
23
|
tags: string[];
|
|
24
24
|
imagePrompt: string;
|
|
25
25
|
}>;
|
package/dist/core/sanity.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type SanityClient } from '@sanity/client';
|
|
2
2
|
import type { SeshatConfig } from '../config.js';
|
|
3
3
|
import type { BlogPlan } from './planner.js';
|
|
4
|
+
import type { ContentTopicDocument, SanityConnectionConfig } from '../types.js';
|
|
4
5
|
/**
|
|
5
6
|
* Get or create a Sanity client instance
|
|
6
7
|
*/
|
|
@@ -10,7 +11,7 @@ export declare function getSanityClient(config: SeshatConfig, options?: {
|
|
|
10
11
|
/**
|
|
11
12
|
* Upload an image file to Sanity assets
|
|
12
13
|
*/
|
|
13
|
-
export declare function uploadImageToSanity(client: SanityClient, imagePath: string
|
|
14
|
+
export declare function uploadImageToSanity(client: SanityClient, imagePath: string): Promise<{
|
|
14
15
|
_type: 'image';
|
|
15
16
|
asset: {
|
|
16
17
|
_type: 'reference';
|
|
@@ -34,4 +35,38 @@ export declare function uploadToSanity(config: SeshatConfig, plan: BlogPlan, por
|
|
|
34
35
|
documentId: string;
|
|
35
36
|
slug: string;
|
|
36
37
|
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a Sanity client from connection config
|
|
40
|
+
*/
|
|
41
|
+
export declare function createSanityClientFromConfig(config: SanityConnectionConfig, options?: {
|
|
42
|
+
readOnly?: boolean;
|
|
43
|
+
}): SanityClient;
|
|
44
|
+
/**
|
|
45
|
+
* Fetch a single content topic from Sanity
|
|
46
|
+
* @param client - Sanity client instance
|
|
47
|
+
* @param topicId - Content topic document ID
|
|
48
|
+
* @returns Content topic document
|
|
49
|
+
*/
|
|
50
|
+
export declare function fetchContentTopic(client: SanityClient, topicId: string): Promise<ContentTopicDocument>;
|
|
51
|
+
/**
|
|
52
|
+
* Fetch all active content topics from Sanity
|
|
53
|
+
* @param client - Sanity client instance
|
|
54
|
+
* @returns Array of active content topic documents
|
|
55
|
+
*/
|
|
56
|
+
export declare function fetchActiveTopics(client: SanityClient): Promise<ContentTopicDocument[]>;
|
|
57
|
+
/**
|
|
58
|
+
* Update a content topic after successful generation
|
|
59
|
+
* @param client - Sanity client instance
|
|
60
|
+
* @param topicId - Content topic document ID
|
|
61
|
+
* @param postId - ID of the newly generated post
|
|
62
|
+
* @param nextRunTime - Calculated next run time
|
|
63
|
+
*/
|
|
64
|
+
export declare function updateTopicAfterGeneration(client: SanityClient, topicId: string, postId: string, nextRunTime: Date): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Update a content topic with error information
|
|
67
|
+
* @param client - Sanity client instance
|
|
68
|
+
* @param topicId - Content topic document ID
|
|
69
|
+
* @param errorMessage - Error message to store
|
|
70
|
+
*/
|
|
71
|
+
export declare function updateTopicError(client: SanityClient, topicId: string, errorMessage: string): Promise<void>;
|
|
37
72
|
//# sourceMappingURL=sanity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanity.d.ts","sourceRoot":"","sources":["../../src/core/sanity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"sanity.d.ts","sourceRoot":"","sources":["../../src/core/sanity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEhF;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,YAAY,CAoBxG;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CAe1E;AAGD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,QAAQ,EACd,gBAAgB,EAAE,GAAG,EAAE,EACvB,QAAQ,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,EAChF,QAAQ,EAAE,IAAI,EACd,YAAY,GAAE,MAAe,GAC5B,OAAO,CAAC,GAAG,CAAC,CAqBd;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,QAAQ,EACd,gBAAgB,EAAE,GAAG,EAAE,EACvB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,IAAI,GACb,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB/C;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,sBAAsB,EAC9B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,YAAY,CAcd;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CAW/B;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAGjC;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,IAAI,GAChB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAOf"}
|
package/dist/core/sanity.js
CHANGED
|
@@ -24,7 +24,7 @@ export function getSanityClient(config, options = {}) {
|
|
|
24
24
|
/**
|
|
25
25
|
* Upload an image file to Sanity assets
|
|
26
26
|
*/
|
|
27
|
-
export async function uploadImageToSanity(client, imagePath
|
|
27
|
+
export async function uploadImageToSanity(client, imagePath) {
|
|
28
28
|
const imageBuffer = await fs.readFile(imagePath);
|
|
29
29
|
// Upload to Sanity assets
|
|
30
30
|
const asset = await client.assets.upload('image', imageBuffer, {
|
|
@@ -69,7 +69,7 @@ export async function uploadToSanity(config, plan, portableTextBody, imagePath,
|
|
|
69
69
|
// Upload the image if provided
|
|
70
70
|
let imageRef = null;
|
|
71
71
|
if (imagePath) {
|
|
72
|
-
imageRef = await uploadImageToSanity(client, imagePath
|
|
72
|
+
imageRef = await uploadImageToSanity(client, imagePath);
|
|
73
73
|
}
|
|
74
74
|
// Create the post document
|
|
75
75
|
const documentType = config.sanity?.documentType || 'post';
|
|
@@ -79,4 +79,80 @@ export async function uploadToSanity(config, plan, portableTextBody, imagePath,
|
|
|
79
79
|
slug: plan.slug,
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a Sanity client from connection config
|
|
84
|
+
*/
|
|
85
|
+
export function createSanityClientFromConfig(config, options = {}) {
|
|
86
|
+
const token = process.env.SANITY_WRITE_TOKEN;
|
|
87
|
+
if (!options.readOnly && !token) {
|
|
88
|
+
throw new Error('SANITY_WRITE_TOKEN environment variable is required for Sanity writes');
|
|
89
|
+
}
|
|
90
|
+
return createClient({
|
|
91
|
+
projectId: config.projectId,
|
|
92
|
+
dataset: config.dataset,
|
|
93
|
+
apiVersion: config.apiVersion || '2024-01-01',
|
|
94
|
+
token: token || undefined,
|
|
95
|
+
useCdn: options.readOnly,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Fetch a single content topic from Sanity
|
|
100
|
+
* @param client - Sanity client instance
|
|
101
|
+
* @param topicId - Content topic document ID
|
|
102
|
+
* @returns Content topic document
|
|
103
|
+
*/
|
|
104
|
+
export async function fetchContentTopic(client, topicId) {
|
|
105
|
+
const query = `*[_type == "contentTopic" && _id == $topicId][0]`;
|
|
106
|
+
const params = { topicId };
|
|
107
|
+
const topic = await client.fetch(query, params);
|
|
108
|
+
if (!topic) {
|
|
109
|
+
throw new Error(`Content topic not found: ${topicId}`);
|
|
110
|
+
}
|
|
111
|
+
return topic;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Fetch all active content topics from Sanity
|
|
115
|
+
* @param client - Sanity client instance
|
|
116
|
+
* @returns Array of active content topic documents
|
|
117
|
+
*/
|
|
118
|
+
export async function fetchActiveTopics(client) {
|
|
119
|
+
const query = `*[_type == "contentTopic" && active == true] | order(name asc)`;
|
|
120
|
+
return await client.fetch(query);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Update a content topic after successful generation
|
|
124
|
+
* @param client - Sanity client instance
|
|
125
|
+
* @param topicId - Content topic document ID
|
|
126
|
+
* @param postId - ID of the newly generated post
|
|
127
|
+
* @param nextRunTime - Calculated next run time
|
|
128
|
+
*/
|
|
129
|
+
export async function updateTopicAfterGeneration(client, topicId, postId, nextRunTime) {
|
|
130
|
+
await client
|
|
131
|
+
.patch(topicId)
|
|
132
|
+
.set({
|
|
133
|
+
lastGeneratedAt: new Date().toISOString(),
|
|
134
|
+
nextRunTime: nextRunTime.toISOString(),
|
|
135
|
+
lastGeneratedPostId: {
|
|
136
|
+
_type: 'reference',
|
|
137
|
+
_ref: postId,
|
|
138
|
+
},
|
|
139
|
+
})
|
|
140
|
+
.inc({ totalGenerated: 1 })
|
|
141
|
+
.unset(['lastError']) // Clear any previous errors
|
|
142
|
+
.commit();
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Update a content topic with error information
|
|
146
|
+
* @param client - Sanity client instance
|
|
147
|
+
* @param topicId - Content topic document ID
|
|
148
|
+
* @param errorMessage - Error message to store
|
|
149
|
+
*/
|
|
150
|
+
export async function updateTopicError(client, topicId, errorMessage) {
|
|
151
|
+
await client
|
|
152
|
+
.patch(topicId)
|
|
153
|
+
.set({
|
|
154
|
+
lastError: `${new Date().toISOString()}: ${errorMessage}`,
|
|
155
|
+
})
|
|
156
|
+
.commit();
|
|
157
|
+
}
|
|
82
158
|
//# sourceMappingURL=sanity.js.map
|
package/dist/core/sanity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanity.js","sourceRoot":"","sources":["../../src/core/sanity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sanity.js","sourceRoot":"","sources":["../../src/core/sanity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler module for parsing cron expressions and determining topic due status
|
|
3
|
+
*/
|
|
4
|
+
import type { ContentTopicDocument, ScheduleInfo } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Parse a cron expression and return the parser instance
|
|
7
|
+
* @param expression - Cron expression (e.g., "0 9 * * 1" for Mondays at 9 AM)
|
|
8
|
+
* @returns Cron parser instance
|
|
9
|
+
* @throws Error if expression is invalid
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseCron(expression: string): import("cron-parser").CronExpression<false>;
|
|
12
|
+
/**
|
|
13
|
+
* Calculate the next run time from a given starting point
|
|
14
|
+
* @param cronExpression - Cron expression
|
|
15
|
+
* @param from - Starting date (defaults to now)
|
|
16
|
+
* @returns Next scheduled run time
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateNextRun(cronExpression: string, from?: Date): Date;
|
|
19
|
+
/**
|
|
20
|
+
* Determine if a topic is due for generation based on its schedule
|
|
21
|
+
*
|
|
22
|
+
* Logic:
|
|
23
|
+
* - If never generated (lastGenerated is null), topic is due
|
|
24
|
+
* - Calculate next run time from last generation
|
|
25
|
+
* - If next run time is in the past or now, topic is due
|
|
26
|
+
*
|
|
27
|
+
* @param cronSchedule - Cron expression for the topic
|
|
28
|
+
* @param lastGenerated - Last generation timestamp (null if never generated)
|
|
29
|
+
* @param now - Current time (defaults to now, useful for testing)
|
|
30
|
+
* @returns true if topic should generate now
|
|
31
|
+
*/
|
|
32
|
+
export declare function isTopicDue(cronSchedule: string, lastGenerated: Date | null, now?: Date): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Get comprehensive schedule information for a topic
|
|
35
|
+
* @param topic - Content topic document from Sanity
|
|
36
|
+
* @returns Schedule information including due status
|
|
37
|
+
*/
|
|
38
|
+
export declare function getTopicScheduleInfo(topic: ContentTopicDocument): ScheduleInfo;
|
|
39
|
+
/**
|
|
40
|
+
* Format a cron expression into human-readable text
|
|
41
|
+
* @param cronExpression - Cron expression to describe
|
|
42
|
+
* @returns Human-readable description (e.g., "Every day at 9:00 AM")
|
|
43
|
+
*/
|
|
44
|
+
export declare function describeCronSchedule(cronExpression: string): string;
|
|
45
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/core/scheduler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEtE;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,+CAU3C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,IAAI,CAMtF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,IAAI,GAAG,IAAI,EAC1B,GAAG,GAAE,IAAiB,GACrB,OAAO,CAiBT;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CA2B9E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAoCnE"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler module for parsing cron expressions and determining topic due status
|
|
3
|
+
*/
|
|
4
|
+
import { parseExpression } from 'cron-parser';
|
|
5
|
+
/**
|
|
6
|
+
* Parse a cron expression and return the parser instance
|
|
7
|
+
* @param expression - Cron expression (e.g., "0 9 * * 1" for Mondays at 9 AM)
|
|
8
|
+
* @returns Cron parser instance
|
|
9
|
+
* @throws Error if expression is invalid
|
|
10
|
+
*/
|
|
11
|
+
export function parseCron(expression) {
|
|
12
|
+
try {
|
|
13
|
+
return parseExpression(expression, {
|
|
14
|
+
utc: true, // Always use UTC for consistency
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw new Error(`Invalid cron expression "${expression}": ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Calculate the next run time from a given starting point
|
|
23
|
+
* @param cronExpression - Cron expression
|
|
24
|
+
* @param from - Starting date (defaults to now)
|
|
25
|
+
* @returns Next scheduled run time
|
|
26
|
+
*/
|
|
27
|
+
export function calculateNextRun(cronExpression, from = new Date()) {
|
|
28
|
+
const interval = parseExpression(cronExpression, {
|
|
29
|
+
currentDate: from,
|
|
30
|
+
utc: true,
|
|
31
|
+
});
|
|
32
|
+
return interval.next().toDate();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Determine if a topic is due for generation based on its schedule
|
|
36
|
+
*
|
|
37
|
+
* Logic:
|
|
38
|
+
* - If never generated (lastGenerated is null), topic is due
|
|
39
|
+
* - Calculate next run time from last generation
|
|
40
|
+
* - If next run time is in the past or now, topic is due
|
|
41
|
+
*
|
|
42
|
+
* @param cronSchedule - Cron expression for the topic
|
|
43
|
+
* @param lastGenerated - Last generation timestamp (null if never generated)
|
|
44
|
+
* @param now - Current time (defaults to now, useful for testing)
|
|
45
|
+
* @returns true if topic should generate now
|
|
46
|
+
*/
|
|
47
|
+
export function isTopicDue(cronSchedule, lastGenerated, now = new Date()) {
|
|
48
|
+
// If never generated, it's due
|
|
49
|
+
if (!lastGenerated) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
// Calculate when the next run should have been, based on last generation
|
|
54
|
+
const nextRun = calculateNextRun(cronSchedule, lastGenerated);
|
|
55
|
+
// If next run time is in the past or now, it's due
|
|
56
|
+
return nextRun <= now;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// If cron expression is invalid, log warning but don't throw
|
|
60
|
+
console.warn(`Invalid cron schedule for topic: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get comprehensive schedule information for a topic
|
|
66
|
+
* @param topic - Content topic document from Sanity
|
|
67
|
+
* @returns Schedule information including due status
|
|
68
|
+
*/
|
|
69
|
+
export function getTopicScheduleInfo(topic) {
|
|
70
|
+
const lastRun = topic.lastGeneratedAt ? new Date(topic.lastGeneratedAt) : null;
|
|
71
|
+
let nextRun = null;
|
|
72
|
+
let isDue = false;
|
|
73
|
+
if (topic.active) {
|
|
74
|
+
try {
|
|
75
|
+
if (lastRun) {
|
|
76
|
+
nextRun = calculateNextRun(topic.cronSchedule, lastRun);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// If never run, next run is "now" (first available time)
|
|
80
|
+
nextRun = calculateNextRun(topic.cronSchedule, new Date());
|
|
81
|
+
}
|
|
82
|
+
isDue = isTopicDue(topic.cronSchedule, lastRun);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Invalid cron, schedule info unavailable
|
|
86
|
+
console.warn(`Cannot calculate schedule for topic ${topic.name}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
isActive: topic.active,
|
|
91
|
+
lastRun,
|
|
92
|
+
nextRun,
|
|
93
|
+
isDue,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Format a cron expression into human-readable text
|
|
98
|
+
* @param cronExpression - Cron expression to describe
|
|
99
|
+
* @returns Human-readable description (e.g., "Every day at 9:00 AM")
|
|
100
|
+
*/
|
|
101
|
+
export function describeCronSchedule(cronExpression) {
|
|
102
|
+
try {
|
|
103
|
+
const interval = parseCron(cronExpression);
|
|
104
|
+
// Get next few occurrences to infer pattern
|
|
105
|
+
const next1 = interval.next().toDate();
|
|
106
|
+
const next2 = interval.next().toDate();
|
|
107
|
+
const next3 = interval.next().toDate();
|
|
108
|
+
const timeDiff1 = next2.getTime() - next1.getTime();
|
|
109
|
+
const timeDiff2 = next3.getTime() - next2.getTime();
|
|
110
|
+
// Check if intervals are consistent
|
|
111
|
+
if (Math.abs(timeDiff1 - timeDiff2) < 1000) {
|
|
112
|
+
const hours = Math.floor(timeDiff1 / (1000 * 60 * 60));
|
|
113
|
+
const days = Math.floor(hours / 24);
|
|
114
|
+
const timeStr = next1.toISOString().slice(11, 16);
|
|
115
|
+
if (days === 1) {
|
|
116
|
+
return `Every day at ${timeStr} UTC`;
|
|
117
|
+
}
|
|
118
|
+
else if (days === 7) {
|
|
119
|
+
const dayName = next1.toLocaleDateString('en-US', { weekday: 'long', timeZone: 'UTC' });
|
|
120
|
+
return `Every ${dayName} at ${timeStr} UTC`;
|
|
121
|
+
}
|
|
122
|
+
else if (hours < 24) {
|
|
123
|
+
return `Every ${hours} hour${hours > 1 ? 's' : ''}`;
|
|
124
|
+
}
|
|
125
|
+
else if (days > 1 && days < 7) {
|
|
126
|
+
return `Every ${days} days at ${timeStr} UTC`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Fallback to showing next run time
|
|
130
|
+
return `Next: ${next1.toISOString().replace('T', ' ').slice(0, 16)} UTC`;
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
return `Invalid schedule: ${cronExpression}`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/core/scheduler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,14 @@ import { printHeader } from './lib/output.js';
|
|
|
4
4
|
import { init } from './commands/init.js';
|
|
5
5
|
import { generate } from './commands/generate.js';
|
|
6
6
|
import { setupWorkflow } from './commands/setup-workflow.js';
|
|
7
|
+
import { checkDueTopics } from './commands/check-due.js';
|
|
7
8
|
const program = new Command();
|
|
8
9
|
// Print the Seshat header
|
|
9
10
|
printHeader();
|
|
10
11
|
program
|
|
11
12
|
.name('seshat')
|
|
12
13
|
.description('AI-powered content generation for Sanity CMS')
|
|
13
|
-
.version('
|
|
14
|
+
.version('2.0.0');
|
|
14
15
|
program
|
|
15
16
|
.command('init')
|
|
16
17
|
.description('Initialize Seshat configuration in the current directory')
|
|
@@ -27,7 +28,10 @@ program
|
|
|
27
28
|
.command('write')
|
|
28
29
|
.description('Generate a new blog post with AI')
|
|
29
30
|
.option('--dry-run', 'Preview the content without saving files')
|
|
30
|
-
.option('-t, --topic <topic>', 'Override the topic from config for this post')
|
|
31
|
+
.option('-t, --topic <topic>', 'Override the topic from config for this post (file-based config only)')
|
|
32
|
+
.option('--topic-id <id>', 'Sanity contentTopic document ID to generate from')
|
|
33
|
+
.option('--sanity-project <projectId>', 'Sanity project ID (required with --topic-id)')
|
|
34
|
+
.option('--sanity-dataset <dataset>', 'Sanity dataset name (required with --topic-id)')
|
|
31
35
|
.action(async (options) => {
|
|
32
36
|
try {
|
|
33
37
|
await generate(options);
|
|
@@ -37,6 +41,25 @@ program
|
|
|
37
41
|
process.exit(1);
|
|
38
42
|
}
|
|
39
43
|
});
|
|
44
|
+
program
|
|
45
|
+
.command('check-due')
|
|
46
|
+
.description('Check which content topics are due for generation based on their schedules')
|
|
47
|
+
.requiredOption('--sanity-project <projectId>', 'Sanity project ID')
|
|
48
|
+
.requiredOption('--sanity-dataset <dataset>', 'Sanity dataset name')
|
|
49
|
+
.option('--json', 'Output topic IDs as JSON array (for GitHub Actions)')
|
|
50
|
+
.action(async (options) => {
|
|
51
|
+
try {
|
|
52
|
+
const dueTopics = await checkDueTopics(options);
|
|
53
|
+
// If JSON output requested, print the array
|
|
54
|
+
if (options.json) {
|
|
55
|
+
console.log(JSON.stringify(dueTopics));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
console.error('Error:', err instanceof Error ? err.message : 'Unknown error');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
40
63
|
program
|
|
41
64
|
.command('setup-workflow')
|
|
42
65
|
.description('Create or update .github/workflows/seshat.yml from seshat.config.json (uses schedule or default daily 9 UTC)')
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type definitions for Seshat
|
|
3
|
+
*/
|
|
4
|
+
import type { GenerationConfig } from './config.js';
|
|
5
|
+
/**
|
|
6
|
+
* Content Topic document type from Sanity
|
|
7
|
+
* Represents a topic configuration for scheduled content generation
|
|
8
|
+
*/
|
|
9
|
+
export interface ContentTopicDocument {
|
|
10
|
+
_id: string;
|
|
11
|
+
_type: 'contentTopic';
|
|
12
|
+
_createdAt: string;
|
|
13
|
+
_updatedAt: string;
|
|
14
|
+
_rev: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
active: boolean;
|
|
18
|
+
topic: string;
|
|
19
|
+
tone: string;
|
|
20
|
+
cronSchedule: string;
|
|
21
|
+
nextRunTime?: string;
|
|
22
|
+
lastGeneratedAt?: string;
|
|
23
|
+
generation?: GenerationConfig;
|
|
24
|
+
sanityOverride?: {
|
|
25
|
+
documentType?: string;
|
|
26
|
+
imageFormat?: 'png' | 'jpg' | 'svg';
|
|
27
|
+
};
|
|
28
|
+
totalGenerated: number;
|
|
29
|
+
lastError?: string;
|
|
30
|
+
lastGeneratedPostId?: {
|
|
31
|
+
_type: 'reference';
|
|
32
|
+
_ref: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Schedule information for a topic
|
|
37
|
+
*/
|
|
38
|
+
export interface ScheduleInfo {
|
|
39
|
+
isActive: boolean;
|
|
40
|
+
lastRun: Date | null;
|
|
41
|
+
nextRun: Date | null;
|
|
42
|
+
isDue: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Configuration for Sanity connection
|
|
46
|
+
*/
|
|
47
|
+
export interface SanityConnectionConfig {
|
|
48
|
+
projectId: string;
|
|
49
|
+
dataset: string;
|
|
50
|
+
apiVersion?: string;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,aAAa,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,cAAc,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IAGb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAGhB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IAGb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAG9B,cAAc,CAAC,EAAE;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;KACrC,CAAC;IAGF,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE;QACpB,KAAK,EAAE,WAAW,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "seshat-scribe",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "AI-powered blog content generation for Sanity CMS using Google Gemini",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@sanity/client": "^7.14.0",
|
|
51
51
|
"chalk": "^5.3.0",
|
|
52
52
|
"commander": "^12.1.0",
|
|
53
|
+
"cron-parser": "^4.9.0",
|
|
53
54
|
"dotenv": "^16.4.7",
|
|
54
55
|
"ora": "^8.1.1",
|
|
55
56
|
"zod": "^3.24.1"
|