loki-mode 5.58.1 → 5.58.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/autonomy/loki +3 -3
- package/dashboard/__init__.py +1 -1
- package/dashboard/migration_engine.py +40 -16
- package/docs/INSTALLATION.md +1 -1
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Multi-agent autonomous startup system. Triggers on "Loki Mode". Takes PRD to deployed product with minimal human intervention. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v5.58.
|
|
6
|
+
# Loki Mode v5.58.2
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -263,4 +263,4 @@ The following features are documented in skill modules but not yet fully automat
|
|
|
263
263
|
| Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
|
|
264
264
|
| Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
|
|
265
265
|
|
|
266
|
-
**v5.58.
|
|
266
|
+
**v5.58.2 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.58.
|
|
1
|
+
5.58.2
|
package/autonomy/loki
CHANGED
|
@@ -5238,7 +5238,7 @@ Tasks:
|
|
|
5238
5238
|
1. Analyze the full codebase structure (languages, frameworks, dependencies, architecture)
|
|
5239
5239
|
2. Create the docs directory: mkdir -p ${migration_dir}/docs
|
|
5240
5240
|
3. Write analysis documentation to ${migration_dir}/docs/analysis.md
|
|
5241
|
-
3. Identify migration seams (logical boundaries for incremental migration) and write them to ${migration_dir}/seams.json as a JSON array of objects with fields: id, name, description, files (array of file paths), dependencies (array of seam ids), priority (high/medium/low)
|
|
5241
|
+
3. Identify migration seams (logical boundaries for incremental migration) and write them to ${migration_dir}/seams.json as a JSON array of objects with fields: id (string, e.g. 'seam-01'), name (string), description (string), type (string: 'module'/'api'/'config'/'adapter'), files (array of file paths), dependencies (array of seam ids), priority (string: 'high'/'medium'/'low')
|
|
5242
5242
|
|
|
5243
5243
|
You MUST create both files. The migration cannot proceed without them.
|
|
5244
5244
|
Write the analysis doc first, then the seams.json."
|
|
@@ -5254,7 +5254,7 @@ Read ${migration_dir}/docs/analysis.md and ${migration_dir}/seams.json for conte
|
|
|
5254
5254
|
|
|
5255
5255
|
Tasks:
|
|
5256
5256
|
1. Identify existing tests and create characterization tests that capture current behavior
|
|
5257
|
-
2. Write ${migration_dir}/features.json as a JSON array of objects with fields: id,
|
|
5257
|
+
2. Write ${migration_dir}/features.json as a JSON array of objects with fields: id (string, e.g. 'F01'), category (string, e.g. 'core'), description (string), characterization_test (string, shell command to verify), passes (boolean, set to true for existing passing behavior), risk (string: 'low'/'medium'/'high')
|
|
5258
5258
|
3. Create a git checkpoint: cd ${codebase_path} && git stash || true
|
|
5259
5259
|
|
|
5260
5260
|
All features in features.json must have passes: true for the gate to pass."
|
|
@@ -5269,7 +5269,7 @@ Migration dir: ${migration_dir}
|
|
|
5269
5269
|
Read ${migration_dir}/docs/analysis.md, ${migration_dir}/seams.json, and ${migration_dir}/features.json for context.
|
|
5270
5270
|
|
|
5271
5271
|
Tasks:
|
|
5272
|
-
1. Create a migration plan and write it to ${migration_dir}/migration-plan.json with fields:
|
|
5272
|
+
1. Create a migration plan and write it to ${migration_dir}/migration-plan.json as a JSON object with fields: version (integer, default 1), strategy (string: 'incremental' or 'big_bang'), steps (array of objects with: id (string), description (string), type (string: 'refactor'/'rewrite'/'config'/'test'), status (string, set to 'completed' after you do the step))
|
|
5273
5273
|
2. Execute the actual code migration transforms in ${codebase_path} -- convert code from the current framework/language to ${target}
|
|
5274
5274
|
3. Update each step status to 'completed' as you finish it
|
|
5275
5275
|
4. Work incrementally seam by seam from ${migration_dir}/seams.json
|
package/dashboard/__init__.py
CHANGED
|
@@ -14,7 +14,7 @@ import re
|
|
|
14
14
|
import subprocess
|
|
15
15
|
import tempfile
|
|
16
16
|
import threading
|
|
17
|
-
from dataclasses import asdict, dataclass, field
|
|
17
|
+
from dataclasses import asdict, dataclass, field, fields
|
|
18
18
|
from datetime import datetime, timezone
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
from typing import Any, Optional
|
|
@@ -38,8 +38,8 @@ class Feature:
|
|
|
38
38
|
"""Individual feature tracked during migration."""
|
|
39
39
|
|
|
40
40
|
id: str
|
|
41
|
-
category: str
|
|
42
|
-
description: str
|
|
41
|
+
category: str = ""
|
|
42
|
+
description: str = ""
|
|
43
43
|
verification_steps: list[str] = field(default_factory=list)
|
|
44
44
|
passes: bool = False
|
|
45
45
|
characterization_test: str = ""
|
|
@@ -52,8 +52,8 @@ class MigrationStep:
|
|
|
52
52
|
"""Single step in a migration plan."""
|
|
53
53
|
|
|
54
54
|
id: str
|
|
55
|
-
description: str
|
|
56
|
-
type: str # e.g. "refactor", "rewrite", "config", "test"
|
|
55
|
+
description: str = ""
|
|
56
|
+
type: str = "" # e.g. "refactor", "rewrite", "config", "test"
|
|
57
57
|
files: list[str] = field(default_factory=list)
|
|
58
58
|
tests_required: list[str] = field(default_factory=list)
|
|
59
59
|
estimated_tokens: int = 0
|
|
@@ -81,9 +81,14 @@ class SeamInfo:
|
|
|
81
81
|
"""Detected seam (boundary/interface) in the codebase."""
|
|
82
82
|
|
|
83
83
|
id: str
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
description: str = ""
|
|
85
|
+
type: str = "" # e.g. "api", "module", "database", "config"
|
|
86
|
+
location: str = ""
|
|
87
|
+
name: str = ""
|
|
88
|
+
priority: str = "medium"
|
|
89
|
+
files: list[str] = field(default_factory=list)
|
|
90
|
+
dependencies: list[str] = field(default_factory=list)
|
|
91
|
+
complexity: str = ""
|
|
87
92
|
confidence: float = 0.0
|
|
88
93
|
suggested_interface: str = ""
|
|
89
94
|
|
|
@@ -353,7 +358,12 @@ class MigrationPipeline:
|
|
|
353
358
|
features_path = self.migration_dir / "features.json"
|
|
354
359
|
try:
|
|
355
360
|
data = json.loads(features_path.read_text(encoding="utf-8"))
|
|
356
|
-
|
|
361
|
+
# Handle both flat list and {"features": [...]} wrapper
|
|
362
|
+
if isinstance(data, dict):
|
|
363
|
+
data = data.get("features", [])
|
|
364
|
+
# Filter to known Feature fields to tolerate extra keys
|
|
365
|
+
_feature_fields = {f.name for f in fields(Feature)}
|
|
366
|
+
features = [Feature(**{k: v for k, v in f.items() if k in _feature_fields}) for f in data]
|
|
357
367
|
except FileNotFoundError:
|
|
358
368
|
return False, "Phase gate failed: features.json not found"
|
|
359
369
|
except (json.JSONDecodeError, TypeError) as exc:
|
|
@@ -372,9 +382,11 @@ class MigrationPipeline:
|
|
|
372
382
|
try:
|
|
373
383
|
data = json.loads(plan_path.read_text(encoding="utf-8"))
|
|
374
384
|
steps_data = data.get("steps", [])
|
|
375
|
-
|
|
385
|
+
_plan_fields = {f.name for f in fields(MigrationPlan)}
|
|
386
|
+
_step_fields = {f.name for f in fields(MigrationStep)}
|
|
387
|
+
plan_data = {k: v for k, v in data.items() if k in _plan_fields and k != "steps"}
|
|
376
388
|
plan = MigrationPlan(**plan_data)
|
|
377
|
-
plan.steps = [MigrationStep(**s) for s in steps_data]
|
|
389
|
+
plan.steps = [MigrationStep(**{k: v for k, v in s.items() if k in _step_fields}) for s in steps_data]
|
|
378
390
|
except FileNotFoundError:
|
|
379
391
|
return False, "Phase gate failed: migration-plan.json not found"
|
|
380
392
|
except (json.JSONDecodeError, TypeError) as exc:
|
|
@@ -501,7 +513,12 @@ class MigrationPipeline:
|
|
|
501
513
|
with self._lock:
|
|
502
514
|
try:
|
|
503
515
|
data = json.loads(features_path.read_text(encoding="utf-8"))
|
|
504
|
-
|
|
516
|
+
# Handle both flat list and {"features": [...]} wrapper
|
|
517
|
+
if isinstance(data, dict):
|
|
518
|
+
data = data.get("features", [])
|
|
519
|
+
# Filter to known Feature fields to tolerate extra keys
|
|
520
|
+
_feature_fields = {f.name for f in fields(Feature)}
|
|
521
|
+
return [Feature(**{k: v for k, v in f.items() if k in _feature_fields}) for f in data]
|
|
505
522
|
except FileNotFoundError:
|
|
506
523
|
logger.warning("Features file not found: %s", features_path)
|
|
507
524
|
raise
|
|
@@ -528,9 +545,12 @@ class MigrationPipeline:
|
|
|
528
545
|
try:
|
|
529
546
|
data = json.loads(plan_path.read_text(encoding="utf-8"))
|
|
530
547
|
# Reconstruct nested MigrationStep objects
|
|
531
|
-
steps_data = data.
|
|
532
|
-
|
|
533
|
-
|
|
548
|
+
steps_data = data.get("steps", [])
|
|
549
|
+
_plan_fields = {f.name for f in fields(MigrationPlan)}
|
|
550
|
+
_step_fields = {f.name for f in fields(MigrationStep)}
|
|
551
|
+
plan_data = {k: v for k, v in data.items() if k in _plan_fields and k != "steps"}
|
|
552
|
+
plan = MigrationPlan(**plan_data)
|
|
553
|
+
plan.steps = [MigrationStep(**{k: v for k, v in s.items() if k in _step_fields}) for s in steps_data]
|
|
534
554
|
return plan
|
|
535
555
|
except FileNotFoundError:
|
|
536
556
|
logger.warning("Plan file not found: %s", plan_path)
|
|
@@ -555,7 +575,11 @@ class MigrationPipeline:
|
|
|
555
575
|
with self._lock:
|
|
556
576
|
try:
|
|
557
577
|
data = json.loads(seams_path.read_text(encoding="utf-8"))
|
|
558
|
-
|
|
578
|
+
# Handle both flat list and {"seams": [...]} wrapper
|
|
579
|
+
if isinstance(data, dict):
|
|
580
|
+
data = data.get("seams", [])
|
|
581
|
+
_seam_fields = {f.name for f in fields(SeamInfo)}
|
|
582
|
+
return [SeamInfo(**{k: v for k, v in s.items() if k in _seam_fields}) for s in data]
|
|
559
583
|
except FileNotFoundError:
|
|
560
584
|
logger.warning("Seams file not found: %s", seams_path)
|
|
561
585
|
raise
|
package/docs/INSTALLATION.md
CHANGED
package/mcp/__init__.py
CHANGED