loki-mode 7.7.16 → 7.7.18

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 a spec (PRD, GitHub issue, OpenAPI doc, etc.) to deployed product with minimal human intervention. Requires --dangerously-skip-permissions flag.
4
4
  ---
5
5
 
6
- # Loki Mode v7.7.16
6
+ # Loki Mode v7.7.18
7
7
 
8
8
  **You are an autonomous agent. You make decisions. You do not ask questions. You do not stop.**
9
9
 
@@ -381,4 +381,4 @@ See `CHANGELOG.md` entries [7.5.7], [7.5.8], [7.5.13] for the per-fix list and r
381
381
 
382
382
  ---
383
383
 
384
- **v7.7.16 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
384
+ **v7.7.18 | [Autonomi](https://www.autonomi.dev/) flagship product | ~260 lines core**
package/VERSION CHANGED
@@ -1 +1 @@
1
- 7.7.16
1
+ 7.7.18
package/autonomy/loki CHANGED
@@ -7255,6 +7255,43 @@ sentrux = {
7255
7255
  'required': 'optional'
7256
7256
  }
7257
7257
 
7258
+ # v7.7.17: memory subsystem health surface. Reports the latest entries
7259
+ # from .loki/memory/.errors.log (rotated by memory/error_log.py) so
7260
+ # developers see regressions in the previously-silent-fail call sites
7261
+ # at run.sh:8724, 9087, 9136. Sibling of checks/disk/sentrux; not
7262
+ # counted in the summary tally to keep backwards-compatible numbers.
7263
+ # Inline file read (rather than importing memory.error_log) so this
7264
+ # block works regardless of the doctor's invocation cwd / sys.path.
7265
+ # v7.7.17 council fix (Opus 2): tail-only read (last 64 KB) so a
7266
+ # pathological oversize log cannot OOM the doctor command. Bash + Bun
7267
+ # emit the SAME relative path string for parity.
7268
+ memory_base = os.path.join(os.environ.get('LOKI_DIR', '.loki'), 'memory')
7269
+ _memory_log_path = os.path.join(memory_base, '.errors.log')
7270
+ _TAIL_BYTES = 64 * 1024
7271
+ memory_recent_errors = []
7272
+ if os.path.isfile(_memory_log_path):
7273
+ try:
7274
+ with open(_memory_log_path, 'rb') as _f:
7275
+ _f.seek(0, 2)
7276
+ _size = _f.tell()
7277
+ _offset = max(0, _size - _TAIL_BYTES)
7278
+ _f.seek(_offset)
7279
+ _chunk = _f.read()
7280
+ _text = _chunk.decode('utf-8', errors='replace')
7281
+ _lines = _text.split('\n')
7282
+ if _offset > 0 and _lines:
7283
+ _lines = _lines[1:] # drop possibly-partial first line
7284
+ _lines = [ln.strip() for ln in _lines if ln.strip()]
7285
+ memory_recent_errors = _lines[-5:]
7286
+ except OSError:
7287
+ memory_recent_errors = []
7288
+ memory = {
7289
+ 'errors_log_path': _memory_log_path if os.path.isfile(_memory_log_path) else None,
7290
+ 'recent_errors': memory_recent_errors,
7291
+ 'recent_error_count': len(memory_recent_errors),
7292
+ 'status': 'pass' if not memory_recent_errors else 'warn',
7293
+ }
7294
+
7258
7295
  pass_count = sum(1 for c in checks if c['status'] == 'pass')
7259
7296
  fail_count = sum(1 for c in checks if c['status'] == 'fail')
7260
7297
  warn_count = sum(1 for c in checks if c['status'] == 'warn')
@@ -7271,6 +7308,7 @@ result = {
7271
7308
  'status': disk_status
7272
7309
  },
7273
7310
  'sentrux': sentrux,
7311
+ 'memory': memory,
7274
7312
  'summary': {
7275
7313
  'passed': pass_count,
7276
7314
  'failed': fail_count,
@@ -14996,6 +15034,88 @@ except Exception as e:
14996
15034
  echo " loki memory namespace stats"
14997
15035
  ;;
14998
15036
 
15037
+ ingest)
15038
+ # v7.7.18 capture wedge: ingest a Claude Code session transcript
15039
+ # into the project's .loki/memory/ store. Solves the diagnosis
15040
+ # root cause where memory only captured during `loki start`.
15041
+ #
15042
+ # Usage:
15043
+ # loki memory ingest --from-claude-transcript <path>
15044
+ # loki memory ingest --from-stdin (reads a JSON summary doc)
15045
+ shift # drop "ingest"
15046
+ local _ingest_mode=""
15047
+ local _ingest_path=""
15048
+ while [ $# -gt 0 ]; do
15049
+ case "$1" in
15050
+ --from-claude-transcript)
15051
+ _ingest_mode="transcript"
15052
+ _ingest_path="${2:-}"
15053
+ if [ $# -ge 2 ]; then shift 2; else shift; fi
15054
+ ;;
15055
+ --from-stdin)
15056
+ _ingest_mode="stdin"
15057
+ shift
15058
+ ;;
15059
+ -h|--help)
15060
+ echo "Usage: loki memory ingest --from-claude-transcript <path>"
15061
+ echo " loki memory ingest --from-stdin (JSON doc on stdin)"
15062
+ echo ""
15063
+ echo "Honors LOKI_MEMORY_CAPTURE_DISABLED=true (escape hatch)."
15064
+ return 0
15065
+ ;;
15066
+ *) shift ;;
15067
+ esac
15068
+ done
15069
+ if [ -z "$_ingest_mode" ]; then
15070
+ echo -e "${RED}Usage: loki memory ingest --from-claude-transcript <path> | --from-stdin${NC}"
15071
+ exit 1
15072
+ fi
15073
+ local _project_root_for_ingest="${SKILL_DIR:-$(pwd)}"
15074
+ local _target_memory_dir
15075
+ _target_memory_dir="$(pwd)/.loki/memory"
15076
+ mkdir -p "$_target_memory_dir" 2>/dev/null || true
15077
+ if [ "$_ingest_mode" = "transcript" ]; then
15078
+ if [ -z "$_ingest_path" ] || [ ! -f "$_ingest_path" ]; then
15079
+ echo -e "${RED}Transcript not found: $_ingest_path${NC}"
15080
+ exit 1
15081
+ fi
15082
+ PYTHONPATH="$_project_root_for_ingest" \
15083
+ python3 -c "
15084
+ import sys, json
15085
+ from memory.ingest import ingest_from_claude_transcript
15086
+ path = ingest_from_claude_transcript(sys.argv[1], sys.argv[2])
15087
+ print(json.dumps({'episode_path': path}))
15088
+ " "$_ingest_path" "$_target_memory_dir"
15089
+ else
15090
+ PYTHONPATH="$_project_root_for_ingest" \
15091
+ python3 -c "
15092
+ import sys, json
15093
+ from memory.ingest import ingest_from_summary
15094
+ doc = json.loads(sys.stdin.read())
15095
+ path = ingest_from_summary(
15096
+ sys.argv[1],
15097
+ goal=doc.get('goal',''),
15098
+ outcome=doc.get('outcome','success'),
15099
+ files_modified=doc.get('files_modified',[]),
15100
+ files_read=doc.get('files_read',[]),
15101
+ tool_calls_summary=doc.get('tool_calls_summary',''),
15102
+ duration_seconds=int(doc.get('duration_seconds',0) or 0),
15103
+ )
15104
+ print(json.dumps({'episode_path': path}))
15105
+ " "$_target_memory_dir"
15106
+ fi
15107
+ ;;
15108
+
15109
+ # NOTE (v7.7.18 council fix Opus 2): hook installer (enable-hook /
15110
+ # disable-hook) DEFERRED to v7.7.19. Claude Code SessionEnd schema
15111
+ # requires {matcher, hooks:[{type,command}]} nested format -- not
15112
+ # the {id, command} format originally drafted. Also only fires on
15113
+ # /clear (not normal exits), and payload is JSON on stdin (not the
15114
+ # $CLAUDE_TRANSCRIPT_PATH env var). The sample hook script at
15115
+ # claude/hooks/loki-session-end.sh ships for users who want to
15116
+ # install manually; the automated installer comes after we verify
15117
+ # the exact schema empirically against a real Claude Code install.
15118
+
14999
15119
  *)
15000
15120
  echo -e "${RED}Unknown memory command: $subcommand${NC}"
15001
15121
  echo "Run 'loki memory help' for usage."
package/autonomy/run.sh CHANGED
@@ -8722,7 +8722,13 @@ try:
8722
8722
  )
8723
8723
  engine.store_episode(trace)
8724
8724
  except Exception as e:
8725
- pass # Silently fail
8725
+ # v7.7.17: replace silent-fail with structured log to .errors.log.
8726
+ # log_memory_error itself never raises (it has its own try/except).
8727
+ try:
8728
+ from memory.error_log import log_memory_error
8729
+ log_memory_error(f'{target_dir}/.loki/memory', 'store_episode_trace', e)
8730
+ except Exception:
8731
+ pass
8726
8732
  PYEOF
8727
8733
  }
8728
8734
 
@@ -9072,8 +9078,15 @@ try:
9072
9078
  json.dump({'path': str(episode_file), 'importance': importance}, f)
9073
9079
  except OSError:
9074
9080
  pass
9075
- except Exception:
9076
- pass # Silently fail -- memory capture must never break the loop
9081
+ except Exception as e:
9082
+ # v7.7.17: replace silent-fail with structured log to .errors.log.
9083
+ # log_memory_error never raises; outer try/except guards even
9084
+ # against import failure of the logger itself.
9085
+ try:
9086
+ from memory.error_log import log_memory_error
9087
+ log_memory_error(f'{target_dir}/.loki/memory', 'auto_capture_episode', e)
9088
+ except Exception:
9089
+ pass
9077
9090
  PYEOF
9078
9091
 
9079
9092
  # v6.83.0 Phase 1: RARV-C REFLECT/VERIFY shadow-write. Only when both
@@ -9128,7 +9141,12 @@ try:
9128
9141
  if result.patterns_created > 0:
9129
9142
  print(f'Memory consolidation: {result.patterns_created} patterns created')
9130
9143
  except Exception as e:
9131
- pass # Silently fail
9144
+ # v7.7.17: replace silent-fail with structured log to .errors.log.
9145
+ try:
9146
+ from memory.error_log import log_memory_error
9147
+ log_memory_error(f'{target_dir}/.loki/memory', 'run_memory_consolidation', e)
9148
+ except Exception:
9149
+ pass
9132
9150
  PYEOF
9133
9151
  }
9134
9152
 
@@ -7,7 +7,7 @@ Modules:
7
7
  control: Session control API (start/stop/pause/resume)
8
8
  """
9
9
 
10
- __version__ = "7.7.16"
10
+ __version__ = "7.7.18"
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:** v7.7.16
5
+ **Version:** v7.7.18
6
6
 
7
7
  ---
8
8