replicas-cli 0.2.782 → 0.2.784

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/index.cjs +48 -15
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -7388,6 +7388,7 @@ var WEB_APP_PATHS = {
7388
7388
  settings: `${DASHBOARD_PATH}/settings`,
7389
7389
  billing: `${DASHBOARD_PATH}/billing`,
7390
7390
  members: `${DASHBOARD_PATH}/members`,
7391
+ learnings: `${DASHBOARD_PATH}/learnings`,
7391
7392
  "audit-logs": `${DASHBOARD_PATH}/audit-logs`,
7392
7393
  accountAgents: `${DASHBOARD_PATH}/account/agents`,
7393
7394
  accountProfile: `${DASHBOARD_PATH}/account/profile`,
@@ -25274,6 +25275,7 @@ In agent mode the CLI hides commands that don't make sense for in-workspace agen
25274
25275
  | \`replicas preview ...\` | Register / list preview URLs (covered in \`PREVIEWS.md\`) |
25275
25276
  | \`replicas service ...\` | Run long-lived services detached so they survive workspace sleep/wake (see below) |
25276
25277
  | \`replicas media ...\` | Upload, list, share, revoke, or delete workspace media; follow \`MEDIA.md\` for destination embedding |
25278
+ | \`replicas skills suggest <SKILL.md> --title <text>\` | Suggest saving a lasting user instruction as a learning (an organization skill); the user accepts or dismisses it |
25277
25279
  | \`replicas slack thread ...\` | Attach or switch Slack thread routing (covered in \`SLACK.md\`) |
25278
25280
 
25279
25281
  \`replicas <command> --help\` is always the source of truth for flags.
@@ -27934,7 +27936,7 @@ var headlessAgentRequestSchema = external_exports.object({
27934
27936
  });
27935
27937
 
27936
27938
  // ../shared/src/cli-version.ts
27937
- var CLI_VERSION = "0.2.782";
27939
+ var CLI_VERSION = "0.2.784";
27938
27940
 
27939
27941
  // ../shared/src/version.ts
27940
27942
  function compareVersions(v1, v2) {
@@ -28617,6 +28619,16 @@ function isPublicMediaKind(value) {
28617
28619
  }
28618
28620
  var MAX_ENGINE_LOG_BYTES = 50 * 1024 * 1024;
28619
28621
 
28622
+ // ../shared/src/frontmatter.ts
28623
+ var import_yaml2 = __toESM(require_dist());
28624
+
28625
+ // ../shared/src/learned-skills.ts
28626
+ var LEARNED_SKILLS_ROOT = `${SANDBOX_PATHS.REPLICAS_DIR}/learned-skills`;
28627
+ var LEARNED_SKILLS_MANIFEST_PATH = `${LEARNED_SKILLS_ROOT}/manifest.json`;
28628
+ var learnedSkillsManifestSchema = external_exports.object({
28629
+ skills: external_exports.array(external_exports.object({ name: external_exports.string(), sha256: external_exports.string() }))
28630
+ });
28631
+
28620
28632
  // ../shared/src/sse.ts
28621
28633
  function parseSseChunk(chunk) {
28622
28634
  let data = "";
@@ -28651,9 +28663,6 @@ async function readSseStream(body, onEvent, shouldContinue = () => true) {
28651
28663
  }
28652
28664
  }
28653
28665
 
28654
- // ../shared/src/frontmatter.ts
28655
- var import_yaml2 = __toESM(require_dist());
28656
-
28657
28666
  // ../shared/src/workspace-identity.ts
28658
28667
  var AWS_SOURCE_IDENTITY_CLAIM = "https://aws.amazon.com/source_identity";
28659
28668
  var WORKSPACE_TOKEN_TTL_SECONDS = 15 * 60;
@@ -32516,6 +32525,19 @@ async function historyTranscriptCommand(name) {
32516
32525
  console.log(file2);
32517
32526
  }
32518
32527
 
32528
+ // src/commands/skills.ts
32529
+ var import_node_fs3 = require("fs");
32530
+ async function skillsSuggestCommand(file2, options) {
32531
+ const body = { content: (0, import_node_fs3.readFileSync)(file2, "utf-8"), title: options.title };
32532
+ const { id, name, update } = await agentFetch("/v1/learned-skills/suggestions", {
32533
+ method: "POST",
32534
+ body
32535
+ });
32536
+ console.log(`Suggested ${update ? "an update to the" : "a new"} learning '${name}'. It is saved only if the user accepts it.`);
32537
+ console.log("Put this link on its own line in your reply; it renders as a chip where the user can review it:");
32538
+ console.log(`[${name}](${MONOLITH_URL}/v1/learned-skills/suggestions/${id})`);
32539
+ }
32540
+
32519
32541
  // src/commands/slack.ts
32520
32542
  var import_chalk22 = __toESM(require("chalk"));
32521
32543
  function getThreadOptions(options) {
@@ -32568,7 +32590,7 @@ async function slackThreadSwitchCommand(workspace, options) {
32568
32590
  // src/commands/service.ts
32569
32591
  var import_chalk23 = __toESM(require("chalk"));
32570
32592
  var import_node_child_process2 = require("child_process");
32571
- var import_node_fs3 = require("fs");
32593
+ var import_node_fs4 = require("fs");
32572
32594
  var import_node_os2 = require("os");
32573
32595
  var import_node_path3 = require("path");
32574
32596
  var SERVICES_DIR = (0, import_node_path3.join)((0, import_node_os2.homedir)(), ".replicas", "services");
@@ -32592,7 +32614,7 @@ function isServiceState(value) {
32592
32614
  function readState(name) {
32593
32615
  let parsed;
32594
32616
  try {
32595
- parsed = JSON.parse((0, import_node_fs3.readFileSync)(statePath(name), "utf-8"));
32617
+ parsed = JSON.parse((0, import_node_fs4.readFileSync)(statePath(name), "utf-8"));
32596
32618
  } catch {
32597
32619
  return null;
32598
32620
  }
@@ -32626,7 +32648,7 @@ async function killServiceGroup(pid) {
32626
32648
  }
32627
32649
  function tailLog(logFile, lines) {
32628
32650
  try {
32629
- return tailLines((0, import_node_fs3.readFileSync)(logFile, "utf-8"), lines);
32651
+ return tailLines((0, import_node_fs4.readFileSync)(logFile, "utf-8"), lines);
32630
32652
  } catch {
32631
32653
  return "";
32632
32654
  }
@@ -32644,11 +32666,11 @@ async function serviceStartCommand(name, commandParts, options) {
32644
32666
  console.log(`Stopping existing "${name}" (pid ${existing.pid}) before restart`);
32645
32667
  await killServiceGroup(existing.pid);
32646
32668
  }
32647
- (0, import_node_fs3.mkdirSync)(SERVICES_DIR, { recursive: true });
32669
+ (0, import_node_fs4.mkdirSync)(SERVICES_DIR, { recursive: true });
32648
32670
  const cwd = (0, import_node_path3.resolve)(options.cwd ?? process.cwd());
32649
32671
  const logFile = (0, import_node_path3.join)(SERVICES_DIR, `${name}.log`);
32650
- const logFd = (0, import_node_fs3.openSync)(logFile, "a");
32651
- (0, import_node_fs3.writeFileSync)(logFd, `
32672
+ const logFd = (0, import_node_fs4.openSync)(logFile, "a");
32673
+ (0, import_node_fs4.writeFileSync)(logFd, `
32652
32674
  === [replicas service] "${name}" started ${(/* @__PURE__ */ new Date()).toISOString()} in ${cwd}: ${command} ===
32653
32675
  `);
32654
32676
  const child = (0, import_node_child_process2.spawn)("bash", ["-lc", command], {
@@ -32657,7 +32679,7 @@ async function serviceStartCommand(name, commandParts, options) {
32657
32679
  stdio: ["ignore", logFd, logFd],
32658
32680
  env: process.env
32659
32681
  });
32660
- (0, import_node_fs3.closeSync)(logFd);
32682
+ (0, import_node_fs4.closeSync)(logFd);
32661
32683
  if (child.pid === void 0) {
32662
32684
  throw new Error("Failed to spawn service process");
32663
32685
  }
@@ -32670,11 +32692,11 @@ async function serviceStartCommand(name, commandParts, options) {
32670
32692
  logFile,
32671
32693
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
32672
32694
  };
32673
- (0, import_node_fs3.writeFileSync)(statePath(name), JSON.stringify(state, null, 2));
32695
+ (0, import_node_fs4.writeFileSync)(statePath(name), JSON.stringify(state, null, 2));
32674
32696
  await sleep(1e3);
32675
32697
  if (!isRunning(child.pid)) {
32676
32698
  const logs = tailLog(logFile, 20);
32677
- (0, import_node_fs3.rmSync)(statePath(name), { force: true });
32699
+ (0, import_node_fs4.rmSync)(statePath(name), { force: true });
32678
32700
  throw new Error(`Service "${name}" exited immediately.${logs ? `
32679
32701
 
32680
32702
  Last log output:
@@ -32694,12 +32716,12 @@ async function serviceStopCommand(name) {
32694
32716
  } else {
32695
32717
  console.log(`Service "${name}" was not running`);
32696
32718
  }
32697
- (0, import_node_fs3.rmSync)(statePath(name), { force: true });
32719
+ (0, import_node_fs4.rmSync)(statePath(name), { force: true });
32698
32720
  }
32699
32721
  async function serviceListCommand() {
32700
32722
  let entries;
32701
32723
  try {
32702
- entries = (0, import_node_fs3.readdirSync)(SERVICES_DIR).filter((f) => f.endsWith(".json"));
32724
+ entries = (0, import_node_fs4.readdirSync)(SERVICES_DIR).filter((f) => f.endsWith(".json"));
32703
32725
  } catch {
32704
32726
  entries = [];
32705
32727
  }
@@ -34077,6 +34099,16 @@ if (isAgentMode()) {
34077
34099
  } catch (error51) {
34078
34100
  if (error51 instanceof Error) console.error(import_chalk25.default.red(`
34079
34101
  \u2717 ${error51.message}
34102
+ `));
34103
+ process.exit(1);
34104
+ }
34105
+ });
34106
+ program.command("skills").description("Organization skills learned from users").command("suggest <file>").description("Suggest saving a SKILL.md as an organization skill; the user reviews it before it is saved").requiredOption("--title <text>", 'Short title shown to the user, e.g. "Always use Conventional Commits"').action(async (file2, options) => {
34107
+ try {
34108
+ await skillsSuggestCommand(file2, options);
34109
+ } catch (error51) {
34110
+ if (error51 instanceof Error) console.error(import_chalk25.default.red(`
34111
+ \u2717 ${error51.message}
34080
34112
  `));
34081
34113
  process.exit(1);
34082
34114
  }
@@ -34092,6 +34124,7 @@ if (isAgentMode()) {
34092
34124
  "service",
34093
34125
  "media",
34094
34126
  "history",
34127
+ "skills",
34095
34128
  "slack",
34096
34129
  "computer",
34097
34130
  "automation",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.782",
3
+ "version": "0.2.784",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {