owpenwork 0.1.14 → 0.1.16

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/dist/bridge.js CHANGED
@@ -31,8 +31,20 @@ export async function startBridge(config, logger, reporter) {
31
31
  store.seedAllowlist("telegram", config.allowlist.telegram);
32
32
  store.seedAllowlist("whatsapp", [...config.whatsappAllowFrom].filter((entry) => entry !== "*"));
33
33
  store.prunePairingRequests();
34
+ logger.debug({
35
+ configPath: config.configPath,
36
+ opencodeUrl: config.opencodeUrl,
37
+ opencodeDirectory: config.opencodeDirectory,
38
+ telegramEnabled: config.telegramEnabled,
39
+ telegramTokenPresent: Boolean(config.telegramToken),
40
+ whatsappEnabled: config.whatsappEnabled,
41
+ groupsEnabled: config.groupsEnabled,
42
+ permissionMode: config.permissionMode,
43
+ toolUpdatesEnabled: config.toolUpdatesEnabled,
44
+ }, "bridge config");
34
45
  const adapters = new Map();
35
46
  if (config.telegramEnabled && config.telegramToken) {
47
+ logger.debug("telegram adapter enabled");
36
48
  adapters.set("telegram", createTelegramAdapter(config, logger, handleInbound));
37
49
  }
38
50
  else {
@@ -40,6 +52,7 @@ export async function startBridge(config, logger, reporter) {
40
52
  reportStatus?.("Telegram adapter disabled.");
41
53
  }
42
54
  if (config.whatsappEnabled) {
55
+ logger.debug("whatsapp adapter enabled");
43
56
  adapters.set("whatsapp", createWhatsAppAdapter(config, logger, handleInbound, { printQr: true, onStatus: reportStatus }));
44
57
  }
45
58
  else {
@@ -241,6 +254,7 @@ export async function startBridge(config, logger, reporter) {
241
254
  if (!adapter)
242
255
  return;
243
256
  const kind = options.kind ?? "system";
257
+ logger.debug({ channel, peerId, kind, length: text.length }, "sendText requested");
244
258
  if (options.display !== false) {
245
259
  reporter?.onOutbound?.({ channel, peerId, text, kind });
246
260
  }
@@ -255,6 +269,13 @@ export async function startBridge(config, logger, reporter) {
255
269
  if (!adapter)
256
270
  return;
257
271
  let inbound = message;
272
+ logger.debug({
273
+ channel: inbound.channel,
274
+ peerId: inbound.peerId,
275
+ fromMe: inbound.fromMe,
276
+ length: inbound.text.length,
277
+ preview: truncateText(inbound.text.trim(), 120),
278
+ }, "inbound received");
258
279
  logger.info({ channel: inbound.channel, peerId: inbound.peerId, length: inbound.text.length }, "received message");
259
280
  const peerKey = inbound.channel === "whatsapp" ? normalizeWhatsAppId(inbound.peerId) : inbound.peerId;
260
281
  if (inbound.channel === "whatsapp") {
@@ -264,6 +285,7 @@ export async function startBridge(config, logger, reporter) {
264
285
  const allowAll = config.whatsappDmPolicy === "open" || config.whatsappAllowFrom.has("*");
265
286
  const isSelf = Boolean(inbound.fromMe && config.whatsappSelfChatMode);
266
287
  const allowed = allowAll || isSelf || store.isAllowed("whatsapp", peerKey);
288
+ logger.debug({ allowAll, isSelf, allowed, dmPolicy: config.whatsappDmPolicy, peerKey }, "whatsapp allowlist check");
267
289
  if (!allowed) {
268
290
  if (config.whatsappDmPolicy === "allowlist") {
269
291
  await sendText(inbound.channel, inbound.peerId, "Access denied. Ask the owner to allowlist your number.", { kind: "system" });
@@ -286,6 +308,7 @@ export async function startBridge(config, logger, reporter) {
286
308
  }
287
309
  else if (config.allowlist[inbound.channel].size > 0) {
288
310
  if (!store.isAllowed(inbound.channel, peerKey)) {
311
+ logger.debug({ channel: inbound.channel, peerKey }, "telegram allowlist denied");
289
312
  await sendText(inbound.channel, inbound.peerId, "Access denied.", { kind: "system" });
290
313
  return;
291
314
  }
@@ -298,6 +321,12 @@ export async function startBridge(config, logger, reporter) {
298
321
  });
299
322
  const session = store.getSession(inbound.channel, peerKey);
300
323
  const sessionID = session?.session_id ?? (await createSession({ ...inbound, peerId: peerKey }));
324
+ logger.debug({
325
+ sessionID,
326
+ channel: inbound.channel,
327
+ peerId: inbound.peerId,
328
+ reused: Boolean(session?.session_id),
329
+ }, "session resolved");
301
330
  enqueue(sessionID, async () => {
302
331
  const runState = {
303
332
  sessionID,
@@ -310,20 +339,29 @@ export async function startBridge(config, logger, reporter) {
310
339
  reportThinking(runState);
311
340
  startTyping(runState);
312
341
  try {
342
+ logger.debug({ sessionID, length: inbound.text.length }, "prompt start");
313
343
  const response = await client.session.prompt({
314
344
  sessionID,
315
345
  parts: [{ type: "text", text: inbound.text }],
316
346
  });
317
347
  const parts = response.parts ?? [];
348
+ const textParts = parts.filter((part) => part.type === "text" && !part.ignored);
349
+ logger.debug({
350
+ sessionID,
351
+ partCount: parts.length,
352
+ textCount: textParts.length,
353
+ }, "prompt response");
318
354
  const reply = parts
319
355
  .filter((part) => part.type === "text" && !part.ignored)
320
356
  .map((part) => part.text ?? "")
321
357
  .join("\n")
322
358
  .trim();
323
359
  if (reply) {
360
+ logger.debug({ sessionID, replyLength: reply.length }, "reply built");
324
361
  await sendText(inbound.channel, inbound.peerId, reply, { kind: "reply" });
325
362
  }
326
363
  else {
364
+ logger.debug({ sessionID }, "reply empty");
327
365
  await sendText(inbound.channel, inbound.peerId, "No response generated. Try again.", {
328
366
  kind: "system",
329
367
  });
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import { createLogger } from "./logger.js";
10
10
  import { createClient } from "./opencode.js";
11
11
  import { truncateText } from "./text.js";
12
12
  import { loginWhatsApp, unpairWhatsApp } from "./whatsapp.js";
13
- const VERSION = "0.1.14";
13
+ const VERSION = "0.1.16";
14
14
  const STEP_OPTIONS = [
15
15
  {
16
16
  value: "config",
@@ -54,12 +54,14 @@ function parseSelections(raw) {
54
54
  .filter((item) => STEP_SET.has(item));
55
55
  return selections.length ? selections : [];
56
56
  }
57
- function defaultSelections(configExists, whatsappLinked) {
57
+ function defaultSelections(configExists, whatsappLinked, telegramLinked) {
58
58
  const selections = [];
59
59
  if (!configExists)
60
60
  selections.push("config");
61
61
  if (!whatsappLinked)
62
62
  selections.push("whatsapp");
63
+ if (!telegramLinked)
64
+ selections.push("telegram");
63
65
  selections.push("start");
64
66
  return selections;
65
67
  }
@@ -182,6 +184,19 @@ async function runSetupWizard(config, options) {
182
184
  allowFrom = allowFrom.length ? allowFrom : ["*"];
183
185
  }
184
186
  }
187
+ const currentWorkspace = config.configFile.opencodeDirectory ?? config.opencodeDirectory;
188
+ const keepDefault = unwrap(await confirm({
189
+ message: `Use this OpenCode workspace? (${currentWorkspace})`,
190
+ initialValue: true,
191
+ }));
192
+ if (!keepDefault) {
193
+ const workspace = unwrap(await text({
194
+ message: "OpenCode workspace path",
195
+ placeholder: "/path/to/workspace",
196
+ validate: (value) => (String(value ?? "").trim() ? undefined : "Path required"),
197
+ }));
198
+ next.opencodeDirectory = workspace.trim();
199
+ }
185
200
  next.channels = next.channels ?? {};
186
201
  next.channels.whatsapp = {
187
202
  dmPolicy,
@@ -275,7 +290,7 @@ async function runGuidedFlow(pathArg, opts) {
275
290
  unwrap(await multiselect({
276
291
  message: "Select what to set up",
277
292
  options: STEP_OPTIONS,
278
- initialValues: defaultSelections(configExists, whatsappLinked),
293
+ initialValues: defaultSelections(configExists, whatsappLinked, Boolean(config.telegramToken)),
279
294
  required: false,
280
295
  }));
281
296
  const selectedSteps = Array.isArray(selections) ? selections : [];
package/dist/config.js CHANGED
@@ -118,16 +118,16 @@ function parseAllowlist(env) {
118
118
  }
119
119
  export function loadConfig(env = process.env, options = {}) {
120
120
  const requireOpencode = options.requireOpencode ?? false;
121
- const opencodeDirectory = env.OPENCODE_DIRECTORY?.trim() ?? "";
122
- if (!opencodeDirectory && requireOpencode) {
123
- throw new Error("OPENCODE_DIRECTORY is required");
124
- }
125
- const resolvedDirectory = opencodeDirectory || process.cwd();
126
121
  const dataDir = expandHome(env.OWPENBOT_DATA_DIR ?? "~/.owpenbot");
127
122
  const dbPath = expandHome(env.OWPENBOT_DB_PATH ?? path.join(dataDir, "owpenbot.db"));
128
123
  const logFile = expandHome(env.OWPENBOT_LOG_FILE ?? path.join(dataDir, "logs", "owpenbot.log"));
129
124
  const configPath = resolveConfigPath(dataDir, env);
130
125
  const { config: configFile } = readConfigFile(configPath);
126
+ const opencodeDirectory = env.OPENCODE_DIRECTORY?.trim() || configFile.opencodeDirectory || "";
127
+ if (!opencodeDirectory && requireOpencode) {
128
+ throw new Error("OPENCODE_DIRECTORY is required");
129
+ }
130
+ const resolvedDirectory = opencodeDirectory || process.cwd();
131
131
  const whatsappFile = configFile.channels?.whatsapp ?? {};
132
132
  const whatsappAccountId = env.WHATSAPP_ACCOUNT_ID?.trim() || "default";
133
133
  const accountAuthDir = whatsappFile.accounts?.[whatsappAccountId]?.authDir;
@@ -146,7 +146,7 @@ export function loadConfig(env = process.env, options = {}) {
146
146
  return {
147
147
  configPath,
148
148
  configFile,
149
- opencodeUrl: env.OPENCODE_URL?.trim() ?? "http://127.0.0.1:4096",
149
+ opencodeUrl: env.OPENCODE_URL?.trim() || configFile.opencodeUrl || "http://127.0.0.1:4096",
150
150
  opencodeDirectory: resolvedDirectory,
151
151
  opencodeUsername: env.OPENCODE_SERVER_USERNAME?.trim() || undefined,
152
152
  opencodePassword: env.OPENCODE_SERVER_PASSWORD?.trim() || undefined,
package/dist/telegram.js CHANGED
@@ -4,6 +4,7 @@ export function createTelegramAdapter(config, logger, onMessage) {
4
4
  if (!config.telegramToken) {
5
5
  throw new Error("TELEGRAM_BOT_TOKEN is required for Telegram adapter");
6
6
  }
7
+ logger.debug({ tokenPresent: true }, "telegram adapter init");
7
8
  const bot = new Bot(config.telegramToken);
8
9
  bot.catch((err) => {
9
10
  logger.error({ error: err.error }, "telegram bot error");
@@ -15,11 +16,13 @@ export function createTelegramAdapter(config, logger, onMessage) {
15
16
  const chatType = msg.chat.type;
16
17
  const isGroup = chatType === "group" || chatType === "supergroup" || chatType === "channel";
17
18
  if (isGroup && !config.groupsEnabled) {
19
+ logger.debug({ chatId: msg.chat.id, chatType }, "telegram message ignored (group disabled)");
18
20
  return;
19
21
  }
20
22
  const text = msg.text ?? msg.caption ?? "";
21
23
  if (!text.trim())
22
24
  return;
25
+ logger.debug({ chatId: msg.chat.id, chatType, length: text.length, preview: text.slice(0, 120) }, "telegram message received");
23
26
  try {
24
27
  await onMessage({
25
28
  channel: "telegram",
@@ -36,6 +39,7 @@ export function createTelegramAdapter(config, logger, onMessage) {
36
39
  name: "telegram",
37
40
  maxTextLength: MAX_TEXT_LENGTH,
38
41
  async start() {
42
+ logger.debug("telegram adapter starting");
39
43
  await bot.start();
40
44
  logger.info("telegram adapter started");
41
45
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "owpenwork",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "WhatsApp bridge for a running OpenCode server",
5
5
  "private": false,
6
6
  "type": "module",