loki-mode 11.4.2 → 11.6.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/lib/chat.sh +6 -3
- package/autonomy/lib/engine10-push.sh +19 -1
- package/autonomy/lib/help-core.sh +1 -1
- package/autonomy/lib/proof-generator.py +23 -5
- package/autonomy/lib/proof-verify.py +607 -5
- package/autonomy/lib/run-summary.sh +17 -1
- package/autonomy/lib/setup-requirements.json +35 -0
- package/autonomy/loki +244 -237
- package/autonomy/notification-checker.py +1 -1
- package/autonomy/provider-offer.sh +95 -47
- package/autonomy/route.sh +38 -6
- package/autonomy/run.sh +42 -14
- package/autonomy/setup-wizard.sh +19 -10
- package/autonomy/verify.sh +40 -1
- package/completions/_loki +3 -1
- package/completions/loki.bash +9 -3
- package/dashboard/__init__.py +3 -10
- package/dashboard/control.py +5 -435
- package/docs/ARCHITECTURE.md +1 -2
- package/docs/CLI-CORE-VERBS.md +2 -6
- package/docs/CLI-REFERENCE.md +3 -1
- package/docs/COMPONENTS.md +0 -2
- package/docs/EVALUATING.md +27 -0
- package/docs/HARNESS-INTELLIGENCE-PLAN.md +20 -0
- package/docs/INSTALLATION.md +1 -1
- package/docs/KNOWN-ISSUES.md +10 -1
- package/docs/PROOF-PASSPORT.md +114 -0
- package/docs/alternative-installations.md +103 -0
- package/docs/authentication.md +19 -1
- package/docs/cost-controls.md +139 -0
- package/docs/dev/release-checklist.md +9 -8
- package/docs/enterprise/security.md +3 -234
- package/docs/environment-variables.md +36 -0
- package/docs/exit-codes.md +102 -2
- package/docs/spec-first-intent.md +29 -0
- package/docs/v10/ARCHITECT-CUTS.md +304 -0
- package/docs/v10/CLI-MODERN.md +2 -2
- package/docs/v10/DECISIONS.md +5 -5
- package/docs/v10/ENGINE.md +735 -267
- package/docs/v10/GUARDS.md +16 -14
- package/docs/v10/GUIDE.md +5 -7
- package/docs/v10/PROGRESS.md +12 -1
- package/docs/v11/MARKET-SLICES.md +1 -5
- package/integrations/openclaw/README.md +20 -0
- package/integrations/vibe-kanban.md +12 -50
- package/loki-ts/data/model-pricing.json +1 -0
- package/loki-ts/dist/loki.js +1156 -1103
- package/mcp/__init__.py +1 -1
- package/mcp/_sdk_loader.py +1 -1
- package/package.json +2 -2
- package/packages/control-plane/dist/server.js +2063 -1032
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/plugins/loki-mode/README.md +41 -1
- package/plugins/loki-mode/commands/handoff.md +12 -0
- package/plugins/loki-mode/commands/loki-verify.md +9 -2
- package/plugins/loki-mode/commands/start.md +20 -0
- package/plugins/loki-mode/hooks/hooks.json +11 -0
- package/plugins/loki-mode/scripts/loki-stop-verify.sh +84 -0
- package/references/quality-control.md +1 -116
- package/skills/00-index.md +2 -2
- package/skills/artifacts.md +0 -22
- package/skills/production.md +2 -38
- package/web-app/dist/assets/{AdminPage-CYJ2BWRC.js → AdminPage-DhXdJNQk.js} +1 -1
- package/web-app/dist/assets/{Avatar-DdK4wynI.js → Avatar-ixVj76fM.js} +1 -1
- package/web-app/dist/assets/{Badge-CrX3MI7J.js → Badge-BGMSp22s.js} +1 -1
- package/web-app/dist/assets/{Button-709-wwGM.js → Button-pYJc32tG.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-BapdTInO.js → CockpitPage-C1JBBouA.js} +1 -1
- package/web-app/dist/assets/{ComparePage-DT99pGvA.js → ComparePage-qD0NV4RK.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-B0uJSys8.js → ErrorBoundary-C-yxO58j.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-BtMFgElP.js → EvidenceReceiptPanel-ByPzuE1S.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-DjJuU941.js → GitHubIssuesPanel-BNv_2BEJ.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-HXfEX1BC.js → GitHubPRsPanel-CuLZQ9CS.js} +1 -1
- package/web-app/dist/assets/{HomePage-Cqyves-S.js → HomePage-CS_FW8Je.js} +2 -2
- package/web-app/dist/assets/{LoginPage-jUbtC7_Y.js → LoginPage-DwiNf1Wm.js} +1 -1
- package/web-app/dist/assets/{MagicPage-DHRsqjgR.js → MagicPage-CmQybLPZ.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-B-pED05R.js → MetricsPage-D9ERdpv8.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-CsbUs21R.js → NotFoundPage-D9ccgdbF.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BtlLEQwB.js → ProjectPage-B9Jslmgv.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-DaRbRjSp.js → ProjectsPage-DnU99Go2.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-DALrtP3F.js → SettingsPage-DcTyx6wo.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-CoPHSNP0.js → ShowcasePage-jEY9ghSr.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-kOuSN50O.js → SystemSettingsPage-CSGltW-8.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-DGWK0LMp.js → TeamsPage-gUuJXb9l.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-C-_10CwA.js → TemplatesPage-37Zhe--v.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-Cz_vPbXL.js → TerminalOutput-B09hRwaR.js} +1 -1
- package/web-app/dist/assets/{activity-icIsXJVa.js → activity-q_4MY9J0.js} +1 -1
- package/web-app/dist/assets/{bell-DbPR2_4r.js → bell-X8OC_PFP.js} +1 -1
- package/web-app/dist/assets/{bot-DvjP3Yh5.js → bot-C-N1PUOD.js} +1 -1
- package/web-app/dist/assets/{check-D1OBxHeU.js → check-B2c76Jmp.js} +1 -1
- package/web-app/dist/assets/{chevron-left-D09jDZ29.js → chevron-left-BF76YLNw.js} +1 -1
- package/web-app/dist/assets/{circle-alert-DyZMLOcC.js → circle-alert-AeFKBD8h.js} +1 -1
- package/web-app/dist/assets/{clock-CdpdJTId.js → clock-CiXRf-FH.js} +1 -1
- package/web-app/dist/assets/{cloud-CoLTlmoj.js → cloud-DKQ8SRJ5.js} +1 -1
- package/web-app/dist/assets/{code-xml-DrkE2ZZY.js → code-xml-DEb6jXWP.js} +1 -1
- package/web-app/dist/assets/{database-CMQQuM2R.js → database-6W7e-E9c.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-CuioDaOG.js → dollar-sign-Ds2GOuyW.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-Cx9j9K1S.js → file-code-corner-CZU0jg52.js} +1 -1
- package/web-app/dist/assets/{file-plus-CYD2zaaI.js → file-plus-DTVYnXCN.js} +1 -1
- package/web-app/dist/assets/{globe-6w-hnQkL.js → globe-0mUzKYDe.js} +1 -1
- package/web-app/dist/assets/{hammer-BpqtautL.js → hammer-BMHZg3YX.js} +1 -1
- package/web-app/dist/assets/{index-Dzs-9EgJ.js → index-BvOTvjax.js} +3 -3
- package/web-app/dist/assets/{layers-D5hd7jb7.js → layers-Df7TdcWB.js} +1 -1
- package/web-app/dist/assets/{loader-circle-C6Y9x_7H.js → loader-circle-kPsVfrSY.js} +1 -1
- package/web-app/dist/assets/{lock-D51L7rYh.js → lock-CXYcbEc5.js} +1 -1
- package/web-app/dist/assets/{package-BJF8hkP8.js → package-Cqhua1ID.js} +1 -1
- package/web-app/dist/assets/{plus-D5kUQ79n.js → plus-lseXhsn-.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-BKdlCa7F.js → refresh-cw-OZriI6gD.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-_bd_YI1e.js → rotate-ccw-CKCfjPg8.js} +1 -1
- package/web-app/dist/assets/{scroll-text-DbkegIxF.js → scroll-text-DoVyyfKb.js} +1 -1
- package/web-app/dist/assets/{server-DAwqFIsq.js → server-DGy7TflW.js} +1 -1
- package/web-app/dist/assets/{shield-alert-BuR1tPHu.js → shield-alert-BCzRcMXi.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-BF6p3mRd.js → thumbs-up-C_znJd5g.js} +1 -1
- package/web-app/dist/assets/{trash-2-BVpnkqqz.js → trash-2-BosCbeeA.js} +1 -1
- package/web-app/dist/assets/{trending-down-DpsDvRwW.js → trending-down-CkR5zDkV.js} +1 -1
- package/web-app/dist/assets/{trending-up-mFogTjt3.js → trending-up-DpUIfOH4.js} +1 -1
- package/web-app/dist/assets/{upload-4T8zpBsi.js → upload-CH9aKc8L.js} +1 -1
- package/web-app/dist/assets/{usePolling-DPXQv8WO.js → usePolling-pzxrHJeg.js} +1 -1
- package/web-app/dist/assets/{user-BYGIFaTm.js → user-B7OHa-VQ.js} +1 -1
- package/web-app/dist/index.html +1 -1
- package/dashboard/run.py +0 -63
- package/docs/openclaw-integration.md +0 -52
- package/docs/v10/HANDOFF-NEXT-WEEK.md +0 -40
- package/docs/v10/MORNING-BRIEF-1003.md +0 -25
- package/docs/v10/MORNING-BRIEF.md +0 -52
- package/docs/v10/TODO.md +0 -35
- package/mcp/resources.py +0 -351
- package/mcp/tools.py +0 -200
package/mcp/tools.py
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Loki Mode MCP Tools
|
|
3
|
-
|
|
4
|
-
Additional tool definitions that can be imported into the server.
|
|
5
|
-
These are helper functions and utilities for the MCP tools.
|
|
6
|
-
Uses StateManager for centralized state access with caching.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import os
|
|
10
|
-
import sys
|
|
11
|
-
import json
|
|
12
|
-
from datetime import datetime, timezone
|
|
13
|
-
from typing import Dict, Any, List, Optional
|
|
14
|
-
|
|
15
|
-
# Add parent directory to path for state manager import
|
|
16
|
-
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
17
|
-
|
|
18
|
-
# Import StateManager for centralized state access
|
|
19
|
-
try:
|
|
20
|
-
from state.manager import StateManager, ManagedFile, get_state_manager
|
|
21
|
-
HAS_STATE_MANAGER = True
|
|
22
|
-
except ImportError:
|
|
23
|
-
HAS_STATE_MANAGER = False
|
|
24
|
-
StateManager = None
|
|
25
|
-
ManagedFile = None
|
|
26
|
-
get_state_manager = None
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def get_loki_base_path() -> str:
|
|
30
|
-
"""Get the base .loki directory path."""
|
|
31
|
-
return os.path.join(os.getcwd(), '.loki')
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# Module-level StateManager instance
|
|
35
|
-
_state_manager = None
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def _get_state_manager() -> Optional['StateManager']:
|
|
39
|
-
"""Get or create the StateManager instance."""
|
|
40
|
-
global _state_manager
|
|
41
|
-
if not HAS_STATE_MANAGER:
|
|
42
|
-
return None
|
|
43
|
-
if _state_manager is None:
|
|
44
|
-
_state_manager = get_state_manager(
|
|
45
|
-
loki_dir=get_loki_base_path(),
|
|
46
|
-
enable_watch=False,
|
|
47
|
-
enable_events=False
|
|
48
|
-
)
|
|
49
|
-
return _state_manager
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def ensure_loki_initialized() -> bool:
|
|
53
|
-
"""Check if Loki Mode is initialized in current directory."""
|
|
54
|
-
return os.path.exists(get_loki_base_path())
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def get_task_queue_path() -> str:
|
|
58
|
-
"""Get path to the task queue file."""
|
|
59
|
-
return os.path.join(get_loki_base_path(), 'state', 'task-queue.json')
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def get_memory_path() -> str:
|
|
63
|
-
"""Get path to the memory directory."""
|
|
64
|
-
return os.path.join(get_loki_base_path(), 'memory')
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def load_task_queue() -> Dict[str, Any]:
|
|
68
|
-
"""Load the task queue from disk using StateManager."""
|
|
69
|
-
manager = _get_state_manager()
|
|
70
|
-
if manager:
|
|
71
|
-
result = manager.get_state("state/task-queue.json")
|
|
72
|
-
if result:
|
|
73
|
-
return result
|
|
74
|
-
# Fallback to direct file read if StateManager not available
|
|
75
|
-
queue_path = get_task_queue_path()
|
|
76
|
-
if os.path.exists(queue_path):
|
|
77
|
-
with open(queue_path, 'r') as f:
|
|
78
|
-
return json.load(f)
|
|
79
|
-
return {"tasks": [], "version": "1.0"}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def save_task_queue(queue: Dict[str, Any]) -> None:
|
|
83
|
-
"""Save the task queue to disk using StateManager."""
|
|
84
|
-
manager = _get_state_manager()
|
|
85
|
-
if manager:
|
|
86
|
-
manager.set_state("state/task-queue.json", queue, source="mcp-tools")
|
|
87
|
-
return
|
|
88
|
-
# Fallback to direct file write if StateManager not available
|
|
89
|
-
queue_path = get_task_queue_path()
|
|
90
|
-
os.makedirs(os.path.dirname(queue_path), exist_ok=True)
|
|
91
|
-
with open(queue_path, 'w') as f:
|
|
92
|
-
json.dump(queue, f, indent=2)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
def create_task(
|
|
96
|
-
title: str,
|
|
97
|
-
description: str,
|
|
98
|
-
priority: str = "medium",
|
|
99
|
-
phase: str = "development"
|
|
100
|
-
) -> Dict[str, Any]:
|
|
101
|
-
"""Create a new task dictionary."""
|
|
102
|
-
queue = load_task_queue()
|
|
103
|
-
next_id = queue.get("_next_id", len(queue['tasks']) + 1)
|
|
104
|
-
task_id = f"task-{next_id:04d}"
|
|
105
|
-
queue["_next_id"] = next_id + 1
|
|
106
|
-
|
|
107
|
-
task = {
|
|
108
|
-
"id": task_id,
|
|
109
|
-
"title": title,
|
|
110
|
-
"description": description,
|
|
111
|
-
"priority": priority,
|
|
112
|
-
"phase": phase,
|
|
113
|
-
"status": "pending",
|
|
114
|
-
"created_at": datetime.now(timezone.utc).isoformat()
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
# Persist _next_id so it survives across calls
|
|
118
|
-
save_task_queue(queue)
|
|
119
|
-
|
|
120
|
-
return task
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def filter_tasks_by_status(tasks: List[Dict], status: str) -> List[Dict]:
|
|
124
|
-
"""Filter tasks by their status."""
|
|
125
|
-
return [t for t in tasks if t.get("status") == status]
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def filter_tasks_by_priority(tasks: List[Dict], priority: str) -> List[Dict]:
|
|
129
|
-
"""Filter tasks by their priority."""
|
|
130
|
-
return [t for t in tasks if t.get("priority") == priority]
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def filter_tasks_by_phase(tasks: List[Dict], phase: str) -> List[Dict]:
|
|
134
|
-
"""Filter tasks by their SDLC phase."""
|
|
135
|
-
return [t for t in tasks if t.get("phase") == phase]
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def get_task_summary(queue: Dict[str, Any]) -> Dict[str, Any]:
|
|
139
|
-
"""Get a summary of the task queue."""
|
|
140
|
-
tasks = queue.get("tasks", [])
|
|
141
|
-
|
|
142
|
-
return {
|
|
143
|
-
"total": len(tasks),
|
|
144
|
-
"by_status": {
|
|
145
|
-
"pending": len(filter_tasks_by_status(tasks, "pending")),
|
|
146
|
-
"in_progress": len(filter_tasks_by_status(tasks, "in_progress")),
|
|
147
|
-
"completed": len(filter_tasks_by_status(tasks, "completed")),
|
|
148
|
-
"blocked": len(filter_tasks_by_status(tasks, "blocked"))
|
|
149
|
-
},
|
|
150
|
-
"by_priority": {
|
|
151
|
-
"critical": len(filter_tasks_by_priority(tasks, "critical")),
|
|
152
|
-
"high": len(filter_tasks_by_priority(tasks, "high")),
|
|
153
|
-
"medium": len(filter_tasks_by_priority(tasks, "medium")),
|
|
154
|
-
"low": len(filter_tasks_by_priority(tasks, "low"))
|
|
155
|
-
},
|
|
156
|
-
"by_phase": {
|
|
157
|
-
"discovery": len(filter_tasks_by_phase(tasks, "discovery")),
|
|
158
|
-
"architecture": len(filter_tasks_by_phase(tasks, "architecture")),
|
|
159
|
-
"development": len(filter_tasks_by_phase(tasks, "development")),
|
|
160
|
-
"testing": len(filter_tasks_by_phase(tasks, "testing")),
|
|
161
|
-
"deployment": len(filter_tasks_by_phase(tasks, "deployment"))
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def format_task_for_display(task: Dict[str, Any]) -> str:
|
|
167
|
-
"""Format a task for human-readable display."""
|
|
168
|
-
lines = [
|
|
169
|
-
f"Task: {task.get('id', 'unknown')}",
|
|
170
|
-
f"Title: {task.get('title', 'Untitled')}",
|
|
171
|
-
f"Status: {task.get('status', 'unknown')}",
|
|
172
|
-
f"Priority: {task.get('priority', 'medium')}",
|
|
173
|
-
f"Phase: {task.get('phase', 'development')}",
|
|
174
|
-
f"Description: {task.get('description', 'No description')}",
|
|
175
|
-
]
|
|
176
|
-
|
|
177
|
-
if task.get('created_at'):
|
|
178
|
-
lines.append(f"Created: {task['created_at']}")
|
|
179
|
-
if task.get('updated_at'):
|
|
180
|
-
lines.append(f"Updated: {task['updated_at']}")
|
|
181
|
-
|
|
182
|
-
return "\n".join(lines)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
def validate_task_status(status: str) -> bool:
|
|
186
|
-
"""Validate a task status value."""
|
|
187
|
-
valid_statuses = ["pending", "in_progress", "completed", "blocked"]
|
|
188
|
-
return status in valid_statuses
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
def validate_task_priority(priority: str) -> bool:
|
|
192
|
-
"""Validate a task priority value."""
|
|
193
|
-
valid_priorities = ["low", "medium", "high", "critical"]
|
|
194
|
-
return priority in valid_priorities
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def validate_task_phase(phase: str) -> bool:
|
|
198
|
-
"""Validate a task SDLC phase value."""
|
|
199
|
-
valid_phases = ["discovery", "architecture", "development", "testing", "deployment"]
|
|
200
|
-
return phase in valid_phases
|