@todoforai/cli 0.1.17 → 0.1.19

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 (2) hide show
  1. package/dist/todoai.js +87 -11
  2. package/package.json +1 -1
package/dist/todoai.js CHANGED
@@ -43188,6 +43188,13 @@ var TodoStatus;
43188
43188
  TodoStatus2["ARCHIVED"] = "ARCHIVED";
43189
43189
  TodoStatus2["DELETED"] = "DELETED";
43190
43190
  })(TodoStatus ||= {});
43191
+ // ../packages/shared-fbe/src/billing.ts
43192
+ var USAGE_WINDOWS = {
43193
+ SESSION_MS: 5 * 60 * 60 * 1000,
43194
+ WEEK_MS: 7 * 24 * 60 * 60 * 1000,
43195
+ WEEKLY_FACTOR: 0.28,
43196
+ SESSION_FACTOR: 1 / 7
43197
+ };
43191
43198
  // ../packages/shared-fbe/src/mimetypes.json
43192
43199
  var mimetypes_default = {
43193
43200
  conversionProfiles: {
@@ -43317,6 +43324,14 @@ for (const [ext, entry] of Object.entries(mimetypes_default.extensions)) {
43317
43324
  if (!MIME_TO_EXT[mime])
43318
43325
  MIME_TO_EXT[mime] = ext;
43319
43326
  }
43327
+ // ../packages/shared-fbe/src/edgeTypes.ts
43328
+ var NON_SHELL_TYPES = new Set([
43329
+ "WEB_EXTENSION" /* WEB_EXTENSION */,
43330
+ "EXTENSION" /* EXTENSION */,
43331
+ "BROWSER" /* BROWSER */,
43332
+ "ANDROID" /* ANDROID */,
43333
+ "IOS" /* IOS */
43334
+ ]);
43320
43335
  // ../packages/shared-fbe/src/blocks/index.ts
43321
43336
  var USER_INPUT_BLOCK_TYPES = new Set([
43322
43337
  "question" /* Question */,
@@ -43436,7 +43451,9 @@ var SERVER_TO_FRONTENDS = {
43436
43451
  payment: {
43437
43452
  status: (userId) => `${"payment:status" /* PAYMENT_STATUS */}:${userId}`
43438
43453
  },
43439
- functions: {}
43454
+ functions: {
43455
+ function_call_request: (userId) => `${"FUNCTION_CALL_REQUEST_AGENT" /* FUNCTION_CALL_REQUEST_AGENT */}:frontend:${userId}`
43456
+ }
43440
43457
  };
43441
43458
  // ../packages/shared-fbe/src/templateBody.ts
43442
43459
  var USER_HEADINGS = new Set([
@@ -43794,6 +43811,64 @@ function getBlockNewPatterns(block, permissions) {
43794
43811
  }
43795
43812
  return pairs.filter(({ raw, pattern }) => !isPatternAllowed(permissions, pattern) && !allow.some((rule) => bashRuleMatchesCmd(rule, serverId, raw))).map(({ pattern }) => pattern);
43796
43813
  }
43814
+ // ../packages/shared-fbe/src/systemAgents.ts
43815
+ var BUSINESS_ANALYZER_AGENT = {
43816
+ id: "00000000-0000-0000-0000-202601013151",
43817
+ name: "Business Analyzer",
43818
+ ownerId: "SYSTEM",
43819
+ systemMessage: `You are a business analyst and growth advisor. Beyond analyzing and updating the business context, you provide ongoing, actionable advice for growing the company's digital presence and business.
43820
+
43821
+ You have no previous context about this business yet \u2014 everything you know must come from the current business context markdown and what you research now. Do not assume prior knowledge or earlier conversations.
43822
+
43823
+ This chat lives on the user's Brand page: the business context markdown you maintain is rendered live right next to this conversation, together with the brand voice answers and the company's online-presence map. Whenever you call update_business_context, the user sees the document change immediately \u2014 refer to it as "your brand page" (never as a file), and keep it polished since it doubles as the company's profile.
43824
+
43825
+ How to analyze and update the business context:
43826
+ 1. Read the current business context markdown from the system prompt
43827
+ 2. Research: fetch websites with webfetch (follow key subpages like /about, /pricing, /contact if they exist); use google_search and google_rag to find competitors and fill knowledge gaps
43828
+ 3. Merge findings into the existing context \u2014 preserve valid existing information, update conflicting facts only when the new source is clearer or more specific \u2014 and save with update_business_context
43829
+
43830
+ Cover these sections (skip any without data):
43831
+ - **Company Info** \u2014 name, founding year, location, team size, stage
43832
+ - **Product & Services** \u2014 offerings, key features, pricing model, target audience
43833
+ - **Value Proposition** \u2014 core problem solved, unique selling points
43834
+ - **Voice & Tone** \u2014 brand personality, communication style (derive from website copy)
43835
+ - **Target Market** \u2014 customer segments, industries, geographic focus, B2B vs B2C
43836
+ - **Tech Stack** \u2014 technologies, integrations, platforms
43837
+ - **Competitors** \u2014 3-5 direct competitors with one-line comparisons
43838
+ - **Online Presence** \u2014 where the company is present: search for its accounts on X/Twitter, LinkedIn, Facebook, Instagram, YouTube, Reddit, GitHub, blog/newsletter, and any industry-relevant platforms. List each found channel as \`platform \u2014 handle/URL \u2014 one-line activity note (e.g. active, stale, unclaimed)\`; also note important channels where no presence was found
43839
+
43840
+ If anything important remains unclear, add an **Open Questions** section at the end.
43841
+
43842
+ Guide the user one step at a time \u2014 they should always know the single next thing to do:
43843
+ - When you need input (brand voice, tone, target audience, which channel to prioritize), prefer the question tool with short multi-choice options over asking open-ended prose questions.
43844
+ - After completing any analysis or context update, always close with a short **Next Steps** section: 2-4 concrete, prioritized tips tailored to this specific business (e.g. SEO/content gaps, social channels worth activating, positioning against the competitors you found, conversion or messaging improvements). Base tips on what you actually observed, keep each to one or two sentences, and lead with the one you'd do first.
43845
+
43846
+ In follow-up conversations, act as an ongoing advisor: answer growth and digital-presence questions using the business context, refresh your analysis when asked, and suggest what to tackle next.`,
43847
+ mcpConfigs: {},
43848
+ edgesMcpConfigs: {},
43849
+ permissions: {
43850
+ allow: ["builtin:webfetch", "builtin:google_search", "cloud:google_rag", "builtin:business_context", "builtin:todoforai_api", "builtin:question"],
43851
+ ask: [],
43852
+ deny: []
43853
+ },
43854
+ createdAt: 0,
43855
+ updatedAt: 0
43856
+ };
43857
+ var JARVIS_AGENT = {
43858
+ id: "00000000-0000-0000-0000-202601013152",
43859
+ name: "JARVIS",
43860
+ ownerId: "SYSTEM",
43861
+ systemMessage: "",
43862
+ model: "",
43863
+ mcpConfigs: {},
43864
+ edgesMcpConfigs: {},
43865
+ createdAt: 0,
43866
+ updatedAt: 0
43867
+ };
43868
+ var SYSTEM_AGENTS = {
43869
+ [BUSINESS_ANALYZER_AGENT.id]: BUSINESS_ANALYZER_AGENT,
43870
+ [JARVIS_AGENT.id]: JARVIS_AGENT
43871
+ };
43797
43872
  // ../packages/shared-fbe/src/outputLimits.ts
43798
43873
  var MAX_LINE_LEN = 300;
43799
43874
  var STREAM_FIRST = 1e4;
@@ -44473,11 +44548,19 @@ function ensureBridgeCredentials(apiUrl) {
44473
44548
  const login = spawnSync("todoforai-bridge", bridgeLoginArgs(apiUrl), { stdio: "inherit" });
44474
44549
  return login.status === 0;
44475
44550
  }
44551
+ function bridgeAlreadyRunning() {
44552
+ if (process.platform === "win32")
44553
+ return false;
44554
+ const r = spawnSync("pgrep", ["-f", "todoforai-bridge"], { encoding: "utf-8" });
44555
+ return r.status === 0 && (r.stdout || "").trim().length > 0;
44556
+ }
44476
44557
  function ensureBridgeRunning(apiUrl, _apiKey) {
44477
44558
  if (!hasBridge()) {
44478
44559
  console.error("\x1B[2mBridge not started: `todoforai-bridge` was not found on PATH. Install TODOforAI Bridge, or pass --no-bridge (or deprecated --no-edge) to silence this.\x1B[0m");
44479
44560
  return;
44480
44561
  }
44562
+ if (bridgeAlreadyRunning())
44563
+ return;
44481
44564
  if (!ensureBridgeCredentials(apiUrl)) {
44482
44565
  console.error("\x1B[33mBridge not started: `todoforai-bridge login` did not complete successfully.\x1B[0m");
44483
44566
  return;
@@ -44500,19 +44583,12 @@ function ensureBridgeRunning(apiUrl, _apiKey) {
44500
44583
  exitCode = code;
44501
44584
  });
44502
44585
  child.unref();
44503
- const pid = child.pid;
44504
- if (!pid)
44586
+ if (!child.pid)
44505
44587
  return;
44506
44588
  const shortLog = logFile.replace(os3.homedir(), "~");
44507
44589
  setTimeout(() => {
44508
- if (!exited) {
44509
- console.error(`\x1B[2mStarted bridge (pid ${pid}), logs: ${shortLog}\x1B[0m`);
44510
- return;
44511
- }
44512
- if (exitCode === 0) {
44513
- console.error(`\x1B[2mBridge exited cleanly. Logs: ${shortLog}\x1B[0m`);
44514
- } else {
44515
- console.error(`\x1B[33mBridge exited early (exit ${exitCode}). Check logs: ${shortLog}. Another instance may already be running.\x1B[0m`);
44590
+ if (exited && exitCode !== 0) {
44591
+ console.error(`\x1B[2mBridge not running (exit ${exitCode}), see ${shortLog}\x1B[0m`);
44516
44592
  }
44517
44593
  }, 500);
44518
44594
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@todoforai/cli",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "todoforai-cli": "dist/todoai.js",