jfl 0.3.0 → 0.4.2

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 (97) hide show
  1. package/README.md +294 -30
  2. package/dist/commands/context-hub.d.ts.map +1 -1
  3. package/dist/commands/context-hub.js +154 -0
  4. package/dist/commands/context-hub.js.map +1 -1
  5. package/dist/commands/flows.d.ts +4 -1
  6. package/dist/commands/flows.d.ts.map +1 -1
  7. package/dist/commands/flows.js +160 -1
  8. package/dist/commands/flows.js.map +1 -1
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +42 -0
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/peter.d.ts.map +1 -1
  13. package/dist/commands/peter.js +220 -1
  14. package/dist/commands/peter.js.map +1 -1
  15. package/dist/commands/pi.d.ts +21 -0
  16. package/dist/commands/pi.d.ts.map +1 -0
  17. package/dist/commands/pi.js +154 -0
  18. package/dist/commands/pi.js.map +1 -0
  19. package/dist/commands/portfolio.d.ts.map +1 -1
  20. package/dist/commands/portfolio.js +22 -69
  21. package/dist/commands/portfolio.js.map +1 -1
  22. package/dist/commands/predict.d.ts +6 -0
  23. package/dist/commands/predict.d.ts.map +1 -0
  24. package/dist/commands/predict.js +234 -0
  25. package/dist/commands/predict.js.map +1 -0
  26. package/dist/commands/synopsis.d.ts +44 -0
  27. package/dist/commands/synopsis.d.ts.map +1 -1
  28. package/dist/commands/synopsis.js +1 -1
  29. package/dist/commands/synopsis.js.map +1 -1
  30. package/dist/commands/update.d.ts.map +1 -1
  31. package/dist/commands/update.js +49 -1
  32. package/dist/commands/update.js.map +1 -1
  33. package/dist/commands/viz.d.ts +7 -0
  34. package/dist/commands/viz.d.ts.map +1 -0
  35. package/dist/commands/viz.js +460 -0
  36. package/dist/commands/viz.js.map +1 -0
  37. package/dist/dashboard/index.d.ts +4 -5
  38. package/dist/dashboard/index.d.ts.map +1 -1
  39. package/dist/dashboard/index.js +57 -146
  40. package/dist/dashboard/index.js.map +1 -1
  41. package/dist/dashboard-static/assets/index-B6kRK9Rq.js +116 -0
  42. package/dist/dashboard-static/assets/index-BpdKJPLu.css +1 -0
  43. package/dist/dashboard-static/index.html +16 -0
  44. package/dist/index.js +112 -19
  45. package/dist/index.js.map +1 -1
  46. package/dist/lib/flow-engine.d.ts +1 -0
  47. package/dist/lib/flow-engine.d.ts.map +1 -1
  48. package/dist/lib/flow-engine.js +30 -1
  49. package/dist/lib/flow-engine.js.map +1 -1
  50. package/dist/lib/hub-client.d.ts +80 -0
  51. package/dist/lib/hub-client.d.ts.map +1 -0
  52. package/dist/lib/hub-client.js +46 -0
  53. package/dist/lib/hub-client.js.map +1 -0
  54. package/dist/lib/predictor.d.ts +99 -0
  55. package/dist/lib/predictor.d.ts.map +1 -0
  56. package/dist/lib/predictor.js +394 -0
  57. package/dist/lib/predictor.js.map +1 -0
  58. package/dist/lib/service-gtm.d.ts +86 -51
  59. package/dist/lib/service-gtm.d.ts.map +1 -1
  60. package/dist/lib/service-gtm.js +417 -242
  61. package/dist/lib/service-gtm.js.map +1 -1
  62. package/dist/lib/telemetry-agent.d.ts +57 -0
  63. package/dist/lib/telemetry-agent.d.ts.map +1 -0
  64. package/dist/lib/telemetry-agent.js +268 -0
  65. package/dist/lib/telemetry-agent.js.map +1 -0
  66. package/dist/lib/telemetry-digest.d.ts.map +1 -1
  67. package/dist/lib/telemetry-digest.js +17 -17
  68. package/dist/lib/telemetry-digest.js.map +1 -1
  69. package/dist/lib/telemetry.d.ts +1 -0
  70. package/dist/lib/telemetry.d.ts.map +1 -1
  71. package/dist/lib/telemetry.js +14 -6
  72. package/dist/lib/telemetry.js.map +1 -1
  73. package/dist/mcp/context-hub-mcp.js +0 -0
  74. package/dist/mcp/service-registry-mcp.js +0 -0
  75. package/dist/types/map.d.ts +1 -1
  76. package/dist/types/map.d.ts.map +1 -1
  77. package/dist/types/map.js.map +1 -1
  78. package/dist/utils/jfl-paths.d.ts +1 -0
  79. package/dist/utils/jfl-paths.d.ts.map +1 -1
  80. package/dist/utils/jfl-paths.js +1 -0
  81. package/dist/utils/jfl-paths.js.map +1 -1
  82. package/package.json +7 -2
  83. package/scripts/generate-changesets.sh +113 -0
  84. package/scripts/pp-branch-pr.sh +115 -0
  85. package/template/.jfl/flows-self-driving.yaml +170 -0
  86. package/dist/dashboard/components.d.ts +0 -7
  87. package/dist/dashboard/components.d.ts.map +0 -1
  88. package/dist/dashboard/components.js +0 -575
  89. package/dist/dashboard/components.js.map +0 -1
  90. package/dist/dashboard/pages.d.ts +0 -7
  91. package/dist/dashboard/pages.d.ts.map +0 -1
  92. package/dist/dashboard/pages.js +0 -1580
  93. package/dist/dashboard/pages.js.map +0 -1
  94. package/dist/dashboard/styles.d.ts +0 -7
  95. package/dist/dashboard/styles.d.ts.map +0 -1
  96. package/dist/dashboard/styles.js +0 -1110
  97. package/dist/dashboard/styles.js.map +0 -1
@@ -1,159 +1,70 @@
1
1
  /**
2
2
  * Context Hub Web Dashboard
3
3
  *
4
- * Serves a Preact+HTM SPA from the existing Context Hub HTTP server.
5
- * Zero build step ships as template strings compiled by normal tsc.
4
+ * Serves pre-built Vite+Preact SPA from dist/dashboard-static/.
5
+ * Static files built at publish time, served by Context Hub at runtime.
6
6
  *
7
- * @purpose HTML generator + route handler for Context Hub web dashboard
7
+ * @purpose Static file server + SPA fallback for Context Hub web dashboard
8
8
  */
9
- import { getDashboardStyles } from "./styles.js";
10
- import { getComponentsJS } from "./components.js";
11
- import { getPagesJS } from "./pages.js";
12
- export function generateDashboardHTML(projectName, port) {
13
- const styles = getDashboardStyles();
14
- const components = getComponentsJS();
15
- const pages = getPagesJS();
16
- return `<!DOCTYPE html>
17
- <html lang="en">
18
- <head>
19
- <meta charset="UTF-8" />
20
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
21
- <title>${escapeHtml(projectName)} - Context Hub</title>
22
- <script src="https://cdn.tailwindcss.com"></script>
23
- <script type="importmap">
24
- {
25
- "imports": {
26
- "preact": "https://esm.sh/preact@10.24.3",
27
- "preact/hooks": "https://esm.sh/preact@10.24.3/hooks",
28
- "htm": "https://esm.sh/htm@3.1.1"
29
- }
30
- }
31
- </script>
32
- <style>${styles}</style>
33
- </head>
34
- <body>
35
- <div id="app"></div>
36
- <script type="module">
37
- import { h, render } from 'preact'
38
- import { useState, useEffect, useRef } from 'preact/hooks'
39
- import htm from 'htm'
40
-
41
- const html = htm.bind(h)
42
-
43
- // Auth: read token from URL, store in localStorage, strip from URL
44
- const urlParams = new URLSearchParams(window.location.search)
45
- const urlToken = urlParams.get('token')
46
- if (urlToken) {
47
- localStorage.setItem('jfl-token', urlToken)
48
- const clean = new URL(window.location)
49
- clean.searchParams.delete('token')
50
- window.history.replaceState({}, '', clean.toString())
51
- }
52
-
53
- function getToken() {
54
- return localStorage.getItem('jfl-token') || ''
55
- }
56
-
57
- async function apiFetch(path, opts = {}) {
58
- const token = getToken()
59
- const headers = {
60
- 'Content-Type': 'application/json',
61
- ...(token ? { 'Authorization': 'Bearer ' + token } : {}),
62
- ...(opts.headers || {})
63
- }
64
- const res = await fetch(path, { ...opts, headers })
65
- if (res.status === 401) {
66
- document.getElementById('app').innerHTML = '<div style="padding: 3rem; text-align: center; color: var(--error);"><h2>Unauthorized</h2><p style="color: var(--muted-foreground); margin-top: 0.5rem;">Token expired or invalid. Run: jfl context-hub dashboard</p></div>'
67
- throw new Error('Unauthorized')
68
- }
69
- return res.json()
70
- }
71
-
72
- // Components
73
- ${components}
74
-
75
- // Pages
76
- ${pages}
77
-
78
- // App
79
- function App() {
80
- const { mode, config, children, loading: modeLoading } = useWorkspaceMode()
81
- const defaultPage = mode === 'portfolio' ? 'portfolio' : mode === 'service' ? 'service' : 'overview'
82
- const [page, setPage] = useState(defaultPage)
83
-
84
- // Update default page when mode loads
85
- useEffect(() => {
86
- if (!modeLoading) {
87
- const dp = mode === 'portfolio' ? 'portfolio' : mode === 'service' ? 'service' : 'overview'
88
- setPage(prev => {
89
- // Only update if still on the initial 'overview' default
90
- if (prev === 'overview' && dp !== 'overview') return dp
91
- return prev
92
- })
93
- }
94
- }, [mode, modeLoading])
95
-
96
- const pageMap = {
97
- overview: OverviewPage,
98
- journal: JournalPage,
99
- agents: AgentsPage,
100
- events: EventsPage,
101
- sessions: SessionsPage,
102
- projects: ProjectsPage,
103
- portfolio: PortfolioOverviewPage,
104
- evals: EvalsPage,
105
- scope: ScopePage,
106
- service: ServiceOverviewPage,
107
- costs: CostsPage,
108
- flows: FlowsPage,
109
- }
110
-
111
- const pageComponent = pageMap[page] || OverviewPage
112
-
113
- if (modeLoading) {
114
- return html\`<div class="loading" style="width: 100%; height: 100vh;">Loading dashboard</div>\`
115
- }
116
-
117
- return html\`
118
- <\${Nav}
119
- currentPage=\${page}
120
- setPage=\${setPage}
121
- projectName="${escapeHtml(projectName)}"
122
- port=\${${port}}
123
- mode=\${mode}
124
- />
125
- <div class="main-content">
126
- <\${pageComponent} mode=\${mode} config=\${config} children=\${children} />
127
- </div>
128
- \`
129
- }
130
-
131
- render(html\`<\${App} />\`, document.getElementById('app'))
132
- </script>
133
- </body>
134
- </html>`;
9
+ import * as fs from "fs";
10
+ import * as path from "path";
11
+ import { fileURLToPath } from "url";
12
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
13
+ const MIME_TYPES = {
14
+ ".html": "text/html; charset=utf-8",
15
+ ".js": "application/javascript; charset=utf-8",
16
+ ".css": "text/css; charset=utf-8",
17
+ ".json": "application/json; charset=utf-8",
18
+ ".svg": "image/svg+xml",
19
+ ".png": "image/png",
20
+ ".ico": "image/x-icon",
21
+ ".woff": "font/woff",
22
+ ".woff2": "font/woff2",
23
+ };
24
+ function getStaticDir() {
25
+ return path.resolve(__dirname, "../dashboard-static");
135
26
  }
136
- function escapeHtml(str) {
137
- return str
138
- .replace(/&/g, "&amp;")
139
- .replace(/</g, "&lt;")
140
- .replace(/>/g, "&gt;")
141
- .replace(/"/g, "&quot;")
142
- .replace(/'/g, "&#39;");
143
- }
144
- export function handleDashboardRoutes(req, res, projectRoot, port) {
27
+ export function handleDashboardRoutes(req, res, _projectRoot, port) {
145
28
  const url = new URL(req.url || "/", `http://localhost:${port}`);
146
29
  if (!url.pathname.startsWith("/dashboard")) {
147
30
  return false;
148
31
  }
149
- // Derive project name from directory
150
- const projectName = projectRoot.split("/").pop() || "Context Hub";
151
- const html = generateDashboardHTML(projectName, port);
152
- res.writeHead(200, {
153
- "Content-Type": "text/html; charset=utf-8",
154
- "Cache-Control": "no-cache",
155
- });
156
- res.end(html);
32
+ const staticDir = getStaticDir();
33
+ if (!fs.existsSync(staticDir)) {
34
+ res.writeHead(500, { "Content-Type": "application/json" });
35
+ res.end(JSON.stringify({ error: "Dashboard not built. Run: cd dashboard && npm run build" }));
36
+ return true;
37
+ }
38
+ const relativePath = url.pathname.replace(/^\/dashboard\/?/, "") || "index.html";
39
+ const filePath = path.join(staticDir, relativePath);
40
+ const normalizedPath = path.normalize(filePath);
41
+ if (!normalizedPath.startsWith(staticDir)) {
42
+ res.writeHead(403, { "Content-Type": "application/json" });
43
+ res.end(JSON.stringify({ error: "Forbidden" }));
44
+ return true;
45
+ }
46
+ if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
47
+ const ext = path.extname(filePath);
48
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
49
+ const isAsset = relativePath.startsWith("assets/");
50
+ res.writeHead(200, {
51
+ "Content-Type": contentType,
52
+ "Cache-Control": isAsset ? "public, max-age=31536000, immutable" : "no-cache",
53
+ });
54
+ fs.createReadStream(filePath).pipe(res);
55
+ return true;
56
+ }
57
+ const indexPath = path.join(staticDir, "index.html");
58
+ if (fs.existsSync(indexPath)) {
59
+ res.writeHead(200, {
60
+ "Content-Type": "text/html; charset=utf-8",
61
+ "Cache-Control": "no-cache",
62
+ });
63
+ fs.createReadStream(indexPath).pipe(res);
64
+ return true;
65
+ }
66
+ res.writeHead(404, { "Content-Type": "application/json" });
67
+ res.end(JSON.stringify({ error: "Dashboard index.html not found" }));
157
68
  return true;
158
69
  }
159
70
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,MAAM,UAAU,qBAAqB,CAAC,WAAmB,EAAE,IAAY;IACrE,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;IACnC,MAAM,UAAU,GAAG,eAAe,EAAE,CAAA;IACpC,MAAM,KAAK,GAAG,UAAU,EAAE,CAAA;IAE1B,OAAO;;;;;WAKE,UAAU,CAAC,WAAW,CAAC;;;;;;;;;;;WAWvB,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAyCX,UAAU;;;MAGV,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBA6Cc,UAAU,CAAC,WAAW,CAAC;oBAC5B,IAAI;;;;;;;;;;;;QAYhB,CAAA;AACR,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,GAAyB,EACzB,GAAwB,EACxB,WAAmB,EACnB,IAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAA;IAE/D,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAA;IACd,CAAC;IAED,qCAAqC;IACrC,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,aAAa,CAAA;IAEjE,MAAM,IAAI,GAAG,qBAAqB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IACrD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;QACjB,cAAc,EAAE,0BAA0B;QAC1C,eAAe,EAAE,UAAU;KAC5B,CAAC,CAAA;IACF,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACb,OAAO,IAAI,CAAA;AACb,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"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"}