policies: add standard policy files #1

Merged
sol merged 1 commits from policies/add-standard-files into master 2026-03-01 08:26:43 +01:00
13 changed files with 1525 additions and 74 deletions

4
.dockerignore Normal file
View File

@ -0,0 +1,4 @@
node_modules/
coverage/
.git/
*.log

9
.editorconfig Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

18
.eslintrc.json Normal file
View File

@ -0,0 +1,18 @@
{
"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 Normal file
View File

@ -0,0 +1,3 @@
node_modules/
coverage/
*.log

4
.prettierignore Normal file
View File

@ -0,0 +1,4 @@
node_modules/
coverage/
dist/
package-lock.json

6
.prettierrc Normal file
View File

@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2
}

23
Makefile Normal file
View File

@ -0,0 +1,23 @@
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 .

View File

@ -3,6 +3,7 @@
A lightweight CLI tool for OpenClaw agents to provide "Antigravity-style" live status updates in Mattermost channels (and others) without spamming.
## Features
- **Live Updates:** Create a single message and update it repeatedly.
- **Sub-Agent Support:** Works in clean environments via embedded config or CLI flags.
- **Cross-Channel:** Supports dynamic channel targeting via `--channel`.
@ -11,6 +12,7 @@ A lightweight CLI tool for OpenClaw agents to provide "Antigravity-style" live s
## Installation
Run the interactive installer wizard:
```bash
./install.sh
```

1290
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

11
package.json Normal file
View File

@ -0,0 +1,11 @@
{
"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"
}
}

View File

@ -6,15 +6,20 @@ It allows you to create a "Live Log" post that you update in-place, reducing cha
## Usage
### 1. Initialize (Start of Task)
Create a new status post. It will print the `POST_ID`.
**Required:** Pass the `CHANNEL_ID` if known (otherwise it defaults to system channel).
```bash
live-status create <CHANNEL_ID> "🚀 **Task Started:** Initializing..."
```
**Output:** `p6...` (The Post ID)
### 2. Update (During Task)
Update the post with new log lines. Use a code block for logs.
```bash
live-status update <POST_ID> "🚀 **Task Started:** Initializing...
\`\`\`
@ -24,7 +29,9 @@ live-status update <POST_ID> "🚀 **Task Started:** Initializing...
```
### 3. Complete (End of Task)
Mark as done.
```bash
live-status update <POST_ID> "✅ **Task Complete.**
\`\`\`
@ -35,6 +42,7 @@ live-status update <POST_ID> "✅ **Task Complete.**
```
## Protocol
- **Always** capture the `POST_ID` from the `create` command.
- **Always** append to the previous log (maintain history).
- **Use Code Blocks** for technical logs.

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
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 ---
const args = process.argv.slice(2);
@ -26,7 +26,11 @@ const CONFIG = {
port: 8065,
token: 'DEFAULT_TOKEN_PLACEHOLDER', // Set via install.sh wizard
// Priority: 1. CLI Flag, 2. Env Var, 3. Hardcoded Fallback (Project-0)
channel_id: options.channel || process.env.MM_CHANNEL_ID || process.env.CHANNEL_ID || 'obzja4hb8pd85xk45xn4p31jye'
channel_id:
options.channel ||
process.env.MM_CHANNEL_ID ||
process.env.CHANNEL_ID ||
'obzja4hb8pd85xk45xn4p31jye',
};
// --- HELPER: HTTP REQUEST ---
@ -38,14 +42,14 @@ function request(method, path, data) {
path: '/api/v4' + path,
method: method,
headers: {
'Authorization': `Bearer ${CONFIG.token}`,
'Content-Type': 'application/json'
}
Authorization: `Bearer ${CONFIG.token}`,
'Content-Type': 'application/json',
},
};
const req = https.request(options, (res) => {
let body = '';
res.on('data', (chunk) => body += chunk);
res.on('data', (chunk) => (body += chunk));
res.on('end', () => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
@ -71,7 +75,7 @@ async function createPost(text) {
try {
const result = await request('POST', '/posts', {
channel_id: CONFIG.channel_id,
message: text
message: text,
});
console.log(result.id);
} catch (e) {
@ -86,11 +90,11 @@ async function updatePost(postId, text) {
await request('PUT', `/posts/${postId}`, {
id: postId,
message: text,
props: current.props
props: current.props,
});
console.log("updated");
console.log('updated');
} catch (e) {
console.error("Error updating post:", e.message);
console.error('Error updating post:', e.message);
process.exit(1);
}
}
@ -104,7 +108,7 @@ if (command === 'create') {
const text = otherArgs.slice(1).join(' ');
updatePost(id, text);
} else {
console.log("Usage: live-status [--channel ID] create <text>");
console.log(" live-status update <id> <text>");
console.log('Usage: live-status [--channel ID] create <text>');
console.log(' live-status update <id> <text>');
process.exit(1);
}

69
tools/secret-scan.sh Executable file
View File

@ -0,0 +1,69 @@
#!/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