fss-link 1.6.1 → 1.6.12

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.
Files changed (43) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +63 -316
  3. package/bundle/fss-link.js +4038 -134262
  4. package/docs/CONFIGURATION.md +200 -0
  5. package/docs/README.md +192 -0
  6. package/docs/TOOLS.md +268 -0
  7. package/docs/assets/batch_0001_fss-link-terminal-interface.png +0 -0
  8. package/docs/assets/batch_0002_multiprovider-connection-hub-a.png +0 -0
  9. package/docs/assets/batch_0003_database-persistence-system-a.png +0 -0
  10. package/docs/assets/batch_0004_context-window-compression-a.png +0 -0
  11. package/docs/assets/batch_0005_file-operations-with-safety.png +0 -0
  12. package/docs/assets/batch_0006_semantic-search-rag-system.png +0 -0
  13. package/docs/assets/batch_0008_document-parsing-suite-a.png +0 -0
  14. package/docs/assets/batch_0009_web-research-tools-a.png +0 -0
  15. package/docs/assets/batch_0010_texttospeech-voice-output-a.png +0 -0
  16. package/docs/assets/batch_0011_shell-command-execution-a.png +0 -0
  17. package/docs/assets/batch_0012_mcp-extension-system-a.png +0 -0
  18. package/docs/assets/batch_0014_approval-mode-switches-a.png +0 -0
  19. package/docs/assets/batch_0015_folder-trust-system-a.png +0 -0
  20. package/package.json +53 -38
  21. package/scripts/check-publish.js +2 -1
  22. package/scripts/install-linux.sh +1 -2
  23. package/scripts/install-macos.sh +1 -2
  24. package/scripts/install-windows.ps1 +1 -2
  25. package/scripts/prebundle-sync-dist.js +51 -0
  26. package/README.pdf +0 -0
  27. package/scripts/analyze-session-logs.sh +0 -279
  28. package/scripts/emergency-kill-all-tests.sh +0 -95
  29. package/scripts/emergency-kill-vitest.sh +0 -95
  30. package/scripts/extract-session-logs.sh +0 -202
  31. package/scripts/get-previous-tag.js +0 -213
  32. package/scripts/get-release-version.js +0 -119
  33. package/scripts/index-session-logs.sh +0 -173
  34. package/scripts/local_telemetry.js +0 -219
  35. package/scripts/memory-monitor.sh +0 -165
  36. package/scripts/process-session-log.py +0 -302
  37. package/scripts/quick-install.sh +0 -195
  38. package/scripts/telemetry_gcp.js +0 -188
  39. package/scripts/telemetry_utils.js +0 -421
  40. package/scripts/test-windows-paths.js +0 -51
  41. package/scripts/tests/get-release-version.test.js +0 -110
  42. package/scripts/tests/test-setup.ts +0 -12
  43. package/scripts/tests/vitest.config.ts +0 -20
@@ -1,173 +0,0 @@
1
- #!/bin/bash
2
- # FSS Link Session Log RAG Indexer
3
- # Indexes processed session logs with FSS-RAG for powerful searching
4
-
5
- set -euo pipefail
6
-
7
- # Configuration
8
- PROCESSED_DIR="/MASTERFOLDER/Projects/fss-link/fss-live-testing/session-logs/processed"
9
- COLLECTION_NAME="fss-link-sessions"
10
-
11
- # Colors
12
- RED='\033[0;31m'
13
- GREEN='\033[0;32m'
14
- YELLOW='\033[1;33m'
15
- BLUE='\033[0;34m'
16
- NC='\033[0m'
17
-
18
- usage() {
19
- cat << EOF
20
- Usage: $0 [OPTIONS]
21
-
22
- Index FSS Link session logs with RAG for semantic searching.
23
-
24
- OPTIONS:
25
- -r, --reindex Recreate index from scratch
26
- -u, --update Add new sessions to existing index
27
- -s, --status Show index status
28
- -h, --help Show this help message
29
-
30
- EXAMPLES:
31
- $0 --reindex # Create fresh index of all sessions
32
- $0 --update # Add new sessions to index
33
- $0 --status # Check index status
34
-
35
- After indexing, search with:
36
- rag ${COLLECTION_NAME} "your query"
37
- rag-all "your query" # Search all collections
38
-
39
- EOF
40
- exit 1
41
- }
42
-
43
- check_rag() {
44
- if ! command -v rag-index &> /dev/null; then
45
- echo -e "${RED}Error: rag-index command not found${NC}"
46
- echo "FSS-RAG system must be installed and accessible"
47
- exit 1
48
- fi
49
- }
50
-
51
- show_status() {
52
- echo -e "${BLUE}=== FSS Link Sessions Index Status ===${NC}\n"
53
-
54
- # Check if collection exists
55
- if rag-index list | grep -q "${COLLECTION_NAME}"; then
56
- echo -e "${GREEN}✓${NC} Collection '${COLLECTION_NAME}' exists"
57
-
58
- # Get collection details
59
- rag-index status "${COLLECTION_NAME}" 2>/dev/null || echo " (Status unavailable)"
60
- else
61
- echo -e "${YELLOW}○${NC} Collection '${COLLECTION_NAME}' not yet created"
62
- echo ""
63
- echo "Run: $0 --reindex to create index"
64
- fi
65
-
66
- echo ""
67
-
68
- # Count processed sessions
69
- if [[ -d "${PROCESSED_DIR}" ]]; then
70
- session_count=$(find "${PROCESSED_DIR}" -name "*.md" -type f | wc -l)
71
- echo "Processed sessions available: ${session_count}"
72
- else
73
- echo -e "${RED}No processed sessions directory found${NC}"
74
- fi
75
- }
76
-
77
- reindex_all() {
78
- echo -e "${BLUE}=== Reindexing FSS Link Sessions ===${NC}\n"
79
-
80
- if [[ ! -d "${PROCESSED_DIR}" ]]; then
81
- echo -e "${RED}Error: Processed sessions directory not found: ${PROCESSED_DIR}${NC}"
82
- exit 1
83
- fi
84
-
85
- # Count sessions
86
- session_count=$(find "${PROCESSED_DIR}" -name "*.md" -type f | wc -l)
87
-
88
- if [[ ${session_count} -eq 0 ]]; then
89
- echo -e "${YELLOW}No processed sessions found to index${NC}"
90
- echo "Run extract-session-logs.sh first to process session logs"
91
- exit 1
92
- fi
93
-
94
- echo "Found ${session_count} processed sessions"
95
- echo ""
96
-
97
- # Check if collection exists
98
- if rag-index list | grep -q "${COLLECTION_NAME}"; then
99
- echo -e "${YELLOW}Warning: Collection '${COLLECTION_NAME}' already exists${NC}"
100
- echo -n "Delete and recreate? (y/N): "
101
- read -r confirm
102
- if [[ ! "${confirm}" =~ ^[Yy]$ ]]; then
103
- echo "Cancelled"
104
- exit 0
105
- fi
106
- echo ""
107
- fi
108
-
109
- # Create index
110
- echo -e "${BLUE}Creating RAG index...${NC}"
111
- echo ""
112
-
113
- cd "${PROCESSED_DIR}" || exit 1
114
-
115
- # Run rag-index with confirmation flag for non-interactive use
116
- if rag-index create . --confirm 2>&1; then
117
- echo ""
118
- echo -e "${GREEN}✓${NC} Successfully indexed ${session_count} sessions"
119
- echo ""
120
- echo -e "${YELLOW}Next steps:${NC}"
121
- echo " 1. Search sessions: rag ${COLLECTION_NAME} 'your query'"
122
- echo " 2. Check status: $0 --status"
123
- echo " 3. Analyze: analyze-session-logs.sh stats"
124
- else
125
- echo ""
126
- echo -e "${RED}✗${NC} Indexing failed"
127
- exit 1
128
- fi
129
- }
130
-
131
- update_index() {
132
- echo -e "${BLUE}=== Updating FSS Link Sessions Index ===${NC}\n"
133
-
134
- # Check if collection exists
135
- if ! rag-index list | grep -q "${COLLECTION_NAME}"; then
136
- echo -e "${YELLOW}Collection '${COLLECTION_NAME}' doesn't exist yet${NC}"
137
- echo "Run: $0 --reindex to create initial index"
138
- exit 1
139
- fi
140
-
141
- echo "This feature requires manual re-indexing currently"
142
- echo "Run: $0 --reindex to recreate the entire index"
143
- }
144
-
145
- # Main execution
146
- main() {
147
- check_rag
148
-
149
- if [[ $# -eq 0 ]]; then
150
- usage
151
- fi
152
-
153
- case "$1" in
154
- -r|--reindex)
155
- reindex_all
156
- ;;
157
- -u|--update)
158
- update_index
159
- ;;
160
- -s|--status)
161
- show_status
162
- ;;
163
- -h|--help)
164
- usage
165
- ;;
166
- *)
167
- echo -e "${RED}Unknown option: $1${NC}"
168
- usage
169
- ;;
170
- esac
171
- }
172
-
173
- main "$@"
@@ -1,219 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * @license
5
- * Copyright 2025 Google LLC
6
- * SPDX-License-Identifier: Apache-2.0
7
- */
8
-
9
- import path from 'path';
10
- import fs from 'fs';
11
- import { spawn, execSync } from 'child_process';
12
- import { fileURLToPath } from 'url';
13
- import {
14
- BIN_DIR,
15
- OTEL_DIR,
16
- ensureBinary,
17
- fileExists,
18
- manageTelemetrySettings,
19
- registerCleanup,
20
- waitForPort,
21
- } from './telemetry_utils.js';
22
-
23
- const __filename = fileURLToPath(import.meta.url);
24
- const __dirname = path.dirname(__filename);
25
-
26
- const OTEL_CONFIG_FILE = path.join(OTEL_DIR, 'collector-local.yaml');
27
- const OTEL_LOG_FILE = path.join(OTEL_DIR, 'collector.log');
28
- const JAEGER_LOG_FILE = path.join(OTEL_DIR, 'jaeger.log');
29
- const JAEGER_PORT = 16686;
30
-
31
- // This configuration is for the primary otelcol-contrib instance.
32
- // It receives from the CLI on 4317, exports traces to Jaeger on 14317,
33
- // and sends metrics/logs to the debug log.
34
- const OTEL_CONFIG_CONTENT = `
35
- receivers:
36
- otlp:
37
- protocols:
38
- grpc:
39
- endpoint: "localhost:4317"
40
- processors:
41
- batch:
42
- timeout: 1s
43
- exporters:
44
- otlp:
45
- endpoint: "localhost:14317"
46
- tls:
47
- insecure: true
48
- debug:
49
- verbosity: detailed
50
- service:
51
- telemetry:
52
- logs:
53
- level: "debug"
54
- metrics:
55
- level: "none"
56
- pipelines:
57
- traces:
58
- receivers: [otlp]
59
- processors: [batch]
60
- exporters: [otlp]
61
- metrics:
62
- receivers: [otlp]
63
- processors: [batch]
64
- exporters: [debug]
65
- logs:
66
- receivers: [otlp]
67
- processors: [batch]
68
- exporters: [debug]
69
- `;
70
-
71
- async function main() {
72
- // 1. Ensure binaries are available, downloading if necessary.
73
- // Binaries are stored in the project's .fss-link/otel/bin directory
74
- // to avoid modifying the user's system.
75
- if (!fileExists(BIN_DIR)) fs.mkdirSync(BIN_DIR, { recursive: true });
76
-
77
- const otelcolPath = await ensureBinary(
78
- 'otelcol-contrib',
79
- 'open-telemetry/opentelemetry-collector-releases',
80
- (version, platform, arch, ext) =>
81
- `otelcol-contrib_${version}_${platform}_${arch}.${ext}`,
82
- 'otelcol-contrib',
83
- false, // isJaeger = false
84
- ).catch((e) => {
85
- console.error(`��� Error getting otelcol-contrib: ${e.message}`);
86
- return null;
87
- });
88
- if (!otelcolPath) process.exit(1);
89
-
90
- const jaegerPath = await ensureBinary(
91
- 'jaeger',
92
- 'jaegertracing/jaeger',
93
- (version, platform, arch, ext) =>
94
- `jaeger-${version}-${platform}-${arch}.${ext}`,
95
- 'jaeger',
96
- true, // isJaeger = true
97
- ).catch((e) => {
98
- console.error(`🛑 Error getting jaeger: ${e.message}`);
99
- return null;
100
- });
101
- if (!jaegerPath) process.exit(1);
102
-
103
- // 2. Kill any existing processes to ensure a clean start.
104
- console.log('🧹 Cleaning up old processes and logs...');
105
- try {
106
- execSync('pkill -f "otelcol-contrib"');
107
- console.log('✅ Stopped existing otelcol-contrib process.');
108
- } catch (_e) {} // eslint-disable-line no-empty
109
- try {
110
- execSync('pkill -f "jaeger"');
111
- console.log('✅ Stopped existing jaeger process.');
112
- } catch (_e) {} // eslint-disable-line no-empty
113
- try {
114
- if (fileExists(OTEL_LOG_FILE)) fs.unlinkSync(OTEL_LOG_FILE);
115
- console.log('✅ Deleted old collector log.');
116
- } catch (e) {
117
- if (e.code !== 'ENOENT') console.error(e);
118
- }
119
- try {
120
- if (fileExists(JAEGER_LOG_FILE)) fs.unlinkSync(JAEGER_LOG_FILE);
121
- console.log('✅ Deleted old jaeger log.');
122
- } catch (e) {
123
- if (e.code !== 'ENOENT') console.error(e);
124
- }
125
-
126
- let jaegerProcess, collectorProcess;
127
- let jaegerLogFd, collectorLogFd;
128
-
129
- const originalSandboxSetting = manageTelemetrySettings(
130
- true,
131
- 'http://localhost:4317',
132
- 'local',
133
- );
134
-
135
- registerCleanup(
136
- () => [jaegerProcess, collectorProcess],
137
- () => [jaegerLogFd, collectorLogFd],
138
- originalSandboxSetting,
139
- );
140
-
141
- if (!fileExists(OTEL_DIR)) fs.mkdirSync(OTEL_DIR, { recursive: true });
142
- fs.writeFileSync(OTEL_CONFIG_FILE, OTEL_CONFIG_CONTENT);
143
- console.log('📄 Wrote OTEL collector config.');
144
-
145
- // Start Jaeger
146
- console.log(`🚀 Starting Jaeger service... Logs: ${JAEGER_LOG_FILE}`);
147
- jaegerLogFd = fs.openSync(JAEGER_LOG_FILE, 'a');
148
- jaegerProcess = spawn(
149
- jaegerPath,
150
- ['--set=receivers.otlp.protocols.grpc.endpoint=localhost:14317'],
151
- { stdio: ['ignore', jaegerLogFd, jaegerLogFd] },
152
- );
153
- console.log(`⏳ Waiting for Jaeger to start (PID: ${jaegerProcess.pid})...`);
154
-
155
- try {
156
- await waitForPort(JAEGER_PORT);
157
- console.log(`✅ Jaeger started successfully.`);
158
- } catch (_) {
159
- console.error(`🛑 Error: Jaeger failed to start on port ${JAEGER_PORT}.`);
160
- if (jaegerProcess && jaegerProcess.pid) {
161
- process.kill(jaegerProcess.pid, 'SIGKILL');
162
- }
163
- if (fileExists(JAEGER_LOG_FILE)) {
164
- console.error('📄 Jaeger Log Output:');
165
- console.error(fs.readFileSync(JAEGER_LOG_FILE, 'utf-8'));
166
- }
167
- process.exit(1);
168
- }
169
-
170
- // Start the primary OTEL collector
171
- console.log(`🚀 Starting OTEL collector... Logs: ${OTEL_LOG_FILE}`);
172
- collectorLogFd = fs.openSync(OTEL_LOG_FILE, 'a');
173
- collectorProcess = spawn(otelcolPath, ['--config', OTEL_CONFIG_FILE], {
174
- stdio: ['ignore', collectorLogFd, collectorLogFd],
175
- });
176
- console.log(
177
- `⏳ Waiting for OTEL collector to start (PID: ${collectorProcess.pid})...`,
178
- );
179
-
180
- try {
181
- await waitForPort(4317);
182
- console.log(`✅ OTEL collector started successfully.`);
183
- } catch (_) {
184
- console.error(`🛑 Error: OTEL collector failed to start on port 4317.`);
185
- if (collectorProcess && collectorProcess.pid) {
186
- process.kill(collectorProcess.pid, 'SIGKILL');
187
- }
188
- if (fileExists(OTEL_LOG_FILE)) {
189
- console.error('📄 OTEL Collector Log Output:');
190
- console.error(fs.readFileSync(OTEL_LOG_FILE, 'utf-8'));
191
- }
192
- process.exit(1);
193
- }
194
-
195
- [jaegerProcess, collectorProcess].forEach((proc) => {
196
- if (proc) {
197
- proc.on('error', (err) => {
198
- console.error(`${proc.spawnargs[0]} process error:`, err);
199
- process.exit(1);
200
- });
201
- }
202
- });
203
-
204
- console.log(`
205
- ✨ Local telemetry environment is running.`);
206
- console.log(
207
- `
208
- 🔎 View traces in the Jaeger UI: http://localhost:${JAEGER_PORT}`,
209
- );
210
- console.log(`📊 View metrics in the logs and metrics: ${OTEL_LOG_FILE}`);
211
- console.log(
212
- `
213
- 📄 Tail logs and metrics in another terminal: tail -f ${OTEL_LOG_FILE}`,
214
- );
215
- console.log(`
216
- Press Ctrl+C to exit.`);
217
- }
218
-
219
- main();
@@ -1,165 +0,0 @@
1
- #!/bin/bash
2
-
3
- # 📊 Memory Monitor for Test Processes
4
- # Purpose: Monitor memory usage during tests and auto-kill if dangerous
5
- # Usage: ./scripts/memory-monitor.sh [--auto-kill] [--threshold-gb=8]
6
-
7
- # Default settings
8
- AUTO_KILL=false
9
- THRESHOLD_GB=8
10
- INTERVAL=5
11
-
12
- # Colors
13
- RED='\033[0;31m'
14
- YELLOW='\033[1;33m'
15
- GREEN='\033[0;32m'
16
- BLUE='\033[0;34m'
17
- NC='\033[0m'
18
-
19
- # Parse arguments
20
- for arg in "$@"; do
21
- case $arg in
22
- --auto-kill)
23
- AUTO_KILL=true
24
- shift
25
- ;;
26
- --threshold-gb=*)
27
- THRESHOLD_GB="${arg#*=}"
28
- shift
29
- ;;
30
- --interval=*)
31
- INTERVAL="${arg#*=}"
32
- shift
33
- ;;
34
- --help)
35
- echo "Memory Monitor for Test Processes"
36
- echo ""
37
- echo "Usage: $0 [options]"
38
- echo ""
39
- echo "Options:"
40
- echo " --auto-kill Automatically kill processes exceeding threshold"
41
- echo " --threshold-gb=N Memory threshold in GB (default: 8)"
42
- echo " --interval=N Check interval in seconds (default: 5)"
43
- echo " --help Show this help"
44
- echo ""
45
- echo "Examples:"
46
- echo " $0 # Monitor only"
47
- echo " $0 --auto-kill # Monitor and auto-kill at 8GB"
48
- echo " $0 --auto-kill --threshold-gb=4 # Auto-kill at 4GB"
49
- exit 0
50
- ;;
51
- esac
52
- done
53
-
54
- THRESHOLD_KB=$((THRESHOLD_GB * 1024 * 1024))
55
-
56
- echo -e "${BLUE}📊 FSS Link Memory Monitor${NC}"
57
- echo -e "${YELLOW}Threshold: ${THRESHOLD_GB}GB | Auto-kill: ${AUTO_KILL} | Interval: ${INTERVAL}s${NC}"
58
- echo -e "${YELLOW}Press Ctrl+C to stop monitoring${NC}"
59
- echo ""
60
-
61
- # Function to format memory
62
- format_memory() {
63
- local kb=$1
64
- if [ $kb -gt 1048576 ]; then
65
- echo "$((kb / 1024 / 1024))GB"
66
- elif [ $kb -gt 1024 ]; then
67
- echo "$((kb / 1024))MB"
68
- else
69
- echo "${kb}KB"
70
- fi
71
- }
72
-
73
- # Function to kill dangerous processes
74
- kill_dangerous_processes() {
75
- local pids="$1"
76
- echo -e "${RED}🚨 EMERGENCY: Memory threshold exceeded!${NC}"
77
- echo -e "${RED}💀 Killing dangerous processes...${NC}"
78
-
79
- for pid in $pids; do
80
- if [ -n "$pid" ]; then
81
- kill -KILL "$pid" 2>/dev/null && echo "Killed PID $pid" || true
82
- fi
83
- done
84
-
85
- # Run the emergency script as backup
86
- echo -e "${YELLOW}Running emergency cleanup...${NC}"
87
- ./scripts/emergency-kill-vitest.sh --force
88
- }
89
-
90
- # Monitoring loop
91
- while true; do
92
- clear
93
- echo -e "${BLUE}📊 FSS Link Memory Monitor - $(date)${NC}"
94
- echo -e "${YELLOW}Threshold: ${THRESHOLD_GB}GB | Auto-kill: ${AUTO_KILL}${NC}"
95
- echo ""
96
-
97
- # System memory overview
98
- echo -e "${GREEN}💻 System Memory:${NC}"
99
- free -h
100
- echo ""
101
-
102
- # Find test processes
103
- TEST_PIDS=$(pgrep -f "vitest\|node.*test\|jest\|mocha" 2>/dev/null || true)
104
-
105
- if [ -z "$TEST_PIDS" ]; then
106
- echo -e "${GREEN}✅ No test processes running${NC}"
107
- else
108
- echo -e "${YELLOW}🧪 Test Processes:${NC}"
109
- printf "%-8s %-8s %-10s %-10s %s\n" "PID" "CPU%" "MEMORY" "STATUS" "COMMAND"
110
- echo "────────────────────────────────────────────────────────────────"
111
-
112
- DANGEROUS_PIDS=""
113
- TOTAL_TEST_MEMORY=0
114
-
115
- for pid in $TEST_PIDS; do
116
- if [ -n "$pid" ]; then
117
- # Get process info
118
- if ps -p "$pid" > /dev/null 2>&1; then
119
- INFO=$(ps -p "$pid" -o pid,%cpu,rss,comm --no-headers 2>/dev/null)
120
- if [ -n "$INFO" ]; then
121
- MEMORY_KB=$(echo "$INFO" | awk '{print $3}')
122
- CPU=$(echo "$INFO" | awk '{print $2}')
123
- COMMAND=$(echo "$INFO" | awk '{print $4}')
124
-
125
- TOTAL_TEST_MEMORY=$((TOTAL_TEST_MEMORY + MEMORY_KB))
126
-
127
- # Format memory for display
128
- MEMORY_DISPLAY=$(format_memory $MEMORY_KB)
129
-
130
- # Check if dangerous
131
- STATUS="OK"
132
- if [ $MEMORY_KB -gt $THRESHOLD_KB ]; then
133
- STATUS="${RED}DANGER${NC}"
134
- DANGEROUS_PIDS="$DANGEROUS_PIDS $pid"
135
- elif [ $MEMORY_KB -gt $((THRESHOLD_KB / 2)) ]; then
136
- STATUS="${YELLOW}WARNING${NC}"
137
- else
138
- STATUS="${GREEN}OK${NC}"
139
- fi
140
-
141
- printf "%-8s %-8s %-10s %-20s %s\n" "$pid" "$CPU%" "$MEMORY_DISPLAY" "$STATUS" "$COMMAND"
142
- fi
143
- fi
144
- fi
145
- done
146
-
147
- echo ""
148
- echo -e "${BLUE}📈 Total Test Memory: $(format_memory $TOTAL_TEST_MEMORY)${NC}"
149
-
150
- # Check for auto-kill
151
- if [ "$AUTO_KILL" = true ] && [ -n "$DANGEROUS_PIDS" ]; then
152
- kill_dangerous_processes "$DANGEROUS_PIDS"
153
- break
154
- elif [ -n "$DANGEROUS_PIDS" ]; then
155
- echo ""
156
- echo -e "${RED}⚠️ DANGEROUS processes detected!${NC}"
157
- echo -e "${YELLOW}Run with --auto-kill to automatically terminate them${NC}"
158
- echo -e "${YELLOW}Or manually run: ./scripts/emergency-kill-vitest.sh${NC}"
159
- fi
160
- fi
161
-
162
- echo ""
163
- echo -e "${BLUE}Next check in ${INTERVAL} seconds... (Ctrl+C to stop)${NC}"
164
- sleep $INTERVAL
165
- done