Compare commits
No commits in common. "0480180b03536edec33d987dfb67eb75beec4852" and "a0acc38fa6d4454ee5d3a9b772e420598cdfedce" have entirely different histories.
0480180b03
...
a0acc38fa6
@ -1,4 +0,0 @@
|
|||||||
node_modules/
|
|
||||||
coverage/
|
|
||||||
.git/
|
|
||||||
*.log
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
insert_final_newline = true
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
"es2020": true
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2020
|
|
||||||
},
|
|
||||||
"plugins": ["security"],
|
|
||||||
"extends": ["eslint:recommended"],
|
|
||||||
"rules": {
|
|
||||||
"no-unused-vars": ["error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
|
|
||||||
"no-console": "warn",
|
|
||||||
"security/detect-object-injection": "warn",
|
|
||||||
"security/detect-non-literal-fs-filename": "warn",
|
|
||||||
"security/detect-eval-with-expression": "error"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
node_modules/
|
|
||||||
coverage/
|
|
||||||
*.log
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
node_modules/
|
|
||||||
coverage/
|
|
||||||
dist/
|
|
||||||
package-lock.json
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "all",
|
|
||||||
"printWidth": 100,
|
|
||||||
"tabWidth": 2
|
|
||||||
}
|
|
||||||
23
Makefile
23
Makefile
@ -1,23 +0,0 @@
|
|||||||
export NODE_ENV := development
|
|
||||||
|
|
||||||
.PHONY: check install test lint fmt fmt-check secret-scan
|
|
||||||
|
|
||||||
check: install lint fmt-check secret-scan test
|
|
||||||
|
|
||||||
install:
|
|
||||||
npm install
|
|
||||||
|
|
||||||
test:
|
|
||||||
@echo "[SKIP] No tests found"
|
|
||||||
|
|
||||||
lint:
|
|
||||||
npx eslint .
|
|
||||||
|
|
||||||
fmt:
|
|
||||||
npx prettier --write .
|
|
||||||
|
|
||||||
fmt-check:
|
|
||||||
npx prettier --check .
|
|
||||||
|
|
||||||
secret-scan:
|
|
||||||
bash tools/secret-scan.sh .
|
|
||||||
@ -3,7 +3,6 @@
|
|||||||
A lightweight CLI tool for OpenClaw agents to provide "Antigravity-style" live status updates in Mattermost channels (and others) without spamming.
|
A lightweight CLI tool for OpenClaw agents to provide "Antigravity-style" live status updates in Mattermost channels (and others) without spamming.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Live Updates:** Create a single message and update it repeatedly.
|
- **Live Updates:** Create a single message and update it repeatedly.
|
||||||
- **Sub-Agent Support:** Works in clean environments via embedded config or CLI flags.
|
- **Sub-Agent Support:** Works in clean environments via embedded config or CLI flags.
|
||||||
- **Cross-Channel:** Supports dynamic channel targeting via `--channel`.
|
- **Cross-Channel:** Supports dynamic channel targeting via `--channel`.
|
||||||
@ -12,7 +11,6 @@ A lightweight CLI tool for OpenClaw agents to provide "Antigravity-style" live s
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Run the interactive installer wizard:
|
Run the interactive installer wizard:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./install.sh
|
./install.sh
|
||||||
```
|
```
|
||||||
|
|||||||
1290
package-lock.json
generated
1290
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "mattermost-openclaw-livestatus",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"private": true,
|
|
||||||
"description": "OpenClaw Live Status Tool for Mattermost",
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^8.56.0",
|
|
||||||
"eslint-plugin-security": "^2.1.0",
|
|
||||||
"prettier": "^3.2.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -6,20 +6,15 @@ It allows you to create a "Live Log" post that you update in-place, reducing cha
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### 1. Initialize (Start of Task)
|
### 1. Initialize (Start of Task)
|
||||||
|
|
||||||
Create a new status post. It will print the `POST_ID`.
|
Create a new status post. It will print the `POST_ID`.
|
||||||
**Required:** Pass the `CHANNEL_ID` if known (otherwise it defaults to system channel).
|
**Required:** Pass the `CHANNEL_ID` if known (otherwise it defaults to system channel).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
live-status create <CHANNEL_ID> "🚀 **Task Started:** Initializing..."
|
live-status create <CHANNEL_ID> "🚀 **Task Started:** Initializing..."
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output:** `p6...` (The Post ID)
|
**Output:** `p6...` (The Post ID)
|
||||||
|
|
||||||
### 2. Update (During Task)
|
### 2. Update (During Task)
|
||||||
|
|
||||||
Update the post with new log lines. Use a code block for logs.
|
Update the post with new log lines. Use a code block for logs.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
live-status update <POST_ID> "🚀 **Task Started:** Initializing...
|
live-status update <POST_ID> "🚀 **Task Started:** Initializing...
|
||||||
\`\`\`
|
\`\`\`
|
||||||
@ -29,9 +24,7 @@ live-status update <POST_ID> "🚀 **Task Started:** Initializing...
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 3. Complete (End of Task)
|
### 3. Complete (End of Task)
|
||||||
|
|
||||||
Mark as done.
|
Mark as done.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
live-status update <POST_ID> "✅ **Task Complete.**
|
live-status update <POST_ID> "✅ **Task Complete.**
|
||||||
\`\`\`
|
\`\`\`
|
||||||
@ -42,7 +35,6 @@ live-status update <POST_ID> "✅ **Task Complete.**
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Protocol
|
## Protocol
|
||||||
|
|
||||||
- **Always** capture the `POST_ID` from the `create` command.
|
- **Always** capture the `POST_ID` from the `create` command.
|
||||||
- **Always** append to the previous log (maintain history).
|
- **Always** append to the previous log (maintain history).
|
||||||
- **Use Code Blocks** for technical logs.
|
- **Use Code Blocks** for technical logs.
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const https = require('http'); // Using http for mattermost:8065 (no ssl inside docker network)
|
const https = require('http'); // Using http for mattermost:8065 (no ssl inside docker network)
|
||||||
const _fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
// --- HELPER: PARSE ARGS ---
|
// --- HELPER: PARSE ARGS ---
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
@ -26,11 +26,7 @@ const CONFIG = {
|
|||||||
port: 8065,
|
port: 8065,
|
||||||
token: 'DEFAULT_TOKEN_PLACEHOLDER', // Set via install.sh wizard
|
token: 'DEFAULT_TOKEN_PLACEHOLDER', // Set via install.sh wizard
|
||||||
// Priority: 1. CLI Flag, 2. Env Var, 3. Hardcoded Fallback (Project-0)
|
// Priority: 1. CLI Flag, 2. Env Var, 3. Hardcoded Fallback (Project-0)
|
||||||
channel_id:
|
channel_id: options.channel || process.env.MM_CHANNEL_ID || process.env.CHANNEL_ID || 'obzja4hb8pd85xk45xn4p31jye'
|
||||||
options.channel ||
|
|
||||||
process.env.MM_CHANNEL_ID ||
|
|
||||||
process.env.CHANNEL_ID ||
|
|
||||||
'obzja4hb8pd85xk45xn4p31jye',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- HELPER: HTTP REQUEST ---
|
// --- HELPER: HTTP REQUEST ---
|
||||||
@ -42,14 +38,14 @@ function request(method, path, data) {
|
|||||||
path: '/api/v4' + path,
|
path: '/api/v4' + path,
|
||||||
method: method,
|
method: method,
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${CONFIG.token}`,
|
'Authorization': `Bearer ${CONFIG.token}`,
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json'
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const req = https.request(options, (res) => {
|
const req = https.request(options, (res) => {
|
||||||
let body = '';
|
let body = '';
|
||||||
res.on('data', (chunk) => (body += chunk));
|
res.on('data', (chunk) => body += chunk);
|
||||||
res.on('end', () => {
|
res.on('end', () => {
|
||||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
try {
|
try {
|
||||||
@ -75,7 +71,7 @@ async function createPost(text) {
|
|||||||
try {
|
try {
|
||||||
const result = await request('POST', '/posts', {
|
const result = await request('POST', '/posts', {
|
||||||
channel_id: CONFIG.channel_id,
|
channel_id: CONFIG.channel_id,
|
||||||
message: text,
|
message: text
|
||||||
});
|
});
|
||||||
console.log(result.id);
|
console.log(result.id);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -90,11 +86,11 @@ async function updatePost(postId, text) {
|
|||||||
await request('PUT', `/posts/${postId}`, {
|
await request('PUT', `/posts/${postId}`, {
|
||||||
id: postId,
|
id: postId,
|
||||||
message: text,
|
message: text,
|
||||||
props: current.props,
|
props: current.props
|
||||||
});
|
});
|
||||||
console.log('updated');
|
console.log("updated");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error updating post:', e.message);
|
console.error("Error updating post:", e.message);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +104,7 @@ if (command === 'create') {
|
|||||||
const text = otherArgs.slice(1).join(' ');
|
const text = otherArgs.slice(1).join(' ');
|
||||||
updatePost(id, text);
|
updatePost(id, text);
|
||||||
} else {
|
} else {
|
||||||
console.log('Usage: live-status [--channel ID] create <text>');
|
console.log("Usage: live-status [--channel ID] create <text>");
|
||||||
console.log(' live-status update <id> <text>');
|
console.log(" live-status update <id> <text>");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,69 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# secret-scan.sh — Scans for private keys and high-entropy secrets
|
|
||||||
# Usage: bash tools/secret-scan.sh [directory]
|
|
||||||
# Uses .secret-scan-allowlist for false positives (one file path per line)
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SCAN_DIR="${1:-.}"
|
|
||||||
ALLOWLIST=".secret-scan-allowlist"
|
|
||||||
FINDINGS=0
|
|
||||||
|
|
||||||
# Build find exclusions
|
|
||||||
EXCLUDES=(-not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/coverage/*" -not -path "*/dist/*")
|
|
||||||
|
|
||||||
# Load allowlist
|
|
||||||
ALLOWLIST_PATHS=()
|
|
||||||
if [ -f "$ALLOWLIST" ]; then
|
|
||||||
while IFS= read -r line || [ -n "$line" ]; do
|
|
||||||
[[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
|
|
||||||
ALLOWLIST_PATHS+=("$line")
|
|
||||||
done < "$ALLOWLIST"
|
|
||||||
fi
|
|
||||||
|
|
||||||
is_allowed() {
|
|
||||||
local file="$1"
|
|
||||||
for allowed in "${ALLOWLIST_PATHS[@]}"; do
|
|
||||||
if [[ "$file" == *"$allowed"* ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "Scanning $SCAN_DIR for secrets..."
|
|
||||||
|
|
||||||
# Scan for private keys
|
|
||||||
while IFS= read -r file; do
|
|
||||||
[ -f "$file" ] || continue
|
|
||||||
is_allowed "$file" && continue
|
|
||||||
if grep -qE '-----BEGIN (RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----' "$file" 2>/dev/null; then
|
|
||||||
echo "FINDING [private-key]: $file"
|
|
||||||
FINDINGS=$((FINDINGS + 1))
|
|
||||||
fi
|
|
||||||
done < <(find "$SCAN_DIR" "${EXCLUDES[@]}" -type f)
|
|
||||||
|
|
||||||
# Scan for high-entropy hex strings (40+ chars)
|
|
||||||
while IFS= read -r file; do
|
|
||||||
[ -f "$file" ] || continue
|
|
||||||
is_allowed "$file" && continue
|
|
||||||
if grep -qE '[0-9a-f]{40,}' "$file" 2>/dev/null; then
|
|
||||||
# Filter out common false positives (git SHAs in lock files, etc.)
|
|
||||||
BASENAME=$(basename "$file")
|
|
||||||
if [[ "$BASENAME" != "package-lock.json" && "$BASENAME" != "*.lock" ]]; then
|
|
||||||
MATCHES=$(grep -oE '[0-9a-f]{40,}' "$file" 2>/dev/null || true)
|
|
||||||
if [ -n "$MATCHES" ]; then
|
|
||||||
echo "FINDING [high-entropy-hex]: $file"
|
|
||||||
FINDINGS=$((FINDINGS + 1))
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done < <(find "$SCAN_DIR" "${EXCLUDES[@]}" -type f -not -name "package-lock.json" -not -name "*.lock")
|
|
||||||
|
|
||||||
if [ "$FINDINGS" -gt 0 ]; then
|
|
||||||
echo "secret-scan: $FINDINGS finding(s) — FAIL"
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "secret-scan: clean — PASS"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
Loading…
Reference in New Issue
Block a user