laminark 2.21.6
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/.claude-plugin/marketplace.json +15 -0
- package/README.md +182 -0
- package/package.json +63 -0
- package/plugin/.claude-plugin/plugin.json +13 -0
- package/plugin/.mcp.json +12 -0
- package/plugin/dist/analysis/worker.d.ts +1 -0
- package/plugin/dist/analysis/worker.js +233 -0
- package/plugin/dist/analysis/worker.js.map +1 -0
- package/plugin/dist/config-t8LZeB-u.mjs +90 -0
- package/plugin/dist/config-t8LZeB-u.mjs.map +1 -0
- package/plugin/dist/hooks/handler.d.ts +284 -0
- package/plugin/dist/hooks/handler.d.ts.map +1 -0
- package/plugin/dist/hooks/handler.js +2125 -0
- package/plugin/dist/hooks/handler.js.map +1 -0
- package/plugin/dist/index.d.ts +445 -0
- package/plugin/dist/index.d.ts.map +1 -0
- package/plugin/dist/index.js +5831 -0
- package/plugin/dist/index.js.map +1 -0
- package/plugin/dist/observations-Ch0nc47i.d.mts +170 -0
- package/plugin/dist/observations-Ch0nc47i.d.mts.map +1 -0
- package/plugin/dist/tool-registry-CZ3mJ4iR.mjs +2655 -0
- package/plugin/dist/tool-registry-CZ3mJ4iR.mjs.map +1 -0
- package/plugin/hooks/hooks.json +78 -0
- package/plugin/scripts/README.md +47 -0
- package/plugin/scripts/bump-version.sh +44 -0
- package/plugin/scripts/ensure-deps.sh +12 -0
- package/plugin/scripts/install.sh +63 -0
- package/plugin/scripts/local-install.sh +103 -0
- package/plugin/scripts/setup-tmpdir.sh +65 -0
- package/plugin/scripts/uninstall.sh +95 -0
- package/plugin/scripts/update.sh +88 -0
- package/plugin/scripts/verify-install.sh +43 -0
- package/plugin/ui/activity.js +185 -0
- package/plugin/ui/app.js +1642 -0
- package/plugin/ui/graph.js +2333 -0
- package/plugin/ui/help.js +228 -0
- package/plugin/ui/index.html +492 -0
- package/plugin/ui/settings.js +650 -0
- package/plugin/ui/styles.css +2910 -0
- package/plugin/ui/timeline.js +652 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Bootstrap installer for Laminark plugin.
|
|
3
|
+
# Works around EXDEV (cross-device rename) errors on btrfs subvolumes,
|
|
4
|
+
# separate /tmp partitions, and other cross-device setups.
|
|
5
|
+
#
|
|
6
|
+
# Usage: curl -fsSL <raw-url> | bash
|
|
7
|
+
# or: ./scripts/install.sh
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
echo "Laminark Marketplace Installer"
|
|
12
|
+
echo "==============================="
|
|
13
|
+
echo ""
|
|
14
|
+
|
|
15
|
+
# Check if claude CLI is available
|
|
16
|
+
if ! command -v claude &> /dev/null; then
|
|
17
|
+
echo "Error: claude CLI not found"
|
|
18
|
+
echo "Please install Claude Code first: https://claude.com/claude-code"
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Check if already installed
|
|
23
|
+
if claude plugin list 2>/dev/null | grep -q "laminark"; then
|
|
24
|
+
CURRENT_VERSION=$(claude plugin list 2>/dev/null | grep "laminark" | awk '{print $2}' || echo "unknown")
|
|
25
|
+
echo "Currently installed: v$CURRENT_VERSION"
|
|
26
|
+
echo ""
|
|
27
|
+
read -p "Update/reinstall? (Y/n): " -n 1 -r
|
|
28
|
+
echo ""
|
|
29
|
+
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
|
30
|
+
echo "Installation cancelled."
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
echo "Removing existing installation..."
|
|
34
|
+
claude plugin remove laminark 2>/dev/null || true
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Set up TMPDIR to avoid EXDEV errors
|
|
38
|
+
CLAUDE_DIR="${CLAUDE_HOME:-$HOME/.claude}"
|
|
39
|
+
SAFE_TMP="$CLAUDE_DIR/tmp"
|
|
40
|
+
|
|
41
|
+
echo ""
|
|
42
|
+
echo "Installing Laminark from marketplace..."
|
|
43
|
+
mkdir -p "$SAFE_TMP"
|
|
44
|
+
TMPDIR="$SAFE_TMP" claude plugin install laminark
|
|
45
|
+
STATUS=$?
|
|
46
|
+
rm -rf "$SAFE_TMP"
|
|
47
|
+
|
|
48
|
+
if [ $STATUS -eq 0 ]; then
|
|
49
|
+
NEW_VERSION=$(claude plugin list 2>/dev/null | grep "laminark" | awk '{print $2}' || echo "unknown")
|
|
50
|
+
echo ""
|
|
51
|
+
echo "✓ Laminark installed successfully! (v$NEW_VERSION)"
|
|
52
|
+
echo ""
|
|
53
|
+
echo "Next steps:"
|
|
54
|
+
echo " 1. Enable the plugin: claude plugin enable laminark"
|
|
55
|
+
echo " 2. Start a new Claude Code session"
|
|
56
|
+
echo " 3. Verify with: /mcp (should show laminark tools)"
|
|
57
|
+
else
|
|
58
|
+
echo ""
|
|
59
|
+
echo "✗ Installation failed with exit code $STATUS"
|
|
60
|
+
exit $STATUS
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
exit 0
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Local installation wrapper for Laminark plugin.
|
|
3
|
+
# Works around EXDEV (cross-device rename) errors on btrfs subvolumes,
|
|
4
|
+
# separate /tmp partitions, and other cross-device setups.
|
|
5
|
+
#
|
|
6
|
+
# Usage: ./scripts/local-install.sh [path-to-laminark]
|
|
7
|
+
# Default path: current directory (.)
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
# Parse path argument (default to current directory)
|
|
12
|
+
PLUGIN_PATH="${1:-.}"
|
|
13
|
+
|
|
14
|
+
# Resolve to absolute path
|
|
15
|
+
if [[ "$PLUGIN_PATH" != /* ]]; then
|
|
16
|
+
PLUGIN_PATH="$(cd "$PLUGIN_PATH" && pwd)"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
echo "Laminark Local Installer"
|
|
20
|
+
echo "========================"
|
|
21
|
+
echo ""
|
|
22
|
+
echo "Installing from: $PLUGIN_PATH"
|
|
23
|
+
|
|
24
|
+
# Validate prerequisites
|
|
25
|
+
if [ ! -d "$PLUGIN_PATH/dist" ]; then
|
|
26
|
+
echo "Error: dist/ directory not found in $PLUGIN_PATH"
|
|
27
|
+
echo "Please run 'npm install && npm run build' first"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
if ! command -v claude &> /dev/null; then
|
|
32
|
+
echo "Error: claude CLI not found"
|
|
33
|
+
echo "Please install Claude Code first: https://claude.com/claude-code"
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Get version from package.json
|
|
38
|
+
if [ -f "$PLUGIN_PATH/package.json" ]; then
|
|
39
|
+
NEW_VERSION=$(grep '"version"' "$PLUGIN_PATH/package.json" | head -1 | sed -E 's/.*"version": "([^"]+)".*/\1/')
|
|
40
|
+
echo "Version to install: v$NEW_VERSION"
|
|
41
|
+
else
|
|
42
|
+
NEW_VERSION="unknown"
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Check if already installed
|
|
46
|
+
if claude plugin list 2>/dev/null | grep -q "laminark"; then
|
|
47
|
+
CURRENT_VERSION=$(claude plugin list 2>/dev/null | grep "laminark" | awk '{print $2}' || echo "unknown")
|
|
48
|
+
echo "Currently installed: v$CURRENT_VERSION"
|
|
49
|
+
echo ""
|
|
50
|
+
|
|
51
|
+
if [ "$CURRENT_VERSION" = "$NEW_VERSION" ]; then
|
|
52
|
+
echo "Same version is already installed."
|
|
53
|
+
read -p "Reinstall anyway? (y/N): " -n 1 -r
|
|
54
|
+
echo ""
|
|
55
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
56
|
+
echo "Installation cancelled."
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
else
|
|
60
|
+
echo "An existing version is installed."
|
|
61
|
+
read -p "Update from v$CURRENT_VERSION to v$NEW_VERSION? (Y/n): " -n 1 -r
|
|
62
|
+
echo ""
|
|
63
|
+
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
|
64
|
+
echo "Installation cancelled."
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
echo "Removing existing installation..."
|
|
70
|
+
TMPDIR="$SAFE_TMP" claude plugin remove laminark 2>/dev/null || true
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Set up safe temp directory on same filesystem as ~/.claude/
|
|
74
|
+
CLAUDE_DIR="${CLAUDE_HOME:-$HOME/.claude}"
|
|
75
|
+
SAFE_TMP="$CLAUDE_DIR/tmp"
|
|
76
|
+
|
|
77
|
+
echo ""
|
|
78
|
+
echo "Creating temporary directory: $SAFE_TMP"
|
|
79
|
+
mkdir -p "$SAFE_TMP"
|
|
80
|
+
|
|
81
|
+
# Run claude plugin add with TMPDIR override
|
|
82
|
+
echo "Running: claude plugin add $PLUGIN_PATH"
|
|
83
|
+
TMPDIR="$SAFE_TMP" claude plugin add "$PLUGIN_PATH"
|
|
84
|
+
STATUS=$?
|
|
85
|
+
|
|
86
|
+
# Clean up
|
|
87
|
+
rm -rf "$SAFE_TMP"
|
|
88
|
+
|
|
89
|
+
if [ $STATUS -eq 0 ]; then
|
|
90
|
+
echo ""
|
|
91
|
+
echo "✓ Laminark plugin installed successfully!"
|
|
92
|
+
echo ""
|
|
93
|
+
echo "Next steps:"
|
|
94
|
+
echo " 1. Enable the plugin: claude plugin enable laminark"
|
|
95
|
+
echo " 2. Start a new Claude Code session"
|
|
96
|
+
echo " 3. Verify with: /mcp (should show laminark tools)"
|
|
97
|
+
else
|
|
98
|
+
echo ""
|
|
99
|
+
echo "✗ Installation failed with exit code $STATUS"
|
|
100
|
+
exit $STATUS
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
exit 0
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Set up TMPDIR globally to avoid EXDEV errors in Claude Code
|
|
3
|
+
# This allows the Claude UI plugin installation to work correctly
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "Claude Code TMPDIR Setup"
|
|
8
|
+
echo "========================"
|
|
9
|
+
echo ""
|
|
10
|
+
echo "This script will configure your shell to use ~/.claude/tmp as TMPDIR,"
|
|
11
|
+
echo "which prevents EXDEV errors when installing plugins via Claude's UI."
|
|
12
|
+
echo ""
|
|
13
|
+
|
|
14
|
+
# Create the temp directory
|
|
15
|
+
CLAUDE_DIR="${CLAUDE_HOME:-$HOME/.claude}"
|
|
16
|
+
TMPDIR_PATH="$CLAUDE_DIR/tmp"
|
|
17
|
+
|
|
18
|
+
mkdir -p "$TMPDIR_PATH"
|
|
19
|
+
echo "✓ Created directory: $TMPDIR_PATH"
|
|
20
|
+
|
|
21
|
+
# Detect shell
|
|
22
|
+
SHELL_NAME=$(basename "$SHELL")
|
|
23
|
+
if [ "$SHELL_NAME" = "zsh" ]; then
|
|
24
|
+
PROFILE="$HOME/.zshrc"
|
|
25
|
+
elif [ "$SHELL_NAME" = "bash" ]; then
|
|
26
|
+
PROFILE="$HOME/.bashrc"
|
|
27
|
+
else
|
|
28
|
+
echo "Warning: Unsupported shell: $SHELL_NAME"
|
|
29
|
+
echo "Please manually add this to your shell profile:"
|
|
30
|
+
echo ""
|
|
31
|
+
echo " export TMPDIR=\$HOME/.claude/tmp"
|
|
32
|
+
echo " mkdir -p \$TMPDIR"
|
|
33
|
+
echo ""
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Check if already configured
|
|
38
|
+
if grep -q "export TMPDIR.*\.claude/tmp" "$PROFILE" 2>/dev/null; then
|
|
39
|
+
echo ""
|
|
40
|
+
echo "✓ TMPDIR already configured in $PROFILE"
|
|
41
|
+
else
|
|
42
|
+
echo ""
|
|
43
|
+
echo "Adding TMPDIR configuration to $PROFILE..."
|
|
44
|
+
cat >> "$PROFILE" << 'EOF'
|
|
45
|
+
|
|
46
|
+
# Claude Code TMPDIR workaround for EXDEV errors
|
|
47
|
+
export TMPDIR=$HOME/.claude/tmp
|
|
48
|
+
mkdir -p $TMPDIR
|
|
49
|
+
EOF
|
|
50
|
+
echo "✓ Added TMPDIR configuration to $PROFILE"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
echo ""
|
|
54
|
+
echo "✓ Setup complete!"
|
|
55
|
+
echo ""
|
|
56
|
+
echo "Next steps:"
|
|
57
|
+
echo " 1. Restart your terminal (or run: source $PROFILE)"
|
|
58
|
+
echo " 2. Restart Claude Code"
|
|
59
|
+
echo " 3. Try installing Laminark via Claude's UI:"
|
|
60
|
+
echo " /plugin → marketplace → NoobyNull/Laminark → install"
|
|
61
|
+
echo ""
|
|
62
|
+
echo "To verify TMPDIR is set, run: echo \$TMPDIR"
|
|
63
|
+
echo "Expected output: $TMPDIR_PATH"
|
|
64
|
+
|
|
65
|
+
exit 0
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Uninstall Laminark plugin with optional data cleanup
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
echo "Laminark Uninstaller"
|
|
7
|
+
echo "===================="
|
|
8
|
+
echo ""
|
|
9
|
+
|
|
10
|
+
# Check if claude CLI is available
|
|
11
|
+
if ! command -v claude &> /dev/null; then
|
|
12
|
+
echo "Error: claude CLI not found"
|
|
13
|
+
echo "Please install Claude Code first: https://claude.com/claude-code"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Check if plugin is installed
|
|
18
|
+
if ! claude plugin list 2>/dev/null | grep -q "laminark"; then
|
|
19
|
+
echo "Laminark plugin is not installed."
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Get current version
|
|
24
|
+
CURRENT_VERSION=$(claude plugin list 2>/dev/null | grep "laminark" | awk '{print $2}' || echo "unknown")
|
|
25
|
+
echo "Currently installed: laminark v$CURRENT_VERSION"
|
|
26
|
+
echo ""
|
|
27
|
+
|
|
28
|
+
# Ask for confirmation
|
|
29
|
+
read -p "Are you sure you want to uninstall Laminark? (y/N): " -n 1 -r
|
|
30
|
+
echo ""
|
|
31
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
32
|
+
echo "Uninstall cancelled."
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Remove the plugin
|
|
37
|
+
echo "Removing plugin..."
|
|
38
|
+
claude plugin remove laminark
|
|
39
|
+
echo "✓ Plugin removed"
|
|
40
|
+
|
|
41
|
+
# Ask about data cleanup
|
|
42
|
+
echo ""
|
|
43
|
+
echo "Data cleanup options:"
|
|
44
|
+
echo " 1. Keep all data (can reinstall later without losing memories)"
|
|
45
|
+
echo " 2. Remove plugin cache only (keeps user data at ~/.laminark/)"
|
|
46
|
+
echo " 3. Remove everything (plugin cache + all memories and data)"
|
|
47
|
+
echo ""
|
|
48
|
+
read -p "Choose option (1-3, default=1): " -n 1 -r CLEANUP_OPTION
|
|
49
|
+
echo ""
|
|
50
|
+
|
|
51
|
+
case $CLEANUP_OPTION in
|
|
52
|
+
2)
|
|
53
|
+
echo "Removing plugin cache..."
|
|
54
|
+
CACHE_DIR="${CLAUDE_HOME:-$HOME/.claude}/plugins/cache/laminark"
|
|
55
|
+
if [ -d "$CACHE_DIR" ]; then
|
|
56
|
+
rm -rf "$CACHE_DIR"
|
|
57
|
+
echo "✓ Plugin cache removed: $CACHE_DIR"
|
|
58
|
+
else
|
|
59
|
+
echo " No cache directory found"
|
|
60
|
+
fi
|
|
61
|
+
;;
|
|
62
|
+
3)
|
|
63
|
+
echo "Removing all data..."
|
|
64
|
+
CACHE_DIR="${CLAUDE_HOME:-$HOME/.claude}/plugins/cache/laminark"
|
|
65
|
+
DATA_DIR="$HOME/.laminark"
|
|
66
|
+
|
|
67
|
+
if [ -d "$CACHE_DIR" ]; then
|
|
68
|
+
rm -rf "$CACHE_DIR"
|
|
69
|
+
echo "✓ Plugin cache removed: $CACHE_DIR"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
if [ -d "$DATA_DIR" ]; then
|
|
73
|
+
echo ""
|
|
74
|
+
echo "WARNING: This will delete all your memories and observations!"
|
|
75
|
+
read -p "Delete $DATA_DIR? (y/N): " -n 1 -r
|
|
76
|
+
echo ""
|
|
77
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
78
|
+
rm -rf "$DATA_DIR"
|
|
79
|
+
echo "✓ Data directory removed: $DATA_DIR"
|
|
80
|
+
else
|
|
81
|
+
echo " Kept data directory: $DATA_DIR"
|
|
82
|
+
fi
|
|
83
|
+
fi
|
|
84
|
+
;;
|
|
85
|
+
*)
|
|
86
|
+
echo "Keeping all data."
|
|
87
|
+
;;
|
|
88
|
+
esac
|
|
89
|
+
|
|
90
|
+
echo ""
|
|
91
|
+
echo "✓ Uninstall complete!"
|
|
92
|
+
echo ""
|
|
93
|
+
echo "To reinstall: ./scripts/local-install.sh or ./scripts/install.sh"
|
|
94
|
+
|
|
95
|
+
exit 0
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Update Laminark plugin to the latest version
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
echo "Laminark Update Checker"
|
|
7
|
+
echo "======================="
|
|
8
|
+
echo ""
|
|
9
|
+
|
|
10
|
+
# Check if claude CLI is available
|
|
11
|
+
if ! command -v claude &> /dev/null; then
|
|
12
|
+
echo "Error: claude CLI not found"
|
|
13
|
+
echo "Please install Claude Code first: https://claude.com/claude-code"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Check if plugin is installed
|
|
18
|
+
if ! claude plugin list 2>/dev/null | grep -q "laminark"; then
|
|
19
|
+
echo "Laminark is not installed."
|
|
20
|
+
echo "Run ./scripts/install.sh to install it."
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Get current version
|
|
25
|
+
CURRENT_VERSION=$(claude plugin list 2>/dev/null | grep "laminark" | awk '{print $2}' || echo "unknown")
|
|
26
|
+
echo "Currently installed: v$CURRENT_VERSION"
|
|
27
|
+
|
|
28
|
+
# Check for updates (try to get latest version from GitHub)
|
|
29
|
+
echo "Checking for updates..."
|
|
30
|
+
LATEST_VERSION=$(curl -fsSL https://api.github.com/repos/NoobyNull/Laminark/releases/latest 2>/dev/null | grep '"tag_name"' | sed -E 's/.*"v?([^"]+)".*/\1/' || echo "")
|
|
31
|
+
|
|
32
|
+
if [ -z "$LATEST_VERSION" ]; then
|
|
33
|
+
echo "Warning: Could not check for updates (GitHub API unavailable)"
|
|
34
|
+
echo ""
|
|
35
|
+
read -p "Force reinstall anyway? (y/N): " -n 1 -r
|
|
36
|
+
echo ""
|
|
37
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
38
|
+
echo "Update cancelled."
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
FORCE_UPDATE=true
|
|
42
|
+
else
|
|
43
|
+
echo "Latest available: v$LATEST_VERSION"
|
|
44
|
+
echo ""
|
|
45
|
+
|
|
46
|
+
# Compare versions
|
|
47
|
+
if [ "$CURRENT_VERSION" = "$LATEST_VERSION" ]; then
|
|
48
|
+
echo "You already have the latest version!"
|
|
49
|
+
echo ""
|
|
50
|
+
read -p "Reinstall anyway? (y/N): " -n 1 -r
|
|
51
|
+
echo ""
|
|
52
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
53
|
+
echo "Update cancelled."
|
|
54
|
+
exit 0
|
|
55
|
+
fi
|
|
56
|
+
fi
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Set up TMPDIR to avoid EXDEV errors
|
|
60
|
+
CLAUDE_DIR="${CLAUDE_HOME:-$HOME/.claude}"
|
|
61
|
+
SAFE_TMP="$CLAUDE_DIR/tmp"
|
|
62
|
+
mkdir -p "$SAFE_TMP"
|
|
63
|
+
|
|
64
|
+
# Reinstall the plugin
|
|
65
|
+
echo ""
|
|
66
|
+
echo "Updating Laminark..."
|
|
67
|
+
TMPDIR="$SAFE_TMP" claude plugin remove laminark 2>/dev/null || true
|
|
68
|
+
TMPDIR="$SAFE_TMP" claude plugin install laminark
|
|
69
|
+
STATUS=$?
|
|
70
|
+
|
|
71
|
+
# Clean up
|
|
72
|
+
rm -rf "$SAFE_TMP"
|
|
73
|
+
|
|
74
|
+
if [ $STATUS -eq 0 ]; then
|
|
75
|
+
NEW_VERSION=$(claude plugin list 2>/dev/null | grep "laminark" | awk '{print $2}' || echo "unknown")
|
|
76
|
+
echo ""
|
|
77
|
+
echo "✓ Laminark updated successfully!"
|
|
78
|
+
echo " Previous version: v$CURRENT_VERSION"
|
|
79
|
+
echo " Current version: v$NEW_VERSION"
|
|
80
|
+
echo ""
|
|
81
|
+
echo "Restart your Claude Code session for changes to take effect."
|
|
82
|
+
else
|
|
83
|
+
echo ""
|
|
84
|
+
echo "✗ Update failed with exit code $STATUS"
|
|
85
|
+
exit $STATUS
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
exit 0
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Verify Laminark plugin installation
|
|
3
|
+
# Checks: plugin registered, enabled status, provides next steps
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "Checking Laminark installation..."
|
|
8
|
+
echo ""
|
|
9
|
+
|
|
10
|
+
# Check if claude CLI is available
|
|
11
|
+
if ! command -v claude &> /dev/null; then
|
|
12
|
+
echo "✗ Error: claude CLI not found"
|
|
13
|
+
echo " Please install Claude Code first: https://claude.com/claude-code"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Check if plugin is registered
|
|
18
|
+
if claude plugin list 2>/dev/null | grep -q "laminark"; then
|
|
19
|
+
echo "✓ Plugin registered: laminark"
|
|
20
|
+
else
|
|
21
|
+
echo "✗ Plugin not registered"
|
|
22
|
+
echo " Please run: ./scripts/local-install.sh"
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Check if plugin is enabled
|
|
27
|
+
if claude plugin list 2>/dev/null | grep "laminark" | grep -q "enabled"; then
|
|
28
|
+
echo "✓ Plugin enabled"
|
|
29
|
+
else
|
|
30
|
+
echo "⚠ Plugin registered but not enabled"
|
|
31
|
+
echo " Run: claude plugin enable laminark"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
echo ""
|
|
35
|
+
echo "Installation verified successfully!"
|
|
36
|
+
echo ""
|
|
37
|
+
echo "Next steps:"
|
|
38
|
+
echo " 1. Start a new Claude Code session"
|
|
39
|
+
echo " 2. Check MCP tools with: /mcp"
|
|
40
|
+
echo " 3. Check hooks with: /hooks"
|
|
41
|
+
echo " 4. Try searching memories with: recall"
|
|
42
|
+
|
|
43
|
+
exit 0
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Laminark Activity Feed Module
|
|
3
|
+
*
|
|
4
|
+
* Listens to SSE-dispatched CustomEvents and renders a live activity feed.
|
|
5
|
+
* Max 100 items in memory, newest first. Supports clear and slide-in animation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
(function () {
|
|
9
|
+
var MAX_ITEMS = 100;
|
|
10
|
+
var items = [];
|
|
11
|
+
var feedEl = null;
|
|
12
|
+
|
|
13
|
+
var EVENT_CONFIG = {
|
|
14
|
+
'laminark:new_observation': {
|
|
15
|
+
icon: '\u{1F4DD}',
|
|
16
|
+
label: 'Observation',
|
|
17
|
+
cssClass: 'activity-observation',
|
|
18
|
+
format: function (d) {
|
|
19
|
+
return d.text || (d.id ? 'Observation ' + d.id.substring(0, 8) : 'New observation');
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
'laminark:entity_updated': {
|
|
23
|
+
icon: '\u{1F9E9}',
|
|
24
|
+
label: 'Entity',
|
|
25
|
+
cssClass: 'activity-entity',
|
|
26
|
+
format: function (d) {
|
|
27
|
+
return (d.label || d.name || d.id || 'Unknown') + (d.type ? ' (' + d.type + ')' : '');
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
'laminark:topic_shift': {
|
|
31
|
+
icon: '\u{1F500}',
|
|
32
|
+
label: 'Topic Shift',
|
|
33
|
+
cssClass: 'activity-topic-shift',
|
|
34
|
+
format: function (d) {
|
|
35
|
+
var msg = 'Topic shift detected';
|
|
36
|
+
if (d.confidence != null) msg += ' (' + (d.confidence * 100).toFixed(0) + '% confidence)';
|
|
37
|
+
return msg;
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
'laminark:session_start': {
|
|
41
|
+
icon: '\u{25B6}\uFE0F',
|
|
42
|
+
label: 'Session Start',
|
|
43
|
+
cssClass: 'activity-session-start',
|
|
44
|
+
format: function (d) {
|
|
45
|
+
return 'Session started' + (d.id ? ': ' + d.id.substring(0, 8) : '');
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
'laminark:session_end': {
|
|
49
|
+
icon: '\u{23F9}\uFE0F',
|
|
50
|
+
label: 'Session End',
|
|
51
|
+
cssClass: 'activity-session-end',
|
|
52
|
+
format: function (d) {
|
|
53
|
+
return 'Session ended' + (d.id ? ': ' + d.id.substring(0, 8) : '');
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
function relativeTime(isoString) {
|
|
59
|
+
if (!isoString) return 'just now';
|
|
60
|
+
try {
|
|
61
|
+
var diff = Date.now() - new Date(isoString).getTime();
|
|
62
|
+
if (diff < 0) diff = 0;
|
|
63
|
+
var secs = Math.floor(diff / 1000);
|
|
64
|
+
if (secs < 60) return secs + 's ago';
|
|
65
|
+
var mins = Math.floor(secs / 60);
|
|
66
|
+
if (mins < 60) return mins + 'm ago';
|
|
67
|
+
var hrs = Math.floor(mins / 60);
|
|
68
|
+
if (hrs < 24) return hrs + 'h ago';
|
|
69
|
+
return Math.floor(hrs / 24) + 'd ago';
|
|
70
|
+
} catch (_e) {
|
|
71
|
+
return 'just now';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function createItemEl(item) {
|
|
76
|
+
var el = document.createElement('div');
|
|
77
|
+
el.className = 'activity-item ' + item.cssClass + ' activity-slide-in';
|
|
78
|
+
|
|
79
|
+
var iconSpan = document.createElement('span');
|
|
80
|
+
iconSpan.className = 'activity-icon';
|
|
81
|
+
iconSpan.textContent = item.icon;
|
|
82
|
+
el.appendChild(iconSpan);
|
|
83
|
+
|
|
84
|
+
var body = document.createElement('div');
|
|
85
|
+
body.className = 'activity-body';
|
|
86
|
+
|
|
87
|
+
var title = document.createElement('div');
|
|
88
|
+
title.className = 'activity-title';
|
|
89
|
+
title.textContent = item.label;
|
|
90
|
+
body.appendChild(title);
|
|
91
|
+
|
|
92
|
+
var desc = document.createElement('div');
|
|
93
|
+
desc.className = 'activity-desc';
|
|
94
|
+
desc.textContent = item.description;
|
|
95
|
+
body.appendChild(desc);
|
|
96
|
+
|
|
97
|
+
el.appendChild(body);
|
|
98
|
+
|
|
99
|
+
var time = document.createElement('span');
|
|
100
|
+
time.className = 'activity-time';
|
|
101
|
+
time.textContent = relativeTime(item.timestamp);
|
|
102
|
+
el.appendChild(time);
|
|
103
|
+
|
|
104
|
+
return el;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function renderFeed() {
|
|
108
|
+
if (!feedEl) return;
|
|
109
|
+
|
|
110
|
+
if (items.length === 0) {
|
|
111
|
+
feedEl.innerHTML = '<p class="empty-state">Waiting for live events...</p>';
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
feedEl.innerHTML = '';
|
|
116
|
+
items.forEach(function (item) {
|
|
117
|
+
feedEl.appendChild(createItemEl(item));
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function addItem(eventName, detail) {
|
|
122
|
+
var config = EVENT_CONFIG[eventName];
|
|
123
|
+
if (!config) return;
|
|
124
|
+
|
|
125
|
+
var item = {
|
|
126
|
+
icon: config.icon,
|
|
127
|
+
label: config.label,
|
|
128
|
+
cssClass: config.cssClass,
|
|
129
|
+
description: config.format(detail || {}),
|
|
130
|
+
timestamp: detail.createdAt || detail.timestamp || new Date().toISOString(),
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
items.unshift(item);
|
|
134
|
+
if (items.length > MAX_ITEMS) {
|
|
135
|
+
items = items.slice(0, MAX_ITEMS);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// If feed is visible, prepend DOM element directly for performance
|
|
139
|
+
if (feedEl) {
|
|
140
|
+
// Remove empty state if present
|
|
141
|
+
var empty = feedEl.querySelector('.empty-state');
|
|
142
|
+
if (empty) empty.remove();
|
|
143
|
+
|
|
144
|
+
var el = createItemEl(item);
|
|
145
|
+
if (feedEl.firstChild) {
|
|
146
|
+
feedEl.insertBefore(el, feedEl.firstChild);
|
|
147
|
+
} else {
|
|
148
|
+
feedEl.appendChild(el);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Trim excess DOM nodes
|
|
152
|
+
while (feedEl.children.length > MAX_ITEMS) {
|
|
153
|
+
feedEl.removeChild(feedEl.lastChild);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function clearFeed() {
|
|
159
|
+
items = [];
|
|
160
|
+
renderFeed();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function initActivityFeed() {
|
|
164
|
+
feedEl = document.getElementById('activity-feed');
|
|
165
|
+
|
|
166
|
+
var clearBtn = document.getElementById('activity-clear-btn');
|
|
167
|
+
if (clearBtn) {
|
|
168
|
+
clearBtn.addEventListener('click', clearFeed);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Listen to all SSE event types
|
|
172
|
+
Object.keys(EVENT_CONFIG).forEach(function (eventName) {
|
|
173
|
+
document.addEventListener(eventName, function (e) {
|
|
174
|
+
addItem(eventName, e.detail || {});
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
renderFeed();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
window.laminarkActivity = {
|
|
182
|
+
initActivityFeed: initActivityFeed,
|
|
183
|
+
clearFeed: clearFeed,
|
|
184
|
+
};
|
|
185
|
+
})();
|