jfl 0.2.5 → 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 (133) hide show
  1. package/README.md +308 -28
  2. package/dist/commands/context-hub.d.ts.map +1 -1
  3. package/dist/commands/context-hub.js +428 -27
  4. package/dist/commands/context-hub.js.map +1 -1
  5. package/dist/commands/eval.d.ts +6 -0
  6. package/dist/commands/eval.d.ts.map +1 -0
  7. package/dist/commands/eval.js +236 -0
  8. package/dist/commands/eval.js.map +1 -0
  9. package/dist/commands/flows.d.ts +4 -1
  10. package/dist/commands/flows.d.ts.map +1 -1
  11. package/dist/commands/flows.js +160 -1
  12. package/dist/commands/flows.js.map +1 -1
  13. package/dist/commands/init.d.ts.map +1 -1
  14. package/dist/commands/init.js +272 -145
  15. package/dist/commands/init.js.map +1 -1
  16. package/dist/commands/peter.d.ts.map +1 -1
  17. package/dist/commands/peter.js +220 -1
  18. package/dist/commands/peter.js.map +1 -1
  19. package/dist/commands/pi.d.ts +21 -0
  20. package/dist/commands/pi.d.ts.map +1 -0
  21. package/dist/commands/pi.js +154 -0
  22. package/dist/commands/pi.js.map +1 -0
  23. package/dist/commands/portfolio.d.ts +6 -0
  24. package/dist/commands/portfolio.d.ts.map +1 -0
  25. package/dist/commands/portfolio.js +249 -0
  26. package/dist/commands/portfolio.js.map +1 -0
  27. package/dist/commands/predict.d.ts +6 -0
  28. package/dist/commands/predict.d.ts.map +1 -0
  29. package/dist/commands/predict.js +234 -0
  30. package/dist/commands/predict.js.map +1 -0
  31. package/dist/commands/scope.d.ts +1 -0
  32. package/dist/commands/scope.d.ts.map +1 -1
  33. package/dist/commands/scope.js +189 -2
  34. package/dist/commands/scope.js.map +1 -1
  35. package/dist/commands/synopsis.d.ts +44 -0
  36. package/dist/commands/synopsis.d.ts.map +1 -1
  37. package/dist/commands/synopsis.js +1 -1
  38. package/dist/commands/synopsis.js.map +1 -1
  39. package/dist/commands/update.d.ts.map +1 -1
  40. package/dist/commands/update.js +49 -1
  41. package/dist/commands/update.js.map +1 -1
  42. package/dist/commands/viz.d.ts +7 -0
  43. package/dist/commands/viz.d.ts.map +1 -0
  44. package/dist/commands/viz.js +460 -0
  45. package/dist/commands/viz.js.map +1 -0
  46. package/dist/commands/voice.js.map +1 -1
  47. package/dist/dashboard/index.d.ts +4 -5
  48. package/dist/dashboard/index.d.ts.map +1 -1
  49. package/dist/dashboard/index.js +57 -119
  50. package/dist/dashboard/index.js.map +1 -1
  51. package/dist/dashboard-static/assets/index-B6kRK9Rq.js +116 -0
  52. package/dist/dashboard-static/assets/index-BpdKJPLu.css +1 -0
  53. package/dist/dashboard-static/index.html +16 -0
  54. package/dist/index.js +120 -20
  55. package/dist/index.js.map +1 -1
  56. package/dist/lib/eval-store.d.ts +15 -0
  57. package/dist/lib/eval-store.d.ts.map +1 -0
  58. package/dist/lib/eval-store.js +179 -0
  59. package/dist/lib/eval-store.js.map +1 -0
  60. package/dist/lib/flow-engine.d.ts +13 -0
  61. package/dist/lib/flow-engine.d.ts.map +1 -1
  62. package/dist/lib/flow-engine.js +164 -3
  63. package/dist/lib/flow-engine.js.map +1 -1
  64. package/dist/lib/hub-client.d.ts +80 -0
  65. package/dist/lib/hub-client.d.ts.map +1 -0
  66. package/dist/lib/hub-client.js +46 -0
  67. package/dist/lib/hub-client.js.map +1 -0
  68. package/dist/lib/predictor.d.ts +99 -0
  69. package/dist/lib/predictor.d.ts.map +1 -0
  70. package/dist/lib/predictor.js +394 -0
  71. package/dist/lib/predictor.js.map +1 -0
  72. package/dist/lib/service-gtm.d.ts +88 -44
  73. package/dist/lib/service-gtm.d.ts.map +1 -1
  74. package/dist/lib/service-gtm.js +451 -243
  75. package/dist/lib/service-gtm.js.map +1 -1
  76. package/dist/lib/telemetry-agent.d.ts +57 -0
  77. package/dist/lib/telemetry-agent.d.ts.map +1 -0
  78. package/dist/lib/telemetry-agent.js +268 -0
  79. package/dist/lib/telemetry-agent.js.map +1 -0
  80. package/dist/lib/telemetry-digest.d.ts.map +1 -1
  81. package/dist/lib/telemetry-digest.js +17 -17
  82. package/dist/lib/telemetry-digest.js.map +1 -1
  83. package/dist/lib/telemetry.d.ts +1 -0
  84. package/dist/lib/telemetry.d.ts.map +1 -1
  85. package/dist/lib/telemetry.js +14 -6
  86. package/dist/lib/telemetry.js.map +1 -1
  87. package/dist/lib/trajectory-loader.d.ts +82 -0
  88. package/dist/lib/trajectory-loader.d.ts.map +1 -0
  89. package/dist/lib/trajectory-loader.js +406 -0
  90. package/dist/lib/trajectory-loader.js.map +1 -0
  91. package/dist/mcp/context-hub-mcp.js +60 -0
  92. package/dist/mcp/context-hub-mcp.js.map +1 -1
  93. package/dist/mcp/service-registry-mcp.js +0 -0
  94. package/dist/types/eval.d.ts +18 -0
  95. package/dist/types/eval.d.ts.map +1 -0
  96. package/dist/types/eval.js +5 -0
  97. package/dist/types/eval.js.map +1 -0
  98. package/dist/types/journal.d.ts +133 -0
  99. package/dist/types/journal.d.ts.map +1 -0
  100. package/dist/types/journal.js +59 -0
  101. package/dist/types/journal.js.map +1 -0
  102. package/dist/types/map.d.ts +1 -1
  103. package/dist/types/map.d.ts.map +1 -1
  104. package/dist/types/map.js.map +1 -1
  105. package/dist/ui/service-dashboard.js.map +1 -1
  106. package/dist/utils/jfl-paths.d.ts +1 -0
  107. package/dist/utils/jfl-paths.d.ts.map +1 -1
  108. package/dist/utils/jfl-paths.js +1 -0
  109. package/dist/utils/jfl-paths.js.map +1 -1
  110. package/dist/utils/wallet.js.map +1 -1
  111. package/package.json +7 -2
  112. package/scripts/generate-changesets.sh +113 -0
  113. package/scripts/migrate-to-branch-sessions.sh +201 -0
  114. package/scripts/pp-branch-pr.sh +115 -0
  115. package/scripts/session/session-cleanup.sh +29 -14
  116. package/scripts/session/session-end.sh +0 -10
  117. package/scripts/session/session-init.sh +0 -16
  118. package/scripts/session/session-sync.sh +0 -10
  119. package/template/.jfl/flows-self-driving.yaml +170 -0
  120. package/template/THEORY.md +26 -0
  121. package/template/scripts/session/session-cleanup.sh +28 -10
  122. package/dist/dashboard/components.d.ts +0 -7
  123. package/dist/dashboard/components.d.ts.map +0 -1
  124. package/dist/dashboard/components.js +0 -163
  125. package/dist/dashboard/components.js.map +0 -1
  126. package/dist/dashboard/pages.d.ts +0 -7
  127. package/dist/dashboard/pages.d.ts.map +0 -1
  128. package/dist/dashboard/pages.js +0 -742
  129. package/dist/dashboard/pages.js.map +0 -1
  130. package/dist/dashboard/styles.d.ts +0 -7
  131. package/dist/dashboard/styles.d.ts.map +0 -1
  132. package/dist/dashboard/styles.js +0 -497
  133. package/dist/dashboard/styles.js.map +0 -1
@@ -0,0 +1,170 @@
1
+ # Self-driving loop flows
2
+ # Enable with: jfl agent enable
3
+ # These flows close the autonomous improvement loop:
4
+ # Peter Parker creates PR -> CI runs eval -> auto-merge if improved
5
+ #
6
+ # Required secrets (set in GitHub repo settings):
7
+ # JFL_HUB_URL - Context Hub URL (e.g. http://localhost:3001)
8
+ # JFL_HUB_TOKEN - Auth token for hub API
9
+ #
10
+ # Required CLI tools:
11
+ # gh - GitHub CLI (for merge/review operations)
12
+
13
+ flows:
14
+ - name: auto-merge-on-improvement
15
+ description: "Auto-merge Peter Parker PRs when eval score improves"
16
+ enabled: true
17
+ trigger:
18
+ pattern: "eval:scored"
19
+ condition: 'data.improved == "true"'
20
+ gate:
21
+ requires_approval: false
22
+ actions:
23
+ - type: log
24
+ message: "Eval passed: {{data.agent}} on PR #{{data.pr_number}} delta={{data.delta}} ({{data.baseline}} -> {{data.composite}})"
25
+ - type: command
26
+ command: |
27
+ if [ "{{data.improved}}" = "true" ] && [ -n "{{data.pr_number}}" ]; then
28
+ gh pr merge {{data.pr_number}} --merge --delete-branch \
29
+ --body "Auto-merged by JFL: test_pass_rate improved by {{data.delta}} ({{data.baseline}} -> {{data.composite}})"
30
+ fi
31
+ - type: journal
32
+ entry_type: "milestone"
33
+ title: "Auto-merged PP PR #{{data.pr_number}}"
34
+ summary: "Peter Parker PR auto-merged. test_pass_rate: {{data.baseline}} -> {{data.composite}} (delta: {{data.delta}})"
35
+
36
+ - name: flag-regression
37
+ description: "Request changes on Peter Parker PRs when eval regresses"
38
+ enabled: true
39
+ trigger:
40
+ pattern: "eval:scored"
41
+ condition: 'data.improved == "false"'
42
+ actions:
43
+ - type: log
44
+ message: "Eval regression: {{data.agent}} on PR #{{data.pr_number}} delta={{data.delta}} ({{data.baseline}} -> {{data.composite}})"
45
+ - type: command
46
+ command: |
47
+ if [ "{{data.improved}}" = "false" ] && [ -n "{{data.pr_number}}" ]; then
48
+ gh pr review {{data.pr_number}} --request-changes \
49
+ --body "JFL eval regression: test_pass_rate dropped by {{data.delta}} ({{data.baseline}} -> {{data.composite}}). Run URL: {{data.run_url}}"
50
+ fi
51
+ - type: journal
52
+ entry_type: "fix"
53
+ title: "Regression flagged: PP PR #{{data.pr_number}}"
54
+ summary: "Peter Parker PR flagged for regression. test_pass_rate: {{data.baseline}} -> {{data.composite}} (delta: {{data.delta}})"
55
+
56
+ - name: log-training-tuple
57
+ description: "Log training tuple after every eval:scored for RL improvement"
58
+ enabled: true
59
+ trigger:
60
+ pattern: "eval:scored"
61
+ actions:
62
+ - type: journal
63
+ entry_type: "discovery"
64
+ title: "Training tuple: {{data.agent}} delta={{data.delta}}"
65
+ summary: "State: score={{data.baseline}}, Action: PR #{{data.pr_number}} ({{data.branch}}), Reward: delta={{data.delta}} improved={{data.improved}}"
66
+ - type: log
67
+ message: "Training tuple logged: state={{data.baseline}} action=PR#{{data.pr_number}} reward={{data.delta}}"
68
+
69
+ # Review → Fix loop flows
70
+ - name: block-merge-on-blockers
71
+ description: "Request changes when AI review finds red (blocker) findings"
72
+ enabled: true
73
+ trigger:
74
+ pattern: "review:findings"
75
+ condition: 'data.has_blockers == "true"'
76
+ actions:
77
+ - type: log
78
+ message: "Review blockers on PR #{{data.pr_number}}: {{data.total_findings}} findings (red={{data.counts.red}})"
79
+ - type: command
80
+ command: |
81
+ if [ "{{data.has_blockers}}" = "true" ] && [ -n "{{data.pr_number}}" ]; then
82
+ gh pr review {{data.pr_number}} --request-changes \
83
+ --body "JFL AI Review found {{data.counts.red}} blocker(s). Address red findings before merge. Run: {{data.run_url}}"
84
+ fi
85
+ - type: journal
86
+ entry_type: "fix"
87
+ title: "Review blockers: PR #{{data.pr_number}}"
88
+ summary: "AI review found {{data.total_findings}} findings ({{data.counts.red}} red, {{data.counts.yellow}} yellow, {{data.counts.blue}} blue). PP should address blockers."
89
+
90
+ - name: log-review-training-data
91
+ description: "Log review results as training data for every review"
92
+ enabled: true
93
+ trigger:
94
+ pattern: "review:findings"
95
+ actions:
96
+ - type: journal
97
+ entry_type: "discovery"
98
+ title: "Review data: PR #{{data.pr_number}} — {{data.total_findings}} findings"
99
+ summary: "Review: {{data.model}} on {{data.branch}}. Findings: red={{data.counts.red}} yellow={{data.counts.yellow}} blue={{data.counts.blue}}. Blockers: {{data.has_blockers}}"
100
+ - type: log
101
+ message: "Review training data logged: PR#{{data.pr_number}} findings={{data.total_findings}} blockers={{data.has_blockers}}"
102
+
103
+ # PP auto-response to review findings
104
+ - name: pp-address-review-blockers
105
+ description: "Spawn Peter Parker to address blocker findings from AI review"
106
+ enabled: true
107
+ trigger:
108
+ pattern: "review:findings"
109
+ condition: 'data.has_blockers == "true"'
110
+ gate:
111
+ requires_approval: true
112
+ max_iterations: 3
113
+ actions:
114
+ - type: log
115
+ message: "PP dispatched to fix {{data.counts.red}} blocker(s) on PR #{{data.pr_number}}"
116
+ - type: spawn
117
+ command: jfl
118
+ args: ["peter", "run", "--task", "Address AI review blockers on PR #{{data.pr_number}} (branch: {{data.branch}}). Findings: {{data.counts.red}} red, {{data.counts.yellow}} yellow. Read the review comment with 'gh pr view {{data.pr_number}} --comments', fix each red finding, commit and push to the same branch. Do NOT create a new PR."]
119
+ detach: true
120
+ - type: journal
121
+ entry_type: "milestone"
122
+ title: "PP auto-fix dispatched: PR #{{data.pr_number}}"
123
+ summary: "Peter Parker spawned to address {{data.counts.red}} review blockers on {{data.branch}}. Max 3 iterations."
124
+
125
+ # Telemetry agent: log high-severity insights
126
+ - name: telemetry-insight-journal
127
+ description: "Log telemetry insights to journal for tracking"
128
+ enabled: true
129
+ trigger:
130
+ pattern: "telemetry:insight"
131
+ actions:
132
+ - type: journal
133
+ entry_type: "discovery"
134
+ title: "Telemetry: {{data.title}}"
135
+ summary: "{{data.description}}. Fix: {{data.suggested_fix}}"
136
+ - type: log
137
+ message: "[telemetry-agent] {{data.severity}} insight: {{data.title}}"
138
+
139
+ # Telemetry agent: spawn PP for high-severity issues
140
+ - name: telemetry-auto-fix
141
+ description: "Spawn Peter Parker to address high-severity telemetry findings"
142
+ enabled: true
143
+ trigger:
144
+ pattern: "telemetry:insight"
145
+ condition: 'data.severity == "high" && data.is_new == true'
146
+ gate:
147
+ requires_approval: true
148
+ actions:
149
+ - type: log
150
+ message: "PP dispatched for telemetry issue: {{data.title}}"
151
+ - type: spawn
152
+ command: jfl
153
+ args: ["peter", "pr", "--task", "Fix telemetry issue: {{data.title}}. Details: {{data.description}}. Suggested fix: {{data.suggested_fix}}"]
154
+ detach: true
155
+ - type: journal
156
+ entry_type: "milestone"
157
+ title: "PP dispatched: {{data.title}}"
158
+ summary: "Telemetry agent detected high-severity issue. Peter Parker spawned to address: {{data.description}}"
159
+
160
+ # Training tuple enrichment with AI quality score
161
+ - name: log-quality-training-tuple
162
+ description: "Log enriched training tuple with AI quality dimensions"
163
+ enabled: true
164
+ trigger:
165
+ pattern: "eval:scored"
166
+ actions:
167
+ - type: journal
168
+ entry_type: "discovery"
169
+ title: "Quality tuple: {{data.agent}} quality={{data.quality_score}}"
170
+ summary: "Enriched tuple — State: baseline={{data.baseline}}, Action: PR #{{data.pr_number}}, Reward: delta={{data.delta}} quality={{data.quality_score}}. Dims: correctness={{data.dim_correctness}} coverage={{data.dim_coverage}} architecture={{data.dim_architecture}} value={{data.dim_value}}"
@@ -0,0 +1,26 @@
1
+ # Theory — {agent-name}
2
+
3
+ ## Current Hypothesis
4
+
5
+ {What do you believe is true about your approach? Why should it work? What's the core insight?}
6
+
7
+ ## Approach
8
+
9
+ {How are you executing on the hypothesis? What's the method?}
10
+
11
+ ## Predictions (specific, falsifiable)
12
+
13
+ | # | Prediction | Metric | Target | By |
14
+ |---|-----------|--------|--------|-----|
15
+ | P1 | {specific claim} | {metric name} | {threshold} | {version or date} |
16
+ | P2 | {specific claim} | {metric name} | {threshold} | {version or date} |
17
+
18
+ ## Evidence
19
+
20
+ | Date | Prediction | Actual | Delta | Verdict |
21
+ |------|-----------|--------|-------|---------|
22
+ | | | | | |
23
+
24
+ ## Revisions
25
+
26
+ {When evidence contradicts predictions, document what changed and why.}
@@ -155,12 +155,21 @@ if [ $MERGE_STATUS -eq 0 ]; then
155
155
  # Push to origin
156
156
  git push origin "$WORKING_BRANCH" 2>/dev/null || echo "⚠ Push failed - run manually: git push origin $WORKING_BRANCH"
157
157
 
158
- # Remove worktree if it exists
159
- WORKTREE_PATH=$(git worktree list | grep "$BRANCH" | awk '{print $1}' | head -1)
158
+ # Remove worktree if it exists (NEVER remove the main repo)
159
+ MAIN_TOPLEVEL=$(git rev-parse --show-toplevel 2>/dev/null)
160
+ WORKTREE_PATH=$(git worktree list | grep "$BRANCH" | grep -v "(bare)" | awk '{print $1}' | head -1)
160
161
  if [ -n "$WORKTREE_PATH" ] && [ -d "$WORKTREE_PATH" ]; then
161
- echo "Removing worktree at $WORKTREE_PATH..."
162
- rm -rf "$WORKTREE_PATH" 2>/dev/null || true
163
- git worktree prune 2>/dev/null || true
162
+ WORKTREE_REAL=$(cd "$WORKTREE_PATH" && pwd -P)
163
+ MAIN_REAL=$(cd "$MAIN_TOPLEVEL" && pwd -P)
164
+ if [ "$WORKTREE_REAL" = "$MAIN_REAL" ]; then
165
+ echo "⚠ SAFETY: refusing to rm -rf main repo at $WORKTREE_PATH"
166
+ elif [ "$WORKTREE_REAL" = "$HOME" ] || [ "$WORKTREE_REAL" = "/" ]; then
167
+ echo "⚠ SAFETY: refusing to rm -rf protected path $WORKTREE_PATH"
168
+ else
169
+ echo "Removing worktree at $WORKTREE_PATH..."
170
+ git worktree remove "$WORKTREE_PATH" --force 2>/dev/null || true
171
+ git worktree prune 2>/dev/null || true
172
+ fi
164
173
  fi
165
174
 
166
175
  # Delete the branch
@@ -227,12 +236,21 @@ else
227
236
  # Push to origin
228
237
  git push origin "$WORKING_BRANCH" 2>/dev/null || echo "⚠ Push failed - run manually: git push origin $WORKING_BRANCH"
229
238
 
230
- # Remove worktree
231
- WORKTREE_PATH=$(git worktree list | grep "$BRANCH" | awk '{print $1}' | head -1)
239
+ # Remove worktree if it exists (NEVER remove the main repo)
240
+ MAIN_TOPLEVEL=$(git rev-parse --show-toplevel 2>/dev/null)
241
+ WORKTREE_PATH=$(git worktree list | grep "$BRANCH" | grep -v "(bare)" | awk '{print $1}' | head -1)
232
242
  if [ -n "$WORKTREE_PATH" ] && [ -d "$WORKTREE_PATH" ]; then
233
- echo "Removing worktree at $WORKTREE_PATH..."
234
- rm -rf "$WORKTREE_PATH" 2>/dev/null || true
235
- git worktree prune 2>/dev/null || true
243
+ WORKTREE_REAL=$(cd "$WORKTREE_PATH" && pwd -P)
244
+ MAIN_REAL=$(cd "$MAIN_TOPLEVEL" && pwd -P)
245
+ if [ "$WORKTREE_REAL" = "$MAIN_REAL" ]; then
246
+ echo "⚠ SAFETY: refusing to rm -rf main repo at $WORKTREE_PATH"
247
+ elif [ "$WORKTREE_REAL" = "$HOME" ] || [ "$WORKTREE_REAL" = "/" ]; then
248
+ echo "⚠ SAFETY: refusing to rm -rf protected path $WORKTREE_PATH"
249
+ else
250
+ echo "Removing worktree at $WORKTREE_PATH..."
251
+ git worktree remove "$WORKTREE_PATH" --force 2>/dev/null || true
252
+ git worktree prune 2>/dev/null || true
253
+ fi
236
254
  fi
237
255
 
238
256
  # Delete the branch
@@ -1,7 +0,0 @@
1
- /**
2
- * Dashboard reusable Preact components
3
- *
4
- * @purpose Preact+HTM component JS strings for Nav, Card, StatusBadge, Table, JournalEntry, etc.
5
- */
6
- export declare function getComponentsJS(): string;
7
- //# sourceMappingURL=components.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/dashboard/components.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAgB,eAAe,IAAI,MAAM,CA4JxC"}
@@ -1,163 +0,0 @@
1
- /**
2
- * Dashboard reusable Preact components
3
- *
4
- * @purpose Preact+HTM component JS strings for Nav, Card, StatusBadge, Table, JournalEntry, etc.
5
- */
6
- export function getComponentsJS() {
7
- return `
8
- function Nav({ currentPage, setPage, projectName, port }) {
9
- const pages = [
10
- { id: 'overview', label: 'Command Center' },
11
- { id: 'journal', label: 'Journal' },
12
- { id: 'agents', label: 'Agents' },
13
- { id: 'events', label: 'Events' },
14
- { id: 'sessions', label: 'Sessions' },
15
- { id: 'projects', label: 'Projects' },
16
- ]
17
-
18
- return html\`
19
- <div class="sidebar">
20
- <div class="sidebar-brand">
21
- <h1>\${projectName || 'Context Hub'}</h1>
22
- <div class="port-badge">Port \${port}</div>
23
- </div>
24
- <ul class="nav-items">
25
- \${pages.map(p => html\`
26
- <li
27
- key=\${p.id}
28
- class=\${'nav-item' + (currentPage === p.id ? ' active' : '')}
29
- onClick=\${() => setPage(p.id)}
30
- >
31
- \${p.label}
32
- </li>
33
- \`)}
34
- </ul>
35
- </div>
36
- \`
37
- }
38
-
39
- function Card({ title, children, className }) {
40
- return html\`
41
- <div class=\${'card ' + (className || '')}>
42
- \${title && html\`<div class="card-title">\${title}</div>\`}
43
- \${children}
44
- </div>
45
- \`
46
- }
47
-
48
- function StatusBadge({ status }) {
49
- const s = (status || 'unknown').toLowerCase()
50
- return html\`<span class=\${'badge badge-' + s}>\${status}</span>\`
51
- }
52
-
53
- function TypeBadge({ type }) {
54
- const t = (type || 'unknown').toLowerCase()
55
- let cls = 'badge-unknown'
56
- if (t.startsWith('peter')) cls = 'badge-peter'
57
- else if (t.startsWith('task')) cls = 'badge-task'
58
- else if (t.startsWith('session')) cls = 'badge-session'
59
- else if (t.startsWith('system')) cls = 'badge-system'
60
- else if (t === 'feature') cls = 'badge-feature'
61
- else if (t === 'fix') cls = 'badge-fix'
62
- else if (t === 'decision') cls = 'badge-decision'
63
- else if (t === 'discovery') cls = 'badge-discovery'
64
- else if (t === 'milestone') cls = 'badge-milestone'
65
- else if (t === 'entry') cls = 'badge-unknown'
66
- else if (t === 'doc') cls = 'badge-unknown'
67
- return html\`<span class=\${'badge ' + cls}>\${type}</span>\`
68
- }
69
-
70
- function DataTable({ headers, rows }) {
71
- if (!rows || rows.length === 0) {
72
- return html\`<div class="empty-state">No data</div>\`
73
- }
74
- return html\`
75
- <table>
76
- <thead>
77
- <tr>\${headers.map(h => html\`<th key=\${h}>\${h}</th>\`)}</tr>
78
- </thead>
79
- <tbody>
80
- \${rows.map((row, i) => html\`
81
- <tr key=\${i}>
82
- \${row.map((cell, j) => html\`<td key=\${j}>\${cell}</td>\`)}
83
- </tr>
84
- \`)}
85
- </tbody>
86
- </table>
87
- \`
88
- }
89
-
90
- function EventRow({ event }) {
91
- const time = new Date(event.timestamp).toLocaleTimeString()
92
- const payload = JSON.stringify(event.data || {}).slice(0, 80)
93
- return html\`
94
- <tr class="event-row">
95
- <td class="event-time">\${time}</td>
96
- <td><\${TypeBadge} type=\${event.type} /></td>
97
- <td>\${event.source || '-'}</td>
98
- <td class="event-payload">\${payload}</td>
99
- </tr>
100
- \`
101
- }
102
-
103
- function JournalEntryRow({ entry, expanded }) {
104
- const time = entry.timestamp ? new Date(entry.timestamp).toLocaleString() : ''
105
- return html\`
106
- <div class="journal-entry">
107
- <div class="journal-entry-header">
108
- <\${TypeBadge} type=\${entry.type || 'entry'} />
109
- <span class="journal-entry-title">\${entry.title}</span>
110
- <span class="journal-entry-time">\${time}</span>
111
- </div>
112
- \${(expanded || entry.content) && html\`
113
- <div class="journal-entry-content">\${(entry.content || '').slice(0, 200)}\${(entry.content || '').length > 200 ? '...' : ''}</div>
114
- \`}
115
- </div>
116
- \`
117
- }
118
-
119
- function SearchInput({ value, onInput, placeholder, loading }) {
120
- return html\`
121
- <div style="position: relative; flex: 1;">
122
- <input
123
- type="text"
124
- class="search-input"
125
- value=\${value}
126
- onInput=\${onInput}
127
- placeholder=\${placeholder || 'Search...'}
128
- onKeyDown=\${e => { if (e.key === 'Enter' && e.target.closest('.card')) { const btn = e.target.closest('.card').querySelector('.btn-primary'); if (btn) btn.click() }}}
129
- />
130
- \${loading && html\`<div class="loading" style="position: absolute; right: 8px; top: 50%; transform: translateY(-50%); padding: 0;"></div>\`}
131
- </div>
132
- \`
133
- }
134
-
135
- function LiveIndicator({ connected }) {
136
- return html\`
137
- <span style="display: inline-flex; align-items: center; font-size: 0.8rem;">
138
- <span class="live-dot" style=\${'background: ' + (connected ? 'var(--success)' : 'var(--error)')}></span>
139
- \${connected ? 'Live' : 'Disconnected'}
140
- </span>
141
- \`
142
- }
143
-
144
- function StatRow({ label, value }) {
145
- return html\`
146
- <div class="stat-row">
147
- <span class="stat-label">\${label}</span>
148
- <span class="stat-value">\${value}</span>
149
- </div>
150
- \`
151
- }
152
-
153
- function RelevanceBar({ score, max }) {
154
- const pct = Math.min(100, Math.round((score / (max || 1)) * 100))
155
- return html\`
156
- <div class="relevance-bar" style="width: 60px;">
157
- <div class="relevance-fill" style=\${'width: ' + pct + '%'}></div>
158
- </div>
159
- \`
160
- }
161
- `;
162
- }
163
- //# sourceMappingURL=components.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"components.js","sourceRoot":"","sources":["../../src/dashboard/components.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,UAAU,eAAe;IAC7B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0JN,CAAA;AACH,CAAC"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Dashboard page components
3
- *
4
- * @purpose Command center pages: journal-first overview, events, agents, projects, sessions, journal
5
- */
6
- export declare function getPagesJS(): string;
7
- //# sourceMappingURL=pages.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/dashboard/pages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAgB,UAAU,IAAI,MAAM,CA+tBnC"}