moflo 4.10.9 → 4.10.10
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.
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: luminarium
|
|
3
|
+
description: |
|
|
4
|
+
Print the localhost URL for The Luminarium — moflo's daemon dashboard — for the current project.
|
|
5
|
+
Use when the user asks for "the luminarium link", "the moflo dashboard", "the daemon UI", or anything synonymous.
|
|
6
|
+
Each project gets a deterministic port in 33000–33999; the actual bound port is recorded in `.moflo/daemon.lock`.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /luminarium — Project Dashboard Link
|
|
10
|
+
|
|
11
|
+
Surface the URL for The Luminarium (the moflo daemon's localhost UI) for the project that this session is running in. No prompts, no confirmations — print the link and stop.
|
|
12
|
+
|
|
13
|
+
## Procedure
|
|
14
|
+
|
|
15
|
+
1. **Find the project root.** Walk up from `process.cwd()` looking for a `.moflo/` directory. The session's cwd is almost always the project root, so check there first.
|
|
16
|
+
|
|
17
|
+
2. **Read `.moflo/daemon.lock`.** It's a JSON file written by the daemon at bind time. The dashboard port is the `port` field:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{ "pid": 12345, "port": 33421, "startedAt": "...", ... }
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- If the file exists and `port` is a valid number → the daemon is running and bound. Use that port.
|
|
24
|
+
- If the file is missing or `port` is absent/invalid → the daemon is not running. See step 4.
|
|
25
|
+
|
|
26
|
+
3. **Print the link** in a single line, with the path verbatim — Claude Code renders it as clickable:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
The Luminarium: http://localhost:<port>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Nothing else. No banner, no follow-up question, no "what would you like to do?".
|
|
33
|
+
|
|
34
|
+
4. **If the daemon isn't running** (no lock file, or unparseable), say so in one line and offer the start command — don't run it:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
The moflo daemon isn't running for this project. Start it with: npx flo daemon start
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Why read the lock, not compute the port
|
|
41
|
+
|
|
42
|
+
The port is project-deterministic (sha256(projectRoot) mapped into 33000–33999), but if the deterministic port was already taken at bind time the daemon scans forward and binds an alternate. The lock file is the only source of truth for what's actually bound. Do not compute the hash yourself — read the file.
|
|
43
|
+
|
|
44
|
+
## Don't
|
|
45
|
+
|
|
46
|
+
- Don't fall back to any hardcoded port — there is no project-agnostic dashboard port; a literal would route to a foreign daemon on a multi-project machine. If the lock is missing, report "not running".
|
|
47
|
+
- Don't compute the deterministic port and report it as the link when the lock is missing — the daemon may be down, or bound to an alternate port. Report "not running" instead.
|
|
48
|
+
- Don't run `flo daemon start` automatically — the user asked for a link, not for daemon management. Leave starting to `/healer` or the user.
|
|
49
|
+
- Don't open a browser. Print the URL; let the user click.
|
|
50
|
+
|
|
51
|
+
## Output
|
|
52
|
+
|
|
53
|
+
A single line. Examples:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
The Luminarium: http://localhost:33421
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
The moflo daemon isn't running for this project. Start it with: npx flo daemon start
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## See Also
|
|
64
|
+
|
|
65
|
+
- `/healer` — diagnoses and (with `--fix`) starts the daemon if it's not running.
|
|
66
|
+
- `src/cli/services/daemon-port.ts` (and its JS twin `bin/lib/daemon-port.mjs`) — canonical port-resolution helpers; `resolveClientPort()` is what the rest of moflo uses.
|
|
@@ -798,6 +798,14 @@ const DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
798
798
|
.btn-primary { background: #238636; border-color: #2ea043; color: #fff; }
|
|
799
799
|
.btn-primary:hover { background: #2ea043; border-color: #3fb950; }
|
|
800
800
|
.dim { color: #484f58; font-size: 0.75rem; font-style: italic; }
|
|
801
|
+
/* Loading state for tabs whose data is slow on first paint (currently
|
|
802
|
+
Claude Stats, which walks the user's transcript dir — can take 10–15s
|
|
803
|
+
on a long history). Pure-CSS spinner; no image, no framework. */
|
|
804
|
+
.loading-block { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; padding: 48px 16px; color: #8b949e; }
|
|
805
|
+
.loading-block .spinner { width: 28px; height: 28px; border: 3px solid #30363d; border-top-color: #58a6ff; border-radius: 50%; animation: lum-spin 0.85s linear infinite; }
|
|
806
|
+
.loading-block .msg { font-size: 0.9rem; color: #c9d1d9; }
|
|
807
|
+
.loading-block .hint { font-size: 0.8rem; color: #8b949e; font-style: italic; max-width: 480px; text-align: center; line-height: 1.5; }
|
|
808
|
+
@keyframes lum-spin { to { transform: rotate(360deg); } }
|
|
801
809
|
</style>
|
|
802
810
|
</head>
|
|
803
811
|
<body>
|
|
@@ -811,7 +819,7 @@ const DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
811
819
|
<div id="panel-schedules" class="panel" style="display:none"><div id="schedules-active"></div><div id="schedules-events"></div></div>
|
|
812
820
|
<div id="panel-executions" class="panel" style="display:none"></div>
|
|
813
821
|
<div id="panel-memory" class="panel" style="display:none"></div>
|
|
814
|
-
<div id="panel-claude-stats" class="panel" style="display:none"></div>
|
|
822
|
+
<div id="panel-claude-stats" class="panel" style="display:none"><div class="loading-block" role="status" aria-label="Loading Claude Code transcripts"><div class="spinner"></div><div class="msg">Reading Claude Code transcripts…</div><div class="hint">First load can take 10–15 seconds — moflo walks every session file in this project's transcript directory. Subsequent loads in this tab are much faster.</div></div></div>
|
|
815
823
|
<div id="poll-indicator" class="poll-indicator"></div>
|
|
816
824
|
<script>
|
|
817
825
|
// Tab navigation — plain DOM, no framework
|
|
@@ -1139,7 +1147,19 @@ const DASHBOARD_HTML = `<!DOCTYPE html>
|
|
|
1139
1147
|
};
|
|
1140
1148
|
function renderClaudeStats(cs) {
|
|
1141
1149
|
const el = document.getElementById('panel-claude-stats');
|
|
1142
|
-
|
|
1150
|
+
// cs is null on first paint AND on fetch error (Promise chain uses
|
|
1151
|
+
// .catch(() => null)). Render the spinner block on both so the user
|
|
1152
|
+
// sees motion during the 10–15s transcript walk and during a transient
|
|
1153
|
+
// network blip — better than a static "Loading..." that looks frozen.
|
|
1154
|
+
if (!cs) {
|
|
1155
|
+
el.innerHTML =
|
|
1156
|
+
'<div class="loading-block" role="status" aria-label="Loading Claude Code transcripts">' +
|
|
1157
|
+
'<div class="spinner"></div>' +
|
|
1158
|
+
'<div class="msg">Reading Claude Code transcripts…</div>' +
|
|
1159
|
+
'<div class="hint">First load can take 10–15 seconds — moflo walks every session file in this project\\'s transcript directory. Subsequent loads in this tab are much faster.</div>' +
|
|
1160
|
+
'</div>';
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1143
1163
|
|
|
1144
1164
|
// Always-visible disclaimer banner — keeps the scope and limits in
|
|
1145
1165
|
// view so the numbers aren't read as account-wide truth.
|
package/dist/src/cli/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "moflo",
|
|
3
|
-
"version": "4.10.
|
|
3
|
+
"version": "4.10.10",
|
|
4
4
|
"description": "MoFlo — AI agent orchestration for Claude Code. A standalone, opinionated toolkit with semantic memory, learned routing, gates, spells, and the /flo issue-execution skill.",
|
|
5
5
|
"main": "dist/src/cli/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
96
96
|
"@typescript-eslint/parser": "^7.18.0",
|
|
97
97
|
"eslint": "^8.0.0",
|
|
98
|
-
"moflo": "^4.10.
|
|
98
|
+
"moflo": "^4.10.9",
|
|
99
99
|
"tsx": "^4.21.0",
|
|
100
100
|
"typescript": "^5.9.3",
|
|
101
101
|
"vitest": "^4.0.0"
|