agim-cli 1.2.56 → 1.2.57
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/CHANGELOG.md +32 -0
- package/dist/core/skills/builtin/agim-memory/SKILL.md +66 -0
- package/dist/core/skills/builtin/agim-reminders/SKILL.md +57 -0
- package/dist/core/skills/builtin/github/SKILL.md +65 -0
- package/dist/core/skills/builtin/long-goal/SKILL.md +69 -0
- package/dist/core/skills/builtin/my/SKILL.md +48 -0
- package/dist/core/skills/builtin/skill-creator/SKILL.md +95 -0
- package/dist/core/skills/builtin/summarize/SKILL.md +53 -0
- package/dist/core/skills/builtin/tmux/SKILL.md +82 -0
- package/dist/core/skills/builtin/weather/SKILL.md +65 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,38 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.2.57] - 2026-05-25
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **9 new builtin skills** inspired by nanobot's skill catalog, dropped
|
|
12
|
+
into `src/core/skills/builtin/`. All are pure-markdown SKILL.md
|
|
13
|
+
packages — they teach the agent procedural knowledge and trigger
|
|
14
|
+
phrases without adding code. Available to every agim agent that
|
|
15
|
+
reads `agim skills available` (native injects into prompt; CLI
|
|
16
|
+
agents load via `mcp__imhub__read_skill`):
|
|
17
|
+
- `weather` — wttr.in + Open-Meteo, no API key
|
|
18
|
+
- `summarize` — URL / article / YouTube / PDF summarisation flow
|
|
19
|
+
- `github` — `gh` CLI patterns (PR, issue, CI runs, gh api)
|
|
20
|
+
- `my` — agent self-introspection (what model, what cwd, what tools)
|
|
21
|
+
- `skill-creator` — meta-skill for writing new SKILL.md packages
|
|
22
|
+
- `tmux` — interactive-TTY guidance with isolated-socket convention
|
|
23
|
+
- `long-goal` — sustained multi-turn objectives via `/goal set`,
|
|
24
|
+
progress logging, and acceptance-criteria rules (adapted from
|
|
25
|
+
nanobot but mapped onto agim's existing goals.ts)
|
|
26
|
+
- `agim-reminders` — replaces nanobot's `cron`; teaches the
|
|
27
|
+
`mcp__imhub__create_reminder` family with concrete examples
|
|
28
|
+
- `agim-memory` — replaces nanobot's `memory`; teaches the
|
|
29
|
+
`memory_*` + `*_memo` tools and the 5W1H taxonomy
|
|
30
|
+
|
|
31
|
+
### Deferred
|
|
32
|
+
|
|
33
|
+
- `long_task` / `complete_goal` MCP tools (nanobot-style auto-register)
|
|
34
|
+
intentionally deferred to v1.2.58 — the `long-goal` skill currently
|
|
35
|
+
routes through the existing `/goal set` slash command. Will revisit
|
|
36
|
+
after observing how often agents reach for self-registered goals
|
|
37
|
+
in real IM use.
|
|
38
|
+
|
|
7
39
|
## [1.2.56] - 2026-05-25
|
|
8
40
|
|
|
9
41
|
### Fixed
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agim-memory
|
|
3
|
+
description: Persist and query the user's long-term facts via agim's `mcp__imhub__memory_*` tools and the 5W1H `*_memo` tools. Use proactively when the user reveals preferences ("我不喝咖啡"), holdings ("我持有 600519"), recurring places ("我家在朝阳"), or facts that should survive past this turn. Also use when answering questions that need facts they've told you before.
|
|
4
|
+
always: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Memory
|
|
8
|
+
|
|
9
|
+
agim has two related stores. Use whichever fits the shape of the data.
|
|
10
|
+
|
|
11
|
+
## Layer 1 — Long-term memory (`memory_*`)
|
|
12
|
+
|
|
13
|
+
Free-form key-value facts, semantic-searchable. Backed by `MEMORY.md` + optional vector index.
|
|
14
|
+
|
|
15
|
+
| Tool | When |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `memory_save({ what, type?: "user"|"feedback"|"project"|"reference" })` | Learn anything worth remembering long-term: user role, preferences, ongoing initiatives, useful URLs |
|
|
18
|
+
| `memory_query({ query, k=5 })` | Recall — user references something they told you before |
|
|
19
|
+
| `memory_list({ type?, limit? })` | Browse what's in memory (rare; usually `query` is better) |
|
|
20
|
+
| `memory_delete({ name })` | User asks you to forget something specific |
|
|
21
|
+
|
|
22
|
+
`type` taxonomy (use this exactly):
|
|
23
|
+
|
|
24
|
+
- **user** — who they are: role, expertise, communication style, goals. Apply when tailoring future replies.
|
|
25
|
+
- **feedback** — corrections + confirmations they gave you. "不要再用表格" / "这种做法对了,下次也这样".
|
|
26
|
+
- **project** — facts about ongoing initiatives. Decays fast — re-check before relying on it.
|
|
27
|
+
- **reference** — pointers to external resources: dashboards, channels, registries. Stable.
|
|
28
|
+
|
|
29
|
+
Write descriptive memories. Bad: "user likes go". Good: "10-year Go expertise; new to this repo's React side — frame frontend explanations via backend analogues".
|
|
30
|
+
|
|
31
|
+
## Layer 2 — Structured 5W1H memos (`save_memo` / `search_memos` / `update_memo` / `delete_memo`)
|
|
32
|
+
|
|
33
|
+
Use for facts with clear who-what-when-where-why-how shape: holdings, addresses, recurring meetings, GPS pins. Each memo has a typed schema and is searchable.
|
|
34
|
+
|
|
35
|
+
| Tool | When |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `save_memo({ what, when?, where?, who?, why?, how?, tags? })` | Fact has temporal / spatial structure |
|
|
38
|
+
| `search_memos({ query?, tags?, limit? })` | "我上次和谁约的午饭在哪?" |
|
|
39
|
+
| `update_memo({ id, … })` | Correct a memo (user said "不对,那家店在国贸") |
|
|
40
|
+
| `delete_memo({ id })` | Remove |
|
|
41
|
+
| `request_location_capture()` | Ask the user to send a location pin (telegram / wechat support this) |
|
|
42
|
+
|
|
43
|
+
## When to save proactively
|
|
44
|
+
|
|
45
|
+
If during a turn you learn something that…
|
|
46
|
+
|
|
47
|
+
- Is **specific** (not generic knowledge)
|
|
48
|
+
- Will be **referenced later** (preferences, ongoing work, holdings)
|
|
49
|
+
- Doesn't fit in the current task's output
|
|
50
|
+
|
|
51
|
+
…save it BEFORE replying. Don't ask permission for every save — that's noise. Do mention briefly: "记下了:你不喝咖啡 → 以后推荐饮品会避开。"
|
|
52
|
+
|
|
53
|
+
## When NOT to save
|
|
54
|
+
|
|
55
|
+
- Code patterns / architecture (read the code)
|
|
56
|
+
- Ephemeral state (current conversation)
|
|
57
|
+
- Anything already in `CLAUDE.md` / project docs
|
|
58
|
+
- Test fixtures / example data
|
|
59
|
+
|
|
60
|
+
These rules apply even if the user asks to save them — push back gently: "这个其实代码里写得很清楚,要不你以后通过读代码而不是记忆来获取?"
|
|
61
|
+
|
|
62
|
+
## On recall, verify before quoting
|
|
63
|
+
|
|
64
|
+
Memories are snapshots of what was true at write time. If a memory says "X holds 600519", but the user just said "我已经清仓了", trust the recent statement and `update_memo` / `memory_save` the new state.
|
|
65
|
+
|
|
66
|
+
Don't quote a memory as authoritative when current observation contradicts it.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agim-reminders
|
|
3
|
+
description: Set / list / cancel / snooze reminders via agim's `mcp__imhub__*_reminder` tools. Use whenever the user mentions a future commitment ("明天要开会", "下周一交报告"), asks for a recurring nudge ("每天9点提醒我吃药"), or asks "我有哪些提醒". This replaces nanobot's `cron` skill — agim has its own scheduler.
|
|
4
|
+
always: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Reminders
|
|
8
|
+
|
|
9
|
+
agim exposes four MCP tools (`mcp__imhub__create_reminder`, `list_reminders`, `cancel_reminder`, `snooze_reminder`). Use them PROACTIVELY — don't wait for "提醒我…"; if the user mentions a future event, offer to set one.
|
|
10
|
+
|
|
11
|
+
## create_reminder
|
|
12
|
+
|
|
13
|
+
| Field | Type | Notes |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `fireAt` | ISO 8601 local time, e.g. `"2026-05-26T12:00:00"` | First fire time. Compute from current time + user's stated offset. |
|
|
16
|
+
| `text` | ≤ 60 chars | Just the activity ("团队聚餐"), NOT the time. |
|
|
17
|
+
| `recurrence` | optional | `"every:5m"` · `"daily:08:00"` · `"weekly:1,3,5:09:00"` (Mon/Wed/Fri at 9:00) |
|
|
18
|
+
| `promptMode` | optional, default `"llm"` | `"literal"` for verbatim; `"llm"` lets agim's LLM polish text at fire time |
|
|
19
|
+
|
|
20
|
+
After creating, reply terse:
|
|
21
|
+
> ✅ 已设:明天 12:00 团队聚餐
|
|
22
|
+
|
|
23
|
+
## list_reminders
|
|
24
|
+
|
|
25
|
+
No args. Returns pending list. Use before suggesting cancel or snooze.
|
|
26
|
+
|
|
27
|
+
## cancel_reminder
|
|
28
|
+
|
|
29
|
+
`id` from `list_reminders`. For recurring, this terminates the whole loop.
|
|
30
|
+
|
|
31
|
+
## snooze_reminder
|
|
32
|
+
|
|
33
|
+
`id` + `duration` (`"5m"` / `"30m"` / `"2h"`). Creates a new reminder, cancels the original.
|
|
34
|
+
|
|
35
|
+
## Examples
|
|
36
|
+
|
|
37
|
+
User: "明天中午吃完饭提醒我去交报告"
|
|
38
|
+
→ `create_reminder({ fireAt: "2026-05-26T13:30:00", text: "交报告" })`
|
|
39
|
+
|
|
40
|
+
User: "每天早上 8 点告诉我天气"
|
|
41
|
+
→ `create_reminder({ fireAt: "2026-05-26T08:00:00", text: "查天气", recurrence: "daily:08:00", promptMode: "llm" })`
|
|
42
|
+
→ at fire time, agim's LLM polish lets you actually call the `weather` skill instead of repeating "查天气".
|
|
43
|
+
|
|
44
|
+
User: "把昨天那个 30 分钟一次的取消了"
|
|
45
|
+
→ `list_reminders()` → find the row → `cancel_reminder({ id: N })`
|
|
46
|
+
|
|
47
|
+
## When NOT to use
|
|
48
|
+
|
|
49
|
+
- **One-off "X 分钟后做 Y"**: yes, use this.
|
|
50
|
+
- **Recurring task agim should execute, not just remind**: use `recurrence` + `promptMode: "llm"` and write the text as a task ("查 BTC 价格然后告诉我"). At each fire, agim wakes you up with that prompt.
|
|
51
|
+
- **Sustained multi-turn objective**: not a reminder. Use `/goal set` (see the `long-goal` skill).
|
|
52
|
+
- **One-shot at exact time + nothing else**: still a reminder.
|
|
53
|
+
|
|
54
|
+
## Constraints
|
|
55
|
+
|
|
56
|
+
- High-frequency (interval < 1h) recurring with `promptMode: "llm"` auto-confirms via card. Keep your reply terse — the user already sees the card.
|
|
57
|
+
- The `_im_context` field is injected by agim; don't try to set it yourself.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github
|
|
3
|
+
description: Interact with GitHub via the `gh` CLI. Use for issues, PRs, CI runs, releases, repo metadata, and gh api queries. Prefer `gh` over raw curl + token because gh handles auth.
|
|
4
|
+
always: false
|
|
5
|
+
metadata:
|
|
6
|
+
agim:
|
|
7
|
+
requires:
|
|
8
|
+
bins: [gh]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# GitHub (`gh` CLI)
|
|
12
|
+
|
|
13
|
+
`gh` is the authoritative way to talk to GitHub from the shell. It picks up the operator's logged-in account from `~/.config/gh/hosts.yml`. Outside a git repo always pass `--repo owner/repo`.
|
|
14
|
+
|
|
15
|
+
## Pull requests
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
gh pr list --repo owner/repo --state open --limit 20
|
|
19
|
+
gh pr view 123 --repo owner/repo
|
|
20
|
+
gh pr diff 123 --repo owner/repo
|
|
21
|
+
gh pr checks 123 --repo owner/repo # CI status (key for "this PR red 在哪")
|
|
22
|
+
gh pr create --repo owner/repo --title "…" --body-file -
|
|
23
|
+
gh pr merge 123 --repo owner/repo --squash --auto # auto-merge when CI green
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Issues
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
gh issue list --repo owner/repo --state open
|
|
30
|
+
gh issue create --repo owner/repo --title "…" --body "…"
|
|
31
|
+
gh issue view 456 --repo owner/repo
|
|
32
|
+
gh issue close 456 --repo owner/repo --comment "fixed in #789"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## CI runs
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
gh run list --repo owner/repo --limit 5
|
|
39
|
+
gh run view <run-id> --repo owner/repo # see jobs + step results
|
|
40
|
+
gh run view <run-id> --repo owner/repo --log-failed # logs of failed steps only
|
|
41
|
+
gh run watch <run-id> --repo owner/repo # block until done
|
|
42
|
+
gh run rerun <run-id> --repo owner/repo
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Releases & tags
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
gh release list --repo owner/repo
|
|
49
|
+
gh release view v1.2.3 --repo owner/repo
|
|
50
|
+
gh release create v1.2.3 --repo owner/repo --notes-file CHANGELOG.md
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Raw API for everything else
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
gh api repos/owner/repo/contents/path/to/file.ts --jq '.content' | base64 -d
|
|
57
|
+
gh api repos/owner/repo/pulls/55 --jq '.title, .state, .user.login'
|
|
58
|
+
gh api graphql -f query='{ viewer { login } }'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Output rules
|
|
62
|
+
|
|
63
|
+
- Long lists: limit with `--limit` and quote only the top N.
|
|
64
|
+
- CI failures: use `--log-failed` and quote the last 40 lines of the failing step, not the whole log.
|
|
65
|
+
- For agim-cli itself, the repo is `benking007/agim`.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: long-goal
|
|
3
|
+
description: Sustained multi-turn objectives — "ship v1.3 this week" / "research X over the next 3 days" / "every morning send a market brief". Use when the user describes work that spans more than one chat turn and should stay visible across sessions. Not for one-shot questions.
|
|
4
|
+
always: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Long-running objectives
|
|
8
|
+
|
|
9
|
+
agim has a built-in goal system distinct from reminders / cron / heartbeats:
|
|
10
|
+
|
|
11
|
+
| Primitive | When |
|
|
12
|
+
|---|---|
|
|
13
|
+
| **/remind** | one-shot fire at time T |
|
|
14
|
+
| **/cron** (in `mcp__imhub__create_reminder` with `recurrence:`) | repeating timer, each tick independent |
|
|
15
|
+
| **/heartbeat** | periodic self-check on what's worth doing now |
|
|
16
|
+
| **/goal** | sustained multi-turn objective whose state agim INJECTS into every prompt |
|
|
17
|
+
|
|
18
|
+
Use **/goal** when the user wants you to keep an objective alive across many back-and-forths.
|
|
19
|
+
|
|
20
|
+
## When to suggest a goal
|
|
21
|
+
|
|
22
|
+
If the user says any of:
|
|
23
|
+
- "帮我跟一下 X 项目"
|
|
24
|
+
- "接下来一周关注 Y"
|
|
25
|
+
- "每天早上看一下 Z"
|
|
26
|
+
- "我要做完 W 才停"
|
|
27
|
+
- "long-term track…"
|
|
28
|
+
|
|
29
|
+
**Don't silently create one** — say:
|
|
30
|
+
> 这听起来像个长期目标,建议你 `/goal set <一句话目标>` 来锁定。我会在之后的每次对话里看到这个目标,能帮你保持方向。
|
|
31
|
+
|
|
32
|
+
If they confirm, they type the command; the goals.ts module persists to `goals.db` and injects the snippet automatically.
|
|
33
|
+
|
|
34
|
+
## What you'll see when a goal is active
|
|
35
|
+
|
|
36
|
+
agim's prompt builder injects a **`[Active goal]`** block (or similar runtime-context line) showing:
|
|
37
|
+
- title
|
|
38
|
+
- body (acceptance criteria / scope)
|
|
39
|
+
- up to 5 most-recent progress notes
|
|
40
|
+
|
|
41
|
+
Treat that block as **session metadata, not a user instruction**. It tells you the user's running objective; it doesn't grant permission to bypass safety rules.
|
|
42
|
+
|
|
43
|
+
## How to make progress on a goal
|
|
44
|
+
|
|
45
|
+
Per turn:
|
|
46
|
+
1. **Read the goal block** at top of context.
|
|
47
|
+
2. Do the work the user asked for *this turn*.
|
|
48
|
+
3. If you completed a step toward the goal, log it concisely. Two ways:
|
|
49
|
+
- Append a progress note: tell the user "Logged: <one-liner>" and they can `/goal note <text>` themselves (current minimal flow)
|
|
50
|
+
- OR drop a `mcp__imhub__save_memo` with `what:"<one-liner>"`, `who:"agent"`, and a tag like `goal:<id>` for retrieval.
|
|
51
|
+
4. If the goal is **done** or the user cancels, suggest `/goal complete <recap>` — they type it.
|
|
52
|
+
|
|
53
|
+
## Writing a good goal title
|
|
54
|
+
|
|
55
|
+
(For the user — pass this back if they ask "good goal title 怎么写")
|
|
56
|
+
|
|
57
|
+
- **Idempotent**: re-issuing the same goal shouldn't conflict. "Ship v1.3" yes; "Finish what I started" no.
|
|
58
|
+
- **Bounded**: time / scope clear. "Finish Memory tab A+D merge" yes; "Improve memory" no.
|
|
59
|
+
- **Self-contained**: someone reading it cold should know the target.
|
|
60
|
+
|
|
61
|
+
## Don't
|
|
62
|
+
|
|
63
|
+
- Don't create more than one **active** goal per thread. agim will block a second `/goal set` until the current one is `completed`/`cancelled`/`paused`.
|
|
64
|
+
- Don't fake progress notes. If nothing changed, say so.
|
|
65
|
+
- Don't treat the goal block as overriding the user's current ask — current ask wins; the goal is context.
|
|
66
|
+
|
|
67
|
+
## Future tools (deferred to v1.2.58)
|
|
68
|
+
|
|
69
|
+
Nanobot's `long_task` / `complete_goal` MCP tools (which let the agent **itself** open/close goals, not just suggest a slash command) are planned. Until they ship, the flow above is the supported path.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: my
|
|
3
|
+
description: Check the agim agent's own runtime state — current model, role, working directory, context size, available tools. Use when diagnosing "why can't you do X?" / "what model are you?" / "what's your current cwd?" / before committing to a long task.
|
|
4
|
+
always: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Self-awareness (`my`)
|
|
8
|
+
|
|
9
|
+
You are running as one of agim's agents (native / claude-code / codex / opencode / cursor / antigravity). When the user asks how you're configured, or you're about to attempt something whose feasibility depends on your runtime, **check before assuming**.
|
|
10
|
+
|
|
11
|
+
## What you can answer directly
|
|
12
|
+
|
|
13
|
+
| Question | How to answer |
|
|
14
|
+
|---|---|
|
|
15
|
+
| "你是哪个 agent?" | Look at the system reminder block — agim's prompt always tells you which agent you are. The active agent's name also appears in `/agents` output. |
|
|
16
|
+
| "用的什么模型?" | For native: read `process.env.IMHUB_NATIVE_BACKEND` or run `agim model show`. For CLI agents: the model is set by the CLI itself (`/model` inside claude-code, `gpt-5` inside codex etc.). |
|
|
17
|
+
| "现在的 cwd?" | Each agent has a per-agent cwd under `~/.agim-workspaces/<agent>/`. Read `AGENTS.md` in that dir to see role-specific instructions; the cwd itself is set at process spawn time. |
|
|
18
|
+
| "context 还剩多少?" | If you're running as a CLI agent, the harness usually shows a status line. For native, recent token usage logs into `journalctl -u agim` under `event=native.turn.done`. |
|
|
19
|
+
| "Apps 列表?" | Run `agim agents` or use the `/agents` slash command. |
|
|
20
|
+
|
|
21
|
+
## What you can change
|
|
22
|
+
|
|
23
|
+
The user (and you, with the user's consent) can change runtime settings via slash commands. Show the user the command, do not silently mutate.
|
|
24
|
+
|
|
25
|
+
| Want to | Command |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Switch agent for this thread | `/cc` (claude-code) · `/oc` (opencode) · `/cx` (codex) · `/cs` (cursor) · `/agy` (antigravity) · `/native` |
|
|
28
|
+
| Switch model on a CLI agent | `/model` (works for claude-code / codex / opencode / cursor) |
|
|
29
|
+
| Reset thread context | `/new` |
|
|
30
|
+
| Stop a running task | `/abort` |
|
|
31
|
+
| Set a sustained objective | `/goal set <title>` |
|
|
32
|
+
| Periodic self-check | `/heartbeat bind <body>` |
|
|
33
|
+
|
|
34
|
+
## Diagnostic checklist (when something fails)
|
|
35
|
+
|
|
36
|
+
Before saying "I can't do that", run through:
|
|
37
|
+
|
|
38
|
+
1. **Tool available?** Tell the user the literal tool name you tried; if it's missing, the operator hasn't enabled it.
|
|
39
|
+
2. **Skill exists?** `mcp__imhub__read_skill("<name>")` returns the body; if it errors, the skill isn't installed.
|
|
40
|
+
3. **Network?** Try `curl -sS -o /dev/null -w "%{http_code}\n" https://www.google.com` (or a target endpoint) — agim runs on the operator's host, no proxy by default.
|
|
41
|
+
4. **API key?** Many skills require `ENV` vars (FINNHUB_API_KEY, MX_APIKEY, etc.). The skill summary block shows `(unavailable: ENV: X)` when missing.
|
|
42
|
+
|
|
43
|
+
## Don't lie about what you are
|
|
44
|
+
|
|
45
|
+
If the user asks something that depends on a capability you lack — say it directly:
|
|
46
|
+
> 我现在跑在 claude-code,没法直接执行长任务的后台守护。建议用 `/native` 或 `agim` 的 bgjob。
|
|
47
|
+
|
|
48
|
+
That's more useful than guessing.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-creator
|
|
3
|
+
description: Create or update agim skills (SKILL.md packages). Use when the user says "新建一个 skill" / "把这个流程做成 skill" / "create a skill for X". Walks through frontmatter, body structure, references/scripts, and where to drop the directory.
|
|
4
|
+
always: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Skill Creator
|
|
8
|
+
|
|
9
|
+
A skill in agim is a directory shipped under one of these roots (workspace shadows builtin):
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
~/.agim/skills/<name>/SKILL.md # operator-owned (highest priority)
|
|
13
|
+
~/.claude/skills/<name>/SKILL.md # shared with terminal Claude
|
|
14
|
+
~/.config/opencode/skills/<name>/SKILL.md
|
|
15
|
+
~/.codex/skills/<name>/SKILL.md
|
|
16
|
+
<agim-dist>/core/skills/builtin/<name>/ # packaged with agim
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`IMHUB_SKILLS_MODE=auto` (default) merges all of them; `agim-only` restricts to `~/.agim/skills/`.
|
|
20
|
+
|
|
21
|
+
## Core principles (adapted from Anthropic + nanobot)
|
|
22
|
+
|
|
23
|
+
1. **Be concise.** The summary block (frontmatter `name` + `description`) is injected into **every** turn. Burn that token budget honestly.
|
|
24
|
+
2. **Trigger phrases in the description.** Write the description so a model can decide whether to load the body without seeing the body. Phrase as "Use when the user asks …".
|
|
25
|
+
3. **Body is read on demand.** Put procedural detail, examples, edge cases, references in the body. The model fetches it via `mcp__imhub__read_skill("<name>")` only when the description matched.
|
|
26
|
+
4. **Match degrees of freedom to the task.** High-freedom text (heuristics) for fuzzy tasks; concrete commands / pseudocode for rigid pipelines.
|
|
27
|
+
5. **No marketing.** A skill is teaching, not selling.
|
|
28
|
+
|
|
29
|
+
## Minimum SKILL.md template
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
---
|
|
33
|
+
name: <kebab-case>
|
|
34
|
+
description: <one-paragraph trigger description. Mention concrete user phrases that should activate this skill. End with key constraints.>
|
|
35
|
+
always: false
|
|
36
|
+
metadata:
|
|
37
|
+
agim:
|
|
38
|
+
requires:
|
|
39
|
+
bins: [optional, list, of, cli, binaries]
|
|
40
|
+
env: [OPTIONAL_ENV_KEYS]
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
# <Display Title>
|
|
44
|
+
|
|
45
|
+
<1-3 line orientation: when to use, what it produces.>
|
|
46
|
+
|
|
47
|
+
## When to use
|
|
48
|
+
|
|
49
|
+
- "trigger phrase 1"
|
|
50
|
+
- "trigger phrase 2"
|
|
51
|
+
|
|
52
|
+
## Steps
|
|
53
|
+
|
|
54
|
+
1. …
|
|
55
|
+
2. …
|
|
56
|
+
|
|
57
|
+
## Output rules
|
|
58
|
+
|
|
59
|
+
- Concise example: …
|
|
60
|
+
- Don't: …
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Frontmatter fields agim respects
|
|
64
|
+
|
|
65
|
+
| Field | Effect |
|
|
66
|
+
|---|---|
|
|
67
|
+
| `name` | Must match dir name. Used as the lookup key. |
|
|
68
|
+
| `description` | First line shown in skill summary. **Lead with trigger phrases.** |
|
|
69
|
+
| `always: true` | Loads full body into every system prompt. Use only for ≤ 200-line skills that apply to >50% of turns (e.g. self-reference). |
|
|
70
|
+
| `metadata.agim.requires.bins` | Missing → skill shows `(unavailable: CLI: <bin>)` in summary. |
|
|
71
|
+
| `metadata.agim.requires.env` | Same, for env vars. |
|
|
72
|
+
|
|
73
|
+
## Workflow
|
|
74
|
+
|
|
75
|
+
1. Decide the **trigger phrases** first; write them down.
|
|
76
|
+
2. Draft frontmatter — name + description + requires.
|
|
77
|
+
3. Sketch the body in ≤ 100 lines. Resist scope creep.
|
|
78
|
+
4. Drop into `~/.agim/skills/<name>/` (workspace). Operator can later promote to builtin via PR.
|
|
79
|
+
5. Restart agim to pick it up (loader caches roots at boot).
|
|
80
|
+
6. Test: ask the user a trigger-phrase question; verify the agent fetched the body via `read_skill`.
|
|
81
|
+
|
|
82
|
+
## Subdirectories
|
|
83
|
+
|
|
84
|
+
- `scripts/` — small executable helpers the body references by path
|
|
85
|
+
- `references/` — long-form docs the body cites
|
|
86
|
+
- `assets/` — images, schemas, fixtures
|
|
87
|
+
|
|
88
|
+
The model reads these via its existing file-read tool when the body references them by path.
|
|
89
|
+
|
|
90
|
+
## Don't
|
|
91
|
+
|
|
92
|
+
- Don't put secrets (API keys, prod URLs) into SKILL.md — those go to `~/.agim/env`.
|
|
93
|
+
- Don't write a skill for one-off requests. Skills are amortised cost.
|
|
94
|
+
- Don't duplicate the model's existing knowledge. ("git is a version-control system" wastes tokens.)
|
|
95
|
+
- Don't write multi-paragraph descriptions; that's body material.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: summarize
|
|
3
|
+
description: Summarize URLs, articles, PDFs, or YouTube videos. Use when the user asks "这篇文章讲什么" / "总结一下 …" / "summarize this link" / "what's this video about". For long content prefer summary over verbatim transcript unless the user explicitly asks for a transcript.
|
|
4
|
+
always: false
|
|
5
|
+
metadata:
|
|
6
|
+
agim:
|
|
7
|
+
requires:
|
|
8
|
+
bins: [curl]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Summarize
|
|
12
|
+
|
|
13
|
+
Two paths depending on content type. Pick **path A** for HTML / article / blog; **path B** for YouTube; **path C** for local files.
|
|
14
|
+
|
|
15
|
+
## Path A — Web page / article
|
|
16
|
+
|
|
17
|
+
1. Fetch the page (server-rendered HTML usually has the body):
|
|
18
|
+
```bash
|
|
19
|
+
curl -sL -A "Mozilla/5.0" "<url>" | head -c 200000
|
|
20
|
+
```
|
|
21
|
+
2. If the page is a SPA (the body has almost no text), try a reader API:
|
|
22
|
+
- `r.jina.ai/<url>` — strips chrome, returns clean text
|
|
23
|
+
```bash
|
|
24
|
+
curl -s "https://r.jina.ai/<url>" # url passed verbatim
|
|
25
|
+
```
|
|
26
|
+
3. Pipe the cleaned text into your own context and produce a 3-section summary:
|
|
27
|
+
- **核心结论** (1-2 sentences)
|
|
28
|
+
- **要点** (3-7 bullets)
|
|
29
|
+
- **数据/引用** (any concrete numbers, dates, names mentioned)
|
|
30
|
+
|
|
31
|
+
## Path B — YouTube
|
|
32
|
+
|
|
33
|
+
The user typically wants a summary, not a transcript. Try transcript route first; fall back gracefully if blocked:
|
|
34
|
+
|
|
35
|
+
1. Try `r.jina.ai` reader on the watch URL — sometimes returns auto-caption text.
|
|
36
|
+
2. If that fails and `yt-dlp` is installed, pull subtitles:
|
|
37
|
+
```bash
|
|
38
|
+
yt-dlp --skip-download --write-auto-sub --sub-lang zh,en --convert-subs vtt -o "/tmp/yt-%(id)s" "<url>"
|
|
39
|
+
```
|
|
40
|
+
3. Read the `.vtt`, strip timestamps, then summarise.
|
|
41
|
+
4. If neither works, tell the user: "字幕拉不到,建议你贴一段文字过来我帮你总结。"
|
|
42
|
+
|
|
43
|
+
## Path C — Local file
|
|
44
|
+
|
|
45
|
+
1. Use the model's file-read tool on `*.md`, `*.txt`, `*.html`, `*.json`.
|
|
46
|
+
2. PDFs: prefer a converter on the host (`pdftotext file.pdf -` if installed); otherwise tell the user you can't read PDFs in this environment.
|
|
47
|
+
|
|
48
|
+
## Output rules
|
|
49
|
+
|
|
50
|
+
- Default reply ≤ 12 lines unless the user asks for detail.
|
|
51
|
+
- If the source is long (> 50K chars): give summary + offer "需要详细展开哪一段?".
|
|
52
|
+
- Always cite the source URL at the bottom.
|
|
53
|
+
- Never paste base64 / raw HTML / raw VTT to the user.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tmux
|
|
3
|
+
description: Remote-control tmux sessions when you need an interactive TTY (REPLs, ncurses tools, ssh sessions with prompts). For long-running NON-interactive work prefer bgjob (`/root/.claude/scripts/bgjob`). Use only when the workflow genuinely needs keystrokes + screen scraping.
|
|
4
|
+
always: false
|
|
5
|
+
metadata:
|
|
6
|
+
agim:
|
|
7
|
+
os: [linux, darwin]
|
|
8
|
+
requires:
|
|
9
|
+
bins: [tmux]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# tmux
|
|
13
|
+
|
|
14
|
+
Use tmux **only** when you need an interactive TTY:
|
|
15
|
+
|
|
16
|
+
- Python / Node REPL with state across calls
|
|
17
|
+
- ncurses (htop, mc, vim) where output requires a terminal emulator
|
|
18
|
+
- ssh sessions that prompt for input
|
|
19
|
+
- Long-running CLIs whose output you'll scrape progressively
|
|
20
|
+
|
|
21
|
+
For everything else — long compiles, deploys, log tails — prefer agim's bgjob (`/root/.claude/scripts/bgjob start <name> -- <cmd>`). bgjob handles cgroup escape, has `tail`/`status`, persists across restarts.
|
|
22
|
+
|
|
23
|
+
## Quickstart (isolated socket)
|
|
24
|
+
|
|
25
|
+
Use a custom socket so tmux state stays scoped to this session and doesn't collide with the operator's own tmux:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
SOCKET_DIR="${AGIM_TMUX_SOCKET_DIR:-/tmp/agim-tmux-sockets}"
|
|
29
|
+
mkdir -p "$SOCKET_DIR"
|
|
30
|
+
SOCKET="$SOCKET_DIR/agim.sock"
|
|
31
|
+
SESSION="agim-$(date +%s)"
|
|
32
|
+
|
|
33
|
+
tmux -S "$SOCKET" new -d -s "$SESSION" -n shell
|
|
34
|
+
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- 'PYTHON_BASIC_REPL=1 python3 -q' Enter
|
|
35
|
+
sleep 0.3
|
|
36
|
+
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
After spawning, **always print monitor commands** so the user can peek:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
要观察会话:
|
|
43
|
+
tmux -S "$SOCKET" attach -t "$SESSION"
|
|
44
|
+
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Common patterns
|
|
48
|
+
|
|
49
|
+
Send a command + wait for prompt:
|
|
50
|
+
```bash
|
|
51
|
+
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- 'curl -sS https://example.com' Enter
|
|
52
|
+
sleep 1
|
|
53
|
+
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -100
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Drain output until a known sentinel appears (poll, max 30s):
|
|
57
|
+
```bash
|
|
58
|
+
for i in $(seq 1 30); do
|
|
59
|
+
if tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -50 | grep -q "READY"; then
|
|
60
|
+
break
|
|
61
|
+
fi
|
|
62
|
+
sleep 1
|
|
63
|
+
done
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Send Ctrl-C / Ctrl-D:
|
|
67
|
+
```bash
|
|
68
|
+
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 C-c
|
|
69
|
+
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 C-d
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Kill the session when done:
|
|
73
|
+
```bash
|
|
74
|
+
tmux -S "$SOCKET" kill-session -t "$SESSION"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Hygiene
|
|
78
|
+
|
|
79
|
+
- One session per task; name with a timestamp so multiple agents don't collide.
|
|
80
|
+
- Kill sessions when work is finished — orphan sessions sit there forever.
|
|
81
|
+
- Don't run long compute under tmux. The session will outlive your agim turn and you can't reattach next turn from a different process.
|
|
82
|
+
- Don't paste secrets into a tmux session — they end up in scrollback.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: weather
|
|
3
|
+
description: Get current weather and short forecasts. No API key required (wttr.in + Open-Meteo). Use when the user asks for weather, temperature, rain forecast, or a city's conditions.
|
|
4
|
+
always: false
|
|
5
|
+
metadata:
|
|
6
|
+
agim:
|
|
7
|
+
requires:
|
|
8
|
+
bins: [curl]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Weather
|
|
12
|
+
|
|
13
|
+
Two zero-key services. Default to `wttr.in` (compact); fall back to Open-Meteo when the user wants structured JSON or a multi-day forecast in a specific unit.
|
|
14
|
+
|
|
15
|
+
## wttr.in (primary)
|
|
16
|
+
|
|
17
|
+
One-liner:
|
|
18
|
+
```bash
|
|
19
|
+
curl -s "wttr.in/Shanghai?format=3"
|
|
20
|
+
# Shanghai: ⛅️ +18°C
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Compact custom format:
|
|
24
|
+
```bash
|
|
25
|
+
curl -s "wttr.in/Shanghai?format=%l:+%c+%t+%h+%w"
|
|
26
|
+
# Shanghai: ⛅️ +18°C 67% ↘8km/h
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Today's forecast only (~10 lines):
|
|
30
|
+
```bash
|
|
31
|
+
curl -s "wttr.in/Shanghai?T&1"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Format codes: `%l` location · `%c` condition emoji · `%t` temp · `%h` humidity · `%w` wind · `%m` moon phase
|
|
35
|
+
|
|
36
|
+
Notes:
|
|
37
|
+
- URL-encode spaces: `wttr.in/New+York`
|
|
38
|
+
- Airport codes also work: `wttr.in/PEK`
|
|
39
|
+
- Units: append `?m` (metric default) or `?u` (USCS)
|
|
40
|
+
- Set User-Agent for ANSI-free text: `curl -s -A "curl" "wttr.in/Tokyo?format=3"`
|
|
41
|
+
|
|
42
|
+
## Open-Meteo (fallback, JSON)
|
|
43
|
+
|
|
44
|
+
Use when the user wants a multi-day forecast or you need structured fields:
|
|
45
|
+
```bash
|
|
46
|
+
curl -sG "https://api.open-meteo.com/v1/forecast" \
|
|
47
|
+
--data-urlencode "latitude=31.23" \
|
|
48
|
+
--data-urlencode "longitude=121.47" \
|
|
49
|
+
--data-urlencode "current=temperature_2m,relative_humidity_2m,wind_speed_10m" \
|
|
50
|
+
--data-urlencode "daily=temperature_2m_max,temperature_2m_min,precipitation_probability_max" \
|
|
51
|
+
--data-urlencode "timezone=auto"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Geocode a city name first if you only have a name:
|
|
55
|
+
```bash
|
|
56
|
+
curl -sG "https://geocoding-api.open-meteo.com/v1/search" \
|
|
57
|
+
--data-urlencode "name=上海" --data-urlencode "count=1"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Output rules
|
|
61
|
+
|
|
62
|
+
- Quote temperature + condition first, then 1 line of extra context (wind, humidity, rain chance).
|
|
63
|
+
- For multi-day, give the next 3 days in a 1-line table:
|
|
64
|
+
`周一 ⛅️ 12-19° · 周二 🌧 9-15° · 周三 ☀️ 14-22°`
|
|
65
|
+
- Never paste raw JSON to the user.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agim-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.57",
|
|
4
4
|
"description": "Agim (阿吉姆) — universal messenger-to-agent bridge. Connect WeChat / Feishu / DingTalk / Email to Claude Code / Codex / OpenCode, or any custom agent via ACP. Installs the `agim` command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|