jfl 0.8.1 → 0.9.1
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 +35 -4
- package/dist/commands/digest.d.ts +6 -0
- package/dist/commands/digest.d.ts.map +1 -1
- package/dist/commands/digest.js +70 -69
- package/dist/commands/digest.js.map +1 -1
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +30 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/eval.d.ts +40 -0
- package/dist/commands/eval.d.ts.map +1 -1
- package/dist/commands/eval.js +8 -8
- package/dist/commands/eval.js.map +1 -1
- package/dist/commands/findings.d.ts +7 -0
- package/dist/commands/findings.d.ts.map +1 -1
- package/dist/commands/findings.js +4 -4
- package/dist/commands/findings.js.map +1 -1
- package/dist/commands/ide.d.ts +2 -1
- package/dist/commands/ide.d.ts.map +1 -1
- package/dist/commands/ide.js +61 -1
- package/dist/commands/ide.js.map +1 -1
- package/dist/commands/init-from-service.d.ts +15 -0
- package/dist/commands/init-from-service.d.ts.map +1 -0
- package/dist/commands/init-from-service.js +541 -0
- package/dist/commands/init-from-service.js.map +1 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +32 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/kanban.d.ts.map +1 -1
- package/dist/commands/kanban.js +13 -4
- package/dist/commands/kanban.js.map +1 -1
- package/dist/commands/linear.d.ts +41 -0
- package/dist/commands/linear.d.ts.map +1 -0
- package/dist/commands/linear.js +715 -0
- package/dist/commands/linear.js.map +1 -0
- package/dist/commands/peter.d.ts.map +1 -1
- package/dist/commands/peter.js +232 -25
- package/dist/commands/peter.js.map +1 -1
- package/dist/commands/portfolio.d.ts +5 -0
- package/dist/commands/portfolio.d.ts.map +1 -1
- package/dist/commands/portfolio.js +193 -203
- package/dist/commands/portfolio.js.map +1 -1
- package/dist/commands/predict.d.ts +19 -0
- package/dist/commands/predict.d.ts.map +1 -1
- package/dist/commands/predict.js +4 -4
- package/dist/commands/predict.js.map +1 -1
- package/dist/commands/services.d.ts.map +1 -1
- package/dist/commands/services.js +146 -0
- package/dist/commands/services.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +279 -20
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/start.d.ts +25 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +191 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/telemetry-monitor.d.ts +11 -0
- package/dist/commands/telemetry-monitor.d.ts.map +1 -0
- package/dist/commands/telemetry-monitor.js +224 -0
- package/dist/commands/telemetry-monitor.js.map +1 -0
- package/dist/commands/telemetry-test.d.ts +11 -0
- package/dist/commands/telemetry-test.d.ts.map +1 -0
- package/dist/commands/telemetry-test.js +67 -0
- package/dist/commands/telemetry-test.js.map +1 -0
- package/dist/commands/tenet-agents.d.ts +13 -0
- package/dist/commands/tenet-agents.d.ts.map +1 -0
- package/dist/commands/tenet-agents.js +191 -0
- package/dist/commands/tenet-agents.js.map +1 -0
- package/dist/commands/tenet-setup.d.ts +20 -0
- package/dist/commands/tenet-setup.d.ts.map +1 -0
- package/dist/commands/tenet-setup.js +135 -0
- package/dist/commands/tenet-setup.js.map +1 -0
- package/dist/commands/train.d.ts +18 -0
- package/dist/commands/train.d.ts.map +1 -1
- package/dist/commands/train.js +182 -0
- package/dist/commands/train.js.map +1 -1
- package/dist/commands/viz.d.ts +33 -0
- package/dist/commands/viz.d.ts.map +1 -1
- package/dist/commands/viz.js +9 -9
- package/dist/commands/viz.js.map +1 -1
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +24 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.js +230 -30
- package/dist/index.js.map +1 -1
- package/dist/lib/advanced-setup.d.ts +78 -0
- package/dist/lib/advanced-setup.d.ts.map +1 -0
- package/dist/lib/advanced-setup.js +433 -0
- package/dist/lib/advanced-setup.js.map +1 -0
- package/dist/lib/agent-config.d.ts +33 -0
- package/dist/lib/agent-config.d.ts.map +1 -1
- package/dist/lib/agent-config.js +26 -0
- package/dist/lib/agent-config.js.map +1 -1
- package/dist/lib/counterfactual-training-bridge.d.ts +114 -0
- package/dist/lib/counterfactual-training-bridge.d.ts.map +1 -0
- package/dist/lib/counterfactual-training-bridge.js +322 -0
- package/dist/lib/counterfactual-training-bridge.js.map +1 -0
- package/dist/lib/discovery-agent.d.ts +48 -0
- package/dist/lib/discovery-agent.d.ts.map +1 -0
- package/dist/lib/discovery-agent.js +111 -0
- package/dist/lib/discovery-agent.js.map +1 -0
- package/dist/lib/flow-engine.d.ts.map +1 -1
- package/dist/lib/flow-engine.js +46 -8
- package/dist/lib/flow-engine.js.map +1 -1
- package/dist/lib/gtm-generator.d.ts +29 -0
- package/dist/lib/gtm-generator.d.ts.map +1 -0
- package/dist/lib/gtm-generator.js +252 -0
- package/dist/lib/gtm-generator.js.map +1 -0
- package/dist/lib/hub-health.d.ts +40 -0
- package/dist/lib/hub-health.d.ts.map +1 -0
- package/dist/lib/hub-health.js +89 -0
- package/dist/lib/hub-health.js.map +1 -0
- package/dist/lib/invariant-monitor.d.ts +6 -2
- package/dist/lib/invariant-monitor.d.ts.map +1 -1
- package/dist/lib/invariant-monitor.js +89 -2
- package/dist/lib/invariant-monitor.js.map +1 -1
- package/dist/lib/journal-analyzer.d.ts +71 -0
- package/dist/lib/journal-analyzer.d.ts.map +1 -0
- package/dist/lib/journal-analyzer.js +306 -0
- package/dist/lib/journal-analyzer.js.map +1 -0
- package/dist/lib/linear-client.d.ts +73 -0
- package/dist/lib/linear-client.d.ts.map +1 -0
- package/dist/lib/linear-client.js +112 -0
- package/dist/lib/linear-client.js.map +1 -0
- package/dist/lib/linear-id-map.d.ts +20 -0
- package/dist/lib/linear-id-map.d.ts.map +1 -0
- package/dist/lib/linear-id-map.js +59 -0
- package/dist/lib/linear-id-map.js.map +1 -0
- package/dist/lib/linear-kanban.d.ts +66 -0
- package/dist/lib/linear-kanban.d.ts.map +1 -0
- package/dist/lib/linear-kanban.js +175 -0
- package/dist/lib/linear-kanban.js.map +1 -0
- package/dist/lib/onboarding.d.ts +40 -0
- package/dist/lib/onboarding.d.ts.map +1 -0
- package/dist/lib/onboarding.js +213 -0
- package/dist/lib/onboarding.js.map +1 -0
- package/dist/lib/physical-world-model.d.ts +50 -0
- package/dist/lib/physical-world-model.d.ts.map +1 -0
- package/dist/lib/physical-world-model.js +251 -0
- package/dist/lib/physical-world-model.js.map +1 -0
- package/dist/lib/planning-loop.d.ts +157 -0
- package/dist/lib/planning-loop.d.ts.map +1 -0
- package/dist/lib/planning-loop.js +537 -0
- package/dist/lib/planning-loop.js.map +1 -0
- package/dist/lib/policy-head.d.ts +13 -0
- package/dist/lib/policy-head.d.ts.map +1 -1
- package/dist/lib/policy-head.js +168 -2
- package/dist/lib/policy-head.js.map +1 -1
- package/dist/lib/resource-optimizer-middleware.d.ts +39 -0
- package/dist/lib/resource-optimizer-middleware.d.ts.map +1 -0
- package/dist/lib/resource-optimizer-middleware.js +222 -0
- package/dist/lib/resource-optimizer-middleware.js.map +1 -0
- package/dist/lib/resource-optimizer.d.ts +71 -0
- package/dist/lib/resource-optimizer.d.ts.map +1 -0
- package/dist/lib/resource-optimizer.js +228 -0
- package/dist/lib/resource-optimizer.js.map +1 -0
- package/dist/lib/rl-manager.d.ts +74 -0
- package/dist/lib/rl-manager.d.ts.map +1 -0
- package/dist/lib/rl-manager.js +245 -0
- package/dist/lib/rl-manager.js.map +1 -0
- package/dist/lib/service-analyzer.d.ts +76 -0
- package/dist/lib/service-analyzer.d.ts.map +1 -0
- package/dist/lib/service-analyzer.js +704 -0
- package/dist/lib/service-analyzer.js.map +1 -0
- package/dist/lib/service-gtm.js +2 -2
- package/dist/lib/service-gtm.js.map +1 -1
- package/dist/lib/service-questionnaire.d.ts +11 -0
- package/dist/lib/service-questionnaire.d.ts.map +1 -0
- package/dist/lib/service-questionnaire.js +89 -0
- package/dist/lib/service-questionnaire.js.map +1 -0
- package/dist/lib/setup/agent-generator.d.ts +2 -0
- package/dist/lib/setup/agent-generator.d.ts.map +1 -1
- package/dist/lib/setup/agent-generator.js +128 -4
- package/dist/lib/setup/agent-generator.js.map +1 -1
- package/dist/lib/setup/flow-generator.d.ts +10 -0
- package/dist/lib/setup/flow-generator.d.ts.map +1 -0
- package/dist/lib/setup/flow-generator.js +113 -0
- package/dist/lib/setup/flow-generator.js.map +1 -0
- package/dist/lib/setup/invariant-bridge.d.ts +91 -0
- package/dist/lib/setup/invariant-bridge.d.ts.map +1 -0
- package/dist/lib/setup/invariant-bridge.js +384 -0
- package/dist/lib/setup/invariant-bridge.js.map +1 -0
- package/dist/lib/setup/spec-generator.d.ts +41 -5
- package/dist/lib/setup/spec-generator.d.ts.map +1 -1
- package/dist/lib/setup/spec-generator.js +503 -29
- package/dist/lib/setup/spec-generator.js.map +1 -1
- package/dist/lib/setup/starter-intelligence.d.ts +25 -0
- package/dist/lib/setup/starter-intelligence.d.ts.map +1 -0
- package/dist/lib/setup/starter-intelligence.js +309 -0
- package/dist/lib/setup/starter-intelligence.js.map +1 -0
- package/dist/lib/stratus-client.js +1 -1
- package/dist/lib/stratus-client.js.map +1 -1
- package/dist/lib/surface-agent.d.ts +78 -0
- package/dist/lib/surface-agent.d.ts.map +1 -0
- package/dist/lib/surface-agent.js +105 -0
- package/dist/lib/surface-agent.js.map +1 -0
- package/dist/lib/surface-coordination-example.d.ts +30 -0
- package/dist/lib/surface-coordination-example.d.ts.map +1 -0
- package/dist/lib/surface-coordination-example.js +164 -0
- package/dist/lib/surface-coordination-example.js.map +1 -0
- package/dist/lib/telemetry/physical-world-collector.d.ts +15 -0
- package/dist/lib/telemetry/physical-world-collector.d.ts.map +1 -0
- package/dist/lib/telemetry/physical-world-collector.js +177 -0
- package/dist/lib/telemetry/physical-world-collector.js.map +1 -0
- package/dist/lib/telemetry/training-bridge.d.ts +51 -0
- package/dist/lib/telemetry/training-bridge.d.ts.map +1 -0
- package/dist/lib/telemetry/training-bridge.js +185 -0
- package/dist/lib/telemetry/training-bridge.js.map +1 -0
- package/dist/lib/telemetry.d.ts +2 -1
- package/dist/lib/telemetry.d.ts.map +1 -1
- package/dist/lib/telemetry.js +23 -2
- package/dist/lib/telemetry.js.map +1 -1
- package/dist/lib/tenet-board-agent.d.ts +52 -0
- package/dist/lib/tenet-board-agent.d.ts.map +1 -0
- package/dist/lib/tenet-board-agent.js +226 -0
- package/dist/lib/tenet-board-agent.js.map +1 -0
- package/dist/lib/tenet-ide-agent.d.ts +40 -0
- package/dist/lib/tenet-ide-agent.d.ts.map +1 -0
- package/dist/lib/tenet-ide-agent.js +199 -0
- package/dist/lib/tenet-ide-agent.js.map +1 -0
- package/dist/lib/workspace/data-pipeline.d.ts.map +1 -1
- package/dist/lib/workspace/data-pipeline.js +27 -5
- package/dist/lib/workspace/data-pipeline.js.map +1 -1
- package/dist/lib/workspace/sidebar-runner.d.ts +13 -0
- package/dist/lib/workspace/sidebar-runner.d.ts.map +1 -0
- package/dist/lib/workspace/sidebar-runner.js +419 -0
- package/dist/lib/workspace/sidebar-runner.js.map +1 -0
- package/dist/lib/workspace/surface-registry.d.ts.map +1 -1
- package/dist/lib/workspace/surface-registry.js +9 -1
- package/dist/lib/workspace/surface-registry.js.map +1 -1
- package/dist/lib/workspace/surfaces/agent-overview.d.ts +3 -3
- package/dist/lib/workspace/surfaces/agent-overview.d.ts.map +1 -1
- package/dist/lib/workspace/surfaces/agent-overview.js +3 -3
- package/dist/lib/workspace/surfaces/agent-overview.js.map +1 -1
- package/dist/lib/workspace/surfaces/index.d.ts +3 -0
- package/dist/lib/workspace/surfaces/index.d.ts.map +1 -1
- package/dist/lib/workspace/surfaces/index.js +3 -0
- package/dist/lib/workspace/surfaces/index.js.map +1 -1
- package/dist/lib/workspace/surfaces/kanban.d.ts +15 -0
- package/dist/lib/workspace/surfaces/kanban.d.ts.map +1 -0
- package/dist/lib/workspace/surfaces/kanban.js +43 -0
- package/dist/lib/workspace/surfaces/kanban.js.map +1 -0
- package/dist/lib/workspace/surfaces/physical-world.d.ts +15 -0
- package/dist/lib/workspace/surfaces/physical-world.d.ts.map +1 -0
- package/dist/lib/workspace/surfaces/physical-world.js +37 -0
- package/dist/lib/workspace/surfaces/physical-world.js.map +1 -0
- package/dist/lib/workspace/surfaces/sidebar.d.ts +22 -0
- package/dist/lib/workspace/surfaces/sidebar.d.ts.map +1 -0
- package/dist/lib/workspace/surfaces/sidebar.js +94 -0
- package/dist/lib/workspace/surfaces/sidebar.js.map +1 -0
- package/dist/lib/workspace/tmux-adapter.d.ts +8 -5
- package/dist/lib/workspace/tmux-adapter.d.ts.map +1 -1
- package/dist/lib/workspace/tmux-adapter.js +38 -7
- package/dist/lib/workspace/tmux-adapter.js.map +1 -1
- package/dist/lib/workspace/tmux-sidebar.d.ts +14 -0
- package/dist/lib/workspace/tmux-sidebar.d.ts.map +1 -0
- package/dist/lib/workspace/tmux-sidebar.js +230 -0
- package/dist/lib/workspace/tmux-sidebar.js.map +1 -0
- package/dist/types/flows.d.ts +2 -1
- package/dist/types/flows.d.ts.map +1 -1
- package/dist/types/physical-world-model.d.ts +65 -0
- package/dist/types/physical-world-model.d.ts.map +1 -0
- package/dist/types/physical-world-model.js +43 -0
- package/dist/types/physical-world-model.js.map +1 -0
- package/dist/types/telemetry.d.ts +37 -0
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/types/world-model.d.ts.map +1 -1
- package/dist/types/world-model.js +14 -7
- package/dist/types/world-model.js.map +1 -1
- package/dist/utils/context-hub-port.d.ts.map +1 -1
- package/dist/utils/context-hub-port.js +6 -1
- package/dist/utils/context-hub-port.js.map +1 -1
- package/dist/utils/jfl-config.d.ts +7 -2
- package/dist/utils/jfl-config.d.ts.map +1 -1
- package/dist/utils/jfl-config.js +14 -4
- package/dist/utils/jfl-config.js.map +1 -1
- package/package.json +3 -2
- package/packages/pi/extensions/context.ts +51 -1
- package/packages/pi/extensions/hub-tools.ts +247 -0
- package/packages/pi/extensions/index.ts +38 -6
- package/packages/pi/extensions/memory-tool.ts +84 -4
- package/packages/pi/extensions/service-skills.ts +214 -0
- package/scripts/telemetry-dashboard.sh +44 -0
- package/scripts/test-planning-loop-e2e.ts +181 -0
- package/scripts/test-server-inference.ts +49 -0
- package/scripts/test-state-sensitivity.ts +32 -0
- package/scripts/train/v2/benchmark.py +661 -0
- package/scripts/train/v2/generate_balanced.py +439 -0
- package/scripts/train/v2/generate_hard_negatives.py +219 -0
- package/scripts/train/v2/infer.py +149 -36
- package/scripts/train/v2/infer_server.py +224 -0
- package/scripts/train/v2/online_train.py +576 -0
- package/scripts/train/v2/precompute.py +24 -6
- package/template/CLAUDE.md +74 -132
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @purpose Smart Project Management Surface — AI-enhanced project tracking with automated issue resolution
|
|
3
|
+
*/
|
|
4
|
+
import type { StatusEntry } from "../backend.js";
|
|
5
|
+
import { SurfaceType } from "../surface-type.js";
|
|
6
|
+
import type { SurfaceContext, LiveData, NotificationRule } from "../surface-type.js";
|
|
7
|
+
export declare class KanbanSurface extends SurfaceType {
|
|
8
|
+
readonly type = "kanban";
|
|
9
|
+
readonly title = "Smart Project Management";
|
|
10
|
+
readonly description = "AI-enhanced project tracking \u2014 tasks automatically move from backlog to completion";
|
|
11
|
+
getCommand(ctx: SurfaceContext): string;
|
|
12
|
+
getStatusEntries(ctx: SurfaceContext, data: LiveData): StatusEntry[];
|
|
13
|
+
getNotificationRules(): NotificationRule[];
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=kanban.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kanban.d.ts","sourceRoot":"","sources":["../../../../src/lib/workspace/surfaces/kanban.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAEpF,qBAAa,aAAc,SAAQ,WAAW;IAC5C,QAAQ,CAAC,IAAI,YAAW;IACxB,QAAQ,CAAC,KAAK,8BAA6B;IAC3C,QAAQ,CAAC,WAAW,6FAAuF;IAE3G,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;IAKvC,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,GAAG,WAAW,EAAE;IAepE,oBAAoB,IAAI,gBAAgB,EAAE;CAkB3C"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @purpose Smart Project Management Surface — AI-enhanced project tracking with automated issue resolution
|
|
3
|
+
*/
|
|
4
|
+
import { SurfaceType } from "../surface-type.js";
|
|
5
|
+
export class KanbanSurface extends SurfaceType {
|
|
6
|
+
type = "kanban";
|
|
7
|
+
title = "Smart Project Management";
|
|
8
|
+
description = "AI-enhanced project tracking — tasks automatically move from backlog to completion";
|
|
9
|
+
getCommand(ctx) {
|
|
10
|
+
// Use the existing kanban command with live refresh
|
|
11
|
+
return `watch -n 10 "echo '🤖 Smart Project Management' && echo '════════════════════════════════' && echo '' && jfl kanban ls --compact 2>/dev/null || (echo '🚀 Self-Driving Project Board' && echo '' && echo 'File a GitHub issue and watch AI agents fix it!' && echo 'Issues move automatically: backlog → in progress → done')"`;
|
|
12
|
+
}
|
|
13
|
+
getStatusEntries(ctx, data) {
|
|
14
|
+
const entries = [];
|
|
15
|
+
// TODO: Integrate with actual kanban data when available
|
|
16
|
+
// For now, return basic placeholder entries
|
|
17
|
+
entries.push({
|
|
18
|
+
label: "Kanban",
|
|
19
|
+
value: "GitHub Issues",
|
|
20
|
+
color: "cyan",
|
|
21
|
+
});
|
|
22
|
+
return entries;
|
|
23
|
+
}
|
|
24
|
+
getNotificationRules() {
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
event: "kanban:high_priority_backlog",
|
|
28
|
+
condition: () => false, // TODO: Connect to actual kanban data
|
|
29
|
+
title: "🔥 High Priority Tasks",
|
|
30
|
+
body: () => "High priority tasks in backlog need attention",
|
|
31
|
+
urgency: "normal",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
event: "kanban:stale_in_progress",
|
|
35
|
+
condition: () => false, // TODO: Connect to actual kanban data
|
|
36
|
+
title: "⏰ Stale In Progress",
|
|
37
|
+
body: () => "Tasks in progress for >7 days",
|
|
38
|
+
urgency: "normal",
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=kanban.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kanban.js","sourceRoot":"","sources":["../../../../src/lib/workspace/surfaces/kanban.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,MAAM,OAAO,aAAc,SAAQ,WAAW;IACnC,IAAI,GAAG,QAAQ,CAAA;IACf,KAAK,GAAG,0BAA0B,CAAA;IAClC,WAAW,GAAG,oFAAoF,CAAA;IAE3G,UAAU,CAAC,GAAmB;QAC5B,oDAAoD;QACpD,OAAO,gUAAgU,CAAA;IACzU,CAAC;IAED,gBAAgB,CAAC,GAAmB,EAAE,IAAc;QAClD,MAAM,OAAO,GAAkB,EAAE,CAAA;QAEjC,yDAAyD;QACzD,4CAA4C;QAE5C,OAAO,CAAC,IAAI,CAAC;YACX,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,eAAe;YACtB,KAAK,EAAE,MAAM;SACd,CAAC,CAAA;QAEF,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,oBAAoB;QAClB,OAAO;YACL;gBACE,KAAK,EAAE,8BAA8B;gBACrC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,sCAAsC;gBAC9D,KAAK,EAAE,wBAAwB;gBAC/B,IAAI,EAAE,GAAG,EAAE,CAAC,+CAA+C;gBAC3D,OAAO,EAAE,QAAQ;aAClB;YACD;gBACE,KAAK,EAAE,0BAA0B;gBACjC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,sCAAsC;gBAC9D,KAAK,EAAE,qBAAqB;gBAC5B,IAAI,EAAE,GAAG,EAAE,CAAC,+BAA+B;gBAC3C,OAAO,EAAE,QAAQ;aAClB;SACF,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @purpose System Intelligence Surface — Real-time development environment monitoring and optimization insights
|
|
3
|
+
*/
|
|
4
|
+
import type { StatusEntry } from "../backend.js";
|
|
5
|
+
import { SurfaceType } from "../surface-type.js";
|
|
6
|
+
import type { SurfaceContext, LiveData, NotificationRule } from "../surface-type.js";
|
|
7
|
+
export declare class PhysicalWorldSurface extends SurfaceType {
|
|
8
|
+
readonly type = "physical-world";
|
|
9
|
+
readonly title = "System Intelligence";
|
|
10
|
+
readonly description = "Real-time system monitoring, build status, and development environment optimization";
|
|
11
|
+
getCommand(ctx: SurfaceContext): string;
|
|
12
|
+
getStatusEntries(ctx: SurfaceContext, data: LiveData): StatusEntry[];
|
|
13
|
+
getNotificationRules(): NotificationRule[];
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=physical-world.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physical-world.d.ts","sourceRoot":"","sources":["../../../../src/lib/workspace/surfaces/physical-world.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAEpF,qBAAa,oBAAqB,SAAQ,WAAW;IACnD,QAAQ,CAAC,IAAI,oBAAmB;IAChC,QAAQ,CAAC,KAAK,yBAAwB;IACtC,QAAQ,CAAC,WAAW,yFAAwF;IAE5G,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;IAKvC,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,GAAG,WAAW,EAAE;IAMpE,oBAAoB,IAAI,gBAAgB,EAAE;CAkB3C"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @purpose System Intelligence Surface — Real-time development environment monitoring and optimization insights
|
|
3
|
+
*/
|
|
4
|
+
import { SurfaceType } from "../surface-type.js";
|
|
5
|
+
export class PhysicalWorldSurface extends SurfaceType {
|
|
6
|
+
type = "physical-world";
|
|
7
|
+
title = "System Intelligence";
|
|
8
|
+
description = "Real-time system monitoring, build status, and development environment optimization";
|
|
9
|
+
getCommand(ctx) {
|
|
10
|
+
// Show user-friendly system status and build health
|
|
11
|
+
return `jfl telemetry monitor --live --filter system 2>/dev/null || (echo "🔧 System Intelligence" && echo "" && echo "💻 Environment Status" && echo "CPU: $(ps -o pcpu= -p $$ 2>/dev/null || echo 'N/A')% (optimal)" && echo "Memory: $(ps -o rss= -p $$ 2>/dev/null | awk '{print int($1/1024)}' || echo 'N/A')MB" && echo "Build: clean" && echo "" && echo "🧠 Smart Monitoring" && echo "Analyzing development patterns..." && echo "Optimizing build performance..." && echo "Learning your workflow...")`;
|
|
12
|
+
}
|
|
13
|
+
getStatusEntries(ctx, data) {
|
|
14
|
+
// For now, return empty since we don't have live data integration
|
|
15
|
+
// TODO: Connect to actual physical-world data pipeline
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
getNotificationRules() {
|
|
19
|
+
return [
|
|
20
|
+
{
|
|
21
|
+
event: "physical_world:thermal_warning",
|
|
22
|
+
condition: () => false, // TODO: Connect to actual data
|
|
23
|
+
title: "🔥 Thermal Warning",
|
|
24
|
+
body: () => "System thermal state critical",
|
|
25
|
+
urgency: "critical",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
event: "physical_world:high_cpu",
|
|
29
|
+
condition: () => false, // TODO: Connect to actual data
|
|
30
|
+
title: "⚡ High CPU Usage",
|
|
31
|
+
body: () => "CPU usage above 90%",
|
|
32
|
+
urgency: "normal",
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=physical-world.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"physical-world.js","sourceRoot":"","sources":["../../../../src/lib/workspace/surfaces/physical-world.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,MAAM,OAAO,oBAAqB,SAAQ,WAAW;IAC1C,IAAI,GAAG,gBAAgB,CAAA;IACvB,KAAK,GAAG,qBAAqB,CAAA;IAC7B,WAAW,GAAG,qFAAqF,CAAA;IAE5G,UAAU,CAAC,GAAmB;QAC5B,oDAAoD;QACpD,OAAO,0eAA0e,CAAA;IACnf,CAAC;IAED,gBAAgB,CAAC,GAAmB,EAAE,IAAc;QAClD,kEAAkE;QAClE,uDAAuD;QACvD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,oBAAoB;QAClB,OAAO;YACL;gBACE,KAAK,EAAE,gCAAgC;gBACvC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,+BAA+B;gBACvD,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,GAAG,EAAE,CAAC,+BAA+B;gBAC3C,OAAO,EAAE,UAAU;aACpB;YACD;gBACE,KAAK,EAAE,yBAAyB;gBAChC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,+BAA+B;gBACvD,KAAK,EAAE,kBAAkB;gBACzB,IAAI,EAAE,GAAG,EAAE,CAAC,qBAAqB;gBACjC,OAAO,EAAE,QAAQ;aAClB;SACF,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sidebar Surface
|
|
3
|
+
*
|
|
4
|
+
* Compact always-on sidebar showing all GTMs in a portfolio.
|
|
5
|
+
* Active GTMs show agent status, idle ones can be launched.
|
|
6
|
+
* Notifications accumulate instead of toasting.
|
|
7
|
+
*
|
|
8
|
+
* @purpose Portfolio sidebar — GTM status, notifications, session switching
|
|
9
|
+
*/
|
|
10
|
+
import type { StatusEntry } from "../backend.js";
|
|
11
|
+
import { SurfaceType } from "../surface-type.js";
|
|
12
|
+
import type { SurfaceContext, LiveData, NotificationRule } from "../surface-type.js";
|
|
13
|
+
export declare class SidebarSurface extends SurfaceType {
|
|
14
|
+
readonly type = "sidebar";
|
|
15
|
+
readonly title = "Sidebar";
|
|
16
|
+
readonly description = "Portfolio sidebar \u2014 all GTMs, agent status, notifications";
|
|
17
|
+
getCommand(ctx: SurfaceContext): string;
|
|
18
|
+
getStatusEntries(_ctx: SurfaceContext, data: LiveData): StatusEntry[];
|
|
19
|
+
getNotificationRules(): NotificationRule[];
|
|
20
|
+
getUpdateInterval(): number;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=sidebar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../../src/lib/workspace/surfaces/sidebar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAEpF,qBAAa,cAAe,SAAQ,WAAW;IAC7C,QAAQ,CAAC,IAAI,aAAY;IACzB,QAAQ,CAAC,KAAK,aAAY;IAC1B,QAAQ,CAAC,WAAW,oEAA8D;IAElF,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;IASvC,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,GAAG,WAAW,EAAE;IAgDrE,oBAAoB,IAAI,gBAAgB,EAAE;IA4B1C,iBAAiB,IAAI,MAAM;CAG5B"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sidebar Surface
|
|
3
|
+
*
|
|
4
|
+
* Compact always-on sidebar showing all GTMs in a portfolio.
|
|
5
|
+
* Active GTMs show agent status, idle ones can be launched.
|
|
6
|
+
* Notifications accumulate instead of toasting.
|
|
7
|
+
*
|
|
8
|
+
* @purpose Portfolio sidebar — GTM status, notifications, session switching
|
|
9
|
+
*/
|
|
10
|
+
import { SurfaceType } from "../surface-type.js";
|
|
11
|
+
export class SidebarSurface extends SurfaceType {
|
|
12
|
+
type = "sidebar";
|
|
13
|
+
title = "Sidebar";
|
|
14
|
+
description = "Portfolio sidebar — all GTMs, agent status, notifications";
|
|
15
|
+
getCommand(ctx) {
|
|
16
|
+
// Try compiled JS first (dist), fall back to tsx for dev
|
|
17
|
+
const distPath = `${ctx.projectRoot}/node_modules/@jfl/cli/dist/lib/workspace/sidebar-runner.js`;
|
|
18
|
+
const srcPath = `${ctx.projectRoot}/src/lib/workspace/sidebar-runner.ts`;
|
|
19
|
+
// Use jfl's own dist if installed globally
|
|
20
|
+
return `node ${distPath} "${ctx.projectRoot}" 2>/dev/null || npx tsx ${srcPath} "${ctx.projectRoot}" 2>/dev/null || node --import tsx/esm ${srcPath} "${ctx.projectRoot}"`;
|
|
21
|
+
}
|
|
22
|
+
getStatusEntries(_ctx, data) {
|
|
23
|
+
const entries = [];
|
|
24
|
+
const children = data.childProjects || [];
|
|
25
|
+
entries.push({ label: "PORTFOLIO", value: "", color: "cyan" });
|
|
26
|
+
if (children.length === 0) {
|
|
27
|
+
entries.push({ label: " No GTMs", value: "discovered", color: "gray" });
|
|
28
|
+
return entries;
|
|
29
|
+
}
|
|
30
|
+
let idx = 1;
|
|
31
|
+
for (const child of children) {
|
|
32
|
+
const icon = child.health === "healthy" ? "🟢"
|
|
33
|
+
: child.health === "degraded" ? "🔴"
|
|
34
|
+
: "⚫";
|
|
35
|
+
let detail = "";
|
|
36
|
+
if (child.activeAgents && child.activeAgents > 0) {
|
|
37
|
+
detail = `${child.activeAgents} agent${child.activeAgents > 1 ? "s" : ""}`;
|
|
38
|
+
if (child.evalScore !== undefined) {
|
|
39
|
+
const trend = child.evalTrend === "up" ? "+" : child.evalTrend === "down" ? "-" : "=";
|
|
40
|
+
detail += ` ${trend}${child.evalScore.toFixed(2)}`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
detail = "idle";
|
|
45
|
+
}
|
|
46
|
+
entries.push({
|
|
47
|
+
label: `${icon} ${child.name}`,
|
|
48
|
+
value: `[${idx}] ${detail}`,
|
|
49
|
+
color: child.health === "healthy" ? "green"
|
|
50
|
+
: child.health === "degraded" ? "red"
|
|
51
|
+
: "gray",
|
|
52
|
+
});
|
|
53
|
+
idx++;
|
|
54
|
+
}
|
|
55
|
+
// Cost
|
|
56
|
+
const totalCost = children.reduce((sum, c) => sum + (c.costToday || 0), 0);
|
|
57
|
+
if (totalCost > 0) {
|
|
58
|
+
entries.push({ label: "", value: "", color: "gray" });
|
|
59
|
+
entries.push({ label: "💰 Cost", value: `$${totalCost.toFixed(2)}/today`, color: totalCost > 10 ? "yellow" : "green" });
|
|
60
|
+
}
|
|
61
|
+
return entries;
|
|
62
|
+
}
|
|
63
|
+
getNotificationRules() {
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
event: "agent:session_complete",
|
|
67
|
+
condition: (data) => {
|
|
68
|
+
const sessions = data.agentSessions || [];
|
|
69
|
+
return sessions.some((s) => s.status === "completed");
|
|
70
|
+
},
|
|
71
|
+
title: "Agent done",
|
|
72
|
+
body: (data) => {
|
|
73
|
+
const s = (data.agentSessions || []).find((s) => s.status === "completed");
|
|
74
|
+
return s ? `${s.agentName}: ${s.delta > 0 ? "+" : ""}${s.delta.toFixed(4)}` : "completed";
|
|
75
|
+
},
|
|
76
|
+
urgency: "normal",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
event: "agent:needs_input",
|
|
80
|
+
title: "Agent needs input",
|
|
81
|
+
urgency: "critical",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
event: "agent:error",
|
|
85
|
+
title: "Agent error",
|
|
86
|
+
urgency: "critical",
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
getUpdateInterval() {
|
|
91
|
+
return 5000;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=sidebar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar.js","sourceRoot":"","sources":["../../../../src/lib/workspace/surfaces/sidebar.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @purpose Tmux backend —
|
|
2
|
+
* @purpose Tmux backend — sidebar via dedicated pane, notifications via display-message, status via status-right
|
|
3
3
|
*/
|
|
4
4
|
import type { WorkspaceBackend, BackendCapabilities, CreateSurfaceOpts, StatusEntry, LogEntry, NotificationOpts } from "./backend.js";
|
|
5
5
|
export declare class TmuxAdapter implements WorkspaceBackend {
|
|
6
6
|
readonly name = "tmux";
|
|
7
7
|
private sessionName;
|
|
8
|
+
private sidebarPaneId;
|
|
9
|
+
private statusEntries;
|
|
8
10
|
isAvailable(): boolean;
|
|
9
11
|
connect(): Promise<void>;
|
|
10
12
|
disconnect(): Promise<void>;
|
|
@@ -18,10 +20,11 @@ export declare class TmuxAdapter implements WorkspaceBackend {
|
|
|
18
20
|
splitSurface(id: string, direction: "horizontal" | "vertical"): Promise<string>;
|
|
19
21
|
focusSurface(id: string): Promise<void>;
|
|
20
22
|
sendText(surfaceId: string, text: string): Promise<void>;
|
|
21
|
-
setStatus(
|
|
22
|
-
setProgress(_surfaceId: string,
|
|
23
|
-
addLog(_surfaceId: string,
|
|
24
|
-
notify(
|
|
23
|
+
setStatus(surfaceId: string, entries: StatusEntry[]): Promise<void>;
|
|
24
|
+
setProgress(_surfaceId: string, label: string, value: number): Promise<void>;
|
|
25
|
+
addLog(_surfaceId: string, entry: LogEntry): Promise<void>;
|
|
26
|
+
notify(opts: NotificationOpts): Promise<void>;
|
|
27
|
+
private updateTmuxStatusBar;
|
|
25
28
|
private escapeForTmux;
|
|
26
29
|
}
|
|
27
30
|
//# sourceMappingURL=tmux-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-adapter.d.ts","sourceRoot":"","sources":["../../../src/lib/workspace/tmux-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"tmux-adapter.d.ts","sourceRoot":"","sources":["../../../src/lib/workspace/tmux-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,gBAAgB,EACjB,MAAM,cAAc,CAAA;AAErB,qBAAa,WAAY,YAAW,gBAAgB;IAClD,QAAQ,CAAC,IAAI,UAAS;IACtB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,aAAa,CAAmC;IAExD,WAAW,IAAI,OAAO;IAShB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,YAAY,IAAI,mBAAmB;IAInC,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,aAAa;IASf,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAe9C,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkCvD,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAM/E,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxD,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnE,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5E,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAK1D,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnD,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,aAAa;CAGtB"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @purpose Tmux backend —
|
|
2
|
+
* @purpose Tmux backend — sidebar via dedicated pane, notifications via display-message, status via status-right
|
|
3
3
|
*/
|
|
4
4
|
import { execSync } from "child_process";
|
|
5
5
|
export class TmuxAdapter {
|
|
6
6
|
name = "tmux";
|
|
7
7
|
sessionName = "";
|
|
8
|
+
sidebarPaneId = null;
|
|
9
|
+
statusEntries = new Map();
|
|
8
10
|
isAvailable() {
|
|
9
11
|
try {
|
|
10
12
|
execSync("which tmux", { stdio: "ignore" });
|
|
@@ -21,7 +23,7 @@ export class TmuxAdapter {
|
|
|
21
23
|
// No persistent connection
|
|
22
24
|
}
|
|
23
25
|
capabilities() {
|
|
24
|
-
return { sidebar:
|
|
26
|
+
return { sidebar: true, notifications: true, mouse: true };
|
|
25
27
|
}
|
|
26
28
|
exec(cmd) {
|
|
27
29
|
try {
|
|
@@ -94,11 +96,40 @@ export class TmuxAdapter {
|
|
|
94
96
|
async sendText(surfaceId, text) {
|
|
95
97
|
this.exec(`tmux send-keys -t "${surfaceId}" "${this.escapeForTmux(text)}" Enter`);
|
|
96
98
|
}
|
|
97
|
-
//
|
|
98
|
-
async setStatus(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
// ─── Sidebar + notifications via tmux status bar + display-message ────────
|
|
100
|
+
async setStatus(surfaceId, entries) {
|
|
101
|
+
this.statusEntries.set(surfaceId, entries);
|
|
102
|
+
this.updateTmuxStatusBar();
|
|
103
|
+
}
|
|
104
|
+
async setProgress(_surfaceId, label, value) {
|
|
105
|
+
const pct = Math.round(value * 100);
|
|
106
|
+
const bar = "█".repeat(Math.floor(pct / 10)) + "░".repeat(10 - Math.floor(pct / 10));
|
|
107
|
+
this.exec(`tmux set-option -t "${this.sessionName}" status-right "${label}: ${bar} ${pct}%"`);
|
|
108
|
+
}
|
|
109
|
+
async addLog(_surfaceId, entry) {
|
|
110
|
+
const prefix = entry.level === "error" ? "❌" : entry.level === "warn" ? "⚠️" : "ℹ️";
|
|
111
|
+
this.exec(`tmux display-message -t "${this.sessionName}" "${prefix} ${this.escapeForTmux(entry.message)}"`);
|
|
112
|
+
}
|
|
113
|
+
async notify(opts) {
|
|
114
|
+
const urgencyIcon = opts.urgency === "critical" ? "🔴" : opts.urgency === "normal" ? "🔵" : "⚪";
|
|
115
|
+
const msg = opts.body ? `${opts.title}: ${opts.body}` : opts.title;
|
|
116
|
+
this.exec(`tmux display-message -t "${this.sessionName}" "${urgencyIcon} ${this.escapeForTmux(msg)}"`);
|
|
117
|
+
}
|
|
118
|
+
updateTmuxStatusBar() {
|
|
119
|
+
// Aggregate top-level status entries into tmux status-right
|
|
120
|
+
const parts = [];
|
|
121
|
+
for (const [_id, entries] of this.statusEntries) {
|
|
122
|
+
for (const e of entries.slice(0, 2)) {
|
|
123
|
+
if (e.value)
|
|
124
|
+
parts.push(`${e.label}:${e.value}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (parts.length > 0) {
|
|
128
|
+
const statusText = parts.slice(0, 4).join(" │ ");
|
|
129
|
+
this.exec(`tmux set-option -t "${this.sessionName}" status-right " ${statusText} "`);
|
|
130
|
+
this.exec(`tmux set-option -t "${this.sessionName}" status-right-length 80`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
102
133
|
escapeForTmux(text) {
|
|
103
134
|
return text.replace(/"/g, '\\"').replace(/\$/g, "\\$");
|
|
104
135
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tmux-adapter.js","sourceRoot":"","sources":["../../../src/lib/workspace/tmux-adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"tmux-adapter.js","sourceRoot":"","sources":["../../../src/lib/workspace/tmux-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Tmux Sidebar Runner
|
|
4
|
+
*
|
|
5
|
+
* Renders live StatusEntry data in a narrow terminal pane.
|
|
6
|
+
* Polls Context Hub + files on the same schedule as DataPipeline.
|
|
7
|
+
* This gives tmux users the sidebar experience that cmux gets natively.
|
|
8
|
+
*
|
|
9
|
+
* Run: node --import tsx/esm tmux-sidebar.ts <projectRoot>
|
|
10
|
+
*
|
|
11
|
+
* @purpose Live sidebar for tmux — renders StatusEntries from hub + file data
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=tmux-sidebar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-sidebar.d.ts","sourceRoot":"","sources":["../../../src/lib/workspace/tmux-sidebar.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Tmux Sidebar Runner
|
|
4
|
+
*
|
|
5
|
+
* Renders live StatusEntry data in a narrow terminal pane.
|
|
6
|
+
* Polls Context Hub + files on the same schedule as DataPipeline.
|
|
7
|
+
* This gives tmux users the sidebar experience that cmux gets natively.
|
|
8
|
+
*
|
|
9
|
+
* Run: node --import tsx/esm tmux-sidebar.ts <projectRoot>
|
|
10
|
+
*
|
|
11
|
+
* @purpose Live sidebar for tmux — renders StatusEntries from hub + file data
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
14
|
+
import { join } from "path";
|
|
15
|
+
const projectRoot = process.argv[2] || process.cwd();
|
|
16
|
+
const POLL_INTERVAL = 5000;
|
|
17
|
+
// ─── Color helpers (ANSI) ─────────────────────────────────────────────────
|
|
18
|
+
const COLORS = {
|
|
19
|
+
green: "\x1b[32m",
|
|
20
|
+
red: "\x1b[31m",
|
|
21
|
+
yellow: "\x1b[33m",
|
|
22
|
+
cyan: "\x1b[36m",
|
|
23
|
+
gray: "\x1b[90m",
|
|
24
|
+
bold: "\x1b[1m",
|
|
25
|
+
dim: "\x1b[2m",
|
|
26
|
+
reset: "\x1b[0m",
|
|
27
|
+
};
|
|
28
|
+
function c(color, text) {
|
|
29
|
+
return `${COLORS[color] || ""}${text}${COLORS.reset}`;
|
|
30
|
+
}
|
|
31
|
+
function readJson(path) {
|
|
32
|
+
if (!existsSync(path))
|
|
33
|
+
return null;
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function collectData() {
|
|
42
|
+
const config = readJson(join(projectRoot, ".jfl", "config.json")) || {};
|
|
43
|
+
const data = {
|
|
44
|
+
projectName: config.name || projectRoot.split("/").pop() || "?",
|
|
45
|
+
projectType: config.type || "?",
|
|
46
|
+
evalComposite: null,
|
|
47
|
+
evalDelta: null,
|
|
48
|
+
evalTrend: "?",
|
|
49
|
+
agents: [],
|
|
50
|
+
activeFlows: 0,
|
|
51
|
+
eventCount: 0,
|
|
52
|
+
trainingTuples: 0,
|
|
53
|
+
trainingWinRate: 0,
|
|
54
|
+
services: [],
|
|
55
|
+
kanbanBacklog: 0,
|
|
56
|
+
kanbanInProgress: 0,
|
|
57
|
+
hubRunning: false,
|
|
58
|
+
};
|
|
59
|
+
// Eval data
|
|
60
|
+
const evalPath = join(projectRoot, ".jfl", "eval", "eval.jsonl");
|
|
61
|
+
if (existsSync(evalPath)) {
|
|
62
|
+
try {
|
|
63
|
+
const lines = readFileSync(evalPath, "utf-8").trim().split("\n").filter(Boolean);
|
|
64
|
+
if (lines.length > 0) {
|
|
65
|
+
const latest = JSON.parse(lines[lines.length - 1]);
|
|
66
|
+
data.evalComposite = latest.composite ?? null;
|
|
67
|
+
if (lines.length > 1) {
|
|
68
|
+
const prev = JSON.parse(lines[lines.length - 2]);
|
|
69
|
+
const prevComposite = prev.composite ?? data.evalComposite;
|
|
70
|
+
data.evalDelta = (data.evalComposite ?? 0) - (prevComposite ?? 0);
|
|
71
|
+
data.evalTrend = data.evalDelta > 0 ? "↑" : data.evalDelta < 0 ? "↓" : "=";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch { }
|
|
76
|
+
}
|
|
77
|
+
// Agents
|
|
78
|
+
const agentsDir = join(projectRoot, ".jfl", "agents");
|
|
79
|
+
if (existsSync(agentsDir)) {
|
|
80
|
+
try {
|
|
81
|
+
const files = readdirSync(agentsDir).filter(f => f.endsWith(".toml"));
|
|
82
|
+
for (const f of files) {
|
|
83
|
+
const name = f.replace(".toml", "");
|
|
84
|
+
data.agents.push({ name, status: "idle" });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch { }
|
|
88
|
+
}
|
|
89
|
+
// Training buffer
|
|
90
|
+
const bufferPath = join(projectRoot, ".jfl", "training-buffer.jsonl");
|
|
91
|
+
if (existsSync(bufferPath)) {
|
|
92
|
+
try {
|
|
93
|
+
const lines = readFileSync(bufferPath, "utf-8").trim().split("\n").filter(Boolean);
|
|
94
|
+
data.trainingTuples = lines.length;
|
|
95
|
+
let improved = 0;
|
|
96
|
+
for (const line of lines) {
|
|
97
|
+
try {
|
|
98
|
+
const t = JSON.parse(line);
|
|
99
|
+
if (t.outcome === "improved" || (t.reward && t.reward > 0))
|
|
100
|
+
improved++;
|
|
101
|
+
}
|
|
102
|
+
catch { }
|
|
103
|
+
}
|
|
104
|
+
data.trainingWinRate = lines.length > 0 ? improved / lines.length : 0;
|
|
105
|
+
}
|
|
106
|
+
catch { }
|
|
107
|
+
}
|
|
108
|
+
// Services
|
|
109
|
+
const services = config.registered_services || [];
|
|
110
|
+
for (const s of services) {
|
|
111
|
+
data.services.push({ name: s.name, type: s.type || "?" });
|
|
112
|
+
}
|
|
113
|
+
// Flows
|
|
114
|
+
const flowsPath = join(projectRoot, ".jfl", "flows", "self-driving.yaml");
|
|
115
|
+
if (existsSync(flowsPath)) {
|
|
116
|
+
try {
|
|
117
|
+
const content = readFileSync(flowsPath, "utf-8");
|
|
118
|
+
const matches = content.match(/enabled:\s*true/g);
|
|
119
|
+
data.activeFlows = matches ? matches.length : 0;
|
|
120
|
+
}
|
|
121
|
+
catch { }
|
|
122
|
+
}
|
|
123
|
+
// Hub check
|
|
124
|
+
const portFile = join(projectRoot, ".jfl", "context-hub.port");
|
|
125
|
+
if (existsSync(portFile)) {
|
|
126
|
+
const port = readFileSync(portFile, "utf-8").trim();
|
|
127
|
+
try {
|
|
128
|
+
// Quick sync check - just see if port file exists and is recent
|
|
129
|
+
data.hubRunning = true;
|
|
130
|
+
}
|
|
131
|
+
catch { }
|
|
132
|
+
}
|
|
133
|
+
// Events (from MAP events file)
|
|
134
|
+
const eventsPath = join(projectRoot, ".jfl", "map-events.jsonl");
|
|
135
|
+
if (existsSync(eventsPath)) {
|
|
136
|
+
try {
|
|
137
|
+
const content = readFileSync(eventsPath, "utf-8").trim();
|
|
138
|
+
data.eventCount = content.split("\n").filter(Boolean).length;
|
|
139
|
+
}
|
|
140
|
+
catch { }
|
|
141
|
+
}
|
|
142
|
+
return data;
|
|
143
|
+
}
|
|
144
|
+
// ─── Render ───────────────────────────────────────────────────────────────
|
|
145
|
+
function render(data) {
|
|
146
|
+
const lines = [];
|
|
147
|
+
const W = process.stdout.columns || 30;
|
|
148
|
+
const sep = c("gray", "─".repeat(Math.min(W, 30)));
|
|
149
|
+
// Header
|
|
150
|
+
lines.push("");
|
|
151
|
+
lines.push(c("bold", ` ${data.projectName}`));
|
|
152
|
+
lines.push(c("gray", ` ${data.projectType}`));
|
|
153
|
+
lines.push(sep);
|
|
154
|
+
// Eval
|
|
155
|
+
if (data.evalComposite !== null) {
|
|
156
|
+
const score = data.evalComposite.toFixed(3);
|
|
157
|
+
const trend = data.evalTrend === "↑" ? c("green", "↑") : data.evalTrend === "↓" ? c("red", "↓") : c("gray", "=");
|
|
158
|
+
const delta = data.evalDelta !== null ? (data.evalDelta > 0 ? c("green", `+${data.evalDelta.toFixed(3)}`) : data.evalDelta < 0 ? c("red", data.evalDelta.toFixed(3)) : "") : "";
|
|
159
|
+
lines.push(c("cyan", " EVAL"));
|
|
160
|
+
lines.push(` ${trend} ${score} ${delta}`);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
lines.push(c("cyan", " EVAL"));
|
|
164
|
+
lines.push(c("gray", " no data yet"));
|
|
165
|
+
}
|
|
166
|
+
lines.push(sep);
|
|
167
|
+
// Agents
|
|
168
|
+
lines.push(c("cyan", ` AGENTS (${data.agents.length})`));
|
|
169
|
+
if (data.agents.length === 0) {
|
|
170
|
+
lines.push(c("gray", " none configured"));
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
for (const a of data.agents.slice(0, 8)) {
|
|
174
|
+
const icon = a.status === "active" ? c("green", "●") : c("gray", "○");
|
|
175
|
+
lines.push(` ${icon} ${a.name}`);
|
|
176
|
+
}
|
|
177
|
+
if (data.agents.length > 8) {
|
|
178
|
+
lines.push(c("gray", ` +${data.agents.length - 8} more`));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
lines.push(sep);
|
|
182
|
+
// Training
|
|
183
|
+
if (data.trainingTuples > 0) {
|
|
184
|
+
lines.push(c("cyan", " TRAINING"));
|
|
185
|
+
lines.push(` ${data.trainingTuples} tuples`);
|
|
186
|
+
const wr = (data.trainingWinRate * 100).toFixed(0);
|
|
187
|
+
const wrColor = data.trainingWinRate > 0.3 ? "green" : data.trainingWinRate > 0.1 ? "yellow" : "gray";
|
|
188
|
+
lines.push(` ${c(wrColor, `${wr}% win rate`)}`);
|
|
189
|
+
lines.push(sep);
|
|
190
|
+
}
|
|
191
|
+
// Services
|
|
192
|
+
if (data.services.length > 0) {
|
|
193
|
+
lines.push(c("cyan", ` SERVICES (${data.services.length})`));
|
|
194
|
+
for (const s of data.services) {
|
|
195
|
+
lines.push(c("gray", ` · ${s.name} (${s.type})`));
|
|
196
|
+
}
|
|
197
|
+
lines.push(sep);
|
|
198
|
+
}
|
|
199
|
+
// Flows
|
|
200
|
+
if (data.activeFlows > 0) {
|
|
201
|
+
lines.push(c("cyan", " FLOWS"));
|
|
202
|
+
lines.push(` ${data.activeFlows} active`);
|
|
203
|
+
lines.push(sep);
|
|
204
|
+
}
|
|
205
|
+
// Hub
|
|
206
|
+
const hubIcon = data.hubRunning ? c("green", "●") : c("red", "○");
|
|
207
|
+
lines.push(` ${hubIcon} Hub ${data.hubRunning ? "running" : "stopped"}`);
|
|
208
|
+
if (data.eventCount > 0) {
|
|
209
|
+
lines.push(c("gray", ` ${data.eventCount} events`));
|
|
210
|
+
}
|
|
211
|
+
// Footer
|
|
212
|
+
lines.push("");
|
|
213
|
+
lines.push(c("dim", ` ${new Date().toLocaleTimeString()}`));
|
|
214
|
+
return lines.join("\n");
|
|
215
|
+
}
|
|
216
|
+
// ─── Main loop ────────────────────────────────────────────────────────────
|
|
217
|
+
function clear() {
|
|
218
|
+
process.stdout.write("\x1b[2J\x1b[H");
|
|
219
|
+
}
|
|
220
|
+
function main() {
|
|
221
|
+
const tick = () => {
|
|
222
|
+
const data = collectData();
|
|
223
|
+
clear();
|
|
224
|
+
process.stdout.write(render(data));
|
|
225
|
+
};
|
|
226
|
+
tick();
|
|
227
|
+
setInterval(tick, POLL_INTERVAL);
|
|
228
|
+
}
|
|
229
|
+
main();
|
|
230
|
+
//# sourceMappingURL=tmux-sidebar.js.map
|