Skip to content

Commit a11a5a5

Browse files
feat(support): add local progress diagnostics
1 parent 57db2a8 commit a11a5a5

7 files changed

Lines changed: 934 additions & 1 deletion

File tree

.beads/issues.jsonl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@
525525
{"id":"bd-9zol","title":"Add DCG fail-open behavior test","status":"closed","priority":2,"issue_type":"task","created_at":"2026-01-11T05:31:03.772170514Z","created_by":"ubuntu","updated_at":"2026-01-11T07:12:30.440839902Z","closed_at":"2026-01-11T07:12:30.440839902Z","close_reason":"Fail-open tests implemented in dcg_edge_case_tests.sh (Tests 11-15 cover invalid JSON, empty input, partial JSON, binary input, and large input scenarios)","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-9zol","depends_on_id":"bd-159q","type":"blocks","created_at":"2026-01-11T05:31:12.546321659Z","created_by":"ubuntu","metadata":"","thread_id":""}],"comments":[{"id":21,"issue_id":"bd-9zol","author":"ubuntu","text":"DCG has a fail-open design - it never blocks workflow on errors or timeouts. Test scenarios: 1) DCG binary crashes during check - command should be ALLOWED, 2) Hook times out (simulate >50ms delay) - command should be ALLOWED, 3) Invalid JSON input - command should be ALLOWED, 4) DCG process exits non-zero - command should be ALLOWED. This ensures DCG never becomes a bottleneck that stops users from working.","created_at":"2026-01-11T05:31:12Z"}]}
526526
{"id":"bd-a1g","title":"Add Tailscale auth guidance to post-install summary","description":"## Task\n\nUpdate the post-install summary in `install.sh` to include Tailscale authentication guidance.\n\n## Current State\n\nThe installer prints a summary at the end with next steps. We need to add Tailscale auth.\n\n## Implementation\n\nIn `print_summary()` function, add:\n\n```bash\n# Check if Tailscale needs auth\nif command -v tailscale &>/dev/null; then\n local ts_status\n ts_status=$(tailscale status --json 2>/dev/null | jq -r '.BackendState // \"unknown\"')\n \n if [[ \"$ts_status\" != \"Running\" ]]; then\n echo \"\"\n echo \" 🔐 Tailscale (Secure Remote Access):\"\n echo \" sudo tailscale up\"\n echo \" → Log in with your Google account\"\n echo \" → Then access this VPS from anywhere!\"\n echo \"\"\n else\n local ts_ip\n ts_ip=$(tailscale ip -4 2>/dev/null)\n echo \"\"\n echo \" ✓ Tailscale connected: $ts_ip\"\n echo \"\"\n fi\nfi\n```\n\n## Ordering in Summary\n\nThe post-install summary should guide users through auth in a logical order:\n\n1. **Tailscale** (first - enables remote access)\n2. **Claude Code** (primary coding agent)\n3. **Codex CLI** (secondary agent)\n4. **Gemini CLI** (uses native Google, likely already authenticated)\n5. **GitHub** (if using git)\n\n## Example Output\n\n```\n============================================================\n ACFS Installation Complete!\n============================================================\n\n Next Steps - Authenticate Your Services:\n\n 🔐 Tailscale (Secure Remote Access):\n sudo tailscale up\n → Log in with your Google account\n → Then access this VPS from anywhere!\n\n 🤖 Claude Code:\n claude\n → Log in with your Anthropic account (Google SSO available)\n\n 🤖 Codex CLI:\n codex login\n → Log in with your ChatGPT account (Google SSO available)\n\n 🤖 Gemini CLI:\n gemini\n → Log in with your Google account\n\n Pro tip: Use the same Google account for all services!\n\n============================================================\n```\n\n## Considerations\n\n- Only show auth steps for services that need it\n- Show ✓ for services already authenticated\n- Keep it concise but actionable","status":"closed","priority":3,"issue_type":"task","created_at":"2025-12-21T21:58:34.656476Z","updated_at":"2025-12-21T22:45:48.037286Z","closed_at":"2025-12-21T22:45:48.037286Z","close_reason":"Tailscale auth guidance added to print_summary() in commit 4ee3080","source_repo":".","compaction_level":0,"original_size":0,"dependencies":[{"issue_id":"bd-a1g","depends_on_id":"bd-bt5","type":"blocks","created_at":"2025-12-21T22:03:15.487935Z","created_by":"daemon","metadata":"{}","thread_id":""}]}
527527
{"id":"bd-a24x","title":"Fix brittle YAML parsing in security.sh","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-12-23T19:37:03.650348Z","updated_at":"2025-12-23T20:07:55.611103Z","closed_at":"2025-12-23T20:07:55.611103Z","close_reason":"Fixed YAML parsing to support arbitrary indentation","source_repo":".","compaction_level":0,"original_size":0}
528-
{"id":"bd-a3eoy","title":"Add local onboarding progress and stuck-step diagnostics","description":"## What\nAdd local-only onboarding progress and stuck-step diagnostics so support bundles and the wizard can explain where a beginner got stuck without collecting private content.\n\n## Why\nThe user experience is currently hard to debug after the fact: support sees the final failure but not the path through terminal, SSH, installer, and onboard steps.\n\n## How\n- Record coarse local milestones such as wizard step completed, installer phase started/completed, doctor invoked, and onboard lesson started/completed.\n- Store locally under ACFS-owned state paths with redaction and opt-out semantics.\n- Surface a concise summary in support bundles.\n\n## Risks\nAvoid analytics creep. No network submission, no keystroke capture, no command history scraping.\n\n## Acceptance Criteria\n- Unit tests cover empty progress, corrupted progress, opt-out, and redacted support output.\n- E2E or smoke test demonstrates a normal path leaves useful local milestones.","status":"open","priority":2,"issue_type":"feature","created_at":"2026-05-08T13:50:58.265108224Z","created_by":"ubuntu","updated_at":"2026-05-08T14:03:19.267069249Z","source_repo":".","compaction_level":0,"original_size":0,"labels":["diagnostics","idea-wizard","next-wave","onboarding","privacy","support","tests"],"dependencies":[{"issue_id":"bd-a3eoy","depends_on_id":"bd-li8yw","type":"blocks","created_at":"2026-05-08T13:53:11.998539785Z","created_by":"ubuntu","metadata":"{}","thread_id":""}]}
528+
{"id":"bd-a3eoy","title":"Add local onboarding progress and stuck-step diagnostics","description":"## What\nAdd local-only onboarding progress and stuck-step diagnostics so support bundles and the wizard can explain where a beginner got stuck without collecting private content.\n\n## Why\nThe user experience is currently hard to debug after the fact: support sees the final failure but not the path through terminal, SSH, installer, and onboard steps.\n\n## How\n- Record coarse local milestones such as wizard step completed, installer phase started/completed, doctor invoked, and onboard lesson started/completed.\n- Store locally under ACFS-owned state paths with redaction and opt-out semantics.\n- Surface a concise summary in support bundles.\n\n## Risks\nAvoid analytics creep. No network submission, no keystroke capture, no command history scraping.\n\n## Acceptance Criteria\n- Unit tests cover empty progress, corrupted progress, opt-out, and redacted support output.\n- E2E or smoke test demonstrates a normal path leaves useful local milestones.","status":"closed","priority":2,"issue_type":"feature","created_at":"2026-05-08T13:50:58.265108224Z","created_by":"ubuntu","updated_at":"2026-05-08T16:01:06.508548873Z","closed_at":"2026-05-08T16:01:06.508300179Z","close_reason":"Completed local-only progress milestones and redacted support diagnostics","source_repo":".","compaction_level":0,"original_size":0,"labels":["diagnostics","idea-wizard","next-wave","onboarding","privacy","support","tests"],"dependencies":[{"issue_id":"bd-a3eoy","depends_on_id":"bd-li8yw","type":"blocks","created_at":"2026-05-08T13:53:11.998539785Z","created_by":"ubuntu","metadata":"{}","thread_id":""}]}
529529
{"id":"bd-a3ht","title":"EPIC: pt (process_triage) Full ACFS Integration","description":"# EPIC: pt (process_triage) Full ACFS Integration\n\n## Background & Context\npt is a Bash-based Bayesian zombie process killer with a gum-powered TUI. It helps developers identify and terminate runaway/zombie processes using probabilistic analysis.\n\n## Technical Specifications\n- **Binary**: `pt`\n- **Language**: Bash script\n- **Install Method**: `curl -fsSL https://raw.githubusercontent.com/.../install.sh | bash`\n- **Config Location**: `~/.config/process_triage/`\n- **Verification**: `pt --version && pt help`\n- **Update**: Re-run installer or `pt update` if available\n- **Robot Mode**: `pt robot` for JSON output\n- **Dependencies**: gum (for TUI), standard Unix tools (ps, kill)\n\n## Classification\n**CORE STACK MEMBER** - System maintenance tool for development environment health.\n\n## Integration Scope\nThis EPIC covers full integration into ACFS including:\n1. Manifest entry in acfs.manifest.yaml (phase: stack, category: tools)\n2. Checksums.yaml entry for verified installer\n3. Doctor command health checks\n4. Update command support\n5. Webapp/wizard mentions\n6. Learning Hub lesson (process management)\n7. Onboarding TUI lesson\n8. TLDR/Command Reference entry\n\n## Dependencies & Relationships\n- Depends on: gum TUI library (already in ACFS)\n- Related to: System administration, development environment maintenance\n- Useful for: Cleaning up after failed builds, zombie Node processes, etc.\n\n## Success Criteria\n- `acfs doctor` shows pt status\n- `acfs update` can update pt\n- Learning Hub explains pt's Bayesian approach\n- Onboarding mentions pt for system maintenance","status":"closed","priority":1,"issue_type":"epic","owner":"jeff141421@gmail.com","created_at":"2026-01-15T18:18:33.595964399Z","created_by":"Dicklesworthstone","updated_at":"2026-01-21T09:46:06.620495131Z","closed_at":"2026-01-21T09:46:06.620442823Z","close_reason":"Completed: PT fully integrated - manifest, checksums, lesson, commands, webapp flywheel/tldr","source_repo":".","compaction_level":0,"original_size":0,"labels":["epic","pt","stack-tool"]}
530530
{"id":"bd-a7qh","title":"Add Playwright production smoke tests to CI workflow","status":"closed","priority":2,"issue_type":"task","created_at":"2025-12-25T17:17:52.900506Z","updated_at":"2025-12-25T17:19:39.621137Z","closed_at":"2025-12-25T17:19:39.621137Z","close_reason":"Added production-smoke.yml workflow that tests live site for JS errors after deploys, daily, and on-demand","source_repo":".","compaction_level":0,"original_size":0}
531531
{"id":"bd-a7t7","title":"dashboard: avoid hardcoded ubuntu@ in SSH tunnel hint","description":"scripts/lib/dashboard.sh prints an SSH port-forward hint using ubuntu@<ip>. This is wrong for TARGET_USER installs and confusing if running as a non-ubuntu user. Use the current user (whoami) for the hint (or derive from state) so the instruction matches the actual SSH username.","status":"closed","priority":3,"issue_type":"bug","created_at":"2025-12-30T23:29:32.007863Z","updated_at":"2025-12-30T23:30:07.731380Z","closed_at":"2025-12-30T23:30:07.731380Z","close_reason":"Completed","source_repo":".","compaction_level":0,"original_size":0}

packages/onboard/onboard.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,20 @@ for candidate in \
833833
fi
834834
done
835835

836+
if [[ -z "${ACFS_LOCAL_PROGRESS_FILE:-}" && -n "$_ONBOARD_ACFS_HOME" ]]; then
837+
ACFS_LOCAL_PROGRESS_FILE="$_ONBOARD_ACFS_HOME/local_progress.json"
838+
fi
839+
for candidate in \
840+
"$_ONBOARD_SCRIPT_DIR/../scripts/lib/progress.sh" \
841+
"$_ONBOARD_SCRIPT_DIR/../../scripts/lib/progress.sh" \
842+
"$_ONBOARD_ACFS_HOME/scripts/lib/progress.sh"; do
843+
if [[ -f "$candidate" ]]; then
844+
# shellcheck disable=SC1090,SC1091
845+
source "$candidate" 2>/dev/null || true
846+
break
847+
fi
848+
done
849+
836850
# Dynamic lesson discovery
837851
# Finds all *.md files in LESSONS_DIR, sorted by filename
838852
# Extracts titles from the first "# Title" line in each file
@@ -1615,6 +1629,9 @@ mark_completed() {
16151629

16161630
# Release lock
16171631
{ exec {lock_fd}>&-; } 2>/dev/null || true
1632+
local lesson_number
1633+
lesson_number="$(get_lesson_number "$lesson" 2>/dev/null || printf '%d' "$((10#$lesson + 1))")"
1634+
local_progress_record_onboard_lesson "completed" "$lesson" "$lesson_number" 2>/dev/null || true
16181635
return 0
16191636
fi
16201637

@@ -1640,6 +1657,9 @@ mark_completed() {
16401657
fi
16411658

16421659
{ exec {lock_fd}>&-; } 2>/dev/null || true
1660+
local lesson_number
1661+
lesson_number="$(get_lesson_number "$lesson" 2>/dev/null || printf '%d' "$((10#$lesson + 1))")"
1662+
local_progress_record_onboard_lesson "completed" "$lesson" "$lesson_number" 2>/dev/null || true
16431663
return 0
16441664
}
16451665

@@ -1771,6 +1791,7 @@ EOF
17711791

17721792
# Release lock
17731793
{ exec {lock_fd}>&-; } 2>/dev/null || true
1794+
local_progress_record_onboard_event "progress_reset" "reset" 0 "$NUM_LESSONS" 2>/dev/null || true
17741795
echo -e "${GREEN}Progress reset!${NC}"
17751796
return 0
17761797
}
@@ -2548,6 +2569,7 @@ show_celebration() {
25482569
show_completion_certificate() {
25492570
local completed_at
25502571
completed_at=$(date '+%Y-%m-%d %H:%M')
2572+
local_progress_record_onboard_event "tutorial_completed" "completed" "$NUM_LESSONS" "$NUM_LESSONS" 2>/dev/null || true
25512573

25522574
clear 2>/dev/null || true
25532575

@@ -2621,6 +2643,8 @@ show_lesson() {
26212643
return 1
26222644
fi
26232645

2646+
local_progress_record_onboard_lesson "started" "$idx" "$lesson_number" 2>/dev/null || true
2647+
26242648
clear 2>/dev/null || true
26252649

26262650
# Header with step indicator
@@ -2802,6 +2826,7 @@ show_status() {
28022826
((completed_count += 1))
28032827
fi
28042828
done
2829+
local_progress_record_onboard_event "status_invoked" "observed" "$completed_count" "$NUM_LESSONS" 2>/dev/null || true
28052830

28062831
if (( NUM_LESSONS == 0 )); then
28072832
show_no_lessons_notice
@@ -2993,6 +3018,7 @@ onboard_main() {
29933018
idx="$(get_lesson_index_by_number "$((10#$arg))" || true)"
29943019
if [[ -n "$idx" ]]; then
29953020
init_progress
3021+
local_progress_record_onboard_event "session_started" "started" "" "$NUM_LESSONS" 2>/dev/null || true
29963022
if ! set_current "$idx"; then
29973023
return 1
29983024
fi
@@ -3078,11 +3104,14 @@ fi)
30783104
Environment:
30793105
ACFS_LESSONS_DIR Path to lesson files (default: $LESSONS_DIR)
30803106
ACFS_PROGRESS_FILE Path to progress file (default: $PROGRESS_FILE)
3107+
ACFS_LOCAL_PROGRESS=off disables local milestone recording
3108+
ACFS_LOCAL_PROGRESS_FILE overrides the milestone file path
30813109
EOF
30823110
return 0
30833111
;;
30843112
"")
30853113
init_progress
3114+
local_progress_record_onboard_event "session_started" "started" "" "$NUM_LESSONS" 2>/dev/null || true
30863115
main_menu
30873116
return $?
30883117
;;

scripts/lib/doctor.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ _acfs_doctor_source_first() {
496496

497497
# Source output formatting library (for TOON support)
498498
_acfs_doctor_source_first "output.sh" || true
499+
_acfs_doctor_source_first "progress.sh" || true
499500

500501
if ! type -t log_error >/dev/null 2>&1; then
501502
log_step() { echo "[*] $*" >&2; }
@@ -4777,6 +4778,8 @@ main() {
47774778
esac
47784779
done
47794780

4781+
local_progress_record_doctor_invoked "$DEEP_MODE" "$FIX_MODE" "$DRY_RUN_MODE" "$JSON_MODE" 2>/dev/null || true
4782+
47804783
if [[ "$JSON_MODE" != "true" ]]; then
47814784
local os_pretty="unknown"
47824785
if [[ -f /etc/os-release ]]; then

0 commit comments

Comments
 (0)