seshat-scribe 0.9.2 → 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/README.md +47 -58
- 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 +4 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +120 -97
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +73 -338
- package/dist/commands/init.js.map +1 -1
- package/dist/config.d.ts +21 -179
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -112
- package/dist/config.js.map +1 -1
- package/dist/core/analyzer.d.ts +1 -1
- package/dist/core/analyzer.d.ts.map +1 -1
- package/dist/core/analyzer.js +2 -115
- package/dist/core/analyzer.js.map +1 -1
- package/dist/core/artist.d.ts +1 -2
- package/dist/core/artist.d.ts.map +1 -1
- package/dist/core/artist.js +2 -5
- package/dist/core/artist.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 +26 -3
- 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 +7 -8
- package/dist/core/writer.d.ts +0 -7
- package/dist/core/writer.d.ts.map +0 -1
- package/dist/core/writer.js +0 -126
- package/dist/core/writer.js.map +0 -1
- package/dist/lib/detection.d.ts +0 -13
- package/dist/lib/detection.d.ts.map +0 -1
- package/dist/lib/detection.js +0 -158
- package/dist/lib/detection.js.map +0 -1
- package/dist/lib/frontmatter.d.ts +0 -28
- package/dist/lib/frontmatter.d.ts.map +0 -1
- package/dist/lib/frontmatter.js +0 -114
- package/dist/lib/frontmatter.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# Seshat
|
|
2
2
|
|
|
3
|
-
AI-powered automatic content generation for
|
|
3
|
+
AI-powered automatic content generation for Sanity CMS. Seshat analyzes your existing content, generates new blog posts using Google Gemini, and publishes directly to Sanity. Automatic generation and publication via GitHub Actions on a schedule.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Free to Use**: Works with Google's free Gemini API tier for text generation, use paid tier for image generation
|
|
8
8
|
- **AI-Powered Planning**: Analyzes existing content to generate unique, non-duplicate topics
|
|
9
9
|
- **BYOK** - Bring Your Own Key, it will use your Gemini key to generate posts
|
|
10
|
-
- **
|
|
11
|
-
- **Smart Generation**: Creates complete articles
|
|
12
|
-
- **Framework Support**: Optional presets for Remix, Next.js, and Astro (or custom configuration)
|
|
13
|
-
- **Flexible Configuration**: Customizable frontmatter, file naming, and content generation options
|
|
10
|
+
- **Sanity Integration**: Automatic image upload and document creation in Portable Text format
|
|
11
|
+
- **Smart Generation**: Creates complete articles as Portable Text with optional hero images
|
|
14
12
|
- **GitHub Actions Integration**: Automate content creation on a schedule
|
|
15
13
|
- **Type-Safe**: Built with TypeScript and Zod for runtime validation
|
|
16
14
|
|
|
@@ -35,11 +33,10 @@ cd your-blog-project
|
|
|
35
33
|
seshat init
|
|
36
34
|
```
|
|
37
35
|
|
|
38
|
-
The interactive wizard will guide you through
|
|
36
|
+
The interactive wizard will guide you through Sanity CMS configuration:
|
|
39
37
|
- Choose between quick setup (recommended defaults) or custom configuration
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- Auto-detect existing blog structure if available
|
|
38
|
+
- Enter your Sanity project ID, dataset, and API version
|
|
39
|
+
- Configure content generation options (optional)
|
|
43
40
|
|
|
44
41
|
### 2. Configure API Keys
|
|
45
42
|
|
|
@@ -55,7 +52,7 @@ export GEMINI_API_KEY="your_api_key_here"
|
|
|
55
52
|
|
|
56
53
|
By default, Seshat will attempt to generate images. To create text-only posts (for free tier), set `enableImageGeneration: false` in your config (see [Configuration](#content-generation) below).
|
|
57
54
|
|
|
58
|
-
|
|
55
|
+
**Sanity Write Token** (required):
|
|
59
56
|
|
|
60
57
|
```bash
|
|
61
58
|
export SANITY_WRITE_TOKEN="your_sanity_token_here"
|
|
@@ -77,64 +74,37 @@ seshat write --dry-run
|
|
|
77
74
|
|
|
78
75
|
Seshat uses `seshat.config.json` for configuration. The wizard creates this automatically, but you can also edit it manually.
|
|
79
76
|
|
|
80
|
-
###
|
|
77
|
+
### Example Configuration
|
|
81
78
|
|
|
82
79
|
```json
|
|
83
80
|
{
|
|
84
81
|
"topic": "Software Engineering and Technology",
|
|
85
82
|
"tone": "Professional yet approachable",
|
|
86
|
-
"framework": "remix",
|
|
87
|
-
"outputMode": "local"
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
- `topic`: Global topic constraint for content generation
|
|
92
|
-
- `tone`: Writing style and voice
|
|
93
|
-
- `framework`: Optional preset - one of `remix`, `next`, `astro`, or `custom` for manual configuration. Framework presets configure frontmatter fields automatically, but are not required
|
|
94
|
-
- `outputMode`: `local` or `sanity`
|
|
95
|
-
|
|
96
|
-
### Local File Output
|
|
97
|
-
|
|
98
|
-
Required when `outputMode` is `local`:
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"contentDir": "app/routes/blog",
|
|
103
|
-
"assetsDir": "public/images/generated",
|
|
104
|
-
"publicAssetPath": "/images/generated"
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### Sanity CMS Output
|
|
109
|
-
|
|
110
|
-
Required when `outputMode` is `sanity`:
|
|
111
|
-
|
|
112
|
-
```json
|
|
113
|
-
{
|
|
114
83
|
"sanity": {
|
|
115
84
|
"projectId": "your-project-id",
|
|
116
85
|
"dataset": "production",
|
|
117
86
|
"apiVersion": "2024-01-01",
|
|
118
87
|
"documentType": "post"
|
|
88
|
+
},
|
|
89
|
+
"generation": {
|
|
90
|
+
"enableImageGeneration": true,
|
|
91
|
+
"targetWordCount": 1500
|
|
119
92
|
}
|
|
120
93
|
}
|
|
121
94
|
```
|
|
122
95
|
|
|
123
|
-
###
|
|
96
|
+
### Core Settings
|
|
124
97
|
|
|
125
|
-
|
|
126
|
-
- `
|
|
127
|
-
- `
|
|
128
|
-
- `
|
|
129
|
-
- `
|
|
98
|
+
- `topic`: Global topic constraint for content generation
|
|
99
|
+
- `tone`: Writing style and voice
|
|
100
|
+
- `sanity`: Sanity CMS configuration (required)
|
|
101
|
+
- `projectId`: Your Sanity project ID
|
|
102
|
+
- `dataset`: Dataset name (default: "production")
|
|
103
|
+
- `apiVersion`: API version (default: "2024-01-01")
|
|
104
|
+
- `documentType`: Document type to create (default: "post")
|
|
130
105
|
|
|
131
|
-
|
|
132
|
-
- `frontmatter.dateField`: Field name for date (e.g., `date`, `pubDate`)
|
|
133
|
-
- `frontmatter.dateFormat`: `iso`, `date-only`, or custom format
|
|
134
|
-
- `frontmatter.imageField`: Field name for image
|
|
135
|
-
- `frontmatter.additionalFields`: Custom metadata as key-value pairs
|
|
106
|
+
### Content Generation
|
|
136
107
|
|
|
137
|
-
**Content Generation**
|
|
138
108
|
- `generation.enableImageGeneration`: Enable/disable AI image generation (default: `true`). Set to `false` for text-only posts if using free Gemini API tier
|
|
139
109
|
- `generation.targetWordCount`: Target word count (optional)
|
|
140
110
|
- `generation.includeCodeExamples`: Emphasize code examples
|
|
@@ -152,6 +122,9 @@ Example for free tier (text-only):
|
|
|
152
122
|
}
|
|
153
123
|
```
|
|
154
124
|
|
|
125
|
+
### Image Format
|
|
126
|
+
|
|
127
|
+
- `imageFormat`: `png`, `jpg`, or `svg` (default: `png`)
|
|
155
128
|
|
|
156
129
|
## GitHub Actions Automation
|
|
157
130
|
|
|
@@ -169,12 +142,12 @@ This creates `.github/workflows/seshat.yml` based on your configuration.
|
|
|
169
142
|
|
|
170
143
|
Add these to your repository secrets (Settings → Secrets and Variables → Actions):
|
|
171
144
|
|
|
172
|
-
- `GEMINI_API_KEY`: Your Google Gemini API key
|
|
173
|
-
- `SANITY_WRITE_TOKEN`: Your Sanity write token (
|
|
145
|
+
- `GEMINI_API_KEY`: Your Google Gemini API key (required)
|
|
146
|
+
- `SANITY_WRITE_TOKEN`: Your Sanity write token (required)
|
|
174
147
|
|
|
175
148
|
### Customize Schedule
|
|
176
149
|
|
|
177
|
-
This will run the
|
|
150
|
+
This will run the GitHub action workflow to generate and publish posts automatically according to the defined schedule.
|
|
178
151
|
|
|
179
152
|
Edit the `schedule` field in `seshat.config.json`:
|
|
180
153
|
|
|
@@ -203,6 +176,7 @@ Generate a new blog post:
|
|
|
203
176
|
```bash
|
|
204
177
|
seshat write
|
|
205
178
|
seshat write --dry-run # Preview without saving
|
|
179
|
+
seshat write -t "Custom Topic" # Override topic for this post
|
|
206
180
|
```
|
|
207
181
|
|
|
208
182
|
### `seshat setup-workflow`
|
|
@@ -215,11 +189,11 @@ seshat setup-workflow
|
|
|
215
189
|
|
|
216
190
|
## How It Works
|
|
217
191
|
|
|
218
|
-
1. **Analysis**: Scans existing content
|
|
192
|
+
1. **Analysis**: Scans existing content from Sanity CMS to understand what you've written
|
|
219
193
|
2. **Planning**: Uses Google Gemini to propose a new, non-duplicate topic
|
|
220
|
-
3. **Writing**: Generates complete article
|
|
194
|
+
3. **Writing**: Generates complete article as Portable Text
|
|
221
195
|
4. **Illustration** (optional): Creates a hero image using Gemini's image generation (if enabled and API supports it)
|
|
222
|
-
5. **Publishing**:
|
|
196
|
+
5. **Publishing**: Uploads content and images to Sanity CMS
|
|
223
197
|
|
|
224
198
|
## Requirements
|
|
225
199
|
|
|
@@ -227,4 +201,19 @@ seshat setup-workflow
|
|
|
227
201
|
- **Free** Google Gemini API key ([Get one here](https://aistudio.google.com/app/apikey) - no credit card required)
|
|
228
202
|
- Free tier: Text generation only
|
|
229
203
|
- Paid tier: Text + AI image generation
|
|
230
|
-
- Sanity write token (
|
|
204
|
+
- Sanity write token (required)
|
|
205
|
+
- Sanity CMS project
|
|
206
|
+
|
|
207
|
+
## Migrating from 0.x
|
|
208
|
+
|
|
209
|
+
Version 1.0.0 is a breaking change that removes local file support and focuses exclusively on Sanity CMS.
|
|
210
|
+
|
|
211
|
+
If you're upgrading from 0.x:
|
|
212
|
+
1. Run `seshat init` to create a new Sanity-only configuration
|
|
213
|
+
2. Remove old config fields: `outputMode`, `contentDir`, `assetsDir`, `publicAssetPath`, `framework`, `fileExtension`, `fileNameTemplate`, `nestedDirectories`, `frontmatter`
|
|
214
|
+
3. Ensure `sanity` configuration is present and valid
|
|
215
|
+
4. Set `SANITY_WRITE_TOKEN` environment variable
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
|
@@ -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,9 +1,12 @@
|
|
|
1
1
|
export interface GenerateOptions {
|
|
2
2
|
dryRun?: boolean;
|
|
3
3
|
topic?: string;
|
|
4
|
+
topicId?: string;
|
|
5
|
+
sanityProject?: string;
|
|
6
|
+
sanityDataset?: string;
|
|
4
7
|
}
|
|
5
8
|
/**
|
|
6
|
-
* Main command: Generate a new blog post with image
|
|
9
|
+
* Main command: Generate a new blog post with image and upload to Sanity
|
|
7
10
|
*/
|
|
8
11
|
export declare function generate(options?: GenerateOptions): Promise<void>;
|
|
9
12
|
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -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"}
|
|
@@ -4,41 +4,67 @@ import os from 'os';
|
|
|
4
4
|
import ora from 'ora';
|
|
5
5
|
import { scanRepository } from '../core/analyzer.js';
|
|
6
6
|
import { planBlogPost } from '../core/planner.js';
|
|
7
|
-
import { writeBlogPost } from '../core/writer.js';
|
|
8
7
|
import { writePortableTextContent } from '../core/portable-writer.js';
|
|
9
8
|
import { generateImage } from '../core/artist.js';
|
|
10
|
-
import { uploadToSanity } from '../core/sanity.js';
|
|
9
|
+
import { uploadToSanity, createSanityClientFromConfig, updateTopicAfterGeneration, updateTopicError } from '../core/sanity.js';
|
|
10
|
+
import { calculateNextRun } from '../core/scheduler.js';
|
|
11
11
|
import { gold, cyan, error, info, scrollWritten } from '../lib/output.js';
|
|
12
12
|
import { resetUsage, formatUsageSummary } from '../lib/usage.js';
|
|
13
|
-
import {
|
|
13
|
+
import { loadTopicFromSanity } from '../config.js';
|
|
14
14
|
/**
|
|
15
|
-
* Main command: Generate a new blog post with image
|
|
15
|
+
* Main command: Generate a new blog post with image and upload to Sanity
|
|
16
16
|
*/
|
|
17
17
|
export async function generate(options = {}) {
|
|
18
|
-
|
|
19
|
-
// Load configuration
|
|
18
|
+
// Load configuration - either from Sanity topic or file (deprecated)
|
|
20
19
|
let config;
|
|
20
|
+
let topicId;
|
|
21
21
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
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
|
+
}
|
|
24
45
|
}
|
|
25
46
|
catch (err) {
|
|
26
|
-
error('Could not load
|
|
27
|
-
|
|
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');
|
|
28
55
|
process.exit(1);
|
|
29
56
|
}
|
|
30
|
-
// Override topic if provided via CLI
|
|
31
|
-
if (options.topic) {
|
|
32
|
-
config = { ...config, topic: options.topic };
|
|
33
|
-
}
|
|
34
57
|
console.log('');
|
|
35
58
|
console.log(gold.bold('⟡ Seshat awakens...'));
|
|
36
|
-
if (
|
|
59
|
+
if (topicId) {
|
|
60
|
+
info(`Topic ID: ${topicId}`);
|
|
61
|
+
}
|
|
62
|
+
else if (options.topic) {
|
|
37
63
|
info(`Topic override: ${options.topic}`);
|
|
38
64
|
}
|
|
39
65
|
console.log('');
|
|
40
66
|
resetUsage();
|
|
41
|
-
// Step 1: Analyze existing content
|
|
67
|
+
// Step 1: Analyze existing content from Sanity
|
|
42
68
|
const analyzeSpinner = ora({
|
|
43
69
|
text: cyan('Reading the archives...'),
|
|
44
70
|
color: 'cyan',
|
|
@@ -71,35 +97,19 @@ export async function generate(options = {}) {
|
|
|
71
97
|
process.exit(1);
|
|
72
98
|
}
|
|
73
99
|
const postDate = new Date();
|
|
74
|
-
const outputMode = config.outputMode || 'local';
|
|
75
|
-
let mdxContent;
|
|
76
|
-
let portableTextBody;
|
|
77
100
|
// Step 3: Generate the image (if enabled)
|
|
78
101
|
const enableImageGeneration = config.generation?.enableImageGeneration ?? true;
|
|
79
102
|
let imagePath = null;
|
|
80
|
-
let isTemporaryImage = false;
|
|
81
103
|
if (enableImageGeneration) {
|
|
82
104
|
const imageSpinner = ora({
|
|
83
105
|
text: cyan('Seshat is painting...'),
|
|
84
106
|
color: 'cyan',
|
|
85
107
|
}).start();
|
|
86
108
|
try {
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const tempImagePath = path.join(tempDir, `seshat-${plan.slug}.${imageExtension}`);
|
|
92
|
-
// Temporarily override config to save to temp
|
|
93
|
-
const tempConfig = { ...config, assetsDir: tempDir };
|
|
94
|
-
imagePath = await generateImage(tempConfig, plan.imagePrompt, plan.slug);
|
|
95
|
-
isTemporaryImage = true;
|
|
96
|
-
imageSpinner.succeed('Image created (temporary)');
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
imagePath = await generateImage(config, plan.imagePrompt, plan.slug);
|
|
100
|
-
const relativeImagePath = path.relative(process.cwd(), imagePath);
|
|
101
|
-
imageSpinner.succeed(`Image created: ${relativeImagePath}`);
|
|
102
|
-
}
|
|
109
|
+
// Save to temp directory for Sanity upload
|
|
110
|
+
const tempDir = os.tmpdir();
|
|
111
|
+
imagePath = await generateImage(plan.imagePrompt, plan.slug, tempDir);
|
|
112
|
+
imageSpinner.succeed('Image created');
|
|
103
113
|
}
|
|
104
114
|
catch (err) {
|
|
105
115
|
imageSpinner.fail('Image generation failed');
|
|
@@ -110,23 +120,14 @@ export async function generate(options = {}) {
|
|
|
110
120
|
else {
|
|
111
121
|
info('Image generation disabled - creating text-only post');
|
|
112
122
|
}
|
|
113
|
-
// Step 4: Write
|
|
123
|
+
// Step 4: Write Portable Text content
|
|
114
124
|
const writeSpinner = ora({
|
|
115
125
|
text: cyan('Seshat is writing...'),
|
|
116
126
|
color: 'cyan',
|
|
117
127
|
}).start();
|
|
128
|
+
let portableTextBody;
|
|
118
129
|
try {
|
|
119
|
-
|
|
120
|
-
// Determine public image path for frontmatter
|
|
121
|
-
const imageExtension = config.imageFormat === 'jpg' ? 'jpg' : (config.imageFormat === 'svg' ? 'svg' : 'png');
|
|
122
|
-
const publicImagePath = imagePath && config.publicAssetPath
|
|
123
|
-
? `${config.publicAssetPath}/${plan.slug}.${imageExtension}`
|
|
124
|
-
: null;
|
|
125
|
-
mdxContent = await writeBlogPost(config, plan, postDate, publicImagePath);
|
|
126
|
-
}
|
|
127
|
-
if (outputMode === 'sanity') {
|
|
128
|
-
portableTextBody = await writePortableTextContent(config, plan);
|
|
129
|
-
}
|
|
130
|
+
portableTextBody = await writePortableTextContent(config, plan);
|
|
130
131
|
writeSpinner.succeed('Content written');
|
|
131
132
|
}
|
|
132
133
|
catch (err) {
|
|
@@ -134,68 +135,90 @@ export async function generate(options = {}) {
|
|
|
134
135
|
error(err instanceof Error ? err.message : 'Unknown error');
|
|
135
136
|
process.exit(1);
|
|
136
137
|
}
|
|
137
|
-
// Step 5:
|
|
138
|
+
// Step 5: Upload to Sanity
|
|
138
139
|
const saveSpinner = ora({
|
|
139
140
|
text: cyan('Inscribing the scroll...'),
|
|
140
141
|
color: 'cyan',
|
|
141
142
|
}).start();
|
|
143
|
+
let result;
|
|
142
144
|
try {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
145
|
+
if (options.dryRun) {
|
|
146
|
+
saveSpinner.info('Dry run: skipping Sanity upload');
|
|
147
|
+
console.log('');
|
|
148
|
+
console.log(gold('--- Generated Content Preview ---'));
|
|
149
|
+
console.log(`Title: ${plan.title}`);
|
|
150
|
+
console.log(`Slug: ${plan.slug}`);
|
|
151
|
+
console.log(`Description: ${plan.description}`);
|
|
152
|
+
console.log(`Tags: ${plan.tags.join(', ')}`);
|
|
153
|
+
console.log(`Blocks: ${portableTextBody.length}`);
|
|
154
|
+
console.log('');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
result = await uploadToSanity(config, plan, portableTextBody, imagePath, postDate);
|
|
158
|
+
saveSpinner.succeed(`Uploaded to Sanity: ${result.documentId}`);
|
|
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
|
|
161
182
|
}
|
|
162
183
|
}
|
|
163
184
|
}
|
|
164
|
-
//
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const fileNameTemplate = config.fileNameTemplate || '{{slug}}';
|
|
169
|
-
const fileName = buildFileName(fileNameTemplate, plan.slug, postDate, fileExtension);
|
|
170
|
-
if (options.dryRun) {
|
|
171
|
-
saveSpinner.info('Dry run: skipping file write');
|
|
172
|
-
console.log('');
|
|
173
|
-
console.log(gold('--- Generated Content Preview ---'));
|
|
174
|
-
console.log(mdxContent.substring(0, 500) + '...');
|
|
175
|
-
console.log('');
|
|
185
|
+
// Clean up temporary image
|
|
186
|
+
if (imagePath) {
|
|
187
|
+
try {
|
|
188
|
+
await fs.unlink(imagePath);
|
|
176
189
|
}
|
|
177
|
-
|
|
178
|
-
//
|
|
179
|
-
if (!config.contentDir) {
|
|
180
|
-
throw new Error('contentDir is required for local output mode');
|
|
181
|
-
}
|
|
182
|
-
let contentPath = path.resolve(process.cwd(), config.contentDir);
|
|
183
|
-
if (config.nestedDirectories) {
|
|
184
|
-
contentPath = buildNestedPath(postDate, contentPath);
|
|
185
|
-
}
|
|
186
|
-
// Ensure content directory exists
|
|
187
|
-
await fs.mkdir(contentPath, { recursive: true });
|
|
188
|
-
// Write the MDX file
|
|
189
|
-
const mdxFilePath = path.join(contentPath, fileName);
|
|
190
|
-
await fs.writeFile(mdxFilePath, mdxContent, 'utf-8');
|
|
191
|
-
const relativeMdxPath = path.relative(process.cwd(), mdxFilePath);
|
|
192
|
-
saveSpinner.succeed(`Saved: ${relativeMdxPath}`);
|
|
190
|
+
catch (cleanupErr) {
|
|
191
|
+
// Ignore cleanup errors
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
194
|
}
|
|
196
195
|
catch (err) {
|
|
197
|
-
saveSpinner.fail('Failed to
|
|
198
|
-
|
|
196
|
+
saveSpinner.fail('Failed to upload to Sanity');
|
|
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
|
+
}
|
|
213
|
+
// Clean up temporary image on error
|
|
214
|
+
if (imagePath) {
|
|
215
|
+
try {
|
|
216
|
+
await fs.unlink(imagePath);
|
|
217
|
+
}
|
|
218
|
+
catch (cleanupErr) {
|
|
219
|
+
// Ignore cleanup errors
|
|
220
|
+
}
|
|
221
|
+
}
|
|
199
222
|
process.exit(1);
|
|
200
223
|
}
|
|
201
224
|
// Usage summary
|
|
@@ -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":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAMA,UAAU,WAAW;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0MnE"}
|