@m13v/s4l 1.6.197-rc.8 → 1.6.198

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/mcp/dist/index.js CHANGED
@@ -20,7 +20,7 @@ import os from "node:os";
20
20
  import path from "node:path";
21
21
  import fs from "node:fs";
22
22
  import { repoDir, runPython, run, readPlan, writePlan, planPath, } from "./repo.js";
23
- import { applySetup, resolveProject, personaReady, listManagedProjectStatus, ensureShortLinksDefault, ensurePersonaProject, findPersonaProject, REQUIRED_FIELDS, RECOMMENDED_FIELDS, configPath, normalizeStringList, } from "./setup.js";
23
+ import { applySetup, resolveProject, personaReady, listManagedProjectStatus, listProjectSettings, ensureShortLinksDefault, ensurePersonaProject, findPersonaProject, REQUIRED_FIELDS, RECOMMENDED_FIELDS, configPath, normalizeStringList, } from "./setup.js";
24
24
  import { xStatus, xConnect, xDetectSources, xScanProfile, summarizeXAuth } from "./twitterAuth.js";
25
25
  import { startProvisioning, isProvisioning, readProgress, runtimeReady, readRuntime, resolvePython, resolveChrome, ensureMenubar, menubarRunning, clearMenubarStop, ensurePipelineCurrent, ensureRuntimeProvisioned, } from "./runtime.js";
26
26
  import { blockOnboardingMilestone, completeOnboardingMilestone, ensureDoctorPhase, onboardingLedger, onboardingSnapshot, recordOnboardingAttempt, runDoctorPhase, } from "./onboarding.js";
@@ -1397,9 +1397,14 @@ tool("project_config", {
1397
1397
  inputSchema: {
1398
1398
  status: z.boolean().optional(),
1399
1399
  action: z
1400
- .enum(["connect_x", "detect_x_sources", "profile_scan"])
1400
+ .enum(["get", "connect_x", "detect_x_sources", "profile_scan"])
1401
1401
  .optional()
1402
- .describe("connect_x = import/validate your X session in the autoposter's managed browser. " +
1402
+ .describe("get = read the CURRENT SAVED VALUES of every project's editable fields (website, " +
1403
+ "description, icp, voice, differentiator, search_topics, get_started_link, " +
1404
+ "content_guardrails, content_angle) plus readiness — the read companion to editing. " +
1405
+ "Use it before tweaking part of a nested value; the panel's Project settings section " +
1406
+ "is built on it. " +
1407
+ "connect_x = import/validate your X session in the autoposter's managed browser. " +
1403
1408
  "With an explicit setup/connect request, warn about possible keychain prompts and call " +
1404
1409
  "with confirm:true without waiting for another yes/no reply. Without confirm:true it " +
1405
1410
  "only previews the operation for users who asked to inspect it rather than run it. " +
@@ -1469,12 +1474,25 @@ tool("project_config", {
1469
1474
  "weight, platform, voice_relationship, booking_link, qualification, subreddit_bans, " +
1470
1475
  "short_links_host, short_links_live, content_angle, messaging, landing_pages, posthog. " +
1471
1476
  "Pass {name:'<project>', fields:{<key>:<value>, ...}}; each key SHALLOW-merges onto the " +
1472
- "project, REPLACING that key's whole value (read the current value via status:true first if " +
1477
+ "project, REPLACING that key's whole value (read the current value via action:'get' first if " +
1473
1478
  "you only want to tweak part of a nested object, then pass the full new value). A value of " +
1474
1479
  "null DELETES the key. 'name' is ignored here (can't rename through this path). This is how " +
1475
1480
  "you edit advanced config without any raw whole-file overwrite."),
1476
1481
  },
1477
1482
  }, async (args) => {
1483
+ // ---- Read current saved values (the panel's Project settings source) ---
1484
+ // Whitelisted field values + readiness for every managed project and the
1485
+ // persona. Read-only; the write path stays the validated merge below.
1486
+ if (args.action === "get") {
1487
+ return jsonContent({
1488
+ action: "get",
1489
+ projects: listProjectSettings(),
1490
+ config_path: configPath(),
1491
+ note: "Current saved values of each project's editable fields. To change one, call project_config " +
1492
+ "with {name, <field>: <new value>} — it merges onto what's saved and re-seeds topics. " +
1493
+ "extra_keys lists advanced keys editable only via the `fields` escape hatch.",
1494
+ });
1495
+ }
1478
1496
  // ---- List import sources (for the panel dropdown) ---------------------
1479
1497
  // Read-only browser/profile detection. Never reads the keychain or decrypts
1480
1498
  // a cookie, so it shows no macOS Safe Storage prompt. Lets the user pick the
@@ -1724,11 +1742,20 @@ tool("project_config", {
1724
1742
  // Apply mode (incremental): merge whatever fields were supplied onto the
1725
1743
  // named project, then report whether it's now ready or still missing fields.
1726
1744
  try {
1727
- recordOnboardingAttempt("project_ready", {
1728
- missing_count: 0,
1729
- });
1745
+ // Editing the persona project must not touch the PRODUCT onboarding
1746
+ // milestone (a persona is never "project_ready" in the product sense; it
1747
+ // validates against PERSONA_REQUIRED_FIELDS inside applySetup).
1748
+ const editingPersona = findPersonaProject()?.name === args.name;
1749
+ if (!editingPersona) {
1750
+ recordOnboardingAttempt("project_ready", {
1751
+ missing_count: 0,
1752
+ });
1753
+ }
1730
1754
  const result = applySetup(args);
1731
- if (result.ready) {
1755
+ if (result.persona) {
1756
+ // no-op on the onboarding ledger; readiness is reported below as usual.
1757
+ }
1758
+ else if (result.ready) {
1732
1759
  completeOnboardingMilestone("project_ready", { missing_count: 0 });
1733
1760
  }
1734
1761
  else {
@@ -1809,6 +1836,7 @@ tool("project_config", {
1809
1836
  ok: true,
1810
1837
  project: result.project,
1811
1838
  action: result.created ? "created" : "updated",
1839
+ persona: result.persona,
1812
1840
  ready: result.ready,
1813
1841
  missing_required: result.missing_required,
1814
1842
  topics_seeded: topicsSeeded,
@@ -1820,16 +1848,19 @@ tool("project_config", {
1820
1848
  fields_removed: result.fields_removed,
1821
1849
  config_path: configPath(),
1822
1850
  onboarding: onboardingSnapshot(),
1823
- note: (result.ready
1824
- ? `Project '${result.project}' is fully configured.${seedNote} Next: if X is not connected, ` +
1825
- `detect sources, warn about keychain prompts, and call project_config with ` +
1826
- `action:'connect_x', confirm:true immediately. Once X is connected, schedule the autopilot ` +
1827
- `(queue_setup + create_scheduled_task per task); the autopilot then drafts on its own. Call the ` +
1828
- `dashboard to confirm the schedule is firing (schedule_state 'ok') that is the final step, ` +
1829
- `no need to wait for or verify a draft card.`
1830
- : `Saved what you provided for '${result.project}'. Still need: ${result.missing_required.join(", ")}. ` +
1831
- `First derive those fields from existing context, profile_scan, and website research, then ` +
1832
- `call project_config again with name='${result.project}'. Ask only if a required field is genuinely unknowable.`) +
1851
+ note: (result.persona
1852
+ ? `Persona '${result.project}' updated.${seedNote}` +
1853
+ (result.ready ? "" : ` Still needs: ${result.missing_required.join(", ")}.`)
1854
+ : result.ready
1855
+ ? `Project '${result.project}' is fully configured.${seedNote} Next: if X is not connected, ` +
1856
+ `detect sources, warn about keychain prompts, and call project_config with ` +
1857
+ `action:'connect_x', confirm:true immediately. Once X is connected, schedule the autopilot ` +
1858
+ `(queue_setup + create_scheduled_task per task); the autopilot then drafts on its own. Call the ` +
1859
+ `dashboard to confirm the schedule is firing (schedule_state 'ok') that is the final step, ` +
1860
+ `no need to wait for or verify a draft card.`
1861
+ : `Saved what you provided for '${result.project}'. Still need: ${result.missing_required.join(", ")}. ` +
1862
+ `First derive those fields from existing context, profile_scan, and website research, then ` +
1863
+ `call project_config again with name='${result.project}'. Ask only if a required field is genuinely unknowable.`) +
1833
1864
  advancedNote,
1834
1865
  });
1835
1866
  }
@@ -4004,7 +4035,7 @@ tool("show_browser_to_user", {
4004
4035
  const message = ensured.error === "no_browser"
4005
4036
  ? "No managed Chrome is running right now. Start a draft cycle or autopilot so there's a live browser session to show."
4006
4037
  : ensured.error === "no_websocket"
4007
- ? "This Node runtime has no WebSocket support (needs Node 21+), so a screencast can't be opened."
4038
+ ? "This runtime has no WebSocket support, so a live screencast can't be opened. Use 'Bring to front' to see the browser window instead."
4008
4039
  : "Couldn't attach to the browser: " + String(ensured.error);
4009
4040
  return jsonContent({ ok: false, running: false, frame: null, message });
4010
4041
  }