@sweny-ai/core 0.1.123 → 0.1.124

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.
Files changed (56) hide show
  1. package/dist/agent-env.d.ts +171 -0
  2. package/dist/agent-env.js +393 -0
  3. package/dist/browser.d.ts +2 -2
  4. package/dist/browser.js +1 -1
  5. package/dist/claude.d.ts +61 -3
  6. package/dist/claude.js +187 -27
  7. package/dist/cli/check.d.ts +42 -1
  8. package/dist/cli/check.js +130 -8
  9. package/dist/cli/cloud-lifecycle.d.ts +24 -29
  10. package/dist/cli/cloud-lifecycle.js +187 -12
  11. package/dist/cli/cloud-report.js +45 -2
  12. package/dist/cli/config-file.d.ts +8 -1
  13. package/dist/cli/config-file.js +42 -1
  14. package/dist/cli/config.js +11 -14
  15. package/dist/cli/e2e.d.ts +22 -0
  16. package/dist/cli/e2e.js +31 -4
  17. package/dist/cli/main.d.ts +1 -0
  18. package/dist/cli/main.js +138 -46
  19. package/dist/cli/marketplace.d.ts +3 -1
  20. package/dist/cli/marketplace.js +2 -2
  21. package/dist/cli/new.d.ts +15 -0
  22. package/dist/cli/new.js +139 -65
  23. package/dist/cli/publish.js +9 -0
  24. package/dist/cli/run-output.d.ts +59 -0
  25. package/dist/cli/run-output.js +189 -0
  26. package/dist/cli/skill-env.d.ts +34 -0
  27. package/dist/cli/skill-env.js +64 -0
  28. package/dist/cli/templates.js +587 -0
  29. package/dist/cli/workflow-input.d.ts +41 -0
  30. package/dist/cli/workflow-input.js +56 -0
  31. package/dist/executor.d.ts +17 -1
  32. package/dist/executor.js +119 -9
  33. package/dist/index.d.ts +3 -3
  34. package/dist/index.js +2 -2
  35. package/dist/mermaid.d.ts +6 -0
  36. package/dist/mermaid.js +10 -5
  37. package/dist/schema.d.ts +218 -188
  38. package/dist/schema.js +24 -3
  39. package/dist/skills/betterstack.js +4 -0
  40. package/dist/skills/datadog.js +3 -0
  41. package/dist/skills/github.js +8 -0
  42. package/dist/skills/linear.js +8 -0
  43. package/dist/skills/notification.js +3 -0
  44. package/dist/skills/sentry.js +4 -0
  45. package/dist/skills/slack.js +2 -0
  46. package/dist/skills/supabase.js +9 -0
  47. package/dist/testing.d.ts +3 -2
  48. package/dist/testing.js +9 -3
  49. package/dist/types.d.ts +99 -2
  50. package/dist/types.js +17 -0
  51. package/dist/untrusted.d.ts +32 -0
  52. package/dist/untrusted.js +46 -0
  53. package/dist/workflows/browser.js +2 -2
  54. package/dist/workflows/implement.yml +2 -0
  55. package/dist/workflows/triage.yml +3 -1
  56. package/package.json +1 -1
@@ -5,6 +5,38 @@
5
5
  * strings — no filesystem reads needed, works from npm install.
6
6
  */
7
7
  export const WORKFLOW_TEMPLATES = [
8
+ {
9
+ id: "explain-repo",
10
+ name: "Explain this repo",
11
+ description: "Read the local checkout and explain it. Needs no tokens, no network beyond Claude.",
12
+ yaml: `id: explain-repo
13
+ name: Explain This Repo
14
+ description: Read the local checkout and explain what it does, how it is laid out, and how to run it.
15
+ workflow_type: generic
16
+ entry: survey
17
+
18
+ nodes:
19
+ survey:
20
+ name: Survey the Repo
21
+ instruction: |
22
+ Look at the current directory. Read the README, the package or
23
+ build manifests, and the top-level layout. Identify the main
24
+ languages, the entry points, and the key directories.
25
+ Only read files. Do not modify anything.
26
+
27
+ explain:
28
+ name: Explain It
29
+ instruction: |
30
+ From the survey, write a short plain-English explanation:
31
+ what this project does, how it is organized, how to build and
32
+ run it, and where a new contributor should start.
33
+ Keep it under 300 words.
34
+
35
+ edges:
36
+ - from: survey
37
+ to: explain
38
+ `,
39
+ },
8
40
  {
9
41
  id: "pr-review",
10
42
  name: "PR Review Bot",
@@ -12,6 +44,7 @@ export const WORKFLOW_TEMPLATES = [
12
44
  yaml: `id: pr-review
13
45
  name: PR Review Bot
14
46
  description: Review pull requests for code quality, security issues, and best practices.
47
+ workflow_type: pr_review
15
48
  entry: fetch-diff
16
49
 
17
50
  nodes:
@@ -58,6 +91,7 @@ edges:
58
91
  yaml: `id: issue-triage
59
92
  name: Issue Triage
60
93
  description: Automatically classify, prioritize, and label new issues.
94
+ workflow_type: generic
61
95
  entry: classify
62
96
 
63
97
  nodes:
@@ -97,6 +131,7 @@ edges:
97
131
  yaml: `id: security-scan
98
132
  name: Security Audit
99
133
  description: Scan repository code and dependencies for security vulnerabilities.
134
+ workflow_type: generic
100
135
  entry: scan-code
101
136
 
102
137
  nodes:
@@ -140,6 +175,7 @@ edges:
140
175
  yaml: `id: release-notes
141
176
  name: Release Notes Generator
142
177
  description: Generate structured release notes from recent commits and merged PRs.
178
+ workflow_type: generic
143
179
  entry: gather
144
180
 
145
181
  nodes:
@@ -176,6 +212,557 @@ edges:
176
212
  to: categorize
177
213
  - from: categorize
178
214
  to: write-notes
215
+ `,
216
+ },
217
+ {
218
+ id: "content-pipeline",
219
+ name: "Content Generation Pipeline",
220
+ description: "Plan, generate, and validate a batch of content, then hand it off for publishing",
221
+ yaml: `id: content-pipeline
222
+ name: Content Generation Pipeline
223
+ description: Plan a content batch, generate it, validate quality, and hand off for publishing.
224
+ workflow_type: content_generation
225
+ entry: plan
226
+
227
+ nodes:
228
+ plan:
229
+ name: Plan Content
230
+ instruction: |
231
+ Decide what content to generate this run. If the input specifies a
232
+ topic, format, or count, honor it directly. Otherwise propose a
233
+ sensible small batch (2-3 pieces) covering distinct, useful topics.
234
+
235
+ Return a plan: for each item, the topic, the target format (e.g.
236
+ article, social post, FAQ entry), and a one-line reason it's worth
237
+ generating.
238
+ output:
239
+ type: object
240
+ properties:
241
+ plan:
242
+ type: array
243
+ items:
244
+ type: object
245
+ properties:
246
+ topic:
247
+ type: string
248
+ format:
249
+ type: string
250
+ reason:
251
+ type: string
252
+ required:
253
+ - topic
254
+ - format
255
+ required:
256
+ - plan
257
+
258
+ generate:
259
+ name: Generate Content
260
+ instruction: |
261
+ For each item in the plan from the previous step, write the content
262
+ directly. Match the requested format, keep facts accurate, and make
263
+ it genuinely useful, no filler.
264
+ output:
265
+ type: object
266
+ properties:
267
+ generated:
268
+ type: array
269
+ items:
270
+ type: object
271
+ properties:
272
+ topic:
273
+ type: string
274
+ format:
275
+ type: string
276
+ content:
277
+ type: string
278
+ required:
279
+ - topic
280
+ - content
281
+ required:
282
+ - generated
283
+
284
+ validate:
285
+ name: Validate Quality
286
+ instruction: |
287
+ Review each generated piece from the previous step. Flag anything
288
+ that's off-topic, factually wrong, too thin, or otherwise not
289
+ publish-ready. Everything else is approved.
290
+ output:
291
+ type: object
292
+ properties:
293
+ approved:
294
+ type: array
295
+ items:
296
+ type: string
297
+ flagged:
298
+ type: array
299
+ items:
300
+ type: object
301
+ properties:
302
+ topic:
303
+ type: string
304
+ issue:
305
+ type: string
306
+ required:
307
+ - topic
308
+ - issue
309
+ required:
310
+ - approved
311
+
312
+ publish:
313
+ name: Hand Off for Publishing
314
+ instruction: |
315
+ Compile the approved content into a publish-ready summary. Call out
316
+ anything flagged for manual review before it goes live.
317
+ output:
318
+ type: object
319
+ properties:
320
+ summary:
321
+ type: string
322
+ required:
323
+ - summary
324
+
325
+ edges:
326
+ - from: plan
327
+ to: generate
328
+ - from: generate
329
+ to: validate
330
+ - from: validate
331
+ to: publish
332
+ `,
333
+ },
334
+ {
335
+ id: "url-monitor",
336
+ name: "URL Change Monitor",
337
+ description: "Watch a set of URLs for content or status changes and alert when something changes",
338
+ yaml: `id: url-monitor
339
+ name: URL Change Monitor
340
+ description: Watch a set of URLs for content or status changes and alert when something changes.
341
+ workflow_type: monitor
342
+ entry: check-sources
343
+
344
+ nodes:
345
+ check-sources:
346
+ name: Fetch Monitored URLs
347
+ instruction: |
348
+ The current content of each monitored URL is provided above as
349
+ context. For each URL, produce a short fingerprint: a handful of key
350
+ facts or values that would change if the page's meaningful content
351
+ changed (ignore timestamps, ads, and other noise).
352
+
353
+ Edit the context sources below to point at the URLs you actually want
354
+ to monitor.
355
+ context:
356
+ - url: https://example.com/status
357
+ - url: https://example.com/changelog
358
+ output:
359
+ type: object
360
+ properties:
361
+ snapshot:
362
+ type: array
363
+ items:
364
+ type: object
365
+ properties:
366
+ url:
367
+ type: string
368
+ fingerprint:
369
+ type: string
370
+ notes:
371
+ type: string
372
+ required:
373
+ - url
374
+ - fingerprint
375
+ required:
376
+ - snapshot
377
+
378
+ compare-baseline:
379
+ name: Compare Against Last Known State
380
+ instruction: |
381
+ Read the last known snapshot from .sweny/monitor-baseline.json if it
382
+ exists. Compare it against the current snapshot from the previous
383
+ step. If no baseline file exists yet, this is the first run: treat
384
+ everything as unchanged and just record the baseline.
385
+
386
+ Write the current snapshot back to .sweny/monitor-baseline.json so
387
+ the next run has something to compare against. Report which URLs
388
+ changed, if any.
389
+ output:
390
+ type: object
391
+ properties:
392
+ changed:
393
+ type: array
394
+ items:
395
+ type: string
396
+ firstRun:
397
+ type: boolean
398
+ summary:
399
+ type: string
400
+ required:
401
+ - changed
402
+ - summary
403
+
404
+ alert-on-change:
405
+ name: Alert on Change
406
+ instruction: |
407
+ If the previous step found any changed URLs, send a notification
408
+ summarizing exactly what changed and why it matters. If nothing
409
+ changed (and it wasn't the first run), skip the notification and
410
+ just report that no alert was needed.
411
+ skills:
412
+ - notification
413
+
414
+ edges:
415
+ - from: check-sources
416
+ to: compare-baseline
417
+ - from: compare-baseline
418
+ to: alert-on-change
419
+ `,
420
+ },
421
+ {
422
+ id: "data-sync",
423
+ name: "Data Sync Pipeline",
424
+ description: "Sync structured records from a source to a target, judged for mapping fidelity",
425
+ yaml: `id: data-sync
426
+ name: Data Sync Pipeline
427
+ description: Sync structured records from a source to a target, with a judge checking every mapping for fidelity.
428
+ workflow_type: data_sync
429
+ entry: fetch-records
430
+
431
+ nodes:
432
+ fetch-records:
433
+ name: Fetch Source Records
434
+ instruction: |
435
+ Fetch the source records to sync (from a URL, API, or file referenced
436
+ in your context or input). Normalize them into a structured JSON
437
+ array with clear, consistent field names.
438
+ output:
439
+ type: object
440
+ properties:
441
+ records:
442
+ type: array
443
+ items:
444
+ type: object
445
+ sourceCount:
446
+ type: number
447
+ required:
448
+ - records
449
+ - sourceCount
450
+
451
+ transform-records:
452
+ name: Transform Records
453
+ instruction: |
454
+ Map each source record from the previous step onto the target
455
+ schema. For any record that can't be cleanly mapped, leave it out of
456
+ "mapped" and log it in "unmapped" with a specific reason.
457
+ output:
458
+ type: object
459
+ properties:
460
+ mapped:
461
+ type: array
462
+ items:
463
+ type: object
464
+ unmapped:
465
+ type: array
466
+ items:
467
+ type: object
468
+ properties:
469
+ record: {}
470
+ reason:
471
+ type: string
472
+ required:
473
+ - reason
474
+ required:
475
+ - mapped
476
+ eval:
477
+ - name: mapping_is_faithful
478
+ kind: judge
479
+ rubric: |
480
+ Read result.data.mapped and result.data.unmapped, and compare
481
+ them against the source records produced by the fetch-records
482
+ step.
483
+
484
+ PASS only if every mapped record preserves the source record's
485
+ key identifying fields (no dropped IDs, no fabricated values),
486
+ and every unmapped record has a specific, genuine reason logged.
487
+
488
+ FAIL if any record was silently dropped, any value was invented,
489
+ or an "unmapped" reason is vague or missing.
490
+
491
+ Respond with a single token: yes or no.
492
+ pass_when: "yes"
493
+
494
+ sync-target:
495
+ name: Write to Target
496
+ instruction: |
497
+ Write the mapped records from the previous step to the sync target.
498
+ Report how many records were written, skipped, or failed, and why.
499
+ output:
500
+ type: object
501
+ properties:
502
+ written:
503
+ type: number
504
+ skipped:
505
+ type: number
506
+ summary:
507
+ type: string
508
+ required:
509
+ - written
510
+ - summary
511
+
512
+ edges:
513
+ - from: fetch-records
514
+ to: transform-records
515
+ - from: transform-records
516
+ to: sync-target
517
+ `,
518
+ },
519
+ {
520
+ id: "seed-content",
521
+ name: "Content Seeder (Supabase)",
522
+ description: "Audit content gaps, generate content, validate quality, and publish straight to Supabase",
523
+ yaml: `id: seed-content
524
+ name: Content Generation Pipeline
525
+ workflow_type: content_generation
526
+ description: Audit content gaps, generate educational content, validate quality, and publish to Supabase
527
+ entry: audit
528
+ nodes:
529
+ audit:
530
+ name: Audit Content Gaps
531
+ instruction: |-
532
+ You are auditing an educational platform's content library.
533
+
534
+ Use supabase_count to check how many items exist for each combination of:
535
+ - Content types: worksheets, games, lessons
536
+ - Subjects: math, science, english, history, geography, economics, music, art, life-skills, foreign-language
537
+ - Difficulties: beginner, easy, medium, hard
538
+
539
+ Also check the input parameters — if the user specified a subject, topic, difficulty, and count,
540
+ skip the full audit and just report what they want generated.
541
+
542
+ Return a structured content plan: what to generate, how many, at what difficulty and grade level.
543
+ Prioritize gaps where a subject has ZERO content of a given type.
544
+ skills:
545
+ - supabase
546
+ output:
547
+ type: object
548
+ properties:
549
+ plan:
550
+ type: array
551
+ items:
552
+ type: object
553
+ properties:
554
+ contentType:
555
+ type: string
556
+ subject:
557
+ type: string
558
+ topic:
559
+ type: string
560
+ difficulty:
561
+ type: string
562
+ gradeLevel:
563
+ type: string
564
+ count:
565
+ type: number
566
+ reason:
567
+ type: string
568
+ required:
569
+ - contentType
570
+ - subject
571
+ - topic
572
+ - difficulty
573
+ - count
574
+ summary:
575
+ type: string
576
+ required:
577
+ - plan
578
+ - summary
579
+ generate:
580
+ name: Generate Content
581
+ instruction: >-
582
+ You are an expert educator creating content for children ages 5-14.
583
+
584
+
585
+ For each item in the content plan from the previous step, generate the content directly.
586
+
587
+ The content must be high-quality, engaging, age-appropriate, and educationally sound.
588
+
589
+
590
+ **For worksheets:**
591
+
592
+ Generate a JSON array of problems. Each problem needs: "problem", "answer", "format" (answer-line |
593
+ multiple-choice | write-on).
594
+
595
+ Requirements:
596
+
597
+ - Every answer MUST be correct. Double-check math, facts, spelling.
598
+
599
+ - Problems must progress in difficulty within the set.
600
+
601
+ - Use at least 2 different problem structures (e.g., equations + word problems for math).
602
+
603
+ - Vary phrasing — no two problems should feel copy-pasted.
604
+
605
+ - For the target grade level, use appropriate vocabulary and complexity.
606
+
607
+
608
+ **For lessons:**
609
+
610
+ Generate complete HTML + CSS + JS for an interactive lesson.
611
+
612
+ Requirements:
613
+
614
+ - Must have substantial educational content (not just a shell with navigation).
615
+
616
+ - Include interactive elements: quizzes, click-to-reveal, drag-and-drop.
617
+
618
+ - Must be visually engaging with colors, icons, and clear typography.
619
+
620
+ - Include practice exercises with immediate feedback.
621
+
622
+ - Minimum 5 teaching sections plus 2 practice activities.
623
+
624
+
625
+ **For games:**
626
+
627
+ Generate a description and educational requirements only (actual game code is generated
628
+
629
+ by the platform's Phaser-based generator).
630
+
631
+
632
+ Use supabase_insert to write each piece of content to the appropriate table.
633
+
634
+
635
+ Table schemas:
636
+
637
+ - worksheets: id (auto), title, subject, topic, difficulty, grade_level, num_questions, problems (jsonb),
638
+ status='published', source='ai-seed'
639
+
640
+ - lessons: id (auto), title, subject, difficulty, grade_level, lesson_type, html_code, css_code, js_code,
641
+ status='published', source='ai-seed'
642
+
643
+ - games: id (auto), title, subject, difficulty, grade_level, game_type, html_code, css_code, js_code,
644
+ status='published', source='ai-seed'
645
+
646
+
647
+ Return a summary of what was generated and inserted.
648
+ skills:
649
+ - supabase
650
+ output:
651
+ type: object
652
+ properties:
653
+ generated:
654
+ type: array
655
+ items:
656
+ type: object
657
+ properties:
658
+ contentType:
659
+ type: string
660
+ title:
661
+ type: string
662
+ subject:
663
+ type: string
664
+ id:
665
+ type: string
666
+ status:
667
+ type: string
668
+ totalGenerated:
669
+ type: number
670
+ errors:
671
+ type: array
672
+ items:
673
+ type: string
674
+ required:
675
+ - generated
676
+ - totalGenerated
677
+ validate:
678
+ name: Validate Content Quality
679
+ instruction: |-
680
+ Review the content that was just generated and inserted.
681
+
682
+ For each item, use supabase_query to fetch it back and verify:
683
+
684
+ **Worksheets:**
685
+ - Parse the problems JSON — are all answers correct?
686
+ - Are problems diverse (not repetitive)?
687
+ - Is difficulty appropriate for the stated grade level?
688
+ - Are there the right number of questions?
689
+
690
+ **Lessons:**
691
+ - Is the HTML substantial (> 500 characters)?
692
+ - Does it contain actual educational content (not just navigation shells)?
693
+ - Are there interactive elements?
694
+
695
+ **Games:**
696
+ - Does the HTML contain a working game structure?
697
+
698
+ Flag any issues. If critical issues are found (wrong answers, empty content),
699
+ use supabase_update to set status='draft' and add a note.
700
+
701
+ Return a quality report.
702
+ skills:
703
+ - supabase
704
+ output:
705
+ type: object
706
+ properties:
707
+ totalReviewed:
708
+ type: number
709
+ passed:
710
+ type: number
711
+ flagged:
712
+ type: number
713
+ issues:
714
+ type: array
715
+ items:
716
+ type: object
717
+ properties:
718
+ id:
719
+ type: string
720
+ title:
721
+ type: string
722
+ issue:
723
+ type: string
724
+ severity:
725
+ type: string
726
+ action:
727
+ type: string
728
+ summary:
729
+ type: string
730
+ required:
731
+ - totalReviewed
732
+ - passed
733
+ - flagged
734
+ - summary
735
+ report:
736
+ name: Generate Report
737
+ instruction: |-
738
+ Compile a final report of the content generation run.
739
+
740
+ Include:
741
+ - Total content generated by type and subject
742
+ - Quality validation results
743
+ - Any issues found and actions taken
744
+ - Recommendations for next content generation run (what gaps remain)
745
+
746
+ Format as a clean markdown summary that a solo operator can scan in 30 seconds.
747
+ skills: []
748
+ output:
749
+ type: object
750
+ properties:
751
+ markdown:
752
+ type: string
753
+ nextPriorities:
754
+ type: array
755
+ items:
756
+ type: string
757
+ required:
758
+ - markdown
759
+ edges:
760
+ - from: audit
761
+ to: generate
762
+ - from: generate
763
+ to: validate
764
+ - from: validate
765
+ to: report
179
766
  `,
180
767
  },
181
768
  ];
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Small, side-effect-free helpers for building the `workflowInput` bag that
3
+ * `sweny workflow run` hands to `execute()`.
4
+ *
5
+ * Deliberately NOT in main.ts: main.ts ends with a top-level
6
+ * `await program.parseAsync()` (see bottom of file), so importing it at all
7
+ * triggers full CLI argv parsing as a side effect. That makes main.ts unsafe
8
+ * to `import` from a test. Anything worth unit-testing in isolation lives
9
+ * here instead (same pattern as config.ts / credentials.ts / e2e.ts).
10
+ */
11
+ /**
12
+ * Merge the CLI-level `--dry-run` flag into a `--input`-validated workflow
13
+ * input bag.
14
+ *
15
+ * #324: `sweny workflow run <file> --dry-run --input '{...}'` (what the
16
+ * GitHub Action and MCP server both pass) silently dropped `dryRun` before
17
+ * this fix: the `--input` branch built `workflowInput` from the caller's
18
+ * JSON alone, and only the config-derived (no-`--input`) branch merged in
19
+ * `config.dryRun`. The executor's fail-closed dry-run gate (see
20
+ * `advanceFromNode` in executor.ts) reads `input.dryRun` directly, so a
21
+ * dropped flag meant the full workflow, side effects included, ran anyway.
22
+ *
23
+ * Only forces `dryRun` *on*: when `--dry-run` is set it always wins, but a
24
+ * caller-supplied `dryRun: true` already present in the `--input` JSON must
25
+ * never be downgraded just because `--dry-run` was omitted.
26
+ */
27
+ export declare function mergeDryRunIntoInput(validatedInput: Record<string, unknown>, cliDryRun: boolean): Record<string, unknown>;
28
+ /**
29
+ * Parse `--timeout` / `--max-steps` for `sweny workflow run`. Throws a clear
30
+ * error on non-numeric or out-of-range values instead of silently falling
31
+ * back to a default (which hid typos like `--timeout 15m`).
32
+ *
33
+ * - `--timeout <ms>`: whole-run wall-clock budget in ms. `0` means no
34
+ * wall-clock budget (returned as `0`). Absent returns `defaultTimeoutMs`.
35
+ * - `--max-steps <n>`: positive integer. Absent returns `undefined` (the
36
+ * executor's own default applies).
37
+ */
38
+ export declare function parseRunBudgetFlags(timeout: string | undefined, maxSteps: string | undefined, defaultTimeoutMs: number): {
39
+ timeoutMs: number;
40
+ maxSteps: number | undefined;
41
+ };