loki-mode 8.8.1 → 8.9.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/loki +59 -6
- package/autonomy/run.sh +65 -0
- package/dashboard/__init__.py +1 -1
- package/loki-ts/dist/loki.js +107 -106
- package/mcp/__init__.py +1 -1
- package/package.json +1 -1
- package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
package/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: loki-mode
|
|
|
3
3
|
description: Autonomous spec-driven build system with a built-in trust layer. It does not call work done until it is verified (RARV-C closure loop, 8 quality gates, completion council, verified-completion evidence gate). Triggers on "Loki Mode". Takes a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Provider-agnostic. Requires --dangerously-skip-permissions flag.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Loki Mode v8.
|
|
6
|
+
# Loki Mode v8.9.0
|
|
7
7
|
|
|
8
8
|
**You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
|
|
9
9
|
|
|
@@ -469,4 +469,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
|
|
|
469
469
|
|
|
470
470
|
---
|
|
471
471
|
|
|
472
|
-
**v8.
|
|
472
|
+
**v8.9.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~410 lines core**
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
8.
|
|
1
|
+
8.9.0
|
package/autonomy/loki
CHANGED
|
@@ -17629,12 +17629,37 @@ else:
|
|
|
17629
17629
|
integrations.append(kw)
|
|
17630
17630
|
|
|
17631
17631
|
# Count database mentions
|
|
17632
|
-
|
|
17633
|
-
|
|
17634
|
-
|
|
17635
|
-
|
|
17636
|
-
|
|
17637
|
-
|
|
17632
|
+
# Count DISTINCT data stores. This feeds a +1-complexity-for-multiple
|
|
17633
|
+
# rule, so what counts as multiple is load-bearing: it pushed a
|
|
17634
|
+
# 322-word issue from moderate to complex, and complex means 18 iterations
|
|
17635
|
+
# instead of 9.
|
|
17636
|
+
#
|
|
17637
|
+
# Three ways the old flat list over-counted a single-database project:
|
|
17638
|
+
# 1. Aliases. 'postgresql' and 'postgres' were separate entries, so one
|
|
17639
|
+
# PostgreSQL app scored TWO data stores by itself. That alone tripped
|
|
17640
|
+
# the rule on a real user's issue.
|
|
17641
|
+
# 2. ORMs. prisma/typeorm/sequelize/drizzle/knex are ACCESS LAYERS, not
|
|
17642
|
+
# stores. Prisma plus PostgreSQL is one database, not two.
|
|
17643
|
+
# 3. Generic words. 'database' and 'migration' matched any PRD that used
|
|
17644
|
+
# the words at all, so a migration-to-the-database line scored two.
|
|
17645
|
+
#
|
|
17646
|
+
# Aliases collapse to one canonical name, ORMs and generic terms are gone.
|
|
17647
|
+
db_aliases = {
|
|
17648
|
+
'postgresql': 'postgres', 'postgres': 'postgres', 'psql': 'postgres',
|
|
17649
|
+
'mysql': 'mysql', 'mariadb': 'mysql',
|
|
17650
|
+
'mongodb': 'mongodb', 'mongo': 'mongodb',
|
|
17651
|
+
'sqlite': 'sqlite',
|
|
17652
|
+
'dynamodb': 'dynamodb',
|
|
17653
|
+
'cassandra': 'cassandra',
|
|
17654
|
+
'redis': 'redis',
|
|
17655
|
+
'elasticsearch': 'elasticsearch',
|
|
17656
|
+
'clickhouse': 'clickhouse',
|
|
17657
|
+
}
|
|
17658
|
+
_seen_db = set()
|
|
17659
|
+
for kw, canonical in db_aliases.items():
|
|
17660
|
+
if kw in content_lower and canonical not in _seen_db:
|
|
17661
|
+
_seen_db.add(canonical)
|
|
17662
|
+
databases.append(canonical)
|
|
17638
17663
|
|
|
17639
17664
|
# Count UI components
|
|
17640
17665
|
ui_keywords = ['dashboard', 'form', 'table', 'modal', 'navbar',
|
|
@@ -17717,6 +17742,34 @@ iteration_map = {
|
|
|
17717
17742
|
}
|
|
17718
17743
|
min_iter, max_iter = iteration_map[complexity]
|
|
17719
17744
|
|
|
17745
|
+
# --- Capability-aware iteration budget ---------------------------------------
|
|
17746
|
+
# The map above was written when a model could not hold a whole feature in one
|
|
17747
|
+
# pass, so work was chopped into many small iterations. On a frontier tier that
|
|
17748
|
+
# is now actively harmful: each iteration boundary is a context reset, and
|
|
17749
|
+
# re-planning mid-feature is where a run loses the thread and burns money.
|
|
17750
|
+
#
|
|
17751
|
+
# A frontier model should be handed the whole job and left to finish it. So the
|
|
17752
|
+
# budget is divided by the capability tier the run will actually dispatch,
|
|
17753
|
+
# rather than assuming the weakest case for everyone. The floor is 1, never 0.
|
|
17754
|
+
#
|
|
17755
|
+
# This scales the ESTIMATE and the ceiling, not the work. A run that genuinely
|
|
17756
|
+
# needs more iterations still takes them; nothing here forces an early stop.
|
|
17757
|
+
_tier_raw = (os.environ.get('LOKI_SESSION_MODEL') or '').strip().lower()
|
|
17758
|
+
_frontier = ('high', 'planning', 'opus', 'sol')
|
|
17759
|
+
_small = ('small', 'fast', 'haiku', 'luna')
|
|
17760
|
+
if _tier_raw in _frontier:
|
|
17761
|
+
# Frontier: one pass for anything short of enterprise scope.
|
|
17762
|
+
min_iter = 1
|
|
17763
|
+
max_iter = max(1, max_iter // 4)
|
|
17764
|
+
elif _tier_raw in _small:
|
|
17765
|
+
# Small models genuinely benefit from more, smaller steps.
|
|
17766
|
+
pass
|
|
17767
|
+
else:
|
|
17768
|
+
# medium / unset: the common default. Halve the legacy budget -- current
|
|
17769
|
+
# workhorse models complete in far fewer passes than this map assumed.
|
|
17770
|
+
min_iter = max(1, min_iter // 2)
|
|
17771
|
+
max_iter = max(min_iter, max_iter // 2)
|
|
17772
|
+
|
|
17720
17773
|
# Adjust based on specific counts
|
|
17721
17774
|
if endpoint_count > 10:
|
|
17722
17775
|
max_iter = max(max_iter, max_iter + endpoint_count // 5)
|
package/autonomy/run.sh
CHANGED
|
@@ -630,6 +630,70 @@ PY
|
|
|
630
630
|
export LOKI_SPEC_SHA256
|
|
631
631
|
}
|
|
632
632
|
|
|
633
|
+
# Scoped-change profile: a bug fix or a single feature in an EXISTING repo.
|
|
634
|
+
#
|
|
635
|
+
# Measured on a real user's run: a 322-word GitHub issue against an existing
|
|
636
|
+
# codebase spent 25+ minutes still inside iteration 1. The work itself was
|
|
637
|
+
# genuine, but the build was also running competitor web research, load and
|
|
638
|
+
# performance testing, regression simulation and UAT -- all of which default to
|
|
639
|
+
# true, and none of which a scoped issue fix needs. That is the difference
|
|
640
|
+
# between a 5-minute fix and a 30-minute one.
|
|
641
|
+
#
|
|
642
|
+
# What this NEVER touches: code review, security, tests, E2E, and the
|
|
643
|
+
# completion council all stay on. Speed here comes from not running phases that
|
|
644
|
+
# are irrelevant to the change, never from skipping verification. A greenfield
|
|
645
|
+
# build or a whole-repo refactor does not match this profile and keeps the full
|
|
646
|
+
# suite.
|
|
647
|
+
#
|
|
648
|
+
# Auto-detected rather than another flag the user has to know: an existing git
|
|
649
|
+
# repo with real history, plus a spec that reads as a scoped change. Set
|
|
650
|
+
# LOKI_SCOPED_CHANGE=0 to force the full suite, or =1 to force this profile.
|
|
651
|
+
loki_detect_scoped_change() {
|
|
652
|
+
# Explicit operator intent always wins, in both directions.
|
|
653
|
+
case "${LOKI_SCOPED_CHANGE:-}" in
|
|
654
|
+
0|false) return 1 ;;
|
|
655
|
+
1|true) return 0 ;;
|
|
656
|
+
esac
|
|
657
|
+
|
|
658
|
+
# Greenfield is not a scoped change: no repo, or a repo with almost no
|
|
659
|
+
# history, means we are building something new.
|
|
660
|
+
local target="${TARGET_DIR:-.}"
|
|
661
|
+
[ -d "$target/.git" ] || return 1
|
|
662
|
+
local commits
|
|
663
|
+
commits="$(git -C "$target" rev-list --count HEAD 2>/dev/null || echo 0)"
|
|
664
|
+
[ "${commits:-0}" -ge 5 ] || return 1
|
|
665
|
+
|
|
666
|
+
# An issue-sourced spec is the canonical scoped change: someone filed a
|
|
667
|
+
# discrete request against code that already exists.
|
|
668
|
+
[ -n "${LOKI_ISSUE_REF:-}" ] && return 0
|
|
669
|
+
case "${LOKI_PRD_FILE:-}" in
|
|
670
|
+
*prd-issue-*) return 0 ;;
|
|
671
|
+
esac
|
|
672
|
+
|
|
673
|
+
return 1
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
loki_apply_scoped_change_profile() {
|
|
677
|
+
loki_detect_scoped_change || return 0
|
|
678
|
+
|
|
679
|
+
# Off: cannot affect the correctness of a scoped change to existing code.
|
|
680
|
+
: "${LOKI_PHASE_WEB_RESEARCH:=false}"
|
|
681
|
+
: "${LOKI_PHASE_PERFORMANCE:=false}"
|
|
682
|
+
: "${LOKI_PHASE_REGRESSION:=false}"
|
|
683
|
+
: "${LOKI_PHASE_UAT:=false}"
|
|
684
|
+
|
|
685
|
+
# On: every trust gate, unchanged. These are the moat.
|
|
686
|
+
: "${LOKI_PHASE_CODE_REVIEW:=true}"
|
|
687
|
+
: "${LOKI_PHASE_SECURITY:=true}"
|
|
688
|
+
: "${LOKI_PHASE_UNIT_TESTS:=true}"
|
|
689
|
+
: "${LOKI_PHASE_E2E_TESTS:=true}"
|
|
690
|
+
|
|
691
|
+
export LOKI_PHASE_WEB_RESEARCH LOKI_PHASE_PERFORMANCE LOKI_PHASE_REGRESSION
|
|
692
|
+
export LOKI_PHASE_UAT LOKI_PHASE_CODE_REVIEW LOKI_PHASE_SECURITY
|
|
693
|
+
export LOKI_PHASE_UNIT_TESTS LOKI_PHASE_E2E_TESTS
|
|
694
|
+
export LOKI_SCOPED_CHANGE_ACTIVE=1
|
|
695
|
+
}
|
|
696
|
+
|
|
633
697
|
loki_apply_build_profile() {
|
|
634
698
|
[ "${LOKI_BUILD_PROFILE:-}" = "simple-web" ] || return 0
|
|
635
699
|
: "${LOKI_PHASE_API_TESTS:=false}"
|
|
@@ -772,6 +836,7 @@ print(catalog["providers"]["claude"]["cli_aliases"].get(os.environ["_LOKI_SELECT
|
|
|
772
836
|
export LOKI_SDK_JUDGE_MODEL LOKI_SDK_PRD_ENRICH_MODEL LOKI_SDK_REVIEW_MODEL
|
|
773
837
|
}
|
|
774
838
|
loki_apply_build_profile
|
|
839
|
+
loki_apply_scoped_change_profile
|
|
775
840
|
|
|
776
841
|
# Default hang guard for EVERY build, not just simple-web.
|
|
777
842
|
#
|