replicas-cli 0.2.469 → 0.2.471
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/dist/index.mjs +81 -37
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -9325,7 +9325,7 @@ LENGTH=$(stat -c%s "$FILE" 2>/dev/null || stat -f%z "$FILE")
|
|
|
9325
9325
|
|
|
9326
9326
|
# 1. Reserve an upload URL + file ID.
|
|
9327
9327
|
RESERVE=$(curl -s -G "https://slack.com/api/files.getUploadURLExternal" \\
|
|
9328
|
-
-H "Authorization: Bearer $
|
|
9328
|
+
-H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
|
|
9329
9329
|
--data-urlencode "filename=$FILENAME" \\
|
|
9330
9330
|
--data-urlencode "length=$LENGTH")
|
|
9331
9331
|
UPLOAD_URL=$(echo "$RESERVE" | jq -r '.upload_url')
|
|
@@ -9340,7 +9340,7 @@ curl -s -X POST "$UPLOAD_URL" \\
|
|
|
9340
9340
|
|
|
9341
9341
|
# 3. Complete the upload, sharing it into the channel/thread with the dashboard link.
|
|
9342
9342
|
curl -s -X POST "https://slack.com/api/files.completeUploadExternal" \\
|
|
9343
|
-
-H "Authorization: Bearer $
|
|
9343
|
+
-H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
|
|
9344
9344
|
-H "Content-Type: application/json; charset=utf-8" \\
|
|
9345
9345
|
-d "{
|
|
9346
9346
|
\\"files\\": [{\\"id\\": \\"$FILE_ID\\", \\"title\\": \\"Screenshot\\"}],
|
|
@@ -9851,10 +9851,10 @@ This guide covers how to interact with Slack from within your Replicas workspace
|
|
|
9851
9851
|
|
|
9852
9852
|
## Prerequisites
|
|
9853
9853
|
|
|
9854
|
-
Check if the \`
|
|
9854
|
+
Check if the \`REPLICAS_SLACK_BOT_TOKEN\` environment variable is set:
|
|
9855
9855
|
|
|
9856
9856
|
\`\`\`bash
|
|
9857
|
-
echo "\${
|
|
9857
|
+
echo "\${REPLICAS_SLACK_BOT_TOKEN:+set}"
|
|
9858
9858
|
\`\`\`
|
|
9859
9859
|
|
|
9860
9860
|
- If **set**: Your workspace has Slack access. You can use the Slack Web API as described below.
|
|
@@ -9862,7 +9862,7 @@ echo "\${SLACK_BOT_TOKEN:+set}"
|
|
|
9862
9862
|
|
|
9863
9863
|
## Using the Slack API
|
|
9864
9864
|
|
|
9865
|
-
All requests use the \`$
|
|
9865
|
+
All requests use the \`$REPLICAS_SLACK_BOT_TOKEN\` for authentication via the Slack Web API.
|
|
9866
9866
|
|
|
9867
9867
|
### Fetching a Thread from a Slack Link
|
|
9868
9868
|
|
|
@@ -9873,14 +9873,14 @@ If you encounter a Slack message link (e.g. \`https://team.slack.com/archives/C0
|
|
|
9873
9873
|
|
|
9874
9874
|
\`\`\`bash
|
|
9875
9875
|
curl -s "https://slack.com/api/conversations.replies?channel=CHANNEL_ID&ts=THREAD_TS" \\
|
|
9876
|
-
-H "Authorization: Bearer $
|
|
9876
|
+
-H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN"
|
|
9877
9877
|
\`\`\`
|
|
9878
9878
|
|
|
9879
9879
|
### Sending a Message
|
|
9880
9880
|
|
|
9881
9881
|
\`\`\`bash
|
|
9882
9882
|
curl -s -X POST "https://slack.com/api/chat.postMessage" \\
|
|
9883
|
-
-H "Authorization: Bearer $
|
|
9883
|
+
-H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
|
|
9884
9884
|
-H "Content-Type: application/json" \\
|
|
9885
9885
|
-d '{
|
|
9886
9886
|
"channel": "CHANNEL_ID",
|
|
@@ -9919,7 +9919,7 @@ The channel and thread flags default to \`SLACK_CHANNEL_ID\` and \`SLACK_THREAD_
|
|
|
9919
9919
|
|
|
9920
9920
|
\`\`\`bash
|
|
9921
9921
|
curl -s "https://slack.com/api/search.messages?query=YOUR_SEARCH_QUERY" \\
|
|
9922
|
-
-H "Authorization: Bearer $
|
|
9922
|
+
-H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN"
|
|
9923
9923
|
\`\`\`
|
|
9924
9924
|
|
|
9925
9925
|
### Uploading Files
|
|
@@ -9933,7 +9933,7 @@ LENGTH=$(stat -c%s "$FILE" 2>/dev/null || stat -f%z "$FILE")
|
|
|
9933
9933
|
|
|
9934
9934
|
# 1. Reserve an upload URL + file ID.
|
|
9935
9935
|
RESERVE=$(curl -s -G "https://slack.com/api/files.getUploadURLExternal" \\
|
|
9936
|
-
-H "Authorization: Bearer $
|
|
9936
|
+
-H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
|
|
9937
9937
|
--data-urlencode "filename=$FILENAME" \\
|
|
9938
9938
|
--data-urlencode "length=$LENGTH")
|
|
9939
9939
|
UPLOAD_URL=$(echo "$RESERVE" | jq -r '.upload_url')
|
|
@@ -9948,7 +9948,7 @@ curl -s -X POST "$UPLOAD_URL" \\
|
|
|
9948
9948
|
|
|
9949
9949
|
# 3. Complete the upload and share into a channel (and optionally a thread).
|
|
9950
9950
|
curl -s -X POST "https://slack.com/api/files.completeUploadExternal" \\
|
|
9951
|
-
-H "Authorization: Bearer $
|
|
9951
|
+
-H "Authorization: Bearer $REPLICAS_SLACK_BOT_TOKEN" \\
|
|
9952
9952
|
-H "Content-Type: application/json; charset=utf-8" \\
|
|
9953
9953
|
-d "{
|
|
9954
9954
|
\\"files\\": [{\\"id\\": \\"$FILE_ID\\", \\"title\\": \\"File title\\"}],
|
|
@@ -10084,7 +10084,7 @@ function formatTurnElapsed(ms) {
|
|
|
10084
10084
|
}
|
|
10085
10085
|
|
|
10086
10086
|
// ../shared/src/cli-version.ts
|
|
10087
|
-
var CLI_VERSION = "0.2.
|
|
10087
|
+
var CLI_VERSION = "0.2.471";
|
|
10088
10088
|
|
|
10089
10089
|
// ../shared/src/version.ts
|
|
10090
10090
|
function compareVersions(v1, v2) {
|
|
@@ -25683,8 +25683,9 @@ function parseOpencodeEvents(events) {
|
|
|
25683
25683
|
if (event.type === "event_msg" && event.payload.type === "user_message") {
|
|
25684
25684
|
const message = event.payload.message;
|
|
25685
25685
|
if (typeof message === "string" && message.trim()) {
|
|
25686
|
+
const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
|
|
25686
25687
|
messages.push({
|
|
25687
|
-
id: `opencode-user-${event.timestamp}
|
|
25688
|
+
id: typeof messageId === "string" ? messageId : `opencode-user-${event.timestamp}`,
|
|
25688
25689
|
type: "user",
|
|
25689
25690
|
content: message,
|
|
25690
25691
|
timestamp: event.timestamp
|
|
@@ -25696,7 +25697,7 @@ function parseOpencodeEvents(events) {
|
|
|
25696
25697
|
const error51 = assistantError(event.payload.info);
|
|
25697
25698
|
if (error51) {
|
|
25698
25699
|
messages.push({
|
|
25699
|
-
id: `opencode
|
|
25700
|
+
id: `opencode-${event.type}-${event.timestamp}`,
|
|
25700
25701
|
type: "error",
|
|
25701
25702
|
message: error51,
|
|
25702
25703
|
timestamp: event.timestamp
|
|
@@ -25707,7 +25708,7 @@ function parseOpencodeEvents(events) {
|
|
|
25707
25708
|
if (event.type === "opencode-error") {
|
|
25708
25709
|
const message = typeof event.payload.message === "string" ? event.payload.message : "Opencode run failed";
|
|
25709
25710
|
messages.push({
|
|
25710
|
-
id: `opencode
|
|
25711
|
+
id: `opencode-${event.type}-${event.timestamp}`,
|
|
25711
25712
|
type: "error",
|
|
25712
25713
|
message,
|
|
25713
25714
|
timestamp: event.timestamp
|
|
@@ -25718,7 +25719,7 @@ function parseOpencodeEvents(events) {
|
|
|
25718
25719
|
const tool = typeof event.payload.tool === "string" ? event.payload.tool : "tool";
|
|
25719
25720
|
const input = event.payload.input ?? event.payload.arguments;
|
|
25720
25721
|
const callId = typeof event.payload.callID === "string" ? event.payload.callID : null;
|
|
25721
|
-
const id2 = callId ? `opencode-${callId}` : `opencode-${event.
|
|
25722
|
+
const id2 = callId ? `opencode-${callId}` : `opencode-${event.type}-${event.timestamp}`;
|
|
25722
25723
|
upsertDisplayMessage(messages, createCallDisplayMessage({
|
|
25723
25724
|
id: id2,
|
|
25724
25725
|
server: "opencode",
|
|
@@ -25731,7 +25732,7 @@ function parseOpencodeEvents(events) {
|
|
|
25731
25732
|
}
|
|
25732
25733
|
const part = partFromEvent(event);
|
|
25733
25734
|
if (!part) continue;
|
|
25734
|
-
let id = `opencode-${event.
|
|
25735
|
+
let id = `opencode-${event.type}-${event.timestamp}`;
|
|
25735
25736
|
if (typeof part.callID === "string") id = `opencode-${part.callID}`;
|
|
25736
25737
|
else if (typeof part.id === "string") id = `opencode-${part.id}`;
|
|
25737
25738
|
const time3 = isRecord(part.time) ? part.time : null;
|
|
@@ -26673,38 +26674,81 @@ function stableString(value) {
|
|
|
26673
26674
|
return String(value);
|
|
26674
26675
|
}
|
|
26675
26676
|
}
|
|
26676
|
-
function
|
|
26677
|
-
if (
|
|
26678
|
-
|
|
26679
|
-
return false;
|
|
26677
|
+
function duplicateKey(message) {
|
|
26678
|
+
if (message.type === "user" || message.type === "agent" || message.type === "reasoning") {
|
|
26679
|
+
return JSON.stringify([message.type, message.content]);
|
|
26680
26680
|
}
|
|
26681
|
-
if (
|
|
26682
|
-
if (
|
|
26683
|
-
if (
|
|
26684
|
-
|
|
26685
|
-
|
|
26686
|
-
|
|
26687
|
-
|
|
26681
|
+
if (message.type === "command") return JSON.stringify([message.type, message.command]);
|
|
26682
|
+
if (message.type === "web_search") return JSON.stringify([message.type, message.query]);
|
|
26683
|
+
if (message.type === "subagent") {
|
|
26684
|
+
return JSON.stringify([
|
|
26685
|
+
message.type,
|
|
26686
|
+
message.description,
|
|
26687
|
+
message.prompt,
|
|
26688
|
+
message.subagentType,
|
|
26689
|
+
message.model
|
|
26690
|
+
]);
|
|
26688
26691
|
}
|
|
26689
|
-
if (
|
|
26690
|
-
return
|
|
26692
|
+
if (message.type === "todo_list") {
|
|
26693
|
+
return JSON.stringify([message.type, stableString(message.items)]);
|
|
26691
26694
|
}
|
|
26692
|
-
if (
|
|
26693
|
-
return
|
|
26695
|
+
if (message.type === "patch") {
|
|
26696
|
+
return JSON.stringify([message.type, stableString(message.operations)]);
|
|
26694
26697
|
}
|
|
26695
|
-
if (
|
|
26696
|
-
return
|
|
26698
|
+
if (message.type === "tool_call") {
|
|
26699
|
+
return JSON.stringify([
|
|
26700
|
+
message.type,
|
|
26701
|
+
message.server,
|
|
26702
|
+
message.tool,
|
|
26703
|
+
stableString(message.input)
|
|
26704
|
+
]);
|
|
26697
26705
|
}
|
|
26698
|
-
return
|
|
26706
|
+
return null;
|
|
26707
|
+
}
|
|
26708
|
+
function duplicateBucketKey(message, bucketOffset = 0) {
|
|
26709
|
+
const key = duplicateKey(message);
|
|
26710
|
+
if (key === null) return null;
|
|
26711
|
+
const bucket = Math.floor(parseTimestampMs(message.timestamp) / DUPLICATE_WINDOW_MS) + bucketOffset;
|
|
26712
|
+
return JSON.stringify([bucket, key]);
|
|
26699
26713
|
}
|
|
26700
26714
|
function mergeCodexAspDisplayMessages(primary, supplemental) {
|
|
26701
26715
|
const merged = [...primary];
|
|
26716
|
+
const firstIndexById = /* @__PURE__ */ new Map();
|
|
26717
|
+
const indexesByDuplicateBucket = /* @__PURE__ */ new Map();
|
|
26718
|
+
const indexMessage = (message, index) => {
|
|
26719
|
+
if (!firstIndexById.has(message.id)) firstIndexById.set(message.id, index);
|
|
26720
|
+
const key = duplicateBucketKey(message);
|
|
26721
|
+
if (key === null) return;
|
|
26722
|
+
const indexes = indexesByDuplicateBucket.get(key) ?? /* @__PURE__ */ new Set();
|
|
26723
|
+
indexes.add(index);
|
|
26724
|
+
indexesByDuplicateBucket.set(key, indexes);
|
|
26725
|
+
};
|
|
26726
|
+
const unindexMessage = (message, index) => {
|
|
26727
|
+
const key = duplicateBucketKey(message);
|
|
26728
|
+
if (key === null) return;
|
|
26729
|
+
const indexes = indexesByDuplicateBucket.get(key);
|
|
26730
|
+
indexes?.delete(index);
|
|
26731
|
+
if (indexes?.size === 0) indexesByDuplicateBucket.delete(key);
|
|
26732
|
+
};
|
|
26733
|
+
merged.forEach(indexMessage);
|
|
26702
26734
|
for (const message of supplemental) {
|
|
26703
|
-
|
|
26704
|
-
if (duplicateIndex ===
|
|
26705
|
-
|
|
26735
|
+
let duplicateIndex = firstIndexById.get(message.id);
|
|
26736
|
+
if (duplicateIndex === void 0) {
|
|
26737
|
+
for (let bucketOffset = -1; bucketOffset <= 1; bucketOffset += 1) {
|
|
26738
|
+
const key = duplicateBucketKey(message, bucketOffset);
|
|
26739
|
+
for (const index of (key === null ? void 0 : indexesByDuplicateBucket.get(key)) ?? []) {
|
|
26740
|
+
if (nearTimestamp(merged[index].timestamp, message.timestamp) && (duplicateIndex === void 0 || index < duplicateIndex)) {
|
|
26741
|
+
duplicateIndex = index;
|
|
26742
|
+
}
|
|
26743
|
+
}
|
|
26744
|
+
}
|
|
26745
|
+
}
|
|
26746
|
+
if (duplicateIndex === void 0) {
|
|
26747
|
+
indexMessage(message, merged.push(message) - 1);
|
|
26706
26748
|
} else if (message.type === "user") {
|
|
26749
|
+
unindexMessage(merged[duplicateIndex], duplicateIndex);
|
|
26707
26750
|
merged[duplicateIndex] = { ...merged[duplicateIndex], timestamp: message.timestamp };
|
|
26751
|
+
indexMessage(merged[duplicateIndex], duplicateIndex);
|
|
26708
26752
|
}
|
|
26709
26753
|
}
|
|
26710
26754
|
return merged.map((message, index) => ({ message, index })).sort((a, b) => parseTimestampMs(a.message.timestamp) - parseTimestampMs(b.message.timestamp) || a.index - b.index).map(({ message }) => message);
|