fix(plugins): make the 10 focused plugins installable, finish the AgentHub rename

The ten `agenthub-*` plugins were listed by the marketplace but could never be
installed — two schema mistakes present since the entries were first authored
(57dc915), both invisible until you actually run `claude plugin install`:

- marketplace entries used `"path": "plugins/<name>"`; the CLI only accepts
  `"source"`, so every one failed with
  `This plugin's marketplace entry is invalid: source: Invalid input`
- each `plugin.json` carried npm's `"repository": { "type", "url" }` object;
  the schema wants a plain string, so the next attempt failed with
  `Validation errors: repository: Invalid input`

Verified by installing all 11 entries into a throwaway CLAUDE_CONFIG_DIR:
1/11 before, 11/11 after. `plugins-marketplace.test.js` was asserting the
broken shape, which is why CI stayed green — it now asserts `source` and
rejects `path`.

Marketplace renamed `claude-code-agent-monitor-plugins` -> `agenthub`, so the
install line is `agenthub@agenthub`. ARCHITECTURE.md documented a marketplace
name (`smartgift-claude-code-monitor`) that never existed in any revision.

The documented `/plugin marketplace add Smartgift-AI/Claude-Code-Monitor` also
never worked: the `owner/repo` shorthand resolves to github.com only, and this
repo is self-hosted on Gitea. Confirmed the CLI rejects `host/owner/repo` and
ignores GH_HOST / GITHUB_HOST / CLAUDE_CODE_MARKETPLACE_URL, so the full
https:// clone URL is the only supported form. Same GitHub-habit class fixed
elsewhere: raw.githubusercontent.com icon URLs (404, and the repo ships
favicon.svg not favicon.ico — the client had the same dead /favicon.ico),
a smartgift.github.io docs link (404), and Gitea `/blob/<ref>/` paths that
must be `/src/branch/<ref>/`.

Repository renamed to Smartgift-AI/AgentHub throughout. Gitea 301-redirects
the old name, so these were stale rather than broken; `docs/superpowers/`
keeps the old name because those are dated decision records.

Adds `repo-links.test.js` to guard both classes (it runs under the existing
pre-commit gate) plus an openapi.yaml drift check — the committed spec had
silently fallen a minor version behind package.json. `generate-openapi-yaml.js`
now exports `render()` so the test compares against one definition of the dump
options instead of a second copy.
This commit is contained in:
2026-09-10 11:03:14 +07:00
parent 876c6de6d2
commit e972267a42
40 changed files with 290 additions and 170 deletions
+13 -13
View File
@@ -1,12 +1,12 @@
{
"name": "claude-code-agent-monitor-plugins",
"name": "agenthub",
"description": "Official plugin marketplace for AgentHub — the `agenthub` plugin installs the dashboard itself (hooks, server, CLI), plus 10 focused plugins for analytics, cost guardrails, productivity, developer tools, AI insights, session forensics, workflow/fleet intelligence, reliability/SLOs, config & memory governance, and dashboard connectivity. Every plugin is powered by the local Agent Monitor API.",
"owner": {
"name": "smartgift",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"plugins": [
{
"name": "agenthub",
@@ -16,61 +16,61 @@
},
{
"name": "agenthub-analytics",
"path": "plugins/agenthub-analytics",
"source": "./plugins/agenthub-analytics",
"description": "Deep analytics on Claude Code sessions — token usage (total_input/total_output/total_cache_read/total_cache_write with compaction baselines pre-summed), cost breakdowns via the pricing engine, usage trends over 365 days, cache efficiency, model mix, and productivity scoring.",
"tags": ["analytics", "tokens", "cost", "productivity"]
},
{
"name": "agenthub-cost-guard",
"path": "plugins/agenthub-cost-guard",
"source": "./plugins/agenthub-cost-guard",
"description": "Budget guardrails — set spend limits, forecast week/month-end cost from daily trends, surface cost-threshold alerts via the alert-rule API, and quantify model-routing savings.",
"tags": ["budget", "cost", "forecast", "alerts"]
},
{
"name": "agenthub-productivity",
"path": "plugins/agenthub-productivity",
"source": "./plugins/agenthub-productivity",
"description": "Productivity automation — daily standups, weekly/monthly reviews, sprint summaries, time-of-day focus analysis, and workflow optimization using the workflow intelligence API's 11 datasets.",
"tags": ["productivity", "reports", "workflows", "standup"]
},
{
"name": "agenthub-devtools",
"path": "plugins/agenthub-devtools",
"source": "./plugins/agenthub-devtools",
"description": "Developer tools for the Agent Monitor — session debugging with full event-chain inspection, data-integrity inspection, event tracing, transcript search, hook diagnostics, data export (JSON/CSV/Markdown), and system health checks.",
"tags": ["devtools", "debug", "diagnostics", "export"]
},
{
"name": "agenthub-insights",
"path": "plugins/agenthub-insights",
"source": "./plugins/agenthub-insights",
"description": "AI-powered insights — pattern detection via workflow intelligence (tool flow transitions, agent co-occurrence), anomaly alerting, trend forecasting, regression watch, benchmarking, optimization recommendations, and session comparison.",
"tags": ["insights", "patterns", "anomaly", "optimization"]
},
{
"name": "agenthub-sessions",
"path": "plugins/agenthub-sessions",
"source": "./plugins/agenthub-sessions",
"description": "Session forensics — search by project/model/status, reconstruct event timelines, replay transcripts turn-by-turn, roll up activity per working directory, and review stale sessions before cleanup.",
"tags": ["sessions", "search", "transcript", "replay"]
},
{
"name": "agenthub-workflows",
"path": "plugins/agenthub-workflows",
"source": "./plugins/agenthub-workflows",
"description": "Multi-agent orchestration & fleet intelligence — map the subagent DAG, audit model delegation and effectiveness, report concurrency lanes, trace error propagation by depth, and review Workflow-tool fleet runs.",
"tags": ["workflows", "orchestration", "subagents", "fleet"]
},
{
"name": "agenthub-quality",
"path": "plugins/agenthub-quality",
"source": "./plugins/agenthub-quality",
"description": "Reliability & SLOs — scan for API errors and tool failures, audit hook delivery health (PreToolUse/PostToolUse balance), track completion/error-rate SLOs with error budgets, and alert on reliability regressions.",
"tags": ["reliability", "errors", "slo", "quality"]
},
{
"name": "agenthub-config",
"path": "plugins/agenthub-config",
"source": "./plugins/agenthub-config",
"description": "Claude Code config & memory governance — audit skills/subagents/commands/MCP servers/hooks/settings via the Config Explorer API and curate the file-based memory store (CLAUDE.md + per-project auto-memory files).",
"tags": ["config", "memory", "governance", "mcp"]
},
{
"name": "agenthub-dashboard",
"path": "plugins/agenthub-dashboard",
"source": "./plugins/agenthub-dashboard",
"description": "Dashboard connector — quick status checks, one-line metrics, live activity watch, and endpoint probing against the Agent Monitor API.",
"tags": ["dashboard", "status", "connector"]
}
+2 -2
View File
@@ -5,8 +5,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git",
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": ["dashboard", "monitoring", "sessions", "cost", "lanes", "claude-code"],
"commands": [
+3 -3
View File
@@ -1779,7 +1779,7 @@ Skills are namespaced: `/agenthub-analytics:session-report`, `/agenthub-producti
| **agenthub-config** | `config-audit`, `memory-review`, `skill-inventory`, `mcp-audit`, `hook-inventory` | `config-auditor` | — | — |
| **agenthub-dashboard** | `dashboard-status`, `quick-stats` | — | — | — |
**Totals**: 10 plugins, 53 skills, 14 agents, 30 slash commands, 3 CLI tools, 3 hook configurations. Each plugin is installable via `claude plugin install <name>@smartgift-claude-code-monitor`, and a server test (`server/__tests__/plugins-marketplace.test.js`) validates the marketplace↔directory bijection plus every `plugin.json`, agent, skill, and command.
**Totals**: 10 plugins, 53 skills, 14 agents, 30 slash commands, 3 CLI tools, 3 hook configurations. Each plugin is installable via `claude plugin install <name>@agenthub`, and a server test (`server/__tests__/plugins-marketplace.test.js`) validates the marketplace↔directory bijection plus every `plugin.json`, agent, skill, and command.
### Data Model Grounding
@@ -1808,8 +1808,8 @@ Plugins compute these from raw API data:
```bash
# Marketplace install
claude plugin marketplace add Smartgift-AI/Claude-Code-Monitor
claude plugin install agenthub-analytics@smartgift-claude-code-monitor
claude plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
claude plugin install agenthub-analytics@agenthub
# Local development testing
claude --plugin-dir plugins/agenthub-analytics
+4 -4
View File
@@ -7,8 +7,8 @@ A step-by-step guide to get AgentHub — the local control surface for Claude Co
If all you want is a working dashboard, skip every step below. From Claude Code:
```
/plugin marketplace add Smartgift-AI/Claude-Code-Monitor
/plugin install agenthub@claude-code-agent-monitor-plugins
/plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
/plugin install agenthub@agenthub
```
The next session start installs the hooks, boots the server, puts the `agenthub` CLI
@@ -39,8 +39,8 @@ dashboard, run it from source, or stay on Node 20.
## Step 1 — Clone the repository
```bash
git clone https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git
cd Claude-Code-Monitor
git clone https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
cd AgentHub
```
---
+2 -2
View File
@@ -68,8 +68,8 @@ Two commands on a machine that has nothing but Claude Code, no clone and no
`npm run setup`:
```
/plugin marketplace add Smartgift-AI/Claude-Code-Monitor
/plugin install agenthub@claude-code-agent-monitor-plugins
/plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
/plugin install agenthub@agenthub
```
The first session start installs the hooks, boots the server, puts `agenthub` on
+2 -2
View File
@@ -41,8 +41,8 @@ Hai lệnh, trên máy chỉ có Claude Code, không cần clone repo, không c
`npm run setup`:
```
/plugin marketplace add Smartgift-AI/Claude-Code-Monitor
/plugin install agenthub@claude-code-agent-monitor-plugins
/plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
/plugin install agenthub@agenthub
```
Lần session-start đầu tiên sẽ cài hooks, boot server, đưa `agenthub` vào PATH và
+1 -1
View File
@@ -61,7 +61,7 @@
"name": "SmartGift",
"url": "https://smartgift.vn"
},
"codeRepository": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"codeRepository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"featureList": "Real-time dashboard, Kanban board, Session tracking, Activity feed, Token usage analytics, Cost tracking, Browser notifications, WebSocket live updates, CLI statusline"
}
</script>
+2 -2
View File
@@ -123,9 +123,9 @@ async function notify(title: string, body: string) {
try {
if ("serviceWorker" in navigator) {
const registration = await navigator.serviceWorker.ready;
await registration.showNotification(title, { body, icon: "/favicon.ico", silent: false });
await registration.showNotification(title, { body, icon: "/favicon.svg", silent: false });
} else {
new Notification(title, { body, icon: "/favicon.ico" });
new Notification(title, { body, icon: "/favicon.svg" });
}
} catch {
// Silently ignore
@@ -127,9 +127,7 @@ describe("agentOriginLabel - parent chain walk", () => {
describe("projectFromCwd - session-cwd fallback for the dir prefix", () => {
it("returns the last path segment of a POSIX cwd", () => {
expect(projectFromCwd("/Users/dev/WebstormProjects/Claude-Code-Agent-Monitor")).toBe(
"Claude-Code-Agent-Monitor"
);
expect(projectFromCwd("/Users/dev/WebstormProjects/AgentHub")).toBe("AgentHub");
});
it("ignores a trailing slash", () => {
+1 -1
View File
@@ -1235,7 +1235,7 @@ export interface UpdateStatusPayload {
* Drives whether the "Update available" call-to-action is shown. */
update_available: boolean;
/** Absolute path to the detected git repository root. Example:
* `"/Users/dev/Claude-Code-Agent-Monitor"`. */
* `"/Users/dev/AgentHub"`. */
repo_root?: string;
/** Resolved ref compared against, e.g. "upstream/master" or "origin/main";
* null when no remote could be resolved (e.g. no remotes configured). */
+2 -2
View File
@@ -53,8 +53,8 @@ flowchart LR
`npm run setup` ends with a fail-soft `npm link` (the `link-cli` script), so after a normal local setup `agenthub` is on your PATH from any directory:
```bash
git clone https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git
cd Claude-Code-Agent-Monitor
git clone https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
cd AgentHub
npm run setup # installs deps AND links agenthub globally
agenthub help
```
+23 -16
View File
@@ -9,13 +9,13 @@ Every plugin is powered by the local Agent Monitor REST API at `http://localhost
### Add the marketplace
```bash
claude plugin marketplace add Smartgift-AI/Claude-Code-Monitor
claude plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
```
### Install the dashboard itself
```bash
claude plugin install agenthub@claude-code-agent-monitor-plugins
claude plugin install agenthub@agenthub
```
That is the whole install: no clone, no `npm run setup`, no `npm run install-hooks`, no manual `npm start`. See [The `agenthub` plugin](#the-agenthub-plugin) below for what it does on first session start.
@@ -39,16 +39,16 @@ marketplace name, not per source).
### Install a focused plugin
```bash
claude plugin install agenthub-analytics@claude-code-agent-monitor-plugins
claude plugin install agenthub-cost-guard@claude-code-agent-monitor-plugins
claude plugin install agenthub-productivity@claude-code-agent-monitor-plugins
claude plugin install agenthub-devtools@claude-code-agent-monitor-plugins
claude plugin install agenthub-insights@claude-code-agent-monitor-plugins
claude plugin install agenthub-sessions@claude-code-agent-monitor-plugins
claude plugin install agenthub-workflows@claude-code-agent-monitor-plugins
claude plugin install agenthub-quality@claude-code-agent-monitor-plugins
claude plugin install agenthub-config@claude-code-agent-monitor-plugins
claude plugin install agenthub-dashboard@claude-code-agent-monitor-plugins
claude plugin install agenthub-analytics@agenthub
claude plugin install agenthub-cost-guard@agenthub
claude plugin install agenthub-productivity@agenthub
claude plugin install agenthub-devtools@agenthub
claude plugin install agenthub-insights@agenthub
claude plugin install agenthub-sessions@agenthub
claude plugin install agenthub-workflows@agenthub
claude plugin install agenthub-quality@agenthub
claude plugin install agenthub-config@agenthub
claude plugin install agenthub-dashboard@agenthub
```
### Or install locally during development
@@ -250,7 +250,7 @@ single port.
### Uninstalling
`claude plugin uninstall agenthub@claude-code-agent-monitor-plugins` only removes
`claude plugin uninstall agenthub@agenthub` only removes
the plugin from the enabled list — verified against a real install/uninstall,
not assumed. It does **not**:
@@ -545,6 +545,13 @@ my-plugin/
Structure is validated by `server/__tests__/plugins-marketplace.test.js`, which enforces the marketplace↔directory bijection, `plugin.json` shape, name/dir agreement, and required frontmatter on every agent / skill / command.
Two of those shape rules exist because getting them wrong makes a plugin **listed but uninstallable**, with no other symptom — the marketplace loads fine and only `claude plugin install` fails:
- A subdirectory entry declares **`"source": "./plugins/<name>"`**, never `"path"`. `path` is not a source key the CLI accepts (`This plugin's marketplace entry is invalid: source: Invalid input`).
- A `plugin.json`'s **`repository` is a string**, not npm's `{ "type", "url" }` object (`Validation errors: repository: Invalid input`).
`server/__tests__/repo-links.test.js` guards the link side: no GitHub `owner/repo` marketplace shorthand (it resolves to github.com only — this repo is on Gitea, so the shorthand cannot work and no `GH_HOST`-style env var redirects it), no `raw.githubusercontent.com` / `*.github.io` / GitHub `/blob/<branch>/` URLs, no retired repository name, and no stale committed `openapi.yaml`.
### Testing locally
```bash
@@ -555,20 +562,20 @@ claude --plugin-dir /path/to/my-plugin # then use /my-plugin:my-skill some arg
### Dashboard not reachable
```bash
cd /path/to/Claude-Code-Agent-Monitor
cd /path/to/AgentHub
npm start # or: npm run dev
```
### Hooks not installed
```bash
cd /path/to/Claude-Code-Agent-Monitor
cd /path/to/AgentHub
npm run setup
```
### Plugin not found
```bash
claude plugin marketplace list
claude plugin marketplace add Smartgift-AI/Claude-Code-Monitor
claude plugin marketplace add https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
```
## License
+1 -1
View File
@@ -1,7 +1,7 @@
{
"id": "claude-code-agent-monitor-landing",
"name": "AgentHub",
"short_name": "CC Monitor",
"short_name": "AgentHub",
"description": "Local-first monitoring dashboard for Claude Code sessions.",
"author": "Nguyễn Ngọc Trí Vĩ",
"start_url": ".",
+20 -20
View File
@@ -3,15 +3,15 @@
openapi: 3.0.3
info:
title: Agent Dashboard for Claude Code API
version: 1.4.6
version: 1.5.0
description: HTTP API for real-time Claude Code session monitoring, agent lifecycle tracking, analytics, pricing, hooks ingestion, and workflow intelligence.
contact:
name: Nguyễn Ngọc Trí Vĩ
email: vinnt@smartgift.vn
url: https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor
url: https://git.smartgift.io.vn/Smartgift-AI/AgentHub
externalDocs:
description: Project documentation
url: https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor#readme
url: https://git.smartgift.io.vn/Smartgift-AI/AgentHub#readme
servers:
- url: http://localhost:4820
description: Local dashboard server (default)
@@ -363,7 +363,7 @@ components:
version:
type: string
description: Dashboard release version from package.json
example: 1.4.6
example: 1.5.0
timestamp:
type: string
format: date-time
@@ -4051,7 +4051,7 @@ components:
items:
type: string
example:
- /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
- /Users/dev/AgentHub
- /Users/son/code/another-project
sources:
type: array
@@ -4540,7 +4540,7 @@ paths:
- id: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d
name: Refactor pricing route + add cost endpoint
status: active
cwd: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
cwd: /Users/dev/AgentHub
model: claude-opus-4-20250514
started_at: '2026-06-25T14:02:11.004Z'
ended_at: null
@@ -4554,7 +4554,7 @@ paths:
- id: 1a2b3c4d-5e6f-4071-8293-a4b5c6d7e8f9
name: Fix flaky transcript pagination test
status: completed
cwd: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
cwd: /Users/dev/AgentHub
model: claude-sonnet-4-20250514
started_at: '2026-06-24T09:12:00.000Z'
ended_at: '2026-06-24T09:48:32.501Z'
@@ -4583,7 +4583,7 @@ paths:
example:
id: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d
name: Refactor pricing route + add cost endpoint
cwd: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
cwd: /Users/dev/AgentHub
model: claude-opus-4-20250514
metadata:
source: hook
@@ -4600,7 +4600,7 @@ paths:
id: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d
name: Refactor pricing route + add cost endpoint
status: active
cwd: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
cwd: /Users/dev/AgentHub
model: claude-opus-4-20250514
started_at: '2026-06-25T14:02:11.004Z'
ended_at: null
@@ -4623,7 +4623,7 @@ paths:
id: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d
name: Refactor pricing route + add cost endpoint
status: active
cwd: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
cwd: /Users/dev/AgentHub
model: claude-opus-4-20250514
started_at: '2026-06-25T14:02:11.004Z'
ended_at: null
@@ -4667,7 +4667,7 @@ paths:
id: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d
name: Refactor pricing route + add cost endpoint
status: active
cwd: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
cwd: /Users/dev/AgentHub
model: claude-opus-4-20250514
started_at: '2026-06-25T14:02:11.004Z'
ended_at: null
@@ -4762,7 +4762,7 @@ paths:
id: b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d
name: Refactor pricing route + add cost endpoint
status: completed
cwd: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
cwd: /Users/dev/AgentHub
model: claude-opus-4-20250514
started_at: '2026-06-25T14:02:11.004Z'
ended_at: '2026-06-25T15:07:44.220Z'
@@ -6119,7 +6119,7 @@ paths:
$ref: '#/components/schemas/SettingsInfoResponse'
example:
db:
path: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor/server/data/agent-monitor.db
path: /Users/dev/AgentHub/server/data/agent-monitor.db
size: 48922624
counts:
sessions: 412
@@ -6697,7 +6697,7 @@ paths:
summary: Behind origin — update available
value:
git_repo: true
repo_root: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
repo_root: /Users/dev/AgentHub
update_available: true
commits_behind: 4
remote_ref: origin/master
@@ -6709,7 +6709,7 @@ paths:
summary: Up to date with origin
value:
git_repo: true
repo_root: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
repo_root: /Users/dev/AgentHub
update_available: false
commits_behind: 0
remote_ref: origin/master
@@ -6754,7 +6754,7 @@ paths:
summary: Behind origin — update available
value:
git_repo: true
repo_root: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
repo_root: /Users/dev/AgentHub
update_available: true
commits_behind: 4
remote_ref: origin/master
@@ -6766,7 +6766,7 @@ paths:
summary: Up to date with origin
value:
git_repo: true
repo_root: /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
repo_root: /Users/dev/AgentHub
update_available: false
commits_behind: 0
remote_ref: origin/master
@@ -10114,7 +10114,7 @@ paths:
example:
items:
- kind: dashboard
path: /Users/dev/Claude-Code-Agent-Monitor
path: /Users/dev/AgentHub
label: Dashboard server
- kind: home
path: /Users/dev
@@ -10965,7 +10965,7 @@ paths:
$ref: '#/components/schemas/SessionsFacetsResponse'
example:
cwds:
- /Users/son/WebstormProjects/Claude-Code-Agent-Monitor
- /Users/dev/AgentHub
- /Users/son/code/another-project
sources:
- local
@@ -11633,4 +11633,4 @@ paths:
errors: 0
'400':
description: Missing file, invalid JSON, or unrecognized export format
x-issues-url: https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor/issues
x-issues-url: https://git.smartgift.io.vn/Smartgift-AI/AgentHub/issues
+3 -3
View File
@@ -18,13 +18,13 @@
"author": "Nguyễn Ngọc Trí Vĩ",
"repository": {
"type": "git",
"url": "git+https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
"url": "git+https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git"
},
"bugs": {
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor/issues"
"url": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub/issues"
},
"license": "UNLICENSED",
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor#readme",
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub#readme",
"keywords": [
"claude",
"claude-code",
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": [
"analytics",
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": ["config", "memory", "governance", "audit", "mcp", "hooks", "claude-code"],
"categories": ["config", "governance", "monitoring"]
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": ["budget", "cost", "forecast", "alerts", "spend", "pricing", "claude-code"],
"categories": ["cost", "monitoring", "alerts"]
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": ["dashboard", "connector", "real-time", "monitoring", "claude-code"],
"categories": ["integration", "monitoring"]
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": ["devtools", "debugging", "diagnostics", "export", "health-check", "claude-code"],
"categories": ["devtools", "debugging", "diagnostics"]
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": [
"insights",
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": ["productivity", "standup", "reports", "sprint", "workflow", "claude-code"],
"categories": ["productivity", "workflow", "reporting"]
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": [
"reliability",
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": ["sessions", "search", "transcript", "replay", "timeline", "cleanup", "claude-code"],
"categories": ["sessions", "monitoring", "devtools"]
@@ -6,11 +6,8 @@
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
"repository": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git",
"license": "MIT",
"keywords": [
"workflows",
+15 -6
View File
@@ -15,7 +15,11 @@ const { createOpenApiSpec } = require("../server/openapi");
const OUT = path.join(__dirname, "..", "openapi.yaml");
function main() {
/** The exact bytes `openapi.yaml` must contain for the current spec. Exported so
* the drift test can compare against the committed file without duplicating the
* dump options — a second copy of them would let the two definitions diverge,
* which is the very staleness this file exists to prevent. */
function render() {
const spec = createOpenApiSpec();
const body = yaml.dump(spec, {
lineWidth: -1, // don't wrap long strings (keeps descriptions/examples intact)
@@ -25,10 +29,15 @@ function main() {
const header =
"# DO NOT EDIT BY HAND. Generated from server/openapi.js via `npm run openapi:yaml`.\n" +
"# This YAML mirrors the live spec served at GET /api/openapi.json.\n";
fs.writeFileSync(OUT, header + body, "utf8");
const stat = fs.statSync(OUT);
const pathCount = Object.keys(spec.paths || {}).length;
console.log(`Wrote ${OUT} (${pathCount} paths, ${stat.size} bytes).`);
return { text: header + body, pathCount: Object.keys(spec.paths || {}).length };
}
main();
function main() {
const { text, pathCount } = render();
fs.writeFileSync(OUT, text, "utf8");
console.log(`Wrote ${OUT} (${pathCount} paths, ${fs.statSync(OUT).size} bytes).`);
}
if (require.main === module) main();
module.exports = { render, OUT };
+1 -1
View File
@@ -89,7 +89,7 @@ function containerRefusalMessage() {
"",
" → Install hooks ON THE HOST instead:",
" npm run install-hooks",
" # or: node /path/to/Claude-Code-Agent-Monitor/scripts/install-hooks.js",
" # or: node /path/to/AgentHub/scripts/install-hooks.js",
"",
" The host handler POSTs to http://localhost:4820, which the container already",
" publishes — so a host-installed hook reaches the containerized dashboard.",
+1 -4
View File
@@ -185,10 +185,7 @@ describe("OpenAPI / Swagger", () => {
// so the spec must not advertise one (a LICENSE url would 404).
assert.equal(res.body.info.license, undefined);
assert.equal(res.body["x-issues-url"], pkg.bugs.url);
assert.match(
res.body.info.contact.url,
/git\.smartgift\.io\.vn\/Smartgift-AI\/Claude-Code-Monitor/
);
assert.match(res.body.info.contact.url, /git\.smartgift\.io\.vn\/Smartgift-AI\/AgentHub/);
for (const pathName of EXPECTED_API_PATHS) {
assert.ok(res.body.paths[pathName], `Expected path ${pathName} to be documented`);
+1 -1
View File
@@ -248,7 +248,7 @@ describe("legacy hook cleanup", () => {
TMP_HOME,
"plugins",
"cache",
"claude-code-agent-monitor-plugins",
"agenthub",
"agenthub",
"abc123",
"scripts",
+9 -4
View File
@@ -79,16 +79,21 @@ describe("plugin marketplace", () => {
for (const entry of subdirEntries) {
describe(`entry: ${entry.name}`, () => {
it("has name, path, description, tags", () => {
it("has name, source, description, tags", () => {
assert.equal(typeof entry.name, "string");
assert.equal(entry.path, `plugins/${entry.name}`);
// `source`, not `path`: the `claude plugin install` CLI validates the
// entry against a schema that only knows `source`, so a `path` entry
// fails with "This plugin's marketplace entry is invalid: source:
// Invalid input" — the plugin is listed but uninstallable.
assert.equal(entry.source, `./plugins/${entry.name}`);
assert.equal(entry.path, undefined, "`path` is not a source key the CLI accepts");
assert.equal(typeof entry.description, "string");
assert.ok(entry.description.length > 20);
assert.ok(Array.isArray(entry.tags) && entry.tags.length > 0);
});
it("path exists on disk", () => {
assert.ok(fs.existsSync(path.join(REPO_ROOT, entry.path)));
it("source exists on disk", () => {
assert.ok(fs.existsSync(path.join(REPO_ROOT, entry.source)));
});
});
}
+138
View File
@@ -0,0 +1,138 @@
/**
* @file repo-links.test.js
* @description Guards the two staleness classes that shipped broken commands to
* users for weeks: (1) GitHub-shaped references in a repo that is self-hosted on
* Gitea — the `owner/repo` marketplace shorthand resolves to github.com ONLY
* (verified against the CLI: it rejects `host/owner/repo` outright and ignores
* GH_HOST / GITHUB_HOST / CLAUDE_CODE_MARKETPLACE_URL), plus raw.githubusercontent
* / *.github.io / `/blob/<branch>` URLs that 404 against Gitea; and (2) a stale
* committed `openapi.yaml`, which had silently drifted a whole minor version
* behind package.json. Pure file reads plus one in-process spec render.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
const { describe, it } = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const { execFileSync } = require("node:child_process");
const REPO_ROOT = path.join(__dirname, "..", "..");
// Only git-tracked text files: keeps node_modules, client/dist and every
// build artifact out without hand-maintaining an ignore list.
const TRACKED_EXT = /\.(md|json|js|cjs|mjs|ts|tsx|sh|ya?ml|html|css)$/;
// This file states every banned pattern verbatim — in the rules below and in
// the comments explaining them — so it must exclude itself or it fails on its
// own source. Derived from __filename rather than hardcoded so a rename can't
// silently re-arm the self-report.
const SELF = path.relative(REPO_ROOT, __filename);
function trackedFiles() {
// No GIT_* scrub here, deliberately: under this repo's pre-commit hook
// GIT_INDEX_FILE points at the index being committed, so `ls-files` lints
// exactly what is about to land. Scrubbing it would lint the previous commit
// instead and let a newly staged violation through.
const out = execFileSync("git", ["ls-files", "-z"], {
cwd: REPO_ROOT,
encoding: "utf8",
maxBuffer: 20_000_000,
});
return (
out
.split("\0")
.filter((f) => f && TRACKED_EXT.test(f))
.filter((f) => f !== SELF)
// Dated design docs and plans record what was true when written; rewriting
// history to satisfy a lint would be a lie about the decision record.
.filter((f) => !f.startsWith("docs/superpowers/"))
// Generated from server/openapi-extra/* (which IS linted): the drift test
// below covers it, so linting both would only double-report one fix.
.filter((f) => f !== "openapi.yaml" && !f.endsWith("package-lock.json"))
);
}
// Each rule: what to look for, and what to do instead. A `skip` pattern is
// tested against the MATCHED TEXT ONLY, never the surrounding line — a skip
// written against nearby prose silently never fires. Add one only when the
// exception is visible inside the match itself.
const RULES = [
{
name: "GitHub owner/repo marketplace shorthand",
// `claude plugin marketplace add Smartgift-AI/AgentHub` — resolves to
// github.com and fails, because this repo lives on Gitea.
re: /plugin marketplace add\s+(?!https?:\/\/)(?!\.{0,2}\/)(?!["'$])[A-Za-z0-9][\w.-]*\/[A-Za-z0-9][\w.-]*/g,
fix: "use the full https:// clone URL — the shorthand is GitHub-only",
// Anthropic's own marketplace really does live on GitHub.
skip: [/anthropics\/claude-plugins-official/],
},
{
name: "GitHub URL for a Smartgift repo",
re: /(?:https?:\/\/)?(?:www\.)?github\.com\/[Ss]martgift[\w-]*\/[\w.-]+/g,
fix: "point at git.smartgift.io.vn",
skip: [],
},
{
name: "raw.githubusercontent.com",
// Our repos are not on GitHub, so every raw URL 404s. Same-origin paths or
// a Gitea /raw/branch/<ref>/ URL instead.
re: /raw\.githubusercontent\.com\/[\w-]+\/[\w.-]+/g,
fix: "use a same-origin path, or a Gitea /raw/branch/<ref>/ URL",
skip: [],
},
{
name: "GitHub Pages host for a Smartgift site",
re: /[\w-]*smartgift[\w-]*\.github\.io/gi,
fix: "there is no GitHub Pages site — link the Gitea docs directory",
skip: [],
},
{
name: "GitHub /blob/<branch>/ path syntax on a Gitea URL",
// Gitea serves files at /src/branch/<ref>/, never /blob/<ref>/.
re: /git\.smartgift\.io\.vn\/[^\s"')\]]*\/blob\/[\w.-]+\//g,
fix: "Gitea serves files at /src/branch/<ref>/",
skip: [],
},
{
name: "retired repository name",
// Gitea 301-redirects the old name, so these never fail loudly — they just
// rot until someone turns the redirect off.
re: /Claude-Code-Monitor|Claude-Code-Agent-Monitor/g,
fix: "the repository is Smartgift-AI/AgentHub",
skip: [],
},
];
describe("repo links and generated files", () => {
const files = trackedFiles();
it("finds tracked text files to lint", () => {
assert.ok(files.length > 50, `expected a populated file list, got ${files.length}`);
});
for (const rule of RULES) {
it(`no ${rule.name}`, () => {
const hits = [];
for (const rel of files) {
const text = fs.readFileSync(path.join(REPO_ROOT, rel), "utf8");
// A fresh regex per file: the /g rules carry lastIndex between calls.
for (const m of text.matchAll(new RegExp(rule.re.source, rule.re.flags))) {
if (rule.skip.some((s) => s.test(m[0]))) continue;
const line = text.slice(0, m.index).split("\n").length;
hits.push(`${rel}:${line}: ${m[0].trim()}`);
}
}
assert.deepEqual(hits, [], `${rule.fix}\n ${hits.join("\n ")}`);
});
}
it("committed openapi.yaml matches the generator output", () => {
const { render, OUT } = require("../../scripts/generate-openapi-yaml");
assert.equal(
fs.readFileSync(OUT, "utf8"),
render().text,
"openapi.yaml is stale — run `npm run openapi:yaml` and commit the result"
);
});
});
+7 -4
View File
@@ -25,7 +25,7 @@ function loadOrCreateVapidKeys() {
const vapidKeys = loadOrCreateVapidKeys();
webpush.setVapidDetails(
"https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"https://git.smartgift.io.vn/Smartgift-AI/AgentHub",
vapidKeys.publicKey,
vapidKeys.privateKey
);
@@ -94,9 +94,12 @@ async function sendPushToAll(db, title, body) {
const payload = JSON.stringify({
title,
body,
icon: "https://raw.githubusercontent.com/Smartgift-AI/Claude-Code-Monitor/main/client/public/favicon.ico",
badge:
"https://raw.githubusercontent.com/Smartgift-AI/Claude-Code-Monitor/main/client/public/favicon.ico",
// Same-origin path, resolved by the service worker against its own scope
// (client/public/sw.js spreads these straight into showNotification). An
// absolute forge/raw URL would 404 — this repo is self-hosted on Gitea and
// ships favicon.svg, not favicon.ico.
icon: "/favicon.svg",
badge: "/favicon.svg",
silent: false,
sound: "default",
});
+1 -1
View File
@@ -14,7 +14,7 @@ const { execFile } = require("child_process");
const DEFAULT_ROOT = path.join(__dirname, "..", "..");
// This build tracks its OWN repository only: origin points at
// git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor. "upstream" is
// git.smartgift.io.vn/Smartgift-AI/AgentHub. "upstream" is
// deliberately absent from the priority list — a stray upstream remote must
// never make the update checker report commits from somebody else's repo.
const REMOTE_PRIORITY = ["origin"];
+2 -8
View File
@@ -40,10 +40,7 @@ const schemas = {
description:
"Distinct, non-empty session working directories (the `cwd` column), sorted ascending. Powers the cwd filter dropdown.",
items: { type: "string" },
example: [
"/Users/son/WebstormProjects/Claude-Code-Agent-Monitor",
"/Users/son/code/another-project",
],
example: ["/Users/dev/AgentHub", "/Users/son/code/another-project"],
},
sources: {
type: "array",
@@ -527,10 +524,7 @@ const paths = {
"application/json": {
schema: { $ref: "#/components/schemas/SessionsFacetsResponse" },
example: {
cwds: [
"/Users/son/WebstormProjects/Claude-Code-Agent-Monitor",
"/Users/son/code/another-project",
],
cwds: ["/Users/dev/AgentHub", "/Users/son/code/another-project"],
sources: ["local", "4d1f0e2a-7b9c-4c33-8a21-9e0f7b6d4c11"],
},
},
+3 -3
View File
@@ -97,7 +97,7 @@ const GENERIC_WEBHOOK_TARGET_EXAMPLE = {
const SETTINGS_INFO_EXAMPLE = {
db: {
path: "/Users/son/WebstormProjects/Claude-Code-Agent-Monitor/server/data/agent-monitor.db",
path: "/Users/dev/AgentHub/server/data/agent-monitor.db",
size: 48922624,
counts: {
sessions: 412,
@@ -351,7 +351,7 @@ const IMPORT_UPLOAD_EXAMPLE = {
const UPDATE_STATUS_AVAILABLE_EXAMPLE = {
git_repo: true,
repo_root: "/Users/son/WebstormProjects/Claude-Code-Agent-Monitor",
repo_root: "/Users/dev/AgentHub",
update_available: true,
commits_behind: 4,
remote_ref: "origin/master",
@@ -363,7 +363,7 @@ const UPDATE_STATUS_AVAILABLE_EXAMPLE = {
const UPDATE_STATUS_UP_TO_DATE_EXAMPLE = {
git_repo: true,
repo_root: "/Users/son/WebstormProjects/Claude-Code-Agent-Monitor",
repo_root: "/Users/dev/AgentHub",
update_available: false,
commits_behind: 0,
remote_ref: "origin/master",
@@ -43,7 +43,7 @@ const exampleSession = {
id: "b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d",
name: "Refactor pricing route + add cost endpoint",
status: "active",
cwd: "/Users/son/WebstormProjects/Claude-Code-Agent-Monitor",
cwd: "/Users/dev/AgentHub",
model: "claude-opus-4-20250514",
started_at: "2026-06-25T14:02:11.004Z",
ended_at: null,
@@ -60,7 +60,7 @@ const exampleCompletedSession = {
id: "1a2b3c4d-5e6f-4071-8293-a4b5c6d7e8f9",
name: "Fix flaky transcript pagination test",
status: "completed",
cwd: "/Users/son/WebstormProjects/Claude-Code-Agent-Monitor",
cwd: "/Users/dev/AgentHub",
model: "claude-sonnet-4-20250514",
started_at: "2026-06-24T09:12:00.000Z",
ended_at: "2026-06-24T09:48:32.501Z",
@@ -176,7 +176,7 @@ const paths = {
example: {
id: "b7f3a2c1-4e5d-4a8b-9c2f-1d6e8a0b3c4d",
name: "Refactor pricing route + add cost endpoint",
cwd: "/Users/son/WebstormProjects/Claude-Code-Agent-Monitor",
cwd: "/Users/dev/AgentHub",
model: "claude-opus-4-20250514",
metadata: { source: "hook", git_branch: "feat/spend-budgets" },
},
+1 -1
View File
@@ -875,7 +875,7 @@ const paths = {
items: [
{
kind: "dashboard",
path: "/Users/dev/Claude-Code-Agent-Monitor",
path: "/Users/dev/AgentHub",
label: "Dashboard server",
},
{ kind: "home", path: "/Users/dev", label: "Home" },
+1 -1
View File
@@ -2,7 +2,7 @@
**AgentHub** brings a high-fidelity, real-time dashboard for your Claude Code AI sessions directly into your VS Code workspace. Monitor token usage, track agent health, and view deep analytics without switching windows.
![Extension Screenshot](https://raw.githubusercontent.com/Smartgift-AI/Claude-Code-Monitor/refs/heads/master/vscode-extension/vscode.png)
![Extension Screenshot](https://git.smartgift.io.vn/Smartgift-AI/AgentHub/raw/branch/main/vscode-extension/vscode.png)
---
+5 -6
View File
@@ -288,8 +288,8 @@ function getErrorHtml() {
<div class="timeline">
<div class="t-step">
<div class="t-label">Initialize Repository</div>
<div class="t-code">git clone https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git
cd Claude-Code-Agent-Monitor
<div class="t-code">git clone https://git.smartgift.io.vn/Smartgift-AI/AgentHub.git
cd AgentHub
npm run setup</div>
</div>
<div class="t-step" style="margin-bottom: 0;">
@@ -317,16 +317,15 @@ npm run setup</div>
Retry Connection
</button>
<a href="https://smartgift.github.io/Claude-Code-Agent-Monitor/" class="btn btn-secondary">
<a href="https://git.smartgift.io.vn/Smartgift-AI/AgentHub/src/branch/main/docs" class="btn btn-secondary">
View Documentation
</a>
</div>
</div>
<div class="footer">
<a href="https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor">GitHub</a>
<a href="https://smartgift.github.io/Claude-Code-Agent-Monitor/">Wiki</a>
<a href="https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor/issues">Support</a>
<a href="https://git.smartgift.io.vn/Smartgift-AI/AgentHub">Repository</a>
<a href="https://git.smartgift.io.vn/Smartgift-AI/AgentHub/issues">Support</a>
</div>
</div>
</body>
+2 -2
View File
@@ -24,9 +24,9 @@
},
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor"
"url": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor/blob/master/vscode-extension/README.md",
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/AgentHub/src/branch/main/vscode-extension/README.md",
"contributes": {
"commands": [
{