loki-mode 11.33.0 → 11.34.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/SKILL.md +2 -2
- package/VERSION +1 -1
- package/dashboard/__init__.py +1 -1
- package/docs/CLI-REFERENCE.md +1 -1
- package/docs/INSTALLATION.md +1 -1
- package/loki-ts/dist/loki.js +2 -2
- package/mcp/__init__.py +1 -1
- package/mcp/cp_tools.py +27 -1
- package/mcp/lsp_proxy.py +23 -0
- package/mcp/managed_tools.py +4 -0
- package/mcp/server.py +107 -1
- package/memory/embeddings.py +53 -30
- package/memory/retrieval.py +3 -3
- package/package.json +2 -2
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
- package/skills/memory.md +3 -3
- package/web-app/dist/assets/{AdminPage-BOo6zbtK.js → AdminPage-DgAVkVWn.js} +1 -1
- package/web-app/dist/assets/{Avatar-x0_oZtYF.js → Avatar-Ck8Yk8be.js} +1 -1
- package/web-app/dist/assets/{Badge-jDB28PQG.js → Badge-FVoXqq4E.js} +1 -1
- package/web-app/dist/assets/{Button-27f5aDrW.js → Button-CMw4G6zi.js} +1 -1
- package/web-app/dist/assets/{CockpitPage-DiAKMj0I.js → CockpitPage-Dj0_prPK.js} +1 -1
- package/web-app/dist/assets/{ComparePage-RKUVbeCG.js → ComparePage-BYRPCzvi.js} +1 -1
- package/web-app/dist/assets/{ErrorBoundary-CQ7c_YJ9.js → ErrorBoundary-MHkHBHLP.js} +1 -1
- package/web-app/dist/assets/{EvidenceReceiptPanel-u65ACFhT.js → EvidenceReceiptPanel-qmeNdpZ8.js} +1 -1
- package/web-app/dist/assets/{GitHubIssuesPanel-8oqCXpcg.js → GitHubIssuesPanel-CylSazZf.js} +1 -1
- package/web-app/dist/assets/{GitHubPRsPanel-DkagnZtO.js → GitHubPRsPanel-0dl-yINT.js} +1 -1
- package/web-app/dist/assets/{HomePage-C5IyKJcO.js → HomePage-C-OGeZVA.js} +2 -2
- package/web-app/dist/assets/{LoginPage-C6-NK6Dd.js → LoginPage-BC07c08R.js} +1 -1
- package/web-app/dist/assets/{MagicPage-FrUAlTFq.js → MagicPage-DMvoB0Et.js} +1 -1
- package/web-app/dist/assets/{MetricsPage-DbHKrYaS.js → MetricsPage-a_X_FL9i.js} +1 -1
- package/web-app/dist/assets/{NotFoundPage-qg7ISn6m.js → NotFoundPage-BIzDa2LX.js} +1 -1
- package/web-app/dist/assets/{ProjectPage-BZzSg0vO.js → ProjectPage-Dp7N7dQ-.js} +3 -3
- package/web-app/dist/assets/{ProjectsPage-CSrkVM0Z.js → ProjectsPage-CodakJwl.js} +1 -1
- package/web-app/dist/assets/{SettingsPage-DoIoG_1E.js → SettingsPage-CWIMbGOb.js} +1 -1
- package/web-app/dist/assets/{ShowcasePage-Cn1JmtRU.js → ShowcasePage-C81ZbWde.js} +1 -1
- package/web-app/dist/assets/{SystemSettingsPage-FD9fvAf5.js → SystemSettingsPage-Z8Rs7C5P.js} +1 -1
- package/web-app/dist/assets/{TeamsPage-BkGU3fTI.js → TeamsPage-CuMnfLdH.js} +1 -1
- package/web-app/dist/assets/{TemplatesPage-Oon4z663.js → TemplatesPage-DIh6RfI5.js} +1 -1
- package/web-app/dist/assets/{TerminalOutput-CLysHg_-.js → TerminalOutput-BqqFtKCm.js} +1 -1
- package/web-app/dist/assets/{activity-BcCTbGiS.js → activity-Qng0kgTC.js} +1 -1
- package/web-app/dist/assets/{bell-BcGnBkdg.js → bell-ReenPvdI.js} +1 -1
- package/web-app/dist/assets/{bot-i31uzgM6.js → bot-KKDc11N7.js} +1 -1
- package/web-app/dist/assets/{check-CExa_B4X.js → check-DqhTYg54.js} +1 -1
- package/web-app/dist/assets/{chevron-left-BP1rmia5.js → chevron-left-BLJibPno.js} +1 -1
- package/web-app/dist/assets/{circle-alert-BOLPoLQg.js → circle-alert-ChtBTJr0.js} +1 -1
- package/web-app/dist/assets/{clock-DatwTgIM.js → clock-C6Ueawd5.js} +1 -1
- package/web-app/dist/assets/{cloud-C3bRnFkT.js → cloud-CVM8HeNm.js} +1 -1
- package/web-app/dist/assets/{code-xml-C66CBkn_.js → code-xml-vr3SukFJ.js} +1 -1
- package/web-app/dist/assets/{database-D1H0smtm.js → database-xDPAFunH.js} +1 -1
- package/web-app/dist/assets/{dollar-sign-6mehyt0I.js → dollar-sign-BLs2gY1_.js} +1 -1
- package/web-app/dist/assets/{file-code-corner-Dcl58rE8.js → file-code-corner-Dw1yS4b1.js} +1 -1
- package/web-app/dist/assets/{file-plus-DusJH-jr.js → file-plus-Cf1L0zye.js} +1 -1
- package/web-app/dist/assets/{globe-8gbaSEAF.js → globe-DSUCGkxh.js} +1 -1
- package/web-app/dist/assets/{hammer-BeUMO3eS.js → hammer-Bo1IfnQ1.js} +1 -1
- package/web-app/dist/assets/{index-BxlLDUq_.js → index-BLbitx-c.js} +3 -3
- package/web-app/dist/assets/{layers-CsO5XwHB.js → layers-C-rNce2h.js} +1 -1
- package/web-app/dist/assets/{loader-circle-8JWxq7au.js → loader-circle-CHa1iGzF.js} +1 -1
- package/web-app/dist/assets/{lock-ByAv_0Uq.js → lock-b-ADIaZI.js} +1 -1
- package/web-app/dist/assets/{package-D-xVbDAP.js → package-DCZqs_Q1.js} +1 -1
- package/web-app/dist/assets/{plus-R7T7gJbI.js → plus-BTaYqxvd.js} +1 -1
- package/web-app/dist/assets/{refresh-cw-D65J_QH-.js → refresh-cw-DHzCeVIr.js} +1 -1
- package/web-app/dist/assets/{rotate-ccw-Cs4Tvq2C.js → rotate-ccw-BY2d4fP5.js} +1 -1
- package/web-app/dist/assets/{scroll-text-N1tgG-co.js → scroll-text-CGQ1IRWy.js} +1 -1
- package/web-app/dist/assets/{server-DD1GqOyy.js → server-VHm7NVEE.js} +1 -1
- package/web-app/dist/assets/{shield-alert-0V3SJyDi.js → shield-alert-MFQ4E5vj.js} +1 -1
- package/web-app/dist/assets/{thumbs-up-BT7l40R8.js → thumbs-up-COBgqBS1.js} +1 -1
- package/web-app/dist/assets/{trash-2-z1gK-C8I.js → trash-2-Dmiwko20.js} +1 -1
- package/web-app/dist/assets/{trending-down-Cp3fR71x.js → trending-down-Bw1hEf7T.js} +1 -1
- package/web-app/dist/assets/{trending-up-DXL-NgP-.js → trending-up-LJq0H2PM.js} +1 -1
- package/web-app/dist/assets/{upload-BX_yQ46Z.js → upload-BiKnI3iU.js} +1 -1
- package/web-app/dist/assets/{usePolling-Bo7CC4Ha.js → usePolling-Dh3h9wuI.js} +1 -1
- package/web-app/dist/assets/{user-C7nAwa5x.js → user-B6JI_lQH.js} +1 -1
- package/web-app/dist/index.html +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: An autonomous software factory that knows what it is supposed to deliver, and proves it did. Use when the user says Loki Mode or asks to build, fix or verify software autonomously.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v11.
|
|
6
|
+
# Loki Mode v11.34.1
|
|
7
7
|
|
|
8
8
|
**Current entry points (Loki 10 engine):** `loki "<task>"`, `loki owner/repo#N` and `loki quick "<task>"` run the Loki 10 engine and end with a signed receipt (`loki verify`). `loki backlog owner/repo --all` runs many issues in parallel. Guide: `docs/v10/GUIDE.md`. The skill instructions below, and `loki start`, describe the previous bash loop. PRD-file starts (`loki start ./prd.md`) and the opencode provider still run on it until FC38-SWEEP ports them; the legacy-engine command and the LOKI_ENGINE switch remain removed. Prefer `loki owner/repo#N` for issues.
|
|
9
9
|
|
|
@@ -496,4 +496,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
496
496
|
|
|
497
497
|
---
|
|
498
498
|
|
|
499
|
-
**v11.
|
|
499
|
+
**v11.34.1 | [Autonomi](https://www.autonomi.dev/) flagship product | core skill**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
11.
|
|
1
|
+
11.34.1
|
package/dashboard/__init__.py
CHANGED
package/docs/CLI-REFERENCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CLI reference
|
|
2
2
|
|
|
3
|
-
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.
|
|
3
|
+
Generated from `loki-ts/src/cli/registry.ts` by `scripts/generate-stale-zero.sh` for v11.34.1. Do not edit by hand.
|
|
4
4
|
Hidden and legacy-only commands are omitted; see `docs/v10/CLI-MODERN.md` for the full inventory.
|
|
5
5
|
|
|
6
6
|
| Command | Description |
|
package/docs/INSTALLATION.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Loki Mode, by [Autonomi](https://www.autonomi.dev/), turns a spec or an issue into a verified pull request with a receipt you can check. This page covers installing it, a first run, and the options around it.
|
|
4
4
|
|
|
5
|
-
**Version:** v11.
|
|
5
|
+
**Version:** v11.34.1
|
|
6
6
|
|
|
7
7
|
**Engine note:** `loki start` is the primary command. `loki start`, `loki "<task>"`, `loki owner/repo#N` and `loki quick` all run the Loki 10 engine, whatever the flag order or input form (PRD file, issue ref, task or one-word brief). The previous loop runs only on `--engine legacy`, `LOKI_ENGINE=legacy`, or for one call when a flag Loki 10 cannot honor is present. See the [user guide](v10/GUIDE.md) and the [5-minute quickstart](QUICKSTART.md).
|
|
8
8
|
|
package/loki-ts/dist/loki.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var lb0=Object.create;var{getPrototypeOf:ab0,defineProperty:AK,getOwnPropertyNames:Si,getOwnPropertyDescriptor:ib0}=Object,bi=Object.prototype.hasOwnProperty;function yi(Z){return this[Z]}var ob0,nb0,sb0=(Z,$,J)=>{var X=Z!=null&&typeof Z==="object";if(X){var Y=$?ob0??=new WeakMap:nb0??=new WeakMap,Q=Y.get(Z);if(Q)return Q}J=Z!=null?lb0(ab0(Z)):{};let z=$||!Z||!Z.__esModule?AK(J,"default",{value:Z,enumerable:!0}):J;for(let W of Si(Z))if(!bi.call(z,W))AK(z,W,{get:yi.bind(Z,W),enumerable:!0});if(X)Y.set(Z,z);return z},rb0=(Z)=>{var $=(xi??=new WeakMap).get(Z),J;if($)return $;if($=AK({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function"){for(var X of Si(Z))if(!bi.call($,X))AK($,X,{get:yi.bind(Z,X),enumerable:!(J=ib0(Z,X))||J.enumerable})}return xi.set(Z,$),$},xi,gN=(Z,$)=>()=>($||Z(($={exports:{}}).exports,$),$.exports);var tb0=(Z)=>Z;function eb0(Z,$){this[Z]=tb0.bind(null,$)}var A0=(Z,$)=>{for(var J in $)AK(Z,J,{get:$[J],enumerable:!0,configurable:!0,set:eb0.bind($,J)})};var S=(Z,$)=>()=>(Z&&($=Z(Z=0)),$);var s9=import.meta.require;var hi={};A0(hi,{lokiDir:()=>P0,homeLokiDir:()=>B2,findRepoRootForVersion:()=>LK,REPO_ROOT:()=>F0});import{resolve as LZ,dirname as cR}from"path";import{fileURLToPath as Zy0}from"url";import{existsSync as mN}from"fs";import{homedir as $y0}from"os";function Jy0(){let Z=vi;for(let $=0;$<6;$++){if(mN(LZ(Z,"VERSION"))&&mN(LZ(Z,"autonomy/run.sh")))return Z;let J=cR(Z);if(J===Z)break;Z=J}return LZ(vi,"..","..","..")}function LK(Z){let $=Z;for(let J=0;J<6;J++){if(mN(LZ($,"VERSION"))&&mN(LZ($,"autonomy/run.sh")))return $;let X=cR($);if(X===$)break;$=X}return LZ(Z,"..","..","..")}function P0(){return process.env.LOKI_DIR??LZ(process.cwd(),".loki")}function B2(){return LZ($y0(),".loki")}var vi,F0;var n0=S(()=>{vi=cR(Zy0(import.meta.url));F0=Jy0()});import{readFileSync as Xy0}from"fs";import{resolve as Yy0,dirname as Qy0}from"path";import{fileURLToPath as zy0}from"url";function q6(){if(w1!==null)return w1;let Z="11.
|
|
2
|
+
var lb0=Object.create;var{getPrototypeOf:ab0,defineProperty:AK,getOwnPropertyNames:Si,getOwnPropertyDescriptor:ib0}=Object,bi=Object.prototype.hasOwnProperty;function yi(Z){return this[Z]}var ob0,nb0,sb0=(Z,$,J)=>{var X=Z!=null&&typeof Z==="object";if(X){var Y=$?ob0??=new WeakMap:nb0??=new WeakMap,Q=Y.get(Z);if(Q)return Q}J=Z!=null?lb0(ab0(Z)):{};let z=$||!Z||!Z.__esModule?AK(J,"default",{value:Z,enumerable:!0}):J;for(let W of Si(Z))if(!bi.call(z,W))AK(z,W,{get:yi.bind(Z,W),enumerable:!0});if(X)Y.set(Z,z);return z},rb0=(Z)=>{var $=(xi??=new WeakMap).get(Z),J;if($)return $;if($=AK({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function"){for(var X of Si(Z))if(!bi.call($,X))AK($,X,{get:yi.bind(Z,X),enumerable:!(J=ib0(Z,X))||J.enumerable})}return xi.set(Z,$),$},xi,gN=(Z,$)=>()=>($||Z(($={exports:{}}).exports,$),$.exports);var tb0=(Z)=>Z;function eb0(Z,$){this[Z]=tb0.bind(null,$)}var A0=(Z,$)=>{for(var J in $)AK(Z,J,{get:$[J],enumerable:!0,configurable:!0,set:eb0.bind($,J)})};var S=(Z,$)=>()=>(Z&&($=Z(Z=0)),$);var s9=import.meta.require;var hi={};A0(hi,{lokiDir:()=>P0,homeLokiDir:()=>B2,findRepoRootForVersion:()=>LK,REPO_ROOT:()=>F0});import{resolve as LZ,dirname as cR}from"path";import{fileURLToPath as Zy0}from"url";import{existsSync as mN}from"fs";import{homedir as $y0}from"os";function Jy0(){let Z=vi;for(let $=0;$<6;$++){if(mN(LZ(Z,"VERSION"))&&mN(LZ(Z,"autonomy/run.sh")))return Z;let J=cR(Z);if(J===Z)break;Z=J}return LZ(vi,"..","..","..")}function LK(Z){let $=Z;for(let J=0;J<6;J++){if(mN(LZ($,"VERSION"))&&mN(LZ($,"autonomy/run.sh")))return $;let X=cR($);if(X===$)break;$=X}return LZ(Z,"..","..","..")}function P0(){return process.env.LOKI_DIR??LZ(process.cwd(),".loki")}function B2(){return LZ($y0(),".loki")}var vi,F0;var n0=S(()=>{vi=cR(Zy0(import.meta.url));F0=Jy0()});import{readFileSync as Xy0}from"fs";import{resolve as Yy0,dirname as Qy0}from"path";import{fileURLToPath as zy0}from"url";function q6(){if(w1!==null)return w1;let Z="11.34.1";if(typeof Z==="string"&&Z.length>0)return w1=Z,w1;try{let $=Qy0(zy0(import.meta.url)),J=LK($);w1=Xy0(Yy0(J,"VERSION"),"utf-8").trim()}catch{w1="unknown"}return w1}var w1=null;var jZ=S(()=>{n0()});import{mkdirSync as lR,readFileSync as uN,realpathSync as Wy0,statSync as Ky0,writeFileSync as aR}from"fs";import{dirname as XY,join as dR,resolve as fi}from"path";function Uy0(){return fi(B2(),"cache","update-check.json")}function FZ(Z){let $=/^(\d+)\.(\d+)\.(\d+)$/.exec(Z.trim());if(!$)return null;return[Number($[1]),Number($[2]),Number($[3])]}function jK(Z,$){let J=FZ(Z),X=FZ($);if(!J||!X)return!1;let[Y,Q,z]=J,[W,K,V]=X;if(Y!==W)return Y>W;if(Q!==K)return Q>K;return z>V}function gi(){let Z=(process.env.LOKI_NO_UPDATE_CHECK??"").trim().toLowerCase();if(Z==="1"||Z==="true"||Z==="yes")return!0;if(process.env.CI)return!0;if(!process.stdout.isTTY)return!0;return!1}function mi(Z){try{let $=uN(Z,"utf-8"),J=JSON.parse($);if(typeof J.checkedAt==="number"&&typeof J.latest==="string"&&FZ(J.latest)!==null)return{checkedAt:J.checkedAt,latest:J.latest}}catch{}return null}function By0(Z){try{let $=JSON.parse(uN(Z,"utf-8")).failedAt;if(typeof $==="number")return $}catch{}return null}function Ny0(Z,$){let J=mi(Z);try{lR(XY(Z),{recursive:!0}),aR(Z,JSON.stringify({...J??{},failedAt:$}),"utf-8")}catch{}}function My0(Z,$){try{lR(XY(Z),{recursive:!0}),aR(Z,JSON.stringify($),"utf-8")}catch{}}async function Oy0(){try{let Z=await fetch(Vy0,{signal:AbortSignal.timeout(Hy0),headers:{accept:"application/json"}});if(!Z.ok)return null;let $=await Z.json();if(typeof $.version==="string"&&FZ($.version)!==null)return $.version}catch{}return null}async function Ay0(Z=Date.now(),$=Oy0,J=Uy0()){let X=mi(J);if(X&&Z-X.checkedAt<Gy0)return X.latest;let Y=By0(J);if(Y!==null&&Z-Y>=0&&Z-Y<qy0)return null;let Q=await $();if(Q===null)return Ny0(J,Z),null;return My0(J,{checkedAt:Z,latest:Q}),Q}function Ly0(Z,$=process.env){if(FZ(Z)===null)return null;let X=$.PATH;if(!X)return null;let Y=new Set;for(let Q of X.split(":")){if(!Q)continue;let z=dR(Q,"loki"),W;try{Ky0(z),W=Wy0(z)}catch{continue}if(Y.has(W))continue;Y.add(W);try{let K=dR(XY(XY(W)),"package.json"),V=JSON.parse(uN(K,"utf8")).version;if(typeof V!=="string")continue;if(jK(V,Z))return{path:z,version:V}}catch{continue}}return null}function jy0(){return fi(B2(),"cache","last-seen-version.json")}function Fy0(Z,$={}){try{if(gi())return!1;if(FZ(Z)===null)return!1;let J=$.seenFile??jy0(),X=null;try{let Q=JSON.parse(uN(J,"utf-8")).version;if(typeof Q==="string"&&FZ(Q)!==null)X=Q}catch{}if(X!==null&&!jK(Z,X))return!1;try{lR(XY(J),{recursive:!0}),aR(J,JSON.stringify({version:Z}),"utf-8")}catch{return!1}if(X===null)return!1;return($.write??((Q)=>process.stderr.write(Q)))(`Loki Mode upgraded ${X} -> ${Z}. What is new: https://github.com/asklokesh/loki-mode/releases/tag/v${Z}
|
|
3
3
|
`),!0}catch{return!1}}function Cy0(Z){let $=Z.replace(/\\/g,"/");if($.includes("/Cellar/"))return"brew upgrade loki-mode";if(/\/pnpm\//.test($)||$.includes("/.pnpm/"))return"pnpm add -g loki-mode (or npm i -g loki-mode)";if($.includes("/yarn/global/")||$.includes("/.yarn/"))return"yarn global add loki-mode (or npm i -g loki-mode)";if($.includes("/.bun/"))return"bun install -g loki-mode (or npm i -g loki-mode)";if($.includes("/lib/node_modules/"))return"npm i -g loki-mode (or bun install -g loki-mode)";if($.includes("/homebrew/"))return"brew upgrade loki-mode";return"bun install -g loki-mode (or npm i -g loki-mode)"}async function ui(Z,$={}){try{if(gi())return;if(FZ(Z)===null)return;let J=$.write??((Q)=>process.stderr.write(Q));Fy0(Z,{write:J,...$.cacheFile?{seenFile:dR(XY($.cacheFile),"last-seen-version.json")}:{}});let X=Ly0(Z,$.env??process.env);if(X!==null){J(`Loki Mode ${X.version} is installed but not the one running (you are running ${Z}).
|
|
4
4
|
Another loki earlier on PATH is winning. Newer copy: ${X.path}
|
|
5
5
|
Run \`which -a loki\` to see the order, then remove or re-point the earlier entry.
|
|
@@ -3238,4 +3238,4 @@ Unknown commands exit 2 with a suggestion; run 'loki help' for the full list.
|
|
|
3238
3238
|
`);{let{suggestCommand:X}=await Promise.resolve().then(() => (t4(),Lo)),Y=$===void 0?void 0:X($);if(Y)process.stderr.write(`Did you mean 'loki ${Y}'?
|
|
3239
3239
|
`)}return process.stderr.write(fb0),2}}dF0();var gb0=()=>globalThis[Symbol.for("loki.ownsStopSignals")]===!0;process.on("SIGINT",()=>{if(!gb0())process.exit(130)});process.on("SIGTERM",()=>{if(!gb0())process.exit(143)});var Qq9=await Yq9(Bun.argv.slice(2));process.exit(Qq9);
|
|
3240
3240
|
|
|
3241
|
-
//# debugId=
|
|
3241
|
+
//# debugId=A5A3988F2D1DA5190300EA7441A8DA12
|
package/mcp/__init__.py
CHANGED
package/mcp/cp_tools.py
CHANGED
|
@@ -251,6 +251,9 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
251
251
|
async def cp_runs_search(verdict: str = "", repo: str = "", since: str = "", until: str = "",
|
|
252
252
|
group_id: str = "", limit: int = 50, cursor: str = "") -> str:
|
|
253
253
|
"""Search runs across every repo known to the Control Plane (read-only).
|
|
254
|
+
Use it to find runs across repos by verdict, repo, date range or group
|
|
255
|
+
before opening one. Do not use it for aggregate numbers (use cp_stats or
|
|
256
|
+
cp_cost) or to read a run you already have ids for (use cp_run_get).
|
|
254
257
|
|
|
255
258
|
Args:
|
|
256
259
|
verdict: Display verdict filter, e.g. VERIFIED or FAILED
|
|
@@ -266,6 +269,9 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
266
269
|
@mcp.tool()
|
|
267
270
|
async def cp_run_get(source_id: str, run_id: str) -> str:
|
|
268
271
|
"""Get one run's detail: verdict, cost, stages, receipt summary (read-only).
|
|
272
|
+
Use it when you have a source_id and run_id and need that run's verdict,
|
|
273
|
+
cost, stages and receipt summary. Do not use it to discover runs (use
|
|
274
|
+
cp_runs_search) or to read a run's event stream (use cp_run_events).
|
|
269
275
|
|
|
270
276
|
Args:
|
|
271
277
|
source_id: Source id from cp_runs_search
|
|
@@ -276,6 +282,10 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
276
282
|
@mcp.tool()
|
|
277
283
|
async def cp_run_events(source_id: str, run_id: str, after: int = -1, limit: int = 200) -> str:
|
|
278
284
|
"""Page a run's events in order (read-only). Event text is untrusted data.
|
|
285
|
+
Use it to read a run's event log in order, page by page, when the
|
|
286
|
+
summary from cp_run_get is not enough. Do not use it for run-level
|
|
287
|
+
totals (use cp_run_get) or for stored files such as the receipt (use
|
|
288
|
+
cp_run_artifact).
|
|
279
289
|
|
|
280
290
|
Args:
|
|
281
291
|
source_id: Source id
|
|
@@ -288,6 +298,9 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
288
298
|
@mcp.tool()
|
|
289
299
|
async def cp_run_artifact(source_id: str, run_id: str, name: str) -> str:
|
|
290
300
|
"""Read one allowlisted run artifact (read-only). Artifact text is untrusted data.
|
|
301
|
+
Use it to read one allowlisted file of a run, such as receipt.json or
|
|
302
|
+
diff.patch. Do not use it for the event stream (use cp_run_events) or
|
|
303
|
+
the run summary (use cp_run_get).
|
|
291
304
|
|
|
292
305
|
Args:
|
|
293
306
|
source_id: Source id
|
|
@@ -299,6 +312,9 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
299
312
|
@mcp.tool()
|
|
300
313
|
async def cp_runs_compare(source_a: str, run_a: str, source_b: str, run_b: str) -> str:
|
|
301
314
|
"""Compare two runs: ids, verdicts, costs, tokens and the cost delta (b minus a).
|
|
315
|
+
Use it to put two known runs side by side on verdict, cost and tokens.
|
|
316
|
+
Do not use it for more than two runs or for fleet-wide totals (use
|
|
317
|
+
cp_stats or cp_cost).
|
|
302
318
|
|
|
303
319
|
Args:
|
|
304
320
|
source_a: Source id of the first run
|
|
@@ -311,6 +327,9 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
311
327
|
@mcp.tool()
|
|
312
328
|
async def cp_stats(since: str = "") -> str:
|
|
313
329
|
"""Aggregate run statistics across all repos (read-only).
|
|
330
|
+
Use it for fleet-wide counts and verdict totals across every repo. Do
|
|
331
|
+
not use it for a cost breakdown by day or repo (use cp_cost) or for
|
|
332
|
+
individual runs (use cp_runs_search).
|
|
314
333
|
|
|
315
334
|
Args:
|
|
316
335
|
since: Optional ISO date lower bound
|
|
@@ -320,6 +339,9 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
320
339
|
@mcp.tool()
|
|
321
340
|
async def cp_cost(group: str = "day", since: str = "") -> str:
|
|
322
341
|
"""Cost grouped by dimension, e.g. day or repo (read-only).
|
|
342
|
+
Use it when you need spend grouped by a dimension such as day or repo.
|
|
343
|
+
Do not use it for verdict or run counts (use cp_stats) or for one run's
|
|
344
|
+
cost (use cp_run_get).
|
|
323
345
|
|
|
324
346
|
Args:
|
|
325
347
|
group: Comma list of dimensions the Control Plane supports
|
|
@@ -329,5 +351,9 @@ def register_cp_tools(mcp, client_factory: Callable[[], CpClient] = CpClient) ->
|
|
|
329
351
|
|
|
330
352
|
@mcp.tool()
|
|
331
353
|
async def cp_repos_list() -> str:
|
|
332
|
-
"""List repo display names known to the Control Plane (names only, no paths).
|
|
354
|
+
"""List repo display names known to the Control Plane (names only, no paths).
|
|
355
|
+
Use it to learn which repo names the Control Plane knows before
|
|
356
|
+
filtering with cp_runs_search. Do not use it to look up runs or paths,
|
|
357
|
+
because it returns display names only.
|
|
358
|
+
"""
|
|
333
359
|
return json.dumps(repos_list(client_factory()))
|
package/mcp/lsp_proxy.py
CHANGED
|
@@ -916,6 +916,10 @@ mcp = _build_lsp_fastmcp()
|
|
|
916
916
|
async def lsp_find_references(file: str, line: int, character: int,
|
|
917
917
|
include_declaration: bool = False) -> str:
|
|
918
918
|
"""Find references to the symbol at the given file / line / character.
|
|
919
|
+
Use it to see every place a symbol at a known file, line and character is used,
|
|
920
|
+
for example before renaming it. Do not use it to jump to the definition (use
|
|
921
|
+
lsp_go_to_definition) or when you only know the name (use lsp_workspace_symbols
|
|
922
|
+
first).
|
|
919
923
|
|
|
920
924
|
Args:
|
|
921
925
|
file: Absolute or cwd-relative path to the source file.
|
|
@@ -940,6 +944,9 @@ async def lsp_find_references(file: str, line: int, character: int,
|
|
|
940
944
|
async def lsp_go_to_definition(file: str, line: int, character: int) -> str:
|
|
941
945
|
"""Resolve the definition location for the symbol at file / line /
|
|
942
946
|
character.
|
|
947
|
+
Use it when you have a file position and want the file and line where that
|
|
948
|
+
symbol is defined. Do not use it when you only have a name (use
|
|
949
|
+
lsp_find_definition_by_name) or want usages (use lsp_find_references).
|
|
943
950
|
|
|
944
951
|
Args:
|
|
945
952
|
file: Absolute or cwd-relative path to the source file.
|
|
@@ -962,6 +969,9 @@ async def lsp_symbol_at_position(file: str, line: int, character: int) -> str:
|
|
|
962
969
|
"""Return the hover / symbol info at the given file / line /
|
|
963
970
|
character. Uses LSP `textDocument/hover` which returns a
|
|
964
971
|
`MarkupContent` plus an optional range.
|
|
972
|
+
Use it to read the type and documentation of the symbol at a known position
|
|
973
|
+
without opening its definition. Do not use it to locate the definition (use
|
|
974
|
+
lsp_go_to_definition) or to check that a name exists (use lsp_check_exists).
|
|
965
975
|
|
|
966
976
|
Args:
|
|
967
977
|
file: Absolute or cwd-relative path to the source file.
|
|
@@ -1099,6 +1109,10 @@ def _lsp_check_exists_blocking(symbol: str, kind: Optional[str] = None,
|
|
|
1099
1109
|
async def lsp_check_exists(symbol: str, kind: Optional[str] = None,
|
|
1100
1110
|
language: Optional[str] = None) -> str:
|
|
1101
1111
|
"""Cheap existence check for a symbol in the current workspace.
|
|
1112
|
+
Call it before writing a reference to a symbol you have not read, because it
|
|
1113
|
+
answers quickly and is cheap. Do not use it to find where the symbol lives (use
|
|
1114
|
+
lsp_find_definition_by_name) or to search by concept (use
|
|
1115
|
+
lsp_workspace_symbols).
|
|
1102
1116
|
|
|
1103
1117
|
The single most useful grounding primitive: an agent about to write
|
|
1104
1118
|
`flightApi.getStatus()` should call `lsp_check_exists("getStatus")`
|
|
@@ -1172,6 +1186,9 @@ def _lsp_get_diagnostics_blocking(file: str) -> str:
|
|
|
1172
1186
|
@mcp.tool()
|
|
1173
1187
|
async def lsp_get_diagnostics(file: str) -> str:
|
|
1174
1188
|
"""Return current LSP diagnostics (errors + warnings) for a file.
|
|
1189
|
+
Call it after editing a file to see new errors and warnings before the next
|
|
1190
|
+
iteration. Do not use it to look up symbols (use lsp_check_exists or
|
|
1191
|
+
lsp_workspace_symbols); it reports problems in one file only.
|
|
1175
1192
|
|
|
1176
1193
|
Diagnostics are published asynchronously by LSP servers via
|
|
1177
1194
|
`textDocument/publishDiagnostics`. This tool opens the file (if not
|
|
@@ -1229,6 +1246,9 @@ def _lsp_workspace_symbols_blocking(query: str, limit: int = 20,
|
|
|
1229
1246
|
async def lsp_workspace_symbols(query: str, limit: int = 20,
|
|
1230
1247
|
language: Optional[str] = None) -> str:
|
|
1231
1248
|
"""Fuzzy-search symbols across the entire workspace.
|
|
1249
|
+
Use it when you know the concept but not the identifier. Do not use it to verify
|
|
1250
|
+
a single known name (use lsp_check_exists) or to get one definition location
|
|
1251
|
+
(use lsp_find_definition_by_name).
|
|
1232
1252
|
|
|
1233
1253
|
Use when an agent is hunting for the right name (knows the
|
|
1234
1254
|
function/class is about "config loading" but isn't sure of the
|
|
@@ -1288,6 +1308,9 @@ async def lsp_find_definition_by_name(symbol: str,
|
|
|
1288
1308
|
"""Find where a named symbol is defined, without needing a file
|
|
1289
1309
|
position upfront. Convenience wrapper: runs workspace/symbol then
|
|
1290
1310
|
returns the first result's location.
|
|
1311
|
+
Use it when you know the symbol name but have no file position. Do not use it
|
|
1312
|
+
when you already have a position (use lsp_go_to_definition) or only a fuzzy
|
|
1313
|
+
concept (use lsp_workspace_symbols).
|
|
1291
1314
|
|
|
1292
1315
|
Args:
|
|
1293
1316
|
symbol: Symbol name to find.
|
package/mcp/managed_tools.py
CHANGED
|
@@ -227,6 +227,10 @@ def register_managed_tools(mcp) -> None:
|
|
|
227
227
|
async def loki_memory_redact(pattern: str, scope: str = "all") -> str:
|
|
228
228
|
"""
|
|
229
229
|
Redact memory versions in the managed-agents store whose content matches a regex.
|
|
230
|
+
Use it to redact sensitive content, for example a leaked secret, from
|
|
231
|
+
managed memory versions that match a regex. Do not use it to read or
|
|
232
|
+
search memory (use mem_search or loki_memory_retrieve); it needs managed
|
|
233
|
+
memory enabled.
|
|
230
234
|
|
|
231
235
|
Iterates memory versions within the requested scope and calls
|
|
232
236
|
``client.beta.memory_stores.memory_versions.redact(...)`` for each
|
package/mcp/server.py
CHANGED
|
@@ -610,6 +610,10 @@ async def loki_memory_retrieve(
|
|
|
610
610
|
) -> str:
|
|
611
611
|
"""
|
|
612
612
|
Retrieve relevant memories for a task using task-aware retrieval.
|
|
613
|
+
Use it at the start of a task to pull the memories most relevant to what you are
|
|
614
|
+
about to do, ranked for the task type. Do not use it for exact keyword lookups
|
|
615
|
+
(use mem_search), for recent history (use mem_timeline) or to fetch known ids
|
|
616
|
+
(use mem_get).
|
|
613
617
|
|
|
614
618
|
Args:
|
|
615
619
|
query: Search query describing what you're looking for
|
|
@@ -677,6 +681,10 @@ async def loki_memory_store_pattern(
|
|
|
677
681
|
) -> str:
|
|
678
682
|
"""
|
|
679
683
|
Store a new semantic pattern learned during this session.
|
|
684
|
+
Use it to save a reusable lesson with its correct and incorrect approach so
|
|
685
|
+
later sessions can retrieve it. Do not use it to log what happened this session
|
|
686
|
+
(use loki_memory_capture_session_summary) or to read patterns back (use
|
|
687
|
+
loki_memory_retrieve).
|
|
680
688
|
|
|
681
689
|
Args:
|
|
682
690
|
pattern: Brief description of the pattern
|
|
@@ -735,6 +743,10 @@ async def loki_memory_store_pattern(
|
|
|
735
743
|
async def loki_task_queue_list() -> str:
|
|
736
744
|
"""
|
|
737
745
|
List all tasks in the Loki Mode task queue.
|
|
746
|
+
Use it to see every queued task with its status and priority before adding or
|
|
747
|
+
updating one. Do not use it to change tasks (use loki_task_queue_add or
|
|
748
|
+
loki_task_queue_update) or for overall project progress (use
|
|
749
|
+
loki_project_status).
|
|
738
750
|
|
|
739
751
|
Returns:
|
|
740
752
|
JSON array of tasks with status, priority, and description
|
|
@@ -788,6 +800,9 @@ async def loki_task_queue_add(
|
|
|
788
800
|
) -> str:
|
|
789
801
|
"""
|
|
790
802
|
Add a new task to the Loki Mode task queue.
|
|
803
|
+
Use it to queue new work with a title, description, priority and SDLC phase. Do
|
|
804
|
+
not use it to change an existing task (use loki_task_queue_update) or to see
|
|
805
|
+
what is already queued (use loki_task_queue_list).
|
|
791
806
|
|
|
792
807
|
Args:
|
|
793
808
|
title: Brief task title
|
|
@@ -884,6 +899,9 @@ async def loki_task_queue_update(
|
|
|
884
899
|
) -> str:
|
|
885
900
|
"""
|
|
886
901
|
Update a task's status or priority.
|
|
902
|
+
Use it to change the status or priority of a task that is already queued. Do not
|
|
903
|
+
use it to create tasks (use loki_task_queue_add) or to declare the whole project
|
|
904
|
+
finished (use loki_complete_task).
|
|
887
905
|
|
|
888
906
|
Args:
|
|
889
907
|
task_id: ID of the task to update
|
|
@@ -959,6 +977,10 @@ async def loki_task_queue_update(
|
|
|
959
977
|
async def loki_state_get() -> str:
|
|
960
978
|
"""
|
|
961
979
|
Get the current Loki Mode state including phase, metrics, and status.
|
|
980
|
+
Use it for a quick read of the current phase, autonomy state and memory presence
|
|
981
|
+
from the .loki directory. Do not use it for task counts and agent activity (use
|
|
982
|
+
loki_project_status) or for token and cost numbers (use
|
|
983
|
+
loki_metrics_efficiency).
|
|
962
984
|
|
|
963
985
|
Returns:
|
|
964
986
|
JSON object with current state information
|
|
@@ -1013,6 +1035,9 @@ async def loki_state_get() -> str:
|
|
|
1013
1035
|
async def loki_metrics_efficiency() -> str:
|
|
1014
1036
|
"""
|
|
1015
1037
|
Get efficiency metrics for the current session.
|
|
1038
|
+
Use it to see token usage, tool calls and efficiency ratios for the current
|
|
1039
|
+
session. Do not use it for per-agent breakdowns (use loki_agent_metrics) or for
|
|
1040
|
+
run state (use loki_state_get).
|
|
1016
1041
|
|
|
1017
1042
|
Returns:
|
|
1018
1043
|
JSON object with token usage, tool calls, and efficiency ratios
|
|
@@ -1065,6 +1090,10 @@ async def loki_memory_capture_session_summary(
|
|
|
1065
1090
|
duration_seconds: int = 0,
|
|
1066
1091
|
) -> str:
|
|
1067
1092
|
"""v7.7.18 capture wedge: store an episode for the current agent session.
|
|
1093
|
+
Call it once at iteration close to record what happened as an episode in the
|
|
1094
|
+
project memory. Do not use it to store a reusable lesson (use
|
|
1095
|
+
loki_memory_store_pattern) or to distill many episodes into patterns (use
|
|
1096
|
+
loki_consolidate_memory).
|
|
1068
1097
|
|
|
1069
1098
|
Call this voluntarily at iteration close (or session end) to write a
|
|
1070
1099
|
structured Episode into the project's .loki/memory/ store. Solves
|
|
@@ -1148,6 +1177,10 @@ async def loki_memory_capture_session_summary(
|
|
|
1148
1177
|
async def loki_consolidate_memory(since_hours: int = 24) -> str:
|
|
1149
1178
|
"""
|
|
1150
1179
|
Run memory consolidation to extract patterns from recent episodes.
|
|
1180
|
+
Use it to turn recent episodes into semantic patterns, typically after several
|
|
1181
|
+
sessions have written episodes. Do not use it to record the current session (use
|
|
1182
|
+
loki_memory_capture_session_summary) or to search what is stored (use
|
|
1183
|
+
mem_search).
|
|
1151
1184
|
|
|
1152
1185
|
Args:
|
|
1153
1186
|
since_hours: Process episodes from the last N hours
|
|
@@ -1188,6 +1221,10 @@ async def loki_complete_task(
|
|
|
1188
1221
|
) -> str:
|
|
1189
1222
|
"""
|
|
1190
1223
|
Declare that the current PRD / task is complete.
|
|
1224
|
+
Call it once, when the PRD or task is fully done and verified, so the
|
|
1225
|
+
orchestrator stops the iteration loop. Do not call it for a single finished
|
|
1226
|
+
subtask (use loki_task_queue_update) or to report progress (use
|
|
1227
|
+
loki_project_status).
|
|
1191
1228
|
|
|
1192
1229
|
Replaces the legacy 'COMPLETION PROMISE FULFILLED: ...' prose string with a
|
|
1193
1230
|
structured tool call. The orchestrator (run.sh) detects this via a signal
|
|
@@ -1381,6 +1418,9 @@ async def get_pending_tasks() -> str:
|
|
|
1381
1418
|
async def loki_v10_run(ref: str, repo_path: str) -> str:
|
|
1382
1419
|
"""
|
|
1383
1420
|
Start a Loki 10 run in the background (same engine as `loki <ref>`).
|
|
1421
|
+
Use it to start a Loki 10 run in the background for a task text or issue
|
|
1422
|
+
reference. Do not use it to follow a run that is already started (use
|
|
1423
|
+
loki_v10_status) or to check a finished receipt (use loki_v10_verify).
|
|
1384
1424
|
|
|
1385
1425
|
Args:
|
|
1386
1426
|
ref: Task text or issue reference (owner/repo#N or issue URL)
|
|
@@ -1406,6 +1446,9 @@ async def loki_v10_run(ref: str, repo_path: str) -> str:
|
|
|
1406
1446
|
async def loki_v10_status(repo_path: str, run_id: str = "") -> str:
|
|
1407
1447
|
"""
|
|
1408
1448
|
Read the state of a Loki 10 run from its events log.
|
|
1449
|
+
Use it to poll a Loki 10 run for its phase, verdict and cost after starting one.
|
|
1450
|
+
Do not use it to start a run (use loki_v10_run) or to check a receipt (use
|
|
1451
|
+
loki_v10_verify).
|
|
1409
1452
|
|
|
1410
1453
|
Args:
|
|
1411
1454
|
repo_path: Repository directory containing .loki/runs
|
|
@@ -1431,6 +1474,9 @@ async def loki_v10_status(repo_path: str, run_id: str = "") -> str:
|
|
|
1431
1474
|
async def loki_v10_verify(receipt_path: str = "", repo_path: str = "") -> str:
|
|
1432
1475
|
"""
|
|
1433
1476
|
Run `loki verify` on a receipt (or the newest run of a repo).
|
|
1477
|
+
Use it to re-verify a finished run's receipt through the same check as `loki
|
|
1478
|
+
verify`. Do not use it to follow a run in progress (use loki_v10_status) or to
|
|
1479
|
+
check changed files quickly (use loki_verify_fast).
|
|
1434
1480
|
|
|
1435
1481
|
Args:
|
|
1436
1482
|
receipt_path: Path to a receipt.json (takes priority)
|
|
@@ -1457,6 +1503,9 @@ async def loki_v10_verify(receipt_path: str = "", repo_path: str = "") -> str:
|
|
|
1457
1503
|
async def loki_start_project(prd_content: str = "", prd_path: str = "") -> str:
|
|
1458
1504
|
"""
|
|
1459
1505
|
Start a new Loki Mode project from a PRD.
|
|
1506
|
+
Use it to initialize a Loki Mode project from a PRD given inline or by path. Do
|
|
1507
|
+
not use it for a single task or issue reference (use loki_v10_run) or to inspect
|
|
1508
|
+
a running project (use loki_project_status).
|
|
1460
1509
|
|
|
1461
1510
|
Args:
|
|
1462
1511
|
prd_content: Inline PRD content (takes priority over prd_path)
|
|
@@ -1520,6 +1569,10 @@ async def loki_start_project(prd_content: str = "", prd_path: str = "") -> str:
|
|
|
1520
1569
|
async def loki_project_status() -> str:
|
|
1521
1570
|
"""
|
|
1522
1571
|
Get the current project status including RARV cycle state, agent activity, and task progress.
|
|
1572
|
+
Use it for the broad picture: RARV cycle state, agent activity and task counts.
|
|
1573
|
+
Do not use it for the raw phase and memory presence (use loki_state_get),
|
|
1574
|
+
quality gates (use loki_quality_report) or token metrics (use
|
|
1575
|
+
loki_agent_metrics).
|
|
1523
1576
|
|
|
1524
1577
|
Returns:
|
|
1525
1578
|
JSON with project status, phase, iteration, agents, and task counts
|
|
@@ -1612,6 +1665,9 @@ def _honest_efficiency_record(rec):
|
|
|
1612
1665
|
async def loki_agent_metrics() -> str:
|
|
1613
1666
|
"""
|
|
1614
1667
|
Get agent metrics including token usage, task completion rates, and timing.
|
|
1668
|
+
Use it to compare agents on token usage, completion rate and timing. Do not use
|
|
1669
|
+
it for session-wide efficiency ratios (use loki_metrics_efficiency) or for task
|
|
1670
|
+
progress (use loki_project_status).
|
|
1615
1671
|
|
|
1616
1672
|
Returns:
|
|
1617
1673
|
JSON with per-agent metrics and aggregates
|
|
@@ -1653,6 +1709,9 @@ async def loki_agent_metrics() -> str:
|
|
|
1653
1709
|
async def loki_checkpoint_restore(checkpoint_id: str = "") -> str:
|
|
1654
1710
|
"""
|
|
1655
1711
|
List available checkpoints or restore project state from a specific checkpoint.
|
|
1712
|
+
Call it with no id to list checkpoints and with an id to restore project state,
|
|
1713
|
+
which changes project state. Do not use it to read current state (use
|
|
1714
|
+
loki_state_get); list first so you restore the right checkpoint.
|
|
1656
1715
|
|
|
1657
1716
|
Args:
|
|
1658
1717
|
checkpoint_id: ID of checkpoint to restore (empty = list all)
|
|
@@ -1707,6 +1766,9 @@ async def loki_checkpoint_restore(checkpoint_id: str = "") -> str:
|
|
|
1707
1766
|
async def loki_quality_report() -> str:
|
|
1708
1767
|
"""
|
|
1709
1768
|
Get quality gate results including blind review scores, council verdicts, and test coverage.
|
|
1769
|
+
Use it for gate results, council verdicts and coverage for the project. Do not
|
|
1770
|
+
use it for the individual review findings of one iteration (use loki_findings)
|
|
1771
|
+
or for overall progress (use loki_project_status).
|
|
1710
1772
|
|
|
1711
1773
|
Returns:
|
|
1712
1774
|
JSON with quality gate status, review results, and coverage metrics
|
|
@@ -1872,6 +1934,10 @@ async def loki_code_search(
|
|
|
1872
1934
|
type_filter: Optional[str] = None,
|
|
1873
1935
|
) -> str:
|
|
1874
1936
|
"""Search the loki-mode codebase semantically.
|
|
1937
|
+
Use it when you know what the code does but not its name, because it ranks by
|
|
1938
|
+
meaning. Do not use it for relationship questions across files (use
|
|
1939
|
+
loki_graph_query), for exact names (use lsp_workspace_symbols) or to check index
|
|
1940
|
+
health (use loki_code_search_stats).
|
|
1875
1941
|
|
|
1876
1942
|
Finds functions, classes, and code sections by meaning, not just keywords.
|
|
1877
1943
|
Returns file paths, line numbers, and code snippets ranked by relevance.
|
|
@@ -1992,6 +2058,9 @@ async def loki_code_search(
|
|
|
1992
2058
|
@mcp.tool()
|
|
1993
2059
|
async def loki_code_search_stats() -> str:
|
|
1994
2060
|
"""Get statistics about the code search index.
|
|
2061
|
+
Use it to confirm the code search index exists and is up to date before trusting
|
|
2062
|
+
results. Do not use it to search code (use loki_code_search); it returns counts
|
|
2063
|
+
only.
|
|
1995
2064
|
|
|
1996
2065
|
Shows total chunks, files indexed, breakdown by language and type.
|
|
1997
2066
|
Useful for verifying the index is up to date.
|
|
@@ -2060,6 +2129,10 @@ async def mem_search(
|
|
|
2060
2129
|
) -> str:
|
|
2061
2130
|
"""
|
|
2062
2131
|
Search memory using full-text search (FTS5).
|
|
2132
|
+
Use it for fast keyword lookups across stored memory with AND, OR, NOT and
|
|
2133
|
+
prefix matching. Do not use it for task-aware ranking (use
|
|
2134
|
+
loki_memory_retrieve), for recent history (use mem_timeline) or to read full
|
|
2135
|
+
entries (use mem_get).
|
|
2063
2136
|
|
|
2064
2137
|
Fast keyword search across all memory types. Supports AND, OR, NOT
|
|
2065
2138
|
operators and prefix matching (e.g. "debug*").
|
|
@@ -2159,6 +2232,9 @@ async def mem_timeline(
|
|
|
2159
2232
|
) -> str:
|
|
2160
2233
|
"""
|
|
2161
2234
|
Get chronological context from memory timeline.
|
|
2235
|
+
Use it to see what happened recently, or around one memory entry, in time order.
|
|
2236
|
+
Do not use it to find entries by keyword (use mem_search) or to rank memories
|
|
2237
|
+
for a task (use loki_memory_retrieve).
|
|
2162
2238
|
|
|
2163
2239
|
Shows recent actions, key decisions, and episode traces in time order.
|
|
2164
2240
|
Use around_id to get context surrounding a specific memory entry.
|
|
@@ -2229,6 +2305,9 @@ async def mem_get(
|
|
|
2229
2305
|
) -> str:
|
|
2230
2306
|
"""
|
|
2231
2307
|
Fetch full details for one or more memory entries by ID.
|
|
2308
|
+
Use it after mem_search or mem_timeline to read full details for the ids you
|
|
2309
|
+
picked. Do not use it to discover entries, because it needs ids (use mem_search
|
|
2310
|
+
or loki_memory_retrieve first).
|
|
2232
2311
|
|
|
2233
2312
|
Use after mem_search to get complete data for specific results.
|
|
2234
2313
|
|
|
@@ -2310,6 +2389,9 @@ async def loki_get_hotspots(
|
|
|
2310
2389
|
limit: int = 10,
|
|
2311
2390
|
) -> str:
|
|
2312
2391
|
"""Get the most frequently changed files in the repository.
|
|
2392
|
+
Use it to find the files that change most often so you can take extra care
|
|
2393
|
+
there. Do not use it to find which files change with a given file (use
|
|
2394
|
+
loki_get_co_changes) or to check documentation (use loki_get_doc_coverage).
|
|
2313
2395
|
|
|
2314
2396
|
Identifies code hotspots based on git commit frequency analysis.
|
|
2315
2397
|
These files deserve extra care during changes (higher risk of regressions).
|
|
@@ -2370,6 +2452,9 @@ async def loki_get_co_changes(
|
|
|
2370
2452
|
file_path: str,
|
|
2371
2453
|
) -> str:
|
|
2372
2454
|
"""Find files that frequently change together with a given file.
|
|
2455
|
+
Use it before editing a file to learn which other files usually change with it.
|
|
2456
|
+
Do not use it to rank the riskiest files overall (use loki_get_hotspots) or to
|
|
2457
|
+
read code relationships (use loki_graph_query).
|
|
2373
2458
|
|
|
2374
2459
|
Uses git co-change analysis to identify coupling between files.
|
|
2375
2460
|
Useful for understanding hidden dependencies and ensuring related
|
|
@@ -2449,6 +2534,9 @@ async def loki_get_co_changes(
|
|
|
2449
2534
|
@mcp.tool()
|
|
2450
2535
|
async def loki_get_doc_coverage() -> str:
|
|
2451
2536
|
"""Get documentation coverage status for the project.
|
|
2537
|
+
Use it to decide where documentation work is needed, based on the docs manifest.
|
|
2538
|
+
Do not use it to find risky code (use loki_get_hotspots) or to search code (use
|
|
2539
|
+
loki_code_search).
|
|
2452
2540
|
|
|
2453
2541
|
Reads from the docs manifest to report which files are documented,
|
|
2454
2542
|
which have stale documentation, and which are missing docs entirely.
|
|
@@ -2508,6 +2596,9 @@ async def loki_get_doc_coverage() -> str:
|
|
|
2508
2596
|
@mcp.tool()
|
|
2509
2597
|
async def loki_findings(iteration: int = -1) -> str:
|
|
2510
2598
|
"""Read structured code-review findings for a given iteration.
|
|
2599
|
+
Use it to read the structured review findings of one iteration, newest by
|
|
2600
|
+
default. Do not use it for gate and council summaries (use loki_quality_report)
|
|
2601
|
+
or to prepare counter-evidence (use loki_counter_evidence_template).
|
|
2511
2602
|
|
|
2512
2603
|
Args:
|
|
2513
2604
|
iteration: iteration number (default -1 = most recent).
|
|
@@ -2591,7 +2682,12 @@ async def loki_findings(iteration: int = -1) -> str:
|
|
|
2591
2682
|
|
|
2592
2683
|
@mcp.tool()
|
|
2593
2684
|
async def loki_learnings(limit: int = 50) -> str:
|
|
2594
|
-
"""Read recent learnings (newest first) from relevant-learnings.json.
|
|
2685
|
+
"""Read recent learnings (newest first) from relevant-learnings.json.
|
|
2686
|
+
Use it to read recent learnings recorded in relevant-learnings.json, newest
|
|
2687
|
+
first, to avoid repeating past mistakes. Do not use it to search or rank memory
|
|
2688
|
+
(use loki_memory_retrieve or mem_search) or to save a new lesson (use
|
|
2689
|
+
loki_memory_store_pattern).
|
|
2690
|
+
"""
|
|
2595
2691
|
_emit_tool_event_async('loki_learnings', 'start', parameters={'limit': limit})
|
|
2596
2692
|
try:
|
|
2597
2693
|
path = safe_path_join('.loki', 'state', 'relevant-learnings.json')
|
|
@@ -2629,6 +2725,10 @@ async def loki_learnings(limit: int = 50) -> str:
|
|
|
2629
2725
|
@mcp.tool()
|
|
2630
2726
|
async def loki_graph_query(question: str, budget: int = 1500, path: str = ".") -> str:
|
|
2631
2727
|
"""Answer a codebase question from a knowledge graph instead of reading files.
|
|
2728
|
+
Use it for questions about structure and relationships, such as what calls what
|
|
2729
|
+
or what depends on what, without reading files. Do not use it to find code by
|
|
2730
|
+
meaning (use loki_code_search) or for exact symbol lookups (use
|
|
2731
|
+
lsp_workspace_symbols).
|
|
2632
2732
|
|
|
2633
2733
|
WHY THIS EXISTS
|
|
2634
2734
|
Loading a large repo into context is the dominant token cost of working
|
|
@@ -2710,6 +2810,9 @@ async def loki_graph_query(question: str, budget: int = 1500, path: str = ".") -
|
|
|
2710
2810
|
@mcp.tool()
|
|
2711
2811
|
async def loki_verify_fast(path: str = ".", diff_base: str = "") -> str:
|
|
2712
2812
|
"""Verify code deterministically in milliseconds. No model call, no network.
|
|
2813
|
+
Use it for an immediate, deterministic check of a repo or its diff against a git
|
|
2814
|
+
ref. Do not use it to verify a finished run's receipt (use loki_v10_verify) or
|
|
2815
|
+
to review code quality (use loki_quality_report).
|
|
2713
2816
|
|
|
2714
2817
|
This is the embeddable verification primitive: an IDE, another agent, a CI
|
|
2715
2818
|
step, or a third-party tool can call it and get a structured verdict back
|
|
@@ -2780,6 +2883,9 @@ async def loki_verify_fast(path: str = ".", diff_base: str = "") -> str:
|
|
|
2780
2883
|
@mcp.tool()
|
|
2781
2884
|
async def loki_counter_evidence_template(iteration: int) -> str:
|
|
2782
2885
|
"""Generate a counter-evidence file template for the given iteration.
|
|
2886
|
+
Use it when you disagree with review findings and need a pre-filled file to
|
|
2887
|
+
argue each one. Do not use it to read the findings themselves (use
|
|
2888
|
+
loki_findings); it only generates the template for the iteration.
|
|
2783
2889
|
|
|
2784
2890
|
Pre-fills canonical findingId for each Critical/High finding so the
|
|
2785
2891
|
user only has to fill in `claim` + `proofType`. Save the template
|