seshat-scribe 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +1 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/setup-workflow.d.ts +2 -0
- package/dist/commands/setup-workflow.d.ts.map +1 -0
- package/dist/commands/setup-workflow.js +37 -0
- package/dist/commands/setup-workflow.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/core/artist.d.ts.map +1 -1
- package/dist/core/artist.js +14 -6
- package/dist/core/artist.js.map +1 -1
- package/dist/core/planner.d.ts.map +1 -1
- package/dist/core/planner.js +37 -5
- package/dist/core/planner.js.map +1 -1
- package/dist/core/writer.d.ts.map +1 -1
- package/dist/core/writer.js +28 -15
- package/dist/core/writer.js.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
- package/templates/workflow.yml +10 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB1C"}
|
package/dist/commands/init.js
CHANGED
|
@@ -23,6 +23,7 @@ export async function init() {
|
|
|
23
23
|
console.log(' Next steps:');
|
|
24
24
|
console.log(' 1. Set your GEMINI_API_KEY environment variable');
|
|
25
25
|
console.log(' 2. Run: seshat write');
|
|
26
|
+
console.log(' 3. Run: seshat setup-workflow (add schedule to config, then run to create .github/workflows/seshat.yml)');
|
|
26
27
|
console.log('');
|
|
27
28
|
}
|
|
28
29
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;IAElE,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5B,IAAI,CAAC,yDAAyD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAEvD,OAAO,CAAC,4BAA4B,CAAC,CAAC;IACtC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;IAElE,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5B,IAAI,CAAC,yDAAyD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAEvD,OAAO,CAAC,4BAA4B,CAAC,CAAC;IACtC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,2GAA2G,CAAC,CAAC;IACzH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-workflow.d.ts","sourceRoot":"","sources":["../../src/commands/setup-workflow.ts"],"names":[],"mappings":"AAQA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA8BnD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { loadConfig } from '../config.js';
|
|
5
|
+
import { success, error, info } from '../lib/output.js';
|
|
6
|
+
const CRON_DEFAULT = '0 9 * * *';
|
|
7
|
+
export async function setupWorkflow() {
|
|
8
|
+
const configPath = path.join(process.cwd(), 'seshat.config.json');
|
|
9
|
+
let config;
|
|
10
|
+
try {
|
|
11
|
+
config = await loadConfig(configPath);
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
error('Could not load seshat.config.json');
|
|
15
|
+
info('Run: seshat init');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const cron = config.schedule ?? CRON_DEFAULT;
|
|
19
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const templatePath = path.resolve(__dirname, '../../templates/workflow.yml');
|
|
21
|
+
let template;
|
|
22
|
+
try {
|
|
23
|
+
template = await fs.readFile(templatePath, 'utf-8');
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
error('Could not read workflow template from package');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const yaml = template.replace(/\{\{CRON\}\}/g, cron);
|
|
30
|
+
const outDir = path.join(process.cwd(), '.github', 'workflows');
|
|
31
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
32
|
+
const outPath = path.join(outDir, 'seshat.yml');
|
|
33
|
+
await fs.writeFile(outPath, yaml, 'utf-8');
|
|
34
|
+
success(`Created ${path.relative(process.cwd(), outPath)} (schedule: ${cron})`);
|
|
35
|
+
info('Add GEMINI_API_KEY to your repository secrets to enable automated runs');
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=setup-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-workflow.js","sourceRoot":"","sources":["../../src/commands/setup-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,YAAY,GAAG,WAAW,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC,CAAC;IAClE,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC3C,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,IAAI,YAAY,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,8BAA8B,CAAC,CAAC;IAC7E,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAChE,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAE3C,OAAO,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,eAAe,IAAI,GAAG,CAAC,CAAC;IAChF,IAAI,CAAC,wEAAwE,CAAC,CAAC;AACjF,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare const SeshatConfigSchema: z.ZodObject<{
|
|
|
9
9
|
topic: z.ZodString;
|
|
10
10
|
tone: z.ZodString;
|
|
11
11
|
framework: z.ZodEnum<["remix", "next", "astro"]>;
|
|
12
|
+
schedule: z.ZodOptional<z.ZodString>;
|
|
12
13
|
}, "strip", z.ZodTypeAny, {
|
|
13
14
|
contentDir: string;
|
|
14
15
|
assetsDir: string;
|
|
@@ -16,6 +17,7 @@ export declare const SeshatConfigSchema: z.ZodObject<{
|
|
|
16
17
|
topic: string;
|
|
17
18
|
tone: string;
|
|
18
19
|
framework: "remix" | "next" | "astro";
|
|
20
|
+
schedule?: string | undefined;
|
|
19
21
|
}, {
|
|
20
22
|
contentDir: string;
|
|
21
23
|
assetsDir: string;
|
|
@@ -23,6 +25,7 @@ export declare const SeshatConfigSchema: z.ZodObject<{
|
|
|
23
25
|
topic: string;
|
|
24
26
|
tone: string;
|
|
25
27
|
framework: "remix" | "next" | "astro";
|
|
28
|
+
schedule?: string | undefined;
|
|
26
29
|
}>;
|
|
27
30
|
export type SeshatConfig = z.infer<typeof SeshatConfigSchema>;
|
|
28
31
|
/**
|
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,kBAAkB
|
|
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,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;EAW7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,YAO5B,CAAC;AAEF;;GAEG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAK1E"}
|
package/dist/config.js
CHANGED
|
@@ -9,6 +9,10 @@ export const SeshatConfigSchema = z.object({
|
|
|
9
9
|
topic: z.string().describe('Global topic constraint for content generation'),
|
|
10
10
|
tone: z.string().describe('Writing tone (e.g., "Professional yet witty")'),
|
|
11
11
|
framework: z.enum(['remix', 'next', 'astro']).describe('Blog framework type'),
|
|
12
|
+
schedule: z
|
|
13
|
+
.string()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe('Cron expression for GitHub Actions (e.g. "0 9 * * *" for daily at 9 UTC)'),
|
|
12
16
|
});
|
|
13
17
|
/**
|
|
14
18
|
* Default configuration values
|
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;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IACtE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;IAChE,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IAClE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;IAC5E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IAC1E,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;IACtE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;IAChE,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IAClE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;IAC5E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;IAC1E,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;IAC7E,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,0EAA0E,CAAC;CACxF,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,UAAU,EAAE,iBAAiB;IAC7B,SAAS,EAAE,yBAAyB;IACpC,eAAe,EAAE,mBAAmB;IACpC,KAAK,EAAE,qCAAqC;IAC5C,IAAI,EAAE,wBAAwB;IAC9B,SAAS,EAAE,OAAO;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artist.d.ts","sourceRoot":"","sources":["../../src/core/artist.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"artist.d.ts","sourceRoot":"","sources":["../../src/core/artist.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAiBjD;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CA8DjB"}
|
package/dist/core/artist.js
CHANGED
|
@@ -3,6 +3,17 @@ import path from 'path';
|
|
|
3
3
|
import { createGenAIClient, SafetyFilterLevel, PersonGeneration } from '../lib/gemini.js';
|
|
4
4
|
import { addUsage } from '../lib/usage.js';
|
|
5
5
|
const IMAGE_MODEL = 'imagen-4.0-generate-001';
|
|
6
|
+
function pickOne(arr) {
|
|
7
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
8
|
+
}
|
|
9
|
+
const STYLE_OVERLAYS = [
|
|
10
|
+
'Style: Digital drawing, hand-drawn aesthetic, slightly imperfect and organic. Warm, approachable colors. Indie illustration or personal blog. Avoid: corporate stock, 3D renders, overly polished.',
|
|
11
|
+
'Style: Muted, film-like colors; slight grain. Feels like a 70s book cover or vintage poster. Avoid: bright flat colors, slick digital look.',
|
|
12
|
+
'Style: Bold shapes, limited palette (2–3 colors), graphic and poster-like. High contrast. Avoid: detailed realism, busy compositions.',
|
|
13
|
+
'Style: Soft, painterly; visible brush strokes. Not photorealistic. Avoid: sharp vectors, corporate clip art.',
|
|
14
|
+
'Style: Minimal: lots of negative space, one strong focal point, restrained colors. Avoid: busy, maximalist.',
|
|
15
|
+
'Style: Slightly surreal or unexpected: one odd angle, scale, or juxtaposition. Still readable. Avoid: generic stock imagery.',
|
|
16
|
+
];
|
|
6
17
|
/**
|
|
7
18
|
* Generate an image using Gemini's Imagen 4.0 model
|
|
8
19
|
*/
|
|
@@ -13,14 +24,11 @@ export async function generateImage(config, imagePrompt, slug) {
|
|
|
13
24
|
await fs.mkdir(assetsPath, { recursive: true });
|
|
14
25
|
try {
|
|
15
26
|
const ai = createGenAIClient();
|
|
16
|
-
// Enhance
|
|
27
|
+
// Enhance with a randomly chosen style overlay so images vary across runs
|
|
28
|
+
const overlay = pickOne(STYLE_OVERLAYS);
|
|
17
29
|
const enhancedPrompt = `${imagePrompt}
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
Should look human-made, not overly polished or synthetic.
|
|
21
|
-
Warm, approachable colors with a personal touch.
|
|
22
|
-
Think indie illustration or personal blog header art.
|
|
23
|
-
Avoid: Corporate stock photo look, 3D renders, photorealistic AI art, overly perfect compositions.`;
|
|
31
|
+
${overlay}`;
|
|
24
32
|
// Generate the image using the correct API with timeout
|
|
25
33
|
const imagePromise = ai.models.generateImages({
|
|
26
34
|
model: IMAGE_MODEL,
|
package/dist/core/artist.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artist.js","sourceRoot":"","sources":["../../src/core/artist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG3C,MAAM,WAAW,GAAG,yBAAyB,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAoB,EACpB,WAAmB,EACnB,IAAY;IAEZ,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;IAEvD,qCAAqC;IACrC,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;QAE/B,
|
|
1
|
+
{"version":3,"file":"artist.js","sourceRoot":"","sources":["../../src/core/artist.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG3C,MAAM,WAAW,GAAG,yBAAyB,CAAC;AAE9C,SAAS,OAAO,CAAI,GAAQ;IAC1B,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,cAAc,GAAa;IAC/B,oMAAoM;IACpM,6IAA6I;IAC7I,uIAAuI;IACvI,8GAA8G;IAC9G,6GAA6G;IAC7G,8HAA8H;CAC/H,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAoB,EACpB,WAAmB,EACnB,IAAY;IAEZ,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;IAEvD,qCAAqC;IACrC,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;QAE/B,0EAA0E;QAC1E,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACxC,MAAM,cAAc,GAAG,GAAG,WAAW;;EAEvC,OAAO,EAAE,CAAC;QAER,wDAAwD;QACxD,MAAM,YAAY,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC;YAC5C,KAAK,EAAE,WAAW;YAClB,MAAM,EAAE,cAAc;YACtB,MAAM,EAAE;gBACN,cAAc,EAAE,CAAC;gBACjB,WAAW,EAAE,MAAM,EAAE,wBAAwB;gBAC7C,iBAAiB,EAAE,iBAAiB,CAAC,mBAAmB;gBACxD,gBAAgB,EAAE,gBAAgB,CAAC,WAAW;aAC/C;SACF,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/C,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,EAAE,KAAK,CAAC,CACnF,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,CAAiC,CAAC;QAEpG,IAAI,CAAC,QAAQ,CAAC,eAAe,IAAI,QAAQ,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;QAED,MAAM,cAAc,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEnD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QAED,oCAAoC;QACpC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3E,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAE3C,QAAQ,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAExE,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QACtG,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QAErD,0CAA0C;QAC1C,MAAM,cAAc,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QAEvD,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAAC,IAAY;IAC1C,gDAAgD;IAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,CAAC;IAEvB,OAAO;;;gDAGuC,GAAG;kDACD,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG;;;;;MAK5D,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE;;;;;OAKpC,CAAC;AACR,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/core/planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/core/planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA+BjD;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAMzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CA+DnB"}
|
package/dist/core/planner.js
CHANGED
|
@@ -2,6 +2,30 @@ import { z } from 'zod';
|
|
|
2
2
|
import { createGenAIClient } from '../lib/gemini.js';
|
|
3
3
|
import { addUsage, fromGenerateContentResponse } from '../lib/usage.js';
|
|
4
4
|
const PLAN_MODEL = 'gemini-3-flash-preview';
|
|
5
|
+
function pickOne(arr) {
|
|
6
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
7
|
+
}
|
|
8
|
+
const TITLE_ARCHETYPES = [
|
|
9
|
+
{ instruction: 'Phrase the title as a question.', example: 'Why Does X Still Break in Production?' },
|
|
10
|
+
{ instruction: 'Use a how-to format.', example: 'How to X Without Y' },
|
|
11
|
+
{ instruction: 'Use a short, declarative statement.', example: 'X Is Underrated' },
|
|
12
|
+
{ instruction: 'Use a provocative or contrarian angle.', example: 'Stop Doing X (Do Y Instead)' },
|
|
13
|
+
{ instruction: 'Use an understated, curiosity-driven title.', example: 'A Small Thing About X' },
|
|
14
|
+
{ instruction: 'Use a list or collection format.', example: '3 Things I Wish I Knew About X' },
|
|
15
|
+
{ instruction: 'Use a title that suggests a story or journey.', example: 'How I Finally Understood X' },
|
|
16
|
+
{ instruction: 'Use a single punchy phrase or a few words.', example: 'Defaults Matter' },
|
|
17
|
+
{ instruction: 'Use a "what nobody tells you" or insider angle.', example: 'What Nobody Tells You About X' },
|
|
18
|
+
];
|
|
19
|
+
const IMAGE_STYLE_DIRECTIONS = [
|
|
20
|
+
{ direction: 'Minimalist line art or iconography; lots of negative space.', example: 'Single continuous line forming a symbol, one accent color on white' },
|
|
21
|
+
{ direction: 'Moody, atmospheric; shallow depth of field or soft focus; like a film still.', example: 'Blurred background, one sharp object, muted palette' },
|
|
22
|
+
{ direction: 'Bold graphic shapes, limited palette (2–3 colors), poster-like.', example: 'Flat geometric shapes, high contrast, no gradients' },
|
|
23
|
+
{ direction: 'Sketchy, hand-drawn; pencil or ink; deliberately imperfect.', example: 'Quick sketch or doodle, visible strokes, unpolished' },
|
|
24
|
+
{ direction: 'Collage or mixed media; layered textures, paper, or found elements.', example: 'Cut-paper, tape, or layered scraps; tactile' },
|
|
25
|
+
{ direction: 'Abstract: gradients, blobs, or organic shapes; no literal objects.', example: 'Soft blobs or waves, dreamy, no recognizable objects' },
|
|
26
|
+
{ direction: 'Flat illustration with one strong accent color on a neutral base.', example: 'Simple shapes, one pop of color, rest muted' },
|
|
27
|
+
{ direction: 'Retro or vintage: 70s book cover, old textbook diagram, or poster.', example: 'Grainy, sepia or faded colors, old typography feel' },
|
|
28
|
+
];
|
|
5
29
|
/**
|
|
6
30
|
* Schema for the blog post plan returned by Gemini
|
|
7
31
|
*/
|
|
@@ -19,6 +43,8 @@ export async function planBlogPost(config, context) {
|
|
|
19
43
|
const ai = createGenAIClient();
|
|
20
44
|
const existingTitles = context.posts.map((p) => p.title).join('\n - ');
|
|
21
45
|
const existingTopics = context.recentTopics.join(', ');
|
|
46
|
+
const titleArchetype = pickOne(TITLE_ARCHETYPES);
|
|
47
|
+
const imageStyle = pickOne(IMAGE_STYLE_DIRECTIONS);
|
|
22
48
|
const prompt = `Plan a new blog post for a developer blog.
|
|
23
49
|
|
|
24
50
|
**Existing Content:**
|
|
@@ -33,17 +59,23 @@ export async function planBlogPost(config, context) {
|
|
|
33
59
|
2. Make it specific and valuable to developers
|
|
34
60
|
3. Avoid duplicating existing posts
|
|
35
61
|
4. Vary from recent posts (if last posts were about X, pick something different)
|
|
36
|
-
5. Create a clear, specific title (not generic)
|
|
37
62
|
|
|
38
|
-
|
|
63
|
+
**Title (important – follow this format):**
|
|
64
|
+
${titleArchetype.instruction} Example: "${titleArchetype.example}"
|
|
65
|
+
- If the existing titles above mostly use one format (e.g. how-to or questions), pick a *different* format for this one.
|
|
66
|
+
- Avoid generic or templated titles. Be specific to the topic.
|
|
67
|
+
|
|
68
|
+
**Image:**
|
|
69
|
+
Describe the header image to match this style: ${imageStyle.direction}
|
|
70
|
+
Example: "${imageStyle.example}" — adapt to the post's topic. Do NOT use a generic "blog header" or "minimalist illustration" phrase; describe a concrete scene, metaphor, or mood.
|
|
39
71
|
|
|
40
72
|
**Output JSON:**
|
|
41
73
|
{
|
|
42
|
-
"title": "
|
|
74
|
+
"title": "<your title in the chosen format>",
|
|
43
75
|
"slug": "url-friendly-slug",
|
|
44
|
-
"description": "One sentence
|
|
76
|
+
"description": "One sentence: vary the phrasing (e.g. benefit, question, or punchy statement — not always 'This post covers X').",
|
|
45
77
|
"tags": ["primary-tag", "related-tag", "context-tag"],
|
|
46
|
-
"imagePrompt": "
|
|
78
|
+
"imagePrompt": "<your image description matching the style above>"
|
|
47
79
|
}
|
|
48
80
|
|
|
49
81
|
Return only valid JSON.`;
|
package/dist/core/planner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/core/planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAIxE,MAAM,UAAU,GAAG,wBAAwB,CAAC;AAE5C;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;CACxB,CAAC,CAAC;AAIH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAoB,EACpB,OAA0B;IAE1B,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAE/B,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG;;;iBAGA,OAAO,CAAC,UAAU;YACvB,cAAc,IAAI,UAAU;YAC5B,cAAc,IAAI,UAAU;;mBAErB,MAAM,CAAC,KAAK;;;0BAGL,MAAM,CAAC,KAAK
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/core/planner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/core/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/core/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAmBjD;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,MAAM,CAAC,CAmEjB"}
|
package/dist/core/writer.js
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { createGenAIClient } from '../lib/gemini.js';
|
|
2
2
|
import { addUsage, fromGenerateContentResponse } from '../lib/usage.js';
|
|
3
3
|
const WRITE_MODEL = 'gemini-3-flash-preview';
|
|
4
|
+
function pickOne(arr) {
|
|
5
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
6
|
+
}
|
|
7
|
+
const OPENING_STYLES = [
|
|
8
|
+
{ instruction: 'Start with 1–2 sentences on why this matters to the reader.' },
|
|
9
|
+
{ instruction: 'Open with a question that the post will answer.' },
|
|
10
|
+
{ instruction: 'Open with a bold or surprising claim, then back it up.' },
|
|
11
|
+
{ instruction: 'Open with a very short anecdote or moment (2–3 sentences) that leads into the topic.' },
|
|
12
|
+
{ instruction: 'Dive straight into the technical content; no preamble. Start with a concrete example or definition.' },
|
|
13
|
+
{ instruction: 'Start with an understated, almost casual observation that draws the reader in.' },
|
|
14
|
+
{ instruction: 'Start by contradicting a common belief or practice, then explain.' },
|
|
15
|
+
{ instruction: 'Start with a specific frustration or "this used to confuse me" and then resolve it.' },
|
|
16
|
+
];
|
|
4
17
|
/**
|
|
5
18
|
* Use Gemini to write a complete MDX blog post
|
|
6
19
|
*/
|
|
@@ -11,34 +24,34 @@ export async function writeBlogPost(config, plan) {
|
|
|
11
24
|
// Pick the first tag from the plan
|
|
12
25
|
const primaryTag = plan.tags[0] || 'general';
|
|
13
26
|
const frontmatterFormat = getFrontmatterFormat(config.framework, plan.title, plan.description, currentDate, primaryTag);
|
|
14
|
-
const
|
|
27
|
+
const opening = pickOne(OPENING_STYLES);
|
|
28
|
+
const prompt = `Write a technical blog post in MDX format. Clear, valuable, focused on helping readers understand. Vary your voice — avoid sounding like a generic AI or a template.
|
|
15
29
|
|
|
16
30
|
**Post Details:**
|
|
17
31
|
- Title: ${plan.title}
|
|
18
32
|
- Description: ${plan.description}
|
|
19
33
|
- Tag: ${primaryTag}
|
|
20
34
|
|
|
35
|
+
**Opening (follow this for the first paragraph):**
|
|
36
|
+
${opening.instruction}
|
|
37
|
+
Do NOT start with "In this article we will...", "In today's post...", or similar. Each post should feel like it was written on a different day.
|
|
38
|
+
|
|
21
39
|
**Writing Style:**
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- Write like you're helping a colleague understand something
|
|
40
|
+
- Prose that delivers value without fluff or filler
|
|
41
|
+
- First-person when it fits ("I found", "I learned"); not every sentence
|
|
42
|
+
- Vary sentence length and rhythm — short and long, not uniform
|
|
43
|
+
- It's okay to be a bit idiosyncratic or opinionated
|
|
44
|
+
- Use examples and code to clarify; show real code, not pseudo-code
|
|
45
|
+
- Explain the "why" behind decisions; include edge cases or gotchas when relevant
|
|
29
46
|
|
|
30
47
|
**Structure:**
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
- Use clear headings to organize ideas
|
|
48
|
+
- Use clear headings, but don't follow a cookie-cutter pattern (e.g. not always Intro → Background → Solution → Conclusion with equal weight)
|
|
49
|
+
- Let the topic dictate structure: some posts need a long setup, others can jump in
|
|
34
50
|
- Include practical code examples where helpful
|
|
35
|
-
- Vary your structure - don't follow a template
|
|
36
51
|
|
|
37
52
|
**Technical Quality:**
|
|
38
53
|
- Be accurate and specific
|
|
39
|
-
-
|
|
40
|
-
- Explain the "why" behind decisions
|
|
41
|
-
- Include edge cases or gotchas when relevant
|
|
54
|
+
- Avoid formulaic transitions ("Furthermore", "Moreover", "It's worth noting that" as crutches)
|
|
42
55
|
|
|
43
56
|
**Tone: ${config.tone}**
|
|
44
57
|
|
package/dist/core/writer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/core/writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAIxE,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAoB,EACpB,IAAc;IAEd,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAE/B,iCAAiC;IACjC,MAAM,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE7C,mCAAmC;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;IAE7C,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/core/writer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Command } from 'commander';
|
|
|
3
3
|
import { printHeader } from './lib/output.js';
|
|
4
4
|
import { init } from './commands/init.js';
|
|
5
5
|
import { generate } from './commands/generate.js';
|
|
6
|
+
import { setupWorkflow } from './commands/setup-workflow.js';
|
|
6
7
|
const program = new Command();
|
|
7
8
|
// Print the Seshat header
|
|
8
9
|
printHeader();
|
|
@@ -35,5 +36,17 @@ program
|
|
|
35
36
|
process.exit(1);
|
|
36
37
|
}
|
|
37
38
|
});
|
|
39
|
+
program
|
|
40
|
+
.command('setup-workflow')
|
|
41
|
+
.description('Create or update .github/workflows/seshat.yml from seshat.config.json (uses schedule or default daily 9 UTC)')
|
|
42
|
+
.action(async () => {
|
|
43
|
+
try {
|
|
44
|
+
await setupWorkflow();
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.error('Error:', err instanceof Error ? err.message : 'Unknown error');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
38
51
|
program.parse();
|
|
39
52
|
//# sourceMappingURL=index.js.map
|
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;
|
|
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;AAE7D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,0BAA0B;AAC1B,WAAW,EAAE,CAAC;AAEd,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,wCAAwC,CAAC;KACrD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0DAA0D,CAAC;KACvE,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,IAAI,EAAE,CAAC;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,WAAW,EAAE,0CAA0C,CAAC;KAC/D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,8GAA8G,CAAC;KAC3H,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,aAAa,EAAE,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "seshat-scribe",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "The Autonomous Scribe for Static Blogs - AI-powered content generation using Google Gemini",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"dev": "tsx src/index.ts",
|
|
13
13
|
"prepare": "npm run build",
|
|
14
|
-
"test": "echo \"No tests yet\" && exit 0"
|
|
14
|
+
"test": "echo \"No tests yet\" && exit 0",
|
|
15
|
+
"release:dry": "npm run build && npm publish --dry-run",
|
|
16
|
+
"release:patch": "npm test && npm version patch -m 'Release v%s' && npm publish && git push && git push --tags",
|
|
17
|
+
"release:minor": "npm test && npm version minor -m 'Release v%s' && npm publish && git push && git push --tags",
|
|
18
|
+
"release:major": "npm test && npm version major -m 'Release v%s' && npm publish && git push && git push --tags"
|
|
15
19
|
},
|
|
16
20
|
"keywords": [
|
|
17
21
|
"blog",
|
package/templates/workflow.yml
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
name: Seshat Scribe
|
|
2
2
|
on:
|
|
3
3
|
schedule:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
workflow_dispatch: # Allow manual triggering
|
|
4
|
+
- cron: '{{CRON}}'
|
|
5
|
+
workflow_dispatch:
|
|
7
6
|
|
|
8
7
|
permissions:
|
|
9
8
|
contents: write
|
|
@@ -11,24 +10,28 @@ permissions:
|
|
|
11
10
|
jobs:
|
|
12
11
|
write:
|
|
13
12
|
runs-on: ubuntu-latest
|
|
14
|
-
|
|
15
13
|
steps:
|
|
16
14
|
- name: Checkout repository
|
|
17
15
|
uses: actions/checkout@v4
|
|
18
16
|
|
|
17
|
+
- name: Install pnpm
|
|
18
|
+
uses: pnpm/action-setup@v4
|
|
19
|
+
with:
|
|
20
|
+
version: 9
|
|
21
|
+
|
|
19
22
|
- name: Setup Node.js
|
|
20
23
|
uses: actions/setup-node@v4
|
|
21
24
|
with:
|
|
22
25
|
node-version: '20'
|
|
23
|
-
cache: '
|
|
26
|
+
cache: 'pnpm'
|
|
24
27
|
|
|
25
28
|
- name: Install dependencies
|
|
26
|
-
run:
|
|
29
|
+
run: pnpm install --frozen-lockfile
|
|
27
30
|
|
|
28
31
|
- name: Summon Seshat
|
|
29
32
|
env:
|
|
30
33
|
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
31
|
-
run:
|
|
34
|
+
run: pnpm exec seshat write
|
|
32
35
|
|
|
33
36
|
- name: Commit and push changes
|
|
34
37
|
run: |
|