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.
- package/README.md +308 -28
- package/dist/commands/context-hub.d.ts.map +1 -1
- package/dist/commands/context-hub.js +428 -27
- package/dist/commands/context-hub.js.map +1 -1
- package/dist/commands/eval.d.ts +6 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/eval.js +236 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/flows.d.ts +4 -1
- package/dist/commands/flows.d.ts.map +1 -1
- package/dist/commands/flows.js +160 -1
- package/dist/commands/flows.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +272 -145
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/peter.d.ts.map +1 -1
- package/dist/commands/peter.js +220 -1
- package/dist/commands/peter.js.map +1 -1
- package/dist/commands/pi.d.ts +21 -0
- package/dist/commands/pi.d.ts.map +1 -0
- package/dist/commands/pi.js +154 -0
- package/dist/commands/pi.js.map +1 -0
- package/dist/commands/portfolio.d.ts +6 -0
- package/dist/commands/portfolio.d.ts.map +1 -0
- package/dist/commands/portfolio.js +249 -0
- package/dist/commands/portfolio.js.map +1 -0
- package/dist/commands/predict.d.ts +6 -0
- package/dist/commands/predict.d.ts.map +1 -0
- package/dist/commands/predict.js +234 -0
- package/dist/commands/predict.js.map +1 -0
- package/dist/commands/scope.d.ts +1 -0
- package/dist/commands/scope.d.ts.map +1 -1
- package/dist/commands/scope.js +189 -2
- package/dist/commands/scope.js.map +1 -1
- package/dist/commands/synopsis.d.ts +44 -0
- package/dist/commands/synopsis.d.ts.map +1 -1
- package/dist/commands/synopsis.js +1 -1
- package/dist/commands/synopsis.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +49 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/viz.d.ts +7 -0
- package/dist/commands/viz.d.ts.map +1 -0
- package/dist/commands/viz.js +460 -0
- package/dist/commands/viz.js.map +1 -0
- package/dist/commands/voice.js.map +1 -1
- package/dist/dashboard/index.d.ts +4 -5
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +57 -119
- package/dist/dashboard/index.js.map +1 -1
- package/dist/dashboard-static/assets/index-B6kRK9Rq.js +116 -0
- package/dist/dashboard-static/assets/index-BpdKJPLu.css +1 -0
- package/dist/dashboard-static/index.html +16 -0
- package/dist/index.js +120 -20
- package/dist/index.js.map +1 -1
- package/dist/lib/eval-store.d.ts +15 -0
- package/dist/lib/eval-store.d.ts.map +1 -0
- package/dist/lib/eval-store.js +179 -0
- package/dist/lib/eval-store.js.map +1 -0
- package/dist/lib/flow-engine.d.ts +13 -0
- package/dist/lib/flow-engine.d.ts.map +1 -1
- package/dist/lib/flow-engine.js +164 -3
- package/dist/lib/flow-engine.js.map +1 -1
- package/dist/lib/hub-client.d.ts +80 -0
- package/dist/lib/hub-client.d.ts.map +1 -0
- package/dist/lib/hub-client.js +46 -0
- package/dist/lib/hub-client.js.map +1 -0
- package/dist/lib/predictor.d.ts +99 -0
- package/dist/lib/predictor.d.ts.map +1 -0
- package/dist/lib/predictor.js +394 -0
- package/dist/lib/predictor.js.map +1 -0
- package/dist/lib/service-gtm.d.ts +88 -44
- package/dist/lib/service-gtm.d.ts.map +1 -1
- package/dist/lib/service-gtm.js +451 -243
- package/dist/lib/service-gtm.js.map +1 -1
- package/dist/lib/telemetry-agent.d.ts +57 -0
- package/dist/lib/telemetry-agent.d.ts.map +1 -0
- package/dist/lib/telemetry-agent.js +268 -0
- package/dist/lib/telemetry-agent.js.map +1 -0
- package/dist/lib/telemetry-digest.d.ts.map +1 -1
- package/dist/lib/telemetry-digest.js +17 -17
- package/dist/lib/telemetry-digest.js.map +1 -1
- package/dist/lib/telemetry.d.ts +1 -0
- package/dist/lib/telemetry.d.ts.map +1 -1
- package/dist/lib/telemetry.js +14 -6
- package/dist/lib/telemetry.js.map +1 -1
- package/dist/lib/trajectory-loader.d.ts +82 -0
- package/dist/lib/trajectory-loader.d.ts.map +1 -0
- package/dist/lib/trajectory-loader.js +406 -0
- package/dist/lib/trajectory-loader.js.map +1 -0
- package/dist/mcp/context-hub-mcp.js +60 -0
- package/dist/mcp/context-hub-mcp.js.map +1 -1
- package/dist/mcp/service-registry-mcp.js +0 -0
- package/dist/types/eval.d.ts +18 -0
- package/dist/types/eval.d.ts.map +1 -0
- package/dist/types/eval.js +5 -0
- package/dist/types/eval.js.map +1 -0
- package/dist/types/journal.d.ts +133 -0
- package/dist/types/journal.d.ts.map +1 -0
- package/dist/types/journal.js +59 -0
- package/dist/types/journal.js.map +1 -0
- package/dist/types/map.d.ts +1 -1
- package/dist/types/map.d.ts.map +1 -1
- package/dist/types/map.js.map +1 -1
- package/dist/ui/service-dashboard.js.map +1 -1
- package/dist/utils/jfl-paths.d.ts +1 -0
- package/dist/utils/jfl-paths.d.ts.map +1 -1
- package/dist/utils/jfl-paths.js +1 -0
- package/dist/utils/jfl-paths.js.map +1 -1
- package/dist/utils/wallet.js.map +1 -1
- package/package.json +7 -2
- package/scripts/generate-changesets.sh +113 -0
- package/scripts/migrate-to-branch-sessions.sh +201 -0
- package/scripts/pp-branch-pr.sh +115 -0
- package/scripts/session/session-cleanup.sh +29 -14
- package/scripts/session/session-end.sh +0 -10
- package/scripts/session/session-init.sh +0 -16
- package/scripts/session/session-sync.sh +0 -10
- package/template/.jfl/flows-self-driving.yaml +170 -0
- package/template/THEORY.md +26 -0
- package/template/scripts/session/session-cleanup.sh +28 -10
- package/dist/dashboard/components.d.ts +0 -7
- package/dist/dashboard/components.d.ts.map +0 -1
- package/dist/dashboard/components.js +0 -163
- package/dist/dashboard/components.js.map +0 -1
- package/dist/dashboard/pages.d.ts +0 -7
- package/dist/dashboard/pages.d.ts.map +0 -1
- package/dist/dashboard/pages.js +0 -742
- package/dist/dashboard/pages.js.map +0 -1
- package/dist/dashboard/styles.d.ts +0 -7
- package/dist/dashboard/styles.d.ts.map +0 -1
- package/dist/dashboard/styles.js +0 -497
- 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
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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 +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 +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"}
|