aidevops 2.52.1 → 2.53.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/README.md +1 -1
- package/VERSION +1 -1
- package/aidevops.sh +15 -9
- package/package.json +4 -4
- package/scripts/npm-postinstall.js +6 -7
- package/setup.sh +1 -1
- package/templates/deploy-templates.sh +144 -0
- package/templates/home/.agent/README.md +33 -0
- package/templates/home/AGENTS.md +96 -0
- package/templates/home/git/.agent/README.md +48 -0
- package/templates/home/git/AGENTS.md +97 -0
- package/templates/standard-functions.sh +179 -0
- package/templates/wordpress-performance-workflow.md +217 -0
- package/.agent/AGENTS.md +0 -614
- package/.agent/accounts.md +0 -65
- package/.agent/aidevops/add-new-mcp-to-aidevops.md +0 -456
- package/.agent/aidevops/api-integrations.md +0 -335
- package/.agent/aidevops/architecture.md +0 -510
- package/.agent/aidevops/configs.md +0 -274
- package/.agent/aidevops/docs.md +0 -244
- package/.agent/aidevops/extension.md +0 -311
- package/.agent/aidevops/mcp-integrations.md +0 -340
- package/.agent/aidevops/mcp-troubleshooting.md +0 -162
- package/.agent/aidevops/memory-patterns.md +0 -172
- package/.agent/aidevops/providers.md +0 -217
- package/.agent/aidevops/recommendations.md +0 -321
- package/.agent/aidevops/requirements.md +0 -301
- package/.agent/aidevops/resources.md +0 -214
- package/.agent/aidevops/security-requirements.md +0 -174
- package/.agent/aidevops/security.md +0 -350
- package/.agent/aidevops/service-links.md +0 -400
- package/.agent/aidevops/services.md +0 -357
- package/.agent/aidevops/setup.md +0 -153
- package/.agent/aidevops/troubleshooting.md +0 -389
- package/.agent/aidevops.md +0 -124
- package/.agent/build-plus.md +0 -244
- package/.agent/content/guidelines.md +0 -109
- package/.agent/content.md +0 -87
- package/.agent/health.md +0 -59
- package/.agent/legal.md +0 -59
- package/.agent/loop-state/full-loop.local.md +0 -16
- package/.agent/loop-state/ralph-loop.local.md +0 -10
- package/.agent/marketing.md +0 -440
- package/.agent/memory/README.md +0 -260
- package/.agent/onboarding.md +0 -796
- package/.agent/plan-plus.md +0 -245
- package/.agent/research.md +0 -100
- package/.agent/sales.md +0 -333
- package/.agent/scripts/101domains-helper.sh +0 -701
- package/.agent/scripts/add-missing-returns.sh +0 -140
- package/.agent/scripts/agent-browser-helper.sh +0 -311
- package/.agent/scripts/agno-setup.sh +0 -712
- package/.agent/scripts/ahrefs-mcp-wrapper.js +0 -168
- package/.agent/scripts/aidevops-update-check.sh +0 -71
- package/.agent/scripts/ampcode-cli.sh +0 -522
- package/.agent/scripts/auto-version-bump.sh +0 -156
- package/.agent/scripts/autogen-helper.sh +0 -512
- package/.agent/scripts/beads-sync-helper.sh +0 -596
- package/.agent/scripts/closte-helper.sh +0 -5
- package/.agent/scripts/cloudron-helper.sh +0 -321
- package/.agent/scripts/codacy-cli-chunked.sh +0 -581
- package/.agent/scripts/codacy-cli.sh +0 -442
- package/.agent/scripts/code-audit-helper.sh +0 -5
- package/.agent/scripts/coderabbit-cli.sh +0 -417
- package/.agent/scripts/coderabbit-pro-analysis.sh +0 -238
- package/.agent/scripts/commands/code-simplifier.md +0 -86
- package/.agent/scripts/commands/full-loop.md +0 -246
- package/.agent/scripts/commands/postflight-loop.md +0 -103
- package/.agent/scripts/commands/recall.md +0 -182
- package/.agent/scripts/commands/remember.md +0 -132
- package/.agent/scripts/commands/save-todo.md +0 -175
- package/.agent/scripts/commands/session-review.md +0 -154
- package/.agent/scripts/comprehensive-quality-fix.sh +0 -106
- package/.agent/scripts/context-builder-helper.sh +0 -522
- package/.agent/scripts/coolify-cli-helper.sh +0 -674
- package/.agent/scripts/coolify-helper.sh +0 -380
- package/.agent/scripts/crawl4ai-examples.sh +0 -401
- package/.agent/scripts/crawl4ai-helper.sh +0 -1078
- package/.agent/scripts/crewai-helper.sh +0 -681
- package/.agent/scripts/dev-browser-helper.sh +0 -513
- package/.agent/scripts/dns-helper.sh +0 -396
- package/.agent/scripts/domain-research-helper.sh +0 -917
- package/.agent/scripts/dspy-helper.sh +0 -285
- package/.agent/scripts/dspyground-helper.sh +0 -291
- package/.agent/scripts/eeat-score-helper.sh +0 -1242
- package/.agent/scripts/efficient-return-fix.sh +0 -92
- package/.agent/scripts/extract-opencode-prompts.sh +0 -128
- package/.agent/scripts/find-missing-returns.sh +0 -113
- package/.agent/scripts/fix-auth-headers.sh +0 -104
- package/.agent/scripts/fix-common-strings.sh +0 -254
- package/.agent/scripts/fix-content-type.sh +0 -100
- package/.agent/scripts/fix-error-messages.sh +0 -130
- package/.agent/scripts/fix-misplaced-returns.sh +0 -74
- package/.agent/scripts/fix-remaining-literals.sh +0 -152
- package/.agent/scripts/fix-return-statements.sh +0 -41
- package/.agent/scripts/fix-s131-default-cases.sh +0 -249
- package/.agent/scripts/fix-sc2155-simple.sh +0 -102
- package/.agent/scripts/fix-shellcheck-critical.sh +0 -187
- package/.agent/scripts/fix-string-literals.sh +0 -273
- package/.agent/scripts/full-loop-helper.sh +0 -773
- package/.agent/scripts/generate-opencode-agents.sh +0 -497
- package/.agent/scripts/generate-opencode-commands.sh +0 -1629
- package/.agent/scripts/generate-skills.sh +0 -366
- package/.agent/scripts/git-platforms-helper.sh +0 -640
- package/.agent/scripts/gitea-cli-helper.sh +0 -743
- package/.agent/scripts/github-cli-helper.sh +0 -702
- package/.agent/scripts/gitlab-cli-helper.sh +0 -682
- package/.agent/scripts/gsc-add-user-helper.sh +0 -325
- package/.agent/scripts/gsc-sitemap-helper.sh +0 -678
- package/.agent/scripts/hetzner-helper.sh +0 -485
- package/.agent/scripts/hostinger-helper.sh +0 -229
- package/.agent/scripts/keyword-research-helper.sh +0 -1815
- package/.agent/scripts/langflow-helper.sh +0 -544
- package/.agent/scripts/linkedin-automation.py +0 -241
- package/.agent/scripts/linter-manager.sh +0 -599
- package/.agent/scripts/linters-local.sh +0 -434
- package/.agent/scripts/list-keys-helper.sh +0 -488
- package/.agent/scripts/local-browser-automation.py +0 -339
- package/.agent/scripts/localhost-helper.sh +0 -744
- package/.agent/scripts/loop-common.sh +0 -806
- package/.agent/scripts/mainwp-helper.sh +0 -728
- package/.agent/scripts/markdown-formatter.sh +0 -338
- package/.agent/scripts/markdown-lint-fix.sh +0 -311
- package/.agent/scripts/mass-fix-returns.sh +0 -58
- package/.agent/scripts/mcp-diagnose.sh +0 -167
- package/.agent/scripts/mcp-inspector-helper.sh +0 -449
- package/.agent/scripts/memory-helper.sh +0 -650
- package/.agent/scripts/monitor-code-review.sh +0 -255
- package/.agent/scripts/onboarding-helper.sh +0 -706
- package/.agent/scripts/opencode-github-setup-helper.sh +0 -797
- package/.agent/scripts/opencode-test-helper.sh +0 -213
- package/.agent/scripts/pagespeed-helper.sh +0 -464
- package/.agent/scripts/pandoc-helper.sh +0 -362
- package/.agent/scripts/postflight-check.sh +0 -555
- package/.agent/scripts/pre-commit-hook.sh +0 -259
- package/.agent/scripts/pre-edit-check.sh +0 -169
- package/.agent/scripts/qlty-cli.sh +0 -356
- package/.agent/scripts/quality-cli-manager.sh +0 -525
- package/.agent/scripts/quality-feedback-helper.sh +0 -462
- package/.agent/scripts/quality-fix.sh +0 -263
- package/.agent/scripts/quality-loop-helper.sh +0 -1108
- package/.agent/scripts/ralph-loop-helper.sh +0 -836
- package/.agent/scripts/ralph-upstream-check.sh +0 -341
- package/.agent/scripts/secretlint-helper.sh +0 -847
- package/.agent/scripts/servers-helper.sh +0 -241
- package/.agent/scripts/ses-helper.sh +0 -619
- package/.agent/scripts/session-review-helper.sh +0 -404
- package/.agent/scripts/setup-linters-wizard.sh +0 -379
- package/.agent/scripts/setup-local-api-keys.sh +0 -330
- package/.agent/scripts/setup-mcp-integrations.sh +0 -472
- package/.agent/scripts/shared-constants.sh +0 -246
- package/.agent/scripts/site-crawler-helper.sh +0 -1487
- package/.agent/scripts/snyk-helper.sh +0 -940
- package/.agent/scripts/sonarcloud-autofix.sh +0 -193
- package/.agent/scripts/sonarcloud-cli.sh +0 -191
- package/.agent/scripts/sonarscanner-cli.sh +0 -455
- package/.agent/scripts/spaceship-helper.sh +0 -747
- package/.agent/scripts/stagehand-helper.sh +0 -321
- package/.agent/scripts/stagehand-python-helper.sh +0 -321
- package/.agent/scripts/stagehand-python-setup.sh +0 -441
- package/.agent/scripts/stagehand-setup.sh +0 -439
- package/.agent/scripts/system-cleanup.sh +0 -340
- package/.agent/scripts/terminal-title-helper.sh +0 -388
- package/.agent/scripts/terminal-title-setup.sh +0 -549
- package/.agent/scripts/test-stagehand-both-integration.sh +0 -317
- package/.agent/scripts/test-stagehand-integration.sh +0 -309
- package/.agent/scripts/test-stagehand-python-integration.sh +0 -341
- package/.agent/scripts/todo-ready.sh +0 -263
- package/.agent/scripts/tool-version-check.sh +0 -362
- package/.agent/scripts/toon-helper.sh +0 -469
- package/.agent/scripts/twilio-helper.sh +0 -917
- package/.agent/scripts/updown-helper.sh +0 -279
- package/.agent/scripts/validate-mcp-integrations.sh +0 -250
- package/.agent/scripts/validate-version-consistency.sh +0 -131
- package/.agent/scripts/vaultwarden-helper.sh +0 -597
- package/.agent/scripts/vercel-cli-helper.sh +0 -816
- package/.agent/scripts/verify-mirrors.sh +0 -169
- package/.agent/scripts/version-manager.sh +0 -831
- package/.agent/scripts/webhosting-helper.sh +0 -471
- package/.agent/scripts/webhosting-verify.sh +0 -238
- package/.agent/scripts/wordpress-mcp-helper.sh +0 -508
- package/.agent/scripts/worktree-helper.sh +0 -595
- package/.agent/scripts/worktree-sessions.sh +0 -577
- package/.agent/seo/dataforseo.md +0 -215
- package/.agent/seo/domain-research.md +0 -532
- package/.agent/seo/eeat-score.md +0 -659
- package/.agent/seo/google-search-console.md +0 -366
- package/.agent/seo/gsc-sitemaps.md +0 -282
- package/.agent/seo/keyword-research.md +0 -521
- package/.agent/seo/serper.md +0 -278
- package/.agent/seo/site-crawler.md +0 -387
- package/.agent/seo.md +0 -236
- package/.agent/services/accounting/quickfile.md +0 -159
- package/.agent/services/communications/telfon.md +0 -470
- package/.agent/services/communications/twilio.md +0 -569
- package/.agent/services/crm/fluentcrm.md +0 -449
- package/.agent/services/email/ses.md +0 -399
- package/.agent/services/hosting/101domains.md +0 -378
- package/.agent/services/hosting/closte.md +0 -177
- package/.agent/services/hosting/cloudflare.md +0 -251
- package/.agent/services/hosting/cloudron.md +0 -478
- package/.agent/services/hosting/dns-providers.md +0 -335
- package/.agent/services/hosting/domain-purchasing.md +0 -344
- package/.agent/services/hosting/hetzner.md +0 -327
- package/.agent/services/hosting/hostinger.md +0 -287
- package/.agent/services/hosting/localhost.md +0 -419
- package/.agent/services/hosting/spaceship.md +0 -353
- package/.agent/services/hosting/webhosting.md +0 -330
- package/.agent/social-media.md +0 -69
- package/.agent/templates/plans-template.md +0 -114
- package/.agent/templates/prd-template.md +0 -129
- package/.agent/templates/tasks-template.md +0 -108
- package/.agent/templates/todo-template.md +0 -89
- package/.agent/tools/ai-assistants/agno.md +0 -471
- package/.agent/tools/ai-assistants/capsolver.md +0 -326
- package/.agent/tools/ai-assistants/configuration.md +0 -221
- package/.agent/tools/ai-assistants/overview.md +0 -209
- package/.agent/tools/ai-assistants/status.md +0 -171
- package/.agent/tools/ai-assistants/windsurf.md +0 -193
- package/.agent/tools/ai-orchestration/autogen.md +0 -406
- package/.agent/tools/ai-orchestration/crewai.md +0 -445
- package/.agent/tools/ai-orchestration/langflow.md +0 -405
- package/.agent/tools/ai-orchestration/openprose.md +0 -487
- package/.agent/tools/ai-orchestration/overview.md +0 -362
- package/.agent/tools/ai-orchestration/packaging.md +0 -647
- package/.agent/tools/browser/agent-browser.md +0 -464
- package/.agent/tools/browser/browser-automation.md +0 -400
- package/.agent/tools/browser/chrome-devtools.md +0 -282
- package/.agent/tools/browser/crawl4ai-integration.md +0 -422
- package/.agent/tools/browser/crawl4ai-resources.md +0 -277
- package/.agent/tools/browser/crawl4ai-usage.md +0 -416
- package/.agent/tools/browser/crawl4ai.md +0 -585
- package/.agent/tools/browser/dev-browser.md +0 -341
- package/.agent/tools/browser/pagespeed.md +0 -260
- package/.agent/tools/browser/playwright.md +0 -266
- package/.agent/tools/browser/playwriter.md +0 -310
- package/.agent/tools/browser/stagehand-examples.md +0 -456
- package/.agent/tools/browser/stagehand-python.md +0 -483
- package/.agent/tools/browser/stagehand.md +0 -421
- package/.agent/tools/build-agent/agent-review.md +0 -224
- package/.agent/tools/build-agent/build-agent.md +0 -784
- package/.agent/tools/build-mcp/aidevops-plugin.md +0 -476
- package/.agent/tools/build-mcp/api-wrapper.md +0 -445
- package/.agent/tools/build-mcp/build-mcp.md +0 -240
- package/.agent/tools/build-mcp/deployment.md +0 -401
- package/.agent/tools/build-mcp/server-patterns.md +0 -632
- package/.agent/tools/build-mcp/transports.md +0 -366
- package/.agent/tools/code-review/auditing.md +0 -383
- package/.agent/tools/code-review/automation.md +0 -219
- package/.agent/tools/code-review/best-practices.md +0 -203
- package/.agent/tools/code-review/codacy.md +0 -151
- package/.agent/tools/code-review/code-simplifier.md +0 -174
- package/.agent/tools/code-review/code-standards.md +0 -309
- package/.agent/tools/code-review/coderabbit.md +0 -101
- package/.agent/tools/code-review/management.md +0 -155
- package/.agent/tools/code-review/qlty.md +0 -248
- package/.agent/tools/code-review/secretlint.md +0 -565
- package/.agent/tools/code-review/setup.md +0 -250
- package/.agent/tools/code-review/snyk.md +0 -563
- package/.agent/tools/code-review/tools.md +0 -230
- package/.agent/tools/content/summarize.md +0 -353
- package/.agent/tools/context/augment-context-engine.md +0 -468
- package/.agent/tools/context/context-builder-agent.md +0 -76
- package/.agent/tools/context/context-builder.md +0 -375
- package/.agent/tools/context/context7.md +0 -371
- package/.agent/tools/context/dspy.md +0 -302
- package/.agent/tools/context/dspyground.md +0 -374
- package/.agent/tools/context/llm-tldr.md +0 -219
- package/.agent/tools/context/osgrep.md +0 -488
- package/.agent/tools/context/prompt-optimization.md +0 -338
- package/.agent/tools/context/toon.md +0 -292
- package/.agent/tools/conversion/pandoc.md +0 -304
- package/.agent/tools/credentials/api-key-management.md +0 -154
- package/.agent/tools/credentials/api-key-setup.md +0 -224
- package/.agent/tools/credentials/environment-variables.md +0 -180
- package/.agent/tools/credentials/vaultwarden.md +0 -382
- package/.agent/tools/data-extraction/outscraper.md +0 -974
- package/.agent/tools/deployment/coolify-cli.md +0 -388
- package/.agent/tools/deployment/coolify-setup.md +0 -353
- package/.agent/tools/deployment/coolify.md +0 -345
- package/.agent/tools/deployment/vercel.md +0 -390
- package/.agent/tools/git/authentication.md +0 -132
- package/.agent/tools/git/gitea-cli.md +0 -193
- package/.agent/tools/git/github-actions.md +0 -207
- package/.agent/tools/git/github-cli.md +0 -223
- package/.agent/tools/git/gitlab-cli.md +0 -190
- package/.agent/tools/git/opencode-github-security.md +0 -350
- package/.agent/tools/git/opencode-github.md +0 -328
- package/.agent/tools/git/opencode-gitlab.md +0 -252
- package/.agent/tools/git/security.md +0 -196
- package/.agent/tools/git.md +0 -207
- package/.agent/tools/opencode/oh-my-opencode.md +0 -375
- package/.agent/tools/opencode/opencode-anthropic-auth.md +0 -446
- package/.agent/tools/opencode/opencode.md +0 -651
- package/.agent/tools/social-media/bird.md +0 -437
- package/.agent/tools/task-management/beads.md +0 -336
- package/.agent/tools/terminal/terminal-title.md +0 -251
- package/.agent/tools/ui/shadcn.md +0 -196
- package/.agent/tools/ui/ui-skills.md +0 -115
- package/.agent/tools/wordpress/localwp.md +0 -311
- package/.agent/tools/wordpress/mainwp.md +0 -391
- package/.agent/tools/wordpress/scf.md +0 -527
- package/.agent/tools/wordpress/wp-admin.md +0 -729
- package/.agent/tools/wordpress/wp-dev.md +0 -940
- package/.agent/tools/wordpress/wp-preferred.md +0 -398
- package/.agent/tools/wordpress.md +0 -95
- package/.agent/workflows/branch/bugfix.md +0 -63
- package/.agent/workflows/branch/chore.md +0 -95
- package/.agent/workflows/branch/experiment.md +0 -115
- package/.agent/workflows/branch/feature.md +0 -59
- package/.agent/workflows/branch/hotfix.md +0 -98
- package/.agent/workflows/branch/refactor.md +0 -92
- package/.agent/workflows/branch/release.md +0 -96
- package/.agent/workflows/branch.md +0 -347
- package/.agent/workflows/bug-fixing.md +0 -267
- package/.agent/workflows/changelog.md +0 -129
- package/.agent/workflows/code-audit-remote.md +0 -279
- package/.agent/workflows/conversation-starter.md +0 -69
- package/.agent/workflows/error-feedback.md +0 -578
- package/.agent/workflows/feature-development.md +0 -355
- package/.agent/workflows/git-workflow.md +0 -702
- package/.agent/workflows/multi-repo-workspace.md +0 -268
- package/.agent/workflows/plans.md +0 -709
- package/.agent/workflows/postflight.md +0 -604
- package/.agent/workflows/pr.md +0 -571
- package/.agent/workflows/preflight.md +0 -278
- package/.agent/workflows/ralph-loop.md +0 -773
- package/.agent/workflows/release.md +0 -498
- package/.agent/workflows/session-manager.md +0 -254
- package/.agent/workflows/session-review.md +0 -311
- package/.agent/workflows/sql-migrations.md +0 -631
- package/.agent/workflows/version-bump.md +0 -283
- package/.agent/workflows/wiki-update.md +0 -333
- package/.agent/workflows/worktree.md +0 -477
|
@@ -1,650 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# memory-helper.sh - Lightweight memory system for aidevops
|
|
3
|
-
# Uses SQLite FTS5 for fast text search without external dependencies
|
|
4
|
-
#
|
|
5
|
-
# Usage:
|
|
6
|
-
# memory-helper.sh store --content "learning" [--type TYPE] [--tags "a,b"] [--session-id ID]
|
|
7
|
-
# memory-helper.sh recall --query "search terms" [--limit 5] [--type TYPE] [--max-age-days 30]
|
|
8
|
-
# memory-helper.sh stats # Show memory statistics
|
|
9
|
-
# memory-helper.sh prune [--older-than-days 90] [--dry-run] # Remove stale entries
|
|
10
|
-
# memory-helper.sh validate # Check for stale/low-quality entries
|
|
11
|
-
# memory-helper.sh export [--format json|toon] # Export all memories
|
|
12
|
-
#
|
|
13
|
-
# Staleness Prevention:
|
|
14
|
-
# - Entries have created_at and last_accessed_at timestamps
|
|
15
|
-
# - Recall updates last_accessed_at (frequently used = valuable)
|
|
16
|
-
# - Prune removes entries older than threshold AND never accessed
|
|
17
|
-
# - Validate warns about potentially stale entries
|
|
18
|
-
|
|
19
|
-
set -euo pipefail
|
|
20
|
-
|
|
21
|
-
# Configuration
|
|
22
|
-
readonly MEMORY_DIR="${AIDEVOPS_MEMORY_DIR:-$HOME/.aidevops/.agent-workspace/memory}"
|
|
23
|
-
readonly MEMORY_DB="$MEMORY_DIR/memory.db"
|
|
24
|
-
readonly DEFAULT_MAX_AGE_DAYS=90
|
|
25
|
-
readonly STALE_WARNING_DAYS=60
|
|
26
|
-
|
|
27
|
-
# Valid learning types (matches documentation and Continuous-Claude-v3)
|
|
28
|
-
readonly VALID_TYPES="WORKING_SOLUTION FAILED_APPROACH CODEBASE_PATTERN USER_PREFERENCE TOOL_CONFIG DECISION CONTEXT ARCHITECTURAL_DECISION ERROR_FIX OPEN_THREAD"
|
|
29
|
-
|
|
30
|
-
# Colors for output
|
|
31
|
-
readonly RED='\033[0;31m'
|
|
32
|
-
readonly GREEN='\033[0;32m'
|
|
33
|
-
readonly YELLOW='\033[0;33m'
|
|
34
|
-
readonly BLUE='\033[0;34m'
|
|
35
|
-
readonly NC='\033[0m' # No Color
|
|
36
|
-
|
|
37
|
-
#######################################
|
|
38
|
-
# Print colored message
|
|
39
|
-
#######################################
|
|
40
|
-
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
|
41
|
-
log_success() { echo -e "${GREEN}[OK]${NC} $*"; }
|
|
42
|
-
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
|
43
|
-
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
|
44
|
-
|
|
45
|
-
#######################################
|
|
46
|
-
# Format JSON results as text (jq fallback)
|
|
47
|
-
# Uses jq if available, otherwise basic parsing
|
|
48
|
-
#######################################
|
|
49
|
-
format_results_text() {
|
|
50
|
-
local input
|
|
51
|
-
input=$(cat)
|
|
52
|
-
|
|
53
|
-
if [[ -z "$input" || "$input" == "[]" ]]; then
|
|
54
|
-
return 0
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
if command -v jq &>/dev/null; then
|
|
58
|
-
echo "$input" | jq -r '.[] | "[\(.type)] (\(.confidence)) - Score: \(.score // "N/A" | tostring | .[0:6])\n \(.content)\n Tags: \(.tags)\n Created: \(.created_at) | Accessed: \(.access_count)x\n"' 2>/dev/null
|
|
59
|
-
else
|
|
60
|
-
# Basic fallback without jq - parse JSON manually
|
|
61
|
-
echo "$input" | sed 's/},{/}\n{/g' | while read -r line; do
|
|
62
|
-
local type content tags created access_count
|
|
63
|
-
type=$(echo "$line" | sed -n 's/.*"type":"\([^"]*\)".*/\1/p')
|
|
64
|
-
content=$(echo "$line" | sed -n 's/.*"content":"\([^"]*\)".*/\1/p' | head -c 100)
|
|
65
|
-
tags=$(echo "$line" | sed -n 's/.*"tags":"\([^"]*\)".*/\1/p')
|
|
66
|
-
created=$(echo "$line" | sed -n 's/.*"created_at":"\([^"]*\)".*/\1/p')
|
|
67
|
-
access_count=$(echo "$line" | sed -n 's/.*"access_count":\([0-9]*\).*/\1/p')
|
|
68
|
-
[[ -n "$type" ]] && echo "[$type] $content..."
|
|
69
|
-
[[ -n "$tags" ]] && echo " Tags: $tags | Created: $created | Accessed: ${access_count:-0}x"
|
|
70
|
-
echo ""
|
|
71
|
-
done
|
|
72
|
-
fi
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
#######################################
|
|
76
|
-
# Extract IDs from JSON (jq fallback)
|
|
77
|
-
#######################################
|
|
78
|
-
extract_ids_from_json() {
|
|
79
|
-
local input
|
|
80
|
-
input=$(cat)
|
|
81
|
-
|
|
82
|
-
if command -v jq &>/dev/null; then
|
|
83
|
-
echo "$input" | jq -r '.[].id' 2>/dev/null
|
|
84
|
-
else
|
|
85
|
-
# Basic fallback - extract id values
|
|
86
|
-
echo "$input" | grep -o '"id":"[^"]*"' | sed 's/"id":"//g; s/"//g'
|
|
87
|
-
fi
|
|
88
|
-
return 0
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
#######################################
|
|
92
|
-
# Initialize database with FTS5 schema
|
|
93
|
-
#######################################
|
|
94
|
-
init_db() {
|
|
95
|
-
mkdir -p "$MEMORY_DIR"
|
|
96
|
-
|
|
97
|
-
if [[ ! -f "$MEMORY_DB" ]]; then
|
|
98
|
-
log_info "Creating memory database at $MEMORY_DB"
|
|
99
|
-
|
|
100
|
-
sqlite3 "$MEMORY_DB" <<'EOF'
|
|
101
|
-
-- FTS5 virtual table for searchable content
|
|
102
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS learnings USING fts5(
|
|
103
|
-
id UNINDEXED,
|
|
104
|
-
session_id UNINDEXED,
|
|
105
|
-
content,
|
|
106
|
-
type,
|
|
107
|
-
tags,
|
|
108
|
-
confidence UNINDEXED,
|
|
109
|
-
created_at UNINDEXED,
|
|
110
|
-
project_path UNINDEXED,
|
|
111
|
-
source UNINDEXED,
|
|
112
|
-
tokenize='porter unicode61'
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
-- Separate table for access tracking (FTS5 doesn't support UPDATE)
|
|
116
|
-
CREATE TABLE IF NOT EXISTS learning_access (
|
|
117
|
-
id TEXT PRIMARY KEY,
|
|
118
|
-
last_accessed_at TEXT,
|
|
119
|
-
access_count INTEGER DEFAULT 0
|
|
120
|
-
);
|
|
121
|
-
EOF
|
|
122
|
-
log_success "Database initialized"
|
|
123
|
-
fi
|
|
124
|
-
return 0
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
#######################################
|
|
128
|
-
# Generate unique ID
|
|
129
|
-
#######################################
|
|
130
|
-
generate_id() {
|
|
131
|
-
# Use timestamp + random for uniqueness
|
|
132
|
-
echo "mem_$(date +%Y%m%d%H%M%S)_$(head -c 4 /dev/urandom | xxd -p)"
|
|
133
|
-
return 0
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
#######################################
|
|
137
|
-
# Store a learning
|
|
138
|
-
#######################################
|
|
139
|
-
cmd_store() {
|
|
140
|
-
local content=""
|
|
141
|
-
local type="WORKING_SOLUTION"
|
|
142
|
-
local tags=""
|
|
143
|
-
local confidence="medium"
|
|
144
|
-
local session_id=""
|
|
145
|
-
local project_path=""
|
|
146
|
-
local source="manual"
|
|
147
|
-
|
|
148
|
-
while [[ $# -gt 0 ]]; do
|
|
149
|
-
case "$1" in
|
|
150
|
-
--content) content="$2"; shift 2 ;;
|
|
151
|
-
--type) type="$2"; shift 2 ;;
|
|
152
|
-
--tags) tags="$2"; shift 2 ;;
|
|
153
|
-
--confidence) confidence="$2"; shift 2 ;;
|
|
154
|
-
--session-id) session_id="$2"; shift 2 ;;
|
|
155
|
-
--project) project_path="$2"; shift 2 ;;
|
|
156
|
-
--source) source="$2"; shift 2 ;;
|
|
157
|
-
*)
|
|
158
|
-
# Allow content as positional argument
|
|
159
|
-
if [[ -z "$content" ]]; then
|
|
160
|
-
content="$1"
|
|
161
|
-
fi
|
|
162
|
-
shift ;;
|
|
163
|
-
esac
|
|
164
|
-
done
|
|
165
|
-
|
|
166
|
-
# Validate required fields
|
|
167
|
-
if [[ -z "$content" ]]; then
|
|
168
|
-
log_error "Content is required. Use --content \"your learning\""
|
|
169
|
-
return 1
|
|
170
|
-
fi
|
|
171
|
-
|
|
172
|
-
# Validate type
|
|
173
|
-
local type_pattern=" $type "
|
|
174
|
-
if [[ ! " $VALID_TYPES " =~ $type_pattern ]]; then
|
|
175
|
-
log_error "Invalid type: $type"
|
|
176
|
-
log_error "Valid types: $VALID_TYPES"
|
|
177
|
-
return 1
|
|
178
|
-
fi
|
|
179
|
-
|
|
180
|
-
# Validate confidence
|
|
181
|
-
if [[ ! "$confidence" =~ ^(high|medium|low)$ ]]; then
|
|
182
|
-
log_error "Invalid confidence: $confidence (use high, medium, or low)"
|
|
183
|
-
return 1
|
|
184
|
-
fi
|
|
185
|
-
|
|
186
|
-
# Generate session_id if not provided
|
|
187
|
-
if [[ -z "$session_id" ]]; then
|
|
188
|
-
session_id="session_$(date +%Y%m%d_%H%M%S)"
|
|
189
|
-
fi
|
|
190
|
-
|
|
191
|
-
# Get current project path if not provided
|
|
192
|
-
if [[ -z "$project_path" ]]; then
|
|
193
|
-
project_path="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
194
|
-
fi
|
|
195
|
-
|
|
196
|
-
init_db
|
|
197
|
-
|
|
198
|
-
local id
|
|
199
|
-
id=$(generate_id)
|
|
200
|
-
local created_at
|
|
201
|
-
created_at=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
202
|
-
|
|
203
|
-
# Escape single quotes for SQL
|
|
204
|
-
local escaped_content="${content//\'/\'\'}"
|
|
205
|
-
local escaped_tags="${tags//\'/\'\'}"
|
|
206
|
-
local escaped_project="${project_path//\'/\'\'}"
|
|
207
|
-
|
|
208
|
-
sqlite3 "$MEMORY_DB" <<EOF
|
|
209
|
-
INSERT INTO learnings (id, session_id, content, type, tags, confidence, created_at, project_path, source)
|
|
210
|
-
VALUES ('$id', '$session_id', '$escaped_content', '$type', '$escaped_tags', '$confidence', '$created_at', '$escaped_project', '$source');
|
|
211
|
-
EOF
|
|
212
|
-
|
|
213
|
-
log_success "Stored learning: $id"
|
|
214
|
-
echo "$id"
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
#######################################
|
|
218
|
-
# Recall learnings with search
|
|
219
|
-
#######################################
|
|
220
|
-
cmd_recall() {
|
|
221
|
-
local query=""
|
|
222
|
-
local limit=5
|
|
223
|
-
local type_filter=""
|
|
224
|
-
local max_age_days=""
|
|
225
|
-
local project_filter=""
|
|
226
|
-
local format="text"
|
|
227
|
-
local recent_mode=false
|
|
228
|
-
|
|
229
|
-
while [[ $# -gt 0 ]]; do
|
|
230
|
-
case "$1" in
|
|
231
|
-
--query|-q) query="$2"; shift 2 ;;
|
|
232
|
-
--limit|-l) limit="$2"; shift 2 ;;
|
|
233
|
-
--type|-t) type_filter="$2"; shift 2 ;;
|
|
234
|
-
--max-age-days) max_age_days="$2"; shift 2 ;;
|
|
235
|
-
--project|-p) project_filter="$2"; shift 2 ;;
|
|
236
|
-
--recent) recent_mode=true; limit="${2:-10}"; shift; [[ "${1:-}" =~ ^[0-9]+$ ]] && shift ;;
|
|
237
|
-
--format) format="$2"; shift 2 ;;
|
|
238
|
-
--json) format="json"; shift ;;
|
|
239
|
-
--stats) cmd_stats; return 0 ;;
|
|
240
|
-
*)
|
|
241
|
-
# Allow query as positional argument
|
|
242
|
-
if [[ -z "$query" ]]; then
|
|
243
|
-
query="$1"
|
|
244
|
-
fi
|
|
245
|
-
shift ;;
|
|
246
|
-
esac
|
|
247
|
-
done
|
|
248
|
-
|
|
249
|
-
init_db
|
|
250
|
-
|
|
251
|
-
# Handle --recent mode (no query required)
|
|
252
|
-
if [[ "$recent_mode" == true ]]; then
|
|
253
|
-
local results
|
|
254
|
-
results=$(sqlite3 -json "$MEMORY_DB" "SELECT l.id, l.content, l.type, l.tags, l.confidence, l.created_at, COALESCE(a.last_accessed_at, '') as last_accessed_at, COALESCE(a.access_count, 0) as access_count FROM learnings l LEFT JOIN learning_access a ON l.id = a.id ORDER BY l.created_at DESC LIMIT $limit;")
|
|
255
|
-
if [[ "$format" == "json" ]]; then
|
|
256
|
-
echo "$results"
|
|
257
|
-
else
|
|
258
|
-
echo ""
|
|
259
|
-
echo "=== Recent Memories (last $limit) ==="
|
|
260
|
-
echo ""
|
|
261
|
-
echo "$results" | format_results_text
|
|
262
|
-
fi
|
|
263
|
-
return 0
|
|
264
|
-
fi
|
|
265
|
-
|
|
266
|
-
if [[ -z "$query" ]]; then
|
|
267
|
-
log_error "Query is required. Use --query \"search terms\" or --recent"
|
|
268
|
-
return 1
|
|
269
|
-
fi
|
|
270
|
-
|
|
271
|
-
# Escape query for FTS5 - escape both single and double quotes
|
|
272
|
-
local escaped_query="${query//\'/\'\'}"
|
|
273
|
-
escaped_query="${escaped_query//\"/\"\"}"
|
|
274
|
-
|
|
275
|
-
# Build filters with validation
|
|
276
|
-
local extra_filters=""
|
|
277
|
-
if [[ -n "$type_filter" ]]; then
|
|
278
|
-
# Validate type to prevent SQL injection
|
|
279
|
-
local type_pattern=" $type_filter "
|
|
280
|
-
if [[ ! " $VALID_TYPES " =~ $type_pattern ]]; then
|
|
281
|
-
log_error "Invalid type: $type_filter"
|
|
282
|
-
log_error "Valid types: $VALID_TYPES"
|
|
283
|
-
return 1
|
|
284
|
-
fi
|
|
285
|
-
extra_filters="$extra_filters AND type = '$type_filter'"
|
|
286
|
-
fi
|
|
287
|
-
if [[ -n "$max_age_days" ]]; then
|
|
288
|
-
# Validate max_age_days is a positive integer
|
|
289
|
-
if ! [[ "$max_age_days" =~ ^[0-9]+$ ]]; then
|
|
290
|
-
log_error "--max-age-days must be a positive integer"
|
|
291
|
-
return 1
|
|
292
|
-
fi
|
|
293
|
-
extra_filters="$extra_filters AND created_at >= datetime('now', '-$max_age_days days')"
|
|
294
|
-
fi
|
|
295
|
-
if [[ -n "$project_filter" ]]; then
|
|
296
|
-
local escaped_project="${project_filter//\'/\'\'}"
|
|
297
|
-
extra_filters="$extra_filters AND project_path LIKE '%$escaped_project%'"
|
|
298
|
-
fi
|
|
299
|
-
|
|
300
|
-
# Search using FTS5 with BM25 ranking
|
|
301
|
-
# Note: FTS5 tables require special handling - can't use table alias in bm25()
|
|
302
|
-
local results
|
|
303
|
-
results=$(sqlite3 -json "$MEMORY_DB" <<EOF
|
|
304
|
-
SELECT
|
|
305
|
-
learnings.id,
|
|
306
|
-
learnings.content,
|
|
307
|
-
learnings.type,
|
|
308
|
-
learnings.tags,
|
|
309
|
-
learnings.confidence,
|
|
310
|
-
learnings.created_at,
|
|
311
|
-
COALESCE(learning_access.last_accessed_at, '') as last_accessed_at,
|
|
312
|
-
COALESCE(learning_access.access_count, 0) as access_count,
|
|
313
|
-
bm25(learnings) as score
|
|
314
|
-
FROM learnings
|
|
315
|
-
LEFT JOIN learning_access ON learnings.id = learning_access.id
|
|
316
|
-
WHERE learnings MATCH '$escaped_query' $extra_filters
|
|
317
|
-
ORDER BY score
|
|
318
|
-
LIMIT $limit;
|
|
319
|
-
EOF
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
# Update access tracking for returned results (prevents staleness)
|
|
323
|
-
if [[ -n "$results" && "$results" != "[]" ]]; then
|
|
324
|
-
local ids
|
|
325
|
-
ids=$(echo "$results" | extract_ids_from_json)
|
|
326
|
-
if [[ -n "$ids" ]]; then
|
|
327
|
-
while IFS= read -r id; do
|
|
328
|
-
[[ -z "$id" ]] && continue
|
|
329
|
-
sqlite3 "$MEMORY_DB" <<EOF
|
|
330
|
-
INSERT INTO learning_access (id, last_accessed_at, access_count)
|
|
331
|
-
VALUES ('$id', datetime('now'), 1)
|
|
332
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
333
|
-
last_accessed_at = datetime('now'),
|
|
334
|
-
access_count = access_count + 1;
|
|
335
|
-
EOF
|
|
336
|
-
done <<< "$ids"
|
|
337
|
-
fi
|
|
338
|
-
fi
|
|
339
|
-
|
|
340
|
-
# Output based on format
|
|
341
|
-
if [[ "$format" == "json" ]]; then
|
|
342
|
-
echo "$results"
|
|
343
|
-
else
|
|
344
|
-
if [[ -z "$results" || "$results" == "[]" ]]; then
|
|
345
|
-
log_warn "No results found for: $query"
|
|
346
|
-
return 0
|
|
347
|
-
fi
|
|
348
|
-
|
|
349
|
-
echo ""
|
|
350
|
-
echo "=== Memory Recall: \"$query\" ==="
|
|
351
|
-
echo ""
|
|
352
|
-
|
|
353
|
-
echo "$results" | format_results_text
|
|
354
|
-
fi
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
#######################################
|
|
358
|
-
# Show memory statistics
|
|
359
|
-
#######################################
|
|
360
|
-
cmd_stats() {
|
|
361
|
-
init_db
|
|
362
|
-
|
|
363
|
-
echo ""
|
|
364
|
-
echo "=== Memory Statistics ==="
|
|
365
|
-
echo ""
|
|
366
|
-
|
|
367
|
-
sqlite3 "$MEMORY_DB" <<'EOF'
|
|
368
|
-
SELECT 'Total learnings' as metric, COUNT(*) as value FROM learnings
|
|
369
|
-
UNION ALL
|
|
370
|
-
SELECT 'By type: ' || type, COUNT(*) FROM learnings GROUP BY type
|
|
371
|
-
UNION ALL
|
|
372
|
-
SELECT 'Never accessed', COUNT(*) FROM learnings l
|
|
373
|
-
LEFT JOIN learning_access a ON l.id = a.id WHERE a.id IS NULL
|
|
374
|
-
UNION ALL
|
|
375
|
-
SELECT 'High confidence', COUNT(*) FROM learnings WHERE confidence = 'high';
|
|
376
|
-
EOF
|
|
377
|
-
|
|
378
|
-
echo ""
|
|
379
|
-
|
|
380
|
-
# Show age distribution
|
|
381
|
-
echo "Age distribution:"
|
|
382
|
-
sqlite3 "$MEMORY_DB" <<'EOF'
|
|
383
|
-
SELECT
|
|
384
|
-
CASE
|
|
385
|
-
WHEN created_at >= datetime('now', '-7 days') THEN ' Last 7 days'
|
|
386
|
-
WHEN created_at >= datetime('now', '-30 days') THEN ' Last 30 days'
|
|
387
|
-
WHEN created_at >= datetime('now', '-90 days') THEN ' Last 90 days'
|
|
388
|
-
ELSE ' Older than 90 days'
|
|
389
|
-
END as age_bucket,
|
|
390
|
-
COUNT(*) as count
|
|
391
|
-
FROM learnings
|
|
392
|
-
GROUP BY 1
|
|
393
|
-
ORDER BY 1;
|
|
394
|
-
EOF
|
|
395
|
-
return 0
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
#######################################
|
|
399
|
-
# Validate and warn about stale entries
|
|
400
|
-
#######################################
|
|
401
|
-
cmd_validate() {
|
|
402
|
-
init_db
|
|
403
|
-
|
|
404
|
-
echo ""
|
|
405
|
-
echo "=== Memory Validation ==="
|
|
406
|
-
echo ""
|
|
407
|
-
|
|
408
|
-
# Check for stale entries (old + never accessed)
|
|
409
|
-
local stale_count
|
|
410
|
-
stale_count=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(*) FROM learnings l LEFT JOIN learning_access a ON l.id = a.id WHERE l.created_at < datetime('now', '-$STALE_WARNING_DAYS days') AND a.id IS NULL;")
|
|
411
|
-
|
|
412
|
-
if [[ "$stale_count" -gt 0 ]]; then
|
|
413
|
-
log_warn "Found $stale_count potentially stale entries (>$STALE_WARNING_DAYS days old, never accessed)"
|
|
414
|
-
echo ""
|
|
415
|
-
echo "Stale entries:"
|
|
416
|
-
sqlite3 "$MEMORY_DB" <<EOF
|
|
417
|
-
SELECT l.id, l.type, substr(l.content, 1, 60) || '...' as content_preview, l.created_at
|
|
418
|
-
FROM learnings l
|
|
419
|
-
LEFT JOIN learning_access a ON l.id = a.id
|
|
420
|
-
WHERE l.created_at < datetime('now', '-$STALE_WARNING_DAYS days')
|
|
421
|
-
AND a.id IS NULL
|
|
422
|
-
LIMIT 10;
|
|
423
|
-
EOF
|
|
424
|
-
echo ""
|
|
425
|
-
echo "Run 'memory-helper.sh prune --older-than-days $STALE_WARNING_DAYS' to clean up"
|
|
426
|
-
else
|
|
427
|
-
log_success "No stale entries found"
|
|
428
|
-
fi
|
|
429
|
-
|
|
430
|
-
# Check for duplicate content
|
|
431
|
-
local dup_count
|
|
432
|
-
dup_count=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(*) FROM (SELECT content, COUNT(*) as cnt FROM learnings GROUP BY content HAVING cnt > 1);" 2>/dev/null || echo "0")
|
|
433
|
-
|
|
434
|
-
if [[ "$dup_count" -gt 0 ]]; then
|
|
435
|
-
log_warn "Found $dup_count duplicate entries"
|
|
436
|
-
fi
|
|
437
|
-
|
|
438
|
-
# Check database size
|
|
439
|
-
local db_size
|
|
440
|
-
db_size=$(du -h "$MEMORY_DB" | cut -f1)
|
|
441
|
-
log_info "Database size: $db_size"
|
|
442
|
-
return 0
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
#######################################
|
|
446
|
-
# Prune old/stale entries
|
|
447
|
-
#######################################
|
|
448
|
-
cmd_prune() {
|
|
449
|
-
local older_than_days=$DEFAULT_MAX_AGE_DAYS
|
|
450
|
-
local dry_run=false
|
|
451
|
-
local keep_accessed=true
|
|
452
|
-
|
|
453
|
-
while [[ $# -gt 0 ]]; do
|
|
454
|
-
case "$1" in
|
|
455
|
-
--older-than-days) older_than_days="$2"; shift 2 ;;
|
|
456
|
-
--dry-run) dry_run=true; shift ;;
|
|
457
|
-
--include-accessed) keep_accessed=false; shift ;;
|
|
458
|
-
*) shift ;;
|
|
459
|
-
esac
|
|
460
|
-
done
|
|
461
|
-
|
|
462
|
-
init_db
|
|
463
|
-
|
|
464
|
-
# Build query to find stale entries
|
|
465
|
-
local count
|
|
466
|
-
if [[ "$keep_accessed" == true ]]; then
|
|
467
|
-
count=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(*) FROM learnings l LEFT JOIN learning_access a ON l.id = a.id WHERE l.created_at < datetime('now', '-$older_than_days days') AND a.id IS NULL;")
|
|
468
|
-
else
|
|
469
|
-
count=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(*) FROM learnings WHERE created_at < datetime('now', '-$older_than_days days');")
|
|
470
|
-
fi
|
|
471
|
-
|
|
472
|
-
if [[ "$count" -eq 0 ]]; then
|
|
473
|
-
log_success "No entries to prune"
|
|
474
|
-
return 0
|
|
475
|
-
fi
|
|
476
|
-
|
|
477
|
-
if [[ "$dry_run" == true ]]; then
|
|
478
|
-
log_info "[DRY RUN] Would delete $count entries"
|
|
479
|
-
echo ""
|
|
480
|
-
if [[ "$keep_accessed" == true ]]; then
|
|
481
|
-
sqlite3 "$MEMORY_DB" <<EOF
|
|
482
|
-
SELECT l.id, l.type, substr(l.content, 1, 50) || '...' as preview, l.created_at
|
|
483
|
-
FROM learnings l
|
|
484
|
-
LEFT JOIN learning_access a ON l.id = a.id
|
|
485
|
-
WHERE l.created_at < datetime('now', '-$older_than_days days') AND a.id IS NULL
|
|
486
|
-
LIMIT 20;
|
|
487
|
-
EOF
|
|
488
|
-
else
|
|
489
|
-
sqlite3 "$MEMORY_DB" <<EOF
|
|
490
|
-
SELECT id, type, substr(content, 1, 50) || '...' as preview, created_at
|
|
491
|
-
FROM learnings
|
|
492
|
-
WHERE created_at < datetime('now', '-$older_than_days days')
|
|
493
|
-
LIMIT 20;
|
|
494
|
-
EOF
|
|
495
|
-
fi
|
|
496
|
-
else
|
|
497
|
-
# Validate older_than_days is a positive integer
|
|
498
|
-
if ! [[ "$older_than_days" =~ ^[0-9]+$ ]]; then
|
|
499
|
-
log_error "--older-than-days must be a positive integer"
|
|
500
|
-
return 1
|
|
501
|
-
fi
|
|
502
|
-
|
|
503
|
-
# Use efficient single DELETE with subquery
|
|
504
|
-
local subquery
|
|
505
|
-
if [[ "$keep_accessed" == true ]]; then
|
|
506
|
-
subquery="SELECT l.id FROM learnings l LEFT JOIN learning_access a ON l.id = a.id WHERE l.created_at < datetime('now', '-$older_than_days days') AND a.id IS NULL"
|
|
507
|
-
else
|
|
508
|
-
subquery="SELECT id FROM learnings WHERE created_at < datetime('now', '-$older_than_days days')"
|
|
509
|
-
fi
|
|
510
|
-
|
|
511
|
-
# Delete from both tables using the subquery (much faster than loop)
|
|
512
|
-
sqlite3 "$MEMORY_DB" "DELETE FROM learning_access WHERE id IN ($subquery);"
|
|
513
|
-
sqlite3 "$MEMORY_DB" "DELETE FROM learnings WHERE id IN ($subquery);"
|
|
514
|
-
|
|
515
|
-
log_success "Pruned $count stale entries"
|
|
516
|
-
|
|
517
|
-
# Rebuild FTS index
|
|
518
|
-
sqlite3 "$MEMORY_DB" "INSERT INTO learnings(learnings) VALUES('rebuild');"
|
|
519
|
-
log_info "Rebuilt search index"
|
|
520
|
-
fi
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
#######################################
|
|
524
|
-
# Export memories
|
|
525
|
-
#######################################
|
|
526
|
-
cmd_export() {
|
|
527
|
-
local format="json"
|
|
528
|
-
|
|
529
|
-
while [[ $# -gt 0 ]]; do
|
|
530
|
-
case "$1" in
|
|
531
|
-
--format) format="$2"; shift 2 ;;
|
|
532
|
-
*) shift ;;
|
|
533
|
-
esac
|
|
534
|
-
done
|
|
535
|
-
|
|
536
|
-
init_db
|
|
537
|
-
|
|
538
|
-
case "$format" in
|
|
539
|
-
json)
|
|
540
|
-
sqlite3 -json "$MEMORY_DB" "SELECT l.*, COALESCE(a.last_accessed_at, '') as last_accessed_at, COALESCE(a.access_count, 0) as access_count FROM learnings l LEFT JOIN learning_access a ON l.id = a.id ORDER BY l.created_at DESC;"
|
|
541
|
-
;;
|
|
542
|
-
toon)
|
|
543
|
-
# TOON format for token efficiency
|
|
544
|
-
local count
|
|
545
|
-
count=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(*) FROM learnings;")
|
|
546
|
-
echo "learnings[$count]{id,type,confidence,content,tags,created_at}:"
|
|
547
|
-
sqlite3 -separator ',' "$MEMORY_DB" "SELECT id, type, confidence, content, tags, created_at FROM learnings ORDER BY created_at DESC;" | while read -r line; do
|
|
548
|
-
echo " $line"
|
|
549
|
-
done
|
|
550
|
-
;;
|
|
551
|
-
*)
|
|
552
|
-
log_error "Unknown format: $format (use json or toon)"
|
|
553
|
-
return 1
|
|
554
|
-
;;
|
|
555
|
-
esac
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
#######################################
|
|
559
|
-
# Show help
|
|
560
|
-
#######################################
|
|
561
|
-
cmd_help() {
|
|
562
|
-
cat <<'EOF'
|
|
563
|
-
memory-helper.sh - Lightweight memory system for aidevops
|
|
564
|
-
|
|
565
|
-
USAGE:
|
|
566
|
-
memory-helper.sh <command> [options]
|
|
567
|
-
|
|
568
|
-
COMMANDS:
|
|
569
|
-
store Store a new learning
|
|
570
|
-
recall Search and retrieve learnings
|
|
571
|
-
stats Show memory statistics
|
|
572
|
-
validate Check for stale/duplicate entries
|
|
573
|
-
prune Remove old entries
|
|
574
|
-
export Export all memories
|
|
575
|
-
help Show this help
|
|
576
|
-
|
|
577
|
-
STORE OPTIONS:
|
|
578
|
-
--content <text> Learning content (required)
|
|
579
|
-
--type <type> Learning type (default: WORKING_SOLUTION)
|
|
580
|
-
--tags <tags> Comma-separated tags
|
|
581
|
-
--confidence <level> high, medium, or low (default: medium)
|
|
582
|
-
--session-id <id> Session identifier
|
|
583
|
-
--project <path> Project path
|
|
584
|
-
|
|
585
|
-
VALID TYPES:
|
|
586
|
-
WORKING_SOLUTION, FAILED_APPROACH, CODEBASE_PATTERN, USER_PREFERENCE,
|
|
587
|
-
TOOL_CONFIG, DECISION, CONTEXT, ARCHITECTURAL_DECISION, ERROR_FIX, OPEN_THREAD
|
|
588
|
-
|
|
589
|
-
RECALL OPTIONS:
|
|
590
|
-
--query <text> Search query (required unless --recent)
|
|
591
|
-
--limit <n> Max results (default: 5)
|
|
592
|
-
--type <type> Filter by type
|
|
593
|
-
--max-age-days <n> Only recent entries
|
|
594
|
-
--project <path> Filter by project path
|
|
595
|
-
--recent [n] Show n most recent entries (default: 10)
|
|
596
|
-
--stats Show memory statistics
|
|
597
|
-
--json Output as JSON
|
|
598
|
-
|
|
599
|
-
PRUNE OPTIONS:
|
|
600
|
-
--older-than-days <n> Age threshold (default: 90)
|
|
601
|
-
--dry-run Show what would be deleted
|
|
602
|
-
--include-accessed Also prune accessed entries
|
|
603
|
-
|
|
604
|
-
STALENESS PREVENTION:
|
|
605
|
-
- Entries track created_at and last_accessed_at
|
|
606
|
-
- Recall updates last_accessed_at (used = valuable)
|
|
607
|
-
- Prune removes old entries that were never accessed
|
|
608
|
-
- Validate warns about potentially stale entries
|
|
609
|
-
|
|
610
|
-
EXAMPLES:
|
|
611
|
-
# Store a learning
|
|
612
|
-
memory-helper.sh store --content "Use FTS5 for fast search" --type WORKING_SOLUTION
|
|
613
|
-
|
|
614
|
-
# Recall learnings
|
|
615
|
-
memory-helper.sh recall --query "database search" --limit 10
|
|
616
|
-
|
|
617
|
-
# Check for stale entries
|
|
618
|
-
memory-helper.sh validate
|
|
619
|
-
|
|
620
|
-
# Clean up old unused entries
|
|
621
|
-
memory-helper.sh prune --older-than-days 60 --dry-run
|
|
622
|
-
EOF
|
|
623
|
-
return 0
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
#######################################
|
|
627
|
-
# Main entry point
|
|
628
|
-
#######################################
|
|
629
|
-
main() {
|
|
630
|
-
local command="${1:-help}"
|
|
631
|
-
shift || true
|
|
632
|
-
|
|
633
|
-
case "$command" in
|
|
634
|
-
store) cmd_store "$@" ;;
|
|
635
|
-
recall) cmd_recall "$@" ;;
|
|
636
|
-
stats) cmd_stats ;;
|
|
637
|
-
validate) cmd_validate ;;
|
|
638
|
-
prune) cmd_prune "$@" ;;
|
|
639
|
-
export) cmd_export "$@" ;;
|
|
640
|
-
help|--help|-h) cmd_help ;;
|
|
641
|
-
*)
|
|
642
|
-
log_error "Unknown command: $command"
|
|
643
|
-
cmd_help
|
|
644
|
-
return 1
|
|
645
|
-
;;
|
|
646
|
-
esac
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
main "$@"
|
|
650
|
-
exit $?
|