pi-discord-bot 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -85,22 +85,26 @@ Unsupported in Discord:
85
85
 
86
86
  ### Use as a Pi package skill
87
87
 
88
- From npm:
88
+ 1. **Install Pi** — follow the [Pi quick start guide](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent#quick-start) and configure your provider auth (e.g. `pi login`).
89
+
90
+ 2. **Install this package** — run in your terminal:
89
91
 
90
92
  ```bash
91
93
  pi install npm:pi-discord-bot
92
94
  ```
93
95
 
94
- From a local source checkout:
96
+ 3. **Start Pi and ask your agent** — just run `pi` and ask it to help you set up the Discord bot:
95
97
 
96
- ```bash
97
- pi install /absolute/path/to/pi-discord-bot
98
+ ```text
99
+ /skill:pi-discord-bot help me set up the bot
98
100
  ```
99
101
 
100
- Then start Pi and use:
102
+ The Pi agent will walk you through creating your Discord app, configuring the token, setting up the policy file, and starting the bot. You don't need to memorize any setup steps — just ask.
101
103
 
102
- ```text
103
- /skill:pi-discord-bot
104
+ Alternatively, from a local source checkout:
105
+
106
+ ```bash
107
+ pi install /absolute/path/to/pi-discord-bot
104
108
  ```
105
109
 
106
110
  See also:
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "allowDMs": true,
3
- "guildIds": ["123456789012345678"],
4
- "channelIds": ["234567890123456789"],
3
+ "guildIds": [],
4
+ "channelIds": [],
5
5
  "mentionMode": "mention-only",
6
6
  "slashCommands": {
7
- "enabled": true,
8
- "guildId": "123456789012345678"
7
+ "enabled": true
9
8
  }
10
9
  }
@@ -1,6 +1,5 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { loadSkillsFromDir } from "@mariozechner/pi-coding-agent";
4
3
  export function getMemory(conversationDir) {
5
4
  const parts = [];
6
5
  for (const path of [join(conversationDir, "..", "MEMORY.md"), join(conversationDir, "MEMORY.md")]) {
@@ -12,15 +11,6 @@ export function getMemory(conversationDir) {
12
11
  }
13
12
  return parts.join("\n\n") || "(no memory yet)";
14
13
  }
15
- export function loadDiscordSkills(conversationDir) {
16
- const map = new Map();
17
- for (const dir of [join(conversationDir, "..", "skills"), join(conversationDir, "skills")]) {
18
- for (const skill of loadSkillsFromDir({ dir, source: dir.includes("/skills") ? "workspace" : "channel" }).skills) {
19
- map.set(skill.name, skill);
20
- }
21
- }
22
- return [...map.values()];
23
- }
24
14
  export function buildAppendSystemPrompt(workspaceDir, conversationKey, memory) {
25
15
  return `## Surface
26
16
  - You are replying through a Discord harness.
@@ -65,7 +65,7 @@ export function wireSessionUpdates(session, runState) {
65
65
  });
66
66
  }
67
67
  export async function runAgentTurn(params) {
68
- const { ctx, conversationDir, scratchDir, sessionManager, agent, session, runState } = params;
68
+ const { ctx, conversationDir, scratchDir, sessionManager, agent, session, runState, resourceLoader } = params;
69
69
  await mkdir(scratchDir, { recursive: true });
70
70
  await mkdir(conversationDir, { recursive: true });
71
71
  syncLogToSessionManager(sessionManager, conversationDir, ctx.message.messageId);
@@ -89,6 +89,15 @@ export async function runAgentTurn(params) {
89
89
  let prompt = `[${ctx.message.userName}]: ${ctx.message.text}`;
90
90
  if (otherAttachments.length > 0)
91
91
  prompt += `\n\n<discord_attachments>\n${otherAttachments.join("\n")}\n</discord_attachments>`;
92
+ // Reload resources (extensions, skills, prompts, themes) from installed packages
93
+ if (resourceLoader) {
94
+ try {
95
+ await resourceLoader.reload();
96
+ }
97
+ catch (err) {
98
+ log.warn("resource reload failed", err instanceof Error ? err.message : String(err));
99
+ }
100
+ }
92
101
  await ctx.setTyping(true);
93
102
  await ctx.setWorking(true);
94
103
  await session.prompt(prompt, imageAttachments.length > 0 ? { images: imageAttachments } : undefined);
package/dist/agent.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Agent } from "@mariozechner/pi-agent-core";
2
- import { AgentSession, AuthStorage, convertToLlm, createCodingTools, createExtensionRuntime, ModelRegistry, SessionManager, } from "@mariozechner/pi-coding-agent";
2
+ import { AgentSession, AuthStorage, convertToLlm, createCodingTools, DefaultResourceLoader, ModelRegistry, SessionManager, } from "@mariozechner/pi-coding-agent";
3
3
  import { join } from "node:path";
4
4
  import { createDiscordSettingsManager } from "./context.js";
5
5
  import { resolveInitialModel, formatModel } from "./agent-models.js";
6
- import { buildAppendSystemPrompt, getMemory, loadDiscordSkills } from "./agent-prompt.js";
6
+ import { buildAppendSystemPrompt, getMemory } from "./agent-prompt.js";
7
7
  import { createDiscordCustomTools } from "./agent-tools.js";
8
8
  import { createSessionOps } from "./agent-session-ops.js";
9
9
  import { runAgentTurn, wireSessionUpdates } from "./agent-runner.js";
@@ -26,19 +26,16 @@ function createRunner(workspaceDir, conversationKey) {
26
26
  const modelRegistry = ModelRegistry.create(authStorage);
27
27
  const sessionManager = SessionManager.open(contextFile, conversationDir);
28
28
  const settingsManager = createDiscordSettingsManager(workspaceDir);
29
- const skills = loadDiscordSkills(conversationDir);
30
29
  let appendSystemPrompt = buildAppendSystemPrompt(workspaceDir, conversationKey, getMemory(conversationDir));
31
- const resourceLoader = {
32
- getExtensions: () => ({ extensions: [], errors: [], runtime: createExtensionRuntime() }),
33
- getSkills: () => ({ skills, diagnostics: [] }),
34
- getPrompts: () => ({ prompts: [], diagnostics: [] }),
35
- getThemes: () => ({ themes: [], diagnostics: [] }),
36
- getAgentsFiles: () => ({ agentsFiles: [] }),
37
- getSystemPrompt: () => undefined,
38
- getAppendSystemPrompt: () => [appendSystemPrompt],
39
- extendResources: () => { },
40
- reload: async () => { },
41
- };
30
+ const resourceLoader = new DefaultResourceLoader({
31
+ cwd: scratchDir,
32
+ settingsManager,
33
+ additionalSkillPaths: [
34
+ join(workspaceDir, "skills"),
35
+ join(conversationDir, "skills"),
36
+ ],
37
+ appendSystemPrompt,
38
+ });
42
39
  const runState = {
43
40
  ctx: null,
44
41
  queue: Promise.resolve(),
@@ -83,7 +80,7 @@ function createRunner(workspaceDir, conversationKey) {
83
80
  return {
84
81
  async run(ctx) {
85
82
  appendSystemPrompt = buildAppendSystemPrompt(workspaceDir, conversationKey, getMemory(conversationDir));
86
- return runAgentTurn({ ctx, conversationDir, scratchDir, sessionManager, agent, session, runState });
83
+ return runAgentTurn({ ctx, conversationDir, scratchDir, sessionManager, agent, session, runState, resourceLoader });
87
84
  },
88
85
  abort() {
89
86
  void session.abort();
package/dist/discord.js CHANGED
@@ -110,13 +110,18 @@ export class DiscordBot {
110
110
  return;
111
111
  const commands = buildSlashCommands();
112
112
  const guildId = policy.slashCommands?.guildId;
113
- if (guildId) {
114
- await this.client.application.commands.set(commands, guildId);
115
- log.info(`registered slash commands in guild ${guildId}`);
113
+ try {
114
+ if (guildId) {
115
+ await this.client.application.commands.set(commands, guildId);
116
+ log.info(`registered slash commands in guild ${guildId}`);
117
+ }
118
+ else {
119
+ await this.client.application.commands.set(commands);
120
+ log.info("registered global slash commands");
121
+ }
116
122
  }
117
- else {
118
- await this.client.application.commands.set(commands);
119
- log.info("registered global slash commands");
123
+ catch (err) {
124
+ log.warn("slash command registration failed (bot will continue without slash commands)", err instanceof Error ? err.message : String(err));
120
125
  }
121
126
  }
122
127
  async onMessage(message) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-discord-bot",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "A small Discord harness built around Pi primitives.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -52,12 +52,14 @@
52
52
  "prepublishOnly": "npm run build && npm test"
53
53
  },
54
54
  "dependencies": {
55
- "@mariozechner/pi-agent-core": "^0.64.0",
56
- "@mariozechner/pi-ai": "^0.64.0",
57
- "@mariozechner/pi-coding-agent": "^0.64.0",
58
- "@sinclair/typebox": "^0.34.41",
59
55
  "discord.js": "^14.19.3"
60
56
  },
57
+ "peerDependencies": {
58
+ "@mariozechner/pi-agent-core": "*",
59
+ "@mariozechner/pi-ai": "*",
60
+ "@mariozechner/pi-coding-agent": "*",
61
+ "@sinclair/typebox": "*"
62
+ },
61
63
  "devDependencies": {
62
64
  "@types/node": "^24.3.0",
63
65
  "tsx": "^4.19.2",