replicas-cli 0.3.223 → 0.3.225

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 +128 -100
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -18056,11 +18056,108 @@ Keep it under 250 words plus the lists. Do not paste the hooks or system prompt
18056
18056
  }
18057
18057
  });
18058
18058
 
18059
+ // ../shared/src/runtime-env.ts
18060
+ function shellQuotePosix(value) {
18061
+ return `'${value.split("'").join("'\\''")}'`;
18062
+ }
18063
+ function serializePosixEnvFile(env, unsetKeys = []) {
18064
+ return `${[
18065
+ ...[...unsetKeys].map((key) => `unset ${key}`),
18066
+ ...Object.entries(env).filter(([, value]) => value.length > 0).map(([key, value]) => `export ${key}=${shellQuotePosix(value)}`)
18067
+ ].join("\n")}
18068
+ `;
18069
+ }
18070
+ function parsePosixEnvUnsetKeys(content) {
18071
+ return content.split("\n").filter((line) => line.startsWith("unset ")).map((line) => line.slice("unset ".length).trim());
18072
+ }
18073
+ function parsePosixEnvFile(content) {
18074
+ const result = {};
18075
+ let pos = 0;
18076
+ while (pos < content.length) {
18077
+ let lineStart;
18078
+ if (pos === 0 || content[pos - 1] === "\n") {
18079
+ lineStart = pos;
18080
+ } else {
18081
+ const nl2 = content.indexOf("\n", pos);
18082
+ if (nl2 === -1) break;
18083
+ lineStart = nl2 + 1;
18084
+ }
18085
+ if (!content.startsWith("export ", lineStart)) {
18086
+ const nl2 = content.indexOf("\n", lineStart);
18087
+ if (nl2 === -1) break;
18088
+ pos = nl2 + 1;
18089
+ continue;
18090
+ }
18091
+ const nameStart = lineStart + "export ".length;
18092
+ const eqIdx = content.indexOf("=", nameStart);
18093
+ if (eqIdx === -1) break;
18094
+ const name = content.slice(nameStart, eqIdx).trim();
18095
+ let cursor = eqIdx + 1;
18096
+ if (content[cursor] !== "'") {
18097
+ const nl2 = content.indexOf("\n", cursor);
18098
+ pos = nl2 === -1 ? content.length : nl2 + 1;
18099
+ continue;
18100
+ }
18101
+ cursor += 1;
18102
+ let value = "";
18103
+ let closed = false;
18104
+ while (cursor < content.length) {
18105
+ const ch = content[cursor];
18106
+ if (ch === "'") {
18107
+ if (content.startsWith("\\''", cursor + 1)) {
18108
+ value += "'";
18109
+ cursor += 4;
18110
+ continue;
18111
+ }
18112
+ cursor += 1;
18113
+ closed = true;
18114
+ break;
18115
+ }
18116
+ value += ch;
18117
+ cursor += 1;
18118
+ }
18119
+ if (closed && name) {
18120
+ result[name] = value;
18121
+ }
18122
+ const nl = content.indexOf("\n", cursor);
18123
+ pos = nl === -1 ? content.length : nl + 1;
18124
+ }
18125
+ return result;
18126
+ }
18127
+ var init_runtime_env = __esm({
18128
+ "../shared/src/runtime-env.ts"() {
18129
+ "use strict";
18130
+ }
18131
+ });
18132
+
18133
+ // ../shared/src/engine/environment.ts
18134
+ var ENGINE_PORT;
18135
+ var init_environment2 = __esm({
18136
+ "../shared/src/engine/environment.ts"() {
18137
+ "use strict";
18138
+ init_type_guards();
18139
+ ENGINE_PORT = 3737;
18140
+ }
18141
+ });
18142
+
18143
+ // ../shared/src/git.ts
18144
+ var GIT_CREDENTIAL_HELPER_FILENAME;
18145
+ var init_git = __esm({
18146
+ "../shared/src/git.ts"() {
18147
+ "use strict";
18148
+ init_url();
18149
+ init_runtime_env();
18150
+ init_environment2();
18151
+ GIT_CREDENTIAL_HELPER_FILENAME = ".git-credential-replicas";
18152
+ }
18153
+ });
18154
+
18059
18155
  // ../shared/src/default-skills/replicas-agent/abilities/github.ts
18060
18156
  var SECTION4, REFERENCE4, GITHUB_ABILITY;
18061
18157
  var init_github2 = __esm({
18062
18158
  "../shared/src/default-skills/replicas-agent/abilities/github.ts"() {
18063
18159
  "use strict";
18160
+ init_git();
18064
18161
  SECTION4 = `### GitHub
18065
18162
  Use the pre-authenticated \`gh\` CLI for repository workflows and the workspace-scoped TypeScript SDK for GitHub API calls.
18066
18163
 
@@ -18071,7 +18168,8 @@ Use this when:
18071
18168
  - You're opening pull requests that build on each other (a stack)
18072
18169
  - You need to interact with GitHub issues or actions
18073
18170
  - You need to use the GitHub API for advanced operations
18074
- - You need to include images in PR descriptions`;
18171
+ - You need to include images in PR descriptions
18172
+ - Pushing or opening a pull request failed`;
18075
18173
  REFERENCE4 = `# GitHub Integration
18076
18174
 
18077
18175
  This guide covers how to interact with GitHub from within your Replicas workspace. Prefer \`@replicas/sdk\` for API calls so batching and data processing stay in one TypeScript program. The \`gh\` CLI remains useful for ergonomic pull request and git-adjacent workflows.
@@ -18111,6 +18209,14 @@ gh pr checks 123
18111
18209
  gh pr merge 123
18112
18210
  \`\`\`
18113
18211
 
18212
+ ### When pushing or opening a pull request fails
18213
+
18214
+ Tell the person the real cause and the real fix, not a guess. Check \`git remote -v\`, \`git config --show-origin --get-all credential.helper\`, and \`gh auth status\` first.
18215
+
18216
+ - **The Replicas credential helper says this workspace has no credentials for the repository:** the repository isn't in the workspace's environment, so this workspace can't push to it even if you cloned it yourself. Say so, and that a workspace on an environment that includes the repository can make the change. When it says it has no credentials for the whole host, check \`~/.replicas/logs\` for a failed GitHub token refresh before choosing a cause.
18217
+ - **\`Resource not accessible by integration\`, or a 403 or 404 that isn't a rate limit:** the token in use can't write to that repository. When it isn't the workspace's own (Replicas configures \`gh\` and the \`~/${GIT_CREDENTIAL_HELPER_FILENAME}\` credential helper), it came from the environment, such as a start hook or variable: say that token lacks access and retry with the workspace's own credentials. Otherwise the Replicas GitHub App can't reach the repository: an organization admin has to install it there or grant it access. A rate limit (\`API rate limit exceeded\`, \`x-ratelimit-remaining: 0\`) only needs a wait and a retry.
18218
+ - Say to reconnect GitHub only when the error itself says so, which happens when PR user attribution is on and the person's GitHub account is missing or expired.
18219
+
18114
18220
  ### Stacked Pull Requests
18115
18221
 
18116
18222
  When a change spans pull requests that build on each other, open each one with \`--base\` set to the branch below it, then link them into a GitHub stack. GitHub then shows the whole stack on every pull request in it. The \`gh stack\` extension is pre-installed.
@@ -28320,16 +28426,25 @@ var init_learned_skills = __esm({
28320
28426
 
28321
28427
  // ../shared/src/user-message-matching.ts
28322
28428
  function parseTimestampMs(timestamp) {
28323
- const value = typeof timestamp === "number" ? timestamp : Date.parse(timestamp);
28324
- return Number.isFinite(value) ? value : 0;
28429
+ if (typeof timestamp === "number") return Number.isFinite(timestamp) ? timestamp : 0;
28430
+ let value = parsedTimestamps.get(timestamp);
28431
+ if (value === void 0) {
28432
+ const parsed = Date.parse(timestamp);
28433
+ value = Number.isFinite(parsed) ? parsed : 0;
28434
+ if (parsedTimestamps.size >= 5e4) parsedTimestamps.clear();
28435
+ parsedTimestamps.set(timestamp, value);
28436
+ }
28437
+ return value;
28325
28438
  }
28326
28439
  function areUserMessagesWithinMatchWindow(a, b) {
28327
28440
  return a.content === b.content && Math.abs(parseTimestampMs(a.timestamp) - parseTimestampMs(b.timestamp)) <= USER_MESSAGE_MATCH_GRACE_PERIOD_MS;
28328
28441
  }
28442
+ var parsedTimestamps;
28329
28443
  var init_user_message_matching = __esm({
28330
28444
  "../shared/src/user-message-matching.ts"() {
28331
28445
  "use strict";
28332
28446
  init_constants();
28447
+ parsedTimestamps = /* @__PURE__ */ new Map();
28333
28448
  }
28334
28449
  });
28335
28450
 
@@ -30633,7 +30748,13 @@ function filterDisplayMessages(messages, provider2) {
30633
30748
  }
30634
30749
  result = result.flatMap((msg) => {
30635
30750
  if (msg.type !== "user") return [msg];
30636
- const { content, files, walkthroughs, appshots, annotations } = stripAttachmentNote(stripReplicasInstructionBlock(msg.content).trim());
30751
+ let stripped = strippedUserContents.get(msg.content);
30752
+ if (!stripped) {
30753
+ stripped = stripAttachmentNote(stripReplicasInstructionBlock(msg.content).trim());
30754
+ if (strippedUserContents.size >= 5e3) strippedUserContents.clear();
30755
+ strippedUserContents.set(msg.content, stripped);
30756
+ }
30757
+ const { content, files, walkthroughs, appshots, annotations } = stripped;
30637
30758
  if (INTERRUPTED_MESSAGE_REGEX.test(content)) {
30638
30759
  return [{ id: msg.id, type: "interruption", timestamp: msg.timestamp }];
30639
30760
  }
@@ -30651,7 +30772,7 @@ function filterDisplayMessages(messages, provider2) {
30651
30772
  });
30652
30773
  return result;
30653
30774
  }
30654
- var INTERRUPTION_DEDUP_WINDOW_MS;
30775
+ var INTERRUPTION_DEDUP_WINDOW_MS, strippedUserContents;
30655
30776
  var init_parsers = __esm({
30656
30777
  "../shared/src/display-message/parsers/index.ts"() {
30657
30778
  "use strict";
@@ -30676,6 +30797,7 @@ var init_parsers = __esm({
30676
30797
  init_mcp();
30677
30798
  init_utils();
30678
30799
  INTERRUPTION_DEDUP_WINDOW_MS = 15e3;
30800
+ strippedUserContents = /* @__PURE__ */ new Map();
30679
30801
  }
30680
30802
  });
30681
30803
 
@@ -31055,80 +31177,6 @@ var init_egress = __esm({
31055
31177
  }
31056
31178
  });
31057
31179
 
31058
- // ../shared/src/runtime-env.ts
31059
- function shellQuotePosix(value) {
31060
- return `'${value.split("'").join("'\\''")}'`;
31061
- }
31062
- function serializePosixEnvFile(env, unsetKeys = []) {
31063
- return `${[
31064
- ...[...unsetKeys].map((key) => `unset ${key}`),
31065
- ...Object.entries(env).filter(([, value]) => value.length > 0).map(([key, value]) => `export ${key}=${shellQuotePosix(value)}`)
31066
- ].join("\n")}
31067
- `;
31068
- }
31069
- function parsePosixEnvUnsetKeys(content) {
31070
- return content.split("\n").filter((line) => line.startsWith("unset ")).map((line) => line.slice("unset ".length).trim());
31071
- }
31072
- function parsePosixEnvFile(content) {
31073
- const result = {};
31074
- let pos = 0;
31075
- while (pos < content.length) {
31076
- let lineStart;
31077
- if (pos === 0 || content[pos - 1] === "\n") {
31078
- lineStart = pos;
31079
- } else {
31080
- const nl2 = content.indexOf("\n", pos);
31081
- if (nl2 === -1) break;
31082
- lineStart = nl2 + 1;
31083
- }
31084
- if (!content.startsWith("export ", lineStart)) {
31085
- const nl2 = content.indexOf("\n", lineStart);
31086
- if (nl2 === -1) break;
31087
- pos = nl2 + 1;
31088
- continue;
31089
- }
31090
- const nameStart = lineStart + "export ".length;
31091
- const eqIdx = content.indexOf("=", nameStart);
31092
- if (eqIdx === -1) break;
31093
- const name = content.slice(nameStart, eqIdx).trim();
31094
- let cursor = eqIdx + 1;
31095
- if (content[cursor] !== "'") {
31096
- const nl2 = content.indexOf("\n", cursor);
31097
- pos = nl2 === -1 ? content.length : nl2 + 1;
31098
- continue;
31099
- }
31100
- cursor += 1;
31101
- let value = "";
31102
- let closed = false;
31103
- while (cursor < content.length) {
31104
- const ch = content[cursor];
31105
- if (ch === "'") {
31106
- if (content.startsWith("\\''", cursor + 1)) {
31107
- value += "'";
31108
- cursor += 4;
31109
- continue;
31110
- }
31111
- cursor += 1;
31112
- closed = true;
31113
- break;
31114
- }
31115
- value += ch;
31116
- cursor += 1;
31117
- }
31118
- if (closed && name) {
31119
- result[name] = value;
31120
- }
31121
- const nl = content.indexOf("\n", cursor);
31122
- pos = nl === -1 ? content.length : nl + 1;
31123
- }
31124
- return result;
31125
- }
31126
- var init_runtime_env = __esm({
31127
- "../shared/src/runtime-env.ts"() {
31128
- "use strict";
31129
- }
31130
- });
31131
-
31132
31180
  // ../shared/src/dotenv.ts
31133
31181
  var init_dotenv = __esm({
31134
31182
  "../shared/src/dotenv.ts"() {
@@ -31136,26 +31184,6 @@ var init_dotenv = __esm({
31136
31184
  }
31137
31185
  });
31138
31186
 
31139
- // ../shared/src/engine/environment.ts
31140
- var ENGINE_PORT;
31141
- var init_environment2 = __esm({
31142
- "../shared/src/engine/environment.ts"() {
31143
- "use strict";
31144
- init_type_guards();
31145
- ENGINE_PORT = 3737;
31146
- }
31147
- });
31148
-
31149
- // ../shared/src/git.ts
31150
- var init_git = __esm({
31151
- "../shared/src/git.ts"() {
31152
- "use strict";
31153
- init_url();
31154
- init_runtime_env();
31155
- init_environment2();
31156
- }
31157
- });
31158
-
31159
31187
  // ../shared/src/code-host.ts
31160
31188
  var init_code_host = __esm({
31161
31189
  "../shared/src/code-host.ts"() {
@@ -31364,7 +31392,7 @@ var CLI_VERSION;
31364
31392
  var init_cli_version = __esm({
31365
31393
  "../shared/src/cli-version.ts"() {
31366
31394
  "use strict";
31367
- CLI_VERSION = "0.3.223";
31395
+ CLI_VERSION = "0.3.225";
31368
31396
  }
31369
31397
  });
31370
31398
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.3.223",
3
+ "version": "0.3.225",
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": {