replicas-engine 0.1.213 → 0.1.215
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/src/index.js +266 -145
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -276,8 +276,200 @@ function parsePosixEnvFile(content) {
|
|
|
276
276
|
return result;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
// ../shared/src/default-skills/replicas-agent/abilities/computer.ts
|
|
280
|
+
var SECTION = `### Computer use (Linux desktop control)
|
|
281
|
+
Drive the workspace's Linux desktop - open a browser, click, type, scroll, screenshot, record - and surface a live noVNC viewer to the user via the \`replicas computer\` CLI. Every Replicas workspace boots with Xvfb / openbox / x11vnc / noVNC pre-installed.
|
|
282
|
+
|
|
283
|
+
**Reference:** \`references/COMPUTER-USE.md\`
|
|
284
|
+
|
|
285
|
+
Use this when:
|
|
286
|
+
- A task requires interacting with a website, web app, or desktop application that has no usable API
|
|
287
|
+
- You want the user to watch the agent work - \`replicas computer start\` exposes a \`Desktop\` tab in the dashboard
|
|
288
|
+
- You're testing UI changes in a browser before reporting them as done
|
|
289
|
+
- You want to record a screen capture of a task as proof to share back`;
|
|
290
|
+
var REFERENCE = `# Computer use (Linux desktop control)
|
|
291
|
+
|
|
292
|
+
Every Replicas workspace boots with a full Linux desktop stack - Xvfb (1920\xD71080), openbox, tint2, x11vnc, noVNC, ffmpeg, and Google Chrome. You drive it through the \`replicas computer\` CLI.
|
|
293
|
+
|
|
294
|
+
Use this for anything the user can't reasonably do via an API - clicking around web apps, filling forms, testing UI changes, dragging files between desktop apps, recording a walkthrough.
|
|
295
|
+
|
|
296
|
+
## When to use it
|
|
297
|
+
|
|
298
|
+
- **Prefer real APIs first.** If a task has a CLI or HTTP API (GitHub, Linear, Slack, Replicas itself), use that. Driving a UI is slower, flakier, and less auditable.
|
|
299
|
+
- **Use it when there's no API**: testing a frontend you just changed, navigating a vendor portal, demonstrating a flow on video.
|
|
300
|
+
- **Use it when the user wants to watch.** \`replicas computer start\` exposes a live \`Desktop\` tab in the dashboard - they can watch you work in real time.
|
|
301
|
+
|
|
302
|
+
## Never use raw \`xdotool\` / \`scrot\` / \`ffmpeg\` directly
|
|
303
|
+
|
|
304
|
+
The CLI is the canonical surface. Chat transcripts that show \`DISPLAY=:99 xdotool key Return\` are noisy and break when the underlying stack changes. Always call the CLI:
|
|
305
|
+
|
|
306
|
+
\`\`\`bash
|
|
307
|
+
# DO
|
|
308
|
+
replicas computer key Return
|
|
309
|
+
replicas computer screenshot /tmp/state.png
|
|
310
|
+
|
|
311
|
+
# DON'T
|
|
312
|
+
DISPLAY=:99 xdotool key Return
|
|
313
|
+
scrot /tmp/state.png
|
|
314
|
+
\`\`\`
|
|
315
|
+
|
|
316
|
+
## Quickstart
|
|
317
|
+
|
|
318
|
+
\`\`\`bash
|
|
319
|
+
# 1) Make the desktop visible to the user (creates an authenticated noVNC
|
|
320
|
+
# preview on port 6080, prints the viewer URL, adds a "Desktop" tab to the
|
|
321
|
+
# dashboard).
|
|
322
|
+
replicas computer start
|
|
323
|
+
|
|
324
|
+
# 2) Launch a browser on the workspace display.
|
|
325
|
+
replicas computer launch chrome
|
|
326
|
+
|
|
327
|
+
# 3) Take a screenshot so you can see what's there.
|
|
328
|
+
replicas computer screenshot /tmp/state.png
|
|
329
|
+
# (Read the PNG yourself before deciding where to click.)
|
|
330
|
+
|
|
331
|
+
# 4) Drive the UI.
|
|
332
|
+
replicas computer key ctrl+l # focus address bar
|
|
333
|
+
replicas computer type "https://news.ycombinator.com"
|
|
334
|
+
replicas computer key Return
|
|
335
|
+
replicas computer click 521 700 # click coordinates from the screenshot
|
|
336
|
+
replicas computer scroll down --amount 5
|
|
337
|
+
|
|
338
|
+
# 5) (Optional) Record a screencap to share back.
|
|
339
|
+
replicas computer record start /tmp/demo.mp4 --fps 60
|
|
340
|
+
# ... do stuff ...
|
|
341
|
+
replicas computer record stop
|
|
342
|
+
replicas media upload /tmp/demo.mp4
|
|
343
|
+
|
|
344
|
+
# 6) Tear down the live preview when done (services keep running for next time).
|
|
345
|
+
replicas computer stop
|
|
346
|
+
\`\`\`
|
|
347
|
+
|
|
348
|
+
## Command reference
|
|
349
|
+
|
|
350
|
+
### \`replicas computer start [--port N] [--display :N] [--size WxH]\`
|
|
351
|
+
Ensures all desktop services are running and creates an authenticated noVNC preview. Prints the viewer URL (\`https://<port>-<hash>.tryreplicas.com/\`). The Replicas dashboard automatically shows a \`Desktop\` tab while this preview is live - point the user at it instead of pasting the URL.
|
|
352
|
+
|
|
353
|
+
Idempotent - safe to call repeatedly. Use it as the first computer-use command in any session.
|
|
354
|
+
|
|
355
|
+
### \`replicas computer stop [--port N]\`
|
|
356
|
+
Tears down the noVNC preview (the \`Desktop\` tab disappears). The underlying Xvfb / openbox / x11vnc / browser keep running so the next \`start\` is instant.
|
|
357
|
+
|
|
358
|
+
### \`replicas computer status\`
|
|
359
|
+
Prints which desktop services are running and the active preview URL (if any). Useful for debugging when a tool call seems to be doing nothing.
|
|
360
|
+
|
|
361
|
+
### \`replicas computer screenshot <path>\`
|
|
362
|
+
Captures the current desktop to a PNG at the given path. Read the file (e.g. with your Read tool) to see what's on screen - coordinates from the screenshot drive subsequent \`click\` / \`move\` / \`drag\` calls.
|
|
363
|
+
|
|
364
|
+
### \`replicas computer click <x> <y> [--button N] [--double] [--modifiers ctrl+shift]\`
|
|
365
|
+
Move to (x, y) and click. Default is left-click (button 1); pass \`--button 3\` for right-click. \`--modifiers\` holds keys during the click (e.g. ctrl-click a link to open in a new tab).
|
|
366
|
+
|
|
367
|
+
### \`replicas computer move <x> <y>\`
|
|
368
|
+
Move the mouse without clicking. Useful for hovering tooltips.
|
|
369
|
+
|
|
370
|
+
### \`replicas computer type <text> [--delay MS]\`
|
|
371
|
+
Type a literal string into the focused field. Default per-character delay is 12ms (~80 wpm) - feels human and avoids breaking apps that debounce input. Bump \`--delay 30\` for stricter apps.
|
|
372
|
+
|
|
373
|
+
For key combos (not literal text), use \`key\`. \`type "ctrl+l"\` will literally type the seven characters \`c t r l + l\`.
|
|
374
|
+
|
|
375
|
+
### \`replicas computer key <combo>\`
|
|
376
|
+
Press a single key or combo. Examples: \`Return\`, \`Escape\`, \`Tab\`, \`ctrl+l\`, \`ctrl+shift+t\`, \`alt+Left\`, \`Page_Down\`, \`Home\`. Syntax matches \`xdotool key\`.
|
|
377
|
+
|
|
378
|
+
### \`replicas computer scroll <up|down|left|right> [--amount N] [--x X --y Y]\`
|
|
379
|
+
Scroll the wheel. Pass \`--x\` / \`--y\` to hover before scrolling (otherwise scrolls wherever the cursor currently is). Default amount is 3 wheel ticks.
|
|
380
|
+
|
|
381
|
+
### \`replicas computer drag <fromX> <fromY> <toX> <toY>\`
|
|
382
|
+
Press left mouse at (fromX, fromY), drag to (toX, toY), release. For things like dragging a file onto an upload zone.
|
|
383
|
+
|
|
384
|
+
### \`replicas computer launch <app> [args...]\`
|
|
385
|
+
Spawns an app on the workspace display. Built-in aliases:
|
|
386
|
+
- \`chrome\` - Google Chrome with a clean profile and sane flags
|
|
387
|
+
- \`chromium\` - Chromium variant
|
|
388
|
+
- \`firefox\` - Firefox
|
|
389
|
+
- \`terminal\` - xfce4-terminal (modern, themed); \`xterm\` for the classic
|
|
390
|
+
- \`notepad\` / \`editor\` - mousepad (lightweight GTK text editor)
|
|
391
|
+
- \`files\` / \`filemanager\` - thunar (file manager)
|
|
392
|
+
Anything else gets \`exec\`'d verbatim, so \`replicas computer launch xeyes\` works if xeyes is installed.
|
|
393
|
+
|
|
394
|
+
### \`replicas computer record start <path> [--fps N]\`
|
|
395
|
+
Starts an ffmpeg screen recorder. Output is a fragmented MP4 (still playable if the workspace dies mid-record). Default 60fps; drop to 30 if the workspace is CPU-constrained.
|
|
396
|
+
|
|
397
|
+
Only one recording at a time. Re-running \`start\` while one is active fails - call \`stop\` first.
|
|
398
|
+
|
|
399
|
+
### \`replicas computer record stop\`
|
|
400
|
+
SIGINTs ffmpeg, waits for it to finalize the MP4, prints the output path. Upload it with \`replicas media upload <path>\` to share it.
|
|
401
|
+
|
|
402
|
+
## Patterns
|
|
403
|
+
|
|
404
|
+
### Action / screenshot loop
|
|
405
|
+
You are blind between tool calls. After any action that changes the screen, take a screenshot before deciding the next coordinate:
|
|
406
|
+
|
|
407
|
+
\`\`\`bash
|
|
408
|
+
replicas computer click 521 700
|
|
409
|
+
sleep 2 # let the page settle
|
|
410
|
+
replicas computer screenshot /tmp/after-click.png
|
|
411
|
+
# read /tmp/after-click.png, decide next click
|
|
412
|
+
\`\`\`
|
|
413
|
+
|
|
414
|
+
\`sleep\` is a regular shell sleep - there's no \`replicas computer wait\` command, but you can mix shell sleeps freely.
|
|
415
|
+
|
|
416
|
+
### Typing into an address bar
|
|
417
|
+
\`\`\`bash
|
|
418
|
+
replicas computer key ctrl+l # focus address bar
|
|
419
|
+
replicas computer type "https://example.com"
|
|
420
|
+
replicas computer key Return
|
|
421
|
+
sleep 3 # wait for page load
|
|
422
|
+
replicas computer screenshot /tmp/loaded.png
|
|
423
|
+
\`\`\`
|
|
424
|
+
|
|
425
|
+
### Coordinates from screenshots
|
|
426
|
+
The display is 1920\xD71080. Screenshot pixels map 1:1 to click coordinates - if your Read tool shows a button at pixel (520, 700), click \`replicas computer click 520 700\`. **No translation needed.** Modern image-reading models often imagine the screenshot is at a different resolution; trust the \`xdpyinfo\` value (\`replicas computer status\` shows the real size).
|
|
427
|
+
|
|
428
|
+
### Letting the user watch
|
|
429
|
+
Always start the desktop session with \`replicas computer start\` *before* doing anything visual, even if you don't need the URL yourself. The Desktop tab appears in their dashboard. They get to watch and intervene if needed.
|
|
430
|
+
|
|
431
|
+
### Recording a deliverable
|
|
432
|
+
For tasks the user wants proof of:
|
|
433
|
+
\`\`\`bash
|
|
434
|
+
replicas computer start # makes it visible live too
|
|
435
|
+
replicas computer record start /tmp/walkthrough.mp4
|
|
436
|
+
# ... your work ...
|
|
437
|
+
replicas computer record stop
|
|
438
|
+
replicas media upload /tmp/walkthrough.mp4
|
|
439
|
+
\`\`\`
|
|
440
|
+
Then embed the printed \`\` line in your chat reply. See \`MEDIA.md\`.
|
|
441
|
+
|
|
442
|
+
### Cleaning up
|
|
443
|
+
Call \`replicas computer stop\` when you're done with the visual demo so the live preview URL goes away. The services keep running so the next \`start\` is instant.
|
|
444
|
+
|
|
445
|
+
## Failure modes
|
|
446
|
+
|
|
447
|
+
- **"Desktop services script missing"**: workspace image is older than this skill. Tell the user - nothing you can do from the CLI side.
|
|
448
|
+
- **\`xdotool ... failed: Can't open display\`**: Xvfb didn't come up. \`replicas computer status\` will show which service is dead. Re-running any CLI command auto-attempts to start it.
|
|
449
|
+
- **Browser doesn't appear after \`launch chrome\`**: give it 1-2s, then screenshot. Chrome cold-start on the virtual display takes ~500ms but bigger pages take longer.
|
|
450
|
+
- **Live preview shows static / black screen**: the browser may have crashed. \`replicas computer status\` should show no Chrome process - re-launch.
|
|
451
|
+
|
|
452
|
+
## What gets baked in vs. lazy
|
|
453
|
+
|
|
454
|
+
| Component | Where |
|
|
455
|
+
|---|---|
|
|
456
|
+
| \`xvfb\`, \`openbox\`, \`tint2\`, \`x11vnc\`, \`websockify\`, \`xdotool\`, \`scrot\`, \`ffmpeg\`, \`google-chrome\` | Baked into the workspace image |
|
|
457
|
+
| Xvfb / openbox / tint2 / x11vnc / websockify processes | Started at workspace boot (\`replicas-start-desktop-services\`) |
|
|
458
|
+
| noVNC preview URL (port 6080) | **Lazy** - created by \`replicas computer start\` |
|
|
459
|
+
| Dashboard \`Desktop\` tab | Appears when the preview URL is live, disappears on \`stop\` |
|
|
460
|
+
|
|
461
|
+
You can call any of the input tools (\`click\`, \`type\`, \`screenshot\`, etc.) without first calling \`start\` - they'll work since the daemons are running. \`start\` is only needed when you want the user to see the live stream.
|
|
462
|
+
`;
|
|
463
|
+
var COMPUTER_ABILITY = {
|
|
464
|
+
label: "Computer use",
|
|
465
|
+
description: "Drive the workspace's Linux desktop and stream a live noVNC viewer.",
|
|
466
|
+
bullet: "- Driving the workspace Linux desktop (open a browser, click, type, scroll, screenshot, record) and exposing a live noVNC viewer in the dashboard",
|
|
467
|
+
section: SECTION,
|
|
468
|
+
referenceFile: { name: "COMPUTER-USE.md", content: REFERENCE }
|
|
469
|
+
};
|
|
470
|
+
|
|
279
471
|
// ../shared/src/default-skills/replicas-agent/abilities/docker.ts
|
|
280
|
-
var
|
|
472
|
+
var SECTION2 = `### Docker
|
|
281
473
|
Start and use the Docker daemon in Replicas workspaces. Docker is pre-installed but the daemon does not auto-start.
|
|
282
474
|
|
|
283
475
|
**Reference:** \`references/DOCKER.md\`
|
|
@@ -286,7 +478,7 @@ Use this when:
|
|
|
286
478
|
- You need to run \`docker\` or \`docker compose\` commands
|
|
287
479
|
- You need to build or run Docker containers
|
|
288
480
|
- Your task involves containerized services or Docker-based workflows`;
|
|
289
|
-
var
|
|
481
|
+
var REFERENCE2 = `# Docker
|
|
290
482
|
|
|
291
483
|
Docker is pre-installed in Replicas workspaces, but the daemon does **not** auto-start. You must start it manually before running any \`docker\` or \`docker compose\` commands.
|
|
292
484
|
|
|
@@ -315,12 +507,12 @@ var DOCKER_ABILITY = {
|
|
|
315
507
|
label: "Docker",
|
|
316
508
|
description: "Start the daemon, build/run containers, drive `docker compose`.",
|
|
317
509
|
bullet: "- Using Docker (starting the daemon, running containers, docker compose)",
|
|
318
|
-
section:
|
|
319
|
-
referenceFile: { name: "DOCKER.md", content:
|
|
510
|
+
section: SECTION2,
|
|
511
|
+
referenceFile: { name: "DOCKER.md", content: REFERENCE2 }
|
|
320
512
|
};
|
|
321
513
|
|
|
322
514
|
// ../shared/src/default-skills/replicas-agent/abilities/github.ts
|
|
323
|
-
var
|
|
515
|
+
var SECTION3 = `### GitHub
|
|
324
516
|
Use the pre-authenticated \`gh\` CLI for pull requests, issues, actions, and API calls.
|
|
325
517
|
|
|
326
518
|
**Reference:** \`references/GITHUB.md\`
|
|
@@ -330,7 +522,7 @@ Use this when:
|
|
|
330
522
|
- You need to interact with GitHub issues or actions
|
|
331
523
|
- You need to use the GitHub API for advanced operations
|
|
332
524
|
- You need to include images in PR descriptions`;
|
|
333
|
-
var
|
|
525
|
+
var REFERENCE3 = `# GitHub Integration
|
|
334
526
|
|
|
335
527
|
This guide covers how to interact with GitHub from within your Replicas workspace.
|
|
336
528
|
|
|
@@ -456,12 +648,12 @@ var GITHUB_ABILITY = {
|
|
|
456
648
|
label: "GitHub",
|
|
457
649
|
description: "Pre-authenticated `gh` CLI for PRs, issues, releases, and GraphQL.",
|
|
458
650
|
bullet: "- Interacting with GitHub (creating PRs, managing issues, using the API, etc.)",
|
|
459
|
-
section:
|
|
460
|
-
referenceFile: { name: "GITHUB.md", content:
|
|
651
|
+
section: SECTION3,
|
|
652
|
+
referenceFile: { name: "GITHUB.md", content: REFERENCE3 }
|
|
461
653
|
};
|
|
462
654
|
|
|
463
655
|
// ../shared/src/default-skills/replicas-agent/abilities/google.ts
|
|
464
|
-
var
|
|
656
|
+
var SECTION4 = `### Google Workspace (Docs, Sheets, Forms, Drive)
|
|
465
657
|
Create and edit Google Docs, Sheets, and Forms via the Replicas gateway. Files are owned by Replicas \u2014 the integration cannot access pre-existing Google content created outside of it.
|
|
466
658
|
|
|
467
659
|
**Reference:** \`references/GOOGLE.md\`
|
|
@@ -470,7 +662,7 @@ Use this when:
|
|
|
470
662
|
- You need to create or edit a Google Doc, Sheet, or Form
|
|
471
663
|
- You need to share, rename, move, or delete a Replicas-created Google file
|
|
472
664
|
- You need to read responses from a Replicas-created Google Form`;
|
|
473
|
-
var
|
|
665
|
+
var REFERENCE4 = `# Google Workspace (Docs, Sheets, Forms, Drive)
|
|
474
666
|
|
|
475
667
|
This guide covers how to create and edit Google Docs, Sheets, and Forms \u2014 plus do basic Drive file operations \u2014 from inside a Replicas workspace, using the monolith as a gateway to Google's APIs.
|
|
476
668
|
|
|
@@ -731,12 +923,12 @@ var GOOGLE_ABILITY = {
|
|
|
731
923
|
label: "Google Workspace",
|
|
732
924
|
description: "Create / edit Docs, Sheets, Forms, and Drive files via the Replicas gateway.",
|
|
733
925
|
bullet: "- Interacting with Google Workspace (creating and editing Docs, Sheets, and Forms, sharing files, reading form responses, etc.)",
|
|
734
|
-
section:
|
|
735
|
-
referenceFile: { name: "GOOGLE.md", content:
|
|
926
|
+
section: SECTION4,
|
|
927
|
+
referenceFile: { name: "GOOGLE.md", content: REFERENCE4 }
|
|
736
928
|
};
|
|
737
929
|
|
|
738
930
|
// ../shared/src/default-skills/replicas-agent/abilities/linear.ts
|
|
739
|
-
var
|
|
931
|
+
var SECTION5 = `### Linear
|
|
740
932
|
Fetch issues, update state, add comments, and search via the Linear GraphQL API.
|
|
741
933
|
|
|
742
934
|
**Reference:** \`references/LINEAR.md\`
|
|
@@ -745,7 +937,7 @@ Use this when:
|
|
|
745
937
|
- You encounter a Linear issue link and need to understand the task
|
|
746
938
|
- You need to update an issue's state (e.g. mark as done)
|
|
747
939
|
- You need to comment on or search for Linear issues`;
|
|
748
|
-
var
|
|
940
|
+
var REFERENCE5 = `# Linear Integration
|
|
749
941
|
|
|
750
942
|
This guide covers how to interact with Linear from within your Replicas workspace.
|
|
751
943
|
|
|
@@ -820,12 +1012,12 @@ var LINEAR_ABILITY = {
|
|
|
820
1012
|
label: "Linear",
|
|
821
1013
|
description: "Fetch issues, post comments, update states via the Linear GraphQL API.",
|
|
822
1014
|
bullet: "- Interacting with Linear (fetching issues, updating state, commenting, etc.)",
|
|
823
|
-
section:
|
|
824
|
-
referenceFile: { name: "LINEAR.md", content:
|
|
1015
|
+
section: SECTION5,
|
|
1016
|
+
referenceFile: { name: "LINEAR.md", content: REFERENCE5 }
|
|
825
1017
|
};
|
|
826
1018
|
|
|
827
1019
|
// ../shared/src/default-skills/replicas-agent/abilities/media.ts
|
|
828
|
-
var
|
|
1020
|
+
var SECTION6 = `### Media
|
|
829
1021
|
Share screenshots, screen recordings, generated diagrams, and audio clips inline in the Replicas chat (and as references in external messages).
|
|
830
1022
|
|
|
831
1023
|
**Reference:** \`references/MEDIA.md\`
|
|
@@ -834,7 +1026,7 @@ Use this when:
|
|
|
834
1026
|
- You produce a screenshot, recording, generated image, or audio clip the user should see
|
|
835
1027
|
- You record video output (browser automation, screen capture) \u2014 including the recommended aspect ratio and FPS
|
|
836
1028
|
- You need to embed media in a Slack/Linear/GitHub message AND keep a referenceable copy in the Replicas dashboard`;
|
|
837
|
-
var
|
|
1029
|
+
var REFERENCE6 = `# Media (Screenshots, Recordings, Audio)
|
|
838
1030
|
|
|
839
1031
|
This guide covers how to share screenshots, screen recordings, generated diagrams, and audio clips with the user inline in the Replicas chat.
|
|
840
1032
|
|
|
@@ -948,12 +1140,12 @@ var MEDIA_ABILITY = {
|
|
|
948
1140
|
label: "Media",
|
|
949
1141
|
description: "Share screenshots, recordings, generated images, and audio clips.",
|
|
950
1142
|
bullet: "- Sharing media (screenshots, screen recordings, generated diagrams, audio clips) \u2014 including in your Replicas chat reply and to external platforms",
|
|
951
|
-
section:
|
|
952
|
-
referenceFile: { name: "MEDIA.md", content:
|
|
1143
|
+
section: SECTION6,
|
|
1144
|
+
referenceFile: { name: "MEDIA.md", content: REFERENCE6 }
|
|
953
1145
|
};
|
|
954
1146
|
|
|
955
1147
|
// ../shared/src/default-skills/replicas-agent/abilities/previews.ts
|
|
956
|
-
var
|
|
1148
|
+
var SECTION7 = `### Previews
|
|
957
1149
|
Expose locally running services (web apps, APIs, databases) as public preview URLs so humans can interact with them directly.
|
|
958
1150
|
|
|
959
1151
|
**Reference:** \`references/PREVIEWS.md\`
|
|
@@ -962,7 +1154,7 @@ Use this when:
|
|
|
962
1154
|
- You need to start a service that a human should view or interact with
|
|
963
1155
|
- The task involves UI work that benefits from human review
|
|
964
1156
|
- You are verifying frontend/backend integrations visually`;
|
|
965
|
-
var
|
|
1157
|
+
var REFERENCE7 = `# Preview URLs
|
|
966
1158
|
|
|
967
1159
|
When you run services on ports \u2014 such as a web app, API server, or database \u2014 humans may want to interact with them directly. You can expose your locally running services as public preview URLs.
|
|
968
1160
|
|
|
@@ -1044,12 +1236,12 @@ var PREVIEWS_ABILITY = {
|
|
|
1044
1236
|
label: "Previews",
|
|
1045
1237
|
description: "Expose locally running services on public preview URLs for humans.",
|
|
1046
1238
|
bullet: "- Creating preview URLs for locally running services",
|
|
1047
|
-
section:
|
|
1048
|
-
referenceFile: { name: "PREVIEWS.md", content:
|
|
1239
|
+
section: SECTION7,
|
|
1240
|
+
referenceFile: { name: "PREVIEWS.md", content: REFERENCE7 }
|
|
1049
1241
|
};
|
|
1050
1242
|
|
|
1051
1243
|
// ../shared/src/default-skills/replicas-agent/abilities/replicas.ts
|
|
1052
|
-
var
|
|
1244
|
+
var SECTION8 = `### Replicas (in-workspace CLI)
|
|
1053
1245
|
Take action *with* Replicas itself \u2014 manage automations, environments (variables, files), repos, and \`replicas.json\` config \u2014 using the pre-installed, pre-authenticated \`replicas\` CLI.
|
|
1054
1246
|
|
|
1055
1247
|
**Reference:** \`references/REPLICAS.md\`
|
|
@@ -1059,7 +1251,7 @@ Use this when:
|
|
|
1059
1251
|
- The user asks you to manage environments, environment variables, or environment files
|
|
1060
1252
|
- The user asks "what envs / repos / automations do I have?"
|
|
1061
1253
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo`;
|
|
1062
|
-
var
|
|
1254
|
+
var REFERENCE8 = `# Replicas (in-workspace CLI)
|
|
1063
1255
|
|
|
1064
1256
|
This guide covers how to take action *with* Replicas itself from inside a Replicas workspace \u2014 managing automations, environments (and their variables/files), repos, previews, and the user's \`replicas.json\` config \u2014 using the pre-installed \`replicas\` CLI.
|
|
1065
1257
|
|
|
@@ -1253,13 +1445,13 @@ var REPLICAS_ABILITY = {
|
|
|
1253
1445
|
description: "Teach the agent about Replicas itself \u2014 automations, environments, the in-workspace CLI.",
|
|
1254
1446
|
// No bullet — help_instructions covers the `replicas` CLI surface in detail.
|
|
1255
1447
|
bullet: "",
|
|
1256
|
-
section:
|
|
1257
|
-
referenceFile: { name: "REPLICAS.md", content:
|
|
1448
|
+
section: SECTION8,
|
|
1449
|
+
referenceFile: { name: "REPLICAS.md", content: REFERENCE8 },
|
|
1258
1450
|
locked: true
|
|
1259
1451
|
};
|
|
1260
1452
|
|
|
1261
1453
|
// ../shared/src/default-skills/replicas-agent/abilities/slack.ts
|
|
1262
|
-
var
|
|
1454
|
+
var SECTION9 = `### Slack
|
|
1263
1455
|
Send messages, read threads, search conversations, and upload files via the Slack Web API.
|
|
1264
1456
|
|
|
1265
1457
|
**Reference:** \`references/SLACK.md\`
|
|
@@ -1269,7 +1461,7 @@ Use this when:
|
|
|
1269
1461
|
- You need to read or fetch a Slack conversation
|
|
1270
1462
|
- You encounter a Slack message link and need to retrieve its content
|
|
1271
1463
|
- The task asks you to notify, update, or communicate via Slack`;
|
|
1272
|
-
var
|
|
1464
|
+
var REFERENCE9 = `# Slack Integration
|
|
1273
1465
|
|
|
1274
1466
|
This guide covers how to interact with Slack from within your Replicas workspace.
|
|
1275
1467
|
|
|
@@ -1342,13 +1534,14 @@ var SLACK_ABILITY = {
|
|
|
1342
1534
|
label: "Slack",
|
|
1343
1535
|
description: "Send messages, read threads, search conversations, upload files.",
|
|
1344
1536
|
bullet: "- Interacting with Slack (sending messages, reading threads, etc.)",
|
|
1345
|
-
section:
|
|
1346
|
-
referenceFile: { name: "SLACK.md", content:
|
|
1537
|
+
section: SECTION9,
|
|
1538
|
+
referenceFile: { name: "SLACK.md", content: REFERENCE9 }
|
|
1347
1539
|
};
|
|
1348
1540
|
|
|
1349
1541
|
// ../shared/src/default-skills/replicas-agent/registry.ts
|
|
1350
1542
|
var REPLICAS_AGENT_ABILITY_REGISTRY = {
|
|
1351
1543
|
replicas: REPLICAS_ABILITY,
|
|
1544
|
+
computer: COMPUTER_ABILITY,
|
|
1352
1545
|
docker: DOCKER_ABILITY,
|
|
1353
1546
|
github: GITHUB_ABILITY,
|
|
1354
1547
|
google: GOOGLE_ABILITY,
|
|
@@ -1493,7 +1686,7 @@ function parseReplicasConfigString(content, filename) {
|
|
|
1493
1686
|
}
|
|
1494
1687
|
|
|
1495
1688
|
// ../shared/src/engine/environment.ts
|
|
1496
|
-
var DAYTONA_SNAPSHOT_ID = "26-05-2026-royal-york-
|
|
1689
|
+
var DAYTONA_SNAPSHOT_ID = "26-05-2026-royal-york-v2";
|
|
1497
1690
|
|
|
1498
1691
|
// ../shared/src/engine/types.ts
|
|
1499
1692
|
var DEFAULT_CHAT_TITLES = {
|
|
@@ -4024,20 +4217,6 @@ var MessageQueueService = class {
|
|
|
4024
4217
|
};
|
|
4025
4218
|
|
|
4026
4219
|
// src/managers/coding-agent-manager.ts
|
|
4027
|
-
var COMPACT_COMMAND_REGEX = /^\/compact\b\s*(.*)$/s;
|
|
4028
|
-
var COMPACT_TURN_MARKER = "\0__replicas_compact_turn__\0";
|
|
4029
|
-
var COMPACT_SUMMARY_PROMPT = [
|
|
4030
|
-
"The user has requested a session compaction. Produce a thorough summary of this conversation that captures everything needed to continue the work without the prior context.",
|
|
4031
|
-
"",
|
|
4032
|
-
"Cover at least:",
|
|
4033
|
-
"1. The high-level goal we are working toward and the user's most recent intent.",
|
|
4034
|
-
"2. Key decisions made and the rationale behind them.",
|
|
4035
|
-
"3. Files inspected or modified (paths + the relevant changes).",
|
|
4036
|
-
"4. Open questions, blockers, and pending follow-ups.",
|
|
4037
|
-
"5. Any environment details, credentials, or external systems already configured.",
|
|
4038
|
-
"",
|
|
4039
|
-
"Format the response as Markdown with clear headings. The session will be reset after your reply and your summary re-injected as the prelude to the next user turn; write it so a future agent can resume using only that prelude."
|
|
4040
|
-
].join("\n");
|
|
4041
4220
|
var MAX_INTERRUPT_QUEUE_ITEMS = 1e3;
|
|
4042
4221
|
var MAX_INTERRUPT_QUEUE_CHARS = 2e5;
|
|
4043
4222
|
var CodingAgentManager = class {
|
|
@@ -4048,9 +4227,7 @@ var CodingAgentManager = class {
|
|
|
4048
4227
|
onSaveSessionId;
|
|
4049
4228
|
onEvent;
|
|
4050
4229
|
hostOnTurnComplete;
|
|
4051
|
-
|
|
4052
|
-
compactionBuffer = "";
|
|
4053
|
-
pendingSessionPrelude = null;
|
|
4230
|
+
compacting = false;
|
|
4054
4231
|
constructor(options) {
|
|
4055
4232
|
this.workingDirectory = options.workingDirectory ?? ENGINE_ENV.WORKSPACE_ROOT;
|
|
4056
4233
|
this.initialSessionId = options.initialSessionId;
|
|
@@ -4059,65 +4236,26 @@ var CodingAgentManager = class {
|
|
|
4059
4236
|
this.hostOnTurnComplete = options.onTurnComplete;
|
|
4060
4237
|
}
|
|
4061
4238
|
onTurnComplete = async () => {
|
|
4062
|
-
if (this.
|
|
4063
|
-
this.
|
|
4064
|
-
const summary = this.compactionBuffer.trim();
|
|
4065
|
-
this.compactionBuffer = "";
|
|
4066
|
-
this.pendingSessionPrelude = summary.length > 0 ? summary : null;
|
|
4067
|
-
this.emitCompactionStatus("completed");
|
|
4068
|
-
try {
|
|
4069
|
-
await this.clearSessionState();
|
|
4070
|
-
} catch (error) {
|
|
4071
|
-
console.error("[CodingAgentManager] Failed to clear session after compaction:", error);
|
|
4072
|
-
}
|
|
4239
|
+
if (this.compacting) {
|
|
4240
|
+
this.setCompacting(false);
|
|
4073
4241
|
}
|
|
4074
4242
|
await this.hostOnTurnComplete();
|
|
4075
4243
|
};
|
|
4076
4244
|
isCompacting() {
|
|
4077
|
-
return this.
|
|
4245
|
+
return this.compacting;
|
|
4078
4246
|
}
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
this.compactionBuffer = this.compactionBuffer.length > 0 ? `${this.compactionBuffer}
|
|
4084
|
-
|
|
4085
|
-
${trimmed}` : trimmed;
|
|
4086
|
-
}
|
|
4087
|
-
consumePendingPrelude(message) {
|
|
4088
|
-
if (!this.pendingSessionPrelude) return message;
|
|
4089
|
-
const prelude = this.pendingSessionPrelude;
|
|
4090
|
-
this.pendingSessionPrelude = null;
|
|
4091
|
-
return `<prior-session-summary>
|
|
4092
|
-
${prelude}
|
|
4093
|
-
</prior-session-summary>
|
|
4094
|
-
|
|
4095
|
-
${message}`;
|
|
4096
|
-
}
|
|
4097
|
-
emitCompactionStatus(state) {
|
|
4247
|
+
// Dedup so a noisy stream of native compaction events doesn't spam the UI with redundant status flips.
|
|
4248
|
+
setCompacting(active) {
|
|
4249
|
+
if (this.compacting === active) return;
|
|
4250
|
+
this.compacting = active;
|
|
4098
4251
|
this.onEvent({
|
|
4099
4252
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4100
4253
|
type: COMPACTION_STATUS_EVENT_TYPE,
|
|
4101
|
-
payload: { state }
|
|
4254
|
+
payload: { state: active ? "in_progress" : "completed" }
|
|
4102
4255
|
});
|
|
4103
4256
|
}
|
|
4104
4257
|
initializeManager(processMessage) {
|
|
4105
|
-
|
|
4106
|
-
if (request.message.startsWith(COMPACT_TURN_MARKER)) {
|
|
4107
|
-
this.compactionInFlight = true;
|
|
4108
|
-
this.compactionBuffer = "";
|
|
4109
|
-
this.emitCompactionStatus("in_progress");
|
|
4110
|
-
const summaryPrompt = this.consumePendingPrelude(
|
|
4111
|
-
request.message.slice(COMPACT_TURN_MARKER.length)
|
|
4112
|
-
);
|
|
4113
|
-
return processMessage({ ...request, message: summaryPrompt });
|
|
4114
|
-
}
|
|
4115
|
-
return processMessage({
|
|
4116
|
-
...request,
|
|
4117
|
-
message: this.consumePendingPrelude(request.message)
|
|
4118
|
-
});
|
|
4119
|
-
};
|
|
4120
|
-
this.messageQueue = new MessageQueueService(wrappedProcessMessage);
|
|
4258
|
+
this.messageQueue = new MessageQueueService(processMessage);
|
|
4121
4259
|
this.initialized = this.initialize();
|
|
4122
4260
|
}
|
|
4123
4261
|
async interrupt() {
|
|
@@ -4137,7 +4275,7 @@ ${message}`;
|
|
|
4137
4275
|
getQueue() {
|
|
4138
4276
|
return this.messageQueue.getQueue().map((m) => ({
|
|
4139
4277
|
id: m.id,
|
|
4140
|
-
message: m.message
|
|
4278
|
+
message: m.message,
|
|
4141
4279
|
queuedAt: m.queuedAt,
|
|
4142
4280
|
...m.senderUserId ? { senderUserId: m.senderUserId } : {},
|
|
4143
4281
|
...m.senderEmail ? { senderEmail: m.senderEmail } : {},
|
|
@@ -4152,18 +4290,6 @@ ${message}`;
|
|
|
4152
4290
|
}
|
|
4153
4291
|
async enqueueMessage(request) {
|
|
4154
4292
|
await this.initialized;
|
|
4155
|
-
const compact = request.message.trimStart().match(COMPACT_COMMAND_REGEX);
|
|
4156
|
-
if (compact) {
|
|
4157
|
-
const guidance = compact[1].trim();
|
|
4158
|
-
const prompt = guidance ? `${COMPACT_SUMMARY_PROMPT}
|
|
4159
|
-
|
|
4160
|
-
Additional guidance from the user for the summary:
|
|
4161
|
-
${guidance}` : COMPACT_SUMMARY_PROMPT;
|
|
4162
|
-
return this.messageQueue.enqueue({
|
|
4163
|
-
...request,
|
|
4164
|
-
message: `${COMPACT_TURN_MARKER}${prompt}`
|
|
4165
|
-
});
|
|
4166
|
-
}
|
|
4167
4293
|
return this.messageQueue.enqueue(request);
|
|
4168
4294
|
}
|
|
4169
4295
|
emitContextUsage(payload) {
|
|
@@ -4202,7 +4328,7 @@ ${guidance}` : COMPACT_SUMMARY_PROMPT;
|
|
|
4202
4328
|
const queue = this.messageQueue.drainQueue({
|
|
4203
4329
|
maxItems: MAX_INTERRUPT_QUEUE_ITEMS,
|
|
4204
4330
|
maxChars: MAX_INTERRUPT_QUEUE_CHARS
|
|
4205
|
-
})
|
|
4331
|
+
});
|
|
4206
4332
|
return {
|
|
4207
4333
|
queue,
|
|
4208
4334
|
isProcessing: this.messageQueue.isProcessing()
|
|
@@ -4479,10 +4605,6 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
4479
4605
|
}
|
|
4480
4606
|
await this.abortAllPendingToolInputs();
|
|
4481
4607
|
}
|
|
4482
|
-
async clearSessionState() {
|
|
4483
|
-
this.sessionId = null;
|
|
4484
|
-
await this.onSaveSessionId(null);
|
|
4485
|
-
}
|
|
4486
4608
|
async abortAllPendingToolInputs() {
|
|
4487
4609
|
const pending = Array.from(this.pendingToolInputs.values());
|
|
4488
4610
|
this.pendingToolInputs.clear();
|
|
@@ -4840,15 +4962,20 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
4840
4962
|
console.log(`[ClaudeManager] Captured and persisted session ID: ${this.sessionId}`);
|
|
4841
4963
|
}
|
|
4842
4964
|
await this.checkForAuthFailure(message);
|
|
4843
|
-
|
|
4844
|
-
for (const block of message.message.content) {
|
|
4845
|
-
if (block.type === "text") {
|
|
4846
|
-
this.captureCompactionText(block.text);
|
|
4847
|
-
}
|
|
4848
|
-
}
|
|
4849
|
-
}
|
|
4965
|
+
this.trackNativeCompaction(message);
|
|
4850
4966
|
await this.recordEvent(message);
|
|
4851
4967
|
}
|
|
4968
|
+
// Claude Code intercepts /compact and auto-compaction inside the SDK process; we just observe the status messages to mirror state to the UI.
|
|
4969
|
+
trackNativeCompaction(message) {
|
|
4970
|
+
if (message.type !== "system") return;
|
|
4971
|
+
if (message.subtype === "status" && message.status === "compacting") {
|
|
4972
|
+
this.setCompacting(true);
|
|
4973
|
+
return;
|
|
4974
|
+
}
|
|
4975
|
+
if (message.subtype === "compact_boundary") {
|
|
4976
|
+
this.setCompacting(false);
|
|
4977
|
+
}
|
|
4978
|
+
}
|
|
4852
4979
|
async recordEvent(event) {
|
|
4853
4980
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
4854
4981
|
const jsonEvent = {
|
|
@@ -5012,11 +5139,6 @@ var CodexManager = class _CodexManager extends CodingAgentManager {
|
|
|
5012
5139
|
this.activeAbortController.abort();
|
|
5013
5140
|
}
|
|
5014
5141
|
}
|
|
5015
|
-
async clearSessionState() {
|
|
5016
|
-
this.currentThreadId = null;
|
|
5017
|
-
this.currentThread = null;
|
|
5018
|
-
await this.onSaveSessionId(null);
|
|
5019
|
-
}
|
|
5020
5142
|
/**
|
|
5021
5143
|
* Update the developer_instructions in ~/.codex/config.toml
|
|
5022
5144
|
* This sets the system prompt that Codex will use for this turn
|
|
@@ -5290,16 +5412,21 @@ var CodexManager = class _CodexManager extends CodingAgentManager {
|
|
|
5290
5412
|
}
|
|
5291
5413
|
return null;
|
|
5292
5414
|
}
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
if (event.type
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5415
|
+
// @openai/codex-sdk doesn't expose manual /compact (TUI-only); we only mirror the auto-compaction rollout entries to the UI.
|
|
5416
|
+
trackNativeCompaction(event) {
|
|
5417
|
+
if (event.type === "compacted") {
|
|
5418
|
+
this.setCompacting(false);
|
|
5419
|
+
return;
|
|
5420
|
+
}
|
|
5421
|
+
if (event.type !== "event_msg") return;
|
|
5422
|
+
const msg = event.payload.msg;
|
|
5423
|
+
if (!msg) return;
|
|
5424
|
+
const itemType = msg.payload?.item?.type;
|
|
5425
|
+
if (itemType !== "context_compaction") return;
|
|
5426
|
+
if (msg.type === "item_started") {
|
|
5427
|
+
this.setCompacting(true);
|
|
5428
|
+
} else if (msg.type === "item_completed") {
|
|
5429
|
+
this.setCompacting(false);
|
|
5303
5430
|
}
|
|
5304
5431
|
}
|
|
5305
5432
|
async startSessionTail(threadId) {
|
|
@@ -5352,7 +5479,7 @@ var CodexManager = class _CodexManager extends CodingAgentManager {
|
|
|
5352
5479
|
this.emitQuotaStatus(snapshot);
|
|
5353
5480
|
}
|
|
5354
5481
|
if (isJsonlEvent2(parsed)) {
|
|
5355
|
-
this.
|
|
5482
|
+
this.trackNativeCompaction(parsed);
|
|
5356
5483
|
this.onEvent(parsed);
|
|
5357
5484
|
emitted += 1;
|
|
5358
5485
|
}
|
|
@@ -5742,11 +5869,6 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
5742
5869
|
console.warn("[CodexAspManager] Failed to interrupt active turn:", error);
|
|
5743
5870
|
}
|
|
5744
5871
|
}
|
|
5745
|
-
async clearSessionState() {
|
|
5746
|
-
this.currentThreadId = null;
|
|
5747
|
-
this.activeTurnId = null;
|
|
5748
|
-
await this.onSaveSessionId(null);
|
|
5749
|
-
}
|
|
5750
5872
|
async getHistory() {
|
|
5751
5873
|
return {
|
|
5752
5874
|
thread_id: this.currentThreadId,
|
|
@@ -5937,7 +6059,6 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
5937
6059
|
if (!text) {
|
|
5938
6060
|
return;
|
|
5939
6061
|
}
|
|
5940
|
-
this.captureCompactionText(text);
|
|
5941
6062
|
const event = this.recordHistoryEvent("response_item", {
|
|
5942
6063
|
type: "message",
|
|
5943
6064
|
role: "assistant",
|