loki-mode 6.64.4 → 6.66.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 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 v6.64.4
6
+ # Loki Mode v6.66.0
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -267,4 +267,4 @@ The following features are documented in skill modules but not yet fully automat
267
267
  | Quality gates 3-reviewer system | Implemented (v5.35.0) | 5 specialist reviewers in `skills/quality-gates.md`; execution in run.sh |
268
268
  | Benchmarks (HumanEval, SWE-bench) | Infrastructure only | Runner scripts and datasets exist in `benchmarks/`; no published results |
269
269
 
270
- **v6.64.4 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
270
+ **v6.66.0 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 6.64.4
1
+ 6.66.0
package/autonomy/run.sh CHANGED
@@ -8798,10 +8798,24 @@ populate_prd_queue() {
8798
8798
  return 0
8799
8799
  fi
8800
8800
 
8801
+ # Prefer the original project PRD over generated quick-prd.md
8802
+ # quick-prd.md contains boilerplate that produces garbage tasks
8803
+ local effective_prd="$prd_file"
8804
+ if [[ "$prd_file" == *"quick-prd.md" ]] || [[ "$prd_file" == *"chat-prd.md" ]]; then
8805
+ # Look for the real PRD in the project root
8806
+ for candidate in "PRD.md" "prd.md" "requirements.md" "REQUIREMENTS.md" "spec.md" "SPEC.md"; do
8807
+ if [[ -f "$candidate" ]]; then
8808
+ effective_prd="$candidate"
8809
+ log_info "Using project PRD ($candidate) instead of generated $prd_file"
8810
+ break
8811
+ fi
8812
+ done
8813
+ fi
8814
+
8801
8815
  log_step "Parsing PRD into structured tasks..."
8802
8816
  mkdir -p ".loki/queue"
8803
8817
 
8804
- LOKI_PRD_FILE="$prd_file" python3 << 'PRD_PARSE_EOF'
8818
+ LOKI_PRD_FILE="$effective_prd" python3 << 'PRD_PARSE_EOF'
8805
8819
  import json, re, os, sys
8806
8820
 
8807
8821
  prd_path = os.environ.get("LOKI_PRD_FILE", "")
@@ -8836,17 +8850,67 @@ for line in content.split("\n"):
8836
8850
  project_name = m.group(1).strip()
8837
8851
  break
8838
8852
 
8839
- # Find feature/requirement sections
8853
+ # Helper: strip numbered prefixes like "4." or "4.1" or "6.3.2" from section names
8854
+ def strip_numbering(name):
8855
+ return re.sub(r'^\d+(\.\d+)*\.?\s*', '', name).strip()
8856
+
8857
+ # Find feature/requirement sections -- expanded keywords for real-world PRDs
8840
8858
  feature_keywords = [
8841
8859
  "features", "requirements", "key features", "core features",
8842
8860
  "functional requirements", "user stories", "deliverables",
8843
- "scope", "functionality", "capabilities", "modules"
8861
+ "project scope", "functionality", "capabilities", "modules",
8862
+ # Real-world PRD section names:
8863
+ "specification", "backend", "frontend", "api", "endpoints",
8864
+ "components", "services", "implementation", "architecture",
8865
+ "build instructions", "interface", "phase",
8866
+ "database", "data model", "workflow",
8867
+ "screens", "routes", "views", "controllers", "models",
8868
+ "pipeline", "integration", "scaffolding", "deploy",
8844
8869
  ]
8845
8870
 
8846
- # Extract features from bullet points in feature sections
8871
+ # Meta sections to skip (applied after stripping numbered prefixes).
8872
+ # Skip check runs BEFORE keyword matching so meta sections are never extracted.
8873
+ skip_keywords = {
8874
+ "table of contents", "overview", "introduction", "summary",
8875
+ "executive summary", "appendix", "references", "changelog",
8876
+ "future roadmap", "out of scope", "environment variables",
8877
+ "risks", "mitigations", "success metrics", "timeline",
8878
+ "glossary", "terminology", "revision history",
8879
+ "target audience", "tech stack", "technology", "deployment",
8880
+ "non-functional", "problem statement", "value proposition",
8881
+ "background", "metrics", "roadmap",
8882
+ }
8883
+
8884
+ def is_skip_section(name):
8885
+ """Check if a section name (after stripping numbers) matches a meta/skip section."""
8886
+ clean = strip_numbering(name).lower()
8887
+ if clean in skip_keywords:
8888
+ return True
8889
+ # Also check substring match for skip keywords
8890
+ for sk in skip_keywords:
8891
+ if sk in clean:
8892
+ return True
8893
+ return False
8894
+
8895
+ # Also skip the document title (H1 heading captured as a section name)
8896
+ h1_title = None
8897
+ for line in content.split("\n"):
8898
+ m = re.match(r'^#\s+(.+)', line)
8899
+ if m:
8900
+ h1_title = m.group(1).strip()
8901
+ break
8902
+
8903
+ # Extract features from bullet points in feature sections (keyword-matched)
8847
8904
  features = []
8848
8905
  for section_name, section_content in sections.items():
8849
- is_feature_section = any(kw in section_name.lower() for kw in feature_keywords)
8906
+ # Skip meta sections first (takes priority over keyword match)
8907
+ if is_skip_section(section_name):
8908
+ continue
8909
+ # Skip the document title section
8910
+ if h1_title and section_name == h1_title:
8911
+ continue
8912
+ clean_name = strip_numbering(section_name).lower()
8913
+ is_feature_section = any(kw in clean_name for kw in feature_keywords)
8850
8914
  if is_feature_section:
8851
8915
  # Extract numbered items or bullet points
8852
8916
  for line in section_content.split("\n"):
@@ -8859,22 +8923,71 @@ for section_name, section_content in sections.items():
8859
8923
  if raw_line and raw_line[0] in (' ', '\t'):
8860
8924
  continue
8861
8925
  feature_text = m.group(1).strip()
8926
+ # Skip boilerplate template lines
8927
+ boilerplate = {
8928
+ "complete the task described above",
8929
+ "follow existing code patterns and conventions",
8930
+ "write tests if applicable",
8931
+ "do not break existing functionality",
8932
+ "task is completed as described",
8933
+ "no errors or regressions introduced",
8934
+ "code follows project conventions",
8935
+ "keep changes minimal and focused",
8936
+ "do not refactor unrelated code",
8937
+ }
8938
+ if feature_text.lower() in boilerplate:
8939
+ continue
8862
8940
  if len(feature_text) > 10: # Skip very short lines
8863
8941
  features.append({
8864
8942
  "title": feature_text,
8865
8943
  "section": section_name,
8866
8944
  })
8867
8945
 
8868
- # If no bullet features found, extract from ## headings that look like features
8946
+ # Also extract ### sub-headings from feature sections as tasks
8947
+ for section_name, section_content in sections.items():
8948
+ if is_skip_section(section_name):
8949
+ continue
8950
+ if h1_title and section_name == h1_title:
8951
+ continue
8952
+ clean_name = strip_numbering(section_name).lower()
8953
+ is_feature_section = any(kw in clean_name for kw in feature_keywords)
8954
+ if is_feature_section:
8955
+ for line in section_content.split("\n"):
8956
+ sub_match = re.match(r'^###\s+(.+)', line)
8957
+ if sub_match:
8958
+ sub_title = strip_numbering(sub_match.group(1).strip())
8959
+ if len(sub_title) > 5:
8960
+ # Avoid duplicates
8961
+ if not any(f["title"] == sub_title for f in features):
8962
+ features.append({"title": sub_title, "section": section_name})
8963
+
8964
+ # Fallback: if no features found via keyword matching, extract ### sub-headings
8965
+ # from ALL non-meta sections
8869
8966
  if not features:
8870
- skip_sections = {"overview", "introduction", "summary", "target audience",
8871
- "tech stack", "technology", "deployment", "timeline",
8872
- "out of scope", "non-functional", "appendix", "references",
8873
- "problem statement", "value proposition", "background"}
8874
8967
  for section_name, section_content in sections.items():
8875
- if section_name.lower() not in skip_sections and len(section_content) > 20:
8968
+ if is_skip_section(section_name):
8969
+ continue
8970
+ if h1_title and section_name == h1_title:
8971
+ continue
8972
+ for line in section_content.split("\n"):
8973
+ sub_match = re.match(r'^###\s+(.+)', line)
8974
+ if sub_match:
8975
+ sub_title = strip_numbering(sub_match.group(1).strip())
8976
+ if len(sub_title) > 5:
8977
+ if not any(f["title"] == sub_title for f in features):
8978
+ features.append({"title": sub_title, "section": section_name})
8979
+
8980
+ # Final fallback: extract from ## headings that are non-meta sections
8981
+ if not features:
8982
+ for section_name, section_content in sections.items():
8983
+ if is_skip_section(section_name):
8984
+ continue
8985
+ if h1_title and section_name == h1_title:
8986
+ continue
8987
+ clean_name = strip_numbering(section_name)
8988
+ if len(section_content) > 20 and len(clean_name) > 5:
8876
8989
  features.append({
8877
- "title": section_name,
8990
+ "title": clean_name,
8878
8991
  "section": "Requirements",
8879
8992
  })
8880
8993
 
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "6.64.4"
10
+ __version__ = "6.66.0"
11
11
 
12
12
  # Expose the control app for easy import
13
13
  try:
@@ -2,7 +2,7 @@
2
2
 
3
3
  The flagship product of [Autonomi](https://www.autonomi.dev/). Complete installation instructions for all platforms and use cases.
4
4
 
5
- **Version:** v6.64.4
5
+ **Version:** v6.66.0
6
6
 
7
7
  ---
8
8
 
package/mcp/__init__.py CHANGED
@@ -57,4 +57,4 @@ try:
57
57
  except ImportError:
58
58
  __all__ = ['mcp']
59
59
 
60
- __version__ = '6.64.4'
60
+ __version__ = '6.66.0'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loki-mode",
3
- "version": "6.64.4",
3
+ "version": "6.66.0",
4
4
  "description": "Loki Mode by Autonomi - Multi-agent autonomous startup system for Claude Code, Codex CLI, and Gemini CLI",
5
5
  "keywords": [
6
6
  "agent",