friend-assistant 0.1.24 → 0.1.25

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
@@ -340,7 +340,7 @@ A plugin: Esc → **Plugins** → **Zerodha** → **Install** (PIN) → **Config
340
340
 
341
341
  A plugin: Esc → **Plugins** → **Alexa** → **Install** (PIN) → **Configure**. You make a small private skill in your own Amazon developer account (free, left in development mode, never published) and Friend is its server, so "Alexa, ask jarvis assistant how my portfolio is" is answered by Friend, aloud and on the Friend screen if one is open. No AWS account and no paid plan. The full walk-through is in [docs/guides/alexa-setup.md](docs/guides/alexa-setup.md).
342
342
 
343
- - **What it does.** Fixed questions (portfolio, weather, tasks, status) are answered straight from Friend's tools. Open questions ("how...", "what...", "tell me...", "show me...", "remind me...", "please...") go to the assistant. English (India) and Hindi (India); Marathi is not available on Alexa.
343
+ - **What it does.** Fixed questions (portfolio, weather, tasks, status) are answered straight from Friend's tools. Open questions go to the assistant: start with one of about 30 words ("how", "what", "tell me", "remind me", "can you", "find", "check", "explain", "calculate", "translate"...) and then say anything. By voice the assistant can look things up, answer questions and add reminders; anything beyond that (messages, files, commands, settings, email) is refused or asked on your phone first. English (India) and Hindi (India); Marathi is not available on Alexa.
344
344
  - **What it cannot do.** Alexa cannot make an Echo speak on its own (use an Alexa Routine for a scheduled spoken report), and a slow answer is held ("Still working. Ask me if it is ready.") because Alexa waits only about 8 seconds.
345
345
  - **Safe by design.** Every request is checked as really from Amazon (certificate, signature, 150-second timestamp), for your skill, from an Echo you allowed with your PIN. The voice can only read: anything that would ask you is sent to your Telegram or WhatsApp for a YES (or skipped), and anything needing your PIN is refused. The assistant cannot change Alexa settings.
346
346
  - **Setup.** Friend needs a public HTTPS address with a real certificate (`friend config set publicUrl https://your-address`). The Configure page shows the endpoint, lets you download the skill files (manifest and English and Hindi models) to paste into the console, and lists your Echo devices. If your address changes later, paste the new endpoint into the console again; nothing else changes.
package/dist/BUILD.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "friend-assistant",
3
- "version": "0.1.24",
4
- "builtAt": "2026-10-10T18:47:26.315Z"
3
+ "version": "0.1.25",
4
+ "builtAt": "2026-10-11T03:15:21.394Z"
5
5
  }
package/dist/friend.mjs CHANGED
@@ -1560,7 +1560,7 @@ var BANNED = /* @__PURE__ */ new Set(["alexa", "amazon", "echo", "skill", "app",
1560
1560
  var MAX_LENGTH = 50;
1561
1561
  function invocationNameProblem(name) {
1562
1562
  const words = name.trim().split(/\s+/).filter(Boolean);
1563
- if (words.length < 2) return 'Use two or more words, like "jarvis assistant". Amazon does not allow a single word.';
1563
+ if (words.length < 1) return 'Enter the name you will say after "Alexa, ask".';
1564
1564
  if (name.length > MAX_LENGTH) return `That is too long (at most ${MAX_LENGTH} characters).`;
1565
1565
  if (!/^[a-z' ]+$/.test(name)) return "Use lower-case letters, spaces and apostrophes only. Spell numbers out as words.";
1566
1566
  const bad = words.find((w) => BANNED.has(w));
@@ -5079,15 +5079,43 @@ var AlexaDevices = class {
5079
5079
 
5080
5080
  // ../server/src/alexa/phrases.ts
5081
5081
  var langOf = (locale2) => locale2?.toLowerCase().startsWith("hi") ? "hi" : "en";
5082
- var LEAD_INTENTS = ["HowIntent", "WhatIntent", "TellMeIntent", "ShowMeIntent", "RemindMeIntent", "PleaseIntent"];
5083
- var LEAD_INS = {
5084
- HowIntent: { en: "how", hi: "\u0915\u0948\u0938\u0947" },
5085
- WhatIntent: { en: "what", hi: "\u0915\u094D\u092F\u093E" },
5086
- TellMeIntent: { en: "tell me", hi: "\u092E\u0941\u091D\u0947 \u092C\u0924\u093E\u0913" },
5087
- ShowMeIntent: { en: "show me", hi: "\u092E\u0941\u091D\u0947 \u0926\u093F\u0916\u093E\u0913" },
5088
- RemindMeIntent: { en: "remind me", hi: "\u092E\u0941\u091D\u0947 \u092F\u093E\u0926 \u0926\u093F\u0932\u093E\u0913" },
5089
- PleaseIntent: { en: "please", hi: "\u0915\u0943\u092A\u092F\u093E" }
5090
- };
5082
+ var LEADS = [
5083
+ ["HowIntent", "how", "\u0915\u0948\u0938\u0947"],
5084
+ ["WhatIntent", "what", "\u0915\u094D\u092F\u093E"],
5085
+ ["TellMeIntent", "tell me", "\u092E\u0941\u091D\u0947 \u092C\u0924\u093E\u0913"],
5086
+ ["ShowMeIntent", "show me", "\u092E\u0941\u091D\u0947 \u0926\u093F\u0916\u093E\u0913"],
5087
+ ["RemindMeIntent", "remind me", "\u092E\u0941\u091D\u0947 \u092F\u093E\u0926 \u0926\u093F\u0932\u093E\u0913"],
5088
+ ["PleaseIntent", "please", "\u0915\u0943\u092A\u092F\u093E"],
5089
+ ["CanYouIntent", "can you", "\u0915\u094D\u092F\u093E \u0924\u0941\u092E"],
5090
+ ["CouldYouIntent", "could you", "\u0915\u094D\u092F\u093E \u0906\u092A"],
5091
+ ["IsThereIntent", "is there", "\u0915\u094D\u092F\u093E \u0915\u094B\u0908"],
5092
+ ["GiveMeIntent", "give me", "\u092E\u0941\u091D\u0947 \u0926\u094B"],
5093
+ ["FindIntent", "find", "\u0916\u094B\u091C\u094B"],
5094
+ ["SearchIntent", "search for", "\u0922\u0942\u0901\u0922\u094B"],
5095
+ ["CheckIntent", "check", "\u091C\u093E\u0901\u091A\u094B"],
5096
+ ["AddIntent", "add", "\u091C\u094B\u0921\u093C\u094B"],
5097
+ ["SetIntent", "set", "\u0938\u0947\u091F \u0915\u0930\u094B"],
5098
+ ["CreateIntent", "create", "\u092C\u0928\u093E\u0913"],
5099
+ ["WriteIntent", "write", "\u0932\u093F\u0916\u094B"],
5100
+ ["ReadIntent", "read", "\u092A\u0922\u093C\u094B"],
5101
+ ["SendIntent", "send", "\u092D\u0947\u091C\u094B"],
5102
+ ["WhenIntent", "when", "\u0915\u092C"],
5103
+ ["WhereIntent", "where", "\u0915\u0939\u093E\u0901"],
5104
+ ["WhoIntent", "who", "\u0915\u094C\u0928"],
5105
+ ["WhyIntent", "why", "\u0915\u094D\u092F\u094B\u0902"],
5106
+ ["WhichIntent", "which", "\u0915\u094C\u0928 \u0938\u093E"],
5107
+ ["ExplainIntent", "explain", "\u0938\u092E\u091D\u093E\u0913"],
5108
+ ["SummarizeIntent", "summarize", "\u0938\u093E\u0930\u093E\u0902\u0936 \u0926\u094B"],
5109
+ ["CalculateIntent", "calculate", "\u0917\u0923\u0928\u093E \u0915\u0930\u094B"],
5110
+ ["ConvertIntent", "convert", "\u092C\u0926\u0932\u094B"],
5111
+ ["TranslateIntent", "translate", "\u0905\u0928\u0941\u0935\u093E\u0926 \u0915\u0930\u094B"],
5112
+ ["ListIntent", "list", "\u0938\u0942\u091A\u0940 \u0926\u093F\u0916\u093E\u0913"],
5113
+ ["DoIntent", "do", "\u0915\u094D\u092F\u093E \u092E\u0948\u0902"],
5114
+ ["IsIntent", "is", "\u0915\u094D\u092F\u093E \u092F\u0939"],
5115
+ ["AreIntent", "are", "\u0915\u094D\u092F\u093E \u092F\u0947"]
5116
+ ];
5117
+ var LEAD_INTENTS = LEADS.map((l) => l[0]);
5118
+ var LEAD_INS = Object.fromEntries(LEADS.map(([name, en, hi]) => [name, { en, hi }]));
5091
5119
  var SAY = {
5092
5120
  notAllowed: { en: "I do not know this Echo yet. Allow it in Friend, under Plugins, Alexa.", hi: "\u092E\u0948\u0902 \u0907\u0938 \u0907\u0915\u094B \u0915\u094B \u0905\u092D\u0940 \u0928\u0939\u0940\u0902 \u092A\u0939\u091A\u093E\u0928\u0924\u093E\u0964 \u092B\u094D\u0930\u0947\u0902\u0921 \u092E\u0947\u0902 \u092A\u094D\u0932\u0917\u0907\u0928\u094D\u0938, \u0905\u0932\u0947\u0915\u094D\u0938\u093E \u092E\u0947\u0902 \u0907\u0938\u0947 \u0905\u0928\u0941\u092E\u0924\u093F \u0926\u0940\u091C\u093F\u090F\u0964" },
5093
5121
  greet: { en: "Friend here. Ask me about your portfolio, the weather, your tasks, or anything else.", hi: "\u092B\u094D\u0930\u0947\u0902\u0921 \u092F\u0939\u093E\u0901 \u0939\u0948\u0964 \u092E\u0941\u091D\u0938\u0947 \u0905\u092A\u0928\u0947 \u092A\u094B\u0930\u094D\u091F\u092B\u094B\u0932\u093F\u092F\u094B, \u092E\u094C\u0938\u092E, \u0915\u093E\u092E\u094B\u0902 \u092F\u093E \u0915\u0941\u091B \u092D\u0940 \u092A\u0942\u091B\u093F\u090F\u0964" },
@@ -12838,7 +12866,7 @@ async function daemonCommand(args, io2, deps = realDeps) {
12838
12866
  import crossSpawn5 from "cross-spawn";
12839
12867
  var PACKAGE = "friend-assistant";
12840
12868
  var real = {
12841
- current: () => true ? "0.1.24" : "development",
12869
+ current: () => true ? "0.1.25" : "development",
12842
12870
  latest: () => new Promise((resolve11) => {
12843
12871
  const child = crossSpawn5("npm", ["view", PACKAGE, "version", "--prefer-online"], { stdio: ["ignore", "pipe", "ignore"] });
12844
12872
  let out = "";
@@ -13126,7 +13154,7 @@ async function run(argv, io2) {
13126
13154
  case "version":
13127
13155
  case "--version":
13128
13156
  case "-v":
13129
- io2.out(true ? "0.1.24" : "development");
13157
+ io2.out(true ? "0.1.25" : "development");
13130
13158
  return 0;
13131
13159
  case "lan":
13132
13160
  return await lanCommand(rest, io2);