aidevops 2.52.1 → 2.53.2
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,806 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# =============================================================================
|
|
3
|
-
# Loop Common - Shared Infrastructure for All Loop Components
|
|
4
|
-
# =============================================================================
|
|
5
|
-
# Provides shared functions for ralph-loop, quality-loop, and full-loop:
|
|
6
|
-
# - State management (JSON-based, survives session restart)
|
|
7
|
-
# - Re-anchor prompt generation
|
|
8
|
-
# - Receipt verification
|
|
9
|
-
# - Memory integration
|
|
10
|
-
#
|
|
11
|
-
# Based on flow-next architecture: fresh context per iteration, file I/O as state
|
|
12
|
-
# Reference: https://github.com/gmickel/gmickel-claude-marketplace/tree/main/plugins/flow-next
|
|
13
|
-
#
|
|
14
|
-
# Usage:
|
|
15
|
-
# source ~/.aidevops/agents/scripts/loop-common.sh
|
|
16
|
-
#
|
|
17
|
-
# Author: AI DevOps Framework
|
|
18
|
-
# =============================================================================
|
|
19
|
-
|
|
20
|
-
set -euo pipefail
|
|
21
|
-
|
|
22
|
-
# =============================================================================
|
|
23
|
-
# Constants
|
|
24
|
-
# =============================================================================
|
|
25
|
-
|
|
26
|
-
readonly LOOP_STATE_DIR="${LOOP_STATE_DIR:-.agent/loop-state}"
|
|
27
|
-
readonly LOOP_STATE_FILE="${LOOP_STATE_DIR}/loop-state.json"
|
|
28
|
-
readonly LOOP_RECEIPTS_DIR="${LOOP_STATE_DIR}/receipts"
|
|
29
|
-
readonly LOOP_REANCHOR_FILE="${LOOP_STATE_DIR}/re-anchor.md"
|
|
30
|
-
|
|
31
|
-
# Legacy state directory (for backward compatibility during migration)
|
|
32
|
-
# shellcheck disable=SC2034 # Exported for use by sourcing scripts
|
|
33
|
-
readonly LOOP_LEGACY_STATE_DIR=".claude"
|
|
34
|
-
|
|
35
|
-
# Colors (exported for use by sourcing scripts)
|
|
36
|
-
export LC_RED='\033[0;31m'
|
|
37
|
-
export LC_GREEN='\033[0;32m'
|
|
38
|
-
export LC_YELLOW='\033[1;33m'
|
|
39
|
-
export LC_BLUE='\033[0;34m'
|
|
40
|
-
export LC_CYAN='\033[0;36m'
|
|
41
|
-
export LC_BOLD='\033[1m'
|
|
42
|
-
export LC_NC='\033[0m'
|
|
43
|
-
|
|
44
|
-
# =============================================================================
|
|
45
|
-
# Logging Functions
|
|
46
|
-
# =============================================================================
|
|
47
|
-
|
|
48
|
-
loop_log_error() {
|
|
49
|
-
local message="$1"
|
|
50
|
-
echo -e "${LC_RED}[loop] Error:${LC_NC} ${message}" >&2
|
|
51
|
-
return 0
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
loop_log_success() {
|
|
55
|
-
local message="$1"
|
|
56
|
-
echo -e "${LC_GREEN}[loop]${LC_NC} ${message}"
|
|
57
|
-
return 0
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
loop_log_warn() {
|
|
61
|
-
local message="$1"
|
|
62
|
-
echo -e "${LC_YELLOW}[loop]${LC_NC} ${message}"
|
|
63
|
-
return 0
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
loop_log_info() {
|
|
67
|
-
local message="$1"
|
|
68
|
-
echo -e "${LC_BLUE}[loop]${LC_NC} ${message}"
|
|
69
|
-
return 0
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
loop_log_step() {
|
|
73
|
-
local message="$1"
|
|
74
|
-
echo -e "${LC_CYAN}[loop]${LC_NC} ${message}"
|
|
75
|
-
return 0
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
# =============================================================================
|
|
79
|
-
# State Management (JSON-based)
|
|
80
|
-
# =============================================================================
|
|
81
|
-
|
|
82
|
-
# Initialize loop state directory
|
|
83
|
-
# Arguments: none
|
|
84
|
-
# Returns: 0
|
|
85
|
-
loop_init_state_dir() {
|
|
86
|
-
mkdir -p "$LOOP_STATE_DIR"
|
|
87
|
-
mkdir -p "$LOOP_RECEIPTS_DIR"
|
|
88
|
-
return 0
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
# Create new loop state
|
|
92
|
-
# Arguments:
|
|
93
|
-
# $1 - loop_type (ralph|preflight|pr-review|postflight|full)
|
|
94
|
-
# $2 - prompt/task description
|
|
95
|
-
# $3 - max_iterations (default: 50)
|
|
96
|
-
# $4 - completion_promise (default: TASK_COMPLETE)
|
|
97
|
-
# $5 - task_id (optional)
|
|
98
|
-
# Returns: 0 on success, 1 on error
|
|
99
|
-
loop_create_state() {
|
|
100
|
-
local loop_type="$1"
|
|
101
|
-
local prompt="$2"
|
|
102
|
-
local max_iterations="${3:-50}"
|
|
103
|
-
local completion_promise="${4:-TASK_COMPLETE}"
|
|
104
|
-
local task_id="${5:-}"
|
|
105
|
-
|
|
106
|
-
loop_init_state_dir
|
|
107
|
-
|
|
108
|
-
# Generate task_id if not provided
|
|
109
|
-
if [[ -z "$task_id" ]]; then
|
|
110
|
-
task_id="loop_$(date +%Y%m%d%H%M%S)"
|
|
111
|
-
fi
|
|
112
|
-
|
|
113
|
-
local started_at
|
|
114
|
-
started_at=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
115
|
-
|
|
116
|
-
# Create JSON state file
|
|
117
|
-
cat > "$LOOP_STATE_FILE" << EOF
|
|
118
|
-
{
|
|
119
|
-
"loop_type": "$loop_type",
|
|
120
|
-
"prompt": $(echo "$prompt" | jq -Rs .),
|
|
121
|
-
"iteration": 1,
|
|
122
|
-
"max_iterations": $max_iterations,
|
|
123
|
-
"phase": "task",
|
|
124
|
-
"task_id": "$task_id",
|
|
125
|
-
"started_at": "$started_at",
|
|
126
|
-
"last_iteration_at": "$started_at",
|
|
127
|
-
"completion_promise": "$completion_promise",
|
|
128
|
-
"attempts": {},
|
|
129
|
-
"receipts": [],
|
|
130
|
-
"blocked_tasks": [],
|
|
131
|
-
"active": true
|
|
132
|
-
}
|
|
133
|
-
EOF
|
|
134
|
-
|
|
135
|
-
loop_log_success "Loop state created: $LOOP_STATE_FILE"
|
|
136
|
-
return 0
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
# Read loop state value
|
|
140
|
-
# Arguments:
|
|
141
|
-
# $1 - JSON key path (e.g., ".iteration", ".task_id")
|
|
142
|
-
# Returns: 0
|
|
143
|
-
# Output: Value to stdout
|
|
144
|
-
loop_get_state() {
|
|
145
|
-
local key="$1"
|
|
146
|
-
|
|
147
|
-
if [[ ! -f "$LOOP_STATE_FILE" ]]; then
|
|
148
|
-
echo ""
|
|
149
|
-
return 0
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
jq -r "$key // empty" "$LOOP_STATE_FILE" 2>/dev/null || echo ""
|
|
153
|
-
return 0
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
# Update loop state value
|
|
157
|
-
# Arguments:
|
|
158
|
-
# $1 - JSON key path (e.g., ".iteration")
|
|
159
|
-
# $2 - New value (will be auto-typed: number, string, bool)
|
|
160
|
-
# Returns: 0 on success, 1 on error
|
|
161
|
-
loop_set_state() {
|
|
162
|
-
local key="$1"
|
|
163
|
-
local value="$2"
|
|
164
|
-
|
|
165
|
-
if [[ ! -f "$LOOP_STATE_FILE" ]]; then
|
|
166
|
-
loop_log_error "No active loop state"
|
|
167
|
-
return 1
|
|
168
|
-
fi
|
|
169
|
-
|
|
170
|
-
local temp_file
|
|
171
|
-
temp_file=$(mktemp)
|
|
172
|
-
|
|
173
|
-
# Determine value type and update
|
|
174
|
-
if [[ "$value" =~ ^[0-9]+$ ]]; then
|
|
175
|
-
# Integer
|
|
176
|
-
jq "$key = $value" "$LOOP_STATE_FILE" > "$temp_file"
|
|
177
|
-
elif [[ "$value" == "true" || "$value" == "false" ]]; then
|
|
178
|
-
# Boolean
|
|
179
|
-
jq "$key = $value" "$LOOP_STATE_FILE" > "$temp_file"
|
|
180
|
-
elif [[ "$value" == "null" ]]; then
|
|
181
|
-
# Null
|
|
182
|
-
jq "$key = null" "$LOOP_STATE_FILE" > "$temp_file"
|
|
183
|
-
else
|
|
184
|
-
# String
|
|
185
|
-
jq "$key = \"$value\"" "$LOOP_STATE_FILE" > "$temp_file"
|
|
186
|
-
fi
|
|
187
|
-
|
|
188
|
-
mv "$temp_file" "$LOOP_STATE_FILE"
|
|
189
|
-
return 0
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
# Increment iteration counter
|
|
193
|
-
# Arguments: none
|
|
194
|
-
# Returns: 0
|
|
195
|
-
# Output: New iteration number
|
|
196
|
-
loop_increment_iteration() {
|
|
197
|
-
local current
|
|
198
|
-
current=$(loop_get_state ".iteration")
|
|
199
|
-
local next=$((current + 1))
|
|
200
|
-
|
|
201
|
-
loop_set_state ".iteration" "$next"
|
|
202
|
-
loop_set_state ".last_iteration_at" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
203
|
-
|
|
204
|
-
echo "$next"
|
|
205
|
-
return 0
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
# Check if loop is active
|
|
209
|
-
# Arguments: none
|
|
210
|
-
# Returns: 0 if active, 1 if not
|
|
211
|
-
loop_is_active() {
|
|
212
|
-
if [[ ! -f "$LOOP_STATE_FILE" ]]; then
|
|
213
|
-
return 1
|
|
214
|
-
fi
|
|
215
|
-
|
|
216
|
-
local active
|
|
217
|
-
active=$(loop_get_state ".active")
|
|
218
|
-
[[ "$active" == "true" ]]
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
# Cancel loop
|
|
222
|
-
# Arguments: none
|
|
223
|
-
# Returns: 0
|
|
224
|
-
loop_cancel() {
|
|
225
|
-
if [[ -f "$LOOP_STATE_FILE" ]]; then
|
|
226
|
-
loop_set_state ".active" "false"
|
|
227
|
-
loop_log_success "Loop cancelled"
|
|
228
|
-
else
|
|
229
|
-
loop_log_warn "No active loop to cancel"
|
|
230
|
-
fi
|
|
231
|
-
return 0
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
# Clean up loop state
|
|
235
|
-
# Arguments: none
|
|
236
|
-
# Returns: 0
|
|
237
|
-
loop_cleanup() {
|
|
238
|
-
rm -f "$LOOP_STATE_FILE"
|
|
239
|
-
rm -f "$LOOP_REANCHOR_FILE"
|
|
240
|
-
# Keep receipts for audit trail
|
|
241
|
-
loop_log_info "Loop state cleaned up (receipts preserved)"
|
|
242
|
-
return 0
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
# =============================================================================
|
|
246
|
-
# Guardrails System (Signs)
|
|
247
|
-
# =============================================================================
|
|
248
|
-
|
|
249
|
-
# Generate guardrails from recent failures
|
|
250
|
-
# Transforms FAILED_APPROACH memories into actionable "signs" that prevent
|
|
251
|
-
# repeating the same mistakes. Limited to N most recent to control token cost.
|
|
252
|
-
#
|
|
253
|
-
# Arguments:
|
|
254
|
-
# $1 - max_signs (default: 5)
|
|
255
|
-
# Returns: 0
|
|
256
|
-
# Output: Guardrails markdown to stdout
|
|
257
|
-
loop_generate_guardrails() {
|
|
258
|
-
local max_signs="${1:-5}"
|
|
259
|
-
local task_id
|
|
260
|
-
task_id=$(loop_get_state ".task_id")
|
|
261
|
-
|
|
262
|
-
# Check if memory helper is available
|
|
263
|
-
if ! command -v ~/.aidevops/agents/scripts/memory-helper.sh &>/dev/null; then
|
|
264
|
-
echo "No guardrails (memory system unavailable)"
|
|
265
|
-
return 0
|
|
266
|
-
fi
|
|
267
|
-
|
|
268
|
-
# Query memory for FAILED_APPROACH entries from this loop
|
|
269
|
-
local failures
|
|
270
|
-
failures=$(~/.aidevops/agents/scripts/memory-helper.sh recall \
|
|
271
|
-
"failure retry loop $task_id" \
|
|
272
|
-
--limit "$max_signs" \
|
|
273
|
-
--format json 2>/dev/null || echo "[]")
|
|
274
|
-
|
|
275
|
-
# Check if we have any failures
|
|
276
|
-
local count
|
|
277
|
-
count=$(echo "$failures" | jq 'length' 2>/dev/null || echo "0")
|
|
278
|
-
|
|
279
|
-
if [[ "$count" == "0" || "$count" == "null" ]]; then
|
|
280
|
-
echo "No guardrails yet (no recorded failures)."
|
|
281
|
-
return 0
|
|
282
|
-
fi
|
|
283
|
-
|
|
284
|
-
# Transform failures to guardrail format
|
|
285
|
-
# Format: "Failed: X. Reason: Y" -> sign with trigger and instruction
|
|
286
|
-
echo "$failures" | jq -r '
|
|
287
|
-
.[] |
|
|
288
|
-
"### Sign: " + (
|
|
289
|
-
.content // .memory // "" |
|
|
290
|
-
gsub("^Failed: "; "") |
|
|
291
|
-
split(". Reason:")[0] // "unknown issue"
|
|
292
|
-
) + "\n" +
|
|
293
|
-
"- **Trigger**: Before similar operation\n" +
|
|
294
|
-
"- **Instruction**: " + (
|
|
295
|
-
.content // .memory // "" |
|
|
296
|
-
split(". Reason:")[1] // "Avoid this approach" |
|
|
297
|
-
gsub("^ "; "")
|
|
298
|
-
) + "\n"
|
|
299
|
-
' 2>/dev/null || echo "No guardrails (parse error)."
|
|
300
|
-
|
|
301
|
-
return 0
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
# =============================================================================
|
|
305
|
-
# Re-Anchor System
|
|
306
|
-
# =============================================================================
|
|
307
|
-
|
|
308
|
-
# Generate re-anchor prompt for fresh context
|
|
309
|
-
# Arguments:
|
|
310
|
-
# $1 - task_keywords (for memory recall)
|
|
311
|
-
# Returns: 0
|
|
312
|
-
# Output: Re-anchor prompt to stdout and file
|
|
313
|
-
loop_generate_reanchor() {
|
|
314
|
-
local task_keywords="${1:-}"
|
|
315
|
-
local task_id
|
|
316
|
-
task_id=$(loop_get_state ".task_id")
|
|
317
|
-
local iteration
|
|
318
|
-
iteration=$(loop_get_state ".iteration")
|
|
319
|
-
local prompt
|
|
320
|
-
prompt=$(loop_get_state ".prompt")
|
|
321
|
-
|
|
322
|
-
loop_init_state_dir
|
|
323
|
-
|
|
324
|
-
# Get git state
|
|
325
|
-
local git_status
|
|
326
|
-
git_status=$(git status --short 2>/dev/null || echo "Not a git repo")
|
|
327
|
-
local git_log
|
|
328
|
-
git_log=$(git log -5 --oneline 2>/dev/null || echo "No git history")
|
|
329
|
-
local git_branch
|
|
330
|
-
git_branch=$(git branch --show-current 2>/dev/null || echo "unknown")
|
|
331
|
-
|
|
332
|
-
# Get TODO.md in-progress tasks
|
|
333
|
-
local todo_in_progress=""
|
|
334
|
-
if [[ -f "TODO.md" ]]; then
|
|
335
|
-
todo_in_progress=$(grep -A10 "## In Progress" TODO.md 2>/dev/null | head -15 || echo "No tasks in progress")
|
|
336
|
-
fi
|
|
337
|
-
|
|
338
|
-
# Extract single next task (the "pin" concept from Loom)
|
|
339
|
-
# Focus on ONE task per iteration to reduce context drift
|
|
340
|
-
local next_task=""
|
|
341
|
-
if [[ -f "TODO.md" ]]; then
|
|
342
|
-
# Get first unchecked task from In Progress section, or first from Backlog
|
|
343
|
-
next_task=$(awk '
|
|
344
|
-
/^## In Progress/,/^##/ { if (/^- \[ \]/) { print; exit } }
|
|
345
|
-
' TODO.md 2>/dev/null || echo "")
|
|
346
|
-
|
|
347
|
-
if [[ -z "$next_task" ]]; then
|
|
348
|
-
next_task=$(awk '
|
|
349
|
-
/^## Backlog/,/^##/ { if (/^- \[ \]/) { print; exit } }
|
|
350
|
-
' TODO.md 2>/dev/null || echo "")
|
|
351
|
-
fi
|
|
352
|
-
fi
|
|
353
|
-
|
|
354
|
-
# Get relevant memories
|
|
355
|
-
local memories=""
|
|
356
|
-
if [[ -n "$task_keywords" ]] && command -v ~/.aidevops/agents/scripts/memory-helper.sh &>/dev/null; then
|
|
357
|
-
memories=$(~/.aidevops/agents/scripts/memory-helper.sh recall "$task_keywords" --limit 5 --format text 2>/dev/null || echo "No relevant memories")
|
|
358
|
-
fi
|
|
359
|
-
|
|
360
|
-
# Generate guardrails from failures (the "signs" concept)
|
|
361
|
-
# These are actionable rules derived from past failures - "same mistake never happens twice"
|
|
362
|
-
local guardrails
|
|
363
|
-
guardrails=$(loop_generate_guardrails 5)
|
|
364
|
-
|
|
365
|
-
# Get latest receipt
|
|
366
|
-
local latest_receipt=""
|
|
367
|
-
local latest_receipt_file
|
|
368
|
-
latest_receipt_file=$(find "$LOOP_RECEIPTS_DIR" -name "*.json" -type f -print0 2>/dev/null | xargs -0 ls -t 2>/dev/null | head -1 || echo "")
|
|
369
|
-
if [[ -n "$latest_receipt_file" && -f "$latest_receipt_file" ]]; then
|
|
370
|
-
latest_receipt=$(cat "$latest_receipt_file")
|
|
371
|
-
fi
|
|
372
|
-
|
|
373
|
-
# Generate re-anchor prompt with single-task focus
|
|
374
|
-
cat > "$LOOP_REANCHOR_FILE" << EOF
|
|
375
|
-
# Re-Anchor Context (MANDATORY - Read Before Any Work)
|
|
376
|
-
|
|
377
|
-
**Loop:** $task_id | **Iteration:** $iteration | **Branch:** $git_branch
|
|
378
|
-
|
|
379
|
-
## Original Task
|
|
380
|
-
|
|
381
|
-
$prompt
|
|
382
|
-
|
|
383
|
-
## FOCUS: Single Next Task
|
|
384
|
-
|
|
385
|
-
Choose the single most important next action. Do NOT try to do everything at once.
|
|
386
|
-
|
|
387
|
-
${next_task:-"No specific task found in TODO.md - work on the original task above."}
|
|
388
|
-
|
|
389
|
-
## Current State
|
|
390
|
-
|
|
391
|
-
### Git Status
|
|
392
|
-
\`\`\`
|
|
393
|
-
$git_status
|
|
394
|
-
\`\`\`
|
|
395
|
-
|
|
396
|
-
### Recent Commits
|
|
397
|
-
\`\`\`
|
|
398
|
-
$git_log
|
|
399
|
-
\`\`\`
|
|
400
|
-
|
|
401
|
-
### TODO.md In Progress
|
|
402
|
-
\`\`\`
|
|
403
|
-
$todo_in_progress
|
|
404
|
-
\`\`\`
|
|
405
|
-
|
|
406
|
-
## Guardrails (Do Not Repeat These Mistakes)
|
|
407
|
-
|
|
408
|
-
$guardrails
|
|
409
|
-
|
|
410
|
-
## Relevant Memories
|
|
411
|
-
|
|
412
|
-
$memories
|
|
413
|
-
|
|
414
|
-
## Previous Iteration Receipt
|
|
415
|
-
|
|
416
|
-
\`\`\`json
|
|
417
|
-
${latest_receipt:-"First iteration - no previous receipt"}
|
|
418
|
-
\`\`\`
|
|
419
|
-
|
|
420
|
-
---
|
|
421
|
-
|
|
422
|
-
**IMPORTANT:** Re-read this context before proceeding. Do NOT rely on conversation history.
|
|
423
|
-
Focus on ONE task per iteration. When the overall task is complete, output: <promise>$(loop_get_state ".completion_promise")</promise>
|
|
424
|
-
EOF
|
|
425
|
-
|
|
426
|
-
cat "$LOOP_REANCHOR_FILE"
|
|
427
|
-
return 0
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
# =============================================================================
|
|
431
|
-
# Receipt System
|
|
432
|
-
# =============================================================================
|
|
433
|
-
|
|
434
|
-
# Create a receipt for completed work
|
|
435
|
-
# Arguments:
|
|
436
|
-
# $1 - type (task|preflight|pr-review|postflight)
|
|
437
|
-
# $2 - outcome (success|retry|blocked)
|
|
438
|
-
# $3 - evidence (JSON object as string, optional)
|
|
439
|
-
# Returns: 0
|
|
440
|
-
# Output: Receipt file path
|
|
441
|
-
loop_create_receipt() {
|
|
442
|
-
local receipt_type="$1"
|
|
443
|
-
local outcome="$2"
|
|
444
|
-
local evidence="${3:-{}}"
|
|
445
|
-
|
|
446
|
-
local task_id
|
|
447
|
-
task_id=$(loop_get_state ".task_id")
|
|
448
|
-
local iteration
|
|
449
|
-
iteration=$(loop_get_state ".iteration")
|
|
450
|
-
local timestamp
|
|
451
|
-
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
452
|
-
|
|
453
|
-
loop_init_state_dir
|
|
454
|
-
|
|
455
|
-
local receipt_file="${LOOP_RECEIPTS_DIR}/${receipt_type}-${task_id}-iter${iteration}.json"
|
|
456
|
-
|
|
457
|
-
# Get commit hash if available
|
|
458
|
-
local commit_hash
|
|
459
|
-
commit_hash=$(git rev-parse --short HEAD 2>/dev/null || echo "none")
|
|
460
|
-
|
|
461
|
-
cat > "$receipt_file" << EOF
|
|
462
|
-
{
|
|
463
|
-
"type": "$receipt_type",
|
|
464
|
-
"id": "$task_id",
|
|
465
|
-
"iteration": $iteration,
|
|
466
|
-
"timestamp": "$timestamp",
|
|
467
|
-
"outcome": "$outcome",
|
|
468
|
-
"commit_hash": "$commit_hash",
|
|
469
|
-
"evidence": $evidence
|
|
470
|
-
}
|
|
471
|
-
EOF
|
|
472
|
-
|
|
473
|
-
# Add receipt to state
|
|
474
|
-
local receipts
|
|
475
|
-
receipts=$(loop_get_state ".receipts")
|
|
476
|
-
if [[ -z "$receipts" || "$receipts" == "null" ]]; then
|
|
477
|
-
receipts="[]"
|
|
478
|
-
fi
|
|
479
|
-
|
|
480
|
-
local temp_file
|
|
481
|
-
temp_file=$(mktemp)
|
|
482
|
-
jq ".receipts += [\"$(basename "$receipt_file")\"]" "$LOOP_STATE_FILE" > "$temp_file"
|
|
483
|
-
mv "$temp_file" "$LOOP_STATE_FILE"
|
|
484
|
-
|
|
485
|
-
loop_log_success "Receipt created: $receipt_file"
|
|
486
|
-
echo "$receipt_file"
|
|
487
|
-
return 0
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
# Verify receipt exists for current iteration
|
|
491
|
-
# Arguments:
|
|
492
|
-
# $1 - type (task|preflight|pr-review|postflight)
|
|
493
|
-
# Returns: 0 if receipt exists, 1 if not
|
|
494
|
-
loop_verify_receipt() {
|
|
495
|
-
local receipt_type="$1"
|
|
496
|
-
local task_id
|
|
497
|
-
task_id=$(loop_get_state ".task_id")
|
|
498
|
-
local iteration
|
|
499
|
-
iteration=$(loop_get_state ".iteration")
|
|
500
|
-
|
|
501
|
-
local receipt_file="${LOOP_RECEIPTS_DIR}/${receipt_type}-${task_id}-iter${iteration}.json"
|
|
502
|
-
|
|
503
|
-
if [[ -f "$receipt_file" ]]; then
|
|
504
|
-
loop_log_success "Receipt verified: $receipt_file"
|
|
505
|
-
return 0
|
|
506
|
-
else
|
|
507
|
-
loop_log_warn "Missing receipt: $receipt_file"
|
|
508
|
-
return 1
|
|
509
|
-
fi
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
# Get latest receipt for a type
|
|
513
|
-
# Arguments:
|
|
514
|
-
# $1 - type (task|preflight|pr-review|postflight)
|
|
515
|
-
# Returns: 0
|
|
516
|
-
# Output: Receipt JSON to stdout
|
|
517
|
-
loop_get_latest_receipt() {
|
|
518
|
-
local receipt_type="$1"
|
|
519
|
-
|
|
520
|
-
local latest
|
|
521
|
-
latest=$(find "$LOOP_RECEIPTS_DIR" -name "${receipt_type}-*.json" -type f -print0 2>/dev/null | xargs -0 ls -t 2>/dev/null | head -1 || echo "")
|
|
522
|
-
|
|
523
|
-
if [[ -n "$latest" && -f "$latest" ]]; then
|
|
524
|
-
cat "$latest"
|
|
525
|
-
else
|
|
526
|
-
echo "{}"
|
|
527
|
-
fi
|
|
528
|
-
return 0
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
# =============================================================================
|
|
532
|
-
# Memory Integration
|
|
533
|
-
# =============================================================================
|
|
534
|
-
|
|
535
|
-
# Store learning from loop iteration
|
|
536
|
-
# Arguments:
|
|
537
|
-
# $1 - type (WORKING_SOLUTION|FAILED_APPROACH|CODEBASE_PATTERN)
|
|
538
|
-
# $2 - content
|
|
539
|
-
# $3 - tags (comma-separated)
|
|
540
|
-
# Returns: 0
|
|
541
|
-
loop_store_memory() {
|
|
542
|
-
local memory_type="$1"
|
|
543
|
-
local content="$2"
|
|
544
|
-
local tags="${3:-loop}"
|
|
545
|
-
|
|
546
|
-
local task_id
|
|
547
|
-
task_id=$(loop_get_state ".task_id")
|
|
548
|
-
|
|
549
|
-
if command -v ~/.aidevops/agents/scripts/memory-helper.sh &>/dev/null; then
|
|
550
|
-
~/.aidevops/agents/scripts/memory-helper.sh store \
|
|
551
|
-
--type "$memory_type" \
|
|
552
|
-
--content "$content" \
|
|
553
|
-
--tags "$tags,loop,$task_id" \
|
|
554
|
-
--session-id "$task_id" 2>/dev/null || true
|
|
555
|
-
loop_log_info "Memory stored: $memory_type"
|
|
556
|
-
fi
|
|
557
|
-
return 0
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
# Store failed approach (called on retry)
|
|
561
|
-
# Arguments:
|
|
562
|
-
# $1 - what failed
|
|
563
|
-
# $2 - why it failed (optional)
|
|
564
|
-
# Returns: 0
|
|
565
|
-
loop_store_failure() {
|
|
566
|
-
local what_failed="$1"
|
|
567
|
-
local why="${2:-Unknown reason}"
|
|
568
|
-
|
|
569
|
-
loop_store_memory "FAILED_APPROACH" "Failed: $what_failed. Reason: $why" "failure,retry"
|
|
570
|
-
return 0
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
# Store successful solution (called on completion)
|
|
574
|
-
# Arguments:
|
|
575
|
-
# $1 - what worked
|
|
576
|
-
# Returns: 0
|
|
577
|
-
loop_store_success() {
|
|
578
|
-
local what_worked="$1"
|
|
579
|
-
|
|
580
|
-
loop_store_memory "WORKING_SOLUTION" "Success: $what_worked" "success,solution"
|
|
581
|
-
return 0
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
# =============================================================================
|
|
585
|
-
# Task Blocking
|
|
586
|
-
# =============================================================================
|
|
587
|
-
|
|
588
|
-
# Track attempt for a task
|
|
589
|
-
# Arguments:
|
|
590
|
-
# $1 - task_id (optional, uses current if not provided)
|
|
591
|
-
# Returns: 0
|
|
592
|
-
# Output: New attempt count
|
|
593
|
-
loop_track_attempt() {
|
|
594
|
-
local task_id="${1:-$(loop_get_state ".task_id")}"
|
|
595
|
-
|
|
596
|
-
local attempts
|
|
597
|
-
attempts=$(jq -r ".attempts[\"$task_id\"] // 0" "$LOOP_STATE_FILE" 2>/dev/null || echo "0")
|
|
598
|
-
local new_attempts=$((attempts + 1))
|
|
599
|
-
|
|
600
|
-
local temp_file
|
|
601
|
-
temp_file=$(mktemp)
|
|
602
|
-
jq ".attempts[\"$task_id\"] = $new_attempts" "$LOOP_STATE_FILE" > "$temp_file"
|
|
603
|
-
mv "$temp_file" "$LOOP_STATE_FILE"
|
|
604
|
-
|
|
605
|
-
echo "$new_attempts"
|
|
606
|
-
return 0
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
# Check if task should be blocked (gutter detection)
|
|
610
|
-
# When the same task fails repeatedly, it's likely "in the gutter" -
|
|
611
|
-
# adding more iterations won't help, need a different approach.
|
|
612
|
-
#
|
|
613
|
-
# Arguments:
|
|
614
|
-
# $1 - max_attempts (default: 5)
|
|
615
|
-
# $2 - task_id (optional)
|
|
616
|
-
# Returns: 0 if should block, 1 if not
|
|
617
|
-
loop_should_block() {
|
|
618
|
-
local max_attempts="${1:-5}"
|
|
619
|
-
local task_id="${2:-$(loop_get_state ".task_id")}"
|
|
620
|
-
|
|
621
|
-
local attempts
|
|
622
|
-
attempts=$(jq -r ".attempts[\"$task_id\"] // 0" "$LOOP_STATE_FILE" 2>/dev/null || echo "0")
|
|
623
|
-
|
|
624
|
-
# Warn at 80% of max attempts (gutter warning)
|
|
625
|
-
local warn_threshold=$(( (max_attempts * 4) / 5 ))
|
|
626
|
-
if [[ "$attempts" -ge "$warn_threshold" && "$attempts" -lt "$max_attempts" ]]; then
|
|
627
|
-
loop_log_warn "Possible gutter: $attempts/$max_attempts attempts on task $task_id"
|
|
628
|
-
loop_log_warn "Consider: different approach, smaller scope, or human review"
|
|
629
|
-
fi
|
|
630
|
-
|
|
631
|
-
[[ "$attempts" -ge "$max_attempts" ]]
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
# Block a task
|
|
635
|
-
# Arguments:
|
|
636
|
-
# $1 - reason
|
|
637
|
-
# $2 - task_id (optional)
|
|
638
|
-
# Returns: 0
|
|
639
|
-
loop_block_task() {
|
|
640
|
-
local reason="$1"
|
|
641
|
-
local task_id="${2:-$(loop_get_state ".task_id")}"
|
|
642
|
-
|
|
643
|
-
local temp_file
|
|
644
|
-
temp_file=$(mktemp)
|
|
645
|
-
jq ".blocked_tasks += [{\"id\": \"$task_id\", \"reason\": \"$reason\", \"blocked_at\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"}]" "$LOOP_STATE_FILE" > "$temp_file"
|
|
646
|
-
mv "$temp_file" "$LOOP_STATE_FILE"
|
|
647
|
-
|
|
648
|
-
loop_store_failure "Task blocked after multiple attempts" "$reason"
|
|
649
|
-
loop_log_warn "Task $task_id blocked: $reason"
|
|
650
|
-
return 0
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
# =============================================================================
|
|
654
|
-
# External Loop Runner
|
|
655
|
-
# =============================================================================
|
|
656
|
-
|
|
657
|
-
# Run external loop with fresh sessions
|
|
658
|
-
# Arguments:
|
|
659
|
-
# $1 - tool (opencode|claude|aider)
|
|
660
|
-
# $2 - prompt
|
|
661
|
-
# $3 - max_iterations
|
|
662
|
-
# $4 - completion_promise
|
|
663
|
-
# Returns: 0 on completion, 1 on max iterations
|
|
664
|
-
loop_run_external() {
|
|
665
|
-
local tool="$1"
|
|
666
|
-
local prompt="$2"
|
|
667
|
-
local max_iterations="${3:-50}"
|
|
668
|
-
local completion_promise="${4:-TASK_COMPLETE}"
|
|
669
|
-
|
|
670
|
-
# Validate tool
|
|
671
|
-
if ! command -v "$tool" &>/dev/null; then
|
|
672
|
-
loop_log_error "Tool not found: $tool"
|
|
673
|
-
return 1
|
|
674
|
-
fi
|
|
675
|
-
|
|
676
|
-
loop_log_info "Starting external loop with $tool"
|
|
677
|
-
loop_log_info "Max iterations: $max_iterations"
|
|
678
|
-
loop_log_info "Completion promise: $completion_promise"
|
|
679
|
-
|
|
680
|
-
local iteration=1
|
|
681
|
-
local output_file
|
|
682
|
-
output_file=$(mktemp)
|
|
683
|
-
trap 'rm -f "$output_file"' EXIT
|
|
684
|
-
|
|
685
|
-
while [[ $iteration -le $max_iterations ]]; do
|
|
686
|
-
loop_log_step "=== Iteration $iteration/$max_iterations ==="
|
|
687
|
-
|
|
688
|
-
# Update state
|
|
689
|
-
loop_set_state ".iteration" "$iteration"
|
|
690
|
-
loop_set_state ".last_iteration_at" "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
691
|
-
|
|
692
|
-
# Generate re-anchor prompt
|
|
693
|
-
local reanchor
|
|
694
|
-
reanchor=$(loop_generate_reanchor "$prompt")
|
|
695
|
-
|
|
696
|
-
# Build full prompt with re-anchor
|
|
697
|
-
local full_prompt="$reanchor"
|
|
698
|
-
|
|
699
|
-
# Run tool (fresh session each time)
|
|
700
|
-
local exit_code=0
|
|
701
|
-
case "$tool" in
|
|
702
|
-
opencode)
|
|
703
|
-
echo "$full_prompt" | opencode --print > "$output_file" 2>&1 || exit_code=$?
|
|
704
|
-
;;
|
|
705
|
-
claude)
|
|
706
|
-
echo "$full_prompt" | claude --print > "$output_file" 2>&1 || exit_code=$?
|
|
707
|
-
;;
|
|
708
|
-
aider)
|
|
709
|
-
aider --yes --message "$full_prompt" > "$output_file" 2>&1 || exit_code=$?
|
|
710
|
-
;;
|
|
711
|
-
*)
|
|
712
|
-
loop_log_error "Unknown tool: $tool"
|
|
713
|
-
return 1
|
|
714
|
-
;;
|
|
715
|
-
esac
|
|
716
|
-
|
|
717
|
-
# Check for completion promise
|
|
718
|
-
if grep -q "<promise>$completion_promise</promise>" "$output_file" 2>/dev/null; then
|
|
719
|
-
loop_log_success "Completion promise detected!"
|
|
720
|
-
loop_create_receipt "task" "success" '{"promise_fulfilled": true}'
|
|
721
|
-
loop_store_success "Task completed after $iteration iterations"
|
|
722
|
-
return 0
|
|
723
|
-
fi
|
|
724
|
-
|
|
725
|
-
# Track attempt and check for blocking
|
|
726
|
-
local attempts
|
|
727
|
-
attempts=$(loop_track_attempt)
|
|
728
|
-
if loop_should_block 5; then
|
|
729
|
-
loop_block_task "Max attempts reached after $attempts tries"
|
|
730
|
-
return 1
|
|
731
|
-
fi
|
|
732
|
-
|
|
733
|
-
# Create retry receipt
|
|
734
|
-
loop_create_receipt "task" "retry" "{\"iteration\": $iteration, \"exit_code\": $exit_code}"
|
|
735
|
-
|
|
736
|
-
iteration=$((iteration + 1))
|
|
737
|
-
|
|
738
|
-
# Brief delay between iterations
|
|
739
|
-
sleep 2
|
|
740
|
-
done
|
|
741
|
-
|
|
742
|
-
loop_log_warn "Max iterations ($max_iterations) reached without completion"
|
|
743
|
-
loop_block_task "Max iterations reached"
|
|
744
|
-
return 1
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
# =============================================================================
|
|
748
|
-
# Status Display
|
|
749
|
-
# =============================================================================
|
|
750
|
-
|
|
751
|
-
# Show loop status
|
|
752
|
-
# Arguments: none
|
|
753
|
-
# Returns: 0
|
|
754
|
-
loop_show_status() {
|
|
755
|
-
if [[ ! -f "$LOOP_STATE_FILE" ]]; then
|
|
756
|
-
echo "No active loop"
|
|
757
|
-
return 0
|
|
758
|
-
fi
|
|
759
|
-
|
|
760
|
-
echo ""
|
|
761
|
-
echo "=== Loop Status ==="
|
|
762
|
-
echo ""
|
|
763
|
-
|
|
764
|
-
local loop_type
|
|
765
|
-
loop_type=$(loop_get_state ".loop_type")
|
|
766
|
-
local task_id
|
|
767
|
-
task_id=$(loop_get_state ".task_id")
|
|
768
|
-
local iteration
|
|
769
|
-
iteration=$(loop_get_state ".iteration")
|
|
770
|
-
local max_iterations
|
|
771
|
-
max_iterations=$(loop_get_state ".max_iterations")
|
|
772
|
-
local phase
|
|
773
|
-
phase=$(loop_get_state ".phase")
|
|
774
|
-
local started_at
|
|
775
|
-
started_at=$(loop_get_state ".started_at")
|
|
776
|
-
local active
|
|
777
|
-
active=$(loop_get_state ".active")
|
|
778
|
-
local completion_promise
|
|
779
|
-
completion_promise=$(loop_get_state ".completion_promise")
|
|
780
|
-
|
|
781
|
-
echo "Type: $loop_type"
|
|
782
|
-
echo "Task ID: $task_id"
|
|
783
|
-
echo "Phase: $phase"
|
|
784
|
-
echo "Iteration: $iteration / $max_iterations"
|
|
785
|
-
echo "Active: $active"
|
|
786
|
-
echo "Started: $started_at"
|
|
787
|
-
echo "Promise: $completion_promise"
|
|
788
|
-
echo ""
|
|
789
|
-
|
|
790
|
-
# Show receipts
|
|
791
|
-
local receipt_count
|
|
792
|
-
receipt_count=$(find "$LOOP_RECEIPTS_DIR" -name "*.json" -type f 2>/dev/null | wc -l | tr -d ' ')
|
|
793
|
-
echo "Receipts: $receipt_count"
|
|
794
|
-
|
|
795
|
-
# Show blocked tasks
|
|
796
|
-
local blocked
|
|
797
|
-
blocked=$(jq -r '.blocked_tasks | length' "$LOOP_STATE_FILE" 2>/dev/null || echo "0")
|
|
798
|
-
if [[ "$blocked" -gt 0 ]]; then
|
|
799
|
-
echo ""
|
|
800
|
-
echo "Blocked tasks:"
|
|
801
|
-
jq -r '.blocked_tasks[] | " - \(.id): \(.reason)"' "$LOOP_STATE_FILE" 2>/dev/null
|
|
802
|
-
fi
|
|
803
|
-
|
|
804
|
-
echo ""
|
|
805
|
-
return 0
|
|
806
|
-
}
|