@agfpd/iapeer 0.4.22 → 0.4.23

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 CHANGED
@@ -10,6 +10,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.4.23] - 2026-06-22
14
+
15
+ ### Added
16
+
17
+ - **`iapeer enable telegram <peer>`** — a discoverability alias for `iapeer connect telegram
18
+ <peer>` (give an existing peer a Telegram bot face). A layperson reaches for "enable
19
+ telegram", not "connect"; both now work and route through the same flow (bot add →
20
+ interface → router restart; asks only the token). telegram is a CHANNEL, not a marketplace
21
+ plugin, so the alias routes to the connect flow, not `enableCapability`. The `connect`
22
+ help line documents the alias. No telegram-runtime change (the mechanism already worked) —
23
+ purely CLI discoverability.
24
+
13
25
  ## [0.4.22] - 2026-06-22
14
26
 
15
27
  ### Added
@@ -340,7 +352,8 @@ Initial public release — the foundation core of the iapeer multi-agent ecosyst
340
352
  - **Heterogeneous peers** — AI agents (Claude, Codex), humans (Telegram), and services
341
353
  (timer = cron, watcher = event) are all first-class and addressed the same way.
342
354
 
343
- [Unreleased]: https://github.com/agfpd/iapeer/compare/v0.4.22...HEAD
355
+ [Unreleased]: https://github.com/agfpd/iapeer/compare/v0.4.23...HEAD
356
+ [0.4.23]: https://github.com/agfpd/iapeer/compare/v0.4.22...v0.4.23
344
357
  [0.4.22]: https://github.com/agfpd/iapeer/compare/v0.4.21...v0.4.22
345
358
  [0.4.21]: https://github.com/agfpd/iapeer/compare/v0.4.20...v0.4.21
346
359
  [0.4.20]: https://github.com/agfpd/iapeer/compare/v0.4.19...v0.4.20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agfpd/iapeer",
3
- "version": "0.4.22",
3
+ "version": "0.4.23",
4
4
  "description": "Foundation core for the iapeer multi-agent ecosystem: identity, registry, storage, codec.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "agfpd",
package/src/cli/index.ts CHANGED
@@ -875,6 +875,41 @@ export async function removePeerCli(
875
875
  }
876
876
  }
877
877
 
878
+ /**
879
+ * `connect telegram <peer>` core — give a peer a Telegram bot face (interfaces.telegram).
880
+ * Shared by the `connect telegram` verb AND the `enable telegram <peer>` discoverability
881
+ * alias (telegram is a CHANNEL, not a marketplace plugin, so both route here, not through
882
+ * enableCapability). Returns the process exit code. The human owes only the token (prompted
883
+ * when omitted on a tty); the system does bot-add → interface → router restart.
884
+ */
885
+ async function connectTelegramVerb(
886
+ peer: string,
887
+ token: string | undefined,
888
+ env: NodeJS.ProcessEnv,
889
+ out: (s: string) => void,
890
+ errOut: (s: string) => void,
891
+ ): Promise<number> {
892
+ const { connectTelegram } = await import('../connect/index.ts')
893
+ const r = await connectTelegram({ peer, token, env })
894
+ if (r.state === 'noop-same-token') {
895
+ out(`connect telegram ${r.peer}: ${r.detail}\n`)
896
+ return 0
897
+ }
898
+ if (r.state !== 'connected') {
899
+ errOut(`connect telegram ${r.peer}: ${r.state}${r.detail ? ` — ${r.detail}` : ''}\n`)
900
+ return 1
901
+ }
902
+ const rs = r.restart!
903
+ out(`bot ${r.username ?? `for "${r.peer}"`} added + interfaced to "${r.peer}"\n`)
904
+ out(
905
+ rs.state === 'restarted'
906
+ ? `router restarted — credentials loaded\n`
907
+ : `router restart ${rs.state}${rs.detail ? ` — ${rs.detail}` : ''} (the channel stays dead until the router restarts)\n`,
908
+ )
909
+ out(`activation: send the bot ${r.username ?? '(see @BotFather)'} its FIRST message — Telegram does not let a bot start the chat\n`)
910
+ return rs.state === 'restarted' ? 0 : 1
911
+ }
912
+
878
913
  // ─────────────────────────────────────────────────────────────────────────────
879
914
  // rename — first-class peer-identity rename (parity with remove/create). Wraps
880
915
  // renamePeer (registry + per-cwd profile, atomic, inside the lock) and KEEPS the
@@ -1168,7 +1203,7 @@ const VERBS: ReadonlyArray<{ sig: string; desc: string }> = [
1168
1203
  desc: 'manual IAP send (fallback)',
1169
1204
  },
1170
1205
  { sig: '<runtime>', desc: "launch the cwd's peer FRESH; on a TTY drop into it (like attach), else detached" },
1171
- { sig: 'connect telegram <peer> [--token <t>]', desc: 'attach a telegram bot to a peer (bot add → interface → router restart; asks only the token)' },
1206
+ { sig: 'connect telegram <peer> [--token <t>]', desc: 'attach a telegram bot to a peer (bot add → interface → router restart; asks only the token). Alias: `iapeer enable telegram <peer>`' },
1172
1207
  { sig: 'enable <plugin> [peer] [--no-setup]', desc: 'install + enable an agfpd capability for a peer' },
1173
1208
  {
1174
1209
  sig: 'new <peer> [runtime]',
@@ -2287,31 +2322,16 @@ export async function runCli(argv: string[], env: NodeJS.ProcessEnv = process.en
2287
2322
  // alias/bot-add/interface/router-restart are resolved by the system. The
2288
2323
  // FIRST message from the human to the bot activates the chat (platform rule).
2289
2324
  if (positionals[0] !== 'telegram' || !positionals[1]) return argErr(errOut, 'connect needs "telegram <peer>" — usage: iapeer connect telegram <peer> [--token <t>] (e.g. iapeer connect telegram boris)')
2290
- const { connectTelegram } = await import('../connect/index.ts')
2291
- const r = await connectTelegram({
2292
- peer: positionals[1],
2293
- token: typeof flags.token === 'string' ? flags.token : undefined,
2294
- env,
2295
- })
2296
- if (r.state === 'noop-same-token') {
2297
- out(`connect telegram ${r.peer}: ${r.detail}\n`)
2298
- return 0
2299
- }
2300
- if (r.state !== 'connected') {
2301
- errOut(`connect telegram ${r.peer}: ${r.state}${r.detail ? ` — ${r.detail}` : ''}\n`)
2302
- return 1
2303
- }
2304
- const rs = r.restart!
2305
- out(`bot ${r.username ?? `for "${r.peer}"`} added + interfaced to "${r.peer}"\n`)
2306
- out(
2307
- rs.state === 'restarted'
2308
- ? `router restarted — credentials loaded\n`
2309
- : `router restart ${rs.state}${rs.detail ? ` — ${rs.detail}` : ''} (the channel stays dead until the router restarts)\n`,
2310
- )
2311
- out(`activation: send the bot ${r.username ?? '(see @BotFather)'} its FIRST message — Telegram does not let a bot start the chat\n`)
2312
- return rs.state === 'restarted' ? 0 : 1
2325
+ return await connectTelegramVerb(positionals[1], typeof flags.token === 'string' ? flags.token : undefined, env, out, errOut)
2313
2326
  }
2314
2327
  case 'enable': {
2328
+ // DISCOVERABILITY ALIAS: `enable telegram <peer>` → `connect telegram <peer>`
2329
+ // (a layperson reaches for "enable telegram"; telegram is a CHANNEL, not a
2330
+ // marketplace plugin, so it routes to the connect flow, NOT enableCapability).
2331
+ if (positionals[0] === 'telegram') {
2332
+ if (!positionals[1]) return argErr(errOut, 'enable telegram needs a peer — usage: iapeer enable telegram <peer> [--token <t>] (alias of `iapeer connect telegram <peer>`)')
2333
+ return await connectTelegramVerb(positionals[1], typeof flags.token === 'string' ? flags.token : undefined, env, out, errOut)
2334
+ }
2315
2335
  // Per-peer capability install (contract Установка §3): install <plugin>@agfpd
2316
2336
  // per-runtime (claude project-scope IN the peer cwd / codex global) + enable +
2317
2337
  // call the plugin's `setup` ONLY if its iapeer.json declares it. Idempotent and