loki-mode 7.81.1 → 7.83.0
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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/completion-council.sh +88 -27
- package/autonomy/lib/config-map.sh +61 -15
- package/autonomy/loki +641 -45
- package/autonomy/run.sh +202 -31
- package/completions/_loki +84 -6
- package/completions/loki.bash +25 -7
- package/dashboard/__init__.py +1 -1
- package/dashboard/audit.py +36 -10
- package/dashboard/registry.py +67 -24
- package/dashboard/server.py +131 -74
- package/docs/INSTALLATION.md +2 -2
- package/events/bus.py +17 -1
- package/events/emit.sh +15 -1
- package/loki-ts/dist/loki.js +7 -4
- package/lokistore/cloud.py +17 -1
- package/lokistore/factory.py +6 -1
- package/lokistore/local.py +11 -3
- package/mcp/__init__.py +1 -1
- package/mcp/server.py +16 -4
- package/memory/cross_project.py +74 -5
- package/memory/embeddings.py +19 -1
- package/memory/retrieval.py +81 -153
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/providers/codex.sh +9 -4
- package/memory/tree_index.py +0 -499
- package/memory/tree_search.py +0 -305
package/dashboard/registry.py
CHANGED
|
@@ -140,6 +140,9 @@ def register_project(
|
|
|
140
140
|
path: str,
|
|
141
141
|
name: Optional[str] = None,
|
|
142
142
|
alias: Optional[str] = None,
|
|
143
|
+
pid: Optional[int] = None,
|
|
144
|
+
port: Optional[int] = None,
|
|
145
|
+
status: Optional[str] = None,
|
|
143
146
|
) -> dict:
|
|
144
147
|
"""
|
|
145
148
|
Register a project in the registry.
|
|
@@ -148,6 +151,18 @@ def register_project(
|
|
|
148
151
|
path: Absolute path to the project directory
|
|
149
152
|
name: Display name (defaults to directory name)
|
|
150
153
|
alias: Short alias for CLI usage
|
|
154
|
+
pid: Live runtime pid for the project's current build (optional)
|
|
155
|
+
port: Live runtime port for the project's current build (optional)
|
|
156
|
+
status: Runtime status override, e.g. "active" / "running" (optional)
|
|
157
|
+
|
|
158
|
+
The pid / port / status kwargs let a caller register a project AND set its
|
|
159
|
+
runtime fields in one atomic, locked load->mutate->save. Before this, the
|
|
160
|
+
runner had to call register_project() and then do a SECOND, unlocked
|
|
161
|
+
load-mutate-save to stamp pid/port/status, which lost-updates a concurrent
|
|
162
|
+
writer (two writers each load the registry, set their own runtime fields,
|
|
163
|
+
and save -- the last save wins and silently drops the other's entry). Set
|
|
164
|
+
these here so the whole change happens inside _registry_lock(). When all
|
|
165
|
+
three are omitted the behavior is unchanged (backward compatible).
|
|
151
166
|
|
|
152
167
|
Returns:
|
|
153
168
|
The registered project entry
|
|
@@ -188,6 +203,16 @@ def register_project(
|
|
|
188
203
|
}
|
|
189
204
|
registry["projects"][project_id] = project
|
|
190
205
|
|
|
206
|
+
# Atomically stamp runtime fields inside the same lock (both the create
|
|
207
|
+
# and update branches). None means "leave as-is" so omitting these
|
|
208
|
+
# keeps the legacy behavior.
|
|
209
|
+
if pid is not None:
|
|
210
|
+
project["pid"] = pid
|
|
211
|
+
if port is not None:
|
|
212
|
+
project["port"] = port
|
|
213
|
+
if status is not None:
|
|
214
|
+
project["status"] = status
|
|
215
|
+
|
|
191
216
|
_save_registry(registry)
|
|
192
217
|
return project
|
|
193
218
|
|
|
@@ -438,7 +463,6 @@ def sync_registry_with_discovery() -> dict:
|
|
|
438
463
|
Returns:
|
|
439
464
|
Summary of sync results
|
|
440
465
|
"""
|
|
441
|
-
registry = _load_registry()
|
|
442
466
|
discovered = discover_projects()
|
|
443
467
|
|
|
444
468
|
# Track results
|
|
@@ -446,31 +470,50 @@ def sync_registry_with_discovery() -> dict:
|
|
|
446
470
|
updated = []
|
|
447
471
|
missing = []
|
|
448
472
|
|
|
449
|
-
#
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
# New project
|
|
458
|
-
project = register_project(path)
|
|
459
|
-
added.append(project)
|
|
460
|
-
else:
|
|
461
|
-
# Update existing
|
|
462
|
-
project = registry["projects"][project_id]
|
|
463
|
-
project["has_loki_dir"] = True
|
|
464
|
-
project["updated_at"] = datetime.now(timezone.utc).isoformat()
|
|
465
|
-
updated.append(project)
|
|
473
|
+
# Mutate a single registry copy under the lock and save it ONCE at the end.
|
|
474
|
+
# Previously this loaded the registry, then called register_project() in the
|
|
475
|
+
# loop (which loads+mutates+saves its OWN copy), and finally saved the stale
|
|
476
|
+
# original over the top -- silently dropping every newly added project (the
|
|
477
|
+
# summary said "added: N" while the on-disk registry kept zero of them). All
|
|
478
|
+
# mutations now happen on the same in-memory dict that gets persisted.
|
|
479
|
+
with _registry_lock():
|
|
480
|
+
registry = _load_registry()
|
|
466
481
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
482
|
+
# Add/update discovered projects
|
|
483
|
+
for project_info in discovered:
|
|
484
|
+
path = project_info["path"]
|
|
485
|
+
project_id = _generate_project_id(path)
|
|
486
|
+
|
|
487
|
+
if project_id not in registry["projects"]:
|
|
488
|
+
# New project
|
|
489
|
+
now = datetime.now(timezone.utc).isoformat()
|
|
490
|
+
project = {
|
|
491
|
+
"id": project_id,
|
|
492
|
+
"path": path,
|
|
493
|
+
"name": os.path.basename(path),
|
|
494
|
+
"alias": None,
|
|
495
|
+
"registered_at": now,
|
|
496
|
+
"updated_at": now,
|
|
497
|
+
"last_accessed": None,
|
|
498
|
+
"has_loki_dir": os.path.isdir(os.path.join(path, ".loki")),
|
|
499
|
+
"status": "active",
|
|
500
|
+
}
|
|
501
|
+
registry["projects"][project_id] = project
|
|
502
|
+
added.append(project)
|
|
503
|
+
else:
|
|
504
|
+
# Update existing
|
|
505
|
+
project = registry["projects"][project_id]
|
|
506
|
+
project["has_loki_dir"] = True
|
|
507
|
+
project["updated_at"] = datetime.now(timezone.utc).isoformat()
|
|
508
|
+
updated.append(project)
|
|
472
509
|
|
|
473
|
-
|
|
510
|
+
# Check for missing projects
|
|
511
|
+
for project_id, project in registry["projects"].items():
|
|
512
|
+
if not os.path.isdir(project["path"]):
|
|
513
|
+
project["status"] = "missing"
|
|
514
|
+
missing.append(project)
|
|
515
|
+
|
|
516
|
+
_save_registry(registry)
|
|
474
517
|
|
|
475
518
|
return {
|
|
476
519
|
"added": len(added),
|