@inetafrica/open-claudia 1.14.3 → 1.14.4

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 (3) hide show
  1. package/bot-agent.js +36 -28
  2. package/bot.js +36 -28
  3. package/package.json +1 -1
package/bot-agent.js CHANGED
@@ -1471,7 +1471,7 @@ bot.onText(/\/upgrade$/, async (msg) => {
1471
1471
  await send("Upgrading...");
1472
1472
  }
1473
1473
  try {
1474
- execSync("npm install -g @inetafrica/open-claudia@latest 2>&1", {
1474
+ execSync(`npm install -g @inetafrica/open-claudia@${latest} 2>&1`, {
1475
1475
  encoding: "utf-8", timeout: 120000,
1476
1476
  cwd: process.env.HOME || require("os").homedir(),
1477
1477
  env: { ...process.env, PATH: FULL_PATH, HOME: process.env.HOME || require("os").homedir() },
@@ -1482,8 +1482,9 @@ bot.onText(/\/upgrade$/, async (msg) => {
1482
1482
  let whatsNew = "";
1483
1483
  try {
1484
1484
  const changelog = fs.readFileSync(path.join(root, "@inetafrica", "open-claudia", "CHANGELOG.md"), "utf-8");
1485
- const versionHeader = `## v${newPkg.version}`;
1486
- const start = changelog.indexOf(versionHeader);
1485
+ let versionHeader = `## v${newPkg.version}`;
1486
+ let start = changelog.indexOf(versionHeader);
1487
+ if (start < 0) { versionHeader = `## ${newPkg.version}`; start = changelog.indexOf(versionHeader); }
1487
1488
  if (start >= 0) {
1488
1489
  const afterHeader = changelog.slice(start + versionHeader.length);
1489
1490
  const nextVersion = afterHeader.indexOf("\n## ");
@@ -1717,6 +1718,25 @@ bot.onText(/\/cancel_auth$/, async (msg) => {
1717
1718
  await send("Claude auth flow cancelled. Normal messages will go to the assistant again.");
1718
1719
  });
1719
1720
 
1721
+ bot.onText(/\/auth_code(?:\s+(.+))?$/, async (msg, match) => {
1722
+ if (!isAuthorized(msg)) return;
1723
+ const code = (match[1] || "").trim();
1724
+ await deleteMessage(msg.message_id);
1725
+ if (!pendingClaudeAuthProcess || pendingClaudeAuthLabel === "manual OAuth token save") {
1726
+ return send("No Claude login flow is waiting for an auth code. Start with /login, or use /use_oauth_token for tokens.");
1727
+ }
1728
+ if (!code || !looksLikeClaudeAuthReply(code)) {
1729
+ return send("That does not look like a Claude auth code/callback. Use /cancel_auth to cancel the login flow.");
1730
+ }
1731
+ try {
1732
+ pendingClaudeAuthProcess.stdin.write(code + "\n");
1733
+ await send("Auth code sent to Claude. I’ll confirm with auth status when Claude finishes.");
1734
+ } catch (e) {
1735
+ clearPendingClaudeAuth();
1736
+ await send(`Could not send auth code to Claude: ${redactSensitive(e.message)}`);
1737
+ }
1738
+ });
1739
+
1720
1740
  bot.onText(/\/login$/, async (msg) => {
1721
1741
  if (!isAuthorized(msg)) return;
1722
1742
  await runClaudeAuthCommand(["auth", "login", "--claudeai", "--email", "sumeet@inet.africa"], "Claude login");
@@ -1985,35 +2005,23 @@ bot.on("message", async (msg) => {
1985
2005
  if (msg.voice || msg.audio || msg.photo || msg.document || msg.video || msg.sticker) return;
1986
2006
  if (isDuplicate(msg.message_id)) return;
1987
2007
 
1988
- // Handle pending Claude auth/token paste-back. Only consume code/token-looking replies;
1989
- // normal chat must still go to Claude instead of being deleted.
1990
- if (pendingClaudeAuthProcess) {
2008
+ // Handle pending manual OAuth token paste mode. Login codes must be sent explicitly
2009
+ // with /auth_code so normal chat can never be deleted/consumed accidentally.
2010
+ if (pendingClaudeAuthProcess && pendingClaudeAuthLabel === "manual OAuth token save") {
1991
2011
  const text = msg.text.trim();
1992
- if (pendingClaudeAuthLabel === "manual OAuth token save") {
1993
- if (looksLikeClaudeToken(text)) {
1994
- await deleteMessage(msg.message_id);
1995
- clearPendingClaudeAuth();
1996
- saveClaudeOAuthToken(text);
1997
- await send(`Claude OAuth token stored in .env${vault.isUnlocked() ? " and vault" : ""}. Restart the bot so launchd picks it up, or use /restart.`);
1998
- await sendClaudeAuthStatusSummary("Stored token. Current Claude auth status:");
1999
- return;
2000
- }
2001
- await send("That does not look like a Claude OAuth token, so I did not delete it or store it. Send /cancel_auth to stop token paste mode.");
2002
- // Fall through and treat the message normally.
2003
- } else if (looksLikeClaudeAuthReply(text)) {
2012
+ if (looksLikeClaudeToken(text)) {
2004
2013
  await deleteMessage(msg.message_id);
2005
- try {
2006
- pendingClaudeAuthProcess.stdin.write(text + "\n");
2007
- await send("Sent to Claude auth process. I’ll confirm when Claude finishes the auth check.");
2008
- } catch (e) {
2009
- clearPendingClaudeAuth();
2010
- await send(`Could not send to Claude auth process: ${redactSensitive(e.message)}`);
2011
- }
2014
+ clearPendingClaudeAuth();
2015
+ saveClaudeOAuthToken(text);
2016
+ await send(`Claude OAuth token stored in .env${vault.isUnlocked() ? " and vault" : ""}. Restart the bot so launchd picks it up, or use /restart.`);
2017
+ await sendClaudeAuthStatusSummary("Stored token. Current Claude auth status:");
2012
2018
  return;
2013
- } else {
2014
- await send("Claude auth is still waiting for a login code/token. I left your message visible and will handle it normally. Send /cancel_auth to cancel the auth flow.");
2015
- // Fall through and treat the message normally.
2016
2019
  }
2020
+ await send("Token paste mode is active, but that does not look like a Claude OAuth token. I left your message visible and will handle it normally. Send /cancel_auth to stop token paste mode.");
2021
+ }
2022
+
2023
+ if (pendingClaudeAuthProcess && pendingClaudeAuthLabel !== "manual OAuth token save") {
2024
+ await send("Claude login is still waiting. I will not delete normal messages. If Claude gave you a code, send it as `/auth_code YOUR_CODE`, or use /cancel_auth.");
2017
2025
  }
2018
2026
 
2019
2027
  // Handle onboarding
package/bot.js CHANGED
@@ -1502,7 +1502,7 @@ bot.onText(/\/upgrade$/, async (msg) => {
1502
1502
  await send("Upgrading...");
1503
1503
  }
1504
1504
  try {
1505
- execSync("npm install -g @inetafrica/open-claudia@latest 2>&1", {
1505
+ execSync(`npm install -g @inetafrica/open-claudia@${latest} 2>&1`, {
1506
1506
  encoding: "utf-8", timeout: 120000,
1507
1507
  cwd: process.env.HOME || require("os").homedir(),
1508
1508
  env: { ...process.env, PATH: FULL_PATH, HOME: process.env.HOME || require("os").homedir() },
@@ -1519,8 +1519,9 @@ bot.onText(/\/upgrade$/, async (msg) => {
1519
1519
  let whatsNew = "";
1520
1520
  try {
1521
1521
  const changelog = fs.readFileSync(path.join(root, "@inetafrica", "open-claudia", "CHANGELOG.md"), "utf-8");
1522
- const versionHeader = `## v${newPkg.version}`;
1523
- const start = changelog.indexOf(versionHeader);
1522
+ let versionHeader = `## v${newPkg.version}`;
1523
+ let start = changelog.indexOf(versionHeader);
1524
+ if (start < 0) { versionHeader = `## ${newPkg.version}`; start = changelog.indexOf(versionHeader); }
1524
1525
  if (start >= 0) {
1525
1526
  const afterHeader = changelog.slice(start + versionHeader.length);
1526
1527
  const nextVersion = afterHeader.indexOf("\n## ");
@@ -1748,6 +1749,25 @@ bot.onText(/\/cancel_auth$/, async (msg) => {
1748
1749
  await send("Claude auth flow cancelled. Normal messages will go to the assistant again.");
1749
1750
  });
1750
1751
 
1752
+ bot.onText(/\/auth_code(?:\s+(.+))?$/, async (msg, match) => {
1753
+ if (!isAuthorized(msg)) return;
1754
+ const code = (match[1] || "").trim();
1755
+ await deleteMessage(msg.message_id);
1756
+ if (!pendingClaudeAuthProcess || pendingClaudeAuthLabel === "manual OAuth token save") {
1757
+ return send("No Claude login flow is waiting for an auth code. Start with /login, or use /use_oauth_token for tokens.");
1758
+ }
1759
+ if (!code || !looksLikeClaudeAuthReply(code)) {
1760
+ return send("That does not look like a Claude auth code/callback. Use /cancel_auth to cancel the login flow.");
1761
+ }
1762
+ try {
1763
+ pendingClaudeAuthProcess.stdin.write(code + "\n");
1764
+ await send("Auth code sent to Claude. I’ll confirm with auth status when Claude finishes.");
1765
+ } catch (e) {
1766
+ clearPendingClaudeAuth();
1767
+ await send(`Could not send auth code to Claude: ${redactSensitive(e.message)}`);
1768
+ }
1769
+ });
1770
+
1751
1771
  bot.onText(/\/login$/, async (msg) => {
1752
1772
  if (!isAuthorized(msg)) return;
1753
1773
  await runClaudeAuthCommand(["auth", "login", "--claudeai", "--email", "sumeet@inet.africa"], "Claude login");
@@ -2024,35 +2044,23 @@ bot.on("message", async (msg) => {
2024
2044
  if (msg.voice || msg.audio || msg.photo || msg.document || msg.video || msg.sticker) return;
2025
2045
  if (isDuplicate(msg.message_id)) return;
2026
2046
 
2027
- // Handle pending Claude auth/token paste-back. Only consume code/token-looking replies;
2028
- // normal chat must still go to Claude instead of being deleted.
2029
- if (pendingClaudeAuthProcess) {
2047
+ // Handle pending manual OAuth token paste mode. Login codes must be sent explicitly
2048
+ // with /auth_code so normal chat can never be deleted/consumed accidentally.
2049
+ if (pendingClaudeAuthProcess && pendingClaudeAuthLabel === "manual OAuth token save") {
2030
2050
  const text = msg.text.trim();
2031
- if (pendingClaudeAuthLabel === "manual OAuth token save") {
2032
- if (looksLikeClaudeToken(text)) {
2033
- await deleteMessage(msg.message_id);
2034
- clearPendingClaudeAuth();
2035
- saveClaudeOAuthToken(text);
2036
- await send(`Claude OAuth token stored in .env${vault.isUnlocked() ? " and vault" : ""}. Restart the bot so launchd picks it up, or use /restart.`);
2037
- await sendClaudeAuthStatusSummary("Stored token. Current Claude auth status:");
2038
- return;
2039
- }
2040
- await send("That does not look like a Claude OAuth token, so I did not delete it or store it. Send /cancel_auth to stop token paste mode.");
2041
- // Fall through and treat the message normally.
2042
- } else if (looksLikeClaudeAuthReply(text)) {
2051
+ if (looksLikeClaudeToken(text)) {
2043
2052
  await deleteMessage(msg.message_id);
2044
- try {
2045
- pendingClaudeAuthProcess.stdin.write(text + "\n");
2046
- await send("Sent to Claude auth process. I’ll confirm when Claude finishes the auth check.");
2047
- } catch (e) {
2048
- clearPendingClaudeAuth();
2049
- await send(`Could not send to Claude auth process: ${redactSensitive(e.message)}`);
2050
- }
2053
+ clearPendingClaudeAuth();
2054
+ saveClaudeOAuthToken(text);
2055
+ await send(`Claude OAuth token stored in .env${vault.isUnlocked() ? " and vault" : ""}. Restart the bot so launchd picks it up, or use /restart.`);
2056
+ await sendClaudeAuthStatusSummary("Stored token. Current Claude auth status:");
2051
2057
  return;
2052
- } else {
2053
- await send("Claude auth is still waiting for a login code/token. I left your message visible and will handle it normally. Send /cancel_auth to cancel the auth flow.");
2054
- // Fall through and treat the message normally.
2055
2058
  }
2059
+ await send("Token paste mode is active, but that does not look like a Claude OAuth token. I left your message visible and will handle it normally. Send /cancel_auth to stop token paste mode.");
2060
+ }
2061
+
2062
+ if (pendingClaudeAuthProcess && pendingClaudeAuthLabel !== "manual OAuth token save") {
2063
+ await send("Claude login is still waiting. I will not delete normal messages. If Claude gave you a code, send it as `/auth_code YOUR_CODE`, or use /cancel_auth.");
2056
2064
  }
2057
2065
 
2058
2066
  // Handle onboarding
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inetafrica/open-claudia",
3
- "version": "1.14.3",
3
+ "version": "1.14.4",
4
4
  "description": "Your always-on AI coding assistant — Claude Code via Telegram",
5
5
  "main": "bot.js",
6
6
  "bin": {