stagent 0.1.10 → 0.1.12

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 (112) hide show
  1. package/README.md +58 -27
  2. package/package.json +3 -3
  3. package/src/__tests__/e2e/blueprint.test.ts +63 -0
  4. package/src/__tests__/e2e/cross-runtime.test.ts +77 -0
  5. package/src/__tests__/e2e/helpers.ts +286 -0
  6. package/src/__tests__/e2e/parallel-workflow.test.ts +120 -0
  7. package/src/__tests__/e2e/sequence-workflow.test.ts +109 -0
  8. package/src/__tests__/e2e/setup.ts +156 -0
  9. package/src/__tests__/e2e/single-task.test.ts +170 -0
  10. package/src/app/api/command-palette/recent/route.ts +41 -18
  11. package/src/app/api/context/batch/route.ts +44 -0
  12. package/src/app/api/permissions/presets/route.ts +80 -0
  13. package/src/app/api/playbook/status/route.ts +15 -0
  14. package/src/app/api/profiles/route.ts +23 -21
  15. package/src/app/api/settings/pricing/route.ts +15 -0
  16. package/src/app/costs/page.tsx +53 -43
  17. package/src/app/globals.css +0 -5
  18. package/src/app/playbook/[slug]/page.tsx +76 -0
  19. package/src/app/playbook/page.tsx +54 -0
  20. package/src/app/profiles/page.tsx +7 -4
  21. package/src/app/settings/page.tsx +2 -2
  22. package/src/app/tasks/page.tsx +5 -0
  23. package/src/components/costs/cost-dashboard.tsx +226 -320
  24. package/src/components/dashboard/activity-feed.tsx +6 -2
  25. package/src/components/notifications/batch-proposal-review.tsx +150 -0
  26. package/src/components/notifications/notification-item.tsx +6 -3
  27. package/src/components/notifications/pending-approval-host.tsx +57 -11
  28. package/src/components/playbook/adoption-heatmap.tsx +69 -0
  29. package/src/components/playbook/journey-card.tsx +110 -0
  30. package/src/components/playbook/playbook-action-button.tsx +22 -0
  31. package/src/components/playbook/playbook-browser.tsx +143 -0
  32. package/src/components/playbook/playbook-card.tsx +102 -0
  33. package/src/components/playbook/playbook-detail-view.tsx +223 -0
  34. package/src/components/playbook/playbook-homepage.tsx +142 -0
  35. package/src/components/playbook/playbook-toc.tsx +90 -0
  36. package/src/components/playbook/playbook-updated-badge.tsx +23 -0
  37. package/src/components/playbook/related-docs.tsx +30 -0
  38. package/src/components/profiles/__tests__/learned-context-panel.test.tsx +175 -0
  39. package/src/components/profiles/context-proposal-review.tsx +7 -3
  40. package/src/components/profiles/learned-context-panel.tsx +116 -8
  41. package/src/components/profiles/profile-detail-view.tsx +7 -19
  42. package/src/components/profiles/profile-form-view.tsx +0 -22
  43. package/src/components/settings/__tests__/auth-config-section.test.tsx +147 -0
  44. package/src/components/settings/api-key-form.tsx +5 -43
  45. package/src/components/settings/auth-config-section.tsx +10 -6
  46. package/src/components/settings/auth-status-badge.tsx +8 -0
  47. package/src/components/settings/budget-guardrails-section.tsx +403 -620
  48. package/src/components/settings/connection-test-control.tsx +63 -0
  49. package/src/components/settings/permissions-section.tsx +85 -75
  50. package/src/components/settings/permissions-sections.tsx +24 -0
  51. package/src/components/settings/presets-section.tsx +159 -0
  52. package/src/components/settings/pricing-registry-panel.tsx +164 -0
  53. package/src/components/shared/app-sidebar.tsx +2 -0
  54. package/src/components/shared/command-palette.tsx +30 -0
  55. package/src/components/shared/light-markdown.tsx +134 -0
  56. package/src/components/workflows/loop-status-view.tsx +8 -4
  57. package/src/components/workflows/workflow-status-view.tsx +16 -9
  58. package/src/lib/agents/__tests__/claude-agent.test.ts +7 -2
  59. package/src/lib/agents/__tests__/learned-context.test.ts +500 -0
  60. package/src/lib/agents/__tests__/pattern-extractor.test.ts +243 -0
  61. package/src/lib/agents/__tests__/sweep.test.ts +202 -0
  62. package/src/lib/agents/claude-agent.ts +104 -78
  63. package/src/lib/agents/learned-context.ts +32 -28
  64. package/src/lib/agents/learning-session.ts +234 -0
  65. package/src/lib/agents/pattern-extractor.ts +34 -64
  66. package/src/lib/agents/profiles/__tests__/sort.test.ts +42 -0
  67. package/src/lib/agents/profiles/builtins/code-reviewer/profile.yaml +0 -1
  68. package/src/lib/agents/profiles/builtins/data-analyst/profile.yaml +0 -1
  69. package/src/lib/agents/profiles/builtins/devops-engineer/profile.yaml +0 -1
  70. package/src/lib/agents/profiles/builtins/document-writer/profile.yaml +0 -1
  71. package/src/lib/agents/profiles/builtins/general/profile.yaml +0 -1
  72. package/src/lib/agents/profiles/builtins/health-fitness-coach/profile.yaml +0 -1
  73. package/src/lib/agents/profiles/builtins/learning-coach/profile.yaml +0 -1
  74. package/src/lib/agents/profiles/builtins/project-manager/profile.yaml +0 -1
  75. package/src/lib/agents/profiles/builtins/researcher/profile.yaml +0 -1
  76. package/src/lib/agents/profiles/builtins/shopping-assistant/profile.yaml +0 -1
  77. package/src/lib/agents/profiles/builtins/sweep/profile.yaml +0 -1
  78. package/src/lib/agents/profiles/builtins/technical-writer/profile.yaml +0 -1
  79. package/src/lib/agents/profiles/builtins/travel-planner/profile.yaml +0 -1
  80. package/src/lib/agents/profiles/builtins/wealth-manager/profile.yaml +0 -1
  81. package/src/lib/agents/profiles/registry.ts +0 -1
  82. package/src/lib/agents/profiles/sort.ts +7 -0
  83. package/src/lib/agents/profiles/types.ts +0 -1
  84. package/src/lib/agents/runtime/catalog.ts +1 -1
  85. package/src/lib/agents/runtime/claude.ts +66 -0
  86. package/src/lib/constants/settings.ts +1 -0
  87. package/src/lib/constants/task-status.ts +6 -0
  88. package/src/lib/data/seed-data/profiles.ts +0 -3
  89. package/src/lib/db/schema.ts +3 -0
  90. package/src/lib/docs/adoption.ts +105 -0
  91. package/src/lib/docs/journey-tracker.ts +21 -0
  92. package/src/lib/docs/reader.ts +102 -0
  93. package/src/lib/docs/types.ts +54 -0
  94. package/src/lib/docs/usage-stage.ts +60 -0
  95. package/src/lib/notifications/actionable.ts +18 -10
  96. package/src/lib/settings/__tests__/budget-guardrails.test.ts +86 -24
  97. package/src/lib/settings/budget-guardrails.ts +213 -85
  98. package/src/lib/settings/permission-presets.ts +150 -0
  99. package/src/lib/settings/runtime-setup.ts +71 -0
  100. package/src/lib/usage/__tests__/ledger.test.ts +29 -5
  101. package/src/lib/usage/__tests__/pricing-registry.test.ts +78 -0
  102. package/src/lib/usage/ledger.ts +4 -2
  103. package/src/lib/usage/pricing-registry.ts +570 -0
  104. package/src/lib/usage/pricing.ts +15 -41
  105. package/src/lib/utils/__tests__/learned-context-history.test.ts +171 -0
  106. package/src/lib/utils/learned-context-history.ts +150 -0
  107. package/src/lib/validators/__tests__/profile.test.ts +0 -15
  108. package/src/lib/validators/__tests__/settings.test.ts +23 -16
  109. package/src/lib/validators/profile.ts +0 -1
  110. package/src/lib/validators/settings.ts +3 -9
  111. package/src/lib/workflows/__tests__/engine.test.ts +2 -0
  112. package/src/lib/workflows/engine.ts +20 -1
@@ -0,0 +1,76 @@
1
+ import { notFound } from "next/navigation";
2
+ import { getDocBySlug, getManifest } from "@/lib/docs/reader";
3
+ import { getAdoptionMap } from "@/lib/docs/adoption";
4
+ import { PlaybookDetailView } from "@/components/playbook/playbook-detail-view";
5
+
6
+ export const dynamic = "force-dynamic";
7
+
8
+ interface PlaybookDetailProps {
9
+ params: Promise<{ slug: string }>;
10
+ }
11
+
12
+ export async function generateMetadata({ params }: PlaybookDetailProps) {
13
+ const { slug } = await params;
14
+ const doc = getDocBySlug(slug);
15
+ return {
16
+ title: doc
17
+ ? `${(doc.frontmatter.title as string) || slug} | Playbook | Stagent`
18
+ : "Not Found | Playbook",
19
+ };
20
+ }
21
+
22
+ export default async function PlaybookDetailPage({
23
+ params,
24
+ }: PlaybookDetailProps) {
25
+ const { slug } = await params;
26
+ const [doc, manifest, adoptionMap] = await Promise.all([
27
+ getDocBySlug(slug),
28
+ getManifest(),
29
+ getAdoptionMap(),
30
+ ]);
31
+
32
+ if (!doc) notFound();
33
+
34
+ // Find related sections from manifest
35
+ const allSections = [...manifest.sections, ...manifest.journeys];
36
+ const currentSection = allSections.find((s) => s.slug === slug);
37
+
38
+ // Find related docs by shared tags
39
+ const currentTags = new Set(
40
+ (currentSection && "tags" in currentSection
41
+ ? (currentSection as { tags: string[] }).tags
42
+ : (doc.frontmatter.tags as string[]) || []
43
+ ).map((t) => t.toLowerCase())
44
+ );
45
+
46
+ const relatedSections = manifest.sections
47
+ .filter(
48
+ (s) =>
49
+ s.slug !== slug &&
50
+ s.tags.some((t) => currentTags.has(t.toLowerCase()))
51
+ )
52
+ .slice(0, 4);
53
+
54
+ const adoption = Object.fromEntries(adoptionMap);
55
+
56
+ // Collect all known doc slugs so markdown links resolve correctly
57
+ const allSlugs = [
58
+ ...manifest.sections.map((s) => s.slug),
59
+ ...manifest.journeys.map((j) => j.slug),
60
+ "getting-started",
61
+ "index",
62
+ ];
63
+
64
+ return (
65
+ <div className="gradient-twilight min-h-[100dvh] p-4 sm:p-6">
66
+ <div className="surface-page rounded-[28px] border border-border/60 p-6 shadow-[0_18px_48px_oklch(0.12_0.02_260_/_0.08)]">
67
+ <PlaybookDetailView
68
+ doc={doc}
69
+ relatedSections={relatedSections}
70
+ adoption={adoption}
71
+ allSlugs={allSlugs}
72
+ />
73
+ </div>
74
+ </div>
75
+ );
76
+ }
@@ -0,0 +1,54 @@
1
+ import { getManifest, getDocsLastGenerated } from "@/lib/docs/reader";
2
+ import { getUsageStage } from "@/lib/docs/usage-stage";
3
+ import { getAdoptionMap } from "@/lib/docs/adoption";
4
+ import { getJourneyCompletions } from "@/lib/docs/journey-tracker";
5
+ import { getSetting, setSetting } from "@/lib/settings/helpers";
6
+ import { PlaybookHomepage } from "@/components/playbook/playbook-homepage";
7
+
8
+ export const dynamic = "force-dynamic";
9
+
10
+ export const metadata = {
11
+ title: "Playbook | Stagent",
12
+ };
13
+
14
+ export default async function PlaybookPage() {
15
+ const [manifest, stage, adoptionMap, lastGenerated, lastVisit] =
16
+ await Promise.all([
17
+ getManifest(),
18
+ getUsageStage(),
19
+ getAdoptionMap(),
20
+ getDocsLastGenerated(),
21
+ getSetting("lastPlaybookVisit"),
22
+ ]);
23
+
24
+ const journeyCompletions = getJourneyCompletions(
25
+ manifest.journeys,
26
+ adoptionMap
27
+ );
28
+
29
+ // Update last visit timestamp
30
+ await setSetting("lastPlaybookVisit", new Date().toISOString());
31
+
32
+ // Serialize maps for client component
33
+ const adoption = Object.fromEntries(adoptionMap);
34
+ const completions = Object.fromEntries(journeyCompletions);
35
+
36
+ const hasUpdates =
37
+ lastGenerated != null &&
38
+ lastVisit != null &&
39
+ new Date(lastGenerated) > new Date(lastVisit);
40
+
41
+ return (
42
+ <div className="gradient-twilight min-h-[100dvh] p-4 sm:p-6">
43
+ <div className="surface-page rounded-[28px] border border-border/60 p-6 shadow-[0_18px_48px_oklch(0.12_0.02_260_/_0.08)]">
44
+ <PlaybookHomepage
45
+ manifest={manifest}
46
+ stage={stage}
47
+ adoption={adoption}
48
+ journeyCompletions={completions}
49
+ hasUpdates={hasUpdates}
50
+ />
51
+ </div>
52
+ </div>
53
+ );
54
+ }
@@ -1,13 +1,16 @@
1
1
  import { listProfiles, isBuiltin } from "@/lib/agents/profiles/registry";
2
+ import { sortProfilesByName } from "@/lib/agents/profiles/sort";
2
3
  import { ProfileBrowser } from "@/components/profiles/profile-browser";
3
4
 
4
5
  export const dynamic = "force-dynamic";
5
6
 
6
7
  export default async function ProfilesPage() {
7
- const profiles = listProfiles().map((p) => ({
8
- ...p,
9
- isBuiltin: isBuiltin(p.id),
10
- }));
8
+ const profiles = sortProfilesByName(
9
+ listProfiles().map((p) => ({
10
+ ...p,
11
+ isBuiltin: isBuiltin(p.id),
12
+ }))
13
+ );
11
14
 
12
15
  return (
13
16
  <div className="gradient-ocean-mist min-h-[100dvh] p-4 sm:p-6">
@@ -1,6 +1,6 @@
1
1
  import { AuthConfigSection } from "@/components/settings/auth-config-section";
2
2
  import { OpenAIRuntimeSection } from "@/components/settings/openai-runtime-section";
3
- import { PermissionsSection } from "@/components/settings/permissions-section";
3
+ import { PermissionsSections } from "@/components/settings/permissions-sections";
4
4
  import { DataManagementSection } from "@/components/settings/data-management-section";
5
5
  import { BudgetGuardrailsSection } from "@/components/settings/budget-guardrails-section";
6
6
 
@@ -19,7 +19,7 @@ export default function SettingsPage() {
19
19
  <AuthConfigSection />
20
20
  <OpenAIRuntimeSection />
21
21
  <BudgetGuardrailsSection />
22
- <PermissionsSection />
22
+ <PermissionsSections />
23
23
  <DataManagementSection />
24
24
  </div>
25
25
  </div>
@@ -0,0 +1,5 @@
1
+ import { redirect } from "next/navigation";
2
+
3
+ export default function TasksIndexPage() {
4
+ redirect("/dashboard");
5
+ }