@agentprojectcontext/apx 1.34.0 → 1.36.0

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.
Files changed (75) hide show
  1. package/package.json +1 -1
  2. package/skills/apx/SKILL.md +1 -1
  3. package/src/core/agent/build-agent-system.js +134 -58
  4. package/src/core/agent/channels/voice-context.js +4 -4
  5. package/src/core/agent/prompt-builder.js +176 -123
  6. package/src/core/agent/prompts/channels/code.md +12 -10
  7. package/src/core/agent/prompts/channels/desktop.md +5 -32
  8. package/src/core/agent/prompts/channels/telegram.md +4 -15
  9. package/src/core/agent/prompts/channels/web_code.md +11 -11
  10. package/src/core/agent/prompts/core/agent-base.md +24 -0
  11. package/src/core/agent/prompts/core/project-agent.md +11 -0
  12. package/src/core/agent/prompts/core/super-agent.md +21 -0
  13. package/src/core/agent/prompts/discipline/action.md +10 -0
  14. package/src/core/agent/prompts/discipline/single-segment.md +6 -0
  15. package/src/core/agent/prompts/discipline/two-segment.md +11 -0
  16. package/src/core/agent/self-memory.js +43 -1
  17. package/src/core/agent/skills/index-store.js +307 -0
  18. package/src/core/agent/skills/index.js +15 -1
  19. package/src/core/agent/skills/inspector.js +317 -0
  20. package/src/core/agent/super-agent.js +7 -1
  21. package/src/core/agent/tools/handlers/_git.js +50 -0
  22. package/src/core/agent/tools/handlers/git-diff.js +44 -0
  23. package/src/core/agent/tools/handlers/git-log.js +38 -0
  24. package/src/core/agent/tools/handlers/git-show.js +34 -0
  25. package/src/core/agent/tools/handlers/git-status.js +61 -0
  26. package/src/core/agent/tools/names.js +31 -0
  27. package/src/core/agent/tools/registry.js +36 -5
  28. package/src/core/config/index.js +21 -0
  29. package/src/core/runtime-skills/apx/SKILL.md +27 -39
  30. package/src/core/runtime-skills/apx-agency-agents/SKILL.md +40 -56
  31. package/src/core/runtime-skills/apx-agent/SKILL.md +27 -30
  32. package/src/core/runtime-skills/apx-mcp/SKILL.md +31 -36
  33. package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +37 -51
  34. package/src/core/runtime-skills/apx-project/SKILL.md +20 -29
  35. package/src/core/runtime-skills/apx-routine/SKILL.md +34 -47
  36. package/src/core/runtime-skills/apx-runtime/SKILL.md +32 -50
  37. package/src/core/runtime-skills/apx-sessions/SKILL.md +96 -145
  38. package/src/core/runtime-skills/apx-skill-builder/SKILL.md +53 -77
  39. package/src/core/runtime-skills/apx-task/SKILL.md +18 -21
  40. package/src/core/runtime-skills/apx-telegram/SKILL.md +43 -54
  41. package/src/core/runtime-skills/apx-voice/SKILL.md +36 -56
  42. package/src/core/stores/conversations.js +27 -2
  43. package/src/host/daemon/api/exec.js +2 -0
  44. package/src/host/daemon/api/skills.js +140 -6
  45. package/src/host/daemon/api/super-agent.js +56 -1
  46. package/src/host/daemon/index.js +17 -0
  47. package/src/interfaces/cli/branding.js +53 -0
  48. package/src/interfaces/cli/commands/skills.js +254 -0
  49. package/src/interfaces/cli/index.js +84 -2
  50. package/src/interfaces/web/dist/assets/index-Cm0KyPoZ.css +1 -0
  51. package/src/interfaces/web/dist/assets/index-DJKA763h.js +628 -0
  52. package/src/interfaces/web/dist/assets/index-DJKA763h.js.map +1 -0
  53. package/src/interfaces/web/dist/index.html +2 -2
  54. package/src/interfaces/web/src/App.tsx +0 -1
  55. package/src/interfaces/web/src/components/chat/ChatList.tsx +412 -0
  56. package/src/interfaces/web/src/components/chat/MessageBubble.tsx +21 -1
  57. package/src/interfaces/web/src/components/settings/AppearancePanel.tsx +1 -1
  58. package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +69 -1
  59. package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +222 -0
  60. package/src/interfaces/web/src/hooks/useChat.ts +54 -2
  61. package/src/interfaces/web/src/i18n/en.ts +12 -1
  62. package/src/interfaces/web/src/i18n/es.ts +12 -1
  63. package/src/interfaces/web/src/lib/api/agents.ts +1 -1
  64. package/src/interfaces/web/src/lib/api/skills.ts +70 -0
  65. package/src/interfaces/web/src/screens/ProjectScreen.tsx +3 -5
  66. package/src/interfaces/web/src/screens/SettingsScreen.tsx +12 -6
  67. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +1 -1
  68. package/src/interfaces/web/src/screens/project/ChatTab.tsx +120 -87
  69. package/src/interfaces/web/src/types/daemon.ts +10 -0
  70. package/src/core/agent/prompts/action-discipline.md +0 -24
  71. package/src/core/agent/prompts/super-agent-base.md +0 -42
  72. package/src/interfaces/web/dist/assets/index-DdmSRtsz.css +0 -1
  73. package/src/interfaces/web/dist/assets/index-M4FspaCH.js +0 -613
  74. package/src/interfaces/web/dist/assets/index-M4FspaCH.js.map +0 -1
  75. package/src/interfaces/web/src/screens/project/ThreadsTab.tsx +0 -100
@@ -1,95 +1,86 @@
1
1
  ---
2
2
  name: apx-skill-builder
3
3
  scope: internal
4
- description: How to author a new APX skill — file location, frontmatter (name, description, scope), body style, and how the super-agent loads it on demand. Load when creating or adding a skill to APX.
4
+ description: Author a new APX skill — file location, frontmatter (name, description, scope), body style, on-demand loader. Load when creating or adding a skill to APX.
5
5
  ---
6
6
 
7
7
  # apx-skill-builder
8
8
 
9
- A **skill** in APX is a Markdown file the super-agent loads on demand to learn how to do something. Inspired by Anthropic's skill-creator pattern, simplified for APX's daemon-served model.
9
+ A **skill** is a Markdown file the super-agent loads on demand. Inspired by Anthropic's skill-creator, simplified for APX's daemon-served model.
10
10
 
11
- ## When to make a skill (vs. inlining in the system prompt)
11
+ ## When to make a skill
12
12
 
13
- - **Make a skill** when the topic is bounded (a tool, a config domain, a recurring workflow), the instructions need >50 tokens to be safe, and not every conversation needs them.
14
- - **Don't** make a skill for one-off explanations, casual chat, or stuff that fits in 2-3 lines in the base prompt.
13
+ - **Yes**: topic is bounded (a tool, a config domain, a recurring workflow), instructions need >50 tokens to be safe, not every conversation needs them.
14
+ - **No**: one-off explanations, casual chat, anything fitting in 2-3 lines of the base prompt.
15
15
 
16
16
  ## File location
17
17
 
18
- Three places APX scans, in priority order:
18
+ Scanned in priority order:
19
19
 
20
- 1. `<repo>/.apc/skills/<slug>/SKILL.md` — project-scoped (only this project's super-agent sees it).
21
- 2. `~/.apx/skills/<slug>/SKILL.md` — user-global (all projects).
22
- 3. `<repo>/skills/<slug>/SKILL.md` in the APX source — bundled (ships with the package).
20
+ 1. `<repo>/.apc/skills/<slug>/SKILL.md` — project-scoped.
21
+ 2. `~/.apx/skills/<slug>/SKILL.md` — user-global.
22
+ 3. `<repo>/skills/<slug>/SKILL.md` in the APX source — bundled.
23
23
 
24
- Either layout works:
25
- - `<slug>/SKILL.md` (dir-style, preferred — lets you ship `references/`, `assets/`, etc.)
26
- - `<slug>.md` (flat-style, fine for short ones)
24
+ Layouts: `<slug>/SKILL.md` (dir-style, preferred — supports `references/`, `assets/`) or `<slug>.md` (flat, fine for short).
27
25
 
28
26
  ## Frontmatter
29
27
 
30
- The file MUST open with YAML frontmatter:
31
-
32
28
  ```yaml
33
29
  ---
34
30
  name: my-skill
35
- description: One-sentence trigger for the super-agent. Include the user-phrases that should cause it to load. Keep it short — appears in skill listings.
36
- scope: public # public (pushed to IDE skill dirs by default) | internal (repo/dev-only) | optional
31
+ description: One-sentence trigger for the super-agent. Include user-phrases that should cause it to load. Short — appears in skill listings.
32
+ scope: public # public (synced globally) | internal (repo/dev-only) | optional (not pushed by default)
37
33
  ---
38
34
  ```
39
35
 
40
- `description` is what the model sees when deciding whether to call `load_skill`. Write it as the *trigger condition*, not a summary of the body.
41
-
42
- `scope` controls distribution: `public` skills are installed globally by `apx skills sync` / `--global`; `internal` ones stay in the APX repo (dev guides like this one); `optional` ones are available but not pushed by default. Omit it and the skill is treated as public.
36
+ `description` is what the model sees when deciding `load_skill`. Write it as the *trigger condition*, not a body summary. Omit `scope` → treated as public.
43
37
 
44
38
  **Good**: `"How to register an MCP server. Load BEFORE running 'apx mcp add' — three scopes, gotchas with stdio commands, secrets handling."`
45
-
46
- **Bad**: `"This skill describes APX's MCP system."` (no trigger; the model won't know when it matters).
39
+ **Bad**: `"This skill describes APX's MCP system."` (no trigger).
47
40
 
48
41
  ## Body style
49
42
 
50
- Opinionated, concrete, anti-example-driven. Every other APX skill in `skills/apx-*` follows the same shape — read one before writing yours:
43
+ Opinionated, concrete, anti-example-driven. Read a sibling `skills/apx-*` before writing yours. Shape:
51
44
 
52
- 1. **One-paragraph "what this is"** (no preamble, no marketing).
53
- 2. **Concrete CLI calls** the user runs, with the most common case first.
54
- 3. **Schema / shape** if the topic involves files or config.
55
- 4. **Anti-examples** — at least one "DON'T do this" with the reason. This is what stops the model from inventing flags.
45
+ 1. **One-paragraph "what this is"** no preamble.
46
+ 2. **Concrete CLI calls** most common first.
47
+ 3. **Schema / shape** if files/config are involved.
48
+ 4. **Anti-examples** — at least one "DON'T" with reason. Stops the model inventing flags.
56
49
  5. **Open questions / footnotes** if the surface is incomplete.
57
50
 
58
- Length budget: 80-200 lines. If it's longer, split into sub-skills or move scripts into `<slug>/scripts/`.
51
+ Length budget: 80-200 lines. Longer split or move scripts to `<slug>/scripts/`.
59
52
 
60
- ## How the super-agent loads it
53
+ ## Loader + commands
61
54
 
62
55
  ```js
63
- // The model emits a tool call:
56
+ // Model emits:
64
57
  load_skill({ slug: "my-skill", project_path: "/abs/path/optional" })
65
58
  ```
66
59
 
67
- That returns the full body. The agent uses the content in-context for that turn; it doesn't persist.
60
+ Returns the full body for the current turn; not persisted.
68
61
 
69
- The user can list installed skills with:
70
62
  ```bash
71
- apx skills list # lists this project's .apc/skills/ (cwd-scoped — run from the project root)
72
- apx skills sync # push bundled/public skills to the global skill dir
73
- apx skills status # show what's installed vs available
63
+ apx skills list # this project's .apc/skills/ (run from project root)
64
+ apx skills sync # push bundled/public skills to global skill dir
65
+ apx skills status # what's installed vs available
74
66
  ```
75
67
 
76
- ## Workflow: create + register
68
+ ## Workflow
77
69
 
78
70
  ```bash
79
- # 1. Pick scope
80
- # Project-scoped: .apc/skills/<slug>/SKILL.md
81
- # User-global: ~/.apx/skills/<slug>/SKILL.md
82
- # Bundled (in repo): skills/<slug>/SKILL.md
71
+ # 1. Pick scope:
72
+ # .apc/skills/<slug>/SKILL.md (project)
73
+ # ~/.apx/skills/<slug>/SKILL.md (user-global)
74
+ # skills/<slug>/SKILL.md (bundled, in repo)
83
75
 
84
- # 2. Write the file
76
+ # 2. Write
85
77
  mkdir -p skills/my-thing
86
78
  $EDITOR skills/my-thing/SKILL.md
87
79
 
88
- # 3. The daemon picks it up on next listSkills() — no restart needed unless
89
- # you've changed the scaffold sync. Confirm:
80
+ # 3. Verify (daemon picks up on next listSkills() — no restart)
90
81
  apx skills list | grep my-thing
91
82
 
92
- # 4. Pre-test with the super-agent (it's the default target — no agent name needed):
83
+ # 4. Pre-test with the super-agent (default target)
93
84
  apx exec "Load the my-thing skill and summarize it in 3 bullets"
94
85
  ```
95
86
 
@@ -97,57 +88,42 @@ apx exec "Load the my-thing skill and summarize it in 3 bullets"
97
88
 
98
89
  ```yaml
99
90
  ---
100
- # DON'T omit description — the model can't trigger on the slug alone.
91
+ # DON'T omit description — the model can't trigger on slug alone.
101
92
  name: vague-stuff
102
93
  ---
103
94
 
104
- # DON'T pile general advice into the body. Pick ONE topic per skill.
105
- # A skill that says "lots of useful tips about everything" is dead weight
106
- # in the model's mental cache.
95
+ # DON'T pile general advice. ONE topic per skill. A grab-bag is dead weight.
107
96
 
108
- # DON'T duplicate apx --help. Skills explain WHEN and WHY, not just WHAT.
109
- # `apx mcp add --help` already lists flags. The skill teaches the decision
110
- # tree ("when shared vs runtime", "what to do if it fails").
97
+ # DON'T duplicate apx --help. Skills explain WHEN and WHY, not WHAT.
98
+ # Teach the decision tree ("shared vs runtime", "what to do if it fails").
111
99
 
112
- # DON'T leave TODOs in production skills. If a section is incomplete,
113
- # delete it from the skill and add it to spec/backlog/.
100
+ # DON'T leave TODOs in production skills. Delete incomplete sections;
101
+ # move them to spec/backlog/.
114
102
  ```
115
103
 
116
- ## Skill scaffolding (optional `<slug>/`)
104
+ ## Optional scaffolding
117
105
 
118
106
  ```
119
107
  skills/my-thing/
120
- ├── SKILL.md ← the body (always)
121
- ├── references/ ← markdown files the skill cites
122
- │ └── examples.md
123
- ├── assets/ images, JSON schemas, sample inputs
124
- └── scripts/ ← shell / node scripts the skill may shell out to
125
- └── verify.sh
108
+ ├── SKILL.md ← always
109
+ ├── references/ ← markdown the skill cites
110
+ ├── assets/ ← images, schemas, sample inputs
111
+ └── scripts/ shell/node helpers the skill shells out to
126
112
  ```
127
113
 
128
- The super-agent only sees `SKILL.md` automatically. `references/` and `scripts/` are addressable via paths from inside the body (e.g. "see references/examples.md"). Use this for skills with lots of supporting material.
129
-
130
- ## Existing APX skills — copy the style
114
+ Only `SKILL.md` is auto-loaded. Reference others by relative path from the body ("see references/examples.md").
131
115
 
132
- - `skills/apx-routine/SKILL.md`routine kind selection + pipeline.
133
- - `skills/apx-mcp/SKILL.md` — three-scope MCP configuration.
134
- - `skills/apx-task/SKILL.md` — TODO management.
135
- - `skills/apx-telegram/SKILL.md` — channel ↔ project ↔ agent wiring.
136
- - `skills/apx-runtime/SKILL.md` — external CLIs (claude-code, codex, …).
137
- - `skills/apx-sessions/SKILL.md` — cross-engine list, resume, summary, `--into apx`.
138
- - `skills/apx-voice/SKILL.md` — TTS engine setup.
139
- - `skills/apx-agent/SKILL.md` — per-project agents.
140
- - `skills/apx-project/SKILL.md` — project registration + typology.
116
+ ## Existing skills — mimic the style
141
117
 
142
- Pick the closest topic, mimic the structure, then write yours.
118
+ `skills/apx-routine`, `apx-mcp`, `apx-task`, `apx-telegram`, `apx-runtime`, `apx-sessions`, `apx-voice`, `apx-agent`, `apx-project`. Pick the closest topic, copy the structure.
143
119
 
144
120
  ## Maintainer contract
145
121
 
146
- `AGENTS.md` rule 6 (regenerated by `apx agent add/import`) requires skills to move in lockstep with feature changes. When you add or change APX behavior, update or add the skill in the same PR — especially under `skills/apx-*`.
122
+ `AGENTS.md` rule 6 (regenerated by `apx agent add/import`) requires skills to move in lockstep with feature changes. Update or add the skill in the same PR as the behavior change — especially `skills/apx-*`.
147
123
 
148
124
  ## Don't
149
125
 
150
- - Don't ship a skill without the frontmatter `description` — the loader can read the file but the trigger is silent.
151
- - Don't put secrets inside skills. They're meant to be read aloud by an LLM.
152
- - Don't reference filesystem paths that only exist on your machine — use `<repo>` or `~/.apx` placeholders.
153
- - Don't write skills in third person. The reader is the model. Write to it.
126
+ - Don't ship without frontmatter `description` — loader works, trigger is silent.
127
+ - Don't put secrets inside skills. They're read aloud by an LLM.
128
+ - Don't reference machine-only paths — use `<repo>` or `~/.apx` placeholders.
129
+ - Don't write in third person. The reader is the model. Write to it.
@@ -1,16 +1,16 @@
1
1
  ---
2
2
  name: apx-task
3
- description: Per-project TODO list. Load when the user wants to note, remind, list, or complete a task. Tasks are project-scoped, event-sourced, and addressable by short id prefix. Triggers: 'add a task', 'remind me to…', 'what's pending', 'mark as done'.
3
+ description: Per-project TODO list. Event-sourced, project-scoped, addressable by short id prefix. Load when user wants to note, remind, list, or complete a task. Triggers: 'add a task', 'remind me to…', 'what's pending', 'mark as done', 'open tasks'.
4
4
  ---
5
5
 
6
6
  # apx-task
7
7
 
8
- A `task` is a per-project TODO. Append-only JSONL event log per month under `~/.apx/projects/<apxId>/tasks/YYYY-MM.jsonl`. State is the fold of the event stream. Once created, a task lives forever — `done` and `drop` don't delete events, they record a state transition. `reopen` flips back to `open`.
8
+ A `task` is a per-project TODO. Append-only JSONL event log per month at `~/.apx/projects/<apxId>/tasks/YYYY-MM.jsonl`. State is the fold of the event stream. Once created a task lives forever — `done` and `drop` record state transitions, don't delete events. `reopen` flips back to `open`.
9
9
 
10
10
  ## Concrete CLI calls
11
11
 
12
12
  ```bash
13
- # Add — most common
13
+ # Add
14
14
  apx task add "Review the auth bug" --project iacrmar
15
15
  apx task add "Call the client" --project iacrmar --due 2026-05-30 --tag urgent
16
16
  apx task add "Demo for tester X" --project iacrmar --agent reviewer --tag demo --tag external --source cli
@@ -25,7 +25,7 @@ apx task list --project iacrmar --limit 5
25
25
 
26
26
  # Inspect / mutate
27
27
  apx task show t_abc123 --project iacrmar
28
- apx task show abc --project iacrmar # prefix match (≥3 chars), unique
28
+ apx task show abc --project iacrmar # prefix match (≥3 chars, unique)
29
29
  apx task done t_abc123 --project iacrmar --by manuel
30
30
  apx task drop t_abc123 --project iacrmar # archived (not "done")
31
31
  apx task reopen t_abc123 --project iacrmar
@@ -35,7 +35,7 @@ apx task patch t_abc123 --project iacrmar --tag bug --tag blocker # replaces
35
35
 
36
36
  ## ID format
37
37
 
38
- `t_` + 6 base36 chars (32-bit entropy → ~4B keyspace). Prefix matching works once you have 3 chars and the prefix uniquely identifies a task. If two tasks share a prefix, you get null — use a longer one.
38
+ `t_` + 6 base36 chars (~4B keyspace). Prefix matching works at ≥3 chars when the prefix is unique. If two tasks share a prefix you get null — use a longer one.
39
39
 
40
40
  ## Fields
41
41
 
@@ -43,36 +43,33 @@ apx task patch t_abc123 --project iacrmar --tag bug --tag blocker # replaces
43
43
  |---|---|---|
44
44
  | `title` | always | One imperative line. Required. |
45
45
  | `body` | optional | Longer notes. Markdown OK. |
46
- | `tags` | optional | Free-form strings. Used by `--tag` filter. |
47
- | `due` | optional | ISO date `YYYY-MM-DD`. Listing supports `--due-before`. |
48
- | `agent` | optional | Slug of an agent responsible. Used by `--agent` filter. |
49
- | `source` | auto/optional | Where the task came from (cli, telegram, super-agent). |
50
- | `state` | derived | `open` after create, `done` / `dropped` after their respective ops. |
46
+ | `tags` | optional | Free-form. Used by `--tag` filter. |
47
+ | `due` | optional | ISO `YYYY-MM-DD`. Supports `--due-before`. |
48
+ | `agent` | optional | Slug of responsible agent. Used by `--agent` filter. |
49
+ | `source` | auto/optional | Origin (cli, telegram, super-agent). |
50
+ | `state` | derived | `open` after create, `done`/`dropped` after ops. |
51
51
 
52
52
  ## Super-agent tools
53
53
 
54
- The super-agent has `create_task` and `list_tasks` tools. So a user message like "note that we need to close the auth bug in iacrmar tomorrow" makes the model call:
54
+ The super-agent has `create_task` and `list_tasks`. "Note that we need to close the auth bug in iacrmar tomorrow" model calls:
55
55
 
56
56
  ```json
57
57
  { "name": "create_task",
58
58
  "arguments": { "project": "iacrmar", "title": "Close the auth bug", "due": "<tomorrow>", "tags": ["bug"] } }
59
59
  ```
60
60
 
61
- When the user asks "what's pending in iacrmar?", the model calls `list_tasks({ project: "iacrmar" })`.
62
-
63
- If the user doesn't say which project, the model should `list_projects` first and ask which one — never assume. If the conversation has a project context (Telegram channel pinned to project), the model uses that.
61
+ "What's pending in iacrmar?" `list_tasks({ project: "iacrmar" })`. If user doesn't say which project, `list_projects` first and ask — never assume. If the channel has pinned project context (Telegram), use that.
64
62
 
65
63
  ## Anti-examples
66
64
 
67
65
  ```bash
68
66
  # DON'T add tasks without --project for real work.
69
67
  apx task add "Stuff" # falls back to first registered project (or default=0)
70
- # ↑ Will dump into a project you may not have meant. Always --project.
71
68
 
72
69
  # DON'T use `done` when the task is no longer relevant. Use `drop`.
73
- apx task done t_abc # implies "I completed this work"
74
- apx task drop t_abc # implies "this is no longer needed; archive without completion"
75
- # Reporting / metrics distinguish them.
70
+ apx task done t_abc # "I completed this work"
71
+ apx task drop t_abc # "no longer needed; archive without completion"
72
+ # Reporting/metrics distinguish them.
76
73
  ```
77
74
 
78
75
  ## Endpoint surface
@@ -90,6 +87,6 @@ GET /projects/:pid/tasks-summary → { open, done, dropped, overdue,
90
87
 
91
88
  ## Don't
92
89
 
93
- - Don't use tasks for reminders that need to *fire* — that's a future routine kind (`task-due-notify`, not built yet). Tasks are a list, not a scheduler.
94
- - Don't depend on `done` deleting the task. It doesn't. The event log stays.
95
- - Don't grep `~/.apx/projects/<id>/tasks/*.jsonl` for state — use `apx task list` or `getTask()`. The fold logic isn't trivial (later events can override fields).
90
+ - Don't use tasks for reminders that need to *fire* — that's a future routine kind (`task-due-notify`, not built). Tasks are a list, not a scheduler.
91
+ - Don't depend on `done` deleting the task. It doesn't. Event log stays.
92
+ - Don't grep `~/.apx/projects/<id>/tasks/*.jsonl` for state — use `apx task list` or `getTask()`. Fold logic isn't trivial (later events override fields).
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: apx-telegram
3
- description: How APX talks to Telegram — channels, project pinning, master agents, media. Load BEFORE configuring a new bot or routing — multi-channel is the only mode now, the root bot_token/chat_id fields are legacy.
3
+ description: APX Telegram plugin — channels, project pinning, master agents, media. Load BEFORE configuring a new bot or routing — multi-channel is the only mode, root bot_token/chat_id are legacy.
4
4
  ---
5
5
 
6
6
  # apx-telegram
7
7
 
8
- APX runs a Telegram plugin that polls `getUpdates` and routes messages. Config lives in `~/.apx/config.json → telegram`. The relationship to remember: **each channel can be pinned to a project and to a master agent**. Messages arriving on a pinned channel automatically run inside that project, optionally handled by a specific agent instead of the default APX super-agent.
8
+ APX polls `getUpdates` and routes messages. Config: `~/.apx/config.json → telegram`. Key model: **each channel can be pinned to a project and a master agent**. Messages on a pinned channel run inside that project, optionally handled by a specific agent instead of the default super-agent.
9
9
 
10
- ## The shape
10
+ ## Shape
11
11
 
12
12
  ```json
13
13
  {
@@ -15,61 +15,60 @@ APX runs a Telegram plugin that polls `getUpdates` and routes messages. Config l
15
15
  "enabled": true,
16
16
  "poll_interval_ms": 1500,
17
17
  "route_to_agent": "", // global default master agent (empty = super-agent)
18
- "respond_with_engine": true, // global default for "should the LLM auto-reply?"
18
+ "respond_with_engine": true, // global default auto-reply flag
19
19
  "channels": [
20
20
  {
21
21
  "name": "default",
22
22
  "bot_token": "<from BotFather>",
23
- "chat_id": "<your numeric chat id>",
24
- "project": "iacrmar", // optional: pin this channel to that project
25
- "route_to_agent": "reviewer", // optional: this agent handles messages on this channel
26
- "respond_with_engine": true, // optional: override the global default
27
- "owner_user_id": "123456789" // optional: per-channel owner (set via `apx telegram owner`)
23
+ "chat_id": "<numeric chat id>",
24
+ "project": "iacrmar", // optional: pin to project
25
+ "route_to_agent": "reviewer", // optional: per-channel agent
26
+ "respond_with_engine": true, // optional: override global
27
+ "owner_user_id": "123456789" // optional: via `apx telegram owner`
28
28
  }
29
29
  ],
30
- "contacts": [], // global roster (user_id → role); see `apx telegram contacts`
31
- "roles": {} // role → allowed tools; see `apx telegram roles`
30
+ "contacts": [], // global roster (user_id → role)
31
+ "roles": {} // role → allowed tools
32
32
  }
33
33
  }
34
34
  ```
35
35
 
36
- The old `telegram.bot_token` / `telegram.chat_id` at the root are **legacy**. Don't write to them. If a config still has them and `channels[]` is empty, APX migrates them into `channels[0]` automatically with a warning on first read.
36
+ Root `telegram.bot_token` / `telegram.chat_id` are **legacy**. Don't write them. If a config still has them and `channels[]` is empty, APX migrates them into `channels[0]` automatically on first read.
37
37
 
38
38
  ## Concrete CLI calls
39
39
 
40
40
  ```bash
41
- # Print the config template to get started
42
- apx telegram setup # note: still emits root bot_token/chat_id — prefer channels[] below
41
+ apx telegram setup # template (still emits legacy root fields — prefer channels[])
43
42
 
44
43
  # Channels CRUD
45
- apx telegram channel add # interactive wizard
44
+ apx telegram channel add # interactive
46
45
  apx telegram channel add clientes --bot-token <T> --chat-id <C> --project iacrmar --agent reviewer
47
- apx telegram channel list # alias: ls
48
- apx telegram channel show clientes # alias: get
46
+ apx telegram channel list # alias: ls
47
+ apx telegram channel show clientes # alias: get
49
48
  apx telegram channel set clientes --project iacrmar
50
49
  apx telegram channel set clientes --agent reviewer
51
50
  apx telegram channel set clientes --respond-engine false
52
51
  apx telegram channel unset clientes --project --agent
53
- apx telegram channel remove clientes # alias: rm
54
- apx telegram owner clientes <user_id> # set the per-channel owner
52
+ apx telegram channel remove clientes # alias: rm
53
+ apx telegram owner clientes <user_id>
55
54
 
56
55
  # Contacts roster + roles (global; gate which tools a sender may trigger)
57
- apx telegram contacts # list the global roster
56
+ apx telegram contacts
58
57
  apx telegram contacts rm <user_id>
59
- apx telegram role <user_id> <role> # assign a role to a contact
60
- apx telegram roles # list role → tools mappings
61
- apx telegram roles set <name> --tools a,b,c # or --tools '*' for all
58
+ apx telegram role <user_id> <role>
59
+ apx telegram roles
60
+ apx telegram roles set <name> --tools a,b,c # or --tools '*'
62
61
  apx telegram roles rm <name>
63
62
 
64
- # Polling lifecycle (rarely needed — autostart with daemon)
63
+ # Polling lifecycle (autostarts with daemon)
65
64
  apx telegram start
66
65
  apx telegram stop
67
66
  apx telegram status
68
67
 
69
- # Sending (defaults to first configured channel; use --chat for explicit chat id)
68
+ # Sending (defaults to first configured channel)
70
69
  apx telegram send "text"
71
70
  apx telegram send "text" --chat 123456789
72
- apx telegram send "text" --interrupt # bypass the pending-agent queue (also: --force)
71
+ apx telegram send "text" --interrupt # bypass pending-agent queue (also: --force)
73
72
 
74
73
  # Media (daemon HTTP API — no dedicated CLI subcommand yet)
75
74
  curl -X POST http://127.0.0.1:7430/telegram/send_photo \
@@ -82,50 +81,40 @@ curl -X POST http://127.0.0.1:7430/telegram/send_voice \
82
81
  -d '{"audio":"/abs/path.ogg","duration":5,"channel":"default"}'
83
82
  ```
84
83
 
85
- Every `channel` CRUD write triggers `POST /admin/reload` so the polling plugin picks up the new wiring without a daemon restart.
84
+ Every `channel` CRUD write triggers `POST /admin/reload` so polling picks up the new wiring without restart.
86
85
 
87
- ## What "pin to project" actually does
86
+ ## What "pin to project" does
88
87
 
89
- When a message arrives on a channel with `project: "iacrmar"`:
88
+ On a message to a channel with `project: "iacrmar"`:
90
89
  1. The super-agent invocation gets `channelMeta.projectId = <iacrmar's id>`.
91
- 2. The system prompt resolves project-scoped data (agents, MCPs, memory) for that turn.
92
- 3. The agent can call tools (`list_agents`, `list_tasks`, `create_task`, …) and they default to that project — the user doesn't have to say "in iacrmar" every message.
90
+ 2. The system prompt resolves project-scoped agents, MCPs, memory.
91
+ 3. Tools (`list_agents`, `list_tasks`, `create_task`, …) default to that project — no need to repeat "in iacrmar" each message.
93
92
 
94
- ## What "master agent" actually does
93
+ ## What "master agent" does
95
94
 
96
- With `route_to_agent: "reviewer"` on the channel, incoming messages go through `/projects/:pid/agents/reviewer/chat` instead of `/super-agent/chat`. The agent's `AGENT.md` system prompt + memory is used. No tools (project agents are `exec_agent`-shaped — text in, text out). Single LLM call.
97
-
98
- Use this when you want a Telegram channel to feel like talking to a specific persona (a reviewer, a sales agent, a customer support agent) instead of the general APX assistant.
99
-
100
- If `route_to_agent` is empty: the channel goes through the super-agent (default APX mode).
95
+ With `route_to_agent: "reviewer"`, messages go through `/projects/:pid/agents/reviewer/chat` instead of `/super-agent/chat`. The agent's `AGENT.md` + memory is used. No tools (project agents are `exec_agent`-shaped — text in, text out). Single LLM call. Use this for persona channels (reviewer, sales, support) instead of the general assistant. Empty = super-agent (default).
101
96
 
102
97
  ## Anti-examples
103
98
 
104
99
  ```bash
105
- # DON'T write to telegram.bot_token / telegram.chat_id directly.
106
- apx config set telegram.bot_token "<T>"
107
- # ↑ Those fields are legacy. Use channels[] via `apx telegram channel`.
100
+ # DON'T write to legacy root fields.
101
+ apx config set telegram.bot_token "<T>" # ← use channels[] via `apx telegram channel`
108
102
 
109
- # DON'T add the same project to two channels expecting routing magic.
110
- # A channel pins messages TO a project, not the other way around. The same
111
- # project can be addressed from multiple channelsfine. But that doesn't
112
- # unify the conversation contexts; each channel has its own message log.
103
+ # DON'T expect routing magic from same project on two channels.
104
+ # A channel pins messages TO a project, not vice-versa. Same project from multiple
105
+ # channels is fine, but each channel has its own message log no unified context.
113
106
 
114
107
  # DON'T set route_to_agent to a non-existent slug.
115
- apx telegram channel set default --agent nope
116
- # ↑ Will silently route to a 404 — the channel's messages won't get a reply
117
- # until you fix it. `apx telegram channel show <name>` to verify.
108
+ apx telegram channel set default --agent nope # silently 404s; verify with channel show
118
109
  ```
119
110
 
120
111
  ## Multiple bots, one APX
121
112
 
122
- `channels[]` supports multiple `{bot_token, chat_id}` pairs. Each can be a different bot OR the same bot with different chats. The plugin polls each in parallel. Project / agent pinning is per-channel.
123
-
124
- This is how you wire "I have a client A bot, a personal bot, and a notifications-only bot": three channels, three (possibly) different bots, distinct project pins.
113
+ `channels[]` supports multiple `{bot_token, chat_id}` pairs different bots OR the same bot with different chats. Plugin polls each in parallel; project/agent pinning is per-channel. Wire "client A bot, personal bot, notifications-only bot" as three channels.
125
114
 
126
115
  ## Don't
127
116
 
128
- - Don't write to `telegram.bot_token` / `telegram.chat_id` at root.
129
- - Don't expect `apx telegram send` to target a project — it sends to a *chat id* (or the channel's configured `chat_id`). Use `apx telegram channel show <name>` to verify wiring.
130
- - Don't set `respond_with_engine: false` and then wonder why messages aren't getting replies. That flag turns auto-reply off for the channel.
131
- - Don't forget that the Telegram plugin only fires on chat IDs you've listed. Messages from other chats are ignored.
117
+ - Write to `telegram.bot_token` / `telegram.chat_id` at root.
118
+ - Expect `apx telegram send` to target a project — it targets a *chat id*. Verify wiring with `apx telegram channel show <name>`.
119
+ - Set `respond_with_engine: false` and then wonder why replies stop. That flag disables auto-reply for the channel.
120
+ - Forget the plugin only fires on listed chat IDs. Other chats are ignored.